From 71e7fbdd41143c32a7723a19d4ec375b7295a67a Mon Sep 17 00:00:00 2001 From: Tanish Date: Sat, 10 Jan 2026 19:16:24 +0530 Subject: [PATCH 01/48] basic gorm setup and automigrate --- server/db/main.go | 16 +++-- .../{migrations.go => migrations_archive.go} | 0 .../001_Create_User.sql | 0 .../002_Create_Projects.sql | 0 .../003_Create_Project_members.sql | 0 .../004_Create_GitProviders.sql | 0 .../005_Create_App.sql | 0 .../006_Create_Github_app.sql | 0 .../007_Create_Github_installations.sql | 0 .../008_Create_App_repositories.sql | 0 .../009_Create_deployments.sql | 0 .../010_Create_Envs.sql | 0 .../011_Create_domains.sql | 0 .../012_Create_Volumes.sql | 0 .../013_Create_Cron.sql | 0 .../014_Create_Registries.sql | 0 .../015_Create_System_settings.sql | 0 .../016_Create_Logs.sql | 0 .../017_Create_Audit_logs.sql | 0 .../018_Create_Service_templates.sql | 0 .../019_Create_Api_tokens.sql | 0 .../020_Create_Sessions.sql | 0 .../021_Create_Notifications.sql | 0 .../022_Create_Backups.sql | 0 .../023_Add_DNS_validation.sql | 0 .../024_Add_Wildcard_domain_settings.sql | 0 .../025_Add_Missing_Indexes.sql | 0 .../026_Add_Version_SystemSettings.sql | 0 .../027_Create_UpdateLogs.sql | 0 .../028_Version_bump_v1.0.1.sql | 0 .../029_Version_Bump_v1.0.2.sql | 0 server/go.mod | 7 ++- server/go.sum | 12 ++++ server/main.go | 27 ++++++++ server/models/appRepositories.go | 16 +++++ server/models/auditLog.go | 2 +- server/models/cron.go | 15 +++++ server/models/logs.go | 28 +++++++++ server/models/main.go | 9 ++- server/models/projectMembers.go | 10 +++ server/models/registries.go | 12 ++++ server/models/updateLog.go | 62 +++++++++++++------ 42 files changed, 186 insertions(+), 30 deletions(-) rename server/db/{migrations.go => migrations_archive.go} (100%) rename server/db/{migrations => migrations_archive}/001_Create_User.sql (100%) rename server/db/{migrations => migrations_archive}/002_Create_Projects.sql (100%) rename server/db/{migrations => migrations_archive}/003_Create_Project_members.sql (100%) rename server/db/{migrations => migrations_archive}/004_Create_GitProviders.sql (100%) rename server/db/{migrations => migrations_archive}/005_Create_App.sql (100%) rename server/db/{migrations => migrations_archive}/006_Create_Github_app.sql (100%) rename server/db/{migrations => migrations_archive}/007_Create_Github_installations.sql (100%) rename server/db/{migrations => migrations_archive}/008_Create_App_repositories.sql (100%) rename server/db/{migrations => migrations_archive}/009_Create_deployments.sql (100%) rename server/db/{migrations => migrations_archive}/010_Create_Envs.sql (100%) rename server/db/{migrations => migrations_archive}/011_Create_domains.sql (100%) rename server/db/{migrations => migrations_archive}/012_Create_Volumes.sql (100%) rename server/db/{migrations => migrations_archive}/013_Create_Cron.sql (100%) rename server/db/{migrations => migrations_archive}/014_Create_Registries.sql (100%) rename server/db/{migrations => migrations_archive}/015_Create_System_settings.sql (100%) rename server/db/{migrations => migrations_archive}/016_Create_Logs.sql (100%) rename server/db/{migrations => migrations_archive}/017_Create_Audit_logs.sql (100%) rename server/db/{migrations => migrations_archive}/018_Create_Service_templates.sql (100%) rename server/db/{migrations => migrations_archive}/019_Create_Api_tokens.sql (100%) rename server/db/{migrations => migrations_archive}/020_Create_Sessions.sql (100%) rename server/db/{migrations => migrations_archive}/021_Create_Notifications.sql (100%) rename server/db/{migrations => migrations_archive}/022_Create_Backups.sql (100%) rename server/db/{migrations => migrations_archive}/023_Add_DNS_validation.sql (100%) rename server/db/{migrations => migrations_archive}/024_Add_Wildcard_domain_settings.sql (100%) rename server/db/{migrations => migrations_archive}/025_Add_Missing_Indexes.sql (100%) rename server/db/{migrations => migrations_archive}/026_Add_Version_SystemSettings.sql (100%) rename server/db/{migrations => migrations_archive}/027_Create_UpdateLogs.sql (100%) rename server/db/{migrations => migrations_archive}/028_Version_bump_v1.0.1.sql (100%) rename server/db/{migrations => migrations_archive}/029_Version_Bump_v1.0.2.sql (100%) create mode 100644 server/models/appRepositories.go create mode 100644 server/models/cron.go create mode 100644 server/models/logs.go create mode 100644 server/models/projectMembers.go create mode 100644 server/models/registries.go diff --git a/server/db/main.go b/server/db/main.go index 4e66b46..584bd48 100644 --- a/server/db/main.go +++ b/server/db/main.go @@ -1,16 +1,18 @@ package db import ( - "database/sql" "fmt" "os" "path/filepath" "github.com/corecollectives/mist/fs" _ "github.com/mattn/go-sqlite3" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "gorm.io/gorm/logger" ) -func InitDB() (*sql.DB, error) { +func InitDB() (*gorm.DB, error) { dbPath := "" if os.Getenv("ENV") == "dev" { dbPath = "./mist.db" @@ -22,12 +24,14 @@ func InitDB() (*sql.DB, error) { if err != nil { return nil, fmt.Errorf("failed to create database directory: %v", err) } - db, err := sql.Open("sqlite3", dbPath) + db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{ + Logger: logger.Default.LogMode(logger.Info), + }) if err != nil { return nil, fmt.Errorf("failed to open database: %v", err) } - if err := runMigrations(db); err != nil { - return nil, fmt.Errorf("failed to run migrations: %v", err) - } + // if err := runMigrations(db); err != nil { + // return nil, fmt.Errorf("failed to run migrations: %v", err) + // } return db, nil } diff --git a/server/db/migrations.go b/server/db/migrations_archive.go similarity index 100% rename from server/db/migrations.go rename to server/db/migrations_archive.go diff --git a/server/db/migrations/001_Create_User.sql b/server/db/migrations_archive/001_Create_User.sql similarity index 100% rename from server/db/migrations/001_Create_User.sql rename to server/db/migrations_archive/001_Create_User.sql diff --git a/server/db/migrations/002_Create_Projects.sql b/server/db/migrations_archive/002_Create_Projects.sql similarity index 100% rename from server/db/migrations/002_Create_Projects.sql rename to server/db/migrations_archive/002_Create_Projects.sql diff --git a/server/db/migrations/003_Create_Project_members.sql b/server/db/migrations_archive/003_Create_Project_members.sql similarity index 100% rename from server/db/migrations/003_Create_Project_members.sql rename to server/db/migrations_archive/003_Create_Project_members.sql diff --git a/server/db/migrations/004_Create_GitProviders.sql b/server/db/migrations_archive/004_Create_GitProviders.sql similarity index 100% rename from server/db/migrations/004_Create_GitProviders.sql rename to server/db/migrations_archive/004_Create_GitProviders.sql diff --git a/server/db/migrations/005_Create_App.sql b/server/db/migrations_archive/005_Create_App.sql similarity index 100% rename from server/db/migrations/005_Create_App.sql rename to server/db/migrations_archive/005_Create_App.sql diff --git a/server/db/migrations/006_Create_Github_app.sql b/server/db/migrations_archive/006_Create_Github_app.sql similarity index 100% rename from server/db/migrations/006_Create_Github_app.sql rename to server/db/migrations_archive/006_Create_Github_app.sql diff --git a/server/db/migrations/007_Create_Github_installations.sql b/server/db/migrations_archive/007_Create_Github_installations.sql similarity index 100% rename from server/db/migrations/007_Create_Github_installations.sql rename to server/db/migrations_archive/007_Create_Github_installations.sql diff --git a/server/db/migrations/008_Create_App_repositories.sql b/server/db/migrations_archive/008_Create_App_repositories.sql similarity index 100% rename from server/db/migrations/008_Create_App_repositories.sql rename to server/db/migrations_archive/008_Create_App_repositories.sql diff --git a/server/db/migrations/009_Create_deployments.sql b/server/db/migrations_archive/009_Create_deployments.sql similarity index 100% rename from server/db/migrations/009_Create_deployments.sql rename to server/db/migrations_archive/009_Create_deployments.sql diff --git a/server/db/migrations/010_Create_Envs.sql b/server/db/migrations_archive/010_Create_Envs.sql similarity index 100% rename from server/db/migrations/010_Create_Envs.sql rename to server/db/migrations_archive/010_Create_Envs.sql diff --git a/server/db/migrations/011_Create_domains.sql b/server/db/migrations_archive/011_Create_domains.sql similarity index 100% rename from server/db/migrations/011_Create_domains.sql rename to server/db/migrations_archive/011_Create_domains.sql diff --git a/server/db/migrations/012_Create_Volumes.sql b/server/db/migrations_archive/012_Create_Volumes.sql similarity index 100% rename from server/db/migrations/012_Create_Volumes.sql rename to server/db/migrations_archive/012_Create_Volumes.sql diff --git a/server/db/migrations/013_Create_Cron.sql b/server/db/migrations_archive/013_Create_Cron.sql similarity index 100% rename from server/db/migrations/013_Create_Cron.sql rename to server/db/migrations_archive/013_Create_Cron.sql diff --git a/server/db/migrations/014_Create_Registries.sql b/server/db/migrations_archive/014_Create_Registries.sql similarity index 100% rename from server/db/migrations/014_Create_Registries.sql rename to server/db/migrations_archive/014_Create_Registries.sql diff --git a/server/db/migrations/015_Create_System_settings.sql b/server/db/migrations_archive/015_Create_System_settings.sql similarity index 100% rename from server/db/migrations/015_Create_System_settings.sql rename to server/db/migrations_archive/015_Create_System_settings.sql diff --git a/server/db/migrations/016_Create_Logs.sql b/server/db/migrations_archive/016_Create_Logs.sql similarity index 100% rename from server/db/migrations/016_Create_Logs.sql rename to server/db/migrations_archive/016_Create_Logs.sql diff --git a/server/db/migrations/017_Create_Audit_logs.sql b/server/db/migrations_archive/017_Create_Audit_logs.sql similarity index 100% rename from server/db/migrations/017_Create_Audit_logs.sql rename to server/db/migrations_archive/017_Create_Audit_logs.sql diff --git a/server/db/migrations/018_Create_Service_templates.sql b/server/db/migrations_archive/018_Create_Service_templates.sql similarity index 100% rename from server/db/migrations/018_Create_Service_templates.sql rename to server/db/migrations_archive/018_Create_Service_templates.sql diff --git a/server/db/migrations/019_Create_Api_tokens.sql b/server/db/migrations_archive/019_Create_Api_tokens.sql similarity index 100% rename from server/db/migrations/019_Create_Api_tokens.sql rename to server/db/migrations_archive/019_Create_Api_tokens.sql diff --git a/server/db/migrations/020_Create_Sessions.sql b/server/db/migrations_archive/020_Create_Sessions.sql similarity index 100% rename from server/db/migrations/020_Create_Sessions.sql rename to server/db/migrations_archive/020_Create_Sessions.sql diff --git a/server/db/migrations/021_Create_Notifications.sql b/server/db/migrations_archive/021_Create_Notifications.sql similarity index 100% rename from server/db/migrations/021_Create_Notifications.sql rename to server/db/migrations_archive/021_Create_Notifications.sql diff --git a/server/db/migrations/022_Create_Backups.sql b/server/db/migrations_archive/022_Create_Backups.sql similarity index 100% rename from server/db/migrations/022_Create_Backups.sql rename to server/db/migrations_archive/022_Create_Backups.sql diff --git a/server/db/migrations/023_Add_DNS_validation.sql b/server/db/migrations_archive/023_Add_DNS_validation.sql similarity index 100% rename from server/db/migrations/023_Add_DNS_validation.sql rename to server/db/migrations_archive/023_Add_DNS_validation.sql diff --git a/server/db/migrations/024_Add_Wildcard_domain_settings.sql b/server/db/migrations_archive/024_Add_Wildcard_domain_settings.sql similarity index 100% rename from server/db/migrations/024_Add_Wildcard_domain_settings.sql rename to server/db/migrations_archive/024_Add_Wildcard_domain_settings.sql diff --git a/server/db/migrations/025_Add_Missing_Indexes.sql b/server/db/migrations_archive/025_Add_Missing_Indexes.sql similarity index 100% rename from server/db/migrations/025_Add_Missing_Indexes.sql rename to server/db/migrations_archive/025_Add_Missing_Indexes.sql diff --git a/server/db/migrations/026_Add_Version_SystemSettings.sql b/server/db/migrations_archive/026_Add_Version_SystemSettings.sql similarity index 100% rename from server/db/migrations/026_Add_Version_SystemSettings.sql rename to server/db/migrations_archive/026_Add_Version_SystemSettings.sql diff --git a/server/db/migrations/027_Create_UpdateLogs.sql b/server/db/migrations_archive/027_Create_UpdateLogs.sql similarity index 100% rename from server/db/migrations/027_Create_UpdateLogs.sql rename to server/db/migrations_archive/027_Create_UpdateLogs.sql diff --git a/server/db/migrations/028_Version_bump_v1.0.1.sql b/server/db/migrations_archive/028_Version_bump_v1.0.1.sql similarity index 100% rename from server/db/migrations/028_Version_bump_v1.0.1.sql rename to server/db/migrations_archive/028_Version_bump_v1.0.1.sql diff --git a/server/db/migrations/029_Version_Bump_v1.0.2.sql b/server/db/migrations_archive/029_Version_Bump_v1.0.2.sql similarity index 100% rename from server/db/migrations/029_Version_Bump_v1.0.2.sql rename to server/db/migrations_archive/029_Version_Bump_v1.0.2.sql diff --git a/server/go.mod b/server/go.mod index 5159166..14ba4ec 100644 --- a/server/go.mod +++ b/server/go.mod @@ -5,7 +5,7 @@ go 1.25.1 require ( github.com/golang-jwt/jwt v3.2.2+incompatible github.com/gorilla/websocket v1.5.3 - github.com/mattn/go-sqlite3 v1.14.32 + github.com/mattn/go-sqlite3 v1.14.33 github.com/rs/zerolog v1.34.0 github.com/shirou/gopsutil v3.21.11+incompatible golang.org/x/crypto v0.43.0 @@ -23,6 +23,8 @@ require ( github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect @@ -40,6 +42,9 @@ require ( go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/otel/trace v1.35.0 // indirect golang.org/x/sys v0.37.0 // indirect + golang.org/x/text v0.33.0 // indirect + gorm.io/driver/sqlite v1.6.0 // indirect + gorm.io/gorm v1.31.1 // indirect ) replace github.com/docker/docker/api => github.com/moby/moby/api v1.52.0-beta.2 diff --git a/server/go.sum b/server/go.sum index db50e76..56684b1 100644 --- a/server/go.sum +++ b/server/go.sum @@ -27,6 +27,10 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keL github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -34,6 +38,8 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.33 h1:A5blZ5ulQo2AtayQ9/limgHEkFreKj1Dv226a1K73s0= +github.com/mattn/go-sqlite3 v1.14.33/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= @@ -78,7 +84,13 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= +gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= +gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg= +gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= diff --git a/server/main.go b/server/main.go index 69517e7..d943101 100644 --- a/server/main.go +++ b/server/main.go @@ -14,6 +14,33 @@ func main() { utils.InitLogger() log.Info().Msg("Starting Mist server") dbInstance, err := db.InitDB() + dbInstance.AutoMigrate( + &models.User{}, + &models.ApiToken{}, + &models.App{}, + &models.AuditLog{}, + &models.Backup{}, + &models.Deployment{}, + &models.EnvVariable{}, + &models.GithubApp{}, + &models.Project{}, + &models.ProjectMembers{}, + &models.GitProvider{}, + &models.GithubInstallation{}, + &models.AppRepositories{}, + &models.Domain{}, + &models.Volume{}, + &models.Cron{}, + &models.Registries{}, + &models.SystemSettings{}, + &models.Logs{}, + &models.AuditLog{}, + &models.ServiceTemplate{}, + &models.ApiToken{}, + &models.Session{}, + &models.Notification{}, + &models.UpdateLog{}, + ) _ = queue.InitQueue(dbInstance) if err != nil { log.Fatal().Err(err).Msg("Error initializing database") diff --git a/server/models/appRepositories.go b/server/models/appRepositories.go new file mode 100644 index 0000000..36bff21 --- /dev/null +++ b/server/models/appRepositories.go @@ -0,0 +1,16 @@ +package models + +import "time" + +type AppRepositories struct { + ID int64 `json:"id"` + AppID int64 `json:"app_id"` + SourceType string `json:"source_type"` + SourceID int64 `json:"source_id"` + RepoFullName string `json:"repo_full_name"` + RepoURL string `json:"repo_url"` + Branch string `json:"branch"` + WebhookID int64 `json:"webhook_id"` + AutoDeploy bool `json:"auto_deploy"` + LastSyncedAt time.Time `json:"last_synced_at"` +} diff --git a/server/models/auditLog.go b/server/models/auditLog.go index e8edacc..c72fdeb 100644 --- a/server/models/auditLog.go +++ b/server/models/auditLog.go @@ -108,7 +108,7 @@ func GetAuditLogsByUser(userID int64, limit, offset int) ([]AuditLog, error) { u.email, al.action, al.resource_type, - al.resource_id, + al.resource_id, SELECT al.details, al.created_at FROM audit_logs al diff --git a/server/models/cron.go b/server/models/cron.go new file mode 100644 index 0000000..1eb6aa2 --- /dev/null +++ b/server/models/cron.go @@ -0,0 +1,15 @@ +package models + +import "time" + +type Cron struct { + ID int64 `json:"id"` + AppID int64 `json:"app_id"` + Name string `json:"name"` + Schedule string `json:"schedule"` + Command string `json:"command"` + LastRun time.Time `json:"last_run"` + NextRun time.Time `json:"next_run"` + Enable bool `json:"enable"` + CreatedAt time.Time `json:"created_at"` +} diff --git a/server/models/logs.go b/server/models/logs.go new file mode 100644 index 0000000..87ecc1d --- /dev/null +++ b/server/models/logs.go @@ -0,0 +1,28 @@ +package models + +import "time" + +type LogSource string + +const ( + LogSourceApp LogSource = "app" + LogSourceSystem LogSource = "system" +) + +type LogLevel string + +const ( + LogLevelInfo LogLevel = "info" + LogLevelWarn LogLevel = "warn" + LogLevelError LogLevel = "error" + LogLevelDebug LogLevel = "debug" +) + +type Logs struct { + ID int64 + Source LogSource + SourceID *int64 + Message string + Level LogLevel + CreatedAt time.Time +} diff --git a/server/models/main.go b/server/models/main.go index 2520495..2785c70 100644 --- a/server/models/main.go +++ b/server/models/main.go @@ -1,9 +1,12 @@ package models -import "database/sql" +import ( -var db *sql.DB + "gorm.io/gorm" +) -func SetDB(database *sql.DB) { +var db *gorm.DB + +func SetDB(database *gorm.DB) { db = database } diff --git a/server/models/projectMembers.go b/server/models/projectMembers.go new file mode 100644 index 0000000..2d9fb85 --- /dev/null +++ b/server/models/projectMembers.go @@ -0,0 +1,10 @@ +package models + +import "time" + +type ProjectMembers struct{ + ID int64 `json:"id"` + ProjectID int64 `json:"project_id"` + USERID int64 `json:"user_id"` + AddedAt time.Time `json:"added_at"` +} \ No newline at end of file diff --git a/server/models/registries.go b/server/models/registries.go new file mode 100644 index 0000000..32b37b9 --- /dev/null +++ b/server/models/registries.go @@ -0,0 +1,12 @@ +package models + +import "time" + +type Registries struct { + ID int64 `json:"id"` + ProjectID int64 `json:"projectId"` + RegistryURL string `json:"registryUrl"` + Username string `json:"username"` + Password string `json:"password"` + CreatedAt time.Time `json:"createdAt"` +} diff --git a/server/models/updateLog.go b/server/models/updateLog.go index 181b3a6..9f5947d 100644 --- a/server/models/updateLog.go +++ b/server/models/updateLog.go @@ -8,17 +8,25 @@ import ( "github.com/rs/zerolog/log" ) +type UpdateStatus string + +const ( + UpdateStatusInProgress UpdateStatus = "in_progress" + UpdateStatusSuccess UpdateStatus = "success" + UpdateStatusFailed UpdateStatus = "failed" +) + type UpdateLog struct { - ID int64 `json:"id"` - VersionFrom string `json:"versionFrom"` - VersionTo string `json:"versionTo"` - Status string `json:"status"` // in_progress, success, failed - Logs string `json:"logs"` - ErrorMessage *string `json:"errorMessage"` - StartedBy int64 `json:"startedBy"` - StartedAt time.Time `json:"startedAt"` - CompletedAt *time.Time `json:"completedAt"` - Username string `json:"username"` + ID int64 + VersionFrom string + VersionTo string + Status UpdateStatus + Logs *string + ErrorMessage *string + StartedBy int64 + StartedAt time.Time + CompletedAt *time.Time + Username *string } func CreateUpdateLog(versionFrom, versionTo string, startedBy int64) (*UpdateLog, error) { @@ -56,7 +64,7 @@ func CreateUpdateLog(versionFrom, versionTo string, startedBy int64) (*UpdateLog return updateLog, nil } -func UpdateUpdateLogStatus(id int64, status string, logs string, errorMessage *string) error { +func UpdateUpdateLogStatus(id int64, status UpdateStatus, logs string, errorMessage *string) error { query := ` UPDATE update_logs SET status = ?, logs = ?, error_message = ?, completed_at = CURRENT_TIMESTAMP @@ -71,7 +79,7 @@ func UpdateUpdateLogStatus(id int64, status string, logs string, errorMessage *s log.Info(). Int64("update_log_id", id). - Str("status", status). + Str("status", string(status)). Msg("Update log status updated") return nil @@ -195,12 +203,17 @@ func GetUpdateLogsAsString() (string, error) { builder.WriteString(log.VersionTo) builder.WriteString("\n") builder.WriteString("Status: ") - builder.WriteString(log.Status) + builder.WriteString(string(log.Status)) builder.WriteString("\n") builder.WriteString("Started: ") builder.WriteString(log.StartedAt.Format("2006-01-02 15:04:05")) builder.WriteString(" by ") - builder.WriteString(log.Username) + if log.Username != nil { + builder.WriteString(*log.Username) + } else { + builder.WriteString("unknown") + } + builder.WriteString("\n") if log.CompletedAt != nil { builder.WriteString("Completed: ") @@ -230,7 +243,7 @@ func CheckAndCompletePendingUpdates() error { latestLog := logs[0] - if latestLog.Status != "in_progress" { + if latestLog.Status != UpdateStatusInProgress { return nil } @@ -257,8 +270,14 @@ func CheckAndCompletePendingUpdates() error { Str("version", currentVersion). Msg("Completing successful update that was interrupted by service restart") - completionLog := latestLog.Logs + "\n✅ Update completed successfully (verified on restart)\n" - err = UpdateUpdateLogStatus(latestLog.ID, "success", completionLog, nil) + existing := "" + if latestLog.Logs != nil { + existing = *latestLog.Logs + } + + completionLog := existing + "\n✅ Update completed successfully (verified on restart)\n" + + err = UpdateUpdateLogStatus(latestLog.ID, UpdateStatusSuccess, completionLog, nil) if err != nil { log.Error().Err(err).Int64("update_log_id", latestLog.ID).Msg("Failed to complete pending update") return err @@ -280,8 +299,13 @@ func CheckAndCompletePendingUpdates() error { Msg("Update appears to have failed (version mismatch detected on startup)") errMsg := "Update process was interrupted and version does not match target" - failureLog := latestLog.Logs + "\n❌ " + errMsg + "\n" - err = UpdateUpdateLogStatus(latestLog.ID, "failed", failureLog, &errMsg) + existing := "" + if latestLog.Logs != nil { + existing = *latestLog.Logs + } + + failureLog := existing + "\n❌ " + errMsg + "\n" + err = UpdateUpdateLogStatus(latestLog.ID, UpdateStatusFailed, failureLog, &errMsg) if err != nil { log.Error().Err(err).Int64("update_log_id", latestLog.ID).Msg("Failed to mark failed update") return err From 452a78b84578a027acc56d5e9aa2ac57dcf4ec0d Mon Sep 17 00:00:00 2001 From: Tanish Date: Sun, 11 Jan 2026 15:59:21 +0530 Subject: [PATCH 02/48] completed apiToken.go --- server/models/apiToken.go | 113 ++++++++++---------------------------- server/models/temp.go | 0 2 files changed, 29 insertions(+), 84 deletions(-) create mode 100644 server/models/temp.go diff --git a/server/models/apiToken.go b/server/models/apiToken.go index 75b457a..b902e04 100644 --- a/server/models/apiToken.go +++ b/server/models/apiToken.go @@ -4,21 +4,22 @@ import ( "time" "github.com/corecollectives/mist/utils" + "gorm.io/gorm" ) type ApiToken struct { - ID int64 `db:"id" json:"id"` - UserID int64 `db:"user_id" json:"userId"` - Name string `db:"name" json:"name"` - TokenHash string `db:"token_hash" json:"-"` // Never expose in JSON - TokenPrefix string `db:"token_prefix" json:"tokenPrefix"` - Scopes *string `db:"scopes" json:"scopes,omitempty"` // JSON array - LastUsedAt *time.Time `db:"last_used_at" json:"lastUsedAt,omitempty"` - LastUsedIP *string `db:"last_used_ip" json:"lastUsedIp,omitempty"` - UsageCount int `db:"usage_count" json:"usageCount"` - ExpiresAt *time.Time `db:"expires_at" json:"expiresAt,omitempty"` - CreatedAt time.Time `db:"created_at" json:"createdAt"` - RevokedAt *time.Time `db:"revoked_at" json:"revokedAt,omitempty"` + ID int64 `gorm:"primaryKey;autoIncrement:false" json:"id"` + UserID int64 `gorm:"index;not null" json:"userId"` + Name string `gorm:"type:varchar(255);not null" json:"name"` + TokenHash string `gorm:"uniqueIndex;type:varchar(255);not null" json:"-"` + TokenPrefix string `gorm:"index;type:varchar(50);not null" json:"tokenPrefix"` + Scopes *string `json:"scopes,omitempty"` + LastUsedAt *time.Time `json:"lastUsedAt,omitempty"` + LastUsedIP *string `json:"lastUsedIp,omitempty"` + UsageCount int `gorm:"default:0" json:"usageCount"` + ExpiresAt *time.Time `gorm:"index" json:"expiresAt,omitempty"` + CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` + RevokedAt *time.Time `json:"revokedAt,omitempty"` } func (t *ApiToken) ToJson() map[string]interface{} { @@ -38,94 +39,38 @@ func (t *ApiToken) ToJson() map[string]interface{} { } func (t *ApiToken) InsertInDB() error { - id := utils.GenerateRandomId() - t.ID = id - query := ` - INSERT INTO api_tokens ( - id, user_id, name, token_hash, token_prefix, scopes, expires_at - ) VALUES (?, ?, ?, ?, ?, ?, ?) - RETURNING created_at - ` - err := db.QueryRow(query, t.ID, t.UserID, t.Name, t.TokenHash, t.TokenPrefix, t.Scopes, t.ExpiresAt).Scan(&t.CreatedAt) - return err + t.ID = utils.GenerateRandomId() + result := db.Create(t) + return result.Error } func GetApiTokensByUserID(userID int64) ([]ApiToken, error) { var tokens []ApiToken - query := ` - SELECT id, user_id, name, token_hash, token_prefix, scopes, - last_used_at, last_used_ip, usage_count, expires_at, - created_at, revoked_at - FROM api_tokens - WHERE user_id = ? AND revoked_at IS NULL - ORDER BY created_at DESC - ` - rows, err := db.Query(query, userID) - if err != nil { - return nil, err - } - defer rows.Close() - - for rows.Next() { - var token ApiToken - err := rows.Scan( - &token.ID, &token.UserID, &token.Name, &token.TokenHash, &token.TokenPrefix, - &token.Scopes, &token.LastUsedAt, &token.LastUsedIP, &token.UsageCount, - &token.ExpiresAt, &token.CreatedAt, &token.RevokedAt, - ) - if err != nil { - return nil, err - } - tokens = append(tokens, token) - } - - return tokens, rows.Err() + result := db.Where("user_id=? AND revoked_at IS NULL", userID).Order("created_at DESC").Find(&tokens) + return tokens, result.Error } func GetApiTokenByHash(tokenHash string) (*ApiToken, error) { var token ApiToken - query := ` - SELECT id, user_id, name, token_hash, token_prefix, scopes, - last_used_at, last_used_ip, usage_count, expires_at, - created_at, revoked_at - FROM api_tokens - WHERE token_hash = ? AND revoked_at IS NULL - ` - err := db.QueryRow(query, tokenHash).Scan( - &token.ID, &token.UserID, &token.Name, &token.TokenHash, &token.TokenPrefix, - &token.Scopes, &token.LastUsedAt, &token.LastUsedIP, &token.UsageCount, - &token.ExpiresAt, &token.CreatedAt, &token.RevokedAt, - ) - if err != nil { - return nil, err + result := db.Where("token_hash=? AND revoked_at IS NULL", tokenHash).First(&token) + if result.Error != nil { + return nil, result.Error } return &token, nil } -func (t *ApiToken) UpdateUsage(ipAddress string) error { - query := ` - UPDATE api_tokens - SET last_used_at = CURRENT_TIMESTAMP, - last_used_ip = ?, - usage_count = usage_count + 1 - WHERE id = ? - ` - _, err := db.Exec(query, ipAddress, t.ID) - return err +func (t *ApiToken) UpdateUsage(lastUsedIP string) error { + return db.Model(t).Updates(map[string]interface{}{ + "last_used_at": time.Now(), + "last_used_ip": lastUsedIP, + "usage_count": gorm.Expr("usage_count + ?", 1), + }).Error } func (t *ApiToken) Revoke() error { - query := ` - UPDATE api_tokens - SET revoked_at = CURRENT_TIMESTAMP - WHERE id = ? - ` - _, err := db.Exec(query, t.ID) - return err + return db.Model(t).Update("revoked_at", time.Now()).Error } func DeleteApiToken(tokenID int64) error { - query := `DELETE FROM api_tokens WHERE id = ?` - _, err := db.Exec(query, tokenID) - return err + return db.Delete(&ApiToken{}, tokenID).Error } diff --git a/server/models/temp.go b/server/models/temp.go new file mode 100644 index 0000000..e69de29 From e12ae05eb9810edeacf2838ae98e031b69d94a33 Mon Sep 17 00:00:00 2001 From: Tanish Date: Sun, 11 Jan 2026 18:48:58 +0530 Subject: [PATCH 03/48] refactored app.go --- server/models/app.go | 292 ++++++++++++------------------------------- 1 file changed, 83 insertions(+), 209 deletions(-) diff --git a/server/models/app.go b/server/models/app.go index 58ef5fc..4788877 100644 --- a/server/models/app.go +++ b/server/models/app.go @@ -1,7 +1,6 @@ package models import ( - "database/sql" "fmt" "time" @@ -34,39 +33,33 @@ const ( ) type App struct { - ID int64 `db:"id" json:"id"` - ProjectID int64 `db:"project_id" json:"project_id"` - CreatedBy int64 `db:"created_by" json:"created_by"` - Name string `db:"name" json:"name"` - Description *string `db:"description" json:"description,omitempty"` - - AppType AppType `db:"app_type" json:"app_type"` - TemplateName *string `db:"template_name" json:"template_name,omitempty"` - - GitProviderID *int64 `db:"git_provider_id" json:"git_provider_id,omitempty"` - GitRepository *string `db:"git_repository" json:"git_repository,omitempty"` - GitBranch string `db:"git_branch" json:"git_branch,omitempty"` - GitCloneURL *string `db:"git_clone_url" json:"git_clone_url,omitempty"` - - DeploymentStrategy DeploymentStrategy `db:"deployment_strategy" json:"deployment_strategy"` - Port *int64 `db:"port" json:"port,omitempty"` - RootDirectory string `db:"root_directory" json:"root_directory,omitempty"` - BuildCommand *string `db:"build_command" json:"build_command,omitempty"` - StartCommand *string `db:"start_command" json:"start_command,omitempty"` - DockerfilePath *string `db:"dockerfile_path" json:"dockerfile_path,omitempty"` - - CPULimit *float64 `db:"cpu_limit" json:"cpu_limit,omitempty"` - MemoryLimit *int `db:"memory_limit" json:"memory_limit,omitempty"` - RestartPolicy RestartPolicy `db:"restart_policy" json:"restart_policy"` - - HealthcheckPath *string `db:"healthcheck_path" json:"healthcheck_path,omitempty"` - HealthcheckInterval int `db:"healthcheck_interval" json:"healthcheck_interval"` - HealthcheckTimeout int `db:"healthcheck_timeout" json:"healthcheck_timeout"` - HealthcheckRetries int `db:"healthcheck_retries" json:"healthcheck_retries"` - Status AppStatus `db:"status" json:"status"` - - CreatedAt time.Time `db:"created_at" json:"created_at"` - UpdatedAt time.Time `db:"updated_at" json:"updated_at"` + ID int64 `gorm:"primaryKey;autoIncrement:false" json:"id"` + ProjectID int64 `gorm:"uniqueIndex:idx_project_app_name;index;not null" json:"project_id"` + Name string `gorm:"uniqueIndex:idx_project_app_name;not null" json:"name"` + CreatedBy int64 `gorm:"index" json:"created_by"` + Description *string `json:"description,omitempty"` + AppType AppType `gorm:"default:'web';index" json:"app_type"` + TemplateName *string `json:"template_name,omitempty"` + GitProviderID *int64 `json:"git_provider_id,omitempty"` + GitRepository *string `json:"git_repository,omitempty"` + GitBranch string `gorm:"default:'main'" json:"git_branch,omitempty"` + GitCloneURL *string `json:"git_clone_url,omitempty"` + DeploymentStrategy DeploymentStrategy `gorm:"default:'auto'" json:"deployment_strategy"` + Port *int64 `json:"port,omitempty"` + RootDirectory string `gorm:"default:'.'" json:"root_directory,omitempty"` + BuildCommand *string `json:"build_command,omitempty"` + StartCommand *string `json:"start_command,omitempty"` + DockerfilePath *string `gorm:"default:'DOCKERFILE'" json:"dockerfile_path,omitempty"` + CPULimit *float64 `json:"cpu_limit,omitempty"` + MemoryLimit *int `json:"memory_limit,omitempty"` + RestartPolicy RestartPolicy `gorm:"default:'unless-stopped'" json:"restart_policy"` + HealthcheckPath *string `json:"healthcheck_path,omitempty"` + HealthcheckInterval int `gorm:"default:30" json:"healthcheck_interval"` + HealthcheckTimeout int `gorm:"default:10" json:"healthcheck_timeout"` + HealthcheckRetries int `gorm:"default:3" json:"healthcheck_retries"` + Status AppStatus `gorm:"default:'stopped';index" json:"status"` + CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` + UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } func (a *App) ToJson() map[string]interface{} { @@ -102,9 +95,7 @@ func (a *App) ToJson() map[string]interface{} { } func (a *App) InsertInDB() error { - id := utils.GenerateRandomId() - a.ID = id - + a.ID = utils.GenerateRandomId() if a.AppType == "" { a.AppType = AppTypeWeb } @@ -118,229 +109,112 @@ func (a *App) InsertInDB() error { a.Status = StatusStopped } - query := ` - INSERT INTO apps ( - id, name, description, project_id, created_by, app_type, template_name, - port, deployment_strategy, restart_policy, git_provider_id, git_repository, - git_branch, git_clone_url, root_directory, build_command, start_command, - dockerfile_path, cpu_limit, memory_limit, healthcheck_path, - healthcheck_interval, healthcheck_timeout, healthcheck_retries, status - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - RETURNING - created_at, updated_at - ` - err := db.QueryRow(query, - a.ID, a.Name, a.Description, a.ProjectID, a.CreatedBy, a.AppType, a.TemplateName, - a.Port, a.DeploymentStrategy, a.RestartPolicy, a.GitProviderID, a.GitRepository, - a.GitBranch, a.GitCloneURL, a.RootDirectory, a.BuildCommand, a.StartCommand, - a.DockerfilePath, a.CPULimit, a.MemoryLimit, a.HealthcheckPath, - a.HealthcheckInterval, a.HealthcheckTimeout, a.HealthcheckRetries, a.Status, - ).Scan(&a.CreatedAt, &a.UpdatedAt) - if err != nil { - return err - } - return nil + return db.Create(a).Error } func GetApplicationByProjectID(projectId int64) ([]App, error) { var apps []App - query := ` - SELECT id, project_id, created_by, name, description, app_type, template_name, - git_provider_id, git_repository, git_branch, git_clone_url, - deployment_strategy, port, root_directory, build_command, start_command, - dockerfile_path, cpu_limit, memory_limit, restart_policy, - healthcheck_path, healthcheck_interval, healthcheck_timeout, healthcheck_retries, - status, created_at, updated_at - FROM apps - WHERE project_id = ? - ` - rows, err := db.Query(query, projectId) - if err != nil { - return nil, err - } - defer rows.Close() - - for rows.Next() { - var app App - err := rows.Scan( - &app.ID, &app.ProjectID, &app.CreatedBy, &app.Name, &app.Description, - &app.AppType, &app.TemplateName, &app.GitProviderID, &app.GitRepository, - &app.GitBranch, &app.GitCloneURL, &app.DeploymentStrategy, &app.Port, - &app.RootDirectory, &app.BuildCommand, &app.StartCommand, &app.DockerfilePath, - &app.CPULimit, &app.MemoryLimit, &app.RestartPolicy, - &app.HealthcheckPath, &app.HealthcheckInterval, &app.HealthcheckTimeout, - &app.HealthcheckRetries, &app.Status, &app.CreatedAt, &app.UpdatedAt, - ) - if err != nil { - return nil, err - } - apps = append(apps, app) - } - if err = rows.Err(); err != nil { - return nil, err - } - return apps, nil + result := db.Where("project_id=?", projectId).Find(&apps) + return apps, result.Error } func GetApplicationByID(appId int64) (*App, error) { var app App - query := ` - SELECT id, project_id, created_by, name, description, app_type, template_name, - git_provider_id, git_repository, git_branch, git_clone_url, - deployment_strategy, port, root_directory, build_command, start_command, - dockerfile_path, cpu_limit, memory_limit, restart_policy, - healthcheck_path, healthcheck_interval, healthcheck_timeout, healthcheck_retries, - status, created_at, updated_at - FROM apps - WHERE id = ? - ` - err := db.QueryRow(query, appId).Scan( - &app.ID, &app.ProjectID, &app.CreatedBy, &app.Name, &app.Description, - &app.AppType, &app.TemplateName, &app.GitProviderID, &app.GitRepository, - &app.GitBranch, &app.GitCloneURL, &app.DeploymentStrategy, &app.Port, - &app.RootDirectory, &app.BuildCommand, &app.StartCommand, &app.DockerfilePath, - &app.CPULimit, &app.MemoryLimit, &app.RestartPolicy, - &app.HealthcheckPath, &app.HealthcheckInterval, &app.HealthcheckTimeout, - &app.HealthcheckRetries, &app.Status, &app.CreatedAt, &app.UpdatedAt, - ) - if err != nil { - return nil, err + result := db.First(&app, "id=?", appId) + if result.Error != nil { + return nil, result.Error } return &app, nil } -func (app *App) UpdateApplication() error { - query := ` - UPDATE apps - SET - name = ?, - description = ?, - app_type = ?, - template_name = ?, - git_provider_id = ?, - git_repository = ?, - git_branch = ?, - git_clone_url = ?, - deployment_strategy = ?, - port = ?, - root_directory = ?, - build_command = ?, - start_command = ?, - dockerfile_path = ?, - cpu_limit = ?, - memory_limit = ?, - restart_policy = ?, - healthcheck_path = ?, - healthcheck_interval = ?, - healthcheck_timeout = ?, - healthcheck_retries = ?, - status = ?, - updated_at = CURRENT_TIMESTAMP - WHERE id = ? - ` - _, err := db.Exec(query, - app.Name, app.Description, app.AppType, app.TemplateName, - app.GitProviderID, app.GitRepository, app.GitBranch, app.GitCloneURL, - app.DeploymentStrategy, app.Port, app.RootDirectory, - app.BuildCommand, app.StartCommand, app.DockerfilePath, - app.CPULimit, app.MemoryLimit, app.RestartPolicy, - app.HealthcheckPath, app.HealthcheckInterval, app.HealthcheckTimeout, - app.HealthcheckRetries, app.Status, app.ID, - ) - return err +func (a *App) UpdateApplication() error { + return db.Model(a).Select("Name", "Description", "AppType", "TemplateName", + "GitProviderID", "GitRepository", "GitBranch", "GitCloneURL", + "DeploymentStrategy", "Port", "RootDirectory", + "BuildCommand", "StartCommand", "DockerfilePath", + "CPULimit", "MemoryLimit", "RestartPolicy", + "HealthcheckPath", "HealthcheckInterval", "HealthcheckTimeout", "HealthcheckRetries", + "Status", "UpdatedAt").Updates(a).Error } func IsUserApplicationOwner(userId int64, appId int64) (bool, error) { - var createdBy int64 - err := db.QueryRow(` - SELECT created_by FROM apps WHERE id = ? - `, appId).Scan(&createdBy) - if err != nil { - return false, err - } - return createdBy == userId, nil + var count int64 + err := db.Model(&App{}). + Where("id = ? AND created_by = ?", appId, userId). + Count(&count).Error + + return count > 0, err } func FindApplicationIDByGitRepoAndBranch(gitRepo string, gitBranch string) (int64, error) { - var appId int64 - err := db.QueryRow(` - SELECT id FROM apps WHERE git_repository = ? AND git_branch = ? - `, gitRepo, gitBranch).Scan(&appId) + var app App + err := db.Select("id"). + Where("git_repository = ? AND git_branch = ?", gitRepo, gitBranch). + First(&app).Error + if err != nil { return 0, err } - return appId, nil + return app.ID, nil } func GetUserIDByAppID(appID int64) (*int64, error) { - query := ` - SELECT created_by FROM apps WHERE id = ? - ` - var userID int64 - err := db.QueryRow(query, appID).Scan(&userID) + var app App + err := db.Select("created_by").First(&app, appID).Error if err != nil { return nil, err } - return &userID, nil + return &app.CreatedBy, nil } -func GetAppIDByDeploymentID(depID int64) (int64, error) { - query := ` - SELECT app_id FROM deployments WHERE id = ? - ` - var appID int64 - err := db.QueryRow(query, depID).Scan(&appID) +func GetAppIDByDeploymentID(depId int64) (int64, error) { + var result struct { + AppID int64 + } + err := db.Table("deployments").Select("app_id").Where("id=?", depId).Scan(&result).Error if err != nil { return 0, err } - return appID, nil + return result.AppID, nil } func GetAppRepoInfo(appId int64) (string, string, int64, string, error) { - var repo sql.NullString - var branch sql.NullString - var name string - var projectId int64 - - err := db.QueryRow(` - SELECT git_repository, git_branch, project_id, name - FROM apps WHERE id = ? - `, appId).Scan(&repo, &branch, &projectId, &name) + var app App + err := db.Select("git_repository, git_branch, project_id, name"). + First(&app, appId).Error + if err != nil { return "", "", 0, "", err } - repoStr := "" - if repo.Valid { - repoStr = repo.String + repo := "" + if app.GitRepository != nil { + repo = *app.GitRepository } - branchStr := "" - if branch.Valid { - branchStr = branch.String - } - - return repoStr, branchStr, projectId, name, nil + return repo, app.GitBranch, app.ProjectID, app.Name, nil } -func GetAppRepoAndBranch(appID int64) (string, string, error) { - var repoName sql.NullString - var branch string - err := db.QueryRow(`SELECT git_repository, COALESCE(git_branch, 'main') FROM apps WHERE id = ?`, appID). - Scan(&repoName, &branch) +func getAppRepoAndBranch(appId int64) (string, string, error) { + var app App + err := db.Select("git_repository, git_branch").First(&app, appId).Error if err != nil { return "", "", err } - if !repoName.Valid || repoName.String == "" { + if app.GitRepository == nil || *app.GitRepository == "" { return "", "", fmt.Errorf("app has no git repository configured") } - return repoName.String, branch, nil + + branch := app.GitBranch + if branch == "" { + branch = "main" + } + + return *app.GitRepository, branch, nil } func DeleteApplication(appID int64) error { - query := `DELETE FROM apps WHERE id = ?` - _, err := db.Exec(query, appID) - return err + return db.Delete(&App{}, appID).Error } // if git_clone_url is set, it uses that From 37694b0981e973a76356c40b4aebc3d412616455 Mon Sep 17 00:00:00 2001 From: Tanish Date: Sun, 11 Jan 2026 20:35:47 +0530 Subject: [PATCH 04/48] auditlogs.go refactored --- server/models/appRepositories.go | 31 +-- server/models/auditLog.go | 322 ++++++------------------------- server/models/temp.go | 2 + 3 files changed, 86 insertions(+), 269 deletions(-) diff --git a/server/models/appRepositories.go b/server/models/appRepositories.go index 36bff21..477748a 100644 --- a/server/models/appRepositories.go +++ b/server/models/appRepositories.go @@ -1,16 +1,25 @@ package models -import "time" +import ( + "time" +) + +type AppRepositorySourceType string + +const ( + SourceGitProvider AppRepositorySourceType = "git_provider" + SourceGithubApp AppRepositorySourceType = "github_app" +) type AppRepositories struct { - ID int64 `json:"id"` - AppID int64 `json:"app_id"` - SourceType string `json:"source_type"` - SourceID int64 `json:"source_id"` - RepoFullName string `json:"repo_full_name"` - RepoURL string `json:"repo_url"` - Branch string `json:"branch"` - WebhookID int64 `json:"webhook_id"` - AutoDeploy bool `json:"auto_deploy"` - LastSyncedAt time.Time `json:"last_synced_at"` + ID int64 `gorm:"primaryKey;autoIncrement:true" json:"id"` + AppID int64 `gorm:"uniqueIndex:idx_app_repo_unique;not null;constraint:OnDelete:CASCADE" json:"app_id"` + SourceType AppRepositorySourceType `gorm:"not null" json:"source_type"` + SourceID int64 `gorm:"not null" json:"source_id"` + RepoFullName string `gorm:"uniqueIndex:idx_app_repo_unique;not null" json:"repo_full_name"` + RepoURL string `gorm:"not null" json:"repo_url"` + Branch string `gorm:"default:'main'" json:"branch"` + WebhookID int64 `json:"webhook_id"` + AutoDeploy bool `gorm:"default:false" json:"auto_deploy"` + LastSyncedAt *time.Time `json:"last_synced_at,omitempty"` } diff --git a/server/models/auditLog.go b/server/models/auditLog.go index c72fdeb..8850a80 100644 --- a/server/models/auditLog.go +++ b/server/models/auditLog.go @@ -1,25 +1,26 @@ package models import ( - "database/sql" "encoding/json" "time" + + "gorm.io/gorm" ) type AuditLog struct { - ID int64 `json:"id"` - UserID *int64 `json:"userId"` - Username *string `json:"username"` - Email *string `json:"email"` - Action string `json:"action"` - ResourceType string `json:"resourceType"` + ID int64 `gorm:"primaryKey;autoIncrement" json:"id"` + UserID *int64 `gorm:"index" json:"user_id"` + Username *string `gorm:"-" json:"username"` + Email *string `gorm:"-" json:"email"` + Action string `gorm:"not null" json:"action"` + ResourceType string `gorm:"not null" json:"resourceType"` ResourceID *int64 `json:"resourceId"` - ResourceName *string `json:"resourceName"` + ResourceName *string `gorm:"-" json:"resourceName"` Details *string `json:"details"` - IPAddress *string `json:"ipAddress"` - UserAgent *string `json:"userAgent"` - TriggerType string `json:"triggerType"` // "user", "webhook", "system" - CreatedAt time.Time `json:"createdAt"` + IPAddress *string `gorm:"-" json:"ipAddress"` + UserAgent *string `gorm:"-" json:"userAgent"` + TriggerType string `gorm:"-" json:"triggerType"` + CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` } type AuditLogDetails struct { @@ -30,56 +31,28 @@ type AuditLogDetails struct { } func (a *AuditLog) Create() error { - query := ` - INSERT INTO audit_logs (user_id, action, resource_type, resource_id, details, created_at) - VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP) - RETURNING id, created_at - ` - return db.QueryRow(query, a.UserID, a.Action, a.ResourceType, a.ResourceID, a.Details). - Scan(&a.ID, &a.CreatedAt) + return db.Create(a).Error } -func GetAllAuditLogs(limit, offset int) ([]AuditLog, error) { - query := ` - SELECT - al.id, - al.user_id, - u.username, - u.email, - al.action, - al.resource_type, - al.resource_id, - al.details, - al.created_at - FROM audit_logs al - LEFT JOIN users u ON al.user_id = u.id - ORDER BY al.created_at DESC - LIMIT ? OFFSET ? - ` - rows, err := db.Query(query, limit, offset) - if err != nil { - return nil, err - } - defer rows.Close() +//hlper function for join logic - var logs []AuditLog - for rows.Next() { - var log AuditLog - err := rows.Scan( - &log.ID, - &log.UserID, - &log.Username, - &log.Email, - &log.Action, - &log.ResourceType, - &log.ResourceID, - &log.Details, - &log.CreatedAt, - ) - if err != nil { - return nil, err - } +func getAuditLogsQuery() *gorm.DB { + return db.Table("audit_logs").Select(`audit_logs.id, + audit_logs.user_id, + users.username, + users.email, + audit_logs.action, + audit_logs.resource_type, + audit_logs.resource_id, + audit_logs.details, + audit_logs.created_at`).Joins("LEFT JOIN users ON audit_logs.user_id=users.id").Order("audit_logs.created_at DESC") + +} +// helper function to reduce repetition +func logHelper(logs []AuditLog) []AuditLog { + for i := range logs { + log := &logs[i] if log.UserID == nil { log.TriggerType = "system" if log.Details != nil && (*log.Details != "") { @@ -93,124 +66,44 @@ func GetAllAuditLogs(limit, offset int) ([]AuditLog, error) { } else { log.TriggerType = "user" } - - logs = append(logs, log) } - return logs, nil + return logs } -func GetAuditLogsByUser(userID int64, limit, offset int) ([]AuditLog, error) { - query := ` - SELECT - al.id, - al.user_id, - u.username, - u.email, - al.action, - al.resource_type, - al.resource_id, SELECT - al.details, - al.created_at - FROM audit_logs al - LEFT JOIN users u ON al.user_id = u.id - WHERE al.user_id = ? - ORDER BY al.created_at DESC - LIMIT ? OFFSET ? - ` - rows, err := db.Query(query, userID, limit, offset) +func GetAllAuditLogs(limit, offset int) ([]AuditLog, error) { + var logs []AuditLog + err := getAuditLogsQuery().Limit(limit).Offset(offset).Scan(&logs).Error if err != nil { return nil, err } - defer rows.Close() + return logHelper(logs), nil +} +func GetAuditLogsByUserID(userID int64, limit, offset int) ([]AuditLog, error) { var logs []AuditLog - for rows.Next() { - var log AuditLog - err := rows.Scan( - &log.ID, - &log.UserID, - &log.Username, - &log.Email, - &log.Action, - &log.ResourceType, - &log.ResourceID, - &log.Details, - &log.CreatedAt, - ) - if err != nil { - return nil, err - } - log.TriggerType = "user" - logs = append(logs, log) + err := getAuditLogsQuery().Where("audit_logs.user_id = ?", userID).Limit(limit).Offset(offset).Scan(&logs).Error + if err != nil { + return nil, err + } + for i := range logs { + logs[i].TriggerType = "user" } return logs, nil } func GetAuditLogsByResource(resourceType string, resourceID int64, limit, offset int) ([]AuditLog, error) { - query := ` - SELECT - al.id, - al.user_id, - u.username, - u.email, - al.action, - al.resource_type, - al.resource_id, - al.details, - al.created_at - FROM audit_logs al - LEFT JOIN users u ON al.user_id = u.id - WHERE al.resource_type = ? AND al.resource_id = ? - ORDER BY al.created_at DESC - LIMIT ? OFFSET ? - ` - rows, err := db.Query(query, resourceType, resourceID, limit, offset) + var logs []AuditLog + err := getAuditLogsQuery().Where("audit_logs.resource_type = ? AND audit_logs.resource_id = ?", resourceType, resourceID). + Limit(limit).Offset(offset).Scan(&logs).Error if err != nil { return nil, err } - defer rows.Close() - - var logs []AuditLog - for rows.Next() { - var log AuditLog - err := rows.Scan( - &log.ID, - &log.UserID, - &log.Username, - &log.Email, - &log.Action, - &log.ResourceType, - &log.ResourceID, - &log.Details, - &log.CreatedAt, - ) - if err != nil { - return nil, err - } - - if log.UserID == nil { - log.TriggerType = "system" - if log.Details != nil && (*log.Details != "") { - var detailsMap map[string]interface{} - if err := json.Unmarshal([]byte(*log.Details), &detailsMap); err == nil { - if triggerType, ok := detailsMap["trigger_type"].(string); ok { - log.TriggerType = triggerType - } - } - } - } else { - log.TriggerType = "user" - } - - logs = append(logs, log) - } - return logs, nil + return logHelper(logs), nil } -func GetAuditLogsCount() (int, error) { - query := `SELECT COUNT(*) FROM audit_logs` - var count int - err := db.QueryRow(query).Scan(&count) +func GetAuditLogsCount() (int64, error) { + var count int64 + err := db.Model(&AuditLog{}).Count(&count).Error return count, err } @@ -257,116 +150,29 @@ func LogSystemAudit(action, resourceType string, resourceID *int64, details inte } func GetAuditLogsByResourceType(resourceType string, limit, offset int) ([]AuditLog, error) { - query := ` - SELECT - al.id, - al.user_id, - u.username, - u.email, - al.action, - al.resource_type, - al.resource_id, - al.details, - al.created_at - FROM audit_logs al - LEFT JOIN users u ON al.user_id = u.id - WHERE al.resource_type = ? - ORDER BY al.created_at DESC - LIMIT ? OFFSET ? - ` - rows, err := db.Query(query, resourceType, limit, offset) + var logs []AuditLog + err := getAuditLogsQuery().Where("audit_logs.resource_type = ?", resourceType). + Limit(limit).Offset(offset).Scan(&logs).Error if err != nil { return nil, err } - defer rows.Close() - - var logs []AuditLog - for rows.Next() { - var log AuditLog - err := rows.Scan( - &log.ID, - &log.UserID, - &log.Username, - &log.Email, - &log.Action, - &log.ResourceType, - &log.ResourceID, - &log.Details, - &log.CreatedAt, - ) - if err != nil { - return nil, err - } - - if log.UserID == nil { - log.TriggerType = "system" - if log.Details != nil && (*log.Details != "") { - var detailsMap map[string]interface{} - if err := json.Unmarshal([]byte(*log.Details), &detailsMap); err == nil { - if triggerType, ok := detailsMap["trigger_type"].(string); ok { - log.TriggerType = triggerType - } - } - } - } else { - log.TriggerType = "user" - } - - logs = append(logs, log) - } - return logs, nil + return logHelper(logs), nil } func GetAuditLogByID(id int64) (*AuditLog, error) { - query := ` - SELECT - al.id, - al.user_id, - u.username, - u.email, - al.action, - al.resource_type, - al.resource_id, - al.details, - al.created_at - FROM audit_logs al - LEFT JOIN users u ON al.user_id = u.id - WHERE al.id = ? - ` - - var log AuditLog - err := db.QueryRow(query, id).Scan( - &log.ID, - &log.UserID, - &log.Username, - &log.Email, - &log.Action, - &log.ResourceType, - &log.ResourceID, - &log.Details, - &log.CreatedAt, - ) + var logs []AuditLog + err := getAuditLogsQuery(). + Where("audit_logs.id = ?", id). + Limit(1). + Scan(&logs).Error - if err == sql.ErrNoRows { - return nil, nil - } if err != nil { return nil, err } - - if log.UserID == nil { - log.TriggerType = "system" - if log.Details != nil && (*log.Details != "") { - var detailsMap map[string]interface{} - if err := json.Unmarshal([]byte(*log.Details), &detailsMap); err == nil { - if triggerType, ok := detailsMap["trigger_type"].(string); ok { - log.TriggerType = triggerType - } - } - } - } else { - log.TriggerType = "user" + if len(logs) == 0 { + return nil, nil } - return &log, nil + enrichedLogs := logHelper(logs) + return &enrichedLogs[0], nil } diff --git a/server/models/temp.go b/server/models/temp.go index e69de29..d6a05a4 100644 --- a/server/models/temp.go +++ b/server/models/temp.go @@ -0,0 +1,2 @@ +package models + From f2efa49e4857e3f20aac46717d05f58d431eafa1 Mon Sep 17 00:00:00 2001 From: 07calc Date: Mon, 12 Jan 2026 19:55:35 +0530 Subject: [PATCH 05/48] CHANGELOG --- CHANGELOG.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c108a67 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,47 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on Keep a Changelog, +and this project adheres to Semantic Versioning. + +## [1.0.3] - 2026-01-12 + +### Added +- deployment cleanup on startup + +### Fixed +- infinite logging when file not found + +### Changed +- logs UI +- replace raw git commands with go-git +- replace raw docker commands with moby + +--- + +## [1.0.2] - 2025-12-31 + +### Added +- individual docker container statistics +- owner's email as let's encrypt email on signup + +--- + +## [1.0.1] - 2025-12-27 + +### Added +- Versioning in dashboard +- `git_clone_url` field for apps + +### Fixed +- update script + +--- + +## [1.0.0] - 2025-12-24 + +### Added +- Initial release +- Core paas functionalities +- web dashboard +- service deployment via docker From 268ee7221f03c3270aaba51fc1cbcfba02d06782 Mon Sep 17 00:00:00 2001 From: 07calc Date: Tue, 13 Jan 2026 14:53:17 +0530 Subject: [PATCH 06/48] chore: update discord link --- README.md | 2 +- www/docs/.vitepress/theme/components/HeroInstall.vue | 2 +- www/docs/index.md | 2 +- www/docs/troubleshooting/index.md | 2 +- www/docs/troubleshooting/manual-update.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4287724..3724535 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ fyrer ## Community - [GitHub](https://github.com/corecollectives/mist) -- [Discord](https://discord.gg/kxK8XHR6) +- [Discord](https://discord.gg/hr6TCQDDkj) - [Documentation](https://trymist.cloud/guide) ## License diff --git a/www/docs/.vitepress/theme/components/HeroInstall.vue b/www/docs/.vitepress/theme/components/HeroInstall.vue index af77098..ac46687 100644 --- a/www/docs/.vitepress/theme/components/HeroInstall.vue +++ b/www/docs/.vitepress/theme/components/HeroInstall.vue @@ -13,7 +13,7 @@
Get Started View on GitHub - + diff --git a/www/docs/index.md b/www/docs/index.md index 5683885..e14f927 100644 --- a/www/docs/index.md +++ b/www/docs/index.md @@ -178,7 +178,7 @@ Mist is a **lightweight, self-hostable Platform-as-a-Service** designed for deve ## Community - [GitHub Repository](https://github.com/corecollectives/mist) -- [Discord Server](https://discord.gg/kxK8XHR6) +- [Discord Server](https://discord.gg/hr6TCQDDkj) - [Report Issues](https://github.com/corecollectives/mist/issues) - [Discussions](https://github.com/corecollectives/mist/discussions) diff --git a/www/docs/troubleshooting/index.md b/www/docs/troubleshooting/index.md index d481e3b..8609e49 100644 --- a/www/docs/troubleshooting/index.md +++ b/www/docs/troubleshooting/index.md @@ -626,7 +626,7 @@ sudo systemctl restart mist 3. **Community support:** - GitHub Issues: [github.com/corecollectives/mist/issues](https://github.com/corecollectives/mist/issues) -- Discord: [discord.gg/kxK8XHR6](https://discord.gg/kxK8XHR6) +- Discord: [discord.gg/kxK8XHR6](https://discord.gg/hr6TCQDDkj) 4. **Gather diagnostic information:** ```bash diff --git a/www/docs/troubleshooting/manual-update.md b/www/docs/troubleshooting/manual-update.md index 71a4945..62c9ad7 100644 --- a/www/docs/troubleshooting/manual-update.md +++ b/www/docs/troubleshooting/manual-update.md @@ -606,7 +606,7 @@ tail -50 /tmp/mist-install.log ### Community Support - **GitHub Issues:** [Report update issues](https://github.com/corecollectives/mist/issues) -- **Discord:** [Get real-time help](https://discord.gg/kxK8XHR6) +- **Discord:** [Get real-time help](https://discord.gg/hr6TCQDDkj) - **Discussions:** [Ask questions](https://github.com/corecollectives/mist/discussions) ### Include in Bug Report From 225aace2c8c84574e4a2067a3813b72797f836f1 Mon Sep 17 00:00:00 2001 From: 07calc Date: Tue, 13 Jan 2026 15:19:03 +0530 Subject: [PATCH 07/48] fix: bad sql query in --- server/models/deployment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/models/deployment.go b/server/models/deployment.go index 85fc5da..b9987bb 100644 --- a/server/models/deployment.go +++ b/server/models/deployment.go @@ -295,7 +295,7 @@ func GetIncompleteDeployments() ([]Deployment, error) { logs, build_logs_path, status, stage, progress, error_message, created_at, started_at, finished_at, duration, is_active, rolled_back_from FROM deployments - WHERE status = 'bulding' OR status = 'deploying' ? + WHERE status = 'building' OR status = 'deploying' ORDER BY created_at DESC ` From c7203d855086498650b556547be22cbfe425edde Mon Sep 17 00:00:00 2001 From: Tanish Date: Tue, 13 Jan 2026 21:44:02 +0530 Subject: [PATCH 08/48] rewritten backup cron and deployment files --- server/models/backup.go | 423 +++++++++++++++++-------- server/models/cron.go | 18 +- server/models/deployment.go | 611 ++++++++++++++++++++++++------------ server/models/temp.go | 2 - 4 files changed, 714 insertions(+), 340 deletions(-) diff --git a/server/models/backup.go b/server/models/backup.go index 0e3e535..6edd4cc 100644 --- a/server/models/backup.go +++ b/server/models/backup.go @@ -4,6 +4,7 @@ import ( "time" "github.com/corecollectives/mist/utils" + "gorm.io/gorm" ) type BackupType string @@ -30,34 +31,49 @@ const ( ) type Backup struct { - ID int64 `db:"id" json:"id"` - AppID int64 `db:"app_id" json:"appId"` - BackupType BackupType `db:"backup_type" json:"backupType"` - BackupName string `db:"backup_name" json:"backupName"` - FilePath string `db:"file_path" json:"filePath"` - FileSize *int64 `db:"file_size" json:"fileSize,omitempty"` - CompressionType string `db:"compression_type" json:"compressionType"` - DatabaseType *string `db:"database_type" json:"databaseType,omitempty"` - DatabaseVersion *string `db:"database_version" json:"databaseVersion,omitempty"` - StorageType StorageType `db:"storage_type" json:"storageType"` - StoragePath *string `db:"storage_path" json:"storagePath,omitempty"` - Status BackupStatus `db:"status" json:"status"` - Progress int `db:"progress" json:"progress"` - ErrorMessage *string `db:"error_message" json:"errorMessage,omitempty"` - Checksum *string `db:"checksum" json:"checksum,omitempty"` - ChecksumAlgorithm string `db:"checksum_algorithm" json:"checksumAlgorithm"` - IsVerified bool `db:"is_verified" json:"isVerified"` - VerifiedAt *time.Time `db:"verified_at" json:"verifiedAt,omitempty"` - CanRestore bool `db:"can_restore" json:"canRestore"` - LastRestoreAt *time.Time `db:"last_restore_at" json:"lastRestoreAt,omitempty"` - RestoreCount int `db:"restore_count" json:"restoreCount"` - RetentionDays *int `db:"retention_days" json:"retentionDays,omitempty"` - AutoDeleteAt *time.Time `db:"auto_delete_at" json:"autoDeleteAt,omitempty"` - CreatedBy *int64 `db:"created_by" json:"createdBy,omitempty"` - CreatedAt time.Time `db:"created_at" json:"createdAt"` - CompletedAt *time.Time `db:"completed_at" json:"completedAt,omitempty"` - Duration *int `db:"duration" json:"duration,omitempty"` - Notes *string `db:"notes" json:"notes,omitempty"` + ID int64 `gorm:"primaryKey;autoIncrement:false" json:"id"` + + AppID int64 `gorm:"index;not null;constraint:OnDelete:CASCADE" json:"appId"` + + BackupType BackupType `gorm:"index;not null" json:"backupType"` + BackupName string `gorm:"not null" json:"backupName"` + FilePath string `gorm:"not null" json:"filePath"` + FileSize *int64 `json:"fileSize,omitempty"` + + CompressionType string `gorm:"default:'gzip'" json:"compressionType"` + + DatabaseType *string `json:"databaseType,omitempty"` + DatabaseVersion *string `json:"databaseVersion,omitempty"` + + StorageType StorageType `gorm:"default:'local'" json:"storageType"` + StoragePath *string `json:"storagePath,omitempty"` + + Status BackupStatus `gorm:"default:'pending';index" json:"status"` + + Progress int `gorm:"default:0" json:"progress"` + ErrorMessage *string `json:"errorMessage,omitempty"` + Checksum *string `json:"checksum,omitempty"` + + ChecksumAlgorithm string `gorm:"default:'sha256'" json:"checksumAlgorithm"` + + IsVerified bool `gorm:"default:false" json:"isVerified"` + VerifiedAt *time.Time `json:"verifiedAt,omitempty"` + + CanRestore bool `gorm:"default:true" json:"canRestore"` + LastRestoreAt *time.Time `json:"lastRestoreAt,omitempty"` + + RestoreCount int `gorm:"default:0" json:"restoreCount"` + + RetentionDays *int `json:"retentionDays,omitempty"` + + AutoDeleteAt *time.Time `gorm:"index" json:"autoDeleteAt,omitempty"` + + CreatedBy *int64 `gorm:"constraint:OnDelete:SET NULL" json:"createdBy,omitempty"` + + CreatedAt time.Time `gorm:"autoCreateTime;index:,sort:desc" json:"createdAt"` + CompletedAt *time.Time `json:"completedAt,omitempty"` + Duration *int `json:"duration,omitempty"` + Notes *string `json:"notes,omitempty"` } func (b *Backup) ToJson() map[string]interface{} { @@ -94,127 +110,272 @@ func (b *Backup) ToJson() map[string]interface{} { } func (b *Backup) InsertInDB() error { - id := utils.GenerateRandomId() - b.ID = id - query := ` - INSERT INTO backups ( - id, app_id, backup_type, backup_name, file_path, - file_size, compression_type, database_type, database_version, - storage_type, storage_path, status, checksum_algorithm, - retention_days, auto_delete_at, created_by, notes - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - RETURNING created_at - ` - err := db.QueryRow(query, b.ID, b.AppID, b.BackupType, b.BackupName, b.FilePath, - b.FileSize, b.CompressionType, b.DatabaseType, b.DatabaseVersion, - b.StorageType, b.StoragePath, b.Status, b.ChecksumAlgorithm, - b.RetentionDays, b.AutoDeleteAt, b.CreatedBy, b.Notes).Scan(&b.CreatedAt) - return err + b.ID = utils.GenerateRandomId() + b.CanRestore = true + + return db.Create(b).Error } -func GetBackupsByAppID(appID int64) ([]Backup, error) { +func GetBackupsByAppID(appId int64) ([]Backup, error) { var backups []Backup - query := ` - SELECT id, app_id, backup_type, backup_name, file_path, file_size, - compression_type, database_type, database_version, - storage_type, storage_path, status, progress, error_message, - checksum, checksum_algorithm, is_verified, verified_at, - can_restore, last_restore_at, restore_count, - retention_days, auto_delete_at, created_by, created_at, - completed_at, duration, notes - FROM backups - WHERE app_id = ? AND status != 'deleted' - ORDER BY created_at DESC - ` - rows, err := db.Query(query, appID) - if err != nil { - return nil, err - } - defer rows.Close() - - for rows.Next() { - var backup Backup - err := rows.Scan( - &backup.ID, &backup.AppID, &backup.BackupType, &backup.BackupName, - &backup.FilePath, &backup.FileSize, &backup.CompressionType, - &backup.DatabaseType, &backup.DatabaseVersion, &backup.StorageType, - &backup.StoragePath, &backup.Status, &backup.Progress, &backup.ErrorMessage, - &backup.Checksum, &backup.ChecksumAlgorithm, &backup.IsVerified, &backup.VerifiedAt, - &backup.CanRestore, &backup.LastRestoreAt, &backup.RestoreCount, - &backup.RetentionDays, &backup.AutoDeleteAt, &backup.CreatedBy, &backup.CreatedAt, - &backup.CompletedAt, &backup.Duration, &backup.Notes, - ) - if err != nil { - return nil, err - } - backups = append(backups, backup) - } - - return backups, rows.Err() + result := db.Where("app_id=? AND status != ?", appId, BackupStatusDeleted).Order("created_at DESC").Find(&backups) + return backups, result.Error } -func GetBackupByID(backupID int64) (*Backup, error) { +func GetBackupByID(backupId int64) (*Backup, error) { var backup Backup - query := ` - SELECT id, app_id, backup_type, backup_name, file_path, file_size, - compression_type, database_type, database_version, - storage_type, storage_path, status, progress, error_message, - checksum, checksum_algorithm, is_verified, verified_at, - can_restore, last_restore_at, restore_count, - retention_days, auto_delete_at, created_by, created_at, - completed_at, duration, notes - FROM backups - WHERE id = ? - ` - err := db.QueryRow(query, backupID).Scan( - &backup.ID, &backup.AppID, &backup.BackupType, &backup.BackupName, - &backup.FilePath, &backup.FileSize, &backup.CompressionType, - &backup.DatabaseType, &backup.DatabaseVersion, &backup.StorageType, - &backup.StoragePath, &backup.Status, &backup.Progress, &backup.ErrorMessage, - &backup.Checksum, &backup.ChecksumAlgorithm, &backup.IsVerified, &backup.VerifiedAt, - &backup.CanRestore, &backup.LastRestoreAt, &backup.RestoreCount, - &backup.RetentionDays, &backup.AutoDeleteAt, &backup.CreatedBy, &backup.CreatedAt, - &backup.CompletedAt, &backup.Duration, &backup.Notes, - ) - if err != nil { - return nil, err + result := db.First(&backup, backupId) + if result.Error != nil { + return nil, result.Error } return &backup, nil } func (b *Backup) UpdateStatus(status BackupStatus, errorMsg *string) error { - query := ` - UPDATE backups - SET status = ?, error_message = ?, completed_at = CURRENT_TIMESTAMP - WHERE id = ? - ` - _, err := db.Exec(query, status, errorMsg, b.ID) - return err + update := map[string]interface{}{ + "status": status, + "error_message": errorMsg, + "completed_at": time.Now(), + } + return db.Model(b).Updates(update).Error } func (b *Backup) UpdateProgress(progress int) error { - query := `UPDATE backups SET progress = ? WHERE id = ?` - _, err := db.Exec(query, progress, b.ID) - return err + return db.Model(b).Update("progress", progress).Error } func (b *Backup) MarkAsRestored() error { - query := ` - UPDATE backups - SET last_restore_at = CURRENT_TIMESTAMP, - restore_count = restore_count + 1 - WHERE id = ? - ` - _, err := db.Exec(query, b.ID) - return err + return db.Model(b).Updates(map[string]interface{}{ + "last_restore_at": time.Now(), + "restore_count": gorm.Expr("restore_count + ?", 1), + }).Error } func DeleteExpiredBackups() error { - query := ` - UPDATE backups - SET status = 'deleted' - WHERE auto_delete_at IS NOT NULL AND auto_delete_at < CURRENT_TIMESTAMP AND status != 'deleted' - ` - _, err := db.Exec(query) - return err + return db.Where("auto_delete_at IS NOT NULL AND auto_delete_at < ? AND status != ?", time.Now(), BackupStatusDeleted).Update("status", BackupStatusDeleted).Error } + +//########################################################################################################################## + +//ARCHIVED CODE BELOW---------------------> + +// package models + +// import ( +// "time" + +// "github.com/corecollectives/mist/utils" +// ) + +// type BackupType string +// type BackupStatus string +// type StorageType string + +// const ( +// BackupTypeManual BackupType = "manual" +// BackupTypeScheduled BackupType = "scheduled" +// BackupTypePreDeployment BackupType = "pre_deployment" +// BackupTypeAutomatic BackupType = "automatic" + +// BackupStatusPending BackupStatus = "pending" +// BackupStatusInProgress BackupStatus = "in_progress" +// BackupStatusCompleted BackupStatus = "completed" +// BackupStatusFailed BackupStatus = "failed" +// BackupStatusDeleted BackupStatus = "deleted" + +// StorageTypeLocal StorageType = "local" +// StorageTypeS3 StorageType = "s3" +// StorageTypeGCS StorageType = "gcs" +// StorageTypeAzure StorageType = "azure" +// StorageTypeFTP StorageType = "ftp" +// ) + +// type Backup struct { +// ID int64 `db:"id" json:"id"` +// AppID int64 `db:"app_id" json:"appId"` +// BackupType BackupType `db:"backup_type" json:"backupType"` +// BackupName string `db:"backup_name" json:"backupName"` +// FilePath string `db:"file_path" json:"filePath"` +// FileSize *int64 `db:"file_size" json:"fileSize,omitempty"` +// CompressionType string `db:"compression_type" json:"compressionType"` +// DatabaseType *string `db:"database_type" json:"databaseType,omitempty"` +// DatabaseVersion *string `db:"database_version" json:"databaseVersion,omitempty"` +// StorageType StorageType `db:"storage_type" json:"storageType"` +// StoragePath *string `db:"storage_path" json:"storagePath,omitempty"` +// Status BackupStatus `db:"status" json:"status"` +// Progress int `db:"progress" json:"progress"` +// ErrorMessage *string `db:"error_message" json:"errorMessage,omitempty"` +// Checksum *string `db:"checksum" json:"checksum,omitempty"` +// ChecksumAlgorithm string `db:"checksum_algorithm" json:"checksumAlgorithm"` +// IsVerified bool `db:"is_verified" json:"isVerified"` +// VerifiedAt *time.Time `db:"verified_at" json:"verifiedAt,omitempty"` +// CanRestore bool `db:"can_restore" json:"canRestore"` +// LastRestoreAt *time.Time `db:"last_restore_at" json:"lastRestoreAt,omitempty"` +// RestoreCount int `db:"restore_count" json:"restoreCount"` +// RetentionDays *int `db:"retention_days" json:"retentionDays,omitempty"` +// AutoDeleteAt *time.Time `db:"auto_delete_at" json:"autoDeleteAt,omitempty"` +// CreatedBy *int64 `db:"created_by" json:"createdBy,omitempty"` +// CreatedAt time.Time `db:"created_at" json:"createdAt"` +// CompletedAt *time.Time `db:"completed_at" json:"completedAt,omitempty"` +// Duration *int `db:"duration" json:"duration,omitempty"` +// Notes *string `db:"notes" json:"notes,omitempty"` +// } + +// func (b *Backup) ToJson() map[string]interface{} { +// return map[string]interface{}{ +// "id": b.ID, +// "appId": b.AppID, +// "backupType": b.BackupType, +// "backupName": b.BackupName, +// "filePath": b.FilePath, +// "fileSize": b.FileSize, +// "compressionType": b.CompressionType, +// "databaseType": b.DatabaseType, +// "databaseVersion": b.DatabaseVersion, +// "storageType": b.StorageType, +// "storagePath": b.StoragePath, +// "status": b.Status, +// "progress": b.Progress, +// "errorMessage": b.ErrorMessage, +// "checksum": b.Checksum, +// "checksumAlgorithm": b.ChecksumAlgorithm, +// "isVerified": b.IsVerified, +// "verifiedAt": b.VerifiedAt, +// "canRestore": b.CanRestore, +// "lastRestoreAt": b.LastRestoreAt, +// "restoreCount": b.RestoreCount, +// "retentionDays": b.RetentionDays, +// "autoDeleteAt": b.AutoDeleteAt, +// "createdBy": b.CreatedBy, +// "createdAt": b.CreatedAt, +// "completedAt": b.CompletedAt, +// "duration": b.Duration, +// "notes": b.Notes, +// } +// } + +// func (b *Backup) InsertInDB() error { +// id := utils.GenerateRandomId() +// b.ID = id +// query := ` +// INSERT INTO backups ( +// id, app_id, backup_type, backup_name, file_path, +// file_size, compression_type, database_type, database_version, +// storage_type, storage_path, status, checksum_algorithm, +// retention_days, auto_delete_at, created_by, notes +// ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +// RETURNING created_at +// ` +// err := db.QueryRow(query, b.ID, b.AppID, b.BackupType, b.BackupName, b.FilePath, +// b.FileSize, b.CompressionType, b.DatabaseType, b.DatabaseVersion, +// b.StorageType, b.StoragePath, b.Status, b.ChecksumAlgorithm, +// b.RetentionDays, b.AutoDeleteAt, b.CreatedBy, b.Notes).Scan(&b.CreatedAt) +// return err +// } + +// func GetBackupsByAppID(appID int64) ([]Backup, error) { +// var backups []Backup +// query := ` +// SELECT id, app_id, backup_type, backup_name, file_path, file_size, +// compression_type, database_type, database_version, +// storage_type, storage_path, status, progress, error_message, +// checksum, checksum_algorithm, is_verified, verified_at, +// can_restore, last_restore_at, restore_count, +// retention_days, auto_delete_at, created_by, created_at, +// completed_at, duration, notes +// FROM backups +// WHERE app_id = ? AND status != 'deleted' +// ORDER BY created_at DESC +// ` +// rows, err := db.Query(query, appID) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// for rows.Next() { +// var backup Backup +// err := rows.Scan( +// &backup.ID, &backup.AppID, &backup.BackupType, &backup.BackupName, +// &backup.FilePath, &backup.FileSize, &backup.CompressionType, +// &backup.DatabaseType, &backup.DatabaseVersion, &backup.StorageType, +// &backup.StoragePath, &backup.Status, &backup.Progress, &backup.ErrorMessage, +// &backup.Checksum, &backup.ChecksumAlgorithm, &backup.IsVerified, &backup.VerifiedAt, +// &backup.CanRestore, &backup.LastRestoreAt, &backup.RestoreCount, +// &backup.RetentionDays, &backup.AutoDeleteAt, &backup.CreatedBy, &backup.CreatedAt, +// &backup.CompletedAt, &backup.Duration, &backup.Notes, +// ) +// if err != nil { +// return nil, err +// } +// backups = append(backups, backup) +// } + +// return backups, rows.Err() +// } + +// func GetBackupByID(backupID int64) (*Backup, error) { +// var backup Backup +// query := ` +// SELECT id, app_id, backup_type, backup_name, file_path, file_size, +// compression_type, database_type, database_version, +// storage_type, storage_path, status, progress, error_message, +// checksum, checksum_algorithm, is_verified, verified_at, +// can_restore, last_restore_at, restore_count, +// retention_days, auto_delete_at, created_by, created_at, +// completed_at, duration, notes +// FROM backups +// WHERE id = ? +// ` +// err := db.QueryRow(query, backupID).Scan( +// &backup.ID, &backup.AppID, &backup.BackupType, &backup.BackupName, +// &backup.FilePath, &backup.FileSize, &backup.CompressionType, +// &backup.DatabaseType, &backup.DatabaseVersion, &backup.StorageType, +// &backup.StoragePath, &backup.Status, &backup.Progress, &backup.ErrorMessage, +// &backup.Checksum, &backup.ChecksumAlgorithm, &backup.IsVerified, &backup.VerifiedAt, +// &backup.CanRestore, &backup.LastRestoreAt, &backup.RestoreCount, +// &backup.RetentionDays, &backup.AutoDeleteAt, &backup.CreatedBy, &backup.CreatedAt, +// &backup.CompletedAt, &backup.Duration, &backup.Notes, +// ) +// if err != nil { +// return nil, err +// } +// return &backup, nil +// } + +// func (b *Backup) UpdateStatus(status BackupStatus, errorMsg *string) error { +// query := ` +// UPDATE backups +// SET status = ?, error_message = ?, completed_at = CURRENT_TIMESTAMP +// WHERE id = ? +// ` +// _, err := db.Exec(query, status, errorMsg, b.ID) +// return err +// } + +// func (b *Backup) UpdateProgress(progress int) error { +// query := `UPDATE backups SET progress = ? WHERE id = ?` +// _, err := db.Exec(query, progress, b.ID) +// return err +// } + +// func (b *Backup) MarkAsRestored() error { +// query := ` +// UPDATE backups +// SET last_restore_at = CURRENT_TIMESTAMP, +// restore_count = restore_count + 1 +// WHERE id = ? +// ` +// _, err := db.Exec(query, b.ID) +// return err +// } + +// func DeleteExpiredBackups() error { +// query := ` +// UPDATE backups +// SET status = 'deleted' +// WHERE auto_delete_at IS NOT NULL AND auto_delete_at < CURRENT_TIMESTAMP AND status != 'deleted' +// ` +// _, err := db.Exec(query) +// return err +// } diff --git a/server/models/cron.go b/server/models/cron.go index 1eb6aa2..262a4db 100644 --- a/server/models/cron.go +++ b/server/models/cron.go @@ -3,13 +3,13 @@ package models import "time" type Cron struct { - ID int64 `json:"id"` - AppID int64 `json:"app_id"` - Name string `json:"name"` - Schedule string `json:"schedule"` - Command string `json:"command"` - LastRun time.Time `json:"last_run"` - NextRun time.Time `json:"next_run"` - Enable bool `json:"enable"` - CreatedAt time.Time `json:"created_at"` + ID int64 `gorm:"primaryKey;autoIncrement:true" json:"id"` + AppID int64 `gorm:"index;constraint:OnDelete:CASCADE;not null" json:"app_id"` + Name string `gorm:"index;not null" json:"name"` + Schedule string `gorm:"not null" json:"schedule"` + Command string `gorm:"not null" json:"command"` + LastRun *time.Time `gorm:"type:timestamp" json:"last_run"` + NextRun *time.Time `gorm:"type:timestamp" json:"next_run"` + Enable bool `gorm:"default:true" json:"enable"` + CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` } diff --git a/server/models/deployment.go b/server/models/deployment.go index 1572cba..e79c41b 100644 --- a/server/models/deployment.go +++ b/server/models/deployment.go @@ -4,6 +4,7 @@ import ( "time" "github.com/corecollectives/mist/utils" + "gorm.io/gorm" ) type DeploymentStatus string @@ -19,28 +20,42 @@ const ( ) type Deployment struct { - ID int64 `db:"id" json:"id"` - AppID int64 `db:"app_id" json:"app_id"` - CommitHash string `db:"commit_hash" json:"commit_hash"` - CommitMessage *string `db:"commit_message" json:"commit_message,omitempty"` - CommitAuthor *string `db:"commit_author" json:"commit_author,omitempty"` - TriggeredBy *int64 `db:"triggered_by" json:"triggered_by,omitempty"` - DeploymentNumber *int `db:"deployment_number" json:"deployment_number,omitempty"` - ContainerID *string `db:"container_id" json:"container_id,omitempty"` - ContainerName *string `db:"container_name" json:"container_name,omitempty"` - ImageTag *string `db:"image_tag" json:"image_tag,omitempty"` - Logs *string `db:"logs" json:"logs,omitempty"` - BuildLogsPath *string `db:"build_logs_path" json:"build_logs_path,omitempty"` - Status DeploymentStatus `db:"status" json:"status"` - Stage string `db:"stage" json:"stage"` - Progress int `db:"progress" json:"progress"` - ErrorMessage *string `db:"error_message" json:"error_message,omitempty"` - CreatedAt time.Time `db:"created_at" json:"created_at"` - StartedAt *time.Time `db:"started_at" json:"started_at,omitempty"` - FinishedAt *time.Time `db:"finished_at" json:"finished_at,omitempty"` - Duration *int `db:"duration" json:"duration,omitempty"` - IsActive bool `db:"is_active" json:"is_active"` - RolledBackFrom *int64 `db:"rolled_back_from" json:"rolled_back_from,omitempty"` + ID int64 `gorm:"primaryKey;autoIncrement:false" json:"id"` + + AppID int64 `gorm:"index:idx_deployments_app_id;not null;constraint:OnDelete:CASCADE" json:"app_id"` + + CommitHash string `gorm:"index:idx_deployments_commit_hash;not null" json:"commit_hash"` + + CommitMessage *string `json:"commit_message,omitempty"` + CommitAuthor *string `json:"commit_author,omitempty"` + + TriggeredBy *int64 `gorm:"constraint:OnDelete:SET NULL" json:"triggered_by,omitempty"` + + DeploymentNumber *int `json:"deployment_number,omitempty"` + + ContainerID *string `json:"container_id,omitempty"` + ContainerName *string `json:"container_name,omitempty"` + ImageTag *string `json:"image_tag,omitempty"` + + Logs *string `json:"logs,omitempty"` + BuildLogsPath *string `json:"build_logs_path,omitempty"` + + Status DeploymentStatus `gorm:"default:'pending';index:idx_deployments_status" json:"status"` + + Stage string `gorm:"default:'pending'" json:"stage"` + Progress int `gorm:"default:0" json:"progress"` + + ErrorMessage *string `json:"error_message,omitempty"` + + CreatedAt time.Time `gorm:"autoCreateTime;index:idx_deployments_created_at,sort:desc" json:"created_at"` + + StartedAt *time.Time `json:"started_at,omitempty"` + FinishedAt *time.Time `json:"finished_at,omitempty"` + Duration *int `json:"duration,omitempty"` + + IsActive bool `gorm:"default:false;index:idx_deployments_is_active" json:"is_active"` + + RolledBackFrom *int64 `gorm:"constraint:OnDelete:SET NULL" json:"rolled_back_from,omitempty"` } func (d *Deployment) ToJson() map[string]interface{} { @@ -71,219 +86,419 @@ func (d *Deployment) ToJson() map[string]interface{} { } func GetDeploymentsByAppID(appID int64) ([]Deployment, error) { - query := ` - SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, - deployment_number, container_id, container_name, image_tag, - logs, build_logs_path, status, stage, progress, error_message, - created_at, started_at, finished_at, duration, is_active, rolled_back_from - FROM deployments - WHERE app_id = ? - ORDER BY created_at DESC - ` - - rows, err := db.Query(query, appID) - if err != nil { - return nil, err - } - defer rows.Close() - var deployments []Deployment - for rows.Next() { - var d Deployment - if err := rows.Scan( - &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, - &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, - &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, - &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, - &d.IsActive, &d.RolledBackFrom, - ); err != nil { - return nil, err - } - deployments = append(deployments, d) - } - - if err := rows.Err(); err != nil { - return nil, err - } - - return deployments, nil + result := db.Where("app_id = ?", appID).Order("created_at DESC").Find(&deployments) + return deployments, result.Error } func (d *Deployment) CreateDeployment() error { - id := utils.GenerateRandomId() - d.ID = id - - var maxDeploymentNum int - err := db.QueryRow(`SELECT COALESCE(MAX(deployment_number), 0) FROM deployments WHERE app_id = ?`, d.AppID).Scan(&maxDeploymentNum) - if err == nil { - deploymentNum := maxDeploymentNum + 1 - d.DeploymentNumber = &deploymentNum - } - - query := ` - INSERT INTO deployments ( - id, app_id, commit_hash, commit_message, commit_author, triggered_by, - deployment_number, status, stage, progress - ) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', 'pending', 0) - RETURNING created_at - ` - err = db.QueryRow(query, d.ID, d.AppID, d.CommitHash, d.CommitMessage, - d.CommitAuthor, d.TriggeredBy, d.DeploymentNumber).Scan(&d.CreatedAt) - if err != nil { - return err + d.ID = utils.GenerateRandomId() + var maxDepNum *int + result := db.Model(&Deployment{}). + Where("app_id = ?", d.AppID). + Pluck("MAX(deployment_number)", &maxDepNum) + + currentNum := 0 + if result.Error == nil && maxDepNum != nil { + currentNum = *maxDepNum } + newNum := currentNum + 1 + d.DeploymentNumber = &newNum d.Status = DeploymentStatusPending d.Stage = "pending" d.Progress = 0 d.IsActive = false - return nil + + return db.Create(d).Error } func GetDeploymentByID(depID int64) (*Deployment, error) { - query := ` - SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, - deployment_number, container_id, container_name, image_tag, - logs, build_logs_path, status, stage, progress, error_message, - created_at, started_at, finished_at, duration, is_active, rolled_back_from - FROM deployments - WHERE id = ? - ` - - var d Deployment - if err := db.QueryRow(query, depID).Scan( - &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, - &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, - &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, - &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, - &d.IsActive, &d.RolledBackFrom, - ); err != nil { - return nil, err + var deployment Deployment + result := db.First(&deployment, "id = ?", depID) + if result.Error != nil { + return nil, result.Error } - - return &d, nil + return &deployment, nil } func GetDeploymentByCommitHash(commitHash string) (*Deployment, error) { - query := ` - SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, - deployment_number, container_id, container_name, image_tag, - logs, build_logs_path, status, stage, progress, error_message, - created_at, started_at, finished_at, duration, is_active, rolled_back_from - FROM deployments - WHERE commit_hash = ? - LIMIT 1 - ` - var d Deployment - if err := db.QueryRow(query, commitHash).Scan( - &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, - &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, - &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, - &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, - &d.IsActive, &d.RolledBackFrom, - ); err != nil { - return nil, err + var deployment Deployment + result := db.First(&deployment, "commit_hash = ?", commitHash) + if result.Error != nil { + return nil, result.Error } - - return &d, nil - + return &deployment, nil } func GetDeploymentByAppIDAndCommitHash(appID int64, commitHash string) (*Deployment, error) { - query := ` - SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, - deployment_number, container_id, container_name, image_tag, - logs, build_logs_path, status, stage, progress, error_message, - created_at, started_at, finished_at, duration, is_active, rolled_back_from - FROM deployments - WHERE app_id = ? AND commit_hash = ? - LIMIT 1 - ` - var d Deployment - if err := db.QueryRow(query, appID, commitHash).Scan( - &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, - &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, - &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, - &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, - &d.IsActive, &d.RolledBackFrom, - ); err != nil { - return nil, err + var deployment Deployment + result := db.First(&deployment, "app_id = ? AND commit_hash = ?", appID, commitHash) + if result.Error != nil { + return nil, result.Error } - - return &d, nil - + return &deployment, nil } - func GetActiveDeploymentByAppID(appID int64) (*Deployment, error) { - query := ` - SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, - deployment_number, container_id, container_name, image_tag, - logs, build_logs_path, status, stage, progress, error_message, - created_at, started_at, finished_at, duration, is_active, rolled_back_from - FROM deployments - WHERE app_id = ? AND is_active = 1 - LIMIT 1 - ` - - var d Deployment - if err := db.QueryRow(query, appID).Scan( - &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, - &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, - &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, - &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, - &d.IsActive, &d.RolledBackFrom, - ); err != nil { - return nil, err + var deployment Deployment + err := db.Where("app_id = ? AND is_active = ?", appID, true).First(&deployment) + if err.Error != nil { + return nil, err.Error } - - return &d, nil + return &deployment, nil } func GetCommitHashByDeploymentID(depID int64) (string, error) { - var commitHash string - err := db.QueryRow(`SELECT commit_hash FROM deployments WHERE id = ?`, depID).Scan(&commitHash) - if err != nil { - return "", err + var d Deployment + result := db.Select("commit_hash").First(&d, "id = ?", depID) + if result.Error != nil { + return "", result.Error } - return commitHash, nil + return d.CommitHash, nil } func UpdateDeploymentStatus(depID int64, status, stage string, progress int, errorMsg *string) error { - query := ` - UPDATE deployments - SET status = ?, stage = ?, progress = ?, error_message = ?, - finished_at = CASE WHEN ? IN ('success', 'failed', 'stopped') THEN CURRENT_TIMESTAMP ELSE finished_at END, - duration = CASE WHEN ? IN ('success', 'failed', 'stopped') THEN - CAST((julianday(CURRENT_TIMESTAMP) - julianday(started_at)) * 86400 AS INTEGER) - ELSE duration END - WHERE id = ? - ` - _, err := db.Exec(query, status, stage, progress, errorMsg, status, status, depID) - return err -} + var d Deployment + result := db.First(&d, "id = ?", depID) + if result.Error != nil { + return result.Error + } + updates := map[string]interface{}{ + "status": status, + "stage": stage, + "progress": progress, + "error_message": errorMsg, + } + if status == string(DeploymentStatusFailed) || status == string(DeploymentStatusSuccess) || status == string(DeploymentStatusStopped) { + now := time.Now() + updates["finished_at"] = &now + if d.StartedAt != nil { + duration := int(now.Sub(*d.StartedAt).Seconds()) + updates["duration"] = &duration + } + } + return db.Model(d).Updates(updates).Error +} func MarkDeploymentStarted(depID int64) error { - query := `UPDATE deployments SET started_at = CURRENT_TIMESTAMP WHERE id = ?` - _, err := db.Exec(query, depID) - return err + now := time.Now() + return db.Model(&Deployment{}).Where("id = ?", depID).Update("started_at", now).Error } func MarkDeploymentActive(depID int64, appID int64) error { - _, err := db.Exec(`UPDATE deployments SET is_active = 0 WHERE app_id = ?`, appID) - if err != nil { - return err - } - - _, err = db.Exec(`UPDATE deployments SET is_active = 1 WHERE id = ?`, depID) - return err + return db.Transaction(func(tx *gorm.DB) error { + err := tx.Model(&Deployment{}).Where("app_id=?", appID).Update("is_active", false).Error + if err != nil { + return err + } + err = tx.Model(&Deployment{}).Where("id = ?", depID).Update("is_active", true).Error + if err != nil { + return err + } + return nil + }) } - func UpdateContainerInfo(depID int64, containerID, containerName, imageTag string) error { - query := ` - UPDATE deployments - SET container_id = ?, container_name = ?, image_tag = ? - WHERE id = ? - ` - _, err := db.Exec(query, containerID, containerName, imageTag, depID) - return err + updates := map[string]interface{}{ + "container_id": containerID, + "container_name": containerName, + "image_tag": imageTag, + } + return db.Model(&Deployment{}).Where("id = ?", depID).Updates(updates).Error } + + + + +//############################################################################################################# +//ARCHIVED CODE BELOW------> + +// package models + +// import ( +// "time" + +// "github.com/corecollectives/mist/utils" +// ) + +// type DeploymentStatus string + +// const ( +// DeploymentStatusPending DeploymentStatus = "pending" +// DeploymentStatusBuilding DeploymentStatus = "building" +// DeploymentStatusDeploying DeploymentStatus = "deploying" +// DeploymentStatusSuccess DeploymentStatus = "success" +// DeploymentStatusFailed DeploymentStatus = "failed" +// DeploymentStatusStopped DeploymentStatus = "stopped" +// DeploymentStatusRolledBack DeploymentStatus = "rolled_back" +// ) + +// type Deployment struct { +// ID int64 `db:"id" json:"id"` +// AppID int64 `db:"app_id" json:"app_id"` +// CommitHash string `db:"commit_hash" json:"commit_hash"` +// CommitMessage *string `db:"commit_message" json:"commit_message,omitempty"` +// CommitAuthor *string `db:"commit_author" json:"commit_author,omitempty"` +// TriggeredBy *int64 `db:"triggered_by" json:"triggered_by,omitempty"` +// DeploymentNumber *int `db:"deployment_number" json:"deployment_number,omitempty"` +// ContainerID *string `db:"container_id" json:"container_id,omitempty"` +// ContainerName *string `db:"container_name" json:"container_name,omitempty"` +// ImageTag *string `db:"image_tag" json:"image_tag,omitempty"` +// Logs *string `db:"logs" json:"logs,omitempty"` +// BuildLogsPath *string `db:"build_logs_path" json:"build_logs_path,omitempty"` +// Status DeploymentStatus `db:"status" json:"status"` +// Stage string `db:"stage" json:"stage"` +// Progress int `db:"progress" json:"progress"` +// ErrorMessage *string `db:"error_message" json:"error_message,omitempty"` +// CreatedAt time.Time `db:"created_at" json:"created_at"` +// StartedAt *time.Time `db:"started_at" json:"started_at,omitempty"` +// FinishedAt *time.Time `db:"finished_at" json:"finished_at,omitempty"` +// Duration *int `db:"duration" json:"duration,omitempty"` +// IsActive bool `db:"is_active" json:"is_active"` +// RolledBackFrom *int64 `db:"rolled_back_from" json:"rolled_back_from,omitempty"` +// } + +// func (d *Deployment) ToJson() map[string]interface{} { +// return map[string]interface{}{ +// "id": d.ID, +// "appId": d.AppID, +// "commitHash": d.CommitHash, +// "commitMessage": d.CommitMessage, +// "commitAuthor": d.CommitAuthor, +// "triggeredBy": d.TriggeredBy, +// "deploymentNumber": d.DeploymentNumber, +// "containerId": d.ContainerID, +// "containerName": d.ContainerName, +// "imageTag": d.ImageTag, +// "logs": d.Logs, +// "buildLogsPath": d.BuildLogsPath, +// "status": d.Status, +// "stage": d.Stage, +// "progress": d.Progress, +// "errorMessage": d.ErrorMessage, +// "createdAt": d.CreatedAt, +// "startedAt": d.StartedAt, +// "finishedAt": d.FinishedAt, +// "duration": d.Duration, +// "isActive": d.IsActive, +// "rolledBackFrom": d.RolledBackFrom, +// } +// } + +// func GetDeploymentsByAppID(appID int64) ([]Deployment, error) { +// query := ` +// SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, +// deployment_number, container_id, container_name, image_tag, +// logs, build_logs_path, status, stage, progress, error_message, +// created_at, started_at, finished_at, duration, is_active, rolled_back_from +// FROM deployments +// WHERE app_id = ? +// ORDER BY created_at DESC +// ` + +// rows, err := db.Query(query, appID) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// var deployments []Deployment +// for rows.Next() { +// var d Deployment +// if err := rows.Scan( +// &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, +// &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, +// &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, +// &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, +// &d.IsActive, &d.RolledBackFrom, +// ); err != nil { +// return nil, err +// } +// deployments = append(deployments, d) +// } + +// if err := rows.Err(); err != nil { +// return nil, err +// } + +// return deployments, nil +// } + +// func (d *Deployment) CreateDeployment() error { +// id := utils.GenerateRandomId() +// d.ID = id + +// var maxDeploymentNum int +// err := db.QueryRow(`SELECT COALESCE(MAX(deployment_number), 0) FROM deployments WHERE app_id = ?`, d.AppID).Scan(&maxDeploymentNum) +// if err == nil { +// deploymentNum := maxDeploymentNum + 1 +// d.DeploymentNumber = &deploymentNum +// } + +// query := ` +// INSERT INTO deployments ( +// id, app_id, commit_hash, commit_message, commit_author, triggered_by, +// deployment_number, status, stage, progress +// ) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', 'pending', 0) +// RETURNING created_at +// ` +// err = db.QueryRow(query, d.ID, d.AppID, d.CommitHash, d.CommitMessage, +// d.CommitAuthor, d.TriggeredBy, d.DeploymentNumber).Scan(&d.CreatedAt) +// if err != nil { +// return err +// } + +// d.Status = DeploymentStatusPending +// d.Stage = "pending" +// d.Progress = 0 +// d.IsActive = false +// return nil +// } + +// func GetDeploymentByID(depID int64) (*Deployment, error) { +// query := ` +// SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, +// deployment_number, container_id, container_name, image_tag, +// logs, build_logs_path, status, stage, progress, error_message, +// created_at, started_at, finished_at, duration, is_active, rolled_back_from +// FROM deployments +// WHERE id = ? +// ` + +// var d Deployment +// if err := db.QueryRow(query, depID).Scan( +// &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, +// &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, +// &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, +// &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, +// &d.IsActive, &d.RolledBackFrom, +// ); err != nil { +// return nil, err +// } + +// return &d, nil +// } + +// func GetDeploymentByCommitHash(commitHash string) (*Deployment, error) { +// query := ` +// SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, +// deployment_number, container_id, container_name, image_tag, +// logs, build_logs_path, status, stage, progress, error_message, +// created_at, started_at, finished_at, duration, is_active, rolled_back_from +// FROM deployments +// WHERE commit_hash = ? +// LIMIT 1 +// ` +// var d Deployment +// if err := db.QueryRow(query, commitHash).Scan( +// &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, +// &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, +// &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, +// &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, +// &d.IsActive, &d.RolledBackFrom, +// ); err != nil { +// return nil, err +// } + +// return &d, nil + +// } + +// func GetDeploymentByAppIDAndCommitHash(appID int64, commitHash string) (*Deployment, error) { +// query := ` +// SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, +// deployment_number, container_id, container_name, image_tag, +// logs, build_logs_path, status, stage, progress, error_message, +// created_at, started_at, finished_at, duration, is_active, rolled_back_from +// FROM deployments +// WHERE app_id = ? AND commit_hash = ? +// LIMIT 1 +// ` +// var d Deployment +// if err := db.QueryRow(query, appID, commitHash).Scan( +// &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, +// &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, +// &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, +// &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, +// &d.IsActive, &d.RolledBackFrom, +// ); err != nil { +// return nil, err +// } + +// return &d, nil + +// } + +// func GetActiveDeploymentByAppID(appID int64) (*Deployment, error) { +// query := ` +// SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, +// deployment_number, container_id, container_name, image_tag, +// logs, build_logs_path, status, stage, progress, error_message, +// created_at, started_at, finished_at, duration, is_active, rolled_back_from +// FROM deployments +// WHERE app_id = ? AND is_active = 1 +// LIMIT 1 +// ` + +// var d Deployment +// if err := db.QueryRow(query, appID).Scan( +// &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, +// &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, +// &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, +// &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, +// &d.IsActive, &d.RolledBackFrom, +// ); err != nil { +// return nil, err +// } + +// return &d, nil +// } + +// func GetCommitHashByDeploymentID(depID int64) (string, error) { +// var commitHash string +// err := db.QueryRow(`SELECT commit_hash FROM deployments WHERE id = ?`, depID).Scan(&commitHash) +// if err != nil { +// return "", err +// } +// return commitHash, nil +// } + +// func UpdateDeploymentStatus(depID int64, status, stage string, progress int, errorMsg *string) error { +// query := ` +// UPDATE deployments +// SET status = ?, stage = ?, progress = ?, error_message = ?, +// finished_at = CASE WHEN ? IN ('success', 'failed', 'stopped') THEN CURRENT_TIMESTAMP ELSE finished_at END, +// duration = CASE WHEN ? IN ('success', 'failed', 'stopped') THEN +// CAST((julianday(CURRENT_TIMESTAMP) - julianday(started_at)) * 86400 AS INTEGER) +// ELSE duration END +// WHERE id = ? +// ` +// _, err := db.Exec(query, status, stage, progress, errorMsg, status, status, depID) +// return err +// } + +// func MarkDeploymentStarted(depID int64) error { +// query := `UPDATE deployments SET started_at = CURRENT_TIMESTAMP WHERE id = ?` +// _, err := db.Exec(query, depID) +// return err +// } + +// func MarkDeploymentActive(depID int64, appID int64) error { +// _, err := db.Exec(`UPDATE deployments SET is_active = 0 WHERE app_id = ?`, appID) +// if err != nil { +// return err +// } + +// _, err = db.Exec(`UPDATE deployments SET is_active = 1 WHERE id = ?`, depID) +// return err +// } + +// func UpdateContainerInfo(depID int64, containerID, containerName, imageTag string) error { +// query := ` +// UPDATE deployments +// SET container_id = ?, container_name = ?, image_tag = ? +// WHERE id = ? +// ` +// _, err := db.Exec(query, containerID, containerName, imageTag, depID) +// return err +// } diff --git a/server/models/temp.go b/server/models/temp.go index d6a05a4..e69de29 100644 --- a/server/models/temp.go +++ b/server/models/temp.go @@ -1,2 +0,0 @@ -package models - From bd396dd6ed2da0a8adfb4b0416864dbc1d912f13 Mon Sep 17 00:00:00 2001 From: Tanish Date: Tue, 13 Jan 2026 22:13:21 +0530 Subject: [PATCH 09/48] rewrote domain file --- server/models/domain.go | 320 ++++++++++++++++++++++++++++------------ 1 file changed, 229 insertions(+), 91 deletions(-) diff --git a/server/models/domain.go b/server/models/domain.go index b569686..24a5f78 100644 --- a/server/models/domain.go +++ b/server/models/domain.go @@ -6,133 +6,271 @@ import ( "github.com/corecollectives/mist/utils" ) +type sslStatus string +type sslProvider string +type acmeChallengeType string + +const ( + SSLStatusPending sslStatus = "pending" + SSLStatusActive sslStatus = "active" + SSLStatusFailed sslStatus = "failed" + SSLStatusDisabled sslStatus = "disabled" + SSLStatusExpired sslStatus = "expired" + + SSLProvider sslProvider = "letsencrypt" + SSLProviderCustom sslProvider = "custom" + SSLProviderNone sslProvider = "none" + + AcmeChallengeTypeHttp01 acmeChallengeType = "http-01" + AcmeChallengeTypeDns01 acmeChallengeType = "dns-01" + AcmeChallengeTypeTlsAlpn01 acmeChallengeType = "tls-alpn-01" +) + type Domain struct { - ID int64 `json:"id"` - AppID int64 `json:"appId"` - Domain string `json:"domain"` - SslStatus string `json:"sslStatus"` - DnsConfigured bool `json:"dnsConfigured"` - DnsVerifiedAt *time.Time `json:"dnsVerifiedAt"` - LastDnsCheck *time.Time `json:"lastDnsCheck"` - DnsCheckError *string `json:"dnsCheckError"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID int64 `gorm:"primaryKey;autoIncrement:false" json:"id"` + + AppID int64 `gorm:"index;not null;constraint:OnDelete:CASCADE" json:"appId"` + + Domain string `gorm:"column:domain_name;uniqueIndex;not null" json:"domain"` + + SslStatus sslStatus `gorm:"default:'pending';index" json:"sslStatus"` + SslProvider sslProvider `gorm:"default:'letsencrypt'" json:"sslProvider,omitempty"` + + CertificatePath *string `json:"certificatePath,omitempty"` + CertificateData *string `json:"-"` + KeyPath *string `json:"keyPath,omitempty"` + KeyData *string `json:"-"` + ChainPath *string `json:"chainPath,omitempty"` + + AcmeAccountUrl *string `json:"acmeAccountUrl,omitempty"` + AcmeChallengeType acmeChallengeType `json:"acmeChallengeType,omitempty"` + + Issuer *string `json:"issuer,omitempty"` + IssuedAt *time.Time `json:"issuedAt,omitempty"` + ExpiresAt *time.Time `gorm:"index" json:"expiresAt,omitempty"` + LastRenewalAttempt *time.Time `json:"lastRenewalAttempt,omitempty"` + RenewalError *string `json:"renewalError,omitempty"` + + AutoRenew bool `gorm:"default:true" json:"autoRenew"` + ForceHttps bool `gorm:"default:false" json:"forceHttps"` + HstsEnabled bool `gorm:"default:false" json:"hstsEnabled"` + HstsMaxAge int `gorm:"default:31536000" json:"hstsMaxAge"` + RedirectWww bool `gorm:"default:false" json:"redirectWww"` + RedirectWwwToRoot bool `gorm:"default:true" json:"redirectWwwToRoot"` + + DnsConfigured bool `gorm:"default:false" json:"dnsConfigured"` + DnsVerifiedAt *time.Time `json:"dnsVerifiedAt,omitempty"` + LastDnsCheck *time.Time `json:"lastDnsCheck,omitempty"` + DnsCheckError *string `json:"dnsCheckError,omitempty"` + + CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` + UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"` } func CreateDomain(appID int64, domain string) (*Domain, error) { - id := utils.GenerateRandomId() - query := ` - INSERT INTO domains (id, app_id, domain_name, ssl_status, dns_configured, created_at, updated_at) - VALUES (?, ?, ?, 'pending', 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) - RETURNING id, app_id, domain_name, ssl_status, dns_configured, dns_verified_at, last_dns_check, dns_check_error, created_at, updated_at - ` var d Domain - err := db.QueryRow(query, id, appID, domain).Scan( - &d.ID, &d.AppID, &d.Domain, &d.SslStatus, &d.DnsConfigured, &d.DnsVerifiedAt, &d.LastDnsCheck, &d.DnsCheckError, &d.CreatedAt, &d.UpdatedAt, - ) - if err != nil { - return nil, err + id := utils.GenerateRandomId() + d.ID = id + d.AppID = appID + d.Domain = domain + result := db.Create(&d) + if result.Error != nil { + return nil, result.Error } return &d, nil } - func GetDomainsByAppID(appID int64) ([]Domain, error) { - query := ` - SELECT id, app_id, domain_name, ssl_status, dns_configured, dns_verified_at, last_dns_check, dns_check_error, created_at, updated_at - FROM domains - WHERE app_id = ? - ORDER BY created_at ASC - ` - rows, err := db.Query(query, appID) - if err != nil { - return nil, err - } - defer rows.Close() - var domains []Domain - for rows.Next() { - var d Domain - err := rows.Scan(&d.ID, &d.AppID, &d.Domain, &d.SslStatus, &d.DnsConfigured, &d.DnsVerifiedAt, &d.LastDnsCheck, &d.DnsCheckError, &d.CreatedAt, &d.UpdatedAt) - if err != nil { - return nil, err - } - domains = append(domains, d) + result := db.Where("app_id = ?", appID).Order("created_at ASC").Find(&domains) + if result.Error != nil { + return nil, result.Error } return domains, nil } func GetPrimaryDomainByAppID(appID int64) (*Domain, error) { - query := ` - SELECT id, app_id, domain_name, ssl_status, dns_configured, dns_verified_at, last_dns_check, dns_check_error, created_at, updated_at - FROM domains - WHERE app_id = ? - ORDER BY created_at ASC - LIMIT 1 - ` var d Domain - err := db.QueryRow(query, appID).Scan(&d.ID, &d.AppID, &d.Domain, &d.SslStatus, &d.DnsConfigured, &d.DnsVerifiedAt, &d.LastDnsCheck, &d.DnsCheckError, &d.CreatedAt, &d.UpdatedAt) - if err != nil { - return nil, err + result := db.Where("app_id = ?", appID).Order("created_at ASC").First(&d) + if result.Error != nil { + return nil, result.Error } return &d, nil } func UpdateDomain(id int64, domain string) error { - query := ` - UPDATE domains - SET domain_name = ?, updated_at = CURRENT_TIMESTAMP - WHERE id = ? - ` - _, err := db.Exec(query, domain, id) - return err + result := db.Model(&Domain{}).Where("id=?", id).Update("domain_name", domain) + return result.Error } func DeleteDomain(id int64) error { - query := `DELETE FROM domains WHERE id = ?` - _, err := db.Exec(query, id) - return err + result := db.Delete(&Domain{}, id) + return result.Error } func GetDomainByID(id int64) (*Domain, error) { - query := ` - SELECT id, app_id, domain_name, ssl_status, dns_configured, dns_verified_at, last_dns_check, dns_check_error, created_at, updated_at - FROM domains - WHERE id = ? - ` var d Domain - err := db.QueryRow(query, id).Scan(&d.ID, &d.AppID, &d.Domain, &d.SslStatus, &d.DnsConfigured, &d.DnsVerifiedAt, &d.LastDnsCheck, &d.DnsCheckError, &d.CreatedAt, &d.UpdatedAt) - if err != nil { - return nil, err + result := db.First(&d, id) + if result.Error != nil { + return nil, result.Error } return &d, nil } func UpdateDomainDnsStatus(id int64, configured bool, errorMsg *string) error { - var query string - var err error + updates := map[string]interface{}{ + "last_dns_check": time.Now(), + } if configured { - query = ` - UPDATE domains - SET dns_configured = 1, - dns_verified_at = CURRENT_TIMESTAMP, - last_dns_check = CURRENT_TIMESTAMP, - dns_check_error = NULL, - updated_at = CURRENT_TIMESTAMP - WHERE id = ? - ` - _, err = db.Exec(query, id) + updates["dns_configured"] = true + updates["dns_verified_at"] = time.Now() + updates["dns_check_error"] = nil } else { - query = ` - UPDATE domains - SET dns_configured = 0, - last_dns_check = CURRENT_TIMESTAMP, - dns_check_error = ?, - updated_at = CURRENT_TIMESTAMP - WHERE id = ? - ` - _, err = db.Exec(query, errorMsg, id) + updates["dns_configured"] = false + updates["dns_check_error"] = errorMsg } - return err + return db.Model(&Domain{ID: id}).Updates(updates).Error } + +//############################################################################################################################################# +//ARCHIVED CODE BELOW-------> + +// package models + +// import ( +// "time" + +// "github.com/corecollectives/mist/utils" +// ) + +// type Domain struct { +// ID int64 `json:"id"` +// AppID int64 `json:"appId"` +// Domain string `json:"domain"` +// SslStatus string `json:"sslStatus"` +// DnsConfigured bool `json:"dnsConfigured"` +// DnsVerifiedAt *time.Time `json:"dnsVerifiedAt"` +// LastDnsCheck *time.Time `json:"lastDnsCheck"` +// DnsCheckError *string `json:"dnsCheckError"` +// CreatedAt time.Time `json:"createdAt"` +// UpdatedAt time.Time `json:"updatedAt"` +// } + +// func CreateDomain(appID int64, domain string) (*Domain, error) { +// id := utils.GenerateRandomId() +// query := ` +// INSERT INTO domains (id, app_id, domain_name, ssl_status, dns_configured, created_at, updated_at) +// VALUES (?, ?, ?, 'pending', 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) +// RETURNING id, app_id, domain_name, ssl_status, dns_configured, dns_verified_at, last_dns_check, dns_check_error, created_at, updated_at +// ` +// var d Domain +// err := db.QueryRow(query, id, appID, domain).Scan( +// &d.ID, &d.AppID, &d.Domain, &d.SslStatus, &d.DnsConfigured, &d.DnsVerifiedAt, &d.LastDnsCheck, &d.DnsCheckError, &d.CreatedAt, &d.UpdatedAt, +// ) +// if err != nil { +// return nil, err +// } +// return &d, nil +// } + +// func GetDomainsByAppID(appID int64) ([]Domain, error) { +// query := ` +// SELECT id, app_id, domain_name, ssl_status, dns_configured, dns_verified_at, last_dns_check, dns_check_error, created_at, updated_at +// FROM domains +// WHERE app_id = ? +// ORDER BY created_at ASC +// ` +// rows, err := db.Query(query, appID) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// var domains []Domain +// for rows.Next() { +// var d Domain +// err := rows.Scan(&d.ID, &d.AppID, &d.Domain, &d.SslStatus, &d.DnsConfigured, &d.DnsVerifiedAt, &d.LastDnsCheck, &d.DnsCheckError, &d.CreatedAt, &d.UpdatedAt) +// if err != nil { +// return nil, err +// } +// domains = append(domains, d) +// } +// return domains, nil +// } + +// func GetPrimaryDomainByAppID(appID int64) (*Domain, error) { +// query := ` +// SELECT id, app_id, domain_name, ssl_status, dns_configured, dns_verified_at, last_dns_check, dns_check_error, created_at, updated_at +// FROM domains +// WHERE app_id = ? +// ORDER BY created_at ASC +// LIMIT 1 +// ` +// var d Domain +// err := db.QueryRow(query, appID).Scan(&d.ID, &d.AppID, &d.Domain, &d.SslStatus, &d.DnsConfigured, &d.DnsVerifiedAt, &d.LastDnsCheck, &d.DnsCheckError, &d.CreatedAt, &d.UpdatedAt) +// if err != nil { +// return nil, err +// } +// return &d, nil +// } + +// func UpdateDomain(id int64, domain string) error { +// query := ` +// UPDATE domains +// SET domain_name = ?, updated_at = CURRENT_TIMESTAMP +// WHERE id = ? +// ` +// _, err := db.Exec(query, domain, id) +// return err +// } + +// func DeleteDomain(id int64) error { +// query := `DELETE FROM domains WHERE id = ?` +// _, err := db.Exec(query, id) +// return err +// } + +// func GetDomainByID(id int64) (*Domain, error) { +// query := ` +// SELECT id, app_id, domain_name, ssl_status, dns_configured, dns_verified_at, last_dns_check, dns_check_error, created_at, updated_at +// FROM domains +// WHERE id = ? +// ` +// var d Domain +// err := db.QueryRow(query, id).Scan(&d.ID, &d.AppID, &d.Domain, &d.SslStatus, &d.DnsConfigured, &d.DnsVerifiedAt, &d.LastDnsCheck, &d.DnsCheckError, &d.CreatedAt, &d.UpdatedAt) +// if err != nil { +// return nil, err +// } +// return &d, nil +// } + +// func UpdateDomainDnsStatus(id int64, configured bool, errorMsg *string) error { +// var query string +// var err error + +// if configured { +// query = ` +// UPDATE domains +// SET dns_configured = 1, +// dns_verified_at = CURRENT_TIMESTAMP, +// last_dns_check = CURRENT_TIMESTAMP, +// dns_check_error = NULL, +// updated_at = CURRENT_TIMESTAMP +// WHERE id = ? +// ` +// _, err = db.Exec(query, id) +// } else { +// query = ` +// UPDATE domains +// SET dns_configured = 0, +// last_dns_check = CURRENT_TIMESTAMP, +// dns_check_error = ?, +// updated_at = CURRENT_TIMESTAMP +// WHERE id = ? +// ` +// _, err = db.Exec(query, errorMsg, id) +// } + +// return err +// } From 7e3da066774a8463229106e6afc08652d13bced6 Mon Sep 17 00:00:00 2001 From: Tanish Date: Tue, 13 Jan 2026 22:33:34 +0530 Subject: [PATCH 10/48] gormified envVariable table --- server/models/envVariable.go | 188 ++++++++++++++++++++++++----------- 1 file changed, 130 insertions(+), 58 deletions(-) diff --git a/server/models/envVariable.go b/server/models/envVariable.go index 20f33c3..c37bafa 100644 --- a/server/models/envVariable.go +++ b/server/models/envVariable.go @@ -7,82 +7,154 @@ import ( ) type EnvVariable struct { - ID int64 `json:"id"` - AppID int64 `json:"appId"` - Key string `json:"key"` - Value string `json:"value"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID int64 `gorm:"primaryKey;autoIncrement:false" json:"id"` + + AppID int64 `gorm:"uniqueIndex:idx_app_key;index;not null;constraint:OnDelete:CASCADE" json:"appId"` + + Key string `gorm:"uniqueIndex:idx_app_key;not null" json:"key"` + + Value string `gorm:"not null" json:"value"` + + IsSecret bool `gorm:"default:false" json:"isSecret,omitempty"` + + CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` + UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"` +} + +func (EnvVariable) TableName() string { + return "envs" } func CreateEnvVariable(appID int64, key, value string) (*EnvVariable, error) { - id := utils.GenerateRandomId() - query := ` - INSERT INTO envs (id, app_id, key, value, created_at, updated_at) - VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) - RETURNING id, app_id, key, value, created_at, updated_at - ` - var env EnvVariable - err := db.QueryRow(query, id, appID, key, value).Scan( - &env.ID, &env.AppID, &env.Key, &env.Value, &env.CreatedAt, &env.UpdatedAt, - ) - if err != nil { - return nil, err + env := &EnvVariable{ + ID: utils.GenerateRandomId(), + AppID: appID, + Key: key, + Value: value, } - return &env, nil -} -func GetEnvVariablesByAppID(appID int64) ([]EnvVariable, error) { - query := ` - SELECT id, app_id, key, value, created_at, updated_at - FROM envs - WHERE app_id = ? - ORDER BY key ASC - ` - rows, err := db.Query(query, appID) - if err != nil { - return nil, err + result := db.Create(env) + if result.Error != nil { + return nil, result.Error } - defer rows.Close() + return env, nil +} +func GetEnvVariablesByAppID(appID int64) ([]EnvVariable, error) { var envs []EnvVariable - for rows.Next() { - var env EnvVariable - err := rows.Scan(&env.ID, &env.AppID, &env.Key, &env.Value, &env.CreatedAt, &env.UpdatedAt) - if err != nil { - return nil, err - } - envs = append(envs, env) - } - return envs, nil + result := db.Where("app_id = ?", appID).Order("key ASC").Find(&envs) + return envs, result.Error } func UpdateEnvVariable(id int64, key, value string) error { - query := ` - UPDATE envs - SET key = ?, value = ?, updated_at = CURRENT_TIMESTAMP - WHERE id = ? - ` - _, err := db.Exec(query, key, value, id) - return err + updates := map[string]interface{}{ + "key": key, + "value": value, + } + return db.Model(&EnvVariable{ID: id}).Updates(updates).Error } func DeleteEnvVariable(id int64) error { - query := `DELETE FROM envs WHERE id = ?` - _, err := db.Exec(query, id) - return err + return db.Delete(&EnvVariable{}, id).Error } func GetEnvVariableByID(id int64) (*EnvVariable, error) { - query := ` - SELECT id, app_id, key, value, created_at, updated_at - FROM envs - WHERE id = ? - ` var env EnvVariable - err := db.QueryRow(query, id).Scan(&env.ID, &env.AppID, &env.Key, &env.Value, &env.CreatedAt, &env.UpdatedAt) - if err != nil { - return nil, err + result := db.First(&env, id) + if result.Error != nil { + return nil, result.Error } return &env, nil } + +//########################################################################################################## +//ARCHIVED CODE BELOW + +// package models + +// import ( +// "time" + +// "github.com/corecollectives/mist/utils" +// ) + +// type EnvVariable struct { +// ID int64 `json:"id"` +// AppID int64 `json:"appId"` +// Key string `json:"key"` +// Value string `json:"value"` +// CreatedAt time.Time `json:"createdAt"` +// UpdatedAt time.Time `json:"updatedAt"` +// } + +// func CreateEnvVariable(appID int64, key, value string) (*EnvVariable, error) { +// id := utils.GenerateRandomId() +// query := ` +// INSERT INTO envs (id, app_id, key, value, created_at, updated_at) +// VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) +// RETURNING id, app_id, key, value, created_at, updated_at +// ` +// var env EnvVariable +// err := db.QueryRow(query, id, appID, key, value).Scan( +// &env.ID, &env.AppID, &env.Key, &env.Value, &env.CreatedAt, &env.UpdatedAt, +// ) +// if err != nil { +// return nil, err +// } +// return &env, nil +// } + +// func GetEnvVariablesByAppID(appID int64) ([]EnvVariable, error) { +// query := ` +// SELECT id, app_id, key, value, created_at, updated_at +// FROM envs +// WHERE app_id = ? +// ORDER BY key ASC +// ` +// rows, err := db.Query(query, appID) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// var envs []EnvVariable +// for rows.Next() { +// var env EnvVariable +// err := rows.Scan(&env.ID, &env.AppID, &env.Key, &env.Value, &env.CreatedAt, &env.UpdatedAt) +// if err != nil { +// return nil, err +// } +// envs = append(envs, env) +// } +// return envs, nil +// } + +// func UpdateEnvVariable(id int64, key, value string) error { +// query := ` +// UPDATE envs +// SET key = ?, value = ?, updated_at = CURRENT_TIMESTAMP +// WHERE id = ? +// ` +// _, err := db.Exec(query, key, value, id) +// return err +// } + +// func DeleteEnvVariable(id int64) error { +// query := `DELETE FROM envs WHERE id = ?` +// _, err := db.Exec(query, id) +// return err +// } + +// func GetEnvVariableByID(id int64) (*EnvVariable, error) { +// query := ` +// SELECT id, app_id, key, value, created_at, updated_at +// FROM envs +// WHERE id = ? +// ` +// var env EnvVariable +// err := db.QueryRow(query, id).Scan(&env.ID, &env.AppID, &env.Key, &env.Value, &env.CreatedAt, &env.UpdatedAt) +// if err != nil { +// return nil, err +// } +// return &env, nil +// } From ccaee7b9f83c5ea19c736ba6946300a03903c788 Mon Sep 17 00:00:00 2001 From: Tanish Date: Tue, 13 Jan 2026 23:20:50 +0530 Subject: [PATCH 11/48] gormified githubApps --- server/models/github.go | 395 ++++++++++++++++++++++++++++------------ 1 file changed, 279 insertions(+), 116 deletions(-) diff --git a/server/models/github.go b/server/models/github.go index d857c02..848db59 100644 --- a/server/models/github.go +++ b/server/models/github.go @@ -1,33 +1,53 @@ package models import ( - "database/sql" + "fmt" "time" + + "gorm.io/gorm" + "gorm.io/gorm/clause" ) type GithubApp struct { - ID int64 `json:"id"` - AppID int64 `json:"appId"` - Name *string `json:"name"` - Slug string `json:"slug"` - ClientID string `json:"clientId"` - ClientSecret string `json:"clientSecret"` - WebhookSecret string `json:"webhookSecret"` - PrivateKey string `json:"privateKey"` - CreatedAt time.Time `json:"createdAt"` + ID int64 `gorm:"primaryKey;autoIncrement:true" json:"id"` + + AppID int64 `gorm:"not null" json:"appId"` + ClientID string `gorm:"not null" json:"clientId"` + ClientSecret string `gorm:"not null" json:"clientSecret"` + WebhookSecret string `gorm:"not null" json:"webhookSecret"` + PrivateKey string `gorm:"not null" json:"privateKey"` + Name *string `json:"name"` + Slug string `gorm:"not null" json:"slug"` + + CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` + UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"` +} + +func (GithubApp) TableName() string { + return "github_app" +} + +type GithubInstallation struct { + InstallationID int64 `gorm:"primaryKey;autoIncrement:false" json:"installation_id"` + + AccountLogin string `json:"account_login"` + AccountType string `json:"account_type"` + AccessToken string `json:"access_token"` + TokenExpiresAt time.Time `json:"token_expires_at"` + + UserID int `gorm:"index" json:"user_id"` + + CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` + UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } func (app *GithubApp) InsertInDB() error { - _, err := db.Exec(` - INSERT INTO github_app (app_id, client_id, client_secret, webhook_secret, private_key, name, slug) - VALUES (?, ?, ?, ?, ?, ?, ?) - `, app.AppID, app.ClientID, app.ClientSecret, app.WebhookSecret, app.PrivateKey, app.Name, app.Slug) - return err + return db.Create(app).Error } func CheckIfAppExists() (bool, error) { - var count int - err := db.QueryRow(`SELECT COUNT(*) FROM github_app`).Scan(&count) + var count int64 + err := db.Model(&GithubApp{}).Count(&count).Error if err != nil { return false, err } @@ -35,92 +55,45 @@ func CheckIfAppExists() (bool, error) { } func GetApp(userID int) (GithubApp, bool, error) { - query := ` - SELECT - a.id, - a.name, - a.app_id, - a.client_id, - a.slug, - a.created_at, - CASE WHEN i.installation_id IS NOT NULL THEN 1 ELSE 0 END AS is_installed - FROM github_app a - LEFT JOIN github_installations i ON i.user_id = ? - WHERE a.id = 1 - ` - - row := db.QueryRow(query, userID) - var app GithubApp - var isInstalled bool - - err := row.Scan( - &app.ID, - &app.Name, - &app.AppID, - &app.ClientID, - &app.Slug, - &app.CreatedAt, - &isInstalled, - ) + err := db.First(&app, 1).Error if err != nil { - if err == sql.ErrNoRows { + if err == gorm.ErrRecordNotFound { return GithubApp{}, false, nil } return GithubApp{}, false, err } - return app, isInstalled, nil -} + var count int64 + err = db.Model(&GithubInstallation{}). + Where("user_id = ?", userID). + Count(&count).Error -type GithubInstallation struct { - InstallationID int64 `json:"installation_id"` - AccountLogin string `json:"account_login"` - AccountType string `json:"account_type"` - AccessToken string `json:"access_token"` - TokenExpiresAt time.Time `json:"token_expires_at"` - UserID int `json:"user_id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + isInstalled := count > 0 + return app, isInstalled, err } func (i *GithubInstallation) InsertOrReplace() error { - _, err := db.Exec(` - INSERT OR REPLACE INTO github_installations - (installation_id, account_login, account_type, access_token, token_expires_at, user_id, updated_at) - VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP) - `, i.InstallationID, i.AccountLogin, i.AccountType, i.AccessToken, i.TokenExpiresAt, i.UserID) - return err + return db.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "installation_id"}}, + UpdateAll: true, + }).Create(i).Error } func GetInstallationID(userID int) (int64, error) { - var installationID int64 - err := db.QueryRow(` - SELECT installation_id FROM github_installations - WHERE user_id = ? - `, userID).Scan(&installationID) + var inst GithubInstallation + err := db.Select("installation_id"). + Where("user_id = ?", userID). + First(&inst).Error if err != nil { return 0, err } - return installationID, nil + return inst.InstallationID, nil } func GetInstallationByUserID(userID int) (GithubInstallation, error) { var inst GithubInstallation - err := db.QueryRow(` - SELECT installation_id, account_login, account_type, access_token, token_expires_at, user_id, created_at, updated_at - FROM github_installations - WHERE user_id = ? - `, userID).Scan( - &inst.InstallationID, - &inst.AccountLogin, - &inst.AccountType, - &inst.AccessToken, - &inst.TokenExpiresAt, - &inst.UserID, - &inst.CreatedAt, - &inst.UpdatedAt, - ) + err := db.Where("user_id = ?", userID).First(&inst).Error if err != nil { return GithubInstallation{}, err } @@ -128,63 +101,253 @@ func GetInstallationByUserID(userID int) (GithubInstallation, error) { } func GetInstallationToken(installationID int64) (string, string, int, error) { - var ( - token string - tokenExpires string - appID int - ) - err := db.QueryRow(` - SELECT i.access_token, i.token_expires_at, a.app_id - FROM github_installations i - JOIN github_app a ON a.id = 1 - WHERE i.installation_id = ? - `, installationID).Scan(&token, &tokenExpires, &appID) + type Result struct { + AccessToken string + TokenExpiresAt time.Time + AppID int + } + + var res Result + err := db.Table("github_installations as i"). + Select("i.access_token, i.token_expires_at, a.app_id"). + Joins("JOIN github_app a ON a.id = 1"). + Where("i.installation_id = ?", installationID). + Scan(&res).Error + if err != nil { return "", "", 0, err } - return token, tokenExpires, appID, nil + + return res.AccessToken, res.TokenExpiresAt.Format(time.RFC3339), res.AppID, nil } func UpdateInstallationToken(installationID int64, token string, newExpiry time.Time) error { - _, err := db.Exec(` - UPDATE github_installations - SET access_token = ?, token_expires_at = ?, updated_at = CURRENT_TIMESTAMP - WHERE installation_id = ? - `, token, newExpiry.Format(time.RFC3339), installationID) - return err + return db.Model(&GithubInstallation{InstallationID: installationID}). + Updates(map[string]interface{}{ + "access_token": token, + "token_expires_at": newExpiry, + "updated_at": time.Now(), + }).Error } func GetGithubAppCredentials(appID int) (string, string, error) { - var appNumericId string - var appPrivateKeyPEM string - - err := db.QueryRow(` - SELECT app_id, private_key FROM github_app WHERE id = 1 - `).Scan(&appNumericId, &appPrivateKeyPEM) - + var app GithubApp + err := db.Select("app_id, private_key").First(&app, 1).Error if err != nil { return "", "", err } - return appNumericId, appPrivateKeyPEM, nil + return fmt.Sprintf("%d", app.AppID), app.PrivateKey, nil } func GetInstallationIDByUserID(userID int64) (int64, error) { - var installationID int64 - err := db.QueryRow(`SELECT installation_id FROM github_installations WHERE user_id = ?`, userID). - Scan(&installationID) + var inst GithubInstallation + err := db.Select("installation_id").Where("user_id = ?", userID).First(&inst).Error if err != nil { return 0, err } - return installationID, nil + return inst.InstallationID, nil } func GetGithubAppIDAndPrivateKey() (int64, string, error) { - var appAppID int64 - var privateKey string - err := db.QueryRow(`SELECT app_id, private_key FROM github_app LIMIT 1`).Scan(&appAppID, &privateKey) + var app GithubApp + err := db.Select("app_id, private_key").First(&app).Error if err != nil { return 0, "", err } - return appAppID, privateKey, nil + return app.AppID, app.PrivateKey, nil } + +//######################################################################################################################## +//ARCHIVED CODE BELOW--------------------------------> + +// package models + +// import ( +// "database/sql" +// "time" +// ) + +// type GithubApp struct { +// ID int64 `json:"id"` +// AppID int64 `json:"appId"` +// Name *string `json:"name"` +// Slug string `json:"slug"` +// ClientID string `json:"clientId"` +// ClientSecret string `json:"clientSecret"` +// WebhookSecret string `json:"webhookSecret"` +// PrivateKey string `json:"privateKey"` +// CreatedAt time.Time `json:"createdAt"` +// } + +// func (app *GithubApp) InsertInDB() error { +// _, err := db.Exec(` +// INSERT INTO github_app (app_id, client_id, client_secret, webhook_secret, private_key, name, slug) +// VALUES (?, ?, ?, ?, ?, ?, ?) +// `, app.AppID, app.ClientID, app.ClientSecret, app.WebhookSecret, app.PrivateKey, app.Name, app.Slug) +// return err +// } + +// func CheckIfAppExists() (bool, error) { +// var count int +// err := db.QueryRow(`SELECT COUNT(*) FROM github_app`).Scan(&count) +// if err != nil { +// return false, err +// } +// return count > 0, nil +// } + +// func GetApp(userID int) (GithubApp, bool, error) { +// query := ` +// SELECT +// a.id, +// a.name, +// a.app_id, +// a.client_id, +// a.slug, +// a.created_at, +// CASE WHEN i.installation_id IS NOT NULL THEN 1 ELSE 0 END AS is_installed +// FROM github_app a +// LEFT JOIN github_installations i ON i.user_id = ? +// WHERE a.id = 1 +// ` + +// row := db.QueryRow(query, userID) + +// var app GithubApp +// var isInstalled bool + +// err := row.Scan( +// &app.ID, +// &app.Name, +// &app.AppID, +// &app.ClientID, +// &app.Slug, +// &app.CreatedAt, +// &isInstalled, +// ) +// if err != nil { +// if err == sql.ErrNoRows { +// return GithubApp{}, false, nil +// } +// return GithubApp{}, false, err +// } + +// return app, isInstalled, nil +// } + +// type GithubInstallation struct { +// InstallationID int64 `json:"installation_id"` +// AccountLogin string `json:"account_login"` +// AccountType string `json:"account_type"` +// AccessToken string `json:"access_token"` +// TokenExpiresAt time.Time `json:"token_expires_at"` +// UserID int `json:"user_id"` +// CreatedAt time.Time `json:"created_at"` +// UpdatedAt time.Time `json:"updated_at"` +// } + +// func (i *GithubInstallation) InsertOrReplace() error { +// _, err := db.Exec(` +// INSERT OR REPLACE INTO github_installations +// (installation_id, account_login, account_type, access_token, token_expires_at, user_id, updated_at) +// VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP) +// `, i.InstallationID, i.AccountLogin, i.AccountType, i.AccessToken, i.TokenExpiresAt, i.UserID) +// return err +// } + +// func GetInstallationID(userID int) (int64, error) { +// var installationID int64 +// err := db.QueryRow(` +// SELECT installation_id FROM github_installations +// WHERE user_id = ? +// `, userID).Scan(&installationID) +// if err != nil { +// return 0, err +// } +// return installationID, nil +// } + +// func GetInstallationByUserID(userID int) (GithubInstallation, error) { +// var inst GithubInstallation +// err := db.QueryRow(` +// SELECT installation_id, account_login, account_type, access_token, token_expires_at, user_id, created_at, updated_at +// FROM github_installations +// WHERE user_id = ? +// `, userID).Scan( +// &inst.InstallationID, +// &inst.AccountLogin, +// &inst.AccountType, +// &inst.AccessToken, +// &inst.TokenExpiresAt, +// &inst.UserID, +// &inst.CreatedAt, +// &inst.UpdatedAt, +// ) +// if err != nil { +// return GithubInstallation{}, err +// } +// return inst, nil +// } + +// func GetInstallationToken(installationID int64) (string, string, int, error) { +// var ( +// token string +// tokenExpires string +// appID int +// ) +// err := db.QueryRow(` +// SELECT i.access_token, i.token_expires_at, a.app_id +// FROM github_installations i +// JOIN github_app a ON a.id = 1 +// WHERE i.installation_id = ? +// `, installationID).Scan(&token, &tokenExpires, &appID) +// if err != nil { +// return "", "", 0, err +// } +// return token, tokenExpires, appID, nil +// } + +// func UpdateInstallationToken(installationID int64, token string, newExpiry time.Time) error { +// _, err := db.Exec(` +// UPDATE github_installations +// SET access_token = ?, token_expires_at = ?, updated_at = CURRENT_TIMESTAMP +// WHERE installation_id = ? +// `, token, newExpiry.Format(time.RFC3339), installationID) +// return err +// } + +// func GetGithubAppCredentials(appID int) (string, string, error) { +// var appNumericId string +// var appPrivateKeyPEM string + +// err := db.QueryRow(` +// SELECT app_id, private_key FROM github_app WHERE id = 1 +// `).Scan(&appNumericId, &appPrivateKeyPEM) + +// if err != nil { +// return "", "", err +// } + +// return appNumericId, appPrivateKeyPEM, nil +// } + +// func GetInstallationIDByUserID(userID int64) (int64, error) { +// var installationID int64 +// err := db.QueryRow(`SELECT installation_id FROM github_installations WHERE user_id = ?`, userID). +// Scan(&installationID) +// if err != nil { +// return 0, err +// } +// return installationID, nil +// } + +// func GetGithubAppIDAndPrivateKey() (int64, string, error) { +// var appAppID int64 +// var privateKey string +// err := db.QueryRow(`SELECT app_id, private_key FROM github_app LIMIT 1`).Scan(&appAppID, &privateKey) +// if err != nil { +// return 0, "", err +// } +// return appAppID, privateKey, nil +// } From cc1dfa55fd968814a2ce2cf9b528575b95589312 Mon Sep 17 00:00:00 2001 From: 07calc Date: Tue, 13 Jan 2026 23:44:32 +0530 Subject: [PATCH 12/48] feat: discord release message --- .github/workflows/discord-release-message.yml | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/discord-release-message.yml diff --git a/.github/workflows/discord-release-message.yml b/.github/workflows/discord-release-message.yml new file mode 100644 index 0000000..4f61e51 --- /dev/null +++ b/.github/workflows/discord-release-message.yml @@ -0,0 +1,29 @@ +name: Discord Release + +on: + release: + types: [published] + +jobs: + notify: + runs-on: ubuntu-latest + steps: + - name: Send Discord notification + env: + WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + BODY: ${{ github.event.release.body }} + TAG: ${{ github.event.release.tag_name }} + URL: ${{ github.event.release.html_url }} + REPO: ${{ github.repository }} + run: | + BODY_TRIM=$(echo "$BODY" | head -c 3900) + curl -H "Content-Type: application/json" \ + -d "{ + \"embeds\": [{ + \"title\": \"🚀 New Release: $TAG\", + \"url\": \"$URL\", + \"description\": \"$BODY_TRIM\", + \"footer\": { \"text\": \"$REPO\" } + }] + }" \ + $WEBHOOK From 0cf39fa8ff0129118e97270c17c14553ef0b94c4 Mon Sep 17 00:00:00 2001 From: 07calc Date: Wed, 14 Jan 2026 00:18:59 +0530 Subject: [PATCH 13/48] chore: remove docker gh action, fix: \n after git clone log --- .github/workflows/discord-release-message.yml | 29 ------------------- server/git/clone.go | 2 +- 2 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 .github/workflows/discord-release-message.yml diff --git a/.github/workflows/discord-release-message.yml b/.github/workflows/discord-release-message.yml deleted file mode 100644 index 4f61e51..0000000 --- a/.github/workflows/discord-release-message.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Discord Release - -on: - release: - types: [published] - -jobs: - notify: - runs-on: ubuntu-latest - steps: - - name: Send Discord notification - env: - WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} - BODY: ${{ github.event.release.body }} - TAG: ${{ github.event.release.tag_name }} - URL: ${{ github.event.release.html_url }} - REPO: ${{ github.repository }} - run: | - BODY_TRIM=$(echo "$BODY" | head -c 3900) - curl -H "Content-Type: application/json" \ - -d "{ - \"embeds\": [{ - \"title\": \"🚀 New Release: $TAG\", - \"url\": \"$URL\", - \"description\": \"$BODY_TRIM\", - \"footer\": { \"text\": \"$REPO\" } - }] - }" \ - $WEBHOOK diff --git a/server/git/clone.go b/server/git/clone.go index 79b140c..1ccaed7 100644 --- a/server/git/clone.go +++ b/server/git/clone.go @@ -10,7 +10,7 @@ import ( ) func CloneRepo(url string, branch string, logFile *os.File, path string) error { - _, err := fmt.Fprintf(logFile, "[GIT]: Cloning into %s", path) + _, err := fmt.Fprintf(logFile, "[GIT]: Cloning into %s\n", path) if err != nil { log.Warn().Msg("error logging into log file") } From 4e5562bc0d7e23562a86d25f6708d7b3d85e646d Mon Sep 17 00:00:00 2001 From: Tanish Date: Wed, 14 Jan 2026 23:30:29 +0530 Subject: [PATCH 14/48] gormified gitProvider logs and notification files --- server/models/gitProvider.go | 459 +++++++++++++++++++++++++--------- server/models/logs.go | 12 +- server/models/notification.go | 330 +++++++++++++++++------- 3 files changed, 585 insertions(+), 216 deletions(-) diff --git a/server/models/gitProvider.go b/server/models/gitProvider.go index fbf05f7..a2db968 100644 --- a/server/models/gitProvider.go +++ b/server/models/gitProvider.go @@ -1,7 +1,6 @@ package models import ( - "database/sql" "encoding/json" "encoding/pem" "fmt" @@ -21,36 +20,23 @@ const ( ) type GitProvider struct { - ID int64 `db:"id" json:"id"` - UserID int64 `db:"user_id" json:"user_id"` - Provider GitProviderType `db:"provider" json:"provider"` - AccessToken string `db:"access_token" json:"access_token"` - RefreshToken *string `db:"refresh_token" json:"refresh_token,omitempty"` - ExpiresAt *time.Time `db:"expires_at" json:"expires_at,omitempty"` - Username *string `db:"username" json:"username,omitempty"` - Email *string `db:"email" json:"email,omitempty"` + ID int64 `gorm:"primaryKey;autoIncrement:true" json:"id"` + UserID int64 `gorm:"uniqueIndex:idx_user_provider;index;not null;constraint:OnDelete:CASCADE" json:"user_id"` + Provider GitProviderType `gorm:"uniqueIndex:idx_user_provider;not null" json:"provider"` + AccessToken string `gorm:"not null" json:"access_token"` + RefreshToken *string `json:"refresh_token,omitempty"` + ExpiresAt *time.Time `json:"expires_at,omitempty"` + Username *string `json:"username,omitempty"` + Email *string `json:"email,omitempty"` } func (gp *GitProvider) InsertInDB() error { - query := ` - INSERT INTO git_providers (user_id, provider, access_token, refresh_token, expires_at, username, email) - VALUES (?, ?, ?, ?, ?, ?, ?) - RETURNING id - ` - err := db.QueryRow(query, gp.UserID, gp.Provider, gp.AccessToken, gp.RefreshToken, gp.ExpiresAt, gp.Username, gp.Email).Scan(&gp.ID) - return err + return db.Create(gp).Error } func GetGitProviderByID(id int64) (*GitProvider, error) { var gp GitProvider - query := ` - SELECT id, user_id, provider, access_token, refresh_token, expires_at, username, email - FROM git_providers - WHERE id = ? - ` - err := db.QueryRow(query, id).Scan( - &gp.ID, &gp.UserID, &gp.Provider, &gp.AccessToken, &gp.RefreshToken, &gp.ExpiresAt, &gp.Username, &gp.Email, - ) + err := db.First(&gp, id).Error if err != nil { return nil, err } @@ -59,14 +45,7 @@ func GetGitProviderByID(id int64) (*GitProvider, error) { func GetGitProviderByUserAndProvider(userID int64, provider GitProviderType) (*GitProvider, error) { var gp GitProvider - query := ` - SELECT id, user_id, provider, access_token, refresh_token, expires_at, username, email - FROM git_providers - WHERE user_id = ? AND provider = ? - ` - err := db.QueryRow(query, userID, provider).Scan( - &gp.ID, &gp.UserID, &gp.Provider, &gp.AccessToken, &gp.RefreshToken, &gp.ExpiresAt, &gp.Username, &gp.Email, - ) + err := db.Where("user_id = ? AND provider = ?", userID, provider).First(&gp).Error if err != nil { return nil, err } @@ -75,113 +54,61 @@ func GetGitProviderByUserAndProvider(userID int64, provider GitProviderType) (*G func GetGitProvidersByUser(userID int64) ([]GitProvider, error) { var providers []GitProvider - query := ` - SELECT id, user_id, provider, access_token, refresh_token, expires_at, username, email - FROM git_providers - WHERE user_id = ? - ` - rows, err := db.Query(query, userID) - if err != nil { - return nil, err - } - defer rows.Close() - - for rows.Next() { - var gp GitProvider - err := rows.Scan( - &gp.ID, &gp.UserID, &gp.Provider, &gp.AccessToken, &gp.RefreshToken, &gp.ExpiresAt, &gp.Username, &gp.Email, - ) - if err != nil { - return nil, err - } - providers = append(providers, gp) - } - return providers, rows.Err() + err := db.Where("user_id = ?", userID).Find(&providers).Error + return providers, err } func (gp *GitProvider) UpdateToken(accessToken string, refreshToken *string, expiresAt *time.Time) error { - query := ` - UPDATE git_providers - SET access_token = ?, refresh_token = ?, expires_at = ? - WHERE id = ? - ` - _, err := db.Exec(query, accessToken, refreshToken, expiresAt, gp.ID) - return err + return db.Model(gp).Updates(map[string]interface{}{ + "access_token": accessToken, + "refresh_token": refreshToken, + "expires_at": expiresAt, + }).Error } func DeleteGitProvider(id int64) error { - query := `DELETE FROM git_providers WHERE id = ?` - _, err := db.Exec(query, id) - return err + return db.Delete(&GitProvider{}, id).Error } func GetGitProviderAccessToken(providerID int64) (string, GitProviderType, bool, error) { - var token string - var provider GitProviderType - var expiresAt sql.NullTime - query := `SELECT access_token, provider, expires_at FROM git_providers WHERE id = ?` - err := db.QueryRow(query, providerID).Scan(&token, &provider, &expiresAt) + var gp GitProvider + err := db.Select("access_token, provider, expires_at").First(&gp, providerID).Error if err != nil { return "", "", false, err } - // check if token is expired needsRefresh := false - if expiresAt.Valid && time.Now().After(expiresAt.Time) { + if gp.ExpiresAt != nil && time.Now().After(*gp.ExpiresAt) { needsRefresh = true } - return token, provider, needsRefresh, nil + return gp.AccessToken, gp.Provider, needsRefresh, nil } func GetAppGitInfo(appID int64) (*int64, *string, string, *string, int64, string, error) { - var gitProviderID sql.NullInt64 - var gitRepository sql.NullString - var gitBranch string - var gitCloneURL sql.NullString - var projectID int64 - var appName string - - query := ` - SELECT git_provider_id, git_repository, COALESCE(git_branch, 'main'), git_clone_url, project_id, name - FROM apps - WHERE id = ? - ` - err := db.QueryRow(query, appID).Scan(&gitProviderID, &gitRepository, &gitBranch, &gitCloneURL, &projectID, &appName) + var app App + err := db.Select("git_provider_id, git_repository, git_branch, git_clone_url, project_id, name"). + First(&app, appID).Error + if err != nil { return nil, nil, "", nil, 0, "", err } - var gitProviderIDPtr *int64 - if gitProviderID.Valid { - gitProviderIDPtr = &gitProviderID.Int64 - } - - var gitRepositoryPtr *string - if gitRepository.Valid { - gitRepositoryPtr = &gitRepository.String - } - - var gitCloneURLPtr *string - if gitCloneURL.Valid { - gitCloneURLPtr = &gitCloneURL.String + gitBranch := app.GitBranch + if gitBranch == "" { + gitBranch = "main" } - return gitProviderIDPtr, gitRepositoryPtr, gitBranch, gitCloneURLPtr, projectID, appName, nil + return app.GitProviderID, app.GitRepository, gitBranch, app.GitCloneURL, app.ProjectID, app.Name, nil } -// this is used for migrating old apps that only have git_repository set func UpdateAppGitCloneURL(appID int64, gitCloneURL string, gitProviderID *int64) error { - query := ` - UPDATE apps - SET git_clone_url = ?, git_provider_id = ? - WHERE id = ? - ` - _, err := db.Exec(query, gitCloneURL, gitProviderID, appID) - return err + return db.Model(&App{ID: appID}).Updates(map[string]interface{}{ + "git_clone_url": gitCloneURL, + "git_provider_id": gitProviderID, + }).Error } -// currently only supports GitHub via GitHub App installations func RefreshGitProviderToken(providerID int64) (string, error) { provider, err := GetGitProviderByID(providerID) if err != nil { @@ -191,7 +118,6 @@ func RefreshGitProviderToken(providerID int64) (string, error) { switch provider.Provider { case GitProviderGitHub: return refreshGitHubToken(provider.UserID) - // will be implemented as we add more git-providers case GitProviderGitLab, GitProviderBitbucket, GitProviderGitea: return "", fmt.Errorf("token refresh not implemented for %s", provider.Provider) default: @@ -210,12 +136,12 @@ func refreshGitHubToken(userID int64) (string, error) { return "", fmt.Errorf("failed to get GitHub App credentials: %w", err) } - jwt, err := generateGithubJwt(appID, privateKey) + jwtToken, err := generateGithubJwt(appID, privateKey) if err != nil { return "", fmt.Errorf("failed to generate GitHub JWT: %w", err) } - newToken, newExpiry, err := regenerateGithubInstallationToken(jwt, installation.InstallationID) + newToken, newExpiry, err := regenerateGithubInstallationToken(jwtToken, installation.InstallationID) if err != nil { return "", fmt.Errorf("failed to regenerate installation token: %w", err) } @@ -225,10 +151,9 @@ func refreshGitHubToken(userID int64) (string, error) { return "", fmt.Errorf("failed to update installation token: %w", err) } - // update the git_provider token - err = (&GitProvider{ID: installation.InstallationID}).UpdateToken(newToken, nil, &newExpiry) - if err != nil { - return newToken, nil + var gp GitProvider + if err := db.Where("user_id = ? AND provider = ?", userID, GitProviderGitHub).First(&gp).Error; err == nil { + _ = gp.UpdateToken(newToken, nil, &newExpiry) } return newToken, nil @@ -251,12 +176,7 @@ func generateGithubJwt(appID int64, privateKeyPEM string) (string, error) { "iss": fmt.Sprintf("%d", appID), }) - signedToken, err := token.SignedString(privateKey) - if err != nil { - return "", err - } - - return signedToken, nil + return token.SignedString(privateKey) } func regenerateGithubInstallationToken(appJWT string, installationID int64) (string, time.Time, error) { @@ -266,6 +186,7 @@ func regenerateGithubInstallationToken(appJWT string, installationID int64) (str if err != nil { return "", time.Time{}, err } + req.Header.Set("Authorization", "Bearer "+appJWT) req.Header.Set("Accept", "application/vnd.github+json") @@ -290,3 +211,299 @@ func regenerateGithubInstallationToken(appJWT string, installationID int64) (str return tokenResp.Token, tokenResp.ExpiresAt, nil } + +//######################################################################################################## +//ARCHIVED CODE BELOW + +// package models + +// import ( +// "database/sql" +// "encoding/json" +// "encoding/pem" +// "fmt" +// "net/http" +// "time" + +// "github.com/golang-jwt/jwt" +// ) + +// type GitProviderType string + +// const ( +// GitProviderGitHub GitProviderType = "github" +// GitProviderGitLab GitProviderType = "gitlab" +// GitProviderBitbucket GitProviderType = "bitbucket" +// GitProviderGitea GitProviderType = "gitea" +// ) + +// type GitProvider struct { +// ID int64 `db:"id" json:"id"` +// UserID int64 `db:"user_id" json:"user_id"` +// Provider GitProviderType `db:"provider" json:"provider"` +// AccessToken string `db:"access_token" json:"access_token"` +// RefreshToken *string `db:"refresh_token" json:"refresh_token,omitempty"` +// ExpiresAt *time.Time `db:"expires_at" json:"expires_at,omitempty"` +// Username *string `db:"username" json:"username,omitempty"` +// Email *string `db:"email" json:"email,omitempty"` +// } + +// func (gp *GitProvider) InsertInDB() error { +// query := ` +// INSERT INTO git_providers (user_id, provider, access_token, refresh_token, expires_at, username, email) +// VALUES (?, ?, ?, ?, ?, ?, ?) +// RETURNING id +// ` +// err := db.QueryRow(query, gp.UserID, gp.Provider, gp.AccessToken, gp.RefreshToken, gp.ExpiresAt, gp.Username, gp.Email).Scan(&gp.ID) +// return err +// } + +// func GetGitProviderByID(id int64) (*GitProvider, error) { +// var gp GitProvider +// query := ` +// SELECT id, user_id, provider, access_token, refresh_token, expires_at, username, email +// FROM git_providers +// WHERE id = ? +// ` +// err := db.QueryRow(query, id).Scan( +// &gp.ID, &gp.UserID, &gp.Provider, &gp.AccessToken, &gp.RefreshToken, &gp.ExpiresAt, &gp.Username, &gp.Email, +// ) +// if err != nil { +// return nil, err +// } +// return &gp, nil +// } + +// func GetGitProviderByUserAndProvider(userID int64, provider GitProviderType) (*GitProvider, error) { +// var gp GitProvider +// query := ` +// SELECT id, user_id, provider, access_token, refresh_token, expires_at, username, email +// FROM git_providers +// WHERE user_id = ? AND provider = ? +// ` +// err := db.QueryRow(query, userID, provider).Scan( +// &gp.ID, &gp.UserID, &gp.Provider, &gp.AccessToken, &gp.RefreshToken, &gp.ExpiresAt, &gp.Username, &gp.Email, +// ) +// if err != nil { +// return nil, err +// } +// return &gp, nil +// } + +// func GetGitProvidersByUser(userID int64) ([]GitProvider, error) { +// var providers []GitProvider +// query := ` +// SELECT id, user_id, provider, access_token, refresh_token, expires_at, username, email +// FROM git_providers +// WHERE user_id = ? +// ` +// rows, err := db.Query(query, userID) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// for rows.Next() { +// var gp GitProvider +// err := rows.Scan( +// &gp.ID, &gp.UserID, &gp.Provider, &gp.AccessToken, &gp.RefreshToken, &gp.ExpiresAt, &gp.Username, &gp.Email, +// ) +// if err != nil { +// return nil, err +// } +// providers = append(providers, gp) +// } +// return providers, rows.Err() +// } + +// func (gp *GitProvider) UpdateToken(accessToken string, refreshToken *string, expiresAt *time.Time) error { +// query := ` +// UPDATE git_providers +// SET access_token = ?, refresh_token = ?, expires_at = ? +// WHERE id = ? +// ` +// _, err := db.Exec(query, accessToken, refreshToken, expiresAt, gp.ID) +// return err +// } + +// func DeleteGitProvider(id int64) error { +// query := `DELETE FROM git_providers WHERE id = ?` +// _, err := db.Exec(query, id) +// return err +// } + +// func GetGitProviderAccessToken(providerID int64) (string, GitProviderType, bool, error) { +// var token string +// var provider GitProviderType +// var expiresAt sql.NullTime +// query := `SELECT access_token, provider, expires_at FROM git_providers WHERE id = ?` +// err := db.QueryRow(query, providerID).Scan(&token, &provider, &expiresAt) +// if err != nil { +// return "", "", false, err +// } + +// // check if token is expired +// needsRefresh := false +// if expiresAt.Valid && time.Now().After(expiresAt.Time) { +// needsRefresh = true +// } + +// return token, provider, needsRefresh, nil +// } + +// func GetAppGitInfo(appID int64) (*int64, *string, string, *string, int64, string, error) { +// var gitProviderID sql.NullInt64 +// var gitRepository sql.NullString +// var gitBranch string +// var gitCloneURL sql.NullString +// var projectID int64 +// var appName string + +// query := ` +// SELECT git_provider_id, git_repository, COALESCE(git_branch, 'main'), git_clone_url, project_id, name +// FROM apps +// WHERE id = ? +// ` +// err := db.QueryRow(query, appID).Scan(&gitProviderID, &gitRepository, &gitBranch, &gitCloneURL, &projectID, &appName) +// if err != nil { +// return nil, nil, "", nil, 0, "", err +// } + +// var gitProviderIDPtr *int64 +// if gitProviderID.Valid { +// gitProviderIDPtr = &gitProviderID.Int64 +// } + +// var gitRepositoryPtr *string +// if gitRepository.Valid { +// gitRepositoryPtr = &gitRepository.String +// } + +// var gitCloneURLPtr *string +// if gitCloneURL.Valid { +// gitCloneURLPtr = &gitCloneURL.String +// } + +// return gitProviderIDPtr, gitRepositoryPtr, gitBranch, gitCloneURLPtr, projectID, appName, nil +// } + +// // this is used for migrating old apps that only have git_repository set +// func UpdateAppGitCloneURL(appID int64, gitCloneURL string, gitProviderID *int64) error { +// query := ` +// UPDATE apps +// SET git_clone_url = ?, git_provider_id = ? +// WHERE id = ? +// ` +// _, err := db.Exec(query, gitCloneURL, gitProviderID, appID) +// return err +// } + +// // currently only supports GitHub via GitHub App installations +// func RefreshGitProviderToken(providerID int64) (string, error) { +// provider, err := GetGitProviderByID(providerID) +// if err != nil { +// return "", err +// } + +// switch provider.Provider { +// case GitProviderGitHub: +// return refreshGitHubToken(provider.UserID) +// // will be implemented as we add more git-providers +// case GitProviderGitLab, GitProviderBitbucket, GitProviderGitea: +// return "", fmt.Errorf("token refresh not implemented for %s", provider.Provider) +// default: +// return "", fmt.Errorf("unknown provider type: %s", provider.Provider) +// } +// } + +// func refreshGitHubToken(userID int64) (string, error) { +// installation, err := GetInstallationByUserID(int(userID)) +// if err != nil { +// return "", fmt.Errorf("failed to get GitHub installation: %w", err) +// } + +// appID, privateKey, err := GetGithubAppIDAndPrivateKey() +// if err != nil { +// return "", fmt.Errorf("failed to get GitHub App credentials: %w", err) +// } + +// jwt, err := generateGithubJwt(appID, privateKey) +// if err != nil { +// return "", fmt.Errorf("failed to generate GitHub JWT: %w", err) +// } + +// newToken, newExpiry, err := regenerateGithubInstallationToken(jwt, installation.InstallationID) +// if err != nil { +// return "", fmt.Errorf("failed to regenerate installation token: %w", err) +// } + +// err = UpdateInstallationToken(installation.InstallationID, newToken, newExpiry) +// if err != nil { +// return "", fmt.Errorf("failed to update installation token: %w", err) +// } + +// // update the git_provider token +// err = (&GitProvider{ID: installation.InstallationID}).UpdateToken(newToken, nil, &newExpiry) +// if err != nil { +// return newToken, nil +// } + +// return newToken, nil +// } + +// func generateGithubJwt(appID int64, privateKeyPEM string) (string, error) { +// block, _ := pem.Decode([]byte(privateKeyPEM)) +// if block == nil { +// return "", fmt.Errorf("failed to decode PEM block") +// } + +// privateKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(privateKeyPEM)) +// if err != nil { +// return "", err +// } + +// token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{ +// "iat": time.Now().Unix(), +// "exp": time.Now().Add(10 * time.Minute).Unix(), +// "iss": fmt.Sprintf("%d", appID), +// }) + +// signedToken, err := token.SignedString(privateKey) +// if err != nil { +// return "", err +// } + +// return signedToken, nil +// } + +// func regenerateGithubInstallationToken(appJWT string, installationID int64) (string, time.Time, error) { +// url := fmt.Sprintf("https://api.github.com/app/installations/%d/access_tokens", installationID) + +// req, err := http.NewRequest("POST", url, nil) +// if err != nil { +// return "", time.Time{}, err +// } +// req.Header.Set("Authorization", "Bearer "+appJWT) +// req.Header.Set("Accept", "application/vnd.github+json") + +// resp, err := http.DefaultClient.Do(req) +// if err != nil { +// return "", time.Time{}, err +// } +// defer resp.Body.Close() + +// if resp.StatusCode != http.StatusCreated { +// return "", time.Time{}, fmt.Errorf("failed to create token, status %d", resp.StatusCode) +// } + +// var tokenResp struct { +// Token string `json:"token"` +// ExpiresAt time.Time `json:"expires_at"` +// } + +// if err := json.NewDecoder(resp.Body).Decode(&tokenResp); err != nil { +// return "", time.Time{}, err +// } + +// return tokenResp.Token, tokenResp.ExpiresAt, nil +// } diff --git a/server/models/logs.go b/server/models/logs.go index 87ecc1d..662572d 100644 --- a/server/models/logs.go +++ b/server/models/logs.go @@ -19,10 +19,10 @@ const ( ) type Logs struct { - ID int64 - Source LogSource - SourceID *int64 - Message string - Level LogLevel - CreatedAt time.Time + ID int64 `gorm:"primaryKey;autoIncrement:true"` + Source LogSource `gorm:"not null"` + SourceID *int64 `gorm:"index"` + Message string `gorm:"not null"` + Level LogLevel `gorm:"not null;default:'info'"` + CreatedAt time.Time `gorm:"autoCreateTime"` } diff --git a/server/models/notification.go b/server/models/notification.go index a0b5775..6a234d4 100644 --- a/server/models/notification.go +++ b/server/models/notification.go @@ -36,28 +36,39 @@ const ( ) type Notification struct { - ID int64 `db:"id" json:"id"` - UserID *int64 `db:"user_id" json:"userId,omitempty"` - Type NotificationType `db:"type" json:"type"` - Title string `db:"title" json:"title"` - Message string `db:"message" json:"message"` - Link *string `db:"link" json:"link,omitempty"` - ResourceType *string `db:"resource_type" json:"resourceType,omitempty"` - ResourceID *int64 `db:"resource_id" json:"resourceId,omitempty"` - EmailSent bool `db:"email_sent" json:"emailSent"` - EmailSentAt *time.Time `db:"email_sent_at" json:"emailSentAt,omitempty"` - SlackSent bool `db:"slack_sent" json:"slackSent"` - SlackSentAt *time.Time `db:"slack_sent_at" json:"slackSentAt,omitempty"` - DiscordSent bool `db:"discord_sent" json:"discordSent"` - DiscordSentAt *time.Time `db:"discord_sent_at" json:"discordSentAt,omitempty"` - WebhookSent bool `db:"webhook_sent" json:"webhookSent"` - WebhookSentAt *time.Time `db:"webhook_sent_at" json:"webhookSentAt,omitempty"` - IsRead bool `db:"is_read" json:"isRead"` - ReadAt *time.Time `db:"read_at" json:"readAt,omitempty"` - Priority NotificationPriority `db:"priority" json:"priority"` - Metadata *string `db:"metadata" json:"metadata,omitempty"` // JSON - CreatedAt time.Time `db:"created_at" json:"createdAt"` - ExpiresAt *time.Time `db:"expires_at" json:"expiresAt,omitempty"` + ID int64 `gorm:"primaryKey;autoIncrement:false" json:"id"` + + UserID *int64 `gorm:"index;constraint:OnDelete:CASCADE" json:"userId,omitempty"` + + Type NotificationType `gorm:"index;not null" json:"type"` + Title string `gorm:"not null" json:"title"` + Message string `gorm:"not null" json:"message"` + + Link *string `json:"link,omitempty"` + ResourceType *string `json:"resourceType,omitempty"` + ResourceID *int64 `json:"resourceId,omitempty"` + + EmailSent bool `gorm:"default:false" json:"emailSent"` + EmailSentAt *time.Time `json:"emailSentAt,omitempty"` + + SlackSent bool `gorm:"default:false" json:"slackSent"` + SlackSentAt *time.Time `json:"slackSentAt,omitempty"` + + DiscordSent bool `gorm:"default:false" json:"discordSent"` + DiscordSentAt *time.Time `json:"discordSentAt,omitempty"` + + WebhookSent bool `gorm:"default:false" json:"webhookSent"` + WebhookSentAt *time.Time `json:"webhookSentAt,omitempty"` + + IsRead bool `gorm:"default:false;index" json:"isRead"` + ReadAt *time.Time `json:"readAt,omitempty"` + + Priority NotificationPriority `gorm:"default:'normal';index" json:"priority"` + + Metadata *string `json:"metadata,omitempty"` + + CreatedAt time.Time `gorm:"autoCreateTime;index:,sort:desc" json:"createdAt"` + ExpiresAt *time.Time `json:"expiresAt,omitempty"` } func (n *Notification) ToJson() map[string]interface{} { @@ -88,91 +99,232 @@ func (n *Notification) ToJson() map[string]interface{} { } func (n *Notification) InsertInDB() error { - id := utils.GenerateRandomId() - n.ID = id - query := ` - INSERT INTO notifications ( - id, user_id, type, title, message, link, - resource_type, resource_id, priority, metadata, expires_at - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - RETURNING created_at - ` - err := db.QueryRow(query, n.ID, n.UserID, n.Type, n.Title, n.Message, n.Link, - n.ResourceType, n.ResourceID, n.Priority, n.Metadata, n.ExpiresAt).Scan(&n.CreatedAt) - return err + n.ID = utils.GenerateRandomId() + + if n.Priority == "" { + n.Priority = PriorityNormal + } + + return db.Create(n).Error } func GetNotificationsByUserID(userID int64, unreadOnly bool) ([]Notification, error) { var notifications []Notification - query := ` - SELECT id, user_id, type, title, message, link, resource_type, resource_id, - email_sent, email_sent_at, slack_sent, slack_sent_at, - discord_sent, discord_sent_at, webhook_sent, webhook_sent_at, - is_read, read_at, priority, metadata, created_at, expires_at - FROM notifications - WHERE user_id = ? OR user_id IS NULL - ` + + query := db.Where(db.Where("user_id = ?", userID).Or("user_id IS NULL")) + if unreadOnly { - query += " AND is_read = 0" + query = query.Where("is_read = ?", false) } - query += " ORDER BY created_at DESC LIMIT 100" - rows, err := db.Query(query, userID) - if err != nil { - return nil, err - } - defer rows.Close() - - for rows.Next() { - var notif Notification - err := rows.Scan( - ¬if.ID, ¬if.UserID, ¬if.Type, ¬if.Title, ¬if.Message, - ¬if.Link, ¬if.ResourceType, ¬if.ResourceID, - ¬if.EmailSent, ¬if.EmailSentAt, ¬if.SlackSent, ¬if.SlackSentAt, - ¬if.DiscordSent, ¬if.DiscordSentAt, ¬if.WebhookSent, ¬if.WebhookSentAt, - ¬if.IsRead, ¬if.ReadAt, ¬if.Priority, ¬if.Metadata, - ¬if.CreatedAt, ¬if.ExpiresAt, - ) - if err != nil { - return nil, err - } - notifications = append(notifications, notif) - } + result := query.Order("created_at DESC").Limit(100).Find(¬ifications) - return notifications, rows.Err() + return notifications, result.Error } func (n *Notification) MarkAsRead() error { - query := ` - UPDATE notifications - SET is_read = 1, read_at = CURRENT_TIMESTAMP - WHERE id = ? - ` - _, err := db.Exec(query, n.ID) - return err + return db.Model(n).Updates(map[string]interface{}{ + "is_read": true, + "read_at": time.Now(), + }).Error } func MarkAllAsRead(userID int64) error { - query := ` - UPDATE notifications - SET is_read = 1, read_at = CURRENT_TIMESTAMP - WHERE user_id = ? AND is_read = 0 - ` - _, err := db.Exec(query, userID) - return err + return db.Model(&Notification{}). + Where("user_id = ? AND is_read = ?", userID, false). + Updates(map[string]interface{}{ + "is_read": true, + "read_at": time.Now(), + }).Error } func DeleteNotification(notificationID int64) error { - query := `DELETE FROM notifications WHERE id = ?` - _, err := db.Exec(query, notificationID) - return err + return db.Delete(&Notification{}, notificationID).Error } func DeleteExpiredNotifications() error { - query := ` - DELETE FROM notifications - WHERE expires_at IS NOT NULL AND expires_at < CURRENT_TIMESTAMP - ` - _, err := db.Exec(query) - return err + return db.Where("expires_at IS NOT NULL AND expires_at < ?", time.Now()). + Delete(&Notification{}).Error } + +//###################################################################################################### +//ARCHIVED CODE BELOW + +// package models + +// import ( +// "time" + +// "github.com/corecollectives/mist/utils" +// ) + +// type NotificationType string + +// const ( +// NotificationDeploymentSuccess NotificationType = "deployment_success" +// NotificationDeploymentFailed NotificationType = "deployment_failed" +// NotificationDeploymentStarted NotificationType = "deployment_started" +// NotificationSSLExpiryWarning NotificationType = "ssl_expiry_warning" +// NotificationSSLRenewalSuccess NotificationType = "ssl_renewal_success" +// NotificationSSLRenewalFailed NotificationType = "ssl_renewal_failed" +// NotificationResourceAlert NotificationType = "resource_alert" +// NotificationAppError NotificationType = "app_error" +// NotificationAppStopped NotificationType = "app_stopped" +// NotificationBackupSuccess NotificationType = "backup_success" +// NotificationBackupFailed NotificationType = "backup_failed" +// NotificationUserInvited NotificationType = "user_invited" +// NotificationMemberAdded NotificationType = "member_added" +// NotificationSystemUpdate NotificationType = "system_update" +// NotificationCustom NotificationType = "custom" +// ) + +// type NotificationPriority string + +// const ( +// PriorityLow NotificationPriority = "low" +// PriorityNormal NotificationPriority = "normal" +// PriorityHigh NotificationPriority = "high" +// PriorityUrgent NotificationPriority = "urgent" +// ) + +// type Notification struct { +// ID int64 `db:"id" json:"id"` +// UserID *int64 `db:"user_id" json:"userId,omitempty"` +// Type NotificationType `db:"type" json:"type"` +// Title string `db:"title" json:"title"` +// Message string `db:"message" json:"message"` +// Link *string `db:"link" json:"link,omitempty"` +// ResourceType *string `db:"resource_type" json:"resourceType,omitempty"` +// ResourceID *int64 `db:"resource_id" json:"resourceId,omitempty"` +// EmailSent bool `db:"email_sent" json:"emailSent"` +// EmailSentAt *time.Time `db:"email_sent_at" json:"emailSentAt,omitempty"` +// SlackSent bool `db:"slack_sent" json:"slackSent"` +// SlackSentAt *time.Time `db:"slack_sent_at" json:"slackSentAt,omitempty"` +// DiscordSent bool `db:"discord_sent" json:"discordSent"` +// DiscordSentAt *time.Time `db:"discord_sent_at" json:"discordSentAt,omitempty"` +// WebhookSent bool `db:"webhook_sent" json:"webhookSent"` +// WebhookSentAt *time.Time `db:"webhook_sent_at" json:"webhookSentAt,omitempty"` +// IsRead bool `db:"is_read" json:"isRead"` +// ReadAt *time.Time `db:"read_at" json:"readAt,omitempty"` +// Priority NotificationPriority `db:"priority" json:"priority"` +// Metadata *string `db:"metadata" json:"metadata,omitempty"` // JSON +// CreatedAt time.Time `db:"created_at" json:"createdAt"` +// ExpiresAt *time.Time `db:"expires_at" json:"expiresAt,omitempty"` +// } + +// func (n *Notification) ToJson() map[string]interface{} { +// return map[string]interface{}{ +// "id": n.ID, +// "userId": n.UserID, +// "type": n.Type, +// "title": n.Title, +// "message": n.Message, +// "link": n.Link, +// "resourceType": n.ResourceType, +// "resourceId": n.ResourceID, +// "emailSent": n.EmailSent, +// "emailSentAt": n.EmailSentAt, +// "slackSent": n.SlackSent, +// "slackSentAt": n.SlackSentAt, +// "discordSent": n.DiscordSent, +// "discordSentAt": n.DiscordSentAt, +// "webhookSent": n.WebhookSent, +// "webhookSentAt": n.WebhookSentAt, +// "isRead": n.IsRead, +// "readAt": n.ReadAt, +// "priority": n.Priority, +// "metadata": n.Metadata, +// "createdAt": n.CreatedAt, +// "expiresAt": n.ExpiresAt, +// } +// } + +// func (n *Notification) InsertInDB() error { +// id := utils.GenerateRandomId() +// n.ID = id +// query := ` +// INSERT INTO notifications ( +// id, user_id, type, title, message, link, +// resource_type, resource_id, priority, metadata, expires_at +// ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +// RETURNING created_at +// ` +// err := db.QueryRow(query, n.ID, n.UserID, n.Type, n.Title, n.Message, n.Link, +// n.ResourceType, n.ResourceID, n.Priority, n.Metadata, n.ExpiresAt).Scan(&n.CreatedAt) +// return err +// } + +// func GetNotificationsByUserID(userID int64, unreadOnly bool) ([]Notification, error) { +// var notifications []Notification +// query := ` +// SELECT id, user_id, type, title, message, link, resource_type, resource_id, +// email_sent, email_sent_at, slack_sent, slack_sent_at, +// discord_sent, discord_sent_at, webhook_sent, webhook_sent_at, +// is_read, read_at, priority, metadata, created_at, expires_at +// FROM notifications +// WHERE user_id = ? OR user_id IS NULL +// ` +// if unreadOnly { +// query += " AND is_read = 0" +// } +// query += " ORDER BY created_at DESC LIMIT 100" + +// rows, err := db.Query(query, userID) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// for rows.Next() { +// var notif Notification +// err := rows.Scan( +// ¬if.ID, ¬if.UserID, ¬if.Type, ¬if.Title, ¬if.Message, +// ¬if.Link, ¬if.ResourceType, ¬if.ResourceID, +// ¬if.EmailSent, ¬if.EmailSentAt, ¬if.SlackSent, ¬if.SlackSentAt, +// ¬if.DiscordSent, ¬if.DiscordSentAt, ¬if.WebhookSent, ¬if.WebhookSentAt, +// ¬if.IsRead, ¬if.ReadAt, ¬if.Priority, ¬if.Metadata, +// ¬if.CreatedAt, ¬if.ExpiresAt, +// ) +// if err != nil { +// return nil, err +// } +// notifications = append(notifications, notif) +// } + +// return notifications, rows.Err() +// } + +// func (n *Notification) MarkAsRead() error { +// query := ` +// UPDATE notifications +// SET is_read = 1, read_at = CURRENT_TIMESTAMP +// WHERE id = ? +// ` +// _, err := db.Exec(query, n.ID) +// return err +// } + +// func MarkAllAsRead(userID int64) error { +// query := ` +// UPDATE notifications +// SET is_read = 1, read_at = CURRENT_TIMESTAMP +// WHERE user_id = ? AND is_read = 0 +// ` +// _, err := db.Exec(query, userID) +// return err +// } + +// func DeleteNotification(notificationID int64) error { +// query := `DELETE FROM notifications WHERE id = ?` +// _, err := db.Exec(query, notificationID) +// return err +// } + +// func DeleteExpiredNotifications() error { +// query := ` +// DELETE FROM notifications +// WHERE expires_at IS NOT NULL AND expires_at < CURRENT_TIMESTAMP +// ` +// _, err := db.Exec(query) +// return err +// } From b275bf79da5000d03b73b3da8a76823d864d71a4 Mon Sep 17 00:00:00 2001 From: Tanish Date: Thu, 15 Jan 2026 00:45:31 +0530 Subject: [PATCH 15/48] gormified project projectMembers registries serviceTemplate files --- server/models/project.go | 686 +++++++++++++++++++------------ server/models/projectMembers.go | 17 +- server/models/registries.go | 22 +- server/models/serviceTemplate.go | 395 ++++++++++++------ 4 files changed, 717 insertions(+), 403 deletions(-) diff --git a/server/models/project.go b/server/models/project.go index ed1c3ff..6c1fb70 100644 --- a/server/models/project.go +++ b/server/models/project.go @@ -1,40 +1,63 @@ package models import ( - "database/sql" "strings" "time" "github.com/corecollectives/mist/utils" + "gorm.io/gorm" ) type Project struct { - ID int64 `json:"id"` - Name string `json:"name"` - Description sql.NullString `json:"description"` - Tags []sql.NullString `json:"tags"` - OwnerID int64 `json:"ownerId"` - Owner *User `json:"owner,omitempty"` - ProjectMembers []User `json:"projectMembers"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID int64 `gorm:"primaryKey;autoIncrement:false" json:"id"` + Name string `gorm:"not null" json:"name"` + Description *string `json:"description"` + + TagsString string `gorm:"column:tags" json:"-"` + Tags []string `gorm:"-" json:"tags"` + + OwnerID int64 `gorm:"not null" json:"ownerId"` + Owner *User `gorm:"foreignKey:OwnerID" json:"owner,omitempty"` + + ProjectMembers []User `gorm:"many2many:project_members;" json:"projectMembers"` + + CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` + UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"` } -func (p *Project) ToJSON() map[string]interface{} { - tags := []string{} - for _, tag := range p.Tags { - if tag.Valid { - tags = append(tags, tag.String) - } +func (p *Project) BeforeSave(tx *gorm.DB) (err error) { + if len(p.Tags) > 0 { + p.TagsString = strings.Join(p.Tags, ",") + } else { + p.TagsString = "" } - if len(tags) == 0 { + return +} + +func (p *Project) AfterFind(tx *gorm.DB) (err error) { + if p.TagsString != "" { + p.Tags = strings.Split(p.TagsString, ",") + } else { + p.Tags = []string{} + } + return +} + +func (p *Project) ToJSON() map[string]interface{} { + tags := p.Tags + if tags == nil { tags = []string{} } + desc := "" + if p.Description != nil { + desc = *p.Description + } + return map[string]interface{}{ "id": p.ID, "name": p.Name, - "description": p.Description.String, + "description": desc, "tags": tags, "ownerId": p.OwnerID, "owner": p.Owner, @@ -47,285 +70,436 @@ func (p *Project) ToJSON() map[string]interface{} { func (p *Project) InsertInDB() error { p.ID = utils.GenerateRandomId() - tagsStr := "" - if len(p.Tags) > 0 { - for i, tag := range p.Tags { - if i > 0 { - tagsStr += "," - } - tagsStr += tag.String - } - } - - var desc interface{} - if p.Description.Valid { - desc = p.Description.String - } else { - desc = nil - } - - query := ` - INSERT INTO projects (id, name, description, tags, owner_id) - VALUES ($1, $2, $3, $4, $5) - RETURNING id, created_at, updated_at - ` - err := db.QueryRow(query, p.ID, p.Name, desc, tagsStr, p.OwnerID).Scan( - &p.ID, &p.CreatedAt, &p.UpdatedAt, - ) - if err != nil { + if err := db.Create(p).Error; err != nil { return err } - _, err = db.Exec(` - INSERT INTO project_members (project_id, user_id) - VALUES ($1, $2) - ON CONFLICT DO NOTHING - `, p.ID, p.OwnerID) - if err != nil { - return err - } - - user, err := GetUserByID(p.OwnerID) - if err != nil { + owner := User{ID: p.OwnerID} + if err := db.Model(p).Association("ProjectMembers").Append(&owner); err != nil { return err } - p.Owner = user - p.ProjectMembers = []User{*user} + p.Owner = &owner + p.ProjectMembers = []User{owner} return nil } func GetProjectByID(projectID int64) (*Project, error) { - query := ` - SELECT - p.id, p.name, p.description, p.tags, p.owner_id, p.created_at, p.updated_at, - u.id, u.username, u.email, u.role, u.avatar_url, u.created_at - FROM projects p - JOIN users u ON p.owner_id = u.id - WHERE p.id = $1 - ` - - project := &Project{} - owner := &User{} - var tagsStr sql.NullString - - err := db.QueryRow(query, projectID).Scan( - &project.ID, - &project.Name, - &project.Description, - &tagsStr, - &project.OwnerID, - &project.CreatedAt, - &project.UpdatedAt, - &owner.ID, - &owner.Username, - &owner.Email, - &owner.Role, - &owner.AvatarURL, - &owner.CreatedAt, - ) - if err != nil { - return nil, err - } - - if tagsStr.Valid { - strTags := strings.Split(tagsStr.String, ",") - tags := make([]sql.NullString, len(strTags)) - for i, s := range strTags { - tags[i] = sql.NullString{ - String: s, - Valid: true, - } - } - project.Tags = tags - } - - project.Owner = owner + var p Project + err := db.Preload("Owner"). + Preload("ProjectMembers"). + First(&p, projectID).Error - memberQuery := ` - SELECT u.id, u.username, u.email, u.role, u.avatar_url, u.created_at - FROM users u - JOIN project_members pm ON u.id = pm.user_id - WHERE pm.project_id = $1 - ` - rows, err := db.Query(memberQuery, projectID) if err != nil { return nil, err } - defer rows.Close() - - var members []User - for rows.Next() { - var member User - if err := rows.Scan( - &member.ID, - &member.Username, - &member.Email, - &member.Role, - &member.AvatarURL, - &member.CreatedAt, - ); err != nil { - return nil, err - } - members = append(members, member) - } - project.ProjectMembers = members - - return project, nil + return &p, nil } func DeleteProjectByID(projectID int64) error { - query := `DELETE FROM projects WHERE id = $1` - _, err := db.Exec(query, projectID) - return err + return db.Delete(&Project{}, projectID).Error } func UpdateProject(p *Project) error { - query := ` - UPDATE projects - SET name = $1, description = $2, tags = $3, updated_at = CURRENT_TIMESTAMP - WHERE id = $4 - RETURNING updated_at - ` - tagsStr := "" - if len(p.Tags) > 0 { - for i, tag := range p.Tags { - if i > 0 { - tagsStr += "," - } - tagsStr += tag.String - } - } - - return db.QueryRow(query, p.Name, p.Description, tagsStr, p.ID).Scan(&p.UpdatedAt) + return db.Model(p).Updates(map[string]interface{}{ + "name": p.Name, + "description": p.Description, + "tags": strings.Join(p.Tags, ","), + "updated_at": time.Now(), + }).Error } func GetProjectsUserIsPartOf(userID int64) ([]Project, error) { - query := ` - SELECT - p.id, p.name, p.description, p.tags, p.owner_id, p.created_at, p.updated_at, - u.id, u.username, u.email, u.role, u.avatar_url, u.created_at - FROM projects p - JOIN project_members pm ON p.id = pm.project_id - JOIN users u ON p.owner_id = u.id - WHERE pm.user_id = $1 - ` - - rows, err := db.Query(query, userID) - if err != nil { - return nil, err - } - defer rows.Close() - var projects []Project - for rows.Next() { - var project Project - var owner User - var tagsStr sql.NullString - - err := rows.Scan( - &project.ID, - &project.Name, - &project.Description, - &tagsStr, - &project.OwnerID, - &project.CreatedAt, - &project.UpdatedAt, - &owner.ID, - &owner.Username, - &owner.Email, - &owner.Role, - &owner.AvatarURL, - &owner.CreatedAt, - ) - if err != nil { - return nil, err - } - if tagsStr.Valid { - strTags := strings.Split(tagsStr.String, ",") - tags := make([]sql.NullString, len(strTags)) - for i, s := range strTags { - tags[i] = sql.NullString{ - String: s, - Valid: true, - } - } - project.Tags = tags - } - - project.Owner = &owner - projects = append(projects, project) - } + err := db.Preload("Owner"). + Joins("JOIN project_members pm ON pm.project_id = projects.id"). + Where("pm.user_id = ?", userID). + Find(&projects).Error - return projects, nil + return projects, err } func HasUserAccessToProject(userID, projectID int64) (bool, error) { - query := ` - SELECT COUNT(1) - FROM project_members - WHERE project_id = $1 AND user_id = $2 - ` - var count int - err := db.QueryRow(query, projectID, userID).Scan(&count) - if err != nil { - return false, err - } - return count > 0, nil + var count int64 + err := db.Table("project_members"). + Where("project_id = ? AND user_id = ?", projectID, userID). + Count(&count).Error + + return count > 0, err } func IsUserProjectOwner(userID, projectID int64) (bool, error) { - query := `SELECT owner_id FROM projects WHERE id = $1` - var ownerID int64 - err := db.QueryRow(query, projectID).Scan(&ownerID) - if err != nil { - return false, err - } - return ownerID == userID, nil + var count int64 + err := db.Model(&Project{}). + Where("id = ? AND owner_id = ?", projectID, userID). + Count(&count).Error + return count > 0, err } func UpdateProjectMembers(projectID int64, userIDs []int64) error { - query := `SELECT owner_id FROM projects WHERE id = $1` - var ownerID int64 - err := db.QueryRow(query, projectID).Scan(&ownerID) - if err != nil { - return err - } - - tx, err := db.Begin() - if err != nil { - return err - } - defer tx.Rollback() + return db.Transaction(func(tx *gorm.DB) error { + var project Project + if err := tx.Select("owner_id").First(&project, projectID).Error; err != nil { + return err + } - _, err = tx.Exec(`DELETE FROM project_members WHERE project_id = $1 AND user_id != $2`, projectID, ownerID) - if err != nil { - return err - } + ownerIncluded := false + for _, uid := range userIDs { + if uid == project.OwnerID { + ownerIncluded = true + break + } + } + if !ownerIncluded { + userIDs = append(userIDs, project.OwnerID) + } - ownerIncluded := false - for _, userID := range userIDs { - if userID == ownerID { - ownerIncluded = true - break + var users []User + for _, uid := range userIDs { + users = append(users, User{ID: uid}) } - } - if !ownerIncluded { - userIDs = append(userIDs, ownerID) - } - for _, userID := range userIDs { - _, err = tx.Exec(` - INSERT INTO project_members (project_id, user_id) - VALUES ($1, $2) - ON CONFLICT (project_id, user_id) DO NOTHING - `, projectID, userID) - if err != nil { + if err := tx.Model(&Project{ID: projectID}).Association("ProjectMembers").Replace(users); err != nil { return err } - } - return tx.Commit() + return nil + }) } + +//############################################################################################################ +//ARCHIVED CODE BELOW + +// package models + +// import ( +// "database/sql" +// "strings" +// "time" + +// "github.com/corecollectives/mist/utils" +// ) + +// type Project struct { +// ID int64 `json:"id"` +// Name string `json:"name"` +// Description sql.NullString `json:"description"` +// Tags []sql.NullString `json:"tags"` +// OwnerID int64 `json:"ownerId"` +// Owner *User `json:"owner,omitempty"` +// ProjectMembers []User `json:"projectMembers"` +// CreatedAt time.Time `json:"createdAt"` +// UpdatedAt time.Time `json:"updatedAt"` +// } + +// func (p *Project) ToJSON() map[string]interface{} { +// tags := []string{} +// for _, tag := range p.Tags { +// if tag.Valid { +// tags = append(tags, tag.String) +// } +// } +// if len(tags) == 0 { +// tags = []string{} +// } + +// return map[string]interface{}{ +// "id": p.ID, +// "name": p.Name, +// "description": p.Description.String, +// "tags": tags, +// "ownerId": p.OwnerID, +// "owner": p.Owner, +// "projectMembers": p.ProjectMembers, +// "createdAt": p.CreatedAt, +// "updatedAt": p.UpdatedAt, +// } +// } + +// func (p *Project) InsertInDB() error { +// p.ID = utils.GenerateRandomId() + +// tagsStr := "" +// if len(p.Tags) > 0 { +// for i, tag := range p.Tags { +// if i > 0 { +// tagsStr += "," +// } +// tagsStr += tag.String +// } +// } + +// var desc interface{} +// if p.Description.Valid { +// desc = p.Description.String +// } else { +// desc = nil +// } + +// query := ` +// INSERT INTO projects (id, name, description, tags, owner_id) +// VALUES ($1, $2, $3, $4, $5) +// RETURNING id, created_at, updated_at +// ` +// err := db.QueryRow(query, p.ID, p.Name, desc, tagsStr, p.OwnerID).Scan( +// &p.ID, &p.CreatedAt, &p.UpdatedAt, +// ) +// if err != nil { +// return err +// } + +// _, err = db.Exec(` +// INSERT INTO project_members (project_id, user_id) +// VALUES ($1, $2) +// ON CONFLICT DO NOTHING +// `, p.ID, p.OwnerID) +// if err != nil { +// return err +// } + +// user, err := GetUserByID(p.OwnerID) +// if err != nil { +// return err +// } +// p.Owner = user + +// p.ProjectMembers = []User{*user} + +// return nil +// } + +// func GetProjectByID(projectID int64) (*Project, error) { +// query := ` +// SELECT +// p.id, p.name, p.description, p.tags, p.owner_id, p.created_at, p.updated_at, +// u.id, u.username, u.email, u.role, u.avatar_url, u.created_at +// FROM projects p +// JOIN users u ON p.owner_id = u.id +// WHERE p.id = $1 +// ` + +// project := &Project{} +// owner := &User{} +// var tagsStr sql.NullString + +// err := db.QueryRow(query, projectID).Scan( +// &project.ID, +// &project.Name, +// &project.Description, +// &tagsStr, +// &project.OwnerID, +// &project.CreatedAt, +// &project.UpdatedAt, +// &owner.ID, +// &owner.Username, +// &owner.Email, +// &owner.Role, +// &owner.AvatarURL, +// &owner.CreatedAt, +// ) +// if err != nil { +// return nil, err +// } + +// if tagsStr.Valid { +// strTags := strings.Split(tagsStr.String, ",") +// tags := make([]sql.NullString, len(strTags)) +// for i, s := range strTags { +// tags[i] = sql.NullString{ +// String: s, +// Valid: true, +// } +// } +// project.Tags = tags +// } + +// project.Owner = owner + +// memberQuery := ` +// SELECT u.id, u.username, u.email, u.role, u.avatar_url, u.created_at +// FROM users u +// JOIN project_members pm ON u.id = pm.user_id +// WHERE pm.project_id = $1 +// ` +// rows, err := db.Query(memberQuery, projectID) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// var members []User +// for rows.Next() { +// var member User +// if err := rows.Scan( +// &member.ID, +// &member.Username, +// &member.Email, +// &member.Role, +// &member.AvatarURL, +// &member.CreatedAt, +// ); err != nil { +// return nil, err +// } +// members = append(members, member) +// } +// project.ProjectMembers = members + +// return project, nil +// } + +// func DeleteProjectByID(projectID int64) error { +// query := `DELETE FROM projects WHERE id = $1` +// _, err := db.Exec(query, projectID) +// return err +// } + +// func UpdateProject(p *Project) error { +// query := ` +// UPDATE projects +// SET name = $1, description = $2, tags = $3, updated_at = CURRENT_TIMESTAMP +// WHERE id = $4 +// RETURNING updated_at +// ` +// tagsStr := "" +// if len(p.Tags) > 0 { +// for i, tag := range p.Tags { +// if i > 0 { +// tagsStr += "," +// } +// tagsStr += tag.String +// } +// } + +// return db.QueryRow(query, p.Name, p.Description, tagsStr, p.ID).Scan(&p.UpdatedAt) +// } + +// func GetProjectsUserIsPartOf(userID int64) ([]Project, error) { +// query := ` +// SELECT +// p.id, p.name, p.description, p.tags, p.owner_id, p.created_at, p.updated_at, +// u.id, u.username, u.email, u.role, u.avatar_url, u.created_at +// FROM projects p +// JOIN project_members pm ON p.id = pm.project_id +// JOIN users u ON p.owner_id = u.id +// WHERE pm.user_id = $1 +// ` + +// rows, err := db.Query(query, userID) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// var projects []Project +// for rows.Next() { +// var project Project +// var owner User +// var tagsStr sql.NullString + +// err := rows.Scan( +// &project.ID, +// &project.Name, +// &project.Description, +// &tagsStr, +// &project.OwnerID, +// &project.CreatedAt, +// &project.UpdatedAt, +// &owner.ID, +// &owner.Username, +// &owner.Email, +// &owner.Role, +// &owner.AvatarURL, +// &owner.CreatedAt, +// ) +// if err != nil { +// return nil, err +// } + +// if tagsStr.Valid { +// strTags := strings.Split(tagsStr.String, ",") +// tags := make([]sql.NullString, len(strTags)) +// for i, s := range strTags { +// tags[i] = sql.NullString{ +// String: s, +// Valid: true, +// } +// } +// project.Tags = tags +// } + +// project.Owner = &owner +// projects = append(projects, project) +// } + +// return projects, nil +// } + +// func HasUserAccessToProject(userID, projectID int64) (bool, error) { +// query := ` +// SELECT COUNT(1) +// FROM project_members +// WHERE project_id = $1 AND user_id = $2 +// ` +// var count int +// err := db.QueryRow(query, projectID, userID).Scan(&count) +// if err != nil { +// return false, err +// } +// return count > 0, nil +// } + +// func IsUserProjectOwner(userID, projectID int64) (bool, error) { +// query := `SELECT owner_id FROM projects WHERE id = $1` +// var ownerID int64 +// err := db.QueryRow(query, projectID).Scan(&ownerID) +// if err != nil { +// return false, err +// } +// return ownerID == userID, nil +// } + +// func UpdateProjectMembers(projectID int64, userIDs []int64) error { +// query := `SELECT owner_id FROM projects WHERE id = $1` +// var ownerID int64 +// err := db.QueryRow(query, projectID).Scan(&ownerID) +// if err != nil { +// return err +// } + +// tx, err := db.Begin() +// if err != nil { +// return err +// } +// defer tx.Rollback() + +// _, err = tx.Exec(`DELETE FROM project_members WHERE project_id = $1 AND user_id != $2`, projectID, ownerID) +// if err != nil { +// return err +// } + +// ownerIncluded := false +// for _, userID := range userIDs { +// if userID == ownerID { +// ownerIncluded = true +// break +// } +// } +// if !ownerIncluded { +// userIDs = append(userIDs, ownerID) +// } + +// for _, userID := range userIDs { +// _, err = tx.Exec(` +// INSERT INTO project_members (project_id, user_id) +// VALUES ($1, $2) +// ON CONFLICT (project_id, user_id) DO NOTHING +// `, projectID, userID) +// if err != nil { +// return err +// } +// } + +// return tx.Commit() +// } diff --git a/server/models/projectMembers.go b/server/models/projectMembers.go index 2d9fb85..cda414d 100644 --- a/server/models/projectMembers.go +++ b/server/models/projectMembers.go @@ -2,9 +2,14 @@ package models import "time" -type ProjectMembers struct{ - ID int64 `json:"id"` - ProjectID int64 `json:"project_id"` - USERID int64 `json:"user_id"` - AddedAt time.Time `json:"added_at"` -} \ No newline at end of file +type ProjectMember struct { + UserID int64 `gorm:"primaryKey;autoIncrement:false" json:"user_id"` + + ProjectID int64 `gorm:"primaryKey;autoIncrement:false" json:"project_id"` + + AddedAt time.Time `gorm:"autoCreateTime" json:"added_at"` +} + +func (ProjectMember) TableName() string { + return "project_members" +} diff --git a/server/models/registries.go b/server/models/registries.go index 32b37b9..509885e 100644 --- a/server/models/registries.go +++ b/server/models/registries.go @@ -2,11 +2,19 @@ package models import "time" -type Registries struct { - ID int64 `json:"id"` - ProjectID int64 `json:"projectId"` - RegistryURL string `json:"registryUrl"` - Username string `json:"username"` - Password string `json:"password"` - CreatedAt time.Time `json:"createdAt"` +type Registry struct { + ID int64 `gorm:"primaryKey;autoIncrement:true" json:"id"` + + ProjectID int64 `gorm:"uniqueIndex:idx_project_registry;not null;constraint:OnDelete:CASCADE" json:"projectId"` + + RegistryURL string `gorm:"uniqueIndex:idx_project_registry;not null" json:"registryUrl"` + + Username string `json:"username"` + Password string `json:"password"` + + CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` +} + +func (Registry) TableName() string { + return "registries" } diff --git a/server/models/serviceTemplate.go b/server/models/serviceTemplate.go index 36be0c1..f75c9ae 100644 --- a/server/models/serviceTemplate.go +++ b/server/models/serviceTemplate.go @@ -1,8 +1,9 @@ package models import ( - "database/sql" "time" + + "gorm.io/gorm" ) type ServiceTemplateCategory string @@ -16,32 +17,48 @@ const ( ) type ServiceTemplate struct { - ID int64 `db:"id" json:"id"` - Name string `db:"name" json:"name"` - DisplayName string `db:"display_name" json:"displayName"` - Category ServiceTemplateCategory `db:"category" json:"category"` - Description *string `db:"description" json:"description,omitempty"` - IconURL *string `db:"icon_url" json:"iconUrl,omitempty"` - DockerImage string `db:"docker_image" json:"dockerImage"` - DockerImageVersion *string `db:"docker_image_version" json:"dockerImageVersion,omitempty"` - DefaultPort int `db:"default_port" json:"defaultPort"` - DefaultEnvVars *string `db:"default_env_vars" json:"defaultEnvVars,omitempty"` - RequiredEnvVars *string `db:"required_env_vars" json:"requiredEnvVars,omitempty"` - DefaultVolumePath *string `db:"default_volume_path" json:"defaultVolumePath,omitempty"` - VolumeRequired bool `db:"volume_required" json:"volumeRequired"` - RecommendedCPU *float64 `db:"recommended_cpu" json:"recommendedCpu,omitempty"` - RecommendedMemory *int `db:"recommended_memory" json:"recommendedMemory,omitempty"` - MinMemory *int `db:"min_memory" json:"minMemory,omitempty"` - HealthcheckCommand *string `db:"healthcheck_command" json:"healthcheckCommand,omitempty"` - HealthcheckInterval int `db:"healthcheck_interval" json:"healthcheckInterval"` - AdminUIImage *string `db:"admin_ui_image" json:"adminUiImage,omitempty"` - AdminUIPort *int `db:"admin_ui_port" json:"adminUiPort,omitempty"` - SetupInstructions *string `db:"setup_instructions" json:"setupInstructions,omitempty"` - IsActive bool `db:"is_active" json:"isActive"` - IsFeatured bool `db:"is_featured" json:"isFeatured"` - SortOrder int `db:"sort_order" json:"sortOrder"` - CreatedAt time.Time `db:"created_at" json:"createdAt"` - UpdatedAt time.Time `db:"updated_at" json:"updatedAt"` + ID int64 `gorm:"primaryKey;autoIncrement:true" json:"id"` + + Name string `gorm:"uniqueIndex;not null" json:"name"` + + DisplayName string `gorm:"not null" json:"displayName"` + + Category ServiceTemplateCategory `gorm:"default:'database';index" json:"category"` + + Description *string `json:"description,omitempty"` + IconURL *string `json:"iconUrl,omitempty"` + + DockerImage string `gorm:"not null" json:"dockerImage"` + DockerImageVersion *string `json:"dockerImageVersion,omitempty"` + + DefaultPort int `gorm:"not null" json:"defaultPort"` + DefaultEnvVars *string `json:"defaultEnvVars,omitempty"` + RequiredEnvVars *string `json:"requiredEnvVars,omitempty"` + + DefaultVolumePath *string `json:"defaultVolumePath,omitempty"` + + VolumeRequired bool `gorm:"default:true" json:"volumeRequired"` + + RecommendedCPU *float64 `json:"recommendedCpu,omitempty"` + RecommendedMemory *int `json:"recommendedMemory,omitempty"` + MinMemory *int `json:"minMemory,omitempty"` + + HealthcheckCommand *string `json:"healthcheckCommand,omitempty"` + + HealthcheckInterval int `gorm:"default:30" json:"healthcheckInterval"` + + AdminUIImage *string `json:"adminUiImage,omitempty"` + AdminUIPort *int `json:"adminUiPort,omitempty"` + SetupInstructions *string `json:"setupInstructions,omitempty"` + + IsActive bool `gorm:"default:true;index" json:"isActive"` + + IsFeatured bool `gorm:"default:false" json:"isFeatured"` + + SortOrder int `gorm:"default:0;index" json:"sortOrder"` + + CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` + UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"` } func (st *ServiceTemplate) ToJson() map[string]interface{} { @@ -77,77 +94,21 @@ func (st *ServiceTemplate) ToJson() map[string]interface{} { func GetAllServiceTemplates() ([]ServiceTemplate, error) { var templates []ServiceTemplate - query := ` - SELECT id, name, display_name, category, description, icon_url, - docker_image, docker_image_version, default_port, default_env_vars, - required_env_vars, default_volume_path, volume_required, - recommended_cpu, recommended_memory, min_memory, - healthcheck_command, healthcheck_interval, - admin_ui_image, admin_ui_port, setup_instructions, - is_active, is_featured, sort_order, created_at, updated_at - FROM service_templates - WHERE is_active = 1 - ORDER BY sort_order, display_name - ` - rows, err := db.Query(query) - if err != nil { - return nil, err - } - defer rows.Close() - - for rows.Next() { - var template ServiceTemplate - err := rows.Scan( - &template.ID, &template.Name, &template.DisplayName, &template.Category, - &template.Description, &template.IconURL, &template.DockerImage, - &template.DockerImageVersion, &template.DefaultPort, &template.DefaultEnvVars, - &template.RequiredEnvVars, &template.DefaultVolumePath, &template.VolumeRequired, - &template.RecommendedCPU, &template.RecommendedMemory, &template.MinMemory, - &template.HealthcheckCommand, &template.HealthcheckInterval, - &template.AdminUIImage, &template.AdminUIPort, &template.SetupInstructions, - &template.IsActive, &template.IsFeatured, &template.SortOrder, - &template.CreatedAt, &template.UpdatedAt, - ) - if err != nil { - return nil, err - } - templates = append(templates, template) - } - - if err = rows.Err(); err != nil { - return nil, err - } - return templates, nil + err := db.Where("is_active = ?", true). + Order("sort_order, display_name"). + Find(&templates).Error + return templates, err } func GetServiceTemplateByName(name string) (*ServiceTemplate, error) { var template ServiceTemplate - query := ` - SELECT id, name, display_name, category, description, icon_url, - docker_image, docker_image_version, default_port, default_env_vars, - required_env_vars, default_volume_path, volume_required, - recommended_cpu, recommended_memory, min_memory, - healthcheck_command, healthcheck_interval, - admin_ui_image, admin_ui_port, setup_instructions, - is_active, is_featured, sort_order, created_at, updated_at - FROM service_templates - WHERE name = ? AND is_active = 1 - ` - err := db.QueryRow(query, name).Scan( - &template.ID, &template.Name, &template.DisplayName, &template.Category, - &template.Description, &template.IconURL, &template.DockerImage, - &template.DockerImageVersion, &template.DefaultPort, &template.DefaultEnvVars, - &template.RequiredEnvVars, &template.DefaultVolumePath, &template.VolumeRequired, - &template.RecommendedCPU, &template.RecommendedMemory, &template.MinMemory, - &template.HealthcheckCommand, &template.HealthcheckInterval, - &template.AdminUIImage, &template.AdminUIPort, &template.SetupInstructions, - &template.IsActive, &template.IsFeatured, &template.SortOrder, - &template.CreatedAt, &template.UpdatedAt, - ) - if err == sql.ErrNoRows { - return nil, nil - } + err := db.Where("name = ? AND is_active = ?", name, true). + First(&template).Error + if err != nil { + if err == gorm.ErrRecordNotFound { + return nil, nil + } return nil, err } return &template, nil @@ -155,45 +116,211 @@ func GetServiceTemplateByName(name string) (*ServiceTemplate, error) { func GetServiceTemplatesByCategory(category ServiceTemplateCategory) ([]ServiceTemplate, error) { var templates []ServiceTemplate - query := ` - SELECT id, name, display_name, category, description, icon_url, - docker_image, docker_image_version, default_port, default_env_vars, - required_env_vars, default_volume_path, volume_required, - recommended_cpu, recommended_memory, min_memory, - healthcheck_command, healthcheck_interval, - admin_ui_image, admin_ui_port, setup_instructions, - is_active, is_featured, sort_order, created_at, updated_at - FROM service_templates - WHERE category = ? AND is_active = 1 - ORDER BY sort_order, display_name - ` - rows, err := db.Query(query, category) - if err != nil { - return nil, err - } - defer rows.Close() - - for rows.Next() { - var template ServiceTemplate - err := rows.Scan( - &template.ID, &template.Name, &template.DisplayName, &template.Category, - &template.Description, &template.IconURL, &template.DockerImage, - &template.DockerImageVersion, &template.DefaultPort, &template.DefaultEnvVars, - &template.RequiredEnvVars, &template.DefaultVolumePath, &template.VolumeRequired, - &template.RecommendedCPU, &template.RecommendedMemory, &template.MinMemory, - &template.HealthcheckCommand, &template.HealthcheckInterval, - &template.AdminUIImage, &template.AdminUIPort, &template.SetupInstructions, - &template.IsActive, &template.IsFeatured, &template.SortOrder, - &template.CreatedAt, &template.UpdatedAt, - ) - if err != nil { - return nil, err - } - templates = append(templates, template) - } - - if err = rows.Err(); err != nil { - return nil, err - } - return templates, nil + err := db.Where("category = ? AND is_active = ?", category, true). + Order("sort_order, display_name"). + Find(&templates).Error + return templates, err } + +//############################################################################################################### +//ARCHIVED CODE BELOW + +// package models + +// import ( +// "database/sql" +// "time" +// ) + +// type ServiceTemplateCategory string + +// const ( +// CategoryDatabase ServiceTemplateCategory = "database" +// CategoryCache ServiceTemplateCategory = "cache" +// CategoryQueue ServiceTemplateCategory = "queue" +// CategoryStorage ServiceTemplateCategory = "storage" +// CategoryOther ServiceTemplateCategory = "other" +// ) + +// type ServiceTemplate struct { +// ID int64 `db:"id" json:"id"` +// Name string `db:"name" json:"name"` +// DisplayName string `db:"display_name" json:"displayName"` +// Category ServiceTemplateCategory `db:"category" json:"category"` +// Description *string `db:"description" json:"description,omitempty"` +// IconURL *string `db:"icon_url" json:"iconUrl,omitempty"` +// DockerImage string `db:"docker_image" json:"dockerImage"` +// DockerImageVersion *string `db:"docker_image_version" json:"dockerImageVersion,omitempty"` +// DefaultPort int `db:"default_port" json:"defaultPort"` +// DefaultEnvVars *string `db:"default_env_vars" json:"defaultEnvVars,omitempty"` +// RequiredEnvVars *string `db:"required_env_vars" json:"requiredEnvVars,omitempty"` +// DefaultVolumePath *string `db:"default_volume_path" json:"defaultVolumePath,omitempty"` +// VolumeRequired bool `db:"volume_required" json:"volumeRequired"` +// RecommendedCPU *float64 `db:"recommended_cpu" json:"recommendedCpu,omitempty"` +// RecommendedMemory *int `db:"recommended_memory" json:"recommendedMemory,omitempty"` +// MinMemory *int `db:"min_memory" json:"minMemory,omitempty"` +// HealthcheckCommand *string `db:"healthcheck_command" json:"healthcheckCommand,omitempty"` +// HealthcheckInterval int `db:"healthcheck_interval" json:"healthcheckInterval"` +// AdminUIImage *string `db:"admin_ui_image" json:"adminUiImage,omitempty"` +// AdminUIPort *int `db:"admin_ui_port" json:"adminUiPort,omitempty"` +// SetupInstructions *string `db:"setup_instructions" json:"setupInstructions,omitempty"` +// IsActive bool `db:"is_active" json:"isActive"` +// IsFeatured bool `db:"is_featured" json:"isFeatured"` +// SortOrder int `db:"sort_order" json:"sortOrder"` +// CreatedAt time.Time `db:"created_at" json:"createdAt"` +// UpdatedAt time.Time `db:"updated_at" json:"updatedAt"` +// } + +// func (st *ServiceTemplate) ToJson() map[string]interface{} { +// return map[string]interface{}{ +// "id": st.ID, +// "name": st.Name, +// "displayName": st.DisplayName, +// "category": st.Category, +// "description": st.Description, +// "iconUrl": st.IconURL, +// "dockerImage": st.DockerImage, +// "dockerImageVersion": st.DockerImageVersion, +// "defaultPort": st.DefaultPort, +// "defaultEnvVars": st.DefaultEnvVars, +// "requiredEnvVars": st.RequiredEnvVars, +// "defaultVolumePath": st.DefaultVolumePath, +// "volumeRequired": st.VolumeRequired, +// "recommendedCpu": st.RecommendedCPU, +// "recommendedMemory": st.RecommendedMemory, +// "minMemory": st.MinMemory, +// "healthcheckCommand": st.HealthcheckCommand, +// "healthcheckInterval": st.HealthcheckInterval, +// "adminUiImage": st.AdminUIImage, +// "adminUiPort": st.AdminUIPort, +// "setupInstructions": st.SetupInstructions, +// "isActive": st.IsActive, +// "isFeatured": st.IsFeatured, +// "sortOrder": st.SortOrder, +// "createdAt": st.CreatedAt, +// "updatedAt": st.UpdatedAt, +// } +// } + +// func GetAllServiceTemplates() ([]ServiceTemplate, error) { +// var templates []ServiceTemplate +// query := ` +// SELECT id, name, display_name, category, description, icon_url, +// docker_image, docker_image_version, default_port, default_env_vars, +// required_env_vars, default_volume_path, volume_required, +// recommended_cpu, recommended_memory, min_memory, +// healthcheck_command, healthcheck_interval, +// admin_ui_image, admin_ui_port, setup_instructions, +// is_active, is_featured, sort_order, created_at, updated_at +// FROM service_templates +// WHERE is_active = 1 +// ORDER BY sort_order, display_name +// ` +// rows, err := db.Query(query) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// for rows.Next() { +// var template ServiceTemplate +// err := rows.Scan( +// &template.ID, &template.Name, &template.DisplayName, &template.Category, +// &template.Description, &template.IconURL, &template.DockerImage, +// &template.DockerImageVersion, &template.DefaultPort, &template.DefaultEnvVars, +// &template.RequiredEnvVars, &template.DefaultVolumePath, &template.VolumeRequired, +// &template.RecommendedCPU, &template.RecommendedMemory, &template.MinMemory, +// &template.HealthcheckCommand, &template.HealthcheckInterval, +// &template.AdminUIImage, &template.AdminUIPort, &template.SetupInstructions, +// &template.IsActive, &template.IsFeatured, &template.SortOrder, +// &template.CreatedAt, &template.UpdatedAt, +// ) +// if err != nil { +// return nil, err +// } +// templates = append(templates, template) +// } + +// if err = rows.Err(); err != nil { +// return nil, err +// } +// return templates, nil +// } + +// func GetServiceTemplateByName(name string) (*ServiceTemplate, error) { +// var template ServiceTemplate +// query := ` +// SELECT id, name, display_name, category, description, icon_url, +// docker_image, docker_image_version, default_port, default_env_vars, +// required_env_vars, default_volume_path, volume_required, +// recommended_cpu, recommended_memory, min_memory, +// healthcheck_command, healthcheck_interval, +// admin_ui_image, admin_ui_port, setup_instructions, +// is_active, is_featured, sort_order, created_at, updated_at +// FROM service_templates +// WHERE name = ? AND is_active = 1 +// ` +// err := db.QueryRow(query, name).Scan( +// &template.ID, &template.Name, &template.DisplayName, &template.Category, +// &template.Description, &template.IconURL, &template.DockerImage, +// &template.DockerImageVersion, &template.DefaultPort, &template.DefaultEnvVars, +// &template.RequiredEnvVars, &template.DefaultVolumePath, &template.VolumeRequired, +// &template.RecommendedCPU, &template.RecommendedMemory, &template.MinMemory, +// &template.HealthcheckCommand, &template.HealthcheckInterval, +// &template.AdminUIImage, &template.AdminUIPort, &template.SetupInstructions, +// &template.IsActive, &template.IsFeatured, &template.SortOrder, +// &template.CreatedAt, &template.UpdatedAt, +// ) +// if err == sql.ErrNoRows { +// return nil, nil +// } +// if err != nil { +// return nil, err +// } +// return &template, nil +// } + +// func GetServiceTemplatesByCategory(category ServiceTemplateCategory) ([]ServiceTemplate, error) { +// var templates []ServiceTemplate +// query := ` +// SELECT id, name, display_name, category, description, icon_url, +// docker_image, docker_image_version, default_port, default_env_vars, +// required_env_vars, default_volume_path, volume_required, +// recommended_cpu, recommended_memory, min_memory, +// healthcheck_command, healthcheck_interval, +// admin_ui_image, admin_ui_port, setup_instructions, +// is_active, is_featured, sort_order, created_at, updated_at +// FROM service_templates +// WHERE category = ? AND is_active = 1 +// ORDER BY sort_order, display_name +// ` +// rows, err := db.Query(query, category) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// for rows.Next() { +// var template ServiceTemplate +// err := rows.Scan( +// &template.ID, &template.Name, &template.DisplayName, &template.Category, +// &template.Description, &template.IconURL, &template.DockerImage, +// &template.DockerImageVersion, &template.DefaultPort, &template.DefaultEnvVars, +// &template.RequiredEnvVars, &template.DefaultVolumePath, &template.VolumeRequired, +// &template.RecommendedCPU, &template.RecommendedMemory, &template.MinMemory, +// &template.HealthcheckCommand, &template.HealthcheckInterval, +// &template.AdminUIImage, &template.AdminUIPort, &template.SetupInstructions, +// &template.IsActive, &template.IsFeatured, &template.SortOrder, +// &template.CreatedAt, &template.UpdatedAt, +// ) +// if err != nil { +// return nil, err +// } +// templates = append(templates, template) +// } + +// if err = rows.Err(); err != nil { +// return nil, err +// } +// return templates, nil +// } From 07f26a448eb764448d18764a47fca44725b76180 Mon Sep 17 00:00:00 2001 From: Tanish Date: Thu, 15 Jan 2026 01:58:56 +0530 Subject: [PATCH 16/48] gormified session systemSettings updateLog user volume --- .../015_Create_System_settings.sql | 4 +- server/models/session.go | 303 +++++++---- server/models/systemSettings.go | 352 +++++++++++-- server/models/systemSettingsDbVer.go | 7 + server/models/updateLog.go | 477 ++++++++++++++---- server/models/user.go | 384 ++++++++++---- server/models/volume.go | 199 +++++--- 7 files changed, 1313 insertions(+), 413 deletions(-) create mode 100644 server/models/systemSettingsDbVer.go diff --git a/server/db/migrations_archive/015_Create_System_settings.sql b/server/db/migrations_archive/015_Create_System_settings.sql index 3f58c6e..9270aa8 100644 --- a/server/db/migrations_archive/015_Create_System_settings.sql +++ b/server/db/migrations_archive/015_Create_System_settings.sql @@ -1,5 +1,7 @@ -CREATE TABLE IF NOT EXISTS system_settings ( +CREATE TABLE IF NOT EXISTS system_settings_ ( key TEXT PRIMARY KEY, value TEXT NOT NULL, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ); + + diff --git a/server/models/session.go b/server/models/session.go index 68c0ab4..dbdad14 100644 --- a/server/models/session.go +++ b/server/models/session.go @@ -4,22 +4,31 @@ import ( "time" ) +type DeviceType string + +const ( + DeviceDesktop DeviceType = "desktop" + DeviceMobile DeviceType = "mobile" + DeviceTablet DeviceType = "tablet" + DeviceUnknown DeviceType = "unknown" +) + type Session struct { - ID string `db:"id" json:"id"` - UserID int64 `db:"user_id" json:"userId"` - SessionData *string `db:"session_data" json:"sessionData,omitempty"` // JSON - IPAddress *string `db:"ip_address" json:"ipAddress,omitempty"` - UserAgent *string `db:"user_agent" json:"userAgent,omitempty"` - DeviceType *string `db:"device_type" json:"deviceType,omitempty"` - Browser *string `db:"browser" json:"browser,omitempty"` - OS *string `db:"os" json:"os,omitempty"` - Location *string `db:"location" json:"location,omitempty"` - IsActive bool `db:"is_active" json:"isActive"` - LastActivityAt time.Time `db:"last_activity_at" json:"lastActivityAt"` - RevokedAt *time.Time `db:"revoked_at" json:"revokedAt,omitempty"` - RevokedReason *string `db:"revoked_reason" json:"revokedReason,omitempty"` - CreatedAt time.Time `db:"created_at" json:"createdAt"` - ExpiresAt time.Time `db:"expires_at" json:"expiresAt"` + ID string `gorm:"primaryKey" json:"id"` + UserID int64 `gorm:"index;not null;constraint:OnDelete:CASCADE" json:"userId"` + SessionData *string `json:"sessionData,omitempty"` + IPAddress *string `json:"ipAddress,omitempty"` + UserAgent *string `json:"userAgent,omitempty"` + DeviceType *string `json:"deviceType,omitempty"` + Browser *string `json:"browser,omitempty"` + OS *string `json:"os,omitempty"` + Location *string `json:"location,omitempty"` + IsActive bool `gorm:"default:true;index" json:"isActive"` + LastActivityAt time.Time `gorm:"autoUpdateTime" json:"lastActivityAt"` + RevokedAt *time.Time `json:"revokedAt,omitempty"` + RevokedReason *string `json:"revokedReason,omitempty"` + CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` + ExpiresAt time.Time `gorm:"not null;index" json:"expiresAt"` } func (s *Session) ToJson() map[string]interface{} { @@ -43,34 +52,12 @@ func (s *Session) ToJson() map[string]interface{} { } func (s *Session) InsertInDB() error { - query := ` - INSERT INTO sessions ( - id, user_id, session_data, ip_address, user_agent, - device_type, browser, os, location, expires_at - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - RETURNING created_at, last_activity_at - ` - err := db.QueryRow(query, s.ID, s.UserID, s.SessionData, s.IPAddress, s.UserAgent, - s.DeviceType, s.Browser, s.OS, s.Location, s.ExpiresAt).Scan(&s.CreatedAt, &s.LastActivityAt) - return err + return db.Create(s).Error } func GetSessionByID(sessionID string) (*Session, error) { var session Session - query := ` - SELECT id, user_id, session_data, ip_address, user_agent, - device_type, browser, os, location, is_active, - last_activity_at, revoked_at, revoked_reason, - created_at, expires_at - FROM sessions - WHERE id = ? AND is_active = 1 - ` - err := db.QueryRow(query, sessionID).Scan( - &session.ID, &session.UserID, &session.SessionData, &session.IPAddress, - &session.UserAgent, &session.DeviceType, &session.Browser, &session.OS, - &session.Location, &session.IsActive, &session.LastActivityAt, - &session.RevokedAt, &session.RevokedReason, &session.CreatedAt, &session.ExpiresAt, - ) + err := db.Where("id = ? AND is_active = ?", sessionID, true).First(&session).Error if err != nil { return nil, err } @@ -79,77 +66,193 @@ func GetSessionByID(sessionID string) (*Session, error) { func GetSessionsByUserID(userID int64) ([]Session, error) { var sessions []Session - query := ` - SELECT id, user_id, session_data, ip_address, user_agent, - device_type, browser, os, location, is_active, - last_activity_at, revoked_at, revoked_reason, - created_at, expires_at - FROM sessions - WHERE user_id = ? AND is_active = 1 - ORDER BY last_activity_at DESC - ` - rows, err := db.Query(query, userID) - if err != nil { - return nil, err - } - defer rows.Close() - - for rows.Next() { - var session Session - err := rows.Scan( - &session.ID, &session.UserID, &session.SessionData, &session.IPAddress, - &session.UserAgent, &session.DeviceType, &session.Browser, &session.OS, - &session.Location, &session.IsActive, &session.LastActivityAt, - &session.RevokedAt, &session.RevokedReason, &session.CreatedAt, &session.ExpiresAt, - ) - if err != nil { - return nil, err - } - sessions = append(sessions, session) - } - - return sessions, rows.Err() + err := db.Where("user_id = ? AND is_active = ?", userID, true). + Order("last_activity_at DESC"). + Find(&sessions).Error + return sessions, err } func (s *Session) UpdateActivity() error { - query := ` - UPDATE sessions - SET last_activity_at = CURRENT_TIMESTAMP - WHERE id = ? - ` - _, err := db.Exec(query, s.ID) - return err + return db.Model(s).Update("last_activity_at", time.Now()).Error } func (s *Session) Revoke(reason string) error { - query := ` - UPDATE sessions - SET is_active = 0, - revoked_at = CURRENT_TIMESTAMP, - revoked_reason = ? - WHERE id = ? - ` - _, err := db.Exec(query, reason, s.ID) - return err + return db.Model(s).Updates(map[string]interface{}{ + "is_active": false, + "revoked_at": time.Now(), + "revoked_reason": reason, + }).Error } func RevokeAllUserSessions(userID int64, reason string) error { - query := ` - UPDATE sessions - SET is_active = 0, - revoked_at = CURRENT_TIMESTAMP, - revoked_reason = ? - WHERE user_id = ? AND is_active = 1 - ` - _, err := db.Exec(query, reason, userID) - return err + return db.Model(&Session{}). + Where("user_id = ? AND is_active = ?", userID, true). + Updates(map[string]interface{}{ + "is_active": false, + "revoked_at": time.Now(), + "revoked_reason": reason, + }).Error } func DeleteExpiredSessions() error { - query := ` - DELETE FROM sessions - WHERE expires_at < CURRENT_TIMESTAMP - ` - _, err := db.Exec(query) - return err + return db.Where("expires_at < ?", time.Now()).Delete(&Session{}).Error } + +//################################################################################################ +//ARCHIVED CODE BELOW + +// package models + +// import ( +// "time" +// ) + +// type Session struct { +// ID string `db:"id" json:"id"` +// UserID int64 `db:"user_id" json:"userId"` +// SessionData *string `db:"session_data" json:"sessionData,omitempty"` // JSON +// IPAddress *string `db:"ip_address" json:"ipAddress,omitempty"` +// UserAgent *string `db:"user_agent" json:"userAgent,omitempty"` +// DeviceType *string `db:"device_type" json:"deviceType,omitempty"` +// Browser *string `db:"browser" json:"browser,omitempty"` +// OS *string `db:"os" json:"os,omitempty"` +// Location *string `db:"location" json:"location,omitempty"` +// IsActive bool `db:"is_active" json:"isActive"` +// LastActivityAt time.Time `db:"last_activity_at" json:"lastActivityAt"` +// RevokedAt *time.Time `db:"revoked_at" json:"revokedAt,omitempty"` +// RevokedReason *string `db:"revoked_reason" json:"revokedReason,omitempty"` +// CreatedAt time.Time `db:"created_at" json:"createdAt"` +// ExpiresAt time.Time `db:"expires_at" json:"expiresAt"` +// } + +// func (s *Session) ToJson() map[string]interface{} { +// return map[string]interface{}{ +// "id": s.ID, +// "userId": s.UserID, +// "sessionData": s.SessionData, +// "ipAddress": s.IPAddress, +// "userAgent": s.UserAgent, +// "deviceType": s.DeviceType, +// "browser": s.Browser, +// "os": s.OS, +// "location": s.Location, +// "isActive": s.IsActive, +// "lastActivityAt": s.LastActivityAt, +// "revokedAt": s.RevokedAt, +// "revokedReason": s.RevokedReason, +// "createdAt": s.CreatedAt, +// "expiresAt": s.ExpiresAt, +// } +// } + +// func (s *Session) InsertInDB() error { +// query := ` +// INSERT INTO sessions ( +// id, user_id, session_data, ip_address, user_agent, +// device_type, browser, os, location, expires_at +// ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +// RETURNING created_at, last_activity_at +// ` +// err := db.QueryRow(query, s.ID, s.UserID, s.SessionData, s.IPAddress, s.UserAgent, +// s.DeviceType, s.Browser, s.OS, s.Location, s.ExpiresAt).Scan(&s.CreatedAt, &s.LastActivityAt) +// return err +// } + +// func GetSessionByID(sessionID string) (*Session, error) { +// var session Session +// query := ` +// SELECT id, user_id, session_data, ip_address, user_agent, +// device_type, browser, os, location, is_active, +// last_activity_at, revoked_at, revoked_reason, +// created_at, expires_at +// FROM sessions +// WHERE id = ? AND is_active = 1 +// ` +// err := db.QueryRow(query, sessionID).Scan( +// &session.ID, &session.UserID, &session.SessionData, &session.IPAddress, +// &session.UserAgent, &session.DeviceType, &session.Browser, &session.OS, +// &session.Location, &session.IsActive, &session.LastActivityAt, +// &session.RevokedAt, &session.RevokedReason, &session.CreatedAt, &session.ExpiresAt, +// ) +// if err != nil { +// return nil, err +// } +// return &session, nil +// } + +// func GetSessionsByUserID(userID int64) ([]Session, error) { +// var sessions []Session +// query := ` +// SELECT id, user_id, session_data, ip_address, user_agent, +// device_type, browser, os, location, is_active, +// last_activity_at, revoked_at, revoked_reason, +// created_at, expires_at +// FROM sessions +// WHERE user_id = ? AND is_active = 1 +// ORDER BY last_activity_at DESC +// ` +// rows, err := db.Query(query, userID) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// for rows.Next() { +// var session Session +// err := rows.Scan( +// &session.ID, &session.UserID, &session.SessionData, &session.IPAddress, +// &session.UserAgent, &session.DeviceType, &session.Browser, &session.OS, +// &session.Location, &session.IsActive, &session.LastActivityAt, +// &session.RevokedAt, &session.RevokedReason, &session.CreatedAt, &session.ExpiresAt, +// ) +// if err != nil { +// return nil, err +// } +// sessions = append(sessions, session) +// } + +// return sessions, rows.Err() +// } + +// func (s *Session) UpdateActivity() error { +// query := ` +// UPDATE sessions +// SET last_activity_at = CURRENT_TIMESTAMP +// WHERE id = ? +// ` +// _, err := db.Exec(query, s.ID) +// return err +// } + +// func (s *Session) Revoke(reason string) error { +// query := ` +// UPDATE sessions +// SET is_active = 0, +// revoked_at = CURRENT_TIMESTAMP, +// revoked_reason = ? +// WHERE id = ? +// ` +// _, err := db.Exec(query, reason, s.ID) +// return err +// } + +// func RevokeAllUserSessions(userID int64, reason string) error { +// query := ` +// UPDATE sessions +// SET is_active = 0, +// revoked_at = CURRENT_TIMESTAMP, +// revoked_reason = ? +// WHERE user_id = ? AND is_active = 1 +// ` +// _, err := db.Exec(query, reason, userID) +// return err +// } + +// func DeleteExpiredSessions() error { +// query := ` +// DELETE FROM sessions +// WHERE expires_at < CURRENT_TIMESTAMP +// ` +// _, err := db.Exec(query) +// return err +// } diff --git a/server/models/systemSettings.go b/server/models/systemSettings.go index 1e61c0e..262a9bf 100644 --- a/server/models/systemSettings.go +++ b/server/models/systemSettings.go @@ -2,11 +2,13 @@ package models import ( "crypto/rand" - "database/sql" "encoding/base64" "fmt" + "time" "github.com/rs/zerolog/log" + "gorm.io/gorm" + "gorm.io/gorm/clause" ) type SystemSettings struct { @@ -21,6 +23,16 @@ type SystemSettings struct { AutoCleanupImages bool `json:"autoCleanupImages"` } +type systemSettingEntry struct { + Key string `gorm:"primaryKey" json:"key"` + Value string `json:"value"` + UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` +} + +func (systemSettingEntry) TableName() string { + return "system_settings" +} + func generateRandomSecret(length int) (string, error) { bytes := make([]byte, length) if _, err := rand.Read(bytes); err != nil { @@ -30,41 +42,43 @@ func generateRandomSecret(length int) (string, error) { } func GetSystemSetting(key string) (string, error) { - var value string - err := db.QueryRow(`SELECT value FROM system_settings WHERE key = ?`, key).Scan(&value) - if err == sql.ErrNoRows { - return "", nil - } + var entry systemSettingEntry + err := db.Where("key = ?", key).First(&entry).Error + if err != nil { + if err == gorm.ErrRecordNotFound { + return "", nil + } return "", err } - return value, nil + return entry.Value, nil } func SetSystemSetting(key, value string) error { - _, err := db.Exec(` - INSERT INTO system_settings (key, value, updated_at) - VALUES (?, ?, CURRENT_TIMESTAMP) - ON CONFLICT(key) DO UPDATE SET value = ?, updated_at = CURRENT_TIMESTAMP - `, key, value, value) - return err + entry := systemSettingEntry{ + Key: key, + Value: value, + } + + return db.Clauses(clause.OnConflict{ + Columns: []clause.Column{{Name: "key"}}, + DoUpdates: clause.AssignmentColumns([]string{"value", "updated_at"}), + }).Create(&entry).Error } func GetSystemSettings() (*SystemSettings, error) { var settings SystemSettings - var wildcardDomain sql.NullString - err := db.QueryRow(`SELECT value FROM system_settings WHERE key = ?`, "wildcard_domain").Scan(&wildcardDomain) - if err != nil && err != sql.ErrNoRows { + wildcardVal, err := GetSystemSetting("wildcard_domain") + if err != nil { return nil, err } - if wildcardDomain.Valid && wildcardDomain.String != "" { - settings.WildcardDomain = &wildcardDomain.String + if wildcardVal != "" { + settings.WildcardDomain = &wildcardVal } - var mistAppName string - err = db.QueryRow(`SELECT value FROM system_settings WHERE key = ?`, "mist_app_name").Scan(&mistAppName) - if err != nil && err != sql.ErrNoRows { + mistAppName, err := GetSystemSetting("mist_app_name") + if err != nil { return nil, err } if mistAppName == "" { @@ -98,8 +112,6 @@ func GetSystemSettings() (*SystemSettings, error) { if err != nil { return nil, err } - // Default to empty string - same-origin requests are always allowed - // Users only need to configure this for cross-origin requests settings.AllowedOrigins = allowedOrigins prodMode, err := GetSystemSetting("production_mode") @@ -138,21 +150,12 @@ func UpdateSystemSettings(wildcardDomain *string, mistAppName string) (*SystemSe if wildcardDomain != nil { wildcardValue = *wildcardDomain } - _, err := db.Exec(` - INSERT INTO system_settings (key, value, updated_at) - VALUES (?, ?, CURRENT_TIMESTAMP) - ON CONFLICT(key) DO UPDATE SET value = ?, updated_at = CURRENT_TIMESTAMP - `, "wildcard_domain", wildcardValue, wildcardValue) - if err != nil { + + if err := SetSystemSetting("wildcard_domain", wildcardValue); err != nil { return nil, err } - _, err = db.Exec(` - INSERT INTO system_settings (key, value, updated_at) - VALUES (?, ?, CURRENT_TIMESTAMP) - ON CONFLICT(key) DO UPDATE SET value = ?, updated_at = CURRENT_TIMESTAMP - `, "mist_app_name", mistAppName, mistAppName) - if err != nil { + if err := SetSystemSetting("mist_app_name", mistAppName); err != nil { return nil, err } @@ -203,7 +206,6 @@ func UpdateDockerSettings(autoCleanupContainers, autoCleanupImages bool) error { return nil } -// UpdateSystemSettings updates all settings from the SystemSettings struct func (s *SystemSettings) UpdateSystemSettings() error { wildcardValue := "" if s.WildcardDomain != nil { @@ -272,3 +274,281 @@ func GenerateAutoDomain(projectName, appName string) (string, error) { return projectName + "-" + appName + "." + wildcardDomain, nil } + +//############################################################################################################ +//ARCHIVED CODE BELOW + +// package models + +// import ( +// "crypto/rand" +// "database/sql" +// "encoding/base64" +// "fmt" + +// "github.com/rs/zerolog/log" +// ) + +// type SystemSettings struct { +// WildcardDomain *string `json:"wildcardDomain"` +// MistAppName string `json:"mistAppName"` +// JwtSecret string `json:"-"` +// GithubWebhookSecret string `json:"-"` +// AllowedOrigins string `json:"allowedOrigins"` +// ProductionMode bool `json:"productionMode"` +// SecureCookies bool `json:"secureCookies"` +// AutoCleanupContainers bool `json:"autoCleanupContainers"` +// AutoCleanupImages bool `json:"autoCleanupImages"` +// } + +// func generateRandomSecret(length int) (string, error) { +// bytes := make([]byte, length) +// if _, err := rand.Read(bytes); err != nil { +// return "", err +// } +// return base64.URLEncoding.EncodeToString(bytes), nil +// } + +// func GetSystemSetting(key string) (string, error) { +// var value string +// err := db.QueryRow(`SELECT value FROM system_settings WHERE key = ?`, key).Scan(&value) +// if err == sql.ErrNoRows { +// return "", nil +// } +// if err != nil { +// return "", err +// } +// return value, nil +// } + +// func SetSystemSetting(key, value string) error { +// _, err := db.Exec(` +// INSERT INTO system_settings (key, value, updated_at) +// VALUES (?, ?, CURRENT_TIMESTAMP) +// ON CONFLICT(key) DO UPDATE SET value = ?, updated_at = CURRENT_TIMESTAMP +// `, key, value, value) +// return err +// } + +// func GetSystemSettings() (*SystemSettings, error) { +// var settings SystemSettings + +// var wildcardDomain sql.NullString +// err := db.QueryRow(`SELECT value FROM system_settings WHERE key = ?`, "wildcard_domain").Scan(&wildcardDomain) +// if err != nil && err != sql.ErrNoRows { +// return nil, err +// } +// if wildcardDomain.Valid && wildcardDomain.String != "" { +// settings.WildcardDomain = &wildcardDomain.String +// } + +// var mistAppName string +// err = db.QueryRow(`SELECT value FROM system_settings WHERE key = ?`, "mist_app_name").Scan(&mistAppName) +// if err != nil && err != sql.ErrNoRows { +// return nil, err +// } +// if mistAppName == "" { +// mistAppName = "mist" +// } +// settings.MistAppName = mistAppName + +// jwtSecret, err := GetSystemSetting("jwt_secret") +// if err != nil { +// return nil, err +// } +// if jwtSecret == "" { +// jwtSecret, err = generateRandomSecret(64) +// if err != nil { +// return nil, fmt.Errorf("failed to generate JWT secret: %w", err) +// } +// if err := SetSystemSetting("jwt_secret", jwtSecret); err != nil { +// return nil, fmt.Errorf("failed to save JWT secret: %w", err) +// } +// log.Info().Msg("Auto-generated JWT secret and saved to database") +// } +// settings.JwtSecret = jwtSecret + +// githubSecret, err := GetSystemSetting("github_webhook_secret") +// if err != nil { +// return nil, err +// } +// settings.GithubWebhookSecret = githubSecret + +// allowedOrigins, err := GetSystemSetting("allowed_origins") +// if err != nil { +// return nil, err +// } +// // Default to empty string - same-origin requests are always allowed +// // Users only need to configure this for cross-origin requests +// settings.AllowedOrigins = allowedOrigins + +// prodMode, err := GetSystemSetting("production_mode") +// if err != nil { +// return nil, err +// } +// settings.ProductionMode = prodMode == "true" + +// secureCookies, err := GetSystemSetting("secure_cookies") +// if err != nil { +// return nil, err +// } +// if secureCookies == "" { +// settings.SecureCookies = settings.ProductionMode +// } else { +// settings.SecureCookies = secureCookies == "true" +// } + +// autoCleanupContainers, err := GetSystemSetting("auto_cleanup_containers") +// if err != nil { +// return nil, err +// } +// settings.AutoCleanupContainers = autoCleanupContainers == "true" + +// autoCleanupImages, err := GetSystemSetting("auto_cleanup_images") +// if err != nil { +// return nil, err +// } +// settings.AutoCleanupImages = autoCleanupImages == "true" + +// return &settings, nil +// } + +// func UpdateSystemSettings(wildcardDomain *string, mistAppName string) (*SystemSettings, error) { +// wildcardValue := "" +// if wildcardDomain != nil { +// wildcardValue = *wildcardDomain +// } +// _, err := db.Exec(` +// INSERT INTO system_settings (key, value, updated_at) +// VALUES (?, ?, CURRENT_TIMESTAMP) +// ON CONFLICT(key) DO UPDATE SET value = ?, updated_at = CURRENT_TIMESTAMP +// `, "wildcard_domain", wildcardValue, wildcardValue) +// if err != nil { +// return nil, err +// } + +// _, err = db.Exec(` +// INSERT INTO system_settings (key, value, updated_at) +// VALUES (?, ?, CURRENT_TIMESTAMP) +// ON CONFLICT(key) DO UPDATE SET value = ?, updated_at = CURRENT_TIMESTAMP +// `, "mist_app_name", mistAppName, mistAppName) +// if err != nil { +// return nil, err +// } + +// return GetSystemSettings() +// } + +// func UpdateSecuritySettings(allowedOrigins string, productionMode, secureCookies bool) error { +// if err := SetSystemSetting("allowed_origins", allowedOrigins); err != nil { +// return err +// } + +// prodModeStr := "false" +// if productionMode { +// prodModeStr = "true" +// } +// if err := SetSystemSetting("production_mode", prodModeStr); err != nil { +// return err +// } + +// secureCookiesStr := "false" +// if secureCookies { +// secureCookiesStr = "true" +// } +// if err := SetSystemSetting("secure_cookies", secureCookiesStr); err != nil { +// return err +// } + +// return nil +// } + +// func UpdateDockerSettings(autoCleanupContainers, autoCleanupImages bool) error { +// cleanupContainersStr := "false" +// if autoCleanupContainers { +// cleanupContainersStr = "true" +// } +// if err := SetSystemSetting("auto_cleanup_containers", cleanupContainersStr); err != nil { +// return err +// } + +// cleanupImagesStr := "false" +// if autoCleanupImages { +// cleanupImagesStr = "true" +// } +// if err := SetSystemSetting("auto_cleanup_images", cleanupImagesStr); err != nil { +// return err +// } + +// return nil +// } + +// // UpdateSystemSettings updates all settings from the SystemSettings struct +// func (s *SystemSettings) UpdateSystemSettings() error { +// wildcardValue := "" +// if s.WildcardDomain != nil { +// wildcardValue = *s.WildcardDomain +// } +// if err := SetSystemSetting("wildcard_domain", wildcardValue); err != nil { +// return err +// } + +// if err := SetSystemSetting("mist_app_name", s.MistAppName); err != nil { +// return err +// } + +// prodModeStr := "false" +// if s.ProductionMode { +// prodModeStr = "true" +// } +// if err := SetSystemSetting("production_mode", prodModeStr); err != nil { +// return err +// } + +// secureCookiesStr := "false" +// if s.SecureCookies { +// secureCookiesStr = "true" +// } +// if err := SetSystemSetting("secure_cookies", secureCookiesStr); err != nil { +// return err +// } + +// cleanupContainersStr := "false" +// if s.AutoCleanupContainers { +// cleanupContainersStr = "true" +// } +// if err := SetSystemSetting("auto_cleanup_containers", cleanupContainersStr); err != nil { +// return err +// } + +// cleanupImagesStr := "false" +// if s.AutoCleanupImages { +// cleanupImagesStr = "true" +// } +// if err := SetSystemSetting("auto_cleanup_images", cleanupImagesStr); err != nil { +// return err +// } + +// return nil +// } + +// func GenerateAutoDomain(projectName, appName string) (string, error) { +// settings, err := GetSystemSettings() +// if err != nil { +// return "", err +// } + +// if settings.WildcardDomain == nil || *settings.WildcardDomain == "" { +// return "", nil +// } + +// wildcardDomain := *settings.WildcardDomain +// if len(wildcardDomain) > 0 && wildcardDomain[0] == '*' { +// wildcardDomain = wildcardDomain[1:] +// } +// if len(wildcardDomain) > 0 && wildcardDomain[0] == '.' { +// wildcardDomain = wildcardDomain[1:] +// } + +// return projectName + "-" + appName + "." + wildcardDomain, nil +// } diff --git a/server/models/systemSettingsDbVer.go b/server/models/systemSettingsDbVer.go new file mode 100644 index 0000000..b285fdc --- /dev/null +++ b/server/models/systemSettingsDbVer.go @@ -0,0 +1,7 @@ +package models + +type SystemSettingsDbVer struct { + key string `gorm:"primaryKey"` + value string `gorm:"not null"` + updatedAt int64 `gorm:"autoUpdateTime"` +} diff --git a/server/models/updateLog.go b/server/models/updateLog.go index 9f5947d..1d9da56 100644 --- a/server/models/updateLog.go +++ b/server/models/updateLog.go @@ -1,11 +1,11 @@ package models import ( - "database/sql" "strings" "time" "github.com/rs/zerolog/log" + "gorm.io/gorm" ) type UpdateStatus string @@ -17,39 +17,29 @@ const ( ) type UpdateLog struct { - ID int64 - VersionFrom string - VersionTo string - Status UpdateStatus - Logs *string - ErrorMessage *string - StartedBy int64 - StartedAt time.Time - CompletedAt *time.Time - Username *string + ID int64 `gorm:"primaryKey;autoIncrement:true" json:"id"` + VersionFrom string `gorm:"not null" json:"version_from"` + VersionTo string `gorm:"not null" json:"version_to"` + Status UpdateStatus `gorm:"index;not null" json:"status"` + Logs *string `json:"logs"` + ErrorMessage *string `json:"error_message"` + StartedBy int64 `gorm:"not null;constraint:OnDelete:CASCADE" json:"started_by"` + StartedAt time.Time `gorm:"autoCreateTime;index:,sort:desc" json:"started_at"` + CompletedAt *time.Time `json:"completed_at"` + Username *string `gorm:"-" json:"username"` } func CreateUpdateLog(versionFrom, versionTo string, startedBy int64) (*UpdateLog, error) { - query := ` - INSERT INTO update_logs (version_from, version_to, status, logs, started_by, started_at) - VALUES (?, ?, 'in_progress', '', ?, CURRENT_TIMESTAMP) - RETURNING id, version_from, version_to, status, logs, error_message, started_by, started_at, completed_at - ` - - updateLog := &UpdateLog{} - err := db.QueryRow(query, versionFrom, versionTo, startedBy).Scan( - &updateLog.ID, - &updateLog.VersionFrom, - &updateLog.VersionTo, - &updateLog.Status, - &updateLog.Logs, - &updateLog.ErrorMessage, - &updateLog.StartedBy, - &updateLog.StartedAt, - &updateLog.CompletedAt, - ) + emptyLogs := "" + updateLog := &UpdateLog{ + VersionFrom: versionFrom, + VersionTo: versionTo, + Status: UpdateStatusInProgress, + Logs: &emptyLogs, + StartedBy: startedBy, + } - if err != nil { + if err := db.Create(updateLog).Error; err != nil { log.Error().Err(err).Msg("Failed to create update log") return nil, err } @@ -65,13 +55,13 @@ func CreateUpdateLog(versionFrom, versionTo string, startedBy int64) (*UpdateLog } func UpdateUpdateLogStatus(id int64, status UpdateStatus, logs string, errorMessage *string) error { - query := ` - UPDATE update_logs - SET status = ?, logs = ?, error_message = ?, completed_at = CURRENT_TIMESTAMP - WHERE id = ? - ` + err := db.Model(&UpdateLog{ID: id}).Updates(map[string]interface{}{ + "status": status, + "logs": logs, + "error_message": errorMessage, + "completed_at": time.Now(), + }).Error - _, err := db.Exec(query, status, logs, errorMessage, id) if err != nil { log.Error().Err(err).Int64("update_log_id", id).Msg("Failed to update log status") return err @@ -86,13 +76,9 @@ func UpdateUpdateLogStatus(id int64, status UpdateStatus, logs string, errorMess } func AppendUpdateLog(id int64, logLine string) error { - query := ` - UPDATE update_logs - SET logs = logs || ? - WHERE id = ? - ` + err := db.Model(&UpdateLog{ID: id}). + Update("logs", gorm.Expr("logs || ?", logLine+"\n")).Error - _, err := db.Exec(query, logLine+"\n", id) if err != nil { log.Error().Err(err).Int64("update_log_id", id).Msg("Failed to append log line") return err @@ -102,84 +88,42 @@ func AppendUpdateLog(id int64, logLine string) error { } func GetUpdateLogs(limit int) ([]UpdateLog, error) { - query := ` - SELECT - ul.id, ul.version_from, ul.version_to, ul.status, - ul.logs, ul.error_message, ul.started_by, ul.started_at, - ul.completed_at, u.username - FROM update_logs ul - LEFT JOIN users u ON ul.started_by = u.id - ORDER BY ul.started_at DESC - LIMIT ? - ` - - rows, err := db.Query(query, limit) + var logs []UpdateLog + + err := db.Table("update_logs"). + Select("update_logs.*, users.username"). + Joins("LEFT JOIN users ON update_logs.started_by = users.id"). + Order("update_logs.started_at DESC"). + Limit(limit). + Scan(&logs).Error + if err != nil { log.Error().Err(err).Msg("Failed to query update logs") return nil, err } - defer rows.Close() - - var logs []UpdateLog - for rows.Next() { - var updateLog UpdateLog - err := rows.Scan( - &updateLog.ID, - &updateLog.VersionFrom, - &updateLog.VersionTo, - &updateLog.Status, - &updateLog.Logs, - &updateLog.ErrorMessage, - &updateLog.StartedBy, - &updateLog.StartedAt, - &updateLog.CompletedAt, - &updateLog.Username, - ) - if err != nil { - log.Error().Err(err).Msg("Failed to scan update log row") - return nil, err - } - logs = append(logs, updateLog) - } return logs, nil } func GetUpdateLogByID(id int64) (*UpdateLog, error) { - query := ` - SELECT - ul.id, ul.version_from, ul.version_to, ul.status, - ul.logs, ul.error_message, ul.started_by, ul.started_at, - ul.completed_at, u.username - FROM update_logs ul - LEFT JOIN users u ON ul.started_by = u.id - WHERE ul.id = ? - ` - - updateLog := &UpdateLog{} - err := db.QueryRow(query, id).Scan( - &updateLog.ID, - &updateLog.VersionFrom, - &updateLog.VersionTo, - &updateLog.Status, - &updateLog.Logs, - &updateLog.ErrorMessage, - &updateLog.StartedBy, - &updateLog.StartedAt, - &updateLog.CompletedAt, - &updateLog.Username, - ) - - if err == sql.ErrNoRows { - return nil, nil - } + var updateLog UpdateLog + + err := db.Table("update_logs"). + Select("update_logs.*, users.username"). + Joins("LEFT JOIN users ON update_logs.started_by = users.id"). + Where("update_logs.id = ?", id). + Scan(&updateLog).Error if err != nil { log.Error().Err(err).Int64("update_log_id", id).Msg("Failed to get update log by ID") return nil, err } - return updateLog, nil + if updateLog.ID == 0 { + return nil, nil + } + + return &updateLog, nil } func GetUpdateLogsAsString() (string, error) { @@ -317,3 +261,326 @@ func CheckAndCompletePendingUpdates() error { return nil } + +//############################################################################################################################ +//ARCHIVED CODE BELOW + +// package models + +// import ( +// "database/sql" +// "strings" +// "time" + +// "github.com/rs/zerolog/log" +// ) + +// type UpdateStatus string + +// const ( +// UpdateStatusInProgress UpdateStatus = "in_progress" +// UpdateStatusSuccess UpdateStatus = "success" +// UpdateStatusFailed UpdateStatus = "failed" +// ) + +// type UpdateLog struct { +// ID int64 +// VersionFrom string +// VersionTo string +// Status UpdateStatus +// Logs *string +// ErrorMessage *string +// StartedBy int64 +// StartedAt time.Time +// CompletedAt *time.Time +// Username *string +// } + +// func CreateUpdateLog(versionFrom, versionTo string, startedBy int64) (*UpdateLog, error) { +// query := ` +// INSERT INTO update_logs (version_from, version_to, status, logs, started_by, started_at) +// VALUES (?, ?, 'in_progress', '', ?, CURRENT_TIMESTAMP) +// RETURNING id, version_from, version_to, status, logs, error_message, started_by, started_at, completed_at +// ` + +// updateLog := &UpdateLog{} +// err := db.QueryRow(query, versionFrom, versionTo, startedBy).Scan( +// &updateLog.ID, +// &updateLog.VersionFrom, +// &updateLog.VersionTo, +// &updateLog.Status, +// &updateLog.Logs, +// &updateLog.ErrorMessage, +// &updateLog.StartedBy, +// &updateLog.StartedAt, +// &updateLog.CompletedAt, +// ) + +// if err != nil { +// log.Error().Err(err).Msg("Failed to create update log") +// return nil, err +// } + +// log.Info(). +// Int64("update_log_id", updateLog.ID). +// Str("from", versionFrom). +// Str("to", versionTo). +// Int64("started_by", startedBy). +// Msg("Update log created") + +// return updateLog, nil +// } + +// func UpdateUpdateLogStatus(id int64, status UpdateStatus, logs string, errorMessage *string) error { +// query := ` +// UPDATE update_logs +// SET status = ?, logs = ?, error_message = ?, completed_at = CURRENT_TIMESTAMP +// WHERE id = ? +// ` + +// _, err := db.Exec(query, status, logs, errorMessage, id) +// if err != nil { +// log.Error().Err(err).Int64("update_log_id", id).Msg("Failed to update log status") +// return err +// } + +// log.Info(). +// Int64("update_log_id", id). +// Str("status", string(status)). +// Msg("Update log status updated") + +// return nil +// } + +// func AppendUpdateLog(id int64, logLine string) error { +// query := ` +// UPDATE update_logs +// SET logs = logs || ? +// WHERE id = ? +// ` + +// _, err := db.Exec(query, logLine+"\n", id) +// if err != nil { +// log.Error().Err(err).Int64("update_log_id", id).Msg("Failed to append log line") +// return err +// } + +// return nil +// } + +// func GetUpdateLogs(limit int) ([]UpdateLog, error) { +// query := ` +// SELECT +// ul.id, ul.version_from, ul.version_to, ul.status, +// ul.logs, ul.error_message, ul.started_by, ul.started_at, +// ul.completed_at, u.username +// FROM update_logs ul +// LEFT JOIN users u ON ul.started_by = u.id +// ORDER BY ul.started_at DESC +// LIMIT ? +// ` + +// rows, err := db.Query(query, limit) +// if err != nil { +// log.Error().Err(err).Msg("Failed to query update logs") +// return nil, err +// } +// defer rows.Close() + +// var logs []UpdateLog +// for rows.Next() { +// var updateLog UpdateLog +// err := rows.Scan( +// &updateLog.ID, +// &updateLog.VersionFrom, +// &updateLog.VersionTo, +// &updateLog.Status, +// &updateLog.Logs, +// &updateLog.ErrorMessage, +// &updateLog.StartedBy, +// &updateLog.StartedAt, +// &updateLog.CompletedAt, +// &updateLog.Username, +// ) +// if err != nil { +// log.Error().Err(err).Msg("Failed to scan update log row") +// return nil, err +// } +// logs = append(logs, updateLog) +// } + +// return logs, nil +// } + +// func GetUpdateLogByID(id int64) (*UpdateLog, error) { +// query := ` +// SELECT +// ul.id, ul.version_from, ul.version_to, ul.status, +// ul.logs, ul.error_message, ul.started_by, ul.started_at, +// ul.completed_at, u.username +// FROM update_logs ul +// LEFT JOIN users u ON ul.started_by = u.id +// WHERE ul.id = ? +// ` + +// updateLog := &UpdateLog{} +// err := db.QueryRow(query, id).Scan( +// &updateLog.ID, +// &updateLog.VersionFrom, +// &updateLog.VersionTo, +// &updateLog.Status, +// &updateLog.Logs, +// &updateLog.ErrorMessage, +// &updateLog.StartedBy, +// &updateLog.StartedAt, +// &updateLog.CompletedAt, +// &updateLog.Username, +// ) + +// if err == sql.ErrNoRows { +// return nil, nil +// } + +// if err != nil { +// log.Error().Err(err).Int64("update_log_id", id).Msg("Failed to get update log by ID") +// return nil, err +// } + +// return updateLog, nil +// } + +// func GetUpdateLogsAsString() (string, error) { +// logs, err := GetUpdateLogs(10) +// if err != nil { +// return "", err +// } + +// if len(logs) == 0 { +// return "No update history available", nil +// } + +// var builder strings.Builder +// builder.WriteString("Recent Update History:\n") +// builder.WriteString("======================\n\n") + +// for _, log := range logs { +// builder.WriteString("Version: ") +// builder.WriteString(log.VersionFrom) +// builder.WriteString(" → ") +// builder.WriteString(log.VersionTo) +// builder.WriteString("\n") +// builder.WriteString("Status: ") +// builder.WriteString(string(log.Status)) +// builder.WriteString("\n") +// builder.WriteString("Started: ") +// builder.WriteString(log.StartedAt.Format("2006-01-02 15:04:05")) +// builder.WriteString(" by ") +// if log.Username != nil { +// builder.WriteString(*log.Username) +// } else { +// builder.WriteString("unknown") +// } + +// builder.WriteString("\n") +// if log.CompletedAt != nil { +// builder.WriteString("Completed: ") +// builder.WriteString(log.CompletedAt.Format("2006-01-02 15:04:05")) +// builder.WriteString("\n") +// } +// if log.ErrorMessage != nil && *log.ErrorMessage != "" { +// builder.WriteString("Error: ") +// builder.WriteString(*log.ErrorMessage) +// builder.WriteString("\n") +// } +// builder.WriteString("\n") +// } + +// return builder.String(), nil +// } + +// func CheckAndCompletePendingUpdates() error { +// logs, err := GetUpdateLogs(1) +// if err != nil { +// return err +// } + +// if len(logs) == 0 { +// return nil +// } + +// latestLog := logs[0] + +// if latestLog.Status != UpdateStatusInProgress { +// return nil +// } + +// log.Info(). +// Int64("update_log_id", latestLog.ID). +// Str("from_version", latestLog.VersionFrom). +// Str("to_version", latestLog.VersionTo). +// Str("age", time.Since(latestLog.StartedAt).String()). +// Msg("Found in-progress update on startup, checking status") + +// currentVersion, err := GetSystemSetting("version") +// if err != nil { +// log.Error().Err(err).Msg("Failed to get current version for update completion check") +// return err +// } + +// if currentVersion == "" { +// currentVersion = "1.0.0" +// } + +// if currentVersion == latestLog.VersionTo { +// log.Info(). +// Int64("update_log_id", latestLog.ID). +// Str("version", currentVersion). +// Msg("Completing successful update that was interrupted by service restart") + +// existing := "" +// if latestLog.Logs != nil { +// existing = *latestLog.Logs +// } + +// completionLog := existing + "\n✅ Update completed successfully (verified on restart)\n" + +// err = UpdateUpdateLogStatus(latestLog.ID, UpdateStatusSuccess, completionLog, nil) +// if err != nil { +// log.Error().Err(err).Int64("update_log_id", latestLog.ID).Msg("Failed to complete pending update") +// return err +// } + +// log.Info(). +// Int64("update_log_id", latestLog.ID). +// Str("from", latestLog.VersionFrom). +// Str("to", latestLog.VersionTo). +// Msg("Successfully completed pending update") +// return nil +// } + +// log.Warn(). +// Int64("update_log_id", latestLog.ID). +// Str("expected_version", latestLog.VersionTo). +// Str("current_version", currentVersion). +// Str("age", time.Since(latestLog.StartedAt).String()). +// Msg("Update appears to have failed (version mismatch detected on startup)") + +// errMsg := "Update process was interrupted and version does not match target" +// existing := "" +// if latestLog.Logs != nil { +// existing = *latestLog.Logs +// } + +// failureLog := existing + "\n❌ " + errMsg + "\n" +// err = UpdateUpdateLogStatus(latestLog.ID, UpdateStatusFailed, failureLog, &errMsg) +// if err != nil { +// log.Error().Err(err).Int64("update_log_id", latestLog.ID).Msg("Failed to mark failed update") +// return err +// } + +// log.Info(). +// Int64("update_log_id", latestLog.ID). +// Msg("Marked failed update as failed") + +// return nil +// } diff --git a/server/models/user.go b/server/models/user.go index 2eefe21..3f13a17 100644 --- a/server/models/user.go +++ b/server/models/user.go @@ -5,30 +5,53 @@ import ( "github.com/corecollectives/mist/utils" "golang.org/x/crypto/bcrypt" + "gorm.io/gorm" ) type User struct { - ID int64 `json:"id"` - Username string `json:"username"` - Email string `json:"email"` - PasswordHash string `json:"-"` - Role string `json:"role"` - AvatarURL *string `json:"avatarUrl"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID int64 `gorm:"primaryKey;autoIncrement:false" json:"id"` + Username string `gorm:"uniqueIndex;not null" json:"username"` + Email string `gorm:"uniqueIndex;not null" json:"email"` + PasswordHash string `gorm:"not null" json:"-"` + Role string `gorm:"default:'user';index" json:"role"` + + FullName *string `json:"fullName,omitempty"` + AvatarURL *string `json:"avatarUrl,omitempty"` + Bio *string `json:"bio,omitempty"` + + EmailVerified bool `gorm:"default:false" json:"emailVerified"` + EmailVerificationToken *string `json:"-"` + EmailVerificationSentAt *time.Time `json:"-"` + + PasswordResetToken *string `json:"-"` + PasswordResetExpiresAt *time.Time `json:"-"` + PasswordChangedAt *time.Time `json:"-"` + + TwoFactorEnabled bool `gorm:"default:false" json:"twoFactorEnabled"` + TwoFactorSecret *string `json:"-"` + TwoFactorBackupCodes *string `json:"-"` + + LastLoginAt *time.Time `json:"lastLoginAt,omitempty"` + LastLoginIP *string `json:"lastLoginIp,omitempty"` + FailedLoginAttempts int `gorm:"default:0" json:"failedLoginAttempts"` + AccountLockedUntil *time.Time `json:"accountLockedUntil,omitempty"` + + Timezone string `gorm:"default:'UTC'" json:"timezone"` + Language string `gorm:"default:'en'" json:"language"` + NotificationPreferences *string `json:"notificationPreferences,omitempty"` + + IsActive bool `gorm:"default:true;index" json:"isActive"` + CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` + UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updatedAt"` + DeletedAt gorm.DeletedAt `gorm:"index" json:"deletedAt,omitempty"` } func (u *User) Create() error { - query := ` - INSERT INTO users (id, username, email, password_hash, role, avatar_url) - VALUES ($1, $2, $3, $4, $5, $6) - RETURNING id, username, email, role, avatar_url, created_at, updated_at - ` u.ID = utils.GenerateRandomId() - err := db.QueryRow(query, u.ID, u.Username, u.Email, u.PasswordHash, u.Role, u.AvatarURL).Scan( - &u.ID, &u.Username, &u.Email, &u.Role, &u.AvatarURL, &u.CreatedAt, &u.UpdatedAt, - ) - return err + if u.Role == "" { + u.Role = "user" + } + return db.Create(u).Error } func (u *User) SetPassword(password string) error { @@ -41,45 +64,35 @@ func (u *User) SetPassword(password string) error { } func GetUserByID(userID int64) (*User, error) { - query := ` - SELECT id, username, email, role, avatar_url, created_at, updated_at - FROM users - WHERE id = $1 - ` - user := &User{} - err := db.QueryRow(query, userID).Scan( - &user.ID, &user.Username, &user.Email, &user.Role, &user.AvatarURL, &user.CreatedAt, &user.UpdatedAt, - ) + var user User + err := db.First(&user, userID).Error if err != nil { return nil, err } - return user, nil + return &user, nil } func DeleteUserByID(userID int64) error { - query := `DELETE FROM users WHERE id = $1` - _, err := db.Exec(query, userID) - return err + return db.Delete(&User{}, userID).Error } func UpdateUser(u *User) error { - query := ` - UPDATE users - SET username = $1, email = $2, role = $3, avatar_url = $4, updated_at = CURRENT_TIMESTAMP - WHERE id = $5 - RETURNING updated_at - ` - return db.QueryRow(query, u.Username, u.Email, u.Role, u.AvatarURL, u.ID).Scan(&u.UpdatedAt) + return db.Model(u).Updates(map[string]interface{}{ + "username": u.Username, + "email": u.Email, + "role": u.Role, + "avatar_url": u.AvatarURL, + "updated_at": time.Now(), + }).Error } func (u *User) MatchPassword(password string) bool { - query := ` - SELECT password_hash - FROM users - WHERE id = $1 - ` var storedHash string - err := db.QueryRow(query, u.ID).Scan(&storedHash) + err := db.Model(&User{}). + Select("password_hash"). + Where("id = ?", u.ID). + Scan(&storedHash).Error + if err != nil { return false } @@ -88,101 +101,250 @@ func (u *User) MatchPassword(password string) bool { } func (u *User) UpdatePassword() error { - query := ` - UPDATE users - SET password_hash = $1, updated_at = CURRENT_TIMESTAMP - WHERE id = $2 - RETURNING updated_at - ` - return db.QueryRow(query, u.PasswordHash, u.ID).Scan(&u.UpdatedAt) - + return db.Model(u).Updates(map[string]interface{}{ + "password_hash": u.PasswordHash, + "updated_at": time.Now(), + }).Error } func GetUserByEmail(email string) (*User, error) { - query := ` - SELECT id, username, email, role, avatar_url, created_at, updated_at - FROM users - WHERE email = $1 - ` - user := &User{} - err := db.QueryRow(query, email).Scan( - &user.ID, &user.Username, &user.Email, &user.Role, &user.AvatarURL, &user.CreatedAt, &user.UpdatedAt, - ) + var user User + err := db.Where("email = ?", email).First(&user).Error if err != nil { return nil, err } - return user, nil + return &user, nil } func GetUserByUsername(username string) (*User, error) { - query := ` - SELECT id, username, email, role, avatar_url, created_at, updated_at - FROM users - WHERE username = $1 - ` - user := &User{} - err := db.QueryRow(query, username).Scan( - &user.ID, &user.Username, &user.Email, &user.Role, &user.AvatarURL, &user.CreatedAt, &user.UpdatedAt, - ) + var user User + err := db.Where("username = ?", username).First(&user).Error if err != nil { return nil, err } - return user, nil + return &user, nil } func UpdateUserPassword(userID int64, passwordHash string) error { - query := ` - UPDATE users - SET password_hash = $1, updated_at = CURRENT_TIMESTAMP - WHERE id = $2 - ` - _, err := db.Exec(query, passwordHash, userID) - return err + return db.Model(&User{ID: userID}).Updates(map[string]interface{}{ + "password_hash": passwordHash, + "updated_at": time.Now(), + }).Error } func GetAllUsers() ([]User, error) { - query := ` - SELECT id, username, email, role, avatar_url, created_at, updated_at - FROM users - ` - rows, err := db.Query(query) - if err != nil { - return nil, err - } - defer rows.Close() - var users []User - for rows.Next() { - user := User{} - err := rows.Scan(&user.ID, &user.Username, &user.Email, &user.Role, &user.AvatarURL, &user.CreatedAt, &user.UpdatedAt) - if err != nil { - return nil, err - } - users = append(users, user) - } - return users, nil + err := db.Find(&users).Error + return users, err } func GetUserRole(userID int64) (string, error) { - query := ` - SELECT role - FROM users - WHERE id = $1 - ` var role string - err := db.QueryRow(query, userID).Scan(&role) + err := db.Model(&User{}). + Select("role"). + Where("id = ?", userID). + Scan(&role).Error + if err != nil { return "", err } return role, nil } -func GetUserCount() (int, error) { - query := `SELECT COUNT(*) FROM users` - var count int - err := db.QueryRow(query).Scan(&count) - if err != nil { - return 0, err - } - return count, nil +func GetUserCount() (int64, error) { + var count int64 + err := db.Model(&User{}).Count(&count).Error + return count, err } + +//############################################################################################################## +//ARCHIVED CODE BELOW + +// package models + +// import ( +// "time" + +// "github.com/corecollectives/mist/utils" +// "golang.org/x/crypto/bcrypt" +// ) + +// type User struct { +// ID int64 `json:"id"` +// Username string `json:"username"` +// Email string `json:"email"` +// PasswordHash string `json:"-"` +// Role string `json:"role"` +// AvatarURL *string `json:"avatarUrl"` +// CreatedAt time.Time `json:"createdAt"` +// UpdatedAt time.Time `json:"updatedAt"` +// } + +// func (u *User) Create() error { +// query := ` +// INSERT INTO users (id, username, email, password_hash, role, avatar_url) +// VALUES ($1, $2, $3, $4, $5, $6) +// RETURNING id, username, email, role, avatar_url, created_at, updated_at +// ` +// u.ID = utils.GenerateRandomId() +// err := db.QueryRow(query, u.ID, u.Username, u.Email, u.PasswordHash, u.Role, u.AvatarURL).Scan( +// &u.ID, &u.Username, &u.Email, &u.Role, &u.AvatarURL, &u.CreatedAt, &u.UpdatedAt, +// ) +// return err +// } + +// func (u *User) SetPassword(password string) error { +// hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) +// if err != nil { +// return err +// } +// u.PasswordHash = string(hashedPassword) +// return nil +// } + +// func GetUserByID(userID int64) (*User, error) { +// query := ` +// SELECT id, username, email, role, avatar_url, created_at, updated_at +// FROM users +// WHERE id = $1 +// ` +// user := &User{} +// err := db.QueryRow(query, userID).Scan( +// &user.ID, &user.Username, &user.Email, &user.Role, &user.AvatarURL, &user.CreatedAt, &user.UpdatedAt, +// ) +// if err != nil { +// return nil, err +// } +// return user, nil +// } + +// func DeleteUserByID(userID int64) error { +// query := `DELETE FROM users WHERE id = $1` +// _, err := db.Exec(query, userID) +// return err +// } + +// func UpdateUser(u *User) error { +// query := ` +// UPDATE users +// SET username = $1, email = $2, role = $3, avatar_url = $4, updated_at = CURRENT_TIMESTAMP +// WHERE id = $5 +// RETURNING updated_at +// ` +// return db.QueryRow(query, u.Username, u.Email, u.Role, u.AvatarURL, u.ID).Scan(&u.UpdatedAt) +// } + +// func (u *User) MatchPassword(password string) bool { +// query := ` +// SELECT password_hash +// FROM users +// WHERE id = $1 +// ` +// var storedHash string +// err := db.QueryRow(query, u.ID).Scan(&storedHash) +// if err != nil { +// return false +// } + +// return bcrypt.CompareHashAndPassword([]byte(storedHash), []byte(password)) == nil +// } + +// func (u *User) UpdatePassword() error { +// query := ` +// UPDATE users +// SET password_hash = $1, updated_at = CURRENT_TIMESTAMP +// WHERE id = $2 +// RETURNING updated_at +// ` +// return db.QueryRow(query, u.PasswordHash, u.ID).Scan(&u.UpdatedAt) + +// } + +// func GetUserByEmail(email string) (*User, error) { +// query := ` +// SELECT id, username, email, role, avatar_url, created_at, updated_at +// FROM users +// WHERE email = $1 +// ` +// user := &User{} +// err := db.QueryRow(query, email).Scan( +// &user.ID, &user.Username, &user.Email, &user.Role, &user.AvatarURL, &user.CreatedAt, &user.UpdatedAt, +// ) +// if err != nil { +// return nil, err +// } +// return user, nil +// } + +// func GetUserByUsername(username string) (*User, error) { +// query := ` +// SELECT id, username, email, role, avatar_url, created_at, updated_at +// FROM users +// WHERE username = $1 +// ` +// user := &User{} +// err := db.QueryRow(query, username).Scan( +// &user.ID, &user.Username, &user.Email, &user.Role, &user.AvatarURL, &user.CreatedAt, &user.UpdatedAt, +// ) +// if err != nil { +// return nil, err +// } +// return user, nil +// } + +// func UpdateUserPassword(userID int64, passwordHash string) error { +// query := ` +// UPDATE users +// SET password_hash = $1, updated_at = CURRENT_TIMESTAMP +// WHERE id = $2 +// ` +// _, err := db.Exec(query, passwordHash, userID) +// return err +// } + +// func GetAllUsers() ([]User, error) { +// query := ` +// SELECT id, username, email, role, avatar_url, created_at, updated_at +// FROM users +// ` +// rows, err := db.Query(query) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// var users []User +// for rows.Next() { +// user := User{} +// err := rows.Scan(&user.ID, &user.Username, &user.Email, &user.Role, &user.AvatarURL, &user.CreatedAt, &user.UpdatedAt) +// if err != nil { +// return nil, err +// } +// users = append(users, user) +// } +// return users, nil +// } + +// func GetUserRole(userID int64) (string, error) { +// query := ` +// SELECT role +// FROM users +// WHERE id = $1 +// ` +// var role string +// err := db.QueryRow(query, userID).Scan(&role) +// if err != nil { +// return "", err +// } +// return role, nil +// } + +// func GetUserCount() (int, error) { +// query := `SELECT COUNT(*) FROM users` +// var count int +// err := db.QueryRow(query).Scan(&count) +// if err != nil { +// return 0, err +// } +// return count, nil +// } diff --git a/server/models/volume.go b/server/models/volume.go index e2e88d8..cc3fc74 100644 --- a/server/models/volume.go +++ b/server/models/volume.go @@ -1,18 +1,19 @@ package models import ( - "database/sql" "time" + + "gorm.io/gorm" ) type Volume struct { - ID int64 `db:"id" json:"id"` - AppID int64 `db:"app_id" json:"appId"` - Name string `db:"name" json:"name"` - HostPath string `db:"host_path" json:"hostPath"` - ContainerPath string `db:"container_path" json:"containerPath"` - ReadOnly bool `db:"read_only" json:"readOnly"` - CreatedAt time.Time `db:"created_at" json:"createdAt"` + ID int64 `gorm:"primaryKey;autoIncrement:true" json:"id"` + AppID int64 `gorm:"uniqueIndex:idx_app_vol_name;not null;constraint:OnDelete:CASCADE" json:"appId"` + Name string `gorm:"uniqueIndex:idx_app_vol_name;not null" json:"name"` + HostPath string `gorm:"not null" json:"hostPath"` + ContainerPath string `gorm:"not null" json:"containerPath"` + ReadOnly bool `gorm:"default:false" json:"readOnly"` + CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` } func (v *Volume) ToJson() map[string]interface{} { @@ -28,78 +29,156 @@ func (v *Volume) ToJson() map[string]interface{} { } func GetVolumesByAppID(appID int64) ([]Volume, error) { - query := ` - SELECT id, app_id, name, host_path, container_path, read_only, created_at - FROM volumes - WHERE app_id = ? - ORDER BY created_at DESC - ` - rows, err := db.Query(query, appID) - if err != nil { - return nil, err - } - defer rows.Close() - var volumes []Volume - for rows.Next() { - var vol Volume - err := rows.Scan(&vol.ID, &vol.AppID, &vol.Name, &vol.HostPath, &vol.ContainerPath, &vol.ReadOnly, &vol.CreatedAt) - if err != nil { - return nil, err - } - volumes = append(volumes, vol) - } - - return volumes, rows.Err() + err := db.Where("app_id = ?", appID).Order("created_at DESC").Find(&volumes).Error + return volumes, err } func GetVolumeByID(id int64) (*Volume, error) { - query := ` - SELECT id, app_id, name, host_path, container_path, read_only, created_at - FROM volumes - WHERE id = ? - ` var vol Volume - err := db.QueryRow(query, id).Scan(&vol.ID, &vol.AppID, &vol.Name, &vol.HostPath, &vol.ContainerPath, &vol.ReadOnly, &vol.CreatedAt) - if err == sql.ErrNoRows { - return nil, nil - } + err := db.First(&vol, id).Error if err != nil { + if err == gorm.ErrRecordNotFound { + return nil, nil + } return nil, err } return &vol, nil } func CreateVolume(appID int64, name, hostPath, containerPath string, readOnly bool) (*Volume, error) { - query := ` - INSERT INTO volumes (app_id, name, host_path, container_path, read_only, created_at) - VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP) - ` - result, err := db.Exec(query, appID, name, hostPath, containerPath, readOnly) - if err != nil { - return nil, err + vol := &Volume{ + AppID: appID, + Name: name, + HostPath: hostPath, + ContainerPath: containerPath, + ReadOnly: readOnly, } - - id, err := result.LastInsertId() + err := db.Create(vol).Error if err != nil { return nil, err } - - return GetVolumeByID(id) + return vol, nil } func UpdateVolume(id int64, name, hostPath, containerPath string, readOnly bool) error { - query := ` - UPDATE volumes - SET name = ?, host_path = ?, container_path = ?, read_only = ? - WHERE id = ? - ` - _, err := db.Exec(query, name, hostPath, containerPath, readOnly, id) - return err + return db.Model(&Volume{ID: id}).Updates(map[string]interface{}{ + "name": name, + "host_path": hostPath, + "container_path": containerPath, + "read_only": readOnly, + }).Error } func DeleteVolume(id int64) error { - query := `DELETE FROM volumes WHERE id = ?` - _, err := db.Exec(query, id) - return err + return db.Delete(&Volume{}, id).Error } + +//############################################################################################################## +//ARCHIVED CODE BELOW + +// package models + +// import ( +// "database/sql" +// "time" +// ) + +// type Volume struct { +// ID int64 `db:"id" json:"id"` +// AppID int64 `db:"app_id" json:"appId"` +// Name string `db:"name" json:"name"` +// HostPath string `db:"host_path" json:"hostPath"` +// ContainerPath string `db:"container_path" json:"containerPath"` +// ReadOnly bool `db:"read_only" json:"readOnly"` +// CreatedAt time.Time `db:"created_at" json:"createdAt"` +// } + +// func (v *Volume) ToJson() map[string]interface{} { +// return map[string]interface{}{ +// "id": v.ID, +// "appId": v.AppID, +// "name": v.Name, +// "hostPath": v.HostPath, +// "containerPath": v.ContainerPath, +// "readOnly": v.ReadOnly, +// "createdAt": v.CreatedAt, +// } +// } + +// func GetVolumesByAppID(appID int64) ([]Volume, error) { +// query := ` +// SELECT id, app_id, name, host_path, container_path, read_only, created_at +// FROM volumes +// WHERE app_id = ? +// ORDER BY created_at DESC +// ` +// rows, err := db.Query(query, appID) +// if err != nil { +// return nil, err +// } +// defer rows.Close() + +// var volumes []Volume +// for rows.Next() { +// var vol Volume +// err := rows.Scan(&vol.ID, &vol.AppID, &vol.Name, &vol.HostPath, &vol.ContainerPath, &vol.ReadOnly, &vol.CreatedAt) +// if err != nil { +// return nil, err +// } +// volumes = append(volumes, vol) +// } + +// return volumes, rows.Err() +// } + +// func GetVolumeByID(id int64) (*Volume, error) { +// query := ` +// SELECT id, app_id, name, host_path, container_path, read_only, created_at +// FROM volumes +// WHERE id = ? +// ` +// var vol Volume +// err := db.QueryRow(query, id).Scan(&vol.ID, &vol.AppID, &vol.Name, &vol.HostPath, &vol.ContainerPath, &vol.ReadOnly, &vol.CreatedAt) +// if err == sql.ErrNoRows { +// return nil, nil +// } +// if err != nil { +// return nil, err +// } +// return &vol, nil +// } + +// func CreateVolume(appID int64, name, hostPath, containerPath string, readOnly bool) (*Volume, error) { +// query := ` +// INSERT INTO volumes (app_id, name, host_path, container_path, read_only, created_at) +// VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP) +// ` +// result, err := db.Exec(query, appID, name, hostPath, containerPath, readOnly) +// if err != nil { +// return nil, err +// } + +// id, err := result.LastInsertId() +// if err != nil { +// return nil, err +// } + +// return GetVolumeByID(id) +// } + +// func UpdateVolume(id int64, name, hostPath, containerPath string, readOnly bool) error { +// query := ` +// UPDATE volumes +// SET name = ?, host_path = ?, container_path = ?, read_only = ? +// WHERE id = ? +// ` +// _, err := db.Exec(query, name, hostPath, containerPath, readOnly, id) +// return err +// } + +// func DeleteVolume(id int64) error { +// query := `DELETE FROM volumes WHERE id = ?` +// _, err := db.Exec(query, id) +// return err +// } From 4a6ae98739c64f6cd39601331bcf5d66fefaf2e4 Mon Sep 17 00:00:00 2001 From: Tanish Date: Thu, 15 Jan 2026 13:58:23 +0530 Subject: [PATCH 17/48] fixed errors and removed old sql dependencies --- server/api/handlers/projects/createProject.go | 10 +- server/api/handlers/projects/updateProject.go | 20 +- server/api/handlers/updates/update.go | 9 +- server/docker/deployer.go | 325 ++++++++++++++++-- server/docker/deployerMain.go | 8 +- server/docker/loadDeployment.go | 19 +- server/main.go | 11 +- server/models/app.go | 2 +- server/models/temp.go | 1 + server/queue/deployQueue.go | 6 +- server/queue/handleWork.go | 4 +- server/queue/main.go | 6 +- 12 files changed, 353 insertions(+), 68 deletions(-) diff --git a/server/api/handlers/projects/createProject.go b/server/api/handlers/projects/createProject.go index d80ce04..2ab25a4 100644 --- a/server/api/handlers/projects/createProject.go +++ b/server/api/handlers/projects/createProject.go @@ -1,7 +1,6 @@ package projects import ( - "database/sql" "encoding/json" "net/http" @@ -42,12 +41,13 @@ func CreateProject(w http.ResponseWriter, r *http.Request) { OwnerID: userData.ID, } if input.Description != "" { - project.Description = sql.NullString{String: input.Description, Valid: true} + desc := input.Description + project.Description = &desc + } else { + project.Description = nil } if input.Tags != nil { - for _, tag := range input.Tags { - project.Tags = append(project.Tags, sql.NullString{String: tag, Valid: true}) - } + project.Tags = input.Tags } err := project.InsertInDB() diff --git a/server/api/handlers/projects/updateProject.go b/server/api/handlers/projects/updateProject.go index efe1a53..7eb8a9b 100644 --- a/server/api/handlers/projects/updateProject.go +++ b/server/api/handlers/projects/updateProject.go @@ -57,19 +57,23 @@ func UpdateProject(w http.ResponseWriter, r *http.Request) { return } - tags := make([]sql.NullString, len(input.Tags)) - for i, tag := range input.Tags { - tags[i] = sql.NullString{ - String: tag, - Valid: true, - } + // tags := make([]string, len(input.Tags)) + // for i, tag := range input.Tags { + // tags[i] = tag + // } + var desc *string + if input.Description != "" { + desc = &input.Description + + } else { + desc = nil } project := &models.Project{ ID: projectId, Name: input.Name, - Description: sql.NullString{String: input.Description, Valid: input.Description != ""}, - Tags: tags, + Description: desc, + Tags: input.Tags, } err = models.UpdateProject(project) diff --git a/server/api/handlers/updates/update.go b/server/api/handlers/updates/update.go index 3e84aa2..8cce9dd 100644 --- a/server/api/handlers/updates/update.go +++ b/server/api/handlers/updates/update.go @@ -270,13 +270,16 @@ func ClearStuckUpdate(w http.ResponseWriter, r *http.Request) { // Only allow clearing in_progress updates if updateLog.Status != "in_progress" { - handlers.SendResponse(w, http.StatusBadRequest, false, nil, "Can only clear in_progress updates", "Current status: "+updateLog.Status) + handlers.SendResponse(w, http.StatusBadRequest, false, nil, "Can only clear in_progress updates", "Current status: "+string(updateLog.Status)) return } - + currentLogs := "" + if updateLog.Logs != nil { + currentLogs = *updateLog.Logs + } // Mark as failed with note that it was manually cleared errMsg := "Update was manually cleared by administrator" - clearLog := updateLog.Logs + "\n⚠️ " + errMsg + "\n" + clearLog := currentLogs + "\n⚠️ " + errMsg + "\n" err = models.UpdateUpdateLogStatus(id, "failed", clearLog, &errMsg) if err != nil { log.Error().Err(err).Int64("update_log_id", id).Msg("Failed to clear stuck update") diff --git a/server/docker/deployer.go b/server/docker/deployer.go index 83ceaeb..2f34af5 100644 --- a/server/docker/deployer.go +++ b/server/docker/deployer.go @@ -1,7 +1,6 @@ package docker import ( - "database/sql" "encoding/json" "fmt" "os" @@ -12,9 +11,10 @@ import ( "github.com/corecollectives/mist/constants" "github.com/corecollectives/mist/models" "github.com/corecollectives/mist/utils" + "gorm.io/gorm" ) -func DeployApp(dep *models.Deployment, app *models.App, appContextPath, imageTag, containerName string, db *sql.DB, logfile *os.File, logger *utils.DeploymentLogger) error { +func DeployApp(dep *models.Deployment, app *models.App, appContextPath, imageTag, containerName string, db *gorm.DB, logfile *os.File, logger *utils.DeploymentLogger) error { logger.Info("Starting deployment process") @@ -203,45 +203,43 @@ func DeployApp(dep *models.Deployment, app *models.App, appContextPath, imageTag return nil } -func UpdateDeployment(dep *models.Deployment, db *sql.DB) error { - stmt, err := db.Prepare("UPDATE deployments SET status=?, stage=?, progress=?, logs=?, error_message=?, finished_at=? WHERE id=?") - if err != nil { - return err - } - defer stmt.Close() - - _, err = stmt.Exec(dep.Status, dep.Stage, dep.Progress, dep.Logs, dep.ErrorMessage, dep.FinishedAt, dep.ID) - return err +func UpdateDeployment(dep *models.Deployment, db *gorm.DB) error { + return db.Model(dep).Updates(map[string]interface{}{ + "status": dep.Status, + "stage": dep.Stage, + "progress": dep.Progress, + "logs": dep.Logs, + "error_message": dep.ErrorMessage, + "finished_at": dep.FinishedAt, + }).Error } func GetLogsPath(commitHash string, depId int64) string { return filepath.Join(constants.Constants["LogPath"].(string), commitHash+strconv.FormatInt(depId, 10)+"_build_logs") } -func UpdateAppStatus(appID int64, status string, db *sql.DB) error { - query := `UPDATE apps SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?` - _, err := db.Exec(query, status, appID) - return err +func UpdateAppStatus(appID int64, status string, db *gorm.DB) error { + return db.Model(&models.App{ID: appID}).Update("status", status).Error } -func GetDeploymentConfig(deploymentID int64, app *models.App, db *sql.DB) (int, []string, map[string]string, error) { +func GetDeploymentConfig(deploymentID int64, app *models.App, db *gorm.DB) (int, []string, map[string]string, error) { appID, err := models.GetAppIDByDeploymentID(deploymentID) if err != nil { return 0, nil, nil, fmt.Errorf("get app ID failed: %w", err) } - var port *int - err = db.QueryRow("SELECT port FROM apps WHERE id = ?", appID).Scan(&port) + var port int + err = db.Model(&models.App{}).Select("port").Where("id = ?", appID).Scan(&port).Error if err != nil { return 0, nil, nil, fmt.Errorf("get port failed: %w", err) } - if port == nil { - defaultPort := 3000 - port = &defaultPort + + if port == 0 { + port = 3000 } domains, err := models.GetDomainsByAppID(appID) - if err != nil && err != sql.ErrNoRows { + if err != nil { return 0, nil, nil, fmt.Errorf("get domains failed: %w", err) } @@ -251,7 +249,7 @@ func GetDeploymentConfig(deploymentID int64, app *models.App, db *sql.DB) (int, } envs, err := models.GetEnvVariablesByAppID(appID) - if err != nil && err != sql.ErrNoRows { + if err != nil { return 0, nil, nil, fmt.Errorf("get env variables failed: %w", err) } @@ -273,5 +271,284 @@ func GetDeploymentConfig(deploymentID int64, app *models.App, db *sql.DB) (int, envMap[env.Key] = env.Value } - return *port, domainStrings, envMap, nil + return port, domainStrings, envMap, nil } + +// package docker + +// import ( +// "database/sql" +// "encoding/json" +// "fmt" +// "os" +// "path/filepath" +// "strconv" +// "time" + +// "github.com/corecollectives/mist/constants" +// "github.com/corecollectives/mist/models" +// "github.com/corecollectives/mist/utils" +// "gorm.io/gorm" +// ) + +// func DeployApp(dep *models.Deployment, app *models.App, appContextPath, imageTag, containerName string, db *gorm.DB, logfile *os.File, logger *utils.DeploymentLogger) error { + +// logger.Info("Starting deployment process") + +// logger.Info("Getting port, domains, and environment variables") +// port, domains, envVars, err := GetDeploymentConfig(dep.ID, app, db) +// if err != nil { +// logger.Error(err, "Failed to get deployment configuration") +// dep.Status = "failed" +// dep.Stage = "failed" +// dep.Progress = 0 +// errMsg := fmt.Sprintf("Failed to get deployment config: %v", err) +// dep.ErrorMessage = &errMsg +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "failed", "failed", 0, &errMsg) +// return fmt.Errorf("get deployment config failed: %w", err) +// } + +// logger.InfoWithFields("Configuration loaded", map[string]interface{}{ +// "domains": domains, +// "port": port, +// "envVars": len(envVars), +// "appType": app.AppType, +// }) + +// if app.AppType == models.AppTypeDatabase { +// logger.Info("Database app detected - pulling Docker image instead of building") + +// if app.TemplateName == nil || *app.TemplateName == "" { +// logger.Error(nil, "Database app missing template name") +// dep.Status = "failed" +// dep.Stage = "failed" +// dep.Progress = 0 +// errMsg := "Database app requires a template name" +// dep.ErrorMessage = &errMsg +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "failed", "failed", 0, &errMsg) +// return fmt.Errorf("database app missing template") +// } + +// template, err := models.GetServiceTemplateByName(*app.TemplateName) +// if err != nil { +// logger.Error(err, "Failed to get service template") +// dep.Status = "failed" +// dep.Stage = "failed" +// dep.Progress = 0 +// errMsg := fmt.Sprintf("Failed to get template: %v", err) +// dep.ErrorMessage = &errMsg +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "failed", "failed", 0, &errMsg) +// return fmt.Errorf("get template failed: %w", err) +// } + +// if template == nil { +// logger.Error(nil, "Template not found") +// dep.Status = "failed" +// dep.Stage = "failed" +// dep.Progress = 0 +// errMsg := fmt.Sprintf("Template not found: %s", *app.TemplateName) +// dep.ErrorMessage = &errMsg +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "failed", "failed", 0, &errMsg) +// return fmt.Errorf("template not found") +// } + +// dep.Status = "building" +// dep.Stage = "pulling" +// dep.Progress = 50 +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "building", "pulling", 50, nil) + +// imageName := template.DockerImage +// if template.DockerImageVersion != nil && *template.DockerImageVersion != "" { +// imageName = imageName + ":" + *template.DockerImageVersion +// } + +// logger.InfoWithFields("Pulling Docker image", map[string]interface{}{ +// "image": imageName, +// }) + +// if err := PullDockerImage(imageName, logfile); err != nil { +// logger.Error(err, "Docker image pull failed") +// dep.Status = "failed" +// dep.Stage = "failed" +// dep.Progress = 0 +// errMsg := fmt.Sprintf("Pull failed: %v", err) +// dep.ErrorMessage = &errMsg +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "failed", "failed", 0, &errMsg) +// UpdateAppStatus(app.ID, "error", db) +// return fmt.Errorf("pull image failed: %w", err) +// } + +// logger.Info("Docker image pulled successfully") +// imageTag = imageName + +// } else { +// dep.Status = "building" +// dep.Stage = "building" +// dep.Progress = 50 +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "building", "building", 50, nil) + +// logger.Info("Building Docker image with environment variables") +// if err := BuildImage(imageTag, appContextPath, envVars, logfile); err != nil { +// logger.Error(err, "Docker image build failed") +// dep.Status = "failed" +// dep.Stage = "failed" +// dep.Progress = 0 +// errMsg := fmt.Sprintf("Build failed: %v", err) +// dep.ErrorMessage = &errMsg +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "failed", "failed", 0, &errMsg) +// UpdateAppStatus(app.ID, "error", db) +// return fmt.Errorf("build image failed: %w", err) +// } + +// logger.Info("Docker image built successfully") +// } + +// dep.Status = "deploying" +// dep.Stage = "deploying" +// dep.Progress = 80 +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "deploying", "deploying", 80, nil) + +// logger.Info("Stopping existing container if exists") +// err = StopRemoveContainer(containerName, logfile) +// if err != nil { +// logger.Error(err, "Failed to stop/remove existing container") +// dep.Status = "failed" +// dep.Stage = "failed" +// dep.Progress = 0 +// errMsg := fmt.Sprintf("Failed to stop/remove container: %v", err) +// dep.ErrorMessage = &errMsg +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "failed", "failed", 0, &errMsg) +// UpdateAppStatus(app.ID, "error", db) +// return fmt.Errorf("stop/remove container failed: %w", err) +// } + +// logger.InfoWithFields("Running container", map[string]interface{}{ +// "domains": domains, +// "port": port, +// "envVars": len(envVars), +// "appType": app.AppType, +// }) + +// if err := RunContainer(app, imageTag, containerName, domains, port, envVars, logfile); err != nil { +// logger.Error(err, "Failed to run container") +// dep.Status = "failed" +// dep.Stage = "failed" +// dep.Progress = 0 +// errMsg := fmt.Sprintf("Failed to run container: %v", err) +// dep.ErrorMessage = &errMsg +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "failed", "failed", 0, &errMsg) +// UpdateAppStatus(app.ID, "error", db) +// return fmt.Errorf("run container failed: %w", err) +// } + +// dep.Status = "success" +// dep.Stage = "success" +// dep.Progress = 100 +// now := time.Now() +// dep.FinishedAt = &now +// UpdateDeployment(dep, db) +// models.UpdateDeploymentStatus(dep.ID, "success", "success", 100, nil) + +// logger.Info("Updating app status to running") +// err = UpdateAppStatus(app.ID, "running", db) +// if err != nil { +// logger.Error(err, "Failed to update app status (non-fatal)") +// } + +// logger.Info("Cleaning up old Docker images") +// if err := CleanupOldImages(app.ID, 5); err != nil { +// logger.Error(err, "Failed to cleanup old images (non-fatal)") +// } + +// logger.InfoWithFields("Deployment succeeded", map[string]interface{}{ +// "deployment_id": dep.ID, +// "container": containerName, +// "app_status": "running", +// }) + +// return nil +// } + +// func UpdateDeployment(dep *models.Deployment, db *gorm.DB) error { +// stmt, err := db.Prepare("UPDATE deployments SET status=?, stage=?, progress=?, logs=?, error_message=?, finished_at=? WHERE id=?") +// if err != nil { +// return err +// } +// defer stmt.Close() + +// _, err = stmt.Exec(dep.Status, dep.Stage, dep.Progress, dep.Logs, dep.ErrorMessage, dep.FinishedAt, dep.ID) +// return err +// } + +// func GetLogsPath(commitHash string, depId int64) string { +// return filepath.Join(constants.Constants["LogPath"].(string), commitHash+strconv.FormatInt(depId, 10)+"_build_logs") +// } + +// func UpdateAppStatus(appID int64, status string, db *sql.DB) error { +// query := `UPDATE apps SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?` +// _, err := db.Exec(query, status, appID) +// return err +// } + +// func GetDeploymentConfig(deploymentID int64, app *models.App, db *sql.DB) (int, []string, map[string]string, error) { +// appID, err := models.GetAppIDByDeploymentID(deploymentID) +// if err != nil { +// return 0, nil, nil, fmt.Errorf("get app ID failed: %w", err) +// } + +// var port *int +// err = db.QueryRow("SELECT port FROM apps WHERE id = ?", appID).Scan(&port) +// if err != nil { +// return 0, nil, nil, fmt.Errorf("get port failed: %w", err) +// } +// if port == nil { +// defaultPort := 3000 +// port = &defaultPort +// } + +// domains, err := models.GetDomainsByAppID(appID) +// if err != nil && err != sql.ErrNoRows { +// return 0, nil, nil, fmt.Errorf("get domains failed: %w", err) +// } + +// var domainStrings []string +// for _, d := range domains { +// domainStrings = append(domainStrings, d.Domain) +// } + +// envs, err := models.GetEnvVariablesByAppID(appID) +// if err != nil && err != sql.ErrNoRows { +// return 0, nil, nil, fmt.Errorf("get env variables failed: %w", err) +// } + +// envMap := make(map[string]string) + +// if app.AppType == models.AppTypeDatabase && app.TemplateName != nil { +// template, err := models.GetServiceTemplateByName(*app.TemplateName) +// if err == nil && template != nil && template.DefaultEnvVars != nil { +// var defaultEnvs map[string]string +// if err := json.Unmarshal([]byte(*template.DefaultEnvVars), &defaultEnvs); err == nil { +// for k, v := range defaultEnvs { +// envMap[k] = v +// } +// } +// } +// } + +// for _, env := range envs { +// envMap[env.Key] = env.Value +// } + +// return *port, domainStrings, envMap, nil +// } diff --git a/server/docker/deployerMain.go b/server/docker/deployerMain.go index a28a8fe..1300316 100644 --- a/server/docker/deployerMain.go +++ b/server/docker/deployerMain.go @@ -1,7 +1,6 @@ package docker import ( - "database/sql" "fmt" "os" "path/filepath" @@ -9,9 +8,10 @@ import ( "github.com/corecollectives/mist/constants" "github.com/corecollectives/mist/models" "github.com/corecollectives/mist/utils" + "gorm.io/gorm" ) -func DeployerMain(Id int64, db *sql.DB, logFile *os.File, logger *utils.DeploymentLogger) (string, error) { +func DeployerMain(Id int64, db *gorm.DB, logFile *os.File, logger *utils.DeploymentLogger) (string, error) { dep, err := LoadDeployment(Id, db) if err != nil { logger.Error(err, "Failed to load deployment") @@ -19,7 +19,9 @@ func DeployerMain(Id int64, db *sql.DB, logFile *os.File, logger *utils.Deployme } var appId int64 - err = db.QueryRow("SELECT app_id FROM deployments WHERE id = ?", Id).Scan(&appId) + // err = db.QueryRow("SELECT app_id FROM deployments WHERE id = ?", Id).Scan(&appId) + err = db.Table("deployments").Select("app_id").Where("id = ?", Id).Take(&appId).Error + if err != nil { logger.Error(err, "Failed to get app_id") return "", fmt.Errorf("failed to get app_id: %w", err) diff --git a/server/docker/loadDeployment.go b/server/docker/loadDeployment.go index 196db66..77b0281 100644 --- a/server/docker/loadDeployment.go +++ b/server/docker/loadDeployment.go @@ -1,27 +1,18 @@ package docker import ( - "database/sql" - "github.com/corecollectives/mist/models" + "gorm.io/gorm" ) -func LoadDeployment(depId int64, db *sql.DB) (*models.Deployment, error) { - row := db.QueryRow("SELECT id, app_id, commit_hash, commit_message, triggered_by, logs, status, created_at, finished_at FROM deployments WHERE id = ?", depId) +func LoadDeployment(depId int64, db *gorm.DB) (*models.Deployment, error) { + // row := db.QueryRow("SELECT id, app_id, commit_hash, commit_message, triggered_by, logs, status, created_at, finished_at FROM deployments WHERE id = ?", depId) dep := &models.Deployment{} - var triggeredBy sql.NullInt64 - var finishedAt sql.NullTime - var logs sql.NullString - err := row.Scan(&dep.ID, &dep.AppID, &dep.CommitHash, &dep.CommitMessage, &triggeredBy, &logs, &dep.Status, &dep.CreatedAt, &finishedAt) + err := db.Table("deployments").Where("id=?", depId).First(&dep).Error + if err != nil { return nil, err } - if triggeredBy.Valid { - dep.TriggeredBy = &triggeredBy.Int64 - } - if finishedAt.Valid { - dep.FinishedAt = &finishedAt.Time - } return dep, nil } diff --git a/server/main.go b/server/main.go index d943101..2ec74ab 100644 --- a/server/main.go +++ b/server/main.go @@ -24,14 +24,14 @@ func main() { &models.EnvVariable{}, &models.GithubApp{}, &models.Project{}, - &models.ProjectMembers{}, + &models.ProjectMember{}, &models.GitProvider{}, &models.GithubInstallation{}, &models.AppRepositories{}, &models.Domain{}, &models.Volume{}, &models.Cron{}, - &models.Registries{}, + &models.Registry{}, &models.SystemSettings{}, &models.Logs{}, &models.AuditLog{}, @@ -46,7 +46,12 @@ func main() { log.Fatal().Err(err).Msg("Error initializing database") return } - defer dbInstance.Close() + sqldb, err := dbInstance.DB() + if err != nil { + log.Fatal().Err(err).Msg("Error getting sql.DB from gorm DB") + return + } + defer sqldb.Close() log.Info().Msg("Database initialized successfully") models.SetDB(dbInstance) diff --git a/server/models/app.go b/server/models/app.go index 4788877..1b55a21 100644 --- a/server/models/app.go +++ b/server/models/app.go @@ -195,7 +195,7 @@ func GetAppRepoInfo(appId int64) (string, string, int64, string, error) { return repo, app.GitBranch, app.ProjectID, app.Name, nil } -func getAppRepoAndBranch(appId int64) (string, string, error) { +func GetAppRepoAndBranch(appId int64) (string, string, error) { var app App err := db.Select("git_repository, git_branch").First(&app, appId).Error if err != nil { diff --git a/server/models/temp.go b/server/models/temp.go index e69de29..778a4c0 100644 --- a/server/models/temp.go +++ b/server/models/temp.go @@ -0,0 +1 @@ +package models \ No newline at end of file diff --git a/server/queue/deployQueue.go b/server/queue/deployQueue.go index 5418e39..15d1c8d 100644 --- a/server/queue/deployQueue.go +++ b/server/queue/deployQueue.go @@ -2,11 +2,11 @@ package queue import ( "context" - "database/sql" "fmt" "sync" "github.com/rs/zerolog/log" + "gorm.io/gorm" ) type Queue struct { @@ -18,7 +18,7 @@ type Queue struct { var queue *Queue -func NewQueue(buffer int, db *sql.DB) *Queue { +func NewQueue(buffer int, db *gorm.DB) *Queue { ctx, cancel := context.WithCancel(context.Background()) q := &Queue{ jobs: make(chan int64, buffer), @@ -36,7 +36,7 @@ func GetQueue() *Queue { return queue } -func (q *Queue) StartWorker(db *sql.DB) { +func (q *Queue) StartWorker(db *gorm.DB) { q.wg.Add(1) go func() { defer q.wg.Done() diff --git a/server/queue/handleWork.go b/server/queue/handleWork.go index d6dfed6..3b09c8c 100644 --- a/server/queue/handleWork.go +++ b/server/queue/handleWork.go @@ -1,7 +1,6 @@ package queue import ( - "database/sql" "fmt" "sync" @@ -10,6 +9,7 @@ import ( "github.com/corecollectives/mist/github" "github.com/corecollectives/mist/models" "github.com/corecollectives/mist/utils" + "gorm.io/gorm" ) // to prevent concurrent deployments of same app @@ -19,7 +19,7 @@ import ( // then this will be helpful var deploymentLocks sync.Map -func (q *Queue) HandleWork(id int64, db *sql.DB) { +func (q *Queue) HandleWork(id int64, db *gorm.DB) { defer func() { if r := recover(); r != nil { errMsg := fmt.Sprintf("panic during deployment: %v", r) diff --git a/server/queue/main.go b/server/queue/main.go index bff4daf..0bb1675 100644 --- a/server/queue/main.go +++ b/server/queue/main.go @@ -1,8 +1,10 @@ package queue -import "database/sql" +import ( + "gorm.io/gorm" +) -func InitQueue(db *sql.DB) *Queue { +func InitQueue(db *gorm.DB) *Queue { q := NewQueue(5, db) return q } From 75f5b504fb9c378bc1b0ed342c65b1275d0c2b56 Mon Sep 17 00:00:00 2001 From: Tanish Date: Thu, 15 Jan 2026 14:52:28 +0530 Subject: [PATCH 18/48] gormified everythnig,old code successfully archived --- server/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/server/main.go b/server/main.go index 2ec74ab..ed76312 100644 --- a/server/main.go +++ b/server/main.go @@ -40,6 +40,7 @@ func main() { &models.Session{}, &models.Notification{}, &models.UpdateLog{}, + &models.SystemSettingsDbVer{}, //this needs checking ) _ = queue.InitQueue(dbInstance) if err != nil { From 6a25e3f78498e9d8dee01f022460423b8cc2f03e Mon Sep 17 00:00:00 2001 From: Tanish Date: Thu, 15 Jan 2026 18:48:23 +0530 Subject: [PATCH 19/48] fixed system setting table --- server/main.go | 4 ++-- server/models/systemSettings.go | 8 ++++---- server/models/systemSettingsDbVer.go | 7 ------- 3 files changed, 6 insertions(+), 13 deletions(-) delete mode 100644 server/models/systemSettingsDbVer.go diff --git a/server/main.go b/server/main.go index ed76312..2388a89 100644 --- a/server/main.go +++ b/server/main.go @@ -32,7 +32,7 @@ func main() { &models.Volume{}, &models.Cron{}, &models.Registry{}, - &models.SystemSettings{}, + &models.SystemSettingEntry{}, &models.Logs{}, &models.AuditLog{}, &models.ServiceTemplate{}, @@ -40,7 +40,7 @@ func main() { &models.Session{}, &models.Notification{}, &models.UpdateLog{}, - &models.SystemSettingsDbVer{}, //this needs checking + // &models.SystemSettingsDbVer{}, //this needs checking ) _ = queue.InitQueue(dbInstance) if err != nil { diff --git a/server/models/systemSettings.go b/server/models/systemSettings.go index 262a9bf..8af0dcf 100644 --- a/server/models/systemSettings.go +++ b/server/models/systemSettings.go @@ -23,13 +23,13 @@ type SystemSettings struct { AutoCleanupImages bool `json:"autoCleanupImages"` } -type systemSettingEntry struct { +type SystemSettingEntry struct { Key string `gorm:"primaryKey" json:"key"` Value string `json:"value"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } -func (systemSettingEntry) TableName() string { +func (SystemSettingEntry) TableName() string { return "system_settings" } @@ -42,7 +42,7 @@ func generateRandomSecret(length int) (string, error) { } func GetSystemSetting(key string) (string, error) { - var entry systemSettingEntry + var entry SystemSettingEntry err := db.Where("key = ?", key).First(&entry).Error if err != nil { @@ -55,7 +55,7 @@ func GetSystemSetting(key string) (string, error) { } func SetSystemSetting(key, value string) error { - entry := systemSettingEntry{ + entry := SystemSettingEntry{ Key: key, Value: value, } diff --git a/server/models/systemSettingsDbVer.go b/server/models/systemSettingsDbVer.go deleted file mode 100644 index b285fdc..0000000 --- a/server/models/systemSettingsDbVer.go +++ /dev/null @@ -1,7 +0,0 @@ -package models - -type SystemSettingsDbVer struct { - key string `gorm:"primaryKey"` - value string `gorm:"not null"` - updatedAt int64 `gorm:"autoUpdateTime"` -} From abba0d9fba7185a2ca7b2c1b6326382677340ea0 Mon Sep 17 00:00:00 2001 From: 07calc Date: Thu, 15 Jan 2026 20:41:12 +0530 Subject: [PATCH 20/48] fix: gorm existing table issues --- cli/cmd/db.go | 15 +- cli/cmd/user.go | 1 - cli/go.mod | 9 +- cli/go.sum | 20 ++- server/api/handlers/applications/preview.go | 5 +- server/api/handlers/auth/login.go | 5 +- server/api/handlers/auth/me.go | 4 +- server/api/handlers/github/repositories.go | 5 +- server/api/handlers/projects/deleteProject.go | 5 +- .../api/handlers/projects/getProjectFromId.go | 5 +- server/api/handlers/projects/updateMembers.go | 5 +- server/api/handlers/projects/updateProject.go | 5 +- server/api/handlers/users/deleteUser.go | 5 +- server/api/handlers/users/getUserById.go | 5 +- server/db/main.go | 7 +- server/db/migrations.go | 151 ++++++++++++++++++ server/github/types.go | 6 +- server/github/webHook.go | 4 +- server/main.go | 28 ---- 19 files changed, 218 insertions(+), 72 deletions(-) create mode 100644 server/db/migrations.go diff --git a/cli/cmd/db.go b/cli/cmd/db.go index d667d82..557a78a 100644 --- a/cli/cmd/db.go +++ b/cli/cmd/db.go @@ -1,36 +1,27 @@ package cmd import ( - "database/sql" "fmt" "os" "github.com/corecollectives/mist/models" _ "github.com/mattn/go-sqlite3" + "gorm.io/driver/sqlite" + "gorm.io/gorm" ) const dbPath = "/var/lib/mist/mist.db" -// initDB initializes the database connection for CLI -// It expects the database file to already exist func initDB() error { - // Check if database file exists if _, err := os.Stat(dbPath); os.IsNotExist(err) { return fmt.Errorf("database file not found at %s. Please ensure Mist is installed and running", dbPath) } - // Open database connection - db, err := sql.Open("sqlite3", dbPath) + db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{}) if err != nil { return fmt.Errorf("failed to open database: %v", err) } - // Test connection - if err := db.Ping(); err != nil { - return fmt.Errorf("failed to connect to database: %v", err) - } - - // Set the database instance for models models.SetDB(db) return nil } diff --git a/cli/cmd/user.go b/cli/cmd/user.go index d836fe3..1c546bf 100644 --- a/cli/cmd/user.go +++ b/cli/cmd/user.go @@ -128,7 +128,6 @@ func changePassword(args []string) { } func listUsers(args []string) { - // Initialize database if err := initDB(); err != nil { fmt.Printf("Error: %v\n", err) os.Exit(1) diff --git a/cli/go.mod b/cli/go.mod index 64b2941..a61e38e 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -4,16 +4,23 @@ go 1.25.1 require ( github.com/corecollectives/mist v0.0.0 + github.com/mattn/go-sqlite3 v1.14.33 golang.org/x/crypto v0.43.0 golang.org/x/term v0.36.0 + gorm.io/driver/sqlite v1.6.0 + gorm.io/gorm v1.31.1 ) require ( + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-sqlite3 v1.14.32 // indirect github.com/rs/zerolog v1.34.0 // indirect golang.org/x/sys v0.37.0 // indirect + golang.org/x/text v0.33.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) replace github.com/corecollectives/mist => ../server diff --git a/cli/go.sum b/cli/go.sum index 5582f98..f1199d7 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -1,12 +1,18 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= -github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.33 h1:A5blZ5ulQo2AtayQ9/limgHEkFreKj1Dv226a1K73s0= +github.com/mattn/go-sqlite3 v1.14.33/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= @@ -20,3 +26,13 @@ golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= +gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= +gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg= +gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= diff --git a/server/api/handlers/applications/preview.go b/server/api/handlers/applications/preview.go index 4640afd..7d3770f 100644 --- a/server/api/handlers/applications/preview.go +++ b/server/api/handlers/applications/preview.go @@ -1,8 +1,8 @@ package applications import ( - "database/sql" "encoding/json" + "errors" "fmt" "net" "net/http" @@ -10,6 +10,7 @@ import ( "github.com/corecollectives/mist/api/handlers" "github.com/corecollectives/mist/api/middleware" "github.com/corecollectives/mist/models" + "gorm.io/gorm" ) func getOutboundIP() string { @@ -56,7 +57,7 @@ func GetPreviewURL(w http.ResponseWriter, r *http.Request) { domain, err := models.GetPrimaryDomainByAppID(req.AppID) if err != nil { - if err == sql.ErrNoRows || err.Error() == "sql: no rows in result set" { + if errors.Is(err, gorm.ErrRecordNotFound) { app, appErr := models.GetApplicationByID(req.AppID) if appErr != nil { handlers.SendResponse(w, http.StatusInternalServerError, false, nil, "Failed to get application", appErr.Error()) diff --git a/server/api/handlers/auth/login.go b/server/api/handlers/auth/login.go index 4b6729d..b0b91dd 100644 --- a/server/api/handlers/auth/login.go +++ b/server/api/handlers/auth/login.go @@ -1,8 +1,8 @@ package auth import ( - "database/sql" "encoding/json" + "errors" "net/http" "strings" @@ -10,6 +10,7 @@ import ( "github.com/corecollectives/mist/api/middleware" "github.com/corecollectives/mist/models" "github.com/rs/zerolog/log" + "gorm.io/gorm" ) func LoginHandler(w http.ResponseWriter, r *http.Request) { @@ -28,7 +29,7 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) { return } user, err := models.GetUserByEmail(cred.Email) - if err == sql.ErrNoRows { + if errors.Is(err, gorm.ErrRecordNotFound) { handlers.SendResponse(w, http.StatusUnauthorized, false, nil, "Invalid email or password", "Unauthorized") return } else if err != nil { diff --git a/server/api/handlers/auth/me.go b/server/api/handlers/auth/me.go index 68bd7fb..270f5ac 100644 --- a/server/api/handlers/auth/me.go +++ b/server/api/handlers/auth/me.go @@ -1,7 +1,6 @@ package auth import ( - "database/sql" "errors" "net/http" @@ -9,6 +8,7 @@ import ( "github.com/corecollectives/mist/api/middleware" "github.com/corecollectives/mist/models" "github.com/corecollectives/mist/store" + "gorm.io/gorm" ) func MeHandler(w http.ResponseWriter, r *http.Request) { @@ -29,7 +29,7 @@ func MeHandler(w http.ResponseWriter, r *http.Request) { userId := claims.UserID user, err := models.GetUserByID(userId) - if errors.Is(err, sql.ErrNoRows) { + if errors.Is(err, gorm.ErrRecordNotFound) { handlers.SendResponse(w, http.StatusOK, true, map[string]interface{}{"setupRequired": setupRequired, "user": nil}, "User not found", "") return } else if err != nil { diff --git a/server/api/handlers/github/repositories.go b/server/api/handlers/github/repositories.go index fc8f2ed..698cc17 100644 --- a/server/api/handlers/github/repositories.go +++ b/server/api/handlers/github/repositories.go @@ -1,8 +1,8 @@ package github import ( - "database/sql" "encoding/json" + "errors" "fmt" "net/http" "time" @@ -11,6 +11,7 @@ import ( "github.com/corecollectives/mist/api/middleware" "github.com/corecollectives/mist/github" "github.com/corecollectives/mist/models" + "gorm.io/gorm" ) type RepoListResponse struct { @@ -26,7 +27,7 @@ func GetRepositories(w http.ResponseWriter, r *http.Request) { } installationID, err := models.GetInstallationID(int(userData.ID)) - if err == sql.ErrNoRows { + if errors.Is(err, gorm.ErrRecordNotFound) { handlers.SendResponse(w, http.StatusNotFound, false, nil, "no installation found for user", "No installation found") return } diff --git a/server/api/handlers/projects/deleteProject.go b/server/api/handlers/projects/deleteProject.go index e496859..1864a8f 100644 --- a/server/api/handlers/projects/deleteProject.go +++ b/server/api/handlers/projects/deleteProject.go @@ -1,13 +1,14 @@ package projects import ( - "database/sql" + "errors" "net/http" "strconv" "github.com/corecollectives/mist/api/handlers" "github.com/corecollectives/mist/api/middleware" "github.com/corecollectives/mist/models" + "gorm.io/gorm" ) func DeleteProject(w http.ResponseWriter, r *http.Request) { @@ -29,7 +30,7 @@ func DeleteProject(w http.ResponseWriter, r *http.Request) { } project, err := models.GetProjectByID(projectId) - if err == sql.ErrNoRows { + if errors.Is(err, gorm.ErrRecordNotFound) { handlers.SendResponse(w, http.StatusNotFound, false, nil, "Project not found", "no project with that ID") return } else if err != nil { diff --git a/server/api/handlers/projects/getProjectFromId.go b/server/api/handlers/projects/getProjectFromId.go index e60ba68..6c9b024 100644 --- a/server/api/handlers/projects/getProjectFromId.go +++ b/server/api/handlers/projects/getProjectFromId.go @@ -1,13 +1,14 @@ package projects import ( - "database/sql" + "errors" "net/http" "strconv" "github.com/corecollectives/mist/api/handlers" "github.com/corecollectives/mist/api/middleware" "github.com/corecollectives/mist/models" + "gorm.io/gorm" ) func GetProjectFromId(w http.ResponseWriter, r *http.Request) { @@ -31,7 +32,7 @@ func GetProjectFromId(w http.ResponseWriter, r *http.Request) { } project, err := models.GetProjectByID(projectId) - if err == sql.ErrNoRows { + if errors.Is(err, gorm.ErrRecordNotFound) { handlers.SendResponse(w, http.StatusNotFound, false, nil, "Project not found", "no project with that ID") return } else if err != nil { diff --git a/server/api/handlers/projects/updateMembers.go b/server/api/handlers/projects/updateMembers.go index 149c4d6..df865cd 100644 --- a/server/api/handlers/projects/updateMembers.go +++ b/server/api/handlers/projects/updateMembers.go @@ -1,14 +1,15 @@ package projects import ( - "database/sql" "encoding/json" + "errors" "net/http" "strconv" "github.com/corecollectives/mist/api/handlers" "github.com/corecollectives/mist/api/middleware" "github.com/corecollectives/mist/models" + "gorm.io/gorm" ) func UpdateMembers(w http.ResponseWriter, r *http.Request) { @@ -38,7 +39,7 @@ func UpdateMembers(w http.ResponseWriter, r *http.Request) { } project, err := models.GetProjectByID(projectId) - if err == sql.ErrNoRows { + if errors.Is(err, gorm.ErrRecordNotFound) { handlers.SendResponse(w, http.StatusNotFound, false, nil, "Project not found", "no such project") return } else if err != nil { diff --git a/server/api/handlers/projects/updateProject.go b/server/api/handlers/projects/updateProject.go index 7eb8a9b..71974e3 100644 --- a/server/api/handlers/projects/updateProject.go +++ b/server/api/handlers/projects/updateProject.go @@ -1,14 +1,15 @@ package projects import ( - "database/sql" "encoding/json" + "errors" "net/http" "strconv" "github.com/corecollectives/mist/api/handlers" "github.com/corecollectives/mist/api/middleware" "github.com/corecollectives/mist/models" + "gorm.io/gorm" ) func UpdateProject(w http.ResponseWriter, r *http.Request) { @@ -44,7 +45,7 @@ func UpdateProject(w http.ResponseWriter, r *http.Request) { } existingProject, err := models.GetProjectByID(projectId) - if err == sql.ErrNoRows { + if errors.Is(err, gorm.ErrRecordNotFound) { handlers.SendResponse(w, http.StatusNotFound, false, nil, "Project not found", "no such project") return } else if err != nil { diff --git a/server/api/handlers/users/deleteUser.go b/server/api/handlers/users/deleteUser.go index 4684de0..a3e6e32 100644 --- a/server/api/handlers/users/deleteUser.go +++ b/server/api/handlers/users/deleteUser.go @@ -1,7 +1,7 @@ package users import ( - "database/sql" + "errors" "net/http" "strconv" @@ -9,6 +9,7 @@ import ( "github.com/corecollectives/mist/api/middleware" "github.com/corecollectives/mist/models" "github.com/corecollectives/mist/store" + "gorm.io/gorm" ) func DeleteUser(w http.ResponseWriter, r *http.Request) { @@ -43,7 +44,7 @@ func DeleteUser(w http.ResponseWriter, r *http.Request) { return } userToDeleteRole, err := models.GetUserRole(int64(id)) - if err == sql.ErrNoRows { + if errors.Is(err, gorm.ErrRecordNotFound) { handlers.SendResponse(w, http.StatusNotFound, false, nil, "User not found", "No such user") return } else if err != nil { diff --git a/server/api/handlers/users/getUserById.go b/server/api/handlers/users/getUserById.go index d8ce507..37173d7 100644 --- a/server/api/handlers/users/getUserById.go +++ b/server/api/handlers/users/getUserById.go @@ -1,13 +1,14 @@ package users import ( - "database/sql" + "errors" "net/http" "strconv" "github.com/corecollectives/mist/api/handlers" "github.com/corecollectives/mist/api/middleware" "github.com/corecollectives/mist/models" + "gorm.io/gorm" ) func GetUserById(w http.ResponseWriter, r *http.Request) { @@ -30,7 +31,7 @@ func GetUserById(w http.ResponseWriter, r *http.Request) { } user, err := models.GetUserByID(userID) if err != nil { - if err == sql.ErrNoRows { + if errors.Is(err, gorm.ErrRecordNotFound) { handlers.SendResponse(w, http.StatusNotFound, false, nil, "User not found", "No user exists with the given ID") return } diff --git a/server/db/main.go b/server/db/main.go index 584bd48..9bffea3 100644 --- a/server/db/main.go +++ b/server/db/main.go @@ -9,7 +9,6 @@ import ( _ "github.com/mattn/go-sqlite3" "gorm.io/driver/sqlite" "gorm.io/gorm" - "gorm.io/gorm/logger" ) func InitDB() (*gorm.DB, error) { @@ -25,11 +24,15 @@ func InitDB() (*gorm.DB, error) { return nil, fmt.Errorf("failed to create database directory: %v", err) } db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{ - Logger: logger.Default.LogMode(logger.Info), + // Logger: logger.Default.LogMode(logger.Info), }) if err != nil { return nil, fmt.Errorf("failed to open database: %v", err) } + err = MigrateDb(db) + if err != nil { + return nil, err + } // if err := runMigrations(db); err != nil { // return nil, fmt.Errorf("failed to run migrations: %v", err) // } diff --git a/server/db/migrations.go b/server/db/migrations.go new file mode 100644 index 0000000..b07b282 --- /dev/null +++ b/server/db/migrations.go @@ -0,0 +1,151 @@ +package db + +import ( + "fmt" + "reflect" + "strings" + + "github.com/corecollectives/mist/models" + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" +) + +func migrateExistingTable(db *gorm.DB, model interface{}) error { + migrator := db.Migrator() + + stmt := &gorm.Statement{DB: db} + if err := stmt.Parse(model); err != nil { + return fmt.Errorf("failed to parse model: %w", err) + } + + tableName := stmt.Schema.Table + + for _, field := range stmt.Schema.Fields { + if field.DBName == "" { + continue + } + + if !migrator.HasColumn(model, field.DBName) { + columnType := getSQLiteColumnType(field) + if columnType == "" { + continue + } + + sql := fmt.Sprintf("ALTER TABLE `%s` ADD COLUMN `%s` %s", tableName, field.DBName, columnType) + + if field.HasDefaultValue && field.DefaultValue != "" { + sql += fmt.Sprintf(" DEFAULT %s", field.DefaultValue) + } + + if err := db.Exec(sql).Error; err != nil { + fmt.Printf("migration.go: warning adding column %s.%s: %v\n", tableName, field.DBName, err) + } + } + } + + return nil +} + +func getSQLiteColumnType(field *schema.Field) string { + switch field.DataType { + case schema.Bool: + return "BOOLEAN" + case schema.Int, schema.Uint: + return "INTEGER" + case schema.Float: + return "REAL" + case schema.String: + return "TEXT" + case schema.Time: + return "DATETIME" + case schema.Bytes: + return "BLOB" + default: + kind := field.FieldType.Kind() + if kind == reflect.Ptr { + kind = field.FieldType.Elem().Kind() + } + switch kind { + case reflect.Bool: + return "BOOLEAN" + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return "INTEGER" + case reflect.Float32, reflect.Float64: + return "REAL" + case reflect.String: + return "TEXT" + case reflect.Struct: + typeName := field.FieldType.String() + if strings.Contains(typeName, "Time") || strings.Contains(typeName, "DeletedAt") { + return "DATETIME" + } + return "TEXT" + default: + return "TEXT" + } + } +} + +func MigrateDb(dbInstance *gorm.DB) error { + migrator := dbInstance.Migrator() + + allModels := []interface{}{ + &models.User{}, + &models.ApiToken{}, + &models.App{}, + &models.AuditLog{}, + &models.Backup{}, + &models.Deployment{}, + &models.EnvVariable{}, + &models.GithubApp{}, + &models.Project{}, + &models.ProjectMember{}, + &models.GitProvider{}, + &models.GithubInstallation{}, + &models.AppRepositories{}, + &models.Domain{}, + &models.Volume{}, + &models.Cron{}, + &models.Registry{}, + &models.SystemSettingEntry{}, + &models.Logs{}, + &models.ServiceTemplate{}, + &models.Session{}, + &models.Notification{}, + &models.UpdateLog{}, + } + + for _, model := range allModels { + if migrator.HasTable(model) { + if err := migrateExistingTable(dbInstance, model); err != nil { + fmt.Printf("migration.go: warning migrating existing table: %v\n", err) + } + } else { + if err := dbInstance.AutoMigrate(model); err != nil { + fmt.Printf("migration.go: error creating table: %v\n", err) + return err + } + } + } + + var wildCardDomain = models.SystemSettingEntry{ + Key: "wildcard_domain", + Value: " ", + } + var MistAppName = models.SystemSettingEntry{ + Key: "mist_app_name", + Value: "mist", + } + var Version = models.SystemSettingEntry{ + Key: "version", + Value: "1.0.4", + } + + dbInstance.Clauses(clause.Insert{Modifier: "OR IGNORE"}).Create(&wildCardDomain) + dbInstance.Clauses(clause.Insert{Modifier: "OR IGNORE"}).Create(&MistAppName) + dbInstance.Clauses(clause.Insert{Modifier: "OR REPLACE"}).Create(&Version) + + return nil +} diff --git a/server/github/types.go b/server/github/types.go index 1a517eb..27f4da5 100644 --- a/server/github/types.go +++ b/server/github/types.go @@ -1,7 +1,5 @@ package github -import "database/sql" - type PushEvent struct { Ref string `json:"ref"` Before string `json:"before"` @@ -186,8 +184,8 @@ type GithubApp struct { type GithubInstallation struct { InstallationID int - AccessToken sql.NullString - TokenExpiresAt sql.NullTime + AccessToken *string + TokenExpiresAt *string } type LatestCommit struct { diff --git a/server/github/webHook.go b/server/github/webHook.go index 249c779..3b7a24b 100644 --- a/server/github/webHook.go +++ b/server/github/webHook.go @@ -1,12 +1,12 @@ package github import ( - "database/sql" "errors" "strings" "github.com/corecollectives/mist/models" "github.com/rs/zerolog/log" + "gorm.io/gorm" ) func CreateDeploymentFromGithubPushEvent(evt PushEvent) (int64, error) { @@ -58,7 +58,7 @@ func CreateDeploymentFromGithubPushEvent(evt PushEvent) (int64, error) { } dep, err := models.GetDeploymentByAppIDAndCommitHash(appID, commit) - if err != nil && err != sql.ErrNoRows { + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { log.Error().Err(err). Int64("app_id", appID). Str("commit", commit). diff --git a/server/main.go b/server/main.go index 2388a89..051ffb3 100644 --- a/server/main.go +++ b/server/main.go @@ -14,34 +14,6 @@ func main() { utils.InitLogger() log.Info().Msg("Starting Mist server") dbInstance, err := db.InitDB() - dbInstance.AutoMigrate( - &models.User{}, - &models.ApiToken{}, - &models.App{}, - &models.AuditLog{}, - &models.Backup{}, - &models.Deployment{}, - &models.EnvVariable{}, - &models.GithubApp{}, - &models.Project{}, - &models.ProjectMember{}, - &models.GitProvider{}, - &models.GithubInstallation{}, - &models.AppRepositories{}, - &models.Domain{}, - &models.Volume{}, - &models.Cron{}, - &models.Registry{}, - &models.SystemSettingEntry{}, - &models.Logs{}, - &models.AuditLog{}, - &models.ServiceTemplate{}, - &models.ApiToken{}, - &models.Session{}, - &models.Notification{}, - &models.UpdateLog{}, - // &models.SystemSettingsDbVer{}, //this needs checking - ) _ = queue.InitQueue(dbInstance) if err != nil { log.Fatal().Err(err).Msg("Error initializing database") From 5ae7bcb2d8a7c3ea75f4ecad5bf5a77e47d47da9 Mon Sep 17 00:00:00 2001 From: 07calc Date: Thu, 15 Jan 2026 22:42:12 +0530 Subject: [PATCH 21/48] fix: gorm logging --- server/db/main.go | 3 +- server/db/migrations.go | 2 +- server/go.mod | 22 ++++++------ server/go.sum | 52 +++++++++++++++++++-------- server/lib/cleanup.go | 4 +-- server/models/deployment.go | 72 +++++++++++++++++++++---------------- server/models/updateLog.go | 3 -- 7 files changed, 95 insertions(+), 63 deletions(-) diff --git a/server/db/main.go b/server/db/main.go index 9bffea3..a7fb9f7 100644 --- a/server/db/main.go +++ b/server/db/main.go @@ -9,6 +9,7 @@ import ( _ "github.com/mattn/go-sqlite3" "gorm.io/driver/sqlite" "gorm.io/gorm" + "gorm.io/gorm/logger" ) func InitDB() (*gorm.DB, error) { @@ -24,7 +25,7 @@ func InitDB() (*gorm.DB, error) { return nil, fmt.Errorf("failed to create database directory: %v", err) } db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{ - // Logger: logger.Default.LogMode(logger.Info), + Logger: logger.Discard, }) if err != nil { return nil, fmt.Errorf("failed to open database: %v", err) diff --git a/server/db/migrations.go b/server/db/migrations.go index b07b282..e5efc68 100644 --- a/server/db/migrations.go +++ b/server/db/migrations.go @@ -140,7 +140,7 @@ func MigrateDb(dbInstance *gorm.DB) error { } var Version = models.SystemSettingEntry{ Key: "version", - Value: "1.0.4", + Value: "1.0.3", } dbInstance.Clauses(clause.Insert{Modifier: "OR IGNORE"}).Create(&wildCardDomain) diff --git a/server/go.mod b/server/go.mod index 4b3ffc5..77e377a 100644 --- a/server/go.mod +++ b/server/go.mod @@ -3,13 +3,19 @@ module github.com/corecollectives/mist go 1.25.1 require ( + github.com/go-git/go-git/v6 v6.0.0-20251231065035-29ae690a9f19 github.com/golang-jwt/jwt v3.2.2+incompatible github.com/gorilla/websocket v1.5.3 github.com/mattn/go-sqlite3 v1.14.33 + github.com/moby/go-archive v0.2.0 + github.com/moby/moby/api v1.52.0 + github.com/moby/moby/client v0.2.1 github.com/rs/zerolog v1.34.0 github.com/shirou/gopsutil v3.21.11+incompatible golang.org/x/crypto v0.46.0 gopkg.in/yaml.v3 v3.0.1 + gorm.io/driver/sqlite v1.6.0 + gorm.io/gorm v1.31.1 ) require ( @@ -27,32 +33,27 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-git/gcfg/v2 v2.0.2 // indirect github.com/go-git/go-billy/v6 v6.0.0-20251217170237-e9738f50a3cd // indirect - github.com/go-git/go-git/v6 v6.0.0-20251231065035-29ae690a9f19 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/klauspost/compress v1.18.2 // indirect - github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/kevinburke/ssh_config v1.4.0 // indirect + github.com/klauspost/compress v1.18.2 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/go-archive v0.2.0 // indirect - github.com/moby/moby/api v1.52.0 // indirect - github.com/moby/moby/client v0.2.1 // indirect github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/sys/sequential v0.6.0 // indirect github.com/moby/sys/user v0.4.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect github.com/pjbgf/sha1cd v0.5.0 // indirect github.com/sergi/go-diff v1.4.0 // indirect - github.com/stretchr/testify v1.11.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/tklauser/go-sysconf v0.3.15 // indirect github.com/tklauser/numcpus v0.10.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect @@ -61,12 +62,9 @@ require ( go.opentelemetry.io/otel v1.35.0 // indirect go.opentelemetry.io/otel/metric v1.35.0 // indirect go.opentelemetry.io/otel/trace v1.35.0 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/text v0.33.0 // indirect - gorm.io/driver/sqlite v1.6.0 // indirect - gorm.io/gorm v1.31.1 // indirect golang.org/x/net v0.48.0 // indirect golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.33.0 // indirect ) replace github.com/docker/docker/api => github.com/moby/moby/api v1.52.0-beta.2 diff --git a/server/go.sum b/server/go.sum index 17a841a..8c19508 100644 --- a/server/go.sum +++ b/server/go.sum @@ -1,7 +1,13 @@ +github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= @@ -26,10 +32,14 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= +github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-git/gcfg/v2 v2.0.2 h1:MY5SIIfTGGEMhdA7d7JePuVVxtKL7Hp+ApGDJAJ7dpo= github.com/go-git/gcfg/v2 v2.0.2/go.mod h1:/lv2NsxvhepuMrldsFilrgct6pxzpGdSRC13ydTLSLs= github.com/go-git/go-billy/v6 v6.0.0-20251217170237-e9738f50a3cd h1:Gd/f9cGi/3h1JOPaa6er+CkKUGyGX2DBJdFbDKVO+R0= github.com/go-git/go-billy/v6 v6.0.0-20251217170237-e9738f50a3cd/go.mod h1:d3XQcsHu1idnquxt48kAv+h+1MUiYKLH/e7LAzjP+pI= +github.com/go-git/go-git-fixtures/v5 v5.1.2-0.20251229094738-4b14af179146 h1:xYfxAopYyL44ot6dMBIb1Z1njFM0ZBQ99HdIB99KxLs= +github.com/go-git/go-git-fixtures/v5 v5.1.2-0.20251229094738-4b14af179146/go.mod h1:QE/75B8tBSLNGyUUbA9tw3EGHoFtYOtypa2h8YJxsWI= github.com/go-git/go-git/v6 v6.0.0-20251231065035-29ae690a9f19 h1:0lz2eJScP8v5YZQsrEw+ggWC5jNySjg4bIZo5BIh6iI= github.com/go-git/go-git/v6 v6.0.0-20251231065035-29ae690a9f19/go.mod h1:L+Evfcs7EdTqxwv854354cb6+++7TFL3hJn3Wy4g+3w= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -44,28 +54,34 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keL github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= -github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/kevinburke/ssh_config v1.4.0 h1:6xxtP5bZ2E4NF5tuQulISpTO2z8XbtH8cg1PWkxoFkQ= github.com/kevinburke/ssh_config v1.4.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= +github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= +github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= -github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.33 h1:A5blZ5ulQo2AtayQ9/limgHEkFreKj1Dv226a1K73s0= github.com/mattn/go-sqlite3 v1.14.33/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= @@ -93,6 +109,8 @@ github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= @@ -103,9 +121,8 @@ github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMT github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= @@ -122,10 +139,12 @@ go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= -golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= -golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= @@ -135,21 +154,26 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg= gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/server/lib/cleanup.go b/server/lib/cleanup.go index c0214e1..6d03887 100644 --- a/server/lib/cleanup.go +++ b/server/lib/cleanup.go @@ -104,7 +104,7 @@ func cleanupUpdates() error { Str("version", currentVersion). Msg("Completing successful update that was interrupted by service restart") - completionLog := latestLog.Logs + "\n✅ Update completed successfully (verified on restart)\n" + completionLog := *latestLog.Logs + "\n✅ Update completed successfully (verified on restart)\n" err = models.UpdateUpdateLogStatus(latestLog.ID, "success", completionLog, nil) if err != nil { log.Error().Err(err).Int64("update_log_id", latestLog.ID).Msg("Failed to complete pending update") @@ -127,7 +127,7 @@ func cleanupUpdates() error { Msg("Update appears to have failed (version mismatch detected on startup)") errMsg := "Update process was interrupted and version does not match target" - failureLog := latestLog.Logs + "\n❌ " + errMsg + "\n" + failureLog := *latestLog.Logs + "\n❌ " + errMsg + "\n" err = models.UpdateUpdateLogStatus(latestLog.ID, "failed", failureLog, &errMsg) if err != nil { log.Error().Err(err).Int64("update_log_id", latestLog.ID).Msg("Failed to mark failed update") diff --git a/server/models/deployment.go b/server/models/deployment.go index 02f8e5c..d02fadb 100644 --- a/server/models/deployment.go +++ b/server/models/deployment.go @@ -500,40 +500,52 @@ func UpdateContainerInfo(depID int64, containerID, containerName, imageTag strin // return err // } func GetIncompleteDeployments() ([]Deployment, error) { - query := ` - SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, - deployment_number, container_id, container_name, image_tag, - logs, build_logs_path, status, stage, progress, error_message, - created_at, started_at, finished_at, duration, is_active, rolled_back_from - FROM deployments - WHERE status = 'building' OR status = 'deploying' - ORDER BY created_at DESC - ` - - rows, err := db.Query(query) - if err != nil { - return nil, err - } - defer rows.Close() - var deployments []Deployment - for rows.Next() { - var d Deployment - if err := rows.Scan( - &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, - &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, - &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, - &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, - &d.IsActive, &d.RolledBackFrom, - ); err != nil { - return nil, err - } - deployments = append(deployments, d) - } - if err := rows.Err(); err != nil { + err := db. + Where("status IN ?", []string{"building", "deploying"}). + Order("created_at DESC"). + Find(&deployments).Error + + if err != nil { return nil, err } return deployments, nil + // query := ` + // SELECT id, app_id, commit_hash, commit_message, commit_author, triggered_by, + // deployment_number, container_id, container_name, image_tag, + // logs, build_logs_path, status, stage, progress, error_message, + // created_at, started_at, finished_at, duration, is_active, rolled_back_from + // FROM deployments + // WHERE status = 'building' OR status = 'deploying' + // ORDER BY created_at DESC + // ` + // + // rows, err := db.Query(query) + // if err != nil { + // return nil, err + // } + // defer rows.Close() + // + // var deployments []Deployment + // for rows.Next() { + // var d Deployment + // if err := rows.Scan( + // &d.ID, &d.AppID, &d.CommitHash, &d.CommitMessage, &d.CommitAuthor, + // &d.TriggeredBy, &d.DeploymentNumber, &d.ContainerID, &d.ContainerName, + // &d.ImageTag, &d.Logs, &d.BuildLogsPath, &d.Status, &d.Stage, &d.Progress, + // &d.ErrorMessage, &d.CreatedAt, &d.StartedAt, &d.FinishedAt, &d.Duration, + // &d.IsActive, &d.RolledBackFrom, + // ); err != nil { + // return nil, err + // } + // deployments = append(deployments, d) + // } + // + // if err := rows.Err(); err != nil { + // return nil, err + // } + // + // return deployments, nil } diff --git a/server/models/updateLog.go b/server/models/updateLog.go index 7cb7920..1d9da56 100644 --- a/server/models/updateLog.go +++ b/server/models/updateLog.go @@ -174,7 +174,6 @@ func GetUpdateLogsAsString() (string, error) { return builder.String(), nil } -<<<<<<< HEAD func CheckAndCompletePendingUpdates() error { logs, err := GetUpdateLogs(1) @@ -585,5 +584,3 @@ func CheckAndCompletePendingUpdates() error { // return nil // } -======= ->>>>>>> main From 7389e272b8bae2d501d0b3ce564f641df63ecc3e Mon Sep 17 00:00:00 2001 From: Kanav Agrawal <72596840+HGRgamer@users.noreply.github.com> Date: Sat, 17 Jan 2026 19:10:11 +0000 Subject: [PATCH 22/48] Add dashboard build step to install-local script --- install-local.sh | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/install-local.sh b/install-local.sh index ba1ce62..b140631 100755 --- a/install-local.sh +++ b/install-local.sh @@ -216,6 +216,36 @@ run_step "Building backend" "cd '$INSTALL_DIR/$GO_BACKEND_DIR' && go build -v -o chmod +x "$GO_BINARY_NAME" log "Build complete" +# ---------------- Dashboard Build ---------------- + +if [ -d "$INSTALL_DIR/dash" ]; then + if ! command -v node >/dev/null 2>&1; then + error "Node.js not found. Install from: https://nodejs.org/" + exit 1 + fi + if ! command -v npm >/dev/null 2>&1; then + error "npm not found" + exit 1 + fi + + run_step "Installing dashboard dependencies" "cd '$INSTALL_DIR/dash' && npm install" || exit 1 + run_step "Building dashboard" "cd '$INSTALL_DIR/dash' && npm run build" || exit 1 + + # Move build output to server/static + DASH_BUILD_DIR="$INSTALL_DIR/dash/dist" + STATIC_DIR="$INSTALL_DIR/server/static" + + if [ -d "$DASH_BUILD_DIR" ]; then + run_step "Moving dashboard build to static folder" "sudo rm -rf '$STATIC_DIR' && sudo mv '$DASH_BUILD_DIR' '$STATIC_DIR'" || exit 1 + log "Dashboard built and deployed to server/static" + else + error "Dashboard build output not found" + exit 1 + fi +else + warn "Dashboard directory not found, skipping dashboard build" +fi + # ---------------- CLI Tool ---------------- if [ -d "$INSTALL_DIR/cli" ]; then From 7d8323e1974ef1fd65bae832ba7e4e49ce86ee3a Mon Sep 17 00:00:00 2001 From: Kanav Agrawal <72596840+HGRgamer@users.noreply.github.com> Date: Sun, 18 Jan 2026 00:46:46 +0530 Subject: [PATCH 23/48] Fix documentation link in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3724535..af93eb2 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ fyrer - [GitHub](https://github.com/corecollectives/mist) - [Discord](https://discord.gg/hr6TCQDDkj) -- [Documentation](https://trymist.cloud/guide) +- [Documentation](https://trymist.cloud/guide/getting-started.html) ## License From 2048e63834d61429b172f8a65b957388df088485 Mon Sep 17 00:00:00 2001 From: Ezio Date: Sun, 18 Jan 2026 01:02:40 +0530 Subject: [PATCH 24/48] Fixed the broken docs link in Readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index af93eb2..f7568b0 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ After installation, access the dashboard at `http://your-server-ip:8080` ## Documentation -Full documentation is available at [trymist.cloud](https://trymist.cloud/guide) +Full documentation is available at [trymist.cloud](https://trymist.cloud/guide/getting-started.html) ## Development From b8fa029cbae0cb2c693b9678fc55e68cda42e1c8 Mon Sep 17 00:00:00 2001 From: Kanav Agrawal <72596840+HGRgamer@users.noreply.github.com> Date: Sat, 17 Jan 2026 20:28:15 +0000 Subject: [PATCH 25/48] Fix: Handle empty wildcard domain correctly --- dash/src/pages/Settings.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dash/src/pages/Settings.tsx b/dash/src/pages/Settings.tsx index 760e54d..3487bb6 100644 --- a/dash/src/pages/Settings.tsx +++ b/dash/src/pages/Settings.tsx @@ -80,7 +80,7 @@ export const SettingsPage = () => { try { const settings = await settingsService.updateSystemSettings({ - wildcardDomain: wildcardDomain.trim() || null, + wildcardDomain: wildcardDomain.trim() || '', mistAppName: mistAppName.trim(), }); setWildcardDomain(settings.wildcardDomain || ''); From 586229324fe0adfbfb0368842a5f070e7c263491 Mon Sep 17 00:00:00 2001 From: Kanav Agrawal <72596840+HGRgamer@users.noreply.github.com> Date: Sat, 17 Jan 2026 20:35:14 +0000 Subject: [PATCH 26/48] Switched to yaml parser for traefik config --- server/utils/traefik.go | 104 ++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/server/utils/traefik.go b/server/utils/traefik.go index 563d8d9..712dd3d 100644 --- a/server/utils/traefik.go +++ b/server/utils/traefik.go @@ -29,7 +29,10 @@ func GenerateDynamicConfig(wildcardDomain *string, mistAppName string) error { } dynamicConfigPath := filepath.Join(TraefikConfigDir, TraefikDynamicFile) - content := generateDynamicYAML(wildcardDomain, mistAppName) + content, err := generateDynamicYAML(wildcardDomain, mistAppName) + if err != nil { + return fmt.Errorf("failed to generate dynamic YAML: %w", err) + } if err := os.WriteFile(dynamicConfigPath, []byte(content), 0644); err != nil { return fmt.Errorf("failed to write dynamic config: %w", err) @@ -42,61 +45,60 @@ func GenerateDynamicConfig(wildcardDomain *string, mistAppName string) error { return nil } -func generateDynamicYAML(wildcardDomain *string, mistAppName string) string { - var b strings.Builder - - b.WriteString(`http: - routers: -`) - - var mistDomain string - if wildcardDomain != nil && *wildcardDomain != "" { - domain := strings.TrimPrefix(*wildcardDomain, "*") - domain = strings.TrimPrefix(domain, ".") - - mistDomain = mistAppName + "." + domain - - b.WriteString(fmt.Sprintf(` - mist-dashboard: - rule: Host(`+"`%s`"+`) - entryPoints: - - websecure - service: mist-dashboard - tls: - certResolver: le - - mist-dashboard-http: - rule: Host(`+"`%s`"+`) - entryPoints: - - web - middlewares: - - https-redirect - service: mist-dashboard -`, mistDomain, mistDomain)) +func generateDynamicYAML(wildcardDomain *string, mistAppName string) ([]byte, error) { + cfg := map[string]any{ + "http": map[string]any{ + "routers": map[string]any{}, + "services": map[string]any{}, + "middlewares": map[string]any{ + "https-redirect": map[string]any{ + "redirectScheme": map[string]any{ + "scheme": "https", + "permanent": true, + }, + }, + }, + }, } - b.WriteString(` - services: -`) - - if mistDomain != "" { - b.WriteString(` - mist-dashboard: - loadBalancer: - servers: - - url: "http://172.17.0.1:8080" -`) + if wildcardDomain == nil || *wildcardDomain == "" { + return yaml.Marshal(cfg) } - b.WriteString(` - middlewares: - https-redirect: - redirectScheme: - scheme: https - permanent: true -`) + domain := strings.TrimPrefix(*wildcardDomain, "*") + domain = strings.TrimPrefix(domain, ".") + + mistDomain := mistAppName + "." + domain + + httpConfig := cfg["http"].(map[string]any) + httpConfig["routers"] = map[string]any{ + "mist-dashboard": map[string]any{ + "rule": fmt.Sprintf("Host(`%s`)", mistDomain), + "entryPoints": []string{"websecure"}, + "service": "mist-dashboard", + "tls": map[string]any{ + "certResolver": "le", + }, + }, + "mist-dashboard-http": map[string]any{ + "rule": fmt.Sprintf("Host(`%s`)", mistDomain), + "entryPoints": []string{"web"}, + "middlewares": []string{"https-redirect"}, + "service": "mist-dashboard", + }, + } + + httpConfig["services"] = map[string]any{ + "mist-dashboard": map[string]any{ + "loadBalancer": map[string]any{ + "servers": []map[string]any{ + {"url": "http://172.17.0.1:8080"}, + }, + }, + }, + } - return b.String() + return yaml.Marshal(cfg) } func ChangeLetsEncryptEmail(email string) error { From 4f25498e71d7779be53b7eefc39ceaddfde9505d Mon Sep 17 00:00:00 2001 From: 07calc Date: Sun, 18 Jan 2026 21:23:24 +0530 Subject: [PATCH 27/48] test: db tests --- server/db/main.go | 2 +- server/db/migrations.go | 6 +- test/database/database_test.go | 2305 ++++++++++++++++++++++++++++++++ test/go.mod | 53 +- test/go.sum | 113 +- test/main.go | 1 - 6 files changed, 2348 insertions(+), 132 deletions(-) create mode 100644 test/database/database_test.go delete mode 100644 test/main.go diff --git a/server/db/main.go b/server/db/main.go index a7fb9f7..8ff8189 100644 --- a/server/db/main.go +++ b/server/db/main.go @@ -30,7 +30,7 @@ func InitDB() (*gorm.DB, error) { if err != nil { return nil, fmt.Errorf("failed to open database: %v", err) } - err = MigrateDb(db) + err = MigrateDB(db) if err != nil { return nil, err } diff --git a/server/db/migrations.go b/server/db/migrations.go index e5efc68..4201ff1 100644 --- a/server/db/migrations.go +++ b/server/db/migrations.go @@ -88,7 +88,11 @@ func getSQLiteColumnType(field *schema.Field) string { } } -func MigrateDb(dbInstance *gorm.DB) error { +func MigrateDB(dbInstance *gorm.DB) error { + return migrateDbInternal(dbInstance) +} + +func migrateDbInternal(dbInstance *gorm.DB) error { migrator := dbInstance.Migrator() allModels := []interface{}{ diff --git a/test/database/database_test.go b/test/database/database_test.go new file mode 100644 index 0000000..0573daf --- /dev/null +++ b/test/database/database_test.go @@ -0,0 +1,2305 @@ +package db + +import ( + "fmt" + "os" + "path/filepath" + "testing" + "time" + + mistdb "github.com/corecollectives/mist/db" + "github.com/corecollectives/mist/models" + "github.com/corecollectives/mist/utils" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "gorm.io/gorm/logger" +) + +func setupTestDB(t *testing.T) *gorm.DB { + tmpDir := t.TempDir() + dbPath := filepath.Join(tmpDir, "test.db") + + db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{ + Logger: logger.Default.LogMode(logger.Silent), + }) + if err != nil { + t.Fatalf("failed to open test database: %v", err) + } + + err = mistdb.MigrateDB(db) + if err != nil { + t.Fatalf("failed to run migrations: %v", err) + } + + models.SetDB(db) + return db +} + +func cleanupDB(db *gorm.DB) { + sqlDB, _ := db.DB() + sqlDB.Close() +} + +func TestInitDB_Success(t *testing.T) { + os.Setenv("ENV", "dev") + defer os.Unsetenv("ENV") + + db, err := mistdb.InitDB() + if err != nil { + t.Fatalf("InitDB failed: %v", err) + } + defer cleanupDB(db) + + if db == nil { + t.Fatal("db should not be nil") + } +} + +func TestInitDB_FailsOnInvalidPath(t *testing.T) { + origEnv := os.Getenv("ENV") + os.Setenv("ENV", "dev") + defer os.Setenv("ENV", origEnv) + + t.Skip("Skipping test that depends on filesystem permissions") +} + +func TestMigrateDb_CreatesAllTables(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + expectedTables := []string{ + "users", "api_tokens", "apps", "audit_logs", "backups", + "deployments", "envs", "projects", "project_members", + "git_providers", "github_installations", "app_repositories", "domains", + "volumes", "crons", "registries", "sessions", "notifications", + } + + for _, table := range expectedTables { + if !db.Migrator().HasTable(table) { + t.Errorf("table %s should exist", table) + } + } +} + +func TestMigrateDb_SkipsExistingTables(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + err := mistdb.MigrateDB(db) + if err != nil { + t.Errorf("re-running migrations should not fail: %v", err) + } +} + +func TestUser_Create(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "testuser", + Email: "test@example.com", + PasswordHash: "hash", + } + + err := user.Create() + if err != nil { + t.Fatalf("CreateUser failed: %v", err) + } + + if user.ID == 0 { + t.Error("user ID should be set after creation") + } + + if user.Role != "user" { + t.Error("default role should be user") + } +} + +func TestUser_Create_DuplicateUsername(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user1 := &models.User{ + ID: utils.GenerateRandomId(), + Username: "uniqueuser", + Email: "user1@example.com", + PasswordHash: "hash", + } + user2 := &models.User{ + ID: utils.GenerateRandomId(), + Username: "uniqueuser", + Email: "user2@example.com", + PasswordHash: "hash", + } + + if err := user1.Create(); err != nil { + t.Fatalf("first user creation failed: %v", err) + } + + err := user2.Create() + if err == nil { + t.Error("should fail with duplicate username") + } +} + +func TestUser_Create_DuplicateEmail(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user1 := &models.User{ + ID: utils.GenerateRandomId(), + Username: "user1", + Email: "same@example.com", + PasswordHash: "hash", + } + user2 := &models.User{ + ID: utils.GenerateRandomId(), + Username: "user2", + Email: "same@example.com", + PasswordHash: "hash", + } + + if err := user1.Create(); err != nil { + t.Fatalf("first user creation failed: %v", err) + } + + err := user2.Create() + if err == nil { + t.Error("should fail with duplicate email") + } +} + +func TestUser_SetPassword(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "passuser", + Email: "pass@example.com", + } + + err := user.SetPassword("testpassword123") + if err != nil { + t.Fatalf("SetPassword failed: %v", err) + } + + if user.PasswordHash == "testpassword123" { + t.Error("password should not be stored in plaintext") + } + + if len(user.PasswordHash) < 50 { + t.Error("password hash should be properly hashed") + } +} + +func TestUser_MatchPassword_Success(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "matchuser", + Email: "match@example.com", + } + user.SetPassword("correctpassword") + user.Create() + + if !user.MatchPassword("correctpassword") { + t.Error("MatchPassword should return true for correct password") + } +} + +func TestUser_MatchPassword_WrongPassword(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "wrongpass", + Email: "wrong@example.com", + } + user.SetPassword("correctpassword") + user.Create() + + if user.MatchPassword("wrongpassword") { + t.Error("MatchPassword should return false for wrong password") + } +} + +func TestGetUserByID_Exists(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + origUser := &models.User{ + ID: utils.GenerateRandomId(), + Username: "getbyid", + Email: "getbyid@example.com", + PasswordHash: "hash", + Role: "admin", + } + origUser.Create() + + user, err := models.GetUserByID(origUser.ID) + if err != nil { + t.Fatalf("GetUserByID failed: %v", err) + } + + if user.Username != origUser.Username { + t.Error("retrieved user should match original") + } +} + +func TestGetUserByID_NotExists(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + _, err := models.GetUserByID(999999) + if err == nil { + t.Error("should return error for non-existent user") + } +} + +func TestGetUserByEmail_Exists(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + origUser := &models.User{ + ID: utils.GenerateRandomId(), + Username: "emailtest", + Email: "findme@example.com", + PasswordHash: "hash", + } + origUser.Create() + + user, err := models.GetUserByEmail("findme@example.com") + if err != nil { + t.Fatalf("GetUserByEmail failed: %v", err) + } + + if user.ID != origUser.ID { + t.Error("retrieved user should match by email") + } +} + +func TestGetUserByUsername_Exists(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + origUser := &models.User{ + ID: utils.GenerateRandomId(), + Username: "uniquetestuser", + Email: "unique@example.com", + PasswordHash: "hash", + } + origUser.Create() + + user, err := models.GetUserByUsername("uniquetestuser") + if err != nil { + t.Fatalf("GetUserByUsername failed: %v", err) + } + + if user.ID != origUser.ID { + t.Error("retrieved user should match by username") + } +} + +func TestUpdateUser(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "updateme", + Email: "update@example.com", + PasswordHash: "hash", + } + user.Create() + + newUsername := "updatedname" + newEmail := "newemail@example.com" + user.Username = newUsername + user.Email = newEmail + + err := models.UpdateUser(user) + if err != nil { + t.Fatalf("UpdateUser failed: %v", err) + } + + updated, _ := models.GetUserByID(user.ID) + if updated.Username != newUsername { + t.Error("username should be updated") + } + if updated.Email != newEmail { + t.Error("email should be updated") + } +} + +func TestUpdateUserPassword(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "passupdate", + Email: "passupdate@example.com", + } + user.SetPassword("oldpassword") + user.Create() + + user.SetPassword("newpassword") + err := user.UpdatePassword() + if err != nil { + t.Fatalf("UpdatePassword failed: %v", err) + } + + if user.MatchPassword("oldpassword") { + t.Error("old password should not match") + } + if !user.MatchPassword("newpassword") { + t.Error("new password should match") + } +} + +func TestDeleteUser(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "deleteme", + Email: "delete@example.com", + PasswordHash: "hash", + } + user.Create() + + err := models.DeleteUserByID(user.ID) + if err != nil { + t.Fatalf("DeleteUser failed: %v", err) + } + + _, err = models.GetUserByID(user.ID) + if err == nil { + t.Error("user should be deleted") + } +} + +func TestGetAllUsers(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + for i := 0; i < 5; i++ { + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "listuser" + string(rune('a'+i)), + Email: "listuser" + string(rune('a'+i)) + "@example.com", + PasswordHash: "hash", + } + user.Create() + } + + users, err := models.GetAllUsers() + if err != nil { + t.Fatalf("GetAllUsers failed: %v", err) + } + + if len(users) < 5 { + t.Error("should return all users") + } +} + +func TestGetUserCount(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + initial, _ := models.GetUserCount() + + for i := 0; i < 3; i++ { + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "countuser" + string(rune('a'+i)), + Email: "countuser" + string(rune('a'+i)) + "@example.com", + PasswordHash: "hash", + } + user.Create() + } + + count, err := models.GetUserCount() + if err != nil { + t.Fatalf("GetUserCount failed: %v", err) + } + + if count != initial+3 { + t.Error("count should include all created users") + } +} + +func TestUserRoleRetrieval(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + adminUser := &models.User{ + ID: utils.GenerateRandomId(), + Username: "adminuser", + Email: "admin@example.com", + PasswordHash: "hash", + Role: "admin", + } + adminUser.Create() + + role, err := models.GetUserRole(adminUser.ID) + if err != nil { + t.Fatalf("GetUserRole failed: %v", err) + } + + if role != "admin" { + t.Error("should return correct role") + } +} + +func TestUser_OptionalFields(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + fullName := "Test Full Name" + avatarURL := "https://example.com/avatar.png" + bio := "Test bio" + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "optionalfields", + Email: "optional@example.com", + PasswordHash: "hash", + FullName: &fullName, + AvatarURL: &avatarURL, + Bio: &bio, + } + user.Create() + + retrieved, _ := models.GetUserByID(user.ID) + if retrieved.FullName == nil || *retrieved.FullName != fullName { + t.Error("FullName should be stored correctly") + } + if retrieved.AvatarURL == nil || *retrieved.AvatarURL != avatarURL { + t.Error("AvatarURL should be stored correctly") + } + if retrieved.Bio == nil || *retrieved.Bio != bio { + t.Error("Bio should be stored correctly") + } +} + +func TestProject_Insert(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "projectowner", + Email: "projectowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + desc := "Test project description" + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Test Project", + Description: &desc, + OwnerID: owner.ID, + Tags: []string{"tag1", "tag2"}, + } + + err := project.InsertInDB() + if err != nil { + t.Fatalf("InsertInDB failed: %v", err) + } + + if project.Owner == nil { + t.Error("owner should be populated after insert") + } +} + +func TestProject_GetByID(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "getprojectowner", + Email: "getprojectowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Get Project Test", + OwnerID: owner.ID, + Tags: []string{"test"}, + } + project.InsertInDB() + + retrieved, err := models.GetProjectByID(project.ID) + if err != nil { + t.Fatalf("GetProjectByID failed: %v", err) + } + + if retrieved.Name != project.Name { + t.Error("project name should match") + } +} + +func TestProject_Update(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "updateprojectowner", + Email: "updateprojectowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Original Name", + OwnerID: owner.ID, + } + project.InsertInDB() + + newName := "Updated Name" + newTags := []string{"newtag"} + project.Name = newName + project.Tags = newTags + + err := models.UpdateProject(project) + if err != nil { + t.Fatalf("UpdateProject failed: %v", err) + } + + updated, _ := models.GetProjectByID(project.ID) + if updated.Name != newName { + t.Error("name should be updated") + } +} + +func TestProject_Delete(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "deleteprojectowner", + Email: "deleteprojectowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Delete Project Test", + OwnerID: owner.ID, + } + project.InsertInDB() + + err := models.DeleteProjectByID(project.ID) + if err != nil { + t.Fatalf("DeleteProject failed: %v", err) + } + + _, err = models.GetProjectByID(project.ID) + if err == nil { + t.Error("project should be deleted") + } +} + +func TestProject_HasUserAccess(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "accessuser", + Email: "accessuser@example.com", + PasswordHash: "hash", + } + user.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Access Project", + OwnerID: user.ID, + } + project.InsertInDB() + + hasAccess, err := models.HasUserAccessToProject(user.ID, project.ID) + if err != nil { + t.Fatalf("HasUserAccessToProject failed: %v", err) + } + + if !hasAccess { + t.Error("owner should have access to project") + } +} + +func TestProject_IsUserOwner(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "owneruser", + Email: "owneruser@example.com", + PasswordHash: "hash", + } + user.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Owner Project", + OwnerID: user.ID, + } + project.InsertInDB() + + isOwner, err := models.IsUserProjectOwner(user.ID, project.ID) + if err != nil { + t.Fatalf("IsUserProjectOwner failed: %v", err) + } + + if !isOwner { + t.Error("user should be project owner") + } +} + +func TestProject_UpdateMembers(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "memberowner", + Email: "memberowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + member1 := &models.User{ + ID: utils.GenerateRandomId(), + Username: "member1", + Email: "member1@example.com", + PasswordHash: "hash", + } + member1.Create() + + member2 := &models.User{ + ID: utils.GenerateRandomId(), + Username: "member2", + Email: "member2@example.com", + PasswordHash: "hash", + } + member2.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Members Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + err := models.UpdateProjectMembers(project.ID, []int64{member1.ID, member2.ID}) + if err != nil { + t.Fatalf("UpdateProjectMembers failed: %v", err) + } + + retrieved, _ := models.GetProjectByID(project.ID) + if len(retrieved.ProjectMembers) < 2 { + t.Error("project should have members") + } +} + +func TestProject_OwnerAlwaysIncludedInMembers(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "forcedowner", + Email: "forcedowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Forced Owner Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + err := models.UpdateProjectMembers(project.ID, []int64{}) + if err != nil { + t.Fatalf("UpdateProjectMembers failed: %v", err) + } + + retrieved, _ := models.GetProjectByID(project.ID) + found := false + for _, member := range retrieved.ProjectMembers { + if member.ID == owner.ID { + found = true + break + } + } + + if !found { + t.Error("owner should always be included in members") + } +} + +func TestProject_GetProjectsUserIsPartOf(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "partofuser", + Email: "partofuser@example.com", + PasswordHash: "hash", + } + user.Create() + + project1 := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Project 1", + OwnerID: user.ID, + } + project1.InsertInDB() + + projects, err := models.GetProjectsUserIsPartOf(user.ID) + if err != nil { + t.Fatalf("GetProjectsUserIsPartOf failed: %v", err) + } + + if len(projects) < 1 { + t.Error("should return projects user is part of") + } +} + +func TestApp_Insert(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "appowner", + Email: "appowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "App Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Test App", + CreatedBy: owner.ID, + AppType: models.AppTypeWeb, + GitBranch: "main", + } + + err := app.InsertInDB() + if err != nil { + t.Fatalf("InsertInDB failed: %v", err) + } + + if app.ID == 0 { + t.Error("app ID should be set") + } + if app.AppType != models.AppTypeWeb { + t.Error("default app type should be web") + } + if app.Status != models.StatusStopped { + t.Error("default status should be stopped") + } +} + +func TestApp_GetByID(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "getappowner", + Email: "getappowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Get App Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Get App Test", + CreatedBy: owner.ID, + } + app.InsertInDB() + + retrieved, err := models.GetApplicationByID(app.ID) + if err != nil { + t.Fatalf("GetApplicationByID failed: %v", err) + } + + if retrieved.Name != app.Name { + t.Error("retrieved app should match") + } +} + +func TestApp_GetByProjectID(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "listappowner", + Email: "listappowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "List App Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + for i := 0; i < 3; i++ { + app := &models.App{ + ProjectID: project.ID, + Name: "App " + string(rune('a'+i)), + CreatedBy: owner.ID, + } + app.InsertInDB() + } + + apps, err := models.GetApplicationByProjectID(project.ID) + if err != nil { + t.Fatalf("GetApplicationByProjectID failed: %v", err) + } + + if len(apps) < 3 { + t.Error("should return all apps for project") + } +} + +func TestApp_Update(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "updateappowner", + Email: "updateappowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Update App Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Original App Name", + CreatedBy: owner.ID, + } + app.InsertInDB() + + newName := "Updated App Name" + port := int64(8080) + app.Name = newName + app.Port = &port + + err := app.UpdateApplication() + if err != nil { + t.Fatalf("UpdateApplication failed: %v", err) + } + + updated, _ := models.GetApplicationByID(app.ID) + if updated.Name != newName { + t.Error("name should be updated") + } + if updated.Port == nil || *updated.Port != 8080 { + t.Error("port should be updated") + } +} + +func TestApp_Delete(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "deleteappowner", + Email: "deleteappowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Delete App Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Delete App Test", + CreatedBy: owner.ID, + } + app.InsertInDB() + + err := models.DeleteApplication(app.ID) + if err != nil { + t.Fatalf("DeleteApplication failed: %v", err) + } + + _, err = models.GetApplicationByID(app.ID) + if err == nil { + t.Error("app should be deleted") + } +} + +func TestApp_IsUserOwner(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "appownerverify", + Email: "appownerverify@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "App Owner Verify Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "App Owner Verify Test", + CreatedBy: owner.ID, + } + app.InsertInDB() + + isOwner, err := models.IsUserApplicationOwner(owner.ID, app.ID) + if err != nil { + t.Fatalf("IsUserApplicationOwner failed: %v", err) + } + + if !isOwner { + t.Error("user should be app owner") + } +} + +func TestApp_CascadingDelete(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "cascadeappowner", + Email: "cascadeappowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Cascade App Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Cascade App Test", + CreatedBy: owner.ID, + } + app.InsertInDB() + + deployment := &models.Deployment{ + ID: utils.GenerateRandomId(), + AppID: app.ID, + CommitHash: "abc123", + } + deployment.CreateDeployment() + + models.DeleteApplication(app.ID) + + var appCount int64 + db.Model(&models.App{}).Where("id = ?", app.ID).Count(&appCount) + if appCount != 0 { + t.Error("app should be deleted") + } +} + +func TestDeployment_Create(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "deployowner", + Email: "deployowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Deploy Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Deploy App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + deployment := &models.Deployment{ + ID: utils.GenerateRandomId(), + AppID: app.ID, + CommitHash: "abc123def456", + TriggeredBy: &owner.ID, + } + + err := deployment.CreateDeployment() + if err != nil { + t.Fatalf("CreateDeployment failed: %v", err) + } + + if deployment.DeploymentNumber == nil { + t.Error("deployment number should be set") + } + if *deployment.DeploymentNumber != 1 { + t.Error("first deployment should have number 1") + } + if deployment.Status != models.DeploymentStatusPending { + t.Error("default status should be pending") + } +} + +func TestDeployment_AutoIncrementNumber(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "multideployowner", + Email: "multideployowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Multi Deploy Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Multi Deploy App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + for i := 0; i < 3; i++ { + deployment := &models.Deployment{ + ID: utils.GenerateRandomId(), + AppID: app.ID, + CommitHash: fmt.Sprintf("commit_%d_%d", time.Now().UnixNano(), i), + } + err := deployment.CreateDeployment() + if err != nil { + t.Fatalf("deployment creation failed: %v", err) + } + + if deployment.DeploymentNumber == nil { + t.Errorf("deployment %d: deployment number is nil", i) + } else { + t.Logf("deployment %d: got number %d", i, *deployment.DeploymentNumber) + } + } + + deployments, _ := models.GetDeploymentsByAppID(app.ID) + if len(deployments) != 3 { + t.Errorf("expected 3 deployments, got %d", len(deployments)) + } +} + +func TestDeployment_GetByID(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "getdeployowner", + Email: "getdeployowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Get Deploy Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Get Deploy App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + deployment := &models.Deployment{ + ID: utils.GenerateRandomId(), + AppID: app.ID, + CommitHash: "getdeploy123", + } + deployment.CreateDeployment() + + retrieved, err := models.GetDeploymentByID(deployment.ID) + if err != nil { + t.Fatalf("GetDeploymentByID failed: %v", err) + } + + if retrieved.CommitHash != deployment.CommitHash { + t.Error("retrieved deployment should match") + } +} + +func TestDeployment_GetByAppID(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "listdeployowner", + Email: "listdeployowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "List Deploy Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "List Deploy App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + for i := 0; i < 3; i++ { + deployment := &models.Deployment{ + ID: utils.GenerateRandomId(), + AppID: app.ID, + CommitHash: "listdeploy" + string(rune('a'+i)), + } + deployment.CreateDeployment() + } + + deployments, err := models.GetDeploymentsByAppID(app.ID) + if err != nil { + t.Fatalf("GetDeploymentsByAppID failed: %v", err) + } + + if len(deployments) < 3 { + t.Error("should return all deployments for app") + } +} + +func TestDeployment_UpdateStatus(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "statusdeployowner", + Email: "statusdeployowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Status Deploy Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Status Deploy App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + deployment := &models.Deployment{ + ID: utils.GenerateRandomId(), + AppID: app.ID, + CommitHash: "statusdeploy123", + } + deployment.CreateDeployment() + + err := models.UpdateDeploymentStatus(deployment.ID, string(models.DeploymentStatusSuccess), "completed", 100, nil) + if err != nil { + t.Fatalf("UpdateDeploymentStatus failed: %v", err) + } + + updated, _ := models.GetDeploymentByID(deployment.ID) + if updated.Status != models.DeploymentStatusSuccess { + t.Error("status should be updated") + } + if updated.FinishedAt == nil { + t.Error("finished_at should be set on completion") + } +} + +func TestDeployment_MarkActive(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "activedeployowner", + Email: "activedeployowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Active Deploy Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Active Deploy App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + deployment1 := &models.Deployment{ + ID: utils.GenerateRandomId(), + AppID: app.ID, + CommitHash: "active1", + } + deployment1.CreateDeployment() + + deployment2 := &models.Deployment{ + ID: utils.GenerateRandomId(), + AppID: app.ID, + CommitHash: "active2", + } + deployment2.CreateDeployment() + + err := models.MarkDeploymentActive(deployment1.ID, app.ID) + if err != nil { + t.Fatalf("MarkDeploymentActive failed: %v", err) + } + + d1, _ := models.GetDeploymentByID(deployment1.ID) + d2, _ := models.GetDeploymentByID(deployment2.ID) + + if !d1.IsActive { + t.Error("first deployment should be active") + } + if d2.IsActive { + t.Error("second deployment should not be active") + } +} + +func TestDeployment_GetIncomplete(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "incompletedeployowner", + Email: "incompletedeployowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Incomplete Deploy Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Incomplete Deploy App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + deployment1 := &models.Deployment{ + ID: utils.GenerateRandomId(), + AppID: app.ID, + CommitHash: "incomplete1", + } + deployment1.CreateDeployment() + + deployment2 := &models.Deployment{ + ID: utils.GenerateRandomId(), + AppID: app.ID, + CommitHash: "incomplete2", + } + deployment2.CreateDeployment() + + models.UpdateDeploymentStatus(deployment2.ID, string(models.DeploymentStatusBuilding), "building", 50, nil) + + incomplete, err := models.GetIncompleteDeployments() + if err != nil { + t.Fatalf("GetIncompleteDeployments failed: %v", err) + } + + found := false + for _, d := range incomplete { + if d.ID == deployment2.ID && d.AppID == app.ID { + found = true + break + } + } + + if !found { + t.Logf("Incomplete deployments found: %d", len(incomplete)) + for _, d := range incomplete { + t.Logf(" - ID: %d, AppID: %d, Status: %s", d.ID, d.AppID, d.Status) + } + t.Error("should return incomplete deployments") + } +} + +func TestDomain_Create(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "domainowner", + Email: "domainowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Domain Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Domain App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + domain, err := models.CreateDomain(app.ID, "example.com") + if err != nil { + t.Fatalf("CreateDomain failed: %v", err) + } + + if domain.Domain != "example.com" { + t.Error("domain name should match") + } + if domain.AppID != app.ID { + t.Error("app id should match") + } + if domain.SslStatus != models.SSLStatusPending { + t.Error("default ssl status should be pending") + } +} + +func TestDomain_GetByAppID(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "listdomainowner", + Email: "listdomainowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "List Domain Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "List Domain App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + models.CreateDomain(app.ID, "domain1.example.com") + models.CreateDomain(app.ID, "domain2.example.com") + + domains, err := models.GetDomainsByAppID(app.ID) + if err != nil { + t.Fatalf("GetDomainsByAppID failed: %v", err) + } + + if len(domains) < 2 { + t.Error("should return all domains for app") + } +} + +func TestDomain_GetPrimary(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "primarydomainowner", + Email: "primarydomainowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Primary Domain Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Primary Domain App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + models.CreateDomain(app.ID, "primary.example.com") + models.CreateDomain(app.ID, "secondary.example.com") + + primary, err := models.GetPrimaryDomainByAppID(app.ID) + if err != nil { + t.Fatalf("GetPrimaryDomainByAppID failed: %v", err) + } + + if primary.Domain != "primary.example.com" { + t.Error("first created domain should be primary") + } +} + +func TestDomain_Update(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "updatedomainowner", + Email: "updatedomainowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Update Domain Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Update Domain App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + domain, _ := models.CreateDomain(app.ID, "olddomain.com") + + err := models.UpdateDomain(domain.ID, "newdomain.com") + if err != nil { + t.Fatalf("UpdateDomain failed: %v", err) + } + + updated, _ := models.GetDomainByID(domain.ID) + if updated.Domain != "newdomain.com" { + t.Error("domain should be updated") + } +} + +func TestDomain_Delete(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "deletedomainowner", + Email: "deletedomainowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Delete Domain Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Delete Domain App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + domain, _ := models.CreateDomain(app.ID, "deleteme.com") + + err := models.DeleteDomain(domain.ID) + if err != nil { + t.Fatalf("DeleteDomain failed: %v", err) + } + + _, err = models.GetDomainByID(domain.ID) + if err == nil { + t.Error("domain should be deleted") + } +} + +func TestDomain_UniqueConstraint(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "uniquedomainowner", + Email: "uniquedomainowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Unique Domain Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app1 := &models.App{ + ProjectID: project.ID, + Name: "Unique Domain App 1", + CreatedBy: owner.ID, + } + app1.InsertInDB() + + app2 := &models.App{ + ProjectID: project.ID, + Name: "Unique Domain App 2", + CreatedBy: owner.ID, + } + app2.InsertInDB() + + _, err := models.CreateDomain(app1.ID, "same-domain.com") + if err != nil { + t.Fatalf("first domain creation failed: %v", err) + } + + _, err = models.CreateDomain(app2.ID, "same-domain.com") + if err == nil { + t.Error("should fail with duplicate domain") + } +} + +func TestEnvVariable_Create(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "envarowner", + Email: "envarowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "EnvVar Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "EnvVar App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + env, err := models.CreateEnvVariable(app.ID, "TEST_VAR", "test_value") + if err != nil { + t.Fatalf("CreateEnvVariable failed: %v", err) + } + + if env.Key != "TEST_VAR" { + t.Error("key should match") + } + if env.Value != "test_value" { + t.Error("value should match") + } +} + +func TestEnvVariable_GetByAppID(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "listenvarowner", + Email: "listenvarowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "List EnvVar Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "List EnvVar App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + models.CreateEnvVariable(app.ID, "VAR1", "val1") + models.CreateEnvVariable(app.ID, "VAR2", "val2") + models.CreateEnvVariable(app.ID, "VAR3", "val3") + + envs, err := models.GetEnvVariablesByAppID(app.ID) + if err != nil { + t.Fatalf("GetEnvVariablesByAppID failed: %v", err) + } + + if len(envs) < 3 { + t.Error("should return all env variables") + } +} + +func TestEnvVariable_Update(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "updateenvarowner", + Email: "updateenvarowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Update EnvVar Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Update EnvVar App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + env, _ := models.CreateEnvVariable(app.ID, "UPDATEME", "oldvalue") + + err := models.UpdateEnvVariable(env.ID, "UPDATEME", "newvalue") + if err != nil { + t.Fatalf("UpdateEnvVariable failed: %v", err) + } + + updated, _ := models.GetEnvVariableByID(env.ID) + if updated.Value != "newvalue" { + t.Error("value should be updated") + } +} + +func TestEnvVariable_Delete(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "deleteenvarowner", + Email: "deleteenvarowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Delete EnvVar Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Delete EnvVar App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + env, _ := models.CreateEnvVariable(app.ID, "DELETEME", "value") + + err := models.DeleteEnvVariable(env.ID) + if err != nil { + t.Fatalf("DeleteEnvVariable failed: %v", err) + } + + _, err = models.GetEnvVariableByID(env.ID) + if err == nil { + t.Error("env variable should be deleted") + } +} + +func TestEnvVariable_UniqueConstraint(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "uniqueenvarowner", + Email: "uniqueenvarowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Unique EnvVar Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Unique EnvVar App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + _, err := models.CreateEnvVariable(app.ID, "UNIQUE_VAR", "value1") + if err != nil { + t.Fatalf("first env var creation failed: %v", err) + } + + _, err = models.CreateEnvVariable(app.ID, "UNIQUE_VAR", "value2") + if err == nil { + t.Error("should fail with duplicate key for same app") + } +} + +func TestVolume_Create(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "volumeowner", + Email: "volumeowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Volume Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Volume App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + vol, err := models.CreateVolume(app.ID, "data", "/host/data", "/container/data", false) + if err != nil { + t.Fatalf("CreateVolume failed: %v", err) + } + + if vol.Name != "data" { + t.Error("name should match") + } + if vol.HostPath != "/host/data" { + t.Error("host path should match") + } + if vol.ContainerPath != "/container/data" { + t.Error("container path should match") + } +} + +func TestVolume_GetByAppID(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "listvolumeowner", + Email: "listvolumeowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "List Volume Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "List Volume App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + models.CreateVolume(app.ID, "vol1", "/h1", "/c1", false) + models.CreateVolume(app.ID, "vol2", "/h2", "/c2", true) + + vols, err := models.GetVolumesByAppID(app.ID) + if err != nil { + t.Fatalf("GetVolumesByAppID failed: %v", err) + } + + if len(vols) < 2 { + t.Error("should return all volumes") + } +} + +func TestVolume_Update(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "updatevolumeowner", + Email: "updatevolumeowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Update Volume Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Update Volume App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + vol, _ := models.CreateVolume(app.ID, "oldname", "/old/host", "/old/container", false) + + err := models.UpdateVolume(vol.ID, "newname", "/new/host", "/new/container", true) + if err != nil { + t.Fatalf("UpdateVolume failed: %v", err) + } + + updated, _ := models.GetVolumeByID(vol.ID) + if updated.Name != "newname" { + t.Error("name should be updated") + } + if updated.ReadOnly != true { + t.Error("readOnly should be updated") + } +} + +func TestVolume_Delete(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + owner := &models.User{ + ID: utils.GenerateRandomId(), + Username: "deletevolumeowner", + Email: "deletevolumeowner@example.com", + PasswordHash: "hash", + } + owner.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Delete Volume Project", + OwnerID: owner.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Delete Volume App", + CreatedBy: owner.ID, + } + app.InsertInDB() + + vol, _ := models.CreateVolume(app.ID, "deleteme", "/host", "/container", false) + + err := models.DeleteVolume(vol.ID) + if err != nil { + t.Fatalf("DeleteVolume failed: %v", err) + } + + result, err := models.GetVolumeByID(vol.ID) + if err != nil { + t.Fatalf("GetVolumeByID failed: %v", err) + } + if result != nil { + t.Error("volume should be deleted") + } +} + +func TestTransaction_Success(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "transuser", + Email: "trans@example.com", + PasswordHash: "hash", + } + user.Create() + + err := db.Transaction(func(tx *gorm.DB) error { + user.Role = "admin" + return tx.Save(user).Error + }) + + if err != nil { + t.Fatalf("Transaction failed: %v", err) + } + + updated, _ := models.GetUserByID(user.ID) + if updated.Role != "admin" { + t.Error("role should be updated within transaction") + } +} + +func TestTransaction_Rollback(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "rollbackuser", + Email: "rollback@example.com", + PasswordHash: "hash", + } + user.Create() + + originalRole := user.Role + + err := db.Transaction(func(tx *gorm.DB) error { + user.Role = "admin" + if err := tx.Save(user).Error; err != nil { + return err + } + return fmt.Errorf("force rollback") + }) + + if err == nil { + t.Error("transaction should fail") + } + + updated, _ := models.GetUserByID(user.ID) + if updated.Role != originalRole { + t.Error("changes should be rolled back") + } +} + +func TestSoftDelete(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "softdeleteuser", + Email: "softdelete@example.com", + PasswordHash: "hash", + } + user.Create() + + db.Delete(user) + + var count int64 + db.Model(&models.User{}).Where("id = ?", user.ID).Count(&count) + if count != 0 { + t.Error("soft deleted user should not be found with regular query") + } + + var deleted models.User + db.Unscoped().Where("id = ?", user.ID).First(&deleted) + if deleted.ID != user.ID { + t.Error("soft deleted user should be retrievable with Unscoped") + } +} + +func TestConcurrentWrites(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "concurrentuser", + Email: "concurrent@example.com", + PasswordHash: "hash", + } + user.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Concurrent Project", + OwnerID: user.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Concurrent App", + CreatedBy: user.ID, + } + app.InsertInDB() + + results := make(chan error, 10) + + for i := 0; i < 10; i++ { + go func(idx int) { + deployment := &models.Deployment{ + ID: utils.GenerateRandomId(), + AppID: app.ID, + CommitHash: fmt.Sprintf("commit%d", idx), + } + results <- deployment.CreateDeployment() + }(i) + } + + for i := 0; i < 10; i++ { + if err := <-results; err != nil { + t.Errorf("concurrent write failed: %v", err) + } + } + + deployments, _ := models.GetDeploymentsByAppID(app.ID) + if len(deployments) != 10 { + t.Error("all concurrent deployments should be created") + } +} + +func TestBoundaryValues(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "boundaryuser", + Email: "boundary@example.com", + PasswordHash: "hash", + } + user.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Boundary Project", + OwnerID: user.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Boundary App", + CreatedBy: user.ID, + CPULimit: float64Ptr(0.0), + MemoryLimit: intPtr(0), + } + app.InsertInDB() + + retrieved, _ := models.GetApplicationByID(app.ID) + if retrieved.CPULimit != nil && *retrieved.CPULimit != 0.0 { + t.Error("zero CPU limit should be preserved") + } + if retrieved.MemoryLimit != nil && *retrieved.MemoryLimit != 0 { + t.Error("zero memory limit should be preserved") + } +} + +func float64Ptr(f float64) *float64 { + return &f +} + +func intPtr(i int) *int { + return &i +} + +func TestLargePayload(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "largeuser", + Email: "large@example.com", + PasswordHash: "hash", + } + user.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Large Project", + OwnerID: user.ID, + Tags: make([]string, 100), + } + for i := range project.Tags { + project.Tags[i] = fmt.Sprintf("tag%d", i) + } + project.InsertInDB() + + retrieved, _ := models.GetProjectByID(project.ID) + if len(retrieved.Tags) != 100 { + t.Error("all tags should be stored and retrieved") + } +} + +func TestNullFields(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "nulluser", + Email: "null@example.com", + PasswordHash: "hash", + FullName: nil, + AvatarURL: nil, + Bio: nil, + } + user.Create() + + retrieved, _ := models.GetUserByID(user.ID) + if retrieved.FullName != nil { + t.Error("nil FullName should remain nil") + } + if retrieved.AvatarURL != nil { + t.Error("nil AvatarURL should remain nil") + } + if retrieved.Bio != nil { + t.Error("nil Bio should remain nil") + } +} + +func TestRelatedRecordsCascade(t *testing.T) { + db := setupTestDB(t) + defer cleanupDB(db) + + user := &models.User{ + ID: utils.GenerateRandomId(), + Username: "cascadeuser", + Email: "cascade@example.com", + PasswordHash: "hash", + } + user.Create() + + project := &models.Project{ + ID: utils.GenerateRandomId(), + Name: "Cascade Project", + OwnerID: user.ID, + } + project.InsertInDB() + + app := &models.App{ + ProjectID: project.ID, + Name: "Cascade App", + CreatedBy: user.ID, + } + app.InsertInDB() + + models.CreateDomain(app.ID, "cascade.example.com") + models.CreateVolume(app.ID, "data", "/host", "/container", false) + + var envCount, domainCount, volumeCount int64 + db.Model(&models.EnvVariable{}).Where("app_id = ?", app.ID).Count(&envCount) + db.Model(&models.Domain{}).Where("app_id = ?", app.ID).Count(&domainCount) + db.Model(&models.Volume{}).Where("app_id = ?", app.ID).Count(&volumeCount) + + if envCount != 0 || domainCount != 1 || volumeCount != 1 { + t.Error("related records should be created") + } + + models.DeleteApplication(app.ID) + + var appCount int64 + db.Model(&models.App{}).Where("id = ?", app.ID).Count(&appCount) + if appCount != 0 { + t.Error("app should be deleted") + } + +} diff --git a/test/go.mod b/test/go.mod index 9503784..d8929e6 100644 --- a/test/go.mod +++ b/test/go.mod @@ -5,51 +5,24 @@ go 1.25.1 replace github.com/corecollectives/mist => ../server require ( - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/ProtonMail/go-crypto v1.3.0 // indirect - github.com/cloudflare/circl v1.6.1 // indirect - github.com/containerd/errdefs v1.0.0 // indirect - github.com/containerd/errdefs/pkg v0.3.0 // indirect - github.com/corecollectives/mist v0.0.0 // indirect - github.com/cyphar/filepath-securejoin v0.6.1 // indirect - github.com/distribution/reference v0.6.0 // indirect - github.com/docker/go-connections v0.6.0 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/emirpasic/gods v1.18.1 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-git/gcfg/v2 v2.0.2 // indirect - github.com/go-git/go-billy/v6 v6.0.0-20251217170237-e9738f50a3cd // indirect - github.com/go-git/go-git/v6 v6.0.0-20251231065035-29ae690a9f19 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/corecollectives/mist v0.0.0 + gorm.io/driver/sqlite v1.6.0 + gorm.io/gorm v1.31.1 +) + +require ( github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect - github.com/gorilla/websocket v1.5.3 // indirect - github.com/kevinburke/ssh_config v1.4.0 // indirect - github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-sqlite3 v1.14.32 // indirect - github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/moby/api v1.52.0 // indirect - github.com/moby/moby/client v0.2.1 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/pjbgf/sha1cd v0.5.0 // indirect + github.com/mattn/go-sqlite3 v1.14.33 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rs/zerolog v1.34.0 // indirect - github.com/sergi/go-diff v1.4.0 // indirect - github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect - github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect - go.opentelemetry.io/otel v1.35.0 // indirect - go.opentelemetry.io/otel/metric v1.35.0 // indirect - go.opentelemetry.io/otel/trace v1.35.0 // indirect golang.org/x/crypto v0.46.0 // indirect - golang.org/x/net v0.48.0 // indirect golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.33.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/test/go.sum b/test/go.sum index 7ddb3ac..1b6c656 100644 --- a/test/go.sum +++ b/test/go.sum @@ -1,114 +1,49 @@ -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= -github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= -github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= -github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= -github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= -github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= -github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= -github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= -github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= -github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= -github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= -github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/go-git/gcfg/v2 v2.0.2 h1:MY5SIIfTGGEMhdA7d7JePuVVxtKL7Hp+ApGDJAJ7dpo= -github.com/go-git/gcfg/v2 v2.0.2/go.mod h1:/lv2NsxvhepuMrldsFilrgct6pxzpGdSRC13ydTLSLs= -github.com/go-git/go-billy/v6 v6.0.0-20251217170237-e9738f50a3cd h1:Gd/f9cGi/3h1JOPaa6er+CkKUGyGX2DBJdFbDKVO+R0= -github.com/go-git/go-billy/v6 v6.0.0-20251217170237-e9738f50a3cd/go.mod h1:d3XQcsHu1idnquxt48kAv+h+1MUiYKLH/e7LAzjP+pI= -github.com/go-git/go-git/v6 v6.0.0-20251231065035-29ae690a9f19 h1:0lz2eJScP8v5YZQsrEw+ggWC5jNySjg4bIZo5BIh6iI= -github.com/go-git/go-git/v6 v6.0.0-20251231065035-29ae690a9f19/go.mod h1:L+Evfcs7EdTqxwv854354cb6+++7TFL3hJn3Wy4g+3w= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= -github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= -github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/kevinburke/ssh_config v1.4.0 h1:6xxtP5bZ2E4NF5tuQulISpTO2z8XbtH8cg1PWkxoFkQ= -github.com/kevinburke/ssh_config v1.4.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= -github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= -github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= -github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= -github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= -github.com/moby/moby/client v0.2.1 h1:1Grh1552mvv6i+sYOdY+xKKVTvzJegcVMhuXocyDz/k= -github.com/moby/moby/client v0.2.1/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= -github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0= -github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= +github.com/mattn/go-sqlite3 v1.14.33 h1:A5blZ5ulQo2AtayQ9/limgHEkFreKj1Dv226a1K73s0= +github.com/mattn/go-sqlite3 v1.14.33/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= -github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= -github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= -github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= -github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= -github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= -go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= -go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= -go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= -go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= -go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= -go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= +gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= +gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg= +gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= diff --git a/test/main.go b/test/main.go deleted file mode 100644 index 56e5404..0000000 --- a/test/main.go +++ /dev/null @@ -1 +0,0 @@ -package test From c6c03826586a6ae345d8f7872ff4e225bb2231ad Mon Sep 17 00:00:00 2001 From: 07calc Date: Sun, 18 Jan 2026 21:26:04 +0530 Subject: [PATCH 28/48] chore: tests CI --- .github/workflows/tests.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..e561fb3 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,23 @@ +name: Tests + +on: + pull_request: + push: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.22' + + - name: Run all tests + working-directory: test + run: go test -v ./... From 440e8e1476f65f4000e0aed901655c231a9cfa21 Mon Sep 17 00:00:00 2001 From: 07calc Date: Sun, 18 Jan 2026 21:29:25 +0530 Subject: [PATCH 29/48] chore: test path --- .github/workflows/tests.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e561fb3..61db259 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -2,9 +2,16 @@ name: Tests on: pull_request: + paths: + - "test/**" + - "server/**" + push: branches: - main + paths: + - "test/**" + - "server/**" jobs: build: From fe7f02d98555f3adcfb2f7c2e419803dc2144f0d Mon Sep 17 00:00:00 2001 From: 07calc Date: Sun, 18 Jan 2026 21:31:01 +0530 Subject: [PATCH 30/48] chore: frontend build check --- .github/workflows/pr-build-check.yml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/workflows/pr-build-check.yml b/.github/workflows/pr-build-check.yml index 7697afd..e98e6ff 100644 --- a/.github/workflows/pr-build-check.yml +++ b/.github/workflows/pr-build-check.yml @@ -1,10 +1,15 @@ -name: PR Build Check +name: Frontend build check on: pull_request: + paths: + - "dash/**" + push: branches: - main + paths: + - "dash/**" jobs: build: @@ -23,12 +28,3 @@ jobs: - name: Build frontend working-directory: dash run: bun run build - - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: '1.22' - - - name: Build server - working-directory: server - run: go build ./... From 8a0284300e0a3f1d8da728f4c585e55dc056ea47 Mon Sep 17 00:00:00 2001 From: 07calc Date: Sun, 18 Jan 2026 21:32:20 +0530 Subject: [PATCH 31/48] chore: test badge in readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f7568b0..5aaed4a 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ A lightweight, self-hostable Platform-as-a-Service built for developers. Deploy Docker applications from Git with automatic builds, custom domains, SSL certificates, and real-time monitoring. [![PR Build Check](https://github.com/corecollectives/Mist/actions/workflows/pr-build-check.yml/badge.svg)](https://github.com/corecollectives/Mist/actions/workflows/pr-build-check.yml) +[![Tests](https://github.com/corecollectives/Mist/actions/workflows/tests.yml/badge.svg)](https://github.com/corecollectives/Mist/actions/workflows/tests.yml) ## Quick Start From 5f3ab79618cbc852f5197b50aa4fe1b9553395a5 Mon Sep 17 00:00:00 2001 From: 07calc Date: Sun, 18 Jan 2026 21:39:59 +0530 Subject: [PATCH 32/48] www: added sitemap --- www/docs/.vitepress/config.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/www/docs/.vitepress/config.js b/www/docs/.vitepress/config.js index 78fd872..00df399 100644 --- a/www/docs/.vitepress/config.js +++ b/www/docs/.vitepress/config.js @@ -1,12 +1,16 @@ import { defineConfig } from 'vitepress' export default defineConfig({ + title: 'Mist', description: 'Self-hostable Platform-as-a-Service', base: '/', head: [ ['link', { rel: 'icon', type: 'image/png', href: '/mist.png' }] ], + sitemap: { + hostname: 'https://trymist.cloud' + }, themeConfig: { logo: '/mist.png', From b032c2b8e86f145d461e2889eed5049d14b5bce2 Mon Sep 17 00:00:00 2001 From: Tanish Date: Mon, 19 Jan 2026 19:56:40 +0530 Subject: [PATCH 33/48] added stopDeployment handler --- .../handlers/deployments/stopDeployment.go | 37 +++++++++++++++++++ server/docker/image.go | 2 + 2 files changed, 39 insertions(+) create mode 100644 server/api/handlers/deployments/stopDeployment.go diff --git a/server/api/handlers/deployments/stopDeployment.go b/server/api/handlers/deployments/stopDeployment.go new file mode 100644 index 0000000..8c0a6b8 --- /dev/null +++ b/server/api/handlers/deployments/stopDeployment.go @@ -0,0 +1,37 @@ +package deployments + +import ( + "encoding/json" + "net/http" + + "github.com/corecollectives/mist/api/handlers" + "github.com/corecollectives/mist/models" +) + +type stopDeployment struct { + DeploymentID int64 `json:"deploymentId"` +} + +func StopDeployment(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + handlers.SendResponse(w, http.StatusMethodNotAllowed, false, nil, "Method not allowed", "Only POST method is allowed") + return + } + var req stopDeployment + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + handlers.SendResponse(w, http.StatusBadRequest, false, nil, "Invalid request body", "Could not parse JSON") + return + } + + deployment, err := models.GetDeploymentByID(req.DeploymentID) + if err != nil { + handlers.SendResponse(w, http.StatusInternalServerError, false, nil, "Failed to get deployment details", err.Error()) + return + } + err = models.UpdateDeploymentStatus(req.DeploymentID, "stopped", "pending", deployment.Progress, deployment.ErrorMessage) + if err != nil { + handlers.SendResponse(w, http.StatusInternalServerError, false, nil, "Failed to stop deployment", err.Error()) + return + } + handlers.SendResponse(w, http.StatusOK, true, nil, "Deployment stopped successfully", "") +} diff --git a/server/docker/image.go b/server/docker/image.go index cff75f9..0a00fec 100644 --- a/server/docker/image.go +++ b/server/docker/image.go @@ -55,6 +55,8 @@ func BuildImage(imageTag, contextPath string, envVars map[string]string, logfile } return nil + + // legacy exec method // // From c26de867a1bafdaf5742aff5322780017b6ab3b4 Mon Sep 17 00:00:00 2001 From: Tanish Date: Mon, 19 Jan 2026 20:32:02 +0530 Subject: [PATCH 34/48] added getDeploymentStatus function --- server/models/deployment.go | 14 ++++++++++++++ server/queue/deployQueue.go | 1 + 2 files changed, 15 insertions(+) diff --git a/server/models/deployment.go b/server/models/deployment.go index d02fadb..1e2fe7d 100644 --- a/server/models/deployment.go +++ b/server/models/deployment.go @@ -207,6 +207,20 @@ func UpdateContainerInfo(depID int64, containerID, containerName, imageTag strin return db.Model(&Deployment{}).Where("id = ?", depID).Updates(updates).Error } +func GetDeploymentStatus(depID int64) (string, error) { + var status string + result := db.Model(&Deployment{}).Select("status").Where("id = ?", depID).Scan(&status) + if result.Error != nil { + return "", result.Error + } + + if result.RowsAffected == 0 { + return "", gorm.ErrRecordNotFound + } + + return status, nil +} + //############################################################################################################# //ARCHIVED CODE BELOW------> diff --git a/server/queue/deployQueue.go b/server/queue/deployQueue.go index 15d1c8d..523b34a 100644 --- a/server/queue/deployQueue.go +++ b/server/queue/deployQueue.go @@ -41,6 +41,7 @@ func (q *Queue) StartWorker(db *gorm.DB) { go func() { defer q.wg.Done() for id := range q.jobs { + q.HandleWork(id, db) } From 17834a1a385048f537b7914b2d8dc5c92402972f Mon Sep 17 00:00:00 2001 From: Tanish Date: Mon, 19 Jan 2026 23:46:43 +0530 Subject: [PATCH 35/48] added a way to stop ongoing deployments --- server/api/RegisterRoutes.go | 1 + .../handlers/deployments/stopDeployment.go | 9 +++++- server/docker/container.go | 10 +++--- server/docker/deployer.go | 19 ++++++++--- server/docker/deployerMain.go | 5 +-- server/docker/image.go | 24 ++++++++------ server/git/clone.go | 5 +-- server/github/cloneRepo.go | 6 ++-- server/queue/ctxManager.go | 32 +++++++++++++++++++ server/queue/deployQueue.go | 11 ++++++- server/queue/handleWork.go | 10 ++++-- 11 files changed, 101 insertions(+), 31 deletions(-) create mode 100644 server/queue/ctxManager.go diff --git a/server/api/RegisterRoutes.go b/server/api/RegisterRoutes.go index a3ab4f4..c4a5d22 100644 --- a/server/api/RegisterRoutes.go +++ b/server/api/RegisterRoutes.go @@ -96,6 +96,7 @@ func RegisterRoutes(mux *http.ServeMux) { mux.Handle("POST /api/deployments/create", middleware.AuthMiddleware()(http.HandlerFunc(deployments.AddDeployHandler))) mux.Handle("POST /api/deployments/getByAppId", middleware.AuthMiddleware()(http.HandlerFunc(deployments.GetByApplicationID))) mux.Handle("GET /api/deployments/logs", middleware.AuthMiddleware()(http.HandlerFunc(deployments.GetCompletedDeploymentLogsHandler))) + mux.Handle("POST /api/deployments/stopDep", middleware.AuthMiddleware()(http.HandlerFunc(deployments.StopDeployment))) mux.Handle("GET /api/templates/list", middleware.AuthMiddleware()(http.HandlerFunc(templates.ListServiceTemplates))) mux.Handle("GET /api/templates/get", middleware.AuthMiddleware()(http.HandlerFunc(templates.GetServiceTemplateByName))) diff --git a/server/api/handlers/deployments/stopDeployment.go b/server/api/handlers/deployments/stopDeployment.go index 8c0a6b8..61115f6 100644 --- a/server/api/handlers/deployments/stopDeployment.go +++ b/server/api/handlers/deployments/stopDeployment.go @@ -6,6 +6,7 @@ import ( "github.com/corecollectives/mist/api/handlers" "github.com/corecollectives/mist/models" + "github.com/corecollectives/mist/queue" ) type stopDeployment struct { @@ -33,5 +34,11 @@ func StopDeployment(w http.ResponseWriter, r *http.Request) { handlers.SendResponse(w, http.StatusInternalServerError, false, nil, "Failed to stop deployment", err.Error()) return } - handlers.SendResponse(w, http.StatusOK, true, nil, "Deployment stopped successfully", "") + wasRunning := queue.Cancel(req.DeploymentID) + message := "Deployment marked as stopped" + if wasRunning { + message = "Deployment aborted immediately" + } + + handlers.SendResponse(w, http.StatusOK, true, nil, message, "") } diff --git a/server/docker/container.go b/server/docker/container.go index 5b9a948..1e3f9ed 100644 --- a/server/docker/container.go +++ b/server/docker/container.go @@ -253,9 +253,9 @@ func ContainerExists(name string) bool { // return true } -func RunContainer(app *models.App, imageTag, containerName string, domains []string, Port int, envVars map[string]string, logfile *os.File) error { +func RunContainer(ctx context.Context, app *models.App, imageTag, containerName string, domains []string, Port int, envVars map[string]string, logfile *os.File) error { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + timeoutCtx, cancel := context.WithTimeout(ctx, 5*time.Minute) defer cancel() cli, err := client.New(client.FromEnv) @@ -388,7 +388,7 @@ func RunContainer(app *models.App, imageTag, containerName string, domains []str hostConfig.Resources.Memory = int64(*app.MemoryLimit) * 1024 * 1024 } - resp, err := cli.ContainerCreate(ctx, client.ContainerCreateOptions{ + resp, err := cli.ContainerCreate(timeoutCtx, client.ContainerCreateOptions{ Name: containerName, Config: &config, HostConfig: &hostConfig, @@ -397,7 +397,7 @@ func RunContainer(app *models.App, imageTag, containerName string, domains []str return fmt.Errorf("failed to create container: %w", err) } - _, err = cli.ContainerStart(ctx, resp.ID, client.ContainerStartOptions{}) + _, err = cli.ContainerStart(timeoutCtx, resp.ID, client.ContainerStartOptions{}) if err != nil { return fmt.Errorf("failed to start container: %w", err) } @@ -661,7 +661,7 @@ func RecreateContainer(app *models.App) error { return fmt.Errorf("failed to stop/remove container: %w", err) } - if err := RunContainer(app, imageTag, containerName, domains, port, envVars, nil); err != nil { + if err := RunContainer(ctx, app, imageTag, containerName, domains, port, envVars, nil); err != nil { return fmt.Errorf("failed to run container: %w", err) } diff --git a/server/docker/deployer.go b/server/docker/deployer.go index 2f34af5..06aaf51 100644 --- a/server/docker/deployer.go +++ b/server/docker/deployer.go @@ -1,6 +1,7 @@ package docker import ( + "context" "encoding/json" "fmt" "os" @@ -14,7 +15,7 @@ import ( "gorm.io/gorm" ) -func DeployApp(dep *models.Deployment, app *models.App, appContextPath, imageTag, containerName string, db *gorm.DB, logfile *os.File, logger *utils.DeploymentLogger) error { +func DeployApp(ctx context.Context, dep *models.Deployment, app *models.App, appContextPath, imageTag, containerName string, db *gorm.DB, logfile *os.File, logger *utils.DeploymentLogger) error { logger.Info("Starting deployment process") @@ -94,7 +95,11 @@ func DeployApp(dep *models.Deployment, app *models.App, appContextPath, imageTag "image": imageName, }) - if err := PullDockerImage(imageName, logfile); err != nil { + if err := PullDockerImage(ctx, imageName, logfile); err != nil { + if ctx.Err() == context.Canceled { + logger.Info("Docker image pull canceled") + return ctx.Err() + } logger.Error(err, "Docker image pull failed") dep.Status = "failed" dep.Stage = "failed" @@ -118,7 +123,11 @@ func DeployApp(dep *models.Deployment, app *models.App, appContextPath, imageTag models.UpdateDeploymentStatus(dep.ID, "building", "building", 50, nil) logger.Info("Building Docker image with environment variables") - if err := BuildImage(imageTag, appContextPath, envVars, logfile); err != nil { + if err := BuildImage(ctx, imageTag, appContextPath, envVars, logfile); err != nil { + if ctx.Err() == context.Canceled { + logger.Info("Docker image build canceled") + return ctx.Err() + } logger.Error(err, "Docker image build failed") dep.Status = "failed" dep.Stage = "failed" @@ -141,7 +150,7 @@ func DeployApp(dep *models.Deployment, app *models.App, appContextPath, imageTag models.UpdateDeploymentStatus(dep.ID, "deploying", "deploying", 80, nil) logger.Info("Stopping existing container if exists") - err = StopRemoveContainer(containerName, logfile) + err = StopRemoveContainer( containerName, logfile) if err != nil { logger.Error(err, "Failed to stop/remove existing container") dep.Status = "failed" @@ -162,7 +171,7 @@ func DeployApp(dep *models.Deployment, app *models.App, appContextPath, imageTag "appType": app.AppType, }) - if err := RunContainer(app, imageTag, containerName, domains, port, envVars, logfile); err != nil { + if err := RunContainer(ctx, app, imageTag, containerName, domains, port, envVars, logfile); err != nil { logger.Error(err, "Failed to run container") dep.Status = "failed" dep.Stage = "failed" diff --git a/server/docker/deployerMain.go b/server/docker/deployerMain.go index 1300316..7b89e37 100644 --- a/server/docker/deployerMain.go +++ b/server/docker/deployerMain.go @@ -1,6 +1,7 @@ package docker import ( + "context" "fmt" "os" "path/filepath" @@ -11,7 +12,7 @@ import ( "gorm.io/gorm" ) -func DeployerMain(Id int64, db *gorm.DB, logFile *os.File, logger *utils.DeploymentLogger) (string, error) { +func DeployerMain(ctx context.Context, Id int64, db *gorm.DB, logFile *os.File, logger *utils.DeploymentLogger) (string, error) { dep, err := LoadDeployment(Id, db) if err != nil { logger.Error(err, "Failed to load deployment") @@ -44,7 +45,7 @@ func DeployerMain(Id int64, db *gorm.DB, logFile *os.File, logger *utils.Deploym imageTag := dep.CommitHash containerName := fmt.Sprintf("app-%d", app.ID) - err = DeployApp(dep, &app, appContextPath, imageTag, containerName, db, logFile, logger) + err = DeployApp(ctx, dep, &app, appContextPath, imageTag, containerName, db, logFile, logger) if err != nil { logger.Error(err, "DeployApp failed") dep.Status = "failed" diff --git a/server/docker/image.go b/server/docker/image.go index 0a00fec..4420db9 100644 --- a/server/docker/image.go +++ b/server/docker/image.go @@ -12,8 +12,8 @@ import ( "github.com/rs/zerolog/log" ) -func BuildImage(imageTag, contextPath string, envVars map[string]string, logfile *os.File) error { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) +func BuildImage(ctx context.Context, imageTag, contextPath string, envVars map[string]string, logfile *os.File) error { + timeoutCtx, cancel := context.WithTimeout(ctx, 15*time.Minute) defer cancel() cli, err := client.New(client.FromEnv) if err != nil { @@ -41,11 +41,14 @@ func BuildImage(imageTag, contextPath string, envVars map[string]string, logfile log.Info().Str("image_tag", imageTag).Msg("Building Docker image") - resp, err := cli.ImageBuild(ctx, buildCtx, buildOptions) + resp, err := cli.ImageBuild(timeoutCtx, buildCtx, buildOptions) if err != nil { - if ctx.Err() == context.DeadlineExceeded { + if timeoutCtx.Err() == context.DeadlineExceeded { return fmt.Errorf("image build timed out after 15 minutes") } + if timeoutCtx.Err() == context.Canceled { + return context.Canceled + } return err } defer resp.Body.Close() @@ -55,8 +58,6 @@ func BuildImage(imageTag, contextPath string, envVars map[string]string, logfile } return nil - - // legacy exec method // // @@ -90,8 +91,8 @@ func BuildImage(imageTag, contextPath string, envVars map[string]string, logfile // return nil } -func PullDockerImage(imageName string, logfile *os.File) error { - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) +func PullDockerImage(ctx context.Context, imageName string, logfile *os.File) error { + timeoutCtx, cancel := context.WithTimeout(ctx, 15*time.Minute) defer cancel() cli, err := client.New(client.FromEnv) @@ -100,11 +101,14 @@ func PullDockerImage(imageName string, logfile *os.File) error { } log.Debug().Str("image_name", imageName).Msg("pulling image") - resp, err := cli.ImagePull(ctx, imageName, client.ImagePullOptions{}) + resp, err := cli.ImagePull(timeoutCtx, imageName, client.ImagePullOptions{}) if err != nil { - if ctx.Err() == context.DeadlineExceeded { + if timeoutCtx.Err() == context.DeadlineExceeded { return fmt.Errorf("image pull timed out after 15 minutes") } + if timeoutCtx.Err() == context.Canceled { + return context.Canceled + } return err } defer resp.Close() diff --git a/server/git/clone.go b/server/git/clone.go index 1ccaed7..6331113 100644 --- a/server/git/clone.go +++ b/server/git/clone.go @@ -1,6 +1,7 @@ package git import ( + "context" "fmt" "os" @@ -9,12 +10,12 @@ import ( "github.com/rs/zerolog/log" ) -func CloneRepo(url string, branch string, logFile *os.File, path string) error { +func CloneRepo(ctx context.Context, url string, branch string, logFile *os.File, path string) error { _, err := fmt.Fprintf(logFile, "[GIT]: Cloning into %s\n", path) if err != nil { log.Warn().Msg("error logging into log file") } - _, err = git.PlainClone(path, &git.CloneOptions{ + _, err = git.PlainCloneContext(ctx, path, &git.CloneOptions{ URL: url, // Progress: logFile, ReferenceName: plumbing.NewBranchReferenceName(branch), diff --git a/server/github/cloneRepo.go b/server/github/cloneRepo.go index 9a6f5f0..19f0019 100644 --- a/server/github/cloneRepo.go +++ b/server/github/cloneRepo.go @@ -11,7 +11,7 @@ import ( "github.com/rs/zerolog/log" ) -func CloneRepo(appId int64, logFile *os.File) error { +func CloneRepo(ctx context.Context, appId int64, logFile *os.File) error { log.Info().Int64("app_id", appId).Msg("Starting repository clone") userId, err := models.GetUserIDByAppID(appId) @@ -71,7 +71,7 @@ func CloneRepo(appId int64, logFile *os.File) error { log.Info().Str("clone_url", cloneURL).Str("branch", branch).Str("path", path).Msg("Cloning repository") - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) + ctx, cancel := context.WithTimeout(ctx, 10*time.Minute) defer cancel() // old command implementation @@ -87,7 +87,7 @@ func CloneRepo(appId int64, logFile *os.File) error { // } // new git sdk implementation - err = git.CloneRepo(repoURL, branch, logFile, path) + err = git.CloneRepo(ctx, repoURL, branch, logFile, path) if err != nil { if ctx.Err() == context.DeadlineExceeded { return fmt.Errorf("git clone timed out after 10 minutes") diff --git a/server/queue/ctxManager.go b/server/queue/ctxManager.go new file mode 100644 index 0000000..ae7c2af --- /dev/null +++ b/server/queue/ctxManager.go @@ -0,0 +1,32 @@ +package queue + +import ( + "context" + "sync" +) + +var activeDeployments = make(map[int64]context.CancelFunc) +var mu sync.Mutex + +func Register(id int64, cancel context.CancelFunc) { + mu.Lock() + defer mu.Unlock() + activeDeployments[id] = cancel +} + +func Unregister(id int64) { + mu.Lock() + defer mu.Unlock() + delete(activeDeployments, id) +} + +func Cancel(id int64) bool { + mu.Lock() + defer mu.Unlock() + if cancel, exists := activeDeployments[id]; exists { + cancel() + delete(activeDeployments, id) + return true + } + return false +} diff --git a/server/queue/deployQueue.go b/server/queue/deployQueue.go index 523b34a..994f1f7 100644 --- a/server/queue/deployQueue.go +++ b/server/queue/deployQueue.go @@ -5,6 +5,7 @@ import ( "fmt" "sync" + "github.com/corecollectives/mist/models" "github.com/rs/zerolog/log" "gorm.io/gorm" ) @@ -41,7 +42,15 @@ func (q *Queue) StartWorker(db *gorm.DB) { go func() { defer q.wg.Done() for id := range q.jobs { - + status, err := models.GetDeploymentStatus(id) + if err != nil { + log.Error().Err(err).Msg("Failed to get deployment status") + continue + } + if status == "stopped" { + log.Info().Msgf("Deployment %d has been stopped before processing, skipping", id) + continue + } q.HandleWork(id, db) } diff --git a/server/queue/handleWork.go b/server/queue/handleWork.go index 3b09c8c..b2f91d6 100644 --- a/server/queue/handleWork.go +++ b/server/queue/handleWork.go @@ -1,6 +1,7 @@ package queue import ( + "context" "fmt" "sync" @@ -27,6 +28,11 @@ func (q *Queue) HandleWork(id int64, db *gorm.DB) { } }() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + Register(id, cancel) + defer Unregister(id) + appId, err := models.GetAppIDByDeploymentID(id) if err != nil { errMsg := fmt.Sprintf("Failed to get app ID: %v", err) @@ -79,7 +85,7 @@ func (q *Queue) HandleWork(id int64, db *gorm.DB) { logger.Info("Cloning repository") models.UpdateDeploymentStatus(id, "cloning", "cloning", 20, nil) - err = github.CloneRepo(appId, logFile) + err = github.CloneRepo(ctx, appId, logFile) if err != nil { logger.Error(err, "Failed to clone repository") errMsg := fmt.Sprintf("Failed to clone repository: %v", err) @@ -92,7 +98,7 @@ func (q *Queue) HandleWork(id int64, db *gorm.DB) { logger.Info("Skipping git clone for database app") } - _, err = docker.DeployerMain(id, db, logFile, logger) + _, err = docker.DeployerMain(ctx, id, db, logFile, logger) if err != nil { logger.Error(err, "Deployment failed") errMsg := fmt.Sprintf("Deployment failed: %v", err) From c54a9085c2ddfb0241c244b12985f9fddc7c1efa Mon Sep 17 00:00:00 2001 From: 07calc Date: Mon, 19 Jan 2026 23:53:01 +0530 Subject: [PATCH 36/48] chore: remove www (moving to submodule) --- www/README.md | 151 - www/bun.lock | 354 - www/docs/.vitepress/cache/deps/_metadata.json | 52 - .../.vitepress/cache/deps/chunk-2CLQ7TTZ.js | 9719 ------------ .../cache/deps/chunk-2CLQ7TTZ.js.map | 7 - .../.vitepress/cache/deps/chunk-LE5NDSFD.js | 12824 ---------------- .../cache/deps/chunk-LE5NDSFD.js.map | 7 - www/docs/.vitepress/cache/deps/package.json | 3 - .../deps/vitepress___@vue_devtools-api.js | 4505 ------ .../deps/vitepress___@vue_devtools-api.js.map | 7 - .../cache/deps/vitepress___@vueuse_core.js | 583 - .../deps/vitepress___@vueuse_core.js.map | 7 - ...ess___@vueuse_integrations_useFocusTrap.js | 1165 -- ...__@vueuse_integrations_useFocusTrap.js.map | 7 - .../vitepress___mark__js_src_vanilla__js.js | 1665 -- ...itepress___mark__js_src_vanilla__js.js.map | 7 - .../cache/deps/vitepress___minisearch.js | 1813 --- .../cache/deps/vitepress___minisearch.js.map | 7 - www/docs/.vitepress/cache/deps/vue.js | 347 - www/docs/.vitepress/cache/deps/vue.js.map | 7 - www/docs/.vitepress/config.js | 142 - www/docs/.vitepress/theme/Layout.vue | 14 - .../theme/components/HeroInstall.vue | 196 - .../theme/components/NavBarVersion.vue | 182 - www/docs/.vitepress/theme/custom.css | 1038 -- www/docs/.vitepress/theme/index.js | 14 - www/docs/api/applications.md | 366 - www/docs/api/authentication.md | 58 - www/docs/api/deployments.md | 240 - www/docs/api/domains.md | 39 - www/docs/api/environment-variables.md | 109 - www/docs/api/github.md | 38 - www/docs/api/overview.md | 151 - www/docs/api/projects.md | 54 - www/docs/api/users.md | 39 - www/docs/api/websockets.md | 327 - www/docs/deployment/backup.md | 527 - www/docs/deployment/configuration.md | 120 - www/docs/deployment/github-app.md | 363 - www/docs/deployment/installation.md | 430 - www/docs/deployment/requirements.md | 192 - www/docs/deployment/security.md | 686 - www/docs/deployment/traefik.md | 318 - www/docs/deployment/upgrading.md | 469 - www/docs/guide/applications.md | 720 - www/docs/guide/architecture.md | 337 - www/docs/guide/audit-logs.md | 74 - www/docs/guide/authentication.md | 198 - www/docs/guide/cli.md | 260 - www/docs/guide/databases.md | 232 - www/docs/guide/deployments.md | 118 - www/docs/guide/domains.md | 188 - www/docs/guide/environment-variables.md | 279 - www/docs/guide/getting-started.md | 162 - www/docs/guide/git-integration.md | 98 - www/docs/guide/logs.md | 132 - www/docs/guide/metrics.md | 52 - www/docs/guide/notifications.md | 84 - www/docs/guide/projects.md | 82 - www/docs/guide/rollback.md | 60 - www/docs/guide/ssl-automation.md | 191 - www/docs/guide/users.md | 167 - www/docs/guide/what-is-mist.md | 146 - www/docs/index.md | 187 - www/docs/public/install.sh | 274 - www/docs/public/mist.png | Bin 58009 -> 0 bytes www/docs/troubleshooting/forgot-password.md | 381 - www/docs/troubleshooting/index.md | 645 - www/docs/troubleshooting/manual-update.md | 628 - www/package-lock.json | 2475 --- www/package.json | 18 - 71 files changed, 47537 deletions(-) delete mode 100644 www/README.md delete mode 100644 www/bun.lock delete mode 100644 www/docs/.vitepress/cache/deps/_metadata.json delete mode 100644 www/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js delete mode 100644 www/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js.map delete mode 100644 www/docs/.vitepress/cache/deps/chunk-LE5NDSFD.js delete mode 100644 www/docs/.vitepress/cache/deps/chunk-LE5NDSFD.js.map delete mode 100644 www/docs/.vitepress/cache/deps/package.json delete mode 100644 www/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js delete mode 100644 www/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map delete mode 100644 www/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js delete mode 100644 www/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map delete mode 100644 www/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js delete mode 100644 www/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map delete mode 100644 www/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js delete mode 100644 www/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map delete mode 100644 www/docs/.vitepress/cache/deps/vitepress___minisearch.js delete mode 100644 www/docs/.vitepress/cache/deps/vitepress___minisearch.js.map delete mode 100644 www/docs/.vitepress/cache/deps/vue.js delete mode 100644 www/docs/.vitepress/cache/deps/vue.js.map delete mode 100644 www/docs/.vitepress/config.js delete mode 100644 www/docs/.vitepress/theme/Layout.vue delete mode 100644 www/docs/.vitepress/theme/components/HeroInstall.vue delete mode 100644 www/docs/.vitepress/theme/components/NavBarVersion.vue delete mode 100644 www/docs/.vitepress/theme/custom.css delete mode 100644 www/docs/.vitepress/theme/index.js delete mode 100644 www/docs/api/applications.md delete mode 100644 www/docs/api/authentication.md delete mode 100644 www/docs/api/deployments.md delete mode 100644 www/docs/api/domains.md delete mode 100644 www/docs/api/environment-variables.md delete mode 100644 www/docs/api/github.md delete mode 100644 www/docs/api/overview.md delete mode 100644 www/docs/api/projects.md delete mode 100644 www/docs/api/users.md delete mode 100644 www/docs/api/websockets.md delete mode 100644 www/docs/deployment/backup.md delete mode 100644 www/docs/deployment/configuration.md delete mode 100644 www/docs/deployment/github-app.md delete mode 100644 www/docs/deployment/installation.md delete mode 100644 www/docs/deployment/requirements.md delete mode 100644 www/docs/deployment/security.md delete mode 100644 www/docs/deployment/traefik.md delete mode 100644 www/docs/deployment/upgrading.md delete mode 100644 www/docs/guide/applications.md delete mode 100644 www/docs/guide/architecture.md delete mode 100644 www/docs/guide/audit-logs.md delete mode 100644 www/docs/guide/authentication.md delete mode 100644 www/docs/guide/cli.md delete mode 100644 www/docs/guide/databases.md delete mode 100644 www/docs/guide/deployments.md delete mode 100644 www/docs/guide/domains.md delete mode 100644 www/docs/guide/environment-variables.md delete mode 100644 www/docs/guide/getting-started.md delete mode 100644 www/docs/guide/git-integration.md delete mode 100644 www/docs/guide/logs.md delete mode 100644 www/docs/guide/metrics.md delete mode 100644 www/docs/guide/notifications.md delete mode 100644 www/docs/guide/projects.md delete mode 100644 www/docs/guide/rollback.md delete mode 100644 www/docs/guide/ssl-automation.md delete mode 100644 www/docs/guide/users.md delete mode 100644 www/docs/guide/what-is-mist.md delete mode 100644 www/docs/index.md delete mode 100755 www/docs/public/install.sh delete mode 100644 www/docs/public/mist.png delete mode 100644 www/docs/troubleshooting/forgot-password.md delete mode 100644 www/docs/troubleshooting/index.md delete mode 100644 www/docs/troubleshooting/manual-update.md delete mode 100644 www/package-lock.json delete mode 100644 www/package.json diff --git a/www/README.md b/www/README.md deleted file mode 100644 index 1043dd7..0000000 --- a/www/README.md +++ /dev/null @@ -1,151 +0,0 @@ -# Mist Documentation - -This directory contains the official documentation for Mist PaaS. - -## Overview - -The documentation is built using [VitePress](https://vitepress.dev/), a Vite & Vue powered static site generator. - -## Development - -### Prerequisites - -- Node.js 18+ -- npm or yarn - -### Install Dependencies - -```bash -npm install -``` - -### Development Server - -Start the development server with hot-reload: - -```bash -npm run docs:dev -``` - -Visit `http://localhost:5173` to view the documentation. - -### Build - -Build the static documentation site: - -```bash -npm run docs:build -``` - -Output will be in `docs/.vitepress/dist/`. - -### Preview Build - -Preview the built documentation: - -```bash -npm run docs:preview -``` - -## Structure - -``` -www/ -├── docs/ -│ ├── .vitepress/ -│ │ ├── config.js # VitePress configuration -│ │ └── theme/ # Custom theme -│ │ ├── index.js # Theme entry -│ │ └── custom.css # Custom styles (matches dash theme) -│ ├── guide/ # User guides -│ │ ├── what-is-mist.md -│ │ ├── getting-started.md -│ │ ├── applications.md -│ │ ├── deployments.md -│ │ ├── environment-variables.md -│ │ ├── domains.md -│ │ ├── git-integration.md -│ │ ├── logs.md -│ │ ├── metrics.md -│ │ ├── authentication.md -│ │ ├── users.md -│ │ ├── audit-logs.md -│ │ ├── databases.md # Coming Soon -│ │ ├── ssl-automation.md # Coming Soon -│ │ ├── rollback.md # Coming Soon -│ │ ├── notifications.md # Coming Soon -│ │ └── cli.md # Coming Soon -│ ├── api/ # API documentation -│ │ ├── overview.md -│ │ ├── authentication.md -│ │ ├── projects.md -│ │ ├── applications.md -│ │ ├── deployments.md -│ │ ├── environment-variables.md -│ │ ├── domains.md -│ │ ├── users.md -│ │ ├── github.md -│ │ └── websockets.md -│ ├── deployment/ # Deployment guides -│ │ ├── installation.md -│ │ ├── configuration.md -│ │ ├── traefik.md -│ │ ├── github-app.md -│ │ ├── upgrading.md -│ │ ├── requirements.md -│ │ ├── security.md -│ │ └── backup.md -│ ├── public/ # Static assets -│ │ └── mist.png # Logo -│ └── index.md # Home page -├── package.json -└── README.md # This file -``` - -## Theme - -The documentation uses a custom theme that matches the Mist dashboard's dark purple color scheme using OKLCH colors. See `docs/.vitepress/theme/custom.css` for the theme implementation. - -### Color Scheme - -- Primary: `oklch(0.488 0.243 264.376)` - Purple -- Background: `oklch(0.141 0.005 285.823)` - Very dark purple -- Card: `oklch(0.21 0.006 285.885)` - Dark purple - -## Contributing - -To add or update documentation: - -1. Create or edit markdown files in the appropriate directory -2. Update `docs/.vitepress/config.js` navigation if adding new pages -3. Test locally with `npm run docs:dev` -4. Build with `npm run docs:build` to verify no errors -5. Submit a pull request - -## Coming Soon Sections - -Pages marked with "Coming Soon" badges represent planned features. These sections include: - -- Database Services -- SSL Automation -- Deployment Rollback -- Notifications -- CLI Tool - -As these features are implemented, update the corresponding documentation pages and remove the "Coming Soon" banners. - -## Deployment - -The documentation can be deployed to any static hosting service: - -- GitHub Pages -- Netlify -- Vercel -- Cloudflare Pages -- Your own web server - -Simply deploy the contents of `docs/.vitepress/dist/` after building. - -## License - -MIT diff --git a/www/bun.lock b/www/bun.lock deleted file mode 100644 index 0d8f030..0000000 --- a/www/bun.lock +++ /dev/null @@ -1,354 +0,0 @@ -{ - "lockfileVersion": 1, - "configVersion": 0, - "workspaces": { - "": { - "name": "www", - "devDependencies": { - "vitepress": "^1.6.4", - "vue": "^3.5.26", - }, - }, - }, - "packages": { - "@algolia/abtesting": ["@algolia/abtesting@1.12.1", "", { "dependencies": { "@algolia/client-common": "5.46.1", "@algolia/requester-browser-xhr": "5.46.1", "@algolia/requester-fetch": "5.46.1", "@algolia/requester-node-http": "5.46.1" } }, "sha512-Y+7e2uPe376OH5O73OB1+vR40ZhbV2kzGh/AR/dPCWguoBOp1IK0o+uZQLX+7i32RMMBEKl3pj6KVEav100Kvg=="], - - "@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.17.7", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", "@algolia/autocomplete-shared": "1.17.7" } }, "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q=="], - - "@algolia/autocomplete-plugin-algolia-insights": ["@algolia/autocomplete-plugin-algolia-insights@1.17.7", "", { "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A=="], - - "@algolia/autocomplete-preset-algolia": ["@algolia/autocomplete-preset-algolia@1.17.7", "", { "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA=="], - - "@algolia/autocomplete-shared": ["@algolia/autocomplete-shared@1.17.7", "", { "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg=="], - - "@algolia/client-abtesting": ["@algolia/client-abtesting@5.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1", "@algolia/requester-browser-xhr": "5.46.1", "@algolia/requester-fetch": "5.46.1", "@algolia/requester-node-http": "5.46.1" } }, "sha512-5SWfl0UGuKxMBYlU2Y9BnlIKKEyhFU5jHE9F9jAd8nbhxZNLk0y7fXE+AZeFtyK1lkVw6O4B/e6c3XIVVCkmqw=="], - - "@algolia/client-analytics": ["@algolia/client-analytics@5.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1", "@algolia/requester-browser-xhr": "5.46.1", "@algolia/requester-fetch": "5.46.1", "@algolia/requester-node-http": "5.46.1" } }, "sha512-496K6B1l/0Jvyp3MbW/YIgmm1a6nkTrKXBM7DoEy9YAOJ8GywGpa2UYjNCW1UrOTt+em1ECzDjRx7PIzTR9YvA=="], - - "@algolia/client-common": ["@algolia/client-common@5.46.1", "", {}, "sha512-3u6AuZ1Kiss6V5JPuZfVIUYfPi8im06QBCgKqLg82GUBJ3SwhiTdSZFIEgz2mzFuitFdW1PQi3c/65zE/3FgIw=="], - - "@algolia/client-insights": ["@algolia/client-insights@5.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1", "@algolia/requester-browser-xhr": "5.46.1", "@algolia/requester-fetch": "5.46.1", "@algolia/requester-node-http": "5.46.1" } }, "sha512-LwuWjdO35HHl1rxtdn48t920Xl26Dl0SMxjxjFeAK/OwK/pIVfYjOZl/f3Pnm7Kixze+6HjpByVxEaqhTuAFaw=="], - - "@algolia/client-personalization": ["@algolia/client-personalization@5.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1", "@algolia/requester-browser-xhr": "5.46.1", "@algolia/requester-fetch": "5.46.1", "@algolia/requester-node-http": "5.46.1" } }, "sha512-6LvJAlfEsn9SVq63MYAFX2iUxztUK2Q7BVZtI1vN87lDiJ/tSVFKgKS/jBVO03A39ePxJQiFv6EKv7lmoGlWtQ=="], - - "@algolia/client-query-suggestions": ["@algolia/client-query-suggestions@5.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1", "@algolia/requester-browser-xhr": "5.46.1", "@algolia/requester-fetch": "5.46.1", "@algolia/requester-node-http": "5.46.1" } }, "sha512-9GLUCyGGo7YOXHcNqbzca82XYHJTbuiI6iT0FTGc0BrnV2N4OcrznUuVKic/duiLSun5gcy/G2Bciw5Sav9f9w=="], - - "@algolia/client-search": ["@algolia/client-search@5.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1", "@algolia/requester-browser-xhr": "5.46.1", "@algolia/requester-fetch": "5.46.1", "@algolia/requester-node-http": "5.46.1" } }, "sha512-NL76o/BoEgU4ObY5oBEC3o6KSPpuXsnSta00tAxTm1iKUWOGR34DQEKhUt8xMHhMKleUNPM/rLPFiIVtfsGU8w=="], - - "@algolia/ingestion": ["@algolia/ingestion@1.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1", "@algolia/requester-browser-xhr": "5.46.1", "@algolia/requester-fetch": "5.46.1", "@algolia/requester-node-http": "5.46.1" } }, "sha512-52Nc8WKC1FFXsdlXlTMl1Re/pTAbd2DiJiNdYmgHiikZcfF96G+Opx4qKiLUG1q7zp9e+ahNwXF6ED0XChMywg=="], - - "@algolia/monitoring": ["@algolia/monitoring@1.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1", "@algolia/requester-browser-xhr": "5.46.1", "@algolia/requester-fetch": "5.46.1", "@algolia/requester-node-http": "5.46.1" } }, "sha512-1x2/2Y/eqz6l3QcEZ8u/zMhSCpjlhePyizJd3sXrmg031HjayYT5+IxikjpqkdF7TU/deCTd/TFUcxLJ2ZHXiQ=="], - - "@algolia/recommend": ["@algolia/recommend@5.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1", "@algolia/requester-browser-xhr": "5.46.1", "@algolia/requester-fetch": "5.46.1", "@algolia/requester-node-http": "5.46.1" } }, "sha512-SSd3KlQuplxV3aRs5+Z09XilFesgpPjtCG7BGRxLTVje5hn9BLmhjO4W3gKw01INUt44Z1r0Fwx5uqnhAouunA=="], - - "@algolia/requester-browser-xhr": ["@algolia/requester-browser-xhr@5.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1" } }, "sha512-3GfCwudeW6/3caKSdmOP6RXZEL4F3GiemCaXEStkTt2Re8f7NcGYAAZnGlHsCzvhlNEuDzPYdYxh4UweY8l/2w=="], - - "@algolia/requester-fetch": ["@algolia/requester-fetch@5.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1" } }, "sha512-JUAxYfmnLYTVtAOFxVvXJ4GDHIhMuaP7JGyZXa/nCk3P8RrN5FCNTdRyftSnxyzwSIAd8qH3CjdBS9WwxxqcHQ=="], - - "@algolia/requester-node-http": ["@algolia/requester-node-http@5.46.1", "", { "dependencies": { "@algolia/client-common": "5.46.1" } }, "sha512-VwbhV1xvTGiek3d2pOS6vNBC4dtbNadyRT+i1niZpGhOJWz1XnfhxNboVbXPGAyMJYz7kDrolbDvEzIDT93uUA=="], - - "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], - - "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], - - "@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], - - "@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], - - "@docsearch/css": ["@docsearch/css@3.8.2", "", {}, "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ=="], - - "@docsearch/js": ["@docsearch/js@3.8.2", "", { "dependencies": { "@docsearch/react": "3.8.2", "preact": "^10.0.0" } }, "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ=="], - - "@docsearch/react": ["@docsearch/react@3.8.2", "", { "dependencies": { "@algolia/autocomplete-core": "1.17.7", "@algolia/autocomplete-preset-algolia": "1.17.7", "@docsearch/css": "3.8.2", "algoliasearch": "^5.14.2" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 19.0.0", "react": ">= 16.8.0 < 19.0.0", "react-dom": ">= 16.8.0 < 19.0.0", "search-insights": ">= 1 < 3" }, "optionalPeers": ["@types/react", "react", "react-dom"] }, "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg=="], - - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], - - "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], - - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], - - "@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], - - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], - - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], - - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], - - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], - - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], - - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], - - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], - - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], - - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], - - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], - - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], - - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], - - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], - - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], - - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], - - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], - - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], - - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], - - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], - - "@iconify-json/simple-icons": ["@iconify-json/simple-icons@1.2.63", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-xZl2UWCwE58VlqZ+pDPmaUhE2tq8MVSTJRr4/9nzzHlDdjJ0Ud1VxNXPrwTSgESKY29iCQw3S0r2nJTSNNngHw=="], - - "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], - - "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], - - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.54.0", "", { "os": "android", "cpu": "arm" }, "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng=="], - - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.54.0", "", { "os": "android", "cpu": "arm64" }, "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw=="], - - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.54.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw=="], - - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.54.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A=="], - - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.54.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA=="], - - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.54.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ=="], - - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.54.0", "", { "os": "linux", "cpu": "arm" }, "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ=="], - - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.54.0", "", { "os": "linux", "cpu": "arm" }, "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA=="], - - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.54.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng=="], - - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.54.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg=="], - - "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.54.0", "", { "os": "linux", "cpu": "none" }, "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw=="], - - "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.54.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA=="], - - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.54.0", "", { "os": "linux", "cpu": "none" }, "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ=="], - - "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.54.0", "", { "os": "linux", "cpu": "none" }, "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A=="], - - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.54.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ=="], - - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.54.0", "", { "os": "linux", "cpu": "x64" }, "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ=="], - - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.54.0", "", { "os": "linux", "cpu": "x64" }, "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw=="], - - "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.54.0", "", { "os": "none", "cpu": "arm64" }, "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg=="], - - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.54.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw=="], - - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.54.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ=="], - - "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.54.0", "", { "os": "win32", "cpu": "x64" }, "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ=="], - - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.54.0", "", { "os": "win32", "cpu": "x64" }, "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg=="], - - "@shikijs/core": ["@shikijs/core@2.5.0", "", { "dependencies": { "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg=="], - - "@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^3.1.0" } }, "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w=="], - - "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw=="], - - "@shikijs/langs": ["@shikijs/langs@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w=="], - - "@shikijs/themes": ["@shikijs/themes@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw=="], - - "@shikijs/transformers": ["@shikijs/transformers@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/types": "2.5.0" } }, "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg=="], - - "@shikijs/types": ["@shikijs/types@2.5.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw=="], - - "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], - - "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], - - "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], - - "@types/linkify-it": ["@types/linkify-it@5.0.0", "", {}, "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="], - - "@types/markdown-it": ["@types/markdown-it@14.1.2", "", { "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" } }, "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog=="], - - "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], - - "@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="], - - "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], - - "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], - - "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], - - "@vitejs/plugin-vue": ["@vitejs/plugin-vue@5.2.4", "", { "peerDependencies": { "vite": "^5.0.0 || ^6.0.0", "vue": "^3.2.25" } }, "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA=="], - - "@vue/compiler-core": ["@vue/compiler-core@3.5.26", "", { "dependencies": { "@babel/parser": "^7.28.5", "@vue/shared": "3.5.26", "entities": "^7.0.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w=="], - - "@vue/compiler-dom": ["@vue/compiler-dom@3.5.26", "", { "dependencies": { "@vue/compiler-core": "3.5.26", "@vue/shared": "3.5.26" } }, "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A=="], - - "@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.26", "", { "dependencies": { "@babel/parser": "^7.28.5", "@vue/compiler-core": "3.5.26", "@vue/compiler-dom": "3.5.26", "@vue/compiler-ssr": "3.5.26", "@vue/shared": "3.5.26", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA=="], - - "@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.26", "", { "dependencies": { "@vue/compiler-dom": "3.5.26", "@vue/shared": "3.5.26" } }, "sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw=="], - - "@vue/devtools-api": ["@vue/devtools-api@7.7.9", "", { "dependencies": { "@vue/devtools-kit": "^7.7.9" } }, "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g=="], - - "@vue/devtools-kit": ["@vue/devtools-kit@7.7.9", "", { "dependencies": { "@vue/devtools-shared": "^7.7.9", "birpc": "^2.3.0", "hookable": "^5.5.3", "mitt": "^3.0.1", "perfect-debounce": "^1.0.0", "speakingurl": "^14.0.1", "superjson": "^2.2.2" } }, "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA=="], - - "@vue/devtools-shared": ["@vue/devtools-shared@7.7.9", "", { "dependencies": { "rfdc": "^1.4.1" } }, "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA=="], - - "@vue/reactivity": ["@vue/reactivity@3.5.26", "", { "dependencies": { "@vue/shared": "3.5.26" } }, "sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ=="], - - "@vue/runtime-core": ["@vue/runtime-core@3.5.26", "", { "dependencies": { "@vue/reactivity": "3.5.26", "@vue/shared": "3.5.26" } }, "sha512-xJWM9KH1kd201w5DvMDOwDHYhrdPTrAatn56oB/LRG4plEQeZRQLw0Bpwih9KYoqmzaxF0OKSn6swzYi84e1/Q=="], - - "@vue/runtime-dom": ["@vue/runtime-dom@3.5.26", "", { "dependencies": { "@vue/reactivity": "3.5.26", "@vue/runtime-core": "3.5.26", "@vue/shared": "3.5.26", "csstype": "^3.2.3" } }, "sha512-XLLd/+4sPC2ZkN/6+V4O4gjJu6kSDbHAChvsyWgm1oGbdSO3efvGYnm25yCjtFm/K7rrSDvSfPDgN1pHgS4VNQ=="], - - "@vue/server-renderer": ["@vue/server-renderer@3.5.26", "", { "dependencies": { "@vue/compiler-ssr": "3.5.26", "@vue/shared": "3.5.26" }, "peerDependencies": { "vue": "3.5.26" } }, "sha512-TYKLXmrwWKSodyVuO1WAubucd+1XlLg4set0YoV+Hu8Lo79mp/YMwWV5mC5FgtsDxX3qo1ONrxFaTP1OQgy1uA=="], - - "@vue/shared": ["@vue/shared@3.5.26", "", {}, "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A=="], - - "@vueuse/core": ["@vueuse/core@12.8.2", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" } }, "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ=="], - - "@vueuse/integrations": ["@vueuse/integrations@12.8.2", "", { "dependencies": { "@vueuse/core": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" }, "peerDependencies": { "async-validator": "^4", "axios": "^1", "change-case": "^5", "drauu": "^0.4", "focus-trap": "^7", "fuse.js": "^7", "idb-keyval": "^6", "jwt-decode": "^4", "nprogress": "^0.2", "qrcode": "^1.5", "sortablejs": "^1", "universal-cookie": "^7" }, "optionalPeers": ["async-validator", "axios", "change-case", "drauu", "fuse.js", "idb-keyval", "jwt-decode", "nprogress", "qrcode", "sortablejs", "universal-cookie"] }, "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g=="], - - "@vueuse/metadata": ["@vueuse/metadata@12.8.2", "", {}, "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A=="], - - "@vueuse/shared": ["@vueuse/shared@12.8.2", "", { "dependencies": { "vue": "^3.5.13" } }, "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w=="], - - "algoliasearch": ["algoliasearch@5.46.1", "", { "dependencies": { "@algolia/abtesting": "1.12.1", "@algolia/client-abtesting": "5.46.1", "@algolia/client-analytics": "5.46.1", "@algolia/client-common": "5.46.1", "@algolia/client-insights": "5.46.1", "@algolia/client-personalization": "5.46.1", "@algolia/client-query-suggestions": "5.46.1", "@algolia/client-search": "5.46.1", "@algolia/ingestion": "1.46.1", "@algolia/monitoring": "1.46.1", "@algolia/recommend": "5.46.1", "@algolia/requester-browser-xhr": "5.46.1", "@algolia/requester-fetch": "5.46.1", "@algolia/requester-node-http": "5.46.1" } }, "sha512-39ol8Ulqb3MntofkXHlrcXKyU8BU0PXvQrXPBIX6eXj/EO4VT7651mhGVORI2oF8ydya9nFzT3fYDoqme/KL6w=="], - - "birpc": ["birpc@2.9.0", "", {}, "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw=="], - - "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], - - "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], - - "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], - - "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], - - "copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "^5.2.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="], - - "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], - - "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], - - "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], - - "emoji-regex-xs": ["emoji-regex-xs@1.0.0", "", {}, "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="], - - "entities": ["entities@7.0.0", "", {}, "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ=="], - - "esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": "bin/esbuild" }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], - - "estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], - - "focus-trap": ["focus-trap@7.6.6", "", { "dependencies": { "tabbable": "^6.3.0" } }, "sha512-v/Z8bvMCajtx4mEXmOo7QEsIzlIOqRXTIwgUfsFOF9gEsespdbD0AkPIka1bSXZ8Y8oZ+2IVDQZePkTfEHZl7Q=="], - - "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], - - "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], - - "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], - - "hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="], - - "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], - - "is-what": ["is-what@5.5.0", "", {}, "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw=="], - - "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - - "mark.js": ["mark.js@8.11.1", "", {}, "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ=="], - - "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="], - - "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], - - "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], - - "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], - - "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], - - "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], - - "minisearch": ["minisearch@7.2.0", "", {}, "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg=="], - - "mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="], - - "nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - - "oniguruma-to-es": ["oniguruma-to-es@3.1.1", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ=="], - - "perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="], - - "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - - "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], - - "preact": ["preact@10.28.0", "", {}, "sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA=="], - - "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], - - "regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], - - "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], - - "regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], - - "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], - - "rollup": ["rollup@4.54.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.54.0", "@rollup/rollup-android-arm64": "4.54.0", "@rollup/rollup-darwin-arm64": "4.54.0", "@rollup/rollup-darwin-x64": "4.54.0", "@rollup/rollup-freebsd-arm64": "4.54.0", "@rollup/rollup-freebsd-x64": "4.54.0", "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", "@rollup/rollup-linux-arm-musleabihf": "4.54.0", "@rollup/rollup-linux-arm64-gnu": "4.54.0", "@rollup/rollup-linux-arm64-musl": "4.54.0", "@rollup/rollup-linux-loong64-gnu": "4.54.0", "@rollup/rollup-linux-ppc64-gnu": "4.54.0", "@rollup/rollup-linux-riscv64-gnu": "4.54.0", "@rollup/rollup-linux-riscv64-musl": "4.54.0", "@rollup/rollup-linux-s390x-gnu": "4.54.0", "@rollup/rollup-linux-x64-gnu": "4.54.0", "@rollup/rollup-linux-x64-musl": "4.54.0", "@rollup/rollup-openharmony-arm64": "4.54.0", "@rollup/rollup-win32-arm64-msvc": "4.54.0", "@rollup/rollup-win32-ia32-msvc": "4.54.0", "@rollup/rollup-win32-x64-gnu": "4.54.0", "@rollup/rollup-win32-x64-msvc": "4.54.0", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw=="], - - "search-insights": ["search-insights@2.17.3", "", {}, "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ=="], - - "shiki": ["shiki@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/langs": "2.5.0", "@shikijs/themes": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ=="], - - "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], - - "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], - - "speakingurl": ["speakingurl@14.0.1", "", {}, "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="], - - "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], - - "superjson": ["superjson@2.2.6", "", { "dependencies": { "copy-anything": "^4" } }, "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA=="], - - "tabbable": ["tabbable@6.3.0", "", {}, "sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ=="], - - "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], - - "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], - - "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], - - "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], - - "unist-util-visit": ["unist-util-visit@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg=="], - - "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], - - "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], - - "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], - - "vite": ["vite@5.4.21", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": "bin/vite.js" }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="], - - "vitepress": ["vitepress@1.6.4", "", { "dependencies": { "@docsearch/css": "3.8.2", "@docsearch/js": "3.8.2", "@iconify-json/simple-icons": "^1.2.21", "@shikijs/core": "^2.1.0", "@shikijs/transformers": "^2.1.0", "@shikijs/types": "^2.1.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.2.1", "@vue/devtools-api": "^7.7.0", "@vue/shared": "^3.5.13", "@vueuse/core": "^12.4.0", "@vueuse/integrations": "^12.4.0", "focus-trap": "^7.6.4", "mark.js": "8.11.1", "minisearch": "^7.1.1", "shiki": "^2.1.0", "vite": "^5.4.14", "vue": "^3.5.13" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3"], "bin": "bin/vitepress.js" }, "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg=="], - - "vue": ["vue@3.5.26", "", { "dependencies": { "@vue/compiler-dom": "3.5.26", "@vue/compiler-sfc": "3.5.26", "@vue/runtime-dom": "3.5.26", "@vue/server-renderer": "3.5.26", "@vue/shared": "3.5.26" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA=="], - - "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], - } -} diff --git a/www/docs/.vitepress/cache/deps/_metadata.json b/www/docs/.vitepress/cache/deps/_metadata.json deleted file mode 100644 index 0174529..0000000 --- a/www/docs/.vitepress/cache/deps/_metadata.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "hash": "a6985175", - "configHash": "202a3a6a", - "lockfileHash": "d734444e", - "browserHash": "ffe086b0", - "optimized": { - "vue": { - "src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js", - "file": "vue.js", - "fileHash": "1e83a252", - "needsInterop": false - }, - "vitepress > @vue/devtools-api": { - "src": "../../../../node_modules/@vue/devtools-api/dist/index.js", - "file": "vitepress___@vue_devtools-api.js", - "fileHash": "dabc8034", - "needsInterop": false - }, - "vitepress > @vueuse/core": { - "src": "../../../../node_modules/@vueuse/core/index.mjs", - "file": "vitepress___@vueuse_core.js", - "fileHash": "aedcf797", - "needsInterop": false - }, - "vitepress > @vueuse/integrations/useFocusTrap": { - "src": "../../../../node_modules/@vueuse/integrations/useFocusTrap.mjs", - "file": "vitepress___@vueuse_integrations_useFocusTrap.js", - "fileHash": "fbb05e5d", - "needsInterop": false - }, - "vitepress > mark.js/src/vanilla.js": { - "src": "../../../../node_modules/mark.js/src/vanilla.js", - "file": "vitepress___mark__js_src_vanilla__js.js", - "fileHash": "3fe456ed", - "needsInterop": false - }, - "vitepress > minisearch": { - "src": "../../../../node_modules/minisearch/dist/es/index.js", - "file": "vitepress___minisearch.js", - "fileHash": "5364dc96", - "needsInterop": false - } - }, - "chunks": { - "chunk-2CLQ7TTZ": { - "file": "chunk-2CLQ7TTZ.js" - }, - "chunk-LE5NDSFD": { - "file": "chunk-LE5NDSFD.js" - } - } -} \ No newline at end of file diff --git a/www/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js b/www/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js deleted file mode 100644 index 8cd09fb..0000000 --- a/www/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js +++ /dev/null @@ -1,9719 +0,0 @@ -import { - Fragment, - TransitionGroup, - computed, - customRef, - defineComponent, - effectScope, - getCurrentInstance, - getCurrentScope, - h, - hasInjectionContext, - inject, - isReactive, - isReadonly, - isRef, - markRaw, - nextTick, - onBeforeMount, - onBeforeUnmount, - onBeforeUpdate, - onMounted, - onScopeDispose, - onUnmounted, - onUpdated, - provide, - reactive, - readonly, - ref, - shallowReactive, - shallowRef, - toRaw, - toRef, - toRefs, - toValue, - unref, - watch, - watchEffect -} from "./chunk-LE5NDSFD.js"; - -// node_modules/@vueuse/shared/index.mjs -function computedEager(fn, options) { - var _a; - const result = shallowRef(); - watchEffect(() => { - result.value = fn(); - }, { - ...options, - flush: (_a = options == null ? void 0 : options.flush) != null ? _a : "sync" - }); - return readonly(result); -} -function computedWithControl(source, fn) { - let v = void 0; - let track; - let trigger; - const dirty = shallowRef(true); - const update = () => { - dirty.value = true; - trigger(); - }; - watch(source, update, { flush: "sync" }); - const get2 = typeof fn === "function" ? fn : fn.get; - const set2 = typeof fn === "function" ? void 0 : fn.set; - const result = customRef((_track, _trigger) => { - track = _track; - trigger = _trigger; - return { - get() { - if (dirty.value) { - v = get2(v); - dirty.value = false; - } - track(); - return v; - }, - set(v2) { - set2 == null ? void 0 : set2(v2); - } - }; - }); - if (Object.isExtensible(result)) - result.trigger = update; - return result; -} -function tryOnScopeDispose(fn) { - if (getCurrentScope()) { - onScopeDispose(fn); - return true; - } - return false; -} -function createEventHook() { - const fns = /* @__PURE__ */ new Set(); - const off = (fn) => { - fns.delete(fn); - }; - const clear = () => { - fns.clear(); - }; - const on = (fn) => { - fns.add(fn); - const offFn = () => off(fn); - tryOnScopeDispose(offFn); - return { - off: offFn - }; - }; - const trigger = (...args) => { - return Promise.all(Array.from(fns).map((fn) => fn(...args))); - }; - return { - on, - off, - trigger, - clear - }; -} -function createGlobalState(stateFactory) { - let initialized = false; - let state; - const scope = effectScope(true); - return (...args) => { - if (!initialized) { - state = scope.run(() => stateFactory(...args)); - initialized = true; - } - return state; - }; -} -var localProvidedStateMap = /* @__PURE__ */ new WeakMap(); -var injectLocal = (...args) => { - var _a; - const key = args[0]; - const instance = (_a = getCurrentInstance()) == null ? void 0 : _a.proxy; - if (instance == null && !hasInjectionContext()) - throw new Error("injectLocal must be called in setup"); - if (instance && localProvidedStateMap.has(instance) && key in localProvidedStateMap.get(instance)) - return localProvidedStateMap.get(instance)[key]; - return inject(...args); -}; -var provideLocal = (key, value) => { - var _a; - const instance = (_a = getCurrentInstance()) == null ? void 0 : _a.proxy; - if (instance == null) - throw new Error("provideLocal must be called in setup"); - if (!localProvidedStateMap.has(instance)) - localProvidedStateMap.set(instance, /* @__PURE__ */ Object.create(null)); - const localProvidedState = localProvidedStateMap.get(instance); - localProvidedState[key] = value; - provide(key, value); -}; -function createInjectionState(composable, options) { - const key = (options == null ? void 0 : options.injectionKey) || Symbol(composable.name || "InjectionState"); - const defaultValue = options == null ? void 0 : options.defaultValue; - const useProvidingState = (...args) => { - const state = composable(...args); - provideLocal(key, state); - return state; - }; - const useInjectedState = () => injectLocal(key, defaultValue); - return [useProvidingState, useInjectedState]; -} -function createRef(value, deep) { - if (deep === true) { - return ref(value); - } else { - return shallowRef(value); - } -} -function createSharedComposable(composable) { - let subscribers = 0; - let state; - let scope; - const dispose = () => { - subscribers -= 1; - if (scope && subscribers <= 0) { - scope.stop(); - state = void 0; - scope = void 0; - } - }; - return (...args) => { - subscribers += 1; - if (!scope) { - scope = effectScope(true); - state = scope.run(() => composable(...args)); - } - tryOnScopeDispose(dispose); - return state; - }; -} -function extendRef(ref2, extend, { enumerable = false, unwrap = true } = {}) { - for (const [key, value] of Object.entries(extend)) { - if (key === "value") - continue; - if (isRef(value) && unwrap) { - Object.defineProperty(ref2, key, { - get() { - return value.value; - }, - set(v) { - value.value = v; - }, - enumerable - }); - } else { - Object.defineProperty(ref2, key, { value, enumerable }); - } - } - return ref2; -} -function get(obj, key) { - if (key == null) - return unref(obj); - return unref(obj)[key]; -} -function isDefined(v) { - return unref(v) != null; -} -function makeDestructurable(obj, arr) { - if (typeof Symbol !== "undefined") { - const clone = { ...obj }; - Object.defineProperty(clone, Symbol.iterator, { - enumerable: false, - value() { - let index = 0; - return { - next: () => ({ - value: arr[index++], - done: index > arr.length - }) - }; - } - }); - return clone; - } else { - return Object.assign([...arr], obj); - } -} -function reactify(fn, options) { - const unrefFn = (options == null ? void 0 : options.computedGetter) === false ? unref : toValue; - return function(...args) { - return computed(() => fn.apply(this, args.map((i) => unrefFn(i)))); - }; -} -function reactifyObject(obj, optionsOrKeys = {}) { - let keys2 = []; - let options; - if (Array.isArray(optionsOrKeys)) { - keys2 = optionsOrKeys; - } else { - options = optionsOrKeys; - const { includeOwnProperties = true } = optionsOrKeys; - keys2.push(...Object.keys(obj)); - if (includeOwnProperties) - keys2.push(...Object.getOwnPropertyNames(obj)); - } - return Object.fromEntries( - keys2.map((key) => { - const value = obj[key]; - return [ - key, - typeof value === "function" ? reactify(value.bind(obj), options) : value - ]; - }) - ); -} -function toReactive(objectRef) { - if (!isRef(objectRef)) - return reactive(objectRef); - const proxy = new Proxy({}, { - get(_, p, receiver) { - return unref(Reflect.get(objectRef.value, p, receiver)); - }, - set(_, p, value) { - if (isRef(objectRef.value[p]) && !isRef(value)) - objectRef.value[p].value = value; - else - objectRef.value[p] = value; - return true; - }, - deleteProperty(_, p) { - return Reflect.deleteProperty(objectRef.value, p); - }, - has(_, p) { - return Reflect.has(objectRef.value, p); - }, - ownKeys() { - return Object.keys(objectRef.value); - }, - getOwnPropertyDescriptor() { - return { - enumerable: true, - configurable: true - }; - } - }); - return reactive(proxy); -} -function reactiveComputed(fn) { - return toReactive(computed(fn)); -} -function reactiveOmit(obj, ...keys2) { - const flatKeys = keys2.flat(); - const predicate = flatKeys[0]; - return reactiveComputed(() => typeof predicate === "function" ? Object.fromEntries(Object.entries(toRefs(obj)).filter(([k, v]) => !predicate(toValue(v), k))) : Object.fromEntries(Object.entries(toRefs(obj)).filter((e) => !flatKeys.includes(e[0])))); -} -var isClient = typeof window !== "undefined" && typeof document !== "undefined"; -var isWorker = typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope; -var isDef = (val) => typeof val !== "undefined"; -var notNullish = (val) => val != null; -var assert = (condition, ...infos) => { - if (!condition) - console.warn(...infos); -}; -var toString = Object.prototype.toString; -var isObject = (val) => toString.call(val) === "[object Object]"; -var now = () => Date.now(); -var timestamp = () => +Date.now(); -var clamp = (n, min, max) => Math.min(max, Math.max(min, n)); -var noop = () => { -}; -var rand = (min, max) => { - min = Math.ceil(min); - max = Math.floor(max); - return Math.floor(Math.random() * (max - min + 1)) + min; -}; -var hasOwn = (val, key) => Object.prototype.hasOwnProperty.call(val, key); -var isIOS = getIsIOS(); -function getIsIOS() { - var _a, _b; - return isClient && ((_a = window == null ? void 0 : window.navigator) == null ? void 0 : _a.userAgent) && (/iP(?:ad|hone|od)/.test(window.navigator.userAgent) || ((_b = window == null ? void 0 : window.navigator) == null ? void 0 : _b.maxTouchPoints) > 2 && /iPad|Macintosh/.test(window == null ? void 0 : window.navigator.userAgent)); -} -function createFilterWrapper(filter, fn) { - function wrapper(...args) { - return new Promise((resolve, reject) => { - Promise.resolve(filter(() => fn.apply(this, args), { fn, thisArg: this, args })).then(resolve).catch(reject); - }); - } - return wrapper; -} -var bypassFilter = (invoke2) => { - return invoke2(); -}; -function debounceFilter(ms, options = {}) { - let timer; - let maxTimer; - let lastRejector = noop; - const _clearTimeout = (timer2) => { - clearTimeout(timer2); - lastRejector(); - lastRejector = noop; - }; - let lastInvoker; - const filter = (invoke2) => { - const duration = toValue(ms); - const maxDuration = toValue(options.maxWait); - if (timer) - _clearTimeout(timer); - if (duration <= 0 || maxDuration !== void 0 && maxDuration <= 0) { - if (maxTimer) { - _clearTimeout(maxTimer); - maxTimer = null; - } - return Promise.resolve(invoke2()); - } - return new Promise((resolve, reject) => { - lastRejector = options.rejectOnCancel ? reject : resolve; - lastInvoker = invoke2; - if (maxDuration && !maxTimer) { - maxTimer = setTimeout(() => { - if (timer) - _clearTimeout(timer); - maxTimer = null; - resolve(lastInvoker()); - }, maxDuration); - } - timer = setTimeout(() => { - if (maxTimer) - _clearTimeout(maxTimer); - maxTimer = null; - resolve(invoke2()); - }, duration); - }); - }; - return filter; -} -function throttleFilter(...args) { - let lastExec = 0; - let timer; - let isLeading = true; - let lastRejector = noop; - let lastValue; - let ms; - let trailing; - let leading; - let rejectOnCancel; - if (!isRef(args[0]) && typeof args[0] === "object") - ({ delay: ms, trailing = true, leading = true, rejectOnCancel = false } = args[0]); - else - [ms, trailing = true, leading = true, rejectOnCancel = false] = args; - const clear = () => { - if (timer) { - clearTimeout(timer); - timer = void 0; - lastRejector(); - lastRejector = noop; - } - }; - const filter = (_invoke) => { - const duration = toValue(ms); - const elapsed = Date.now() - lastExec; - const invoke2 = () => { - return lastValue = _invoke(); - }; - clear(); - if (duration <= 0) { - lastExec = Date.now(); - return invoke2(); - } - if (elapsed > duration && (leading || !isLeading)) { - lastExec = Date.now(); - invoke2(); - } else if (trailing) { - lastValue = new Promise((resolve, reject) => { - lastRejector = rejectOnCancel ? reject : resolve; - timer = setTimeout(() => { - lastExec = Date.now(); - isLeading = true; - resolve(invoke2()); - clear(); - }, Math.max(0, duration - elapsed)); - }); - } - if (!leading && !timer) - timer = setTimeout(() => isLeading = true, duration); - isLeading = false; - return lastValue; - }; - return filter; -} -function pausableFilter(extendFilter = bypassFilter, options = {}) { - const { - initialState = "active" - } = options; - const isActive = toRef2(initialState === "active"); - function pause() { - isActive.value = false; - } - function resume() { - isActive.value = true; - } - const eventFilter = (...args) => { - if (isActive.value) - extendFilter(...args); - }; - return { isActive: readonly(isActive), pause, resume, eventFilter }; -} -function cacheStringFunction(fn) { - const cache = /* @__PURE__ */ Object.create(null); - return (str) => { - const hit = cache[str]; - return hit || (cache[str] = fn(str)); - }; -} -var hyphenateRE = /\B([A-Z])/g; -var hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, "-$1").toLowerCase()); -var camelizeRE = /-(\w)/g; -var camelize = cacheStringFunction((str) => { - return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : ""); -}); -function promiseTimeout(ms, throwOnTimeout = false, reason = "Timeout") { - return new Promise((resolve, reject) => { - if (throwOnTimeout) - setTimeout(() => reject(reason), ms); - else - setTimeout(resolve, ms); - }); -} -function identity(arg) { - return arg; -} -function createSingletonPromise(fn) { - let _promise; - function wrapper() { - if (!_promise) - _promise = fn(); - return _promise; - } - wrapper.reset = async () => { - const _prev = _promise; - _promise = void 0; - if (_prev) - await _prev; - }; - return wrapper; -} -function invoke(fn) { - return fn(); -} -function containsProp(obj, ...props) { - return props.some((k) => k in obj); -} -function increaseWithUnit(target, delta) { - var _a; - if (typeof target === "number") - return target + delta; - const value = ((_a = target.match(/^-?\d+\.?\d*/)) == null ? void 0 : _a[0]) || ""; - const unit = target.slice(value.length); - const result = Number.parseFloat(value) + delta; - if (Number.isNaN(result)) - return target; - return result + unit; -} -function pxValue(px) { - return px.endsWith("rem") ? Number.parseFloat(px) * 16 : Number.parseFloat(px); -} -function objectPick(obj, keys2, omitUndefined = false) { - return keys2.reduce((n, k) => { - if (k in obj) { - if (!omitUndefined || obj[k] !== void 0) - n[k] = obj[k]; - } - return n; - }, {}); -} -function objectOmit(obj, keys2, omitUndefined = false) { - return Object.fromEntries(Object.entries(obj).filter(([key, value]) => { - return (!omitUndefined || value !== void 0) && !keys2.includes(key); - })); -} -function objectEntries(obj) { - return Object.entries(obj); -} -function getLifeCycleTarget(target) { - return target || getCurrentInstance(); -} -function toArray(value) { - return Array.isArray(value) ? value : [value]; -} -function toRef2(...args) { - if (args.length !== 1) - return toRef(...args); - const r = args[0]; - return typeof r === "function" ? readonly(customRef(() => ({ get: r, set: noop }))) : ref(r); -} -var resolveRef = toRef2; -function reactivePick(obj, ...keys2) { - const flatKeys = keys2.flat(); - const predicate = flatKeys[0]; - return reactiveComputed(() => typeof predicate === "function" ? Object.fromEntries(Object.entries(toRefs(obj)).filter(([k, v]) => predicate(toValue(v), k))) : Object.fromEntries(flatKeys.map((k) => [k, toRef2(obj, k)]))); -} -function refAutoReset(defaultValue, afterMs = 1e4) { - return customRef((track, trigger) => { - let value = toValue(defaultValue); - let timer; - const resetAfter = () => setTimeout(() => { - value = toValue(defaultValue); - trigger(); - }, toValue(afterMs)); - tryOnScopeDispose(() => { - clearTimeout(timer); - }); - return { - get() { - track(); - return value; - }, - set(newValue) { - value = newValue; - trigger(); - clearTimeout(timer); - timer = resetAfter(); - } - }; - }); -} -function useDebounceFn(fn, ms = 200, options = {}) { - return createFilterWrapper( - debounceFilter(ms, options), - fn - ); -} -function refDebounced(value, ms = 200, options = {}) { - const debounced = ref(value.value); - const updater = useDebounceFn(() => { - debounced.value = value.value; - }, ms, options); - watch(value, () => updater()); - return debounced; -} -function refDefault(source, defaultValue) { - return computed({ - get() { - var _a; - return (_a = source.value) != null ? _a : defaultValue; - }, - set(value) { - source.value = value; - } - }); -} -function useThrottleFn(fn, ms = 200, trailing = false, leading = true, rejectOnCancel = false) { - return createFilterWrapper( - throttleFilter(ms, trailing, leading, rejectOnCancel), - fn - ); -} -function refThrottled(value, delay = 200, trailing = true, leading = true) { - if (delay <= 0) - return value; - const throttled = ref(value.value); - const updater = useThrottleFn(() => { - throttled.value = value.value; - }, delay, trailing, leading); - watch(value, () => updater()); - return throttled; -} -function refWithControl(initial, options = {}) { - let source = initial; - let track; - let trigger; - const ref2 = customRef((_track, _trigger) => { - track = _track; - trigger = _trigger; - return { - get() { - return get2(); - }, - set(v) { - set2(v); - } - }; - }); - function get2(tracking = true) { - if (tracking) - track(); - return source; - } - function set2(value, triggering = true) { - var _a, _b; - if (value === source) - return; - const old = source; - if (((_a = options.onBeforeChange) == null ? void 0 : _a.call(options, value, old)) === false) - return; - source = value; - (_b = options.onChanged) == null ? void 0 : _b.call(options, value, old); - if (triggering) - trigger(); - } - const untrackedGet = () => get2(false); - const silentSet = (v) => set2(v, false); - const peek = () => get2(false); - const lay = (v) => set2(v, false); - return extendRef( - ref2, - { - get: get2, - set: set2, - untrackedGet, - silentSet, - peek, - lay - }, - { enumerable: true } - ); -} -var controlledRef = refWithControl; -function set(...args) { - if (args.length === 2) { - const [ref2, value] = args; - ref2.value = value; - } - if (args.length === 3) { - const [target, key, value] = args; - target[key] = value; - } -} -function watchWithFilter(source, cb, options = {}) { - const { - eventFilter = bypassFilter, - ...watchOptions - } = options; - return watch( - source, - createFilterWrapper( - eventFilter, - cb - ), - watchOptions - ); -} -function watchPausable(source, cb, options = {}) { - const { - eventFilter: filter, - initialState = "active", - ...watchOptions - } = options; - const { eventFilter, pause, resume, isActive } = pausableFilter(filter, { initialState }); - const stop = watchWithFilter( - source, - cb, - { - ...watchOptions, - eventFilter - } - ); - return { stop, pause, resume, isActive }; -} -function syncRef(left, right, ...[options]) { - const { - flush = "sync", - deep = false, - immediate = true, - direction = "both", - transform = {} - } = options || {}; - const watchers = []; - const transformLTR = "ltr" in transform && transform.ltr || ((v) => v); - const transformRTL = "rtl" in transform && transform.rtl || ((v) => v); - if (direction === "both" || direction === "ltr") { - watchers.push(watchPausable( - left, - (newValue) => { - watchers.forEach((w) => w.pause()); - right.value = transformLTR(newValue); - watchers.forEach((w) => w.resume()); - }, - { flush, deep, immediate } - )); - } - if (direction === "both" || direction === "rtl") { - watchers.push(watchPausable( - right, - (newValue) => { - watchers.forEach((w) => w.pause()); - left.value = transformRTL(newValue); - watchers.forEach((w) => w.resume()); - }, - { flush, deep, immediate } - )); - } - const stop = () => { - watchers.forEach((w) => w.stop()); - }; - return stop; -} -function syncRefs(source, targets, options = {}) { - const { - flush = "sync", - deep = false, - immediate = true - } = options; - const targetsArray = toArray(targets); - return watch( - source, - (newValue) => targetsArray.forEach((target) => target.value = newValue), - { flush, deep, immediate } - ); -} -function toRefs2(objectRef, options = {}) { - if (!isRef(objectRef)) - return toRefs(objectRef); - const result = Array.isArray(objectRef.value) ? Array.from({ length: objectRef.value.length }) : {}; - for (const key in objectRef.value) { - result[key] = customRef(() => ({ - get() { - return objectRef.value[key]; - }, - set(v) { - var _a; - const replaceRef = (_a = toValue(options.replaceRef)) != null ? _a : true; - if (replaceRef) { - if (Array.isArray(objectRef.value)) { - const copy = [...objectRef.value]; - copy[key] = v; - objectRef.value = copy; - } else { - const newObject = { ...objectRef.value, [key]: v }; - Object.setPrototypeOf(newObject, Object.getPrototypeOf(objectRef.value)); - objectRef.value = newObject; - } - } else { - objectRef.value[key] = v; - } - } - })); - } - return result; -} -var toValue2 = toValue; -var resolveUnref = toValue; -function tryOnBeforeMount(fn, sync = true, target) { - const instance = getLifeCycleTarget(target); - if (instance) - onBeforeMount(fn, target); - else if (sync) - fn(); - else - nextTick(fn); -} -function tryOnBeforeUnmount(fn, target) { - const instance = getLifeCycleTarget(target); - if (instance) - onBeforeUnmount(fn, target); -} -function tryOnMounted(fn, sync = true, target) { - const instance = getLifeCycleTarget(); - if (instance) - onMounted(fn, target); - else if (sync) - fn(); - else - nextTick(fn); -} -function tryOnUnmounted(fn, target) { - const instance = getLifeCycleTarget(target); - if (instance) - onUnmounted(fn, target); -} -function createUntil(r, isNot = false) { - function toMatch(condition, { flush = "sync", deep = false, timeout, throwOnTimeout } = {}) { - let stop = null; - const watcher = new Promise((resolve) => { - stop = watch( - r, - (v) => { - if (condition(v) !== isNot) { - if (stop) - stop(); - else - nextTick(() => stop == null ? void 0 : stop()); - resolve(v); - } - }, - { - flush, - deep, - immediate: true - } - ); - }); - const promises = [watcher]; - if (timeout != null) { - promises.push( - promiseTimeout(timeout, throwOnTimeout).then(() => toValue(r)).finally(() => stop == null ? void 0 : stop()) - ); - } - return Promise.race(promises); - } - function toBe(value, options) { - if (!isRef(value)) - return toMatch((v) => v === value, options); - const { flush = "sync", deep = false, timeout, throwOnTimeout } = options != null ? options : {}; - let stop = null; - const watcher = new Promise((resolve) => { - stop = watch( - [r, value], - ([v1, v2]) => { - if (isNot !== (v1 === v2)) { - if (stop) - stop(); - else - nextTick(() => stop == null ? void 0 : stop()); - resolve(v1); - } - }, - { - flush, - deep, - immediate: true - } - ); - }); - const promises = [watcher]; - if (timeout != null) { - promises.push( - promiseTimeout(timeout, throwOnTimeout).then(() => toValue(r)).finally(() => { - stop == null ? void 0 : stop(); - return toValue(r); - }) - ); - } - return Promise.race(promises); - } - function toBeTruthy(options) { - return toMatch((v) => Boolean(v), options); - } - function toBeNull(options) { - return toBe(null, options); - } - function toBeUndefined(options) { - return toBe(void 0, options); - } - function toBeNaN(options) { - return toMatch(Number.isNaN, options); - } - function toContains(value, options) { - return toMatch((v) => { - const array = Array.from(v); - return array.includes(value) || array.includes(toValue(value)); - }, options); - } - function changed(options) { - return changedTimes(1, options); - } - function changedTimes(n = 1, options) { - let count = -1; - return toMatch(() => { - count += 1; - return count >= n; - }, options); - } - if (Array.isArray(toValue(r))) { - const instance = { - toMatch, - toContains, - changed, - changedTimes, - get not() { - return createUntil(r, !isNot); - } - }; - return instance; - } else { - const instance = { - toMatch, - toBe, - toBeTruthy, - toBeNull, - toBeNaN, - toBeUndefined, - changed, - changedTimes, - get not() { - return createUntil(r, !isNot); - } - }; - return instance; - } -} -function until(r) { - return createUntil(r); -} -function defaultComparator(value, othVal) { - return value === othVal; -} -function useArrayDifference(...args) { - var _a, _b; - const list = args[0]; - const values = args[1]; - let compareFn = (_a = args[2]) != null ? _a : defaultComparator; - const { - symmetric = false - } = (_b = args[3]) != null ? _b : {}; - if (typeof compareFn === "string") { - const key = compareFn; - compareFn = (value, othVal) => value[key] === othVal[key]; - } - const diff1 = computed(() => toValue(list).filter((x) => toValue(values).findIndex((y) => compareFn(x, y)) === -1)); - if (symmetric) { - const diff2 = computed(() => toValue(values).filter((x) => toValue(list).findIndex((y) => compareFn(x, y)) === -1)); - return computed(() => symmetric ? [...toValue(diff1), ...toValue(diff2)] : toValue(diff1)); - } else { - return diff1; - } -} -function useArrayEvery(list, fn) { - return computed(() => toValue(list).every((element, index, array) => fn(toValue(element), index, array))); -} -function useArrayFilter(list, fn) { - return computed(() => toValue(list).map((i) => toValue(i)).filter(fn)); -} -function useArrayFind(list, fn) { - return computed(() => toValue( - toValue(list).find((element, index, array) => fn(toValue(element), index, array)) - )); -} -function useArrayFindIndex(list, fn) { - return computed(() => toValue(list).findIndex((element, index, array) => fn(toValue(element), index, array))); -} -function findLast(arr, cb) { - let index = arr.length; - while (index-- > 0) { - if (cb(arr[index], index, arr)) - return arr[index]; - } - return void 0; -} -function useArrayFindLast(list, fn) { - return computed(() => toValue( - !Array.prototype.findLast ? findLast(toValue(list), (element, index, array) => fn(toValue(element), index, array)) : toValue(list).findLast((element, index, array) => fn(toValue(element), index, array)) - )); -} -function isArrayIncludesOptions(obj) { - return isObject(obj) && containsProp(obj, "formIndex", "comparator"); -} -function useArrayIncludes(...args) { - var _a; - const list = args[0]; - const value = args[1]; - let comparator = args[2]; - let formIndex = 0; - if (isArrayIncludesOptions(comparator)) { - formIndex = (_a = comparator.fromIndex) != null ? _a : 0; - comparator = comparator.comparator; - } - if (typeof comparator === "string") { - const key = comparator; - comparator = (element, value2) => element[key] === toValue(value2); - } - comparator = comparator != null ? comparator : (element, value2) => element === toValue(value2); - return computed(() => toValue(list).slice(formIndex).some((element, index, array) => comparator( - toValue(element), - toValue(value), - index, - toValue(array) - ))); -} -function useArrayJoin(list, separator) { - return computed(() => toValue(list).map((i) => toValue(i)).join(toValue(separator))); -} -function useArrayMap(list, fn) { - return computed(() => toValue(list).map((i) => toValue(i)).map(fn)); -} -function useArrayReduce(list, reducer, ...args) { - const reduceCallback = (sum, value, index) => reducer(toValue(sum), toValue(value), index); - return computed(() => { - const resolved = toValue(list); - return args.length ? resolved.reduce(reduceCallback, typeof args[0] === "function" ? toValue(args[0]()) : toValue(args[0])) : resolved.reduce(reduceCallback); - }); -} -function useArraySome(list, fn) { - return computed(() => toValue(list).some((element, index, array) => fn(toValue(element), index, array))); -} -function uniq(array) { - return Array.from(new Set(array)); -} -function uniqueElementsBy(array, fn) { - return array.reduce((acc, v) => { - if (!acc.some((x) => fn(v, x, array))) - acc.push(v); - return acc; - }, []); -} -function useArrayUnique(list, compareFn) { - return computed(() => { - const resolvedList = toValue(list).map((element) => toValue(element)); - return compareFn ? uniqueElementsBy(resolvedList, compareFn) : uniq(resolvedList); - }); -} -function useCounter(initialValue = 0, options = {}) { - let _initialValue = unref(initialValue); - const count = shallowRef(initialValue); - const { - max = Number.POSITIVE_INFINITY, - min = Number.NEGATIVE_INFINITY - } = options; - const inc = (delta = 1) => count.value = Math.max(Math.min(max, count.value + delta), min); - const dec = (delta = 1) => count.value = Math.min(Math.max(min, count.value - delta), max); - const get2 = () => count.value; - const set2 = (val) => count.value = Math.max(min, Math.min(max, val)); - const reset = (val = _initialValue) => { - _initialValue = val; - return set2(val); - }; - return { count, inc, dec, get: get2, set: set2, reset }; -} -var REGEX_PARSE = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[T\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/i; -var REGEX_FORMAT = /[YMDHhms]o|\[([^\]]+)\]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a{1,2}|A{1,2}|m{1,2}|s{1,2}|Z{1,2}|z{1,4}|SSS/g; -function defaultMeridiem(hours, minutes, isLowercase, hasPeriod) { - let m = hours < 12 ? "AM" : "PM"; - if (hasPeriod) - m = m.split("").reduce((acc, curr) => acc += `${curr}.`, ""); - return isLowercase ? m.toLowerCase() : m; -} -function formatOrdinal(num) { - const suffixes = ["th", "st", "nd", "rd"]; - const v = num % 100; - return num + (suffixes[(v - 20) % 10] || suffixes[v] || suffixes[0]); -} -function formatDate(date, formatStr, options = {}) { - var _a; - const years = date.getFullYear(); - const month = date.getMonth(); - const days = date.getDate(); - const hours = date.getHours(); - const minutes = date.getMinutes(); - const seconds = date.getSeconds(); - const milliseconds = date.getMilliseconds(); - const day = date.getDay(); - const meridiem = (_a = options.customMeridiem) != null ? _a : defaultMeridiem; - const stripTimeZone = (dateString) => { - var _a2; - return (_a2 = dateString.split(" ")[1]) != null ? _a2 : ""; - }; - const matches = { - Yo: () => formatOrdinal(years), - YY: () => String(years).slice(-2), - YYYY: () => years, - M: () => month + 1, - Mo: () => formatOrdinal(month + 1), - MM: () => `${month + 1}`.padStart(2, "0"), - MMM: () => date.toLocaleDateString(toValue(options.locales), { month: "short" }), - MMMM: () => date.toLocaleDateString(toValue(options.locales), { month: "long" }), - D: () => String(days), - Do: () => formatOrdinal(days), - DD: () => `${days}`.padStart(2, "0"), - H: () => String(hours), - Ho: () => formatOrdinal(hours), - HH: () => `${hours}`.padStart(2, "0"), - h: () => `${hours % 12 || 12}`.padStart(1, "0"), - ho: () => formatOrdinal(hours % 12 || 12), - hh: () => `${hours % 12 || 12}`.padStart(2, "0"), - m: () => String(minutes), - mo: () => formatOrdinal(minutes), - mm: () => `${minutes}`.padStart(2, "0"), - s: () => String(seconds), - so: () => formatOrdinal(seconds), - ss: () => `${seconds}`.padStart(2, "0"), - SSS: () => `${milliseconds}`.padStart(3, "0"), - d: () => day, - dd: () => date.toLocaleDateString(toValue(options.locales), { weekday: "narrow" }), - ddd: () => date.toLocaleDateString(toValue(options.locales), { weekday: "short" }), - dddd: () => date.toLocaleDateString(toValue(options.locales), { weekday: "long" }), - A: () => meridiem(hours, minutes), - AA: () => meridiem(hours, minutes, false, true), - a: () => meridiem(hours, minutes, true), - aa: () => meridiem(hours, minutes, true, true), - z: () => stripTimeZone(date.toLocaleDateString(toValue(options.locales), { timeZoneName: "shortOffset" })), - zz: () => stripTimeZone(date.toLocaleDateString(toValue(options.locales), { timeZoneName: "shortOffset" })), - zzz: () => stripTimeZone(date.toLocaleDateString(toValue(options.locales), { timeZoneName: "shortOffset" })), - zzzz: () => stripTimeZone(date.toLocaleDateString(toValue(options.locales), { timeZoneName: "longOffset" })) - }; - return formatStr.replace(REGEX_FORMAT, (match, $1) => { - var _a2, _b; - return (_b = $1 != null ? $1 : (_a2 = matches[match]) == null ? void 0 : _a2.call(matches)) != null ? _b : match; - }); -} -function normalizeDate(date) { - if (date === null) - return new Date(Number.NaN); - if (date === void 0) - return /* @__PURE__ */ new Date(); - if (date instanceof Date) - return new Date(date); - if (typeof date === "string" && !/Z$/i.test(date)) { - const d = date.match(REGEX_PARSE); - if (d) { - const m = d[2] - 1 || 0; - const ms = (d[7] || "0").substring(0, 3); - return new Date(d[1], m, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms); - } - } - return new Date(date); -} -function useDateFormat(date, formatStr = "HH:mm:ss", options = {}) { - return computed(() => formatDate(normalizeDate(toValue(date)), toValue(formatStr), options)); -} -function useIntervalFn(cb, interval = 1e3, options = {}) { - const { - immediate = true, - immediateCallback = false - } = options; - let timer = null; - const isActive = shallowRef(false); - function clean() { - if (timer) { - clearInterval(timer); - timer = null; - } - } - function pause() { - isActive.value = false; - clean(); - } - function resume() { - const intervalValue = toValue(interval); - if (intervalValue <= 0) - return; - isActive.value = true; - if (immediateCallback) - cb(); - clean(); - if (isActive.value) - timer = setInterval(cb, intervalValue); - } - if (immediate && isClient) - resume(); - if (isRef(interval) || typeof interval === "function") { - const stopWatch = watch(interval, () => { - if (isActive.value && isClient) - resume(); - }); - tryOnScopeDispose(stopWatch); - } - tryOnScopeDispose(pause); - return { - isActive, - pause, - resume - }; -} -function useInterval(interval = 1e3, options = {}) { - const { - controls: exposeControls = false, - immediate = true, - callback - } = options; - const counter = shallowRef(0); - const update = () => counter.value += 1; - const reset = () => { - counter.value = 0; - }; - const controls = useIntervalFn( - callback ? () => { - update(); - callback(counter.value); - } : update, - interval, - { immediate } - ); - if (exposeControls) { - return { - counter, - reset, - ...controls - }; - } else { - return counter; - } -} -function useLastChanged(source, options = {}) { - var _a; - const ms = shallowRef((_a = options.initialValue) != null ? _a : null); - watch( - source, - () => ms.value = timestamp(), - options - ); - return ms; -} -function useTimeoutFn(cb, interval, options = {}) { - const { - immediate = true, - immediateCallback = false - } = options; - const isPending = shallowRef(false); - let timer = null; - function clear() { - if (timer) { - clearTimeout(timer); - timer = null; - } - } - function stop() { - isPending.value = false; - clear(); - } - function start(...args) { - if (immediateCallback) - cb(); - clear(); - isPending.value = true; - timer = setTimeout(() => { - isPending.value = false; - timer = null; - cb(...args); - }, toValue(interval)); - } - if (immediate) { - isPending.value = true; - if (isClient) - start(); - } - tryOnScopeDispose(stop); - return { - isPending: readonly(isPending), - start, - stop - }; -} -function useTimeout(interval = 1e3, options = {}) { - const { - controls: exposeControls = false, - callback - } = options; - const controls = useTimeoutFn( - callback != null ? callback : noop, - interval, - options - ); - const ready = computed(() => !controls.isPending.value); - if (exposeControls) { - return { - ready, - ...controls - }; - } else { - return ready; - } -} -function useToNumber(value, options = {}) { - const { - method = "parseFloat", - radix, - nanToZero - } = options; - return computed(() => { - let resolved = toValue(value); - if (typeof method === "function") - resolved = method(resolved); - else if (typeof resolved === "string") - resolved = Number[method](resolved, radix); - if (nanToZero && Number.isNaN(resolved)) - resolved = 0; - return resolved; - }); -} -function useToString(value) { - return computed(() => `${toValue(value)}`); -} -function useToggle(initialValue = false, options = {}) { - const { - truthyValue = true, - falsyValue = false - } = options; - const valueIsRef = isRef(initialValue); - const _value = shallowRef(initialValue); - function toggle(value) { - if (arguments.length) { - _value.value = value; - return _value.value; - } else { - const truthy = toValue(truthyValue); - _value.value = _value.value === truthy ? toValue(falsyValue) : truthy; - return _value.value; - } - } - if (valueIsRef) - return toggle; - else - return [_value, toggle]; -} -function watchArray(source, cb, options) { - let oldList = (options == null ? void 0 : options.immediate) ? [] : [...typeof source === "function" ? source() : Array.isArray(source) ? source : toValue(source)]; - return watch(source, (newList, _, onCleanup) => { - const oldListRemains = Array.from({ length: oldList.length }); - const added = []; - for (const obj of newList) { - let found = false; - for (let i = 0; i < oldList.length; i++) { - if (!oldListRemains[i] && obj === oldList[i]) { - oldListRemains[i] = true; - found = true; - break; - } - } - if (!found) - added.push(obj); - } - const removed = oldList.filter((_2, i) => !oldListRemains[i]); - cb(newList, oldList, added, removed, onCleanup); - oldList = [...newList]; - }, options); -} -function watchAtMost(source, cb, options) { - const { - count, - ...watchOptions - } = options; - const current = shallowRef(0); - const stop = watchWithFilter( - source, - (...args) => { - current.value += 1; - if (current.value >= toValue(count)) - nextTick(() => stop()); - cb(...args); - }, - watchOptions - ); - return { count: current, stop }; -} -function watchDebounced(source, cb, options = {}) { - const { - debounce = 0, - maxWait = void 0, - ...watchOptions - } = options; - return watchWithFilter( - source, - cb, - { - ...watchOptions, - eventFilter: debounceFilter(debounce, { maxWait }) - } - ); -} -function watchDeep(source, cb, options) { - return watch( - source, - cb, - { - ...options, - deep: true - } - ); -} -function watchIgnorable(source, cb, options = {}) { - const { - eventFilter = bypassFilter, - ...watchOptions - } = options; - const filteredCb = createFilterWrapper( - eventFilter, - cb - ); - let ignoreUpdates; - let ignorePrevAsyncUpdates; - let stop; - if (watchOptions.flush === "sync") { - const ignore = shallowRef(false); - ignorePrevAsyncUpdates = () => { - }; - ignoreUpdates = (updater) => { - ignore.value = true; - updater(); - ignore.value = false; - }; - stop = watch( - source, - (...args) => { - if (!ignore.value) - filteredCb(...args); - }, - watchOptions - ); - } else { - const disposables = []; - const ignoreCounter = shallowRef(0); - const syncCounter = shallowRef(0); - ignorePrevAsyncUpdates = () => { - ignoreCounter.value = syncCounter.value; - }; - disposables.push( - watch( - source, - () => { - syncCounter.value++; - }, - { ...watchOptions, flush: "sync" } - ) - ); - ignoreUpdates = (updater) => { - const syncCounterPrev = syncCounter.value; - updater(); - ignoreCounter.value += syncCounter.value - syncCounterPrev; - }; - disposables.push( - watch( - source, - (...args) => { - const ignore = ignoreCounter.value > 0 && ignoreCounter.value === syncCounter.value; - ignoreCounter.value = 0; - syncCounter.value = 0; - if (ignore) - return; - filteredCb(...args); - }, - watchOptions - ) - ); - stop = () => { - disposables.forEach((fn) => fn()); - }; - } - return { stop, ignoreUpdates, ignorePrevAsyncUpdates }; -} -function watchImmediate(source, cb, options) { - return watch( - source, - cb, - { - ...options, - immediate: true - } - ); -} -function watchOnce(source, cb, options) { - const stop = watch(source, (...args) => { - nextTick(() => stop()); - return cb(...args); - }, options); - return stop; -} -function watchThrottled(source, cb, options = {}) { - const { - throttle = 0, - trailing = true, - leading = true, - ...watchOptions - } = options; - return watchWithFilter( - source, - cb, - { - ...watchOptions, - eventFilter: throttleFilter(throttle, trailing, leading) - } - ); -} -function watchTriggerable(source, cb, options = {}) { - let cleanupFn; - function onEffect() { - if (!cleanupFn) - return; - const fn = cleanupFn; - cleanupFn = void 0; - fn(); - } - function onCleanup(callback) { - cleanupFn = callback; - } - const _cb = (value, oldValue) => { - onEffect(); - return cb(value, oldValue, onCleanup); - }; - const res = watchIgnorable(source, _cb, options); - const { ignoreUpdates } = res; - const trigger = () => { - let res2; - ignoreUpdates(() => { - res2 = _cb(getWatchSources(source), getOldValue(source)); - }); - return res2; - }; - return { - ...res, - trigger - }; -} -function getWatchSources(sources) { - if (isReactive(sources)) - return sources; - if (Array.isArray(sources)) - return sources.map((item) => toValue(item)); - return toValue(sources); -} -function getOldValue(source) { - return Array.isArray(source) ? source.map(() => void 0) : void 0; -} -function whenever(source, cb, options) { - const stop = watch( - source, - (v, ov, onInvalidate) => { - if (v) { - if (options == null ? void 0 : options.once) - nextTick(() => stop()); - cb(v, ov, onInvalidate); - } - }, - { - ...options, - once: false - } - ); - return stop; -} - -// node_modules/@vueuse/core/index.mjs -function computedAsync(evaluationCallback, initialState, optionsOrRef) { - let options; - if (isRef(optionsOrRef)) { - options = { - evaluating: optionsOrRef - }; - } else { - options = optionsOrRef || {}; - } - const { - lazy = false, - evaluating = void 0, - shallow = true, - onError = noop - } = options; - const started = shallowRef(!lazy); - const current = shallow ? shallowRef(initialState) : ref(initialState); - let counter = 0; - watchEffect(async (onInvalidate) => { - if (!started.value) - return; - counter++; - const counterAtBeginning = counter; - let hasFinished = false; - if (evaluating) { - Promise.resolve().then(() => { - evaluating.value = true; - }); - } - try { - const result = await evaluationCallback((cancelCallback) => { - onInvalidate(() => { - if (evaluating) - evaluating.value = false; - if (!hasFinished) - cancelCallback(); - }); - }); - if (counterAtBeginning === counter) - current.value = result; - } catch (e) { - onError(e); - } finally { - if (evaluating && counterAtBeginning === counter) - evaluating.value = false; - hasFinished = true; - } - }); - if (lazy) { - return computed(() => { - started.value = true; - return current.value; - }); - } else { - return current; - } -} -function computedInject(key, options, defaultSource, treatDefaultAsFactory) { - let source = inject(key); - if (defaultSource) - source = inject(key, defaultSource); - if (treatDefaultAsFactory) - source = inject(key, defaultSource, treatDefaultAsFactory); - if (typeof options === "function") { - return computed((ctx) => options(source, ctx)); - } else { - return computed({ - get: (ctx) => options.get(source, ctx), - set: options.set - }); - } -} -function createReusableTemplate(options = {}) { - const { - inheritAttrs = true - } = options; - const render = shallowRef(); - const define = defineComponent({ - setup(_, { slots }) { - return () => { - render.value = slots.default; - }; - } - }); - const reuse = defineComponent({ - inheritAttrs, - props: options.props, - setup(props, { attrs, slots }) { - return () => { - var _a; - if (!render.value && true) - throw new Error("[VueUse] Failed to find the definition of reusable template"); - const vnode = (_a = render.value) == null ? void 0 : _a.call(render, { - ...options.props == null ? keysToCamelKebabCase(attrs) : props, - $slots: slots - }); - return inheritAttrs && (vnode == null ? void 0 : vnode.length) === 1 ? vnode[0] : vnode; - }; - } - }); - return makeDestructurable( - { define, reuse }, - [define, reuse] - ); -} -function keysToCamelKebabCase(obj) { - const newObj = {}; - for (const key in obj) - newObj[camelize(key)] = obj[key]; - return newObj; -} -function createTemplatePromise(options = {}) { - let index = 0; - const instances = ref([]); - function create(...args) { - const props = shallowReactive({ - key: index++, - args, - promise: void 0, - resolve: () => { - }, - reject: () => { - }, - isResolving: false, - options - }); - instances.value.push(props); - props.promise = new Promise((_resolve, _reject) => { - props.resolve = (v) => { - props.isResolving = true; - return _resolve(v); - }; - props.reject = _reject; - }).finally(() => { - props.promise = void 0; - const index2 = instances.value.indexOf(props); - if (index2 !== -1) - instances.value.splice(index2, 1); - }); - return props.promise; - } - function start(...args) { - if (options.singleton && instances.value.length > 0) - return instances.value[0].promise; - return create(...args); - } - const component = defineComponent((_, { slots }) => { - const renderList = () => instances.value.map((props) => { - var _a; - return h(Fragment, { key: props.key }, (_a = slots.default) == null ? void 0 : _a.call(slots, props)); - }); - if (options.transition) - return () => h(TransitionGroup, options.transition, renderList); - return renderList; - }); - component.start = start; - return component; -} -function createUnrefFn(fn) { - return function(...args) { - return fn.apply(this, args.map((i) => toValue(i))); - }; -} -var defaultWindow = isClient ? window : void 0; -var defaultDocument = isClient ? window.document : void 0; -var defaultNavigator = isClient ? window.navigator : void 0; -var defaultLocation = isClient ? window.location : void 0; -function unrefElement(elRef) { - var _a; - const plain = toValue(elRef); - return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain; -} -function useEventListener(...args) { - const cleanups = []; - const cleanup = () => { - cleanups.forEach((fn) => fn()); - cleanups.length = 0; - }; - const register = (el, event, listener, options) => { - el.addEventListener(event, listener, options); - return () => el.removeEventListener(event, listener, options); - }; - const firstParamTargets = computed(() => { - const test = toArray(toValue(args[0])).filter((e) => e != null); - return test.every((e) => typeof e !== "string") ? test : void 0; - }); - const stopWatch = watchImmediate( - () => { - var _a, _b; - return [ - (_b = (_a = firstParamTargets.value) == null ? void 0 : _a.map((e) => unrefElement(e))) != null ? _b : [defaultWindow].filter((e) => e != null), - toArray(toValue(firstParamTargets.value ? args[1] : args[0])), - toArray(unref(firstParamTargets.value ? args[2] : args[1])), - // @ts-expect-error - TypeScript gets the correct types, but somehow still complains - toValue(firstParamTargets.value ? args[3] : args[2]) - ]; - }, - ([raw_targets, raw_events, raw_listeners, raw_options]) => { - cleanup(); - if (!(raw_targets == null ? void 0 : raw_targets.length) || !(raw_events == null ? void 0 : raw_events.length) || !(raw_listeners == null ? void 0 : raw_listeners.length)) - return; - const optionsClone = isObject(raw_options) ? { ...raw_options } : raw_options; - cleanups.push( - ...raw_targets.flatMap( - (el) => raw_events.flatMap( - (event) => raw_listeners.map((listener) => register(el, event, listener, optionsClone)) - ) - ) - ); - }, - { flush: "post" } - ); - const stop = () => { - stopWatch(); - cleanup(); - }; - tryOnScopeDispose(cleanup); - return stop; -} -var _iOSWorkaround = false; -function onClickOutside(target, handler, options = {}) { - const { window: window2 = defaultWindow, ignore = [], capture = true, detectIframe = false, controls = false } = options; - if (!window2) { - return controls ? { stop: noop, cancel: noop, trigger: noop } : noop; - } - if (isIOS && !_iOSWorkaround) { - _iOSWorkaround = true; - const listenerOptions = { passive: true }; - Array.from(window2.document.body.children).forEach((el) => useEventListener(el, "click", noop, listenerOptions)); - useEventListener(window2.document.documentElement, "click", noop, listenerOptions); - } - let shouldListen = true; - const shouldIgnore = (event) => { - return toValue(ignore).some((target2) => { - if (typeof target2 === "string") { - return Array.from(window2.document.querySelectorAll(target2)).some((el) => el === event.target || event.composedPath().includes(el)); - } else { - const el = unrefElement(target2); - return el && (event.target === el || event.composedPath().includes(el)); - } - }); - }; - function hasMultipleRoots(target2) { - const vm = toValue(target2); - return vm && vm.$.subTree.shapeFlag === 16; - } - function checkMultipleRoots(target2, event) { - const vm = toValue(target2); - const children = vm.$.subTree && vm.$.subTree.children; - if (children == null || !Array.isArray(children)) - return false; - return children.some((child) => child.el === event.target || event.composedPath().includes(child.el)); - } - const listener = (event) => { - const el = unrefElement(target); - if (event.target == null) - return; - if (!(el instanceof Element) && hasMultipleRoots(target) && checkMultipleRoots(target, event)) - return; - if (!el || el === event.target || event.composedPath().includes(el)) - return; - if ("detail" in event && event.detail === 0) - shouldListen = !shouldIgnore(event); - if (!shouldListen) { - shouldListen = true; - return; - } - handler(event); - }; - let isProcessingClick = false; - const cleanup = [ - useEventListener(window2, "click", (event) => { - if (!isProcessingClick) { - isProcessingClick = true; - setTimeout(() => { - isProcessingClick = false; - }, 0); - listener(event); - } - }, { passive: true, capture }), - useEventListener(window2, "pointerdown", (e) => { - const el = unrefElement(target); - shouldListen = !shouldIgnore(e) && !!(el && !e.composedPath().includes(el)); - }, { passive: true }), - detectIframe && useEventListener(window2, "blur", (event) => { - setTimeout(() => { - var _a; - const el = unrefElement(target); - if (((_a = window2.document.activeElement) == null ? void 0 : _a.tagName) === "IFRAME" && !(el == null ? void 0 : el.contains(window2.document.activeElement))) { - handler(event); - } - }, 0); - }, { passive: true }) - ].filter(Boolean); - const stop = () => cleanup.forEach((fn) => fn()); - if (controls) { - return { - stop, - cancel: () => { - shouldListen = false; - }, - trigger: (event) => { - shouldListen = true; - listener(event); - shouldListen = false; - } - }; - } - return stop; -} -function useMounted() { - const isMounted = shallowRef(false); - const instance = getCurrentInstance(); - if (instance) { - onMounted(() => { - isMounted.value = true; - }, instance); - } - return isMounted; -} -function useSupported(callback) { - const isMounted = useMounted(); - return computed(() => { - isMounted.value; - return Boolean(callback()); - }); -} -function useMutationObserver(target, callback, options = {}) { - const { window: window2 = defaultWindow, ...mutationOptions } = options; - let observer; - const isSupported = useSupported(() => window2 && "MutationObserver" in window2); - const cleanup = () => { - if (observer) { - observer.disconnect(); - observer = void 0; - } - }; - const targets = computed(() => { - const value = toValue(target); - const items = toArray(value).map(unrefElement).filter(notNullish); - return new Set(items); - }); - const stopWatch = watch( - () => targets.value, - (targets2) => { - cleanup(); - if (isSupported.value && targets2.size) { - observer = new MutationObserver(callback); - targets2.forEach((el) => observer.observe(el, mutationOptions)); - } - }, - { immediate: true, flush: "post" } - ); - const takeRecords = () => { - return observer == null ? void 0 : observer.takeRecords(); - }; - const stop = () => { - stopWatch(); - cleanup(); - }; - tryOnScopeDispose(stop); - return { - isSupported, - stop, - takeRecords - }; -} -function onElementRemoval(target, callback, options = {}) { - const { - window: window2 = defaultWindow, - document: document2 = window2 == null ? void 0 : window2.document, - flush = "sync" - } = options; - if (!window2 || !document2) - return noop; - let stopFn; - const cleanupAndUpdate = (fn) => { - stopFn == null ? void 0 : stopFn(); - stopFn = fn; - }; - const stopWatch = watchEffect(() => { - const el = unrefElement(target); - if (el) { - const { stop } = useMutationObserver( - document2, - (mutationsList) => { - const targetRemoved = mutationsList.map((mutation) => [...mutation.removedNodes]).flat().some((node) => node === el || node.contains(el)); - if (targetRemoved) { - callback(mutationsList); - } - }, - { - window: window2, - childList: true, - subtree: true - } - ); - cleanupAndUpdate(stop); - } - }, { flush }); - const stopHandle = () => { - stopWatch(); - cleanupAndUpdate(); - }; - tryOnScopeDispose(stopHandle); - return stopHandle; -} -function createKeyPredicate(keyFilter) { - if (typeof keyFilter === "function") - return keyFilter; - else if (typeof keyFilter === "string") - return (event) => event.key === keyFilter; - else if (Array.isArray(keyFilter)) - return (event) => keyFilter.includes(event.key); - return () => true; -} -function onKeyStroke(...args) { - let key; - let handler; - let options = {}; - if (args.length === 3) { - key = args[0]; - handler = args[1]; - options = args[2]; - } else if (args.length === 2) { - if (typeof args[1] === "object") { - key = true; - handler = args[0]; - options = args[1]; - } else { - key = args[0]; - handler = args[1]; - } - } else { - key = true; - handler = args[0]; - } - const { - target = defaultWindow, - eventName = "keydown", - passive = false, - dedupe = false - } = options; - const predicate = createKeyPredicate(key); - const listener = (e) => { - if (e.repeat && toValue(dedupe)) - return; - if (predicate(e)) - handler(e); - }; - return useEventListener(target, eventName, listener, passive); -} -function onKeyDown(key, handler, options = {}) { - return onKeyStroke(key, handler, { ...options, eventName: "keydown" }); -} -function onKeyPressed(key, handler, options = {}) { - return onKeyStroke(key, handler, { ...options, eventName: "keypress" }); -} -function onKeyUp(key, handler, options = {}) { - return onKeyStroke(key, handler, { ...options, eventName: "keyup" }); -} -var DEFAULT_DELAY = 500; -var DEFAULT_THRESHOLD = 10; -function onLongPress(target, handler, options) { - var _a, _b; - const elementRef = computed(() => unrefElement(target)); - let timeout; - let posStart; - let startTimestamp; - let hasLongPressed = false; - function clear() { - if (timeout) { - clearTimeout(timeout); - timeout = void 0; - } - posStart = void 0; - startTimestamp = void 0; - hasLongPressed = false; - } - function onRelease(ev) { - var _a2, _b2, _c; - const [_startTimestamp, _posStart, _hasLongPressed] = [startTimestamp, posStart, hasLongPressed]; - clear(); - if (!(options == null ? void 0 : options.onMouseUp) || !_posStart || !_startTimestamp) - return; - if (((_a2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _a2.self) && ev.target !== elementRef.value) - return; - if ((_b2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _b2.prevent) - ev.preventDefault(); - if ((_c = options == null ? void 0 : options.modifiers) == null ? void 0 : _c.stop) - ev.stopPropagation(); - const dx = ev.x - _posStart.x; - const dy = ev.y - _posStart.y; - const distance = Math.sqrt(dx * dx + dy * dy); - options.onMouseUp(ev.timeStamp - _startTimestamp, distance, _hasLongPressed); - } - function onDown(ev) { - var _a2, _b2, _c, _d; - if (((_a2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _a2.self) && ev.target !== elementRef.value) - return; - clear(); - if ((_b2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _b2.prevent) - ev.preventDefault(); - if ((_c = options == null ? void 0 : options.modifiers) == null ? void 0 : _c.stop) - ev.stopPropagation(); - posStart = { - x: ev.x, - y: ev.y - }; - startTimestamp = ev.timeStamp; - timeout = setTimeout( - () => { - hasLongPressed = true; - handler(ev); - }, - (_d = options == null ? void 0 : options.delay) != null ? _d : DEFAULT_DELAY - ); - } - function onMove(ev) { - var _a2, _b2, _c, _d; - if (((_a2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _a2.self) && ev.target !== elementRef.value) - return; - if (!posStart || (options == null ? void 0 : options.distanceThreshold) === false) - return; - if ((_b2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _b2.prevent) - ev.preventDefault(); - if ((_c = options == null ? void 0 : options.modifiers) == null ? void 0 : _c.stop) - ev.stopPropagation(); - const dx = ev.x - posStart.x; - const dy = ev.y - posStart.y; - const distance = Math.sqrt(dx * dx + dy * dy); - if (distance >= ((_d = options == null ? void 0 : options.distanceThreshold) != null ? _d : DEFAULT_THRESHOLD)) - clear(); - } - const listenerOptions = { - capture: (_a = options == null ? void 0 : options.modifiers) == null ? void 0 : _a.capture, - once: (_b = options == null ? void 0 : options.modifiers) == null ? void 0 : _b.once - }; - const cleanup = [ - useEventListener(elementRef, "pointerdown", onDown, listenerOptions), - useEventListener(elementRef, "pointermove", onMove, listenerOptions), - useEventListener(elementRef, ["pointerup", "pointerleave"], onRelease, listenerOptions) - ]; - const stop = () => cleanup.forEach((fn) => fn()); - return stop; -} -function isFocusedElementEditable() { - const { activeElement, body } = document; - if (!activeElement) - return false; - if (activeElement === body) - return false; - switch (activeElement.tagName) { - case "INPUT": - case "TEXTAREA": - return true; - } - return activeElement.hasAttribute("contenteditable"); -} -function isTypedCharValid({ - keyCode, - metaKey, - ctrlKey, - altKey -}) { - if (metaKey || ctrlKey || altKey) - return false; - if (keyCode >= 48 && keyCode <= 57 || keyCode >= 96 && keyCode <= 105) - return true; - if (keyCode >= 65 && keyCode <= 90) - return true; - return false; -} -function onStartTyping(callback, options = {}) { - const { document: document2 = defaultDocument } = options; - const keydown = (event) => { - if (!isFocusedElementEditable() && isTypedCharValid(event)) { - callback(event); - } - }; - if (document2) - useEventListener(document2, "keydown", keydown, { passive: true }); -} -function templateRef(key, initialValue = null) { - const instance = getCurrentInstance(); - let _trigger = () => { - }; - const element = customRef((track, trigger) => { - _trigger = trigger; - return { - get() { - var _a, _b; - track(); - return (_b = (_a = instance == null ? void 0 : instance.proxy) == null ? void 0 : _a.$refs[key]) != null ? _b : initialValue; - }, - set() { - } - }; - }); - tryOnMounted(_trigger); - onUpdated(_trigger); - return element; -} -function useActiveElement(options = {}) { - var _a; - const { - window: window2 = defaultWindow, - deep = true, - triggerOnRemoval = false - } = options; - const document2 = (_a = options.document) != null ? _a : window2 == null ? void 0 : window2.document; - const getDeepActiveElement = () => { - var _a2; - let element = document2 == null ? void 0 : document2.activeElement; - if (deep) { - while (element == null ? void 0 : element.shadowRoot) - element = (_a2 = element == null ? void 0 : element.shadowRoot) == null ? void 0 : _a2.activeElement; - } - return element; - }; - const activeElement = shallowRef(); - const trigger = () => { - activeElement.value = getDeepActiveElement(); - }; - if (window2) { - const listenerOptions = { - capture: true, - passive: true - }; - useEventListener( - window2, - "blur", - (event) => { - if (event.relatedTarget !== null) - return; - trigger(); - }, - listenerOptions - ); - useEventListener( - window2, - "focus", - trigger, - listenerOptions - ); - } - if (triggerOnRemoval) { - onElementRemoval(activeElement, trigger, { document: document2 }); - } - trigger(); - return activeElement; -} -function useRafFn(fn, options = {}) { - const { - immediate = true, - fpsLimit = void 0, - window: window2 = defaultWindow, - once = false - } = options; - const isActive = shallowRef(false); - const intervalLimit = computed(() => { - return fpsLimit ? 1e3 / toValue(fpsLimit) : null; - }); - let previousFrameTimestamp = 0; - let rafId = null; - function loop(timestamp2) { - if (!isActive.value || !window2) - return; - if (!previousFrameTimestamp) - previousFrameTimestamp = timestamp2; - const delta = timestamp2 - previousFrameTimestamp; - if (intervalLimit.value && delta < intervalLimit.value) { - rafId = window2.requestAnimationFrame(loop); - return; - } - previousFrameTimestamp = timestamp2; - fn({ delta, timestamp: timestamp2 }); - if (once) { - isActive.value = false; - rafId = null; - return; - } - rafId = window2.requestAnimationFrame(loop); - } - function resume() { - if (!isActive.value && window2) { - isActive.value = true; - previousFrameTimestamp = 0; - rafId = window2.requestAnimationFrame(loop); - } - } - function pause() { - isActive.value = false; - if (rafId != null && window2) { - window2.cancelAnimationFrame(rafId); - rafId = null; - } - } - if (immediate) - resume(); - tryOnScopeDispose(pause); - return { - isActive: readonly(isActive), - pause, - resume - }; -} -function useAnimate(target, keyframes, options) { - let config; - let animateOptions; - if (isObject(options)) { - config = options; - animateOptions = objectOmit(options, ["window", "immediate", "commitStyles", "persist", "onReady", "onError"]); - } else { - config = { duration: options }; - animateOptions = options; - } - const { - window: window2 = defaultWindow, - immediate = true, - commitStyles, - persist, - playbackRate: _playbackRate = 1, - onReady, - onError = (e) => { - console.error(e); - } - } = config; - const isSupported = useSupported(() => window2 && HTMLElement && "animate" in HTMLElement.prototype); - const animate = shallowRef(void 0); - const store = shallowReactive({ - startTime: null, - currentTime: null, - timeline: null, - playbackRate: _playbackRate, - pending: false, - playState: immediate ? "idle" : "paused", - replaceState: "active" - }); - const pending = computed(() => store.pending); - const playState = computed(() => store.playState); - const replaceState = computed(() => store.replaceState); - const startTime = computed({ - get() { - return store.startTime; - }, - set(value) { - store.startTime = value; - if (animate.value) - animate.value.startTime = value; - } - }); - const currentTime = computed({ - get() { - return store.currentTime; - }, - set(value) { - store.currentTime = value; - if (animate.value) { - animate.value.currentTime = value; - syncResume(); - } - } - }); - const timeline = computed({ - get() { - return store.timeline; - }, - set(value) { - store.timeline = value; - if (animate.value) - animate.value.timeline = value; - } - }); - const playbackRate = computed({ - get() { - return store.playbackRate; - }, - set(value) { - store.playbackRate = value; - if (animate.value) - animate.value.playbackRate = value; - } - }); - const play = () => { - if (animate.value) { - try { - animate.value.play(); - syncResume(); - } catch (e) { - syncPause(); - onError(e); - } - } else { - update(); - } - }; - const pause = () => { - var _a; - try { - (_a = animate.value) == null ? void 0 : _a.pause(); - syncPause(); - } catch (e) { - onError(e); - } - }; - const reverse = () => { - var _a; - if (!animate.value) - update(); - try { - (_a = animate.value) == null ? void 0 : _a.reverse(); - syncResume(); - } catch (e) { - syncPause(); - onError(e); - } - }; - const finish = () => { - var _a; - try { - (_a = animate.value) == null ? void 0 : _a.finish(); - syncPause(); - } catch (e) { - onError(e); - } - }; - const cancel = () => { - var _a; - try { - (_a = animate.value) == null ? void 0 : _a.cancel(); - syncPause(); - } catch (e) { - onError(e); - } - }; - watch(() => unrefElement(target), (el) => { - if (el) { - update(); - } else { - animate.value = void 0; - } - }); - watch(() => keyframes, (value) => { - if (animate.value) { - update(); - const targetEl = unrefElement(target); - if (targetEl) { - animate.value.effect = new KeyframeEffect( - targetEl, - toValue(value), - animateOptions - ); - } - } - }, { deep: true }); - tryOnMounted(() => update(true), false); - tryOnScopeDispose(cancel); - function update(init) { - const el = unrefElement(target); - if (!isSupported.value || !el) - return; - if (!animate.value) - animate.value = el.animate(toValue(keyframes), animateOptions); - if (persist) - animate.value.persist(); - if (_playbackRate !== 1) - animate.value.playbackRate = _playbackRate; - if (init && !immediate) - animate.value.pause(); - else - syncResume(); - onReady == null ? void 0 : onReady(animate.value); - } - const listenerOptions = { passive: true }; - useEventListener(animate, ["cancel", "finish", "remove"], syncPause, listenerOptions); - useEventListener(animate, "finish", () => { - var _a; - if (commitStyles) - (_a = animate.value) == null ? void 0 : _a.commitStyles(); - }, listenerOptions); - const { resume: resumeRef, pause: pauseRef } = useRafFn(() => { - if (!animate.value) - return; - store.pending = animate.value.pending; - store.playState = animate.value.playState; - store.replaceState = animate.value.replaceState; - store.startTime = animate.value.startTime; - store.currentTime = animate.value.currentTime; - store.timeline = animate.value.timeline; - store.playbackRate = animate.value.playbackRate; - }, { immediate: false }); - function syncResume() { - if (isSupported.value) - resumeRef(); - } - function syncPause() { - if (isSupported.value && window2) - window2.requestAnimationFrame(pauseRef); - } - return { - isSupported, - animate, - // actions - play, - pause, - reverse, - finish, - cancel, - // state - pending, - playState, - replaceState, - startTime, - currentTime, - timeline, - playbackRate - }; -} -function useAsyncQueue(tasks, options) { - const { - interrupt = true, - onError = noop, - onFinished = noop, - signal - } = options || {}; - const promiseState = { - aborted: "aborted", - fulfilled: "fulfilled", - pending: "pending", - rejected: "rejected" - }; - const initialResult = Array.from(Array.from({ length: tasks.length }), () => ({ state: promiseState.pending, data: null })); - const result = reactive(initialResult); - const activeIndex = shallowRef(-1); - if (!tasks || tasks.length === 0) { - onFinished(); - return { - activeIndex, - result - }; - } - function updateResult(state, res) { - activeIndex.value++; - result[activeIndex.value].data = res; - result[activeIndex.value].state = state; - } - tasks.reduce((prev, curr) => { - return prev.then((prevRes) => { - var _a; - if (signal == null ? void 0 : signal.aborted) { - updateResult(promiseState.aborted, new Error("aborted")); - return; - } - if (((_a = result[activeIndex.value]) == null ? void 0 : _a.state) === promiseState.rejected && interrupt) { - onFinished(); - return; - } - const done = curr(prevRes).then((currentRes) => { - updateResult(promiseState.fulfilled, currentRes); - if (activeIndex.value === tasks.length - 1) - onFinished(); - return currentRes; - }); - if (!signal) - return done; - return Promise.race([done, whenAborted(signal)]); - }).catch((e) => { - if (signal == null ? void 0 : signal.aborted) { - updateResult(promiseState.aborted, e); - return e; - } - updateResult(promiseState.rejected, e); - onError(); - return e; - }); - }, Promise.resolve()); - return { - activeIndex, - result - }; -} -function whenAborted(signal) { - return new Promise((resolve, reject) => { - const error = new Error("aborted"); - if (signal.aborted) - reject(error); - else - signal.addEventListener("abort", () => reject(error), { once: true }); - }); -} -function useAsyncState(promise, initialState, options) { - const { - immediate = true, - delay = 0, - onError = noop, - onSuccess = noop, - resetOnExecute = true, - shallow = true, - throwError - } = options != null ? options : {}; - const state = shallow ? shallowRef(initialState) : ref(initialState); - const isReady = shallowRef(false); - const isLoading = shallowRef(false); - const error = shallowRef(void 0); - async function execute(delay2 = 0, ...args) { - if (resetOnExecute) - state.value = initialState; - error.value = void 0; - isReady.value = false; - isLoading.value = true; - if (delay2 > 0) - await promiseTimeout(delay2); - const _promise = typeof promise === "function" ? promise(...args) : promise; - try { - const data = await _promise; - state.value = data; - isReady.value = true; - onSuccess(data); - } catch (e) { - error.value = e; - onError(e); - if (throwError) - throw e; - } finally { - isLoading.value = false; - } - return state.value; - } - if (immediate) { - execute(delay); - } - const shell = { - state, - isReady, - isLoading, - error, - execute - }; - function waitUntilIsLoaded() { - return new Promise((resolve, reject) => { - until(isLoading).toBe(false).then(() => resolve(shell)).catch(reject); - }); - } - return { - ...shell, - then(onFulfilled, onRejected) { - return waitUntilIsLoaded().then(onFulfilled, onRejected); - } - }; -} -var defaults = { - array: (v) => JSON.stringify(v), - object: (v) => JSON.stringify(v), - set: (v) => JSON.stringify(Array.from(v)), - map: (v) => JSON.stringify(Object.fromEntries(v)), - null: () => "" -}; -function getDefaultSerialization(target) { - if (!target) - return defaults.null; - if (target instanceof Map) - return defaults.map; - else if (target instanceof Set) - return defaults.set; - else if (Array.isArray(target)) - return defaults.array; - else - return defaults.object; -} -function useBase64(target, options) { - const base64 = shallowRef(""); - const promise = shallowRef(); - function execute() { - if (!isClient) - return; - promise.value = new Promise((resolve, reject) => { - try { - const _target = toValue(target); - if (_target == null) { - resolve(""); - } else if (typeof _target === "string") { - resolve(blobToBase64(new Blob([_target], { type: "text/plain" }))); - } else if (_target instanceof Blob) { - resolve(blobToBase64(_target)); - } else if (_target instanceof ArrayBuffer) { - resolve(window.btoa(String.fromCharCode(...new Uint8Array(_target)))); - } else if (_target instanceof HTMLCanvasElement) { - resolve(_target.toDataURL(options == null ? void 0 : options.type, options == null ? void 0 : options.quality)); - } else if (_target instanceof HTMLImageElement) { - const img = _target.cloneNode(false); - img.crossOrigin = "Anonymous"; - imgLoaded(img).then(() => { - const canvas = document.createElement("canvas"); - const ctx = canvas.getContext("2d"); - canvas.width = img.width; - canvas.height = img.height; - ctx.drawImage(img, 0, 0, canvas.width, canvas.height); - resolve(canvas.toDataURL(options == null ? void 0 : options.type, options == null ? void 0 : options.quality)); - }).catch(reject); - } else if (typeof _target === "object") { - const _serializeFn = (options == null ? void 0 : options.serializer) || getDefaultSerialization(_target); - const serialized = _serializeFn(_target); - return resolve(blobToBase64(new Blob([serialized], { type: "application/json" }))); - } else { - reject(new Error("target is unsupported types")); - } - } catch (error) { - reject(error); - } - }); - promise.value.then((res) => { - base64.value = (options == null ? void 0 : options.dataUrl) === false ? res.replace(/^data:.*?;base64,/, "") : res; - }); - return promise.value; - } - if (isRef(target) || typeof target === "function") - watch(target, execute, { immediate: true }); - else - execute(); - return { - base64, - promise, - execute - }; -} -function imgLoaded(img) { - return new Promise((resolve, reject) => { - if (!img.complete) { - img.onload = () => { - resolve(); - }; - img.onerror = reject; - } else { - resolve(); - } - }); -} -function blobToBase64(blob) { - return new Promise((resolve, reject) => { - const fr = new FileReader(); - fr.onload = (e) => { - resolve(e.target.result); - }; - fr.onerror = reject; - fr.readAsDataURL(blob); - }); -} -function useBattery(options = {}) { - const { navigator: navigator2 = defaultNavigator } = options; - const events2 = ["chargingchange", "chargingtimechange", "dischargingtimechange", "levelchange"]; - const isSupported = useSupported(() => navigator2 && "getBattery" in navigator2 && typeof navigator2.getBattery === "function"); - const charging = shallowRef(false); - const chargingTime = shallowRef(0); - const dischargingTime = shallowRef(0); - const level = shallowRef(1); - let battery; - function updateBatteryInfo() { - charging.value = this.charging; - chargingTime.value = this.chargingTime || 0; - dischargingTime.value = this.dischargingTime || 0; - level.value = this.level; - } - if (isSupported.value) { - navigator2.getBattery().then((_battery) => { - battery = _battery; - updateBatteryInfo.call(battery); - useEventListener(battery, events2, updateBatteryInfo, { passive: true }); - }); - } - return { - isSupported, - charging, - chargingTime, - dischargingTime, - level - }; -} -function useBluetooth(options) { - let { - acceptAllDevices = false - } = options || {}; - const { - filters = void 0, - optionalServices = void 0, - navigator: navigator2 = defaultNavigator - } = options || {}; - const isSupported = useSupported(() => navigator2 && "bluetooth" in navigator2); - const device = shallowRef(); - const error = shallowRef(null); - watch(device, () => { - connectToBluetoothGATTServer(); - }); - async function requestDevice() { - if (!isSupported.value) - return; - error.value = null; - if (filters && filters.length > 0) - acceptAllDevices = false; - try { - device.value = await (navigator2 == null ? void 0 : navigator2.bluetooth.requestDevice({ - acceptAllDevices, - filters, - optionalServices - })); - } catch (err) { - error.value = err; - } - } - const server = shallowRef(); - const isConnected = shallowRef(false); - function reset() { - isConnected.value = false; - device.value = void 0; - server.value = void 0; - } - async function connectToBluetoothGATTServer() { - error.value = null; - if (device.value && device.value.gatt) { - useEventListener(device, "gattserverdisconnected", reset, { passive: true }); - try { - server.value = await device.value.gatt.connect(); - isConnected.value = server.value.connected; - } catch (err) { - error.value = err; - } - } - } - tryOnMounted(() => { - var _a; - if (device.value) - (_a = device.value.gatt) == null ? void 0 : _a.connect(); - }); - tryOnScopeDispose(() => { - var _a; - if (device.value) - (_a = device.value.gatt) == null ? void 0 : _a.disconnect(); - }); - return { - isSupported, - isConnected: readonly(isConnected), - // Device: - device, - requestDevice, - // Server: - server, - // Errors: - error - }; -} -var ssrWidthSymbol = Symbol("vueuse-ssr-width"); -function useSSRWidth() { - const ssrWidth = hasInjectionContext() ? injectLocal(ssrWidthSymbol, null) : null; - return typeof ssrWidth === "number" ? ssrWidth : void 0; -} -function provideSSRWidth(width, app) { - if (app !== void 0) { - app.provide(ssrWidthSymbol, width); - } else { - provideLocal(ssrWidthSymbol, width); - } -} -function useMediaQuery(query, options = {}) { - const { window: window2 = defaultWindow, ssrWidth = useSSRWidth() } = options; - const isSupported = useSupported(() => window2 && "matchMedia" in window2 && typeof window2.matchMedia === "function"); - const ssrSupport = shallowRef(typeof ssrWidth === "number"); - const mediaQuery = shallowRef(); - const matches = shallowRef(false); - const handler = (event) => { - matches.value = event.matches; - }; - watchEffect(() => { - if (ssrSupport.value) { - ssrSupport.value = !isSupported.value; - const queryStrings = toValue(query).split(","); - matches.value = queryStrings.some((queryString) => { - const not = queryString.includes("not all"); - const minWidth = queryString.match(/\(\s*min-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/); - const maxWidth = queryString.match(/\(\s*max-width:\s*(-?\d+(?:\.\d*)?[a-z]+\s*)\)/); - let res = Boolean(minWidth || maxWidth); - if (minWidth && res) { - res = ssrWidth >= pxValue(minWidth[1]); - } - if (maxWidth && res) { - res = ssrWidth <= pxValue(maxWidth[1]); - } - return not ? !res : res; - }); - return; - } - if (!isSupported.value) - return; - mediaQuery.value = window2.matchMedia(toValue(query)); - matches.value = mediaQuery.value.matches; - }); - useEventListener(mediaQuery, "change", handler, { passive: true }); - return computed(() => matches.value); -} -var breakpointsTailwind = { - "sm": 640, - "md": 768, - "lg": 1024, - "xl": 1280, - "2xl": 1536 -}; -var breakpointsBootstrapV5 = { - xs: 0, - sm: 576, - md: 768, - lg: 992, - xl: 1200, - xxl: 1400 -}; -var breakpointsVuetifyV2 = { - xs: 0, - sm: 600, - md: 960, - lg: 1264, - xl: 1904 -}; -var breakpointsVuetifyV3 = { - xs: 0, - sm: 600, - md: 960, - lg: 1280, - xl: 1920, - xxl: 2560 -}; -var breakpointsVuetify = breakpointsVuetifyV2; -var breakpointsAntDesign = { - xs: 480, - sm: 576, - md: 768, - lg: 992, - xl: 1200, - xxl: 1600 -}; -var breakpointsQuasar = { - xs: 0, - sm: 600, - md: 1024, - lg: 1440, - xl: 1920 -}; -var breakpointsSematic = { - mobileS: 320, - mobileM: 375, - mobileL: 425, - tablet: 768, - laptop: 1024, - laptopL: 1440, - desktop4K: 2560 -}; -var breakpointsMasterCss = { - "3xs": 360, - "2xs": 480, - "xs": 600, - "sm": 768, - "md": 1024, - "lg": 1280, - "xl": 1440, - "2xl": 1600, - "3xl": 1920, - "4xl": 2560 -}; -var breakpointsPrimeFlex = { - sm: 576, - md: 768, - lg: 992, - xl: 1200 -}; -var breakpointsElement = { - xs: 0, - sm: 768, - md: 992, - lg: 1200, - xl: 1920 -}; -function useBreakpoints(breakpoints, options = {}) { - function getValue2(k, delta) { - let v = toValue(breakpoints[toValue(k)]); - if (delta != null) - v = increaseWithUnit(v, delta); - if (typeof v === "number") - v = `${v}px`; - return v; - } - const { window: window2 = defaultWindow, strategy = "min-width", ssrWidth = useSSRWidth() } = options; - const ssrSupport = typeof ssrWidth === "number"; - const mounted = ssrSupport ? shallowRef(false) : { value: true }; - if (ssrSupport) { - tryOnMounted(() => mounted.value = !!window2); - } - function match(query, size) { - if (!mounted.value && ssrSupport) { - return query === "min" ? ssrWidth >= pxValue(size) : ssrWidth <= pxValue(size); - } - if (!window2) - return false; - return window2.matchMedia(`(${query}-width: ${size})`).matches; - } - const greaterOrEqual = (k) => { - return useMediaQuery(() => `(min-width: ${getValue2(k)})`, options); - }; - const smallerOrEqual = (k) => { - return useMediaQuery(() => `(max-width: ${getValue2(k)})`, options); - }; - const shortcutMethods = Object.keys(breakpoints).reduce((shortcuts, k) => { - Object.defineProperty(shortcuts, k, { - get: () => strategy === "min-width" ? greaterOrEqual(k) : smallerOrEqual(k), - enumerable: true, - configurable: true - }); - return shortcuts; - }, {}); - function current() { - const points = Object.keys(breakpoints).map((k) => [k, shortcutMethods[k], pxValue(getValue2(k))]).sort((a, b) => a[2] - b[2]); - return computed(() => points.filter(([, v]) => v.value).map(([k]) => k)); - } - return Object.assign(shortcutMethods, { - greaterOrEqual, - smallerOrEqual, - greater(k) { - return useMediaQuery(() => `(min-width: ${getValue2(k, 0.1)})`, options); - }, - smaller(k) { - return useMediaQuery(() => `(max-width: ${getValue2(k, -0.1)})`, options); - }, - between(a, b) { - return useMediaQuery(() => `(min-width: ${getValue2(a)}) and (max-width: ${getValue2(b, -0.1)})`, options); - }, - isGreater(k) { - return match("min", getValue2(k, 0.1)); - }, - isGreaterOrEqual(k) { - return match("min", getValue2(k)); - }, - isSmaller(k) { - return match("max", getValue2(k, -0.1)); - }, - isSmallerOrEqual(k) { - return match("max", getValue2(k)); - }, - isInBetween(a, b) { - return match("min", getValue2(a)) && match("max", getValue2(b, -0.1)); - }, - current, - active() { - const bps = current(); - return computed(() => bps.value.length === 0 ? "" : bps.value.at(strategy === "min-width" ? -1 : 0)); - } - }); -} -function useBroadcastChannel(options) { - const { - name, - window: window2 = defaultWindow - } = options; - const isSupported = useSupported(() => window2 && "BroadcastChannel" in window2); - const isClosed = shallowRef(false); - const channel = ref(); - const data = ref(); - const error = shallowRef(null); - const post = (data2) => { - if (channel.value) - channel.value.postMessage(data2); - }; - const close = () => { - if (channel.value) - channel.value.close(); - isClosed.value = true; - }; - if (isSupported.value) { - tryOnMounted(() => { - error.value = null; - channel.value = new BroadcastChannel(name); - const listenerOptions = { - passive: true - }; - useEventListener(channel, "message", (e) => { - data.value = e.data; - }, listenerOptions); - useEventListener(channel, "messageerror", (e) => { - error.value = e; - }, listenerOptions); - useEventListener(channel, "close", () => { - isClosed.value = true; - }, listenerOptions); - }); - } - tryOnScopeDispose(() => { - close(); - }); - return { - isSupported, - channel, - data, - post, - close, - error, - isClosed - }; -} -var WRITABLE_PROPERTIES = [ - "hash", - "host", - "hostname", - "href", - "pathname", - "port", - "protocol", - "search" -]; -function useBrowserLocation(options = {}) { - const { window: window2 = defaultWindow } = options; - const refs = Object.fromEntries( - WRITABLE_PROPERTIES.map((key) => [key, ref()]) - ); - for (const [key, ref2] of objectEntries(refs)) { - watch(ref2, (value) => { - if (!(window2 == null ? void 0 : window2.location) || window2.location[key] === value) - return; - window2.location[key] = value; - }); - } - const buildState = (trigger) => { - var _a; - const { state: state2, length } = (window2 == null ? void 0 : window2.history) || {}; - const { origin } = (window2 == null ? void 0 : window2.location) || {}; - for (const key of WRITABLE_PROPERTIES) - refs[key].value = (_a = window2 == null ? void 0 : window2.location) == null ? void 0 : _a[key]; - return reactive({ - trigger, - state: state2, - length, - origin, - ...refs - }); - }; - const state = ref(buildState("load")); - if (window2) { - const listenerOptions = { passive: true }; - useEventListener(window2, "popstate", () => state.value = buildState("popstate"), listenerOptions); - useEventListener(window2, "hashchange", () => state.value = buildState("hashchange"), listenerOptions); - } - return state; -} -function useCached(refValue, comparator = (a, b) => a === b, options) { - const { deepRefs = true, ...watchOptions } = options || {}; - const cachedValue = createRef(refValue.value, deepRefs); - watch(() => refValue.value, (value) => { - if (!comparator(value, cachedValue.value)) - cachedValue.value = value; - }, watchOptions); - return cachedValue; -} -function usePermission(permissionDesc, options = {}) { - const { - controls = false, - navigator: navigator2 = defaultNavigator - } = options; - const isSupported = useSupported(() => navigator2 && "permissions" in navigator2); - const permissionStatus = shallowRef(); - const desc = typeof permissionDesc === "string" ? { name: permissionDesc } : permissionDesc; - const state = shallowRef(); - const update = () => { - var _a, _b; - state.value = (_b = (_a = permissionStatus.value) == null ? void 0 : _a.state) != null ? _b : "prompt"; - }; - useEventListener(permissionStatus, "change", update, { passive: true }); - const query = createSingletonPromise(async () => { - if (!isSupported.value) - return; - if (!permissionStatus.value) { - try { - permissionStatus.value = await navigator2.permissions.query(desc); - } catch (e) { - permissionStatus.value = void 0; - } finally { - update(); - } - } - if (controls) - return toRaw(permissionStatus.value); - }); - query(); - if (controls) { - return { - state, - isSupported, - query - }; - } else { - return state; - } -} -function useClipboard(options = {}) { - const { - navigator: navigator2 = defaultNavigator, - read = false, - source, - copiedDuring = 1500, - legacy = false - } = options; - const isClipboardApiSupported = useSupported(() => navigator2 && "clipboard" in navigator2); - const permissionRead = usePermission("clipboard-read"); - const permissionWrite = usePermission("clipboard-write"); - const isSupported = computed(() => isClipboardApiSupported.value || legacy); - const text = shallowRef(""); - const copied = shallowRef(false); - const timeout = useTimeoutFn(() => copied.value = false, copiedDuring, { immediate: false }); - async function updateText() { - let useLegacy = !(isClipboardApiSupported.value && isAllowed(permissionRead.value)); - if (!useLegacy) { - try { - text.value = await navigator2.clipboard.readText(); - } catch (e) { - useLegacy = true; - } - } - if (useLegacy) { - text.value = legacyRead(); - } - } - if (isSupported.value && read) - useEventListener(["copy", "cut"], updateText, { passive: true }); - async function copy(value = toValue(source)) { - if (isSupported.value && value != null) { - let useLegacy = !(isClipboardApiSupported.value && isAllowed(permissionWrite.value)); - if (!useLegacy) { - try { - await navigator2.clipboard.writeText(value); - } catch (e) { - useLegacy = true; - } - } - if (useLegacy) - legacyCopy(value); - text.value = value; - copied.value = true; - timeout.start(); - } - } - function legacyCopy(value) { - const ta = document.createElement("textarea"); - ta.value = value != null ? value : ""; - ta.style.position = "absolute"; - ta.style.opacity = "0"; - document.body.appendChild(ta); - ta.select(); - document.execCommand("copy"); - ta.remove(); - } - function legacyRead() { - var _a, _b, _c; - return (_c = (_b = (_a = document == null ? void 0 : document.getSelection) == null ? void 0 : _a.call(document)) == null ? void 0 : _b.toString()) != null ? _c : ""; - } - function isAllowed(status) { - return status === "granted" || status === "prompt"; - } - return { - isSupported, - text, - copied, - copy - }; -} -function useClipboardItems(options = {}) { - const { - navigator: navigator2 = defaultNavigator, - read = false, - source, - copiedDuring = 1500 - } = options; - const isSupported = useSupported(() => navigator2 && "clipboard" in navigator2); - const content = ref([]); - const copied = shallowRef(false); - const timeout = useTimeoutFn(() => copied.value = false, copiedDuring, { immediate: false }); - function updateContent() { - if (isSupported.value) { - navigator2.clipboard.read().then((items) => { - content.value = items; - }); - } - } - if (isSupported.value && read) - useEventListener(["copy", "cut"], updateContent, { passive: true }); - async function copy(value = toValue(source)) { - if (isSupported.value && value != null) { - await navigator2.clipboard.write(value); - content.value = value; - copied.value = true; - timeout.start(); - } - } - return { - isSupported, - content, - copied, - copy - }; -} -function cloneFnJSON(source) { - return JSON.parse(JSON.stringify(source)); -} -function useCloned(source, options = {}) { - const cloned = ref({}); - const isModified = shallowRef(false); - let _lastSync = false; - const { - manual, - clone = cloneFnJSON, - // watch options - deep = true, - immediate = true - } = options; - watch(cloned, () => { - if (_lastSync) { - _lastSync = false; - return; - } - isModified.value = true; - }, { - deep: true, - flush: "sync" - }); - function sync() { - _lastSync = true; - isModified.value = false; - cloned.value = clone(toValue(source)); - } - if (!manual && (isRef(source) || typeof source === "function")) { - watch(source, sync, { - ...options, - deep, - immediate - }); - } else { - sync(); - } - return { cloned, isModified, sync }; -} -var _global = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {}; -var globalKey = "__vueuse_ssr_handlers__"; -var handlers = getHandlers(); -function getHandlers() { - if (!(globalKey in _global)) - _global[globalKey] = _global[globalKey] || {}; - return _global[globalKey]; -} -function getSSRHandler(key, fallback) { - return handlers[key] || fallback; -} -function setSSRHandler(key, fn) { - handlers[key] = fn; -} -function usePreferredDark(options) { - return useMediaQuery("(prefers-color-scheme: dark)", options); -} -function guessSerializerType(rawInit) { - return rawInit == null ? "any" : rawInit instanceof Set ? "set" : rawInit instanceof Map ? "map" : rawInit instanceof Date ? "date" : typeof rawInit === "boolean" ? "boolean" : typeof rawInit === "string" ? "string" : typeof rawInit === "object" ? "object" : !Number.isNaN(rawInit) ? "number" : "any"; -} -var StorageSerializers = { - boolean: { - read: (v) => v === "true", - write: (v) => String(v) - }, - object: { - read: (v) => JSON.parse(v), - write: (v) => JSON.stringify(v) - }, - number: { - read: (v) => Number.parseFloat(v), - write: (v) => String(v) - }, - any: { - read: (v) => v, - write: (v) => String(v) - }, - string: { - read: (v) => v, - write: (v) => String(v) - }, - map: { - read: (v) => new Map(JSON.parse(v)), - write: (v) => JSON.stringify(Array.from(v.entries())) - }, - set: { - read: (v) => new Set(JSON.parse(v)), - write: (v) => JSON.stringify(Array.from(v)) - }, - date: { - read: (v) => new Date(v), - write: (v) => v.toISOString() - } -}; -var customStorageEventName = "vueuse-storage"; -function useStorage(key, defaults2, storage, options = {}) { - var _a; - const { - flush = "pre", - deep = true, - listenToStorageChanges = true, - writeDefaults = true, - mergeDefaults = false, - shallow, - window: window2 = defaultWindow, - eventFilter, - onError = (e) => { - console.error(e); - }, - initOnMounted - } = options; - const data = (shallow ? shallowRef : ref)(typeof defaults2 === "function" ? defaults2() : defaults2); - const keyComputed = computed(() => toValue(key)); - if (!storage) { - try { - storage = getSSRHandler("getDefaultStorage", () => { - var _a2; - return (_a2 = defaultWindow) == null ? void 0 : _a2.localStorage; - })(); - } catch (e) { - onError(e); - } - } - if (!storage) - return data; - const rawInit = toValue(defaults2); - const type = guessSerializerType(rawInit); - const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type]; - const { pause: pauseWatch, resume: resumeWatch } = watchPausable( - data, - () => write(data.value), - { flush, deep, eventFilter } - ); - watch(keyComputed, () => update(), { flush }); - if (window2 && listenToStorageChanges) { - tryOnMounted(() => { - if (storage instanceof Storage) - useEventListener(window2, "storage", update, { passive: true }); - else - useEventListener(window2, customStorageEventName, updateFromCustomEvent); - if (initOnMounted) - update(); - }); - } - if (!initOnMounted) - update(); - function dispatchWriteEvent(oldValue, newValue) { - if (window2) { - const payload = { - key: keyComputed.value, - oldValue, - newValue, - storageArea: storage - }; - window2.dispatchEvent(storage instanceof Storage ? new StorageEvent("storage", payload) : new CustomEvent(customStorageEventName, { - detail: payload - })); - } - } - function write(v) { - try { - const oldValue = storage.getItem(keyComputed.value); - if (v == null) { - dispatchWriteEvent(oldValue, null); - storage.removeItem(keyComputed.value); - } else { - const serialized = serializer.write(v); - if (oldValue !== serialized) { - storage.setItem(keyComputed.value, serialized); - dispatchWriteEvent(oldValue, serialized); - } - } - } catch (e) { - onError(e); - } - } - function read(event) { - const rawValue = event ? event.newValue : storage.getItem(keyComputed.value); - if (rawValue == null) { - if (writeDefaults && rawInit != null) - storage.setItem(keyComputed.value, serializer.write(rawInit)); - return rawInit; - } else if (!event && mergeDefaults) { - const value = serializer.read(rawValue); - if (typeof mergeDefaults === "function") - return mergeDefaults(value, rawInit); - else if (type === "object" && !Array.isArray(value)) - return { ...rawInit, ...value }; - return value; - } else if (typeof rawValue !== "string") { - return rawValue; - } else { - return serializer.read(rawValue); - } - } - function update(event) { - if (event && event.storageArea !== storage) - return; - if (event && event.key == null) { - data.value = rawInit; - return; - } - if (event && event.key !== keyComputed.value) - return; - pauseWatch(); - try { - if ((event == null ? void 0 : event.newValue) !== serializer.write(data.value)) - data.value = read(event); - } catch (e) { - onError(e); - } finally { - if (event) - nextTick(resumeWatch); - else - resumeWatch(); - } - } - function updateFromCustomEvent(event) { - update(event.detail); - } - return data; -} -var CSS_DISABLE_TRANS = "*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}"; -function useColorMode(options = {}) { - const { - selector = "html", - attribute = "class", - initialValue = "auto", - window: window2 = defaultWindow, - storage, - storageKey = "vueuse-color-scheme", - listenToStorageChanges = true, - storageRef, - emitAuto, - disableTransition = true - } = options; - const modes = { - auto: "", - light: "light", - dark: "dark", - ...options.modes || {} - }; - const preferredDark = usePreferredDark({ window: window2 }); - const system = computed(() => preferredDark.value ? "dark" : "light"); - const store = storageRef || (storageKey == null ? toRef2(initialValue) : useStorage(storageKey, initialValue, storage, { window: window2, listenToStorageChanges })); - const state = computed(() => store.value === "auto" ? system.value : store.value); - const updateHTMLAttrs = getSSRHandler( - "updateHTMLAttrs", - (selector2, attribute2, value) => { - const el = typeof selector2 === "string" ? window2 == null ? void 0 : window2.document.querySelector(selector2) : unrefElement(selector2); - if (!el) - return; - const classesToAdd = /* @__PURE__ */ new Set(); - const classesToRemove = /* @__PURE__ */ new Set(); - let attributeToChange = null; - if (attribute2 === "class") { - const current = value.split(/\s/g); - Object.values(modes).flatMap((i) => (i || "").split(/\s/g)).filter(Boolean).forEach((v) => { - if (current.includes(v)) - classesToAdd.add(v); - else - classesToRemove.add(v); - }); - } else { - attributeToChange = { key: attribute2, value }; - } - if (classesToAdd.size === 0 && classesToRemove.size === 0 && attributeToChange === null) - return; - let style; - if (disableTransition) { - style = window2.document.createElement("style"); - style.appendChild(document.createTextNode(CSS_DISABLE_TRANS)); - window2.document.head.appendChild(style); - } - for (const c of classesToAdd) { - el.classList.add(c); - } - for (const c of classesToRemove) { - el.classList.remove(c); - } - if (attributeToChange) { - el.setAttribute(attributeToChange.key, attributeToChange.value); - } - if (disableTransition) { - window2.getComputedStyle(style).opacity; - document.head.removeChild(style); - } - } - ); - function defaultOnChanged(mode) { - var _a; - updateHTMLAttrs(selector, attribute, (_a = modes[mode]) != null ? _a : mode); - } - function onChanged(mode) { - if (options.onChanged) - options.onChanged(mode, defaultOnChanged); - else - defaultOnChanged(mode); - } - watch(state, onChanged, { flush: "post", immediate: true }); - tryOnMounted(() => onChanged(state.value)); - const auto = computed({ - get() { - return emitAuto ? store.value : state.value; - }, - set(v) { - store.value = v; - } - }); - return Object.assign(auto, { store, system, state }); -} -function useConfirmDialog(revealed = shallowRef(false)) { - const confirmHook = createEventHook(); - const cancelHook = createEventHook(); - const revealHook = createEventHook(); - let _resolve = noop; - const reveal = (data) => { - revealHook.trigger(data); - revealed.value = true; - return new Promise((resolve) => { - _resolve = resolve; - }); - }; - const confirm = (data) => { - revealed.value = false; - confirmHook.trigger(data); - _resolve({ data, isCanceled: false }); - }; - const cancel = (data) => { - revealed.value = false; - cancelHook.trigger(data); - _resolve({ data, isCanceled: true }); - }; - return { - isRevealed: computed(() => revealed.value), - reveal, - confirm, - cancel, - onReveal: revealHook.on, - onConfirm: confirmHook.on, - onCancel: cancelHook.on - }; -} -function useCountdown(initialCountdown, options) { - var _a, _b; - const remaining = shallowRef(toValue(initialCountdown)); - const intervalController = useIntervalFn(() => { - var _a2, _b2; - const value = remaining.value - 1; - remaining.value = value < 0 ? 0 : value; - (_a2 = options == null ? void 0 : options.onTick) == null ? void 0 : _a2.call(options); - if (remaining.value <= 0) { - intervalController.pause(); - (_b2 = options == null ? void 0 : options.onComplete) == null ? void 0 : _b2.call(options); - } - }, (_a = options == null ? void 0 : options.interval) != null ? _a : 1e3, { immediate: (_b = options == null ? void 0 : options.immediate) != null ? _b : false }); - const reset = (countdown) => { - var _a2; - remaining.value = (_a2 = toValue(countdown)) != null ? _a2 : toValue(initialCountdown); - }; - const stop = () => { - intervalController.pause(); - reset(); - }; - const resume = () => { - if (!intervalController.isActive.value) { - if (remaining.value > 0) { - intervalController.resume(); - } - } - }; - const start = (countdown) => { - reset(countdown); - intervalController.resume(); - }; - return { - remaining, - reset, - stop, - start, - pause: intervalController.pause, - resume, - isActive: intervalController.isActive - }; -} -function useCssVar(prop, target, options = {}) { - const { window: window2 = defaultWindow, initialValue, observe = false } = options; - const variable = shallowRef(initialValue); - const elRef = computed(() => { - var _a; - return unrefElement(target) || ((_a = window2 == null ? void 0 : window2.document) == null ? void 0 : _a.documentElement); - }); - function updateCssVar() { - var _a; - const key = toValue(prop); - const el = toValue(elRef); - if (el && window2 && key) { - const value = (_a = window2.getComputedStyle(el).getPropertyValue(key)) == null ? void 0 : _a.trim(); - variable.value = value || variable.value || initialValue; - } - } - if (observe) { - useMutationObserver(elRef, updateCssVar, { - attributeFilter: ["style", "class"], - window: window2 - }); - } - watch( - [elRef, () => toValue(prop)], - (_, old) => { - if (old[0] && old[1]) - old[0].style.removeProperty(old[1]); - updateCssVar(); - }, - { immediate: true } - ); - watch( - [variable, elRef], - ([val, el]) => { - const raw_prop = toValue(prop); - if ((el == null ? void 0 : el.style) && raw_prop) { - if (val == null) - el.style.removeProperty(raw_prop); - else - el.style.setProperty(raw_prop, val); - } - }, - { immediate: true } - ); - return variable; -} -function useCurrentElement(rootComponent) { - const vm = getCurrentInstance(); - const currentElement = computedWithControl( - () => null, - () => rootComponent ? unrefElement(rootComponent) : vm.proxy.$el - ); - onUpdated(currentElement.trigger); - onMounted(currentElement.trigger); - return currentElement; -} -function useCycleList(list, options) { - const state = shallowRef(getInitialValue()); - const listRef = toRef2(list); - const index = computed({ - get() { - var _a; - const targetList = listRef.value; - let index2 = (options == null ? void 0 : options.getIndexOf) ? options.getIndexOf(state.value, targetList) : targetList.indexOf(state.value); - if (index2 < 0) - index2 = (_a = options == null ? void 0 : options.fallbackIndex) != null ? _a : 0; - return index2; - }, - set(v) { - set2(v); - } - }); - function set2(i) { - const targetList = listRef.value; - const length = targetList.length; - const index2 = (i % length + length) % length; - const value = targetList[index2]; - state.value = value; - return value; - } - function shift(delta = 1) { - return set2(index.value + delta); - } - function next(n = 1) { - return shift(n); - } - function prev(n = 1) { - return shift(-n); - } - function getInitialValue() { - var _a, _b; - return (_b = toValue((_a = options == null ? void 0 : options.initialValue) != null ? _a : toValue(list)[0])) != null ? _b : void 0; - } - watch(listRef, () => set2(index.value)); - return { - state, - index, - next, - prev, - go: set2 - }; -} -function useDark(options = {}) { - const { - valueDark = "dark", - valueLight = "" - } = options; - const mode = useColorMode({ - ...options, - onChanged: (mode2, defaultHandler) => { - var _a; - if (options.onChanged) - (_a = options.onChanged) == null ? void 0 : _a.call(options, mode2 === "dark", defaultHandler, mode2); - else - defaultHandler(mode2); - }, - modes: { - dark: valueDark, - light: valueLight - } - }); - const system = computed(() => mode.system.value); - const isDark = computed({ - get() { - return mode.value === "dark"; - }, - set(v) { - const modeVal = v ? "dark" : "light"; - if (system.value === modeVal) - mode.value = "auto"; - else - mode.value = modeVal; - } - }); - return isDark; -} -function fnBypass(v) { - return v; -} -function fnSetSource(source, value) { - return source.value = value; -} -function defaultDump(clone) { - return clone ? typeof clone === "function" ? clone : cloneFnJSON : fnBypass; -} -function defaultParse(clone) { - return clone ? typeof clone === "function" ? clone : cloneFnJSON : fnBypass; -} -function useManualRefHistory(source, options = {}) { - const { - clone = false, - dump = defaultDump(clone), - parse = defaultParse(clone), - setSource = fnSetSource - } = options; - function _createHistoryRecord() { - return markRaw({ - snapshot: dump(source.value), - timestamp: timestamp() - }); - } - const last = ref(_createHistoryRecord()); - const undoStack = ref([]); - const redoStack = ref([]); - const _setSource = (record) => { - setSource(source, parse(record.snapshot)); - last.value = record; - }; - const commit = () => { - undoStack.value.unshift(last.value); - last.value = _createHistoryRecord(); - if (options.capacity && undoStack.value.length > options.capacity) - undoStack.value.splice(options.capacity, Number.POSITIVE_INFINITY); - if (redoStack.value.length) - redoStack.value.splice(0, redoStack.value.length); - }; - const clear = () => { - undoStack.value.splice(0, undoStack.value.length); - redoStack.value.splice(0, redoStack.value.length); - }; - const undo = () => { - const state = undoStack.value.shift(); - if (state) { - redoStack.value.unshift(last.value); - _setSource(state); - } - }; - const redo = () => { - const state = redoStack.value.shift(); - if (state) { - undoStack.value.unshift(last.value); - _setSource(state); - } - }; - const reset = () => { - _setSource(last.value); - }; - const history = computed(() => [last.value, ...undoStack.value]); - const canUndo = computed(() => undoStack.value.length > 0); - const canRedo = computed(() => redoStack.value.length > 0); - return { - source, - undoStack, - redoStack, - last, - history, - canUndo, - canRedo, - clear, - commit, - reset, - undo, - redo - }; -} -function useRefHistory(source, options = {}) { - const { - deep = false, - flush = "pre", - eventFilter - } = options; - const { - eventFilter: composedFilter, - pause, - resume: resumeTracking, - isActive: isTracking - } = pausableFilter(eventFilter); - const { - ignoreUpdates, - ignorePrevAsyncUpdates, - stop - } = watchIgnorable( - source, - commit, - { deep, flush, eventFilter: composedFilter } - ); - function setSource(source2, value) { - ignorePrevAsyncUpdates(); - ignoreUpdates(() => { - source2.value = value; - }); - } - const manualHistory = useManualRefHistory(source, { ...options, clone: options.clone || deep, setSource }); - const { clear, commit: manualCommit } = manualHistory; - function commit() { - ignorePrevAsyncUpdates(); - manualCommit(); - } - function resume(commitNow) { - resumeTracking(); - if (commitNow) - commit(); - } - function batch(fn) { - let canceled = false; - const cancel = () => canceled = true; - ignoreUpdates(() => { - fn(cancel); - }); - if (!canceled) - commit(); - } - function dispose() { - stop(); - clear(); - } - return { - ...manualHistory, - isTracking, - pause, - resume, - commit, - batch, - dispose - }; -} -function useDebouncedRefHistory(source, options = {}) { - const filter = options.debounce ? debounceFilter(options.debounce) : void 0; - const history = useRefHistory(source, { ...options, eventFilter: filter }); - return { - ...history - }; -} -function useDeviceMotion(options = {}) { - const { - window: window2 = defaultWindow, - requestPermissions = false, - eventFilter = bypassFilter - } = options; - const isSupported = useSupported(() => typeof DeviceMotionEvent !== "undefined"); - const requirePermissions = useSupported(() => isSupported.value && "requestPermission" in DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === "function"); - const permissionGranted = shallowRef(false); - const acceleration = ref({ x: null, y: null, z: null }); - const rotationRate = ref({ alpha: null, beta: null, gamma: null }); - const interval = shallowRef(0); - const accelerationIncludingGravity = ref({ - x: null, - y: null, - z: null - }); - function init() { - if (window2) { - const onDeviceMotion = createFilterWrapper( - eventFilter, - (event) => { - var _a, _b, _c, _d, _e, _f, _g, _h, _i; - acceleration.value = { - x: ((_a = event.acceleration) == null ? void 0 : _a.x) || null, - y: ((_b = event.acceleration) == null ? void 0 : _b.y) || null, - z: ((_c = event.acceleration) == null ? void 0 : _c.z) || null - }; - accelerationIncludingGravity.value = { - x: ((_d = event.accelerationIncludingGravity) == null ? void 0 : _d.x) || null, - y: ((_e = event.accelerationIncludingGravity) == null ? void 0 : _e.y) || null, - z: ((_f = event.accelerationIncludingGravity) == null ? void 0 : _f.z) || null - }; - rotationRate.value = { - alpha: ((_g = event.rotationRate) == null ? void 0 : _g.alpha) || null, - beta: ((_h = event.rotationRate) == null ? void 0 : _h.beta) || null, - gamma: ((_i = event.rotationRate) == null ? void 0 : _i.gamma) || null - }; - interval.value = event.interval; - } - ); - useEventListener(window2, "devicemotion", onDeviceMotion, { passive: true }); - } - } - const ensurePermissions = async () => { - if (!requirePermissions.value) - permissionGranted.value = true; - if (permissionGranted.value) - return; - if (requirePermissions.value) { - const requestPermission = DeviceMotionEvent.requestPermission; - try { - const response = await requestPermission(); - if (response === "granted") { - permissionGranted.value = true; - init(); - } - } catch (error) { - console.error(error); - } - } - }; - if (isSupported.value) { - if (requestPermissions && requirePermissions.value) { - ensurePermissions().then(() => init()); - } else { - init(); - } - } - return { - acceleration, - accelerationIncludingGravity, - rotationRate, - interval, - isSupported, - requirePermissions, - ensurePermissions, - permissionGranted - }; -} -function useDeviceOrientation(options = {}) { - const { window: window2 = defaultWindow } = options; - const isSupported = useSupported(() => window2 && "DeviceOrientationEvent" in window2); - const isAbsolute = shallowRef(false); - const alpha = shallowRef(null); - const beta = shallowRef(null); - const gamma = shallowRef(null); - if (window2 && isSupported.value) { - useEventListener(window2, "deviceorientation", (event) => { - isAbsolute.value = event.absolute; - alpha.value = event.alpha; - beta.value = event.beta; - gamma.value = event.gamma; - }, { passive: true }); - } - return { - isSupported, - isAbsolute, - alpha, - beta, - gamma - }; -} -function useDevicePixelRatio(options = {}) { - const { - window: window2 = defaultWindow - } = options; - const pixelRatio = shallowRef(1); - const query = useMediaQuery(() => `(resolution: ${pixelRatio.value}dppx)`, options); - let stop = noop; - if (window2) { - stop = watchImmediate(query, () => pixelRatio.value = window2.devicePixelRatio); - } - return { - pixelRatio: readonly(pixelRatio), - stop - }; -} -function useDevicesList(options = {}) { - const { - navigator: navigator2 = defaultNavigator, - requestPermissions = false, - constraints = { audio: true, video: true }, - onUpdated: onUpdated2 - } = options; - const devices = ref([]); - const videoInputs = computed(() => devices.value.filter((i) => i.kind === "videoinput")); - const audioInputs = computed(() => devices.value.filter((i) => i.kind === "audioinput")); - const audioOutputs = computed(() => devices.value.filter((i) => i.kind === "audiooutput")); - const isSupported = useSupported(() => navigator2 && navigator2.mediaDevices && navigator2.mediaDevices.enumerateDevices); - const permissionGranted = shallowRef(false); - let stream; - async function update() { - if (!isSupported.value) - return; - devices.value = await navigator2.mediaDevices.enumerateDevices(); - onUpdated2 == null ? void 0 : onUpdated2(devices.value); - if (stream) { - stream.getTracks().forEach((t) => t.stop()); - stream = null; - } - } - async function ensurePermissions() { - const deviceName = constraints.video ? "camera" : "microphone"; - if (!isSupported.value) - return false; - if (permissionGranted.value) - return true; - const { state, query } = usePermission(deviceName, { controls: true }); - await query(); - if (state.value !== "granted") { - let granted = true; - try { - stream = await navigator2.mediaDevices.getUserMedia(constraints); - } catch (e) { - stream = null; - granted = false; - } - update(); - permissionGranted.value = granted; - } else { - permissionGranted.value = true; - } - return permissionGranted.value; - } - if (isSupported.value) { - if (requestPermissions) - ensurePermissions(); - useEventListener(navigator2.mediaDevices, "devicechange", update, { passive: true }); - update(); - } - return { - devices, - ensurePermissions, - permissionGranted, - videoInputs, - audioInputs, - audioOutputs, - isSupported - }; -} -function useDisplayMedia(options = {}) { - var _a; - const enabled = shallowRef((_a = options.enabled) != null ? _a : false); - const video = options.video; - const audio = options.audio; - const { navigator: navigator2 = defaultNavigator } = options; - const isSupported = useSupported(() => { - var _a2; - return (_a2 = navigator2 == null ? void 0 : navigator2.mediaDevices) == null ? void 0 : _a2.getDisplayMedia; - }); - const constraint = { audio, video }; - const stream = shallowRef(); - async function _start() { - var _a2; - if (!isSupported.value || stream.value) - return; - stream.value = await navigator2.mediaDevices.getDisplayMedia(constraint); - (_a2 = stream.value) == null ? void 0 : _a2.getTracks().forEach((t) => useEventListener(t, "ended", stop, { passive: true })); - return stream.value; - } - async function _stop() { - var _a2; - (_a2 = stream.value) == null ? void 0 : _a2.getTracks().forEach((t) => t.stop()); - stream.value = void 0; - } - function stop() { - _stop(); - enabled.value = false; - } - async function start() { - await _start(); - if (stream.value) - enabled.value = true; - return stream.value; - } - watch( - enabled, - (v) => { - if (v) - _start(); - else - _stop(); - }, - { immediate: true } - ); - return { - isSupported, - stream, - start, - stop, - enabled - }; -} -function useDocumentVisibility(options = {}) { - const { document: document2 = defaultDocument } = options; - if (!document2) - return shallowRef("visible"); - const visibility = shallowRef(document2.visibilityState); - useEventListener(document2, "visibilitychange", () => { - visibility.value = document2.visibilityState; - }, { passive: true }); - return visibility; -} -function useDraggable(target, options = {}) { - var _a; - const { - pointerTypes, - preventDefault: preventDefault2, - stopPropagation, - exact, - onMove, - onEnd, - onStart, - initialValue, - axis = "both", - draggingElement = defaultWindow, - containerElement, - handle: draggingHandle = target, - buttons = [0] - } = options; - const position = ref( - (_a = toValue(initialValue)) != null ? _a : { x: 0, y: 0 } - ); - const pressedDelta = ref(); - const filterEvent = (e) => { - if (pointerTypes) - return pointerTypes.includes(e.pointerType); - return true; - }; - const handleEvent = (e) => { - if (toValue(preventDefault2)) - e.preventDefault(); - if (toValue(stopPropagation)) - e.stopPropagation(); - }; - const start = (e) => { - var _a2; - if (!toValue(buttons).includes(e.button)) - return; - if (toValue(options.disabled) || !filterEvent(e)) - return; - if (toValue(exact) && e.target !== toValue(target)) - return; - const container = toValue(containerElement); - const containerRect = (_a2 = container == null ? void 0 : container.getBoundingClientRect) == null ? void 0 : _a2.call(container); - const targetRect = toValue(target).getBoundingClientRect(); - const pos = { - x: e.clientX - (container ? targetRect.left - containerRect.left + container.scrollLeft : targetRect.left), - y: e.clientY - (container ? targetRect.top - containerRect.top + container.scrollTop : targetRect.top) - }; - if ((onStart == null ? void 0 : onStart(pos, e)) === false) - return; - pressedDelta.value = pos; - handleEvent(e); - }; - const move = (e) => { - if (toValue(options.disabled) || !filterEvent(e)) - return; - if (!pressedDelta.value) - return; - const container = toValue(containerElement); - const targetRect = toValue(target).getBoundingClientRect(); - let { x, y } = position.value; - if (axis === "x" || axis === "both") { - x = e.clientX - pressedDelta.value.x; - if (container) - x = Math.min(Math.max(0, x), container.scrollWidth - targetRect.width); - } - if (axis === "y" || axis === "both") { - y = e.clientY - pressedDelta.value.y; - if (container) - y = Math.min(Math.max(0, y), container.scrollHeight - targetRect.height); - } - position.value = { - x, - y - }; - onMove == null ? void 0 : onMove(position.value, e); - handleEvent(e); - }; - const end = (e) => { - if (toValue(options.disabled) || !filterEvent(e)) - return; - if (!pressedDelta.value) - return; - pressedDelta.value = void 0; - onEnd == null ? void 0 : onEnd(position.value, e); - handleEvent(e); - }; - if (isClient) { - const config = () => { - var _a2; - return { - capture: (_a2 = options.capture) != null ? _a2 : true, - passive: !toValue(preventDefault2) - }; - }; - useEventListener(draggingHandle, "pointerdown", start, config); - useEventListener(draggingElement, "pointermove", move, config); - useEventListener(draggingElement, "pointerup", end, config); - } - return { - ...toRefs2(position), - position, - isDragging: computed(() => !!pressedDelta.value), - style: computed( - () => `left:${position.value.x}px;top:${position.value.y}px;` - ) - }; -} -function useDropZone(target, options = {}) { - var _a, _b; - const isOverDropZone = shallowRef(false); - const files = shallowRef(null); - let counter = 0; - let isValid = true; - if (isClient) { - const _options = typeof options === "function" ? { onDrop: options } : options; - const multiple = (_a = _options.multiple) != null ? _a : true; - const preventDefaultForUnhandled = (_b = _options.preventDefaultForUnhandled) != null ? _b : false; - const getFiles = (event) => { - var _a2, _b2; - const list = Array.from((_b2 = (_a2 = event.dataTransfer) == null ? void 0 : _a2.files) != null ? _b2 : []); - return list.length === 0 ? null : multiple ? list : [list[0]]; - }; - const checkDataTypes = (types) => { - const dataTypes = unref(_options.dataTypes); - if (typeof dataTypes === "function") - return dataTypes(types); - if (!(dataTypes == null ? void 0 : dataTypes.length)) - return true; - if (types.length === 0) - return false; - return types.every( - (type) => dataTypes.some((allowedType) => type.includes(allowedType)) - ); - }; - const checkValidity = (items) => { - const types = Array.from(items != null ? items : []).map((item) => item.type); - const dataTypesValid = checkDataTypes(types); - const multipleFilesValid = multiple || items.length <= 1; - return dataTypesValid && multipleFilesValid; - }; - const isSafari = () => /^(?:(?!chrome|android).)*safari/i.test(navigator.userAgent) && !("chrome" in window); - const handleDragEvent = (event, eventType) => { - var _a2, _b2, _c, _d, _e, _f; - const dataTransferItemList = (_a2 = event.dataTransfer) == null ? void 0 : _a2.items; - isValid = (_b2 = dataTransferItemList && checkValidity(dataTransferItemList)) != null ? _b2 : false; - if (preventDefaultForUnhandled) { - event.preventDefault(); - } - if (!isSafari() && !isValid) { - if (event.dataTransfer) { - event.dataTransfer.dropEffect = "none"; - } - return; - } - event.preventDefault(); - if (event.dataTransfer) { - event.dataTransfer.dropEffect = "copy"; - } - const currentFiles = getFiles(event); - switch (eventType) { - case "enter": - counter += 1; - isOverDropZone.value = true; - (_c = _options.onEnter) == null ? void 0 : _c.call(_options, null, event); - break; - case "over": - (_d = _options.onOver) == null ? void 0 : _d.call(_options, null, event); - break; - case "leave": - counter -= 1; - if (counter === 0) - isOverDropZone.value = false; - (_e = _options.onLeave) == null ? void 0 : _e.call(_options, null, event); - break; - case "drop": - counter = 0; - isOverDropZone.value = false; - if (isValid) { - files.value = currentFiles; - (_f = _options.onDrop) == null ? void 0 : _f.call(_options, currentFiles, event); - } - break; - } - }; - useEventListener(target, "dragenter", (event) => handleDragEvent(event, "enter")); - useEventListener(target, "dragover", (event) => handleDragEvent(event, "over")); - useEventListener(target, "dragleave", (event) => handleDragEvent(event, "leave")); - useEventListener(target, "drop", (event) => handleDragEvent(event, "drop")); - } - return { - files, - isOverDropZone - }; -} -function useResizeObserver(target, callback, options = {}) { - const { window: window2 = defaultWindow, ...observerOptions } = options; - let observer; - const isSupported = useSupported(() => window2 && "ResizeObserver" in window2); - const cleanup = () => { - if (observer) { - observer.disconnect(); - observer = void 0; - } - }; - const targets = computed(() => { - const _targets = toValue(target); - return Array.isArray(_targets) ? _targets.map((el) => unrefElement(el)) : [unrefElement(_targets)]; - }); - const stopWatch = watch( - targets, - (els) => { - cleanup(); - if (isSupported.value && window2) { - observer = new ResizeObserver(callback); - for (const _el of els) { - if (_el) - observer.observe(_el, observerOptions); - } - } - }, - { immediate: true, flush: "post" } - ); - const stop = () => { - cleanup(); - stopWatch(); - }; - tryOnScopeDispose(stop); - return { - isSupported, - stop - }; -} -function useElementBounding(target, options = {}) { - const { - reset = true, - windowResize = true, - windowScroll = true, - immediate = true, - updateTiming = "sync" - } = options; - const height = shallowRef(0); - const bottom = shallowRef(0); - const left = shallowRef(0); - const right = shallowRef(0); - const top = shallowRef(0); - const width = shallowRef(0); - const x = shallowRef(0); - const y = shallowRef(0); - function recalculate() { - const el = unrefElement(target); - if (!el) { - if (reset) { - height.value = 0; - bottom.value = 0; - left.value = 0; - right.value = 0; - top.value = 0; - width.value = 0; - x.value = 0; - y.value = 0; - } - return; - } - const rect = el.getBoundingClientRect(); - height.value = rect.height; - bottom.value = rect.bottom; - left.value = rect.left; - right.value = rect.right; - top.value = rect.top; - width.value = rect.width; - x.value = rect.x; - y.value = rect.y; - } - function update() { - if (updateTiming === "sync") - recalculate(); - else if (updateTiming === "next-frame") - requestAnimationFrame(() => recalculate()); - } - useResizeObserver(target, update); - watch(() => unrefElement(target), (ele) => !ele && update()); - useMutationObserver(target, update, { - attributeFilter: ["style", "class"] - }); - if (windowScroll) - useEventListener("scroll", update, { capture: true, passive: true }); - if (windowResize) - useEventListener("resize", update, { passive: true }); - tryOnMounted(() => { - if (immediate) - update(); - }); - return { - height, - bottom, - left, - right, - top, - width, - x, - y, - update - }; -} -function useElementByPoint(options) { - const { - x, - y, - document: document2 = defaultDocument, - multiple, - interval = "requestAnimationFrame", - immediate = true - } = options; - const isSupported = useSupported(() => { - if (toValue(multiple)) - return document2 && "elementsFromPoint" in document2; - return document2 && "elementFromPoint" in document2; - }); - const element = shallowRef(null); - const cb = () => { - var _a, _b; - element.value = toValue(multiple) ? (_a = document2 == null ? void 0 : document2.elementsFromPoint(toValue(x), toValue(y))) != null ? _a : [] : (_b = document2 == null ? void 0 : document2.elementFromPoint(toValue(x), toValue(y))) != null ? _b : null; - }; - const controls = interval === "requestAnimationFrame" ? useRafFn(cb, { immediate }) : useIntervalFn(cb, interval, { immediate }); - return { - isSupported, - element, - ...controls - }; -} -function useElementHover(el, options = {}) { - const { - delayEnter = 0, - delayLeave = 0, - triggerOnRemoval = false, - window: window2 = defaultWindow - } = options; - const isHovered = shallowRef(false); - let timer; - const toggle = (entering) => { - const delay = entering ? delayEnter : delayLeave; - if (timer) { - clearTimeout(timer); - timer = void 0; - } - if (delay) - timer = setTimeout(() => isHovered.value = entering, delay); - else - isHovered.value = entering; - }; - if (!window2) - return isHovered; - useEventListener(el, "mouseenter", () => toggle(true), { passive: true }); - useEventListener(el, "mouseleave", () => toggle(false), { passive: true }); - if (triggerOnRemoval) { - onElementRemoval( - computed(() => unrefElement(el)), - () => toggle(false) - ); - } - return isHovered; -} -function useElementSize(target, initialSize = { width: 0, height: 0 }, options = {}) { - const { window: window2 = defaultWindow, box = "content-box" } = options; - const isSVG = computed(() => { - var _a, _b; - return (_b = (_a = unrefElement(target)) == null ? void 0 : _a.namespaceURI) == null ? void 0 : _b.includes("svg"); - }); - const width = shallowRef(initialSize.width); - const height = shallowRef(initialSize.height); - const { stop: stop1 } = useResizeObserver( - target, - ([entry]) => { - const boxSize = box === "border-box" ? entry.borderBoxSize : box === "content-box" ? entry.contentBoxSize : entry.devicePixelContentBoxSize; - if (window2 && isSVG.value) { - const $elem = unrefElement(target); - if ($elem) { - const rect = $elem.getBoundingClientRect(); - width.value = rect.width; - height.value = rect.height; - } - } else { - if (boxSize) { - const formatBoxSize = toArray(boxSize); - width.value = formatBoxSize.reduce((acc, { inlineSize }) => acc + inlineSize, 0); - height.value = formatBoxSize.reduce((acc, { blockSize }) => acc + blockSize, 0); - } else { - width.value = entry.contentRect.width; - height.value = entry.contentRect.height; - } - } - }, - options - ); - tryOnMounted(() => { - const ele = unrefElement(target); - if (ele) { - width.value = "offsetWidth" in ele ? ele.offsetWidth : initialSize.width; - height.value = "offsetHeight" in ele ? ele.offsetHeight : initialSize.height; - } - }); - const stop2 = watch( - () => unrefElement(target), - (ele) => { - width.value = ele ? initialSize.width : 0; - height.value = ele ? initialSize.height : 0; - } - ); - function stop() { - stop1(); - stop2(); - } - return { - width, - height, - stop - }; -} -function useIntersectionObserver(target, callback, options = {}) { - const { - root, - rootMargin = "0px", - threshold = 0, - window: window2 = defaultWindow, - immediate = true - } = options; - const isSupported = useSupported(() => window2 && "IntersectionObserver" in window2); - const targets = computed(() => { - const _target = toValue(target); - return toArray(_target).map(unrefElement).filter(notNullish); - }); - let cleanup = noop; - const isActive = shallowRef(immediate); - const stopWatch = isSupported.value ? watch( - () => [targets.value, unrefElement(root), isActive.value], - ([targets2, root2]) => { - cleanup(); - if (!isActive.value) - return; - if (!targets2.length) - return; - const observer = new IntersectionObserver( - callback, - { - root: unrefElement(root2), - rootMargin, - threshold - } - ); - targets2.forEach((el) => el && observer.observe(el)); - cleanup = () => { - observer.disconnect(); - cleanup = noop; - }; - }, - { immediate, flush: "post" } - ) : noop; - const stop = () => { - cleanup(); - stopWatch(); - isActive.value = false; - }; - tryOnScopeDispose(stop); - return { - isSupported, - isActive, - pause() { - cleanup(); - isActive.value = false; - }, - resume() { - isActive.value = true; - }, - stop - }; -} -function useElementVisibility(element, options = {}) { - const { - window: window2 = defaultWindow, - scrollTarget, - threshold = 0, - rootMargin, - once = false - } = options; - const elementIsVisible = shallowRef(false); - const { stop } = useIntersectionObserver( - element, - (intersectionObserverEntries) => { - let isIntersecting = elementIsVisible.value; - let latestTime = 0; - for (const entry of intersectionObserverEntries) { - if (entry.time >= latestTime) { - latestTime = entry.time; - isIntersecting = entry.isIntersecting; - } - } - elementIsVisible.value = isIntersecting; - if (once) { - watchOnce(elementIsVisible, () => { - stop(); - }); - } - }, - { - root: scrollTarget, - window: window2, - threshold, - rootMargin: toValue(rootMargin) - } - ); - return elementIsVisible; -} -var events = /* @__PURE__ */ new Map(); -function useEventBus(key) { - const scope = getCurrentScope(); - function on(listener) { - var _a; - const listeners = events.get(key) || /* @__PURE__ */ new Set(); - listeners.add(listener); - events.set(key, listeners); - const _off = () => off(listener); - (_a = scope == null ? void 0 : scope.cleanups) == null ? void 0 : _a.push(_off); - return _off; - } - function once(listener) { - function _listener(...args) { - off(_listener); - listener(...args); - } - return on(_listener); - } - function off(listener) { - const listeners = events.get(key); - if (!listeners) - return; - listeners.delete(listener); - if (!listeners.size) - reset(); - } - function reset() { - events.delete(key); - } - function emit(event, payload) { - var _a; - (_a = events.get(key)) == null ? void 0 : _a.forEach((v) => v(event, payload)); - } - return { on, once, off, emit, reset }; -} -function resolveNestedOptions$1(options) { - if (options === true) - return {}; - return options; -} -function useEventSource(url, events2 = [], options = {}) { - const event = shallowRef(null); - const data = shallowRef(null); - const status = shallowRef("CONNECTING"); - const eventSource = ref(null); - const error = shallowRef(null); - const urlRef = toRef2(url); - const lastEventId = shallowRef(null); - let explicitlyClosed = false; - let retried = 0; - const { - withCredentials = false, - immediate = true, - autoConnect = true, - autoReconnect - } = options; - const close = () => { - if (isClient && eventSource.value) { - eventSource.value.close(); - eventSource.value = null; - status.value = "CLOSED"; - explicitlyClosed = true; - } - }; - const _init = () => { - if (explicitlyClosed || typeof urlRef.value === "undefined") - return; - const es = new EventSource(urlRef.value, { withCredentials }); - status.value = "CONNECTING"; - eventSource.value = es; - es.onopen = () => { - status.value = "OPEN"; - error.value = null; - }; - es.onerror = (e) => { - status.value = "CLOSED"; - error.value = e; - if (es.readyState === 2 && !explicitlyClosed && autoReconnect) { - es.close(); - const { - retries = -1, - delay = 1e3, - onFailed - } = resolveNestedOptions$1(autoReconnect); - retried += 1; - if (typeof retries === "number" && (retries < 0 || retried < retries)) - setTimeout(_init, delay); - else if (typeof retries === "function" && retries()) - setTimeout(_init, delay); - else - onFailed == null ? void 0 : onFailed(); - } - }; - es.onmessage = (e) => { - event.value = null; - data.value = e.data; - lastEventId.value = e.lastEventId; - }; - for (const event_name of events2) { - useEventListener(es, event_name, (e) => { - event.value = event_name; - data.value = e.data || null; - }, { passive: true }); - } - }; - const open = () => { - if (!isClient) - return; - close(); - explicitlyClosed = false; - retried = 0; - _init(); - }; - if (immediate) - open(); - if (autoConnect) - watch(urlRef, open); - tryOnScopeDispose(close); - return { - eventSource, - event, - data, - status, - error, - open, - close, - lastEventId - }; -} -function useEyeDropper(options = {}) { - const { initialValue = "" } = options; - const isSupported = useSupported(() => typeof window !== "undefined" && "EyeDropper" in window); - const sRGBHex = shallowRef(initialValue); - async function open(openOptions) { - if (!isSupported.value) - return; - const eyeDropper = new window.EyeDropper(); - const result = await eyeDropper.open(openOptions); - sRGBHex.value = result.sRGBHex; - return result; - } - return { isSupported, sRGBHex, open }; -} -function useFavicon(newIcon = null, options = {}) { - const { - baseUrl = "", - rel = "icon", - document: document2 = defaultDocument - } = options; - const favicon = toRef2(newIcon); - const applyIcon = (icon) => { - const elements = document2 == null ? void 0 : document2.head.querySelectorAll(`link[rel*="${rel}"]`); - if (!elements || elements.length === 0) { - const link = document2 == null ? void 0 : document2.createElement("link"); - if (link) { - link.rel = rel; - link.href = `${baseUrl}${icon}`; - link.type = `image/${icon.split(".").pop()}`; - document2 == null ? void 0 : document2.head.append(link); - } - return; - } - elements == null ? void 0 : elements.forEach((el) => el.href = `${baseUrl}${icon}`); - }; - watch( - favicon, - (i, o) => { - if (typeof i === "string" && i !== o) - applyIcon(i); - }, - { immediate: true } - ); - return favicon; -} -var payloadMapping = { - json: "application/json", - text: "text/plain" -}; -function isFetchOptions(obj) { - return obj && containsProp(obj, "immediate", "refetch", "initialData", "timeout", "beforeFetch", "afterFetch", "onFetchError", "fetch", "updateDataOnError"); -} -var reAbsolute = /^(?:[a-z][a-z\d+\-.]*:)?\/\//i; -function isAbsoluteURL(url) { - return reAbsolute.test(url); -} -function headersToObject(headers) { - if (typeof Headers !== "undefined" && headers instanceof Headers) - return Object.fromEntries(headers.entries()); - return headers; -} -function combineCallbacks(combination, ...callbacks) { - if (combination === "overwrite") { - return async (ctx) => { - let callback; - for (let i = callbacks.length - 1; i >= 0; i--) { - if (callbacks[i] != null) { - callback = callbacks[i]; - break; - } - } - if (callback) - return { ...ctx, ...await callback(ctx) }; - return ctx; - }; - } else { - return async (ctx) => { - for (const callback of callbacks) { - if (callback) - ctx = { ...ctx, ...await callback(ctx) }; - } - return ctx; - }; - } -} -function createFetch(config = {}) { - const _combination = config.combination || "chain"; - const _options = config.options || {}; - const _fetchOptions = config.fetchOptions || {}; - function useFactoryFetch(url, ...args) { - const computedUrl = computed(() => { - const baseUrl = toValue(config.baseUrl); - const targetUrl = toValue(url); - return baseUrl && !isAbsoluteURL(targetUrl) ? joinPaths(baseUrl, targetUrl) : targetUrl; - }); - let options = _options; - let fetchOptions = _fetchOptions; - if (args.length > 0) { - if (isFetchOptions(args[0])) { - options = { - ...options, - ...args[0], - beforeFetch: combineCallbacks(_combination, _options.beforeFetch, args[0].beforeFetch), - afterFetch: combineCallbacks(_combination, _options.afterFetch, args[0].afterFetch), - onFetchError: combineCallbacks(_combination, _options.onFetchError, args[0].onFetchError) - }; - } else { - fetchOptions = { - ...fetchOptions, - ...args[0], - headers: { - ...headersToObject(fetchOptions.headers) || {}, - ...headersToObject(args[0].headers) || {} - } - }; - } - } - if (args.length > 1 && isFetchOptions(args[1])) { - options = { - ...options, - ...args[1], - beforeFetch: combineCallbacks(_combination, _options.beforeFetch, args[1].beforeFetch), - afterFetch: combineCallbacks(_combination, _options.afterFetch, args[1].afterFetch), - onFetchError: combineCallbacks(_combination, _options.onFetchError, args[1].onFetchError) - }; - } - return useFetch(computedUrl, fetchOptions, options); - } - return useFactoryFetch; -} -function useFetch(url, ...args) { - var _a; - const supportsAbort = typeof AbortController === "function"; - let fetchOptions = {}; - let options = { - immediate: true, - refetch: false, - timeout: 0, - updateDataOnError: false - }; - const config = { - method: "GET", - type: "text", - payload: void 0 - }; - if (args.length > 0) { - if (isFetchOptions(args[0])) - options = { ...options, ...args[0] }; - else - fetchOptions = args[0]; - } - if (args.length > 1) { - if (isFetchOptions(args[1])) - options = { ...options, ...args[1] }; - } - const { - fetch = (_a = defaultWindow) == null ? void 0 : _a.fetch, - initialData, - timeout - } = options; - const responseEvent = createEventHook(); - const errorEvent = createEventHook(); - const finallyEvent = createEventHook(); - const isFinished = shallowRef(false); - const isFetching = shallowRef(false); - const aborted = shallowRef(false); - const statusCode = shallowRef(null); - const response = shallowRef(null); - const error = shallowRef(null); - const data = shallowRef(initialData || null); - const canAbort = computed(() => supportsAbort && isFetching.value); - let controller; - let timer; - const abort = () => { - if (supportsAbort) { - controller == null ? void 0 : controller.abort(); - controller = new AbortController(); - controller.signal.onabort = () => aborted.value = true; - fetchOptions = { - ...fetchOptions, - signal: controller.signal - }; - } - }; - const loading = (isLoading) => { - isFetching.value = isLoading; - isFinished.value = !isLoading; - }; - if (timeout) - timer = useTimeoutFn(abort, timeout, { immediate: false }); - let executeCounter = 0; - const execute = async (throwOnFailed = false) => { - var _a2, _b; - abort(); - loading(true); - error.value = null; - statusCode.value = null; - aborted.value = false; - executeCounter += 1; - const currentExecuteCounter = executeCounter; - const defaultFetchOptions = { - method: config.method, - headers: {} - }; - const payload = toValue(config.payload); - if (payload) { - const headers = headersToObject(defaultFetchOptions.headers); - const proto = Object.getPrototypeOf(payload); - if (!config.payloadType && payload && (proto === Object.prototype || Array.isArray(proto)) && !(payload instanceof FormData)) - config.payloadType = "json"; - if (config.payloadType) - headers["Content-Type"] = (_a2 = payloadMapping[config.payloadType]) != null ? _a2 : config.payloadType; - defaultFetchOptions.body = config.payloadType === "json" ? JSON.stringify(payload) : payload; - } - let isCanceled = false; - const context = { - url: toValue(url), - options: { - ...defaultFetchOptions, - ...fetchOptions - }, - cancel: () => { - isCanceled = true; - } - }; - if (options.beforeFetch) - Object.assign(context, await options.beforeFetch(context)); - if (isCanceled || !fetch) { - loading(false); - return Promise.resolve(null); - } - let responseData = null; - if (timer) - timer.start(); - return fetch( - context.url, - { - ...defaultFetchOptions, - ...context.options, - headers: { - ...headersToObject(defaultFetchOptions.headers), - ...headersToObject((_b = context.options) == null ? void 0 : _b.headers) - } - } - ).then(async (fetchResponse) => { - response.value = fetchResponse; - statusCode.value = fetchResponse.status; - responseData = await fetchResponse.clone()[config.type](); - if (!fetchResponse.ok) { - data.value = initialData || null; - throw new Error(fetchResponse.statusText); - } - if (options.afterFetch) { - ({ data: responseData } = await options.afterFetch({ - data: responseData, - response: fetchResponse, - context, - execute - })); - } - data.value = responseData; - responseEvent.trigger(fetchResponse); - return fetchResponse; - }).catch(async (fetchError) => { - let errorData = fetchError.message || fetchError.name; - if (options.onFetchError) { - ({ error: errorData, data: responseData } = await options.onFetchError({ - data: responseData, - error: fetchError, - response: response.value, - context, - execute - })); - } - error.value = errorData; - if (options.updateDataOnError) - data.value = responseData; - errorEvent.trigger(fetchError); - if (throwOnFailed) - throw fetchError; - return null; - }).finally(() => { - if (currentExecuteCounter === executeCounter) - loading(false); - if (timer) - timer.stop(); - finallyEvent.trigger(null); - }); - }; - const refetch = toRef2(options.refetch); - watch( - [ - refetch, - toRef2(url) - ], - ([refetch2]) => refetch2 && execute(), - { deep: true } - ); - const shell = { - isFinished: readonly(isFinished), - isFetching: readonly(isFetching), - statusCode, - response, - error, - data, - canAbort, - aborted, - abort, - execute, - onFetchResponse: responseEvent.on, - onFetchError: errorEvent.on, - onFetchFinally: finallyEvent.on, - // method - get: setMethod("GET"), - put: setMethod("PUT"), - post: setMethod("POST"), - delete: setMethod("DELETE"), - patch: setMethod("PATCH"), - head: setMethod("HEAD"), - options: setMethod("OPTIONS"), - // type - json: setType("json"), - text: setType("text"), - blob: setType("blob"), - arrayBuffer: setType("arrayBuffer"), - formData: setType("formData") - }; - function setMethod(method) { - return (payload, payloadType) => { - if (!isFetching.value) { - config.method = method; - config.payload = payload; - config.payloadType = payloadType; - if (isRef(config.payload)) { - watch( - [ - refetch, - toRef2(config.payload) - ], - ([refetch2]) => refetch2 && execute(), - { deep: true } - ); - } - return { - ...shell, - then(onFulfilled, onRejected) { - return waitUntilFinished().then(onFulfilled, onRejected); - } - }; - } - return void 0; - }; - } - function waitUntilFinished() { - return new Promise((resolve, reject) => { - until(isFinished).toBe(true).then(() => resolve(shell)).catch(reject); - }); - } - function setType(type) { - return () => { - if (!isFetching.value) { - config.type = type; - return { - ...shell, - then(onFulfilled, onRejected) { - return waitUntilFinished().then(onFulfilled, onRejected); - } - }; - } - return void 0; - }; - } - if (options.immediate) - Promise.resolve().then(() => execute()); - return { - ...shell, - then(onFulfilled, onRejected) { - return waitUntilFinished().then(onFulfilled, onRejected); - } - }; -} -function joinPaths(start, end) { - if (!start.endsWith("/") && !end.startsWith("/")) { - return `${start}/${end}`; - } - if (start.endsWith("/") && end.startsWith("/")) { - return `${start.slice(0, -1)}${end}`; - } - return `${start}${end}`; -} -var DEFAULT_OPTIONS = { - multiple: true, - accept: "*", - reset: false, - directory: false -}; -function prepareInitialFiles(files) { - if (!files) - return null; - if (files instanceof FileList) - return files; - const dt = new DataTransfer(); - for (const file of files) { - dt.items.add(file); - } - return dt.files; -} -function useFileDialog(options = {}) { - const { - document: document2 = defaultDocument - } = options; - const files = ref(prepareInitialFiles(options.initialFiles)); - const { on: onChange, trigger: changeTrigger } = createEventHook(); - const { on: onCancel, trigger: cancelTrigger } = createEventHook(); - let input; - if (document2) { - input = document2.createElement("input"); - input.type = "file"; - input.onchange = (event) => { - const result = event.target; - files.value = result.files; - changeTrigger(files.value); - }; - input.oncancel = () => { - cancelTrigger(); - }; - } - const reset = () => { - files.value = null; - if (input && input.value) { - input.value = ""; - changeTrigger(null); - } - }; - const open = (localOptions) => { - if (!input) - return; - const _options = { - ...DEFAULT_OPTIONS, - ...options, - ...localOptions - }; - input.multiple = _options.multiple; - input.accept = _options.accept; - input.webkitdirectory = _options.directory; - if (hasOwn(_options, "capture")) - input.capture = _options.capture; - if (_options.reset) - reset(); - input.click(); - }; - return { - files: readonly(files), - open, - reset, - onCancel, - onChange - }; -} -function useFileSystemAccess(options = {}) { - const { - window: _window = defaultWindow, - dataType = "Text" - } = options; - const window2 = _window; - const isSupported = useSupported(() => window2 && "showSaveFilePicker" in window2 && "showOpenFilePicker" in window2); - const fileHandle = shallowRef(); - const data = shallowRef(); - const file = shallowRef(); - const fileName = computed(() => { - var _a, _b; - return (_b = (_a = file.value) == null ? void 0 : _a.name) != null ? _b : ""; - }); - const fileMIME = computed(() => { - var _a, _b; - return (_b = (_a = file.value) == null ? void 0 : _a.type) != null ? _b : ""; - }); - const fileSize = computed(() => { - var _a, _b; - return (_b = (_a = file.value) == null ? void 0 : _a.size) != null ? _b : 0; - }); - const fileLastModified = computed(() => { - var _a, _b; - return (_b = (_a = file.value) == null ? void 0 : _a.lastModified) != null ? _b : 0; - }); - async function open(_options = {}) { - if (!isSupported.value) - return; - const [handle] = await window2.showOpenFilePicker({ ...toValue(options), ..._options }); - fileHandle.value = handle; - await updateData(); - } - async function create(_options = {}) { - if (!isSupported.value) - return; - fileHandle.value = await window2.showSaveFilePicker({ ...options, ..._options }); - data.value = void 0; - await updateData(); - } - async function save(_options = {}) { - if (!isSupported.value) - return; - if (!fileHandle.value) - return saveAs(_options); - if (data.value) { - const writableStream = await fileHandle.value.createWritable(); - await writableStream.write(data.value); - await writableStream.close(); - } - await updateFile(); - } - async function saveAs(_options = {}) { - if (!isSupported.value) - return; - fileHandle.value = await window2.showSaveFilePicker({ ...options, ..._options }); - if (data.value) { - const writableStream = await fileHandle.value.createWritable(); - await writableStream.write(data.value); - await writableStream.close(); - } - await updateFile(); - } - async function updateFile() { - var _a; - file.value = await ((_a = fileHandle.value) == null ? void 0 : _a.getFile()); - } - async function updateData() { - var _a, _b; - await updateFile(); - const type = toValue(dataType); - if (type === "Text") - data.value = await ((_a = file.value) == null ? void 0 : _a.text()); - else if (type === "ArrayBuffer") - data.value = await ((_b = file.value) == null ? void 0 : _b.arrayBuffer()); - else if (type === "Blob") - data.value = file.value; - } - watch(() => toValue(dataType), updateData); - return { - isSupported, - data, - file, - fileName, - fileMIME, - fileSize, - fileLastModified, - open, - create, - save, - saveAs, - updateData - }; -} -function useFocus(target, options = {}) { - const { initialValue = false, focusVisible = false, preventScroll = false } = options; - const innerFocused = shallowRef(false); - const targetElement = computed(() => unrefElement(target)); - const listenerOptions = { passive: true }; - useEventListener(targetElement, "focus", (event) => { - var _a, _b; - if (!focusVisible || ((_b = (_a = event.target).matches) == null ? void 0 : _b.call(_a, ":focus-visible"))) - innerFocused.value = true; - }, listenerOptions); - useEventListener(targetElement, "blur", () => innerFocused.value = false, listenerOptions); - const focused = computed({ - get: () => innerFocused.value, - set(value) { - var _a, _b; - if (!value && innerFocused.value) - (_a = targetElement.value) == null ? void 0 : _a.blur(); - else if (value && !innerFocused.value) - (_b = targetElement.value) == null ? void 0 : _b.focus({ preventScroll }); - } - }); - watch( - targetElement, - () => { - focused.value = initialValue; - }, - { immediate: true, flush: "post" } - ); - return { focused }; -} -var EVENT_FOCUS_IN = "focusin"; -var EVENT_FOCUS_OUT = "focusout"; -var PSEUDO_CLASS_FOCUS_WITHIN = ":focus-within"; -function useFocusWithin(target, options = {}) { - const { window: window2 = defaultWindow } = options; - const targetElement = computed(() => unrefElement(target)); - const _focused = shallowRef(false); - const focused = computed(() => _focused.value); - const activeElement = useActiveElement(options); - if (!window2 || !activeElement.value) { - return { focused }; - } - const listenerOptions = { passive: true }; - useEventListener(targetElement, EVENT_FOCUS_IN, () => _focused.value = true, listenerOptions); - useEventListener(targetElement, EVENT_FOCUS_OUT, () => { - var _a, _b, _c; - return _focused.value = (_c = (_b = (_a = targetElement.value) == null ? void 0 : _a.matches) == null ? void 0 : _b.call(_a, PSEUDO_CLASS_FOCUS_WITHIN)) != null ? _c : false; - }, listenerOptions); - return { focused }; -} -function useFps(options) { - var _a; - const fps = shallowRef(0); - if (typeof performance === "undefined") - return fps; - const every = (_a = options == null ? void 0 : options.every) != null ? _a : 10; - let last = performance.now(); - let ticks = 0; - useRafFn(() => { - ticks += 1; - if (ticks >= every) { - const now2 = performance.now(); - const diff = now2 - last; - fps.value = Math.round(1e3 / (diff / ticks)); - last = now2; - ticks = 0; - } - }); - return fps; -} -var eventHandlers = [ - "fullscreenchange", - "webkitfullscreenchange", - "webkitendfullscreen", - "mozfullscreenchange", - "MSFullscreenChange" -]; -function useFullscreen(target, options = {}) { - const { - document: document2 = defaultDocument, - autoExit = false - } = options; - const targetRef = computed(() => { - var _a; - return (_a = unrefElement(target)) != null ? _a : document2 == null ? void 0 : document2.documentElement; - }); - const isFullscreen = shallowRef(false); - const requestMethod = computed(() => { - return [ - "requestFullscreen", - "webkitRequestFullscreen", - "webkitEnterFullscreen", - "webkitEnterFullScreen", - "webkitRequestFullScreen", - "mozRequestFullScreen", - "msRequestFullscreen" - ].find((m) => document2 && m in document2 || targetRef.value && m in targetRef.value); - }); - const exitMethod = computed(() => { - return [ - "exitFullscreen", - "webkitExitFullscreen", - "webkitExitFullScreen", - "webkitCancelFullScreen", - "mozCancelFullScreen", - "msExitFullscreen" - ].find((m) => document2 && m in document2 || targetRef.value && m in targetRef.value); - }); - const fullscreenEnabled = computed(() => { - return [ - "fullScreen", - "webkitIsFullScreen", - "webkitDisplayingFullscreen", - "mozFullScreen", - "msFullscreenElement" - ].find((m) => document2 && m in document2 || targetRef.value && m in targetRef.value); - }); - const fullscreenElementMethod = [ - "fullscreenElement", - "webkitFullscreenElement", - "mozFullScreenElement", - "msFullscreenElement" - ].find((m) => document2 && m in document2); - const isSupported = useSupported(() => targetRef.value && document2 && requestMethod.value !== void 0 && exitMethod.value !== void 0 && fullscreenEnabled.value !== void 0); - const isCurrentElementFullScreen = () => { - if (fullscreenElementMethod) - return (document2 == null ? void 0 : document2[fullscreenElementMethod]) === targetRef.value; - return false; - }; - const isElementFullScreen = () => { - if (fullscreenEnabled.value) { - if (document2 && document2[fullscreenEnabled.value] != null) { - return document2[fullscreenEnabled.value]; - } else { - const target2 = targetRef.value; - if ((target2 == null ? void 0 : target2[fullscreenEnabled.value]) != null) { - return Boolean(target2[fullscreenEnabled.value]); - } - } - } - return false; - }; - async function exit() { - if (!isSupported.value || !isFullscreen.value) - return; - if (exitMethod.value) { - if ((document2 == null ? void 0 : document2[exitMethod.value]) != null) { - await document2[exitMethod.value](); - } else { - const target2 = targetRef.value; - if ((target2 == null ? void 0 : target2[exitMethod.value]) != null) - await target2[exitMethod.value](); - } - } - isFullscreen.value = false; - } - async function enter() { - if (!isSupported.value || isFullscreen.value) - return; - if (isElementFullScreen()) - await exit(); - const target2 = targetRef.value; - if (requestMethod.value && (target2 == null ? void 0 : target2[requestMethod.value]) != null) { - await target2[requestMethod.value](); - isFullscreen.value = true; - } - } - async function toggle() { - await (isFullscreen.value ? exit() : enter()); - } - const handlerCallback = () => { - const isElementFullScreenValue = isElementFullScreen(); - if (!isElementFullScreenValue || isElementFullScreenValue && isCurrentElementFullScreen()) - isFullscreen.value = isElementFullScreenValue; - }; - const listenerOptions = { capture: false, passive: true }; - useEventListener(document2, eventHandlers, handlerCallback, listenerOptions); - useEventListener(() => unrefElement(targetRef), eventHandlers, handlerCallback, listenerOptions); - if (autoExit) - tryOnScopeDispose(exit); - return { - isSupported, - isFullscreen, - enter, - exit, - toggle - }; -} -function mapGamepadToXbox360Controller(gamepad) { - return computed(() => { - if (gamepad.value) { - return { - buttons: { - a: gamepad.value.buttons[0], - b: gamepad.value.buttons[1], - x: gamepad.value.buttons[2], - y: gamepad.value.buttons[3] - }, - bumper: { - left: gamepad.value.buttons[4], - right: gamepad.value.buttons[5] - }, - triggers: { - left: gamepad.value.buttons[6], - right: gamepad.value.buttons[7] - }, - stick: { - left: { - horizontal: gamepad.value.axes[0], - vertical: gamepad.value.axes[1], - button: gamepad.value.buttons[10] - }, - right: { - horizontal: gamepad.value.axes[2], - vertical: gamepad.value.axes[3], - button: gamepad.value.buttons[11] - } - }, - dpad: { - up: gamepad.value.buttons[12], - down: gamepad.value.buttons[13], - left: gamepad.value.buttons[14], - right: gamepad.value.buttons[15] - }, - back: gamepad.value.buttons[8], - start: gamepad.value.buttons[9] - }; - } - return null; - }); -} -function useGamepad(options = {}) { - const { - navigator: navigator2 = defaultNavigator - } = options; - const isSupported = useSupported(() => navigator2 && "getGamepads" in navigator2); - const gamepads = ref([]); - const onConnectedHook = createEventHook(); - const onDisconnectedHook = createEventHook(); - const stateFromGamepad = (gamepad) => { - const hapticActuators = []; - const vibrationActuator = "vibrationActuator" in gamepad ? gamepad.vibrationActuator : null; - if (vibrationActuator) - hapticActuators.push(vibrationActuator); - if (gamepad.hapticActuators) - hapticActuators.push(...gamepad.hapticActuators); - return { - id: gamepad.id, - index: gamepad.index, - connected: gamepad.connected, - mapping: gamepad.mapping, - timestamp: gamepad.timestamp, - vibrationActuator: gamepad.vibrationActuator, - hapticActuators, - axes: gamepad.axes.map((axes) => axes), - buttons: gamepad.buttons.map((button) => ({ pressed: button.pressed, touched: button.touched, value: button.value })) - }; - }; - const updateGamepadState = () => { - const _gamepads = (navigator2 == null ? void 0 : navigator2.getGamepads()) || []; - for (const gamepad of _gamepads) { - if (gamepad && gamepads.value[gamepad.index]) - gamepads.value[gamepad.index] = stateFromGamepad(gamepad); - } - }; - const { isActive, pause, resume } = useRafFn(updateGamepadState); - const onGamepadConnected = (gamepad) => { - if (!gamepads.value.some(({ index }) => index === gamepad.index)) { - gamepads.value.push(stateFromGamepad(gamepad)); - onConnectedHook.trigger(gamepad.index); - } - resume(); - }; - const onGamepadDisconnected = (gamepad) => { - gamepads.value = gamepads.value.filter((x) => x.index !== gamepad.index); - onDisconnectedHook.trigger(gamepad.index); - }; - const listenerOptions = { passive: true }; - useEventListener("gamepadconnected", (e) => onGamepadConnected(e.gamepad), listenerOptions); - useEventListener("gamepaddisconnected", (e) => onGamepadDisconnected(e.gamepad), listenerOptions); - tryOnMounted(() => { - const _gamepads = (navigator2 == null ? void 0 : navigator2.getGamepads()) || []; - for (const gamepad of _gamepads) { - if (gamepad && gamepads.value[gamepad.index]) - onGamepadConnected(gamepad); - } - }); - pause(); - return { - isSupported, - onConnected: onConnectedHook.on, - onDisconnected: onDisconnectedHook.on, - gamepads, - pause, - resume, - isActive - }; -} -function useGeolocation(options = {}) { - const { - enableHighAccuracy = true, - maximumAge = 3e4, - timeout = 27e3, - navigator: navigator2 = defaultNavigator, - immediate = true - } = options; - const isSupported = useSupported(() => navigator2 && "geolocation" in navigator2); - const locatedAt = shallowRef(null); - const error = shallowRef(null); - const coords = ref({ - accuracy: 0, - latitude: Number.POSITIVE_INFINITY, - longitude: Number.POSITIVE_INFINITY, - altitude: null, - altitudeAccuracy: null, - heading: null, - speed: null - }); - function updatePosition(position) { - locatedAt.value = position.timestamp; - coords.value = position.coords; - error.value = null; - } - let watcher; - function resume() { - if (isSupported.value) { - watcher = navigator2.geolocation.watchPosition( - updatePosition, - (err) => error.value = err, - { - enableHighAccuracy, - maximumAge, - timeout - } - ); - } - } - if (immediate) - resume(); - function pause() { - if (watcher && navigator2) - navigator2.geolocation.clearWatch(watcher); - } - tryOnScopeDispose(() => { - pause(); - }); - return { - isSupported, - coords, - locatedAt, - error, - resume, - pause - }; -} -var defaultEvents$1 = ["mousemove", "mousedown", "resize", "keydown", "touchstart", "wheel"]; -var oneMinute = 6e4; -function useIdle(timeout = oneMinute, options = {}) { - const { - initialState = false, - listenForVisibilityChange = true, - events: events2 = defaultEvents$1, - window: window2 = defaultWindow, - eventFilter = throttleFilter(50) - } = options; - const idle = shallowRef(initialState); - const lastActive = shallowRef(timestamp()); - let timer; - const reset = () => { - idle.value = false; - clearTimeout(timer); - timer = setTimeout(() => idle.value = true, timeout); - }; - const onEvent = createFilterWrapper( - eventFilter, - () => { - lastActive.value = timestamp(); - reset(); - } - ); - if (window2) { - const document2 = window2.document; - const listenerOptions = { passive: true }; - for (const event of events2) - useEventListener(window2, event, onEvent, listenerOptions); - if (listenForVisibilityChange) { - useEventListener(document2, "visibilitychange", () => { - if (!document2.hidden) - onEvent(); - }, listenerOptions); - } - reset(); - } - return { - idle, - lastActive, - reset - }; -} -async function loadImage(options) { - return new Promise((resolve, reject) => { - const img = new Image(); - const { src, srcset, sizes, class: clazz, loading, crossorigin, referrerPolicy, width, height, decoding, fetchPriority, ismap, usemap } = options; - img.src = src; - if (srcset != null) - img.srcset = srcset; - if (sizes != null) - img.sizes = sizes; - if (clazz != null) - img.className = clazz; - if (loading != null) - img.loading = loading; - if (crossorigin != null) - img.crossOrigin = crossorigin; - if (referrerPolicy != null) - img.referrerPolicy = referrerPolicy; - if (width != null) - img.width = width; - if (height != null) - img.height = height; - if (decoding != null) - img.decoding = decoding; - if (fetchPriority != null) - img.fetchPriority = fetchPriority; - if (ismap != null) - img.isMap = ismap; - if (usemap != null) - img.useMap = usemap; - img.onload = () => resolve(img); - img.onerror = reject; - }); -} -function useImage(options, asyncStateOptions = {}) { - const state = useAsyncState( - () => loadImage(toValue(options)), - void 0, - { - resetOnExecute: true, - ...asyncStateOptions - } - ); - watch( - () => toValue(options), - () => state.execute(asyncStateOptions.delay), - { deep: true } - ); - return state; -} -function resolveElement(el) { - if (typeof Window !== "undefined" && el instanceof Window) - return el.document.documentElement; - if (typeof Document !== "undefined" && el instanceof Document) - return el.documentElement; - return el; -} -var ARRIVED_STATE_THRESHOLD_PIXELS = 1; -function useScroll(element, options = {}) { - const { - throttle = 0, - idle = 200, - onStop = noop, - onScroll = noop, - offset = { - left: 0, - right: 0, - top: 0, - bottom: 0 - }, - eventListenerOptions = { - capture: false, - passive: true - }, - behavior = "auto", - window: window2 = defaultWindow, - onError = (e) => { - console.error(e); - } - } = options; - const internalX = shallowRef(0); - const internalY = shallowRef(0); - const x = computed({ - get() { - return internalX.value; - }, - set(x2) { - scrollTo(x2, void 0); - } - }); - const y = computed({ - get() { - return internalY.value; - }, - set(y2) { - scrollTo(void 0, y2); - } - }); - function scrollTo(_x, _y) { - var _a, _b, _c, _d; - if (!window2) - return; - const _element = toValue(element); - if (!_element) - return; - (_c = _element instanceof Document ? window2.document.body : _element) == null ? void 0 : _c.scrollTo({ - top: (_a = toValue(_y)) != null ? _a : y.value, - left: (_b = toValue(_x)) != null ? _b : x.value, - behavior: toValue(behavior) - }); - const scrollContainer = ((_d = _element == null ? void 0 : _element.document) == null ? void 0 : _d.documentElement) || (_element == null ? void 0 : _element.documentElement) || _element; - if (x != null) - internalX.value = scrollContainer.scrollLeft; - if (y != null) - internalY.value = scrollContainer.scrollTop; - } - const isScrolling = shallowRef(false); - const arrivedState = reactive({ - left: true, - right: false, - top: true, - bottom: false - }); - const directions = reactive({ - left: false, - right: false, - top: false, - bottom: false - }); - const onScrollEnd = (e) => { - if (!isScrolling.value) - return; - isScrolling.value = false; - directions.left = false; - directions.right = false; - directions.top = false; - directions.bottom = false; - onStop(e); - }; - const onScrollEndDebounced = useDebounceFn(onScrollEnd, throttle + idle); - const setArrivedState = (target) => { - var _a; - if (!window2) - return; - const el = ((_a = target == null ? void 0 : target.document) == null ? void 0 : _a.documentElement) || (target == null ? void 0 : target.documentElement) || unrefElement(target); - const { display, flexDirection, direction } = getComputedStyle(el); - const directionMultipler = direction === "rtl" ? -1 : 1; - const scrollLeft = el.scrollLeft; - directions.left = scrollLeft < internalX.value; - directions.right = scrollLeft > internalX.value; - const left = Math.abs(scrollLeft * directionMultipler) <= (offset.left || 0); - const right = Math.abs(scrollLeft * directionMultipler) + el.clientWidth >= el.scrollWidth - (offset.right || 0) - ARRIVED_STATE_THRESHOLD_PIXELS; - if (display === "flex" && flexDirection === "row-reverse") { - arrivedState.left = right; - arrivedState.right = left; - } else { - arrivedState.left = left; - arrivedState.right = right; - } - internalX.value = scrollLeft; - let scrollTop = el.scrollTop; - if (target === window2.document && !scrollTop) - scrollTop = window2.document.body.scrollTop; - directions.top = scrollTop < internalY.value; - directions.bottom = scrollTop > internalY.value; - const top = Math.abs(scrollTop) <= (offset.top || 0); - const bottom = Math.abs(scrollTop) + el.clientHeight >= el.scrollHeight - (offset.bottom || 0) - ARRIVED_STATE_THRESHOLD_PIXELS; - if (display === "flex" && flexDirection === "column-reverse") { - arrivedState.top = bottom; - arrivedState.bottom = top; - } else { - arrivedState.top = top; - arrivedState.bottom = bottom; - } - internalY.value = scrollTop; - }; - const onScrollHandler = (e) => { - var _a; - if (!window2) - return; - const eventTarget = (_a = e.target.documentElement) != null ? _a : e.target; - setArrivedState(eventTarget); - isScrolling.value = true; - onScrollEndDebounced(e); - onScroll(e); - }; - useEventListener( - element, - "scroll", - throttle ? useThrottleFn(onScrollHandler, throttle, true, false) : onScrollHandler, - eventListenerOptions - ); - tryOnMounted(() => { - try { - const _element = toValue(element); - if (!_element) - return; - setArrivedState(_element); - } catch (e) { - onError(e); - } - }); - useEventListener( - element, - "scrollend", - onScrollEnd, - eventListenerOptions - ); - return { - x, - y, - isScrolling, - arrivedState, - directions, - measure() { - const _element = toValue(element); - if (window2 && _element) - setArrivedState(_element); - } - }; -} -function useInfiniteScroll(element, onLoadMore, options = {}) { - var _a; - const { - direction = "bottom", - interval = 100, - canLoadMore = () => true - } = options; - const state = reactive(useScroll( - element, - { - ...options, - offset: { - [direction]: (_a = options.distance) != null ? _a : 0, - ...options.offset - } - } - )); - const promise = ref(); - const isLoading = computed(() => !!promise.value); - const observedElement = computed(() => { - return resolveElement(toValue(element)); - }); - const isElementVisible = useElementVisibility(observedElement); - function checkAndLoad() { - state.measure(); - if (!observedElement.value || !isElementVisible.value || !canLoadMore(observedElement.value)) - return; - const { scrollHeight, clientHeight, scrollWidth, clientWidth } = observedElement.value; - const isNarrower = direction === "bottom" || direction === "top" ? scrollHeight <= clientHeight : scrollWidth <= clientWidth; - if (state.arrivedState[direction] || isNarrower) { - if (!promise.value) { - promise.value = Promise.all([ - onLoadMore(state), - new Promise((resolve) => setTimeout(resolve, interval)) - ]).finally(() => { - promise.value = null; - nextTick(() => checkAndLoad()); - }); - } - } - } - const stop = watch( - () => [state.arrivedState[direction], isElementVisible.value], - checkAndLoad, - { immediate: true } - ); - tryOnUnmounted(stop); - return { - isLoading, - reset() { - nextTick(() => checkAndLoad()); - } - }; -} -var defaultEvents = ["mousedown", "mouseup", "keydown", "keyup"]; -function useKeyModifier(modifier, options = {}) { - const { - events: events2 = defaultEvents, - document: document2 = defaultDocument, - initial = null - } = options; - const state = shallowRef(initial); - if (document2) { - events2.forEach((listenerEvent) => { - useEventListener(document2, listenerEvent, (evt) => { - if (typeof evt.getModifierState === "function") - state.value = evt.getModifierState(modifier); - }, { passive: true }); - }); - } - return state; -} -function useLocalStorage(key, initialValue, options = {}) { - const { window: window2 = defaultWindow } = options; - return useStorage(key, initialValue, window2 == null ? void 0 : window2.localStorage, options); -} -var DefaultMagicKeysAliasMap = { - ctrl: "control", - command: "meta", - cmd: "meta", - option: "alt", - up: "arrowup", - down: "arrowdown", - left: "arrowleft", - right: "arrowright" -}; -function useMagicKeys(options = {}) { - const { - reactive: useReactive = false, - target = defaultWindow, - aliasMap = DefaultMagicKeysAliasMap, - passive = true, - onEventFired = noop - } = options; - const current = reactive(/* @__PURE__ */ new Set()); - const obj = { - toJSON() { - return {}; - }, - current - }; - const refs = useReactive ? reactive(obj) : obj; - const metaDeps = /* @__PURE__ */ new Set(); - const usedKeys = /* @__PURE__ */ new Set(); - function setRefs(key, value) { - if (key in refs) { - if (useReactive) - refs[key] = value; - else - refs[key].value = value; - } - } - function reset() { - current.clear(); - for (const key of usedKeys) - setRefs(key, false); - } - function updateRefs(e, value) { - var _a, _b; - const key = (_a = e.key) == null ? void 0 : _a.toLowerCase(); - const code = (_b = e.code) == null ? void 0 : _b.toLowerCase(); - const values = [code, key].filter(Boolean); - if (key) { - if (value) - current.add(key); - else - current.delete(key); - } - for (const key2 of values) { - usedKeys.add(key2); - setRefs(key2, value); - } - if (key === "meta" && !value) { - metaDeps.forEach((key2) => { - current.delete(key2); - setRefs(key2, false); - }); - metaDeps.clear(); - } else if (typeof e.getModifierState === "function" && e.getModifierState("Meta") && value) { - [...current, ...values].forEach((key2) => metaDeps.add(key2)); - } - } - useEventListener(target, "keydown", (e) => { - updateRefs(e, true); - return onEventFired(e); - }, { passive }); - useEventListener(target, "keyup", (e) => { - updateRefs(e, false); - return onEventFired(e); - }, { passive }); - useEventListener("blur", reset, { passive }); - useEventListener("focus", reset, { passive }); - const proxy = new Proxy( - refs, - { - get(target2, prop, rec) { - if (typeof prop !== "string") - return Reflect.get(target2, prop, rec); - prop = prop.toLowerCase(); - if (prop in aliasMap) - prop = aliasMap[prop]; - if (!(prop in refs)) { - if (/[+_-]/.test(prop)) { - const keys2 = prop.split(/[+_-]/g).map((i) => i.trim()); - refs[prop] = computed(() => keys2.map((key) => toValue(proxy[key])).every(Boolean)); - } else { - refs[prop] = shallowRef(false); - } - } - const r = Reflect.get(target2, prop, rec); - return useReactive ? toValue(r) : r; - } - } - ); - return proxy; -} -function usingElRef(source, cb) { - if (toValue(source)) - cb(toValue(source)); -} -function timeRangeToArray(timeRanges) { - let ranges = []; - for (let i = 0; i < timeRanges.length; ++i) - ranges = [...ranges, [timeRanges.start(i), timeRanges.end(i)]]; - return ranges; -} -function tracksToArray(tracks) { - return Array.from(tracks).map(({ label, kind, language, mode, activeCues, cues, inBandMetadataTrackDispatchType }, id) => ({ id, label, kind, language, mode, activeCues, cues, inBandMetadataTrackDispatchType })); -} -var defaultOptions = { - src: "", - tracks: [] -}; -function useMediaControls(target, options = {}) { - target = toRef2(target); - options = { - ...defaultOptions, - ...options - }; - const { - document: document2 = defaultDocument - } = options; - const listenerOptions = { passive: true }; - const currentTime = shallowRef(0); - const duration = shallowRef(0); - const seeking = shallowRef(false); - const volume = shallowRef(1); - const waiting = shallowRef(false); - const ended = shallowRef(false); - const playing = shallowRef(false); - const rate = shallowRef(1); - const stalled = shallowRef(false); - const buffered = ref([]); - const tracks = ref([]); - const selectedTrack = shallowRef(-1); - const isPictureInPicture = shallowRef(false); - const muted = shallowRef(false); - const supportsPictureInPicture = document2 && "pictureInPictureEnabled" in document2; - const sourceErrorEvent = createEventHook(); - const playbackErrorEvent = createEventHook(); - const disableTrack = (track) => { - usingElRef(target, (el) => { - if (track) { - const id = typeof track === "number" ? track : track.id; - el.textTracks[id].mode = "disabled"; - } else { - for (let i = 0; i < el.textTracks.length; ++i) - el.textTracks[i].mode = "disabled"; - } - selectedTrack.value = -1; - }); - }; - const enableTrack = (track, disableTracks = true) => { - usingElRef(target, (el) => { - const id = typeof track === "number" ? track : track.id; - if (disableTracks) - disableTrack(); - el.textTracks[id].mode = "showing"; - selectedTrack.value = id; - }); - }; - const togglePictureInPicture = () => { - return new Promise((resolve, reject) => { - usingElRef(target, async (el) => { - if (supportsPictureInPicture) { - if (!isPictureInPicture.value) { - el.requestPictureInPicture().then(resolve).catch(reject); - } else { - document2.exitPictureInPicture().then(resolve).catch(reject); - } - } - }); - }); - }; - watchEffect(() => { - if (!document2) - return; - const el = toValue(target); - if (!el) - return; - const src = toValue(options.src); - let sources = []; - if (!src) - return; - if (typeof src === "string") - sources = [{ src }]; - else if (Array.isArray(src)) - sources = src; - else if (isObject(src)) - sources = [src]; - el.querySelectorAll("source").forEach((e) => { - e.remove(); - }); - sources.forEach(({ src: src2, type, media }) => { - const source = document2.createElement("source"); - source.setAttribute("src", src2); - source.setAttribute("type", type || ""); - source.setAttribute("media", media || ""); - useEventListener(source, "error", sourceErrorEvent.trigger, listenerOptions); - el.appendChild(source); - }); - el.load(); - }); - watch([target, volume], () => { - const el = toValue(target); - if (!el) - return; - el.volume = volume.value; - }); - watch([target, muted], () => { - const el = toValue(target); - if (!el) - return; - el.muted = muted.value; - }); - watch([target, rate], () => { - const el = toValue(target); - if (!el) - return; - el.playbackRate = rate.value; - }); - watchEffect(() => { - if (!document2) - return; - const textTracks = toValue(options.tracks); - const el = toValue(target); - if (!textTracks || !textTracks.length || !el) - return; - el.querySelectorAll("track").forEach((e) => e.remove()); - textTracks.forEach(({ default: isDefault, kind, label, src, srcLang }, i) => { - const track = document2.createElement("track"); - track.default = isDefault || false; - track.kind = kind; - track.label = label; - track.src = src; - track.srclang = srcLang; - if (track.default) - selectedTrack.value = i; - el.appendChild(track); - }); - }); - const { ignoreUpdates: ignoreCurrentTimeUpdates } = watchIgnorable(currentTime, (time) => { - const el = toValue(target); - if (!el) - return; - el.currentTime = time; - }); - const { ignoreUpdates: ignorePlayingUpdates } = watchIgnorable(playing, (isPlaying) => { - const el = toValue(target); - if (!el) - return; - if (isPlaying) { - el.play().catch((e) => { - playbackErrorEvent.trigger(e); - throw e; - }); - } else { - el.pause(); - } - }); - useEventListener( - target, - "timeupdate", - () => ignoreCurrentTimeUpdates(() => currentTime.value = toValue(target).currentTime), - listenerOptions - ); - useEventListener( - target, - "durationchange", - () => duration.value = toValue(target).duration, - listenerOptions - ); - useEventListener( - target, - "progress", - () => buffered.value = timeRangeToArray(toValue(target).buffered), - listenerOptions - ); - useEventListener( - target, - "seeking", - () => seeking.value = true, - listenerOptions - ); - useEventListener( - target, - "seeked", - () => seeking.value = false, - listenerOptions - ); - useEventListener( - target, - ["waiting", "loadstart"], - () => { - waiting.value = true; - ignorePlayingUpdates(() => playing.value = false); - }, - listenerOptions - ); - useEventListener( - target, - "loadeddata", - () => waiting.value = false, - listenerOptions - ); - useEventListener( - target, - "playing", - () => { - waiting.value = false; - ended.value = false; - ignorePlayingUpdates(() => playing.value = true); - }, - listenerOptions - ); - useEventListener( - target, - "ratechange", - () => rate.value = toValue(target).playbackRate, - listenerOptions - ); - useEventListener( - target, - "stalled", - () => stalled.value = true, - listenerOptions - ); - useEventListener( - target, - "ended", - () => ended.value = true, - listenerOptions - ); - useEventListener( - target, - "pause", - () => ignorePlayingUpdates(() => playing.value = false), - listenerOptions - ); - useEventListener( - target, - "play", - () => ignorePlayingUpdates(() => playing.value = true), - listenerOptions - ); - useEventListener( - target, - "enterpictureinpicture", - () => isPictureInPicture.value = true, - listenerOptions - ); - useEventListener( - target, - "leavepictureinpicture", - () => isPictureInPicture.value = false, - listenerOptions - ); - useEventListener( - target, - "volumechange", - () => { - const el = toValue(target); - if (!el) - return; - volume.value = el.volume; - muted.value = el.muted; - }, - listenerOptions - ); - const listeners = []; - const stop = watch([target], () => { - const el = toValue(target); - if (!el) - return; - stop(); - listeners[0] = useEventListener(el.textTracks, "addtrack", () => tracks.value = tracksToArray(el.textTracks), listenerOptions); - listeners[1] = useEventListener(el.textTracks, "removetrack", () => tracks.value = tracksToArray(el.textTracks), listenerOptions); - listeners[2] = useEventListener(el.textTracks, "change", () => tracks.value = tracksToArray(el.textTracks), listenerOptions); - }); - tryOnScopeDispose(() => listeners.forEach((listener) => listener())); - return { - currentTime, - duration, - waiting, - seeking, - ended, - stalled, - buffered, - playing, - rate, - // Volume - volume, - muted, - // Tracks - tracks, - selectedTrack, - enableTrack, - disableTrack, - // Picture in Picture - supportsPictureInPicture, - togglePictureInPicture, - isPictureInPicture, - // Events - onSourceError: sourceErrorEvent.on, - onPlaybackError: playbackErrorEvent.on - }; -} -function useMemoize(resolver, options) { - const initCache = () => { - if (options == null ? void 0 : options.cache) - return shallowReactive(options.cache); - return shallowReactive(/* @__PURE__ */ new Map()); - }; - const cache = initCache(); - const generateKey = (...args) => (options == null ? void 0 : options.getKey) ? options.getKey(...args) : JSON.stringify(args); - const _loadData = (key, ...args) => { - cache.set(key, resolver(...args)); - return cache.get(key); - }; - const loadData = (...args) => _loadData(generateKey(...args), ...args); - const deleteData = (...args) => { - cache.delete(generateKey(...args)); - }; - const clearData = () => { - cache.clear(); - }; - const memoized = (...args) => { - const key = generateKey(...args); - if (cache.has(key)) - return cache.get(key); - return _loadData(key, ...args); - }; - memoized.load = loadData; - memoized.delete = deleteData; - memoized.clear = clearData; - memoized.generateKey = generateKey; - memoized.cache = cache; - return memoized; -} -function useMemory(options = {}) { - const memory = ref(); - const isSupported = useSupported(() => typeof performance !== "undefined" && "memory" in performance); - if (isSupported.value) { - const { interval = 1e3 } = options; - useIntervalFn(() => { - memory.value = performance.memory; - }, interval, { immediate: options.immediate, immediateCallback: options.immediateCallback }); - } - return { isSupported, memory }; -} -var UseMouseBuiltinExtractors = { - page: (event) => [event.pageX, event.pageY], - client: (event) => [event.clientX, event.clientY], - screen: (event) => [event.screenX, event.screenY], - movement: (event) => event instanceof MouseEvent ? [event.movementX, event.movementY] : null -}; -function useMouse(options = {}) { - const { - type = "page", - touch = true, - resetOnTouchEnds = false, - initialValue = { x: 0, y: 0 }, - window: window2 = defaultWindow, - target = window2, - scroll = true, - eventFilter - } = options; - let _prevMouseEvent = null; - let _prevScrollX = 0; - let _prevScrollY = 0; - const x = shallowRef(initialValue.x); - const y = shallowRef(initialValue.y); - const sourceType = shallowRef(null); - const extractor = typeof type === "function" ? type : UseMouseBuiltinExtractors[type]; - const mouseHandler = (event) => { - const result = extractor(event); - _prevMouseEvent = event; - if (result) { - [x.value, y.value] = result; - sourceType.value = "mouse"; - } - if (window2) { - _prevScrollX = window2.scrollX; - _prevScrollY = window2.scrollY; - } - }; - const touchHandler = (event) => { - if (event.touches.length > 0) { - const result = extractor(event.touches[0]); - if (result) { - [x.value, y.value] = result; - sourceType.value = "touch"; - } - } - }; - const scrollHandler = () => { - if (!_prevMouseEvent || !window2) - return; - const pos = extractor(_prevMouseEvent); - if (_prevMouseEvent instanceof MouseEvent && pos) { - x.value = pos[0] + window2.scrollX - _prevScrollX; - y.value = pos[1] + window2.scrollY - _prevScrollY; - } - }; - const reset = () => { - x.value = initialValue.x; - y.value = initialValue.y; - }; - const mouseHandlerWrapper = eventFilter ? (event) => eventFilter(() => mouseHandler(event), {}) : (event) => mouseHandler(event); - const touchHandlerWrapper = eventFilter ? (event) => eventFilter(() => touchHandler(event), {}) : (event) => touchHandler(event); - const scrollHandlerWrapper = eventFilter ? () => eventFilter(() => scrollHandler(), {}) : () => scrollHandler(); - if (target) { - const listenerOptions = { passive: true }; - useEventListener(target, ["mousemove", "dragover"], mouseHandlerWrapper, listenerOptions); - if (touch && type !== "movement") { - useEventListener(target, ["touchstart", "touchmove"], touchHandlerWrapper, listenerOptions); - if (resetOnTouchEnds) - useEventListener(target, "touchend", reset, listenerOptions); - } - if (scroll && type === "page") - useEventListener(window2, "scroll", scrollHandlerWrapper, listenerOptions); - } - return { - x, - y, - sourceType - }; -} -function useMouseInElement(target, options = {}) { - const { - handleOutside = true, - window: window2 = defaultWindow - } = options; - const type = options.type || "page"; - const { x, y, sourceType } = useMouse(options); - const targetRef = shallowRef(target != null ? target : window2 == null ? void 0 : window2.document.body); - const elementX = shallowRef(0); - const elementY = shallowRef(0); - const elementPositionX = shallowRef(0); - const elementPositionY = shallowRef(0); - const elementHeight = shallowRef(0); - const elementWidth = shallowRef(0); - const isOutside = shallowRef(true); - let stop = () => { - }; - if (window2) { - stop = watch( - [targetRef, x, y], - () => { - const el = unrefElement(targetRef); - if (!el || !(el instanceof Element)) - return; - const { - left, - top, - width, - height - } = el.getBoundingClientRect(); - elementPositionX.value = left + (type === "page" ? window2.pageXOffset : 0); - elementPositionY.value = top + (type === "page" ? window2.pageYOffset : 0); - elementHeight.value = height; - elementWidth.value = width; - const elX = x.value - elementPositionX.value; - const elY = y.value - elementPositionY.value; - isOutside.value = width === 0 || height === 0 || elX < 0 || elY < 0 || elX > width || elY > height; - if (handleOutside || !isOutside.value) { - elementX.value = elX; - elementY.value = elY; - } - }, - { immediate: true } - ); - useEventListener( - document, - "mouseleave", - () => isOutside.value = true, - { passive: true } - ); - } - return { - x, - y, - sourceType, - elementX, - elementY, - elementPositionX, - elementPositionY, - elementHeight, - elementWidth, - isOutside, - stop - }; -} -function useMousePressed(options = {}) { - const { - touch = true, - drag = true, - capture = false, - initialValue = false, - window: window2 = defaultWindow - } = options; - const pressed = shallowRef(initialValue); - const sourceType = shallowRef(null); - if (!window2) { - return { - pressed, - sourceType - }; - } - const onPressed = (srcType) => (event) => { - var _a; - pressed.value = true; - sourceType.value = srcType; - (_a = options.onPressed) == null ? void 0 : _a.call(options, event); - }; - const onReleased = (event) => { - var _a; - pressed.value = false; - sourceType.value = null; - (_a = options.onReleased) == null ? void 0 : _a.call(options, event); - }; - const target = computed(() => unrefElement(options.target) || window2); - const listenerOptions = { passive: true, capture }; - useEventListener(target, "mousedown", onPressed("mouse"), listenerOptions); - useEventListener(window2, "mouseleave", onReleased, listenerOptions); - useEventListener(window2, "mouseup", onReleased, listenerOptions); - if (drag) { - useEventListener(target, "dragstart", onPressed("mouse"), listenerOptions); - useEventListener(window2, "drop", onReleased, listenerOptions); - useEventListener(window2, "dragend", onReleased, listenerOptions); - } - if (touch) { - useEventListener(target, "touchstart", onPressed("touch"), listenerOptions); - useEventListener(window2, "touchend", onReleased, listenerOptions); - useEventListener(window2, "touchcancel", onReleased, listenerOptions); - } - return { - pressed, - sourceType - }; -} -function useNavigatorLanguage(options = {}) { - const { window: window2 = defaultWindow } = options; - const navigator2 = window2 == null ? void 0 : window2.navigator; - const isSupported = useSupported(() => navigator2 && "language" in navigator2); - const language = shallowRef(navigator2 == null ? void 0 : navigator2.language); - useEventListener(window2, "languagechange", () => { - if (navigator2) - language.value = navigator2.language; - }, { passive: true }); - return { - isSupported, - language - }; -} -function useNetwork(options = {}) { - const { window: window2 = defaultWindow } = options; - const navigator2 = window2 == null ? void 0 : window2.navigator; - const isSupported = useSupported(() => navigator2 && "connection" in navigator2); - const isOnline = shallowRef(true); - const saveData = shallowRef(false); - const offlineAt = shallowRef(void 0); - const onlineAt = shallowRef(void 0); - const downlink = shallowRef(void 0); - const downlinkMax = shallowRef(void 0); - const rtt = shallowRef(void 0); - const effectiveType = shallowRef(void 0); - const type = shallowRef("unknown"); - const connection = isSupported.value && navigator2.connection; - function updateNetworkInformation() { - if (!navigator2) - return; - isOnline.value = navigator2.onLine; - offlineAt.value = isOnline.value ? void 0 : Date.now(); - onlineAt.value = isOnline.value ? Date.now() : void 0; - if (connection) { - downlink.value = connection.downlink; - downlinkMax.value = connection.downlinkMax; - effectiveType.value = connection.effectiveType; - rtt.value = connection.rtt; - saveData.value = connection.saveData; - type.value = connection.type; - } - } - const listenerOptions = { passive: true }; - if (window2) { - useEventListener(window2, "offline", () => { - isOnline.value = false; - offlineAt.value = Date.now(); - }, listenerOptions); - useEventListener(window2, "online", () => { - isOnline.value = true; - onlineAt.value = Date.now(); - }, listenerOptions); - } - if (connection) - useEventListener(connection, "change", updateNetworkInformation, listenerOptions); - updateNetworkInformation(); - return { - isSupported, - isOnline: readonly(isOnline), - saveData: readonly(saveData), - offlineAt: readonly(offlineAt), - onlineAt: readonly(onlineAt), - downlink: readonly(downlink), - downlinkMax: readonly(downlinkMax), - effectiveType: readonly(effectiveType), - rtt: readonly(rtt), - type: readonly(type) - }; -} -function useNow(options = {}) { - const { - controls: exposeControls = false, - interval = "requestAnimationFrame" - } = options; - const now2 = ref(/* @__PURE__ */ new Date()); - const update = () => now2.value = /* @__PURE__ */ new Date(); - const controls = interval === "requestAnimationFrame" ? useRafFn(update, { immediate: true }) : useIntervalFn(update, interval, { immediate: true }); - if (exposeControls) { - return { - now: now2, - ...controls - }; - } else { - return now2; - } -} -function useObjectUrl(object) { - const url = shallowRef(); - const release = () => { - if (url.value) - URL.revokeObjectURL(url.value); - url.value = void 0; - }; - watch( - () => toValue(object), - (newObject) => { - release(); - if (newObject) - url.value = URL.createObjectURL(newObject); - }, - { immediate: true } - ); - tryOnScopeDispose(release); - return readonly(url); -} -function useClamp(value, min, max) { - if (typeof value === "function" || isReadonly(value)) - return computed(() => clamp(toValue(value), toValue(min), toValue(max))); - const _value = ref(value); - return computed({ - get() { - return _value.value = clamp(_value.value, toValue(min), toValue(max)); - }, - set(value2) { - _value.value = clamp(value2, toValue(min), toValue(max)); - } - }); -} -function useOffsetPagination(options) { - const { - total = Number.POSITIVE_INFINITY, - pageSize = 10, - page = 1, - onPageChange = noop, - onPageSizeChange = noop, - onPageCountChange = noop - } = options; - const currentPageSize = useClamp(pageSize, 1, Number.POSITIVE_INFINITY); - const pageCount = computed(() => Math.max( - 1, - Math.ceil(toValue(total) / toValue(currentPageSize)) - )); - const currentPage = useClamp(page, 1, pageCount); - const isFirstPage = computed(() => currentPage.value === 1); - const isLastPage = computed(() => currentPage.value === pageCount.value); - if (isRef(page)) { - syncRef(page, currentPage, { - direction: isReadonly(page) ? "ltr" : "both" - }); - } - if (isRef(pageSize)) { - syncRef(pageSize, currentPageSize, { - direction: isReadonly(pageSize) ? "ltr" : "both" - }); - } - function prev() { - currentPage.value--; - } - function next() { - currentPage.value++; - } - const returnValue = { - currentPage, - currentPageSize, - pageCount, - isFirstPage, - isLastPage, - prev, - next - }; - watch(currentPage, () => { - onPageChange(reactive(returnValue)); - }); - watch(currentPageSize, () => { - onPageSizeChange(reactive(returnValue)); - }); - watch(pageCount, () => { - onPageCountChange(reactive(returnValue)); - }); - return returnValue; -} -function useOnline(options = {}) { - const { isOnline } = useNetwork(options); - return isOnline; -} -function usePageLeave(options = {}) { - const { window: window2 = defaultWindow } = options; - const isLeft = shallowRef(false); - const handler = (event) => { - if (!window2) - return; - event = event || window2.event; - const from = event.relatedTarget || event.toElement; - isLeft.value = !from; - }; - if (window2) { - const listenerOptions = { passive: true }; - useEventListener(window2, "mouseout", handler, listenerOptions); - useEventListener(window2.document, "mouseleave", handler, listenerOptions); - useEventListener(window2.document, "mouseenter", handler, listenerOptions); - } - return isLeft; -} -function useScreenOrientation(options = {}) { - const { - window: window2 = defaultWindow - } = options; - const isSupported = useSupported(() => window2 && "screen" in window2 && "orientation" in window2.screen); - const screenOrientation = isSupported.value ? window2.screen.orientation : {}; - const orientation = ref(screenOrientation.type); - const angle = shallowRef(screenOrientation.angle || 0); - if (isSupported.value) { - useEventListener(window2, "orientationchange", () => { - orientation.value = screenOrientation.type; - angle.value = screenOrientation.angle; - }, { passive: true }); - } - const lockOrientation = (type) => { - if (isSupported.value && typeof screenOrientation.lock === "function") - return screenOrientation.lock(type); - return Promise.reject(new Error("Not supported")); - }; - const unlockOrientation = () => { - if (isSupported.value && typeof screenOrientation.unlock === "function") - screenOrientation.unlock(); - }; - return { - isSupported, - orientation, - angle, - lockOrientation, - unlockOrientation - }; -} -function useParallax(target, options = {}) { - const { - deviceOrientationTiltAdjust = (i) => i, - deviceOrientationRollAdjust = (i) => i, - mouseTiltAdjust = (i) => i, - mouseRollAdjust = (i) => i, - window: window2 = defaultWindow - } = options; - const orientation = reactive(useDeviceOrientation({ window: window2 })); - const screenOrientation = reactive(useScreenOrientation({ window: window2 })); - const { - elementX: x, - elementY: y, - elementWidth: width, - elementHeight: height - } = useMouseInElement(target, { handleOutside: false, window: window2 }); - const source = computed(() => { - if (orientation.isSupported && (orientation.alpha != null && orientation.alpha !== 0 || orientation.gamma != null && orientation.gamma !== 0)) { - return "deviceOrientation"; - } - return "mouse"; - }); - const roll = computed(() => { - if (source.value === "deviceOrientation") { - let value; - switch (screenOrientation.orientation) { - case "landscape-primary": - value = orientation.gamma / 90; - break; - case "landscape-secondary": - value = -orientation.gamma / 90; - break; - case "portrait-primary": - value = -orientation.beta / 90; - break; - case "portrait-secondary": - value = orientation.beta / 90; - break; - default: - value = -orientation.beta / 90; - } - return deviceOrientationRollAdjust(value); - } else { - const value = -(y.value - height.value / 2) / height.value; - return mouseRollAdjust(value); - } - }); - const tilt = computed(() => { - if (source.value === "deviceOrientation") { - let value; - switch (screenOrientation.orientation) { - case "landscape-primary": - value = orientation.beta / 90; - break; - case "landscape-secondary": - value = -orientation.beta / 90; - break; - case "portrait-primary": - value = orientation.gamma / 90; - break; - case "portrait-secondary": - value = -orientation.gamma / 90; - break; - default: - value = orientation.gamma / 90; - } - return deviceOrientationTiltAdjust(value); - } else { - const value = (x.value - width.value / 2) / width.value; - return mouseTiltAdjust(value); - } - }); - return { roll, tilt, source }; -} -function useParentElement(element = useCurrentElement()) { - const parentElement = shallowRef(); - const update = () => { - const el = unrefElement(element); - if (el) - parentElement.value = el.parentElement; - }; - tryOnMounted(update); - watch(() => toValue(element), update); - return parentElement; -} -function usePerformanceObserver(options, callback) { - const { - window: window2 = defaultWindow, - immediate = true, - ...performanceOptions - } = options; - const isSupported = useSupported(() => window2 && "PerformanceObserver" in window2); - let observer; - const stop = () => { - observer == null ? void 0 : observer.disconnect(); - }; - const start = () => { - if (isSupported.value) { - stop(); - observer = new PerformanceObserver(callback); - observer.observe(performanceOptions); - } - }; - tryOnScopeDispose(stop); - if (immediate) - start(); - return { - isSupported, - start, - stop - }; -} -var defaultState = { - x: 0, - y: 0, - pointerId: 0, - pressure: 0, - tiltX: 0, - tiltY: 0, - width: 0, - height: 0, - twist: 0, - pointerType: null -}; -var keys = Object.keys(defaultState); -function usePointer(options = {}) { - const { - target = defaultWindow - } = options; - const isInside = shallowRef(false); - const state = ref(options.initialValue || {}); - Object.assign(state.value, defaultState, state.value); - const handler = (event) => { - isInside.value = true; - if (options.pointerTypes && !options.pointerTypes.includes(event.pointerType)) - return; - state.value = objectPick(event, keys, false); - }; - if (target) { - const listenerOptions = { passive: true }; - useEventListener(target, ["pointerdown", "pointermove", "pointerup"], handler, listenerOptions); - useEventListener(target, "pointerleave", () => isInside.value = false, listenerOptions); - } - return { - ...toRefs2(state), - isInside - }; -} -function usePointerLock(target, options = {}) { - const { document: document2 = defaultDocument } = options; - const isSupported = useSupported(() => document2 && "pointerLockElement" in document2); - const element = shallowRef(); - const triggerElement = shallowRef(); - let targetElement; - if (isSupported.value) { - const listenerOptions = { passive: true }; - useEventListener(document2, "pointerlockchange", () => { - var _a; - const currentElement = (_a = document2.pointerLockElement) != null ? _a : element.value; - if (targetElement && currentElement === targetElement) { - element.value = document2.pointerLockElement; - if (!element.value) - targetElement = triggerElement.value = null; - } - }, listenerOptions); - useEventListener(document2, "pointerlockerror", () => { - var _a; - const currentElement = (_a = document2.pointerLockElement) != null ? _a : element.value; - if (targetElement && currentElement === targetElement) { - const action = document2.pointerLockElement ? "release" : "acquire"; - throw new Error(`Failed to ${action} pointer lock.`); - } - }, listenerOptions); - } - async function lock(e) { - var _a; - if (!isSupported.value) - throw new Error("Pointer Lock API is not supported by your browser."); - triggerElement.value = e instanceof Event ? e.currentTarget : null; - targetElement = e instanceof Event ? (_a = unrefElement(target)) != null ? _a : triggerElement.value : unrefElement(e); - if (!targetElement) - throw new Error("Target element undefined."); - targetElement.requestPointerLock(); - return await until(element).toBe(targetElement); - } - async function unlock() { - if (!element.value) - return false; - document2.exitPointerLock(); - await until(element).toBeNull(); - return true; - } - return { - isSupported, - element, - triggerElement, - lock, - unlock - }; -} -function usePointerSwipe(target, options = {}) { - const targetRef = toRef2(target); - const { - threshold = 50, - onSwipe, - onSwipeEnd, - onSwipeStart, - disableTextSelect = false - } = options; - const posStart = reactive({ x: 0, y: 0 }); - const updatePosStart = (x, y) => { - posStart.x = x; - posStart.y = y; - }; - const posEnd = reactive({ x: 0, y: 0 }); - const updatePosEnd = (x, y) => { - posEnd.x = x; - posEnd.y = y; - }; - const distanceX = computed(() => posStart.x - posEnd.x); - const distanceY = computed(() => posStart.y - posEnd.y); - const { max, abs } = Math; - const isThresholdExceeded = computed(() => max(abs(distanceX.value), abs(distanceY.value)) >= threshold); - const isSwiping = shallowRef(false); - const isPointerDown = shallowRef(false); - const direction = computed(() => { - if (!isThresholdExceeded.value) - return "none"; - if (abs(distanceX.value) > abs(distanceY.value)) { - return distanceX.value > 0 ? "left" : "right"; - } else { - return distanceY.value > 0 ? "up" : "down"; - } - }); - const eventIsAllowed = (e) => { - var _a, _b, _c; - const isReleasingButton = e.buttons === 0; - const isPrimaryButton = e.buttons === 1; - return (_c = (_b = (_a = options.pointerTypes) == null ? void 0 : _a.includes(e.pointerType)) != null ? _b : isReleasingButton || isPrimaryButton) != null ? _c : true; - }; - const listenerOptions = { passive: true }; - const stops = [ - useEventListener(target, "pointerdown", (e) => { - if (!eventIsAllowed(e)) - return; - isPointerDown.value = true; - const eventTarget = e.target; - eventTarget == null ? void 0 : eventTarget.setPointerCapture(e.pointerId); - const { clientX: x, clientY: y } = e; - updatePosStart(x, y); - updatePosEnd(x, y); - onSwipeStart == null ? void 0 : onSwipeStart(e); - }, listenerOptions), - useEventListener(target, "pointermove", (e) => { - if (!eventIsAllowed(e)) - return; - if (!isPointerDown.value) - return; - const { clientX: x, clientY: y } = e; - updatePosEnd(x, y); - if (!isSwiping.value && isThresholdExceeded.value) - isSwiping.value = true; - if (isSwiping.value) - onSwipe == null ? void 0 : onSwipe(e); - }, listenerOptions), - useEventListener(target, "pointerup", (e) => { - if (!eventIsAllowed(e)) - return; - if (isSwiping.value) - onSwipeEnd == null ? void 0 : onSwipeEnd(e, direction.value); - isPointerDown.value = false; - isSwiping.value = false; - }, listenerOptions) - ]; - tryOnMounted(() => { - var _a, _b, _c, _d, _e, _f, _g, _h; - (_b = (_a = targetRef.value) == null ? void 0 : _a.style) == null ? void 0 : _b.setProperty("touch-action", "none"); - if (disableTextSelect) { - (_d = (_c = targetRef.value) == null ? void 0 : _c.style) == null ? void 0 : _d.setProperty("-webkit-user-select", "none"); - (_f = (_e = targetRef.value) == null ? void 0 : _e.style) == null ? void 0 : _f.setProperty("-ms-user-select", "none"); - (_h = (_g = targetRef.value) == null ? void 0 : _g.style) == null ? void 0 : _h.setProperty("user-select", "none"); - } - }); - const stop = () => stops.forEach((s) => s()); - return { - isSwiping: readonly(isSwiping), - direction: readonly(direction), - posStart: readonly(posStart), - posEnd: readonly(posEnd), - distanceX, - distanceY, - stop - }; -} -function usePreferredColorScheme(options) { - const isLight = useMediaQuery("(prefers-color-scheme: light)", options); - const isDark = useMediaQuery("(prefers-color-scheme: dark)", options); - return computed(() => { - if (isDark.value) - return "dark"; - if (isLight.value) - return "light"; - return "no-preference"; - }); -} -function usePreferredContrast(options) { - const isMore = useMediaQuery("(prefers-contrast: more)", options); - const isLess = useMediaQuery("(prefers-contrast: less)", options); - const isCustom = useMediaQuery("(prefers-contrast: custom)", options); - return computed(() => { - if (isMore.value) - return "more"; - if (isLess.value) - return "less"; - if (isCustom.value) - return "custom"; - return "no-preference"; - }); -} -function usePreferredLanguages(options = {}) { - const { window: window2 = defaultWindow } = options; - if (!window2) - return ref(["en"]); - const navigator2 = window2.navigator; - const value = ref(navigator2.languages); - useEventListener(window2, "languagechange", () => { - value.value = navigator2.languages; - }, { passive: true }); - return value; -} -function usePreferredReducedMotion(options) { - const isReduced = useMediaQuery("(prefers-reduced-motion: reduce)", options); - return computed(() => { - if (isReduced.value) - return "reduce"; - return "no-preference"; - }); -} -function usePreferredReducedTransparency(options) { - const isReduced = useMediaQuery("(prefers-reduced-transparency: reduce)", options); - return computed(() => { - if (isReduced.value) - return "reduce"; - return "no-preference"; - }); -} -function usePrevious(value, initialValue) { - const previous = shallowRef(initialValue); - watch( - toRef2(value), - (_, oldValue) => { - previous.value = oldValue; - }, - { flush: "sync" } - ); - return readonly(previous); -} -var topVarName = "--vueuse-safe-area-top"; -var rightVarName = "--vueuse-safe-area-right"; -var bottomVarName = "--vueuse-safe-area-bottom"; -var leftVarName = "--vueuse-safe-area-left"; -function useScreenSafeArea() { - const top = shallowRef(""); - const right = shallowRef(""); - const bottom = shallowRef(""); - const left = shallowRef(""); - if (isClient) { - const topCssVar = useCssVar(topVarName); - const rightCssVar = useCssVar(rightVarName); - const bottomCssVar = useCssVar(bottomVarName); - const leftCssVar = useCssVar(leftVarName); - topCssVar.value = "env(safe-area-inset-top, 0px)"; - rightCssVar.value = "env(safe-area-inset-right, 0px)"; - bottomCssVar.value = "env(safe-area-inset-bottom, 0px)"; - leftCssVar.value = "env(safe-area-inset-left, 0px)"; - update(); - useEventListener("resize", useDebounceFn(update), { passive: true }); - } - function update() { - top.value = getValue(topVarName); - right.value = getValue(rightVarName); - bottom.value = getValue(bottomVarName); - left.value = getValue(leftVarName); - } - return { - top, - right, - bottom, - left, - update - }; -} -function getValue(position) { - return getComputedStyle(document.documentElement).getPropertyValue(position); -} -function useScriptTag(src, onLoaded = noop, options = {}) { - const { - immediate = true, - manual = false, - type = "text/javascript", - async = true, - crossOrigin, - referrerPolicy, - noModule, - defer, - document: document2 = defaultDocument, - attrs = {} - } = options; - const scriptTag = shallowRef(null); - let _promise = null; - const loadScript = (waitForScriptLoad) => new Promise((resolve, reject) => { - const resolveWithElement = (el2) => { - scriptTag.value = el2; - resolve(el2); - return el2; - }; - if (!document2) { - resolve(false); - return; - } - let shouldAppend = false; - let el = document2.querySelector(`script[src="${toValue(src)}"]`); - if (!el) { - el = document2.createElement("script"); - el.type = type; - el.async = async; - el.src = toValue(src); - if (defer) - el.defer = defer; - if (crossOrigin) - el.crossOrigin = crossOrigin; - if (noModule) - el.noModule = noModule; - if (referrerPolicy) - el.referrerPolicy = referrerPolicy; - Object.entries(attrs).forEach(([name, value]) => el == null ? void 0 : el.setAttribute(name, value)); - shouldAppend = true; - } else if (el.hasAttribute("data-loaded")) { - resolveWithElement(el); - } - const listenerOptions = { - passive: true - }; - useEventListener(el, "error", (event) => reject(event), listenerOptions); - useEventListener(el, "abort", (event) => reject(event), listenerOptions); - useEventListener(el, "load", () => { - el.setAttribute("data-loaded", "true"); - onLoaded(el); - resolveWithElement(el); - }, listenerOptions); - if (shouldAppend) - el = document2.head.appendChild(el); - if (!waitForScriptLoad) - resolveWithElement(el); - }); - const load = (waitForScriptLoad = true) => { - if (!_promise) - _promise = loadScript(waitForScriptLoad); - return _promise; - }; - const unload = () => { - if (!document2) - return; - _promise = null; - if (scriptTag.value) - scriptTag.value = null; - const el = document2.querySelector(`script[src="${toValue(src)}"]`); - if (el) - document2.head.removeChild(el); - }; - if (immediate && !manual) - tryOnMounted(load); - if (!manual) - tryOnUnmounted(unload); - return { scriptTag, load, unload }; -} -function checkOverflowScroll(ele) { - const style = window.getComputedStyle(ele); - if (style.overflowX === "scroll" || style.overflowY === "scroll" || style.overflowX === "auto" && ele.clientWidth < ele.scrollWidth || style.overflowY === "auto" && ele.clientHeight < ele.scrollHeight) { - return true; - } else { - const parent = ele.parentNode; - if (!parent || parent.tagName === "BODY") - return false; - return checkOverflowScroll(parent); - } -} -function preventDefault(rawEvent) { - const e = rawEvent || window.event; - const _target = e.target; - if (checkOverflowScroll(_target)) - return false; - if (e.touches.length > 1) - return true; - if (e.preventDefault) - e.preventDefault(); - return false; -} -var elInitialOverflow = /* @__PURE__ */ new WeakMap(); -function useScrollLock(element, initialState = false) { - const isLocked = shallowRef(initialState); - let stopTouchMoveListener = null; - let initialOverflow = ""; - watch(toRef2(element), (el) => { - const target = resolveElement(toValue(el)); - if (target) { - const ele = target; - if (!elInitialOverflow.get(ele)) - elInitialOverflow.set(ele, ele.style.overflow); - if (ele.style.overflow !== "hidden") - initialOverflow = ele.style.overflow; - if (ele.style.overflow === "hidden") - return isLocked.value = true; - if (isLocked.value) - return ele.style.overflow = "hidden"; - } - }, { - immediate: true - }); - const lock = () => { - const el = resolveElement(toValue(element)); - if (!el || isLocked.value) - return; - if (isIOS) { - stopTouchMoveListener = useEventListener( - el, - "touchmove", - (e) => { - preventDefault(e); - }, - { passive: false } - ); - } - el.style.overflow = "hidden"; - isLocked.value = true; - }; - const unlock = () => { - const el = resolveElement(toValue(element)); - if (!el || !isLocked.value) - return; - if (isIOS) - stopTouchMoveListener == null ? void 0 : stopTouchMoveListener(); - el.style.overflow = initialOverflow; - elInitialOverflow.delete(el); - isLocked.value = false; - }; - tryOnScopeDispose(unlock); - return computed({ - get() { - return isLocked.value; - }, - set(v) { - if (v) - lock(); - else unlock(); - } - }); -} -function useSessionStorage(key, initialValue, options = {}) { - const { window: window2 = defaultWindow } = options; - return useStorage(key, initialValue, window2 == null ? void 0 : window2.sessionStorage, options); -} -function useShare(shareOptions = {}, options = {}) { - const { navigator: navigator2 = defaultNavigator } = options; - const _navigator = navigator2; - const isSupported = useSupported(() => _navigator && "canShare" in _navigator); - const share = async (overrideOptions = {}) => { - if (isSupported.value) { - const data = { - ...toValue(shareOptions), - ...toValue(overrideOptions) - }; - let granted = true; - if (data.files && _navigator.canShare) - granted = _navigator.canShare({ files: data.files }); - if (granted) - return _navigator.share(data); - } - }; - return { - isSupported, - share - }; -} -var defaultSortFn = (source, compareFn) => source.sort(compareFn); -var defaultCompare = (a, b) => a - b; -function useSorted(...args) { - var _a, _b, _c, _d; - const [source] = args; - let compareFn = defaultCompare; - let options = {}; - if (args.length === 2) { - if (typeof args[1] === "object") { - options = args[1]; - compareFn = (_a = options.compareFn) != null ? _a : defaultCompare; - } else { - compareFn = (_b = args[1]) != null ? _b : defaultCompare; - } - } else if (args.length > 2) { - compareFn = (_c = args[1]) != null ? _c : defaultCompare; - options = (_d = args[2]) != null ? _d : {}; - } - const { - dirty = false, - sortFn = defaultSortFn - } = options; - if (!dirty) - return computed(() => sortFn([...toValue(source)], compareFn)); - watchEffect(() => { - const result = sortFn(toValue(source), compareFn); - if (isRef(source)) - source.value = result; - else - source.splice(0, source.length, ...result); - }); - return source; -} -function useSpeechRecognition(options = {}) { - const { - interimResults = true, - continuous = true, - maxAlternatives = 1, - window: window2 = defaultWindow - } = options; - const lang = toRef2(options.lang || "en-US"); - const isListening = shallowRef(false); - const isFinal = shallowRef(false); - const result = shallowRef(""); - const error = shallowRef(void 0); - let recognition; - const start = () => { - isListening.value = true; - }; - const stop = () => { - isListening.value = false; - }; - const toggle = (value = !isListening.value) => { - if (value) { - start(); - } else { - stop(); - } - }; - const SpeechRecognition = window2 && (window2.SpeechRecognition || window2.webkitSpeechRecognition); - const isSupported = useSupported(() => SpeechRecognition); - if (isSupported.value) { - recognition = new SpeechRecognition(); - recognition.continuous = continuous; - recognition.interimResults = interimResults; - recognition.lang = toValue(lang); - recognition.maxAlternatives = maxAlternatives; - recognition.onstart = () => { - isListening.value = true; - isFinal.value = false; - }; - watch(lang, (lang2) => { - if (recognition && !isListening.value) - recognition.lang = lang2; - }); - recognition.onresult = (event) => { - const currentResult = event.results[event.resultIndex]; - const { transcript } = currentResult[0]; - isFinal.value = currentResult.isFinal; - result.value = transcript; - error.value = void 0; - }; - recognition.onerror = (event) => { - error.value = event; - }; - recognition.onend = () => { - isListening.value = false; - recognition.lang = toValue(lang); - }; - watch(isListening, (newValue, oldValue) => { - if (newValue === oldValue) - return; - if (newValue) - recognition.start(); - else - recognition.stop(); - }); - } - tryOnScopeDispose(() => { - stop(); - }); - return { - isSupported, - isListening, - isFinal, - recognition, - result, - error, - toggle, - start, - stop - }; -} -function useSpeechSynthesis(text, options = {}) { - const { - pitch = 1, - rate = 1, - volume = 1, - window: window2 = defaultWindow - } = options; - const synth = window2 && window2.speechSynthesis; - const isSupported = useSupported(() => synth); - const isPlaying = shallowRef(false); - const status = shallowRef("init"); - const spokenText = toRef2(text || ""); - const lang = toRef2(options.lang || "en-US"); - const error = shallowRef(void 0); - const toggle = (value = !isPlaying.value) => { - isPlaying.value = value; - }; - const bindEventsForUtterance = (utterance2) => { - utterance2.lang = toValue(lang); - utterance2.voice = toValue(options.voice) || null; - utterance2.pitch = toValue(pitch); - utterance2.rate = toValue(rate); - utterance2.volume = volume; - utterance2.onstart = () => { - isPlaying.value = true; - status.value = "play"; - }; - utterance2.onpause = () => { - isPlaying.value = false; - status.value = "pause"; - }; - utterance2.onresume = () => { - isPlaying.value = true; - status.value = "play"; - }; - utterance2.onend = () => { - isPlaying.value = false; - status.value = "end"; - }; - utterance2.onerror = (event) => { - error.value = event; - }; - }; - const utterance = computed(() => { - isPlaying.value = false; - status.value = "init"; - const newUtterance = new SpeechSynthesisUtterance(spokenText.value); - bindEventsForUtterance(newUtterance); - return newUtterance; - }); - const speak = () => { - synth.cancel(); - if (utterance) - synth.speak(utterance.value); - }; - const stop = () => { - synth.cancel(); - isPlaying.value = false; - }; - if (isSupported.value) { - bindEventsForUtterance(utterance.value); - watch(lang, (lang2) => { - if (utterance.value && !isPlaying.value) - utterance.value.lang = lang2; - }); - if (options.voice) { - watch(options.voice, () => { - synth.cancel(); - }); - } - watch(isPlaying, () => { - if (isPlaying.value) - synth.resume(); - else - synth.pause(); - }); - } - tryOnScopeDispose(() => { - isPlaying.value = false; - }); - return { - isSupported, - isPlaying, - status, - utterance, - error, - stop, - toggle, - speak - }; -} -function useStepper(steps, initialStep) { - const stepsRef = ref(steps); - const stepNames = computed(() => Array.isArray(stepsRef.value) ? stepsRef.value : Object.keys(stepsRef.value)); - const index = ref(stepNames.value.indexOf(initialStep != null ? initialStep : stepNames.value[0])); - const current = computed(() => at(index.value)); - const isFirst = computed(() => index.value === 0); - const isLast = computed(() => index.value === stepNames.value.length - 1); - const next = computed(() => stepNames.value[index.value + 1]); - const previous = computed(() => stepNames.value[index.value - 1]); - function at(index2) { - if (Array.isArray(stepsRef.value)) - return stepsRef.value[index2]; - return stepsRef.value[stepNames.value[index2]]; - } - function get2(step) { - if (!stepNames.value.includes(step)) - return; - return at(stepNames.value.indexOf(step)); - } - function goTo(step) { - if (stepNames.value.includes(step)) - index.value = stepNames.value.indexOf(step); - } - function goToNext() { - if (isLast.value) - return; - index.value++; - } - function goToPrevious() { - if (isFirst.value) - return; - index.value--; - } - function goBackTo(step) { - if (isAfter(step)) - goTo(step); - } - function isNext(step) { - return stepNames.value.indexOf(step) === index.value + 1; - } - function isPrevious(step) { - return stepNames.value.indexOf(step) === index.value - 1; - } - function isCurrent(step) { - return stepNames.value.indexOf(step) === index.value; - } - function isBefore(step) { - return index.value < stepNames.value.indexOf(step); - } - function isAfter(step) { - return index.value > stepNames.value.indexOf(step); - } - return { - steps: stepsRef, - stepNames, - index, - current, - next, - previous, - isFirst, - isLast, - at, - get: get2, - goTo, - goToNext, - goToPrevious, - goBackTo, - isNext, - isPrevious, - isCurrent, - isBefore, - isAfter - }; -} -function useStorageAsync(key, initialValue, storage, options = {}) { - var _a; - const { - flush = "pre", - deep = true, - listenToStorageChanges = true, - writeDefaults = true, - mergeDefaults = false, - shallow, - window: window2 = defaultWindow, - eventFilter, - onError = (e) => { - console.error(e); - } - } = options; - const rawInit = toValue(initialValue); - const type = guessSerializerType(rawInit); - const data = (shallow ? shallowRef : ref)(toValue(initialValue)); - const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type]; - if (!storage) { - try { - storage = getSSRHandler("getDefaultStorageAsync", () => { - var _a2; - return (_a2 = defaultWindow) == null ? void 0 : _a2.localStorage; - })(); - } catch (e) { - onError(e); - } - } - async function read(event) { - if (!storage || event && event.key !== key) - return; - try { - const rawValue = event ? event.newValue : await storage.getItem(key); - if (rawValue == null) { - data.value = rawInit; - if (writeDefaults && rawInit !== null) - await storage.setItem(key, await serializer.write(rawInit)); - } else if (mergeDefaults) { - const value = await serializer.read(rawValue); - if (typeof mergeDefaults === "function") - data.value = mergeDefaults(value, rawInit); - else if (type === "object" && !Array.isArray(value)) - data.value = { ...rawInit, ...value }; - else data.value = value; - } else { - data.value = await serializer.read(rawValue); - } - } catch (e) { - onError(e); - } - } - read(); - if (window2 && listenToStorageChanges) - useEventListener(window2, "storage", (e) => Promise.resolve().then(() => read(e)), { passive: true }); - if (storage) { - watchWithFilter( - data, - async () => { - try { - if (data.value == null) - await storage.removeItem(key); - else - await storage.setItem(key, await serializer.write(data.value)); - } catch (e) { - onError(e); - } - }, - { - flush, - deep, - eventFilter - } - ); - } - return data; -} -var _id = 0; -function useStyleTag(css, options = {}) { - const isLoaded = shallowRef(false); - const { - document: document2 = defaultDocument, - immediate = true, - manual = false, - id = `vueuse_styletag_${++_id}` - } = options; - const cssRef = shallowRef(css); - let stop = () => { - }; - const load = () => { - if (!document2) - return; - const el = document2.getElementById(id) || document2.createElement("style"); - if (!el.isConnected) { - el.id = id; - if (options.media) - el.media = options.media; - document2.head.appendChild(el); - } - if (isLoaded.value) - return; - stop = watch( - cssRef, - (value) => { - el.textContent = value; - }, - { immediate: true } - ); - isLoaded.value = true; - }; - const unload = () => { - if (!document2 || !isLoaded.value) - return; - stop(); - document2.head.removeChild(document2.getElementById(id)); - isLoaded.value = false; - }; - if (immediate && !manual) - tryOnMounted(load); - if (!manual) - tryOnScopeDispose(unload); - return { - id, - css: cssRef, - unload, - load, - isLoaded: readonly(isLoaded) - }; -} -function useSwipe(target, options = {}) { - const { - threshold = 50, - onSwipe, - onSwipeEnd, - onSwipeStart, - passive = true - } = options; - const coordsStart = reactive({ x: 0, y: 0 }); - const coordsEnd = reactive({ x: 0, y: 0 }); - const diffX = computed(() => coordsStart.x - coordsEnd.x); - const diffY = computed(() => coordsStart.y - coordsEnd.y); - const { max, abs } = Math; - const isThresholdExceeded = computed(() => max(abs(diffX.value), abs(diffY.value)) >= threshold); - const isSwiping = shallowRef(false); - const direction = computed(() => { - if (!isThresholdExceeded.value) - return "none"; - if (abs(diffX.value) > abs(diffY.value)) { - return diffX.value > 0 ? "left" : "right"; - } else { - return diffY.value > 0 ? "up" : "down"; - } - }); - const getTouchEventCoords = (e) => [e.touches[0].clientX, e.touches[0].clientY]; - const updateCoordsStart = (x, y) => { - coordsStart.x = x; - coordsStart.y = y; - }; - const updateCoordsEnd = (x, y) => { - coordsEnd.x = x; - coordsEnd.y = y; - }; - const listenerOptions = { passive, capture: !passive }; - const onTouchEnd = (e) => { - if (isSwiping.value) - onSwipeEnd == null ? void 0 : onSwipeEnd(e, direction.value); - isSwiping.value = false; - }; - const stops = [ - useEventListener(target, "touchstart", (e) => { - if (e.touches.length !== 1) - return; - const [x, y] = getTouchEventCoords(e); - updateCoordsStart(x, y); - updateCoordsEnd(x, y); - onSwipeStart == null ? void 0 : onSwipeStart(e); - }, listenerOptions), - useEventListener(target, "touchmove", (e) => { - if (e.touches.length !== 1) - return; - const [x, y] = getTouchEventCoords(e); - updateCoordsEnd(x, y); - if (listenerOptions.capture && !listenerOptions.passive && Math.abs(diffX.value) > Math.abs(diffY.value)) - e.preventDefault(); - if (!isSwiping.value && isThresholdExceeded.value) - isSwiping.value = true; - if (isSwiping.value) - onSwipe == null ? void 0 : onSwipe(e); - }, listenerOptions), - useEventListener(target, ["touchend", "touchcancel"], onTouchEnd, listenerOptions) - ]; - const stop = () => stops.forEach((s) => s()); - return { - isSwiping, - direction, - coordsStart, - coordsEnd, - lengthX: diffX, - lengthY: diffY, - stop, - // TODO: Remove in the next major version - isPassiveEventSupported: true - }; -} -function useTemplateRefsList() { - const refs = ref([]); - refs.value.set = (el) => { - if (el) - refs.value.push(el); - }; - onBeforeUpdate(() => { - refs.value.length = 0; - }); - return refs; -} -function useTextDirection(options = {}) { - const { - document: document2 = defaultDocument, - selector = "html", - observe = false, - initialValue = "ltr" - } = options; - function getValue2() { - var _a, _b; - return (_b = (_a = document2 == null ? void 0 : document2.querySelector(selector)) == null ? void 0 : _a.getAttribute("dir")) != null ? _b : initialValue; - } - const dir = ref(getValue2()); - tryOnMounted(() => dir.value = getValue2()); - if (observe && document2) { - useMutationObserver( - document2.querySelector(selector), - () => dir.value = getValue2(), - { attributes: true } - ); - } - return computed({ - get() { - return dir.value; - }, - set(v) { - var _a, _b; - dir.value = v; - if (!document2) - return; - if (dir.value) - (_a = document2.querySelector(selector)) == null ? void 0 : _a.setAttribute("dir", dir.value); - else - (_b = document2.querySelector(selector)) == null ? void 0 : _b.removeAttribute("dir"); - } - }); -} -function getRangesFromSelection(selection) { - var _a; - const rangeCount = (_a = selection.rangeCount) != null ? _a : 0; - return Array.from({ length: rangeCount }, (_, i) => selection.getRangeAt(i)); -} -function useTextSelection(options = {}) { - const { - window: window2 = defaultWindow - } = options; - const selection = ref(null); - const text = computed(() => { - var _a, _b; - return (_b = (_a = selection.value) == null ? void 0 : _a.toString()) != null ? _b : ""; - }); - const ranges = computed(() => selection.value ? getRangesFromSelection(selection.value) : []); - const rects = computed(() => ranges.value.map((range) => range.getBoundingClientRect())); - function onSelectionChange() { - selection.value = null; - if (window2) - selection.value = window2.getSelection(); - } - if (window2) - useEventListener(window2.document, "selectionchange", onSelectionChange, { passive: true }); - return { - text, - rects, - ranges, - selection - }; -} -function tryRequestAnimationFrame(window2 = defaultWindow, fn) { - if (window2 && typeof window2.requestAnimationFrame === "function") { - window2.requestAnimationFrame(fn); - } else { - fn(); - } -} -function useTextareaAutosize(options = {}) { - var _a, _b; - const { window: window2 = defaultWindow } = options; - const textarea = toRef2(options == null ? void 0 : options.element); - const input = toRef2((_a = options == null ? void 0 : options.input) != null ? _a : ""); - const styleProp = (_b = options == null ? void 0 : options.styleProp) != null ? _b : "height"; - const textareaScrollHeight = shallowRef(1); - const textareaOldWidth = shallowRef(0); - function triggerResize() { - var _a2; - if (!textarea.value) - return; - let height = ""; - textarea.value.style[styleProp] = "1px"; - textareaScrollHeight.value = (_a2 = textarea.value) == null ? void 0 : _a2.scrollHeight; - const _styleTarget = toValue(options == null ? void 0 : options.styleTarget); - if (_styleTarget) - _styleTarget.style[styleProp] = `${textareaScrollHeight.value}px`; - else - height = `${textareaScrollHeight.value}px`; - textarea.value.style[styleProp] = height; - } - watch([input, textarea], () => nextTick(triggerResize), { immediate: true }); - watch(textareaScrollHeight, () => { - var _a2; - return (_a2 = options == null ? void 0 : options.onResize) == null ? void 0 : _a2.call(options); - }); - useResizeObserver(textarea, ([{ contentRect }]) => { - if (textareaOldWidth.value === contentRect.width) - return; - tryRequestAnimationFrame(window2, () => { - textareaOldWidth.value = contentRect.width; - triggerResize(); - }); - }); - if (options == null ? void 0 : options.watch) - watch(options.watch, triggerResize, { immediate: true, deep: true }); - return { - textarea, - input, - triggerResize - }; -} -function useThrottledRefHistory(source, options = {}) { - const { throttle = 200, trailing = true } = options; - const filter = throttleFilter(throttle, trailing); - const history = useRefHistory(source, { ...options, eventFilter: filter }); - return { - ...history - }; -} -var DEFAULT_UNITS = [ - { max: 6e4, value: 1e3, name: "second" }, - { max: 276e4, value: 6e4, name: "minute" }, - { max: 72e6, value: 36e5, name: "hour" }, - { max: 5184e5, value: 864e5, name: "day" }, - { max: 24192e5, value: 6048e5, name: "week" }, - { max: 28512e6, value: 2592e6, name: "month" }, - { max: Number.POSITIVE_INFINITY, value: 31536e6, name: "year" } -]; -var DEFAULT_MESSAGES = { - justNow: "just now", - past: (n) => n.match(/\d/) ? `${n} ago` : n, - future: (n) => n.match(/\d/) ? `in ${n}` : n, - month: (n, past) => n === 1 ? past ? "last month" : "next month" : `${n} month${n > 1 ? "s" : ""}`, - year: (n, past) => n === 1 ? past ? "last year" : "next year" : `${n} year${n > 1 ? "s" : ""}`, - day: (n, past) => n === 1 ? past ? "yesterday" : "tomorrow" : `${n} day${n > 1 ? "s" : ""}`, - week: (n, past) => n === 1 ? past ? "last week" : "next week" : `${n} week${n > 1 ? "s" : ""}`, - hour: (n) => `${n} hour${n > 1 ? "s" : ""}`, - minute: (n) => `${n} minute${n > 1 ? "s" : ""}`, - second: (n) => `${n} second${n > 1 ? "s" : ""}`, - invalid: "" -}; -function DEFAULT_FORMATTER(date) { - return date.toISOString().slice(0, 10); -} -function useTimeAgo(time, options = {}) { - const { - controls: exposeControls = false, - updateInterval = 3e4 - } = options; - const { now: now2, ...controls } = useNow({ interval: updateInterval, controls: true }); - const timeAgo = computed(() => formatTimeAgo(new Date(toValue(time)), options, toValue(now2))); - if (exposeControls) { - return { - timeAgo, - ...controls - }; - } else { - return timeAgo; - } -} -function formatTimeAgo(from, options = {}, now2 = Date.now()) { - var _a; - const { - max, - messages = DEFAULT_MESSAGES, - fullDateFormatter = DEFAULT_FORMATTER, - units = DEFAULT_UNITS, - showSecond = false, - rounding = "round" - } = options; - const roundFn = typeof rounding === "number" ? (n) => +n.toFixed(rounding) : Math[rounding]; - const diff = +now2 - +from; - const absDiff = Math.abs(diff); - function getValue2(diff2, unit) { - return roundFn(Math.abs(diff2) / unit.value); - } - function format(diff2, unit) { - const val = getValue2(diff2, unit); - const past = diff2 > 0; - const str = applyFormat(unit.name, val, past); - return applyFormat(past ? "past" : "future", str, past); - } - function applyFormat(name, val, isPast) { - const formatter = messages[name]; - if (typeof formatter === "function") - return formatter(val, isPast); - return formatter.replace("{0}", val.toString()); - } - if (absDiff < 6e4 && !showSecond) - return messages.justNow; - if (typeof max === "number" && absDiff > max) - return fullDateFormatter(new Date(from)); - if (typeof max === "string") { - const unitMax = (_a = units.find((i) => i.name === max)) == null ? void 0 : _a.max; - if (unitMax && absDiff > unitMax) - return fullDateFormatter(new Date(from)); - } - for (const [idx, unit] of units.entries()) { - const val = getValue2(diff, unit); - if (val <= 0 && units[idx - 1]) - return format(diff, units[idx - 1]); - if (absDiff < unit.max) - return format(diff, unit); - } - return messages.invalid; -} -function useTimeoutPoll(fn, interval, options = {}) { - const { - immediate = true, - immediateCallback = false - } = options; - const { start } = useTimeoutFn(loop, interval, { immediate }); - const isActive = shallowRef(false); - async function loop() { - if (!isActive.value) - return; - await fn(); - start(); - } - function resume() { - if (!isActive.value) { - isActive.value = true; - if (immediateCallback) - fn(); - start(); - } - } - function pause() { - isActive.value = false; - } - if (immediate && isClient) - resume(); - tryOnScopeDispose(pause); - return { - isActive, - pause, - resume - }; -} -function useTimestamp(options = {}) { - const { - controls: exposeControls = false, - offset = 0, - immediate = true, - interval = "requestAnimationFrame", - callback - } = options; - const ts = shallowRef(timestamp() + offset); - const update = () => ts.value = timestamp() + offset; - const cb = callback ? () => { - update(); - callback(ts.value); - } : update; - const controls = interval === "requestAnimationFrame" ? useRafFn(cb, { immediate }) : useIntervalFn(cb, interval, { immediate }); - if (exposeControls) { - return { - timestamp: ts, - ...controls - }; - } else { - return ts; - } -} -function useTitle(newTitle = null, options = {}) { - var _a, _b, _c; - const { - document: document2 = defaultDocument, - restoreOnUnmount = (t) => t - } = options; - const originalTitle = (_a = document2 == null ? void 0 : document2.title) != null ? _a : ""; - const title = toRef2((_b = newTitle != null ? newTitle : document2 == null ? void 0 : document2.title) != null ? _b : null); - const isReadonly2 = !!(newTitle && typeof newTitle === "function"); - function format(t) { - if (!("titleTemplate" in options)) - return t; - const template = options.titleTemplate || "%s"; - return typeof template === "function" ? template(t) : toValue(template).replace(/%s/g, t); - } - watch( - title, - (newValue, oldValue) => { - if (newValue !== oldValue && document2) - document2.title = format(newValue != null ? newValue : ""); - }, - { immediate: true } - ); - if (options.observe && !options.titleTemplate && document2 && !isReadonly2) { - useMutationObserver( - (_c = document2.head) == null ? void 0 : _c.querySelector("title"), - () => { - if (document2 && document2.title !== title.value) - title.value = format(document2.title); - }, - { childList: true } - ); - } - tryOnScopeDispose(() => { - if (restoreOnUnmount) { - const restoredTitle = restoreOnUnmount(originalTitle, title.value || ""); - if (restoredTitle != null && document2) - document2.title = restoredTitle; - } - }); - return title; -} -var _TransitionPresets = { - easeInSine: [0.12, 0, 0.39, 0], - easeOutSine: [0.61, 1, 0.88, 1], - easeInOutSine: [0.37, 0, 0.63, 1], - easeInQuad: [0.11, 0, 0.5, 0], - easeOutQuad: [0.5, 1, 0.89, 1], - easeInOutQuad: [0.45, 0, 0.55, 1], - easeInCubic: [0.32, 0, 0.67, 0], - easeOutCubic: [0.33, 1, 0.68, 1], - easeInOutCubic: [0.65, 0, 0.35, 1], - easeInQuart: [0.5, 0, 0.75, 0], - easeOutQuart: [0.25, 1, 0.5, 1], - easeInOutQuart: [0.76, 0, 0.24, 1], - easeInQuint: [0.64, 0, 0.78, 0], - easeOutQuint: [0.22, 1, 0.36, 1], - easeInOutQuint: [0.83, 0, 0.17, 1], - easeInExpo: [0.7, 0, 0.84, 0], - easeOutExpo: [0.16, 1, 0.3, 1], - easeInOutExpo: [0.87, 0, 0.13, 1], - easeInCirc: [0.55, 0, 1, 0.45], - easeOutCirc: [0, 0.55, 0.45, 1], - easeInOutCirc: [0.85, 0, 0.15, 1], - easeInBack: [0.36, 0, 0.66, -0.56], - easeOutBack: [0.34, 1.56, 0.64, 1], - easeInOutBack: [0.68, -0.6, 0.32, 1.6] -}; -var TransitionPresets = Object.assign({}, { linear: identity }, _TransitionPresets); -function createEasingFunction([p0, p1, p2, p3]) { - const a = (a1, a2) => 1 - 3 * a2 + 3 * a1; - const b = (a1, a2) => 3 * a2 - 6 * a1; - const c = (a1) => 3 * a1; - const calcBezier = (t, a1, a2) => ((a(a1, a2) * t + b(a1, a2)) * t + c(a1)) * t; - const getSlope = (t, a1, a2) => 3 * a(a1, a2) * t * t + 2 * b(a1, a2) * t + c(a1); - const getTforX = (x) => { - let aGuessT = x; - for (let i = 0; i < 4; ++i) { - const currentSlope = getSlope(aGuessT, p0, p2); - if (currentSlope === 0) - return aGuessT; - const currentX = calcBezier(aGuessT, p0, p2) - x; - aGuessT -= currentX / currentSlope; - } - return aGuessT; - }; - return (x) => p0 === p1 && p2 === p3 ? x : calcBezier(getTforX(x), p1, p3); -} -function lerp(a, b, alpha) { - return a + alpha * (b - a); -} -function toVec(t) { - return (typeof t === "number" ? [t] : t) || []; -} -function executeTransition(source, from, to, options = {}) { - var _a, _b; - const fromVal = toValue(from); - const toVal = toValue(to); - const v1 = toVec(fromVal); - const v2 = toVec(toVal); - const duration = (_a = toValue(options.duration)) != null ? _a : 1e3; - const startedAt = Date.now(); - const endAt = Date.now() + duration; - const trans = typeof options.transition === "function" ? options.transition : (_b = toValue(options.transition)) != null ? _b : identity; - const ease = typeof trans === "function" ? trans : createEasingFunction(trans); - return new Promise((resolve) => { - source.value = fromVal; - const tick = () => { - var _a2; - if ((_a2 = options.abort) == null ? void 0 : _a2.call(options)) { - resolve(); - return; - } - const now2 = Date.now(); - const alpha = ease((now2 - startedAt) / duration); - const arr = toVec(source.value).map((n, i) => lerp(v1[i], v2[i], alpha)); - if (Array.isArray(source.value)) - source.value = arr.map((n, i) => { - var _a3, _b2; - return lerp((_a3 = v1[i]) != null ? _a3 : 0, (_b2 = v2[i]) != null ? _b2 : 0, alpha); - }); - else if (typeof source.value === "number") - source.value = arr[0]; - if (now2 < endAt) { - requestAnimationFrame(tick); - } else { - source.value = toVal; - resolve(); - } - }; - tick(); - }); -} -function useTransition(source, options = {}) { - let currentId = 0; - const sourceVal = () => { - const v = toValue(source); - return typeof v === "number" ? v : v.map(toValue); - }; - const outputRef = ref(sourceVal()); - watch(sourceVal, async (to) => { - var _a, _b; - if (toValue(options.disabled)) - return; - const id = ++currentId; - if (options.delay) - await promiseTimeout(toValue(options.delay)); - if (id !== currentId) - return; - const toVal = Array.isArray(to) ? to.map(toValue) : toValue(to); - (_a = options.onStarted) == null ? void 0 : _a.call(options); - await executeTransition(outputRef, outputRef.value, toVal, { - ...options, - abort: () => { - var _a2; - return id !== currentId || ((_a2 = options.abort) == null ? void 0 : _a2.call(options)); - } - }); - (_b = options.onFinished) == null ? void 0 : _b.call(options); - }, { deep: true }); - watch(() => toValue(options.disabled), (disabled) => { - if (disabled) { - currentId++; - outputRef.value = sourceVal(); - } - }); - tryOnScopeDispose(() => { - currentId++; - }); - return computed(() => toValue(options.disabled) ? sourceVal() : outputRef.value); -} -function useUrlSearchParams(mode = "history", options = {}) { - const { - initialValue = {}, - removeNullishValues = true, - removeFalsyValues = false, - write: enableWrite = true, - writeMode = "replace", - window: window2 = defaultWindow - } = options; - if (!window2) - return reactive(initialValue); - const state = reactive({}); - function getRawParams() { - if (mode === "history") { - return window2.location.search || ""; - } else if (mode === "hash") { - const hash = window2.location.hash || ""; - const index = hash.indexOf("?"); - return index > 0 ? hash.slice(index) : ""; - } else { - return (window2.location.hash || "").replace(/^#/, ""); - } - } - function constructQuery(params) { - const stringified = params.toString(); - if (mode === "history") - return `${stringified ? `?${stringified}` : ""}${window2.location.hash || ""}`; - if (mode === "hash-params") - return `${window2.location.search || ""}${stringified ? `#${stringified}` : ""}`; - const hash = window2.location.hash || "#"; - const index = hash.indexOf("?"); - if (index > 0) - return `${window2.location.search || ""}${hash.slice(0, index)}${stringified ? `?${stringified}` : ""}`; - return `${window2.location.search || ""}${hash}${stringified ? `?${stringified}` : ""}`; - } - function read() { - return new URLSearchParams(getRawParams()); - } - function updateState(params) { - const unusedKeys = new Set(Object.keys(state)); - for (const key of params.keys()) { - const paramsForKey = params.getAll(key); - state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || ""; - unusedKeys.delete(key); - } - Array.from(unusedKeys).forEach((key) => delete state[key]); - } - const { pause, resume } = watchPausable( - state, - () => { - const params = new URLSearchParams(""); - Object.keys(state).forEach((key) => { - const mapEntry = state[key]; - if (Array.isArray(mapEntry)) - mapEntry.forEach((value) => params.append(key, value)); - else if (removeNullishValues && mapEntry == null) - params.delete(key); - else if (removeFalsyValues && !mapEntry) - params.delete(key); - else - params.set(key, mapEntry); - }); - write(params, false); - }, - { deep: true } - ); - function write(params, shouldUpdate) { - pause(); - if (shouldUpdate) - updateState(params); - if (writeMode === "replace") { - window2.history.replaceState( - window2.history.state, - window2.document.title, - window2.location.pathname + constructQuery(params) - ); - } else { - window2.history.pushState( - window2.history.state, - window2.document.title, - window2.location.pathname + constructQuery(params) - ); - } - resume(); - } - function onChanged() { - if (!enableWrite) - return; - write(read(), true); - } - const listenerOptions = { passive: true }; - useEventListener(window2, "popstate", onChanged, listenerOptions); - if (mode !== "history") - useEventListener(window2, "hashchange", onChanged, listenerOptions); - const initial = read(); - if (initial.keys().next().value) - updateState(initial); - else - Object.assign(state, initialValue); - return state; -} -function useUserMedia(options = {}) { - var _a, _b; - const enabled = shallowRef((_a = options.enabled) != null ? _a : false); - const autoSwitch = shallowRef((_b = options.autoSwitch) != null ? _b : true); - const constraints = ref(options.constraints); - const { navigator: navigator2 = defaultNavigator } = options; - const isSupported = useSupported(() => { - var _a2; - return (_a2 = navigator2 == null ? void 0 : navigator2.mediaDevices) == null ? void 0 : _a2.getUserMedia; - }); - const stream = shallowRef(); - function getDeviceOptions(type) { - switch (type) { - case "video": { - if (constraints.value) - return constraints.value.video || false; - break; - } - case "audio": { - if (constraints.value) - return constraints.value.audio || false; - break; - } - } - } - async function _start() { - if (!isSupported.value || stream.value) - return; - stream.value = await navigator2.mediaDevices.getUserMedia({ - video: getDeviceOptions("video"), - audio: getDeviceOptions("audio") - }); - return stream.value; - } - function _stop() { - var _a2; - (_a2 = stream.value) == null ? void 0 : _a2.getTracks().forEach((t) => t.stop()); - stream.value = void 0; - } - function stop() { - _stop(); - enabled.value = false; - } - async function start() { - await _start(); - if (stream.value) - enabled.value = true; - return stream.value; - } - async function restart() { - _stop(); - return await start(); - } - watch( - enabled, - (v) => { - if (v) - _start(); - else _stop(); - }, - { immediate: true } - ); - watch( - constraints, - () => { - if (autoSwitch.value && stream.value) - restart(); - }, - { immediate: true } - ); - tryOnScopeDispose(() => { - stop(); - }); - return { - isSupported, - stream, - start, - stop, - restart, - constraints, - enabled, - autoSwitch - }; -} -function useVModel(props, key, emit, options = {}) { - var _a, _b, _c; - const { - clone = false, - passive = false, - eventName, - deep = false, - defaultValue, - shouldEmit - } = options; - const vm = getCurrentInstance(); - const _emit = emit || (vm == null ? void 0 : vm.emit) || ((_a = vm == null ? void 0 : vm.$emit) == null ? void 0 : _a.bind(vm)) || ((_c = (_b = vm == null ? void 0 : vm.proxy) == null ? void 0 : _b.$emit) == null ? void 0 : _c.bind(vm == null ? void 0 : vm.proxy)); - let event = eventName; - if (!key) { - key = "modelValue"; - } - event = event || `update:${key.toString()}`; - const cloneFn = (val) => !clone ? val : typeof clone === "function" ? clone(val) : cloneFnJSON(val); - const getValue2 = () => isDef(props[key]) ? cloneFn(props[key]) : defaultValue; - const triggerEmit = (value) => { - if (shouldEmit) { - if (shouldEmit(value)) - _emit(event, value); - } else { - _emit(event, value); - } - }; - if (passive) { - const initialValue = getValue2(); - const proxy = ref(initialValue); - let isUpdating = false; - watch( - () => props[key], - (v) => { - if (!isUpdating) { - isUpdating = true; - proxy.value = cloneFn(v); - nextTick(() => isUpdating = false); - } - } - ); - watch( - proxy, - (v) => { - if (!isUpdating && (v !== props[key] || deep)) - triggerEmit(v); - }, - { deep } - ); - return proxy; - } else { - return computed({ - get() { - return getValue2(); - }, - set(value) { - triggerEmit(value); - } - }); - } -} -function useVModels(props, emit, options = {}) { - const ret = {}; - for (const key in props) { - ret[key] = useVModel( - props, - key, - emit, - options - ); - } - return ret; -} -function useVibrate(options) { - const { - pattern = [], - interval = 0, - navigator: navigator2 = defaultNavigator - } = options || {}; - const isSupported = useSupported(() => typeof navigator2 !== "undefined" && "vibrate" in navigator2); - const patternRef = toRef2(pattern); - let intervalControls; - const vibrate = (pattern2 = patternRef.value) => { - if (isSupported.value) - navigator2.vibrate(pattern2); - }; - const stop = () => { - if (isSupported.value) - navigator2.vibrate(0); - intervalControls == null ? void 0 : intervalControls.pause(); - }; - if (interval > 0) { - intervalControls = useIntervalFn( - vibrate, - interval, - { - immediate: false, - immediateCallback: false - } - ); - } - return { - isSupported, - pattern, - intervalControls, - vibrate, - stop - }; -} -function useVirtualList(list, options) { - const { containerStyle, wrapperProps, scrollTo, calculateRange, currentList, containerRef } = "itemHeight" in options ? useVerticalVirtualList(options, list) : useHorizontalVirtualList(options, list); - return { - list: currentList, - scrollTo, - containerProps: { - ref: containerRef, - onScroll: () => { - calculateRange(); - }, - style: containerStyle - }, - wrapperProps - }; -} -function useVirtualListResources(list) { - const containerRef = shallowRef(null); - const size = useElementSize(containerRef); - const currentList = ref([]); - const source = shallowRef(list); - const state = ref({ start: 0, end: 10 }); - return { state, source, currentList, size, containerRef }; -} -function createGetViewCapacity(state, source, itemSize) { - return (containerSize) => { - if (typeof itemSize === "number") - return Math.ceil(containerSize / itemSize); - const { start = 0 } = state.value; - let sum = 0; - let capacity = 0; - for (let i = start; i < source.value.length; i++) { - const size = itemSize(i); - sum += size; - capacity = i; - if (sum > containerSize) - break; - } - return capacity - start; - }; -} -function createGetOffset(source, itemSize) { - return (scrollDirection) => { - if (typeof itemSize === "number") - return Math.floor(scrollDirection / itemSize) + 1; - let sum = 0; - let offset = 0; - for (let i = 0; i < source.value.length; i++) { - const size = itemSize(i); - sum += size; - if (sum >= scrollDirection) { - offset = i; - break; - } - } - return offset + 1; - }; -} -function createCalculateRange(type, overscan, getOffset, getViewCapacity, { containerRef, state, currentList, source }) { - return () => { - const element = containerRef.value; - if (element) { - const offset = getOffset(type === "vertical" ? element.scrollTop : element.scrollLeft); - const viewCapacity = getViewCapacity(type === "vertical" ? element.clientHeight : element.clientWidth); - const from = offset - overscan; - const to = offset + viewCapacity + overscan; - state.value = { - start: from < 0 ? 0 : from, - end: to > source.value.length ? source.value.length : to - }; - currentList.value = source.value.slice(state.value.start, state.value.end).map((ele, index) => ({ - data: ele, - index: index + state.value.start - })); - } - }; -} -function createGetDistance(itemSize, source) { - return (index) => { - if (typeof itemSize === "number") { - const size2 = index * itemSize; - return size2; - } - const size = source.value.slice(0, index).reduce((sum, _, i) => sum + itemSize(i), 0); - return size; - }; -} -function useWatchForSizes(size, list, containerRef, calculateRange) { - watch([size.width, size.height, list, containerRef], () => { - calculateRange(); - }); -} -function createComputedTotalSize(itemSize, source) { - return computed(() => { - if (typeof itemSize === "number") - return source.value.length * itemSize; - return source.value.reduce((sum, _, index) => sum + itemSize(index), 0); - }); -} -var scrollToDictionaryForElementScrollKey = { - horizontal: "scrollLeft", - vertical: "scrollTop" -}; -function createScrollTo(type, calculateRange, getDistance, containerRef) { - return (index) => { - if (containerRef.value) { - containerRef.value[scrollToDictionaryForElementScrollKey[type]] = getDistance(index); - calculateRange(); - } - }; -} -function useHorizontalVirtualList(options, list) { - const resources = useVirtualListResources(list); - const { state, source, currentList, size, containerRef } = resources; - const containerStyle = { overflowX: "auto" }; - const { itemWidth, overscan = 5 } = options; - const getViewCapacity = createGetViewCapacity(state, source, itemWidth); - const getOffset = createGetOffset(source, itemWidth); - const calculateRange = createCalculateRange("horizontal", overscan, getOffset, getViewCapacity, resources); - const getDistanceLeft = createGetDistance(itemWidth, source); - const offsetLeft = computed(() => getDistanceLeft(state.value.start)); - const totalWidth = createComputedTotalSize(itemWidth, source); - useWatchForSizes(size, list, containerRef, calculateRange); - const scrollTo = createScrollTo("horizontal", calculateRange, getDistanceLeft, containerRef); - const wrapperProps = computed(() => { - return { - style: { - height: "100%", - width: `${totalWidth.value - offsetLeft.value}px`, - marginLeft: `${offsetLeft.value}px`, - display: "flex" - } - }; - }); - return { - scrollTo, - calculateRange, - wrapperProps, - containerStyle, - currentList, - containerRef - }; -} -function useVerticalVirtualList(options, list) { - const resources = useVirtualListResources(list); - const { state, source, currentList, size, containerRef } = resources; - const containerStyle = { overflowY: "auto" }; - const { itemHeight, overscan = 5 } = options; - const getViewCapacity = createGetViewCapacity(state, source, itemHeight); - const getOffset = createGetOffset(source, itemHeight); - const calculateRange = createCalculateRange("vertical", overscan, getOffset, getViewCapacity, resources); - const getDistanceTop = createGetDistance(itemHeight, source); - const offsetTop = computed(() => getDistanceTop(state.value.start)); - const totalHeight = createComputedTotalSize(itemHeight, source); - useWatchForSizes(size, list, containerRef, calculateRange); - const scrollTo = createScrollTo("vertical", calculateRange, getDistanceTop, containerRef); - const wrapperProps = computed(() => { - return { - style: { - width: "100%", - height: `${totalHeight.value - offsetTop.value}px`, - marginTop: `${offsetTop.value}px` - } - }; - }); - return { - calculateRange, - scrollTo, - containerStyle, - wrapperProps, - currentList, - containerRef - }; -} -function useWakeLock(options = {}) { - const { - navigator: navigator2 = defaultNavigator, - document: document2 = defaultDocument - } = options; - const requestedType = shallowRef(false); - const sentinel = shallowRef(null); - const documentVisibility = useDocumentVisibility({ document: document2 }); - const isSupported = useSupported(() => navigator2 && "wakeLock" in navigator2); - const isActive = computed(() => !!sentinel.value && documentVisibility.value === "visible"); - if (isSupported.value) { - useEventListener(sentinel, "release", () => { - var _a, _b; - requestedType.value = (_b = (_a = sentinel.value) == null ? void 0 : _a.type) != null ? _b : false; - }, { passive: true }); - whenever( - () => documentVisibility.value === "visible" && (document2 == null ? void 0 : document2.visibilityState) === "visible" && requestedType.value, - (type) => { - requestedType.value = false; - forceRequest(type); - } - ); - } - async function forceRequest(type) { - var _a; - await ((_a = sentinel.value) == null ? void 0 : _a.release()); - sentinel.value = isSupported.value ? await navigator2.wakeLock.request(type) : null; - } - async function request(type) { - if (documentVisibility.value === "visible") - await forceRequest(type); - else - requestedType.value = type; - } - async function release() { - requestedType.value = false; - const s = sentinel.value; - sentinel.value = null; - await (s == null ? void 0 : s.release()); - } - return { - sentinel, - isSupported, - isActive, - request, - forceRequest, - release - }; -} -function useWebNotification(options = {}) { - const { - window: window2 = defaultWindow, - requestPermissions: _requestForPermissions = true - } = options; - const defaultWebNotificationOptions = options; - const isSupported = useSupported(() => { - if (!window2 || !("Notification" in window2)) - return false; - if (Notification.permission === "granted") - return true; - try { - const notification2 = new Notification(""); - notification2.onshow = () => { - notification2.close(); - }; - } catch (e) { - if (e.name === "TypeError") - return false; - } - return true; - }); - const permissionGranted = shallowRef(isSupported.value && "permission" in Notification && Notification.permission === "granted"); - const notification = ref(null); - const ensurePermissions = async () => { - if (!isSupported.value) - return; - if (!permissionGranted.value && Notification.permission !== "denied") { - const result = await Notification.requestPermission(); - if (result === "granted") - permissionGranted.value = true; - } - return permissionGranted.value; - }; - const { on: onClick, trigger: clickTrigger } = createEventHook(); - const { on: onShow, trigger: showTrigger } = createEventHook(); - const { on: onError, trigger: errorTrigger } = createEventHook(); - const { on: onClose, trigger: closeTrigger } = createEventHook(); - const show = async (overrides) => { - if (!isSupported.value || !permissionGranted.value) - return; - const options2 = Object.assign({}, defaultWebNotificationOptions, overrides); - notification.value = new Notification(options2.title || "", options2); - notification.value.onclick = clickTrigger; - notification.value.onshow = showTrigger; - notification.value.onerror = errorTrigger; - notification.value.onclose = closeTrigger; - return notification.value; - }; - const close = () => { - if (notification.value) - notification.value.close(); - notification.value = null; - }; - if (_requestForPermissions) - tryOnMounted(ensurePermissions); - tryOnScopeDispose(close); - if (isSupported.value && window2) { - const document2 = window2.document; - useEventListener(document2, "visibilitychange", (e) => { - e.preventDefault(); - if (document2.visibilityState === "visible") { - close(); - } - }); - } - return { - isSupported, - notification, - ensurePermissions, - permissionGranted, - show, - close, - onClick, - onShow, - onError, - onClose - }; -} -var DEFAULT_PING_MESSAGE = "ping"; -function resolveNestedOptions(options) { - if (options === true) - return {}; - return options; -} -function useWebSocket(url, options = {}) { - const { - onConnected, - onDisconnected, - onError, - onMessage, - immediate = true, - autoConnect = true, - autoClose = true, - protocols = [] - } = options; - const data = ref(null); - const status = shallowRef("CLOSED"); - const wsRef = ref(); - const urlRef = toRef2(url); - let heartbeatPause; - let heartbeatResume; - let explicitlyClosed = false; - let retried = 0; - let bufferedData = []; - let retryTimeout; - let pongTimeoutWait; - const _sendBuffer = () => { - if (bufferedData.length && wsRef.value && status.value === "OPEN") { - for (const buffer of bufferedData) - wsRef.value.send(buffer); - bufferedData = []; - } - }; - const resetRetry = () => { - if (retryTimeout != null) { - clearTimeout(retryTimeout); - retryTimeout = void 0; - } - }; - const resetHeartbeat = () => { - clearTimeout(pongTimeoutWait); - pongTimeoutWait = void 0; - }; - const close = (code = 1e3, reason) => { - resetRetry(); - if (!isClient && !isWorker || !wsRef.value) - return; - explicitlyClosed = true; - resetHeartbeat(); - heartbeatPause == null ? void 0 : heartbeatPause(); - wsRef.value.close(code, reason); - wsRef.value = void 0; - }; - const send = (data2, useBuffer = true) => { - if (!wsRef.value || status.value !== "OPEN") { - if (useBuffer) - bufferedData.push(data2); - return false; - } - _sendBuffer(); - wsRef.value.send(data2); - return true; - }; - const _init = () => { - if (explicitlyClosed || typeof urlRef.value === "undefined") - return; - const ws = new WebSocket(urlRef.value, protocols); - wsRef.value = ws; - status.value = "CONNECTING"; - ws.onopen = () => { - status.value = "OPEN"; - retried = 0; - onConnected == null ? void 0 : onConnected(ws); - heartbeatResume == null ? void 0 : heartbeatResume(); - _sendBuffer(); - }; - ws.onclose = (ev) => { - status.value = "CLOSED"; - resetHeartbeat(); - heartbeatPause == null ? void 0 : heartbeatPause(); - onDisconnected == null ? void 0 : onDisconnected(ws, ev); - if (!explicitlyClosed && options.autoReconnect && (wsRef.value == null || ws === wsRef.value)) { - const { - retries = -1, - delay = 1e3, - onFailed - } = resolveNestedOptions(options.autoReconnect); - const checkRetires = typeof retries === "function" ? retries : () => typeof retries === "number" && (retries < 0 || retried < retries); - if (checkRetires(retried)) { - retried += 1; - retryTimeout = setTimeout(_init, delay); - } else { - onFailed == null ? void 0 : onFailed(); - } - } - }; - ws.onerror = (e) => { - onError == null ? void 0 : onError(ws, e); - }; - ws.onmessage = (e) => { - if (options.heartbeat) { - resetHeartbeat(); - const { - message = DEFAULT_PING_MESSAGE, - responseMessage = message - } = resolveNestedOptions(options.heartbeat); - if (e.data === toValue(responseMessage)) - return; - } - data.value = e.data; - onMessage == null ? void 0 : onMessage(ws, e); - }; - }; - if (options.heartbeat) { - const { - message = DEFAULT_PING_MESSAGE, - interval = 1e3, - pongTimeout = 1e3 - } = resolveNestedOptions(options.heartbeat); - const { pause, resume } = useIntervalFn( - () => { - send(toValue(message), false); - if (pongTimeoutWait != null) - return; - pongTimeoutWait = setTimeout(() => { - close(); - explicitlyClosed = false; - }, pongTimeout); - }, - interval, - { immediate: false } - ); - heartbeatPause = pause; - heartbeatResume = resume; - } - if (autoClose) { - if (isClient) - useEventListener("beforeunload", () => close(), { passive: true }); - tryOnScopeDispose(close); - } - const open = () => { - if (!isClient && !isWorker) - return; - close(); - explicitlyClosed = false; - retried = 0; - _init(); - }; - if (immediate) - open(); - if (autoConnect) - watch(urlRef, open); - return { - data, - status, - close, - send, - open, - ws: wsRef - }; -} -function useWebWorker(arg0, workerOptions, options) { - const { - window: window2 = defaultWindow - } = options != null ? options : {}; - const data = ref(null); - const worker = shallowRef(); - const post = (...args) => { - if (!worker.value) - return; - worker.value.postMessage(...args); - }; - const terminate = function terminate2() { - if (!worker.value) - return; - worker.value.terminate(); - }; - if (window2) { - if (typeof arg0 === "string") - worker.value = new Worker(arg0, workerOptions); - else if (typeof arg0 === "function") - worker.value = arg0(); - else - worker.value = arg0; - worker.value.onmessage = (e) => { - data.value = e.data; - }; - tryOnScopeDispose(() => { - if (worker.value) - worker.value.terminate(); - }); - } - return { - data, - post, - terminate, - worker - }; -} -function depsParser(deps, localDeps) { - if (deps.length === 0 && localDeps.length === 0) - return ""; - const depsString = deps.map((dep) => `'${dep}'`).toString(); - const depsFunctionString = localDeps.filter((dep) => typeof dep === "function").map((fn) => { - const str = fn.toString(); - if (str.trim().startsWith("function")) { - return str; - } else { - const name = fn.name; - return `const ${name} = ${str}`; - } - }).join(";"); - const importString = `importScripts(${depsString});`; - return `${depsString.trim() === "" ? "" : importString} ${depsFunctionString}`; -} -function jobRunner(userFunc) { - return (e) => { - const userFuncArgs = e.data[0]; - return Promise.resolve(userFunc.apply(void 0, userFuncArgs)).then((result) => { - postMessage(["SUCCESS", result]); - }).catch((error) => { - postMessage(["ERROR", error]); - }); - }; -} -function createWorkerBlobUrl(fn, deps, localDeps) { - const blobCode = `${depsParser(deps, localDeps)}; onmessage=(${jobRunner})(${fn})`; - const blob = new Blob([blobCode], { type: "text/javascript" }); - const url = URL.createObjectURL(blob); - return url; -} -function useWebWorkerFn(fn, options = {}) { - const { - dependencies = [], - localDependencies = [], - timeout, - window: window2 = defaultWindow - } = options; - const worker = ref(); - const workerStatus = shallowRef("PENDING"); - const promise = ref({}); - const timeoutId = shallowRef(); - const workerTerminate = (status = "PENDING") => { - if (worker.value && worker.value._url && window2) { - worker.value.terminate(); - URL.revokeObjectURL(worker.value._url); - promise.value = {}; - worker.value = void 0; - window2.clearTimeout(timeoutId.value); - workerStatus.value = status; - } - }; - workerTerminate(); - tryOnScopeDispose(workerTerminate); - const generateWorker = () => { - const blobUrl = createWorkerBlobUrl(fn, dependencies, localDependencies); - const newWorker = new Worker(blobUrl); - newWorker._url = blobUrl; - newWorker.onmessage = (e) => { - const { resolve = () => { - }, reject = () => { - } } = promise.value; - const [status, result] = e.data; - switch (status) { - case "SUCCESS": - resolve(result); - workerTerminate(status); - break; - default: - reject(result); - workerTerminate("ERROR"); - break; - } - }; - newWorker.onerror = (e) => { - const { reject = () => { - } } = promise.value; - e.preventDefault(); - reject(e); - workerTerminate("ERROR"); - }; - if (timeout) { - timeoutId.value = setTimeout( - () => workerTerminate("TIMEOUT_EXPIRED"), - timeout - ); - } - return newWorker; - }; - const callWorker = (...fnArgs) => new Promise((resolve, reject) => { - var _a; - promise.value = { - resolve, - reject - }; - (_a = worker.value) == null ? void 0 : _a.postMessage([[...fnArgs]]); - workerStatus.value = "RUNNING"; - }); - const workerFn = (...fnArgs) => { - if (workerStatus.value === "RUNNING") { - console.error( - "[useWebWorkerFn] You can only run one instance of the worker at a time." - ); - return Promise.reject(); - } - worker.value = generateWorker(); - return callWorker(...fnArgs); - }; - return { - workerFn, - workerStatus, - workerTerminate - }; -} -function useWindowFocus(options = {}) { - const { window: window2 = defaultWindow } = options; - if (!window2) - return shallowRef(false); - const focused = shallowRef(window2.document.hasFocus()); - const listenerOptions = { passive: true }; - useEventListener(window2, "blur", () => { - focused.value = false; - }, listenerOptions); - useEventListener(window2, "focus", () => { - focused.value = true; - }, listenerOptions); - return focused; -} -function useWindowScroll(options = {}) { - const { window: window2 = defaultWindow, ...rest } = options; - return useScroll(window2, rest); -} -function useWindowSize(options = {}) { - const { - window: window2 = defaultWindow, - initialWidth = Number.POSITIVE_INFINITY, - initialHeight = Number.POSITIVE_INFINITY, - listenOrientation = true, - includeScrollbar = true, - type = "inner" - } = options; - const width = shallowRef(initialWidth); - const height = shallowRef(initialHeight); - const update = () => { - if (window2) { - if (type === "outer") { - width.value = window2.outerWidth; - height.value = window2.outerHeight; - } else if (type === "visual" && window2.visualViewport) { - const { width: visualViewportWidth, height: visualViewportHeight, scale } = window2.visualViewport; - width.value = Math.round(visualViewportWidth * scale); - height.value = Math.round(visualViewportHeight * scale); - } else if (includeScrollbar) { - width.value = window2.innerWidth; - height.value = window2.innerHeight; - } else { - width.value = window2.document.documentElement.clientWidth; - height.value = window2.document.documentElement.clientHeight; - } - } - }; - update(); - tryOnMounted(update); - const listenerOptions = { passive: true }; - useEventListener("resize", update, listenerOptions); - if (window2 && type === "visual" && window2.visualViewport) { - useEventListener(window2.visualViewport, "resize", update, listenerOptions); - } - if (listenOrientation) { - const matches = useMediaQuery("(orientation: portrait)"); - watch(matches, () => update()); - } - return { width, height }; -} - -export { - computedEager, - computedWithControl, - tryOnScopeDispose, - createEventHook, - createGlobalState, - injectLocal, - provideLocal, - createInjectionState, - createRef, - createSharedComposable, - extendRef, - get, - isDefined, - makeDestructurable, - reactify, - reactifyObject, - toReactive, - reactiveComputed, - reactiveOmit, - isClient, - isWorker, - isDef, - notNullish, - assert, - isObject, - now, - timestamp, - clamp, - noop, - rand, - hasOwn, - isIOS, - createFilterWrapper, - bypassFilter, - debounceFilter, - throttleFilter, - pausableFilter, - hyphenate, - camelize, - promiseTimeout, - identity, - createSingletonPromise, - invoke, - containsProp, - increaseWithUnit, - pxValue, - objectPick, - objectOmit, - objectEntries, - getLifeCycleTarget, - toArray, - toRef2 as toRef, - resolveRef, - reactivePick, - refAutoReset, - useDebounceFn, - refDebounced, - refDefault, - useThrottleFn, - refThrottled, - refWithControl, - controlledRef, - set, - watchWithFilter, - watchPausable, - syncRef, - syncRefs, - toRefs2 as toRefs, - toValue2 as toValue, - resolveUnref, - tryOnBeforeMount, - tryOnBeforeUnmount, - tryOnMounted, - tryOnUnmounted, - until, - useArrayDifference, - useArrayEvery, - useArrayFilter, - useArrayFind, - useArrayFindIndex, - useArrayFindLast, - useArrayIncludes, - useArrayJoin, - useArrayMap, - useArrayReduce, - useArraySome, - useArrayUnique, - useCounter, - formatDate, - normalizeDate, - useDateFormat, - useIntervalFn, - useInterval, - useLastChanged, - useTimeoutFn, - useTimeout, - useToNumber, - useToString, - useToggle, - watchArray, - watchAtMost, - watchDebounced, - watchDeep, - watchIgnorable, - watchImmediate, - watchOnce, - watchThrottled, - watchTriggerable, - whenever, - computedAsync, - computedInject, - createReusableTemplate, - createTemplatePromise, - createUnrefFn, - defaultWindow, - defaultDocument, - defaultNavigator, - defaultLocation, - unrefElement, - useEventListener, - onClickOutside, - useMounted, - useSupported, - useMutationObserver, - onElementRemoval, - onKeyStroke, - onKeyDown, - onKeyPressed, - onKeyUp, - onLongPress, - onStartTyping, - templateRef, - useActiveElement, - useRafFn, - useAnimate, - useAsyncQueue, - useAsyncState, - useBase64, - useBattery, - useBluetooth, - useSSRWidth, - provideSSRWidth, - useMediaQuery, - breakpointsTailwind, - breakpointsBootstrapV5, - breakpointsVuetifyV2, - breakpointsVuetifyV3, - breakpointsVuetify, - breakpointsAntDesign, - breakpointsQuasar, - breakpointsSematic, - breakpointsMasterCss, - breakpointsPrimeFlex, - breakpointsElement, - useBreakpoints, - useBroadcastChannel, - useBrowserLocation, - useCached, - usePermission, - useClipboard, - useClipboardItems, - cloneFnJSON, - useCloned, - getSSRHandler, - setSSRHandler, - usePreferredDark, - StorageSerializers, - customStorageEventName, - useStorage, - useColorMode, - useConfirmDialog, - useCountdown, - useCssVar, - useCurrentElement, - useCycleList, - useDark, - useManualRefHistory, - useRefHistory, - useDebouncedRefHistory, - useDeviceMotion, - useDeviceOrientation, - useDevicePixelRatio, - useDevicesList, - useDisplayMedia, - useDocumentVisibility, - useDraggable, - useDropZone, - useResizeObserver, - useElementBounding, - useElementByPoint, - useElementHover, - useElementSize, - useIntersectionObserver, - useElementVisibility, - useEventBus, - useEventSource, - useEyeDropper, - useFavicon, - createFetch, - useFetch, - useFileDialog, - useFileSystemAccess, - useFocus, - useFocusWithin, - useFps, - useFullscreen, - mapGamepadToXbox360Controller, - useGamepad, - useGeolocation, - useIdle, - useImage, - useScroll, - useInfiniteScroll, - useKeyModifier, - useLocalStorage, - DefaultMagicKeysAliasMap, - useMagicKeys, - useMediaControls, - useMemoize, - useMemory, - useMouse, - useMouseInElement, - useMousePressed, - useNavigatorLanguage, - useNetwork, - useNow, - useObjectUrl, - useOffsetPagination, - useOnline, - usePageLeave, - useScreenOrientation, - useParallax, - useParentElement, - usePerformanceObserver, - usePointer, - usePointerLock, - usePointerSwipe, - usePreferredColorScheme, - usePreferredContrast, - usePreferredLanguages, - usePreferredReducedMotion, - usePreferredReducedTransparency, - usePrevious, - useScreenSafeArea, - useScriptTag, - useScrollLock, - useSessionStorage, - useShare, - useSorted, - useSpeechRecognition, - useSpeechSynthesis, - useStepper, - useStorageAsync, - useStyleTag, - useSwipe, - useTemplateRefsList, - useTextDirection, - useTextSelection, - useTextareaAutosize, - useThrottledRefHistory, - useTimeAgo, - formatTimeAgo, - useTimeoutPoll, - useTimestamp, - useTitle, - TransitionPresets, - executeTransition, - useTransition, - useUrlSearchParams, - useUserMedia, - useVModel, - useVModels, - useVibrate, - useVirtualList, - useWakeLock, - useWebNotification, - useWebSocket, - useWebWorker, - useWebWorkerFn, - useWindowFocus, - useWindowScroll, - useWindowSize -}; -//# sourceMappingURL=chunk-2CLQ7TTZ.js.map diff --git a/www/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js.map b/www/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js.map deleted file mode 100644 index 64aea30..0000000 --- a/www/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../node_modules/@vueuse/shared/index.mjs", "../../../../node_modules/@vueuse/core/index.mjs"], - "sourcesContent": ["import { shallowRef, watchEffect, readonly, watch, customRef, getCurrentScope, onScopeDispose, effectScope, getCurrentInstance, hasInjectionContext, inject, provide, ref, isRef, unref, toValue as toValue$1, computed, reactive, toRefs as toRefs$1, toRef as toRef$1, onBeforeMount, nextTick, onBeforeUnmount, onMounted, onUnmounted, isReactive } from 'vue';\n\nfunction computedEager(fn, options) {\n var _a;\n const result = shallowRef();\n watchEffect(() => {\n result.value = fn();\n }, {\n ...options,\n flush: (_a = options == null ? void 0 : options.flush) != null ? _a : \"sync\"\n });\n return readonly(result);\n}\n\nfunction computedWithControl(source, fn) {\n let v = void 0;\n let track;\n let trigger;\n const dirty = shallowRef(true);\n const update = () => {\n dirty.value = true;\n trigger();\n };\n watch(source, update, { flush: \"sync\" });\n const get = typeof fn === \"function\" ? fn : fn.get;\n const set = typeof fn === \"function\" ? void 0 : fn.set;\n const result = customRef((_track, _trigger) => {\n track = _track;\n trigger = _trigger;\n return {\n get() {\n if (dirty.value) {\n v = get(v);\n dirty.value = false;\n }\n track();\n return v;\n },\n set(v2) {\n set == null ? void 0 : set(v2);\n }\n };\n });\n if (Object.isExtensible(result))\n result.trigger = update;\n return result;\n}\n\nfunction tryOnScopeDispose(fn) {\n if (getCurrentScope()) {\n onScopeDispose(fn);\n return true;\n }\n return false;\n}\n\nfunction createEventHook() {\n const fns = /* @__PURE__ */ new Set();\n const off = (fn) => {\n fns.delete(fn);\n };\n const clear = () => {\n fns.clear();\n };\n const on = (fn) => {\n fns.add(fn);\n const offFn = () => off(fn);\n tryOnScopeDispose(offFn);\n return {\n off: offFn\n };\n };\n const trigger = (...args) => {\n return Promise.all(Array.from(fns).map((fn) => fn(...args)));\n };\n return {\n on,\n off,\n trigger,\n clear\n };\n}\n\nfunction createGlobalState(stateFactory) {\n let initialized = false;\n let state;\n const scope = effectScope(true);\n return (...args) => {\n if (!initialized) {\n state = scope.run(() => stateFactory(...args));\n initialized = true;\n }\n return state;\n };\n}\n\nconst localProvidedStateMap = /* @__PURE__ */ new WeakMap();\n\nconst injectLocal = (...args) => {\n var _a;\n const key = args[0];\n const instance = (_a = getCurrentInstance()) == null ? void 0 : _a.proxy;\n if (instance == null && !hasInjectionContext())\n throw new Error(\"injectLocal must be called in setup\");\n if (instance && localProvidedStateMap.has(instance) && key in localProvidedStateMap.get(instance))\n return localProvidedStateMap.get(instance)[key];\n return inject(...args);\n};\n\nconst provideLocal = (key, value) => {\n var _a;\n const instance = (_a = getCurrentInstance()) == null ? void 0 : _a.proxy;\n if (instance == null)\n throw new Error(\"provideLocal must be called in setup\");\n if (!localProvidedStateMap.has(instance))\n localProvidedStateMap.set(instance, /* @__PURE__ */ Object.create(null));\n const localProvidedState = localProvidedStateMap.get(instance);\n localProvidedState[key] = value;\n provide(key, value);\n};\n\nfunction createInjectionState(composable, options) {\n const key = (options == null ? void 0 : options.injectionKey) || Symbol(composable.name || \"InjectionState\");\n const defaultValue = options == null ? void 0 : options.defaultValue;\n const useProvidingState = (...args) => {\n const state = composable(...args);\n provideLocal(key, state);\n return state;\n };\n const useInjectedState = () => injectLocal(key, defaultValue);\n return [useProvidingState, useInjectedState];\n}\n\nfunction createRef(value, deep) {\n if (deep === true) {\n return ref(value);\n } else {\n return shallowRef(value);\n }\n}\n\nfunction createSharedComposable(composable) {\n let subscribers = 0;\n let state;\n let scope;\n const dispose = () => {\n subscribers -= 1;\n if (scope && subscribers <= 0) {\n scope.stop();\n state = void 0;\n scope = void 0;\n }\n };\n return (...args) => {\n subscribers += 1;\n if (!scope) {\n scope = effectScope(true);\n state = scope.run(() => composable(...args));\n }\n tryOnScopeDispose(dispose);\n return state;\n };\n}\n\nfunction extendRef(ref, extend, { enumerable = false, unwrap = true } = {}) {\n for (const [key, value] of Object.entries(extend)) {\n if (key === \"value\")\n continue;\n if (isRef(value) && unwrap) {\n Object.defineProperty(ref, key, {\n get() {\n return value.value;\n },\n set(v) {\n value.value = v;\n },\n enumerable\n });\n } else {\n Object.defineProperty(ref, key, { value, enumerable });\n }\n }\n return ref;\n}\n\nfunction get(obj, key) {\n if (key == null)\n return unref(obj);\n return unref(obj)[key];\n}\n\nfunction isDefined(v) {\n return unref(v) != null;\n}\n\nfunction makeDestructurable(obj, arr) {\n if (typeof Symbol !== \"undefined\") {\n const clone = { ...obj };\n Object.defineProperty(clone, Symbol.iterator, {\n enumerable: false,\n value() {\n let index = 0;\n return {\n next: () => ({\n value: arr[index++],\n done: index > arr.length\n })\n };\n }\n });\n return clone;\n } else {\n return Object.assign([...arr], obj);\n }\n}\n\nfunction reactify(fn, options) {\n const unrefFn = (options == null ? void 0 : options.computedGetter) === false ? unref : toValue$1;\n return function(...args) {\n return computed(() => fn.apply(this, args.map((i) => unrefFn(i))));\n };\n}\n\nfunction reactifyObject(obj, optionsOrKeys = {}) {\n let keys = [];\n let options;\n if (Array.isArray(optionsOrKeys)) {\n keys = optionsOrKeys;\n } else {\n options = optionsOrKeys;\n const { includeOwnProperties = true } = optionsOrKeys;\n keys.push(...Object.keys(obj));\n if (includeOwnProperties)\n keys.push(...Object.getOwnPropertyNames(obj));\n }\n return Object.fromEntries(\n keys.map((key) => {\n const value = obj[key];\n return [\n key,\n typeof value === \"function\" ? reactify(value.bind(obj), options) : value\n ];\n })\n );\n}\n\nfunction toReactive(objectRef) {\n if (!isRef(objectRef))\n return reactive(objectRef);\n const proxy = new Proxy({}, {\n get(_, p, receiver) {\n return unref(Reflect.get(objectRef.value, p, receiver));\n },\n set(_, p, value) {\n if (isRef(objectRef.value[p]) && !isRef(value))\n objectRef.value[p].value = value;\n else\n objectRef.value[p] = value;\n return true;\n },\n deleteProperty(_, p) {\n return Reflect.deleteProperty(objectRef.value, p);\n },\n has(_, p) {\n return Reflect.has(objectRef.value, p);\n },\n ownKeys() {\n return Object.keys(objectRef.value);\n },\n getOwnPropertyDescriptor() {\n return {\n enumerable: true,\n configurable: true\n };\n }\n });\n return reactive(proxy);\n}\n\nfunction reactiveComputed(fn) {\n return toReactive(computed(fn));\n}\n\nfunction reactiveOmit(obj, ...keys) {\n const flatKeys = keys.flat();\n const predicate = flatKeys[0];\n return reactiveComputed(() => typeof predicate === \"function\" ? Object.fromEntries(Object.entries(toRefs$1(obj)).filter(([k, v]) => !predicate(toValue$1(v), k))) : Object.fromEntries(Object.entries(toRefs$1(obj)).filter((e) => !flatKeys.includes(e[0]))));\n}\n\nconst isClient = typeof window !== \"undefined\" && typeof document !== \"undefined\";\nconst isWorker = typeof WorkerGlobalScope !== \"undefined\" && globalThis instanceof WorkerGlobalScope;\nconst isDef = (val) => typeof val !== \"undefined\";\nconst notNullish = (val) => val != null;\nconst assert = (condition, ...infos) => {\n if (!condition)\n console.warn(...infos);\n};\nconst toString = Object.prototype.toString;\nconst isObject = (val) => toString.call(val) === \"[object Object]\";\nconst now = () => Date.now();\nconst timestamp = () => +Date.now();\nconst clamp = (n, min, max) => Math.min(max, Math.max(min, n));\nconst noop = () => {\n};\nconst rand = (min, max) => {\n min = Math.ceil(min);\n max = Math.floor(max);\n return Math.floor(Math.random() * (max - min + 1)) + min;\n};\nconst hasOwn = (val, key) => Object.prototype.hasOwnProperty.call(val, key);\nconst isIOS = /* @__PURE__ */ getIsIOS();\nfunction getIsIOS() {\n var _a, _b;\n return isClient && ((_a = window == null ? void 0 : window.navigator) == null ? void 0 : _a.userAgent) && (/iP(?:ad|hone|od)/.test(window.navigator.userAgent) || ((_b = window == null ? void 0 : window.navigator) == null ? void 0 : _b.maxTouchPoints) > 2 && /iPad|Macintosh/.test(window == null ? void 0 : window.navigator.userAgent));\n}\n\nfunction createFilterWrapper(filter, fn) {\n function wrapper(...args) {\n return new Promise((resolve, reject) => {\n Promise.resolve(filter(() => fn.apply(this, args), { fn, thisArg: this, args })).then(resolve).catch(reject);\n });\n }\n return wrapper;\n}\nconst bypassFilter = (invoke) => {\n return invoke();\n};\nfunction debounceFilter(ms, options = {}) {\n let timer;\n let maxTimer;\n let lastRejector = noop;\n const _clearTimeout = (timer2) => {\n clearTimeout(timer2);\n lastRejector();\n lastRejector = noop;\n };\n let lastInvoker;\n const filter = (invoke) => {\n const duration = toValue$1(ms);\n const maxDuration = toValue$1(options.maxWait);\n if (timer)\n _clearTimeout(timer);\n if (duration <= 0 || maxDuration !== void 0 && maxDuration <= 0) {\n if (maxTimer) {\n _clearTimeout(maxTimer);\n maxTimer = null;\n }\n return Promise.resolve(invoke());\n }\n return new Promise((resolve, reject) => {\n lastRejector = options.rejectOnCancel ? reject : resolve;\n lastInvoker = invoke;\n if (maxDuration && !maxTimer) {\n maxTimer = setTimeout(() => {\n if (timer)\n _clearTimeout(timer);\n maxTimer = null;\n resolve(lastInvoker());\n }, maxDuration);\n }\n timer = setTimeout(() => {\n if (maxTimer)\n _clearTimeout(maxTimer);\n maxTimer = null;\n resolve(invoke());\n }, duration);\n });\n };\n return filter;\n}\nfunction throttleFilter(...args) {\n let lastExec = 0;\n let timer;\n let isLeading = true;\n let lastRejector = noop;\n let lastValue;\n let ms;\n let trailing;\n let leading;\n let rejectOnCancel;\n if (!isRef(args[0]) && typeof args[0] === \"object\")\n ({ delay: ms, trailing = true, leading = true, rejectOnCancel = false } = args[0]);\n else\n [ms, trailing = true, leading = true, rejectOnCancel = false] = args;\n const clear = () => {\n if (timer) {\n clearTimeout(timer);\n timer = void 0;\n lastRejector();\n lastRejector = noop;\n }\n };\n const filter = (_invoke) => {\n const duration = toValue$1(ms);\n const elapsed = Date.now() - lastExec;\n const invoke = () => {\n return lastValue = _invoke();\n };\n clear();\n if (duration <= 0) {\n lastExec = Date.now();\n return invoke();\n }\n if (elapsed > duration && (leading || !isLeading)) {\n lastExec = Date.now();\n invoke();\n } else if (trailing) {\n lastValue = new Promise((resolve, reject) => {\n lastRejector = rejectOnCancel ? reject : resolve;\n timer = setTimeout(() => {\n lastExec = Date.now();\n isLeading = true;\n resolve(invoke());\n clear();\n }, Math.max(0, duration - elapsed));\n });\n }\n if (!leading && !timer)\n timer = setTimeout(() => isLeading = true, duration);\n isLeading = false;\n return lastValue;\n };\n return filter;\n}\nfunction pausableFilter(extendFilter = bypassFilter, options = {}) {\n const {\n initialState = \"active\"\n } = options;\n const isActive = toRef(initialState === \"active\");\n function pause() {\n isActive.value = false;\n }\n function resume() {\n isActive.value = true;\n }\n const eventFilter = (...args) => {\n if (isActive.value)\n extendFilter(...args);\n };\n return { isActive: readonly(isActive), pause, resume, eventFilter };\n}\n\nfunction cacheStringFunction(fn) {\n const cache = /* @__PURE__ */ Object.create(null);\n return (str) => {\n const hit = cache[str];\n return hit || (cache[str] = fn(str));\n };\n}\nconst hyphenateRE = /\\B([A-Z])/g;\nconst hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, \"-$1\").toLowerCase());\nconst camelizeRE = /-(\\w)/g;\nconst camelize = cacheStringFunction((str) => {\n return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : \"\");\n});\n\nfunction promiseTimeout(ms, throwOnTimeout = false, reason = \"Timeout\") {\n return new Promise((resolve, reject) => {\n if (throwOnTimeout)\n setTimeout(() => reject(reason), ms);\n else\n setTimeout(resolve, ms);\n });\n}\nfunction identity(arg) {\n return arg;\n}\nfunction createSingletonPromise(fn) {\n let _promise;\n function wrapper() {\n if (!_promise)\n _promise = fn();\n return _promise;\n }\n wrapper.reset = async () => {\n const _prev = _promise;\n _promise = void 0;\n if (_prev)\n await _prev;\n };\n return wrapper;\n}\nfunction invoke(fn) {\n return fn();\n}\nfunction containsProp(obj, ...props) {\n return props.some((k) => k in obj);\n}\nfunction increaseWithUnit(target, delta) {\n var _a;\n if (typeof target === \"number\")\n return target + delta;\n const value = ((_a = target.match(/^-?\\d+\\.?\\d*/)) == null ? void 0 : _a[0]) || \"\";\n const unit = target.slice(value.length);\n const result = Number.parseFloat(value) + delta;\n if (Number.isNaN(result))\n return target;\n return result + unit;\n}\nfunction pxValue(px) {\n return px.endsWith(\"rem\") ? Number.parseFloat(px) * 16 : Number.parseFloat(px);\n}\nfunction objectPick(obj, keys, omitUndefined = false) {\n return keys.reduce((n, k) => {\n if (k in obj) {\n if (!omitUndefined || obj[k] !== void 0)\n n[k] = obj[k];\n }\n return n;\n }, {});\n}\nfunction objectOmit(obj, keys, omitUndefined = false) {\n return Object.fromEntries(Object.entries(obj).filter(([key, value]) => {\n return (!omitUndefined || value !== void 0) && !keys.includes(key);\n }));\n}\nfunction objectEntries(obj) {\n return Object.entries(obj);\n}\nfunction getLifeCycleTarget(target) {\n return target || getCurrentInstance();\n}\nfunction toArray(value) {\n return Array.isArray(value) ? value : [value];\n}\n\nfunction toRef(...args) {\n if (args.length !== 1)\n return toRef$1(...args);\n const r = args[0];\n return typeof r === \"function\" ? readonly(customRef(() => ({ get: r, set: noop }))) : ref(r);\n}\nconst resolveRef = toRef;\n\nfunction reactivePick(obj, ...keys) {\n const flatKeys = keys.flat();\n const predicate = flatKeys[0];\n return reactiveComputed(() => typeof predicate === \"function\" ? Object.fromEntries(Object.entries(toRefs$1(obj)).filter(([k, v]) => predicate(toValue$1(v), k))) : Object.fromEntries(flatKeys.map((k) => [k, toRef(obj, k)])));\n}\n\nfunction refAutoReset(defaultValue, afterMs = 1e4) {\n return customRef((track, trigger) => {\n let value = toValue$1(defaultValue);\n let timer;\n const resetAfter = () => setTimeout(() => {\n value = toValue$1(defaultValue);\n trigger();\n }, toValue$1(afterMs));\n tryOnScopeDispose(() => {\n clearTimeout(timer);\n });\n return {\n get() {\n track();\n return value;\n },\n set(newValue) {\n value = newValue;\n trigger();\n clearTimeout(timer);\n timer = resetAfter();\n }\n };\n });\n}\n\nfunction useDebounceFn(fn, ms = 200, options = {}) {\n return createFilterWrapper(\n debounceFilter(ms, options),\n fn\n );\n}\n\nfunction refDebounced(value, ms = 200, options = {}) {\n const debounced = ref(value.value);\n const updater = useDebounceFn(() => {\n debounced.value = value.value;\n }, ms, options);\n watch(value, () => updater());\n return debounced;\n}\n\nfunction refDefault(source, defaultValue) {\n return computed({\n get() {\n var _a;\n return (_a = source.value) != null ? _a : defaultValue;\n },\n set(value) {\n source.value = value;\n }\n });\n}\n\nfunction useThrottleFn(fn, ms = 200, trailing = false, leading = true, rejectOnCancel = false) {\n return createFilterWrapper(\n throttleFilter(ms, trailing, leading, rejectOnCancel),\n fn\n );\n}\n\nfunction refThrottled(value, delay = 200, trailing = true, leading = true) {\n if (delay <= 0)\n return value;\n const throttled = ref(value.value);\n const updater = useThrottleFn(() => {\n throttled.value = value.value;\n }, delay, trailing, leading);\n watch(value, () => updater());\n return throttled;\n}\n\nfunction refWithControl(initial, options = {}) {\n let source = initial;\n let track;\n let trigger;\n const ref = customRef((_track, _trigger) => {\n track = _track;\n trigger = _trigger;\n return {\n get() {\n return get();\n },\n set(v) {\n set(v);\n }\n };\n });\n function get(tracking = true) {\n if (tracking)\n track();\n return source;\n }\n function set(value, triggering = true) {\n var _a, _b;\n if (value === source)\n return;\n const old = source;\n if (((_a = options.onBeforeChange) == null ? void 0 : _a.call(options, value, old)) === false)\n return;\n source = value;\n (_b = options.onChanged) == null ? void 0 : _b.call(options, value, old);\n if (triggering)\n trigger();\n }\n const untrackedGet = () => get(false);\n const silentSet = (v) => set(v, false);\n const peek = () => get(false);\n const lay = (v) => set(v, false);\n return extendRef(\n ref,\n {\n get,\n set,\n untrackedGet,\n silentSet,\n peek,\n lay\n },\n { enumerable: true }\n );\n}\nconst controlledRef = refWithControl;\n\nfunction set(...args) {\n if (args.length === 2) {\n const [ref, value] = args;\n ref.value = value;\n }\n if (args.length === 3) {\n const [target, key, value] = args;\n target[key] = value;\n }\n}\n\nfunction watchWithFilter(source, cb, options = {}) {\n const {\n eventFilter = bypassFilter,\n ...watchOptions\n } = options;\n return watch(\n source,\n createFilterWrapper(\n eventFilter,\n cb\n ),\n watchOptions\n );\n}\n\nfunction watchPausable(source, cb, options = {}) {\n const {\n eventFilter: filter,\n initialState = \"active\",\n ...watchOptions\n } = options;\n const { eventFilter, pause, resume, isActive } = pausableFilter(filter, { initialState });\n const stop = watchWithFilter(\n source,\n cb,\n {\n ...watchOptions,\n eventFilter\n }\n );\n return { stop, pause, resume, isActive };\n}\n\nfunction syncRef(left, right, ...[options]) {\n const {\n flush = \"sync\",\n deep = false,\n immediate = true,\n direction = \"both\",\n transform = {}\n } = options || {};\n const watchers = [];\n const transformLTR = \"ltr\" in transform && transform.ltr || ((v) => v);\n const transformRTL = \"rtl\" in transform && transform.rtl || ((v) => v);\n if (direction === \"both\" || direction === \"ltr\") {\n watchers.push(watchPausable(\n left,\n (newValue) => {\n watchers.forEach((w) => w.pause());\n right.value = transformLTR(newValue);\n watchers.forEach((w) => w.resume());\n },\n { flush, deep, immediate }\n ));\n }\n if (direction === \"both\" || direction === \"rtl\") {\n watchers.push(watchPausable(\n right,\n (newValue) => {\n watchers.forEach((w) => w.pause());\n left.value = transformRTL(newValue);\n watchers.forEach((w) => w.resume());\n },\n { flush, deep, immediate }\n ));\n }\n const stop = () => {\n watchers.forEach((w) => w.stop());\n };\n return stop;\n}\n\nfunction syncRefs(source, targets, options = {}) {\n const {\n flush = \"sync\",\n deep = false,\n immediate = true\n } = options;\n const targetsArray = toArray(targets);\n return watch(\n source,\n (newValue) => targetsArray.forEach((target) => target.value = newValue),\n { flush, deep, immediate }\n );\n}\n\nfunction toRefs(objectRef, options = {}) {\n if (!isRef(objectRef))\n return toRefs$1(objectRef);\n const result = Array.isArray(objectRef.value) ? Array.from({ length: objectRef.value.length }) : {};\n for (const key in objectRef.value) {\n result[key] = customRef(() => ({\n get() {\n return objectRef.value[key];\n },\n set(v) {\n var _a;\n const replaceRef = (_a = toValue$1(options.replaceRef)) != null ? _a : true;\n if (replaceRef) {\n if (Array.isArray(objectRef.value)) {\n const copy = [...objectRef.value];\n copy[key] = v;\n objectRef.value = copy;\n } else {\n const newObject = { ...objectRef.value, [key]: v };\n Object.setPrototypeOf(newObject, Object.getPrototypeOf(objectRef.value));\n objectRef.value = newObject;\n }\n } else {\n objectRef.value[key] = v;\n }\n }\n }));\n }\n return result;\n}\n\nconst toValue = toValue$1;\nconst resolveUnref = toValue$1;\n\nfunction tryOnBeforeMount(fn, sync = true, target) {\n const instance = getLifeCycleTarget(target);\n if (instance)\n onBeforeMount(fn, target);\n else if (sync)\n fn();\n else\n nextTick(fn);\n}\n\nfunction tryOnBeforeUnmount(fn, target) {\n const instance = getLifeCycleTarget(target);\n if (instance)\n onBeforeUnmount(fn, target);\n}\n\nfunction tryOnMounted(fn, sync = true, target) {\n const instance = getLifeCycleTarget();\n if (instance)\n onMounted(fn, target);\n else if (sync)\n fn();\n else\n nextTick(fn);\n}\n\nfunction tryOnUnmounted(fn, target) {\n const instance = getLifeCycleTarget(target);\n if (instance)\n onUnmounted(fn, target);\n}\n\nfunction createUntil(r, isNot = false) {\n function toMatch(condition, { flush = \"sync\", deep = false, timeout, throwOnTimeout } = {}) {\n let stop = null;\n const watcher = new Promise((resolve) => {\n stop = watch(\n r,\n (v) => {\n if (condition(v) !== isNot) {\n if (stop)\n stop();\n else\n nextTick(() => stop == null ? void 0 : stop());\n resolve(v);\n }\n },\n {\n flush,\n deep,\n immediate: true\n }\n );\n });\n const promises = [watcher];\n if (timeout != null) {\n promises.push(\n promiseTimeout(timeout, throwOnTimeout).then(() => toValue$1(r)).finally(() => stop == null ? void 0 : stop())\n );\n }\n return Promise.race(promises);\n }\n function toBe(value, options) {\n if (!isRef(value))\n return toMatch((v) => v === value, options);\n const { flush = \"sync\", deep = false, timeout, throwOnTimeout } = options != null ? options : {};\n let stop = null;\n const watcher = new Promise((resolve) => {\n stop = watch(\n [r, value],\n ([v1, v2]) => {\n if (isNot !== (v1 === v2)) {\n if (stop)\n stop();\n else\n nextTick(() => stop == null ? void 0 : stop());\n resolve(v1);\n }\n },\n {\n flush,\n deep,\n immediate: true\n }\n );\n });\n const promises = [watcher];\n if (timeout != null) {\n promises.push(\n promiseTimeout(timeout, throwOnTimeout).then(() => toValue$1(r)).finally(() => {\n stop == null ? void 0 : stop();\n return toValue$1(r);\n })\n );\n }\n return Promise.race(promises);\n }\n function toBeTruthy(options) {\n return toMatch((v) => Boolean(v), options);\n }\n function toBeNull(options) {\n return toBe(null, options);\n }\n function toBeUndefined(options) {\n return toBe(void 0, options);\n }\n function toBeNaN(options) {\n return toMatch(Number.isNaN, options);\n }\n function toContains(value, options) {\n return toMatch((v) => {\n const array = Array.from(v);\n return array.includes(value) || array.includes(toValue$1(value));\n }, options);\n }\n function changed(options) {\n return changedTimes(1, options);\n }\n function changedTimes(n = 1, options) {\n let count = -1;\n return toMatch(() => {\n count += 1;\n return count >= n;\n }, options);\n }\n if (Array.isArray(toValue$1(r))) {\n const instance = {\n toMatch,\n toContains,\n changed,\n changedTimes,\n get not() {\n return createUntil(r, !isNot);\n }\n };\n return instance;\n } else {\n const instance = {\n toMatch,\n toBe,\n toBeTruthy,\n toBeNull,\n toBeNaN,\n toBeUndefined,\n changed,\n changedTimes,\n get not() {\n return createUntil(r, !isNot);\n }\n };\n return instance;\n }\n}\nfunction until(r) {\n return createUntil(r);\n}\n\nfunction defaultComparator(value, othVal) {\n return value === othVal;\n}\nfunction useArrayDifference(...args) {\n var _a, _b;\n const list = args[0];\n const values = args[1];\n let compareFn = (_a = args[2]) != null ? _a : defaultComparator;\n const {\n symmetric = false\n } = (_b = args[3]) != null ? _b : {};\n if (typeof compareFn === \"string\") {\n const key = compareFn;\n compareFn = (value, othVal) => value[key] === othVal[key];\n }\n const diff1 = computed(() => toValue$1(list).filter((x) => toValue$1(values).findIndex((y) => compareFn(x, y)) === -1));\n if (symmetric) {\n const diff2 = computed(() => toValue$1(values).filter((x) => toValue$1(list).findIndex((y) => compareFn(x, y)) === -1));\n return computed(() => symmetric ? [...toValue$1(diff1), ...toValue$1(diff2)] : toValue$1(diff1));\n } else {\n return diff1;\n }\n}\n\nfunction useArrayEvery(list, fn) {\n return computed(() => toValue$1(list).every((element, index, array) => fn(toValue$1(element), index, array)));\n}\n\nfunction useArrayFilter(list, fn) {\n return computed(() => toValue$1(list).map((i) => toValue$1(i)).filter(fn));\n}\n\nfunction useArrayFind(list, fn) {\n return computed(() => toValue$1(\n toValue$1(list).find((element, index, array) => fn(toValue$1(element), index, array))\n ));\n}\n\nfunction useArrayFindIndex(list, fn) {\n return computed(() => toValue$1(list).findIndex((element, index, array) => fn(toValue$1(element), index, array)));\n}\n\nfunction findLast(arr, cb) {\n let index = arr.length;\n while (index-- > 0) {\n if (cb(arr[index], index, arr))\n return arr[index];\n }\n return void 0;\n}\nfunction useArrayFindLast(list, fn) {\n return computed(() => toValue$1(\n !Array.prototype.findLast ? findLast(toValue$1(list), (element, index, array) => fn(toValue$1(element), index, array)) : toValue$1(list).findLast((element, index, array) => fn(toValue$1(element), index, array))\n ));\n}\n\nfunction isArrayIncludesOptions(obj) {\n return isObject(obj) && containsProp(obj, \"formIndex\", \"comparator\");\n}\nfunction useArrayIncludes(...args) {\n var _a;\n const list = args[0];\n const value = args[1];\n let comparator = args[2];\n let formIndex = 0;\n if (isArrayIncludesOptions(comparator)) {\n formIndex = (_a = comparator.fromIndex) != null ? _a : 0;\n comparator = comparator.comparator;\n }\n if (typeof comparator === \"string\") {\n const key = comparator;\n comparator = (element, value2) => element[key] === toValue$1(value2);\n }\n comparator = comparator != null ? comparator : (element, value2) => element === toValue$1(value2);\n return computed(() => toValue$1(list).slice(formIndex).some((element, index, array) => comparator(\n toValue$1(element),\n toValue$1(value),\n index,\n toValue$1(array)\n )));\n}\n\nfunction useArrayJoin(list, separator) {\n return computed(() => toValue$1(list).map((i) => toValue$1(i)).join(toValue$1(separator)));\n}\n\nfunction useArrayMap(list, fn) {\n return computed(() => toValue$1(list).map((i) => toValue$1(i)).map(fn));\n}\n\nfunction useArrayReduce(list, reducer, ...args) {\n const reduceCallback = (sum, value, index) => reducer(toValue$1(sum), toValue$1(value), index);\n return computed(() => {\n const resolved = toValue$1(list);\n return args.length ? resolved.reduce(reduceCallback, typeof args[0] === \"function\" ? toValue$1(args[0]()) : toValue$1(args[0])) : resolved.reduce(reduceCallback);\n });\n}\n\nfunction useArraySome(list, fn) {\n return computed(() => toValue$1(list).some((element, index, array) => fn(toValue$1(element), index, array)));\n}\n\nfunction uniq(array) {\n return Array.from(new Set(array));\n}\nfunction uniqueElementsBy(array, fn) {\n return array.reduce((acc, v) => {\n if (!acc.some((x) => fn(v, x, array)))\n acc.push(v);\n return acc;\n }, []);\n}\nfunction useArrayUnique(list, compareFn) {\n return computed(() => {\n const resolvedList = toValue$1(list).map((element) => toValue$1(element));\n return compareFn ? uniqueElementsBy(resolvedList, compareFn) : uniq(resolvedList);\n });\n}\n\nfunction useCounter(initialValue = 0, options = {}) {\n let _initialValue = unref(initialValue);\n const count = shallowRef(initialValue);\n const {\n max = Number.POSITIVE_INFINITY,\n min = Number.NEGATIVE_INFINITY\n } = options;\n const inc = (delta = 1) => count.value = Math.max(Math.min(max, count.value + delta), min);\n const dec = (delta = 1) => count.value = Math.min(Math.max(min, count.value - delta), max);\n const get = () => count.value;\n const set = (val) => count.value = Math.max(min, Math.min(max, val));\n const reset = (val = _initialValue) => {\n _initialValue = val;\n return set(val);\n };\n return { count, inc, dec, get, set, reset };\n}\n\nconst REGEX_PARSE = /^(\\d{4})[-/]?(\\d{1,2})?[-/]?(\\d{0,2})[T\\s]*(\\d{1,2})?:?(\\d{1,2})?:?(\\d{1,2})?[.:]?(\\d+)?$/i;\nconst REGEX_FORMAT = /[YMDHhms]o|\\[([^\\]]+)\\]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a{1,2}|A{1,2}|m{1,2}|s{1,2}|Z{1,2}|z{1,4}|SSS/g;\nfunction defaultMeridiem(hours, minutes, isLowercase, hasPeriod) {\n let m = hours < 12 ? \"AM\" : \"PM\";\n if (hasPeriod)\n m = m.split(\"\").reduce((acc, curr) => acc += `${curr}.`, \"\");\n return isLowercase ? m.toLowerCase() : m;\n}\nfunction formatOrdinal(num) {\n const suffixes = [\"th\", \"st\", \"nd\", \"rd\"];\n const v = num % 100;\n return num + (suffixes[(v - 20) % 10] || suffixes[v] || suffixes[0]);\n}\nfunction formatDate(date, formatStr, options = {}) {\n var _a;\n const years = date.getFullYear();\n const month = date.getMonth();\n const days = date.getDate();\n const hours = date.getHours();\n const minutes = date.getMinutes();\n const seconds = date.getSeconds();\n const milliseconds = date.getMilliseconds();\n const day = date.getDay();\n const meridiem = (_a = options.customMeridiem) != null ? _a : defaultMeridiem;\n const stripTimeZone = (dateString) => {\n var _a2;\n return (_a2 = dateString.split(\" \")[1]) != null ? _a2 : \"\";\n };\n const matches = {\n Yo: () => formatOrdinal(years),\n YY: () => String(years).slice(-2),\n YYYY: () => years,\n M: () => month + 1,\n Mo: () => formatOrdinal(month + 1),\n MM: () => `${month + 1}`.padStart(2, \"0\"),\n MMM: () => date.toLocaleDateString(toValue$1(options.locales), { month: \"short\" }),\n MMMM: () => date.toLocaleDateString(toValue$1(options.locales), { month: \"long\" }),\n D: () => String(days),\n Do: () => formatOrdinal(days),\n DD: () => `${days}`.padStart(2, \"0\"),\n H: () => String(hours),\n Ho: () => formatOrdinal(hours),\n HH: () => `${hours}`.padStart(2, \"0\"),\n h: () => `${hours % 12 || 12}`.padStart(1, \"0\"),\n ho: () => formatOrdinal(hours % 12 || 12),\n hh: () => `${hours % 12 || 12}`.padStart(2, \"0\"),\n m: () => String(minutes),\n mo: () => formatOrdinal(minutes),\n mm: () => `${minutes}`.padStart(2, \"0\"),\n s: () => String(seconds),\n so: () => formatOrdinal(seconds),\n ss: () => `${seconds}`.padStart(2, \"0\"),\n SSS: () => `${milliseconds}`.padStart(3, \"0\"),\n d: () => day,\n dd: () => date.toLocaleDateString(toValue$1(options.locales), { weekday: \"narrow\" }),\n ddd: () => date.toLocaleDateString(toValue$1(options.locales), { weekday: \"short\" }),\n dddd: () => date.toLocaleDateString(toValue$1(options.locales), { weekday: \"long\" }),\n A: () => meridiem(hours, minutes),\n AA: () => meridiem(hours, minutes, false, true),\n a: () => meridiem(hours, minutes, true),\n aa: () => meridiem(hours, minutes, true, true),\n z: () => stripTimeZone(date.toLocaleDateString(toValue$1(options.locales), { timeZoneName: \"shortOffset\" })),\n zz: () => stripTimeZone(date.toLocaleDateString(toValue$1(options.locales), { timeZoneName: \"shortOffset\" })),\n zzz: () => stripTimeZone(date.toLocaleDateString(toValue$1(options.locales), { timeZoneName: \"shortOffset\" })),\n zzzz: () => stripTimeZone(date.toLocaleDateString(toValue$1(options.locales), { timeZoneName: \"longOffset\" }))\n };\n return formatStr.replace(REGEX_FORMAT, (match, $1) => {\n var _a2, _b;\n return (_b = $1 != null ? $1 : (_a2 = matches[match]) == null ? void 0 : _a2.call(matches)) != null ? _b : match;\n });\n}\nfunction normalizeDate(date) {\n if (date === null)\n return new Date(Number.NaN);\n if (date === void 0)\n return /* @__PURE__ */ new Date();\n if (date instanceof Date)\n return new Date(date);\n if (typeof date === \"string\" && !/Z$/i.test(date)) {\n const d = date.match(REGEX_PARSE);\n if (d) {\n const m = d[2] - 1 || 0;\n const ms = (d[7] || \"0\").substring(0, 3);\n return new Date(d[1], m, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms);\n }\n }\n return new Date(date);\n}\nfunction useDateFormat(date, formatStr = \"HH:mm:ss\", options = {}) {\n return computed(() => formatDate(normalizeDate(toValue$1(date)), toValue$1(formatStr), options));\n}\n\nfunction useIntervalFn(cb, interval = 1e3, options = {}) {\n const {\n immediate = true,\n immediateCallback = false\n } = options;\n let timer = null;\n const isActive = shallowRef(false);\n function clean() {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n }\n function pause() {\n isActive.value = false;\n clean();\n }\n function resume() {\n const intervalValue = toValue$1(interval);\n if (intervalValue <= 0)\n return;\n isActive.value = true;\n if (immediateCallback)\n cb();\n clean();\n if (isActive.value)\n timer = setInterval(cb, intervalValue);\n }\n if (immediate && isClient)\n resume();\n if (isRef(interval) || typeof interval === \"function\") {\n const stopWatch = watch(interval, () => {\n if (isActive.value && isClient)\n resume();\n });\n tryOnScopeDispose(stopWatch);\n }\n tryOnScopeDispose(pause);\n return {\n isActive,\n pause,\n resume\n };\n}\n\nfunction useInterval(interval = 1e3, options = {}) {\n const {\n controls: exposeControls = false,\n immediate = true,\n callback\n } = options;\n const counter = shallowRef(0);\n const update = () => counter.value += 1;\n const reset = () => {\n counter.value = 0;\n };\n const controls = useIntervalFn(\n callback ? () => {\n update();\n callback(counter.value);\n } : update,\n interval,\n { immediate }\n );\n if (exposeControls) {\n return {\n counter,\n reset,\n ...controls\n };\n } else {\n return counter;\n }\n}\n\nfunction useLastChanged(source, options = {}) {\n var _a;\n const ms = shallowRef((_a = options.initialValue) != null ? _a : null);\n watch(\n source,\n () => ms.value = timestamp(),\n options\n );\n return ms;\n}\n\nfunction useTimeoutFn(cb, interval, options = {}) {\n const {\n immediate = true,\n immediateCallback = false\n } = options;\n const isPending = shallowRef(false);\n let timer = null;\n function clear() {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n }\n function stop() {\n isPending.value = false;\n clear();\n }\n function start(...args) {\n if (immediateCallback)\n cb();\n clear();\n isPending.value = true;\n timer = setTimeout(() => {\n isPending.value = false;\n timer = null;\n cb(...args);\n }, toValue$1(interval));\n }\n if (immediate) {\n isPending.value = true;\n if (isClient)\n start();\n }\n tryOnScopeDispose(stop);\n return {\n isPending: readonly(isPending),\n start,\n stop\n };\n}\n\nfunction useTimeout(interval = 1e3, options = {}) {\n const {\n controls: exposeControls = false,\n callback\n } = options;\n const controls = useTimeoutFn(\n callback != null ? callback : noop,\n interval,\n options\n );\n const ready = computed(() => !controls.isPending.value);\n if (exposeControls) {\n return {\n ready,\n ...controls\n };\n } else {\n return ready;\n }\n}\n\nfunction useToNumber(value, options = {}) {\n const {\n method = \"parseFloat\",\n radix,\n nanToZero\n } = options;\n return computed(() => {\n let resolved = toValue$1(value);\n if (typeof method === \"function\")\n resolved = method(resolved);\n else if (typeof resolved === \"string\")\n resolved = Number[method](resolved, radix);\n if (nanToZero && Number.isNaN(resolved))\n resolved = 0;\n return resolved;\n });\n}\n\nfunction useToString(value) {\n return computed(() => `${toValue$1(value)}`);\n}\n\nfunction useToggle(initialValue = false, options = {}) {\n const {\n truthyValue = true,\n falsyValue = false\n } = options;\n const valueIsRef = isRef(initialValue);\n const _value = shallowRef(initialValue);\n function toggle(value) {\n if (arguments.length) {\n _value.value = value;\n return _value.value;\n } else {\n const truthy = toValue$1(truthyValue);\n _value.value = _value.value === truthy ? toValue$1(falsyValue) : truthy;\n return _value.value;\n }\n }\n if (valueIsRef)\n return toggle;\n else\n return [_value, toggle];\n}\n\nfunction watchArray(source, cb, options) {\n let oldList = (options == null ? void 0 : options.immediate) ? [] : [...typeof source === \"function\" ? source() : Array.isArray(source) ? source : toValue$1(source)];\n return watch(source, (newList, _, onCleanup) => {\n const oldListRemains = Array.from({ length: oldList.length });\n const added = [];\n for (const obj of newList) {\n let found = false;\n for (let i = 0; i < oldList.length; i++) {\n if (!oldListRemains[i] && obj === oldList[i]) {\n oldListRemains[i] = true;\n found = true;\n break;\n }\n }\n if (!found)\n added.push(obj);\n }\n const removed = oldList.filter((_2, i) => !oldListRemains[i]);\n cb(newList, oldList, added, removed, onCleanup);\n oldList = [...newList];\n }, options);\n}\n\nfunction watchAtMost(source, cb, options) {\n const {\n count,\n ...watchOptions\n } = options;\n const current = shallowRef(0);\n const stop = watchWithFilter(\n source,\n (...args) => {\n current.value += 1;\n if (current.value >= toValue$1(count))\n nextTick(() => stop());\n cb(...args);\n },\n watchOptions\n );\n return { count: current, stop };\n}\n\nfunction watchDebounced(source, cb, options = {}) {\n const {\n debounce = 0,\n maxWait = void 0,\n ...watchOptions\n } = options;\n return watchWithFilter(\n source,\n cb,\n {\n ...watchOptions,\n eventFilter: debounceFilter(debounce, { maxWait })\n }\n );\n}\n\nfunction watchDeep(source, cb, options) {\n return watch(\n source,\n cb,\n {\n ...options,\n deep: true\n }\n );\n}\n\nfunction watchIgnorable(source, cb, options = {}) {\n const {\n eventFilter = bypassFilter,\n ...watchOptions\n } = options;\n const filteredCb = createFilterWrapper(\n eventFilter,\n cb\n );\n let ignoreUpdates;\n let ignorePrevAsyncUpdates;\n let stop;\n if (watchOptions.flush === \"sync\") {\n const ignore = shallowRef(false);\n ignorePrevAsyncUpdates = () => {\n };\n ignoreUpdates = (updater) => {\n ignore.value = true;\n updater();\n ignore.value = false;\n };\n stop = watch(\n source,\n (...args) => {\n if (!ignore.value)\n filteredCb(...args);\n },\n watchOptions\n );\n } else {\n const disposables = [];\n const ignoreCounter = shallowRef(0);\n const syncCounter = shallowRef(0);\n ignorePrevAsyncUpdates = () => {\n ignoreCounter.value = syncCounter.value;\n };\n disposables.push(\n watch(\n source,\n () => {\n syncCounter.value++;\n },\n { ...watchOptions, flush: \"sync\" }\n )\n );\n ignoreUpdates = (updater) => {\n const syncCounterPrev = syncCounter.value;\n updater();\n ignoreCounter.value += syncCounter.value - syncCounterPrev;\n };\n disposables.push(\n watch(\n source,\n (...args) => {\n const ignore = ignoreCounter.value > 0 && ignoreCounter.value === syncCounter.value;\n ignoreCounter.value = 0;\n syncCounter.value = 0;\n if (ignore)\n return;\n filteredCb(...args);\n },\n watchOptions\n )\n );\n stop = () => {\n disposables.forEach((fn) => fn());\n };\n }\n return { stop, ignoreUpdates, ignorePrevAsyncUpdates };\n}\n\nfunction watchImmediate(source, cb, options) {\n return watch(\n source,\n cb,\n {\n ...options,\n immediate: true\n }\n );\n}\n\nfunction watchOnce(source, cb, options) {\n const stop = watch(source, (...args) => {\n nextTick(() => stop());\n return cb(...args);\n }, options);\n return stop;\n}\n\nfunction watchThrottled(source, cb, options = {}) {\n const {\n throttle = 0,\n trailing = true,\n leading = true,\n ...watchOptions\n } = options;\n return watchWithFilter(\n source,\n cb,\n {\n ...watchOptions,\n eventFilter: throttleFilter(throttle, trailing, leading)\n }\n );\n}\n\nfunction watchTriggerable(source, cb, options = {}) {\n let cleanupFn;\n function onEffect() {\n if (!cleanupFn)\n return;\n const fn = cleanupFn;\n cleanupFn = void 0;\n fn();\n }\n function onCleanup(callback) {\n cleanupFn = callback;\n }\n const _cb = (value, oldValue) => {\n onEffect();\n return cb(value, oldValue, onCleanup);\n };\n const res = watchIgnorable(source, _cb, options);\n const { ignoreUpdates } = res;\n const trigger = () => {\n let res2;\n ignoreUpdates(() => {\n res2 = _cb(getWatchSources(source), getOldValue(source));\n });\n return res2;\n };\n return {\n ...res,\n trigger\n };\n}\nfunction getWatchSources(sources) {\n if (isReactive(sources))\n return sources;\n if (Array.isArray(sources))\n return sources.map((item) => toValue$1(item));\n return toValue$1(sources);\n}\nfunction getOldValue(source) {\n return Array.isArray(source) ? source.map(() => void 0) : void 0;\n}\n\nfunction whenever(source, cb, options) {\n const stop = watch(\n source,\n (v, ov, onInvalidate) => {\n if (v) {\n if (options == null ? void 0 : options.once)\n nextTick(() => stop());\n cb(v, ov, onInvalidate);\n }\n },\n {\n ...options,\n once: false\n }\n );\n return stop;\n}\n\nexport { assert, refAutoReset as autoResetRef, bypassFilter, camelize, clamp, computedEager, computedWithControl, containsProp, computedWithControl as controlledComputed, controlledRef, createEventHook, createFilterWrapper, createGlobalState, createInjectionState, reactify as createReactiveFn, createRef, createSharedComposable, createSingletonPromise, debounceFilter, refDebounced as debouncedRef, watchDebounced as debouncedWatch, computedEager as eagerComputed, extendRef, formatDate, get, getLifeCycleTarget, hasOwn, hyphenate, identity, watchIgnorable as ignorableWatch, increaseWithUnit, injectLocal, invoke, isClient, isDef, isDefined, isIOS, isObject, isWorker, makeDestructurable, noop, normalizeDate, notNullish, now, objectEntries, objectOmit, objectPick, pausableFilter, watchPausable as pausableWatch, promiseTimeout, provideLocal, pxValue, rand, reactify, reactifyObject, reactiveComputed, reactiveOmit, reactivePick, refAutoReset, refDebounced, refDefault, refThrottled, refWithControl, resolveRef, resolveUnref, set, syncRef, syncRefs, throttleFilter, refThrottled as throttledRef, watchThrottled as throttledWatch, timestamp, toArray, toReactive, toRef, toRefs, toValue, tryOnBeforeMount, tryOnBeforeUnmount, tryOnMounted, tryOnScopeDispose, tryOnUnmounted, until, useArrayDifference, useArrayEvery, useArrayFilter, useArrayFind, useArrayFindIndex, useArrayFindLast, useArrayIncludes, useArrayJoin, useArrayMap, useArrayReduce, useArraySome, useArrayUnique, useCounter, useDateFormat, refDebounced as useDebounce, useDebounceFn, useInterval, useIntervalFn, useLastChanged, refThrottled as useThrottle, useThrottleFn, useTimeout, useTimeoutFn, useToNumber, useToString, useToggle, watchArray, watchAtMost, watchDebounced, watchDeep, watchIgnorable, watchImmediate, watchOnce, watchPausable, watchThrottled, watchTriggerable, watchWithFilter, whenever };\n", "import { noop, makeDestructurable, camelize, isClient, toArray, watchImmediate, isObject, tryOnScopeDispose, isIOS, notNullish, tryOnMounted, objectOmit, promiseTimeout, until, injectLocal, provideLocal, pxValue, increaseWithUnit, objectEntries, createRef, createSingletonPromise, useTimeoutFn, pausableWatch, toRef, createEventHook, useIntervalFn, computedWithControl, timestamp, pausableFilter, watchIgnorable, debounceFilter, bypassFilter, createFilterWrapper, toRefs, watchOnce, containsProp, hasOwn, throttleFilter, useDebounceFn, useThrottleFn, tryOnUnmounted, clamp, syncRef, objectPick, watchWithFilter, identity, isDef, whenever, isWorker } from '@vueuse/shared';\nexport * from '@vueuse/shared';\nimport { isRef, shallowRef, ref, watchEffect, computed, inject, defineComponent, h, TransitionGroup, shallowReactive, Fragment, toValue, unref, getCurrentInstance, onMounted, watch, customRef, onUpdated, readonly, reactive, hasInjectionContext, toRaw, nextTick, markRaw, getCurrentScope, isReadonly, onBeforeUpdate } from 'vue';\n\nfunction computedAsync(evaluationCallback, initialState, optionsOrRef) {\n let options;\n if (isRef(optionsOrRef)) {\n options = {\n evaluating: optionsOrRef\n };\n } else {\n options = optionsOrRef || {};\n }\n const {\n lazy = false,\n evaluating = void 0,\n shallow = true,\n onError = noop\n } = options;\n const started = shallowRef(!lazy);\n const current = shallow ? shallowRef(initialState) : ref(initialState);\n let counter = 0;\n watchEffect(async (onInvalidate) => {\n if (!started.value)\n return;\n counter++;\n const counterAtBeginning = counter;\n let hasFinished = false;\n if (evaluating) {\n Promise.resolve().then(() => {\n evaluating.value = true;\n });\n }\n try {\n const result = await evaluationCallback((cancelCallback) => {\n onInvalidate(() => {\n if (evaluating)\n evaluating.value = false;\n if (!hasFinished)\n cancelCallback();\n });\n });\n if (counterAtBeginning === counter)\n current.value = result;\n } catch (e) {\n onError(e);\n } finally {\n if (evaluating && counterAtBeginning === counter)\n evaluating.value = false;\n hasFinished = true;\n }\n });\n if (lazy) {\n return computed(() => {\n started.value = true;\n return current.value;\n });\n } else {\n return current;\n }\n}\n\nfunction computedInject(key, options, defaultSource, treatDefaultAsFactory) {\n let source = inject(key);\n if (defaultSource)\n source = inject(key, defaultSource);\n if (treatDefaultAsFactory)\n source = inject(key, defaultSource, treatDefaultAsFactory);\n if (typeof options === \"function\") {\n return computed((ctx) => options(source, ctx));\n } else {\n return computed({\n get: (ctx) => options.get(source, ctx),\n set: options.set\n });\n }\n}\n\nfunction createReusableTemplate(options = {}) {\n const {\n inheritAttrs = true\n } = options;\n const render = shallowRef();\n const define = /*@__PURE__*/ defineComponent({\n setup(_, { slots }) {\n return () => {\n render.value = slots.default;\n };\n }\n });\n const reuse = /*@__PURE__*/ defineComponent({\n inheritAttrs,\n props: options.props,\n setup(props, { attrs, slots }) {\n return () => {\n var _a;\n if (!render.value && process.env.NODE_ENV !== \"production\")\n throw new Error(\"[VueUse] Failed to find the definition of reusable template\");\n const vnode = (_a = render.value) == null ? void 0 : _a.call(render, {\n ...options.props == null ? keysToCamelKebabCase(attrs) : props,\n $slots: slots\n });\n return inheritAttrs && (vnode == null ? void 0 : vnode.length) === 1 ? vnode[0] : vnode;\n };\n }\n });\n return makeDestructurable(\n { define, reuse },\n [define, reuse]\n );\n}\nfunction keysToCamelKebabCase(obj) {\n const newObj = {};\n for (const key in obj)\n newObj[camelize(key)] = obj[key];\n return newObj;\n}\n\nfunction createTemplatePromise(options = {}) {\n let index = 0;\n const instances = ref([]);\n function create(...args) {\n const props = shallowReactive({\n key: index++,\n args,\n promise: void 0,\n resolve: () => {\n },\n reject: () => {\n },\n isResolving: false,\n options\n });\n instances.value.push(props);\n props.promise = new Promise((_resolve, _reject) => {\n props.resolve = (v) => {\n props.isResolving = true;\n return _resolve(v);\n };\n props.reject = _reject;\n }).finally(() => {\n props.promise = void 0;\n const index2 = instances.value.indexOf(props);\n if (index2 !== -1)\n instances.value.splice(index2, 1);\n });\n return props.promise;\n }\n function start(...args) {\n if (options.singleton && instances.value.length > 0)\n return instances.value[0].promise;\n return create(...args);\n }\n const component = /*@__PURE__*/ defineComponent((_, { slots }) => {\n const renderList = () => instances.value.map((props) => {\n var _a;\n return h(Fragment, { key: props.key }, (_a = slots.default) == null ? void 0 : _a.call(slots, props));\n });\n if (options.transition)\n return () => h(TransitionGroup, options.transition, renderList);\n return renderList;\n });\n component.start = start;\n return component;\n}\n\nfunction createUnrefFn(fn) {\n return function(...args) {\n return fn.apply(this, args.map((i) => toValue(i)));\n };\n}\n\nconst defaultWindow = isClient ? window : void 0;\nconst defaultDocument = isClient ? window.document : void 0;\nconst defaultNavigator = isClient ? window.navigator : void 0;\nconst defaultLocation = isClient ? window.location : void 0;\n\nfunction unrefElement(elRef) {\n var _a;\n const plain = toValue(elRef);\n return (_a = plain == null ? void 0 : plain.$el) != null ? _a : plain;\n}\n\nfunction useEventListener(...args) {\n const cleanups = [];\n const cleanup = () => {\n cleanups.forEach((fn) => fn());\n cleanups.length = 0;\n };\n const register = (el, event, listener, options) => {\n el.addEventListener(event, listener, options);\n return () => el.removeEventListener(event, listener, options);\n };\n const firstParamTargets = computed(() => {\n const test = toArray(toValue(args[0])).filter((e) => e != null);\n return test.every((e) => typeof e !== \"string\") ? test : void 0;\n });\n const stopWatch = watchImmediate(\n () => {\n var _a, _b;\n return [\n (_b = (_a = firstParamTargets.value) == null ? void 0 : _a.map((e) => unrefElement(e))) != null ? _b : [defaultWindow].filter((e) => e != null),\n toArray(toValue(firstParamTargets.value ? args[1] : args[0])),\n toArray(unref(firstParamTargets.value ? args[2] : args[1])),\n // @ts-expect-error - TypeScript gets the correct types, but somehow still complains\n toValue(firstParamTargets.value ? args[3] : args[2])\n ];\n },\n ([raw_targets, raw_events, raw_listeners, raw_options]) => {\n cleanup();\n if (!(raw_targets == null ? void 0 : raw_targets.length) || !(raw_events == null ? void 0 : raw_events.length) || !(raw_listeners == null ? void 0 : raw_listeners.length))\n return;\n const optionsClone = isObject(raw_options) ? { ...raw_options } : raw_options;\n cleanups.push(\n ...raw_targets.flatMap(\n (el) => raw_events.flatMap(\n (event) => raw_listeners.map((listener) => register(el, event, listener, optionsClone))\n )\n )\n );\n },\n { flush: \"post\" }\n );\n const stop = () => {\n stopWatch();\n cleanup();\n };\n tryOnScopeDispose(cleanup);\n return stop;\n}\n\nlet _iOSWorkaround = false;\nfunction onClickOutside(target, handler, options = {}) {\n const { window = defaultWindow, ignore = [], capture = true, detectIframe = false, controls = false } = options;\n if (!window) {\n return controls ? { stop: noop, cancel: noop, trigger: noop } : noop;\n }\n if (isIOS && !_iOSWorkaround) {\n _iOSWorkaround = true;\n const listenerOptions = { passive: true };\n Array.from(window.document.body.children).forEach((el) => useEventListener(el, \"click\", noop, listenerOptions));\n useEventListener(window.document.documentElement, \"click\", noop, listenerOptions);\n }\n let shouldListen = true;\n const shouldIgnore = (event) => {\n return toValue(ignore).some((target2) => {\n if (typeof target2 === \"string\") {\n return Array.from(window.document.querySelectorAll(target2)).some((el) => el === event.target || event.composedPath().includes(el));\n } else {\n const el = unrefElement(target2);\n return el && (event.target === el || event.composedPath().includes(el));\n }\n });\n };\n function hasMultipleRoots(target2) {\n const vm = toValue(target2);\n return vm && vm.$.subTree.shapeFlag === 16;\n }\n function checkMultipleRoots(target2, event) {\n const vm = toValue(target2);\n const children = vm.$.subTree && vm.$.subTree.children;\n if (children == null || !Array.isArray(children))\n return false;\n return children.some((child) => child.el === event.target || event.composedPath().includes(child.el));\n }\n const listener = (event) => {\n const el = unrefElement(target);\n if (event.target == null)\n return;\n if (!(el instanceof Element) && hasMultipleRoots(target) && checkMultipleRoots(target, event))\n return;\n if (!el || el === event.target || event.composedPath().includes(el))\n return;\n if (\"detail\" in event && event.detail === 0)\n shouldListen = !shouldIgnore(event);\n if (!shouldListen) {\n shouldListen = true;\n return;\n }\n handler(event);\n };\n let isProcessingClick = false;\n const cleanup = [\n useEventListener(window, \"click\", (event) => {\n if (!isProcessingClick) {\n isProcessingClick = true;\n setTimeout(() => {\n isProcessingClick = false;\n }, 0);\n listener(event);\n }\n }, { passive: true, capture }),\n useEventListener(window, \"pointerdown\", (e) => {\n const el = unrefElement(target);\n shouldListen = !shouldIgnore(e) && !!(el && !e.composedPath().includes(el));\n }, { passive: true }),\n detectIframe && useEventListener(window, \"blur\", (event) => {\n setTimeout(() => {\n var _a;\n const el = unrefElement(target);\n if (((_a = window.document.activeElement) == null ? void 0 : _a.tagName) === \"IFRAME\" && !(el == null ? void 0 : el.contains(window.document.activeElement))) {\n handler(event);\n }\n }, 0);\n }, { passive: true })\n ].filter(Boolean);\n const stop = () => cleanup.forEach((fn) => fn());\n if (controls) {\n return {\n stop,\n cancel: () => {\n shouldListen = false;\n },\n trigger: (event) => {\n shouldListen = true;\n listener(event);\n shouldListen = false;\n }\n };\n }\n return stop;\n}\n\nfunction useMounted() {\n const isMounted = shallowRef(false);\n const instance = getCurrentInstance();\n if (instance) {\n onMounted(() => {\n isMounted.value = true;\n }, instance);\n }\n return isMounted;\n}\n\nfunction useSupported(callback) {\n const isMounted = useMounted();\n return computed(() => {\n isMounted.value;\n return Boolean(callback());\n });\n}\n\nfunction useMutationObserver(target, callback, options = {}) {\n const { window = defaultWindow, ...mutationOptions } = options;\n let observer;\n const isSupported = useSupported(() => window && \"MutationObserver\" in window);\n const cleanup = () => {\n if (observer) {\n observer.disconnect();\n observer = void 0;\n }\n };\n const targets = computed(() => {\n const value = toValue(target);\n const items = toArray(value).map(unrefElement).filter(notNullish);\n return new Set(items);\n });\n const stopWatch = watch(\n () => targets.value,\n (targets2) => {\n cleanup();\n if (isSupported.value && targets2.size) {\n observer = new MutationObserver(callback);\n targets2.forEach((el) => observer.observe(el, mutationOptions));\n }\n },\n { immediate: true, flush: \"post\" }\n );\n const takeRecords = () => {\n return observer == null ? void 0 : observer.takeRecords();\n };\n const stop = () => {\n stopWatch();\n cleanup();\n };\n tryOnScopeDispose(stop);\n return {\n isSupported,\n stop,\n takeRecords\n };\n}\n\nfunction onElementRemoval(target, callback, options = {}) {\n const {\n window = defaultWindow,\n document = window == null ? void 0 : window.document,\n flush = \"sync\"\n } = options;\n if (!window || !document)\n return noop;\n let stopFn;\n const cleanupAndUpdate = (fn) => {\n stopFn == null ? void 0 : stopFn();\n stopFn = fn;\n };\n const stopWatch = watchEffect(() => {\n const el = unrefElement(target);\n if (el) {\n const { stop } = useMutationObserver(\n document,\n (mutationsList) => {\n const targetRemoved = mutationsList.map((mutation) => [...mutation.removedNodes]).flat().some((node) => node === el || node.contains(el));\n if (targetRemoved) {\n callback(mutationsList);\n }\n },\n {\n window,\n childList: true,\n subtree: true\n }\n );\n cleanupAndUpdate(stop);\n }\n }, { flush });\n const stopHandle = () => {\n stopWatch();\n cleanupAndUpdate();\n };\n tryOnScopeDispose(stopHandle);\n return stopHandle;\n}\n\nfunction createKeyPredicate(keyFilter) {\n if (typeof keyFilter === \"function\")\n return keyFilter;\n else if (typeof keyFilter === \"string\")\n return (event) => event.key === keyFilter;\n else if (Array.isArray(keyFilter))\n return (event) => keyFilter.includes(event.key);\n return () => true;\n}\nfunction onKeyStroke(...args) {\n let key;\n let handler;\n let options = {};\n if (args.length === 3) {\n key = args[0];\n handler = args[1];\n options = args[2];\n } else if (args.length === 2) {\n if (typeof args[1] === \"object\") {\n key = true;\n handler = args[0];\n options = args[1];\n } else {\n key = args[0];\n handler = args[1];\n }\n } else {\n key = true;\n handler = args[0];\n }\n const {\n target = defaultWindow,\n eventName = \"keydown\",\n passive = false,\n dedupe = false\n } = options;\n const predicate = createKeyPredicate(key);\n const listener = (e) => {\n if (e.repeat && toValue(dedupe))\n return;\n if (predicate(e))\n handler(e);\n };\n return useEventListener(target, eventName, listener, passive);\n}\nfunction onKeyDown(key, handler, options = {}) {\n return onKeyStroke(key, handler, { ...options, eventName: \"keydown\" });\n}\nfunction onKeyPressed(key, handler, options = {}) {\n return onKeyStroke(key, handler, { ...options, eventName: \"keypress\" });\n}\nfunction onKeyUp(key, handler, options = {}) {\n return onKeyStroke(key, handler, { ...options, eventName: \"keyup\" });\n}\n\nconst DEFAULT_DELAY = 500;\nconst DEFAULT_THRESHOLD = 10;\nfunction onLongPress(target, handler, options) {\n var _a, _b;\n const elementRef = computed(() => unrefElement(target));\n let timeout;\n let posStart;\n let startTimestamp;\n let hasLongPressed = false;\n function clear() {\n if (timeout) {\n clearTimeout(timeout);\n timeout = void 0;\n }\n posStart = void 0;\n startTimestamp = void 0;\n hasLongPressed = false;\n }\n function onRelease(ev) {\n var _a2, _b2, _c;\n const [_startTimestamp, _posStart, _hasLongPressed] = [startTimestamp, posStart, hasLongPressed];\n clear();\n if (!(options == null ? void 0 : options.onMouseUp) || !_posStart || !_startTimestamp)\n return;\n if (((_a2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _a2.self) && ev.target !== elementRef.value)\n return;\n if ((_b2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _b2.prevent)\n ev.preventDefault();\n if ((_c = options == null ? void 0 : options.modifiers) == null ? void 0 : _c.stop)\n ev.stopPropagation();\n const dx = ev.x - _posStart.x;\n const dy = ev.y - _posStart.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n options.onMouseUp(ev.timeStamp - _startTimestamp, distance, _hasLongPressed);\n }\n function onDown(ev) {\n var _a2, _b2, _c, _d;\n if (((_a2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _a2.self) && ev.target !== elementRef.value)\n return;\n clear();\n if ((_b2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _b2.prevent)\n ev.preventDefault();\n if ((_c = options == null ? void 0 : options.modifiers) == null ? void 0 : _c.stop)\n ev.stopPropagation();\n posStart = {\n x: ev.x,\n y: ev.y\n };\n startTimestamp = ev.timeStamp;\n timeout = setTimeout(\n () => {\n hasLongPressed = true;\n handler(ev);\n },\n (_d = options == null ? void 0 : options.delay) != null ? _d : DEFAULT_DELAY\n );\n }\n function onMove(ev) {\n var _a2, _b2, _c, _d;\n if (((_a2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _a2.self) && ev.target !== elementRef.value)\n return;\n if (!posStart || (options == null ? void 0 : options.distanceThreshold) === false)\n return;\n if ((_b2 = options == null ? void 0 : options.modifiers) == null ? void 0 : _b2.prevent)\n ev.preventDefault();\n if ((_c = options == null ? void 0 : options.modifiers) == null ? void 0 : _c.stop)\n ev.stopPropagation();\n const dx = ev.x - posStart.x;\n const dy = ev.y - posStart.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n if (distance >= ((_d = options == null ? void 0 : options.distanceThreshold) != null ? _d : DEFAULT_THRESHOLD))\n clear();\n }\n const listenerOptions = {\n capture: (_a = options == null ? void 0 : options.modifiers) == null ? void 0 : _a.capture,\n once: (_b = options == null ? void 0 : options.modifiers) == null ? void 0 : _b.once\n };\n const cleanup = [\n useEventListener(elementRef, \"pointerdown\", onDown, listenerOptions),\n useEventListener(elementRef, \"pointermove\", onMove, listenerOptions),\n useEventListener(elementRef, [\"pointerup\", \"pointerleave\"], onRelease, listenerOptions)\n ];\n const stop = () => cleanup.forEach((fn) => fn());\n return stop;\n}\n\nfunction isFocusedElementEditable() {\n const { activeElement, body } = document;\n if (!activeElement)\n return false;\n if (activeElement === body)\n return false;\n switch (activeElement.tagName) {\n case \"INPUT\":\n case \"TEXTAREA\":\n return true;\n }\n return activeElement.hasAttribute(\"contenteditable\");\n}\nfunction isTypedCharValid({\n keyCode,\n metaKey,\n ctrlKey,\n altKey\n}) {\n if (metaKey || ctrlKey || altKey)\n return false;\n if (keyCode >= 48 && keyCode <= 57 || keyCode >= 96 && keyCode <= 105)\n return true;\n if (keyCode >= 65 && keyCode <= 90)\n return true;\n return false;\n}\nfunction onStartTyping(callback, options = {}) {\n const { document: document2 = defaultDocument } = options;\n const keydown = (event) => {\n if (!isFocusedElementEditable() && isTypedCharValid(event)) {\n callback(event);\n }\n };\n if (document2)\n useEventListener(document2, \"keydown\", keydown, { passive: true });\n}\n\nfunction templateRef(key, initialValue = null) {\n const instance = getCurrentInstance();\n let _trigger = () => {\n };\n const element = customRef((track, trigger) => {\n _trigger = trigger;\n return {\n get() {\n var _a, _b;\n track();\n return (_b = (_a = instance == null ? void 0 : instance.proxy) == null ? void 0 : _a.$refs[key]) != null ? _b : initialValue;\n },\n set() {\n }\n };\n });\n tryOnMounted(_trigger);\n onUpdated(_trigger);\n return element;\n}\n\nfunction useActiveElement(options = {}) {\n var _a;\n const {\n window = defaultWindow,\n deep = true,\n triggerOnRemoval = false\n } = options;\n const document = (_a = options.document) != null ? _a : window == null ? void 0 : window.document;\n const getDeepActiveElement = () => {\n var _a2;\n let element = document == null ? void 0 : document.activeElement;\n if (deep) {\n while (element == null ? void 0 : element.shadowRoot)\n element = (_a2 = element == null ? void 0 : element.shadowRoot) == null ? void 0 : _a2.activeElement;\n }\n return element;\n };\n const activeElement = shallowRef();\n const trigger = () => {\n activeElement.value = getDeepActiveElement();\n };\n if (window) {\n const listenerOptions = {\n capture: true,\n passive: true\n };\n useEventListener(\n window,\n \"blur\",\n (event) => {\n if (event.relatedTarget !== null)\n return;\n trigger();\n },\n listenerOptions\n );\n useEventListener(\n window,\n \"focus\",\n trigger,\n listenerOptions\n );\n }\n if (triggerOnRemoval) {\n onElementRemoval(activeElement, trigger, { document });\n }\n trigger();\n return activeElement;\n}\n\nfunction useRafFn(fn, options = {}) {\n const {\n immediate = true,\n fpsLimit = void 0,\n window = defaultWindow,\n once = false\n } = options;\n const isActive = shallowRef(false);\n const intervalLimit = computed(() => {\n return fpsLimit ? 1e3 / toValue(fpsLimit) : null;\n });\n let previousFrameTimestamp = 0;\n let rafId = null;\n function loop(timestamp) {\n if (!isActive.value || !window)\n return;\n if (!previousFrameTimestamp)\n previousFrameTimestamp = timestamp;\n const delta = timestamp - previousFrameTimestamp;\n if (intervalLimit.value && delta < intervalLimit.value) {\n rafId = window.requestAnimationFrame(loop);\n return;\n }\n previousFrameTimestamp = timestamp;\n fn({ delta, timestamp });\n if (once) {\n isActive.value = false;\n rafId = null;\n return;\n }\n rafId = window.requestAnimationFrame(loop);\n }\n function resume() {\n if (!isActive.value && window) {\n isActive.value = true;\n previousFrameTimestamp = 0;\n rafId = window.requestAnimationFrame(loop);\n }\n }\n function pause() {\n isActive.value = false;\n if (rafId != null && window) {\n window.cancelAnimationFrame(rafId);\n rafId = null;\n }\n }\n if (immediate)\n resume();\n tryOnScopeDispose(pause);\n return {\n isActive: readonly(isActive),\n pause,\n resume\n };\n}\n\nfunction useAnimate(target, keyframes, options) {\n let config;\n let animateOptions;\n if (isObject(options)) {\n config = options;\n animateOptions = objectOmit(options, [\"window\", \"immediate\", \"commitStyles\", \"persist\", \"onReady\", \"onError\"]);\n } else {\n config = { duration: options };\n animateOptions = options;\n }\n const {\n window = defaultWindow,\n immediate = true,\n commitStyles,\n persist,\n playbackRate: _playbackRate = 1,\n onReady,\n onError = (e) => {\n console.error(e);\n }\n } = config;\n const isSupported = useSupported(() => window && HTMLElement && \"animate\" in HTMLElement.prototype);\n const animate = shallowRef(void 0);\n const store = shallowReactive({\n startTime: null,\n currentTime: null,\n timeline: null,\n playbackRate: _playbackRate,\n pending: false,\n playState: immediate ? \"idle\" : \"paused\",\n replaceState: \"active\"\n });\n const pending = computed(() => store.pending);\n const playState = computed(() => store.playState);\n const replaceState = computed(() => store.replaceState);\n const startTime = computed({\n get() {\n return store.startTime;\n },\n set(value) {\n store.startTime = value;\n if (animate.value)\n animate.value.startTime = value;\n }\n });\n const currentTime = computed({\n get() {\n return store.currentTime;\n },\n set(value) {\n store.currentTime = value;\n if (animate.value) {\n animate.value.currentTime = value;\n syncResume();\n }\n }\n });\n const timeline = computed({\n get() {\n return store.timeline;\n },\n set(value) {\n store.timeline = value;\n if (animate.value)\n animate.value.timeline = value;\n }\n });\n const playbackRate = computed({\n get() {\n return store.playbackRate;\n },\n set(value) {\n store.playbackRate = value;\n if (animate.value)\n animate.value.playbackRate = value;\n }\n });\n const play = () => {\n if (animate.value) {\n try {\n animate.value.play();\n syncResume();\n } catch (e) {\n syncPause();\n onError(e);\n }\n } else {\n update();\n }\n };\n const pause = () => {\n var _a;\n try {\n (_a = animate.value) == null ? void 0 : _a.pause();\n syncPause();\n } catch (e) {\n onError(e);\n }\n };\n const reverse = () => {\n var _a;\n if (!animate.value)\n update();\n try {\n (_a = animate.value) == null ? void 0 : _a.reverse();\n syncResume();\n } catch (e) {\n syncPause();\n onError(e);\n }\n };\n const finish = () => {\n var _a;\n try {\n (_a = animate.value) == null ? void 0 : _a.finish();\n syncPause();\n } catch (e) {\n onError(e);\n }\n };\n const cancel = () => {\n var _a;\n try {\n (_a = animate.value) == null ? void 0 : _a.cancel();\n syncPause();\n } catch (e) {\n onError(e);\n }\n };\n watch(() => unrefElement(target), (el) => {\n if (el) {\n update();\n } else {\n animate.value = void 0;\n }\n });\n watch(() => keyframes, (value) => {\n if (animate.value) {\n update();\n const targetEl = unrefElement(target);\n if (targetEl) {\n animate.value.effect = new KeyframeEffect(\n targetEl,\n toValue(value),\n animateOptions\n );\n }\n }\n }, { deep: true });\n tryOnMounted(() => update(true), false);\n tryOnScopeDispose(cancel);\n function update(init) {\n const el = unrefElement(target);\n if (!isSupported.value || !el)\n return;\n if (!animate.value)\n animate.value = el.animate(toValue(keyframes), animateOptions);\n if (persist)\n animate.value.persist();\n if (_playbackRate !== 1)\n animate.value.playbackRate = _playbackRate;\n if (init && !immediate)\n animate.value.pause();\n else\n syncResume();\n onReady == null ? void 0 : onReady(animate.value);\n }\n const listenerOptions = { passive: true };\n useEventListener(animate, [\"cancel\", \"finish\", \"remove\"], syncPause, listenerOptions);\n useEventListener(animate, \"finish\", () => {\n var _a;\n if (commitStyles)\n (_a = animate.value) == null ? void 0 : _a.commitStyles();\n }, listenerOptions);\n const { resume: resumeRef, pause: pauseRef } = useRafFn(() => {\n if (!animate.value)\n return;\n store.pending = animate.value.pending;\n store.playState = animate.value.playState;\n store.replaceState = animate.value.replaceState;\n store.startTime = animate.value.startTime;\n store.currentTime = animate.value.currentTime;\n store.timeline = animate.value.timeline;\n store.playbackRate = animate.value.playbackRate;\n }, { immediate: false });\n function syncResume() {\n if (isSupported.value)\n resumeRef();\n }\n function syncPause() {\n if (isSupported.value && window)\n window.requestAnimationFrame(pauseRef);\n }\n return {\n isSupported,\n animate,\n // actions\n play,\n pause,\n reverse,\n finish,\n cancel,\n // state\n pending,\n playState,\n replaceState,\n startTime,\n currentTime,\n timeline,\n playbackRate\n };\n}\n\nfunction useAsyncQueue(tasks, options) {\n const {\n interrupt = true,\n onError = noop,\n onFinished = noop,\n signal\n } = options || {};\n const promiseState = {\n aborted: \"aborted\",\n fulfilled: \"fulfilled\",\n pending: \"pending\",\n rejected: \"rejected\"\n };\n const initialResult = Array.from(Array.from({ length: tasks.length }), () => ({ state: promiseState.pending, data: null }));\n const result = reactive(initialResult);\n const activeIndex = shallowRef(-1);\n if (!tasks || tasks.length === 0) {\n onFinished();\n return {\n activeIndex,\n result\n };\n }\n function updateResult(state, res) {\n activeIndex.value++;\n result[activeIndex.value].data = res;\n result[activeIndex.value].state = state;\n }\n tasks.reduce((prev, curr) => {\n return prev.then((prevRes) => {\n var _a;\n if (signal == null ? void 0 : signal.aborted) {\n updateResult(promiseState.aborted, new Error(\"aborted\"));\n return;\n }\n if (((_a = result[activeIndex.value]) == null ? void 0 : _a.state) === promiseState.rejected && interrupt) {\n onFinished();\n return;\n }\n const done = curr(prevRes).then((currentRes) => {\n updateResult(promiseState.fulfilled, currentRes);\n if (activeIndex.value === tasks.length - 1)\n onFinished();\n return currentRes;\n });\n if (!signal)\n return done;\n return Promise.race([done, whenAborted(signal)]);\n }).catch((e) => {\n if (signal == null ? void 0 : signal.aborted) {\n updateResult(promiseState.aborted, e);\n return e;\n }\n updateResult(promiseState.rejected, e);\n onError();\n return e;\n });\n }, Promise.resolve());\n return {\n activeIndex,\n result\n };\n}\nfunction whenAborted(signal) {\n return new Promise((resolve, reject) => {\n const error = new Error(\"aborted\");\n if (signal.aborted)\n reject(error);\n else\n signal.addEventListener(\"abort\", () => reject(error), { once: true });\n });\n}\n\nfunction useAsyncState(promise, initialState, options) {\n const {\n immediate = true,\n delay = 0,\n onError = noop,\n onSuccess = noop,\n resetOnExecute = true,\n shallow = true,\n throwError\n } = options != null ? options : {};\n const state = shallow ? shallowRef(initialState) : ref(initialState);\n const isReady = shallowRef(false);\n const isLoading = shallowRef(false);\n const error = shallowRef(void 0);\n async function execute(delay2 = 0, ...args) {\n if (resetOnExecute)\n state.value = initialState;\n error.value = void 0;\n isReady.value = false;\n isLoading.value = true;\n if (delay2 > 0)\n await promiseTimeout(delay2);\n const _promise = typeof promise === \"function\" ? promise(...args) : promise;\n try {\n const data = await _promise;\n state.value = data;\n isReady.value = true;\n onSuccess(data);\n } catch (e) {\n error.value = e;\n onError(e);\n if (throwError)\n throw e;\n } finally {\n isLoading.value = false;\n }\n return state.value;\n }\n if (immediate) {\n execute(delay);\n }\n const shell = {\n state,\n isReady,\n isLoading,\n error,\n execute\n };\n function waitUntilIsLoaded() {\n return new Promise((resolve, reject) => {\n until(isLoading).toBe(false).then(() => resolve(shell)).catch(reject);\n });\n }\n return {\n ...shell,\n then(onFulfilled, onRejected) {\n return waitUntilIsLoaded().then(onFulfilled, onRejected);\n }\n };\n}\n\nconst defaults = {\n array: (v) => JSON.stringify(v),\n object: (v) => JSON.stringify(v),\n set: (v) => JSON.stringify(Array.from(v)),\n map: (v) => JSON.stringify(Object.fromEntries(v)),\n null: () => \"\"\n};\nfunction getDefaultSerialization(target) {\n if (!target)\n return defaults.null;\n if (target instanceof Map)\n return defaults.map;\n else if (target instanceof Set)\n return defaults.set;\n else if (Array.isArray(target))\n return defaults.array;\n else\n return defaults.object;\n}\n\nfunction useBase64(target, options) {\n const base64 = shallowRef(\"\");\n const promise = shallowRef();\n function execute() {\n if (!isClient)\n return;\n promise.value = new Promise((resolve, reject) => {\n try {\n const _target = toValue(target);\n if (_target == null) {\n resolve(\"\");\n } else if (typeof _target === \"string\") {\n resolve(blobToBase64(new Blob([_target], { type: \"text/plain\" })));\n } else if (_target instanceof Blob) {\n resolve(blobToBase64(_target));\n } else if (_target instanceof ArrayBuffer) {\n resolve(window.btoa(String.fromCharCode(...new Uint8Array(_target))));\n } else if (_target instanceof HTMLCanvasElement) {\n resolve(_target.toDataURL(options == null ? void 0 : options.type, options == null ? void 0 : options.quality));\n } else if (_target instanceof HTMLImageElement) {\n const img = _target.cloneNode(false);\n img.crossOrigin = \"Anonymous\";\n imgLoaded(img).then(() => {\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n canvas.width = img.width;\n canvas.height = img.height;\n ctx.drawImage(img, 0, 0, canvas.width, canvas.height);\n resolve(canvas.toDataURL(options == null ? void 0 : options.type, options == null ? void 0 : options.quality));\n }).catch(reject);\n } else if (typeof _target === \"object\") {\n const _serializeFn = (options == null ? void 0 : options.serializer) || getDefaultSerialization(_target);\n const serialized = _serializeFn(_target);\n return resolve(blobToBase64(new Blob([serialized], { type: \"application/json\" })));\n } else {\n reject(new Error(\"target is unsupported types\"));\n }\n } catch (error) {\n reject(error);\n }\n });\n promise.value.then((res) => {\n base64.value = (options == null ? void 0 : options.dataUrl) === false ? res.replace(/^data:.*?;base64,/, \"\") : res;\n });\n return promise.value;\n }\n if (isRef(target) || typeof target === \"function\")\n watch(target, execute, { immediate: true });\n else\n execute();\n return {\n base64,\n promise,\n execute\n };\n}\nfunction imgLoaded(img) {\n return new Promise((resolve, reject) => {\n if (!img.complete) {\n img.onload = () => {\n resolve();\n };\n img.onerror = reject;\n } else {\n resolve();\n }\n });\n}\nfunction blobToBase64(blob) {\n return new Promise((resolve, reject) => {\n const fr = new FileReader();\n fr.onload = (e) => {\n resolve(e.target.result);\n };\n fr.onerror = reject;\n fr.readAsDataURL(blob);\n });\n}\n\nfunction useBattery(options = {}) {\n const { navigator = defaultNavigator } = options;\n const events = [\"chargingchange\", \"chargingtimechange\", \"dischargingtimechange\", \"levelchange\"];\n const isSupported = useSupported(() => navigator && \"getBattery\" in navigator && typeof navigator.getBattery === \"function\");\n const charging = shallowRef(false);\n const chargingTime = shallowRef(0);\n const dischargingTime = shallowRef(0);\n const level = shallowRef(1);\n let battery;\n function updateBatteryInfo() {\n charging.value = this.charging;\n chargingTime.value = this.chargingTime || 0;\n dischargingTime.value = this.dischargingTime || 0;\n level.value = this.level;\n }\n if (isSupported.value) {\n navigator.getBattery().then((_battery) => {\n battery = _battery;\n updateBatteryInfo.call(battery);\n useEventListener(battery, events, updateBatteryInfo, { passive: true });\n });\n }\n return {\n isSupported,\n charging,\n chargingTime,\n dischargingTime,\n level\n };\n}\n\nfunction useBluetooth(options) {\n let {\n acceptAllDevices = false\n } = options || {};\n const {\n filters = void 0,\n optionalServices = void 0,\n navigator = defaultNavigator\n } = options || {};\n const isSupported = useSupported(() => navigator && \"bluetooth\" in navigator);\n const device = shallowRef();\n const error = shallowRef(null);\n watch(device, () => {\n connectToBluetoothGATTServer();\n });\n async function requestDevice() {\n if (!isSupported.value)\n return;\n error.value = null;\n if (filters && filters.length > 0)\n acceptAllDevices = false;\n try {\n device.value = await (navigator == null ? void 0 : navigator.bluetooth.requestDevice({\n acceptAllDevices,\n filters,\n optionalServices\n }));\n } catch (err) {\n error.value = err;\n }\n }\n const server = shallowRef();\n const isConnected = shallowRef(false);\n function reset() {\n isConnected.value = false;\n device.value = void 0;\n server.value = void 0;\n }\n async function connectToBluetoothGATTServer() {\n error.value = null;\n if (device.value && device.value.gatt) {\n useEventListener(device, \"gattserverdisconnected\", reset, { passive: true });\n try {\n server.value = await device.value.gatt.connect();\n isConnected.value = server.value.connected;\n } catch (err) {\n error.value = err;\n }\n }\n }\n tryOnMounted(() => {\n var _a;\n if (device.value)\n (_a = device.value.gatt) == null ? void 0 : _a.connect();\n });\n tryOnScopeDispose(() => {\n var _a;\n if (device.value)\n (_a = device.value.gatt) == null ? void 0 : _a.disconnect();\n });\n return {\n isSupported,\n isConnected: readonly(isConnected),\n // Device:\n device,\n requestDevice,\n // Server:\n server,\n // Errors:\n error\n };\n}\n\nconst ssrWidthSymbol = Symbol(\"vueuse-ssr-width\");\nfunction useSSRWidth() {\n const ssrWidth = hasInjectionContext() ? injectLocal(ssrWidthSymbol, null) : null;\n return typeof ssrWidth === \"number\" ? ssrWidth : void 0;\n}\nfunction provideSSRWidth(width, app) {\n if (app !== void 0) {\n app.provide(ssrWidthSymbol, width);\n } else {\n provideLocal(ssrWidthSymbol, width);\n }\n}\n\nfunction useMediaQuery(query, options = {}) {\n const { window = defaultWindow, ssrWidth = useSSRWidth() } = options;\n const isSupported = useSupported(() => window && \"matchMedia\" in window && typeof window.matchMedia === \"function\");\n const ssrSupport = shallowRef(typeof ssrWidth === \"number\");\n const mediaQuery = shallowRef();\n const matches = shallowRef(false);\n const handler = (event) => {\n matches.value = event.matches;\n };\n watchEffect(() => {\n if (ssrSupport.value) {\n ssrSupport.value = !isSupported.value;\n const queryStrings = toValue(query).split(\",\");\n matches.value = queryStrings.some((queryString) => {\n const not = queryString.includes(\"not all\");\n const minWidth = queryString.match(/\\(\\s*min-width:\\s*(-?\\d+(?:\\.\\d*)?[a-z]+\\s*)\\)/);\n const maxWidth = queryString.match(/\\(\\s*max-width:\\s*(-?\\d+(?:\\.\\d*)?[a-z]+\\s*)\\)/);\n let res = Boolean(minWidth || maxWidth);\n if (minWidth && res) {\n res = ssrWidth >= pxValue(minWidth[1]);\n }\n if (maxWidth && res) {\n res = ssrWidth <= pxValue(maxWidth[1]);\n }\n return not ? !res : res;\n });\n return;\n }\n if (!isSupported.value)\n return;\n mediaQuery.value = window.matchMedia(toValue(query));\n matches.value = mediaQuery.value.matches;\n });\n useEventListener(mediaQuery, \"change\", handler, { passive: true });\n return computed(() => matches.value);\n}\n\nconst breakpointsTailwind = {\n \"sm\": 640,\n \"md\": 768,\n \"lg\": 1024,\n \"xl\": 1280,\n \"2xl\": 1536\n};\nconst breakpointsBootstrapV5 = {\n xs: 0,\n sm: 576,\n md: 768,\n lg: 992,\n xl: 1200,\n xxl: 1400\n};\nconst breakpointsVuetifyV2 = {\n xs: 0,\n sm: 600,\n md: 960,\n lg: 1264,\n xl: 1904\n};\nconst breakpointsVuetifyV3 = {\n xs: 0,\n sm: 600,\n md: 960,\n lg: 1280,\n xl: 1920,\n xxl: 2560\n};\nconst breakpointsVuetify = breakpointsVuetifyV2;\nconst breakpointsAntDesign = {\n xs: 480,\n sm: 576,\n md: 768,\n lg: 992,\n xl: 1200,\n xxl: 1600\n};\nconst breakpointsQuasar = {\n xs: 0,\n sm: 600,\n md: 1024,\n lg: 1440,\n xl: 1920\n};\nconst breakpointsSematic = {\n mobileS: 320,\n mobileM: 375,\n mobileL: 425,\n tablet: 768,\n laptop: 1024,\n laptopL: 1440,\n desktop4K: 2560\n};\nconst breakpointsMasterCss = {\n \"3xs\": 360,\n \"2xs\": 480,\n \"xs\": 600,\n \"sm\": 768,\n \"md\": 1024,\n \"lg\": 1280,\n \"xl\": 1440,\n \"2xl\": 1600,\n \"3xl\": 1920,\n \"4xl\": 2560\n};\nconst breakpointsPrimeFlex = {\n sm: 576,\n md: 768,\n lg: 992,\n xl: 1200\n};\nconst breakpointsElement = {\n xs: 0,\n sm: 768,\n md: 992,\n lg: 1200,\n xl: 1920\n};\n\nfunction useBreakpoints(breakpoints, options = {}) {\n function getValue(k, delta) {\n let v = toValue(breakpoints[toValue(k)]);\n if (delta != null)\n v = increaseWithUnit(v, delta);\n if (typeof v === \"number\")\n v = `${v}px`;\n return v;\n }\n const { window = defaultWindow, strategy = \"min-width\", ssrWidth = useSSRWidth() } = options;\n const ssrSupport = typeof ssrWidth === \"number\";\n const mounted = ssrSupport ? shallowRef(false) : { value: true };\n if (ssrSupport) {\n tryOnMounted(() => mounted.value = !!window);\n }\n function match(query, size) {\n if (!mounted.value && ssrSupport) {\n return query === \"min\" ? ssrWidth >= pxValue(size) : ssrWidth <= pxValue(size);\n }\n if (!window)\n return false;\n return window.matchMedia(`(${query}-width: ${size})`).matches;\n }\n const greaterOrEqual = (k) => {\n return useMediaQuery(() => `(min-width: ${getValue(k)})`, options);\n };\n const smallerOrEqual = (k) => {\n return useMediaQuery(() => `(max-width: ${getValue(k)})`, options);\n };\n const shortcutMethods = Object.keys(breakpoints).reduce((shortcuts, k) => {\n Object.defineProperty(shortcuts, k, {\n get: () => strategy === \"min-width\" ? greaterOrEqual(k) : smallerOrEqual(k),\n enumerable: true,\n configurable: true\n });\n return shortcuts;\n }, {});\n function current() {\n const points = Object.keys(breakpoints).map((k) => [k, shortcutMethods[k], pxValue(getValue(k))]).sort((a, b) => a[2] - b[2]);\n return computed(() => points.filter(([, v]) => v.value).map(([k]) => k));\n }\n return Object.assign(shortcutMethods, {\n greaterOrEqual,\n smallerOrEqual,\n greater(k) {\n return useMediaQuery(() => `(min-width: ${getValue(k, 0.1)})`, options);\n },\n smaller(k) {\n return useMediaQuery(() => `(max-width: ${getValue(k, -0.1)})`, options);\n },\n between(a, b) {\n return useMediaQuery(() => `(min-width: ${getValue(a)}) and (max-width: ${getValue(b, -0.1)})`, options);\n },\n isGreater(k) {\n return match(\"min\", getValue(k, 0.1));\n },\n isGreaterOrEqual(k) {\n return match(\"min\", getValue(k));\n },\n isSmaller(k) {\n return match(\"max\", getValue(k, -0.1));\n },\n isSmallerOrEqual(k) {\n return match(\"max\", getValue(k));\n },\n isInBetween(a, b) {\n return match(\"min\", getValue(a)) && match(\"max\", getValue(b, -0.1));\n },\n current,\n active() {\n const bps = current();\n return computed(() => bps.value.length === 0 ? \"\" : bps.value.at(strategy === \"min-width\" ? -1 : 0));\n }\n });\n}\n\nfunction useBroadcastChannel(options) {\n const {\n name,\n window = defaultWindow\n } = options;\n const isSupported = useSupported(() => window && \"BroadcastChannel\" in window);\n const isClosed = shallowRef(false);\n const channel = ref();\n const data = ref();\n const error = shallowRef(null);\n const post = (data2) => {\n if (channel.value)\n channel.value.postMessage(data2);\n };\n const close = () => {\n if (channel.value)\n channel.value.close();\n isClosed.value = true;\n };\n if (isSupported.value) {\n tryOnMounted(() => {\n error.value = null;\n channel.value = new BroadcastChannel(name);\n const listenerOptions = {\n passive: true\n };\n useEventListener(channel, \"message\", (e) => {\n data.value = e.data;\n }, listenerOptions);\n useEventListener(channel, \"messageerror\", (e) => {\n error.value = e;\n }, listenerOptions);\n useEventListener(channel, \"close\", () => {\n isClosed.value = true;\n }, listenerOptions);\n });\n }\n tryOnScopeDispose(() => {\n close();\n });\n return {\n isSupported,\n channel,\n data,\n post,\n close,\n error,\n isClosed\n };\n}\n\nconst WRITABLE_PROPERTIES = [\n \"hash\",\n \"host\",\n \"hostname\",\n \"href\",\n \"pathname\",\n \"port\",\n \"protocol\",\n \"search\"\n];\nfunction useBrowserLocation(options = {}) {\n const { window = defaultWindow } = options;\n const refs = Object.fromEntries(\n WRITABLE_PROPERTIES.map((key) => [key, ref()])\n );\n for (const [key, ref] of objectEntries(refs)) {\n watch(ref, (value) => {\n if (!(window == null ? void 0 : window.location) || window.location[key] === value)\n return;\n window.location[key] = value;\n });\n }\n const buildState = (trigger) => {\n var _a;\n const { state: state2, length } = (window == null ? void 0 : window.history) || {};\n const { origin } = (window == null ? void 0 : window.location) || {};\n for (const key of WRITABLE_PROPERTIES)\n refs[key].value = (_a = window == null ? void 0 : window.location) == null ? void 0 : _a[key];\n return reactive({\n trigger,\n state: state2,\n length,\n origin,\n ...refs\n });\n };\n const state = ref(buildState(\"load\"));\n if (window) {\n const listenerOptions = { passive: true };\n useEventListener(window, \"popstate\", () => state.value = buildState(\"popstate\"), listenerOptions);\n useEventListener(window, \"hashchange\", () => state.value = buildState(\"hashchange\"), listenerOptions);\n }\n return state;\n}\n\nfunction useCached(refValue, comparator = (a, b) => a === b, options) {\n const { deepRefs = true, ...watchOptions } = options || {};\n const cachedValue = createRef(refValue.value, deepRefs);\n watch(() => refValue.value, (value) => {\n if (!comparator(value, cachedValue.value))\n cachedValue.value = value;\n }, watchOptions);\n return cachedValue;\n}\n\nfunction usePermission(permissionDesc, options = {}) {\n const {\n controls = false,\n navigator = defaultNavigator\n } = options;\n const isSupported = useSupported(() => navigator && \"permissions\" in navigator);\n const permissionStatus = shallowRef();\n const desc = typeof permissionDesc === \"string\" ? { name: permissionDesc } : permissionDesc;\n const state = shallowRef();\n const update = () => {\n var _a, _b;\n state.value = (_b = (_a = permissionStatus.value) == null ? void 0 : _a.state) != null ? _b : \"prompt\";\n };\n useEventListener(permissionStatus, \"change\", update, { passive: true });\n const query = createSingletonPromise(async () => {\n if (!isSupported.value)\n return;\n if (!permissionStatus.value) {\n try {\n permissionStatus.value = await navigator.permissions.query(desc);\n } catch (e) {\n permissionStatus.value = void 0;\n } finally {\n update();\n }\n }\n if (controls)\n return toRaw(permissionStatus.value);\n });\n query();\n if (controls) {\n return {\n state,\n isSupported,\n query\n };\n } else {\n return state;\n }\n}\n\nfunction useClipboard(options = {}) {\n const {\n navigator = defaultNavigator,\n read = false,\n source,\n copiedDuring = 1500,\n legacy = false\n } = options;\n const isClipboardApiSupported = useSupported(() => navigator && \"clipboard\" in navigator);\n const permissionRead = usePermission(\"clipboard-read\");\n const permissionWrite = usePermission(\"clipboard-write\");\n const isSupported = computed(() => isClipboardApiSupported.value || legacy);\n const text = shallowRef(\"\");\n const copied = shallowRef(false);\n const timeout = useTimeoutFn(() => copied.value = false, copiedDuring, { immediate: false });\n async function updateText() {\n let useLegacy = !(isClipboardApiSupported.value && isAllowed(permissionRead.value));\n if (!useLegacy) {\n try {\n text.value = await navigator.clipboard.readText();\n } catch (e) {\n useLegacy = true;\n }\n }\n if (useLegacy) {\n text.value = legacyRead();\n }\n }\n if (isSupported.value && read)\n useEventListener([\"copy\", \"cut\"], updateText, { passive: true });\n async function copy(value = toValue(source)) {\n if (isSupported.value && value != null) {\n let useLegacy = !(isClipboardApiSupported.value && isAllowed(permissionWrite.value));\n if (!useLegacy) {\n try {\n await navigator.clipboard.writeText(value);\n } catch (e) {\n useLegacy = true;\n }\n }\n if (useLegacy)\n legacyCopy(value);\n text.value = value;\n copied.value = true;\n timeout.start();\n }\n }\n function legacyCopy(value) {\n const ta = document.createElement(\"textarea\");\n ta.value = value != null ? value : \"\";\n ta.style.position = \"absolute\";\n ta.style.opacity = \"0\";\n document.body.appendChild(ta);\n ta.select();\n document.execCommand(\"copy\");\n ta.remove();\n }\n function legacyRead() {\n var _a, _b, _c;\n return (_c = (_b = (_a = document == null ? void 0 : document.getSelection) == null ? void 0 : _a.call(document)) == null ? void 0 : _b.toString()) != null ? _c : \"\";\n }\n function isAllowed(status) {\n return status === \"granted\" || status === \"prompt\";\n }\n return {\n isSupported,\n text,\n copied,\n copy\n };\n}\n\nfunction useClipboardItems(options = {}) {\n const {\n navigator = defaultNavigator,\n read = false,\n source,\n copiedDuring = 1500\n } = options;\n const isSupported = useSupported(() => navigator && \"clipboard\" in navigator);\n const content = ref([]);\n const copied = shallowRef(false);\n const timeout = useTimeoutFn(() => copied.value = false, copiedDuring, { immediate: false });\n function updateContent() {\n if (isSupported.value) {\n navigator.clipboard.read().then((items) => {\n content.value = items;\n });\n }\n }\n if (isSupported.value && read)\n useEventListener([\"copy\", \"cut\"], updateContent, { passive: true });\n async function copy(value = toValue(source)) {\n if (isSupported.value && value != null) {\n await navigator.clipboard.write(value);\n content.value = value;\n copied.value = true;\n timeout.start();\n }\n }\n return {\n isSupported,\n content,\n copied,\n copy\n };\n}\n\nfunction cloneFnJSON(source) {\n return JSON.parse(JSON.stringify(source));\n}\nfunction useCloned(source, options = {}) {\n const cloned = ref({});\n const isModified = shallowRef(false);\n let _lastSync = false;\n const {\n manual,\n clone = cloneFnJSON,\n // watch options\n deep = true,\n immediate = true\n } = options;\n watch(cloned, () => {\n if (_lastSync) {\n _lastSync = false;\n return;\n }\n isModified.value = true;\n }, {\n deep: true,\n flush: \"sync\"\n });\n function sync() {\n _lastSync = true;\n isModified.value = false;\n cloned.value = clone(toValue(source));\n }\n if (!manual && (isRef(source) || typeof source === \"function\")) {\n watch(source, sync, {\n ...options,\n deep,\n immediate\n });\n } else {\n sync();\n }\n return { cloned, isModified, sync };\n}\n\nconst _global = typeof globalThis !== \"undefined\" ? globalThis : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : {};\nconst globalKey = \"__vueuse_ssr_handlers__\";\nconst handlers = /* @__PURE__ */ getHandlers();\nfunction getHandlers() {\n if (!(globalKey in _global))\n _global[globalKey] = _global[globalKey] || {};\n return _global[globalKey];\n}\nfunction getSSRHandler(key, fallback) {\n return handlers[key] || fallback;\n}\nfunction setSSRHandler(key, fn) {\n handlers[key] = fn;\n}\n\nfunction usePreferredDark(options) {\n return useMediaQuery(\"(prefers-color-scheme: dark)\", options);\n}\n\nfunction guessSerializerType(rawInit) {\n return rawInit == null ? \"any\" : rawInit instanceof Set ? \"set\" : rawInit instanceof Map ? \"map\" : rawInit instanceof Date ? \"date\" : typeof rawInit === \"boolean\" ? \"boolean\" : typeof rawInit === \"string\" ? \"string\" : typeof rawInit === \"object\" ? \"object\" : !Number.isNaN(rawInit) ? \"number\" : \"any\";\n}\n\nconst StorageSerializers = {\n boolean: {\n read: (v) => v === \"true\",\n write: (v) => String(v)\n },\n object: {\n read: (v) => JSON.parse(v),\n write: (v) => JSON.stringify(v)\n },\n number: {\n read: (v) => Number.parseFloat(v),\n write: (v) => String(v)\n },\n any: {\n read: (v) => v,\n write: (v) => String(v)\n },\n string: {\n read: (v) => v,\n write: (v) => String(v)\n },\n map: {\n read: (v) => new Map(JSON.parse(v)),\n write: (v) => JSON.stringify(Array.from(v.entries()))\n },\n set: {\n read: (v) => new Set(JSON.parse(v)),\n write: (v) => JSON.stringify(Array.from(v))\n },\n date: {\n read: (v) => new Date(v),\n write: (v) => v.toISOString()\n }\n};\nconst customStorageEventName = \"vueuse-storage\";\nfunction useStorage(key, defaults, storage, options = {}) {\n var _a;\n const {\n flush = \"pre\",\n deep = true,\n listenToStorageChanges = true,\n writeDefaults = true,\n mergeDefaults = false,\n shallow,\n window = defaultWindow,\n eventFilter,\n onError = (e) => {\n console.error(e);\n },\n initOnMounted\n } = options;\n const data = (shallow ? shallowRef : ref)(typeof defaults === \"function\" ? defaults() : defaults);\n const keyComputed = computed(() => toValue(key));\n if (!storage) {\n try {\n storage = getSSRHandler(\"getDefaultStorage\", () => {\n var _a2;\n return (_a2 = defaultWindow) == null ? void 0 : _a2.localStorage;\n })();\n } catch (e) {\n onError(e);\n }\n }\n if (!storage)\n return data;\n const rawInit = toValue(defaults);\n const type = guessSerializerType(rawInit);\n const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type];\n const { pause: pauseWatch, resume: resumeWatch } = pausableWatch(\n data,\n () => write(data.value),\n { flush, deep, eventFilter }\n );\n watch(keyComputed, () => update(), { flush });\n if (window && listenToStorageChanges) {\n tryOnMounted(() => {\n if (storage instanceof Storage)\n useEventListener(window, \"storage\", update, { passive: true });\n else\n useEventListener(window, customStorageEventName, updateFromCustomEvent);\n if (initOnMounted)\n update();\n });\n }\n if (!initOnMounted)\n update();\n function dispatchWriteEvent(oldValue, newValue) {\n if (window) {\n const payload = {\n key: keyComputed.value,\n oldValue,\n newValue,\n storageArea: storage\n };\n window.dispatchEvent(storage instanceof Storage ? new StorageEvent(\"storage\", payload) : new CustomEvent(customStorageEventName, {\n detail: payload\n }));\n }\n }\n function write(v) {\n try {\n const oldValue = storage.getItem(keyComputed.value);\n if (v == null) {\n dispatchWriteEvent(oldValue, null);\n storage.removeItem(keyComputed.value);\n } else {\n const serialized = serializer.write(v);\n if (oldValue !== serialized) {\n storage.setItem(keyComputed.value, serialized);\n dispatchWriteEvent(oldValue, serialized);\n }\n }\n } catch (e) {\n onError(e);\n }\n }\n function read(event) {\n const rawValue = event ? event.newValue : storage.getItem(keyComputed.value);\n if (rawValue == null) {\n if (writeDefaults && rawInit != null)\n storage.setItem(keyComputed.value, serializer.write(rawInit));\n return rawInit;\n } else if (!event && mergeDefaults) {\n const value = serializer.read(rawValue);\n if (typeof mergeDefaults === \"function\")\n return mergeDefaults(value, rawInit);\n else if (type === \"object\" && !Array.isArray(value))\n return { ...rawInit, ...value };\n return value;\n } else if (typeof rawValue !== \"string\") {\n return rawValue;\n } else {\n return serializer.read(rawValue);\n }\n }\n function update(event) {\n if (event && event.storageArea !== storage)\n return;\n if (event && event.key == null) {\n data.value = rawInit;\n return;\n }\n if (event && event.key !== keyComputed.value)\n return;\n pauseWatch();\n try {\n if ((event == null ? void 0 : event.newValue) !== serializer.write(data.value))\n data.value = read(event);\n } catch (e) {\n onError(e);\n } finally {\n if (event)\n nextTick(resumeWatch);\n else\n resumeWatch();\n }\n }\n function updateFromCustomEvent(event) {\n update(event.detail);\n }\n return data;\n}\n\nconst CSS_DISABLE_TRANS = \"*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}\";\nfunction useColorMode(options = {}) {\n const {\n selector = \"html\",\n attribute = \"class\",\n initialValue = \"auto\",\n window = defaultWindow,\n storage,\n storageKey = \"vueuse-color-scheme\",\n listenToStorageChanges = true,\n storageRef,\n emitAuto,\n disableTransition = true\n } = options;\n const modes = {\n auto: \"\",\n light: \"light\",\n dark: \"dark\",\n ...options.modes || {}\n };\n const preferredDark = usePreferredDark({ window });\n const system = computed(() => preferredDark.value ? \"dark\" : \"light\");\n const store = storageRef || (storageKey == null ? toRef(initialValue) : useStorage(storageKey, initialValue, storage, { window, listenToStorageChanges }));\n const state = computed(() => store.value === \"auto\" ? system.value : store.value);\n const updateHTMLAttrs = getSSRHandler(\n \"updateHTMLAttrs\",\n (selector2, attribute2, value) => {\n const el = typeof selector2 === \"string\" ? window == null ? void 0 : window.document.querySelector(selector2) : unrefElement(selector2);\n if (!el)\n return;\n const classesToAdd = /* @__PURE__ */ new Set();\n const classesToRemove = /* @__PURE__ */ new Set();\n let attributeToChange = null;\n if (attribute2 === \"class\") {\n const current = value.split(/\\s/g);\n Object.values(modes).flatMap((i) => (i || \"\").split(/\\s/g)).filter(Boolean).forEach((v) => {\n if (current.includes(v))\n classesToAdd.add(v);\n else\n classesToRemove.add(v);\n });\n } else {\n attributeToChange = { key: attribute2, value };\n }\n if (classesToAdd.size === 0 && classesToRemove.size === 0 && attributeToChange === null)\n return;\n let style;\n if (disableTransition) {\n style = window.document.createElement(\"style\");\n style.appendChild(document.createTextNode(CSS_DISABLE_TRANS));\n window.document.head.appendChild(style);\n }\n for (const c of classesToAdd) {\n el.classList.add(c);\n }\n for (const c of classesToRemove) {\n el.classList.remove(c);\n }\n if (attributeToChange) {\n el.setAttribute(attributeToChange.key, attributeToChange.value);\n }\n if (disableTransition) {\n window.getComputedStyle(style).opacity;\n document.head.removeChild(style);\n }\n }\n );\n function defaultOnChanged(mode) {\n var _a;\n updateHTMLAttrs(selector, attribute, (_a = modes[mode]) != null ? _a : mode);\n }\n function onChanged(mode) {\n if (options.onChanged)\n options.onChanged(mode, defaultOnChanged);\n else\n defaultOnChanged(mode);\n }\n watch(state, onChanged, { flush: \"post\", immediate: true });\n tryOnMounted(() => onChanged(state.value));\n const auto = computed({\n get() {\n return emitAuto ? store.value : state.value;\n },\n set(v) {\n store.value = v;\n }\n });\n return Object.assign(auto, { store, system, state });\n}\n\nfunction useConfirmDialog(revealed = shallowRef(false)) {\n const confirmHook = createEventHook();\n const cancelHook = createEventHook();\n const revealHook = createEventHook();\n let _resolve = noop;\n const reveal = (data) => {\n revealHook.trigger(data);\n revealed.value = true;\n return new Promise((resolve) => {\n _resolve = resolve;\n });\n };\n const confirm = (data) => {\n revealed.value = false;\n confirmHook.trigger(data);\n _resolve({ data, isCanceled: false });\n };\n const cancel = (data) => {\n revealed.value = false;\n cancelHook.trigger(data);\n _resolve({ data, isCanceled: true });\n };\n return {\n isRevealed: computed(() => revealed.value),\n reveal,\n confirm,\n cancel,\n onReveal: revealHook.on,\n onConfirm: confirmHook.on,\n onCancel: cancelHook.on\n };\n}\n\nfunction useCountdown(initialCountdown, options) {\n var _a, _b;\n const remaining = shallowRef(toValue(initialCountdown));\n const intervalController = useIntervalFn(() => {\n var _a2, _b2;\n const value = remaining.value - 1;\n remaining.value = value < 0 ? 0 : value;\n (_a2 = options == null ? void 0 : options.onTick) == null ? void 0 : _a2.call(options);\n if (remaining.value <= 0) {\n intervalController.pause();\n (_b2 = options == null ? void 0 : options.onComplete) == null ? void 0 : _b2.call(options);\n }\n }, (_a = options == null ? void 0 : options.interval) != null ? _a : 1e3, { immediate: (_b = options == null ? void 0 : options.immediate) != null ? _b : false });\n const reset = (countdown) => {\n var _a2;\n remaining.value = (_a2 = toValue(countdown)) != null ? _a2 : toValue(initialCountdown);\n };\n const stop = () => {\n intervalController.pause();\n reset();\n };\n const resume = () => {\n if (!intervalController.isActive.value) {\n if (remaining.value > 0) {\n intervalController.resume();\n }\n }\n };\n const start = (countdown) => {\n reset(countdown);\n intervalController.resume();\n };\n return {\n remaining,\n reset,\n stop,\n start,\n pause: intervalController.pause,\n resume,\n isActive: intervalController.isActive\n };\n}\n\nfunction useCssVar(prop, target, options = {}) {\n const { window = defaultWindow, initialValue, observe = false } = options;\n const variable = shallowRef(initialValue);\n const elRef = computed(() => {\n var _a;\n return unrefElement(target) || ((_a = window == null ? void 0 : window.document) == null ? void 0 : _a.documentElement);\n });\n function updateCssVar() {\n var _a;\n const key = toValue(prop);\n const el = toValue(elRef);\n if (el && window && key) {\n const value = (_a = window.getComputedStyle(el).getPropertyValue(key)) == null ? void 0 : _a.trim();\n variable.value = value || variable.value || initialValue;\n }\n }\n if (observe) {\n useMutationObserver(elRef, updateCssVar, {\n attributeFilter: [\"style\", \"class\"],\n window\n });\n }\n watch(\n [elRef, () => toValue(prop)],\n (_, old) => {\n if (old[0] && old[1])\n old[0].style.removeProperty(old[1]);\n updateCssVar();\n },\n { immediate: true }\n );\n watch(\n [variable, elRef],\n ([val, el]) => {\n const raw_prop = toValue(prop);\n if ((el == null ? void 0 : el.style) && raw_prop) {\n if (val == null)\n el.style.removeProperty(raw_prop);\n else\n el.style.setProperty(raw_prop, val);\n }\n },\n { immediate: true }\n );\n return variable;\n}\n\nfunction useCurrentElement(rootComponent) {\n const vm = getCurrentInstance();\n const currentElement = computedWithControl(\n () => null,\n () => rootComponent ? unrefElement(rootComponent) : vm.proxy.$el\n );\n onUpdated(currentElement.trigger);\n onMounted(currentElement.trigger);\n return currentElement;\n}\n\nfunction useCycleList(list, options) {\n const state = shallowRef(getInitialValue());\n const listRef = toRef(list);\n const index = computed({\n get() {\n var _a;\n const targetList = listRef.value;\n let index2 = (options == null ? void 0 : options.getIndexOf) ? options.getIndexOf(state.value, targetList) : targetList.indexOf(state.value);\n if (index2 < 0)\n index2 = (_a = options == null ? void 0 : options.fallbackIndex) != null ? _a : 0;\n return index2;\n },\n set(v) {\n set(v);\n }\n });\n function set(i) {\n const targetList = listRef.value;\n const length = targetList.length;\n const index2 = (i % length + length) % length;\n const value = targetList[index2];\n state.value = value;\n return value;\n }\n function shift(delta = 1) {\n return set(index.value + delta);\n }\n function next(n = 1) {\n return shift(n);\n }\n function prev(n = 1) {\n return shift(-n);\n }\n function getInitialValue() {\n var _a, _b;\n return (_b = toValue((_a = options == null ? void 0 : options.initialValue) != null ? _a : toValue(list)[0])) != null ? _b : void 0;\n }\n watch(listRef, () => set(index.value));\n return {\n state,\n index,\n next,\n prev,\n go: set\n };\n}\n\nfunction useDark(options = {}) {\n const {\n valueDark = \"dark\",\n valueLight = \"\"\n } = options;\n const mode = useColorMode({\n ...options,\n onChanged: (mode2, defaultHandler) => {\n var _a;\n if (options.onChanged)\n (_a = options.onChanged) == null ? void 0 : _a.call(options, mode2 === \"dark\", defaultHandler, mode2);\n else\n defaultHandler(mode2);\n },\n modes: {\n dark: valueDark,\n light: valueLight\n }\n });\n const system = computed(() => mode.system.value);\n const isDark = computed({\n get() {\n return mode.value === \"dark\";\n },\n set(v) {\n const modeVal = v ? \"dark\" : \"light\";\n if (system.value === modeVal)\n mode.value = \"auto\";\n else\n mode.value = modeVal;\n }\n });\n return isDark;\n}\n\nfunction fnBypass(v) {\n return v;\n}\nfunction fnSetSource(source, value) {\n return source.value = value;\n}\nfunction defaultDump(clone) {\n return clone ? typeof clone === \"function\" ? clone : cloneFnJSON : fnBypass;\n}\nfunction defaultParse(clone) {\n return clone ? typeof clone === \"function\" ? clone : cloneFnJSON : fnBypass;\n}\nfunction useManualRefHistory(source, options = {}) {\n const {\n clone = false,\n dump = defaultDump(clone),\n parse = defaultParse(clone),\n setSource = fnSetSource\n } = options;\n function _createHistoryRecord() {\n return markRaw({\n snapshot: dump(source.value),\n timestamp: timestamp()\n });\n }\n const last = ref(_createHistoryRecord());\n const undoStack = ref([]);\n const redoStack = ref([]);\n const _setSource = (record) => {\n setSource(source, parse(record.snapshot));\n last.value = record;\n };\n const commit = () => {\n undoStack.value.unshift(last.value);\n last.value = _createHistoryRecord();\n if (options.capacity && undoStack.value.length > options.capacity)\n undoStack.value.splice(options.capacity, Number.POSITIVE_INFINITY);\n if (redoStack.value.length)\n redoStack.value.splice(0, redoStack.value.length);\n };\n const clear = () => {\n undoStack.value.splice(0, undoStack.value.length);\n redoStack.value.splice(0, redoStack.value.length);\n };\n const undo = () => {\n const state = undoStack.value.shift();\n if (state) {\n redoStack.value.unshift(last.value);\n _setSource(state);\n }\n };\n const redo = () => {\n const state = redoStack.value.shift();\n if (state) {\n undoStack.value.unshift(last.value);\n _setSource(state);\n }\n };\n const reset = () => {\n _setSource(last.value);\n };\n const history = computed(() => [last.value, ...undoStack.value]);\n const canUndo = computed(() => undoStack.value.length > 0);\n const canRedo = computed(() => redoStack.value.length > 0);\n return {\n source,\n undoStack,\n redoStack,\n last,\n history,\n canUndo,\n canRedo,\n clear,\n commit,\n reset,\n undo,\n redo\n };\n}\n\nfunction useRefHistory(source, options = {}) {\n const {\n deep = false,\n flush = \"pre\",\n eventFilter\n } = options;\n const {\n eventFilter: composedFilter,\n pause,\n resume: resumeTracking,\n isActive: isTracking\n } = pausableFilter(eventFilter);\n const {\n ignoreUpdates,\n ignorePrevAsyncUpdates,\n stop\n } = watchIgnorable(\n source,\n commit,\n { deep, flush, eventFilter: composedFilter }\n );\n function setSource(source2, value) {\n ignorePrevAsyncUpdates();\n ignoreUpdates(() => {\n source2.value = value;\n });\n }\n const manualHistory = useManualRefHistory(source, { ...options, clone: options.clone || deep, setSource });\n const { clear, commit: manualCommit } = manualHistory;\n function commit() {\n ignorePrevAsyncUpdates();\n manualCommit();\n }\n function resume(commitNow) {\n resumeTracking();\n if (commitNow)\n commit();\n }\n function batch(fn) {\n let canceled = false;\n const cancel = () => canceled = true;\n ignoreUpdates(() => {\n fn(cancel);\n });\n if (!canceled)\n commit();\n }\n function dispose() {\n stop();\n clear();\n }\n return {\n ...manualHistory,\n isTracking,\n pause,\n resume,\n commit,\n batch,\n dispose\n };\n}\n\nfunction useDebouncedRefHistory(source, options = {}) {\n const filter = options.debounce ? debounceFilter(options.debounce) : void 0;\n const history = useRefHistory(source, { ...options, eventFilter: filter });\n return {\n ...history\n };\n}\n\nfunction useDeviceMotion(options = {}) {\n const {\n window = defaultWindow,\n requestPermissions = false,\n eventFilter = bypassFilter\n } = options;\n const isSupported = useSupported(() => typeof DeviceMotionEvent !== \"undefined\");\n const requirePermissions = useSupported(() => isSupported.value && \"requestPermission\" in DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === \"function\");\n const permissionGranted = shallowRef(false);\n const acceleration = ref({ x: null, y: null, z: null });\n const rotationRate = ref({ alpha: null, beta: null, gamma: null });\n const interval = shallowRef(0);\n const accelerationIncludingGravity = ref({\n x: null,\n y: null,\n z: null\n });\n function init() {\n if (window) {\n const onDeviceMotion = createFilterWrapper(\n eventFilter,\n (event) => {\n var _a, _b, _c, _d, _e, _f, _g, _h, _i;\n acceleration.value = {\n x: ((_a = event.acceleration) == null ? void 0 : _a.x) || null,\n y: ((_b = event.acceleration) == null ? void 0 : _b.y) || null,\n z: ((_c = event.acceleration) == null ? void 0 : _c.z) || null\n };\n accelerationIncludingGravity.value = {\n x: ((_d = event.accelerationIncludingGravity) == null ? void 0 : _d.x) || null,\n y: ((_e = event.accelerationIncludingGravity) == null ? void 0 : _e.y) || null,\n z: ((_f = event.accelerationIncludingGravity) == null ? void 0 : _f.z) || null\n };\n rotationRate.value = {\n alpha: ((_g = event.rotationRate) == null ? void 0 : _g.alpha) || null,\n beta: ((_h = event.rotationRate) == null ? void 0 : _h.beta) || null,\n gamma: ((_i = event.rotationRate) == null ? void 0 : _i.gamma) || null\n };\n interval.value = event.interval;\n }\n );\n useEventListener(window, \"devicemotion\", onDeviceMotion, { passive: true });\n }\n }\n const ensurePermissions = async () => {\n if (!requirePermissions.value)\n permissionGranted.value = true;\n if (permissionGranted.value)\n return;\n if (requirePermissions.value) {\n const requestPermission = DeviceMotionEvent.requestPermission;\n try {\n const response = await requestPermission();\n if (response === \"granted\") {\n permissionGranted.value = true;\n init();\n }\n } catch (error) {\n console.error(error);\n }\n }\n };\n if (isSupported.value) {\n if (requestPermissions && requirePermissions.value) {\n ensurePermissions().then(() => init());\n } else {\n init();\n }\n }\n return {\n acceleration,\n accelerationIncludingGravity,\n rotationRate,\n interval,\n isSupported,\n requirePermissions,\n ensurePermissions,\n permissionGranted\n };\n}\n\nfunction useDeviceOrientation(options = {}) {\n const { window = defaultWindow } = options;\n const isSupported = useSupported(() => window && \"DeviceOrientationEvent\" in window);\n const isAbsolute = shallowRef(false);\n const alpha = shallowRef(null);\n const beta = shallowRef(null);\n const gamma = shallowRef(null);\n if (window && isSupported.value) {\n useEventListener(window, \"deviceorientation\", (event) => {\n isAbsolute.value = event.absolute;\n alpha.value = event.alpha;\n beta.value = event.beta;\n gamma.value = event.gamma;\n }, { passive: true });\n }\n return {\n isSupported,\n isAbsolute,\n alpha,\n beta,\n gamma\n };\n}\n\nfunction useDevicePixelRatio(options = {}) {\n const {\n window = defaultWindow\n } = options;\n const pixelRatio = shallowRef(1);\n const query = useMediaQuery(() => `(resolution: ${pixelRatio.value}dppx)`, options);\n let stop = noop;\n if (window) {\n stop = watchImmediate(query, () => pixelRatio.value = window.devicePixelRatio);\n }\n return {\n pixelRatio: readonly(pixelRatio),\n stop\n };\n}\n\nfunction useDevicesList(options = {}) {\n const {\n navigator = defaultNavigator,\n requestPermissions = false,\n constraints = { audio: true, video: true },\n onUpdated\n } = options;\n const devices = ref([]);\n const videoInputs = computed(() => devices.value.filter((i) => i.kind === \"videoinput\"));\n const audioInputs = computed(() => devices.value.filter((i) => i.kind === \"audioinput\"));\n const audioOutputs = computed(() => devices.value.filter((i) => i.kind === \"audiooutput\"));\n const isSupported = useSupported(() => navigator && navigator.mediaDevices && navigator.mediaDevices.enumerateDevices);\n const permissionGranted = shallowRef(false);\n let stream;\n async function update() {\n if (!isSupported.value)\n return;\n devices.value = await navigator.mediaDevices.enumerateDevices();\n onUpdated == null ? void 0 : onUpdated(devices.value);\n if (stream) {\n stream.getTracks().forEach((t) => t.stop());\n stream = null;\n }\n }\n async function ensurePermissions() {\n const deviceName = constraints.video ? \"camera\" : \"microphone\";\n if (!isSupported.value)\n return false;\n if (permissionGranted.value)\n return true;\n const { state, query } = usePermission(deviceName, { controls: true });\n await query();\n if (state.value !== \"granted\") {\n let granted = true;\n try {\n stream = await navigator.mediaDevices.getUserMedia(constraints);\n } catch (e) {\n stream = null;\n granted = false;\n }\n update();\n permissionGranted.value = granted;\n } else {\n permissionGranted.value = true;\n }\n return permissionGranted.value;\n }\n if (isSupported.value) {\n if (requestPermissions)\n ensurePermissions();\n useEventListener(navigator.mediaDevices, \"devicechange\", update, { passive: true });\n update();\n }\n return {\n devices,\n ensurePermissions,\n permissionGranted,\n videoInputs,\n audioInputs,\n audioOutputs,\n isSupported\n };\n}\n\nfunction useDisplayMedia(options = {}) {\n var _a;\n const enabled = shallowRef((_a = options.enabled) != null ? _a : false);\n const video = options.video;\n const audio = options.audio;\n const { navigator = defaultNavigator } = options;\n const isSupported = useSupported(() => {\n var _a2;\n return (_a2 = navigator == null ? void 0 : navigator.mediaDevices) == null ? void 0 : _a2.getDisplayMedia;\n });\n const constraint = { audio, video };\n const stream = shallowRef();\n async function _start() {\n var _a2;\n if (!isSupported.value || stream.value)\n return;\n stream.value = await navigator.mediaDevices.getDisplayMedia(constraint);\n (_a2 = stream.value) == null ? void 0 : _a2.getTracks().forEach((t) => useEventListener(t, \"ended\", stop, { passive: true }));\n return stream.value;\n }\n async function _stop() {\n var _a2;\n (_a2 = stream.value) == null ? void 0 : _a2.getTracks().forEach((t) => t.stop());\n stream.value = void 0;\n }\n function stop() {\n _stop();\n enabled.value = false;\n }\n async function start() {\n await _start();\n if (stream.value)\n enabled.value = true;\n return stream.value;\n }\n watch(\n enabled,\n (v) => {\n if (v)\n _start();\n else\n _stop();\n },\n { immediate: true }\n );\n return {\n isSupported,\n stream,\n start,\n stop,\n enabled\n };\n}\n\nfunction useDocumentVisibility(options = {}) {\n const { document = defaultDocument } = options;\n if (!document)\n return shallowRef(\"visible\");\n const visibility = shallowRef(document.visibilityState);\n useEventListener(document, \"visibilitychange\", () => {\n visibility.value = document.visibilityState;\n }, { passive: true });\n return visibility;\n}\n\nfunction useDraggable(target, options = {}) {\n var _a;\n const {\n pointerTypes,\n preventDefault,\n stopPropagation,\n exact,\n onMove,\n onEnd,\n onStart,\n initialValue,\n axis = \"both\",\n draggingElement = defaultWindow,\n containerElement,\n handle: draggingHandle = target,\n buttons = [0]\n } = options;\n const position = ref(\n (_a = toValue(initialValue)) != null ? _a : { x: 0, y: 0 }\n );\n const pressedDelta = ref();\n const filterEvent = (e) => {\n if (pointerTypes)\n return pointerTypes.includes(e.pointerType);\n return true;\n };\n const handleEvent = (e) => {\n if (toValue(preventDefault))\n e.preventDefault();\n if (toValue(stopPropagation))\n e.stopPropagation();\n };\n const start = (e) => {\n var _a2;\n if (!toValue(buttons).includes(e.button))\n return;\n if (toValue(options.disabled) || !filterEvent(e))\n return;\n if (toValue(exact) && e.target !== toValue(target))\n return;\n const container = toValue(containerElement);\n const containerRect = (_a2 = container == null ? void 0 : container.getBoundingClientRect) == null ? void 0 : _a2.call(container);\n const targetRect = toValue(target).getBoundingClientRect();\n const pos = {\n x: e.clientX - (container ? targetRect.left - containerRect.left + container.scrollLeft : targetRect.left),\n y: e.clientY - (container ? targetRect.top - containerRect.top + container.scrollTop : targetRect.top)\n };\n if ((onStart == null ? void 0 : onStart(pos, e)) === false)\n return;\n pressedDelta.value = pos;\n handleEvent(e);\n };\n const move = (e) => {\n if (toValue(options.disabled) || !filterEvent(e))\n return;\n if (!pressedDelta.value)\n return;\n const container = toValue(containerElement);\n const targetRect = toValue(target).getBoundingClientRect();\n let { x, y } = position.value;\n if (axis === \"x\" || axis === \"both\") {\n x = e.clientX - pressedDelta.value.x;\n if (container)\n x = Math.min(Math.max(0, x), container.scrollWidth - targetRect.width);\n }\n if (axis === \"y\" || axis === \"both\") {\n y = e.clientY - pressedDelta.value.y;\n if (container)\n y = Math.min(Math.max(0, y), container.scrollHeight - targetRect.height);\n }\n position.value = {\n x,\n y\n };\n onMove == null ? void 0 : onMove(position.value, e);\n handleEvent(e);\n };\n const end = (e) => {\n if (toValue(options.disabled) || !filterEvent(e))\n return;\n if (!pressedDelta.value)\n return;\n pressedDelta.value = void 0;\n onEnd == null ? void 0 : onEnd(position.value, e);\n handleEvent(e);\n };\n if (isClient) {\n const config = () => {\n var _a2;\n return {\n capture: (_a2 = options.capture) != null ? _a2 : true,\n passive: !toValue(preventDefault)\n };\n };\n useEventListener(draggingHandle, \"pointerdown\", start, config);\n useEventListener(draggingElement, \"pointermove\", move, config);\n useEventListener(draggingElement, \"pointerup\", end, config);\n }\n return {\n ...toRefs(position),\n position,\n isDragging: computed(() => !!pressedDelta.value),\n style: computed(\n () => `left:${position.value.x}px;top:${position.value.y}px;`\n )\n };\n}\n\nfunction useDropZone(target, options = {}) {\n var _a, _b;\n const isOverDropZone = shallowRef(false);\n const files = shallowRef(null);\n let counter = 0;\n let isValid = true;\n if (isClient) {\n const _options = typeof options === \"function\" ? { onDrop: options } : options;\n const multiple = (_a = _options.multiple) != null ? _a : true;\n const preventDefaultForUnhandled = (_b = _options.preventDefaultForUnhandled) != null ? _b : false;\n const getFiles = (event) => {\n var _a2, _b2;\n const list = Array.from((_b2 = (_a2 = event.dataTransfer) == null ? void 0 : _a2.files) != null ? _b2 : []);\n return list.length === 0 ? null : multiple ? list : [list[0]];\n };\n const checkDataTypes = (types) => {\n const dataTypes = unref(_options.dataTypes);\n if (typeof dataTypes === \"function\")\n return dataTypes(types);\n if (!(dataTypes == null ? void 0 : dataTypes.length))\n return true;\n if (types.length === 0)\n return false;\n return types.every(\n (type) => dataTypes.some((allowedType) => type.includes(allowedType))\n );\n };\n const checkValidity = (items) => {\n const types = Array.from(items != null ? items : []).map((item) => item.type);\n const dataTypesValid = checkDataTypes(types);\n const multipleFilesValid = multiple || items.length <= 1;\n return dataTypesValid && multipleFilesValid;\n };\n const isSafari = () => /^(?:(?!chrome|android).)*safari/i.test(navigator.userAgent) && !(\"chrome\" in window);\n const handleDragEvent = (event, eventType) => {\n var _a2, _b2, _c, _d, _e, _f;\n const dataTransferItemList = (_a2 = event.dataTransfer) == null ? void 0 : _a2.items;\n isValid = (_b2 = dataTransferItemList && checkValidity(dataTransferItemList)) != null ? _b2 : false;\n if (preventDefaultForUnhandled) {\n event.preventDefault();\n }\n if (!isSafari() && !isValid) {\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = \"none\";\n }\n return;\n }\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = \"copy\";\n }\n const currentFiles = getFiles(event);\n switch (eventType) {\n case \"enter\":\n counter += 1;\n isOverDropZone.value = true;\n (_c = _options.onEnter) == null ? void 0 : _c.call(_options, null, event);\n break;\n case \"over\":\n (_d = _options.onOver) == null ? void 0 : _d.call(_options, null, event);\n break;\n case \"leave\":\n counter -= 1;\n if (counter === 0)\n isOverDropZone.value = false;\n (_e = _options.onLeave) == null ? void 0 : _e.call(_options, null, event);\n break;\n case \"drop\":\n counter = 0;\n isOverDropZone.value = false;\n if (isValid) {\n files.value = currentFiles;\n (_f = _options.onDrop) == null ? void 0 : _f.call(_options, currentFiles, event);\n }\n break;\n }\n };\n useEventListener(target, \"dragenter\", (event) => handleDragEvent(event, \"enter\"));\n useEventListener(target, \"dragover\", (event) => handleDragEvent(event, \"over\"));\n useEventListener(target, \"dragleave\", (event) => handleDragEvent(event, \"leave\"));\n useEventListener(target, \"drop\", (event) => handleDragEvent(event, \"drop\"));\n }\n return {\n files,\n isOverDropZone\n };\n}\n\nfunction useResizeObserver(target, callback, options = {}) {\n const { window = defaultWindow, ...observerOptions } = options;\n let observer;\n const isSupported = useSupported(() => window && \"ResizeObserver\" in window);\n const cleanup = () => {\n if (observer) {\n observer.disconnect();\n observer = void 0;\n }\n };\n const targets = computed(() => {\n const _targets = toValue(target);\n return Array.isArray(_targets) ? _targets.map((el) => unrefElement(el)) : [unrefElement(_targets)];\n });\n const stopWatch = watch(\n targets,\n (els) => {\n cleanup();\n if (isSupported.value && window) {\n observer = new ResizeObserver(callback);\n for (const _el of els) {\n if (_el)\n observer.observe(_el, observerOptions);\n }\n }\n },\n { immediate: true, flush: \"post\" }\n );\n const stop = () => {\n cleanup();\n stopWatch();\n };\n tryOnScopeDispose(stop);\n return {\n isSupported,\n stop\n };\n}\n\nfunction useElementBounding(target, options = {}) {\n const {\n reset = true,\n windowResize = true,\n windowScroll = true,\n immediate = true,\n updateTiming = \"sync\"\n } = options;\n const height = shallowRef(0);\n const bottom = shallowRef(0);\n const left = shallowRef(0);\n const right = shallowRef(0);\n const top = shallowRef(0);\n const width = shallowRef(0);\n const x = shallowRef(0);\n const y = shallowRef(0);\n function recalculate() {\n const el = unrefElement(target);\n if (!el) {\n if (reset) {\n height.value = 0;\n bottom.value = 0;\n left.value = 0;\n right.value = 0;\n top.value = 0;\n width.value = 0;\n x.value = 0;\n y.value = 0;\n }\n return;\n }\n const rect = el.getBoundingClientRect();\n height.value = rect.height;\n bottom.value = rect.bottom;\n left.value = rect.left;\n right.value = rect.right;\n top.value = rect.top;\n width.value = rect.width;\n x.value = rect.x;\n y.value = rect.y;\n }\n function update() {\n if (updateTiming === \"sync\")\n recalculate();\n else if (updateTiming === \"next-frame\")\n requestAnimationFrame(() => recalculate());\n }\n useResizeObserver(target, update);\n watch(() => unrefElement(target), (ele) => !ele && update());\n useMutationObserver(target, update, {\n attributeFilter: [\"style\", \"class\"]\n });\n if (windowScroll)\n useEventListener(\"scroll\", update, { capture: true, passive: true });\n if (windowResize)\n useEventListener(\"resize\", update, { passive: true });\n tryOnMounted(() => {\n if (immediate)\n update();\n });\n return {\n height,\n bottom,\n left,\n right,\n top,\n width,\n x,\n y,\n update\n };\n}\n\nfunction useElementByPoint(options) {\n const {\n x,\n y,\n document = defaultDocument,\n multiple,\n interval = \"requestAnimationFrame\",\n immediate = true\n } = options;\n const isSupported = useSupported(() => {\n if (toValue(multiple))\n return document && \"elementsFromPoint\" in document;\n return document && \"elementFromPoint\" in document;\n });\n const element = shallowRef(null);\n const cb = () => {\n var _a, _b;\n element.value = toValue(multiple) ? (_a = document == null ? void 0 : document.elementsFromPoint(toValue(x), toValue(y))) != null ? _a : [] : (_b = document == null ? void 0 : document.elementFromPoint(toValue(x), toValue(y))) != null ? _b : null;\n };\n const controls = interval === \"requestAnimationFrame\" ? useRafFn(cb, { immediate }) : useIntervalFn(cb, interval, { immediate });\n return {\n isSupported,\n element,\n ...controls\n };\n}\n\nfunction useElementHover(el, options = {}) {\n const {\n delayEnter = 0,\n delayLeave = 0,\n triggerOnRemoval = false,\n window = defaultWindow\n } = options;\n const isHovered = shallowRef(false);\n let timer;\n const toggle = (entering) => {\n const delay = entering ? delayEnter : delayLeave;\n if (timer) {\n clearTimeout(timer);\n timer = void 0;\n }\n if (delay)\n timer = setTimeout(() => isHovered.value = entering, delay);\n else\n isHovered.value = entering;\n };\n if (!window)\n return isHovered;\n useEventListener(el, \"mouseenter\", () => toggle(true), { passive: true });\n useEventListener(el, \"mouseleave\", () => toggle(false), { passive: true });\n if (triggerOnRemoval) {\n onElementRemoval(\n computed(() => unrefElement(el)),\n () => toggle(false)\n );\n }\n return isHovered;\n}\n\nfunction useElementSize(target, initialSize = { width: 0, height: 0 }, options = {}) {\n const { window = defaultWindow, box = \"content-box\" } = options;\n const isSVG = computed(() => {\n var _a, _b;\n return (_b = (_a = unrefElement(target)) == null ? void 0 : _a.namespaceURI) == null ? void 0 : _b.includes(\"svg\");\n });\n const width = shallowRef(initialSize.width);\n const height = shallowRef(initialSize.height);\n const { stop: stop1 } = useResizeObserver(\n target,\n ([entry]) => {\n const boxSize = box === \"border-box\" ? entry.borderBoxSize : box === \"content-box\" ? entry.contentBoxSize : entry.devicePixelContentBoxSize;\n if (window && isSVG.value) {\n const $elem = unrefElement(target);\n if ($elem) {\n const rect = $elem.getBoundingClientRect();\n width.value = rect.width;\n height.value = rect.height;\n }\n } else {\n if (boxSize) {\n const formatBoxSize = toArray(boxSize);\n width.value = formatBoxSize.reduce((acc, { inlineSize }) => acc + inlineSize, 0);\n height.value = formatBoxSize.reduce((acc, { blockSize }) => acc + blockSize, 0);\n } else {\n width.value = entry.contentRect.width;\n height.value = entry.contentRect.height;\n }\n }\n },\n options\n );\n tryOnMounted(() => {\n const ele = unrefElement(target);\n if (ele) {\n width.value = \"offsetWidth\" in ele ? ele.offsetWidth : initialSize.width;\n height.value = \"offsetHeight\" in ele ? ele.offsetHeight : initialSize.height;\n }\n });\n const stop2 = watch(\n () => unrefElement(target),\n (ele) => {\n width.value = ele ? initialSize.width : 0;\n height.value = ele ? initialSize.height : 0;\n }\n );\n function stop() {\n stop1();\n stop2();\n }\n return {\n width,\n height,\n stop\n };\n}\n\nfunction useIntersectionObserver(target, callback, options = {}) {\n const {\n root,\n rootMargin = \"0px\",\n threshold = 0,\n window = defaultWindow,\n immediate = true\n } = options;\n const isSupported = useSupported(() => window && \"IntersectionObserver\" in window);\n const targets = computed(() => {\n const _target = toValue(target);\n return toArray(_target).map(unrefElement).filter(notNullish);\n });\n let cleanup = noop;\n const isActive = shallowRef(immediate);\n const stopWatch = isSupported.value ? watch(\n () => [targets.value, unrefElement(root), isActive.value],\n ([targets2, root2]) => {\n cleanup();\n if (!isActive.value)\n return;\n if (!targets2.length)\n return;\n const observer = new IntersectionObserver(\n callback,\n {\n root: unrefElement(root2),\n rootMargin,\n threshold\n }\n );\n targets2.forEach((el) => el && observer.observe(el));\n cleanup = () => {\n observer.disconnect();\n cleanup = noop;\n };\n },\n { immediate, flush: \"post\" }\n ) : noop;\n const stop = () => {\n cleanup();\n stopWatch();\n isActive.value = false;\n };\n tryOnScopeDispose(stop);\n return {\n isSupported,\n isActive,\n pause() {\n cleanup();\n isActive.value = false;\n },\n resume() {\n isActive.value = true;\n },\n stop\n };\n}\n\nfunction useElementVisibility(element, options = {}) {\n const {\n window = defaultWindow,\n scrollTarget,\n threshold = 0,\n rootMargin,\n once = false\n } = options;\n const elementIsVisible = shallowRef(false);\n const { stop } = useIntersectionObserver(\n element,\n (intersectionObserverEntries) => {\n let isIntersecting = elementIsVisible.value;\n let latestTime = 0;\n for (const entry of intersectionObserverEntries) {\n if (entry.time >= latestTime) {\n latestTime = entry.time;\n isIntersecting = entry.isIntersecting;\n }\n }\n elementIsVisible.value = isIntersecting;\n if (once) {\n watchOnce(elementIsVisible, () => {\n stop();\n });\n }\n },\n {\n root: scrollTarget,\n window,\n threshold,\n rootMargin: toValue(rootMargin)\n }\n );\n return elementIsVisible;\n}\n\nconst events = /* @__PURE__ */ new Map();\n\nfunction useEventBus(key) {\n const scope = getCurrentScope();\n function on(listener) {\n var _a;\n const listeners = events.get(key) || /* @__PURE__ */ new Set();\n listeners.add(listener);\n events.set(key, listeners);\n const _off = () => off(listener);\n (_a = scope == null ? void 0 : scope.cleanups) == null ? void 0 : _a.push(_off);\n return _off;\n }\n function once(listener) {\n function _listener(...args) {\n off(_listener);\n listener(...args);\n }\n return on(_listener);\n }\n function off(listener) {\n const listeners = events.get(key);\n if (!listeners)\n return;\n listeners.delete(listener);\n if (!listeners.size)\n reset();\n }\n function reset() {\n events.delete(key);\n }\n function emit(event, payload) {\n var _a;\n (_a = events.get(key)) == null ? void 0 : _a.forEach((v) => v(event, payload));\n }\n return { on, once, off, emit, reset };\n}\n\nfunction resolveNestedOptions$1(options) {\n if (options === true)\n return {};\n return options;\n}\nfunction useEventSource(url, events = [], options = {}) {\n const event = shallowRef(null);\n const data = shallowRef(null);\n const status = shallowRef(\"CONNECTING\");\n const eventSource = ref(null);\n const error = shallowRef(null);\n const urlRef = toRef(url);\n const lastEventId = shallowRef(null);\n let explicitlyClosed = false;\n let retried = 0;\n const {\n withCredentials = false,\n immediate = true,\n autoConnect = true,\n autoReconnect\n } = options;\n const close = () => {\n if (isClient && eventSource.value) {\n eventSource.value.close();\n eventSource.value = null;\n status.value = \"CLOSED\";\n explicitlyClosed = true;\n }\n };\n const _init = () => {\n if (explicitlyClosed || typeof urlRef.value === \"undefined\")\n return;\n const es = new EventSource(urlRef.value, { withCredentials });\n status.value = \"CONNECTING\";\n eventSource.value = es;\n es.onopen = () => {\n status.value = \"OPEN\";\n error.value = null;\n };\n es.onerror = (e) => {\n status.value = \"CLOSED\";\n error.value = e;\n if (es.readyState === 2 && !explicitlyClosed && autoReconnect) {\n es.close();\n const {\n retries = -1,\n delay = 1e3,\n onFailed\n } = resolveNestedOptions$1(autoReconnect);\n retried += 1;\n if (typeof retries === \"number\" && (retries < 0 || retried < retries))\n setTimeout(_init, delay);\n else if (typeof retries === \"function\" && retries())\n setTimeout(_init, delay);\n else\n onFailed == null ? void 0 : onFailed();\n }\n };\n es.onmessage = (e) => {\n event.value = null;\n data.value = e.data;\n lastEventId.value = e.lastEventId;\n };\n for (const event_name of events) {\n useEventListener(es, event_name, (e) => {\n event.value = event_name;\n data.value = e.data || null;\n }, { passive: true });\n }\n };\n const open = () => {\n if (!isClient)\n return;\n close();\n explicitlyClosed = false;\n retried = 0;\n _init();\n };\n if (immediate)\n open();\n if (autoConnect)\n watch(urlRef, open);\n tryOnScopeDispose(close);\n return {\n eventSource,\n event,\n data,\n status,\n error,\n open,\n close,\n lastEventId\n };\n}\n\nfunction useEyeDropper(options = {}) {\n const { initialValue = \"\" } = options;\n const isSupported = useSupported(() => typeof window !== \"undefined\" && \"EyeDropper\" in window);\n const sRGBHex = shallowRef(initialValue);\n async function open(openOptions) {\n if (!isSupported.value)\n return;\n const eyeDropper = new window.EyeDropper();\n const result = await eyeDropper.open(openOptions);\n sRGBHex.value = result.sRGBHex;\n return result;\n }\n return { isSupported, sRGBHex, open };\n}\n\nfunction useFavicon(newIcon = null, options = {}) {\n const {\n baseUrl = \"\",\n rel = \"icon\",\n document = defaultDocument\n } = options;\n const favicon = toRef(newIcon);\n const applyIcon = (icon) => {\n const elements = document == null ? void 0 : document.head.querySelectorAll(`link[rel*=\"${rel}\"]`);\n if (!elements || elements.length === 0) {\n const link = document == null ? void 0 : document.createElement(\"link\");\n if (link) {\n link.rel = rel;\n link.href = `${baseUrl}${icon}`;\n link.type = `image/${icon.split(\".\").pop()}`;\n document == null ? void 0 : document.head.append(link);\n }\n return;\n }\n elements == null ? void 0 : elements.forEach((el) => el.href = `${baseUrl}${icon}`);\n };\n watch(\n favicon,\n (i, o) => {\n if (typeof i === \"string\" && i !== o)\n applyIcon(i);\n },\n { immediate: true }\n );\n return favicon;\n}\n\nconst payloadMapping = {\n json: \"application/json\",\n text: \"text/plain\"\n};\nfunction isFetchOptions(obj) {\n return obj && containsProp(obj, \"immediate\", \"refetch\", \"initialData\", \"timeout\", \"beforeFetch\", \"afterFetch\", \"onFetchError\", \"fetch\", \"updateDataOnError\");\n}\nconst reAbsolute = /^(?:[a-z][a-z\\d+\\-.]*:)?\\/\\//i;\nfunction isAbsoluteURL(url) {\n return reAbsolute.test(url);\n}\nfunction headersToObject(headers) {\n if (typeof Headers !== \"undefined\" && headers instanceof Headers)\n return Object.fromEntries(headers.entries());\n return headers;\n}\nfunction combineCallbacks(combination, ...callbacks) {\n if (combination === \"overwrite\") {\n return async (ctx) => {\n let callback;\n for (let i = callbacks.length - 1; i >= 0; i--) {\n if (callbacks[i] != null) {\n callback = callbacks[i];\n break;\n }\n }\n if (callback)\n return { ...ctx, ...await callback(ctx) };\n return ctx;\n };\n } else {\n return async (ctx) => {\n for (const callback of callbacks) {\n if (callback)\n ctx = { ...ctx, ...await callback(ctx) };\n }\n return ctx;\n };\n }\n}\nfunction createFetch(config = {}) {\n const _combination = config.combination || \"chain\";\n const _options = config.options || {};\n const _fetchOptions = config.fetchOptions || {};\n function useFactoryFetch(url, ...args) {\n const computedUrl = computed(() => {\n const baseUrl = toValue(config.baseUrl);\n const targetUrl = toValue(url);\n return baseUrl && !isAbsoluteURL(targetUrl) ? joinPaths(baseUrl, targetUrl) : targetUrl;\n });\n let options = _options;\n let fetchOptions = _fetchOptions;\n if (args.length > 0) {\n if (isFetchOptions(args[0])) {\n options = {\n ...options,\n ...args[0],\n beforeFetch: combineCallbacks(_combination, _options.beforeFetch, args[0].beforeFetch),\n afterFetch: combineCallbacks(_combination, _options.afterFetch, args[0].afterFetch),\n onFetchError: combineCallbacks(_combination, _options.onFetchError, args[0].onFetchError)\n };\n } else {\n fetchOptions = {\n ...fetchOptions,\n ...args[0],\n headers: {\n ...headersToObject(fetchOptions.headers) || {},\n ...headersToObject(args[0].headers) || {}\n }\n };\n }\n }\n if (args.length > 1 && isFetchOptions(args[1])) {\n options = {\n ...options,\n ...args[1],\n beforeFetch: combineCallbacks(_combination, _options.beforeFetch, args[1].beforeFetch),\n afterFetch: combineCallbacks(_combination, _options.afterFetch, args[1].afterFetch),\n onFetchError: combineCallbacks(_combination, _options.onFetchError, args[1].onFetchError)\n };\n }\n return useFetch(computedUrl, fetchOptions, options);\n }\n return useFactoryFetch;\n}\nfunction useFetch(url, ...args) {\n var _a;\n const supportsAbort = typeof AbortController === \"function\";\n let fetchOptions = {};\n let options = {\n immediate: true,\n refetch: false,\n timeout: 0,\n updateDataOnError: false\n };\n const config = {\n method: \"GET\",\n type: \"text\",\n payload: void 0\n };\n if (args.length > 0) {\n if (isFetchOptions(args[0]))\n options = { ...options, ...args[0] };\n else\n fetchOptions = args[0];\n }\n if (args.length > 1) {\n if (isFetchOptions(args[1]))\n options = { ...options, ...args[1] };\n }\n const {\n fetch = (_a = defaultWindow) == null ? void 0 : _a.fetch,\n initialData,\n timeout\n } = options;\n const responseEvent = createEventHook();\n const errorEvent = createEventHook();\n const finallyEvent = createEventHook();\n const isFinished = shallowRef(false);\n const isFetching = shallowRef(false);\n const aborted = shallowRef(false);\n const statusCode = shallowRef(null);\n const response = shallowRef(null);\n const error = shallowRef(null);\n const data = shallowRef(initialData || null);\n const canAbort = computed(() => supportsAbort && isFetching.value);\n let controller;\n let timer;\n const abort = () => {\n if (supportsAbort) {\n controller == null ? void 0 : controller.abort();\n controller = new AbortController();\n controller.signal.onabort = () => aborted.value = true;\n fetchOptions = {\n ...fetchOptions,\n signal: controller.signal\n };\n }\n };\n const loading = (isLoading) => {\n isFetching.value = isLoading;\n isFinished.value = !isLoading;\n };\n if (timeout)\n timer = useTimeoutFn(abort, timeout, { immediate: false });\n let executeCounter = 0;\n const execute = async (throwOnFailed = false) => {\n var _a2, _b;\n abort();\n loading(true);\n error.value = null;\n statusCode.value = null;\n aborted.value = false;\n executeCounter += 1;\n const currentExecuteCounter = executeCounter;\n const defaultFetchOptions = {\n method: config.method,\n headers: {}\n };\n const payload = toValue(config.payload);\n if (payload) {\n const headers = headersToObject(defaultFetchOptions.headers);\n const proto = Object.getPrototypeOf(payload);\n if (!config.payloadType && payload && (proto === Object.prototype || Array.isArray(proto)) && !(payload instanceof FormData))\n config.payloadType = \"json\";\n if (config.payloadType)\n headers[\"Content-Type\"] = (_a2 = payloadMapping[config.payloadType]) != null ? _a2 : config.payloadType;\n defaultFetchOptions.body = config.payloadType === \"json\" ? JSON.stringify(payload) : payload;\n }\n let isCanceled = false;\n const context = {\n url: toValue(url),\n options: {\n ...defaultFetchOptions,\n ...fetchOptions\n },\n cancel: () => {\n isCanceled = true;\n }\n };\n if (options.beforeFetch)\n Object.assign(context, await options.beforeFetch(context));\n if (isCanceled || !fetch) {\n loading(false);\n return Promise.resolve(null);\n }\n let responseData = null;\n if (timer)\n timer.start();\n return fetch(\n context.url,\n {\n ...defaultFetchOptions,\n ...context.options,\n headers: {\n ...headersToObject(defaultFetchOptions.headers),\n ...headersToObject((_b = context.options) == null ? void 0 : _b.headers)\n }\n }\n ).then(async (fetchResponse) => {\n response.value = fetchResponse;\n statusCode.value = fetchResponse.status;\n responseData = await fetchResponse.clone()[config.type]();\n if (!fetchResponse.ok) {\n data.value = initialData || null;\n throw new Error(fetchResponse.statusText);\n }\n if (options.afterFetch) {\n ({ data: responseData } = await options.afterFetch({\n data: responseData,\n response: fetchResponse,\n context,\n execute\n }));\n }\n data.value = responseData;\n responseEvent.trigger(fetchResponse);\n return fetchResponse;\n }).catch(async (fetchError) => {\n let errorData = fetchError.message || fetchError.name;\n if (options.onFetchError) {\n ({ error: errorData, data: responseData } = await options.onFetchError({\n data: responseData,\n error: fetchError,\n response: response.value,\n context,\n execute\n }));\n }\n error.value = errorData;\n if (options.updateDataOnError)\n data.value = responseData;\n errorEvent.trigger(fetchError);\n if (throwOnFailed)\n throw fetchError;\n return null;\n }).finally(() => {\n if (currentExecuteCounter === executeCounter)\n loading(false);\n if (timer)\n timer.stop();\n finallyEvent.trigger(null);\n });\n };\n const refetch = toRef(options.refetch);\n watch(\n [\n refetch,\n toRef(url)\n ],\n ([refetch2]) => refetch2 && execute(),\n { deep: true }\n );\n const shell = {\n isFinished: readonly(isFinished),\n isFetching: readonly(isFetching),\n statusCode,\n response,\n error,\n data,\n canAbort,\n aborted,\n abort,\n execute,\n onFetchResponse: responseEvent.on,\n onFetchError: errorEvent.on,\n onFetchFinally: finallyEvent.on,\n // method\n get: setMethod(\"GET\"),\n put: setMethod(\"PUT\"),\n post: setMethod(\"POST\"),\n delete: setMethod(\"DELETE\"),\n patch: setMethod(\"PATCH\"),\n head: setMethod(\"HEAD\"),\n options: setMethod(\"OPTIONS\"),\n // type\n json: setType(\"json\"),\n text: setType(\"text\"),\n blob: setType(\"blob\"),\n arrayBuffer: setType(\"arrayBuffer\"),\n formData: setType(\"formData\")\n };\n function setMethod(method) {\n return (payload, payloadType) => {\n if (!isFetching.value) {\n config.method = method;\n config.payload = payload;\n config.payloadType = payloadType;\n if (isRef(config.payload)) {\n watch(\n [\n refetch,\n toRef(config.payload)\n ],\n ([refetch2]) => refetch2 && execute(),\n { deep: true }\n );\n }\n return {\n ...shell,\n then(onFulfilled, onRejected) {\n return waitUntilFinished().then(onFulfilled, onRejected);\n }\n };\n }\n return void 0;\n };\n }\n function waitUntilFinished() {\n return new Promise((resolve, reject) => {\n until(isFinished).toBe(true).then(() => resolve(shell)).catch(reject);\n });\n }\n function setType(type) {\n return () => {\n if (!isFetching.value) {\n config.type = type;\n return {\n ...shell,\n then(onFulfilled, onRejected) {\n return waitUntilFinished().then(onFulfilled, onRejected);\n }\n };\n }\n return void 0;\n };\n }\n if (options.immediate)\n Promise.resolve().then(() => execute());\n return {\n ...shell,\n then(onFulfilled, onRejected) {\n return waitUntilFinished().then(onFulfilled, onRejected);\n }\n };\n}\nfunction joinPaths(start, end) {\n if (!start.endsWith(\"/\") && !end.startsWith(\"/\")) {\n return `${start}/${end}`;\n }\n if (start.endsWith(\"/\") && end.startsWith(\"/\")) {\n return `${start.slice(0, -1)}${end}`;\n }\n return `${start}${end}`;\n}\n\nconst DEFAULT_OPTIONS = {\n multiple: true,\n accept: \"*\",\n reset: false,\n directory: false\n};\nfunction prepareInitialFiles(files) {\n if (!files)\n return null;\n if (files instanceof FileList)\n return files;\n const dt = new DataTransfer();\n for (const file of files) {\n dt.items.add(file);\n }\n return dt.files;\n}\nfunction useFileDialog(options = {}) {\n const {\n document = defaultDocument\n } = options;\n const files = ref(prepareInitialFiles(options.initialFiles));\n const { on: onChange, trigger: changeTrigger } = createEventHook();\n const { on: onCancel, trigger: cancelTrigger } = createEventHook();\n let input;\n if (document) {\n input = document.createElement(\"input\");\n input.type = \"file\";\n input.onchange = (event) => {\n const result = event.target;\n files.value = result.files;\n changeTrigger(files.value);\n };\n input.oncancel = () => {\n cancelTrigger();\n };\n }\n const reset = () => {\n files.value = null;\n if (input && input.value) {\n input.value = \"\";\n changeTrigger(null);\n }\n };\n const open = (localOptions) => {\n if (!input)\n return;\n const _options = {\n ...DEFAULT_OPTIONS,\n ...options,\n ...localOptions\n };\n input.multiple = _options.multiple;\n input.accept = _options.accept;\n input.webkitdirectory = _options.directory;\n if (hasOwn(_options, \"capture\"))\n input.capture = _options.capture;\n if (_options.reset)\n reset();\n input.click();\n };\n return {\n files: readonly(files),\n open,\n reset,\n onCancel,\n onChange\n };\n}\n\nfunction useFileSystemAccess(options = {}) {\n const {\n window: _window = defaultWindow,\n dataType = \"Text\"\n } = options;\n const window = _window;\n const isSupported = useSupported(() => window && \"showSaveFilePicker\" in window && \"showOpenFilePicker\" in window);\n const fileHandle = shallowRef();\n const data = shallowRef();\n const file = shallowRef();\n const fileName = computed(() => {\n var _a, _b;\n return (_b = (_a = file.value) == null ? void 0 : _a.name) != null ? _b : \"\";\n });\n const fileMIME = computed(() => {\n var _a, _b;\n return (_b = (_a = file.value) == null ? void 0 : _a.type) != null ? _b : \"\";\n });\n const fileSize = computed(() => {\n var _a, _b;\n return (_b = (_a = file.value) == null ? void 0 : _a.size) != null ? _b : 0;\n });\n const fileLastModified = computed(() => {\n var _a, _b;\n return (_b = (_a = file.value) == null ? void 0 : _a.lastModified) != null ? _b : 0;\n });\n async function open(_options = {}) {\n if (!isSupported.value)\n return;\n const [handle] = await window.showOpenFilePicker({ ...toValue(options), ..._options });\n fileHandle.value = handle;\n await updateData();\n }\n async function create(_options = {}) {\n if (!isSupported.value)\n return;\n fileHandle.value = await window.showSaveFilePicker({ ...options, ..._options });\n data.value = void 0;\n await updateData();\n }\n async function save(_options = {}) {\n if (!isSupported.value)\n return;\n if (!fileHandle.value)\n return saveAs(_options);\n if (data.value) {\n const writableStream = await fileHandle.value.createWritable();\n await writableStream.write(data.value);\n await writableStream.close();\n }\n await updateFile();\n }\n async function saveAs(_options = {}) {\n if (!isSupported.value)\n return;\n fileHandle.value = await window.showSaveFilePicker({ ...options, ..._options });\n if (data.value) {\n const writableStream = await fileHandle.value.createWritable();\n await writableStream.write(data.value);\n await writableStream.close();\n }\n await updateFile();\n }\n async function updateFile() {\n var _a;\n file.value = await ((_a = fileHandle.value) == null ? void 0 : _a.getFile());\n }\n async function updateData() {\n var _a, _b;\n await updateFile();\n const type = toValue(dataType);\n if (type === \"Text\")\n data.value = await ((_a = file.value) == null ? void 0 : _a.text());\n else if (type === \"ArrayBuffer\")\n data.value = await ((_b = file.value) == null ? void 0 : _b.arrayBuffer());\n else if (type === \"Blob\")\n data.value = file.value;\n }\n watch(() => toValue(dataType), updateData);\n return {\n isSupported,\n data,\n file,\n fileName,\n fileMIME,\n fileSize,\n fileLastModified,\n open,\n create,\n save,\n saveAs,\n updateData\n };\n}\n\nfunction useFocus(target, options = {}) {\n const { initialValue = false, focusVisible = false, preventScroll = false } = options;\n const innerFocused = shallowRef(false);\n const targetElement = computed(() => unrefElement(target));\n const listenerOptions = { passive: true };\n useEventListener(targetElement, \"focus\", (event) => {\n var _a, _b;\n if (!focusVisible || ((_b = (_a = event.target).matches) == null ? void 0 : _b.call(_a, \":focus-visible\")))\n innerFocused.value = true;\n }, listenerOptions);\n useEventListener(targetElement, \"blur\", () => innerFocused.value = false, listenerOptions);\n const focused = computed({\n get: () => innerFocused.value,\n set(value) {\n var _a, _b;\n if (!value && innerFocused.value)\n (_a = targetElement.value) == null ? void 0 : _a.blur();\n else if (value && !innerFocused.value)\n (_b = targetElement.value) == null ? void 0 : _b.focus({ preventScroll });\n }\n });\n watch(\n targetElement,\n () => {\n focused.value = initialValue;\n },\n { immediate: true, flush: \"post\" }\n );\n return { focused };\n}\n\nconst EVENT_FOCUS_IN = \"focusin\";\nconst EVENT_FOCUS_OUT = \"focusout\";\nconst PSEUDO_CLASS_FOCUS_WITHIN = \":focus-within\";\nfunction useFocusWithin(target, options = {}) {\n const { window = defaultWindow } = options;\n const targetElement = computed(() => unrefElement(target));\n const _focused = shallowRef(false);\n const focused = computed(() => _focused.value);\n const activeElement = useActiveElement(options);\n if (!window || !activeElement.value) {\n return { focused };\n }\n const listenerOptions = { passive: true };\n useEventListener(targetElement, EVENT_FOCUS_IN, () => _focused.value = true, listenerOptions);\n useEventListener(targetElement, EVENT_FOCUS_OUT, () => {\n var _a, _b, _c;\n return _focused.value = (_c = (_b = (_a = targetElement.value) == null ? void 0 : _a.matches) == null ? void 0 : _b.call(_a, PSEUDO_CLASS_FOCUS_WITHIN)) != null ? _c : false;\n }, listenerOptions);\n return { focused };\n}\n\nfunction useFps(options) {\n var _a;\n const fps = shallowRef(0);\n if (typeof performance === \"undefined\")\n return fps;\n const every = (_a = options == null ? void 0 : options.every) != null ? _a : 10;\n let last = performance.now();\n let ticks = 0;\n useRafFn(() => {\n ticks += 1;\n if (ticks >= every) {\n const now = performance.now();\n const diff = now - last;\n fps.value = Math.round(1e3 / (diff / ticks));\n last = now;\n ticks = 0;\n }\n });\n return fps;\n}\n\nconst eventHandlers = [\n \"fullscreenchange\",\n \"webkitfullscreenchange\",\n \"webkitendfullscreen\",\n \"mozfullscreenchange\",\n \"MSFullscreenChange\"\n];\nfunction useFullscreen(target, options = {}) {\n const {\n document = defaultDocument,\n autoExit = false\n } = options;\n const targetRef = computed(() => {\n var _a;\n return (_a = unrefElement(target)) != null ? _a : document == null ? void 0 : document.documentElement;\n });\n const isFullscreen = shallowRef(false);\n const requestMethod = computed(() => {\n return [\n \"requestFullscreen\",\n \"webkitRequestFullscreen\",\n \"webkitEnterFullscreen\",\n \"webkitEnterFullScreen\",\n \"webkitRequestFullScreen\",\n \"mozRequestFullScreen\",\n \"msRequestFullscreen\"\n ].find((m) => document && m in document || targetRef.value && m in targetRef.value);\n });\n const exitMethod = computed(() => {\n return [\n \"exitFullscreen\",\n \"webkitExitFullscreen\",\n \"webkitExitFullScreen\",\n \"webkitCancelFullScreen\",\n \"mozCancelFullScreen\",\n \"msExitFullscreen\"\n ].find((m) => document && m in document || targetRef.value && m in targetRef.value);\n });\n const fullscreenEnabled = computed(() => {\n return [\n \"fullScreen\",\n \"webkitIsFullScreen\",\n \"webkitDisplayingFullscreen\",\n \"mozFullScreen\",\n \"msFullscreenElement\"\n ].find((m) => document && m in document || targetRef.value && m in targetRef.value);\n });\n const fullscreenElementMethod = [\n \"fullscreenElement\",\n \"webkitFullscreenElement\",\n \"mozFullScreenElement\",\n \"msFullscreenElement\"\n ].find((m) => document && m in document);\n const isSupported = useSupported(() => targetRef.value && document && requestMethod.value !== void 0 && exitMethod.value !== void 0 && fullscreenEnabled.value !== void 0);\n const isCurrentElementFullScreen = () => {\n if (fullscreenElementMethod)\n return (document == null ? void 0 : document[fullscreenElementMethod]) === targetRef.value;\n return false;\n };\n const isElementFullScreen = () => {\n if (fullscreenEnabled.value) {\n if (document && document[fullscreenEnabled.value] != null) {\n return document[fullscreenEnabled.value];\n } else {\n const target2 = targetRef.value;\n if ((target2 == null ? void 0 : target2[fullscreenEnabled.value]) != null) {\n return Boolean(target2[fullscreenEnabled.value]);\n }\n }\n }\n return false;\n };\n async function exit() {\n if (!isSupported.value || !isFullscreen.value)\n return;\n if (exitMethod.value) {\n if ((document == null ? void 0 : document[exitMethod.value]) != null) {\n await document[exitMethod.value]();\n } else {\n const target2 = targetRef.value;\n if ((target2 == null ? void 0 : target2[exitMethod.value]) != null)\n await target2[exitMethod.value]();\n }\n }\n isFullscreen.value = false;\n }\n async function enter() {\n if (!isSupported.value || isFullscreen.value)\n return;\n if (isElementFullScreen())\n await exit();\n const target2 = targetRef.value;\n if (requestMethod.value && (target2 == null ? void 0 : target2[requestMethod.value]) != null) {\n await target2[requestMethod.value]();\n isFullscreen.value = true;\n }\n }\n async function toggle() {\n await (isFullscreen.value ? exit() : enter());\n }\n const handlerCallback = () => {\n const isElementFullScreenValue = isElementFullScreen();\n if (!isElementFullScreenValue || isElementFullScreenValue && isCurrentElementFullScreen())\n isFullscreen.value = isElementFullScreenValue;\n };\n const listenerOptions = { capture: false, passive: true };\n useEventListener(document, eventHandlers, handlerCallback, listenerOptions);\n useEventListener(() => unrefElement(targetRef), eventHandlers, handlerCallback, listenerOptions);\n if (autoExit)\n tryOnScopeDispose(exit);\n return {\n isSupported,\n isFullscreen,\n enter,\n exit,\n toggle\n };\n}\n\nfunction mapGamepadToXbox360Controller(gamepad) {\n return computed(() => {\n if (gamepad.value) {\n return {\n buttons: {\n a: gamepad.value.buttons[0],\n b: gamepad.value.buttons[1],\n x: gamepad.value.buttons[2],\n y: gamepad.value.buttons[3]\n },\n bumper: {\n left: gamepad.value.buttons[4],\n right: gamepad.value.buttons[5]\n },\n triggers: {\n left: gamepad.value.buttons[6],\n right: gamepad.value.buttons[7]\n },\n stick: {\n left: {\n horizontal: gamepad.value.axes[0],\n vertical: gamepad.value.axes[1],\n button: gamepad.value.buttons[10]\n },\n right: {\n horizontal: gamepad.value.axes[2],\n vertical: gamepad.value.axes[3],\n button: gamepad.value.buttons[11]\n }\n },\n dpad: {\n up: gamepad.value.buttons[12],\n down: gamepad.value.buttons[13],\n left: gamepad.value.buttons[14],\n right: gamepad.value.buttons[15]\n },\n back: gamepad.value.buttons[8],\n start: gamepad.value.buttons[9]\n };\n }\n return null;\n });\n}\nfunction useGamepad(options = {}) {\n const {\n navigator = defaultNavigator\n } = options;\n const isSupported = useSupported(() => navigator && \"getGamepads\" in navigator);\n const gamepads = ref([]);\n const onConnectedHook = createEventHook();\n const onDisconnectedHook = createEventHook();\n const stateFromGamepad = (gamepad) => {\n const hapticActuators = [];\n const vibrationActuator = \"vibrationActuator\" in gamepad ? gamepad.vibrationActuator : null;\n if (vibrationActuator)\n hapticActuators.push(vibrationActuator);\n if (gamepad.hapticActuators)\n hapticActuators.push(...gamepad.hapticActuators);\n return {\n id: gamepad.id,\n index: gamepad.index,\n connected: gamepad.connected,\n mapping: gamepad.mapping,\n timestamp: gamepad.timestamp,\n vibrationActuator: gamepad.vibrationActuator,\n hapticActuators,\n axes: gamepad.axes.map((axes) => axes),\n buttons: gamepad.buttons.map((button) => ({ pressed: button.pressed, touched: button.touched, value: button.value }))\n };\n };\n const updateGamepadState = () => {\n const _gamepads = (navigator == null ? void 0 : navigator.getGamepads()) || [];\n for (const gamepad of _gamepads) {\n if (gamepad && gamepads.value[gamepad.index])\n gamepads.value[gamepad.index] = stateFromGamepad(gamepad);\n }\n };\n const { isActive, pause, resume } = useRafFn(updateGamepadState);\n const onGamepadConnected = (gamepad) => {\n if (!gamepads.value.some(({ index }) => index === gamepad.index)) {\n gamepads.value.push(stateFromGamepad(gamepad));\n onConnectedHook.trigger(gamepad.index);\n }\n resume();\n };\n const onGamepadDisconnected = (gamepad) => {\n gamepads.value = gamepads.value.filter((x) => x.index !== gamepad.index);\n onDisconnectedHook.trigger(gamepad.index);\n };\n const listenerOptions = { passive: true };\n useEventListener(\"gamepadconnected\", (e) => onGamepadConnected(e.gamepad), listenerOptions);\n useEventListener(\"gamepaddisconnected\", (e) => onGamepadDisconnected(e.gamepad), listenerOptions);\n tryOnMounted(() => {\n const _gamepads = (navigator == null ? void 0 : navigator.getGamepads()) || [];\n for (const gamepad of _gamepads) {\n if (gamepad && gamepads.value[gamepad.index])\n onGamepadConnected(gamepad);\n }\n });\n pause();\n return {\n isSupported,\n onConnected: onConnectedHook.on,\n onDisconnected: onDisconnectedHook.on,\n gamepads,\n pause,\n resume,\n isActive\n };\n}\n\nfunction useGeolocation(options = {}) {\n const {\n enableHighAccuracy = true,\n maximumAge = 3e4,\n timeout = 27e3,\n navigator = defaultNavigator,\n immediate = true\n } = options;\n const isSupported = useSupported(() => navigator && \"geolocation\" in navigator);\n const locatedAt = shallowRef(null);\n const error = shallowRef(null);\n const coords = ref({\n accuracy: 0,\n latitude: Number.POSITIVE_INFINITY,\n longitude: Number.POSITIVE_INFINITY,\n altitude: null,\n altitudeAccuracy: null,\n heading: null,\n speed: null\n });\n function updatePosition(position) {\n locatedAt.value = position.timestamp;\n coords.value = position.coords;\n error.value = null;\n }\n let watcher;\n function resume() {\n if (isSupported.value) {\n watcher = navigator.geolocation.watchPosition(\n updatePosition,\n (err) => error.value = err,\n {\n enableHighAccuracy,\n maximumAge,\n timeout\n }\n );\n }\n }\n if (immediate)\n resume();\n function pause() {\n if (watcher && navigator)\n navigator.geolocation.clearWatch(watcher);\n }\n tryOnScopeDispose(() => {\n pause();\n });\n return {\n isSupported,\n coords,\n locatedAt,\n error,\n resume,\n pause\n };\n}\n\nconst defaultEvents$1 = [\"mousemove\", \"mousedown\", \"resize\", \"keydown\", \"touchstart\", \"wheel\"];\nconst oneMinute = 6e4;\nfunction useIdle(timeout = oneMinute, options = {}) {\n const {\n initialState = false,\n listenForVisibilityChange = true,\n events = defaultEvents$1,\n window = defaultWindow,\n eventFilter = throttleFilter(50)\n } = options;\n const idle = shallowRef(initialState);\n const lastActive = shallowRef(timestamp());\n let timer;\n const reset = () => {\n idle.value = false;\n clearTimeout(timer);\n timer = setTimeout(() => idle.value = true, timeout);\n };\n const onEvent = createFilterWrapper(\n eventFilter,\n () => {\n lastActive.value = timestamp();\n reset();\n }\n );\n if (window) {\n const document = window.document;\n const listenerOptions = { passive: true };\n for (const event of events)\n useEventListener(window, event, onEvent, listenerOptions);\n if (listenForVisibilityChange) {\n useEventListener(document, \"visibilitychange\", () => {\n if (!document.hidden)\n onEvent();\n }, listenerOptions);\n }\n reset();\n }\n return {\n idle,\n lastActive,\n reset\n };\n}\n\nasync function loadImage(options) {\n return new Promise((resolve, reject) => {\n const img = new Image();\n const { src, srcset, sizes, class: clazz, loading, crossorigin, referrerPolicy, width, height, decoding, fetchPriority, ismap, usemap } = options;\n img.src = src;\n if (srcset != null)\n img.srcset = srcset;\n if (sizes != null)\n img.sizes = sizes;\n if (clazz != null)\n img.className = clazz;\n if (loading != null)\n img.loading = loading;\n if (crossorigin != null)\n img.crossOrigin = crossorigin;\n if (referrerPolicy != null)\n img.referrerPolicy = referrerPolicy;\n if (width != null)\n img.width = width;\n if (height != null)\n img.height = height;\n if (decoding != null)\n img.decoding = decoding;\n if (fetchPriority != null)\n img.fetchPriority = fetchPriority;\n if (ismap != null)\n img.isMap = ismap;\n if (usemap != null)\n img.useMap = usemap;\n img.onload = () => resolve(img);\n img.onerror = reject;\n });\n}\nfunction useImage(options, asyncStateOptions = {}) {\n const state = useAsyncState(\n () => loadImage(toValue(options)),\n void 0,\n {\n resetOnExecute: true,\n ...asyncStateOptions\n }\n );\n watch(\n () => toValue(options),\n () => state.execute(asyncStateOptions.delay),\n { deep: true }\n );\n return state;\n}\n\nfunction resolveElement(el) {\n if (typeof Window !== \"undefined\" && el instanceof Window)\n return el.document.documentElement;\n if (typeof Document !== \"undefined\" && el instanceof Document)\n return el.documentElement;\n return el;\n}\n\nconst ARRIVED_STATE_THRESHOLD_PIXELS = 1;\nfunction useScroll(element, options = {}) {\n const {\n throttle = 0,\n idle = 200,\n onStop = noop,\n onScroll = noop,\n offset = {\n left: 0,\n right: 0,\n top: 0,\n bottom: 0\n },\n eventListenerOptions = {\n capture: false,\n passive: true\n },\n behavior = \"auto\",\n window = defaultWindow,\n onError = (e) => {\n console.error(e);\n }\n } = options;\n const internalX = shallowRef(0);\n const internalY = shallowRef(0);\n const x = computed({\n get() {\n return internalX.value;\n },\n set(x2) {\n scrollTo(x2, void 0);\n }\n });\n const y = computed({\n get() {\n return internalY.value;\n },\n set(y2) {\n scrollTo(void 0, y2);\n }\n });\n function scrollTo(_x, _y) {\n var _a, _b, _c, _d;\n if (!window)\n return;\n const _element = toValue(element);\n if (!_element)\n return;\n (_c = _element instanceof Document ? window.document.body : _element) == null ? void 0 : _c.scrollTo({\n top: (_a = toValue(_y)) != null ? _a : y.value,\n left: (_b = toValue(_x)) != null ? _b : x.value,\n behavior: toValue(behavior)\n });\n const scrollContainer = ((_d = _element == null ? void 0 : _element.document) == null ? void 0 : _d.documentElement) || (_element == null ? void 0 : _element.documentElement) || _element;\n if (x != null)\n internalX.value = scrollContainer.scrollLeft;\n if (y != null)\n internalY.value = scrollContainer.scrollTop;\n }\n const isScrolling = shallowRef(false);\n const arrivedState = reactive({\n left: true,\n right: false,\n top: true,\n bottom: false\n });\n const directions = reactive({\n left: false,\n right: false,\n top: false,\n bottom: false\n });\n const onScrollEnd = (e) => {\n if (!isScrolling.value)\n return;\n isScrolling.value = false;\n directions.left = false;\n directions.right = false;\n directions.top = false;\n directions.bottom = false;\n onStop(e);\n };\n const onScrollEndDebounced = useDebounceFn(onScrollEnd, throttle + idle);\n const setArrivedState = (target) => {\n var _a;\n if (!window)\n return;\n const el = ((_a = target == null ? void 0 : target.document) == null ? void 0 : _a.documentElement) || (target == null ? void 0 : target.documentElement) || unrefElement(target);\n const { display, flexDirection, direction } = getComputedStyle(el);\n const directionMultipler = direction === \"rtl\" ? -1 : 1;\n const scrollLeft = el.scrollLeft;\n directions.left = scrollLeft < internalX.value;\n directions.right = scrollLeft > internalX.value;\n const left = Math.abs(scrollLeft * directionMultipler) <= (offset.left || 0);\n const right = Math.abs(scrollLeft * directionMultipler) + el.clientWidth >= el.scrollWidth - (offset.right || 0) - ARRIVED_STATE_THRESHOLD_PIXELS;\n if (display === \"flex\" && flexDirection === \"row-reverse\") {\n arrivedState.left = right;\n arrivedState.right = left;\n } else {\n arrivedState.left = left;\n arrivedState.right = right;\n }\n internalX.value = scrollLeft;\n let scrollTop = el.scrollTop;\n if (target === window.document && !scrollTop)\n scrollTop = window.document.body.scrollTop;\n directions.top = scrollTop < internalY.value;\n directions.bottom = scrollTop > internalY.value;\n const top = Math.abs(scrollTop) <= (offset.top || 0);\n const bottom = Math.abs(scrollTop) + el.clientHeight >= el.scrollHeight - (offset.bottom || 0) - ARRIVED_STATE_THRESHOLD_PIXELS;\n if (display === \"flex\" && flexDirection === \"column-reverse\") {\n arrivedState.top = bottom;\n arrivedState.bottom = top;\n } else {\n arrivedState.top = top;\n arrivedState.bottom = bottom;\n }\n internalY.value = scrollTop;\n };\n const onScrollHandler = (e) => {\n var _a;\n if (!window)\n return;\n const eventTarget = (_a = e.target.documentElement) != null ? _a : e.target;\n setArrivedState(eventTarget);\n isScrolling.value = true;\n onScrollEndDebounced(e);\n onScroll(e);\n };\n useEventListener(\n element,\n \"scroll\",\n throttle ? useThrottleFn(onScrollHandler, throttle, true, false) : onScrollHandler,\n eventListenerOptions\n );\n tryOnMounted(() => {\n try {\n const _element = toValue(element);\n if (!_element)\n return;\n setArrivedState(_element);\n } catch (e) {\n onError(e);\n }\n });\n useEventListener(\n element,\n \"scrollend\",\n onScrollEnd,\n eventListenerOptions\n );\n return {\n x,\n y,\n isScrolling,\n arrivedState,\n directions,\n measure() {\n const _element = toValue(element);\n if (window && _element)\n setArrivedState(_element);\n }\n };\n}\n\nfunction useInfiniteScroll(element, onLoadMore, options = {}) {\n var _a;\n const {\n direction = \"bottom\",\n interval = 100,\n canLoadMore = () => true\n } = options;\n const state = reactive(useScroll(\n element,\n {\n ...options,\n offset: {\n [direction]: (_a = options.distance) != null ? _a : 0,\n ...options.offset\n }\n }\n ));\n const promise = ref();\n const isLoading = computed(() => !!promise.value);\n const observedElement = computed(() => {\n return resolveElement(toValue(element));\n });\n const isElementVisible = useElementVisibility(observedElement);\n function checkAndLoad() {\n state.measure();\n if (!observedElement.value || !isElementVisible.value || !canLoadMore(observedElement.value))\n return;\n const { scrollHeight, clientHeight, scrollWidth, clientWidth } = observedElement.value;\n const isNarrower = direction === \"bottom\" || direction === \"top\" ? scrollHeight <= clientHeight : scrollWidth <= clientWidth;\n if (state.arrivedState[direction] || isNarrower) {\n if (!promise.value) {\n promise.value = Promise.all([\n onLoadMore(state),\n new Promise((resolve) => setTimeout(resolve, interval))\n ]).finally(() => {\n promise.value = null;\n nextTick(() => checkAndLoad());\n });\n }\n }\n }\n const stop = watch(\n () => [state.arrivedState[direction], isElementVisible.value],\n checkAndLoad,\n { immediate: true }\n );\n tryOnUnmounted(stop);\n return {\n isLoading,\n reset() {\n nextTick(() => checkAndLoad());\n }\n };\n}\n\nconst defaultEvents = [\"mousedown\", \"mouseup\", \"keydown\", \"keyup\"];\nfunction useKeyModifier(modifier, options = {}) {\n const {\n events = defaultEvents,\n document = defaultDocument,\n initial = null\n } = options;\n const state = shallowRef(initial);\n if (document) {\n events.forEach((listenerEvent) => {\n useEventListener(document, listenerEvent, (evt) => {\n if (typeof evt.getModifierState === \"function\")\n state.value = evt.getModifierState(modifier);\n }, { passive: true });\n });\n }\n return state;\n}\n\nfunction useLocalStorage(key, initialValue, options = {}) {\n const { window = defaultWindow } = options;\n return useStorage(key, initialValue, window == null ? void 0 : window.localStorage, options);\n}\n\nconst DefaultMagicKeysAliasMap = {\n ctrl: \"control\",\n command: \"meta\",\n cmd: \"meta\",\n option: \"alt\",\n up: \"arrowup\",\n down: \"arrowdown\",\n left: \"arrowleft\",\n right: \"arrowright\"\n};\n\nfunction useMagicKeys(options = {}) {\n const {\n reactive: useReactive = false,\n target = defaultWindow,\n aliasMap = DefaultMagicKeysAliasMap,\n passive = true,\n onEventFired = noop\n } = options;\n const current = reactive(/* @__PURE__ */ new Set());\n const obj = {\n toJSON() {\n return {};\n },\n current\n };\n const refs = useReactive ? reactive(obj) : obj;\n const metaDeps = /* @__PURE__ */ new Set();\n const usedKeys = /* @__PURE__ */ new Set();\n function setRefs(key, value) {\n if (key in refs) {\n if (useReactive)\n refs[key] = value;\n else\n refs[key].value = value;\n }\n }\n function reset() {\n current.clear();\n for (const key of usedKeys)\n setRefs(key, false);\n }\n function updateRefs(e, value) {\n var _a, _b;\n const key = (_a = e.key) == null ? void 0 : _a.toLowerCase();\n const code = (_b = e.code) == null ? void 0 : _b.toLowerCase();\n const values = [code, key].filter(Boolean);\n if (key) {\n if (value)\n current.add(key);\n else\n current.delete(key);\n }\n for (const key2 of values) {\n usedKeys.add(key2);\n setRefs(key2, value);\n }\n if (key === \"meta\" && !value) {\n metaDeps.forEach((key2) => {\n current.delete(key2);\n setRefs(key2, false);\n });\n metaDeps.clear();\n } else if (typeof e.getModifierState === \"function\" && e.getModifierState(\"Meta\") && value) {\n [...current, ...values].forEach((key2) => metaDeps.add(key2));\n }\n }\n useEventListener(target, \"keydown\", (e) => {\n updateRefs(e, true);\n return onEventFired(e);\n }, { passive });\n useEventListener(target, \"keyup\", (e) => {\n updateRefs(e, false);\n return onEventFired(e);\n }, { passive });\n useEventListener(\"blur\", reset, { passive });\n useEventListener(\"focus\", reset, { passive });\n const proxy = new Proxy(\n refs,\n {\n get(target2, prop, rec) {\n if (typeof prop !== \"string\")\n return Reflect.get(target2, prop, rec);\n prop = prop.toLowerCase();\n if (prop in aliasMap)\n prop = aliasMap[prop];\n if (!(prop in refs)) {\n if (/[+_-]/.test(prop)) {\n const keys = prop.split(/[+_-]/g).map((i) => i.trim());\n refs[prop] = computed(() => keys.map((key) => toValue(proxy[key])).every(Boolean));\n } else {\n refs[prop] = shallowRef(false);\n }\n }\n const r = Reflect.get(target2, prop, rec);\n return useReactive ? toValue(r) : r;\n }\n }\n );\n return proxy;\n}\n\nfunction usingElRef(source, cb) {\n if (toValue(source))\n cb(toValue(source));\n}\nfunction timeRangeToArray(timeRanges) {\n let ranges = [];\n for (let i = 0; i < timeRanges.length; ++i)\n ranges = [...ranges, [timeRanges.start(i), timeRanges.end(i)]];\n return ranges;\n}\nfunction tracksToArray(tracks) {\n return Array.from(tracks).map(({ label, kind, language, mode, activeCues, cues, inBandMetadataTrackDispatchType }, id) => ({ id, label, kind, language, mode, activeCues, cues, inBandMetadataTrackDispatchType }));\n}\nconst defaultOptions = {\n src: \"\",\n tracks: []\n};\nfunction useMediaControls(target, options = {}) {\n target = toRef(target);\n options = {\n ...defaultOptions,\n ...options\n };\n const {\n document = defaultDocument\n } = options;\n const listenerOptions = { passive: true };\n const currentTime = shallowRef(0);\n const duration = shallowRef(0);\n const seeking = shallowRef(false);\n const volume = shallowRef(1);\n const waiting = shallowRef(false);\n const ended = shallowRef(false);\n const playing = shallowRef(false);\n const rate = shallowRef(1);\n const stalled = shallowRef(false);\n const buffered = ref([]);\n const tracks = ref([]);\n const selectedTrack = shallowRef(-1);\n const isPictureInPicture = shallowRef(false);\n const muted = shallowRef(false);\n const supportsPictureInPicture = document && \"pictureInPictureEnabled\" in document;\n const sourceErrorEvent = createEventHook();\n const playbackErrorEvent = createEventHook();\n const disableTrack = (track) => {\n usingElRef(target, (el) => {\n if (track) {\n const id = typeof track === \"number\" ? track : track.id;\n el.textTracks[id].mode = \"disabled\";\n } else {\n for (let i = 0; i < el.textTracks.length; ++i)\n el.textTracks[i].mode = \"disabled\";\n }\n selectedTrack.value = -1;\n });\n };\n const enableTrack = (track, disableTracks = true) => {\n usingElRef(target, (el) => {\n const id = typeof track === \"number\" ? track : track.id;\n if (disableTracks)\n disableTrack();\n el.textTracks[id].mode = \"showing\";\n selectedTrack.value = id;\n });\n };\n const togglePictureInPicture = () => {\n return new Promise((resolve, reject) => {\n usingElRef(target, async (el) => {\n if (supportsPictureInPicture) {\n if (!isPictureInPicture.value) {\n el.requestPictureInPicture().then(resolve).catch(reject);\n } else {\n document.exitPictureInPicture().then(resolve).catch(reject);\n }\n }\n });\n });\n };\n watchEffect(() => {\n if (!document)\n return;\n const el = toValue(target);\n if (!el)\n return;\n const src = toValue(options.src);\n let sources = [];\n if (!src)\n return;\n if (typeof src === \"string\")\n sources = [{ src }];\n else if (Array.isArray(src))\n sources = src;\n else if (isObject(src))\n sources = [src];\n el.querySelectorAll(\"source\").forEach((e) => {\n e.remove();\n });\n sources.forEach(({ src: src2, type, media }) => {\n const source = document.createElement(\"source\");\n source.setAttribute(\"src\", src2);\n source.setAttribute(\"type\", type || \"\");\n source.setAttribute(\"media\", media || \"\");\n useEventListener(source, \"error\", sourceErrorEvent.trigger, listenerOptions);\n el.appendChild(source);\n });\n el.load();\n });\n watch([target, volume], () => {\n const el = toValue(target);\n if (!el)\n return;\n el.volume = volume.value;\n });\n watch([target, muted], () => {\n const el = toValue(target);\n if (!el)\n return;\n el.muted = muted.value;\n });\n watch([target, rate], () => {\n const el = toValue(target);\n if (!el)\n return;\n el.playbackRate = rate.value;\n });\n watchEffect(() => {\n if (!document)\n return;\n const textTracks = toValue(options.tracks);\n const el = toValue(target);\n if (!textTracks || !textTracks.length || !el)\n return;\n el.querySelectorAll(\"track\").forEach((e) => e.remove());\n textTracks.forEach(({ default: isDefault, kind, label, src, srcLang }, i) => {\n const track = document.createElement(\"track\");\n track.default = isDefault || false;\n track.kind = kind;\n track.label = label;\n track.src = src;\n track.srclang = srcLang;\n if (track.default)\n selectedTrack.value = i;\n el.appendChild(track);\n });\n });\n const { ignoreUpdates: ignoreCurrentTimeUpdates } = watchIgnorable(currentTime, (time) => {\n const el = toValue(target);\n if (!el)\n return;\n el.currentTime = time;\n });\n const { ignoreUpdates: ignorePlayingUpdates } = watchIgnorable(playing, (isPlaying) => {\n const el = toValue(target);\n if (!el)\n return;\n if (isPlaying) {\n el.play().catch((e) => {\n playbackErrorEvent.trigger(e);\n throw e;\n });\n } else {\n el.pause();\n }\n });\n useEventListener(\n target,\n \"timeupdate\",\n () => ignoreCurrentTimeUpdates(() => currentTime.value = toValue(target).currentTime),\n listenerOptions\n );\n useEventListener(\n target,\n \"durationchange\",\n () => duration.value = toValue(target).duration,\n listenerOptions\n );\n useEventListener(\n target,\n \"progress\",\n () => buffered.value = timeRangeToArray(toValue(target).buffered),\n listenerOptions\n );\n useEventListener(\n target,\n \"seeking\",\n () => seeking.value = true,\n listenerOptions\n );\n useEventListener(\n target,\n \"seeked\",\n () => seeking.value = false,\n listenerOptions\n );\n useEventListener(\n target,\n [\"waiting\", \"loadstart\"],\n () => {\n waiting.value = true;\n ignorePlayingUpdates(() => playing.value = false);\n },\n listenerOptions\n );\n useEventListener(\n target,\n \"loadeddata\",\n () => waiting.value = false,\n listenerOptions\n );\n useEventListener(\n target,\n \"playing\",\n () => {\n waiting.value = false;\n ended.value = false;\n ignorePlayingUpdates(() => playing.value = true);\n },\n listenerOptions\n );\n useEventListener(\n target,\n \"ratechange\",\n () => rate.value = toValue(target).playbackRate,\n listenerOptions\n );\n useEventListener(\n target,\n \"stalled\",\n () => stalled.value = true,\n listenerOptions\n );\n useEventListener(\n target,\n \"ended\",\n () => ended.value = true,\n listenerOptions\n );\n useEventListener(\n target,\n \"pause\",\n () => ignorePlayingUpdates(() => playing.value = false),\n listenerOptions\n );\n useEventListener(\n target,\n \"play\",\n () => ignorePlayingUpdates(() => playing.value = true),\n listenerOptions\n );\n useEventListener(\n target,\n \"enterpictureinpicture\",\n () => isPictureInPicture.value = true,\n listenerOptions\n );\n useEventListener(\n target,\n \"leavepictureinpicture\",\n () => isPictureInPicture.value = false,\n listenerOptions\n );\n useEventListener(\n target,\n \"volumechange\",\n () => {\n const el = toValue(target);\n if (!el)\n return;\n volume.value = el.volume;\n muted.value = el.muted;\n },\n listenerOptions\n );\n const listeners = [];\n const stop = watch([target], () => {\n const el = toValue(target);\n if (!el)\n return;\n stop();\n listeners[0] = useEventListener(el.textTracks, \"addtrack\", () => tracks.value = tracksToArray(el.textTracks), listenerOptions);\n listeners[1] = useEventListener(el.textTracks, \"removetrack\", () => tracks.value = tracksToArray(el.textTracks), listenerOptions);\n listeners[2] = useEventListener(el.textTracks, \"change\", () => tracks.value = tracksToArray(el.textTracks), listenerOptions);\n });\n tryOnScopeDispose(() => listeners.forEach((listener) => listener()));\n return {\n currentTime,\n duration,\n waiting,\n seeking,\n ended,\n stalled,\n buffered,\n playing,\n rate,\n // Volume\n volume,\n muted,\n // Tracks\n tracks,\n selectedTrack,\n enableTrack,\n disableTrack,\n // Picture in Picture\n supportsPictureInPicture,\n togglePictureInPicture,\n isPictureInPicture,\n // Events\n onSourceError: sourceErrorEvent.on,\n onPlaybackError: playbackErrorEvent.on\n };\n}\n\nfunction useMemoize(resolver, options) {\n const initCache = () => {\n if (options == null ? void 0 : options.cache)\n return shallowReactive(options.cache);\n return shallowReactive(/* @__PURE__ */ new Map());\n };\n const cache = initCache();\n const generateKey = (...args) => (options == null ? void 0 : options.getKey) ? options.getKey(...args) : JSON.stringify(args);\n const _loadData = (key, ...args) => {\n cache.set(key, resolver(...args));\n return cache.get(key);\n };\n const loadData = (...args) => _loadData(generateKey(...args), ...args);\n const deleteData = (...args) => {\n cache.delete(generateKey(...args));\n };\n const clearData = () => {\n cache.clear();\n };\n const memoized = (...args) => {\n const key = generateKey(...args);\n if (cache.has(key))\n return cache.get(key);\n return _loadData(key, ...args);\n };\n memoized.load = loadData;\n memoized.delete = deleteData;\n memoized.clear = clearData;\n memoized.generateKey = generateKey;\n memoized.cache = cache;\n return memoized;\n}\n\nfunction useMemory(options = {}) {\n const memory = ref();\n const isSupported = useSupported(() => typeof performance !== \"undefined\" && \"memory\" in performance);\n if (isSupported.value) {\n const { interval = 1e3 } = options;\n useIntervalFn(() => {\n memory.value = performance.memory;\n }, interval, { immediate: options.immediate, immediateCallback: options.immediateCallback });\n }\n return { isSupported, memory };\n}\n\nconst UseMouseBuiltinExtractors = {\n page: (event) => [event.pageX, event.pageY],\n client: (event) => [event.clientX, event.clientY],\n screen: (event) => [event.screenX, event.screenY],\n movement: (event) => event instanceof MouseEvent ? [event.movementX, event.movementY] : null\n};\nfunction useMouse(options = {}) {\n const {\n type = \"page\",\n touch = true,\n resetOnTouchEnds = false,\n initialValue = { x: 0, y: 0 },\n window = defaultWindow,\n target = window,\n scroll = true,\n eventFilter\n } = options;\n let _prevMouseEvent = null;\n let _prevScrollX = 0;\n let _prevScrollY = 0;\n const x = shallowRef(initialValue.x);\n const y = shallowRef(initialValue.y);\n const sourceType = shallowRef(null);\n const extractor = typeof type === \"function\" ? type : UseMouseBuiltinExtractors[type];\n const mouseHandler = (event) => {\n const result = extractor(event);\n _prevMouseEvent = event;\n if (result) {\n [x.value, y.value] = result;\n sourceType.value = \"mouse\";\n }\n if (window) {\n _prevScrollX = window.scrollX;\n _prevScrollY = window.scrollY;\n }\n };\n const touchHandler = (event) => {\n if (event.touches.length > 0) {\n const result = extractor(event.touches[0]);\n if (result) {\n [x.value, y.value] = result;\n sourceType.value = \"touch\";\n }\n }\n };\n const scrollHandler = () => {\n if (!_prevMouseEvent || !window)\n return;\n const pos = extractor(_prevMouseEvent);\n if (_prevMouseEvent instanceof MouseEvent && pos) {\n x.value = pos[0] + window.scrollX - _prevScrollX;\n y.value = pos[1] + window.scrollY - _prevScrollY;\n }\n };\n const reset = () => {\n x.value = initialValue.x;\n y.value = initialValue.y;\n };\n const mouseHandlerWrapper = eventFilter ? (event) => eventFilter(() => mouseHandler(event), {}) : (event) => mouseHandler(event);\n const touchHandlerWrapper = eventFilter ? (event) => eventFilter(() => touchHandler(event), {}) : (event) => touchHandler(event);\n const scrollHandlerWrapper = eventFilter ? () => eventFilter(() => scrollHandler(), {}) : () => scrollHandler();\n if (target) {\n const listenerOptions = { passive: true };\n useEventListener(target, [\"mousemove\", \"dragover\"], mouseHandlerWrapper, listenerOptions);\n if (touch && type !== \"movement\") {\n useEventListener(target, [\"touchstart\", \"touchmove\"], touchHandlerWrapper, listenerOptions);\n if (resetOnTouchEnds)\n useEventListener(target, \"touchend\", reset, listenerOptions);\n }\n if (scroll && type === \"page\")\n useEventListener(window, \"scroll\", scrollHandlerWrapper, listenerOptions);\n }\n return {\n x,\n y,\n sourceType\n };\n}\n\nfunction useMouseInElement(target, options = {}) {\n const {\n handleOutside = true,\n window = defaultWindow\n } = options;\n const type = options.type || \"page\";\n const { x, y, sourceType } = useMouse(options);\n const targetRef = shallowRef(target != null ? target : window == null ? void 0 : window.document.body);\n const elementX = shallowRef(0);\n const elementY = shallowRef(0);\n const elementPositionX = shallowRef(0);\n const elementPositionY = shallowRef(0);\n const elementHeight = shallowRef(0);\n const elementWidth = shallowRef(0);\n const isOutside = shallowRef(true);\n let stop = () => {\n };\n if (window) {\n stop = watch(\n [targetRef, x, y],\n () => {\n const el = unrefElement(targetRef);\n if (!el || !(el instanceof Element))\n return;\n const {\n left,\n top,\n width,\n height\n } = el.getBoundingClientRect();\n elementPositionX.value = left + (type === \"page\" ? window.pageXOffset : 0);\n elementPositionY.value = top + (type === \"page\" ? window.pageYOffset : 0);\n elementHeight.value = height;\n elementWidth.value = width;\n const elX = x.value - elementPositionX.value;\n const elY = y.value - elementPositionY.value;\n isOutside.value = width === 0 || height === 0 || elX < 0 || elY < 0 || elX > width || elY > height;\n if (handleOutside || !isOutside.value) {\n elementX.value = elX;\n elementY.value = elY;\n }\n },\n { immediate: true }\n );\n useEventListener(\n document,\n \"mouseleave\",\n () => isOutside.value = true,\n { passive: true }\n );\n }\n return {\n x,\n y,\n sourceType,\n elementX,\n elementY,\n elementPositionX,\n elementPositionY,\n elementHeight,\n elementWidth,\n isOutside,\n stop\n };\n}\n\nfunction useMousePressed(options = {}) {\n const {\n touch = true,\n drag = true,\n capture = false,\n initialValue = false,\n window = defaultWindow\n } = options;\n const pressed = shallowRef(initialValue);\n const sourceType = shallowRef(null);\n if (!window) {\n return {\n pressed,\n sourceType\n };\n }\n const onPressed = (srcType) => (event) => {\n var _a;\n pressed.value = true;\n sourceType.value = srcType;\n (_a = options.onPressed) == null ? void 0 : _a.call(options, event);\n };\n const onReleased = (event) => {\n var _a;\n pressed.value = false;\n sourceType.value = null;\n (_a = options.onReleased) == null ? void 0 : _a.call(options, event);\n };\n const target = computed(() => unrefElement(options.target) || window);\n const listenerOptions = { passive: true, capture };\n useEventListener(target, \"mousedown\", onPressed(\"mouse\"), listenerOptions);\n useEventListener(window, \"mouseleave\", onReleased, listenerOptions);\n useEventListener(window, \"mouseup\", onReleased, listenerOptions);\n if (drag) {\n useEventListener(target, \"dragstart\", onPressed(\"mouse\"), listenerOptions);\n useEventListener(window, \"drop\", onReleased, listenerOptions);\n useEventListener(window, \"dragend\", onReleased, listenerOptions);\n }\n if (touch) {\n useEventListener(target, \"touchstart\", onPressed(\"touch\"), listenerOptions);\n useEventListener(window, \"touchend\", onReleased, listenerOptions);\n useEventListener(window, \"touchcancel\", onReleased, listenerOptions);\n }\n return {\n pressed,\n sourceType\n };\n}\n\nfunction useNavigatorLanguage(options = {}) {\n const { window = defaultWindow } = options;\n const navigator = window == null ? void 0 : window.navigator;\n const isSupported = useSupported(() => navigator && \"language\" in navigator);\n const language = shallowRef(navigator == null ? void 0 : navigator.language);\n useEventListener(window, \"languagechange\", () => {\n if (navigator)\n language.value = navigator.language;\n }, { passive: true });\n return {\n isSupported,\n language\n };\n}\n\nfunction useNetwork(options = {}) {\n const { window = defaultWindow } = options;\n const navigator = window == null ? void 0 : window.navigator;\n const isSupported = useSupported(() => navigator && \"connection\" in navigator);\n const isOnline = shallowRef(true);\n const saveData = shallowRef(false);\n const offlineAt = shallowRef(void 0);\n const onlineAt = shallowRef(void 0);\n const downlink = shallowRef(void 0);\n const downlinkMax = shallowRef(void 0);\n const rtt = shallowRef(void 0);\n const effectiveType = shallowRef(void 0);\n const type = shallowRef(\"unknown\");\n const connection = isSupported.value && navigator.connection;\n function updateNetworkInformation() {\n if (!navigator)\n return;\n isOnline.value = navigator.onLine;\n offlineAt.value = isOnline.value ? void 0 : Date.now();\n onlineAt.value = isOnline.value ? Date.now() : void 0;\n if (connection) {\n downlink.value = connection.downlink;\n downlinkMax.value = connection.downlinkMax;\n effectiveType.value = connection.effectiveType;\n rtt.value = connection.rtt;\n saveData.value = connection.saveData;\n type.value = connection.type;\n }\n }\n const listenerOptions = { passive: true };\n if (window) {\n useEventListener(window, \"offline\", () => {\n isOnline.value = false;\n offlineAt.value = Date.now();\n }, listenerOptions);\n useEventListener(window, \"online\", () => {\n isOnline.value = true;\n onlineAt.value = Date.now();\n }, listenerOptions);\n }\n if (connection)\n useEventListener(connection, \"change\", updateNetworkInformation, listenerOptions);\n updateNetworkInformation();\n return {\n isSupported,\n isOnline: readonly(isOnline),\n saveData: readonly(saveData),\n offlineAt: readonly(offlineAt),\n onlineAt: readonly(onlineAt),\n downlink: readonly(downlink),\n downlinkMax: readonly(downlinkMax),\n effectiveType: readonly(effectiveType),\n rtt: readonly(rtt),\n type: readonly(type)\n };\n}\n\nfunction useNow(options = {}) {\n const {\n controls: exposeControls = false,\n interval = \"requestAnimationFrame\"\n } = options;\n const now = ref(/* @__PURE__ */ new Date());\n const update = () => now.value = /* @__PURE__ */ new Date();\n const controls = interval === \"requestAnimationFrame\" ? useRafFn(update, { immediate: true }) : useIntervalFn(update, interval, { immediate: true });\n if (exposeControls) {\n return {\n now,\n ...controls\n };\n } else {\n return now;\n }\n}\n\nfunction useObjectUrl(object) {\n const url = shallowRef();\n const release = () => {\n if (url.value)\n URL.revokeObjectURL(url.value);\n url.value = void 0;\n };\n watch(\n () => toValue(object),\n (newObject) => {\n release();\n if (newObject)\n url.value = URL.createObjectURL(newObject);\n },\n { immediate: true }\n );\n tryOnScopeDispose(release);\n return readonly(url);\n}\n\nfunction useClamp(value, min, max) {\n if (typeof value === \"function\" || isReadonly(value))\n return computed(() => clamp(toValue(value), toValue(min), toValue(max)));\n const _value = ref(value);\n return computed({\n get() {\n return _value.value = clamp(_value.value, toValue(min), toValue(max));\n },\n set(value2) {\n _value.value = clamp(value2, toValue(min), toValue(max));\n }\n });\n}\n\nfunction useOffsetPagination(options) {\n const {\n total = Number.POSITIVE_INFINITY,\n pageSize = 10,\n page = 1,\n onPageChange = noop,\n onPageSizeChange = noop,\n onPageCountChange = noop\n } = options;\n const currentPageSize = useClamp(pageSize, 1, Number.POSITIVE_INFINITY);\n const pageCount = computed(() => Math.max(\n 1,\n Math.ceil(toValue(total) / toValue(currentPageSize))\n ));\n const currentPage = useClamp(page, 1, pageCount);\n const isFirstPage = computed(() => currentPage.value === 1);\n const isLastPage = computed(() => currentPage.value === pageCount.value);\n if (isRef(page)) {\n syncRef(page, currentPage, {\n direction: isReadonly(page) ? \"ltr\" : \"both\"\n });\n }\n if (isRef(pageSize)) {\n syncRef(pageSize, currentPageSize, {\n direction: isReadonly(pageSize) ? \"ltr\" : \"both\"\n });\n }\n function prev() {\n currentPage.value--;\n }\n function next() {\n currentPage.value++;\n }\n const returnValue = {\n currentPage,\n currentPageSize,\n pageCount,\n isFirstPage,\n isLastPage,\n prev,\n next\n };\n watch(currentPage, () => {\n onPageChange(reactive(returnValue));\n });\n watch(currentPageSize, () => {\n onPageSizeChange(reactive(returnValue));\n });\n watch(pageCount, () => {\n onPageCountChange(reactive(returnValue));\n });\n return returnValue;\n}\n\nfunction useOnline(options = {}) {\n const { isOnline } = useNetwork(options);\n return isOnline;\n}\n\nfunction usePageLeave(options = {}) {\n const { window = defaultWindow } = options;\n const isLeft = shallowRef(false);\n const handler = (event) => {\n if (!window)\n return;\n event = event || window.event;\n const from = event.relatedTarget || event.toElement;\n isLeft.value = !from;\n };\n if (window) {\n const listenerOptions = { passive: true };\n useEventListener(window, \"mouseout\", handler, listenerOptions);\n useEventListener(window.document, \"mouseleave\", handler, listenerOptions);\n useEventListener(window.document, \"mouseenter\", handler, listenerOptions);\n }\n return isLeft;\n}\n\nfunction useScreenOrientation(options = {}) {\n const {\n window = defaultWindow\n } = options;\n const isSupported = useSupported(() => window && \"screen\" in window && \"orientation\" in window.screen);\n const screenOrientation = isSupported.value ? window.screen.orientation : {};\n const orientation = ref(screenOrientation.type);\n const angle = shallowRef(screenOrientation.angle || 0);\n if (isSupported.value) {\n useEventListener(window, \"orientationchange\", () => {\n orientation.value = screenOrientation.type;\n angle.value = screenOrientation.angle;\n }, { passive: true });\n }\n const lockOrientation = (type) => {\n if (isSupported.value && typeof screenOrientation.lock === \"function\")\n return screenOrientation.lock(type);\n return Promise.reject(new Error(\"Not supported\"));\n };\n const unlockOrientation = () => {\n if (isSupported.value && typeof screenOrientation.unlock === \"function\")\n screenOrientation.unlock();\n };\n return {\n isSupported,\n orientation,\n angle,\n lockOrientation,\n unlockOrientation\n };\n}\n\nfunction useParallax(target, options = {}) {\n const {\n deviceOrientationTiltAdjust = (i) => i,\n deviceOrientationRollAdjust = (i) => i,\n mouseTiltAdjust = (i) => i,\n mouseRollAdjust = (i) => i,\n window = defaultWindow\n } = options;\n const orientation = reactive(useDeviceOrientation({ window }));\n const screenOrientation = reactive(useScreenOrientation({ window }));\n const {\n elementX: x,\n elementY: y,\n elementWidth: width,\n elementHeight: height\n } = useMouseInElement(target, { handleOutside: false, window });\n const source = computed(() => {\n if (orientation.isSupported && (orientation.alpha != null && orientation.alpha !== 0 || orientation.gamma != null && orientation.gamma !== 0)) {\n return \"deviceOrientation\";\n }\n return \"mouse\";\n });\n const roll = computed(() => {\n if (source.value === \"deviceOrientation\") {\n let value;\n switch (screenOrientation.orientation) {\n case \"landscape-primary\":\n value = orientation.gamma / 90;\n break;\n case \"landscape-secondary\":\n value = -orientation.gamma / 90;\n break;\n case \"portrait-primary\":\n value = -orientation.beta / 90;\n break;\n case \"portrait-secondary\":\n value = orientation.beta / 90;\n break;\n default:\n value = -orientation.beta / 90;\n }\n return deviceOrientationRollAdjust(value);\n } else {\n const value = -(y.value - height.value / 2) / height.value;\n return mouseRollAdjust(value);\n }\n });\n const tilt = computed(() => {\n if (source.value === \"deviceOrientation\") {\n let value;\n switch (screenOrientation.orientation) {\n case \"landscape-primary\":\n value = orientation.beta / 90;\n break;\n case \"landscape-secondary\":\n value = -orientation.beta / 90;\n break;\n case \"portrait-primary\":\n value = orientation.gamma / 90;\n break;\n case \"portrait-secondary\":\n value = -orientation.gamma / 90;\n break;\n default:\n value = orientation.gamma / 90;\n }\n return deviceOrientationTiltAdjust(value);\n } else {\n const value = (x.value - width.value / 2) / width.value;\n return mouseTiltAdjust(value);\n }\n });\n return { roll, tilt, source };\n}\n\nfunction useParentElement(element = useCurrentElement()) {\n const parentElement = shallowRef();\n const update = () => {\n const el = unrefElement(element);\n if (el)\n parentElement.value = el.parentElement;\n };\n tryOnMounted(update);\n watch(() => toValue(element), update);\n return parentElement;\n}\n\nfunction usePerformanceObserver(options, callback) {\n const {\n window = defaultWindow,\n immediate = true,\n ...performanceOptions\n } = options;\n const isSupported = useSupported(() => window && \"PerformanceObserver\" in window);\n let observer;\n const stop = () => {\n observer == null ? void 0 : observer.disconnect();\n };\n const start = () => {\n if (isSupported.value) {\n stop();\n observer = new PerformanceObserver(callback);\n observer.observe(performanceOptions);\n }\n };\n tryOnScopeDispose(stop);\n if (immediate)\n start();\n return {\n isSupported,\n start,\n stop\n };\n}\n\nconst defaultState = {\n x: 0,\n y: 0,\n pointerId: 0,\n pressure: 0,\n tiltX: 0,\n tiltY: 0,\n width: 0,\n height: 0,\n twist: 0,\n pointerType: null\n};\nconst keys = /* @__PURE__ */ Object.keys(defaultState);\nfunction usePointer(options = {}) {\n const {\n target = defaultWindow\n } = options;\n const isInside = shallowRef(false);\n const state = ref(options.initialValue || {});\n Object.assign(state.value, defaultState, state.value);\n const handler = (event) => {\n isInside.value = true;\n if (options.pointerTypes && !options.pointerTypes.includes(event.pointerType))\n return;\n state.value = objectPick(event, keys, false);\n };\n if (target) {\n const listenerOptions = { passive: true };\n useEventListener(target, [\"pointerdown\", \"pointermove\", \"pointerup\"], handler, listenerOptions);\n useEventListener(target, \"pointerleave\", () => isInside.value = false, listenerOptions);\n }\n return {\n ...toRefs(state),\n isInside\n };\n}\n\nfunction usePointerLock(target, options = {}) {\n const { document = defaultDocument } = options;\n const isSupported = useSupported(() => document && \"pointerLockElement\" in document);\n const element = shallowRef();\n const triggerElement = shallowRef();\n let targetElement;\n if (isSupported.value) {\n const listenerOptions = { passive: true };\n useEventListener(document, \"pointerlockchange\", () => {\n var _a;\n const currentElement = (_a = document.pointerLockElement) != null ? _a : element.value;\n if (targetElement && currentElement === targetElement) {\n element.value = document.pointerLockElement;\n if (!element.value)\n targetElement = triggerElement.value = null;\n }\n }, listenerOptions);\n useEventListener(document, \"pointerlockerror\", () => {\n var _a;\n const currentElement = (_a = document.pointerLockElement) != null ? _a : element.value;\n if (targetElement && currentElement === targetElement) {\n const action = document.pointerLockElement ? \"release\" : \"acquire\";\n throw new Error(`Failed to ${action} pointer lock.`);\n }\n }, listenerOptions);\n }\n async function lock(e) {\n var _a;\n if (!isSupported.value)\n throw new Error(\"Pointer Lock API is not supported by your browser.\");\n triggerElement.value = e instanceof Event ? e.currentTarget : null;\n targetElement = e instanceof Event ? (_a = unrefElement(target)) != null ? _a : triggerElement.value : unrefElement(e);\n if (!targetElement)\n throw new Error(\"Target element undefined.\");\n targetElement.requestPointerLock();\n return await until(element).toBe(targetElement);\n }\n async function unlock() {\n if (!element.value)\n return false;\n document.exitPointerLock();\n await until(element).toBeNull();\n return true;\n }\n return {\n isSupported,\n element,\n triggerElement,\n lock,\n unlock\n };\n}\n\nfunction usePointerSwipe(target, options = {}) {\n const targetRef = toRef(target);\n const {\n threshold = 50,\n onSwipe,\n onSwipeEnd,\n onSwipeStart,\n disableTextSelect = false\n } = options;\n const posStart = reactive({ x: 0, y: 0 });\n const updatePosStart = (x, y) => {\n posStart.x = x;\n posStart.y = y;\n };\n const posEnd = reactive({ x: 0, y: 0 });\n const updatePosEnd = (x, y) => {\n posEnd.x = x;\n posEnd.y = y;\n };\n const distanceX = computed(() => posStart.x - posEnd.x);\n const distanceY = computed(() => posStart.y - posEnd.y);\n const { max, abs } = Math;\n const isThresholdExceeded = computed(() => max(abs(distanceX.value), abs(distanceY.value)) >= threshold);\n const isSwiping = shallowRef(false);\n const isPointerDown = shallowRef(false);\n const direction = computed(() => {\n if (!isThresholdExceeded.value)\n return \"none\";\n if (abs(distanceX.value) > abs(distanceY.value)) {\n return distanceX.value > 0 ? \"left\" : \"right\";\n } else {\n return distanceY.value > 0 ? \"up\" : \"down\";\n }\n });\n const eventIsAllowed = (e) => {\n var _a, _b, _c;\n const isReleasingButton = e.buttons === 0;\n const isPrimaryButton = e.buttons === 1;\n return (_c = (_b = (_a = options.pointerTypes) == null ? void 0 : _a.includes(e.pointerType)) != null ? _b : isReleasingButton || isPrimaryButton) != null ? _c : true;\n };\n const listenerOptions = { passive: true };\n const stops = [\n useEventListener(target, \"pointerdown\", (e) => {\n if (!eventIsAllowed(e))\n return;\n isPointerDown.value = true;\n const eventTarget = e.target;\n eventTarget == null ? void 0 : eventTarget.setPointerCapture(e.pointerId);\n const { clientX: x, clientY: y } = e;\n updatePosStart(x, y);\n updatePosEnd(x, y);\n onSwipeStart == null ? void 0 : onSwipeStart(e);\n }, listenerOptions),\n useEventListener(target, \"pointermove\", (e) => {\n if (!eventIsAllowed(e))\n return;\n if (!isPointerDown.value)\n return;\n const { clientX: x, clientY: y } = e;\n updatePosEnd(x, y);\n if (!isSwiping.value && isThresholdExceeded.value)\n isSwiping.value = true;\n if (isSwiping.value)\n onSwipe == null ? void 0 : onSwipe(e);\n }, listenerOptions),\n useEventListener(target, \"pointerup\", (e) => {\n if (!eventIsAllowed(e))\n return;\n if (isSwiping.value)\n onSwipeEnd == null ? void 0 : onSwipeEnd(e, direction.value);\n isPointerDown.value = false;\n isSwiping.value = false;\n }, listenerOptions)\n ];\n tryOnMounted(() => {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n (_b = (_a = targetRef.value) == null ? void 0 : _a.style) == null ? void 0 : _b.setProperty(\"touch-action\", \"none\");\n if (disableTextSelect) {\n (_d = (_c = targetRef.value) == null ? void 0 : _c.style) == null ? void 0 : _d.setProperty(\"-webkit-user-select\", \"none\");\n (_f = (_e = targetRef.value) == null ? void 0 : _e.style) == null ? void 0 : _f.setProperty(\"-ms-user-select\", \"none\");\n (_h = (_g = targetRef.value) == null ? void 0 : _g.style) == null ? void 0 : _h.setProperty(\"user-select\", \"none\");\n }\n });\n const stop = () => stops.forEach((s) => s());\n return {\n isSwiping: readonly(isSwiping),\n direction: readonly(direction),\n posStart: readonly(posStart),\n posEnd: readonly(posEnd),\n distanceX,\n distanceY,\n stop\n };\n}\n\nfunction usePreferredColorScheme(options) {\n const isLight = useMediaQuery(\"(prefers-color-scheme: light)\", options);\n const isDark = useMediaQuery(\"(prefers-color-scheme: dark)\", options);\n return computed(() => {\n if (isDark.value)\n return \"dark\";\n if (isLight.value)\n return \"light\";\n return \"no-preference\";\n });\n}\n\nfunction usePreferredContrast(options) {\n const isMore = useMediaQuery(\"(prefers-contrast: more)\", options);\n const isLess = useMediaQuery(\"(prefers-contrast: less)\", options);\n const isCustom = useMediaQuery(\"(prefers-contrast: custom)\", options);\n return computed(() => {\n if (isMore.value)\n return \"more\";\n if (isLess.value)\n return \"less\";\n if (isCustom.value)\n return \"custom\";\n return \"no-preference\";\n });\n}\n\nfunction usePreferredLanguages(options = {}) {\n const { window = defaultWindow } = options;\n if (!window)\n return ref([\"en\"]);\n const navigator = window.navigator;\n const value = ref(navigator.languages);\n useEventListener(window, \"languagechange\", () => {\n value.value = navigator.languages;\n }, { passive: true });\n return value;\n}\n\nfunction usePreferredReducedMotion(options) {\n const isReduced = useMediaQuery(\"(prefers-reduced-motion: reduce)\", options);\n return computed(() => {\n if (isReduced.value)\n return \"reduce\";\n return \"no-preference\";\n });\n}\n\nfunction usePreferredReducedTransparency(options) {\n const isReduced = useMediaQuery(\"(prefers-reduced-transparency: reduce)\", options);\n return computed(() => {\n if (isReduced.value)\n return \"reduce\";\n return \"no-preference\";\n });\n}\n\nfunction usePrevious(value, initialValue) {\n const previous = shallowRef(initialValue);\n watch(\n toRef(value),\n (_, oldValue) => {\n previous.value = oldValue;\n },\n { flush: \"sync\" }\n );\n return readonly(previous);\n}\n\nconst topVarName = \"--vueuse-safe-area-top\";\nconst rightVarName = \"--vueuse-safe-area-right\";\nconst bottomVarName = \"--vueuse-safe-area-bottom\";\nconst leftVarName = \"--vueuse-safe-area-left\";\nfunction useScreenSafeArea() {\n const top = shallowRef(\"\");\n const right = shallowRef(\"\");\n const bottom = shallowRef(\"\");\n const left = shallowRef(\"\");\n if (isClient) {\n const topCssVar = useCssVar(topVarName);\n const rightCssVar = useCssVar(rightVarName);\n const bottomCssVar = useCssVar(bottomVarName);\n const leftCssVar = useCssVar(leftVarName);\n topCssVar.value = \"env(safe-area-inset-top, 0px)\";\n rightCssVar.value = \"env(safe-area-inset-right, 0px)\";\n bottomCssVar.value = \"env(safe-area-inset-bottom, 0px)\";\n leftCssVar.value = \"env(safe-area-inset-left, 0px)\";\n update();\n useEventListener(\"resize\", useDebounceFn(update), { passive: true });\n }\n function update() {\n top.value = getValue(topVarName);\n right.value = getValue(rightVarName);\n bottom.value = getValue(bottomVarName);\n left.value = getValue(leftVarName);\n }\n return {\n top,\n right,\n bottom,\n left,\n update\n };\n}\nfunction getValue(position) {\n return getComputedStyle(document.documentElement).getPropertyValue(position);\n}\n\nfunction useScriptTag(src, onLoaded = noop, options = {}) {\n const {\n immediate = true,\n manual = false,\n type = \"text/javascript\",\n async = true,\n crossOrigin,\n referrerPolicy,\n noModule,\n defer,\n document = defaultDocument,\n attrs = {}\n } = options;\n const scriptTag = shallowRef(null);\n let _promise = null;\n const loadScript = (waitForScriptLoad) => new Promise((resolve, reject) => {\n const resolveWithElement = (el2) => {\n scriptTag.value = el2;\n resolve(el2);\n return el2;\n };\n if (!document) {\n resolve(false);\n return;\n }\n let shouldAppend = false;\n let el = document.querySelector(`script[src=\"${toValue(src)}\"]`);\n if (!el) {\n el = document.createElement(\"script\");\n el.type = type;\n el.async = async;\n el.src = toValue(src);\n if (defer)\n el.defer = defer;\n if (crossOrigin)\n el.crossOrigin = crossOrigin;\n if (noModule)\n el.noModule = noModule;\n if (referrerPolicy)\n el.referrerPolicy = referrerPolicy;\n Object.entries(attrs).forEach(([name, value]) => el == null ? void 0 : el.setAttribute(name, value));\n shouldAppend = true;\n } else if (el.hasAttribute(\"data-loaded\")) {\n resolveWithElement(el);\n }\n const listenerOptions = {\n passive: true\n };\n useEventListener(el, \"error\", (event) => reject(event), listenerOptions);\n useEventListener(el, \"abort\", (event) => reject(event), listenerOptions);\n useEventListener(el, \"load\", () => {\n el.setAttribute(\"data-loaded\", \"true\");\n onLoaded(el);\n resolveWithElement(el);\n }, listenerOptions);\n if (shouldAppend)\n el = document.head.appendChild(el);\n if (!waitForScriptLoad)\n resolveWithElement(el);\n });\n const load = (waitForScriptLoad = true) => {\n if (!_promise)\n _promise = loadScript(waitForScriptLoad);\n return _promise;\n };\n const unload = () => {\n if (!document)\n return;\n _promise = null;\n if (scriptTag.value)\n scriptTag.value = null;\n const el = document.querySelector(`script[src=\"${toValue(src)}\"]`);\n if (el)\n document.head.removeChild(el);\n };\n if (immediate && !manual)\n tryOnMounted(load);\n if (!manual)\n tryOnUnmounted(unload);\n return { scriptTag, load, unload };\n}\n\nfunction checkOverflowScroll(ele) {\n const style = window.getComputedStyle(ele);\n if (style.overflowX === \"scroll\" || style.overflowY === \"scroll\" || style.overflowX === \"auto\" && ele.clientWidth < ele.scrollWidth || style.overflowY === \"auto\" && ele.clientHeight < ele.scrollHeight) {\n return true;\n } else {\n const parent = ele.parentNode;\n if (!parent || parent.tagName === \"BODY\")\n return false;\n return checkOverflowScroll(parent);\n }\n}\nfunction preventDefault(rawEvent) {\n const e = rawEvent || window.event;\n const _target = e.target;\n if (checkOverflowScroll(_target))\n return false;\n if (e.touches.length > 1)\n return true;\n if (e.preventDefault)\n e.preventDefault();\n return false;\n}\nconst elInitialOverflow = /* @__PURE__ */ new WeakMap();\nfunction useScrollLock(element, initialState = false) {\n const isLocked = shallowRef(initialState);\n let stopTouchMoveListener = null;\n let initialOverflow = \"\";\n watch(toRef(element), (el) => {\n const target = resolveElement(toValue(el));\n if (target) {\n const ele = target;\n if (!elInitialOverflow.get(ele))\n elInitialOverflow.set(ele, ele.style.overflow);\n if (ele.style.overflow !== \"hidden\")\n initialOverflow = ele.style.overflow;\n if (ele.style.overflow === \"hidden\")\n return isLocked.value = true;\n if (isLocked.value)\n return ele.style.overflow = \"hidden\";\n }\n }, {\n immediate: true\n });\n const lock = () => {\n const el = resolveElement(toValue(element));\n if (!el || isLocked.value)\n return;\n if (isIOS) {\n stopTouchMoveListener = useEventListener(\n el,\n \"touchmove\",\n (e) => {\n preventDefault(e);\n },\n { passive: false }\n );\n }\n el.style.overflow = \"hidden\";\n isLocked.value = true;\n };\n const unlock = () => {\n const el = resolveElement(toValue(element));\n if (!el || !isLocked.value)\n return;\n if (isIOS)\n stopTouchMoveListener == null ? void 0 : stopTouchMoveListener();\n el.style.overflow = initialOverflow;\n elInitialOverflow.delete(el);\n isLocked.value = false;\n };\n tryOnScopeDispose(unlock);\n return computed({\n get() {\n return isLocked.value;\n },\n set(v) {\n if (v)\n lock();\n else unlock();\n }\n });\n}\n\nfunction useSessionStorage(key, initialValue, options = {}) {\n const { window = defaultWindow } = options;\n return useStorage(key, initialValue, window == null ? void 0 : window.sessionStorage, options);\n}\n\nfunction useShare(shareOptions = {}, options = {}) {\n const { navigator = defaultNavigator } = options;\n const _navigator = navigator;\n const isSupported = useSupported(() => _navigator && \"canShare\" in _navigator);\n const share = async (overrideOptions = {}) => {\n if (isSupported.value) {\n const data = {\n ...toValue(shareOptions),\n ...toValue(overrideOptions)\n };\n let granted = true;\n if (data.files && _navigator.canShare)\n granted = _navigator.canShare({ files: data.files });\n if (granted)\n return _navigator.share(data);\n }\n };\n return {\n isSupported,\n share\n };\n}\n\nconst defaultSortFn = (source, compareFn) => source.sort(compareFn);\nconst defaultCompare = (a, b) => a - b;\nfunction useSorted(...args) {\n var _a, _b, _c, _d;\n const [source] = args;\n let compareFn = defaultCompare;\n let options = {};\n if (args.length === 2) {\n if (typeof args[1] === \"object\") {\n options = args[1];\n compareFn = (_a = options.compareFn) != null ? _a : defaultCompare;\n } else {\n compareFn = (_b = args[1]) != null ? _b : defaultCompare;\n }\n } else if (args.length > 2) {\n compareFn = (_c = args[1]) != null ? _c : defaultCompare;\n options = (_d = args[2]) != null ? _d : {};\n }\n const {\n dirty = false,\n sortFn = defaultSortFn\n } = options;\n if (!dirty)\n return computed(() => sortFn([...toValue(source)], compareFn));\n watchEffect(() => {\n const result = sortFn(toValue(source), compareFn);\n if (isRef(source))\n source.value = result;\n else\n source.splice(0, source.length, ...result);\n });\n return source;\n}\n\nfunction useSpeechRecognition(options = {}) {\n const {\n interimResults = true,\n continuous = true,\n maxAlternatives = 1,\n window = defaultWindow\n } = options;\n const lang = toRef(options.lang || \"en-US\");\n const isListening = shallowRef(false);\n const isFinal = shallowRef(false);\n const result = shallowRef(\"\");\n const error = shallowRef(void 0);\n let recognition;\n const start = () => {\n isListening.value = true;\n };\n const stop = () => {\n isListening.value = false;\n };\n const toggle = (value = !isListening.value) => {\n if (value) {\n start();\n } else {\n stop();\n }\n };\n const SpeechRecognition = window && (window.SpeechRecognition || window.webkitSpeechRecognition);\n const isSupported = useSupported(() => SpeechRecognition);\n if (isSupported.value) {\n recognition = new SpeechRecognition();\n recognition.continuous = continuous;\n recognition.interimResults = interimResults;\n recognition.lang = toValue(lang);\n recognition.maxAlternatives = maxAlternatives;\n recognition.onstart = () => {\n isListening.value = true;\n isFinal.value = false;\n };\n watch(lang, (lang2) => {\n if (recognition && !isListening.value)\n recognition.lang = lang2;\n });\n recognition.onresult = (event) => {\n const currentResult = event.results[event.resultIndex];\n const { transcript } = currentResult[0];\n isFinal.value = currentResult.isFinal;\n result.value = transcript;\n error.value = void 0;\n };\n recognition.onerror = (event) => {\n error.value = event;\n };\n recognition.onend = () => {\n isListening.value = false;\n recognition.lang = toValue(lang);\n };\n watch(isListening, (newValue, oldValue) => {\n if (newValue === oldValue)\n return;\n if (newValue)\n recognition.start();\n else\n recognition.stop();\n });\n }\n tryOnScopeDispose(() => {\n stop();\n });\n return {\n isSupported,\n isListening,\n isFinal,\n recognition,\n result,\n error,\n toggle,\n start,\n stop\n };\n}\n\nfunction useSpeechSynthesis(text, options = {}) {\n const {\n pitch = 1,\n rate = 1,\n volume = 1,\n window = defaultWindow\n } = options;\n const synth = window && window.speechSynthesis;\n const isSupported = useSupported(() => synth);\n const isPlaying = shallowRef(false);\n const status = shallowRef(\"init\");\n const spokenText = toRef(text || \"\");\n const lang = toRef(options.lang || \"en-US\");\n const error = shallowRef(void 0);\n const toggle = (value = !isPlaying.value) => {\n isPlaying.value = value;\n };\n const bindEventsForUtterance = (utterance2) => {\n utterance2.lang = toValue(lang);\n utterance2.voice = toValue(options.voice) || null;\n utterance2.pitch = toValue(pitch);\n utterance2.rate = toValue(rate);\n utterance2.volume = volume;\n utterance2.onstart = () => {\n isPlaying.value = true;\n status.value = \"play\";\n };\n utterance2.onpause = () => {\n isPlaying.value = false;\n status.value = \"pause\";\n };\n utterance2.onresume = () => {\n isPlaying.value = true;\n status.value = \"play\";\n };\n utterance2.onend = () => {\n isPlaying.value = false;\n status.value = \"end\";\n };\n utterance2.onerror = (event) => {\n error.value = event;\n };\n };\n const utterance = computed(() => {\n isPlaying.value = false;\n status.value = \"init\";\n const newUtterance = new SpeechSynthesisUtterance(spokenText.value);\n bindEventsForUtterance(newUtterance);\n return newUtterance;\n });\n const speak = () => {\n synth.cancel();\n if (utterance)\n synth.speak(utterance.value);\n };\n const stop = () => {\n synth.cancel();\n isPlaying.value = false;\n };\n if (isSupported.value) {\n bindEventsForUtterance(utterance.value);\n watch(lang, (lang2) => {\n if (utterance.value && !isPlaying.value)\n utterance.value.lang = lang2;\n });\n if (options.voice) {\n watch(options.voice, () => {\n synth.cancel();\n });\n }\n watch(isPlaying, () => {\n if (isPlaying.value)\n synth.resume();\n else\n synth.pause();\n });\n }\n tryOnScopeDispose(() => {\n isPlaying.value = false;\n });\n return {\n isSupported,\n isPlaying,\n status,\n utterance,\n error,\n stop,\n toggle,\n speak\n };\n}\n\nfunction useStepper(steps, initialStep) {\n const stepsRef = ref(steps);\n const stepNames = computed(() => Array.isArray(stepsRef.value) ? stepsRef.value : Object.keys(stepsRef.value));\n const index = ref(stepNames.value.indexOf(initialStep != null ? initialStep : stepNames.value[0]));\n const current = computed(() => at(index.value));\n const isFirst = computed(() => index.value === 0);\n const isLast = computed(() => index.value === stepNames.value.length - 1);\n const next = computed(() => stepNames.value[index.value + 1]);\n const previous = computed(() => stepNames.value[index.value - 1]);\n function at(index2) {\n if (Array.isArray(stepsRef.value))\n return stepsRef.value[index2];\n return stepsRef.value[stepNames.value[index2]];\n }\n function get(step) {\n if (!stepNames.value.includes(step))\n return;\n return at(stepNames.value.indexOf(step));\n }\n function goTo(step) {\n if (stepNames.value.includes(step))\n index.value = stepNames.value.indexOf(step);\n }\n function goToNext() {\n if (isLast.value)\n return;\n index.value++;\n }\n function goToPrevious() {\n if (isFirst.value)\n return;\n index.value--;\n }\n function goBackTo(step) {\n if (isAfter(step))\n goTo(step);\n }\n function isNext(step) {\n return stepNames.value.indexOf(step) === index.value + 1;\n }\n function isPrevious(step) {\n return stepNames.value.indexOf(step) === index.value - 1;\n }\n function isCurrent(step) {\n return stepNames.value.indexOf(step) === index.value;\n }\n function isBefore(step) {\n return index.value < stepNames.value.indexOf(step);\n }\n function isAfter(step) {\n return index.value > stepNames.value.indexOf(step);\n }\n return {\n steps: stepsRef,\n stepNames,\n index,\n current,\n next,\n previous,\n isFirst,\n isLast,\n at,\n get,\n goTo,\n goToNext,\n goToPrevious,\n goBackTo,\n isNext,\n isPrevious,\n isCurrent,\n isBefore,\n isAfter\n };\n}\n\nfunction useStorageAsync(key, initialValue, storage, options = {}) {\n var _a;\n const {\n flush = \"pre\",\n deep = true,\n listenToStorageChanges = true,\n writeDefaults = true,\n mergeDefaults = false,\n shallow,\n window = defaultWindow,\n eventFilter,\n onError = (e) => {\n console.error(e);\n }\n } = options;\n const rawInit = toValue(initialValue);\n const type = guessSerializerType(rawInit);\n const data = (shallow ? shallowRef : ref)(toValue(initialValue));\n const serializer = (_a = options.serializer) != null ? _a : StorageSerializers[type];\n if (!storage) {\n try {\n storage = getSSRHandler(\"getDefaultStorageAsync\", () => {\n var _a2;\n return (_a2 = defaultWindow) == null ? void 0 : _a2.localStorage;\n })();\n } catch (e) {\n onError(e);\n }\n }\n async function read(event) {\n if (!storage || event && event.key !== key)\n return;\n try {\n const rawValue = event ? event.newValue : await storage.getItem(key);\n if (rawValue == null) {\n data.value = rawInit;\n if (writeDefaults && rawInit !== null)\n await storage.setItem(key, await serializer.write(rawInit));\n } else if (mergeDefaults) {\n const value = await serializer.read(rawValue);\n if (typeof mergeDefaults === \"function\")\n data.value = mergeDefaults(value, rawInit);\n else if (type === \"object\" && !Array.isArray(value))\n data.value = { ...rawInit, ...value };\n else data.value = value;\n } else {\n data.value = await serializer.read(rawValue);\n }\n } catch (e) {\n onError(e);\n }\n }\n read();\n if (window && listenToStorageChanges)\n useEventListener(window, \"storage\", (e) => Promise.resolve().then(() => read(e)), { passive: true });\n if (storage) {\n watchWithFilter(\n data,\n async () => {\n try {\n if (data.value == null)\n await storage.removeItem(key);\n else\n await storage.setItem(key, await serializer.write(data.value));\n } catch (e) {\n onError(e);\n }\n },\n {\n flush,\n deep,\n eventFilter\n }\n );\n }\n return data;\n}\n\nlet _id = 0;\nfunction useStyleTag(css, options = {}) {\n const isLoaded = shallowRef(false);\n const {\n document = defaultDocument,\n immediate = true,\n manual = false,\n id = `vueuse_styletag_${++_id}`\n } = options;\n const cssRef = shallowRef(css);\n let stop = () => {\n };\n const load = () => {\n if (!document)\n return;\n const el = document.getElementById(id) || document.createElement(\"style\");\n if (!el.isConnected) {\n el.id = id;\n if (options.media)\n el.media = options.media;\n document.head.appendChild(el);\n }\n if (isLoaded.value)\n return;\n stop = watch(\n cssRef,\n (value) => {\n el.textContent = value;\n },\n { immediate: true }\n );\n isLoaded.value = true;\n };\n const unload = () => {\n if (!document || !isLoaded.value)\n return;\n stop();\n document.head.removeChild(document.getElementById(id));\n isLoaded.value = false;\n };\n if (immediate && !manual)\n tryOnMounted(load);\n if (!manual)\n tryOnScopeDispose(unload);\n return {\n id,\n css: cssRef,\n unload,\n load,\n isLoaded: readonly(isLoaded)\n };\n}\n\nfunction useSwipe(target, options = {}) {\n const {\n threshold = 50,\n onSwipe,\n onSwipeEnd,\n onSwipeStart,\n passive = true\n } = options;\n const coordsStart = reactive({ x: 0, y: 0 });\n const coordsEnd = reactive({ x: 0, y: 0 });\n const diffX = computed(() => coordsStart.x - coordsEnd.x);\n const diffY = computed(() => coordsStart.y - coordsEnd.y);\n const { max, abs } = Math;\n const isThresholdExceeded = computed(() => max(abs(diffX.value), abs(diffY.value)) >= threshold);\n const isSwiping = shallowRef(false);\n const direction = computed(() => {\n if (!isThresholdExceeded.value)\n return \"none\";\n if (abs(diffX.value) > abs(diffY.value)) {\n return diffX.value > 0 ? \"left\" : \"right\";\n } else {\n return diffY.value > 0 ? \"up\" : \"down\";\n }\n });\n const getTouchEventCoords = (e) => [e.touches[0].clientX, e.touches[0].clientY];\n const updateCoordsStart = (x, y) => {\n coordsStart.x = x;\n coordsStart.y = y;\n };\n const updateCoordsEnd = (x, y) => {\n coordsEnd.x = x;\n coordsEnd.y = y;\n };\n const listenerOptions = { passive, capture: !passive };\n const onTouchEnd = (e) => {\n if (isSwiping.value)\n onSwipeEnd == null ? void 0 : onSwipeEnd(e, direction.value);\n isSwiping.value = false;\n };\n const stops = [\n useEventListener(target, \"touchstart\", (e) => {\n if (e.touches.length !== 1)\n return;\n const [x, y] = getTouchEventCoords(e);\n updateCoordsStart(x, y);\n updateCoordsEnd(x, y);\n onSwipeStart == null ? void 0 : onSwipeStart(e);\n }, listenerOptions),\n useEventListener(target, \"touchmove\", (e) => {\n if (e.touches.length !== 1)\n return;\n const [x, y] = getTouchEventCoords(e);\n updateCoordsEnd(x, y);\n if (listenerOptions.capture && !listenerOptions.passive && Math.abs(diffX.value) > Math.abs(diffY.value))\n e.preventDefault();\n if (!isSwiping.value && isThresholdExceeded.value)\n isSwiping.value = true;\n if (isSwiping.value)\n onSwipe == null ? void 0 : onSwipe(e);\n }, listenerOptions),\n useEventListener(target, [\"touchend\", \"touchcancel\"], onTouchEnd, listenerOptions)\n ];\n const stop = () => stops.forEach((s) => s());\n return {\n isSwiping,\n direction,\n coordsStart,\n coordsEnd,\n lengthX: diffX,\n lengthY: diffY,\n stop,\n // TODO: Remove in the next major version\n isPassiveEventSupported: true\n };\n}\n\nfunction useTemplateRefsList() {\n const refs = ref([]);\n refs.value.set = (el) => {\n if (el)\n refs.value.push(el);\n };\n onBeforeUpdate(() => {\n refs.value.length = 0;\n });\n return refs;\n}\n\nfunction useTextDirection(options = {}) {\n const {\n document = defaultDocument,\n selector = \"html\",\n observe = false,\n initialValue = \"ltr\"\n } = options;\n function getValue() {\n var _a, _b;\n return (_b = (_a = document == null ? void 0 : document.querySelector(selector)) == null ? void 0 : _a.getAttribute(\"dir\")) != null ? _b : initialValue;\n }\n const dir = ref(getValue());\n tryOnMounted(() => dir.value = getValue());\n if (observe && document) {\n useMutationObserver(\n document.querySelector(selector),\n () => dir.value = getValue(),\n { attributes: true }\n );\n }\n return computed({\n get() {\n return dir.value;\n },\n set(v) {\n var _a, _b;\n dir.value = v;\n if (!document)\n return;\n if (dir.value)\n (_a = document.querySelector(selector)) == null ? void 0 : _a.setAttribute(\"dir\", dir.value);\n else\n (_b = document.querySelector(selector)) == null ? void 0 : _b.removeAttribute(\"dir\");\n }\n });\n}\n\nfunction getRangesFromSelection(selection) {\n var _a;\n const rangeCount = (_a = selection.rangeCount) != null ? _a : 0;\n return Array.from({ length: rangeCount }, (_, i) => selection.getRangeAt(i));\n}\nfunction useTextSelection(options = {}) {\n const {\n window = defaultWindow\n } = options;\n const selection = ref(null);\n const text = computed(() => {\n var _a, _b;\n return (_b = (_a = selection.value) == null ? void 0 : _a.toString()) != null ? _b : \"\";\n });\n const ranges = computed(() => selection.value ? getRangesFromSelection(selection.value) : []);\n const rects = computed(() => ranges.value.map((range) => range.getBoundingClientRect()));\n function onSelectionChange() {\n selection.value = null;\n if (window)\n selection.value = window.getSelection();\n }\n if (window)\n useEventListener(window.document, \"selectionchange\", onSelectionChange, { passive: true });\n return {\n text,\n rects,\n ranges,\n selection\n };\n}\n\nfunction tryRequestAnimationFrame(window = defaultWindow, fn) {\n if (window && typeof window.requestAnimationFrame === \"function\") {\n window.requestAnimationFrame(fn);\n } else {\n fn();\n }\n}\nfunction useTextareaAutosize(options = {}) {\n var _a, _b;\n const { window = defaultWindow } = options;\n const textarea = toRef(options == null ? void 0 : options.element);\n const input = toRef((_a = options == null ? void 0 : options.input) != null ? _a : \"\");\n const styleProp = (_b = options == null ? void 0 : options.styleProp) != null ? _b : \"height\";\n const textareaScrollHeight = shallowRef(1);\n const textareaOldWidth = shallowRef(0);\n function triggerResize() {\n var _a2;\n if (!textarea.value)\n return;\n let height = \"\";\n textarea.value.style[styleProp] = \"1px\";\n textareaScrollHeight.value = (_a2 = textarea.value) == null ? void 0 : _a2.scrollHeight;\n const _styleTarget = toValue(options == null ? void 0 : options.styleTarget);\n if (_styleTarget)\n _styleTarget.style[styleProp] = `${textareaScrollHeight.value}px`;\n else\n height = `${textareaScrollHeight.value}px`;\n textarea.value.style[styleProp] = height;\n }\n watch([input, textarea], () => nextTick(triggerResize), { immediate: true });\n watch(textareaScrollHeight, () => {\n var _a2;\n return (_a2 = options == null ? void 0 : options.onResize) == null ? void 0 : _a2.call(options);\n });\n useResizeObserver(textarea, ([{ contentRect }]) => {\n if (textareaOldWidth.value === contentRect.width)\n return;\n tryRequestAnimationFrame(window, () => {\n textareaOldWidth.value = contentRect.width;\n triggerResize();\n });\n });\n if (options == null ? void 0 : options.watch)\n watch(options.watch, triggerResize, { immediate: true, deep: true });\n return {\n textarea,\n input,\n triggerResize\n };\n}\n\nfunction useThrottledRefHistory(source, options = {}) {\n const { throttle = 200, trailing = true } = options;\n const filter = throttleFilter(throttle, trailing);\n const history = useRefHistory(source, { ...options, eventFilter: filter });\n return {\n ...history\n };\n}\n\nconst DEFAULT_UNITS = [\n { max: 6e4, value: 1e3, name: \"second\" },\n { max: 276e4, value: 6e4, name: \"minute\" },\n { max: 72e6, value: 36e5, name: \"hour\" },\n { max: 5184e5, value: 864e5, name: \"day\" },\n { max: 24192e5, value: 6048e5, name: \"week\" },\n { max: 28512e6, value: 2592e6, name: \"month\" },\n { max: Number.POSITIVE_INFINITY, value: 31536e6, name: \"year\" }\n];\nconst DEFAULT_MESSAGES = {\n justNow: \"just now\",\n past: (n) => n.match(/\\d/) ? `${n} ago` : n,\n future: (n) => n.match(/\\d/) ? `in ${n}` : n,\n month: (n, past) => n === 1 ? past ? \"last month\" : \"next month\" : `${n} month${n > 1 ? \"s\" : \"\"}`,\n year: (n, past) => n === 1 ? past ? \"last year\" : \"next year\" : `${n} year${n > 1 ? \"s\" : \"\"}`,\n day: (n, past) => n === 1 ? past ? \"yesterday\" : \"tomorrow\" : `${n} day${n > 1 ? \"s\" : \"\"}`,\n week: (n, past) => n === 1 ? past ? \"last week\" : \"next week\" : `${n} week${n > 1 ? \"s\" : \"\"}`,\n hour: (n) => `${n} hour${n > 1 ? \"s\" : \"\"}`,\n minute: (n) => `${n} minute${n > 1 ? \"s\" : \"\"}`,\n second: (n) => `${n} second${n > 1 ? \"s\" : \"\"}`,\n invalid: \"\"\n};\nfunction DEFAULT_FORMATTER(date) {\n return date.toISOString().slice(0, 10);\n}\nfunction useTimeAgo(time, options = {}) {\n const {\n controls: exposeControls = false,\n updateInterval = 3e4\n } = options;\n const { now, ...controls } = useNow({ interval: updateInterval, controls: true });\n const timeAgo = computed(() => formatTimeAgo(new Date(toValue(time)), options, toValue(now)));\n if (exposeControls) {\n return {\n timeAgo,\n ...controls\n };\n } else {\n return timeAgo;\n }\n}\nfunction formatTimeAgo(from, options = {}, now = Date.now()) {\n var _a;\n const {\n max,\n messages = DEFAULT_MESSAGES,\n fullDateFormatter = DEFAULT_FORMATTER,\n units = DEFAULT_UNITS,\n showSecond = false,\n rounding = \"round\"\n } = options;\n const roundFn = typeof rounding === \"number\" ? (n) => +n.toFixed(rounding) : Math[rounding];\n const diff = +now - +from;\n const absDiff = Math.abs(diff);\n function getValue(diff2, unit) {\n return roundFn(Math.abs(diff2) / unit.value);\n }\n function format(diff2, unit) {\n const val = getValue(diff2, unit);\n const past = diff2 > 0;\n const str = applyFormat(unit.name, val, past);\n return applyFormat(past ? \"past\" : \"future\", str, past);\n }\n function applyFormat(name, val, isPast) {\n const formatter = messages[name];\n if (typeof formatter === \"function\")\n return formatter(val, isPast);\n return formatter.replace(\"{0}\", val.toString());\n }\n if (absDiff < 6e4 && !showSecond)\n return messages.justNow;\n if (typeof max === \"number\" && absDiff > max)\n return fullDateFormatter(new Date(from));\n if (typeof max === \"string\") {\n const unitMax = (_a = units.find((i) => i.name === max)) == null ? void 0 : _a.max;\n if (unitMax && absDiff > unitMax)\n return fullDateFormatter(new Date(from));\n }\n for (const [idx, unit] of units.entries()) {\n const val = getValue(diff, unit);\n if (val <= 0 && units[idx - 1])\n return format(diff, units[idx - 1]);\n if (absDiff < unit.max)\n return format(diff, unit);\n }\n return messages.invalid;\n}\n\nfunction useTimeoutPoll(fn, interval, options = {}) {\n const {\n immediate = true,\n immediateCallback = false\n } = options;\n const { start } = useTimeoutFn(loop, interval, { immediate });\n const isActive = shallowRef(false);\n async function loop() {\n if (!isActive.value)\n return;\n await fn();\n start();\n }\n function resume() {\n if (!isActive.value) {\n isActive.value = true;\n if (immediateCallback)\n fn();\n start();\n }\n }\n function pause() {\n isActive.value = false;\n }\n if (immediate && isClient)\n resume();\n tryOnScopeDispose(pause);\n return {\n isActive,\n pause,\n resume\n };\n}\n\nfunction useTimestamp(options = {}) {\n const {\n controls: exposeControls = false,\n offset = 0,\n immediate = true,\n interval = \"requestAnimationFrame\",\n callback\n } = options;\n const ts = shallowRef(timestamp() + offset);\n const update = () => ts.value = timestamp() + offset;\n const cb = callback ? () => {\n update();\n callback(ts.value);\n } : update;\n const controls = interval === \"requestAnimationFrame\" ? useRafFn(cb, { immediate }) : useIntervalFn(cb, interval, { immediate });\n if (exposeControls) {\n return {\n timestamp: ts,\n ...controls\n };\n } else {\n return ts;\n }\n}\n\nfunction useTitle(newTitle = null, options = {}) {\n var _a, _b, _c;\n const {\n document = defaultDocument,\n restoreOnUnmount = (t) => t\n } = options;\n const originalTitle = (_a = document == null ? void 0 : document.title) != null ? _a : \"\";\n const title = toRef((_b = newTitle != null ? newTitle : document == null ? void 0 : document.title) != null ? _b : null);\n const isReadonly = !!(newTitle && typeof newTitle === \"function\");\n function format(t) {\n if (!(\"titleTemplate\" in options))\n return t;\n const template = options.titleTemplate || \"%s\";\n return typeof template === \"function\" ? template(t) : toValue(template).replace(/%s/g, t);\n }\n watch(\n title,\n (newValue, oldValue) => {\n if (newValue !== oldValue && document)\n document.title = format(newValue != null ? newValue : \"\");\n },\n { immediate: true }\n );\n if (options.observe && !options.titleTemplate && document && !isReadonly) {\n useMutationObserver(\n (_c = document.head) == null ? void 0 : _c.querySelector(\"title\"),\n () => {\n if (document && document.title !== title.value)\n title.value = format(document.title);\n },\n { childList: true }\n );\n }\n tryOnScopeDispose(() => {\n if (restoreOnUnmount) {\n const restoredTitle = restoreOnUnmount(originalTitle, title.value || \"\");\n if (restoredTitle != null && document)\n document.title = restoredTitle;\n }\n });\n return title;\n}\n\nconst _TransitionPresets = {\n easeInSine: [0.12, 0, 0.39, 0],\n easeOutSine: [0.61, 1, 0.88, 1],\n easeInOutSine: [0.37, 0, 0.63, 1],\n easeInQuad: [0.11, 0, 0.5, 0],\n easeOutQuad: [0.5, 1, 0.89, 1],\n easeInOutQuad: [0.45, 0, 0.55, 1],\n easeInCubic: [0.32, 0, 0.67, 0],\n easeOutCubic: [0.33, 1, 0.68, 1],\n easeInOutCubic: [0.65, 0, 0.35, 1],\n easeInQuart: [0.5, 0, 0.75, 0],\n easeOutQuart: [0.25, 1, 0.5, 1],\n easeInOutQuart: [0.76, 0, 0.24, 1],\n easeInQuint: [0.64, 0, 0.78, 0],\n easeOutQuint: [0.22, 1, 0.36, 1],\n easeInOutQuint: [0.83, 0, 0.17, 1],\n easeInExpo: [0.7, 0, 0.84, 0],\n easeOutExpo: [0.16, 1, 0.3, 1],\n easeInOutExpo: [0.87, 0, 0.13, 1],\n easeInCirc: [0.55, 0, 1, 0.45],\n easeOutCirc: [0, 0.55, 0.45, 1],\n easeInOutCirc: [0.85, 0, 0.15, 1],\n easeInBack: [0.36, 0, 0.66, -0.56],\n easeOutBack: [0.34, 1.56, 0.64, 1],\n easeInOutBack: [0.68, -0.6, 0.32, 1.6]\n};\nconst TransitionPresets = /* @__PURE__ */ Object.assign({}, { linear: identity }, _TransitionPresets);\nfunction createEasingFunction([p0, p1, p2, p3]) {\n const a = (a1, a2) => 1 - 3 * a2 + 3 * a1;\n const b = (a1, a2) => 3 * a2 - 6 * a1;\n const c = (a1) => 3 * a1;\n const calcBezier = (t, a1, a2) => ((a(a1, a2) * t + b(a1, a2)) * t + c(a1)) * t;\n const getSlope = (t, a1, a2) => 3 * a(a1, a2) * t * t + 2 * b(a1, a2) * t + c(a1);\n const getTforX = (x) => {\n let aGuessT = x;\n for (let i = 0; i < 4; ++i) {\n const currentSlope = getSlope(aGuessT, p0, p2);\n if (currentSlope === 0)\n return aGuessT;\n const currentX = calcBezier(aGuessT, p0, p2) - x;\n aGuessT -= currentX / currentSlope;\n }\n return aGuessT;\n };\n return (x) => p0 === p1 && p2 === p3 ? x : calcBezier(getTforX(x), p1, p3);\n}\nfunction lerp(a, b, alpha) {\n return a + alpha * (b - a);\n}\nfunction toVec(t) {\n return (typeof t === \"number\" ? [t] : t) || [];\n}\nfunction executeTransition(source, from, to, options = {}) {\n var _a, _b;\n const fromVal = toValue(from);\n const toVal = toValue(to);\n const v1 = toVec(fromVal);\n const v2 = toVec(toVal);\n const duration = (_a = toValue(options.duration)) != null ? _a : 1e3;\n const startedAt = Date.now();\n const endAt = Date.now() + duration;\n const trans = typeof options.transition === \"function\" ? options.transition : (_b = toValue(options.transition)) != null ? _b : identity;\n const ease = typeof trans === \"function\" ? trans : createEasingFunction(trans);\n return new Promise((resolve) => {\n source.value = fromVal;\n const tick = () => {\n var _a2;\n if ((_a2 = options.abort) == null ? void 0 : _a2.call(options)) {\n resolve();\n return;\n }\n const now = Date.now();\n const alpha = ease((now - startedAt) / duration);\n const arr = toVec(source.value).map((n, i) => lerp(v1[i], v2[i], alpha));\n if (Array.isArray(source.value))\n source.value = arr.map((n, i) => {\n var _a3, _b2;\n return lerp((_a3 = v1[i]) != null ? _a3 : 0, (_b2 = v2[i]) != null ? _b2 : 0, alpha);\n });\n else if (typeof source.value === \"number\")\n source.value = arr[0];\n if (now < endAt) {\n requestAnimationFrame(tick);\n } else {\n source.value = toVal;\n resolve();\n }\n };\n tick();\n });\n}\nfunction useTransition(source, options = {}) {\n let currentId = 0;\n const sourceVal = () => {\n const v = toValue(source);\n return typeof v === \"number\" ? v : v.map(toValue);\n };\n const outputRef = ref(sourceVal());\n watch(sourceVal, async (to) => {\n var _a, _b;\n if (toValue(options.disabled))\n return;\n const id = ++currentId;\n if (options.delay)\n await promiseTimeout(toValue(options.delay));\n if (id !== currentId)\n return;\n const toVal = Array.isArray(to) ? to.map(toValue) : toValue(to);\n (_a = options.onStarted) == null ? void 0 : _a.call(options);\n await executeTransition(outputRef, outputRef.value, toVal, {\n ...options,\n abort: () => {\n var _a2;\n return id !== currentId || ((_a2 = options.abort) == null ? void 0 : _a2.call(options));\n }\n });\n (_b = options.onFinished) == null ? void 0 : _b.call(options);\n }, { deep: true });\n watch(() => toValue(options.disabled), (disabled) => {\n if (disabled) {\n currentId++;\n outputRef.value = sourceVal();\n }\n });\n tryOnScopeDispose(() => {\n currentId++;\n });\n return computed(() => toValue(options.disabled) ? sourceVal() : outputRef.value);\n}\n\nfunction useUrlSearchParams(mode = \"history\", options = {}) {\n const {\n initialValue = {},\n removeNullishValues = true,\n removeFalsyValues = false,\n write: enableWrite = true,\n writeMode = \"replace\",\n window = defaultWindow\n } = options;\n if (!window)\n return reactive(initialValue);\n const state = reactive({});\n function getRawParams() {\n if (mode === \"history\") {\n return window.location.search || \"\";\n } else if (mode === \"hash\") {\n const hash = window.location.hash || \"\";\n const index = hash.indexOf(\"?\");\n return index > 0 ? hash.slice(index) : \"\";\n } else {\n return (window.location.hash || \"\").replace(/^#/, \"\");\n }\n }\n function constructQuery(params) {\n const stringified = params.toString();\n if (mode === \"history\")\n return `${stringified ? `?${stringified}` : \"\"}${window.location.hash || \"\"}`;\n if (mode === \"hash-params\")\n return `${window.location.search || \"\"}${stringified ? `#${stringified}` : \"\"}`;\n const hash = window.location.hash || \"#\";\n const index = hash.indexOf(\"?\");\n if (index > 0)\n return `${window.location.search || \"\"}${hash.slice(0, index)}${stringified ? `?${stringified}` : \"\"}`;\n return `${window.location.search || \"\"}${hash}${stringified ? `?${stringified}` : \"\"}`;\n }\n function read() {\n return new URLSearchParams(getRawParams());\n }\n function updateState(params) {\n const unusedKeys = new Set(Object.keys(state));\n for (const key of params.keys()) {\n const paramsForKey = params.getAll(key);\n state[key] = paramsForKey.length > 1 ? paramsForKey : params.get(key) || \"\";\n unusedKeys.delete(key);\n }\n Array.from(unusedKeys).forEach((key) => delete state[key]);\n }\n const { pause, resume } = pausableWatch(\n state,\n () => {\n const params = new URLSearchParams(\"\");\n Object.keys(state).forEach((key) => {\n const mapEntry = state[key];\n if (Array.isArray(mapEntry))\n mapEntry.forEach((value) => params.append(key, value));\n else if (removeNullishValues && mapEntry == null)\n params.delete(key);\n else if (removeFalsyValues && !mapEntry)\n params.delete(key);\n else\n params.set(key, mapEntry);\n });\n write(params, false);\n },\n { deep: true }\n );\n function write(params, shouldUpdate) {\n pause();\n if (shouldUpdate)\n updateState(params);\n if (writeMode === \"replace\") {\n window.history.replaceState(\n window.history.state,\n window.document.title,\n window.location.pathname + constructQuery(params)\n );\n } else {\n window.history.pushState(\n window.history.state,\n window.document.title,\n window.location.pathname + constructQuery(params)\n );\n }\n resume();\n }\n function onChanged() {\n if (!enableWrite)\n return;\n write(read(), true);\n }\n const listenerOptions = { passive: true };\n useEventListener(window, \"popstate\", onChanged, listenerOptions);\n if (mode !== \"history\")\n useEventListener(window, \"hashchange\", onChanged, listenerOptions);\n const initial = read();\n if (initial.keys().next().value)\n updateState(initial);\n else\n Object.assign(state, initialValue);\n return state;\n}\n\nfunction useUserMedia(options = {}) {\n var _a, _b;\n const enabled = shallowRef((_a = options.enabled) != null ? _a : false);\n const autoSwitch = shallowRef((_b = options.autoSwitch) != null ? _b : true);\n const constraints = ref(options.constraints);\n const { navigator = defaultNavigator } = options;\n const isSupported = useSupported(() => {\n var _a2;\n return (_a2 = navigator == null ? void 0 : navigator.mediaDevices) == null ? void 0 : _a2.getUserMedia;\n });\n const stream = shallowRef();\n function getDeviceOptions(type) {\n switch (type) {\n case \"video\": {\n if (constraints.value)\n return constraints.value.video || false;\n break;\n }\n case \"audio\": {\n if (constraints.value)\n return constraints.value.audio || false;\n break;\n }\n }\n }\n async function _start() {\n if (!isSupported.value || stream.value)\n return;\n stream.value = await navigator.mediaDevices.getUserMedia({\n video: getDeviceOptions(\"video\"),\n audio: getDeviceOptions(\"audio\")\n });\n return stream.value;\n }\n function _stop() {\n var _a2;\n (_a2 = stream.value) == null ? void 0 : _a2.getTracks().forEach((t) => t.stop());\n stream.value = void 0;\n }\n function stop() {\n _stop();\n enabled.value = false;\n }\n async function start() {\n await _start();\n if (stream.value)\n enabled.value = true;\n return stream.value;\n }\n async function restart() {\n _stop();\n return await start();\n }\n watch(\n enabled,\n (v) => {\n if (v)\n _start();\n else _stop();\n },\n { immediate: true }\n );\n watch(\n constraints,\n () => {\n if (autoSwitch.value && stream.value)\n restart();\n },\n { immediate: true }\n );\n tryOnScopeDispose(() => {\n stop();\n });\n return {\n isSupported,\n stream,\n start,\n stop,\n restart,\n constraints,\n enabled,\n autoSwitch\n };\n}\n\nfunction useVModel(props, key, emit, options = {}) {\n var _a, _b, _c;\n const {\n clone = false,\n passive = false,\n eventName,\n deep = false,\n defaultValue,\n shouldEmit\n } = options;\n const vm = getCurrentInstance();\n const _emit = emit || (vm == null ? void 0 : vm.emit) || ((_a = vm == null ? void 0 : vm.$emit) == null ? void 0 : _a.bind(vm)) || ((_c = (_b = vm == null ? void 0 : vm.proxy) == null ? void 0 : _b.$emit) == null ? void 0 : _c.bind(vm == null ? void 0 : vm.proxy));\n let event = eventName;\n if (!key) {\n key = \"modelValue\";\n }\n event = event || `update:${key.toString()}`;\n const cloneFn = (val) => !clone ? val : typeof clone === \"function\" ? clone(val) : cloneFnJSON(val);\n const getValue = () => isDef(props[key]) ? cloneFn(props[key]) : defaultValue;\n const triggerEmit = (value) => {\n if (shouldEmit) {\n if (shouldEmit(value))\n _emit(event, value);\n } else {\n _emit(event, value);\n }\n };\n if (passive) {\n const initialValue = getValue();\n const proxy = ref(initialValue);\n let isUpdating = false;\n watch(\n () => props[key],\n (v) => {\n if (!isUpdating) {\n isUpdating = true;\n proxy.value = cloneFn(v);\n nextTick(() => isUpdating = false);\n }\n }\n );\n watch(\n proxy,\n (v) => {\n if (!isUpdating && (v !== props[key] || deep))\n triggerEmit(v);\n },\n { deep }\n );\n return proxy;\n } else {\n return computed({\n get() {\n return getValue();\n },\n set(value) {\n triggerEmit(value);\n }\n });\n }\n}\n\nfunction useVModels(props, emit, options = {}) {\n const ret = {};\n for (const key in props) {\n ret[key] = useVModel(\n props,\n key,\n emit,\n options\n );\n }\n return ret;\n}\n\nfunction useVibrate(options) {\n const {\n pattern = [],\n interval = 0,\n navigator = defaultNavigator\n } = options || {};\n const isSupported = useSupported(() => typeof navigator !== \"undefined\" && \"vibrate\" in navigator);\n const patternRef = toRef(pattern);\n let intervalControls;\n const vibrate = (pattern2 = patternRef.value) => {\n if (isSupported.value)\n navigator.vibrate(pattern2);\n };\n const stop = () => {\n if (isSupported.value)\n navigator.vibrate(0);\n intervalControls == null ? void 0 : intervalControls.pause();\n };\n if (interval > 0) {\n intervalControls = useIntervalFn(\n vibrate,\n interval,\n {\n immediate: false,\n immediateCallback: false\n }\n );\n }\n return {\n isSupported,\n pattern,\n intervalControls,\n vibrate,\n stop\n };\n}\n\nfunction useVirtualList(list, options) {\n const { containerStyle, wrapperProps, scrollTo, calculateRange, currentList, containerRef } = \"itemHeight\" in options ? useVerticalVirtualList(options, list) : useHorizontalVirtualList(options, list);\n return {\n list: currentList,\n scrollTo,\n containerProps: {\n ref: containerRef,\n onScroll: () => {\n calculateRange();\n },\n style: containerStyle\n },\n wrapperProps\n };\n}\nfunction useVirtualListResources(list) {\n const containerRef = shallowRef(null);\n const size = useElementSize(containerRef);\n const currentList = ref([]);\n const source = shallowRef(list);\n const state = ref({ start: 0, end: 10 });\n return { state, source, currentList, size, containerRef };\n}\nfunction createGetViewCapacity(state, source, itemSize) {\n return (containerSize) => {\n if (typeof itemSize === \"number\")\n return Math.ceil(containerSize / itemSize);\n const { start = 0 } = state.value;\n let sum = 0;\n let capacity = 0;\n for (let i = start; i < source.value.length; i++) {\n const size = itemSize(i);\n sum += size;\n capacity = i;\n if (sum > containerSize)\n break;\n }\n return capacity - start;\n };\n}\nfunction createGetOffset(source, itemSize) {\n return (scrollDirection) => {\n if (typeof itemSize === \"number\")\n return Math.floor(scrollDirection / itemSize) + 1;\n let sum = 0;\n let offset = 0;\n for (let i = 0; i < source.value.length; i++) {\n const size = itemSize(i);\n sum += size;\n if (sum >= scrollDirection) {\n offset = i;\n break;\n }\n }\n return offset + 1;\n };\n}\nfunction createCalculateRange(type, overscan, getOffset, getViewCapacity, { containerRef, state, currentList, source }) {\n return () => {\n const element = containerRef.value;\n if (element) {\n const offset = getOffset(type === \"vertical\" ? element.scrollTop : element.scrollLeft);\n const viewCapacity = getViewCapacity(type === \"vertical\" ? element.clientHeight : element.clientWidth);\n const from = offset - overscan;\n const to = offset + viewCapacity + overscan;\n state.value = {\n start: from < 0 ? 0 : from,\n end: to > source.value.length ? source.value.length : to\n };\n currentList.value = source.value.slice(state.value.start, state.value.end).map((ele, index) => ({\n data: ele,\n index: index + state.value.start\n }));\n }\n };\n}\nfunction createGetDistance(itemSize, source) {\n return (index) => {\n if (typeof itemSize === \"number\") {\n const size2 = index * itemSize;\n return size2;\n }\n const size = source.value.slice(0, index).reduce((sum, _, i) => sum + itemSize(i), 0);\n return size;\n };\n}\nfunction useWatchForSizes(size, list, containerRef, calculateRange) {\n watch([size.width, size.height, list, containerRef], () => {\n calculateRange();\n });\n}\nfunction createComputedTotalSize(itemSize, source) {\n return computed(() => {\n if (typeof itemSize === \"number\")\n return source.value.length * itemSize;\n return source.value.reduce((sum, _, index) => sum + itemSize(index), 0);\n });\n}\nconst scrollToDictionaryForElementScrollKey = {\n horizontal: \"scrollLeft\",\n vertical: \"scrollTop\"\n};\nfunction createScrollTo(type, calculateRange, getDistance, containerRef) {\n return (index) => {\n if (containerRef.value) {\n containerRef.value[scrollToDictionaryForElementScrollKey[type]] = getDistance(index);\n calculateRange();\n }\n };\n}\nfunction useHorizontalVirtualList(options, list) {\n const resources = useVirtualListResources(list);\n const { state, source, currentList, size, containerRef } = resources;\n const containerStyle = { overflowX: \"auto\" };\n const { itemWidth, overscan = 5 } = options;\n const getViewCapacity = createGetViewCapacity(state, source, itemWidth);\n const getOffset = createGetOffset(source, itemWidth);\n const calculateRange = createCalculateRange(\"horizontal\", overscan, getOffset, getViewCapacity, resources);\n const getDistanceLeft = createGetDistance(itemWidth, source);\n const offsetLeft = computed(() => getDistanceLeft(state.value.start));\n const totalWidth = createComputedTotalSize(itemWidth, source);\n useWatchForSizes(size, list, containerRef, calculateRange);\n const scrollTo = createScrollTo(\"horizontal\", calculateRange, getDistanceLeft, containerRef);\n const wrapperProps = computed(() => {\n return {\n style: {\n height: \"100%\",\n width: `${totalWidth.value - offsetLeft.value}px`,\n marginLeft: `${offsetLeft.value}px`,\n display: \"flex\"\n }\n };\n });\n return {\n scrollTo,\n calculateRange,\n wrapperProps,\n containerStyle,\n currentList,\n containerRef\n };\n}\nfunction useVerticalVirtualList(options, list) {\n const resources = useVirtualListResources(list);\n const { state, source, currentList, size, containerRef } = resources;\n const containerStyle = { overflowY: \"auto\" };\n const { itemHeight, overscan = 5 } = options;\n const getViewCapacity = createGetViewCapacity(state, source, itemHeight);\n const getOffset = createGetOffset(source, itemHeight);\n const calculateRange = createCalculateRange(\"vertical\", overscan, getOffset, getViewCapacity, resources);\n const getDistanceTop = createGetDistance(itemHeight, source);\n const offsetTop = computed(() => getDistanceTop(state.value.start));\n const totalHeight = createComputedTotalSize(itemHeight, source);\n useWatchForSizes(size, list, containerRef, calculateRange);\n const scrollTo = createScrollTo(\"vertical\", calculateRange, getDistanceTop, containerRef);\n const wrapperProps = computed(() => {\n return {\n style: {\n width: \"100%\",\n height: `${totalHeight.value - offsetTop.value}px`,\n marginTop: `${offsetTop.value}px`\n }\n };\n });\n return {\n calculateRange,\n scrollTo,\n containerStyle,\n wrapperProps,\n currentList,\n containerRef\n };\n}\n\nfunction useWakeLock(options = {}) {\n const {\n navigator = defaultNavigator,\n document = defaultDocument\n } = options;\n const requestedType = shallowRef(false);\n const sentinel = shallowRef(null);\n const documentVisibility = useDocumentVisibility({ document });\n const isSupported = useSupported(() => navigator && \"wakeLock\" in navigator);\n const isActive = computed(() => !!sentinel.value && documentVisibility.value === \"visible\");\n if (isSupported.value) {\n useEventListener(sentinel, \"release\", () => {\n var _a, _b;\n requestedType.value = (_b = (_a = sentinel.value) == null ? void 0 : _a.type) != null ? _b : false;\n }, { passive: true });\n whenever(\n () => documentVisibility.value === \"visible\" && (document == null ? void 0 : document.visibilityState) === \"visible\" && requestedType.value,\n (type) => {\n requestedType.value = false;\n forceRequest(type);\n }\n );\n }\n async function forceRequest(type) {\n var _a;\n await ((_a = sentinel.value) == null ? void 0 : _a.release());\n sentinel.value = isSupported.value ? await navigator.wakeLock.request(type) : null;\n }\n async function request(type) {\n if (documentVisibility.value === \"visible\")\n await forceRequest(type);\n else\n requestedType.value = type;\n }\n async function release() {\n requestedType.value = false;\n const s = sentinel.value;\n sentinel.value = null;\n await (s == null ? void 0 : s.release());\n }\n return {\n sentinel,\n isSupported,\n isActive,\n request,\n forceRequest,\n release\n };\n}\n\nfunction useWebNotification(options = {}) {\n const {\n window = defaultWindow,\n requestPermissions: _requestForPermissions = true\n } = options;\n const defaultWebNotificationOptions = options;\n const isSupported = useSupported(() => {\n if (!window || !(\"Notification\" in window))\n return false;\n if (Notification.permission === \"granted\")\n return true;\n try {\n const notification2 = new Notification(\"\");\n notification2.onshow = () => {\n notification2.close();\n };\n } catch (e) {\n if (e.name === \"TypeError\")\n return false;\n }\n return true;\n });\n const permissionGranted = shallowRef(isSupported.value && \"permission\" in Notification && Notification.permission === \"granted\");\n const notification = ref(null);\n const ensurePermissions = async () => {\n if (!isSupported.value)\n return;\n if (!permissionGranted.value && Notification.permission !== \"denied\") {\n const result = await Notification.requestPermission();\n if (result === \"granted\")\n permissionGranted.value = true;\n }\n return permissionGranted.value;\n };\n const { on: onClick, trigger: clickTrigger } = createEventHook();\n const { on: onShow, trigger: showTrigger } = createEventHook();\n const { on: onError, trigger: errorTrigger } = createEventHook();\n const { on: onClose, trigger: closeTrigger } = createEventHook();\n const show = async (overrides) => {\n if (!isSupported.value || !permissionGranted.value)\n return;\n const options2 = Object.assign({}, defaultWebNotificationOptions, overrides);\n notification.value = new Notification(options2.title || \"\", options2);\n notification.value.onclick = clickTrigger;\n notification.value.onshow = showTrigger;\n notification.value.onerror = errorTrigger;\n notification.value.onclose = closeTrigger;\n return notification.value;\n };\n const close = () => {\n if (notification.value)\n notification.value.close();\n notification.value = null;\n };\n if (_requestForPermissions)\n tryOnMounted(ensurePermissions);\n tryOnScopeDispose(close);\n if (isSupported.value && window) {\n const document = window.document;\n useEventListener(document, \"visibilitychange\", (e) => {\n e.preventDefault();\n if (document.visibilityState === \"visible\") {\n close();\n }\n });\n }\n return {\n isSupported,\n notification,\n ensurePermissions,\n permissionGranted,\n show,\n close,\n onClick,\n onShow,\n onError,\n onClose\n };\n}\n\nconst DEFAULT_PING_MESSAGE = \"ping\";\nfunction resolveNestedOptions(options) {\n if (options === true)\n return {};\n return options;\n}\nfunction useWebSocket(url, options = {}) {\n const {\n onConnected,\n onDisconnected,\n onError,\n onMessage,\n immediate = true,\n autoConnect = true,\n autoClose = true,\n protocols = []\n } = options;\n const data = ref(null);\n const status = shallowRef(\"CLOSED\");\n const wsRef = ref();\n const urlRef = toRef(url);\n let heartbeatPause;\n let heartbeatResume;\n let explicitlyClosed = false;\n let retried = 0;\n let bufferedData = [];\n let retryTimeout;\n let pongTimeoutWait;\n const _sendBuffer = () => {\n if (bufferedData.length && wsRef.value && status.value === \"OPEN\") {\n for (const buffer of bufferedData)\n wsRef.value.send(buffer);\n bufferedData = [];\n }\n };\n const resetRetry = () => {\n if (retryTimeout != null) {\n clearTimeout(retryTimeout);\n retryTimeout = void 0;\n }\n };\n const resetHeartbeat = () => {\n clearTimeout(pongTimeoutWait);\n pongTimeoutWait = void 0;\n };\n const close = (code = 1e3, reason) => {\n resetRetry();\n if (!isClient && !isWorker || !wsRef.value)\n return;\n explicitlyClosed = true;\n resetHeartbeat();\n heartbeatPause == null ? void 0 : heartbeatPause();\n wsRef.value.close(code, reason);\n wsRef.value = void 0;\n };\n const send = (data2, useBuffer = true) => {\n if (!wsRef.value || status.value !== \"OPEN\") {\n if (useBuffer)\n bufferedData.push(data2);\n return false;\n }\n _sendBuffer();\n wsRef.value.send(data2);\n return true;\n };\n const _init = () => {\n if (explicitlyClosed || typeof urlRef.value === \"undefined\")\n return;\n const ws = new WebSocket(urlRef.value, protocols);\n wsRef.value = ws;\n status.value = \"CONNECTING\";\n ws.onopen = () => {\n status.value = \"OPEN\";\n retried = 0;\n onConnected == null ? void 0 : onConnected(ws);\n heartbeatResume == null ? void 0 : heartbeatResume();\n _sendBuffer();\n };\n ws.onclose = (ev) => {\n status.value = \"CLOSED\";\n resetHeartbeat();\n heartbeatPause == null ? void 0 : heartbeatPause();\n onDisconnected == null ? void 0 : onDisconnected(ws, ev);\n if (!explicitlyClosed && options.autoReconnect && (wsRef.value == null || ws === wsRef.value)) {\n const {\n retries = -1,\n delay = 1e3,\n onFailed\n } = resolveNestedOptions(options.autoReconnect);\n const checkRetires = typeof retries === \"function\" ? retries : () => typeof retries === \"number\" && (retries < 0 || retried < retries);\n if (checkRetires(retried)) {\n retried += 1;\n retryTimeout = setTimeout(_init, delay);\n } else {\n onFailed == null ? void 0 : onFailed();\n }\n }\n };\n ws.onerror = (e) => {\n onError == null ? void 0 : onError(ws, e);\n };\n ws.onmessage = (e) => {\n if (options.heartbeat) {\n resetHeartbeat();\n const {\n message = DEFAULT_PING_MESSAGE,\n responseMessage = message\n } = resolveNestedOptions(options.heartbeat);\n if (e.data === toValue(responseMessage))\n return;\n }\n data.value = e.data;\n onMessage == null ? void 0 : onMessage(ws, e);\n };\n };\n if (options.heartbeat) {\n const {\n message = DEFAULT_PING_MESSAGE,\n interval = 1e3,\n pongTimeout = 1e3\n } = resolveNestedOptions(options.heartbeat);\n const { pause, resume } = useIntervalFn(\n () => {\n send(toValue(message), false);\n if (pongTimeoutWait != null)\n return;\n pongTimeoutWait = setTimeout(() => {\n close();\n explicitlyClosed = false;\n }, pongTimeout);\n },\n interval,\n { immediate: false }\n );\n heartbeatPause = pause;\n heartbeatResume = resume;\n }\n if (autoClose) {\n if (isClient)\n useEventListener(\"beforeunload\", () => close(), { passive: true });\n tryOnScopeDispose(close);\n }\n const open = () => {\n if (!isClient && !isWorker)\n return;\n close();\n explicitlyClosed = false;\n retried = 0;\n _init();\n };\n if (immediate)\n open();\n if (autoConnect)\n watch(urlRef, open);\n return {\n data,\n status,\n close,\n send,\n open,\n ws: wsRef\n };\n}\n\nfunction useWebWorker(arg0, workerOptions, options) {\n const {\n window = defaultWindow\n } = options != null ? options : {};\n const data = ref(null);\n const worker = shallowRef();\n const post = (...args) => {\n if (!worker.value)\n return;\n worker.value.postMessage(...args);\n };\n const terminate = function terminate2() {\n if (!worker.value)\n return;\n worker.value.terminate();\n };\n if (window) {\n if (typeof arg0 === \"string\")\n worker.value = new Worker(arg0, workerOptions);\n else if (typeof arg0 === \"function\")\n worker.value = arg0();\n else\n worker.value = arg0;\n worker.value.onmessage = (e) => {\n data.value = e.data;\n };\n tryOnScopeDispose(() => {\n if (worker.value)\n worker.value.terminate();\n });\n }\n return {\n data,\n post,\n terminate,\n worker\n };\n}\n\nfunction depsParser(deps, localDeps) {\n if (deps.length === 0 && localDeps.length === 0)\n return \"\";\n const depsString = deps.map((dep) => `'${dep}'`).toString();\n const depsFunctionString = localDeps.filter((dep) => typeof dep === \"function\").map((fn) => {\n const str = fn.toString();\n if (str.trim().startsWith(\"function\")) {\n return str;\n } else {\n const name = fn.name;\n return `const ${name} = ${str}`;\n }\n }).join(\";\");\n const importString = `importScripts(${depsString});`;\n return `${depsString.trim() === \"\" ? \"\" : importString} ${depsFunctionString}`;\n}\n\nfunction jobRunner(userFunc) {\n return (e) => {\n const userFuncArgs = e.data[0];\n return Promise.resolve(userFunc.apply(void 0, userFuncArgs)).then((result) => {\n postMessage([\"SUCCESS\", result]);\n }).catch((error) => {\n postMessage([\"ERROR\", error]);\n });\n };\n}\n\nfunction createWorkerBlobUrl(fn, deps, localDeps) {\n const blobCode = `${depsParser(deps, localDeps)}; onmessage=(${jobRunner})(${fn})`;\n const blob = new Blob([blobCode], { type: \"text/javascript\" });\n const url = URL.createObjectURL(blob);\n return url;\n}\n\nfunction useWebWorkerFn(fn, options = {}) {\n const {\n dependencies = [],\n localDependencies = [],\n timeout,\n window = defaultWindow\n } = options;\n const worker = ref();\n const workerStatus = shallowRef(\"PENDING\");\n const promise = ref({});\n const timeoutId = shallowRef();\n const workerTerminate = (status = \"PENDING\") => {\n if (worker.value && worker.value._url && window) {\n worker.value.terminate();\n URL.revokeObjectURL(worker.value._url);\n promise.value = {};\n worker.value = void 0;\n window.clearTimeout(timeoutId.value);\n workerStatus.value = status;\n }\n };\n workerTerminate();\n tryOnScopeDispose(workerTerminate);\n const generateWorker = () => {\n const blobUrl = createWorkerBlobUrl(fn, dependencies, localDependencies);\n const newWorker = new Worker(blobUrl);\n newWorker._url = blobUrl;\n newWorker.onmessage = (e) => {\n const { resolve = () => {\n }, reject = () => {\n } } = promise.value;\n const [status, result] = e.data;\n switch (status) {\n case \"SUCCESS\":\n resolve(result);\n workerTerminate(status);\n break;\n default:\n reject(result);\n workerTerminate(\"ERROR\");\n break;\n }\n };\n newWorker.onerror = (e) => {\n const { reject = () => {\n } } = promise.value;\n e.preventDefault();\n reject(e);\n workerTerminate(\"ERROR\");\n };\n if (timeout) {\n timeoutId.value = setTimeout(\n () => workerTerminate(\"TIMEOUT_EXPIRED\"),\n timeout\n );\n }\n return newWorker;\n };\n const callWorker = (...fnArgs) => new Promise((resolve, reject) => {\n var _a;\n promise.value = {\n resolve,\n reject\n };\n (_a = worker.value) == null ? void 0 : _a.postMessage([[...fnArgs]]);\n workerStatus.value = \"RUNNING\";\n });\n const workerFn = (...fnArgs) => {\n if (workerStatus.value === \"RUNNING\") {\n console.error(\n \"[useWebWorkerFn] You can only run one instance of the worker at a time.\"\n );\n return Promise.reject();\n }\n worker.value = generateWorker();\n return callWorker(...fnArgs);\n };\n return {\n workerFn,\n workerStatus,\n workerTerminate\n };\n}\n\nfunction useWindowFocus(options = {}) {\n const { window = defaultWindow } = options;\n if (!window)\n return shallowRef(false);\n const focused = shallowRef(window.document.hasFocus());\n const listenerOptions = { passive: true };\n useEventListener(window, \"blur\", () => {\n focused.value = false;\n }, listenerOptions);\n useEventListener(window, \"focus\", () => {\n focused.value = true;\n }, listenerOptions);\n return focused;\n}\n\nfunction useWindowScroll(options = {}) {\n const { window = defaultWindow, ...rest } = options;\n return useScroll(window, rest);\n}\n\nfunction useWindowSize(options = {}) {\n const {\n window = defaultWindow,\n initialWidth = Number.POSITIVE_INFINITY,\n initialHeight = Number.POSITIVE_INFINITY,\n listenOrientation = true,\n includeScrollbar = true,\n type = \"inner\"\n } = options;\n const width = shallowRef(initialWidth);\n const height = shallowRef(initialHeight);\n const update = () => {\n if (window) {\n if (type === \"outer\") {\n width.value = window.outerWidth;\n height.value = window.outerHeight;\n } else if (type === \"visual\" && window.visualViewport) {\n const { width: visualViewportWidth, height: visualViewportHeight, scale } = window.visualViewport;\n width.value = Math.round(visualViewportWidth * scale);\n height.value = Math.round(visualViewportHeight * scale);\n } else if (includeScrollbar) {\n width.value = window.innerWidth;\n height.value = window.innerHeight;\n } else {\n width.value = window.document.documentElement.clientWidth;\n height.value = window.document.documentElement.clientHeight;\n }\n }\n };\n update();\n tryOnMounted(update);\n const listenerOptions = { passive: true };\n useEventListener(\"resize\", update, listenerOptions);\n if (window && type === \"visual\" && window.visualViewport) {\n useEventListener(window.visualViewport, \"resize\", update, listenerOptions);\n }\n if (listenOrientation) {\n const matches = useMediaQuery(\"(orientation: portrait)\");\n watch(matches, () => update());\n }\n return { width, height };\n}\n\nexport { DefaultMagicKeysAliasMap, StorageSerializers, TransitionPresets, computedAsync as asyncComputed, breakpointsAntDesign, breakpointsBootstrapV5, breakpointsElement, breakpointsMasterCss, breakpointsPrimeFlex, breakpointsQuasar, breakpointsSematic, breakpointsTailwind, breakpointsVuetify, breakpointsVuetifyV2, breakpointsVuetifyV3, cloneFnJSON, computedAsync, computedInject, createFetch, createReusableTemplate, createTemplatePromise, createUnrefFn, customStorageEventName, defaultDocument, defaultLocation, defaultNavigator, defaultWindow, executeTransition, formatTimeAgo, getSSRHandler, mapGamepadToXbox360Controller, onClickOutside, onElementRemoval, onKeyDown, onKeyPressed, onKeyStroke, onKeyUp, onLongPress, onStartTyping, provideSSRWidth, setSSRHandler, templateRef, unrefElement, useActiveElement, useAnimate, useAsyncQueue, useAsyncState, useBase64, useBattery, useBluetooth, useBreakpoints, useBroadcastChannel, useBrowserLocation, useCached, useClipboard, useClipboardItems, useCloned, useColorMode, useConfirmDialog, useCountdown, useCssVar, useCurrentElement, useCycleList, useDark, useDebouncedRefHistory, useDeviceMotion, useDeviceOrientation, useDevicePixelRatio, useDevicesList, useDisplayMedia, useDocumentVisibility, useDraggable, useDropZone, useElementBounding, useElementByPoint, useElementHover, useElementSize, useElementVisibility, useEventBus, useEventListener, useEventSource, useEyeDropper, useFavicon, useFetch, useFileDialog, useFileSystemAccess, useFocus, useFocusWithin, useFps, useFullscreen, useGamepad, useGeolocation, useIdle, useImage, useInfiniteScroll, useIntersectionObserver, useKeyModifier, useLocalStorage, useMagicKeys, useManualRefHistory, useMediaControls, useMediaQuery, useMemoize, useMemory, useMounted, useMouse, useMouseInElement, useMousePressed, useMutationObserver, useNavigatorLanguage, useNetwork, useNow, useObjectUrl, useOffsetPagination, useOnline, usePageLeave, useParallax, useParentElement, usePerformanceObserver, usePermission, usePointer, usePointerLock, usePointerSwipe, usePreferredColorScheme, usePreferredContrast, usePreferredDark, usePreferredLanguages, usePreferredReducedMotion, usePreferredReducedTransparency, usePrevious, useRafFn, useRefHistory, useResizeObserver, useSSRWidth, useScreenOrientation, useScreenSafeArea, useScriptTag, useScroll, useScrollLock, useSessionStorage, useShare, useSorted, useSpeechRecognition, useSpeechSynthesis, useStepper, useStorage, useStorageAsync, useStyleTag, useSupported, useSwipe, useTemplateRefsList, useTextDirection, useTextSelection, useTextareaAutosize, useThrottledRefHistory, useTimeAgo, useTimeoutPoll, useTimestamp, useTitle, useTransition, useUrlSearchParams, useUserMedia, useVModel, useVModels, useVibrate, useVirtualList, useWakeLock, useWebNotification, useWebSocket, useWebWorker, useWebWorkerFn, useWindowFocus, useWindowScroll, useWindowSize };\n"], - "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,SAAS,cAAc,IAAI,SAAS;AAClC,MAAI;AACJ,QAAM,SAAS,WAAW;AAC1B,cAAY,MAAM;AAChB,WAAO,QAAQ,GAAG;AAAA,EACpB,GAAG;AAAA,IACD,GAAG;AAAA,IACH,QAAQ,KAAK,WAAW,OAAO,SAAS,QAAQ,UAAU,OAAO,KAAK;AAAA,EACxE,CAAC;AACD,SAAO,SAAS,MAAM;AACxB;AAEA,SAAS,oBAAoB,QAAQ,IAAI;AACvC,MAAI,IAAI;AACR,MAAI;AACJ,MAAI;AACJ,QAAM,QAAQ,WAAW,IAAI;AAC7B,QAAM,SAAS,MAAM;AACnB,UAAM,QAAQ;AACd,YAAQ;AAAA,EACV;AACA,QAAM,QAAQ,QAAQ,EAAE,OAAO,OAAO,CAAC;AACvC,QAAMA,OAAM,OAAO,OAAO,aAAa,KAAK,GAAG;AAC/C,QAAMC,OAAM,OAAO,OAAO,aAAa,SAAS,GAAG;AACnD,QAAM,SAAS,UAAU,CAAC,QAAQ,aAAa;AAC7C,YAAQ;AACR,cAAU;AACV,WAAO;AAAA,MACL,MAAM;AACJ,YAAI,MAAM,OAAO;AACf,cAAID,KAAI,CAAC;AACT,gBAAM,QAAQ;AAAA,QAChB;AACA,cAAM;AACN,eAAO;AAAA,MACT;AAAA,MACA,IAAI,IAAI;AACN,QAAAC,QAAO,OAAO,SAASA,KAAI,EAAE;AAAA,MAC/B;AAAA,IACF;AAAA,EACF,CAAC;AACD,MAAI,OAAO,aAAa,MAAM;AAC5B,WAAO,UAAU;AACnB,SAAO;AACT;AAEA,SAAS,kBAAkB,IAAI;AAC7B,MAAI,gBAAgB,GAAG;AACrB,mBAAe,EAAE;AACjB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB;AACzB,QAAM,MAAsB,oBAAI,IAAI;AACpC,QAAM,MAAM,CAAC,OAAO;AAClB,QAAI,OAAO,EAAE;AAAA,EACf;AACA,QAAM,QAAQ,MAAM;AAClB,QAAI,MAAM;AAAA,EACZ;AACA,QAAM,KAAK,CAAC,OAAO;AACjB,QAAI,IAAI,EAAE;AACV,UAAM,QAAQ,MAAM,IAAI,EAAE;AAC1B,sBAAkB,KAAK;AACvB,WAAO;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AACA,QAAM,UAAU,IAAI,SAAS;AAC3B,WAAO,QAAQ,IAAI,MAAM,KAAK,GAAG,EAAE,IAAI,CAAC,OAAO,GAAG,GAAG,IAAI,CAAC,CAAC;AAAA,EAC7D;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,cAAc;AACvC,MAAI,cAAc;AAClB,MAAI;AACJ,QAAM,QAAQ,YAAY,IAAI;AAC9B,SAAO,IAAI,SAAS;AAClB,QAAI,CAAC,aAAa;AAChB,cAAQ,MAAM,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC;AAC7C,oBAAc;AAAA,IAChB;AACA,WAAO;AAAA,EACT;AACF;AAEA,IAAM,wBAAwC,oBAAI,QAAQ;AAE1D,IAAM,cAAc,IAAI,SAAS;AAC/B,MAAI;AACJ,QAAM,MAAM,KAAK,CAAC;AAClB,QAAM,YAAY,KAAK,mBAAmB,MAAM,OAAO,SAAS,GAAG;AACnE,MAAI,YAAY,QAAQ,CAAC,oBAAoB;AAC3C,UAAM,IAAI,MAAM,qCAAqC;AACvD,MAAI,YAAY,sBAAsB,IAAI,QAAQ,KAAK,OAAO,sBAAsB,IAAI,QAAQ;AAC9F,WAAO,sBAAsB,IAAI,QAAQ,EAAE,GAAG;AAChD,SAAO,OAAO,GAAG,IAAI;AACvB;AAEA,IAAM,eAAe,CAAC,KAAK,UAAU;AACnC,MAAI;AACJ,QAAM,YAAY,KAAK,mBAAmB,MAAM,OAAO,SAAS,GAAG;AACnE,MAAI,YAAY;AACd,UAAM,IAAI,MAAM,sCAAsC;AACxD,MAAI,CAAC,sBAAsB,IAAI,QAAQ;AACrC,0BAAsB,IAAI,UAA0B,uBAAO,OAAO,IAAI,CAAC;AACzE,QAAM,qBAAqB,sBAAsB,IAAI,QAAQ;AAC7D,qBAAmB,GAAG,IAAI;AAC1B,UAAQ,KAAK,KAAK;AACpB;AAEA,SAAS,qBAAqB,YAAY,SAAS;AACjD,QAAM,OAAO,WAAW,OAAO,SAAS,QAAQ,iBAAiB,OAAO,WAAW,QAAQ,gBAAgB;AAC3G,QAAM,eAAe,WAAW,OAAO,SAAS,QAAQ;AACxD,QAAM,oBAAoB,IAAI,SAAS;AACrC,UAAM,QAAQ,WAAW,GAAG,IAAI;AAChC,iBAAa,KAAK,KAAK;AACvB,WAAO;AAAA,EACT;AACA,QAAM,mBAAmB,MAAM,YAAY,KAAK,YAAY;AAC5D,SAAO,CAAC,mBAAmB,gBAAgB;AAC7C;AAEA,SAAS,UAAU,OAAO,MAAM;AAC9B,MAAI,SAAS,MAAM;AACjB,WAAO,IAAI,KAAK;AAAA,EAClB,OAAO;AACL,WAAO,WAAW,KAAK;AAAA,EACzB;AACF;AAEA,SAAS,uBAAuB,YAAY;AAC1C,MAAI,cAAc;AAClB,MAAI;AACJ,MAAI;AACJ,QAAM,UAAU,MAAM;AACpB,mBAAe;AACf,QAAI,SAAS,eAAe,GAAG;AAC7B,YAAM,KAAK;AACX,cAAQ;AACR,cAAQ;AAAA,IACV;AAAA,EACF;AACA,SAAO,IAAI,SAAS;AAClB,mBAAe;AACf,QAAI,CAAC,OAAO;AACV,cAAQ,YAAY,IAAI;AACxB,cAAQ,MAAM,IAAI,MAAM,WAAW,GAAG,IAAI,CAAC;AAAA,IAC7C;AACA,sBAAkB,OAAO;AACzB,WAAO;AAAA,EACT;AACF;AAEA,SAAS,UAAUC,MAAK,QAAQ,EAAE,aAAa,OAAO,SAAS,KAAK,IAAI,CAAC,GAAG;AAC1E,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,QAAQ;AACV;AACF,QAAI,MAAM,KAAK,KAAK,QAAQ;AAC1B,aAAO,eAAeA,MAAK,KAAK;AAAA,QAC9B,MAAM;AACJ,iBAAO,MAAM;AAAA,QACf;AAAA,QACA,IAAI,GAAG;AACL,gBAAM,QAAQ;AAAA,QAChB;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,aAAO,eAAeA,MAAK,KAAK,EAAE,OAAO,WAAW,CAAC;AAAA,IACvD;AAAA,EACF;AACA,SAAOA;AACT;AAEA,SAAS,IAAI,KAAK,KAAK;AACrB,MAAI,OAAO;AACT,WAAO,MAAM,GAAG;AAClB,SAAO,MAAM,GAAG,EAAE,GAAG;AACvB;AAEA,SAAS,UAAU,GAAG;AACpB,SAAO,MAAM,CAAC,KAAK;AACrB;AAEA,SAAS,mBAAmB,KAAK,KAAK;AACpC,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,QAAQ,EAAE,GAAG,IAAI;AACvB,WAAO,eAAe,OAAO,OAAO,UAAU;AAAA,MAC5C,YAAY;AAAA,MACZ,QAAQ;AACN,YAAI,QAAQ;AACZ,eAAO;AAAA,UACL,MAAM,OAAO;AAAA,YACX,OAAO,IAAI,OAAO;AAAA,YAClB,MAAM,QAAQ,IAAI;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT,OAAO;AACL,WAAO,OAAO,OAAO,CAAC,GAAG,GAAG,GAAG,GAAG;AAAA,EACpC;AACF;AAEA,SAAS,SAAS,IAAI,SAAS;AAC7B,QAAM,WAAW,WAAW,OAAO,SAAS,QAAQ,oBAAoB,QAAQ,QAAQ;AACxF,SAAO,YAAY,MAAM;AACvB,WAAO,SAAS,MAAM,GAAG,MAAM,MAAM,KAAK,IAAI,CAAC,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC;AAAA,EACnE;AACF;AAEA,SAAS,eAAe,KAAK,gBAAgB,CAAC,GAAG;AAC/C,MAAIC,QAAO,CAAC;AACZ,MAAI;AACJ,MAAI,MAAM,QAAQ,aAAa,GAAG;AAChC,IAAAA,QAAO;AAAA,EACT,OAAO;AACL,cAAU;AACV,UAAM,EAAE,uBAAuB,KAAK,IAAI;AACxC,IAAAA,MAAK,KAAK,GAAG,OAAO,KAAK,GAAG,CAAC;AAC7B,QAAI;AACF,MAAAA,MAAK,KAAK,GAAG,OAAO,oBAAoB,GAAG,CAAC;AAAA,EAChD;AACA,SAAO,OAAO;AAAA,IACZA,MAAK,IAAI,CAAC,QAAQ;AAChB,YAAM,QAAQ,IAAI,GAAG;AACrB,aAAO;AAAA,QACL;AAAA,QACA,OAAO,UAAU,aAAa,SAAS,MAAM,KAAK,GAAG,GAAG,OAAO,IAAI;AAAA,MACrE;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,WAAW,WAAW;AAC7B,MAAI,CAAC,MAAM,SAAS;AAClB,WAAO,SAAS,SAAS;AAC3B,QAAM,QAAQ,IAAI,MAAM,CAAC,GAAG;AAAA,IAC1B,IAAI,GAAG,GAAG,UAAU;AAClB,aAAO,MAAM,QAAQ,IAAI,UAAU,OAAO,GAAG,QAAQ,CAAC;AAAA,IACxD;AAAA,IACA,IAAI,GAAG,GAAG,OAAO;AACf,UAAI,MAAM,UAAU,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK;AAC3C,kBAAU,MAAM,CAAC,EAAE,QAAQ;AAAA;AAE3B,kBAAU,MAAM,CAAC,IAAI;AACvB,aAAO;AAAA,IACT;AAAA,IACA,eAAe,GAAG,GAAG;AACnB,aAAO,QAAQ,eAAe,UAAU,OAAO,CAAC;AAAA,IAClD;AAAA,IACA,IAAI,GAAG,GAAG;AACR,aAAO,QAAQ,IAAI,UAAU,OAAO,CAAC;AAAA,IACvC;AAAA,IACA,UAAU;AACR,aAAO,OAAO,KAAK,UAAU,KAAK;AAAA,IACpC;AAAA,IACA,2BAA2B;AACzB,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF,CAAC;AACD,SAAO,SAAS,KAAK;AACvB;AAEA,SAAS,iBAAiB,IAAI;AAC5B,SAAO,WAAW,SAAS,EAAE,CAAC;AAChC;AAEA,SAAS,aAAa,QAAQA,OAAM;AAClC,QAAM,WAAWA,MAAK,KAAK;AAC3B,QAAM,YAAY,SAAS,CAAC;AAC5B,SAAO,iBAAiB,MAAM,OAAO,cAAc,aAAa,OAAO,YAAY,OAAO,QAAQ,OAAS,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,QAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,OAAO,YAAY,OAAO,QAAQ,OAAS,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/P;AAEA,IAAM,WAAW,OAAO,WAAW,eAAe,OAAO,aAAa;AACtE,IAAM,WAAW,OAAO,sBAAsB,eAAe,sBAAsB;AACnF,IAAM,QAAQ,CAAC,QAAQ,OAAO,QAAQ;AACtC,IAAM,aAAa,CAAC,QAAQ,OAAO;AACnC,IAAM,SAAS,CAAC,cAAc,UAAU;AACtC,MAAI,CAAC;AACH,YAAQ,KAAK,GAAG,KAAK;AACzB;AACA,IAAM,WAAW,OAAO,UAAU;AAClC,IAAM,WAAW,CAAC,QAAQ,SAAS,KAAK,GAAG,MAAM;AACjD,IAAM,MAAM,MAAM,KAAK,IAAI;AAC3B,IAAM,YAAY,MAAM,CAAC,KAAK,IAAI;AAClC,IAAM,QAAQ,CAAC,GAAG,KAAK,QAAQ,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,CAAC;AAC7D,IAAM,OAAO,MAAM;AACnB;AACA,IAAM,OAAO,CAAC,KAAK,QAAQ;AACzB,QAAM,KAAK,KAAK,GAAG;AACnB,QAAM,KAAK,MAAM,GAAG;AACpB,SAAO,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,MAAM,EAAE,IAAI;AACvD;AACA,IAAM,SAAS,CAAC,KAAK,QAAQ,OAAO,UAAU,eAAe,KAAK,KAAK,GAAG;AAC1E,IAAM,QAAwB,SAAS;AACvC,SAAS,WAAW;AAClB,MAAI,IAAI;AACR,SAAO,cAAc,KAAK,UAAU,OAAO,SAAS,OAAO,cAAc,OAAO,SAAS,GAAG,eAAe,mBAAmB,KAAK,OAAO,UAAU,SAAS,OAAO,KAAK,UAAU,OAAO,SAAS,OAAO,cAAc,OAAO,SAAS,GAAG,kBAAkB,KAAK,iBAAiB,KAAK,UAAU,OAAO,SAAS,OAAO,UAAU,SAAS;AAC9U;AAEA,SAAS,oBAAoB,QAAQ,IAAI;AACvC,WAAS,WAAW,MAAM;AACxB,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAQ,QAAQ,OAAO,MAAM,GAAG,MAAM,MAAM,IAAI,GAAG,EAAE,IAAI,SAAS,MAAM,KAAK,CAAC,CAAC,EAAE,KAAK,OAAO,EAAE,MAAM,MAAM;AAAA,IAC7G,CAAC;AAAA,EACH;AACA,SAAO;AACT;AACA,IAAM,eAAe,CAACC,YAAW;AAC/B,SAAOA,QAAO;AAChB;AACA,SAAS,eAAe,IAAI,UAAU,CAAC,GAAG;AACxC,MAAI;AACJ,MAAI;AACJ,MAAI,eAAe;AACnB,QAAM,gBAAgB,CAAC,WAAW;AAChC,iBAAa,MAAM;AACnB,iBAAa;AACb,mBAAe;AAAA,EACjB;AACA,MAAI;AACJ,QAAM,SAAS,CAACA,YAAW;AACzB,UAAM,WAAW,QAAU,EAAE;AAC7B,UAAM,cAAc,QAAU,QAAQ,OAAO;AAC7C,QAAI;AACF,oBAAc,KAAK;AACrB,QAAI,YAAY,KAAK,gBAAgB,UAAU,eAAe,GAAG;AAC/D,UAAI,UAAU;AACZ,sBAAc,QAAQ;AACtB,mBAAW;AAAA,MACb;AACA,aAAO,QAAQ,QAAQA,QAAO,CAAC;AAAA,IACjC;AACA,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,qBAAe,QAAQ,iBAAiB,SAAS;AACjD,oBAAcA;AACd,UAAI,eAAe,CAAC,UAAU;AAC5B,mBAAW,WAAW,MAAM;AAC1B,cAAI;AACF,0BAAc,KAAK;AACrB,qBAAW;AACX,kBAAQ,YAAY,CAAC;AAAA,QACvB,GAAG,WAAW;AAAA,MAChB;AACA,cAAQ,WAAW,MAAM;AACvB,YAAI;AACF,wBAAc,QAAQ;AACxB,mBAAW;AACX,gBAAQA,QAAO,CAAC;AAAA,MAClB,GAAG,QAAQ;AAAA,IACb,CAAC;AAAA,EACH;AACA,SAAO;AACT;AACA,SAAS,kBAAkB,MAAM;AAC/B,MAAI,WAAW;AACf,MAAI;AACJ,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,OAAO,KAAK,CAAC,MAAM;AACxC,KAAC,EAAE,OAAO,IAAI,WAAW,MAAM,UAAU,MAAM,iBAAiB,MAAM,IAAI,KAAK,CAAC;AAAA;AAEhF,KAAC,IAAI,WAAW,MAAM,UAAU,MAAM,iBAAiB,KAAK,IAAI;AAClE,QAAM,QAAQ,MAAM;AAClB,QAAI,OAAO;AACT,mBAAa,KAAK;AAClB,cAAQ;AACR,mBAAa;AACb,qBAAe;AAAA,IACjB;AAAA,EACF;AACA,QAAM,SAAS,CAAC,YAAY;AAC1B,UAAM,WAAW,QAAU,EAAE;AAC7B,UAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,UAAMA,UAAS,MAAM;AACnB,aAAO,YAAY,QAAQ;AAAA,IAC7B;AACA,UAAM;AACN,QAAI,YAAY,GAAG;AACjB,iBAAW,KAAK,IAAI;AACpB,aAAOA,QAAO;AAAA,IAChB;AACA,QAAI,UAAU,aAAa,WAAW,CAAC,YAAY;AACjD,iBAAW,KAAK,IAAI;AACpB,MAAAA,QAAO;AAAA,IACT,WAAW,UAAU;AACnB,kBAAY,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC3C,uBAAe,iBAAiB,SAAS;AACzC,gBAAQ,WAAW,MAAM;AACvB,qBAAW,KAAK,IAAI;AACpB,sBAAY;AACZ,kBAAQA,QAAO,CAAC;AAChB,gBAAM;AAAA,QACR,GAAG,KAAK,IAAI,GAAG,WAAW,OAAO,CAAC;AAAA,MACpC,CAAC;AAAA,IACH;AACA,QAAI,CAAC,WAAW,CAAC;AACf,cAAQ,WAAW,MAAM,YAAY,MAAM,QAAQ;AACrD,gBAAY;AACZ,WAAO;AAAA,EACT;AACA,SAAO;AACT;AACA,SAAS,eAAe,eAAe,cAAc,UAAU,CAAC,GAAG;AACjE,QAAM;AAAA,IACJ,eAAe;AAAA,EACjB,IAAI;AACJ,QAAM,WAAWC,OAAM,iBAAiB,QAAQ;AAChD,WAAS,QAAQ;AACf,aAAS,QAAQ;AAAA,EACnB;AACA,WAAS,SAAS;AAChB,aAAS,QAAQ;AAAA,EACnB;AACA,QAAM,cAAc,IAAI,SAAS;AAC/B,QAAI,SAAS;AACX,mBAAa,GAAG,IAAI;AAAA,EACxB;AACA,SAAO,EAAE,UAAU,SAAS,QAAQ,GAAG,OAAO,QAAQ,YAAY;AACpE;AAEA,SAAS,oBAAoB,IAAI;AAC/B,QAAM,QAAwB,uBAAO,OAAO,IAAI;AAChD,SAAO,CAAC,QAAQ;AACd,UAAM,MAAM,MAAM,GAAG;AACrB,WAAO,QAAQ,MAAM,GAAG,IAAI,GAAG,GAAG;AAAA,EACpC;AACF;AACA,IAAM,cAAc;AACpB,IAAM,YAAY,oBAAoB,CAAC,QAAQ,IAAI,QAAQ,aAAa,KAAK,EAAE,YAAY,CAAC;AAC5F,IAAM,aAAa;AACnB,IAAM,WAAW,oBAAoB,CAAC,QAAQ;AAC5C,SAAO,IAAI,QAAQ,YAAY,CAAC,GAAG,MAAM,IAAI,EAAE,YAAY,IAAI,EAAE;AACnE,CAAC;AAED,SAAS,eAAe,IAAI,iBAAiB,OAAO,SAAS,WAAW;AACtE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI;AACF,iBAAW,MAAM,OAAO,MAAM,GAAG,EAAE;AAAA;AAEnC,iBAAW,SAAS,EAAE;AAAA,EAC1B,CAAC;AACH;AACA,SAAS,SAAS,KAAK;AACrB,SAAO;AACT;AACA,SAAS,uBAAuB,IAAI;AAClC,MAAI;AACJ,WAAS,UAAU;AACjB,QAAI,CAAC;AACH,iBAAW,GAAG;AAChB,WAAO;AAAA,EACT;AACA,UAAQ,QAAQ,YAAY;AAC1B,UAAM,QAAQ;AACd,eAAW;AACX,QAAI;AACF,YAAM;AAAA,EACV;AACA,SAAO;AACT;AACA,SAAS,OAAO,IAAI;AAClB,SAAO,GAAG;AACZ;AACA,SAAS,aAAa,QAAQ,OAAO;AACnC,SAAO,MAAM,KAAK,CAAC,MAAM,KAAK,GAAG;AACnC;AACA,SAAS,iBAAiB,QAAQ,OAAO;AACvC,MAAI;AACJ,MAAI,OAAO,WAAW;AACpB,WAAO,SAAS;AAClB,QAAM,UAAU,KAAK,OAAO,MAAM,cAAc,MAAM,OAAO,SAAS,GAAG,CAAC,MAAM;AAChF,QAAM,OAAO,OAAO,MAAM,MAAM,MAAM;AACtC,QAAM,SAAS,OAAO,WAAW,KAAK,IAAI;AAC1C,MAAI,OAAO,MAAM,MAAM;AACrB,WAAO;AACT,SAAO,SAAS;AAClB;AACA,SAAS,QAAQ,IAAI;AACnB,SAAO,GAAG,SAAS,KAAK,IAAI,OAAO,WAAW,EAAE,IAAI,KAAK,OAAO,WAAW,EAAE;AAC/E;AACA,SAAS,WAAW,KAAKF,OAAM,gBAAgB,OAAO;AACpD,SAAOA,MAAK,OAAO,CAAC,GAAG,MAAM;AAC3B,QAAI,KAAK,KAAK;AACZ,UAAI,CAAC,iBAAiB,IAAI,CAAC,MAAM;AAC/B,UAAE,CAAC,IAAI,IAAI,CAAC;AAAA,IAChB;AACA,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACP;AACA,SAAS,WAAW,KAAKA,OAAM,gBAAgB,OAAO;AACpD,SAAO,OAAO,YAAY,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM;AACrE,YAAQ,CAAC,iBAAiB,UAAU,WAAW,CAACA,MAAK,SAAS,GAAG;AAAA,EACnE,CAAC,CAAC;AACJ;AACA,SAAS,cAAc,KAAK;AAC1B,SAAO,OAAO,QAAQ,GAAG;AAC3B;AACA,SAAS,mBAAmB,QAAQ;AAClC,SAAO,UAAU,mBAAmB;AACtC;AACA,SAAS,QAAQ,OAAO;AACtB,SAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC9C;AAEA,SAASE,UAAS,MAAM;AACtB,MAAI,KAAK,WAAW;AAClB,WAAO,MAAQ,GAAG,IAAI;AACxB,QAAM,IAAI,KAAK,CAAC;AAChB,SAAO,OAAO,MAAM,aAAa,SAAS,UAAU,OAAO,EAAE,KAAK,GAAG,KAAK,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;AAC7F;AACA,IAAM,aAAaA;AAEnB,SAAS,aAAa,QAAQF,OAAM;AAClC,QAAM,WAAWA,MAAK,KAAK;AAC3B,QAAM,YAAY,SAAS,CAAC;AAC5B,SAAO,iBAAiB,MAAM,OAAO,cAAc,aAAa,OAAO,YAAY,OAAO,QAAQ,OAAS,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,UAAU,QAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,OAAO,YAAY,SAAS,IAAI,CAAC,MAAM,CAAC,GAAGE,OAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAChO;AAEA,SAAS,aAAa,cAAc,UAAU,KAAK;AACjD,SAAO,UAAU,CAAC,OAAO,YAAY;AACnC,QAAI,QAAQ,QAAU,YAAY;AAClC,QAAI;AACJ,UAAM,aAAa,MAAM,WAAW,MAAM;AACxC,cAAQ,QAAU,YAAY;AAC9B,cAAQ;AAAA,IACV,GAAG,QAAU,OAAO,CAAC;AACrB,sBAAkB,MAAM;AACtB,mBAAa,KAAK;AAAA,IACpB,CAAC;AACD,WAAO;AAAA,MACL,MAAM;AACJ,cAAM;AACN,eAAO;AAAA,MACT;AAAA,MACA,IAAI,UAAU;AACZ,gBAAQ;AACR,gBAAQ;AACR,qBAAa,KAAK;AAClB,gBAAQ,WAAW;AAAA,MACrB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,cAAc,IAAI,KAAK,KAAK,UAAU,CAAC,GAAG;AACjD,SAAO;AAAA,IACL,eAAe,IAAI,OAAO;AAAA,IAC1B;AAAA,EACF;AACF;AAEA,SAAS,aAAa,OAAO,KAAK,KAAK,UAAU,CAAC,GAAG;AACnD,QAAM,YAAY,IAAI,MAAM,KAAK;AACjC,QAAM,UAAU,cAAc,MAAM;AAClC,cAAU,QAAQ,MAAM;AAAA,EAC1B,GAAG,IAAI,OAAO;AACd,QAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,SAAO;AACT;AAEA,SAAS,WAAW,QAAQ,cAAc;AACxC,SAAO,SAAS;AAAA,IACd,MAAM;AACJ,UAAI;AACJ,cAAQ,KAAK,OAAO,UAAU,OAAO,KAAK;AAAA,IAC5C;AAAA,IACA,IAAI,OAAO;AACT,aAAO,QAAQ;AAAA,IACjB;AAAA,EACF,CAAC;AACH;AAEA,SAAS,cAAc,IAAI,KAAK,KAAK,WAAW,OAAO,UAAU,MAAM,iBAAiB,OAAO;AAC7F,SAAO;AAAA,IACL,eAAe,IAAI,UAAU,SAAS,cAAc;AAAA,IACpD;AAAA,EACF;AACF;AAEA,SAAS,aAAa,OAAO,QAAQ,KAAK,WAAW,MAAM,UAAU,MAAM;AACzE,MAAI,SAAS;AACX,WAAO;AACT,QAAM,YAAY,IAAI,MAAM,KAAK;AACjC,QAAM,UAAU,cAAc,MAAM;AAClC,cAAU,QAAQ,MAAM;AAAA,EAC1B,GAAG,OAAO,UAAU,OAAO;AAC3B,QAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,SAAO;AACT;AAEA,SAAS,eAAe,SAAS,UAAU,CAAC,GAAG;AAC7C,MAAI,SAAS;AACb,MAAI;AACJ,MAAI;AACJ,QAAMH,OAAM,UAAU,CAAC,QAAQ,aAAa;AAC1C,YAAQ;AACR,cAAU;AACV,WAAO;AAAA,MACL,MAAM;AACJ,eAAOF,KAAI;AAAA,MACb;AAAA,MACA,IAAI,GAAG;AACL,QAAAC,KAAI,CAAC;AAAA,MACP;AAAA,IACF;AAAA,EACF,CAAC;AACD,WAASD,KAAI,WAAW,MAAM;AAC5B,QAAI;AACF,YAAM;AACR,WAAO;AAAA,EACT;AACA,WAASC,KAAI,OAAO,aAAa,MAAM;AACrC,QAAI,IAAI;AACR,QAAI,UAAU;AACZ;AACF,UAAM,MAAM;AACZ,UAAM,KAAK,QAAQ,mBAAmB,OAAO,SAAS,GAAG,KAAK,SAAS,OAAO,GAAG,OAAO;AACtF;AACF,aAAS;AACT,KAAC,KAAK,QAAQ,cAAc,OAAO,SAAS,GAAG,KAAK,SAAS,OAAO,GAAG;AACvE,QAAI;AACF,cAAQ;AAAA,EACZ;AACA,QAAM,eAAe,MAAMD,KAAI,KAAK;AACpC,QAAM,YAAY,CAAC,MAAMC,KAAI,GAAG,KAAK;AACrC,QAAM,OAAO,MAAMD,KAAI,KAAK;AAC5B,QAAM,MAAM,CAAC,MAAMC,KAAI,GAAG,KAAK;AAC/B,SAAO;AAAA,IACLC;AAAA,IACA;AAAA,MACE,KAAAF;AAAA,MACA,KAAAC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,EAAE,YAAY,KAAK;AAAA,EACrB;AACF;AACA,IAAM,gBAAgB;AAEtB,SAAS,OAAO,MAAM;AACpB,MAAI,KAAK,WAAW,GAAG;AACrB,UAAM,CAACC,MAAK,KAAK,IAAI;AACrB,IAAAA,KAAI,QAAQ;AAAA,EACd;AACA,MAAI,KAAK,WAAW,GAAG;AACrB,UAAM,CAAC,QAAQ,KAAK,KAAK,IAAI;AAC7B,WAAO,GAAG,IAAI;AAAA,EAChB;AACF;AAEA,SAAS,gBAAgB,QAAQ,IAAI,UAAU,CAAC,GAAG;AACjD,QAAM;AAAA,IACJ,cAAc;AAAA,IACd,GAAG;AAAA,EACL,IAAI;AACJ,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,cAAc,QAAQ,IAAI,UAAU,CAAC,GAAG;AAC/C,QAAM;AAAA,IACJ,aAAa;AAAA,IACb,eAAe;AAAA,IACf,GAAG;AAAA,EACL,IAAI;AACJ,QAAM,EAAE,aAAa,OAAO,QAAQ,SAAS,IAAI,eAAe,QAAQ,EAAE,aAAa,CAAC;AACxF,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,MAAM,OAAO,QAAQ,SAAS;AACzC;AAEA,SAAS,QAAQ,MAAM,UAAU,CAAC,OAAO,GAAG;AAC1C,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY,CAAC;AAAA,EACf,IAAI,WAAW,CAAC;AAChB,QAAM,WAAW,CAAC;AAClB,QAAM,eAAe,SAAS,aAAa,UAAU,QAAQ,CAAC,MAAM;AACpE,QAAM,eAAe,SAAS,aAAa,UAAU,QAAQ,CAAC,MAAM;AACpE,MAAI,cAAc,UAAU,cAAc,OAAO;AAC/C,aAAS,KAAK;AAAA,MACZ;AAAA,MACA,CAAC,aAAa;AACZ,iBAAS,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;AACjC,cAAM,QAAQ,aAAa,QAAQ;AACnC,iBAAS,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,MACpC;AAAA,MACA,EAAE,OAAO,MAAM,UAAU;AAAA,IAC3B,CAAC;AAAA,EACH;AACA,MAAI,cAAc,UAAU,cAAc,OAAO;AAC/C,aAAS,KAAK;AAAA,MACZ;AAAA,MACA,CAAC,aAAa;AACZ,iBAAS,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;AACjC,aAAK,QAAQ,aAAa,QAAQ;AAClC,iBAAS,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,MACpC;AAAA,MACA,EAAE,OAAO,MAAM,UAAU;AAAA,IAC3B,CAAC;AAAA,EACH;AACA,QAAM,OAAO,MAAM;AACjB,aAAS,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,EAClC;AACA,SAAO;AACT;AAEA,SAAS,SAAS,QAAQ,SAAS,UAAU,CAAC,GAAG;AAC/C,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,EACd,IAAI;AACJ,QAAM,eAAe,QAAQ,OAAO;AACpC,SAAO;AAAA,IACL;AAAA,IACA,CAAC,aAAa,aAAa,QAAQ,CAAC,WAAW,OAAO,QAAQ,QAAQ;AAAA,IACtE,EAAE,OAAO,MAAM,UAAU;AAAA,EAC3B;AACF;AAEA,SAASI,QAAO,WAAW,UAAU,CAAC,GAAG;AACvC,MAAI,CAAC,MAAM,SAAS;AAClB,WAAO,OAAS,SAAS;AAC3B,QAAM,SAAS,MAAM,QAAQ,UAAU,KAAK,IAAI,MAAM,KAAK,EAAE,QAAQ,UAAU,MAAM,OAAO,CAAC,IAAI,CAAC;AAClG,aAAW,OAAO,UAAU,OAAO;AACjC,WAAO,GAAG,IAAI,UAAU,OAAO;AAAA,MAC7B,MAAM;AACJ,eAAO,UAAU,MAAM,GAAG;AAAA,MAC5B;AAAA,MACA,IAAI,GAAG;AACL,YAAI;AACJ,cAAM,cAAc,KAAK,QAAU,QAAQ,UAAU,MAAM,OAAO,KAAK;AACvE,YAAI,YAAY;AACd,cAAI,MAAM,QAAQ,UAAU,KAAK,GAAG;AAClC,kBAAM,OAAO,CAAC,GAAG,UAAU,KAAK;AAChC,iBAAK,GAAG,IAAI;AACZ,sBAAU,QAAQ;AAAA,UACpB,OAAO;AACL,kBAAM,YAAY,EAAE,GAAG,UAAU,OAAO,CAAC,GAAG,GAAG,EAAE;AACjD,mBAAO,eAAe,WAAW,OAAO,eAAe,UAAU,KAAK,CAAC;AACvE,sBAAU,QAAQ;AAAA,UACpB;AAAA,QACF,OAAO;AACL,oBAAU,MAAM,GAAG,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,EAAE;AAAA,EACJ;AACA,SAAO;AACT;AAEA,IAAMC,WAAU;AAChB,IAAM,eAAe;AAErB,SAAS,iBAAiB,IAAI,OAAO,MAAM,QAAQ;AACjD,QAAM,WAAW,mBAAmB,MAAM;AAC1C,MAAI;AACF,kBAAc,IAAI,MAAM;AAAA,WACjB;AACP,OAAG;AAAA;AAEH,aAAS,EAAE;AACf;AAEA,SAAS,mBAAmB,IAAI,QAAQ;AACtC,QAAM,WAAW,mBAAmB,MAAM;AAC1C,MAAI;AACF,oBAAgB,IAAI,MAAM;AAC9B;AAEA,SAAS,aAAa,IAAI,OAAO,MAAM,QAAQ;AAC7C,QAAM,WAAW,mBAAmB;AACpC,MAAI;AACF,cAAU,IAAI,MAAM;AAAA,WACb;AACP,OAAG;AAAA;AAEH,aAAS,EAAE;AACf;AAEA,SAAS,eAAe,IAAI,QAAQ;AAClC,QAAM,WAAW,mBAAmB,MAAM;AAC1C,MAAI;AACF,gBAAY,IAAI,MAAM;AAC1B;AAEA,SAAS,YAAY,GAAG,QAAQ,OAAO;AACrC,WAAS,QAAQ,WAAW,EAAE,QAAQ,QAAQ,OAAO,OAAO,SAAS,eAAe,IAAI,CAAC,GAAG;AAC1F,QAAI,OAAO;AACX,UAAM,UAAU,IAAI,QAAQ,CAAC,YAAY;AACvC,aAAO;AAAA,QACL;AAAA,QACA,CAAC,MAAM;AACL,cAAI,UAAU,CAAC,MAAM,OAAO;AAC1B,gBAAI;AACF,mBAAK;AAAA;AAEL,uBAAS,MAAM,QAAQ,OAAO,SAAS,KAAK,CAAC;AAC/C,oBAAQ,CAAC;AAAA,UACX;AAAA,QACF;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF,CAAC;AACD,UAAM,WAAW,CAAC,OAAO;AACzB,QAAI,WAAW,MAAM;AACnB,eAAS;AAAA,QACP,eAAe,SAAS,cAAc,EAAE,KAAK,MAAM,QAAU,CAAC,CAAC,EAAE,QAAQ,MAAM,QAAQ,OAAO,SAAS,KAAK,CAAC;AAAA,MAC/G;AAAA,IACF;AACA,WAAO,QAAQ,KAAK,QAAQ;AAAA,EAC9B;AACA,WAAS,KAAK,OAAO,SAAS;AAC5B,QAAI,CAAC,MAAM,KAAK;AACd,aAAO,QAAQ,CAAC,MAAM,MAAM,OAAO,OAAO;AAC5C,UAAM,EAAE,QAAQ,QAAQ,OAAO,OAAO,SAAS,eAAe,IAAI,WAAW,OAAO,UAAU,CAAC;AAC/F,QAAI,OAAO;AACX,UAAM,UAAU,IAAI,QAAQ,CAAC,YAAY;AACvC,aAAO;AAAA,QACL,CAAC,GAAG,KAAK;AAAA,QACT,CAAC,CAAC,IAAI,EAAE,MAAM;AACZ,cAAI,WAAW,OAAO,KAAK;AACzB,gBAAI;AACF,mBAAK;AAAA;AAEL,uBAAS,MAAM,QAAQ,OAAO,SAAS,KAAK,CAAC;AAC/C,oBAAQ,EAAE;AAAA,UACZ;AAAA,QACF;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF,CAAC;AACD,UAAM,WAAW,CAAC,OAAO;AACzB,QAAI,WAAW,MAAM;AACnB,eAAS;AAAA,QACP,eAAe,SAAS,cAAc,EAAE,KAAK,MAAM,QAAU,CAAC,CAAC,EAAE,QAAQ,MAAM;AAC7E,kBAAQ,OAAO,SAAS,KAAK;AAC7B,iBAAO,QAAU,CAAC;AAAA,QACpB,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO,QAAQ,KAAK,QAAQ;AAAA,EAC9B;AACA,WAAS,WAAW,SAAS;AAC3B,WAAO,QAAQ,CAAC,MAAM,QAAQ,CAAC,GAAG,OAAO;AAAA,EAC3C;AACA,WAAS,SAAS,SAAS;AACzB,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B;AACA,WAAS,cAAc,SAAS;AAC9B,WAAO,KAAK,QAAQ,OAAO;AAAA,EAC7B;AACA,WAAS,QAAQ,SAAS;AACxB,WAAO,QAAQ,OAAO,OAAO,OAAO;AAAA,EACtC;AACA,WAAS,WAAW,OAAO,SAAS;AAClC,WAAO,QAAQ,CAAC,MAAM;AACpB,YAAM,QAAQ,MAAM,KAAK,CAAC;AAC1B,aAAO,MAAM,SAAS,KAAK,KAAK,MAAM,SAAS,QAAU,KAAK,CAAC;AAAA,IACjE,GAAG,OAAO;AAAA,EACZ;AACA,WAAS,QAAQ,SAAS;AACxB,WAAO,aAAa,GAAG,OAAO;AAAA,EAChC;AACA,WAAS,aAAa,IAAI,GAAG,SAAS;AACpC,QAAI,QAAQ;AACZ,WAAO,QAAQ,MAAM;AACnB,eAAS;AACT,aAAO,SAAS;AAAA,IAClB,GAAG,OAAO;AAAA,EACZ;AACA,MAAI,MAAM,QAAQ,QAAU,CAAC,CAAC,GAAG;AAC/B,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,MAAM;AACR,eAAO,YAAY,GAAG,CAAC,KAAK;AAAA,MAC9B;AAAA,IACF;AACA,WAAO;AAAA,EACT,OAAO;AACL,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,MAAM;AACR,eAAO,YAAY,GAAG,CAAC,KAAK;AAAA,MAC9B;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AACA,SAAS,MAAM,GAAG;AAChB,SAAO,YAAY,CAAC;AACtB;AAEA,SAAS,kBAAkB,OAAO,QAAQ;AACxC,SAAO,UAAU;AACnB;AACA,SAAS,sBAAsB,MAAM;AACnC,MAAI,IAAI;AACR,QAAM,OAAO,KAAK,CAAC;AACnB,QAAM,SAAS,KAAK,CAAC;AACrB,MAAI,aAAa,KAAK,KAAK,CAAC,MAAM,OAAO,KAAK;AAC9C,QAAM;AAAA,IACJ,YAAY;AAAA,EACd,KAAK,KAAK,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC;AACnC,MAAI,OAAO,cAAc,UAAU;AACjC,UAAM,MAAM;AACZ,gBAAY,CAAC,OAAO,WAAW,MAAM,GAAG,MAAM,OAAO,GAAG;AAAA,EAC1D;AACA,QAAM,QAAQ,SAAS,MAAM,QAAU,IAAI,EAAE,OAAO,CAAC,MAAM,QAAU,MAAM,EAAE,UAAU,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;AACtH,MAAI,WAAW;AACb,UAAM,QAAQ,SAAS,MAAM,QAAU,MAAM,EAAE,OAAO,CAAC,MAAM,QAAU,IAAI,EAAE,UAAU,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;AACtH,WAAO,SAAS,MAAM,YAAY,CAAC,GAAG,QAAU,KAAK,GAAG,GAAG,QAAU,KAAK,CAAC,IAAI,QAAU,KAAK,CAAC;AAAA,EACjG,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEA,SAAS,cAAc,MAAM,IAAI;AAC/B,SAAO,SAAS,MAAM,QAAU,IAAI,EAAE,MAAM,CAAC,SAAS,OAAO,UAAU,GAAG,QAAU,OAAO,GAAG,OAAO,KAAK,CAAC,CAAC;AAC9G;AAEA,SAAS,eAAe,MAAM,IAAI;AAChC,SAAO,SAAS,MAAM,QAAU,IAAI,EAAE,IAAI,CAAC,MAAM,QAAU,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;AAC3E;AAEA,SAAS,aAAa,MAAM,IAAI;AAC9B,SAAO,SAAS,MAAM;AAAA,IACpB,QAAU,IAAI,EAAE,KAAK,CAAC,SAAS,OAAO,UAAU,GAAG,QAAU,OAAO,GAAG,OAAO,KAAK,CAAC;AAAA,EACtF,CAAC;AACH;AAEA,SAAS,kBAAkB,MAAM,IAAI;AACnC,SAAO,SAAS,MAAM,QAAU,IAAI,EAAE,UAAU,CAAC,SAAS,OAAO,UAAU,GAAG,QAAU,OAAO,GAAG,OAAO,KAAK,CAAC,CAAC;AAClH;AAEA,SAAS,SAAS,KAAK,IAAI;AACzB,MAAI,QAAQ,IAAI;AAChB,SAAO,UAAU,GAAG;AAClB,QAAI,GAAG,IAAI,KAAK,GAAG,OAAO,GAAG;AAC3B,aAAO,IAAI,KAAK;AAAA,EACpB;AACA,SAAO;AACT;AACA,SAAS,iBAAiB,MAAM,IAAI;AAClC,SAAO,SAAS,MAAM;AAAA,IACpB,CAAC,MAAM,UAAU,WAAW,SAAS,QAAU,IAAI,GAAG,CAAC,SAAS,OAAO,UAAU,GAAG,QAAU,OAAO,GAAG,OAAO,KAAK,CAAC,IAAI,QAAU,IAAI,EAAE,SAAS,CAAC,SAAS,OAAO,UAAU,GAAG,QAAU,OAAO,GAAG,OAAO,KAAK,CAAC;AAAA,EACnN,CAAC;AACH;AAEA,SAAS,uBAAuB,KAAK;AACnC,SAAO,SAAS,GAAG,KAAK,aAAa,KAAK,aAAa,YAAY;AACrE;AACA,SAAS,oBAAoB,MAAM;AACjC,MAAI;AACJ,QAAM,OAAO,KAAK,CAAC;AACnB,QAAM,QAAQ,KAAK,CAAC;AACpB,MAAI,aAAa,KAAK,CAAC;AACvB,MAAI,YAAY;AAChB,MAAI,uBAAuB,UAAU,GAAG;AACtC,iBAAa,KAAK,WAAW,cAAc,OAAO,KAAK;AACvD,iBAAa,WAAW;AAAA,EAC1B;AACA,MAAI,OAAO,eAAe,UAAU;AAClC,UAAM,MAAM;AACZ,iBAAa,CAAC,SAAS,WAAW,QAAQ,GAAG,MAAM,QAAU,MAAM;AAAA,EACrE;AACA,eAAa,cAAc,OAAO,aAAa,CAAC,SAAS,WAAW,YAAY,QAAU,MAAM;AAChG,SAAO,SAAS,MAAM,QAAU,IAAI,EAAE,MAAM,SAAS,EAAE,KAAK,CAAC,SAAS,OAAO,UAAU;AAAA,IACrF,QAAU,OAAO;AAAA,IACjB,QAAU,KAAK;AAAA,IACf;AAAA,IACA,QAAU,KAAK;AAAA,EACjB,CAAC,CAAC;AACJ;AAEA,SAAS,aAAa,MAAM,WAAW;AACrC,SAAO,SAAS,MAAM,QAAU,IAAI,EAAE,IAAI,CAAC,MAAM,QAAU,CAAC,CAAC,EAAE,KAAK,QAAU,SAAS,CAAC,CAAC;AAC3F;AAEA,SAAS,YAAY,MAAM,IAAI;AAC7B,SAAO,SAAS,MAAM,QAAU,IAAI,EAAE,IAAI,CAAC,MAAM,QAAU,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;AACxE;AAEA,SAAS,eAAe,MAAM,YAAY,MAAM;AAC9C,QAAM,iBAAiB,CAAC,KAAK,OAAO,UAAU,QAAQ,QAAU,GAAG,GAAG,QAAU,KAAK,GAAG,KAAK;AAC7F,SAAO,SAAS,MAAM;AACpB,UAAM,WAAW,QAAU,IAAI;AAC/B,WAAO,KAAK,SAAS,SAAS,OAAO,gBAAgB,OAAO,KAAK,CAAC,MAAM,aAAa,QAAU,KAAK,CAAC,EAAE,CAAC,IAAI,QAAU,KAAK,CAAC,CAAC,CAAC,IAAI,SAAS,OAAO,cAAc;AAAA,EAClK,CAAC;AACH;AAEA,SAAS,aAAa,MAAM,IAAI;AAC9B,SAAO,SAAS,MAAM,QAAU,IAAI,EAAE,KAAK,CAAC,SAAS,OAAO,UAAU,GAAG,QAAU,OAAO,GAAG,OAAO,KAAK,CAAC,CAAC;AAC7G;AAEA,SAAS,KAAK,OAAO;AACnB,SAAO,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC;AAClC;AACA,SAAS,iBAAiB,OAAO,IAAI;AACnC,SAAO,MAAM,OAAO,CAAC,KAAK,MAAM;AAC9B,QAAI,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC;AAClC,UAAI,KAAK,CAAC;AACZ,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACP;AACA,SAAS,eAAe,MAAM,WAAW;AACvC,SAAO,SAAS,MAAM;AACpB,UAAM,eAAe,QAAU,IAAI,EAAE,IAAI,CAAC,YAAY,QAAU,OAAO,CAAC;AACxE,WAAO,YAAY,iBAAiB,cAAc,SAAS,IAAI,KAAK,YAAY;AAAA,EAClF,CAAC;AACH;AAEA,SAAS,WAAW,eAAe,GAAG,UAAU,CAAC,GAAG;AAClD,MAAI,gBAAgB,MAAM,YAAY;AACtC,QAAM,QAAQ,WAAW,YAAY;AACrC,QAAM;AAAA,IACJ,MAAM,OAAO;AAAA,IACb,MAAM,OAAO;AAAA,EACf,IAAI;AACJ,QAAM,MAAM,CAAC,QAAQ,MAAM,MAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,QAAQ,KAAK,GAAG,GAAG;AACzF,QAAM,MAAM,CAAC,QAAQ,MAAM,MAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,MAAM,QAAQ,KAAK,GAAG,GAAG;AACzF,QAAMP,OAAM,MAAM,MAAM;AACxB,QAAMC,OAAM,CAAC,QAAQ,MAAM,QAAQ,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,GAAG,CAAC;AACnE,QAAM,QAAQ,CAAC,MAAM,kBAAkB;AACrC,oBAAgB;AAChB,WAAOA,KAAI,GAAG;AAAA,EAChB;AACA,SAAO,EAAE,OAAO,KAAK,KAAK,KAAAD,MAAK,KAAAC,MAAK,MAAM;AAC5C;AAEA,IAAM,cAAc;AACpB,IAAM,eAAe;AACrB,SAAS,gBAAgB,OAAO,SAAS,aAAa,WAAW;AAC/D,MAAI,IAAI,QAAQ,KAAK,OAAO;AAC5B,MAAI;AACF,QAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,KAAK,SAAS,OAAO,GAAG,IAAI,KAAK,EAAE;AAC7D,SAAO,cAAc,EAAE,YAAY,IAAI;AACzC;AACA,SAAS,cAAc,KAAK;AAC1B,QAAM,WAAW,CAAC,MAAM,MAAM,MAAM,IAAI;AACxC,QAAM,IAAI,MAAM;AAChB,SAAO,OAAO,UAAU,IAAI,MAAM,EAAE,KAAK,SAAS,CAAC,KAAK,SAAS,CAAC;AACpE;AACA,SAAS,WAAW,MAAM,WAAW,UAAU,CAAC,GAAG;AACjD,MAAI;AACJ,QAAM,QAAQ,KAAK,YAAY;AAC/B,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,eAAe,KAAK,gBAAgB;AAC1C,QAAM,MAAM,KAAK,OAAO;AACxB,QAAM,YAAY,KAAK,QAAQ,mBAAmB,OAAO,KAAK;AAC9D,QAAM,gBAAgB,CAAC,eAAe;AACpC,QAAI;AACJ,YAAQ,MAAM,WAAW,MAAM,GAAG,EAAE,CAAC,MAAM,OAAO,MAAM;AAAA,EAC1D;AACA,QAAM,UAAU;AAAA,IACd,IAAI,MAAM,cAAc,KAAK;AAAA,IAC7B,IAAI,MAAM,OAAO,KAAK,EAAE,MAAM,EAAE;AAAA,IAChC,MAAM,MAAM;AAAA,IACZ,GAAG,MAAM,QAAQ;AAAA,IACjB,IAAI,MAAM,cAAc,QAAQ,CAAC;AAAA,IACjC,IAAI,MAAM,GAAG,QAAQ,CAAC,GAAG,SAAS,GAAG,GAAG;AAAA,IACxC,KAAK,MAAM,KAAK,mBAAmB,QAAU,QAAQ,OAAO,GAAG,EAAE,OAAO,QAAQ,CAAC;AAAA,IACjF,MAAM,MAAM,KAAK,mBAAmB,QAAU,QAAQ,OAAO,GAAG,EAAE,OAAO,OAAO,CAAC;AAAA,IACjF,GAAG,MAAM,OAAO,IAAI;AAAA,IACpB,IAAI,MAAM,cAAc,IAAI;AAAA,IAC5B,IAAI,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG;AAAA,IACnC,GAAG,MAAM,OAAO,KAAK;AAAA,IACrB,IAAI,MAAM,cAAc,KAAK;AAAA,IAC7B,IAAI,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,GAAG;AAAA,IACpC,GAAG,MAAM,GAAG,QAAQ,MAAM,EAAE,GAAG,SAAS,GAAG,GAAG;AAAA,IAC9C,IAAI,MAAM,cAAc,QAAQ,MAAM,EAAE;AAAA,IACxC,IAAI,MAAM,GAAG,QAAQ,MAAM,EAAE,GAAG,SAAS,GAAG,GAAG;AAAA,IAC/C,GAAG,MAAM,OAAO,OAAO;AAAA,IACvB,IAAI,MAAM,cAAc,OAAO;AAAA,IAC/B,IAAI,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,GAAG;AAAA,IACtC,GAAG,MAAM,OAAO,OAAO;AAAA,IACvB,IAAI,MAAM,cAAc,OAAO;AAAA,IAC/B,IAAI,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,GAAG;AAAA,IACtC,KAAK,MAAM,GAAG,YAAY,GAAG,SAAS,GAAG,GAAG;AAAA,IAC5C,GAAG,MAAM;AAAA,IACT,IAAI,MAAM,KAAK,mBAAmB,QAAU,QAAQ,OAAO,GAAG,EAAE,SAAS,SAAS,CAAC;AAAA,IACnF,KAAK,MAAM,KAAK,mBAAmB,QAAU,QAAQ,OAAO,GAAG,EAAE,SAAS,QAAQ,CAAC;AAAA,IACnF,MAAM,MAAM,KAAK,mBAAmB,QAAU,QAAQ,OAAO,GAAG,EAAE,SAAS,OAAO,CAAC;AAAA,IACnF,GAAG,MAAM,SAAS,OAAO,OAAO;AAAA,IAChC,IAAI,MAAM,SAAS,OAAO,SAAS,OAAO,IAAI;AAAA,IAC9C,GAAG,MAAM,SAAS,OAAO,SAAS,IAAI;AAAA,IACtC,IAAI,MAAM,SAAS,OAAO,SAAS,MAAM,IAAI;AAAA,IAC7C,GAAG,MAAM,cAAc,KAAK,mBAAmB,QAAU,QAAQ,OAAO,GAAG,EAAE,cAAc,cAAc,CAAC,CAAC;AAAA,IAC3G,IAAI,MAAM,cAAc,KAAK,mBAAmB,QAAU,QAAQ,OAAO,GAAG,EAAE,cAAc,cAAc,CAAC,CAAC;AAAA,IAC5G,KAAK,MAAM,cAAc,KAAK,mBAAmB,QAAU,QAAQ,OAAO,GAAG,EAAE,cAAc,cAAc,CAAC,CAAC;AAAA,IAC7G,MAAM,MAAM,cAAc,KAAK,mBAAmB,QAAU,QAAQ,OAAO,GAAG,EAAE,cAAc,aAAa,CAAC,CAAC;AAAA,EAC/G;AACA,SAAO,UAAU,QAAQ,cAAc,CAAC,OAAO,OAAO;AACpD,QAAI,KAAK;AACT,YAAQ,KAAK,MAAM,OAAO,MAAM,MAAM,QAAQ,KAAK,MAAM,OAAO,SAAS,IAAI,KAAK,OAAO,MAAM,OAAO,KAAK;AAAA,EAC7G,CAAC;AACH;AACA,SAAS,cAAc,MAAM;AAC3B,MAAI,SAAS;AACX,WAAO,IAAI,KAAK,OAAO,GAAG;AAC5B,MAAI,SAAS;AACX,WAAuB,oBAAI,KAAK;AAClC,MAAI,gBAAgB;AAClB,WAAO,IAAI,KAAK,IAAI;AACtB,MAAI,OAAO,SAAS,YAAY,CAAC,MAAM,KAAK,IAAI,GAAG;AACjD,UAAM,IAAI,KAAK,MAAM,WAAW;AAChC,QAAI,GAAG;AACL,YAAM,IAAI,EAAE,CAAC,IAAI,KAAK;AACtB,YAAM,MAAM,EAAE,CAAC,KAAK,KAAK,UAAU,GAAG,CAAC;AACvC,aAAO,IAAI,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE;AAAA,IACzE;AAAA,EACF;AACA,SAAO,IAAI,KAAK,IAAI;AACtB;AACA,SAAS,cAAc,MAAM,YAAY,YAAY,UAAU,CAAC,GAAG;AACjE,SAAO,SAAS,MAAM,WAAW,cAAc,QAAU,IAAI,CAAC,GAAG,QAAU,SAAS,GAAG,OAAO,CAAC;AACjG;AAEA,SAAS,cAAc,IAAI,WAAW,KAAK,UAAU,CAAC,GAAG;AACvD,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,oBAAoB;AAAA,EACtB,IAAI;AACJ,MAAI,QAAQ;AACZ,QAAM,WAAW,WAAW,KAAK;AACjC,WAAS,QAAQ;AACf,QAAI,OAAO;AACT,oBAAc,KAAK;AACnB,cAAQ;AAAA,IACV;AAAA,EACF;AACA,WAAS,QAAQ;AACf,aAAS,QAAQ;AACjB,UAAM;AAAA,EACR;AACA,WAAS,SAAS;AAChB,UAAM,gBAAgB,QAAU,QAAQ;AACxC,QAAI,iBAAiB;AACnB;AACF,aAAS,QAAQ;AACjB,QAAI;AACF,SAAG;AACL,UAAM;AACN,QAAI,SAAS;AACX,cAAQ,YAAY,IAAI,aAAa;AAAA,EACzC;AACA,MAAI,aAAa;AACf,WAAO;AACT,MAAI,MAAM,QAAQ,KAAK,OAAO,aAAa,YAAY;AACrD,UAAM,YAAY,MAAM,UAAU,MAAM;AACtC,UAAI,SAAS,SAAS;AACpB,eAAO;AAAA,IACX,CAAC;AACD,sBAAkB,SAAS;AAAA,EAC7B;AACA,oBAAkB,KAAK;AACvB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,YAAY,WAAW,KAAK,UAAU,CAAC,GAAG;AACjD,QAAM;AAAA,IACJ,UAAU,iBAAiB;AAAA,IAC3B,YAAY;AAAA,IACZ;AAAA,EACF,IAAI;AACJ,QAAM,UAAU,WAAW,CAAC;AAC5B,QAAM,SAAS,MAAM,QAAQ,SAAS;AACtC,QAAM,QAAQ,MAAM;AAClB,YAAQ,QAAQ;AAAA,EAClB;AACA,QAAM,WAAW;AAAA,IACf,WAAW,MAAM;AACf,aAAO;AACP,eAAS,QAAQ,KAAK;AAAA,IACxB,IAAI;AAAA,IACJ;AAAA,IACA,EAAE,UAAU;AAAA,EACd;AACA,MAAI,gBAAgB;AAClB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL;AAAA,EACF,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEA,SAAS,eAAe,QAAQ,UAAU,CAAC,GAAG;AAC5C,MAAI;AACJ,QAAM,KAAK,YAAY,KAAK,QAAQ,iBAAiB,OAAO,KAAK,IAAI;AACrE;AAAA,IACE;AAAA,IACA,MAAM,GAAG,QAAQ,UAAU;AAAA,IAC3B;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,IAAI,UAAU,UAAU,CAAC,GAAG;AAChD,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,oBAAoB;AAAA,EACtB,IAAI;AACJ,QAAM,YAAY,WAAW,KAAK;AAClC,MAAI,QAAQ;AACZ,WAAS,QAAQ;AACf,QAAI,OAAO;AACT,mBAAa,KAAK;AAClB,cAAQ;AAAA,IACV;AAAA,EACF;AACA,WAAS,OAAO;AACd,cAAU,QAAQ;AAClB,UAAM;AAAA,EACR;AACA,WAAS,SAAS,MAAM;AACtB,QAAI;AACF,SAAG;AACL,UAAM;AACN,cAAU,QAAQ;AAClB,YAAQ,WAAW,MAAM;AACvB,gBAAU,QAAQ;AAClB,cAAQ;AACR,SAAG,GAAG,IAAI;AAAA,IACZ,GAAG,QAAU,QAAQ,CAAC;AAAA,EACxB;AACA,MAAI,WAAW;AACb,cAAU,QAAQ;AAClB,QAAI;AACF,YAAM;AAAA,EACV;AACA,oBAAkB,IAAI;AACtB,SAAO;AAAA,IACL,WAAW,SAAS,SAAS;AAAA,IAC7B;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,WAAW,WAAW,KAAK,UAAU,CAAC,GAAG;AAChD,QAAM;AAAA,IACJ,UAAU,iBAAiB;AAAA,IAC3B;AAAA,EACF,IAAI;AACJ,QAAM,WAAW;AAAA,IACf,YAAY,OAAO,WAAW;AAAA,IAC9B;AAAA,IACA;AAAA,EACF;AACA,QAAM,QAAQ,SAAS,MAAM,CAAC,SAAS,UAAU,KAAK;AACtD,MAAI,gBAAgB;AAClB,WAAO;AAAA,MACL;AAAA,MACA,GAAG;AAAA,IACL;AAAA,EACF,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEA,SAAS,YAAY,OAAO,UAAU,CAAC,GAAG;AACxC,QAAM;AAAA,IACJ,SAAS;AAAA,IACT;AAAA,IACA;AAAA,EACF,IAAI;AACJ,SAAO,SAAS,MAAM;AACpB,QAAI,WAAW,QAAU,KAAK;AAC9B,QAAI,OAAO,WAAW;AACpB,iBAAW,OAAO,QAAQ;AAAA,aACnB,OAAO,aAAa;AAC3B,iBAAW,OAAO,MAAM,EAAE,UAAU,KAAK;AAC3C,QAAI,aAAa,OAAO,MAAM,QAAQ;AACpC,iBAAW;AACb,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,YAAY,OAAO;AAC1B,SAAO,SAAS,MAAM,GAAG,QAAU,KAAK,CAAC,EAAE;AAC7C;AAEA,SAAS,UAAU,eAAe,OAAO,UAAU,CAAC,GAAG;AACrD,QAAM;AAAA,IACJ,cAAc;AAAA,IACd,aAAa;AAAA,EACf,IAAI;AACJ,QAAM,aAAa,MAAM,YAAY;AACrC,QAAM,SAAS,WAAW,YAAY;AACtC,WAAS,OAAO,OAAO;AACrB,QAAI,UAAU,QAAQ;AACpB,aAAO,QAAQ;AACf,aAAO,OAAO;AAAA,IAChB,OAAO;AACL,YAAM,SAAS,QAAU,WAAW;AACpC,aAAO,QAAQ,OAAO,UAAU,SAAS,QAAU,UAAU,IAAI;AACjE,aAAO,OAAO;AAAA,IAChB;AAAA,EACF;AACA,MAAI;AACF,WAAO;AAAA;AAEP,WAAO,CAAC,QAAQ,MAAM;AAC1B;AAEA,SAAS,WAAW,QAAQ,IAAI,SAAS;AACvC,MAAI,WAAW,WAAW,OAAO,SAAS,QAAQ,aAAa,CAAC,IAAI,CAAC,GAAG,OAAO,WAAW,aAAa,OAAO,IAAI,MAAM,QAAQ,MAAM,IAAI,SAAS,QAAU,MAAM,CAAC;AACpK,SAAO,MAAM,QAAQ,CAAC,SAAS,GAAG,cAAc;AAC9C,UAAM,iBAAiB,MAAM,KAAK,EAAE,QAAQ,QAAQ,OAAO,CAAC;AAC5D,UAAM,QAAQ,CAAC;AACf,eAAW,OAAO,SAAS;AACzB,UAAI,QAAQ;AACZ,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,YAAI,CAAC,eAAe,CAAC,KAAK,QAAQ,QAAQ,CAAC,GAAG;AAC5C,yBAAe,CAAC,IAAI;AACpB,kBAAQ;AACR;AAAA,QACF;AAAA,MACF;AACA,UAAI,CAAC;AACH,cAAM,KAAK,GAAG;AAAA,IAClB;AACA,UAAM,UAAU,QAAQ,OAAO,CAAC,IAAI,MAAM,CAAC,eAAe,CAAC,CAAC;AAC5D,OAAG,SAAS,SAAS,OAAO,SAAS,SAAS;AAC9C,cAAU,CAAC,GAAG,OAAO;AAAA,EACvB,GAAG,OAAO;AACZ;AAEA,SAAS,YAAY,QAAQ,IAAI,SAAS;AACxC,QAAM;AAAA,IACJ;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AACJ,QAAM,UAAU,WAAW,CAAC;AAC5B,QAAM,OAAO;AAAA,IACX;AAAA,IACA,IAAI,SAAS;AACX,cAAQ,SAAS;AACjB,UAAI,QAAQ,SAAS,QAAU,KAAK;AAClC,iBAAS,MAAM,KAAK,CAAC;AACvB,SAAG,GAAG,IAAI;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACA,SAAO,EAAE,OAAO,SAAS,KAAK;AAChC;AAEA,SAAS,eAAe,QAAQ,IAAI,UAAU,CAAC,GAAG;AAChD,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,UAAU;AAAA,IACV,GAAG;AAAA,EACL,IAAI;AACJ,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,aAAa,eAAe,UAAU,EAAE,QAAQ,CAAC;AAAA,IACnD;AAAA,EACF;AACF;AAEA,SAAS,UAAU,QAAQ,IAAI,SAAS;AACtC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,eAAe,QAAQ,IAAI,UAAU,CAAC,GAAG;AAChD,QAAM;AAAA,IACJ,cAAc;AAAA,IACd,GAAG;AAAA,EACL,IAAI;AACJ,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACA,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI,aAAa,UAAU,QAAQ;AACjC,UAAM,SAAS,WAAW,KAAK;AAC/B,6BAAyB,MAAM;AAAA,IAC/B;AACA,oBAAgB,CAAC,YAAY;AAC3B,aAAO,QAAQ;AACf,cAAQ;AACR,aAAO,QAAQ;AAAA,IACjB;AACA,WAAO;AAAA,MACL;AAAA,MACA,IAAI,SAAS;AACX,YAAI,CAAC,OAAO;AACV,qBAAW,GAAG,IAAI;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM,cAAc,CAAC;AACrB,UAAM,gBAAgB,WAAW,CAAC;AAClC,UAAM,cAAc,WAAW,CAAC;AAChC,6BAAyB,MAAM;AAC7B,oBAAc,QAAQ,YAAY;AAAA,IACpC;AACA,gBAAY;AAAA,MACV;AAAA,QACE;AAAA,QACA,MAAM;AACJ,sBAAY;AAAA,QACd;AAAA,QACA,EAAE,GAAG,cAAc,OAAO,OAAO;AAAA,MACnC;AAAA,IACF;AACA,oBAAgB,CAAC,YAAY;AAC3B,YAAM,kBAAkB,YAAY;AACpC,cAAQ;AACR,oBAAc,SAAS,YAAY,QAAQ;AAAA,IAC7C;AACA,gBAAY;AAAA,MACV;AAAA,QACE;AAAA,QACA,IAAI,SAAS;AACX,gBAAM,SAAS,cAAc,QAAQ,KAAK,cAAc,UAAU,YAAY;AAC9E,wBAAc,QAAQ;AACtB,sBAAY,QAAQ;AACpB,cAAI;AACF;AACF,qBAAW,GAAG,IAAI;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,WAAO,MAAM;AACX,kBAAY,QAAQ,CAAC,OAAO,GAAG,CAAC;AAAA,IAClC;AAAA,EACF;AACA,SAAO,EAAE,MAAM,eAAe,uBAAuB;AACvD;AAEA,SAAS,eAAe,QAAQ,IAAI,SAAS;AAC3C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,WAAW;AAAA,IACb;AAAA,EACF;AACF;AAEA,SAAS,UAAU,QAAQ,IAAI,SAAS;AACtC,QAAM,OAAO,MAAM,QAAQ,IAAI,SAAS;AACtC,aAAS,MAAM,KAAK,CAAC;AACrB,WAAO,GAAG,GAAG,IAAI;AAAA,EACnB,GAAG,OAAO;AACV,SAAO;AACT;AAEA,SAAS,eAAe,QAAQ,IAAI,UAAU,CAAC,GAAG;AAChD,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,WAAW;AAAA,IACX,UAAU;AAAA,IACV,GAAG;AAAA,EACL,IAAI;AACJ,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,aAAa,eAAe,UAAU,UAAU,OAAO;AAAA,IACzD;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,QAAQ,IAAI,UAAU,CAAC,GAAG;AAClD,MAAI;AACJ,WAAS,WAAW;AAClB,QAAI,CAAC;AACH;AACF,UAAM,KAAK;AACX,gBAAY;AACZ,OAAG;AAAA,EACL;AACA,WAAS,UAAU,UAAU;AAC3B,gBAAY;AAAA,EACd;AACA,QAAM,MAAM,CAAC,OAAO,aAAa;AAC/B,aAAS;AACT,WAAO,GAAG,OAAO,UAAU,SAAS;AAAA,EACtC;AACA,QAAM,MAAM,eAAe,QAAQ,KAAK,OAAO;AAC/C,QAAM,EAAE,cAAc,IAAI;AAC1B,QAAM,UAAU,MAAM;AACpB,QAAI;AACJ,kBAAc,MAAM;AAClB,aAAO,IAAI,gBAAgB,MAAM,GAAG,YAAY,MAAM,CAAC;AAAA,IACzD,CAAC;AACD,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,EACF;AACF;AACA,SAAS,gBAAgB,SAAS;AAChC,MAAI,WAAW,OAAO;AACpB,WAAO;AACT,MAAI,MAAM,QAAQ,OAAO;AACvB,WAAO,QAAQ,IAAI,CAAC,SAAS,QAAU,IAAI,CAAC;AAC9C,SAAO,QAAU,OAAO;AAC1B;AACA,SAAS,YAAY,QAAQ;AAC3B,SAAO,MAAM,QAAQ,MAAM,IAAI,OAAO,IAAI,MAAM,MAAM,IAAI;AAC5D;AAEA,SAAS,SAAS,QAAQ,IAAI,SAAS;AACrC,QAAM,OAAO;AAAA,IACX;AAAA,IACA,CAAC,GAAG,IAAI,iBAAiB;AACvB,UAAI,GAAG;AACL,YAAI,WAAW,OAAO,SAAS,QAAQ;AACrC,mBAAS,MAAM,KAAK,CAAC;AACvB,WAAG,GAAG,IAAI,YAAY;AAAA,MACxB;AAAA,IACF;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,MAAM;AAAA,IACR;AAAA,EACF;AACA,SAAO;AACT;;;ACnkDA,SAAS,cAAc,oBAAoB,cAAc,cAAc;AACrE,MAAI;AACJ,MAAI,MAAM,YAAY,GAAG;AACvB,cAAU;AAAA,MACR,YAAY;AAAA,IACd;AAAA,EACF,OAAO;AACL,cAAU,gBAAgB,CAAC;AAAA,EAC7B;AACA,QAAM;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,UAAU;AAAA,IACV,UAAU;AAAA,EACZ,IAAI;AACJ,QAAM,UAAU,WAAW,CAAC,IAAI;AAChC,QAAM,UAAU,UAAU,WAAW,YAAY,IAAI,IAAI,YAAY;AACrE,MAAI,UAAU;AACd,cAAY,OAAO,iBAAiB;AAClC,QAAI,CAAC,QAAQ;AACX;AACF;AACA,UAAM,qBAAqB;AAC3B,QAAI,cAAc;AAClB,QAAI,YAAY;AACd,cAAQ,QAAQ,EAAE,KAAK,MAAM;AAC3B,mBAAW,QAAQ;AAAA,MACrB,CAAC;AAAA,IACH;AACA,QAAI;AACF,YAAM,SAAS,MAAM,mBAAmB,CAAC,mBAAmB;AAC1D,qBAAa,MAAM;AACjB,cAAI;AACF,uBAAW,QAAQ;AACrB,cAAI,CAAC;AACH,2BAAe;AAAA,QACnB,CAAC;AAAA,MACH,CAAC;AACD,UAAI,uBAAuB;AACzB,gBAAQ,QAAQ;AAAA,IACpB,SAAS,GAAG;AACV,cAAQ,CAAC;AAAA,IACX,UAAE;AACA,UAAI,cAAc,uBAAuB;AACvC,mBAAW,QAAQ;AACrB,oBAAc;AAAA,IAChB;AAAA,EACF,CAAC;AACD,MAAI,MAAM;AACR,WAAO,SAAS,MAAM;AACpB,cAAQ,QAAQ;AAChB,aAAO,QAAQ;AAAA,IACjB,CAAC;AAAA,EACH,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEA,SAAS,eAAe,KAAK,SAAS,eAAe,uBAAuB;AAC1E,MAAI,SAAS,OAAO,GAAG;AACvB,MAAI;AACF,aAAS,OAAO,KAAK,aAAa;AACpC,MAAI;AACF,aAAS,OAAO,KAAK,eAAe,qBAAqB;AAC3D,MAAI,OAAO,YAAY,YAAY;AACjC,WAAO,SAAS,CAAC,QAAQ,QAAQ,QAAQ,GAAG,CAAC;AAAA,EAC/C,OAAO;AACL,WAAO,SAAS;AAAA,MACd,KAAK,CAAC,QAAQ,QAAQ,IAAI,QAAQ,GAAG;AAAA,MACrC,KAAK,QAAQ;AAAA,IACf,CAAC;AAAA,EACH;AACF;AAEA,SAAS,uBAAuB,UAAU,CAAC,GAAG;AAC5C,QAAM;AAAA,IACJ,eAAe;AAAA,EACjB,IAAI;AACJ,QAAM,SAAS,WAAW;AAC1B,QAAM,SAAuB,gBAAgB;AAAA,IAC3C,MAAM,GAAG,EAAE,MAAM,GAAG;AAClB,aAAO,MAAM;AACX,eAAO,QAAQ,MAAM;AAAA,MACvB;AAAA,IACF;AAAA,EACF,CAAC;AACD,QAAM,QAAsB,gBAAgB;AAAA,IAC1C;AAAA,IACA,OAAO,QAAQ;AAAA,IACf,MAAM,OAAO,EAAE,OAAO,MAAM,GAAG;AAC7B,aAAO,MAAM;AACX,YAAI;AACJ,YAAI,CAAC,OAAO,SAAS;AACnB,gBAAM,IAAI,MAAM,6DAA6D;AAC/E,cAAM,SAAS,KAAK,OAAO,UAAU,OAAO,SAAS,GAAG,KAAK,QAAQ;AAAA,UACnE,GAAG,QAAQ,SAAS,OAAO,qBAAqB,KAAK,IAAI;AAAA,UACzD,QAAQ;AAAA,QACV,CAAC;AACD,eAAO,iBAAiB,SAAS,OAAO,SAAS,MAAM,YAAY,IAAI,MAAM,CAAC,IAAI;AAAA,MACpF;AAAA,IACF;AAAA,EACF,CAAC;AACD,SAAO;AAAA,IACL,EAAE,QAAQ,MAAM;AAAA,IAChB,CAAC,QAAQ,KAAK;AAAA,EAChB;AACF;AACA,SAAS,qBAAqB,KAAK;AACjC,QAAM,SAAS,CAAC;AAChB,aAAW,OAAO;AAChB,WAAO,SAAS,GAAG,CAAC,IAAI,IAAI,GAAG;AACjC,SAAO;AACT;AAEA,SAAS,sBAAsB,UAAU,CAAC,GAAG;AAC3C,MAAI,QAAQ;AACZ,QAAM,YAAY,IAAI,CAAC,CAAC;AACxB,WAAS,UAAU,MAAM;AACvB,UAAM,QAAQ,gBAAgB;AAAA,MAC5B,KAAK;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,SAAS,MAAM;AAAA,MACf;AAAA,MACA,QAAQ,MAAM;AAAA,MACd;AAAA,MACA,aAAa;AAAA,MACb;AAAA,IACF,CAAC;AACD,cAAU,MAAM,KAAK,KAAK;AAC1B,UAAM,UAAU,IAAI,QAAQ,CAAC,UAAU,YAAY;AACjD,YAAM,UAAU,CAAC,MAAM;AACrB,cAAM,cAAc;AACpB,eAAO,SAAS,CAAC;AAAA,MACnB;AACA,YAAM,SAAS;AAAA,IACjB,CAAC,EAAE,QAAQ,MAAM;AACf,YAAM,UAAU;AAChB,YAAM,SAAS,UAAU,MAAM,QAAQ,KAAK;AAC5C,UAAI,WAAW;AACb,kBAAU,MAAM,OAAO,QAAQ,CAAC;AAAA,IACpC,CAAC;AACD,WAAO,MAAM;AAAA,EACf;AACA,WAAS,SAAS,MAAM;AACtB,QAAI,QAAQ,aAAa,UAAU,MAAM,SAAS;AAChD,aAAO,UAAU,MAAM,CAAC,EAAE;AAC5B,WAAO,OAAO,GAAG,IAAI;AAAA,EACvB;AACA,QAAM,YAA0B,gBAAgB,CAAC,GAAG,EAAE,MAAM,MAAM;AAChE,UAAM,aAAa,MAAM,UAAU,MAAM,IAAI,CAAC,UAAU;AACtD,UAAI;AACJ,aAAO,EAAE,UAAU,EAAE,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM,YAAY,OAAO,SAAS,GAAG,KAAK,OAAO,KAAK,CAAC;AAAA,IACtG,CAAC;AACD,QAAI,QAAQ;AACV,aAAO,MAAM,EAAE,iBAAiB,QAAQ,YAAY,UAAU;AAChE,WAAO;AAAA,EACT,CAAC;AACD,YAAU,QAAQ;AAClB,SAAO;AACT;AAEA,SAAS,cAAc,IAAI;AACzB,SAAO,YAAY,MAAM;AACvB,WAAO,GAAG,MAAM,MAAM,KAAK,IAAI,CAAC,MAAM,QAAQ,CAAC,CAAC,CAAC;AAAA,EACnD;AACF;AAEA,IAAM,gBAAgB,WAAW,SAAS;AAC1C,IAAM,kBAAkB,WAAW,OAAO,WAAW;AACrD,IAAM,mBAAmB,WAAW,OAAO,YAAY;AACvD,IAAM,kBAAkB,WAAW,OAAO,WAAW;AAErD,SAAS,aAAa,OAAO;AAC3B,MAAI;AACJ,QAAM,QAAQ,QAAQ,KAAK;AAC3B,UAAQ,KAAK,SAAS,OAAO,SAAS,MAAM,QAAQ,OAAO,KAAK;AAClE;AAEA,SAAS,oBAAoB,MAAM;AACjC,QAAM,WAAW,CAAC;AAClB,QAAM,UAAU,MAAM;AACpB,aAAS,QAAQ,CAAC,OAAO,GAAG,CAAC;AAC7B,aAAS,SAAS;AAAA,EACpB;AACA,QAAM,WAAW,CAAC,IAAI,OAAO,UAAU,YAAY;AACjD,OAAG,iBAAiB,OAAO,UAAU,OAAO;AAC5C,WAAO,MAAM,GAAG,oBAAoB,OAAO,UAAU,OAAO;AAAA,EAC9D;AACA,QAAM,oBAAoB,SAAS,MAAM;AACvC,UAAM,OAAO,QAAQ,QAAQ,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,KAAK,IAAI;AAC9D,WAAO,KAAK,MAAM,CAAC,MAAM,OAAO,MAAM,QAAQ,IAAI,OAAO;AAAA,EAC3D,CAAC;AACD,QAAM,YAAY;AAAA,IAChB,MAAM;AACJ,UAAI,IAAI;AACR,aAAO;AAAA,SACJ,MAAM,KAAK,kBAAkB,UAAU,OAAO,SAAS,GAAG,IAAI,CAAC,MAAM,aAAa,CAAC,CAAC,MAAM,OAAO,KAAK,CAAC,aAAa,EAAE,OAAO,CAAC,MAAM,KAAK,IAAI;AAAA,QAC9I,QAAQ,QAAQ,kBAAkB,QAAQ,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;AAAA,QAC5D,QAAQ,MAAM,kBAAkB,QAAQ,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;AAAA;AAAA,QAE1D,QAAQ,kBAAkB,QAAQ,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,IACA,CAAC,CAAC,aAAa,YAAY,eAAe,WAAW,MAAM;AACzD,cAAQ;AACR,UAAI,EAAE,eAAe,OAAO,SAAS,YAAY,WAAW,EAAE,cAAc,OAAO,SAAS,WAAW,WAAW,EAAE,iBAAiB,OAAO,SAAS,cAAc;AACjK;AACF,YAAM,eAAe,SAAS,WAAW,IAAI,EAAE,GAAG,YAAY,IAAI;AAClE,eAAS;AAAA,QACP,GAAG,YAAY;AAAA,UACb,CAAC,OAAO,WAAW;AAAA,YACjB,CAAC,UAAU,cAAc,IAAI,CAAC,aAAa,SAAS,IAAI,OAAO,UAAU,YAAY,CAAC;AAAA,UACxF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,OAAO,OAAO;AAAA,EAClB;AACA,QAAM,OAAO,MAAM;AACjB,cAAU;AACV,YAAQ;AAAA,EACV;AACA,oBAAkB,OAAO;AACzB,SAAO;AACT;AAEA,IAAI,iBAAiB;AACrB,SAAS,eAAe,QAAQ,SAAS,UAAU,CAAC,GAAG;AACrD,QAAM,EAAE,QAAAO,UAAS,eAAe,SAAS,CAAC,GAAG,UAAU,MAAM,eAAe,OAAO,WAAW,MAAM,IAAI;AACxG,MAAI,CAACA,SAAQ;AACX,WAAO,WAAW,EAAE,MAAM,MAAM,QAAQ,MAAM,SAAS,KAAK,IAAI;AAAA,EAClE;AACA,MAAI,SAAS,CAAC,gBAAgB;AAC5B,qBAAiB;AACjB,UAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,UAAM,KAAKA,QAAO,SAAS,KAAK,QAAQ,EAAE,QAAQ,CAAC,OAAO,iBAAiB,IAAI,SAAS,MAAM,eAAe,CAAC;AAC9G,qBAAiBA,QAAO,SAAS,iBAAiB,SAAS,MAAM,eAAe;AAAA,EAClF;AACA,MAAI,eAAe;AACnB,QAAM,eAAe,CAAC,UAAU;AAC9B,WAAO,QAAQ,MAAM,EAAE,KAAK,CAAC,YAAY;AACvC,UAAI,OAAO,YAAY,UAAU;AAC/B,eAAO,MAAM,KAAKA,QAAO,SAAS,iBAAiB,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,OAAO,MAAM,UAAU,MAAM,aAAa,EAAE,SAAS,EAAE,CAAC;AAAA,MACpI,OAAO;AACL,cAAM,KAAK,aAAa,OAAO;AAC/B,eAAO,OAAO,MAAM,WAAW,MAAM,MAAM,aAAa,EAAE,SAAS,EAAE;AAAA,MACvE;AAAA,IACF,CAAC;AAAA,EACH;AACA,WAAS,iBAAiB,SAAS;AACjC,UAAM,KAAK,QAAQ,OAAO;AAC1B,WAAO,MAAM,GAAG,EAAE,QAAQ,cAAc;AAAA,EAC1C;AACA,WAAS,mBAAmB,SAAS,OAAO;AAC1C,UAAM,KAAK,QAAQ,OAAO;AAC1B,UAAM,WAAW,GAAG,EAAE,WAAW,GAAG,EAAE,QAAQ;AAC9C,QAAI,YAAY,QAAQ,CAAC,MAAM,QAAQ,QAAQ;AAC7C,aAAO;AACT,WAAO,SAAS,KAAK,CAAC,UAAU,MAAM,OAAO,MAAM,UAAU,MAAM,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;AAAA,EACtG;AACA,QAAM,WAAW,CAAC,UAAU;AAC1B,UAAM,KAAK,aAAa,MAAM;AAC9B,QAAI,MAAM,UAAU;AAClB;AACF,QAAI,EAAE,cAAc,YAAY,iBAAiB,MAAM,KAAK,mBAAmB,QAAQ,KAAK;AAC1F;AACF,QAAI,CAAC,MAAM,OAAO,MAAM,UAAU,MAAM,aAAa,EAAE,SAAS,EAAE;AAChE;AACF,QAAI,YAAY,SAAS,MAAM,WAAW;AACxC,qBAAe,CAAC,aAAa,KAAK;AACpC,QAAI,CAAC,cAAc;AACjB,qBAAe;AACf;AAAA,IACF;AACA,YAAQ,KAAK;AAAA,EACf;AACA,MAAI,oBAAoB;AACxB,QAAM,UAAU;AAAA,IACd,iBAAiBA,SAAQ,SAAS,CAAC,UAAU;AAC3C,UAAI,CAAC,mBAAmB;AACtB,4BAAoB;AACpB,mBAAW,MAAM;AACf,8BAAoB;AAAA,QACtB,GAAG,CAAC;AACJ,iBAAS,KAAK;AAAA,MAChB;AAAA,IACF,GAAG,EAAE,SAAS,MAAM,QAAQ,CAAC;AAAA,IAC7B,iBAAiBA,SAAQ,eAAe,CAAC,MAAM;AAC7C,YAAM,KAAK,aAAa,MAAM;AAC9B,qBAAe,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,aAAa,EAAE,SAAS,EAAE;AAAA,IAC3E,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,IACpB,gBAAgB,iBAAiBA,SAAQ,QAAQ,CAAC,UAAU;AAC1D,iBAAW,MAAM;AACf,YAAI;AACJ,cAAM,KAAK,aAAa,MAAM;AAC9B,cAAM,KAAKA,QAAO,SAAS,kBAAkB,OAAO,SAAS,GAAG,aAAa,YAAY,EAAE,MAAM,OAAO,SAAS,GAAG,SAASA,QAAO,SAAS,aAAa,IAAI;AAC5J,kBAAQ,KAAK;AAAA,QACf;AAAA,MACF,GAAG,CAAC;AAAA,IACN,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,EACtB,EAAE,OAAO,OAAO;AAChB,QAAM,OAAO,MAAM,QAAQ,QAAQ,CAAC,OAAO,GAAG,CAAC;AAC/C,MAAI,UAAU;AACZ,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,MAAM;AACZ,uBAAe;AAAA,MACjB;AAAA,MACA,SAAS,CAAC,UAAU;AAClB,uBAAe;AACf,iBAAS,KAAK;AACd,uBAAe;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa;AACpB,QAAM,YAAY,WAAW,KAAK;AAClC,QAAM,WAAW,mBAAmB;AACpC,MAAI,UAAU;AACZ,cAAU,MAAM;AACd,gBAAU,QAAQ;AAAA,IACpB,GAAG,QAAQ;AAAA,EACb;AACA,SAAO;AACT;AAEA,SAAS,aAAa,UAAU;AAC9B,QAAM,YAAY,WAAW;AAC7B,SAAO,SAAS,MAAM;AACpB,cAAU;AACV,WAAO,QAAQ,SAAS,CAAC;AAAA,EAC3B,CAAC;AACH;AAEA,SAAS,oBAAoB,QAAQ,UAAU,UAAU,CAAC,GAAG;AAC3D,QAAM,EAAE,QAAAA,UAAS,eAAe,GAAG,gBAAgB,IAAI;AACvD,MAAI;AACJ,QAAM,cAAc,aAAa,MAAMA,WAAU,sBAAsBA,OAAM;AAC7E,QAAM,UAAU,MAAM;AACpB,QAAI,UAAU;AACZ,eAAS,WAAW;AACpB,iBAAW;AAAA,IACb;AAAA,EACF;AACA,QAAM,UAAU,SAAS,MAAM;AAC7B,UAAM,QAAQ,QAAQ,MAAM;AAC5B,UAAM,QAAQ,QAAQ,KAAK,EAAE,IAAI,YAAY,EAAE,OAAO,UAAU;AAChE,WAAO,IAAI,IAAI,KAAK;AAAA,EACtB,CAAC;AACD,QAAM,YAAY;AAAA,IAChB,MAAM,QAAQ;AAAA,IACd,CAAC,aAAa;AACZ,cAAQ;AACR,UAAI,YAAY,SAAS,SAAS,MAAM;AACtC,mBAAW,IAAI,iBAAiB,QAAQ;AACxC,iBAAS,QAAQ,CAAC,OAAO,SAAS,QAAQ,IAAI,eAAe,CAAC;AAAA,MAChE;AAAA,IACF;AAAA,IACA,EAAE,WAAW,MAAM,OAAO,OAAO;AAAA,EACnC;AACA,QAAM,cAAc,MAAM;AACxB,WAAO,YAAY,OAAO,SAAS,SAAS,YAAY;AAAA,EAC1D;AACA,QAAM,OAAO,MAAM;AACjB,cAAU;AACV,YAAQ;AAAA,EACV;AACA,oBAAkB,IAAI;AACtB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,QAAQ,UAAU,UAAU,CAAC,GAAG;AACxD,QAAM;AAAA,IACJ,QAAAA,UAAS;AAAA,IACT,UAAAC,YAAWD,WAAU,OAAO,SAASA,QAAO;AAAA,IAC5C,QAAQ;AAAA,EACV,IAAI;AACJ,MAAI,CAACA,WAAU,CAACC;AACd,WAAO;AACT,MAAI;AACJ,QAAM,mBAAmB,CAAC,OAAO;AAC/B,cAAU,OAAO,SAAS,OAAO;AACjC,aAAS;AAAA,EACX;AACA,QAAM,YAAY,YAAY,MAAM;AAClC,UAAM,KAAK,aAAa,MAAM;AAC9B,QAAI,IAAI;AACN,YAAM,EAAE,KAAK,IAAI;AAAA,QACfA;AAAA,QACA,CAAC,kBAAkB;AACjB,gBAAM,gBAAgB,cAAc,IAAI,CAAC,aAAa,CAAC,GAAG,SAAS,YAAY,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,SAAS,SAAS,MAAM,KAAK,SAAS,EAAE,CAAC;AACxI,cAAI,eAAe;AACjB,qBAAS,aAAa;AAAA,UACxB;AAAA,QACF;AAAA,QACA;AAAA,UACE,QAAAD;AAAA,UACA,WAAW;AAAA,UACX,SAAS;AAAA,QACX;AAAA,MACF;AACA,uBAAiB,IAAI;AAAA,IACvB;AAAA,EACF,GAAG,EAAE,MAAM,CAAC;AACZ,QAAM,aAAa,MAAM;AACvB,cAAU;AACV,qBAAiB;AAAA,EACnB;AACA,oBAAkB,UAAU;AAC5B,SAAO;AACT;AAEA,SAAS,mBAAmB,WAAW;AACrC,MAAI,OAAO,cAAc;AACvB,WAAO;AAAA,WACA,OAAO,cAAc;AAC5B,WAAO,CAAC,UAAU,MAAM,QAAQ;AAAA,WACzB,MAAM,QAAQ,SAAS;AAC9B,WAAO,CAAC,UAAU,UAAU,SAAS,MAAM,GAAG;AAChD,SAAO,MAAM;AACf;AACA,SAAS,eAAe,MAAM;AAC5B,MAAI;AACJ,MAAI;AACJ,MAAI,UAAU,CAAC;AACf,MAAI,KAAK,WAAW,GAAG;AACrB,UAAM,KAAK,CAAC;AACZ,cAAU,KAAK,CAAC;AAChB,cAAU,KAAK,CAAC;AAAA,EAClB,WAAW,KAAK,WAAW,GAAG;AAC5B,QAAI,OAAO,KAAK,CAAC,MAAM,UAAU;AAC/B,YAAM;AACN,gBAAU,KAAK,CAAC;AAChB,gBAAU,KAAK,CAAC;AAAA,IAClB,OAAO;AACL,YAAM,KAAK,CAAC;AACZ,gBAAU,KAAK,CAAC;AAAA,IAClB;AAAA,EACF,OAAO;AACL,UAAM;AACN,cAAU,KAAK,CAAC;AAAA,EAClB;AACA,QAAM;AAAA,IACJ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,SAAS;AAAA,EACX,IAAI;AACJ,QAAM,YAAY,mBAAmB,GAAG;AACxC,QAAM,WAAW,CAAC,MAAM;AACtB,QAAI,EAAE,UAAU,QAAQ,MAAM;AAC5B;AACF,QAAI,UAAU,CAAC;AACb,cAAQ,CAAC;AAAA,EACb;AACA,SAAO,iBAAiB,QAAQ,WAAW,UAAU,OAAO;AAC9D;AACA,SAAS,UAAU,KAAK,SAAS,UAAU,CAAC,GAAG;AAC7C,SAAO,YAAY,KAAK,SAAS,EAAE,GAAG,SAAS,WAAW,UAAU,CAAC;AACvE;AACA,SAAS,aAAa,KAAK,SAAS,UAAU,CAAC,GAAG;AAChD,SAAO,YAAY,KAAK,SAAS,EAAE,GAAG,SAAS,WAAW,WAAW,CAAC;AACxE;AACA,SAAS,QAAQ,KAAK,SAAS,UAAU,CAAC,GAAG;AAC3C,SAAO,YAAY,KAAK,SAAS,EAAE,GAAG,SAAS,WAAW,QAAQ,CAAC;AACrE;AAEA,IAAM,gBAAgB;AACtB,IAAM,oBAAoB;AAC1B,SAAS,YAAY,QAAQ,SAAS,SAAS;AAC7C,MAAI,IAAI;AACR,QAAM,aAAa,SAAS,MAAM,aAAa,MAAM,CAAC;AACtD,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI,iBAAiB;AACrB,WAAS,QAAQ;AACf,QAAI,SAAS;AACX,mBAAa,OAAO;AACpB,gBAAU;AAAA,IACZ;AACA,eAAW;AACX,qBAAiB;AACjB,qBAAiB;AAAA,EACnB;AACA,WAAS,UAAU,IAAI;AACrB,QAAI,KAAK,KAAK;AACd,UAAM,CAAC,iBAAiB,WAAW,eAAe,IAAI,CAAC,gBAAgB,UAAU,cAAc;AAC/F,UAAM;AACN,QAAI,EAAE,WAAW,OAAO,SAAS,QAAQ,cAAc,CAAC,aAAa,CAAC;AACpE;AACF,UAAM,MAAM,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,SAAS,IAAI,SAAS,GAAG,WAAW,WAAW;AACjH;AACF,SAAK,MAAM,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,SAAS,IAAI;AAC9E,SAAG,eAAe;AACpB,SAAK,KAAK,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,SAAS,GAAG;AAC5E,SAAG,gBAAgB;AACrB,UAAM,KAAK,GAAG,IAAI,UAAU;AAC5B,UAAM,KAAK,GAAG,IAAI,UAAU;AAC5B,UAAM,WAAW,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAC5C,YAAQ,UAAU,GAAG,YAAY,iBAAiB,UAAU,eAAe;AAAA,EAC7E;AACA,WAAS,OAAO,IAAI;AAClB,QAAI,KAAK,KAAK,IAAI;AAClB,UAAM,MAAM,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,SAAS,IAAI,SAAS,GAAG,WAAW,WAAW;AACjH;AACF,UAAM;AACN,SAAK,MAAM,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,SAAS,IAAI;AAC9E,SAAG,eAAe;AACpB,SAAK,KAAK,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,SAAS,GAAG;AAC5E,SAAG,gBAAgB;AACrB,eAAW;AAAA,MACT,GAAG,GAAG;AAAA,MACN,GAAG,GAAG;AAAA,IACR;AACA,qBAAiB,GAAG;AACpB,cAAU;AAAA,MACR,MAAM;AACJ,yBAAiB;AACjB,gBAAQ,EAAE;AAAA,MACZ;AAAA,OACC,KAAK,WAAW,OAAO,SAAS,QAAQ,UAAU,OAAO,KAAK;AAAA,IACjE;AAAA,EACF;AACA,WAAS,OAAO,IAAI;AAClB,QAAI,KAAK,KAAK,IAAI;AAClB,UAAM,MAAM,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,SAAS,IAAI,SAAS,GAAG,WAAW,WAAW;AACjH;AACF,QAAI,CAAC,aAAa,WAAW,OAAO,SAAS,QAAQ,uBAAuB;AAC1E;AACF,SAAK,MAAM,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,SAAS,IAAI;AAC9E,SAAG,eAAe;AACpB,SAAK,KAAK,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,SAAS,GAAG;AAC5E,SAAG,gBAAgB;AACrB,UAAM,KAAK,GAAG,IAAI,SAAS;AAC3B,UAAM,KAAK,GAAG,IAAI,SAAS;AAC3B,UAAM,WAAW,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAC5C,QAAI,cAAc,KAAK,WAAW,OAAO,SAAS,QAAQ,sBAAsB,OAAO,KAAK;AAC1F,YAAM;AAAA,EACV;AACA,QAAM,kBAAkB;AAAA,IACtB,UAAU,KAAK,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,SAAS,GAAG;AAAA,IACnF,OAAO,KAAK,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,SAAS,GAAG;AAAA,EAClF;AACA,QAAM,UAAU;AAAA,IACd,iBAAiB,YAAY,eAAe,QAAQ,eAAe;AAAA,IACnE,iBAAiB,YAAY,eAAe,QAAQ,eAAe;AAAA,IACnE,iBAAiB,YAAY,CAAC,aAAa,cAAc,GAAG,WAAW,eAAe;AAAA,EACxF;AACA,QAAM,OAAO,MAAM,QAAQ,QAAQ,CAAC,OAAO,GAAG,CAAC;AAC/C,SAAO;AACT;AAEA,SAAS,2BAA2B;AAClC,QAAM,EAAE,eAAe,KAAK,IAAI;AAChC,MAAI,CAAC;AACH,WAAO;AACT,MAAI,kBAAkB;AACpB,WAAO;AACT,UAAQ,cAAc,SAAS;AAAA,IAC7B,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,EACX;AACA,SAAO,cAAc,aAAa,iBAAiB;AACrD;AACA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAG;AACD,MAAI,WAAW,WAAW;AACxB,WAAO;AACT,MAAI,WAAW,MAAM,WAAW,MAAM,WAAW,MAAM,WAAW;AAChE,WAAO;AACT,MAAI,WAAW,MAAM,WAAW;AAC9B,WAAO;AACT,SAAO;AACT;AACA,SAAS,cAAc,UAAU,UAAU,CAAC,GAAG;AAC7C,QAAM,EAAE,UAAU,YAAY,gBAAgB,IAAI;AAClD,QAAM,UAAU,CAAC,UAAU;AACzB,QAAI,CAAC,yBAAyB,KAAK,iBAAiB,KAAK,GAAG;AAC1D,eAAS,KAAK;AAAA,IAChB;AAAA,EACF;AACA,MAAI;AACF,qBAAiB,WAAW,WAAW,SAAS,EAAE,SAAS,KAAK,CAAC;AACrE;AAEA,SAAS,YAAY,KAAK,eAAe,MAAM;AAC7C,QAAM,WAAW,mBAAmB;AACpC,MAAI,WAAW,MAAM;AAAA,EACrB;AACA,QAAM,UAAU,UAAU,CAAC,OAAO,YAAY;AAC5C,eAAW;AACX,WAAO;AAAA,MACL,MAAM;AACJ,YAAI,IAAI;AACR,cAAM;AACN,gBAAQ,MAAM,KAAK,YAAY,OAAO,SAAS,SAAS,UAAU,OAAO,SAAS,GAAG,MAAM,GAAG,MAAM,OAAO,KAAK;AAAA,MAClH;AAAA,MACA,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF,CAAC;AACD,eAAa,QAAQ;AACrB,YAAU,QAAQ;AAClB,SAAO;AACT;AAEA,SAAS,iBAAiB,UAAU,CAAC,GAAG;AACtC,MAAI;AACJ,QAAM;AAAA,IACJ,QAAAA,UAAS;AAAA,IACT,OAAO;AAAA,IACP,mBAAmB;AAAA,EACrB,IAAI;AACJ,QAAMC,aAAY,KAAK,QAAQ,aAAa,OAAO,KAAKD,WAAU,OAAO,SAASA,QAAO;AACzF,QAAM,uBAAuB,MAAM;AACjC,QAAI;AACJ,QAAI,UAAUC,aAAY,OAAO,SAASA,UAAS;AACnD,QAAI,MAAM;AACR,aAAO,WAAW,OAAO,SAAS,QAAQ;AACxC,mBAAW,MAAM,WAAW,OAAO,SAAS,QAAQ,eAAe,OAAO,SAAS,IAAI;AAAA,IAC3F;AACA,WAAO;AAAA,EACT;AACA,QAAM,gBAAgB,WAAW;AACjC,QAAM,UAAU,MAAM;AACpB,kBAAc,QAAQ,qBAAqB;AAAA,EAC7C;AACA,MAAID,SAAQ;AACV,UAAM,kBAAkB;AAAA,MACtB,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AACA;AAAA,MACEA;AAAA,MACA;AAAA,MACA,CAAC,UAAU;AACT,YAAI,MAAM,kBAAkB;AAC1B;AACF,gBAAQ;AAAA,MACV;AAAA,MACA;AAAA,IACF;AACA;AAAA,MACEA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,kBAAkB;AACpB,qBAAiB,eAAe,SAAS,EAAE,UAAAC,UAAS,CAAC;AAAA,EACvD;AACA,UAAQ;AACR,SAAO;AACT;AAEA,SAAS,SAAS,IAAI,UAAU,CAAC,GAAG;AAClC,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,QAAAD,UAAS;AAAA,IACT,OAAO;AAAA,EACT,IAAI;AACJ,QAAM,WAAW,WAAW,KAAK;AACjC,QAAM,gBAAgB,SAAS,MAAM;AACnC,WAAO,WAAW,MAAM,QAAQ,QAAQ,IAAI;AAAA,EAC9C,CAAC;AACD,MAAI,yBAAyB;AAC7B,MAAI,QAAQ;AACZ,WAAS,KAAKE,YAAW;AACvB,QAAI,CAAC,SAAS,SAAS,CAACF;AACtB;AACF,QAAI,CAAC;AACH,+BAAyBE;AAC3B,UAAM,QAAQA,aAAY;AAC1B,QAAI,cAAc,SAAS,QAAQ,cAAc,OAAO;AACtD,cAAQF,QAAO,sBAAsB,IAAI;AACzC;AAAA,IACF;AACA,6BAAyBE;AACzB,OAAG,EAAE,OAAO,WAAAA,WAAU,CAAC;AACvB,QAAI,MAAM;AACR,eAAS,QAAQ;AACjB,cAAQ;AACR;AAAA,IACF;AACA,YAAQF,QAAO,sBAAsB,IAAI;AAAA,EAC3C;AACA,WAAS,SAAS;AAChB,QAAI,CAAC,SAAS,SAASA,SAAQ;AAC7B,eAAS,QAAQ;AACjB,+BAAyB;AACzB,cAAQA,QAAO,sBAAsB,IAAI;AAAA,IAC3C;AAAA,EACF;AACA,WAAS,QAAQ;AACf,aAAS,QAAQ;AACjB,QAAI,SAAS,QAAQA,SAAQ;AAC3B,MAAAA,QAAO,qBAAqB,KAAK;AACjC,cAAQ;AAAA,IACV;AAAA,EACF;AACA,MAAI;AACF,WAAO;AACT,oBAAkB,KAAK;AACvB,SAAO;AAAA,IACL,UAAU,SAAS,QAAQ;AAAA,IAC3B;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,WAAW,QAAQ,WAAW,SAAS;AAC9C,MAAI;AACJ,MAAI;AACJ,MAAI,SAAS,OAAO,GAAG;AACrB,aAAS;AACT,qBAAiB,WAAW,SAAS,CAAC,UAAU,aAAa,gBAAgB,WAAW,WAAW,SAAS,CAAC;AAAA,EAC/G,OAAO;AACL,aAAS,EAAE,UAAU,QAAQ;AAC7B,qBAAiB;AAAA,EACnB;AACA,QAAM;AAAA,IACJ,QAAAA,UAAS;AAAA,IACT,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA,cAAc,gBAAgB;AAAA,IAC9B;AAAA,IACA,UAAU,CAAC,MAAM;AACf,cAAQ,MAAM,CAAC;AAAA,IACjB;AAAA,EACF,IAAI;AACJ,QAAM,cAAc,aAAa,MAAMA,WAAU,eAAe,aAAa,YAAY,SAAS;AAClG,QAAM,UAAU,WAAW,MAAM;AACjC,QAAM,QAAQ,gBAAgB;AAAA,IAC5B,WAAW;AAAA,IACX,aAAa;AAAA,IACb,UAAU;AAAA,IACV,cAAc;AAAA,IACd,SAAS;AAAA,IACT,WAAW,YAAY,SAAS;AAAA,IAChC,cAAc;AAAA,EAChB,CAAC;AACD,QAAM,UAAU,SAAS,MAAM,MAAM,OAAO;AAC5C,QAAM,YAAY,SAAS,MAAM,MAAM,SAAS;AAChD,QAAM,eAAe,SAAS,MAAM,MAAM,YAAY;AACtD,QAAM,YAAY,SAAS;AAAA,IACzB,MAAM;AACJ,aAAO,MAAM;AAAA,IACf;AAAA,IACA,IAAI,OAAO;AACT,YAAM,YAAY;AAClB,UAAI,QAAQ;AACV,gBAAQ,MAAM,YAAY;AAAA,IAC9B;AAAA,EACF,CAAC;AACD,QAAM,cAAc,SAAS;AAAA,IAC3B,MAAM;AACJ,aAAO,MAAM;AAAA,IACf;AAAA,IACA,IAAI,OAAO;AACT,YAAM,cAAc;AACpB,UAAI,QAAQ,OAAO;AACjB,gBAAQ,MAAM,cAAc;AAC5B,mBAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF,CAAC;AACD,QAAM,WAAW,SAAS;AAAA,IACxB,MAAM;AACJ,aAAO,MAAM;AAAA,IACf;AAAA,IACA,IAAI,OAAO;AACT,YAAM,WAAW;AACjB,UAAI,QAAQ;AACV,gBAAQ,MAAM,WAAW;AAAA,IAC7B;AAAA,EACF,CAAC;AACD,QAAM,eAAe,SAAS;AAAA,IAC5B,MAAM;AACJ,aAAO,MAAM;AAAA,IACf;AAAA,IACA,IAAI,OAAO;AACT,YAAM,eAAe;AACrB,UAAI,QAAQ;AACV,gBAAQ,MAAM,eAAe;AAAA,IACjC;AAAA,EACF,CAAC;AACD,QAAM,OAAO,MAAM;AACjB,QAAI,QAAQ,OAAO;AACjB,UAAI;AACF,gBAAQ,MAAM,KAAK;AACnB,mBAAW;AAAA,MACb,SAAS,GAAG;AACV,kBAAU;AACV,gBAAQ,CAAC;AAAA,MACX;AAAA,IACF,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,QAAQ,MAAM;AAClB,QAAI;AACJ,QAAI;AACF,OAAC,KAAK,QAAQ,UAAU,OAAO,SAAS,GAAG,MAAM;AACjD,gBAAU;AAAA,IACZ,SAAS,GAAG;AACV,cAAQ,CAAC;AAAA,IACX;AAAA,EACF;AACA,QAAM,UAAU,MAAM;AACpB,QAAI;AACJ,QAAI,CAAC,QAAQ;AACX,aAAO;AACT,QAAI;AACF,OAAC,KAAK,QAAQ,UAAU,OAAO,SAAS,GAAG,QAAQ;AACnD,iBAAW;AAAA,IACb,SAAS,GAAG;AACV,gBAAU;AACV,cAAQ,CAAC;AAAA,IACX;AAAA,EACF;AACA,QAAM,SAAS,MAAM;AACnB,QAAI;AACJ,QAAI;AACF,OAAC,KAAK,QAAQ,UAAU,OAAO,SAAS,GAAG,OAAO;AAClD,gBAAU;AAAA,IACZ,SAAS,GAAG;AACV,cAAQ,CAAC;AAAA,IACX;AAAA,EACF;AACA,QAAM,SAAS,MAAM;AACnB,QAAI;AACJ,QAAI;AACF,OAAC,KAAK,QAAQ,UAAU,OAAO,SAAS,GAAG,OAAO;AAClD,gBAAU;AAAA,IACZ,SAAS,GAAG;AACV,cAAQ,CAAC;AAAA,IACX;AAAA,EACF;AACA,QAAM,MAAM,aAAa,MAAM,GAAG,CAAC,OAAO;AACxC,QAAI,IAAI;AACN,aAAO;AAAA,IACT,OAAO;AACL,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF,CAAC;AACD,QAAM,MAAM,WAAW,CAAC,UAAU;AAChC,QAAI,QAAQ,OAAO;AACjB,aAAO;AACP,YAAM,WAAW,aAAa,MAAM;AACpC,UAAI,UAAU;AACZ,gBAAQ,MAAM,SAAS,IAAI;AAAA,UACzB;AAAA,UACA,QAAQ,KAAK;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,EAAE,MAAM,KAAK,CAAC;AACjB,eAAa,MAAM,OAAO,IAAI,GAAG,KAAK;AACtC,oBAAkB,MAAM;AACxB,WAAS,OAAO,MAAM;AACpB,UAAM,KAAK,aAAa,MAAM;AAC9B,QAAI,CAAC,YAAY,SAAS,CAAC;AACzB;AACF,QAAI,CAAC,QAAQ;AACX,cAAQ,QAAQ,GAAG,QAAQ,QAAQ,SAAS,GAAG,cAAc;AAC/D,QAAI;AACF,cAAQ,MAAM,QAAQ;AACxB,QAAI,kBAAkB;AACpB,cAAQ,MAAM,eAAe;AAC/B,QAAI,QAAQ,CAAC;AACX,cAAQ,MAAM,MAAM;AAAA;AAEpB,iBAAW;AACb,eAAW,OAAO,SAAS,QAAQ,QAAQ,KAAK;AAAA,EAClD;AACA,QAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,mBAAiB,SAAS,CAAC,UAAU,UAAU,QAAQ,GAAG,WAAW,eAAe;AACpF,mBAAiB,SAAS,UAAU,MAAM;AACxC,QAAI;AACJ,QAAI;AACF,OAAC,KAAK,QAAQ,UAAU,OAAO,SAAS,GAAG,aAAa;AAAA,EAC5D,GAAG,eAAe;AAClB,QAAM,EAAE,QAAQ,WAAW,OAAO,SAAS,IAAI,SAAS,MAAM;AAC5D,QAAI,CAAC,QAAQ;AACX;AACF,UAAM,UAAU,QAAQ,MAAM;AAC9B,UAAM,YAAY,QAAQ,MAAM;AAChC,UAAM,eAAe,QAAQ,MAAM;AACnC,UAAM,YAAY,QAAQ,MAAM;AAChC,UAAM,cAAc,QAAQ,MAAM;AAClC,UAAM,WAAW,QAAQ,MAAM;AAC/B,UAAM,eAAe,QAAQ,MAAM;AAAA,EACrC,GAAG,EAAE,WAAW,MAAM,CAAC;AACvB,WAAS,aAAa;AACpB,QAAI,YAAY;AACd,gBAAU;AAAA,EACd;AACA,WAAS,YAAY;AACnB,QAAI,YAAY,SAASA;AACvB,MAAAA,QAAO,sBAAsB,QAAQ;AAAA,EACzC;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,cAAc,OAAO,SAAS;AACrC,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,aAAa;AAAA,IACb;AAAA,EACF,IAAI,WAAW,CAAC;AAChB,QAAM,eAAe;AAAA,IACnB,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AACA,QAAM,gBAAgB,MAAM,KAAK,MAAM,KAAK,EAAE,QAAQ,MAAM,OAAO,CAAC,GAAG,OAAO,EAAE,OAAO,aAAa,SAAS,MAAM,KAAK,EAAE;AAC1H,QAAM,SAAS,SAAS,aAAa;AACrC,QAAM,cAAc,WAAW,EAAE;AACjC,MAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,eAAW;AACX,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,WAAS,aAAa,OAAO,KAAK;AAChC,gBAAY;AACZ,WAAO,YAAY,KAAK,EAAE,OAAO;AACjC,WAAO,YAAY,KAAK,EAAE,QAAQ;AAAA,EACpC;AACA,QAAM,OAAO,CAAC,MAAM,SAAS;AAC3B,WAAO,KAAK,KAAK,CAAC,YAAY;AAC5B,UAAI;AACJ,UAAI,UAAU,OAAO,SAAS,OAAO,SAAS;AAC5C,qBAAa,aAAa,SAAS,IAAI,MAAM,SAAS,CAAC;AACvD;AAAA,MACF;AACA,YAAM,KAAK,OAAO,YAAY,KAAK,MAAM,OAAO,SAAS,GAAG,WAAW,aAAa,YAAY,WAAW;AACzG,mBAAW;AACX;AAAA,MACF;AACA,YAAM,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC,eAAe;AAC9C,qBAAa,aAAa,WAAW,UAAU;AAC/C,YAAI,YAAY,UAAU,MAAM,SAAS;AACvC,qBAAW;AACb,eAAO;AAAA,MACT,CAAC;AACD,UAAI,CAAC;AACH,eAAO;AACT,aAAO,QAAQ,KAAK,CAAC,MAAM,YAAY,MAAM,CAAC,CAAC;AAAA,IACjD,CAAC,EAAE,MAAM,CAAC,MAAM;AACd,UAAI,UAAU,OAAO,SAAS,OAAO,SAAS;AAC5C,qBAAa,aAAa,SAAS,CAAC;AACpC,eAAO;AAAA,MACT;AACA,mBAAa,aAAa,UAAU,CAAC;AACrC,cAAQ;AACR,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,QAAQ,QAAQ,CAAC;AACpB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AACA,SAAS,YAAY,QAAQ;AAC3B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,QAAQ,IAAI,MAAM,SAAS;AACjC,QAAI,OAAO;AACT,aAAO,KAAK;AAAA;AAEZ,aAAO,iBAAiB,SAAS,MAAM,OAAO,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,EACxE,CAAC;AACH;AAEA,SAAS,cAAc,SAAS,cAAc,SAAS;AACrD,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,UAAU;AAAA,IACV;AAAA,EACF,IAAI,WAAW,OAAO,UAAU,CAAC;AACjC,QAAM,QAAQ,UAAU,WAAW,YAAY,IAAI,IAAI,YAAY;AACnE,QAAM,UAAU,WAAW,KAAK;AAChC,QAAM,YAAY,WAAW,KAAK;AAClC,QAAM,QAAQ,WAAW,MAAM;AAC/B,iBAAe,QAAQ,SAAS,MAAM,MAAM;AAC1C,QAAI;AACF,YAAM,QAAQ;AAChB,UAAM,QAAQ;AACd,YAAQ,QAAQ;AAChB,cAAU,QAAQ;AAClB,QAAI,SAAS;AACX,YAAM,eAAe,MAAM;AAC7B,UAAM,WAAW,OAAO,YAAY,aAAa,QAAQ,GAAG,IAAI,IAAI;AACpE,QAAI;AACF,YAAM,OAAO,MAAM;AACnB,YAAM,QAAQ;AACd,cAAQ,QAAQ;AAChB,gBAAU,IAAI;AAAA,IAChB,SAAS,GAAG;AACV,YAAM,QAAQ;AACd,cAAQ,CAAC;AACT,UAAI;AACF,cAAM;AAAA,IACV,UAAE;AACA,gBAAU,QAAQ;AAAA,IACpB;AACA,WAAO,MAAM;AAAA,EACf;AACA,MAAI,WAAW;AACb,YAAQ,KAAK;AAAA,EACf;AACA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,WAAS,oBAAoB;AAC3B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,SAAS,EAAE,KAAK,KAAK,EAAE,KAAK,MAAM,QAAQ,KAAK,CAAC,EAAE,MAAM,MAAM;AAAA,IACtE,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,KAAK,aAAa,YAAY;AAC5B,aAAO,kBAAkB,EAAE,KAAK,aAAa,UAAU;AAAA,IACzD;AAAA,EACF;AACF;AAEA,IAAM,WAAW;AAAA,EACf,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC;AAAA,EAC9B,QAAQ,CAAC,MAAM,KAAK,UAAU,CAAC;AAAA,EAC/B,KAAK,CAAC,MAAM,KAAK,UAAU,MAAM,KAAK,CAAC,CAAC;AAAA,EACxC,KAAK,CAAC,MAAM,KAAK,UAAU,OAAO,YAAY,CAAC,CAAC;AAAA,EAChD,MAAM,MAAM;AACd;AACA,SAAS,wBAAwB,QAAQ;AACvC,MAAI,CAAC;AACH,WAAO,SAAS;AAClB,MAAI,kBAAkB;AACpB,WAAO,SAAS;AAAA,WACT,kBAAkB;AACzB,WAAO,SAAS;AAAA,WACT,MAAM,QAAQ,MAAM;AAC3B,WAAO,SAAS;AAAA;AAEhB,WAAO,SAAS;AACpB;AAEA,SAAS,UAAU,QAAQ,SAAS;AAClC,QAAM,SAAS,WAAW,EAAE;AAC5B,QAAM,UAAU,WAAW;AAC3B,WAAS,UAAU;AACjB,QAAI,CAAC;AACH;AACF,YAAQ,QAAQ,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC/C,UAAI;AACF,cAAM,UAAU,QAAQ,MAAM;AAC9B,YAAI,WAAW,MAAM;AACnB,kBAAQ,EAAE;AAAA,QACZ,WAAW,OAAO,YAAY,UAAU;AACtC,kBAAQ,aAAa,IAAI,KAAK,CAAC,OAAO,GAAG,EAAE,MAAM,aAAa,CAAC,CAAC,CAAC;AAAA,QACnE,WAAW,mBAAmB,MAAM;AAClC,kBAAQ,aAAa,OAAO,CAAC;AAAA,QAC/B,WAAW,mBAAmB,aAAa;AACzC,kBAAQ,OAAO,KAAK,OAAO,aAAa,GAAG,IAAI,WAAW,OAAO,CAAC,CAAC,CAAC;AAAA,QACtE,WAAW,mBAAmB,mBAAmB;AAC/C,kBAAQ,QAAQ,UAAU,WAAW,OAAO,SAAS,QAAQ,MAAM,WAAW,OAAO,SAAS,QAAQ,OAAO,CAAC;AAAA,QAChH,WAAW,mBAAmB,kBAAkB;AAC9C,gBAAM,MAAM,QAAQ,UAAU,KAAK;AACnC,cAAI,cAAc;AAClB,oBAAU,GAAG,EAAE,KAAK,MAAM;AACxB,kBAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,kBAAM,MAAM,OAAO,WAAW,IAAI;AAClC,mBAAO,QAAQ,IAAI;AACnB,mBAAO,SAAS,IAAI;AACpB,gBAAI,UAAU,KAAK,GAAG,GAAG,OAAO,OAAO,OAAO,MAAM;AACpD,oBAAQ,OAAO,UAAU,WAAW,OAAO,SAAS,QAAQ,MAAM,WAAW,OAAO,SAAS,QAAQ,OAAO,CAAC;AAAA,UAC/G,CAAC,EAAE,MAAM,MAAM;AAAA,QACjB,WAAW,OAAO,YAAY,UAAU;AACtC,gBAAM,gBAAgB,WAAW,OAAO,SAAS,QAAQ,eAAe,wBAAwB,OAAO;AACvG,gBAAM,aAAa,aAAa,OAAO;AACvC,iBAAO,QAAQ,aAAa,IAAI,KAAK,CAAC,UAAU,GAAG,EAAE,MAAM,mBAAmB,CAAC,CAAC,CAAC;AAAA,QACnF,OAAO;AACL,iBAAO,IAAI,MAAM,6BAA6B,CAAC;AAAA,QACjD;AAAA,MACF,SAAS,OAAO;AACd,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AACD,YAAQ,MAAM,KAAK,CAAC,QAAQ;AAC1B,aAAO,SAAS,WAAW,OAAO,SAAS,QAAQ,aAAa,QAAQ,IAAI,QAAQ,qBAAqB,EAAE,IAAI;AAAA,IACjH,CAAC;AACD,WAAO,QAAQ;AAAA,EACjB;AACA,MAAI,MAAM,MAAM,KAAK,OAAO,WAAW;AACrC,UAAM,QAAQ,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA;AAE1C,YAAQ;AACV,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AACA,SAAS,UAAU,KAAK;AACtB,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI,CAAC,IAAI,UAAU;AACjB,UAAI,SAAS,MAAM;AACjB,gBAAQ;AAAA,MACV;AACA,UAAI,UAAU;AAAA,IAChB,OAAO;AACL,cAAQ;AAAA,IACV;AAAA,EACF,CAAC;AACH;AACA,SAAS,aAAa,MAAM;AAC1B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,KAAK,IAAI,WAAW;AAC1B,OAAG,SAAS,CAAC,MAAM;AACjB,cAAQ,EAAE,OAAO,MAAM;AAAA,IACzB;AACA,OAAG,UAAU;AACb,OAAG,cAAc,IAAI;AAAA,EACvB,CAAC;AACH;AAEA,SAAS,WAAW,UAAU,CAAC,GAAG;AAChC,QAAM,EAAE,WAAAG,aAAY,iBAAiB,IAAI;AACzC,QAAMC,UAAS,CAAC,kBAAkB,sBAAsB,yBAAyB,aAAa;AAC9F,QAAM,cAAc,aAAa,MAAMD,cAAa,gBAAgBA,cAAa,OAAOA,WAAU,eAAe,UAAU;AAC3H,QAAM,WAAW,WAAW,KAAK;AACjC,QAAM,eAAe,WAAW,CAAC;AACjC,QAAM,kBAAkB,WAAW,CAAC;AACpC,QAAM,QAAQ,WAAW,CAAC;AAC1B,MAAI;AACJ,WAAS,oBAAoB;AAC3B,aAAS,QAAQ,KAAK;AACtB,iBAAa,QAAQ,KAAK,gBAAgB;AAC1C,oBAAgB,QAAQ,KAAK,mBAAmB;AAChD,UAAM,QAAQ,KAAK;AAAA,EACrB;AACA,MAAI,YAAY,OAAO;AACrB,IAAAA,WAAU,WAAW,EAAE,KAAK,CAAC,aAAa;AACxC,gBAAU;AACV,wBAAkB,KAAK,OAAO;AAC9B,uBAAiB,SAASC,SAAQ,mBAAmB,EAAE,SAAS,KAAK,CAAC;AAAA,IACxE,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,aAAa,SAAS;AAC7B,MAAI;AAAA,IACF,mBAAmB;AAAA,EACrB,IAAI,WAAW,CAAC;AAChB,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,WAAAD,aAAY;AAAA,EACd,IAAI,WAAW,CAAC;AAChB,QAAM,cAAc,aAAa,MAAMA,cAAa,eAAeA,UAAS;AAC5E,QAAM,SAAS,WAAW;AAC1B,QAAM,QAAQ,WAAW,IAAI;AAC7B,QAAM,QAAQ,MAAM;AAClB,iCAA6B;AAAA,EAC/B,CAAC;AACD,iBAAe,gBAAgB;AAC7B,QAAI,CAAC,YAAY;AACf;AACF,UAAM,QAAQ;AACd,QAAI,WAAW,QAAQ,SAAS;AAC9B,yBAAmB;AACrB,QAAI;AACF,aAAO,QAAQ,OAAOA,cAAa,OAAO,SAASA,WAAU,UAAU,cAAc;AAAA,QACnF;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,YAAM,QAAQ;AAAA,IAChB;AAAA,EACF;AACA,QAAM,SAAS,WAAW;AAC1B,QAAM,cAAc,WAAW,KAAK;AACpC,WAAS,QAAQ;AACf,gBAAY,QAAQ;AACpB,WAAO,QAAQ;AACf,WAAO,QAAQ;AAAA,EACjB;AACA,iBAAe,+BAA+B;AAC5C,UAAM,QAAQ;AACd,QAAI,OAAO,SAAS,OAAO,MAAM,MAAM;AACrC,uBAAiB,QAAQ,0BAA0B,OAAO,EAAE,SAAS,KAAK,CAAC;AAC3E,UAAI;AACF,eAAO,QAAQ,MAAM,OAAO,MAAM,KAAK,QAAQ;AAC/C,oBAAY,QAAQ,OAAO,MAAM;AAAA,MACnC,SAAS,KAAK;AACZ,cAAM,QAAQ;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACA,eAAa,MAAM;AACjB,QAAI;AACJ,QAAI,OAAO;AACT,OAAC,KAAK,OAAO,MAAM,SAAS,OAAO,SAAS,GAAG,QAAQ;AAAA,EAC3D,CAAC;AACD,oBAAkB,MAAM;AACtB,QAAI;AACJ,QAAI,OAAO;AACT,OAAC,KAAK,OAAO,MAAM,SAAS,OAAO,SAAS,GAAG,WAAW;AAAA,EAC9D,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA,aAAa,SAAS,WAAW;AAAA;AAAA,IAEjC;AAAA,IACA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA,EACF;AACF;AAEA,IAAM,iBAAiB,OAAO,kBAAkB;AAChD,SAAS,cAAc;AACrB,QAAM,WAAW,oBAAoB,IAAI,YAAY,gBAAgB,IAAI,IAAI;AAC7E,SAAO,OAAO,aAAa,WAAW,WAAW;AACnD;AACA,SAAS,gBAAgB,OAAO,KAAK;AACnC,MAAI,QAAQ,QAAQ;AAClB,QAAI,QAAQ,gBAAgB,KAAK;AAAA,EACnC,OAAO;AACL,iBAAa,gBAAgB,KAAK;AAAA,EACpC;AACF;AAEA,SAAS,cAAc,OAAO,UAAU,CAAC,GAAG;AAC1C,QAAM,EAAE,QAAAH,UAAS,eAAe,WAAW,YAAY,EAAE,IAAI;AAC7D,QAAM,cAAc,aAAa,MAAMA,WAAU,gBAAgBA,WAAU,OAAOA,QAAO,eAAe,UAAU;AAClH,QAAM,aAAa,WAAW,OAAO,aAAa,QAAQ;AAC1D,QAAM,aAAa,WAAW;AAC9B,QAAM,UAAU,WAAW,KAAK;AAChC,QAAM,UAAU,CAAC,UAAU;AACzB,YAAQ,QAAQ,MAAM;AAAA,EACxB;AACA,cAAY,MAAM;AAChB,QAAI,WAAW,OAAO;AACpB,iBAAW,QAAQ,CAAC,YAAY;AAChC,YAAM,eAAe,QAAQ,KAAK,EAAE,MAAM,GAAG;AAC7C,cAAQ,QAAQ,aAAa,KAAK,CAAC,gBAAgB;AACjD,cAAM,MAAM,YAAY,SAAS,SAAS;AAC1C,cAAM,WAAW,YAAY,MAAM,gDAAgD;AACnF,cAAM,WAAW,YAAY,MAAM,gDAAgD;AACnF,YAAI,MAAM,QAAQ,YAAY,QAAQ;AACtC,YAAI,YAAY,KAAK;AACnB,gBAAM,YAAY,QAAQ,SAAS,CAAC,CAAC;AAAA,QACvC;AACA,YAAI,YAAY,KAAK;AACnB,gBAAM,YAAY,QAAQ,SAAS,CAAC,CAAC;AAAA,QACvC;AACA,eAAO,MAAM,CAAC,MAAM;AAAA,MACtB,CAAC;AACD;AAAA,IACF;AACA,QAAI,CAAC,YAAY;AACf;AACF,eAAW,QAAQA,QAAO,WAAW,QAAQ,KAAK,CAAC;AACnD,YAAQ,QAAQ,WAAW,MAAM;AAAA,EACnC,CAAC;AACD,mBAAiB,YAAY,UAAU,SAAS,EAAE,SAAS,KAAK,CAAC;AACjE,SAAO,SAAS,MAAM,QAAQ,KAAK;AACrC;AAEA,IAAM,sBAAsB;AAAA,EAC1B,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACT;AACA,IAAM,yBAAyB;AAAA,EAC7B,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,KAAK;AACP;AACA,IAAM,uBAAuB;AAAA,EAC3B,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AACA,IAAM,uBAAuB;AAAA,EAC3B,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,KAAK;AACP;AACA,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;AAAA,EAC3B,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,KAAK;AACP;AACA,IAAM,oBAAoB;AAAA,EACxB,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AACA,IAAM,qBAAqB;AAAA,EACzB,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;AACb;AACA,IAAM,uBAAuB;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACT;AACA,IAAM,uBAAuB;AAAA,EAC3B,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AACA,IAAM,qBAAqB;AAAA,EACzB,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEA,SAAS,eAAe,aAAa,UAAU,CAAC,GAAG;AACjD,WAASK,UAAS,GAAG,OAAO;AAC1B,QAAI,IAAI,QAAQ,YAAY,QAAQ,CAAC,CAAC,CAAC;AACvC,QAAI,SAAS;AACX,UAAI,iBAAiB,GAAG,KAAK;AAC/B,QAAI,OAAO,MAAM;AACf,UAAI,GAAG,CAAC;AACV,WAAO;AAAA,EACT;AACA,QAAM,EAAE,QAAAL,UAAS,eAAe,WAAW,aAAa,WAAW,YAAY,EAAE,IAAI;AACrF,QAAM,aAAa,OAAO,aAAa;AACvC,QAAM,UAAU,aAAa,WAAW,KAAK,IAAI,EAAE,OAAO,KAAK;AAC/D,MAAI,YAAY;AACd,iBAAa,MAAM,QAAQ,QAAQ,CAAC,CAACA,OAAM;AAAA,EAC7C;AACA,WAAS,MAAM,OAAO,MAAM;AAC1B,QAAI,CAAC,QAAQ,SAAS,YAAY;AAChC,aAAO,UAAU,QAAQ,YAAY,QAAQ,IAAI,IAAI,YAAY,QAAQ,IAAI;AAAA,IAC/E;AACA,QAAI,CAACA;AACH,aAAO;AACT,WAAOA,QAAO,WAAW,IAAI,KAAK,WAAW,IAAI,GAAG,EAAE;AAAA,EACxD;AACA,QAAM,iBAAiB,CAAC,MAAM;AAC5B,WAAO,cAAc,MAAM,eAAeK,UAAS,CAAC,CAAC,KAAK,OAAO;AAAA,EACnE;AACA,QAAM,iBAAiB,CAAC,MAAM;AAC5B,WAAO,cAAc,MAAM,eAAeA,UAAS,CAAC,CAAC,KAAK,OAAO;AAAA,EACnE;AACA,QAAM,kBAAkB,OAAO,KAAK,WAAW,EAAE,OAAO,CAAC,WAAW,MAAM;AACxE,WAAO,eAAe,WAAW,GAAG;AAAA,MAClC,KAAK,MAAM,aAAa,cAAc,eAAe,CAAC,IAAI,eAAe,CAAC;AAAA,MAC1E,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACL,WAAS,UAAU;AACjB,UAAM,SAAS,OAAO,KAAK,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,gBAAgB,CAAC,GAAG,QAAQA,UAAS,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAC5H,WAAO,SAAS,MAAM,OAAO,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAAA,EACzE;AACA,SAAO,OAAO,OAAO,iBAAiB;AAAA,IACpC;AAAA,IACA;AAAA,IACA,QAAQ,GAAG;AACT,aAAO,cAAc,MAAM,eAAeA,UAAS,GAAG,GAAG,CAAC,KAAK,OAAO;AAAA,IACxE;AAAA,IACA,QAAQ,GAAG;AACT,aAAO,cAAc,MAAM,eAAeA,UAAS,GAAG,IAAI,CAAC,KAAK,OAAO;AAAA,IACzE;AAAA,IACA,QAAQ,GAAG,GAAG;AACZ,aAAO,cAAc,MAAM,eAAeA,UAAS,CAAC,CAAC,qBAAqBA,UAAS,GAAG,IAAI,CAAC,KAAK,OAAO;AAAA,IACzG;AAAA,IACA,UAAU,GAAG;AACX,aAAO,MAAM,OAAOA,UAAS,GAAG,GAAG,CAAC;AAAA,IACtC;AAAA,IACA,iBAAiB,GAAG;AAClB,aAAO,MAAM,OAAOA,UAAS,CAAC,CAAC;AAAA,IACjC;AAAA,IACA,UAAU,GAAG;AACX,aAAO,MAAM,OAAOA,UAAS,GAAG,IAAI,CAAC;AAAA,IACvC;AAAA,IACA,iBAAiB,GAAG;AAClB,aAAO,MAAM,OAAOA,UAAS,CAAC,CAAC;AAAA,IACjC;AAAA,IACA,YAAY,GAAG,GAAG;AAChB,aAAO,MAAM,OAAOA,UAAS,CAAC,CAAC,KAAK,MAAM,OAAOA,UAAS,GAAG,IAAI,CAAC;AAAA,IACpE;AAAA,IACA;AAAA,IACA,SAAS;AACP,YAAM,MAAM,QAAQ;AACpB,aAAO,SAAS,MAAM,IAAI,MAAM,WAAW,IAAI,KAAK,IAAI,MAAM,GAAG,aAAa,cAAc,KAAK,CAAC,CAAC;AAAA,IACrG;AAAA,EACF,CAAC;AACH;AAEA,SAAS,oBAAoB,SAAS;AACpC,QAAM;AAAA,IACJ;AAAA,IACA,QAAAL,UAAS;AAAA,EACX,IAAI;AACJ,QAAM,cAAc,aAAa,MAAMA,WAAU,sBAAsBA,OAAM;AAC7E,QAAM,WAAW,WAAW,KAAK;AACjC,QAAM,UAAU,IAAI;AACpB,QAAM,OAAO,IAAI;AACjB,QAAM,QAAQ,WAAW,IAAI;AAC7B,QAAM,OAAO,CAAC,UAAU;AACtB,QAAI,QAAQ;AACV,cAAQ,MAAM,YAAY,KAAK;AAAA,EACnC;AACA,QAAM,QAAQ,MAAM;AAClB,QAAI,QAAQ;AACV,cAAQ,MAAM,MAAM;AACtB,aAAS,QAAQ;AAAA,EACnB;AACA,MAAI,YAAY,OAAO;AACrB,iBAAa,MAAM;AACjB,YAAM,QAAQ;AACd,cAAQ,QAAQ,IAAI,iBAAiB,IAAI;AACzC,YAAM,kBAAkB;AAAA,QACtB,SAAS;AAAA,MACX;AACA,uBAAiB,SAAS,WAAW,CAAC,MAAM;AAC1C,aAAK,QAAQ,EAAE;AAAA,MACjB,GAAG,eAAe;AAClB,uBAAiB,SAAS,gBAAgB,CAAC,MAAM;AAC/C,cAAM,QAAQ;AAAA,MAChB,GAAG,eAAe;AAClB,uBAAiB,SAAS,SAAS,MAAM;AACvC,iBAAS,QAAQ;AAAA,MACnB,GAAG,eAAe;AAAA,IACpB,CAAC;AAAA,EACH;AACA,oBAAkB,MAAM;AACtB,UAAM;AAAA,EACR,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,SAAS,mBAAmB,UAAU,CAAC,GAAG;AACxC,QAAM,EAAE,QAAAA,UAAS,cAAc,IAAI;AACnC,QAAM,OAAO,OAAO;AAAA,IAClB,oBAAoB,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC;AAAA,EAC/C;AACA,aAAW,CAAC,KAAKM,IAAG,KAAK,cAAc,IAAI,GAAG;AAC5C,UAAMA,MAAK,CAAC,UAAU;AACpB,UAAI,EAAEN,WAAU,OAAO,SAASA,QAAO,aAAaA,QAAO,SAAS,GAAG,MAAM;AAC3E;AACF,MAAAA,QAAO,SAAS,GAAG,IAAI;AAAA,IACzB,CAAC;AAAA,EACH;AACA,QAAM,aAAa,CAAC,YAAY;AAC9B,QAAI;AACJ,UAAM,EAAE,OAAO,QAAQ,OAAO,KAAKA,WAAU,OAAO,SAASA,QAAO,YAAY,CAAC;AACjF,UAAM,EAAE,OAAO,KAAKA,WAAU,OAAO,SAASA,QAAO,aAAa,CAAC;AACnE,eAAW,OAAO;AAChB,WAAK,GAAG,EAAE,SAAS,KAAKA,WAAU,OAAO,SAASA,QAAO,aAAa,OAAO,SAAS,GAAG,GAAG;AAC9F,WAAO,SAAS;AAAA,MACd;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACA,QAAM,QAAQ,IAAI,WAAW,MAAM,CAAC;AACpC,MAAIA,SAAQ;AACV,UAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,qBAAiBA,SAAQ,YAAY,MAAM,MAAM,QAAQ,WAAW,UAAU,GAAG,eAAe;AAChG,qBAAiBA,SAAQ,cAAc,MAAM,MAAM,QAAQ,WAAW,YAAY,GAAG,eAAe;AAAA,EACtG;AACA,SAAO;AACT;AAEA,SAAS,UAAU,UAAU,aAAa,CAAC,GAAG,MAAM,MAAM,GAAG,SAAS;AACpE,QAAM,EAAE,WAAW,MAAM,GAAG,aAAa,IAAI,WAAW,CAAC;AACzD,QAAM,cAAc,UAAU,SAAS,OAAO,QAAQ;AACtD,QAAM,MAAM,SAAS,OAAO,CAAC,UAAU;AACrC,QAAI,CAAC,WAAW,OAAO,YAAY,KAAK;AACtC,kBAAY,QAAQ;AAAA,EACxB,GAAG,YAAY;AACf,SAAO;AACT;AAEA,SAAS,cAAc,gBAAgB,UAAU,CAAC,GAAG;AACnD,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,WAAAG,aAAY;AAAA,EACd,IAAI;AACJ,QAAM,cAAc,aAAa,MAAMA,cAAa,iBAAiBA,UAAS;AAC9E,QAAM,mBAAmB,WAAW;AACpC,QAAM,OAAO,OAAO,mBAAmB,WAAW,EAAE,MAAM,eAAe,IAAI;AAC7E,QAAM,QAAQ,WAAW;AACzB,QAAM,SAAS,MAAM;AACnB,QAAI,IAAI;AACR,UAAM,SAAS,MAAM,KAAK,iBAAiB,UAAU,OAAO,SAAS,GAAG,UAAU,OAAO,KAAK;AAAA,EAChG;AACA,mBAAiB,kBAAkB,UAAU,QAAQ,EAAE,SAAS,KAAK,CAAC;AACtE,QAAM,QAAQ,uBAAuB,YAAY;AAC/C,QAAI,CAAC,YAAY;AACf;AACF,QAAI,CAAC,iBAAiB,OAAO;AAC3B,UAAI;AACF,yBAAiB,QAAQ,MAAMA,WAAU,YAAY,MAAM,IAAI;AAAA,MACjE,SAAS,GAAG;AACV,yBAAiB,QAAQ;AAAA,MAC3B,UAAE;AACA,eAAO;AAAA,MACT;AAAA,IACF;AACA,QAAI;AACF,aAAO,MAAM,iBAAiB,KAAK;AAAA,EACvC,CAAC;AACD,QAAM;AACN,MAAI,UAAU;AACZ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEA,SAAS,aAAa,UAAU,CAAC,GAAG;AAClC,QAAM;AAAA,IACJ,WAAAA,aAAY;AAAA,IACZ,OAAO;AAAA,IACP;AAAA,IACA,eAAe;AAAA,IACf,SAAS;AAAA,EACX,IAAI;AACJ,QAAM,0BAA0B,aAAa,MAAMA,cAAa,eAAeA,UAAS;AACxF,QAAM,iBAAiB,cAAc,gBAAgB;AACrD,QAAM,kBAAkB,cAAc,iBAAiB;AACvD,QAAM,cAAc,SAAS,MAAM,wBAAwB,SAAS,MAAM;AAC1E,QAAM,OAAO,WAAW,EAAE;AAC1B,QAAM,SAAS,WAAW,KAAK;AAC/B,QAAM,UAAU,aAAa,MAAM,OAAO,QAAQ,OAAO,cAAc,EAAE,WAAW,MAAM,CAAC;AAC3F,iBAAe,aAAa;AAC1B,QAAI,YAAY,EAAE,wBAAwB,SAAS,UAAU,eAAe,KAAK;AACjF,QAAI,CAAC,WAAW;AACd,UAAI;AACF,aAAK,QAAQ,MAAMA,WAAU,UAAU,SAAS;AAAA,MAClD,SAAS,GAAG;AACV,oBAAY;AAAA,MACd;AAAA,IACF;AACA,QAAI,WAAW;AACb,WAAK,QAAQ,WAAW;AAAA,IAC1B;AAAA,EACF;AACA,MAAI,YAAY,SAAS;AACvB,qBAAiB,CAAC,QAAQ,KAAK,GAAG,YAAY,EAAE,SAAS,KAAK,CAAC;AACjE,iBAAe,KAAK,QAAQ,QAAQ,MAAM,GAAG;AAC3C,QAAI,YAAY,SAAS,SAAS,MAAM;AACtC,UAAI,YAAY,EAAE,wBAAwB,SAAS,UAAU,gBAAgB,KAAK;AAClF,UAAI,CAAC,WAAW;AACd,YAAI;AACF,gBAAMA,WAAU,UAAU,UAAU,KAAK;AAAA,QAC3C,SAAS,GAAG;AACV,sBAAY;AAAA,QACd;AAAA,MACF;AACA,UAAI;AACF,mBAAW,KAAK;AAClB,WAAK,QAAQ;AACb,aAAO,QAAQ;AACf,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF;AACA,WAAS,WAAW,OAAO;AACzB,UAAM,KAAK,SAAS,cAAc,UAAU;AAC5C,OAAG,QAAQ,SAAS,OAAO,QAAQ;AACnC,OAAG,MAAM,WAAW;AACpB,OAAG,MAAM,UAAU;AACnB,aAAS,KAAK,YAAY,EAAE;AAC5B,OAAG,OAAO;AACV,aAAS,YAAY,MAAM;AAC3B,OAAG,OAAO;AAAA,EACZ;AACA,WAAS,aAAa;AACpB,QAAI,IAAI,IAAI;AACZ,YAAQ,MAAM,MAAM,KAAK,YAAY,OAAO,SAAS,SAAS,iBAAiB,OAAO,SAAS,GAAG,KAAK,QAAQ,MAAM,OAAO,SAAS,GAAG,SAAS,MAAM,OAAO,KAAK;AAAA,EACrK;AACA,WAAS,UAAU,QAAQ;AACzB,WAAO,WAAW,aAAa,WAAW;AAAA,EAC5C;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,UAAU,CAAC,GAAG;AACvC,QAAM;AAAA,IACJ,WAAAA,aAAY;AAAA,IACZ,OAAO;AAAA,IACP;AAAA,IACA,eAAe;AAAA,EACjB,IAAI;AACJ,QAAM,cAAc,aAAa,MAAMA,cAAa,eAAeA,UAAS;AAC5E,QAAM,UAAU,IAAI,CAAC,CAAC;AACtB,QAAM,SAAS,WAAW,KAAK;AAC/B,QAAM,UAAU,aAAa,MAAM,OAAO,QAAQ,OAAO,cAAc,EAAE,WAAW,MAAM,CAAC;AAC3F,WAAS,gBAAgB;AACvB,QAAI,YAAY,OAAO;AACrB,MAAAA,WAAU,UAAU,KAAK,EAAE,KAAK,CAAC,UAAU;AACzC,gBAAQ,QAAQ;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AACA,MAAI,YAAY,SAAS;AACvB,qBAAiB,CAAC,QAAQ,KAAK,GAAG,eAAe,EAAE,SAAS,KAAK,CAAC;AACpE,iBAAe,KAAK,QAAQ,QAAQ,MAAM,GAAG;AAC3C,QAAI,YAAY,SAAS,SAAS,MAAM;AACtC,YAAMA,WAAU,UAAU,MAAM,KAAK;AACrC,cAAQ,QAAQ;AAChB,aAAO,QAAQ;AACf,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,YAAY,QAAQ;AAC3B,SAAO,KAAK,MAAM,KAAK,UAAU,MAAM,CAAC;AAC1C;AACA,SAAS,UAAU,QAAQ,UAAU,CAAC,GAAG;AACvC,QAAM,SAAS,IAAI,CAAC,CAAC;AACrB,QAAM,aAAa,WAAW,KAAK;AACnC,MAAI,YAAY;AAChB,QAAM;AAAA,IACJ;AAAA,IACA,QAAQ;AAAA;AAAA,IAER,OAAO;AAAA,IACP,YAAY;AAAA,EACd,IAAI;AACJ,QAAM,QAAQ,MAAM;AAClB,QAAI,WAAW;AACb,kBAAY;AACZ;AAAA,IACF;AACA,eAAW,QAAQ;AAAA,EACrB,GAAG;AAAA,IACD,MAAM;AAAA,IACN,OAAO;AAAA,EACT,CAAC;AACD,WAAS,OAAO;AACd,gBAAY;AACZ,eAAW,QAAQ;AACnB,WAAO,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA,EACtC;AACA,MAAI,CAAC,WAAW,MAAM,MAAM,KAAK,OAAO,WAAW,aAAa;AAC9D,UAAM,QAAQ,MAAM;AAAA,MAClB,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,OAAO;AACL,SAAK;AAAA,EACP;AACA,SAAO,EAAE,QAAQ,YAAY,KAAK;AACpC;AAEA,IAAM,UAAU,OAAO,eAAe,cAAc,aAAa,OAAO,WAAW,cAAc,SAAS,OAAO,WAAW,cAAc,SAAS,OAAO,SAAS,cAAc,OAAO,CAAC;AACzL,IAAM,YAAY;AAClB,IAAM,WAA2B,YAAY;AAC7C,SAAS,cAAc;AACrB,MAAI,EAAE,aAAa;AACjB,YAAQ,SAAS,IAAI,QAAQ,SAAS,KAAK,CAAC;AAC9C,SAAO,QAAQ,SAAS;AAC1B;AACA,SAAS,cAAc,KAAK,UAAU;AACpC,SAAO,SAAS,GAAG,KAAK;AAC1B;AACA,SAAS,cAAc,KAAK,IAAI;AAC9B,WAAS,GAAG,IAAI;AAClB;AAEA,SAAS,iBAAiB,SAAS;AACjC,SAAO,cAAc,gCAAgC,OAAO;AAC9D;AAEA,SAAS,oBAAoB,SAAS;AACpC,SAAO,WAAW,OAAO,QAAQ,mBAAmB,MAAM,QAAQ,mBAAmB,MAAM,QAAQ,mBAAmB,OAAO,SAAS,OAAO,YAAY,YAAY,YAAY,OAAO,YAAY,WAAW,WAAW,OAAO,YAAY,WAAW,WAAW,CAAC,OAAO,MAAM,OAAO,IAAI,WAAW;AACzS;AAEA,IAAM,qBAAqB;AAAA,EACzB,SAAS;AAAA,IACP,MAAM,CAAC,MAAM,MAAM;AAAA,IACnB,OAAO,CAAC,MAAM,OAAO,CAAC;AAAA,EACxB;AAAA,EACA,QAAQ;AAAA,IACN,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC;AAAA,IACzB,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC;AAAA,EAChC;AAAA,EACA,QAAQ;AAAA,IACN,MAAM,CAAC,MAAM,OAAO,WAAW,CAAC;AAAA,IAChC,OAAO,CAAC,MAAM,OAAO,CAAC;AAAA,EACxB;AAAA,EACA,KAAK;AAAA,IACH,MAAM,CAAC,MAAM;AAAA,IACb,OAAO,CAAC,MAAM,OAAO,CAAC;AAAA,EACxB;AAAA,EACA,QAAQ;AAAA,IACN,MAAM,CAAC,MAAM;AAAA,IACb,OAAO,CAAC,MAAM,OAAO,CAAC;AAAA,EACxB;AAAA,EACA,KAAK;AAAA,IACH,MAAM,CAAC,MAAM,IAAI,IAAI,KAAK,MAAM,CAAC,CAAC;AAAA,IAClC,OAAO,CAAC,MAAM,KAAK,UAAU,MAAM,KAAK,EAAE,QAAQ,CAAC,CAAC;AAAA,EACtD;AAAA,EACA,KAAK;AAAA,IACH,MAAM,CAAC,MAAM,IAAI,IAAI,KAAK,MAAM,CAAC,CAAC;AAAA,IAClC,OAAO,CAAC,MAAM,KAAK,UAAU,MAAM,KAAK,CAAC,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM;AAAA,IACJ,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC;AAAA,IACvB,OAAO,CAAC,MAAM,EAAE,YAAY;AAAA,EAC9B;AACF;AACA,IAAM,yBAAyB;AAC/B,SAAS,WAAW,KAAKI,WAAU,SAAS,UAAU,CAAC,GAAG;AACxD,MAAI;AACJ,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,yBAAyB;AAAA,IACzB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB;AAAA,IACA,QAAAP,UAAS;AAAA,IACT;AAAA,IACA,UAAU,CAAC,MAAM;AACf,cAAQ,MAAM,CAAC;AAAA,IACjB;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,QAAQ,UAAU,aAAa,KAAK,OAAOO,cAAa,aAAaA,UAAS,IAAIA,SAAQ;AAChG,QAAM,cAAc,SAAS,MAAM,QAAQ,GAAG,CAAC;AAC/C,MAAI,CAAC,SAAS;AACZ,QAAI;AACF,gBAAU,cAAc,qBAAqB,MAAM;AACjD,YAAI;AACJ,gBAAQ,MAAM,kBAAkB,OAAO,SAAS,IAAI;AAAA,MACtD,CAAC,EAAE;AAAA,IACL,SAAS,GAAG;AACV,cAAQ,CAAC;AAAA,IACX;AAAA,EACF;AACA,MAAI,CAAC;AACH,WAAO;AACT,QAAM,UAAU,QAAQA,SAAQ;AAChC,QAAM,OAAO,oBAAoB,OAAO;AACxC,QAAM,cAAc,KAAK,QAAQ,eAAe,OAAO,KAAK,mBAAmB,IAAI;AACnF,QAAM,EAAE,OAAO,YAAY,QAAQ,YAAY,IAAI;AAAA,IACjD;AAAA,IACA,MAAM,MAAM,KAAK,KAAK;AAAA,IACtB,EAAE,OAAO,MAAM,YAAY;AAAA,EAC7B;AACA,QAAM,aAAa,MAAM,OAAO,GAAG,EAAE,MAAM,CAAC;AAC5C,MAAIP,WAAU,wBAAwB;AACpC,iBAAa,MAAM;AACjB,UAAI,mBAAmB;AACrB,yBAAiBA,SAAQ,WAAW,QAAQ,EAAE,SAAS,KAAK,CAAC;AAAA;AAE7D,yBAAiBA,SAAQ,wBAAwB,qBAAqB;AACxE,UAAI;AACF,eAAO;AAAA,IACX,CAAC;AAAA,EACH;AACA,MAAI,CAAC;AACH,WAAO;AACT,WAAS,mBAAmB,UAAU,UAAU;AAC9C,QAAIA,SAAQ;AACV,YAAM,UAAU;AAAA,QACd,KAAK,YAAY;AAAA,QACjB;AAAA,QACA;AAAA,QACA,aAAa;AAAA,MACf;AACA,MAAAA,QAAO,cAAc,mBAAmB,UAAU,IAAI,aAAa,WAAW,OAAO,IAAI,IAAI,YAAY,wBAAwB;AAAA,QAC/H,QAAQ;AAAA,MACV,CAAC,CAAC;AAAA,IACJ;AAAA,EACF;AACA,WAAS,MAAM,GAAG;AAChB,QAAI;AACF,YAAM,WAAW,QAAQ,QAAQ,YAAY,KAAK;AAClD,UAAI,KAAK,MAAM;AACb,2BAAmB,UAAU,IAAI;AACjC,gBAAQ,WAAW,YAAY,KAAK;AAAA,MACtC,OAAO;AACL,cAAM,aAAa,WAAW,MAAM,CAAC;AACrC,YAAI,aAAa,YAAY;AAC3B,kBAAQ,QAAQ,YAAY,OAAO,UAAU;AAC7C,6BAAmB,UAAU,UAAU;AAAA,QACzC;AAAA,MACF;AAAA,IACF,SAAS,GAAG;AACV,cAAQ,CAAC;AAAA,IACX;AAAA,EACF;AACA,WAAS,KAAK,OAAO;AACnB,UAAM,WAAW,QAAQ,MAAM,WAAW,QAAQ,QAAQ,YAAY,KAAK;AAC3E,QAAI,YAAY,MAAM;AACpB,UAAI,iBAAiB,WAAW;AAC9B,gBAAQ,QAAQ,YAAY,OAAO,WAAW,MAAM,OAAO,CAAC;AAC9D,aAAO;AAAA,IACT,WAAW,CAAC,SAAS,eAAe;AAClC,YAAM,QAAQ,WAAW,KAAK,QAAQ;AACtC,UAAI,OAAO,kBAAkB;AAC3B,eAAO,cAAc,OAAO,OAAO;AAAA,eAC5B,SAAS,YAAY,CAAC,MAAM,QAAQ,KAAK;AAChD,eAAO,EAAE,GAAG,SAAS,GAAG,MAAM;AAChC,aAAO;AAAA,IACT,WAAW,OAAO,aAAa,UAAU;AACvC,aAAO;AAAA,IACT,OAAO;AACL,aAAO,WAAW,KAAK,QAAQ;AAAA,IACjC;AAAA,EACF;AACA,WAAS,OAAO,OAAO;AACrB,QAAI,SAAS,MAAM,gBAAgB;AACjC;AACF,QAAI,SAAS,MAAM,OAAO,MAAM;AAC9B,WAAK,QAAQ;AACb;AAAA,IACF;AACA,QAAI,SAAS,MAAM,QAAQ,YAAY;AACrC;AACF,eAAW;AACX,QAAI;AACF,WAAK,SAAS,OAAO,SAAS,MAAM,cAAc,WAAW,MAAM,KAAK,KAAK;AAC3E,aAAK,QAAQ,KAAK,KAAK;AAAA,IAC3B,SAAS,GAAG;AACV,cAAQ,CAAC;AAAA,IACX,UAAE;AACA,UAAI;AACF,iBAAS,WAAW;AAAA;AAEpB,oBAAY;AAAA,IAChB;AAAA,EACF;AACA,WAAS,sBAAsB,OAAO;AACpC,WAAO,MAAM,MAAM;AAAA,EACrB;AACA,SAAO;AACT;AAEA,IAAM,oBAAoB;AAC1B,SAAS,aAAa,UAAU,CAAC,GAAG;AAClC,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,QAAAA,UAAS;AAAA,IACT;AAAA,IACA,aAAa;AAAA,IACb,yBAAyB;AAAA,IACzB;AAAA,IACA;AAAA,IACA,oBAAoB;AAAA,EACtB,IAAI;AACJ,QAAM,QAAQ;AAAA,IACZ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,GAAG,QAAQ,SAAS,CAAC;AAAA,EACvB;AACA,QAAM,gBAAgB,iBAAiB,EAAE,QAAAA,QAAO,CAAC;AACjD,QAAM,SAAS,SAAS,MAAM,cAAc,QAAQ,SAAS,OAAO;AACpE,QAAM,QAAQ,eAAe,cAAc,OAAOQ,OAAM,YAAY,IAAI,WAAW,YAAY,cAAc,SAAS,EAAE,QAAAR,SAAQ,uBAAuB,CAAC;AACxJ,QAAM,QAAQ,SAAS,MAAM,MAAM,UAAU,SAAS,OAAO,QAAQ,MAAM,KAAK;AAChF,QAAM,kBAAkB;AAAA,IACtB;AAAA,IACA,CAAC,WAAW,YAAY,UAAU;AAChC,YAAM,KAAK,OAAO,cAAc,WAAWA,WAAU,OAAO,SAASA,QAAO,SAAS,cAAc,SAAS,IAAI,aAAa,SAAS;AACtI,UAAI,CAAC;AACH;AACF,YAAM,eAA+B,oBAAI,IAAI;AAC7C,YAAM,kBAAkC,oBAAI,IAAI;AAChD,UAAI,oBAAoB;AACxB,UAAI,eAAe,SAAS;AAC1B,cAAM,UAAU,MAAM,MAAM,KAAK;AACjC,eAAO,OAAO,KAAK,EAAE,QAAQ,CAAC,OAAO,KAAK,IAAI,MAAM,KAAK,CAAC,EAAE,OAAO,OAAO,EAAE,QAAQ,CAAC,MAAM;AACzF,cAAI,QAAQ,SAAS,CAAC;AACpB,yBAAa,IAAI,CAAC;AAAA;AAElB,4BAAgB,IAAI,CAAC;AAAA,QACzB,CAAC;AAAA,MACH,OAAO;AACL,4BAAoB,EAAE,KAAK,YAAY,MAAM;AAAA,MAC/C;AACA,UAAI,aAAa,SAAS,KAAK,gBAAgB,SAAS,KAAK,sBAAsB;AACjF;AACF,UAAI;AACJ,UAAI,mBAAmB;AACrB,gBAAQA,QAAO,SAAS,cAAc,OAAO;AAC7C,cAAM,YAAY,SAAS,eAAe,iBAAiB,CAAC;AAC5D,QAAAA,QAAO,SAAS,KAAK,YAAY,KAAK;AAAA,MACxC;AACA,iBAAW,KAAK,cAAc;AAC5B,WAAG,UAAU,IAAI,CAAC;AAAA,MACpB;AACA,iBAAW,KAAK,iBAAiB;AAC/B,WAAG,UAAU,OAAO,CAAC;AAAA,MACvB;AACA,UAAI,mBAAmB;AACrB,WAAG,aAAa,kBAAkB,KAAK,kBAAkB,KAAK;AAAA,MAChE;AACA,UAAI,mBAAmB;AACrB,QAAAA,QAAO,iBAAiB,KAAK,EAAE;AAC/B,iBAAS,KAAK,YAAY,KAAK;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AACA,WAAS,iBAAiB,MAAM;AAC9B,QAAI;AACJ,oBAAgB,UAAU,YAAY,KAAK,MAAM,IAAI,MAAM,OAAO,KAAK,IAAI;AAAA,EAC7E;AACA,WAAS,UAAU,MAAM;AACvB,QAAI,QAAQ;AACV,cAAQ,UAAU,MAAM,gBAAgB;AAAA;AAExC,uBAAiB,IAAI;AAAA,EACzB;AACA,QAAM,OAAO,WAAW,EAAE,OAAO,QAAQ,WAAW,KAAK,CAAC;AAC1D,eAAa,MAAM,UAAU,MAAM,KAAK,CAAC;AACzC,QAAM,OAAO,SAAS;AAAA,IACpB,MAAM;AACJ,aAAO,WAAW,MAAM,QAAQ,MAAM;AAAA,IACxC;AAAA,IACA,IAAI,GAAG;AACL,YAAM,QAAQ;AAAA,IAChB;AAAA,EACF,CAAC;AACD,SAAO,OAAO,OAAO,MAAM,EAAE,OAAO,QAAQ,MAAM,CAAC;AACrD;AAEA,SAAS,iBAAiB,WAAW,WAAW,KAAK,GAAG;AACtD,QAAM,cAAc,gBAAgB;AACpC,QAAM,aAAa,gBAAgB;AACnC,QAAM,aAAa,gBAAgB;AACnC,MAAI,WAAW;AACf,QAAM,SAAS,CAAC,SAAS;AACvB,eAAW,QAAQ,IAAI;AACvB,aAAS,QAAQ;AACjB,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,iBAAW;AAAA,IACb,CAAC;AAAA,EACH;AACA,QAAM,UAAU,CAAC,SAAS;AACxB,aAAS,QAAQ;AACjB,gBAAY,QAAQ,IAAI;AACxB,aAAS,EAAE,MAAM,YAAY,MAAM,CAAC;AAAA,EACtC;AACA,QAAM,SAAS,CAAC,SAAS;AACvB,aAAS,QAAQ;AACjB,eAAW,QAAQ,IAAI;AACvB,aAAS,EAAE,MAAM,YAAY,KAAK,CAAC;AAAA,EACrC;AACA,SAAO;AAAA,IACL,YAAY,SAAS,MAAM,SAAS,KAAK;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,WAAW;AAAA,IACrB,WAAW,YAAY;AAAA,IACvB,UAAU,WAAW;AAAA,EACvB;AACF;AAEA,SAAS,aAAa,kBAAkB,SAAS;AAC/C,MAAI,IAAI;AACR,QAAM,YAAY,WAAW,QAAQ,gBAAgB,CAAC;AACtD,QAAM,qBAAqB,cAAc,MAAM;AAC7C,QAAI,KAAK;AACT,UAAM,QAAQ,UAAU,QAAQ;AAChC,cAAU,QAAQ,QAAQ,IAAI,IAAI;AAClC,KAAC,MAAM,WAAW,OAAO,SAAS,QAAQ,WAAW,OAAO,SAAS,IAAI,KAAK,OAAO;AACrF,QAAI,UAAU,SAAS,GAAG;AACxB,yBAAmB,MAAM;AACzB,OAAC,MAAM,WAAW,OAAO,SAAS,QAAQ,eAAe,OAAO,SAAS,IAAI,KAAK,OAAO;AAAA,IAC3F;AAAA,EACF,IAAI,KAAK,WAAW,OAAO,SAAS,QAAQ,aAAa,OAAO,KAAK,KAAK,EAAE,YAAY,KAAK,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,KAAK,MAAM,CAAC;AACjK,QAAM,QAAQ,CAAC,cAAc;AAC3B,QAAI;AACJ,cAAU,SAAS,MAAM,QAAQ,SAAS,MAAM,OAAO,MAAM,QAAQ,gBAAgB;AAAA,EACvF;AACA,QAAM,OAAO,MAAM;AACjB,uBAAmB,MAAM;AACzB,UAAM;AAAA,EACR;AACA,QAAM,SAAS,MAAM;AACnB,QAAI,CAAC,mBAAmB,SAAS,OAAO;AACtC,UAAI,UAAU,QAAQ,GAAG;AACvB,2BAAmB,OAAO;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AACA,QAAM,QAAQ,CAAC,cAAc;AAC3B,UAAM,SAAS;AACf,uBAAmB,OAAO;AAAA,EAC5B;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,mBAAmB;AAAA,IAC1B;AAAA,IACA,UAAU,mBAAmB;AAAA,EAC/B;AACF;AAEA,SAAS,UAAU,MAAM,QAAQ,UAAU,CAAC,GAAG;AAC7C,QAAM,EAAE,QAAAA,UAAS,eAAe,cAAc,UAAU,MAAM,IAAI;AAClE,QAAM,WAAW,WAAW,YAAY;AACxC,QAAM,QAAQ,SAAS,MAAM;AAC3B,QAAI;AACJ,WAAO,aAAa,MAAM,OAAO,KAAKA,WAAU,OAAO,SAASA,QAAO,aAAa,OAAO,SAAS,GAAG;AAAA,EACzG,CAAC;AACD,WAAS,eAAe;AACtB,QAAI;AACJ,UAAM,MAAM,QAAQ,IAAI;AACxB,UAAM,KAAK,QAAQ,KAAK;AACxB,QAAI,MAAMA,WAAU,KAAK;AACvB,YAAM,SAAS,KAAKA,QAAO,iBAAiB,EAAE,EAAE,iBAAiB,GAAG,MAAM,OAAO,SAAS,GAAG,KAAK;AAClG,eAAS,QAAQ,SAAS,SAAS,SAAS;AAAA,IAC9C;AAAA,EACF;AACA,MAAI,SAAS;AACX,wBAAoB,OAAO,cAAc;AAAA,MACvC,iBAAiB,CAAC,SAAS,OAAO;AAAA,MAClC,QAAAA;AAAA,IACF,CAAC;AAAA,EACH;AACA;AAAA,IACE,CAAC,OAAO,MAAM,QAAQ,IAAI,CAAC;AAAA,IAC3B,CAAC,GAAG,QAAQ;AACV,UAAI,IAAI,CAAC,KAAK,IAAI,CAAC;AACjB,YAAI,CAAC,EAAE,MAAM,eAAe,IAAI,CAAC,CAAC;AACpC,mBAAa;AAAA,IACf;AAAA,IACA,EAAE,WAAW,KAAK;AAAA,EACpB;AACA;AAAA,IACE,CAAC,UAAU,KAAK;AAAA,IAChB,CAAC,CAAC,KAAK,EAAE,MAAM;AACb,YAAM,WAAW,QAAQ,IAAI;AAC7B,WAAK,MAAM,OAAO,SAAS,GAAG,UAAU,UAAU;AAChD,YAAI,OAAO;AACT,aAAG,MAAM,eAAe,QAAQ;AAAA;AAEhC,aAAG,MAAM,YAAY,UAAU,GAAG;AAAA,MACtC;AAAA,IACF;AAAA,IACA,EAAE,WAAW,KAAK;AAAA,EACpB;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,eAAe;AACxC,QAAM,KAAK,mBAAmB;AAC9B,QAAM,iBAAiB;AAAA,IACrB,MAAM;AAAA,IACN,MAAM,gBAAgB,aAAa,aAAa,IAAI,GAAG,MAAM;AAAA,EAC/D;AACA,YAAU,eAAe,OAAO;AAChC,YAAU,eAAe,OAAO;AAChC,SAAO;AACT;AAEA,SAAS,aAAa,MAAM,SAAS;AACnC,QAAM,QAAQ,WAAW,gBAAgB,CAAC;AAC1C,QAAM,UAAUQ,OAAM,IAAI;AAC1B,QAAM,QAAQ,SAAS;AAAA,IACrB,MAAM;AACJ,UAAI;AACJ,YAAM,aAAa,QAAQ;AAC3B,UAAI,UAAU,WAAW,OAAO,SAAS,QAAQ,cAAc,QAAQ,WAAW,MAAM,OAAO,UAAU,IAAI,WAAW,QAAQ,MAAM,KAAK;AAC3I,UAAI,SAAS;AACX,kBAAU,KAAK,WAAW,OAAO,SAAS,QAAQ,kBAAkB,OAAO,KAAK;AAClF,aAAO;AAAA,IACT;AAAA,IACA,IAAI,GAAG;AACL,MAAAC,KAAI,CAAC;AAAA,IACP;AAAA,EACF,CAAC;AACD,WAASA,KAAI,GAAG;AACd,UAAM,aAAa,QAAQ;AAC3B,UAAM,SAAS,WAAW;AAC1B,UAAM,UAAU,IAAI,SAAS,UAAU;AACvC,UAAM,QAAQ,WAAW,MAAM;AAC/B,UAAM,QAAQ;AACd,WAAO;AAAA,EACT;AACA,WAAS,MAAM,QAAQ,GAAG;AACxB,WAAOA,KAAI,MAAM,QAAQ,KAAK;AAAA,EAChC;AACA,WAAS,KAAK,IAAI,GAAG;AACnB,WAAO,MAAM,CAAC;AAAA,EAChB;AACA,WAAS,KAAK,IAAI,GAAG;AACnB,WAAO,MAAM,CAAC,CAAC;AAAA,EACjB;AACA,WAAS,kBAAkB;AACzB,QAAI,IAAI;AACR,YAAQ,KAAK,SAAS,KAAK,WAAW,OAAO,SAAS,QAAQ,iBAAiB,OAAO,KAAK,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,OAAO,KAAK;AAAA,EAC/H;AACA,QAAM,SAAS,MAAMA,KAAI,MAAM,KAAK,CAAC;AACrC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAIA;AAAA,EACN;AACF;AAEA,SAAS,QAAQ,UAAU,CAAC,GAAG;AAC7B,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,aAAa;AAAA,EACf,IAAI;AACJ,QAAM,OAAO,aAAa;AAAA,IACxB,GAAG;AAAA,IACH,WAAW,CAAC,OAAO,mBAAmB;AACpC,UAAI;AACJ,UAAI,QAAQ;AACV,SAAC,KAAK,QAAQ,cAAc,OAAO,SAAS,GAAG,KAAK,SAAS,UAAU,QAAQ,gBAAgB,KAAK;AAAA;AAEpG,uBAAe,KAAK;AAAA,IACxB;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AACD,QAAM,SAAS,SAAS,MAAM,KAAK,OAAO,KAAK;AAC/C,QAAM,SAAS,SAAS;AAAA,IACtB,MAAM;AACJ,aAAO,KAAK,UAAU;AAAA,IACxB;AAAA,IACA,IAAI,GAAG;AACL,YAAM,UAAU,IAAI,SAAS;AAC7B,UAAI,OAAO,UAAU;AACnB,aAAK,QAAQ;AAAA;AAEb,aAAK,QAAQ;AAAA,IACjB;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAEA,SAAS,SAAS,GAAG;AACnB,SAAO;AACT;AACA,SAAS,YAAY,QAAQ,OAAO;AAClC,SAAO,OAAO,QAAQ;AACxB;AACA,SAAS,YAAY,OAAO;AAC1B,SAAO,QAAQ,OAAO,UAAU,aAAa,QAAQ,cAAc;AACrE;AACA,SAAS,aAAa,OAAO;AAC3B,SAAO,QAAQ,OAAO,UAAU,aAAa,QAAQ,cAAc;AACrE;AACA,SAAS,oBAAoB,QAAQ,UAAU,CAAC,GAAG;AACjD,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,OAAO,YAAY,KAAK;AAAA,IACxB,QAAQ,aAAa,KAAK;AAAA,IAC1B,YAAY;AAAA,EACd,IAAI;AACJ,WAAS,uBAAuB;AAC9B,WAAO,QAAQ;AAAA,MACb,UAAU,KAAK,OAAO,KAAK;AAAA,MAC3B,WAAW,UAAU;AAAA,IACvB,CAAC;AAAA,EACH;AACA,QAAM,OAAO,IAAI,qBAAqB,CAAC;AACvC,QAAM,YAAY,IAAI,CAAC,CAAC;AACxB,QAAM,YAAY,IAAI,CAAC,CAAC;AACxB,QAAM,aAAa,CAAC,WAAW;AAC7B,cAAU,QAAQ,MAAM,OAAO,QAAQ,CAAC;AACxC,SAAK,QAAQ;AAAA,EACf;AACA,QAAM,SAAS,MAAM;AACnB,cAAU,MAAM,QAAQ,KAAK,KAAK;AAClC,SAAK,QAAQ,qBAAqB;AAClC,QAAI,QAAQ,YAAY,UAAU,MAAM,SAAS,QAAQ;AACvD,gBAAU,MAAM,OAAO,QAAQ,UAAU,OAAO,iBAAiB;AACnE,QAAI,UAAU,MAAM;AAClB,gBAAU,MAAM,OAAO,GAAG,UAAU,MAAM,MAAM;AAAA,EACpD;AACA,QAAM,QAAQ,MAAM;AAClB,cAAU,MAAM,OAAO,GAAG,UAAU,MAAM,MAAM;AAChD,cAAU,MAAM,OAAO,GAAG,UAAU,MAAM,MAAM;AAAA,EAClD;AACA,QAAM,OAAO,MAAM;AACjB,UAAM,QAAQ,UAAU,MAAM,MAAM;AACpC,QAAI,OAAO;AACT,gBAAU,MAAM,QAAQ,KAAK,KAAK;AAClC,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF;AACA,QAAM,OAAO,MAAM;AACjB,UAAM,QAAQ,UAAU,MAAM,MAAM;AACpC,QAAI,OAAO;AACT,gBAAU,MAAM,QAAQ,KAAK,KAAK;AAClC,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF;AACA,QAAM,QAAQ,MAAM;AAClB,eAAW,KAAK,KAAK;AAAA,EACvB;AACA,QAAM,UAAU,SAAS,MAAM,CAAC,KAAK,OAAO,GAAG,UAAU,KAAK,CAAC;AAC/D,QAAM,UAAU,SAAS,MAAM,UAAU,MAAM,SAAS,CAAC;AACzD,QAAM,UAAU,SAAS,MAAM,UAAU,MAAM,SAAS,CAAC;AACzD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,cAAc,QAAQ,UAAU,CAAC,GAAG;AAC3C,QAAM;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,IACR;AAAA,EACF,IAAI;AACJ,QAAM;AAAA,IACJ,aAAa;AAAA,IACb;AAAA,IACA,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ,IAAI,eAAe,WAAW;AAC9B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAAA,IACF;AAAA,IACA;AAAA,IACA,EAAE,MAAM,OAAO,aAAa,eAAe;AAAA,EAC7C;AACA,WAAS,UAAU,SAAS,OAAO;AACjC,2BAAuB;AACvB,kBAAc,MAAM;AAClB,cAAQ,QAAQ;AAAA,IAClB,CAAC;AAAA,EACH;AACA,QAAM,gBAAgB,oBAAoB,QAAQ,EAAE,GAAG,SAAS,OAAO,QAAQ,SAAS,MAAM,UAAU,CAAC;AACzG,QAAM,EAAE,OAAO,QAAQ,aAAa,IAAI;AACxC,WAAS,SAAS;AAChB,2BAAuB;AACvB,iBAAa;AAAA,EACf;AACA,WAAS,OAAO,WAAW;AACzB,mBAAe;AACf,QAAI;AACF,aAAO;AAAA,EACX;AACA,WAAS,MAAM,IAAI;AACjB,QAAI,WAAW;AACf,UAAM,SAAS,MAAM,WAAW;AAChC,kBAAc,MAAM;AAClB,SAAG,MAAM;AAAA,IACX,CAAC;AACD,QAAI,CAAC;AACH,aAAO;AAAA,EACX;AACA,WAAS,UAAU;AACjB,SAAK;AACL,UAAM;AAAA,EACR;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,QAAQ,UAAU,CAAC,GAAG;AACpD,QAAM,SAAS,QAAQ,WAAW,eAAe,QAAQ,QAAQ,IAAI;AACrE,QAAM,UAAU,cAAc,QAAQ,EAAE,GAAG,SAAS,aAAa,OAAO,CAAC;AACzE,SAAO;AAAA,IACL,GAAG;AAAA,EACL;AACF;AAEA,SAAS,gBAAgB,UAAU,CAAC,GAAG;AACrC,QAAM;AAAA,IACJ,QAAAT,UAAS;AAAA,IACT,qBAAqB;AAAA,IACrB,cAAc;AAAA,EAChB,IAAI;AACJ,QAAM,cAAc,aAAa,MAAM,OAAO,sBAAsB,WAAW;AAC/E,QAAM,qBAAqB,aAAa,MAAM,YAAY,SAAS,uBAAuB,qBAAqB,OAAO,kBAAkB,sBAAsB,UAAU;AACxK,QAAM,oBAAoB,WAAW,KAAK;AAC1C,QAAM,eAAe,IAAI,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AACtD,QAAM,eAAe,IAAI,EAAE,OAAO,MAAM,MAAM,MAAM,OAAO,KAAK,CAAC;AACjE,QAAM,WAAW,WAAW,CAAC;AAC7B,QAAM,+BAA+B,IAAI;AAAA,IACvC,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL,CAAC;AACD,WAAS,OAAO;AACd,QAAIA,SAAQ;AACV,YAAM,iBAAiB;AAAA,QACrB;AAAA,QACA,CAAC,UAAU;AACT,cAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AACpC,uBAAa,QAAQ;AAAA,YACnB,KAAK,KAAK,MAAM,iBAAiB,OAAO,SAAS,GAAG,MAAM;AAAA,YAC1D,KAAK,KAAK,MAAM,iBAAiB,OAAO,SAAS,GAAG,MAAM;AAAA,YAC1D,KAAK,KAAK,MAAM,iBAAiB,OAAO,SAAS,GAAG,MAAM;AAAA,UAC5D;AACA,uCAA6B,QAAQ;AAAA,YACnC,KAAK,KAAK,MAAM,iCAAiC,OAAO,SAAS,GAAG,MAAM;AAAA,YAC1E,KAAK,KAAK,MAAM,iCAAiC,OAAO,SAAS,GAAG,MAAM;AAAA,YAC1E,KAAK,KAAK,MAAM,iCAAiC,OAAO,SAAS,GAAG,MAAM;AAAA,UAC5E;AACA,uBAAa,QAAQ;AAAA,YACnB,SAAS,KAAK,MAAM,iBAAiB,OAAO,SAAS,GAAG,UAAU;AAAA,YAClE,QAAQ,KAAK,MAAM,iBAAiB,OAAO,SAAS,GAAG,SAAS;AAAA,YAChE,SAAS,KAAK,MAAM,iBAAiB,OAAO,SAAS,GAAG,UAAU;AAAA,UACpE;AACA,mBAAS,QAAQ,MAAM;AAAA,QACzB;AAAA,MACF;AACA,uBAAiBA,SAAQ,gBAAgB,gBAAgB,EAAE,SAAS,KAAK,CAAC;AAAA,IAC5E;AAAA,EACF;AACA,QAAM,oBAAoB,YAAY;AACpC,QAAI,CAAC,mBAAmB;AACtB,wBAAkB,QAAQ;AAC5B,QAAI,kBAAkB;AACpB;AACF,QAAI,mBAAmB,OAAO;AAC5B,YAAM,oBAAoB,kBAAkB;AAC5C,UAAI;AACF,cAAM,WAAW,MAAM,kBAAkB;AACzC,YAAI,aAAa,WAAW;AAC1B,4BAAkB,QAAQ;AAC1B,eAAK;AAAA,QACP;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,KAAK;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACA,MAAI,YAAY,OAAO;AACrB,QAAI,sBAAsB,mBAAmB,OAAO;AAClD,wBAAkB,EAAE,KAAK,MAAM,KAAK,CAAC;AAAA,IACvC,OAAO;AACL,WAAK;AAAA,IACP;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,UAAU,CAAC,GAAG;AAC1C,QAAM,EAAE,QAAAA,UAAS,cAAc,IAAI;AACnC,QAAM,cAAc,aAAa,MAAMA,WAAU,4BAA4BA,OAAM;AACnF,QAAM,aAAa,WAAW,KAAK;AACnC,QAAM,QAAQ,WAAW,IAAI;AAC7B,QAAM,OAAO,WAAW,IAAI;AAC5B,QAAM,QAAQ,WAAW,IAAI;AAC7B,MAAIA,WAAU,YAAY,OAAO;AAC/B,qBAAiBA,SAAQ,qBAAqB,CAAC,UAAU;AACvD,iBAAW,QAAQ,MAAM;AACzB,YAAM,QAAQ,MAAM;AACpB,WAAK,QAAQ,MAAM;AACnB,YAAM,QAAQ,MAAM;AAAA,IACtB,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,EACtB;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,oBAAoB,UAAU,CAAC,GAAG;AACzC,QAAM;AAAA,IACJ,QAAAA,UAAS;AAAA,EACX,IAAI;AACJ,QAAM,aAAa,WAAW,CAAC;AAC/B,QAAM,QAAQ,cAAc,MAAM,gBAAgB,WAAW,KAAK,SAAS,OAAO;AAClF,MAAI,OAAO;AACX,MAAIA,SAAQ;AACV,WAAO,eAAe,OAAO,MAAM,WAAW,QAAQA,QAAO,gBAAgB;AAAA,EAC/E;AACA,SAAO;AAAA,IACL,YAAY,SAAS,UAAU;AAAA,IAC/B;AAAA,EACF;AACF;AAEA,SAAS,eAAe,UAAU,CAAC,GAAG;AACpC,QAAM;AAAA,IACJ,WAAAG,aAAY;AAAA,IACZ,qBAAqB;AAAA,IACrB,cAAc,EAAE,OAAO,MAAM,OAAO,KAAK;AAAA,IACzC,WAAAO;AAAA,EACF,IAAI;AACJ,QAAM,UAAU,IAAI,CAAC,CAAC;AACtB,QAAM,cAAc,SAAS,MAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY,CAAC;AACvF,QAAM,cAAc,SAAS,MAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY,CAAC;AACvF,QAAM,eAAe,SAAS,MAAM,QAAQ,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,aAAa,CAAC;AACzF,QAAM,cAAc,aAAa,MAAMP,cAAaA,WAAU,gBAAgBA,WAAU,aAAa,gBAAgB;AACrH,QAAM,oBAAoB,WAAW,KAAK;AAC1C,MAAI;AACJ,iBAAe,SAAS;AACtB,QAAI,CAAC,YAAY;AACf;AACF,YAAQ,QAAQ,MAAMA,WAAU,aAAa,iBAAiB;AAC9D,IAAAO,cAAa,OAAO,SAASA,WAAU,QAAQ,KAAK;AACpD,QAAI,QAAQ;AACV,aAAO,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;AAC1C,eAAS;AAAA,IACX;AAAA,EACF;AACA,iBAAe,oBAAoB;AACjC,UAAM,aAAa,YAAY,QAAQ,WAAW;AAClD,QAAI,CAAC,YAAY;AACf,aAAO;AACT,QAAI,kBAAkB;AACpB,aAAO;AACT,UAAM,EAAE,OAAO,MAAM,IAAI,cAAc,YAAY,EAAE,UAAU,KAAK,CAAC;AACrE,UAAM,MAAM;AACZ,QAAI,MAAM,UAAU,WAAW;AAC7B,UAAI,UAAU;AACd,UAAI;AACF,iBAAS,MAAMP,WAAU,aAAa,aAAa,WAAW;AAAA,MAChE,SAAS,GAAG;AACV,iBAAS;AACT,kBAAU;AAAA,MACZ;AACA,aAAO;AACP,wBAAkB,QAAQ;AAAA,IAC5B,OAAO;AACL,wBAAkB,QAAQ;AAAA,IAC5B;AACA,WAAO,kBAAkB;AAAA,EAC3B;AACA,MAAI,YAAY,OAAO;AACrB,QAAI;AACF,wBAAkB;AACpB,qBAAiBA,WAAU,cAAc,gBAAgB,QAAQ,EAAE,SAAS,KAAK,CAAC;AAClF,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,UAAU,CAAC,GAAG;AACrC,MAAI;AACJ,QAAM,UAAU,YAAY,KAAK,QAAQ,YAAY,OAAO,KAAK,KAAK;AACtE,QAAM,QAAQ,QAAQ;AACtB,QAAM,QAAQ,QAAQ;AACtB,QAAM,EAAE,WAAAA,aAAY,iBAAiB,IAAI;AACzC,QAAM,cAAc,aAAa,MAAM;AACrC,QAAI;AACJ,YAAQ,MAAMA,cAAa,OAAO,SAASA,WAAU,iBAAiB,OAAO,SAAS,IAAI;AAAA,EAC5F,CAAC;AACD,QAAM,aAAa,EAAE,OAAO,MAAM;AAClC,QAAM,SAAS,WAAW;AAC1B,iBAAe,SAAS;AACtB,QAAI;AACJ,QAAI,CAAC,YAAY,SAAS,OAAO;AAC/B;AACF,WAAO,QAAQ,MAAMA,WAAU,aAAa,gBAAgB,UAAU;AACtE,KAAC,MAAM,OAAO,UAAU,OAAO,SAAS,IAAI,UAAU,EAAE,QAAQ,CAAC,MAAM,iBAAiB,GAAG,SAAS,MAAM,EAAE,SAAS,KAAK,CAAC,CAAC;AAC5H,WAAO,OAAO;AAAA,EAChB;AACA,iBAAe,QAAQ;AACrB,QAAI;AACJ,KAAC,MAAM,OAAO,UAAU,OAAO,SAAS,IAAI,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;AAC/E,WAAO,QAAQ;AAAA,EACjB;AACA,WAAS,OAAO;AACd,UAAM;AACN,YAAQ,QAAQ;AAAA,EAClB;AACA,iBAAe,QAAQ;AACrB,UAAM,OAAO;AACb,QAAI,OAAO;AACT,cAAQ,QAAQ;AAClB,WAAO,OAAO;AAAA,EAChB;AACA;AAAA,IACE;AAAA,IACA,CAAC,MAAM;AACL,UAAI;AACF,eAAO;AAAA;AAEP,cAAM;AAAA,IACV;AAAA,IACA,EAAE,WAAW,KAAK;AAAA,EACpB;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,UAAU,CAAC,GAAG;AAC3C,QAAM,EAAE,UAAAF,YAAW,gBAAgB,IAAI;AACvC,MAAI,CAACA;AACH,WAAO,WAAW,SAAS;AAC7B,QAAM,aAAa,WAAWA,UAAS,eAAe;AACtD,mBAAiBA,WAAU,oBAAoB,MAAM;AACnD,eAAW,QAAQA,UAAS;AAAA,EAC9B,GAAG,EAAE,SAAS,KAAK,CAAC;AACpB,SAAO;AACT;AAEA,SAAS,aAAa,QAAQ,UAAU,CAAC,GAAG;AAC1C,MAAI;AACJ,QAAM;AAAA,IACJ;AAAA,IACA,gBAAAU;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB;AAAA,IACA,QAAQ,iBAAiB;AAAA,IACzB,UAAU,CAAC,CAAC;AAAA,EACd,IAAI;AACJ,QAAM,WAAW;AAAA,KACd,KAAK,QAAQ,YAAY,MAAM,OAAO,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,EAC3D;AACA,QAAM,eAAe,IAAI;AACzB,QAAM,cAAc,CAAC,MAAM;AACzB,QAAI;AACF,aAAO,aAAa,SAAS,EAAE,WAAW;AAC5C,WAAO;AAAA,EACT;AACA,QAAM,cAAc,CAAC,MAAM;AACzB,QAAI,QAAQA,eAAc;AACxB,QAAE,eAAe;AACnB,QAAI,QAAQ,eAAe;AACzB,QAAE,gBAAgB;AAAA,EACtB;AACA,QAAM,QAAQ,CAAC,MAAM;AACnB,QAAI;AACJ,QAAI,CAAC,QAAQ,OAAO,EAAE,SAAS,EAAE,MAAM;AACrC;AACF,QAAI,QAAQ,QAAQ,QAAQ,KAAK,CAAC,YAAY,CAAC;AAC7C;AACF,QAAI,QAAQ,KAAK,KAAK,EAAE,WAAW,QAAQ,MAAM;AAC/C;AACF,UAAM,YAAY,QAAQ,gBAAgB;AAC1C,UAAM,iBAAiB,MAAM,aAAa,OAAO,SAAS,UAAU,0BAA0B,OAAO,SAAS,IAAI,KAAK,SAAS;AAChI,UAAM,aAAa,QAAQ,MAAM,EAAE,sBAAsB;AACzD,UAAM,MAAM;AAAA,MACV,GAAG,EAAE,WAAW,YAAY,WAAW,OAAO,cAAc,OAAO,UAAU,aAAa,WAAW;AAAA,MACrG,GAAG,EAAE,WAAW,YAAY,WAAW,MAAM,cAAc,MAAM,UAAU,YAAY,WAAW;AAAA,IACpG;AACA,SAAK,WAAW,OAAO,SAAS,QAAQ,KAAK,CAAC,OAAO;AACnD;AACF,iBAAa,QAAQ;AACrB,gBAAY,CAAC;AAAA,EACf;AACA,QAAM,OAAO,CAAC,MAAM;AAClB,QAAI,QAAQ,QAAQ,QAAQ,KAAK,CAAC,YAAY,CAAC;AAC7C;AACF,QAAI,CAAC,aAAa;AAChB;AACF,UAAM,YAAY,QAAQ,gBAAgB;AAC1C,UAAM,aAAa,QAAQ,MAAM,EAAE,sBAAsB;AACzD,QAAI,EAAE,GAAG,EAAE,IAAI,SAAS;AACxB,QAAI,SAAS,OAAO,SAAS,QAAQ;AACnC,UAAI,EAAE,UAAU,aAAa,MAAM;AACnC,UAAI;AACF,YAAI,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,GAAG,UAAU,cAAc,WAAW,KAAK;AAAA,IACzE;AACA,QAAI,SAAS,OAAO,SAAS,QAAQ;AACnC,UAAI,EAAE,UAAU,aAAa,MAAM;AACnC,UAAI;AACF,YAAI,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,GAAG,UAAU,eAAe,WAAW,MAAM;AAAA,IAC3E;AACA,aAAS,QAAQ;AAAA,MACf;AAAA,MACA;AAAA,IACF;AACA,cAAU,OAAO,SAAS,OAAO,SAAS,OAAO,CAAC;AAClD,gBAAY,CAAC;AAAA,EACf;AACA,QAAM,MAAM,CAAC,MAAM;AACjB,QAAI,QAAQ,QAAQ,QAAQ,KAAK,CAAC,YAAY,CAAC;AAC7C;AACF,QAAI,CAAC,aAAa;AAChB;AACF,iBAAa,QAAQ;AACrB,aAAS,OAAO,SAAS,MAAM,SAAS,OAAO,CAAC;AAChD,gBAAY,CAAC;AAAA,EACf;AACA,MAAI,UAAU;AACZ,UAAM,SAAS,MAAM;AACnB,UAAI;AACJ,aAAO;AAAA,QACL,UAAU,MAAM,QAAQ,YAAY,OAAO,MAAM;AAAA,QACjD,SAAS,CAAC,QAAQA,eAAc;AAAA,MAClC;AAAA,IACF;AACA,qBAAiB,gBAAgB,eAAe,OAAO,MAAM;AAC7D,qBAAiB,iBAAiB,eAAe,MAAM,MAAM;AAC7D,qBAAiB,iBAAiB,aAAa,KAAK,MAAM;AAAA,EAC5D;AACA,SAAO;AAAA,IACL,GAAGC,QAAO,QAAQ;AAAA,IAClB;AAAA,IACA,YAAY,SAAS,MAAM,CAAC,CAAC,aAAa,KAAK;AAAA,IAC/C,OAAO;AAAA,MACL,MAAM,QAAQ,SAAS,MAAM,CAAC,UAAU,SAAS,MAAM,CAAC;AAAA,IAC1D;AAAA,EACF;AACF;AAEA,SAAS,YAAY,QAAQ,UAAU,CAAC,GAAG;AACzC,MAAI,IAAI;AACR,QAAM,iBAAiB,WAAW,KAAK;AACvC,QAAM,QAAQ,WAAW,IAAI;AAC7B,MAAI,UAAU;AACd,MAAI,UAAU;AACd,MAAI,UAAU;AACZ,UAAM,WAAW,OAAO,YAAY,aAAa,EAAE,QAAQ,QAAQ,IAAI;AACvE,UAAM,YAAY,KAAK,SAAS,aAAa,OAAO,KAAK;AACzD,UAAM,8BAA8B,KAAK,SAAS,+BAA+B,OAAO,KAAK;AAC7F,UAAM,WAAW,CAAC,UAAU;AAC1B,UAAI,KAAK;AACT,YAAM,OAAO,MAAM,MAAM,OAAO,MAAM,MAAM,iBAAiB,OAAO,SAAS,IAAI,UAAU,OAAO,MAAM,CAAC,CAAC;AAC1G,aAAO,KAAK,WAAW,IAAI,OAAO,WAAW,OAAO,CAAC,KAAK,CAAC,CAAC;AAAA,IAC9D;AACA,UAAM,iBAAiB,CAAC,UAAU;AAChC,YAAM,YAAY,MAAM,SAAS,SAAS;AAC1C,UAAI,OAAO,cAAc;AACvB,eAAO,UAAU,KAAK;AACxB,UAAI,EAAE,aAAa,OAAO,SAAS,UAAU;AAC3C,eAAO;AACT,UAAI,MAAM,WAAW;AACnB,eAAO;AACT,aAAO,MAAM;AAAA,QACX,CAAC,SAAS,UAAU,KAAK,CAAC,gBAAgB,KAAK,SAAS,WAAW,CAAC;AAAA,MACtE;AAAA,IACF;AACA,UAAM,gBAAgB,CAAC,UAAU;AAC/B,YAAM,QAAQ,MAAM,KAAK,SAAS,OAAO,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,KAAK,IAAI;AAC5E,YAAM,iBAAiB,eAAe,KAAK;AAC3C,YAAM,qBAAqB,YAAY,MAAM,UAAU;AACvD,aAAO,kBAAkB;AAAA,IAC3B;AACA,UAAM,WAAW,MAAM,mCAAmC,KAAK,UAAU,SAAS,KAAK,EAAE,YAAY;AACrG,UAAM,kBAAkB,CAAC,OAAO,cAAc;AAC5C,UAAI,KAAK,KAAK,IAAI,IAAI,IAAI;AAC1B,YAAM,wBAAwB,MAAM,MAAM,iBAAiB,OAAO,SAAS,IAAI;AAC/E,iBAAW,MAAM,wBAAwB,cAAc,oBAAoB,MAAM,OAAO,MAAM;AAC9F,UAAI,4BAA4B;AAC9B,cAAM,eAAe;AAAA,MACvB;AACA,UAAI,CAAC,SAAS,KAAK,CAAC,SAAS;AAC3B,YAAI,MAAM,cAAc;AACtB,gBAAM,aAAa,aAAa;AAAA,QAClC;AACA;AAAA,MACF;AACA,YAAM,eAAe;AACrB,UAAI,MAAM,cAAc;AACtB,cAAM,aAAa,aAAa;AAAA,MAClC;AACA,YAAM,eAAe,SAAS,KAAK;AACnC,cAAQ,WAAW;AAAA,QACjB,KAAK;AACH,qBAAW;AACX,yBAAe,QAAQ;AACvB,WAAC,KAAK,SAAS,YAAY,OAAO,SAAS,GAAG,KAAK,UAAU,MAAM,KAAK;AACxE;AAAA,QACF,KAAK;AACH,WAAC,KAAK,SAAS,WAAW,OAAO,SAAS,GAAG,KAAK,UAAU,MAAM,KAAK;AACvE;AAAA,QACF,KAAK;AACH,qBAAW;AACX,cAAI,YAAY;AACd,2BAAe,QAAQ;AACzB,WAAC,KAAK,SAAS,YAAY,OAAO,SAAS,GAAG,KAAK,UAAU,MAAM,KAAK;AACxE;AAAA,QACF,KAAK;AACH,oBAAU;AACV,yBAAe,QAAQ;AACvB,cAAI,SAAS;AACX,kBAAM,QAAQ;AACd,aAAC,KAAK,SAAS,WAAW,OAAO,SAAS,GAAG,KAAK,UAAU,cAAc,KAAK;AAAA,UACjF;AACA;AAAA,MACJ;AAAA,IACF;AACA,qBAAiB,QAAQ,aAAa,CAAC,UAAU,gBAAgB,OAAO,OAAO,CAAC;AAChF,qBAAiB,QAAQ,YAAY,CAAC,UAAU,gBAAgB,OAAO,MAAM,CAAC;AAC9E,qBAAiB,QAAQ,aAAa,CAAC,UAAU,gBAAgB,OAAO,OAAO,CAAC;AAChF,qBAAiB,QAAQ,QAAQ,CAAC,UAAU,gBAAgB,OAAO,MAAM,CAAC;AAAA,EAC5E;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,QAAQ,UAAU,UAAU,CAAC,GAAG;AACzD,QAAM,EAAE,QAAAZ,UAAS,eAAe,GAAG,gBAAgB,IAAI;AACvD,MAAI;AACJ,QAAM,cAAc,aAAa,MAAMA,WAAU,oBAAoBA,OAAM;AAC3E,QAAM,UAAU,MAAM;AACpB,QAAI,UAAU;AACZ,eAAS,WAAW;AACpB,iBAAW;AAAA,IACb;AAAA,EACF;AACA,QAAM,UAAU,SAAS,MAAM;AAC7B,UAAM,WAAW,QAAQ,MAAM;AAC/B,WAAO,MAAM,QAAQ,QAAQ,IAAI,SAAS,IAAI,CAAC,OAAO,aAAa,EAAE,CAAC,IAAI,CAAC,aAAa,QAAQ,CAAC;AAAA,EACnG,CAAC;AACD,QAAM,YAAY;AAAA,IAChB;AAAA,IACA,CAAC,QAAQ;AACP,cAAQ;AACR,UAAI,YAAY,SAASA,SAAQ;AAC/B,mBAAW,IAAI,eAAe,QAAQ;AACtC,mBAAW,OAAO,KAAK;AACrB,cAAI;AACF,qBAAS,QAAQ,KAAK,eAAe;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,WAAW,MAAM,OAAO,OAAO;AAAA,EACnC;AACA,QAAM,OAAO,MAAM;AACjB,YAAQ;AACR,cAAU;AAAA,EACZ;AACA,oBAAkB,IAAI;AACtB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,QAAQ,UAAU,CAAC,GAAG;AAChD,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,eAAe;AAAA,IACf,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,eAAe;AAAA,EACjB,IAAI;AACJ,QAAM,SAAS,WAAW,CAAC;AAC3B,QAAM,SAAS,WAAW,CAAC;AAC3B,QAAM,OAAO,WAAW,CAAC;AACzB,QAAM,QAAQ,WAAW,CAAC;AAC1B,QAAM,MAAM,WAAW,CAAC;AACxB,QAAM,QAAQ,WAAW,CAAC;AAC1B,QAAM,IAAI,WAAW,CAAC;AACtB,QAAM,IAAI,WAAW,CAAC;AACtB,WAAS,cAAc;AACrB,UAAM,KAAK,aAAa,MAAM;AAC9B,QAAI,CAAC,IAAI;AACP,UAAI,OAAO;AACT,eAAO,QAAQ;AACf,eAAO,QAAQ;AACf,aAAK,QAAQ;AACb,cAAM,QAAQ;AACd,YAAI,QAAQ;AACZ,cAAM,QAAQ;AACd,UAAE,QAAQ;AACV,UAAE,QAAQ;AAAA,MACZ;AACA;AAAA,IACF;AACA,UAAM,OAAO,GAAG,sBAAsB;AACtC,WAAO,QAAQ,KAAK;AACpB,WAAO,QAAQ,KAAK;AACpB,SAAK,QAAQ,KAAK;AAClB,UAAM,QAAQ,KAAK;AACnB,QAAI,QAAQ,KAAK;AACjB,UAAM,QAAQ,KAAK;AACnB,MAAE,QAAQ,KAAK;AACf,MAAE,QAAQ,KAAK;AAAA,EACjB;AACA,WAAS,SAAS;AAChB,QAAI,iBAAiB;AACnB,kBAAY;AAAA,aACL,iBAAiB;AACxB,4BAAsB,MAAM,YAAY,CAAC;AAAA,EAC7C;AACA,oBAAkB,QAAQ,MAAM;AAChC,QAAM,MAAM,aAAa,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,OAAO,CAAC;AAC3D,sBAAoB,QAAQ,QAAQ;AAAA,IAClC,iBAAiB,CAAC,SAAS,OAAO;AAAA,EACpC,CAAC;AACD,MAAI;AACF,qBAAiB,UAAU,QAAQ,EAAE,SAAS,MAAM,SAAS,KAAK,CAAC;AACrE,MAAI;AACF,qBAAiB,UAAU,QAAQ,EAAE,SAAS,KAAK,CAAC;AACtD,eAAa,MAAM;AACjB,QAAI;AACF,aAAO;AAAA,EACX,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,SAAS;AAClC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,UAAAC,YAAW;AAAA,IACX;AAAA,IACA,WAAW;AAAA,IACX,YAAY;AAAA,EACd,IAAI;AACJ,QAAM,cAAc,aAAa,MAAM;AACrC,QAAI,QAAQ,QAAQ;AAClB,aAAOA,aAAY,uBAAuBA;AAC5C,WAAOA,aAAY,sBAAsBA;AAAA,EAC3C,CAAC;AACD,QAAM,UAAU,WAAW,IAAI;AAC/B,QAAM,KAAK,MAAM;AACf,QAAI,IAAI;AACR,YAAQ,QAAQ,QAAQ,QAAQ,KAAK,KAAKA,aAAY,OAAO,SAASA,UAAS,kBAAkB,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,MAAM,OAAO,KAAK,CAAC,KAAK,KAAKA,aAAY,OAAO,SAASA,UAAS,iBAAiB,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,MAAM,OAAO,KAAK;AAAA,EACpP;AACA,QAAM,WAAW,aAAa,0BAA0B,SAAS,IAAI,EAAE,UAAU,CAAC,IAAI,cAAc,IAAI,UAAU,EAAE,UAAU,CAAC;AAC/H,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AACF;AAEA,SAAS,gBAAgB,IAAI,UAAU,CAAC,GAAG;AACzC,QAAM;AAAA,IACJ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,mBAAmB;AAAA,IACnB,QAAAD,UAAS;AAAA,EACX,IAAI;AACJ,QAAM,YAAY,WAAW,KAAK;AAClC,MAAI;AACJ,QAAM,SAAS,CAAC,aAAa;AAC3B,UAAM,QAAQ,WAAW,aAAa;AACtC,QAAI,OAAO;AACT,mBAAa,KAAK;AAClB,cAAQ;AAAA,IACV;AACA,QAAI;AACF,cAAQ,WAAW,MAAM,UAAU,QAAQ,UAAU,KAAK;AAAA;AAE1D,gBAAU,QAAQ;AAAA,EACtB;AACA,MAAI,CAACA;AACH,WAAO;AACT,mBAAiB,IAAI,cAAc,MAAM,OAAO,IAAI,GAAG,EAAE,SAAS,KAAK,CAAC;AACxE,mBAAiB,IAAI,cAAc,MAAM,OAAO,KAAK,GAAG,EAAE,SAAS,KAAK,CAAC;AACzE,MAAI,kBAAkB;AACpB;AAAA,MACE,SAAS,MAAM,aAAa,EAAE,CAAC;AAAA,MAC/B,MAAM,OAAO,KAAK;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,eAAe,QAAQ,cAAc,EAAE,OAAO,GAAG,QAAQ,EAAE,GAAG,UAAU,CAAC,GAAG;AACnF,QAAM,EAAE,QAAAA,UAAS,eAAe,MAAM,cAAc,IAAI;AACxD,QAAM,QAAQ,SAAS,MAAM;AAC3B,QAAI,IAAI;AACR,YAAQ,MAAM,KAAK,aAAa,MAAM,MAAM,OAAO,SAAS,GAAG,iBAAiB,OAAO,SAAS,GAAG,SAAS,KAAK;AAAA,EACnH,CAAC;AACD,QAAM,QAAQ,WAAW,YAAY,KAAK;AAC1C,QAAM,SAAS,WAAW,YAAY,MAAM;AAC5C,QAAM,EAAE,MAAM,MAAM,IAAI;AAAA,IACtB;AAAA,IACA,CAAC,CAAC,KAAK,MAAM;AACX,YAAM,UAAU,QAAQ,eAAe,MAAM,gBAAgB,QAAQ,gBAAgB,MAAM,iBAAiB,MAAM;AAClH,UAAIA,WAAU,MAAM,OAAO;AACzB,cAAM,QAAQ,aAAa,MAAM;AACjC,YAAI,OAAO;AACT,gBAAM,OAAO,MAAM,sBAAsB;AACzC,gBAAM,QAAQ,KAAK;AACnB,iBAAO,QAAQ,KAAK;AAAA,QACtB;AAAA,MACF,OAAO;AACL,YAAI,SAAS;AACX,gBAAM,gBAAgB,QAAQ,OAAO;AACrC,gBAAM,QAAQ,cAAc,OAAO,CAAC,KAAK,EAAE,WAAW,MAAM,MAAM,YAAY,CAAC;AAC/E,iBAAO,QAAQ,cAAc,OAAO,CAAC,KAAK,EAAE,UAAU,MAAM,MAAM,WAAW,CAAC;AAAA,QAChF,OAAO;AACL,gBAAM,QAAQ,MAAM,YAAY;AAChC,iBAAO,QAAQ,MAAM,YAAY;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACA,eAAa,MAAM;AACjB,UAAM,MAAM,aAAa,MAAM;AAC/B,QAAI,KAAK;AACP,YAAM,QAAQ,iBAAiB,MAAM,IAAI,cAAc,YAAY;AACnE,aAAO,QAAQ,kBAAkB,MAAM,IAAI,eAAe,YAAY;AAAA,IACxE;AAAA,EACF,CAAC;AACD,QAAM,QAAQ;AAAA,IACZ,MAAM,aAAa,MAAM;AAAA,IACzB,CAAC,QAAQ;AACP,YAAM,QAAQ,MAAM,YAAY,QAAQ;AACxC,aAAO,QAAQ,MAAM,YAAY,SAAS;AAAA,IAC5C;AAAA,EACF;AACA,WAAS,OAAO;AACd,UAAM;AACN,UAAM;AAAA,EACR;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,wBAAwB,QAAQ,UAAU,UAAU,CAAC,GAAG;AAC/D,QAAM;AAAA,IACJ;AAAA,IACA,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,QAAAA,UAAS;AAAA,IACT,YAAY;AAAA,EACd,IAAI;AACJ,QAAM,cAAc,aAAa,MAAMA,WAAU,0BAA0BA,OAAM;AACjF,QAAM,UAAU,SAAS,MAAM;AAC7B,UAAM,UAAU,QAAQ,MAAM;AAC9B,WAAO,QAAQ,OAAO,EAAE,IAAI,YAAY,EAAE,OAAO,UAAU;AAAA,EAC7D,CAAC;AACD,MAAI,UAAU;AACd,QAAM,WAAW,WAAW,SAAS;AACrC,QAAM,YAAY,YAAY,QAAQ;AAAA,IACpC,MAAM,CAAC,QAAQ,OAAO,aAAa,IAAI,GAAG,SAAS,KAAK;AAAA,IACxD,CAAC,CAAC,UAAU,KAAK,MAAM;AACrB,cAAQ;AACR,UAAI,CAAC,SAAS;AACZ;AACF,UAAI,CAAC,SAAS;AACZ;AACF,YAAM,WAAW,IAAI;AAAA,QACnB;AAAA,QACA;AAAA,UACE,MAAM,aAAa,KAAK;AAAA,UACxB;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,eAAS,QAAQ,CAAC,OAAO,MAAM,SAAS,QAAQ,EAAE,CAAC;AACnD,gBAAU,MAAM;AACd,iBAAS,WAAW;AACpB,kBAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA,EAAE,WAAW,OAAO,OAAO;AAAA,EAC7B,IAAI;AACJ,QAAM,OAAO,MAAM;AACjB,YAAQ;AACR,cAAU;AACV,aAAS,QAAQ;AAAA,EACnB;AACA,oBAAkB,IAAI;AACtB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ;AACN,cAAQ;AACR,eAAS,QAAQ;AAAA,IACnB;AAAA,IACA,SAAS;AACP,eAAS,QAAQ;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,SAAS,UAAU,CAAC,GAAG;AACnD,QAAM;AAAA,IACJ,QAAAA,UAAS;AAAA,IACT;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA,OAAO;AAAA,EACT,IAAI;AACJ,QAAM,mBAAmB,WAAW,KAAK;AACzC,QAAM,EAAE,KAAK,IAAI;AAAA,IACf;AAAA,IACA,CAAC,gCAAgC;AAC/B,UAAI,iBAAiB,iBAAiB;AACtC,UAAI,aAAa;AACjB,iBAAW,SAAS,6BAA6B;AAC/C,YAAI,MAAM,QAAQ,YAAY;AAC5B,uBAAa,MAAM;AACnB,2BAAiB,MAAM;AAAA,QACzB;AAAA,MACF;AACA,uBAAiB,QAAQ;AACzB,UAAI,MAAM;AACR,kBAAU,kBAAkB,MAAM;AAChC,eAAK;AAAA,QACP,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,QAAAA;AAAA,MACA;AAAA,MACA,YAAY,QAAQ,UAAU;AAAA,IAChC;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,SAAyB,oBAAI,IAAI;AAEvC,SAAS,YAAY,KAAK;AACxB,QAAM,QAAQ,gBAAgB;AAC9B,WAAS,GAAG,UAAU;AACpB,QAAI;AACJ,UAAM,YAAY,OAAO,IAAI,GAAG,KAAqB,oBAAI,IAAI;AAC7D,cAAU,IAAI,QAAQ;AACtB,WAAO,IAAI,KAAK,SAAS;AACzB,UAAM,OAAO,MAAM,IAAI,QAAQ;AAC/B,KAAC,KAAK,SAAS,OAAO,SAAS,MAAM,aAAa,OAAO,SAAS,GAAG,KAAK,IAAI;AAC9E,WAAO;AAAA,EACT;AACA,WAAS,KAAK,UAAU;AACtB,aAAS,aAAa,MAAM;AAC1B,UAAI,SAAS;AACb,eAAS,GAAG,IAAI;AAAA,IAClB;AACA,WAAO,GAAG,SAAS;AAAA,EACrB;AACA,WAAS,IAAI,UAAU;AACrB,UAAM,YAAY,OAAO,IAAI,GAAG;AAChC,QAAI,CAAC;AACH;AACF,cAAU,OAAO,QAAQ;AACzB,QAAI,CAAC,UAAU;AACb,YAAM;AAAA,EACV;AACA,WAAS,QAAQ;AACf,WAAO,OAAO,GAAG;AAAA,EACnB;AACA,WAAS,KAAK,OAAO,SAAS;AAC5B,QAAI;AACJ,KAAC,KAAK,OAAO,IAAI,GAAG,MAAM,OAAO,SAAS,GAAG,QAAQ,CAAC,MAAM,EAAE,OAAO,OAAO,CAAC;AAAA,EAC/E;AACA,SAAO,EAAE,IAAI,MAAM,KAAK,MAAM,MAAM;AACtC;AAEA,SAAS,uBAAuB,SAAS;AACvC,MAAI,YAAY;AACd,WAAO,CAAC;AACV,SAAO;AACT;AACA,SAAS,eAAe,KAAKI,UAAS,CAAC,GAAG,UAAU,CAAC,GAAG;AACtD,QAAM,QAAQ,WAAW,IAAI;AAC7B,QAAM,OAAO,WAAW,IAAI;AAC5B,QAAM,SAAS,WAAW,YAAY;AACtC,QAAM,cAAc,IAAI,IAAI;AAC5B,QAAM,QAAQ,WAAW,IAAI;AAC7B,QAAM,SAASI,OAAM,GAAG;AACxB,QAAM,cAAc,WAAW,IAAI;AACnC,MAAI,mBAAmB;AACvB,MAAI,UAAU;AACd,QAAM;AAAA,IACJ,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,cAAc;AAAA,IACd;AAAA,EACF,IAAI;AACJ,QAAM,QAAQ,MAAM;AAClB,QAAI,YAAY,YAAY,OAAO;AACjC,kBAAY,MAAM,MAAM;AACxB,kBAAY,QAAQ;AACpB,aAAO,QAAQ;AACf,yBAAmB;AAAA,IACrB;AAAA,EACF;AACA,QAAM,QAAQ,MAAM;AAClB,QAAI,oBAAoB,OAAO,OAAO,UAAU;AAC9C;AACF,UAAM,KAAK,IAAI,YAAY,OAAO,OAAO,EAAE,gBAAgB,CAAC;AAC5D,WAAO,QAAQ;AACf,gBAAY,QAAQ;AACpB,OAAG,SAAS,MAAM;AAChB,aAAO,QAAQ;AACf,YAAM,QAAQ;AAAA,IAChB;AACA,OAAG,UAAU,CAAC,MAAM;AAClB,aAAO,QAAQ;AACf,YAAM,QAAQ;AACd,UAAI,GAAG,eAAe,KAAK,CAAC,oBAAoB,eAAe;AAC7D,WAAG,MAAM;AACT,cAAM;AAAA,UACJ,UAAU;AAAA,UACV,QAAQ;AAAA,UACR;AAAA,QACF,IAAI,uBAAuB,aAAa;AACxC,mBAAW;AACX,YAAI,OAAO,YAAY,aAAa,UAAU,KAAK,UAAU;AAC3D,qBAAW,OAAO,KAAK;AAAA,iBAChB,OAAO,YAAY,cAAc,QAAQ;AAChD,qBAAW,OAAO,KAAK;AAAA;AAEvB,sBAAY,OAAO,SAAS,SAAS;AAAA,MACzC;AAAA,IACF;AACA,OAAG,YAAY,CAAC,MAAM;AACpB,YAAM,QAAQ;AACd,WAAK,QAAQ,EAAE;AACf,kBAAY,QAAQ,EAAE;AAAA,IACxB;AACA,eAAW,cAAcJ,SAAQ;AAC/B,uBAAiB,IAAI,YAAY,CAAC,MAAM;AACtC,cAAM,QAAQ;AACd,aAAK,QAAQ,EAAE,QAAQ;AAAA,MACzB,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,IACtB;AAAA,EACF;AACA,QAAM,OAAO,MAAM;AACjB,QAAI,CAAC;AACH;AACF,UAAM;AACN,uBAAmB;AACnB,cAAU;AACV,UAAM;AAAA,EACR;AACA,MAAI;AACF,SAAK;AACP,MAAI;AACF,UAAM,QAAQ,IAAI;AACpB,oBAAkB,KAAK;AACvB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,cAAc,UAAU,CAAC,GAAG;AACnC,QAAM,EAAE,eAAe,GAAG,IAAI;AAC9B,QAAM,cAAc,aAAa,MAAM,OAAO,WAAW,eAAe,gBAAgB,MAAM;AAC9F,QAAM,UAAU,WAAW,YAAY;AACvC,iBAAe,KAAK,aAAa;AAC/B,QAAI,CAAC,YAAY;AACf;AACF,UAAM,aAAa,IAAI,OAAO,WAAW;AACzC,UAAM,SAAS,MAAM,WAAW,KAAK,WAAW;AAChD,YAAQ,QAAQ,OAAO;AACvB,WAAO;AAAA,EACT;AACA,SAAO,EAAE,aAAa,SAAS,KAAK;AACtC;AAEA,SAAS,WAAW,UAAU,MAAM,UAAU,CAAC,GAAG;AAChD,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAAH,YAAW;AAAA,EACb,IAAI;AACJ,QAAM,UAAUO,OAAM,OAAO;AAC7B,QAAM,YAAY,CAAC,SAAS;AAC1B,UAAM,WAAWP,aAAY,OAAO,SAASA,UAAS,KAAK,iBAAiB,cAAc,GAAG,IAAI;AACjG,QAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC,YAAM,OAAOA,aAAY,OAAO,SAASA,UAAS,cAAc,MAAM;AACtE,UAAI,MAAM;AACR,aAAK,MAAM;AACX,aAAK,OAAO,GAAG,OAAO,GAAG,IAAI;AAC7B,aAAK,OAAO,SAAS,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC;AAC1C,QAAAA,aAAY,OAAO,SAASA,UAAS,KAAK,OAAO,IAAI;AAAA,MACvD;AACA;AAAA,IACF;AACA,gBAAY,OAAO,SAAS,SAAS,QAAQ,CAAC,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,EAAE;AAAA,EACpF;AACA;AAAA,IACE;AAAA,IACA,CAAC,GAAG,MAAM;AACR,UAAI,OAAO,MAAM,YAAY,MAAM;AACjC,kBAAU,CAAC;AAAA,IACf;AAAA,IACA,EAAE,WAAW,KAAK;AAAA,EACpB;AACA,SAAO;AACT;AAEA,IAAM,iBAAiB;AAAA,EACrB,MAAM;AAAA,EACN,MAAM;AACR;AACA,SAAS,eAAe,KAAK;AAC3B,SAAO,OAAO,aAAa,KAAK,aAAa,WAAW,eAAe,WAAW,eAAe,cAAc,gBAAgB,SAAS,mBAAmB;AAC7J;AACA,IAAM,aAAa;AACnB,SAAS,cAAc,KAAK;AAC1B,SAAO,WAAW,KAAK,GAAG;AAC5B;AACA,SAAS,gBAAgB,SAAS;AAChC,MAAI,OAAO,YAAY,eAAe,mBAAmB;AACvD,WAAO,OAAO,YAAY,QAAQ,QAAQ,CAAC;AAC7C,SAAO;AACT;AACA,SAAS,iBAAiB,gBAAgB,WAAW;AACnD,MAAI,gBAAgB,aAAa;AAC/B,WAAO,OAAO,QAAQ;AACpB,UAAI;AACJ,eAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAI,UAAU,CAAC,KAAK,MAAM;AACxB,qBAAW,UAAU,CAAC;AACtB;AAAA,QACF;AAAA,MACF;AACA,UAAI;AACF,eAAO,EAAE,GAAG,KAAK,GAAG,MAAM,SAAS,GAAG,EAAE;AAC1C,aAAO;AAAA,IACT;AAAA,EACF,OAAO;AACL,WAAO,OAAO,QAAQ;AACpB,iBAAW,YAAY,WAAW;AAChC,YAAI;AACF,gBAAM,EAAE,GAAG,KAAK,GAAG,MAAM,SAAS,GAAG,EAAE;AAAA,MAC3C;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AACA,SAAS,YAAY,SAAS,CAAC,GAAG;AAChC,QAAM,eAAe,OAAO,eAAe;AAC3C,QAAM,WAAW,OAAO,WAAW,CAAC;AACpC,QAAM,gBAAgB,OAAO,gBAAgB,CAAC;AAC9C,WAAS,gBAAgB,QAAQ,MAAM;AACrC,UAAM,cAAc,SAAS,MAAM;AACjC,YAAM,UAAU,QAAQ,OAAO,OAAO;AACtC,YAAM,YAAY,QAAQ,GAAG;AAC7B,aAAO,WAAW,CAAC,cAAc,SAAS,IAAI,UAAU,SAAS,SAAS,IAAI;AAAA,IAChF,CAAC;AACD,QAAI,UAAU;AACd,QAAI,eAAe;AACnB,QAAI,KAAK,SAAS,GAAG;AACnB,UAAI,eAAe,KAAK,CAAC,CAAC,GAAG;AAC3B,kBAAU;AAAA,UACR,GAAG;AAAA,UACH,GAAG,KAAK,CAAC;AAAA,UACT,aAAa,iBAAiB,cAAc,SAAS,aAAa,KAAK,CAAC,EAAE,WAAW;AAAA,UACrF,YAAY,iBAAiB,cAAc,SAAS,YAAY,KAAK,CAAC,EAAE,UAAU;AAAA,UAClF,cAAc,iBAAiB,cAAc,SAAS,cAAc,KAAK,CAAC,EAAE,YAAY;AAAA,QAC1F;AAAA,MACF,OAAO;AACL,uBAAe;AAAA,UACb,GAAG;AAAA,UACH,GAAG,KAAK,CAAC;AAAA,UACT,SAAS;AAAA,YACP,GAAG,gBAAgB,aAAa,OAAO,KAAK,CAAC;AAAA,YAC7C,GAAG,gBAAgB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;AAAA,UAC1C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,KAAK,SAAS,KAAK,eAAe,KAAK,CAAC,CAAC,GAAG;AAC9C,gBAAU;AAAA,QACR,GAAG;AAAA,QACH,GAAG,KAAK,CAAC;AAAA,QACT,aAAa,iBAAiB,cAAc,SAAS,aAAa,KAAK,CAAC,EAAE,WAAW;AAAA,QACrF,YAAY,iBAAiB,cAAc,SAAS,YAAY,KAAK,CAAC,EAAE,UAAU;AAAA,QAClF,cAAc,iBAAiB,cAAc,SAAS,cAAc,KAAK,CAAC,EAAE,YAAY;AAAA,MAC1F;AAAA,IACF;AACA,WAAO,SAAS,aAAa,cAAc,OAAO;AAAA,EACpD;AACA,SAAO;AACT;AACA,SAAS,SAAS,QAAQ,MAAM;AAC9B,MAAI;AACJ,QAAM,gBAAgB,OAAO,oBAAoB;AACjD,MAAI,eAAe,CAAC;AACpB,MAAI,UAAU;AAAA,IACZ,WAAW;AAAA,IACX,SAAS;AAAA,IACT,SAAS;AAAA,IACT,mBAAmB;AAAA,EACrB;AACA,QAAM,SAAS;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AACA,MAAI,KAAK,SAAS,GAAG;AACnB,QAAI,eAAe,KAAK,CAAC,CAAC;AACxB,gBAAU,EAAE,GAAG,SAAS,GAAG,KAAK,CAAC,EAAE;AAAA;AAEnC,qBAAe,KAAK,CAAC;AAAA,EACzB;AACA,MAAI,KAAK,SAAS,GAAG;AACnB,QAAI,eAAe,KAAK,CAAC,CAAC;AACxB,gBAAU,EAAE,GAAG,SAAS,GAAG,KAAK,CAAC,EAAE;AAAA,EACvC;AACA,QAAM;AAAA,IACJ,SAAS,KAAK,kBAAkB,OAAO,SAAS,GAAG;AAAA,IACnD;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,gBAAgB,gBAAgB;AACtC,QAAM,aAAa,gBAAgB;AACnC,QAAM,eAAe,gBAAgB;AACrC,QAAM,aAAa,WAAW,KAAK;AACnC,QAAM,aAAa,WAAW,KAAK;AACnC,QAAM,UAAU,WAAW,KAAK;AAChC,QAAM,aAAa,WAAW,IAAI;AAClC,QAAM,WAAW,WAAW,IAAI;AAChC,QAAM,QAAQ,WAAW,IAAI;AAC7B,QAAM,OAAO,WAAW,eAAe,IAAI;AAC3C,QAAM,WAAW,SAAS,MAAM,iBAAiB,WAAW,KAAK;AACjE,MAAI;AACJ,MAAI;AACJ,QAAM,QAAQ,MAAM;AAClB,QAAI,eAAe;AACjB,oBAAc,OAAO,SAAS,WAAW,MAAM;AAC/C,mBAAa,IAAI,gBAAgB;AACjC,iBAAW,OAAO,UAAU,MAAM,QAAQ,QAAQ;AAClD,qBAAe;AAAA,QACb,GAAG;AAAA,QACH,QAAQ,WAAW;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACA,QAAM,UAAU,CAAC,cAAc;AAC7B,eAAW,QAAQ;AACnB,eAAW,QAAQ,CAAC;AAAA,EACtB;AACA,MAAI;AACF,YAAQ,aAAa,OAAO,SAAS,EAAE,WAAW,MAAM,CAAC;AAC3D,MAAI,iBAAiB;AACrB,QAAM,UAAU,OAAO,gBAAgB,UAAU;AAC/C,QAAI,KAAK;AACT,UAAM;AACN,YAAQ,IAAI;AACZ,UAAM,QAAQ;AACd,eAAW,QAAQ;AACnB,YAAQ,QAAQ;AAChB,sBAAkB;AAClB,UAAM,wBAAwB;AAC9B,UAAM,sBAAsB;AAAA,MAC1B,QAAQ,OAAO;AAAA,MACf,SAAS,CAAC;AAAA,IACZ;AACA,UAAM,UAAU,QAAQ,OAAO,OAAO;AACtC,QAAI,SAAS;AACX,YAAM,UAAU,gBAAgB,oBAAoB,OAAO;AAC3D,YAAM,QAAQ,OAAO,eAAe,OAAO;AAC3C,UAAI,CAAC,OAAO,eAAe,YAAY,UAAU,OAAO,aAAa,MAAM,QAAQ,KAAK,MAAM,EAAE,mBAAmB;AACjH,eAAO,cAAc;AACvB,UAAI,OAAO;AACT,gBAAQ,cAAc,KAAK,MAAM,eAAe,OAAO,WAAW,MAAM,OAAO,MAAM,OAAO;AAC9F,0BAAoB,OAAO,OAAO,gBAAgB,SAAS,KAAK,UAAU,OAAO,IAAI;AAAA,IACvF;AACA,QAAI,aAAa;AACjB,UAAM,UAAU;AAAA,MACd,KAAK,QAAQ,GAAG;AAAA,MAChB,SAAS;AAAA,QACP,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,MACA,QAAQ,MAAM;AACZ,qBAAa;AAAA,MACf;AAAA,IACF;AACA,QAAI,QAAQ;AACV,aAAO,OAAO,SAAS,MAAM,QAAQ,YAAY,OAAO,CAAC;AAC3D,QAAI,cAAc,CAAC,OAAO;AACxB,cAAQ,KAAK;AACb,aAAO,QAAQ,QAAQ,IAAI;AAAA,IAC7B;AACA,QAAI,eAAe;AACnB,QAAI;AACF,YAAM,MAAM;AACd,WAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,QACE,GAAG;AAAA,QACH,GAAG,QAAQ;AAAA,QACX,SAAS;AAAA,UACP,GAAG,gBAAgB,oBAAoB,OAAO;AAAA,UAC9C,GAAG,iBAAiB,KAAK,QAAQ,YAAY,OAAO,SAAS,GAAG,OAAO;AAAA,QACzE;AAAA,MACF;AAAA,IACF,EAAE,KAAK,OAAO,kBAAkB;AAC9B,eAAS,QAAQ;AACjB,iBAAW,QAAQ,cAAc;AACjC,qBAAe,MAAM,cAAc,MAAM,EAAE,OAAO,IAAI,EAAE;AACxD,UAAI,CAAC,cAAc,IAAI;AACrB,aAAK,QAAQ,eAAe;AAC5B,cAAM,IAAI,MAAM,cAAc,UAAU;AAAA,MAC1C;AACA,UAAI,QAAQ,YAAY;AACtB,SAAC,EAAE,MAAM,aAAa,IAAI,MAAM,QAAQ,WAAW;AAAA,UACjD,MAAM;AAAA,UACN,UAAU;AAAA,UACV;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AACA,WAAK,QAAQ;AACb,oBAAc,QAAQ,aAAa;AACnC,aAAO;AAAA,IACT,CAAC,EAAE,MAAM,OAAO,eAAe;AAC7B,UAAI,YAAY,WAAW,WAAW,WAAW;AACjD,UAAI,QAAQ,cAAc;AACxB,SAAC,EAAE,OAAO,WAAW,MAAM,aAAa,IAAI,MAAM,QAAQ,aAAa;AAAA,UACrE,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU,SAAS;AAAA,UACnB;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AACA,YAAM,QAAQ;AACd,UAAI,QAAQ;AACV,aAAK,QAAQ;AACf,iBAAW,QAAQ,UAAU;AAC7B,UAAI;AACF,cAAM;AACR,aAAO;AAAA,IACT,CAAC,EAAE,QAAQ,MAAM;AACf,UAAI,0BAA0B;AAC5B,gBAAQ,KAAK;AACf,UAAI;AACF,cAAM,KAAK;AACb,mBAAa,QAAQ,IAAI;AAAA,IAC3B,CAAC;AAAA,EACH;AACA,QAAM,UAAUO,OAAM,QAAQ,OAAO;AACrC;AAAA,IACE;AAAA,MACE;AAAA,MACAA,OAAM,GAAG;AAAA,IACX;AAAA,IACA,CAAC,CAAC,QAAQ,MAAM,YAAY,QAAQ;AAAA,IACpC,EAAE,MAAM,KAAK;AAAA,EACf;AACA,QAAM,QAAQ;AAAA,IACZ,YAAY,SAAS,UAAU;AAAA,IAC/B,YAAY,SAAS,UAAU;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB,cAAc;AAAA,IAC/B,cAAc,WAAW;AAAA,IACzB,gBAAgB,aAAa;AAAA;AAAA,IAE7B,KAAK,UAAU,KAAK;AAAA,IACpB,KAAK,UAAU,KAAK;AAAA,IACpB,MAAM,UAAU,MAAM;AAAA,IACtB,QAAQ,UAAU,QAAQ;AAAA,IAC1B,OAAO,UAAU,OAAO;AAAA,IACxB,MAAM,UAAU,MAAM;AAAA,IACtB,SAAS,UAAU,SAAS;AAAA;AAAA,IAE5B,MAAM,QAAQ,MAAM;AAAA,IACpB,MAAM,QAAQ,MAAM;AAAA,IACpB,MAAM,QAAQ,MAAM;AAAA,IACpB,aAAa,QAAQ,aAAa;AAAA,IAClC,UAAU,QAAQ,UAAU;AAAA,EAC9B;AACA,WAAS,UAAU,QAAQ;AACzB,WAAO,CAAC,SAAS,gBAAgB;AAC/B,UAAI,CAAC,WAAW,OAAO;AACrB,eAAO,SAAS;AAChB,eAAO,UAAU;AACjB,eAAO,cAAc;AACrB,YAAI,MAAM,OAAO,OAAO,GAAG;AACzB;AAAA,YACE;AAAA,cACE;AAAA,cACAA,OAAM,OAAO,OAAO;AAAA,YACtB;AAAA,YACA,CAAC,CAAC,QAAQ,MAAM,YAAY,QAAQ;AAAA,YACpC,EAAE,MAAM,KAAK;AAAA,UACf;AAAA,QACF;AACA,eAAO;AAAA,UACL,GAAG;AAAA,UACH,KAAK,aAAa,YAAY;AAC5B,mBAAO,kBAAkB,EAAE,KAAK,aAAa,UAAU;AAAA,UACzD;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,WAAS,oBAAoB;AAC3B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,UAAU,EAAE,KAAK,IAAI,EAAE,KAAK,MAAM,QAAQ,KAAK,CAAC,EAAE,MAAM,MAAM;AAAA,IACtE,CAAC;AAAA,EACH;AACA,WAAS,QAAQ,MAAM;AACrB,WAAO,MAAM;AACX,UAAI,CAAC,WAAW,OAAO;AACrB,eAAO,OAAO;AACd,eAAO;AAAA,UACL,GAAG;AAAA,UACH,KAAK,aAAa,YAAY;AAC5B,mBAAO,kBAAkB,EAAE,KAAK,aAAa,UAAU;AAAA,UACzD;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,MAAI,QAAQ;AACV,YAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,CAAC;AACxC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,KAAK,aAAa,YAAY;AAC5B,aAAO,kBAAkB,EAAE,KAAK,aAAa,UAAU;AAAA,IACzD;AAAA,EACF;AACF;AACA,SAAS,UAAU,OAAO,KAAK;AAC7B,MAAI,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,WAAW,GAAG,GAAG;AAChD,WAAO,GAAG,KAAK,IAAI,GAAG;AAAA,EACxB;AACA,MAAI,MAAM,SAAS,GAAG,KAAK,IAAI,WAAW,GAAG,GAAG;AAC9C,WAAO,GAAG,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,GAAG;AAAA,EACpC;AACA,SAAO,GAAG,KAAK,GAAG,GAAG;AACvB;AAEA,IAAM,kBAAkB;AAAA,EACtB,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,WAAW;AACb;AACA,SAAS,oBAAoB,OAAO;AAClC,MAAI,CAAC;AACH,WAAO;AACT,MAAI,iBAAiB;AACnB,WAAO;AACT,QAAM,KAAK,IAAI,aAAa;AAC5B,aAAW,QAAQ,OAAO;AACxB,OAAG,MAAM,IAAI,IAAI;AAAA,EACnB;AACA,SAAO,GAAG;AACZ;AACA,SAAS,cAAc,UAAU,CAAC,GAAG;AACnC,QAAM;AAAA,IACJ,UAAAP,YAAW;AAAA,EACb,IAAI;AACJ,QAAM,QAAQ,IAAI,oBAAoB,QAAQ,YAAY,CAAC;AAC3D,QAAM,EAAE,IAAI,UAAU,SAAS,cAAc,IAAI,gBAAgB;AACjE,QAAM,EAAE,IAAI,UAAU,SAAS,cAAc,IAAI,gBAAgB;AACjE,MAAI;AACJ,MAAIA,WAAU;AACZ,YAAQA,UAAS,cAAc,OAAO;AACtC,UAAM,OAAO;AACb,UAAM,WAAW,CAAC,UAAU;AAC1B,YAAM,SAAS,MAAM;AACrB,YAAM,QAAQ,OAAO;AACrB,oBAAc,MAAM,KAAK;AAAA,IAC3B;AACA,UAAM,WAAW,MAAM;AACrB,oBAAc;AAAA,IAChB;AAAA,EACF;AACA,QAAM,QAAQ,MAAM;AAClB,UAAM,QAAQ;AACd,QAAI,SAAS,MAAM,OAAO;AACxB,YAAM,QAAQ;AACd,oBAAc,IAAI;AAAA,IACpB;AAAA,EACF;AACA,QAAM,OAAO,CAAC,iBAAiB;AAC7B,QAAI,CAAC;AACH;AACF,UAAM,WAAW;AAAA,MACf,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AACA,UAAM,WAAW,SAAS;AAC1B,UAAM,SAAS,SAAS;AACxB,UAAM,kBAAkB,SAAS;AACjC,QAAI,OAAO,UAAU,SAAS;AAC5B,YAAM,UAAU,SAAS;AAC3B,QAAI,SAAS;AACX,YAAM;AACR,UAAM,MAAM;AAAA,EACd;AACA,SAAO;AAAA,IACL,OAAO,SAAS,KAAK;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,oBAAoB,UAAU,CAAC,GAAG;AACzC,QAAM;AAAA,IACJ,QAAQ,UAAU;AAAA,IAClB,WAAW;AAAA,EACb,IAAI;AACJ,QAAMD,UAAS;AACf,QAAM,cAAc,aAAa,MAAMA,WAAU,wBAAwBA,WAAU,wBAAwBA,OAAM;AACjH,QAAM,aAAa,WAAW;AAC9B,QAAM,OAAO,WAAW;AACxB,QAAM,OAAO,WAAW;AACxB,QAAM,WAAW,SAAS,MAAM;AAC9B,QAAI,IAAI;AACR,YAAQ,MAAM,KAAK,KAAK,UAAU,OAAO,SAAS,GAAG,SAAS,OAAO,KAAK;AAAA,EAC5E,CAAC;AACD,QAAM,WAAW,SAAS,MAAM;AAC9B,QAAI,IAAI;AACR,YAAQ,MAAM,KAAK,KAAK,UAAU,OAAO,SAAS,GAAG,SAAS,OAAO,KAAK;AAAA,EAC5E,CAAC;AACD,QAAM,WAAW,SAAS,MAAM;AAC9B,QAAI,IAAI;AACR,YAAQ,MAAM,KAAK,KAAK,UAAU,OAAO,SAAS,GAAG,SAAS,OAAO,KAAK;AAAA,EAC5E,CAAC;AACD,QAAM,mBAAmB,SAAS,MAAM;AACtC,QAAI,IAAI;AACR,YAAQ,MAAM,KAAK,KAAK,UAAU,OAAO,SAAS,GAAG,iBAAiB,OAAO,KAAK;AAAA,EACpF,CAAC;AACD,iBAAe,KAAK,WAAW,CAAC,GAAG;AACjC,QAAI,CAAC,YAAY;AACf;AACF,UAAM,CAAC,MAAM,IAAI,MAAMA,QAAO,mBAAmB,EAAE,GAAG,QAAQ,OAAO,GAAG,GAAG,SAAS,CAAC;AACrF,eAAW,QAAQ;AACnB,UAAM,WAAW;AAAA,EACnB;AACA,iBAAe,OAAO,WAAW,CAAC,GAAG;AACnC,QAAI,CAAC,YAAY;AACf;AACF,eAAW,QAAQ,MAAMA,QAAO,mBAAmB,EAAE,GAAG,SAAS,GAAG,SAAS,CAAC;AAC9E,SAAK,QAAQ;AACb,UAAM,WAAW;AAAA,EACnB;AACA,iBAAe,KAAK,WAAW,CAAC,GAAG;AACjC,QAAI,CAAC,YAAY;AACf;AACF,QAAI,CAAC,WAAW;AACd,aAAO,OAAO,QAAQ;AACxB,QAAI,KAAK,OAAO;AACd,YAAM,iBAAiB,MAAM,WAAW,MAAM,eAAe;AAC7D,YAAM,eAAe,MAAM,KAAK,KAAK;AACrC,YAAM,eAAe,MAAM;AAAA,IAC7B;AACA,UAAM,WAAW;AAAA,EACnB;AACA,iBAAe,OAAO,WAAW,CAAC,GAAG;AACnC,QAAI,CAAC,YAAY;AACf;AACF,eAAW,QAAQ,MAAMA,QAAO,mBAAmB,EAAE,GAAG,SAAS,GAAG,SAAS,CAAC;AAC9E,QAAI,KAAK,OAAO;AACd,YAAM,iBAAiB,MAAM,WAAW,MAAM,eAAe;AAC7D,YAAM,eAAe,MAAM,KAAK,KAAK;AACrC,YAAM,eAAe,MAAM;AAAA,IAC7B;AACA,UAAM,WAAW;AAAA,EACnB;AACA,iBAAe,aAAa;AAC1B,QAAI;AACJ,SAAK,QAAQ,QAAQ,KAAK,WAAW,UAAU,OAAO,SAAS,GAAG,QAAQ;AAAA,EAC5E;AACA,iBAAe,aAAa;AAC1B,QAAI,IAAI;AACR,UAAM,WAAW;AACjB,UAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAI,SAAS;AACX,WAAK,QAAQ,QAAQ,KAAK,KAAK,UAAU,OAAO,SAAS,GAAG,KAAK;AAAA,aAC1D,SAAS;AAChB,WAAK,QAAQ,QAAQ,KAAK,KAAK,UAAU,OAAO,SAAS,GAAG,YAAY;AAAA,aACjE,SAAS;AAChB,WAAK,QAAQ,KAAK;AAAA,EACtB;AACA,QAAM,MAAM,QAAQ,QAAQ,GAAG,UAAU;AACzC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,SAAS,QAAQ,UAAU,CAAC,GAAG;AACtC,QAAM,EAAE,eAAe,OAAO,eAAe,OAAO,gBAAgB,MAAM,IAAI;AAC9E,QAAM,eAAe,WAAW,KAAK;AACrC,QAAM,gBAAgB,SAAS,MAAM,aAAa,MAAM,CAAC;AACzD,QAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,mBAAiB,eAAe,SAAS,CAAC,UAAU;AAClD,QAAI,IAAI;AACR,QAAI,CAAC,kBAAkB,MAAM,KAAK,MAAM,QAAQ,YAAY,OAAO,SAAS,GAAG,KAAK,IAAI,gBAAgB;AACtG,mBAAa,QAAQ;AAAA,EACzB,GAAG,eAAe;AAClB,mBAAiB,eAAe,QAAQ,MAAM,aAAa,QAAQ,OAAO,eAAe;AACzF,QAAM,UAAU,SAAS;AAAA,IACvB,KAAK,MAAM,aAAa;AAAA,IACxB,IAAI,OAAO;AACT,UAAI,IAAI;AACR,UAAI,CAAC,SAAS,aAAa;AACzB,SAAC,KAAK,cAAc,UAAU,OAAO,SAAS,GAAG,KAAK;AAAA,eAC/C,SAAS,CAAC,aAAa;AAC9B,SAAC,KAAK,cAAc,UAAU,OAAO,SAAS,GAAG,MAAM,EAAE,cAAc,CAAC;AAAA,IAC5E;AAAA,EACF,CAAC;AACD;AAAA,IACE;AAAA,IACA,MAAM;AACJ,cAAQ,QAAQ;AAAA,IAClB;AAAA,IACA,EAAE,WAAW,MAAM,OAAO,OAAO;AAAA,EACnC;AACA,SAAO,EAAE,QAAQ;AACnB;AAEA,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AACxB,IAAM,4BAA4B;AAClC,SAAS,eAAe,QAAQ,UAAU,CAAC,GAAG;AAC5C,QAAM,EAAE,QAAAA,UAAS,cAAc,IAAI;AACnC,QAAM,gBAAgB,SAAS,MAAM,aAAa,MAAM,CAAC;AACzD,QAAM,WAAW,WAAW,KAAK;AACjC,QAAM,UAAU,SAAS,MAAM,SAAS,KAAK;AAC7C,QAAM,gBAAgB,iBAAiB,OAAO;AAC9C,MAAI,CAACA,WAAU,CAAC,cAAc,OAAO;AACnC,WAAO,EAAE,QAAQ;AAAA,EACnB;AACA,QAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,mBAAiB,eAAe,gBAAgB,MAAM,SAAS,QAAQ,MAAM,eAAe;AAC5F,mBAAiB,eAAe,iBAAiB,MAAM;AACrD,QAAI,IAAI,IAAI;AACZ,WAAO,SAAS,SAAS,MAAM,MAAM,KAAK,cAAc,UAAU,OAAO,SAAS,GAAG,YAAY,OAAO,SAAS,GAAG,KAAK,IAAI,yBAAyB,MAAM,OAAO,KAAK;AAAA,EAC1K,GAAG,eAAe;AAClB,SAAO,EAAE,QAAQ;AACnB;AAEA,SAAS,OAAO,SAAS;AACvB,MAAI;AACJ,QAAM,MAAM,WAAW,CAAC;AACxB,MAAI,OAAO,gBAAgB;AACzB,WAAO;AACT,QAAM,SAAS,KAAK,WAAW,OAAO,SAAS,QAAQ,UAAU,OAAO,KAAK;AAC7E,MAAI,OAAO,YAAY,IAAI;AAC3B,MAAI,QAAQ;AACZ,WAAS,MAAM;AACb,aAAS;AACT,QAAI,SAAS,OAAO;AAClB,YAAMa,OAAM,YAAY,IAAI;AAC5B,YAAM,OAAOA,OAAM;AACnB,UAAI,QAAQ,KAAK,MAAM,OAAO,OAAO,MAAM;AAC3C,aAAOA;AACP,cAAQ;AAAA,IACV;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAEA,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,SAAS,cAAc,QAAQ,UAAU,CAAC,GAAG;AAC3C,QAAM;AAAA,IACJ,UAAAZ,YAAW;AAAA,IACX,WAAW;AAAA,EACb,IAAI;AACJ,QAAM,YAAY,SAAS,MAAM;AAC/B,QAAI;AACJ,YAAQ,KAAK,aAAa,MAAM,MAAM,OAAO,KAAKA,aAAY,OAAO,SAASA,UAAS;AAAA,EACzF,CAAC;AACD,QAAM,eAAe,WAAW,KAAK;AACrC,QAAM,gBAAgB,SAAS,MAAM;AACnC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,CAAC,MAAMA,aAAY,KAAKA,aAAY,UAAU,SAAS,KAAK,UAAU,KAAK;AAAA,EACpF,CAAC;AACD,QAAM,aAAa,SAAS,MAAM;AAChC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,CAAC,MAAMA,aAAY,KAAKA,aAAY,UAAU,SAAS,KAAK,UAAU,KAAK;AAAA,EACpF,CAAC;AACD,QAAM,oBAAoB,SAAS,MAAM;AACvC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,CAAC,MAAMA,aAAY,KAAKA,aAAY,UAAU,SAAS,KAAK,UAAU,KAAK;AAAA,EACpF,CAAC;AACD,QAAM,0BAA0B;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,CAAC,MAAMA,aAAY,KAAKA,SAAQ;AACvC,QAAM,cAAc,aAAa,MAAM,UAAU,SAASA,aAAY,cAAc,UAAU,UAAU,WAAW,UAAU,UAAU,kBAAkB,UAAU,MAAM;AACzK,QAAM,6BAA6B,MAAM;AACvC,QAAI;AACF,cAAQA,aAAY,OAAO,SAASA,UAAS,uBAAuB,OAAO,UAAU;AACvF,WAAO;AAAA,EACT;AACA,QAAM,sBAAsB,MAAM;AAChC,QAAI,kBAAkB,OAAO;AAC3B,UAAIA,aAAYA,UAAS,kBAAkB,KAAK,KAAK,MAAM;AACzD,eAAOA,UAAS,kBAAkB,KAAK;AAAA,MACzC,OAAO;AACL,cAAM,UAAU,UAAU;AAC1B,aAAK,WAAW,OAAO,SAAS,QAAQ,kBAAkB,KAAK,MAAM,MAAM;AACzE,iBAAO,QAAQ,QAAQ,kBAAkB,KAAK,CAAC;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,iBAAe,OAAO;AACpB,QAAI,CAAC,YAAY,SAAS,CAAC,aAAa;AACtC;AACF,QAAI,WAAW,OAAO;AACpB,WAAKA,aAAY,OAAO,SAASA,UAAS,WAAW,KAAK,MAAM,MAAM;AACpE,cAAMA,UAAS,WAAW,KAAK,EAAE;AAAA,MACnC,OAAO;AACL,cAAM,UAAU,UAAU;AAC1B,aAAK,WAAW,OAAO,SAAS,QAAQ,WAAW,KAAK,MAAM;AAC5D,gBAAM,QAAQ,WAAW,KAAK,EAAE;AAAA,MACpC;AAAA,IACF;AACA,iBAAa,QAAQ;AAAA,EACvB;AACA,iBAAe,QAAQ;AACrB,QAAI,CAAC,YAAY,SAAS,aAAa;AACrC;AACF,QAAI,oBAAoB;AACtB,YAAM,KAAK;AACb,UAAM,UAAU,UAAU;AAC1B,QAAI,cAAc,UAAU,WAAW,OAAO,SAAS,QAAQ,cAAc,KAAK,MAAM,MAAM;AAC5F,YAAM,QAAQ,cAAc,KAAK,EAAE;AACnC,mBAAa,QAAQ;AAAA,IACvB;AAAA,EACF;AACA,iBAAe,SAAS;AACtB,WAAO,aAAa,QAAQ,KAAK,IAAI,MAAM;AAAA,EAC7C;AACA,QAAM,kBAAkB,MAAM;AAC5B,UAAM,2BAA2B,oBAAoB;AACrD,QAAI,CAAC,4BAA4B,4BAA4B,2BAA2B;AACtF,mBAAa,QAAQ;AAAA,EACzB;AACA,QAAM,kBAAkB,EAAE,SAAS,OAAO,SAAS,KAAK;AACxD,mBAAiBA,WAAU,eAAe,iBAAiB,eAAe;AAC1E,mBAAiB,MAAM,aAAa,SAAS,GAAG,eAAe,iBAAiB,eAAe;AAC/F,MAAI;AACF,sBAAkB,IAAI;AACxB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,8BAA8B,SAAS;AAC9C,SAAO,SAAS,MAAM;AACpB,QAAI,QAAQ,OAAO;AACjB,aAAO;AAAA,QACL,SAAS;AAAA,UACP,GAAG,QAAQ,MAAM,QAAQ,CAAC;AAAA,UAC1B,GAAG,QAAQ,MAAM,QAAQ,CAAC;AAAA,UAC1B,GAAG,QAAQ,MAAM,QAAQ,CAAC;AAAA,UAC1B,GAAG,QAAQ,MAAM,QAAQ,CAAC;AAAA,QAC5B;AAAA,QACA,QAAQ;AAAA,UACN,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,UAC7B,OAAO,QAAQ,MAAM,QAAQ,CAAC;AAAA,QAChC;AAAA,QACA,UAAU;AAAA,UACR,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,UAC7B,OAAO,QAAQ,MAAM,QAAQ,CAAC;AAAA,QAChC;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,YACJ,YAAY,QAAQ,MAAM,KAAK,CAAC;AAAA,YAChC,UAAU,QAAQ,MAAM,KAAK,CAAC;AAAA,YAC9B,QAAQ,QAAQ,MAAM,QAAQ,EAAE;AAAA,UAClC;AAAA,UACA,OAAO;AAAA,YACL,YAAY,QAAQ,MAAM,KAAK,CAAC;AAAA,YAChC,UAAU,QAAQ,MAAM,KAAK,CAAC;AAAA,YAC9B,QAAQ,QAAQ,MAAM,QAAQ,EAAE;AAAA,UAClC;AAAA,QACF;AAAA,QACA,MAAM;AAAA,UACJ,IAAI,QAAQ,MAAM,QAAQ,EAAE;AAAA,UAC5B,MAAM,QAAQ,MAAM,QAAQ,EAAE;AAAA,UAC9B,MAAM,QAAQ,MAAM,QAAQ,EAAE;AAAA,UAC9B,OAAO,QAAQ,MAAM,QAAQ,EAAE;AAAA,QACjC;AAAA,QACA,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,QAC7B,OAAO,QAAQ,MAAM,QAAQ,CAAC;AAAA,MAChC;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AACA,SAAS,WAAW,UAAU,CAAC,GAAG;AAChC,QAAM;AAAA,IACJ,WAAAE,aAAY;AAAA,EACd,IAAI;AACJ,QAAM,cAAc,aAAa,MAAMA,cAAa,iBAAiBA,UAAS;AAC9E,QAAM,WAAW,IAAI,CAAC,CAAC;AACvB,QAAM,kBAAkB,gBAAgB;AACxC,QAAM,qBAAqB,gBAAgB;AAC3C,QAAM,mBAAmB,CAAC,YAAY;AACpC,UAAM,kBAAkB,CAAC;AACzB,UAAM,oBAAoB,uBAAuB,UAAU,QAAQ,oBAAoB;AACvF,QAAI;AACF,sBAAgB,KAAK,iBAAiB;AACxC,QAAI,QAAQ;AACV,sBAAgB,KAAK,GAAG,QAAQ,eAAe;AACjD,WAAO;AAAA,MACL,IAAI,QAAQ;AAAA,MACZ,OAAO,QAAQ;AAAA,MACf,WAAW,QAAQ;AAAA,MACnB,SAAS,QAAQ;AAAA,MACjB,WAAW,QAAQ;AAAA,MACnB,mBAAmB,QAAQ;AAAA,MAC3B;AAAA,MACA,MAAM,QAAQ,KAAK,IAAI,CAAC,SAAS,IAAI;AAAA,MACrC,SAAS,QAAQ,QAAQ,IAAI,CAAC,YAAY,EAAE,SAAS,OAAO,SAAS,SAAS,OAAO,SAAS,OAAO,OAAO,MAAM,EAAE;AAAA,IACtH;AAAA,EACF;AACA,QAAM,qBAAqB,MAAM;AAC/B,UAAM,aAAaA,cAAa,OAAO,SAASA,WAAU,YAAY,MAAM,CAAC;AAC7E,eAAW,WAAW,WAAW;AAC/B,UAAI,WAAW,SAAS,MAAM,QAAQ,KAAK;AACzC,iBAAS,MAAM,QAAQ,KAAK,IAAI,iBAAiB,OAAO;AAAA,IAC5D;AAAA,EACF;AACA,QAAM,EAAE,UAAU,OAAO,OAAO,IAAI,SAAS,kBAAkB;AAC/D,QAAM,qBAAqB,CAAC,YAAY;AACtC,QAAI,CAAC,SAAS,MAAM,KAAK,CAAC,EAAE,MAAM,MAAM,UAAU,QAAQ,KAAK,GAAG;AAChE,eAAS,MAAM,KAAK,iBAAiB,OAAO,CAAC;AAC7C,sBAAgB,QAAQ,QAAQ,KAAK;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AACA,QAAM,wBAAwB,CAAC,YAAY;AACzC,aAAS,QAAQ,SAAS,MAAM,OAAO,CAAC,MAAM,EAAE,UAAU,QAAQ,KAAK;AACvE,uBAAmB,QAAQ,QAAQ,KAAK;AAAA,EAC1C;AACA,QAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,mBAAiB,oBAAoB,CAAC,MAAM,mBAAmB,EAAE,OAAO,GAAG,eAAe;AAC1F,mBAAiB,uBAAuB,CAAC,MAAM,sBAAsB,EAAE,OAAO,GAAG,eAAe;AAChG,eAAa,MAAM;AACjB,UAAM,aAAaA,cAAa,OAAO,SAASA,WAAU,YAAY,MAAM,CAAC;AAC7E,eAAW,WAAW,WAAW;AAC/B,UAAI,WAAW,SAAS,MAAM,QAAQ,KAAK;AACzC,2BAAmB,OAAO;AAAA,IAC9B;AAAA,EACF,CAAC;AACD,QAAM;AACN,SAAO;AAAA,IACL;AAAA,IACA,aAAa,gBAAgB;AAAA,IAC7B,gBAAgB,mBAAmB;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,eAAe,UAAU,CAAC,GAAG;AACpC,QAAM;AAAA,IACJ,qBAAqB;AAAA,IACrB,aAAa;AAAA,IACb,UAAU;AAAA,IACV,WAAAA,aAAY;AAAA,IACZ,YAAY;AAAA,EACd,IAAI;AACJ,QAAM,cAAc,aAAa,MAAMA,cAAa,iBAAiBA,UAAS;AAC9E,QAAM,YAAY,WAAW,IAAI;AACjC,QAAM,QAAQ,WAAW,IAAI;AAC7B,QAAM,SAAS,IAAI;AAAA,IACjB,UAAU;AAAA,IACV,UAAU,OAAO;AAAA,IACjB,WAAW,OAAO;AAAA,IAClB,UAAU;AAAA,IACV,kBAAkB;AAAA,IAClB,SAAS;AAAA,IACT,OAAO;AAAA,EACT,CAAC;AACD,WAAS,eAAe,UAAU;AAChC,cAAU,QAAQ,SAAS;AAC3B,WAAO,QAAQ,SAAS;AACxB,UAAM,QAAQ;AAAA,EAChB;AACA,MAAI;AACJ,WAAS,SAAS;AAChB,QAAI,YAAY,OAAO;AACrB,gBAAUA,WAAU,YAAY;AAAA,QAC9B;AAAA,QACA,CAAC,QAAQ,MAAM,QAAQ;AAAA,QACvB;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI;AACF,WAAO;AACT,WAAS,QAAQ;AACf,QAAI,WAAWA;AACb,MAAAA,WAAU,YAAY,WAAW,OAAO;AAAA,EAC5C;AACA,oBAAkB,MAAM;AACtB,UAAM;AAAA,EACR,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,IAAM,kBAAkB,CAAC,aAAa,aAAa,UAAU,WAAW,cAAc,OAAO;AAC7F,IAAM,YAAY;AAClB,SAAS,QAAQ,UAAU,WAAW,UAAU,CAAC,GAAG;AAClD,QAAM;AAAA,IACJ,eAAe;AAAA,IACf,4BAA4B;AAAA,IAC5B,QAAAC,UAAS;AAAA,IACT,QAAAJ,UAAS;AAAA,IACT,cAAc,eAAe,EAAE;AAAA,EACjC,IAAI;AACJ,QAAM,OAAO,WAAW,YAAY;AACpC,QAAM,aAAa,WAAW,UAAU,CAAC;AACzC,MAAI;AACJ,QAAM,QAAQ,MAAM;AAClB,SAAK,QAAQ;AACb,iBAAa,KAAK;AAClB,YAAQ,WAAW,MAAM,KAAK,QAAQ,MAAM,OAAO;AAAA,EACrD;AACA,QAAM,UAAU;AAAA,IACd;AAAA,IACA,MAAM;AACJ,iBAAW,QAAQ,UAAU;AAC7B,YAAM;AAAA,IACR;AAAA,EACF;AACA,MAAIA,SAAQ;AACV,UAAMC,YAAWD,QAAO;AACxB,UAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,eAAW,SAASI;AAClB,uBAAiBJ,SAAQ,OAAO,SAAS,eAAe;AAC1D,QAAI,2BAA2B;AAC7B,uBAAiBC,WAAU,oBAAoB,MAAM;AACnD,YAAI,CAACA,UAAS;AACZ,kBAAQ;AAAA,MACZ,GAAG,eAAe;AAAA,IACpB;AACA,UAAM;AAAA,EACR;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,UAAU,SAAS;AAChC,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,MAAM,IAAI,MAAM;AACtB,UAAM,EAAE,KAAK,QAAQ,OAAO,OAAO,OAAO,SAAS,aAAa,gBAAgB,OAAO,QAAQ,UAAU,eAAe,OAAO,OAAO,IAAI;AAC1I,QAAI,MAAM;AACV,QAAI,UAAU;AACZ,UAAI,SAAS;AACf,QAAI,SAAS;AACX,UAAI,QAAQ;AACd,QAAI,SAAS;AACX,UAAI,YAAY;AAClB,QAAI,WAAW;AACb,UAAI,UAAU;AAChB,QAAI,eAAe;AACjB,UAAI,cAAc;AACpB,QAAI,kBAAkB;AACpB,UAAI,iBAAiB;AACvB,QAAI,SAAS;AACX,UAAI,QAAQ;AACd,QAAI,UAAU;AACZ,UAAI,SAAS;AACf,QAAI,YAAY;AACd,UAAI,WAAW;AACjB,QAAI,iBAAiB;AACnB,UAAI,gBAAgB;AACtB,QAAI,SAAS;AACX,UAAI,QAAQ;AACd,QAAI,UAAU;AACZ,UAAI,SAAS;AACf,QAAI,SAAS,MAAM,QAAQ,GAAG;AAC9B,QAAI,UAAU;AAAA,EAChB,CAAC;AACH;AACA,SAAS,SAAS,SAAS,oBAAoB,CAAC,GAAG;AACjD,QAAM,QAAQ;AAAA,IACZ,MAAM,UAAU,QAAQ,OAAO,CAAC;AAAA,IAChC;AAAA,IACA;AAAA,MACE,gBAAgB;AAAA,MAChB,GAAG;AAAA,IACL;AAAA,EACF;AACA;AAAA,IACE,MAAM,QAAQ,OAAO;AAAA,IACrB,MAAM,MAAM,QAAQ,kBAAkB,KAAK;AAAA,IAC3C,EAAE,MAAM,KAAK;AAAA,EACf;AACA,SAAO;AACT;AAEA,SAAS,eAAe,IAAI;AAC1B,MAAI,OAAO,WAAW,eAAe,cAAc;AACjD,WAAO,GAAG,SAAS;AACrB,MAAI,OAAO,aAAa,eAAe,cAAc;AACnD,WAAO,GAAG;AACZ,SAAO;AACT;AAEA,IAAM,iCAAiC;AACvC,SAAS,UAAU,SAAS,UAAU,CAAC,GAAG;AACxC,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA,MACP,KAAK;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,IACA,uBAAuB;AAAA,MACrB,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA,WAAW;AAAA,IACX,QAAAD,UAAS;AAAA,IACT,UAAU,CAAC,MAAM;AACf,cAAQ,MAAM,CAAC;AAAA,IACjB;AAAA,EACF,IAAI;AACJ,QAAM,YAAY,WAAW,CAAC;AAC9B,QAAM,YAAY,WAAW,CAAC;AAC9B,QAAM,IAAI,SAAS;AAAA,IACjB,MAAM;AACJ,aAAO,UAAU;AAAA,IACnB;AAAA,IACA,IAAI,IAAI;AACN,eAAS,IAAI,MAAM;AAAA,IACrB;AAAA,EACF,CAAC;AACD,QAAM,IAAI,SAAS;AAAA,IACjB,MAAM;AACJ,aAAO,UAAU;AAAA,IACnB;AAAA,IACA,IAAI,IAAI;AACN,eAAS,QAAQ,EAAE;AAAA,IACrB;AAAA,EACF,CAAC;AACD,WAAS,SAAS,IAAI,IAAI;AACxB,QAAI,IAAI,IAAI,IAAI;AAChB,QAAI,CAACA;AACH;AACF,UAAM,WAAW,QAAQ,OAAO;AAChC,QAAI,CAAC;AACH;AACF,KAAC,KAAK,oBAAoB,WAAWA,QAAO,SAAS,OAAO,aAAa,OAAO,SAAS,GAAG,SAAS;AAAA,MACnG,MAAM,KAAK,QAAQ,EAAE,MAAM,OAAO,KAAK,EAAE;AAAA,MACzC,OAAO,KAAK,QAAQ,EAAE,MAAM,OAAO,KAAK,EAAE;AAAA,MAC1C,UAAU,QAAQ,QAAQ;AAAA,IAC5B,CAAC;AACD,UAAM,oBAAoB,KAAK,YAAY,OAAO,SAAS,SAAS,aAAa,OAAO,SAAS,GAAG,qBAAqB,YAAY,OAAO,SAAS,SAAS,oBAAoB;AAClL,QAAI,KAAK;AACP,gBAAU,QAAQ,gBAAgB;AACpC,QAAI,KAAK;AACP,gBAAU,QAAQ,gBAAgB;AAAA,EACtC;AACA,QAAM,cAAc,WAAW,KAAK;AACpC,QAAM,eAAe,SAAS;AAAA,IAC5B,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,IACL,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,aAAa,SAAS;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,IACL,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,cAAc,CAAC,MAAM;AACzB,QAAI,CAAC,YAAY;AACf;AACF,gBAAY,QAAQ;AACpB,eAAW,OAAO;AAClB,eAAW,QAAQ;AACnB,eAAW,MAAM;AACjB,eAAW,SAAS;AACpB,WAAO,CAAC;AAAA,EACV;AACA,QAAM,uBAAuB,cAAc,aAAa,WAAW,IAAI;AACvE,QAAM,kBAAkB,CAAC,WAAW;AAClC,QAAI;AACJ,QAAI,CAACA;AACH;AACF,UAAM,OAAO,KAAK,UAAU,OAAO,SAAS,OAAO,aAAa,OAAO,SAAS,GAAG,qBAAqB,UAAU,OAAO,SAAS,OAAO,oBAAoB,aAAa,MAAM;AAChL,UAAM,EAAE,SAAS,eAAe,UAAU,IAAI,iBAAiB,EAAE;AACjE,UAAM,qBAAqB,cAAc,QAAQ,KAAK;AACtD,UAAM,aAAa,GAAG;AACtB,eAAW,OAAO,aAAa,UAAU;AACzC,eAAW,QAAQ,aAAa,UAAU;AAC1C,UAAM,OAAO,KAAK,IAAI,aAAa,kBAAkB,MAAM,OAAO,QAAQ;AAC1E,UAAM,QAAQ,KAAK,IAAI,aAAa,kBAAkB,IAAI,GAAG,eAAe,GAAG,eAAe,OAAO,SAAS,KAAK;AACnH,QAAI,YAAY,UAAU,kBAAkB,eAAe;AACzD,mBAAa,OAAO;AACpB,mBAAa,QAAQ;AAAA,IACvB,OAAO;AACL,mBAAa,OAAO;AACpB,mBAAa,QAAQ;AAAA,IACvB;AACA,cAAU,QAAQ;AAClB,QAAI,YAAY,GAAG;AACnB,QAAI,WAAWA,QAAO,YAAY,CAAC;AACjC,kBAAYA,QAAO,SAAS,KAAK;AACnC,eAAW,MAAM,YAAY,UAAU;AACvC,eAAW,SAAS,YAAY,UAAU;AAC1C,UAAM,MAAM,KAAK,IAAI,SAAS,MAAM,OAAO,OAAO;AAClD,UAAM,SAAS,KAAK,IAAI,SAAS,IAAI,GAAG,gBAAgB,GAAG,gBAAgB,OAAO,UAAU,KAAK;AACjG,QAAI,YAAY,UAAU,kBAAkB,kBAAkB;AAC5D,mBAAa,MAAM;AACnB,mBAAa,SAAS;AAAA,IACxB,OAAO;AACL,mBAAa,MAAM;AACnB,mBAAa,SAAS;AAAA,IACxB;AACA,cAAU,QAAQ;AAAA,EACpB;AACA,QAAM,kBAAkB,CAAC,MAAM;AAC7B,QAAI;AACJ,QAAI,CAACA;AACH;AACF,UAAM,eAAe,KAAK,EAAE,OAAO,oBAAoB,OAAO,KAAK,EAAE;AACrE,oBAAgB,WAAW;AAC3B,gBAAY,QAAQ;AACpB,yBAAqB,CAAC;AACtB,aAAS,CAAC;AAAA,EACZ;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,WAAW,cAAc,iBAAiB,UAAU,MAAM,KAAK,IAAI;AAAA,IACnE;AAAA,EACF;AACA,eAAa,MAAM;AACjB,QAAI;AACF,YAAM,WAAW,QAAQ,OAAO;AAChC,UAAI,CAAC;AACH;AACF,sBAAgB,QAAQ;AAAA,IAC1B,SAAS,GAAG;AACV,cAAQ,CAAC;AAAA,IACX;AAAA,EACF,CAAC;AACD;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AACR,YAAM,WAAW,QAAQ,OAAO;AAChC,UAAIA,WAAU;AACZ,wBAAgB,QAAQ;AAAA,IAC5B;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,SAAS,YAAY,UAAU,CAAC,GAAG;AAC5D,MAAI;AACJ,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,cAAc,MAAM;AAAA,EACtB,IAAI;AACJ,QAAM,QAAQ,SAAS;AAAA,IACrB;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,QAAQ;AAAA,QACN,CAAC,SAAS,IAAI,KAAK,QAAQ,aAAa,OAAO,KAAK;AAAA,QACpD,GAAG,QAAQ;AAAA,MACb;AAAA,IACF;AAAA,EACF,CAAC;AACD,QAAM,UAAU,IAAI;AACpB,QAAM,YAAY,SAAS,MAAM,CAAC,CAAC,QAAQ,KAAK;AAChD,QAAM,kBAAkB,SAAS,MAAM;AACrC,WAAO,eAAe,QAAQ,OAAO,CAAC;AAAA,EACxC,CAAC;AACD,QAAM,mBAAmB,qBAAqB,eAAe;AAC7D,WAAS,eAAe;AACtB,UAAM,QAAQ;AACd,QAAI,CAAC,gBAAgB,SAAS,CAAC,iBAAiB,SAAS,CAAC,YAAY,gBAAgB,KAAK;AACzF;AACF,UAAM,EAAE,cAAc,cAAc,aAAa,YAAY,IAAI,gBAAgB;AACjF,UAAM,aAAa,cAAc,YAAY,cAAc,QAAQ,gBAAgB,eAAe,eAAe;AACjH,QAAI,MAAM,aAAa,SAAS,KAAK,YAAY;AAC/C,UAAI,CAAC,QAAQ,OAAO;AAClB,gBAAQ,QAAQ,QAAQ,IAAI;AAAA,UAC1B,WAAW,KAAK;AAAA,UAChB,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,QAAQ,CAAC;AAAA,QACxD,CAAC,EAAE,QAAQ,MAAM;AACf,kBAAQ,QAAQ;AAChB,mBAAS,MAAM,aAAa,CAAC;AAAA,QAC/B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACA,QAAM,OAAO;AAAA,IACX,MAAM,CAAC,MAAM,aAAa,SAAS,GAAG,iBAAiB,KAAK;AAAA,IAC5D;AAAA,IACA,EAAE,WAAW,KAAK;AAAA,EACpB;AACA,iBAAe,IAAI;AACnB,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AACN,eAAS,MAAM,aAAa,CAAC;AAAA,IAC/B;AAAA,EACF;AACF;AAEA,IAAM,gBAAgB,CAAC,aAAa,WAAW,WAAW,OAAO;AACjE,SAAS,eAAe,UAAU,UAAU,CAAC,GAAG;AAC9C,QAAM;AAAA,IACJ,QAAAI,UAAS;AAAA,IACT,UAAAH,YAAW;AAAA,IACX,UAAU;AAAA,EACZ,IAAI;AACJ,QAAM,QAAQ,WAAW,OAAO;AAChC,MAAIA,WAAU;AACZ,IAAAG,QAAO,QAAQ,CAAC,kBAAkB;AAChC,uBAAiBH,WAAU,eAAe,CAAC,QAAQ;AACjD,YAAI,OAAO,IAAI,qBAAqB;AAClC,gBAAM,QAAQ,IAAI,iBAAiB,QAAQ;AAAA,MAC/C,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,IACtB,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,KAAK,cAAc,UAAU,CAAC,GAAG;AACxD,QAAM,EAAE,QAAAD,UAAS,cAAc,IAAI;AACnC,SAAO,WAAW,KAAK,cAAcA,WAAU,OAAO,SAASA,QAAO,cAAc,OAAO;AAC7F;AAEA,IAAM,2BAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,SAAS;AAAA,EACT,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACT;AAEA,SAAS,aAAa,UAAU,CAAC,GAAG;AAClC,QAAM;AAAA,IACJ,UAAU,cAAc;AAAA,IACxB,SAAS;AAAA,IACT,WAAW;AAAA,IACX,UAAU;AAAA,IACV,eAAe;AAAA,EACjB,IAAI;AACJ,QAAM,UAAU,SAAyB,oBAAI,IAAI,CAAC;AAClD,QAAM,MAAM;AAAA,IACV,SAAS;AACP,aAAO,CAAC;AAAA,IACV;AAAA,IACA;AAAA,EACF;AACA,QAAM,OAAO,cAAc,SAAS,GAAG,IAAI;AAC3C,QAAM,WAA2B,oBAAI,IAAI;AACzC,QAAM,WAA2B,oBAAI,IAAI;AACzC,WAAS,QAAQ,KAAK,OAAO;AAC3B,QAAI,OAAO,MAAM;AACf,UAAI;AACF,aAAK,GAAG,IAAI;AAAA;AAEZ,aAAK,GAAG,EAAE,QAAQ;AAAA,IACtB;AAAA,EACF;AACA,WAAS,QAAQ;AACf,YAAQ,MAAM;AACd,eAAW,OAAO;AAChB,cAAQ,KAAK,KAAK;AAAA,EACtB;AACA,WAAS,WAAW,GAAG,OAAO;AAC5B,QAAI,IAAI;AACR,UAAM,OAAO,KAAK,EAAE,QAAQ,OAAO,SAAS,GAAG,YAAY;AAC3D,UAAM,QAAQ,KAAK,EAAE,SAAS,OAAO,SAAS,GAAG,YAAY;AAC7D,UAAM,SAAS,CAAC,MAAM,GAAG,EAAE,OAAO,OAAO;AACzC,QAAI,KAAK;AACP,UAAI;AACF,gBAAQ,IAAI,GAAG;AAAA;AAEf,gBAAQ,OAAO,GAAG;AAAA,IACtB;AACA,eAAW,QAAQ,QAAQ;AACzB,eAAS,IAAI,IAAI;AACjB,cAAQ,MAAM,KAAK;AAAA,IACrB;AACA,QAAI,QAAQ,UAAU,CAAC,OAAO;AAC5B,eAAS,QAAQ,CAAC,SAAS;AACzB,gBAAQ,OAAO,IAAI;AACnB,gBAAQ,MAAM,KAAK;AAAA,MACrB,CAAC;AACD,eAAS,MAAM;AAAA,IACjB,WAAW,OAAO,EAAE,qBAAqB,cAAc,EAAE,iBAAiB,MAAM,KAAK,OAAO;AAC1F,OAAC,GAAG,SAAS,GAAG,MAAM,EAAE,QAAQ,CAAC,SAAS,SAAS,IAAI,IAAI,CAAC;AAAA,IAC9D;AAAA,EACF;AACA,mBAAiB,QAAQ,WAAW,CAAC,MAAM;AACzC,eAAW,GAAG,IAAI;AAClB,WAAO,aAAa,CAAC;AAAA,EACvB,GAAG,EAAE,QAAQ,CAAC;AACd,mBAAiB,QAAQ,SAAS,CAAC,MAAM;AACvC,eAAW,GAAG,KAAK;AACnB,WAAO,aAAa,CAAC;AAAA,EACvB,GAAG,EAAE,QAAQ,CAAC;AACd,mBAAiB,QAAQ,OAAO,EAAE,QAAQ,CAAC;AAC3C,mBAAiB,SAAS,OAAO,EAAE,QAAQ,CAAC;AAC5C,QAAM,QAAQ,IAAI;AAAA,IAChB;AAAA,IACA;AAAA,MACE,IAAI,SAAS,MAAM,KAAK;AACtB,YAAI,OAAO,SAAS;AAClB,iBAAO,QAAQ,IAAI,SAAS,MAAM,GAAG;AACvC,eAAO,KAAK,YAAY;AACxB,YAAI,QAAQ;AACV,iBAAO,SAAS,IAAI;AACtB,YAAI,EAAE,QAAQ,OAAO;AACnB,cAAI,QAAQ,KAAK,IAAI,GAAG;AACtB,kBAAMc,QAAO,KAAK,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACrD,iBAAK,IAAI,IAAI,SAAS,MAAMA,MAAK,IAAI,CAAC,QAAQ,QAAQ,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,OAAO,CAAC;AAAA,UACnF,OAAO;AACL,iBAAK,IAAI,IAAI,WAAW,KAAK;AAAA,UAC/B;AAAA,QACF;AACA,cAAM,IAAI,QAAQ,IAAI,SAAS,MAAM,GAAG;AACxC,eAAO,cAAc,QAAQ,CAAC,IAAI;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,QAAQ,IAAI;AAC9B,MAAI,QAAQ,MAAM;AAChB,OAAG,QAAQ,MAAM,CAAC;AACtB;AACA,SAAS,iBAAiB,YAAY;AACpC,MAAI,SAAS,CAAC;AACd,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,EAAE;AACvC,aAAS,CAAC,GAAG,QAAQ,CAAC,WAAW,MAAM,CAAC,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC;AAC/D,SAAO;AACT;AACA,SAAS,cAAc,QAAQ;AAC7B,SAAO,MAAM,KAAK,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,MAAM,UAAU,MAAM,YAAY,MAAM,gCAAgC,GAAG,QAAQ,EAAE,IAAI,OAAO,MAAM,UAAU,MAAM,YAAY,MAAM,gCAAgC,EAAE;AACpN;AACA,IAAM,iBAAiB;AAAA,EACrB,KAAK;AAAA,EACL,QAAQ,CAAC;AACX;AACA,SAAS,iBAAiB,QAAQ,UAAU,CAAC,GAAG;AAC9C,WAASN,OAAM,MAAM;AACrB,YAAU;AAAA,IACR,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACA,QAAM;AAAA,IACJ,UAAAP,YAAW;AAAA,EACb,IAAI;AACJ,QAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,QAAM,cAAc,WAAW,CAAC;AAChC,QAAM,WAAW,WAAW,CAAC;AAC7B,QAAM,UAAU,WAAW,KAAK;AAChC,QAAM,SAAS,WAAW,CAAC;AAC3B,QAAM,UAAU,WAAW,KAAK;AAChC,QAAM,QAAQ,WAAW,KAAK;AAC9B,QAAM,UAAU,WAAW,KAAK;AAChC,QAAM,OAAO,WAAW,CAAC;AACzB,QAAM,UAAU,WAAW,KAAK;AAChC,QAAM,WAAW,IAAI,CAAC,CAAC;AACvB,QAAM,SAAS,IAAI,CAAC,CAAC;AACrB,QAAM,gBAAgB,WAAW,EAAE;AACnC,QAAM,qBAAqB,WAAW,KAAK;AAC3C,QAAM,QAAQ,WAAW,KAAK;AAC9B,QAAM,2BAA2BA,aAAY,6BAA6BA;AAC1E,QAAM,mBAAmB,gBAAgB;AACzC,QAAM,qBAAqB,gBAAgB;AAC3C,QAAM,eAAe,CAAC,UAAU;AAC9B,eAAW,QAAQ,CAAC,OAAO;AACzB,UAAI,OAAO;AACT,cAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,WAAG,WAAW,EAAE,EAAE,OAAO;AAAA,MAC3B,OAAO;AACL,iBAAS,IAAI,GAAG,IAAI,GAAG,WAAW,QAAQ,EAAE;AAC1C,aAAG,WAAW,CAAC,EAAE,OAAO;AAAA,MAC5B;AACA,oBAAc,QAAQ;AAAA,IACxB,CAAC;AAAA,EACH;AACA,QAAM,cAAc,CAAC,OAAO,gBAAgB,SAAS;AACnD,eAAW,QAAQ,CAAC,OAAO;AACzB,YAAM,KAAK,OAAO,UAAU,WAAW,QAAQ,MAAM;AACrD,UAAI;AACF,qBAAa;AACf,SAAG,WAAW,EAAE,EAAE,OAAO;AACzB,oBAAc,QAAQ;AAAA,IACxB,CAAC;AAAA,EACH;AACA,QAAM,yBAAyB,MAAM;AACnC,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,iBAAW,QAAQ,OAAO,OAAO;AAC/B,YAAI,0BAA0B;AAC5B,cAAI,CAAC,mBAAmB,OAAO;AAC7B,eAAG,wBAAwB,EAAE,KAAK,OAAO,EAAE,MAAM,MAAM;AAAA,UACzD,OAAO;AACL,YAAAA,UAAS,qBAAqB,EAAE,KAAK,OAAO,EAAE,MAAM,MAAM;AAAA,UAC5D;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACA,cAAY,MAAM;AAChB,QAAI,CAACA;AACH;AACF,UAAM,KAAK,QAAQ,MAAM;AACzB,QAAI,CAAC;AACH;AACF,UAAM,MAAM,QAAQ,QAAQ,GAAG;AAC/B,QAAI,UAAU,CAAC;AACf,QAAI,CAAC;AACH;AACF,QAAI,OAAO,QAAQ;AACjB,gBAAU,CAAC,EAAE,IAAI,CAAC;AAAA,aACX,MAAM,QAAQ,GAAG;AACxB,gBAAU;AAAA,aACH,SAAS,GAAG;AACnB,gBAAU,CAAC,GAAG;AAChB,OAAG,iBAAiB,QAAQ,EAAE,QAAQ,CAAC,MAAM;AAC3C,QAAE,OAAO;AAAA,IACX,CAAC;AACD,YAAQ,QAAQ,CAAC,EAAE,KAAK,MAAM,MAAM,MAAM,MAAM;AAC9C,YAAM,SAASA,UAAS,cAAc,QAAQ;AAC9C,aAAO,aAAa,OAAO,IAAI;AAC/B,aAAO,aAAa,QAAQ,QAAQ,EAAE;AACtC,aAAO,aAAa,SAAS,SAAS,EAAE;AACxC,uBAAiB,QAAQ,SAAS,iBAAiB,SAAS,eAAe;AAC3E,SAAG,YAAY,MAAM;AAAA,IACvB,CAAC;AACD,OAAG,KAAK;AAAA,EACV,CAAC;AACD,QAAM,CAAC,QAAQ,MAAM,GAAG,MAAM;AAC5B,UAAM,KAAK,QAAQ,MAAM;AACzB,QAAI,CAAC;AACH;AACF,OAAG,SAAS,OAAO;AAAA,EACrB,CAAC;AACD,QAAM,CAAC,QAAQ,KAAK,GAAG,MAAM;AAC3B,UAAM,KAAK,QAAQ,MAAM;AACzB,QAAI,CAAC;AACH;AACF,OAAG,QAAQ,MAAM;AAAA,EACnB,CAAC;AACD,QAAM,CAAC,QAAQ,IAAI,GAAG,MAAM;AAC1B,UAAM,KAAK,QAAQ,MAAM;AACzB,QAAI,CAAC;AACH;AACF,OAAG,eAAe,KAAK;AAAA,EACzB,CAAC;AACD,cAAY,MAAM;AAChB,QAAI,CAACA;AACH;AACF,UAAM,aAAa,QAAQ,QAAQ,MAAM;AACzC,UAAM,KAAK,QAAQ,MAAM;AACzB,QAAI,CAAC,cAAc,CAAC,WAAW,UAAU,CAAC;AACxC;AACF,OAAG,iBAAiB,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;AACtD,eAAW,QAAQ,CAAC,EAAE,SAAS,WAAW,MAAM,OAAO,KAAK,QAAQ,GAAG,MAAM;AAC3E,YAAM,QAAQA,UAAS,cAAc,OAAO;AAC5C,YAAM,UAAU,aAAa;AAC7B,YAAM,OAAO;AACb,YAAM,QAAQ;AACd,YAAM,MAAM;AACZ,YAAM,UAAU;AAChB,UAAI,MAAM;AACR,sBAAc,QAAQ;AACxB,SAAG,YAAY,KAAK;AAAA,IACtB,CAAC;AAAA,EACH,CAAC;AACD,QAAM,EAAE,eAAe,yBAAyB,IAAI,eAAe,aAAa,CAAC,SAAS;AACxF,UAAM,KAAK,QAAQ,MAAM;AACzB,QAAI,CAAC;AACH;AACF,OAAG,cAAc;AAAA,EACnB,CAAC;AACD,QAAM,EAAE,eAAe,qBAAqB,IAAI,eAAe,SAAS,CAAC,cAAc;AACrF,UAAM,KAAK,QAAQ,MAAM;AACzB,QAAI,CAAC;AACH;AACF,QAAI,WAAW;AACb,SAAG,KAAK,EAAE,MAAM,CAAC,MAAM;AACrB,2BAAmB,QAAQ,CAAC;AAC5B,cAAM;AAAA,MACR,CAAC;AAAA,IACH,OAAO;AACL,SAAG,MAAM;AAAA,IACX;AAAA,EACF,CAAC;AACD;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,yBAAyB,MAAM,YAAY,QAAQ,QAAQ,MAAM,EAAE,WAAW;AAAA,IACpF;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,SAAS,QAAQ,QAAQ,MAAM,EAAE;AAAA,IACvC;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,SAAS,QAAQ,iBAAiB,QAAQ,MAAM,EAAE,QAAQ;AAAA,IAChE;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,QAAQ,QAAQ;AAAA,IACtB;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,QAAQ,QAAQ;AAAA,IACtB;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA,CAAC,WAAW,WAAW;AAAA,IACvB,MAAM;AACJ,cAAQ,QAAQ;AAChB,2BAAqB,MAAM,QAAQ,QAAQ,KAAK;AAAA,IAClD;AAAA,IACA;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,QAAQ,QAAQ;AAAA,IACtB;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM;AACJ,cAAQ,QAAQ;AAChB,YAAM,QAAQ;AACd,2BAAqB,MAAM,QAAQ,QAAQ,IAAI;AAAA,IACjD;AAAA,IACA;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,KAAK,QAAQ,QAAQ,MAAM,EAAE;AAAA,IACnC;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,QAAQ,QAAQ;AAAA,IACtB;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,MAAM,QAAQ;AAAA,IACpB;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,qBAAqB,MAAM,QAAQ,QAAQ,KAAK;AAAA,IACtD;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,qBAAqB,MAAM,QAAQ,QAAQ,IAAI;AAAA,IACrD;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,mBAAmB,QAAQ;AAAA,IACjC;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM,mBAAmB,QAAQ;AAAA,IACjC;AAAA,EACF;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,MAAM;AACJ,YAAM,KAAK,QAAQ,MAAM;AACzB,UAAI,CAAC;AACH;AACF,aAAO,QAAQ,GAAG;AAClB,YAAM,QAAQ,GAAG;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AACA,QAAM,YAAY,CAAC;AACnB,QAAM,OAAO,MAAM,CAAC,MAAM,GAAG,MAAM;AACjC,UAAM,KAAK,QAAQ,MAAM;AACzB,QAAI,CAAC;AACH;AACF,SAAK;AACL,cAAU,CAAC,IAAI,iBAAiB,GAAG,YAAY,YAAY,MAAM,OAAO,QAAQ,cAAc,GAAG,UAAU,GAAG,eAAe;AAC7H,cAAU,CAAC,IAAI,iBAAiB,GAAG,YAAY,eAAe,MAAM,OAAO,QAAQ,cAAc,GAAG,UAAU,GAAG,eAAe;AAChI,cAAU,CAAC,IAAI,iBAAiB,GAAG,YAAY,UAAU,MAAM,OAAO,QAAQ,cAAc,GAAG,UAAU,GAAG,eAAe;AAAA,EAC7H,CAAC;AACD,oBAAkB,MAAM,UAAU,QAAQ,CAAC,aAAa,SAAS,CAAC,CAAC;AACnE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA,eAAe,iBAAiB;AAAA,IAChC,iBAAiB,mBAAmB;AAAA,EACtC;AACF;AAEA,SAAS,WAAW,UAAU,SAAS;AACrC,QAAM,YAAY,MAAM;AACtB,QAAI,WAAW,OAAO,SAAS,QAAQ;AACrC,aAAO,gBAAgB,QAAQ,KAAK;AACtC,WAAO,gBAAgC,oBAAI,IAAI,CAAC;AAAA,EAClD;AACA,QAAM,QAAQ,UAAU;AACxB,QAAM,cAAc,IAAI,UAAU,WAAW,OAAO,SAAS,QAAQ,UAAU,QAAQ,OAAO,GAAG,IAAI,IAAI,KAAK,UAAU,IAAI;AAC5H,QAAM,YAAY,CAAC,QAAQ,SAAS;AAClC,UAAM,IAAI,KAAK,SAAS,GAAG,IAAI,CAAC;AAChC,WAAO,MAAM,IAAI,GAAG;AAAA,EACtB;AACA,QAAM,WAAW,IAAI,SAAS,UAAU,YAAY,GAAG,IAAI,GAAG,GAAG,IAAI;AACrE,QAAM,aAAa,IAAI,SAAS;AAC9B,UAAM,OAAO,YAAY,GAAG,IAAI,CAAC;AAAA,EACnC;AACA,QAAM,YAAY,MAAM;AACtB,UAAM,MAAM;AAAA,EACd;AACA,QAAM,WAAW,IAAI,SAAS;AAC5B,UAAM,MAAM,YAAY,GAAG,IAAI;AAC/B,QAAI,MAAM,IAAI,GAAG;AACf,aAAO,MAAM,IAAI,GAAG;AACtB,WAAO,UAAU,KAAK,GAAG,IAAI;AAAA,EAC/B;AACA,WAAS,OAAO;AAChB,WAAS,SAAS;AAClB,WAAS,QAAQ;AACjB,WAAS,cAAc;AACvB,WAAS,QAAQ;AACjB,SAAO;AACT;AAEA,SAAS,UAAU,UAAU,CAAC,GAAG;AAC/B,QAAM,SAAS,IAAI;AACnB,QAAM,cAAc,aAAa,MAAM,OAAO,gBAAgB,eAAe,YAAY,WAAW;AACpG,MAAI,YAAY,OAAO;AACrB,UAAM,EAAE,WAAW,IAAI,IAAI;AAC3B,kBAAc,MAAM;AAClB,aAAO,QAAQ,YAAY;AAAA,IAC7B,GAAG,UAAU,EAAE,WAAW,QAAQ,WAAW,mBAAmB,QAAQ,kBAAkB,CAAC;AAAA,EAC7F;AACA,SAAO,EAAE,aAAa,OAAO;AAC/B;AAEA,IAAM,4BAA4B;AAAA,EAChC,MAAM,CAAC,UAAU,CAAC,MAAM,OAAO,MAAM,KAAK;AAAA,EAC1C,QAAQ,CAAC,UAAU,CAAC,MAAM,SAAS,MAAM,OAAO;AAAA,EAChD,QAAQ,CAAC,UAAU,CAAC,MAAM,SAAS,MAAM,OAAO;AAAA,EAChD,UAAU,CAAC,UAAU,iBAAiB,aAAa,CAAC,MAAM,WAAW,MAAM,SAAS,IAAI;AAC1F;AACA,SAAS,SAAS,UAAU,CAAC,GAAG;AAC9B,QAAM;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,mBAAmB;AAAA,IACnB,eAAe,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,IAC5B,QAAAD,UAAS;AAAA,IACT,SAASA;AAAA,IACT,SAAS;AAAA,IACT;AAAA,EACF,IAAI;AACJ,MAAI,kBAAkB;AACtB,MAAI,eAAe;AACnB,MAAI,eAAe;AACnB,QAAM,IAAI,WAAW,aAAa,CAAC;AACnC,QAAM,IAAI,WAAW,aAAa,CAAC;AACnC,QAAM,aAAa,WAAW,IAAI;AAClC,QAAM,YAAY,OAAO,SAAS,aAAa,OAAO,0BAA0B,IAAI;AACpF,QAAM,eAAe,CAAC,UAAU;AAC9B,UAAM,SAAS,UAAU,KAAK;AAC9B,sBAAkB;AAClB,QAAI,QAAQ;AACV,OAAC,EAAE,OAAO,EAAE,KAAK,IAAI;AACrB,iBAAW,QAAQ;AAAA,IACrB;AACA,QAAIA,SAAQ;AACV,qBAAeA,QAAO;AACtB,qBAAeA,QAAO;AAAA,IACxB;AAAA,EACF;AACA,QAAM,eAAe,CAAC,UAAU;AAC9B,QAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,YAAM,SAAS,UAAU,MAAM,QAAQ,CAAC,CAAC;AACzC,UAAI,QAAQ;AACV,SAAC,EAAE,OAAO,EAAE,KAAK,IAAI;AACrB,mBAAW,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACA,QAAM,gBAAgB,MAAM;AAC1B,QAAI,CAAC,mBAAmB,CAACA;AACvB;AACF,UAAM,MAAM,UAAU,eAAe;AACrC,QAAI,2BAA2B,cAAc,KAAK;AAChD,QAAE,QAAQ,IAAI,CAAC,IAAIA,QAAO,UAAU;AACpC,QAAE,QAAQ,IAAI,CAAC,IAAIA,QAAO,UAAU;AAAA,IACtC;AAAA,EACF;AACA,QAAM,QAAQ,MAAM;AAClB,MAAE,QAAQ,aAAa;AACvB,MAAE,QAAQ,aAAa;AAAA,EACzB;AACA,QAAM,sBAAsB,cAAc,CAAC,UAAU,YAAY,MAAM,aAAa,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,aAAa,KAAK;AAC/H,QAAM,sBAAsB,cAAc,CAAC,UAAU,YAAY,MAAM,aAAa,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,aAAa,KAAK;AAC/H,QAAM,uBAAuB,cAAc,MAAM,YAAY,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,MAAM,cAAc;AAC9G,MAAI,QAAQ;AACV,UAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,qBAAiB,QAAQ,CAAC,aAAa,UAAU,GAAG,qBAAqB,eAAe;AACxF,QAAI,SAAS,SAAS,YAAY;AAChC,uBAAiB,QAAQ,CAAC,cAAc,WAAW,GAAG,qBAAqB,eAAe;AAC1F,UAAI;AACF,yBAAiB,QAAQ,YAAY,OAAO,eAAe;AAAA,IAC/D;AACA,QAAI,UAAU,SAAS;AACrB,uBAAiBA,SAAQ,UAAU,sBAAsB,eAAe;AAAA,EAC5E;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,QAAQ,UAAU,CAAC,GAAG;AAC/C,QAAM;AAAA,IACJ,gBAAgB;AAAA,IAChB,QAAAA,UAAS;AAAA,EACX,IAAI;AACJ,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,EAAE,GAAG,GAAG,WAAW,IAAI,SAAS,OAAO;AAC7C,QAAM,YAAY,WAAW,UAAU,OAAO,SAASA,WAAU,OAAO,SAASA,QAAO,SAAS,IAAI;AACrG,QAAM,WAAW,WAAW,CAAC;AAC7B,QAAM,WAAW,WAAW,CAAC;AAC7B,QAAM,mBAAmB,WAAW,CAAC;AACrC,QAAM,mBAAmB,WAAW,CAAC;AACrC,QAAM,gBAAgB,WAAW,CAAC;AAClC,QAAM,eAAe,WAAW,CAAC;AACjC,QAAM,YAAY,WAAW,IAAI;AACjC,MAAI,OAAO,MAAM;AAAA,EACjB;AACA,MAAIA,SAAQ;AACV,WAAO;AAAA,MACL,CAAC,WAAW,GAAG,CAAC;AAAA,MAChB,MAAM;AACJ,cAAM,KAAK,aAAa,SAAS;AACjC,YAAI,CAAC,MAAM,EAAE,cAAc;AACzB;AACF,cAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,IAAI,GAAG,sBAAsB;AAC7B,yBAAiB,QAAQ,QAAQ,SAAS,SAASA,QAAO,cAAc;AACxE,yBAAiB,QAAQ,OAAO,SAAS,SAASA,QAAO,cAAc;AACvE,sBAAc,QAAQ;AACtB,qBAAa,QAAQ;AACrB,cAAM,MAAM,EAAE,QAAQ,iBAAiB;AACvC,cAAM,MAAM,EAAE,QAAQ,iBAAiB;AACvC,kBAAU,QAAQ,UAAU,KAAK,WAAW,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,SAAS,MAAM;AAC5F,YAAI,iBAAiB,CAAC,UAAU,OAAO;AACrC,mBAAS,QAAQ;AACjB,mBAAS,QAAQ;AAAA,QACnB;AAAA,MACF;AAAA,MACA,EAAE,WAAW,KAAK;AAAA,IACpB;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA,MAAM,UAAU,QAAQ;AAAA,MACxB,EAAE,SAAS,KAAK;AAAA,IAClB;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,UAAU,CAAC,GAAG;AACrC,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,UAAU;AAAA,IACV,eAAe;AAAA,IACf,QAAAA,UAAS;AAAA,EACX,IAAI;AACJ,QAAM,UAAU,WAAW,YAAY;AACvC,QAAM,aAAa,WAAW,IAAI;AAClC,MAAI,CAACA,SAAQ;AACX,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM,YAAY,CAAC,YAAY,CAAC,UAAU;AACxC,QAAI;AACJ,YAAQ,QAAQ;AAChB,eAAW,QAAQ;AACnB,KAAC,KAAK,QAAQ,cAAc,OAAO,SAAS,GAAG,KAAK,SAAS,KAAK;AAAA,EACpE;AACA,QAAM,aAAa,CAAC,UAAU;AAC5B,QAAI;AACJ,YAAQ,QAAQ;AAChB,eAAW,QAAQ;AACnB,KAAC,KAAK,QAAQ,eAAe,OAAO,SAAS,GAAG,KAAK,SAAS,KAAK;AAAA,EACrE;AACA,QAAM,SAAS,SAAS,MAAM,aAAa,QAAQ,MAAM,KAAKA,OAAM;AACpE,QAAM,kBAAkB,EAAE,SAAS,MAAM,QAAQ;AACjD,mBAAiB,QAAQ,aAAa,UAAU,OAAO,GAAG,eAAe;AACzE,mBAAiBA,SAAQ,cAAc,YAAY,eAAe;AAClE,mBAAiBA,SAAQ,WAAW,YAAY,eAAe;AAC/D,MAAI,MAAM;AACR,qBAAiB,QAAQ,aAAa,UAAU,OAAO,GAAG,eAAe;AACzE,qBAAiBA,SAAQ,QAAQ,YAAY,eAAe;AAC5D,qBAAiBA,SAAQ,WAAW,YAAY,eAAe;AAAA,EACjE;AACA,MAAI,OAAO;AACT,qBAAiB,QAAQ,cAAc,UAAU,OAAO,GAAG,eAAe;AAC1E,qBAAiBA,SAAQ,YAAY,YAAY,eAAe;AAChE,qBAAiBA,SAAQ,eAAe,YAAY,eAAe;AAAA,EACrE;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,UAAU,CAAC,GAAG;AAC1C,QAAM,EAAE,QAAAA,UAAS,cAAc,IAAI;AACnC,QAAMG,aAAYH,WAAU,OAAO,SAASA,QAAO;AACnD,QAAM,cAAc,aAAa,MAAMG,cAAa,cAAcA,UAAS;AAC3E,QAAM,WAAW,WAAWA,cAAa,OAAO,SAASA,WAAU,QAAQ;AAC3E,mBAAiBH,SAAQ,kBAAkB,MAAM;AAC/C,QAAIG;AACF,eAAS,QAAQA,WAAU;AAAA,EAC/B,GAAG,EAAE,SAAS,KAAK,CAAC;AACpB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,WAAW,UAAU,CAAC,GAAG;AAChC,QAAM,EAAE,QAAAH,UAAS,cAAc,IAAI;AACnC,QAAMG,aAAYH,WAAU,OAAO,SAASA,QAAO;AACnD,QAAM,cAAc,aAAa,MAAMG,cAAa,gBAAgBA,UAAS;AAC7E,QAAM,WAAW,WAAW,IAAI;AAChC,QAAM,WAAW,WAAW,KAAK;AACjC,QAAM,YAAY,WAAW,MAAM;AACnC,QAAM,WAAW,WAAW,MAAM;AAClC,QAAM,WAAW,WAAW,MAAM;AAClC,QAAM,cAAc,WAAW,MAAM;AACrC,QAAM,MAAM,WAAW,MAAM;AAC7B,QAAM,gBAAgB,WAAW,MAAM;AACvC,QAAM,OAAO,WAAW,SAAS;AACjC,QAAM,aAAa,YAAY,SAASA,WAAU;AAClD,WAAS,2BAA2B;AAClC,QAAI,CAACA;AACH;AACF,aAAS,QAAQA,WAAU;AAC3B,cAAU,QAAQ,SAAS,QAAQ,SAAS,KAAK,IAAI;AACrD,aAAS,QAAQ,SAAS,QAAQ,KAAK,IAAI,IAAI;AAC/C,QAAI,YAAY;AACd,eAAS,QAAQ,WAAW;AAC5B,kBAAY,QAAQ,WAAW;AAC/B,oBAAc,QAAQ,WAAW;AACjC,UAAI,QAAQ,WAAW;AACvB,eAAS,QAAQ,WAAW;AAC5B,WAAK,QAAQ,WAAW;AAAA,IAC1B;AAAA,EACF;AACA,QAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,MAAIH,SAAQ;AACV,qBAAiBA,SAAQ,WAAW,MAAM;AACxC,eAAS,QAAQ;AACjB,gBAAU,QAAQ,KAAK,IAAI;AAAA,IAC7B,GAAG,eAAe;AAClB,qBAAiBA,SAAQ,UAAU,MAAM;AACvC,eAAS,QAAQ;AACjB,eAAS,QAAQ,KAAK,IAAI;AAAA,IAC5B,GAAG,eAAe;AAAA,EACpB;AACA,MAAI;AACF,qBAAiB,YAAY,UAAU,0BAA0B,eAAe;AAClF,2BAAyB;AACzB,SAAO;AAAA,IACL;AAAA,IACA,UAAU,SAAS,QAAQ;AAAA,IAC3B,UAAU,SAAS,QAAQ;AAAA,IAC3B,WAAW,SAAS,SAAS;AAAA,IAC7B,UAAU,SAAS,QAAQ;AAAA,IAC3B,UAAU,SAAS,QAAQ;AAAA,IAC3B,aAAa,SAAS,WAAW;AAAA,IACjC,eAAe,SAAS,aAAa;AAAA,IACrC,KAAK,SAAS,GAAG;AAAA,IACjB,MAAM,SAAS,IAAI;AAAA,EACrB;AACF;AAEA,SAAS,OAAO,UAAU,CAAC,GAAG;AAC5B,QAAM;AAAA,IACJ,UAAU,iBAAiB;AAAA,IAC3B,WAAW;AAAA,EACb,IAAI;AACJ,QAAMa,OAAM,IAAoB,oBAAI,KAAK,CAAC;AAC1C,QAAM,SAAS,MAAMA,KAAI,QAAwB,oBAAI,KAAK;AAC1D,QAAM,WAAW,aAAa,0BAA0B,SAAS,QAAQ,EAAE,WAAW,KAAK,CAAC,IAAI,cAAc,QAAQ,UAAU,EAAE,WAAW,KAAK,CAAC;AACnJ,MAAI,gBAAgB;AAClB,WAAO;AAAA,MACL,KAAAA;AAAA,MACA,GAAG;AAAA,IACL;AAAA,EACF,OAAO;AACL,WAAOA;AAAA,EACT;AACF;AAEA,SAAS,aAAa,QAAQ;AAC5B,QAAM,MAAM,WAAW;AACvB,QAAM,UAAU,MAAM;AACpB,QAAI,IAAI;AACN,UAAI,gBAAgB,IAAI,KAAK;AAC/B,QAAI,QAAQ;AAAA,EACd;AACA;AAAA,IACE,MAAM,QAAQ,MAAM;AAAA,IACpB,CAAC,cAAc;AACb,cAAQ;AACR,UAAI;AACF,YAAI,QAAQ,IAAI,gBAAgB,SAAS;AAAA,IAC7C;AAAA,IACA,EAAE,WAAW,KAAK;AAAA,EACpB;AACA,oBAAkB,OAAO;AACzB,SAAO,SAAS,GAAG;AACrB;AAEA,SAAS,SAAS,OAAO,KAAK,KAAK;AACjC,MAAI,OAAO,UAAU,cAAc,WAAW,KAAK;AACjD,WAAO,SAAS,MAAM,MAAM,QAAQ,KAAK,GAAG,QAAQ,GAAG,GAAG,QAAQ,GAAG,CAAC,CAAC;AACzE,QAAM,SAAS,IAAI,KAAK;AACxB,SAAO,SAAS;AAAA,IACd,MAAM;AACJ,aAAO,OAAO,QAAQ,MAAM,OAAO,OAAO,QAAQ,GAAG,GAAG,QAAQ,GAAG,CAAC;AAAA,IACtE;AAAA,IACA,IAAI,QAAQ;AACV,aAAO,QAAQ,MAAM,QAAQ,QAAQ,GAAG,GAAG,QAAQ,GAAG,CAAC;AAAA,IACzD;AAAA,EACF,CAAC;AACH;AAEA,SAAS,oBAAoB,SAAS;AACpC,QAAM;AAAA,IACJ,QAAQ,OAAO;AAAA,IACf,WAAW;AAAA,IACX,OAAO;AAAA,IACP,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,EACtB,IAAI;AACJ,QAAM,kBAAkB,SAAS,UAAU,GAAG,OAAO,iBAAiB;AACtE,QAAM,YAAY,SAAS,MAAM,KAAK;AAAA,IACpC;AAAA,IACA,KAAK,KAAK,QAAQ,KAAK,IAAI,QAAQ,eAAe,CAAC;AAAA,EACrD,CAAC;AACD,QAAM,cAAc,SAAS,MAAM,GAAG,SAAS;AAC/C,QAAM,cAAc,SAAS,MAAM,YAAY,UAAU,CAAC;AAC1D,QAAM,aAAa,SAAS,MAAM,YAAY,UAAU,UAAU,KAAK;AACvE,MAAI,MAAM,IAAI,GAAG;AACf,YAAQ,MAAM,aAAa;AAAA,MACzB,WAAW,WAAW,IAAI,IAAI,QAAQ;AAAA,IACxC,CAAC;AAAA,EACH;AACA,MAAI,MAAM,QAAQ,GAAG;AACnB,YAAQ,UAAU,iBAAiB;AAAA,MACjC,WAAW,WAAW,QAAQ,IAAI,QAAQ;AAAA,IAC5C,CAAC;AAAA,EACH;AACA,WAAS,OAAO;AACd,gBAAY;AAAA,EACd;AACA,WAAS,OAAO;AACd,gBAAY;AAAA,EACd;AACA,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,aAAa,MAAM;AACvB,iBAAa,SAAS,WAAW,CAAC;AAAA,EACpC,CAAC;AACD,QAAM,iBAAiB,MAAM;AAC3B,qBAAiB,SAAS,WAAW,CAAC;AAAA,EACxC,CAAC;AACD,QAAM,WAAW,MAAM;AACrB,sBAAkB,SAAS,WAAW,CAAC;AAAA,EACzC,CAAC;AACD,SAAO;AACT;AAEA,SAAS,UAAU,UAAU,CAAC,GAAG;AAC/B,QAAM,EAAE,SAAS,IAAI,WAAW,OAAO;AACvC,SAAO;AACT;AAEA,SAAS,aAAa,UAAU,CAAC,GAAG;AAClC,QAAM,EAAE,QAAAb,UAAS,cAAc,IAAI;AACnC,QAAM,SAAS,WAAW,KAAK;AAC/B,QAAM,UAAU,CAAC,UAAU;AACzB,QAAI,CAACA;AACH;AACF,YAAQ,SAASA,QAAO;AACxB,UAAM,OAAO,MAAM,iBAAiB,MAAM;AAC1C,WAAO,QAAQ,CAAC;AAAA,EAClB;AACA,MAAIA,SAAQ;AACV,UAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,qBAAiBA,SAAQ,YAAY,SAAS,eAAe;AAC7D,qBAAiBA,QAAO,UAAU,cAAc,SAAS,eAAe;AACxE,qBAAiBA,QAAO,UAAU,cAAc,SAAS,eAAe;AAAA,EAC1E;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,UAAU,CAAC,GAAG;AAC1C,QAAM;AAAA,IACJ,QAAAA,UAAS;AAAA,EACX,IAAI;AACJ,QAAM,cAAc,aAAa,MAAMA,WAAU,YAAYA,WAAU,iBAAiBA,QAAO,MAAM;AACrG,QAAM,oBAAoB,YAAY,QAAQA,QAAO,OAAO,cAAc,CAAC;AAC3E,QAAM,cAAc,IAAI,kBAAkB,IAAI;AAC9C,QAAM,QAAQ,WAAW,kBAAkB,SAAS,CAAC;AACrD,MAAI,YAAY,OAAO;AACrB,qBAAiBA,SAAQ,qBAAqB,MAAM;AAClD,kBAAY,QAAQ,kBAAkB;AACtC,YAAM,QAAQ,kBAAkB;AAAA,IAClC,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,EACtB;AACA,QAAM,kBAAkB,CAAC,SAAS;AAChC,QAAI,YAAY,SAAS,OAAO,kBAAkB,SAAS;AACzD,aAAO,kBAAkB,KAAK,IAAI;AACpC,WAAO,QAAQ,OAAO,IAAI,MAAM,eAAe,CAAC;AAAA,EAClD;AACA,QAAM,oBAAoB,MAAM;AAC9B,QAAI,YAAY,SAAS,OAAO,kBAAkB,WAAW;AAC3D,wBAAkB,OAAO;AAAA,EAC7B;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,YAAY,QAAQ,UAAU,CAAC,GAAG;AACzC,QAAM;AAAA,IACJ,8BAA8B,CAAC,MAAM;AAAA,IACrC,8BAA8B,CAAC,MAAM;AAAA,IACrC,kBAAkB,CAAC,MAAM;AAAA,IACzB,kBAAkB,CAAC,MAAM;AAAA,IACzB,QAAAA,UAAS;AAAA,EACX,IAAI;AACJ,QAAM,cAAc,SAAS,qBAAqB,EAAE,QAAAA,QAAO,CAAC,CAAC;AAC7D,QAAM,oBAAoB,SAAS,qBAAqB,EAAE,QAAAA,QAAO,CAAC,CAAC;AACnE,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,UAAU;AAAA,IACV,cAAc;AAAA,IACd,eAAe;AAAA,EACjB,IAAI,kBAAkB,QAAQ,EAAE,eAAe,OAAO,QAAAA,QAAO,CAAC;AAC9D,QAAM,SAAS,SAAS,MAAM;AAC5B,QAAI,YAAY,gBAAgB,YAAY,SAAS,QAAQ,YAAY,UAAU,KAAK,YAAY,SAAS,QAAQ,YAAY,UAAU,IAAI;AAC7I,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC;AACD,QAAM,OAAO,SAAS,MAAM;AAC1B,QAAI,OAAO,UAAU,qBAAqB;AACxC,UAAI;AACJ,cAAQ,kBAAkB,aAAa;AAAA,QACrC,KAAK;AACH,kBAAQ,YAAY,QAAQ;AAC5B;AAAA,QACF,KAAK;AACH,kBAAQ,CAAC,YAAY,QAAQ;AAC7B;AAAA,QACF,KAAK;AACH,kBAAQ,CAAC,YAAY,OAAO;AAC5B;AAAA,QACF,KAAK;AACH,kBAAQ,YAAY,OAAO;AAC3B;AAAA,QACF;AACE,kBAAQ,CAAC,YAAY,OAAO;AAAA,MAChC;AACA,aAAO,4BAA4B,KAAK;AAAA,IAC1C,OAAO;AACL,YAAM,QAAQ,EAAE,EAAE,QAAQ,OAAO,QAAQ,KAAK,OAAO;AACrD,aAAO,gBAAgB,KAAK;AAAA,IAC9B;AAAA,EACF,CAAC;AACD,QAAM,OAAO,SAAS,MAAM;AAC1B,QAAI,OAAO,UAAU,qBAAqB;AACxC,UAAI;AACJ,cAAQ,kBAAkB,aAAa;AAAA,QACrC,KAAK;AACH,kBAAQ,YAAY,OAAO;AAC3B;AAAA,QACF,KAAK;AACH,kBAAQ,CAAC,YAAY,OAAO;AAC5B;AAAA,QACF,KAAK;AACH,kBAAQ,YAAY,QAAQ;AAC5B;AAAA,QACF,KAAK;AACH,kBAAQ,CAAC,YAAY,QAAQ;AAC7B;AAAA,QACF;AACE,kBAAQ,YAAY,QAAQ;AAAA,MAChC;AACA,aAAO,4BAA4B,KAAK;AAAA,IAC1C,OAAO;AACL,YAAM,SAAS,EAAE,QAAQ,MAAM,QAAQ,KAAK,MAAM;AAClD,aAAO,gBAAgB,KAAK;AAAA,IAC9B;AAAA,EACF,CAAC;AACD,SAAO,EAAE,MAAM,MAAM,OAAO;AAC9B;AAEA,SAAS,iBAAiB,UAAU,kBAAkB,GAAG;AACvD,QAAM,gBAAgB,WAAW;AACjC,QAAM,SAAS,MAAM;AACnB,UAAM,KAAK,aAAa,OAAO;AAC/B,QAAI;AACF,oBAAc,QAAQ,GAAG;AAAA,EAC7B;AACA,eAAa,MAAM;AACnB,QAAM,MAAM,QAAQ,OAAO,GAAG,MAAM;AACpC,SAAO;AACT;AAEA,SAAS,uBAAuB,SAAS,UAAU;AACjD,QAAM;AAAA,IACJ,QAAAA,UAAS;AAAA,IACT,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,IAAI;AACJ,QAAM,cAAc,aAAa,MAAMA,WAAU,yBAAyBA,OAAM;AAChF,MAAI;AACJ,QAAM,OAAO,MAAM;AACjB,gBAAY,OAAO,SAAS,SAAS,WAAW;AAAA,EAClD;AACA,QAAM,QAAQ,MAAM;AAClB,QAAI,YAAY,OAAO;AACrB,WAAK;AACL,iBAAW,IAAI,oBAAoB,QAAQ;AAC3C,eAAS,QAAQ,kBAAkB;AAAA,IACrC;AAAA,EACF;AACA,oBAAkB,IAAI;AACtB,MAAI;AACF,UAAM;AACR,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,IAAM,eAAe;AAAA,EACnB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,WAAW;AAAA,EACX,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,aAAa;AACf;AACA,IAAM,OAAuB,OAAO,KAAK,YAAY;AACrD,SAAS,WAAW,UAAU,CAAC,GAAG;AAChC,QAAM;AAAA,IACJ,SAAS;AAAA,EACX,IAAI;AACJ,QAAM,WAAW,WAAW,KAAK;AACjC,QAAM,QAAQ,IAAI,QAAQ,gBAAgB,CAAC,CAAC;AAC5C,SAAO,OAAO,MAAM,OAAO,cAAc,MAAM,KAAK;AACpD,QAAM,UAAU,CAAC,UAAU;AACzB,aAAS,QAAQ;AACjB,QAAI,QAAQ,gBAAgB,CAAC,QAAQ,aAAa,SAAS,MAAM,WAAW;AAC1E;AACF,UAAM,QAAQ,WAAW,OAAO,MAAM,KAAK;AAAA,EAC7C;AACA,MAAI,QAAQ;AACV,UAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,qBAAiB,QAAQ,CAAC,eAAe,eAAe,WAAW,GAAG,SAAS,eAAe;AAC9F,qBAAiB,QAAQ,gBAAgB,MAAM,SAAS,QAAQ,OAAO,eAAe;AAAA,EACxF;AACA,SAAO;AAAA,IACL,GAAGY,QAAO,KAAK;AAAA,IACf;AAAA,EACF;AACF;AAEA,SAAS,eAAe,QAAQ,UAAU,CAAC,GAAG;AAC5C,QAAM,EAAE,UAAAX,YAAW,gBAAgB,IAAI;AACvC,QAAM,cAAc,aAAa,MAAMA,aAAY,wBAAwBA,SAAQ;AACnF,QAAM,UAAU,WAAW;AAC3B,QAAM,iBAAiB,WAAW;AAClC,MAAI;AACJ,MAAI,YAAY,OAAO;AACrB,UAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,qBAAiBA,WAAU,qBAAqB,MAAM;AACpD,UAAI;AACJ,YAAM,kBAAkB,KAAKA,UAAS,uBAAuB,OAAO,KAAK,QAAQ;AACjF,UAAI,iBAAiB,mBAAmB,eAAe;AACrD,gBAAQ,QAAQA,UAAS;AACzB,YAAI,CAAC,QAAQ;AACX,0BAAgB,eAAe,QAAQ;AAAA,MAC3C;AAAA,IACF,GAAG,eAAe;AAClB,qBAAiBA,WAAU,oBAAoB,MAAM;AACnD,UAAI;AACJ,YAAM,kBAAkB,KAAKA,UAAS,uBAAuB,OAAO,KAAK,QAAQ;AACjF,UAAI,iBAAiB,mBAAmB,eAAe;AACrD,cAAM,SAASA,UAAS,qBAAqB,YAAY;AACzD,cAAM,IAAI,MAAM,aAAa,MAAM,gBAAgB;AAAA,MACrD;AAAA,IACF,GAAG,eAAe;AAAA,EACpB;AACA,iBAAe,KAAK,GAAG;AACrB,QAAI;AACJ,QAAI,CAAC,YAAY;AACf,YAAM,IAAI,MAAM,oDAAoD;AACtE,mBAAe,QAAQ,aAAa,QAAQ,EAAE,gBAAgB;AAC9D,oBAAgB,aAAa,SAAS,KAAK,aAAa,MAAM,MAAM,OAAO,KAAK,eAAe,QAAQ,aAAa,CAAC;AACrH,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,2BAA2B;AAC7C,kBAAc,mBAAmB;AACjC,WAAO,MAAM,MAAM,OAAO,EAAE,KAAK,aAAa;AAAA,EAChD;AACA,iBAAe,SAAS;AACtB,QAAI,CAAC,QAAQ;AACX,aAAO;AACT,IAAAA,UAAS,gBAAgB;AACzB,UAAM,MAAM,OAAO,EAAE,SAAS;AAC9B,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,QAAQ,UAAU,CAAC,GAAG;AAC7C,QAAM,YAAYO,OAAM,MAAM;AAC9B,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,oBAAoB;AAAA,EACtB,IAAI;AACJ,QAAM,WAAW,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AACxC,QAAM,iBAAiB,CAAC,GAAG,MAAM;AAC/B,aAAS,IAAI;AACb,aAAS,IAAI;AAAA,EACf;AACA,QAAM,SAAS,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AACtC,QAAM,eAAe,CAAC,GAAG,MAAM;AAC7B,WAAO,IAAI;AACX,WAAO,IAAI;AAAA,EACb;AACA,QAAM,YAAY,SAAS,MAAM,SAAS,IAAI,OAAO,CAAC;AACtD,QAAM,YAAY,SAAS,MAAM,SAAS,IAAI,OAAO,CAAC;AACtD,QAAM,EAAE,KAAK,IAAI,IAAI;AACrB,QAAM,sBAAsB,SAAS,MAAM,IAAI,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,CAAC,KAAK,SAAS;AACvG,QAAM,YAAY,WAAW,KAAK;AAClC,QAAM,gBAAgB,WAAW,KAAK;AACtC,QAAM,YAAY,SAAS,MAAM;AAC/B,QAAI,CAAC,oBAAoB;AACvB,aAAO;AACT,QAAI,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,GAAG;AAC/C,aAAO,UAAU,QAAQ,IAAI,SAAS;AAAA,IACxC,OAAO;AACL,aAAO,UAAU,QAAQ,IAAI,OAAO;AAAA,IACtC;AAAA,EACF,CAAC;AACD,QAAM,iBAAiB,CAAC,MAAM;AAC5B,QAAI,IAAI,IAAI;AACZ,UAAM,oBAAoB,EAAE,YAAY;AACxC,UAAM,kBAAkB,EAAE,YAAY;AACtC,YAAQ,MAAM,MAAM,KAAK,QAAQ,iBAAiB,OAAO,SAAS,GAAG,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,qBAAqB,oBAAoB,OAAO,KAAK;AAAA,EACpK;AACA,QAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,QAAM,QAAQ;AAAA,IACZ,iBAAiB,QAAQ,eAAe,CAAC,MAAM;AAC7C,UAAI,CAAC,eAAe,CAAC;AACnB;AACF,oBAAc,QAAQ;AACtB,YAAM,cAAc,EAAE;AACtB,qBAAe,OAAO,SAAS,YAAY,kBAAkB,EAAE,SAAS;AACxE,YAAM,EAAE,SAAS,GAAG,SAAS,EAAE,IAAI;AACnC,qBAAe,GAAG,CAAC;AACnB,mBAAa,GAAG,CAAC;AACjB,sBAAgB,OAAO,SAAS,aAAa,CAAC;AAAA,IAChD,GAAG,eAAe;AAAA,IAClB,iBAAiB,QAAQ,eAAe,CAAC,MAAM;AAC7C,UAAI,CAAC,eAAe,CAAC;AACnB;AACF,UAAI,CAAC,cAAc;AACjB;AACF,YAAM,EAAE,SAAS,GAAG,SAAS,EAAE,IAAI;AACnC,mBAAa,GAAG,CAAC;AACjB,UAAI,CAAC,UAAU,SAAS,oBAAoB;AAC1C,kBAAU,QAAQ;AACpB,UAAI,UAAU;AACZ,mBAAW,OAAO,SAAS,QAAQ,CAAC;AAAA,IACxC,GAAG,eAAe;AAAA,IAClB,iBAAiB,QAAQ,aAAa,CAAC,MAAM;AAC3C,UAAI,CAAC,eAAe,CAAC;AACnB;AACF,UAAI,UAAU;AACZ,sBAAc,OAAO,SAAS,WAAW,GAAG,UAAU,KAAK;AAC7D,oBAAc,QAAQ;AACtB,gBAAU,QAAQ;AAAA,IACpB,GAAG,eAAe;AAAA,EACpB;AACA,eAAa,MAAM;AACjB,QAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AAChC,KAAC,MAAM,KAAK,UAAU,UAAU,OAAO,SAAS,GAAG,UAAU,OAAO,SAAS,GAAG,YAAY,gBAAgB,MAAM;AAClH,QAAI,mBAAmB;AACrB,OAAC,MAAM,KAAK,UAAU,UAAU,OAAO,SAAS,GAAG,UAAU,OAAO,SAAS,GAAG,YAAY,uBAAuB,MAAM;AACzH,OAAC,MAAM,KAAK,UAAU,UAAU,OAAO,SAAS,GAAG,UAAU,OAAO,SAAS,GAAG,YAAY,mBAAmB,MAAM;AACrH,OAAC,MAAM,KAAK,UAAU,UAAU,OAAO,SAAS,GAAG,UAAU,OAAO,SAAS,GAAG,YAAY,eAAe,MAAM;AAAA,IACnH;AAAA,EACF,CAAC;AACD,QAAM,OAAO,MAAM,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC3C,SAAO;AAAA,IACL,WAAW,SAAS,SAAS;AAAA,IAC7B,WAAW,SAAS,SAAS;AAAA,IAC7B,UAAU,SAAS,QAAQ;AAAA,IAC3B,QAAQ,SAAS,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,wBAAwB,SAAS;AACxC,QAAM,UAAU,cAAc,iCAAiC,OAAO;AACtE,QAAM,SAAS,cAAc,gCAAgC,OAAO;AACpE,SAAO,SAAS,MAAM;AACpB,QAAI,OAAO;AACT,aAAO;AACT,QAAI,QAAQ;AACV,aAAO;AACT,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,qBAAqB,SAAS;AACrC,QAAM,SAAS,cAAc,4BAA4B,OAAO;AAChE,QAAM,SAAS,cAAc,4BAA4B,OAAO;AAChE,QAAM,WAAW,cAAc,8BAA8B,OAAO;AACpE,SAAO,SAAS,MAAM;AACpB,QAAI,OAAO;AACT,aAAO;AACT,QAAI,OAAO;AACT,aAAO;AACT,QAAI,SAAS;AACX,aAAO;AACT,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,sBAAsB,UAAU,CAAC,GAAG;AAC3C,QAAM,EAAE,QAAAR,UAAS,cAAc,IAAI;AACnC,MAAI,CAACA;AACH,WAAO,IAAI,CAAC,IAAI,CAAC;AACnB,QAAMG,aAAYH,QAAO;AACzB,QAAM,QAAQ,IAAIG,WAAU,SAAS;AACrC,mBAAiBH,SAAQ,kBAAkB,MAAM;AAC/C,UAAM,QAAQG,WAAU;AAAA,EAC1B,GAAG,EAAE,SAAS,KAAK,CAAC;AACpB,SAAO;AACT;AAEA,SAAS,0BAA0B,SAAS;AAC1C,QAAM,YAAY,cAAc,oCAAoC,OAAO;AAC3E,SAAO,SAAS,MAAM;AACpB,QAAI,UAAU;AACZ,aAAO;AACT,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,gCAAgC,SAAS;AAChD,QAAM,YAAY,cAAc,0CAA0C,OAAO;AACjF,SAAO,SAAS,MAAM;AACpB,QAAI,UAAU;AACZ,aAAO;AACT,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,YAAY,OAAO,cAAc;AACxC,QAAM,WAAW,WAAW,YAAY;AACxC;AAAA,IACEK,OAAM,KAAK;AAAA,IACX,CAAC,GAAG,aAAa;AACf,eAAS,QAAQ;AAAA,IACnB;AAAA,IACA,EAAE,OAAO,OAAO;AAAA,EAClB;AACA,SAAO,SAAS,QAAQ;AAC1B;AAEA,IAAM,aAAa;AACnB,IAAM,eAAe;AACrB,IAAM,gBAAgB;AACtB,IAAM,cAAc;AACpB,SAAS,oBAAoB;AAC3B,QAAM,MAAM,WAAW,EAAE;AACzB,QAAM,QAAQ,WAAW,EAAE;AAC3B,QAAM,SAAS,WAAW,EAAE;AAC5B,QAAM,OAAO,WAAW,EAAE;AAC1B,MAAI,UAAU;AACZ,UAAM,YAAY,UAAU,UAAU;AACtC,UAAM,cAAc,UAAU,YAAY;AAC1C,UAAM,eAAe,UAAU,aAAa;AAC5C,UAAM,aAAa,UAAU,WAAW;AACxC,cAAU,QAAQ;AAClB,gBAAY,QAAQ;AACpB,iBAAa,QAAQ;AACrB,eAAW,QAAQ;AACnB,WAAO;AACP,qBAAiB,UAAU,cAAc,MAAM,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,EACrE;AACA,WAAS,SAAS;AAChB,QAAI,QAAQ,SAAS,UAAU;AAC/B,UAAM,QAAQ,SAAS,YAAY;AACnC,WAAO,QAAQ,SAAS,aAAa;AACrC,SAAK,QAAQ,SAAS,WAAW;AAAA,EACnC;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AACA,SAAS,SAAS,UAAU;AAC1B,SAAO,iBAAiB,SAAS,eAAe,EAAE,iBAAiB,QAAQ;AAC7E;AAEA,SAAS,aAAa,KAAK,WAAW,MAAM,UAAU,CAAC,GAAG;AACxD,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,OAAO;AAAA,IACP,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAAP,YAAW;AAAA,IACX,QAAQ,CAAC;AAAA,EACX,IAAI;AACJ,QAAM,YAAY,WAAW,IAAI;AACjC,MAAI,WAAW;AACf,QAAM,aAAa,CAAC,sBAAsB,IAAI,QAAQ,CAAC,SAAS,WAAW;AACzE,UAAM,qBAAqB,CAAC,QAAQ;AAClC,gBAAU,QAAQ;AAClB,cAAQ,GAAG;AACX,aAAO;AAAA,IACT;AACA,QAAI,CAACA,WAAU;AACb,cAAQ,KAAK;AACb;AAAA,IACF;AACA,QAAI,eAAe;AACnB,QAAI,KAAKA,UAAS,cAAc,eAAe,QAAQ,GAAG,CAAC,IAAI;AAC/D,QAAI,CAAC,IAAI;AACP,WAAKA,UAAS,cAAc,QAAQ;AACpC,SAAG,OAAO;AACV,SAAG,QAAQ;AACX,SAAG,MAAM,QAAQ,GAAG;AACpB,UAAI;AACF,WAAG,QAAQ;AACb,UAAI;AACF,WAAG,cAAc;AACnB,UAAI;AACF,WAAG,WAAW;AAChB,UAAI;AACF,WAAG,iBAAiB;AACtB,aAAO,QAAQ,KAAK,EAAE,QAAQ,CAAC,CAAC,MAAM,KAAK,MAAM,MAAM,OAAO,SAAS,GAAG,aAAa,MAAM,KAAK,CAAC;AACnG,qBAAe;AAAA,IACjB,WAAW,GAAG,aAAa,aAAa,GAAG;AACzC,yBAAmB,EAAE;AAAA,IACvB;AACA,UAAM,kBAAkB;AAAA,MACtB,SAAS;AAAA,IACX;AACA,qBAAiB,IAAI,SAAS,CAAC,UAAU,OAAO,KAAK,GAAG,eAAe;AACvE,qBAAiB,IAAI,SAAS,CAAC,UAAU,OAAO,KAAK,GAAG,eAAe;AACvE,qBAAiB,IAAI,QAAQ,MAAM;AACjC,SAAG,aAAa,eAAe,MAAM;AACrC,eAAS,EAAE;AACX,yBAAmB,EAAE;AAAA,IACvB,GAAG,eAAe;AAClB,QAAI;AACF,WAAKA,UAAS,KAAK,YAAY,EAAE;AACnC,QAAI,CAAC;AACH,yBAAmB,EAAE;AAAA,EACzB,CAAC;AACD,QAAM,OAAO,CAAC,oBAAoB,SAAS;AACzC,QAAI,CAAC;AACH,iBAAW,WAAW,iBAAiB;AACzC,WAAO;AAAA,EACT;AACA,QAAM,SAAS,MAAM;AACnB,QAAI,CAACA;AACH;AACF,eAAW;AACX,QAAI,UAAU;AACZ,gBAAU,QAAQ;AACpB,UAAM,KAAKA,UAAS,cAAc,eAAe,QAAQ,GAAG,CAAC,IAAI;AACjE,QAAI;AACF,MAAAA,UAAS,KAAK,YAAY,EAAE;AAAA,EAChC;AACA,MAAI,aAAa,CAAC;AAChB,iBAAa,IAAI;AACnB,MAAI,CAAC;AACH,mBAAe,MAAM;AACvB,SAAO,EAAE,WAAW,MAAM,OAAO;AACnC;AAEA,SAAS,oBAAoB,KAAK;AAChC,QAAM,QAAQ,OAAO,iBAAiB,GAAG;AACzC,MAAI,MAAM,cAAc,YAAY,MAAM,cAAc,YAAY,MAAM,cAAc,UAAU,IAAI,cAAc,IAAI,eAAe,MAAM,cAAc,UAAU,IAAI,eAAe,IAAI,cAAc;AACxM,WAAO;AAAA,EACT,OAAO;AACL,UAAM,SAAS,IAAI;AACnB,QAAI,CAAC,UAAU,OAAO,YAAY;AAChC,aAAO;AACT,WAAO,oBAAoB,MAAM;AAAA,EACnC;AACF;AACA,SAAS,eAAe,UAAU;AAChC,QAAM,IAAI,YAAY,OAAO;AAC7B,QAAM,UAAU,EAAE;AAClB,MAAI,oBAAoB,OAAO;AAC7B,WAAO;AACT,MAAI,EAAE,QAAQ,SAAS;AACrB,WAAO;AACT,MAAI,EAAE;AACJ,MAAE,eAAe;AACnB,SAAO;AACT;AACA,IAAM,oBAAoC,oBAAI,QAAQ;AACtD,SAAS,cAAc,SAAS,eAAe,OAAO;AACpD,QAAM,WAAW,WAAW,YAAY;AACxC,MAAI,wBAAwB;AAC5B,MAAI,kBAAkB;AACtB,QAAMO,OAAM,OAAO,GAAG,CAAC,OAAO;AAC5B,UAAM,SAAS,eAAe,QAAQ,EAAE,CAAC;AACzC,QAAI,QAAQ;AACV,YAAM,MAAM;AACZ,UAAI,CAAC,kBAAkB,IAAI,GAAG;AAC5B,0BAAkB,IAAI,KAAK,IAAI,MAAM,QAAQ;AAC/C,UAAI,IAAI,MAAM,aAAa;AACzB,0BAAkB,IAAI,MAAM;AAC9B,UAAI,IAAI,MAAM,aAAa;AACzB,eAAO,SAAS,QAAQ;AAC1B,UAAI,SAAS;AACX,eAAO,IAAI,MAAM,WAAW;AAAA,IAChC;AAAA,EACF,GAAG;AAAA,IACD,WAAW;AAAA,EACb,CAAC;AACD,QAAM,OAAO,MAAM;AACjB,UAAM,KAAK,eAAe,QAAQ,OAAO,CAAC;AAC1C,QAAI,CAAC,MAAM,SAAS;AAClB;AACF,QAAI,OAAO;AACT,8BAAwB;AAAA,QACtB;AAAA,QACA;AAAA,QACA,CAAC,MAAM;AACL,yBAAe,CAAC;AAAA,QAClB;AAAA,QACA,EAAE,SAAS,MAAM;AAAA,MACnB;AAAA,IACF;AACA,OAAG,MAAM,WAAW;AACpB,aAAS,QAAQ;AAAA,EACnB;AACA,QAAM,SAAS,MAAM;AACnB,UAAM,KAAK,eAAe,QAAQ,OAAO,CAAC;AAC1C,QAAI,CAAC,MAAM,CAAC,SAAS;AACnB;AACF,QAAI;AACF,+BAAyB,OAAO,SAAS,sBAAsB;AACjE,OAAG,MAAM,WAAW;AACpB,sBAAkB,OAAO,EAAE;AAC3B,aAAS,QAAQ;AAAA,EACnB;AACA,oBAAkB,MAAM;AACxB,SAAO,SAAS;AAAA,IACd,MAAM;AACJ,aAAO,SAAS;AAAA,IAClB;AAAA,IACA,IAAI,GAAG;AACL,UAAI;AACF,aAAK;AAAA,UACF,QAAO;AAAA,IACd;AAAA,EACF,CAAC;AACH;AAEA,SAAS,kBAAkB,KAAK,cAAc,UAAU,CAAC,GAAG;AAC1D,QAAM,EAAE,QAAAR,UAAS,cAAc,IAAI;AACnC,SAAO,WAAW,KAAK,cAAcA,WAAU,OAAO,SAASA,QAAO,gBAAgB,OAAO;AAC/F;AAEA,SAAS,SAAS,eAAe,CAAC,GAAG,UAAU,CAAC,GAAG;AACjD,QAAM,EAAE,WAAAG,aAAY,iBAAiB,IAAI;AACzC,QAAM,aAAaA;AACnB,QAAM,cAAc,aAAa,MAAM,cAAc,cAAc,UAAU;AAC7E,QAAM,QAAQ,OAAO,kBAAkB,CAAC,MAAM;AAC5C,QAAI,YAAY,OAAO;AACrB,YAAM,OAAO;AAAA,QACX,GAAG,QAAQ,YAAY;AAAA,QACvB,GAAG,QAAQ,eAAe;AAAA,MAC5B;AACA,UAAI,UAAU;AACd,UAAI,KAAK,SAAS,WAAW;AAC3B,kBAAU,WAAW,SAAS,EAAE,OAAO,KAAK,MAAM,CAAC;AACrD,UAAI;AACF,eAAO,WAAW,MAAM,IAAI;AAAA,IAChC;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,IAAM,gBAAgB,CAAC,QAAQ,cAAc,OAAO,KAAK,SAAS;AAClE,IAAM,iBAAiB,CAAC,GAAG,MAAM,IAAI;AACrC,SAAS,aAAa,MAAM;AAC1B,MAAI,IAAI,IAAI,IAAI;AAChB,QAAM,CAAC,MAAM,IAAI;AACjB,MAAI,YAAY;AAChB,MAAI,UAAU,CAAC;AACf,MAAI,KAAK,WAAW,GAAG;AACrB,QAAI,OAAO,KAAK,CAAC,MAAM,UAAU;AAC/B,gBAAU,KAAK,CAAC;AAChB,mBAAa,KAAK,QAAQ,cAAc,OAAO,KAAK;AAAA,IACtD,OAAO;AACL,mBAAa,KAAK,KAAK,CAAC,MAAM,OAAO,KAAK;AAAA,IAC5C;AAAA,EACF,WAAW,KAAK,SAAS,GAAG;AAC1B,iBAAa,KAAK,KAAK,CAAC,MAAM,OAAO,KAAK;AAC1C,eAAW,KAAK,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC;AAAA,EAC3C;AACA,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,SAAS;AAAA,EACX,IAAI;AACJ,MAAI,CAAC;AACH,WAAO,SAAS,MAAM,OAAO,CAAC,GAAG,QAAQ,MAAM,CAAC,GAAG,SAAS,CAAC;AAC/D,cAAY,MAAM;AAChB,UAAM,SAAS,OAAO,QAAQ,MAAM,GAAG,SAAS;AAChD,QAAI,MAAM,MAAM;AACd,aAAO,QAAQ;AAAA;AAEf,aAAO,OAAO,GAAG,OAAO,QAAQ,GAAG,MAAM;AAAA,EAC7C,CAAC;AACD,SAAO;AACT;AAEA,SAAS,qBAAqB,UAAU,CAAC,GAAG;AAC1C,QAAM;AAAA,IACJ,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,QAAAH,UAAS;AAAA,EACX,IAAI;AACJ,QAAM,OAAOQ,OAAM,QAAQ,QAAQ,OAAO;AAC1C,QAAM,cAAc,WAAW,KAAK;AACpC,QAAM,UAAU,WAAW,KAAK;AAChC,QAAM,SAAS,WAAW,EAAE;AAC5B,QAAM,QAAQ,WAAW,MAAM;AAC/B,MAAI;AACJ,QAAM,QAAQ,MAAM;AAClB,gBAAY,QAAQ;AAAA,EACtB;AACA,QAAM,OAAO,MAAM;AACjB,gBAAY,QAAQ;AAAA,EACtB;AACA,QAAM,SAAS,CAAC,QAAQ,CAAC,YAAY,UAAU;AAC7C,QAAI,OAAO;AACT,YAAM;AAAA,IACR,OAAO;AACL,WAAK;AAAA,IACP;AAAA,EACF;AACA,QAAM,oBAAoBR,YAAWA,QAAO,qBAAqBA,QAAO;AACxE,QAAM,cAAc,aAAa,MAAM,iBAAiB;AACxD,MAAI,YAAY,OAAO;AACrB,kBAAc,IAAI,kBAAkB;AACpC,gBAAY,aAAa;AACzB,gBAAY,iBAAiB;AAC7B,gBAAY,OAAO,QAAQ,IAAI;AAC/B,gBAAY,kBAAkB;AAC9B,gBAAY,UAAU,MAAM;AAC1B,kBAAY,QAAQ;AACpB,cAAQ,QAAQ;AAAA,IAClB;AACA,UAAM,MAAM,CAAC,UAAU;AACrB,UAAI,eAAe,CAAC,YAAY;AAC9B,oBAAY,OAAO;AAAA,IACvB,CAAC;AACD,gBAAY,WAAW,CAAC,UAAU;AAChC,YAAM,gBAAgB,MAAM,QAAQ,MAAM,WAAW;AACrD,YAAM,EAAE,WAAW,IAAI,cAAc,CAAC;AACtC,cAAQ,QAAQ,cAAc;AAC9B,aAAO,QAAQ;AACf,YAAM,QAAQ;AAAA,IAChB;AACA,gBAAY,UAAU,CAAC,UAAU;AAC/B,YAAM,QAAQ;AAAA,IAChB;AACA,gBAAY,QAAQ,MAAM;AACxB,kBAAY,QAAQ;AACpB,kBAAY,OAAO,QAAQ,IAAI;AAAA,IACjC;AACA,UAAM,aAAa,CAAC,UAAU,aAAa;AACzC,UAAI,aAAa;AACf;AACF,UAAI;AACF,oBAAY,MAAM;AAAA;AAElB,oBAAY,KAAK;AAAA,IACrB,CAAC;AAAA,EACH;AACA,oBAAkB,MAAM;AACtB,SAAK;AAAA,EACP,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,MAAM,UAAU,CAAC,GAAG;AAC9C,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAAA,UAAS;AAAA,EACX,IAAI;AACJ,QAAM,QAAQA,WAAUA,QAAO;AAC/B,QAAM,cAAc,aAAa,MAAM,KAAK;AAC5C,QAAM,YAAY,WAAW,KAAK;AAClC,QAAM,SAAS,WAAW,MAAM;AAChC,QAAM,aAAaQ,OAAM,QAAQ,EAAE;AACnC,QAAM,OAAOA,OAAM,QAAQ,QAAQ,OAAO;AAC1C,QAAM,QAAQ,WAAW,MAAM;AAC/B,QAAM,SAAS,CAAC,QAAQ,CAAC,UAAU,UAAU;AAC3C,cAAU,QAAQ;AAAA,EACpB;AACA,QAAM,yBAAyB,CAAC,eAAe;AAC7C,eAAW,OAAO,QAAQ,IAAI;AAC9B,eAAW,QAAQ,QAAQ,QAAQ,KAAK,KAAK;AAC7C,eAAW,QAAQ,QAAQ,KAAK;AAChC,eAAW,OAAO,QAAQ,IAAI;AAC9B,eAAW,SAAS;AACpB,eAAW,UAAU,MAAM;AACzB,gBAAU,QAAQ;AAClB,aAAO,QAAQ;AAAA,IACjB;AACA,eAAW,UAAU,MAAM;AACzB,gBAAU,QAAQ;AAClB,aAAO,QAAQ;AAAA,IACjB;AACA,eAAW,WAAW,MAAM;AAC1B,gBAAU,QAAQ;AAClB,aAAO,QAAQ;AAAA,IACjB;AACA,eAAW,QAAQ,MAAM;AACvB,gBAAU,QAAQ;AAClB,aAAO,QAAQ;AAAA,IACjB;AACA,eAAW,UAAU,CAAC,UAAU;AAC9B,YAAM,QAAQ;AAAA,IAChB;AAAA,EACF;AACA,QAAM,YAAY,SAAS,MAAM;AAC/B,cAAU,QAAQ;AAClB,WAAO,QAAQ;AACf,UAAM,eAAe,IAAI,yBAAyB,WAAW,KAAK;AAClE,2BAAuB,YAAY;AACnC,WAAO;AAAA,EACT,CAAC;AACD,QAAM,QAAQ,MAAM;AAClB,UAAM,OAAO;AACb,QAAI;AACF,YAAM,MAAM,UAAU,KAAK;AAAA,EAC/B;AACA,QAAM,OAAO,MAAM;AACjB,UAAM,OAAO;AACb,cAAU,QAAQ;AAAA,EACpB;AACA,MAAI,YAAY,OAAO;AACrB,2BAAuB,UAAU,KAAK;AACtC,UAAM,MAAM,CAAC,UAAU;AACrB,UAAI,UAAU,SAAS,CAAC,UAAU;AAChC,kBAAU,MAAM,OAAO;AAAA,IAC3B,CAAC;AACD,QAAI,QAAQ,OAAO;AACjB,YAAM,QAAQ,OAAO,MAAM;AACzB,cAAM,OAAO;AAAA,MACf,CAAC;AAAA,IACH;AACA,UAAM,WAAW,MAAM;AACrB,UAAI,UAAU;AACZ,cAAM,OAAO;AAAA;AAEb,cAAM,MAAM;AAAA,IAChB,CAAC;AAAA,EACH;AACA,oBAAkB,MAAM;AACtB,cAAU,QAAQ;AAAA,EACpB,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,WAAW,OAAO,aAAa;AACtC,QAAM,WAAW,IAAI,KAAK;AAC1B,QAAM,YAAY,SAAS,MAAM,MAAM,QAAQ,SAAS,KAAK,IAAI,SAAS,QAAQ,OAAO,KAAK,SAAS,KAAK,CAAC;AAC7G,QAAM,QAAQ,IAAI,UAAU,MAAM,QAAQ,eAAe,OAAO,cAAc,UAAU,MAAM,CAAC,CAAC,CAAC;AACjG,QAAM,UAAU,SAAS,MAAM,GAAG,MAAM,KAAK,CAAC;AAC9C,QAAM,UAAU,SAAS,MAAM,MAAM,UAAU,CAAC;AAChD,QAAM,SAAS,SAAS,MAAM,MAAM,UAAU,UAAU,MAAM,SAAS,CAAC;AACxE,QAAM,OAAO,SAAS,MAAM,UAAU,MAAM,MAAM,QAAQ,CAAC,CAAC;AAC5D,QAAM,WAAW,SAAS,MAAM,UAAU,MAAM,MAAM,QAAQ,CAAC,CAAC;AAChE,WAAS,GAAG,QAAQ;AAClB,QAAI,MAAM,QAAQ,SAAS,KAAK;AAC9B,aAAO,SAAS,MAAM,MAAM;AAC9B,WAAO,SAAS,MAAM,UAAU,MAAM,MAAM,CAAC;AAAA,EAC/C;AACA,WAASO,KAAI,MAAM;AACjB,QAAI,CAAC,UAAU,MAAM,SAAS,IAAI;AAChC;AACF,WAAO,GAAG,UAAU,MAAM,QAAQ,IAAI,CAAC;AAAA,EACzC;AACA,WAAS,KAAK,MAAM;AAClB,QAAI,UAAU,MAAM,SAAS,IAAI;AAC/B,YAAM,QAAQ,UAAU,MAAM,QAAQ,IAAI;AAAA,EAC9C;AACA,WAAS,WAAW;AAClB,QAAI,OAAO;AACT;AACF,UAAM;AAAA,EACR;AACA,WAAS,eAAe;AACtB,QAAI,QAAQ;AACV;AACF,UAAM;AAAA,EACR;AACA,WAAS,SAAS,MAAM;AACtB,QAAI,QAAQ,IAAI;AACd,WAAK,IAAI;AAAA,EACb;AACA,WAAS,OAAO,MAAM;AACpB,WAAO,UAAU,MAAM,QAAQ,IAAI,MAAM,MAAM,QAAQ;AAAA,EACzD;AACA,WAAS,WAAW,MAAM;AACxB,WAAO,UAAU,MAAM,QAAQ,IAAI,MAAM,MAAM,QAAQ;AAAA,EACzD;AACA,WAAS,UAAU,MAAM;AACvB,WAAO,UAAU,MAAM,QAAQ,IAAI,MAAM,MAAM;AAAA,EACjD;AACA,WAAS,SAAS,MAAM;AACtB,WAAO,MAAM,QAAQ,UAAU,MAAM,QAAQ,IAAI;AAAA,EACnD;AACA,WAAS,QAAQ,MAAM;AACrB,WAAO,MAAM,QAAQ,UAAU,MAAM,QAAQ,IAAI;AAAA,EACnD;AACA,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,KAAK,cAAc,SAAS,UAAU,CAAC,GAAG;AACjE,MAAI;AACJ,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,yBAAyB;AAAA,IACzB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB;AAAA,IACA,QAAAf,UAAS;AAAA,IACT;AAAA,IACA,UAAU,CAAC,MAAM;AACf,cAAQ,MAAM,CAAC;AAAA,IACjB;AAAA,EACF,IAAI;AACJ,QAAM,UAAU,QAAQ,YAAY;AACpC,QAAM,OAAO,oBAAoB,OAAO;AACxC,QAAM,QAAQ,UAAU,aAAa,KAAK,QAAQ,YAAY,CAAC;AAC/D,QAAM,cAAc,KAAK,QAAQ,eAAe,OAAO,KAAK,mBAAmB,IAAI;AACnF,MAAI,CAAC,SAAS;AACZ,QAAI;AACF,gBAAU,cAAc,0BAA0B,MAAM;AACtD,YAAI;AACJ,gBAAQ,MAAM,kBAAkB,OAAO,SAAS,IAAI;AAAA,MACtD,CAAC,EAAE;AAAA,IACL,SAAS,GAAG;AACV,cAAQ,CAAC;AAAA,IACX;AAAA,EACF;AACA,iBAAe,KAAK,OAAO;AACzB,QAAI,CAAC,WAAW,SAAS,MAAM,QAAQ;AACrC;AACF,QAAI;AACF,YAAM,WAAW,QAAQ,MAAM,WAAW,MAAM,QAAQ,QAAQ,GAAG;AACnE,UAAI,YAAY,MAAM;AACpB,aAAK,QAAQ;AACb,YAAI,iBAAiB,YAAY;AAC/B,gBAAM,QAAQ,QAAQ,KAAK,MAAM,WAAW,MAAM,OAAO,CAAC;AAAA,MAC9D,WAAW,eAAe;AACxB,cAAM,QAAQ,MAAM,WAAW,KAAK,QAAQ;AAC5C,YAAI,OAAO,kBAAkB;AAC3B,eAAK,QAAQ,cAAc,OAAO,OAAO;AAAA,iBAClC,SAAS,YAAY,CAAC,MAAM,QAAQ,KAAK;AAChD,eAAK,QAAQ,EAAE,GAAG,SAAS,GAAG,MAAM;AAAA,YACjC,MAAK,QAAQ;AAAA,MACpB,OAAO;AACL,aAAK,QAAQ,MAAM,WAAW,KAAK,QAAQ;AAAA,MAC7C;AAAA,IACF,SAAS,GAAG;AACV,cAAQ,CAAC;AAAA,IACX;AAAA,EACF;AACA,OAAK;AACL,MAAIA,WAAU;AACZ,qBAAiBA,SAAQ,WAAW,CAAC,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,KAAK,CAAC,CAAC,GAAG,EAAE,SAAS,KAAK,CAAC;AACrG,MAAI,SAAS;AACX;AAAA,MACE;AAAA,MACA,YAAY;AACV,YAAI;AACF,cAAI,KAAK,SAAS;AAChB,kBAAM,QAAQ,WAAW,GAAG;AAAA;AAE5B,kBAAM,QAAQ,QAAQ,KAAK,MAAM,WAAW,MAAM,KAAK,KAAK,CAAC;AAAA,QACjE,SAAS,GAAG;AACV,kBAAQ,CAAC;AAAA,QACX;AAAA,MACF;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAI,MAAM;AACV,SAAS,YAAY,KAAK,UAAU,CAAC,GAAG;AACtC,QAAM,WAAW,WAAW,KAAK;AACjC,QAAM;AAAA,IACJ,UAAAC,YAAW;AAAA,IACX,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,KAAK,mBAAmB,EAAE,GAAG;AAAA,EAC/B,IAAI;AACJ,QAAM,SAAS,WAAW,GAAG;AAC7B,MAAI,OAAO,MAAM;AAAA,EACjB;AACA,QAAM,OAAO,MAAM;AACjB,QAAI,CAACA;AACH;AACF,UAAM,KAAKA,UAAS,eAAe,EAAE,KAAKA,UAAS,cAAc,OAAO;AACxE,QAAI,CAAC,GAAG,aAAa;AACnB,SAAG,KAAK;AACR,UAAI,QAAQ;AACV,WAAG,QAAQ,QAAQ;AACrB,MAAAA,UAAS,KAAK,YAAY,EAAE;AAAA,IAC9B;AACA,QAAI,SAAS;AACX;AACF,WAAO;AAAA,MACL;AAAA,MACA,CAAC,UAAU;AACT,WAAG,cAAc;AAAA,MACnB;AAAA,MACA,EAAE,WAAW,KAAK;AAAA,IACpB;AACA,aAAS,QAAQ;AAAA,EACnB;AACA,QAAM,SAAS,MAAM;AACnB,QAAI,CAACA,aAAY,CAAC,SAAS;AACzB;AACF,SAAK;AACL,IAAAA,UAAS,KAAK,YAAYA,UAAS,eAAe,EAAE,CAAC;AACrD,aAAS,QAAQ;AAAA,EACnB;AACA,MAAI,aAAa,CAAC;AAChB,iBAAa,IAAI;AACnB,MAAI,CAAC;AACH,sBAAkB,MAAM;AAC1B,SAAO;AAAA,IACL;AAAA,IACA,KAAK;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,SAAS,QAAQ;AAAA,EAC7B;AACF;AAEA,SAAS,SAAS,QAAQ,UAAU,CAAC,GAAG;AACtC,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,EACZ,IAAI;AACJ,QAAM,cAAc,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AAC3C,QAAM,YAAY,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AACzC,QAAM,QAAQ,SAAS,MAAM,YAAY,IAAI,UAAU,CAAC;AACxD,QAAM,QAAQ,SAAS,MAAM,YAAY,IAAI,UAAU,CAAC;AACxD,QAAM,EAAE,KAAK,IAAI,IAAI;AACrB,QAAM,sBAAsB,SAAS,MAAM,IAAI,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,CAAC,KAAK,SAAS;AAC/F,QAAM,YAAY,WAAW,KAAK;AAClC,QAAM,YAAY,SAAS,MAAM;AAC/B,QAAI,CAAC,oBAAoB;AACvB,aAAO;AACT,QAAI,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,GAAG;AACvC,aAAO,MAAM,QAAQ,IAAI,SAAS;AAAA,IACpC,OAAO;AACL,aAAO,MAAM,QAAQ,IAAI,OAAO;AAAA,IAClC;AAAA,EACF,CAAC;AACD,QAAM,sBAAsB,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,OAAO;AAC9E,QAAM,oBAAoB,CAAC,GAAG,MAAM;AAClC,gBAAY,IAAI;AAChB,gBAAY,IAAI;AAAA,EAClB;AACA,QAAM,kBAAkB,CAAC,GAAG,MAAM;AAChC,cAAU,IAAI;AACd,cAAU,IAAI;AAAA,EAChB;AACA,QAAM,kBAAkB,EAAE,SAAS,SAAS,CAAC,QAAQ;AACrD,QAAM,aAAa,CAAC,MAAM;AACxB,QAAI,UAAU;AACZ,oBAAc,OAAO,SAAS,WAAW,GAAG,UAAU,KAAK;AAC7D,cAAU,QAAQ;AAAA,EACpB;AACA,QAAM,QAAQ;AAAA,IACZ,iBAAiB,QAAQ,cAAc,CAAC,MAAM;AAC5C,UAAI,EAAE,QAAQ,WAAW;AACvB;AACF,YAAM,CAAC,GAAG,CAAC,IAAI,oBAAoB,CAAC;AACpC,wBAAkB,GAAG,CAAC;AACtB,sBAAgB,GAAG,CAAC;AACpB,sBAAgB,OAAO,SAAS,aAAa,CAAC;AAAA,IAChD,GAAG,eAAe;AAAA,IAClB,iBAAiB,QAAQ,aAAa,CAAC,MAAM;AAC3C,UAAI,EAAE,QAAQ,WAAW;AACvB;AACF,YAAM,CAAC,GAAG,CAAC,IAAI,oBAAoB,CAAC;AACpC,sBAAgB,GAAG,CAAC;AACpB,UAAI,gBAAgB,WAAW,CAAC,gBAAgB,WAAW,KAAK,IAAI,MAAM,KAAK,IAAI,KAAK,IAAI,MAAM,KAAK;AACrG,UAAE,eAAe;AACnB,UAAI,CAAC,UAAU,SAAS,oBAAoB;AAC1C,kBAAU,QAAQ;AACpB,UAAI,UAAU;AACZ,mBAAW,OAAO,SAAS,QAAQ,CAAC;AAAA,IACxC,GAAG,eAAe;AAAA,IAClB,iBAAiB,QAAQ,CAAC,YAAY,aAAa,GAAG,YAAY,eAAe;AAAA,EACnF;AACA,QAAM,OAAO,MAAM,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC3C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT,SAAS;AAAA,IACT;AAAA;AAAA,IAEA,yBAAyB;AAAA,EAC3B;AACF;AAEA,SAAS,sBAAsB;AAC7B,QAAM,OAAO,IAAI,CAAC,CAAC;AACnB,OAAK,MAAM,MAAM,CAAC,OAAO;AACvB,QAAI;AACF,WAAK,MAAM,KAAK,EAAE;AAAA,EACtB;AACA,iBAAe,MAAM;AACnB,SAAK,MAAM,SAAS;AAAA,EACtB,CAAC;AACD,SAAO;AACT;AAEA,SAAS,iBAAiB,UAAU,CAAC,GAAG;AACtC,QAAM;AAAA,IACJ,UAAAA,YAAW;AAAA,IACX,WAAW;AAAA,IACX,UAAU;AAAA,IACV,eAAe;AAAA,EACjB,IAAI;AACJ,WAASI,YAAW;AAClB,QAAI,IAAI;AACR,YAAQ,MAAM,KAAKJ,aAAY,OAAO,SAASA,UAAS,cAAc,QAAQ,MAAM,OAAO,SAAS,GAAG,aAAa,KAAK,MAAM,OAAO,KAAK;AAAA,EAC7I;AACA,QAAM,MAAM,IAAII,UAAS,CAAC;AAC1B,eAAa,MAAM,IAAI,QAAQA,UAAS,CAAC;AACzC,MAAI,WAAWJ,WAAU;AACvB;AAAA,MACEA,UAAS,cAAc,QAAQ;AAAA,MAC/B,MAAM,IAAI,QAAQI,UAAS;AAAA,MAC3B,EAAE,YAAY,KAAK;AAAA,IACrB;AAAA,EACF;AACA,SAAO,SAAS;AAAA,IACd,MAAM;AACJ,aAAO,IAAI;AAAA,IACb;AAAA,IACA,IAAI,GAAG;AACL,UAAI,IAAI;AACR,UAAI,QAAQ;AACZ,UAAI,CAACJ;AACH;AACF,UAAI,IAAI;AACN,SAAC,KAAKA,UAAS,cAAc,QAAQ,MAAM,OAAO,SAAS,GAAG,aAAa,OAAO,IAAI,KAAK;AAAA;AAE3F,SAAC,KAAKA,UAAS,cAAc,QAAQ,MAAM,OAAO,SAAS,GAAG,gBAAgB,KAAK;AAAA,IACvF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,uBAAuB,WAAW;AACzC,MAAI;AACJ,QAAM,cAAc,KAAK,UAAU,eAAe,OAAO,KAAK;AAC9D,SAAO,MAAM,KAAK,EAAE,QAAQ,WAAW,GAAG,CAAC,GAAG,MAAM,UAAU,WAAW,CAAC,CAAC;AAC7E;AACA,SAAS,iBAAiB,UAAU,CAAC,GAAG;AACtC,QAAM;AAAA,IACJ,QAAAD,UAAS;AAAA,EACX,IAAI;AACJ,QAAM,YAAY,IAAI,IAAI;AAC1B,QAAM,OAAO,SAAS,MAAM;AAC1B,QAAI,IAAI;AACR,YAAQ,MAAM,KAAK,UAAU,UAAU,OAAO,SAAS,GAAG,SAAS,MAAM,OAAO,KAAK;AAAA,EACvF,CAAC;AACD,QAAM,SAAS,SAAS,MAAM,UAAU,QAAQ,uBAAuB,UAAU,KAAK,IAAI,CAAC,CAAC;AAC5F,QAAM,QAAQ,SAAS,MAAM,OAAO,MAAM,IAAI,CAAC,UAAU,MAAM,sBAAsB,CAAC,CAAC;AACvF,WAAS,oBAAoB;AAC3B,cAAU,QAAQ;AAClB,QAAIA;AACF,gBAAU,QAAQA,QAAO,aAAa;AAAA,EAC1C;AACA,MAAIA;AACF,qBAAiBA,QAAO,UAAU,mBAAmB,mBAAmB,EAAE,SAAS,KAAK,CAAC;AAC3F,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,yBAAyBA,UAAS,eAAe,IAAI;AAC5D,MAAIA,WAAU,OAAOA,QAAO,0BAA0B,YAAY;AAChE,IAAAA,QAAO,sBAAsB,EAAE;AAAA,EACjC,OAAO;AACL,OAAG;AAAA,EACL;AACF;AACA,SAAS,oBAAoB,UAAU,CAAC,GAAG;AACzC,MAAI,IAAI;AACR,QAAM,EAAE,QAAAA,UAAS,cAAc,IAAI;AACnC,QAAM,WAAWQ,OAAM,WAAW,OAAO,SAAS,QAAQ,OAAO;AACjE,QAAM,QAAQA,QAAO,KAAK,WAAW,OAAO,SAAS,QAAQ,UAAU,OAAO,KAAK,EAAE;AACrF,QAAM,aAAa,KAAK,WAAW,OAAO,SAAS,QAAQ,cAAc,OAAO,KAAK;AACrF,QAAM,uBAAuB,WAAW,CAAC;AACzC,QAAM,mBAAmB,WAAW,CAAC;AACrC,WAAS,gBAAgB;AACvB,QAAI;AACJ,QAAI,CAAC,SAAS;AACZ;AACF,QAAI,SAAS;AACb,aAAS,MAAM,MAAM,SAAS,IAAI;AAClC,yBAAqB,SAAS,MAAM,SAAS,UAAU,OAAO,SAAS,IAAI;AAC3E,UAAM,eAAe,QAAQ,WAAW,OAAO,SAAS,QAAQ,WAAW;AAC3E,QAAI;AACF,mBAAa,MAAM,SAAS,IAAI,GAAG,qBAAqB,KAAK;AAAA;AAE7D,eAAS,GAAG,qBAAqB,KAAK;AACxC,aAAS,MAAM,MAAM,SAAS,IAAI;AAAA,EACpC;AACA,QAAM,CAAC,OAAO,QAAQ,GAAG,MAAM,SAAS,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;AAC3E,QAAM,sBAAsB,MAAM;AAChC,QAAI;AACJ,YAAQ,MAAM,WAAW,OAAO,SAAS,QAAQ,aAAa,OAAO,SAAS,IAAI,KAAK,OAAO;AAAA,EAChG,CAAC;AACD,oBAAkB,UAAU,CAAC,CAAC,EAAE,YAAY,CAAC,MAAM;AACjD,QAAI,iBAAiB,UAAU,YAAY;AACzC;AACF,6BAAyBR,SAAQ,MAAM;AACrC,uBAAiB,QAAQ,YAAY;AACrC,oBAAc;AAAA,IAChB,CAAC;AAAA,EACH,CAAC;AACD,MAAI,WAAW,OAAO,SAAS,QAAQ;AACrC,UAAM,QAAQ,OAAO,eAAe,EAAE,WAAW,MAAM,MAAM,KAAK,CAAC;AACrE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,QAAQ,UAAU,CAAC,GAAG;AACpD,QAAM,EAAE,WAAW,KAAK,WAAW,KAAK,IAAI;AAC5C,QAAM,SAAS,eAAe,UAAU,QAAQ;AAChD,QAAM,UAAU,cAAc,QAAQ,EAAE,GAAG,SAAS,aAAa,OAAO,CAAC;AACzE,SAAO;AAAA,IACL,GAAG;AAAA,EACL;AACF;AAEA,IAAM,gBAAgB;AAAA,EACpB,EAAE,KAAK,KAAK,OAAO,KAAK,MAAM,SAAS;AAAA,EACvC,EAAE,KAAK,OAAO,OAAO,KAAK,MAAM,SAAS;AAAA,EACzC,EAAE,KAAK,MAAM,OAAO,MAAM,MAAM,OAAO;AAAA,EACvC,EAAE,KAAK,QAAQ,OAAO,OAAO,MAAM,MAAM;AAAA,EACzC,EAAE,KAAK,SAAS,OAAO,QAAQ,MAAM,OAAO;AAAA,EAC5C,EAAE,KAAK,SAAS,OAAO,QAAQ,MAAM,QAAQ;AAAA,EAC7C,EAAE,KAAK,OAAO,mBAAmB,OAAO,SAAS,MAAM,OAAO;AAChE;AACA,IAAM,mBAAmB;AAAA,EACvB,SAAS;AAAA,EACT,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,GAAG,CAAC,SAAS;AAAA,EAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK;AAAA,EAC3C,OAAO,CAAC,GAAG,SAAS,MAAM,IAAI,OAAO,eAAe,eAAe,GAAG,CAAC,SAAS,IAAI,IAAI,MAAM,EAAE;AAAA,EAChG,MAAM,CAAC,GAAG,SAAS,MAAM,IAAI,OAAO,cAAc,cAAc,GAAG,CAAC,QAAQ,IAAI,IAAI,MAAM,EAAE;AAAA,EAC5F,KAAK,CAAC,GAAG,SAAS,MAAM,IAAI,OAAO,cAAc,aAAa,GAAG,CAAC,OAAO,IAAI,IAAI,MAAM,EAAE;AAAA,EACzF,MAAM,CAAC,GAAG,SAAS,MAAM,IAAI,OAAO,cAAc,cAAc,GAAG,CAAC,QAAQ,IAAI,IAAI,MAAM,EAAE;AAAA,EAC5F,MAAM,CAAC,MAAM,GAAG,CAAC,QAAQ,IAAI,IAAI,MAAM,EAAE;AAAA,EACzC,QAAQ,CAAC,MAAM,GAAG,CAAC,UAAU,IAAI,IAAI,MAAM,EAAE;AAAA,EAC7C,QAAQ,CAAC,MAAM,GAAG,CAAC,UAAU,IAAI,IAAI,MAAM,EAAE;AAAA,EAC7C,SAAS;AACX;AACA,SAAS,kBAAkB,MAAM;AAC/B,SAAO,KAAK,YAAY,EAAE,MAAM,GAAG,EAAE;AACvC;AACA,SAAS,WAAW,MAAM,UAAU,CAAC,GAAG;AACtC,QAAM;AAAA,IACJ,UAAU,iBAAiB;AAAA,IAC3B,iBAAiB;AAAA,EACnB,IAAI;AACJ,QAAM,EAAE,KAAAa,MAAK,GAAG,SAAS,IAAI,OAAO,EAAE,UAAU,gBAAgB,UAAU,KAAK,CAAC;AAChF,QAAM,UAAU,SAAS,MAAM,cAAc,IAAI,KAAK,QAAQ,IAAI,CAAC,GAAG,SAAS,QAAQA,IAAG,CAAC,CAAC;AAC5F,MAAI,gBAAgB;AAClB,WAAO;AAAA,MACL;AAAA,MACA,GAAG;AAAA,IACL;AAAA,EACF,OAAO;AACL,WAAO;AAAA,EACT;AACF;AACA,SAAS,cAAc,MAAM,UAAU,CAAC,GAAGA,OAAM,KAAK,IAAI,GAAG;AAC3D,MAAI;AACJ,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,oBAAoB;AAAA,IACpB,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,WAAW;AAAA,EACb,IAAI;AACJ,QAAM,UAAU,OAAO,aAAa,WAAW,CAAC,MAAM,CAAC,EAAE,QAAQ,QAAQ,IAAI,KAAK,QAAQ;AAC1F,QAAM,OAAO,CAACA,OAAM,CAAC;AACrB,QAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,WAASR,UAAS,OAAO,MAAM;AAC7B,WAAO,QAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK;AAAA,EAC7C;AACA,WAAS,OAAO,OAAO,MAAM;AAC3B,UAAM,MAAMA,UAAS,OAAO,IAAI;AAChC,UAAM,OAAO,QAAQ;AACrB,UAAM,MAAM,YAAY,KAAK,MAAM,KAAK,IAAI;AAC5C,WAAO,YAAY,OAAO,SAAS,UAAU,KAAK,IAAI;AAAA,EACxD;AACA,WAAS,YAAY,MAAM,KAAK,QAAQ;AACtC,UAAM,YAAY,SAAS,IAAI;AAC/B,QAAI,OAAO,cAAc;AACvB,aAAO,UAAU,KAAK,MAAM;AAC9B,WAAO,UAAU,QAAQ,OAAO,IAAI,SAAS,CAAC;AAAA,EAChD;AACA,MAAI,UAAU,OAAO,CAAC;AACpB,WAAO,SAAS;AAClB,MAAI,OAAO,QAAQ,YAAY,UAAU;AACvC,WAAO,kBAAkB,IAAI,KAAK,IAAI,CAAC;AACzC,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,WAAW,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,OAAO,SAAS,GAAG;AAC/E,QAAI,WAAW,UAAU;AACvB,aAAO,kBAAkB,IAAI,KAAK,IAAI,CAAC;AAAA,EAC3C;AACA,aAAW,CAAC,KAAK,IAAI,KAAK,MAAM,QAAQ,GAAG;AACzC,UAAM,MAAMA,UAAS,MAAM,IAAI;AAC/B,QAAI,OAAO,KAAK,MAAM,MAAM,CAAC;AAC3B,aAAO,OAAO,MAAM,MAAM,MAAM,CAAC,CAAC;AACpC,QAAI,UAAU,KAAK;AACjB,aAAO,OAAO,MAAM,IAAI;AAAA,EAC5B;AACA,SAAO,SAAS;AAClB;AAEA,SAAS,eAAe,IAAI,UAAU,UAAU,CAAC,GAAG;AAClD,QAAM;AAAA,IACJ,YAAY;AAAA,IACZ,oBAAoB;AAAA,EACtB,IAAI;AACJ,QAAM,EAAE,MAAM,IAAI,aAAa,MAAM,UAAU,EAAE,UAAU,CAAC;AAC5D,QAAM,WAAW,WAAW,KAAK;AACjC,iBAAe,OAAO;AACpB,QAAI,CAAC,SAAS;AACZ;AACF,UAAM,GAAG;AACT,UAAM;AAAA,EACR;AACA,WAAS,SAAS;AAChB,QAAI,CAAC,SAAS,OAAO;AACnB,eAAS,QAAQ;AACjB,UAAI;AACF,WAAG;AACL,YAAM;AAAA,IACR;AAAA,EACF;AACA,WAAS,QAAQ;AACf,aAAS,QAAQ;AAAA,EACnB;AACA,MAAI,aAAa;AACf,WAAO;AACT,oBAAkB,KAAK;AACvB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,aAAa,UAAU,CAAC,GAAG;AAClC,QAAM;AAAA,IACJ,UAAU,iBAAiB;AAAA,IAC3B,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,WAAW;AAAA,IACX;AAAA,EACF,IAAI;AACJ,QAAM,KAAK,WAAW,UAAU,IAAI,MAAM;AAC1C,QAAM,SAAS,MAAM,GAAG,QAAQ,UAAU,IAAI;AAC9C,QAAM,KAAK,WAAW,MAAM;AAC1B,WAAO;AACP,aAAS,GAAG,KAAK;AAAA,EACnB,IAAI;AACJ,QAAM,WAAW,aAAa,0BAA0B,SAAS,IAAI,EAAE,UAAU,CAAC,IAAI,cAAc,IAAI,UAAU,EAAE,UAAU,CAAC;AAC/H,MAAI,gBAAgB;AAClB,WAAO;AAAA,MACL,WAAW;AAAA,MACX,GAAG;AAAA,IACL;AAAA,EACF,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEA,SAAS,SAAS,WAAW,MAAM,UAAU,CAAC,GAAG;AAC/C,MAAI,IAAI,IAAI;AACZ,QAAM;AAAA,IACJ,UAAAJ,YAAW;AAAA,IACX,mBAAmB,CAAC,MAAM;AAAA,EAC5B,IAAI;AACJ,QAAM,iBAAiB,KAAKA,aAAY,OAAO,SAASA,UAAS,UAAU,OAAO,KAAK;AACvF,QAAM,QAAQO,QAAO,KAAK,YAAY,OAAO,WAAWP,aAAY,OAAO,SAASA,UAAS,UAAU,OAAO,KAAK,IAAI;AACvH,QAAMe,cAAa,CAAC,EAAE,YAAY,OAAO,aAAa;AACtD,WAAS,OAAO,GAAG;AACjB,QAAI,EAAE,mBAAmB;AACvB,aAAO;AACT,UAAM,WAAW,QAAQ,iBAAiB;AAC1C,WAAO,OAAO,aAAa,aAAa,SAAS,CAAC,IAAI,QAAQ,QAAQ,EAAE,QAAQ,OAAO,CAAC;AAAA,EAC1F;AACA;AAAA,IACE;AAAA,IACA,CAAC,UAAU,aAAa;AACtB,UAAI,aAAa,YAAYf;AAC3B,QAAAA,UAAS,QAAQ,OAAO,YAAY,OAAO,WAAW,EAAE;AAAA,IAC5D;AAAA,IACA,EAAE,WAAW,KAAK;AAAA,EACpB;AACA,MAAI,QAAQ,WAAW,CAAC,QAAQ,iBAAiBA,aAAY,CAACe,aAAY;AACxE;AAAA,OACG,KAAKf,UAAS,SAAS,OAAO,SAAS,GAAG,cAAc,OAAO;AAAA,MAChE,MAAM;AACJ,YAAIA,aAAYA,UAAS,UAAU,MAAM;AACvC,gBAAM,QAAQ,OAAOA,UAAS,KAAK;AAAA,MACvC;AAAA,MACA,EAAE,WAAW,KAAK;AAAA,IACpB;AAAA,EACF;AACA,oBAAkB,MAAM;AACtB,QAAI,kBAAkB;AACpB,YAAM,gBAAgB,iBAAiB,eAAe,MAAM,SAAS,EAAE;AACvE,UAAI,iBAAiB,QAAQA;AAC3B,QAAAA,UAAS,QAAQ;AAAA,IACrB;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAEA,IAAM,qBAAqB;AAAA,EACzB,YAAY,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EAC7B,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EAC9B,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EAChC,YAAY,CAAC,MAAM,GAAG,KAAK,CAAC;AAAA,EAC5B,aAAa,CAAC,KAAK,GAAG,MAAM,CAAC;AAAA,EAC7B,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EAChC,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EAC9B,cAAc,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EAC/B,gBAAgB,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EACjC,aAAa,CAAC,KAAK,GAAG,MAAM,CAAC;AAAA,EAC7B,cAAc,CAAC,MAAM,GAAG,KAAK,CAAC;AAAA,EAC9B,gBAAgB,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EACjC,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EAC9B,cAAc,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EAC/B,gBAAgB,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EACjC,YAAY,CAAC,KAAK,GAAG,MAAM,CAAC;AAAA,EAC5B,aAAa,CAAC,MAAM,GAAG,KAAK,CAAC;AAAA,EAC7B,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EAChC,YAAY,CAAC,MAAM,GAAG,GAAG,IAAI;AAAA,EAC7B,aAAa,CAAC,GAAG,MAAM,MAAM,CAAC;AAAA,EAC9B,eAAe,CAAC,MAAM,GAAG,MAAM,CAAC;AAAA,EAChC,YAAY,CAAC,MAAM,GAAG,MAAM,KAAK;AAAA,EACjC,aAAa,CAAC,MAAM,MAAM,MAAM,CAAC;AAAA,EACjC,eAAe,CAAC,MAAM,MAAM,MAAM,GAAG;AACvC;AACA,IAAM,oBAAoC,OAAO,OAAO,CAAC,GAAG,EAAE,QAAQ,SAAS,GAAG,kBAAkB;AACpG,SAAS,qBAAqB,CAAC,IAAI,IAAI,IAAI,EAAE,GAAG;AAC9C,QAAM,IAAI,CAAC,IAAI,OAAO,IAAI,IAAI,KAAK,IAAI;AACvC,QAAM,IAAI,CAAC,IAAI,OAAO,IAAI,KAAK,IAAI;AACnC,QAAM,IAAI,CAAC,OAAO,IAAI;AACtB,QAAM,aAAa,CAAC,GAAG,IAAI,SAAS,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,EAAE,KAAK;AAC9E,QAAM,WAAW,CAAC,GAAG,IAAI,OAAO,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE;AAChF,QAAM,WAAW,CAAC,MAAM;AACtB,QAAI,UAAU;AACd,aAAS,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG;AAC1B,YAAM,eAAe,SAAS,SAAS,IAAI,EAAE;AAC7C,UAAI,iBAAiB;AACnB,eAAO;AACT,YAAM,WAAW,WAAW,SAAS,IAAI,EAAE,IAAI;AAC/C,iBAAW,WAAW;AAAA,IACxB;AACA,WAAO;AAAA,EACT;AACA,SAAO,CAAC,MAAM,OAAO,MAAM,OAAO,KAAK,IAAI,WAAW,SAAS,CAAC,GAAG,IAAI,EAAE;AAC3E;AACA,SAAS,KAAK,GAAG,GAAG,OAAO;AACzB,SAAO,IAAI,SAAS,IAAI;AAC1B;AACA,SAAS,MAAM,GAAG;AAChB,UAAQ,OAAO,MAAM,WAAW,CAAC,CAAC,IAAI,MAAM,CAAC;AAC/C;AACA,SAAS,kBAAkB,QAAQ,MAAM,IAAI,UAAU,CAAC,GAAG;AACzD,MAAI,IAAI;AACR,QAAM,UAAU,QAAQ,IAAI;AAC5B,QAAM,QAAQ,QAAQ,EAAE;AACxB,QAAM,KAAK,MAAM,OAAO;AACxB,QAAM,KAAK,MAAM,KAAK;AACtB,QAAM,YAAY,KAAK,QAAQ,QAAQ,QAAQ,MAAM,OAAO,KAAK;AACjE,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,QAAQ,KAAK,IAAI,IAAI;AAC3B,QAAM,QAAQ,OAAO,QAAQ,eAAe,aAAa,QAAQ,cAAc,KAAK,QAAQ,QAAQ,UAAU,MAAM,OAAO,KAAK;AAChI,QAAM,OAAO,OAAO,UAAU,aAAa,QAAQ,qBAAqB,KAAK;AAC7E,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,WAAO,QAAQ;AACf,UAAM,OAAO,MAAM;AACjB,UAAI;AACJ,WAAK,MAAM,QAAQ,UAAU,OAAO,SAAS,IAAI,KAAK,OAAO,GAAG;AAC9D,gBAAQ;AACR;AAAA,MACF;AACA,YAAMY,OAAM,KAAK,IAAI;AACrB,YAAM,QAAQ,MAAMA,OAAM,aAAa,QAAQ;AAC/C,YAAM,MAAM,MAAM,OAAO,KAAK,EAAE,IAAI,CAAC,GAAG,MAAM,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC;AACvE,UAAI,MAAM,QAAQ,OAAO,KAAK;AAC5B,eAAO,QAAQ,IAAI,IAAI,CAAC,GAAG,MAAM;AAC/B,cAAI,KAAK;AACT,iBAAO,MAAM,MAAM,GAAG,CAAC,MAAM,OAAO,MAAM,IAAI,MAAM,GAAG,CAAC,MAAM,OAAO,MAAM,GAAG,KAAK;AAAA,QACrF,CAAC;AAAA,eACM,OAAO,OAAO,UAAU;AAC/B,eAAO,QAAQ,IAAI,CAAC;AACtB,UAAIA,OAAM,OAAO;AACf,8BAAsB,IAAI;AAAA,MAC5B,OAAO;AACL,eAAO,QAAQ;AACf,gBAAQ;AAAA,MACV;AAAA,IACF;AACA,SAAK;AAAA,EACP,CAAC;AACH;AACA,SAAS,cAAc,QAAQ,UAAU,CAAC,GAAG;AAC3C,MAAI,YAAY;AAChB,QAAM,YAAY,MAAM;AACtB,UAAM,IAAI,QAAQ,MAAM;AACxB,WAAO,OAAO,MAAM,WAAW,IAAI,EAAE,IAAI,OAAO;AAAA,EAClD;AACA,QAAM,YAAY,IAAI,UAAU,CAAC;AACjC,QAAM,WAAW,OAAO,OAAO;AAC7B,QAAI,IAAI;AACR,QAAI,QAAQ,QAAQ,QAAQ;AAC1B;AACF,UAAM,KAAK,EAAE;AACb,QAAI,QAAQ;AACV,YAAM,eAAe,QAAQ,QAAQ,KAAK,CAAC;AAC7C,QAAI,OAAO;AACT;AACF,UAAM,QAAQ,MAAM,QAAQ,EAAE,IAAI,GAAG,IAAI,OAAO,IAAI,QAAQ,EAAE;AAC9D,KAAC,KAAK,QAAQ,cAAc,OAAO,SAAS,GAAG,KAAK,OAAO;AAC3D,UAAM,kBAAkB,WAAW,UAAU,OAAO,OAAO;AAAA,MACzD,GAAG;AAAA,MACH,OAAO,MAAM;AACX,YAAI;AACJ,eAAO,OAAO,eAAe,MAAM,QAAQ,UAAU,OAAO,SAAS,IAAI,KAAK,OAAO;AAAA,MACvF;AAAA,IACF,CAAC;AACD,KAAC,KAAK,QAAQ,eAAe,OAAO,SAAS,GAAG,KAAK,OAAO;AAAA,EAC9D,GAAG,EAAE,MAAM,KAAK,CAAC;AACjB,QAAM,MAAM,QAAQ,QAAQ,QAAQ,GAAG,CAAC,aAAa;AACnD,QAAI,UAAU;AACZ;AACA,gBAAU,QAAQ,UAAU;AAAA,IAC9B;AAAA,EACF,CAAC;AACD,oBAAkB,MAAM;AACtB;AAAA,EACF,CAAC;AACD,SAAO,SAAS,MAAM,QAAQ,QAAQ,QAAQ,IAAI,UAAU,IAAI,UAAU,KAAK;AACjF;AAEA,SAAS,mBAAmB,OAAO,WAAW,UAAU,CAAC,GAAG;AAC1D,QAAM;AAAA,IACJ,eAAe,CAAC;AAAA,IAChB,sBAAsB;AAAA,IACtB,oBAAoB;AAAA,IACpB,OAAO,cAAc;AAAA,IACrB,YAAY;AAAA,IACZ,QAAAb,UAAS;AAAA,EACX,IAAI;AACJ,MAAI,CAACA;AACH,WAAO,SAAS,YAAY;AAC9B,QAAM,QAAQ,SAAS,CAAC,CAAC;AACzB,WAAS,eAAe;AACtB,QAAI,SAAS,WAAW;AACtB,aAAOA,QAAO,SAAS,UAAU;AAAA,IACnC,WAAW,SAAS,QAAQ;AAC1B,YAAM,OAAOA,QAAO,SAAS,QAAQ;AACrC,YAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,aAAO,QAAQ,IAAI,KAAK,MAAM,KAAK,IAAI;AAAA,IACzC,OAAO;AACL,cAAQA,QAAO,SAAS,QAAQ,IAAI,QAAQ,MAAM,EAAE;AAAA,IACtD;AAAA,EACF;AACA,WAAS,eAAe,QAAQ;AAC9B,UAAM,cAAc,OAAO,SAAS;AACpC,QAAI,SAAS;AACX,aAAO,GAAG,cAAc,IAAI,WAAW,KAAK,EAAE,GAAGA,QAAO,SAAS,QAAQ,EAAE;AAC7E,QAAI,SAAS;AACX,aAAO,GAAGA,QAAO,SAAS,UAAU,EAAE,GAAG,cAAc,IAAI,WAAW,KAAK,EAAE;AAC/E,UAAM,OAAOA,QAAO,SAAS,QAAQ;AACrC,UAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,QAAI,QAAQ;AACV,aAAO,GAAGA,QAAO,SAAS,UAAU,EAAE,GAAG,KAAK,MAAM,GAAG,KAAK,CAAC,GAAG,cAAc,IAAI,WAAW,KAAK,EAAE;AACtG,WAAO,GAAGA,QAAO,SAAS,UAAU,EAAE,GAAG,IAAI,GAAG,cAAc,IAAI,WAAW,KAAK,EAAE;AAAA,EACtF;AACA,WAAS,OAAO;AACd,WAAO,IAAI,gBAAgB,aAAa,CAAC;AAAA,EAC3C;AACA,WAAS,YAAY,QAAQ;AAC3B,UAAM,aAAa,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC;AAC7C,eAAW,OAAO,OAAO,KAAK,GAAG;AAC/B,YAAM,eAAe,OAAO,OAAO,GAAG;AACtC,YAAM,GAAG,IAAI,aAAa,SAAS,IAAI,eAAe,OAAO,IAAI,GAAG,KAAK;AACzE,iBAAW,OAAO,GAAG;AAAA,IACvB;AACA,UAAM,KAAK,UAAU,EAAE,QAAQ,CAAC,QAAQ,OAAO,MAAM,GAAG,CAAC;AAAA,EAC3D;AACA,QAAM,EAAE,OAAO,OAAO,IAAI;AAAA,IACxB;AAAA,IACA,MAAM;AACJ,YAAM,SAAS,IAAI,gBAAgB,EAAE;AACrC,aAAO,KAAK,KAAK,EAAE,QAAQ,CAAC,QAAQ;AAClC,cAAM,WAAW,MAAM,GAAG;AAC1B,YAAI,MAAM,QAAQ,QAAQ;AACxB,mBAAS,QAAQ,CAAC,UAAU,OAAO,OAAO,KAAK,KAAK,CAAC;AAAA,iBAC9C,uBAAuB,YAAY;AAC1C,iBAAO,OAAO,GAAG;AAAA,iBACV,qBAAqB,CAAC;AAC7B,iBAAO,OAAO,GAAG;AAAA;AAEjB,iBAAO,IAAI,KAAK,QAAQ;AAAA,MAC5B,CAAC;AACD,YAAM,QAAQ,KAAK;AAAA,IACrB;AAAA,IACA,EAAE,MAAM,KAAK;AAAA,EACf;AACA,WAAS,MAAM,QAAQ,cAAc;AACnC,UAAM;AACN,QAAI;AACF,kBAAY,MAAM;AACpB,QAAI,cAAc,WAAW;AAC3B,MAAAA,QAAO,QAAQ;AAAA,QACbA,QAAO,QAAQ;AAAA,QACfA,QAAO,SAAS;AAAA,QAChBA,QAAO,SAAS,WAAW,eAAe,MAAM;AAAA,MAClD;AAAA,IACF,OAAO;AACL,MAAAA,QAAO,QAAQ;AAAA,QACbA,QAAO,QAAQ;AAAA,QACfA,QAAO,SAAS;AAAA,QAChBA,QAAO,SAAS,WAAW,eAAe,MAAM;AAAA,MAClD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,WAAS,YAAY;AACnB,QAAI,CAAC;AACH;AACF,UAAM,KAAK,GAAG,IAAI;AAAA,EACpB;AACA,QAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,mBAAiBA,SAAQ,YAAY,WAAW,eAAe;AAC/D,MAAI,SAAS;AACX,qBAAiBA,SAAQ,cAAc,WAAW,eAAe;AACnE,QAAM,UAAU,KAAK;AACrB,MAAI,QAAQ,KAAK,EAAE,KAAK,EAAE;AACxB,gBAAY,OAAO;AAAA;AAEnB,WAAO,OAAO,OAAO,YAAY;AACnC,SAAO;AACT;AAEA,SAAS,aAAa,UAAU,CAAC,GAAG;AAClC,MAAI,IAAI;AACR,QAAM,UAAU,YAAY,KAAK,QAAQ,YAAY,OAAO,KAAK,KAAK;AACtE,QAAM,aAAa,YAAY,KAAK,QAAQ,eAAe,OAAO,KAAK,IAAI;AAC3E,QAAM,cAAc,IAAI,QAAQ,WAAW;AAC3C,QAAM,EAAE,WAAAG,aAAY,iBAAiB,IAAI;AACzC,QAAM,cAAc,aAAa,MAAM;AACrC,QAAI;AACJ,YAAQ,MAAMA,cAAa,OAAO,SAASA,WAAU,iBAAiB,OAAO,SAAS,IAAI;AAAA,EAC5F,CAAC;AACD,QAAM,SAAS,WAAW;AAC1B,WAAS,iBAAiB,MAAM;AAC9B,YAAQ,MAAM;AAAA,MACZ,KAAK,SAAS;AACZ,YAAI,YAAY;AACd,iBAAO,YAAY,MAAM,SAAS;AACpC;AAAA,MACF;AAAA,MACA,KAAK,SAAS;AACZ,YAAI,YAAY;AACd,iBAAO,YAAY,MAAM,SAAS;AACpC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,iBAAe,SAAS;AACtB,QAAI,CAAC,YAAY,SAAS,OAAO;AAC/B;AACF,WAAO,QAAQ,MAAMA,WAAU,aAAa,aAAa;AAAA,MACvD,OAAO,iBAAiB,OAAO;AAAA,MAC/B,OAAO,iBAAiB,OAAO;AAAA,IACjC,CAAC;AACD,WAAO,OAAO;AAAA,EAChB;AACA,WAAS,QAAQ;AACf,QAAI;AACJ,KAAC,MAAM,OAAO,UAAU,OAAO,SAAS,IAAI,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;AAC/E,WAAO,QAAQ;AAAA,EACjB;AACA,WAAS,OAAO;AACd,UAAM;AACN,YAAQ,QAAQ;AAAA,EAClB;AACA,iBAAe,QAAQ;AACrB,UAAM,OAAO;AACb,QAAI,OAAO;AACT,cAAQ,QAAQ;AAClB,WAAO,OAAO;AAAA,EAChB;AACA,iBAAe,UAAU;AACvB,UAAM;AACN,WAAO,MAAM,MAAM;AAAA,EACrB;AACA;AAAA,IACE;AAAA,IACA,CAAC,MAAM;AACL,UAAI;AACF,eAAO;AAAA,UACJ,OAAM;AAAA,IACb;AAAA,IACA,EAAE,WAAW,KAAK;AAAA,EACpB;AACA;AAAA,IACE;AAAA,IACA,MAAM;AACJ,UAAI,WAAW,SAAS,OAAO;AAC7B,gBAAQ;AAAA,IACZ;AAAA,IACA,EAAE,WAAW,KAAK;AAAA,EACpB;AACA,oBAAkB,MAAM;AACtB,SAAK;AAAA,EACP,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,UAAU,OAAO,KAAK,MAAM,UAAU,CAAC,GAAG;AACjD,MAAI,IAAI,IAAI;AACZ,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,KAAK,mBAAmB;AAC9B,QAAM,QAAQ,SAAS,MAAM,OAAO,SAAS,GAAG,WAAW,KAAK,MAAM,OAAO,SAAS,GAAG,UAAU,OAAO,SAAS,GAAG,KAAK,EAAE,QAAQ,MAAM,KAAK,MAAM,OAAO,SAAS,GAAG,UAAU,OAAO,SAAS,GAAG,UAAU,OAAO,SAAS,GAAG,KAAK,MAAM,OAAO,SAAS,GAAG,KAAK;AACtQ,MAAI,QAAQ;AACZ,MAAI,CAAC,KAAK;AACR,UAAM;AAAA,EACR;AACA,UAAQ,SAAS,UAAU,IAAI,SAAS,CAAC;AACzC,QAAM,UAAU,CAAC,QAAQ,CAAC,QAAQ,MAAM,OAAO,UAAU,aAAa,MAAM,GAAG,IAAI,YAAY,GAAG;AAClG,QAAME,YAAW,MAAM,MAAM,MAAM,GAAG,CAAC,IAAI,QAAQ,MAAM,GAAG,CAAC,IAAI;AACjE,QAAM,cAAc,CAAC,UAAU;AAC7B,QAAI,YAAY;AACd,UAAI,WAAW,KAAK;AAClB,cAAM,OAAO,KAAK;AAAA,IACtB,OAAO;AACL,YAAM,OAAO,KAAK;AAAA,IACpB;AAAA,EACF;AACA,MAAI,SAAS;AACX,UAAM,eAAeA,UAAS;AAC9B,UAAM,QAAQ,IAAI,YAAY;AAC9B,QAAI,aAAa;AACjB;AAAA,MACE,MAAM,MAAM,GAAG;AAAA,MACf,CAAC,MAAM;AACL,YAAI,CAAC,YAAY;AACf,uBAAa;AACb,gBAAM,QAAQ,QAAQ,CAAC;AACvB,mBAAS,MAAM,aAAa,KAAK;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AACA;AAAA,MACE;AAAA,MACA,CAAC,MAAM;AACL,YAAI,CAAC,eAAe,MAAM,MAAM,GAAG,KAAK;AACtC,sBAAY,CAAC;AAAA,MACjB;AAAA,MACA,EAAE,KAAK;AAAA,IACT;AACA,WAAO;AAAA,EACT,OAAO;AACL,WAAO,SAAS;AAAA,MACd,MAAM;AACJ,eAAOA,UAAS;AAAA,MAClB;AAAA,MACA,IAAI,OAAO;AACT,oBAAY,KAAK;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,WAAW,OAAO,MAAM,UAAU,CAAC,GAAG;AAC7C,QAAM,MAAM,CAAC;AACb,aAAW,OAAO,OAAO;AACvB,QAAI,GAAG,IAAI;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,SAAS;AAC3B,QAAM;AAAA,IACJ,UAAU,CAAC;AAAA,IACX,WAAW;AAAA,IACX,WAAAF,aAAY;AAAA,EACd,IAAI,WAAW,CAAC;AAChB,QAAM,cAAc,aAAa,MAAM,OAAOA,eAAc,eAAe,aAAaA,UAAS;AACjG,QAAM,aAAaK,OAAM,OAAO;AAChC,MAAI;AACJ,QAAM,UAAU,CAAC,WAAW,WAAW,UAAU;AAC/C,QAAI,YAAY;AACd,MAAAL,WAAU,QAAQ,QAAQ;AAAA,EAC9B;AACA,QAAM,OAAO,MAAM;AACjB,QAAI,YAAY;AACd,MAAAA,WAAU,QAAQ,CAAC;AACrB,wBAAoB,OAAO,SAAS,iBAAiB,MAAM;AAAA,EAC7D;AACA,MAAI,WAAW,GAAG;AAChB,uBAAmB;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,QACE,WAAW;AAAA,QACX,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,eAAe,MAAM,SAAS;AACrC,QAAM,EAAE,gBAAgB,cAAc,UAAU,gBAAgB,aAAa,aAAa,IAAI,gBAAgB,UAAU,uBAAuB,SAAS,IAAI,IAAI,yBAAyB,SAAS,IAAI;AACtM,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,gBAAgB;AAAA,MACd,KAAK;AAAA,MACL,UAAU,MAAM;AACd,uBAAe;AAAA,MACjB;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;AACA,SAAS,wBAAwB,MAAM;AACrC,QAAM,eAAe,WAAW,IAAI;AACpC,QAAM,OAAO,eAAe,YAAY;AACxC,QAAM,cAAc,IAAI,CAAC,CAAC;AAC1B,QAAM,SAAS,WAAW,IAAI;AAC9B,QAAM,QAAQ,IAAI,EAAE,OAAO,GAAG,KAAK,GAAG,CAAC;AACvC,SAAO,EAAE,OAAO,QAAQ,aAAa,MAAM,aAAa;AAC1D;AACA,SAAS,sBAAsB,OAAO,QAAQ,UAAU;AACtD,SAAO,CAAC,kBAAkB;AACxB,QAAI,OAAO,aAAa;AACtB,aAAO,KAAK,KAAK,gBAAgB,QAAQ;AAC3C,UAAM,EAAE,QAAQ,EAAE,IAAI,MAAM;AAC5B,QAAI,MAAM;AACV,QAAI,WAAW;AACf,aAAS,IAAI,OAAO,IAAI,OAAO,MAAM,QAAQ,KAAK;AAChD,YAAM,OAAO,SAAS,CAAC;AACvB,aAAO;AACP,iBAAW;AACX,UAAI,MAAM;AACR;AAAA,IACJ;AACA,WAAO,WAAW;AAAA,EACpB;AACF;AACA,SAAS,gBAAgB,QAAQ,UAAU;AACzC,SAAO,CAAC,oBAAoB;AAC1B,QAAI,OAAO,aAAa;AACtB,aAAO,KAAK,MAAM,kBAAkB,QAAQ,IAAI;AAClD,QAAI,MAAM;AACV,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,OAAO,MAAM,QAAQ,KAAK;AAC5C,YAAM,OAAO,SAAS,CAAC;AACvB,aAAO;AACP,UAAI,OAAO,iBAAiB;AAC1B,iBAAS;AACT;AAAA,MACF;AAAA,IACF;AACA,WAAO,SAAS;AAAA,EAClB;AACF;AACA,SAAS,qBAAqB,MAAM,UAAU,WAAW,iBAAiB,EAAE,cAAc,OAAO,aAAa,OAAO,GAAG;AACtH,SAAO,MAAM;AACX,UAAM,UAAU,aAAa;AAC7B,QAAI,SAAS;AACX,YAAM,SAAS,UAAU,SAAS,aAAa,QAAQ,YAAY,QAAQ,UAAU;AACrF,YAAM,eAAe,gBAAgB,SAAS,aAAa,QAAQ,eAAe,QAAQ,WAAW;AACrG,YAAM,OAAO,SAAS;AACtB,YAAM,KAAK,SAAS,eAAe;AACnC,YAAM,QAAQ;AAAA,QACZ,OAAO,OAAO,IAAI,IAAI;AAAA,QACtB,KAAK,KAAK,OAAO,MAAM,SAAS,OAAO,MAAM,SAAS;AAAA,MACxD;AACA,kBAAY,QAAQ,OAAO,MAAM,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,KAAK,WAAW;AAAA,QAC9F,MAAM;AAAA,QACN,OAAO,QAAQ,MAAM,MAAM;AAAA,MAC7B,EAAE;AAAA,IACJ;AAAA,EACF;AACF;AACA,SAAS,kBAAkB,UAAU,QAAQ;AAC3C,SAAO,CAAC,UAAU;AAChB,QAAI,OAAO,aAAa,UAAU;AAChC,YAAM,QAAQ,QAAQ;AACtB,aAAO;AAAA,IACT;AACA,UAAM,OAAO,OAAO,MAAM,MAAM,GAAG,KAAK,EAAE,OAAO,CAAC,KAAK,GAAG,MAAM,MAAM,SAAS,CAAC,GAAG,CAAC;AACpF,WAAO;AAAA,EACT;AACF;AACA,SAAS,iBAAiB,MAAM,MAAM,cAAc,gBAAgB;AAClE,QAAM,CAAC,KAAK,OAAO,KAAK,QAAQ,MAAM,YAAY,GAAG,MAAM;AACzD,mBAAe;AAAA,EACjB,CAAC;AACH;AACA,SAAS,wBAAwB,UAAU,QAAQ;AACjD,SAAO,SAAS,MAAM;AACpB,QAAI,OAAO,aAAa;AACtB,aAAO,OAAO,MAAM,SAAS;AAC/B,WAAO,OAAO,MAAM,OAAO,CAAC,KAAK,GAAG,UAAU,MAAM,SAAS,KAAK,GAAG,CAAC;AAAA,EACxE,CAAC;AACH;AACA,IAAM,wCAAwC;AAAA,EAC5C,YAAY;AAAA,EACZ,UAAU;AACZ;AACA,SAAS,eAAe,MAAM,gBAAgB,aAAa,cAAc;AACvE,SAAO,CAAC,UAAU;AAChB,QAAI,aAAa,OAAO;AACtB,mBAAa,MAAM,sCAAsC,IAAI,CAAC,IAAI,YAAY,KAAK;AACnF,qBAAe;AAAA,IACjB;AAAA,EACF;AACF;AACA,SAAS,yBAAyB,SAAS,MAAM;AAC/C,QAAM,YAAY,wBAAwB,IAAI;AAC9C,QAAM,EAAE,OAAO,QAAQ,aAAa,MAAM,aAAa,IAAI;AAC3D,QAAM,iBAAiB,EAAE,WAAW,OAAO;AAC3C,QAAM,EAAE,WAAW,WAAW,EAAE,IAAI;AACpC,QAAM,kBAAkB,sBAAsB,OAAO,QAAQ,SAAS;AACtE,QAAM,YAAY,gBAAgB,QAAQ,SAAS;AACnD,QAAM,iBAAiB,qBAAqB,cAAc,UAAU,WAAW,iBAAiB,SAAS;AACzG,QAAM,kBAAkB,kBAAkB,WAAW,MAAM;AAC3D,QAAM,aAAa,SAAS,MAAM,gBAAgB,MAAM,MAAM,KAAK,CAAC;AACpE,QAAM,aAAa,wBAAwB,WAAW,MAAM;AAC5D,mBAAiB,MAAM,MAAM,cAAc,cAAc;AACzD,QAAM,WAAW,eAAe,cAAc,gBAAgB,iBAAiB,YAAY;AAC3F,QAAM,eAAe,SAAS,MAAM;AAClC,WAAO;AAAA,MACL,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO,GAAG,WAAW,QAAQ,WAAW,KAAK;AAAA,QAC7C,YAAY,GAAG,WAAW,KAAK;AAAA,QAC/B,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AACA,SAAS,uBAAuB,SAAS,MAAM;AAC7C,QAAM,YAAY,wBAAwB,IAAI;AAC9C,QAAM,EAAE,OAAO,QAAQ,aAAa,MAAM,aAAa,IAAI;AAC3D,QAAM,iBAAiB,EAAE,WAAW,OAAO;AAC3C,QAAM,EAAE,YAAY,WAAW,EAAE,IAAI;AACrC,QAAM,kBAAkB,sBAAsB,OAAO,QAAQ,UAAU;AACvE,QAAM,YAAY,gBAAgB,QAAQ,UAAU;AACpD,QAAM,iBAAiB,qBAAqB,YAAY,UAAU,WAAW,iBAAiB,SAAS;AACvG,QAAM,iBAAiB,kBAAkB,YAAY,MAAM;AAC3D,QAAM,YAAY,SAAS,MAAM,eAAe,MAAM,MAAM,KAAK,CAAC;AAClE,QAAM,cAAc,wBAAwB,YAAY,MAAM;AAC9D,mBAAiB,MAAM,MAAM,cAAc,cAAc;AACzD,QAAM,WAAW,eAAe,YAAY,gBAAgB,gBAAgB,YAAY;AACxF,QAAM,eAAe,SAAS,MAAM;AAClC,WAAO;AAAA,MACL,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ,GAAG,YAAY,QAAQ,UAAU,KAAK;AAAA,QAC9C,WAAW,GAAG,UAAU,KAAK;AAAA,MAC/B;AAAA,IACF;AAAA,EACF,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,YAAY,UAAU,CAAC,GAAG;AACjC,QAAM;AAAA,IACJ,WAAAA,aAAY;AAAA,IACZ,UAAAF,YAAW;AAAA,EACb,IAAI;AACJ,QAAM,gBAAgB,WAAW,KAAK;AACtC,QAAM,WAAW,WAAW,IAAI;AAChC,QAAM,qBAAqB,sBAAsB,EAAE,UAAAA,UAAS,CAAC;AAC7D,QAAM,cAAc,aAAa,MAAME,cAAa,cAAcA,UAAS;AAC3E,QAAM,WAAW,SAAS,MAAM,CAAC,CAAC,SAAS,SAAS,mBAAmB,UAAU,SAAS;AAC1F,MAAI,YAAY,OAAO;AACrB,qBAAiB,UAAU,WAAW,MAAM;AAC1C,UAAI,IAAI;AACR,oBAAc,SAAS,MAAM,KAAK,SAAS,UAAU,OAAO,SAAS,GAAG,SAAS,OAAO,KAAK;AAAA,IAC/F,GAAG,EAAE,SAAS,KAAK,CAAC;AACpB;AAAA,MACE,MAAM,mBAAmB,UAAU,cAAcF,aAAY,OAAO,SAASA,UAAS,qBAAqB,aAAa,cAAc;AAAA,MACtI,CAAC,SAAS;AACR,sBAAc,QAAQ;AACtB,qBAAa,IAAI;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AACA,iBAAe,aAAa,MAAM;AAChC,QAAI;AACJ,YAAQ,KAAK,SAAS,UAAU,OAAO,SAAS,GAAG,QAAQ;AAC3D,aAAS,QAAQ,YAAY,QAAQ,MAAME,WAAU,SAAS,QAAQ,IAAI,IAAI;AAAA,EAChF;AACA,iBAAe,QAAQ,MAAM;AAC3B,QAAI,mBAAmB,UAAU;AAC/B,YAAM,aAAa,IAAI;AAAA;AAEvB,oBAAc,QAAQ;AAAA,EAC1B;AACA,iBAAe,UAAU;AACvB,kBAAc,QAAQ;AACtB,UAAM,IAAI,SAAS;AACnB,aAAS,QAAQ;AACjB,WAAO,KAAK,OAAO,SAAS,EAAE,QAAQ;AAAA,EACxC;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,UAAU,CAAC,GAAG;AACxC,QAAM;AAAA,IACJ,QAAAH,UAAS;AAAA,IACT,oBAAoB,yBAAyB;AAAA,EAC/C,IAAI;AACJ,QAAM,gCAAgC;AACtC,QAAM,cAAc,aAAa,MAAM;AACrC,QAAI,CAACA,WAAU,EAAE,kBAAkBA;AACjC,aAAO;AACT,QAAI,aAAa,eAAe;AAC9B,aAAO;AACT,QAAI;AACF,YAAM,gBAAgB,IAAI,aAAa,EAAE;AACzC,oBAAc,SAAS,MAAM;AAC3B,sBAAc,MAAM;AAAA,MACtB;AAAA,IACF,SAAS,GAAG;AACV,UAAI,EAAE,SAAS;AACb,eAAO;AAAA,IACX;AACA,WAAO;AAAA,EACT,CAAC;AACD,QAAM,oBAAoB,WAAW,YAAY,SAAS,gBAAgB,gBAAgB,aAAa,eAAe,SAAS;AAC/H,QAAM,eAAe,IAAI,IAAI;AAC7B,QAAM,oBAAoB,YAAY;AACpC,QAAI,CAAC,YAAY;AACf;AACF,QAAI,CAAC,kBAAkB,SAAS,aAAa,eAAe,UAAU;AACpE,YAAM,SAAS,MAAM,aAAa,kBAAkB;AACpD,UAAI,WAAW;AACb,0BAAkB,QAAQ;AAAA,IAC9B;AACA,WAAO,kBAAkB;AAAA,EAC3B;AACA,QAAM,EAAE,IAAI,SAAS,SAAS,aAAa,IAAI,gBAAgB;AAC/D,QAAM,EAAE,IAAI,QAAQ,SAAS,YAAY,IAAI,gBAAgB;AAC7D,QAAM,EAAE,IAAI,SAAS,SAAS,aAAa,IAAI,gBAAgB;AAC/D,QAAM,EAAE,IAAI,SAAS,SAAS,aAAa,IAAI,gBAAgB;AAC/D,QAAM,OAAO,OAAO,cAAc;AAChC,QAAI,CAAC,YAAY,SAAS,CAAC,kBAAkB;AAC3C;AACF,UAAM,WAAW,OAAO,OAAO,CAAC,GAAG,+BAA+B,SAAS;AAC3E,iBAAa,QAAQ,IAAI,aAAa,SAAS,SAAS,IAAI,QAAQ;AACpE,iBAAa,MAAM,UAAU;AAC7B,iBAAa,MAAM,SAAS;AAC5B,iBAAa,MAAM,UAAU;AAC7B,iBAAa,MAAM,UAAU;AAC7B,WAAO,aAAa;AAAA,EACtB;AACA,QAAM,QAAQ,MAAM;AAClB,QAAI,aAAa;AACf,mBAAa,MAAM,MAAM;AAC3B,iBAAa,QAAQ;AAAA,EACvB;AACA,MAAI;AACF,iBAAa,iBAAiB;AAChC,oBAAkB,KAAK;AACvB,MAAI,YAAY,SAASA,SAAQ;AAC/B,UAAMC,YAAWD,QAAO;AACxB,qBAAiBC,WAAU,oBAAoB,CAAC,MAAM;AACpD,QAAE,eAAe;AACjB,UAAIA,UAAS,oBAAoB,WAAW;AAC1C,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,IAAM,uBAAuB;AAC7B,SAAS,qBAAqB,SAAS;AACrC,MAAI,YAAY;AACd,WAAO,CAAC;AACV,SAAO;AACT;AACA,SAAS,aAAa,KAAK,UAAU,CAAC,GAAG;AACvC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,YAAY,CAAC;AAAA,EACf,IAAI;AACJ,QAAM,OAAO,IAAI,IAAI;AACrB,QAAM,SAAS,WAAW,QAAQ;AAClC,QAAM,QAAQ,IAAI;AAClB,QAAM,SAASO,OAAM,GAAG;AACxB,MAAI;AACJ,MAAI;AACJ,MAAI,mBAAmB;AACvB,MAAI,UAAU;AACd,MAAI,eAAe,CAAC;AACpB,MAAI;AACJ,MAAI;AACJ,QAAM,cAAc,MAAM;AACxB,QAAI,aAAa,UAAU,MAAM,SAAS,OAAO,UAAU,QAAQ;AACjE,iBAAW,UAAU;AACnB,cAAM,MAAM,KAAK,MAAM;AACzB,qBAAe,CAAC;AAAA,IAClB;AAAA,EACF;AACA,QAAM,aAAa,MAAM;AACvB,QAAI,gBAAgB,MAAM;AACxB,mBAAa,YAAY;AACzB,qBAAe;AAAA,IACjB;AAAA,EACF;AACA,QAAM,iBAAiB,MAAM;AAC3B,iBAAa,eAAe;AAC5B,sBAAkB;AAAA,EACpB;AACA,QAAM,QAAQ,CAAC,OAAO,KAAK,WAAW;AACpC,eAAW;AACX,QAAI,CAAC,YAAY,CAAC,YAAY,CAAC,MAAM;AACnC;AACF,uBAAmB;AACnB,mBAAe;AACf,sBAAkB,OAAO,SAAS,eAAe;AACjD,UAAM,MAAM,MAAM,MAAM,MAAM;AAC9B,UAAM,QAAQ;AAAA,EAChB;AACA,QAAM,OAAO,CAAC,OAAO,YAAY,SAAS;AACxC,QAAI,CAAC,MAAM,SAAS,OAAO,UAAU,QAAQ;AAC3C,UAAI;AACF,qBAAa,KAAK,KAAK;AACzB,aAAO;AAAA,IACT;AACA,gBAAY;AACZ,UAAM,MAAM,KAAK,KAAK;AACtB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,MAAM;AAClB,QAAI,oBAAoB,OAAO,OAAO,UAAU;AAC9C;AACF,UAAM,KAAK,IAAI,UAAU,OAAO,OAAO,SAAS;AAChD,UAAM,QAAQ;AACd,WAAO,QAAQ;AACf,OAAG,SAAS,MAAM;AAChB,aAAO,QAAQ;AACf,gBAAU;AACV,qBAAe,OAAO,SAAS,YAAY,EAAE;AAC7C,yBAAmB,OAAO,SAAS,gBAAgB;AACnD,kBAAY;AAAA,IACd;AACA,OAAG,UAAU,CAAC,OAAO;AACnB,aAAO,QAAQ;AACf,qBAAe;AACf,wBAAkB,OAAO,SAAS,eAAe;AACjD,wBAAkB,OAAO,SAAS,eAAe,IAAI,EAAE;AACvD,UAAI,CAAC,oBAAoB,QAAQ,kBAAkB,MAAM,SAAS,QAAQ,OAAO,MAAM,QAAQ;AAC7F,cAAM;AAAA,UACJ,UAAU;AAAA,UACV,QAAQ;AAAA,UACR;AAAA,QACF,IAAI,qBAAqB,QAAQ,aAAa;AAC9C,cAAM,eAAe,OAAO,YAAY,aAAa,UAAU,MAAM,OAAO,YAAY,aAAa,UAAU,KAAK,UAAU;AAC9H,YAAI,aAAa,OAAO,GAAG;AACzB,qBAAW;AACX,yBAAe,WAAW,OAAO,KAAK;AAAA,QACxC,OAAO;AACL,sBAAY,OAAO,SAAS,SAAS;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AACA,OAAG,UAAU,CAAC,MAAM;AAClB,iBAAW,OAAO,SAAS,QAAQ,IAAI,CAAC;AAAA,IAC1C;AACA,OAAG,YAAY,CAAC,MAAM;AACpB,UAAI,QAAQ,WAAW;AACrB,uBAAe;AACf,cAAM;AAAA,UACJ,UAAU;AAAA,UACV,kBAAkB;AAAA,QACpB,IAAI,qBAAqB,QAAQ,SAAS;AAC1C,YAAI,EAAE,SAAS,QAAQ,eAAe;AACpC;AAAA,MACJ;AACA,WAAK,QAAQ,EAAE;AACf,mBAAa,OAAO,SAAS,UAAU,IAAI,CAAC;AAAA,IAC9C;AAAA,EACF;AACA,MAAI,QAAQ,WAAW;AACrB,UAAM;AAAA,MACJ,UAAU;AAAA,MACV,WAAW;AAAA,MACX,cAAc;AAAA,IAChB,IAAI,qBAAqB,QAAQ,SAAS;AAC1C,UAAM,EAAE,OAAO,OAAO,IAAI;AAAA,MACxB,MAAM;AACJ,aAAK,QAAQ,OAAO,GAAG,KAAK;AAC5B,YAAI,mBAAmB;AACrB;AACF,0BAAkB,WAAW,MAAM;AACjC,gBAAM;AACN,6BAAmB;AAAA,QACrB,GAAG,WAAW;AAAA,MAChB;AAAA,MACA;AAAA,MACA,EAAE,WAAW,MAAM;AAAA,IACrB;AACA,qBAAiB;AACjB,sBAAkB;AAAA,EACpB;AACA,MAAI,WAAW;AACb,QAAI;AACF,uBAAiB,gBAAgB,MAAM,MAAM,GAAG,EAAE,SAAS,KAAK,CAAC;AACnE,sBAAkB,KAAK;AAAA,EACzB;AACA,QAAM,OAAO,MAAM;AACjB,QAAI,CAAC,YAAY,CAAC;AAChB;AACF,UAAM;AACN,uBAAmB;AACnB,cAAU;AACV,UAAM;AAAA,EACR;AACA,MAAI;AACF,SAAK;AACP,MAAI;AACF,UAAM,QAAQ,IAAI;AACpB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI;AAAA,EACN;AACF;AAEA,SAAS,aAAa,MAAM,eAAe,SAAS;AAClD,QAAM;AAAA,IACJ,QAAAR,UAAS;AAAA,EACX,IAAI,WAAW,OAAO,UAAU,CAAC;AACjC,QAAM,OAAO,IAAI,IAAI;AACrB,QAAM,SAAS,WAAW;AAC1B,QAAM,OAAO,IAAI,SAAS;AACxB,QAAI,CAAC,OAAO;AACV;AACF,WAAO,MAAM,YAAY,GAAG,IAAI;AAAA,EAClC;AACA,QAAM,YAAY,SAAS,aAAa;AACtC,QAAI,CAAC,OAAO;AACV;AACF,WAAO,MAAM,UAAU;AAAA,EACzB;AACA,MAAIA,SAAQ;AACV,QAAI,OAAO,SAAS;AAClB,aAAO,QAAQ,IAAI,OAAO,MAAM,aAAa;AAAA,aACtC,OAAO,SAAS;AACvB,aAAO,QAAQ,KAAK;AAAA;AAEpB,aAAO,QAAQ;AACjB,WAAO,MAAM,YAAY,CAAC,MAAM;AAC9B,WAAK,QAAQ,EAAE;AAAA,IACjB;AACA,sBAAkB,MAAM;AACtB,UAAI,OAAO;AACT,eAAO,MAAM,UAAU;AAAA,IAC3B,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,WAAW,MAAM,WAAW;AACnC,MAAI,KAAK,WAAW,KAAK,UAAU,WAAW;AAC5C,WAAO;AACT,QAAM,aAAa,KAAK,IAAI,CAAC,QAAQ,IAAI,GAAG,GAAG,EAAE,SAAS;AAC1D,QAAM,qBAAqB,UAAU,OAAO,CAAC,QAAQ,OAAO,QAAQ,UAAU,EAAE,IAAI,CAAC,OAAO;AAC1F,UAAM,MAAM,GAAG,SAAS;AACxB,QAAI,IAAI,KAAK,EAAE,WAAW,UAAU,GAAG;AACrC,aAAO;AAAA,IACT,OAAO;AACL,YAAM,OAAO,GAAG;AAChB,aAAO,SAAS,IAAI,MAAM,GAAG;AAAA,IAC/B;AAAA,EACF,CAAC,EAAE,KAAK,GAAG;AACX,QAAM,eAAe,iBAAiB,UAAU;AAChD,SAAO,GAAG,WAAW,KAAK,MAAM,KAAK,KAAK,YAAY,IAAI,kBAAkB;AAC9E;AAEA,SAAS,UAAU,UAAU;AAC3B,SAAO,CAAC,MAAM;AACZ,UAAM,eAAe,EAAE,KAAK,CAAC;AAC7B,WAAO,QAAQ,QAAQ,SAAS,MAAM,QAAQ,YAAY,CAAC,EAAE,KAAK,CAAC,WAAW;AAC5E,kBAAY,CAAC,WAAW,MAAM,CAAC;AAAA,IACjC,CAAC,EAAE,MAAM,CAAC,UAAU;AAClB,kBAAY,CAAC,SAAS,KAAK,CAAC;AAAA,IAC9B,CAAC;AAAA,EACH;AACF;AAEA,SAAS,oBAAoB,IAAI,MAAM,WAAW;AAChD,QAAM,WAAW,GAAG,WAAW,MAAM,SAAS,CAAC,gBAAgB,SAAS,KAAK,EAAE;AAC/E,QAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC7D,QAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,SAAO;AACT;AAEA,SAAS,eAAe,IAAI,UAAU,CAAC,GAAG;AACxC,QAAM;AAAA,IACJ,eAAe,CAAC;AAAA,IAChB,oBAAoB,CAAC;AAAA,IACrB;AAAA,IACA,QAAAA,UAAS;AAAA,EACX,IAAI;AACJ,QAAM,SAAS,IAAI;AACnB,QAAM,eAAe,WAAW,SAAS;AACzC,QAAM,UAAU,IAAI,CAAC,CAAC;AACtB,QAAM,YAAY,WAAW;AAC7B,QAAM,kBAAkB,CAAC,SAAS,cAAc;AAC9C,QAAI,OAAO,SAAS,OAAO,MAAM,QAAQA,SAAQ;AAC/C,aAAO,MAAM,UAAU;AACvB,UAAI,gBAAgB,OAAO,MAAM,IAAI;AACrC,cAAQ,QAAQ,CAAC;AACjB,aAAO,QAAQ;AACf,MAAAA,QAAO,aAAa,UAAU,KAAK;AACnC,mBAAa,QAAQ;AAAA,IACvB;AAAA,EACF;AACA,kBAAgB;AAChB,oBAAkB,eAAe;AACjC,QAAM,iBAAiB,MAAM;AAC3B,UAAM,UAAU,oBAAoB,IAAI,cAAc,iBAAiB;AACvE,UAAM,YAAY,IAAI,OAAO,OAAO;AACpC,cAAU,OAAO;AACjB,cAAU,YAAY,CAAC,MAAM;AAC3B,YAAM,EAAE,UAAU,MAAM;AAAA,MACxB,GAAG,SAAS,MAAM;AAAA,MAClB,EAAE,IAAI,QAAQ;AACd,YAAM,CAAC,QAAQ,MAAM,IAAI,EAAE;AAC3B,cAAQ,QAAQ;AAAA,QACd,KAAK;AACH,kBAAQ,MAAM;AACd,0BAAgB,MAAM;AACtB;AAAA,QACF;AACE,iBAAO,MAAM;AACb,0BAAgB,OAAO;AACvB;AAAA,MACJ;AAAA,IACF;AACA,cAAU,UAAU,CAAC,MAAM;AACzB,YAAM,EAAE,SAAS,MAAM;AAAA,MACvB,EAAE,IAAI,QAAQ;AACd,QAAE,eAAe;AACjB,aAAO,CAAC;AACR,sBAAgB,OAAO;AAAA,IACzB;AACA,QAAI,SAAS;AACX,gBAAU,QAAQ;AAAA,QAChB,MAAM,gBAAgB,iBAAiB;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,QAAM,aAAa,IAAI,WAAW,IAAI,QAAQ,CAAC,SAAS,WAAW;AACjE,QAAI;AACJ,YAAQ,QAAQ;AAAA,MACd;AAAA,MACA;AAAA,IACF;AACA,KAAC,KAAK,OAAO,UAAU,OAAO,SAAS,GAAG,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;AACnE,iBAAa,QAAQ;AAAA,EACvB,CAAC;AACD,QAAM,WAAW,IAAI,WAAW;AAC9B,QAAI,aAAa,UAAU,WAAW;AACpC,cAAQ;AAAA,QACN;AAAA,MACF;AACA,aAAO,QAAQ,OAAO;AAAA,IACxB;AACA,WAAO,QAAQ,eAAe;AAC9B,WAAO,WAAW,GAAG,MAAM;AAAA,EAC7B;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,eAAe,UAAU,CAAC,GAAG;AACpC,QAAM,EAAE,QAAAA,UAAS,cAAc,IAAI;AACnC,MAAI,CAACA;AACH,WAAO,WAAW,KAAK;AACzB,QAAM,UAAU,WAAWA,QAAO,SAAS,SAAS,CAAC;AACrD,QAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,mBAAiBA,SAAQ,QAAQ,MAAM;AACrC,YAAQ,QAAQ;AAAA,EAClB,GAAG,eAAe;AAClB,mBAAiBA,SAAQ,SAAS,MAAM;AACtC,YAAQ,QAAQ;AAAA,EAClB,GAAG,eAAe;AAClB,SAAO;AACT;AAEA,SAAS,gBAAgB,UAAU,CAAC,GAAG;AACrC,QAAM,EAAE,QAAAA,UAAS,eAAe,GAAG,KAAK,IAAI;AAC5C,SAAO,UAAUA,SAAQ,IAAI;AAC/B;AAEA,SAAS,cAAc,UAAU,CAAC,GAAG;AACnC,QAAM;AAAA,IACJ,QAAAA,UAAS;AAAA,IACT,eAAe,OAAO;AAAA,IACtB,gBAAgB,OAAO;AAAA,IACvB,oBAAoB;AAAA,IACpB,mBAAmB;AAAA,IACnB,OAAO;AAAA,EACT,IAAI;AACJ,QAAM,QAAQ,WAAW,YAAY;AACrC,QAAM,SAAS,WAAW,aAAa;AACvC,QAAM,SAAS,MAAM;AACnB,QAAIA,SAAQ;AACV,UAAI,SAAS,SAAS;AACpB,cAAM,QAAQA,QAAO;AACrB,eAAO,QAAQA,QAAO;AAAA,MACxB,WAAW,SAAS,YAAYA,QAAO,gBAAgB;AACrD,cAAM,EAAE,OAAO,qBAAqB,QAAQ,sBAAsB,MAAM,IAAIA,QAAO;AACnF,cAAM,QAAQ,KAAK,MAAM,sBAAsB,KAAK;AACpD,eAAO,QAAQ,KAAK,MAAM,uBAAuB,KAAK;AAAA,MACxD,WAAW,kBAAkB;AAC3B,cAAM,QAAQA,QAAO;AACrB,eAAO,QAAQA,QAAO;AAAA,MACxB,OAAO;AACL,cAAM,QAAQA,QAAO,SAAS,gBAAgB;AAC9C,eAAO,QAAQA,QAAO,SAAS,gBAAgB;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACP,eAAa,MAAM;AACnB,QAAM,kBAAkB,EAAE,SAAS,KAAK;AACxC,mBAAiB,UAAU,QAAQ,eAAe;AAClD,MAAIA,WAAU,SAAS,YAAYA,QAAO,gBAAgB;AACxD,qBAAiBA,QAAO,gBAAgB,UAAU,QAAQ,eAAe;AAAA,EAC3E;AACA,MAAI,mBAAmB;AACrB,UAAM,UAAU,cAAc,yBAAyB;AACvD,UAAM,SAAS,MAAM,OAAO,CAAC;AAAA,EAC/B;AACA,SAAO,EAAE,OAAO,OAAO;AACzB;", - "names": ["get", "set", "ref", "keys", "invoke", "toRef", "toRefs", "toValue", "window", "document", "timestamp", "navigator", "events", "getValue", "ref", "defaults", "toRef", "set", "onUpdated", "preventDefault", "toRefs", "now", "keys", "get", "isReadonly"] -} diff --git a/www/docs/.vitepress/cache/deps/chunk-LE5NDSFD.js b/www/docs/.vitepress/cache/deps/chunk-LE5NDSFD.js deleted file mode 100644 index 42925ac..0000000 --- a/www/docs/.vitepress/cache/deps/chunk-LE5NDSFD.js +++ /dev/null @@ -1,12824 +0,0 @@ -// node_modules/@vue/shared/dist/shared.esm-bundler.js -function makeMap(str) { - const map2 = /* @__PURE__ */ Object.create(null); - for (const key of str.split(",")) map2[key] = 1; - return (val) => val in map2; -} -var EMPTY_OBJ = true ? Object.freeze({}) : {}; -var EMPTY_ARR = true ? Object.freeze([]) : []; -var NOOP = () => { -}; -var NO = () => false; -var isOn = (key) => key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && // uppercase letter -(key.charCodeAt(2) > 122 || key.charCodeAt(2) < 97); -var isModelListener = (key) => key.startsWith("onUpdate:"); -var extend = Object.assign; -var remove = (arr, el) => { - const i = arr.indexOf(el); - if (i > -1) { - arr.splice(i, 1); - } -}; -var hasOwnProperty = Object.prototype.hasOwnProperty; -var hasOwn = (val, key) => hasOwnProperty.call(val, key); -var isArray = Array.isArray; -var isMap = (val) => toTypeString(val) === "[object Map]"; -var isSet = (val) => toTypeString(val) === "[object Set]"; -var isDate = (val) => toTypeString(val) === "[object Date]"; -var isRegExp = (val) => toTypeString(val) === "[object RegExp]"; -var isFunction = (val) => typeof val === "function"; -var isString = (val) => typeof val === "string"; -var isSymbol = (val) => typeof val === "symbol"; -var isObject = (val) => val !== null && typeof val === "object"; -var isPromise = (val) => { - return (isObject(val) || isFunction(val)) && isFunction(val.then) && isFunction(val.catch); -}; -var objectToString = Object.prototype.toString; -var toTypeString = (value) => objectToString.call(value); -var toRawType = (value) => { - return toTypeString(value).slice(8, -1); -}; -var isPlainObject = (val) => toTypeString(val) === "[object Object]"; -var isIntegerKey = (key) => isString(key) && key !== "NaN" && key[0] !== "-" && "" + parseInt(key, 10) === key; -var isReservedProp = makeMap( - // the leading comma is intentional so empty string "" is also included - ",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted" -); -var isBuiltInDirective = makeMap( - "bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo" -); -var cacheStringFunction = (fn) => { - const cache = /* @__PURE__ */ Object.create(null); - return (str) => { - const hit = cache[str]; - return hit || (cache[str] = fn(str)); - }; -}; -var camelizeRE = /-\w/g; -var camelize = cacheStringFunction( - (str) => { - return str.replace(camelizeRE, (c) => c.slice(1).toUpperCase()); - } -); -var hyphenateRE = /\B([A-Z])/g; -var hyphenate = cacheStringFunction( - (str) => str.replace(hyphenateRE, "-$1").toLowerCase() -); -var capitalize = cacheStringFunction((str) => { - return str.charAt(0).toUpperCase() + str.slice(1); -}); -var toHandlerKey = cacheStringFunction( - (str) => { - const s = str ? `on${capitalize(str)}` : ``; - return s; - } -); -var hasChanged = (value, oldValue) => !Object.is(value, oldValue); -var invokeArrayFns = (fns, ...arg) => { - for (let i = 0; i < fns.length; i++) { - fns[i](...arg); - } -}; -var def = (obj, key, value, writable = false) => { - Object.defineProperty(obj, key, { - configurable: true, - enumerable: false, - writable, - value - }); -}; -var looseToNumber = (val) => { - const n = parseFloat(val); - return isNaN(n) ? val : n; -}; -var toNumber = (val) => { - const n = isString(val) ? Number(val) : NaN; - return isNaN(n) ? val : n; -}; -var _globalThis; -var getGlobalThis = () => { - return _globalThis || (_globalThis = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {}); -}; -var GLOBALS_ALLOWED = "Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console,Error,Symbol"; -var isGloballyAllowed = makeMap(GLOBALS_ALLOWED); -function normalizeStyle(value) { - if (isArray(value)) { - const res = {}; - for (let i = 0; i < value.length; i++) { - const item = value[i]; - const normalized = isString(item) ? parseStringStyle(item) : normalizeStyle(item); - if (normalized) { - for (const key in normalized) { - res[key] = normalized[key]; - } - } - } - return res; - } else if (isString(value) || isObject(value)) { - return value; - } -} -var listDelimiterRE = /;(?![^(]*\))/g; -var propertyDelimiterRE = /:([^]+)/; -var styleCommentRE = /\/\*[^]*?\*\//g; -function parseStringStyle(cssText) { - const ret = {}; - cssText.replace(styleCommentRE, "").split(listDelimiterRE).forEach((item) => { - if (item) { - const tmp = item.split(propertyDelimiterRE); - tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim()); - } - }); - return ret; -} -function stringifyStyle(styles) { - if (!styles) return ""; - if (isString(styles)) return styles; - let ret = ""; - for (const key in styles) { - const value = styles[key]; - if (isString(value) || typeof value === "number") { - const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key); - ret += `${normalizedKey}:${value};`; - } - } - return ret; -} -function normalizeClass(value) { - let res = ""; - if (isString(value)) { - res = value; - } else if (isArray(value)) { - for (let i = 0; i < value.length; i++) { - const normalized = normalizeClass(value[i]); - if (normalized) { - res += normalized + " "; - } - } - } else if (isObject(value)) { - for (const name in value) { - if (value[name]) { - res += name + " "; - } - } - } - return res.trim(); -} -function normalizeProps(props) { - if (!props) return null; - let { class: klass, style } = props; - if (klass && !isString(klass)) { - props.class = normalizeClass(klass); - } - if (style) { - props.style = normalizeStyle(style); - } - return props; -} -var HTML_TAGS = "html,body,base,head,link,meta,style,title,address,article,aside,footer,header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot"; -var SVG_TAGS = "svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistantLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,text,textPath,title,tspan,unknown,use,view"; -var MATH_TAGS = "annotation,annotation-xml,maction,maligngroup,malignmark,math,menclose,merror,mfenced,mfrac,mfraction,mglyph,mi,mlabeledtr,mlongdiv,mmultiscripts,mn,mo,mover,mpadded,mphantom,mprescripts,mroot,mrow,ms,mscarries,mscarry,msgroup,msline,mspace,msqrt,msrow,mstack,mstyle,msub,msubsup,msup,mtable,mtd,mtext,mtr,munder,munderover,none,semantics"; -var VOID_TAGS = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr"; -var isHTMLTag = makeMap(HTML_TAGS); -var isSVGTag = makeMap(SVG_TAGS); -var isMathMLTag = makeMap(MATH_TAGS); -var isVoidTag = makeMap(VOID_TAGS); -var specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`; -var isSpecialBooleanAttr = makeMap(specialBooleanAttrs); -var isBooleanAttr = makeMap( - specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,inert,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected` -); -function includeBooleanAttr(value) { - return !!value || value === ""; -} -var isKnownHtmlAttr = makeMap( - `accept,accept-charset,accesskey,action,align,allow,alt,async,autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,border,buffered,capture,challenge,charset,checked,cite,class,code,codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,formaction,formenctype,formmethod,formnovalidate,formtarget,headers,height,hidden,high,href,hreflang,http-equiv,icon,id,importance,inert,integrity,ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,target,title,translate,type,usemap,value,width,wrap` -); -var isKnownSvgAttr = makeMap( - `xmlns,accent-height,accumulate,additive,alignment-baseline,alphabetic,amplitude,arabic-form,ascent,attributeName,attributeType,azimuth,baseFrequency,baseline-shift,baseProfile,bbox,begin,bias,by,calcMode,cap-height,class,clip,clipPathUnits,clip-path,clip-rule,color,color-interpolation,color-interpolation-filters,color-profile,color-rendering,contentScriptType,contentStyleType,crossorigin,cursor,cx,cy,d,decelerate,descent,diffuseConstant,direction,display,divisor,dominant-baseline,dur,dx,dy,edgeMode,elevation,enable-background,end,exponent,fill,fill-opacity,fill-rule,filter,filterRes,filterUnits,flood-color,flood-opacity,font-family,font-size,font-size-adjust,font-stretch,font-style,font-variant,font-weight,format,from,fr,fx,fy,g1,g2,glyph-name,glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,gradientTransform,gradientUnits,hanging,height,href,hreflang,horiz-adv-x,horiz-origin-x,id,ideographic,image-rendering,in,in2,intercept,k,k1,k2,k3,k4,kernelMatrix,kernelUnitLength,kerning,keyPoints,keySplines,keyTimes,lang,lengthAdjust,letter-spacing,lighting-color,limitingConeAngle,local,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mask,maskContentUnits,maskUnits,mathematical,max,media,method,min,mode,name,numOctaves,offset,opacity,operator,order,orient,orientation,origin,overflow,overline-position,overline-thickness,panose-1,paint-order,path,pathLength,patternContentUnits,patternTransform,patternUnits,ping,pointer-events,points,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,preserveAspectRatio,primitiveUnits,r,radius,referrerPolicy,refX,refY,rel,rendering-intent,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,result,rotate,rx,ry,scale,seed,shape-rendering,slope,spacing,specularConstant,specularExponent,speed,spreadMethod,startOffset,stdDeviation,stemh,stemv,stitchTiles,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,string,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,style,surfaceScale,systemLanguage,tabindex,tableValues,target,targetX,targetY,text-anchor,text-decoration,text-rendering,textLength,to,transform,transform-origin,type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,unicode-range,units-per-em,v-alphabetic,v-hanging,v-ideographic,v-mathematical,values,vector-effect,version,vert-adv-y,vert-origin-x,vert-origin-y,viewBox,viewTarget,visibility,width,widths,word-spacing,writing-mode,x,x-height,x1,x2,xChannelSelector,xlink:actuate,xlink:arcrole,xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xmlns:xlink,xml:base,xml:lang,xml:space,y,y1,y2,yChannelSelector,z,zoomAndPan` -); -var isKnownMathMLAttr = makeMap( - `accent,accentunder,actiontype,align,alignmentscope,altimg,altimg-height,altimg-valign,altimg-width,alttext,bevelled,close,columnsalign,columnlines,columnspan,denomalign,depth,dir,display,displaystyle,encoding,equalcolumns,equalrows,fence,fontstyle,fontweight,form,frame,framespacing,groupalign,height,href,id,indentalign,indentalignfirst,indentalignlast,indentshift,indentshiftfirst,indentshiftlast,indextype,justify,largetop,largeop,lquote,lspace,mathbackground,mathcolor,mathsize,mathvariant,maxsize,minlabelspacing,mode,other,overflow,position,rowalign,rowlines,rowspan,rquote,rspace,scriptlevel,scriptminsize,scriptsizemultiplier,selection,separator,separators,shift,side,src,stackalign,stretchy,subscriptshift,superscriptshift,symmetric,voffset,width,widths,xlink:href,xlink:show,xlink:type,xmlns` -); -function isRenderableAttrValue(value) { - if (value == null) { - return false; - } - const type = typeof value; - return type === "string" || type === "number" || type === "boolean"; -} -var cssVarNameEscapeSymbolsRE = /[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g; -function getEscapedCssVarName(key, doubleEscape) { - return key.replace( - cssVarNameEscapeSymbolsRE, - (s) => doubleEscape ? s === '"' ? '\\\\\\"' : `\\\\${s}` : `\\${s}` - ); -} -function looseCompareArrays(a, b) { - if (a.length !== b.length) return false; - let equal = true; - for (let i = 0; equal && i < a.length; i++) { - equal = looseEqual(a[i], b[i]); - } - return equal; -} -function looseEqual(a, b) { - if (a === b) return true; - let aValidType = isDate(a); - let bValidType = isDate(b); - if (aValidType || bValidType) { - return aValidType && bValidType ? a.getTime() === b.getTime() : false; - } - aValidType = isSymbol(a); - bValidType = isSymbol(b); - if (aValidType || bValidType) { - return a === b; - } - aValidType = isArray(a); - bValidType = isArray(b); - if (aValidType || bValidType) { - return aValidType && bValidType ? looseCompareArrays(a, b) : false; - } - aValidType = isObject(a); - bValidType = isObject(b); - if (aValidType || bValidType) { - if (!aValidType || !bValidType) { - return false; - } - const aKeysCount = Object.keys(a).length; - const bKeysCount = Object.keys(b).length; - if (aKeysCount !== bKeysCount) { - return false; - } - for (const key in a) { - const aHasKey = a.hasOwnProperty(key); - const bHasKey = b.hasOwnProperty(key); - if (aHasKey && !bHasKey || !aHasKey && bHasKey || !looseEqual(a[key], b[key])) { - return false; - } - } - } - return String(a) === String(b); -} -function looseIndexOf(arr, val) { - return arr.findIndex((item) => looseEqual(item, val)); -} -var isRef = (val) => { - return !!(val && val["__v_isRef"] === true); -}; -var toDisplayString = (val) => { - return isString(val) ? val : val == null ? "" : isArray(val) || isObject(val) && (val.toString === objectToString || !isFunction(val.toString)) ? isRef(val) ? toDisplayString(val.value) : JSON.stringify(val, replacer, 2) : String(val); -}; -var replacer = (_key, val) => { - if (isRef(val)) { - return replacer(_key, val.value); - } else if (isMap(val)) { - return { - [`Map(${val.size})`]: [...val.entries()].reduce( - (entries, [key, val2], i) => { - entries[stringifySymbol(key, i) + " =>"] = val2; - return entries; - }, - {} - ) - }; - } else if (isSet(val)) { - return { - [`Set(${val.size})`]: [...val.values()].map((v) => stringifySymbol(v)) - }; - } else if (isSymbol(val)) { - return stringifySymbol(val); - } else if (isObject(val) && !isArray(val) && !isPlainObject(val)) { - return String(val); - } - return val; -}; -var stringifySymbol = (v, i = "") => { - var _a; - return ( - // Symbol.description in es2019+ so we need to cast here to pass - // the lib: es2016 check - isSymbol(v) ? `Symbol(${(_a = v.description) != null ? _a : i})` : v - ); -}; -function normalizeCssVarValue(value) { - if (value == null) { - return "initial"; - } - if (typeof value === "string") { - return value === "" ? " " : value; - } - if (typeof value !== "number" || !Number.isFinite(value)) { - if (true) { - console.warn( - "[Vue warn] Invalid value used for CSS binding. Expected a string or a finite number but received:", - value - ); - } - } - return String(value); -} - -// node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js -function warn(msg, ...args) { - console.warn(`[Vue warn] ${msg}`, ...args); -} -var activeEffectScope; -var EffectScope = class { - constructor(detached = false) { - this.detached = detached; - this._active = true; - this._on = 0; - this.effects = []; - this.cleanups = []; - this._isPaused = false; - this.parent = activeEffectScope; - if (!detached && activeEffectScope) { - this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push( - this - ) - 1; - } - } - get active() { - return this._active; - } - pause() { - if (this._active) { - this._isPaused = true; - let i, l; - if (this.scopes) { - for (i = 0, l = this.scopes.length; i < l; i++) { - this.scopes[i].pause(); - } - } - for (i = 0, l = this.effects.length; i < l; i++) { - this.effects[i].pause(); - } - } - } - /** - * Resumes the effect scope, including all child scopes and effects. - */ - resume() { - if (this._active) { - if (this._isPaused) { - this._isPaused = false; - let i, l; - if (this.scopes) { - for (i = 0, l = this.scopes.length; i < l; i++) { - this.scopes[i].resume(); - } - } - for (i = 0, l = this.effects.length; i < l; i++) { - this.effects[i].resume(); - } - } - } - } - run(fn) { - if (this._active) { - const currentEffectScope = activeEffectScope; - try { - activeEffectScope = this; - return fn(); - } finally { - activeEffectScope = currentEffectScope; - } - } else if (true) { - warn(`cannot run an inactive effect scope.`); - } - } - /** - * This should only be called on non-detached scopes - * @internal - */ - on() { - if (++this._on === 1) { - this.prevScope = activeEffectScope; - activeEffectScope = this; - } - } - /** - * This should only be called on non-detached scopes - * @internal - */ - off() { - if (this._on > 0 && --this._on === 0) { - activeEffectScope = this.prevScope; - this.prevScope = void 0; - } - } - stop(fromParent) { - if (this._active) { - this._active = false; - let i, l; - for (i = 0, l = this.effects.length; i < l; i++) { - this.effects[i].stop(); - } - this.effects.length = 0; - for (i = 0, l = this.cleanups.length; i < l; i++) { - this.cleanups[i](); - } - this.cleanups.length = 0; - if (this.scopes) { - for (i = 0, l = this.scopes.length; i < l; i++) { - this.scopes[i].stop(true); - } - this.scopes.length = 0; - } - if (!this.detached && this.parent && !fromParent) { - const last = this.parent.scopes.pop(); - if (last && last !== this) { - this.parent.scopes[this.index] = last; - last.index = this.index; - } - } - this.parent = void 0; - } - } -}; -function effectScope(detached) { - return new EffectScope(detached); -} -function getCurrentScope() { - return activeEffectScope; -} -function onScopeDispose(fn, failSilently = false) { - if (activeEffectScope) { - activeEffectScope.cleanups.push(fn); - } else if (!failSilently) { - warn( - `onScopeDispose() is called when there is no active effect scope to be associated with.` - ); - } -} -var activeSub; -var pausedQueueEffects = /* @__PURE__ */ new WeakSet(); -var ReactiveEffect = class { - constructor(fn) { - this.fn = fn; - this.deps = void 0; - this.depsTail = void 0; - this.flags = 1 | 4; - this.next = void 0; - this.cleanup = void 0; - this.scheduler = void 0; - if (activeEffectScope && activeEffectScope.active) { - activeEffectScope.effects.push(this); - } - } - pause() { - this.flags |= 64; - } - resume() { - if (this.flags & 64) { - this.flags &= -65; - if (pausedQueueEffects.has(this)) { - pausedQueueEffects.delete(this); - this.trigger(); - } - } - } - /** - * @internal - */ - notify() { - if (this.flags & 2 && !(this.flags & 32)) { - return; - } - if (!(this.flags & 8)) { - batch(this); - } - } - run() { - if (!(this.flags & 1)) { - return this.fn(); - } - this.flags |= 2; - cleanupEffect(this); - prepareDeps(this); - const prevEffect = activeSub; - const prevShouldTrack = shouldTrack; - activeSub = this; - shouldTrack = true; - try { - return this.fn(); - } finally { - if (activeSub !== this) { - warn( - "Active effect was not restored correctly - this is likely a Vue internal bug." - ); - } - cleanupDeps(this); - activeSub = prevEffect; - shouldTrack = prevShouldTrack; - this.flags &= -3; - } - } - stop() { - if (this.flags & 1) { - for (let link = this.deps; link; link = link.nextDep) { - removeSub(link); - } - this.deps = this.depsTail = void 0; - cleanupEffect(this); - this.onStop && this.onStop(); - this.flags &= -2; - } - } - trigger() { - if (this.flags & 64) { - pausedQueueEffects.add(this); - } else if (this.scheduler) { - this.scheduler(); - } else { - this.runIfDirty(); - } - } - /** - * @internal - */ - runIfDirty() { - if (isDirty(this)) { - this.run(); - } - } - get dirty() { - return isDirty(this); - } -}; -var batchDepth = 0; -var batchedSub; -var batchedComputed; -function batch(sub, isComputed = false) { - sub.flags |= 8; - if (isComputed) { - sub.next = batchedComputed; - batchedComputed = sub; - return; - } - sub.next = batchedSub; - batchedSub = sub; -} -function startBatch() { - batchDepth++; -} -function endBatch() { - if (--batchDepth > 0) { - return; - } - if (batchedComputed) { - let e = batchedComputed; - batchedComputed = void 0; - while (e) { - const next = e.next; - e.next = void 0; - e.flags &= -9; - e = next; - } - } - let error; - while (batchedSub) { - let e = batchedSub; - batchedSub = void 0; - while (e) { - const next = e.next; - e.next = void 0; - e.flags &= -9; - if (e.flags & 1) { - try { - ; - e.trigger(); - } catch (err) { - if (!error) error = err; - } - } - e = next; - } - } - if (error) throw error; -} -function prepareDeps(sub) { - for (let link = sub.deps; link; link = link.nextDep) { - link.version = -1; - link.prevActiveLink = link.dep.activeLink; - link.dep.activeLink = link; - } -} -function cleanupDeps(sub) { - let head; - let tail = sub.depsTail; - let link = tail; - while (link) { - const prev = link.prevDep; - if (link.version === -1) { - if (link === tail) tail = prev; - removeSub(link); - removeDep(link); - } else { - head = link; - } - link.dep.activeLink = link.prevActiveLink; - link.prevActiveLink = void 0; - link = prev; - } - sub.deps = head; - sub.depsTail = tail; -} -function isDirty(sub) { - for (let link = sub.deps; link; link = link.nextDep) { - if (link.dep.version !== link.version || link.dep.computed && (refreshComputed(link.dep.computed) || link.dep.version !== link.version)) { - return true; - } - } - if (sub._dirty) { - return true; - } - return false; -} -function refreshComputed(computed3) { - if (computed3.flags & 4 && !(computed3.flags & 16)) { - return; - } - computed3.flags &= -17; - if (computed3.globalVersion === globalVersion) { - return; - } - computed3.globalVersion = globalVersion; - if (!computed3.isSSR && computed3.flags & 128 && (!computed3.deps && !computed3._dirty || !isDirty(computed3))) { - return; - } - computed3.flags |= 2; - const dep = computed3.dep; - const prevSub = activeSub; - const prevShouldTrack = shouldTrack; - activeSub = computed3; - shouldTrack = true; - try { - prepareDeps(computed3); - const value = computed3.fn(computed3._value); - if (dep.version === 0 || hasChanged(value, computed3._value)) { - computed3.flags |= 128; - computed3._value = value; - dep.version++; - } - } catch (err) { - dep.version++; - throw err; - } finally { - activeSub = prevSub; - shouldTrack = prevShouldTrack; - cleanupDeps(computed3); - computed3.flags &= -3; - } -} -function removeSub(link, soft = false) { - const { dep, prevSub, nextSub } = link; - if (prevSub) { - prevSub.nextSub = nextSub; - link.prevSub = void 0; - } - if (nextSub) { - nextSub.prevSub = prevSub; - link.nextSub = void 0; - } - if (dep.subsHead === link) { - dep.subsHead = nextSub; - } - if (dep.subs === link) { - dep.subs = prevSub; - if (!prevSub && dep.computed) { - dep.computed.flags &= -5; - for (let l = dep.computed.deps; l; l = l.nextDep) { - removeSub(l, true); - } - } - } - if (!soft && !--dep.sc && dep.map) { - dep.map.delete(dep.key); - } -} -function removeDep(link) { - const { prevDep, nextDep } = link; - if (prevDep) { - prevDep.nextDep = nextDep; - link.prevDep = void 0; - } - if (nextDep) { - nextDep.prevDep = prevDep; - link.nextDep = void 0; - } -} -function effect(fn, options) { - if (fn.effect instanceof ReactiveEffect) { - fn = fn.effect.fn; - } - const e = new ReactiveEffect(fn); - if (options) { - extend(e, options); - } - try { - e.run(); - } catch (err) { - e.stop(); - throw err; - } - const runner = e.run.bind(e); - runner.effect = e; - return runner; -} -function stop(runner) { - runner.effect.stop(); -} -var shouldTrack = true; -var trackStack = []; -function pauseTracking() { - trackStack.push(shouldTrack); - shouldTrack = false; -} -function resetTracking() { - const last = trackStack.pop(); - shouldTrack = last === void 0 ? true : last; -} -function cleanupEffect(e) { - const { cleanup } = e; - e.cleanup = void 0; - if (cleanup) { - const prevSub = activeSub; - activeSub = void 0; - try { - cleanup(); - } finally { - activeSub = prevSub; - } - } -} -var globalVersion = 0; -var Link = class { - constructor(sub, dep) { - this.sub = sub; - this.dep = dep; - this.version = dep.version; - this.nextDep = this.prevDep = this.nextSub = this.prevSub = this.prevActiveLink = void 0; - } -}; -var Dep = class { - // TODO isolatedDeclarations "__v_skip" - constructor(computed3) { - this.computed = computed3; - this.version = 0; - this.activeLink = void 0; - this.subs = void 0; - this.map = void 0; - this.key = void 0; - this.sc = 0; - this.__v_skip = true; - if (true) { - this.subsHead = void 0; - } - } - track(debugInfo) { - if (!activeSub || !shouldTrack || activeSub === this.computed) { - return; - } - let link = this.activeLink; - if (link === void 0 || link.sub !== activeSub) { - link = this.activeLink = new Link(activeSub, this); - if (!activeSub.deps) { - activeSub.deps = activeSub.depsTail = link; - } else { - link.prevDep = activeSub.depsTail; - activeSub.depsTail.nextDep = link; - activeSub.depsTail = link; - } - addSub(link); - } else if (link.version === -1) { - link.version = this.version; - if (link.nextDep) { - const next = link.nextDep; - next.prevDep = link.prevDep; - if (link.prevDep) { - link.prevDep.nextDep = next; - } - link.prevDep = activeSub.depsTail; - link.nextDep = void 0; - activeSub.depsTail.nextDep = link; - activeSub.depsTail = link; - if (activeSub.deps === link) { - activeSub.deps = next; - } - } - } - if (activeSub.onTrack) { - activeSub.onTrack( - extend( - { - effect: activeSub - }, - debugInfo - ) - ); - } - return link; - } - trigger(debugInfo) { - this.version++; - globalVersion++; - this.notify(debugInfo); - } - notify(debugInfo) { - startBatch(); - try { - if (true) { - for (let head = this.subsHead; head; head = head.nextSub) { - if (head.sub.onTrigger && !(head.sub.flags & 8)) { - head.sub.onTrigger( - extend( - { - effect: head.sub - }, - debugInfo - ) - ); - } - } - } - for (let link = this.subs; link; link = link.prevSub) { - if (link.sub.notify()) { - ; - link.sub.dep.notify(); - } - } - } finally { - endBatch(); - } - } -}; -function addSub(link) { - link.dep.sc++; - if (link.sub.flags & 4) { - const computed3 = link.dep.computed; - if (computed3 && !link.dep.subs) { - computed3.flags |= 4 | 16; - for (let l = computed3.deps; l; l = l.nextDep) { - addSub(l); - } - } - const currentTail = link.dep.subs; - if (currentTail !== link) { - link.prevSub = currentTail; - if (currentTail) currentTail.nextSub = link; - } - if (link.dep.subsHead === void 0) { - link.dep.subsHead = link; - } - link.dep.subs = link; - } -} -var targetMap = /* @__PURE__ */ new WeakMap(); -var ITERATE_KEY = Symbol( - true ? "Object iterate" : "" -); -var MAP_KEY_ITERATE_KEY = Symbol( - true ? "Map keys iterate" : "" -); -var ARRAY_ITERATE_KEY = Symbol( - true ? "Array iterate" : "" -); -function track(target, type, key) { - if (shouldTrack && activeSub) { - let depsMap = targetMap.get(target); - if (!depsMap) { - targetMap.set(target, depsMap = /* @__PURE__ */ new Map()); - } - let dep = depsMap.get(key); - if (!dep) { - depsMap.set(key, dep = new Dep()); - dep.map = depsMap; - dep.key = key; - } - if (true) { - dep.track({ - target, - type, - key - }); - } else { - dep.track(); - } - } -} -function trigger(target, type, key, newValue, oldValue, oldTarget) { - const depsMap = targetMap.get(target); - if (!depsMap) { - globalVersion++; - return; - } - const run = (dep) => { - if (dep) { - if (true) { - dep.trigger({ - target, - type, - key, - newValue, - oldValue, - oldTarget - }); - } else { - dep.trigger(); - } - } - }; - startBatch(); - if (type === "clear") { - depsMap.forEach(run); - } else { - const targetIsArray = isArray(target); - const isArrayIndex = targetIsArray && isIntegerKey(key); - if (targetIsArray && key === "length") { - const newLength = Number(newValue); - depsMap.forEach((dep, key2) => { - if (key2 === "length" || key2 === ARRAY_ITERATE_KEY || !isSymbol(key2) && key2 >= newLength) { - run(dep); - } - }); - } else { - if (key !== void 0 || depsMap.has(void 0)) { - run(depsMap.get(key)); - } - if (isArrayIndex) { - run(depsMap.get(ARRAY_ITERATE_KEY)); - } - switch (type) { - case "add": - if (!targetIsArray) { - run(depsMap.get(ITERATE_KEY)); - if (isMap(target)) { - run(depsMap.get(MAP_KEY_ITERATE_KEY)); - } - } else if (isArrayIndex) { - run(depsMap.get("length")); - } - break; - case "delete": - if (!targetIsArray) { - run(depsMap.get(ITERATE_KEY)); - if (isMap(target)) { - run(depsMap.get(MAP_KEY_ITERATE_KEY)); - } - } - break; - case "set": - if (isMap(target)) { - run(depsMap.get(ITERATE_KEY)); - } - break; - } - } - } - endBatch(); -} -function getDepFromReactive(object, key) { - const depMap = targetMap.get(object); - return depMap && depMap.get(key); -} -function reactiveReadArray(array) { - const raw = toRaw(array); - if (raw === array) return raw; - track(raw, "iterate", ARRAY_ITERATE_KEY); - return isShallow(array) ? raw : raw.map(toReactive); -} -function shallowReadArray(arr) { - track(arr = toRaw(arr), "iterate", ARRAY_ITERATE_KEY); - return arr; -} -function toWrapped(target, item) { - if (isReadonly(target)) { - return isReactive(target) ? toReadonly(toReactive(item)) : toReadonly(item); - } - return toReactive(item); -} -var arrayInstrumentations = { - __proto__: null, - [Symbol.iterator]() { - return iterator(this, Symbol.iterator, (item) => toWrapped(this, item)); - }, - concat(...args) { - return reactiveReadArray(this).concat( - ...args.map((x) => isArray(x) ? reactiveReadArray(x) : x) - ); - }, - entries() { - return iterator(this, "entries", (value) => { - value[1] = toWrapped(this, value[1]); - return value; - }); - }, - every(fn, thisArg) { - return apply(this, "every", fn, thisArg, void 0, arguments); - }, - filter(fn, thisArg) { - return apply( - this, - "filter", - fn, - thisArg, - (v) => v.map((item) => toWrapped(this, item)), - arguments - ); - }, - find(fn, thisArg) { - return apply( - this, - "find", - fn, - thisArg, - (item) => toWrapped(this, item), - arguments - ); - }, - findIndex(fn, thisArg) { - return apply(this, "findIndex", fn, thisArg, void 0, arguments); - }, - findLast(fn, thisArg) { - return apply( - this, - "findLast", - fn, - thisArg, - (item) => toWrapped(this, item), - arguments - ); - }, - findLastIndex(fn, thisArg) { - return apply(this, "findLastIndex", fn, thisArg, void 0, arguments); - }, - // flat, flatMap could benefit from ARRAY_ITERATE but are not straight-forward to implement - forEach(fn, thisArg) { - return apply(this, "forEach", fn, thisArg, void 0, arguments); - }, - includes(...args) { - return searchProxy(this, "includes", args); - }, - indexOf(...args) { - return searchProxy(this, "indexOf", args); - }, - join(separator) { - return reactiveReadArray(this).join(separator); - }, - // keys() iterator only reads `length`, no optimization required - lastIndexOf(...args) { - return searchProxy(this, "lastIndexOf", args); - }, - map(fn, thisArg) { - return apply(this, "map", fn, thisArg, void 0, arguments); - }, - pop() { - return noTracking(this, "pop"); - }, - push(...args) { - return noTracking(this, "push", args); - }, - reduce(fn, ...args) { - return reduce(this, "reduce", fn, args); - }, - reduceRight(fn, ...args) { - return reduce(this, "reduceRight", fn, args); - }, - shift() { - return noTracking(this, "shift"); - }, - // slice could use ARRAY_ITERATE but also seems to beg for range tracking - some(fn, thisArg) { - return apply(this, "some", fn, thisArg, void 0, arguments); - }, - splice(...args) { - return noTracking(this, "splice", args); - }, - toReversed() { - return reactiveReadArray(this).toReversed(); - }, - toSorted(comparer) { - return reactiveReadArray(this).toSorted(comparer); - }, - toSpliced(...args) { - return reactiveReadArray(this).toSpliced(...args); - }, - unshift(...args) { - return noTracking(this, "unshift", args); - }, - values() { - return iterator(this, "values", (item) => toWrapped(this, item)); - } -}; -function iterator(self2, method, wrapValue) { - const arr = shallowReadArray(self2); - const iter = arr[method](); - if (arr !== self2 && !isShallow(self2)) { - iter._next = iter.next; - iter.next = () => { - const result = iter._next(); - if (!result.done) { - result.value = wrapValue(result.value); - } - return result; - }; - } - return iter; -} -var arrayProto = Array.prototype; -function apply(self2, method, fn, thisArg, wrappedRetFn, args) { - const arr = shallowReadArray(self2); - const needsWrap = arr !== self2 && !isShallow(self2); - const methodFn = arr[method]; - if (methodFn !== arrayProto[method]) { - const result2 = methodFn.apply(self2, args); - return needsWrap ? toReactive(result2) : result2; - } - let wrappedFn = fn; - if (arr !== self2) { - if (needsWrap) { - wrappedFn = function(item, index) { - return fn.call(this, toWrapped(self2, item), index, self2); - }; - } else if (fn.length > 2) { - wrappedFn = function(item, index) { - return fn.call(this, item, index, self2); - }; - } - } - const result = methodFn.call(arr, wrappedFn, thisArg); - return needsWrap && wrappedRetFn ? wrappedRetFn(result) : result; -} -function reduce(self2, method, fn, args) { - const arr = shallowReadArray(self2); - let wrappedFn = fn; - if (arr !== self2) { - if (!isShallow(self2)) { - wrappedFn = function(acc, item, index) { - return fn.call(this, acc, toWrapped(self2, item), index, self2); - }; - } else if (fn.length > 3) { - wrappedFn = function(acc, item, index) { - return fn.call(this, acc, item, index, self2); - }; - } - } - return arr[method](wrappedFn, ...args); -} -function searchProxy(self2, method, args) { - const arr = toRaw(self2); - track(arr, "iterate", ARRAY_ITERATE_KEY); - const res = arr[method](...args); - if ((res === -1 || res === false) && isProxy(args[0])) { - args[0] = toRaw(args[0]); - return arr[method](...args); - } - return res; -} -function noTracking(self2, method, args = []) { - pauseTracking(); - startBatch(); - const res = toRaw(self2)[method].apply(self2, args); - endBatch(); - resetTracking(); - return res; -} -var isNonTrackableKeys = makeMap(`__proto__,__v_isRef,__isVue`); -var builtInSymbols = new Set( - Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(isSymbol) -); -function hasOwnProperty2(key) { - if (!isSymbol(key)) key = String(key); - const obj = toRaw(this); - track(obj, "has", key); - return obj.hasOwnProperty(key); -} -var BaseReactiveHandler = class { - constructor(_isReadonly = false, _isShallow = false) { - this._isReadonly = _isReadonly; - this._isShallow = _isShallow; - } - get(target, key, receiver) { - if (key === "__v_skip") return target["__v_skip"]; - const isReadonly2 = this._isReadonly, isShallow2 = this._isShallow; - if (key === "__v_isReactive") { - return !isReadonly2; - } else if (key === "__v_isReadonly") { - return isReadonly2; - } else if (key === "__v_isShallow") { - return isShallow2; - } else if (key === "__v_raw") { - if (receiver === (isReadonly2 ? isShallow2 ? shallowReadonlyMap : readonlyMap : isShallow2 ? shallowReactiveMap : reactiveMap).get(target) || // receiver is not the reactive proxy, but has the same prototype - // this means the receiver is a user proxy of the reactive proxy - Object.getPrototypeOf(target) === Object.getPrototypeOf(receiver)) { - return target; - } - return; - } - const targetIsArray = isArray(target); - if (!isReadonly2) { - let fn; - if (targetIsArray && (fn = arrayInstrumentations[key])) { - return fn; - } - if (key === "hasOwnProperty") { - return hasOwnProperty2; - } - } - const res = Reflect.get( - target, - key, - // if this is a proxy wrapping a ref, return methods using the raw ref - // as receiver so that we don't have to call `toRaw` on the ref in all - // its class methods - isRef2(target) ? target : receiver - ); - if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) { - return res; - } - if (!isReadonly2) { - track(target, "get", key); - } - if (isShallow2) { - return res; - } - if (isRef2(res)) { - const value = targetIsArray && isIntegerKey(key) ? res : res.value; - return isReadonly2 && isObject(value) ? readonly(value) : value; - } - if (isObject(res)) { - return isReadonly2 ? readonly(res) : reactive(res); - } - return res; - } -}; -var MutableReactiveHandler = class extends BaseReactiveHandler { - constructor(isShallow2 = false) { - super(false, isShallow2); - } - set(target, key, value, receiver) { - let oldValue = target[key]; - const isArrayWithIntegerKey = isArray(target) && isIntegerKey(key); - if (!this._isShallow) { - const isOldValueReadonly = isReadonly(oldValue); - if (!isShallow(value) && !isReadonly(value)) { - oldValue = toRaw(oldValue); - value = toRaw(value); - } - if (!isArrayWithIntegerKey && isRef2(oldValue) && !isRef2(value)) { - if (isOldValueReadonly) { - if (true) { - warn( - `Set operation on key "${String(key)}" failed: target is readonly.`, - target[key] - ); - } - return true; - } else { - oldValue.value = value; - return true; - } - } - } - const hadKey = isArrayWithIntegerKey ? Number(key) < target.length : hasOwn(target, key); - const result = Reflect.set( - target, - key, - value, - isRef2(target) ? target : receiver - ); - if (target === toRaw(receiver)) { - if (!hadKey) { - trigger(target, "add", key, value); - } else if (hasChanged(value, oldValue)) { - trigger(target, "set", key, value, oldValue); - } - } - return result; - } - deleteProperty(target, key) { - const hadKey = hasOwn(target, key); - const oldValue = target[key]; - const result = Reflect.deleteProperty(target, key); - if (result && hadKey) { - trigger(target, "delete", key, void 0, oldValue); - } - return result; - } - has(target, key) { - const result = Reflect.has(target, key); - if (!isSymbol(key) || !builtInSymbols.has(key)) { - track(target, "has", key); - } - return result; - } - ownKeys(target) { - track( - target, - "iterate", - isArray(target) ? "length" : ITERATE_KEY - ); - return Reflect.ownKeys(target); - } -}; -var ReadonlyReactiveHandler = class extends BaseReactiveHandler { - constructor(isShallow2 = false) { - super(true, isShallow2); - } - set(target, key) { - if (true) { - warn( - `Set operation on key "${String(key)}" failed: target is readonly.`, - target - ); - } - return true; - } - deleteProperty(target, key) { - if (true) { - warn( - `Delete operation on key "${String(key)}" failed: target is readonly.`, - target - ); - } - return true; - } -}; -var mutableHandlers = new MutableReactiveHandler(); -var readonlyHandlers = new ReadonlyReactiveHandler(); -var shallowReactiveHandlers = new MutableReactiveHandler(true); -var shallowReadonlyHandlers = new ReadonlyReactiveHandler(true); -var toShallow = (value) => value; -var getProto = (v) => Reflect.getPrototypeOf(v); -function createIterableMethod(method, isReadonly2, isShallow2) { - return function(...args) { - const target = this["__v_raw"]; - const rawTarget = toRaw(target); - const targetIsMap = isMap(rawTarget); - const isPair = method === "entries" || method === Symbol.iterator && targetIsMap; - const isKeyOnly = method === "keys" && targetIsMap; - const innerIterator = target[method](...args); - const wrap = isShallow2 ? toShallow : isReadonly2 ? toReadonly : toReactive; - !isReadonly2 && track( - rawTarget, - "iterate", - isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY - ); - return { - // iterator protocol - next() { - const { value, done } = innerIterator.next(); - return done ? { value, done } : { - value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), - done - }; - }, - // iterable protocol - [Symbol.iterator]() { - return this; - } - }; - }; -} -function createReadonlyMethod(type) { - return function(...args) { - if (true) { - const key = args[0] ? `on key "${args[0]}" ` : ``; - warn( - `${capitalize(type)} operation ${key}failed: target is readonly.`, - toRaw(this) - ); - } - return type === "delete" ? false : type === "clear" ? void 0 : this; - }; -} -function createInstrumentations(readonly2, shallow) { - const instrumentations = { - get(key) { - const target = this["__v_raw"]; - const rawTarget = toRaw(target); - const rawKey = toRaw(key); - if (!readonly2) { - if (hasChanged(key, rawKey)) { - track(rawTarget, "get", key); - } - track(rawTarget, "get", rawKey); - } - const { has } = getProto(rawTarget); - const wrap = shallow ? toShallow : readonly2 ? toReadonly : toReactive; - if (has.call(rawTarget, key)) { - return wrap(target.get(key)); - } else if (has.call(rawTarget, rawKey)) { - return wrap(target.get(rawKey)); - } else if (target !== rawTarget) { - target.get(key); - } - }, - get size() { - const target = this["__v_raw"]; - !readonly2 && track(toRaw(target), "iterate", ITERATE_KEY); - return target.size; - }, - has(key) { - const target = this["__v_raw"]; - const rawTarget = toRaw(target); - const rawKey = toRaw(key); - if (!readonly2) { - if (hasChanged(key, rawKey)) { - track(rawTarget, "has", key); - } - track(rawTarget, "has", rawKey); - } - return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey); - }, - forEach(callback, thisArg) { - const observed = this; - const target = observed["__v_raw"]; - const rawTarget = toRaw(target); - const wrap = shallow ? toShallow : readonly2 ? toReadonly : toReactive; - !readonly2 && track(rawTarget, "iterate", ITERATE_KEY); - return target.forEach((value, key) => { - return callback.call(thisArg, wrap(value), wrap(key), observed); - }); - } - }; - extend( - instrumentations, - readonly2 ? { - add: createReadonlyMethod("add"), - set: createReadonlyMethod("set"), - delete: createReadonlyMethod("delete"), - clear: createReadonlyMethod("clear") - } : { - add(value) { - if (!shallow && !isShallow(value) && !isReadonly(value)) { - value = toRaw(value); - } - const target = toRaw(this); - const proto = getProto(target); - const hadKey = proto.has.call(target, value); - if (!hadKey) { - target.add(value); - trigger(target, "add", value, value); - } - return this; - }, - set(key, value) { - if (!shallow && !isShallow(value) && !isReadonly(value)) { - value = toRaw(value); - } - const target = toRaw(this); - const { has, get } = getProto(target); - let hadKey = has.call(target, key); - if (!hadKey) { - key = toRaw(key); - hadKey = has.call(target, key); - } else if (true) { - checkIdentityKeys(target, has, key); - } - const oldValue = get.call(target, key); - target.set(key, value); - if (!hadKey) { - trigger(target, "add", key, value); - } else if (hasChanged(value, oldValue)) { - trigger(target, "set", key, value, oldValue); - } - return this; - }, - delete(key) { - const target = toRaw(this); - const { has, get } = getProto(target); - let hadKey = has.call(target, key); - if (!hadKey) { - key = toRaw(key); - hadKey = has.call(target, key); - } else if (true) { - checkIdentityKeys(target, has, key); - } - const oldValue = get ? get.call(target, key) : void 0; - const result = target.delete(key); - if (hadKey) { - trigger(target, "delete", key, void 0, oldValue); - } - return result; - }, - clear() { - const target = toRaw(this); - const hadItems = target.size !== 0; - const oldTarget = true ? isMap(target) ? new Map(target) : new Set(target) : void 0; - const result = target.clear(); - if (hadItems) { - trigger( - target, - "clear", - void 0, - void 0, - oldTarget - ); - } - return result; - } - } - ); - const iteratorMethods = [ - "keys", - "values", - "entries", - Symbol.iterator - ]; - iteratorMethods.forEach((method) => { - instrumentations[method] = createIterableMethod(method, readonly2, shallow); - }); - return instrumentations; -} -function createInstrumentationGetter(isReadonly2, shallow) { - const instrumentations = createInstrumentations(isReadonly2, shallow); - return (target, key, receiver) => { - if (key === "__v_isReactive") { - return !isReadonly2; - } else if (key === "__v_isReadonly") { - return isReadonly2; - } else if (key === "__v_raw") { - return target; - } - return Reflect.get( - hasOwn(instrumentations, key) && key in target ? instrumentations : target, - key, - receiver - ); - }; -} -var mutableCollectionHandlers = { - get: createInstrumentationGetter(false, false) -}; -var shallowCollectionHandlers = { - get: createInstrumentationGetter(false, true) -}; -var readonlyCollectionHandlers = { - get: createInstrumentationGetter(true, false) -}; -var shallowReadonlyCollectionHandlers = { - get: createInstrumentationGetter(true, true) -}; -function checkIdentityKeys(target, has, key) { - const rawKey = toRaw(key); - if (rawKey !== key && has.call(target, rawKey)) { - const type = toRawType(target); - warn( - `Reactive ${type} contains both the raw and reactive versions of the same object${type === `Map` ? ` as keys` : ``}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.` - ); - } -} -var reactiveMap = /* @__PURE__ */ new WeakMap(); -var shallowReactiveMap = /* @__PURE__ */ new WeakMap(); -var readonlyMap = /* @__PURE__ */ new WeakMap(); -var shallowReadonlyMap = /* @__PURE__ */ new WeakMap(); -function targetTypeMap(rawType) { - switch (rawType) { - case "Object": - case "Array": - return 1; - case "Map": - case "Set": - case "WeakMap": - case "WeakSet": - return 2; - default: - return 0; - } -} -function getTargetType(value) { - return value["__v_skip"] || !Object.isExtensible(value) ? 0 : targetTypeMap(toRawType(value)); -} -function reactive(target) { - if (isReadonly(target)) { - return target; - } - return createReactiveObject( - target, - false, - mutableHandlers, - mutableCollectionHandlers, - reactiveMap - ); -} -function shallowReactive(target) { - return createReactiveObject( - target, - false, - shallowReactiveHandlers, - shallowCollectionHandlers, - shallowReactiveMap - ); -} -function readonly(target) { - return createReactiveObject( - target, - true, - readonlyHandlers, - readonlyCollectionHandlers, - readonlyMap - ); -} -function shallowReadonly(target) { - return createReactiveObject( - target, - true, - shallowReadonlyHandlers, - shallowReadonlyCollectionHandlers, - shallowReadonlyMap - ); -} -function createReactiveObject(target, isReadonly2, baseHandlers, collectionHandlers, proxyMap) { - if (!isObject(target)) { - if (true) { - warn( - `value cannot be made ${isReadonly2 ? "readonly" : "reactive"}: ${String( - target - )}` - ); - } - return target; - } - if (target["__v_raw"] && !(isReadonly2 && target["__v_isReactive"])) { - return target; - } - const targetType = getTargetType(target); - if (targetType === 0) { - return target; - } - const existingProxy = proxyMap.get(target); - if (existingProxy) { - return existingProxy; - } - const proxy = new Proxy( - target, - targetType === 2 ? collectionHandlers : baseHandlers - ); - proxyMap.set(target, proxy); - return proxy; -} -function isReactive(value) { - if (isReadonly(value)) { - return isReactive(value["__v_raw"]); - } - return !!(value && value["__v_isReactive"]); -} -function isReadonly(value) { - return !!(value && value["__v_isReadonly"]); -} -function isShallow(value) { - return !!(value && value["__v_isShallow"]); -} -function isProxy(value) { - return value ? !!value["__v_raw"] : false; -} -function toRaw(observed) { - const raw = observed && observed["__v_raw"]; - return raw ? toRaw(raw) : observed; -} -function markRaw(value) { - if (!hasOwn(value, "__v_skip") && Object.isExtensible(value)) { - def(value, "__v_skip", true); - } - return value; -} -var toReactive = (value) => isObject(value) ? reactive(value) : value; -var toReadonly = (value) => isObject(value) ? readonly(value) : value; -function isRef2(r) { - return r ? r["__v_isRef"] === true : false; -} -function ref(value) { - return createRef(value, false); -} -function shallowRef(value) { - return createRef(value, true); -} -function createRef(rawValue, shallow) { - if (isRef2(rawValue)) { - return rawValue; - } - return new RefImpl(rawValue, shallow); -} -var RefImpl = class { - constructor(value, isShallow2) { - this.dep = new Dep(); - this["__v_isRef"] = true; - this["__v_isShallow"] = false; - this._rawValue = isShallow2 ? value : toRaw(value); - this._value = isShallow2 ? value : toReactive(value); - this["__v_isShallow"] = isShallow2; - } - get value() { - if (true) { - this.dep.track({ - target: this, - type: "get", - key: "value" - }); - } else { - this.dep.track(); - } - return this._value; - } - set value(newValue) { - const oldValue = this._rawValue; - const useDirectValue = this["__v_isShallow"] || isShallow(newValue) || isReadonly(newValue); - newValue = useDirectValue ? newValue : toRaw(newValue); - if (hasChanged(newValue, oldValue)) { - this._rawValue = newValue; - this._value = useDirectValue ? newValue : toReactive(newValue); - if (true) { - this.dep.trigger({ - target: this, - type: "set", - key: "value", - newValue, - oldValue - }); - } else { - this.dep.trigger(); - } - } - } -}; -function triggerRef(ref2) { - if (ref2.dep) { - if (true) { - ref2.dep.trigger({ - target: ref2, - type: "set", - key: "value", - newValue: ref2._value - }); - } else { - ref2.dep.trigger(); - } - } -} -function unref(ref2) { - return isRef2(ref2) ? ref2.value : ref2; -} -function toValue(source) { - return isFunction(source) ? source() : unref(source); -} -var shallowUnwrapHandlers = { - get: (target, key, receiver) => key === "__v_raw" ? target : unref(Reflect.get(target, key, receiver)), - set: (target, key, value, receiver) => { - const oldValue = target[key]; - if (isRef2(oldValue) && !isRef2(value)) { - oldValue.value = value; - return true; - } else { - return Reflect.set(target, key, value, receiver); - } - } -}; -function proxyRefs(objectWithRefs) { - return isReactive(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers); -} -var CustomRefImpl = class { - constructor(factory) { - this["__v_isRef"] = true; - this._value = void 0; - const dep = this.dep = new Dep(); - const { get, set } = factory(dep.track.bind(dep), dep.trigger.bind(dep)); - this._get = get; - this._set = set; - } - get value() { - return this._value = this._get(); - } - set value(newVal) { - this._set(newVal); - } -}; -function customRef(factory) { - return new CustomRefImpl(factory); -} -function toRefs(object) { - if (!isProxy(object)) { - warn(`toRefs() expects a reactive object but received a plain one.`); - } - const ret = isArray(object) ? new Array(object.length) : {}; - for (const key in object) { - ret[key] = propertyToRef(object, key); - } - return ret; -} -var ObjectRefImpl = class { - constructor(_object, _key, _defaultValue) { - this._object = _object; - this._key = _key; - this._defaultValue = _defaultValue; - this["__v_isRef"] = true; - this._value = void 0; - this._raw = toRaw(_object); - let shallow = true; - let obj = _object; - if (!isArray(_object) || !isIntegerKey(String(_key))) { - do { - shallow = !isProxy(obj) || isShallow(obj); - } while (shallow && (obj = obj["__v_raw"])); - } - this._shallow = shallow; - } - get value() { - let val = this._object[this._key]; - if (this._shallow) { - val = unref(val); - } - return this._value = val === void 0 ? this._defaultValue : val; - } - set value(newVal) { - if (this._shallow && isRef2(this._raw[this._key])) { - const nestedRef = this._object[this._key]; - if (isRef2(nestedRef)) { - nestedRef.value = newVal; - return; - } - } - this._object[this._key] = newVal; - } - get dep() { - return getDepFromReactive(this._raw, this._key); - } -}; -var GetterRefImpl = class { - constructor(_getter) { - this._getter = _getter; - this["__v_isRef"] = true; - this["__v_isReadonly"] = true; - this._value = void 0; - } - get value() { - return this._value = this._getter(); - } -}; -function toRef(source, key, defaultValue) { - if (isRef2(source)) { - return source; - } else if (isFunction(source)) { - return new GetterRefImpl(source); - } else if (isObject(source) && arguments.length > 1) { - return propertyToRef(source, key, defaultValue); - } else { - return ref(source); - } -} -function propertyToRef(source, key, defaultValue) { - return new ObjectRefImpl(source, key, defaultValue); -} -var ComputedRefImpl = class { - constructor(fn, setter, isSSR) { - this.fn = fn; - this.setter = setter; - this._value = void 0; - this.dep = new Dep(this); - this.__v_isRef = true; - this.deps = void 0; - this.depsTail = void 0; - this.flags = 16; - this.globalVersion = globalVersion - 1; - this.next = void 0; - this.effect = this; - this["__v_isReadonly"] = !setter; - this.isSSR = isSSR; - } - /** - * @internal - */ - notify() { - this.flags |= 16; - if (!(this.flags & 8) && // avoid infinite self recursion - activeSub !== this) { - batch(this, true); - return true; - } else if (true) ; - } - get value() { - const link = true ? this.dep.track({ - target: this, - type: "get", - key: "value" - }) : this.dep.track(); - refreshComputed(this); - if (link) { - link.version = this.dep.version; - } - return this._value; - } - set value(newValue) { - if (this.setter) { - this.setter(newValue); - } else if (true) { - warn("Write operation failed: computed value is readonly"); - } - } -}; -function computed(getterOrOptions, debugOptions, isSSR = false) { - let getter; - let setter; - if (isFunction(getterOrOptions)) { - getter = getterOrOptions; - } else { - getter = getterOrOptions.get; - setter = getterOrOptions.set; - } - const cRef = new ComputedRefImpl(getter, setter, isSSR); - if (debugOptions && !isSSR) { - cRef.onTrack = debugOptions.onTrack; - cRef.onTrigger = debugOptions.onTrigger; - } - return cRef; -} -var TrackOpTypes = { - "GET": "get", - "HAS": "has", - "ITERATE": "iterate" -}; -var TriggerOpTypes = { - "SET": "set", - "ADD": "add", - "DELETE": "delete", - "CLEAR": "clear" -}; -var INITIAL_WATCHER_VALUE = {}; -var cleanupMap = /* @__PURE__ */ new WeakMap(); -var activeWatcher = void 0; -function getCurrentWatcher() { - return activeWatcher; -} -function onWatcherCleanup(cleanupFn, failSilently = false, owner = activeWatcher) { - if (owner) { - let cleanups = cleanupMap.get(owner); - if (!cleanups) cleanupMap.set(owner, cleanups = []); - cleanups.push(cleanupFn); - } else if (!failSilently) { - warn( - `onWatcherCleanup() was called when there was no active watcher to associate with.` - ); - } -} -function watch(source, cb, options = EMPTY_OBJ) { - const { immediate, deep, once, scheduler, augmentJob, call } = options; - const warnInvalidSource = (s) => { - (options.onWarn || warn)( - `Invalid watch source: `, - s, - `A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types.` - ); - }; - const reactiveGetter = (source2) => { - if (deep) return source2; - if (isShallow(source2) || deep === false || deep === 0) - return traverse(source2, 1); - return traverse(source2); - }; - let effect2; - let getter; - let cleanup; - let boundCleanup; - let forceTrigger = false; - let isMultiSource = false; - if (isRef2(source)) { - getter = () => source.value; - forceTrigger = isShallow(source); - } else if (isReactive(source)) { - getter = () => reactiveGetter(source); - forceTrigger = true; - } else if (isArray(source)) { - isMultiSource = true; - forceTrigger = source.some((s) => isReactive(s) || isShallow(s)); - getter = () => source.map((s) => { - if (isRef2(s)) { - return s.value; - } else if (isReactive(s)) { - return reactiveGetter(s); - } else if (isFunction(s)) { - return call ? call(s, 2) : s(); - } else { - warnInvalidSource(s); - } - }); - } else if (isFunction(source)) { - if (cb) { - getter = call ? () => call(source, 2) : source; - } else { - getter = () => { - if (cleanup) { - pauseTracking(); - try { - cleanup(); - } finally { - resetTracking(); - } - } - const currentEffect = activeWatcher; - activeWatcher = effect2; - try { - return call ? call(source, 3, [boundCleanup]) : source(boundCleanup); - } finally { - activeWatcher = currentEffect; - } - }; - } - } else { - getter = NOOP; - warnInvalidSource(source); - } - if (cb && deep) { - const baseGetter = getter; - const depth = deep === true ? Infinity : deep; - getter = () => traverse(baseGetter(), depth); - } - const scope = getCurrentScope(); - const watchHandle = () => { - effect2.stop(); - if (scope && scope.active) { - remove(scope.effects, effect2); - } - }; - if (once && cb) { - const _cb = cb; - cb = (...args) => { - _cb(...args); - watchHandle(); - }; - } - let oldValue = isMultiSource ? new Array(source.length).fill(INITIAL_WATCHER_VALUE) : INITIAL_WATCHER_VALUE; - const job = (immediateFirstRun) => { - if (!(effect2.flags & 1) || !effect2.dirty && !immediateFirstRun) { - return; - } - if (cb) { - const newValue = effect2.run(); - if (deep || forceTrigger || (isMultiSource ? newValue.some((v, i) => hasChanged(v, oldValue[i])) : hasChanged(newValue, oldValue))) { - if (cleanup) { - cleanup(); - } - const currentWatcher = activeWatcher; - activeWatcher = effect2; - try { - const args = [ - newValue, - // pass undefined as the old value when it's changed for the first time - oldValue === INITIAL_WATCHER_VALUE ? void 0 : isMultiSource && oldValue[0] === INITIAL_WATCHER_VALUE ? [] : oldValue, - boundCleanup - ]; - oldValue = newValue; - call ? call(cb, 3, args) : ( - // @ts-expect-error - cb(...args) - ); - } finally { - activeWatcher = currentWatcher; - } - } - } else { - effect2.run(); - } - }; - if (augmentJob) { - augmentJob(job); - } - effect2 = new ReactiveEffect(getter); - effect2.scheduler = scheduler ? () => scheduler(job, false) : job; - boundCleanup = (fn) => onWatcherCleanup(fn, false, effect2); - cleanup = effect2.onStop = () => { - const cleanups = cleanupMap.get(effect2); - if (cleanups) { - if (call) { - call(cleanups, 4); - } else { - for (const cleanup2 of cleanups) cleanup2(); - } - cleanupMap.delete(effect2); - } - }; - if (true) { - effect2.onTrack = options.onTrack; - effect2.onTrigger = options.onTrigger; - } - if (cb) { - if (immediate) { - job(true); - } else { - oldValue = effect2.run(); - } - } else if (scheduler) { - scheduler(job.bind(null, true), true); - } else { - effect2.run(); - } - watchHandle.pause = effect2.pause.bind(effect2); - watchHandle.resume = effect2.resume.bind(effect2); - watchHandle.stop = watchHandle; - return watchHandle; -} -function traverse(value, depth = Infinity, seen) { - if (depth <= 0 || !isObject(value) || value["__v_skip"]) { - return value; - } - seen = seen || /* @__PURE__ */ new Map(); - if ((seen.get(value) || 0) >= depth) { - return value; - } - seen.set(value, depth); - depth--; - if (isRef2(value)) { - traverse(value.value, depth, seen); - } else if (isArray(value)) { - for (let i = 0; i < value.length; i++) { - traverse(value[i], depth, seen); - } - } else if (isSet(value) || isMap(value)) { - value.forEach((v) => { - traverse(v, depth, seen); - }); - } else if (isPlainObject(value)) { - for (const key in value) { - traverse(value[key], depth, seen); - } - for (const key of Object.getOwnPropertySymbols(value)) { - if (Object.prototype.propertyIsEnumerable.call(value, key)) { - traverse(value[key], depth, seen); - } - } - } - return value; -} - -// node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js -var stack = []; -function pushWarningContext(vnode) { - stack.push(vnode); -} -function popWarningContext() { - stack.pop(); -} -var isWarning = false; -function warn$1(msg, ...args) { - if (isWarning) return; - isWarning = true; - pauseTracking(); - const instance = stack.length ? stack[stack.length - 1].component : null; - const appWarnHandler = instance && instance.appContext.config.warnHandler; - const trace = getComponentTrace(); - if (appWarnHandler) { - callWithErrorHandling( - appWarnHandler, - instance, - 11, - [ - // eslint-disable-next-line no-restricted-syntax - msg + args.map((a) => { - var _a, _b; - return (_b = (_a = a.toString) == null ? void 0 : _a.call(a)) != null ? _b : JSON.stringify(a); - }).join(""), - instance && instance.proxy, - trace.map( - ({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>` - ).join("\n"), - trace - ] - ); - } else { - const warnArgs = [`[Vue warn]: ${msg}`, ...args]; - if (trace.length && // avoid spamming console during tests - true) { - warnArgs.push(` -`, ...formatTrace(trace)); - } - console.warn(...warnArgs); - } - resetTracking(); - isWarning = false; -} -function getComponentTrace() { - let currentVNode = stack[stack.length - 1]; - if (!currentVNode) { - return []; - } - const normalizedStack = []; - while (currentVNode) { - const last = normalizedStack[0]; - if (last && last.vnode === currentVNode) { - last.recurseCount++; - } else { - normalizedStack.push({ - vnode: currentVNode, - recurseCount: 0 - }); - } - const parentInstance = currentVNode.component && currentVNode.component.parent; - currentVNode = parentInstance && parentInstance.vnode; - } - return normalizedStack; -} -function formatTrace(trace) { - const logs = []; - trace.forEach((entry, i) => { - logs.push(...i === 0 ? [] : [` -`], ...formatTraceEntry(entry)); - }); - return logs; -} -function formatTraceEntry({ vnode, recurseCount }) { - const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``; - const isRoot = vnode.component ? vnode.component.parent == null : false; - const open = ` at <${formatComponentName( - vnode.component, - vnode.type, - isRoot - )}`; - const close = `>` + postfix; - return vnode.props ? [open, ...formatProps(vnode.props), close] : [open + close]; -} -function formatProps(props) { - const res = []; - const keys = Object.keys(props); - keys.slice(0, 3).forEach((key) => { - res.push(...formatProp(key, props[key])); - }); - if (keys.length > 3) { - res.push(` ...`); - } - return res; -} -function formatProp(key, value, raw) { - if (isString(value)) { - value = JSON.stringify(value); - return raw ? value : [`${key}=${value}`]; - } else if (typeof value === "number" || typeof value === "boolean" || value == null) { - return raw ? value : [`${key}=${value}`]; - } else if (isRef2(value)) { - value = formatProp(key, toRaw(value.value), true); - return raw ? value : [`${key}=Ref<`, value, `>`]; - } else if (isFunction(value)) { - return [`${key}=fn${value.name ? `<${value.name}>` : ``}`]; - } else { - value = toRaw(value); - return raw ? value : [`${key}=`, value]; - } -} -function assertNumber(val, type) { - if (false) return; - if (val === void 0) { - return; - } else if (typeof val !== "number") { - warn$1(`${type} is not a valid number - got ${JSON.stringify(val)}.`); - } else if (isNaN(val)) { - warn$1(`${type} is NaN - the duration expression might be incorrect.`); - } -} -var ErrorCodes = { - "SETUP_FUNCTION": 0, - "0": "SETUP_FUNCTION", - "RENDER_FUNCTION": 1, - "1": "RENDER_FUNCTION", - "NATIVE_EVENT_HANDLER": 5, - "5": "NATIVE_EVENT_HANDLER", - "COMPONENT_EVENT_HANDLER": 6, - "6": "COMPONENT_EVENT_HANDLER", - "VNODE_HOOK": 7, - "7": "VNODE_HOOK", - "DIRECTIVE_HOOK": 8, - "8": "DIRECTIVE_HOOK", - "TRANSITION_HOOK": 9, - "9": "TRANSITION_HOOK", - "APP_ERROR_HANDLER": 10, - "10": "APP_ERROR_HANDLER", - "APP_WARN_HANDLER": 11, - "11": "APP_WARN_HANDLER", - "FUNCTION_REF": 12, - "12": "FUNCTION_REF", - "ASYNC_COMPONENT_LOADER": 13, - "13": "ASYNC_COMPONENT_LOADER", - "SCHEDULER": 14, - "14": "SCHEDULER", - "COMPONENT_UPDATE": 15, - "15": "COMPONENT_UPDATE", - "APP_UNMOUNT_CLEANUP": 16, - "16": "APP_UNMOUNT_CLEANUP" -}; -var ErrorTypeStrings$1 = { - ["sp"]: "serverPrefetch hook", - ["bc"]: "beforeCreate hook", - ["c"]: "created hook", - ["bm"]: "beforeMount hook", - ["m"]: "mounted hook", - ["bu"]: "beforeUpdate hook", - ["u"]: "updated", - ["bum"]: "beforeUnmount hook", - ["um"]: "unmounted hook", - ["a"]: "activated hook", - ["da"]: "deactivated hook", - ["ec"]: "errorCaptured hook", - ["rtc"]: "renderTracked hook", - ["rtg"]: "renderTriggered hook", - [0]: "setup function", - [1]: "render function", - [2]: "watcher getter", - [3]: "watcher callback", - [4]: "watcher cleanup function", - [5]: "native event handler", - [6]: "component event handler", - [7]: "vnode hook", - [8]: "directive hook", - [9]: "transition hook", - [10]: "app errorHandler", - [11]: "app warnHandler", - [12]: "ref function", - [13]: "async component loader", - [14]: "scheduler flush", - [15]: "component update", - [16]: "app unmount cleanup function" -}; -function callWithErrorHandling(fn, instance, type, args) { - try { - return args ? fn(...args) : fn(); - } catch (err) { - handleError(err, instance, type); - } -} -function callWithAsyncErrorHandling(fn, instance, type, args) { - if (isFunction(fn)) { - const res = callWithErrorHandling(fn, instance, type, args); - if (res && isPromise(res)) { - res.catch((err) => { - handleError(err, instance, type); - }); - } - return res; - } - if (isArray(fn)) { - const values = []; - for (let i = 0; i < fn.length; i++) { - values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)); - } - return values; - } else if (true) { - warn$1( - `Invalid value type passed to callWithAsyncErrorHandling(): ${typeof fn}` - ); - } -} -function handleError(err, instance, type, throwInDev = true) { - const contextVNode = instance ? instance.vnode : null; - const { errorHandler, throwUnhandledErrorInProduction } = instance && instance.appContext.config || EMPTY_OBJ; - if (instance) { - let cur = instance.parent; - const exposedInstance = instance.proxy; - const errorInfo = true ? ErrorTypeStrings$1[type] : `https://vuejs.org/error-reference/#runtime-${type}`; - while (cur) { - const errorCapturedHooks = cur.ec; - if (errorCapturedHooks) { - for (let i = 0; i < errorCapturedHooks.length; i++) { - if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) { - return; - } - } - } - cur = cur.parent; - } - if (errorHandler) { - pauseTracking(); - callWithErrorHandling(errorHandler, null, 10, [ - err, - exposedInstance, - errorInfo - ]); - resetTracking(); - return; - } - } - logError(err, type, contextVNode, throwInDev, throwUnhandledErrorInProduction); -} -function logError(err, type, contextVNode, throwInDev = true, throwInProd = false) { - if (true) { - const info = ErrorTypeStrings$1[type]; - if (contextVNode) { - pushWarningContext(contextVNode); - } - warn$1(`Unhandled error${info ? ` during execution of ${info}` : ``}`); - if (contextVNode) { - popWarningContext(); - } - if (throwInDev) { - throw err; - } else { - console.error(err); - } - } else if (throwInProd) { - throw err; - } else { - console.error(err); - } -} -var queue = []; -var flushIndex = -1; -var pendingPostFlushCbs = []; -var activePostFlushCbs = null; -var postFlushIndex = 0; -var resolvedPromise = Promise.resolve(); -var currentFlushPromise = null; -var RECURSION_LIMIT = 100; -function nextTick(fn) { - const p2 = currentFlushPromise || resolvedPromise; - return fn ? p2.then(this ? fn.bind(this) : fn) : p2; -} -function findInsertionIndex(id) { - let start = flushIndex + 1; - let end = queue.length; - while (start < end) { - const middle = start + end >>> 1; - const middleJob = queue[middle]; - const middleJobId = getId(middleJob); - if (middleJobId < id || middleJobId === id && middleJob.flags & 2) { - start = middle + 1; - } else { - end = middle; - } - } - return start; -} -function queueJob(job) { - if (!(job.flags & 1)) { - const jobId = getId(job); - const lastJob = queue[queue.length - 1]; - if (!lastJob || // fast path when the job id is larger than the tail - !(job.flags & 2) && jobId >= getId(lastJob)) { - queue.push(job); - } else { - queue.splice(findInsertionIndex(jobId), 0, job); - } - job.flags |= 1; - queueFlush(); - } -} -function queueFlush() { - if (!currentFlushPromise) { - currentFlushPromise = resolvedPromise.then(flushJobs); - } -} -function queuePostFlushCb(cb) { - if (!isArray(cb)) { - if (activePostFlushCbs && cb.id === -1) { - activePostFlushCbs.splice(postFlushIndex + 1, 0, cb); - } else if (!(cb.flags & 1)) { - pendingPostFlushCbs.push(cb); - cb.flags |= 1; - } - } else { - pendingPostFlushCbs.push(...cb); - } - queueFlush(); -} -function flushPreFlushCbs(instance, seen, i = flushIndex + 1) { - if (true) { - seen = seen || /* @__PURE__ */ new Map(); - } - for (; i < queue.length; i++) { - const cb = queue[i]; - if (cb && cb.flags & 2) { - if (instance && cb.id !== instance.uid) { - continue; - } - if (checkRecursiveUpdates(seen, cb)) { - continue; - } - queue.splice(i, 1); - i--; - if (cb.flags & 4) { - cb.flags &= -2; - } - cb(); - if (!(cb.flags & 4)) { - cb.flags &= -2; - } - } - } -} -function flushPostFlushCbs(seen) { - if (pendingPostFlushCbs.length) { - const deduped = [...new Set(pendingPostFlushCbs)].sort( - (a, b) => getId(a) - getId(b) - ); - pendingPostFlushCbs.length = 0; - if (activePostFlushCbs) { - activePostFlushCbs.push(...deduped); - return; - } - activePostFlushCbs = deduped; - if (true) { - seen = seen || /* @__PURE__ */ new Map(); - } - for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) { - const cb = activePostFlushCbs[postFlushIndex]; - if (checkRecursiveUpdates(seen, cb)) { - continue; - } - if (cb.flags & 4) { - cb.flags &= -2; - } - if (!(cb.flags & 8)) cb(); - cb.flags &= -2; - } - activePostFlushCbs = null; - postFlushIndex = 0; - } -} -var getId = (job) => job.id == null ? job.flags & 2 ? -1 : Infinity : job.id; -function flushJobs(seen) { - if (true) { - seen = seen || /* @__PURE__ */ new Map(); - } - const check = true ? (job) => checkRecursiveUpdates(seen, job) : NOOP; - try { - for (flushIndex = 0; flushIndex < queue.length; flushIndex++) { - const job = queue[flushIndex]; - if (job && !(job.flags & 8)) { - if (check(job)) { - continue; - } - if (job.flags & 4) { - job.flags &= ~1; - } - callWithErrorHandling( - job, - job.i, - job.i ? 15 : 14 - ); - if (!(job.flags & 4)) { - job.flags &= ~1; - } - } - } - } finally { - for (; flushIndex < queue.length; flushIndex++) { - const job = queue[flushIndex]; - if (job) { - job.flags &= -2; - } - } - flushIndex = -1; - queue.length = 0; - flushPostFlushCbs(seen); - currentFlushPromise = null; - if (queue.length || pendingPostFlushCbs.length) { - flushJobs(seen); - } - } -} -function checkRecursiveUpdates(seen, fn) { - const count = seen.get(fn) || 0; - if (count > RECURSION_LIMIT) { - const instance = fn.i; - const componentName = instance && getComponentName(instance.type); - handleError( - `Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.`, - null, - 10 - ); - return true; - } - seen.set(fn, count + 1); - return false; -} -var isHmrUpdating = false; -var hmrDirtyComponents = /* @__PURE__ */ new Map(); -if (true) { - getGlobalThis().__VUE_HMR_RUNTIME__ = { - createRecord: tryWrap(createRecord), - rerender: tryWrap(rerender), - reload: tryWrap(reload) - }; -} -var map = /* @__PURE__ */ new Map(); -function registerHMR(instance) { - const id = instance.type.__hmrId; - let record = map.get(id); - if (!record) { - createRecord(id, instance.type); - record = map.get(id); - } - record.instances.add(instance); -} -function unregisterHMR(instance) { - map.get(instance.type.__hmrId).instances.delete(instance); -} -function createRecord(id, initialDef) { - if (map.has(id)) { - return false; - } - map.set(id, { - initialDef: normalizeClassComponent(initialDef), - instances: /* @__PURE__ */ new Set() - }); - return true; -} -function normalizeClassComponent(component) { - return isClassComponent(component) ? component.__vccOpts : component; -} -function rerender(id, newRender) { - const record = map.get(id); - if (!record) { - return; - } - record.initialDef.render = newRender; - [...record.instances].forEach((instance) => { - if (newRender) { - instance.render = newRender; - normalizeClassComponent(instance.type).render = newRender; - } - instance.renderCache = []; - isHmrUpdating = true; - if (!(instance.job.flags & 8)) { - instance.update(); - } - isHmrUpdating = false; - }); -} -function reload(id, newComp) { - const record = map.get(id); - if (!record) return; - newComp = normalizeClassComponent(newComp); - updateComponentDef(record.initialDef, newComp); - const instances = [...record.instances]; - for (let i = 0; i < instances.length; i++) { - const instance = instances[i]; - const oldComp = normalizeClassComponent(instance.type); - let dirtyInstances = hmrDirtyComponents.get(oldComp); - if (!dirtyInstances) { - if (oldComp !== record.initialDef) { - updateComponentDef(oldComp, newComp); - } - hmrDirtyComponents.set(oldComp, dirtyInstances = /* @__PURE__ */ new Set()); - } - dirtyInstances.add(instance); - instance.appContext.propsCache.delete(instance.type); - instance.appContext.emitsCache.delete(instance.type); - instance.appContext.optionsCache.delete(instance.type); - if (instance.ceReload) { - dirtyInstances.add(instance); - instance.ceReload(newComp.styles); - dirtyInstances.delete(instance); - } else if (instance.parent) { - queueJob(() => { - if (!(instance.job.flags & 8)) { - isHmrUpdating = true; - instance.parent.update(); - isHmrUpdating = false; - dirtyInstances.delete(instance); - } - }); - } else if (instance.appContext.reload) { - instance.appContext.reload(); - } else if (typeof window !== "undefined") { - window.location.reload(); - } else { - console.warn( - "[HMR] Root or manually mounted instance modified. Full reload required." - ); - } - if (instance.root.ce && instance !== instance.root) { - instance.root.ce._removeChildStyle(oldComp); - } - } - queuePostFlushCb(() => { - hmrDirtyComponents.clear(); - }); -} -function updateComponentDef(oldComp, newComp) { - extend(oldComp, newComp); - for (const key in oldComp) { - if (key !== "__file" && !(key in newComp)) { - delete oldComp[key]; - } - } -} -function tryWrap(fn) { - return (id, arg) => { - try { - return fn(id, arg); - } catch (e) { - console.error(e); - console.warn( - `[HMR] Something went wrong during Vue component hot-reload. Full reload required.` - ); - } - }; -} -var devtools$1; -var buffer = []; -var devtoolsNotInstalled = false; -function emit$1(event, ...args) { - if (devtools$1) { - devtools$1.emit(event, ...args); - } else if (!devtoolsNotInstalled) { - buffer.push({ event, args }); - } -} -function setDevtoolsHook$1(hook, target) { - var _a, _b; - devtools$1 = hook; - if (devtools$1) { - devtools$1.enabled = true; - buffer.forEach(({ event, args }) => devtools$1.emit(event, ...args)); - buffer = []; - } else if ( - // handle late devtools injection - only do this if we are in an actual - // browser environment to avoid the timer handle stalling test runner exit - // (#4815) - typeof window !== "undefined" && // some envs mock window but not fully - window.HTMLElement && // also exclude jsdom - // eslint-disable-next-line no-restricted-syntax - !((_b = (_a = window.navigator) == null ? void 0 : _a.userAgent) == null ? void 0 : _b.includes("jsdom")) - ) { - const replay = target.__VUE_DEVTOOLS_HOOK_REPLAY__ = target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []; - replay.push((newHook) => { - setDevtoolsHook$1(newHook, target); - }); - setTimeout(() => { - if (!devtools$1) { - target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null; - devtoolsNotInstalled = true; - buffer = []; - } - }, 3e3); - } else { - devtoolsNotInstalled = true; - buffer = []; - } -} -function devtoolsInitApp(app, version2) { - emit$1("app:init", app, version2, { - Fragment, - Text, - Comment, - Static - }); -} -function devtoolsUnmountApp(app) { - emit$1("app:unmount", app); -} -var devtoolsComponentAdded = createDevtoolsComponentHook( - "component:added" - /* COMPONENT_ADDED */ -); -var devtoolsComponentUpdated = createDevtoolsComponentHook( - "component:updated" - /* COMPONENT_UPDATED */ -); -var _devtoolsComponentRemoved = createDevtoolsComponentHook( - "component:removed" - /* COMPONENT_REMOVED */ -); -var devtoolsComponentRemoved = (component) => { - if (devtools$1 && typeof devtools$1.cleanupBuffer === "function" && // remove the component if it wasn't buffered - !devtools$1.cleanupBuffer(component)) { - _devtoolsComponentRemoved(component); - } -}; -function createDevtoolsComponentHook(hook) { - return (component) => { - emit$1( - hook, - component.appContext.app, - component.uid, - component.parent ? component.parent.uid : void 0, - component - ); - }; -} -var devtoolsPerfStart = createDevtoolsPerformanceHook( - "perf:start" - /* PERFORMANCE_START */ -); -var devtoolsPerfEnd = createDevtoolsPerformanceHook( - "perf:end" - /* PERFORMANCE_END */ -); -function createDevtoolsPerformanceHook(hook) { - return (component, type, time) => { - emit$1(hook, component.appContext.app, component.uid, component, type, time); - }; -} -function devtoolsComponentEmit(component, event, params) { - emit$1( - "component:emit", - component.appContext.app, - component, - event, - params - ); -} -var currentRenderingInstance = null; -var currentScopeId = null; -function setCurrentRenderingInstance(instance) { - const prev = currentRenderingInstance; - currentRenderingInstance = instance; - currentScopeId = instance && instance.type.__scopeId || null; - return prev; -} -function pushScopeId(id) { - currentScopeId = id; -} -function popScopeId() { - currentScopeId = null; -} -var withScopeId = (_id) => withCtx; -function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot) { - if (!ctx) return fn; - if (fn._n) { - return fn; - } - const renderFnWithContext = (...args) => { - if (renderFnWithContext._d) { - setBlockTracking(-1); - } - const prevInstance = setCurrentRenderingInstance(ctx); - let res; - try { - res = fn(...args); - } finally { - setCurrentRenderingInstance(prevInstance); - if (renderFnWithContext._d) { - setBlockTracking(1); - } - } - if (true) { - devtoolsComponentUpdated(ctx); - } - return res; - }; - renderFnWithContext._n = true; - renderFnWithContext._c = true; - renderFnWithContext._d = true; - return renderFnWithContext; -} -function validateDirectiveName(name) { - if (isBuiltInDirective(name)) { - warn$1("Do not use built-in directive ids as custom directive id: " + name); - } -} -function withDirectives(vnode, directives) { - if (currentRenderingInstance === null) { - warn$1(`withDirectives can only be used inside render functions.`); - return vnode; - } - const instance = getComponentPublicInstance(currentRenderingInstance); - const bindings = vnode.dirs || (vnode.dirs = []); - for (let i = 0; i < directives.length; i++) { - let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i]; - if (dir) { - if (isFunction(dir)) { - dir = { - mounted: dir, - updated: dir - }; - } - if (dir.deep) { - traverse(value); - } - bindings.push({ - dir, - instance, - value, - oldValue: void 0, - arg, - modifiers - }); - } - } - return vnode; -} -function invokeDirectiveHook(vnode, prevVNode, instance, name) { - const bindings = vnode.dirs; - const oldBindings = prevVNode && prevVNode.dirs; - for (let i = 0; i < bindings.length; i++) { - const binding = bindings[i]; - if (oldBindings) { - binding.oldValue = oldBindings[i].value; - } - let hook = binding.dir[name]; - if (hook) { - pauseTracking(); - callWithAsyncErrorHandling(hook, instance, 8, [ - vnode.el, - binding, - vnode, - prevVNode - ]); - resetTracking(); - } - } -} -function provide(key, value) { - if (true) { - if (!currentInstance || currentInstance.isMounted) { - warn$1(`provide() can only be used inside setup().`); - } - } - if (currentInstance) { - let provides = currentInstance.provides; - const parentProvides = currentInstance.parent && currentInstance.parent.provides; - if (parentProvides === provides) { - provides = currentInstance.provides = Object.create(parentProvides); - } - provides[key] = value; - } -} -function inject(key, defaultValue, treatDefaultAsFactory = false) { - const instance = getCurrentInstance(); - if (instance || currentApp) { - let provides = currentApp ? currentApp._context.provides : instance ? instance.parent == null || instance.ce ? instance.vnode.appContext && instance.vnode.appContext.provides : instance.parent.provides : void 0; - if (provides && key in provides) { - return provides[key]; - } else if (arguments.length > 1) { - return treatDefaultAsFactory && isFunction(defaultValue) ? defaultValue.call(instance && instance.proxy) : defaultValue; - } else if (true) { - warn$1(`injection "${String(key)}" not found.`); - } - } else if (true) { - warn$1(`inject() can only be used inside setup() or functional components.`); - } -} -function hasInjectionContext() { - return !!(getCurrentInstance() || currentApp); -} -var ssrContextKey = Symbol.for("v-scx"); -var useSSRContext = () => { - { - const ctx = inject(ssrContextKey); - if (!ctx) { - warn$1( - `Server rendering context not provided. Make sure to only call useSSRContext() conditionally in the server build.` - ); - } - return ctx; - } -}; -function watchEffect(effect2, options) { - return doWatch(effect2, null, options); -} -function watchPostEffect(effect2, options) { - return doWatch( - effect2, - null, - true ? extend({}, options, { flush: "post" }) : { flush: "post" } - ); -} -function watchSyncEffect(effect2, options) { - return doWatch( - effect2, - null, - true ? extend({}, options, { flush: "sync" }) : { flush: "sync" } - ); -} -function watch2(source, cb, options) { - if (!isFunction(cb)) { - warn$1( - `\`watch(fn, options?)\` signature has been moved to a separate API. Use \`watchEffect(fn, options?)\` instead. \`watch\` now only supports \`watch(source, cb, options?) signature.` - ); - } - return doWatch(source, cb, options); -} -function doWatch(source, cb, options = EMPTY_OBJ) { - const { immediate, deep, flush, once } = options; - if (!cb) { - if (immediate !== void 0) { - warn$1( - `watch() "immediate" option is only respected when using the watch(source, callback, options?) signature.` - ); - } - if (deep !== void 0) { - warn$1( - `watch() "deep" option is only respected when using the watch(source, callback, options?) signature.` - ); - } - if (once !== void 0) { - warn$1( - `watch() "once" option is only respected when using the watch(source, callback, options?) signature.` - ); - } - } - const baseWatchOptions = extend({}, options); - if (true) baseWatchOptions.onWarn = warn$1; - const runsImmediately = cb && immediate || !cb && flush !== "post"; - let ssrCleanup; - if (isInSSRComponentSetup) { - if (flush === "sync") { - const ctx = useSSRContext(); - ssrCleanup = ctx.__watcherHandles || (ctx.__watcherHandles = []); - } else if (!runsImmediately) { - const watchStopHandle = () => { - }; - watchStopHandle.stop = NOOP; - watchStopHandle.resume = NOOP; - watchStopHandle.pause = NOOP; - return watchStopHandle; - } - } - const instance = currentInstance; - baseWatchOptions.call = (fn, type, args) => callWithAsyncErrorHandling(fn, instance, type, args); - let isPre = false; - if (flush === "post") { - baseWatchOptions.scheduler = (job) => { - queuePostRenderEffect(job, instance && instance.suspense); - }; - } else if (flush !== "sync") { - isPre = true; - baseWatchOptions.scheduler = (job, isFirstRun) => { - if (isFirstRun) { - job(); - } else { - queueJob(job); - } - }; - } - baseWatchOptions.augmentJob = (job) => { - if (cb) { - job.flags |= 4; - } - if (isPre) { - job.flags |= 2; - if (instance) { - job.id = instance.uid; - job.i = instance; - } - } - }; - const watchHandle = watch(source, cb, baseWatchOptions); - if (isInSSRComponentSetup) { - if (ssrCleanup) { - ssrCleanup.push(watchHandle); - } else if (runsImmediately) { - watchHandle(); - } - } - return watchHandle; -} -function instanceWatch(source, value, options) { - const publicThis = this.proxy; - const getter = isString(source) ? source.includes(".") ? createPathGetter(publicThis, source) : () => publicThis[source] : source.bind(publicThis, publicThis); - let cb; - if (isFunction(value)) { - cb = value; - } else { - cb = value.handler; - options = value; - } - const reset = setCurrentInstance(this); - const res = doWatch(getter, cb.bind(publicThis), options); - reset(); - return res; -} -function createPathGetter(ctx, path) { - const segments = path.split("."); - return () => { - let cur = ctx; - for (let i = 0; i < segments.length && cur; i++) { - cur = cur[segments[i]]; - } - return cur; - }; -} -var TeleportEndKey = Symbol("_vte"); -var isTeleport = (type) => type.__isTeleport; -var isTeleportDisabled = (props) => props && (props.disabled || props.disabled === ""); -var isTeleportDeferred = (props) => props && (props.defer || props.defer === ""); -var isTargetSVG = (target) => typeof SVGElement !== "undefined" && target instanceof SVGElement; -var isTargetMathML = (target) => typeof MathMLElement === "function" && target instanceof MathMLElement; -var resolveTarget = (props, select) => { - const targetSelector = props && props.to; - if (isString(targetSelector)) { - if (!select) { - warn$1( - `Current renderer does not support string target for Teleports. (missing querySelector renderer option)` - ); - return null; - } else { - const target = select(targetSelector); - if (!target && !isTeleportDisabled(props)) { - warn$1( - `Failed to locate Teleport target with selector "${targetSelector}". Note the target element must exist before the component is mounted - i.e. the target cannot be rendered by the component itself, and ideally should be outside of the entire Vue component tree.` - ); - } - return target; - } - } else { - if (!targetSelector && !isTeleportDisabled(props)) { - warn$1(`Invalid Teleport target: ${targetSelector}`); - } - return targetSelector; - } -}; -var TeleportImpl = { - name: "Teleport", - __isTeleport: true, - process(n1, n2, container, anchor, parentComponent, parentSuspense, namespace, slotScopeIds, optimized, internals) { - const { - mc: mountChildren, - pc: patchChildren, - pbc: patchBlockChildren, - o: { insert, querySelector, createText, createComment } - } = internals; - const disabled = isTeleportDisabled(n2.props); - let { shapeFlag, children, dynamicChildren } = n2; - if (isHmrUpdating) { - optimized = false; - dynamicChildren = null; - } - if (n1 == null) { - const placeholder = n2.el = true ? createComment("teleport start") : createText(""); - const mainAnchor = n2.anchor = true ? createComment("teleport end") : createText(""); - insert(placeholder, container, anchor); - insert(mainAnchor, container, anchor); - const mount = (container2, anchor2) => { - if (shapeFlag & 16) { - mountChildren( - children, - container2, - anchor2, - parentComponent, - parentSuspense, - namespace, - slotScopeIds, - optimized - ); - } - }; - const mountToTarget = () => { - const target = n2.target = resolveTarget(n2.props, querySelector); - const targetAnchor = prepareAnchor(target, n2, createText, insert); - if (target) { - if (namespace !== "svg" && isTargetSVG(target)) { - namespace = "svg"; - } else if (namespace !== "mathml" && isTargetMathML(target)) { - namespace = "mathml"; - } - if (parentComponent && parentComponent.isCE) { - (parentComponent.ce._teleportTargets || (parentComponent.ce._teleportTargets = /* @__PURE__ */ new Set())).add(target); - } - if (!disabled) { - mount(target, targetAnchor); - updateCssVars(n2, false); - } - } else if (!disabled) { - warn$1( - "Invalid Teleport target on mount:", - target, - `(${typeof target})` - ); - } - }; - if (disabled) { - mount(container, mainAnchor); - updateCssVars(n2, true); - } - if (isTeleportDeferred(n2.props)) { - n2.el.__isMounted = false; - queuePostRenderEffect(() => { - mountToTarget(); - delete n2.el.__isMounted; - }, parentSuspense); - } else { - mountToTarget(); - } - } else { - if (isTeleportDeferred(n2.props) && n1.el.__isMounted === false) { - queuePostRenderEffect(() => { - TeleportImpl.process( - n1, - n2, - container, - anchor, - parentComponent, - parentSuspense, - namespace, - slotScopeIds, - optimized, - internals - ); - }, parentSuspense); - return; - } - n2.el = n1.el; - n2.targetStart = n1.targetStart; - const mainAnchor = n2.anchor = n1.anchor; - const target = n2.target = n1.target; - const targetAnchor = n2.targetAnchor = n1.targetAnchor; - const wasDisabled = isTeleportDisabled(n1.props); - const currentContainer = wasDisabled ? container : target; - const currentAnchor = wasDisabled ? mainAnchor : targetAnchor; - if (namespace === "svg" || isTargetSVG(target)) { - namespace = "svg"; - } else if (namespace === "mathml" || isTargetMathML(target)) { - namespace = "mathml"; - } - if (dynamicChildren) { - patchBlockChildren( - n1.dynamicChildren, - dynamicChildren, - currentContainer, - parentComponent, - parentSuspense, - namespace, - slotScopeIds - ); - traverseStaticChildren(n1, n2, false); - } else if (!optimized) { - patchChildren( - n1, - n2, - currentContainer, - currentAnchor, - parentComponent, - parentSuspense, - namespace, - slotScopeIds, - false - ); - } - if (disabled) { - if (!wasDisabled) { - moveTeleport( - n2, - container, - mainAnchor, - internals, - 1 - ); - } else { - if (n2.props && n1.props && n2.props.to !== n1.props.to) { - n2.props.to = n1.props.to; - } - } - } else { - if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) { - const nextTarget = n2.target = resolveTarget( - n2.props, - querySelector - ); - if (nextTarget) { - moveTeleport( - n2, - nextTarget, - null, - internals, - 0 - ); - } else if (true) { - warn$1( - "Invalid Teleport target on update:", - target, - `(${typeof target})` - ); - } - } else if (wasDisabled) { - moveTeleport( - n2, - target, - targetAnchor, - internals, - 1 - ); - } - } - updateCssVars(n2, disabled); - } - }, - remove(vnode, parentComponent, parentSuspense, { um: unmount, o: { remove: hostRemove } }, doRemove) { - const { - shapeFlag, - children, - anchor, - targetStart, - targetAnchor, - target, - props - } = vnode; - if (target) { - hostRemove(targetStart); - hostRemove(targetAnchor); - } - doRemove && hostRemove(anchor); - if (shapeFlag & 16) { - const shouldRemove = doRemove || !isTeleportDisabled(props); - for (let i = 0; i < children.length; i++) { - const child = children[i]; - unmount( - child, - parentComponent, - parentSuspense, - shouldRemove, - !!child.dynamicChildren - ); - } - } - }, - move: moveTeleport, - hydrate: hydrateTeleport -}; -function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2) { - if (moveType === 0) { - insert(vnode.targetAnchor, container, parentAnchor); - } - const { el, anchor, shapeFlag, children, props } = vnode; - const isReorder = moveType === 2; - if (isReorder) { - insert(el, container, parentAnchor); - } - if (!isReorder || isTeleportDisabled(props)) { - if (shapeFlag & 16) { - for (let i = 0; i < children.length; i++) { - move( - children[i], - container, - parentAnchor, - 2 - ); - } - } - } - if (isReorder) { - insert(anchor, container, parentAnchor); - } -} -function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { - o: { nextSibling, parentNode, querySelector, insert, createText } -}, hydrateChildren) { - function hydrateDisabledTeleport(node2, vnode2, targetStart, targetAnchor) { - vnode2.anchor = hydrateChildren( - nextSibling(node2), - vnode2, - parentNode(node2), - parentComponent, - parentSuspense, - slotScopeIds, - optimized - ); - vnode2.targetStart = targetStart; - vnode2.targetAnchor = targetAnchor; - } - const target = vnode.target = resolveTarget( - vnode.props, - querySelector - ); - const disabled = isTeleportDisabled(vnode.props); - if (target) { - const targetNode = target._lpa || target.firstChild; - if (vnode.shapeFlag & 16) { - if (disabled) { - hydrateDisabledTeleport( - node, - vnode, - targetNode, - targetNode && nextSibling(targetNode) - ); - } else { - vnode.anchor = nextSibling(node); - let targetAnchor = targetNode; - while (targetAnchor) { - if (targetAnchor && targetAnchor.nodeType === 8) { - if (targetAnchor.data === "teleport start anchor") { - vnode.targetStart = targetAnchor; - } else if (targetAnchor.data === "teleport anchor") { - vnode.targetAnchor = targetAnchor; - target._lpa = vnode.targetAnchor && nextSibling(vnode.targetAnchor); - break; - } - } - targetAnchor = nextSibling(targetAnchor); - } - if (!vnode.targetAnchor) { - prepareAnchor(target, vnode, createText, insert); - } - hydrateChildren( - targetNode && nextSibling(targetNode), - vnode, - target, - parentComponent, - parentSuspense, - slotScopeIds, - optimized - ); - } - } - updateCssVars(vnode, disabled); - } else if (disabled) { - if (vnode.shapeFlag & 16) { - hydrateDisabledTeleport(node, vnode, node, nextSibling(node)); - } - } - return vnode.anchor && nextSibling(vnode.anchor); -} -var Teleport = TeleportImpl; -function updateCssVars(vnode, isDisabled) { - const ctx = vnode.ctx; - if (ctx && ctx.ut) { - let node, anchor; - if (isDisabled) { - node = vnode.el; - anchor = vnode.anchor; - } else { - node = vnode.targetStart; - anchor = vnode.targetAnchor; - } - while (node && node !== anchor) { - if (node.nodeType === 1) node.setAttribute("data-v-owner", ctx.uid); - node = node.nextSibling; - } - ctx.ut(); - } -} -function prepareAnchor(target, vnode, createText, insert) { - const targetStart = vnode.targetStart = createText(""); - const targetAnchor = vnode.targetAnchor = createText(""); - targetStart[TeleportEndKey] = targetAnchor; - if (target) { - insert(targetStart, target); - insert(targetAnchor, target); - } - return targetAnchor; -} -var leaveCbKey = Symbol("_leaveCb"); -var enterCbKey = Symbol("_enterCb"); -function useTransitionState() { - const state = { - isMounted: false, - isLeaving: false, - isUnmounting: false, - leavingVNodes: /* @__PURE__ */ new Map() - }; - onMounted(() => { - state.isMounted = true; - }); - onBeforeUnmount(() => { - state.isUnmounting = true; - }); - return state; -} -var TransitionHookValidator = [Function, Array]; -var BaseTransitionPropsValidators = { - mode: String, - appear: Boolean, - persisted: Boolean, - // enter - onBeforeEnter: TransitionHookValidator, - onEnter: TransitionHookValidator, - onAfterEnter: TransitionHookValidator, - onEnterCancelled: TransitionHookValidator, - // leave - onBeforeLeave: TransitionHookValidator, - onLeave: TransitionHookValidator, - onAfterLeave: TransitionHookValidator, - onLeaveCancelled: TransitionHookValidator, - // appear - onBeforeAppear: TransitionHookValidator, - onAppear: TransitionHookValidator, - onAfterAppear: TransitionHookValidator, - onAppearCancelled: TransitionHookValidator -}; -var recursiveGetSubtree = (instance) => { - const subTree = instance.subTree; - return subTree.component ? recursiveGetSubtree(subTree.component) : subTree; -}; -var BaseTransitionImpl = { - name: `BaseTransition`, - props: BaseTransitionPropsValidators, - setup(props, { slots }) { - const instance = getCurrentInstance(); - const state = useTransitionState(); - return () => { - const children = slots.default && getTransitionRawChildren(slots.default(), true); - if (!children || !children.length) { - return; - } - const child = findNonCommentChild(children); - const rawProps = toRaw(props); - const { mode } = rawProps; - if (mode && mode !== "in-out" && mode !== "out-in" && mode !== "default") { - warn$1(`invalid mode: ${mode}`); - } - if (state.isLeaving) { - return emptyPlaceholder(child); - } - const innerChild = getInnerChild$1(child); - if (!innerChild) { - return emptyPlaceholder(child); - } - let enterHooks = resolveTransitionHooks( - innerChild, - rawProps, - state, - instance, - // #11061, ensure enterHooks is fresh after clone - (hooks) => enterHooks = hooks - ); - if (innerChild.type !== Comment) { - setTransitionHooks(innerChild, enterHooks); - } - let oldInnerChild = instance.subTree && getInnerChild$1(instance.subTree); - if (oldInnerChild && oldInnerChild.type !== Comment && !isSameVNodeType(oldInnerChild, innerChild) && recursiveGetSubtree(instance).type !== Comment) { - let leavingHooks = resolveTransitionHooks( - oldInnerChild, - rawProps, - state, - instance - ); - setTransitionHooks(oldInnerChild, leavingHooks); - if (mode === "out-in" && innerChild.type !== Comment) { - state.isLeaving = true; - leavingHooks.afterLeave = () => { - state.isLeaving = false; - if (!(instance.job.flags & 8)) { - instance.update(); - } - delete leavingHooks.afterLeave; - oldInnerChild = void 0; - }; - return emptyPlaceholder(child); - } else if (mode === "in-out" && innerChild.type !== Comment) { - leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => { - const leavingVNodesCache = getLeavingNodesForType( - state, - oldInnerChild - ); - leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild; - el[leaveCbKey] = () => { - earlyRemove(); - el[leaveCbKey] = void 0; - delete enterHooks.delayedLeave; - oldInnerChild = void 0; - }; - enterHooks.delayedLeave = () => { - delayedLeave(); - delete enterHooks.delayedLeave; - oldInnerChild = void 0; - }; - }; - } else { - oldInnerChild = void 0; - } - } else if (oldInnerChild) { - oldInnerChild = void 0; - } - return child; - }; - } -}; -function findNonCommentChild(children) { - let child = children[0]; - if (children.length > 1) { - let hasFound = false; - for (const c of children) { - if (c.type !== Comment) { - if (hasFound) { - warn$1( - " can only be used on a single element or component. Use for lists." - ); - break; - } - child = c; - hasFound = true; - if (false) break; - } - } - } - return child; -} -var BaseTransition = BaseTransitionImpl; -function getLeavingNodesForType(state, vnode) { - const { leavingVNodes } = state; - let leavingVNodesCache = leavingVNodes.get(vnode.type); - if (!leavingVNodesCache) { - leavingVNodesCache = /* @__PURE__ */ Object.create(null); - leavingVNodes.set(vnode.type, leavingVNodesCache); - } - return leavingVNodesCache; -} -function resolveTransitionHooks(vnode, props, state, instance, postClone) { - const { - appear, - mode, - persisted = false, - onBeforeEnter, - onEnter, - onAfterEnter, - onEnterCancelled, - onBeforeLeave, - onLeave, - onAfterLeave, - onLeaveCancelled, - onBeforeAppear, - onAppear, - onAfterAppear, - onAppearCancelled - } = props; - const key = String(vnode.key); - const leavingVNodesCache = getLeavingNodesForType(state, vnode); - const callHook3 = (hook, args) => { - hook && callWithAsyncErrorHandling( - hook, - instance, - 9, - args - ); - }; - const callAsyncHook = (hook, args) => { - const done = args[1]; - callHook3(hook, args); - if (isArray(hook)) { - if (hook.every((hook2) => hook2.length <= 1)) done(); - } else if (hook.length <= 1) { - done(); - } - }; - const hooks = { - mode, - persisted, - beforeEnter(el) { - let hook = onBeforeEnter; - if (!state.isMounted) { - if (appear) { - hook = onBeforeAppear || onBeforeEnter; - } else { - return; - } - } - if (el[leaveCbKey]) { - el[leaveCbKey]( - true - /* cancelled */ - ); - } - const leavingVNode = leavingVNodesCache[key]; - if (leavingVNode && isSameVNodeType(vnode, leavingVNode) && leavingVNode.el[leaveCbKey]) { - leavingVNode.el[leaveCbKey](); - } - callHook3(hook, [el]); - }, - enter(el) { - let hook = onEnter; - let afterHook = onAfterEnter; - let cancelHook = onEnterCancelled; - if (!state.isMounted) { - if (appear) { - hook = onAppear || onEnter; - afterHook = onAfterAppear || onAfterEnter; - cancelHook = onAppearCancelled || onEnterCancelled; - } else { - return; - } - } - let called = false; - const done = el[enterCbKey] = (cancelled) => { - if (called) return; - called = true; - if (cancelled) { - callHook3(cancelHook, [el]); - } else { - callHook3(afterHook, [el]); - } - if (hooks.delayedLeave) { - hooks.delayedLeave(); - } - el[enterCbKey] = void 0; - }; - if (hook) { - callAsyncHook(hook, [el, done]); - } else { - done(); - } - }, - leave(el, remove2) { - const key2 = String(vnode.key); - if (el[enterCbKey]) { - el[enterCbKey]( - true - /* cancelled */ - ); - } - if (state.isUnmounting) { - return remove2(); - } - callHook3(onBeforeLeave, [el]); - let called = false; - const done = el[leaveCbKey] = (cancelled) => { - if (called) return; - called = true; - remove2(); - if (cancelled) { - callHook3(onLeaveCancelled, [el]); - } else { - callHook3(onAfterLeave, [el]); - } - el[leaveCbKey] = void 0; - if (leavingVNodesCache[key2] === vnode) { - delete leavingVNodesCache[key2]; - } - }; - leavingVNodesCache[key2] = vnode; - if (onLeave) { - callAsyncHook(onLeave, [el, done]); - } else { - done(); - } - }, - clone(vnode2) { - const hooks2 = resolveTransitionHooks( - vnode2, - props, - state, - instance, - postClone - ); - if (postClone) postClone(hooks2); - return hooks2; - } - }; - return hooks; -} -function emptyPlaceholder(vnode) { - if (isKeepAlive(vnode)) { - vnode = cloneVNode(vnode); - vnode.children = null; - return vnode; - } -} -function getInnerChild$1(vnode) { - if (!isKeepAlive(vnode)) { - if (isTeleport(vnode.type) && vnode.children) { - return findNonCommentChild(vnode.children); - } - return vnode; - } - if (vnode.component) { - return vnode.component.subTree; - } - const { shapeFlag, children } = vnode; - if (children) { - if (shapeFlag & 16) { - return children[0]; - } - if (shapeFlag & 32 && isFunction(children.default)) { - return children.default(); - } - } -} -function setTransitionHooks(vnode, hooks) { - if (vnode.shapeFlag & 6 && vnode.component) { - vnode.transition = hooks; - setTransitionHooks(vnode.component.subTree, hooks); - } else if (vnode.shapeFlag & 128) { - vnode.ssContent.transition = hooks.clone(vnode.ssContent); - vnode.ssFallback.transition = hooks.clone(vnode.ssFallback); - } else { - vnode.transition = hooks; - } -} -function getTransitionRawChildren(children, keepComment = false, parentKey) { - let ret = []; - let keyedFragmentCount = 0; - for (let i = 0; i < children.length; i++) { - let child = children[i]; - const key = parentKey == null ? child.key : String(parentKey) + String(child.key != null ? child.key : i); - if (child.type === Fragment) { - if (child.patchFlag & 128) keyedFragmentCount++; - ret = ret.concat( - getTransitionRawChildren(child.children, keepComment, key) - ); - } else if (keepComment || child.type !== Comment) { - ret.push(key != null ? cloneVNode(child, { key }) : child); - } - } - if (keyedFragmentCount > 1) { - for (let i = 0; i < ret.length; i++) { - ret[i].patchFlag = -2; - } - } - return ret; -} -function defineComponent(options, extraOptions) { - return isFunction(options) ? ( - // #8236: extend call and options.name access are considered side-effects - // by Rollup, so we have to wrap it in a pure-annotated IIFE. - (() => extend({ name: options.name }, extraOptions, { setup: options }))() - ) : options; -} -function useId() { - const i = getCurrentInstance(); - if (i) { - return (i.appContext.config.idPrefix || "v") + "-" + i.ids[0] + i.ids[1]++; - } else if (true) { - warn$1( - `useId() is called when there is no active component instance to be associated with.` - ); - } - return ""; -} -function markAsyncBoundary(instance) { - instance.ids = [instance.ids[0] + instance.ids[2]++ + "-", 0, 0]; -} -var knownTemplateRefs = /* @__PURE__ */ new WeakSet(); -function useTemplateRef(key) { - const i = getCurrentInstance(); - const r = shallowRef(null); - if (i) { - const refs = i.refs === EMPTY_OBJ ? i.refs = {} : i.refs; - let desc; - if ((desc = Object.getOwnPropertyDescriptor(refs, key)) && !desc.configurable) { - warn$1(`useTemplateRef('${key}') already exists.`); - } else { - Object.defineProperty(refs, key, { - enumerable: true, - get: () => r.value, - set: (val) => r.value = val - }); - } - } else if (true) { - warn$1( - `useTemplateRef() is called when there is no active component instance to be associated with.` - ); - } - const ret = true ? readonly(r) : r; - if (true) { - knownTemplateRefs.add(ret); - } - return ret; -} -var pendingSetRefMap = /* @__PURE__ */ new WeakMap(); -function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) { - if (isArray(rawRef)) { - rawRef.forEach( - (r, i) => setRef( - r, - oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), - parentSuspense, - vnode, - isUnmount - ) - ); - return; - } - if (isAsyncWrapper(vnode) && !isUnmount) { - if (vnode.shapeFlag & 512 && vnode.type.__asyncResolved && vnode.component.subTree.component) { - setRef(rawRef, oldRawRef, parentSuspense, vnode.component.subTree); - } - return; - } - const refValue = vnode.shapeFlag & 4 ? getComponentPublicInstance(vnode.component) : vnode.el; - const value = isUnmount ? null : refValue; - const { i: owner, r: ref2 } = rawRef; - if (!owner) { - warn$1( - `Missing ref owner context. ref cannot be used on hoisted vnodes. A vnode with ref must be created inside the render function.` - ); - return; - } - const oldRef = oldRawRef && oldRawRef.r; - const refs = owner.refs === EMPTY_OBJ ? owner.refs = {} : owner.refs; - const setupState = owner.setupState; - const rawSetupState = toRaw(setupState); - const canSetSetupRef = setupState === EMPTY_OBJ ? NO : (key) => { - if (true) { - if (hasOwn(rawSetupState, key) && !isRef2(rawSetupState[key])) { - warn$1( - `Template ref "${key}" used on a non-ref value. It will not work in the production build.` - ); - } - if (knownTemplateRefs.has(rawSetupState[key])) { - return false; - } - } - return hasOwn(rawSetupState, key); - }; - const canSetRef = (ref22) => { - return !knownTemplateRefs.has(ref22); - }; - if (oldRef != null && oldRef !== ref2) { - invalidatePendingSetRef(oldRawRef); - if (isString(oldRef)) { - refs[oldRef] = null; - if (canSetSetupRef(oldRef)) { - setupState[oldRef] = null; - } - } else if (isRef2(oldRef)) { - if (canSetRef(oldRef)) { - oldRef.value = null; - } - const oldRawRefAtom = oldRawRef; - if (oldRawRefAtom.k) refs[oldRawRefAtom.k] = null; - } - } - if (isFunction(ref2)) { - callWithErrorHandling(ref2, owner, 12, [value, refs]); - } else { - const _isString = isString(ref2); - const _isRef = isRef2(ref2); - if (_isString || _isRef) { - const doSet = () => { - if (rawRef.f) { - const existing = _isString ? canSetSetupRef(ref2) ? setupState[ref2] : refs[ref2] : canSetRef(ref2) || !rawRef.k ? ref2.value : refs[rawRef.k]; - if (isUnmount) { - isArray(existing) && remove(existing, refValue); - } else { - if (!isArray(existing)) { - if (_isString) { - refs[ref2] = [refValue]; - if (canSetSetupRef(ref2)) { - setupState[ref2] = refs[ref2]; - } - } else { - const newVal = [refValue]; - if (canSetRef(ref2)) { - ref2.value = newVal; - } - if (rawRef.k) refs[rawRef.k] = newVal; - } - } else if (!existing.includes(refValue)) { - existing.push(refValue); - } - } - } else if (_isString) { - refs[ref2] = value; - if (canSetSetupRef(ref2)) { - setupState[ref2] = value; - } - } else if (_isRef) { - if (canSetRef(ref2)) { - ref2.value = value; - } - if (rawRef.k) refs[rawRef.k] = value; - } else if (true) { - warn$1("Invalid template ref type:", ref2, `(${typeof ref2})`); - } - }; - if (value) { - const job = () => { - doSet(); - pendingSetRefMap.delete(rawRef); - }; - job.id = -1; - pendingSetRefMap.set(rawRef, job); - queuePostRenderEffect(job, parentSuspense); - } else { - invalidatePendingSetRef(rawRef); - doSet(); - } - } else if (true) { - warn$1("Invalid template ref type:", ref2, `(${typeof ref2})`); - } - } -} -function invalidatePendingSetRef(rawRef) { - const pendingSetRef = pendingSetRefMap.get(rawRef); - if (pendingSetRef) { - pendingSetRef.flags |= 8; - pendingSetRefMap.delete(rawRef); - } -} -var hasLoggedMismatchError = false; -var logMismatchError = () => { - if (hasLoggedMismatchError) { - return; - } - console.error("Hydration completed but contains mismatches."); - hasLoggedMismatchError = true; -}; -var isSVGContainer = (container) => container.namespaceURI.includes("svg") && container.tagName !== "foreignObject"; -var isMathMLContainer = (container) => container.namespaceURI.includes("MathML"); -var getContainerType = (container) => { - if (container.nodeType !== 1) return void 0; - if (isSVGContainer(container)) return "svg"; - if (isMathMLContainer(container)) return "mathml"; - return void 0; -}; -var isComment = (node) => node.nodeType === 8; -function createHydrationFunctions(rendererInternals) { - const { - mt: mountComponent, - p: patch, - o: { - patchProp: patchProp2, - createText, - nextSibling, - parentNode, - remove: remove2, - insert, - createComment - } - } = rendererInternals; - const hydrate2 = (vnode, container) => { - if (!container.hasChildNodes()) { - warn$1( - `Attempting to hydrate existing markup but container is empty. Performing full mount instead.` - ); - patch(null, vnode, container); - flushPostFlushCbs(); - container._vnode = vnode; - return; - } - hydrateNode(container.firstChild, vnode, null, null, null); - flushPostFlushCbs(); - container._vnode = vnode; - }; - const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => { - optimized = optimized || !!vnode.dynamicChildren; - const isFragmentStart = isComment(node) && node.data === "["; - const onMismatch = () => handleMismatch( - node, - vnode, - parentComponent, - parentSuspense, - slotScopeIds, - isFragmentStart - ); - const { type, ref: ref2, shapeFlag, patchFlag } = vnode; - let domType = node.nodeType; - vnode.el = node; - if (true) { - def(node, "__vnode", vnode, true); - def(node, "__vueParentComponent", parentComponent, true); - } - if (patchFlag === -2) { - optimized = false; - vnode.dynamicChildren = null; - } - let nextNode = null; - switch (type) { - case Text: - if (domType !== 3) { - if (vnode.children === "") { - insert(vnode.el = createText(""), parentNode(node), node); - nextNode = node; - } else { - nextNode = onMismatch(); - } - } else { - if (node.data !== vnode.children) { - warn$1( - `Hydration text mismatch in`, - node.parentNode, - ` - - rendered on server: ${JSON.stringify( - node.data - )} - - expected on client: ${JSON.stringify(vnode.children)}` - ); - logMismatchError(); - node.data = vnode.children; - } - nextNode = nextSibling(node); - } - break; - case Comment: - if (isTemplateNode(node)) { - nextNode = nextSibling(node); - replaceNode( - vnode.el = node.content.firstChild, - node, - parentComponent - ); - } else if (domType !== 8 || isFragmentStart) { - nextNode = onMismatch(); - } else { - nextNode = nextSibling(node); - } - break; - case Static: - if (isFragmentStart) { - node = nextSibling(node); - domType = node.nodeType; - } - if (domType === 1 || domType === 3) { - nextNode = node; - const needToAdoptContent = !vnode.children.length; - for (let i = 0; i < vnode.staticCount; i++) { - if (needToAdoptContent) - vnode.children += nextNode.nodeType === 1 ? nextNode.outerHTML : nextNode.data; - if (i === vnode.staticCount - 1) { - vnode.anchor = nextNode; - } - nextNode = nextSibling(nextNode); - } - return isFragmentStart ? nextSibling(nextNode) : nextNode; - } else { - onMismatch(); - } - break; - case Fragment: - if (!isFragmentStart) { - nextNode = onMismatch(); - } else { - nextNode = hydrateFragment( - node, - vnode, - parentComponent, - parentSuspense, - slotScopeIds, - optimized - ); - } - break; - default: - if (shapeFlag & 1) { - if ((domType !== 1 || vnode.type.toLowerCase() !== node.tagName.toLowerCase()) && !isTemplateNode(node)) { - nextNode = onMismatch(); - } else { - nextNode = hydrateElement( - node, - vnode, - parentComponent, - parentSuspense, - slotScopeIds, - optimized - ); - } - } else if (shapeFlag & 6) { - vnode.slotScopeIds = slotScopeIds; - const container = parentNode(node); - if (isFragmentStart) { - nextNode = locateClosingAnchor(node); - } else if (isComment(node) && node.data === "teleport start") { - nextNode = locateClosingAnchor(node, node.data, "teleport end"); - } else { - nextNode = nextSibling(node); - } - mountComponent( - vnode, - container, - null, - parentComponent, - parentSuspense, - getContainerType(container), - optimized - ); - if (isAsyncWrapper(vnode) && !vnode.type.__asyncResolved) { - let subTree; - if (isFragmentStart) { - subTree = createVNode(Fragment); - subTree.anchor = nextNode ? nextNode.previousSibling : container.lastChild; - } else { - subTree = node.nodeType === 3 ? createTextVNode("") : createVNode("div"); - } - subTree.el = node; - vnode.component.subTree = subTree; - } - } else if (shapeFlag & 64) { - if (domType !== 8) { - nextNode = onMismatch(); - } else { - nextNode = vnode.type.hydrate( - node, - vnode, - parentComponent, - parentSuspense, - slotScopeIds, - optimized, - rendererInternals, - hydrateChildren - ); - } - } else if (shapeFlag & 128) { - nextNode = vnode.type.hydrate( - node, - vnode, - parentComponent, - parentSuspense, - getContainerType(parentNode(node)), - slotScopeIds, - optimized, - rendererInternals, - hydrateNode - ); - } else if (true) { - warn$1("Invalid HostVNode type:", type, `(${typeof type})`); - } - } - if (ref2 != null) { - setRef(ref2, null, parentSuspense, vnode); - } - return nextNode; - }; - const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => { - optimized = optimized || !!vnode.dynamicChildren; - const { type, props, patchFlag, shapeFlag, dirs, transition } = vnode; - const forcePatch = type === "input" || type === "option"; - if (true) { - if (dirs) { - invokeDirectiveHook(vnode, null, parentComponent, "created"); - } - let needCallTransitionHooks = false; - if (isTemplateNode(el)) { - needCallTransitionHooks = needTransition( - null, - // no need check parentSuspense in hydration - transition - ) && parentComponent && parentComponent.vnode.props && parentComponent.vnode.props.appear; - const content = el.content.firstChild; - if (needCallTransitionHooks) { - const cls = content.getAttribute("class"); - if (cls) content.$cls = cls; - transition.beforeEnter(content); - } - replaceNode(content, el, parentComponent); - vnode.el = el = content; - } - if (shapeFlag & 16 && // skip if element has innerHTML / textContent - !(props && (props.innerHTML || props.textContent))) { - let next = hydrateChildren( - el.firstChild, - vnode, - el, - parentComponent, - parentSuspense, - slotScopeIds, - optimized - ); - let hasWarned2 = false; - while (next) { - if (!isMismatchAllowed( - el, - 1 - /* CHILDREN */ - )) { - if (!hasWarned2) { - warn$1( - `Hydration children mismatch on`, - el, - ` -Server rendered element contains more child nodes than client vdom.` - ); - hasWarned2 = true; - } - logMismatchError(); - } - const cur = next; - next = next.nextSibling; - remove2(cur); - } - } else if (shapeFlag & 8) { - let clientText = vnode.children; - if (clientText[0] === "\n" && (el.tagName === "PRE" || el.tagName === "TEXTAREA")) { - clientText = clientText.slice(1); - } - const { textContent } = el; - if (textContent !== clientText && // innerHTML normalize \r\n or \r into a single \n in the DOM - textContent !== clientText.replace(/\r\n|\r/g, "\n")) { - if (!isMismatchAllowed( - el, - 0 - /* TEXT */ - )) { - warn$1( - `Hydration text content mismatch on`, - el, - ` - - rendered on server: ${textContent} - - expected on client: ${clientText}` - ); - logMismatchError(); - } - el.textContent = vnode.children; - } - } - if (props) { - if (true) { - const isCustomElement = el.tagName.includes("-"); - for (const key in props) { - if (// #11189 skip if this node has directives that have created hooks - // as it could have mutated the DOM in any possible way - !(dirs && dirs.some((d) => d.dir.created)) && propHasMismatch(el, key, props[key], vnode, parentComponent)) { - logMismatchError(); - } - if (forcePatch && (key.endsWith("value") || key === "indeterminate") || isOn(key) && !isReservedProp(key) || // force hydrate v-bind with .prop modifiers - key[0] === "." || isCustomElement) { - patchProp2(el, key, null, props[key], void 0, parentComponent); - } - } - } else if (props.onClick) { - patchProp2( - el, - "onClick", - null, - props.onClick, - void 0, - parentComponent - ); - } else if (patchFlag & 4 && isReactive(props.style)) { - for (const key in props.style) props.style[key]; - } - } - let vnodeHooks; - if (vnodeHooks = props && props.onVnodeBeforeMount) { - invokeVNodeHook(vnodeHooks, parentComponent, vnode); - } - if (dirs) { - invokeDirectiveHook(vnode, null, parentComponent, "beforeMount"); - } - if ((vnodeHooks = props && props.onVnodeMounted) || dirs || needCallTransitionHooks) { - queueEffectWithSuspense(() => { - vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode); - needCallTransitionHooks && transition.enter(el); - dirs && invokeDirectiveHook(vnode, null, parentComponent, "mounted"); - }, parentSuspense); - } - } - return el.nextSibling; - }; - const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => { - optimized = optimized || !!parentVNode.dynamicChildren; - const children = parentVNode.children; - const l = children.length; - let hasWarned2 = false; - for (let i = 0; i < l; i++) { - const vnode = optimized ? children[i] : children[i] = normalizeVNode(children[i]); - const isText = vnode.type === Text; - if (node) { - if (isText && !optimized) { - if (i + 1 < l && normalizeVNode(children[i + 1]).type === Text) { - insert( - createText( - node.data.slice(vnode.children.length) - ), - container, - nextSibling(node) - ); - node.data = vnode.children; - } - } - node = hydrateNode( - node, - vnode, - parentComponent, - parentSuspense, - slotScopeIds, - optimized - ); - } else if (isText && !vnode.children) { - insert(vnode.el = createText(""), container); - } else { - if (!isMismatchAllowed( - container, - 1 - /* CHILDREN */ - )) { - if (!hasWarned2) { - warn$1( - `Hydration children mismatch on`, - container, - ` -Server rendered element contains fewer child nodes than client vdom.` - ); - hasWarned2 = true; - } - logMismatchError(); - } - patch( - null, - vnode, - container, - null, - parentComponent, - parentSuspense, - getContainerType(container), - slotScopeIds - ); - } - } - return node; - }; - const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => { - const { slotScopeIds: fragmentSlotScopeIds } = vnode; - if (fragmentSlotScopeIds) { - slotScopeIds = slotScopeIds ? slotScopeIds.concat(fragmentSlotScopeIds) : fragmentSlotScopeIds; - } - const container = parentNode(node); - const next = hydrateChildren( - nextSibling(node), - vnode, - container, - parentComponent, - parentSuspense, - slotScopeIds, - optimized - ); - if (next && isComment(next) && next.data === "]") { - return nextSibling(vnode.anchor = next); - } else { - logMismatchError(); - insert(vnode.anchor = createComment(`]`), container, next); - return next; - } - }; - const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => { - if (!isMismatchAllowed( - node.parentElement, - 1 - /* CHILDREN */ - )) { - warn$1( - `Hydration node mismatch: -- rendered on server:`, - node, - node.nodeType === 3 ? `(text)` : isComment(node) && node.data === "[" ? `(start of fragment)` : ``, - ` -- expected on client:`, - vnode.type - ); - logMismatchError(); - } - vnode.el = null; - if (isFragment) { - const end = locateClosingAnchor(node); - while (true) { - const next2 = nextSibling(node); - if (next2 && next2 !== end) { - remove2(next2); - } else { - break; - } - } - } - const next = nextSibling(node); - const container = parentNode(node); - remove2(node); - patch( - null, - vnode, - container, - next, - parentComponent, - parentSuspense, - getContainerType(container), - slotScopeIds - ); - if (parentComponent) { - parentComponent.vnode.el = vnode.el; - updateHOCHostEl(parentComponent, vnode.el); - } - return next; - }; - const locateClosingAnchor = (node, open = "[", close = "]") => { - let match = 0; - while (node) { - node = nextSibling(node); - if (node && isComment(node)) { - if (node.data === open) match++; - if (node.data === close) { - if (match === 0) { - return nextSibling(node); - } else { - match--; - } - } - } - } - return node; - }; - const replaceNode = (newNode, oldNode, parentComponent) => { - const parentNode2 = oldNode.parentNode; - if (parentNode2) { - parentNode2.replaceChild(newNode, oldNode); - } - let parent = parentComponent; - while (parent) { - if (parent.vnode.el === oldNode) { - parent.vnode.el = parent.subTree.el = newNode; - } - parent = parent.parent; - } - }; - const isTemplateNode = (node) => { - return node.nodeType === 1 && node.tagName === "TEMPLATE"; - }; - return [hydrate2, hydrateNode]; -} -function propHasMismatch(el, key, clientValue, vnode, instance) { - let mismatchType; - let mismatchKey; - let actual; - let expected; - if (key === "class") { - if (el.$cls) { - actual = el.$cls; - delete el.$cls; - } else { - actual = el.getAttribute("class"); - } - expected = normalizeClass(clientValue); - if (!isSetEqual(toClassSet(actual || ""), toClassSet(expected))) { - mismatchType = 2; - mismatchKey = `class`; - } - } else if (key === "style") { - actual = el.getAttribute("style") || ""; - expected = isString(clientValue) ? clientValue : stringifyStyle(normalizeStyle(clientValue)); - const actualMap = toStyleMap(actual); - const expectedMap = toStyleMap(expected); - if (vnode.dirs) { - for (const { dir, value } of vnode.dirs) { - if (dir.name === "show" && !value) { - expectedMap.set("display", "none"); - } - } - } - if (instance) { - resolveCssVars(instance, vnode, expectedMap); - } - if (!isMapEqual(actualMap, expectedMap)) { - mismatchType = 3; - mismatchKey = "style"; - } - } else if (el instanceof SVGElement && isKnownSvgAttr(key) || el instanceof HTMLElement && (isBooleanAttr(key) || isKnownHtmlAttr(key))) { - if (isBooleanAttr(key)) { - actual = el.hasAttribute(key); - expected = includeBooleanAttr(clientValue); - } else if (clientValue == null) { - actual = el.hasAttribute(key); - expected = false; - } else { - if (el.hasAttribute(key)) { - actual = el.getAttribute(key); - } else if (key === "value" && el.tagName === "TEXTAREA") { - actual = el.value; - } else { - actual = false; - } - expected = isRenderableAttrValue(clientValue) ? String(clientValue) : false; - } - if (actual !== expected) { - mismatchType = 4; - mismatchKey = key; - } - } - if (mismatchType != null && !isMismatchAllowed(el, mismatchType)) { - const format = (v) => v === false ? `(not rendered)` : `${mismatchKey}="${v}"`; - const preSegment = `Hydration ${MismatchTypeString[mismatchType]} mismatch on`; - const postSegment = ` - - rendered on server: ${format(actual)} - - expected on client: ${format(expected)} - Note: this mismatch is check-only. The DOM will not be rectified in production due to performance overhead. - You should fix the source of the mismatch.`; - { - warn$1(preSegment, el, postSegment); - } - return true; - } - return false; -} -function toClassSet(str) { - return new Set(str.trim().split(/\s+/)); -} -function isSetEqual(a, b) { - if (a.size !== b.size) { - return false; - } - for (const s of a) { - if (!b.has(s)) { - return false; - } - } - return true; -} -function toStyleMap(str) { - const styleMap = /* @__PURE__ */ new Map(); - for (const item of str.split(";")) { - let [key, value] = item.split(":"); - key = key.trim(); - value = value && value.trim(); - if (key && value) { - styleMap.set(key, value); - } - } - return styleMap; -} -function isMapEqual(a, b) { - if (a.size !== b.size) { - return false; - } - for (const [key, value] of a) { - if (value !== b.get(key)) { - return false; - } - } - return true; -} -function resolveCssVars(instance, vnode, expectedMap) { - const root = instance.subTree; - if (instance.getCssVars && (vnode === root || root && root.type === Fragment && root.children.includes(vnode))) { - const cssVars = instance.getCssVars(); - for (const key in cssVars) { - const value = normalizeCssVarValue(cssVars[key]); - expectedMap.set(`--${getEscapedCssVarName(key, false)}`, value); - } - } - if (vnode === root && instance.parent) { - resolveCssVars(instance.parent, instance.vnode, expectedMap); - } -} -var allowMismatchAttr = "data-allow-mismatch"; -var MismatchTypeString = { - [ - 0 - /* TEXT */ - ]: "text", - [ - 1 - /* CHILDREN */ - ]: "children", - [ - 2 - /* CLASS */ - ]: "class", - [ - 3 - /* STYLE */ - ]: "style", - [ - 4 - /* ATTRIBUTE */ - ]: "attribute" -}; -function isMismatchAllowed(el, allowedType) { - if (allowedType === 0 || allowedType === 1) { - while (el && !el.hasAttribute(allowMismatchAttr)) { - el = el.parentElement; - } - } - const allowedAttr = el && el.getAttribute(allowMismatchAttr); - if (allowedAttr == null) { - return false; - } else if (allowedAttr === "") { - return true; - } else { - const list = allowedAttr.split(","); - if (allowedType === 0 && list.includes("children")) { - return true; - } - return list.includes(MismatchTypeString[allowedType]); - } -} -var requestIdleCallback = getGlobalThis().requestIdleCallback || ((cb) => setTimeout(cb, 1)); -var cancelIdleCallback = getGlobalThis().cancelIdleCallback || ((id) => clearTimeout(id)); -var hydrateOnIdle = (timeout = 1e4) => (hydrate2) => { - const id = requestIdleCallback(hydrate2, { timeout }); - return () => cancelIdleCallback(id); -}; -function elementIsVisibleInViewport(el) { - const { top, left, bottom, right } = el.getBoundingClientRect(); - const { innerHeight, innerWidth } = window; - return (top > 0 && top < innerHeight || bottom > 0 && bottom < innerHeight) && (left > 0 && left < innerWidth || right > 0 && right < innerWidth); -} -var hydrateOnVisible = (opts) => (hydrate2, forEach) => { - const ob = new IntersectionObserver((entries) => { - for (const e of entries) { - if (!e.isIntersecting) continue; - ob.disconnect(); - hydrate2(); - break; - } - }, opts); - forEach((el) => { - if (!(el instanceof Element)) return; - if (elementIsVisibleInViewport(el)) { - hydrate2(); - ob.disconnect(); - return false; - } - ob.observe(el); - }); - return () => ob.disconnect(); -}; -var hydrateOnMediaQuery = (query) => (hydrate2) => { - if (query) { - const mql = matchMedia(query); - if (mql.matches) { - hydrate2(); - } else { - mql.addEventListener("change", hydrate2, { once: true }); - return () => mql.removeEventListener("change", hydrate2); - } - } -}; -var hydrateOnInteraction = (interactions = []) => (hydrate2, forEach) => { - if (isString(interactions)) interactions = [interactions]; - let hasHydrated = false; - const doHydrate = (e) => { - if (!hasHydrated) { - hasHydrated = true; - teardown(); - hydrate2(); - e.target.dispatchEvent(new e.constructor(e.type, e)); - } - }; - const teardown = () => { - forEach((el) => { - for (const i of interactions) { - el.removeEventListener(i, doHydrate); - } - }); - }; - forEach((el) => { - for (const i of interactions) { - el.addEventListener(i, doHydrate, { once: true }); - } - }); - return teardown; -}; -function forEachElement(node, cb) { - if (isComment(node) && node.data === "[") { - let depth = 1; - let next = node.nextSibling; - while (next) { - if (next.nodeType === 1) { - const result = cb(next); - if (result === false) { - break; - } - } else if (isComment(next)) { - if (next.data === "]") { - if (--depth === 0) break; - } else if (next.data === "[") { - depth++; - } - } - next = next.nextSibling; - } - } else { - cb(node); - } -} -var isAsyncWrapper = (i) => !!i.type.__asyncLoader; -function defineAsyncComponent(source) { - if (isFunction(source)) { - source = { loader: source }; - } - const { - loader, - loadingComponent, - errorComponent, - delay = 200, - hydrate: hydrateStrategy, - timeout, - // undefined = never times out - suspensible = true, - onError: userOnError - } = source; - let pendingRequest = null; - let resolvedComp; - let retries = 0; - const retry = () => { - retries++; - pendingRequest = null; - return load(); - }; - const load = () => { - let thisRequest; - return pendingRequest || (thisRequest = pendingRequest = loader().catch((err) => { - err = err instanceof Error ? err : new Error(String(err)); - if (userOnError) { - return new Promise((resolve2, reject) => { - const userRetry = () => resolve2(retry()); - const userFail = () => reject(err); - userOnError(err, userRetry, userFail, retries + 1); - }); - } else { - throw err; - } - }).then((comp) => { - if (thisRequest !== pendingRequest && pendingRequest) { - return pendingRequest; - } - if (!comp) { - warn$1( - `Async component loader resolved to undefined. If you are using retry(), make sure to return its return value.` - ); - } - if (comp && (comp.__esModule || comp[Symbol.toStringTag] === "Module")) { - comp = comp.default; - } - if (comp && !isObject(comp) && !isFunction(comp)) { - throw new Error(`Invalid async component load result: ${comp}`); - } - resolvedComp = comp; - return comp; - })); - }; - return defineComponent({ - name: "AsyncComponentWrapper", - __asyncLoader: load, - __asyncHydrate(el, instance, hydrate2) { - let patched = false; - (instance.bu || (instance.bu = [])).push(() => patched = true); - const performHydrate = () => { - if (patched) { - if (true) { - warn$1( - `Skipping lazy hydration for component '${getComponentName(resolvedComp) || resolvedComp.__file}': it was updated before lazy hydration performed.` - ); - } - return; - } - hydrate2(); - }; - const doHydrate = hydrateStrategy ? () => { - const teardown = hydrateStrategy( - performHydrate, - (cb) => forEachElement(el, cb) - ); - if (teardown) { - (instance.bum || (instance.bum = [])).push(teardown); - } - } : performHydrate; - if (resolvedComp) { - doHydrate(); - } else { - load().then(() => !instance.isUnmounted && doHydrate()); - } - }, - get __asyncResolved() { - return resolvedComp; - }, - setup() { - const instance = currentInstance; - markAsyncBoundary(instance); - if (resolvedComp) { - return () => createInnerComp(resolvedComp, instance); - } - const onError = (err) => { - pendingRequest = null; - handleError( - err, - instance, - 13, - !errorComponent - ); - }; - if (suspensible && instance.suspense || isInSSRComponentSetup) { - return load().then((comp) => { - return () => createInnerComp(comp, instance); - }).catch((err) => { - onError(err); - return () => errorComponent ? createVNode(errorComponent, { - error: err - }) : null; - }); - } - const loaded = ref(false); - const error = ref(); - const delayed = ref(!!delay); - if (delay) { - setTimeout(() => { - delayed.value = false; - }, delay); - } - if (timeout != null) { - setTimeout(() => { - if (!loaded.value && !error.value) { - const err = new Error( - `Async component timed out after ${timeout}ms.` - ); - onError(err); - error.value = err; - } - }, timeout); - } - load().then(() => { - loaded.value = true; - if (instance.parent && isKeepAlive(instance.parent.vnode)) { - instance.parent.update(); - } - }).catch((err) => { - onError(err); - error.value = err; - }); - return () => { - if (loaded.value && resolvedComp) { - return createInnerComp(resolvedComp, instance); - } else if (error.value && errorComponent) { - return createVNode(errorComponent, { - error: error.value - }); - } else if (loadingComponent && !delayed.value) { - return createInnerComp( - loadingComponent, - instance - ); - } - }; - } - }); -} -function createInnerComp(comp, parent) { - const { ref: ref2, props, children, ce } = parent.vnode; - const vnode = createVNode(comp, props, children); - vnode.ref = ref2; - vnode.ce = ce; - delete parent.vnode.ce; - return vnode; -} -var isKeepAlive = (vnode) => vnode.type.__isKeepAlive; -var KeepAliveImpl = { - name: `KeepAlive`, - // Marker for special handling inside the renderer. We are not using a === - // check directly on KeepAlive in the renderer, because importing it directly - // would prevent it from being tree-shaken. - __isKeepAlive: true, - props: { - include: [String, RegExp, Array], - exclude: [String, RegExp, Array], - max: [String, Number] - }, - setup(props, { slots }) { - const instance = getCurrentInstance(); - const sharedContext = instance.ctx; - if (!sharedContext.renderer) { - return () => { - const children = slots.default && slots.default(); - return children && children.length === 1 ? children[0] : children; - }; - } - const cache = /* @__PURE__ */ new Map(); - const keys = /* @__PURE__ */ new Set(); - let current = null; - if (true) { - instance.__v_cache = cache; - } - const parentSuspense = instance.suspense; - const { - renderer: { - p: patch, - m: move, - um: _unmount, - o: { createElement } - } - } = sharedContext; - const storageContainer = createElement("div"); - sharedContext.activate = (vnode, container, anchor, namespace, optimized) => { - const instance2 = vnode.component; - move(vnode, container, anchor, 0, parentSuspense); - patch( - instance2.vnode, - vnode, - container, - anchor, - instance2, - parentSuspense, - namespace, - vnode.slotScopeIds, - optimized - ); - queuePostRenderEffect(() => { - instance2.isDeactivated = false; - if (instance2.a) { - invokeArrayFns(instance2.a); - } - const vnodeHook = vnode.props && vnode.props.onVnodeMounted; - if (vnodeHook) { - invokeVNodeHook(vnodeHook, instance2.parent, vnode); - } - }, parentSuspense); - if (true) { - devtoolsComponentAdded(instance2); - } - }; - sharedContext.deactivate = (vnode) => { - const instance2 = vnode.component; - invalidateMount(instance2.m); - invalidateMount(instance2.a); - move(vnode, storageContainer, null, 1, parentSuspense); - queuePostRenderEffect(() => { - if (instance2.da) { - invokeArrayFns(instance2.da); - } - const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted; - if (vnodeHook) { - invokeVNodeHook(vnodeHook, instance2.parent, vnode); - } - instance2.isDeactivated = true; - }, parentSuspense); - if (true) { - devtoolsComponentAdded(instance2); - } - if (true) { - instance2.__keepAliveStorageContainer = storageContainer; - } - }; - function unmount(vnode) { - resetShapeFlag(vnode); - _unmount(vnode, instance, parentSuspense, true); - } - function pruneCache(filter) { - cache.forEach((vnode, key) => { - const name = getComponentName( - isAsyncWrapper(vnode) ? vnode.type.__asyncResolved || {} : vnode.type - ); - if (name && !filter(name)) { - pruneCacheEntry(key); - } - }); - } - function pruneCacheEntry(key) { - const cached = cache.get(key); - if (cached && (!current || !isSameVNodeType(cached, current))) { - unmount(cached); - } else if (current) { - resetShapeFlag(current); - } - cache.delete(key); - keys.delete(key); - } - watch2( - () => [props.include, props.exclude], - ([include, exclude]) => { - include && pruneCache((name) => matches(include, name)); - exclude && pruneCache((name) => !matches(exclude, name)); - }, - // prune post-render after `current` has been updated - { flush: "post", deep: true } - ); - let pendingCacheKey = null; - const cacheSubtree = () => { - if (pendingCacheKey != null) { - if (isSuspense(instance.subTree.type)) { - queuePostRenderEffect(() => { - cache.set(pendingCacheKey, getInnerChild(instance.subTree)); - }, instance.subTree.suspense); - } else { - cache.set(pendingCacheKey, getInnerChild(instance.subTree)); - } - } - }; - onMounted(cacheSubtree); - onUpdated(cacheSubtree); - onBeforeUnmount(() => { - cache.forEach((cached) => { - const { subTree, suspense } = instance; - const vnode = getInnerChild(subTree); - if (cached.type === vnode.type && cached.key === vnode.key) { - resetShapeFlag(vnode); - const da = vnode.component.da; - da && queuePostRenderEffect(da, suspense); - return; - } - unmount(cached); - }); - }); - return () => { - pendingCacheKey = null; - if (!slots.default) { - return current = null; - } - const children = slots.default(); - const rawVNode = children[0]; - if (children.length > 1) { - if (true) { - warn$1(`KeepAlive should contain exactly one component child.`); - } - current = null; - return children; - } else if (!isVNode(rawVNode) || !(rawVNode.shapeFlag & 4) && !(rawVNode.shapeFlag & 128)) { - current = null; - return rawVNode; - } - let vnode = getInnerChild(rawVNode); - if (vnode.type === Comment) { - current = null; - return vnode; - } - const comp = vnode.type; - const name = getComponentName( - isAsyncWrapper(vnode) ? vnode.type.__asyncResolved || {} : comp - ); - const { include, exclude, max } = props; - if (include && (!name || !matches(include, name)) || exclude && name && matches(exclude, name)) { - vnode.shapeFlag &= -257; - current = vnode; - return rawVNode; - } - const key = vnode.key == null ? comp : vnode.key; - const cachedVNode = cache.get(key); - if (vnode.el) { - vnode = cloneVNode(vnode); - if (rawVNode.shapeFlag & 128) { - rawVNode.ssContent = vnode; - } - } - pendingCacheKey = key; - if (cachedVNode) { - vnode.el = cachedVNode.el; - vnode.component = cachedVNode.component; - if (vnode.transition) { - setTransitionHooks(vnode, vnode.transition); - } - vnode.shapeFlag |= 512; - keys.delete(key); - keys.add(key); - } else { - keys.add(key); - if (max && keys.size > parseInt(max, 10)) { - pruneCacheEntry(keys.values().next().value); - } - } - vnode.shapeFlag |= 256; - current = vnode; - return isSuspense(rawVNode.type) ? rawVNode : vnode; - }; - } -}; -var KeepAlive = KeepAliveImpl; -function matches(pattern, name) { - if (isArray(pattern)) { - return pattern.some((p2) => matches(p2, name)); - } else if (isString(pattern)) { - return pattern.split(",").includes(name); - } else if (isRegExp(pattern)) { - pattern.lastIndex = 0; - return pattern.test(name); - } - return false; -} -function onActivated(hook, target) { - registerKeepAliveHook(hook, "a", target); -} -function onDeactivated(hook, target) { - registerKeepAliveHook(hook, "da", target); -} -function registerKeepAliveHook(hook, type, target = currentInstance) { - const wrappedHook = hook.__wdc || (hook.__wdc = () => { - let current = target; - while (current) { - if (current.isDeactivated) { - return; - } - current = current.parent; - } - return hook(); - }); - injectHook(type, wrappedHook, target); - if (target) { - let current = target.parent; - while (current && current.parent) { - if (isKeepAlive(current.parent.vnode)) { - injectToKeepAliveRoot(wrappedHook, type, target, current); - } - current = current.parent; - } - } -} -function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) { - const injected = injectHook( - type, - hook, - keepAliveRoot, - true - /* prepend */ - ); - onUnmounted(() => { - remove(keepAliveRoot[type], injected); - }, target); -} -function resetShapeFlag(vnode) { - vnode.shapeFlag &= -257; - vnode.shapeFlag &= -513; -} -function getInnerChild(vnode) { - return vnode.shapeFlag & 128 ? vnode.ssContent : vnode; -} -function injectHook(type, hook, target = currentInstance, prepend = false) { - if (target) { - const hooks = target[type] || (target[type] = []); - const wrappedHook = hook.__weh || (hook.__weh = (...args) => { - pauseTracking(); - const reset = setCurrentInstance(target); - const res = callWithAsyncErrorHandling(hook, target, type, args); - reset(); - resetTracking(); - return res; - }); - if (prepend) { - hooks.unshift(wrappedHook); - } else { - hooks.push(wrappedHook); - } - return wrappedHook; - } else if (true) { - const apiName = toHandlerKey(ErrorTypeStrings$1[type].replace(/ hook$/, "")); - warn$1( - `${apiName} is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement.` - ); - } -} -var createHook = (lifecycle) => (hook, target = currentInstance) => { - if (!isInSSRComponentSetup || lifecycle === "sp") { - injectHook(lifecycle, (...args) => hook(...args), target); - } -}; -var onBeforeMount = createHook("bm"); -var onMounted = createHook("m"); -var onBeforeUpdate = createHook( - "bu" -); -var onUpdated = createHook("u"); -var onBeforeUnmount = createHook( - "bum" -); -var onUnmounted = createHook("um"); -var onServerPrefetch = createHook( - "sp" -); -var onRenderTriggered = createHook("rtg"); -var onRenderTracked = createHook("rtc"); -function onErrorCaptured(hook, target = currentInstance) { - injectHook("ec", hook, target); -} -var COMPONENTS = "components"; -var DIRECTIVES = "directives"; -function resolveComponent(name, maybeSelfReference) { - return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name; -} -var NULL_DYNAMIC_COMPONENT = Symbol.for("v-ndc"); -function resolveDynamicComponent(component) { - if (isString(component)) { - return resolveAsset(COMPONENTS, component, false) || component; - } else { - return component || NULL_DYNAMIC_COMPONENT; - } -} -function resolveDirective(name) { - return resolveAsset(DIRECTIVES, name); -} -function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) { - const instance = currentRenderingInstance || currentInstance; - if (instance) { - const Component = instance.type; - if (type === COMPONENTS) { - const selfName = getComponentName( - Component, - false - ); - if (selfName && (selfName === name || selfName === camelize(name) || selfName === capitalize(camelize(name)))) { - return Component; - } - } - const res = ( - // local registration - // check instance[type] first which is resolved for options API - resolve(instance[type] || Component[type], name) || // global registration - resolve(instance.appContext[type], name) - ); - if (!res && maybeSelfReference) { - return Component; - } - if (warnMissing && !res) { - const extra = type === COMPONENTS ? ` -If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.` : ``; - warn$1(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`); - } - return res; - } else if (true) { - warn$1( - `resolve${capitalize(type.slice(0, -1))} can only be used in render() or setup().` - ); - } -} -function resolve(registry, name) { - return registry && (registry[name] || registry[camelize(name)] || registry[capitalize(camelize(name))]); -} -function renderList(source, renderItem, cache, index) { - let ret; - const cached = cache && cache[index]; - const sourceIsArray = isArray(source); - if (sourceIsArray || isString(source)) { - const sourceIsReactiveArray = sourceIsArray && isReactive(source); - let needsWrap = false; - let isReadonlySource = false; - if (sourceIsReactiveArray) { - needsWrap = !isShallow(source); - isReadonlySource = isReadonly(source); - source = shallowReadArray(source); - } - ret = new Array(source.length); - for (let i = 0, l = source.length; i < l; i++) { - ret[i] = renderItem( - needsWrap ? isReadonlySource ? toReadonly(toReactive(source[i])) : toReactive(source[i]) : source[i], - i, - void 0, - cached && cached[i] - ); - } - } else if (typeof source === "number") { - if (!Number.isInteger(source)) { - warn$1(`The v-for range expect an integer value but got ${source}.`); - } - ret = new Array(source); - for (let i = 0; i < source; i++) { - ret[i] = renderItem(i + 1, i, void 0, cached && cached[i]); - } - } else if (isObject(source)) { - if (source[Symbol.iterator]) { - ret = Array.from( - source, - (item, i) => renderItem(item, i, void 0, cached && cached[i]) - ); - } else { - const keys = Object.keys(source); - ret = new Array(keys.length); - for (let i = 0, l = keys.length; i < l; i++) { - const key = keys[i]; - ret[i] = renderItem(source[key], key, i, cached && cached[i]); - } - } - } else { - ret = []; - } - if (cache) { - cache[index] = ret; - } - return ret; -} -function createSlots(slots, dynamicSlots) { - for (let i = 0; i < dynamicSlots.length; i++) { - const slot = dynamicSlots[i]; - if (isArray(slot)) { - for (let j = 0; j < slot.length; j++) { - slots[slot[j].name] = slot[j].fn; - } - } else if (slot) { - slots[slot.name] = slot.key ? (...args) => { - const res = slot.fn(...args); - if (res) res.key = slot.key; - return res; - } : slot.fn; - } - } - return slots; -} -function renderSlot(slots, name, props = {}, fallback, noSlotted) { - if (currentRenderingInstance.ce || currentRenderingInstance.parent && isAsyncWrapper(currentRenderingInstance.parent) && currentRenderingInstance.parent.ce) { - const hasProps = Object.keys(props).length > 0; - if (name !== "default") props.name = name; - return openBlock(), createBlock( - Fragment, - null, - [createVNode("slot", props, fallback && fallback())], - hasProps ? -2 : 64 - ); - } - let slot = slots[name]; - if (slot && slot.length > 1) { - warn$1( - `SSR-optimized slot function detected in a non-SSR-optimized render function. You need to mark this component with $dynamic-slots in the parent template.` - ); - slot = () => []; - } - if (slot && slot._c) { - slot._d = false; - } - openBlock(); - const validSlotContent = slot && ensureValidVNode(slot(props)); - const slotKey = props.key || // slot content array of a dynamic conditional slot may have a branch - // key attached in the `createSlots` helper, respect that - validSlotContent && validSlotContent.key; - const rendered = createBlock( - Fragment, - { - key: (slotKey && !isSymbol(slotKey) ? slotKey : `_${name}`) + // #7256 force differentiate fallback content from actual content - (!validSlotContent && fallback ? "_fb" : "") - }, - validSlotContent || (fallback ? fallback() : []), - validSlotContent && slots._ === 1 ? 64 : -2 - ); - if (!noSlotted && rendered.scopeId) { - rendered.slotScopeIds = [rendered.scopeId + "-s"]; - } - if (slot && slot._c) { - slot._d = true; - } - return rendered; -} -function ensureValidVNode(vnodes) { - return vnodes.some((child) => { - if (!isVNode(child)) return true; - if (child.type === Comment) return false; - if (child.type === Fragment && !ensureValidVNode(child.children)) - return false; - return true; - }) ? vnodes : null; -} -function toHandlers(obj, preserveCaseIfNecessary) { - const ret = {}; - if (!isObject(obj)) { - warn$1(`v-on with no argument expects an object value.`); - return ret; - } - for (const key in obj) { - ret[preserveCaseIfNecessary && /[A-Z]/.test(key) ? `on:${key}` : toHandlerKey(key)] = obj[key]; - } - return ret; -} -var getPublicInstance = (i) => { - if (!i) return null; - if (isStatefulComponent(i)) return getComponentPublicInstance(i); - return getPublicInstance(i.parent); -}; -var publicPropertiesMap = ( - // Move PURE marker to new line to workaround compiler discarding it - // due to type annotation - extend(/* @__PURE__ */ Object.create(null), { - $: (i) => i, - $el: (i) => i.vnode.el, - $data: (i) => i.data, - $props: (i) => true ? shallowReadonly(i.props) : i.props, - $attrs: (i) => true ? shallowReadonly(i.attrs) : i.attrs, - $slots: (i) => true ? shallowReadonly(i.slots) : i.slots, - $refs: (i) => true ? shallowReadonly(i.refs) : i.refs, - $parent: (i) => getPublicInstance(i.parent), - $root: (i) => getPublicInstance(i.root), - $host: (i) => i.ce, - $emit: (i) => i.emit, - $options: (i) => __VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type, - $forceUpdate: (i) => i.f || (i.f = () => { - queueJob(i.update); - }), - $nextTick: (i) => i.n || (i.n = nextTick.bind(i.proxy)), - $watch: (i) => __VUE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP - }) -); -var isReservedPrefix = (key) => key === "_" || key === "$"; -var hasSetupBinding = (state, key) => state !== EMPTY_OBJ && !state.__isScriptSetup && hasOwn(state, key); -var PublicInstanceProxyHandlers = { - get({ _: instance }, key) { - if (key === "__v_skip") { - return true; - } - const { ctx, setupState, data, props, accessCache, type, appContext } = instance; - if (key === "__isVue") { - return true; - } - if (key[0] !== "$") { - const n = accessCache[key]; - if (n !== void 0) { - switch (n) { - case 1: - return setupState[key]; - case 2: - return data[key]; - case 4: - return ctx[key]; - case 3: - return props[key]; - } - } else if (hasSetupBinding(setupState, key)) { - accessCache[key] = 1; - return setupState[key]; - } else if (__VUE_OPTIONS_API__ && data !== EMPTY_OBJ && hasOwn(data, key)) { - accessCache[key] = 2; - return data[key]; - } else if (hasOwn(props, key)) { - accessCache[key] = 3; - return props[key]; - } else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) { - accessCache[key] = 4; - return ctx[key]; - } else if (!__VUE_OPTIONS_API__ || shouldCacheAccess) { - accessCache[key] = 0; - } - } - const publicGetter = publicPropertiesMap[key]; - let cssModule, globalProperties; - if (publicGetter) { - if (key === "$attrs") { - track(instance.attrs, "get", ""); - markAttrsAccessed(); - } else if (key === "$slots") { - track(instance, "get", key); - } - return publicGetter(instance); - } else if ( - // css module (injected by vue-loader) - (cssModule = type.__cssModules) && (cssModule = cssModule[key]) - ) { - return cssModule; - } else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) { - accessCache[key] = 4; - return ctx[key]; - } else if ( - // global properties - globalProperties = appContext.config.globalProperties, hasOwn(globalProperties, key) - ) { - { - return globalProperties[key]; - } - } else if (currentRenderingInstance && (!isString(key) || // #1091 avoid internal isRef/isVNode checks on component instance leading - // to infinite warning loop - key.indexOf("__v") !== 0)) { - if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn(data, key)) { - warn$1( - `Property ${JSON.stringify( - key - )} must be accessed via $data because it starts with a reserved character ("$" or "_") and is not proxied on the render context.` - ); - } else if (instance === currentRenderingInstance) { - warn$1( - `Property ${JSON.stringify(key)} was accessed during render but is not defined on instance.` - ); - } - } - }, - set({ _: instance }, key, value) { - const { data, setupState, ctx } = instance; - if (hasSetupBinding(setupState, key)) { - setupState[key] = value; - return true; - } else if (setupState.__isScriptSetup && hasOwn(setupState, key)) { - warn$1(`Cannot mutate ${eventName} is not declared in the emits option. It will leak into the component's attributes ($attrs).` : null\n }\n }\n });\n }\n }\n return result;\n}\nfunction processInstanceState(instance) {\n const mergedType = resolveMergedOptions(instance);\n return processProps(instance).concat(\n processState(instance),\n processSetupState(instance),\n processComputed(instance, mergedType),\n processAttrs(instance),\n processProvide(instance),\n processInject(instance, mergedType),\n processRefs(instance),\n processEventListeners(instance)\n );\n}\n\n// src/core/component/state/index.ts\nfunction getInstanceState(params) {\n var _a25;\n const instance = getComponentInstance(activeAppRecord.value, params.instanceId);\n const id = getUniqueComponentId(instance);\n const name = getInstanceName(instance);\n const file = (_a25 = instance == null ? void 0 : instance.type) == null ? void 0 : _a25.__file;\n const state = processInstanceState(instance);\n return {\n id,\n name,\n file,\n state,\n instance\n };\n}\n\n// src/core/component/tree/walker.ts\ninit_esm_shims();\n\n// src/core/component/tree/filter.ts\ninit_esm_shims();\nimport { classify as classify2, kebabize } from \"@vue/devtools-shared\";\nvar ComponentFilter = class {\n constructor(filter) {\n this.filter = filter || \"\";\n }\n /**\n * Check if an instance is qualified.\n *\n * @param {Vue|Vnode} instance\n * @return {boolean}\n */\n isQualified(instance) {\n const name = getInstanceName(instance);\n return classify2(name).toLowerCase().includes(this.filter) || kebabize(name).toLowerCase().includes(this.filter);\n }\n};\nfunction createComponentFilter(filterText) {\n return new ComponentFilter(filterText);\n}\n\n// src/core/component/tree/walker.ts\nvar ComponentWalker = class {\n constructor(options) {\n // Dedupe instances (Some instances may be both on a component and on a child abstract/functional component)\n this.captureIds = /* @__PURE__ */ new Map();\n const { filterText = \"\", maxDepth, recursively, api } = options;\n this.componentFilter = createComponentFilter(filterText);\n this.maxDepth = maxDepth;\n this.recursively = recursively;\n this.api = api;\n }\n getComponentTree(instance) {\n this.captureIds = /* @__PURE__ */ new Map();\n return this.findQualifiedChildren(instance, 0);\n }\n getComponentParents(instance) {\n this.captureIds = /* @__PURE__ */ new Map();\n const parents = [];\n this.captureId(instance);\n let parent = instance;\n while (parent = parent.parent) {\n this.captureId(parent);\n parents.push(parent);\n }\n return parents;\n }\n captureId(instance) {\n if (!instance)\n return null;\n const id = instance.__VUE_DEVTOOLS_NEXT_UID__ != null ? instance.__VUE_DEVTOOLS_NEXT_UID__ : getUniqueComponentId(instance);\n instance.__VUE_DEVTOOLS_NEXT_UID__ = id;\n if (this.captureIds.has(id))\n return null;\n else\n this.captureIds.set(id, void 0);\n this.mark(instance);\n return id;\n }\n /**\n * Capture the meta information of an instance. (recursive)\n *\n * @param {Vue} instance\n * @return {object}\n */\n async capture(instance, depth) {\n var _a25;\n if (!instance)\n return null;\n const id = this.captureId(instance);\n const name = getInstanceName(instance);\n const children = this.getInternalInstanceChildren(instance.subTree).filter((child) => !isBeingDestroyed(child));\n const parents = this.getComponentParents(instance) || [];\n const inactive = !!instance.isDeactivated || parents.some((parent) => parent.isDeactivated);\n const treeNode = {\n uid: instance.uid,\n id,\n name,\n renderKey: getRenderKey(instance.vnode ? instance.vnode.key : null),\n inactive,\n children: [],\n isFragment: isFragment(instance),\n tags: typeof instance.type !== \"function\" ? [] : [\n {\n label: \"functional\",\n textColor: 5592405,\n backgroundColor: 15658734\n }\n ],\n autoOpen: this.recursively,\n file: instance.type.__file || \"\"\n };\n if (depth < this.maxDepth || instance.type.__isKeepAlive || parents.some((parent) => parent.type.__isKeepAlive)) {\n treeNode.children = await Promise.all(children.map((child) => this.capture(child, depth + 1)).filter(Boolean));\n }\n if (this.isKeepAlive(instance)) {\n const cachedComponents = this.getKeepAliveCachedInstances(instance);\n const childrenIds = children.map((child) => child.__VUE_DEVTOOLS_NEXT_UID__);\n for (const cachedChild of cachedComponents) {\n if (!childrenIds.includes(cachedChild.__VUE_DEVTOOLS_NEXT_UID__)) {\n const node = await this.capture({ ...cachedChild, isDeactivated: true }, depth + 1);\n if (node)\n treeNode.children.push(node);\n }\n }\n }\n const rootElements = getRootElementsFromComponentInstance(instance);\n const firstElement = rootElements[0];\n if (firstElement == null ? void 0 : firstElement.parentElement) {\n const parentInstance = instance.parent;\n const parentRootElements = parentInstance ? getRootElementsFromComponentInstance(parentInstance) : [];\n let el = firstElement;\n const indexList = [];\n do {\n indexList.push(Array.from(el.parentElement.childNodes).indexOf(el));\n el = el.parentElement;\n } while (el.parentElement && parentRootElements.length && !parentRootElements.includes(el));\n treeNode.domOrder = indexList.reverse();\n } else {\n treeNode.domOrder = [-1];\n }\n if ((_a25 = instance.suspense) == null ? void 0 : _a25.suspenseKey) {\n treeNode.tags.push({\n label: instance.suspense.suspenseKey,\n backgroundColor: 14979812,\n textColor: 16777215\n });\n this.mark(instance, true);\n }\n this.api.visitComponentTree({\n treeNode,\n componentInstance: instance,\n app: instance.appContext.app,\n filter: this.componentFilter.filter\n });\n return treeNode;\n }\n /**\n * Find qualified children from a single instance.\n * If the instance itself is qualified, just return itself.\n * This is ok because [].concat works in both cases.\n *\n * @param {Vue|Vnode} instance\n * @return {Vue|Array}\n */\n async findQualifiedChildren(instance, depth) {\n var _a25;\n if (this.componentFilter.isQualified(instance) && !((_a25 = instance.type.devtools) == null ? void 0 : _a25.hide)) {\n return [await this.capture(instance, depth)];\n } else if (instance.subTree) {\n const list = this.isKeepAlive(instance) ? this.getKeepAliveCachedInstances(instance) : this.getInternalInstanceChildren(instance.subTree);\n return this.findQualifiedChildrenFromList(list, depth);\n } else {\n return [];\n }\n }\n /**\n * Iterate through an array of instances and flatten it into\n * an array of qualified instances. This is a depth-first\n * traversal - e.g. if an instance is not matched, we will\n * recursively go deeper until a qualified child is found.\n *\n * @param {Array} instances\n * @return {Array}\n */\n async findQualifiedChildrenFromList(instances, depth) {\n instances = instances.filter((child) => {\n var _a25;\n return !isBeingDestroyed(child) && !((_a25 = child.type.devtools) == null ? void 0 : _a25.hide);\n });\n if (!this.componentFilter.filter)\n return Promise.all(instances.map((child) => this.capture(child, depth)));\n else\n return Array.prototype.concat.apply([], await Promise.all(instances.map((i) => this.findQualifiedChildren(i, depth))));\n }\n /**\n * Get children from a component instance.\n */\n getInternalInstanceChildren(subTree, suspense = null) {\n const list = [];\n if (subTree) {\n if (subTree.component) {\n !suspense ? list.push(subTree.component) : list.push({ ...subTree.component, suspense });\n } else if (subTree.suspense) {\n const suspenseKey = !subTree.suspense.isInFallback ? \"suspense default\" : \"suspense fallback\";\n list.push(...this.getInternalInstanceChildren(subTree.suspense.activeBranch, { ...subTree.suspense, suspenseKey }));\n } else if (Array.isArray(subTree.children)) {\n subTree.children.forEach((childSubTree) => {\n if (childSubTree.component)\n !suspense ? list.push(childSubTree.component) : list.push({ ...childSubTree.component, suspense });\n else\n list.push(...this.getInternalInstanceChildren(childSubTree, suspense));\n });\n }\n }\n return list.filter((child) => {\n var _a25;\n return !isBeingDestroyed(child) && !((_a25 = child.type.devtools) == null ? void 0 : _a25.hide);\n });\n }\n /**\n * Mark an instance as captured and store it in the instance map.\n *\n * @param {Vue} instance\n */\n mark(instance, force = false) {\n const instanceMap = getAppRecord(instance).instanceMap;\n if (force || !instanceMap.has(instance.__VUE_DEVTOOLS_NEXT_UID__)) {\n instanceMap.set(instance.__VUE_DEVTOOLS_NEXT_UID__, instance);\n activeAppRecord.value.instanceMap = instanceMap;\n }\n }\n isKeepAlive(instance) {\n return instance.type.__isKeepAlive && instance.__v_cache;\n }\n getKeepAliveCachedInstances(instance) {\n return Array.from(instance.__v_cache.values()).map((vnode) => vnode.component).filter(Boolean);\n }\n};\n\n// src/core/timeline/index.ts\ninit_esm_shims();\nimport { isBrowser as isBrowser2 } from \"@vue/devtools-shared\";\n\n// src/core/timeline/perf.ts\ninit_esm_shims();\nvar markEndQueue = /* @__PURE__ */ new Map();\nvar PERFORMANCE_EVENT_LAYER_ID = \"performance\";\nasync function performanceMarkStart(api, app, uid, vm, type, time) {\n const appRecord = await getAppRecord(app);\n if (!appRecord) {\n return;\n }\n const componentName = getInstanceName(vm) || \"Unknown Component\";\n const groupId = devtoolsState.perfUniqueGroupId++;\n const groupKey = `${uid}-${type}`;\n appRecord.perfGroupIds.set(groupKey, { groupId, time });\n await api.addTimelineEvent({\n layerId: PERFORMANCE_EVENT_LAYER_ID,\n event: {\n time: Date.now(),\n data: {\n component: componentName,\n type,\n measure: \"start\"\n },\n title: componentName,\n subtitle: type,\n groupId\n }\n });\n if (markEndQueue.has(groupKey)) {\n const {\n app: app2,\n uid: uid2,\n instance,\n type: type2,\n time: time2\n } = markEndQueue.get(groupKey);\n markEndQueue.delete(groupKey);\n await performanceMarkEnd(\n api,\n app2,\n uid2,\n instance,\n type2,\n time2\n );\n }\n}\nfunction performanceMarkEnd(api, app, uid, vm, type, time) {\n const appRecord = getAppRecord(app);\n if (!appRecord)\n return;\n const componentName = getInstanceName(vm) || \"Unknown Component\";\n const groupKey = `${uid}-${type}`;\n const groupInfo = appRecord.perfGroupIds.get(groupKey);\n if (groupInfo) {\n const groupId = groupInfo.groupId;\n const startTime = groupInfo.time;\n const duration = time - startTime;\n api.addTimelineEvent({\n layerId: PERFORMANCE_EVENT_LAYER_ID,\n event: {\n time: Date.now(),\n data: {\n component: componentName,\n type,\n measure: \"end\",\n duration: {\n _custom: {\n type: \"Duration\",\n value: duration,\n display: `${duration} ms`\n }\n }\n },\n title: componentName,\n subtitle: type,\n groupId\n }\n });\n } else {\n markEndQueue.set(groupKey, { app, uid, instance: vm, type, time });\n }\n}\n\n// src/core/timeline/index.ts\nvar COMPONENT_EVENT_LAYER_ID = \"component-event\";\nfunction setupBuiltinTimelineLayers(api) {\n if (!isBrowser2)\n return;\n api.addTimelineLayer({\n id: \"mouse\",\n label: \"Mouse\",\n color: 10768815\n });\n [\"mousedown\", \"mouseup\", \"click\", \"dblclick\"].forEach((eventType) => {\n if (!devtoolsState.timelineLayersState.recordingState || !devtoolsState.timelineLayersState.mouseEventEnabled)\n return;\n window.addEventListener(eventType, async (event) => {\n await api.addTimelineEvent({\n layerId: \"mouse\",\n event: {\n time: Date.now(),\n data: {\n type: eventType,\n x: event.clientX,\n y: event.clientY\n },\n title: eventType\n }\n });\n }, {\n capture: true,\n passive: true\n });\n });\n api.addTimelineLayer({\n id: \"keyboard\",\n label: \"Keyboard\",\n color: 8475055\n });\n [\"keyup\", \"keydown\", \"keypress\"].forEach((eventType) => {\n window.addEventListener(eventType, async (event) => {\n if (!devtoolsState.timelineLayersState.recordingState || !devtoolsState.timelineLayersState.keyboardEventEnabled)\n return;\n await api.addTimelineEvent({\n layerId: \"keyboard\",\n event: {\n time: Date.now(),\n data: {\n type: eventType,\n key: event.key,\n ctrlKey: event.ctrlKey,\n shiftKey: event.shiftKey,\n altKey: event.altKey,\n metaKey: event.metaKey\n },\n title: event.key\n }\n });\n }, {\n capture: true,\n passive: true\n });\n });\n api.addTimelineLayer({\n id: COMPONENT_EVENT_LAYER_ID,\n label: \"Component events\",\n color: 5226637\n });\n hook.on.componentEmit(async (app, instance, event, params) => {\n if (!devtoolsState.timelineLayersState.recordingState || !devtoolsState.timelineLayersState.componentEventEnabled)\n return;\n const appRecord = await getAppRecord(app);\n if (!appRecord)\n return;\n const componentId = `${appRecord.id}:${instance.uid}`;\n const componentName = getInstanceName(instance) || \"Unknown Component\";\n api.addTimelineEvent({\n layerId: COMPONENT_EVENT_LAYER_ID,\n event: {\n time: Date.now(),\n data: {\n component: {\n _custom: {\n type: \"component-definition\",\n display: componentName\n }\n },\n event,\n params\n },\n title: event,\n subtitle: `by ${componentName}`,\n meta: {\n componentId\n }\n }\n });\n });\n api.addTimelineLayer({\n id: \"performance\",\n label: PERFORMANCE_EVENT_LAYER_ID,\n color: 4307050\n });\n hook.on.perfStart((app, uid, vm, type, time) => {\n if (!devtoolsState.timelineLayersState.recordingState || !devtoolsState.timelineLayersState.performanceEventEnabled)\n return;\n performanceMarkStart(api, app, uid, vm, type, time);\n });\n hook.on.perfEnd((app, uid, vm, type, time) => {\n if (!devtoolsState.timelineLayersState.recordingState || !devtoolsState.timelineLayersState.performanceEventEnabled)\n return;\n performanceMarkEnd(api, app, uid, vm, type, time);\n });\n}\n\n// src/core/vm/index.ts\ninit_esm_shims();\nvar MAX_$VM = 10;\nvar $vmQueue = [];\nfunction exposeInstanceToWindow(componentInstance) {\n if (typeof window === \"undefined\")\n return;\n const win = window;\n if (!componentInstance)\n return;\n win.$vm = componentInstance;\n if ($vmQueue[0] !== componentInstance) {\n if ($vmQueue.length >= MAX_$VM) {\n $vmQueue.pop();\n }\n for (let i = $vmQueue.length; i > 0; i--) {\n win[`$vm${i}`] = $vmQueue[i] = $vmQueue[i - 1];\n }\n win.$vm0 = $vmQueue[0] = componentInstance;\n }\n}\n\n// src/core/plugin/components.ts\nvar INSPECTOR_ID = \"components\";\nfunction createComponentsDevToolsPlugin(app) {\n const descriptor = {\n id: INSPECTOR_ID,\n label: \"Components\",\n app\n };\n const setupFn = (api) => {\n api.addInspector({\n id: INSPECTOR_ID,\n label: \"Components\",\n treeFilterPlaceholder: \"Search components\"\n });\n setupBuiltinTimelineLayers(api);\n api.on.getInspectorTree(async (payload) => {\n if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {\n const instance = getComponentInstance(activeAppRecord.value, payload.instanceId);\n if (instance) {\n const walker2 = new ComponentWalker({\n filterText: payload.filter,\n // @TODO: should make this configurable?\n maxDepth: 100,\n recursively: false,\n api\n });\n payload.rootNodes = await walker2.getComponentTree(instance);\n }\n }\n });\n api.on.getInspectorState(async (payload) => {\n var _a25;\n if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {\n const result = getInstanceState({\n instanceId: payload.nodeId\n });\n const componentInstance = result.instance;\n const app2 = (_a25 = result.instance) == null ? void 0 : _a25.appContext.app;\n const _payload = {\n componentInstance,\n app: app2,\n instanceData: result\n };\n devtoolsContext.hooks.callHookWith((callbacks) => {\n callbacks.forEach((cb) => cb(_payload));\n }, \"inspectComponent\" /* INSPECT_COMPONENT */);\n payload.state = result;\n exposeInstanceToWindow(componentInstance);\n }\n });\n api.on.editInspectorState(async (payload) => {\n if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {\n editState(payload);\n await api.sendInspectorState(\"components\");\n }\n });\n const debounceSendInspectorTree = debounce4(() => {\n api.sendInspectorTree(INSPECTOR_ID);\n }, 120);\n const debounceSendInspectorState = debounce4(() => {\n api.sendInspectorState(INSPECTOR_ID);\n }, 120);\n const componentAddedCleanup = hook.on.componentAdded(async (app2, uid, parentUid, component) => {\n var _a25, _b25, _c;\n if (devtoolsState.highPerfModeEnabled)\n return;\n if ((_c = (_b25 = (_a25 = app2 == null ? void 0 : app2._instance) == null ? void 0 : _a25.type) == null ? void 0 : _b25.devtools) == null ? void 0 : _c.hide)\n return;\n if (!app2 || typeof uid !== \"number\" && !uid || !component)\n return;\n const id = await getComponentId({\n app: app2,\n uid,\n instance: component\n });\n const appRecord = await getAppRecord(app2);\n if (component) {\n if (component.__VUE_DEVTOOLS_NEXT_UID__ == null)\n component.__VUE_DEVTOOLS_NEXT_UID__ = id;\n if (!(appRecord == null ? void 0 : appRecord.instanceMap.has(id))) {\n appRecord == null ? void 0 : appRecord.instanceMap.set(id, component);\n if (activeAppRecord.value.id === (appRecord == null ? void 0 : appRecord.id))\n activeAppRecord.value.instanceMap = appRecord.instanceMap;\n }\n }\n if (!appRecord)\n return;\n debounceSendInspectorTree();\n });\n const componentUpdatedCleanup = hook.on.componentUpdated(async (app2, uid, parentUid, component) => {\n var _a25, _b25, _c;\n if (devtoolsState.highPerfModeEnabled)\n return;\n if ((_c = (_b25 = (_a25 = app2 == null ? void 0 : app2._instance) == null ? void 0 : _a25.type) == null ? void 0 : _b25.devtools) == null ? void 0 : _c.hide)\n return;\n if (!app2 || typeof uid !== \"number\" && !uid || !component)\n return;\n const id = await getComponentId({\n app: app2,\n uid,\n instance: component\n });\n const appRecord = await getAppRecord(app2);\n if (component) {\n if (component.__VUE_DEVTOOLS_NEXT_UID__ == null)\n component.__VUE_DEVTOOLS_NEXT_UID__ = id;\n if (!(appRecord == null ? void 0 : appRecord.instanceMap.has(id))) {\n appRecord == null ? void 0 : appRecord.instanceMap.set(id, component);\n if (activeAppRecord.value.id === (appRecord == null ? void 0 : appRecord.id))\n activeAppRecord.value.instanceMap = appRecord.instanceMap;\n }\n }\n if (!appRecord)\n return;\n debounceSendInspectorTree();\n debounceSendInspectorState();\n });\n const componentRemovedCleanup = hook.on.componentRemoved(async (app2, uid, parentUid, component) => {\n var _a25, _b25, _c;\n if (devtoolsState.highPerfModeEnabled)\n return;\n if ((_c = (_b25 = (_a25 = app2 == null ? void 0 : app2._instance) == null ? void 0 : _a25.type) == null ? void 0 : _b25.devtools) == null ? void 0 : _c.hide)\n return;\n if (!app2 || typeof uid !== \"number\" && !uid || !component)\n return;\n const appRecord = await getAppRecord(app2);\n if (!appRecord)\n return;\n const id = await getComponentId({\n app: app2,\n uid,\n instance: component\n });\n appRecord == null ? void 0 : appRecord.instanceMap.delete(id);\n if (activeAppRecord.value.id === (appRecord == null ? void 0 : appRecord.id))\n activeAppRecord.value.instanceMap = appRecord.instanceMap;\n debounceSendInspectorTree();\n });\n };\n return [descriptor, setupFn];\n}\n\n// src/core/plugin/index.ts\nvar _a12, _b12;\n(_b12 = (_a12 = target8).__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__) != null ? _b12 : _a12.__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__ = /* @__PURE__ */ new Set();\nfunction setupDevToolsPlugin(pluginDescriptor, setupFn) {\n return hook.setupDevToolsPlugin(pluginDescriptor, setupFn);\n}\nfunction callDevToolsPluginSetupFn(plugin, app) {\n const [pluginDescriptor, setupFn] = plugin;\n if (pluginDescriptor.app !== app)\n return;\n const api = new DevToolsPluginAPI({\n plugin: {\n setupFn,\n descriptor: pluginDescriptor\n },\n ctx: devtoolsContext\n });\n if (pluginDescriptor.packageName === \"vuex\") {\n api.on.editInspectorState((payload) => {\n api.sendInspectorState(payload.inspectorId);\n });\n }\n setupFn(api);\n}\nfunction removeRegisteredPluginApp(app) {\n target8.__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__.delete(app);\n}\nfunction registerDevToolsPlugin(app, options) {\n if (target8.__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__.has(app)) {\n return;\n }\n if (devtoolsState.highPerfModeEnabled && !(options == null ? void 0 : options.inspectingComponent)) {\n return;\n }\n target8.__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__.add(app);\n devtoolsPluginBuffer.forEach((plugin) => {\n callDevToolsPluginSetupFn(plugin, app);\n });\n}\n\n// src/core/router/index.ts\ninit_esm_shims();\nimport { deepClone, target as global3 } from \"@vue/devtools-shared\";\nimport { debounce as debounce5 } from \"perfect-debounce\";\n\n// src/ctx/router.ts\ninit_esm_shims();\nimport { target as global2 } from \"@vue/devtools-shared\";\nvar ROUTER_KEY = \"__VUE_DEVTOOLS_ROUTER__\";\nvar ROUTER_INFO_KEY = \"__VUE_DEVTOOLS_ROUTER_INFO__\";\nvar _a13, _b13;\n(_b13 = (_a13 = global2)[ROUTER_INFO_KEY]) != null ? _b13 : _a13[ROUTER_INFO_KEY] = {\n currentRoute: null,\n routes: []\n};\nvar _a14, _b14;\n(_b14 = (_a14 = global2)[ROUTER_KEY]) != null ? _b14 : _a14[ROUTER_KEY] = {};\nvar devtoolsRouterInfo = new Proxy(global2[ROUTER_INFO_KEY], {\n get(target22, property) {\n return global2[ROUTER_INFO_KEY][property];\n }\n});\nvar devtoolsRouter = new Proxy(global2[ROUTER_KEY], {\n get(target22, property) {\n if (property === \"value\") {\n return global2[ROUTER_KEY];\n }\n }\n});\n\n// src/core/router/index.ts\nfunction getRoutes(router) {\n const routesMap = /* @__PURE__ */ new Map();\n return ((router == null ? void 0 : router.getRoutes()) || []).filter((i) => !routesMap.has(i.path) && routesMap.set(i.path, 1));\n}\nfunction filterRoutes(routes) {\n return routes.map((item) => {\n let { path, name, children, meta } = item;\n if (children == null ? void 0 : children.length)\n children = filterRoutes(children);\n return {\n path,\n name,\n children,\n meta\n };\n });\n}\nfunction filterCurrentRoute(route) {\n if (route) {\n const { fullPath, hash, href, path, name, matched, params, query } = route;\n return {\n fullPath,\n hash,\n href,\n path,\n name,\n params,\n query,\n matched: filterRoutes(matched)\n };\n }\n return route;\n}\nfunction normalizeRouterInfo(appRecord, activeAppRecord2) {\n function init() {\n var _a25;\n const router = (_a25 = appRecord.app) == null ? void 0 : _a25.config.globalProperties.$router;\n const currentRoute = filterCurrentRoute(router == null ? void 0 : router.currentRoute.value);\n const routes = filterRoutes(getRoutes(router));\n const c = console.warn;\n console.warn = () => {\n };\n global3[ROUTER_INFO_KEY] = {\n currentRoute: currentRoute ? deepClone(currentRoute) : {},\n routes: deepClone(routes)\n };\n global3[ROUTER_KEY] = router;\n console.warn = c;\n }\n init();\n hook.on.componentUpdated(debounce5(() => {\n var _a25;\n if (((_a25 = activeAppRecord2.value) == null ? void 0 : _a25.app) !== appRecord.app)\n return;\n init();\n if (devtoolsState.highPerfModeEnabled)\n return;\n devtoolsContext.hooks.callHook(\"routerInfoUpdated\" /* ROUTER_INFO_UPDATED */, { state: global3[ROUTER_INFO_KEY] });\n }, 200));\n}\n\n// src/ctx/api.ts\nfunction createDevToolsApi(hooks2) {\n return {\n // get inspector tree\n async getInspectorTree(payload) {\n const _payload = {\n ...payload,\n app: activeAppRecord.value.app,\n rootNodes: []\n };\n await new Promise((resolve) => {\n hooks2.callHookWith(async (callbacks) => {\n await Promise.all(callbacks.map((cb) => cb(_payload)));\n resolve();\n }, \"getInspectorTree\" /* GET_INSPECTOR_TREE */);\n });\n return _payload.rootNodes;\n },\n // get inspector state\n async getInspectorState(payload) {\n const _payload = {\n ...payload,\n app: activeAppRecord.value.app,\n state: null\n };\n const ctx = {\n currentTab: `custom-inspector:${payload.inspectorId}`\n };\n await new Promise((resolve) => {\n hooks2.callHookWith(async (callbacks) => {\n await Promise.all(callbacks.map((cb) => cb(_payload, ctx)));\n resolve();\n }, \"getInspectorState\" /* GET_INSPECTOR_STATE */);\n });\n return _payload.state;\n },\n // edit inspector state\n editInspectorState(payload) {\n const stateEditor2 = new StateEditor();\n const _payload = {\n ...payload,\n app: activeAppRecord.value.app,\n set: (obj, path = payload.path, value = payload.state.value, cb) => {\n stateEditor2.set(obj, path, value, cb || stateEditor2.createDefaultSetCallback(payload.state));\n }\n };\n hooks2.callHookWith((callbacks) => {\n callbacks.forEach((cb) => cb(_payload));\n }, \"editInspectorState\" /* EDIT_INSPECTOR_STATE */);\n },\n // send inspector state\n sendInspectorState(inspectorId) {\n const inspector = getInspector(inspectorId);\n hooks2.callHook(\"sendInspectorState\" /* SEND_INSPECTOR_STATE */, { inspectorId, plugin: {\n descriptor: inspector.descriptor,\n setupFn: () => ({})\n } });\n },\n // inspect component inspector\n inspectComponentInspector() {\n return inspectComponentHighLighter();\n },\n // cancel inspect component inspector\n cancelInspectComponentInspector() {\n return cancelInspectComponentHighLighter();\n },\n // get component render code\n getComponentRenderCode(id) {\n const instance = getComponentInstance(activeAppRecord.value, id);\n if (instance)\n return !(typeof (instance == null ? void 0 : instance.type) === \"function\") ? instance.render.toString() : instance.type.toString();\n },\n // scroll to component\n scrollToComponent(id) {\n return scrollToComponent({ id });\n },\n // open in editor\n openInEditor,\n // get vue inspector\n getVueInspector: getComponentInspector,\n // toggle app\n toggleApp(id, options) {\n const appRecord = devtoolsAppRecords.value.find((record) => record.id === id);\n if (appRecord) {\n setActiveAppRecordId(id);\n setActiveAppRecord(appRecord);\n normalizeRouterInfo(appRecord, activeAppRecord);\n callInspectorUpdatedHook();\n registerDevToolsPlugin(appRecord.app, options);\n }\n },\n // inspect dom\n inspectDOM(instanceId) {\n const instance = getComponentInstance(activeAppRecord.value, instanceId);\n if (instance) {\n const [el] = getRootElementsFromComponentInstance(instance);\n if (el) {\n target9.__VUE_DEVTOOLS_INSPECT_DOM_TARGET__ = el;\n }\n }\n },\n updatePluginSettings(pluginId, key, value) {\n setPluginSettings(pluginId, key, value);\n },\n getPluginSettings(pluginId) {\n return {\n options: getPluginSettingsOptions(pluginId),\n values: getPluginSettings(pluginId)\n };\n }\n };\n}\n\n// src/ctx/env.ts\ninit_esm_shims();\nimport { target as target10 } from \"@vue/devtools-shared\";\nvar _a15, _b15;\n(_b15 = (_a15 = target10).__VUE_DEVTOOLS_ENV__) != null ? _b15 : _a15.__VUE_DEVTOOLS_ENV__ = {\n vitePluginDetected: false\n};\nfunction getDevToolsEnv() {\n return target10.__VUE_DEVTOOLS_ENV__;\n}\nfunction setDevToolsEnv(env) {\n target10.__VUE_DEVTOOLS_ENV__ = {\n ...target10.__VUE_DEVTOOLS_ENV__,\n ...env\n };\n}\n\n// src/ctx/index.ts\nvar hooks = createDevToolsCtxHooks();\nvar _a16, _b16;\n(_b16 = (_a16 = target11).__VUE_DEVTOOLS_KIT_CONTEXT__) != null ? _b16 : _a16.__VUE_DEVTOOLS_KIT_CONTEXT__ = {\n hooks,\n get state() {\n return {\n ...devtoolsState,\n activeAppRecordId: activeAppRecord.id,\n activeAppRecord: activeAppRecord.value,\n appRecords: devtoolsAppRecords.value\n };\n },\n api: createDevToolsApi(hooks)\n};\nvar devtoolsContext = target11.__VUE_DEVTOOLS_KIT_CONTEXT__;\n\n// src/core/app/index.ts\ninit_esm_shims();\nvar import_speakingurl = __toESM(require_speakingurl2(), 1);\nimport { isBrowser as isBrowser3, target as target12 } from \"@vue/devtools-shared\";\nvar _a17, _b17;\nvar appRecordInfo = (_b17 = (_a17 = target12).__VUE_DEVTOOLS_NEXT_APP_RECORD_INFO__) != null ? _b17 : _a17.__VUE_DEVTOOLS_NEXT_APP_RECORD_INFO__ = {\n id: 0,\n appIds: /* @__PURE__ */ new Set()\n};\nfunction getAppRecordName(app, fallbackName) {\n var _a25;\n return ((_a25 = app == null ? void 0 : app._component) == null ? void 0 : _a25.name) || `App ${fallbackName}`;\n}\nfunction getAppRootInstance(app) {\n var _a25, _b25, _c, _d;\n if (app._instance)\n return app._instance;\n else if ((_b25 = (_a25 = app._container) == null ? void 0 : _a25._vnode) == null ? void 0 : _b25.component)\n return (_d = (_c = app._container) == null ? void 0 : _c._vnode) == null ? void 0 : _d.component;\n}\nfunction removeAppRecordId(app) {\n const id = app.__VUE_DEVTOOLS_NEXT_APP_RECORD_ID__;\n if (id != null) {\n appRecordInfo.appIds.delete(id);\n appRecordInfo.id--;\n }\n}\nfunction getAppRecordId(app, defaultId) {\n if (app.__VUE_DEVTOOLS_NEXT_APP_RECORD_ID__ != null)\n return app.__VUE_DEVTOOLS_NEXT_APP_RECORD_ID__;\n let id = defaultId != null ? defaultId : (appRecordInfo.id++).toString();\n if (defaultId && appRecordInfo.appIds.has(id)) {\n let count = 1;\n while (appRecordInfo.appIds.has(`${defaultId}_${count}`))\n count++;\n id = `${defaultId}_${count}`;\n }\n appRecordInfo.appIds.add(id);\n app.__VUE_DEVTOOLS_NEXT_APP_RECORD_ID__ = id;\n return id;\n}\nfunction createAppRecord(app, types) {\n var _a25, _b25;\n const rootInstance = getAppRootInstance(app);\n if (rootInstance) {\n appRecordInfo.id++;\n const name = getAppRecordName(app, appRecordInfo.id.toString());\n const id = getAppRecordId(app, (0, import_speakingurl.default)(name));\n const [el] = getRootElementsFromComponentInstance(rootInstance);\n const record = {\n id,\n name,\n types,\n instanceMap: /* @__PURE__ */ new Map(),\n perfGroupIds: /* @__PURE__ */ new Map(),\n rootInstance,\n iframe: isBrowser3 && document !== (el == null ? void 0 : el.ownerDocument) ? (_b25 = (_a25 = el == null ? void 0 : el.ownerDocument) == null ? void 0 : _a25.location) == null ? void 0 : _b25.pathname : void 0\n };\n app.__VUE_DEVTOOLS_NEXT_APP_RECORD__ = record;\n const rootId = `${record.id}:root`;\n record.instanceMap.set(rootId, record.rootInstance);\n record.rootInstance.__VUE_DEVTOOLS_NEXT_UID__ = rootId;\n return record;\n } else {\n return {};\n }\n}\n\n// src/core/iframe/index.ts\ninit_esm_shims();\nfunction detectIframeApp(target22, inIframe = false) {\n if (inIframe) {\n let sendEventToParent2 = function(cb) {\n try {\n const hook3 = window.parent.__VUE_DEVTOOLS_GLOBAL_HOOK__;\n if (hook3) {\n cb(hook3);\n }\n } catch (e) {\n }\n };\n var sendEventToParent = sendEventToParent2;\n const hook2 = {\n id: \"vue-devtools-next\",\n devtoolsVersion: \"7.0\",\n on: (event, cb) => {\n sendEventToParent2((hook3) => {\n hook3.on(event, cb);\n });\n },\n once: (event, cb) => {\n sendEventToParent2((hook3) => {\n hook3.once(event, cb);\n });\n },\n off: (event, cb) => {\n sendEventToParent2((hook3) => {\n hook3.off(event, cb);\n });\n },\n emit: (event, ...payload) => {\n sendEventToParent2((hook3) => {\n hook3.emit(event, ...payload);\n });\n }\n };\n Object.defineProperty(target22, \"__VUE_DEVTOOLS_GLOBAL_HOOK__\", {\n get() {\n return hook2;\n },\n configurable: true\n });\n }\n function injectVueHookToIframe(iframe) {\n if (iframe.__vdevtools__injected) {\n return;\n }\n try {\n iframe.__vdevtools__injected = true;\n const inject = () => {\n try {\n iframe.contentWindow.__VUE_DEVTOOLS_IFRAME__ = iframe;\n const script = iframe.contentDocument.createElement(\"script\");\n script.textContent = `;(${detectIframeApp.toString()})(window, true)`;\n iframe.contentDocument.documentElement.appendChild(script);\n script.parentNode.removeChild(script);\n } catch (e) {\n }\n };\n inject();\n iframe.addEventListener(\"load\", () => inject());\n } catch (e) {\n }\n }\n function injectVueHookToIframes() {\n if (typeof window === \"undefined\") {\n return;\n }\n const iframes = Array.from(document.querySelectorAll(\"iframe:not([data-vue-devtools-ignore])\"));\n for (const iframe of iframes) {\n injectVueHookToIframe(iframe);\n }\n }\n injectVueHookToIframes();\n let iframeAppChecks = 0;\n const iframeAppCheckTimer = setInterval(() => {\n injectVueHookToIframes();\n iframeAppChecks++;\n if (iframeAppChecks >= 5) {\n clearInterval(iframeAppCheckTimer);\n }\n }, 1e3);\n}\n\n// src/core/index.ts\nfunction initDevTools() {\n var _a25;\n detectIframeApp(target13);\n updateDevToolsState({\n vitePluginDetected: getDevToolsEnv().vitePluginDetected\n });\n const isDevToolsNext = ((_a25 = target13.__VUE_DEVTOOLS_GLOBAL_HOOK__) == null ? void 0 : _a25.id) === \"vue-devtools-next\";\n if (target13.__VUE_DEVTOOLS_GLOBAL_HOOK__ && isDevToolsNext)\n return;\n const _devtoolsHook = createDevToolsHook();\n if (target13.__VUE_DEVTOOLS_HOOK_REPLAY__) {\n try {\n target13.__VUE_DEVTOOLS_HOOK_REPLAY__.forEach((cb) => cb(_devtoolsHook));\n target13.__VUE_DEVTOOLS_HOOK_REPLAY__ = [];\n } catch (e) {\n console.error(\"[vue-devtools] Error during hook replay\", e);\n }\n }\n _devtoolsHook.once(\"init\", (Vue) => {\n target13.__VUE_DEVTOOLS_VUE2_APP_DETECTED__ = true;\n console.log(\"%c[_____Vue DevTools v7 log_____]\", \"color: red; font-bold: 600; font-size: 16px;\");\n console.log(\"%cVue DevTools v7 detected in your Vue2 project. v7 only supports Vue3 and will not work.\", \"font-bold: 500; font-size: 14px;\");\n const legacyChromeUrl = \"https://chromewebstore.google.com/detail/vuejs-devtools/iaajmlceplecbljialhhkmedjlpdblhp\";\n const legacyFirefoxUrl = \"https://addons.mozilla.org/firefox/addon/vue-js-devtools-v6-legacy\";\n console.log(`%cThe legacy version of chrome extension that supports both Vue 2 and Vue 3 has been moved to %c ${legacyChromeUrl}`, \"font-size: 14px;\", \"text-decoration: underline; cursor: pointer;font-size: 14px;\");\n console.log(`%cThe legacy version of firefox extension that supports both Vue 2 and Vue 3 has been moved to %c ${legacyFirefoxUrl}`, \"font-size: 14px;\", \"text-decoration: underline; cursor: pointer;font-size: 14px;\");\n console.log(\"%cPlease install and enable only the legacy version for your Vue2 app.\", \"font-bold: 500; font-size: 14px;\");\n console.log(\"%c[_____Vue DevTools v7 log_____]\", \"color: red; font-bold: 600; font-size: 16px;\");\n });\n hook.on.setupDevtoolsPlugin((pluginDescriptor, setupFn) => {\n var _a26;\n addDevToolsPluginToBuffer(pluginDescriptor, setupFn);\n const { app } = (_a26 = activeAppRecord) != null ? _a26 : {};\n if (pluginDescriptor.settings) {\n initPluginSettings(pluginDescriptor.id, pluginDescriptor.settings);\n }\n if (!app)\n return;\n callDevToolsPluginSetupFn([pluginDescriptor, setupFn], app);\n });\n onLegacyDevToolsPluginApiAvailable(() => {\n const normalizedPluginBuffer = devtoolsPluginBuffer.filter(([item]) => item.id !== \"components\");\n normalizedPluginBuffer.forEach(([pluginDescriptor, setupFn]) => {\n _devtoolsHook.emit(\"devtools-plugin:setup\" /* SETUP_DEVTOOLS_PLUGIN */, pluginDescriptor, setupFn, { target: \"legacy\" });\n });\n });\n hook.on.vueAppInit(async (app, version, types) => {\n const appRecord = createAppRecord(app, types);\n const normalizedAppRecord = {\n ...appRecord,\n app,\n version\n };\n addDevToolsAppRecord(normalizedAppRecord);\n if (devtoolsAppRecords.value.length === 1) {\n setActiveAppRecord(normalizedAppRecord);\n setActiveAppRecordId(normalizedAppRecord.id);\n normalizeRouterInfo(normalizedAppRecord, activeAppRecord);\n registerDevToolsPlugin(normalizedAppRecord.app);\n }\n setupDevToolsPlugin(...createComponentsDevToolsPlugin(normalizedAppRecord.app));\n updateDevToolsState({\n connected: true\n });\n _devtoolsHook.apps.push(app);\n });\n hook.on.vueAppUnmount(async (app) => {\n const activeRecords = devtoolsAppRecords.value.filter((appRecord) => appRecord.app !== app);\n if (activeRecords.length === 0) {\n updateDevToolsState({\n connected: false\n });\n }\n removeDevToolsAppRecord(app);\n removeAppRecordId(app);\n if (activeAppRecord.value.app === app) {\n setActiveAppRecord(activeRecords[0]);\n devtoolsContext.hooks.callHook(\"sendActiveAppUpdatedToClient\" /* SEND_ACTIVE_APP_UNMOUNTED_TO_CLIENT */);\n }\n target13.__VUE_DEVTOOLS_GLOBAL_HOOK__.apps.splice(target13.__VUE_DEVTOOLS_GLOBAL_HOOK__.apps.indexOf(app), 1);\n removeRegisteredPluginApp(app);\n });\n subscribeDevToolsHook(_devtoolsHook);\n if (!target13.__VUE_DEVTOOLS_GLOBAL_HOOK__) {\n Object.defineProperty(target13, \"__VUE_DEVTOOLS_GLOBAL_HOOK__\", {\n get() {\n return _devtoolsHook;\n },\n configurable: true\n });\n } else {\n if (!isNuxtApp) {\n Object.assign(__VUE_DEVTOOLS_GLOBAL_HOOK__, _devtoolsHook);\n }\n }\n}\nfunction onDevToolsClientConnected(fn) {\n return new Promise((resolve) => {\n if (devtoolsState.connected && devtoolsState.clientConnected) {\n fn();\n resolve();\n return;\n }\n devtoolsContext.hooks.hook(\"devtoolsConnectedUpdated\" /* DEVTOOLS_CONNECTED_UPDATED */, ({ state }) => {\n if (state.connected && state.clientConnected) {\n fn();\n resolve();\n }\n });\n });\n}\n\n// src/core/high-perf-mode/index.ts\ninit_esm_shims();\nfunction toggleHighPerfMode(state) {\n devtoolsState.highPerfModeEnabled = state != null ? state : !devtoolsState.highPerfModeEnabled;\n if (!state && activeAppRecord.value) {\n registerDevToolsPlugin(activeAppRecord.value.app);\n }\n}\n\n// src/core/component/state/format.ts\ninit_esm_shims();\n\n// src/core/component/state/reviver.ts\ninit_esm_shims();\nimport { target as target14 } from \"@vue/devtools-shared\";\nfunction reviveSet(val) {\n const result = /* @__PURE__ */ new Set();\n const list = val._custom.value;\n for (let i = 0; i < list.length; i++) {\n const value = list[i];\n result.add(revive(value));\n }\n return result;\n}\nfunction reviveMap(val) {\n const result = /* @__PURE__ */ new Map();\n const list = val._custom.value;\n for (let i = 0; i < list.length; i++) {\n const { key, value } = list[i];\n result.set(key, revive(value));\n }\n return result;\n}\nfunction revive(val) {\n if (val === UNDEFINED) {\n return void 0;\n } else if (val === INFINITY) {\n return Number.POSITIVE_INFINITY;\n } else if (val === NEGATIVE_INFINITY) {\n return Number.NEGATIVE_INFINITY;\n } else if (val === NAN) {\n return Number.NaN;\n } else if (val && val._custom) {\n const { _custom: custom } = val;\n if (custom.type === \"component\")\n return activeAppRecord.value.instanceMap.get(custom.id);\n else if (custom.type === \"map\")\n return reviveMap(val);\n else if (custom.type === \"set\")\n return reviveSet(val);\n else if (custom.type === \"bigint\")\n return BigInt(custom.value);\n else\n return revive(custom.value);\n } else if (symbolRE.test(val)) {\n const [, string] = symbolRE.exec(val);\n return Symbol.for(string);\n } else if (specialTypeRE.test(val)) {\n const [, type, string, , details] = specialTypeRE.exec(val);\n const result = new target14[type](string);\n if (type === \"Error\" && details)\n result.stack = details;\n return result;\n } else {\n return val;\n }\n}\nfunction reviver(key, value) {\n return revive(value);\n}\n\n// src/core/component/state/format.ts\nfunction getInspectorStateValueType(value, raw = true) {\n const type = typeof value;\n if (value == null || value === UNDEFINED || value === \"undefined\") {\n return \"null\";\n } else if (type === \"boolean\" || type === \"number\" || value === INFINITY || value === NEGATIVE_INFINITY || value === NAN) {\n return \"literal\";\n } else if (value == null ? void 0 : value._custom) {\n if (raw || value._custom.display != null || value._custom.displayText != null)\n return \"custom\";\n else\n return getInspectorStateValueType(value._custom.value);\n } else if (typeof value === \"string\") {\n const typeMatch = specialTypeRE.exec(value);\n if (typeMatch) {\n const [, type2] = typeMatch;\n return `native ${type2}`;\n } else {\n return \"string\";\n }\n } else if (Array.isArray(value) || (value == null ? void 0 : value._isArray)) {\n return \"array\";\n } else if (isPlainObject(value)) {\n return \"plain-object\";\n } else {\n return \"unknown\";\n }\n}\nfunction formatInspectorStateValue(value, quotes = false, options) {\n var _a25, _b25, _c;\n const { customClass } = options != null ? options : {};\n let result;\n const type = getInspectorStateValueType(value, false);\n if (type !== \"custom\" && (value == null ? void 0 : value._custom))\n value = value._custom.value;\n if (result = internalStateTokenToString(value)) {\n return result;\n } else if (type === \"custom\") {\n const nestedName = ((_a25 = value._custom.value) == null ? void 0 : _a25._custom) && formatInspectorStateValue(value._custom.value, quotes, options);\n return nestedName || value._custom.displayText || value._custom.display;\n } else if (type === \"array\") {\n return `Array[${value.length}]`;\n } else if (type === \"plain-object\") {\n return `Object${Object.keys(value).length ? \"\" : \" (empty)\"}`;\n } else if (type == null ? void 0 : type.includes(\"native\")) {\n return escape((_b25 = specialTypeRE.exec(value)) == null ? void 0 : _b25[2]);\n } else if (typeof value === \"string\") {\n const typeMatch = value.match(rawTypeRE);\n if (typeMatch) {\n value = escapeString(typeMatch[1]);\n } else if (quotes) {\n value = `\"${(customClass == null ? void 0 : customClass.string) ? `${escapeString(value)}` : escapeString(value)}\"`;\n } else {\n value = (customClass == null ? void 0 : customClass.string) ? `${escapeString(value)}` : escapeString(value);\n }\n }\n return value;\n}\nfunction escapeString(value) {\n return escape(value).replace(/ /g, \" \").replace(/\\n/g, \"\\\\n\");\n}\nfunction getRaw(value) {\n var _a25, _b25, _c;\n let customType;\n const isCustom = getInspectorStateValueType(value) === \"custom\";\n let inherit = {};\n if (isCustom) {\n const data = value;\n const customValue = (_a25 = data._custom) == null ? void 0 : _a25.value;\n const currentCustomType = (_b25 = data._custom) == null ? void 0 : _b25.type;\n const nestedCustom = typeof customValue === \"object\" && customValue !== null && \"_custom\" in customValue ? getRaw(customValue) : { inherit: void 0, value: void 0, customType: void 0 };\n inherit = nestedCustom.inherit || ((_c = data._custom) == null ? void 0 : _c.fields) || {};\n value = nestedCustom.value || customValue;\n customType = nestedCustom.customType || currentCustomType;\n }\n if (value && value._isArray)\n value = value.items;\n return { value, inherit, customType };\n}\nfunction toEdit(value, customType) {\n if (customType === \"bigint\")\n return value;\n if (customType === \"date\")\n return value;\n return replaceTokenToString(JSON.stringify(value));\n}\nfunction toSubmit(value, customType) {\n if (customType === \"bigint\")\n return BigInt(value);\n if (customType === \"date\")\n return new Date(value);\n return JSON.parse(replaceStringToToken(value), reviver);\n}\n\n// src/core/devtools-client/detected.ts\ninit_esm_shims();\nimport { target as target15 } from \"@vue/devtools-shared\";\nfunction updateDevToolsClientDetected(params) {\n devtoolsState.devtoolsClientDetected = {\n ...devtoolsState.devtoolsClientDetected,\n ...params\n };\n const devtoolsClientVisible = Object.values(devtoolsState.devtoolsClientDetected).some(Boolean);\n toggleHighPerfMode(!devtoolsClientVisible);\n}\nvar _a18, _b18;\n(_b18 = (_a18 = target15).__VUE_DEVTOOLS_UPDATE_CLIENT_DETECTED__) != null ? _b18 : _a18.__VUE_DEVTOOLS_UPDATE_CLIENT_DETECTED__ = updateDevToolsClientDetected;\n\n// src/messaging/index.ts\ninit_esm_shims();\nimport { target as target21 } from \"@vue/devtools-shared\";\nimport { createBirpc, createBirpcGroup } from \"birpc\";\n\n// src/messaging/presets/index.ts\ninit_esm_shims();\n\n// src/messaging/presets/broadcast-channel/index.ts\ninit_esm_shims();\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/index.js\ninit_esm_shims();\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/class-registry.js\ninit_esm_shims();\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/registry.js\ninit_esm_shims();\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/double-indexed-kv.js\ninit_esm_shims();\nvar DoubleIndexedKV = class {\n constructor() {\n this.keyToValue = /* @__PURE__ */ new Map();\n this.valueToKey = /* @__PURE__ */ new Map();\n }\n set(key, value) {\n this.keyToValue.set(key, value);\n this.valueToKey.set(value, key);\n }\n getByKey(key) {\n return this.keyToValue.get(key);\n }\n getByValue(value) {\n return this.valueToKey.get(value);\n }\n clear() {\n this.keyToValue.clear();\n this.valueToKey.clear();\n }\n};\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/registry.js\nvar Registry = class {\n constructor(generateIdentifier) {\n this.generateIdentifier = generateIdentifier;\n this.kv = new DoubleIndexedKV();\n }\n register(value, identifier) {\n if (this.kv.getByValue(value)) {\n return;\n }\n if (!identifier) {\n identifier = this.generateIdentifier(value);\n }\n this.kv.set(identifier, value);\n }\n clear() {\n this.kv.clear();\n }\n getIdentifier(value) {\n return this.kv.getByValue(value);\n }\n getValue(identifier) {\n return this.kv.getByKey(identifier);\n }\n};\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/class-registry.js\nvar ClassRegistry = class extends Registry {\n constructor() {\n super((c) => c.name);\n this.classToAllowedProps = /* @__PURE__ */ new Map();\n }\n register(value, options) {\n if (typeof options === \"object\") {\n if (options.allowProps) {\n this.classToAllowedProps.set(value, options.allowProps);\n }\n super.register(value, options.identifier);\n } else {\n super.register(value, options);\n }\n }\n getAllowedProps(value) {\n return this.classToAllowedProps.get(value);\n }\n};\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/custom-transformer-registry.js\ninit_esm_shims();\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/util.js\ninit_esm_shims();\nfunction valuesOfObj(record) {\n if (\"values\" in Object) {\n return Object.values(record);\n }\n const values = [];\n for (const key in record) {\n if (record.hasOwnProperty(key)) {\n values.push(record[key]);\n }\n }\n return values;\n}\nfunction find(record, predicate) {\n const values = valuesOfObj(record);\n if (\"find\" in values) {\n return values.find(predicate);\n }\n const valuesNotNever = values;\n for (let i = 0; i < valuesNotNever.length; i++) {\n const value = valuesNotNever[i];\n if (predicate(value)) {\n return value;\n }\n }\n return void 0;\n}\nfunction forEach(record, run) {\n Object.entries(record).forEach(([key, value]) => run(value, key));\n}\nfunction includes(arr, value) {\n return arr.indexOf(value) !== -1;\n}\nfunction findArr(record, predicate) {\n for (let i = 0; i < record.length; i++) {\n const value = record[i];\n if (predicate(value)) {\n return value;\n }\n }\n return void 0;\n}\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/custom-transformer-registry.js\nvar CustomTransformerRegistry = class {\n constructor() {\n this.transfomers = {};\n }\n register(transformer) {\n this.transfomers[transformer.name] = transformer;\n }\n findApplicable(v) {\n return find(this.transfomers, (transformer) => transformer.isApplicable(v));\n }\n findByName(name) {\n return this.transfomers[name];\n }\n};\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/plainer.js\ninit_esm_shims();\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/is.js\ninit_esm_shims();\nvar getType = (payload) => Object.prototype.toString.call(payload).slice(8, -1);\nvar isUndefined = (payload) => typeof payload === \"undefined\";\nvar isNull = (payload) => payload === null;\nvar isPlainObject2 = (payload) => {\n if (typeof payload !== \"object\" || payload === null)\n return false;\n if (payload === Object.prototype)\n return false;\n if (Object.getPrototypeOf(payload) === null)\n return true;\n return Object.getPrototypeOf(payload) === Object.prototype;\n};\nvar isEmptyObject = (payload) => isPlainObject2(payload) && Object.keys(payload).length === 0;\nvar isArray = (payload) => Array.isArray(payload);\nvar isString = (payload) => typeof payload === \"string\";\nvar isNumber = (payload) => typeof payload === \"number\" && !isNaN(payload);\nvar isBoolean = (payload) => typeof payload === \"boolean\";\nvar isRegExp = (payload) => payload instanceof RegExp;\nvar isMap = (payload) => payload instanceof Map;\nvar isSet = (payload) => payload instanceof Set;\nvar isSymbol = (payload) => getType(payload) === \"Symbol\";\nvar isDate = (payload) => payload instanceof Date && !isNaN(payload.valueOf());\nvar isError = (payload) => payload instanceof Error;\nvar isNaNValue = (payload) => typeof payload === \"number\" && isNaN(payload);\nvar isPrimitive2 = (payload) => isBoolean(payload) || isNull(payload) || isUndefined(payload) || isNumber(payload) || isString(payload) || isSymbol(payload);\nvar isBigint = (payload) => typeof payload === \"bigint\";\nvar isInfinite = (payload) => payload === Infinity || payload === -Infinity;\nvar isTypedArray = (payload) => ArrayBuffer.isView(payload) && !(payload instanceof DataView);\nvar isURL = (payload) => payload instanceof URL;\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/pathstringifier.js\ninit_esm_shims();\nvar escapeKey = (key) => key.replace(/\\./g, \"\\\\.\");\nvar stringifyPath = (path) => path.map(String).map(escapeKey).join(\".\");\nvar parsePath = (string) => {\n const result = [];\n let segment = \"\";\n for (let i = 0; i < string.length; i++) {\n let char = string.charAt(i);\n const isEscapedDot = char === \"\\\\\" && string.charAt(i + 1) === \".\";\n if (isEscapedDot) {\n segment += \".\";\n i++;\n continue;\n }\n const isEndOfSegment = char === \".\";\n if (isEndOfSegment) {\n result.push(segment);\n segment = \"\";\n continue;\n }\n segment += char;\n }\n const lastSegment = segment;\n result.push(lastSegment);\n return result;\n};\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/transformer.js\ninit_esm_shims();\nfunction simpleTransformation(isApplicable, annotation, transform, untransform) {\n return {\n isApplicable,\n annotation,\n transform,\n untransform\n };\n}\nvar simpleRules = [\n simpleTransformation(isUndefined, \"undefined\", () => null, () => void 0),\n simpleTransformation(isBigint, \"bigint\", (v) => v.toString(), (v) => {\n if (typeof BigInt !== \"undefined\") {\n return BigInt(v);\n }\n console.error(\"Please add a BigInt polyfill.\");\n return v;\n }),\n simpleTransformation(isDate, \"Date\", (v) => v.toISOString(), (v) => new Date(v)),\n simpleTransformation(isError, \"Error\", (v, superJson) => {\n const baseError = {\n name: v.name,\n message: v.message\n };\n superJson.allowedErrorProps.forEach((prop) => {\n baseError[prop] = v[prop];\n });\n return baseError;\n }, (v, superJson) => {\n const e = new Error(v.message);\n e.name = v.name;\n e.stack = v.stack;\n superJson.allowedErrorProps.forEach((prop) => {\n e[prop] = v[prop];\n });\n return e;\n }),\n simpleTransformation(isRegExp, \"regexp\", (v) => \"\" + v, (regex) => {\n const body = regex.slice(1, regex.lastIndexOf(\"/\"));\n const flags = regex.slice(regex.lastIndexOf(\"/\") + 1);\n return new RegExp(body, flags);\n }),\n simpleTransformation(\n isSet,\n \"set\",\n // (sets only exist in es6+)\n // eslint-disable-next-line es5/no-es6-methods\n (v) => [...v.values()],\n (v) => new Set(v)\n ),\n simpleTransformation(isMap, \"map\", (v) => [...v.entries()], (v) => new Map(v)),\n simpleTransformation((v) => isNaNValue(v) || isInfinite(v), \"number\", (v) => {\n if (isNaNValue(v)) {\n return \"NaN\";\n }\n if (v > 0) {\n return \"Infinity\";\n } else {\n return \"-Infinity\";\n }\n }, Number),\n simpleTransformation((v) => v === 0 && 1 / v === -Infinity, \"number\", () => {\n return \"-0\";\n }, Number),\n simpleTransformation(isURL, \"URL\", (v) => v.toString(), (v) => new URL(v))\n];\nfunction compositeTransformation(isApplicable, annotation, transform, untransform) {\n return {\n isApplicable,\n annotation,\n transform,\n untransform\n };\n}\nvar symbolRule = compositeTransformation((s, superJson) => {\n if (isSymbol(s)) {\n const isRegistered = !!superJson.symbolRegistry.getIdentifier(s);\n return isRegistered;\n }\n return false;\n}, (s, superJson) => {\n const identifier = superJson.symbolRegistry.getIdentifier(s);\n return [\"symbol\", identifier];\n}, (v) => v.description, (_, a, superJson) => {\n const value = superJson.symbolRegistry.getValue(a[1]);\n if (!value) {\n throw new Error(\"Trying to deserialize unknown symbol\");\n }\n return value;\n});\nvar constructorToName = [\n Int8Array,\n Uint8Array,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n Float32Array,\n Float64Array,\n Uint8ClampedArray\n].reduce((obj, ctor) => {\n obj[ctor.name] = ctor;\n return obj;\n}, {});\nvar typedArrayRule = compositeTransformation(isTypedArray, (v) => [\"typed-array\", v.constructor.name], (v) => [...v], (v, a) => {\n const ctor = constructorToName[a[1]];\n if (!ctor) {\n throw new Error(\"Trying to deserialize unknown typed array\");\n }\n return new ctor(v);\n});\nfunction isInstanceOfRegisteredClass(potentialClass, superJson) {\n if (potentialClass == null ? void 0 : potentialClass.constructor) {\n const isRegistered = !!superJson.classRegistry.getIdentifier(potentialClass.constructor);\n return isRegistered;\n }\n return false;\n}\nvar classRule = compositeTransformation(isInstanceOfRegisteredClass, (clazz, superJson) => {\n const identifier = superJson.classRegistry.getIdentifier(clazz.constructor);\n return [\"class\", identifier];\n}, (clazz, superJson) => {\n const allowedProps = superJson.classRegistry.getAllowedProps(clazz.constructor);\n if (!allowedProps) {\n return { ...clazz };\n }\n const result = {};\n allowedProps.forEach((prop) => {\n result[prop] = clazz[prop];\n });\n return result;\n}, (v, a, superJson) => {\n const clazz = superJson.classRegistry.getValue(a[1]);\n if (!clazz) {\n throw new Error(`Trying to deserialize unknown class '${a[1]}' - check https://github.com/blitz-js/superjson/issues/116#issuecomment-773996564`);\n }\n return Object.assign(Object.create(clazz.prototype), v);\n});\nvar customRule = compositeTransformation((value, superJson) => {\n return !!superJson.customTransformerRegistry.findApplicable(value);\n}, (value, superJson) => {\n const transformer = superJson.customTransformerRegistry.findApplicable(value);\n return [\"custom\", transformer.name];\n}, (value, superJson) => {\n const transformer = superJson.customTransformerRegistry.findApplicable(value);\n return transformer.serialize(value);\n}, (v, a, superJson) => {\n const transformer = superJson.customTransformerRegistry.findByName(a[1]);\n if (!transformer) {\n throw new Error(\"Trying to deserialize unknown custom value\");\n }\n return transformer.deserialize(v);\n});\nvar compositeRules = [classRule, symbolRule, customRule, typedArrayRule];\nvar transformValue = (value, superJson) => {\n const applicableCompositeRule = findArr(compositeRules, (rule) => rule.isApplicable(value, superJson));\n if (applicableCompositeRule) {\n return {\n value: applicableCompositeRule.transform(value, superJson),\n type: applicableCompositeRule.annotation(value, superJson)\n };\n }\n const applicableSimpleRule = findArr(simpleRules, (rule) => rule.isApplicable(value, superJson));\n if (applicableSimpleRule) {\n return {\n value: applicableSimpleRule.transform(value, superJson),\n type: applicableSimpleRule.annotation\n };\n }\n return void 0;\n};\nvar simpleRulesByAnnotation = {};\nsimpleRules.forEach((rule) => {\n simpleRulesByAnnotation[rule.annotation] = rule;\n});\nvar untransformValue = (json, type, superJson) => {\n if (isArray(type)) {\n switch (type[0]) {\n case \"symbol\":\n return symbolRule.untransform(json, type, superJson);\n case \"class\":\n return classRule.untransform(json, type, superJson);\n case \"custom\":\n return customRule.untransform(json, type, superJson);\n case \"typed-array\":\n return typedArrayRule.untransform(json, type, superJson);\n default:\n throw new Error(\"Unknown transformation: \" + type);\n }\n } else {\n const transformation = simpleRulesByAnnotation[type];\n if (!transformation) {\n throw new Error(\"Unknown transformation: \" + type);\n }\n return transformation.untransform(json, superJson);\n }\n};\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/accessDeep.js\ninit_esm_shims();\nvar getNthKey = (value, n) => {\n if (n > value.size)\n throw new Error(\"index out of bounds\");\n const keys = value.keys();\n while (n > 0) {\n keys.next();\n n--;\n }\n return keys.next().value;\n};\nfunction validatePath(path) {\n if (includes(path, \"__proto__\")) {\n throw new Error(\"__proto__ is not allowed as a property\");\n }\n if (includes(path, \"prototype\")) {\n throw new Error(\"prototype is not allowed as a property\");\n }\n if (includes(path, \"constructor\")) {\n throw new Error(\"constructor is not allowed as a property\");\n }\n}\nvar getDeep = (object, path) => {\n validatePath(path);\n for (let i = 0; i < path.length; i++) {\n const key = path[i];\n if (isSet(object)) {\n object = getNthKey(object, +key);\n } else if (isMap(object)) {\n const row = +key;\n const type = +path[++i] === 0 ? \"key\" : \"value\";\n const keyOfRow = getNthKey(object, row);\n switch (type) {\n case \"key\":\n object = keyOfRow;\n break;\n case \"value\":\n object = object.get(keyOfRow);\n break;\n }\n } else {\n object = object[key];\n }\n }\n return object;\n};\nvar setDeep = (object, path, mapper) => {\n validatePath(path);\n if (path.length === 0) {\n return mapper(object);\n }\n let parent = object;\n for (let i = 0; i < path.length - 1; i++) {\n const key = path[i];\n if (isArray(parent)) {\n const index = +key;\n parent = parent[index];\n } else if (isPlainObject2(parent)) {\n parent = parent[key];\n } else if (isSet(parent)) {\n const row = +key;\n parent = getNthKey(parent, row);\n } else if (isMap(parent)) {\n const isEnd = i === path.length - 2;\n if (isEnd) {\n break;\n }\n const row = +key;\n const type = +path[++i] === 0 ? \"key\" : \"value\";\n const keyOfRow = getNthKey(parent, row);\n switch (type) {\n case \"key\":\n parent = keyOfRow;\n break;\n case \"value\":\n parent = parent.get(keyOfRow);\n break;\n }\n }\n }\n const lastKey = path[path.length - 1];\n if (isArray(parent)) {\n parent[+lastKey] = mapper(parent[+lastKey]);\n } else if (isPlainObject2(parent)) {\n parent[lastKey] = mapper(parent[lastKey]);\n }\n if (isSet(parent)) {\n const oldValue = getNthKey(parent, +lastKey);\n const newValue = mapper(oldValue);\n if (oldValue !== newValue) {\n parent.delete(oldValue);\n parent.add(newValue);\n }\n }\n if (isMap(parent)) {\n const row = +path[path.length - 2];\n const keyToRow = getNthKey(parent, row);\n const type = +lastKey === 0 ? \"key\" : \"value\";\n switch (type) {\n case \"key\": {\n const newKey = mapper(keyToRow);\n parent.set(newKey, parent.get(keyToRow));\n if (newKey !== keyToRow) {\n parent.delete(keyToRow);\n }\n break;\n }\n case \"value\": {\n parent.set(keyToRow, mapper(parent.get(keyToRow)));\n break;\n }\n }\n }\n return object;\n};\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/plainer.js\nfunction traverse(tree, walker2, origin = []) {\n if (!tree) {\n return;\n }\n if (!isArray(tree)) {\n forEach(tree, (subtree, key) => traverse(subtree, walker2, [...origin, ...parsePath(key)]));\n return;\n }\n const [nodeValue, children] = tree;\n if (children) {\n forEach(children, (child, key) => {\n traverse(child, walker2, [...origin, ...parsePath(key)]);\n });\n }\n walker2(nodeValue, origin);\n}\nfunction applyValueAnnotations(plain, annotations, superJson) {\n traverse(annotations, (type, path) => {\n plain = setDeep(plain, path, (v) => untransformValue(v, type, superJson));\n });\n return plain;\n}\nfunction applyReferentialEqualityAnnotations(plain, annotations) {\n function apply(identicalPaths, path) {\n const object = getDeep(plain, parsePath(path));\n identicalPaths.map(parsePath).forEach((identicalObjectPath) => {\n plain = setDeep(plain, identicalObjectPath, () => object);\n });\n }\n if (isArray(annotations)) {\n const [root, other] = annotations;\n root.forEach((identicalPath) => {\n plain = setDeep(plain, parsePath(identicalPath), () => plain);\n });\n if (other) {\n forEach(other, apply);\n }\n } else {\n forEach(annotations, apply);\n }\n return plain;\n}\nvar isDeep = (object, superJson) => isPlainObject2(object) || isArray(object) || isMap(object) || isSet(object) || isInstanceOfRegisteredClass(object, superJson);\nfunction addIdentity(object, path, identities) {\n const existingSet = identities.get(object);\n if (existingSet) {\n existingSet.push(path);\n } else {\n identities.set(object, [path]);\n }\n}\nfunction generateReferentialEqualityAnnotations(identitites, dedupe) {\n const result = {};\n let rootEqualityPaths = void 0;\n identitites.forEach((paths) => {\n if (paths.length <= 1) {\n return;\n }\n if (!dedupe) {\n paths = paths.map((path) => path.map(String)).sort((a, b) => a.length - b.length);\n }\n const [representativePath, ...identicalPaths] = paths;\n if (representativePath.length === 0) {\n rootEqualityPaths = identicalPaths.map(stringifyPath);\n } else {\n result[stringifyPath(representativePath)] = identicalPaths.map(stringifyPath);\n }\n });\n if (rootEqualityPaths) {\n if (isEmptyObject(result)) {\n return [rootEqualityPaths];\n } else {\n return [rootEqualityPaths, result];\n }\n } else {\n return isEmptyObject(result) ? void 0 : result;\n }\n}\nvar walker = (object, identities, superJson, dedupe, path = [], objectsInThisPath = [], seenObjects = /* @__PURE__ */ new Map()) => {\n var _a25;\n const primitive = isPrimitive2(object);\n if (!primitive) {\n addIdentity(object, path, identities);\n const seen = seenObjects.get(object);\n if (seen) {\n return dedupe ? {\n transformedValue: null\n } : seen;\n }\n }\n if (!isDeep(object, superJson)) {\n const transformed2 = transformValue(object, superJson);\n const result2 = transformed2 ? {\n transformedValue: transformed2.value,\n annotations: [transformed2.type]\n } : {\n transformedValue: object\n };\n if (!primitive) {\n seenObjects.set(object, result2);\n }\n return result2;\n }\n if (includes(objectsInThisPath, object)) {\n return {\n transformedValue: null\n };\n }\n const transformationResult = transformValue(object, superJson);\n const transformed = (_a25 = transformationResult == null ? void 0 : transformationResult.value) != null ? _a25 : object;\n const transformedValue = isArray(transformed) ? [] : {};\n const innerAnnotations = {};\n forEach(transformed, (value, index) => {\n if (index === \"__proto__\" || index === \"constructor\" || index === \"prototype\") {\n throw new Error(`Detected property ${index}. This is a prototype pollution risk, please remove it from your object.`);\n }\n const recursiveResult = walker(value, identities, superJson, dedupe, [...path, index], [...objectsInThisPath, object], seenObjects);\n transformedValue[index] = recursiveResult.transformedValue;\n if (isArray(recursiveResult.annotations)) {\n innerAnnotations[index] = recursiveResult.annotations;\n } else if (isPlainObject2(recursiveResult.annotations)) {\n forEach(recursiveResult.annotations, (tree, key) => {\n innerAnnotations[escapeKey(index) + \".\" + key] = tree;\n });\n }\n });\n const result = isEmptyObject(innerAnnotations) ? {\n transformedValue,\n annotations: !!transformationResult ? [transformationResult.type] : void 0\n } : {\n transformedValue,\n annotations: !!transformationResult ? [transformationResult.type, innerAnnotations] : innerAnnotations\n };\n if (!primitive) {\n seenObjects.set(object, result);\n }\n return result;\n};\n\n// ../../node_modules/.pnpm/copy-anything@3.0.5/node_modules/copy-anything/dist/index.js\ninit_esm_shims();\n\n// ../../node_modules/.pnpm/is-what@4.1.16/node_modules/is-what/dist/index.js\ninit_esm_shims();\nfunction getType2(payload) {\n return Object.prototype.toString.call(payload).slice(8, -1);\n}\nfunction isArray2(payload) {\n return getType2(payload) === \"Array\";\n}\nfunction isPlainObject3(payload) {\n if (getType2(payload) !== \"Object\")\n return false;\n const prototype = Object.getPrototypeOf(payload);\n return !!prototype && prototype.constructor === Object && prototype === Object.prototype;\n}\nfunction isNull2(payload) {\n return getType2(payload) === \"Null\";\n}\nfunction isOneOf(a, b, c, d, e) {\n return (value) => a(value) || b(value) || !!c && c(value) || !!d && d(value) || !!e && e(value);\n}\nfunction isUndefined2(payload) {\n return getType2(payload) === \"Undefined\";\n}\nvar isNullOrUndefined = isOneOf(isNull2, isUndefined2);\n\n// ../../node_modules/.pnpm/copy-anything@3.0.5/node_modules/copy-anything/dist/index.js\nfunction assignProp(carry, key, newVal, originalObject, includeNonenumerable) {\n const propType = {}.propertyIsEnumerable.call(originalObject, key) ? \"enumerable\" : \"nonenumerable\";\n if (propType === \"enumerable\")\n carry[key] = newVal;\n if (includeNonenumerable && propType === \"nonenumerable\") {\n Object.defineProperty(carry, key, {\n value: newVal,\n enumerable: false,\n writable: true,\n configurable: true\n });\n }\n}\nfunction copy(target22, options = {}) {\n if (isArray2(target22)) {\n return target22.map((item) => copy(item, options));\n }\n if (!isPlainObject3(target22)) {\n return target22;\n }\n const props = Object.getOwnPropertyNames(target22);\n const symbols = Object.getOwnPropertySymbols(target22);\n return [...props, ...symbols].reduce((carry, key) => {\n if (isArray2(options.props) && !options.props.includes(key)) {\n return carry;\n }\n const val = target22[key];\n const newVal = copy(val, options);\n assignProp(carry, key, newVal, target22, options.nonenumerable);\n return carry;\n }, {});\n}\n\n// ../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/index.js\nvar SuperJSON = class {\n /**\n * @param dedupeReferentialEqualities If true, SuperJSON will make sure only one instance of referentially equal objects are serialized and the rest are replaced with `null`.\n */\n constructor({ dedupe = false } = {}) {\n this.classRegistry = new ClassRegistry();\n this.symbolRegistry = new Registry((s) => {\n var _a25;\n return (_a25 = s.description) != null ? _a25 : \"\";\n });\n this.customTransformerRegistry = new CustomTransformerRegistry();\n this.allowedErrorProps = [];\n this.dedupe = dedupe;\n }\n serialize(object) {\n const identities = /* @__PURE__ */ new Map();\n const output = walker(object, identities, this, this.dedupe);\n const res = {\n json: output.transformedValue\n };\n if (output.annotations) {\n res.meta = {\n ...res.meta,\n values: output.annotations\n };\n }\n const equalityAnnotations = generateReferentialEqualityAnnotations(identities, this.dedupe);\n if (equalityAnnotations) {\n res.meta = {\n ...res.meta,\n referentialEqualities: equalityAnnotations\n };\n }\n return res;\n }\n deserialize(payload) {\n const { json, meta } = payload;\n let result = copy(json);\n if (meta == null ? void 0 : meta.values) {\n result = applyValueAnnotations(result, meta.values, this);\n }\n if (meta == null ? void 0 : meta.referentialEqualities) {\n result = applyReferentialEqualityAnnotations(result, meta.referentialEqualities);\n }\n return result;\n }\n stringify(object) {\n return JSON.stringify(this.serialize(object));\n }\n parse(string) {\n return this.deserialize(JSON.parse(string));\n }\n registerClass(v, options) {\n this.classRegistry.register(v, options);\n }\n registerSymbol(v, identifier) {\n this.symbolRegistry.register(v, identifier);\n }\n registerCustom(transformer, name) {\n this.customTransformerRegistry.register({\n name,\n ...transformer\n });\n }\n allowErrorProps(...props) {\n this.allowedErrorProps.push(...props);\n }\n};\nSuperJSON.defaultInstance = new SuperJSON();\nSuperJSON.serialize = SuperJSON.defaultInstance.serialize.bind(SuperJSON.defaultInstance);\nSuperJSON.deserialize = SuperJSON.defaultInstance.deserialize.bind(SuperJSON.defaultInstance);\nSuperJSON.stringify = SuperJSON.defaultInstance.stringify.bind(SuperJSON.defaultInstance);\nSuperJSON.parse = SuperJSON.defaultInstance.parse.bind(SuperJSON.defaultInstance);\nSuperJSON.registerClass = SuperJSON.defaultInstance.registerClass.bind(SuperJSON.defaultInstance);\nSuperJSON.registerSymbol = SuperJSON.defaultInstance.registerSymbol.bind(SuperJSON.defaultInstance);\nSuperJSON.registerCustom = SuperJSON.defaultInstance.registerCustom.bind(SuperJSON.defaultInstance);\nSuperJSON.allowErrorProps = SuperJSON.defaultInstance.allowErrorProps.bind(SuperJSON.defaultInstance);\nvar serialize = SuperJSON.serialize;\nvar deserialize = SuperJSON.deserialize;\nvar stringify = SuperJSON.stringify;\nvar parse = SuperJSON.parse;\nvar registerClass = SuperJSON.registerClass;\nvar registerCustom = SuperJSON.registerCustom;\nvar registerSymbol = SuperJSON.registerSymbol;\nvar allowErrorProps = SuperJSON.allowErrorProps;\n\n// src/messaging/presets/broadcast-channel/context.ts\ninit_esm_shims();\nvar __DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY = \"__devtools-kit-broadcast-messaging-event-key__\";\n\n// src/messaging/presets/broadcast-channel/index.ts\nvar BROADCAST_CHANNEL_NAME = \"__devtools-kit:broadcast-channel__\";\nfunction createBroadcastChannel() {\n const channel = new BroadcastChannel(BROADCAST_CHANNEL_NAME);\n return {\n post: (data) => {\n channel.postMessage(SuperJSON.stringify({\n event: __DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY,\n data\n }));\n },\n on: (handler) => {\n channel.onmessage = (event) => {\n const parsed = SuperJSON.parse(event.data);\n if (parsed.event === __DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY) {\n handler(parsed.data);\n }\n };\n }\n };\n}\n\n// src/messaging/presets/electron/index.ts\ninit_esm_shims();\n\n// src/messaging/presets/electron/client.ts\ninit_esm_shims();\n\n// src/messaging/presets/electron/context.ts\ninit_esm_shims();\nimport { target as target16 } from \"@vue/devtools-shared\";\nvar __ELECTRON_CLIENT_CONTEXT__ = \"electron:client-context\";\nvar __ELECTRON_RPOXY_CONTEXT__ = \"electron:proxy-context\";\nvar __ELECTRON_SERVER_CONTEXT__ = \"electron:server-context\";\nvar __DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__ = {\n // client\n CLIENT_TO_PROXY: \"client->proxy\",\n // on: proxy->client\n // proxy\n PROXY_TO_CLIENT: \"proxy->client\",\n // on: server->proxy\n PROXY_TO_SERVER: \"proxy->server\",\n // on: client->proxy\n // server\n SERVER_TO_PROXY: \"server->proxy\"\n // on: proxy->server\n};\nfunction getElectronClientContext() {\n return target16[__ELECTRON_CLIENT_CONTEXT__];\n}\nfunction setElectronClientContext(context) {\n target16[__ELECTRON_CLIENT_CONTEXT__] = context;\n}\nfunction getElectronProxyContext() {\n return target16[__ELECTRON_RPOXY_CONTEXT__];\n}\nfunction setElectronProxyContext(context) {\n target16[__ELECTRON_RPOXY_CONTEXT__] = context;\n}\nfunction getElectronServerContext() {\n return target16[__ELECTRON_SERVER_CONTEXT__];\n}\nfunction setElectronServerContext(context) {\n target16[__ELECTRON_SERVER_CONTEXT__] = context;\n}\n\n// src/messaging/presets/electron/client.ts\nfunction createElectronClientChannel() {\n const socket = getElectronClientContext();\n return {\n post: (data) => {\n socket.emit(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.CLIENT_TO_PROXY, SuperJSON.stringify(data));\n },\n on: (handler) => {\n socket.on(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.PROXY_TO_CLIENT, (e) => {\n handler(SuperJSON.parse(e));\n });\n }\n };\n}\n\n// src/messaging/presets/electron/proxy.ts\ninit_esm_shims();\nfunction createElectronProxyChannel() {\n const socket = getElectronProxyContext();\n return {\n post: (data) => {\n },\n on: (handler) => {\n socket.on(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.SERVER_TO_PROXY, (data) => {\n socket.broadcast.emit(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.PROXY_TO_CLIENT, data);\n });\n socket.on(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.CLIENT_TO_PROXY, (data) => {\n socket.broadcast.emit(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.PROXY_TO_SERVER, data);\n });\n }\n };\n}\n\n// src/messaging/presets/electron/server.ts\ninit_esm_shims();\nfunction createElectronServerChannel() {\n const socket = getElectronServerContext();\n return {\n post: (data) => {\n socket.emit(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.SERVER_TO_PROXY, SuperJSON.stringify(data));\n },\n on: (handler) => {\n socket.on(__DEVTOOLS_KIT_ELECTRON_MESSAGING_EVENT_KEY__.PROXY_TO_SERVER, (data) => {\n handler(SuperJSON.parse(data));\n });\n }\n };\n}\n\n// src/messaging/presets/extension/index.ts\ninit_esm_shims();\n\n// src/messaging/presets/extension/client.ts\ninit_esm_shims();\n\n// src/messaging/presets/extension/context.ts\ninit_esm_shims();\nimport { target as target17 } from \"@vue/devtools-shared\";\nvar __EXTENSION_CLIENT_CONTEXT__ = \"electron:client-context\";\nvar __DEVTOOLS_KIT_EXTENSION_MESSAGING_EVENT_KEY__ = {\n // client\n CLIENT_TO_PROXY: \"client->proxy\",\n // on: proxy->client\n // proxy\n PROXY_TO_CLIENT: \"proxy->client\",\n // on: server->proxy\n PROXY_TO_SERVER: \"proxy->server\",\n // on: client->proxy\n // server\n SERVER_TO_PROXY: \"server->proxy\"\n // on: proxy->server\n};\nfunction getExtensionClientContext() {\n return target17[__EXTENSION_CLIENT_CONTEXT__];\n}\nfunction setExtensionClientContext(context) {\n target17[__EXTENSION_CLIENT_CONTEXT__] = context;\n}\n\n// src/messaging/presets/extension/client.ts\nfunction createExtensionClientChannel() {\n let disconnected = false;\n let port = null;\n let reconnectTimer = null;\n let onMessageHandler = null;\n function connect() {\n try {\n clearTimeout(reconnectTimer);\n port = chrome.runtime.connect({\n name: `${chrome.devtools.inspectedWindow.tabId}`\n });\n setExtensionClientContext(port);\n disconnected = false;\n port == null ? void 0 : port.onMessage.addListener(onMessageHandler);\n port.onDisconnect.addListener(() => {\n disconnected = true;\n port == null ? void 0 : port.onMessage.removeListener(onMessageHandler);\n reconnectTimer = setTimeout(connect, 1e3);\n });\n } catch (e) {\n disconnected = true;\n }\n }\n connect();\n return {\n post: (data) => {\n if (disconnected) {\n return;\n }\n port == null ? void 0 : port.postMessage(SuperJSON.stringify(data));\n },\n on: (handler) => {\n onMessageHandler = (data) => {\n if (disconnected) {\n return;\n }\n handler(SuperJSON.parse(data));\n };\n port == null ? void 0 : port.onMessage.addListener(onMessageHandler);\n }\n };\n}\n\n// src/messaging/presets/extension/proxy.ts\ninit_esm_shims();\nfunction createExtensionProxyChannel() {\n const port = chrome.runtime.connect({\n name: \"content-script\"\n });\n function sendMessageToUserApp(payload) {\n window.postMessage({\n source: __DEVTOOLS_KIT_EXTENSION_MESSAGING_EVENT_KEY__.PROXY_TO_SERVER,\n payload\n }, \"*\");\n }\n function sendMessageToDevToolsClient(e) {\n if (e.data && e.data.source === __DEVTOOLS_KIT_EXTENSION_MESSAGING_EVENT_KEY__.SERVER_TO_PROXY) {\n try {\n port.postMessage(e.data.payload);\n } catch (e2) {\n }\n }\n }\n port.onMessage.addListener(sendMessageToUserApp);\n window.addEventListener(\"message\", sendMessageToDevToolsClient);\n port.onDisconnect.addListener(() => {\n window.removeEventListener(\"message\", sendMessageToDevToolsClient);\n sendMessageToUserApp(SuperJSON.stringify({\n event: \"shutdown\"\n }));\n });\n sendMessageToUserApp(SuperJSON.stringify({\n event: \"init\"\n }));\n return {\n post: (data) => {\n },\n on: (handler) => {\n }\n };\n}\n\n// src/messaging/presets/extension/server.ts\ninit_esm_shims();\nfunction createExtensionServerChannel() {\n return {\n post: (data) => {\n window.postMessage({\n source: __DEVTOOLS_KIT_EXTENSION_MESSAGING_EVENT_KEY__.SERVER_TO_PROXY,\n payload: SuperJSON.stringify(data)\n }, \"*\");\n },\n on: (handler) => {\n const listener = (event) => {\n if (event.data.source === __DEVTOOLS_KIT_EXTENSION_MESSAGING_EVENT_KEY__.PROXY_TO_SERVER && event.data.payload) {\n handler(SuperJSON.parse(event.data.payload));\n }\n };\n window.addEventListener(\"message\", listener);\n return () => {\n window.removeEventListener(\"message\", listener);\n };\n }\n };\n}\n\n// src/messaging/presets/iframe/index.ts\ninit_esm_shims();\n\n// src/messaging/presets/iframe/client.ts\ninit_esm_shims();\nimport { isBrowser as isBrowser4 } from \"@vue/devtools-shared\";\n\n// src/messaging/presets/iframe/context.ts\ninit_esm_shims();\nimport { target as target18 } from \"@vue/devtools-shared\";\nvar __DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY = \"__devtools-kit-iframe-messaging-event-key__\";\nvar __IFRAME_SERVER_CONTEXT__ = \"iframe:server-context\";\nfunction getIframeServerContext() {\n return target18[__IFRAME_SERVER_CONTEXT__];\n}\nfunction setIframeServerContext(context) {\n target18[__IFRAME_SERVER_CONTEXT__] = context;\n}\n\n// src/messaging/presets/iframe/client.ts\nfunction createIframeClientChannel() {\n if (!isBrowser4) {\n return {\n post: (data) => {\n },\n on: (handler) => {\n }\n };\n }\n return {\n post: (data) => window.parent.postMessage(SuperJSON.stringify({\n event: __DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY,\n data\n }), \"*\"),\n on: (handler) => window.addEventListener(\"message\", (event) => {\n try {\n const parsed = SuperJSON.parse(event.data);\n if (event.source === window.parent && parsed.event === __DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY) {\n handler(parsed.data);\n }\n } catch (e) {\n }\n })\n };\n}\n\n// src/messaging/presets/iframe/server.ts\ninit_esm_shims();\nimport { isBrowser as isBrowser5 } from \"@vue/devtools-shared\";\nfunction createIframeServerChannel() {\n if (!isBrowser5) {\n return {\n post: (data) => {\n },\n on: (handler) => {\n }\n };\n }\n return {\n post: (data) => {\n var _a25;\n const iframe = getIframeServerContext();\n (_a25 = iframe == null ? void 0 : iframe.contentWindow) == null ? void 0 : _a25.postMessage(SuperJSON.stringify({\n event: __DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY,\n data\n }), \"*\");\n },\n on: (handler) => {\n window.addEventListener(\"message\", (event) => {\n const iframe = getIframeServerContext();\n try {\n const parsed = SuperJSON.parse(event.data);\n if (event.source === (iframe == null ? void 0 : iframe.contentWindow) && parsed.event === __DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY) {\n handler(parsed.data);\n }\n } catch (e) {\n }\n });\n }\n };\n}\n\n// src/messaging/presets/vite/index.ts\ninit_esm_shims();\n\n// src/messaging/presets/vite/client.ts\ninit_esm_shims();\n\n// src/messaging/presets/vite/context.ts\ninit_esm_shims();\nimport { target as target19 } from \"@vue/devtools-shared\";\nvar __DEVTOOLS_KIT_VITE_MESSAGING_EVENT_KEY = \"__devtools-kit-vite-messaging-event-key__\";\nvar __VITE_CLIENT_CONTEXT__ = \"vite:client-context\";\nvar __VITE_SERVER_CONTEXT__ = \"vite:server-context\";\nfunction getViteClientContext() {\n return target19[__VITE_CLIENT_CONTEXT__];\n}\nfunction setViteClientContext(context) {\n target19[__VITE_CLIENT_CONTEXT__] = context;\n}\nfunction getViteServerContext() {\n return target19[__VITE_SERVER_CONTEXT__];\n}\nfunction setViteServerContext(context) {\n target19[__VITE_SERVER_CONTEXT__] = context;\n}\n\n// src/messaging/presets/vite/client.ts\nfunction createViteClientChannel() {\n const client = getViteClientContext();\n return {\n post: (data) => {\n client == null ? void 0 : client.send(__DEVTOOLS_KIT_VITE_MESSAGING_EVENT_KEY, SuperJSON.stringify(data));\n },\n on: (handler) => {\n client == null ? void 0 : client.on(__DEVTOOLS_KIT_VITE_MESSAGING_EVENT_KEY, (event) => {\n handler(SuperJSON.parse(event));\n });\n }\n };\n}\n\n// src/messaging/presets/vite/server.ts\ninit_esm_shims();\nfunction createViteServerChannel() {\n var _a25;\n const viteServer = getViteServerContext();\n const ws = (_a25 = viteServer.hot) != null ? _a25 : viteServer.ws;\n return {\n post: (data) => ws == null ? void 0 : ws.send(__DEVTOOLS_KIT_VITE_MESSAGING_EVENT_KEY, SuperJSON.stringify(data)),\n on: (handler) => ws == null ? void 0 : ws.on(__DEVTOOLS_KIT_VITE_MESSAGING_EVENT_KEY, (event) => {\n handler(SuperJSON.parse(event));\n })\n };\n}\n\n// src/messaging/presets/ws/index.ts\ninit_esm_shims();\n\n// src/messaging/presets/ws/client.ts\ninit_esm_shims();\n\n// src/messaging/presets/ws/context.ts\ninit_esm_shims();\nimport { target as target20 } from \"@vue/devtools-shared\";\n\n// src/messaging/presets/ws/server.ts\ninit_esm_shims();\n\n// src/messaging/index.ts\nvar _a19, _b19;\n(_b19 = (_a19 = target21).__VUE_DEVTOOLS_KIT_MESSAGE_CHANNELS__) != null ? _b19 : _a19.__VUE_DEVTOOLS_KIT_MESSAGE_CHANNELS__ = [];\nvar _a20, _b20;\n(_b20 = (_a20 = target21).__VUE_DEVTOOLS_KIT_RPC_CLIENT__) != null ? _b20 : _a20.__VUE_DEVTOOLS_KIT_RPC_CLIENT__ = null;\nvar _a21, _b21;\n(_b21 = (_a21 = target21).__VUE_DEVTOOLS_KIT_RPC_SERVER__) != null ? _b21 : _a21.__VUE_DEVTOOLS_KIT_RPC_SERVER__ = null;\nvar _a22, _b22;\n(_b22 = (_a22 = target21).__VUE_DEVTOOLS_KIT_VITE_RPC_CLIENT__) != null ? _b22 : _a22.__VUE_DEVTOOLS_KIT_VITE_RPC_CLIENT__ = null;\nvar _a23, _b23;\n(_b23 = (_a23 = target21).__VUE_DEVTOOLS_KIT_VITE_RPC_SERVER__) != null ? _b23 : _a23.__VUE_DEVTOOLS_KIT_VITE_RPC_SERVER__ = null;\nvar _a24, _b24;\n(_b24 = (_a24 = target21).__VUE_DEVTOOLS_KIT_BROADCAST_RPC_SERVER__) != null ? _b24 : _a24.__VUE_DEVTOOLS_KIT_BROADCAST_RPC_SERVER__ = null;\nfunction setRpcClientToGlobal(rpc) {\n target21.__VUE_DEVTOOLS_KIT_RPC_CLIENT__ = rpc;\n}\nfunction setRpcServerToGlobal(rpc) {\n target21.__VUE_DEVTOOLS_KIT_RPC_SERVER__ = rpc;\n}\nfunction getRpcClient() {\n return target21.__VUE_DEVTOOLS_KIT_RPC_CLIENT__;\n}\nfunction getRpcServer() {\n return target21.__VUE_DEVTOOLS_KIT_RPC_SERVER__;\n}\nfunction setViteRpcClientToGlobal(rpc) {\n target21.__VUE_DEVTOOLS_KIT_VITE_RPC_CLIENT__ = rpc;\n}\nfunction setViteRpcServerToGlobal(rpc) {\n target21.__VUE_DEVTOOLS_KIT_VITE_RPC_SERVER__ = rpc;\n}\nfunction getViteRpcClient() {\n return target21.__VUE_DEVTOOLS_KIT_VITE_RPC_CLIENT__;\n}\nfunction getViteRpcServer() {\n return target21.__VUE_DEVTOOLS_KIT_VITE_RPC_SERVER__;\n}\nfunction getChannel(preset, host = \"client\") {\n const channel = {\n iframe: {\n client: createIframeClientChannel,\n server: createIframeServerChannel\n }[host],\n electron: {\n client: createElectronClientChannel,\n proxy: createElectronProxyChannel,\n server: createElectronServerChannel\n }[host],\n vite: {\n client: createViteClientChannel,\n server: createViteServerChannel\n }[host],\n broadcast: {\n client: createBroadcastChannel,\n server: createBroadcastChannel\n }[host],\n extension: {\n client: createExtensionClientChannel,\n proxy: createExtensionProxyChannel,\n server: createExtensionServerChannel\n }[host]\n }[preset];\n return channel();\n}\nfunction createRpcClient(functions, options = {}) {\n const { channel: _channel, options: _options, preset } = options;\n const channel = preset ? getChannel(preset) : _channel;\n const rpc = createBirpc(functions, {\n ..._options,\n ...channel,\n timeout: -1\n });\n if (preset === \"vite\") {\n setViteRpcClientToGlobal(rpc);\n return;\n }\n setRpcClientToGlobal(rpc);\n return rpc;\n}\nfunction createRpcServer(functions, options = {}) {\n const { channel: _channel, options: _options, preset } = options;\n const channel = preset ? getChannel(preset, \"server\") : _channel;\n const rpcServer = getRpcServer();\n if (!rpcServer) {\n const group = createBirpcGroup(functions, [channel], {\n ..._options,\n timeout: -1\n });\n if (preset === \"vite\") {\n setViteRpcServerToGlobal(group);\n return;\n }\n setRpcServerToGlobal(group);\n } else {\n rpcServer.updateChannels((channels) => {\n channels.push(channel);\n });\n }\n}\nfunction createRpcProxy(options = {}) {\n const { channel: _channel, options: _options, preset } = options;\n const channel = preset ? getChannel(preset, \"proxy\") : _channel;\n return createBirpc({}, {\n ..._options,\n ...channel,\n timeout: -1\n });\n}\n\n// src/shared/index.ts\ninit_esm_shims();\n\n// src/shared/env.ts\ninit_esm_shims();\n\n// src/shared/time.ts\ninit_esm_shims();\n\n// src/shared/util.ts\ninit_esm_shims();\n\n// src/core/component/state/replacer.ts\ninit_esm_shims();\n\n// src/core/component/state/custom.ts\ninit_esm_shims();\nfunction getFunctionDetails(func) {\n let string = \"\";\n let matches = null;\n try {\n string = Function.prototype.toString.call(func);\n matches = String.prototype.match.call(string, /\\([\\s\\S]*?\\)/);\n } catch (e) {\n }\n const match = matches && matches[0];\n const args = typeof match === \"string\" ? match : \"(?)\";\n const name = typeof func.name === \"string\" ? func.name : \"\";\n return {\n _custom: {\n type: \"function\",\n displayText: `function ${escape(name)}${args}`,\n tooltipText: string.trim() ? `
${string}
` : null\n }\n };\n}\nfunction getBigIntDetails(val) {\n const stringifiedBigInt = BigInt.prototype.toString.call(val);\n return {\n _custom: {\n type: \"bigint\",\n displayText: `BigInt(${stringifiedBigInt})`,\n value: stringifiedBigInt\n }\n };\n}\nfunction getDateDetails(val) {\n const date = new Date(val.getTime());\n date.setMinutes(date.getMinutes() - date.getTimezoneOffset());\n return {\n _custom: {\n type: \"date\",\n displayText: Date.prototype.toString.call(val),\n value: date.toISOString().slice(0, -1)\n }\n };\n}\nfunction getMapDetails(val) {\n const list = Object.fromEntries(val);\n return {\n _custom: {\n type: \"map\",\n displayText: \"Map\",\n value: list,\n readOnly: true,\n fields: {\n abstract: true\n }\n }\n };\n}\nfunction getSetDetails(val) {\n const list = Array.from(val);\n return {\n _custom: {\n type: \"set\",\n displayText: `Set[${list.length}]`,\n value: list,\n readOnly: true\n }\n };\n}\nfunction getCaughtGetters(store) {\n const getters = {};\n const origGetters = store.getters || {};\n const keys = Object.keys(origGetters);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n Object.defineProperty(getters, key, {\n enumerable: true,\n get: () => {\n try {\n return origGetters[key];\n } catch (e) {\n return e;\n }\n }\n });\n }\n return getters;\n}\nfunction reduceStateList(list) {\n if (!list.length)\n return void 0;\n return list.reduce((map, item) => {\n const key = item.type || \"data\";\n const obj = map[key] = map[key] || {};\n obj[item.key] = item.value;\n return map;\n }, {});\n}\nfunction namedNodeMapToObject(map) {\n const result = {};\n const l = map.length;\n for (let i = 0; i < l; i++) {\n const node = map.item(i);\n result[node.name] = node.value;\n }\n return result;\n}\nfunction getStoreDetails(store) {\n return {\n _custom: {\n type: \"store\",\n displayText: \"Store\",\n value: {\n state: store.state,\n getters: getCaughtGetters(store)\n },\n fields: {\n abstract: true\n }\n }\n };\n}\nfunction getRouterDetails(router) {\n return {\n _custom: {\n type: \"router\",\n displayText: \"VueRouter\",\n value: {\n options: router.options,\n currentRoute: router.currentRoute\n },\n fields: {\n abstract: true\n }\n }\n };\n}\nfunction getInstanceDetails(instance) {\n if (instance._)\n instance = instance._;\n const state = processInstanceState(instance);\n return {\n _custom: {\n type: \"component\",\n id: instance.__VUE_DEVTOOLS_NEXT_UID__,\n displayText: getInstanceName(instance),\n tooltipText: \"Component instance\",\n value: reduceStateList(state),\n fields: {\n abstract: true\n }\n }\n };\n}\nfunction getComponentDefinitionDetails(definition) {\n let display = getComponentName(definition);\n if (display) {\n if (definition.name && definition.__file)\n display += ` (${definition.__file})`;\n } else {\n display = \"Unknown Component\";\n }\n return {\n _custom: {\n type: \"component-definition\",\n displayText: display,\n tooltipText: \"Component definition\",\n ...definition.__file ? {\n file: definition.__file\n } : {}\n }\n };\n}\nfunction getHTMLElementDetails(value) {\n try {\n return {\n _custom: {\n type: \"HTMLElement\",\n displayText: `<${value.tagName.toLowerCase()}>`,\n value: namedNodeMapToObject(value.attributes)\n }\n };\n } catch (e) {\n return {\n _custom: {\n type: \"HTMLElement\",\n displayText: `${String(value)}`\n }\n };\n }\n}\nfunction tryGetRefValue(ref) {\n if (ensurePropertyExists(ref, \"_value\", true)) {\n return ref._value;\n }\n if (ensurePropertyExists(ref, \"value\", true)) {\n return ref.value;\n }\n}\nfunction getObjectDetails(object) {\n var _a25, _b25, _c, _d;\n const info = getSetupStateType(object);\n const isState = info.ref || info.computed || info.reactive;\n if (isState) {\n const stateTypeName = info.computed ? \"Computed\" : info.ref ? \"Ref\" : info.reactive ? \"Reactive\" : null;\n const value = toRaw2(info.reactive ? object : tryGetRefValue(object));\n const raw = ensurePropertyExists(object, \"effect\") ? ((_b25 = (_a25 = object.effect) == null ? void 0 : _a25.raw) == null ? void 0 : _b25.toString()) || ((_d = (_c = object.effect) == null ? void 0 : _c.fn) == null ? void 0 : _d.toString()) : null;\n return {\n _custom: {\n type: stateTypeName == null ? void 0 : stateTypeName.toLowerCase(),\n stateTypeName,\n value,\n ...raw ? { tooltipText: `${raw}` } : {}\n }\n };\n }\n if (ensurePropertyExists(object, \"__asyncLoader\") && typeof object.__asyncLoader === \"function\") {\n return {\n _custom: {\n type: \"component-definition\",\n display: \"Async component definition\"\n }\n };\n }\n}\n\n// src/core/component/state/replacer.ts\nfunction stringifyReplacer(key, _value, depth, seenInstance) {\n var _a25;\n if (key === \"compilerOptions\")\n return;\n const val = this[key];\n const type = typeof val;\n if (Array.isArray(val)) {\n const l = val.length;\n if (l > MAX_ARRAY_SIZE) {\n return {\n _isArray: true,\n length: l,\n items: val.slice(0, MAX_ARRAY_SIZE)\n };\n }\n return val;\n } else if (typeof val === \"string\") {\n if (val.length > MAX_STRING_SIZE)\n return `${val.substring(0, MAX_STRING_SIZE)}... (${val.length} total length)`;\n else\n return val;\n } else if (type === \"undefined\") {\n return UNDEFINED;\n } else if (val === Number.POSITIVE_INFINITY) {\n return INFINITY;\n } else if (val === Number.NEGATIVE_INFINITY) {\n return NEGATIVE_INFINITY;\n } else if (typeof val === \"function\") {\n return getFunctionDetails(val);\n } else if (type === \"symbol\") {\n return `[native Symbol ${Symbol.prototype.toString.call(val)}]`;\n } else if (typeof val === \"bigint\") {\n return getBigIntDetails(val);\n } else if (val !== null && typeof val === \"object\") {\n const proto = Object.prototype.toString.call(val);\n if (proto === \"[object Map]\") {\n return getMapDetails(val);\n } else if (proto === \"[object Set]\") {\n return getSetDetails(val);\n } else if (proto === \"[object RegExp]\") {\n return `[native RegExp ${RegExp.prototype.toString.call(val)}]`;\n } else if (proto === \"[object Date]\") {\n return getDateDetails(val);\n } else if (proto === \"[object Error]\") {\n return `[native Error ${val.message}<>${val.stack}]`;\n } else if (ensurePropertyExists(val, \"state\", true) && ensurePropertyExists(val, \"_vm\", true)) {\n return getStoreDetails(val);\n } else if (val.constructor && val.constructor.name === \"VueRouter\") {\n return getRouterDetails(val);\n } else if (isVueInstance(val)) {\n const componentVal = getInstanceDetails(val);\n const parentInstanceDepth = seenInstance == null ? void 0 : seenInstance.get(val);\n if (parentInstanceDepth && parentInstanceDepth < depth) {\n return `[[CircularRef]] <${componentVal._custom.displayText}>`;\n }\n seenInstance == null ? void 0 : seenInstance.set(val, depth);\n return componentVal;\n } else if (ensurePropertyExists(val, \"render\", true) && typeof val.render === \"function\") {\n return getComponentDefinitionDetails(val);\n } else if (val.constructor && val.constructor.name === \"VNode\") {\n return `[native VNode <${val.tag}>]`;\n } else if (typeof HTMLElement !== \"undefined\" && val instanceof HTMLElement) {\n return getHTMLElementDetails(val);\n } else if (((_a25 = val.constructor) == null ? void 0 : _a25.name) === \"Store\" && \"_wrappedGetters\" in val) {\n return \"[object Store]\";\n } else if (ensurePropertyExists(val, \"currentRoute\", true)) {\n return \"[object Router]\";\n }\n const customDetails = getObjectDetails(val);\n if (customDetails != null)\n return customDetails;\n } else if (Number.isNaN(val)) {\n return NAN;\n }\n return sanitize(val);\n}\n\n// src/shared/transfer.ts\ninit_esm_shims();\nvar MAX_SERIALIZED_SIZE = 2 * 1024 * 1024;\nfunction isObject(_data, proto) {\n return proto === \"[object Object]\";\n}\nfunction isArray3(_data, proto) {\n return proto === \"[object Array]\";\n}\nfunction isVueReactiveLinkNode(node) {\n var _a25;\n const constructorName = (_a25 = node == null ? void 0 : node.constructor) == null ? void 0 : _a25.name;\n return constructorName === \"Dep\" && \"activeLink\" in node || constructorName === \"Link\" && \"dep\" in node;\n}\nfunction encode(data, replacer, list, seen, depth = 0, seenVueInstance = /* @__PURE__ */ new Map()) {\n let stored;\n let key;\n let value;\n let i;\n let l;\n const seenIndex = seen.get(data);\n if (seenIndex != null)\n return seenIndex;\n const index = list.length;\n const proto = Object.prototype.toString.call(data);\n if (isObject(data, proto)) {\n if (isVueReactiveLinkNode(data)) {\n return index;\n }\n stored = {};\n seen.set(data, index);\n list.push(stored);\n const keys = Object.keys(data);\n for (i = 0, l = keys.length; i < l; i++) {\n key = keys[i];\n if (key === \"compilerOptions\")\n return index;\n value = data[key];\n const isVm = value != null && isObject(value, Object.prototype.toString.call(data)) && isVueInstance(value);\n try {\n if (replacer) {\n value = replacer.call(data, key, value, depth, seenVueInstance);\n }\n } catch (e) {\n value = e;\n }\n stored[key] = encode(value, replacer, list, seen, depth + 1, seenVueInstance);\n if (isVm) {\n seenVueInstance.delete(value);\n }\n }\n } else if (isArray3(data, proto)) {\n stored = [];\n seen.set(data, index);\n list.push(stored);\n for (i = 0, l = data.length; i < l; i++) {\n try {\n value = data[i];\n if (replacer)\n value = replacer.call(data, i, value, depth, seenVueInstance);\n } catch (e) {\n value = e;\n }\n stored[i] = encode(value, replacer, list, seen, depth + 1, seenVueInstance);\n }\n } else {\n list.push(data);\n }\n return index;\n}\nfunction decode(list, reviver2 = null) {\n let i = list.length;\n let j, k, data, key, value, proto;\n while (i--) {\n data = list[i];\n proto = Object.prototype.toString.call(data);\n if (proto === \"[object Object]\") {\n const keys = Object.keys(data);\n for (j = 0, k = keys.length; j < k; j++) {\n key = keys[j];\n value = list[data[key]];\n if (reviver2)\n value = reviver2.call(data, key, value);\n data[key] = value;\n }\n } else if (proto === \"[object Array]\") {\n for (j = 0, k = data.length; j < k; j++) {\n value = list[data[j]];\n if (reviver2)\n value = reviver2.call(data, j, value);\n data[j] = value;\n }\n }\n }\n}\nfunction stringifyCircularAutoChunks(data, replacer = null, space = null) {\n let result;\n try {\n result = arguments.length === 1 ? JSON.stringify(data) : JSON.stringify(data, (k, v) => {\n var _a25;\n return (_a25 = replacer == null ? void 0 : replacer(k, v)) == null ? void 0 : _a25.call(this);\n }, space);\n } catch (e) {\n result = stringifyStrictCircularAutoChunks(data, replacer, space);\n }\n if (result.length > MAX_SERIALIZED_SIZE) {\n const chunkCount = Math.ceil(result.length / MAX_SERIALIZED_SIZE);\n const chunks = [];\n for (let i = 0; i < chunkCount; i++)\n chunks.push(result.slice(i * MAX_SERIALIZED_SIZE, (i + 1) * MAX_SERIALIZED_SIZE));\n return chunks;\n }\n return result;\n}\nfunction stringifyStrictCircularAutoChunks(data, replacer = null, space = null) {\n const list = [];\n encode(data, replacer, list, /* @__PURE__ */ new Map());\n return space ? ` ${JSON.stringify(list, null, space)}` : ` ${JSON.stringify(list)}`;\n}\nfunction parseCircularAutoChunks(data, reviver2 = null) {\n if (Array.isArray(data))\n data = data.join(\"\");\n const hasCircular = /^\\s/.test(data);\n if (!hasCircular) {\n return arguments.length === 1 ? JSON.parse(data) : JSON.parse(data, reviver2);\n } else {\n const list = JSON.parse(data);\n decode(list, reviver2);\n return list[0];\n }\n}\n\n// src/shared/util.ts\nfunction stringify2(data) {\n return stringifyCircularAutoChunks(data, stringifyReplacer);\n}\nfunction parse2(data, revive2 = false) {\n if (data == void 0)\n return {};\n return revive2 ? parseCircularAutoChunks(data, reviver) : parseCircularAutoChunks(data);\n}\n\n// src/index.ts\nvar devtools = {\n hook,\n init: () => {\n initDevTools();\n },\n get ctx() {\n return devtoolsContext;\n },\n get api() {\n return devtoolsContext.api;\n }\n};\nexport {\n DevToolsContextHookKeys,\n DevToolsMessagingHookKeys,\n DevToolsV6PluginAPIHookKeys,\n INFINITY,\n NAN,\n NEGATIVE_INFINITY,\n ROUTER_INFO_KEY,\n ROUTER_KEY,\n UNDEFINED,\n activeAppRecord,\n addCustomCommand,\n addCustomTab,\n addDevToolsAppRecord,\n addDevToolsPluginToBuffer,\n addInspector,\n callConnectedUpdatedHook,\n callDevToolsPluginSetupFn,\n callInspectorUpdatedHook,\n callStateUpdatedHook,\n createComponentsDevToolsPlugin,\n createDevToolsApi,\n createDevToolsCtxHooks,\n createRpcClient,\n createRpcProxy,\n createRpcServer,\n devtools,\n devtoolsAppRecords,\n devtoolsContext,\n devtoolsInspector,\n devtoolsPluginBuffer,\n devtoolsRouter,\n devtoolsRouterInfo,\n devtoolsState,\n escape,\n formatInspectorStateValue,\n getActiveInspectors,\n getDevToolsEnv,\n getExtensionClientContext,\n getInspector,\n getInspectorActions,\n getInspectorInfo,\n getInspectorNodeActions,\n getInspectorStateValueType,\n getRaw,\n getRpcClient,\n getRpcServer,\n getViteRpcClient,\n getViteRpcServer,\n initDevTools,\n isPlainObject,\n onDevToolsClientConnected,\n onDevToolsConnected,\n parse2 as parse,\n registerDevToolsPlugin,\n removeCustomCommand,\n removeDevToolsAppRecord,\n removeRegisteredPluginApp,\n resetDevToolsState,\n setActiveAppRecord,\n setActiveAppRecordId,\n setDevToolsEnv,\n setElectronClientContext,\n setElectronProxyContext,\n setElectronServerContext,\n setExtensionClientContext,\n setIframeServerContext,\n setOpenInEditorBaseUrl,\n setRpcServerToGlobal,\n setViteClientContext,\n setViteRpcClientToGlobal,\n setViteRpcServerToGlobal,\n setViteServerContext,\n setupDevToolsPlugin,\n stringify2 as stringify,\n toEdit,\n toSubmit,\n toggleClientConnected,\n toggleComponentInspectorEnabled,\n toggleHighPerfMode,\n updateDevToolsClientDetected,\n updateDevToolsState,\n updateTimelineLayersState\n};\n"], - "mappings": "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ACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAU;AAAA,QACV,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAU;AAAA,QACV,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAU;AAAA,QACV,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAU;AAAA,QACV,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAU;AAAA;AAAA;AAAA,QAGV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,MAAgB;AAAA,QAChB,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,MAAgB;AAAA,QAChB,MAAgB;AAAA,QAChB,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,QAA4B;AAAA,QAC5B,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA;AAAA,QAGV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA;AAAA;AAAA,QAGV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,MAAgB;AAAA,QAChB,MAAgB;AAAA;AAAA,QAEhB,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA;AAAA,QAGV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA;AAAA,QAGV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA;AAAA,QAGV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA;AAAA,QAGV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA;AAAA,QAGV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA;AAAA,QAEV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAQ;AAAA,QACR,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAQ;AAAA,QACR,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAU;AAAA,QACV,KAAQ;AAAA,QACR,KAAQ;AAAA,QACR,KAAU;AAAA,QACV,KAAU;AAAA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", - "names": ["hooks", "hooks", "hook", "hook", "hooks", "clearTimeout", "setTimeout", "__create", "__defProp", "__getOwnPropDesc", "__getOwnPropNames", "__getProtoOf", "__hasOwnProp", "__esm", "__commonJS", "__copyProps", "__toESM", "init_esm_shims", "init_esm_shims", "init_esm_shims", "_a", "init_esm_shims", "init_esm_shims", "init_esm_shims", "_a2", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "__toESM", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "init_esm_shims", "_a22", "init_esm_shims", "init_esm_shims"] -} diff --git a/www/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js b/www/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js deleted file mode 100644 index 9a0fa5e..0000000 --- a/www/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +++ /dev/null @@ -1,583 +0,0 @@ -import { - DefaultMagicKeysAliasMap, - StorageSerializers, - TransitionPresets, - assert, - breakpointsAntDesign, - breakpointsBootstrapV5, - breakpointsElement, - breakpointsMasterCss, - breakpointsPrimeFlex, - breakpointsQuasar, - breakpointsSematic, - breakpointsTailwind, - breakpointsVuetify, - breakpointsVuetifyV2, - breakpointsVuetifyV3, - bypassFilter, - camelize, - clamp, - cloneFnJSON, - computedAsync, - computedEager, - computedInject, - computedWithControl, - containsProp, - controlledRef, - createEventHook, - createFetch, - createFilterWrapper, - createGlobalState, - createInjectionState, - createRef, - createReusableTemplate, - createSharedComposable, - createSingletonPromise, - createTemplatePromise, - createUnrefFn, - customStorageEventName, - debounceFilter, - defaultDocument, - defaultLocation, - defaultNavigator, - defaultWindow, - executeTransition, - extendRef, - formatDate, - formatTimeAgo, - get, - getLifeCycleTarget, - getSSRHandler, - hasOwn, - hyphenate, - identity, - increaseWithUnit, - injectLocal, - invoke, - isClient, - isDef, - isDefined, - isIOS, - isObject, - isWorker, - makeDestructurable, - mapGamepadToXbox360Controller, - noop, - normalizeDate, - notNullish, - now, - objectEntries, - objectOmit, - objectPick, - onClickOutside, - onElementRemoval, - onKeyDown, - onKeyPressed, - onKeyStroke, - onKeyUp, - onLongPress, - onStartTyping, - pausableFilter, - promiseTimeout, - provideLocal, - provideSSRWidth, - pxValue, - rand, - reactify, - reactifyObject, - reactiveComputed, - reactiveOmit, - reactivePick, - refAutoReset, - refDebounced, - refDefault, - refThrottled, - refWithControl, - resolveRef, - resolveUnref, - set, - setSSRHandler, - syncRef, - syncRefs, - templateRef, - throttleFilter, - timestamp, - toArray, - toReactive, - toRef, - toRefs, - toValue, - tryOnBeforeMount, - tryOnBeforeUnmount, - tryOnMounted, - tryOnScopeDispose, - tryOnUnmounted, - unrefElement, - until, - useActiveElement, - useAnimate, - useArrayDifference, - useArrayEvery, - useArrayFilter, - useArrayFind, - useArrayFindIndex, - useArrayFindLast, - useArrayIncludes, - useArrayJoin, - useArrayMap, - useArrayReduce, - useArraySome, - useArrayUnique, - useAsyncQueue, - useAsyncState, - useBase64, - useBattery, - useBluetooth, - useBreakpoints, - useBroadcastChannel, - useBrowserLocation, - useCached, - useClipboard, - useClipboardItems, - useCloned, - useColorMode, - useConfirmDialog, - useCountdown, - useCounter, - useCssVar, - useCurrentElement, - useCycleList, - useDark, - useDateFormat, - useDebounceFn, - useDebouncedRefHistory, - useDeviceMotion, - useDeviceOrientation, - useDevicePixelRatio, - useDevicesList, - useDisplayMedia, - useDocumentVisibility, - useDraggable, - useDropZone, - useElementBounding, - useElementByPoint, - useElementHover, - useElementSize, - useElementVisibility, - useEventBus, - useEventListener, - useEventSource, - useEyeDropper, - useFavicon, - useFetch, - useFileDialog, - useFileSystemAccess, - useFocus, - useFocusWithin, - useFps, - useFullscreen, - useGamepad, - useGeolocation, - useIdle, - useImage, - useInfiniteScroll, - useIntersectionObserver, - useInterval, - useIntervalFn, - useKeyModifier, - useLastChanged, - useLocalStorage, - useMagicKeys, - useManualRefHistory, - useMediaControls, - useMediaQuery, - useMemoize, - useMemory, - useMounted, - useMouse, - useMouseInElement, - useMousePressed, - useMutationObserver, - useNavigatorLanguage, - useNetwork, - useNow, - useObjectUrl, - useOffsetPagination, - useOnline, - usePageLeave, - useParallax, - useParentElement, - usePerformanceObserver, - usePermission, - usePointer, - usePointerLock, - usePointerSwipe, - usePreferredColorScheme, - usePreferredContrast, - usePreferredDark, - usePreferredLanguages, - usePreferredReducedMotion, - usePreferredReducedTransparency, - usePrevious, - useRafFn, - useRefHistory, - useResizeObserver, - useSSRWidth, - useScreenOrientation, - useScreenSafeArea, - useScriptTag, - useScroll, - useScrollLock, - useSessionStorage, - useShare, - useSorted, - useSpeechRecognition, - useSpeechSynthesis, - useStepper, - useStorage, - useStorageAsync, - useStyleTag, - useSupported, - useSwipe, - useTemplateRefsList, - useTextDirection, - useTextSelection, - useTextareaAutosize, - useThrottleFn, - useThrottledRefHistory, - useTimeAgo, - useTimeout, - useTimeoutFn, - useTimeoutPoll, - useTimestamp, - useTitle, - useToNumber, - useToString, - useToggle, - useTransition, - useUrlSearchParams, - useUserMedia, - useVModel, - useVModels, - useVibrate, - useVirtualList, - useWakeLock, - useWebNotification, - useWebSocket, - useWebWorker, - useWebWorkerFn, - useWindowFocus, - useWindowScroll, - useWindowSize, - watchArray, - watchAtMost, - watchDebounced, - watchDeep, - watchIgnorable, - watchImmediate, - watchOnce, - watchPausable, - watchThrottled, - watchTriggerable, - watchWithFilter, - whenever -} from "./chunk-2CLQ7TTZ.js"; -import "./chunk-LE5NDSFD.js"; -export { - DefaultMagicKeysAliasMap, - StorageSerializers, - TransitionPresets, - assert, - computedAsync as asyncComputed, - refAutoReset as autoResetRef, - breakpointsAntDesign, - breakpointsBootstrapV5, - breakpointsElement, - breakpointsMasterCss, - breakpointsPrimeFlex, - breakpointsQuasar, - breakpointsSematic, - breakpointsTailwind, - breakpointsVuetify, - breakpointsVuetifyV2, - breakpointsVuetifyV3, - bypassFilter, - camelize, - clamp, - cloneFnJSON, - computedAsync, - computedEager, - computedInject, - computedWithControl, - containsProp, - computedWithControl as controlledComputed, - controlledRef, - createEventHook, - createFetch, - createFilterWrapper, - createGlobalState, - createInjectionState, - reactify as createReactiveFn, - createRef, - createReusableTemplate, - createSharedComposable, - createSingletonPromise, - createTemplatePromise, - createUnrefFn, - customStorageEventName, - debounceFilter, - refDebounced as debouncedRef, - watchDebounced as debouncedWatch, - defaultDocument, - defaultLocation, - defaultNavigator, - defaultWindow, - computedEager as eagerComputed, - executeTransition, - extendRef, - formatDate, - formatTimeAgo, - get, - getLifeCycleTarget, - getSSRHandler, - hasOwn, - hyphenate, - identity, - watchIgnorable as ignorableWatch, - increaseWithUnit, - injectLocal, - invoke, - isClient, - isDef, - isDefined, - isIOS, - isObject, - isWorker, - makeDestructurable, - mapGamepadToXbox360Controller, - noop, - normalizeDate, - notNullish, - now, - objectEntries, - objectOmit, - objectPick, - onClickOutside, - onElementRemoval, - onKeyDown, - onKeyPressed, - onKeyStroke, - onKeyUp, - onLongPress, - onStartTyping, - pausableFilter, - watchPausable as pausableWatch, - promiseTimeout, - provideLocal, - provideSSRWidth, - pxValue, - rand, - reactify, - reactifyObject, - reactiveComputed, - reactiveOmit, - reactivePick, - refAutoReset, - refDebounced, - refDefault, - refThrottled, - refWithControl, - resolveRef, - resolveUnref, - set, - setSSRHandler, - syncRef, - syncRefs, - templateRef, - throttleFilter, - refThrottled as throttledRef, - watchThrottled as throttledWatch, - timestamp, - toArray, - toReactive, - toRef, - toRefs, - toValue, - tryOnBeforeMount, - tryOnBeforeUnmount, - tryOnMounted, - tryOnScopeDispose, - tryOnUnmounted, - unrefElement, - until, - useActiveElement, - useAnimate, - useArrayDifference, - useArrayEvery, - useArrayFilter, - useArrayFind, - useArrayFindIndex, - useArrayFindLast, - useArrayIncludes, - useArrayJoin, - useArrayMap, - useArrayReduce, - useArraySome, - useArrayUnique, - useAsyncQueue, - useAsyncState, - useBase64, - useBattery, - useBluetooth, - useBreakpoints, - useBroadcastChannel, - useBrowserLocation, - useCached, - useClipboard, - useClipboardItems, - useCloned, - useColorMode, - useConfirmDialog, - useCountdown, - useCounter, - useCssVar, - useCurrentElement, - useCycleList, - useDark, - useDateFormat, - refDebounced as useDebounce, - useDebounceFn, - useDebouncedRefHistory, - useDeviceMotion, - useDeviceOrientation, - useDevicePixelRatio, - useDevicesList, - useDisplayMedia, - useDocumentVisibility, - useDraggable, - useDropZone, - useElementBounding, - useElementByPoint, - useElementHover, - useElementSize, - useElementVisibility, - useEventBus, - useEventListener, - useEventSource, - useEyeDropper, - useFavicon, - useFetch, - useFileDialog, - useFileSystemAccess, - useFocus, - useFocusWithin, - useFps, - useFullscreen, - useGamepad, - useGeolocation, - useIdle, - useImage, - useInfiniteScroll, - useIntersectionObserver, - useInterval, - useIntervalFn, - useKeyModifier, - useLastChanged, - useLocalStorage, - useMagicKeys, - useManualRefHistory, - useMediaControls, - useMediaQuery, - useMemoize, - useMemory, - useMounted, - useMouse, - useMouseInElement, - useMousePressed, - useMutationObserver, - useNavigatorLanguage, - useNetwork, - useNow, - useObjectUrl, - useOffsetPagination, - useOnline, - usePageLeave, - useParallax, - useParentElement, - usePerformanceObserver, - usePermission, - usePointer, - usePointerLock, - usePointerSwipe, - usePreferredColorScheme, - usePreferredContrast, - usePreferredDark, - usePreferredLanguages, - usePreferredReducedMotion, - usePreferredReducedTransparency, - usePrevious, - useRafFn, - useRefHistory, - useResizeObserver, - useSSRWidth, - useScreenOrientation, - useScreenSafeArea, - useScriptTag, - useScroll, - useScrollLock, - useSessionStorage, - useShare, - useSorted, - useSpeechRecognition, - useSpeechSynthesis, - useStepper, - useStorage, - useStorageAsync, - useStyleTag, - useSupported, - useSwipe, - useTemplateRefsList, - useTextDirection, - useTextSelection, - useTextareaAutosize, - refThrottled as useThrottle, - useThrottleFn, - useThrottledRefHistory, - useTimeAgo, - useTimeout, - useTimeoutFn, - useTimeoutPoll, - useTimestamp, - useTitle, - useToNumber, - useToString, - useToggle, - useTransition, - useUrlSearchParams, - useUserMedia, - useVModel, - useVModels, - useVibrate, - useVirtualList, - useWakeLock, - useWebNotification, - useWebSocket, - useWebWorker, - useWebWorkerFn, - useWindowFocus, - useWindowScroll, - useWindowSize, - watchArray, - watchAtMost, - watchDebounced, - watchDeep, - watchIgnorable, - watchImmediate, - watchOnce, - watchPausable, - watchThrottled, - watchTriggerable, - watchWithFilter, - whenever -}; -//# sourceMappingURL=vitepress___@vueuse_core.js.map diff --git a/www/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map b/www/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map deleted file mode 100644 index 9865211..0000000 --- a/www/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": [], - "sourcesContent": [], - "mappings": "", - "names": [] -} diff --git a/www/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js b/www/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js deleted file mode 100644 index c5aff5c..0000000 --- a/www/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +++ /dev/null @@ -1,1165 +0,0 @@ -import { - notNullish, - toArray, - tryOnScopeDispose, - unrefElement -} from "./chunk-2CLQ7TTZ.js"; -import { - computed, - shallowRef, - toValue, - watch -} from "./chunk-LE5NDSFD.js"; - -// node_modules/tabbable/dist/index.esm.js -var candidateSelectors = ["input:not([inert])", "select:not([inert])", "textarea:not([inert])", "a[href]:not([inert])", "button:not([inert])", "[tabindex]:not(slot):not([inert])", "audio[controls]:not([inert])", "video[controls]:not([inert])", '[contenteditable]:not([contenteditable="false"]):not([inert])', "details>summary:first-of-type:not([inert])", "details:not([inert])"]; -var candidateSelector = candidateSelectors.join(","); -var NoElement = typeof Element === "undefined"; -var matches = NoElement ? function() { -} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; -var getRootNode = !NoElement && Element.prototype.getRootNode ? function(element) { - var _element$getRootNode; - return element === null || element === void 0 ? void 0 : (_element$getRootNode = element.getRootNode) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode.call(element); -} : function(element) { - return element === null || element === void 0 ? void 0 : element.ownerDocument; -}; -var _isInert = function isInert(node, lookUp) { - var _node$getAttribute; - if (lookUp === void 0) { - lookUp = true; - } - var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, "inert"); - var inert = inertAtt === "" || inertAtt === "true"; - var result = inert || lookUp && node && _isInert(node.parentNode); - return result; -}; -var isContentEditable = function isContentEditable2(node) { - var _node$getAttribute2; - var attValue = node === null || node === void 0 ? void 0 : (_node$getAttribute2 = node.getAttribute) === null || _node$getAttribute2 === void 0 ? void 0 : _node$getAttribute2.call(node, "contenteditable"); - return attValue === "" || attValue === "true"; -}; -var getCandidates = function getCandidates2(el, includeContainer, filter) { - if (_isInert(el)) { - return []; - } - var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector)); - if (includeContainer && matches.call(el, candidateSelector)) { - candidates.unshift(el); - } - candidates = candidates.filter(filter); - return candidates; -}; -var _getCandidatesIteratively = function getCandidatesIteratively(elements, includeContainer, options) { - var candidates = []; - var elementsToCheck = Array.from(elements); - while (elementsToCheck.length) { - var element = elementsToCheck.shift(); - if (_isInert(element, false)) { - continue; - } - if (element.tagName === "SLOT") { - var assigned = element.assignedElements(); - var content = assigned.length ? assigned : element.children; - var nestedCandidates = _getCandidatesIteratively(content, true, options); - if (options.flatten) { - candidates.push.apply(candidates, nestedCandidates); - } else { - candidates.push({ - scopeParent: element, - candidates: nestedCandidates - }); - } - } else { - var validCandidate = matches.call(element, candidateSelector); - if (validCandidate && options.filter(element) && (includeContainer || !elements.includes(element))) { - candidates.push(element); - } - var shadowRoot = element.shadowRoot || // check for an undisclosed shadow - typeof options.getShadowRoot === "function" && options.getShadowRoot(element); - var validShadowRoot = !_isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element)); - if (shadowRoot && validShadowRoot) { - var _nestedCandidates = _getCandidatesIteratively(shadowRoot === true ? element.children : shadowRoot.children, true, options); - if (options.flatten) { - candidates.push.apply(candidates, _nestedCandidates); - } else { - candidates.push({ - scopeParent: element, - candidates: _nestedCandidates - }); - } - } else { - elementsToCheck.unshift.apply(elementsToCheck, element.children); - } - } - } - return candidates; -}; -var hasTabIndex = function hasTabIndex2(node) { - return !isNaN(parseInt(node.getAttribute("tabindex"), 10)); -}; -var getTabIndex = function getTabIndex2(node) { - if (!node) { - throw new Error("No node provided"); - } - if (node.tabIndex < 0) { - if ((/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && !hasTabIndex(node)) { - return 0; - } - } - return node.tabIndex; -}; -var getSortOrderTabIndex = function getSortOrderTabIndex2(node, isScope) { - var tabIndex = getTabIndex(node); - if (tabIndex < 0 && isScope && !hasTabIndex(node)) { - return 0; - } - return tabIndex; -}; -var sortOrderedTabbables = function sortOrderedTabbables2(a, b) { - return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex; -}; -var isInput = function isInput2(node) { - return node.tagName === "INPUT"; -}; -var isHiddenInput = function isHiddenInput2(node) { - return isInput(node) && node.type === "hidden"; -}; -var isDetailsWithSummary = function isDetailsWithSummary2(node) { - var r = node.tagName === "DETAILS" && Array.prototype.slice.apply(node.children).some(function(child) { - return child.tagName === "SUMMARY"; - }); - return r; -}; -var getCheckedRadio = function getCheckedRadio2(nodes, form) { - for (var i = 0; i < nodes.length; i++) { - if (nodes[i].checked && nodes[i].form === form) { - return nodes[i]; - } - } -}; -var isTabbableRadio = function isTabbableRadio2(node) { - if (!node.name) { - return true; - } - var radioScope = node.form || getRootNode(node); - var queryRadios = function queryRadios2(name) { - return radioScope.querySelectorAll('input[type="radio"][name="' + name + '"]'); - }; - var radioSet; - if (typeof window !== "undefined" && typeof window.CSS !== "undefined" && typeof window.CSS.escape === "function") { - radioSet = queryRadios(window.CSS.escape(node.name)); - } else { - try { - radioSet = queryRadios(node.name); - } catch (err) { - console.error("Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s", err.message); - return false; - } - } - var checked = getCheckedRadio(radioSet, node.form); - return !checked || checked === node; -}; -var isRadio = function isRadio2(node) { - return isInput(node) && node.type === "radio"; -}; -var isNonTabbableRadio = function isNonTabbableRadio2(node) { - return isRadio(node) && !isTabbableRadio(node); -}; -var isNodeAttached = function isNodeAttached2(node) { - var _nodeRoot; - var nodeRoot = node && getRootNode(node); - var nodeRootHost = (_nodeRoot = nodeRoot) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot.host; - var attached = false; - if (nodeRoot && nodeRoot !== node) { - var _nodeRootHost, _nodeRootHost$ownerDo, _node$ownerDocument; - attached = !!((_nodeRootHost = nodeRootHost) !== null && _nodeRootHost !== void 0 && (_nodeRootHost$ownerDo = _nodeRootHost.ownerDocument) !== null && _nodeRootHost$ownerDo !== void 0 && _nodeRootHost$ownerDo.contains(nodeRootHost) || node !== null && node !== void 0 && (_node$ownerDocument = node.ownerDocument) !== null && _node$ownerDocument !== void 0 && _node$ownerDocument.contains(node)); - while (!attached && nodeRootHost) { - var _nodeRoot2, _nodeRootHost2, _nodeRootHost2$ownerD; - nodeRoot = getRootNode(nodeRootHost); - nodeRootHost = (_nodeRoot2 = nodeRoot) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2.host; - attached = !!((_nodeRootHost2 = nodeRootHost) !== null && _nodeRootHost2 !== void 0 && (_nodeRootHost2$ownerD = _nodeRootHost2.ownerDocument) !== null && _nodeRootHost2$ownerD !== void 0 && _nodeRootHost2$ownerD.contains(nodeRootHost)); - } - } - return attached; -}; -var isZeroArea = function isZeroArea2(node) { - var _node$getBoundingClie = node.getBoundingClientRect(), width = _node$getBoundingClie.width, height = _node$getBoundingClie.height; - return width === 0 && height === 0; -}; -var isHidden = function isHidden2(node, _ref) { - var displayCheck = _ref.displayCheck, getShadowRoot = _ref.getShadowRoot; - if (displayCheck === "full-native") { - if ("checkVisibility" in node) { - var visible = node.checkVisibility({ - // Checking opacity might be desirable for some use cases, but natively, - // opacity zero elements _are_ focusable and tabbable. - checkOpacity: false, - opacityProperty: false, - contentVisibilityAuto: true, - visibilityProperty: true, - // This is an alias for `visibilityProperty`. Contemporary browsers - // support both. However, this alias has wider browser support (Chrome - // >= 105 and Firefox >= 106, vs. Chrome >= 121 and Firefox >= 122), so - // we include it anyway. - checkVisibilityCSS: true - }); - return !visible; - } - } - if (getComputedStyle(node).visibility === "hidden") { - return true; - } - var isDirectSummary = matches.call(node, "details>summary:first-of-type"); - var nodeUnderDetails = isDirectSummary ? node.parentElement : node; - if (matches.call(nodeUnderDetails, "details:not([open]) *")) { - return true; - } - if (!displayCheck || displayCheck === "full" || // full-native can run this branch when it falls through in case - // Element#checkVisibility is unsupported - displayCheck === "full-native" || displayCheck === "legacy-full") { - if (typeof getShadowRoot === "function") { - var originalNode = node; - while (node) { - var parentElement = node.parentElement; - var rootNode = getRootNode(node); - if (parentElement && !parentElement.shadowRoot && getShadowRoot(parentElement) === true) { - return isZeroArea(node); - } else if (node.assignedSlot) { - node = node.assignedSlot; - } else if (!parentElement && rootNode !== node.ownerDocument) { - node = rootNode.host; - } else { - node = parentElement; - } - } - node = originalNode; - } - if (isNodeAttached(node)) { - return !node.getClientRects().length; - } - if (displayCheck !== "legacy-full") { - return true; - } - } else if (displayCheck === "non-zero-area") { - return isZeroArea(node); - } - return false; -}; -var isDisabledFromFieldset = function isDisabledFromFieldset2(node) { - if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(node.tagName)) { - var parentNode = node.parentElement; - while (parentNode) { - if (parentNode.tagName === "FIELDSET" && parentNode.disabled) { - for (var i = 0; i < parentNode.children.length; i++) { - var child = parentNode.children.item(i); - if (child.tagName === "LEGEND") { - return matches.call(parentNode, "fieldset[disabled] *") ? true : !child.contains(node); - } - } - return true; - } - parentNode = parentNode.parentElement; - } - } - return false; -}; -var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable2(options, node) { - if (node.disabled || // we must do an inert look up to filter out any elements inside an inert ancestor - // because we're limited in the type of selectors we can use in JSDom (see related - // note related to `candidateSelectors`) - _isInert(node) || isHiddenInput(node) || isHidden(node, options) || // For a details element with a summary, the summary element gets the focus - isDetailsWithSummary(node) || isDisabledFromFieldset(node)) { - return false; - } - return true; -}; -var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable2(options, node) { - if (isNonTabbableRadio(node) || getTabIndex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) { - return false; - } - return true; -}; -var isShadowRootTabbable = function isShadowRootTabbable2(shadowHostNode) { - var tabIndex = parseInt(shadowHostNode.getAttribute("tabindex"), 10); - if (isNaN(tabIndex) || tabIndex >= 0) { - return true; - } - return false; -}; -var _sortByOrder = function sortByOrder(candidates) { - var regularTabbables = []; - var orderedTabbables = []; - candidates.forEach(function(item, i) { - var isScope = !!item.scopeParent; - var element = isScope ? item.scopeParent : item; - var candidateTabindex = getSortOrderTabIndex(element, isScope); - var elements = isScope ? _sortByOrder(item.candidates) : element; - if (candidateTabindex === 0) { - isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element); - } else { - orderedTabbables.push({ - documentOrder: i, - tabIndex: candidateTabindex, - item, - isScope, - content: elements - }); - } - }); - return orderedTabbables.sort(sortOrderedTabbables).reduce(function(acc, sortable) { - sortable.isScope ? acc.push.apply(acc, sortable.content) : acc.push(sortable.content); - return acc; - }, []).concat(regularTabbables); -}; -var tabbable = function tabbable2(container, options) { - options = options || {}; - var candidates; - if (options.getShadowRoot) { - candidates = _getCandidatesIteratively([container], options.includeContainer, { - filter: isNodeMatchingSelectorTabbable.bind(null, options), - flatten: false, - getShadowRoot: options.getShadowRoot, - shadowRootFilter: isShadowRootTabbable - }); - } else { - candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options)); - } - return _sortByOrder(candidates); -}; -var focusable = function focusable2(container, options) { - options = options || {}; - var candidates; - if (options.getShadowRoot) { - candidates = _getCandidatesIteratively([container], options.includeContainer, { - filter: isNodeMatchingSelectorFocusable.bind(null, options), - flatten: true, - getShadowRoot: options.getShadowRoot - }); - } else { - candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options)); - } - return candidates; -}; -var isTabbable = function isTabbable2(node, options) { - options = options || {}; - if (!node) { - throw new Error("No node provided"); - } - if (matches.call(node, candidateSelector) === false) { - return false; - } - return isNodeMatchingSelectorTabbable(options, node); -}; -var focusableCandidateSelector = candidateSelectors.concat("iframe").join(","); -var isFocusable = function isFocusable2(node, options) { - options = options || {}; - if (!node) { - throw new Error("No node provided"); - } - if (matches.call(node, focusableCandidateSelector) === false) { - return false; - } - return isNodeMatchingSelectorFocusable(options, node); -}; - -// node_modules/focus-trap/dist/focus-trap.esm.js -function _arrayLikeToArray(r, a) { - (null == a || a > r.length) && (a = r.length); - for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; - return n; -} -function _arrayWithoutHoles(r) { - if (Array.isArray(r)) return _arrayLikeToArray(r); -} -function _defineProperty(e, r, t) { - return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { - value: t, - enumerable: true, - configurable: true, - writable: true - }) : e[r] = t, e; -} -function _iterableToArray(r) { - if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); -} -function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); -} -function ownKeys(e, r) { - var t = Object.keys(e); - if (Object.getOwnPropertySymbols) { - var o = Object.getOwnPropertySymbols(e); - r && (o = o.filter(function(r2) { - return Object.getOwnPropertyDescriptor(e, r2).enumerable; - })), t.push.apply(t, o); - } - return t; -} -function _objectSpread2(e) { - for (var r = 1; r < arguments.length; r++) { - var t = null != arguments[r] ? arguments[r] : {}; - r % 2 ? ownKeys(Object(t), true).forEach(function(r2) { - _defineProperty(e, r2, t[r2]); - }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r2) { - Object.defineProperty(e, r2, Object.getOwnPropertyDescriptor(t, r2)); - }); - } - return e; -} -function _toConsumableArray(r) { - return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); -} -function _toPrimitive(t, r) { - if ("object" != typeof t || !t) return t; - var e = t[Symbol.toPrimitive]; - if (void 0 !== e) { - var i = e.call(t, r); - if ("object" != typeof i) return i; - throw new TypeError("@@toPrimitive must return a primitive value."); - } - return ("string" === r ? String : Number)(t); -} -function _toPropertyKey(t) { - var i = _toPrimitive(t, "string"); - return "symbol" == typeof i ? i : i + ""; -} -function _unsupportedIterableToArray(r, a) { - if (r) { - if ("string" == typeof r) return _arrayLikeToArray(r, a); - var t = {}.toString.call(r).slice(8, -1); - return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; - } -} -var activeFocusTraps = { - activateTrap: function activateTrap(trapStack, trap) { - if (trapStack.length > 0) { - var activeTrap = trapStack[trapStack.length - 1]; - if (activeTrap !== trap) { - activeTrap._setPausedState(true); - } - } - var trapIndex = trapStack.indexOf(trap); - if (trapIndex === -1) { - trapStack.push(trap); - } else { - trapStack.splice(trapIndex, 1); - trapStack.push(trap); - } - }, - deactivateTrap: function deactivateTrap(trapStack, trap) { - var trapIndex = trapStack.indexOf(trap); - if (trapIndex !== -1) { - trapStack.splice(trapIndex, 1); - } - if (trapStack.length > 0 && !trapStack[trapStack.length - 1]._isManuallyPaused()) { - trapStack[trapStack.length - 1]._setPausedState(false); - } - } -}; -var isSelectableInput = function isSelectableInput2(node) { - return node.tagName && node.tagName.toLowerCase() === "input" && typeof node.select === "function"; -}; -var isEscapeEvent = function isEscapeEvent2(e) { - return (e === null || e === void 0 ? void 0 : e.key) === "Escape" || (e === null || e === void 0 ? void 0 : e.key) === "Esc" || (e === null || e === void 0 ? void 0 : e.keyCode) === 27; -}; -var isTabEvent = function isTabEvent2(e) { - return (e === null || e === void 0 ? void 0 : e.key) === "Tab" || (e === null || e === void 0 ? void 0 : e.keyCode) === 9; -}; -var isKeyForward = function isKeyForward2(e) { - return isTabEvent(e) && !e.shiftKey; -}; -var isKeyBackward = function isKeyBackward2(e) { - return isTabEvent(e) && e.shiftKey; -}; -var delay = function delay2(fn) { - return setTimeout(fn, 0); -}; -var valueOrHandler = function valueOrHandler2(value) { - for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - params[_key - 1] = arguments[_key]; - } - return typeof value === "function" ? value.apply(void 0, params) : value; -}; -var getActualTarget = function getActualTarget2(event) { - return event.target.shadowRoot && typeof event.composedPath === "function" ? event.composedPath()[0] : event.target; -}; -var internalTrapStack = []; -var createFocusTrap = function createFocusTrap2(elements, userOptions) { - var doc = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.document) || document; - var trapStack = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.trapStack) || internalTrapStack; - var config = _objectSpread2({ - returnFocusOnDeactivate: true, - escapeDeactivates: true, - delayInitialFocus: true, - isKeyForward, - isKeyBackward - }, userOptions); - var state = { - // containers given to createFocusTrap() - // @type {Array} - containers: [], - // list of objects identifying tabbable nodes in `containers` in the trap - // NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap - // is active, but the trap should never get to a state where there isn't at least one group - // with at least one tabbable node in it (that would lead to an error condition that would - // result in an error being thrown) - // @type {Array<{ - // container: HTMLElement, - // tabbableNodes: Array, // empty if none - // focusableNodes: Array, // empty if none - // posTabIndexesFound: boolean, - // firstTabbableNode: HTMLElement|undefined, - // lastTabbableNode: HTMLElement|undefined, - // firstDomTabbableNode: HTMLElement|undefined, - // lastDomTabbableNode: HTMLElement|undefined, - // nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined - // }>} - containerGroups: [], - // same order/length as `containers` list - // references to objects in `containerGroups`, but only those that actually have - // tabbable nodes in them - // NOTE: same order as `containers` and `containerGroups`, but __not necessarily__ - // the same length - tabbableGroups: [], - nodeFocusedBeforeActivation: null, - mostRecentlyFocusedNode: null, - active: false, - paused: false, - manuallyPaused: false, - // timer ID for when delayInitialFocus is true and initial focus in this trap - // has been delayed during activation - delayInitialFocusTimer: void 0, - // the most recent KeyboardEvent for the configured nav key (typically [SHIFT+]TAB), if any - recentNavEvent: void 0 - }; - var trap; - var getOption = function getOption2(configOverrideOptions, optionName, configOptionName) { - return configOverrideOptions && configOverrideOptions[optionName] !== void 0 ? configOverrideOptions[optionName] : config[configOptionName || optionName]; - }; - var findContainerIndex = function findContainerIndex2(element, event) { - var composedPath = typeof (event === null || event === void 0 ? void 0 : event.composedPath) === "function" ? event.composedPath() : void 0; - return state.containerGroups.findIndex(function(_ref) { - var container = _ref.container, tabbableNodes = _ref.tabbableNodes; - return container.contains(element) || // fall back to explicit tabbable search which will take into consideration any - // web components if the `tabbableOptions.getShadowRoot` option was used for - // the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't - // look inside web components even if open) - (composedPath === null || composedPath === void 0 ? void 0 : composedPath.includes(container)) || tabbableNodes.find(function(node) { - return node === element; - }); - }); - }; - var getNodeForOption = function getNodeForOption2(optionName) { - var _ref2 = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, _ref2$hasFallback = _ref2.hasFallback, hasFallback = _ref2$hasFallback === void 0 ? false : _ref2$hasFallback, _ref2$params = _ref2.params, params = _ref2$params === void 0 ? [] : _ref2$params; - var optionValue = config[optionName]; - if (typeof optionValue === "function") { - optionValue = optionValue.apply(void 0, _toConsumableArray(params)); - } - if (optionValue === true) { - optionValue = void 0; - } - if (!optionValue) { - if (optionValue === void 0 || optionValue === false) { - return optionValue; - } - throw new Error("`".concat(optionName, "` was specified but was not a node, or did not return a node")); - } - var node = optionValue; - if (typeof optionValue === "string") { - try { - node = doc.querySelector(optionValue); - } catch (err) { - throw new Error("`".concat(optionName, '` appears to be an invalid selector; error="').concat(err.message, '"')); - } - if (!node) { - if (!hasFallback) { - throw new Error("`".concat(optionName, "` as selector refers to no known node")); - } - } - } - return node; - }; - var getInitialFocusNode = function getInitialFocusNode2() { - var node = getNodeForOption("initialFocus", { - hasFallback: true - }); - if (node === false) { - return false; - } - if (node === void 0 || node && !isFocusable(node, config.tabbableOptions)) { - if (findContainerIndex(doc.activeElement) >= 0) { - node = doc.activeElement; - } else { - var firstTabbableGroup = state.tabbableGroups[0]; - var firstTabbableNode = firstTabbableGroup && firstTabbableGroup.firstTabbableNode; - node = firstTabbableNode || getNodeForOption("fallbackFocus"); - } - } else if (node === null) { - node = getNodeForOption("fallbackFocus"); - } - if (!node) { - throw new Error("Your focus-trap needs to have at least one focusable element"); - } - return node; - }; - var updateTabbableNodes = function updateTabbableNodes2() { - state.containerGroups = state.containers.map(function(container) { - var tabbableNodes = tabbable(container, config.tabbableOptions); - var focusableNodes = focusable(container, config.tabbableOptions); - var firstTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[0] : void 0; - var lastTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[tabbableNodes.length - 1] : void 0; - var firstDomTabbableNode = focusableNodes.find(function(node) { - return isTabbable(node); - }); - var lastDomTabbableNode = focusableNodes.slice().reverse().find(function(node) { - return isTabbable(node); - }); - var posTabIndexesFound = !!tabbableNodes.find(function(node) { - return getTabIndex(node) > 0; - }); - return { - container, - tabbableNodes, - focusableNodes, - /** True if at least one node with positive `tabindex` was found in this container. */ - posTabIndexesFound, - /** First tabbable node in container, __tabindex__ order; `undefined` if none. */ - firstTabbableNode, - /** Last tabbable node in container, __tabindex__ order; `undefined` if none. */ - lastTabbableNode, - // NOTE: DOM order is NOT NECESSARILY "document position" order, but figuring that out - // would require more than just https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition - // because that API doesn't work with Shadow DOM as well as it should (@see - // https://github.com/whatwg/dom/issues/320) and since this first/last is only needed, so far, - // to address an edge case related to positive tabindex support, this seems like a much easier, - // "close enough most of the time" alternative for positive tabindexes which should generally - // be avoided anyway... - /** First tabbable node in container, __DOM__ order; `undefined` if none. */ - firstDomTabbableNode, - /** Last tabbable node in container, __DOM__ order; `undefined` if none. */ - lastDomTabbableNode, - /** - * Finds the __tabbable__ node that follows the given node in the specified direction, - * in this container, if any. - * @param {HTMLElement} node - * @param {boolean} [forward] True if going in forward tab order; false if going - * in reverse. - * @returns {HTMLElement|undefined} The next tabbable node, if any. - */ - nextTabbableNode: function nextTabbableNode(node) { - var forward = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : true; - var nodeIdx = tabbableNodes.indexOf(node); - if (nodeIdx < 0) { - if (forward) { - return focusableNodes.slice(focusableNodes.indexOf(node) + 1).find(function(el) { - return isTabbable(el); - }); - } - return focusableNodes.slice(0, focusableNodes.indexOf(node)).reverse().find(function(el) { - return isTabbable(el); - }); - } - return tabbableNodes[nodeIdx + (forward ? 1 : -1)]; - } - }; - }); - state.tabbableGroups = state.containerGroups.filter(function(group) { - return group.tabbableNodes.length > 0; - }); - if (state.tabbableGroups.length <= 0 && !getNodeForOption("fallbackFocus")) { - throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times"); - } - if (state.containerGroups.find(function(g) { - return g.posTabIndexesFound; - }) && state.containerGroups.length > 1) { - throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps."); - } - }; - var _getActiveElement = function getActiveElement(el) { - var activeElement = el.activeElement; - if (!activeElement) { - return; - } - if (activeElement.shadowRoot && activeElement.shadowRoot.activeElement !== null) { - return _getActiveElement(activeElement.shadowRoot); - } - return activeElement; - }; - var _tryFocus = function tryFocus(node) { - if (node === false) { - return; - } - if (node === _getActiveElement(document)) { - return; - } - if (!node || !node.focus) { - _tryFocus(getInitialFocusNode()); - return; - } - node.focus({ - preventScroll: !!config.preventScroll - }); - state.mostRecentlyFocusedNode = node; - if (isSelectableInput(node)) { - node.select(); - } - }; - var getReturnFocusNode = function getReturnFocusNode2(previousActiveElement) { - var node = getNodeForOption("setReturnFocus", { - params: [previousActiveElement] - }); - return node ? node : node === false ? false : previousActiveElement; - }; - var findNextNavNode = function findNextNavNode2(_ref3) { - var target = _ref3.target, event = _ref3.event, _ref3$isBackward = _ref3.isBackward, isBackward = _ref3$isBackward === void 0 ? false : _ref3$isBackward; - target = target || getActualTarget(event); - updateTabbableNodes(); - var destinationNode = null; - if (state.tabbableGroups.length > 0) { - var containerIndex = findContainerIndex(target, event); - var containerGroup = containerIndex >= 0 ? state.containerGroups[containerIndex] : void 0; - if (containerIndex < 0) { - if (isBackward) { - destinationNode = state.tabbableGroups[state.tabbableGroups.length - 1].lastTabbableNode; - } else { - destinationNode = state.tabbableGroups[0].firstTabbableNode; - } - } else if (isBackward) { - var startOfGroupIndex = state.tabbableGroups.findIndex(function(_ref4) { - var firstTabbableNode = _ref4.firstTabbableNode; - return target === firstTabbableNode; - }); - if (startOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) { - startOfGroupIndex = containerIndex; - } - if (startOfGroupIndex >= 0) { - var destinationGroupIndex = startOfGroupIndex === 0 ? state.tabbableGroups.length - 1 : startOfGroupIndex - 1; - var destinationGroup = state.tabbableGroups[destinationGroupIndex]; - destinationNode = getTabIndex(target) >= 0 ? destinationGroup.lastTabbableNode : destinationGroup.lastDomTabbableNode; - } else if (!isTabEvent(event)) { - destinationNode = containerGroup.nextTabbableNode(target, false); - } - } else { - var lastOfGroupIndex = state.tabbableGroups.findIndex(function(_ref5) { - var lastTabbableNode = _ref5.lastTabbableNode; - return target === lastTabbableNode; - }); - if (lastOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) { - lastOfGroupIndex = containerIndex; - } - if (lastOfGroupIndex >= 0) { - var _destinationGroupIndex = lastOfGroupIndex === state.tabbableGroups.length - 1 ? 0 : lastOfGroupIndex + 1; - var _destinationGroup = state.tabbableGroups[_destinationGroupIndex]; - destinationNode = getTabIndex(target) >= 0 ? _destinationGroup.firstTabbableNode : _destinationGroup.firstDomTabbableNode; - } else if (!isTabEvent(event)) { - destinationNode = containerGroup.nextTabbableNode(target); - } - } - } else { - destinationNode = getNodeForOption("fallbackFocus"); - } - return destinationNode; - }; - var checkPointerDown = function checkPointerDown2(e) { - var target = getActualTarget(e); - if (findContainerIndex(target, e) >= 0) { - return; - } - if (valueOrHandler(config.clickOutsideDeactivates, e)) { - trap.deactivate({ - // NOTE: by setting `returnFocus: false`, deactivate() will do nothing, - // which will result in the outside click setting focus to the node - // that was clicked (and if not focusable, to "nothing"); by setting - // `returnFocus: true`, we'll attempt to re-focus the node originally-focused - // on activation (or the configured `setReturnFocus` node), whether the - // outside click was on a focusable node or not - returnFocus: config.returnFocusOnDeactivate - }); - return; - } - if (valueOrHandler(config.allowOutsideClick, e)) { - return; - } - e.preventDefault(); - }; - var checkFocusIn = function checkFocusIn2(event) { - var target = getActualTarget(event); - var targetContained = findContainerIndex(target, event) >= 0; - if (targetContained || target instanceof Document) { - if (targetContained) { - state.mostRecentlyFocusedNode = target; - } - } else { - event.stopImmediatePropagation(); - var nextNode; - var navAcrossContainers = true; - if (state.mostRecentlyFocusedNode) { - if (getTabIndex(state.mostRecentlyFocusedNode) > 0) { - var mruContainerIdx = findContainerIndex(state.mostRecentlyFocusedNode); - var tabbableNodes = state.containerGroups[mruContainerIdx].tabbableNodes; - if (tabbableNodes.length > 0) { - var mruTabIdx = tabbableNodes.findIndex(function(node) { - return node === state.mostRecentlyFocusedNode; - }); - if (mruTabIdx >= 0) { - if (config.isKeyForward(state.recentNavEvent)) { - if (mruTabIdx + 1 < tabbableNodes.length) { - nextNode = tabbableNodes[mruTabIdx + 1]; - navAcrossContainers = false; - } - } else { - if (mruTabIdx - 1 >= 0) { - nextNode = tabbableNodes[mruTabIdx - 1]; - navAcrossContainers = false; - } - } - } - } - } else { - if (!state.containerGroups.some(function(g) { - return g.tabbableNodes.some(function(n) { - return getTabIndex(n) > 0; - }); - })) { - navAcrossContainers = false; - } - } - } else { - navAcrossContainers = false; - } - if (navAcrossContainers) { - nextNode = findNextNavNode({ - // move FROM the MRU node, not event-related node (which will be the node that is - // outside the trap causing the focus escape we're trying to fix) - target: state.mostRecentlyFocusedNode, - isBackward: config.isKeyBackward(state.recentNavEvent) - }); - } - if (nextNode) { - _tryFocus(nextNode); - } else { - _tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode()); - } - } - state.recentNavEvent = void 0; - }; - var checkKeyNav = function checkKeyNav2(event) { - var isBackward = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false; - state.recentNavEvent = event; - var destinationNode = findNextNavNode({ - event, - isBackward - }); - if (destinationNode) { - if (isTabEvent(event)) { - event.preventDefault(); - } - _tryFocus(destinationNode); - } - }; - var checkTabKey = function checkTabKey2(event) { - if (config.isKeyForward(event) || config.isKeyBackward(event)) { - checkKeyNav(event, config.isKeyBackward(event)); - } - }; - var checkEscapeKey = function checkEscapeKey2(event) { - if (isEscapeEvent(event) && valueOrHandler(config.escapeDeactivates, event) !== false) { - event.preventDefault(); - trap.deactivate(); - } - }; - var checkClick = function checkClick2(e) { - var target = getActualTarget(e); - if (findContainerIndex(target, e) >= 0) { - return; - } - if (valueOrHandler(config.clickOutsideDeactivates, e)) { - return; - } - if (valueOrHandler(config.allowOutsideClick, e)) { - return; - } - e.preventDefault(); - e.stopImmediatePropagation(); - }; - var addListeners = function addListeners2() { - if (!state.active) { - return; - } - activeFocusTraps.activateTrap(trapStack, trap); - state.delayInitialFocusTimer = config.delayInitialFocus ? delay(function() { - _tryFocus(getInitialFocusNode()); - }) : _tryFocus(getInitialFocusNode()); - doc.addEventListener("focusin", checkFocusIn, true); - doc.addEventListener("mousedown", checkPointerDown, { - capture: true, - passive: false - }); - doc.addEventListener("touchstart", checkPointerDown, { - capture: true, - passive: false - }); - doc.addEventListener("click", checkClick, { - capture: true, - passive: false - }); - doc.addEventListener("keydown", checkTabKey, { - capture: true, - passive: false - }); - doc.addEventListener("keydown", checkEscapeKey); - return trap; - }; - var removeListeners = function removeListeners2() { - if (!state.active) { - return; - } - doc.removeEventListener("focusin", checkFocusIn, true); - doc.removeEventListener("mousedown", checkPointerDown, true); - doc.removeEventListener("touchstart", checkPointerDown, true); - doc.removeEventListener("click", checkClick, true); - doc.removeEventListener("keydown", checkTabKey, true); - doc.removeEventListener("keydown", checkEscapeKey); - return trap; - }; - var checkDomRemoval = function checkDomRemoval2(mutations) { - var isFocusedNodeRemoved = mutations.some(function(mutation) { - var removedNodes = Array.from(mutation.removedNodes); - return removedNodes.some(function(node) { - return node === state.mostRecentlyFocusedNode; - }); - }); - if (isFocusedNodeRemoved) { - _tryFocus(getInitialFocusNode()); - } - }; - var mutationObserver = typeof window !== "undefined" && "MutationObserver" in window ? new MutationObserver(checkDomRemoval) : void 0; - var updateObservedNodes = function updateObservedNodes2() { - if (!mutationObserver) { - return; - } - mutationObserver.disconnect(); - if (state.active && !state.paused) { - state.containers.map(function(container) { - mutationObserver.observe(container, { - subtree: true, - childList: true - }); - }); - } - }; - trap = { - get active() { - return state.active; - }, - get paused() { - return state.paused; - }, - activate: function activate(activateOptions) { - if (state.active) { - return this; - } - var onActivate = getOption(activateOptions, "onActivate"); - var onPostActivate = getOption(activateOptions, "onPostActivate"); - var checkCanFocusTrap = getOption(activateOptions, "checkCanFocusTrap"); - if (!checkCanFocusTrap) { - updateTabbableNodes(); - } - state.active = true; - state.paused = false; - state.nodeFocusedBeforeActivation = _getActiveElement(doc); - onActivate === null || onActivate === void 0 || onActivate(); - var finishActivation = function finishActivation2() { - if (checkCanFocusTrap) { - updateTabbableNodes(); - } - addListeners(); - updateObservedNodes(); - onPostActivate === null || onPostActivate === void 0 || onPostActivate(); - }; - if (checkCanFocusTrap) { - checkCanFocusTrap(state.containers.concat()).then(finishActivation, finishActivation); - return this; - } - finishActivation(); - return this; - }, - deactivate: function deactivate(deactivateOptions) { - if (!state.active) { - return this; - } - var options = _objectSpread2({ - onDeactivate: config.onDeactivate, - onPostDeactivate: config.onPostDeactivate, - checkCanReturnFocus: config.checkCanReturnFocus - }, deactivateOptions); - clearTimeout(state.delayInitialFocusTimer); - state.delayInitialFocusTimer = void 0; - removeListeners(); - state.active = false; - state.paused = false; - updateObservedNodes(); - activeFocusTraps.deactivateTrap(trapStack, trap); - var onDeactivate = getOption(options, "onDeactivate"); - var onPostDeactivate = getOption(options, "onPostDeactivate"); - var checkCanReturnFocus = getOption(options, "checkCanReturnFocus"); - var returnFocus = getOption(options, "returnFocus", "returnFocusOnDeactivate"); - onDeactivate === null || onDeactivate === void 0 || onDeactivate(); - var finishDeactivation = function finishDeactivation2() { - delay(function() { - if (returnFocus) { - _tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation)); - } - onPostDeactivate === null || onPostDeactivate === void 0 || onPostDeactivate(); - }); - }; - if (returnFocus && checkCanReturnFocus) { - checkCanReturnFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation)).then(finishDeactivation, finishDeactivation); - return this; - } - finishDeactivation(); - return this; - }, - pause: function pause(pauseOptions) { - if (!state.active) { - return this; - } - state.manuallyPaused = true; - return this._setPausedState(true, pauseOptions); - }, - unpause: function unpause(unpauseOptions) { - if (!state.active) { - return this; - } - state.manuallyPaused = false; - if (trapStack[trapStack.length - 1] !== this) { - return this; - } - return this._setPausedState(false, unpauseOptions); - }, - updateContainerElements: function updateContainerElements(containerElements) { - var elementsAsArray = [].concat(containerElements).filter(Boolean); - state.containers = elementsAsArray.map(function(element) { - return typeof element === "string" ? doc.querySelector(element) : element; - }); - if (state.active) { - updateTabbableNodes(); - } - updateObservedNodes(); - return this; - } - }; - Object.defineProperties(trap, { - _isManuallyPaused: { - value: function value() { - return state.manuallyPaused; - } - }, - _setPausedState: { - value: function value(paused, options) { - if (state.paused === paused) { - return this; - } - state.paused = paused; - if (paused) { - var onPause = getOption(options, "onPause"); - var onPostPause = getOption(options, "onPostPause"); - onPause === null || onPause === void 0 || onPause(); - removeListeners(); - updateObservedNodes(); - onPostPause === null || onPostPause === void 0 || onPostPause(); - } else { - var onUnpause = getOption(options, "onUnpause"); - var onPostUnpause = getOption(options, "onPostUnpause"); - onUnpause === null || onUnpause === void 0 || onUnpause(); - updateTabbableNodes(); - addListeners(); - updateObservedNodes(); - onPostUnpause === null || onPostUnpause === void 0 || onPostUnpause(); - } - return this; - } - } - }); - trap.updateContainerElements(elements); - return trap; -}; - -// node_modules/@vueuse/integrations/useFocusTrap.mjs -function useFocusTrap(target, options = {}) { - let trap; - const { immediate, ...focusTrapOptions } = options; - const hasFocus = shallowRef(false); - const isPaused = shallowRef(false); - const activate = (opts) => trap && trap.activate(opts); - const deactivate = (opts) => trap && trap.deactivate(opts); - const pause = () => { - if (trap) { - trap.pause(); - isPaused.value = true; - } - }; - const unpause = () => { - if (trap) { - trap.unpause(); - isPaused.value = false; - } - }; - const targets = computed(() => { - const _targets = toValue(target); - return toArray(_targets).map((el) => { - const _el = toValue(el); - return typeof _el === "string" ? _el : unrefElement(_el); - }).filter(notNullish); - }); - watch( - targets, - (els) => { - if (!els.length) - return; - trap = createFocusTrap(els, { - ...focusTrapOptions, - onActivate() { - hasFocus.value = true; - if (options.onActivate) - options.onActivate(); - }, - onDeactivate() { - hasFocus.value = false; - if (options.onDeactivate) - options.onDeactivate(); - } - }); - if (immediate) - activate(); - }, - { flush: "post" } - ); - tryOnScopeDispose(() => deactivate()); - return { - hasFocus, - isPaused, - activate, - deactivate, - pause, - unpause - }; -} -export { - useFocusTrap -}; -/*! Bundled license information: - -tabbable/dist/index.esm.js: - (*! - * tabbable 6.3.0 - * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE - *) - -focus-trap/dist/focus-trap.esm.js: - (*! - * focus-trap 7.6.6 - * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE - *) -*/ -//# sourceMappingURL=vitepress___@vueuse_integrations_useFocusTrap.js.map diff --git a/www/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map b/www/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map deleted file mode 100644 index aea1c00..0000000 --- a/www/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../node_modules/tabbable/src/index.js", "../../../../node_modules/focus-trap/index.js", "../../../../node_modules/@vueuse/integrations/useFocusTrap.mjs"], - "sourcesContent": ["// NOTE: separate `:not()` selectors has broader browser support than the newer\n// `:not([inert], [inert] *)` (Feb 2023)\n// CAREFUL: JSDom does not support `:not([inert] *)` as a selector; using it causes\n// the entire query to fail, resulting in no nodes found, which will break a lot\n// of things... so we have to rely on JS to identify nodes inside an inert container\nconst candidateSelectors = [\n 'input:not([inert])',\n 'select:not([inert])',\n 'textarea:not([inert])',\n 'a[href]:not([inert])',\n 'button:not([inert])',\n '[tabindex]:not(slot):not([inert])',\n 'audio[controls]:not([inert])',\n 'video[controls]:not([inert])',\n '[contenteditable]:not([contenteditable=\"false\"]):not([inert])',\n 'details>summary:first-of-type:not([inert])',\n 'details:not([inert])',\n];\nconst candidateSelector = /* #__PURE__ */ candidateSelectors.join(',');\n\nconst NoElement = typeof Element === 'undefined';\n\nconst matches = NoElement\n ? function () {}\n : Element.prototype.matches ||\n Element.prototype.msMatchesSelector ||\n Element.prototype.webkitMatchesSelector;\n\nconst getRootNode =\n !NoElement && Element.prototype.getRootNode\n ? (element) => element?.getRootNode?.()\n : (element) => element?.ownerDocument;\n\n/**\n * Determines if a node is inert or in an inert ancestor.\n * @param {Element} [node]\n * @param {boolean} [lookUp] If true and `node` is not inert, looks up at ancestors to\n * see if any of them are inert. If false, only `node` itself is considered.\n * @returns {boolean} True if inert itself or by way of being in an inert ancestor.\n * False if `node` is falsy.\n */\nconst isInert = function (node, lookUp = true) {\n // CAREFUL: JSDom does not support inert at all, so we can't use the `HTMLElement.inert`\n // JS API property; we have to check the attribute, which can either be empty or 'true';\n // if it's `null` (not specified) or 'false', it's an active element\n const inertAtt = node?.getAttribute?.('inert');\n const inert = inertAtt === '' || inertAtt === 'true';\n\n // NOTE: this could also be handled with `node.matches('[inert], :is([inert] *)')`\n // if it weren't for `matches()` not being a function on shadow roots; the following\n // code works for any kind of node\n // CAREFUL: JSDom does not appear to support certain selectors like `:not([inert] *)`\n // so it likely would not support `:is([inert] *)` either...\n const result = inert || (lookUp && node && isInert(node.parentNode)); // recursive\n\n return result;\n};\n\n/**\n * Determines if a node's content is editable.\n * @param {Element} [node]\n * @returns True if it's content-editable; false if it's not or `node` is falsy.\n */\nconst isContentEditable = function (node) {\n // CAREFUL: JSDom does not support the `HTMLElement.isContentEditable` API so we have\n // to use the attribute directly to check for this, which can either be empty or 'true';\n // if it's `null` (not specified) or 'false', it's a non-editable element\n const attValue = node?.getAttribute?.('contenteditable');\n return attValue === '' || attValue === 'true';\n};\n\n/**\n * @param {Element} el container to check in\n * @param {boolean} includeContainer add container to check\n * @param {(node: Element) => boolean} filter filter candidates\n * @returns {Element[]}\n */\nconst getCandidates = function (el, includeContainer, filter) {\n // even if `includeContainer=false`, we still have to check it for inertness because\n // if it's inert, all its children are inert\n if (isInert(el)) {\n return [];\n }\n\n let candidates = Array.prototype.slice.apply(\n el.querySelectorAll(candidateSelector)\n );\n if (includeContainer && matches.call(el, candidateSelector)) {\n candidates.unshift(el);\n }\n candidates = candidates.filter(filter);\n return candidates;\n};\n\n/**\n * @callback GetShadowRoot\n * @param {Element} element to check for shadow root\n * @returns {ShadowRoot|boolean} ShadowRoot if available or boolean indicating if a shadowRoot is attached but not available.\n */\n\n/**\n * @callback ShadowRootFilter\n * @param {Element} shadowHostNode the element which contains shadow content\n * @returns {boolean} true if a shadow root could potentially contain valid candidates.\n */\n\n/**\n * @typedef {Object} CandidateScope\n * @property {Element} scopeParent contains inner candidates\n * @property {Element[]} candidates list of candidates found in the scope parent\n */\n\n/**\n * @typedef {Object} IterativeOptions\n * @property {GetShadowRoot|boolean} getShadowRoot true if shadow support is enabled; falsy if not;\n * if a function, implies shadow support is enabled and either returns the shadow root of an element\n * or a boolean stating if it has an undisclosed shadow root\n * @property {(node: Element) => boolean} filter filter candidates\n * @property {boolean} flatten if true then result will flatten any CandidateScope into the returned list\n * @property {ShadowRootFilter} shadowRootFilter filter shadow roots;\n */\n\n/**\n * @param {Element[]} elements list of element containers to match candidates from\n * @param {boolean} includeContainer add container list to check\n * @param {IterativeOptions} options\n * @returns {Array.}\n */\nconst getCandidatesIteratively = function (\n elements,\n includeContainer,\n options\n) {\n const candidates = [];\n const elementsToCheck = Array.from(elements);\n while (elementsToCheck.length) {\n const element = elementsToCheck.shift();\n if (isInert(element, false)) {\n // no need to look up since we're drilling down\n // anything inside this container will also be inert\n continue;\n }\n\n if (element.tagName === 'SLOT') {\n // add shadow dom slot scope (slot itself cannot be focusable)\n const assigned = element.assignedElements();\n const content = assigned.length ? assigned : element.children;\n const nestedCandidates = getCandidatesIteratively(content, true, options);\n if (options.flatten) {\n candidates.push(...nestedCandidates);\n } else {\n candidates.push({\n scopeParent: element,\n candidates: nestedCandidates,\n });\n }\n } else {\n // check candidate element\n const validCandidate = matches.call(element, candidateSelector);\n if (\n validCandidate &&\n options.filter(element) &&\n (includeContainer || !elements.includes(element))\n ) {\n candidates.push(element);\n }\n\n // iterate over shadow content if possible\n const shadowRoot =\n element.shadowRoot ||\n // check for an undisclosed shadow\n (typeof options.getShadowRoot === 'function' &&\n options.getShadowRoot(element));\n\n // no inert look up because we're already drilling down and checking for inertness\n // on the way down, so all containers to this root node should have already been\n // vetted as non-inert\n const validShadowRoot =\n !isInert(shadowRoot, false) &&\n (!options.shadowRootFilter || options.shadowRootFilter(element));\n\n if (shadowRoot && validShadowRoot) {\n // add shadow dom scope IIF a shadow root node was given; otherwise, an undisclosed\n // shadow exists, so look at light dom children as fallback BUT create a scope for any\n // child candidates found because they're likely slotted elements (elements that are\n // children of the web component element (which has the shadow), in the light dom, but\n // slotted somewhere _inside_ the undisclosed shadow) -- the scope is created below,\n // _after_ we return from this recursive call\n const nestedCandidates = getCandidatesIteratively(\n shadowRoot === true ? element.children : shadowRoot.children,\n true,\n options\n );\n\n if (options.flatten) {\n candidates.push(...nestedCandidates);\n } else {\n candidates.push({\n scopeParent: element,\n candidates: nestedCandidates,\n });\n }\n } else {\n // there's not shadow so just dig into the element's (light dom) children\n // __without__ giving the element special scope treatment\n elementsToCheck.unshift(...element.children);\n }\n }\n }\n return candidates;\n};\n\n/**\n * @private\n * Determines if the node has an explicitly specified `tabindex` attribute.\n * @param {HTMLElement} node\n * @returns {boolean} True if so; false if not.\n */\nconst hasTabIndex = function (node) {\n return !isNaN(parseInt(node.getAttribute('tabindex'), 10));\n};\n\n/**\n * Determine the tab index of a given node.\n * @param {HTMLElement} node\n * @returns {number} Tab order (negative, 0, or positive number).\n * @throws {Error} If `node` is falsy.\n */\nconst getTabIndex = function (node) {\n if (!node) {\n throw new Error('No node provided');\n }\n\n if (node.tabIndex < 0) {\n // in Chrome,
,
\n while (parentNode) {\n if (parentNode.tagName === 'FIELDSET' && parentNode.disabled) {\n // look for the first among the children of the disabled
\n for (let i = 0; i < parentNode.children.length; i++) {\n const child = parentNode.children.item(i);\n // when the first (in document order) is found\n if (child.tagName === 'LEGEND') {\n // if its parent
is not nested in another disabled
,\n // return whether `node` is a descendant of its first \n return matches.call(parentNode, 'fieldset[disabled] *')\n ? true\n : !child.contains(node);\n }\n }\n // the disabled
containing `node` has no \n return true;\n }\n parentNode = parentNode.parentElement;\n }\n }\n\n // else, node's tabbable/focusable state should not be affected by a fieldset's\n // enabled/disabled state\n return false;\n};\n\nconst isNodeMatchingSelectorFocusable = function (options, node) {\n if (\n node.disabled ||\n // we must do an inert look up to filter out any elements inside an inert ancestor\n // because we're limited in the type of selectors we can use in JSDom (see related\n // note related to `candidateSelectors`)\n isInert(node) ||\n isHiddenInput(node) ||\n isHidden(node, options) ||\n // For a details element with a summary, the summary element gets the focus\n isDetailsWithSummary(node) ||\n isDisabledFromFieldset(node)\n ) {\n return false;\n }\n return true;\n};\n\nconst isNodeMatchingSelectorTabbable = function (options, node) {\n if (\n isNonTabbableRadio(node) ||\n getTabIndex(node) < 0 ||\n !isNodeMatchingSelectorFocusable(options, node)\n ) {\n return false;\n }\n return true;\n};\n\nconst isShadowRootTabbable = function (shadowHostNode) {\n const tabIndex = parseInt(shadowHostNode.getAttribute('tabindex'), 10);\n if (isNaN(tabIndex) || tabIndex >= 0) {\n return true;\n }\n // If a custom element has an explicit negative tabindex,\n // browsers will not allow tab targeting said element's children.\n return false;\n};\n\n/**\n * @param {Array.} candidates\n * @returns Element[]\n */\nconst sortByOrder = function (candidates) {\n const regularTabbables = [];\n const orderedTabbables = [];\n candidates.forEach(function (item, i) {\n const isScope = !!item.scopeParent;\n const element = isScope ? item.scopeParent : item;\n const candidateTabindex = getSortOrderTabIndex(element, isScope);\n const elements = isScope ? sortByOrder(item.candidates) : element;\n if (candidateTabindex === 0) {\n isScope\n ? regularTabbables.push(...elements)\n : regularTabbables.push(element);\n } else {\n orderedTabbables.push({\n documentOrder: i,\n tabIndex: candidateTabindex,\n item: item,\n isScope: isScope,\n content: elements,\n });\n }\n });\n\n return orderedTabbables\n .sort(sortOrderedTabbables)\n .reduce((acc, sortable) => {\n sortable.isScope\n ? acc.push(...sortable.content)\n : acc.push(sortable.content);\n return acc;\n }, [])\n .concat(regularTabbables);\n};\n\nconst tabbable = function (container, options) {\n options = options || {};\n\n let candidates;\n if (options.getShadowRoot) {\n candidates = getCandidatesIteratively(\n [container],\n options.includeContainer,\n {\n filter: isNodeMatchingSelectorTabbable.bind(null, options),\n flatten: false,\n getShadowRoot: options.getShadowRoot,\n shadowRootFilter: isShadowRootTabbable,\n }\n );\n } else {\n candidates = getCandidates(\n container,\n options.includeContainer,\n isNodeMatchingSelectorTabbable.bind(null, options)\n );\n }\n return sortByOrder(candidates);\n};\n\nconst focusable = function (container, options) {\n options = options || {};\n\n let candidates;\n if (options.getShadowRoot) {\n candidates = getCandidatesIteratively(\n [container],\n options.includeContainer,\n {\n filter: isNodeMatchingSelectorFocusable.bind(null, options),\n flatten: true,\n getShadowRoot: options.getShadowRoot,\n }\n );\n } else {\n candidates = getCandidates(\n container,\n options.includeContainer,\n isNodeMatchingSelectorFocusable.bind(null, options)\n );\n }\n\n return candidates;\n};\n\nconst isTabbable = function (node, options) {\n options = options || {};\n if (!node) {\n throw new Error('No node provided');\n }\n if (matches.call(node, candidateSelector) === false) {\n return false;\n }\n return isNodeMatchingSelectorTabbable(options, node);\n};\n\nconst focusableCandidateSelector = /* #__PURE__ */ candidateSelectors\n .concat('iframe')\n .join(',');\n\nconst isFocusable = function (node, options) {\n options = options || {};\n if (!node) {\n throw new Error('No node provided');\n }\n if (matches.call(node, focusableCandidateSelector) === false) {\n return false;\n }\n return isNodeMatchingSelectorFocusable(options, node);\n};\n\nexport { tabbable, focusable, isTabbable, isFocusable, getTabIndex };\n", "import {\n tabbable,\n focusable,\n isFocusable,\n isTabbable,\n getTabIndex,\n} from 'tabbable';\n\nconst activeFocusTraps = {\n activateTrap(trapStack, trap) {\n if (trapStack.length > 0) {\n const activeTrap = trapStack[trapStack.length - 1];\n if (activeTrap !== trap) {\n activeTrap._setPausedState(true);\n }\n }\n\n const trapIndex = trapStack.indexOf(trap);\n if (trapIndex === -1) {\n trapStack.push(trap);\n } else {\n // move this existing trap to the front of the queue\n trapStack.splice(trapIndex, 1);\n trapStack.push(trap);\n }\n },\n\n deactivateTrap(trapStack, trap) {\n const trapIndex = trapStack.indexOf(trap);\n if (trapIndex !== -1) {\n trapStack.splice(trapIndex, 1);\n }\n\n if (\n trapStack.length > 0 &&\n !trapStack[trapStack.length - 1]._isManuallyPaused()\n ) {\n trapStack[trapStack.length - 1]._setPausedState(false);\n }\n },\n};\n\nconst isSelectableInput = function (node) {\n return (\n node.tagName &&\n node.tagName.toLowerCase() === 'input' &&\n typeof node.select === 'function'\n );\n};\n\nconst isEscapeEvent = function (e) {\n return e?.key === 'Escape' || e?.key === 'Esc' || e?.keyCode === 27;\n};\n\nconst isTabEvent = function (e) {\n return e?.key === 'Tab' || e?.keyCode === 9;\n};\n\n// checks for TAB by default\nconst isKeyForward = function (e) {\n return isTabEvent(e) && !e.shiftKey;\n};\n\n// checks for SHIFT+TAB by default\nconst isKeyBackward = function (e) {\n return isTabEvent(e) && e.shiftKey;\n};\n\nconst delay = function (fn) {\n return setTimeout(fn, 0);\n};\n\n/**\n * Get an option's value when it could be a plain value, or a handler that provides\n * the value.\n * @param {*} value Option's value to check.\n * @param {...*} [params] Any parameters to pass to the handler, if `value` is a function.\n * @returns {*} The `value`, or the handler's returned value.\n */\nconst valueOrHandler = function (value, ...params) {\n return typeof value === 'function' ? value(...params) : value;\n};\n\nconst getActualTarget = function (event) {\n // NOTE: If the trap is _inside_ a shadow DOM, event.target will always be the\n // shadow host. However, event.target.composedPath() will be an array of\n // nodes \"clicked\" from inner-most (the actual element inside the shadow) to\n // outer-most (the host HTML document). If we have access to composedPath(),\n // then use its first element; otherwise, fall back to event.target (and\n // this only works for an _open_ shadow DOM; otherwise,\n // composedPath()[0] === event.target always).\n return event.target.shadowRoot && typeof event.composedPath === 'function'\n ? event.composedPath()[0]\n : event.target;\n};\n\n// NOTE: this must be _outside_ `createFocusTrap()` to make sure all traps in this\n// current instance use the same stack if `userOptions.trapStack` isn't specified\nconst internalTrapStack = [];\n\nconst createFocusTrap = function (elements, userOptions) {\n // SSR: a live trap shouldn't be created in this type of environment so this\n // should be safe code to execute if the `document` option isn't specified\n const doc = userOptions?.document || document;\n\n const trapStack = userOptions?.trapStack || internalTrapStack;\n\n const config = {\n returnFocusOnDeactivate: true,\n escapeDeactivates: true,\n delayInitialFocus: true,\n isKeyForward,\n isKeyBackward,\n ...userOptions,\n };\n\n const state = {\n // containers given to createFocusTrap()\n // @type {Array}\n containers: [],\n\n // list of objects identifying tabbable nodes in `containers` in the trap\n // NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap\n // is active, but the trap should never get to a state where there isn't at least one group\n // with at least one tabbable node in it (that would lead to an error condition that would\n // result in an error being thrown)\n // @type {Array<{\n // container: HTMLElement,\n // tabbableNodes: Array, // empty if none\n // focusableNodes: Array, // empty if none\n // posTabIndexesFound: boolean,\n // firstTabbableNode: HTMLElement|undefined,\n // lastTabbableNode: HTMLElement|undefined,\n // firstDomTabbableNode: HTMLElement|undefined,\n // lastDomTabbableNode: HTMLElement|undefined,\n // nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined\n // }>}\n containerGroups: [], // same order/length as `containers` list\n\n // references to objects in `containerGroups`, but only those that actually have\n // tabbable nodes in them\n // NOTE: same order as `containers` and `containerGroups`, but __not necessarily__\n // the same length\n tabbableGroups: [],\n\n nodeFocusedBeforeActivation: null,\n mostRecentlyFocusedNode: null,\n active: false,\n paused: false,\n manuallyPaused: false,\n\n // timer ID for when delayInitialFocus is true and initial focus in this trap\n // has been delayed during activation\n delayInitialFocusTimer: undefined,\n\n // the most recent KeyboardEvent for the configured nav key (typically [SHIFT+]TAB), if any\n recentNavEvent: undefined,\n };\n\n let trap; // eslint-disable-line prefer-const -- some private functions reference it, and its methods reference private functions, so we must declare here and define later\n\n /**\n * Gets a configuration option value.\n * @param {Object|undefined} configOverrideOptions If true, and option is defined in this set,\n * value will be taken from this object. Otherwise, value will be taken from base configuration.\n * @param {string} optionName Name of the option whose value is sought.\n * @param {string|undefined} [configOptionName] Name of option to use __instead of__ `optionName`\n * IIF `configOverrideOptions` is not defined. Otherwise, `optionName` is used.\n */\n const getOption = (configOverrideOptions, optionName, configOptionName) => {\n return configOverrideOptions &&\n configOverrideOptions[optionName] !== undefined\n ? configOverrideOptions[optionName]\n : config[configOptionName || optionName];\n };\n\n /**\n * Finds the index of the container that contains the element.\n * @param {HTMLElement} element\n * @param {Event} [event] If available, and `element` isn't directly found in any container,\n * the event's composed path is used to see if includes any known trap containers in the\n * case where the element is inside a Shadow DOM.\n * @returns {number} Index of the container in either `state.containers` or\n * `state.containerGroups` (the order/length of these lists are the same); -1\n * if the element isn't found.\n */\n const findContainerIndex = function (element, event) {\n const composedPath =\n typeof event?.composedPath === 'function'\n ? event.composedPath()\n : undefined;\n // NOTE: search `containerGroups` because it's possible a group contains no tabbable\n // nodes, but still contains focusable nodes (e.g. if they all have `tabindex=-1`)\n // and we still need to find the element in there\n return state.containerGroups.findIndex(\n ({ container, tabbableNodes }) =>\n container.contains(element) ||\n // fall back to explicit tabbable search which will take into consideration any\n // web components if the `tabbableOptions.getShadowRoot` option was used for\n // the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't\n // look inside web components even if open)\n composedPath?.includes(container) ||\n tabbableNodes.find((node) => node === element)\n );\n };\n\n /**\n * Gets the node for the given option, which is expected to be an option that\n * can be either a DOM node, a string that is a selector to get a node, `false`\n * (if a node is explicitly NOT given), or a function that returns any of these\n * values.\n * @param {string} optionName\n * @param {Object} options\n * @param {boolean} [options.hasFallback] True if the option could be a selector string\n * and the option allows for a fallback scenario in the case where the selector is\n * valid but does not match a node (i.e. the queried node doesn't exist in the DOM).\n * @param {Array} [options.params] Params to pass to the option if it's a function.\n * @returns {undefined | null | false | HTMLElement | SVGElement} Returns\n * `undefined` if the option is not specified; `null` if the option didn't resolve\n * to a node but `options.hasFallback=true`, `false` if the option resolved to `false`\n * (node explicitly not given); otherwise, the resolved DOM node.\n * @throws {Error} If the option is set, not `false`, and is not, or does not\n * resolve to a node, unless the option is a selector string and `options.hasFallback=true`.\n */\n const getNodeForOption = function (\n optionName,\n { hasFallback = false, params = [] } = {}\n ) {\n let optionValue = config[optionName];\n\n if (typeof optionValue === 'function') {\n optionValue = optionValue(...params);\n }\n\n if (optionValue === true) {\n optionValue = undefined; // use default value\n }\n\n if (!optionValue) {\n if (optionValue === undefined || optionValue === false) {\n return optionValue;\n }\n // else, empty string (invalid), null (invalid), 0 (invalid)\n\n throw new Error(\n `\\`${optionName}\\` was specified but was not a node, or did not return a node`\n );\n }\n\n let node = optionValue; // could be HTMLElement, SVGElement, or non-empty string at this point\n\n if (typeof optionValue === 'string') {\n try {\n node = doc.querySelector(optionValue); // resolve to node, or null if fails\n } catch (err) {\n throw new Error(\n `\\`${optionName}\\` appears to be an invalid selector; error=\"${err.message}\"`\n );\n }\n\n if (!node) {\n if (!hasFallback) {\n throw new Error(\n `\\`${optionName}\\` as selector refers to no known node`\n );\n }\n // else, `node` MUST be `null` because that's what `Document.querySelector()` returns\n // if the selector is valid but doesn't match anything\n }\n }\n\n return node;\n };\n\n const getInitialFocusNode = function () {\n let node = getNodeForOption('initialFocus', { hasFallback: true });\n\n // false explicitly indicates we want no initialFocus at all\n if (node === false) {\n return false;\n }\n\n if (\n node === undefined ||\n (node && !isFocusable(node, config.tabbableOptions))\n ) {\n // option not specified nor focusable: use fallback options\n if (findContainerIndex(doc.activeElement) >= 0) {\n node = doc.activeElement;\n } else {\n const firstTabbableGroup = state.tabbableGroups[0];\n const firstTabbableNode =\n firstTabbableGroup && firstTabbableGroup.firstTabbableNode;\n\n // NOTE: `fallbackFocus` option function cannot return `false` (not supported)\n node = firstTabbableNode || getNodeForOption('fallbackFocus');\n }\n } else if (node === null) {\n // option is a VALID selector string that doesn't yield a node: use the `fallbackFocus`\n // option instead of the default behavior when the option isn't specified at all\n node = getNodeForOption('fallbackFocus');\n }\n\n if (!node) {\n throw new Error(\n 'Your focus-trap needs to have at least one focusable element'\n );\n }\n\n return node;\n };\n\n const updateTabbableNodes = function () {\n state.containerGroups = state.containers.map((container) => {\n const tabbableNodes = tabbable(container, config.tabbableOptions);\n\n // NOTE: if we have tabbable nodes, we must have focusable nodes; focusable nodes\n // are a superset of tabbable nodes since nodes with negative `tabindex` attributes\n // are focusable but not tabbable\n const focusableNodes = focusable(container, config.tabbableOptions);\n\n const firstTabbableNode =\n tabbableNodes.length > 0 ? tabbableNodes[0] : undefined;\n const lastTabbableNode =\n tabbableNodes.length > 0\n ? tabbableNodes[tabbableNodes.length - 1]\n : undefined;\n\n const firstDomTabbableNode = focusableNodes.find((node) =>\n isTabbable(node)\n );\n const lastDomTabbableNode = focusableNodes\n .slice()\n .reverse()\n .find((node) => isTabbable(node));\n\n const posTabIndexesFound = !!tabbableNodes.find(\n (node) => getTabIndex(node) > 0\n );\n\n return {\n container,\n tabbableNodes,\n focusableNodes,\n\n /** True if at least one node with positive `tabindex` was found in this container. */\n posTabIndexesFound,\n\n /** First tabbable node in container, __tabindex__ order; `undefined` if none. */\n firstTabbableNode,\n /** Last tabbable node in container, __tabindex__ order; `undefined` if none. */\n lastTabbableNode,\n\n // NOTE: DOM order is NOT NECESSARILY \"document position\" order, but figuring that out\n // would require more than just https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition\n // because that API doesn't work with Shadow DOM as well as it should (@see\n // https://github.com/whatwg/dom/issues/320) and since this first/last is only needed, so far,\n // to address an edge case related to positive tabindex support, this seems like a much easier,\n // \"close enough most of the time\" alternative for positive tabindexes which should generally\n // be avoided anyway...\n /** First tabbable node in container, __DOM__ order; `undefined` if none. */\n firstDomTabbableNode,\n /** Last tabbable node in container, __DOM__ order; `undefined` if none. */\n lastDomTabbableNode,\n\n /**\n * Finds the __tabbable__ node that follows the given node in the specified direction,\n * in this container, if any.\n * @param {HTMLElement} node\n * @param {boolean} [forward] True if going in forward tab order; false if going\n * in reverse.\n * @returns {HTMLElement|undefined} The next tabbable node, if any.\n */\n nextTabbableNode(node, forward = true) {\n const nodeIdx = tabbableNodes.indexOf(node);\n if (nodeIdx < 0) {\n // either not tabbable nor focusable, or was focused but not tabbable (negative tabindex):\n // since `node` should at least have been focusable, we assume that's the case and mimic\n // what browsers do, which is set focus to the next node in __document position order__,\n // regardless of positive tabindexes, if any -- and for reasons explained in the NOTE\n // above related to `firstDomTabbable` and `lastDomTabbable` properties, we fall back to\n // basic DOM order\n if (forward) {\n return focusableNodes\n .slice(focusableNodes.indexOf(node) + 1)\n .find((el) => isTabbable(el));\n }\n\n return focusableNodes\n .slice(0, focusableNodes.indexOf(node))\n .reverse()\n .find((el) => isTabbable(el));\n }\n\n return tabbableNodes[nodeIdx + (forward ? 1 : -1)];\n },\n };\n });\n\n state.tabbableGroups = state.containerGroups.filter(\n (group) => group.tabbableNodes.length > 0\n );\n\n // throw if no groups have tabbable nodes and we don't have a fallback focus node either\n if (\n state.tabbableGroups.length <= 0 &&\n !getNodeForOption('fallbackFocus') // returning false not supported for this option\n ) {\n throw new Error(\n 'Your focus-trap must have at least one container with at least one tabbable node in it at all times'\n );\n }\n\n // NOTE: Positive tabindexes are only properly supported in single-container traps because\n // doing it across multiple containers where tabindexes could be all over the place\n // would require Tabbable to support multiple containers, would require additional\n // specialized Shadow DOM support, and would require Tabbable's multi-container support\n // to look at those containers in document position order rather than user-provided\n // order (as they are treated in Focus-trap, for legacy reasons). See discussion on\n // https://github.com/focus-trap/focus-trap/issues/375 for more details.\n if (\n state.containerGroups.find((g) => g.posTabIndexesFound) &&\n state.containerGroups.length > 1\n ) {\n throw new Error(\n \"At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.\"\n );\n }\n };\n\n /**\n * Gets the current activeElement. If it's a web-component and has open shadow-root\n * it will recursively search inside shadow roots for the \"true\" activeElement.\n *\n * @param {Document | ShadowRoot} el\n *\n * @returns {HTMLElement} The element that currently has the focus\n **/\n const getActiveElement = function (el) {\n const activeElement = el.activeElement;\n\n if (!activeElement) {\n return;\n }\n\n if (\n activeElement.shadowRoot &&\n activeElement.shadowRoot.activeElement !== null\n ) {\n return getActiveElement(activeElement.shadowRoot);\n }\n\n return activeElement;\n };\n\n const tryFocus = function (node) {\n if (node === false) {\n return;\n }\n\n if (node === getActiveElement(document)) {\n return;\n }\n\n if (!node || !node.focus) {\n tryFocus(getInitialFocusNode());\n return;\n }\n\n node.focus({ preventScroll: !!config.preventScroll });\n // NOTE: focus() API does not trigger focusIn event so set MRU node manually\n state.mostRecentlyFocusedNode = node;\n\n if (isSelectableInput(node)) {\n node.select();\n }\n };\n\n const getReturnFocusNode = function (previousActiveElement) {\n const node = getNodeForOption('setReturnFocus', {\n params: [previousActiveElement],\n });\n return node ? node : node === false ? false : previousActiveElement;\n };\n\n /**\n * Finds the next node (in either direction) where focus should move according to a\n * keyboard focus-in event.\n * @param {Object} params\n * @param {Node} [params.target] Known target __from which__ to navigate, if any.\n * @param {KeyboardEvent|FocusEvent} [params.event] Event to use if `target` isn't known (event\n * will be used to determine the `target`). Ignored if `target` is specified.\n * @param {boolean} [params.isBackward] True if focus should move backward.\n * @returns {Node|undefined} The next node, or `undefined` if a next node couldn't be\n * determined given the current state of the trap.\n */\n const findNextNavNode = function ({ target, event, isBackward = false }) {\n target = target || getActualTarget(event);\n updateTabbableNodes();\n\n let destinationNode = null;\n\n if (state.tabbableGroups.length > 0) {\n // make sure the target is actually contained in a group\n // NOTE: the target may also be the container itself if it's focusable\n // with tabIndex='-1' and was given initial focus\n const containerIndex = findContainerIndex(target, event);\n const containerGroup =\n containerIndex >= 0 ? state.containerGroups[containerIndex] : undefined;\n\n if (containerIndex < 0) {\n // target not found in any group: quite possible focus has escaped the trap,\n // so bring it back into...\n if (isBackward) {\n // ...the last node in the last group\n destinationNode =\n state.tabbableGroups[state.tabbableGroups.length - 1]\n .lastTabbableNode;\n } else {\n // ...the first node in the first group\n destinationNode = state.tabbableGroups[0].firstTabbableNode;\n }\n } else if (isBackward) {\n // REVERSE\n\n // is the target the first tabbable node in a group?\n let startOfGroupIndex = state.tabbableGroups.findIndex(\n ({ firstTabbableNode }) => target === firstTabbableNode\n );\n\n if (\n startOfGroupIndex < 0 &&\n (containerGroup.container === target ||\n (isFocusable(target, config.tabbableOptions) &&\n !isTabbable(target, config.tabbableOptions) &&\n !containerGroup.nextTabbableNode(target, false)))\n ) {\n // an exception case where the target is either the container itself, or\n // a non-tabbable node that was given focus (i.e. tabindex is negative\n // and user clicked on it or node was programmatically given focus)\n // and is not followed by any other tabbable node, in which\n // case, we should handle shift+tab as if focus were on the container's\n // first tabbable node, and go to the last tabbable node of the LAST group\n startOfGroupIndex = containerIndex;\n }\n\n if (startOfGroupIndex >= 0) {\n // YES: then shift+tab should go to the last tabbable node in the\n // previous group (and wrap around to the last tabbable node of\n // the LAST group if it's the first tabbable node of the FIRST group)\n const destinationGroupIndex =\n startOfGroupIndex === 0\n ? state.tabbableGroups.length - 1\n : startOfGroupIndex - 1;\n\n const destinationGroup = state.tabbableGroups[destinationGroupIndex];\n\n destinationNode =\n getTabIndex(target) >= 0\n ? destinationGroup.lastTabbableNode\n : destinationGroup.lastDomTabbableNode;\n } else if (!isTabEvent(event)) {\n // user must have customized the nav keys so we have to move focus manually _within_\n // the active group: do this based on the order determined by tabbable()\n destinationNode = containerGroup.nextTabbableNode(target, false);\n }\n } else {\n // FORWARD\n\n // is the target the last tabbable node in a group?\n let lastOfGroupIndex = state.tabbableGroups.findIndex(\n ({ lastTabbableNode }) => target === lastTabbableNode\n );\n\n if (\n lastOfGroupIndex < 0 &&\n (containerGroup.container === target ||\n (isFocusable(target, config.tabbableOptions) &&\n !isTabbable(target, config.tabbableOptions) &&\n !containerGroup.nextTabbableNode(target)))\n ) {\n // an exception case where the target is the container itself, or\n // a non-tabbable node that was given focus (i.e. tabindex is negative\n // and user clicked on it or node was programmatically given focus)\n // and is not followed by any other tabbable node, in which\n // case, we should handle tab as if focus were on the container's\n // last tabbable node, and go to the first tabbable node of the FIRST group\n lastOfGroupIndex = containerIndex;\n }\n\n if (lastOfGroupIndex >= 0) {\n // YES: then tab should go to the first tabbable node in the next\n // group (and wrap around to the first tabbable node of the FIRST\n // group if it's the last tabbable node of the LAST group)\n const destinationGroupIndex =\n lastOfGroupIndex === state.tabbableGroups.length - 1\n ? 0\n : lastOfGroupIndex + 1;\n\n const destinationGroup = state.tabbableGroups[destinationGroupIndex];\n\n destinationNode =\n getTabIndex(target) >= 0\n ? destinationGroup.firstTabbableNode\n : destinationGroup.firstDomTabbableNode;\n } else if (!isTabEvent(event)) {\n // user must have customized the nav keys so we have to move focus manually _within_\n // the active group: do this based on the order determined by tabbable()\n destinationNode = containerGroup.nextTabbableNode(target);\n }\n }\n } else {\n // no groups available\n // NOTE: the fallbackFocus option does not support returning false to opt-out\n destinationNode = getNodeForOption('fallbackFocus');\n }\n\n return destinationNode;\n };\n\n // This needs to be done on mousedown and touchstart instead of click\n // so that it precedes the focus event.\n const checkPointerDown = function (e) {\n const target = getActualTarget(e);\n\n if (findContainerIndex(target, e) >= 0) {\n // allow the click since it ocurred inside the trap\n return;\n }\n\n if (valueOrHandler(config.clickOutsideDeactivates, e)) {\n // immediately deactivate the trap\n trap.deactivate({\n // NOTE: by setting `returnFocus: false`, deactivate() will do nothing,\n // which will result in the outside click setting focus to the node\n // that was clicked (and if not focusable, to \"nothing\"); by setting\n // `returnFocus: true`, we'll attempt to re-focus the node originally-focused\n // on activation (or the configured `setReturnFocus` node), whether the\n // outside click was on a focusable node or not\n returnFocus: config.returnFocusOnDeactivate,\n });\n return;\n }\n\n // This is needed for mobile devices.\n // (If we'll only let `click` events through,\n // then on mobile they will be blocked anyways if `touchstart` is blocked.)\n if (valueOrHandler(config.allowOutsideClick, e)) {\n // allow the click outside the trap to take place\n return;\n }\n\n // otherwise, prevent the click\n e.preventDefault();\n };\n\n // In case focus escapes the trap for some strange reason, pull it back in.\n // NOTE: the focusIn event is NOT cancelable, so if focus escapes, it may cause unexpected\n // scrolling if the node that got focused was out of view; there's nothing we can do to\n // prevent that from happening by the time we discover that focus escaped\n const checkFocusIn = function (event) {\n const target = getActualTarget(event);\n const targetContained = findContainerIndex(target, event) >= 0;\n\n // In Firefox when you Tab out of an iframe the Document is briefly focused.\n if (targetContained || target instanceof Document) {\n if (targetContained) {\n state.mostRecentlyFocusedNode = target;\n }\n } else {\n // escaped! pull it back in to where it just left\n event.stopImmediatePropagation();\n\n // focus will escape if the MRU node had a positive tab index and user tried to nav forward;\n // it will also escape if the MRU node had a 0 tab index and user tried to nav backward\n // toward a node with a positive tab index\n let nextNode; // next node to focus, if we find one\n let navAcrossContainers = true;\n if (state.mostRecentlyFocusedNode) {\n if (getTabIndex(state.mostRecentlyFocusedNode) > 0) {\n // MRU container index must be >=0 otherwise we wouldn't have it as an MRU node...\n const mruContainerIdx = findContainerIndex(\n state.mostRecentlyFocusedNode\n );\n // there MAY not be any tabbable nodes in the container if there are at least 2 containers\n // and the MRU node is focusable but not tabbable (focus-trap requires at least 1 container\n // with at least one tabbable node in order to function, so this could be the other container\n // with nothing tabbable in it)\n const { tabbableNodes } = state.containerGroups[mruContainerIdx];\n if (tabbableNodes.length > 0) {\n // MRU tab index MAY not be found if the MRU node is focusable but not tabbable\n const mruTabIdx = tabbableNodes.findIndex(\n (node) => node === state.mostRecentlyFocusedNode\n );\n if (mruTabIdx >= 0) {\n if (config.isKeyForward(state.recentNavEvent)) {\n if (mruTabIdx + 1 < tabbableNodes.length) {\n nextNode = tabbableNodes[mruTabIdx + 1];\n navAcrossContainers = false;\n }\n // else, don't wrap within the container as focus should move to next/previous\n // container\n } else {\n if (mruTabIdx - 1 >= 0) {\n nextNode = tabbableNodes[mruTabIdx - 1];\n navAcrossContainers = false;\n }\n // else, don't wrap within the container as focus should move to next/previous\n // container\n }\n // else, don't find in container order without considering direction too\n }\n }\n // else, no tabbable nodes in that container (which means we must have at least one other\n // container with at least one tabbable node in it, otherwise focus-trap would've thrown\n // an error the last time updateTabbableNodes() was run): find next node among all known\n // containers\n } else {\n // check to see if there's at least one tabbable node with a positive tab index inside\n // the trap because focus seems to escape when navigating backward from a tabbable node\n // with tabindex=0 when this is the case (instead of wrapping to the tabbable node with\n // the greatest positive tab index like it should)\n if (\n !state.containerGroups.some((g) =>\n g.tabbableNodes.some((n) => getTabIndex(n) > 0)\n )\n ) {\n // no containers with tabbable nodes with positive tab indexes which means the focus\n // escaped for some other reason and we should just execute the fallback to the\n // MRU node or initial focus node, if any\n navAcrossContainers = false;\n }\n }\n } else {\n // no MRU node means we're likely in some initial condition when the trap has just\n // been activated and initial focus hasn't been given yet, in which case we should\n // fall through to trying to focus the initial focus node, which is what should\n // happen below at this point in the logic\n navAcrossContainers = false;\n }\n\n if (navAcrossContainers) {\n nextNode = findNextNavNode({\n // move FROM the MRU node, not event-related node (which will be the node that is\n // outside the trap causing the focus escape we're trying to fix)\n target: state.mostRecentlyFocusedNode,\n isBackward: config.isKeyBackward(state.recentNavEvent),\n });\n }\n\n if (nextNode) {\n tryFocus(nextNode);\n } else {\n tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());\n }\n }\n\n state.recentNavEvent = undefined; // clear\n };\n\n // Hijack key nav events on the first and last focusable nodes of the trap,\n // in order to prevent focus from escaping. If it escapes for even a\n // moment it can end up scrolling the page and causing confusion so we\n // kind of need to capture the action at the keydown phase.\n const checkKeyNav = function (event, isBackward = false) {\n state.recentNavEvent = event;\n\n const destinationNode = findNextNavNode({ event, isBackward });\n if (destinationNode) {\n if (isTabEvent(event)) {\n // since tab natively moves focus, we wouldn't have a destination node unless we\n // were on the edge of a container and had to move to the next/previous edge, in\n // which case we want to prevent default to keep the browser from moving focus\n // to where it normally would\n event.preventDefault();\n }\n tryFocus(destinationNode);\n }\n // else, let the browser take care of [shift+]tab and move the focus\n };\n\n const checkTabKey = function (event) {\n if (config.isKeyForward(event) || config.isKeyBackward(event)) {\n checkKeyNav(event, config.isKeyBackward(event));\n }\n };\n\n // we use a different event phase for the Escape key to allow canceling the event and checking for this in escapeDeactivates\n const checkEscapeKey = function (event) {\n if (\n isEscapeEvent(event) &&\n valueOrHandler(config.escapeDeactivates, event) !== false\n ) {\n event.preventDefault();\n trap.deactivate();\n }\n };\n\n const checkClick = function (e) {\n const target = getActualTarget(e);\n\n if (findContainerIndex(target, e) >= 0) {\n return;\n }\n\n if (valueOrHandler(config.clickOutsideDeactivates, e)) {\n return;\n }\n\n if (valueOrHandler(config.allowOutsideClick, e)) {\n return;\n }\n\n e.preventDefault();\n e.stopImmediatePropagation();\n };\n\n //\n // EVENT LISTENERS\n //\n\n const addListeners = function () {\n if (!state.active) {\n return;\n }\n\n // There can be only one listening focus trap at a time\n activeFocusTraps.activateTrap(trapStack, trap);\n\n // Delay ensures that the focused element doesn't capture the event\n // that caused the focus trap activation.\n state.delayInitialFocusTimer = config.delayInitialFocus\n ? delay(function () {\n tryFocus(getInitialFocusNode());\n })\n : tryFocus(getInitialFocusNode());\n\n doc.addEventListener('focusin', checkFocusIn, true);\n doc.addEventListener('mousedown', checkPointerDown, {\n capture: true,\n passive: false,\n });\n doc.addEventListener('touchstart', checkPointerDown, {\n capture: true,\n passive: false,\n });\n doc.addEventListener('click', checkClick, {\n capture: true,\n passive: false,\n });\n doc.addEventListener('keydown', checkTabKey, {\n capture: true,\n passive: false,\n });\n doc.addEventListener('keydown', checkEscapeKey);\n\n return trap;\n };\n\n const removeListeners = function () {\n if (!state.active) {\n return;\n }\n\n doc.removeEventListener('focusin', checkFocusIn, true);\n doc.removeEventListener('mousedown', checkPointerDown, true);\n doc.removeEventListener('touchstart', checkPointerDown, true);\n doc.removeEventListener('click', checkClick, true);\n doc.removeEventListener('keydown', checkTabKey, true);\n doc.removeEventListener('keydown', checkEscapeKey);\n\n return trap;\n };\n\n //\n // MUTATION OBSERVER\n //\n\n const checkDomRemoval = function (mutations) {\n const isFocusedNodeRemoved = mutations.some(function (mutation) {\n const removedNodes = Array.from(mutation.removedNodes);\n return removedNodes.some(function (node) {\n return node === state.mostRecentlyFocusedNode;\n });\n });\n\n // If the currently focused is removed then browsers will move focus to the\n // element. If this happens, try to move focus back into the trap.\n if (isFocusedNodeRemoved) {\n tryFocus(getInitialFocusNode());\n }\n };\n\n // Use MutationObserver - if supported - to detect if focused node is removed\n // from the DOM.\n const mutationObserver =\n typeof window !== 'undefined' && 'MutationObserver' in window\n ? new MutationObserver(checkDomRemoval)\n : undefined;\n\n const updateObservedNodes = function () {\n if (!mutationObserver) {\n return;\n }\n\n mutationObserver.disconnect();\n if (state.active && !state.paused) {\n state.containers.map(function (container) {\n mutationObserver.observe(container, {\n subtree: true,\n childList: true,\n });\n });\n }\n };\n\n //\n // TRAP DEFINITION\n //\n\n trap = {\n get active() {\n return state.active;\n },\n\n get paused() {\n return state.paused;\n },\n\n activate(activateOptions) {\n if (state.active) {\n return this;\n }\n\n const onActivate = getOption(activateOptions, 'onActivate');\n const onPostActivate = getOption(activateOptions, 'onPostActivate');\n const checkCanFocusTrap = getOption(activateOptions, 'checkCanFocusTrap');\n\n if (!checkCanFocusTrap) {\n updateTabbableNodes();\n }\n\n state.active = true;\n state.paused = false;\n state.nodeFocusedBeforeActivation = getActiveElement(doc);\n\n onActivate?.();\n\n const finishActivation = () => {\n if (checkCanFocusTrap) {\n updateTabbableNodes();\n }\n addListeners();\n updateObservedNodes();\n onPostActivate?.();\n };\n\n if (checkCanFocusTrap) {\n checkCanFocusTrap(state.containers.concat()).then(\n finishActivation,\n finishActivation\n );\n return this;\n }\n\n finishActivation();\n return this;\n },\n\n deactivate(deactivateOptions) {\n if (!state.active) {\n return this;\n }\n\n const options = {\n onDeactivate: config.onDeactivate,\n onPostDeactivate: config.onPostDeactivate,\n checkCanReturnFocus: config.checkCanReturnFocus,\n ...deactivateOptions,\n };\n\n clearTimeout(state.delayInitialFocusTimer); // noop if undefined\n state.delayInitialFocusTimer = undefined;\n\n removeListeners();\n state.active = false;\n state.paused = false;\n updateObservedNodes();\n\n activeFocusTraps.deactivateTrap(trapStack, trap);\n\n const onDeactivate = getOption(options, 'onDeactivate');\n const onPostDeactivate = getOption(options, 'onPostDeactivate');\n const checkCanReturnFocus = getOption(options, 'checkCanReturnFocus');\n const returnFocus = getOption(\n options,\n 'returnFocus',\n 'returnFocusOnDeactivate'\n );\n\n onDeactivate?.();\n\n const finishDeactivation = () => {\n delay(() => {\n if (returnFocus) {\n tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));\n }\n onPostDeactivate?.();\n });\n };\n\n if (returnFocus && checkCanReturnFocus) {\n checkCanReturnFocus(\n getReturnFocusNode(state.nodeFocusedBeforeActivation)\n ).then(finishDeactivation, finishDeactivation);\n return this;\n }\n\n finishDeactivation();\n return this;\n },\n\n pause(pauseOptions) {\n if (!state.active) {\n return this;\n }\n\n state.manuallyPaused = true;\n\n return this._setPausedState(true, pauseOptions);\n },\n\n unpause(unpauseOptions) {\n if (!state.active) {\n return this;\n }\n\n state.manuallyPaused = false;\n\n if (trapStack[trapStack.length - 1] !== this) {\n return this;\n }\n\n return this._setPausedState(false, unpauseOptions);\n },\n\n updateContainerElements(containerElements) {\n const elementsAsArray = [].concat(containerElements).filter(Boolean);\n\n state.containers = elementsAsArray.map((element) =>\n typeof element === 'string' ? doc.querySelector(element) : element\n );\n\n if (state.active) {\n updateTabbableNodes();\n }\n\n updateObservedNodes();\n\n return this;\n },\n };\n\n Object.defineProperties(trap, {\n _isManuallyPaused: {\n value() {\n return state.manuallyPaused;\n },\n },\n _setPausedState: {\n value(paused, options) {\n if (state.paused === paused) {\n return this;\n }\n\n state.paused = paused;\n if (paused) {\n const onPause = getOption(options, 'onPause');\n const onPostPause = getOption(options, 'onPostPause');\n onPause?.();\n\n removeListeners();\n updateObservedNodes();\n\n onPostPause?.();\n } else {\n const onUnpause = getOption(options, 'onUnpause');\n const onPostUnpause = getOption(options, 'onPostUnpause');\n\n onUnpause?.();\n\n updateTabbableNodes();\n addListeners();\n updateObservedNodes();\n\n onPostUnpause?.();\n }\n\n return this;\n },\n },\n });\n\n // initialize container elements\n trap.updateContainerElements(elements);\n\n return trap;\n};\n\nexport { createFocusTrap };\n", "import { toArray, unrefElement, tryOnScopeDispose } from '@vueuse/core';\nimport { notNullish } from '@vueuse/shared';\nimport { createFocusTrap } from 'focus-trap';\nimport { shallowRef, computed, toValue, watch } from 'vue';\n\nfunction useFocusTrap(target, options = {}) {\n let trap;\n const { immediate, ...focusTrapOptions } = options;\n const hasFocus = shallowRef(false);\n const isPaused = shallowRef(false);\n const activate = (opts) => trap && trap.activate(opts);\n const deactivate = (opts) => trap && trap.deactivate(opts);\n const pause = () => {\n if (trap) {\n trap.pause();\n isPaused.value = true;\n }\n };\n const unpause = () => {\n if (trap) {\n trap.unpause();\n isPaused.value = false;\n }\n };\n const targets = computed(() => {\n const _targets = toValue(target);\n return toArray(_targets).map((el) => {\n const _el = toValue(el);\n return typeof _el === \"string\" ? _el : unrefElement(_el);\n }).filter(notNullish);\n });\n watch(\n targets,\n (els) => {\n if (!els.length)\n return;\n trap = createFocusTrap(els, {\n ...focusTrapOptions,\n onActivate() {\n hasFocus.value = true;\n if (options.onActivate)\n options.onActivate();\n },\n onDeactivate() {\n hasFocus.value = false;\n if (options.onDeactivate)\n options.onDeactivate();\n }\n });\n if (immediate)\n activate();\n },\n { flush: \"post\" }\n );\n tryOnScopeDispose(() => deactivate());\n return {\n hasFocus,\n isPaused,\n activate,\n deactivate,\n pause,\n unpause\n };\n}\n\nexport { useFocusTrap };\n"], - "mappings": "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", - "names": ["candidateSelectors", "candidateSelector", "join", "NoElement", "Element", "matches", "prototype", "msMatchesSelector", "webkitMatchesSelector", "getRootNode", "element", "_element$getRootNode", "call", "ownerDocument", "isInert", "node", "lookUp", "_node$getAttribute", "inertAtt", "getAttribute", "inert", "result", "parentNode", "isContentEditable", "_node$getAttribute2", "attValue", "getCandidates", "el", "includeContainer", "filter", "candidates", "Array", "slice", "apply", "querySelectorAll", "unshift", "getCandidatesIteratively", "elements", "options", "elementsToCheck", "from", "length", "shift", "tagName", "assigned", "assignedElements", "content", "children", "nestedCandidates", "flatten", "push", "scopeParent", "validCandidate", "includes", "shadowRoot", "getShadowRoot", "validShadowRoot", "shadowRootFilter", "hasTabIndex", "isNaN", "parseInt", "getTabIndex", "Error", "tabIndex", "test", "getSortOrderTabIndex", "isScope", "sortOrderedTabbables", "a", "b", "documentOrder", "isInput", "isHiddenInput", "type", "isDetailsWithSummary", "r", "some", "child", "getCheckedRadio", "nodes", "form", "i", "checked", "isTabbableRadio", "name", "radioScope", "queryRadios", "radioSet", "window", "CSS", "escape", "err", "console", "error", "message", "isRadio", "isNonTabbableRadio", "isNodeAttached", "_nodeRoot", "nodeRoot", "nodeRootHost", "host", "attached", "_nodeRootHost", "_nodeRootHost$ownerDo", "_node$ownerDocument", "contains", "_nodeRoot2", "_nodeRootHost2", "_nodeRootHost2$ownerD", "isZeroArea", "_node$getBoundingClie", "getBoundingClientRect", "width", "height", "isHidden", "_ref", "displayCheck", "visible", "checkVisibility", "checkOpacity", "opacityProperty", "contentVisibilityAuto", "visibilityProperty", "checkVisibilityCSS", "getComputedStyle", "visibility", "isDirectSummary", "nodeUnderDetails", "parentElement", "originalNode", "rootNode", "assignedSlot", "getClientRects", "isDisabledFromFieldset", "disabled", "item", "isNodeMatchingSelectorFocusable", "isNodeMatchingSelectorTabbable", "isShadowRootTabbable", "shadowHostNode", "sortByOrder", "regularTabbables", "orderedTabbables", "forEach", "candidateTabindex", "sort", "reduce", "acc", "sortable", "concat", "tabbable", "container", "bind", "focusable", "isTabbable", "focusableCandidateSelector", "isFocusable", "activeFocusTraps", "activateTrap", "trapStack", "trap", "length", "activeTrap", "_setPausedState", "trapIndex", "indexOf", "push", "splice", "deactivateTrap", "_isManuallyPaused", "isSelectableInput", "node", "tagName", "toLowerCase", "select", "isEscapeEvent", "e", "key", "keyCode", "isTabEvent", "isKeyForward", "shiftKey", "isKeyBackward", "delay", "fn", "setTimeout", "valueOrHandler", "value", "_len", "arguments", "params", "Array", "_key", "apply", "getActualTarget", "event", "target", "shadowRoot", "composedPath", "internalTrapStack", "createFocusTrap", "elements", "userOptions", "doc", "document", "config", "_objectSpread", "returnFocusOnDeactivate", "escapeDeactivates", "delayInitialFocus", "state", "containers", "containerGroups", "tabbableGroups", "nodeFocusedBeforeActivation", "mostRecentlyFocusedNode", "active", "paused", "manuallyPaused", "delayInitialFocusTimer", "undefined", "recentNavEvent", "getOption", "configOverrideOptions", "optionName", "configOptionName", "findContainerIndex", "element", "findIndex", "_ref", "container", "tabbableNodes", "contains", "includes", "find", "getNodeForOption", "_ref2", "_ref2$hasFallback", "hasFallback", "_ref2$params", "optionValue", "_toConsumableArray", "Error", "concat", "querySelector", "err", "message", "getInitialFocusNode", "isFocusable", "tabbableOptions", "activeElement", "firstTabbableGroup", "firstTabbableNode", "updateTabbableNodes", "map", "tabbable", "focusableNodes", "focusable", "lastTabbableNode", "firstDomTabbableNode", "isTabbable", "lastDomTabbableNode", "slice", "reverse", "posTabIndexesFound", "getTabIndex", "nextTabbableNode", "forward", "nodeIdx", "el", "filter", "group", "g", "getActiveElement", "tryFocus", "focus", "preventScroll", "getReturnFocusNode", "previousActiveElement", "findNextNavNode", "_ref3", "_ref3$isBackward", "isBackward", "destinationNode", "containerIndex", "containerGroup", "startOfGroupIndex", "_ref4", "destinationGroupIndex", "destinationGroup", "lastOfGroupIndex", "_ref5", "checkPointerDown", "clickOutsideDeactivates", "deactivate", "returnFocus", "allowOutsideClick", "preventDefault", "checkFocusIn", "targetContained", "Document", "stopImmediatePropagation", "nextNode", "navAcrossContainers", "mruContainerIdx", "mruTabIdx", "some", "n", "checkKeyNav", "checkTabKey", "checkEscapeKey", "checkClick", "addListeners", "addEventListener", "capture", "passive", "removeListeners", "removeEventListener", "checkDomRemoval", "mutations", "isFocusedNodeRemoved", "mutation", "removedNodes", "from", "mutationObserver", "window", "MutationObserver", "updateObservedNodes", "disconnect", "observe", "subtree", "childList", "activate", "activateOptions", "onActivate", "onPostActivate", "checkCanFocusTrap", "finishActivation", "then", "deactivateOptions", "options", "onDeactivate", "onPostDeactivate", "checkCanReturnFocus", "clearTimeout", "finishDeactivation", "pause", "pauseOptions", "unpause", "unpauseOptions", "updateContainerElements", "containerElements", "elementsAsArray", "Boolean", "Object", "defineProperties", "onPause", "onPostPause", "onUnpause", "onPostUnpause"] -} diff --git a/www/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js b/www/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js deleted file mode 100644 index cdaee94..0000000 --- a/www/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +++ /dev/null @@ -1,1665 +0,0 @@ -// node_modules/mark.js/src/lib/domiterator.js -var DOMIterator = class _DOMIterator { - /** - * @param {HTMLElement|HTMLElement[]|NodeList|string} ctx - The context DOM - * element, an array of DOM elements, a NodeList or a selector - * @param {boolean} [iframes=true] - A boolean indicating if iframes should - * be handled - * @param {string[]} [exclude=[]] - An array containing exclusion selectors - * for iframes - * @param {number} [iframesTimeout=5000] - A number indicating the ms to - * wait before an iframe should be skipped, in case the load event isn't - * fired. This also applies if the user is offline and the resource of the - * iframe is online (either by the browsers "offline" mode or because - * there's no internet connection) - */ - constructor(ctx, iframes = true, exclude = [], iframesTimeout = 5e3) { - this.ctx = ctx; - this.iframes = iframes; - this.exclude = exclude; - this.iframesTimeout = iframesTimeout; - } - /** - * Checks if the specified DOM element matches the selector - * @param {HTMLElement} element - The DOM element - * @param {string|string[]} selector - The selector or an array with - * selectors - * @return {boolean} - * @access public - */ - static matches(element, selector) { - const selectors = typeof selector === "string" ? [selector] : selector, fn = element.matches || element.matchesSelector || element.msMatchesSelector || element.mozMatchesSelector || element.oMatchesSelector || element.webkitMatchesSelector; - if (fn) { - let match = false; - selectors.every((sel) => { - if (fn.call(element, sel)) { - match = true; - return false; - } - return true; - }); - return match; - } else { - return false; - } - } - /** - * Returns all contexts filtered by duplicates (even nested) - * @return {HTMLElement[]} - An array containing DOM contexts - * @access protected - */ - getContexts() { - let ctx, filteredCtx = []; - if (typeof this.ctx === "undefined" || !this.ctx) { - ctx = []; - } else if (NodeList.prototype.isPrototypeOf(this.ctx)) { - ctx = Array.prototype.slice.call(this.ctx); - } else if (Array.isArray(this.ctx)) { - ctx = this.ctx; - } else if (typeof this.ctx === "string") { - ctx = Array.prototype.slice.call( - document.querySelectorAll(this.ctx) - ); - } else { - ctx = [this.ctx]; - } - ctx.forEach((ctx2) => { - const isDescendant = filteredCtx.filter((contexts) => { - return contexts.contains(ctx2); - }).length > 0; - if (filteredCtx.indexOf(ctx2) === -1 && !isDescendant) { - filteredCtx.push(ctx2); - } - }); - return filteredCtx; - } - /** - * @callback DOMIterator~getIframeContentsSuccessCallback - * @param {HTMLDocument} contents - The contentDocument of the iframe - */ - /** - * Calls the success callback function with the iframe document. If it can't - * be accessed it calls the error callback function - * @param {HTMLElement} ifr - The iframe DOM element - * @param {DOMIterator~getIframeContentsSuccessCallback} successFn - * @param {function} [errorFn] - * @access protected - */ - getIframeContents(ifr, successFn, errorFn = () => { - }) { - let doc; - try { - const ifrWin = ifr.contentWindow; - doc = ifrWin.document; - if (!ifrWin || !doc) { - throw new Error("iframe inaccessible"); - } - } catch (e) { - errorFn(); - } - if (doc) { - successFn(doc); - } - } - /** - * Checks if an iframe is empty (if about:blank is the shown page) - * @param {HTMLElement} ifr - The iframe DOM element - * @return {boolean} - * @access protected - */ - isIframeBlank(ifr) { - const bl = "about:blank", src = ifr.getAttribute("src").trim(), href = ifr.contentWindow.location.href; - return href === bl && src !== bl && src; - } - /** - * Observes the onload event of an iframe and calls the success callback or - * the error callback if the iframe is inaccessible. If the event isn't - * fired within the specified {@link DOMIterator#iframesTimeout}, then it'll - * call the error callback too - * @param {HTMLElement} ifr - The iframe DOM element - * @param {DOMIterator~getIframeContentsSuccessCallback} successFn - * @param {function} errorFn - * @access protected - */ - observeIframeLoad(ifr, successFn, errorFn) { - let called = false, tout = null; - const listener = () => { - if (called) { - return; - } - called = true; - clearTimeout(tout); - try { - if (!this.isIframeBlank(ifr)) { - ifr.removeEventListener("load", listener); - this.getIframeContents(ifr, successFn, errorFn); - } - } catch (e) { - errorFn(); - } - }; - ifr.addEventListener("load", listener); - tout = setTimeout(listener, this.iframesTimeout); - } - /** - * Callback when the iframe is ready - * @callback DOMIterator~onIframeReadySuccessCallback - * @param {HTMLDocument} contents - The contentDocument of the iframe - */ - /** - * Callback if the iframe can't be accessed - * @callback DOMIterator~onIframeReadyErrorCallback - */ - /** - * Calls the callback if the specified iframe is ready for DOM access - * @param {HTMLElement} ifr - The iframe DOM element - * @param {DOMIterator~onIframeReadySuccessCallback} successFn - Success - * callback - * @param {DOMIterator~onIframeReadyErrorCallback} errorFn - Error callback - * @see {@link http://stackoverflow.com/a/36155560/3894981} for - * background information - * @access protected - */ - onIframeReady(ifr, successFn, errorFn) { - try { - if (ifr.contentWindow.document.readyState === "complete") { - if (this.isIframeBlank(ifr)) { - this.observeIframeLoad(ifr, successFn, errorFn); - } else { - this.getIframeContents(ifr, successFn, errorFn); - } - } else { - this.observeIframeLoad(ifr, successFn, errorFn); - } - } catch (e) { - errorFn(); - } - } - /** - * Callback when all iframes are ready for DOM access - * @callback DOMIterator~waitForIframesDoneCallback - */ - /** - * Iterates over all iframes and calls the done callback when all of them - * are ready for DOM access (including nested ones) - * @param {HTMLElement} ctx - The context DOM element - * @param {DOMIterator~waitForIframesDoneCallback} done - Done callback - */ - waitForIframes(ctx, done) { - let eachCalled = 0; - this.forEachIframe(ctx, () => true, (ifr) => { - eachCalled++; - this.waitForIframes(ifr.querySelector("html"), () => { - if (!--eachCalled) { - done(); - } - }); - }, (handled) => { - if (!handled) { - done(); - } - }); - } - /** - * Callback allowing to filter an iframe. Must return true when the element - * should remain, otherwise false - * @callback DOMIterator~forEachIframeFilterCallback - * @param {HTMLElement} iframe - The iframe DOM element - */ - /** - * Callback for each iframe content - * @callback DOMIterator~forEachIframeEachCallback - * @param {HTMLElement} content - The iframe document - */ - /** - * Callback if all iframes inside the context were handled - * @callback DOMIterator~forEachIframeEndCallback - * @param {number} handled - The number of handled iframes (those who - * wheren't filtered) - */ - /** - * Iterates over all iframes inside the specified context and calls the - * callbacks when they're ready. Filters iframes based on the instance - * exclusion selectors - * @param {HTMLElement} ctx - The context DOM element - * @param {DOMIterator~forEachIframeFilterCallback} filter - Filter callback - * @param {DOMIterator~forEachIframeEachCallback} each - Each callback - * @param {DOMIterator~forEachIframeEndCallback} [end] - End callback - * @access protected - */ - forEachIframe(ctx, filter, each, end = () => { - }) { - let ifr = ctx.querySelectorAll("iframe"), open = ifr.length, handled = 0; - ifr = Array.prototype.slice.call(ifr); - const checkEnd = () => { - if (--open <= 0) { - end(handled); - } - }; - if (!open) { - checkEnd(); - } - ifr.forEach((ifr2) => { - if (_DOMIterator.matches(ifr2, this.exclude)) { - checkEnd(); - } else { - this.onIframeReady(ifr2, (con) => { - if (filter(ifr2)) { - handled++; - each(con); - } - checkEnd(); - }, checkEnd); - } - }); - } - /** - * Creates a NodeIterator on the specified context - * @see {@link https://developer.mozilla.org/en/docs/Web/API/NodeIterator} - * @param {HTMLElement} ctx - The context DOM element - * @param {DOMIterator~whatToShow} whatToShow - * @param {DOMIterator~filterCb} filter - * @return {NodeIterator} - * @access protected - */ - createIterator(ctx, whatToShow, filter) { - return document.createNodeIterator(ctx, whatToShow, filter, false); - } - /** - * Creates an instance of DOMIterator in an iframe - * @param {HTMLDocument} contents - Iframe document - * @return {DOMIterator} - * @access protected - */ - createInstanceOnIframe(contents) { - return new _DOMIterator(contents.querySelector("html"), this.iframes); - } - /** - * Checks if an iframe occurs between two nodes, more specifically if an - * iframe occurs before the specified node and after the specified prevNode - * @param {HTMLElement} node - The node that should occur after the iframe - * @param {HTMLElement} prevNode - The node that should occur before the - * iframe - * @param {HTMLElement} ifr - The iframe to check against - * @return {boolean} - * @access protected - */ - compareNodeIframe(node, prevNode, ifr) { - const compCurr = node.compareDocumentPosition(ifr), prev = Node.DOCUMENT_POSITION_PRECEDING; - if (compCurr & prev) { - if (prevNode !== null) { - const compPrev = prevNode.compareDocumentPosition(ifr), after = Node.DOCUMENT_POSITION_FOLLOWING; - if (compPrev & after) { - return true; - } - } else { - return true; - } - } - return false; - } - /** - * @typedef {DOMIterator~getIteratorNodeReturn} - * @type {object.} - * @property {HTMLElement} prevNode - The previous node or null if there is - * no - * @property {HTMLElement} node - The current node - */ - /** - * Returns the previous and current node of the specified iterator - * @param {NodeIterator} itr - The iterator - * @return {DOMIterator~getIteratorNodeReturn} - * @access protected - */ - getIteratorNode(itr) { - const prevNode = itr.previousNode(); - let node; - if (prevNode === null) { - node = itr.nextNode(); - } else { - node = itr.nextNode() && itr.nextNode(); - } - return { - prevNode, - node - }; - } - /** - * An array containing objects. The object key "val" contains an iframe - * DOM element. The object key "handled" contains a boolean indicating if - * the iframe was handled already. - * It wouldn't be enough to save all open or all already handled iframes. - * The information of open iframes is necessary because they may occur after - * all other text nodes (and compareNodeIframe would never be true). The - * information of already handled iframes is necessary as otherwise they may - * be handled multiple times - * @typedef DOMIterator~checkIframeFilterIfr - * @type {object[]} - */ - /** - * Checks if an iframe wasn't handled already and if so, calls - * {@link DOMIterator#compareNodeIframe} to check if it should be handled. - * Information wheter an iframe was or wasn't handled is given within the - * ifr dictionary - * @param {HTMLElement} node - The node that should occur after the iframe - * @param {HTMLElement} prevNode - The node that should occur before the - * iframe - * @param {HTMLElement} currIfr - The iframe to check - * @param {DOMIterator~checkIframeFilterIfr} ifr - The iframe dictionary. - * Will be manipulated (by reference) - * @return {boolean} Returns true when it should be handled, otherwise false - * @access protected - */ - checkIframeFilter(node, prevNode, currIfr, ifr) { - let key = false, handled = false; - ifr.forEach((ifrDict, i) => { - if (ifrDict.val === currIfr) { - key = i; - handled = ifrDict.handled; - } - }); - if (this.compareNodeIframe(node, prevNode, currIfr)) { - if (key === false && !handled) { - ifr.push({ - val: currIfr, - handled: true - }); - } else if (key !== false && !handled) { - ifr[key].handled = true; - } - return true; - } - if (key === false) { - ifr.push({ - val: currIfr, - handled: false - }); - } - return false; - } - /** - * Creates an iterator on all open iframes in the specified array and calls - * the end callback when finished - * @param {DOMIterator~checkIframeFilterIfr} ifr - * @param {DOMIterator~whatToShow} whatToShow - * @param {DOMIterator~forEachNodeCallback} eCb - Each callback - * @param {DOMIterator~filterCb} fCb - * @access protected - */ - handleOpenIframes(ifr, whatToShow, eCb, fCb) { - ifr.forEach((ifrDict) => { - if (!ifrDict.handled) { - this.getIframeContents(ifrDict.val, (con) => { - this.createInstanceOnIframe(con).forEachNode( - whatToShow, - eCb, - fCb - ); - }); - } - }); - } - /** - * Iterates through all nodes in the specified context and handles iframe - * nodes at the correct position - * @param {DOMIterator~whatToShow} whatToShow - * @param {HTMLElement} ctx - The context - * @param {DOMIterator~forEachNodeCallback} eachCb - Each callback - * @param {DOMIterator~filterCb} filterCb - Filter callback - * @param {DOMIterator~forEachNodeEndCallback} doneCb - End callback - * @access protected - */ - iterateThroughNodes(whatToShow, ctx, eachCb, filterCb, doneCb) { - const itr = this.createIterator(ctx, whatToShow, filterCb); - let ifr = [], elements = [], node, prevNode, retrieveNodes = () => { - ({ - prevNode, - node - } = this.getIteratorNode(itr)); - return node; - }; - while (retrieveNodes()) { - if (this.iframes) { - this.forEachIframe(ctx, (currIfr) => { - return this.checkIframeFilter(node, prevNode, currIfr, ifr); - }, (con) => { - this.createInstanceOnIframe(con).forEachNode( - whatToShow, - (ifrNode) => elements.push(ifrNode), - filterCb - ); - }); - } - elements.push(node); - } - elements.forEach((node2) => { - eachCb(node2); - }); - if (this.iframes) { - this.handleOpenIframes(ifr, whatToShow, eachCb, filterCb); - } - doneCb(); - } - /** - * Callback for each node - * @callback DOMIterator~forEachNodeCallback - * @param {HTMLElement} node - The DOM text node element - */ - /** - * Callback if all contexts were handled - * @callback DOMIterator~forEachNodeEndCallback - */ - /** - * Iterates over all contexts and initializes - * {@link DOMIterator#iterateThroughNodes iterateThroughNodes} on them - * @param {DOMIterator~whatToShow} whatToShow - * @param {DOMIterator~forEachNodeCallback} each - Each callback - * @param {DOMIterator~filterCb} filter - Filter callback - * @param {DOMIterator~forEachNodeEndCallback} done - End callback - * @access public - */ - forEachNode(whatToShow, each, filter, done = () => { - }) { - const contexts = this.getContexts(); - let open = contexts.length; - if (!open) { - done(); - } - contexts.forEach((ctx) => { - const ready = () => { - this.iterateThroughNodes(whatToShow, ctx, each, filter, () => { - if (--open <= 0) { - done(); - } - }); - }; - if (this.iframes) { - this.waitForIframes(ctx, ready); - } else { - ready(); - } - }); - } - /** - * Callback to filter nodes. Can return e.g. NodeFilter.FILTER_ACCEPT or - * NodeFilter.FILTER_REJECT - * @see {@link http://tinyurl.com/zdczmm2} - * @callback DOMIterator~filterCb - * @param {HTMLElement} node - The node to filter - */ - /** - * @typedef DOMIterator~whatToShow - * @see {@link http://tinyurl.com/zfqqkx2} - * @type {number} - */ -}; - -// node_modules/mark.js/src/lib/mark.js -var Mark = class { - // eslint-disable-line no-unused-vars - /** - * @param {HTMLElement|HTMLElement[]|NodeList|string} ctx - The context DOM - * element, an array of DOM elements, a NodeList or a selector - */ - constructor(ctx) { - this.ctx = ctx; - this.ie = false; - const ua = window.navigator.userAgent; - if (ua.indexOf("MSIE") > -1 || ua.indexOf("Trident") > -1) { - this.ie = true; - } - } - /** - * Options defined by the user. They will be initialized from one of the - * public methods. See {@link Mark#mark}, {@link Mark#markRegExp}, - * {@link Mark#markRanges} and {@link Mark#unmark} for option properties. - * @type {object} - * @param {object} [val] - An object that will be merged with defaults - * @access protected - */ - set opt(val) { - this._opt = Object.assign({}, { - "element": "", - "className": "", - "exclude": [], - "iframes": false, - "iframesTimeout": 5e3, - "separateWordSearch": true, - "diacritics": true, - "synonyms": {}, - "accuracy": "partially", - "acrossElements": false, - "caseSensitive": false, - "ignoreJoiners": false, - "ignoreGroups": 0, - "ignorePunctuation": [], - "wildcards": "disabled", - "each": () => { - }, - "noMatch": () => { - }, - "filter": () => true, - "done": () => { - }, - "debug": false, - "log": window.console - }, val); - } - get opt() { - return this._opt; - } - /** - * An instance of DOMIterator - * @type {DOMIterator} - * @access protected - */ - get iterator() { - return new DOMIterator( - this.ctx, - this.opt.iframes, - this.opt.exclude, - this.opt.iframesTimeout - ); - } - /** - * Logs a message if log is enabled - * @param {string} msg - The message to log - * @param {string} [level="debug"] - The log level, e.g. warn - * error, debug - * @access protected - */ - log(msg, level = "debug") { - const log = this.opt.log; - if (!this.opt.debug) { - return; - } - if (typeof log === "object" && typeof log[level] === "function") { - log[level](`mark.js: ${msg}`); - } - } - /** - * Escapes a string for usage within a regular expression - * @param {string} str - The string to escape - * @return {string} - * @access protected - */ - escapeStr(str) { - return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - } - /** - * Creates a regular expression string to match the specified search - * term including synonyms, diacritics and accuracy if defined - * @param {string} str - The search term to be used - * @return {string} - * @access protected - */ - createRegExp(str) { - if (this.opt.wildcards !== "disabled") { - str = this.setupWildcardsRegExp(str); - } - str = this.escapeStr(str); - if (Object.keys(this.opt.synonyms).length) { - str = this.createSynonymsRegExp(str); - } - if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) { - str = this.setupIgnoreJoinersRegExp(str); - } - if (this.opt.diacritics) { - str = this.createDiacriticsRegExp(str); - } - str = this.createMergedBlanksRegExp(str); - if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) { - str = this.createJoinersRegExp(str); - } - if (this.opt.wildcards !== "disabled") { - str = this.createWildcardsRegExp(str); - } - str = this.createAccuracyRegExp(str); - return str; - } - /** - * Creates a regular expression string to match the defined synonyms - * @param {string} str - The search term to be used - * @return {string} - * @access protected - */ - createSynonymsRegExp(str) { - const syn = this.opt.synonyms, sens = this.opt.caseSensitive ? "" : "i", joinerPlaceholder = this.opt.ignoreJoiners || this.opt.ignorePunctuation.length ? "\0" : ""; - for (let index in syn) { - if (syn.hasOwnProperty(index)) { - const value = syn[index], k1 = this.opt.wildcards !== "disabled" ? this.setupWildcardsRegExp(index) : this.escapeStr(index), k2 = this.opt.wildcards !== "disabled" ? this.setupWildcardsRegExp(value) : this.escapeStr(value); - if (k1 !== "" && k2 !== "") { - str = str.replace( - new RegExp( - `(${this.escapeStr(k1)}|${this.escapeStr(k2)})`, - `gm${sens}` - ), - joinerPlaceholder + `(${this.processSynomyms(k1)}|${this.processSynomyms(k2)})` + joinerPlaceholder - ); - } - } - } - return str; - } - /** - * Setup synonyms to work with ignoreJoiners and or ignorePunctuation - * @param {string} str - synonym key or value to process - * @return {string} - processed synonym string - */ - processSynomyms(str) { - if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) { - str = this.setupIgnoreJoinersRegExp(str); - } - return str; - } - /** - * Sets up the regular expression string to allow later insertion of - * wildcard regular expression matches - * @param {string} str - The search term to be used - * @return {string} - * @access protected - */ - setupWildcardsRegExp(str) { - str = str.replace(/(?:\\)*\?/g, (val) => { - return val.charAt(0) === "\\" ? "?" : ""; - }); - return str.replace(/(?:\\)*\*/g, (val) => { - return val.charAt(0) === "\\" ? "*" : ""; - }); - } - /** - * Sets up the regular expression string to allow later insertion of - * wildcard regular expression matches - * @param {string} str - The search term to be used - * @return {string} - * @access protected - */ - createWildcardsRegExp(str) { - let spaces = this.opt.wildcards === "withSpaces"; - return str.replace(/\u0001/g, spaces ? "[\\S\\s]?" : "\\S?").replace(/\u0002/g, spaces ? "[\\S\\s]*?" : "\\S*"); - } - /** - * Sets up the regular expression string to allow later insertion of - * designated characters (soft hyphens & zero width characters) - * @param {string} str - The search term to be used - * @return {string} - * @access protected - */ - setupIgnoreJoinersRegExp(str) { - return str.replace(/[^(|)\\]/g, (val, indx, original) => { - let nextChar = original.charAt(indx + 1); - if (/[(|)\\]/.test(nextChar) || nextChar === "") { - return val; - } else { - return val + "\0"; - } - }); - } - /** - * Creates a regular expression string to allow ignoring of designated - * characters (soft hyphens, zero width characters & punctuation) based on - * the specified option values of ignorePunctuation and - * ignoreJoiners - * @param {string} str - The search term to be used - * @return {string} - * @access protected - */ - createJoinersRegExp(str) { - let joiner = []; - const ignorePunctuation = this.opt.ignorePunctuation; - if (Array.isArray(ignorePunctuation) && ignorePunctuation.length) { - joiner.push(this.escapeStr(ignorePunctuation.join(""))); - } - if (this.opt.ignoreJoiners) { - joiner.push("\\u00ad\\u200b\\u200c\\u200d"); - } - return joiner.length ? str.split(/\u0000+/).join(`[${joiner.join("")}]*`) : str; - } - /** - * Creates a regular expression string to match diacritics - * @param {string} str - The search term to be used - * @return {string} - * @access protected - */ - createDiacriticsRegExp(str) { - const sens = this.opt.caseSensitive ? "" : "i", dct = this.opt.caseSensitive ? [ - "aàáảãạăằắẳẵặâầấẩẫậäåāą", - "AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ", - "cçćč", - "CÇĆČ", - "dđď", - "DĐĎ", - "eèéẻẽẹêềếểễệëěēę", - "EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ", - "iìíỉĩịîïī", - "IÌÍỈĨỊÎÏĪ", - "lł", - "LŁ", - "nñňń", - "NÑŇŃ", - "oòóỏõọôồốổỗộơởỡớờợöøō", - "OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ", - "rř", - "RŘ", - "sšśșş", - "SŠŚȘŞ", - "tťțţ", - "TŤȚŢ", - "uùúủũụưừứửữựûüůū", - "UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ", - "yýỳỷỹỵÿ", - "YÝỲỶỸỴŸ", - "zžżź", - "ZŽŻŹ" - ] : [ - "aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ", - "cçćčCÇĆČ", - "dđďDĐĎ", - "eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ", - "iìíỉĩịîïīIÌÍỈĨỊÎÏĪ", - "lłLŁ", - "nñňńNÑŇŃ", - "oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ", - "rřRŘ", - "sšśșşSŠŚȘŞ", - "tťțţTŤȚŢ", - "uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ", - "yýỳỷỹỵÿYÝỲỶỸỴŸ", - "zžżźZŽŻŹ" - ]; - let handled = []; - str.split("").forEach((ch) => { - dct.every((dct2) => { - if (dct2.indexOf(ch) !== -1) { - if (handled.indexOf(dct2) > -1) { - return false; - } - str = str.replace( - new RegExp(`[${dct2}]`, `gm${sens}`), - `[${dct2}]` - ); - handled.push(dct2); - } - return true; - }); - }); - return str; - } - /** - * Creates a regular expression string that merges whitespace characters - * including subsequent ones into a single pattern, one or multiple - * whitespaces - * @param {string} str - The search term to be used - * @return {string} - * @access protected - */ - createMergedBlanksRegExp(str) { - return str.replace(/[\s]+/gmi, "[\\s]+"); - } - /** - * Creates a regular expression string to match the specified string with - * the defined accuracy. As in the regular expression of "exactly" can be - * a group containing a blank at the beginning, all regular expressions will - * be created with two groups. The first group can be ignored (may contain - * the said blank), the second contains the actual match - * @param {string} str - The searm term to be used - * @return {str} - * @access protected - */ - createAccuracyRegExp(str) { - const chars = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿"; - let acc = this.opt.accuracy, val = typeof acc === "string" ? acc : acc.value, ls = typeof acc === "string" ? [] : acc.limiters, lsJoin = ""; - ls.forEach((limiter) => { - lsJoin += `|${this.escapeStr(limiter)}`; - }); - switch (val) { - case "partially": - default: - return `()(${str})`; - case "complementary": - lsJoin = "\\s" + (lsJoin ? lsJoin : this.escapeStr(chars)); - return `()([^${lsJoin}]*${str}[^${lsJoin}]*)`; - case "exactly": - return `(^|\\s${lsJoin})(${str})(?=$|\\s${lsJoin})`; - } - } - /** - * @typedef Mark~separatedKeywords - * @type {object.} - * @property {array.} keywords - The list of keywords - * @property {number} length - The length - */ - /** - * Returns a list of keywords dependent on whether separate word search - * was defined. Also it filters empty keywords - * @param {array} sv - The array of keywords - * @return {Mark~separatedKeywords} - * @access protected - */ - getSeparatedKeywords(sv) { - let stack = []; - sv.forEach((kw) => { - if (!this.opt.separateWordSearch) { - if (kw.trim() && stack.indexOf(kw) === -1) { - stack.push(kw); - } - } else { - kw.split(" ").forEach((kwSplitted) => { - if (kwSplitted.trim() && stack.indexOf(kwSplitted) === -1) { - stack.push(kwSplitted); - } - }); - } - }); - return { - // sort because of https://git.io/v6USg - "keywords": stack.sort((a, b) => { - return b.length - a.length; - }), - "length": stack.length - }; - } - /** - * Check if a value is a number - * @param {number|string} value - the value to check; - * numeric strings allowed - * @return {boolean} - * @access protected - */ - isNumeric(value) { - return Number(parseFloat(value)) == value; - } - /** - * @typedef Mark~rangeObject - * @type {object} - * @property {number} start - The start position within the composite value - * @property {number} length - The length of the string to mark within the - * composite value. - */ - /** - * @typedef Mark~setOfRanges - * @type {object[]} - * @property {Mark~rangeObject} - */ - /** - * Returns a processed list of integer offset indexes that do not overlap - * each other, and remove any string values or additional elements - * @param {Mark~setOfRanges} array - unprocessed raw array - * @return {Mark~setOfRanges} - processed array with any invalid entries - * removed - * @throws Will throw an error if an array of objects is not passed - * @access protected - */ - checkRanges(array) { - if (!Array.isArray(array) || Object.prototype.toString.call(array[0]) !== "[object Object]") { - this.log("markRanges() will only accept an array of objects"); - this.opt.noMatch(array); - return []; - } - const stack = []; - let last = 0; - array.sort((a, b) => { - return a.start - b.start; - }).forEach((item) => { - let { start, end, valid } = this.callNoMatchOnInvalidRanges(item, last); - if (valid) { - item.start = start; - item.length = end - start; - stack.push(item); - last = end; - } - }); - return stack; - } - /** - * @typedef Mark~validObject - * @type {object} - * @property {number} start - The start position within the composite value - * @property {number} end - The calculated end position within the composite - * value. - * @property {boolean} valid - boolean value indicating that the start and - * calculated end range is valid - */ - /** - * Initial validation of ranges for markRanges. Preliminary checks are done - * to ensure the start and length values exist and are not zero or non- - * numeric - * @param {Mark~rangeObject} range - the current range object - * @param {number} last - last index of range - * @return {Mark~validObject} - * @access protected - */ - callNoMatchOnInvalidRanges(range, last) { - let start, end, valid = false; - if (range && typeof range.start !== "undefined") { - start = parseInt(range.start, 10); - end = start + parseInt(range.length, 10); - if (this.isNumeric(range.start) && this.isNumeric(range.length) && end - last > 0 && end - start > 0) { - valid = true; - } else { - this.log( - `Ignoring invalid or overlapping range: ${JSON.stringify(range)}` - ); - this.opt.noMatch(range); - } - } else { - this.log(`Ignoring invalid range: ${JSON.stringify(range)}`); - this.opt.noMatch(range); - } - return { - start, - end, - valid - }; - } - /** - * Check valid range for markRanges. Check ranges with access to the context - * string. Range values are double checked, lengths that extend the mark - * beyond the string length are limitied and ranges containing only - * whitespace are ignored - * @param {Mark~rangeObject} range - the current range object - * @param {number} originalLength - original length of the context string - * @param {string} string - current content string - * @return {Mark~validObject} - * @access protected - */ - checkWhitespaceRanges(range, originalLength, string) { - let end, valid = true, max = string.length, offset = originalLength - max, start = parseInt(range.start, 10) - offset; - start = start > max ? max : start; - end = start + parseInt(range.length, 10); - if (end > max) { - end = max; - this.log(`End range automatically set to the max value of ${max}`); - } - if (start < 0 || end - start < 0 || start > max || end > max) { - valid = false; - this.log(`Invalid range: ${JSON.stringify(range)}`); - this.opt.noMatch(range); - } else if (string.substring(start, end).replace(/\s+/g, "") === "") { - valid = false; - this.log("Skipping whitespace only range: " + JSON.stringify(range)); - this.opt.noMatch(range); - } - return { - start, - end, - valid - }; - } - /** - * @typedef Mark~getTextNodesDict - * @type {object.} - * @property {string} value - The composite value of all text nodes - * @property {object[]} nodes - An array of objects - * @property {number} nodes.start - The start position within the composite - * value - * @property {number} nodes.end - The end position within the composite - * value - * @property {HTMLElement} nodes.node - The DOM text node element - */ - /** - * Callback - * @callback Mark~getTextNodesCallback - * @param {Mark~getTextNodesDict} - */ - /** - * Calls the callback with an object containing all text nodes (including - * iframe text nodes) with start and end positions and the composite value - * of them (string) - * @param {Mark~getTextNodesCallback} cb - Callback - * @access protected - */ - getTextNodes(cb) { - let val = "", nodes = []; - this.iterator.forEachNode(NodeFilter.SHOW_TEXT, (node) => { - nodes.push({ - start: val.length, - end: (val += node.textContent).length, - node - }); - }, (node) => { - if (this.matchesExclude(node.parentNode)) { - return NodeFilter.FILTER_REJECT; - } else { - return NodeFilter.FILTER_ACCEPT; - } - }, () => { - cb({ - value: val, - nodes - }); - }); - } - /** - * Checks if an element matches any of the specified exclude selectors. Also - * it checks for elements in which no marks should be performed (e.g. - * script and style tags) and optionally already marked elements - * @param {HTMLElement} el - The element to check - * @return {boolean} - * @access protected - */ - matchesExclude(el) { - return DOMIterator.matches(el, this.opt.exclude.concat([ - // ignores the elements itself, not their childrens (selector *) - "script", - "style", - "title", - "head", - "html" - ])); - } - /** - * Wraps the instance element and class around matches that fit the start - * and end positions within the node - * @param {HTMLElement} node - The DOM text node - * @param {number} start - The position where to start wrapping - * @param {number} end - The position where to end wrapping - * @return {HTMLElement} Returns the splitted text node that will appear - * after the wrapped text node - * @access protected - */ - wrapRangeInTextNode(node, start, end) { - const hEl = !this.opt.element ? "mark" : this.opt.element, startNode = node.splitText(start), ret = startNode.splitText(end - start); - let repl = document.createElement(hEl); - repl.setAttribute("data-markjs", "true"); - if (this.opt.className) { - repl.setAttribute("class", this.opt.className); - } - repl.textContent = startNode.textContent; - startNode.parentNode.replaceChild(repl, startNode); - return ret; - } - /** - * @typedef Mark~wrapRangeInMappedTextNodeDict - * @type {object.} - * @property {string} value - The composite value of all text nodes - * @property {object[]} nodes - An array of objects - * @property {number} nodes.start - The start position within the composite - * value - * @property {number} nodes.end - The end position within the composite - * value - * @property {HTMLElement} nodes.node - The DOM text node element - */ - /** - * Each callback - * @callback Mark~wrapMatchesEachCallback - * @param {HTMLElement} node - The wrapped DOM element - * @param {number} lastIndex - The last matching position within the - * composite value of text nodes - */ - /** - * Filter callback - * @callback Mark~wrapMatchesFilterCallback - * @param {HTMLElement} node - The matching text node DOM element - */ - /** - * Determines matches by start and end positions using the text node - * dictionary even across text nodes and calls - * {@link Mark#wrapRangeInTextNode} to wrap them - * @param {Mark~wrapRangeInMappedTextNodeDict} dict - The dictionary - * @param {number} start - The start position of the match - * @param {number} end - The end position of the match - * @param {Mark~wrapMatchesFilterCallback} filterCb - Filter callback - * @param {Mark~wrapMatchesEachCallback} eachCb - Each callback - * @access protected - */ - wrapRangeInMappedTextNode(dict, start, end, filterCb, eachCb) { - dict.nodes.every((n, i) => { - const sibl = dict.nodes[i + 1]; - if (typeof sibl === "undefined" || sibl.start > start) { - if (!filterCb(n.node)) { - return false; - } - const s = start - n.start, e = (end > n.end ? n.end : end) - n.start, startStr = dict.value.substr(0, n.start), endStr = dict.value.substr(e + n.start); - n.node = this.wrapRangeInTextNode(n.node, s, e); - dict.value = startStr + endStr; - dict.nodes.forEach((k, j) => { - if (j >= i) { - if (dict.nodes[j].start > 0 && j !== i) { - dict.nodes[j].start -= e; - } - dict.nodes[j].end -= e; - } - }); - end -= e; - eachCb(n.node.previousSibling, n.start); - if (end > n.end) { - start = n.end; - } else { - return false; - } - } - return true; - }); - } - /** - * Filter callback before each wrapping - * @callback Mark~wrapMatchesFilterCallback - * @param {string} match - The matching string - * @param {HTMLElement} node - The text node where the match occurs - */ - /** - * Callback for each wrapped element - * @callback Mark~wrapMatchesEachCallback - * @param {HTMLElement} element - The marked DOM element - */ - /** - * Callback on end - * @callback Mark~wrapMatchesEndCallback - */ - /** - * Wraps the instance element and class around matches within single HTML - * elements in all contexts - * @param {RegExp} regex - The regular expression to be searched for - * @param {number} ignoreGroups - A number indicating the amount of RegExp - * matching groups to ignore - * @param {Mark~wrapMatchesFilterCallback} filterCb - * @param {Mark~wrapMatchesEachCallback} eachCb - * @param {Mark~wrapMatchesEndCallback} endCb - * @access protected - */ - wrapMatches(regex, ignoreGroups, filterCb, eachCb, endCb) { - const matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1; - this.getTextNodes((dict) => { - dict.nodes.forEach((node) => { - node = node.node; - let match; - while ((match = regex.exec(node.textContent)) !== null && match[matchIdx] !== "") { - if (!filterCb(match[matchIdx], node)) { - continue; - } - let pos = match.index; - if (matchIdx !== 0) { - for (let i = 1; i < matchIdx; i++) { - pos += match[i].length; - } - } - node = this.wrapRangeInTextNode( - node, - pos, - pos + match[matchIdx].length - ); - eachCb(node.previousSibling); - regex.lastIndex = 0; - } - }); - endCb(); - }); - } - /** - * Callback for each wrapped element - * @callback Mark~wrapMatchesAcrossElementsEachCallback - * @param {HTMLElement} element - The marked DOM element - */ - /** - * Filter callback before each wrapping - * @callback Mark~wrapMatchesAcrossElementsFilterCallback - * @param {string} match - The matching string - * @param {HTMLElement} node - The text node where the match occurs - */ - /** - * Callback on end - * @callback Mark~wrapMatchesAcrossElementsEndCallback - */ - /** - * Wraps the instance element and class around matches across all HTML - * elements in all contexts - * @param {RegExp} regex - The regular expression to be searched for - * @param {number} ignoreGroups - A number indicating the amount of RegExp - * matching groups to ignore - * @param {Mark~wrapMatchesAcrossElementsFilterCallback} filterCb - * @param {Mark~wrapMatchesAcrossElementsEachCallback} eachCb - * @param {Mark~wrapMatchesAcrossElementsEndCallback} endCb - * @access protected - */ - wrapMatchesAcrossElements(regex, ignoreGroups, filterCb, eachCb, endCb) { - const matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1; - this.getTextNodes((dict) => { - let match; - while ((match = regex.exec(dict.value)) !== null && match[matchIdx] !== "") { - let start = match.index; - if (matchIdx !== 0) { - for (let i = 1; i < matchIdx; i++) { - start += match[i].length; - } - } - const end = start + match[matchIdx].length; - this.wrapRangeInMappedTextNode(dict, start, end, (node) => { - return filterCb(match[matchIdx], node); - }, (node, lastIndex) => { - regex.lastIndex = lastIndex; - eachCb(node); - }); - } - endCb(); - }); - } - /** - * Callback for each wrapped element - * @callback Mark~wrapRangeFromIndexEachCallback - * @param {HTMLElement} element - The marked DOM element - * @param {Mark~rangeObject} range - the current range object; provided - * start and length values will be numeric integers modified from the - * provided original ranges. - */ - /** - * Filter callback before each wrapping - * @callback Mark~wrapRangeFromIndexFilterCallback - * @param {HTMLElement} node - The text node which includes the range - * @param {Mark~rangeObject} range - the current range object - * @param {string} match - string extracted from the matching range - * @param {number} counter - A counter indicating the number of all marks - */ - /** - * Callback on end - * @callback Mark~wrapRangeFromIndexEndCallback - */ - /** - * Wraps the indicated ranges across all HTML elements in all contexts - * @param {Mark~setOfRanges} ranges - * @param {Mark~wrapRangeFromIndexFilterCallback} filterCb - * @param {Mark~wrapRangeFromIndexEachCallback} eachCb - * @param {Mark~wrapRangeFromIndexEndCallback} endCb - * @access protected - */ - wrapRangeFromIndex(ranges, filterCb, eachCb, endCb) { - this.getTextNodes((dict) => { - const originalLength = dict.value.length; - ranges.forEach((range, counter) => { - let { start, end, valid } = this.checkWhitespaceRanges( - range, - originalLength, - dict.value - ); - if (valid) { - this.wrapRangeInMappedTextNode(dict, start, end, (node) => { - return filterCb( - node, - range, - dict.value.substring(start, end), - counter - ); - }, (node) => { - eachCb(node, range); - }); - } - }); - endCb(); - }); - } - /** - * Unwraps the specified DOM node with its content (text nodes or HTML) - * without destroying possibly present events (using innerHTML) and - * normalizes the parent at the end (merge splitted text nodes) - * @param {HTMLElement} node - The DOM node to unwrap - * @access protected - */ - unwrapMatches(node) { - const parent = node.parentNode; - let docFrag = document.createDocumentFragment(); - while (node.firstChild) { - docFrag.appendChild(node.removeChild(node.firstChild)); - } - parent.replaceChild(docFrag, node); - if (!this.ie) { - parent.normalize(); - } else { - this.normalizeTextNode(parent); - } - } - /** - * Normalizes text nodes. It's a workaround for the native normalize method - * that has a bug in IE (see attached link). Should only be used in IE - * browsers as it's slower than the native method. - * @see {@link http://tinyurl.com/z5asa8c} - * @param {HTMLElement} node - The DOM node to normalize - * @access protected - */ - normalizeTextNode(node) { - if (!node) { - return; - } - if (node.nodeType === 3) { - while (node.nextSibling && node.nextSibling.nodeType === 3) { - node.nodeValue += node.nextSibling.nodeValue; - node.parentNode.removeChild(node.nextSibling); - } - } else { - this.normalizeTextNode(node.firstChild); - } - this.normalizeTextNode(node.nextSibling); - } - /** - * Callback when finished - * @callback Mark~commonDoneCallback - * @param {number} totalMatches - The number of marked elements - */ - /** - * @typedef Mark~commonOptions - * @type {object.} - * @property {string} [element="mark"] - HTML element tag name - * @property {string} [className] - An optional class name - * @property {string[]} [exclude] - An array with exclusion selectors. - * Elements matching those selectors will be ignored - * @property {boolean} [iframes=false] - Whether to search inside iframes - * @property {Mark~commonDoneCallback} [done] - * @property {boolean} [debug=false] - Wheter to log messages - * @property {object} [log=window.console] - Where to log messages (only if - * debug is true) - */ - /** - * Callback for each marked element - * @callback Mark~markRegExpEachCallback - * @param {HTMLElement} element - The marked DOM element - */ - /** - * Callback if there were no matches - * @callback Mark~markRegExpNoMatchCallback - * @param {RegExp} regexp - The regular expression - */ - /** - * Callback to filter matches - * @callback Mark~markRegExpFilterCallback - * @param {HTMLElement} textNode - The text node which includes the match - * @param {string} match - The matching string for the RegExp - * @param {number} counter - A counter indicating the number of all marks - */ - /** - * These options also include the common options from - * {@link Mark~commonOptions} - * @typedef Mark~markRegExpOptions - * @type {object.} - * @property {Mark~markRegExpEachCallback} [each] - * @property {Mark~markRegExpNoMatchCallback} [noMatch] - * @property {Mark~markRegExpFilterCallback} [filter] - */ - /** - * Marks a custom regular expression - * @param {RegExp} regexp - The regular expression - * @param {Mark~markRegExpOptions} [opt] - Optional options object - * @access public - */ - markRegExp(regexp, opt) { - this.opt = opt; - this.log(`Searching with expression "${regexp}"`); - let totalMatches = 0, fn = "wrapMatches"; - const eachCb = (element) => { - totalMatches++; - this.opt.each(element); - }; - if (this.opt.acrossElements) { - fn = "wrapMatchesAcrossElements"; - } - this[fn](regexp, this.opt.ignoreGroups, (match, node) => { - return this.opt.filter(node, match, totalMatches); - }, eachCb, () => { - if (totalMatches === 0) { - this.opt.noMatch(regexp); - } - this.opt.done(totalMatches); - }); - } - /** - * Callback for each marked element - * @callback Mark~markEachCallback - * @param {HTMLElement} element - The marked DOM element - */ - /** - * Callback if there were no matches - * @callback Mark~markNoMatchCallback - * @param {RegExp} term - The search term that was not found - */ - /** - * Callback to filter matches - * @callback Mark~markFilterCallback - * @param {HTMLElement} textNode - The text node which includes the match - * @param {string} match - The matching term - * @param {number} totalCounter - A counter indicating the number of all - * marks - * @param {number} termCounter - A counter indicating the number of marks - * for the specific match - */ - /** - * @typedef Mark~markAccuracyObject - * @type {object.} - * @property {string} value - A accuracy string value - * @property {string[]} limiters - A custom array of limiters. For example - * ["-", ","] - */ - /** - * @typedef Mark~markAccuracySetting - * @type {string} - * @property {"partially"|"complementary"|"exactly"|Mark~markAccuracyObject} - * [accuracy="partially"] - Either one of the following string values: - *
    - *
  • partially: When searching for "lor" only "lor" inside - * "lorem" will be marked
  • - *
  • complementary: When searching for "lor" the whole word - * "lorem" will be marked
  • - *
  • exactly: When searching for "lor" only those exact words - * will be marked. In this example nothing inside "lorem". This value - * is equivalent to the previous option wordBoundary
  • - *
- * Or an object containing two properties: - *
    - *
  • value: One of the above named string values
  • - *
  • limiters: A custom array of string limiters for accuracy - * "exactly" or "complementary"
  • - *
- */ - /** - * @typedef Mark~markWildcardsSetting - * @type {string} - * @property {"disabled"|"enabled"|"withSpaces"} - * [wildcards="disabled"] - Set to any of the following string values: - *
    - *
  • disabled: Disable wildcard usage
  • - *
  • enabled: When searching for "lor?m", the "?" will match zero - * or one non-space character (e.g. "lorm", "loram", "lor3m", etc). When - * searching for "lor*m", the "*" will match zero or more non-space - * characters (e.g. "lorm", "loram", "lor123m", etc).
  • - *
  • withSpaces: When searching for "lor?m", the "?" will - * match zero or one space or non-space character (e.g. "lor m", "loram", - * etc). When searching for "lor*m", the "*" will match zero or more space - * or non-space characters (e.g. "lorm", "lore et dolor ipsum", "lor: m", - * etc).
  • - *
- */ - /** - * @typedef Mark~markIgnorePunctuationSetting - * @type {string[]} - * @property {string} The strings in this setting will contain punctuation - * marks that will be ignored: - *
    - *
  • These punctuation marks can be between any characters, e.g. setting - * this option to ["'"] would match "Worlds", "World's" and - * "Wo'rlds"
  • - *
  • One or more apostrophes between the letters would still produce a - * match (e.g. "W'o''r'l'd's").
  • - *
  • A typical setting for this option could be as follows: - *
    ignorePunctuation: ":;.,-–—‒_(){}[]!'\"+=".split(""),
    This - * setting includes common punctuation as well as a minus, en-dash, - * em-dash and figure-dash - * ({@link https://en.wikipedia.org/wiki/Dash#Figure_dash ref}), as well - * as an underscore.
  • - *
- */ - /** - * These options also include the common options from - * {@link Mark~commonOptions} - * @typedef Mark~markOptions - * @type {object.} - * @property {boolean} [separateWordSearch=true] - Whether to search for - * each word separated by a blank instead of the complete term - * @property {boolean} [diacritics=true] - If diacritic characters should be - * matched. ({@link https://en.wikipedia.org/wiki/Diacritic Diacritics}) - * @property {object} [synonyms] - An object with synonyms. The key will be - * a synonym for the value and the value for the key - * @property {Mark~markAccuracySetting} [accuracy] - * @property {Mark~markWildcardsSetting} [wildcards] - * @property {boolean} [acrossElements=false] - Whether to find matches - * across HTML elements. By default, only matches within single HTML - * elements will be found - * @property {boolean} [ignoreJoiners=false] - Whether to ignore word - * joiners inside of key words. These include soft-hyphens, zero-width - * space, zero-width non-joiners and zero-width joiners. - * @property {Mark~markIgnorePunctuationSetting} [ignorePunctuation] - * @property {Mark~markEachCallback} [each] - * @property {Mark~markNoMatchCallback} [noMatch] - * @property {Mark~markFilterCallback} [filter] - */ - /** - * Marks the specified search terms - * @param {string|string[]} [sv] - Search value, either a search string or - * an array containing multiple search strings - * @param {Mark~markOptions} [opt] - Optional options object - * @access public - */ - mark(sv, opt) { - this.opt = opt; - let totalMatches = 0, fn = "wrapMatches"; - const { - keywords: kwArr, - length: kwArrLen - } = this.getSeparatedKeywords(typeof sv === "string" ? [sv] : sv), sens = this.opt.caseSensitive ? "" : "i", handler = (kw) => { - let regex = new RegExp(this.createRegExp(kw), `gm${sens}`), matches = 0; - this.log(`Searching with expression "${regex}"`); - this[fn](regex, 1, (term, node) => { - return this.opt.filter(node, kw, totalMatches, matches); - }, (element) => { - matches++; - totalMatches++; - this.opt.each(element); - }, () => { - if (matches === 0) { - this.opt.noMatch(kw); - } - if (kwArr[kwArrLen - 1] === kw) { - this.opt.done(totalMatches); - } else { - handler(kwArr[kwArr.indexOf(kw) + 1]); - } - }); - }; - if (this.opt.acrossElements) { - fn = "wrapMatchesAcrossElements"; - } - if (kwArrLen === 0) { - this.opt.done(totalMatches); - } else { - handler(kwArr[0]); - } - } - /** - * Callback for each marked element - * @callback Mark~markRangesEachCallback - * @param {HTMLElement} element - The marked DOM element - * @param {array} range - array of range start and end points - */ - /** - * Callback if a processed range is invalid, out-of-bounds, overlaps another - * range, or only matches whitespace - * @callback Mark~markRangesNoMatchCallback - * @param {Mark~rangeObject} range - a range object - */ - /** - * Callback to filter matches - * @callback Mark~markRangesFilterCallback - * @param {HTMLElement} node - The text node which includes the range - * @param {array} range - array of range start and end points - * @param {string} match - string extracted from the matching range - * @param {number} counter - A counter indicating the number of all marks - */ - /** - * These options also include the common options from - * {@link Mark~commonOptions} - * @typedef Mark~markRangesOptions - * @type {object.} - * @property {Mark~markRangesEachCallback} [each] - * @property {Mark~markRangesNoMatchCallback} [noMatch] - * @property {Mark~markRangesFilterCallback} [filter] - */ - /** - * Marks an array of objects containing a start with an end or length of the - * string to mark - * @param {Mark~setOfRanges} rawRanges - The original (preprocessed) - * array of objects - * @param {Mark~markRangesOptions} [opt] - Optional options object - * @access public - */ - markRanges(rawRanges, opt) { - this.opt = opt; - let totalMatches = 0, ranges = this.checkRanges(rawRanges); - if (ranges && ranges.length) { - this.log( - "Starting to mark with the following ranges: " + JSON.stringify(ranges) - ); - this.wrapRangeFromIndex( - ranges, - (node, range, match, counter) => { - return this.opt.filter(node, range, match, counter); - }, - (element, range) => { - totalMatches++; - this.opt.each(element, range); - }, - () => { - this.opt.done(totalMatches); - } - ); - } else { - this.opt.done(totalMatches); - } - } - /** - * Removes all marked elements inside the context with their HTML and - * normalizes the parent at the end - * @param {Mark~commonOptions} [opt] - Optional options object - * @access public - */ - unmark(opt) { - this.opt = opt; - let sel = this.opt.element ? this.opt.element : "*"; - sel += "[data-markjs]"; - if (this.opt.className) { - sel += `.${this.opt.className}`; - } - this.log(`Removal selector "${sel}"`); - this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT, (node) => { - this.unwrapMatches(node); - }, (node) => { - const matchesSel = DOMIterator.matches(node, sel), matchesExclude = this.matchesExclude(node); - if (!matchesSel || matchesExclude) { - return NodeFilter.FILTER_REJECT; - } else { - return NodeFilter.FILTER_ACCEPT; - } - }, this.opt.done); - } -}; - -// node_modules/mark.js/src/vanilla.js -function Mark2(ctx) { - const instance = new Mark(ctx); - this.mark = (sv, opt) => { - instance.mark(sv, opt); - return this; - }; - this.markRegExp = (sv, opt) => { - instance.markRegExp(sv, opt); - return this; - }; - this.markRanges = (sv, opt) => { - instance.markRanges(sv, opt); - return this; - }; - this.unmark = (opt) => { - instance.unmark(opt); - return this; - }; - return this; -} -export { - Mark2 as default -}; -//# sourceMappingURL=vitepress___mark__js_src_vanilla__js.js.map diff --git a/www/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map b/www/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map deleted file mode 100644 index 8c14168..0000000 --- a/www/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../node_modules/mark.js/src/lib/domiterator.js", "../../../../node_modules/mark.js/src/lib/mark.js", "../../../../node_modules/mark.js/src/vanilla.js"], - "sourcesContent": ["/**\n * A NodeIterator with iframes support and a method to check if an element is\n * matching a specified selector\n * @example\n * const iterator = new DOMIterator(\n * document.querySelector(\"#context\"), true\n * );\n * iterator.forEachNode(NodeFilter.SHOW_TEXT, node => {\n * console.log(node);\n * }, node => {\n * if(DOMIterator.matches(node.parentNode, \".ignore\")){\n * return NodeFilter.FILTER_REJECT;\n * } else {\n * return NodeFilter.FILTER_ACCEPT;\n * }\n * }, () => {\n * console.log(\"DONE\");\n * });\n * @todo Outsource into separate repository\n */\nexport default class DOMIterator {\n\n /**\n * @param {HTMLElement|HTMLElement[]|NodeList|string} ctx - The context DOM\n * element, an array of DOM elements, a NodeList or a selector\n * @param {boolean} [iframes=true] - A boolean indicating if iframes should\n * be handled\n * @param {string[]} [exclude=[]] - An array containing exclusion selectors\n * for iframes\n * @param {number} [iframesTimeout=5000] - A number indicating the ms to\n * wait before an iframe should be skipped, in case the load event isn't\n * fired. This also applies if the user is offline and the resource of the\n * iframe is online (either by the browsers \"offline\" mode or because\n * there's no internet connection)\n */\n constructor(ctx, iframes = true, exclude = [], iframesTimeout = 5000) {\n /**\n * The context of the instance. Either a DOM element, an array of DOM\n * elements, a NodeList or a selector\n * @type {HTMLElement|HTMLElement[]|NodeList|string}\n * @access protected\n */\n this.ctx = ctx;\n /**\n * Boolean indicating if iframe support is enabled\n * @type {boolean}\n * @access protected\n */\n this.iframes = iframes;\n /**\n * An array containing exclusion selectors for iframes\n * @type {string[]}\n */\n this.exclude = exclude;\n /**\n * The maximum ms to wait for a load event before skipping an iframe\n * @type {number}\n */\n this.iframesTimeout = iframesTimeout;\n }\n\n /**\n * Checks if the specified DOM element matches the selector\n * @param {HTMLElement} element - The DOM element\n * @param {string|string[]} selector - The selector or an array with\n * selectors\n * @return {boolean}\n * @access public\n */\n static matches(element, selector) {\n const selectors = typeof selector === 'string' ? [selector] : selector,\n fn = (\n element.matches ||\n element.matchesSelector ||\n element.msMatchesSelector ||\n element.mozMatchesSelector ||\n element.oMatchesSelector ||\n element.webkitMatchesSelector\n );\n if (fn) {\n let match = false;\n selectors.every(sel => {\n if (fn.call(element, sel)) {\n match = true;\n return false;\n }\n return true;\n });\n return match;\n } else { // may be false e.g. when el is a textNode\n return false;\n }\n }\n\n /**\n * Returns all contexts filtered by duplicates (even nested)\n * @return {HTMLElement[]} - An array containing DOM contexts\n * @access protected\n */\n getContexts() {\n let ctx,\n filteredCtx = [];\n if (typeof this.ctx === 'undefined' || !this.ctx) { // e.g. null\n ctx = [];\n } else if (NodeList.prototype.isPrototypeOf(this.ctx)) {\n ctx = Array.prototype.slice.call(this.ctx);\n } else if (Array.isArray(this.ctx)) {\n ctx = this.ctx;\n } else if (typeof this.ctx === 'string') {\n ctx = Array.prototype.slice.call(\n document.querySelectorAll(this.ctx)\n );\n } else { // e.g. HTMLElement or element inside iframe\n ctx = [this.ctx];\n }\n // filter duplicate text nodes\n ctx.forEach(ctx => {\n const isDescendant = filteredCtx.filter(contexts => {\n return contexts.contains(ctx);\n }).length > 0;\n if (filteredCtx.indexOf(ctx) === -1 && !isDescendant) {\n filteredCtx.push(ctx);\n }\n });\n return filteredCtx;\n }\n\n /**\n * @callback DOMIterator~getIframeContentsSuccessCallback\n * @param {HTMLDocument} contents - The contentDocument of the iframe\n */\n /**\n * Calls the success callback function with the iframe document. If it can't\n * be accessed it calls the error callback function\n * @param {HTMLElement} ifr - The iframe DOM element\n * @param {DOMIterator~getIframeContentsSuccessCallback} successFn\n * @param {function} [errorFn]\n * @access protected\n */\n getIframeContents(ifr, successFn, errorFn = () => {}) {\n let doc;\n try {\n const ifrWin = ifr.contentWindow;\n doc = ifrWin.document;\n if (!ifrWin || !doc) { // no permission = null. Undefined in Phantom\n throw new Error('iframe inaccessible');\n }\n } catch (e) {\n errorFn();\n }\n if (doc) {\n successFn(doc);\n }\n }\n\n /**\n * Checks if an iframe is empty (if about:blank is the shown page)\n * @param {HTMLElement} ifr - The iframe DOM element\n * @return {boolean}\n * @access protected\n */\n isIframeBlank(ifr) {\n const bl = 'about:blank',\n src = ifr.getAttribute('src').trim(),\n href = ifr.contentWindow.location.href;\n return href === bl && src !== bl && src;\n }\n\n /**\n * Observes the onload event of an iframe and calls the success callback or\n * the error callback if the iframe is inaccessible. If the event isn't\n * fired within the specified {@link DOMIterator#iframesTimeout}, then it'll\n * call the error callback too\n * @param {HTMLElement} ifr - The iframe DOM element\n * @param {DOMIterator~getIframeContentsSuccessCallback} successFn\n * @param {function} errorFn\n * @access protected\n */\n observeIframeLoad(ifr, successFn, errorFn) {\n let called = false,\n tout = null;\n const listener = () => {\n if (called) {\n return;\n }\n called = true;\n clearTimeout(tout);\n try {\n if (!this.isIframeBlank(ifr)) {\n ifr.removeEventListener('load', listener);\n this.getIframeContents(ifr, successFn, errorFn);\n }\n } catch (e) { // isIframeBlank maybe throws throws an error\n errorFn();\n }\n };\n ifr.addEventListener('load', listener);\n tout = setTimeout(listener, this.iframesTimeout);\n }\n\n /**\n * Callback when the iframe is ready\n * @callback DOMIterator~onIframeReadySuccessCallback\n * @param {HTMLDocument} contents - The contentDocument of the iframe\n */\n /**\n * Callback if the iframe can't be accessed\n * @callback DOMIterator~onIframeReadyErrorCallback\n */\n /**\n * Calls the callback if the specified iframe is ready for DOM access\n * @param {HTMLElement} ifr - The iframe DOM element\n * @param {DOMIterator~onIframeReadySuccessCallback} successFn - Success\n * callback\n * @param {DOMIterator~onIframeReadyErrorCallback} errorFn - Error callback\n * @see {@link http://stackoverflow.com/a/36155560/3894981} for\n * background information\n * @access protected\n */\n onIframeReady(ifr, successFn, errorFn) {\n try {\n if (ifr.contentWindow.document.readyState === 'complete') {\n if (this.isIframeBlank(ifr)) {\n this.observeIframeLoad(ifr, successFn, errorFn);\n } else {\n this.getIframeContents(ifr, successFn, errorFn);\n }\n } else {\n this.observeIframeLoad(ifr, successFn, errorFn);\n }\n } catch (e) { // accessing document failed\n errorFn();\n }\n }\n\n /**\n * Callback when all iframes are ready for DOM access\n * @callback DOMIterator~waitForIframesDoneCallback\n */\n /**\n * Iterates over all iframes and calls the done callback when all of them\n * are ready for DOM access (including nested ones)\n * @param {HTMLElement} ctx - The context DOM element\n * @param {DOMIterator~waitForIframesDoneCallback} done - Done callback\n */\n waitForIframes(ctx, done) {\n let eachCalled = 0;\n this.forEachIframe(ctx, () => true, ifr => {\n eachCalled++;\n this.waitForIframes(ifr.querySelector('html'), () => {\n if (!(--eachCalled)) {\n done();\n }\n });\n }, handled => {\n if (!handled) {\n done();\n }\n });\n }\n\n /**\n * Callback allowing to filter an iframe. Must return true when the element\n * should remain, otherwise false\n * @callback DOMIterator~forEachIframeFilterCallback\n * @param {HTMLElement} iframe - The iframe DOM element\n */\n /**\n * Callback for each iframe content\n * @callback DOMIterator~forEachIframeEachCallback\n * @param {HTMLElement} content - The iframe document\n */\n /**\n * Callback if all iframes inside the context were handled\n * @callback DOMIterator~forEachIframeEndCallback\n * @param {number} handled - The number of handled iframes (those who\n * wheren't filtered)\n */\n /**\n * Iterates over all iframes inside the specified context and calls the\n * callbacks when they're ready. Filters iframes based on the instance\n * exclusion selectors\n * @param {HTMLElement} ctx - The context DOM element\n * @param {DOMIterator~forEachIframeFilterCallback} filter - Filter callback\n * @param {DOMIterator~forEachIframeEachCallback} each - Each callback\n * @param {DOMIterator~forEachIframeEndCallback} [end] - End callback\n * @access protected\n */\n forEachIframe(ctx, filter, each, end = () => {}) {\n let ifr = ctx.querySelectorAll('iframe'),\n open = ifr.length,\n handled = 0;\n ifr = Array.prototype.slice.call(ifr);\n const checkEnd = () => {\n if (--open <= 0) {\n end(handled);\n }\n };\n if (!open) {\n checkEnd();\n }\n ifr.forEach(ifr => {\n if (DOMIterator.matches(ifr, this.exclude)) {\n checkEnd();\n } else {\n this.onIframeReady(ifr, con => {\n if (filter(ifr)) {\n handled++;\n each(con);\n }\n checkEnd();\n }, checkEnd);\n }\n });\n }\n\n /**\n * Creates a NodeIterator on the specified context\n * @see {@link https://developer.mozilla.org/en/docs/Web/API/NodeIterator}\n * @param {HTMLElement} ctx - The context DOM element\n * @param {DOMIterator~whatToShow} whatToShow\n * @param {DOMIterator~filterCb} filter\n * @return {NodeIterator}\n * @access protected\n */\n createIterator(ctx, whatToShow, filter) {\n return document.createNodeIterator(ctx, whatToShow, filter, false);\n }\n\n /**\n * Creates an instance of DOMIterator in an iframe\n * @param {HTMLDocument} contents - Iframe document\n * @return {DOMIterator}\n * @access protected\n */\n createInstanceOnIframe(contents) {\n return new DOMIterator(contents.querySelector('html'), this.iframes);\n }\n\n /**\n * Checks if an iframe occurs between two nodes, more specifically if an\n * iframe occurs before the specified node and after the specified prevNode\n * @param {HTMLElement} node - The node that should occur after the iframe\n * @param {HTMLElement} prevNode - The node that should occur before the\n * iframe\n * @param {HTMLElement} ifr - The iframe to check against\n * @return {boolean}\n * @access protected\n */\n compareNodeIframe(node, prevNode, ifr) {\n const compCurr = node.compareDocumentPosition(ifr),\n prev = Node.DOCUMENT_POSITION_PRECEDING;\n if (compCurr & prev) {\n if (prevNode !== null) {\n const compPrev = prevNode.compareDocumentPosition(ifr),\n after = Node.DOCUMENT_POSITION_FOLLOWING;\n if (compPrev & after) {\n return true;\n }\n } else {\n return true;\n }\n }\n return false;\n }\n\n /**\n * @typedef {DOMIterator~getIteratorNodeReturn}\n * @type {object.}\n * @property {HTMLElement} prevNode - The previous node or null if there is\n * no\n * @property {HTMLElement} node - The current node\n */\n /**\n * Returns the previous and current node of the specified iterator\n * @param {NodeIterator} itr - The iterator\n * @return {DOMIterator~getIteratorNodeReturn}\n * @access protected\n */\n getIteratorNode(itr) {\n const prevNode = itr.previousNode();\n let node;\n if (prevNode === null) {\n node = itr.nextNode();\n } else {\n node = itr.nextNode() && itr.nextNode();\n }\n return {\n prevNode,\n node\n };\n }\n\n /**\n * An array containing objects. The object key \"val\" contains an iframe\n * DOM element. The object key \"handled\" contains a boolean indicating if\n * the iframe was handled already.\n * It wouldn't be enough to save all open or all already handled iframes.\n * The information of open iframes is necessary because they may occur after\n * all other text nodes (and compareNodeIframe would never be true). The\n * information of already handled iframes is necessary as otherwise they may\n * be handled multiple times\n * @typedef DOMIterator~checkIframeFilterIfr\n * @type {object[]}\n */\n /**\n * Checks if an iframe wasn't handled already and if so, calls\n * {@link DOMIterator#compareNodeIframe} to check if it should be handled.\n * Information wheter an iframe was or wasn't handled is given within the\n * ifr dictionary\n * @param {HTMLElement} node - The node that should occur after the iframe\n * @param {HTMLElement} prevNode - The node that should occur before the\n * iframe\n * @param {HTMLElement} currIfr - The iframe to check\n * @param {DOMIterator~checkIframeFilterIfr} ifr - The iframe dictionary.\n * Will be manipulated (by reference)\n * @return {boolean} Returns true when it should be handled, otherwise false\n * @access protected\n */\n checkIframeFilter(node, prevNode, currIfr, ifr) {\n let key = false, // false === doesn't exist\n handled = false;\n ifr.forEach((ifrDict, i) => {\n if (ifrDict.val === currIfr) {\n key = i;\n handled = ifrDict.handled;\n }\n });\n if (this.compareNodeIframe(node, prevNode, currIfr)) {\n if (key === false && !handled) {\n ifr.push({\n val: currIfr,\n handled: true\n });\n } else if (key !== false && !handled) {\n ifr[key].handled = true;\n }\n return true;\n }\n if (key === false) {\n ifr.push({\n val: currIfr,\n handled: false\n });\n }\n return false;\n }\n\n /**\n * Creates an iterator on all open iframes in the specified array and calls\n * the end callback when finished\n * @param {DOMIterator~checkIframeFilterIfr} ifr\n * @param {DOMIterator~whatToShow} whatToShow\n * @param {DOMIterator~forEachNodeCallback} eCb - Each callback\n * @param {DOMIterator~filterCb} fCb\n * @access protected\n */\n handleOpenIframes(ifr, whatToShow, eCb, fCb) {\n ifr.forEach(ifrDict => {\n if (!ifrDict.handled) {\n this.getIframeContents(ifrDict.val, con => {\n this.createInstanceOnIframe(con).forEachNode(\n whatToShow, eCb, fCb\n );\n });\n }\n });\n }\n\n /**\n * Iterates through all nodes in the specified context and handles iframe\n * nodes at the correct position\n * @param {DOMIterator~whatToShow} whatToShow\n * @param {HTMLElement} ctx - The context\n * @param {DOMIterator~forEachNodeCallback} eachCb - Each callback\n * @param {DOMIterator~filterCb} filterCb - Filter callback\n * @param {DOMIterator~forEachNodeEndCallback} doneCb - End callback\n * @access protected\n */\n iterateThroughNodes(whatToShow, ctx, eachCb, filterCb, doneCb) {\n const itr = this.createIterator(ctx, whatToShow, filterCb);\n let ifr = [],\n elements = [],\n node, prevNode, retrieveNodes = () => {\n ({\n prevNode,\n node\n } = this.getIteratorNode(itr));\n return node;\n };\n while (retrieveNodes()) {\n if (this.iframes) {\n this.forEachIframe(ctx, currIfr => {\n // note that ifr will be manipulated here\n return this.checkIframeFilter(node, prevNode, currIfr, ifr);\n }, con => {\n this.createInstanceOnIframe(con).forEachNode(\n whatToShow, ifrNode => elements.push(ifrNode), filterCb\n );\n });\n }\n // it's faster to call the each callback in an array loop\n // than in this while loop\n elements.push(node);\n }\n elements.forEach(node => {\n eachCb(node);\n });\n if (this.iframes) {\n this.handleOpenIframes(ifr, whatToShow, eachCb, filterCb);\n }\n doneCb();\n }\n\n /**\n * Callback for each node\n * @callback DOMIterator~forEachNodeCallback\n * @param {HTMLElement} node - The DOM text node element\n */\n /**\n * Callback if all contexts were handled\n * @callback DOMIterator~forEachNodeEndCallback\n */\n /**\n * Iterates over all contexts and initializes\n * {@link DOMIterator#iterateThroughNodes iterateThroughNodes} on them\n * @param {DOMIterator~whatToShow} whatToShow\n * @param {DOMIterator~forEachNodeCallback} each - Each callback\n * @param {DOMIterator~filterCb} filter - Filter callback\n * @param {DOMIterator~forEachNodeEndCallback} done - End callback\n * @access public\n */\n forEachNode(whatToShow, each, filter, done = () => {}) {\n const contexts = this.getContexts();\n let open = contexts.length;\n if (!open) {\n done();\n }\n contexts.forEach(ctx => {\n const ready = () => {\n this.iterateThroughNodes(whatToShow, ctx, each, filter, () => {\n if (--open <= 0) { // call end all contexts were handled\n done();\n }\n });\n };\n // wait for iframes to avoid recursive calls, otherwise this would\n // perhaps reach the recursive function call limit with many nodes\n if (this.iframes) {\n this.waitForIframes(ctx, ready);\n } else {\n ready();\n }\n });\n }\n\n /**\n * Callback to filter nodes. Can return e.g. NodeFilter.FILTER_ACCEPT or\n * NodeFilter.FILTER_REJECT\n * @see {@link http://tinyurl.com/zdczmm2}\n * @callback DOMIterator~filterCb\n * @param {HTMLElement} node - The node to filter\n */\n /**\n * @typedef DOMIterator~whatToShow\n * @see {@link http://tinyurl.com/zfqqkx2}\n * @type {number}\n */\n}\n", "import DOMIterator from './domiterator';\n\n/**\n * Marks search terms in DOM elements\n * @example\n * new Mark(document.querySelector(\".context\")).mark(\"lorem ipsum\");\n * @example\n * new Mark(document.querySelector(\".context\")).markRegExp(/lorem/gmi);\n */\nexport default class Mark { // eslint-disable-line no-unused-vars\n\n /**\n * @param {HTMLElement|HTMLElement[]|NodeList|string} ctx - The context DOM\n * element, an array of DOM elements, a NodeList or a selector\n */\n constructor(ctx) {\n /**\n * The context of the instance. Either a DOM element, an array of DOM\n * elements, a NodeList or a selector\n * @type {HTMLElement|HTMLElement[]|NodeList|string}\n * @access protected\n */\n this.ctx = ctx;\n /**\n * Specifies if the current browser is a IE (necessary for the node\n * normalization bug workaround). See {@link Mark#unwrapMatches}\n * @type {boolean}\n * @access protected\n */\n this.ie = false;\n const ua = window.navigator.userAgent;\n if (ua.indexOf('MSIE') > -1 || ua.indexOf('Trident') > -1) {\n this.ie = true;\n }\n }\n\n /**\n * Options defined by the user. They will be initialized from one of the\n * public methods. See {@link Mark#mark}, {@link Mark#markRegExp},\n * {@link Mark#markRanges} and {@link Mark#unmark} for option properties.\n * @type {object}\n * @param {object} [val] - An object that will be merged with defaults\n * @access protected\n */\n set opt(val) {\n this._opt = Object.assign({}, {\n 'element': '',\n 'className': '',\n 'exclude': [],\n 'iframes': false,\n 'iframesTimeout': 5000,\n 'separateWordSearch': true,\n 'diacritics': true,\n 'synonyms': {},\n 'accuracy': 'partially',\n 'acrossElements': false,\n 'caseSensitive': false,\n 'ignoreJoiners': false,\n 'ignoreGroups': 0,\n 'ignorePunctuation': [],\n 'wildcards': 'disabled',\n 'each': () => {},\n 'noMatch': () => {},\n 'filter': () => true,\n 'done': () => {},\n 'debug': false,\n 'log': window.console\n }, val);\n }\n\n get opt() {\n return this._opt;\n }\n\n /**\n * An instance of DOMIterator\n * @type {DOMIterator}\n * @access protected\n */\n get iterator() {\n // always return new instance in case there were option changes\n return new DOMIterator(\n this.ctx,\n this.opt.iframes,\n this.opt.exclude,\n this.opt.iframesTimeout\n );\n }\n\n /**\n * Logs a message if log is enabled\n * @param {string} msg - The message to log\n * @param {string} [level=\"debug\"] - The log level, e.g. warn\n * error, debug\n * @access protected\n */\n log(msg, level = 'debug') {\n const log = this.opt.log;\n if (!this.opt.debug) {\n return;\n }\n if (typeof log === 'object' && typeof log[level] === 'function') {\n log[level](`mark.js: ${msg}`);\n }\n }\n\n /**\n * Escapes a string for usage within a regular expression\n * @param {string} str - The string to escape\n * @return {string}\n * @access protected\n */\n escapeStr(str) {\n // eslint-disable-next-line no-useless-escape\n return str.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, '\\\\$&');\n }\n\n /**\n * Creates a regular expression string to match the specified search\n * term including synonyms, diacritics and accuracy if defined\n * @param {string} str - The search term to be used\n * @return {string}\n * @access protected\n */\n createRegExp(str) {\n if (this.opt.wildcards !== 'disabled') {\n str = this.setupWildcardsRegExp(str);\n }\n str = this.escapeStr(str);\n if (Object.keys(this.opt.synonyms).length) {\n str = this.createSynonymsRegExp(str);\n }\n if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {\n str = this.setupIgnoreJoinersRegExp(str);\n }\n if (this.opt.diacritics) {\n str = this.createDiacriticsRegExp(str);\n }\n str = this.createMergedBlanksRegExp(str);\n if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {\n str = this.createJoinersRegExp(str);\n }\n if (this.opt.wildcards !== 'disabled') {\n str = this.createWildcardsRegExp(str);\n }\n str = this.createAccuracyRegExp(str);\n return str;\n }\n\n /**\n * Creates a regular expression string to match the defined synonyms\n * @param {string} str - The search term to be used\n * @return {string}\n * @access protected\n */\n createSynonymsRegExp(str) {\n const syn = this.opt.synonyms,\n sens = this.opt.caseSensitive ? '' : 'i',\n // add replacement character placeholder before and after the\n // synonym group\n joinerPlaceholder = this.opt.ignoreJoiners ||\n this.opt.ignorePunctuation.length ? '\\u0000' : '';\n for (let index in syn) {\n if (syn.hasOwnProperty(index)) {\n const value = syn[index],\n k1 = this.opt.wildcards !== 'disabled' ?\n this.setupWildcardsRegExp(index) :\n this.escapeStr(index),\n k2 = this.opt.wildcards !== 'disabled' ?\n this.setupWildcardsRegExp(value) :\n this.escapeStr(value);\n if (k1 !== '' && k2 !== '') {\n str = str.replace(\n new RegExp(\n `(${this.escapeStr(k1)}|${this.escapeStr(k2)})`,\n `gm${sens}`\n ),\n joinerPlaceholder +\n `(${this.processSynomyms(k1)}|` +\n `${this.processSynomyms(k2)})` +\n joinerPlaceholder\n );\n }\n }\n }\n return str;\n }\n\n /**\n * Setup synonyms to work with ignoreJoiners and or ignorePunctuation\n * @param {string} str - synonym key or value to process\n * @return {string} - processed synonym string\n */\n processSynomyms(str) {\n if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {\n str = this.setupIgnoreJoinersRegExp(str);\n }\n return str;\n }\n\n /**\n * Sets up the regular expression string to allow later insertion of\n * wildcard regular expression matches\n * @param {string} str - The search term to be used\n * @return {string}\n * @access protected\n */\n setupWildcardsRegExp(str) {\n // replace single character wildcard with unicode 0001\n str = str.replace(/(?:\\\\)*\\?/g, val => {\n return val.charAt(0) === '\\\\' ? '?' : '\\u0001';\n });\n // replace multiple character wildcard with unicode 0002\n return str.replace(/(?:\\\\)*\\*/g, val => {\n return val.charAt(0) === '\\\\' ? '*' : '\\u0002';\n });\n }\n\n /**\n * Sets up the regular expression string to allow later insertion of\n * wildcard regular expression matches\n * @param {string} str - The search term to be used\n * @return {string}\n * @access protected\n */\n createWildcardsRegExp(str) {\n // default to \"enable\" (i.e. to not include spaces)\n // \"withSpaces\" uses `[\\\\S\\\\s]` instead of `.` because the latter\n // does not match new line characters\n let spaces = this.opt.wildcards === 'withSpaces';\n return str\n // replace unicode 0001 with a RegExp class to match any single\n // character, or any single non-whitespace character depending\n // on the setting\n .replace(/\\u0001/g, spaces ? '[\\\\S\\\\s]?' : '\\\\S?')\n // replace unicode 0002 with a RegExp class to match zero or\n // more characters, or zero or more non-whitespace characters\n // depending on the setting\n .replace(/\\u0002/g, spaces ? '[\\\\S\\\\s]*?' : '\\\\S*');\n }\n\n /**\n * Sets up the regular expression string to allow later insertion of\n * designated characters (soft hyphens & zero width characters)\n * @param {string} str - The search term to be used\n * @return {string}\n * @access protected\n */\n setupIgnoreJoinersRegExp(str) {\n // adding a \"null\" unicode character as it will not be modified by the\n // other \"create\" regular expression functions\n return str.replace(/[^(|)\\\\]/g, (val, indx, original) => {\n // don't add a null after an opening \"(\", around a \"|\" or before\n // a closing \"(\", or between an escapement (e.g. \\+)\n let nextChar = original.charAt(indx + 1);\n if (/[(|)\\\\]/.test(nextChar) || nextChar === '') {\n return val;\n } else {\n return val + '\\u0000';\n }\n });\n }\n\n /**\n * Creates a regular expression string to allow ignoring of designated\n * characters (soft hyphens, zero width characters & punctuation) based on\n * the specified option values of ignorePunctuation and\n * ignoreJoiners\n * @param {string} str - The search term to be used\n * @return {string}\n * @access protected\n */\n createJoinersRegExp(str) {\n let joiner = [];\n const ignorePunctuation = this.opt.ignorePunctuation;\n if (Array.isArray(ignorePunctuation) && ignorePunctuation.length) {\n joiner.push(this.escapeStr(ignorePunctuation.join('')));\n }\n if (this.opt.ignoreJoiners) {\n // u+00ad = soft hyphen\n // u+200b = zero-width space\n // u+200c = zero-width non-joiner\n // u+200d = zero-width joiner\n joiner.push('\\\\u00ad\\\\u200b\\\\u200c\\\\u200d');\n }\n return joiner.length ?\n str.split(/\\u0000+/).join(`[${joiner.join('')}]*`) :\n str;\n }\n\n /**\n * Creates a regular expression string to match diacritics\n * @param {string} str - The search term to be used\n * @return {string}\n * @access protected\n */\n createDiacriticsRegExp(str) {\n const sens = this.opt.caseSensitive ? '' : 'i',\n dct = this.opt.caseSensitive ? [\n 'aàáảãạăằắẳẵặâầấẩẫậäåāą', 'AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ',\n 'cçćč', 'CÇĆČ', 'dđď', 'DĐĎ',\n 'eèéẻẽẹêềếểễệëěēę', 'EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ',\n 'iìíỉĩịîïī', 'IÌÍỈĨỊÎÏĪ', 'lł', 'LŁ', 'nñňń',\n 'NÑŇŃ', 'oòóỏõọôồốổỗộơởỡớờợöøō', 'OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ',\n 'rř', 'RŘ', 'sšśșş', 'SŠŚȘŞ',\n 'tťțţ', 'TŤȚŢ', 'uùúủũụưừứửữựûüůū', 'UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ',\n 'yýỳỷỹỵÿ', 'YÝỲỶỸỴŸ', 'zžżź', 'ZŽŻŹ'\n ] : [\n 'aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ', 'cçćčCÇĆČ',\n 'dđďDĐĎ', 'eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ',\n 'iìíỉĩịîïīIÌÍỈĨỊÎÏĪ', 'lłLŁ', 'nñňńNÑŇŃ',\n 'oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ', 'rřRŘ',\n 'sšśșşSŠŚȘŞ', 'tťțţTŤȚŢ',\n 'uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ', 'yýỳỷỹỵÿYÝỲỶỸỴŸ', 'zžżźZŽŻŹ'\n ];\n let handled = [];\n str.split('').forEach(ch => {\n dct.every(dct => {\n // Check if the character is inside a diacritics list\n if (dct.indexOf(ch) !== -1) {\n // Check if the related diacritics list was not\n // handled yet\n if (handled.indexOf(dct) > -1) {\n return false;\n }\n // Make sure that the character OR any other\n // character in the diacritics list will be matched\n str = str.replace(\n new RegExp(`[${dct}]`, `gm${sens}`), `[${dct}]`\n );\n handled.push(dct);\n }\n return true;\n });\n });\n return str;\n }\n\n /**\n * Creates a regular expression string that merges whitespace characters\n * including subsequent ones into a single pattern, one or multiple\n * whitespaces\n * @param {string} str - The search term to be used\n * @return {string}\n * @access protected\n */\n createMergedBlanksRegExp(str) {\n return str.replace(/[\\s]+/gmi, '[\\\\s]+');\n }\n\n /**\n * Creates a regular expression string to match the specified string with\n * the defined accuracy. As in the regular expression of \"exactly\" can be\n * a group containing a blank at the beginning, all regular expressions will\n * be created with two groups. The first group can be ignored (may contain\n * the said blank), the second contains the actual match\n * @param {string} str - The searm term to be used\n * @return {str}\n * @access protected\n */\n createAccuracyRegExp(str) {\n const chars = '!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~¡¿';\n let acc = this.opt.accuracy,\n val = typeof acc === 'string' ? acc : acc.value,\n ls = typeof acc === 'string' ? [] : acc.limiters,\n lsJoin = '';\n ls.forEach(limiter => {\n lsJoin += `|${this.escapeStr(limiter)}`;\n });\n switch (val) {\n case 'partially':\n default:\n return `()(${str})`;\n case 'complementary':\n lsJoin = '\\\\s' + (lsJoin ? lsJoin : this.escapeStr(chars));\n return `()([^${lsJoin}]*${str}[^${lsJoin}]*)`;\n case 'exactly':\n return `(^|\\\\s${lsJoin})(${str})(?=$|\\\\s${lsJoin})`;\n }\n }\n\n /**\n * @typedef Mark~separatedKeywords\n * @type {object.}\n * @property {array.} keywords - The list of keywords\n * @property {number} length - The length\n */\n /**\n * Returns a list of keywords dependent on whether separate word search\n * was defined. Also it filters empty keywords\n * @param {array} sv - The array of keywords\n * @return {Mark~separatedKeywords}\n * @access protected\n */\n getSeparatedKeywords(sv) {\n let stack = [];\n sv.forEach(kw => {\n if (!this.opt.separateWordSearch) {\n if (kw.trim() && stack.indexOf(kw) === -1) {\n stack.push(kw);\n }\n } else {\n kw.split(' ').forEach(kwSplitted => {\n if (kwSplitted.trim() && stack.indexOf(kwSplitted) === -1) {\n stack.push(kwSplitted);\n }\n });\n }\n });\n return {\n // sort because of https://git.io/v6USg\n 'keywords': stack.sort((a, b) => {\n return b.length - a.length;\n }),\n 'length': stack.length\n };\n }\n\n /**\n * Check if a value is a number\n * @param {number|string} value - the value to check;\n * numeric strings allowed\n * @return {boolean}\n * @access protected\n */\n isNumeric(value) {\n // http://stackoverflow.com/a/16655847/145346\n // eslint-disable-next-line eqeqeq\n return Number(parseFloat(value)) == value;\n }\n\n /**\n * @typedef Mark~rangeObject\n * @type {object}\n * @property {number} start - The start position within the composite value\n * @property {number} length - The length of the string to mark within the\n * composite value.\n */\n /**\n * @typedef Mark~setOfRanges\n * @type {object[]}\n * @property {Mark~rangeObject}\n */\n /**\n * Returns a processed list of integer offset indexes that do not overlap\n * each other, and remove any string values or additional elements\n * @param {Mark~setOfRanges} array - unprocessed raw array\n * @return {Mark~setOfRanges} - processed array with any invalid entries\n * removed\n * @throws Will throw an error if an array of objects is not passed\n * @access protected\n */\n checkRanges(array) {\n // start and length indexes are included in an array of objects\n // [{start: 0, length: 1}, {start: 4, length: 5}]\n // quick validity check of the first entry only\n if (\n !Array.isArray(array) ||\n Object.prototype.toString.call( array[0] ) !== '[object Object]'\n ) {\n this.log('markRanges() will only accept an array of objects');\n this.opt.noMatch(array);\n return [];\n }\n const stack = [];\n let last = 0;\n array\n // acending sort to ensure there is no overlap in start & end\n // offsets\n .sort((a, b) => {\n return a.start - b.start;\n })\n .forEach(item => {\n let {start, end, valid} = this.callNoMatchOnInvalidRanges(item, last);\n if (valid) {\n // preserve item in case there are extra key:values within\n item.start = start;\n item.length = end - start;\n stack.push(item);\n last = end;\n }\n });\n return stack;\n }\n\n /**\n * @typedef Mark~validObject\n * @type {object}\n * @property {number} start - The start position within the composite value\n * @property {number} end - The calculated end position within the composite\n * value.\n * @property {boolean} valid - boolean value indicating that the start and\n * calculated end range is valid\n */\n /**\n * Initial validation of ranges for markRanges. Preliminary checks are done\n * to ensure the start and length values exist and are not zero or non-\n * numeric\n * @param {Mark~rangeObject} range - the current range object\n * @param {number} last - last index of range\n * @return {Mark~validObject}\n * @access protected\n */\n callNoMatchOnInvalidRanges(range, last) {\n let start, end,\n valid = false;\n if (range && typeof range.start !== 'undefined') {\n start = parseInt(range.start, 10);\n end = start + parseInt(range.length, 10);\n // ignore overlapping values & non-numeric entries\n if (\n this.isNumeric(range.start) &&\n this.isNumeric(range.length) &&\n end - last > 0 &&\n end - start > 0\n ) {\n valid = true;\n } else {\n this.log(\n 'Ignoring invalid or overlapping range: ' +\n `${JSON.stringify(range)}`\n );\n this.opt.noMatch(range);\n }\n } else {\n this.log(`Ignoring invalid range: ${JSON.stringify(range)}`);\n this.opt.noMatch(range);\n }\n return {\n start: start,\n end: end,\n valid: valid\n };\n }\n\n /**\n * Check valid range for markRanges. Check ranges with access to the context\n * string. Range values are double checked, lengths that extend the mark\n * beyond the string length are limitied and ranges containing only\n * whitespace are ignored\n * @param {Mark~rangeObject} range - the current range object\n * @param {number} originalLength - original length of the context string\n * @param {string} string - current content string\n * @return {Mark~validObject}\n * @access protected\n */\n checkWhitespaceRanges(range, originalLength, string) {\n let end,\n valid = true,\n // the max value changes after the DOM is manipulated\n max = string.length,\n // adjust offset to account for wrapped text node\n offset = originalLength - max,\n start = parseInt(range.start, 10) - offset;\n // make sure to stop at max\n start = start > max ? max : start;\n end = start + parseInt(range.length, 10);\n if (end > max) {\n end = max;\n this.log(`End range automatically set to the max value of ${max}`);\n }\n if (start < 0 || end - start < 0 || start > max || end > max) {\n valid = false;\n this.log(`Invalid range: ${JSON.stringify(range)}`);\n this.opt.noMatch(range);\n } else if (string.substring(start, end).replace(/\\s+/g, '') === '') {\n valid = false;\n // whitespace only; even if wrapped it is not visible\n this.log('Skipping whitespace only range: ' +JSON.stringify(range));\n this.opt.noMatch(range);\n }\n return {\n start: start,\n end: end,\n valid: valid\n };\n }\n\n /**\n * @typedef Mark~getTextNodesDict\n * @type {object.}\n * @property {string} value - The composite value of all text nodes\n * @property {object[]} nodes - An array of objects\n * @property {number} nodes.start - The start position within the composite\n * value\n * @property {number} nodes.end - The end position within the composite\n * value\n * @property {HTMLElement} nodes.node - The DOM text node element\n */\n /**\n * Callback\n * @callback Mark~getTextNodesCallback\n * @param {Mark~getTextNodesDict}\n */\n /**\n * Calls the callback with an object containing all text nodes (including\n * iframe text nodes) with start and end positions and the composite value\n * of them (string)\n * @param {Mark~getTextNodesCallback} cb - Callback\n * @access protected\n */\n getTextNodes(cb) {\n let val = '',\n nodes = [];\n this.iterator.forEachNode(NodeFilter.SHOW_TEXT, node => {\n nodes.push({\n start: val.length,\n end: (val += node.textContent).length,\n node\n });\n }, node => {\n if (this.matchesExclude(node.parentNode)) {\n return NodeFilter.FILTER_REJECT;\n } else {\n return NodeFilter.FILTER_ACCEPT;\n }\n }, () => {\n cb({\n value: val,\n nodes: nodes\n });\n });\n }\n\n /**\n * Checks if an element matches any of the specified exclude selectors. Also\n * it checks for elements in which no marks should be performed (e.g.\n * script and style tags) and optionally already marked elements\n * @param {HTMLElement} el - The element to check\n * @return {boolean}\n * @access protected\n */\n matchesExclude(el) {\n return DOMIterator.matches(el, this.opt.exclude.concat([\n // ignores the elements itself, not their childrens (selector *)\n 'script', 'style', 'title', 'head', 'html'\n ]));\n }\n\n /**\n * Wraps the instance element and class around matches that fit the start\n * and end positions within the node\n * @param {HTMLElement} node - The DOM text node\n * @param {number} start - The position where to start wrapping\n * @param {number} end - The position where to end wrapping\n * @return {HTMLElement} Returns the splitted text node that will appear\n * after the wrapped text node\n * @access protected\n */\n wrapRangeInTextNode(node, start, end) {\n const hEl = !this.opt.element ? 'mark' : this.opt.element,\n startNode = node.splitText(start),\n ret = startNode.splitText(end - start);\n let repl = document.createElement(hEl);\n repl.setAttribute('data-markjs', 'true');\n if (this.opt.className) {\n repl.setAttribute('class', this.opt.className);\n }\n repl.textContent = startNode.textContent;\n startNode.parentNode.replaceChild(repl, startNode);\n return ret;\n }\n\n /**\n * @typedef Mark~wrapRangeInMappedTextNodeDict\n * @type {object.}\n * @property {string} value - The composite value of all text nodes\n * @property {object[]} nodes - An array of objects\n * @property {number} nodes.start - The start position within the composite\n * value\n * @property {number} nodes.end - The end position within the composite\n * value\n * @property {HTMLElement} nodes.node - The DOM text node element\n */\n /**\n * Each callback\n * @callback Mark~wrapMatchesEachCallback\n * @param {HTMLElement} node - The wrapped DOM element\n * @param {number} lastIndex - The last matching position within the\n * composite value of text nodes\n */\n /**\n * Filter callback\n * @callback Mark~wrapMatchesFilterCallback\n * @param {HTMLElement} node - The matching text node DOM element\n */\n /**\n * Determines matches by start and end positions using the text node\n * dictionary even across text nodes and calls\n * {@link Mark#wrapRangeInTextNode} to wrap them\n * @param {Mark~wrapRangeInMappedTextNodeDict} dict - The dictionary\n * @param {number} start - The start position of the match\n * @param {number} end - The end position of the match\n * @param {Mark~wrapMatchesFilterCallback} filterCb - Filter callback\n * @param {Mark~wrapMatchesEachCallback} eachCb - Each callback\n * @access protected\n */\n wrapRangeInMappedTextNode(dict, start, end, filterCb, eachCb) {\n // iterate over all text nodes to find the one matching the positions\n dict.nodes.every((n, i) => {\n const sibl = dict.nodes[i + 1];\n if (typeof sibl === 'undefined' || sibl.start > start) {\n if (!filterCb(n.node)) {\n return false;\n }\n // map range from dict.value to text node\n const s = start - n.start,\n e = (end > n.end ? n.end : end) - n.start,\n startStr = dict.value.substr(0, n.start),\n endStr = dict.value.substr(e + n.start);\n n.node = this.wrapRangeInTextNode(n.node, s, e);\n // recalculate positions to also find subsequent matches in the\n // same text node. Necessary as the text node in dict now only\n // contains the splitted part after the wrapped one\n dict.value = startStr + endStr;\n dict.nodes.forEach((k, j) => {\n if (j >= i) {\n if (dict.nodes[j].start > 0 && j !== i) {\n dict.nodes[j].start -= e;\n }\n dict.nodes[j].end -= e;\n }\n });\n end -= e;\n eachCb(n.node.previousSibling, n.start);\n if (end > n.end) {\n start = n.end;\n } else {\n return false;\n }\n }\n return true;\n });\n }\n\n /**\n * Filter callback before each wrapping\n * @callback Mark~wrapMatchesFilterCallback\n * @param {string} match - The matching string\n * @param {HTMLElement} node - The text node where the match occurs\n */\n /**\n * Callback for each wrapped element\n * @callback Mark~wrapMatchesEachCallback\n * @param {HTMLElement} element - The marked DOM element\n */\n /**\n * Callback on end\n * @callback Mark~wrapMatchesEndCallback\n */\n /**\n * Wraps the instance element and class around matches within single HTML\n * elements in all contexts\n * @param {RegExp} regex - The regular expression to be searched for\n * @param {number} ignoreGroups - A number indicating the amount of RegExp\n * matching groups to ignore\n * @param {Mark~wrapMatchesFilterCallback} filterCb\n * @param {Mark~wrapMatchesEachCallback} eachCb\n * @param {Mark~wrapMatchesEndCallback} endCb\n * @access protected\n */\n wrapMatches(regex, ignoreGroups, filterCb, eachCb, endCb) {\n const matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1;\n this.getTextNodes(dict => {\n dict.nodes.forEach(node => {\n node = node.node;\n let match;\n while (\n (match = regex.exec(node.textContent)) !== null &&\n match[matchIdx] !== ''\n ) {\n if (!filterCb(match[matchIdx], node)) {\n continue;\n }\n let pos = match.index;\n if (matchIdx !== 0) {\n for (let i = 1; i < matchIdx; i++) {\n pos += match[i].length;\n }\n }\n node = this.wrapRangeInTextNode(\n node,\n pos,\n pos + match[matchIdx].length\n );\n eachCb(node.previousSibling);\n // reset index of last match as the node changed and the\n // index isn't valid anymore http://tinyurl.com/htsudjd\n regex.lastIndex = 0;\n }\n });\n endCb();\n });\n }\n\n /**\n * Callback for each wrapped element\n * @callback Mark~wrapMatchesAcrossElementsEachCallback\n * @param {HTMLElement} element - The marked DOM element\n */\n /**\n * Filter callback before each wrapping\n * @callback Mark~wrapMatchesAcrossElementsFilterCallback\n * @param {string} match - The matching string\n * @param {HTMLElement} node - The text node where the match occurs\n */\n /**\n * Callback on end\n * @callback Mark~wrapMatchesAcrossElementsEndCallback\n */\n /**\n * Wraps the instance element and class around matches across all HTML\n * elements in all contexts\n * @param {RegExp} regex - The regular expression to be searched for\n * @param {number} ignoreGroups - A number indicating the amount of RegExp\n * matching groups to ignore\n * @param {Mark~wrapMatchesAcrossElementsFilterCallback} filterCb\n * @param {Mark~wrapMatchesAcrossElementsEachCallback} eachCb\n * @param {Mark~wrapMatchesAcrossElementsEndCallback} endCb\n * @access protected\n */\n wrapMatchesAcrossElements(regex, ignoreGroups, filterCb, eachCb, endCb) {\n const matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1;\n this.getTextNodes(dict => {\n let match;\n while (\n (match = regex.exec(dict.value)) !== null &&\n match[matchIdx] !== ''\n ) {\n // calculate range inside dict.value\n let start = match.index;\n if (matchIdx !== 0) {\n for (let i = 1; i < matchIdx; i++) {\n start += match[i].length;\n }\n }\n const end = start + match[matchIdx].length;\n // note that dict will be updated automatically, as it'll change\n // in the wrapping process, due to the fact that text\n // nodes will be splitted\n this.wrapRangeInMappedTextNode(dict, start, end, node => {\n return filterCb(match[matchIdx], node);\n }, (node, lastIndex) => {\n regex.lastIndex = lastIndex;\n eachCb(node);\n });\n }\n endCb();\n });\n }\n\n /**\n * Callback for each wrapped element\n * @callback Mark~wrapRangeFromIndexEachCallback\n * @param {HTMLElement} element - The marked DOM element\n * @param {Mark~rangeObject} range - the current range object; provided\n * start and length values will be numeric integers modified from the\n * provided original ranges.\n */\n /**\n * Filter callback before each wrapping\n * @callback Mark~wrapRangeFromIndexFilterCallback\n * @param {HTMLElement} node - The text node which includes the range\n * @param {Mark~rangeObject} range - the current range object\n * @param {string} match - string extracted from the matching range\n * @param {number} counter - A counter indicating the number of all marks\n */\n /**\n * Callback on end\n * @callback Mark~wrapRangeFromIndexEndCallback\n */\n /**\n * Wraps the indicated ranges across all HTML elements in all contexts\n * @param {Mark~setOfRanges} ranges\n * @param {Mark~wrapRangeFromIndexFilterCallback} filterCb\n * @param {Mark~wrapRangeFromIndexEachCallback} eachCb\n * @param {Mark~wrapRangeFromIndexEndCallback} endCb\n * @access protected\n */\n wrapRangeFromIndex(ranges, filterCb, eachCb, endCb) {\n this.getTextNodes(dict => {\n const originalLength = dict.value.length;\n ranges.forEach((range, counter) => {\n let {start, end, valid} = this.checkWhitespaceRanges(\n range,\n originalLength,\n dict.value\n );\n if (valid) {\n this.wrapRangeInMappedTextNode(dict, start, end, node => {\n return filterCb(\n node,\n range,\n dict.value.substring(start, end),\n counter\n );\n }, node => {\n eachCb(node, range);\n });\n }\n });\n endCb();\n });\n }\n\n /**\n * Unwraps the specified DOM node with its content (text nodes or HTML)\n * without destroying possibly present events (using innerHTML) and\n * normalizes the parent at the end (merge splitted text nodes)\n * @param {HTMLElement} node - The DOM node to unwrap\n * @access protected\n */\n unwrapMatches(node) {\n const parent = node.parentNode;\n let docFrag = document.createDocumentFragment();\n while (node.firstChild) {\n docFrag.appendChild(node.removeChild(node.firstChild));\n }\n parent.replaceChild(docFrag, node);\n if (!this.ie) { // use browser's normalize method\n parent.normalize();\n } else { // custom method (needs more time)\n this.normalizeTextNode(parent);\n }\n }\n\n /**\n * Normalizes text nodes. It's a workaround for the native normalize method\n * that has a bug in IE (see attached link). Should only be used in IE\n * browsers as it's slower than the native method.\n * @see {@link http://tinyurl.com/z5asa8c}\n * @param {HTMLElement} node - The DOM node to normalize\n * @access protected\n */\n normalizeTextNode(node) {\n if (!node) {\n return;\n }\n if (node.nodeType === 3) {\n while (node.nextSibling && node.nextSibling.nodeType === 3) {\n node.nodeValue += node.nextSibling.nodeValue;\n node.parentNode.removeChild(node.nextSibling);\n }\n } else {\n this.normalizeTextNode(node.firstChild);\n }\n this.normalizeTextNode(node.nextSibling);\n }\n\n /**\n * Callback when finished\n * @callback Mark~commonDoneCallback\n * @param {number} totalMatches - The number of marked elements\n */\n /**\n * @typedef Mark~commonOptions\n * @type {object.}\n * @property {string} [element=\"mark\"] - HTML element tag name\n * @property {string} [className] - An optional class name\n * @property {string[]} [exclude] - An array with exclusion selectors.\n * Elements matching those selectors will be ignored\n * @property {boolean} [iframes=false] - Whether to search inside iframes\n * @property {Mark~commonDoneCallback} [done]\n * @property {boolean} [debug=false] - Wheter to log messages\n * @property {object} [log=window.console] - Where to log messages (only if\n * debug is true)\n */\n /**\n * Callback for each marked element\n * @callback Mark~markRegExpEachCallback\n * @param {HTMLElement} element - The marked DOM element\n */\n /**\n * Callback if there were no matches\n * @callback Mark~markRegExpNoMatchCallback\n * @param {RegExp} regexp - The regular expression\n */\n /**\n * Callback to filter matches\n * @callback Mark~markRegExpFilterCallback\n * @param {HTMLElement} textNode - The text node which includes the match\n * @param {string} match - The matching string for the RegExp\n * @param {number} counter - A counter indicating the number of all marks\n */\n /**\n * These options also include the common options from\n * {@link Mark~commonOptions}\n * @typedef Mark~markRegExpOptions\n * @type {object.}\n * @property {Mark~markRegExpEachCallback} [each]\n * @property {Mark~markRegExpNoMatchCallback} [noMatch]\n * @property {Mark~markRegExpFilterCallback} [filter]\n */\n /**\n * Marks a custom regular expression\n * @param {RegExp} regexp - The regular expression\n * @param {Mark~markRegExpOptions} [opt] - Optional options object\n * @access public\n */\n markRegExp(regexp, opt) {\n this.opt = opt;\n this.log(`Searching with expression \"${regexp}\"`);\n let totalMatches = 0,\n fn = 'wrapMatches';\n const eachCb = element => {\n totalMatches++;\n this.opt.each(element);\n };\n if (this.opt.acrossElements) {\n fn = 'wrapMatchesAcrossElements';\n }\n this[fn](regexp, this.opt.ignoreGroups, (match, node) => {\n return this.opt.filter(node, match, totalMatches);\n }, eachCb, () => {\n if (totalMatches === 0) {\n this.opt.noMatch(regexp);\n }\n this.opt.done(totalMatches);\n });\n }\n\n /**\n * Callback for each marked element\n * @callback Mark~markEachCallback\n * @param {HTMLElement} element - The marked DOM element\n */\n /**\n * Callback if there were no matches\n * @callback Mark~markNoMatchCallback\n * @param {RegExp} term - The search term that was not found\n */\n /**\n * Callback to filter matches\n * @callback Mark~markFilterCallback\n * @param {HTMLElement} textNode - The text node which includes the match\n * @param {string} match - The matching term\n * @param {number} totalCounter - A counter indicating the number of all\n * marks\n * @param {number} termCounter - A counter indicating the number of marks\n * for the specific match\n */\n /**\n * @typedef Mark~markAccuracyObject\n * @type {object.}\n * @property {string} value - A accuracy string value\n * @property {string[]} limiters - A custom array of limiters. For example\n * [\"-\", \",\"]\n */\n /**\n * @typedef Mark~markAccuracySetting\n * @type {string}\n * @property {\"partially\"|\"complementary\"|\"exactly\"|Mark~markAccuracyObject}\n * [accuracy=\"partially\"] - Either one of the following string values:\n *
    \n *
  • partially: When searching for \"lor\" only \"lor\" inside\n * \"lorem\" will be marked
  • \n *
  • complementary: When searching for \"lor\" the whole word\n * \"lorem\" will be marked
  • \n *
  • exactly: When searching for \"lor\" only those exact words\n * will be marked. In this example nothing inside \"lorem\". This value\n * is equivalent to the previous option wordBoundary
  • \n *
\n * Or an object containing two properties:\n *
    \n *
  • value: One of the above named string values
  • \n *
  • limiters: A custom array of string limiters for accuracy\n * \"exactly\" or \"complementary\"
  • \n *
\n */\n /**\n * @typedef Mark~markWildcardsSetting\n * @type {string}\n * @property {\"disabled\"|\"enabled\"|\"withSpaces\"}\n * [wildcards=\"disabled\"] - Set to any of the following string values:\n *
    \n *
  • disabled: Disable wildcard usage
  • \n *
  • enabled: When searching for \"lor?m\", the \"?\" will match zero\n * or one non-space character (e.g. \"lorm\", \"loram\", \"lor3m\", etc). When\n * searching for \"lor*m\", the \"*\" will match zero or more non-space\n * characters (e.g. \"lorm\", \"loram\", \"lor123m\", etc).
  • \n *
  • withSpaces: When searching for \"lor?m\", the \"?\" will\n * match zero or one space or non-space character (e.g. \"lor m\", \"loram\",\n * etc). When searching for \"lor*m\", the \"*\" will match zero or more space\n * or non-space characters (e.g. \"lorm\", \"lore et dolor ipsum\", \"lor: m\",\n * etc).
  • \n *
\n */\n /**\n * @typedef Mark~markIgnorePunctuationSetting\n * @type {string[]}\n * @property {string} The strings in this setting will contain punctuation\n * marks that will be ignored:\n *
    \n *
  • These punctuation marks can be between any characters, e.g. setting\n * this option to [\"'\"] would match \"Worlds\", \"World's\" and\n * \"Wo'rlds\"
  • \n *
  • One or more apostrophes between the letters would still produce a\n * match (e.g. \"W'o''r'l'd's\").
  • \n *
  • A typical setting for this option could be as follows:\n *
    ignorePunctuation: \":;.,-–—‒_(){}[]!'\\\"+=\".split(\"\"),
    This\n * setting includes common punctuation as well as a minus, en-dash,\n * em-dash and figure-dash\n * ({@link https://en.wikipedia.org/wiki/Dash#Figure_dash ref}), as well\n * as an underscore.
  • \n *
\n */\n /**\n * These options also include the common options from\n * {@link Mark~commonOptions}\n * @typedef Mark~markOptions\n * @type {object.}\n * @property {boolean} [separateWordSearch=true] - Whether to search for\n * each word separated by a blank instead of the complete term\n * @property {boolean} [diacritics=true] - If diacritic characters should be\n * matched. ({@link https://en.wikipedia.org/wiki/Diacritic Diacritics})\n * @property {object} [synonyms] - An object with synonyms. The key will be\n * a synonym for the value and the value for the key\n * @property {Mark~markAccuracySetting} [accuracy]\n * @property {Mark~markWildcardsSetting} [wildcards]\n * @property {boolean} [acrossElements=false] - Whether to find matches\n * across HTML elements. By default, only matches within single HTML\n * elements will be found\n * @property {boolean} [ignoreJoiners=false] - Whether to ignore word\n * joiners inside of key words. These include soft-hyphens, zero-width\n * space, zero-width non-joiners and zero-width joiners.\n * @property {Mark~markIgnorePunctuationSetting} [ignorePunctuation]\n * @property {Mark~markEachCallback} [each]\n * @property {Mark~markNoMatchCallback} [noMatch]\n * @property {Mark~markFilterCallback} [filter]\n */\n /**\n * Marks the specified search terms\n * @param {string|string[]} [sv] - Search value, either a search string or\n * an array containing multiple search strings\n * @param {Mark~markOptions} [opt] - Optional options object\n * @access public\n */\n mark(sv, opt) {\n this.opt = opt;\n let totalMatches = 0,\n fn = 'wrapMatches';\n\n const {\n keywords: kwArr,\n length: kwArrLen\n } = this.getSeparatedKeywords(typeof sv === 'string' ? [sv] : sv),\n sens = this.opt.caseSensitive ? '' : 'i',\n handler = kw => { // async function calls as iframes are async too\n let regex = new RegExp(this.createRegExp(kw), `gm${sens}`),\n matches = 0;\n this.log(`Searching with expression \"${regex}\"`);\n this[fn](regex, 1, (term, node) => {\n return this.opt.filter(node, kw, totalMatches, matches);\n }, element => {\n matches++;\n totalMatches++;\n this.opt.each(element);\n }, () => {\n if (matches === 0) {\n this.opt.noMatch(kw);\n }\n if (kwArr[kwArrLen - 1] === kw) {\n this.opt.done(totalMatches);\n } else {\n handler(kwArr[kwArr.indexOf(kw) + 1]);\n }\n });\n };\n if (this.opt.acrossElements) {\n fn = 'wrapMatchesAcrossElements';\n }\n if (kwArrLen === 0) {\n this.opt.done(totalMatches);\n } else {\n handler(kwArr[0]);\n }\n }\n\n /**\n * Callback for each marked element\n * @callback Mark~markRangesEachCallback\n * @param {HTMLElement} element - The marked DOM element\n * @param {array} range - array of range start and end points\n */\n /**\n * Callback if a processed range is invalid, out-of-bounds, overlaps another\n * range, or only matches whitespace\n * @callback Mark~markRangesNoMatchCallback\n * @param {Mark~rangeObject} range - a range object\n */\n /**\n * Callback to filter matches\n * @callback Mark~markRangesFilterCallback\n * @param {HTMLElement} node - The text node which includes the range\n * @param {array} range - array of range start and end points\n * @param {string} match - string extracted from the matching range\n * @param {number} counter - A counter indicating the number of all marks\n */\n /**\n * These options also include the common options from\n * {@link Mark~commonOptions}\n * @typedef Mark~markRangesOptions\n * @type {object.}\n * @property {Mark~markRangesEachCallback} [each]\n * @property {Mark~markRangesNoMatchCallback} [noMatch]\n * @property {Mark~markRangesFilterCallback} [filter]\n */\n /**\n * Marks an array of objects containing a start with an end or length of the\n * string to mark\n * @param {Mark~setOfRanges} rawRanges - The original (preprocessed)\n * array of objects\n * @param {Mark~markRangesOptions} [opt] - Optional options object\n * @access public\n */\n markRanges(rawRanges, opt) {\n this.opt = opt;\n let totalMatches = 0,\n ranges = this.checkRanges(rawRanges);\n if (ranges && ranges.length) {\n this.log(\n 'Starting to mark with the following ranges: ' +\n JSON.stringify(ranges)\n );\n this.wrapRangeFromIndex(\n ranges, (node, range, match, counter) => {\n return this.opt.filter(node, range, match, counter);\n }, (element, range) => {\n totalMatches++;\n this.opt.each(element, range);\n }, () => {\n this.opt.done(totalMatches);\n }\n );\n } else {\n this.opt.done(totalMatches);\n }\n }\n\n /**\n * Removes all marked elements inside the context with their HTML and\n * normalizes the parent at the end\n * @param {Mark~commonOptions} [opt] - Optional options object\n * @access public\n */\n unmark(opt) {\n this.opt = opt;\n let sel = this.opt.element ? this.opt.element : '*';\n sel += '[data-markjs]';\n if (this.opt.className) {\n sel += `.${this.opt.className}`;\n }\n this.log(`Removal selector \"${sel}\"`);\n this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT, node => {\n this.unwrapMatches(node);\n }, node => {\n const matchesSel = DOMIterator.matches(node, sel),\n matchesExclude = this.matchesExclude(node);\n if (!matchesSel || matchesExclude) {\n return NodeFilter.FILTER_REJECT;\n } else {\n return NodeFilter.FILTER_ACCEPT;\n }\n }, this.opt.done);\n }\n}\n", "import MarkJS from './lib/mark';\n\nexport default function Mark(ctx) {\n const instance = new MarkJS(ctx);\n this.mark = (sv, opt) => {\n instance.mark(sv, opt);\n return this;\n };\n this.markRegExp = (sv, opt) => {\n instance.markRegExp(sv, opt);\n return this;\n };\n this.markRanges = (sv, opt) => {\n instance.markRanges(sv, opt);\n return this;\n };\n this.unmark = (opt) => {\n instance.unmark(opt);\n return this;\n };\n return this;\n}"], - "mappings": "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", - "names": ["ctx", "ifr", "node", "dct", "Mark"] -} diff --git a/www/docs/.vitepress/cache/deps/vitepress___minisearch.js b/www/docs/.vitepress/cache/deps/vitepress___minisearch.js deleted file mode 100644 index b8b876b..0000000 --- a/www/docs/.vitepress/cache/deps/vitepress___minisearch.js +++ /dev/null @@ -1,1813 +0,0 @@ -// node_modules/minisearch/dist/es/index.js -var ENTRIES = "ENTRIES"; -var KEYS = "KEYS"; -var VALUES = "VALUES"; -var LEAF = ""; -var TreeIterator = class { - constructor(set, type) { - const node = set._tree; - const keys = Array.from(node.keys()); - this.set = set; - this._type = type; - this._path = keys.length > 0 ? [{ node, keys }] : []; - } - next() { - const value = this.dive(); - this.backtrack(); - return value; - } - dive() { - if (this._path.length === 0) { - return { done: true, value: void 0 }; - } - const { node, keys } = last$1(this._path); - if (last$1(keys) === LEAF) { - return { done: false, value: this.result() }; - } - const child = node.get(last$1(keys)); - this._path.push({ node: child, keys: Array.from(child.keys()) }); - return this.dive(); - } - backtrack() { - if (this._path.length === 0) { - return; - } - const keys = last$1(this._path).keys; - keys.pop(); - if (keys.length > 0) { - return; - } - this._path.pop(); - this.backtrack(); - } - key() { - return this.set._prefix + this._path.map(({ keys }) => last$1(keys)).filter((key) => key !== LEAF).join(""); - } - value() { - return last$1(this._path).node.get(LEAF); - } - result() { - switch (this._type) { - case VALUES: - return this.value(); - case KEYS: - return this.key(); - default: - return [this.key(), this.value()]; - } - } - [Symbol.iterator]() { - return this; - } -}; -var last$1 = (array) => { - return array[array.length - 1]; -}; -var fuzzySearch = (node, query, maxDistance) => { - const results = /* @__PURE__ */ new Map(); - if (query === void 0) - return results; - const n = query.length + 1; - const m = n + maxDistance; - const matrix = new Uint8Array(m * n).fill(maxDistance + 1); - for (let j = 0; j < n; ++j) - matrix[j] = j; - for (let i = 1; i < m; ++i) - matrix[i * n] = i; - recurse(node, query, maxDistance, results, matrix, 1, n, ""); - return results; -}; -var recurse = (node, query, maxDistance, results, matrix, m, n, prefix) => { - const offset = m * n; - key: for (const key of node.keys()) { - if (key === LEAF) { - const distance = matrix[offset - 1]; - if (distance <= maxDistance) { - results.set(prefix, [node.get(key), distance]); - } - } else { - let i = m; - for (let pos = 0; pos < key.length; ++pos, ++i) { - const char = key[pos]; - const thisRowOffset = n * i; - const prevRowOffset = thisRowOffset - n; - let minDistance = matrix[thisRowOffset]; - const jmin = Math.max(0, i - maxDistance - 1); - const jmax = Math.min(n - 1, i + maxDistance); - for (let j = jmin; j < jmax; ++j) { - const different = char !== query[j]; - const rpl = matrix[prevRowOffset + j] + +different; - const del = matrix[prevRowOffset + j + 1] + 1; - const ins = matrix[thisRowOffset + j] + 1; - const dist = matrix[thisRowOffset + j + 1] = Math.min(rpl, del, ins); - if (dist < minDistance) - minDistance = dist; - } - if (minDistance > maxDistance) { - continue key; - } - } - recurse(node.get(key), query, maxDistance, results, matrix, i, n, prefix + key); - } - } -}; -var SearchableMap = class _SearchableMap { - /** - * The constructor is normally called without arguments, creating an empty - * map. In order to create a {@link SearchableMap} from an iterable or from an - * object, check {@link SearchableMap.from} and {@link - * SearchableMap.fromObject}. - * - * The constructor arguments are for internal use, when creating derived - * mutable views of a map at a prefix. - */ - constructor(tree = /* @__PURE__ */ new Map(), prefix = "") { - this._size = void 0; - this._tree = tree; - this._prefix = prefix; - } - /** - * Creates and returns a mutable view of this {@link SearchableMap}, - * containing only entries that share the given prefix. - * - * ### Usage: - * - * ```javascript - * let map = new SearchableMap() - * map.set("unicorn", 1) - * map.set("universe", 2) - * map.set("university", 3) - * map.set("unique", 4) - * map.set("hello", 5) - * - * let uni = map.atPrefix("uni") - * uni.get("unique") // => 4 - * uni.get("unicorn") // => 1 - * uni.get("hello") // => undefined - * - * let univer = map.atPrefix("univer") - * univer.get("unique") // => undefined - * univer.get("universe") // => 2 - * univer.get("university") // => 3 - * ``` - * - * @param prefix The prefix - * @return A {@link SearchableMap} representing a mutable view of the original - * Map at the given prefix - */ - atPrefix(prefix) { - if (!prefix.startsWith(this._prefix)) { - throw new Error("Mismatched prefix"); - } - const [node, path] = trackDown(this._tree, prefix.slice(this._prefix.length)); - if (node === void 0) { - const [parentNode, key] = last(path); - for (const k of parentNode.keys()) { - if (k !== LEAF && k.startsWith(key)) { - const node2 = /* @__PURE__ */ new Map(); - node2.set(k.slice(key.length), parentNode.get(k)); - return new _SearchableMap(node2, prefix); - } - } - } - return new _SearchableMap(node, prefix); - } - /** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear - */ - clear() { - this._size = void 0; - this._tree.clear(); - } - /** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete - * @param key Key to delete - */ - delete(key) { - this._size = void 0; - return remove(this._tree, key); - } - /** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries - * @return An iterator iterating through `[key, value]` entries. - */ - entries() { - return new TreeIterator(this, ENTRIES); - } - /** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach - * @param fn Iteration function - */ - forEach(fn) { - for (const [key, value] of this) { - fn(key, value, this); - } - } - /** - * Returns a Map of all the entries that have a key within the given edit - * distance from the search key. The keys of the returned Map are the matching - * keys, while the values are two-element arrays where the first element is - * the value associated to the key, and the second is the edit distance of the - * key to the search key. - * - * ### Usage: - * - * ```javascript - * let map = new SearchableMap() - * map.set('hello', 'world') - * map.set('hell', 'yeah') - * map.set('ciao', 'mondo') - * - * // Get all entries that match the key 'hallo' with a maximum edit distance of 2 - * map.fuzzyGet('hallo', 2) - * // => Map(2) { 'hello' => ['world', 1], 'hell' => ['yeah', 2] } - * - * // In the example, the "hello" key has value "world" and edit distance of 1 - * // (change "e" to "a"), the key "hell" has value "yeah" and edit distance of 2 - * // (change "e" to "a", delete "o") - * ``` - * - * @param key The search key - * @param maxEditDistance The maximum edit distance (Levenshtein) - * @return A Map of the matching keys to their value and edit distance - */ - fuzzyGet(key, maxEditDistance) { - return fuzzySearch(this._tree, key, maxEditDistance); - } - /** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get - * @param key Key to get - * @return Value associated to the key, or `undefined` if the key is not - * found. - */ - get(key) { - const node = lookup(this._tree, key); - return node !== void 0 ? node.get(LEAF) : void 0; - } - /** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has - * @param key Key - * @return True if the key is in the map, false otherwise - */ - has(key) { - const node = lookup(this._tree, key); - return node !== void 0 && node.has(LEAF); - } - /** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys - * @return An `Iterable` iterating through keys - */ - keys() { - return new TreeIterator(this, KEYS); - } - /** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set - * @param key Key to set - * @param value Value to associate to the key - * @return The {@link SearchableMap} itself, to allow chaining - */ - set(key, value) { - if (typeof key !== "string") { - throw new Error("key must be a string"); - } - this._size = void 0; - const node = createPath(this._tree, key); - node.set(LEAF, value); - return this; - } - /** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size - */ - get size() { - if (this._size) { - return this._size; - } - this._size = 0; - const iter = this.entries(); - while (!iter.next().done) - this._size += 1; - return this._size; - } - /** - * Updates the value at the given key using the provided function. The function - * is called with the current value at the key, and its return value is used as - * the new value to be set. - * - * ### Example: - * - * ```javascript - * // Increment the current value by one - * searchableMap.update('somekey', (currentValue) => currentValue == null ? 0 : currentValue + 1) - * ``` - * - * If the value at the given key is or will be an object, it might not require - * re-assignment. In that case it is better to use `fetch()`, because it is - * faster. - * - * @param key The key to update - * @param fn The function used to compute the new value from the current one - * @return The {@link SearchableMap} itself, to allow chaining - */ - update(key, fn) { - if (typeof key !== "string") { - throw new Error("key must be a string"); - } - this._size = void 0; - const node = createPath(this._tree, key); - node.set(LEAF, fn(node.get(LEAF))); - return this; - } - /** - * Fetches the value of the given key. If the value does not exist, calls the - * given function to create a new value, which is inserted at the given key - * and subsequently returned. - * - * ### Example: - * - * ```javascript - * const map = searchableMap.fetch('somekey', () => new Map()) - * map.set('foo', 'bar') - * ``` - * - * @param key The key to update - * @param initial A function that creates a new value if the key does not exist - * @return The existing or new value at the given key - */ - fetch(key, initial) { - if (typeof key !== "string") { - throw new Error("key must be a string"); - } - this._size = void 0; - const node = createPath(this._tree, key); - let value = node.get(LEAF); - if (value === void 0) { - node.set(LEAF, value = initial()); - } - return value; - } - /** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values - * @return An `Iterable` iterating through values. - */ - values() { - return new TreeIterator(this, VALUES); - } - /** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@iterator - */ - [Symbol.iterator]() { - return this.entries(); - } - /** - * Creates a {@link SearchableMap} from an `Iterable` of entries - * - * @param entries Entries to be inserted in the {@link SearchableMap} - * @return A new {@link SearchableMap} with the given entries - */ - static from(entries) { - const tree = new _SearchableMap(); - for (const [key, value] of entries) { - tree.set(key, value); - } - return tree; - } - /** - * Creates a {@link SearchableMap} from the iterable properties of a JavaScript object - * - * @param object Object of entries for the {@link SearchableMap} - * @return A new {@link SearchableMap} with the given entries - */ - static fromObject(object) { - return _SearchableMap.from(Object.entries(object)); - } -}; -var trackDown = (tree, key, path = []) => { - if (key.length === 0 || tree == null) { - return [tree, path]; - } - for (const k of tree.keys()) { - if (k !== LEAF && key.startsWith(k)) { - path.push([tree, k]); - return trackDown(tree.get(k), key.slice(k.length), path); - } - } - path.push([tree, key]); - return trackDown(void 0, "", path); -}; -var lookup = (tree, key) => { - if (key.length === 0 || tree == null) { - return tree; - } - for (const k of tree.keys()) { - if (k !== LEAF && key.startsWith(k)) { - return lookup(tree.get(k), key.slice(k.length)); - } - } -}; -var createPath = (node, key) => { - const keyLength = key.length; - outer: for (let pos = 0; node && pos < keyLength; ) { - for (const k of node.keys()) { - if (k !== LEAF && key[pos] === k[0]) { - const len = Math.min(keyLength - pos, k.length); - let offset = 1; - while (offset < len && key[pos + offset] === k[offset]) - ++offset; - const child2 = node.get(k); - if (offset === k.length) { - node = child2; - } else { - const intermediate = /* @__PURE__ */ new Map(); - intermediate.set(k.slice(offset), child2); - node.set(key.slice(pos, pos + offset), intermediate); - node.delete(k); - node = intermediate; - } - pos += offset; - continue outer; - } - } - const child = /* @__PURE__ */ new Map(); - node.set(key.slice(pos), child); - return child; - } - return node; -}; -var remove = (tree, key) => { - const [node, path] = trackDown(tree, key); - if (node === void 0) { - return; - } - node.delete(LEAF); - if (node.size === 0) { - cleanup(path); - } else if (node.size === 1) { - const [key2, value] = node.entries().next().value; - merge(path, key2, value); - } -}; -var cleanup = (path) => { - if (path.length === 0) { - return; - } - const [node, key] = last(path); - node.delete(key); - if (node.size === 0) { - cleanup(path.slice(0, -1)); - } else if (node.size === 1) { - const [key2, value] = node.entries().next().value; - if (key2 !== LEAF) { - merge(path.slice(0, -1), key2, value); - } - } -}; -var merge = (path, key, value) => { - if (path.length === 0) { - return; - } - const [node, nodeKey] = last(path); - node.set(nodeKey + key, value); - node.delete(nodeKey); -}; -var last = (array) => { - return array[array.length - 1]; -}; -var OR = "or"; -var AND = "and"; -var AND_NOT = "and_not"; -var MiniSearch = class _MiniSearch { - /** - * @param options Configuration options - * - * ### Examples: - * - * ```javascript - * // Create a search engine that indexes the 'title' and 'text' fields of your - * // documents: - * const miniSearch = new MiniSearch({ fields: ['title', 'text'] }) - * ``` - * - * ### ID Field: - * - * ```javascript - * // Your documents are assumed to include a unique 'id' field, but if you want - * // to use a different field for document identification, you can set the - * // 'idField' option: - * const miniSearch = new MiniSearch({ idField: 'key', fields: ['title', 'text'] }) - * ``` - * - * ### Options and defaults: - * - * ```javascript - * // The full set of options (here with their default value) is: - * const miniSearch = new MiniSearch({ - * // idField: field that uniquely identifies a document - * idField: 'id', - * - * // extractField: function used to get the value of a field in a document. - * // By default, it assumes the document is a flat object with field names as - * // property keys and field values as string property values, but custom logic - * // can be implemented by setting this option to a custom extractor function. - * extractField: (document, fieldName) => document[fieldName], - * - * // tokenize: function used to split fields into individual terms. By - * // default, it is also used to tokenize search queries, unless a specific - * // `tokenize` search option is supplied. When tokenizing an indexed field, - * // the field name is passed as the second argument. - * tokenize: (string, _fieldName) => string.split(SPACE_OR_PUNCTUATION), - * - * // processTerm: function used to process each tokenized term before - * // indexing. It can be used for stemming and normalization. Return a falsy - * // value in order to discard a term. By default, it is also used to process - * // search queries, unless a specific `processTerm` option is supplied as a - * // search option. When processing a term from a indexed field, the field - * // name is passed as the second argument. - * processTerm: (term, _fieldName) => term.toLowerCase(), - * - * // searchOptions: default search options, see the `search` method for - * // details - * searchOptions: undefined, - * - * // fields: document fields to be indexed. Mandatory, but not set by default - * fields: undefined - * - * // storeFields: document fields to be stored and returned as part of the - * // search results. - * storeFields: [] - * }) - * ``` - */ - constructor(options) { - if ((options === null || options === void 0 ? void 0 : options.fields) == null) { - throw new Error('MiniSearch: option "fields" must be provided'); - } - const autoVacuum = options.autoVacuum == null || options.autoVacuum === true ? defaultAutoVacuumOptions : options.autoVacuum; - this._options = { - ...defaultOptions, - ...options, - autoVacuum, - searchOptions: { ...defaultSearchOptions, ...options.searchOptions || {} }, - autoSuggestOptions: { ...defaultAutoSuggestOptions, ...options.autoSuggestOptions || {} } - }; - this._index = new SearchableMap(); - this._documentCount = 0; - this._documentIds = /* @__PURE__ */ new Map(); - this._idToShortId = /* @__PURE__ */ new Map(); - this._fieldIds = {}; - this._fieldLength = /* @__PURE__ */ new Map(); - this._avgFieldLength = []; - this._nextId = 0; - this._storedFields = /* @__PURE__ */ new Map(); - this._dirtCount = 0; - this._currentVacuum = null; - this._enqueuedVacuum = null; - this._enqueuedVacuumConditions = defaultVacuumConditions; - this.addFields(this._options.fields); - } - /** - * Adds a document to the index - * - * @param document The document to be indexed - */ - add(document) { - const { extractField, stringifyField, tokenize, processTerm, fields, idField } = this._options; - const id = extractField(document, idField); - if (id == null) { - throw new Error(`MiniSearch: document does not have ID field "${idField}"`); - } - if (this._idToShortId.has(id)) { - throw new Error(`MiniSearch: duplicate ID ${id}`); - } - const shortDocumentId = this.addDocumentId(id); - this.saveStoredFields(shortDocumentId, document); - for (const field of fields) { - const fieldValue = extractField(document, field); - if (fieldValue == null) - continue; - const tokens = tokenize(stringifyField(fieldValue, field), field); - const fieldId = this._fieldIds[field]; - const uniqueTerms = new Set(tokens).size; - this.addFieldLength(shortDocumentId, fieldId, this._documentCount - 1, uniqueTerms); - for (const term of tokens) { - const processedTerm = processTerm(term, field); - if (Array.isArray(processedTerm)) { - for (const t of processedTerm) { - this.addTerm(fieldId, shortDocumentId, t); - } - } else if (processedTerm) { - this.addTerm(fieldId, shortDocumentId, processedTerm); - } - } - } - } - /** - * Adds all the given documents to the index - * - * @param documents An array of documents to be indexed - */ - addAll(documents) { - for (const document of documents) - this.add(document); - } - /** - * Adds all the given documents to the index asynchronously. - * - * Returns a promise that resolves (to `undefined`) when the indexing is done. - * This method is useful when index many documents, to avoid blocking the main - * thread. The indexing is performed asynchronously and in chunks. - * - * @param documents An array of documents to be indexed - * @param options Configuration options - * @return A promise resolving to `undefined` when the indexing is done - */ - addAllAsync(documents, options = {}) { - const { chunkSize = 10 } = options; - const acc = { chunk: [], promise: Promise.resolve() }; - const { chunk, promise } = documents.reduce(({ chunk: chunk2, promise: promise2 }, document, i) => { - chunk2.push(document); - if ((i + 1) % chunkSize === 0) { - return { - chunk: [], - promise: promise2.then(() => new Promise((resolve) => setTimeout(resolve, 0))).then(() => this.addAll(chunk2)) - }; - } else { - return { chunk: chunk2, promise: promise2 }; - } - }, acc); - return promise.then(() => this.addAll(chunk)); - } - /** - * Removes the given document from the index. - * - * The document to remove must NOT have changed between indexing and removal, - * otherwise the index will be corrupted. - * - * This method requires passing the full document to be removed (not just the - * ID), and immediately removes the document from the inverted index, allowing - * memory to be released. A convenient alternative is {@link - * MiniSearch#discard}, which needs only the document ID, and has the same - * visible effect, but delays cleaning up the index until the next vacuuming. - * - * @param document The document to be removed - */ - remove(document) { - const { tokenize, processTerm, extractField, stringifyField, fields, idField } = this._options; - const id = extractField(document, idField); - if (id == null) { - throw new Error(`MiniSearch: document does not have ID field "${idField}"`); - } - const shortId = this._idToShortId.get(id); - if (shortId == null) { - throw new Error(`MiniSearch: cannot remove document with ID ${id}: it is not in the index`); - } - for (const field of fields) { - const fieldValue = extractField(document, field); - if (fieldValue == null) - continue; - const tokens = tokenize(stringifyField(fieldValue, field), field); - const fieldId = this._fieldIds[field]; - const uniqueTerms = new Set(tokens).size; - this.removeFieldLength(shortId, fieldId, this._documentCount, uniqueTerms); - for (const term of tokens) { - const processedTerm = processTerm(term, field); - if (Array.isArray(processedTerm)) { - for (const t of processedTerm) { - this.removeTerm(fieldId, shortId, t); - } - } else if (processedTerm) { - this.removeTerm(fieldId, shortId, processedTerm); - } - } - } - this._storedFields.delete(shortId); - this._documentIds.delete(shortId); - this._idToShortId.delete(id); - this._fieldLength.delete(shortId); - this._documentCount -= 1; - } - /** - * Removes all the given documents from the index. If called with no arguments, - * it removes _all_ documents from the index. - * - * @param documents The documents to be removed. If this argument is omitted, - * all documents are removed. Note that, for removing all documents, it is - * more efficient to call this method with no arguments than to pass all - * documents. - */ - removeAll(documents) { - if (documents) { - for (const document of documents) - this.remove(document); - } else if (arguments.length > 0) { - throw new Error("Expected documents to be present. Omit the argument to remove all documents."); - } else { - this._index = new SearchableMap(); - this._documentCount = 0; - this._documentIds = /* @__PURE__ */ new Map(); - this._idToShortId = /* @__PURE__ */ new Map(); - this._fieldLength = /* @__PURE__ */ new Map(); - this._avgFieldLength = []; - this._storedFields = /* @__PURE__ */ new Map(); - this._nextId = 0; - } - } - /** - * Discards the document with the given ID, so it won't appear in search results - * - * It has the same visible effect of {@link MiniSearch.remove} (both cause the - * document to stop appearing in searches), but a different effect on the - * internal data structures: - * - * - {@link MiniSearch#remove} requires passing the full document to be - * removed as argument, and removes it from the inverted index immediately. - * - * - {@link MiniSearch#discard} instead only needs the document ID, and - * works by marking the current version of the document as discarded, so it - * is immediately ignored by searches. This is faster and more convenient - * than {@link MiniSearch#remove}, but the index is not immediately - * modified. To take care of that, vacuuming is performed after a certain - * number of documents are discarded, cleaning up the index and allowing - * memory to be released. - * - * After discarding a document, it is possible to re-add a new version, and - * only the new version will appear in searches. In other words, discarding - * and re-adding a document works exactly like removing and re-adding it. The - * {@link MiniSearch.replace} method can also be used to replace a document - * with a new version. - * - * #### Details about vacuuming - * - * Repetite calls to this method would leave obsolete document references in - * the index, invisible to searches. Two mechanisms take care of cleaning up: - * clean up during search, and vacuuming. - * - * - Upon search, whenever a discarded ID is found (and ignored for the - * results), references to the discarded document are removed from the - * inverted index entries for the search terms. This ensures that subsequent - * searches for the same terms do not need to skip these obsolete references - * again. - * - * - In addition, vacuuming is performed automatically by default (see the - * `autoVacuum` field in {@link Options}) after a certain number of - * documents are discarded. Vacuuming traverses all terms in the index, - * cleaning up all references to discarded documents. Vacuuming can also be - * triggered manually by calling {@link MiniSearch#vacuum}. - * - * @param id The ID of the document to be discarded - */ - discard(id) { - const shortId = this._idToShortId.get(id); - if (shortId == null) { - throw new Error(`MiniSearch: cannot discard document with ID ${id}: it is not in the index`); - } - this._idToShortId.delete(id); - this._documentIds.delete(shortId); - this._storedFields.delete(shortId); - (this._fieldLength.get(shortId) || []).forEach((fieldLength, fieldId) => { - this.removeFieldLength(shortId, fieldId, this._documentCount, fieldLength); - }); - this._fieldLength.delete(shortId); - this._documentCount -= 1; - this._dirtCount += 1; - this.maybeAutoVacuum(); - } - maybeAutoVacuum() { - if (this._options.autoVacuum === false) { - return; - } - const { minDirtFactor, minDirtCount, batchSize, batchWait } = this._options.autoVacuum; - this.conditionalVacuum({ batchSize, batchWait }, { minDirtCount, minDirtFactor }); - } - /** - * Discards the documents with the given IDs, so they won't appear in search - * results - * - * It is equivalent to calling {@link MiniSearch#discard} for all the given - * IDs, but with the optimization of triggering at most one automatic - * vacuuming at the end. - * - * Note: to remove all documents from the index, it is faster and more - * convenient to call {@link MiniSearch.removeAll} with no argument, instead - * of passing all IDs to this method. - */ - discardAll(ids) { - const autoVacuum = this._options.autoVacuum; - try { - this._options.autoVacuum = false; - for (const id of ids) { - this.discard(id); - } - } finally { - this._options.autoVacuum = autoVacuum; - } - this.maybeAutoVacuum(); - } - /** - * It replaces an existing document with the given updated version - * - * It works by discarding the current version and adding the updated one, so - * it is functionally equivalent to calling {@link MiniSearch#discard} - * followed by {@link MiniSearch#add}. The ID of the updated document should - * be the same as the original one. - * - * Since it uses {@link MiniSearch#discard} internally, this method relies on - * vacuuming to clean up obsolete document references from the index, allowing - * memory to be released (see {@link MiniSearch#discard}). - * - * @param updatedDocument The updated document to replace the old version - * with - */ - replace(updatedDocument) { - const { idField, extractField } = this._options; - const id = extractField(updatedDocument, idField); - this.discard(id); - this.add(updatedDocument); - } - /** - * Triggers a manual vacuuming, cleaning up references to discarded documents - * from the inverted index - * - * Vacuuming is only useful for applications that use the {@link - * MiniSearch#discard} or {@link MiniSearch#replace} methods. - * - * By default, vacuuming is performed automatically when needed (controlled by - * the `autoVacuum` field in {@link Options}), so there is usually no need to - * call this method, unless one wants to make sure to perform vacuuming at a - * specific moment. - * - * Vacuuming traverses all terms in the inverted index in batches, and cleans - * up references to discarded documents from the posting list, allowing memory - * to be released. - * - * The method takes an optional object as argument with the following keys: - * - * - `batchSize`: the size of each batch (1000 by default) - * - * - `batchWait`: the number of milliseconds to wait between batches (10 by - * default) - * - * On large indexes, vacuuming could have a non-negligible cost: batching - * avoids blocking the thread for long, diluting this cost so that it is not - * negatively affecting the application. Nonetheless, this method should only - * be called when necessary, and relying on automatic vacuuming is usually - * better. - * - * It returns a promise that resolves (to undefined) when the clean up is - * completed. If vacuuming is already ongoing at the time this method is - * called, a new one is enqueued immediately after the ongoing one, and a - * corresponding promise is returned. However, no more than one vacuuming is - * enqueued on top of the ongoing one, even if this method is called more - * times (enqueuing multiple ones would be useless). - * - * @param options Configuration options for the batch size and delay. See - * {@link VacuumOptions}. - */ - vacuum(options = {}) { - return this.conditionalVacuum(options); - } - conditionalVacuum(options, conditions) { - if (this._currentVacuum) { - this._enqueuedVacuumConditions = this._enqueuedVacuumConditions && conditions; - if (this._enqueuedVacuum != null) { - return this._enqueuedVacuum; - } - this._enqueuedVacuum = this._currentVacuum.then(() => { - const conditions2 = this._enqueuedVacuumConditions; - this._enqueuedVacuumConditions = defaultVacuumConditions; - return this.performVacuuming(options, conditions2); - }); - return this._enqueuedVacuum; - } - if (this.vacuumConditionsMet(conditions) === false) { - return Promise.resolve(); - } - this._currentVacuum = this.performVacuuming(options); - return this._currentVacuum; - } - async performVacuuming(options, conditions) { - const initialDirtCount = this._dirtCount; - if (this.vacuumConditionsMet(conditions)) { - const batchSize = options.batchSize || defaultVacuumOptions.batchSize; - const batchWait = options.batchWait || defaultVacuumOptions.batchWait; - let i = 1; - for (const [term, fieldsData] of this._index) { - for (const [fieldId, fieldIndex] of fieldsData) { - for (const [shortId] of fieldIndex) { - if (this._documentIds.has(shortId)) { - continue; - } - if (fieldIndex.size <= 1) { - fieldsData.delete(fieldId); - } else { - fieldIndex.delete(shortId); - } - } - } - if (this._index.get(term).size === 0) { - this._index.delete(term); - } - if (i % batchSize === 0) { - await new Promise((resolve) => setTimeout(resolve, batchWait)); - } - i += 1; - } - this._dirtCount -= initialDirtCount; - } - await null; - this._currentVacuum = this._enqueuedVacuum; - this._enqueuedVacuum = null; - } - vacuumConditionsMet(conditions) { - if (conditions == null) { - return true; - } - let { minDirtCount, minDirtFactor } = conditions; - minDirtCount = minDirtCount || defaultAutoVacuumOptions.minDirtCount; - minDirtFactor = minDirtFactor || defaultAutoVacuumOptions.minDirtFactor; - return this.dirtCount >= minDirtCount && this.dirtFactor >= minDirtFactor; - } - /** - * Is `true` if a vacuuming operation is ongoing, `false` otherwise - */ - get isVacuuming() { - return this._currentVacuum != null; - } - /** - * The number of documents discarded since the most recent vacuuming - */ - get dirtCount() { - return this._dirtCount; - } - /** - * A number between 0 and 1 giving an indication about the proportion of - * documents that are discarded, and can therefore be cleaned up by vacuuming. - * A value close to 0 means that the index is relatively clean, while a higher - * value means that the index is relatively dirty, and vacuuming could release - * memory. - */ - get dirtFactor() { - return this._dirtCount / (1 + this._documentCount + this._dirtCount); - } - /** - * Returns `true` if a document with the given ID is present in the index and - * available for search, `false` otherwise - * - * @param id The document ID - */ - has(id) { - return this._idToShortId.has(id); - } - /** - * Returns the stored fields (as configured in the `storeFields` constructor - * option) for the given document ID. Returns `undefined` if the document is - * not present in the index. - * - * @param id The document ID - */ - getStoredFields(id) { - const shortId = this._idToShortId.get(id); - if (shortId == null) { - return void 0; - } - return this._storedFields.get(shortId); - } - /** - * Search for documents matching the given search query. - * - * The result is a list of scored document IDs matching the query, sorted by - * descending score, and each including data about which terms were matched and - * in which fields. - * - * ### Basic usage: - * - * ```javascript - * // Search for "zen art motorcycle" with default options: terms have to match - * // exactly, and individual terms are joined with OR - * miniSearch.search('zen art motorcycle') - * // => [ { id: 2, score: 2.77258, match: { ... } }, { id: 4, score: 1.38629, match: { ... } } ] - * ``` - * - * ### Restrict search to specific fields: - * - * ```javascript - * // Search only in the 'title' field - * miniSearch.search('zen', { fields: ['title'] }) - * ``` - * - * ### Field boosting: - * - * ```javascript - * // Boost a field - * miniSearch.search('zen', { boost: { title: 2 } }) - * ``` - * - * ### Prefix search: - * - * ```javascript - * // Search for "moto" with prefix search (it will match documents - * // containing terms that start with "moto" or "neuro") - * miniSearch.search('moto neuro', { prefix: true }) - * ``` - * - * ### Fuzzy search: - * - * ```javascript - * // Search for "ismael" with fuzzy search (it will match documents containing - * // terms similar to "ismael", with a maximum edit distance of 0.2 term.length - * // (rounded to nearest integer) - * miniSearch.search('ismael', { fuzzy: 0.2 }) - * ``` - * - * ### Combining strategies: - * - * ```javascript - * // Mix of exact match, prefix search, and fuzzy search - * miniSearch.search('ismael mob', { - * prefix: true, - * fuzzy: 0.2 - * }) - * ``` - * - * ### Advanced prefix and fuzzy search: - * - * ```javascript - * // Perform fuzzy and prefix search depending on the search term. Here - * // performing prefix and fuzzy search only on terms longer than 3 characters - * miniSearch.search('ismael mob', { - * prefix: term => term.length > 3 - * fuzzy: term => term.length > 3 ? 0.2 : null - * }) - * ``` - * - * ### Combine with AND: - * - * ```javascript - * // Combine search terms with AND (to match only documents that contain both - * // "motorcycle" and "art") - * miniSearch.search('motorcycle art', { combineWith: 'AND' }) - * ``` - * - * ### Combine with AND_NOT: - * - * There is also an AND_NOT combinator, that finds documents that match the - * first term, but do not match any of the other terms. This combinator is - * rarely useful with simple queries, and is meant to be used with advanced - * query combinations (see later for more details). - * - * ### Filtering results: - * - * ```javascript - * // Filter only results in the 'fiction' category (assuming that 'category' - * // is a stored field) - * miniSearch.search('motorcycle art', { - * filter: (result) => result.category === 'fiction' - * }) - * ``` - * - * ### Wildcard query - * - * Searching for an empty string (assuming the default tokenizer) returns no - * results. Sometimes though, one needs to match all documents, like in a - * "wildcard" search. This is possible by passing the special value - * {@link MiniSearch.wildcard} as the query: - * - * ```javascript - * // Return search results for all documents - * miniSearch.search(MiniSearch.wildcard) - * ``` - * - * Note that search options such as `filter` and `boostDocument` are still - * applied, influencing which results are returned, and their order: - * - * ```javascript - * // Return search results for all documents in the 'fiction' category - * miniSearch.search(MiniSearch.wildcard, { - * filter: (result) => result.category === 'fiction' - * }) - * ``` - * - * ### Advanced combination of queries: - * - * It is possible to combine different subqueries with OR, AND, and AND_NOT, - * and even with different search options, by passing a query expression - * tree object as the first argument, instead of a string. - * - * ```javascript - * // Search for documents that contain "zen" and ("motorcycle" or "archery") - * miniSearch.search({ - * combineWith: 'AND', - * queries: [ - * 'zen', - * { - * combineWith: 'OR', - * queries: ['motorcycle', 'archery'] - * } - * ] - * }) - * - * // Search for documents that contain ("apple" or "pear") but not "juice" and - * // not "tree" - * miniSearch.search({ - * combineWith: 'AND_NOT', - * queries: [ - * { - * combineWith: 'OR', - * queries: ['apple', 'pear'] - * }, - * 'juice', - * 'tree' - * ] - * }) - * ``` - * - * Each node in the expression tree can be either a string, or an object that - * supports all {@link SearchOptions} fields, plus a `queries` array field for - * subqueries. - * - * Note that, while this can become complicated to do by hand for complex or - * deeply nested queries, it provides a formalized expression tree API for - * external libraries that implement a parser for custom query languages. - * - * @param query Search query - * @param searchOptions Search options. Each option, if not given, defaults to the corresponding value of `searchOptions` given to the constructor, or to the library default. - */ - search(query, searchOptions = {}) { - const { searchOptions: globalSearchOptions } = this._options; - const searchOptionsWithDefaults = { ...globalSearchOptions, ...searchOptions }; - const rawResults = this.executeQuery(query, searchOptions); - const results = []; - for (const [docId, { score, terms, match }] of rawResults) { - const quality = terms.length || 1; - const result = { - id: this._documentIds.get(docId), - score: score * quality, - terms: Object.keys(match), - queryTerms: terms, - match - }; - Object.assign(result, this._storedFields.get(docId)); - if (searchOptionsWithDefaults.filter == null || searchOptionsWithDefaults.filter(result)) { - results.push(result); - } - } - if (query === _MiniSearch.wildcard && searchOptionsWithDefaults.boostDocument == null) { - return results; - } - results.sort(byScore); - return results; - } - /** - * Provide suggestions for the given search query - * - * The result is a list of suggested modified search queries, derived from the - * given search query, each with a relevance score, sorted by descending score. - * - * By default, it uses the same options used for search, except that by - * default it performs prefix search on the last term of the query, and - * combine terms with `'AND'` (requiring all query terms to match). Custom - * options can be passed as a second argument. Defaults can be changed upon - * calling the {@link MiniSearch} constructor, by passing a - * `autoSuggestOptions` option. - * - * ### Basic usage: - * - * ```javascript - * // Get suggestions for 'neuro': - * miniSearch.autoSuggest('neuro') - * // => [ { suggestion: 'neuromancer', terms: [ 'neuromancer' ], score: 0.46240 } ] - * ``` - * - * ### Multiple words: - * - * ```javascript - * // Get suggestions for 'zen ar': - * miniSearch.autoSuggest('zen ar') - * // => [ - * // { suggestion: 'zen archery art', terms: [ 'zen', 'archery', 'art' ], score: 1.73332 }, - * // { suggestion: 'zen art', terms: [ 'zen', 'art' ], score: 1.21313 } - * // ] - * ``` - * - * ### Fuzzy suggestions: - * - * ```javascript - * // Correct spelling mistakes using fuzzy search: - * miniSearch.autoSuggest('neromancer', { fuzzy: 0.2 }) - * // => [ { suggestion: 'neuromancer', terms: [ 'neuromancer' ], score: 1.03998 } ] - * ``` - * - * ### Filtering: - * - * ```javascript - * // Get suggestions for 'zen ar', but only within the 'fiction' category - * // (assuming that 'category' is a stored field): - * miniSearch.autoSuggest('zen ar', { - * filter: (result) => result.category === 'fiction' - * }) - * // => [ - * // { suggestion: 'zen archery art', terms: [ 'zen', 'archery', 'art' ], score: 1.73332 }, - * // { suggestion: 'zen art', terms: [ 'zen', 'art' ], score: 1.21313 } - * // ] - * ``` - * - * @param queryString Query string to be expanded into suggestions - * @param options Search options. The supported options and default values - * are the same as for the {@link MiniSearch#search} method, except that by - * default prefix search is performed on the last term in the query, and terms - * are combined with `'AND'`. - * @return A sorted array of suggestions sorted by relevance score. - */ - autoSuggest(queryString, options = {}) { - options = { ...this._options.autoSuggestOptions, ...options }; - const suggestions = /* @__PURE__ */ new Map(); - for (const { score, terms } of this.search(queryString, options)) { - const phrase = terms.join(" "); - const suggestion = suggestions.get(phrase); - if (suggestion != null) { - suggestion.score += score; - suggestion.count += 1; - } else { - suggestions.set(phrase, { score, terms, count: 1 }); - } - } - const results = []; - for (const [suggestion, { score, terms, count }] of suggestions) { - results.push({ suggestion, terms, score: score / count }); - } - results.sort(byScore); - return results; - } - /** - * Total number of documents available to search - */ - get documentCount() { - return this._documentCount; - } - /** - * Number of terms in the index - */ - get termCount() { - return this._index.size; - } - /** - * Deserializes a JSON index (serialized with `JSON.stringify(miniSearch)`) - * and instantiates a MiniSearch instance. It should be given the same options - * originally used when serializing the index. - * - * ### Usage: - * - * ```javascript - * // If the index was serialized with: - * let miniSearch = new MiniSearch({ fields: ['title', 'text'] }) - * miniSearch.addAll(documents) - * - * const json = JSON.stringify(miniSearch) - * // It can later be deserialized like this: - * miniSearch = MiniSearch.loadJSON(json, { fields: ['title', 'text'] }) - * ``` - * - * @param json JSON-serialized index - * @param options configuration options, same as the constructor - * @return An instance of MiniSearch deserialized from the given JSON. - */ - static loadJSON(json, options) { - if (options == null) { - throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index"); - } - return this.loadJS(JSON.parse(json), options); - } - /** - * Async equivalent of {@link MiniSearch.loadJSON} - * - * This function is an alternative to {@link MiniSearch.loadJSON} that returns - * a promise, and loads the index in batches, leaving pauses between them to avoid - * blocking the main thread. It tends to be slower than the synchronous - * version, but does not block the main thread, so it can be a better choice - * when deserializing very large indexes. - * - * @param json JSON-serialized index - * @param options configuration options, same as the constructor - * @return A Promise that will resolve to an instance of MiniSearch deserialized from the given JSON. - */ - static async loadJSONAsync(json, options) { - if (options == null) { - throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index"); - } - return this.loadJSAsync(JSON.parse(json), options); - } - /** - * Returns the default value of an option. It will throw an error if no option - * with the given name exists. - * - * @param optionName Name of the option - * @return The default value of the given option - * - * ### Usage: - * - * ```javascript - * // Get default tokenizer - * MiniSearch.getDefault('tokenize') - * - * // Get default term processor - * MiniSearch.getDefault('processTerm') - * - * // Unknown options will throw an error - * MiniSearch.getDefault('notExisting') - * // => throws 'MiniSearch: unknown option "notExisting"' - * ``` - */ - static getDefault(optionName) { - if (defaultOptions.hasOwnProperty(optionName)) { - return getOwnProperty(defaultOptions, optionName); - } else { - throw new Error(`MiniSearch: unknown option "${optionName}"`); - } - } - /** - * @ignore - */ - static loadJS(js, options) { - const { index, documentIds, fieldLength, storedFields, serializationVersion } = js; - const miniSearch = this.instantiateMiniSearch(js, options); - miniSearch._documentIds = objectToNumericMap(documentIds); - miniSearch._fieldLength = objectToNumericMap(fieldLength); - miniSearch._storedFields = objectToNumericMap(storedFields); - for (const [shortId, id] of miniSearch._documentIds) { - miniSearch._idToShortId.set(id, shortId); - } - for (const [term, data] of index) { - const dataMap = /* @__PURE__ */ new Map(); - for (const fieldId of Object.keys(data)) { - let indexEntry = data[fieldId]; - if (serializationVersion === 1) { - indexEntry = indexEntry.ds; - } - dataMap.set(parseInt(fieldId, 10), objectToNumericMap(indexEntry)); - } - miniSearch._index.set(term, dataMap); - } - return miniSearch; - } - /** - * @ignore - */ - static async loadJSAsync(js, options) { - const { index, documentIds, fieldLength, storedFields, serializationVersion } = js; - const miniSearch = this.instantiateMiniSearch(js, options); - miniSearch._documentIds = await objectToNumericMapAsync(documentIds); - miniSearch._fieldLength = await objectToNumericMapAsync(fieldLength); - miniSearch._storedFields = await objectToNumericMapAsync(storedFields); - for (const [shortId, id] of miniSearch._documentIds) { - miniSearch._idToShortId.set(id, shortId); - } - let count = 0; - for (const [term, data] of index) { - const dataMap = /* @__PURE__ */ new Map(); - for (const fieldId of Object.keys(data)) { - let indexEntry = data[fieldId]; - if (serializationVersion === 1) { - indexEntry = indexEntry.ds; - } - dataMap.set(parseInt(fieldId, 10), await objectToNumericMapAsync(indexEntry)); - } - if (++count % 1e3 === 0) - await wait(0); - miniSearch._index.set(term, dataMap); - } - return miniSearch; - } - /** - * @ignore - */ - static instantiateMiniSearch(js, options) { - const { documentCount, nextId, fieldIds, averageFieldLength, dirtCount, serializationVersion } = js; - if (serializationVersion !== 1 && serializationVersion !== 2) { - throw new Error("MiniSearch: cannot deserialize an index created with an incompatible version"); - } - const miniSearch = new _MiniSearch(options); - miniSearch._documentCount = documentCount; - miniSearch._nextId = nextId; - miniSearch._idToShortId = /* @__PURE__ */ new Map(); - miniSearch._fieldIds = fieldIds; - miniSearch._avgFieldLength = averageFieldLength; - miniSearch._dirtCount = dirtCount || 0; - miniSearch._index = new SearchableMap(); - return miniSearch; - } - /** - * @ignore - */ - executeQuery(query, searchOptions = {}) { - if (query === _MiniSearch.wildcard) { - return this.executeWildcardQuery(searchOptions); - } - if (typeof query !== "string") { - const options2 = { ...searchOptions, ...query, queries: void 0 }; - const results2 = query.queries.map((subquery) => this.executeQuery(subquery, options2)); - return this.combineResults(results2, options2.combineWith); - } - const { tokenize, processTerm, searchOptions: globalSearchOptions } = this._options; - const options = { tokenize, processTerm, ...globalSearchOptions, ...searchOptions }; - const { tokenize: searchTokenize, processTerm: searchProcessTerm } = options; - const terms = searchTokenize(query).flatMap((term) => searchProcessTerm(term)).filter((term) => !!term); - const queries = terms.map(termToQuerySpec(options)); - const results = queries.map((query2) => this.executeQuerySpec(query2, options)); - return this.combineResults(results, options.combineWith); - } - /** - * @ignore - */ - executeQuerySpec(query, searchOptions) { - const options = { ...this._options.searchOptions, ...searchOptions }; - const boosts = (options.fields || this._options.fields).reduce((boosts2, field) => ({ ...boosts2, [field]: getOwnProperty(options.boost, field) || 1 }), {}); - const { boostDocument, weights, maxFuzzy, bm25: bm25params } = options; - const { fuzzy: fuzzyWeight, prefix: prefixWeight } = { ...defaultSearchOptions.weights, ...weights }; - const data = this._index.get(query.term); - const results = this.termResults(query.term, query.term, 1, query.termBoost, data, boosts, boostDocument, bm25params); - let prefixMatches; - let fuzzyMatches; - if (query.prefix) { - prefixMatches = this._index.atPrefix(query.term); - } - if (query.fuzzy) { - const fuzzy = query.fuzzy === true ? 0.2 : query.fuzzy; - const maxDistance = fuzzy < 1 ? Math.min(maxFuzzy, Math.round(query.term.length * fuzzy)) : fuzzy; - if (maxDistance) - fuzzyMatches = this._index.fuzzyGet(query.term, maxDistance); - } - if (prefixMatches) { - for (const [term, data2] of prefixMatches) { - const distance = term.length - query.term.length; - if (!distance) { - continue; - } - fuzzyMatches === null || fuzzyMatches === void 0 ? void 0 : fuzzyMatches.delete(term); - const weight = prefixWeight * term.length / (term.length + 0.3 * distance); - this.termResults(query.term, term, weight, query.termBoost, data2, boosts, boostDocument, bm25params, results); - } - } - if (fuzzyMatches) { - for (const term of fuzzyMatches.keys()) { - const [data2, distance] = fuzzyMatches.get(term); - if (!distance) { - continue; - } - const weight = fuzzyWeight * term.length / (term.length + distance); - this.termResults(query.term, term, weight, query.termBoost, data2, boosts, boostDocument, bm25params, results); - } - } - return results; - } - /** - * @ignore - */ - executeWildcardQuery(searchOptions) { - const results = /* @__PURE__ */ new Map(); - const options = { ...this._options.searchOptions, ...searchOptions }; - for (const [shortId, id] of this._documentIds) { - const score = options.boostDocument ? options.boostDocument(id, "", this._storedFields.get(shortId)) : 1; - results.set(shortId, { - score, - terms: [], - match: {} - }); - } - return results; - } - /** - * @ignore - */ - combineResults(results, combineWith = OR) { - if (results.length === 0) { - return /* @__PURE__ */ new Map(); - } - const operator = combineWith.toLowerCase(); - const combinator = combinators[operator]; - if (!combinator) { - throw new Error(`Invalid combination operator: ${combineWith}`); - } - return results.reduce(combinator) || /* @__PURE__ */ new Map(); - } - /** - * Allows serialization of the index to JSON, to possibly store it and later - * deserialize it with {@link MiniSearch.loadJSON}. - * - * Normally one does not directly call this method, but rather call the - * standard JavaScript `JSON.stringify()` passing the {@link MiniSearch} - * instance, and JavaScript will internally call this method. Upon - * deserialization, one must pass to {@link MiniSearch.loadJSON} the same - * options used to create the original instance that was serialized. - * - * ### Usage: - * - * ```javascript - * // Serialize the index: - * let miniSearch = new MiniSearch({ fields: ['title', 'text'] }) - * miniSearch.addAll(documents) - * const json = JSON.stringify(miniSearch) - * - * // Later, to deserialize it: - * miniSearch = MiniSearch.loadJSON(json, { fields: ['title', 'text'] }) - * ``` - * - * @return A plain-object serializable representation of the search index. - */ - toJSON() { - const index = []; - for (const [term, fieldIndex] of this._index) { - const data = {}; - for (const [fieldId, freqs] of fieldIndex) { - data[fieldId] = Object.fromEntries(freqs); - } - index.push([term, data]); - } - return { - documentCount: this._documentCount, - nextId: this._nextId, - documentIds: Object.fromEntries(this._documentIds), - fieldIds: this._fieldIds, - fieldLength: Object.fromEntries(this._fieldLength), - averageFieldLength: this._avgFieldLength, - storedFields: Object.fromEntries(this._storedFields), - dirtCount: this._dirtCount, - index, - serializationVersion: 2 - }; - } - /** - * @ignore - */ - termResults(sourceTerm, derivedTerm, termWeight, termBoost, fieldTermData, fieldBoosts, boostDocumentFn, bm25params, results = /* @__PURE__ */ new Map()) { - if (fieldTermData == null) - return results; - for (const field of Object.keys(fieldBoosts)) { - const fieldBoost = fieldBoosts[field]; - const fieldId = this._fieldIds[field]; - const fieldTermFreqs = fieldTermData.get(fieldId); - if (fieldTermFreqs == null) - continue; - let matchingFields = fieldTermFreqs.size; - const avgFieldLength = this._avgFieldLength[fieldId]; - for (const docId of fieldTermFreqs.keys()) { - if (!this._documentIds.has(docId)) { - this.removeTerm(fieldId, docId, derivedTerm); - matchingFields -= 1; - continue; - } - const docBoost = boostDocumentFn ? boostDocumentFn(this._documentIds.get(docId), derivedTerm, this._storedFields.get(docId)) : 1; - if (!docBoost) - continue; - const termFreq = fieldTermFreqs.get(docId); - const fieldLength = this._fieldLength.get(docId)[fieldId]; - const rawScore = calcBM25Score(termFreq, matchingFields, this._documentCount, fieldLength, avgFieldLength, bm25params); - const weightedScore = termWeight * termBoost * fieldBoost * docBoost * rawScore; - const result = results.get(docId); - if (result) { - result.score += weightedScore; - assignUniqueTerm(result.terms, sourceTerm); - const match = getOwnProperty(result.match, derivedTerm); - if (match) { - match.push(field); - } else { - result.match[derivedTerm] = [field]; - } - } else { - results.set(docId, { - score: weightedScore, - terms: [sourceTerm], - match: { [derivedTerm]: [field] } - }); - } - } - } - return results; - } - /** - * @ignore - */ - addTerm(fieldId, documentId, term) { - const indexData = this._index.fetch(term, createMap); - let fieldIndex = indexData.get(fieldId); - if (fieldIndex == null) { - fieldIndex = /* @__PURE__ */ new Map(); - fieldIndex.set(documentId, 1); - indexData.set(fieldId, fieldIndex); - } else { - const docs = fieldIndex.get(documentId); - fieldIndex.set(documentId, (docs || 0) + 1); - } - } - /** - * @ignore - */ - removeTerm(fieldId, documentId, term) { - if (!this._index.has(term)) { - this.warnDocumentChanged(documentId, fieldId, term); - return; - } - const indexData = this._index.fetch(term, createMap); - const fieldIndex = indexData.get(fieldId); - if (fieldIndex == null || fieldIndex.get(documentId) == null) { - this.warnDocumentChanged(documentId, fieldId, term); - } else if (fieldIndex.get(documentId) <= 1) { - if (fieldIndex.size <= 1) { - indexData.delete(fieldId); - } else { - fieldIndex.delete(documentId); - } - } else { - fieldIndex.set(documentId, fieldIndex.get(documentId) - 1); - } - if (this._index.get(term).size === 0) { - this._index.delete(term); - } - } - /** - * @ignore - */ - warnDocumentChanged(shortDocumentId, fieldId, term) { - for (const fieldName of Object.keys(this._fieldIds)) { - if (this._fieldIds[fieldName] === fieldId) { - this._options.logger("warn", `MiniSearch: document with ID ${this._documentIds.get(shortDocumentId)} has changed before removal: term "${term}" was not present in field "${fieldName}". Removing a document after it has changed can corrupt the index!`, "version_conflict"); - return; - } - } - } - /** - * @ignore - */ - addDocumentId(documentId) { - const shortDocumentId = this._nextId; - this._idToShortId.set(documentId, shortDocumentId); - this._documentIds.set(shortDocumentId, documentId); - this._documentCount += 1; - this._nextId += 1; - return shortDocumentId; - } - /** - * @ignore - */ - addFields(fields) { - for (let i = 0; i < fields.length; i++) { - this._fieldIds[fields[i]] = i; - } - } - /** - * @ignore - */ - addFieldLength(documentId, fieldId, count, length) { - let fieldLengths = this._fieldLength.get(documentId); - if (fieldLengths == null) - this._fieldLength.set(documentId, fieldLengths = []); - fieldLengths[fieldId] = length; - const averageFieldLength = this._avgFieldLength[fieldId] || 0; - const totalFieldLength = averageFieldLength * count + length; - this._avgFieldLength[fieldId] = totalFieldLength / (count + 1); - } - /** - * @ignore - */ - removeFieldLength(documentId, fieldId, count, length) { - if (count === 1) { - this._avgFieldLength[fieldId] = 0; - return; - } - const totalFieldLength = this._avgFieldLength[fieldId] * count - length; - this._avgFieldLength[fieldId] = totalFieldLength / (count - 1); - } - /** - * @ignore - */ - saveStoredFields(documentId, doc) { - const { storeFields, extractField } = this._options; - if (storeFields == null || storeFields.length === 0) { - return; - } - let documentFields = this._storedFields.get(documentId); - if (documentFields == null) - this._storedFields.set(documentId, documentFields = {}); - for (const fieldName of storeFields) { - const fieldValue = extractField(doc, fieldName); - if (fieldValue !== void 0) - documentFields[fieldName] = fieldValue; - } - } -}; -MiniSearch.wildcard = Symbol("*"); -var getOwnProperty = (object, property) => Object.prototype.hasOwnProperty.call(object, property) ? object[property] : void 0; -var combinators = { - [OR]: (a, b) => { - for (const docId of b.keys()) { - const existing = a.get(docId); - if (existing == null) { - a.set(docId, b.get(docId)); - } else { - const { score, terms, match } = b.get(docId); - existing.score = existing.score + score; - existing.match = Object.assign(existing.match, match); - assignUniqueTerms(existing.terms, terms); - } - } - return a; - }, - [AND]: (a, b) => { - const combined = /* @__PURE__ */ new Map(); - for (const docId of b.keys()) { - const existing = a.get(docId); - if (existing == null) - continue; - const { score, terms, match } = b.get(docId); - assignUniqueTerms(existing.terms, terms); - combined.set(docId, { - score: existing.score + score, - terms: existing.terms, - match: Object.assign(existing.match, match) - }); - } - return combined; - }, - [AND_NOT]: (a, b) => { - for (const docId of b.keys()) - a.delete(docId); - return a; - } -}; -var defaultBM25params = { k: 1.2, b: 0.7, d: 0.5 }; -var calcBM25Score = (termFreq, matchingCount, totalCount, fieldLength, avgFieldLength, bm25params) => { - const { k, b, d } = bm25params; - const invDocFreq = Math.log(1 + (totalCount - matchingCount + 0.5) / (matchingCount + 0.5)); - return invDocFreq * (d + termFreq * (k + 1) / (termFreq + k * (1 - b + b * fieldLength / avgFieldLength))); -}; -var termToQuerySpec = (options) => (term, i, terms) => { - const fuzzy = typeof options.fuzzy === "function" ? options.fuzzy(term, i, terms) : options.fuzzy || false; - const prefix = typeof options.prefix === "function" ? options.prefix(term, i, terms) : options.prefix === true; - const termBoost = typeof options.boostTerm === "function" ? options.boostTerm(term, i, terms) : 1; - return { term, fuzzy, prefix, termBoost }; -}; -var defaultOptions = { - idField: "id", - extractField: (document, fieldName) => document[fieldName], - stringifyField: (fieldValue, fieldName) => fieldValue.toString(), - tokenize: (text) => text.split(SPACE_OR_PUNCTUATION), - processTerm: (term) => term.toLowerCase(), - fields: void 0, - searchOptions: void 0, - storeFields: [], - logger: (level, message) => { - if (typeof (console === null || console === void 0 ? void 0 : console[level]) === "function") - console[level](message); - }, - autoVacuum: true -}; -var defaultSearchOptions = { - combineWith: OR, - prefix: false, - fuzzy: false, - maxFuzzy: 6, - boost: {}, - weights: { fuzzy: 0.45, prefix: 0.375 }, - bm25: defaultBM25params -}; -var defaultAutoSuggestOptions = { - combineWith: AND, - prefix: (term, i, terms) => i === terms.length - 1 -}; -var defaultVacuumOptions = { batchSize: 1e3, batchWait: 10 }; -var defaultVacuumConditions = { minDirtFactor: 0.1, minDirtCount: 20 }; -var defaultAutoVacuumOptions = { ...defaultVacuumOptions, ...defaultVacuumConditions }; -var assignUniqueTerm = (target, term) => { - if (!target.includes(term)) - target.push(term); -}; -var assignUniqueTerms = (target, source) => { - for (const term of source) { - if (!target.includes(term)) - target.push(term); - } -}; -var byScore = ({ score: a }, { score: b }) => b - a; -var createMap = () => /* @__PURE__ */ new Map(); -var objectToNumericMap = (object) => { - const map = /* @__PURE__ */ new Map(); - for (const key of Object.keys(object)) { - map.set(parseInt(key, 10), object[key]); - } - return map; -}; -var objectToNumericMapAsync = async (object) => { - const map = /* @__PURE__ */ new Map(); - let count = 0; - for (const key of Object.keys(object)) { - map.set(parseInt(key, 10), object[key]); - if (++count % 1e3 === 0) { - await wait(0); - } - } - return map; -}; -var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); -var SPACE_OR_PUNCTUATION = /[\n\r\p{Z}\p{P}]+/u; -export { - MiniSearch as default -}; -//# sourceMappingURL=vitepress___minisearch.js.map diff --git a/www/docs/.vitepress/cache/deps/vitepress___minisearch.js.map b/www/docs/.vitepress/cache/deps/vitepress___minisearch.js.map deleted file mode 100644 index 33129dd..0000000 --- a/www/docs/.vitepress/cache/deps/vitepress___minisearch.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../../../node_modules/minisearch/src/SearchableMap/TreeIterator.ts", "../../../../node_modules/minisearch/src/SearchableMap/fuzzySearch.ts", "../../../../node_modules/minisearch/src/SearchableMap/SearchableMap.ts", "../../../../node_modules/minisearch/src/MiniSearch.ts"], - "sourcesContent": ["import type { RadixTree, Entry, LeafType } from './types'\n\n/** @ignore */\nconst ENTRIES = 'ENTRIES'\n\n/** @ignore */\nconst KEYS = 'KEYS'\n\n/** @ignore */\nconst VALUES = 'VALUES'\n\n/** @ignore */\nconst LEAF = '' as LeafType\n\ninterface Iterators {\n ENTRIES: Entry\n KEYS: string\n VALUES: T\n}\n\ntype Kind = keyof Iterators\ntype Result> = Iterators[K]\n\ntype IteratorPath = {\n node: RadixTree,\n keys: string[]\n}[]\n\nexport type IterableSet = {\n _tree: RadixTree,\n _prefix: string\n}\n\n/**\n * @private\n */\nclass TreeIterator> implements Iterator> {\n set: IterableSet\n _type: K\n _path: IteratorPath\n\n constructor (set: IterableSet, type: K) {\n const node = set._tree\n const keys = Array.from(node.keys())\n this.set = set\n this._type = type\n this._path = keys.length > 0 ? [{ node, keys }] : []\n }\n\n next (): IteratorResult> {\n const value = this.dive()\n this.backtrack()\n return value\n }\n\n dive (): IteratorResult> {\n if (this._path.length === 0) { return { done: true, value: undefined } }\n const { node, keys } = last(this._path)!\n if (last(keys) === LEAF) { return { done: false, value: this.result() } }\n\n const child = node.get(last(keys)!)!\n this._path.push({ node: child, keys: Array.from(child.keys()) })\n return this.dive()\n }\n\n backtrack (): void {\n if (this._path.length === 0) { return }\n const keys = last(this._path)!.keys\n keys.pop()\n if (keys.length > 0) { return }\n this._path.pop()\n this.backtrack()\n }\n\n key (): string {\n return this.set._prefix + this._path\n .map(({ keys }) => last(keys))\n .filter(key => key !== LEAF)\n .join('')\n }\n\n value (): T {\n return last(this._path)!.node.get(LEAF)!\n }\n\n result (): Result {\n switch (this._type) {\n case VALUES: return this.value() as Result\n case KEYS: return this.key() as Result\n default: return [this.key(), this.value()] as Result\n }\n }\n\n [Symbol.iterator] () {\n return this\n }\n}\n\nconst last = (array: T[]): T | undefined => {\n return array[array.length - 1]\n}\n\nexport { TreeIterator, ENTRIES, KEYS, VALUES, LEAF }\n", "/* eslint-disable no-labels */\nimport { LEAF } from './TreeIterator'\nimport type { RadixTree } from './types'\n\nexport type FuzzyResult = [T, number]\n\nexport type FuzzyResults = Map>\n\n/**\n * @ignore\n */\nexport const fuzzySearch = (node: RadixTree, query: string, maxDistance: number): FuzzyResults => {\n const results: FuzzyResults = new Map()\n if (query === undefined) return results\n\n // Number of columns in the Levenshtein matrix.\n const n = query.length + 1\n\n // Matching terms can never be longer than N + maxDistance.\n const m = n + maxDistance\n\n // Fill first matrix row and column with numbers: 0 1 2 3 ...\n const matrix = new Uint8Array(m * n).fill(maxDistance + 1)\n for (let j = 0; j < n; ++j) matrix[j] = j\n for (let i = 1; i < m; ++i) matrix[i * n] = i\n\n recurse(\n node,\n query,\n maxDistance,\n results,\n matrix,\n 1,\n n,\n ''\n )\n\n return results\n}\n\n// Modified version of http://stevehanov.ca/blog/?id=114\n\n// This builds a Levenshtein matrix for a given query and continuously updates\n// it for nodes in the radix tree that fall within the given maximum edit\n// distance. Keeping the same matrix around is beneficial especially for larger\n// edit distances.\n//\n// k a t e <-- query\n// 0 1 2 3 4\n// c 1 1 2 3 4\n// a 2 2 1 2 3\n// t 3 3 2 1 [2] <-- edit distance\n// ^\n// ^ term in radix tree, rows are added and removed as needed\n\nconst recurse = (\n node: RadixTree,\n query: string,\n maxDistance: number,\n results: FuzzyResults,\n matrix: Uint8Array,\n m: number,\n n: number,\n prefix: string\n): void => {\n const offset = m * n\n\n key: for (const key of node.keys()) {\n if (key === LEAF) {\n // We've reached a leaf node. Check if the edit distance acceptable and\n // store the result if it is.\n const distance = matrix[offset - 1]\n if (distance <= maxDistance) {\n results.set(prefix, [node.get(key)!, distance])\n }\n } else {\n // Iterate over all characters in the key. Update the Levenshtein matrix\n // and check if the minimum distance in the last row is still within the\n // maximum edit distance. If it is, we can recurse over all child nodes.\n let i = m\n for (let pos = 0; pos < key.length; ++pos, ++i) {\n const char = key[pos]\n const thisRowOffset = n * i\n const prevRowOffset = thisRowOffset - n\n\n // Set the first column based on the previous row, and initialize the\n // minimum distance in the current row.\n let minDistance = matrix[thisRowOffset]\n\n const jmin = Math.max(0, i - maxDistance - 1)\n const jmax = Math.min(n - 1, i + maxDistance)\n\n // Iterate over remaining columns (characters in the query).\n for (let j = jmin; j < jmax; ++j) {\n const different = char !== query[j]\n\n // It might make sense to only read the matrix positions used for\n // deletion/insertion if the characters are different. But we want to\n // avoid conditional reads for performance reasons.\n const rpl = matrix[prevRowOffset + j] + +different\n const del = matrix[prevRowOffset + j + 1] + 1\n const ins = matrix[thisRowOffset + j] + 1\n\n const dist = matrix[thisRowOffset + j + 1] = Math.min(rpl, del, ins)\n\n if (dist < minDistance) minDistance = dist\n }\n\n // Because distance will never decrease, we can stop. There will be no\n // matching child nodes.\n if (minDistance > maxDistance) {\n continue key\n }\n }\n\n recurse(\n node.get(key)!,\n query,\n maxDistance,\n results,\n matrix,\n i,\n n,\n prefix + key\n )\n }\n }\n}\n\nexport default fuzzySearch\n", "/* eslint-disable no-labels */\nimport { TreeIterator, ENTRIES, KEYS, VALUES, LEAF } from './TreeIterator'\nimport fuzzySearch, { type FuzzyResults } from './fuzzySearch'\nimport type { RadixTree, Entry, Path } from './types'\n\n/**\n * A class implementing the same interface as a standard JavaScript\n * [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)\n * with string keys, but adding support for efficiently searching entries with\n * prefix or fuzzy search. This class is used internally by {@link MiniSearch}\n * as the inverted index data structure. The implementation is a radix tree\n * (compressed prefix tree).\n *\n * Since this class can be of general utility beyond _MiniSearch_, it is\n * exported by the `minisearch` package and can be imported (or required) as\n * `minisearch/SearchableMap`.\n *\n * @typeParam T The type of the values stored in the map.\n */\nexport default class SearchableMap {\n /**\n * @internal\n */\n _tree: RadixTree\n\n /**\n * @internal\n */\n _prefix: string\n\n private _size: number | undefined = undefined\n\n /**\n * The constructor is normally called without arguments, creating an empty\n * map. In order to create a {@link SearchableMap} from an iterable or from an\n * object, check {@link SearchableMap.from} and {@link\n * SearchableMap.fromObject}.\n *\n * The constructor arguments are for internal use, when creating derived\n * mutable views of a map at a prefix.\n */\n constructor (tree: RadixTree = new Map(), prefix = '') {\n this._tree = tree\n this._prefix = prefix\n }\n\n /**\n * Creates and returns a mutable view of this {@link SearchableMap},\n * containing only entries that share the given prefix.\n *\n * ### Usage:\n *\n * ```javascript\n * let map = new SearchableMap()\n * map.set(\"unicorn\", 1)\n * map.set(\"universe\", 2)\n * map.set(\"university\", 3)\n * map.set(\"unique\", 4)\n * map.set(\"hello\", 5)\n *\n * let uni = map.atPrefix(\"uni\")\n * uni.get(\"unique\") // => 4\n * uni.get(\"unicorn\") // => 1\n * uni.get(\"hello\") // => undefined\n *\n * let univer = map.atPrefix(\"univer\")\n * univer.get(\"unique\") // => undefined\n * univer.get(\"universe\") // => 2\n * univer.get(\"university\") // => 3\n * ```\n *\n * @param prefix The prefix\n * @return A {@link SearchableMap} representing a mutable view of the original\n * Map at the given prefix\n */\n atPrefix (prefix: string): SearchableMap {\n if (!prefix.startsWith(this._prefix)) { throw new Error('Mismatched prefix') }\n\n const [node, path] = trackDown(this._tree, prefix.slice(this._prefix.length))\n\n if (node === undefined) {\n const [parentNode, key] = last(path)\n\n for (const k of parentNode!.keys()) {\n if (k !== LEAF && k.startsWith(key)) {\n const node = new Map()\n node.set(k.slice(key.length), parentNode!.get(k)!)\n return new SearchableMap(node, prefix)\n }\n }\n }\n\n return new SearchableMap(node, prefix)\n }\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear\n */\n clear (): void {\n this._size = undefined\n this._tree.clear()\n }\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete\n * @param key Key to delete\n */\n delete (key: string): void {\n this._size = undefined\n return remove(this._tree, key)\n }\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries\n * @return An iterator iterating through `[key, value]` entries.\n */\n entries () {\n return new TreeIterator(this, ENTRIES)\n }\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach\n * @param fn Iteration function\n */\n forEach (fn: (key: string, value: T, map: SearchableMap) => void): void {\n for (const [key, value] of this) {\n fn(key, value, this)\n }\n }\n\n /**\n * Returns a Map of all the entries that have a key within the given edit\n * distance from the search key. The keys of the returned Map are the matching\n * keys, while the values are two-element arrays where the first element is\n * the value associated to the key, and the second is the edit distance of the\n * key to the search key.\n *\n * ### Usage:\n *\n * ```javascript\n * let map = new SearchableMap()\n * map.set('hello', 'world')\n * map.set('hell', 'yeah')\n * map.set('ciao', 'mondo')\n *\n * // Get all entries that match the key 'hallo' with a maximum edit distance of 2\n * map.fuzzyGet('hallo', 2)\n * // => Map(2) { 'hello' => ['world', 1], 'hell' => ['yeah', 2] }\n *\n * // In the example, the \"hello\" key has value \"world\" and edit distance of 1\n * // (change \"e\" to \"a\"), the key \"hell\" has value \"yeah\" and edit distance of 2\n * // (change \"e\" to \"a\", delete \"o\")\n * ```\n *\n * @param key The search key\n * @param maxEditDistance The maximum edit distance (Levenshtein)\n * @return A Map of the matching keys to their value and edit distance\n */\n fuzzyGet (key: string, maxEditDistance: number): FuzzyResults {\n return fuzzySearch(this._tree, key, maxEditDistance)\n }\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get\n * @param key Key to get\n * @return Value associated to the key, or `undefined` if the key is not\n * found.\n */\n get (key: string): T | undefined {\n const node = lookup(this._tree, key)\n return node !== undefined ? node.get(LEAF) : undefined\n }\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has\n * @param key Key\n * @return True if the key is in the map, false otherwise\n */\n has (key: string): boolean {\n const node = lookup(this._tree, key)\n return node !== undefined && node.has(LEAF)\n }\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys\n * @return An `Iterable` iterating through keys\n */\n keys () {\n return new TreeIterator(this, KEYS)\n }\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set\n * @param key Key to set\n * @param value Value to associate to the key\n * @return The {@link SearchableMap} itself, to allow chaining\n */\n set (key: string, value: T): SearchableMap {\n if (typeof key !== 'string') { throw new Error('key must be a string') }\n this._size = undefined\n const node = createPath(this._tree, key)\n node.set(LEAF, value)\n return this\n }\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size\n */\n get size (): number {\n if (this._size) { return this._size }\n /** @ignore */\n this._size = 0\n\n const iter = this.entries()\n while (!iter.next().done) this._size! += 1\n\n return this._size\n }\n\n /**\n * Updates the value at the given key using the provided function. The function\n * is called with the current value at the key, and its return value is used as\n * the new value to be set.\n *\n * ### Example:\n *\n * ```javascript\n * // Increment the current value by one\n * searchableMap.update('somekey', (currentValue) => currentValue == null ? 0 : currentValue + 1)\n * ```\n *\n * If the value at the given key is or will be an object, it might not require\n * re-assignment. In that case it is better to use `fetch()`, because it is\n * faster.\n *\n * @param key The key to update\n * @param fn The function used to compute the new value from the current one\n * @return The {@link SearchableMap} itself, to allow chaining\n */\n update (key: string, fn: (value: T | undefined) => T): SearchableMap {\n if (typeof key !== 'string') { throw new Error('key must be a string') }\n this._size = undefined\n const node = createPath(this._tree, key)\n node.set(LEAF, fn(node.get(LEAF)))\n return this\n }\n\n /**\n * Fetches the value of the given key. If the value does not exist, calls the\n * given function to create a new value, which is inserted at the given key\n * and subsequently returned.\n *\n * ### Example:\n *\n * ```javascript\n * const map = searchableMap.fetch('somekey', () => new Map())\n * map.set('foo', 'bar')\n * ```\n *\n * @param key The key to update\n * @param initial A function that creates a new value if the key does not exist\n * @return The existing or new value at the given key\n */\n fetch (key: string, initial: () => T): T {\n if (typeof key !== 'string') { throw new Error('key must be a string') }\n this._size = undefined\n const node = createPath(this._tree, key)\n\n let value = node.get(LEAF)\n if (value === undefined) {\n node.set(LEAF, value = initial())\n }\n\n return value\n }\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values\n * @return An `Iterable` iterating through values.\n */\n values () {\n return new TreeIterator(this, VALUES)\n }\n\n /**\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@iterator\n */\n [Symbol.iterator] () {\n return this.entries()\n }\n\n /**\n * Creates a {@link SearchableMap} from an `Iterable` of entries\n *\n * @param entries Entries to be inserted in the {@link SearchableMap}\n * @return A new {@link SearchableMap} with the given entries\n */\n static from (entries: Iterable> | Entry[]) {\n const tree = new SearchableMap()\n for (const [key, value] of entries) {\n tree.set(key, value)\n }\n return tree\n }\n\n /**\n * Creates a {@link SearchableMap} from the iterable properties of a JavaScript object\n *\n * @param object Object of entries for the {@link SearchableMap}\n * @return A new {@link SearchableMap} with the given entries\n */\n static fromObject (object: { [key: string]: T }) {\n return SearchableMap.from(Object.entries(object))\n }\n}\n\nconst trackDown = (tree: RadixTree | undefined, key: string, path: Path = []): [RadixTree | undefined, Path] => {\n if (key.length === 0 || tree == null) { return [tree, path] }\n\n for (const k of tree.keys()) {\n if (k !== LEAF && key.startsWith(k)) {\n path.push([tree, k]) // performance: update in place\n return trackDown(tree.get(k)!, key.slice(k.length), path)\n }\n }\n\n path.push([tree, key]) // performance: update in place\n return trackDown(undefined, '', path)\n}\n\nconst lookup = (tree: RadixTree, key: string): RadixTree | undefined => {\n if (key.length === 0 || tree == null) { return tree }\n\n for (const k of tree.keys()) {\n if (k !== LEAF && key.startsWith(k)) {\n return lookup(tree.get(k)!, key.slice(k.length))\n }\n }\n}\n\n// Create a path in the radix tree for the given key, and returns the deepest\n// node. This function is in the hot path for indexing. It avoids unnecessary\n// string operations and recursion for performance.\nconst createPath = (node: RadixTree, key: string): RadixTree => {\n const keyLength = key.length\n\n outer: for (let pos = 0; node && pos < keyLength;) {\n for (const k of node.keys()) {\n // Check whether this key is a candidate: the first characters must match.\n if (k !== LEAF && key[pos] === k[0]) {\n const len = Math.min(keyLength - pos, k.length)\n\n // Advance offset to the point where key and k no longer match.\n let offset = 1\n while (offset < len && key[pos + offset] === k[offset]) ++offset\n\n const child = node.get(k)!\n if (offset === k.length) {\n // The existing key is shorter than the key we need to create.\n node = child\n } else {\n // Partial match: we need to insert an intermediate node to contain\n // both the existing subtree and the new node.\n const intermediate = new Map()\n intermediate.set(k.slice(offset), child)\n node.set(key.slice(pos, pos + offset), intermediate)\n node.delete(k)\n node = intermediate\n }\n\n pos += offset\n continue outer\n }\n }\n\n // Create a final child node to contain the final suffix of the key.\n const child = new Map()\n node.set(key.slice(pos), child)\n return child\n }\n\n return node\n}\n\nconst remove = (tree: RadixTree, key: string): void => {\n const [node, path] = trackDown(tree, key)\n if (node === undefined) { return }\n node.delete(LEAF)\n\n if (node.size === 0) {\n cleanup(path)\n } else if (node.size === 1) {\n const [key, value] = node.entries().next().value!\n merge(path, key as string, value as RadixTree)\n }\n}\n\nconst cleanup = (path: Path): void => {\n if (path.length === 0) { return }\n\n const [node, key] = last(path)\n node!.delete(key)\n\n if (node!.size === 0) {\n cleanup(path.slice(0, -1))\n } else if (node!.size === 1) {\n const [key, value] = node!.entries().next().value!\n if (key !== LEAF) {\n merge(path.slice(0, -1), key as string, value as RadixTree)\n }\n }\n}\n\nconst merge = (path: Path, key: string, value: RadixTree): void => {\n if (path.length === 0) { return }\n\n const [node, nodeKey] = last(path)\n node!.set(nodeKey + key, value)\n node!.delete(nodeKey)\n}\n\nconst last = (array: T[]): T => {\n return array[array.length - 1]\n}\n", "import SearchableMap from './SearchableMap/SearchableMap'\n\nexport type LowercaseCombinationOperator = 'or' | 'and' | 'and_not'\nexport type CombinationOperator = LowercaseCombinationOperator | Uppercase | Capitalize\n\nconst OR: LowercaseCombinationOperator = 'or'\nconst AND: LowercaseCombinationOperator = 'and'\nconst AND_NOT: LowercaseCombinationOperator = 'and_not'\n\n/**\n * Search options to customize the search behavior.\n */\nexport type SearchOptions = {\n /**\n * Names of the fields to search in. If omitted, all fields are searched.\n */\n fields?: string[],\n\n /**\n * Function used to filter search results, for example on the basis of stored\n * fields. It takes as argument each search result and should return a boolean\n * to indicate if the result should be kept or not.\n */\n filter?: (result: SearchResult) => boolean,\n\n /**\n * Key-value object of field names to boosting values. By default, fields are\n * assigned a boosting factor of 1. If one assigns to a field a boosting value\n * of 2, a result that matches the query in that field is assigned a score\n * twice as high as a result matching the query in another field, all else\n * being equal.\n */\n boost?: { [fieldName: string]: number },\n\n /**\n * Function to calculate a boost factor for each term.\n *\n * This function, if provided, is called for each query term (as split by\n * `tokenize` and processed by `processTerm`). The arguments passed to the\n * function are the query term, the positional index of the term in the query,\n * and the array of all query terms. It is expected to return a numeric boost\n * factor for the term. A factor lower than 1 reduces the importance of the\n * term, a factor greater than 1 increases it. A factor of exactly 1 is\n * neutral, and does not affect the term's importance.\n */\n boostTerm?: (term: string, i: number, terms: string[]) => number,\n\n /**\n * Relative weights to assign to prefix search results and fuzzy search\n * results. Exact matches are assigned a weight of 1.\n */\n weights?: { fuzzy: number, prefix: number },\n\n /**\n * Function to calculate a boost factor for documents. It takes as arguments\n * the document ID, and a term that matches the search in that document, and\n * the value of the stored fields for the document (if any). It should return\n * a boosting factor: a number higher than 1 increases the computed score, a\n * number lower than 1 decreases the score, and a falsy value skips the search\n * result completely.\n */\n boostDocument?: (documentId: any, term: string, storedFields?: Record) => number,\n\n /**\n * Controls whether to perform prefix search. It can be a simple boolean, or a\n * function.\n *\n * If a boolean is passed, prefix search is performed if true.\n *\n * If a function is passed, it is called upon search with a search term, the\n * positional index of that search term in the tokenized search query, and the\n * tokenized search query. The function should return a boolean to indicate\n * whether to perform prefix search for that search term.\n */\n prefix?: boolean | ((term: string, index: number, terms: string[]) => boolean),\n\n /**\n * Controls whether to perform fuzzy search. It can be a simple boolean, or a\n * number, or a function.\n *\n * If a boolean is given, fuzzy search with a default fuzziness parameter is\n * performed if true.\n *\n * If a number higher or equal to 1 is given, fuzzy search is performed, with\n * a maximum edit distance (Levenshtein) equal to the number.\n *\n * If a number between 0 and 1 is given, fuzzy search is performed within a\n * maximum edit distance corresponding to that fraction of the term length,\n * approximated to the nearest integer. For example, 0.2 would mean an edit\n * distance of 20% of the term length, so 1 character in a 5-characters term.\n * The calculated fuzziness value is limited by the `maxFuzzy` option, to\n * prevent slowdown for very long queries.\n *\n * If a function is passed, the function is called upon search with a search\n * term, a positional index of that term in the tokenized search query, and\n * the tokenized search query. It should return a boolean or a number, with\n * the meaning documented above.\n */\n fuzzy?: boolean | number | ((term: string, index: number, terms: string[]) => boolean | number),\n\n /**\n * Controls the maximum fuzziness when using a fractional fuzzy value. This is\n * set to 6 by default. Very high edit distances usually don't produce\n * meaningful results, but can excessively impact search performance.\n */\n maxFuzzy?: number,\n\n /**\n * The operand to combine partial results for each term. By default it is\n * \"OR\", so results matching _any_ of the search terms are returned by a\n * search. If \"AND\" is given, only results matching _all_ the search terms are\n * returned by a search.\n */\n combineWith?: CombinationOperator,\n\n /**\n * Function to tokenize the search query. By default, the same tokenizer used\n * for indexing is used also for search.\n *\n * @remarks This function is called after `extractField` extracts a truthy\n * value from a field. This function is then expected to split the extracted\n * `text` document into tokens (more commonly referred to as \"terms\" in this\n * context). The resulting split might be simple, like for example on word\n * boundaries, or it might be more complex, taking into account certain\n * encoding, or parsing needs, or even just special cases. Think about how one\n * might need to go about indexing the term \"short-term\". You would likely\n * want to treat this case specially, and return two terms instead, `[\n * \"short\", \"term\" ]`.\n *\n * Or, you could let such a case be handled by the `processTerm` function,\n * which is designed to turn each token/term into whole terms or sub-terms. In\n * any case, the purpose of this function is to split apart the provided\n * `text` document into parts that can be processed by the `processTerm`\n * function.\n */\n tokenize?: (text: string) => string[],\n\n /**\n * Function to process or normalize terms in the search query. By default, the\n * same term processor used for indexing is used also for search.\n *\n * @remarks\n * During the document indexing phase, the first step is to call the\n * `extractField` function to fetch the requested value/field from the\n * document. This is then passed off to the `tokenize` function, which will\n * break apart each value into \"terms\". These terms are then individually\n * passed through this function to compute each term individually. A term\n * might for example be something like \"lbs\", in which case one would likely\n * want to return `[ \"lbs\", \"lb\", \"pound\", \"pounds\" ]`. You may also return\n * just a single string, or a falsy value if you would like to skip indexing\n * entirely for a specific term.\n *\n * Truthy return value(s) are then fed to the indexer as positive matches for\n * this document. In our example above, all four of the `[ \"lbs\", \"lb\",\n * \"pound\", \"pounds\" ]` terms would be added to the indexing engine, matching\n * against the current document being computed.\n *\n * *Note: Whatever values are returned from this function will receive no\n * further processing before being indexed. This means for example, if you\n * include whitespace at the beginning or end of a word, it will also be\n * indexed that way, with the included whitespace.*\n */\n processTerm?: (term: string) => string | string[] | null | undefined | false\n\n /**\n * BM25+ algorithm parameters. Customizing these is almost never necessary,\n * and finetuning them requires an understanding of the BM25 scoring model. In\n * most cases, it is best to omit this option to use defaults, and instead use\n * boosting to tweak scoring for specific use cases.\n */\n bm25?: BM25Params\n}\n\ntype SearchOptionsWithDefaults = SearchOptions & {\n boost: { [fieldName: string]: number },\n\n weights: { fuzzy: number, prefix: number },\n\n prefix: boolean | ((term: string, index: number, terms: string[]) => boolean),\n\n fuzzy: boolean | number | ((term: string, index: number, terms: string[]) => boolean | number),\n\n maxFuzzy: number,\n\n combineWith: CombinationOperator\n\n bm25: BM25Params\n}\n\n/**\n * Configuration options passed to the {@link MiniSearch} constructor\n *\n * @typeParam T The type of documents being indexed.\n */\nexport type Options = {\n /**\n * Names of the document fields to be indexed.\n */\n fields: string[],\n\n /**\n * Name of the ID field, uniquely identifying a document.\n */\n idField?: string,\n\n /**\n * Names of fields to store, so that search results would include them. By\n * default none, so results would only contain the id field.\n */\n storeFields?: string[],\n\n /**\n * Function used to extract the value of each field in documents. By default,\n * the documents are assumed to be plain objects with field names as keys,\n * but by specifying a custom `extractField` function one can completely\n * customize how the fields are extracted.\n *\n * The function takes as arguments the document, and the name of the field to\n * extract from it. It should return the field value as a string.\n *\n * @remarks\n * The returned string is fed into the `tokenize` function to split it up\n * into tokens.\n */\n extractField?: (document: T, fieldName: string) => any,\n\n /**\n * Function used to turn field values into strings for indexing\n *\n * The function takes as arguments the field value, and the name of the field\n * to stringify, so that its logic can be customized on specific fields. By\n * default, it simply calls `toString()` on the field value (which in many\n * cases is already a string).\n *\n * ### Example:\n *\n * ```javascript\n * // Custom stringifier that formats dates as \"Tuesday, September 16, 2025\"\n * const miniSearch = new MiniSearch({\n * fields: ['title', 'date'],\n * stringifyField: ((fieldValue, _fieldName) => {\n * if (fieldValue instanceof Date) {\n * return fieldValue.toLocaleDateString('en-US', {\n * weekday: 'long',\n * year: 'numeric',\n * month: 'long',\n * day: 'numeric'\n * })\n * } else {\n * return fieldValue.toString()\n * }\n * }\n * })\n * ```\n */\n stringifyField?: (fieldValue: any, fieldName: string) => string,\n\n /**\n * Function used to split a field value into individual terms to be indexed.\n * The default tokenizer separates terms by space or punctuation, but a\n * custom tokenizer can be provided for custom logic.\n *\n * The function takes as arguments string to tokenize, and the name of the\n * field it comes from. It should return the terms as an array of strings.\n * When used for tokenizing a search query instead of a document field, the\n * `fieldName` is undefined.\n *\n * @remarks\n * This function is called after `extractField` extracts a truthy value from a\n * field. This function is then expected to split the extracted `text` document\n * into tokens (more commonly referred to as \"terms\" in this context). The resulting\n * split might be simple, like for example on word boundaries, or it might be more\n * complex, taking into account certain encoding, or parsing needs, or even just\n * special cases. Think about how one might need to go about indexing the term\n * \"short-term\". You would likely want to treat this case specially, and return two\n * terms instead, `[ \"short\", \"term\" ]`.\n *\n * Or, you could let such a case be handled by the `processTerm` function,\n * which is designed to turn each token/term into whole terms or sub-terms. In any\n * case, the purpose of this function is to split apart the provided `text` document\n * into parts that can be processed by the `processTerm` function.\n */\n tokenize?: (text: string, fieldName?: string) => string[],\n\n /**\n * Function used to process a term before indexing or search. This can be\n * used for normalization (such as stemming). By default, terms are\n * downcased, and otherwise no other normalization is performed.\n *\n * The function takes as arguments a term to process, and the name of the\n * field it comes from. It should return the processed term as a string, or a\n * falsy value to reject the term entirely.\n *\n * It can also return an array of strings, in which case each string in the\n * returned array is indexed as a separate term.\n *\n * @remarks\n * During the document indexing phase, the first step is to call the `extractField`\n * function to fetch the requested value/field from the document. This is then\n * passed off to the `tokenizer`, which will break apart each value into \"terms\".\n * These terms are then individually passed through the `processTerm` function\n * to compute each term individually. A term might for example be something\n * like \"lbs\", in which case one would likely want to return\n * `[ \"lbs\", \"lb\", \"pound\", \"pounds\" ]`. You may also return a single string value,\n * or a falsy value if you would like to skip indexing entirely for a specific term.\n *\n * Truthy return value(s) are then fed to the indexer as positive matches for this\n * document. In our example above, all four of the `[ \"lbs\", \"lb\", \"pound\", \"pounds\" ]`\n * terms would be added to the indexing engine, matching against the current document\n * being computed.\n *\n * *Note: Whatever values are returned from this function will receive no further\n * processing before being indexed. This means for example, if you include whitespace\n * at the beginning or end of a word, it will also be indexed that way, with the\n * included whitespace.*\n */\n processTerm?: (term: string, fieldName?: string) => string | string[] | null | undefined | false,\n\n /**\n * Function called to log messages. Arguments are a log level ('debug',\n * 'info', 'warn', or 'error'), a log message, and an optional string code\n * that identifies the reason for the log.\n *\n * The default implementation uses `console`, if defined.\n */\n logger?: (level: LogLevel, message: string, code?: string) => void\n\n /**\n * If `true` (the default), vacuuming is performed automatically as soon as\n * {@link MiniSearch#discard} is called a certain number of times, cleaning up\n * obsolete references from the index. If `false`, no automatic vacuuming is\n * performed. Custom settings controlling auto vacuuming thresholds, as well\n * as batching behavior, can be passed as an object (see the {@link\n * AutoVacuumOptions} type).\n */\n autoVacuum?: boolean | AutoVacuumOptions\n\n /**\n * Default search options (see the {@link SearchOptions} type and the {@link\n * MiniSearch#search} method for details)\n */\n searchOptions?: SearchOptions,\n\n /**\n * Default auto suggest options (see the {@link SearchOptions} type and the\n * {@link MiniSearch#autoSuggest} method for details)\n */\n autoSuggestOptions?: SearchOptions\n}\n\ntype OptionsWithDefaults = Options & {\n storeFields: string[]\n\n idField: string\n\n extractField: (document: T, fieldName: string) => any\n\n stringifyField: (fieldValue: any, fieldName: string) => string\n\n tokenize: (text: string, fieldName: string) => string[]\n\n processTerm: (term: string, fieldName: string) => string | string[] | null | undefined | false\n\n logger: (level: LogLevel, message: string, code?: string) => void\n\n autoVacuum: false | AutoVacuumOptions\n\n searchOptions: SearchOptionsWithDefaults\n\n autoSuggestOptions: SearchOptions\n}\n\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error'\n\n/**\n * The type of auto-suggestions\n */\nexport type Suggestion = {\n /**\n * The suggestion\n */\n suggestion: string,\n\n /**\n * Suggestion as an array of terms\n */\n terms: string[],\n\n /**\n * Score for the suggestion\n */\n score: number\n}\n\n/**\n * Match information for a search result. It is a key-value object where keys\n * are terms that matched, and values are the list of fields that the term was\n * found in.\n */\nexport type MatchInfo = {\n [term: string]: string[]\n}\n\n/**\n * Type of the search results. Each search result indicates the document ID, the\n * terms that matched, the match information, the score, and all the stored\n * fields.\n */\nexport type SearchResult = {\n /**\n * The document ID\n */\n id: any,\n\n /**\n * List of document terms that matched. For example, if a prefix search for\n * `\"moto\"` matches `\"motorcycle\"`, `terms` will contain `\"motorcycle\"`.\n */\n terms: string[],\n\n /**\n * List of query terms that matched. For example, if a prefix search for\n * `\"moto\"` matches `\"motorcycle\"`, `queryTerms` will contain `\"moto\"`.\n */\n queryTerms: string[],\n\n /**\n * Score of the search results\n */\n score: number,\n\n /**\n * Match information, see {@link MatchInfo}\n */\n match: MatchInfo,\n\n /**\n * Stored fields\n */\n [key: string]: any\n}\n\n/**\n * @ignore\n */\nexport type AsPlainObject = {\n documentCount: number,\n nextId: number,\n documentIds: { [shortId: string]: any }\n fieldIds: { [fieldName: string]: number }\n fieldLength: { [shortId: string]: number[] }\n averageFieldLength: number[],\n storedFields: { [shortId: string]: any }\n dirtCount?: number,\n index: [string, { [fieldId: string]: SerializedIndexEntry }][]\n serializationVersion: number\n}\n\nexport type QueryCombination = SearchOptions & { queries: Query[] }\n\n/**\n * Wildcard query, used to match all terms\n */\nexport type Wildcard = typeof MiniSearch.wildcard\n\n/**\n * Search query expression, either a query string or an expression tree\n * combining several queries with a combination of AND or OR.\n */\nexport type Query = QueryCombination | string | Wildcard\n\n/**\n * Options to control vacuuming behavior.\n *\n * Vacuuming cleans up document references made obsolete by {@link\n * MiniSearch.discard} from the index. On large indexes, vacuuming is\n * potentially costly, because it has to traverse the whole inverted index.\n * Therefore, in order to dilute this cost so it does not negatively affects the\n * application, vacuuming is performed in batches, with a delay between each\n * batch. These options are used to configure the batch size and the delay\n * between batches.\n */\nexport type VacuumOptions = {\n /**\n * Size of each vacuuming batch (the number of terms in the index that will be\n * traversed in each batch). Defaults to 1000.\n */\n batchSize?: number,\n\n /**\n * Wait time between each vacuuming batch in milliseconds. Defaults to 10.\n */\n batchWait?: number\n}\n\n/**\n * Sets minimum thresholds for `dirtCount` and `dirtFactor` that trigger an\n * automatic vacuuming.\n */\nexport type VacuumConditions = {\n /**\n * Minimum `dirtCount` (number of discarded documents since the last vacuuming)\n * under which auto vacuum is not triggered. It defaults to 20.\n */\n minDirtCount?: number\n\n /**\n * Minimum `dirtFactor` (proportion of discarded documents over the total)\n * under which auto vacuum is not triggered. It defaults to 0.1.\n */\n minDirtFactor?: number,\n}\n\n/**\n * Options to control auto vacuum behavior. When discarding a document with\n * {@link MiniSearch#discard}, a vacuuming operation is automatically started if\n * the `dirtCount` and `dirtFactor` are above the `minDirtCount` and\n * `minDirtFactor` thresholds defined by this configuration. See {@link\n * VacuumConditions} for details on these.\n *\n * Also, `batchSize` and `batchWait` can be specified, controlling batching\n * behavior (see {@link VacuumOptions}).\n */\nexport type AutoVacuumOptions = VacuumOptions & VacuumConditions\n\ntype QuerySpec = {\n prefix: boolean,\n fuzzy: number | boolean,\n term: string,\n termBoost: number\n}\n\ntype DocumentTermFreqs = Map\ntype FieldTermData = Map\n\ninterface RawResultValue {\n // Intermediate score, before applying the final score based on number of\n // matched terms.\n score: number,\n\n // Set of all query terms that were matched. They may not be present in the\n // text exactly in the case of prefix/fuzzy matches. We must check for\n // uniqueness before adding a new term. This is much faster than using a set,\n // because the number of elements is relatively small.\n terms: string[],\n\n // All terms that were found in the content, including the fields in which\n // they were present. This object will be provided as part of the final search\n // results.\n match: MatchInfo,\n}\n\ntype RawResult = Map\n\n/**\n * {@link MiniSearch} is the main entrypoint class, implementing a full-text\n * search engine in memory.\n *\n * @typeParam T The type of the documents being indexed.\n *\n * ### Basic example:\n *\n * ```javascript\n * const documents = [\n * {\n * id: 1,\n * title: 'Moby Dick',\n * text: 'Call me Ishmael. Some years ago...',\n * category: 'fiction'\n * },\n * {\n * id: 2,\n * title: 'Zen and the Art of Motorcycle Maintenance',\n * text: 'I can see by my watch...',\n * category: 'fiction'\n * },\n * {\n * id: 3,\n * title: 'Neuromancer',\n * text: 'The sky above the port was...',\n * category: 'fiction'\n * },\n * {\n * id: 4,\n * title: 'Zen and the Art of Archery',\n * text: 'At first sight it must seem...',\n * category: 'non-fiction'\n * },\n * // ...and more\n * ]\n *\n * // Create a search engine that indexes the 'title' and 'text' fields for\n * // full-text search. Search results will include 'title' and 'category' (plus the\n * // id field, that is always stored and returned)\n * const miniSearch = new MiniSearch({\n * fields: ['title', 'text'],\n * storeFields: ['title', 'category']\n * })\n *\n * // Add documents to the index\n * miniSearch.addAll(documents)\n *\n * // Search for documents:\n * let results = miniSearch.search('zen art motorcycle')\n * // => [\n * // { id: 2, title: 'Zen and the Art of Motorcycle Maintenance', category: 'fiction', score: 2.77258 },\n * // { id: 4, title: 'Zen and the Art of Archery', category: 'non-fiction', score: 1.38629 }\n * // ]\n * ```\n */\nexport default class MiniSearch {\n protected _options: OptionsWithDefaults\n protected _index: SearchableMap\n protected _documentCount: number\n protected _documentIds: Map\n protected _idToShortId: Map\n protected _fieldIds: { [key: string]: number }\n protected _fieldLength: Map\n protected _avgFieldLength: number[]\n protected _nextId: number\n protected _storedFields: Map>\n protected _dirtCount: number\n private _currentVacuum: Promise | null\n private _enqueuedVacuum: Promise | null\n private _enqueuedVacuumConditions: VacuumConditions | undefined\n\n /**\n * The special wildcard symbol that can be passed to {@link MiniSearch#search}\n * to match all documents\n */\n static readonly wildcard: unique symbol = Symbol('*')\n\n /**\n * @param options Configuration options\n *\n * ### Examples:\n *\n * ```javascript\n * // Create a search engine that indexes the 'title' and 'text' fields of your\n * // documents:\n * const miniSearch = new MiniSearch({ fields: ['title', 'text'] })\n * ```\n *\n * ### ID Field:\n *\n * ```javascript\n * // Your documents are assumed to include a unique 'id' field, but if you want\n * // to use a different field for document identification, you can set the\n * // 'idField' option:\n * const miniSearch = new MiniSearch({ idField: 'key', fields: ['title', 'text'] })\n * ```\n *\n * ### Options and defaults:\n *\n * ```javascript\n * // The full set of options (here with their default value) is:\n * const miniSearch = new MiniSearch({\n * // idField: field that uniquely identifies a document\n * idField: 'id',\n *\n * // extractField: function used to get the value of a field in a document.\n * // By default, it assumes the document is a flat object with field names as\n * // property keys and field values as string property values, but custom logic\n * // can be implemented by setting this option to a custom extractor function.\n * extractField: (document, fieldName) => document[fieldName],\n *\n * // tokenize: function used to split fields into individual terms. By\n * // default, it is also used to tokenize search queries, unless a specific\n * // `tokenize` search option is supplied. When tokenizing an indexed field,\n * // the field name is passed as the second argument.\n * tokenize: (string, _fieldName) => string.split(SPACE_OR_PUNCTUATION),\n *\n * // processTerm: function used to process each tokenized term before\n * // indexing. It can be used for stemming and normalization. Return a falsy\n * // value in order to discard a term. By default, it is also used to process\n * // search queries, unless a specific `processTerm` option is supplied as a\n * // search option. When processing a term from a indexed field, the field\n * // name is passed as the second argument.\n * processTerm: (term, _fieldName) => term.toLowerCase(),\n *\n * // searchOptions: default search options, see the `search` method for\n * // details\n * searchOptions: undefined,\n *\n * // fields: document fields to be indexed. Mandatory, but not set by default\n * fields: undefined\n *\n * // storeFields: document fields to be stored and returned as part of the\n * // search results.\n * storeFields: []\n * })\n * ```\n */\n constructor (options: Options) {\n if (options?.fields == null) {\n throw new Error('MiniSearch: option \"fields\" must be provided')\n }\n\n const autoVacuum = (options.autoVacuum == null || options.autoVacuum === true) ? defaultAutoVacuumOptions : options.autoVacuum\n\n this._options = {\n ...defaultOptions,\n ...options,\n autoVacuum,\n searchOptions: { ...defaultSearchOptions, ...(options.searchOptions || {}) },\n autoSuggestOptions: { ...defaultAutoSuggestOptions, ...(options.autoSuggestOptions || {}) }\n }\n\n this._index = new SearchableMap()\n\n this._documentCount = 0\n\n this._documentIds = new Map()\n\n this._idToShortId = new Map()\n\n // Fields are defined during initialization, don't change, are few in\n // number, rarely need iterating over, and have string keys. Therefore in\n // this case an object is a better candidate than a Map to store the mapping\n // from field key to ID.\n this._fieldIds = {}\n\n this._fieldLength = new Map()\n\n this._avgFieldLength = []\n\n this._nextId = 0\n\n this._storedFields = new Map()\n\n this._dirtCount = 0\n\n this._currentVacuum = null\n\n this._enqueuedVacuum = null\n this._enqueuedVacuumConditions = defaultVacuumConditions\n\n this.addFields(this._options.fields)\n }\n\n /**\n * Adds a document to the index\n *\n * @param document The document to be indexed\n */\n add (document: T): void {\n const { extractField, stringifyField, tokenize, processTerm, fields, idField } = this._options\n const id = extractField(document, idField)\n if (id == null) {\n throw new Error(`MiniSearch: document does not have ID field \"${idField}\"`)\n }\n\n if (this._idToShortId.has(id)) {\n throw new Error(`MiniSearch: duplicate ID ${id}`)\n }\n\n const shortDocumentId = this.addDocumentId(id)\n this.saveStoredFields(shortDocumentId, document)\n\n for (const field of fields) {\n const fieldValue = extractField(document, field)\n if (fieldValue == null) continue\n\n const tokens = tokenize(stringifyField(fieldValue, field), field)\n const fieldId = this._fieldIds[field]\n\n const uniqueTerms = new Set(tokens).size\n this.addFieldLength(shortDocumentId, fieldId, this._documentCount - 1, uniqueTerms)\n\n for (const term of tokens) {\n const processedTerm = processTerm(term, field)\n if (Array.isArray(processedTerm)) {\n for (const t of processedTerm) {\n this.addTerm(fieldId, shortDocumentId, t)\n }\n } else if (processedTerm) {\n this.addTerm(fieldId, shortDocumentId, processedTerm)\n }\n }\n }\n }\n\n /**\n * Adds all the given documents to the index\n *\n * @param documents An array of documents to be indexed\n */\n addAll (documents: readonly T[]): void {\n for (const document of documents) this.add(document)\n }\n\n /**\n * Adds all the given documents to the index asynchronously.\n *\n * Returns a promise that resolves (to `undefined`) when the indexing is done.\n * This method is useful when index many documents, to avoid blocking the main\n * thread. The indexing is performed asynchronously and in chunks.\n *\n * @param documents An array of documents to be indexed\n * @param options Configuration options\n * @return A promise resolving to `undefined` when the indexing is done\n */\n addAllAsync (documents: readonly T[], options: { chunkSize?: number } = {}): Promise {\n const { chunkSize = 10 } = options\n const acc: { chunk: T[], promise: Promise } = { chunk: [], promise: Promise.resolve() }\n\n const { chunk, promise } = documents.reduce(({ chunk, promise }, document: T, i: number) => {\n chunk.push(document)\n if ((i + 1) % chunkSize === 0) {\n return {\n chunk: [],\n promise: promise\n .then(() => new Promise(resolve => setTimeout(resolve, 0)))\n .then(() => this.addAll(chunk))\n }\n } else {\n return { chunk, promise }\n }\n }, acc)\n\n return promise.then(() => this.addAll(chunk))\n }\n\n /**\n * Removes the given document from the index.\n *\n * The document to remove must NOT have changed between indexing and removal,\n * otherwise the index will be corrupted.\n *\n * This method requires passing the full document to be removed (not just the\n * ID), and immediately removes the document from the inverted index, allowing\n * memory to be released. A convenient alternative is {@link\n * MiniSearch#discard}, which needs only the document ID, and has the same\n * visible effect, but delays cleaning up the index until the next vacuuming.\n *\n * @param document The document to be removed\n */\n remove (document: T): void {\n const { tokenize, processTerm, extractField, stringifyField, fields, idField } = this._options\n const id = extractField(document, idField)\n\n if (id == null) {\n throw new Error(`MiniSearch: document does not have ID field \"${idField}\"`)\n }\n\n const shortId = this._idToShortId.get(id)\n\n if (shortId == null) {\n throw new Error(`MiniSearch: cannot remove document with ID ${id}: it is not in the index`)\n }\n\n for (const field of fields) {\n const fieldValue = extractField(document, field)\n if (fieldValue == null) continue\n\n const tokens = tokenize(stringifyField(fieldValue, field), field)\n const fieldId = this._fieldIds[field]\n\n const uniqueTerms = new Set(tokens).size\n this.removeFieldLength(shortId, fieldId, this._documentCount, uniqueTerms)\n\n for (const term of tokens) {\n const processedTerm = processTerm(term, field)\n if (Array.isArray(processedTerm)) {\n for (const t of processedTerm) {\n this.removeTerm(fieldId, shortId, t)\n }\n } else if (processedTerm) {\n this.removeTerm(fieldId, shortId, processedTerm)\n }\n }\n }\n\n this._storedFields.delete(shortId)\n this._documentIds.delete(shortId)\n this._idToShortId.delete(id)\n this._fieldLength.delete(shortId)\n this._documentCount -= 1\n }\n\n /**\n * Removes all the given documents from the index. If called with no arguments,\n * it removes _all_ documents from the index.\n *\n * @param documents The documents to be removed. If this argument is omitted,\n * all documents are removed. Note that, for removing all documents, it is\n * more efficient to call this method with no arguments than to pass all\n * documents.\n */\n removeAll (documents?: readonly T[]): void {\n if (documents) {\n for (const document of documents) this.remove(document)\n } else if (arguments.length > 0) {\n throw new Error('Expected documents to be present. Omit the argument to remove all documents.')\n } else {\n this._index = new SearchableMap()\n this._documentCount = 0\n this._documentIds = new Map()\n this._idToShortId = new Map()\n this._fieldLength = new Map()\n this._avgFieldLength = []\n this._storedFields = new Map()\n this._nextId = 0\n }\n }\n\n /**\n * Discards the document with the given ID, so it won't appear in search results\n *\n * It has the same visible effect of {@link MiniSearch.remove} (both cause the\n * document to stop appearing in searches), but a different effect on the\n * internal data structures:\n *\n * - {@link MiniSearch#remove} requires passing the full document to be\n * removed as argument, and removes it from the inverted index immediately.\n *\n * - {@link MiniSearch#discard} instead only needs the document ID, and\n * works by marking the current version of the document as discarded, so it\n * is immediately ignored by searches. This is faster and more convenient\n * than {@link MiniSearch#remove}, but the index is not immediately\n * modified. To take care of that, vacuuming is performed after a certain\n * number of documents are discarded, cleaning up the index and allowing\n * memory to be released.\n *\n * After discarding a document, it is possible to re-add a new version, and\n * only the new version will appear in searches. In other words, discarding\n * and re-adding a document works exactly like removing and re-adding it. The\n * {@link MiniSearch.replace} method can also be used to replace a document\n * with a new version.\n *\n * #### Details about vacuuming\n *\n * Repetite calls to this method would leave obsolete document references in\n * the index, invisible to searches. Two mechanisms take care of cleaning up:\n * clean up during search, and vacuuming.\n *\n * - Upon search, whenever a discarded ID is found (and ignored for the\n * results), references to the discarded document are removed from the\n * inverted index entries for the search terms. This ensures that subsequent\n * searches for the same terms do not need to skip these obsolete references\n * again.\n *\n * - In addition, vacuuming is performed automatically by default (see the\n * `autoVacuum` field in {@link Options}) after a certain number of\n * documents are discarded. Vacuuming traverses all terms in the index,\n * cleaning up all references to discarded documents. Vacuuming can also be\n * triggered manually by calling {@link MiniSearch#vacuum}.\n *\n * @param id The ID of the document to be discarded\n */\n discard (id: any): void {\n const shortId = this._idToShortId.get(id)\n\n if (shortId == null) {\n throw new Error(`MiniSearch: cannot discard document with ID ${id}: it is not in the index`)\n }\n\n this._idToShortId.delete(id)\n this._documentIds.delete(shortId)\n this._storedFields.delete(shortId)\n\n ;(this._fieldLength.get(shortId) || []).forEach((fieldLength, fieldId) => {\n this.removeFieldLength(shortId, fieldId, this._documentCount, fieldLength)\n })\n\n this._fieldLength.delete(shortId)\n\n this._documentCount -= 1\n this._dirtCount += 1\n\n this.maybeAutoVacuum()\n }\n\n private maybeAutoVacuum (): void {\n if (this._options.autoVacuum === false) { return }\n\n const { minDirtFactor, minDirtCount, batchSize, batchWait } = this._options.autoVacuum\n this.conditionalVacuum({ batchSize, batchWait }, { minDirtCount, minDirtFactor })\n }\n\n /**\n * Discards the documents with the given IDs, so they won't appear in search\n * results\n *\n * It is equivalent to calling {@link MiniSearch#discard} for all the given\n * IDs, but with the optimization of triggering at most one automatic\n * vacuuming at the end.\n *\n * Note: to remove all documents from the index, it is faster and more\n * convenient to call {@link MiniSearch.removeAll} with no argument, instead\n * of passing all IDs to this method.\n */\n discardAll (ids: readonly any[]): void {\n const autoVacuum = this._options.autoVacuum\n\n try {\n this._options.autoVacuum = false\n\n for (const id of ids) {\n this.discard(id)\n }\n } finally {\n this._options.autoVacuum = autoVacuum\n }\n\n this.maybeAutoVacuum()\n }\n\n /**\n * It replaces an existing document with the given updated version\n *\n * It works by discarding the current version and adding the updated one, so\n * it is functionally equivalent to calling {@link MiniSearch#discard}\n * followed by {@link MiniSearch#add}. The ID of the updated document should\n * be the same as the original one.\n *\n * Since it uses {@link MiniSearch#discard} internally, this method relies on\n * vacuuming to clean up obsolete document references from the index, allowing\n * memory to be released (see {@link MiniSearch#discard}).\n *\n * @param updatedDocument The updated document to replace the old version\n * with\n */\n replace (updatedDocument: T): void {\n const { idField, extractField } = this._options\n const id = extractField(updatedDocument, idField)\n\n this.discard(id)\n this.add(updatedDocument)\n }\n\n /**\n * Triggers a manual vacuuming, cleaning up references to discarded documents\n * from the inverted index\n *\n * Vacuuming is only useful for applications that use the {@link\n * MiniSearch#discard} or {@link MiniSearch#replace} methods.\n *\n * By default, vacuuming is performed automatically when needed (controlled by\n * the `autoVacuum` field in {@link Options}), so there is usually no need to\n * call this method, unless one wants to make sure to perform vacuuming at a\n * specific moment.\n *\n * Vacuuming traverses all terms in the inverted index in batches, and cleans\n * up references to discarded documents from the posting list, allowing memory\n * to be released.\n *\n * The method takes an optional object as argument with the following keys:\n *\n * - `batchSize`: the size of each batch (1000 by default)\n *\n * - `batchWait`: the number of milliseconds to wait between batches (10 by\n * default)\n *\n * On large indexes, vacuuming could have a non-negligible cost: batching\n * avoids blocking the thread for long, diluting this cost so that it is not\n * negatively affecting the application. Nonetheless, this method should only\n * be called when necessary, and relying on automatic vacuuming is usually\n * better.\n *\n * It returns a promise that resolves (to undefined) when the clean up is\n * completed. If vacuuming is already ongoing at the time this method is\n * called, a new one is enqueued immediately after the ongoing one, and a\n * corresponding promise is returned. However, no more than one vacuuming is\n * enqueued on top of the ongoing one, even if this method is called more\n * times (enqueuing multiple ones would be useless).\n *\n * @param options Configuration options for the batch size and delay. See\n * {@link VacuumOptions}.\n */\n vacuum (options: VacuumOptions = {}): Promise {\n return this.conditionalVacuum(options)\n }\n\n private conditionalVacuum (options: VacuumOptions, conditions?: VacuumConditions): Promise {\n // If a vacuum is already ongoing, schedule another as soon as it finishes,\n // unless there's already one enqueued. If one was already enqueued, do not\n // enqueue another on top, but make sure that the conditions are the\n // broadest.\n if (this._currentVacuum) {\n this._enqueuedVacuumConditions = this._enqueuedVacuumConditions && conditions\n if (this._enqueuedVacuum != null) { return this._enqueuedVacuum }\n\n this._enqueuedVacuum = this._currentVacuum.then(() => {\n const conditions = this._enqueuedVacuumConditions\n this._enqueuedVacuumConditions = defaultVacuumConditions\n return this.performVacuuming(options, conditions)\n })\n return this._enqueuedVacuum\n }\n\n if (this.vacuumConditionsMet(conditions) === false) { return Promise.resolve() }\n\n this._currentVacuum = this.performVacuuming(options)\n return this._currentVacuum\n }\n\n private async performVacuuming (options: VacuumOptions, conditions?: VacuumConditions): Promise {\n const initialDirtCount = this._dirtCount\n\n if (this.vacuumConditionsMet(conditions)) {\n const batchSize = options.batchSize || defaultVacuumOptions.batchSize\n const batchWait = options.batchWait || defaultVacuumOptions.batchWait\n let i = 1\n\n for (const [term, fieldsData] of this._index) {\n for (const [fieldId, fieldIndex] of fieldsData) {\n for (const [shortId] of fieldIndex) {\n if (this._documentIds.has(shortId)) { continue }\n\n if (fieldIndex.size <= 1) {\n fieldsData.delete(fieldId)\n } else {\n fieldIndex.delete(shortId)\n }\n }\n }\n\n if (this._index.get(term)!.size === 0) {\n this._index.delete(term)\n }\n\n if (i % batchSize === 0) {\n await new Promise((resolve) => setTimeout(resolve, batchWait))\n }\n\n i += 1\n }\n\n this._dirtCount -= initialDirtCount\n }\n\n // Make the next lines always async, so they execute after this function returns\n await null\n\n this._currentVacuum = this._enqueuedVacuum\n this._enqueuedVacuum = null\n }\n\n private vacuumConditionsMet (conditions?: VacuumConditions) {\n if (conditions == null) { return true }\n\n let { minDirtCount, minDirtFactor } = conditions\n minDirtCount = minDirtCount || defaultAutoVacuumOptions.minDirtCount\n minDirtFactor = minDirtFactor || defaultAutoVacuumOptions.minDirtFactor\n\n return this.dirtCount >= minDirtCount && this.dirtFactor >= minDirtFactor\n }\n\n /**\n * Is `true` if a vacuuming operation is ongoing, `false` otherwise\n */\n get isVacuuming (): boolean {\n return this._currentVacuum != null\n }\n\n /**\n * The number of documents discarded since the most recent vacuuming\n */\n get dirtCount (): number {\n return this._dirtCount\n }\n\n /**\n * A number between 0 and 1 giving an indication about the proportion of\n * documents that are discarded, and can therefore be cleaned up by vacuuming.\n * A value close to 0 means that the index is relatively clean, while a higher\n * value means that the index is relatively dirty, and vacuuming could release\n * memory.\n */\n get dirtFactor (): number {\n return this._dirtCount / (1 + this._documentCount + this._dirtCount)\n }\n\n /**\n * Returns `true` if a document with the given ID is present in the index and\n * available for search, `false` otherwise\n *\n * @param id The document ID\n */\n has (id: any): boolean {\n return this._idToShortId.has(id)\n }\n\n /**\n * Returns the stored fields (as configured in the `storeFields` constructor\n * option) for the given document ID. Returns `undefined` if the document is\n * not present in the index.\n *\n * @param id The document ID\n */\n getStoredFields (id: any): Record | undefined {\n const shortId = this._idToShortId.get(id)\n\n if (shortId == null) { return undefined }\n\n return this._storedFields.get(shortId)\n }\n\n /**\n * Search for documents matching the given search query.\n *\n * The result is a list of scored document IDs matching the query, sorted by\n * descending score, and each including data about which terms were matched and\n * in which fields.\n *\n * ### Basic usage:\n *\n * ```javascript\n * // Search for \"zen art motorcycle\" with default options: terms have to match\n * // exactly, and individual terms are joined with OR\n * miniSearch.search('zen art motorcycle')\n * // => [ { id: 2, score: 2.77258, match: { ... } }, { id: 4, score: 1.38629, match: { ... } } ]\n * ```\n *\n * ### Restrict search to specific fields:\n *\n * ```javascript\n * // Search only in the 'title' field\n * miniSearch.search('zen', { fields: ['title'] })\n * ```\n *\n * ### Field boosting:\n *\n * ```javascript\n * // Boost a field\n * miniSearch.search('zen', { boost: { title: 2 } })\n * ```\n *\n * ### Prefix search:\n *\n * ```javascript\n * // Search for \"moto\" with prefix search (it will match documents\n * // containing terms that start with \"moto\" or \"neuro\")\n * miniSearch.search('moto neuro', { prefix: true })\n * ```\n *\n * ### Fuzzy search:\n *\n * ```javascript\n * // Search for \"ismael\" with fuzzy search (it will match documents containing\n * // terms similar to \"ismael\", with a maximum edit distance of 0.2 term.length\n * // (rounded to nearest integer)\n * miniSearch.search('ismael', { fuzzy: 0.2 })\n * ```\n *\n * ### Combining strategies:\n *\n * ```javascript\n * // Mix of exact match, prefix search, and fuzzy search\n * miniSearch.search('ismael mob', {\n * prefix: true,\n * fuzzy: 0.2\n * })\n * ```\n *\n * ### Advanced prefix and fuzzy search:\n *\n * ```javascript\n * // Perform fuzzy and prefix search depending on the search term. Here\n * // performing prefix and fuzzy search only on terms longer than 3 characters\n * miniSearch.search('ismael mob', {\n * prefix: term => term.length > 3\n * fuzzy: term => term.length > 3 ? 0.2 : null\n * })\n * ```\n *\n * ### Combine with AND:\n *\n * ```javascript\n * // Combine search terms with AND (to match only documents that contain both\n * // \"motorcycle\" and \"art\")\n * miniSearch.search('motorcycle art', { combineWith: 'AND' })\n * ```\n *\n * ### Combine with AND_NOT:\n *\n * There is also an AND_NOT combinator, that finds documents that match the\n * first term, but do not match any of the other terms. This combinator is\n * rarely useful with simple queries, and is meant to be used with advanced\n * query combinations (see later for more details).\n *\n * ### Filtering results:\n *\n * ```javascript\n * // Filter only results in the 'fiction' category (assuming that 'category'\n * // is a stored field)\n * miniSearch.search('motorcycle art', {\n * filter: (result) => result.category === 'fiction'\n * })\n * ```\n *\n * ### Wildcard query\n *\n * Searching for an empty string (assuming the default tokenizer) returns no\n * results. Sometimes though, one needs to match all documents, like in a\n * \"wildcard\" search. This is possible by passing the special value\n * {@link MiniSearch.wildcard} as the query:\n *\n * ```javascript\n * // Return search results for all documents\n * miniSearch.search(MiniSearch.wildcard)\n * ```\n *\n * Note that search options such as `filter` and `boostDocument` are still\n * applied, influencing which results are returned, and their order:\n *\n * ```javascript\n * // Return search results for all documents in the 'fiction' category\n * miniSearch.search(MiniSearch.wildcard, {\n * filter: (result) => result.category === 'fiction'\n * })\n * ```\n *\n * ### Advanced combination of queries:\n *\n * It is possible to combine different subqueries with OR, AND, and AND_NOT,\n * and even with different search options, by passing a query expression\n * tree object as the first argument, instead of a string.\n *\n * ```javascript\n * // Search for documents that contain \"zen\" and (\"motorcycle\" or \"archery\")\n * miniSearch.search({\n * combineWith: 'AND',\n * queries: [\n * 'zen',\n * {\n * combineWith: 'OR',\n * queries: ['motorcycle', 'archery']\n * }\n * ]\n * })\n *\n * // Search for documents that contain (\"apple\" or \"pear\") but not \"juice\" and\n * // not \"tree\"\n * miniSearch.search({\n * combineWith: 'AND_NOT',\n * queries: [\n * {\n * combineWith: 'OR',\n * queries: ['apple', 'pear']\n * },\n * 'juice',\n * 'tree'\n * ]\n * })\n * ```\n *\n * Each node in the expression tree can be either a string, or an object that\n * supports all {@link SearchOptions} fields, plus a `queries` array field for\n * subqueries.\n *\n * Note that, while this can become complicated to do by hand for complex or\n * deeply nested queries, it provides a formalized expression tree API for\n * external libraries that implement a parser for custom query languages.\n *\n * @param query Search query\n * @param searchOptions Search options. Each option, if not given, defaults to the corresponding value of `searchOptions` given to the constructor, or to the library default.\n */\n search (query: Query, searchOptions: SearchOptions = {}): SearchResult[] {\n const { searchOptions: globalSearchOptions } = this._options\n const searchOptionsWithDefaults: SearchOptionsWithDefaults = { ...globalSearchOptions, ...searchOptions }\n\n const rawResults = this.executeQuery(query, searchOptions)\n const results = []\n\n for (const [docId, { score, terms, match }] of rawResults) {\n // terms are the matched query terms, which will be returned to the user\n // as queryTerms. The quality is calculated based on them, as opposed to\n // the matched terms in the document (which can be different due to\n // prefix and fuzzy match)\n const quality = terms.length || 1\n\n const result = {\n id: this._documentIds.get(docId),\n score: score * quality,\n terms: Object.keys(match),\n queryTerms: terms,\n match\n }\n\n Object.assign(result, this._storedFields.get(docId))\n if (searchOptionsWithDefaults.filter == null || searchOptionsWithDefaults.filter(result)) {\n results.push(result)\n }\n }\n\n // If it's a wildcard query, and no document boost is applied, skip sorting\n // the results, as all results have the same score of 1\n if (query === MiniSearch.wildcard && searchOptionsWithDefaults.boostDocument == null) {\n return results\n }\n\n results.sort(byScore)\n return results\n }\n\n /**\n * Provide suggestions for the given search query\n *\n * The result is a list of suggested modified search queries, derived from the\n * given search query, each with a relevance score, sorted by descending score.\n *\n * By default, it uses the same options used for search, except that by\n * default it performs prefix search on the last term of the query, and\n * combine terms with `'AND'` (requiring all query terms to match). Custom\n * options can be passed as a second argument. Defaults can be changed upon\n * calling the {@link MiniSearch} constructor, by passing a\n * `autoSuggestOptions` option.\n *\n * ### Basic usage:\n *\n * ```javascript\n * // Get suggestions for 'neuro':\n * miniSearch.autoSuggest('neuro')\n * // => [ { suggestion: 'neuromancer', terms: [ 'neuromancer' ], score: 0.46240 } ]\n * ```\n *\n * ### Multiple words:\n *\n * ```javascript\n * // Get suggestions for 'zen ar':\n * miniSearch.autoSuggest('zen ar')\n * // => [\n * // { suggestion: 'zen archery art', terms: [ 'zen', 'archery', 'art' ], score: 1.73332 },\n * // { suggestion: 'zen art', terms: [ 'zen', 'art' ], score: 1.21313 }\n * // ]\n * ```\n *\n * ### Fuzzy suggestions:\n *\n * ```javascript\n * // Correct spelling mistakes using fuzzy search:\n * miniSearch.autoSuggest('neromancer', { fuzzy: 0.2 })\n * // => [ { suggestion: 'neuromancer', terms: [ 'neuromancer' ], score: 1.03998 } ]\n * ```\n *\n * ### Filtering:\n *\n * ```javascript\n * // Get suggestions for 'zen ar', but only within the 'fiction' category\n * // (assuming that 'category' is a stored field):\n * miniSearch.autoSuggest('zen ar', {\n * filter: (result) => result.category === 'fiction'\n * })\n * // => [\n * // { suggestion: 'zen archery art', terms: [ 'zen', 'archery', 'art' ], score: 1.73332 },\n * // { suggestion: 'zen art', terms: [ 'zen', 'art' ], score: 1.21313 }\n * // ]\n * ```\n *\n * @param queryString Query string to be expanded into suggestions\n * @param options Search options. The supported options and default values\n * are the same as for the {@link MiniSearch#search} method, except that by\n * default prefix search is performed on the last term in the query, and terms\n * are combined with `'AND'`.\n * @return A sorted array of suggestions sorted by relevance score.\n */\n autoSuggest (queryString: string, options: SearchOptions = {}): Suggestion[] {\n options = { ...this._options.autoSuggestOptions, ...options }\n\n const suggestions: Map & { count: number }> = new Map()\n\n for (const { score, terms } of this.search(queryString, options)) {\n const phrase = terms.join(' ')\n const suggestion = suggestions.get(phrase)\n if (suggestion != null) {\n suggestion.score += score\n suggestion.count += 1\n } else {\n suggestions.set(phrase, { score, terms, count: 1 })\n }\n }\n\n const results = []\n for (const [suggestion, { score, terms, count }] of suggestions) {\n results.push({ suggestion, terms, score: score / count })\n }\n\n results.sort(byScore)\n return results\n }\n\n /**\n * Total number of documents available to search\n */\n get documentCount (): number {\n return this._documentCount\n }\n\n /**\n * Number of terms in the index\n */\n get termCount (): number {\n return this._index.size\n }\n\n /**\n * Deserializes a JSON index (serialized with `JSON.stringify(miniSearch)`)\n * and instantiates a MiniSearch instance. It should be given the same options\n * originally used when serializing the index.\n *\n * ### Usage:\n *\n * ```javascript\n * // If the index was serialized with:\n * let miniSearch = new MiniSearch({ fields: ['title', 'text'] })\n * miniSearch.addAll(documents)\n *\n * const json = JSON.stringify(miniSearch)\n * // It can later be deserialized like this:\n * miniSearch = MiniSearch.loadJSON(json, { fields: ['title', 'text'] })\n * ```\n *\n * @param json JSON-serialized index\n * @param options configuration options, same as the constructor\n * @return An instance of MiniSearch deserialized from the given JSON.\n */\n static loadJSON (json: string, options: Options): MiniSearch {\n if (options == null) {\n throw new Error('MiniSearch: loadJSON should be given the same options used when serializing the index')\n }\n return this.loadJS(JSON.parse(json), options)\n }\n\n /**\n * Async equivalent of {@link MiniSearch.loadJSON}\n *\n * This function is an alternative to {@link MiniSearch.loadJSON} that returns\n * a promise, and loads the index in batches, leaving pauses between them to avoid\n * blocking the main thread. It tends to be slower than the synchronous\n * version, but does not block the main thread, so it can be a better choice\n * when deserializing very large indexes.\n *\n * @param json JSON-serialized index\n * @param options configuration options, same as the constructor\n * @return A Promise that will resolve to an instance of MiniSearch deserialized from the given JSON.\n */\n static async loadJSONAsync (json: string, options: Options): Promise> {\n if (options == null) {\n throw new Error('MiniSearch: loadJSON should be given the same options used when serializing the index')\n }\n return this.loadJSAsync(JSON.parse(json), options)\n }\n\n /**\n * Returns the default value of an option. It will throw an error if no option\n * with the given name exists.\n *\n * @param optionName Name of the option\n * @return The default value of the given option\n *\n * ### Usage:\n *\n * ```javascript\n * // Get default tokenizer\n * MiniSearch.getDefault('tokenize')\n *\n * // Get default term processor\n * MiniSearch.getDefault('processTerm')\n *\n * // Unknown options will throw an error\n * MiniSearch.getDefault('notExisting')\n * // => throws 'MiniSearch: unknown option \"notExisting\"'\n * ```\n */\n static getDefault (optionName: string): any {\n if (defaultOptions.hasOwnProperty(optionName)) {\n return getOwnProperty(defaultOptions, optionName)\n } else {\n throw new Error(`MiniSearch: unknown option \"${optionName}\"`)\n }\n }\n\n /**\n * @ignore\n */\n static loadJS (js: AsPlainObject, options: Options): MiniSearch {\n const {\n index,\n documentIds,\n fieldLength,\n storedFields,\n serializationVersion\n } = js\n\n const miniSearch = this.instantiateMiniSearch(js, options)\n\n miniSearch._documentIds = objectToNumericMap(documentIds)\n miniSearch._fieldLength = objectToNumericMap(fieldLength)\n miniSearch._storedFields = objectToNumericMap(storedFields)\n\n for (const [shortId, id] of miniSearch._documentIds) {\n miniSearch._idToShortId.set(id, shortId)\n }\n\n for (const [term, data] of index) {\n const dataMap = new Map() as FieldTermData\n\n for (const fieldId of Object.keys(data)) {\n let indexEntry = data[fieldId]\n\n // Version 1 used to nest the index entry inside a field called ds\n if (serializationVersion === 1) {\n indexEntry = indexEntry.ds as unknown as SerializedIndexEntry\n }\n\n dataMap.set(parseInt(fieldId, 10), objectToNumericMap(indexEntry) as DocumentTermFreqs)\n }\n\n miniSearch._index.set(term, dataMap)\n }\n\n return miniSearch\n }\n\n /**\n * @ignore\n */\n static async loadJSAsync (js: AsPlainObject, options: Options): Promise> {\n const {\n index,\n documentIds,\n fieldLength,\n storedFields,\n serializationVersion\n } = js\n\n const miniSearch = this.instantiateMiniSearch(js, options)\n\n miniSearch._documentIds = await objectToNumericMapAsync(documentIds)\n miniSearch._fieldLength = await objectToNumericMapAsync(fieldLength)\n miniSearch._storedFields = await objectToNumericMapAsync(storedFields)\n\n for (const [shortId, id] of miniSearch._documentIds) {\n miniSearch._idToShortId.set(id, shortId)\n }\n\n let count = 0\n for (const [term, data] of index) {\n const dataMap = new Map() as FieldTermData\n\n for (const fieldId of Object.keys(data)) {\n let indexEntry = data[fieldId]\n\n // Version 1 used to nest the index entry inside a field called ds\n if (serializationVersion === 1) {\n indexEntry = indexEntry.ds as unknown as SerializedIndexEntry\n }\n\n dataMap.set(parseInt(fieldId, 10), await objectToNumericMapAsync(indexEntry) as DocumentTermFreqs)\n }\n\n if (++count % 1000 === 0) await wait(0)\n miniSearch._index.set(term, dataMap)\n }\n\n return miniSearch\n }\n\n /**\n * @ignore\n */\n private static instantiateMiniSearch (js: AsPlainObject, options: Options): MiniSearch {\n const {\n documentCount,\n nextId,\n fieldIds,\n averageFieldLength,\n dirtCount,\n serializationVersion\n } = js\n\n if (serializationVersion !== 1 && serializationVersion !== 2) {\n throw new Error('MiniSearch: cannot deserialize an index created with an incompatible version')\n }\n\n const miniSearch = new MiniSearch(options)\n\n miniSearch._documentCount = documentCount\n miniSearch._nextId = nextId\n miniSearch._idToShortId = new Map()\n miniSearch._fieldIds = fieldIds\n miniSearch._avgFieldLength = averageFieldLength\n miniSearch._dirtCount = dirtCount || 0\n miniSearch._index = new SearchableMap()\n\n return miniSearch\n }\n\n /**\n * @ignore\n */\n private executeQuery (query: Query, searchOptions: SearchOptions = {}): RawResult {\n if (query === MiniSearch.wildcard) {\n return this.executeWildcardQuery(searchOptions)\n }\n\n if (typeof query !== 'string') {\n const options = { ...searchOptions, ...query, queries: undefined }\n const results = query.queries.map((subquery) => this.executeQuery(subquery, options))\n return this.combineResults(results, options.combineWith)\n }\n\n const { tokenize, processTerm, searchOptions: globalSearchOptions } = this._options\n const options = { tokenize, processTerm, ...globalSearchOptions, ...searchOptions }\n const { tokenize: searchTokenize, processTerm: searchProcessTerm } = options\n const terms = searchTokenize(query)\n .flatMap((term: string) => searchProcessTerm(term))\n .filter((term) => !!term) as string[]\n const queries: QuerySpec[] = terms.map(termToQuerySpec(options))\n const results = queries.map(query => this.executeQuerySpec(query, options))\n\n return this.combineResults(results, options.combineWith)\n }\n\n /**\n * @ignore\n */\n private executeQuerySpec (query: QuerySpec, searchOptions: SearchOptions): RawResult {\n const options: SearchOptionsWithDefaults = { ...this._options.searchOptions, ...searchOptions }\n\n const boosts = (options.fields || this._options.fields).reduce((boosts, field) =>\n ({ ...boosts, [field]: getOwnProperty(options.boost, field) || 1 }), {})\n\n const {\n boostDocument,\n weights,\n maxFuzzy,\n bm25: bm25params\n } = options\n\n const { fuzzy: fuzzyWeight, prefix: prefixWeight } = { ...defaultSearchOptions.weights, ...weights }\n\n const data = this._index.get(query.term)\n const results = this.termResults(query.term, query.term, 1, query.termBoost, data, boosts, boostDocument, bm25params)\n\n let prefixMatches\n let fuzzyMatches\n\n if (query.prefix) {\n prefixMatches = this._index.atPrefix(query.term)\n }\n\n if (query.fuzzy) {\n const fuzzy = (query.fuzzy === true) ? 0.2 : query.fuzzy\n const maxDistance = fuzzy < 1 ? Math.min(maxFuzzy, Math.round(query.term.length * fuzzy)) : fuzzy\n if (maxDistance) fuzzyMatches = this._index.fuzzyGet(query.term, maxDistance)\n }\n\n if (prefixMatches) {\n for (const [term, data] of prefixMatches) {\n const distance = term.length - query.term.length\n if (!distance) { continue } // Skip exact match.\n\n // Delete the term from fuzzy results (if present) if it is also a\n // prefix result. This entry will always be scored as a prefix result.\n fuzzyMatches?.delete(term)\n\n // Weight gradually approaches 0 as distance goes to infinity, with the\n // weight for the hypothetical distance 0 being equal to prefixWeight.\n // The rate of change is much lower than that of fuzzy matches to\n // account for the fact that prefix matches stay more relevant than\n // fuzzy matches for longer distances.\n const weight = prefixWeight * term.length / (term.length + 0.3 * distance)\n this.termResults(query.term, term, weight, query.termBoost, data, boosts, boostDocument, bm25params, results)\n }\n }\n\n if (fuzzyMatches) {\n for (const term of fuzzyMatches.keys()) {\n const [data, distance] = fuzzyMatches.get(term)!\n if (!distance) { continue } // Skip exact match.\n\n // Weight gradually approaches 0 as distance goes to infinity, with the\n // weight for the hypothetical distance 0 being equal to fuzzyWeight.\n const weight = fuzzyWeight * term.length / (term.length + distance)\n this.termResults(query.term, term, weight, query.termBoost, data, boosts, boostDocument, bm25params, results)\n }\n }\n\n return results\n }\n\n /**\n * @ignore\n */\n private executeWildcardQuery (searchOptions: SearchOptions): RawResult {\n const results = new Map() as RawResult\n const options: SearchOptionsWithDefaults = { ...this._options.searchOptions, ...searchOptions }\n\n for (const [shortId, id] of this._documentIds) {\n const score = options.boostDocument ? options.boostDocument(id, '', this._storedFields.get(shortId)) : 1\n results.set(shortId, {\n score,\n terms: [],\n match: {}\n })\n }\n\n return results\n }\n\n /**\n * @ignore\n */\n private combineResults (results: RawResult[], combineWith: CombinationOperator = OR): RawResult {\n if (results.length === 0) { return new Map() }\n const operator = combineWith.toLowerCase()\n const combinator = (combinators as Record)[operator]\n\n if (!combinator) {\n throw new Error(`Invalid combination operator: ${combineWith}`)\n }\n\n return results.reduce(combinator) || new Map()\n }\n\n /**\n * Allows serialization of the index to JSON, to possibly store it and later\n * deserialize it with {@link MiniSearch.loadJSON}.\n *\n * Normally one does not directly call this method, but rather call the\n * standard JavaScript `JSON.stringify()` passing the {@link MiniSearch}\n * instance, and JavaScript will internally call this method. Upon\n * deserialization, one must pass to {@link MiniSearch.loadJSON} the same\n * options used to create the original instance that was serialized.\n *\n * ### Usage:\n *\n * ```javascript\n * // Serialize the index:\n * let miniSearch = new MiniSearch({ fields: ['title', 'text'] })\n * miniSearch.addAll(documents)\n * const json = JSON.stringify(miniSearch)\n *\n * // Later, to deserialize it:\n * miniSearch = MiniSearch.loadJSON(json, { fields: ['title', 'text'] })\n * ```\n *\n * @return A plain-object serializable representation of the search index.\n */\n toJSON (): AsPlainObject {\n const index: [string, { [key: string]: SerializedIndexEntry }][] = []\n\n for (const [term, fieldIndex] of this._index) {\n const data: { [key: string]: SerializedIndexEntry } = {}\n\n for (const [fieldId, freqs] of fieldIndex) {\n data[fieldId] = Object.fromEntries(freqs)\n }\n\n index.push([term, data])\n }\n\n return {\n documentCount: this._documentCount,\n nextId: this._nextId,\n documentIds: Object.fromEntries(this._documentIds),\n fieldIds: this._fieldIds,\n fieldLength: Object.fromEntries(this._fieldLength),\n averageFieldLength: this._avgFieldLength,\n storedFields: Object.fromEntries(this._storedFields),\n dirtCount: this._dirtCount,\n index,\n serializationVersion: 2\n }\n }\n\n /**\n * @ignore\n */\n private termResults (\n sourceTerm: string,\n derivedTerm: string,\n termWeight: number,\n termBoost: number,\n fieldTermData: FieldTermData | undefined,\n fieldBoosts: { [field: string]: number },\n boostDocumentFn: ((id: any, term: string, storedFields?: Record) => number) | undefined,\n bm25params: BM25Params,\n results: RawResult = new Map()\n ): RawResult {\n if (fieldTermData == null) return results\n\n for (const field of Object.keys(fieldBoosts)) {\n const fieldBoost = fieldBoosts[field]\n const fieldId = this._fieldIds[field]\n\n const fieldTermFreqs = fieldTermData.get(fieldId)\n if (fieldTermFreqs == null) continue\n\n let matchingFields = fieldTermFreqs.size\n const avgFieldLength = this._avgFieldLength[fieldId]\n\n for (const docId of fieldTermFreqs.keys()) {\n if (!this._documentIds.has(docId)) {\n this.removeTerm(fieldId, docId, derivedTerm)\n matchingFields -= 1\n continue\n }\n\n const docBoost = boostDocumentFn ? boostDocumentFn(this._documentIds.get(docId), derivedTerm, this._storedFields.get(docId)) : 1\n if (!docBoost) continue\n\n const termFreq = fieldTermFreqs.get(docId)!\n const fieldLength = this._fieldLength.get(docId)![fieldId]\n\n // NOTE: The total number of fields is set to the number of documents\n // `this._documentCount`. It could also make sense to use the number of\n // documents where the current field is non-blank as a normalization\n // factor. This will make a difference in scoring if the field is rarely\n // present. This is currently not supported, and may require further\n // analysis to see if it is a valid use case.\n const rawScore = calcBM25Score(termFreq, matchingFields, this._documentCount, fieldLength, avgFieldLength, bm25params)\n const weightedScore = termWeight * termBoost * fieldBoost * docBoost * rawScore\n\n const result = results.get(docId)\n if (result) {\n result.score += weightedScore\n assignUniqueTerm(result.terms, sourceTerm)\n const match = getOwnProperty(result.match, derivedTerm)\n if (match) {\n match.push(field)\n } else {\n result.match[derivedTerm] = [field]\n }\n } else {\n results.set(docId, {\n score: weightedScore,\n terms: [sourceTerm],\n match: { [derivedTerm]: [field] }\n })\n }\n }\n }\n\n return results\n }\n\n /**\n * @ignore\n */\n private addTerm (fieldId: number, documentId: number, term: string): void {\n const indexData = this._index.fetch(term, createMap)\n\n let fieldIndex = indexData.get(fieldId)\n if (fieldIndex == null) {\n fieldIndex = new Map()\n fieldIndex.set(documentId, 1)\n indexData.set(fieldId, fieldIndex)\n } else {\n const docs = fieldIndex.get(documentId)\n fieldIndex.set(documentId, (docs || 0) + 1)\n }\n }\n\n /**\n * @ignore\n */\n private removeTerm (fieldId: number, documentId: number, term: string): void {\n if (!this._index.has(term)) {\n this.warnDocumentChanged(documentId, fieldId, term)\n return\n }\n\n const indexData = this._index.fetch(term, createMap)\n\n const fieldIndex = indexData.get(fieldId)\n if (fieldIndex == null || fieldIndex.get(documentId) == null) {\n this.warnDocumentChanged(documentId, fieldId, term)\n } else if (fieldIndex.get(documentId)! <= 1) {\n if (fieldIndex.size <= 1) {\n indexData.delete(fieldId)\n } else {\n fieldIndex.delete(documentId)\n }\n } else {\n fieldIndex.set(documentId, fieldIndex.get(documentId)! - 1)\n }\n\n if (this._index.get(term)!.size === 0) {\n this._index.delete(term)\n }\n }\n\n /**\n * @ignore\n */\n private warnDocumentChanged (shortDocumentId: number, fieldId: number, term: string): void {\n for (const fieldName of Object.keys(this._fieldIds)) {\n if (this._fieldIds[fieldName] === fieldId) {\n this._options.logger('warn', `MiniSearch: document with ID ${this._documentIds.get(shortDocumentId)} has changed before removal: term \"${term}\" was not present in field \"${fieldName}\". Removing a document after it has changed can corrupt the index!`, 'version_conflict')\n return\n }\n }\n }\n\n /**\n * @ignore\n */\n private addDocumentId (documentId: any): number {\n const shortDocumentId = this._nextId\n this._idToShortId.set(documentId, shortDocumentId)\n this._documentIds.set(shortDocumentId, documentId)\n this._documentCount += 1\n this._nextId += 1\n return shortDocumentId\n }\n\n /**\n * @ignore\n */\n private addFields (fields: string[]): void {\n for (let i = 0; i < fields.length; i++) {\n this._fieldIds[fields[i]] = i\n }\n }\n\n /**\n * @ignore\n */\n private addFieldLength (documentId: number, fieldId: number, count: number, length: number): void {\n let fieldLengths = this._fieldLength.get(documentId)\n if (fieldLengths == null) this._fieldLength.set(documentId, fieldLengths = [])\n fieldLengths[fieldId] = length\n\n const averageFieldLength = this._avgFieldLength[fieldId] || 0\n const totalFieldLength = (averageFieldLength * count) + length\n this._avgFieldLength[fieldId] = totalFieldLength / (count + 1)\n }\n\n /**\n * @ignore\n */\n private removeFieldLength (documentId: number, fieldId: number, count: number, length: number): void {\n if (count === 1) {\n this._avgFieldLength[fieldId] = 0\n return\n }\n const totalFieldLength = (this._avgFieldLength[fieldId] * count) - length\n this._avgFieldLength[fieldId] = totalFieldLength / (count - 1)\n }\n\n /**\n * @ignore\n */\n private saveStoredFields (documentId: number, doc: T): void {\n const { storeFields, extractField } = this._options\n if (storeFields == null || storeFields.length === 0) { return }\n\n let documentFields = this._storedFields.get(documentId)\n if (documentFields == null) this._storedFields.set(documentId, documentFields = {})\n\n for (const fieldName of storeFields) {\n const fieldValue = extractField(doc, fieldName)\n if (fieldValue !== undefined) documentFields[fieldName] = fieldValue\n }\n }\n}\n\nconst getOwnProperty = (object: any, property: string) =>\n Object.prototype.hasOwnProperty.call(object, property) ? object[property] : undefined\n\ntype CombinatorFunction = (a: RawResult, b: RawResult) => RawResult\n\nconst combinators: Record = {\n [OR]: (a: RawResult, b: RawResult) => {\n for (const docId of b.keys()) {\n const existing = a.get(docId)\n if (existing == null) {\n a.set(docId, b.get(docId)!)\n } else {\n const { score, terms, match } = b.get(docId)!\n existing.score = existing.score + score\n existing.match = Object.assign(existing.match, match)\n assignUniqueTerms(existing.terms, terms)\n }\n }\n\n return a\n },\n [AND]: (a: RawResult, b: RawResult) => {\n const combined = new Map()\n\n for (const docId of b.keys()) {\n const existing = a.get(docId)\n if (existing == null) continue\n\n const { score, terms, match } = b.get(docId)!\n assignUniqueTerms(existing.terms, terms)\n combined.set(docId, {\n score: existing.score + score,\n terms: existing.terms,\n match: Object.assign(existing.match, match)\n })\n }\n\n return combined\n },\n [AND_NOT]: (a: RawResult, b: RawResult) => {\n for (const docId of b.keys()) a.delete(docId)\n return a\n }\n}\n\n/**\n * Parameters of the BM25+ scoring algorithm. Customizing these is almost never\n * necessary, and finetuning them requires an understanding of the BM25 scoring\n * model.\n *\n * Some information about BM25 (and BM25+) can be found at these links:\n *\n * - https://en.wikipedia.org/wiki/Okapi_BM25\n * - https://opensourceconnections.com/blog/2015/10/16/bm25-the-next-generation-of-lucene-relevation/\n */\nexport type BM25Params = {\n /** Term frequency saturation point.\n *\n * Recommended values are between `1.2` and `2`. Higher values increase the\n * difference in score between documents with higher and lower term\n * frequencies. Setting this to `0` or a negative value is invalid. Defaults\n * to `1.2`\n */\n k: number,\n\n /**\n * Length normalization impact.\n *\n * Recommended values are around `0.75`. Higher values increase the weight\n * that field length has on scoring. Setting this to `0` (not recommended)\n * means that the field length has no effect on scoring. Negative values are\n * invalid. Defaults to `0.7`.\n */\n b: number,\n\n /**\n * BM25+ frequency normalization lower bound (usually called δ).\n *\n * Recommended values are between `0.5` and `1`. Increasing this parameter\n * increases the minimum relevance of one occurrence of a search term\n * regardless of its (possibly very long) field length. Negative values are\n * invalid. Defaults to `0.5`.\n */\n d: number\n}\n\nconst defaultBM25params: BM25Params = { k: 1.2, b: 0.7, d: 0.5 }\n\nconst calcBM25Score = (\n termFreq: number,\n matchingCount: number,\n totalCount: number,\n fieldLength: number,\n avgFieldLength: number,\n bm25params: BM25Params\n): number => {\n const { k, b, d } = bm25params\n const invDocFreq = Math.log(1 + (totalCount - matchingCount + 0.5) / (matchingCount + 0.5))\n return invDocFreq * (d + termFreq * (k + 1) / (termFreq + k * (1 - b + b * fieldLength / avgFieldLength)))\n}\n\nconst termToQuerySpec = (options: SearchOptions) => (term: string, i: number, terms: string[]): QuerySpec => {\n const fuzzy = (typeof options.fuzzy === 'function')\n ? options.fuzzy(term, i, terms)\n : (options.fuzzy || false)\n const prefix = (typeof options.prefix === 'function')\n ? options.prefix(term, i, terms)\n : (options.prefix === true)\n const termBoost = (typeof options.boostTerm === 'function')\n ? options.boostTerm(term, i, terms)\n : 1\n return { term, fuzzy, prefix, termBoost }\n}\n\nconst defaultOptions = {\n idField: 'id',\n extractField: (document: any, fieldName: string) => document[fieldName],\n stringifyField: (fieldValue: any, fieldName: string) => fieldValue.toString(),\n tokenize: (text: string) => text.split(SPACE_OR_PUNCTUATION),\n processTerm: (term: string) => term.toLowerCase(),\n fields: undefined,\n searchOptions: undefined,\n storeFields: [],\n logger: (level: LogLevel, message: string): void => {\n if (typeof console?.[level] === 'function') console[level](message)\n },\n autoVacuum: true\n}\n\nconst defaultSearchOptions = {\n combineWith: OR,\n prefix: false,\n fuzzy: false,\n maxFuzzy: 6,\n boost: {},\n weights: { fuzzy: 0.45, prefix: 0.375 },\n bm25: defaultBM25params\n}\n\nconst defaultAutoSuggestOptions = {\n combineWith: AND,\n prefix: (term: string, i: number, terms: string[]): boolean =>\n i === terms.length - 1\n}\n\nconst defaultVacuumOptions = { batchSize: 1000, batchWait: 10 }\nconst defaultVacuumConditions = { minDirtFactor: 0.1, minDirtCount: 20 }\n\nconst defaultAutoVacuumOptions = { ...defaultVacuumOptions, ...defaultVacuumConditions }\n\nconst assignUniqueTerm = (target: string[], term: string): void => {\n // Avoid adding duplicate terms.\n if (!target.includes(term)) target.push(term)\n}\n\nconst assignUniqueTerms = (target: string[], source: readonly string[]): void => {\n for (const term of source) {\n // Avoid adding duplicate terms.\n if (!target.includes(term)) target.push(term)\n }\n}\n\ntype Scored = { score: number }\nconst byScore = ({ score: a }: Scored, { score: b }: Scored) => b - a\n\nconst createMap = () => new Map()\n\ninterface SerializedIndexEntry {\n [key: string]: number\n}\n\nconst objectToNumericMap = (object: { [key: string]: T }): Map => {\n const map = new Map()\n\n for (const key of Object.keys(object)) {\n map.set(parseInt(key, 10), object[key])\n }\n\n return map\n}\n\nconst objectToNumericMapAsync = async (object: { [key: string]: T }): Promise> => {\n const map = new Map()\n\n let count = 0\n for (const key of Object.keys(object)) {\n map.set(parseInt(key, 10), object[key])\n if (++count % 1000 === 0) {\n await wait(0)\n }\n }\n\n return map\n}\n\nconst wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))\n\n// This regular expression matches any Unicode space, newline, or punctuation\n// character\nconst SPACE_OR_PUNCTUATION = /[\\n\\r\\p{Z}\\p{P}]+/u\n"], - "mappings": "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", - "names": ["last", "node", "child", "key", "chunk", "promise", "conditions", "options", "results", "query", "boosts", "data"] -} diff --git a/www/docs/.vitepress/cache/deps/vue.js b/www/docs/.vitepress/cache/deps/vue.js deleted file mode 100644 index 1e4f0e3..0000000 --- a/www/docs/.vitepress/cache/deps/vue.js +++ /dev/null @@ -1,347 +0,0 @@ -import { - BaseTransition, - BaseTransitionPropsValidators, - Comment, - DeprecationTypes, - EffectScope, - ErrorCodes, - ErrorTypeStrings, - Fragment, - KeepAlive, - ReactiveEffect, - Static, - Suspense, - Teleport, - Text, - TrackOpTypes, - Transition, - TransitionGroup, - TriggerOpTypes, - VueElement, - assertNumber, - callWithAsyncErrorHandling, - callWithErrorHandling, - camelize, - capitalize, - cloneVNode, - compatUtils, - compile, - computed, - createApp, - createBaseVNode, - createBlock, - createCommentVNode, - createElementBlock, - createHydrationRenderer, - createPropsRestProxy, - createRenderer, - createSSRApp, - createSlots, - createStaticVNode, - createTextVNode, - createVNode, - customRef, - defineAsyncComponent, - defineComponent, - defineCustomElement, - defineEmits, - defineExpose, - defineModel, - defineOptions, - defineProps, - defineSSRCustomElement, - defineSlots, - devtools, - effect, - effectScope, - getCurrentInstance, - getCurrentScope, - getCurrentWatcher, - getTransitionRawChildren, - guardReactiveProps, - h, - handleError, - hasInjectionContext, - hydrate, - hydrateOnIdle, - hydrateOnInteraction, - hydrateOnMediaQuery, - hydrateOnVisible, - initCustomFormatter, - initDirectivesForSSR, - inject, - isMemoSame, - isProxy, - isReactive, - isReadonly, - isRef, - isRuntimeOnly, - isShallow, - isVNode, - markRaw, - mergeDefaults, - mergeModels, - mergeProps, - nextTick, - nodeOps, - normalizeClass, - normalizeProps, - normalizeStyle, - onActivated, - onBeforeMount, - onBeforeUnmount, - onBeforeUpdate, - onDeactivated, - onErrorCaptured, - onMounted, - onRenderTracked, - onRenderTriggered, - onScopeDispose, - onServerPrefetch, - onUnmounted, - onUpdated, - onWatcherCleanup, - openBlock, - patchProp, - popScopeId, - provide, - proxyRefs, - pushScopeId, - queuePostFlushCb, - reactive, - readonly, - ref, - registerRuntimeCompiler, - render, - renderList, - renderSlot, - resolveComponent, - resolveDirective, - resolveDynamicComponent, - resolveFilter, - resolveTransitionHooks, - setBlockTracking, - setDevtoolsHook, - setTransitionHooks, - shallowReactive, - shallowReadonly, - shallowRef, - ssrContextKey, - ssrUtils, - stop, - toDisplayString, - toHandlerKey, - toHandlers, - toRaw, - toRef, - toRefs, - toValue, - transformVNodeArgs, - triggerRef, - unref, - useAttrs, - useCssModule, - useCssVars, - useHost, - useId, - useModel, - useSSRContext, - useShadowRoot, - useSlots, - useTemplateRef, - useTransitionState, - vModelCheckbox, - vModelDynamic, - vModelRadio, - vModelSelect, - vModelText, - vShow, - version, - warn, - watch, - watchEffect, - watchPostEffect, - watchSyncEffect, - withAsyncContext, - withCtx, - withDefaults, - withDirectives, - withKeys, - withMemo, - withModifiers, - withScopeId -} from "./chunk-LE5NDSFD.js"; -export { - BaseTransition, - BaseTransitionPropsValidators, - Comment, - DeprecationTypes, - EffectScope, - ErrorCodes, - ErrorTypeStrings, - Fragment, - KeepAlive, - ReactiveEffect, - Static, - Suspense, - Teleport, - Text, - TrackOpTypes, - Transition, - TransitionGroup, - TriggerOpTypes, - VueElement, - assertNumber, - callWithAsyncErrorHandling, - callWithErrorHandling, - camelize, - capitalize, - cloneVNode, - compatUtils, - compile, - computed, - createApp, - createBlock, - createCommentVNode, - createElementBlock, - createBaseVNode as createElementVNode, - createHydrationRenderer, - createPropsRestProxy, - createRenderer, - createSSRApp, - createSlots, - createStaticVNode, - createTextVNode, - createVNode, - customRef, - defineAsyncComponent, - defineComponent, - defineCustomElement, - defineEmits, - defineExpose, - defineModel, - defineOptions, - defineProps, - defineSSRCustomElement, - defineSlots, - devtools, - effect, - effectScope, - getCurrentInstance, - getCurrentScope, - getCurrentWatcher, - getTransitionRawChildren, - guardReactiveProps, - h, - handleError, - hasInjectionContext, - hydrate, - hydrateOnIdle, - hydrateOnInteraction, - hydrateOnMediaQuery, - hydrateOnVisible, - initCustomFormatter, - initDirectivesForSSR, - inject, - isMemoSame, - isProxy, - isReactive, - isReadonly, - isRef, - isRuntimeOnly, - isShallow, - isVNode, - markRaw, - mergeDefaults, - mergeModels, - mergeProps, - nextTick, - nodeOps, - normalizeClass, - normalizeProps, - normalizeStyle, - onActivated, - onBeforeMount, - onBeforeUnmount, - onBeforeUpdate, - onDeactivated, - onErrorCaptured, - onMounted, - onRenderTracked, - onRenderTriggered, - onScopeDispose, - onServerPrefetch, - onUnmounted, - onUpdated, - onWatcherCleanup, - openBlock, - patchProp, - popScopeId, - provide, - proxyRefs, - pushScopeId, - queuePostFlushCb, - reactive, - readonly, - ref, - registerRuntimeCompiler, - render, - renderList, - renderSlot, - resolveComponent, - resolveDirective, - resolveDynamicComponent, - resolveFilter, - resolveTransitionHooks, - setBlockTracking, - setDevtoolsHook, - setTransitionHooks, - shallowReactive, - shallowReadonly, - shallowRef, - ssrContextKey, - ssrUtils, - stop, - toDisplayString, - toHandlerKey, - toHandlers, - toRaw, - toRef, - toRefs, - toValue, - transformVNodeArgs, - triggerRef, - unref, - useAttrs, - useCssModule, - useCssVars, - useHost, - useId, - useModel, - useSSRContext, - useShadowRoot, - useSlots, - useTemplateRef, - useTransitionState, - vModelCheckbox, - vModelDynamic, - vModelRadio, - vModelSelect, - vModelText, - vShow, - version, - warn, - watch, - watchEffect, - watchPostEffect, - watchSyncEffect, - withAsyncContext, - withCtx, - withDefaults, - withDirectives, - withKeys, - withMemo, - withModifiers, - withScopeId -}; -//# sourceMappingURL=vue.js.map diff --git a/www/docs/.vitepress/cache/deps/vue.js.map b/www/docs/.vitepress/cache/deps/vue.js.map deleted file mode 100644 index 9865211..0000000 --- a/www/docs/.vitepress/cache/deps/vue.js.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": [], - "sourcesContent": [], - "mappings": "", - "names": [] -} diff --git a/www/docs/.vitepress/config.js b/www/docs/.vitepress/config.js deleted file mode 100644 index 00df399..0000000 --- a/www/docs/.vitepress/config.js +++ /dev/null @@ -1,142 +0,0 @@ -import { defineConfig } from 'vitepress' - -export default defineConfig({ - - title: 'Mist', - description: 'Self-hostable Platform-as-a-Service', - base: '/', - head: [ - ['link', { rel: 'icon', type: 'image/png', href: '/mist.png' }] - ], - sitemap: { - hostname: 'https://trymist.cloud' - }, - - themeConfig: { - logo: '/mist.png', - - nav: [ - { text: 'Home', link: '/' }, - { text: 'Guide', link: '/guide/getting-started' }, - // { text: 'API', link: '/api/overview' }, - { text: 'Deployment', link: '/deployment/installation' }, - { text: 'Troubleshooting', link: '/troubleshooting/' } - // { text: 'GitHub', link: 'https://github.com/corecollectives/mist' } - ], - - sidebar: { - '/guide/': [ - { - text: 'Introduction', - items: [ - { text: 'What is Mist?', link: '/guide/what-is-mist' }, - { text: 'Getting Started', link: '/guide/getting-started' }, - { text: 'Architecture', link: '/guide/architecture' } - ] - }, - { - text: 'Core Features', - items: [ - { text: 'Projects', link: '/guide/projects' }, - { text: 'Applications', link: '/guide/applications' }, - { text: 'Deployments', link: '/guide/deployments' }, - { text: 'Environment Variables', link: '/guide/environment-variables' }, - { text: 'Domains & SSL', link: '/guide/domains' }, - { text: 'Git Integration', link: '/guide/git-integration' }, - { text: 'Database Services', link: '/guide/databases' }, - { text: 'SSL Automation', link: '/guide/ssl-automation' }, - ] - }, - { - text: 'Monitoring', - items: [ - { text: 'Logs', link: '/guide/logs' }, - { text: 'System Metrics', link: '/guide/metrics' }, - { text: 'Audit Logs', link: '/guide/audit-logs' } - ] - }, - { - text: 'User Management', - items: [ - { text: 'Authentication', link: '/guide/authentication' }, - { text: 'Users & Roles', link: '/guide/users' } - ] - }, - { - text: 'Administration', - items: [ - { text: 'CLI Tool', link: '/guide/cli' } - ] - }, - { - text: 'Coming Soon', - items: [ - { text: 'Rollback Deployments', link: '/guide/rollback' }, - { text: 'Notifications', link: '/guide/notifications' } - ] - } - ], - '/api/': [ - { - text: 'API Reference', - items: [ - { text: 'Overview', link: '/api/overview' }, - { text: 'Authentication', link: '/api/authentication' }, - { text: 'Projects', link: '/api/projects' }, - { text: 'Applications', link: '/api/applications' }, - { text: 'Deployments', link: '/api/deployments' }, - { text: 'Environment Variables', link: '/api/environment-variables' }, - { text: 'Domains', link: '/api/domains' }, - { text: 'Users', link: '/api/users' }, - { text: 'GitHub Integration', link: '/api/github' }, - { text: 'WebSockets', link: '/api/websockets' } - ] - } - ], - '/deployment/': [ - { - text: 'Deployment', - items: [ - { text: 'Installation', link: '/deployment/installation' }, - { text: 'Configuration', link: '/deployment/configuration' }, - { text: 'Traefik Setup', link: '/deployment/traefik' }, - { text: 'GitHub App Setup', link: '/deployment/github-app' }, - { text: 'Upgrading', link: '/deployment/upgrading' } - ] - }, - { - text: 'Production', - items: [ - { text: 'System Requirements', link: '/deployment/requirements' }, - { text: 'Security Best Practices', link: '/deployment/security' }, - { text: 'Backup & Recovery', link: '/deployment/backup' } - ] - } - ], - '/troubleshooting/': [ - { - text: 'Troubleshooting', - items: [ - { text: 'Common Issues', link: '/troubleshooting/' }, - { text: 'Forgot Password', link: '/troubleshooting/forgot-password' }, - { text: 'Manual Update', link: '/troubleshooting/manual-update' } - ] - } - ] - }, - - socialLinks: [ - { icon: 'github', link: 'https://github.com/corecollectives/mist' }, - { icon: 'discord', link: 'https://discord.gg/kxK8XHR6' } - ], - - footer: { - message: 'Released under the MIT License.', - copyright: 'Copyright © 2025 Mist PaaS' - }, - - search: { - provider: 'local' - } - } -}) diff --git a/www/docs/.vitepress/theme/Layout.vue b/www/docs/.vitepress/theme/Layout.vue deleted file mode 100644 index 44a46ec..0000000 --- a/www/docs/.vitepress/theme/Layout.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/www/docs/.vitepress/theme/components/HeroInstall.vue b/www/docs/.vitepress/theme/components/HeroInstall.vue deleted file mode 100644 index ac46687..0000000 --- a/www/docs/.vitepress/theme/components/HeroInstall.vue +++ /dev/null @@ -1,196 +0,0 @@ - - - - - diff --git a/www/docs/.vitepress/theme/components/NavBarVersion.vue b/www/docs/.vitepress/theme/components/NavBarVersion.vue deleted file mode 100644 index 415a77a..0000000 --- a/www/docs/.vitepress/theme/components/NavBarVersion.vue +++ /dev/null @@ -1,182 +0,0 @@ - - - - - diff --git a/www/docs/.vitepress/theme/custom.css b/www/docs/.vitepress/theme/custom.css deleted file mode 100644 index 0b865fa..0000000 --- a/www/docs/.vitepress/theme/custom.css +++ /dev/null @@ -1,1038 +0,0 @@ -/** - * Custom theme matching the Mist dashboard - * Color scheme: Dark purple theme with OKLCH colors - * Modern design with subtle shadows inspired by Bun - */ - -:root { - /* Light mode colors */ - --vp-c-brand-1: oklch(0.488 0.243 264.376); - --vp-c-brand-2: oklch(0.623 0.214 259.815); - --vp-c-brand-3: oklch(0.546 0.245 262.881); - --vp-c-brand-soft: oklch(0.424 0.199 265.638); - - /* Light Background Colors */ - --vp-c-bg: oklch(1 0 0); - --vp-c-bg-soft: oklch(0.98 0 0); - --vp-c-bg-mute: oklch(0.96 0 0); - --vp-c-bg-alt: oklch(0.98 0 0); - - /* Light Text Colors */ - --vp-c-text-1: oklch(0.141 0.005 285.823); - --vp-c-text-2: oklch(0.461 0.015 286.067); - --vp-c-text-3: oklch(0.556 0 0); - - /* Custom blocks text colors for light mode */ - --vp-custom-block-info-text: oklch(0.141 0.005 285.823); - --vp-custom-block-tip-text: oklch(0.141 0.005 285.823); - --vp-custom-block-warning-text: oklch(0.141 0.005 285.823); - --vp-custom-block-danger-text: oklch(0.141 0.005 285.823); - - /* Light Border Colors */ - --vp-c-border: oklch(0 0 0 / 10%); - --vp-c-divider: oklch(0 0 0 / 10%); - --vp-c-gutter: oklch(0 0 0 / 10%); - - /* Light Component Colors */ - --vp-c-default-1: oklch(0.96 0 0); - --vp-c-default-2: oklch(0.98 0 0); - --vp-c-default-3: oklch(1 0 0); - --vp-c-default-soft: oklch(0.96 0 0); - - /* Code Colors */ - --vp-code-bg: oklch(0.98 0 0); - --vp-code-color: oklch(0.488 0.243 264.376); - - /* Sidebar Colors */ - --vp-sidebar-bg-color: oklch(0.98 0 0); - - /* Custom Accent */ - --vp-c-accent: oklch(0.488 0.243 264.376); - - /* Button Colors */ - --vp-button-brand-bg: oklch(0.488 0.243 264.376); - --vp-button-brand-text: oklch(0.97 0.014 254.604); - --vp-button-brand-hover-bg: oklch(0.623 0.214 259.815); - --vp-button-brand-hover-text: oklch(0.97 0.014 254.604); - --vp-button-brand-active-bg: oklch(0.546 0.245 262.881); - - /* Border Radius */ - --vp-border-radius: 0.65rem; - - /* Shadows */ - --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.04); - --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.08); - --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12); - --shadow-xl: 0 12px 32px rgba(0, 0, 0, 0.16); -} - -.dark { - /* Dark mode colors */ - --vp-c-bg: oklch(0.141 0.005 285.823); - --vp-c-bg-soft: oklch(0.21 0.006 285.885); - --vp-c-bg-mute: oklch(0.274 0.006 286.033); - --vp-c-bg-alt: oklch(0.21 0.006 285.885); - - /* Dark Text Colors */ - --vp-c-text-1: oklch(0.985 0 0); - --vp-c-text-2: oklch(0.705 0.015 286.067); - --vp-c-text-3: oklch(0.556 0 0); - - /* Dark Border Colors */ - --vp-c-border: oklch(1 0 0 / 10%); - --vp-c-divider: oklch(1 0 0 / 10%); - --vp-c-gutter: oklch(1 0 0 / 10%); - - /* Dark Component Colors */ - --vp-c-default-1: oklch(0.274 0.006 286.033); - --vp-c-default-2: oklch(0.21 0.006 285.885); - --vp-c-default-3: oklch(0.141 0.005 285.823); - --vp-c-default-soft: oklch(0.274 0.006 286.033); - - /* Dark Code Colors */ - --vp-code-bg: oklch(0.21 0.006 285.885); - --vp-code-color: oklch(0.809 0.105 251.813); - - /* Dark Sidebar Colors */ - --vp-sidebar-bg-color: oklch(0.21 0.006 285.885); - - /* Shadows for dark mode */ - --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3); - --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4); - --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5); - --shadow-xl: 0 12px 32px rgba(0, 0, 0, 0.6); -} - -/* Custom Styling */ -.VPNavBar { - background-color: var(--vp-c-bg-soft) !important; - border-bottom: 1px solid var(--vp-c-border); - backdrop-filter: blur(8px); - box-shadow: var(--shadow-sm); -} - -/* Fix navbar color consistency - remove default VitePress gradient/transition effects */ -.VPNavBar.has-sidebar { - background-color: var(--vp-c-bg-soft) !important; -} - -.VPNavBar:not(.home) { - background-color: var(--vp-c-bg-soft) !important; -} - -.VPNavBar.filled { - background-color: var(--vp-c-bg-soft) !important; -} - -/* Ensure navbar content has consistent colors */ -.VPNavBar .content { - background-color: transparent !important; -} - -.VPNavBar .content-body { - background-color: transparent !important; -} - -.VPNavBar .divider { - background-color: transparent !important; -} - -/* Navbar logo and title sizing */ -.VPNavBarTitle { - display: flex; - align-items: center; - gap: 0; -} - -/* Increase logo size */ -.VPNavBar .logo { - width: 32px !important; - height: 32px !important; - margin-right: 12px !important; -} - -/* Increase title/name size */ -.VPNavBar .title { - font-size: 1.25rem !important; - font-weight: 700 !important; - letter-spacing: -0.01em !important; -} - -/* Navbar version positioning - keep it attached to title */ -.navbar-version { - flex-shrink: 0; - margin-left: 0.5rem !important; - display: inline-flex !important; - align-items: center !important; -} - -/* Ensure the VPNavBarTitle area contains both title and version */ -.VPNavBar .VPNavBarTitle .title-container { - display: flex; - align-items: center; - gap: 0.5rem; -} - -@media (max-width: 960px) { - .VPNavBar .logo { - width: 28px !important; - height: 28px !important; - } - - .VPNavBar .title { - font-size: 1.1rem !important; - } - - .navbar-version { - margin-left: 0.25rem !important; - } -} - -.VPSidebar { - background-color: var(--vp-c-bg-soft) !important; - box-shadow: var(--shadow-md); -} - -.VPContent { - background-color: var(--vp-c-bg) !important; -} - -/* Hero Section Enhancement */ -.VPHero { - padding-top: 8rem !important; - padding-bottom: 3rem !important; - padding-left: 1.5rem !important; - padding-right: 1.5rem !important; -} - -.VPHero .container { - max-width: 1200px; - margin: 0 auto !important; -} - -.VPHero .main { - max-width: 800px; - margin: 0 auto !important; - /* text-align: center; */ -} - -.VPHero .name { - background: linear-gradient(135deg, oklch(0.809 0.105 251.813), oklch(0.488 0.243 264.376)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; - font-weight: 800; - letter-spacing: -0.02em; -} - -.VPHero .text { - font-weight: 600; - font-size: 3rem; - line-height: 1.2; - letter-spacing: -0.01em; -} - -.VPHero .tagline { - font-size: 1.25rem; - line-height: 1.6; - color: var(--vp-c-text-2); - max-width: 600px; - margin: 0 auto; -} - -.VPHero .image { - max-width: 250px !important; - filter: drop-shadow(0 8px 24px rgba(0, 0, 0, 0.12)); - margin: 0 auto !important; -} - -.VPHero .image-container { - display: flex; - justify-content: center; -} - -@media (max-width: 768px) { - .VPHero { - padding-top: 3rem !important; - } - - .VPHero .text { - font-size: 2rem; - } - - .VPHero .tagline { - font-size: 1rem; - } - - .VPHero .image { - max-width: 200px !important; - width: 100% !important; - height: auto !important; - display: block !important; - } - - .VPHero .image img { - width: 100% !important; - height: auto !important; - display: block !important; - margin: 0 auto !important; - } - - .VPHero .image-container { - display: flex !important; - justify-content: center !important; - align-items: center !important; - width: 100% !important; - margin-bottom: 1.5rem !important; - } -} - -/* Custom badge for "Coming Soon" */ -.coming-soon-badge { - display: inline-block; - background: linear-gradient(135deg, oklch(0.488 0.243 264.376), oklch(0.623 0.214 259.815)); - color: white !important; - padding: 0.25rem 0.75rem; - border-radius: 0.5rem; - font-size: 0.875rem; - font-weight: 600; - margin-left: 0.5rem; - vertical-align: middle; -} - -/* Custom card styling */ -.custom-card { - background: var(--vp-c-bg-soft); - border: 1px solid var(--vp-c-border); - border-radius: 12px; - padding: 1.5rem; - margin: 1rem 0; - box-shadow: var(--shadow-md); - transition: all 0.3s ease; -} - -.custom-card:hover { - box-shadow: var(--shadow-lg); - transform: translateY(-2px); -} - -.custom-card h3 { - margin-top: 0; - color: var(--vp-c-brand-1); -} - -/* Feature grid */ -.feature-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); - gap: 1.5rem; - margin: 2rem 0; -} - -.feature-card { - background: var(--vp-c-bg-soft); - border: 1px solid var(--vp-c-border); - border-radius: 12px; - padding: 1.5rem; - transition: all 0.3s ease; - box-shadow: var(--shadow-sm); -} - -.feature-card:hover { - transform: translateY(-4px); - border-color: var(--vp-c-brand-1); - box-shadow: var(--shadow-lg); -} - -.feature-card h3 { - margin-top: 0; - color: var(--vp-c-brand-2); - display: flex; - align-items: center; - gap: 0.5rem; -} - -.feature-icon { - font-size: 1.5rem; -} - -/* VitePress Features Section Enhancement */ -.VPFeatures { - padding: 3rem 1.5rem !important; - max-width: 1200px; - margin: 0 auto; -} - -.VPFeature { - background: var(--vp-c-bg-soft); - border: 1px solid var(--vp-c-border); - border-radius: 12px; - padding: 1.5rem; - transition: all 0.3s ease; - box-shadow: var(--shadow-sm); -} - -.VPFeature:hover { - transform: translateY(-4px); - box-shadow: var(--shadow-lg); - border-color: var(--vp-c-brand-1); -} - -/* Coming Soon Banner */ -.coming-soon-banner { - background: linear-gradient(135deg, oklch(0.488 0.243 264.376) 0%, oklch(0.424 0.199 265.638) 100%); - border: 1px solid oklch(0.623 0.214 259.815); - border-radius: var(--vp-border-radius); - padding: 1rem 1.5rem; - margin: 1.5rem 0; - color: white !important; -} - -.coming-soon-banner h4 { - margin: 0 0 0.5rem 0; - color: white !important; -} - -.coming-soon-banner p { - margin: 0; - color: white !important; - opacity: 0.95; -} - -.coming-soon-banner ul, -.coming-soon-banner ol { - color: white !important; -} - -.coming-soon-banner li { - color: white !important; -} - -.coming-soon-banner strong { - color: white !important; -} - -.coming-soon-banner code { - color: white !important; - background: rgba(0, 0, 0, 0.25) !important; - padding: 0.2em 0.4em; - border-radius: 4px; -} - -.coming-soon-banner a { - color: white !important; - text-decoration: underline; - font-weight: 600; -} - -.coming-soon-banner a:hover { - color: rgba(255, 255, 255, 0.85) !important; -} - -/* Code blocks */ -.vp-code-group { - margin: 1rem 0; - border-radius: 12px; - overflow: hidden; - box-shadow: var(--shadow-md); -} - -div[class*='language-'] { - border-radius: 12px; - box-shadow: var(--shadow-sm); - border: 1px solid var(--vp-c-border); -} - -div[class*='language-']:hover { - box-shadow: var(--shadow-md); -} - -/* Code copy button */ -.vp-code-group button, -div[class*='language-'] button { - transition: all 0.2s ease; -} - -.vp-code-group button:hover, -div[class*='language-'] button:hover { - transform: scale(1.05); -} - -/* Home hero customization */ -.VPHero .name { - background: linear-gradient(135deg, oklch(0.809 0.105 251.813), oklch(0.488 0.243 264.376)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -/* Content sections */ -.vp-doc { - max-width: 1200px !important; - margin: 0 auto; -} - -.vp-doc .content-container { - max-width: 1200px !important; -} - -.vp-doc h2 { - border-top: 1px solid var(--vp-c-divider); - padding-top: 2rem; - margin-top: 3rem; - font-weight: 700; - letter-spacing: -0.01em; -} - -.vp-doc h3 { - font-weight: 600; - letter-spacing: -0.005em; - color: var(--vp-c-brand-1); -} - -/* Cards in content */ -.vp-doc .custom-block { - border-radius: 12px; - box-shadow: var(--shadow-sm); - transition: all 0.3s ease; -} - -.vp-doc .custom-block:hover { - box-shadow: var(--shadow-md); - transform: translateY(-2px); -} - -/* Links */ -a { - color: var(--vp-c-brand-1); - text-decoration: none; -} - -a:hover { - color: var(--vp-c-brand-2); -} - -/* Fix link visibility in code blocks and inline code */ -.vp-doc a code, -code a { - color: var(--vp-c-brand-1) !important; -} - -.dark .vp-doc a code, -.dark code a { - color: var(--vp-c-brand-2) !important; -} - -/* Fix text visibility in custom blocks (info, tip, warning, danger) */ -/* Keep white text on blue/colored backgrounds in BOTH light and dark modes */ -.vp-doc .custom-block.info, -.vp-doc .custom-block.tip, -.vp-doc .custom-block.warning, -.vp-doc .custom-block.danger, -.custom-block.info, -.custom-block.tip, -.custom-block.warning, -.custom-block.danger { - color: white !important; -} - -.vp-doc .custom-block.info .custom-block-title, -.vp-doc .custom-block.tip .custom-block-title, -.vp-doc .custom-block.warning .custom-block-title, -.vp-doc .custom-block.danger .custom-block-title, -.custom-block.info .custom-block-title, -.custom-block.tip .custom-block-title, -.custom-block.warning .custom-block-title, -.custom-block.danger .custom-block-title { - color: white !important; -} - -.vp-doc .custom-block.info p, -.vp-doc .custom-block.tip p, -.vp-doc .custom-block.warning p, -.vp-doc .custom-block.danger p, -.custom-block.info p, -.custom-block.tip p, -.custom-block.warning p, -.custom-block.danger p { - color: white !important; -} - -.vp-doc .custom-block.info ul, -.vp-doc .custom-block.tip ul, -.vp-doc .custom-block.warning ul, -.vp-doc .custom-block.danger ul, -.vp-doc .custom-block.info ol, -.vp-doc .custom-block.tip ol, -.vp-doc .custom-block.warning ol, -.vp-doc .custom-block.danger ol, -.custom-block.info ul, -.custom-block.tip ul, -.custom-block.warning ul, -.custom-block.danger ul, -.custom-block.info ol, -.custom-block.tip ol, -.custom-block.warning ol, -.custom-block.danger ol { - color: white !important; -} - -.vp-doc .custom-block.info li, -.vp-doc .custom-block.tip li, -.vp-doc .custom-block.warning li, -.vp-doc .custom-block.danger li, -.custom-block.info li, -.custom-block.tip li, -.custom-block.warning li, -.custom-block.danger li { - color: white !important; -} - -.vp-doc .custom-block.info strong, -.vp-doc .custom-block.tip strong, -.vp-doc .custom-block.warning strong, -.vp-doc .custom-block.danger strong, -.custom-block.info strong, -.custom-block.tip strong, -.custom-block.warning strong, -.custom-block.danger strong { - color: white !important; -} - -.vp-doc .custom-block.info code, -.vp-doc .custom-block.tip code, -.vp-doc .custom-block.warning code, -.vp-doc .custom-block.danger code, -.custom-block.info code, -.custom-block.tip code, -.custom-block.warning code, -.custom-block.danger code { - color: white !important; - background: rgba(0, 0, 0, 0.25) !important; - padding: 0.2em 0.4em; - border-radius: 4px; -} - -.dark .vp-doc .custom-block.info code, -.dark .vp-doc .custom-block.tip code, -.dark .vp-doc .custom-block.warning code, -.dark .vp-doc .custom-block.danger code, -.dark .custom-block.info code, -.dark .custom-block.tip code, -.dark .custom-block.warning code, -.dark .custom-block.danger code { - color: white !important; - background: rgba(0, 0, 0, 0.3) !important; - padding: 0.2em 0.4em; - border-radius: 4px; -} - -/* Fix links in custom blocks - keep white with underline */ -.vp-doc .custom-block a, -.custom-block a { - color: white !important; - text-decoration: underline; - font-weight: 600; -} - -.dark .vp-doc .custom-block a, -.dark .custom-block a { - color: white !important; -} - -.vp-doc .custom-block a:hover, -.custom-block a:hover { - color: rgba(255, 255, 255, 0.85) !important; - text-decoration: underline; -} - -.dark .vp-doc .custom-block a:hover, -.dark .custom-block a:hover { - color: rgba(255, 255, 255, 0.85) !important; -} - -/* Fix inline code visibility in light mode */ -:not(pre) > code { - color: oklch(0.35 0.25 264.376) !important; - background-color: oklch(0.96 0 0) !important; -} - -.dark :not(pre) > code { - color: oklch(0.809 0.105 251.813) !important; - background-color: oklch(0.21 0.006 285.885) !important; -} - -/* Tables */ -table { - border-collapse: collapse; - width: 100%; - margin: 1rem 0; -} - -th, td { - border: 1px solid var(--vp-c-border); - padding: 0.75rem; - text-align: left; -} - -th { - background: var(--vp-c-bg-soft); - font-weight: 600; -} - -tr:hover { - background: var(--vp-c-bg-mute); -} - -/* Comparison Table Styling */ -.comparison-section { - margin: 3rem 0; - width: 100%; -} - -.comparison-section h3 { - text-align: center; - margin-bottom: 2rem; -} - -.comparison-table-wrapper { - margin: 2rem auto; - border-radius: 12px; - overflow: hidden; - box-shadow: var(--shadow-lg); - border: 1px solid var(--vp-c-border); - max-width: 100%; -} - -.comparison-table-wrapper table { - margin: 0 auto; - box-shadow: none; - width: 100%; - table-layout: fixed; -} - -.comparison-table-wrapper th { - background: var(--vp-c-brand-1); - color: white; - font-weight: 700; - padding: 1rem 0.75rem; - text-align: center; - font-size: 0.9rem; - width: 16.66%; -} - -.comparison-table-wrapper th:first-child { - text-align: left; - padding-left: 1.5rem; - width: 20%; -} - -.comparison-table-wrapper td { - padding: 0.875rem 0.5rem; - vertical-align: middle; - font-size: 0.85rem; - width: 16.66%; -} - -.comparison-table-wrapper td:first-child { - font-weight: 600; - color: var(--vp-c-text-1); - padding-left: 1.5rem; - white-space: nowrap; - width: 20%; -} - -.comparison-table-wrapper td:not(:first-child) { - text-align: center; -} - -.comparison-table-wrapper tr:hover { - background: var(--vp-c-bg-soft); -} - -.comparison-table-wrapper tbody tr { - transition: all 0.2s ease; - border-bottom: 1px solid var(--vp-c-border); -} - -.comparison-table-wrapper tbody tr:last-child { - border-bottom: none; -} - -/* Features comparison lists */ -.features-comparison { - background: var(--vp-c-bg-soft); - border: 1px solid var(--vp-c-border); - border-left: 4px solid #10b981; - border-radius: 8px; - padding: 1.5rem 1.5rem 1.5rem 2rem; - margin: 1.5rem 0; - box-shadow: var(--shadow-sm); -} - -.features-comparison.limitations { - border-left-color: #f59e0b; -} - -.features-comparison ul { - margin: 0; - padding: 0; - list-style: none; -} - -.features-comparison li { - padding: 0.5rem 0; - position: relative; - padding-left: 1.5rem; - line-height: 1.7; -} - -.features-comparison li:before { - content: "●"; - position: absolute; - left: 0; - color: #10b981; - font-size: 0.8rem; - top: 0.6rem; -} - -.features-comparison.limitations li:before { - color: #f59e0b; -} - -/* Important Notes Section */ -.important-notes { - margin: 3rem 0; -} - -.important-notes .custom-block { - margin: 2rem 0; - padding: 1.5rem 2rem; - border-radius: 12px; - box-shadow: var(--shadow-lg); - transition: all 0.3s ease; - font-size: 1.05rem; - line-height: 1.8; -} - -.important-notes .custom-block:hover { - box-shadow: var(--shadow-xl); - transform: translateY(-3px); -} - -.important-notes .custom-block.info { - border-left: 6px solid #3b82f6; - background: linear-gradient(to right, rgba(59, 130, 246, 0.05), transparent); -} - -.important-notes .custom-block.tip { - border-left: 6px solid #10b981; - background: linear-gradient(to right, rgba(16, 185, 129, 0.05), transparent); -} - -.important-notes .custom-block-title { - font-size: 1.25rem; - font-weight: 700; - margin-bottom: 0.75rem; -} - -.important-notes .custom-block p { - font-size: 1.05rem; - line-height: 1.8; - margin: 0.5rem 0; -} - -.important-notes .custom-block strong { - font-weight: 700; - font-size: 1.1rem; -} - -/* Professional Features Grid */ -.features-grid-professional { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); - gap: 1.5rem; - margin: 2.5rem auto; - max-width: 1200px; -} - -.feature-card-pro { - background: var(--vp-c-bg-soft); - border: 1px solid var(--vp-c-border); - border-radius: 12px; - padding: 2rem; - transition: all 0.3s ease; - box-shadow: var(--shadow-sm); - position: relative; - overflow: hidden; -} - -.feature-card-pro::before { - content: ''; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 3px; - background: linear-gradient(90deg, var(--vp-c-brand-1), var(--vp-c-brand-2)); - transform: scaleX(0); - transition: transform 0.3s ease; -} - -.feature-card-pro:hover { - transform: translateY(-4px); - box-shadow: var(--shadow-lg); - border-color: var(--vp-c-brand-1); -} - -.feature-card-pro:hover::before { - transform: scaleX(1); -} - -.feature-icon-pro { - width: 48px; - height: 48px; - background: var(--vp-c-brand-1); - border-radius: 10px; - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 1.25rem; - color: white; - transition: all 0.3s ease; -} - -.feature-card-pro:hover .feature-icon-pro { - background: var(--vp-c-brand-2); - color: white; - transform: scale(1.1) rotate(5deg); -} - -.feature-card-pro h3 { - margin: 0 0 0.75rem 0; - font-size: 1.15rem; - font-weight: 600; - color: var(--vp-c-text-1); - letter-spacing: -0.01em; -} - -.feature-card-pro p { - margin: 0; - color: var(--vp-c-text-2); - font-size: 0.95rem; - line-height: 1.6; -} - -@media (max-width: 768px) { - .features-grid-professional { - grid-template-columns: 1fr; - gap: 1rem; - } - - .feature-card-pro { - padding: 1.5rem; - } -} - -/* Coming Soon Section Styling */ -.vp-doc h3 + p { - line-height: 1.8; - color: var(--vp-c-text-2); -} - -/* Responsive Table for Mobile */ -@media (max-width: 768px) { - .comparison-table-wrapper { - overflow-x: auto; - margin: 2rem 0; - } - - .comparison-table-wrapper table { - min-width: 900px; - } - - .features-grid-professional { - grid-template-columns: 1fr; - } - - .features-comparison { - padding: 1rem 1rem 1rem 1.5rem; - } - - .comparison-section { - margin: 2rem 0; - } -} - -@media (max-width: 1024px) { - .comparison-table-wrapper { - overflow-x: auto; - } - - .comparison-table-wrapper table { - min-width: 900px; - } -} -.status-badge { - display: inline-block; - padding: 0.25rem 0.75rem; - border-radius: 0.5rem; - font-size: 0.875rem; - font-weight: 600; - margin: 0.25rem; -} - -.status-implemented { - background: oklch(0.488 0.243 264.376); - color: white !important; -} - -.status-planned { - background: oklch(0.274 0.006 286.033); - color: white !important; -} - -.status-coming-soon { - background: linear-gradient(135deg, oklch(0.488 0.243 264.376), oklch(0.623 0.214 259.815)); - color: white !important; -} - -/* Ultra high specificity override for custom blocks in light mode */ -:root .vp-doc .custom-block.info *, -:root .vp-doc .custom-block.tip *, -:root .vp-doc .custom-block.warning *, -:root .vp-doc .custom-block.danger *, -:root .custom-block.info *, -:root .custom-block.tip *, -:root .custom-block.warning *, -:root .custom-block.danger * { - color: white !important; -} - -/* Ensure custom block backgrounds are visible */ -:root .vp-doc .custom-block.info, -:root .custom-block.info { - background-color: #3b82f6 !important; -} - -:root .vp-doc .custom-block.tip, -:root .custom-block.tip { - background-color: #10b981 !important; -} - -:root .vp-doc .custom-block.warning, -:root .custom-block.warning { - background-color: #f59e0b !important; -} - -:root .vp-doc .custom-block.danger, -:root .custom-block.danger { - background-color: #ef4444 !important; -} - -/* Code blocks inside custom blocks */ -:root .vp-doc .custom-block code, -:root .custom-block code { - background: rgba(0, 0, 0, 0.25) !important; - color: white !important; -} diff --git a/www/docs/.vitepress/theme/index.js b/www/docs/.vitepress/theme/index.js deleted file mode 100644 index e48e9a8..0000000 --- a/www/docs/.vitepress/theme/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import DefaultTheme from 'vitepress/theme' -import './custom.css' -import HeroInstall from './components/HeroInstall.vue' -import NavBarVersion from './components/NavBarVersion.vue' -import Layout from './Layout.vue' - -export default { - extends: DefaultTheme, - Layout, - enhanceApp({ app }) { - app.component('HeroInstall', HeroInstall) - app.component('NavBarVersion', NavBarVersion) - } -} diff --git a/www/docs/api/applications.md b/www/docs/api/applications.md deleted file mode 100644 index cbf2609..0000000 --- a/www/docs/api/applications.md +++ /dev/null @@ -1,366 +0,0 @@ -# Applications API - -Manage applications programmatically. All endpoints require authentication via JWT cookie. - -## Create Application - -`POST /api/apps/create` - -Creates a new application in a project. Supports three app types: `web`, `service`, and `database`. - -### Request Body - -```json -{ - "name": "my-app", - "description": "My application description", - "projectId": 1, - "appType": "web", - "port": 3000, - "envVars": { - "NODE_ENV": "production", - "API_KEY": "secret" - } -} -``` - -**For database apps**, use: - -```json -{ - "name": "my-postgres", - "description": "PostgreSQL database", - "projectId": 1, - "appType": "database", - "templateName": "postgresql", - "envVars": { - "POSTGRES_PASSWORD": "secret123" - } -} -``` - -### Parameters - -- `name` (required): Application name -- `description` (optional): Application description -- `projectId` (required): ID of the project -- `appType` (optional): One of `web`, `service`, or `database` (defaults to `web`) -- `port` (optional): Port number for web apps (defaults to 3000) -- `templateName` (required for database apps): Template name (e.g., `postgresql`, `mysql`, `redis`, `mongodb`) -- `envVars` (optional): Key-value map of environment variables - -### Response - -```json -{ - "success": true, - "message": "Application created successfully", - "data": { - "id": 1, - "name": "my-app", - "description": "My application description", - "project_id": 1, - "app_type": "web", - "port": 3000, - "status": "stopped", - "created_by": 1, - "created_at": "2025-01-15T10:30:00Z" - } -} -``` - -::: tip -For web apps, Mist automatically generates a domain if wildcard DNS is configured. -::: - -## List Applications - -`POST /api/apps/get` - -Retrieves all applications in a project that the authenticated user has access to. - -### Request Body - -```json -{ - "projectId": 1 -} -``` - -### Response - -```json -{ - "success": true, - "message": "Applications retrieved successfully", - "data": [ - { - "id": 1, - "name": "my-app", - "app_type": "web", - "status": "running", - "port": 3000, - "git_repository": "https://github.com/user/repo", - "git_branch": "main", - "created_at": "2025-01-15T10:30:00Z" - } - ] -} -``` - -## Get Application by ID - -`POST /api/apps/get/id` - -Retrieves a single application by its ID. - -### Request Body - -```json -{ - "appId": 1 -} -``` - -### Response - -```json -{ - "success": true, - "message": "Application retrieved successfully", - "data": { - "id": 1, - "name": "my-app", - "description": "My application", - "project_id": 1, - "app_type": "web", - "port": 3000, - "status": "running", - "git_repository": "https://github.com/user/repo", - "git_branch": "main", - "root_directory": "", - "dockerfile_path": null, - "deployment_strategy": "rolling", - "restart_policy": "unless-stopped", - "cpu_limit": 1.0, - "memory_limit": 512, - "created_at": "2025-01-15T10:30:00Z", - "updated_at": "2025-01-15T12:00:00Z" - } -} -``` - -## Update Application - -`POST /api/apps/update` - -Updates an application's configuration. Only the application owner can update settings. - -### Request Body - -All fields are optional. Only include fields you want to update: - -```json -{ - "appId": 1, - "name": "updated-app", - "description": "Updated description", - "gitRepository": "https://github.com/user/new-repo", - "gitBranch": "develop", - "port": 8080, - "rootDirectory": "/app", - "dockerfilePath": "docker/Dockerfile", - "deploymentStrategy": "rolling", - "status": "running", - "cpuLimit": 2.0, - "memoryLimit": 1024, - "restartPolicy": "always" -} -``` - -### Parameters - -- `appId` (required): Application ID to update -- `name`: Application name -- `description`: Application description -- `gitRepository`: Git repository URL -- `gitBranch`: Git branch name -- `port`: Application port -- `rootDirectory`: Root directory for builds -- `dockerfilePath`: Path to Dockerfile -- `deploymentStrategy`: Deployment strategy -- `status`: Application status (`stopped`, `running`, `error`, `building`, `deploying`) -- `cpuLimit`: CPU limit in cores (e.g., 1.0, 2.0) -- `memoryLimit`: Memory limit in MB (e.g., 512, 1024) -- `restartPolicy`: One of `no`, `always`, `on-failure`, `unless-stopped` - -### Response - -```json -{ - "success": true, - "message": "Application updated successfully", - "data": { - "id": 1, - "name": "updated-app", - "git_branch": "develop", - "updated_at": "2025-01-15T14:00:00Z" - } -} -``` - -## Container Controls - -### Stop Container - -`POST /api/apps/container/stop?appId=1` - -Stops a running container. - -### Start Container - -`POST /api/apps/container/start?appId=1` - -Starts a stopped container. - -### Restart Container - -`POST /api/apps/container/restart?appId=1` - -Restarts a container. - -### Response (all control endpoints) - -```json -{ - "success": true, - "message": "Container stopped successfully", - "data": { - "message": "Container stopped successfully" - } -} -``` - -## Get Container Status - -`GET /api/apps/container/status?appId=1` - -Retrieves the current status of a container. - -### Response - -```json -{ - "success": true, - "message": "Container status retrieved successfully", - "data": { - "state": "running", - "status": "Up 2 hours", - "id": "abc123def456" - } -} -``` - -## Get Container Logs - -`GET /api/apps/container/logs?appId=1&tail=100` - -Retrieves container logs. - -### Query Parameters - -- `appId` (required): Application ID -- `tail` (optional): Number of lines to retrieve (default: 100) - -### Response - -```json -{ - "success": true, - "message": "Container logs retrieved successfully", - "data": { - "logs": "2025-01-15T10:30:00Z Server started\n2025-01-15T10:30:01Z Listening on port 3000" - } -} -``` - -## cURL Examples - -### Create a Web Application - -```bash -curl -X POST https://mist.example.com/api/apps/create \ - -H "Content-Type: application/json" \ - -b cookies.txt \ - -d '{ - "name": "my-web-app", - "description": "My Node.js application", - "projectId": 1, - "appType": "web", - "port": 3000, - "envVars": { - "NODE_ENV": "production" - } - }' -``` - -### Create a Database Application - -```bash -curl -X POST https://mist.example.com/api/apps/create \ - -H "Content-Type: application/json" \ - -b cookies.txt \ - -d '{ - "name": "my-postgres", - "description": "PostgreSQL database", - "projectId": 1, - "appType": "database", - "templateName": "postgresql", - "envVars": { - "POSTGRES_PASSWORD": "mysecretpassword", - "POSTGRES_DB": "mydb" - } - }' -``` - -### Update Application - -```bash -curl -X POST https://mist.example.com/api/apps/update \ - -H "Content-Type: application/json" \ - -b cookies.txt \ - -d '{ - "appId": 1, - "name": "updated-app", - "gitBranch": "develop", - "cpuLimit": 2.0, - "memoryLimit": 1024 - }' -``` - -### Stop Container - -```bash -curl -X POST 'https://mist.example.com/api/apps/container/stop?appId=1' \ - -b cookies.txt -``` - -### Get Container Logs - -```bash -curl -X GET 'https://mist.example.com/api/apps/container/logs?appId=1&tail=50' \ - -b cookies.txt -``` - -::: tip Authentication -All endpoints require authentication via JWT cookie. Use `-b cookies.txt` with cURL to persist cookies after login. -::: - -## Related Endpoints - -- [Environment Variables API](/api/environment-variables) - Manage app environment variables -- [Domains API](/api/domains) - Manage app domains -- [Deployments API](/api/deployments) - Deploy applications -- [WebSocket API](/api/websockets) - Real-time container logs - -For the complete implementation, see [server/api/handlers/applications](https://github.com/corecollectives/mist/tree/main/server/api/handlers/applications). diff --git a/www/docs/api/authentication.md b/www/docs/api/authentication.md deleted file mode 100644 index 6d47028..0000000 --- a/www/docs/api/authentication.md +++ /dev/null @@ -1,58 +0,0 @@ -# Authentication API - -Manage user authentication via API. - -## Login - -`POST /api/auth/login` - -**Request:** -```json -{ - "email": "user@example.com", - "password": "password" -} -``` - -**Response:** -```json -{ - "success": true, - "data": { - "user": { - "id": 1, - "email": "user@example.com", - "role": "admin" - } - } -} -``` - -Sets HTTP-only cookie with JWT token. - -## Logout - -`POST /api/auth/logout` - -Clears authentication cookie. - -## Get Current User - -`GET /api/auth/me` - -Returns currently authenticated user. - -**Response:** -```json -{ - "success": true, - "data": { - "id": 1, - "email": "user@example.com", - "role": "admin", - "createdAt": "2025-01-15T10:00:00Z" - } -} -``` - -See [server/api/handlers/auth](https://github.com/corecollectives/mist/tree/main/server/api/handlers/auth) for implementation details. diff --git a/www/docs/api/deployments.md b/www/docs/api/deployments.md deleted file mode 100644 index f3b86b5..0000000 --- a/www/docs/api/deployments.md +++ /dev/null @@ -1,240 +0,0 @@ -# Deployments API - -Trigger and manage deployments programmatically. All endpoints require authentication. - -## Trigger Deployment - -`POST /api/deployment/add` - -Triggers a new deployment for an application. For web/service apps, it fetches the latest commit from the configured Git repository. For database apps, it deploys using the service template's Docker image. - -### Request Body - -```json -{ - "appId": 1 -} -``` - -### Parameters - -- `appId` (required): The ID of the application to deploy - -### Response - -```json -{ - "id": 15, - "app_id": 1, - "commit_hash": "a1b2c3d4e5f6", - "commit_message": "Fix user authentication bug", - "status": "pending", - "stage": "", - "progress": 0, - "created_at": "2025-01-15T10:30:00Z" -} -``` - -::: tip Deployment Queue -Deployments are added to a queue and processed by background workers. The deployment status updates from `pending` → `building` → `deploying` → `success` (or `failed`). -::: - -## List Deployments - -`POST /api/deployment/getByAppId` - -Retrieves deployment history for an application, including all previous deployments with their statuses. - -### Request Body - -```json -{ - "appId": 1 -} -``` - -### Response - -```json -{ - "success": true, - "message": "Deployments retrieved successfully", - "data": [ - { - "id": 15, - "app_id": 1, - "deployment_number": 15, - "commit_hash": "a1b2c3d4e5f6", - "commit_message": "Fix user authentication bug", - "status": "success", - "stage": "completed", - "progress": 100, - "duration": 45, - "is_active": true, - "created_at": "2025-01-15T10:30:00Z", - "updated_at": "2025-01-15T10:31:00Z" - }, - { - "id": 14, - "app_id": 1, - "deployment_number": 14, - "commit_hash": "f6e5d4c3b2a1", - "commit_message": "Add user profile page", - "status": "success", - "stage": "completed", - "progress": 100, - "duration": 38, - "is_active": false, - "rolled_back_from": 15, - "created_at": "2025-01-14T16:20:00Z", - "updated_at": "2025-01-14T16:21:00Z" - } - ] -} -``` - -### Deployment Statuses - -- `pending`: Deployment is queued and waiting to start -- `building`: Application is being built (cloning repo, building Docker image) -- `deploying`: Container is being deployed -- `success`: Deployment completed successfully -- `failed`: Deployment failed (check error message and logs) -- `stopped`: Deployment was manually stopped -- `rolled_back`: Deployment was rolled back to a previous version - -## Get Deployment Logs - -`GET /api/deployment/logs/:deploymentId` - -Retrieves build logs for a specific deployment. These are the logs generated during the build process. - -### Response - -``` -Cloning repository... -Cloning into '/tmp/mist-build-123'... -Building Docker image... -Step 1/8 : FROM node:18-alpine - ---> 1a2b3c4d5e6f -Step 2/8 : WORKDIR /app - ---> Running in 7f8e9d0c1b2a - ---> 3c4d5e6f7a8b -... -Successfully built abc123def456 -Successfully tagged mist-app-1:latest -Deployment completed successfully -``` - -## WebSocket: Watch Deployment Status - -`WS /ws/deployment/logs?deploymentId=15` - -Connect to a WebSocket to receive real-time deployment status updates and logs. - -### Connection - -```javascript -const ws = new WebSocket('wss://mist.example.com/ws/deployment/logs?deploymentId=15'); - -ws.onmessage = (event) => { - const data = JSON.parse(event.data); - - if (data.type === 'status') { - console.log('Status:', data.data.status); - console.log('Progress:', data.data.progress + '%'); - console.log('Stage:', data.data.stage); - } else if (data.type === 'log') { - console.log('Log:', data.data.line); - } -}; -``` - -### Message Types - -**Status Update:** -```json -{ - "type": "status", - "timestamp": "2025-01-15T10:30:15Z", - "data": { - "deployment_id": 15, - "status": "building", - "stage": "cloning_repo", - "progress": 25, - "message": "Cloning repository...", - "error_message": "" - } -} -``` - -**Log Line:** -```json -{ - "type": "log", - "timestamp": "2025-01-15T10:30:16Z", - "data": { - "line": "Step 1/8 : FROM node:18-alpine" - } -} -``` - -**Error:** -```json -{ - "type": "error", - "timestamp": "2025-01-15T10:30:30Z", - "data": { - "message": "Failed to build Docker image: exit code 1" - } -} -``` - -## Deployment Stages - -During a deployment, the system goes through these stages: - -1. **cloning_repo** - Cloning Git repository -2. **building_image** - Building Docker image -3. **stopping_old** - Stopping previous container -4. **starting_new** - Starting new container -5. **completed** - Deployment finished successfully - -## cURL Examples - -### Trigger Deployment - -```bash -curl -X POST https://mist.example.com/api/deployment/add \ - -H "Content-Type: application/json" \ - -b cookies.txt \ - -d '{"appId": 1}' -``` - -### List Deployments - -```bash -curl -X POST https://mist.example.com/api/deployment/getByAppId \ - -H "Content-Type: application/json" \ - -b cookies.txt \ - -d '{"appId": 1}' -``` - -### Get Deployment Logs - -```bash -curl https://mist.example.com/api/deployment/logs/15 \ - -b cookies.txt -``` - -::: tip Real-time Updates -For real-time deployment progress, use the WebSocket endpoint. The REST API logs endpoint only returns completed logs after the deployment finishes. -::: - -## Related Endpoints - -- [Applications API](/api/applications) - Manage applications -- [WebSocket API](/api/websockets) - Real-time updates -- [GitHub API](/api/github) - GitHub integration - -For the complete implementation, see [server/api/handlers/deployments](https://github.com/corecollectives/mist/tree/main/server/api/handlers/deployments) and [server/docker/deployer.go](https://github.com/corecollectives/mist/blob/main/server/docker/deployer.go). diff --git a/www/docs/api/domains.md b/www/docs/api/domains.md deleted file mode 100644 index 97d07d1..0000000 --- a/www/docs/api/domains.md +++ /dev/null @@ -1,39 +0,0 @@ -# Domains API - -Manage application domains. - -## Add Domain - -`POST /api/apps/domains/create` - -**Request:** -```json -{ - "appId": 1, - "domain": "app.example.com" -} -``` - -## List Domains - -`POST /api/apps/domains/get` - -**Request:** -```json -{ - "appId": 1 -} -``` - -## Delete Domain - -`DELETE /api/apps/domains/delete` - -**Request:** -```json -{ - "id": 1 -} -``` - -See [server/api/handlers/applications/domains.go](https://github.com/corecollectives/mist/blob/main/server/api/handlers/applications/domains.go) for implementation. diff --git a/www/docs/api/environment-variables.md b/www/docs/api/environment-variables.md deleted file mode 100644 index 463fa5f..0000000 --- a/www/docs/api/environment-variables.md +++ /dev/null @@ -1,109 +0,0 @@ -# Environment Variables API - -Manage environment variables via API. - -## Create Variable - -`POST /api/apps/envs/create` - -### Request Body - -```json -{ - "appId": 1, - "key": "API_KEY", - "value": "secret-value" -} -``` - -### Response - -```json -{ - "success": true, - "data": { - "id": 1, - "appId": 1, - "key": "API_KEY", - "value": "secret-value", - "createdAt": "2025-01-15T10:30:00Z" - } -} -``` - -## List Variables - -`POST /api/apps/envs/get` - -### Request Body - -```json -{ - "appId": 1 -} -``` - -### Response - -```json -{ - "success": true, - "data": [ - { - "id": 1, - "key": "API_KEY", - "value": "secret-value", - "createdAt": "2025-01-15T10:30:00Z" - } - ] -} -``` - -## Update Variable - -`PUT /api/apps/envs/update` - -### Request Body - -```json -{ - "id": 1, - "key": "API_KEY", - "value": "new-secret-value" -} -``` - -## Delete Variable - -`DELETE /api/apps/envs/delete` - -### Request Body - -```json -{ - "id": 1 -} -``` - -## Example: Bulk Import - -```bash -#!/bin/bash - -APP_ID=1 - -# Read .env file and create variables -while IFS='=' read -r key value; do - # Skip comments and empty lines - [[ $key =~ ^#.*$ ]] && continue - [[ -z $key ]] && continue - - # Create variable - curl -X POST https://mist.example.com/api/apps/envs/create \ - -H "Content-Type: application/json" \ - -b cookies.txt \ - -d "{\"appId\": $APP_ID, \"key\": \"$key\", \"value\": \"$value\"}" -done < .env -``` - -For complete API reference, see [server/api/handlers/applications/envs.go](https://github.com/corecollectives/mist/blob/main/server/api/handlers/applications/envs.go). diff --git a/www/docs/api/github.md b/www/docs/api/github.md deleted file mode 100644 index 0663031..0000000 --- a/www/docs/api/github.md +++ /dev/null @@ -1,38 +0,0 @@ -# GitHub API - -GitHub integration endpoints. - -## List Repositories - -`POST /api/github/repos` - -Returns repositories accessible via installed GitHub App. - -**Request:** -```json -{ - "installationId": 12345 -} -``` - -## List Branches - -`POST /api/github/branches` - -**Request:** -```json -{ - "repoFullName": "user/repo", - "installationId": 12345 -} -``` - -Returns branches for the specified repository. - -## Webhook Endpoint - -`POST /api/webhooks/github` - -Receives GitHub webhook events for auto-deployment. - -See [server/api/handlers/github](https://github.com/corecollectives/mist/tree/main/server/api/handlers/github) for implementation. diff --git a/www/docs/api/overview.md b/www/docs/api/overview.md deleted file mode 100644 index ef7cfb3..0000000 --- a/www/docs/api/overview.md +++ /dev/null @@ -1,151 +0,0 @@ -# API Overview - -Mist provides a comprehensive REST API for programmatic access to all features. - -## Base URL - -``` -https://your-mist-instance.com/api -``` - -## Authentication - -All API requests require authentication using JWT tokens stored in HTTP-only cookies. - -### Via Browser - -Cookies are set automatically after login. - -### Via cURL/API Client - -1. Login to get session cookie: - -```bash -curl -X POST https://mist.example.com/api/auth/login \ - -H "Content-Type: application/json" \ - -d '{"email": "user@example.com", "password": "password"}' \ - -c cookies.txt -``` - -2. Use cookie in subsequent requests: - -```bash -curl https://mist.example.com/api/apps \ - -b cookies.txt -``` - -## API Endpoints - -### Authentication -- `POST /api/auth/login` - Login -- `POST /api/auth/logout` - Logout -- `GET /api/auth/me` - Get current user - -### Projects -- `GET /api/projects` - List projects -- `POST /api/projects/create` - Create project -- `GET /api/projects/:id` - Get project -- `PUT /api/projects/update` - Update project -- `DELETE /api/projects/delete` - Delete project - -### Applications -- `POST /api/apps/get` - List applications -- `POST /api/apps/create` - Create application -- `POST /api/apps/update` - Update application -- `POST /api/apps/delete` - Delete application - -### Deployments -- `POST /api/deployments/create` - Trigger deployment -- `POST /api/deployments/get` - List deployments -- `GET /api/deployments/:id` - Get deployment details - -### Environment Variables -- `POST /api/apps/envs/create` - Create variable -- `POST /api/apps/envs/get` - List variables -- `PUT /api/apps/envs/update` - Update variable -- `DELETE /api/apps/envs/delete` - Delete variable - -### Domains -- `POST /api/apps/domains/create` - Add domain -- `POST /api/apps/domains/get` - List domains -- `DELETE /api/apps/domains/delete` - Remove domain - -### Users (Admin Only) -- `POST /api/users/get` - List users -- `POST /api/users/create` - Create user -- `DELETE /api/users/delete` - Delete user - -### GitHub Integration -- `POST /api/github/repos` - List repositories -- `POST /api/github/branches` - List branches -- `POST /api/webhooks/github` - Webhook endpoint - -## WebSocket Endpoints - -### Container Logs -``` -ws://your-mist-instance.com/api/ws/logs/:containerId -``` - -### System Metrics -``` -ws://your-mist-instance.com/api/ws/metrics -``` - -### Deployment Status -``` -ws://your-mist-instance.com/api/ws/deployment/:deploymentId -``` - -## Response Format - -### Success Response - -```json -{ - "success": true, - "data": { ... } -} -``` - -### Error Response - -```json -{ - "success": false, - "error": "Error message" -} -``` - -## Rate Limiting - -Currently no rate limiting is enforced. This will be added in future releases. - -## API Versioning - -The API is currently unversioned. Breaking changes will be avoided when possible. - -## Coming Soon - -
-

🚧 API Improvements

-
- -- **API Tokens** - Generate tokens for non-browser clients -- **OpenAPI Specification** - Interactive API documentation -- **API Versioning** - v1, v2, etc. -- **Rate Limiting** - Prevent API abuse -- **Webhooks** - Subscribe to events -- **GraphQL API** - Alternative to REST - -## Detailed Documentation - -- [Authentication API](./authentication) -- [Projects API](./projects) -- [Applications API](./applications) -- [Deployments API](./deployments) -- [Environment Variables API](./environment-variables) -- [Domains API](./domains) -- [Users API](./users) -- [GitHub API](./github) -- [WebSockets API](./websockets) diff --git a/www/docs/api/projects.md b/www/docs/api/projects.md deleted file mode 100644 index 6c38bb1..0000000 --- a/www/docs/api/projects.md +++ /dev/null @@ -1,54 +0,0 @@ -# Projects API - -Manage projects via API. - -## List Projects - -`GET /api/projects` - -Returns all projects accessible to the authenticated user. - -## Create Project - -`POST /api/projects/create` - -**Request:** -```json -{ - "name": "My Project", - "description": "Project description", - "tags": "production,web" -} -``` - -## Get Project - -`GET /api/projects/:id` - -Returns project details including applications and members. - -## Update Project - -`PUT /api/projects/update` - -**Request:** -```json -{ - "id": 1, - "name": "Updated Name", - "description": "New description" -} -``` - -## Delete Project - -`DELETE /api/projects/delete` - -**Request:** -```json -{ - "id": 1 -} -``` - -See [server/api/handlers/projects](https://github.com/corecollectives/mist/tree/main/server/api/handlers/projects) for details. diff --git a/www/docs/api/users.md b/www/docs/api/users.md deleted file mode 100644 index d110bf6..0000000 --- a/www/docs/api/users.md +++ /dev/null @@ -1,39 +0,0 @@ -# Users API - -Manage users (Admin only). - -## List Users - -`POST /api/users/get` - -Returns all users in the system. - -## Create User - -`POST /api/users/create` - -**Request:** -```json -{ - "email": "newuser@example.com", - "password": "securepassword", - "role": "user" -} -``` - -## Delete User - -`DELETE /api/users/delete` - -**Request:** -```json -{ - "id": 1 -} -``` - -::: warning Admin Only -These endpoints require admin role. -::: - -See [server/api/handlers/auth/users.go](https://github.com/corecollectives/mist/blob/main/server/api/handlers/auth/users.go) for details. diff --git a/www/docs/api/websockets.md b/www/docs/api/websockets.md deleted file mode 100644 index eefd3ff..0000000 --- a/www/docs/api/websockets.md +++ /dev/null @@ -1,327 +0,0 @@ -# WebSockets API - -Real-time data streaming via WebSocket connections. Mist provides WebSocket endpoints for live container logs, deployment status, and system metrics. - -## Container Logs (Real-time) - -`WS /ws/container/logs?appId={appId}` - -Streams live container logs from a running application. This provides real-time log output as the container generates it. - -### Connection - -```javascript -const ws = new WebSocket('wss://mist.example.com/ws/container/logs?appId=1'); - -ws.onopen = () => { - console.log('Connected to container logs'); -}; - -ws.onmessage = (event) => { - const message = JSON.parse(event.data); - - switch(message.type) { - case 'status': - console.log('Container status:', message.data); - break; - case 'log': - console.log('Log:', message.data.line); - break; - case 'error': - console.error('Error:', message.data.message); - break; - case 'end': - console.log('Log stream ended'); - break; - } -}; - -ws.onerror = (error) => { - console.error('WebSocket error:', error); -}; - -ws.onclose = () => { - console.log('Disconnected from container logs'); -}; -``` - -### Message Types - -**Status Update (initial connection):** -```json -{ - "type": "status", - "timestamp": "2025-01-15T10:30:00Z", - "data": { - "container": "mist-app-1", - "state": "running", - "status": "Up 2 hours" - } -} -``` - -**Log Line:** -```json -{ - "type": "log", - "timestamp": "2025-01-15T10:30:01Z", - "data": { - "line": "2025-01-15 10:30:01 [INFO] Server listening on port 3000" - } -} -``` - -**Error:** -```json -{ - "type": "error", - "timestamp": "2025-01-15T10:30:05Z", - "data": { - "message": "Container not found" - } -} -``` - -**Stream End:** -```json -{ - "type": "end", - "timestamp": "2025-01-15T10:35:00Z", - "data": { - "message": "Log stream ended" - } -} -``` - -### Features - -- **Auto-reconnect**: Includes ping/pong messages every 30 seconds to keep connection alive -- **Buffer size**: Handles large log lines up to 1MB -- **Tail logs**: Shows last 100 lines on connection -- **Real-time**: Streams logs as they're generated - -### Notes - -::: warning Container Must Be Running -The WebSocket connection requires the container to be in a `running` state. If the container is stopped, you'll receive an error message. -::: - -## Deployment Logs & Status - -`WS /ws/deployment/logs?deploymentId={deploymentId}` - -Streams real-time deployment progress, build logs, and status updates during a deployment. - -### Connection - -```javascript -const ws = new WebSocket('wss://mist.example.com/ws/deployment/logs?deploymentId=15'); - -ws.onmessage = (event) => { - const message = JSON.parse(event.data); - - if (message.type === 'status') { - updateProgressBar(message.data.progress); - updateStage(message.data.stage); - } else if (message.type === 'log') { - appendLog(message.data.line); - } else if (message.type === 'error') { - showError(message.data.message); - } -}; -``` - -### Message Types - -**Status Update:** -```json -{ - "type": "status", - "timestamp": "2025-01-15T10:30:15Z", - "data": { - "deployment_id": 15, - "status": "building", - "stage": "building_image", - "progress": 50, - "message": "Building Docker image...", - "error_message": "" - } -} -``` - -**Log Line:** -```json -{ - "type": "log", - "timestamp": "2025-01-15T10:30:16Z", - "data": { - "line": "Step 3/8 : COPY package*.json ./" - } -} -``` - -**Error:** -```json -{ - "type": "error", - "timestamp": "2025-01-15T10:30:30Z", - "data": { - "message": "Docker build failed: exit code 1" - } -} -``` - -### Status Flow - -1. **pending** (0%) - Deployment queued -2. **building** (25-75%) - Building Docker image -3. **deploying** (75-90%) - Starting container -4. **success** (100%) - Deployment complete -5. **failed** (error) - Deployment failed - -### Stages - -- `cloning_repo` - Cloning Git repository -- `building_image` - Building Docker image -- `stopping_old` - Stopping previous container -- `starting_new` - Starting new container -- `completed` - Deployment finished - -## System Metrics - -`WS /ws/metrics` - -Streams real-time system metrics including CPU usage, memory, disk space, and Docker stats. - -### Connection - -```javascript -const ws = new WebSocket('wss://mist.example.com/ws/metrics'); - -ws.onmessage = (event) => { - const metrics = JSON.parse(event.data); - updateDashboard(metrics); -}; -``` - -### Message Format - -```json -{ - "timestamp": "2025-01-15T10:30:00Z", - "cpu": { - "usage": 25.5, - "cores": 4 - }, - "memory": { - "used": 4294967296, - "total": 17179869184, - "percent": 25.0 - }, - "disk": { - "used": 53687091200, - "total": 536870912000, - "percent": 10.0 - }, - "docker": { - "containers_running": 5, - "containers_total": 8, - "images": 12 - } -} -``` - -### Update Frequency - -Metrics are broadcast every **1 second** to all connected clients. - -## React/TypeScript Example - -Here's a complete example using React hooks: - -```typescript -import { useEffect, useState } from 'react'; - -interface LogMessage { - type: 'log' | 'status' | 'error' | 'end'; - timestamp: string; - data: any; -} - -export function useContainerLogs(appId: number) { - const [logs, setLogs] = useState([]); - const [status, setStatus] = useState('connecting'); - const [error, setError] = useState(null); - - useEffect(() => { - const ws = new WebSocket( - `wss://mist.example.com/ws/container/logs?appId=${appId}` - ); - - ws.onopen = () => { - setStatus('connected'); - }; - - ws.onmessage = (event) => { - const message: LogMessage = JSON.parse(event.data); - - switch (message.type) { - case 'log': - setLogs(prev => [...prev, message.data.line]); - break; - case 'status': - setStatus(message.data.state); - break; - case 'error': - setError(message.data.message); - break; - case 'end': - setStatus('ended'); - break; - } - }; - - ws.onerror = () => { - setError('WebSocket connection error'); - setStatus('error'); - }; - - ws.onclose = () => { - setStatus('disconnected'); - }; - - return () => { - ws.close(); - }; - }, [appId]); - - return { logs, status, error }; -} -``` - -## Authentication - -WebSocket connections inherit authentication from HTTP cookies. Make sure the user is authenticated before establishing WebSocket connections. - -::: tip Secure Connections -In production, always use `wss://` (WebSocket Secure) instead of `ws://` for encrypted connections. -::: - -## Error Handling - -Common error scenarios: - -- **Container not found**: Application doesn't have a running container -- **Permission denied**: User doesn't have access to the application -- **Connection timeout**: Network issues or firewall blocking WebSocket -- **Container not running**: Container is stopped or in error state - -## Browser Compatibility - -WebSocket API is supported in all modern browsers: -- Chrome/Edge 16+ -- Firefox 11+ -- Safari 7+ -- Opera 12.1+ - -For the complete implementation, see [server/websockets](https://github.com/corecollectives/mist/tree/main/server/websockets). diff --git a/www/docs/deployment/backup.md b/www/docs/deployment/backup.md deleted file mode 100644 index 092f6b3..0000000 --- a/www/docs/deployment/backup.md +++ /dev/null @@ -1,527 +0,0 @@ -# Backup & Recovery - -Backup and restore your Mist installation. - -## What to Backup - -### 1. SQLite Database (Critical) - -The database contains all your Mist data: -- Users, sessions, and authentication tokens -- Projects and team members -- Applications and configurations -- Deployments and deployment history -- Environment variables (including secrets) -- Domains and SSL certificate tracking -- GitHub App credentials -- Audit logs - -**Location**: `/var/lib/mist/mist.db` - -**Size**: Typically 10-100 MB depending on usage - -::: danger Critical Data -This is the **single most important file** to backup. Without it, you lose all configuration and deployment history. -::: - -### 2. SSL Certificates (Important) - -Let's Encrypt SSL certificates for your domains. - -**Location**: `/opt/mist/letsencrypt/acme.json` - -**Note**: Certificates can be re-issued by Let's Encrypt, but backing them up prevents rate limiting and downtime during recovery. - -### 3. Traefik Configuration (Auto-Generated) - -Dynamic Traefik routing configuration. - -**Location**: `/var/lib/mist/traefik/dynamic.yml` - -**Note**: This file is auto-generated from the database, so restoring the database will recreate it. - -### 4. User Uploads (Optional) - -User avatars and uploaded files. - -**Location**: `/var/lib/mist/uploads/` - -**Size**: Usually small (< 100 MB) - -### 5. Application Data (Important for Databases) - -If you're running databases (PostgreSQL, MySQL, MongoDB, Redis) as applications in Mist, their data is stored in Docker volumes. - -**List volumes:** -```bash -docker volume ls | grep mist -``` - -**Backup application volumes separately** if they contain important data. - -### What NOT to Backup - -- `/var/lib/mist/logs/` - Build logs (can be large, usually not needed) -- Git repositories - Cloned from source, can be re-cloned -- Docker images - Can be rebuilt -- `/var/lib/mist/traefik/dynamic.yml` - Auto-generated from database - -## Manual Backup - -### Quick Database Backup - -```bash -# Stop Mist service for consistency -sudo systemctl stop mist - -# Backup database with timestamp -sudo cp /var/lib/mist/mist.db /var/backups/mist_$(date +%Y%m%d_%H%M%S).db - -# Start Mist service -sudo systemctl start mist - -# Verify backup -ls -lh /var/backups/mist_*.db -``` - -::: tip Hot Backup (No Downtime) -SQLite supports online backups. You can backup without stopping Mist: - -```bash -# Create backup directory -sudo mkdir -p /var/backups/mist - -# Hot backup using SQLite -sqlite3 /var/lib/mist/mist.db ".backup /var/backups/mist_$(date +%Y%m%d_%H%M%S).db" -``` -::: - -### Full System Backup - -Backup all Mist data including database, certificates, and uploads: - -```bash -# Create backup directory -sudo mkdir -p /var/backups/mist - -# Stop Mist for consistency (optional for hot backup) -sudo systemctl stop mist - -# Backup everything -sudo tar -czf /var/backups/mist_full_$(date +%Y%m%d_%H%M%S).tar.gz \ - /var/lib/mist/mist.db \ - /var/lib/mist/uploads \ - /opt/mist/letsencrypt/acme.json \ - /opt/mist/traefik-static.yml - -# Start Mist -sudo systemctl start mist - -# Verify backup -ls -lh /var/backups/mist_full_*.tar.gz -``` - -### Backup Database Volumes (for Database Applications) - -If you run databases (PostgreSQL, MySQL, etc.) as applications in Mist: - -```bash -# List all Docker volumes -docker volume ls - -# Backup a specific volume -docker run --rm -v app-123_data:/data -v /var/backups:/backup \ - alpine tar -czf /backup/app-123_data_$(date +%Y%m%d).tar.gz -C /data . -``` - -## Automated Backup Script - -Create `/usr/local/bin/mist-backup.sh`: - -```bash -#!/bin/bash - -# Mist Automated Backup Script -BACKUP_DIR="/var/backups/mist" -DATE=$(date +%Y%m%d_%H%M%S) -RETENTION_DAYS=30 -DB_PATH="/var/lib/mist/mist.db" -CERT_PATH="/opt/mist/letsencrypt/acme.json" - -# Create backup directory -mkdir -p $BACKUP_DIR - -# Hot backup database using SQLite (no downtime) -if [ -f "$DB_PATH" ]; then - sqlite3 $DB_PATH ".backup $BACKUP_DIR/mist_$DATE.db" - echo "✅ Database backed up: mist_$DATE.db" -else - echo "❌ Database not found at $DB_PATH" - exit 1 -fi - -# Backup SSL certificates -if [ -f "$CERT_PATH" ]; then - cp $CERT_PATH $BACKUP_DIR/acme_$DATE.json - echo "✅ Certificates backed up: acme_$DATE.json" -fi - -# Backup user uploads (if exists) -if [ -d "/var/lib/mist/uploads" ]; then - tar -czf $BACKUP_DIR/uploads_$DATE.tar.gz -C /var/lib/mist uploads - echo "✅ Uploads backed up: uploads_$DATE.tar.gz" -fi - -# Remove old backups (keep last N days) -find $BACKUP_DIR -name "mist_*.db" -mtime +$RETENTION_DAYS -delete -find $BACKUP_DIR -name "acme_*.json" -mtime +$RETENTION_DAYS -delete -find $BACKUP_DIR -name "uploads_*.tar.gz" -mtime +$RETENTION_DAYS -delete - -echo "✅ Backup completed at $DATE" -echo "📁 Backup location: $BACKUP_DIR" - -# Optional: Copy to remote server -# rsync -avz $BACKUP_DIR/ user@backup-server:/backups/mist/ -``` - -Make executable and schedule: - -```bash -# Make script executable -sudo chmod +x /usr/local/bin/mist-backup.sh - -# Test the script -sudo /usr/local/bin/mist-backup.sh - -# Schedule daily backups at 2 AM -(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/mist-backup.sh") | crontab - - -# Verify cron job -crontab -l -``` - -::: tip Backup Frequency -- **Development**: Daily backups with 7-day retention -- **Production**: Daily backups with 30-day retention + offsite copies -- **Critical systems**: Multiple daily backups + real-time replication -::: - -## Backup to Cloud Storage - -### AWS S3 - -```bash -# Install AWS CLI -curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" -unzip awscliv2.zip -sudo ./aws/install - -# Configure credentials -aws configure -# Enter: Access Key ID, Secret Access Key, Region - -# Backup to S3 -aws s3 cp /var/backups/mist/mist_$(date +%Y%m%d_%H%M%S).db \ - s3://your-bucket/mist-backups/ - -# Automated S3 backup (add to backup script) -aws s3 sync /var/backups/mist/ s3://your-bucket/mist-backups/ --delete -``` - -### Backblaze B2 - -```bash -# Install B2 CLI -sudo pip3 install b2 - -# Authenticate -b2 authorize-account - -# Create bucket (one-time) -b2 create-bucket mist-backups allPrivate - -# Upload backup -b2 upload-file mist-backups /var/backups/mist/mist_latest.db mist_$(date +%Y%m%d).db -``` - -### Rsync to Remote Server - -```bash -# Setup SSH key (one-time, run as backup user) -ssh-keygen -t ed25519 -f ~/.ssh/backup_key -N "" -ssh-copy-id -i ~/.ssh/backup_key user@backup-server - -# Sync backups -rsync -avz -e "ssh -i ~/.ssh/backup_key" \ - /var/backups/mist/ \ - user@backup-server:/backups/mist/ - -# Add to automated script -rsync -avz --delete \ - /var/backups/mist/ \ - user@backup-server:/backups/mist/ -``` - -### Rclone (Universal Cloud Backup) - -Rclone supports 40+ cloud providers (S3, Google Drive, Dropbox, OneDrive, etc.): - -```bash -# Install rclone -curl https://rclone.org/install.sh | sudo bash - -# Configure cloud provider (interactive) -rclone config - -# Backup to cloud -rclone copy /var/backups/mist/ remote:mist-backups/ -v - -# Automated sync (add to backup script) -rclone sync /var/backups/mist/ remote:mist-backups/ --delete-excluded -``` - -## Restore from Backup - -### Database Restore - -```bash -# Stop Mist service -sudo systemctl stop mist - -# Backup current database (just in case) -sudo cp /var/lib/mist/mist.db /var/lib/mist/mist.db.before-restore - -# Restore database from backup -sudo cp /var/backups/mist/mist_20250122_140000.db /var/lib/mist/mist.db - -# Fix permissions (important!) -sudo chown $USER:$USER /var/lib/mist/mist.db -sudo chmod 644 /var/lib/mist/mist.db - -# Start Mist service -sudo systemctl start mist - -# Verify service is running -sudo systemctl status mist - -# Check logs for errors -journalctl -u mist -f -``` - -::: warning Permission Issues -Make sure the database file is owned by the user running the Mist service (usually the user who installed Mist, not `mist` or `root`). -::: - -### Full System Restore - -```bash -# Stop Mist service -sudo systemctl stop mist - -# Extract full backup -sudo tar -xzf /var/backups/mist_full_20250122.tar.gz -C / - -# Or restore individual files -sudo tar -xzf /var/backups/mist_full_20250122.tar.gz \ - -C / \ - var/lib/mist/mist.db \ - opt/mist/letsencrypt/acme.json - -# Fix permissions -sudo chown -R $USER:$USER /var/lib/mist -sudo chmod 600 /opt/mist/letsencrypt/acme.json - -# Restart services -sudo systemctl start mist -docker compose -f /opt/mist/traefik-compose.yml restart - -# Verify everything is running -sudo systemctl status mist -docker ps | grep traefik -``` - -### Restore SSL Certificates - -```bash -# Stop Traefik -docker compose -f /opt/mist/traefik-compose.yml down - -# Restore certificates -sudo cp /var/backups/mist/acme_20250122.json /opt/mist/letsencrypt/acme.json -sudo chmod 600 /opt/mist/letsencrypt/acme.json - -# Start Traefik -docker compose -f /opt/mist/traefik-compose.yml up -d - -# Verify certificates are loaded -docker logs traefik 2>&1 | grep -i certificate -``` - -### Restore Docker Volumes (Database Applications) - -```bash -# Stop the application container first -docker stop container-name - -# Restore volume from backup -docker run --rm -v app-123_data:/data -v /var/backups:/backup \ - alpine sh -c "cd /data && tar -xzf /backup/app-123_data_20250122.tar.gz" - -# Start the application container -docker start container-name -``` - -## Disaster Recovery - -### Complete Server Loss - -Follow these steps to recover from total server failure: - -1. **Provision New Server** - ```bash - # Same OS as original (Ubuntu 20.04+ recommended) - # Install Docker first - curl -fsSL https://get.docker.com | sh - ``` - -2. **Install Mist** - ```bash - curl -fsSL https://raw.githubusercontent.com/corecollectives/mist/main/install.sh | bash - ``` - -3. **Stop Mist Service** - ```bash - sudo systemctl stop mist - ``` - -4. **Restore Database** - ```bash - # Copy backup to new server - scp backup-server:/backups/mist_latest.db /tmp/ - - # Restore database - sudo cp /tmp/mist_latest.db /var/lib/mist/mist.db - sudo chown $USER:$USER /var/lib/mist/mist.db - ``` - -5. **Restore SSL Certificates (optional, but recommended)** - ```bash - # Copy certificates - scp backup-server:/backups/acme.json /tmp/ - - # Restore - sudo cp /tmp/acme.json /opt/mist/letsencrypt/acme.json - sudo chmod 600 /opt/mist/letsencrypt/acme.json - ``` - -6. **Start Services** - ```bash - sudo systemctl start mist - docker compose -f /opt/mist/traefik-compose.yml restart - ``` - -7. **Verify Recovery** - ```bash - # Check Mist service - sudo systemctl status mist - - # Check Traefik - docker ps | grep traefik - - # Access web interface - curl http://localhost:8080/health # or your domain - ``` - -8. **Update DNS** (if IP changed) - - Update A records to point to new server IP - - Wait for DNS propagation (5-60 minutes) - -### Database Corruption - -Check and recover from database corruption: - -```bash -# Check database integrity -sqlite3 /var/lib/mist/mist.db "PRAGMA integrity_check;" - -# If output is "ok", database is fine -# If errors appear, restore from backup: - -sudo systemctl stop mist -sudo cp /var/lib/mist/mist.db /var/lib/mist/mist.db.corrupted -sudo cp /var/backups/mist/mist_LATEST.db /var/lib/mist/mist.db -sudo systemctl start mist -``` - -### Accidental Data Deletion - -If you accidentally delete data through the UI: - -```bash -# Stop Mist immediately -sudo systemctl stop mist - -# Restore from most recent backup -sudo cp /var/backups/mist/mist_$(ls -t /var/backups/mist/mist_*.db | head -1) \ - /var/lib/mist/mist.db - -# Start Mist -sudo systemctl start mist -``` - -::: tip Recovery Point Objective (RPO) -Your RPO = time between backups. If you backup daily at 2 AM and disaster strikes at 1 PM, you lose up to 11 hours of data. For critical systems, increase backup frequency or use real-time replication. -::: - -## Backup Best Practices - -### The 3-2-1 Rule - -- **3** copies of data -- **2** different storage types -- **1** offsite copy - -### Backup Checklist - -- [ ] Automated daily backups configured -- [ ] Backups stored on separate disk/server -- [ ] Offsite/cloud backup configured -- [ ] Backup retention policy defined (7-30 days) -- [ ] Backup integrity tested regularly -- [ ] Restore procedure documented -- [ ] Recovery time objective (RTO) defined -- [ ] Recovery point objective (RPO) defined - -### Test Your Backups - -Regularly test restore procedures: - -```bash -# Test restore on separate server -scp backup-server:/backups/mist_latest.db /tmp/test-restore.db -sqlite3 /tmp/test-restore.db "SELECT COUNT(*) FROM users;" -``` - -## Coming Soon - -The following backup features are planned for future releases: - -- **Built-in Backup UI** - Configure and manage backups from the dashboard -- **One-Click Restore** - Restore from backup through the UI -- **Automated S3/Cloud Backup** - Built-in integration with cloud storage -- **Scheduled Backups** - Configure backup schedules per project or system-wide -- **Backup Verification** - Automatic integrity checks and restore testing -- **Point-in-Time Recovery** - Restore to a specific moment in time -- **Incremental Backups** - Save storage with differential backups -- **Database Replication** - Real-time database replication to standby server -- **Automated Application Volume Backups** - Backup database volumes automatically -- **Backup Encryption** - Encrypt backups at rest and in transit -- **Retention Policies** - Flexible retention rules (hourly, daily, weekly, monthly) -- **Webhook Notifications** - Get notified on backup success/failure - -## Getting Help - -If you encounter issues with backup or recovery: - -- [GitHub Issues](https://github.com/corecollectives/mist/issues) -- [GitHub Discussions](https://github.com/corecollectives/mist/discussions) diff --git a/www/docs/deployment/configuration.md b/www/docs/deployment/configuration.md deleted file mode 100644 index 45231df..0000000 --- a/www/docs/deployment/configuration.md +++ /dev/null @@ -1,120 +0,0 @@ -# Configuration - -Configure Mist for your environment. - -## Configuration System - -Mist uses a **database-driven configuration system**. Most settings are stored in the SQLite database at `/var/lib/mist/mist.db` and managed through the web UI or API. - -::: tip -There is no `/etc/mist/config.yml` file. System settings are configured through the **Settings → System** page in the web interface. -::: - -## Fixed Configuration Values - -Some values are hardcoded in the application: - -### Server Port - -- **Port:** `8080` (hardcoded) -- **Location:** `server/api/main.go:33` -- **Cannot be changed** via environment variables - -### Session Configuration - -- **JWT Expiry:** 31 days (hardcoded) -- **Location:** `server/api/middleware/auth.go:21` - -### File Paths - -- **Root Path:** `/var/lib/mist` -- **Logs:** `/var/lib/mist/logs` -- **Avatars:** `/var/lib/mist/uploads/avatar` -- **Traefik Config:** `/var/lib/mist/traefik` -- **Certificates:** `/opt/mist/letsencrypt/acme.json` - -## Database Configuration - -All system settings and credentials are stored in the SQLite database. - -### GitHub App Configuration - -GitHub App credentials are stored in the `github_app` table: -- App ID -- Client ID -- Client Secret -- Webhook Secret -- Private Key (RSA) - -Configure through: **Settings → Integrations → GitHub App** - -See [GitHub App Setup](./github-app) for configuration instructions. - -## Docker Configuration - -Mist uses the Docker socket at `/var/run/docker.sock`. - -Ensure the user running Mist has Docker permissions: - -```bash -sudo usermod -aG docker mist-user -``` - -## Traefik Integration - -Mist automatically generates Traefik configuration in `/var/lib/mist/traefik/`: -- `traefik.yml` - Static configuration -- `dynamic.yml` - Dynamic routing rules (auto-generated) - -See [Traefik Setup](./traefik) for detailed configuration. - -## System Settings - -System-wide settings are configured through the Mist UI (requires owner role). - -### Wildcard Domain - -Configure automatic domain generation for web applications: - -1. Navigate to **Settings** → **System** -2. Enter your wildcard domain (e.g., `example.com` or `*.example.com`) -3. Optionally configure the Mist dashboard subdomain name (default: `mist`) - -When configured, new web applications automatically receive domains in the format: -``` -{project-name}-{app-name}.{wildcard-domain} -``` - -**Example:** -- Wildcard domain: `apps.example.com` -- Project: `production`, App: `api` -- Auto-generated domain: `production-api.apps.example.com` - -**DNS Requirements:** -Configure a wildcard DNS record: -``` -Type: A -Name: * -Value: YOUR_SERVER_IP -``` - -Or for nested subdomains: -``` -Type: A -Name: *.apps -Value: YOUR_SERVER_IP -``` - -[Learn more about wildcard domains →](../guide/domains#wildcard-domain-configuration) - -## Coming Soon - -The following configuration features are planned: - -- **Configurable Server Port** - Change port via UI or configuration -- **Configurable JWT Secret** - Set JWT secret during installation -- **SMTP Configuration** - Email settings for notifications -- **Backup Settings** - Automatic backup configuration -- **Resource Limits** - Global resource limits per project/application -- **Logging Configuration** - Log levels and destinations -- **Custom SSL Certificates** - Upload custom TLS certificates diff --git a/www/docs/deployment/github-app.md b/www/docs/deployment/github-app.md deleted file mode 100644 index cf2a491..0000000 --- a/www/docs/deployment/github-app.md +++ /dev/null @@ -1,363 +0,0 @@ -# GitHub App Setup - -Configure GitHub App integration for automatic deployments from GitHub repositories. - -## Overview - -Mist uses **GitHub App integration** (not OAuth Apps or Personal Access Tokens) to: -- Access your repositories -- Receive webhook notifications for code pushes -- Trigger automatic deployments when you push code -- Clone private repositories securely - -## Automatic GitHub App Creation - -Mist provides a streamlined process to create a GitHub App directly from the dashboard. - -### Step 1: Access GitHub App Setup - -1. Log in to Mist as **Owner** (only Owners can create GitHub Apps) -2. Navigate to **Settings → Integrations → GitHub** -3. Click **"Create GitHub App"** or **"Connect GitHub"** - -### Step 2: Create GitHub App - -1. Log in to Mist as **Owner** (only Owners can create GitHub Apps) -2. Navigate to **Settings → Integrations → GitHub** -3. Click **"Create GitHub App"** or **"Connect GitHub"** - -### Step 3: Automatic GitHub App Creation - -When you click "Create GitHub App" in Mist: - -1. **Mist generates a manifest** with: - - App name: `Mist-{random-5-digit-number}` (e.g., `Mist-12345`) - - Webhook URL: Auto-configured based on your Mist installation - - Callback URLs for OAuth - - Required permissions (contents, metadata, webhooks) - - Event subscriptions (push, pull_request, deployment_status) - -2. **You're redirected to GitHub** with pre-filled configuration - -3. **GitHub creates the app** and redirects back to Mist - -4. **Mist stores credentials** in the database: - - App ID - - Client ID - - Client Secret - - Private Key (RSA) - - Webhook Secret - -::: tip Fully Automated -You don't need to manually configure permissions, generate keys, or copy credentials. Mist handles everything automatically. -::: - -## GitHub App Permissions - -The automatically created GitHub App requests these permissions: - -**Repository Permissions:** -- **Contents**: Read - Access repository files and commits -- **Metadata**: Read - Basic repository information -- **Pull Requests**: Read - View pull requests -- **Deployments**: Read - Deployment status -- **Administration**: Write - Manage repository settings -- **Webhooks**: Write - Create and manage webhooks - -**Subscribed Events:** -- **Push** - Triggered when code is pushed to repository -- **Pull Request** - Triggered on PR events -- **Deployment Status** - Triggered on deployment updates - -**Webhook Security:** -- Webhook signatures are validated using HMAC-SHA256 -- Only requests with valid signatures are processed -- Webhook secret is automatically generated during app creation - -## Install GitHub App on Repositories - -After creating the GitHub App, you need to install it on the repositories you want to deploy: - -### Install on Your Account/Organization - -1. **From Mist Dashboard**: - - After successful app creation, you're redirected to installation page - - Or go to GitHub → Settings → Applications → Your Mist App → Install - -2. **Select Installation Target**: - - Personal account - - Or organization (if you have access) - -3. **Choose Repository Access**: - - **All repositories**: Mist can access all current and future repos - - **Only select repositories**: Choose specific repos to grant access - -4. **Complete Installation**: - - Click **"Install"** - - You'll be redirected back to Mist - -### Verify Installation - -In Mist dashboard: - -1. **Create a new application** or edit existing -2. Go to **Git Configuration** section -3. **Repository dropdown** should show your installed repositories -4. Select repository and branch -5. Configure Dockerfile path -6. Deploy! - -::: tip Multiple Organizations -If you have multiple GitHub organizations, you can install the same GitHub App on each organization separately. Each installation is independent. -::: - -## Configure Webhook URL for Production - -If you need to update the GitHub App webhook URL after initial creation: - -1. Go to [GitHub Apps Settings](https://github.com/settings/apps) -2. Select your Mist app -3. Update **Webhook URL** to: `https://mist.yourdomain.com/api/github/webhook` -4. Update **Callback URL** to: `https://mist.yourdomain.com/api/github/callback` -5. Update **Setup URL** to: `https://mist.yourdomain.com/api/github/installation/callback` -6. Click **"Save changes"** - -## Automatic Deployments - -Once configured, Mist automatically deploys when you push code: - -### How it Works - -1. **You push code** to a branch configured in Mist -2. **GitHub sends webhook** to Mist -3. **Mist receives push event** and starts deployment -4. **Clones repository** using GitHub App authentication -5. **Builds Docker image** from Dockerfile -6. **Deploys container** with configured settings -7. **Updates deployment status** in Mist dashboard - -### Monitor Webhook Deliveries - -Check if webhooks are being delivered successfully: - -1. Go to [GitHub Apps Settings](https://github.com/settings/apps) -2. Select your Mist app -3. Click **"Advanced" tab** -4. View **Recent Deliveries** - -Look for: -- ✅ **200 OK**: Webhook received successfully -- ❌ **Failed**: Check error details and Mist logs - -## Test Webhook Integration - -Verify that automatic deployments work correctly: - -### Method 1: Push to Repository - -1. **Configure application** in Mist with GitHub repository -2. **Make a change** to your code -3. **Commit and push**: - ```bash - git add . - git commit -m "Test deployment" - git push origin main - ``` -4. **Check Mist dashboard**: - - Navigate to application → Deployments - - You should see a new deployment starting automatically - - Monitor build logs in real-time - -### Method 2: Redeliver Webhook - -Test without pushing new code: - -1. Go to [GitHub Apps Settings](https://github.com/settings/apps) -2. Click your Mist app → **Advanced** tab -3. Find a recent **push** event in Recent Deliveries -4. Click **"Redeliver"** -5. Check Mist dashboard for new deployment - -### Method 3: Check Mist Logs - -Monitor webhook reception in real-time: - -```bash -# Watch for incoming webhooks -sudo journalctl -u mist -f | grep -i "webhook\|github" - -# Check recent webhook activity -sudo journalctl -u mist -n 100 | grep -i webhook -``` - -Look for log messages like: -- `Received GitHub webhook` -- `Processing push event for repository: owner/repo` -- `Starting deployment for application: app-name` - -## Troubleshooting - -### Webhooks Not Being Received - -**Check webhook deliveries in GitHub:** - -1. GitHub Apps → Your App → Advanced tab -2. Look at Recent Deliveries -3. If failed: - - ❌ **Connection timeout**: Firewall blocking GitHub IPs - - ❌ **Connection refused**: Mist not running or port 8080 not accessible - - ❌ **404 Not Found**: Wrong webhook URL - - ❌ **500 Internal Server Error**: Check Mist logs for errors - -**Verify webhook URL is accessible:** - -```bash -# Test from external server (or use webhook.site for testing) -curl -X POST https://your-mist-domain.com/api/github/webhook \ - -H "Content-Type: application/json" \ - -d '{"test": true}' - -# Should return 200 or similar (not 404/timeout) -``` - -**Check firewall rules:** - -```bash -# Verify port 80/443 are open -sudo ufw status | grep -E "80|443" - -# If using Mist API directly (port 8080), verify it's accessible -curl http://your-domain:8080/health # Should work -``` - -**Allow GitHub webhook IPs (optional, for security):** - -```bash -# Get GitHub's current IP ranges -curl https://api.github.com/meta | jq -r '.hooks[]' - -# Example: Allow GitHub IPs for webhook endpoint -# (Implement via nginx/firewall rules) -``` - -### Repositories Not Showing in Dropdown - -**Verify GitHub App installation:** - -1. Go to GitHub → Settings → Applications → Installed GitHub Apps -2. Find your Mist app -3. Verify it's installed on the correct account/organization -4. Check repository access (All repositories or Selected ones) - -**Reinstall GitHub App:** - -If repositories still don't appear: -1. Uninstall the GitHub App from GitHub settings -2. Go back to Mist → Settings → Integrations -3. Reinstall the app -4. Select repositories to grant access - -**Check Mist logs:** - -```bash -sudo journalctl -u mist -n 100 | grep -i "github\|repository" -``` - -### Private Key Errors - -If you see errors related to GitHub authentication: - -**Verify GitHub App exists in database:** - -```bash -sqlite3 /var/lib/mist/mist.db "SELECT app_id, client_id FROM github_app;" -``` - -**Check private key format:** - -The private key should be stored as RSA format in the database. If corrupted: -1. Delete the GitHub App from Mist settings -2. Recreate it using the automatic setup process - -### Deployment Not Triggering - -**Verify branch configuration:** - -- Make sure you're pushing to the **branch configured in Mist** -- Default is often `main` but could be `master`, `develop`, etc. - -**Check deployment logs:** - -```bash -# View recent deployments -sudo journalctl -u mist | grep -i "deployment\|deploy" - -# Check for errors -sudo journalctl -u mist -p err -``` - -**Manually trigger deployment:** - -From Mist dashboard: -1. Go to application details -2. Click **"Deploy"** button -3. Monitor build logs - -### Webhook URL Changed - -If you change your Mist domain or IP: - -1. Update webhook URL in GitHub App settings (see "Configure Webhook URL for Production" above) -2. Or delete and recreate the GitHub App through Mist UI - -## Security Best Practices - -### Webhook Security - -Mist validates all incoming webhook requests using HMAC-SHA256 signatures. Only authenticated requests from GitHub are processed. - -**Additional Security (Optional):** - -If you want an extra layer of security, restrict webhook endpoint access to GitHub's IP ranges: - -**Option 1: IP Whitelist (Nginx)** - -```nginx -# /etc/nginx/sites-available/mist -location /api/github/webhook { - # GitHub webhook IP ranges (update periodically from https://api.github.com/meta) - allow 140.82.112.0/20; - allow 143.55.64.0/20; - allow 185.199.108.0/22; - allow 192.30.252.0/22; - deny all; - - proxy_pass http://localhost:8080; -} -``` - -**Option 2: Firewall Rules** - -Use UFW or iptables to allow only GitHub IP ranges for the webhook endpoint. - -## Advanced Configuration - -### Multiple GitHub Apps - -You can only have **one GitHub App per Mist instance** currently. If you need multiple: - -- Use different Mist instances for different organizations -- Or install the same GitHub App on multiple organizations - -### GitHub Enterprise Server - -Mist uses GitHub.com APIs. For GitHub Enterprise Server support: -- Currently not supported -- Coming soon: Configurable GitHub API base URL - -## Further Reading - -- [GitHub Apps Documentation](https://docs.github.com/en/apps) -- [GitHub Webhooks](https://docs.github.com/en/webhooks) -- [GitHub API Meta Endpoint](https://docs.github.com/en/rest/meta) - Get webhook IP ranges - diff --git a/www/docs/deployment/installation.md b/www/docs/deployment/installation.md deleted file mode 100644 index f00e440..0000000 --- a/www/docs/deployment/installation.md +++ /dev/null @@ -1,430 +0,0 @@ -# Installation - -Install Mist on your server with a single command. - -## Prerequisites - -### System Requirements - -- **OS**: Ubuntu 20.04+, Debian 11+, Fedora, RHEL/CentOS, Arch Linux (any Linux with systemd) -- **RAM**: Minimum 1GB, recommended 2GB+ -- **Disk**: Minimum 10GB free space -- **Docker**: Version 20.10 or later (**REQUIRED** - must be installed first) -- **Docker Compose**: v2 (usually bundled with Docker) -- **Ports**: 80, 443, 8080 must be available - -### Docker Installation - -::: warning Install Docker First -The Mist installation script does NOT install Docker. You must install Docker before running the script. -::: - -```bash -# Ubuntu/Debian -curl -fsSL https://get.docker.com | sh -sudo usermod -aG docker $USER - -# Log out and back in for group changes to take effect - -# Verify installation -docker --version -docker compose version -``` - -[Official Docker Installation Guide →](https://docs.docker.com/engine/install/) - -## Quick Install - -### One-Line Installation - -```bash -curl -fsSL https://trymist.cloud/install.sh | bash -``` - -During installation, you'll be prompted for: -- **Let's Encrypt Email**: Email for SSL certificate notifications (default: admin@example.com) - -### What the Installation Script Does - -The script performs the following steps: - -1. **System Detection** - - Detects package manager (apt/dnf/yum/pacman) - - Checks for Docker installation - -2. **Install Dependencies** - - Git, curl, wget, unzip - - Build tools (gcc, g++, make) - -3. **Install Runtimes** (if not present) - - Go 1.22.11 → `/usr/local/go` - - Bun → `~/.bun` - -4. **Clone Repository** - - Clones Mist from GitHub → `/opt/mist` - - Uses `main` branch - -5. **Create Docker Network** - - Creates `traefik-net` Docker bridge network - -6. **Configure Traefik** - - Updates `/opt/mist/traefik-static.yml` with your email - - Starts Traefik via Docker Compose - -7. **Build Frontend** - - Runs `bun install` and `bun run build` in `/opt/mist/dash` - - Copies built files to `/opt/mist/server/static/` - -8. **Build Backend** - - Runs `go mod tidy` and `go build` in `/opt/mist/server` - - Creates binary at `/opt/mist/server/mist` - -9. **Create Data Directory** - - Creates `/var/lib/mist/` - - Creates empty database file - - Creates traefik config directory - -10. **Configure Firewall** - - Opens port 8080 (UFW/firewalld/iptables) - -11. **Create Systemd Service** - - Creates `/etc/systemd/system/mist.service` - - Enables and starts service - -::: tip Installation Time -On a 1 vCPU server, installation takes 5-10 minutes due to Go and frontend builds. On 2+ vCPUs, it takes 2-5 minutes. -::: - -### Installation Paths - -After installation, files are located at: - -``` -/opt/mist/ # Main installation -├── server/ -│ ├── mist # Go binary (executable) -│ └── static/ # Frontend build files -├── dash/ # Frontend source (kept) -├── traefik-static.yml # Traefik configuration -├── traefik-compose.yml # Docker Compose file -└── letsencrypt/ # SSL certificates - -/var/lib/mist/ # Data directory -├── mist.db # SQLite database -├── traefik/ # Dynamic configs -│ └── dynamic.yml # Generated at runtime -├── logs/ # Build logs (created at runtime) -├── uploads/ -│ └── avatar/ # User avatars (created at runtime) -└── repos/ # Git clones (temporary) - -/etc/systemd/system/mist.service # Service definition - -/usr/local/go/ # Go installation -~/.bun/ # Bun installation -``` - -## Post-Installation - -### 1. Verify Installation - -Check that Mist is running: - -```bash -# Check service status -sudo systemctl status mist - -# View logs -sudo journalctl -u mist -n 50 -f -``` - -### 2. Access Dashboard - -Navigate to `http://your-server-ip:8080` in your browser. - -::: tip First-Time Setup -On first visit, you'll create the owner account. This account has full system privileges. -::: - -### 3. Create Admin Account - -On the setup page: -1. Enter email address -2. Create a strong password -3. Click "Create Admin Account" -4. You'll be automatically logged in - -### 4. Configure Wildcard Domain (Optional) - -For automatic domain generation: -1. Go to **Settings** → **System** -2. Enter your wildcard domain (e.g., `example.com`) -3. Configure DNS with wildcard A record pointing `*.example.com` to your server -4. New web applications will automatically get domains like `{project}-{app}.example.com` - -[Learn more about wildcard domains →](../guide/domains#wildcard-domain-configuration) - -### 5. Configure GitHub Integration - -For Git-based deployments: -1. Go to **Settings** → **Git** -2. Follow instructions to create a GitHub App -3. Install the app on your repositories - -[Learn more about GitHub setup →](./github-app) - -## Verification - -### Check Components - -Verify all components are running: - -```bash -# Mist service -sudo systemctl status mist - -# Traefik container -docker ps | grep traefik - -# Docker network -docker network ls | grep traefik-net - -# Database file -ls -lh /var/lib/mist/mist.db -``` - -### Test API - -```bash -# Health check (should return system info) -curl http://localhost:8080/api/health -``` - -### Check Ports - -Verify ports are accessible: - -```bash -# Check if ports are listening -sudo netstat -tulpn | grep -E ':(80|443|8080) ' - -# Or with ss -sudo ss -tulpn | grep -E ':(80|443|8080) ' -``` - -## Updating Installation - -To update to the latest version: - -```bash -# Re-run installation script -curl -sSL https://raw.githubusercontent.com/corecollectives/mist/main/install.sh | bash -``` - -::: warning Destructive Update -The installation script performs `git reset --hard origin/main`, which will overwrite any local changes. Always backup your data before updating. -::: - -[Learn more about upgrading →](./upgrading) - -## Uninstallation - -To completely remove Mist: - -```bash -curl -sSL https://raw.githubusercontent.com/corecollectives/mist/main/uninstall.sh | bash -``` - -This will: -- Stop and disable the systemd service -- Remove the service file -- Delete `/opt/mist/` directory -- Delete `/var/lib/mist/mist.db` database -- Remove firewall rules for port 8080 -- Remove Go and Bun PATH entries from `~/.bashrc` - -::: warning Data Preservation -The uninstall script does NOT remove: -- Traefik container (still running) -- Docker network `traefik-net` -- SSL certificates in `/opt/mist/letsencrypt/` -- `/var/lib/mist/traefik/` directory -- Go and Bun installations - -Manually remove these if desired. -::: - -## Troubleshooting - -### Installation Fails - -**Docker not installed:** -``` -Error: Docker is not installed -``` -Install Docker first using the official installation guide. - -**Port already in use:** -``` -Error: Port 8080 is already in use -``` -Check what's using the port: -```bash -sudo lsof -i :8080 -# or -sudo netstat -tulpn | grep :8080 -``` - -**Build fails:** -``` -Error: Go build failed -``` -Check system resources and try again. Build requires significant CPU and RAM. - -### Service Won't Start - -Check logs for errors: - -```bash -sudo journalctl -u mist -n 100 --no-pager -``` - -Common issues: -- Database file permissions -- Port 8080 already in use -- Docker socket not accessible -- Missing dependencies - -### Docker Socket Permission Denied - -If Mist can't access Docker: - -```bash -# Add user to docker group -sudo usermod -aG docker $(whoami) - -# Log out and back in, or: -newgrp docker - -# Restart service -sudo systemctl restart mist -``` - -### Traefik Not Running - -Check Traefik status: - -```bash -docker ps | grep traefik -docker logs traefik -``` - -Restart Traefik: - -```bash -cd /opt/mist -docker compose -f traefik-compose.yml down -docker compose -f traefik-compose.yml up -d -``` - -### Can't Access Dashboard - -1. **Check firewall**: - ```bash - sudo ufw status - sudo ufw allow 8080/tcp - ``` - -2. **Check service**: - ```bash - sudo systemctl status mist - ``` - -3. **Check if port is listening**: - ```bash - curl http://localhost:8080 - ``` - -4. **Check from external**: - ```bash - curl http://YOUR_SERVER_IP:8080 - ``` - -### Database Migration Errors - -If database migrations fail: - -```bash -# Backup database -sudo cp /var/lib/mist/mist.db /var/lib/mist/mist.db.backup - -# Delete and recreate (CAUTION: loses all data) -sudo rm /var/lib/mist/mist.db -sudo touch /var/lib/mist/mist.db -sudo chown $(whoami):$(whoami) /var/lib/mist/mist.db - -# Restart service -sudo systemctl restart mist -``` - -## Advanced Installation - -### Custom Installation Path - -The installation script uses `/opt/mist` by default. To use a custom path, clone and build manually: - -```bash -# Clone to custom location -git clone https://github.com/corecollectives/mist.git /your/custom/path - -# Follow manual build steps -cd /your/custom/path -# ... (frontend and backend build) - -# Update systemd service WorkingDirectory -sudo nano /etc/systemd/system/mist.service -``` - -### Development Installation - -For local development: - -```bash -# Clone repository -git clone https://github.com/corecollectives/mist.git -cd mist - -# Frontend -cd dash -bun install -bun run dev # Runs on port 5173 - -# Backend (separate terminal) -cd server -go mod tidy -go run main.go # Runs on port 8080 -``` - -[Learn more about development setup →](https://github.com/corecollectives/mist#development) - -## Security Recommendations - -After installation: - -1. **Change default firewall rules** - Only allow necessary ports -2. **Set strong password** - Use a password manager -3. **Configure GitHub webhook secret** - Secure webhook endpoint -4. **Regular backups** - Backup `/var/lib/mist/mist.db` -5. **Update regularly** - Keep Mist up to date -6. **Disable Traefik dashboard** - In production, disable port 8081 -7. **Monitor logs** - Watch for suspicious activity - -[Learn more about security →](./security) - -## Next Steps - -- [Configure GitHub Integration](./github-app) -- [Set Up Custom Domains](../guide/domains) -- [Create Your First Application](../guide/applications) -- [Configure Backups](./backup) -- [Review Security Best Practices](./security) diff --git a/www/docs/deployment/requirements.md b/www/docs/deployment/requirements.md deleted file mode 100644 index ee19eaa..0000000 --- a/www/docs/deployment/requirements.md +++ /dev/null @@ -1,192 +0,0 @@ -# System Requirements - -Hardware and software requirements for running Mist. - -## Minimum Requirements - -### Small Deployments (1-5 applications) - -- **CPU**: 1 vCPU -- **RAM**: 1GB minimum, 2GB recommended -- **Disk**: 10GB SSD -- **Network**: 100 Mbps -- **Cost**: ~$5-10/month VPS - -::: tip Build Performance -The build process (compiling Go and bundling frontend) requires significant CPU. During installation, 1 vCPU may take 5-10 minutes to build. -::: - -### Medium Deployments (5-20 applications) - -- **CPU**: 2 vCPU -- **RAM**: 2-4GB -- **Disk**: 20-50GB SSD -- **Network**: 500 Mbps -- **Cost**: ~$12-24/month VPS - -### Large Deployments (20+ applications) - -- **CPU**: 4+ vCPU -- **RAM**: 8GB+ -- **Disk**: 100GB+ SSD -- **Network**: 1 Gbps -- **Cost**: ~$40+/month VPS - -## Software Requirements - -### Operating System - -- Ubuntu 20.04 LTS or later -- Debian 11 or later -- Any Linux distribution with: - - systemd - - Docker support - - Modern kernel (5.x+) - -### Docker - -**Required** - Must be installed before running Mist installation script - -- Docker Engine 20.10 or later -- Docker Compose v2 (for Traefik) -- Docker socket accessible at `/var/run/docker.sock` - -::: warning Install Docker First -The Mist installation script does NOT install Docker. You must install Docker manually before running the script. - -[Install Docker →](https://docs.docker.com/engine/install/) -::: - -### Build Dependencies - -Automatically installed by the installation script: -- Go 1.22.11 -- Bun (JavaScript runtime) -- Build essentials (gcc, g++, make) -- Git, curl, wget, unzip - -### Network - -- **Required Ports**: 80, 443, 8080 must be available -- Port 80: HTTP entry point (Traefik) -- Port 443: HTTPS entry point (Traefik) -- Port 8080: Mist API and Dashboard -- Port 8081: Traefik Dashboard (optional) - -- **Outbound internet access** for: - - GitHub API (api.github.com) - - Docker Hub (hub.docker.com) - - Package downloads (Go, Bun, system packages) - - Let's Encrypt ACME challenges (acme-v02.api.letsencrypt.org) - -## Recommended Cloud Providers - -### DigitalOcean - -- **Droplet**: Basic ($12/month, 2GB RAM) -- Pre-installed Docker images available -- Good for most use cases - -### Hetzner Cloud - -- **CX21**: (€5/month, 2GB RAM) -- Excellent price/performance -- European data centers - -### Linode - -- **Nanode**: ($5/month, 1GB RAM) -- Good for small deployments -- Global data centers - -### Vultr - -- **Regular Performance**: ($6/month, 1GB RAM) -- Multiple locations worldwide - -## Storage Considerations - -### Installation Size - -- **Mist binary**: 8-15MB -- **Frontend assets**: ~5MB -- **Go installation**: ~150MB (if not already installed) -- **Bun installation**: ~50MB (if not already installed) -- **Build dependencies**: ~100MB -- **Total installation**: ~500MB-1GB - -### Database - -- SQLite database grows slowly (~10MB per 1000 deployments) -- Initial database: ~100KB -- Recommend at least 1GB for database growth - -### Git Repositories - -- Cloned during deployment to `/var/lib/mist/repos/{app-id}/` -- Average repo: 50-500MB -- **Temporary** - Cleaned up after successful builds -- Multiple concurrent clones possible - -### Docker Images - -- Images stored by Docker Engine -- Size varies: 100MB - 2GB per image -- Each deployment creates new image tagged with commit hash -- Old images remain until manually pruned -- Recommendation: - - Small deployments: 10-20GB - - Medium deployments: 50-100GB - - Large deployments: 100GB+ - -### Logs - -- Build logs stored in filesystem: `/var/lib/mist/logs/{deployment-id}/build.log` -- Average log file: 1-5MB -- Not automatically cleaned up -- Recommend 5-10GB for logs - -### User Uploads - -- Avatars stored in `/var/lib/mist/uploads/avatar/` -- Maximum size: 5MB per avatar -- Minimal storage impact - -## Performance Benchmarks - -### API Response Time - -- Average: 20-50ms -- p95: < 100ms -- p99: < 200ms - -### Concurrent Deployments - -- Small (1 CPU): 1-2 concurrent -- Medium (2 CPU): 3-5 concurrent -- Large (4+ CPU): 10+ concurrent - -### WebSocket Connections - -- Hundreds of concurrent connections supported -- Minimal resource overhead - -## Scaling Considerations - -
-

🚧 Multi-Node Support Coming Soon

-

Horizontal scaling planned for Phase 4.

-
- -### Current Limitations - -- Single server deployment only -- Vertical scaling (upgrade server) required -- No load balancing across nodes - -### Future Plans - -- Docker Swarm support -- Kubernetes option -- Multi-server deployments -- Shared storage for builds diff --git a/www/docs/deployment/security.md b/www/docs/deployment/security.md deleted file mode 100644 index 77b32ab..0000000 --- a/www/docs/deployment/security.md +++ /dev/null @@ -1,686 +0,0 @@ -# Security Best Practices - -Secure your Mist installation in production. - -## Server Security - -### Firewall Configuration - -Configure firewall to allow only necessary ports: - -```bash -# UFW example (Ubuntu/Debian) -sudo ufw default deny incoming -sudo ufw default allow outgoing - -# Allow SSH (change 22 if using custom port) -sudo ufw allow 22/tcp - -# Allow HTTP and HTTPS (required for web access and SSL challenges) -sudo ufw allow 80/tcp -sudo ufw allow 443/tcp - -# Allow Mist API (if accessing directly, otherwise only localhost) -sudo ufw allow 8080/tcp - -# Optional: Allow Traefik dashboard (restrict to specific IPs in production) -sudo ufw allow 8081/tcp - -# Enable firewall -sudo ufw enable - -# Verify rules -sudo ufw status numbered -``` - -**Production Firewall Best Practices:** - -```bash -# Restrict Mist API to localhost only (recommended if using Traefik) -sudo ufw delete allow 8080/tcp -sudo ufw allow from 127.0.0.1 to any port 8080 - -# Restrict Traefik dashboard to localhost only -sudo ufw delete allow 8081/tcp -sudo ufw allow from 127.0.0.1 to any port 8081 - -# Or allow only from specific admin IP -sudo ufw allow from YOUR_ADMIN_IP to any port 8081 - -# Allow SSH only from specific IP (very secure) -sudo ufw delete allow 22/tcp -sudo ufw allow from YOUR_ADMIN_IP to any port 22 -``` - -### SSH Hardening - -```bash -# Disable root login -sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config - -# Disable password auth (use SSH keys only) -sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config - -# Restart SSH -sudo systemctl restart sshd -``` - -### Keep System Updated - -```bash -# Ubuntu/Debian -sudo apt update && sudo apt upgrade -y - -# Enable automatic security updates -sudo apt install unattended-upgrades -sudo dpkg-reconfigure -plow unattended-upgrades -``` - -## Mist Security - -### Strong Passwords - -Enforce strong password requirements for all users: - -- **Minimum length**: 12 characters (16+ recommended) -- **Complexity**: Mix of uppercase, lowercase, numbers, and symbols -- **No common passwords**: Avoid dictionary words, names, dates -- **Use password manager**: 1Password, Bitwarden, LastPass -- **Unique per account**: Never reuse passwords - -**Owner Account Security:** -- The first user account becomes the Owner with full system access -- Use an extremely strong password for the Owner account -- Consider using a hardware security key (coming soon) - -### JWT Secret - -::: warning Hardcoded JWT Secret -Currently, the JWT secret is **hardcoded** in the application (`server/api/middleware/auth.go:14`). This is a **security risk** for production deployments. - -**Workaround:** Modify the code before deployment: -```bash -cd /opt/mist/server/api/middleware -# Edit auth.go and change line 14 to use a strong random value -# Then rebuild: cd /opt/mist/server && go build -o ../bin/server main.go -``` - -**Upcoming:** Configurable JWT secret via environment variable. -::: - -Generate a strong JWT secret: - -```bash -# Generate random 64-character secret -openssl rand -hex 32 - -# Or use this one-liner -openssl rand -base64 48 | tr -d "=+/" | cut -c1-64 -``` - -### Session Security - -- **Session duration**: 31 days (hardcoded) -- **Sessions** are stored as JWT tokens -- **Token expiry**: Automatically logged out after 31 days -- **No session revocation**: Currently, there's no way to force-logout users (coming soon) - -### GitHub Webhook Secret - -GitHub webhook requests are validated using HMAC-SHA256 signatures. - -**How it works:** -- Webhook secret is automatically generated when creating GitHub App -- Stored securely in Mist database -- All incoming webhook requests are validated before processing -- Invalid signatures are rejected - -Generate a strong webhook secret if creating manually: - -```bash -# Generate webhook secret (only needed for manual setup) -openssl rand -hex 32 -``` - -Configure in: **Settings → Integrations → GitHub App** (automatic during app creation) - -## Docker Security - -### Socket Permissions - -The Mist backend requires access to the Docker socket to manage containers: - -```bash -# Verify Docker socket permissions -ls -la /var/run/docker.sock - -# Should show: srw-rw---- 1 root docker - -# Add your user to docker group (done during installation) -sudo usermod -aG docker $USER - -# Log out and back in for group changes to take effect -``` - -::: danger Security Consideration -Access to the Docker socket = root-level access to the host system. The user running Mist can: -- Create privileged containers -- Mount host filesystem -- Escape container isolation - -**Mitigations:** -- Run Mist as a non-root user (recommended, default in install script) -- Never expose Mist API publicly without authentication -- Use Docker rootless mode (advanced, requires configuration) -- Monitor Docker events for suspicious activity -::: - -### Container Isolation - -Applications deployed by Mist run in Docker containers with: - -- **Network isolation**: Apps on `traefik-net` for controlled routing -- **Resource limits**: (coming soon - CPU/memory limits) -- **Read-only filesystems**: (coming soon) -- **Non-root users**: Depends on Dockerfile used - -**Best Practices for Application Dockerfiles:** - -```dockerfile -# Use specific versions, not :latest -FROM node:20-alpine - -# Run as non-root user -RUN addgroup -g 1001 -S appuser && \ - adduser -S appuser -u 1001 -USER appuser - -# Use multi-stage builds to reduce attack surface -# Copy only necessary files -# Scan images for vulnerabilities -``` - -### Image Security - -- **Official base images**: Use official Docker images (node, python, golang, etc.) -- **Image scanning**: (coming soon - automatic vulnerability scanning) -- **Keep images updated**: Rebuild periodically with latest base images -- **Minimize layers**: Combine RUN commands to reduce image size -- **No secrets in images**: Never `COPY` or embed secrets in Dockerfiles - -**Scan images manually:** - -```bash -# Install Trivy (vulnerability scanner) -sudo apt install wget apt-transport-https gnupg lsb-release -wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add - -echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list -sudo apt update -sudo apt install trivy - -# Scan an image -trivy image your-app-image:latest -``` - -## Network Security - -### Reverse Proxy - -- Always use Traefik as reverse proxy -- Never expose application ports directly -- Configure proper CORS headers - -### SSL/TLS - -Mist provides automatic SSL/TLS certificate provisioning and management. - -**Current Features:** -- ✅ Automatic SSL certificate issuance via Let's Encrypt -- ✅ Automatic certificate renewal (90-day certificates, renewed at 60 days) -- ✅ HTTP to HTTPS redirect enabled by default for domains -- ✅ TLS 1.2+ encryption (configured by Traefik v3.1) -- ✅ Modern cipher suites -- ✅ Perfect Forward Secrecy (PFS) - -**How it Works:** -1. User adds domain to application in Mist UI -2. Mist updates Traefik configuration with domain routing -3. Traefik automatically requests certificate from Let's Encrypt -4. Let's Encrypt verifies domain ownership via HTTP-01 challenge (port 80) -5. Certificate stored in `/opt/mist/letsencrypt/acme.json` -6. Traefik serves traffic over HTTPS with automatic HTTP redirect - -**Certificate Storage:** -```bash -# View certificate file -sudo ls -la /opt/mist/letsencrypt/acme.json - -# Should show: -rw------- (600 permissions) - -# Backup certificates -sudo cp /opt/mist/letsencrypt/acme.json /var/backups/acme_$(date +%Y%m%d).json -``` - -**Verify SSL Configuration:** - -```bash -# Test SSL connection -openssl s_client -connect your-domain.com:443 -servername your-domain.com - -# Check certificate expiry -echo | openssl s_client -servername your-domain.com -connect your-domain.com:443 2>/dev/null | openssl x509 -noout -dates - -# Use SSL Labs for comprehensive analysis -# https://www.ssllabs.com/ssltest/analyze.html?d=your-domain.com -``` - -[Learn more about SSL automation →](../guide/ssl-automation) - -**Coming Soon:** -- Wildcard SSL certificates (`*.example.com`) -- Custom certificate upload -- HSTS headers and security policies -- Certificate expiry notifications -- mTLS (mutual TLS) for service-to-service communication - -## Database Security - -### SQLite File Permissions - -The SQLite database contains ALL Mist data including secrets. Protect it carefully: - -```bash -# Check current permissions -ls -la /var/lib/mist/mist.db - -# Set restrictive permissions (read/write for owner only) -sudo chmod 600 /var/lib/mist/mist.db - -# Ensure owned by the user running Mist (not root!) -sudo chown $USER:$USER /var/lib/mist/mist.db - -# Verify -ls -la /var/lib/mist/mist.db -# Should show: -rw------- 1 youruser youruser -``` - -### Database Encryption - -::: warning Database Not Encrypted -SQLite database is currently stored in **plaintext** on disk. This means: -- Anyone with file access can read the database -- All secrets (API keys, tokens, env vars) are visible -- Backups should be encrypted separately - -**Mitigations:** -- Encrypt the entire disk/volume (LUKS, dm-crypt) -- Encrypt backups before uploading to cloud storage -- Restrict server access to trusted administrators only -- Use encrypted backup destinations (encrypted S3 buckets, etc.) -::: - -**Encrypt backups:** - -```bash -# Using GPG -gpg --symmetric --cipher-algo AES256 /var/backups/mist_backup.db - -# Using OpenSSL -openssl enc -aes-256-cbc -salt -in /var/backups/mist_backup.db -out /var/backups/mist_backup.db.enc - -# Decrypt when needed -openssl enc -d -aes-256-cbc -in /var/backups/mist_backup.db.enc -out /var/backups/mist_backup.db -``` - -### Backup Security - -```bash -# Automated encrypted backup script -#!/bin/bash -DATE=$(date +%Y%m%d_%H%M%S) -BACKUP_DIR="/var/backups/mist" -DB_FILE="/var/lib/mist/mist.db" -ENCRYPTION_KEY="your-encryption-passphrase" # Store securely! - -# Hot backup -sqlite3 $DB_FILE ".backup $BACKUP_DIR/mist_$DATE.db" - -# Encrypt backup -openssl enc -aes-256-cbc -salt -pbkdf2 \ - -in $BACKUP_DIR/mist_$DATE.db \ - -out $BACKUP_DIR/mist_$DATE.db.enc \ - -pass pass:"$ENCRYPTION_KEY" - -# Remove unencrypted backup -rm $BACKUP_DIR/mist_$DATE.db - -# Keep last 30 days -find $BACKUP_DIR -name "mist_*.db.enc" -mtime +30 -delete -``` - -See [Backup & Recovery](./backup) for complete backup procedures. - -## Application Security - -### Environment Variables & Secrets - -Environment variables can contain sensitive data (API keys, database passwords, etc.): - -**Security Best Practices:** - -```bash -# Never commit secrets to Git repositories -# Add .env to .gitignore - -# Never log secrets -# Avoid console.log() or print() statements with env vars - -# Rotate secrets regularly -# Change API keys every 90 days or after team member leaves - -# Use strong random values -openssl rand -hex 32 -``` - -**How Mist Handles Secrets:** - -- Environment variables stored in SQLite database (plaintext) -- Passed to containers at deployment time via Docker `-e` flag -- Also passed as `--build-arg` during image builds -- Visible in `docker inspect` output on the host - -::: warning Secrets Visibility -Environment variables are: -- **Stored in plaintext** in the database -- **Visible to anyone** with access to the Mist database or Docker host -- **Passed to build process** (avoid using secrets during build) - -**Upcoming**: Secret encryption at rest and secret management integration (Vault, AWS Secrets Manager) -::: - -**Minimize Secret Exposure:** - -1. **Don't use secrets in Dockerfile ARG**: They're stored in image layers - ```dockerfile - # BAD - Secret visible in image history - ARG API_KEY - RUN curl -H "Authorization: $API_KEY" https://api.example.com/setup - - # GOOD - Fetch at runtime - CMD node app.js # App reads API_KEY from process.env at runtime - ``` - -2. **Use secret management for databases**: Connect to external secret managers at runtime - -3. **Limit access**: Only give secrets to apps that need them - -### Audit Logging - -Mist tracks important actions in the audit log: - -**What's Logged:** -- User authentication (login/logout) -- Application creation/deletion -- Deployments -- Domain changes -- Environment variable changes -- Project member changes -- System settings changes - -**Access Audit Logs:** -- Navigate to **Settings → Audit Logs** in the UI -- Or query database: `SELECT * FROM audit_logs ORDER BY created_at DESC LIMIT 100` - -**Security Monitoring:** - -```bash -# View recent audit logs via database -sqlite3 /var/lib/mist/mist.db "SELECT user_id, action, resource_type, created_at FROM audit_logs ORDER BY created_at DESC LIMIT 50;" -``` - -**What to Monitor:** -- Failed login attempts (possible brute force) -- Unusual deployment times (after hours activity) -- Unexpected user creations -- Permission changes -- Bulk deletions - -::: tip -Set up alerts for critical actions (coming soon). For now, periodically review audit logs manually. -::: - -## Monitoring & Incident Response - -### Log Monitoring - -Monitor system and application logs for security events: - -```bash -# Watch Mist backend logs in real-time -sudo journalctl -u mist -f - -# Filter for authentication events -sudo journalctl -u mist | grep -i "login\|auth\|failed" - -# Watch Traefik access logs -docker logs -f traefik - -# Monitor all Docker container activity -docker events - -# Check for unauthorized container creation -docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.CreatedAt}}" -``` - -### System Monitoring - -Monitor resource usage for anomalies: - -```bash -# Monitor disk space (database growth, logs, containers) -df -h -du -sh /var/lib/mist/* -docker system df - -# Monitor memory usage -free -h -docker stats --no-stream - -# Monitor CPU usage -top -bn1 | head -20 - -# Check Docker daemon resource usage -ps aux | grep dockerd -``` - -### Security Alerts - -Set up alerts for critical events (manual for now, automated coming soon): - -**Monitor for:** -- Multiple failed login attempts -- Unusual deployment times -- High resource usage (potential crypto mining) -- New user creations -- Permission escalations -- Database file modifications -- Firewall rule changes - -**Simple alerting script example:** - -```bash -#!/bin/bash -# /usr/local/bin/mist-security-alert.sh - -# Check for failed logins in last hour -FAILED_LOGINS=$(sudo journalctl -u mist --since "1 hour ago" | grep -c "authentication failed") - -if [ $FAILED_LOGINS -gt 10 ]; then - echo "WARNING: $FAILED_LOGINS failed login attempts in the last hour" | \ - mail -s "Mist Security Alert" admin@example.com -fi - -# Check database size growth (possible data exfiltration) -DB_SIZE=$(stat -f%z /var/lib/mist/mist.db 2>/dev/null || stat -c%s /var/lib/mist/mist.db) -if [ $DB_SIZE -gt 1073741824 ]; then # 1GB - echo "WARNING: Database size exceeds 1GB" | \ - mail -s "Mist Database Alert" admin@example.com -fi -``` - -### Incident Response - -If you suspect a security incident: - -1. **Isolate**: Stop Mist and Traefik immediately - ```bash - sudo systemctl stop mist - docker compose -f /opt/mist/traefik-compose.yml down - ``` - -2. **Preserve Evidence**: Backup current state before changes - ```bash - sqlite3 /var/lib/mist/mist.db ".backup /tmp/incident_db_$(date +%Y%m%d_%H%M%S).db" - sudo journalctl -u mist > /tmp/incident_logs_$(date +%Y%m%d_%H%M%S).log - docker ps -a > /tmp/incident_containers_$(date +%Y%m%d_%H%M%S).txt - ``` - -3. **Investigate**: Check audit logs, system logs, container logs - -4. **Remediate**: Change passwords, rotate secrets, patch vulnerabilities - -5. **Restore**: From clean backup if compromised - -6. **Report**: If vulnerability in Mist itself, report to maintainers - -## Coming Soon - -The following security features are planned for future releases: - -**Authentication & Authorization:** -- Two-Factor Authentication (TOTP/WebAuthn) -- SSO/SAML integration -- OAuth2 provider support -- API key management with scopes -- Session management (force logout, view active sessions) - -**Secrets Management:** -- Environment variable encryption at rest -- Integration with HashiCorp Vault -- AWS Secrets Manager integration -- Secret rotation policies -- Secret scanning in code repositories - -**Network Security:** -- Rate limiting per IP/user -- IP whitelisting for admin access -- Custom security headers (CSP, HSTS, X-Frame-Options) -- Web Application Firewall (WAF) integration -- DDoS protection configuration - -**Application Security:** -- Automated vulnerability scanning for Docker images -- Security policy enforcement (required base images, etc.) -- Container resource limits (CPU, memory, network) -- Read-only container filesystems -- Seccomp profiles and AppArmor - -**Monitoring & Compliance:** -- Security dashboard and metrics -- Automated security alerts (email, Slack, webhook) -- Compliance reporting (SOC 2, ISO 27001) -- Security audit trail export -- Real-time threat detection - -**Data Protection:** -- Database encryption at rest -- Backup encryption by default -- Automated backup integrity verification -- Point-in-time recovery -- Data retention policies - -## Security Checklist - -Use this checklist to ensure your Mist installation is properly secured: - -### Server Security -- [ ] Firewall configured and enabled (UFW/iptables) -- [ ] Only necessary ports open (22, 80, 443, 8080, 8081) -- [ ] Mist API (8080) and Traefik dashboard (8081) restricted to localhost or specific IPs -- [ ] SSH hardened (key-only auth, no root login) -- [ ] Automatic security updates enabled -- [ ] System packages up to date -- [ ] Disk encryption enabled (optional but recommended for sensitive data) - -### Mist Security -- [ ] Strong passwords enforced for all users (12+ characters) -- [ ] Owner account uses extremely strong password -- [ ] JWT secret changed from hardcoded value (requires code modification) -- [ ] GitHub webhook secret configured and validated -- [ ] Regular security updates applied to Mist - -### Docker Security -- [ ] Mist running as non-root user -- [ ] User in docker group (but aware of security implications) -- [ ] Docker socket permissions restricted (660) -- [ ] Containers use official base images only -- [ ] Images periodically scanned for vulnerabilities -- [ ] Unnecessary containers removed regularly - -### Database Security -- [ ] Database file permissions locked down (600) -- [ ] Database owned by correct user (not root) -- [ ] Automated backups configured -- [ ] Backups stored securely (encrypted and offsite) -- [ ] Backup restoration tested regularly - -### Network Security -- [ ] SSL/TLS enabled for all public domains -- [ ] Certificates automatically renewing -- [ ] HTTP automatically redirects to HTTPS -- [ ] Traefik dashboard access restricted -- [ ] No application ports exposed directly (all through Traefik) - -### Application Security -- [ ] No secrets committed to Git repositories -- [ ] Environment variables contain only necessary data -- [ ] Secrets rotated regularly (90 days) -- [ ] Audit logs reviewed periodically -- [ ] Suspicious activity monitored - -### Monitoring & Response -- [ ] Log monitoring configured -- [ ] Disk space alerts set up -- [ ] Resource usage monitored -- [ ] Incident response plan documented -- [ ] Emergency contacts updated - -### Compliance (if applicable) -- [ ] Data retention policy defined -- [ ] User data handling documented -- [ ] Privacy policy published -- [ ] Terms of service published -- [ ] GDPR/compliance requirements met - -## Reporting Security Issues - -Found a security vulnerability in Mist? - -**Please report responsibly:** - -1. **DO NOT** open a public GitHub issue for security vulnerabilities -2. **DO** report via [GitHub Security Advisories](https://github.com/corecollectives/mist/security/advisories/new) -3. **OR** email: security@corecollectives.com (if available) -4. Include: - - Description of the vulnerability - - Steps to reproduce - - Potential impact - - Suggested fix (if any) - -**We will:** -- Acknowledge receipt within 48 hours -- Provide estimated fix timeline -- Credit you in security advisory (if desired) -- Keep you updated on progress - -Thank you for helping keep Mist secure! diff --git a/www/docs/deployment/traefik.md b/www/docs/deployment/traefik.md deleted file mode 100644 index 4283355..0000000 --- a/www/docs/deployment/traefik.md +++ /dev/null @@ -1,318 +0,0 @@ -# Traefik Setup - -Configure Traefik reverse proxy for Mist. - -## Overview - -Traefik v3.1 is installed automatically with the Mist installation script. It provides: -- Automatic SSL/TLS certificate management via Let's Encrypt -- Reverse proxy for all deployed applications -- HTTP to HTTPS redirection -- Docker label-based routing -- Dynamic configuration updates - -## Installation Location - -Traefik is installed in `/opt/mist/` with the following structure: - -``` -/opt/mist/ -├── traefik-compose.yml # Docker Compose configuration -├── traefik-static.yml # Static Traefik configuration -└── letsencrypt/ - └── acme.json # SSL certificates storage -``` - -## Docker Compose Configuration - -`/opt/mist/traefik-compose.yml`: - -```yaml -services: - traefik: - image: traefik:v3.1 - container_name: traefik - restart: unless-stopped - ports: - - "80:80" # HTTP - - "443:443" # HTTPS - - "8081:8080" # Traefik dashboard - volumes: - - "/var/run/docker.sock:/var/run/docker.sock:ro" - - "./letsencrypt:/letsencrypt" - - "/var/lib/mist/traefik:/etc/traefik/dynamic:ro" - - "./traefik-static.yml:/etc/traefik/traefik.yml:ro" - networks: - - traefik-net - -networks: - traefik-net: - external: true -``` - -## Static Configuration - -`/opt/mist/traefik-static.yml`: - -```yaml -api: - dashboard: true - insecure: true - -providers: - docker: - exposedByDefault: false - network: traefik-net - endpoint: "unix:///var/run/docker.sock" - file: - directory: /etc/traefik/dynamic - watch: true - -entryPoints: - web: - address: ":80" - websecure: - address: ":443" - -certificatesResolvers: - le: - acme: - email: admin@example.com # Set during installation - storage: /letsencrypt/acme.json - httpChallenge: - entryPoint: web - -log: - level: INFO -``` - -## Dynamic Configuration - -Mist automatically generates dynamic Traefik configuration in `/var/lib/mist/traefik/dynamic.yml` based on deployed applications and domains. - -This file is auto-generated and updated when: -- Applications are deployed -- Domains are added or removed -- SSL certificates are issued - -::: warning -Do not manually edit files in `/var/lib/mist/traefik/`. They are auto-generated by Mist. -::: - -## SSL/TLS Configuration - -Mist automatically configures Traefik for SSL/TLS with Let's Encrypt integration. - -### Automatic SSL Setup - -When you add a domain to your application, Mist automatically: -1. Updates dynamic Traefik configuration -2. Adds Docker labels to application containers -3. Traefik requests SSL certificate from Let's Encrypt via HTTP-01 challenge -4. Sets up HTTP to HTTPS redirect -5. Enables automatic certificate renewal (every 60 days) - -### Certificate Resolver - -The Let's Encrypt certificate resolver is configured in `/opt/mist/traefik-static.yml`: - -```yaml -certificatesResolvers: - le: - acme: - email: your-email@example.com # Set during installation - storage: /letsencrypt/acme.json - httpChallenge: - entryPoint: web -``` - -### Certificate Storage - -Certificates are stored in `/opt/mist/letsencrypt/acme.json`. - -```bash -# View certificate file -ls -la /opt/mist/letsencrypt/acme.json - -# Backup certificates -sudo cp /opt/mist/letsencrypt/acme.json /backup/acme.json.$(date +%Y%m%d) -``` - -::: warning Important -The `acme.json` file must have `600` permissions for security: -```bash -sudo chmod 600 /opt/mist/letsencrypt/acme.json -``` -::: - -### How SSL Works in Mist - -1. **Domain Added**: User adds domain to application via Mist UI -2. **Container Deployed**: Mist deploys container with Traefik labels: - ```yaml - traefik.enable=true - traefik.http.routers.{app-id}.rule=Host(`domain.com`) - traefik.http.routers.{app-id}.entrypoints=websecure - traefik.http.routers.{app-id}.tls.certresolver=le - ``` -3. **Certificate Request**: Traefik automatically requests certificate from Let's Encrypt -4. **HTTP Challenge**: Let's Encrypt verifies domain ownership via HTTP-01 challenge -5. **Certificate Issued**: Certificate stored in `acme.json` and served by Traefik -6. **Auto-Renewal**: Traefik automatically renews certificates before expiry - -### Verifying SSL Configuration - -Check Traefik logs for certificate operations: - -```bash -docker logs traefik 2>&1 | grep -i certificate -docker logs traefik 2>&1 | grep -i acme -``` - -Look for messages like: -- `Serving default certificate` -- `Certificate obtained for domain` -- `Renewing certificate` - -Check certificate status in Mist UI: -- Navigate to application **Domains** tab -- Certificate status shows as "Active" when issued - -[Learn more about SSL automation →](../guide/ssl-automation) - -## Dashboard Access - -Traefik dashboard is available at: -``` -http://your-server-ip:8081 -``` - -The dashboard shows: -- Active routers and services -- Middleware configuration -- SSL certificate status -- Real-time metrics - -::: warning Security -The dashboard is configured with `insecure: true` for easy access. In production environments: -- Restrict access via firewall rules -- Use SSH tunneling for remote access -- Or disable the dashboard entirely - -```bash -# Restrict to localhost only (recommended) -sudo ufw deny 8081 -sudo ufw allow from 127.0.0.1 to any port 8081 - -# Access via SSH tunnel -ssh -L 8081:localhost:8081 user@your-server -# Then browse to http://localhost:8081 -``` -::: - -## Network Configuration - -Mist uses the `traefik-net` Docker network for routing: - -```bash -# Verify network exists -docker network inspect traefik-net - -# View connected containers -docker network inspect traefik-net --format='{{range .Containers}}{{.Name}} {{end}}' -``` - -All application containers are automatically connected to `traefik-net` when deployed with domains. - -## Troubleshooting - -### Check Traefik Status - -```bash -# Verify Traefik is running -docker ps | grep traefik - -# Check container health -docker inspect traefik --format='{{.State.Status}}' -``` - -### View Logs - -```bash -# All logs -docker logs traefik - -# Follow logs in real-time -docker logs -f traefik - -# Search for errors -docker logs traefik 2>&1 | grep -i error - -# Certificate-related logs -docker logs traefik 2>&1 | grep -i acme -docker logs traefik 2>&1 | grep -i certificate -``` - -### Verify Configuration - -```bash -# Check Traefik version -docker exec traefik traefik version - -# Verify static configuration -cat /opt/mist/traefik-static.yml - -# Check dynamic configuration -cat /var/lib/mist/traefik/dynamic.yml -``` - -### Common Issues - -**Port conflicts:** -```bash -# Check if ports 80, 443, 8081 are in use -sudo netstat -tulpn | grep -E ':(80|443|8081)' -``` - -**Certificate issues:** -```bash -# Check acme.json permissions -ls -la /opt/mist/letsencrypt/acme.json -# Should be: -rw------- (600) - -# Reset certificates (if needed) -sudo rm /opt/mist/letsencrypt/acme.json -sudo touch /opt/mist/letsencrypt/acme.json -sudo chmod 600 /opt/mist/letsencrypt/acme.json -docker restart traefik -``` - -**Network issues:** -```bash -# Verify traefik-net exists -docker network ls | grep traefik-net - -# Recreate network if needed -docker network create traefik-net -docker restart traefik -``` - -### Restart Traefik - -```bash -cd /opt/mist -docker compose -f traefik-compose.yml restart -``` - -For more details, see [Traefik Documentation](https://doc.traefik.io/traefik/). - -## Coming Soon - -The following Traefik features are planned: - -- **Wildcard SSL Certificates** - Single certificate for `*.domain.com` -- **Custom Certificate Upload** - Use your own SSL certificates -- **Advanced Rate Limiting** - Request throttling per domain -- **IP Whitelisting** - Restrict access by IP address -- **Basic Authentication** - Password-protect applications via Traefik -- **Custom Headers** - Set security headers (HSTS, CSP, etc.) diff --git a/www/docs/deployment/upgrading.md b/www/docs/deployment/upgrading.md deleted file mode 100644 index 5e45c39..0000000 --- a/www/docs/deployment/upgrading.md +++ /dev/null @@ -1,469 +0,0 @@ -# Upgrading Mist - -Keep your Mist installation up to date with the latest features and security patches. - -## Before You Upgrade - -::: danger Always Backup First -**NEVER upgrade without a recent backup.** Database migrations can fail or cause data loss. - -```bash -# Quick backup before upgrading -sudo systemctl stop mist -sqlite3 /var/lib/mist/mist.db ".backup /var/backups/mist_pre_upgrade_$(date +%Y%m%d_%H%M%S).db" -sudo systemctl start mist -``` - -See [Backup & Recovery](./backup) for complete backup procedures. -::: - -### Pre-Upgrade Checklist - -- [ ] Backup database (`/var/lib/mist/mist.db`) -- [ ] Backup SSL certificates (`/opt/mist/letsencrypt/acme.json`) -- [ ] Check [CHANGELOG.md](https://github.com/corecollectives/mist/blob/main/CHANGELOG.md) for breaking changes -- [ ] Note current deployed applications and their status -- [ ] Have rollback plan ready -- [ ] Schedule upgrade during low-traffic window - -## Check Current Version - -Check your current Mist version: - -**Via Dashboard:** -1. Navigate to **Extras → Updates** -2. View current version at the top -3. Click "Check for Updates" to see if updates are available - -**Via API:** -```bash -curl http://localhost:8080/api/updates/version -``` - -**Via CLI:** -```bash -# Check git commit (if available) -cd /opt/mist && git log -1 --oneline - -# Check systemd service status -sudo systemctl status mist -``` - -## Upgrade Methods - -### Method 1: Dashboard One-Click Update (Recommended) - -Mist includes a built-in update system accessible from the dashboard: - -1. Navigate to **Extras → Updates** in the dashboard -2. Click **"Check for Updates"** to see if a new version is available -3. Review the release notes and changes -4. Click **"Update Now"** to trigger the automatic update -5. The system will: - - Download and install the latest version - - Restart the Mist service - - Run database migrations automatically - - Mark the update as complete - -::: tip Auto-Recovery -If an update appears stuck (rare), simply restart the Mist service: -```bash -sudo systemctl restart mist -``` - -The system automatically detects incomplete updates on startup and resolves them based on the installed version. -::: - -::: warning Manual Clearing -Owners can manually clear stuck updates via the dashboard or API if needed: -```bash -curl -X POST http://localhost:8080/api/updates/clear \ - -H "Authorization: Bearer YOUR_TOKEN" -``` -::: - -### Method 2: Re-run Installation Script - -The installation script is idempotent and will update your existing installation: - -```bash -# 1. Backup database -sudo systemctl stop mist -sqlite3 /var/lib/mist/mist.db ".backup /var/backups/mist_backup_$(date +%Y%m%d).db" -sudo systemctl start mist - -# 2. Re-run installation script -curl -fsSL https://raw.githubusercontent.com/corecollectives/mist/main/install.sh | bash - -# 3. Verify upgrade -sudo systemctl status mist -sudo journalctl -u mist -n 50 -``` - -**What it does:** -- Pulls latest code from GitHub (`main` branch) -- Rebuilds Go backend -- Rebuilds Vite frontend -- Restarts Mist service -- Preserves database and all data -- Runs database migrations automatically - -### Method 3: Manual Git Pull and Rebuild - -If you want more control over the upgrade process: - -```bash -# 1. Backup database -sudo systemctl stop mist -sqlite3 /var/lib/mist/mist.db ".backup /var/backups/mist_backup_$(date +%Y%m%d).db" - -# 2. Pull latest code -cd /opt/mist -git fetch origin -git pull origin main - -# 3. Rebuild backend -cd server -go build -o ../bin/server main.go - -# 4. Rebuild frontend -cd ../dash -npm install -npm run build - -# 5. Restart service -sudo systemctl start mist - -# 6. Verify -sudo systemctl status mist -sudo journalctl -u mist -n 50 -``` - -### Method 4: Upgrade to Specific Version - -To upgrade to a specific release or branch: - -```bash -# 1. Backup -sudo systemctl stop mist -sqlite3 /var/lib/mist/mist.db ".backup /var/backups/mist_backup_$(date +%Y%m%d).db" - -# 2. Checkout specific version -cd /opt/mist -git fetch --all --tags -git checkout tags/v1.2.3 # or specific commit hash - -# 3. Rebuild (same as Method 2) -cd server && go build -o ../bin/server main.go -cd ../dash && npm install && npm run build - -# 4. Restart -sudo systemctl start mist -``` - -## Database Migrations - -Mist automatically runs database migrations on startup. The migration system is located in `server/db/migrations/`. - -### How Migrations Work - -1. **On Startup**: Mist checks which migrations have been applied -2. **Auto-Execute**: Runs any pending migrations in order -3. **Track Applied**: Stores migration history in the database -4. **Continue**: Starts normally after migrations complete - -### Monitoring Migrations - -Check migration status in logs: - -```bash -# View recent Mist logs -sudo journalctl -u mist -n 100 - -# Follow logs in real-time during upgrade -sudo journalctl -u mist -f - -# Search for migration-related logs -sudo journalctl -u mist | grep -i migration -sudo journalctl -u mist | grep -i "Running migration" -``` - -Look for messages like: -- `Running migrations...` -- `Migration 001_Create_User.sql completed` -- `All migrations applied successfully` - -### Migration Locations - -Migrations are stored in: -``` -/opt/mist/server/db/migrations/ -├── 001_Create_User.sql -├── 002_Create_Projects.sql -├── 003_Create_Project_members.sql -├── 004_Create_GitProviders.sql -└── ... -``` - -### If Migrations Fail - -If a migration fails during upgrade: - -```bash -# Stop Mist -sudo systemctl stop mist - -# Check logs for error details -sudo journalctl -u mist -n 100 | grep -i error - -# Restore from backup -sudo cp /var/backups/mist_backup_YYYYMMDD.db /var/lib/mist/mist.db - -# Try again or report issue on GitHub -sudo systemctl start mist -``` - -::: warning -Never manually modify the database schema. Always use the built-in migration system or report schema issues on GitHub. -::: - -## Post-Upgrade Verification - -After upgrading, verify everything works correctly: - -### 1. Check Service Status - -```bash -# Verify Mist is running -sudo systemctl status mist - -# Check for errors in recent logs -sudo journalctl -u mist -n 50 -``` - -### 2. Test Web Interface and Version - -```bash -# Test localhost access -curl http://localhost:8080/health - -# Check updated version -curl http://localhost:8080/api/updates/version - -# Or browse to your domain -# https://your-mist-domain.com -``` - -**Via Dashboard:** -- Log in and check the sidebar shows the new version -- Navigate to **Extras → Updates** to verify the update was successful - -### 3. Verify Applications - -- Log in to Mist dashboard -- Check all applications are showing as "Running" -- Test one or two applications to ensure they're accessible -- Check recent deployments in audit logs - -### 4. Check Traefik - -```bash -# Verify Traefik is running -docker ps | grep traefik - -# Check Traefik logs for errors -docker logs traefik 2>&1 | tail -50 -``` - -### 5. Test SSL Certificates - -```bash -# Check certificate status for your domains -curl -I https://your-app-domain.com - -# Verify SSL in browser (no warnings) -``` - -## Rollback Procedure - -If the upgrade causes issues and you need to rollback: - -### Quick Rollback - -```bash -# 1. Stop Mist -sudo systemctl stop mist - -# 2. Restore previous code (if available) -cd /opt/mist -git log --oneline -10 # Find previous commit -git reset --hard - -# 3. Restore database backup -sudo cp /var/backups/mist_backup_YYYYMMDD.db /var/lib/mist/mist.db - -# 4. Rebuild (if code changed) -cd server && go build -o ../bin/server main.go - -# 5. Restart -sudo systemctl start mist - -# 6. Verify -sudo systemctl status mist -``` - -### Full Rollback - -If you need to completely restore to pre-upgrade state: - -```bash -# Stop services -sudo systemctl stop mist -docker compose -f /opt/mist/traefik-compose.yml down - -# Restore database -sudo cp /var/backups/mist_backup_YYYYMMDD.db /var/lib/mist/mist.db - -# Restore certificates (if needed) -sudo cp /var/backups/acme_backup_YYYYMMDD.json /opt/mist/letsencrypt/acme.json - -# Restore code to previous version -cd /opt/mist -git reset --hard - -# Rebuild -cd server && go build -o ../bin/server main.go -cd ../dash && npm install && npm run build - -# Restart services -sudo systemctl start mist -docker compose -f /opt/mist/traefik-compose.yml up -d - -# Verify -sudo systemctl status mist -``` - -::: danger Report Issues -If you need to rollback, please report the issue on [GitHub Issues](https://github.com/corecollectives/mist/issues) with: -- Error logs from `journalctl -u mist` -- What version you upgraded from/to -- Steps that led to the problem -::: - -## Upgrade Best Practices - -### Scheduling Upgrades - -- **Development**: Upgrade anytime -- **Staging**: Upgrade and test thoroughly before production -- **Production**: Schedule during maintenance windows or low-traffic periods - -### Testing Strategy - -1. **Test in Staging First**: If possible, test upgrade on staging server -2. **Read Changelog**: Check for breaking changes and new features -3. **Backup Everything**: Database, certificates, uploads -4. **Gradual Rollout**: Test one application before full deployment -5. **Monitor Closely**: Watch logs and metrics for 24-48 hours after upgrade - -### Stay Updated - -- Watch [GitHub Releases](https://github.com/corecollectives/mist/releases) -- Subscribe to [GitHub Discussions](https://github.com/corecollectives/mist/discussions) -- Check for security updates regularly - -### Recommended Upgrade Frequency - -- **Security patches**: Apply immediately -- **Minor versions**: Monthly or when new features needed -- **Major versions**: Test thoroughly in staging first - -## Troubleshooting Upgrades - -### Common Issues - -**Build fails during upgrade:** -```bash -# Clear build cache and retry -cd /opt/mist/server -go clean -cache -go build -o ../bin/server main.go - -cd /opt/mist/dash -rm -rf node_modules package-lock.json -npm install -npm run build -``` - -**Service won't start after upgrade:** -```bash -# Check detailed logs -sudo journalctl -u mist -n 100 --no-pager - -# Check for port conflicts -sudo netstat -tulpn | grep 8080 - -# Verify file permissions -ls -la /opt/mist/bin/server -``` - -**Database migration stuck:** -```bash -# Check if database is locked -sudo lsof /var/lib/mist/mist.db - -# If locked, stop all processes accessing it -sudo systemctl stop mist -# Wait a few seconds -sudo systemctl start mist -``` - -**Update appears stuck in dashboard:** -```bash -# The system auto-recovers on restart -sudo systemctl restart mist - -# Check logs to verify resolution -sudo journalctl -u mist -n 50 - -# Or manually clear via API -curl -X POST http://localhost:8080/api/updates/clear \ - -H "Authorization: Bearer YOUR_TOKEN" -``` - -See the [Troubleshooting Guide](../troubleshooting/) for more update-related issues. - -**Applications not accessible after upgrade:** -```bash -# Restart Traefik -docker compose -f /opt/mist/traefik-compose.yml restart - -# Check Traefik logs -docker logs traefik 2>&1 | tail -100 - -# Verify dynamic config -cat /var/lib/mist/traefik/dynamic.yml -``` - -## Available Now - -The following upgrade features are currently available: - -- ✅ **One-Click Dashboard Updates** - Update directly from **Extras → Updates** -- ✅ **Version Display** - View current version in sidebar and updates page -- ✅ **Update Status Tracking** - Monitor update progress and history -- ✅ **Automatic Recovery** - System auto-resolves stuck updates on restart -- ✅ **Manual Update Clear** - Owners can manually clear stuck updates -- ✅ **Check for Updates** - View available updates from dashboard -- ✅ **Database Auto-Migrations** - Migrations run automatically on update - -## Coming Soon - -The following upgrade features are planned for future releases: - -- **In-App Update Notifications** - Push notifications when updates are available -- **Automatic Scheduled Updates** - Opt-in automatic updates with configurable schedule -- **Update Channels** - Choose stable, beta, or nightly update channel -- **Pre-Upgrade Health Check** - Automatic system checks before upgrade -- **One-Click Rollback** - Built-in rollback from dashboard -- **Staged Rollouts** - Upgrade one server at a time in multi-server setup diff --git a/www/docs/guide/applications.md b/www/docs/guide/applications.md deleted file mode 100644 index 413f3f6..0000000 --- a/www/docs/guide/applications.md +++ /dev/null @@ -1,720 +0,0 @@ -# Applications - -Applications are the core deployable units in Mist. Each application represents a containerized service that can be a web application, background service, or managed database. - -## Application Types - -Mist supports three distinct application types: - -### Web Applications (`web`) - -Web applications are services exposed via HTTP/HTTPS through Traefik reverse proxy: - -- **Public access** via custom domains -- **Auto-generated domains** (if wildcard DNS configured) -- **SSL certificates** managed automatically -- **Port configuration** (default: 3000) -- **Git-based deployments** from GitHub repositories - -**Use cases**: Websites, web apps, REST APIs, GraphQL servers - -### Service Applications (`service`) - -Background services that run without external HTTP access: - -- **Internal only** - Not exposed to public internet -- **Port 3000** (internal, not routable) -- **Git-based deployments** from GitHub repositories -- **Same deployment flow** as web apps - -**Use cases**: Workers, queue processors, scheduled tasks, internal services - -### Database Applications (`database`) - -Managed database services using pre-configured Docker templates: - -- **Template-based** deployment (PostgreSQL, MySQL, Redis, MongoDB) -- **No Git repository** required -- **Pre-configured** CPU and memory limits from template -- **Version control** via Docker image tags -- **Environment variables** for configuration (passwords, databases, etc.) - -**Use cases**: PostgreSQL, MySQL, Redis, MongoDB, or any other database service - -## Creating an Application - -### Via Dashboard - -1. Navigate to your project -2. Click **"New Application"** -3. Select application type: - - **Web** - For public-facing applications - - **Service** - For background workers - - **Database** - For managed database services -4. Fill in the required fields based on type - -### Web/Service Configuration - -**Initial Creation (Required):** -- **Name**: Unique identifier within project (lowercase, numbers, hyphens only) -- **Description**: Optional application description -- **Port**: Port your app listens on (default: 3000) - -**After Creation (Configure in App Settings):** -- **Git Repository**: Connect GitHub repository -- **Git Branch**: Select branch to deploy from -- **Dockerfile Path**: Path to your Dockerfile (default: `./Dockerfile`) -- **Root Directory**: Root directory for builds (default: `/`) -- **Environment Variables**: Add key-value pairs in Environment tab - -::: tip Build & Start Commands Not Yet Available -Build and start commands are coming soon. Currently, you must provide a Dockerfile for your application. -::: - -### Database Configuration - -- **Name**: Database instance name -- **Description**: Optional description -- **Template**: Select from available templates: - - PostgreSQL - - MySQL - - Redis - - MongoDB -- **Environment Variables**: Database credentials and settings - -::: tip Auto-Generated Domains -For web applications, Mist can automatically generate a subdomain if wildcard DNS is configured in system settings. The format is `{project-name}-{app-name}.{wildcard-domain}`. - -Example: If wildcard domain is `example.com`, project is `production`, and app is `api`, the auto-generated domain will be `production-api.example.com`. - -This only applies to web applications. Service and database apps do not get auto-generated domains. -::: - -## Resource Configuration - -### CPU Limits - -Set CPU core limits for your application: - -- **Default**: No limit (uses available CPU) -- **Range**: 0.1 to N cores (e.g., 0.5, 1.0, 2.0) -- **Database defaults**: Applied automatically from templates - -```javascript -// API example -{ - "appId": 1, - "cpuLimit": 1.0 // 1 CPU core -} -``` - -### Memory Limits - -Set memory limits in megabytes: - -- **Default**: No limit (uses available memory) -- **Range**: 128MB to system maximum -- **Database defaults**: Applied automatically from templates - -```javascript -// API example -{ - "appId": 1, - "memoryLimit": 512 // 512 MB -} -``` - -### Restart Policies - -Control container restart behavior: - -- **`no`**: Never restart automatically -- **`always`**: Always restart if stopped -- **`on-failure`**: Restart only on failure -- **`unless-stopped`**: Restart unless manually stopped (default) - -```javascript -// API example -{ - "appId": 1, - "restartPolicy": "unless-stopped" -} -``` - -## Container Configuration - -### Dockerfile Requirements - -**All web and service applications require a Dockerfile.** Mist builds your application using Docker. - -#### Basic Dockerfile Structure - -Your repository must include a Dockerfile with: -1. **Base image** (FROM statement) -2. **Working directory** (WORKDIR) -3. **Dependency installation** (COPY package files, RUN install commands) -4. **Application code** (COPY source files) -5. **Port exposure** (EXPOSE - optional but recommended) -6. **Start command** (CMD or ENTRYPOINT) - -Example for Node.js: -```dockerfile -FROM node:18-alpine -WORKDIR /app - -# Copy dependency files -COPY package*.json ./ - -# Install dependencies -RUN npm ci --production - -# Copy application code -COPY . . - -# Expose port (should match port in Mist config) -EXPOSE 3000 - -# Start command -CMD ["node", "server.js"] -``` - -Example for Python: -```dockerfile -FROM python:3.11-slim -WORKDIR /app - -# Copy requirements -COPY requirements.txt . - -# Install dependencies -RUN pip install --no-cache-dir -r requirements.txt - -# Copy application -COPY . . - -# Expose port -EXPOSE 8000 - -# Start command -CMD ["python", "app.py"] -``` - -Example for Go: -```dockerfile -FROM golang:1.21-alpine AS builder -WORKDIR /app -COPY go.* ./ -RUN go mod download -COPY . . -RUN go build -o main . - -FROM alpine:latest -WORKDIR /app -COPY --from=builder /app/main . -EXPOSE 8080 -CMD ["./main"] -``` - -::: tip Dockerfile Path -If your Dockerfile is not in the root directory, specify the path in the app settings (e.g., `./docker/Dockerfile` or `./backend/Dockerfile`). -::: - -### Dockerfile Support - -### Dockerfile Support - -Mist supports custom Dockerfiles in your repository: - -1. **Default location**: `./Dockerfile` in repository root -2. **Custom path**: Specify via `dockerfilePath` setting (e.g., `./docker/Dockerfile.prod`) -3. **Root directory**: Set `rootDirectory` for builds in subdirectories (e.g., `/services/api`) - -The build process: -- Uses your specified Dockerfile -- Passes all environment variables as `--build-arg` -- Tags image with commit hash for version tracking -- Stores build logs for debugging - -```dockerfile -# Example multi-service monorepo structure -# Repository structure: -# /services -# /api -# Dockerfile -# ... -# /worker -# Dockerfile -# ... - -# For API service, set: -# Root Directory: /services/api -# Dockerfile Path: ./Dockerfile - -FROM node:18-alpine -WORKDIR /app -COPY package*.json ./ -RUN npm ci --production -COPY . . -EXPOSE 3000 -CMD ["node", "server.js"] -``` - -::: tip Multi-Stage Builds -Use multi-stage Dockerfiles to keep production images small and secure. Copy only necessary artifacts from build stage to runtime stage. -::: - -### Health Checks - -::: warning Coming Soon -Health checks are an upcoming feature. Container health monitoring is not yet implemented. -::: - -Health checks will allow automatic container monitoring: -- HTTP endpoint checks (e.g., `/health`) -- Configurable check intervals and timeouts -- Automatic restart on health check failures -- Status tracking in dashboard - -## Git Integration - -### Connecting a Repository - -For web and service applications: - -1. **Install GitHub App** on your GitHub account/organization -2. **Grant access** to repositories in Mist settings -3. **Select repository** when creating application -4. **Choose branch** to deploy from - -### Configuration Settings - -After creating your application, configure Git integration in the app settings: - -- **Git Repository**: Repository name format `owner/repo` (e.g., `myorg/myapp`) -- **Git Branch**: Branch name to deploy (e.g., `main`, `develop`) -- **Root Directory**: Subdirectory for monorepos (optional, default: `/`) -- **Dockerfile Path**: Path to Dockerfile (optional, default: `./Dockerfile`) - -::: warning Dockerfile Required -Your repository must contain a valid Dockerfile. Build and start commands are not yet supported - all applications are deployed using Docker. -::: - -```javascript -// API example -{ - "appId": 1, - "gitRepository": "myorg/myapp", - "gitBranch": "main", - "rootDirectory": "/", - "dockerfilePath": "./Dockerfile" -} -``` - -## Environment Variables - -Applications can have unlimited environment variables for configuration. See the [Environment Variables guide](./environment-variables) for details. - -### Adding Variables - -1. Go to **Environment Variables** tab -2. Click **"Add Variable"** or use **"Bulk Paste"** -3. Enter key-value pairs -4. Variables are applied on next deployment - -### Build-time & Runtime - -All environment variables are available in both phases: - -- **Build-time**: Passed as `--build-arg` during Docker image build -- **Runtime**: Passed as `-e` flags when container starts -- **Both**: All variables are automatically available in both phases - -Example Dockerfile using build args: -```dockerfile -FROM node:18-alpine - -# Build arg accessible during build -ARG NODE_ENV -ARG API_URL - -WORKDIR /app -COPY package*.json ./ -RUN npm ci --production=$NODE_ENV - -COPY . . - -# Runtime environment variables -ENV NODE_ENV=$NODE_ENV -ENV API_URL=$API_URL - -CMD ["node", "server.js"] -``` - -::: warning Secrets Management -Never commit secrets to Git. Always use environment variables for sensitive data like API keys, passwords, and tokens. -::: - -## Deployment - -### Deployment Process - -When you deploy an application, Mist follows this pipeline: - -**For Web/Service Apps:** -1. **Repository Clone**: Clones your Git repository to `/var/lib/mist/projects/{projectId}/apps/{appName}` -2. **Image Build**: Builds Docker image using your Dockerfile with environment variables as build args -3. **Container Stop**: Gracefully stops existing container (if running) -4. **Container Start**: Starts new container with updated configuration -5. **Domain Routing**: Updates Traefik routes (for web apps with domains) - -**For Database Apps:** -1. **Image Pull**: Pulls the specified Docker image from Docker Hub -2. **Container Stop**: Stops existing container (if running) -3. **Container Start**: Starts new container with template configuration - -### Manual Deployment - -Trigger deployment from dashboard: - -1. Click **"Deploy"** button -2. Latest commit is fetched automatically -3. Deployment added to queue -4. Build starts when worker is available -5. Watch real-time progress and logs - -For databases, deployment uses the configured Docker image version from the template. - -### Automatic Deployment - -With GitHub App configured: - -- **Push events**: Auto-deploy on push to configured branch -- **Webhooks**: GitHub triggers deployment automatically -- **Status updates**: Real-time deployment progress - -[Learn more about deployments →](./deployments) - -## Deployment Strategies - -Mist uses a rolling deployment strategy: - -- **Rolling** (default): Stops old container, then starts new container -- Zero-downtime deployments coming soon - -```javascript -{ - "deploymentStrategy": "rolling" -} -``` - -## Domains - -Add custom domains to web applications: - -1. Go to **Domains** tab -2. Click **"Add Domain"** -3. Enter domain name (e.g., `app.example.com`) -4. Configure DNS A record to point to your server -5. Wait for DNS verification -6. SSL certificate issued automatically via Let's Encrypt - -[Learn more about domains →](./domains) - -## Container Controls - -### Networking - -All containers are connected to the `traefik-net` Docker bridge network for communication: - -**Web Apps with Domains:** -- Connected to `traefik-net` -- Routed through Traefik reverse proxy -- Automatic SSL/TLS via Let's Encrypt -- HTTP to HTTPS redirect enabled -- Accessible via custom domains - -**Web Apps without Domains:** -- Exposed directly on host port (e.g., `-p 3000:3000`) -- Accessible via `http://server-ip:port` -- No SSL by default - -**Service Apps:** -- Connected to `traefik-net` -- No external port exposure -- Accessible by other containers via container name: `app-{appId}` - -**Database Apps:** -- Connected to `traefik-net` -- Internal DNS resolution -- Accessible by other apps via container name: `app-{appId}` -- Example connection: `postgres://user:pass@app-123:5432/dbname` - -::: tip Inter-Container Communication -Applications can communicate with each other using the container name format `app-{appId}` where `{appId}` is the application ID shown in the dashboard. -::: - -### Start/Stop/Restart - -Control container lifecycle from dashboard or API: - -- **Stop**: Gracefully stops container -- **Start**: Starts stopped container -- **Restart**: Restarts running container - -### Application Status - -Container states: - -- **`stopped`**: Container is not running -- **`running`**: Container is active and healthy -- **`error`**: Container failed to start or crashed -- **`building`**: Docker image is being built -- **`deploying`**: Container is being deployed - -## Monitoring - -### Real-time Logs - -View live container logs via WebSocket: - -- **Real-time streaming**: See logs as they're generated -- **Last 100 lines**: Initial connection shows tail -- **Auto-reconnect**: Maintains connection with ping/pong -- **Timestamps**: Each log line includes timestamp - -[View logs tab in dashboard or use WebSocket API](/api/websockets) - -### Deployment History - -Track all deployments: - -- **Deployment number**: Sequential numbering -- **Commit info**: Hash and message (for Git apps) -- **Status**: pending → building → deploying → success/failed -- **Duration**: Build and deployment time -- **Build logs**: Complete build output -- **Active deployment**: Currently running version - -### Container Statistics - -Monitor basic container information: - -- Container name and ID -- Container state (running, stopped, exited) -- Container uptime - -::: tip Coming Soon -Advanced metrics including CPU usage, memory consumption, and network I/O are coming soon. -::: - -## Application Settings - -Update application configuration: - -- **General**: Name, description -- **Git**: Repository URL, branch, paths -- **Resources**: CPU, memory limits -- **Container**: Restart policy -- **Status**: Control running state - -::: tip Audit Logging -All configuration changes are logged in the audit log with user information and timestamps. -::: - -## Rollback - -::: warning Coming Soon -Rollback functionality is an upcoming feature. You cannot currently rollback to previous deployments. -::: - -When available, you'll be able to: -1. View deployment history -2. Select a previous successful deployment -3. Click "Rollback" to redeploy that version -4. Previous Docker images will be reused (no rebuild needed) - -## Service Templates - -Database applications use pre-configured service templates: - -### How Templates Work - -1. **Template Selection**: Choose from available database/service templates -2. **Auto-Configuration**: CPU, memory, port, and environment variables set from template -3. **Docker Image**: Pre-defined image and version from template -4. **One-Click Deploy**: No Dockerfile or Git repository required - -### Template Properties - -Each template defines: -- `dockerImage`: Docker Hub image name -- `dockerImageVersion`: Image tag (e.g., `latest`, `14-alpine`) -- `defaultPort`: Container port -- `recommendedCpu`: Suggested CPU cores -- `recommendedMemory`: Suggested memory in MB -- `defaultEnvVars`: Pre-configured environment variables -- `volumeRequired`: Whether persistent volume is needed - -### Available Templates - -Common templates include: -- **PostgreSQL**: Full-featured relational database -- **MySQL**: Popular open-source database -- **Redis**: In-memory data store and cache -- **MongoDB**: Document-oriented database -- **MariaDB**: MySQL-compatible database - -::: tip Coming Soon -Custom template creation and management by administrators is an upcoming feature. Currently, only pre-defined templates are available. -::: - -## Best Practices - -### Application Structure - -Organize your repository: - -``` -my-app/ -├── src/ # Source code -├── Dockerfile # Production Dockerfile -├── .dockerignore # Exclude unnecessary files -├── package.json # Dependencies -├── .env.example # Document required env vars -└── README.md # Setup instructions -``` - -### Resource Planning - -- **Start small**: Begin with default limits -- **Database memory**: Databases need sufficient RAM -- **CPU limits**: Set realistic limits for consistent performance - -::: tip Coming Soon -Once metrics are available, you'll be able to monitor usage and scale accordingly. -::: - -### Environment Variables - -- Document all required variables in README -- Use descriptive key names (e.g., `DATABASE_URL` not `DB`) -- Separate development and production configs -- Rotate secrets regularly - -### Build Optimization - -Use `.dockerignore` to exclude files: - -``` -node_modules -.git -.env -*.log -*.md -.vscode -.idea -``` - -Use multi-stage builds: - -```dockerfile -# Build stage -FROM node:18-alpine AS builder -WORKDIR /app -COPY package*.json ./ -RUN npm ci -COPY . . -RUN npm run build - -# Production stage -FROM node:18-alpine -WORKDIR /app -COPY --from=builder /app/dist ./dist -COPY --from=builder /app/node_modules ./node_modules -CMD ["node", "dist/server.js"] -``` - -### Health Check Implementation - -Add health check endpoint to your application: - -```javascript -// Express.js example -app.get('/health', (req, res) => { - // Check database connection - // Check external dependencies - res.status(200).json({ - status: 'healthy', - timestamp: new Date().toISOString() - }); -}); -``` - -```python -# Flask example -@app.route('/health') -def health(): - return {'status': 'healthy'}, 200 -``` - -## Troubleshooting - -### Build Failures - -Check deployment logs for errors: - -- **Missing dependencies**: Check your package manager files (package.json, requirements.txt, etc.) -- **Dockerfile errors**: Verify Dockerfile syntax and commands -- **Build args missing**: Ensure required environment variables are set -- **Out of disk space**: Clean up old Docker images with `docker system prune` -- **Permission denied**: Check file permissions and COPY commands in Dockerfile -- **Git clone failed**: Verify GitHub App installation and repository access - -### Container Won't Start - -Common issues: - -- **Dockerfile CMD missing**: Container needs a command to run -- **Port mismatch**: Dockerfile EXPOSE port should match app configuration -- **Missing env vars**: Required environment variables not set -- **Application crashes**: Check container logs for runtime errors -- **Resource limits**: Container may be OOM killed if memory limit too low - -### Application Not Accessible - -Checklist: - -- ✅ Container status is `running` (green indicator) -- ✅ Domain has A record pointing to server -- ✅ DNS has propagated (check with `dig` or `nslookup`) -- ✅ Firewall allows ports 80/443 -- ✅ Application is listening on correct port -- ✅ No errors in container logs - -### Performance Issues - -Investigate: - -- Check CPU/memory usage in metrics -- Review container logs for errors -- Increase resource limits if needed -- Check database query performance -- Review application profiling data - -## API Reference - -See the [Applications API documentation](/api/applications) for programmatic access to: - -- Create applications -- Update configuration -- Control containers -- Get status and logs -- Manage resources - -## Related Topics - -- [Deployments](./deployments) - Deploy your applications -- [Environment Variables](./environment-variables) - Configure applications -- [Domains](./domains) - Add custom domains -- [Git Integration](./git-integration) - Connect GitHub repositories -- [Logs](./logs) - Monitor application logs diff --git a/www/docs/guide/architecture.md b/www/docs/guide/architecture.md deleted file mode 100644 index 161a2ad..0000000 --- a/www/docs/guide/architecture.md +++ /dev/null @@ -1,337 +0,0 @@ -# Architecture - -Mist is designed as a lightweight, monolithic application with a focus on simplicity and resource efficiency. - -## System Design - -### High-Level Architecture - -``` -Internet Traffic - ↓ - [Traefik Proxy] ← SSL/TLS, Domain Routing - ↓ - [App Containers] ← Your deployed applications - ↑ - [Mist Backend] ← Go API Server - ↑ - [SQLite DB] ← Application state - ↑ - [Frontend SPA] ← React dashboard -``` - -## Core Components - -### 1. Backend API Server (Go) - -**Location**: `/server` - -The backend is a single Go binary that handles: - -- **REST API** - HTTP endpoints for CRUD operations -- **WebSocket Server** - Real-time updates for logs and metrics -- **Authentication** - JWT-based auth with HTTP-only cookies -- **Deployment Queue** - In-memory queue for build jobs -- **Deployment Workers** - Goroutines that process deployments -- **Docker Integration** - Direct socket communication -- **GitHub Webhooks** - Auto-deploy on push events - -**Key Features:** -- Single compiled binary -- No external process managers needed -- Embedded migrations -- Graceful shutdown handling - -### 2. Frontend (React + Vite) - -**Location**: `/dash` - -Modern single-page application providing: - -- Dashboard with real-time updates -- Application management interface -- Deployment monitoring -- Log viewer with WebSocket streaming -- System metrics visualization - -**Tech Stack:** -- React 18 -- Vite for build tooling -- Tailwind CSS for styling -- Shadcn/ui components - -### 3. Database (SQLite) - -**Location**: `/var/lib/mist/mist.db` - -Embedded file-based database storing: - -- Users and sessions -- Projects and members -- Applications -- Deployments -- Environment variables -- Domains -- Audit logs -- System settings - -**Benefits:** -- No separate database server -- Automatic backups (just copy the file) -- ACID transactions -- Zero configuration - -### 4. Docker Engine - -Mist communicates with Docker via the socket (`/var/run/docker.sock`) to: - -- Build images from Dockerfiles -- Create and manage containers -- Stream container logs -- Monitor container status -- Configure networks - -### 5. Reverse Proxy (Traefik) - -**Location**: `docker-compose.yml` - -Traefik handles: - -- HTTP/HTTPS traffic routing -- Domain-based routing to containers -- SSL/TLS termination -- Load balancing (future) - -**Configuration:** -- Dynamic configuration via Docker labels -- File-based static configuration -- Automatic service discovery - -## Deployment Workflow - -### 1. User Triggers Deployment - -```mermaid -User → Frontend → API → Deployment Queue -``` - -### 2. Queue Processing - -```go -// Simplified deployment worker -func processDeployment(job DeploymentJob) { - // 1. Clone Git repository - cloneRepo(job.RepoURL, job.Branch) - - // 2. Build Docker image - buildImage(job.Dockerfile, job.BuildArgs) - - // 3. Stop old container (if exists) - stopContainer(job.AppID) - - // 4. Start new container - startContainer(job.Image, job.EnvVars, job.Port) - - // 5. Update Traefik routes - updateProxy(job.Domain, job.ContainerName) - - // 6. Update database - markDeploymentComplete(job.ID) -} -``` - -### 3. Real-time Updates - -WebSocket connections stream: -- Build logs during image creation -- Container logs after deployment -- System metrics every second -- Mist backend logs via journalctl integration - -## Data Flow - -### REST API Request - -``` -Frontend → API Endpoint → Middleware (Auth) → Handler → Database → Response -``` - -### WebSocket Connection - -``` -Frontend → WebSocket Upgrade → Auth Check → Stream Data → Client -``` - -### Deployment Flow - -``` -1. Git Push -2. GitHub Webhook → Mist API -3. Create Deployment Record -4. Add to Queue -5. Worker Picks Up Job -6. Clone Repo -7. Build Docker Image (stream logs via WebSocket) -8. Start Container -9. Update Traefik Config -10. Mark Deployment Complete -11. Notify Frontend via WebSocket -``` - -## Security Architecture - -### Authentication - -- JWT tokens stored in HTTP-only cookies -- Refresh token rotation -- Session management -- Password hashing with bcrypt - -### Authorization - -- Role-based access control (admin, user) -- Project-level permissions -- Owner-only operations - -### API Security - -- Rate limiting (planned) -- CORS configuration -- Input validation -- SQL injection prevention (parameterized queries) -- XSS protection - -## Monitoring & Observability - -### Logging Architecture - -**Container Logs:** -- Streamed from Docker via socket connection -- Real-time delivery via WebSocket to frontend -- Last 100 lines buffered on connection - -**System Logs:** -- Mist backend logs collected via systemd journal -- Accessed through `journalctl` integration -- Live streaming to `/logs` page -- Includes all Go backend output (API, deployments, errors) - -**Build Logs:** -- Written to filesystem during Docker builds -- Path: `/var/lib/mist/logs/.log` -- Accessible through deployment details - -### Metrics Collection - -**System Metrics:** -- CPU usage (percentage) -- Memory usage (used/total) -- Disk usage (used/total) -- Updated every second via WebSocket - -**Container Metrics:** -- Container state (running/stopped/error) -- Container uptime -- Basic container information - -::: tip -Advanced per-container metrics (CPU, memory, network I/O) are planned for future releases. -::: - -## Scalability Considerations - -### Current Design (Single Server) - -✅ **Strengths:** -- Simple deployment -- No complex networking -- Easy to debug -- Low resource usage - -⚠️ **Limitations:** -- Single point of failure -- Limited to one server's resources -- No horizontal scaling - -### Future Improvements - -🚧 **Planned:** -- Multi-node support with Docker Swarm -- Database replication -- Load balancing -- Shared storage for builds - -## File System Layout - -``` -/var/lib/mist/ -├── mist.db # SQLite database -├── repos/ # Cloned Git repositories -│ └── / -│ └── / -├── builds/ # Build artifacts -│ └── / -└── logs/ # Build logs - └── .log - -/etc/mist/ -├── config.yml # Mist configuration -└── traefik/ # Traefik configs - ├── traefik.yml - └── dynamic/ - -/usr/local/bin/ -└── mist # Mist binary -``` - -## Performance Characteristics - -### Resource Usage - -**Idle State:** -- CPU: < 1% -- RAM: ~50-100MB -- Disk: ~100MB - -**Under Load (10 concurrent deployments):** -- CPU: 10-30% -- RAM: ~200-500MB -- Disk: Depends on app sizes - -### Benchmarks - -- API Response Time: < 50ms (p95) -- WebSocket Latency: < 10ms -- Concurrent Users: 100+ -- Apps per Instance: 1000+ - -## Technology Choices - -### Why Go? - -- Fast compilation and execution -- Excellent concurrency (goroutines) -- Single binary deployment -- Strong standard library -- Great Docker SDK - -### Why SQLite? - -- Zero configuration -- Embedded database -- ACID compliance -- Perfect for single-server deployments -- Easy backups (copy file) - -### Why Traefik? - -- Dynamic configuration -- Docker integration -- Automatic service discovery -- Let's Encrypt support -- Modern and actively maintained - -## Learn More - -- [Deployment Process](./deployments) -- [Traefik Configuration](/deployment/traefik) diff --git a/www/docs/guide/audit-logs.md b/www/docs/guide/audit-logs.md deleted file mode 100644 index ba9590e..0000000 --- a/www/docs/guide/audit-logs.md +++ /dev/null @@ -1,74 +0,0 @@ -# Audit Logs - -Track all user actions in your Mist instance. - -## Overview - -Audit logs record: -- User authentication events -- Application deployments -- Configuration changes -- User management actions -- Project modifications - -## Viewing Audit Logs - -
-

🚧 Audit Log UI Coming Soon

-

Audit logs are currently stored in the database but UI for viewing is under development.

-
- -## What's Logged - -### Authentication -- User login attempts -- Session creation -- Logout events - -### Applications -- Application creation -- Application updates -- Application deletion -- Deployment triggers - -### Environment Variables -- Variable creation -- Variable updates -- Variable deletion - -### Projects -- Project creation -- Member addition/removal -- Project settings changes - -### Domains -- Domain addition -- Domain removal - -### Users (Admin) -- User creation -- Role changes -- User deletion - -## Log Structure - -Each audit log entry includes: -- **Timestamp** - When action occurred -- **User** - Who performed the action -- **Action** - What was done -- **Resource** - What was affected -- **Details** - Additional context -- **IP Address** - Source IP - -## Coming Soon - -
-

🚧 Audit Log Features

-
- -- **Audit Log Viewer UI** - Browse logs in dashboard -- **Search & Filter** - Find specific events -- **Export Logs** - Download as CSV/JSON -- **Retention Policies** - Configure log retention -- **Compliance Reports** - Generate audit reports -- **Real-time Alerts** - Notify on suspicious activity diff --git a/www/docs/guide/authentication.md b/www/docs/guide/authentication.md deleted file mode 100644 index d743b0f..0000000 --- a/www/docs/guide/authentication.md +++ /dev/null @@ -1,198 +0,0 @@ -# Authentication & Users - -Manage users and authentication in your Mist instance. - -## User Roles - -Mist implements a hierarchical role-based access control (RBAC) system with three distinct roles: - -### Owner - -The highest privilege level in Mist with complete system control. - -**Characteristics:** -- **Unique**: Only ONE owner can exist in the system -- **Created**: Automatically assigned during first-time setup -- **Cannot be duplicated**: No API or UI allows creating additional owners - -**Permissions:** -- ✅ Full system access to all features -- ✅ View and update system settings (wildcard domain, etc.) -- ✅ Create and delete projects -- ✅ Create users (admin and user roles only) -- ✅ Delete any user including admins -- ✅ View all audit logs -- ✅ Access all projects and applications -- ✅ Manage Traefik configuration - -**Special Considerations:** -- Owner can delete themselves, which resets the system to setup mode -- If the owner is deleted, a new owner can be created via signup - -### Admin - -High-level administrative privileges, second to owner. - -**Permissions:** -- ✅ Create and manage projects -- ✅ Create users (admin and user roles only) -- ✅ Delete users (except owners and other admins) -- ✅ View all audit logs -- ✅ Access assigned projects as member -- ✅ Manage applications in assigned projects -- ❌ Cannot view or update system settings -- ❌ Cannot delete owners -- ❌ Cannot delete other admins -- ❌ Cannot create owner accounts - -### User - -Standard user role with limited permissions. - -**Permissions:** -- ✅ Access assigned projects as member -- ✅ Deploy applications in assigned projects -- ✅ View logs and metrics for assigned projects -- ✅ Manage application settings in assigned projects -- ✅ View own profile -- ❌ Cannot create projects -- ❌ Cannot create users -- ❌ Cannot view system settings -- ❌ Cannot view audit logs - -## Authentication - -### Login - -Access Mist at `http://your-server-ip:8080`: - -1. Enter email and password -2. Click **"Sign In"** -3. JWT token stored in HTTP-only cookie - -### Session Management - -- Sessions expire after 31 days -- Tokens stored in secure HTTP-only cookies -- Role embedded in JWT for fast authorization -- Role verified against database on each request - -### First-Time Setup - -On first access, create the owner account: - -1. Navigate to `http://your-server-ip:8080` -2. You'll see the setup page -3. Enter email and password -4. Click **"Create Admin Account"** -5. You'll be automatically logged in as **owner** - -::: tip -The first user is always assigned the owner role. After the first user is created, the signup page is disabled. -::: - -## User Management - -### Creating Users - -**Who can create users**: Owner and Admin roles only - -1. Go to **Settings** → **Users** -2. Click **"Add User"** or **"New User"** -3. Enter user details: - - Username - - Email - - Password -4. Select role: - - **Admin**: Full administrative privileges (cannot create owners) - - **User**: Standard user access -5. Click **"Create"** - -::: warning Cannot Create Owners -The owner role cannot be assigned when creating users. Only one owner exists per Mist instance. -::: - -### Updating Users - -**Who can update users**: Owner and Admin - -Edit user details: -- Update username -- Update email -- Reset password -- Change role (owner/admin only) - -All user updates are logged in the audit log. - -### Deleting Users - -**Who can delete users**: -- **Owner**: Can delete any user including admins -- **Admin**: Can only delete users (not owners or other admins) -- **User**: Cannot delete any users - -To delete a user: -1. Navigate to **Settings** → **Users** -2. Click delete icon next to the user -3. Confirm deletion - -::: warning -- Admins cannot delete owners or other admins -- Deleting a user removes their access but preserves projects and applications they created -- If the owner deletes themselves, the system resets to setup mode -::: - -## Role Hierarchy - -The role hierarchy is strictly enforced: - -``` -Owner (highest) - ↓ -Admin - ↓ -User (lowest) -``` - -**Deletion Rules:** -- Owner can delete: Admin, User -- Admin can delete: User only -- User cannot delete anyone - -## Security Features - -### Password Security - -- Minimum 8 characters required -- Hashed with bcrypt algorithm -- Salted for additional security -- Never stored in plain text - -### JWT Tokens - -- Signed with HS256 algorithm -- Includes user ID, email, and role -- 31-day expiration -- Stored in HTTP-only cookies (prevents XSS attacks) - -### Session Security - -- HTTP-only cookies prevent JavaScript access -- Secure flag enabled in production (HTTPS) -- Role verified on every API request -- Invalid tokens result in automatic logout - -## Coming Soon - -
-

🚧 Authentication Enhancements

-
- -- **Password Reset** - Email-based password recovery -- **Email Verification** - Verify email addresses -- **Two-Factor Authentication** - TOTP/Authenticator app support -- **SSO Integration** - OAuth2, SAML support -- **API Tokens** - Generate tokens for CLI/API access -- **Session Management UI** - View and revoke active sessions -- **User Invitations** - Invite users via email -- **Fine-grained Permissions** - Custom permission sets diff --git a/www/docs/guide/cli.md b/www/docs/guide/cli.md deleted file mode 100644 index f83ce02..0000000 --- a/www/docs/guide/cli.md +++ /dev/null @@ -1,260 +0,0 @@ -# CLI Tool - -Command-line interface for managing Mist users and system settings. - -The Mist CLI (`mist-cli`) is a powerful command-line tool that allows administrators to manage their Mist installation directly from the terminal. It's automatically installed when you install Mist using the standard installation script. - -## Installation - -The CLI tool is automatically installed during Mist installation and is available at `/usr/local/bin/mist-cli`. - -To verify installation: - -```bash -mist-cli version -``` - -## Available Commands - -## Available Commands - -The CLI supports the following main commands: - -- `user` - Manage users -- `settings` - Manage system settings -- `version` - Show CLI version -- `help` - Show help message - -Use `mist-cli --help` for more information about each command. - ---- - -## User Management - -Manage user accounts including password changes and listing users. - -### Change User Password - -Change a user's password with optional interactive or non-interactive mode. - -**Interactive mode (recommended):** -```bash -mist-cli user change-password --username admin -``` - -This will prompt you to enter and confirm the new password securely. - -**Non-interactive mode:** -```bash -mist-cli user change-password --username admin --password newpass123 -``` - -**Examples:** -```bash -# Change admin password (interactive) -mist-cli user change-password --username admin - -# Change user password directly -mist-cli user change-password --username john --password SecurePass123 -``` - -### List Users - -Display all users in the system with their details. - -```bash -mist-cli user list -``` - -**Output:** -``` -Users: ----------------------------------------------- -ID Username Email Role ----------------------------------------------- -1 admin admin@example.com owner -2 developer dev@example.com member ----------------------------------------------- -Total: 2 users -``` - ---- - -## System Settings Management - -Manage system-wide settings that control Mist behavior. - -### List All Settings - -View all current system settings: - -```bash -mist-cli settings list -``` - -**Output:** -``` -System Settings: ----------------------------------------------- -Setting Value ----------------------------------------------- -wildcard_domain example.com -mist_app_name mist -production_mode true -secure_cookies true -auto_cleanup_containers false -auto_cleanup_images false ----------------------------------------------- -``` - -### Get Specific Setting - -Retrieve the value of a specific setting: - -```bash -mist-cli settings get --key wildcard_domain -``` - -**Available setting keys:** -- `wildcard_domain` - Wildcard domain for auto-generated app domains -- `mist_app_name` - Subdomain name for Mist dashboard -- `production_mode` - Enable production mode (true/false) -- `secure_cookies` - Enable secure cookies for HTTPS (true/false) -- `auto_cleanup_containers` - Auto cleanup stopped containers (true/false) -- `auto_cleanup_images` - Auto cleanup dangling images (true/false) - -### Set Setting Value - -Update a system setting: - -```bash -mist-cli settings set --key --value -``` - -**Examples:** - -```bash -# Set wildcard domain -mist-cli settings set --key wildcard_domain --value apps.example.com - -# Enable production mode -mist-cli settings set --key production_mode --value true - -# Enable secure cookies -mist-cli settings set --key secure_cookies --value true - -# Enable auto cleanup -mist-cli settings set --key auto_cleanup_containers --value true -mist-cli settings set --key auto_cleanup_images --value true - -# Change Mist dashboard subdomain -mist-cli settings set --key mist_app_name --value dashboard -``` - ---- - -## Common Use Cases - -### Initial Setup - -After installing Mist, set up your wildcard domain: - -```bash -# Configure wildcard domain -mist-cli settings set --key wildcard_domain --value apps.example.com - -# Set Mist dashboard subdomain -mist-cli settings set --key mist_app_name --value mist - -# Enable production mode -mist-cli settings set --key production_mode --value true -``` - -### Password Recovery - -If you've forgotten the admin password: - -```bash -# Reset admin password -sudo mist-cli user change-password --username admin -``` - -### Enable Auto Cleanup - -To automatically clean up Docker resources: - -```bash -# Enable container cleanup -mist-cli settings set --key auto_cleanup_containers --value true - -# Enable image cleanup -mist-cli settings set --key auto_cleanup_images --value true -``` - -### Check Current Configuration - -View all settings and users: - -```bash -# List all settings -mist-cli settings list - -# List all users -mist-cli user list -``` - ---- - -## Permissions - -The CLI requires direct access to the Mist database at `/var/lib/mist/mist.db`. You may need to run commands with `sudo`: - -```bash -sudo mist-cli user change-password --username admin -``` - ---- - -## Troubleshooting - -### Database Not Found - -**Error:** -``` -Error: database file not found at /var/lib/mist/mist.db. Please ensure Mist is installed and running -``` - -**Solution:** Ensure Mist is properly installed and the service is running: -```bash -sudo systemctl status mist -``` - -### Permission Denied - -**Error:** Permission issues when accessing the database - -**Solution:** Run the command with sudo: -```bash -sudo mist-cli settings list -``` - -### Unknown Setting Key - -**Error:** -``` -Error: Unknown setting key 'invalid_key' -``` - -**Solution:** Use `mist-cli settings --help` to see available setting keys. - ---- - -## Help & Support - -For more information on any command, use the `--help` flag: - -```bash -mist-cli --help -mist-cli user --help -mist-cli settings --help -``` diff --git a/www/docs/guide/databases.md b/www/docs/guide/databases.md deleted file mode 100644 index 71c11f2..0000000 --- a/www/docs/guide/databases.md +++ /dev/null @@ -1,232 +0,0 @@ -# Database Services - -One-click database provisioning for your applications. - -Mist provides managed database services through pre-configured Docker templates, allowing you to quickly deploy databases without manual configuration. - -## Available Databases - -### PostgreSQL -- Latest PostgreSQL version -- Pre-configured with recommended settings -- Automatic environment variable setup -- Internal network access via `app-{appId}` hostname -- Template-driven CPU and memory limits - -### MySQL -- Latest MySQL version -- Optimized configuration -- User and password management via environment variables -- Internal network connectivity - -### MariaDB -- MySQL-compatible database -- Drop-in replacement for MySQL -- Same connection interface - -### Redis -- In-memory data store and cache -- Latest Redis version -- Password protection via environment variables -- Pub/sub and caching support - -### MongoDB -- Document-oriented database -- Latest MongoDB version -- User authentication support -- Internal DNS resolution - -## Creating a Database - -1. Navigate to your project -2. Click **"New Application"** -3. Select **"Database"** type -4. Choose your database template: - - PostgreSQL - - MySQL - - MariaDB - - Redis - - MongoDB -5. Enter instance name and description -6. Configure environment variables (passwords, database names) -7. Click **"Create"** - -The database will be provisioned automatically with: -- Pre-configured port from template -- Recommended CPU and memory limits -- Default environment variables -- Connected to `traefik-net` network - -## Connecting to Databases - -### From Your Applications - -Databases are accessible via internal hostname using the format `app-{appId}`: - -**Example Connection Strings:** - -```bash -# PostgreSQL -DATABASE_URL=postgresql://user:password@app-123:5432/myapp - -# MySQL -DATABASE_URL=mysql://root:password@app-124:3306/myapp - -# Redis -REDIS_URL=redis://:password@app-125:6379 - -# MongoDB -MONGODB_URI=mongodb://admin:password@app-126:27017/myapp -``` - -Replace `app-{appId}` with your actual database application ID shown in the dashboard. - -### Configuration via Environment Variables - -Add connection details to your web/service application's environment variables: - -1. Go to your application's **Environment** tab -2. Add database connection variables -3. Use the database's container name (`app-{appId}`) -4. Deploy your application - -## Database Management - -### Environment Variables - -Configure your database through environment variables: - -**PostgreSQL:** -``` -POSTGRES_USER=myuser -POSTGRES_PASSWORD=mypassword -POSTGRES_DB=mydatabase -``` - -**MySQL:** -``` -MYSQL_ROOT_PASSWORD=rootpassword -MYSQL_DATABASE=mydatabase -MYSQL_USER=myuser -MYSQL_PASSWORD=mypassword -``` - -**MongoDB:** -``` -MONGO_INITDB_ROOT_USERNAME=admin -MONGO_INITDB_ROOT_PASSWORD=password -``` - -**Redis:** -``` -REDIS_PASSWORD=yourpassword -``` - -### Resource Limits - -Template-based defaults are applied: -- **CPU**: 1.0 cores (adjustable) -- **Memory**: 512MB (adjustable) -- **Restart Policy**: unless-stopped - -You can modify these in the application settings. - -### Container Management - -- **Start/Stop**: Control database lifecycle from dashboard -- **Restart**: Restart database containers -- **Logs**: View database logs in real-time -- **Status**: Monitor container state and uptime - -## Networking - -All databases are connected to the `traefik-net` network: -- Internal DNS resolution -- Accessible by container name (`app-{appId}`) -- Isolated from public internet -- Secure inter-container communication - -## Best Practices - -### Security - -- **Strong Passwords**: Use complex passwords for database users -- **Environment Variables**: Never hardcode credentials -- **Least Privilege**: Create database users with minimal required permissions -- **Network Isolation**: Databases are not exposed externally by default - -### Performance - -- **Resource Allocation**: Monitor usage and adjust CPU/memory limits -- **Connection Pooling**: Use connection pools in your applications -- **Indexing**: Create appropriate indexes for query performance -- **Monitoring**: Check logs regularly for errors or warnings - -### Backup - -::: warning Manual Backups Required -Automatic backup scheduling is not yet available. Manually backup your databases regularly using database-specific tools. -::: - -**Backup Methods:** - -**PostgreSQL:** -```bash -docker exec app-{appId} pg_dump -U user dbname > backup.sql -``` - -**MySQL:** -```bash -docker exec app-{appId} mysqldump -u root -p dbname > backup.sql -``` - -**MongoDB:** -```bash -docker exec app-{appId} mongodump --out /backup -``` - -## Coming Soon - -
-

🚧 Upcoming Features

-
- -- **External Access** - Public database access with security controls -- **Management UIs** - Built-in admin interfaces (pgAdmin, phpMyAdmin, Mongo Express, Redis Commander) -- **Automated Backups** - Scheduled backup and restore -- **Connection Pooling** - Optimize database connections -- **Replication** - High availability setups -- **Multiple Versions** - Choose specific database versions -- **Volume Management** - Persistent volume configuration -- **Database Cloning** - Duplicate databases for staging/testing -- **Performance Metrics** - Database-specific monitoring -- **Auto-Configuration** - Automatic environment variable injection to apps - -## Troubleshooting - -### Connection Refused - -- Verify database container is running -- Check container logs for errors -- Ensure correct hostname format (`app-{appId}`) -- Verify port matches database default - -### Authentication Failed - -- Check environment variables are set correctly -- Verify username and password -- Ensure database user has been created -- Check database logs for auth errors - -### Application Can't Connect - -- Verify both containers are on `traefik-net` network -- Check firewall rules aren't blocking internal traffic -- Test connection from application container logs -- Verify DNS resolution of container name - -## Related Documentation - -- [Applications](./applications) - Application types and management -- [Environment Variables](./environment-variables) - Managing configuration -- [Service Templates](./applications#service-templates) - How templates work diff --git a/www/docs/guide/deployments.md b/www/docs/guide/deployments.md deleted file mode 100644 index 63af2b3..0000000 --- a/www/docs/guide/deployments.md +++ /dev/null @@ -1,118 +0,0 @@ -# Deployments - -Learn how to deploy and manage your applications. - -## Deployment Process - -When you trigger a deployment, Mist: - -1. **Clones** your Git repository (for web/service apps) -2. **Builds** Docker image using your Dockerfile with environment variables as build args -3. **Stops** the previous container (if exists) -4. **Starts** new container with updated code -5. **Updates** Traefik routing configuration (for web apps with domains) -6. **Streams** real-time logs to your dashboard - -For database applications, Mist pulls the Docker image instead of building from source. - -## Triggering Deployments - -### Manual Deployment - -Click the **"Deploy"** button in your application dashboard. - -### Automatic Deployment - -Configure GitHub webhooks to auto-deploy on push: - -1. Install Mist GitHub App on your repository -2. Enable webhooks in application settings -3. Push to your configured branch -4. Deployment triggers automatically - -[Learn more about Git integration →](./git-integration) - -## Deployment Status - -Monitor deployment progress in real-time: - -- 🟡 **Queued** - Waiting in deployment queue -- 🔵 **Building** - Docker image being built -- 🟢 **Running** - Container started successfully -- 🔴 **Failed** - Deployment encountered an error - -## Build Logs - -View detailed build logs during and after deployment: - -1. Go to **Deployments** tab -2. Click on a deployment -3. View streaming logs in real-time - -Logs include: -- Git clone output -- Build command execution -- Docker image creation -- Container startup - -## Deployment History - -Track all deployments with full history: - -- Deployment timestamp -- Commit hash and message -- Build duration -- Status (success/failed) -- Triggering user or webhook - -## Coming Soon - -
-

🚧 Deployment Features

-
- -- **Rollback** - Revert to previous deployments with one click -- **Blue-Green Deployments** - Zero-downtime deployments -- **Canary Releases** - Gradual traffic shifting -- **Deployment Hooks** - Pre/post deploy scripts -- **Manual Approval** - Require approval before production deploys -- **Scheduled Deployments** - Deploy at specific times -- **Preview Environments** - Auto-deploy pull requests - -## Troubleshooting - -### Build Failures - -Common causes: -- Missing dependencies -- Incorrect build command -- Dockerfile errors -- Insufficient permissions - -**Solution**: Check build logs for specific error messages - -### Container Won't Start - -Possible issues: -- Wrong start command -- Port configuration mismatch -- Missing environment variables -- Application crashes on startup - -**Solution**: Review container logs for errors - -### Slow Builds - -Optimization tips: -- Use `.dockerignore` to exclude unnecessary files -- Implement Docker layer caching -- Use multi-stage builds -- Optimize dependency installation - -## Best Practices - -- ✅ Test locally before deploying -- ✅ Use feature branches for experimentation -- ✅ Monitor logs during deployment -- ✅ Set up health checks -- ✅ Keep deployment logs for debugging diff --git a/www/docs/guide/domains.md b/www/docs/guide/domains.md deleted file mode 100644 index 458e2e6..0000000 --- a/www/docs/guide/domains.md +++ /dev/null @@ -1,188 +0,0 @@ -# Domains & SSL - -Configure custom domains for your applications. - -## Wildcard Domain Configuration - -Mist supports automatic domain generation for web applications using a wildcard domain configuration. - -### What is Wildcard Domain? - -When configured, Mist automatically generates a subdomain for every new web application using the pattern: -``` -{project-name}-{app-name}.{wildcard-domain} -``` - -### Setting Up Wildcard Domain - -1. Go to **Settings** (requires owner role) -2. Enter your wildcard domain (e.g., `example.com` or `*.example.com`) -3. Optionally configure the Mist dashboard subdomain name (default: `mist`) -4. Click **"Save"** - -### DNS Configuration for Wildcard - -To use wildcard domains, configure a wildcard DNS record: - -``` -Type: A -Name: * -Value: YOUR_SERVER_IP -TTL: 3600 -``` - -Or for subdomains: -``` -Type: A -Name: *.apps -Value: YOUR_SERVER_IP -TTL: 3600 -``` - -This allows any subdomain (e.g., `production-api.example.com`, `staging-web.example.com`) to route to your server. - -### Benefits - -- **Automatic domains**: No manual domain configuration needed for new apps -- **Consistent naming**: Standardized domain format across all applications -- **SSL automation**: Auto-generated domains get automatic Let's Encrypt certificates -- **Easy management**: Change the base domain in one place - -### Examples - -**Wildcard domain**: `example.com` -- Project: `production`, App: `api` → `production-api.example.com` -- Project: `staging`, App: `frontend` → `staging-frontend.example.com` - -**Wildcard domain**: `apps.mysite.com` -- Project: `personal`, App: `blog` → `personal-blog.apps.mysite.com` - -::: tip -Auto-generated domains only apply to web applications. Service and database applications do not receive automatic domains. -::: - -## Adding a Domain - -1. Navigate to your application -2. Go to **Domains** tab -3. Click **"Add Domain"** -4. Enter your domain name (e.g., `app.example.com`) -5. Click **"Add"** - -## DNS Configuration - -Point your domain to your Mist server: - -### A Record - -``` -Type: A -Name: app (or @ for root) -Value: YOUR_SERVER_IP -TTL: 3600 -``` - -### CNAME Record (Subdomain) - -``` -Type: CNAME -Name: app -Value: yourdomain.com -TTL: 3600 -``` - -## Verify DNS Propagation - -Check if DNS has propagated: - -```bash -dig app.example.com -nslookup app.example.com -``` - -Propagation can take 5 minutes to 48 hours. - -## SSL/TLS Certificates - -Mist automatically provisions and manages SSL/TLS certificates for your domains using Let's Encrypt and Traefik. - -### Automatic SSL - -When you add a domain to your application: - -1. **Domain Verification**: Mist verifies your DNS is correctly configured -2. **Certificate Request**: Traefik automatically requests a certificate from Let's Encrypt -3. **HTTPS Enabled**: Your domain is secured with SSL/TLS -4. **HTTP Redirect**: HTTP traffic is automatically redirected to HTTPS - -### Auto-Renewal - -Certificates are automatically renewed by Traefik: -- Renewal happens before expiration (typically 30 days before) -- Zero downtime during renewal -- No manual intervention required - -### Requirements - -For automatic SSL to work: -- Domain DNS must point to your Mist server (A record) -- Ports 80 and 443 must be open and accessible -- Domain must be publicly accessible for Let's Encrypt verification - -::: tip Certificate Status -You can view the SSL status of your domains in the Domains tab of your application. Status will show as "pending" during issuance and "active" once the certificate is installed. -::: - -### Coming Soon - -- **Wildcard Support** - `*.example.com` certificates -- **Custom Certificates** - Upload your own SSL certs - -## Multiple Domains - -Add multiple domains to the same application: - -``` -app.example.com -www.app.example.com -app.yourdomain.com -``` - -All domains will route to the same container. - -## Domain Management - -### Edit Domain - -Update domain configuration in the domains list. - -### Delete Domain - -Remove a domain from your application: - -1. Click the delete icon next to the domain -2. Confirm deletion - -## Troubleshooting - -### Domain Not Resolving - -- Verify DNS records are correct -- Wait for DNS propagation (can take up to 48 hours) -- Check DNS with: `dig app.example.com` or `nslookup app.example.com` -- Clear local DNS cache: `sudo systemd-resolve --flush-caches` - -### SSL Certificate Not Issuing - -- Verify domain DNS points to your server IP -- Ensure ports 80 and 443 are open in your firewall -- Check that domain is publicly accessible -- View Traefik logs for errors: `docker logs traefik` -- Let's Encrypt has rate limits - wait if you've made many requests - -### HTTPS Not Working - -- Wait a few minutes for certificate issuance -- Check SSL status in Domains tab (should show "active") -- Verify Traefik container is running: `docker ps | grep traefik` -- Check Traefik configuration in `/etc/traefik/` diff --git a/www/docs/guide/environment-variables.md b/www/docs/guide/environment-variables.md deleted file mode 100644 index e032037..0000000 --- a/www/docs/guide/environment-variables.md +++ /dev/null @@ -1,279 +0,0 @@ -# Environment Variables - -Environment variables allow you to configure your applications without hardcoding values in your code. - -## Overview - -Environment variables in Mist are: - -- **Secure**: Values are masked in the UI -- **Flexible**: Support both build-time and runtime variables -- **Easy to Manage**: Single and bulk import modes - -## Adding Environment Variables - -### Single Variable - -1. Navigate to your application -2. Go to **Environment** tab -3. Click **"Add Variable"** -4. Select **"Single"** mode -5. Enter **Key** and **Value** -6. Click **"Add"** - -### Bulk Import New - -Add multiple variables at once by pasting them in `KEY=VALUE` format: - -1. Click **"Add Variable"** -2. Select **"Bulk Paste"** mode -3. Paste your environment variables: - -```bash -NODE_ENV=production -DATABASE_URL=postgresql://user:pass@host:5432/db -API_KEY=your-api-key-here -REDIS_URL=redis://localhost:6379 -PORT=3000 -``` - -4. Preview detected variables -5. Click **"Add X Variables"** - -#### Supported Formats - -The parser supports: - -```bash -# Standard format -KEY=value - -# With quotes -KEY="value with spaces" -KEY='single quoted value' - -# Comments (ignored) -# This is a comment -DATABASE_URL=postgres://localhost - -# Empty lines (ignored) - -NEXT_PUBLIC_API=https://api.example.com -``` - -## Variable Types - -### Runtime Variables - -Available when your container runs: - -```javascript -// Node.js -const apiKey = process.env.API_KEY; - -// Python -import os -api_key = os.environ.get('API_KEY') -``` - -### Build-time Variables - -Available during the build process: - -```dockerfile -ARG NODE_ENV -RUN npm run build -``` - -## Editing Variables - -1. Find the variable in the list -2. Click the **Edit** icon (pencil) -3. Modify key or value -4. Click **"Save"** - -## Deleting Variables - -1. Find the variable in the list -2. Click the **Delete** icon (trash) -3. Confirm deletion - -::: warning -Changes to environment variables require redeployment to take effect. -::: - -## Common Use Cases - -### Database Connection - -```bash -DATABASE_URL=postgresql://user:password@host:5432/dbname -DB_HOST=localhost -DB_PORT=5432 -DB_NAME=myapp -DB_USER=appuser -DB_PASSWORD=secret123 -``` - -### API Keys - -```bash -STRIPE_API_KEY=sk_test_xxxxx -SENDGRID_API_KEY=SG.xxxxx -AWS_ACCESS_KEY_ID=AKIAXXXXX -AWS_SECRET_ACCESS_KEY=xxxxx -``` - -### Application Configuration - -```bash -NODE_ENV=production -PORT=3000 -LOG_LEVEL=info -SESSION_SECRET=random-secret-string -``` - -### Feature Flags - -```bash -ENABLE_ANALYTICS=true -ENABLE_BETA_FEATURES=false -MAINTENANCE_MODE=false -``` - -## Best Practices - -### Security - -- ✅ Never commit secrets to Git -- ✅ Use environment variables for all sensitive data -- ✅ Rotate API keys regularly -- ✅ Use different values for staging and production - -### Naming Conventions - -```bash -# Use UPPER_SNAKE_CASE -DATABASE_URL=... - -# Prefix public variables (Next.js, Vite, etc.) -NEXT_PUBLIC_API_URL=... -VITE_API_URL=... - -# Group related variables -AWS_REGION=us-east-1 -AWS_BUCKET=my-bucket -AWS_ACCESS_KEY_ID=... -``` - -### Organization - -```bash -# Database -DATABASE_URL=... -DATABASE_POOL_SIZE=10 - -# Redis -REDIS_URL=... -REDIS_TTL=3600 - -# External Services -STRIPE_KEY=... -SENDGRID_KEY=... - -# App Config -NODE_ENV=production -PORT=3000 -``` - -## Coming Soon - -
-

🚧 Planned Features

-

Future enhancements for environment variables:

-
- -- **Encryption at Rest** - Encrypted storage for sensitive values -- **Variable Groups** - Organize variables into reusable groups -- **Templates** - Pre-defined variable sets for common stacks -- **Version History** - Track changes to variables over time -- **Import/Export** - Download as `.env` file -- **Secrets Management** - Integration with Vault or similar -- **Variable Validation** - Ensure required variables are set - -## Troubleshooting - -### Variables Not Available - -**Problem**: Environment variables not accessible in application - -**Solutions**: -- Redeploy the application after adding variables -- Check variable names (case-sensitive) -- Verify the variable is not overridden elsewhere - -### Build Failing - -**Problem**: Build fails after adding variables - -**Solutions**: -- Check for special characters in values -- Use quotes for values with spaces -- Ensure variables don't conflict with system variables - -### Parsing Errors (Bulk Import) - -**Problem**: Some variables not detected - -**Solutions**: -- Ensure format is `KEY=VALUE` -- Keys must start with letter or underscore -- Keys can only contain letters, numbers, and underscores -- Remove invalid characters - -## Examples by Framework - -### Node.js / Express - -```bash -NODE_ENV=production -PORT=3000 -DATABASE_URL=postgresql://localhost/myapp -SESSION_SECRET=your-secret-key -``` - -### Next.js - -```bash -# Server-side -DATABASE_URL=postgresql://localhost/myapp - -# Client-side (must be prefixed) -NEXT_PUBLIC_API_URL=https://api.example.com -``` - -### Python / Django - -```bash -DJANGO_SECRET_KEY=your-secret-key -DEBUG=False -DATABASE_URL=postgresql://localhost/myapp -ALLOWED_HOSTS=example.com,www.example.com -``` - -### Go - -```bash -PORT=8080 -DATABASE_URL=postgresql://localhost/myapp -JWT_SECRET=your-jwt-secret -``` - -## API Reference - -Manage environment variables programmatically via the API: - -- [Create Variable](/api/environment-variables#create) -- [List Variables](/api/environment-variables#list) -- [Update Variable](/api/environment-variables#update) -- [Delete Variable](/api/environment-variables#delete) diff --git a/www/docs/guide/getting-started.md b/www/docs/guide/getting-started.md deleted file mode 100644 index 68f234a..0000000 --- a/www/docs/guide/getting-started.md +++ /dev/null @@ -1,162 +0,0 @@ -# Getting Started - -This guide will walk you through installing Mist and deploying your first application. - -## Prerequisites - -Before installing Mist, ensure you have: - -- A Linux server (Ubuntu 20.04+ or Debian 11+ recommended) -- Docker installed and running -- At least 256MB RAM and 2GB disk space -- Root or sudo access -- A domain name (optional, but recommended for production) - -## Installation - -### Quick Install - -The easiest way to install Mist is using the installation script: - -```bash -curl -sSL https://trymist.cloud/install.sh | bash -``` - -This script will: -1. Download the latest Mist binary -2. Set up Traefik reverse proxy -3. Create systemd service for auto-start -4. Configure firewall rules (ports 80, 443, 8080) - -[Learn more about installation →](/deployment/installation) - -## First-Time Setup - -After installation, Mist will be available at `http://your-server-ip:8080`. - -### 1. Create Admin Account - -On first visit, you'll see the setup page: - -1. Enter admin email and password -2. Click "Create Admin Account" -3. You'll be automatically logged in - -### 2. Configure Wildcard Domain (Optional) - -For automatic domain generation: - -1. Go to **Settings** → **System** -2. Enter your wildcard domain (e.g., `example.com`) -3. Configure DNS with a wildcard A record pointing `*.example.com` to your server -4. New web applications will automatically get domains like `{project}-{app}.example.com` - -[Learn more about wildcard domains →](./domains#wildcard-domain-configuration) - -### 3. Configure GitHub Integration (Optional) - -To enable Git deployments: - -1. Go to **Settings** → **Git** -2. Follow the instructions to create a GitHub App -3. Install the app on your repositories - -[Learn more about GitHub setup →](/deployment/github-app) - -## Deploy Your First Application - -### Step 1: Create a Project - -Projects organize your applications: - -1. Click **"New Project"** in the dashboard -2. Enter a name (e.g., "My Portfolio") -3. Add tags (optional) -4. Click **"Create Project"** - -### Step 2: Create an Application - -1. Open your project -2. Click **"New Application"** -3. Fill in the basic details: - - **Name**: Your app name - - **Description**: Brief description of your app - - **Port**: Application port (e.g., 3000) -4. Click **"Create Application"** -5. Configure additional settings inside the app: - - **Git Repository**: Select from connected repos - - **Branch**: Choose branch to deploy - - **Dockerfile Path**: Path to your Dockerfile (e.g., `./Dockerfile`) - -### Step 3: Add Environment Variables - -1. Go to the **Environment** tab -2. Click **"Add Variable"** or use **"Bulk Paste"** -3. Add your environment variables: - ``` - NODE_ENV=production - DATABASE_URL=your-database-url - API_KEY=your-api-key - ``` - -### Step 4: Deploy - -1. Click **"Deploy"** button -2. Watch real-time build logs -3. Wait for deployment to complete -4. Access your app via the generated URL - -## Configure Custom Domain - -### Step 1: Add Domain - -1. Go to **Domains** tab in your application -2. Click **"Add Domain"** -3. Enter your domain (e.g., `app.example.com`) - -### Step 2: Configure DNS - -Point your domain to your server: - -``` -Type: A Record -Name: app (or @ for root domain) -Value: YOUR_SERVER_IP -TTL: 3600 (or auto) -``` - -### Step 3: Wait for DNS Propagation - -DNS changes can take 5 minutes to 48 hours to propagate. Check with: - -```bash -dig app.example.com -``` - -::: tip SSL/TLS Certificate -SSL certificates are automatically provisioned using Traefik and Let's Encrypt. Once your DNS is configured and propagated, your application will automatically get an SSL certificate. -::: - -## Next Steps - -Now that you have Mist running, explore these topics: - -- [**Projects**](./projects) - Organize applications -- [**Deployments**](./deployments) - Deployment strategies -- [**Environment Variables**](./environment-variables) - Managing configuration -- [**Monitoring**](./logs) - Container and system logs -- [**Metrics**](./metrics) - System resource monitoring -- [**Git Integration**](./git-integration) - Auto-deploy on push - -## Getting Help - -- [GitHub Issues](https://github.com/corecollectives/mist/issues) - Report bugs -- [GitHub Discussions](https://github.com/corecollectives/mist/discussions) - Ask questions -- [Documentation](/) - Read more guides - -## What's Next? - -### Coming Soon Features - -- 🚧 Email notifications for deployments -- 🚧 CLI tool for terminal deployments diff --git a/www/docs/guide/git-integration.md b/www/docs/guide/git-integration.md deleted file mode 100644 index 98b64f2..0000000 --- a/www/docs/guide/git-integration.md +++ /dev/null @@ -1,98 +0,0 @@ -# Git Integration - -Connect Mist with GitHub to enable automatic deployments. - -## GitHub App Setup - -### 1. Create GitHub App - -Follow the [GitHub App Setup Guide](/deployment/github-app) to create and install the Mist GitHub App. - -### 2. Install on Repositories - -Install the GitHub App on repositories you want to deploy: - -1. Visit GitHub App settings -2. Click **"Install App"** -3. Select repositories -4. Grant required permissions - -### 3. Connect in Mist - -Once installed, repositories appear in the application creation form. - -## Auto-Deploy on Push - -Enable automatic deployments: - -1. Create application with GitHub repository -2. Select branch to deploy -3. Push code to that branch -4. Mist receives webhook and deploys automatically - -## Webhook Events - -Mist listens for these GitHub events: - -- **Push** - Code pushed to branch -- **Pull Request** (coming soon) - PR opened/updated - -## Commit Tracking - -Each deployment tracks: - -- Commit hash (SHA) -- Commit message -- Author information -- Timestamp - -View commit details in the deployments list. - -## Branch Management - -### Selecting Branch - -Choose which branch to deploy: - -- `main` - Production deployments -- `develop` - Staging environment -- `feature/*` - Feature testing - -### Changing Branch - -Update the deployment branch: - -1. Go to application settings -2. Change **Branch** field -3. Save changes -4. Next deployment uses new branch - -## Coming Soon - -
-

🚧 Git Features in Development

-
- -- **GitLab Integration** - Connect GitLab repositories -- **Bitbucket Support** - Bitbucket repositories -- **Pull Request Previews** - Deploy PRs to preview URLs -- **Commit Status Updates** - Update GitHub with deployment status -- **Multiple Git Providers** - Use multiple providers per app -- **Self-hosted Git** - Gitea, Gogs support - -## Troubleshooting - -### Webhook Not Triggering - -Check: -- GitHub App is installed on repository -- Webhook URL is correct -- Repository permissions are granted -- Firewall allows GitHub webhook IPs - -### Wrong Branch Deploying - -Verify: -- Branch name matches exactly (case-sensitive) -- Application settings have correct branch -- Webhook is configured for correct events diff --git a/www/docs/guide/logs.md b/www/docs/guide/logs.md deleted file mode 100644 index 8be67ac..0000000 --- a/www/docs/guide/logs.md +++ /dev/null @@ -1,132 +0,0 @@ -# Logs & Monitoring - -Monitor your applications and system with real-time logs and system metrics. - -## System Logs - -View live logs from the Mist backend server: - -1. Navigate to **Logs** page in the main navigation -2. System logs stream in real-time -3. Powered by `journalctl` under the hood - -### What's Included - -System logs show all output from the Mist Go backend, including: -- Application lifecycle events (startup, shutdown) -- Deployment processing -- API requests and responses -- Container operations -- Error messages and stack traces -- System events and notifications - -### Features - -- **Real-time streaming** - Logs appear instantly via WebSocket -- **Live updates** - See backend activity as it happens -- **journalctl integration** - Leverages systemd journal for reliable log collection -- **Filterable** - Search and filter system logs -- **Persistent** - Logs stored in systemd journal - -::: tip -System logs are useful for debugging deployment issues, monitoring backend activity, and troubleshooting system-level problems. -::: - -## Container Logs - -View live logs from your running containers: - -1. Navigate to your application -2. Go to **Logs** tab -3. Logs stream in real-time via WebSocket - -### Features - -- **Real-time streaming** - Logs appear instantly -- **Auto-scroll** - Automatically scrolls to latest logs -- **Color coding** - Error, warning, and info levels highlighted -- **Search** - Filter logs by keyword (coming soon) -- **Download** - Export logs to file (coming soon) - -## Build Logs - -View logs from deployment builds: - -1. Go to **Deployments** tab -2. Click on a deployment -3. View complete build output - -Build logs show: -- Git clone process -- Dependency installation -- Build command execution -- Docker image creation -- Container startup - -## System Metrics - -Monitor server resource usage: - -### CPU Usage - -Real-time CPU utilization displayed as percentage. - -### Memory Usage - -Current RAM usage and available memory. - -### Disk Usage - -Storage space used and available on server. - -### Update Frequency - -Metrics update every second via WebSocket. - -## Coming Soon - -
-

🚧 Advanced Monitoring Features

-
- -- **Log Aggregation** - Search across all logs -- **Log Retention** - Configure how long to keep logs -- **Log Export** - Download logs as files -- **Application Metrics** - Request count, response times -- **Alerting** - Email/Slack notifications for errors -- **Custom Dashboards** - Create metric visualizations -- **Error Tracking** - Sentry-like error monitoring -- **Uptime Monitoring** - Track application availability - -## Log Best Practices - -### Structured Logging - -Use JSON format for easier parsing: - -```javascript -console.log(JSON.stringify({ - level: 'info', - message: 'User logged in', - userId: 123, - timestamp: new Date().toISOString() -})); -``` - -### Log Levels - -Use appropriate log levels: - -```javascript -console.log('Info message'); // Info -console.warn('Warning message'); // Warning -console.error('Error message'); // Error -``` - -### Avoid Sensitive Data - -Never log: -- Passwords -- API keys -- Credit card numbers -- Personal identification diff --git a/www/docs/guide/metrics.md b/www/docs/guide/metrics.md deleted file mode 100644 index 848247d..0000000 --- a/www/docs/guide/metrics.md +++ /dev/null @@ -1,52 +0,0 @@ -# System Metrics - -Monitor your Mist server's resource usage in real-time. - -::: tip Application-Level Metrics -Currently, Mist displays system-level metrics only. Per-application metrics (CPU, memory, network usage per container) are coming soon. -::: - -## Available Metrics - -### CPU Usage - -- **Current Usage**: Real-time CPU percentage -- **Per-Core**: Individual core utilization -- **Load Average**: System load over time - -### Memory (RAM) - -- **Used**: Currently allocated memory -- **Free**: Available memory -- **Total**: Total system memory -- **Percentage**: Memory usage percentage - -### Disk Space - -- **Used**: Storage space consumed -- **Free**: Available storage -- **Total**: Total disk capacity -- **Percentage**: Disk usage percentage - -## Viewing Metrics - -Access system metrics from: - -1. **Dashboard** - Overview of all metrics -2. **System Status** page - Detailed metrics view - -Metrics update every second via WebSocket connection. - -## Coming Soon - -
-

🚧 Enhanced Metrics

-
- -- **Historical Data** - View metrics over time -- **Metric Charts** - Visualize trends with graphs -- **Per-Application Metrics** - Resource usage by app -- **Network Metrics** - Bandwidth monitoring -- **Disk I/O** - Read/write operations -- **Alerts** - Notifications when thresholds exceeded -- **Metric Export** - Prometheus integration diff --git a/www/docs/guide/notifications.md b/www/docs/guide/notifications.md deleted file mode 100644 index e9cf0d2..0000000 --- a/www/docs/guide/notifications.md +++ /dev/null @@ -1,84 +0,0 @@ -# Notifications Coming Soon - -Get notified about deployments, errors, and system events. - -
-

🚧 Feature in Development

-

Notification system is planned for Phase 1 (Medium Priority).

-
- -## Planned Channels - -### Email Notifications - -- SMTP configuration -- Customizable templates -- Per-user preferences -- Batch digest mode - -### Slack Integration - -- Webhook integration -- Channel selection -- Custom message formatting -- Thread support - -### Discord Webhooks - -- Rich embed messages -- Role mentions -- Server/channel selection - -### Custom Webhooks - -- HTTP POST to any URL -- JSON payload -- Custom headers -- Retry logic - -## Event Types - -### Deployment Events - -- ✅ Deployment started -- ✅ Deployment succeeded -- ❌ Deployment failed -- 🔄 Rollback performed - -### System Events - -- ⚠️ High CPU usage -- ⚠️ Low disk space -- ⚠️ Memory threshold exceeded -- 🔒 SSL certificate expiring soon - -### Application Events - -- 🐛 Application crashed -- 🔄 Application restarted -- ⏱️ Slow response times -- ❌ Health check failed - -## Notification Preferences - -```yaml -# Per-user configuration -notifications: - email: - enabled: true - events: - - deployment.success - - deployment.failed - slack: - enabled: true - webhook: https://hooks.slack.com/... - events: - - deployment.failed - - system.alert -``` - -## Expected Release - -Target: Q2 2025 - -[View implementation plan →](https://github.com/corecollectives/mist/blob/main/roadmap.md#notification-system) diff --git a/www/docs/guide/projects.md b/www/docs/guide/projects.md deleted file mode 100644 index 1cfc7ce..0000000 --- a/www/docs/guide/projects.md +++ /dev/null @@ -1,82 +0,0 @@ -# Projects - -Projects help you organize and group related applications together. - -## Overview - -A project is a container for multiple applications, allowing you to: - -- Group related applications (e.g., frontend, backend, worker) -- Manage team access and permissions -- Organize by client, environment, or purpose -- Track resources and deployments collectively - -## Creating a Project - -1. Click **"New Project"** from the dashboard -2. Enter project details: - - **Name**: Descriptive project name - - **Description**: Optional description - - **Tags**: Comma-separated tags for filtering - -3. Click **"Create"** - -## Project Members - -Add team members to collaborate on projects: - -1. Open your project -2. Go to **Members** tab -3. Click **"Add Member"** -4. Select user(s) from list -5. Click **"Save"** - -### Member Access - -All project members have equal access to: -- View all applications in the project -- Deploy applications -- View logs and metrics -- Manage application settings - -::: tip Coming Soon -Role-based permissions (Owner, Admin, Member) and ownership transfer are upcoming features. Currently, all members have full access to the project. -::: - -## Managing Applications - -All applications within a project are listed on the project page: - -- Create new applications -- View deployment status -- Access application details -- Monitor resource usage - -## Project Settings - -### General - -- Update project name and description -- Modify tags for organization -- View project statistics -- Manage project members - -### Danger Zone - -- Delete project (requires confirmation) - - Only the project owner can delete the project - - Deletes all applications and their data - -## Coming Soon - -
-

🚧 Upcoming Features

-
- -- **Role-Based Permissions** - Owner, Admin, and Member roles with different access levels -- **Project Ownership Transfer** - Transfer project ownership to another user -- **Project-level Environment Variables** - Share variables across apps -- **Project Templates** - Quick-start templates for common stacks -- **Resource Quotas** - Limit CPU, memory, and storage per project -- **Billing Integration** - Track costs per project -- **Project Archives** - Temporarily disable all apps diff --git a/www/docs/guide/rollback.md b/www/docs/guide/rollback.md deleted file mode 100644 index 79f59d8..0000000 --- a/www/docs/guide/rollback.md +++ /dev/null @@ -1,60 +0,0 @@ -# Deployment Rollback Coming Soon - -Instantly revert to previous deployments. - -
-

🚧 Feature in Development

-

Deployment rollback is a high-priority feature for Phase 1.

-
- -## Planned Features - -### One-Click Rollback - -- Revert to any previous deployment -- Instant container swap -- Zero configuration required -- Preserves deployment history - -### Deployment History - -- Keep last N deployments (configurable) -- View complete deployment timeline -- Compare deployments side-by-side -- Track rollback events - -### Image Management - -- Automatic image retention -- Configurable cleanup policy -- Disk space management -- Image size tracking - -## How It Will Work - -```bash -# In the dashboard: -1. Go to Deployments tab -2. Find previous successful deployment -3. Click "Rollback to this deployment" -4. Confirm rollback -5. Container switches to previous image instantly -``` - -## Rollback Strategies - -### Quick Rollback -- Keep previous container image -- Instant switch (< 10 seconds) -- Previous environment variables restored - -### Full Rollback -- Roll back code, config, and environment -- Complete state restoration -- Useful for major issues - -## Expected Release - -Target: Q1 2025 - Quick Win Priority - -[View implementation plan →](https://github.com/corecollectives/mist/blob/main/roadmap.md#deployment-rollback) diff --git a/www/docs/guide/ssl-automation.md b/www/docs/guide/ssl-automation.md deleted file mode 100644 index 60b10fa..0000000 --- a/www/docs/guide/ssl-automation.md +++ /dev/null @@ -1,191 +0,0 @@ -# SSL Automation - -Automatic SSL/TLS certificate provisioning with Let's Encrypt. - -Mist provides automatic SSL certificate management through Traefik and Let's Encrypt integration, ensuring your applications are always secured with HTTPS. - -## Features - -### Automatic Certificate Issuance - -- **Let's Encrypt Integration**: Free SSL certificates via ACME protocol -- **Automatic Generation**: Certificates issued when you add a domain -- **HTTP-01 Challenge**: Domain verification through HTTP -- **Zero Configuration**: No manual certificate management needed - -### Auto-Renewal - -- **Automatic Renewal**: Certificates renewed before expiry (typically 30 days before) -- **Zero Downtime**: Renewals happen seamlessly in the background -- **No Manual Intervention**: Traefik handles the entire renewal process - -### Security Features - -- **Force HTTPS**: Automatic HTTP to HTTPS redirect enabled by default -- **TLS 1.2+**: Modern encryption standards -- **Secure Headers**: Best practice security headers configured - -## How It Works - -### Adding a Domain - -1. **Add Domain**: Enter your domain name in the application's Domains tab -2. **DNS Verification**: Ensure your domain's A record points to your Mist server -3. **Automatic Issuance**: Traefik detects the new domain and requests a certificate -4. **Certificate Installation**: Let's Encrypt issues the certificate and Traefik installs it -5. **HTTPS Enabled**: Your application is now accessible via HTTPS - -The entire process is automatic and typically takes 1-2 minutes after DNS propagation. - -### Domain Labels - -Mist automatically configures Traefik labels on your containers: - -```yaml -traefik.enable=true -traefik.http.routers.app-{id}.rule=Host(`your-domain.com`) -traefik.http.routers.app-{id}.entrypoints=websecure -traefik.http.routers.app-{id}.tls=true -traefik.http.routers.app-{id}.tls.certresolver=le -traefik.http.routers.app-{id}-http.rule=Host(`your-domain.com`) -traefik.http.routers.app-{id}-http.entrypoints=web -traefik.http.routers.app-{id}-http.middlewares=https-redirect -traefik.http.middlewares.https-redirect.redirectscheme.scheme=https -``` - -### Certificate Storage - -Certificates are stored in Traefik's ACME storage: -- Location: `/etc/traefik/acme.json` -- Format: JSON file with encrypted certificates -- Backup: Recommended to backup this file regularly - -## Requirements - -For SSL automation to work properly: - -1. **Valid Domain**: Domain must be registered and active -2. **DNS Configuration**: A record pointing to your server's public IP -3. **Port Access**: Ports 80 (HTTP) and 443 (HTTPS) must be publicly accessible -4. **Public Server**: Server must be reachable from the internet for Let's Encrypt verification -5. **No Rate Limits**: Be aware of Let's Encrypt rate limits (50 certificates per domain per week) - -## Monitoring Certificate Status - -### In Dashboard - -View certificate status in the Domains tab: -- **Pending**: Certificate request in progress -- **Active**: Certificate successfully issued and installed -- **Failed**: Certificate issuance failed (check logs) - -### Via Logs - -Check Traefik logs for certificate operations: - -```bash -docker logs traefik -``` - -Look for messages like: -- `Obtaining certificate for domain` -- `Certificate obtained successfully` -- `Renewing certificate` - -## Troubleshooting - -### Certificate Not Issuing - -**DNS Not Propagated** -- Wait for DNS propagation (up to 48 hours) -- Verify with: `dig your-domain.com` - -**Port Not Accessible** -- Check firewall: `sudo ufw status` -- Ensure ports 80 and 443 are open -- Test accessibility: `curl -I http://your-domain.com` - -**Let's Encrypt Rate Limit** -- Let's Encrypt has limits: 50 certificates per registered domain per week -- Wait if you've hit the limit -- Use Let's Encrypt staging environment for testing - -**Domain Verification Failed** -- Ensure domain points to correct IP -- Check that no other service is using port 80 -- Verify Traefik is running: `docker ps | grep traefik` - -### Certificate Not Renewing - -**Check ACME Storage** -```bash -ls -la /etc/traefik/acme.json -``` - -**Check Traefik Configuration** -```bash -cat /etc/traefik/traefik.yml -``` - -Ensure certificate resolver is configured: -```yaml -certificatesResolvers: - le: - acme: - email: your-email@example.com - storage: /acme.json - httpChallenge: - entryPoint: web -``` - -### Debugging - -Enable debug logging in Traefik: -1. Edit Traefik configuration -2. Set log level to DEBUG -3. Restart Traefik: `docker restart traefik` -4. Monitor logs: `docker logs -f traefik` - -## Best Practices - -### Email Configuration - -Configure a valid email in Traefik for Let's Encrypt notifications: -- Notifies about certificate expiration -- Required for Let's Encrypt terms acceptance -- Used for important updates - -### Backup ACME Storage - -Regularly backup `/etc/traefik/acme.json`: -```bash -cp /etc/traefik/acme.json /backup/acme.json.$(date +%Y%m%d) -``` - -### Test Domains - -Use staging environment for testing: -- Avoids rate limits -- Tests certificate issuance without counting against production limits -- Configure in Traefik: `caServer: https://acme-staging-v02.api.letsencrypt.org/directory` - -### Multiple Domains - -You can add multiple domains to a single application: -- Each domain gets its own certificate -- All domains route to the same container -- Certificates managed independently - -## Coming Soon - -- **Wildcard Certificates**: Support for `*.example.com` domains -- **Custom Certificates**: Upload and manage your own SSL certificates -- **Certificate Dashboard**: View all certificates and expiration dates -- **DNS-01 Challenge**: Support for wildcard certificates via DNS validation -- **Certificate Notifications**: Email alerts before certificate expiration - -## Related Documentation - -- [Domains Guide](./domains) - Managing application domains -- [Traefik Configuration](/deployment/traefik) - Advanced Traefik setup -- [Applications](./applications) - Application management diff --git a/www/docs/guide/users.md b/www/docs/guide/users.md deleted file mode 100644 index 951dc80..0000000 --- a/www/docs/guide/users.md +++ /dev/null @@ -1,167 +0,0 @@ -# Users & Roles - -Manage users and their permissions in Mist. - -## System Roles - -Mist has a hierarchical role-based access control system with three levels: - -### Owner - -**Highest privilege level** - Complete system control - -- Only ONE owner exists per Mist instance -- Created automatically during first-time setup -- Cannot be duplicated through UI or API -- Full access to all features and settings -- Can view and update system settings -- Can create and delete users (including admins) -- Can view all audit logs -- Can delete themselves (resets system to setup mode) - -### Admin - -**High-level administrative privileges** - Second to owner - -- Can create and manage projects -- Can create users (admin and user roles) -- Can delete users (except owners and other admins) -- Can view all audit logs -- Access to assigned projects only -- **Cannot** view or modify system settings -- **Cannot** delete owners or other admins -- **Cannot** create owner accounts - -### User - -**Standard role** - Basic project access - -- Can access assigned projects -- Can deploy applications -- Can manage applications in assigned projects -- Can view logs and metrics -- **Cannot** create projects -- **Cannot** create other users -- **Cannot** view system settings -- **Cannot** view audit logs - -## Role Comparison - -| Permission | Owner | Admin | User | -|-----------|-------|-------|------| -| View system settings | ✅ | ❌ | ❌ | -| Update system settings | ✅ | ❌ | ❌ | -| Create projects | ✅ | ✅ | ❌ | -| Create users | ✅ | ✅ | ❌ | -| Delete owners | ✅ | ❌ | ❌ | -| Delete admins | ✅ | ❌ | ❌ | -| Delete users | ✅ | ✅ | ❌ | -| View audit logs | ✅ | ✅ | ❌ | -| Access assigned projects | ✅ | ✅ | ✅ | -| Manage applications | ✅ | ✅ | ✅ | - -## Managing Users - -### Creating Users - -**Required role**: Owner or Admin - -1. Navigate to **Settings** → **Users** -2. Click **"Add User"** or **"New User"** -3. Fill in user information: - - Username - - Email address - - Password -4. Select role: - - **Admin**: For administrative users - - **User**: For standard users -5. Click **"Create"** - -::: tip -You cannot create additional owner accounts. Only one owner exists per Mist instance. -::: - -### Viewing Users - -**Required role**: Owner or Admin - -View all users in the system: -- Username -- Email -- Role (displayed with color-coded badges) -- Account creation date - -**Role badge colors:** -- Owner: Purple -- Admin: Blue -- User: Gray - -### Updating Users - -**Required role**: Owner or Admin - -Modify existing user details: -1. Click on the user you want to edit -2. Update information: - - Username - - Email - - Password - - Role (owner/admin only) -3. Click **"Save"** - -All changes are logged in the audit system. - -### Deleting Users - -**Deletion permissions:** -- **Owner**: Can delete any user (admins and users) -- **Admin**: Can only delete users (not owners or other admins) -- **User**: Cannot delete anyone - -To delete a user: -1. Navigate to the Users page -2. Click the delete icon next to the user -3. Confirm the deletion - -::: warning Deletion Restrictions -- Admins cannot delete owners or other admins -- Projects and applications created by the deleted user are preserved -- If the owner deletes themselves, the system resets to setup mode -::: - -## Project Roles - -::: info Coming Soon -Project-level roles (Owner, Admin, Member) are not yet implemented. Currently, all project members have equal access to project resources. - -See [Projects documentation](./projects) for more details on project membership. -::: - -## Best Practices - -### Role Assignment - -- **Owner**: Reserve for the primary system administrator -- **Admin**: For trusted team members who need to manage users and projects -- **User**: For team members who only need to work on specific projects - -### Security Recommendations - -1. **Limit Admins**: Only assign admin role to users who need administrative privileges -2. **Use Users**: Most team members should have the user role -3. **Protect Owner**: The owner account should have a strong password and be well-protected -4. **Regular Audits**: Review user list regularly and remove inactive accounts -5. **Audit Logs**: Monitor audit logs for suspicious activity - -### Account Management - -- Set strong password requirements for all users -- Remove users who no longer need access -- Review role assignments periodically -- Document who has owner and admin access - -## Related Documentation - -- [Authentication](./authentication) - Detailed authentication information -- [Audit Logs](./audit-logs) - Track user actions -- [Projects](./projects) - Project membership management diff --git a/www/docs/guide/what-is-mist.md b/www/docs/guide/what-is-mist.md deleted file mode 100644 index ad0b6dd..0000000 --- a/www/docs/guide/what-is-mist.md +++ /dev/null @@ -1,146 +0,0 @@ -# What is Mist? - -Mist is a **self-hostable Platform-as-a-Service (PaaS)** that allows you to deploy and manage Docker-based applications on your own infrastructure. Think of it as your own private Heroku, but with more control and zero vendor lock-in. - -## Overview - -Mist simplifies the deployment workflow by providing: - -- **Automated Deployments** - Push to Git and deploy automatically -- **Container Management** - Docker-based isolation for applications -- **Real-time Monitoring** - WebSocket-powered live logs and metrics -- **Team Collaboration** - Projects with multi-user access -- **Domain Management** - Custom domains with automatic SSL and wildcard domain support - -## Architecture - -Mist is built with a **monolithic Go backend** and a **React + Vite frontend**, designed to run efficiently on a single VPS with minimal resources. - -### Core Components - -``` -┌─────────────────────────────────────────────┐ -│ Frontend (React + Vite) │ -│ Modern UI with Real-time Updates │ -└──────────────────┬──────────────────────────┘ - │ REST API + WebSocket -┌──────────────────▼──────────────────────────┐ -│ Backend API (Go) │ -│ • Authentication & Authorization │ -│ • Project & Application Management │ -│ • Deployment Queue & Workers │ -│ • Real-time Log Streaming │ -└──────────┬────────────────┬──────────────────┘ - │ │ - │ │ -┌──────────▼────────┐ ┌────▼──────────────────┐ -│ SQLite Database │ │ Docker Engine │ -│ • Users │ │ • Build Images │ -│ • Projects │ │ • Run Containers │ -│ • Apps │ │ • Manage Networks │ -│ • Deployments │ │ │ -└───────────────────┘ └───────────────────────┘ - │ - ┌─────────▼─────────┐ - │ Traefik Proxy │ - │ • Route Traffic │ - │ • SSL/TLS │ - └────────────────────┘ -``` - -[Learn more about architecture →](./architecture) - -## Key Features - -### Deployment Workflow - -1. **Connect Repository** - Link your GitHub repository -2. **Configure Build** - Set build and start commands -3. **Add Environment Variables** - Configure runtime environment -4. **Deploy** - Push to Git or manually trigger deployment -5. **Monitor** - Watch real-time logs and metrics - -### Technology Stack - -**Backend:** -- Go (1.21+) - Fast, compiled language -- SQLite - Embedded database -- Traefik - Reverse proxy and load balancer -- Docker - Container runtime - -**Frontend:** -- React 18 - UI framework -- Vite - Build tool and dev server -- Tailwind CSS - Styling -- Shadcn/ui - Component library - -## Why Choose Mist? - -### 🪶 Ultra Lightweight - -- **Single Binary** - No complex installation process -- **No External Database** - SQLite embedded -- **Minimal Dependencies** - Just Docker required -- **Low Resource Usage** - Runs on basic VPS ($5-10/month) - -### ⚡ Real-time Experience - -- **WebSocket-First** - Instant feedback for all operations -- **Live Logs** - Stream container and system logs in real-time -- **Live Metrics** - CPU, RAM, and disk usage updated every second -- **Deployment Status** - Watch builds progress in real-time -- **System Monitoring** - View Mist backend logs via journalctl integration - -### 🔧 Developer Friendly - -- **Simple Setup** - One-line installation script -- **Intuitive UI** - Clean, modern dashboard -- **Comprehensive API** - RESTful endpoints for automation -- **CLI Tool** - (Coming Soon) Deploy from terminal - -### 🔐 Secure - -- **JWT Authentication** - Secure token-based auth -- **HTTP-Only Cookies** - Protection against XSS -- **Audit Logging** - Track all user actions -- **Role-Based Access** - Admin and user roles -- **Environment Encryption** - (Coming Soon) Secrets at rest - -## Use Cases - -### Personal Projects - -Host your side projects, portfolios, and experimental apps without paying for expensive hosting. - -### Small Teams - -Collaborate with team members on multiple projects with organized workspaces and access control. - -### Staging Environments - -Run isolated staging environments alongside production apps for testing before deployment. - -### Microservices - -Deploy and manage multiple microservices with custom domains and networking. - -## Comparison with Other PaaS - -| Feature | Mist | Coolify | Dokploy | CapRover | Heroku | -|---------|------|---------|---------|----------|--------| -| **Self-hosted** | ✅ | ✅ | ✅ | ✅ | ❌ | -| **Open Source** | ✅ | ✅ | ✅ | ✅ | ❌ | -| **Real-time Monitoring** | ✅ | ✅ | ✅ | ❌ | ✅ | -| **No External DB** | ✅ (SQLite) | ❌ (Postgres) | ❌ (Postgres) | ❌ (Mongo) | N/A | -| **Go Backend** | ✅ | ❌ (Node) | ❌ (Node) | ❌ (Node) | N/A | -| **Single Binary** | ✅ | ❌ | ❌ | ❌ | N/A | -| **Git Integration** | ✅ GitHub | ✅ Multiple | ✅ Multiple | ✅ Multiple | ✅ Multiple | -| **Managed Databases** | ✅ | ✅ | ✅ | ✅ | ✅ | -| **SSL Automation** | ✅ | ✅ | ✅ | ✅ | ✅ | -| **Auto Domain Generation** | ✅ | ❌ | ❌ | ✅ | ✅ | - -## Getting Started - -Ready to deploy your first application with Mist? - -[Get Started →](./getting-started) diff --git a/www/docs/index.md b/www/docs/index.md deleted file mode 100644 index e14f927..0000000 --- a/www/docs/index.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -layout: home - -hero: - name: Mist - text: | - Self-hostable - Platform-as-a-Service - tagline: Deploy applications with ease. Lightweight, fast, and built for developers. - image: - src: /mist.png - alt: Mist Logo ---- - - - - - -## Core Features - -
- -
-
- -
-

Easy Deployment

-

Deploy Docker apps from Git with automatic builds and zero-downtime updates

-
- -
-
- -
-

Git Integration

-

Native GitHub integration with webhooks for automatic deployments on push

-
- -
-
- -
-

Domains & SSL

-

Custom domains with automatic Let's Encrypt SSL certificate provisioning

-
- -
-
- -
-

Real-time Monitoring

-

Live deployment logs, system metrics, and container status with WebSocket updates

-
- -
-
- -
-

Ultra Lightweight

-

Single Go binary with embedded SQLite. No external dependencies required

-
- -
-
- -
-

Secure by Default

-

JWT authentication, audit logs, and role-based access control built-in

-
- -
-
- -
-

Database Services

-

One-click provisioning for PostgreSQL, MySQL, Redis, and MongoDB

-
- -
-
- -
-

Multi-User Projects

-

Team collaboration with project organization and role-based permissions

-
- -
-
- -
-

Environment Variables

-

Manage build-time and runtime environment variables with bulk import support

-
- -
- -## Why Mist? - -Mist is a **lightweight, self-hostable Platform-as-a-Service** designed for developers and small teams who want the simplicity of Heroku with the control of self-hosting. - -
- -### Platform Comparison - -
- -| Feature | Mist | Coolify | Dokploy | CapRover | Dokku | -|---------|------|---------|---------|----------|-------| -| **Installation** | Single command | Docker Compose | Single command | Docker Compose | Single command | -| **Dependencies** | Docker only | Docker + PostgreSQL/Redis | Docker only | Docker + PostgreSQL | Docker only | -| **Memory Usage** | ~50MB | ~500MB+ | ~100MB | ~300MB+ | Minimal | -| **Database** | SQLite (embedded) | PostgreSQL | PostgreSQL | PostgreSQL | File-based | -| **Real-time Updates** | ✓ WebSocket | ~ Polling | ✓ WebSocket | ~ Limited | ✗ No | -| **Multi-User** | ✓ Built-in | ✓ Built-in | ✓ Built-in | ~ Basic | ✗ Single user | -| **UI Framework** | React | Vue.js | React | Angular | Web + CLI | -| **Git Providers** | GitHub only | Multi-provider | Multi-provider | Multi-provider | Multi-provider | -| **One-click Upgrade** | ✓ Built-in | ✓ Built-in | ✓ Built-in | ✓ Built-in | ~ CLI only | -| **Docker Compose** | ✗ Not supported | ✓ Full support | ✓ Full support | ~ Limited | ~ Via plugins | -| **S3 Backups** | ✗ Not available | ✓ Automated | ✓ Automated | ~ Manual | ✗ Not available | -| **Template Library** | ✗ Coming soon | ✓ Extensive | ✓ Available | ✓ One-click apps | ~ Limited | -| **GitHub Integration** | ✓ Native | ✓ Native | ✓ Native | ~ Basic | ~ Via plugins | -| **Auto SSL** | ✓ Let's Encrypt | ✓ Let's Encrypt | ✓ Let's Encrypt | ✓ Let's Encrypt | ~ Via plugins | -| **Learning Curve** | Easy | Moderate | Easy | Moderate | Steep | -| **High Availability** | ✗ Single node | ✗ Single node | ✗ Single node | ✓ Cluster support | ✗ Single node | -| **Container Orchestration** | Docker | Docker | Docker | Docker Swarm | Docker/Kubernetes | -| **Maturity** | New (2025) | Established | New (2024) | Mature | Very mature | - -
- -
- -### What Mist Does Well - -
- -- **Minimal Resource Footprint** - Runs efficiently on a single VPS with just Docker installed (~50MB RAM) -- **Real-time Everything** - WebSocket-first architecture for instant feedback on logs, metrics, and deployments -- **Zero External Dependencies** - No PostgreSQL, Redis, or other services required. Just Docker. -- **Fast Setup** - Single command installation with automatic configuration -- **One-Click Updates** - Seamless upgrades from the dashboard with automatic rollback on failure -- **Modern UI/UX** - Clean, intuitive React interface with excellent developer experience - -
- -### Current Limitations - -
- -- **No High Availability** - Single node deployment only. Not suitable for mission-critical production workloads requiring 99.99% uptime -- **Limited Container Orchestration** - No Kubernetes support. Uses basic Docker containers without advanced orchestration -- **Single Git Provider** - Currently only supports GitHub. GitLab and Bitbucket support planned for future releases -- **No Docker Compose Support** - Cannot deploy docker-compose.yml files directly. Requires Dockerfile-based deployments only -- **No Automated Backups** - Missing S3/cloud storage integration for automatic database and application backups -- **Limited Template Library** - No pre-built application templates or one-click deployments (coming soon) -- **No Database Clustering** - Provisioned databases run as single containers without replication or clustering -- **Early Stage Project** - New platform (2024) with smaller community compared to established alternatives like Dokku or CapRover -- **Manual Scaling** - No auto-scaling capabilities. Manual intervention required for resource adjustments - -
- -
- -::: info Important Note -**Mist is not a drop-in replacement for Coolify, Dokploy, or other platforms.** We are a lightweight alternative focused on simplicity and minimal resource usage. If you need advanced features like Docker Compose support, multi-git providers, or high availability right now, consider using the more established alternatives above. However, these features are on our roadmap and will be available in Mist soon. -::: - -::: tip Fast Growing -**Mist is actively developed and rapidly evolving.** New features are being added continuously. All missing features listed above are on the roadmap and will be implemented soon. We're committed to making Mist a complete, production-ready PaaS solution. -::: - -
- - -## Community - -- [GitHub Repository](https://github.com/corecollectives/mist) -- [Discord Server](https://discord.gg/hr6TCQDDkj) -- [Report Issues](https://github.com/corecollectives/mist/issues) -- [Discussions](https://github.com/corecollectives/mist/discussions) - -## License - -Mist is open source software licensed under the [MIT License](https://github.com/corecollectives/mist/blob/main/LICENSE). diff --git a/www/docs/public/install.sh b/www/docs/public/install.sh deleted file mode 100755 index 91a6b79..0000000 --- a/www/docs/public/install.sh +++ /dev/null @@ -1,274 +0,0 @@ -#!/bin/bash -set -Eeo pipefail - - -LOG_FILE="/tmp/mist-install.log" -sudo rm -f "$LOG_FILE" 2>/dev/null || true -: > "$LOG_FILE" - -REAL_USER="${SUDO_USER:-$USER}" -REAL_HOME="$(getent passwd "$REAL_USER" | cut -d: -f6)" - -REPO="https://github.com/corecollectives/mist" -BRANCH="release" -APP_NAME="mist" -INSTALL_DIR="/opt/mist" -GO_BACKEND_DIR="server" -GO_BINARY_NAME="mist" -PORT=8080 -MIST_FILE="/var/lib/mist/mist.db" -SERVICE_FILE="/etc/systemd/system/$APP_NAME.service" - -SPINNER_PID="" -SUDO_KEEPALIVE_PID="" - -export PATH="/usr/local/go/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH" - -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' - -log() { echo -e "${GREEN}[INFO]${NC} $1" | tee -a "$LOG_FILE"; } -warn() { echo -e "${YELLOW}[WARN]${NC} $1" | tee -a "$LOG_FILE"; } -error() { echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"; } - -spinner() { - local i=0 chars='|/-\' - while :; do - i=$(( (i + 1) % 4 )) - printf "\r⏳ %c" "${chars:$i:1}" - sleep 0.1 - done -} - -run_step() { - printf "\n▶ $1\n" - spinner & SPINNER_PID=$! - if bash -c "$2" >>"$LOG_FILE" 2>&1; then - kill "$SPINNER_PID" 2>/dev/null || true - wait "$SPINNER_PID" 2>/dev/null || true - printf "\r\033[K✔ Done\n" - return 0 - else - kill "$SPINNER_PID" 2>/dev/null || true - wait "$SPINNER_PID" 2>/dev/null || true - printf "\r\033[K✘ Failed\n" - return 1 - fi -} - -cleanup() { - kill "$SPINNER_PID" 2>/dev/null || true - kill "$SUDO_KEEPALIVE_PID" 2>/dev/null || true -} -trap cleanup EXIT - -rollback() { - error "Installation failed! Cleaning up..." - if [ -f "$SERVICE_FILE" ]; then - sudo systemctl stop "$APP_NAME" 2>>"$LOG_FILE" || true - sudo systemctl disable "$APP_NAME" 2>>"$LOG_FILE" || true - sudo rm -f "$SERVICE_FILE" 2>>"$LOG_FILE" || true - fi - error "Check logs: $LOG_FILE" - tail -30 "$LOG_FILE" 2>/dev/null - cleanup - exit 1 -} - -trap - ERR -log "Starting Mist installation..." - -if [ "$EUID" -ne 0 ] && [ -z "${SUDO_USER:-}" ]; then - error "This script requires sudo. Run: sudo bash install.sh" - exit 1 -fi - -echo "🔐 Verifying sudo access..." -sudo -v || exit 1 - -(while true; do sleep 60; sudo -n true || exit; done) 2>/dev/null & -SUDO_KEEPALIVE_PID=$! - -log "Checking disk space..." -AVAILABLE=$(df /opt 2>/dev/null | tail -1 | awk '{print $4}' || echo "0") -if [ "$AVAILABLE" -lt 2000000 ]; then - error "Need at least 2GB free in /opt" - exit 1 -fi - -log "Checking network..." -if ! curl -s --connect-timeout 10 https://github.com >/dev/null 2>&1; then - error "No network connectivity" - exit 1 -fi - -trap rollback ERR - -log "Installing dependencies..." -if command -v apt >/dev/null 2>&1; then - run_step "Installing packages (apt)" "sudo DEBIAN_FRONTEND=noninteractive apt update && sudo DEBIAN_FRONTEND=noninteractive apt install -y git curl build-essential wget unzip" || exit 1 -elif command -v dnf >/dev/null 2>&1; then - run_step "Installing packages (dnf)" "sudo dnf install -y git curl gcc make wget unzip" || exit 1 -elif command -v yum >/dev/null 2>&1; then - run_step "Installing packages (yum)" "sudo yum install -y git curl gcc make wget unzip" || exit 1 -elif command -v pacman >/dev/null 2>&1; then - run_step "Installing packages (pacman)" "sudo pacman -Sy --noconfirm git curl base-devel wget unzip" || exit 1 -else - error "Unsupported package manager" - exit 1 -fi - -if ! command -v docker >/dev/null 2>&1; then - error "Docker not found. Install from: https://docs.docker.com/engine/install/" - exit 1 -fi -if ! docker ps >/dev/null 2>&1; then - error "Docker not running or no permissions" - exit 1 -fi -log "Docker verified" - -if ! command -v go >/dev/null 2>&1; then - ARCH=$(uname -m) - case "$ARCH" in - x86_64) GO_ARCH="amd64";; - aarch64|arm64) GO_ARCH="arm64";; - armv7l) GO_ARCH="armv6l";; - *) error "Unsupported arch: $ARCH"; exit 1;; - esac - - run_step "Downloading Go" "wget -q https://go.dev/dl/go1.22.11.linux-${GO_ARCH}.tar.gz -O /tmp/go.tar.gz" || exit 1 - run_step "Installing Go" "sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf /tmp/go.tar.gz && rm -f /tmp/go.tar.gz" || exit 1 - - grep -q '/usr/local/go/bin' "$REAL_HOME/.bashrc" 2>/dev/null || echo 'export PATH=$PATH:/usr/local/go/bin' >>"$REAL_HOME/.bashrc" - export PATH="$PATH:/usr/local/go/bin" -fi -go version >>"$LOG_FILE" 2>&1 || { error "Go not working"; exit 1; } -log "Go ready" - -# ---------------- Repo ---------------- - -if [ -d "$INSTALL_DIR/.git" ]; then - log "Updating repository..." - cd "$INSTALL_DIR" - git config --local advice.detachedHead false 2>&1 || true - run_step "Fetching $BRANCH" "cd '$INSTALL_DIR' && git fetch origin '$BRANCH' && git reset --hard origin/'$BRANCH'" || exit 1 -else - run_step "Creating directory" "sudo mkdir -p '$INSTALL_DIR' && sudo chown '$REAL_USER:$REAL_USER' '$INSTALL_DIR'" || exit 1 - run_step "Cloning repository" "git clone -b '$BRANCH' --single-branch --depth 1 '$REPO' '$INSTALL_DIR'" || exit 1 -fi - -[ -d "$INSTALL_DIR/$GO_BACKEND_DIR" ] || { error "Server directory missing"; exit 1; } - -run_step "Setting ownership" "sudo chown -R root:root '$INSTALL_DIR'" || exit 1 - -sudo git config --global --add safe.directory "$INSTALL_DIR" >>"$LOG_FILE" 2>&1 || true - -log "Repository ready" - -run_step "Creating data directories" "sudo mkdir -p /var/lib/mist/{traefik,logs,backups} && sudo touch '$MIST_FILE' && sudo chown -R root:root /var/lib/mist && sudo chmod -R 755 /var/lib/mist" || exit 1 -run_step "Creating Traefik config" "sudo tee /var/lib/mist/traefik/dynamic.yml >/dev/null <<'EOF' -http: - routers: {} - services: {} -EOF -" || exit 1 - -cd "$INSTALL_DIR/$GO_BACKEND_DIR" -[ -f "go.mod" ] || { error "go.mod missing"; exit 1; } -run_step "Downloading dependencies" "cd '$INSTALL_DIR/$GO_BACKEND_DIR' && go mod download && go mod tidy" || exit 1 -run_step "Building backend" "cd '$INSTALL_DIR/$GO_BACKEND_DIR' && go build -v -o '$GO_BINARY_NAME'" || exit 1 -[ -f "$GO_BINARY_NAME" ] || { error "Binary not created"; exit 1; } -chmod +x "$GO_BINARY_NAME" -log "Build complete" - -# ---------------- CLI Tool ---------------- - -if [ -d "$INSTALL_DIR/cli" ]; then - if run_step "Building CLI tool" "cd '$INSTALL_DIR/cli' && go mod tidy && go build -o mist-cli"; then - if run_step "Installing CLI tool" "sudo cp '$INSTALL_DIR/cli/mist-cli' /usr/local/bin/mist-cli && sudo chmod +x /usr/local/bin/mist-cli"; then - log "CLI tool installed: mist-cli" - else - warn "Failed to install CLI tool, but continuing..." - fi - else - warn "Failed to build CLI tool, but continuing..." - fi -fi - -run_step "Creating systemd service" "sudo tee '$SERVICE_FILE' >/dev/null <<'EOF' -[Unit] -Description=Mist Service -After=network.target docker.service -Requires=docker.service - -[Service] -WorkingDirectory=/opt/mist/server -ExecStart=/opt/mist/server/mist -Restart=always -RestartSec=5 -User=root -Environment=PORT=8080 -Environment=PATH=/usr/local/go/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin - -[Install] -WantedBy=multi-user.target -EOF -" || exit 1 - -if sudo systemctl is-active --quiet "$APP_NAME" 2>/dev/null; then - log "Service already running, restarting..." - run_step "Restarting service" "sudo systemctl daemon-reload && sudo systemctl restart '$APP_NAME'" || exit 1 -else - run_step "Starting service" "sudo systemctl daemon-reload && sudo systemctl enable '$APP_NAME' && sudo systemctl start '$APP_NAME'" || exit 1 -fi -sleep 3 -sudo systemctl is-active --quiet "$APP_NAME" || { error "Service failed to start"; sudo journalctl -u "$APP_NAME" -n 20; exit 1; } -log "Service running" - -[ -f "$INSTALL_DIR/traefik-compose.yml" ] || { error "traefik-compose.yml missing"; exit 1; } -run_step "Creating Docker network" "docker network inspect traefik-net >/dev/null 2>&1 || docker network create traefik-net" || warn "Network creation failed" -run_step "Starting Traefik" "docker compose -f '$INSTALL_DIR/traefik-compose.yml' up -d" || warn "Traefik failed" - -if command -v ufw >/dev/null 2>&1; then - sudo ufw allow $PORT/tcp 2>&1 || true -elif command -v firewall-cmd >/dev/null 2>&1; then - sudo firewall-cmd --permanent --add-port=${PORT}/tcp 2>&1 || true - sudo firewall-cmd --reload 2>&1 || true -fi - -log "Running health check..." -sleep 5 -HTTP_OK=false -for i in {1..10}; do - if curl -f -s -o /dev/null "http://localhost:$PORT/api/health" 2>>"$LOG_FILE"; then - HTTP_OK=true - break - fi - sleep 2 -done -[ "$HTTP_OK" = true ] && log "HTTP check passed" || warn "HTTP check failed (may still be initializing)" - -SERVER_IP=$(curl -fsSL https://api.ipify.org 2>/dev/null || hostname -I | awk '{print $1}') -CLI_INSTALLED="" -if [ -f "/usr/local/bin/mist-cli" ]; then - CLI_INSTALLED="║ 💻 CLI Tool: mist-cli --help ║" -fi - -echo -echo "╔════════════════════════════════════════════╗" -echo "║ 🎉 Mist installation complete ║" -printf "║ 👉 %-40s║\n" "http://$SERVER_IP:$PORT" -if [ -n "$CLI_INSTALLED" ]; then - printf "║ %-42s ║\n" "$CLI_INSTALLED" -fi -echo "╚════════════════════════════════════════════╝" -echo -echo "📄 Logs: $LOG_FILE" -echo "🔧 Service: sudo systemctl status $APP_NAME" -echo "📋 Logs: sudo journalctl -u $APP_NAME -f" -if [ -f "/usr/local/bin/mist-cli" ]; then - echo "💻 CLI Tool: mist-cli --help" -fi diff --git a/www/docs/public/mist.png b/www/docs/public/mist.png deleted file mode 100644 index 0c9c10be5da61ac33daeb66a61a697aba15b2972..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58009 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 PLRe}_+KM#_R$u=gGNMu{ diff --git a/www/docs/troubleshooting/forgot-password.md b/www/docs/troubleshooting/forgot-password.md deleted file mode 100644 index e376aac..0000000 --- a/www/docs/troubleshooting/forgot-password.md +++ /dev/null @@ -1,381 +0,0 @@ -# Forgot Password Recovery - -Step-by-step guide to recover access when you've forgotten your password. - ---- - -## Overview - -If you've forgotten your Mist password, you can reset it using the `mist-cli` command-line tool. This tool provides direct database access to change user passwords without requiring dashboard access. - -::: warning Server Access Required -You need SSH or direct access to the server where Mist is installed to use this method. -::: - ---- - -## Quick Recovery Steps - -### 1. SSH into Your Server - -Connect to your server where Mist is installed: - -```bash -ssh user@your-server-ip -``` - -### 2. Reset Password Using CLI - -Run the password reset command: - -```bash -sudo mist-cli user change-password --username YOUR_USERNAME -``` - -You'll be prompted to enter and confirm your new password: - -``` -Enter new password: -Confirm new password: -✓ Password changed successfully for user 'YOUR_USERNAME' -``` - -### 3. Log Back In - -Navigate to your Mist dashboard and log in with your new password: - -``` -https://your-mist-domain.com -``` - ---- - -## Detailed Instructions - -### For Admin Users - -If you're the admin and forgot the admin password: - -```bash -# SSH to server -ssh user@your-server-ip - -# Reset admin password -sudo mist-cli user change-password --username admin - -# Enter and confirm new password when prompted -``` - -**Example session:** -```bash -$ sudo mist-cli user change-password --username admin -Enter new password: **************** -Confirm new password: **************** -✓ Password changed successfully for user 'admin' -``` - -### For Other Users - -If you're helping another user who forgot their password: - -```bash -# First, list all users to verify the username -sudo mist-cli user list - -# Output: -# Users: -# ---------------------------------------------- -# ID Username Email Role -# ---------------------------------------------- -# 1 admin admin@example.com owner -# 2 developer dev@example.com member -# ---------------------------------------------- - -# Reset the specific user's password -sudo mist-cli user change-password --username developer -``` - ---- - -## Non-Interactive Mode - -If you need to reset a password in a script or automation, you can provide the password directly: - -```bash -sudo mist-cli user change-password --username admin --password NewSecurePass123 -``` - -::: warning Security Notice -Using the `--password` flag will expose the password in: -- Shell history -- Process list (visible via `ps` command) -- Log files - -Use this method only when necessary and clear your shell history afterward: -```bash -history -c -``` -::: - ---- - -## Troubleshooting - -### CLI Command Not Found - -**Error:** -```bash -mist-cli: command not found -``` - -**Solution:** - -Check if the CLI is installed: -```bash -ls -la /usr/local/bin/mist-cli -``` - -If not found, rebuild and install the CLI: -```bash -cd /opt/mist/cli -sudo go build -o mist-cli -sudo cp mist-cli /usr/local/bin/ -sudo chmod +x /usr/local/bin/mist-cli - -# Verify installation -mist-cli version -``` - -### Permission Denied - -**Error:** -```bash -Error: open /var/lib/mist/mist.db: permission denied -``` - -**Solution:** - -Run the command with `sudo`: -```bash -sudo mist-cli user change-password --username admin -``` - -### Database Not Found - -**Error:** -```bash -Error: database file not found at /var/lib/mist/mist.db -``` - -**Solution:** - -Verify Mist is installed and running: -```bash -# Check service status -sudo systemctl status mist - -# Check if database file exists -ls -la /var/lib/mist/mist.db - -# If service is not running, start it -sudo systemctl start mist -``` - -### User Not Found - -**Error:** -```bash -Error: User 'johndoe' not found -``` - -**Solution:** - -List all users to find the correct username: -```bash -sudo mist-cli user list -``` - -Usernames are case-sensitive, so ensure you're using the exact username as shown in the list. - -### Passwords Don't Match - -**Error:** -```bash -Error: Passwords do not match -``` - -**Solution:** - -When entering passwords in interactive mode, make sure you type the same password twice. If you keep getting this error: - -1. Copy your desired password to clipboard -2. Paste it when prompted for "Enter new password" -3. Paste it again when prompted for "Confirm new password" - -Or use non-interactive mode: -```bash -sudo mist-cli user change-password --username admin --password YourNewPassword123 -``` - ---- - -## Security Best Practices - -### After Password Reset - -1. **Clear shell history** if you used non-interactive mode: -```bash -history -c -``` - -2. **Use a strong password:** - - At least 12 characters - - Mix of uppercase, lowercase, numbers, and symbols - - Avoid common words or patterns - -3. **Consider using a password manager** like: - - Bitwarden - - 1Password - - KeePassXC - -### Prevent Future Lockouts - -1. **Store passwords securely:** - - Use a password manager - - Keep encrypted backup of credentials - - Document recovery procedures - -2. **Set up multiple admin accounts:** -```bash -# Create a backup admin account (via dashboard) -# Or add an additional user with owner role -``` - -3. **Keep SSH access secure:** - - Use SSH keys instead of passwords - - Document server access procedures - - Maintain backup access methods - ---- - -## Alternative Recovery Methods - -### If You Don't Have Server Access - -If you cannot access the server directly, you'll need to: - -1. **Contact your hosting provider** or system administrator -2. **Access the server console** through your cloud provider's dashboard (AWS, DigitalOcean, etc.) -3. **Use server recovery mode** if available - -### If CLI is Not Available - -If the CLI tool is not installed or not working, you can reset the password directly in the database: - -::: danger Advanced Users Only -Direct database manipulation can corrupt your data. Use the CLI method when possible. -::: - -```bash -# Connect to database -sqlite3 /var/lib/mist/mist.db - -# Generate password hash (use a temporary Go script or online bcrypt generator) -# Then update the database -UPDATE users SET password_hash = 'YOUR_BCRYPT_HASH' WHERE username = 'admin'; -.quit -``` - ---- - -## Testing the New Password - -After resetting your password: - -1. **Open your browser** and navigate to Mist dashboard -2. **Clear browser cookies** (recommended): - - Chrome: Settings → Privacy → Clear browsing data → Cookies - - Firefox: Settings → Privacy → Clear Data → Cookies -3. **Log in** with your username and new password -4. **Verify access** to all dashboard features - ---- - -## Common Scenarios - -### Scenario 1: Locked Out as Only Admin - -```bash -# SSH to server -ssh user@server - -# Reset your admin password -sudo mist-cli user change-password --username admin - -# Log back into dashboard -# https://your-mist-domain.com -``` - -### Scenario 2: Reset Password for Another User - -```bash -# List users first -sudo mist-cli user list - -# Reset specific user's password -sudo mist-cli user change-password --username developer - -# Notify the user of their password reset -``` - -### Scenario 3: Bulk Password Reset - -```bash -# Reset multiple users (requires bash loop) -for user in developer tester; do - sudo mist-cli user change-password --username $user --password TempPassword123 - echo "Reset password for $user" -done - -# Notify users to change their temporary passwords -``` - ---- - -## Getting Help - -If you're still having trouble recovering access: - -### Check Documentation -- [CLI Tool Guide](/guide/cli) - Complete CLI documentation -- [User Management](/guide/users) - User roles and permissions -- [Authentication](/guide/authentication) - Login and security - -### Community Support -- **GitHub Issues:** [github.com/corecollectives/mist/issues](https://github.com/corecollectives/mist/issues) -- **Discord:** [discord.gg/kxK8XHR6](https://discord.gg/kxK8XHR6) - -### Provide This Information -When asking for help, include: - -```bash -# Mist version -curl http://localhost:8080/api/updates/version - -# Service status -sudo systemctl status mist - -# CLI version -mist-cli version - -# User list (remove sensitive info) -sudo mist-cli user list -``` - ---- - -## Related Documentation - -- [CLI Tool Guide](/guide/cli) - Full CLI documentation -- [User Management](/guide/users) - Managing users and roles -- [Common Issues](/troubleshooting/) - Other troubleshooting guides diff --git a/www/docs/troubleshooting/index.md b/www/docs/troubleshooting/index.md deleted file mode 100644 index 8609e49..0000000 --- a/www/docs/troubleshooting/index.md +++ /dev/null @@ -1,645 +0,0 @@ -# Troubleshooting Guide - -Common issues and solutions for Mist deployments. - -::: tip Quick Links -- [Forgot Password Recovery](/troubleshooting/forgot-password) - Reset your password using CLI -- [Manual Update Guide](/troubleshooting/manual-update) - Update Mist manually if dashboard update fails -- [Community Support](https://discord.gg/kxK8XHR6) - Get help from the community -::: - ---- - -## Installation Issues - -### Installation Script Fails - -**Problem:** Installation script exits with errors - -**Solutions:** - -1. **Check system requirements:** -```bash -# Verify Docker is installed and running -docker --version -docker ps - -# Check disk space (need at least 2GB) -df -h /opt - -# Verify network connectivity -curl -s https://github.com -``` - -2. **Run with proper permissions:** -```bash -sudo bash install.sh -``` - -3. **Check the installation log:** -```bash -tail -50 /tmp/mist-install.log -``` - -### Go Installation Fails - -**Problem:** Go download or installation fails - -**Solution:** -```bash -# Manually install Go 1.22+ -wget https://go.dev/dl/go1.22.11.linux-amd64.tar.gz -sudo rm -rf /usr/local/go -sudo tar -C /usr/local -xzf go1.22.11.linux-amd64.tar.gz -export PATH=$PATH:/usr/local/go/bin -go version -``` - -### Docker Permission Denied - -**Problem:** Docker commands fail with permission errors - -**Solution:** -```bash -# Add current user to docker group -sudo usermod -aG docker $USER - -# Restart shell or run -newgrp docker - -# Verify -docker ps -``` - ---- - -## Service Issues - -### Mist Service Won't Start - -**Problem:** `systemctl start mist` fails - -**Diagnosis:** -```bash -# Check service status -sudo systemctl status mist - -# View recent logs -sudo journalctl -u mist -n 50 --no-pager - -# Check if port 8080 is already in use -sudo lsof -i :8080 -``` - -**Solutions:** - -1. **Port already in use:** -```bash -# Stop the conflicting service - -# Reload and restart -sudo systemctl daemon-reload -sudo systemctl restart mist -``` - -2. **Database issues:** -```bash -# Check database file permissions -ls -la /var/lib/mist/mist.db - -# Fix permissions if needed -sudo chown root:root /var/lib/mist/mist.db -sudo chmod 644 /var/lib/mist/mist.db -``` - -3. **Binary issues:** -```bash -# Rebuild the binary -cd /opt/mist/server -sudo go build -o mist -sudo systemctl restart mist -``` - -### Service Crashes After Update - -**Problem:** Service won't start after running update - -**Solution:** -```bash -# Check for stuck update logs -sudo journalctl -u mist -n 100 --no-pager | grep -i update - -# If update is stuck, manually clear it using CLI -sudo mist-cli settings list - -# View update logs via API or dashboard -curl http://localhost:8080/api/updates/history - -# Force restart the service -sudo systemctl daemon-reload -sudo systemctl restart mist -``` - ---- - -## Deployment Issues - -### Build Fails - -**Problem:** Application build fails during deployment - -**Diagnosis:** -```bash -# Check build logs in the dashboard -# Or check Docker logs -docker logs -``` - -**Common causes:** - -1. **Missing dependencies:** -```dockerfile -# Add missing dependencies to Dockerfile -RUN npm install -# or -RUN pip install -r requirements.txt -``` - -2. **Wrong build context:** -```dockerfile -# Ensure Dockerfile is in repository root -# Or specify custom path in deployment settings -``` - -3. **Build timeout:** -- Increase timeout in deployment settings -- Optimize Dockerfile with multi-stage builds -- Use build cache effectively - -### Container Keeps Restarting - -**Problem:** Deployed container restarts repeatedly - -**Diagnosis:** -```bash -# View container logs -docker logs - -# Check container status -docker ps -a | grep - -# Inspect container -docker inspect -``` - -**Common solutions:** - -1. **Application crashes on startup:** -- Check environment variables are set correctly -- Verify database connection strings -- Check port configuration - -2. **Health check failures:** -- Ensure health check endpoint returns 200 -- Increase health check timeout -- Verify health check path is correct - -3. **Missing environment variables:** -```bash -# Check via Mist dashboard or API -# Add missing variables in Environment Variables section -``` - -### Port Already in Use - -**Problem:** Deployment fails with "port already allocated" error - -**Solution:** -```bash -# Find conflicting container -docker ps | grep - -# Stop conflicting container -docker stop - -# Or change your app's port in environment variables -``` - ---- - -## Domain & SSL Issues - -### Domain Not Resolving - -**Problem:** Custom domain doesn't point to your application - -**Checklist:** - -1. **DNS Configuration:** -```bash -# Verify DNS records -dig yourdomain.com -nslookup yourdomain.com - -# Should point to your server IP -# A record: yourdomain.com -> your-server-ip -``` - -2. **Wildcard domain setup:** -```bash -# Verify wildcard domain setting -mist-cli settings get --key wildcard_domain - -# Should be set to your domain -mist-cli settings set --key wildcard_domain --value apps.example.com -``` - -3. **Traefik configuration:** -```bash -# Check Traefik is running -docker ps | grep traefik - -# Restart Traefik if needed -cd /opt/mist -docker compose -f traefik-compose.yml restart -``` - -### SSL Certificate Issues - -**Problem:** SSL certificate not generating or invalid - -**Diagnosis:** -```bash -# Check Traefik logs -docker logs traefik - -# Verify domain is accessible -curl -v https://yourdomain.com -``` - -**Solutions:** - -1. **Let's Encrypt rate limit:** -- Wait 1 hour (for failures) or 1 week (for cert limit) -- Use staging environment for testing - -2. **DNS not propagated:** -```bash -# Wait for DNS propagation (up to 48 hours) -# Check propagation status -dig +trace yourdomain.com -``` - -3. **Firewall blocking ports:** -```bash -# Ensure ports 80 and 443 are open -sudo ufw status -sudo ufw allow 80/tcp -sudo ufw allow 443/tcp -``` - ---- - -## Database Issues - -### Cannot Connect to Database - -**Problem:** Application can't connect to database service - -**Solutions:** - -1. **Verify database is running:** -```bash -docker ps | grep postgres -# or -docker ps | grep mysql -``` - -2. **Check connection string:** -- Ensure environment variables are correct -- Format: `postgresql://user:password@host:5432/dbname` -- Host should be the container name - -3. **Network issues:** -```bash -# Verify containers are on same network -docker network inspect traefik-net -``` - -### Database Data Lost After Restart - -**Problem:** Data disappears when container restarts - -**Solution:** -- Ensure volumes are properly configured -- Check volume mounts: -```bash -docker inspect | grep -A 10 Mounts -``` - ---- - -## GitHub Integration Issues - -### GitHub App Not Connecting - -**Problem:** Cannot connect GitHub repositories - -**Diagnosis:** -1. Verify GitHub App is installed on your organization/account -2. Check webhook delivery in GitHub App settings -3. Ensure webhook URL is accessible from internet - -**Solution:** -```bash -# Verify GitHub App settings in Mist dashboard -# Go to Settings -> Git - -# Test webhook: -curl -X POST https://your-mist-domain.com/api/github/webhook \ - -H "Content-Type: application/json" \ - -d '{"action": "ping"}' -``` - -### Webhook Delivery Fails - -**Problem:** GitHub webhooks not reaching Mist - -**Solutions:** - -1. **Firewall blocking webhooks:** -```bash -# Ensure Mist is accessible from internet -# Check if your server has public IP -curl ifconfig.me -``` - -2. **Wrong webhook URL:** -- Update in GitHub App settings -- Format: `https://your-mist-domain.com/api/github/webhook` - ---- - -## Performance Issues - -### Slow Dashboard Loading - -**Problem:** Dashboard takes long to load - -**Solutions:** - -1. **Check system resources:** -```bash -# View CPU and memory usage -htop - -# Check disk space -df -h - -# View container resource usage -docker stats -``` - -2. **Too many logs:** -```bash -# Clean up old logs -sudo find /var/lib/mist/logs -type f -mtime +7 -delete -``` - -3. **Database optimization:** -```bash -# Vacuum SQLite database -sqlite3 /var/lib/mist/mist.db "VACUUM;" -``` - -### High CPU Usage - -**Problem:** Server CPU constantly high - -**Diagnosis:** -```bash -# Check which process is using CPU -top -bn1 | head -20 - -# Check Docker container CPU -docker stats --no-stream -``` - -**Solutions:** - -1. **Too many containers:** -- Enable auto cleanup in settings -- Manually clean stopped containers: -```bash -docker container prune -f -``` - -2. **Container resource limits:** -- Set CPU/memory limits in deployment settings - ---- - -## Update Issues - -::: tip Manual Update Available -If you're experiencing issues with dashboard updates, you can [update manually using the install script](/troubleshooting/manual-update). -::: - -### Update Stuck in Progress - -**Problem:** Update shows "in progress" but nothing happens - -**Solution:** -```bash -# Check if update process is actually running -ps aux | grep install.sh - -# If not running, the startup check should auto-resolve it -# Force restart to trigger the check -sudo systemctl restart mist - -# Alternatively, manually clear stuck update via API -# (requires owner access) -curl -X POST http://localhost:8080/api/updates/clear?id= \ - --cookie "session_token=your_token" -``` - -**Or perform a manual update:** -```bash -# See full manual update guide -curl -fsSL https://trymist.cloud/install.sh | sudo bash -``` - -[→ Full Manual Update Guide](/troubleshooting/manual-update) - -### Update Failed - -**Problem:** Update failed and service won't start - -**Solution:** -```bash -# Check update logs -sudo journalctl -u mist -n 100 --no-pager - -# Revert to previous version if needed -cd /opt/mist -git log --oneline -10 -sudo git reset --hard -cd server -sudo go build -o mist -sudo systemctl restart mist -``` - -**Or perform a manual update with automatic recovery:** -```bash -curl -fsSL https://trymist.cloud/install.sh | sudo bash -``` - -[→ Full Manual Update Guide](/troubleshooting/manual-update) - ---- - -## CLI Issues - -### CLI Command Not Found - -**Problem:** `mist-cli` command not found - -**Solution:** -```bash -# Check if CLI is installed -ls -la /usr/local/bin/mist-cli - -# If not found, rebuild and install -cd /opt/mist/cli -sudo go build -o mist-cli -sudo cp mist-cli /usr/local/bin/ -sudo chmod +x /usr/local/bin/mist-cli -``` - -### CLI Database Access Denied - -**Problem:** CLI can't access database - -**Solution:** -```bash -# Run with sudo -sudo mist-cli user list - -# Or fix database permissions -sudo chown root:root /var/lib/mist/mist.db -sudo chmod 644 /var/lib/mist/mist.db -``` - ---- - -## Network Issues - -### Cannot Access Dashboard - -**Problem:** Cannot reach Mist dashboard in browser - -**Checklist:** - -1. **Service running:** -```bash -sudo systemctl status mist -curl http://localhost:8080/api/health -``` - -2. **Firewall:** -```bash -# Check firewall rules -sudo ufw status - -# Allow port 8080 -sudo ufw allow 8080/tcp -``` - -3. **Port forwarding:** -- If behind NAT, ensure port forwarding is configured -- Check router/cloud provider settings - -### Applications Not Accessible - -**Problem:** Deployed apps return 404 or 502 errors - -**Diagnosis:** -```bash -# Check Traefik logs -docker logs traefik - -# Verify Traefik config -cat /var/lib/mist/traefik/dynamic.yml - -# Check app container is running -docker ps | grep -``` - -**Solutions:** - -1. **Traefik not running:** -```bash -cd /opt/mist -docker compose -f traefik-compose.yml up -d -``` - -2. **Wrong domain configuration:** -- Verify domain is correctly set in Mist dashboard -- Check DNS points to your server - -3. **Container not in traefik-net:** -```bash -docker network connect traefik-net -``` - ---- - -## Getting More Help - -If you're still experiencing issues: - -1. **Check logs:** -```bash -# Service logs -sudo journalctl -u mist -n 100 --no-pager - -# Container logs -docker logs - -# Traefik logs -docker logs traefik -``` - -2. **Enable debug logging:** -```bash -# Edit service file -sudo nano /etc/systemd/system/mist.service - -# Add debug environment variable -Environment=LOG_LEVEL=debug - -# Restart -sudo systemctl daemon-reload -sudo systemctl restart mist -``` - -3. **Community support:** -- GitHub Issues: [github.com/corecollectives/mist/issues](https://github.com/corecollectives/mist/issues) -- Discord: [discord.gg/kxK8XHR6](https://discord.gg/hr6TCQDDkj) - -4. **Gather diagnostic information:** -```bash -# System info -uname -a -docker version -docker compose version - -# Mist version -curl http://localhost:8080/api/updates/version - -# Resource usage -free -h -df -h -docker stats --no-stream -``` diff --git a/www/docs/troubleshooting/manual-update.md b/www/docs/troubleshooting/manual-update.md deleted file mode 100644 index 62c9ad7..0000000 --- a/www/docs/troubleshooting/manual-update.md +++ /dev/null @@ -1,628 +0,0 @@ -# Manual Update Guide - -Step-by-step guide to manually update Mist when the dashboard update fails or gets stuck. - ---- - -## Overview - -If you're experiencing issues updating Mist through the dashboard, you can perform a manual update using the same installation script. This method is safe and will preserve all your data, applications, and settings. - -::: tip Safe Update Process -The installation script is designed to be idempotent - you can run it multiple times safely. It will: -- ✅ Preserve your database and all data -- ✅ Keep all applications and deployments running -- ✅ Maintain your settings and configurations -- ✅ Update only the Mist binary and system files -::: - ---- - -## When to Use Manual Update - -Use manual update when: -- Dashboard update gets stuck in "in progress" state -- Update fails with errors in the dashboard -- Service won't restart after an update -- You want to update from a specific Git branch -- You need to rollback to a previous version - ---- - -## Quick Update Steps - -### 1. SSH into Your Server - -```bash -ssh user@your-server-ip -``` - -### 2. Run the Installation Script - -The same script used for installation will update your existing installation: - -```bash -curl -fsSL https://trymist.cloud/install.sh | sudo bash -``` - -That's it! The script will: -1. Detect your existing installation -2. Update the repository to the latest version -3. Rebuild the binary -4. Restart the service -5. Verify everything is working - -### 3. Verify Update - -```bash -# Check service status -sudo systemctl status mist - -# Check version -curl http://localhost:8080/api/updates/version - -# Access dashboard -# https://your-mist-domain.com -``` - ---- - -## Detailed Manual Update Process - -### Step 1: Prepare for Update - -Before updating, it's good practice to check the current state: - -```bash -# Check current version -curl http://localhost:8080/api/updates/version - -# Check service status -sudo systemctl status mist - -# View current running containers -docker ps -``` - -### Step 2: Run the Update Script - -Execute the installation script with sudo: - -```bash -curl -fsSL https://trymist.cloud/install.sh | sudo bash -``` - -**What the script does:** -1. Checks system requirements -2. Updates Git repository from the `release` branch -3. Downloads Go dependencies -4. Builds the new binary -5. Restarts the Mist service -6. Verifies the service is running - -**Expected output:** -``` -Starting Mist installation... -▶ Updating repository... -✔ Done -▶ Downloading dependencies... -✔ Done -▶ Building backend... -✔ Done -▶ Restarting service... -✔ Done -╔════════════════════════════════════════════╗ -║ 🎉 Mist installation complete ║ -║ 👉 http://your-server-ip:8080 ║ -╚════════════════════════════════════════════╝ -``` - -### Step 3: Verify the Update - -After the script completes: - -1. **Check service is running:** -```bash -sudo systemctl status mist -``` - -Expected output: `Active: active (running)` - -2. **Verify new version:** -```bash -curl http://localhost:8080/api/updates/version -``` - -3. **Check service logs:** -```bash -sudo journalctl -u mist -n 50 --no-pager -``` - -4. **Test dashboard access:** - - Open your browser - - Navigate to your Mist dashboard - - Log in and verify functionality - -5. **Check applications:** - - Verify all applications are still running - - Check deployment history - - Test application access - ---- - -## Handling Update Issues - -### Update Script Fails - -If the update script encounters errors: - -**1. Check the installation log:** -```bash -tail -100 /tmp/mist-install.log -``` - -**2. Common issues:** - -#### Port Already in Use -```bash -# Stop Mist service first -sudo systemctl stop mist - -# Run update script -curl -fsSL https://trymist.cloud/install.sh | sudo bash -``` - -#### Git Conflicts -```bash -# Navigate to installation directory -cd /opt/mist - -# Reset any local changes -sudo git reset --hard - -# Run update script again -curl -fsSL https://trymist.cloud/install.sh | sudo bash -``` - -#### Build Failures -```bash -# Clear Go cache -sudo go clean -cache -modcache - -# Rebuild manually -cd /opt/mist/server -sudo go mod tidy -sudo go build -o mist - -# Restart service -sudo systemctl restart mist -``` - -### Service Won't Start After Update - -If Mist service fails to start after update: - -**1. Check service status and logs:** -```bash -sudo systemctl status mist -sudo journalctl -u mist -n 100 --no-pager -``` - -**2. Check for common issues:** - -#### Database Locked -```bash -# Stop service -sudo systemctl stop mist - -# Check for processes using database -sudo lsof /var/lib/mist/mist.db - -# Kill any stale processes if found -sudo pkill -9 mist - -# Start service -sudo systemctl start mist -``` - -#### Binary Not Executable -```bash -# Make binary executable -sudo chmod +x /opt/mist/server/mist - -# Restart service -sudo systemctl restart mist -``` - -#### Missing Dependencies -```bash -# Reinstall dependencies -cd /opt/mist/server -sudo go mod download -sudo go build -o mist -sudo systemctl restart mist -``` - -### Applications Not Working After Update - -If your applications are inaccessible after update: - -**1. Check Traefik is running:** -```bash -docker ps | grep traefik -``` - -**2. Restart Traefik if needed:** -```bash -cd /opt/mist -docker compose -f traefik-compose.yml restart -``` - -**3. Check application containers:** -```bash -docker ps -a -``` - -**4. Restart specific containers if needed:** -```bash -docker restart -``` - ---- - -## Update from Specific Version or Branch - -### Update from Specific Git Branch - -To update from a different branch (e.g., `main`, `develop`): - -```bash -# Navigate to installation directory -cd /opt/mist - -# Switch to desired branch -sudo git fetch origin -sudo git checkout -sudo git pull origin - -# Build and restart -cd server -sudo go mod tidy -sudo go build -o mist -sudo systemctl restart mist -``` - -### Rollback to Previous Version - -If the new update causes issues, you can rollback: - -**1. View recent versions:** -```bash -cd /opt/mist -git log --oneline -10 -``` - -**2. Rollback to specific commit:** -```bash -# Replace with desired version -sudo git reset --hard - -# Rebuild -cd server -sudo go build -o mist - -# Restart -sudo systemctl restart mist -``` - -**3. Rollback to previous release tag:** -```bash -# View available tags -git tag -l - -# Checkout specific tag -sudo git checkout tags/v1.0.0 - -# Rebuild and restart -cd server -sudo go build -o mist -sudo systemctl restart mist -``` - ---- - -## Clearing Stuck Updates - -If a dashboard update is stuck in "in progress" state: - -### Method 1: Restart Service (Automatic Fix) - -Simply restart the Mist service - the startup check will automatically resolve stuck updates: - -```bash -sudo systemctl restart mist -``` - -The system will: -- Check for stuck updates on startup -- Compare current version with target version -- Mark update as success if versions match -- Mark as failed if versions don't match - -### Method 2: Manual Fix Using CLI - -Clear the stuck update manually: - -**1. List update history:** -```bash -# Check update logs via dashboard or: -curl http://localhost:8080/api/updates/history -``` - -**2. Clear stuck update:** - -Via API (requires authentication): -```bash -# Note: You need to be logged in and get the update_log_id -curl -X POST "http://localhost:8080/api/updates/clear?id=" \ - --cookie "session_token=your_session_token" -``` - -### Method 3: Complete Manual Update - -Perform a complete manual update which will automatically fix the stuck state: - -```bash -# Run installation script -curl -fsSL https://trymist.cloud/install.sh | sudo bash - -# Service restart will resolve stuck update -``` - ---- - -## Update Best Practices - -### Before Updating - -1. **Backup database:** -```bash -# Create backup directory -sudo mkdir -p /var/lib/mist/backups - -# Copy database -sudo cp /var/lib/mist/mist.db /var/lib/mist/backups/mist.db.$(date +%Y%m%d_%H%M%S) -``` - -2. **Check disk space:** -```bash -df -h /opt -``` - -3. **Note current version:** -```bash -curl http://localhost:8080/api/updates/version -``` - -4. **Check running applications:** -```bash -docker ps -``` - -### During Update - -1. **Monitor the update process:** -```bash -# In a separate terminal, watch logs -sudo journalctl -u mist -f -``` - -2. **Don't interrupt the process:** - - Let the script complete - - Don't cancel or close the terminal - - Wait for confirmation message - -### After Update - -1. **Verify service health:** -```bash -# Check service -sudo systemctl status mist - -# Check logs for errors -sudo journalctl -u mist -n 50 --no-pager | grep -i error - -# Test health endpoint -curl http://localhost:8080/api/health -``` - -2. **Test critical functionality:** - - Log into dashboard - - Check applications are accessible - - Test deployment (optional) - - Verify domains are working - -3. **Clean up old builds (optional):** -```bash -# Clean Docker resources if needed -docker system prune -f -``` - ---- - -## Automated Update Script - -For convenience, you can create a custom update script: - -```bash -#!/bin/bash -# save as: /usr/local/bin/mist-update - -set -e - -echo "🔄 Starting Mist update..." - -# Backup database -echo "📦 Creating database backup..." -sudo mkdir -p /var/lib/mist/backups -sudo cp /var/lib/mist/mist.db /var/lib/mist/backups/mist.db.$(date +%Y%m%d_%H%M%S) - -# Run update -echo "⬇️ Downloading and installing update..." -curl -fsSL https://trymist.cloud/install.sh | sudo bash - -# Verify -echo "✅ Verifying update..." -sleep 3 -sudo systemctl status mist --no-pager - -echo "🎉 Update complete!" -echo "Current version:" -curl -s http://localhost:8080/api/updates/version | jq -r '.data.version' -``` - -**Make it executable and use it:** -```bash -sudo chmod +x /usr/local/bin/mist-update -sudo mist-update -``` - ---- - -## Update Frequency - -### Recommended Update Schedule - -- **Security updates:** As soon as available -- **Feature updates:** Monthly or as needed -- **Patch updates:** When issues are fixed - -### Check for Available Updates - -**Via Dashboard:** -- Navigate to Settings → Updates -- Click "Check for Updates" - -**Via API:** -```bash -curl http://localhost:8080/api/updates/check -``` - -**Via GitHub:** -- Check [releases page](https://github.com/corecollectives/mist/releases) -- Watch repository for notifications - ---- - -## Maintenance Mode (Optional) - -For minimal downtime during updates: - -**1. Create maintenance page:** -```bash -# Add to Traefik config to show maintenance page -# This is optional - most updates complete in under 30 seconds -``` - -**2. Notify users:** -- Post in team chat -- Send email notification -- Update status page - -**3. Schedule updates:** -- Choose low-traffic periods -- Plan for 5-10 minutes downtime -- Have rollback plan ready - ---- - -## Troubleshooting Specific Errors - -### Error: "go: command not found" - -```bash -# Install Go -wget https://go.dev/dl/go1.22.11.linux-amd64.tar.gz -sudo rm -rf /usr/local/go -sudo tar -C /usr/local -xzf go1.22.11.linux-amd64.tar.gz -export PATH=$PATH:/usr/local/go/bin - -# Run update again -curl -fsSL https://trymist.cloud/install.sh | sudo bash -``` - -### Error: "Permission denied" - -```bash -# Ensure you're using sudo -sudo bash install.sh - -# Or fix ownership -sudo chown -R root:root /opt/mist -sudo chmod -R 755 /opt/mist -``` - -### Error: "Database is locked" - -```bash -# Stop all processes -sudo systemctl stop mist - -# Check for lock -sudo lsof /var/lib/mist/mist.db - -# Kill if needed -sudo pkill -9 mist - -# Restart -sudo systemctl start mist -``` - ---- - -## Getting Help - -If manual update doesn't resolve your issue: - -### Gather Information - -```bash -# System info -uname -a - -# Mist version -curl http://localhost:8080/api/updates/version - -# Service status -sudo systemctl status mist - -# Recent logs -sudo journalctl -u mist -n 100 --no-pager - -# Installation log -tail -50 /tmp/mist-install.log -``` - -### Community Support - -- **GitHub Issues:** [Report update issues](https://github.com/corecollectives/mist/issues) -- **Discord:** [Get real-time help](https://discord.gg/hr6TCQDDkj) -- **Discussions:** [Ask questions](https://github.com/corecollectives/mist/discussions) - -### Include in Bug Report - -When reporting update issues, include: -- Current version and target version -- Complete error messages -- Installation log (`/tmp/mist-install.log`) -- Service logs (`sudo journalctl -u mist -n 100`) -- System information (`uname -a`) - ---- - -## Related Documentation - -- [Upgrading Guide](/deployment/upgrading) - Official upgrade documentation -- [Common Issues](/troubleshooting/) - General troubleshooting -- [Installation Guide](/deployment/installation) - Initial installation -- [Backup & Recovery](/deployment/backup) - Data backup procedures diff --git a/www/package-lock.json b/www/package-lock.json deleted file mode 100644 index e853a69..0000000 --- a/www/package-lock.json +++ /dev/null @@ -1,2475 +0,0 @@ -{ - "name": "www", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "www", - "version": "1.0.0", - "license": "ISC", - "devDependencies": { - "vitepress": "^1.6.4", - "vue": "^3.5.26" - } - }, - "node_modules/@algolia/abtesting": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.12.1.tgz", - "integrity": "sha512-Y+7e2uPe376OH5O73OB1+vR40ZhbV2kzGh/AR/dPCWguoBOp1IK0o+uZQLX+7i32RMMBEKl3pj6KVEav100Kvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/autocomplete-core": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz", - "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", - "@algolia/autocomplete-shared": "1.17.7" - } - }, - "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz", - "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.7" - }, - "peerDependencies": { - "search-insights": ">= 1 < 3" - } - }, - "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz", - "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.7" - }, - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-shared": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz", - "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/client-abtesting": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.46.1.tgz", - "integrity": "sha512-5SWfl0UGuKxMBYlU2Y9BnlIKKEyhFU5jHE9F9jAd8nbhxZNLk0y7fXE+AZeFtyK1lkVw6O4B/e6c3XIVVCkmqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.46.1.tgz", - "integrity": "sha512-496K6B1l/0Jvyp3MbW/YIgmm1a6nkTrKXBM7DoEy9YAOJ8GywGpa2UYjNCW1UrOTt+em1ECzDjRx7PIzTR9YvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-common": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.46.1.tgz", - "integrity": "sha512-3u6AuZ1Kiss6V5JPuZfVIUYfPi8im06QBCgKqLg82GUBJ3SwhiTdSZFIEgz2mzFuitFdW1PQi3c/65zE/3FgIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-insights": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.46.1.tgz", - "integrity": "sha512-LwuWjdO35HHl1rxtdn48t920Xl26Dl0SMxjxjFeAK/OwK/pIVfYjOZl/f3Pnm7Kixze+6HjpByVxEaqhTuAFaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.46.1.tgz", - "integrity": "sha512-6LvJAlfEsn9SVq63MYAFX2iUxztUK2Q7BVZtI1vN87lDiJ/tSVFKgKS/jBVO03A39ePxJQiFv6EKv7lmoGlWtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-query-suggestions": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.46.1.tgz", - "integrity": "sha512-9GLUCyGGo7YOXHcNqbzca82XYHJTbuiI6iT0FTGc0BrnV2N4OcrznUuVKic/duiLSun5gcy/G2Bciw5Sav9f9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-search": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.46.1.tgz", - "integrity": "sha512-NL76o/BoEgU4ObY5oBEC3o6KSPpuXsnSta00tAxTm1iKUWOGR34DQEKhUt8xMHhMKleUNPM/rLPFiIVtfsGU8w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/ingestion": { - "version": "1.46.1", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.46.1.tgz", - "integrity": "sha512-52Nc8WKC1FFXsdlXlTMl1Re/pTAbd2DiJiNdYmgHiikZcfF96G+Opx4qKiLUG1q7zp9e+ahNwXF6ED0XChMywg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/monitoring": { - "version": "1.46.1", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.46.1.tgz", - "integrity": "sha512-1x2/2Y/eqz6l3QcEZ8u/zMhSCpjlhePyizJd3sXrmg031HjayYT5+IxikjpqkdF7TU/deCTd/TFUcxLJ2ZHXiQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/recommend": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.46.1.tgz", - "integrity": "sha512-SSd3KlQuplxV3aRs5+Z09XilFesgpPjtCG7BGRxLTVje5hn9BLmhjO4W3gKw01INUt44Z1r0Fwx5uqnhAouunA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.46.1.tgz", - "integrity": "sha512-3GfCwudeW6/3caKSdmOP6RXZEL4F3GiemCaXEStkTt2Re8f7NcGYAAZnGlHsCzvhlNEuDzPYdYxh4UweY8l/2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-fetch": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.46.1.tgz", - "integrity": "sha512-JUAxYfmnLYTVtAOFxVvXJ4GDHIhMuaP7JGyZXa/nCk3P8RrN5FCNTdRyftSnxyzwSIAd8qH3CjdBS9WwxxqcHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-node-http": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.46.1.tgz", - "integrity": "sha512-VwbhV1xvTGiek3d2pOS6vNBC4dtbNadyRT+i1niZpGhOJWz1XnfhxNboVbXPGAyMJYz7kDrolbDvEzIDT93uUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.5" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@docsearch/css": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz", - "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@docsearch/js": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.8.2.tgz", - "integrity": "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@docsearch/react": "3.8.2", - "preact": "^10.0.0" - } - }, - "node_modules/@docsearch/react": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.2.tgz", - "integrity": "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-core": "1.17.7", - "@algolia/autocomplete-preset-algolia": "1.17.7", - "@docsearch/css": "3.8.2", - "algoliasearch": "^5.14.2" - }, - "peerDependencies": { - "@types/react": ">= 16.8.0 < 19.0.0", - "react": ">= 16.8.0 < 19.0.0", - "react-dom": ">= 16.8.0 < 19.0.0", - "search-insights": ">= 1 < 3" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "search-insights": { - "optional": true - } - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@iconify-json/simple-icons": { - "version": "1.2.63", - "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.63.tgz", - "integrity": "sha512-xZl2UWCwE58VlqZ+pDPmaUhE2tq8MVSTJRr4/9nzzHlDdjJ0Ud1VxNXPrwTSgESKY29iCQw3S0r2nJTSNNngHw==", - "dev": true, - "license": "CC0-1.0", - "dependencies": { - "@iconify/types": "*" - } - }, - "node_modules/@iconify/types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", - "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz", - "integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz", - "integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz", - "integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz", - "integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz", - "integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz", - "integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz", - "integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz", - "integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz", - "integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz", - "integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz", - "integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz", - "integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz", - "integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz", - "integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz", - "integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz", - "integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz", - "integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz", - "integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz", - "integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz", - "integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz", - "integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz", - "integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@shikijs/core": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz", - "integrity": "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/engine-javascript": "2.5.0", - "@shikijs/engine-oniguruma": "2.5.0", - "@shikijs/types": "2.5.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4", - "hast-util-to-html": "^9.0.4" - } - }, - "node_modules/@shikijs/engine-javascript": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz", - "integrity": "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0", - "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^3.1.0" - } - }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz", - "integrity": "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0", - "@shikijs/vscode-textmate": "^10.0.2" - } - }, - "node_modules/@shikijs/langs": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-2.5.0.tgz", - "integrity": "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0" - } - }, - "node_modules/@shikijs/themes": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-2.5.0.tgz", - "integrity": "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0" - } - }, - "node_modules/@shikijs/transformers": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-2.5.0.tgz", - "integrity": "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/core": "2.5.0", - "@shikijs/types": "2.5.0" - } - }, - "node_modules/@shikijs/types": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-2.5.0.tgz", - "integrity": "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", - "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/markdown-it": { - "version": "14.1.2", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", - "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/linkify-it": "^5", - "@types/mdurl": "^2" - } - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/web-bluetooth": { - "version": "0.0.21", - "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", - "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, - "license": "ISC" - }, - "node_modules/@vitejs/plugin-vue": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", - "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "vite": "^5.0.0 || ^6.0.0", - "vue": "^3.2.25" - } - }, - "node_modules/@vue/compiler-core": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.26.tgz", - "integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.5", - "@vue/shared": "3.5.26", - "entities": "^7.0.0", - "estree-walker": "^2.0.2", - "source-map-js": "^1.2.1" - } - }, - "node_modules/@vue/compiler-dom": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz", - "integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/compiler-core": "3.5.26", - "@vue/shared": "3.5.26" - } - }, - "node_modules/@vue/compiler-sfc": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.26.tgz", - "integrity": "sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.5", - "@vue/compiler-core": "3.5.26", - "@vue/compiler-dom": "3.5.26", - "@vue/compiler-ssr": "3.5.26", - "@vue/shared": "3.5.26", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.21", - "postcss": "^8.5.6", - "source-map-js": "^1.2.1" - } - }, - "node_modules/@vue/compiler-ssr": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.26.tgz", - "integrity": "sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.26", - "@vue/shared": "3.5.26" - } - }, - "node_modules/@vue/devtools-api": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.9.tgz", - "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/devtools-kit": "^7.7.9" - } - }, - "node_modules/@vue/devtools-kit": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz", - "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/devtools-shared": "^7.7.9", - "birpc": "^2.3.0", - "hookable": "^5.5.3", - "mitt": "^3.0.1", - "perfect-debounce": "^1.0.0", - "speakingurl": "^14.0.1", - "superjson": "^2.2.2" - } - }, - "node_modules/@vue/devtools-shared": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz", - "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "rfdc": "^1.4.1" - } - }, - "node_modules/@vue/reactivity": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.26.tgz", - "integrity": "sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/shared": "3.5.26" - } - }, - "node_modules/@vue/runtime-core": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.26.tgz", - "integrity": "sha512-xJWM9KH1kd201w5DvMDOwDHYhrdPTrAatn56oB/LRG4plEQeZRQLw0Bpwih9KYoqmzaxF0OKSn6swzYi84e1/Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.26", - "@vue/shared": "3.5.26" - } - }, - "node_modules/@vue/runtime-dom": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.26.tgz", - "integrity": "sha512-XLLd/+4sPC2ZkN/6+V4O4gjJu6kSDbHAChvsyWgm1oGbdSO3efvGYnm25yCjtFm/K7rrSDvSfPDgN1pHgS4VNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.26", - "@vue/runtime-core": "3.5.26", - "@vue/shared": "3.5.26", - "csstype": "^3.2.3" - } - }, - "node_modules/@vue/server-renderer": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.26.tgz", - "integrity": "sha512-TYKLXmrwWKSodyVuO1WAubucd+1XlLg4set0YoV+Hu8Lo79mp/YMwWV5mC5FgtsDxX3qo1ONrxFaTP1OQgy1uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/compiler-ssr": "3.5.26", - "@vue/shared": "3.5.26" - }, - "peerDependencies": { - "vue": "3.5.26" - } - }, - "node_modules/@vue/shared": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz", - "integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@vueuse/core": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.8.2.tgz", - "integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/web-bluetooth": "^0.0.21", - "@vueuse/metadata": "12.8.2", - "@vueuse/shared": "12.8.2", - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/integrations": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-12.8.2.tgz", - "integrity": "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vueuse/core": "12.8.2", - "@vueuse/shared": "12.8.2", - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "async-validator": "^4", - "axios": "^1", - "change-case": "^5", - "drauu": "^0.4", - "focus-trap": "^7", - "fuse.js": "^7", - "idb-keyval": "^6", - "jwt-decode": "^4", - "nprogress": "^0.2", - "qrcode": "^1.5", - "sortablejs": "^1", - "universal-cookie": "^7" - }, - "peerDependenciesMeta": { - "async-validator": { - "optional": true - }, - "axios": { - "optional": true - }, - "change-case": { - "optional": true - }, - "drauu": { - "optional": true - }, - "focus-trap": { - "optional": true - }, - "fuse.js": { - "optional": true - }, - "idb-keyval": { - "optional": true - }, - "jwt-decode": { - "optional": true - }, - "nprogress": { - "optional": true - }, - "qrcode": { - "optional": true - }, - "sortablejs": { - "optional": true - }, - "universal-cookie": { - "optional": true - } - } - }, - "node_modules/@vueuse/metadata": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.8.2.tgz", - "integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/shared": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.8.2.tgz", - "integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==", - "dev": true, - "license": "MIT", - "dependencies": { - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/algoliasearch": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.46.1.tgz", - "integrity": "sha512-39ol8Ulqb3MntofkXHlrcXKyU8BU0PXvQrXPBIX6eXj/EO4VT7651mhGVORI2oF8ydya9nFzT3fYDoqme/KL6w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@algolia/abtesting": "1.12.1", - "@algolia/client-abtesting": "5.46.1", - "@algolia/client-analytics": "5.46.1", - "@algolia/client-common": "5.46.1", - "@algolia/client-insights": "5.46.1", - "@algolia/client-personalization": "5.46.1", - "@algolia/client-query-suggestions": "5.46.1", - "@algolia/client-search": "5.46.1", - "@algolia/ingestion": "1.46.1", - "@algolia/monitoring": "1.46.1", - "@algolia/recommend": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/birpc": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz", - "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/copy-anything": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz", - "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-what": "^5.2.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/emoji-regex-xs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", - "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==", - "dev": true, - "license": "MIT" - }, - "node_modules/entities": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.0.tgz", - "integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, - "node_modules/focus-trap": { - "version": "7.6.6", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.6.tgz", - "integrity": "sha512-v/Z8bvMCajtx4mEXmOo7QEsIzlIOqRXTIwgUfsFOF9gEsespdbD0AkPIka1bSXZ8Y8oZ+2IVDQZePkTfEHZl7Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "tabbable": "^6.3.0" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/hast-util-to-html": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", - "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^3.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hookable": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", - "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-what": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz", - "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/mark.js": { - "version": "8.11.1", - "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", - "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", - "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/minisearch": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.2.0.tgz", - "integrity": "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==", - "dev": true, - "license": "MIT" - }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "dev": true, - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/oniguruma-to-es": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz", - "integrity": "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex-xs": "^1.0.0", - "regex": "^6.0.1", - "regex-recursion": "^6.0.2" - } - }, - "node_modules/perfect-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", - "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/preact": { - "version": "10.28.0", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.0.tgz", - "integrity": "sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - } - }, - "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", - "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-recursion": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", - "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-utilities": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", - "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", - "dev": true, - "license": "MIT" - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/rollup": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz", - "integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.54.0", - "@rollup/rollup-android-arm64": "4.54.0", - "@rollup/rollup-darwin-arm64": "4.54.0", - "@rollup/rollup-darwin-x64": "4.54.0", - "@rollup/rollup-freebsd-arm64": "4.54.0", - "@rollup/rollup-freebsd-x64": "4.54.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", - "@rollup/rollup-linux-arm-musleabihf": "4.54.0", - "@rollup/rollup-linux-arm64-gnu": "4.54.0", - "@rollup/rollup-linux-arm64-musl": "4.54.0", - "@rollup/rollup-linux-loong64-gnu": "4.54.0", - "@rollup/rollup-linux-ppc64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-musl": "4.54.0", - "@rollup/rollup-linux-s390x-gnu": "4.54.0", - "@rollup/rollup-linux-x64-gnu": "4.54.0", - "@rollup/rollup-linux-x64-musl": "4.54.0", - "@rollup/rollup-openharmony-arm64": "4.54.0", - "@rollup/rollup-win32-arm64-msvc": "4.54.0", - "@rollup/rollup-win32-ia32-msvc": "4.54.0", - "@rollup/rollup-win32-x64-gnu": "4.54.0", - "@rollup/rollup-win32-x64-msvc": "4.54.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/search-insights": { - "version": "2.17.3", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", - "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/shiki": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-2.5.0.tgz", - "integrity": "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/core": "2.5.0", - "@shikijs/engine-javascript": "2.5.0", - "@shikijs/engine-oniguruma": "2.5.0", - "@shikijs/langs": "2.5.0", - "@shikijs/themes": "2.5.0", - "@shikijs/types": "2.5.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/speakingurl": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", - "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "dev": true, - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/superjson": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz", - "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "copy-anything": "^4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/tabbable": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.3.0.tgz", - "integrity": "sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vite": { - "version": "5.4.21", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", - "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vitepress": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.6.4.tgz", - "integrity": "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@docsearch/css": "3.8.2", - "@docsearch/js": "3.8.2", - "@iconify-json/simple-icons": "^1.2.21", - "@shikijs/core": "^2.1.0", - "@shikijs/transformers": "^2.1.0", - "@shikijs/types": "^2.1.0", - "@types/markdown-it": "^14.1.2", - "@vitejs/plugin-vue": "^5.2.1", - "@vue/devtools-api": "^7.7.0", - "@vue/shared": "^3.5.13", - "@vueuse/core": "^12.4.0", - "@vueuse/integrations": "^12.4.0", - "focus-trap": "^7.6.4", - "mark.js": "8.11.1", - "minisearch": "^7.1.1", - "shiki": "^2.1.0", - "vite": "^5.4.14", - "vue": "^3.5.13" - }, - "bin": { - "vitepress": "bin/vitepress.js" - }, - "peerDependencies": { - "markdown-it-mathjax3": "^4", - "postcss": "^8" - }, - "peerDependenciesMeta": { - "markdown-it-mathjax3": { - "optional": true - }, - "postcss": { - "optional": true - } - } - }, - "node_modules/vue": { - "version": "3.5.26", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz", - "integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@vue/compiler-dom": "3.5.26", - "@vue/compiler-sfc": "3.5.26", - "@vue/runtime-dom": "3.5.26", - "@vue/server-renderer": "3.5.26", - "@vue/shared": "3.5.26" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/www/package.json b/www/package.json deleted file mode 100644 index 0ff4650..0000000 --- a/www/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "mist-docs", - "version": "1.0.0", - "description": "Documentation for Mist - Self-hostable PaaS", - "type": "module", - "scripts": { - "docs:dev": "vitepress dev docs", - "docs:build": "vitepress build docs", - "docs:preview": "vitepress preview docs" - }, - "keywords": ["mist", "paas", "documentation", "self-hosted"], - "author": "", - "license": "MIT", - "devDependencies": { - "vitepress": "^1.6.4", - "vue": "^3.5.26" - } -} From 09a543a717d2f9696bfbf8df20252bda2789369a Mon Sep 17 00:00:00 2001 From: 07calc Date: Mon, 19 Jan 2026 23:53:32 +0530 Subject: [PATCH 37/48] chore: add www as submodule --- .gitmodules | 3 +++ www | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 www diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..10e796c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "www"] + path = www + url = https://github.com/trymist/www diff --git a/www b/www new file mode 160000 index 0000000..fcfc7bc --- /dev/null +++ b/www @@ -0,0 +1 @@ +Subproject commit fcfc7bcebaf3b6b7a24fbcfdd34b3adebd97d6c0 From 743ccc5b1a4c2ef0b0c0d94ed4941d54f204c112 Mon Sep 17 00:00:00 2001 From: 07calc Date: Mon, 19 Jan 2026 23:54:33 +0530 Subject: [PATCH 38/48] chore: remove bin/ --- bin/mist-cli | Bin 7542560 -> 0 bytes bin/server | Bin 14995920 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 bin/mist-cli delete mode 100755 bin/server diff --git a/bin/mist-cli b/bin/mist-cli deleted file mode 100755 index 9f39b50823d8bf55a74118cb423849aa79709ee7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7542560 zcmeFa3wTpi)<2wH2?(CZMT&p~ELyy_h}sGrQYdf&DHLI}C`z$376lsG1jLIH>Tf4{xYNlq_Ozwdqj&-Xmv zW0jn<*S@c{_F8MNeK`+Ia!pQ6NwFAzsg`e981mfY5Fq($u^jDLE5iJ7Sn@44{N7+0 zW64A~UBDQ_I7f$PeVPbbjHguwEd(=P6@SFj(cw8nge(^0X|#|}J&T^g(cx(uA%n&f z4HbXPm%+DO5yaCWU-ak5M`T9hY0f9=YtjpDx?AScpF0ABMA&$m^AR_mS>r^!XV&Tt z&%DQFkHV+*-stU2MJnbybid4Z=zf{ccplXeVLT0dvK0Pn((&Dt=0J#H`Lr{DKfCy~ zSUTrBs^>eZr#GIBdV1rjw^r1}_g^?=JAdJn?KGZ7J;u|>*8_R@o(wOD5`RYfjOVNm zy$hJ{|7rh9^?X&!Zx-cNEnnH;xkEPJVmys@&erp3s!X7%vVX?&MNx{yVmys@&O|=a z@9X~QWVhU+*Ov@0;j3kd#xq5)fbC@&H zl`ow?^v8@-pa1UAg4d5T{Ve?Bb4sC)WsF*lf!w z@h!`(E2_J()N-My;}ai}57?lSi5` z^ta_Y7Fq1Mj`|dA5E>f`0~phdHwz|KX~)O<4>%fJ>%TE7w=Eo zd&&6X?N`71z`((`et6a8TeoCha_z1s3;*zgmyxa8zXd={-)>?8fOQ9VB}qRa3H)_* zsJn9R1+u$?&q)HW071J;zadF_(%;@qzbccoCz_=E>?GySN&+8|q@1E8^=?U$esYrX zZ%$IqpOe6SNy_}}}Qg3|{_;-@D=lUe+-$>HVHq>&Ru}R8*GYQ<9q?|KJ>KzKcvg2RpznhYj^A9BKPL54U(w=`L zfj^%Fz9I?UK1z~)XOezhog_VVP= zUz()+rAgASNs@kVlJ;t2|lxv^lNRBa{iX2otu)h=kg@!S0}0W;w0rv zO49!8lax>M&W?Yb|7IsCzfY3({5J~d4$nVMQcf&MdoE0p{=OvX42R;TY`>?#p0rcY_V(-9{N-E;F6244_e_Mxd)cf^&9sa6b&T+k+zt!PG^z=5pJx0G4>+tf2Bp#~t^p<(f z*(LK9RMu49v#{1%Su?w2;-cy$m9yvHy{OVMZ{9tNtC!5H_0F&H&YLHbcAL=St*WV< zzhK^cueWC2J(XVMsJO3o;mS(OlKD%jYZp~kdMxgWs>Rg{EJo7Wh4(C;UwfaWc13MP z^%A$Grm}WkZRPx$iYinq^3SWNx^JF){=!8TcTHtwJmX@Yx3W%DR9orwuJBY^@VsXs zN@f#o9AiPr^A{`tkZW#_&s(!%QFR3xa3Av~iPs52FPL|CP4)Z*74vJoaj4_bzkL*d3w8Rz2Npv zctE9s{-Qfph?st`i*`pt*x%{Vi2R?CDrqY9x;06-%T*tKHe?C z56kD12fZ~*Dv+0`BH}?ukhpr$GU<6BS^0LO#phXoj;htw_sy=Ezt~d^)~mEsR4?|- zucO9qJC!98dFC$xrfaGfExH>CJEZ`* z1=v*b0*cH;dmxFv-EBK-s%vYReKa~;=`rP);&M)yIB)c|qw_7sYu=dnYvS$t>*K)d zM<-t4oH4RppGZ9V+8ZF{Q{hue6ThkW<$o#gAf>_+WrXE3-I6IFJ;bkkXFmB~;w>3O zrbt8S)_5)>ZO6KpvS*hxOl#DViBe>U5Tj(7!bp>XH2jbK>G&U28(Z-!=t#qF*Z7?$ z;O^^b*#JFA*yAE>wLGea`!8JBhaRmT>ES<#_)N>wdiZ$}&agbMhie8c>`71D%X;|F zB0kNsTMzp#VSK9PZwT{m%LCFciAD(jm;mCZ$pqJvil|*CcrPO{o~%LLzL zg6EpxM@{eC+`o7=Kn1942}E z&t`(dB#-}Pncx_H@jtr>&M{#8<(S~C+xW{h!7-5HfB7c(1#zgw;xNH6kmG-<34UQ5 zYO$1>;FvYU|H@2o^ZcXS1n(D5jdd{-oc?>`&trlQFo1a0nc!I_c)ba3%oP~jXo6p2 zN*^}C2b7|8Gr_Y= z@H`XTZi0_C!E;RT>rL=n6MT#bo^OIvyBmKF6Z}R4h^K0T-(-T9n&9~+c$o=)vk6{q zf{!)9t4#25Cb-80|CR|}XM#IS@Ol%x$OLaR!6%yFVH3RA1b@;5pJak>G{GmE;Ln)g zX1V&D2|m@7ev1h{%>-{U!Anf=T_(7kdCSOF6TH-v{*Vbi(*!?ig3mU=H52^XCirm^ z{8kgZ-2}hQ1h=e9@PC;JZZ*N@nBX=O{B{#O%LKpE1h<>uhEIagIVSi#Q~F#JyxauO zH^Jwd;0_b~ZWCNJ!7EJgQWJcE30`J`SDN7ECb-)KuQI{!F~L11c-+^5_&O7Op(%a6 z2~J8=AbSu~yZ;!@6DcId;PyfMX+H!>=;Tfj5T5%rkN{hQE>97^Z7C z(kj9)GEA3lq)CLIXE=@F=S2874AX@h*(kz4W0*@6k+2B=fML3FBlRNuD8qE&Mm!?? z5W{qxN6JNb9m90xMoL9^CBt0Wh&V*JhGDvNBe^1cFT-@PN9-beH^X%8MrH3Zw72ydC)1@0}72%s1<`O}qNrXo;OxJGYIT5~+VY+l9 z8%1~o!*u0F!XkVL!*roX>P5IO!*u;eJR;nSVY+xDo!*uCJY$E(N!*u0FEF!$0VY+Z5$N$6r?_t=^@KF)o#xPyB zkya6Ykzu-OBTXXwJj0hU{G15?hGDv9BO68dXAILN8wrc>4;a3j;d&8%l;JBF_K5I9 z4CgRhF2d^=rt3CRD#9xnrpq?s5aAkz>8g$7itxP*(?uJxi}2kH(={8hiSX?V(y88Kw(1@|*}?$uM27k&Ple zf?>K`BViG~gkic`BlRNOmtneCBOVd%#V}o~k#Z4EWtdBLkx~&pTY@lMtPzI@pJbS> z)kv-gf5I?bsu8;gA7i+XVVelQ%`jc75sL`#XP8Syk>lqC{TX&Jd{l(DF-+HLq*a7p zWOxF@O(Og}!xI^PPK1BMFkP#WjUxOrhUrp`ghluV4AYewsTbi#8Kw(0;t}D87*-iB z7vXgbI~gt&;gt+eW!NFYH4M|G8p##mdl_~yY!~6X8K!GBViV!p8Kz4$ViDn67@ooK z@w0;d4AZq5IV!>v7^X`#(kjAtPaS7*hY|i-e`+v&B!!7`0pBRrF*bpT&ZQ*sYQ4|IV(x2|Ve8Ru3;2TiHt%1~K-*nv z;F#+F;CSimNqJ4^UQ0`P(-cc=z*RVK^zTFtrr(|jhPQ0NLaSQHUvEDs?Q|rk((dsJ zL9wITsifVB41X2r*M2GqnF@ThGBG~oO-sH z_171E_gM%CU%zjwfe*En7z8^r{D7p~xjo#uKBkX8l&F9EYhV7yB4K~nlufN_@PGNrXkbHd6db)f&fVfAM&@@1$&hhuwQlR1$Zw3vgPi+>IIOZ%VN zmg1d>mx2Cc!&Lva&s6_e>++k`P@f;ad8H+m-KK_0)#wfQbwsbjZ+>(XeoLd5;nx!# zDj);J??nQB0e*9%8F~AaVW91P?=WR^O{TlylrJ;yRNnq*W^kodO*yLuTGhbkYTz(h zoOguJE{y}gIo54kcD0UWYrM1leZAOO+Ie?w*KPty)xaSc5*X8pAL;>00AtaYyDK&h zQ#LztyRBGHf%wrQV-J9#;#oSpD4W&M?$gbddgZ$v@NOg$EeC&R=Iut;t$9s%Zg)Z| zsG%WF{F|d}@}{Jy4M$er7&z_!=mBS77Z9Ny_(=7iaj1iisKeh;Q%*Wgwbc7|gD5G! zp7nL9^OVP%qp5kj1G~V#+EcsIx^j(CyTqUJAlI-uwxk!44rUBZLtDn6En}7{n^vEHP!oeh1F1cni_JXg1)N6P1U5 zfE-`h%pGdV+raygXu2~rmHq6chQ^_<<5m)dl&il)K6}l-FuQV*6a+ttu~+QQRF}N z0Q%;=(CI(ZtLB|ZD#`^cKOE(FS50atd_r1ec+6kv5Udb4M^0t>P|YAEA{ zUtVT$1>VQN(xy)*EnL~21pXR!D-V7E>x6|pi5iqmv$JP3+SJfYh?IlsX&~q9c>l2! zHD#L`T%BFz3Qb9I794jfuH$NGZuTU#;DC3ikYy({<#`q_%MsOx9BSycRE!N}oljKr zhC1rJ>fd=@4V+d_zoRyvAFmESDN6UEO9kgu#dTf{{!q{!`lH~0ua6phT=u?UKZGvj z<{9nhe`H;8c!z40^%3GK=*=!u3r;BOJ`32ak)PA1Y6n!gq zg=VCb6f~Cvwv{NZW_E9^TJX6qqoklMdM6QFssv{L4s7SFpDdBfURWX7nATLGX# z7KetNJf2hBSe!jdyUmXZsO(@<&`@9!;MxxDf+P@i*`p$lVKUHJ_#munR$EEXZ7*r~ zz;`>1u^EuVux7N`!kRhEN5R20{iWs7889xV8=eJVKrKD6lIY31=Fm`<4v6`){giW{E?;eN7f6yAVReqc!$6eSukJX<3gKNZyp2D7QGlX zXjRz)kQ^`5tiJw1)mAXg=IgBnr)8-HYSx#xpo9Gh$y1zdr!}6V`7$vh9k=Q0;tiv-4SYI zwWS%>L=5wb-S_u`YU3pAR5TCfh_d1LC`b)0O_BD==gPVe0i*V+p;fUia^HU@ef1C5 z=2v)p*ZLmM+aLL@D0~|WccHhXYQPIE+OS`FxRUCtV2`pP7sbWx5C7S8W!*)h#+6?< z17~#U?f*F46}p9XZVwlA-^UP<)F3LcSFVm~bA{%hg1L|gfxkOXA8|IH8(%W~?UK-t zR6@&Of~EQTO;R@ZPjwfqJzKrRx00af75Gi}EkVT9FyAm$EL!`YYPavs$|w4ea7cRr&h7P0zRRKZvK{PH zxu6#{Y`!3x3w=;ljr&JyRKxwU_PF3?z!12kSrG*)~eF^I+x&9fN{WsH2u;IN4RkUoR| z&2;g?{=mYX{t$(8Qg^7lrq?kIce!BYhJO7*&FL+s7|D56fDtF{|tbcGGf^)BH2b6nkADx$52cC zEiFBF&0s4W?-`m4XN;CVQ|>1*rr9AMf7Pxi1l1DIe< z1EMp2L=YgBNy=@p1+L(jk?k0R!Srl7yd4&Qdn(2c$4jtJJrb+Ip-cJjZ-=*Oz+HST zIEc2d{1w|EVf`UiwJDPa8cF3 z&;ba!LKDw9F*K*P6sKB=9QOpg!Ex#@Tr5huZ#sOc(}S~9ZPSBuQ|;4(3sQ5Z2N$I} zrUzH2mQD@2Qp=|z!s80O6V{HPwvxaFC4pI1XQ0+r5~#>33ET&*vnmHT$aMzp$e$j3 zIJF-2Obgeoy35|)XCr$9m`bRc21p0Jb&#WJEuSSJ$h*Atc_;S@cgXKKs(RC1SI z==#(r5fI6r5y@p=kfWc-@v!KUzdcO}?T}=A;irO(zu`lY@q2s)8C@nazW>9KLVlbZ zFDSVlN&JQXdX|*L1Yp1dgvI#X`du?MOIT8zno|(!Kuz*+f|@@OrQQ4Wsi|Fzm`meE%IE62#o9CzQmDQ(Y2stDca=d_qqsi5X8QiTQ+{ki=Y~ zCyWzQM~sP>SBQqji8)^6Fo>D1gf5rF{O3;uG5^7be|s8~{2so7m}6g&661zJPhmig z`IaE#%ZT(BUj7F|B>V_rt^F~xNO*|(14Dy+gr@yRh0uo|$!dj=pdZPa#ew+2?^(jP z)L?(kIjxv2daZV7L~AZIqSXP7Xf2iY&EUsbct4CYG5(x^RTzI0G5)6IsG$K@VQi@Z z6cQS6>z^r>XQM1sl4I3t%co2k&_~F|*{C8k;5t1WBy_P=HPV3?i2E0;AeQ04yH!sI zS)HDZ(kz+>rdLNfSDbBaXj0ZsMg#<2@fM`2R|DzU+NAE11~Pv94BCj|fP0HJyqh#O z<;9~G<Nkgq-Qx>mmS!|QVS+8?ir zN4GT&7z^0&w#GiAW!&Hz=~bSFw!5_F(Ws8SOV4H#YJ1{06~%DIyMDKK0D>8{3Vt(1 zR1f9RCPX!fQR@PD2mr%(HD+vw;(%B#_P6&?)(u7JFpnoRy0Rw{1LOuV{s(udwm7>t z45I!hDGmKthf?rr#XmNrAN~!+zYKIp*)%tM;_w5FLvJ_IJeo0Ez7ktgTD~zQeT^? z`gfGxxt$k#NnYUEbcdus3VR2dWc&_=%Jk-6ZRgS+mdJei4UpCfZ1h%s1|r#D+4P46 zorTH85V@f60t&Y%DXoaL0@}OtG6OugY*w=62kAd?8uR1$EcZG!SZb5@?<|{dIIQ}t z{8?E(cp*v$<XvR;A%xbb&2G$fh*3A;cE3eQ1@^&?EtDnbPnlnKs9;|7YbW4L^~vT;$JH z8oncw!@Oqxe5IjY0t)hH6(|k0BJC{I$X}`|4fACFQsggH8fMDmWio%6(%_JQIr+2Z zC=I+}OAXGdis!FV8ivXI9_05Z4HwDebuxdQ(qNH*75TGPC=H*3T3G(2iWc^NSiCj- zU4X;1FXGq{@sAOtG`z&$P2ndy#pgdph|=&Q8U1}c@*m@`((n*|)nND;J_;V=19RkH z_&FKo!*?%AB+utR#$VqZ2$JFQALFmjh19$7g4}%g#v$A)!+iLzM)E^=$$yN$zM%*n z7D4`E@(iBMrLmrmC56F)gY1~Of!nj-$xS8i-&E6ztGqwv_lO(B_EBV zD=4lfl0>RGmE@q3vxys)n3*{;88bx5&s@oA)6^Hgt^cXRTh-xv)KKqK6<+G*NUFN^ zdi_rwepnrTKutL;W75@>HuXhC|6`^=o7(&dmNqfXVOCrG4Qea>A}la<9^7aG#Z1z{ zjra{&-DENiMfEEZe0lEIUi+$e=|7{7%v7oA^(*5^gS`FlO$|^sjkCEzlT$!pNB%yi zQVb70c<;aiAHlzsr1;nB3&;JArbZvkX+HSbcnjVw(F+iG3xQ!@jypCJ3o6QbUh0U7 zoPk!C;@a-?w_BBUn~)c82{ZElBashq-w=KKlbEP^H{}i|4-Q`x^ zYF2NE#lZJhV)4eN`de&Hzh;a64WV3wa-)6mX2+X7idB7?LRDTmq~{j!dRpsT~>H$slAB8JT z&pb8M`&BgFf+bh)G`K|Cmt(Zt7`09fdNbSA1D|5~7>*DD9Z%?L6nfw@uH!0isLDPy z@3gl+%H7AL{*PF$Pc#ZGRpApaIH3Hb2}{gssJJM$y?Z1m4a1QIag%NMnPKaQBBkLR zyjYC2GuGZY_JAIn%h=q`vA?AU%)iqCR62lS{A+h84=w~$4C+_US6_^O!|=~-$4|BW z)epVfUj5HoO(0J!=DY0GH@*KxaHk9o>0DGz-{?!Pwl5c(5BZ#og88)KY2s_+RSld} z13M#si3!MQOMc)DhTlh2~z`5gOf*I{HCdyBffP``r01M%-3 z`>X%*9)9&7-Uvv00RLWRhwyJV5aLXEjm+XIcy~>!tKc(li7W7K(tMybl#pHRxd-SQ zkKQ=YD+7747?410sS?#h7c%hCiS9fDpsZXgRV}f7G!SJ~fEeA7bER8`OH#EL%}i2<&CzpMrn4 za*)llzxp5Vdl+b+y!z%5j;@29%ZbIjJBV5og-4vIVfJs?U^NI=`#|J@Xl%hhh{%FA z@B2&*wSH+kH2*M2zBcL^ef(HJFXwT`xCJ_hxBJqJwP4W%)0kT5AjXDhx*F{mO z1&4fAwS^WYc$b6qUF>U#G#I13yZGSk*2n@qfm+b2Y-oUai|scy#os92+EbU0c29x@ z9hyBb7VoQ=@4ACGxr+;SD(iQPlr1T0!CN(-L?+67Y0Dk%qF`Byk@>uy+Os6cL zU{vNrW$nx)(kE*BEK!v3w7+22U84dcq$lE#WS#G?1r7moh9kgWGX!k~4%6@M+-;S70f?$bMuE6Vy? z5TRq!JMe^4DhlT)F0IJX?hd<^o98RNvFfob%ayWEEjV5CFM_7W2wVPNYG_SNP1)xf z^_DX*wmTU}^BfXycD9X6Az3u~?ashi$oTA>$Sc@@Z3wy~&m{V>jJsp}=j_Uc?-2Du zF%F_W0J#i6u)C^ec`WuDo}qnijOO`qa78RkOv0I5jF4#){tNy zLQk#M3>5{fCZjG8!Ew444dCsPjTBruaw&aq%oz{g;%KXZ+*pBlrq!MDvDr&@*me*t$K zVqtHa8o;ie18XL6K2RK*(ppsC-gEgi&Mn`Ue}f=omJd=>PGP^^ChXONDtMq3X8f`p zqJYGYz%QzVHTxo|jK2r4Pi6TvYzAOp9RAe`R z9Tn^Us*WWGCzEAZG4=Jpex5;3!uM0rN?5*Hao$;Re9It84Y3$sf_Y`&0R1Zhv=^9j z+_^nIA(fM1ZsQ4Xiw@vdYu}mIgZ?&YKgek`H}Sxv$SDT=YOzXc#y#If`))|I537!W zH#n&cyo)UXXvG%ZT&%Wi{~^$$O*c0tF+JwYT9*Zp-pq@TN z8niT#DS>>nh1SObn497?QHor@TnA_z$Nu&duO0F{)i-xb8X~w)X&-99=3r-FxAqW< zjE*B7^TXZ6--~z|A)GIra=X|dNs~~<4ac!sJP1{2f9cg>^;J+wj4$on+%8m#OhF-f z7i9bAqn&#D%Smfb*w8TCwTip%m4-vKF0gyB9@U8?YG?~@9CU@&T7a{ye8)O{ibdlE zfpHDR?FkKIMc(3U$e(kVN$|8@y!=9DR5mPT5@S0gP(P|w4Sk0NQxL(iT8dKx*y^~8 zWc8>i$JqpIGCAA#6&`hiXFyeEyoEvC_jRlw6m0ii&P>0eFR!@V*34$|XW`C*#8-I^PU4_zomo3L-E;Yq#EDvKzEJFMS}JWz)!;b|Ir@qSc^ zV#^>Ev9?CS(kr%YgG9W@getlDK(B2PhcQHg$EfcV7waK}VQ3frW;l24-SAsHDD*fc z{5#6&n8Q8+aAjUB@09R58Q{V?nPWxg9MreKc&gIyAzQ0sdLQ4DVY(BN{bzf=B38jA za_fFAk$WkT3)f+r8}ji%c2mbJJbr>aMC!6T;1)7EIKb4w-FDHzJ$Q8NAOw%x6(za| zhCu7tbD0VoZZV2mB%mpb}r_J0iwqU%&oi5y>A@gs2Tkg}S)7lP+_#gZP<#SnEFCXz32;loaB3^Uh z!guW+S<-^5P|`@G)GkIN!kvVuHh+#}5R<})EbeS^$? z;{b*B2uG2B2i>^BTMN(;Ml~Gq-G?oit8Zf)u-FGnPuqqFo^LtAQ#eD@hmk0KGVoAt zYf3nSVHhHOQdO?prrfrh&s`^#yP%bjJMRdDlc-H(Nd!^epDz{V{RIzmd7+H8QA1{> zWOjoTS6Nr2w43amgyfZP5mo|n*=85(GQk(Fo@ zumMKWTw8vd-l<4QLh_p1zY!Vq_G5@svVnY6Y9KwEtO*~uE8DgcMC+x!_TRBs2jh-o z&kiZOdLl(k6*l_0|F8uV3v9h~5~-p~7s`$<-s2&`uDZzvkl8{l0F4GeWrd1eTrqXC*fi6 zn>t@YamnI^~kVLIQj0E0^qDarW`9C6r!es-mrUAq_tcvq?k z`3(K|@L{139?x!KcI?nx_c;OjR(+lY@hzSY@-MGbgT|Q>*yuRcwL07PSDF|w-n70^ z>JY4k^AjXY*vQgCrC6(ZST>CNIE7mvsBgv}wOt(rKk-DYw5-prXL9T(gcOGLBNPEn zOz8Ecv@(g*gJenZ1-oG#-z^vak4otAEY`6A7 zV+I7Q1N#$EHdwcs!=jF9Z(v%{5~O7T+7_hMu9xYq;wY&5a*<^mH^8v&bBW;g3-OR_ zV~RU5NW`7Qqf6YIGVWlPIFV8eGgC=V%hb{1Hpf5&(mmA8h%DnFe`Tr zdq`mjArzvmgaJS)d9O4eme(*96g?A=d!Ce58Vr>^`lL}EzD;bYbYj(v{)KW{1y!`S zJerHmXxI%=MBB!{BcGy(#zaahPI}R_1%z6fy52}3_4`sEF!Z}ULJ1edphd(!%E1Su zey-B;+CKgQ=)v@AAdx==3@Ex$U+vx%fA@qcc!a21R^Fe#CWcD%giohCi3h= zUJj9$8&SF{Leu{9m2oE6QP0sT1{Z|LMnPG9%;3n+a|pW-FNM`h+0QWk#p^sZ)fLy( zR?@VatiC7%i`)#Vh^-J`a{!WPienT`HY~fbCpaO2k-7dD%b~g4EGjI9G71g-bNv-S zpB$)a@FjiV{#i821?j@dU5FQrf{0+Fv>xaQnFO<>)fn{PMNeWzRMlxlbo0qrOfVBT z(nE~Z>06M2)p8QGENNbh5A7V=5A1?TkyP@a*ufm^W51XJpl~=Il3R87t^oqR8xIp4 z)k&Es)MIDrdS`qkb@RGX_cd|8;2C+oV0wC7|FjZoAfZ@y2)vZtE-?OZ_HjJJFn3-O z#1}6c0TM67uy|?03(w<)#ZyXk7x+YwBJg;eKQ=PHMe+$=#d{N;(2YQNG!0UVq99)l zNnX=(F>xmZf7Qu67m@`R;cs!gocWsiD80bcB-tq zmk`ucs*b|GgV|tQ9Pa?HV#rJt=Lb|ZGz%}BG{Omk!@138F#T;N8tT-PU2%mSVDo01 zwDHZ_uVDyuH8w=^rgC6G+^TUMz(t!4ZxJlo=S6)5$CV9qt_i8Fj(US*3hmnm-{<-G znZp*E2KB^tXh=TkE#AekNS1*tr4qmXSc-3s7?$1rkS`nCr)< zY0^HSK-cXP@H3QYw5M=0xATBHPeu`;`pAO|n@PY_WNq{8=W6W@EeUI{t|D7wY{7Vb zoMq{wEf=G$W(@~f4CBl=4$MtL7;ne{;WaLm=Z%zx`ykfbYj3W=2C;Iy)~`(UL4GL> zvk)-+Ee;ahg$D9;(*VBayVn-r>{ZYD6-aKJ>xUJClw$hC9Kilx76IoT{B*{-c89YI zY9lQPO(5~d^+6qf5KFpg54pclpiPSMuyEDU)O($S7mA(&9Z=oCR<*;gx;^k=cBG$4C`B%0lp<(@c|FayR!Fvf%#KwpJ012&6-saZoq ze_wY6MzOT*X$FKDhhxR8oMymA@ziyYSw3q*62VDvvlNdVZGrMmw!pQYP&HA^f*)uO z_;=Ki08ldtBcOApGi*9Fkv=>(HXeeI68d@{0eu4x1F8*b5_aLQ{%x3y zjkwZ*@`m`=p4us57ld@HRJ#|kTZGLm&o?7pyLcOZ@?<&J4$`esDgTcA8+Q_H!d`H= zwkF1_7^zo5JZkx}ij;U2Jwz2Y`ggR!EPqooe%fRqZ)9~Se-+B_%#@vtm(7#A@Mx#u zADL}TNa7=3zR*71DD9UEvFBKyKOZ8w!Grv&Dmm4#V_>EuEH#9*W5^)FY9TVk3vef2 zcHxDZhe^oT8}XzaL&kQ&j$uMp!kn~Yn(*Ww-c1%wDWsHD6 zESeIxU)W~Ds1f;vM0+EHP}vh{zc5`Q{@14Xyd#kkmMo;Fn5OG?i(L!9pG0~p5C2d! z2GU#9=VE!f1kD%r%4k9`_Ed^eh)zn=x8l>iR*F)XC9M$Zk&vjJN)#po>~}1xH{n_U zVT|LN5#6?wU^fl2+HHu#DM+a$(IZ zVMw%|@}2uXZqeh>q&=?C)GtZ`dz_~aJ7H3}hVP>0s&bCn?E)=9HH$L^TUgFydKFjj z7eY?Cf{U`tqStf?P6@8&@fwGvXl+bPjV_#`Y+gMw9cNTyK93h3t1~@(qeLnr#b9#^ zU!N&B#yT=HTvQ($?ZsU7Qyuo5?JV$JGs z_y*H)jnh29Pje8WkzD1*P$QjXi-l>m+MsOhyIoog$1?om7+)utC$uz;LLVdQwDQPK zLNMYyYQafmU2irW7nN*iCzvyu*0^jCSAVcloZ(LIhw;&FzeZ`GgB1sE`=!>OwJQzz z?Efw<5hZA9nCoB4(A00NJCSYZ*i3=Had>pZ-v}9TS%(PVFF4dHV|sRoVZ>({qO9Y1 zn9G8z!)`WBr~N6HP#}WvhxCd+SNk z!_nUZkDJp49=GrT*6@pK)B>%#y@fl~ri6O$nG|xiI%7@PE}VA%mXc6^YYFZjzFqD=4et`TZvB3r z$_X-N_NQ>vvZ3kzi-a4u1b5@$xJ~40@QRpNMn>RGdJ;Kr#2L^{DI73EH}fGkdmuOF zn;G}Zh&4up-2bGf31$d*aOeX@G|ReOX1OB{)3iG|I(7;DBlgc|2PH(i5SwYV-3WvQ z-@?Aow%)8WePm{LCO)~=xFcr}`snS6+b1BVpqFL&PrZ#vC@<-;iA#F^E-uzN*hxNJ znc#nwHJ4Fcl}p8i-C7EU>gRtOY0)0J3U>m~e}er6+D}hp0!iF?5GX>8G%$HGySnAEZ0Do=U#Q6U)szEj+YuF~DRuq(jh-XP`+9v^!59^-R?jY3p+IM0h{o@W;`UgReMPgHrrf<4n7M zThr;c8)ps&CKi4?68+=Ni=@xk6wrqP0^+v-g9g07gSr8q4W#yra!yl3!d$m7u5edkE(5Ml0XXWh<^Xft;c7~r&LLpK! zG^D31IKdV!38rHJI$$=PQ~ZBHP1qWSa}DYKLZ=64_4ae&Xg29P7|ZM>#NRB~;px^H zq5eIo7!CRFEI14M5&8XvHkomHaEOrG$G$Bx@}h|8f%Mjr0u={2d92PED6@(i9F8c%|EE0ISCqD`8qIKraa&vPcANHH6eez+AY~>1?<;}!Ryq2B zZ)gO87~Tjm6SsT68Zy@`PmuIHVY7$_&fsy&>6A;)n`40&#p8mz^!yEh=o zZRkHM_8u(>_C7B9FKQl)^XAs*UR(ku=rgMAMKltl@0chPS6d!b(@;iWIj~m_is%cmnD#FR})Y>#P*i)C3wLtBy81JJY&VkL?K^%qsF6979 zuR$AELl7y?o>tRppr3YHgSS+L)ig9(dGT19JIs=9B>n6V=`RST_V37*>?To&KqnMR zfj8p%E_h^R_Q-BCG9`cU<^-L;%2-$xk?2w3L9S=Nbv&ZM#G{aFUxmyoh)nEPH;~CP zrOai)@bI!=@TWlTFIfo)Wp@Q90=d&9au3q4kXxcWyUpouvbxfWvsEDXJs=l{PiXUk zo2LP}Py)eTKrSv)i?so{4MeUdSW~6E_>rX+OC}SLXf9LB-Km7I6R`*g{oIlX+3dX+!bR%JQerMAigwe7&UcXQVyiZ~R2Q+U ztRT_FRyG_xkeGC0V4^@5wje{^+_NX%LCIn4V4TB>gA*i+5uHcVY75!ee4r^``@>E) z=HrEIj8MP%(f%YGVlUGEh$U(v<0-|lR=Juc0LBSW6%MntS&jV*7_3rb!e)>t3uRn? zJv_=cfX3RAe`Io|EF*vg6x2~mFV0QEw8{L(AZ{4F6Imq9bvH=XW*BOvae6^ z7xrP#sIq3-v}4mv-6^t#)fejZKQ&-Q6EW>fj4SPL*O?m@Z8QXs96xt}0rWPMGE+JG zg+X*kOdh!?ryWqp<3bM4MtraajfI~HDkqKV#(&1D_eADK#HH)|ZgpWo(?5_4N5(B(;2HJYz%S~|jiD#g*b6#EpGW>G$PZ|zp4wwP3E zyDL~^a|Zjj%7Srqoxp#f74`wp521#`vu-SjvUtGl}$w>{Kr!oi$(zHId^Wy6&a9# zDY%0MJF%iL<0pbbd$p^eDu6OskT3^Mr(>_d=rl*(^i*@coss2%b(GPW~C6Jw8WlD<5DuFFS^5VilQX3RA{MXLmz z0ntBkpgj0Afc0nkdoS0&?@)gxOIgqD!S!cwcg$~@C8$C?l{zB*NJ)R4!{S3{E&y@8 zxWIjuHF}BeDq)`_e3}|`S{bMMSKt!Nt1(CiI!^7hdoL2h=74r9<(ce%@Dji@UgMwx zLK#n1T#1JAs1u4z6ds!SxjS5cHf_0SuOdIw0CNFs2f== zsE%cqQT%{I9Jy-H20FLF8=<`b4AXPcr2#Ai9Mg>MlcnH_0Na#e4!vd??F>5$LqSm0 zGeOeXG$foh0<*M9Kf$iqCLgY3p??k8F=HLli>=AgoO*p5yEHn^8``TmW{!wloRkSj z|M>SEa}JJ|)sVv)mQ95P z*aiu|-&d4SAdp!QT)?p#ZJ?;V;Y!2$@%+uCL$Z|3jHe98Py!8VQ87%%{Y6_Gz>iZY zZUqCJG{liTfXmow%LFK`7E*C8=o=bysTx{l4Tl?h<5(tedfbG<#2}Xbk1Na+Bi*w& zgda{iQfzV@8GwD_;r2_{7y{Zmr9`{g8#-lQ-yh{9Oxdw6joo2VfBB2Vmak{ zc4QYE3pp9tloZJlzr5`4{{sL1@8H*ag@NB^+x{o`^%p*JCzTTx&NHpBYwzt1vUhfKmO3ajb#= z4HwDnwC3%8(Td?3!9FK6fd(O@DEulROn75$Y>ESU^TN0tiaeYp`~)0$aIo}JQ_j#` z-25pN(^>2N^Bws+eNnCfcw7ZVR&Pe$k#O`|lx4YW6f7e#85C3LL0E~C`ww4&c0e`I ziA)E(5fTvPOJ8gjjz)Z64Z&CHr`uP|z3Bc;Igfn~Db8jMieZlnu0_m0?yse_)1#({ zJ08%2>1Y8L?Z$B19%dhxmIOzX6kH~O!)65MUeG=x=<3y8Qm|LTE+`TXif9^gO~Ort zePJK4W6HzFKm=42-GC2E$qFMYpkeiR?__qs1KIW#zD@);3jE1owP30hrYbs*o{27B zqABPrw3apA4MgN)`$*^B#r2dB#Byx*8__+Fe8v4Oa(uRS;19UCDO}4*k2;nPPLVpt zp$7Zv9uj+356K?g-PEdV!l!~u5Hb2nTfMwq4z>z-A_;EH_GVZA`|$1l)QU4Fyr z;v^sZ0Yqc;I~qAb3uQd^=t%6Z#fCOw)Pd`!;fcnCp;65w09<^=DkO=jOxUBYJ;Mc| zFp!kuJ#ZNq9&REK^|fhB(Fk$@WQ;iB8Oj*;t;;Mhu(r&& z(xM%JpDEm_&up7rJ9BB5?qcr|t$X+%B7;$*kd)p3$o@wX{Rdydh-CkB-4t5NW~^I8 z(lC7lDfrDD>=oiX^5=gcD+p_s>>8Mwwo8Th69UEEKaB$%Yeb%4U@14oppT z!_Hsm2DX;>2o=QwJEJhjV!S+#!$#p^Sfx6Bzr|bYSeKaE1Z&wgmYJdITU764}8l?S-Lc{IQ`~ zkq-^6Bk}XSB=WRfx0{9h38}Gg$?#oqi35U(38g-eh5qpfr6KZr!xUNY?b3062YkCF z%1cN2@h19qUvt9c>Vo6k0p;_)@a^_w(=m`c&a(H?x2vpQ$pL`s$_?i^Wm4R=X*kav z^xei?=NO1_*SS=J*dNA|$twL9Xd9GZ#|iI8gUuu*n`TKv?iz!x#%PfAHTf@c-Tu0C zEYRpzl4ivz+D2V^p)=IGrzB|`zRl$d&LS1tTxr;P0ovx21TP^Kwv$+gsNYMlwHZek zKrewrm>9Z)97sGue;!vK4&Vb@efe=M-OYT3zwolz97+SH2VH&P;XADTyFj38V%0EjP?VwzMwE1RwOPz2nu;JY01csLxM+?Y-Y$7PRDMqz;%ubI;@I8SWrFgO#sUrP19mvm24 zDb>exCag|iN#9k8^^sB%1FBy*OKG)0|JQMka=jQIjx6CL;)hb2KkMNd-Xh2GIDBpK zffNMAIL11f7{{wQjs*w2MGhzl>@DJqRg6Vror-LsmIQkdy4x7XyD*M-N2_V5A+D$M zMMJ1D)ixvPE^^UsCN1F(mSr5pzlJ1YHjH9ul@e?O1ZqKk_QV*)Ror>c?vUrvLg1dn zuR|%`hdDSgmdS<{ax6z&fkk30zv%==xWEn4$BY5}K`K4ZBcfQI{u@WUqr<2^4vv$f znj0M1hH_=|MX^2Zz(s6}M~%UjhUqDna#HC^bIk;M`CzkP#e%LhJk;Q~v{N?| zdFi*>ndB8DnFK#w58f^ri{?`7K+eHz4zz3Dr={KkhY($4T;>TP4_#pxV^#S0W@G_d znzCOF^?#IfaAO*D@PTwFj$Yu1GKxHG$H7OfYHq+Z%4lxw{GgXjJy>(JGk(E~3H(Cf z>xHa|L6G8mpDyL4opNDyr=?y{xG2`-E)F=-afz425B4nWi#Eb1`T{Ici?-+{u$vx` z`*$ROV+&&NEWc)j&cS$GkL18F*GI4A^ba@9CDuq;xtN!6u@o9`r!(Zii~>Z5)Zh{? zX%GB4ItmOpR4FiU`xmN%n8HOK6i=RrGz)|fn~6R{Zit!BT~=b&At&NUk1Y<(8mz11 ziL7AP!PvVXd-n*2IedKJe+P^%>_6GYZ{@5X0;-e*RjTS;t~4h;rq@#nX~@@IFp+k9 zai<(UpA*Tz=QPu6ZIgquA13>4n;gJP^!M0IC(FMU<%c_29NLP0T}E)E5}U`x7?tDm zzkx}8eA?Dym2HxXk_jwWYSS(mP1%R}8kc3uY+{k)6=EJMKyIvW{YkvT@BIM2GdUAq zU)YY`#G>igT`Ojl$TcL}UwCqwUZf{WYsq7g7jR0&#@ac$!Om)yRw7oGImrwZfyNH3 zUz;E~#5OLNE44Sygk0{AfjQHG^$!+Jp^Y8o+|D(#RI5Y{A{=k|oKm>Gb5JYe_8Ai>JgJBVP|5umT>g6iVZHGYk|LGM!nm&hCGBG zt;ux-Cu37-T@DZVOb61Px#$Bj34b~8BDWp%fwb1`O3o#q2#^`8yumePBGS{NsXN)ccPS zg%0DZ%}eW7j==Z7X0deO-s9jv6hP3dhr6;t3>)kh<~K@*^Aw2xqaIw$#kyx*sl}HE^Dd1W(n^93$_0>i0yc^L zPSrehi}oAVo;{C zrIZh03TGeyh$+=xzb1~D$Z|x8eI=-d)94vo0SSwBB4b|x);BXSj4!gX1^&W6OkwX) zw@zN@S8XdwEaCTIIPtgxYyGoeA=@CStOirmiCp-AmB^({6-|KfF*5{*W>BZhAh0@j zawnn84LW61><0&RoTSda5=@i*g%^sNzyfup+WT0Y#%F`@y&6zQEv3V13D5w9CcIdu z_rp_1q7UHmU*Nb#QlRhMI0g$EU%^tq2j$>{ z)!EjV(%?rkIL&}8gOtHU3(jDzFV4q+EpC;PCsc!RdJ^^n+IE@FDZn2zCieI9`^2J^ zqWO`ZfY5B}$#}HjtQ4k4_aYAn4q;7zV?qnzMwY-@`}A_Su)|JlT2&=WVAh?1Z*%p8 z1044h4BsQ_hc&O3xx|q!)T)+6d$YDZgruloo8^XSyvG|s^1 zt^hi0@C`W*^ePh$X1_z&j2`gBN&hiu8V^U=Xv{ywKsx{*5ReQHzVhr@Zr*c+dVi}V z^HBOum>Tc}s#$euQp+XU#cOAccdJne84`$tKPLK1QGwKNCjY#L zhuG=`0rh)BaO9Wg%b?XV>F~TZ*22ei+?^%1-OD=#wb3{muIoa1;M5#Thv;>hq9;-5 zy1mxl+GyF-AVg!F$x(Psp$g;?*ma{ zcevp`k=TliU>_miz|o{P(37RzV(nt}V0=f;eVzI3!w?TT4?+ren6xUJVK>kjUx%S^ z2yQ8D6fTiq+p66Dm8q6x7cxUWd*T5VtJ&Z>Wz#gfvdNP<>V$F1L((52?>r}K&OmxQ zoXcF_DmcOY>vh;iz7NwMD4~FZgX|yJzur#&*d3RPQ7QJX?=sPslf4+!ZNb#6nxJkw ztO16fJp;=TD8Z^i-Vt}0Y{e_}t+nvv0ES6r`mmx?P4&KyVYYI=;P&F+bg^GBzvF(v ze1TlZ^t+7xf=FQAFPIN9&*g4av9@z7h?baEK_-#`#LOQIu$t5qViBm)G!7HWEs_}& z1}d2}N8m6bZm8`@TQ_=R*Oq2>CGciMMDn43x(F5>Ajkh}3Hrje#rfqX4i-PYZ>y~T z3tsD2jj$*Uj|$+bEDJT_EQpayIDy}e`TL>M2g0;3=$i3wvqo;AIzbzA#5@7)mydr? z@wAeF1RQd}`fh(?2w+puSMHd1qPpI|80HPopO}PV2Hcu=Djdc2*BQfh=o|L65_pq@ z*N0PxP{xn3AcCWI@T4sgG-dcT?Ou)C%4AD54Zi_rvw+I;jqb& zH1f=(g4cX#&v>9^E=f?-#V$u>P3vbWDA zGQ{~q4E@{E&76VuXGPL=o{;qaxHJ8?CFsv1lBu*zUrK?rwSDr2iwq1K6P64G$a- zvy+ku@)E0Ix)aXK1VX=)6E;L0uFzfNgm-8R?}>B5M_{hm2%2iAc9GqnqEXeN~)`QxsHe-pbvAs?;*fCC)X0>n8i zgnFGzytrc`W9eFbcdQ%h6Mw+;6~fG;pB@nMA6y9*>L3lWAq`NVka^G#iCw_{6*h|x z*FNtO;!>L?)VYyRY)FJ(!Czpl85vLWbcZyC?x(bk){0W}UH=Kq`rn77&Z^_29-9Hs zk}`DUnR>k=+P{A*$c#;M%vTMki!`$2EP9k6k!U1zS8jii7(#UnvW zaU^J8-~^8+@<`AbVRJUA!4()!V@`99&L}D1+PM)VZ~r8iHY-Zta=3`Pq*U3wCOy{T z4y;M%y1+TNe@(i@2h#`MJ}R7CHl|YCxdWGChju{4IJgo4kIW*h1~a4bpaZr-WIxCU z;gceVM?03*N&;F*;26qx1uG~ckGj&_SYdgUt4Lyrh8{fe)h2zpbU}7$NpM^?!TStp z*bbX27IktROjNz7z^l>=`n>XhIjJN6j9>4S2Z1#@g$cxtHs2wL{|#t5b?m>1$6 zj21XYv4<^yGfFxrZIxJ-E5&X_2*jKzjlHwrz@466gq5@6!1QzkE-b?0S#jV(9LI2m z`scGuu>l9&i4Z?4j=vfq6S;g#YuD#yKN+h);4zu+MufV=-KJd$G2T z-L%1>hZ)9R*%eQBSa%Z=`yCEG6I3clX43}mHRW8Tp&d&0CJLswF?=AYsR2sf3 zfL}*{&*&h&X+2>oCiWV17_-&;61^|)NFL&OFa%Hwm_H|L^<%{QXGw zdFGipbLPyMGiT16IdcL-=>jeXw=%zTc}PLKP4H-|eeIPweU zaMR?HnX26Rn{%{*CTH_^Zzjl}eD}%4-p$*ZwD$>kfg^Ut3;Bg!XM-X;+2^x_pV-!$ zBmR*yW%nT;uIxE~AD=gWDn3h9cVDLbCSZ+c-%OdNfp!I!C<<QI23=FnLC3b&E=QV)yFR%S zHcZ*yHnXG5R-i&TXlJAMsH}Aw_P-jHXzg4YmaAbCH8OhWjBrrSxZ4fNsp10m$n!O9 zF+y_i^$+E1*t7J`fZXe@J_h924|@&B^v%5nqsHINF9o(wY){gJF~b}n<(go|DbtK$ zH=+hgW_@`GMgW`39*>U}=A@qZ3R{s0F?j~se^9>n#TJ?ii@c}foY?7>^49`5lFi9GI5Lou#Fx1iF+H8CatybAg zhHU1^vo=`PZo$M$9GsA9OaB7ZFq3c|#H{kE=$q`LWM9VK2MY|R3I4Pn1}g*E?o-i@ zoLu3`6_=BadLn0(7gPX<9llImy`p-<0*I z4#&BA4xmn*SbbViGmZgsbwUBh(YhoXPi_l?^CkW{H?n)Sf@MB(wNyeHS!dKW4?YzN z8XDqjv7%YO#8tuz4tY4jEgYLAZ$5*XN0C2bOD`@}(@WFS`cN_*e_r&({JB*OX#A-& zt8Ou}-qQYm%b(1tA%E`unB&h~LKWRnaqO5tMR%`v{w8G8^>=0$Fz!=HUe5mySd|g@ z@3E@(w_(=HG=<&LgHf0NXN>x*1;(fq|1(C-v}M^epUQtdDTm5^aqFCScEGI{8Mi7v z@;VnE`RHgMMCZMIpO_EH*QsCGGe5*_Mj+)D%7&$KIduaJN0LsFS! zq71S-J&e0vF@thydYv{AS5Oi5*E@UV4ZfvQhDmT$5tus69|$lG)w9u$s;))W9@Ef9 zh)(yaY%03&@^E^7=5|L0`w(Q$QPt+HzK;?zly>?fY(H$&d1w{CjnN;_iBkrtR%@v4;p=`Ma(L-YEBV$pbVb#8CB#w10ctM1m)lMK1I~VC`&r&dZO_cdHyEhem+SqkH;% zuoMUzR^&k)n!tIsrUOw+n{AI>waT|(`%AMET4eBMgd=?CrGdhatk z{ov|u{lM)X>A+iHpZ>cZ86NZ`TSSZzM%vH`3W$G#&s>pdk zFg6A*p2}?>U)O+tM|U(fZM{6IJ9wQ)LAD^|wyN%0i|n8cX4F7bR!a9&SvRDw6{3Bc zo)+IP-zH*nvJPn4dcwlWZhJC1%`rAd*JZie+HW>qxNtC9JC*oivHwF zS%T8R@J7}VrtbA#{G0xAAF8db#~lCO*pq*^bo1})U(CPppM?DT`&<8~{M+=u%D;Aq zq;LNH_;<#?xaw>Q)h|cIuO1huU%l9vfJTmu&tHl}hKm(M_Nbif;$!I_H~k-SGV7ZQ z|6N`-P1iX2H#U&}N1S}e|1Bpo`*A2}&ybT(*b}*w-x1G@>h1_htXzhk{Yr0!9v3jQ z^xsaW|DN2f|7tAf*bjE*i?q5W#>#<4h_bSdchh=D(6@J87|t*L&8jcRo}FhxMN-y- zP#m*A$dcCFtlfOuQ?G4j@7}4as@wne?=`#U4o>X*cW7x!K&_w$XWY1G)MM0^vTm19!Yt6?wtUT9T zvV*zDB7u&AMt0l=|9k{yZH@zgHvi=UkQtj*WZS7Z_Tag8>h0V@j=ZrG{%o+9e}x3K zbkXj)13x-WKEH%6>KrTSjq*?*mLiHu8!Dn-V}E~jxWC_PQ@~we(WfSwR$M75p~7uq z^6guDqzB94yomkspAZz+LP63aZzqj<(4%>1YOrz|6u=FwH!T}1X*m@zHum zCw{W6w@&PD`)hCMJ3p%lOMjR-F0kElJbg+jvHzRL$=+E`6nFMlIser&qF3@tB6_VH z9F-BYT=zrI)kR~H`uGe^~DJCFN;OUodF zzpWWY?P0F=4-Tu5mQ|ct+81a`Rp;o=FEA&Db=U-Yp&+0kf*}tqlrs5pz5>% zy0ytG@?_s+S>_e+NULbRj6-!*RcBWdL-TU%erA!^fgIlC9Po@u5yqeZu_) z+fVXR9M2y9v{$gnA;M)~B4Dw9Z(o#QJ<26cGk_$KSvw&$3IR2My|=r_>Q&s;_=4 zcEf?Hw))-J0tKSe$%IDTy2LT8j;@n*lDJ^29ngBpf9EQVfmquLL*WZiYtrQ5t~J~N zeoVEEbzQ3_CSKcWZDe~sOub8*=LJhA%OSn5(zyb&J|fw2yMxldm3I<}ou zH~iVU)CGt@tc<%505b78ev>+<^_I52xvpby9y@4qn2Od@WEMEbNt&7hrpo1<+;WOv zvPCwkCY);Y`}U{$eMzd~kL>X&|9O73vLxwd9_1CuWh|*8m}Uy}-w>N$5%ABXQ{bQC zF;ySMT7L)u9sh7|i?Z5$T|a`T9U=eJam|1?`~_X>W{eE~Xebu@Q<2C$E|?w1u`}_H z0;Om|^y*VX2I!uGFXSKH^>S2RCvnRfJCMKS#I=UCef zG~o2q5qlZ`j3UEC7->OiZ~m$0;AobAe!~R_;vWg8{}46MF#M#c8T+KZxm#VwKToRb zc&Fx!)D=S`6I0((LjRcAC#(M!OML_WsUNYyZq0i-%RkT57toKr1=lxN1ok3tDde5I zM_*i&$2$K8OCe-B#YqQlbsTlaCs~dM#jg+6U0x> z`PctdbJB{;9^=2!8Nl3kc888%u|GMnZy?B#Y^aO zT)_#1^cX=vdg2=FK^wwlhOlNStdtZ}(5VUZt%Pdau3yRyC~M10_3+KdA8Cwi@{i(I zfjMBIi|uiXKaAf#SxFOeIq|)Nn3_EqN>Z|%_$|wKWZ82Z=J@N|-TZ|PKok~&i|`j- z8&}rIrQ~}>GORO(?)9;*jq2CM@F1Q3NbPrD^rVOlkS(#_kBlu^)w;QP6gmI#56g-D zgS>ISLbi5zOFo&d21qy?b%+BOhn zkL)-c(mVCc#f%98xxCDxbI2}e9J>^GiDMtOTq~LiF>g=ZuweD~pQG{sy>qBb z-}MTuBy22uT=97PclYS8H4Tr#iW9J$Z-0_52brSuRY>u0*k^yk6%$)KV+j`OEht*0 zbq`+GN0c>ZY~AyEHgg{jVR;S$t9)MZx2^aaeU$1>5`WA*Hjq68MrTC&<@?hL7H~+e zp+i1WN2@#MOrkrvz=iIliN)dlT$`U55cz`jlfj=Gz_-5gf^|ic#4Ma>>SBFrq3#_e z>I|#mM7y57#C`5s-zB=`w?5IL!2gKr%Jr;f{W4Sz0rJ+~P)@r3^R!Zkl0e7QSOfdO?5+g`kQ%z*o}{0QYgeR*)D*o>4k~=^bp@Rs2SIo_LmH2YIM7!`L=T`Sk=&o(aA}1`ol$B2|RH`imI{nFdRQ!=hsmf_odx`G}{rJPmHmG^v z+WBQX?5oe&78Usy{Uu~9U4Pl#qxny+eR7xYo?oy(+VJN<2tuG7ZzaaSIggj%Tcqel z*K)@ZN>t{eSh0;a!?``STT28ilvd8OwbjCzu(AAo!<;?jFYXNFp?{N9Vfvv#GPWw& zu7)P>Q~Rnn&f3Z7kQtJ?rXaCIUlPy7Upat*+FAYi%+=|y&`ujy{*=dqwzvPQ_>&=L zFS~U1v2dbL2%=>vaRK8zRe^E-k%WuP^YrIg%Ju z*3|(?3hi%^{T=k-xY(6tWyvaKdy{OhMUvAB_3|z+?+{^%-2v=^TX_4JH*b*MKIN^8 zw}#>=6NSon;W92cX^37Q)9ZR(8%y;1j9xeJI(1*Y{!Oo&BSxVq^|5cir9U5l#r1y> z`z^!4gC*bRtFbY@_Y!%p{A|jY*z`||_4k=#65e~0KYSmf?;!8K51PW~AxfkXy-F8Z z>5?6m-btnRw$dNQuD`ez5PuN@X(8}W6?ODyr&LXE>ZwyqmcN3ny!3<3?CU0HWn-KBjK=7ID9ZA_$mxG4w<5Fy-HgB z8%uUjQnhc~J1F_0GHq9#P%^0VIji$C)%l|8+)kbLRdqh6IzOY%9wn{L=d8{?N~+H1 zRHsV*S#@sRVV%#Z&bO%Zbzu}xI`-b%y-W72Gry$jgvyi@zlB78LY2R)%3l-skkd$f zO%495D*v!gBKIh1l|N$*?xUnCcSQa$cBQe{bE^0)>evB`{aH0{CDWB%JWc;3AU27t z%Rlc~+G@{Xv7V&^f(NDls=7Z^-JcumkhK_JpQzPOsP30lcVFYHXKAY&_S#Wt)g6ql zu18~S`{KUKIP1^9(~9|Xb}4@*SEy5dvI5T6!>>Anhd;c;!xRM4T7=Gu@IEsHj0909 zX&db6d7d^$Bw=0w4aArpGkSc-9yMT)U`qX`9=kNYUgBSxe~h8ex08zC;Ll(5XQTeS z2woT0^5^mf{>*6P&zxz(F5VJgmuwFnzI%7@aOZtIXg47;1 zlY(E~$UM+J6WY4cKbz3Ire~QMGP5?A2HpIp3h z{8-nCL|$N#Ja|p|goyt#H{+P){xqh?=pRTT=M|Ro_0PkcKUK~L^K#zma-L;5muGX{ zpq#0^oL9P>RhIMCY|cjIyf`oCM3-}a%XwKg=ZVT$otN`)m$T4v)?{;@qnxq4oMT+h z56Vx_0;I64rRFLgBTc)u&nqiqs=dBFeo0y3XI@e!hUl>EP%0I@=^$w?(SM3=#2+}u z-agS=e034?`{SzzMA8eoHC@qvW@$JJQ)HJp7LoO}_eYrh$e;Wz)<6Dj6w5rFue#Wq zmGAC<`Z41By0WlW{{vwM{hz}>XpIs7-oDE3@o$wcR{5!Ym4ABGj_cnqy|cIw_IIdx(u`fq!8=~cQgcanflc1h-UUqg za+tnGFx_r)r@y=-71WJCZDxe{f8g++q6YMDpK}@yISsh!>i3Wq#L#$NPrACI>#; zq8$VO{=VT){@3th^B?P`f4O*&v-X@aJgdl4JgcS|vBlHfeMcNgA|9PNzfs` z`BYl5EQcdj(p0wY2#V5Y{_#7?Zw_QCm|**R9KE;sqiAGl3HZrvEx7S#$Z6~k{`mbu z`S*@Ki<+T8D*DvSgChPB-^eqUwEL4+>wP*QGu z4&vHjIxif11jX3I#uh$EHW-c9-J{?7KEujP2HnGIMgzTpK(6;C*J}8L$dfkG#&i+ z>I?s|59Jd6i}Am)oBqWuHEU6IB2D|Z)O6az(3YBY_Asb@P4pk{ofs*=fPM!54synb z^G?Gr9`dj?H}p6EKod$7KFXCk1+M?%TMOrMZH>Dww6M%S+;R^hjLgs#Te~xJ^?dQ% zzq@??g5@Yt7a6UMzsG0ipXA`Pw@?U!=HaNZEfHO?{=Q;3>Tnr0ImF}%Phh7TLxY@r z9frX4H*V{Pl2rlN%y07tkl?!wvY?KNmf4qb(5_m;CFzx7DIKiqMyM;+wucg#0&B5; z9#Ej|+5;AP7ZE&>Y_H1i7Xu%=f6vpl6Z)ML+2X}I2KwiB36l0~lIOX6Y%iyx9~PVh zhQtS6*Dw5x&uePvcG9gNc^+X;-+!Sy!!#{u zVWVDB(dh#At@YX3&YP-z?o{;r2%d-Q{gDrG^-5~+6%bDRU+Pfi39Fr66NAe9E0+vl zFXby;m((Xm9lVwPf#?-R^ty;YCf#TBMJ}d#(un%2Ra?NOlO|!R_4K!6rXUZZgw>)CY$f<;kPr~|fFG?fVW#A92{uSyAMk%$M- zApk8A(0%=VI0u{GX~3d;FQ8|wZ2o}g@n-#VUN|;FXBoU_fG{0h3LQ#2NUna#0FWrw z)=i0Du!D-lQrwShtb>2lVmj>yJ!nX&xot2HMEnFcLA+} zg1kb()qm{SYNxM-bn;hmRyUt4K?WGr8sQhv2_CdUkkh8LT#LK$3ZD$WV*>mblIBbV z00bOZ6~Ui<)Ptb%`>Wj@j|U|uky$+S+ALZZYmFgjT59fi3ppHX>&FW`RVJQlskuRk zO@r#SJ7zlxFz5y$JWT^shaV@4G$ngjEv0 zw`|YmeR!QJnopAqn(aUTYQIP(>Tlo&rkV8BJVnju-;m{xz?sYOr{m31v@C0P$en(9 zU-hf5Qe#WBbN^DBk@*Ro96+vUS+X15K-at~im-&J-e(3H3fq3?7fp|~EZJLM?TE7p z#6Ls|HS(u3C;lPQf}l(sv!=!Jw62e}nL|*#=DB9E@^!hiWGK0<2}~_Z`D~a&T-aLz z^e8sd@|jkolg3mb{5|%KXCC5J(~{|I8w3N5ETzPahmAFJ85RW@0^-_d?e=-myZZ}U zcsDUt9#v|B{mr(2lIo||LpBrpafJC?&b)o>Ro^d@Qqu|k8Aq^jmWnR=DzblnQH%L) z`KbO8|9gB`Tc|y&h<{kRR~vxkB~PIV450JbP=sv2=Y4k*F0sY!BHhAs$_`+n`X*C{ zYHshkp$UKi67B4HO(m0F>k{AVq$b-Q0~n0iRMybSnXKus)ityAN+oAa6L2WQKCu7g zDH`i+rz!uM`P$v#eR@U9!`AIhJFS_&yV6>g{fWN}%BL(tKBI22Gy`&0#hM!gq`)7B zKT{TR2yXZI!?gmZ`{f*Dc78#Ufm+cFlJe`Ie`?ibrT*-7IUscL1KWn>UgAXU9MS=& z6j>ulpSRX^SYz9t!tk0G4*?V+{^j5GVx%3MSTYa@Tr^1TJ#%uoQm)T zODPBcWp=WLRj$X!@|3#dw2FW;o6C_vhdy%xQL6mg_oHlpqLkiKy3fsmXY$yETTfuz z&910^un3?{!#Ol@@QczjU8{N*0fF%a@%8;wCp6wn1-L}J?L^$LWsEFBfh&9 zil?0ih4X(kK(890zvUFmJ{o>=Li}2)B2AaoF&f*uY`0sF8fzBu{7hsL0{P6U_!1Ld z*9~4{+u)I|g?jfZUzeCFEK8azgRakVjtucn3z~Ny)AI1|X=$XXsBY~k#ec_t-Wna; zFX!Jz(~X372T>NgaDDw3X43%2MsbCkKy`mrthHIo8y)z#f(N|6_tKVmd?mZ7l3#?s z-#NBmj?Kp58PwW^50%XWm+bfmAl9b_|7Pom$e6COr|^RrSh=40D?Lm_xkbGo*7iru zlE@-e^6|=2OjX$DCc9-&<5yQvroUXx@pC$50AtJQm$T%TRW5FEM3eoQtZlJM0Wood z@$WkSnL#iZ9-wW7R*40tV#+4RB!4U3IR8C$%_@NV7EJXFM*r1^C+{@e1wx>sZ% zv7s9~%_Ea4aW`-T(EzUl+f+2#u5>1LsdlXSxB0ZT63I5D$wjzR9%!C1@3>sKjh;VE1oxfZKjc zV)~>kgemP1m4$T!UNT;-MKKNf;&)cM0hVMSW&6Yb3*KO^RTSh*jatTq^9~W#=3x`> zp;sa4aXC#Sw}`!qVbX+Ktt3n`4A$MPH#**rfbkNhwF?PnV0J3l`-p!~qEh!S>Tla?=xXGh=fa6gDTeH!eB z?xb)1?J!e?{DO8sZq`>`?X3IKAB*qgX}-$8@%WI^rNVQLtG^*z|BdH{_7Iywn1f1m z-@@LS_ew4DuD^f~nL-7{j+LjTECLHF3p!${=IiqGYrzR5$?w?wTNp9j^3mj6IOW@! zd#1>B{#8XLVww+QgZG}tPjLF3OdIqi-j8)f+FY{Qz^`wm>gH#xmiNZG1H~9Ym8OH0qg4W<)Hc(=y`Hl>t0Z?WHu}a5jVBA&K zLT`0xx~6}AIE-;V3>;XGj_x69Cf4|bA!)}Z?2Ez(2ktDl&DAc-$2 zkt6Vr_&jh|(u`H+pxfQP+^W7`6;^ems#-`@?P?D4+pHnmxDNGLNA{l%lqIWQx~pcomKL`g2|PyI~5y`%M@wX+4^V z7!T^f8=UZN_cv3D*Rtw$EYhOqJ&%$oGLt7*L{<2=pGpmJ^G!}fNB><$=lxEwpTRZ! ztcf0IrCbjC>qqYy;KoOKbf0FQuz60u8ymE(v~9)pQGY!K+m@OqHqnkL?Yix0zqNmp z@pAAw`>9#ak6#Ab;8bcWZT^Z|{9ArHAR-pY{2~v2Z2oQC^eZJN!g`Y(==rqWA9k9^ zx4CHmM5xGI20yr`ud-P+c+H>cBPqjCGvgGUSDJHZ;Oo zWnYwZ{PFj0`Gx3}`0W=vpoK<9uz5xbBC+@{$ z?~=*3x-+(55=misG{c*u6bnmF8kQa1kt`}@_ZP*5zSF2mMcI=DLsQ%iBCiGXYfPFHm6aRVZ)O#cnj zxc^rGxG#%ylBOT}bF8G@|K%kbiW%LRFD;oy%fr&k!qVK0@+~V}tkVA2UIksFxV0m3 z9+!oWQQr0@GM`uO4-GRbiprVbEGtFg%%ZyF_gX|8cB#0~b=MI5d5!+7>?_+9a8{y` z34|VZ#{PRJ9YkyPJM+mAvcFG2uBD6GT8FqMl_P&wkgJH}fZ8dQr$L!h&8^>HxR$a_* z>xSSAqvoJ^P3cAmKWhLdS4vqQY-by>hslohl+IoocG?z*ub3)aYuo*AU#435pc;)o zVr@S_Rn1g^hC3%o9l8L+d{@j!@h~cB#D7LRf~n{|AE4&!qJ)E#K&R<)K-q+up|N3% zEz*S*W4Zqtkr!z?h}bPi`-a;3cRFiySC+;QG6d!kAX4KQMtk$(%CXT z_WOm?V7W2cgg+oMUTYUQpJWD#^`pwlm2w+mZHL=JXg9C=Oa?t7m9^cXvKA_5`Lib* zK#-{x`ri3XhRO=~0m7J7(oY=5I&^JqIawj56g_mDBBe+~#B0ihcrzN0nN}dS&auqS zoCv8(Tw{tL3HKAy9{V&gagc7?gD4Cp3h9nMT3ISRW*VvGkP16oV+nQCTCIuVHMOHe zv4+-u@tOyp6Rr2JPu^HX!|RjZSx6@T$1nyWL*x>vy~GXria)=;>c4o+byg77#4GYg zlAWHR3hMy{-O>E4un}Y8HRo8)!@!$+ZqCEbFqPOl?tXDsjw*=XdNMsa8Qd>N(e!v8 zLt5>m%!%=uJq*CXR0V*B2E_&h0Q4Q^%2PJrh{R9?(W1oa!W)7IWT#4K z&Y?6tkK4h9>xMga8NmUi&gB|bw14u60cKLekB-;8^{g;}5xA%l`ulepL~g#WZBVU# z2JW-0!TKN5qmBnG5ps@85y%x@a!fg)4oYxFd%^2}9^kao5j$3Ov8*=pEho|vSaI3A z;a*^P^TBNRbs~e{vRAi$nWYr(1U+o{rc1nybVkSjkw);PxVgyB% z^&h+g!`ZXlg>s(U{BQx(4`5VjMu0+!ge%)KBfe2Gas0&U`I-ue4*rRD=v!`@@I*VZ2pUVKscJ)`7boIr)A6h-%l$EM5c`!+OWN3ZtOgx2Q}+-W z!M~WjaO2zB5{QYYX3Zo3Scs?}%|lhY^JTp1QsZeMBo3Nn$gt2jdNgpvGmOMQiD*~) znz6^S#d=LSA;bOIy?2wDg1{a!j42mNK-2MR*14&nwt47wMx+Lr3Z7yc!b@Ot|JLn2 zXS4X~DrUWGH!HvEXHl2)d&_^2+uN##%1{SIvvSVwP5$EbkNR(BXg{T-qBe{zGHt-= zPj`+++Q;4gKgeaC$mx6@UH@wYhMI(InFvj89Fig(%)KT4hhNt`k}0;i1clt|+S!d0 zFeY1dWM;JnErYizci{TNzDws>o+JiRF2u$_syVCqVQ=l2Ds^q<0ip)%G2_HL` z$C*0y8yxESO{=LOZZ3=YedX^HR&B%4Iw+IK64B~ErLX#l#^Jbxn_r)ze*gV@@@oc1 z@bkCHr?;<~gZ}$|FaF5fn5{nOzXQ>M0vsAlzx$_@0~*rESVE^;-!#0g`eqxx(&W$6 zU_BDjBfp2e>4qyq)2Ugk8F%`c>$65lzF6B$09!j|Uz5;laUf8q@oVEUb0DYDf&pc8 zEk>q&?{0GN%VGX5@|mf`bg@ja{Zw*{DhOa=y4Q7p7O~)-^VzN4+yrTm|IYujT~cDv zlYx}by26gBllROL@E?sM14A2Ta&iJzqtU>!n%odS!oTegJ;!Cz4RKforcFHRa=XIE zv<`^Z9H<&~zwy2>91DIEChxNC9Rzz%7m^MRPJ2AqUf7q#Qgc$g=Jh8itflRBXpdu1 z|0WdqA6VJZx)fcS5_%1a!YM{fFL713>Udzh=4V!%07WDxulD>|R+Q^(=SXwB+BC;l z>o3ikcueIA!=3ZD4@+;XjV)SJ+xl^=l|v9+$d5afEAic)U1Y~9=ptqq>muE4=oHJ= zgMmW(g#+tzHcrkj@t=i$T(!!@s!lQ=4@68-A?cR*XlUN742)7n2?v*s^??ezE7 zuN&$9VD!D&szFZAC`x0L5Pjiiv~vY;1rg}GS@dla0MU1b=-XiQ{f?D|NRxBudvZWu zZiinRsOHf36e|vWNlsoh$=}PhPSuLO4bseGt?wCq_o-X~X_t$%cDy-=7QKOwPGnX1 zRfxvS7;kNh*k1p&v(dPUUkQ8U4vM&(o;-#TN`Ofyri!uO=|wg<=P=do4PbtL%M^BZ z0HwH#c_DKba-!j@tAcvn_*nim0gaBDV4BF_4m68$+169h;V$W|6(kKMiQYzl`V+nz z2ox)yUXEF}Tb%TI`j_*|=wq|6$RqLsRALdg7AFPw7|0;yQyEDgJgoHiMTdEERr33WTjIo0In z_e~nfA} ztpUT%jcp^1Dfd&!K)nqd_iXmVZT5qYg6?MAIK>W{Ouuny++h?D?NgR*rx^pogb_BFCh3cAJqn_82kqDx*07yHL4fl6cZud_~^gpNY^t=R9L_xkH*Z?|w($LueW zSS9^buBzN=ac8+>wAq@i?St=uQh;N=O2ab5sWd1@Ve5v`I>SGtXV{grBUq+;{>SG_ zxe9Y=ncm>PvJV663zq5g*3l{L%>xz9t%X))N?|Trp!=86M`5zvQSTP#tZBQK;8KaT z_>n$62$cBZC2Y0Jd=q%HC5lXr;eS?KzU0BNgnU2}4_&0bpG&t@tsW$j#!*sTbc z=-sRPoHb;;rgJSd;hCq^dfRV$uGT%R)LCf%(sCWzy;5)VRR1%sK>jlQ;@oArmpOs; zua!P1Sf+EK%p@y4)0N)ABE6PHx@TgVC3$J2XZ z=yH=Wspzn!wvOM4#OylW^CwC)LpPv8fA~AQeqTpM$5ipF!GQ><>umizY>zA+l!({d zsIk}t&)Nzf{pZ)}m_F9`$W7J{NY3jHP-PX~2%kbZ=!OLvFZ=DPR3@{g2 zEHt#8%=+)oYENirV=8xsw$)U-V?$eZHgC@`ozF55GPF_Lo8)^|Hfw0J>AdNXFR-(j zk&RO(J&kPG6%y;xtC%6N9!$59piOUP^+rCJ^&qf>VnCSW3qO|B`ED_xk?88^XEmtry(fhU#Rhwg72MRI658ba6T%;GsOq?lg{Op}*+^ zDQ|iC(%0F?2I9;-SX)9&`A)At#(hMJPlG{k=1*W3vi=?Z6PC>2qsIYYxd;clxU zdJN$zT@vk)i3#noaA8kS@zu3oU}*5qPUP~PssZ!R&X9g~N1F`)TK~fi?Nlni0i62O z|0)CCD_YaCghmmsXQ8u&R&JQT8xtiSK_8tR3>(MN-Gj!z1E><2Zou?BzhL+c3*eV> z6oEFC`vcyDPYhw$AoB;|i{myiR4H!R zrm332CB(wNX+c1ZOq)rFmYVM^7Z2~=Qd4bn-_Ehc(Mp~ai?gL>e@nxNIQSB>#n%@s z96Xr^v_#UP4N6v*rn)!PxSk~&gydn0ind1 zqPbaCXR+avrMcWO$|`R!PQQQ z=ykkicJjKS*YW`I7SMNgqFgxm9%3+bnU;U_78jrW&5+6Fy=_Y^ymN1-1H84Z))DGZ zLJ?gkdSjJtEUr)ez)Zbryep8 zVJ}ZiWc-8r>r~!3^gqs4s)wzt&XT&+pdlF0s~3vVt{a2?H1AX49E&RgEsU|QWMZmp zVAg!qUN`SE`)-j%z0{cn7En^UMEZSzViYiz)nl?d8x!YyADJ5e+c2(wX!~S z@JGveB6U(7PP+wqYGe*9cGxpgLe%RyY&L1kGHt$0Ogzo{adJPkV^Kh=8*EspHcquB z+chv$A>&oMCaIzCs2Z#A;-Eq=TOl)OcZJh(EA+Az`fnHHRc9kl)y-S2K9j8MtWUh` zAB;B-zssz@Z@&kANvvCHFQ@T>#7CZ+{lQ;;Loi&@@AowaNj}Hs{}I^1NMZWJg2JSc zik9Nk<4>-m_KOF9wpeZ}I*3P~R?+6`E?*Np&e`h{OT1vqz23Y9omVpcE1;XdLYjo{{6U&x77UCA0_Qs z(eu&P2g?IfgU+R3miI5Gt{nfE05YOwTv=^h@^toLKk%w=)im5ZOD7j=xrceiWUqQc z(ey84{F=)=n~Kiob5K9U^aN^}f_dV+qYz6JmRbFCuJ0wQ!nqoZoI}J(WhjsP31*mb zWPVB>N%CG?|9=L*2Q8@$&p=jrNj#Y*6sy-O{BynviE$mS6lE${o)qmvees&fOGPh^ zk{9{A{kK~wr3T+RVi)ZqU!j8yOds=_3k~T%5?E$_PQS?-EvA|azQx$7f99pI9u9RbrJx=!NQkNEM z+m8pOA6p3$19?&X>7DdBzI|}4O+v0^_Rh!PJeJ!C!Q0nrs5qv%xMlVrP_} zW123^TndJ}Hh;YrguM-~<3=_QhJ1snMiHhlgkhgX9`hyl>A0$VRkh7M{5QS|)I=L#e7tzAurXY1S3 z>U$8067cA^vbDX8Lu{5u{eR5m#P=2^>b$|hOE@Y}c?JOtq06R=#(8_!Ja_!dhCFr^;FU+NM!cajr@=D+o0>I=x*Kmu27o{?s9wnAflkVd^NJ#5tbi8(z-d@5RV?;#O? z%QcKa8eEL&p#ot!C~@mF1};h-)z4G){NAX#{evHH^0RnN%LBYiFwj9g8^^mF|GQ8& zY^laP_5AwM`(=SVvwDrps0d1g3QyD&MH=F(>@mL3XbZxxm><7eSG5p!|&5s)XwvmQe zXP(mZpMNBO)c)djxa4lVq@q{-jJ_RmHH0x8&fl5-&nyV~%JokhIRhLjh;6o!H5liO zb}~)8m~YktOf10^Qp`udVI>MaG0%~booC=PhLs@Dgmc7CE~4sy0tZ!{VrgK+4C8+v z3!8gX!6N@M$RkE%{H7=OoN@D+%;;Ae;7&yoidw28&D{3`a~c1PRz!dVn}u*$kw1~~ znXj406;{FjGUUnpAs@88Ir@CoO`j^E=y9n2$3H%S^$VIxtaY7{!Q3wF+p#zE4gER3 zk|Rq`u%{Ti`FqL&c3$#$ulliTClTzq@BrqYF)dqbnxYEX>}mM{Q_Iw6W159oxf!uh z%C`D@>>(qJt@@P%zHE@$rqmY9V>p8hy}V3+AYlz_YV}el6QH7&S)gP3q235WHk`*c zq6Kg0_>`FW>lE`mF5d=u+qozIXsAQ4p0EvWm1xuYYxyCezULOg5VfklTbHL=C1LXSm=4JMYBXXfUVkyiAHwaK`z zY%PY9tW&HuG}n5m>tA9dUs1Nj8AZE^JO=y!ucB07HiX~|X0{8)6#JLyE4(_D@lpL)vzbh&rCrcZbI^5| z0{GOf`6^ZOo5K!?JY1>_H~zdZlG(4v=aWkLyuUtQ&SzFDTX{w!$myz_p8Ae?VD;*$ zYd&$5w9bX-)=3ckUSMgJx`N*#J=3X=xUAMcAV$Rr4LWN#SMIGBT{+iT zx&-j5QW;mQzbN99t#?29-}`A!qm~+DnR$f)&NUg)o1Z)w^U7e#)+IRAu~`uI`}M~M zBY*tmdGs*xS>7BBQTjhUrw^qgXN;QsJR*>vh#NG8rRK@l9ad=X=kOc~f;t)YwXwy7?%@Dsd@3JwcSpx7g`ARHaQ^7X>B%7jPfyklEMgz`09Gc~?o$`v zS`>>{l9MiZ?L5oUk1YN0EWW8M0z5VdW@t1|3Pef+zxDL`3Vv;E)+A%qYzdZd|2cFDbi9S946`?y?g&s@ipMtW}(-`aDT( zqn5U)OoMCO!ntLqGJfM-rPrU1LrQagiXDWY#{c-%cbbnBK@`{Hp|VC-*F$B~co0F95D?@~ zJVyGU$EUYIkEZG!(}RZhMGwgIh4gq4db9_Gcu|CqieM!0>~Fo=UO`%x5H=9#1q33n2)8!*T3js8cLA|A~yKwFhjDOd>tx;U7int7^ZumCcmt(J=yomg#%VwOY9Ga0Ni}WeWk_0E1b2HTc zn8QCRXPKy4nRKs)xR17lrCQ6XtTea7tG=LtbzCnpA$7qJPZWBag-M^i(kHWLyEVXB z62hur2&)Rm^={m!uh2+NbS|}Z)M~DGc2CQA3cKQh?yd-#I_!#KVXUq==3jM%m9(zV z{5f1Lrlm@CouPO|CQ^HJ#sy#88QGqAX$L*={!R466`Y1rPgtfM_k<&lB(lh*o>2S3 zp143ganTR{&wAn&#zeL!j=v@Bi3*2eg?}7d3 zjeZe-G4JU)WT3#nR8YXvyK`rs1|xWB&&fbQC^Xw0euz^zU4O z&qMs?=GHZYYECAgD%F@pQ0HFxCHtC{{)Z&A;i_#pf1B5|B9&04CG0+#aU6R!`j=<(4<|qC3l(T_1#WTl zZ9X$##wyxBI>?WIyx8L=UNh$a{3jqp{kk^jz}SNhAAi>@@YQ6t^}}QpILJST8rV5~ z=Oy}z1Ju930>L1l{>kdI<5VubdRp%4!yhv>S3smc=+hB4kPoQB!5U|(D8sV+uCf;3 zi!WyTU%HF+D#??ytYOWDiGj-=_u?)g^xseSiY*vVd8EdZ4?C&BETzJ+#SxPhRYF>0 zUy`cC{{{U+8_rrdBC?z=jrg~dVA90DnO@^l;k`6ZpP=6y_2#)iNTdG(CJW-W<(=AA8s;@ccRX@ZZ*P zf>iXjEd0$%0KVtH&xqsGsrm4ii>tmT_;d2$KN7$nmJk0X2mjbC{5e_pw>tQ5{wxpw z$%22J;1A1%f3X7(eF*eE4??{!GE2+#7x^^8asn_+R1R56!}#9Kf&jZO+d}$m7gfN&%CB_rFUyC&neYB$fTZuth5w+@ zANZs5;s4qZ`O8`OcV^)~<(Pk`eE4$&|6IWzode&ozvRp2zvj`W-ogJzYl#2oEc~k+ z{Gb0ck3Pc$|6_o-`7wWdf&ZL*_;0&Tye$iVvl5IxyE*u$=EGmkcmI2WKgZ^{yz$HY zIV>OkO%DFCS@?4T_!a)|CFD}kH-D0c|75{GPVjAh4De?jVlre#8R9Qv-p?5Thr0@% ziH8K*hXk89Z36Qz7eA+>^TJyEZFIZ;EI`sa*cvhrvlH`_OVTJp!0Ep`1%9T$PtF1F@IQZrtAe*$H{TBNGl6@e6Q)l8$fCb4sOJsjfj=Ce z?P)EIdLvD~S~umE`aj5n=nu@IOC~k}{T~R}Gh|9@o$G%yKl^6a>sS1kUZH~{{-Y%L z_gJQ|uTfDa6=AXV72e4op>J5xvn6g$_<(D_)2fww@1zYdob4EtF^ZT)&4q0+fK8nPdj0@>LQbjU%=t^f{pbW-RYj()ddSY^qwgf5U)a=ZQJ zP@&u}`MfU@1pW

Pn`-BV*Vf3brAj#|>*qtWS;U$Ni|+A7mEe*2#xNmR1Tr3rttv zMt@j4@zysE!uoQ~_!n4m5TzRp9KjaChciT-NX zh@+bC7wG#`p2oyieg>G}9^U%lE4>0tYFo9}uueHr*K@nl0S-ObD7!y2FfKN7yAGXX zl)WBH@!uajm{oDBm6d(tZYA^nl74wtN9cVMzuHZZp#e-)^mnsH*e6>F1U6=ocWaPU zYktd0nwgr|X(%N@-BF@nz*X>ThQ8F$;?9HZQ@Lfi$ytdgY9<7-HjrK<(5azEpu`A@ zN0JDQy@3z5Y-eA|eu|xSL`k4nxp(mjf4rN63f^MY*jpcm1Zqfye;A+qKR+w+E&6VDV1DpA zIZKrD(V_tn|5BGaZy3N2RO&N<5>Vm4k14L6HzgAP(JV5Rc+~;mnDy;?7z7QT@v1U9Q^ zwiC$o4&!9+=~rRyT5s?5-f;6D82*%QoqOto*aa)w^HD%u#Qwu!Oe*J5{r9i#@AO9Q zciwk!{nUXIonh7mrPD8MI-lR7=_hf1xss>infvj#VkVm#p!Ihz@k#m;Ml5gb=|54( zZk1JV?WTgQnX_@`Orl79kf~F85>KWA1{w4&&53BDqZ<;Mq*@@_sAK$U%UFy({J9-t9;TMIrO);f^sE@;C20qSJ^3> zeq|><{}tZIV{g^RVqn7PW8IpIsB?7Hpvr zMU>#I*S5^U`egJppw*A8#bs)+XOCWKeX_WIMPgq?@2=n)Z!gnv3)Y`r7v(Fl&LD@UP1b& z6|n_PFqBvMxmWpNdSW;4N{J-w+m8^Jtk)_#yvj}9$mor{dY`;3svvfkoE8$!lG@vQ z?A22KLKVmXP?rzj)Gq|U{?y#5UhGd#du!K#S(g_Zx6w;YM;?E^^R+uyZg^OhW;!vx z@>5v6e0p)aog}u4L(t43t6CWXr~i{?!r>o#pKSDYe&2g~d;C>4Xoh^(OBHrzZyhOK zl~XpNvb5ig-=BBSAGMkT8t@N#$$9Y&c!?Jk0}AgV`NW1Y4G|hpp=&&CcRbu3BK&2m>0jk zC^D06%mci{9vlY1ua}c*7d%1Mr|{Ijo0ea@r@ZjJ)V}K!YdATJTeCLK+LSrQOMV3h zwDZw%?^C~d$ums8aA6W+L1(<0I_1!W7a{}Jzh|bj1~~A2{|+8eVNfC3d1~+0``!Gv z{cJS}X=U3C=_7I{k8J{u6Z*A;n%827qO}@ZT1Etcq#Z2nni= zR|dqsvf=|TcGyZu=Zl&(V|^}~3DbDuKBO8fWBA)i)UtCQMSddqIx zc!SBkj5H1^=vbYp(v7j!`Gdc?AE>B<081mmdi)pl<4RqaE(Df*B8b)4K>61erE9SNc-JFm-z7CPv@m@bKb;9-d7kxgRV47yTg)dJ-|MOC{ z{k)Es`iB7q&wE39DvDXaxyN_~AA1R0V~@Rlk+`HuYtM0IwT#Uvszh#h^kI0=>je;j z!X6Z+d#ZPxNo>`*PiV+Cz3UwH7;->hfxxKa@^qMqs)AuyZccic)wtBc$rFm2tJ_;@ z=HKYXpefHE#73k4y#S6@Fg5sP55xL zCg*k*x6|33>TIuiJKoiZtQYGRATVl+R_(Zx<^Q+IEuJ4ouvsV1d;4zDl>6Iai?16} z`|;X>rn7k3EB+>d&DXxiE^X1Q(QF|!-Y#?dr(WthFEf(AwV5ONTa`JKzYUq;{GHaG z*~gNw1@K{4`+%6Zu7cxpM18?ux}kO)qN2U7;8SnjHZ7N83#vdw%P6h)7Ty&sz-&`M zVXlySjS5jcNy3{e)F1pxq1|jyxqf`*W;|^&)#3w$U`cGTE37V_3W+EO)j4@a;q1i* zoUEtwU1fN<$5P^T;@8!>^?QAFIu^f+HGtV$>JvXT?=sz|P!8^}m0Qs#FL)FzR`?T> zj+dEW?5s@ibziPI(MHB^7wU81Y4`GrXSfp)N}Nk%CA^Xg^yNp}biueCP)Brh1qSRBW`<<%*m89KOe4pkJxa7iWtr=LKg zhKZaB92u`!ut1X;(VHHyF38}8@18WUO8mNS1vAxX1EJkI>$^=w5P86u~0h>>n~ZraE_5wkn{X{|kbmPkyN-~MXaRA*xf-%Vjw&bLs~@xPLuL0#-c{BD zn*OP823eG^p_TpVaT?ztgrb{W_w1?9jqZ@bRDZ+#Xv80Ez!#Y-Wo+^8Q`$dXS)dR< zED)E_919}BvseAJ)yj1S)QX#>|I8bzl26pub{yohs_}1m)Sd$_A!}7PEfbs2FD73p z8OgFf?KkkqNt%L)f6BCQCSAzhy#HW*C~$}&P@FExuC7D?Hq+w@#kM|J(z?`3?n{i(Kg_1plGsSxJ6r5oA)&i6r=rpl z(WQm6Ugzya7PnAmY!`dU!q5FSPV8&MGP#+81US_MfyzZM^fW+f{o+->ICov9&41=J zro^LdO3ag>ZvL9v-M(Unod&RmG}BCU_T^>7=RQGt+)b@w{i9V|g-(a?Tk6g!*oh6V z7|*2HCC;kSvHw9VX@_xts(ZzTQ3yTm|uO9#vEdec_gmJ93}7wDr*e& z>(GU@F0U~k?T3lzj1Otcjo)x>sS4Us9JYnV(U#w%`+T=&d(NHEyFFvAJ;HzH=>cz1 zyEr2i9Uvs@(;jiv27)j1DrC?Snd8RbwQn(JM(%x|HbO> zKL1Dk6@jb;nN=>TFB0Y1zeQnF{0Y>xMlVDs42J#xWxntdod4@?xqo4ZfOTT#w)~2N zH>-bK(0&@2U%w2|o&Kb3jC53Prwy{6|H5$=iOF$*FN0^V&W?ki$I^o0L4RxQq#2U7aYq!Y%i!OAASlex2 zUzgmiE;+M;kaGHf%T<;4NLb#hTr0(!7zAbzsOO-N@+6DfRyLol15YLsIOem$Uj-;s z!8u5%hzr(8@7cUn>mSkQ>cH@`A-SpRZK023aAUggpff1 z4YtD|c~8IO7Wx~!;hkzH+Uq*~Lg%E3#9G!XEya5G6W0WDm(>KK8K%@4qr*UJ!Zr};W`Gt;Z?i8no>MG!!?$L>qHGOG z>=WMb&oevMrKT0|ApPQr86&iL)bU0kisk;qw_e};GQ=EdVwPstkA&Mdg%jKs|Cg5$ zc?XL$P?0Zn)$3-IP2|)-$4iA1lNXdwesl9n^~rOKPEXYL=g&F)i_;1QqxwlMqI(nRSD^Qr1X2t|6SSH0!h!-X#+XIw|I z3m$jthNw+ve-^4i5d)IoinLQIxHruPE5?2&8CXjWtXmom?KxOBO=;th%_iS50gZF~>=KK;8Vf7-kI*MDPdZr7&2gpQay z=yRT3|9;lpzkQAW=QO6J#cBL&lflNnhGa1Qb@U<_JU>=yIR35UGCRS}j8r%N#mjN7 z@nZaUi?1jRMZsP+ zlk^k?AF3fv6u34a3d~sGL_x4WtNR*O8+Y^;2w|i85(u~o

    #B(FgpNE(b{89tL^ zC#%f2*0mLi{sxpRE3tie4}T6UQMC%pb%4BI^&JWS-CAxco;e|J7`HC(EUK z>t=Y?=|rEO_cBcoj+>N+{WJ`>JCx|=z1lTk%a;omfBug^LMjjOjZ)Fy z?nINz)a29O35n@n99EUNE5F70Z`S^qVg0sYv!DbKzq>tB|Mm;b^#KDRvU7-k(}T8a zSoSyUM*FJD?T^_0+7QHl#h>ikg6sK)MIz{5zWa+^sgY0fWgnHg=j|+_%Yp#%MP{VR z$1c?0{!EzwN6Z>_t7>?EN%b+Ywncmv=}i97F+-pD?0D$IzqK9Et7}=y_io2&dOTY) z%)^*`OvVFe%?*PQ7xbsfYK}(J+R!}K%YG{0ddKQUnw1=SjbL)Y9|4^n@e)Ja<|~EK zf7r3gI~1JxA)QlB&!?jOeovFNW$oXe$u@ayO~3}MpND~8&qn9G2d%D9^J;axyByW^ z+Wo=jt?jOjVdL0$xq!h@N`sO`jOxQoq4h_jrRO2%CD}MOwYC6;Mu*7^amr1g2tFon z8`Qz%(1k$_gd3T+T_n6Ny4)yf;*~2?9r+4GzFN2yS`GfX(du-SOzw{UAaWg$Pp-sQ zdSRr+Yx2zQ?qEJk?gJMdjei~c6Mf)MUj_D&b+MaVs9+Tuh>msJ3aBsT)}g8UYO}pu ztCp8qFP|2C?{0>*;Iyw<3vSwGEztSwrp5XAuRpg3Mw#1k2$<7%dbIIX8}ytVl&CJ^;t)jEd8r=A=WmQGXWuNjv5y6`Ph6w`YFXqrx7q zR)1qSzOw;fb|aDoeb0o-V%?v`Xf){}m=*p)8i@!^SO@%G6m`F<=)~MYQ>$txn8i{m0fnk=uEJ@lcyxI2gwIjTF zEA>%(jY#QE|GO8c-()zzwX1W906@~x;6g8cdk`jg6@6m!*U*}fM#M!s`nRJa?B~nB zfvxLtvABgYObz~jSbG!rD68xLKLH{M5+_Kakwp`Y5?ljHn+T~127Lx6fJ-%k^&7X8 zy0i#MM4=j-1R1Ae2Wwj`UDR5?F10RgS*<33tQG@UWKj#^@{HpGXaS`)|M%zKXOC;m^$$ z!{?(Y`7KIX{+RS$R>mSKn&IxAq!5N1*a#OpiPqZ&n*PuC+Lj%4Po*SuVJTnL=D|qH ztD4z|K1kKlN88Rl7!$-p;klZqtN&$)cQUu_S{gFXjKwuOdv8Z(<49q^IBk^T+O0X{ z#GB0NV|g!7iHsM4iBcZF&ls&Fy6RHy0eQ(c#0Tk&+H6|Rl32F#^k9WzuhGwDeHkOb zxA?7$sh5%ecw1uy3)jx9w}|tj$JelO_^K0p>p%W|%QNsJ27EPdVc4_0y({2*_INVO zEgQo(g|XWJzL<(<%+A9H>T89{1K(h|55|kslqNfqq!Y@uXj2ahW4log(&d^m z6srvn0Hr;Ir%{tRPz`i1GMCg9>u86hnBN14{h>?Z!hyNOw6tWJ?}Ep?c@Zz zRuk+F+z{-RwsUOtrzzxAd}2lv-6n(q=y{xRc^;o<4z+wvV=gS~ zx?81m6~0$jZ5w7D)6}nJk+xEC=rf7K6Nf%qyRq@*#5i)B9K4aNo5=WK50LwT@%Z*< zt|9)}w^TCFI1vfWnR*F>9|y5XI^BmSe2Ja>> z_kSB)*TYyf@xH_MR?Wu#Tn0tjLwk@+QluS-?UcIJ5aNC|Ji!uY@a&*r){Y-qp!E6| zwSXDaT$biR?fHV~$uuwOe&a>uujfVeyleED6EcO{HlSE9rTv&^gR7;hrya$D&4}FF zIBLCOH%GP_6R;Lvt4E+4RVrudb#j*E;Ue+d#_y{2J=@PaGo!In0?f+%>c*M?{AM)| zr`1dIw3A;wQhC!<;ImXe>pf8&{DF$s8u2gQmd#UmZ`ih&$LQJkcV)qL}2{CaV(?3arDO-BU6QE4Kt0`NRjT6oZ(v&J+ZpRlqQ zTr86bJ#vB|*%ZTG*QL?sviq4Ro$p(~m1vDB5nep7F}4 z|IiEeXN3;1TcK#0eSQflWLXxw9K51w*D}9_BrqRo7{xp_PLoF1H5|1d){)2DZ*Tme zXY4ckGjx-ax!VNJ#LjUt*E{P!)A8(yVModS-9HseB!Q_>h9ML=h+UdsWGzKn&*YFY zkE1m>B$&_o_cgc@`NtWKpXyTfpRer<3Jz0V&UK*rt0=H(Cio}6a zP=OuvN2v|IYFCAGI;GO`@b8^-J3hd{j{=j)d}Q!%c9GEb=TXPZE8y2V2ruzBLN1dJ z*sAP%$1;Fk3>bH%d^Tj!9OhZ-?tJrru(VLYva1!XnEO0GUvejsnX_OXFPb*SbhwY1 zUk!W|mW^cnT7fz&M6>?+C-HFBG|GuSOP)0EuS>qap7-t;`_;7P`N|C8XHf(9l|PuW zE9UX^NMPyvkrvz_z_~xNu#QQ<())n|x7YhnGe1pD-FH~ru=d{!`)XZcCA=fxxr*rveA^#JoH~0?b&WrkRitr;h!`HXg&=xhpEH-KuTcmS}CN z*43>&lFC)`>FGyb@HX()hD$auneeq;!Ho=!>Hf$p7syNU*lM##0|7l1BiNOm>ffrK z(k37GwIW{7QAG+cF z4pgl7`^K+vDmFJ35aZs{=%-6_vK zhth}ECW3?*{}dav-aU(m6aD^CktdO?>to0n{EK{R?Ie=5pa5Me=Y@N{eemo8N*L94 zxgL<$MdOs)*M2{=i?=4waU^d!@)eWsm_YdcU7Us;IOYC!exiYpy$#>LncG_4hvw)i z5F!XZ$MY|d8% z7=EO`%SRH6dEX*#8Kg{{E=p$_Jb6rG~MteB=+0b zp8*5`e!!Z~hfJ9_`blyd+JZwpv?W!gVcT%QB=F;{_O-nLUKxFB6UyqN$tPyKAd3h7 z?&0xw1w>A%ACub8t6`S9ORvP{?h~{^l{N|{l)a)Vo1s1T-)<#E6u6PKTbHy>rSTtA zE)Y(%eTQf{#mVGoC+vgV6{)Y5cwb44Bxs##6Ff04()WbgikF*@@k_TDoml-hErA3g zmBW}S$FEMk7#}(H1b@ee1Mu(6!V;p-ebs*}wq-BcPT6l!qK`^=@2meNkkv01@we7@ z?#I=}nkN$u+2rw}A}(iuWQh>EBR6Kz z=hqU1DV46|Wi31ou96wsIK6*gV=3fs;YQT1b2szE{n_vM^Cyd}p%7u#u1m(xc^eYG1>@gNU;k5% zSSn&Y-5N`n1>ow6J(ji;+1kf496kHEN=}=}f>kG2^-d-mhsD~&eT4S8Kly>UY^mJ( zGgP~JCvpJ>@0!M|g`kdL_dZVMn}miF7kmdhnYKB_2lRarvoL4qYld?at~PX?aa%@N z7uRDP^crLQTJNi2eo`@EPLj}chHnMW|(At{61>i46*LK26ZzqlC=wMCsAA z*hE{=Lz_oleAa4YKQX_-EjE8+a*SnsRpWfY`;B_Qd%-k~KGwW2T+>OnvV!F{vw_ht z2uIHjZ>Z>On$SRrqkIee^$p5cx?8+P$s<+Ma?R?h+&jzdH^4EwU24{Nz=i_Mx4?XU zg}#9A;ypsk8Y-%X`)2<_m08eEUQTumJ-x!W;O2T()_YbLHiT}j_bs>;?E9wnYpB?0 zoJ(ujmSR={8*pkJ)c|MayJLT41gb|10&@h=+(i$wmvTXks@v{CT#6*Qhlw7Lm)a^yi zsMLG=<0pCZ%f~To6)YZHNl3SbfLf8}|` zfrsnYll9w);Xl9J?|Xh#^`a`u_hHPfK7O>6kCOeZnLwfMh3&KCHQlsf0f@=62QEGVhTM( z(IF)h$fU-?E&A5jkYjxPNIZRB(JfH-_CowjfzYK4K<5>?x3PfKQu)bcI0TgQ7s2!` zm|E5lntGNN+7(2k7;+SZq9<~FGP8~Fg3Sqk$2sLTl=XLT`OGBYe&tPfvSX#<_G}KD z36Gtu&!`tL+_Nx^k{_0>oGqr%zwis{jGD;#UD2A*Y|}AanN9r@9TQFUj1mYQMDNUuVcqvX2gG)Z%R;V+XYCK}WVf0EixYH0U}W7Ac#_&YW-Ef^)8vAt`{-rIU266UJ){OwD#yvAVN_vICnXQMJRhhvx zIm>+WmpPS^a$oRuNX}N370dyh@><{X>#LVk@uJpOvyl{sRX=WoS?kKqkCY7HVzM~= zo#y)UBZCHviA)lQFN4GTTlwVO8;!j~tF*K;+RrMYW&{3>F+P0TvipYG;`Oy5r@UcI zsIH914(#5+jZ+VHvHOnNp7n+CECWLf55tMKVBNBYDE6=6`;%CZgPnJ|VH3G;G``_L zO0l%($C=Io+Ho-bvF2a_nM_sC7ydxXr(etY3|P(@?Z=KGkg4rkV)`#GIRw+Q9%n|V z6w?>7UqrkMzq1WdHo#D#WQQC5i8d4Ck7&F@j6c;dzFhQn-$fPnF*8K_5fIAL^pVj* zk=xNnW&tAj#Ub^P76gxFiKEzK@*97KhoQYO*WM!klkQ8xuVG*fYNMJ}<_}e}<$nL7 z8hY0KIoFHCM(&fk63@AMA594dq$_kk9MDZbNT*vE`|K;7BglxA5BVRw@t^hO|4RQ) zV3HfD>g`7^{Im93VR+hbdTz$uBQwq?Pk!e4k-iz?=MyswKVMRE;+UNE%wyKeKKJa4 zAM(w(@Fknz>502WmqT#m85Rk0-*%%ea{cA5Rn?$7_3DZ`AgOB5J*CLR8}= zbPD`zR+LY|{x{rwI-Fb+S}Xf*$zH3!tE9gf4&dUG{Gpfp?88QT){Au}OM{ovKSN~p zJJl_>!Omx~P!I^Y?hG$fvtGH6hlovqB+Myr^6ua)H=pj$Y+?jBFE5*IYzn;iC(eZc z$7$skS>;*gWR5n;HWQ$dl}bTjyhZ2ig1Xo&2j+|oLv zO^#8$9B(v1zG;3H?I&@GYRx!dgbUML!j+J#K{GwMV$-wu+sc*WzRkXF!7Dc{{(lmy zA;OPnk&51oAN`_6v=YNf5Bygi1}0Mo7BLJpp>``zV~CQ0a#qmF%}u+NstdSDlPY)K z(T4#hF$;>le2_3%`6)}u&wn|-yd97;iev+`y38O`${^#@Ad`r%^TwBDhzH}#Q?pa! z%UuVJFTXHSm-RkUckuWk;i`%BVt~m#{4P7d+$w=Q)(Rv_cTCPIK59>lFlP!@IG_>c zLP_HqJHjB1YmGGCfB;>NG?pC0#SiQVbJ=;3LC2(xFg8Dr#upPfVC|^)Deny|AJ!JX zk7r5(dAS7gLIiRtHy0w17fK-Cs_l7|5y-bCiwI=5u_ZCGu-u9)E^~)}Vg(V7YLu!^ z3@l~?UA<=CMTp>WW?-pqxfKyS-5XK%69FmdJ5IdF=fahQAy-ThXVaBbRk!vki3Te} z?EW6Co%(aIj-SDIhTrPvNH*k^vj~hF3?bekUx!&U{UBU}$`mN759T@CSLzIXCCx-%)9jh(=;Ne${&Sppwk-W^ zzWzoV{ZNx9t4LSf-L0b+;hvUwOy(qoVly2#(nE3wwNg6VX*)OYF%M$?xAK9mj4(^ z68u-lnN`?48I8E_FwMkGXL*y~-ixy-7eCptbKc&I+mwd4>nSi2as5RkghMw{+%{7ABZ4^r9Oi)w7rY^vYOl z9{A2Dn0{>o^OJJbUn}lNVj;)%OdFDzd^avp&#^rw>rIkOH+=NtDPyfSG6li?Egf!uVm z2t;A*M5^en<9@vsqft#n^Zmz|FI8Nr>$DK%w>JFt4zcH$K> z{2j4Vt7q-lPX!V%NSUUzF{_-=B2$G(?&`LY8GAAJt7BWkm+bu{+`w!o4ZXPrK%GX*YR!$)MtIkmkjEpLq1 z>*Xd@9@WB#EpYS$N3$LM5@|4X5PGIaJy|N6v+2Huw;}8;cOJOHu zJn->Y26TJK$g+y`qx(K*{;sEBNvV6N=aPhTZs!D_aR+N(05j zT;7I0O7;S=o9YPKA3F?908L&Vty-@kF;^t3V_Z-$tOq&v!Gpiyf!VCJfBqq~QgHm2wbB`1wqUINB8BV82z21o zA}R7nK5>QYwcfXdBte|mO(=+y=erYs6#YkQ2hXWghPnyawUNHZaGLiQkTp=e)?cx8 z+Vw5d3o{z)CAAYQH(Sx&8sK~zxLY9)X4J==-WLe1aQ}L~WvvNLcyxBu7>#uGg7H{4 zW@kW05BJCmR73z1JdQ3-j85HI zW{#Bd%p*I#4fAM&8q(ULeDJGGoFGp|ytz{@c%*(Ec9NzOOn5ckWj@$DwbMmZ=9$rG)<7JM&!A z9lOm$ZR2}Yt^aIX;E+8gSosBFYjWZJWof%4=M`40&0Jik!v5Mki~qzD%I!a%lJNnAT-~0(zE7raZdy^q< z`s55CG~d|yJ`T3NGVR%U8C;efCs$GQeidQ(`i^h@RMLN~$YUo~cxq7`|GpW@jZ}2H znP;Qes2ZcOd9uO@A7Kc_nSI{IFzM}%VcteDLu>bjK5DgLHobwshb)|Ei&uY=hM4*{ z;Z?pkfA7*f0{A{CI%13%PQqBWZjMW1hqFy!7|CJ zai75U<=+JTq=x8U^%hr!tc`}&2SRI!|6A>AJ3>QeTbHkOk0^&p4{cd1%=Txtlihpj z;el}PKqe?VblMqC-A<=sg>UwA6!y)(%(MmqUse=H3QcIOnfL8C_J=#K+%_oBV-=8_ zR#8SF-rBk19#$KfBb-h+pLF8urcIF5ICPhPR=b|cbq@(h_-r@G_}O5;Z%b{YuHC#<{k1(<(s5vbjtn9R}{feV2ITuxRD@ zmaHenBC(L z;9hY{_AQtD=HHS}IHsY0g8gst*dLbK@Am$-<@_QkLo?_AWJT*?)SW=?F!Pqq*iY%* zG+G6+-V0Ya<&`%p9&!X8^KFs+FDyWpVJhCx0D{_5J|Rfa*B;xxv|1Q~&j!68YhGDu>> zq{U350^vJtqdNS-j_g3_ZrugKN7TwDKBz64pNTqz#1M3C#%A-eA74McPyYrg?ld)i z+%qkyr|Mp&p@Q*(*@gRAuB|LXlB`dGkyulA6+x^g#3rkD#5q;$xxJz`+;RGAm!#z}GF614kJ7`ZdtfxE58)ES7&QJkFHx3}7W0)+Ex?>=iqWblVj#NYpaN zhkJD>Thq~EXQb>z$yjYzPBro)niJR64@iiXUOfp>_n7$1G{I1YrN}-6<4hoNW7|KF z^p&k5OJ<(f0&>)Y@qou zyI}lZ88-Tjs){iQduT-qUNU9}BH%uExMd?a$e1@C&%;I(5zoWvd|^PFWP%=7M6z!E zhu2^3J&zsSS;qf2*&BsfSaz;vYkAX2p*5W`)BYBw^EvLNbOpgp69z%R*5j9m{#^$1!Ke6WE~PFMaVM&#=v zGKT?W%49P-g-PEy6g{}b0A%1}tf>xeKZi*$fhrr&>xTt0UsEV*B>$h9*bn-r6Pc8) z5vMuek4$gp)Y`F;v#3OKyNu?I?;G1{b#nYvcK+ZO8tgPYb**zwfS)vIG11~F0k5Ap zIa~3tdmryM1GmZIZ-z*xnDE#uyPRU&?d)IsQj5AjNZH5fh9nqkWGAL9*-+}M#i)>PogpWj9lZ`%BA?p@G9b!8bIiEDq;U)BiuAf-P zB{ba<+{tQm{^3z%H%CEBzS$ZD0+C6wI-%+@P_-S40#nq#QUTW(pC4FK`a}O92^4Wk zNh1OR`Zs=vziUNp7M>d5hkTMA(Opbx@04WH@eE6jKKU&5iEjar6r!6CZM&+Pj*d*M z3hr!gsCe_1B@Lk|WsKs+OG3!O*$p)nE1K&Af)N>?Nn}}M(Ah+xS$l7TznEDPv1KMC z?KA*1mJ&%xEN=I@;5D&z@hzZ=#9W#Zb!EhJSWM|yai-0@1&yXaT+SE#Ju1!WmCk>8 zdL_0ZNpDNP11b731Q@55+=yt{dTH3nZUGS#ZXSOC-lrbma+sR+j~UHY?bf-w8z~b| z8K^cP5x=1YfezIqdbe{8YmY}&BmTe1)}YkFpG2*w^d%SYzOUYM1d6F)nSDRf zzOPEYf5LlTZr^X?Kv}mLByK`J zpOLH&xtne@m1z1cl{i+F7~>(Scb7~vubw%JR{)^>-mA$L|2+HtIlaf|VE+T}-FGa& z56XFp`^o66dX03G-9FoKR$mYEdhNF*2L>s5jJ{u^Zu$dH&HLCd#9EM&c~!!jr!FsY zA12wY8j01X7bwL-At;KiPWQ5==BEs>0)bIy#^ujRao}?sTrJ4Ys zT0)=M33oLU?#w-mpG0((Siq*c^N_Ef>Rk{yW@TO+A+?L7WD+S8qTkL0=)@}05 zKdPn`vs}B=gqhD9$wo5gl9JwLev45<;>&GKSNp>YWsMMrO)~Y0g~pm7KGU7i)AnVR zT1ZtQB=4*3Cs%j>XhptJOYQ!zc;H`^?w?^}5eozz6s`TQPi(v0`4Uhk3=VSC0j zX5M{|V>I*y!oOAX4Ed~oBT(^ML%$0|ze1_Td>MXro+FdB%w3dedvLOPkV<+hL{m}@ zp&Hnj9EJLfx7dLOi$~Hx=uzRU4a-ce4fm-f%Cd1#o?q*vj^cIEPOLZH`y82w+n_U%Sy!S=!469U^U&$-&iFQvm zuk8LM_;V8P-A&i?XSYT2N3E`uP}0*+zoA-eSbT-2L-qX{9;7B5R=+>Si|&#tr%2>n z6V9zhu`#_}zeRTRkK{g2+_%y1BX^Rj-sqPivjCq_b<0IoN-EY&tI{{6D|+>KNRtbw zT;<*XD${7AF*us&n3m5TlHeNuM>bq^bv3L#R)<%EIZsnxd<)925!-;$RbHs}*bbHQJ&hI9RdI_>lQ*v*u4H!0`ha{rAh3+ZfkJ8+ZC6b(w*jH!+~|ea_JR zGJ)|!#&&`vxT802(`K?O4Ya{o8{c!fUU7=?&#vNQhug>?%uu;~FvV6nIbXzjiD5$< zW7=w2HRnw1lBFCn@)7$?5XH~4r^RFYjG|`~8IdUK$yOSC3k})pGcr}gYV*BM74LXA8^nc%9>JyA_|lw;&!@W0n9QFi zAb(`5z!Kb>ps6svT0s!?dGhPZ&<0nAib07hpO9q_SUsWXZ z8GihsovLu?i&{FVqT`n1@XN`0M(UG|?*<}+*s>1FpRhtwKP1c(4F?QC>>5tX_K2xS;Ch17#7d9e?pZ0y!TstmI%T%g}6oQ!6u^IJ9)3X=>;-w%F|34O6a4R4Yj& zuSzn?L$AbgfbLE?MOx@qx_JxK&Lk5p6Fa&YGyO9;E|cAib98wiXS*`i(9J>~S{d6% z+=b<=js$0k{%xyoiG6RG*v0^YwciTlY>JwahX2}?IIRnZ!4`7COx*;^-nb*02M}&s zkz(kaFQWcPK0R-|wX4jQ2q?BOc1l_>WV+yc*H*thM6Y`Kttc(hBI~!Nw`(w82&ka{ zrRWl&6>c?|4ZB5FutH~!tRUYwi?de`qJu-1bd*UonvEwj-y-kD1>+Qw(~hHYk+_V1 zcf?s5A}(Fqo3h>b>-6I_tE3`9Xm(>NT0=n>6W-6ti0PQuw05Ze%@=!h$I2SZN7x}| z#r(l1$U}1A8Q@{j_hSrw{%=M(8=8D=K7@jGTKmaGYL?a=_S;y(umA~TO&>! znAqP_vD??Wfo=$o=tq5nD|%MkT<2?>#RqddW3dPcy-24`@m=j7**nb|o>moiXeBI? zHIXG*w`pId5>wE2c6VLKM#q~QeDm?^REPFgb$;ylUg&a$?mp#ZSMP^)N(0(S- zRmxb#hOGTrO~jkX#}%Gfs%Lej&dSjmt%c=NRzKa3!D4WbCyT-T3Sju2-inGY_|F+8 zK%!$n!^-Lg5yCXHFV)^bwF`bh)2Mbo_bIKAYRYpbV3~=s{d2F!tYBu71i?oU=%lShMSk5>0IEK-l zvgGjkrynr9nk|@1e{KwetkFC$6QgJKAhDsQhOi=l{~%fXXSVp?mQvi9Fn5~b-WGuZ zibvIoY;>mmi%OC-cL4 zEqQjhWG|YK>6^crC&%Fu?ZS~k0$l2Bd&Q|KYdB3 z<*!@+e()_+PX4{{5a(}Qfkj#Jk!q+ao0w|(#7QX?a;CV~#}RS!CaACwyM?1E+jM7P zRid+(|BN1rWc5xy_%jb|51NS{bS*UY)slB82)JzFH9KbtW9Kubchj${QvFvaLLwYW zb)bpf$|}Q;;ez4+TbY6M4`MIMUOCfQJ0UcSXt6m^-xnDou?)}LT*fB9-bX7D<;q4B zy!`xF_Uy75PtRkabJ3uSs)m*4OVT1)mye`B8b3)WfU?dQ^3IW8QXfb`6>c>~JtRM0 zD1cZ5T~|R@Bl-BzvW^ynBR>^Ijp=>?^}mE-zNgplJ4nYZMk)u;ec}OM#k9J{<9rJ) z817pzqkiaTz6Ic#q21P>30=7}^b19K>&i3`E+_+`-%|x)$UrytagX=HLU>tl)KTKi zMy;h@vW^Dt5?XW|v^Y>;UolgFoH5QvLW$`Nok&*w*;ISR9?Pm!`9h<%CZM*e6Kbnc zMarQK#fLGIQv)p|x5v9s!<)javb%o9AC{0}cll1Q+hYS#o!wn@&7GBBEya8CTgW+{ zf2hoehNEWWA>?a#9&8tjs?@8C1q~3X~I80Lh??_f%gm=bu(#O8bcdL1Wf9rdiA6Wo*RZz${ zd0vVpxZU0QR-&b4-G|<^_FYKLy!K7zSk=z=;V^IgG59&0b%JUR-%lsft2(tG8%foM0|gK$bFTZyew~72Ah})q4HmUUzxE!20;e}cfibjLq?WF zcdFcL4Tl0`yL02P36@J%OslmzT89Cfv}bK{JhxPKur{XfcD5$RbKPrSrOueM^kkKq za=f4@erOW*9Kncrv|p6pCaEXcA@)m%<@*1 zT(T5Jl9b^r>`mYxh}MY0~f0WK({O;*3%11E&DN^?hLgqF_INYFxlqGFv-5~)0r zr@MU5emjwXaZ`B24G&k6)G>Zoc*Ip)A>sMH`=GI}4gZsl{27F*mYQ35EugTk2nf=U z)V0cpG(-PSLcB1t5EbyFmTR-HGZHj(q#HAtPGMHhK=DWi=C{j<#Ne}#_9+g{v z;KTu$8Ax@$*`z`9uI!7Q_fEe|^`Lqub`}C`Dxn%ERduR9#y{!%$rE2&qdNDNn5mJk zb(U8!Su5h#3T(B?sMaH@mOUTbU51?{RAuh1uJEJC8!FBn&Rh&mM=_^3ug<-UHTu}K zNMA$f+_Lnx+{UoJosVqJ&!JiVbi@R?A7o9SwM=SbLC;wfgl@K1%4#9eQrV=&kX3lPmiqcF!WCYH7!)uv3KQA`?5Zcwt&s*=ct;jb&o0U^(SC0MO zUo)+Ov2n3q`gD*y=THBJ-d=OQVMbDXfvV7*@s{Q8LTbb$%8;60Luak8&q$pcx{E`( z)K}T@P?E})zE7p-Tg0xSTcE1+Ss_8b)6Df1CD~~1Q-qR9STFQm?&!l$V&Ewl$&Wo0 zHBS>kn47OCP8PD6ofJDa4c0kd1#52~1M6dcz7p1otkHQ&Pi~s&me3aQZ*1ft$=a=b z&ENItOVxAN9*I4{-kf8?xvTn*%BaX)!QbZIHkWRWh9`4LO7PqjS)D$dzhKm2G=}du zy1Ku*dUlAew*JL=+p;p^4^GGe ztfDUA&O|Oanb`610VEhapvZ-3)17cWo}mqmSTOfyAoMm$_C!km+Zl>$hFCsUQiGU{{$Dwpu79EZfrc(wFX}|G+e% z&D>OReu=q3sfoj}?=VB%0i>IC3-|+t7QF?9OXNawmEv%iT^&0_3Fuyne=iSv!s;yYi zg+*0!6fllJl)1m$k}m0<3{XTVO-y)SS?trVm;ze^y=a!Ls1r5|MbfgR>`rJU&!mH6+=!+pJm{!if9Y1*&DWqxf8@DOoX!EC?*K6x zwf)bz2?h;}Ak!1{+3ri5y%xnLeZ71IB9D|jNWhjo0ysiwj%mlN4*&q&Vf96%alu3U ziSwkhvbAKtx`%(*WkWdrrL{!IhU*`yWC~w99Ekg%`Sd>XO7{ev@cKUUt?r*O_m`9m z(al2d#?ei?xoI^J++z7hg3nu&w~uvio?zH3w1Do_N`SXMPzV3a=aqY*{`>?^a{pH) zNnxkTGIbj6yX$dHR@jZ?pdd~qIigwztw>ebDU`vbD7~MQOwqMYTW&3>=TiC!Y4hDP zL|+p*WZsh}FI(lPuKAWT;hfN4N+#=Bm|Y~Sr|4rMumTjV%tyfAla9@*lI8r!IGdO=@noUaWjOerps={PSaT;Wgrorx$;|!$P zO3!8HI|G2^{)?ya!R|fwWqBtr%RtjW{N1Iz-lXSrkf;gR%xNdP*Vv+^(pc!o40nSH zK4l78va<}5iHScgpo&a8@1S~|V87q?65pSu@9)+3H}Nz+&^^q)-19aswW#Md>E#5T zy75~6oFrDORw1u(BC8`(yv%C|b?ec5X$UovFI8#|Z`F0`Quic1jAV^ZmMZW{85nae z0s1m1DgCxh08_nK>aKZ~UX%;24t?i@eqB-}$lxzG81D1>du*v$TX9GJ*>?KoS3s+zy4~yOag{ekFc-?) zi}fUub)kw#PrIXeK>rOi^}o;5F3gU24@b@M!lC&AGFU1^;fqRDDMNwT7T+ggH)Id~ zfF%0Xv;r!s6+XpZy4&<7k~L~qsTW_c#w)7Ufq$DFS}x5`RQ(C>y%0$W<6r4C57hg;dX++1?z?CIt! zE#~IfdLEx>ggafv0ktzl=VClk)V)Miy$s6AIH`00Zby^% z^E~Rn|DyU)YArS$PCfuIz`bNR+H85ygafcePDIwt9|^Y&R{re>p*zyde?aEWhm`Jm zp$!*|zSmgUK&wkLwIjU_$8g5hW-O>;moCl*3g??dq_t`0_9|!A4ytSpvXv^2i)p<$FsX-1R;yf@6DBvt7sG#i!nE&U&l48hC})5EIuzl$Z0RCVe;xC% zo@`Z-3A`dR(^&KLP{P*leo0=9LZ|2D*&L6URsaX=BJq&uH*&YMg6w}L1LL@{Gl3ee z(k8pcEOtNsJ7qP&RBcTS3S;xW!tnLjQ2f_?smFWR%A>W=?c`OreAc7!Wbkv*yQ$0{ znNVmqQAcv`9>xM=XeAU3b)p|2w+QiMbFuXpZ+YrtHK-rQ$#9&idxg z^8b1CwpWLGjVe>fEwDJMNibpFq&=K(u8FkA_lN7AaOBT^TowrTT1Oc9o}Zd9a=#5P z_XW*X4_Mz(V7UaLoNz97cj(BIdL)JP>+H8?Z2$3mVutf-BcTj-Gmg1CXAJpMc1V24 zCB~}Gux;>4iTjWOOno$8G{$Fy!~B;tW77_0H?$A<@zbQ0alc8C_b zE`GKWf)&+v{ z_ncWmV8S*NJi;2&{;o~TkCh;T20?Sn62pi@u`J=ve%WJ$Xl&lsy3f7!ucayaQ$I%a zL+pr05!ub~^hqf@Qo=9nLU||_rKsxe=|sVHu@Nyc-HApCMyZ+I+s@BplDnGl`Gx-A z{!zZ*ueb|VzT1mwePh3|;lRowcQLEZW>e?|*<(XjtSkzTFRY1FXOge8kn;nApN(uf zs})8#fPY7x7R5fVoF&xy7q#AL5!9@vaN0FwL?Nwnx@PaEP}n3&jW{@XO@dM_gddsM z-k!F(J*e;>krF3fhP&cJ=*M(EJiST*GD8T?aXPvRosRc%qEU9TSytDHY5pn>J8K_9 z-lbP`c8j(|LJ?MoSp8X;fm%2I)7%2qXWi%vGyv)rX?=ztRkg~AJlCRzIN@LE7f-PS zNm-7nFQGpH%xbI0J9L4!s8s4Lt=c{at%^M$Co8bgB=UW=t??MZXoA>LU&#bk{*F!c zKMD<&v^6ZpfB2Xx)h4kEE%UW4*IgvoZfZ&s7~i7IWX%Glnp4i9gm-V&TOtL#`B(Gc zs0l?#ydri$t#^xm&X@6DvY%%aA4F?IvmfNQHnb}m2$@G+cXkR=BpiI=l$dbB znm(grchIpMFs+i_2~V%bbsh^$kfzH{U+t0Atb<8`>HG@UPQJg5CFM=NqpCOd$b$uTZKC~Aa-6VMD=#o6P&){W-o_mU9kWAfYol}G-S!GzFgKzqD~G#tnm;r63^ zcU^B7)#N|FR-0BB$!a4vEUyiH?BDl>pIssTj;?cRiw}%JXBCbkQE6>tQjxK5mFBUr zhRU5fX6VN?aKNc-769VmKve(NR=noBi}gR+d}E1IOSn|zvgQ7c_ZYK3KgVDE+69qO zqsSzV^^mpur^S>)$r0zj$vyWfk(xw{E6**IOp3cuk3?Bl51mjLFZbiy&{s>6U%g;N z_wdAb;fo7x@tzY3Ll+lTudFHrOh#}<;iyJpN5$mF%L09nhppIecZn@f^=@j?~@++@njiLY)fS&x^3AST&Epz`qTTs+XY}Nuty@1r&_1G%O@f2;f zvwcse>#U6y@cTKLPXUVRV-IGmmn6DtC1(Z1KGT||z5Ga*^xx^yi5nSzCmD>k-idE* z4FoNLK)!`sI6SmP3wd?f5@)uu?{+djb1HIQ{CH$WQxy<{?T(e@+1b@8%~}2Rs&m$I zu{$Fx=Q*vwZaj-S_w8v}88xB(HDo%dAkc^3#io1y=qla*W}{}sAMQZjQZG5ZI$ugi z*Q2<{tg&GAlVYts`=Cf=&8b!G;L%NC)NTF=szl_4d>3YiACLwLy=nAM#h&J)UPR)% zh}diHy;xWAKCDGZTeH^~QjQ{z(Pu2B?d$mBxQ>sG&HSR{iyq-c+X2zG*X|0c_Kn*$ z^oxo;zVkP+Ueh;pcgFGrQJ+23AP^1D*$%XD!M6R7U}MMU$924aZ06RE&wI3OuukA{ z8!OgNI|`5eVa7sT7M`P~<5v4+S{fnSS%>&*`wts2(SMB1HP{b$P1|{>o4lwy|8B4U zO2c!v^LW^{yB-jh@Q4~!E4^ph_L|wUZ`{72oA8{S|0b)YIRwyWnc9kw95RrjE_y(a zERpiuzuco`u=qgmVWnjKefNp%3 zOD(kRi>COqEPjF_Vj=|>?Hy_2HTn!&eHRb3jGA@NzeaMtCp&kz9?doIXD~H1=T>Wz zMl{+rOUuyK%nAD$5%!Q$YO868Y2fSup2ZUx{00DMW`BFwEa#Ga!x}bCFXRBn*#I+V zNFI!^$T`?t)*~f%a7_xZcXbeaO(Kc3Wn(^LY@V!(&_;K< zMWL2Q3eE+E;P>&6f~Cy;7V)u%Mj-xc9+T3IIQ)%*G**J_g$W>Wj{<|*fO_;Q?U?C@ z_*=eltCL`mY<)+)%%oletc-p4+wGnV=<__anZD3lI;1pq>!IW#K?tvAwA$>tk;4!S z)N$D&Ii6lToa^^2Zhb5(nU<+4sROae)w$z;)KpUn{~TI5eG5hOsdlaJH-B%g62pxIQ*I7kr|xXm*SOB8bsB?9eZei zCeFn2SNw7rP?3UbfmOqSXGvhT%jMZfbUE_}b_USnO#@|*6W%QTjO4!9gA``Qow)5D zOJ55*Sb6rpAd3gvAq9V5y2lv~5OXvSsX_`v0{VQ%w$Y8MYmj|fg9okZ&ksdH`KUMj1 z>otElz(F-IXWzzAUs3%%UzFIhz}?PBTJ`rlPHj(BhunI-ss8of;lWXQFqsGG)t~-+ zx9a=T<<;nqD-(5ReSYL_+%7Cp*Eo^I%EGqyp|$?N68PDq*sOg;|Bl4Bz{G76+FXXl5AKogNGm8q+OhJR-K_A!@w5hIQqiuq~49vT4)@~ z=YLNb$HD)L9gK(!IYjNMEGu|)cxQ1s9b(PtU6N28srp^v)vr_ol&K#z zMFk-Q>H5=sI@8EfBe5b-zSLqwOLtRQZYXRe3Z0lJV{4UC`|g--^-F1dvkfG@f|mak zd*s!zOf;l=M#;|hW`!<*C2=7Ea3u?q9*gU?F5 z#jrZ>mE+!HhllI>@|E_%X?*lvmb%Z{@BWhb&f1Ryz4t}#Fa{C#WnB60d&3NdtNsj_ zGO^;O2D&?vweoBp7!iGm2ZqJIMESJ~(>WuJ^7p1`om3BK{eKE?tPA2WrnsgbW_^&& zVAxU_{Qw#@T?6hjw-skB!QjnUG)6UQZ2`^7tXbPp(cE)+JC}MDtUMnTKwbzW@k*Y# z$Gj%{itX|jQ`xKwc;sc$$=G#{6UsBQ0`@Y^S}v40(ZabyD8rdMgnp5Sw0%#t?_~Yy zN7xb(O2k$Dcrc2lj{rpq29{C-&NmqCV0$l%eTVa!c=@k?@-jU5UHuTL9nN}HR~1{P zjW*W5;?uVlYyRcVQ$s?z%XuHHjG#GeV&+G60 zqMP@-Q?G$}LW6&1O61f-0bd zvG{Xi)eK~EJW#TXl5Ti4x?`om9ISlfW7U_Tb3(Rz?>|)0{*YuBYvLTrixlJT#%;a2 zmt7lZYrmaLNk1u>gR}u|$DfafM!&YmBDp_~fN2PT-BO{zvtY`F@`9DkX=qMKqS^5c zXj&|q+q$E<^;e)dS!g;|Sv01c(D>5OEPpl8nhoE8X1YbwzdM?`Hqe|XG!s2Erkv0` z_K}E29O;B?@mx2uoi_zU#X_{3w9+D*DJMkd7(}*rKHZpT&vR*L zh_5|F|4g=ss=Fil;ztQYb38<*oDgmLFvSMpB%)9nqC=snw`jIL+pRsP)q!TP+EeVI zG3A8jM`>tEl4wr;1~hdR&9v@lzV}nmlnTvak~N5Irkv1Z8#IajS+XHPxYawpo~bNi^4|p*eK_I2O@E&vYZ)wReNa$dCJyZILM_ zMBhq76knfc&xITb`E_DiWzn479nB5j1I@7_+$;}`DJL|q#8d5QO`_TJ=GUVsw`ev# z-K{m}UJ4q+1_L}arkv1BHfR$4Gcbv0?!kz9ECe*hpr>}qETZeXBU*GtqCL;DH$;qJ z$_Y`|`>FQ)g=KK7-G-;3@%rZ=M5Pu{W_LsjG3;I(D8e}&B2!L?evyXgf+V8#ZyZFp zgU}RNG{5>&H^S{41DXLsvxB4sYL6)=G-srtdHa<_d!`(1W>(YBLuASc(f=4kR=?#Z(LDEh zifms09Mqz0i|DHEh<2BPNP9lq$Cg^cnQ}t3*G)0Plj{yD=AVp?P5XKROTjVUKIr3Ou+ zf3~r_Z5jK4Z$PxmB09M{qL)qqQGv*Ivxmr(6QUR2OOdTHiRSDyG+zH4)FRg+>Ugpn z;a)roMCLTiY!8tsCq$Q~Av!#XXv@~GC){?6W@2|VR|h~dNbPy3-4f1}6Pl0TO||C{ zR;Vr6ZuiQRLdrUbYIxej}udYqBXYrO4*$%DWR#`;F-4WFkfyfBzWDk)kCq(n#NfGXbB%;eb zL@@8B$GZ{d;S)XLU>^+>u!OyNQyQS-lYk0SfFj)it>_1!JgV!y`a&9*lhVL!W2M=4 z=)loHM=p1=C(96hvxr<7E#Az-H39_ zw?I_LD>vIiWXcKArD=!`Pa-N#Lv$#`@r*??u{)aE{h+b@|2NwnQ%-0;-kEC8BdZf+ zTl$(M8{O#Z4(h|}09C9SUn)?EPJGOON$~fiB%oO-Kr8;YThos@20%v&P;NS)|4FM) zeiF>+6qq}@gBdywFoOkV#q(+PDNFs~ zxWz5ElzNCvIU#CJLv%_K(X2E?hvM%!7R_zl(flfjrem?CoGB+XzBDw;S0u=G{K04r zGQ(Odn*QCn!DZ-idbVH=nOPm}1NH>}_M!|9l z6>vXYq{e7dpiqo4D6D1l`AdnGO!)=`Q$P^tj^L%)ATVi$-ZI-$TR%%A1l?k8+tpw zCwE&nO^+WF?tR~KQ;bB2q)H=AP3F`$W05RA#I09Pb*|`Moq<21Iwd0L?-yEv)|={l z`ev%Vk1tOU^xIx_k~-p`9;*Yvfrq=b_v-J0z$l2(9s)d!^w`hR5I9K$Z*KT{mY4v7 zUv)=tBW`p%&DgQPwg87K2!^L2cyC#v1#RDezyU!;cLXQQ1cBz6)_*v|!{Qh$FTatZ z)2t+xAs!afZTEZK_Tbldn<>_<+g7mPrf#dEPJei)8&&VEOf>p~`L@wjraF~r)!DN& z(dY-)TdD%*d)?vObtZ6(^ZgOQNsL%~Ur)8_$t0MoQecki4(8I)fYBH#|4urfr_umj zodi^x0`&I>yR~cH=>RfgettTbhBPn(lVD<<$!5*&4rb+*fGHMN|NXCN%{nd(%&ROm zTQlg16qs|mgE{_2z!>3}oepO6wiIKlB7>VcQCtU^BbSWQ|Vy3w$d;TVPh1RLzGlk z;euCRBK%G6&Yi%m4fRjFti`*GhgmD&ArDU=RPZRJ`Dov?v-zlCKR?Rfx3tQy)u9$h zKz!Q<-#xF37{aQ;jxAWz3#4gvX>~)c@H{0tnUAtVjJYTYlpNytw6m%EmQac*< z>o@$of#R?~tDSo-Wez@#7A{f?$%xU{Ey<`hJH2EdY}=sKl!AXRmt&c@O|lJVo&Q@p z%;tA<=lwa2upe$ob@jt9CJ0;jvPamkt$}Ew8mWI{xhxH>$XfMkC0lP3E_NcXO~j?} zoA?y(-aQ?a;pXrs>INUw4wQ`8w)YMZwUSyta8~vN6XU?S+5BXD#rkz`y3bqR;e5qA zs0<1Aw~JVbMH`lVyxj&>iWwjZ7&`d=QJLXxZNRS{&OMxKtt%cDyfyE-rkkB$Wd=_& zn$BHFU^@XnEc)*1Ns#OfKa(3i>uqpA)_>_IM94wGMsro5=Pi}ji9wrikVj+3sTSda zznJn9@$nCS+*}U+mH9wV3Vv#y6wKj=O%<#_T;~fer?ob(j;}*`jQX|&E5~gXShEOS zrPv0u#!pZ@ab@vwEHSN72+A5(qGzt*Os|?XMd+s`FA&hC5@cuehbCp4)iy3T;bEGI zSaG;0@`q-WYVC@1DrQjfTn=CgtTFM4T-B^8W!($7p~f}kEb*-=;v~uV#!3Y*MY7g# z;r{Cfin3J~At3+WP?@nShXinnI9YTZ58VQUoi|7INbFS~aW29)XAtRos@bx=zseVR zja4FX=)%8yz3=RcIhkvS!(?kaseOn=8QMwFtf})CF~H;BM?%5>qoFKX86BDz_=-g< z8zs{3x0Gjv&5(dD>mDWY=R@y9Fzc_C9&crbbBkyjv1TVq>T>&Yvsmm&4vc>G=r09t zNnYG@SM*@|_y2}1;PX>FoqlEDpO%0RK|`C}$4J*7UDV4G^Xc`5n9>^_Jn=MK zL!^t5FMy|76@NM%IM)XL_=Iej4m*ZgyKieXDV%#E*OClql3VOu=b2KUfLHJbQkfKd z+o$e|U(=#Tgi7msEP#0Hd!JHigKO3Yvf2XdTb;wN0r)Tg-J3ugtekBmiv&=14TvL7 z!@1YAvw$^ji5g>{GFtgVS`;gAcx6ERk3ii0eMQPC^!X>AUL;gjj99I=eQmocxn|99 zI6wL)!9LsA7Ew@TXGj-nw-CxwAAK8;;)lt?ZFH>(%|ODcV!zYpk*sT1p2*MOH##db z7NHN)g1p^|v9<>Ywz4%cCtpfk-%s1sQ4^f-I2yu=xM{}y0CBImnoJ!E2+hoWjC-mz z*ZgQ{IixIh1+%y}#-I4QC|lr!+RzQ;EItrm@1u;{KxoLg@Qv$=@PC=osLMOD-LNTp zN^NLHc7VlCTkuCDtDI3qRuW}$Fd^^%W9s#MNs9r*)|{Oz&we~4i$&eZg2pijaFgD~ z$+~B+i2rv_1$=U`J2TaLUaxswXjq{e<>JF>=~2G6O_YC~_h>ldh% z)chJ+84rYxi!Ow&aDDD6f0qu*92>4#$8puYWFkUTqlJhPtf3ppEKKqo{V7tY?-Voc zTKn%;2Svg}7ouqiFwOnP%RntAmP;&TLMkGI$h0(x5&Sw;%*;Q0t=w5AAN zSX1tvM^*iyGa0C;>IHeR!79Uw^QjC4W^E+vJh&*5^~Hh{h(8KR=Nu`JO+})m`h-+) zd9Vq2!c5@ncW+?n`i1>Z`M_GlyJ8i`S4478D;${-w;>5c4TP%1xS>v|r^{e$r(#w+q`jpN z7prtJig>13ow~~5VzVxWak^@mz7+-~AP@ot^KaL$_KKg)whlzzU^$vT(5j@_4R-pb#kT?9wz6vd8spIJL~=n78< zIH6D2_p(7R`?TD49cJES;0G(;!*=54F+)%#8qGC{mM=!TDjCjlCB+G$o$3Nb21QpVdc$ z!4!`_R@l>}eDiNVI`|&Ay67IZKmy~+{D$b>WlFrdE#8YWLCOhcYW#t3eqDaz>BZa} z%_+g`H~mQqZNL_ingufHw$MSayc_(testVV0kp~?P1!l6d&!Ie;cO_t~`ib zz6DVAfN#Mz*_svq^xaja3fL1|I7r0o1UhhzQ+xo@fE=b>ID*xv*1JxKpCOOkjI{Fb<2qv%%cYAqNW8RcUf?J`H0z2fhwy*`|5Gm`^b z&L_A3_We?;!jBr>ea$ZD@hG>4}t1bam_f;M*I$qD1zM6OR zTs^bZJ?#3bUZfB>e`u*cL;^s}thpCsLGM`J6U{nOO8FOu1Zu{Y8D9nXfkOc<7vMPn zc6Xj*=AZ7!LxOfo^f;0`H{(QFLv$xGq}f`bIAj}6KNPCJUv#4ULjzv|Su@Dc^X|Hr zpn}}3Y*0qE(fs^>Uc1BfAi**u`LScidW9u3 zcEG!H+9`I+5nPB3Zy|j<`hmMn-7$X5QODl$JQv$_kr+SbxVrlTkHs(MVm}wnzmCrZ z{|$4&Z+1*Q_Z?HA84vNGiURIK_Q44s6Q^iG7^6IJ2JHES5;)W^Q-WmFcpN3ik(EVK-^i-Om@BNNc^9O~oU`_1IT z%K+#80F3ef^=M@2^L&avoMCw&qY52**S$QH(qEjd3*Tt=gwPR77wWAagPqjrpODpc z8TRi=VISnjZwA@&+?7wsJj2}}pVd6o^6C{;Rm$vU^Q?8?eqB<;H)ei1>MPhqea!hb18MD{ zm_{QHFgr@)mxC`YefEIN>w{AEyqiM@pW+!CunV;Tn+Ra`T(gTRob6;fWi8Vg zz6!*&Jb`BW-G3OXQunCJWLR@~czUT*@kR3q;R&ZIB_}F^j?0-PgICNH8eJ5gdTL1g z+G(;|Ltt4xK)Ip>W?+s`m1lE$!FlG9@be~ns6$0fWgKRK2BRCz!X**OdN~65B+^EI z9>^sic$0l|aev;J5R8}3PEgg|`V)_Uv0aBC71b_tPJzGp(Y`WHsteT>rc6%bfB64c zdl&GkimU(s1adGS@dP9o1!}B-0dGM?6EQW>pgS0BP;2qh7R4gkRuPhjiWoQnayTA6 zUTRfrORLsft#{;NZ34>8RsnA)t)jL%F;)@Z3P@}IpYNJ|l7Lv>_y7FzJUM&sxvrU6 zv(}n5Yt~$r!QZraN&|HDjm0{~q48V5++-3CbbW8-Y{~g@>)Qg5_pk`^^nIr225Qw* z?s)FLT$!E4QPXDhKshr$3QWX>Uqfu7^QGa8o1^$c0J*Kxem*w0nIs_$$R*KJmtbq$ zjWFo*c@F(203fGCkNgX(fHBvKx#mjk7$kDyWp6wOa@TRVmZ{a2>yi(uJ9r1dX?2b} z_ety3&;Cr_eSF@FDcbV>a@V}y-7T--ud+kb@)-Hp4qyr2yYs#>`qwP)(hx9;lL}d0a##h*bjyp?EXE7QmL4{^?#-&i;K6&o zHoRjRd}H|o{?t)^-v7_?V{?<8i}KY$3-~9y>Iy_;Vcfo(T@=YIux|Gz&QrmikXpo z9_(Tu2eN+;OvDdt>yrkW#k!dq`P2%hKqG^;1Kx5s|2qn-otpz#;v zXUlfBvW@G=c8F!G+c%v~=HK|#s0jW-m{$0Q(b9+upZ+X|h3WQ&2(YE~E(FJa{wFO~ zUB7tQ`F})TUzaby<1O7v*VgrNQ>XYdc!kL(<-<8aI+50!Zcpr+IX=0IONyc&q*u75 zP4v~Pdms&lL%#pIo<9PV;FtwAT;F$DvJvSsyw2V^U@8wP$R7hOfq>@sW8pC}-YG^je)j z`Z4+Qs958lNuFG4xYV8%yYY{F2JxkmGFd4Xf{<(5zG?Z);%e#s4mrVmVEGylm8;)Y-ABS>UZa#UGKHVkN3*cczsZYs{g&$^6s`u}}IRi-@|t3_08S#=q!hdYB5MQdP0a zbrNnTQ2wRv_+84MMER=s^xeWww|aFmEM>)RjUEA94P~p~yx#M9b6YQW>6NUUn0cZ8 z0hI#YW*P@K&?vXhHHt%<$w#OA^S!wlJ~2zK-SOsb7_9@wv&@^j9XC(aK#R<;yQa~e zXp!oJOWg3V_G5Ez>uXi?Djxb1%1j{mc}@Yl5_Uy)#z(EI&4h`$2R}{wQqfmdi+`h?m)t$w)cT=( zQm59+*&6ig*|N~d;*cXVeE{|3E-`oOKfRbVA@t>w%D;0F*Z1^F=HARxENU-P4dG~Q z2bkH?l>6;vY@e)(?zI$_!r!WBZusU_AIs=XoW`MI(FSC_GgVYp7pCcXrdNHqC2TkD z+Wixw4^x(jBZso7!y;%k+c-NEmX-U39;xWvl-;RC36(F+T}MLFO29}+CN>1xa@}qf z34dSsyPulwD4Tm8raiIfp&cx`Z^pZUrr`uA2^TD7-dLUbFx;(B`hR|pV6lCsg#A=B zSQ1W^RineHf`0J7PnPrw+X|BYrxI=4#2$K1cSCm|OQfQ!Uq&^sH_dZD&+@}J-96N9 zQM1<(WrtO-4x=W!N58bFoo^B)R&VnEc|vDJUQ{+pZqJxfRV!huHG{B8} zj_e&YcUN|o-|!W7_ia-en0)(_P_|>!+^YmwJF$+3I2LouRzVeBo2ru2S(#2L02Lq5 zIZJvGsj8bi_~25lJg0hCGjruxmNn*>H+mOu0scs_-vSR^{^5*q{J9du_z&srwx*1L zVfB}U_2*^Q_c=zP{rZdpo2o6RsauecwE)HdiL14iXEDtBWr2!Yk}2*hPb>duE1xAn zBSnqDSS$(^vJ;eP!Y%`SaPY6uC=47ynWdAvd9XAl@sC`eM

    D($wn12 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

    {znbv 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

      }3!Ht5UP1d3AI2>R@G}BlfM`*qK_w}Lm zNi1&{El={ldrsfDev{9RiOytQM`c8yA)UFlub!yU9sF%E!sO%}#ReMaA4gsw8N1Jz zgEg?Q^Ml{oWMPr;lJkkg>M@O1u6CGb6w;t;U-1|1)5`_E9 zTU~EdPw(ZP0@*K^7vV5~Mfr=G=LY{ABfp4p(FaCQAHeK`W|1NAaOQ-|qniNW!&yfj zhGJT8K0+2-S%^oFN2 zSu3bVQYucdS5PAfOQ1wK$16WqJ4x_CnfsFsX5<*p;#{TujO#@0PWpAb1F{cm@~00 zUYB1u{%_O9cb~ebBxSvC#g5!J7j2%I`dvvMjBfR~V-8w|@8E8u&n61n-DmnkI#(RP z)!{UkZ<(FX*9ZHkHe)Zd@8C{ms`K|*Z#-rk#HkaHusHHJY*NF)ZRB7WG zR5b@GIz;3kDr0V0=2~yQ7Ovqkds(W<>y2O_p9@IXdxQM^Gn!;YUq|F3A{#wVB0>QV zUe!PEl5HE{nOrsY9IbhHNu+Fb(KLXDHV&nU92Iu%LYLN22T>~68Ob~#HCYP)vN0O# zkFc{K4-?k2QILAMJ+QzoTFzjxGT~4Q5rDCtePHn@t5q7Fjfr&4e^7dC{>u#DI@9ty zKqCVSWN7ydJktTD|0@{;vf1C(N|@<&sndvh*qLV`>`_;cOjILzzlQV70YIh~k?E+h zyV8pQx(1>Bj<^KjTRaHDf)LiP5ug#)~c(LCp|TqA3QR- z!iA7FlQSknf=4PVPR2(nqS-&Arz09y%^^(&f>RJoKDP7^NM6RsPV>1qtg9pV0|44_ z=lNVC7jq=Af08ny=|_QO^y$b_PY1YWc+dJRtGxfK?1N+P>#7`KsJQ{*yvk7JQR zEIJd52@#ttU1Mmt5s@;by^sata~o70Z9YFLeYW}qa0X(s)tFL# z5qn@SqL?i}a_uV`KWEioG&({+JEG|V2;NYj50qjty`y&q?k#ZO0?qJ1LtXw3&+P!F zYrWh>CMjew9*KVKfD#;@y^QSMRnlQBSzGjLE`lISp1K0!i*LE`KdUS6pf7IPcc+#; z=!13T=@N$ivjd?>*_mO`bu-L)vf+xSgkf0$y>Da>^sF2f#T^!wD0t>tyH}mSe?Qi0 z<2L!nZ8gRnl9OdIcfc8~eGd3SdwrO&RvzM#!F#&M_}Iob?jPQ!&u=*&9ZkSh?O6nL zc)HeNc|MUtO0ZT=OmCuBnptZh+aZ|CGlBp0J!x9X`0;)ipwHuuU`cFeHl5dJ;ZU64 zH_&g&0%+=cN_fWdqf!9+1+9gC95+|+IWpAD zWD|aF)7d`TV6RtShj!yxz!4_i^ML?;Dh6~Ef%aJiXbYc-N>-;-E z1a#QK!T-#EfT5;+Bo%#GYAI4N6JlXcGga96 z8TN^<#PX9vJ&Xod7wFJ$7Fr}h|5?b)QyHE_lwxJ!f8>3{_an%mI`dz+4$L{E$Y)uf zQJ)|YN(bQ6Y`;NU>aI$$pQ-*coRy`( z6$$&Sb$Xv=f3(ln%_N09>Uq8M9AgB(!BvFtMiPYRI;)$C{@X17#Mbgp`T6;CTg!j( z&(E)(1T~u*p?(~eNP%ShZTp^Ge^4-yc*~NrCJCrk>)%@WQ<8xs(XUzgxy{PYPtKZD zz9nBhT4;nbCjA+8hwPA6!=$h{2Qp9^5j&jkDsASQBImiPWzPt`Fm+1;Egw?9&Q>X| zh?*1-yRkii2LBJW=z6^Q^XI6M1tXJ^G}1Jib4n4ari^2e$RK?#3=eEAKQ$&Hi>eN_ z$)t>(3lPD=^B@SZ6681U---U{Hy_%@Zh2`LEd^amur}z!g;zK$6*YgHDU8r;rYNed zU5xzR+7){x@O6cUJA<2_F=J1=28EGeD|k%k=!%1%r2Tj%GT4Px0XZDyoD+7IVGR-6u% z9(Tz8p`Sy0g}Yzt-^$KD!)^unR{SYTA&ZETunnl<-gc-l@Lfrypg67tWW0)#5GUUW;0n&j$o)I7j z5^rHxo&GM4%fA>ZaN=<}U4Wt52cZ^GCk?@Q6l-HdwWyY@PWd-5C@QCz!VFNI6F^E89fuf5YK&n9bX{X2CYxSNE6ea4gC|xGT$Ql# z8m=i=PKPUMxckUE2#f|x4UF4VVeUn0`@m6(fKnp_5irT$Oaw?-D}k;uA34P1TQ`R)8UL8WFvV8Inqf9C?~GDy z@BDAV{VMd{3lwJM!9NlA_Jp0!OM9}#fTECPWV``ix~dsH0)^+ygLW6&TCwpr=*Aqf zSt?HJ*in89yDK_}5?E-#gDCz1mvEj)_K>mx!AW3D*zoEVB%msj6WIG-HYP`!J#eBca~G@iX?gByCOT zY?~h^B-$T^SnIqKNnv!JyrvM_HL&b82Ecv;kE<_m_9eEhKvS-&UnFX&k-0X&o{R?A z2LBz*zC zV<7%t^J7+@pM$_~dMDh;TJYY?49)O@V>A_}4s(7j z=x;tYkG;!$Edtw(xtt#bUsilou(bjXre4h24pg)izsuHFkgfjb!pT!-kWll+HDiAe z6Us=ezRh23`7gp4JnVwyAY7Y|nJjrb6ZR7=&|#iXi|^&)3DQ^+K?b?VNLVi;1(DHs zOx=pBL_@U<;k9OF^(Fxn6i@2rCF^g|pR|1v+r(&}ybV0k+&=jvs%By8HO#^b@8)K! zriu)#H(|e=^U@iZyZ(wRnR)o?g)f*;F=Gq&?S2bKuJD+W0VWV7!#Wq`zk z(GMHFWG$}OW*p(Uj-fndPYy{xj12;rfV+7@HwdwH%D0P#a>-Az2`c1)$X=lS>XjH< zuSznbv3~A3&G3Ja@DuQ_oSumPt@yI>zX4^ckx=lCf&ZXZ@js_k{5x6rhjtzd{~xYs zfxpdP6lkT`>6PTVeFENM3rqW6Ye5l_>j5dRs71AQ!4EZ9c<(G|tXzYG2##i`^KNEc z@eT(rBgCaQaku=x+n^LhKH{}hs{M8d-uU!I6##2t%jiQbc}&Wm(7gP%Pon&>QvPA| z(S-6}9^Y#D=d=7wl#hK5AKybA8wNnaK82T1XbpZsRsPsX6|fPvnN-nX8TyfnW(fx^%EQl5&Fx=(Um1hQaQ?D>3O$6Q*+lBdTDiY=<>3HCR(0!sVU^V)v(UjUbe zs@k&&#bBB9%ZcnK8+aKqw&`An$+?f0A@9Hi6FA^Eva z+~A(`C?NBU-$w;3PElW&D>Ap7D@-5CEdfU_3x4b3B?mCXa1;p^?t&PB|D8)cc9YDW zXiuvnfDqPcoYhZt)Be9*r8LVDX12#Jnu!AYu`+pt#_%Bynw+$uXF)1bHORTKF;JYdJaLzTx4|S!?A9~rc^Nq%?CDiPB78%;aW9UPN?4xea zr1aSiHX`we94BRC;usQ;sR8*ypYxzzI5a>}CooK|$~>%cS{cPC&lp zsPzRoi{xWGb$Idg`OL1tefgBxQI(Zc37wlF6(=&s$t_Tz3gaYcfb!#Ny2XI&3;lz( zSF1Wh!o_zu28Tx1?Y$~gUe_2bTyZZd=B~aI3_aK!U8nq^FVx&ItQ>rCr??t;pBhLC z&n=J_2i^HYt9^K>T0I<|DF@&chBhsF0f>{heLNBmZi`M z->e8Tg@{ zj)(s^ry*#a^G5t)NXL-h{T96H@jkQ>#XEij%Q-eL=3joOi5@H!6LC&Al0eJohLeIq zS?5Ul?zwz~okRP>L3vUkb^$@U1Vx0(u$MoP2R7q|757x>w3o{wDz|Q7g!Z3{R*|I-b#^+f1 zkRNZKihdzeZEfG((ImsGU49(mz*Zo>)}o3n;h&ZafBLcD?=G||nt<`ofuEfWzw5E! z&;I%FZToR{L_Cmk+awWL<=c>=n_I7cynX(el9V-0&3_MQSzFE;NI!kAR!oNqHhRQ_ zW)1KjmH$`FTygt+J9{DQxxaBLi@7=M6FXK&82A%Kzj1{QF=jA2Q$04&VvidXNW1te_>JP%B7^$#J@6HYJ`y~9lDmdm>Y%y_ z7H|ftso{5GqtHXfY7}?PRw8SWZaLl&g@9!DO!w>=2&bM}40#6}+6L~q*-_D7b$DIK zTto{w$*k^S4?%CqR6i^OanF4dKZA6lYwxoue93pf_@mb(>)XAzm97AD{q-$-5s@>XMHoX(<>!UHW_1VzyTN&YEoJJKlr?1_Zm(txN zoN)>QT5=koYEBz^jm>G_{mbUGLWHT2m@u2*wH zZk=&(S6Nx|29NIC;E|0hd}qKN^+y>_)u->FK(T`0dRF7$S9f z))rSSo?3nl!1}dSzcIXgu-D=E{-ho5c`ig7=5KgxQBT~T+umQWdRCU@e+Xw}bPacS zB_^xUEMI6F+&{w3XKten<1;qro+e*vmYB(O^pzrm6!R$*S7Q3f1ipA_o|T59qfw&{o(FAp6Tnj(!Hef zDY*Bq*d07shu-`wLzi|Q&RckU9gg1Z5C35nnide+#b8sv0k}f~?tKU{fZOwe1 z4fRPK>23zKt1rB)=}c6qpmD0RB(y5p!KnJqfhOX`zpNhqQW#t0{zDzeQ4;#N;c*TI z!6uyV(GA2vRe3#dj3%!l2T5|8P5&5aO2VbCC@z#)1&oCvm*d_RP$Y`XM>Iu#z?|M6 zK5N6%QiX0krGCL9pbF1CL(CAN)zWUGOM0y;>9sZbyOQwZnkvzDfT9WUpicW0=JB9w zx1K(MaElJjNQMCarLHC62x(A)i)uiF)zJ>Vs@8r?1CMU~O1GcIO&l*t zxlEg4?MlKUT@jLOHR>iL8(I<`2a@ecjj=$)SM`%7-aTj+fB5`)Pf4|N&WpAGPoUor z9qAUzE**cfqomjBl3t%jZ!8Hvr3ttP1pG-8FiR(X@;M8VFGvvkrAFt!FYpsUfPRl^ z`fVfq){uT*Y5INcTPf5c4{eS5w(cnjedF8uwZGs?QVtG6amtm1b~kv1O0Ry(6{mc1 zp!?M$m|MbEm5!>iW6(X95J@JStrQ?|y;pE*TSM531BAt1CI05@)l+J4)@@J5*sB<< zFWhkiMT5V7kSOq%(QB2j7hITFa>IQn#@`B~y{R+ZE1fFFX!CXG)2)Gu_BAxKVI##< zxmX6;7R&HM+Lhv5SfQ9EsC$5U)T# z0)%7zui&tI?)M}V#_=*e)RDe^_$A>45uxRsw)c+A@GY7D)w__?P{i^v_Pgcs-$3C5 zkcy7-=>#>Bqz2Xi`Go;XLxe;!+xbEpN_y4%Q-@&wi2>$Ee`td`T`Ww@LU7Rmu{*MG z&)X)M5LB`(0Sbs-Rxj7+wbe-3Gy(p@*8_LK1H%GJ6*wqY4ZML7)~CTFG-K<9mn*)L zq3O)uVaR#>GhU6iZ8;j-p-P4WO?(KapNSwf$_kO_3#^YSrY(|>ojPM@>w_89If*fc z;l1Gx?OZN-GAsauX6c_2txHt@vOc7+dh0_n{#`yc>B63~KBTY}i7{d8gLyRkg%VQl z56itjzWT;CzLfPC;3~hD_!8{TeX#!_iu7#_7vqV+E%#fYPRflvVY8XOjmizkiWakH zyRxT>#x|_4F1%2aIblSm;mJc&8qRNPn2wdL7Nc@JK#$MkQ)1(@CqDdB{-Gzh=jI`r zDCAlDg73o-4e>8X4y5X z*gbfiM$MKPzotTkyIKqOS9aBmSg^TLpQOj5&0y0|BZdNTdN8WnW~>TNOOB#Mp?^2feYTY=Z5tre8;7dC&&b@Lc|2L6ymn))R9Y1$rlsrAmfC?QBW6 zTIy%oiS@T%2_=3r3Y2)^W1AAf(dx7FEOLlW*>G->I;rbNs#^5}3RoIbUr*Bezvw#C zL3XwU<>VgLKwB|Z)sX|Bv_e46D5N+%xE)sPO044%bJUXSBWmGDUAlyDS2-;~V1%}6 z*DT`j$%3t&-7q`} zfDn%Rqy6EhbH)IeUPAfC*5j-8aAyRjD&|EHL*0T$_ql7XfNC7LHx0gG1LVyK35bsi z<)baM^Rwiw9aPh`!~*(>Qa{o$ zG3;F3140Bt2JSb4*Rj2rqCS2e)A~*H`$R3)3p5nN{?VVw!p>W7!!(%mQRiCu7U2Wq z|3c<`#L6l4M$ek4(sZ`#X<)$G2+Ds!1J}4|FL1)&fpE#MUL%GOEn`SulB&-Zj9-0G zsHiwkLOtY|hYqF5V|HQwl~Z+tG@~tarvQotefPWPjFzl)mNMrv)G*%^0-K}vH_{$Z zNf_vVrFO|kw}|PeiNSS3)19k%7+JkW0j3PM0Y5!H?seDbQ@!Rl3fW)dR5N-em$Y0A z2(HSt%ag+eb=}~1G4l??#K`nk&L$M)&K&4+cdE|Wrr)#qu80D3H$KU0d-3!YOmkI0 zn&}E~QBMj%>`um-kjsbEmGzCbeS`WY9Urjqq-qWOEJTUTsAjDqf*_}El)zs3thRbZ zwID`*;tZU*h#bGk^y_q;MZf^+B@H%v7Sg9P{o{X!xa+G!x88|R$RLM$TA*+w=mKYIFleVqh=L5k`m7b@ zmGSEcoomC+%gYe$V)SiRG>%}y$gOth_-*L(I{Q^tJcd8UuSC2$un0e$G!Fei|q~_p_GR8w{)gdiAH^tE@b8bJ8Cr)>4q6`d0@A7R2$uNia+weByWm-o3BAWCST$=3n75W03-(We zq4(}GOUjrtK23xF*;FtRbDBdZnxjukV^^40-fDLmNjWvU7Z}N^>(f`VhUh)})MN6x ziLVdvHSE0RUDT-?%7uK`v4!gWdeWy%5(=qq)_D*=3U8Q8so@gRsIJBnN8te(z2=Q~ zXnFd!a=f?YJFA3uZ2y^;6TmwT;RN6Nai6a#e#U%9RcoJ5X79xb?5)0fLdbvK3ZU8r zFw`(m9Q5m^Hc*&_ox{jb?HH3!7C{p{%8%RWTn^iDEVhdk8)0mTj{V>ckV0wTu zZic*IXNYVXnZS8fivYD!;pKU}O#RZ{k#;VGECmTzv=j{!p}DiyCL?$>W#;LAv&uji z&Ua{7k0h3UhXo-Fvnl(H-j;O!1oMaVs&AXzfKvZ2T%XeUA(({P7^(BwR6HRa;`eCg zlqu$~-AhJXl$LTh+6HzD-6z8LrU-sVr(T8P0?1GjPH!wKNSXRMn0;#RBC~iC?D|8? z(2=HQvX5ZGs}){Znc8g8A3}mt>3wQG-=s&(#T)v`@=O3#kK>~xT$If_fT_OFTv`&U zFEL9qQNF+6)5#Z=nAs)Rhgs5V+mLWh8~7?SM<6csZ5&kB`L%q%o9%?E-CD_i4L>c*rnG_GdS|`8^GtLDklXpz9w_ zsDEHu@6<{j_mN|kb~8sr@{7=XsSne-RfK93;k?&D?j?1;ruF_FtFV7>OZh;d6!FO= zK6zR#2z}J&fcC6?^j^wL8bv^&JgUx`PGDAmmWp%X85nY#m-U@Ap;sTn!r81|4MnVy z=nDKmi7XF2*TmrPMm>4_{_1dw1}^&dQyToWDW^)LtyZ zM4GW}+*HGgKg&kGqALsY0EgF8?WLwk zcW}62C~5=wqNY~^>0r!TPTg)J5Pe$Ohx6B)E%^BYzaR$xLc%x5^WZkpB<#G~g_1B; z#QhOgNl=P~Tug*AaVpON+?S1QrIvm)N6M!e0Km`&wh>G1f`-tH6b(EdDv6aW%sg0Z ztQtsfy)ET90rR3J93riKQNV}*=>mG0>Q&g4PF zO03#55?otboih;+nsVNprH^N^&!2hvAGp;RNL?~okaAbI=R5`4RGG0(E6|`3O)zh1 z%`Kd<J1fVkWOVr*Z|u#Hmyhl zXv19$pT6~KC64(ff~n0AOa+3?wtBHtjs(Kc{*W^;svj`4N*RP=Jic&QiVr2cW0i2w zAI=(vRKB?vAwD_)eo;_?WM*7G1ZE{mD`xNXs!&H7cIJtm{J-vC zIM?36P~O?zLgZeuK$Ck*^wfm+4)OPv)rwKiUGowuXZF2$Fg89PO)1CWht&vxGse+2 z?wSYj5-4;?#oKb|#({`WrL*38>aIR<>nbfm!vD2Ot=_89yd7c)>+83R!`C!LibD@M zz{$ryJPy<^Pey2w4XJj5d8rBMM%+enQ6A2=`(O5CZFt3 z6ax3>vZv_VaA5yIhsF_8_cJzF_`y(0?;VEuI1`EfxezPP;;}Z$6~zQ6qw84Q4|*yt zybv(xH!P739+uL1Hd{&RQ#ebY{oODhV_Jnfg*g)7AW&EI9r5pL`W>9x9{&mzz&*i> zboX=-9J-}|1$eDDb3TC&PM{eni9+c)(BBtgDwrg5$ePR0j>Mx*p0WzFtd>kALZtZ1jy-~GT(Nai=&`%%Isyt*@s5^MoQFJZy*y_m zdf8qUzvPLWfAcBx-~Ro{ns3V7pGJtChyfQZ$oUUm{N@vumBO+a%dlCB-p(%Dh!kq! zrI`Pr-(naYPa=NkgN}@fXgt<6{0pOX3D3DZL%jI;fj- zSt}h_FkA;pUUkwS9W%xVr~8chU0Auy`oqw~6fgV+DZ&}Q`lDu;2;l>iFvz3)0E0*% z7zFD#otyDT!nRPbbMa;DHycqB)UnbG4jBQ@hR1pCYzp<1Gz zxZUe6znQkLs2Z!D7!Yu|7u8l76iP5Cl!UK?3_sL__w6O2&x%0FtJhU;+lfso{Npq$ znR9l5bNu0)VI{qG4GE{!mV^VFkQNHhpt%^X8~s2Aw};I$A7+;*4iBWn2=bl%lbcTe zCt+G%Od&CLTJo@3^2vXj)Wm&9abeMx5f~>T?&?1Q>9x)^{BkeJ+Jk3p)-YU(-Y^Fd zgwehkjP`&L;VA3{j{I9&on!D7E&0!dY_tUuWd-LT_=3wlAk2asPDG8cjy6J_*}qqw z+^qdrkpq!wPgIctdK3P{bu@Fh?@yT>#7=sfd;udEq4Gp+@me> z!6;~)vAxJ#Ok{AmR-_2mT;Vn50D)1(T{8&^mObFQt8c`YJ?KUnO7R6fM$e?~?29I? zg_@|=pbYmCyfs{ZpqWaTpuO4ihee>Jr72?8KoI~+PNc)43o%r~X5{cJ=NUQK@{1b~ z@SZQfaANFx%@(#!c@Fe{nC1DF&BpThL;Ly6B{=j2?xcmZ%%?bk{G36#NzEk;=Q`1e z9>{FQEbOuHP13jK@D=Hil&ez6?g9Vo09kb^h%S`RD6Zc&{0f9=wtnMM|D<#Za#AMR zH1aRB^B-^j|6k+uks5g6&^{JIh5hS(#8FYi0V=sP&{p_>8K}r=>v5tu$E(i^P#2VI z;h3xUcG7+VVLiYIRWU28;iWJ`O;`sE1`p}*zW@0R+}5#4;ZyYFnby%jxI27$7W%S zGbm==<=NIVSDxl5SJPLCMOa)1Qgy~eWCmN9Y{VA!hsFcjh445)Rk5m=m@W414`&p0 zgn=kD*y|7D*a*D9b>z-5CFbB#`q4Pm3M@Fbo|iy?{{RdBqphWyV7TvGJ;A-EKJ7<$ zSsnW2UF#>fe{k0Larl}$|MNPGs+p6|b63}}w!uRl_na#I=5^0`n{QQz0(iLR3`ehS z*lsCVLpal$@WNhq`T0M(?=topDcB6@jNH)^KzF3G1pLeYd_%&I;hwpEH4^(>J9X-t z?quqGNBa8cM}i7aoms~uuISrn-w`JNnm_;K z&jJ2mFZs_6`{7%__yPaEA%;5>FuZFQFhwbM?ZdxANRhGkDiYv_tVaFp?$DT@<)@#j7M)bpolf}gAhx?9}RvMt8@bX!c)&+g^=dDaa5Jil5$`_9wP!UgjDS#445 z3XsfxSA>rdu0?!|b}i=P|FuDQU3q;&+$A-F>i(h@LLYG8A6P{=g^YrhCJ6qL9oQ53 zy8|i4c=0o_6hCES@H4GUV#p=zF8n2*pu-qWN)=#-l~f4dUy9ZL59xma-^7G@D=*gg zfDMu3xixZ9&cqV)&b$)yFI?9sF`wZjXeBA1m-K&z*Qix?FA3?OUZ0nQzT%W=jNe2i zj38wk^9Nv%X{JU%P2re>5ol6Q9w&3~T)=tl^x`u(>w^m;hGI3m1oSqMUo?^gU4!}Q zD`ub^98SvoP(r+Z=&6SIJ^DG6H$d@7w#@0uj`y3F$oOMb)Kg+k@RZbiU2&>!-5ONU z@jjjyIvnq#3b4cZ!ziVs;JloQFMXk$oa5Xa);fIe@!-QCOZcV#3w&-AZlo1(>N&b9 zYXWvr-CI^=PXK0d50uO3+y3y>oCxKbA@*YyyhWhla*!prI6Tz7$clhpMt&3eGNR zMzE?ij7LFBvD_E^D+{7ELJHa<1!4TR=`ZjxmrjO{@%p&%5fAv+#^EyqTc>sSaM??S z4?E#;;UgaK4`N;3!k-zA4IheFGJH_@xbP7V_3?M;RBhjMt%A22m>G`dqE2CtOKEj_A_vD;VRHIAOe%hdxHFB=EiT#@9quQC zjgIp3s*YTF^PLqHr&S&P|JeKT_^67k?Q|9ho41k0AP60dnus_-K@)|c1Bu+0ZVkc+ z?r}r(bwNl2Y9x)FV0zkiGBeDo<1nM+GCGQ*gF#UeP&OA5a8zVQ5f^UTDiKB?LFw;# zPTkvmI}7^qz2EoO%a8QEx7Kq`ojP^u)Tyc)Z@u2**Os*1T6z7={+{cz9y}Xo#xzj) zYJU!8^)8|zJ!}4}*aL-08xA@ew`Lzo-msR1=^L8(h&RKs_4rw|C^+;ibwp1IYA(r% zjRr`^l)_*da;K$Tr*FsEb;L;$?s)hGtjlfIG;(}QVDg98ad zC57J_c^+6MfourtH+W(Q!?0$&rNd&l={)>o;thHJl6PWSxv>x*vy9sTpYaqr5ax`T zc@R`gFsvNcfXR@E$-Z+2lSEN8QxI|ETNr(fg_0?f^$ZWsgManNA!ky?6APuRD#ABIseP#kmKVJ9tp;19#~z@ zFr|JB;Lhvxuxc?qJgZPYcd}l2y&fI_C+f;8^mBt`DE}44tv~=xW}6XTQ^d1t!V}}~ zrWO#EEJ$k=S^<3KRN#=OA_9tM1)tPenEi_QZV>)wpk=)I%?ukI2_FgIjg0$x9IR&{ zyoS!S;eI8|C%D-w^e@@afb7N-Si#i#m}LMeHUHJaSHV8Y)xaqrvFJ!s0Q+qfdT3_3 z9zGKup8np(EoESbIkE&gUspkQGUz7~B)KL#O?%E{ud<{Cog@J{0`>%CyA_e!eOA`KI9Kn}VNj3VyyR`1#f?{D2UWx6Qe* z7x;4zL`Hlk%^>m_fQ*q(w|w@8NeG|HAR-}uv_hz-Nr(@lgruPpsDuo~xT!)AB_Yv7 zNVXaBLJunqR0~N{3ynsfWb@`UaCN?t#wzek=*CP3Mjub(CxnsA z%s$f{AL@<|^n&e1a}4>!6~p-S5L|MDoUFJ+mH4fw^Ie=T)ir$RUTT&l@VQa1o`7$b zF^4;A*z1z;%`$$88kr98c?qAJDGK$F4ZcDJp9|VfSpq&aS^ICo=T3pI0`<;Gz_-ZQ zh{9Pr4#(kWM*1x>_TgwirUQI86TS+jC{KZ}9!E8Rer~|`7ak-i^iz|)?}sljztfi9 z13{-6`qh91=v`dnT#g7VO+Jo?3GO4ZlxqwYh?TIhfHtFWJ#5^}gT>INm=!MDEQt%i z^-`3L#&1N4gG?Vk!fr3w9&evPYPIt*R*)OiMSF?%m-(GJf7F)NpBbq=|hShygJ z08u_32`sqUYT%|u(0!S#VkfbXC_i8^^8ky}m=##CBxaB`a66~;AQp+~X$}#Y4%qB7 zRIPTdg^2CCQd`ecuc`Q%^Vd}TAW5xOQurZ&u;P)#4 zEAf*j@Z-~t-^n;{g7_gE%vOZVN&FDTE_+n?ne*pV{4g%0;)ejjiboPZd>HkBL-50g z4L?Tx1HQRt9^%KW#7~~Uk54;(=i#&m;)ihHHw&4Q_#y15@iXV|srX^wO2rQWgcXk@ ze)up}01m+qA2$3L^-nAUnt6yHvl2gf0zW?O_|4`~4ZsiKz;6*UC-Fnr(cqV~A87ad z0=j$8E)a1PW%dyImw>{=ljROj`Ag* z(LH{d9r4Rl_+{Gh%S5D5Mt4C%VegNkv@WYnnZpMc+S4aF@3O|<}KNrS7z@hMSrQnCCeinYnO8k&j z@Z*#Cu_zmU5B=N3&qe%Je3^nDz&Q&1CU%dXyCZ&Xg`eAwpBv*}0zY>Oeux?k5JkQq zEAc~C!H-Yk$D(Zbz49*;KR5Af{vriGfO8c1Rd6-?;>V(F_7N*u1lBb8 z!iw?Ykvte@9fl4h6n<$A`}l{bTL7Y&NAN>d!H-Yk$D(Zb9e&@$FUN$oTI_d z(QW@rOYewZx`H*`j$gVl2XL79rKjMRZbV>0F!Lz<(oOvE6#P(>4Zq+{QK+neF&x9~FLD_xL5uhF1S`Dp;|Amc-9#Y@~HT;pa@j&uM&# ziMg3a;fHl4!4FTt4@KGVTl}ttAGV|#^~h|;&v{h%jp!afSI72qDOg>0{9J}X>w?11 zm4ctk=$F9HrSNl^_~9w|p(q=E54~gI=K_8!FsrxY=Q=9@;Ma`Vyd6LH55N!0EZO_&gNDQ3*2U_~ z_xr!H8XUVwAt#^)JTFjvsri@=51`lzva$Yw6+h5myzFtmFjujS6I zhu|SUSu&2z)2(EkOp8hQgI{17kGprVVD86Z+}NdyYSfxuv@eXDK+0U<3m!`22E)r> z8OJhhY&5s__{QwV;?UM-V7+UmPdSD`dln|f`eF!J;t@U%O9fnpPH zE5MPBlEO7joH()~S;z#)L11h}@W2)8bvx()eK zUGNC^s#w%!S=p#Xk*_lgzL^m_Y^Ck$34qNN6#g;~ZMY}RvKcw39Nb#DYF)QyA} zgWst++OW6ZC42C}^Xs&yTeYVRZA>iMRk4Y%z=YsnC_R-~(Y;&IyS@yyrFyXiCR{7= zxNbuS52i(5XR@Wktz>}-lO_JN*~*dnoRMki^!Ck~JVJRVXPs}oOyi6AFh|b|C-Y}W z{?RJGuAu;j6p(J^>t($-lLeGn1)w#G-EeV;oNz`79=+bvpTII(nzoEI0G3Jmg?a5} zfDEVOECH(}>W$-1ft!DV9vxp2^K&wK^!~qebYLivV=SWMFwk_&D&Hk?9&&V0_wmqD z(xTr$kav^c#rS`A9}iwki~ghg_(I12s{44fep=MueY~6TKj|*sTx9tz648&+#nZQO zE+U*5>Cp*SORQ^~u9jHSru*eAZUd;GOD5L5u$E0hvdG%-!%?6fWpO87ojhyIZyr?_ zHcxVb{4hQq$%dpy0-SZQ(HmVCUl{%o1W&Cy}sVsmQabX0Xuv8QD&_C&2upBJZ>! zZ)fDcRb-|a`LY!`gOQCY60l31Y1GbG?AeTbSVcm(O5|iK@_0rrRgo@49t$iVwIaXE zg;&_kfW~dc^rc2C_%r4r#01Qkc~;CO#uOn2_(^H+SuxKrW;n{fxIev$KynT_SZYqQ zC?4Y*<^LOOENMv$_tKJRSyYAQU~|Klb}pBW=g3kfy=t-8Nd|$i7q40<4rCwYb4!-O z80dm2k&I?{UGiou4) zf2%iaXxz!SC5JdnYfHaWA5?O*r2{dN1|}Q_Ro&t5ha^}?!4&`pkT5Xe&>)0rHNU|J zwq#XLmOfvq3$C0`uQN zTw;PRE&H!3{1w zxEmAL!@6VNYv1kei9f)AA2)xxgF$=xpj6ro7na2<&%tx`3jHTj{MsA|McMt2cY?P5f=G+xz+MwO~rJ$^`@YPaO?)ZkSk z0;-UD^;oVRE7YS=Jv!FYk?j-TKh%QH@|E8 zt8a9KW7Hcu!XWjAj^N^()e(NIK7^;1*5Tu)Su=YUrHu#A>u_-8IgvjxyF^t#{lEs! zKmD1Hr~6NSoQL`{iP>S69)oTaYVCFK3AnG)pb*-=?-86gS~~oo9+@!$KT~n!cQj+4 z{ue!zjt2Z%cWlQAz6+MKq#ektoF%`r@tGdn0}t@8vXSRoFd5$0!+7+eUhsh&l=agd zKlKiegH60-lW-64#q4m8pI(p-j;Xsa9U)=w@NdC2UUE$sAc1l4Kq!nRU?49UNV}~E z{=CCm_i5EV@#iHYslW@k^Kr&-ZU(+Q5q}{9t7m|Wuj$Ai%00r25Az6VDhD$xZ%Nns)8_n@+rG74qfcE2ewZ~OIfGvpytVBYp>Z*UU+zk1nSzYyGjb_L*W_8ss>@-8x zwBm*Q&rTFssUB;jFGa9#hdW#M#G?~oI^-pd1z+Rh9_^l|%pQm3Y%REs1w{G|$Bi1G z(2W87+>YZ*8UqZcM1^EU*d3(#Z6zx_p+mS@h3}q5{!VN57VO~5B_#Z9SGT@)__mY1 zbU0pzw;uSrz=fZS-T1k(LU*ix?K_MQ-&J1-*<3vnvbp*ygyQJUbqlxXj&-`@(5p?0 zt4CrC00I9C&{WT_$Io4?zIw8>_*7P0Jzd)SGS*ssZ7WW~>pL7^-V8=00yc;VmIW){ z?SS$yAQMO6?<-jA#kC%|B{kA_ggIzwIZGQsE<6H|4_%?OWIah`4mm_?H__S+w3ciT zBC64E;Xg3e5I2{?jg+n?pw&X!>Jq_C0Ii-TxCx-uR|B`uLEv*b{%{be<3l_byNJno z*tRlrCt8Fb7r6O*ak(e>@d&8e{|&%r@AMXYfW{)Xpye0dWnze^^Dz9~ zc0nV4E?$nGD+BtHuM|?%Q+Bek8rfLO*;t6$W5=q=)?E2OX08)IiwIt|yO6&+;i@h# z=kF}SR9!Kb-I9fXs&0(oBrbf~j|j+a0?R<)I|1^XNnVq6emE?Nv97BZ+CLuD zmwYjoU4|B!q*)wxwH%t+U>2#$gG~-+CvxXAY;rSblfxM#G||B(cQcGHNLN7v-W;tz z&QQ|&-^Bq@j>Td78+eh~@HaB8vh7@(oJR?li{>OH~DJQ7}@GVlZLBNJT2b zW(6Y^C`&sQ)+$H)UQin&A^GJFgaYIh8<) z?1tUMHml2c+SRf*ARea`@~2@uezdH_vc;MQxgdecvWamieg-x;fUB0JPjJ9bYe7~6 z67ZnhoG#0k`ZJ`=jv1WHV6J^t<~dPxj@qo5h0g?9sCSj|*h7&kVS@ zR=Fo>X$QV$UuiH~z1AK(~LSXUes0jB0 zh0h01tN4(_d(V{xLO%}8#;PQ?TAHh*=Izp0+ze-(nN|cf0LyddU;&VQjkNcMK2e=7 z6qb6ztVfl6W22n=>u4rPU8EXHtkden5pM}d!=kR5;HyqFrk4vK}bHjC|lGJ}3juAWob>Jwe zV?gz zS_s{W>lp|uWLPH->&!o79~3^8)fBNBY`4q$cWr{1IL5H6pM_Hh>hKU}LtvWD6Xu(i)2J z4Y@#J#4(6%_aDh}vSe|YBZMbZ=JthdEW{>mwfEl_ddnCHPiyS;TXP%AFvr-~Uci^c zAGilq1!`dZZ_yuu4yFN^p*CzthiZkg9_p?vFa(@R%;tNeAxF|BzO8WUX@idp-tdMb z2lnOwW3|60)QW@ec*GryH5)J*fDOtIo-N0Adcz``K@KP|BCx5aX7ju^tS3u=FYGyp zR~b7*AVR{kT_EXI21xisyj?~n>;In_e?Z7jT16AmBj7q<@%Of~)1=L3#GCB{)9(?^ zeg@f0B0)G~5V~=bj6NWh8ly1i>!Ih=7)4*5=LADstQU3Z}K0riZ&)3VsTqf+}5OHTQ;>FzqTq<1wWRKU|jQzYqomn#r;-? z$EH;uvkGQi=6SgnA_wBw;y)l5XRl_$qXq}wdwT=gRv6phjCE~A8*T@M(kfnb{uxJ_bps`^QSCjK|ho+YEFWKn(PNEQd{t3)~hPE<0(DtKw$E?Dp zXTtjC83HSTj121ccfi{T))%fyfwe*E_`B30=f}HEF2RO;n_6YO!-0iz{_ti09KU&%c^T*T?>0L$-@o!C#Jhvg-aZ9YWAsF3QFslNiC#p6TpIawcer zb+V_ppYeR-p)Z?AbKd2QJ(Fa~7li81c2TJgKFem~Q!pl!?w^7LgJi zed~=w9ppo5{8zg>#n|A$h`Z~d0nErr| zQwTB}=SyE8;;uUno|NR#W2S$1MEaio=8@x{4tE^CQp-QRy<>h8f1Ki?BxjKxq7e>G zpR~j|VNuJ06=zr}`zf`WeB-Y#c3@`kV4*sgPaK;4FN-XBLGg)MKI}bavBpogb;u9W z!CSQ(U(`f?q(Uc#{6Y6EO2Nu#ct8v^oC@S5dzPx7@=;q_4>6o9$*C6)@GsKC<=MQS za(cG^W;loD=*3fW{MX>9r+mG*Jl{WyqA8!0D1^H(1`@Z^*fQ;4yr!{of;q*#6fMrV zYIqV}&d)bisOaI8HIQeG$jIEmb%m=qAu{R_kK3^t6`UfCS-#VF;RX8`5Y=s3h{*RF zld!{ywRmc_|3V&Q%<&np=J-p1iwl^z{Ab&t#$C7=UlKscwER+FqF~0$`8hb>yu2Hr zMy3Ka-v*Q-t^9_wi~IOteNk}XZl!f&8ZFt$1Oop_7W~@E@=-<8M^$Fx6!YGzP9;(9 zLj9cx^5{xCL1Hi3D(vto7Bzc?9pb4?0z$NjNx6Yk2a2XT{eAG#zi4Xz&M@1H=tzIz zooT{5qW=m1l-Q|07lfVagt7tqCi?%m2Zd)6OaaY6F-6WQui$@SH}wDWKkPJ!c0+%G zFUO+qs^_5{8~G@*6G^A16c^iIBH1DTa)M-B&_(_MUFSFH+bst`+b!xt65EMtdpGkB zO0*A~h3%u7rM|m-RuN|Y-e_L*i_UE+_?27qp+<CkibW{UmH0?d4}er;(r$eMs5Ay-!QCAIHF$q*_t zsh0qdX<#2R2%(vbPsk-eQ;av&!+)f$oR(iSJ>P#aUJB}qrWer5e;P9s`j3SrsR#n1 z2!s$0s7H6~#0q)}$k9u>?%4_fq2I;bz)t=3C9i-#stfS@0U8mj+Oj6z3J6zHk9 zBK0TxC;g6$x~__Q?%5Oyr1Z}V67Vbjg~2d|f1&Q1{5vdMo?~&Z3*75kwG&eiV=!v$ zYUH7OO0Bme|8|z2=&9%{5TNLDIT$lL_c=QOI^d7{AAtY)U6Av+72V@+qhA`&cjzkr z{I2uM_;e~{N@mg2On)w3vWli=`5}e%Y&CvjGzBJ3VAK^R0{=w``lt3?;eU_t|4HA+ z|2@WRviAYo=)dZj6wD)b@~QE2T%vw!6vNQY>m@ns z(5{e^Q(b-y8XH>qvK(VbH&844&AF-dcI5xPnll4`7%fh3^3T8XcD%c@@iUbn8)w)1 zue$RJhB+DLWSHM~=TwH|FeFFvoqH#4sdlCjWwc_>#I)OuQBYPoIfHq1T*N&90>G{-u%k#C` zW97Si7ShhrYQ^^~TwY=FSA|x)7tIEZb1qWP)oN+b)5G-vJdppFd}_5YA&bR7Rb|Hg zCFdpN>qJZSbaCcgh^=yXf!@3*nWQTbEV}ayNmB_;U1_g#tRnDo{#;{RvWTfxl0{Y$ zy!@0v8d@?H`YUC9Rvp2X0e8tdzAH`rv$Ad&z28%IMo0gT-Ua`PWOwTHCjF}-(Ke7D z&hV^!i)M8 z+6(h~%&y(H*zE^e-y@h($0=mJxaF$&s@9(qrGiIg>F{nesNXJeY`KVh`ISqIudM>}Lz9&5@6 zv@iV{0eHXUt-QQ<0hZ^Jw3TDC-GRfW`?Gk_-C(?4hS&J!*avvM!v7vF?T&5JBhwsu z@wR!mxApauX4P{ybHAf9l#?9WjW4i4(lp2Z=?N3;=*;dlGzI_9lkn#!XmsqtoZ0n( zw*LMe==g=P9|hWu^+UnLYhIvjkROZEdQp8WC(t(7OwljUcAWVNZHqUT$NY z2?wH8!`WNJV^xgGJElQ_I{tlJ>Gh9uNOfM98rv{5&3JTL0*f7wTUa2hb5D`>JDY2wp(yezk;@rY4zZuO{hyunf5lVv5M`y_Zc2B7;!M=}M52!F${*5g`J2~E`DdEt-<2$X#bYL^V&7l> z0DJk`3s_#Z;J-@>nqS@vT=#8WV&J<`6>epT< zNpgFYs{fm}QGX%p50|FW_p%>Q|B>i>7i{+?eG3ys8(E1`e+Yf8`E!DQE++q+lfpj< z{G7l~^|ty%cl-5Pq4Ee~dA=7|{$;X-rE%xO7J+}6WS~C^1O4ueH>@6!Rgc~v3qEox ziXSJ?<93$M6Y&@gvT-MXEyY(%Q6Jl#(j7W|d~g3dv_C<=)=3GVU;DEK^!L!uE+3qv zS{CrYaP$bvO0JcCD(HOJ2|U$*r(5y?qsq3uBhzYd+EKr~c!9XT?8>2O@fJOlbmBL|@woUCu1BEB4e3B(c75!j&UM;DgsfOF4sGmG zy%G4drS|cg0t!}mu2jL^uG9IooQPk-0eOZQ%P0 z9=^Z@9SgWYy>(N?)MeERx7I`46dBiWESIreFK!ZxETC*NrhX!mGYt76DaAm|s$ju~ zhnLa!PiDihRG6w5fweSO^vteCcO^fyrCwN3%r*c*vWNciyb5<6&VXmJb6LTh7z8#R z+De9^OoU!eN*e&3$yYcP~tuw}5hIPe`*u5{X$9j9hr7bvG ze@06Vp{bx<9)QGKWd2nP06u{Z8gq-vj~3IfSZ8|`V;X{RNw7C}tIivO!`HQ-lfPQ| z7;YhU@UEthqqn1Vtdwx}aQHVSYKiqH#i0K*nwCdQJZg6=K8MsVB=x~Nh#?O*3kuRU zLUGzZh5|O2FJI~cBwuKoFL$%2X;6W7fqcam<-p zN`po(MFkgzOVgcbE^nwYdOj6$fCYHSfeF?mH{}~QKh!mU65jmitxyK+z0(}uCz!m+ zqgeiH4fNNgKWmEzCyaQPvH+f&{Z7AbY?|>k7S27P3{Pk(s?HjUASIuTgMUEttV}J} z`U*^V;NL8zm$ovCZ#2);Wkp-gPE+zAQ8O@d$sRCrrnVBGj9Wfn9NxxqR?(^j3lJVU z5d5sCyKzsZTU&|KxU;V8F)qy)>AT1i8NUeI$}!8>r`^{Ic1_&R%E_d*bO`d6Xe)c+ zVrRFbq-f*3e%eY+#%Fvia5j7wPhQ$dy@j`$-%qy3WFkFsN5CD3Ph5CAf-@HDC?X>= z7eR+7cFq~x)w5~Wu_eKs6HA(Q_ATkv9QYpI0*fw|%6sJGSIewU6`V&h10}LtFYG zTF`7Mh)&3V^rXts+R7Oj@nC!PV%R38f2&94AI2!T21(O&&HHZb1aOcvy(~&3SpsXw zdi*Wki9MM1v3&~`q1$8@g6$eh0tW+?yY$-qDBytfAH>h|nWB>ZbTHXq6Bx!2Ww_CE zu?2FYv67Pzh=1%Z+D;)?s26XpOzn28RR9qWwe7~obkm`;+IAxcuk}fhXVm@9F5{wY z5Qvtz>GVwD-zD)loaz>iQbM5*1xi~}yhm_Lqr0vM-7mN)P^UW@lHF={{gQavd$>|7 zC-R##S3JI?Jw5^jlqAFpR8(%*ehxHcQGJ73cA}`z=BBnDiSmNGCI&YL>dMm_l06&6 z!Fw6w2TF`$by0E)Ar2X;C8He z*;bdr2Xt(P=Yk5y$2xuprubON41 zI`;m}&sig7M#f$H!cb*DsKAMFNF8doC|#9t*u(_vi8gm%vCgFOF)37@iZU};=Abn~ zxX3sSWg0)V6{zT4mGNEZog{r`p#0A!2Hy%`M6@bU^frloDGJV11q=Nm<5sRj!DDO% zt465G_?89tO@RAdXm8Wu9?8->A!32t-vaq^mi+Ej@%Z}EjPKAkr5T6UysVH;asiK7;EH>bTJU!25br`^4Zb7#f?w8QE3+!p=VBnFrPe z@UL<^Y==F(p(fgYuwOIM3(czqf5hLF108|(!2ILHW)~TELSMSi588itEUvCRIRww2i9lE%*i6M*ByLQ8d|T zuyr>hTsAb|`Z~ZK*R|5kFQR?YV!44fkAJGf(Y_q(A85Ova%7#UUW z`^M~uRR!8^^$($dStb2Q^S%ya?f`9OBkj5CtS3yhkji(DgvON~S-b`+&ya-~!Sya& zi+A-uhXeHS$GM9RRK7>6^JWs<|C%l}rllRM=IL)u^&(tkOu-1E{DUz*+?|KK8Ksda zYcPDU%ndH6Zd?C7oNb<&Q&M!WvW122!w7{f@P{*BQD9E`fcy!tVGRXJTJ1&BzL^6! z4Os>J@UJzl%g!*oRqL8>v%sMsQ0?!CDcd z-OmHaw59v_yK?M+;9D-}x7YjU>ydd-s=r=*Df-*-4)DY%EVf4Gr7Q9rKf4}5qg9Z} zsj)1HW2O_(e%exACISXH6DbSl^~P`U!c36#OpBx)p8%&a+X}RI#`t;`dKSrkrVw)! z$`^VL)0f1Zr+`X3ypg^WFO2jJO^uAlrnKtj`q)OKxT~VTfA*?1#%6`E(she^#2&ImuEXlg0H*qy~uyuD(v$}dxbx1 z=HjPBND-Ut32he7`B!=~=6d{;!FA)bu7d}48C+Udns;2?jJ&~RV>XqI*-^i zmW_$ylP-=qc$U_A^9GvFL3qYaq^y7o%a+hvp3r+Gp-mXWiZJVj(7*=397x-|!N5qn ze=68>62=E-p#3U8>_~_d#8DqMB;YIddZ7Ju|4`GuP*$@;tNoVvNw4*WcEz47jZA9R zM${k>!GVLlw0qg90_}zVF`Uhx<_&F?okE`YW)Kayln8x&p=J+aLTgoE6vKJE-c!8g z?i{c7%vYHHHG3TY^u#wH9l;$GI~GN1zgmlL`$RURN7q>2)_qZ~va zo}B)f!OgBf`_=O<1pfuvXD^&0m3W#y%?z%6LR-02RU<{#o81BB+CgQ}QfPhjMU3o1 zy%;?6Ktz=+!Cz%Ho3xsfK~rz2&C|3y9U^lFf$(UhTYR-UxRp7_r=^WK4HVtetzenQrPW8zV&7T%CC zW=E(6rGu=Y^}f(f@Rj1C?xX5C7k9=o`CHkOMvQ^6vpOYj?!KgCl&9czU+tGAtAT48 zDMp*xE%hYJJ@=44U}NmBzb-GId$(QQ&^A*(VEG;Ponf}dA@dc=hBEFibHz@f0m(&U z78W19d4mN-!g`!+Ew=;b4Sj4UL9^mCiwZEqzHi(FUlp(m=~@hmjt4~{I8VoK@j{FO zO3;0vJD>}VUjt=oBIR7{O~ha2&n{6yW(~yMVUOcbY3LnaXjjyM=JJMiQfqkw?jByX z)Y^ns`?PAzec*3k0y{ViOVM;JtXTHT-QXKj{$c4sjarpOdbnQX>5}%d(7xKw{tPne zOWIe0qpPsnq?8t1?6e=VDT*mn8ZVKB?Asqh`RYv%pX;G6)uyQ6+4hk>YC0^4)3LXz zMacutwvWL?%QA-wWUDXtJx_e2Hy7flP2aXl z&u#YhGH8A4wH7kNqm`|Nej$$9@J`KELllxBzdj_c=eFw^xZ*axdCVp?fL_hMPQeEI zoPJ=3F=#Xq5MwWQI%9X2*bG4^-J(M6*2U*hk%#-up!;WHH&)LVxtTiFpohmTz_%VA z_)hFe7V4zYZ{2CCMDPtm3Objl#{b%_RXzPhfueEqaRf6E8#ax{#&`c8ITy74RRaPtM9z z{~sDcJd%TJ*(<*IHr3dW&@aP-o^2hQ7J3Uc(?ejJp?GVnUfZnIp2~KqjaT*7W^UT6 zYo~6Bfw9_yyB&JV=X$SpGj#J_ZPq4=rM_^B8npF^kuYQK*(^rU9VA&~I>w*&Jnde( zYd|F)ym&Nhvy*-T-il2A9LodR(tj}~Jm_SEp^RnkWAQt_SG#2MOSmhPA%n*Mm8G7( zdEqhqI!k@EEa;;-n=G9RWqvhdEKR7TC=Bzn;9@DYUo%3HD|0(aY_e-+k?Dg0*x>mD z=Q$(-V_{yo0DHXqJ*e^wM4l@*qY_&-Ta_ImI5R{J63m=3k~ z7Glq4h9t2sRCxv>&(RY5Df)PT*pJ{z{ndB?FLr{bPH)ZiyEMpWvn9&efhypUjT@h_ zVK^zrec@}c{(Gv|@s-&#yt(gR5E(Yo7rE?ktS1!qiL^S_#<4*=;!F30;`%oDVNpKA z6{oH8gBVsGFm%N|!7UDGL7RNFn;_QXF&wk9MQ_Ng?|u!8$I-n3?eYf(Z2hxcJH|qPc(3R%}g$i zGdQt7tMRH6us;P?r{cErZ1ORdkE>t`&~eE7cE)9?K@DVC^1t+X$mdd`uUw0wBCxo$WE|e!AP2~z>0cgzq;Sl6a zfMowFS=9x$p76116jAdb&$gYuQRjoNF2z8xy<{~IN%L&`#I3E|&*tzA`H~dQ{nQt^ z9uJ%b-GW$?|2(S}k2rNuY940dCGnX$(;s_-tz6XVh%1)c5g>D|jEVES$H& zM3UUt0~-Kz_3;p~I6y=BC;#Zq(HLDUxY#=^*b=~|1bR&jVwj*QTvDQO#1&7!hrE~r zy}K3a!p(WDJo~BDxKwx~@)*_CVZ8d(OKQZ?y)l9=>=Nj!3wsd%$z;!4Q2X0U4-w(DV`ZrRue-By3{tZoQnPiROexHZP#p*NJ%jZp&UOt}> z>E$~c*vqqx-yylx!)G?awJ?7rJWtTCJMape4@siP3HolVHV5}%+yQ-HIh6zXL4w~3 z2^4X$l4a6KhxSHN8P5*ro>Im#@eS^ZOhTdcA_1%DZt;BHAG-k5whp|V7AbQuIt z2h~PCDSsbN$ltS)^0%2}f&4Y(sXDK5jFBpTrD4!%naFrHrsOZ#B31sHP;0qMrH zB7YmZmcLSFq~GLEl>EJm{$&Z-%d){51nvrm-ZdYJ=-pr!y%i9>XH)c^#qn2(-?Px! zD2YOL@q0EUYlZQmON8nT6u)Od{Cf6M{LZqA-wKM~vyFO{asuWE-n?0uWpIB;QvMP) zv%M623CebP*nzvqfm@iG;k=t_zDr9VaO^4IK7*IumT?@%63 zk<_n-y^-irZq=oJ_gq50Fe^HgF6-Z_hb24I-U-s7_VFPds)8BOp@txNN{4!UMWRDJ zPOL0`Q6!3-V0;AmoAFgA`MX?5pg6P(`8(#A?kQyq6o=!k$Rre6YnQ*~2vzbE%HKmb zrO@Zw%?bLL^7oFvC+NeBpilm9$p{_Cr?umSKI`}p`nZ`9^lAG|f)!lN&t`ScLZ`|iLTHsIi8jdYYN~-79PnuV+I89mp7(Rx zYM27}zn&#EaKo1p?v%enfS>i9WS4d43OQcoL&!0PIYExku>_sME_XcLHM^wrW#gBx zL+swqpAdf7!T$7nC3$~`r(N=HT1a>jlK1!BNM0q4)%wfBU=MSC2|OW{s7TI|`2&{? zIQOW~p=s4z#4q^1%*H}>)8DXvf*xVDK1ovo%UsqQ=ZsCO?5WmLd?LwQYPy3`^Y!p0 z`0KX`r`94d`fYUpEcXqZl-3^7#nYC zCdc(5E11(UNKP-rYKFKir%cCy0w!Y*NZYq^{LNveLbUx^7oqLHz9FUU_ijkEJ<@UT zz3mycJ!WFKbqzDI++UH-c=v?*AOU7#{oX2OqYv7`M@Yv^Y&^4|(Z5;7M(2brAM3$t zC(Dwj(C*@HX}X2VyYbgehk?v{(96U2-GUgvdIi^jBypyQKxTA9ovB#~k zoa6Ug7{S#1X{E(SOTNe^Pe88c2ye{If#>J~_>k&NpHK8e`VP=r+Vt=uC;WTbTnh)N zQAd8^XE+1Cy5opp1?P9O^w4T`Q&J@B)@4I6#2Gy&D9TrGUWfKJ$IBs22ws6yUg$E9Gc|HH;)x*(g%A4c^D1Y9 z8P$v@3&lZ;E)>dK8~KUOfs=?aJj%y|0zSXR@{b~05iUidIs@-iov@b~&zii0_=dqR z@}R({&OHllF`9TV<&sy~P;|vWqZ{|nH<>A#XR;7Bae*qc^1E{|SMp;%$}r^zn#)VC z>&xk1O_cz~A?!`Yiu6^~cIyN-NwGRFARh-spPt?mRU-r1LoUElXAGnLMC+J=a2n># zJnYA9%p5jL1lyOJa)$QzP^;JlsXy!}$EHgjC~DhRw&tzjX~x=z$p{G_pCEvi;8XqW$(>t#X>}cMo%R-F|b-Qhspzz58gV z_Iq{R5!){dGWEaFevkG@^gpm9hVI1tM^-l;qacV(!zC;2BXMJ$xENp#%<&^CYaO+l zwAzc2C{R@BpGTLVstd7O*CFfh*I=uAq&(dlnS5AQmSUGng3|--x7lJSvtpAZW?-Ow zkuAo_n0#c9bK&X0c285=L>iM}ZB=emu|DE!0k;Rv%ONiMtZ_5XF@%q+lG?qpLn3&% zxBplV$_Q=MU;O>=$glQYu~&SQS+^Oc*Z@c_Md#&tNaLoH?TOh?14A!|40}T1^4| z;Y&QK)_58-Sq$8dJt7*NEV5wh1foH6NukWGk0Xz<7J3=d-qj&(BBX?a+B) z_qS7)_r09Sad<4vc{TEu03u$l%`3!~c@i{)N_Z5G!Fw0xKXZ}6VX++T9gw=BLD6~Fv z-%y2du?(xc$Cg4K2EZi$Qq-?j8hX7B!c4`niZ;Sr@lrxdtDwXTPT2Gpc6l75iQ-@% z>1W&#W?xFNm=7)_{l*=~hbZUEmLs0DWZ<7_?6#74Uy1@S!9|HeC z6aF`mHVOY#f9lYW6bI#Z0sO$uzz4vJSndP;Zx;ENRem1e?~@Au37y~%J=_8Q;?D4Y zHd^4{&4<80gPFiT{ZionI9 z-=ag?5_1`A&S8Hl{nHIoUdsAtQhv}iI7ImYNk4}y4`Uj9=SIO}m+Q^Sq9nfDa0^~b zU%yl7Qiww*I>)Ltu^3J*z#+{{OYj$Q{pl3UJm6t#+`?HDYAPajI^gGIxdM9rvWGw> z_(Ih#CM@CGU8aAYUOX-|ic@Cg28P33;h|y9lNTWZs;rUoWMZnUqbLuHg6u3(J1z48 zPh`+o1diDcBd1n-nA{Gfa}m67UvZNuus(_dCG3tSre6rASB3PZI)!G+fp8Pif`^a+ zUs}z(c;WhGtG1Lo9oar}M1VhWNO7c_Kvb}%ImWMksrbijt$bSkg~FM&ru>@(&J52| zoJoZN1KZ?h6P$_Gq5ST(oSZ50+b!~YRjpZe(ztT*snY*u@}cD49~Ey#kk;Z&i2Oo= z6FK3yKM0Sqje=ZTq@Ho$eJo-gkgYalYt5d=s05m8+dHHA^e;M~sn&OwEBVq|0{otw znS$T7D>~v=Kv3=YZLjHs-+}_cZy_Io-+vxb`27uOQ}By#27YHh*a1H>+BYQdhLUU& zIym7uDFD-r{>F_`#sDzQ`ez6nW++zEzJ^ zqy}gw)11c13QU>Tgl>1DqmW-s;^TgJHwbkPcV$9EnT&9bz>?5#YVt{eLA88{hO_q% ziULmtNdd8>0P_hC2v2vLSF5uc&rzdarC zzd?LG@y=%7#SDy&Xp~G?-?-~KwoYf+6un3M_f#%)a+mBq7+sl#y$AjQDaWu_r|TR_ zuhOYuV{@@uBq%DXuFO17WoI@2Z!0ci2joHN+EvgV|j3q-}K6rc#jQ9 zz8;f&%@CjY_wT+0zKl+B0`Ea5@CAcwHdPKO2^|b>fvUo3kJA0uf#l~Jogy_fg z-uCwm9xn6`c;zZq@@(+%Rh7M8$>sZBa5xnHBSiaEH^)SoQWuNsShwXR#IUNtX9AaO z-&Kf3kiKyGYk~~ZVfm@uv0yZNUc;NF02kr=F)TtEaJ58^@oV&gLr}bP<~2pvp?-aX zc;Mp=l44pMTPjvo4s^Qf#^#v5`EV$NHL&Ug%xiMAV36s;zjaZ-E;+=xIQ$Av&?A?^6e4-%pNLx0<8aR}to$eBAFPdi07yQH<3I3lzNmrX z$PWJ40agdcDZlo&(Q|WaYzX&;n4YJ4WbD~`WI;1q zmwqE~e1j3|fWA%Kd*G$#scrS23;841Ej|v8p@Q=2Xf33XZT!QY3E7NpBc?L*h1Kqa zf_LDnV{TQjh6v?^2oqX;Y`8aaL*aRKdD%Y4)(ay8e*s4#h>mK)<%u^X>Ob48UklPj z4tKG^JqWHA!_vLE8$7vtJxkgIy1z$PkcbZ0*T(-s^yAw2f-~T&hvZ19CsN+6&A$tG zG89g#8=sAOVsBt#xL||12_yE3H&n;+>bq=CIPqKx=c)i|vN&NrPUf>(6;4o{+SHkB zQ==Co4E7*Ni(-8QE+y8N@fH0`Ld~kNKjMc2)5!5FrI8K;2T$$6${3m{`VdSkiIguO zWmk=leqgmfCUrxoY0(|<6B$m%UZ#g9e0Lhfpy28aXCA;U1w>oB_XQ>i&o}_HQRM+A zjBAhr8}#A>cMs9wkl!Da@7ohU1J5Zd+Fbd`f(-g|V!o|MZjYmP_Jt>y?6PWst3QUo zsyiS%FvHmZ2Y;MEuw92w6#byY!)J##_d~A(2e>ySdoB&R2X?dPdLwzqUKq)H#9Of2 zqd4&H{#uY*KiPVd>#F+1V?U?Y*?lGJm&gv97-oWS;RIK|C;HK*1=!!ZE?Krng^yCC zLgc)-UeKmbAnq*wAvSE}4hopz@z@IJIh9YY5317tZ1#7r12w3gui&a;H)aX^^E#wQ z|3BfMO#z%_CCvo+ZoGsqID{*fc^V%tGRpV_Z=eADck$8t#=wc8+ozHeWx|jo7 zG3M`yudPG(;#eo0HTL@Yv@s^Xp)aIiz~TrJdpW zTXlru&5I|4#@J^D8vh7A$N~ACO5aVSuh$U|HsNRmMc+*peVd?BK+ezzk~nOJmZRek z-WyAHS=Ci=Bh0`8mn_%;fnQ!uL9nF#1t>Jyy+7y2jXQ3-CE5eN+2ReoRkGwGrmx4qB>B*R z+T(sG0@&Av3xx;DuFZ8w2ua1gynJ#TZi-?*$Q^QS9X1R>vEg`(Wz2$gro~Xt#iU}Z zzrf^g&w)lMA6D14;O-2VGaY`XDjXr;-wZrJs5qG*^p>cKGTOI9IodaUbrxM^^(E`l z=&izo0j6xjA3P^H#JM@X9qtKDr-xZ))2^}lOQayTz3aK#^qx2Y~N*Fw(q5*j;4KA5rc{7IiB1WtBpMkR-mtV zqyHN0MFh_jZ(493ZnQyDV)Y+LW(7xvlydE2p=31CHlrTc6>L zWHNu#0xroy%}pj^DQI?Q#}JbNypfWVVJ^lRyaybS!T{9EP#qZH1aIvY{{W=Hxeghg zAdbX2Mpc8LSO$JzV5si0#fM0X2V;Q_&CR9;L2ONZ9GDo#<|W&BguRV_P!n_gwgSXa z>$erwI>M4KWZf2vhxzPe!GkXUAo_#N))ueDJ#RhMj7^JSi=mrQZmo78^3{W>B(fJG zxfm)-nplS9(XhVo)!Dvq!G)3W+)2s3cF-WUea>XfzzIIvo^3I2=%d7@5=3lN5mt}~ zD*_s55~D8I9#d}K%J``VKZM?(Z-v=wI;8TwSwxr5mt9# zL1de84%JLJZAlQaND>r5@?iOv?R3RDY*oZ=!rI-+h9B$U>GdYQxcM^U5>5)Q(Q0M_ zBfKrD7kl!Tgnq4#~E*L|TVRPfM&&^tyLbC*Q1feHU^5D&Ng5Kr#9)p@)< zP{%TEIiA>Ld6fk_VJ4?w0=Qb%pXH?$Aj*rZL}Ml9zH>1Ua2~4Fe1p``|L`$o;qmw_ ztK{z#9+tH~b`m)*HeSVF@9*c0%yuvc9WeGIB)b9jx!V2a27%CjFk0+3qrIWeV*Si_ z<*x2UGwlQ*)&jgY^iB2TA&FJKJ72VtlB~U@2tyF~dBGFD1 z=mon7^CR8k@~t3N_(Yo!l$hTE)?*c{-Vi+55k>!rqlWoS9KS+tm4brpIPd>|5`OKW zS7SZUhTIWd^GRhkl#}RBK!~ncQB(Z~9FyQjX(b$&11768QC-xrd0dPzn}_dc9#6rx zl(yN9T`0z`6J=BReZtcvfwn0N3-DW3$=@kF@_d=J7-V^@%Jvamf-;fhdOuFZe_r`m za9_=SIVS-}LSR#0A}7Z8Sx7tEUyw*U>iN8Ewtd$bVyyiJ?(0sJVdab+V-Lg#Wj0L; zOO=MUSlm;hJ-CiikF4tr<>hJCb^o1<0WQgi|YpjyVI4SQfNBr4;4Ei$0z#1@qBau`z_; zG~!%GkR3SmhE;C`irrLwB+MhGv?F2I?U&=p88+V^x8Bj40t|yBSL9lz>c)2i!lNg$ zM+)>H2RlR(Uc5FbV<(D?EDWo^0h=>#tS44^)Ry~7s+{wU|&r8n|^+$CcV~G+W zjfke@B1I~Q^<7R}G&R2_JX>s#n&07q9MMQNL>~)-tZp9%QRxQ5Bwd|*Rc=*E0D4d5cP!0a}?ksF`h~cEp zUDc&{^J*6&&vgX&W&(_rOHX7G)aUVeC6PN0Qvw4}=uf_o;iH1SmGv7tuuQGswP(ia zqObTp7U?T^57$YTtU<-7*}H*ATg9LZV<7?dW#netQ$n z@EU-9SkeI+5QxLP4xa?l$?;+!m7UP2x+_9kG&cSUml?A{@Kj-9HP%fGW#gxZV@x?) zW){xxK3}m?p<1E>*TB$%gk&WT$Cz?Jg_O~)FobnxAdW8vh9EV6S_CO!jxY6S3d(=3 zKa1f5Y_*(ik1=G0JXhy6@EM-z6!S4pDJX8?mUCs7AGN}To}u5k-wWpOhI@Jon)LtL zbREv(sSQp5<*4%i@#o=_O{_0mpGt{ zNZA;{odRF+UR((Pv$WW+u#&w1wl(Z)#?cVKi5`m)4*02FxaGGbFgZ(M0=H)4_D>m# z^I8%RjvB&sILLLE@%-lsay9{W^=^$FXJ1`PkdxaTpU(@B5U?i{9MHqh=7U6-^PTMt zhu9!KxKG{xH))b(c{&3k!_L9A81T1zX6oA>VFUhKs7Q7J5j^joyALfd| z)2a|mF8v>Ur)r>Q$w3ya1y4XCcuwK4_8ujxnZ_G_DsK^>@fI6*AEyl9TJTHM4yIh4 z$<{;4HB4Dn^l>F5xMBzMn3DX&xAx-4Y4ZmAA_LFyMJ~cQG|L3i5^dSqSVq~Htu5<;U152<%s1R{VPwckGpZ~kLV`xpYWnp!NDKqra7Upfrn>3h7UdTbJD0j`d5BLh9N0f828WqK8lu2G+?rfs)6J$jf(!j3@n1G3h^l9Ly&JvuV%$C^E@0sV>vuiMUb864o4hb-e>7U3o_Xz@)o`tP%Sg z4h>e;{pLA#NEEz!STewjwipKIazHA}bn}PvG%DtmSC&_@Q#=jnx+zNg%*BbvgKVAV~ zybxTJ$yACPR1Yv3>q9>Hz0iMc;&?jZd-p2VDTch|7pG ze*k&Vn%ez)RA$06#L6^|nN}c^m69NxPIYr5v%%8rE#BhME^MQLwptULlfWNcjxI^5 z)yPtd+qHXMV*s23;EFSF1dj{gv|R`lnTazFT6m6(IF&*prrrX#mTg|BPmyset_2XI z1PBCEH-WMNe@A-JK;YpAei(Ecnda2`>=d?6$tgJNY7TQ zvPr0HHrCg;Hwf@mP(eieda3cu!;zV&_)Mrjt;Q+44)^V z!10{=fjuS^V7<*{H*WepfG%l@_Vqb7@lZT(WFTN0_zREYU}?c-Z^64J|Bj`;f!0O+ zu$fIEjO^$j$U|3yAVUBlC-GARLaH1{yWZ1u5GPSL;$VZ)Gr#KuGZdV;SF9rw7jhvU zTeI#v$Td9GR=Y_M-C~AfR`PsrMF!pCr5Khou>N2?aGjjoj{Ri)@g`CvhYai@Bj!_Q zf(lhh#T#xxw7ia1?XM&k9!bA0DCWN6{W}LMtLgZGP}9JQ@jC!0^TzLL@JRGBJ(Ch0z|+lv*Sz8hV5zG zKdwUgg(#nG3}T2_=&tL-Hh{J99$B zcIT(bZ&1%m^QKtvFCYwGbBB-xDM&)a9BHC=Vfg~%A{Gga3$7-LZN_>$g_WITW$-gj zQ|Vx0Vhe$v(NDWLcYgD2AU)1`ePM(u`&4qt1azr|Jv^#=M^RfPHc}8P{z=(~l+8p#-v<8z~6D zD3}r(1p>4BQ&_#}51%q^CygOEFbSu)z>FQ6JB{KAin6xJIw=cT!E_*bAt_rFeHL0^ zrwNv#Zvj+blfH|npAa2ScmS@Fdlf^LM>Y)mLT}*2Ivhr49YI+7wwjS__2zDd+1Y`^ zC+RK*zX|QdUE}9}rN)n7T$_J6dqUGkIFYCYXWMyJbFmQrG@M(b2b)j@4z9tWLYuj5 z#n*M2ik{MhykkC&WZZ5w(M^}3i9XHb zn4$8qommd4SV8{8zNFXL#pf#S!N`^$fw&te&JG7cLu7Hf!Kn(6R4+0KLLCwX|dh~-t$<N9`8v_4iyg7bJ>htt!XEEd3-{0M4_4>0}LI)L=oziT`=DLcrp7 zcW=*u_g5+9Xq6~O(*H==(b94q3R`!HI-mXAuF6YH5bHhAd9+A1fueaN#mVZx=R9&1 zzUlO3qV7|GgKhgl#poOI72te6@C9iA_!QR3Uj%Mipi^Y&O)nv;~*AH z1-{1Ufusr*>?Z3`5}8Ikz7v&>Xk8>|DgFIhg$}qh6&-*N*n40MSzC5vqtfIIXmX7N z(vDFA*OnvV+6G*4+aeqriK{v#S#Nk~&tvPSo*gRjgx&_pN(_ zns#R57+)p-YUA4d?{M21Bn_MM^YOSi1=HaEgb`jZP*>`pn~Dl+>nopJO!kI-@G^iW z+N;&AO$`THtksP~7RByi?Pk>w6k1J1ceTDFm8n`2VsAbwG`_;lpOnf(TTZR#xBop; z@&jj)yq)LAM=&MNu`M~N@rlMAb9^d-{L=0_6#>@xg0WcJhQPoRnYUX%@PQoK`t`Pt&yVy?*CQTi^Rm;p3R3pQmJ*ns^(AX_K7)IE z6BcL-V3?=6&B^C=Rtl(77BzJpBd{geavfLJ)y>p%ilWdHnY7b2b+_{jdY{=HK+~%_4jq{H8 zyQm`#z`K7i-};x}80_FqN9;%DuA5VUPi&-F3byu_Y>TQQc9fwe95V=OR%2PHr3~Jn z>0{!-12|g(bmOWf7A-2V!Zeqoi_+gFxrk4p4`MV9&2f@THHw%rWnC*e914IZzA4no zUJ+`?X^4wI>M$$)KeW9Ie3aF-_n$x_;Swfb&>$c|v4(mJ3Yw^B0s&?q(I~d1LR-91 zthS}(0;h5bP6ABFv1x0sdj7}LT2HU1wzY_&H35YHR=HRNX%*4xGaYR~dk6$e-tTYi zXC{*b)c()=^7)YGnf>g`+H0@9_S$Q&y;i7wKl6o~vH9PuD&1bYLn3#Fp(ef`S%$;U zt7h5ZXTMuG{CxLMTuq2&pXZX^xcMwMfA+cLe3$$b$zB^t%|^wHTAqa00*!H@_xDSD zT1EauPEDSAn2*(7l9Nkt^f{%AKFiQ>U@;&~qv>DM$+8TEa^R_5z60uDpklZArw<>$ zY#By&i?*g{GngVyRJEwc1>S-#;#`|uo=%)4K5<@l65>2pLV7V)g+6%}1q558$kWm1 zXMFlBfj);ppQqKFX>ud`Poqzdj4Arm1ttx`xxMI9(iv8KMxYo8?F)_B%LoU@Y^*vF ziQ=nJ@}v1a-j2apibQ36=17zlPEMj#h)YJIRI#s$rhF2uitK=x(nz#AMWPG5Kd8%) zC`+6p(UNW?$^dnds9WDob9Bl^u8UBKcHCWm(t}c&vIl)qJvaVGN2=edHd0+W4+5P2 zvXN?oOZv2uCXm#8BF^gFIR3;8G`>>%BcCf`g?v1p*a}b`MpgZOh=o`*|6R@KGns%e zp>k}MDrBpOu52q@1b3Mgk(Z=D+NJnMo4ZzI3F+;2Yb2>}sl>b^d@Q@(cRTanHCfdA z6O2;*gn#E83S;5OcAcIzi@BH;D>V=ACUE)H0+6g!Y8Amf`Ckabts4P5-|^R{uae>@@T-?dKBwZ2t+!T;+oo`WugZgIN|th#^Vz{W zI&S5@iz^e$;z$Nn^Q1OWZ}=PtzA_rZUVj>4*oIwpJ%k<`c_Xe|GedGi{7-TL73$Iv z(*O&;LV3TeP7o<~T;;Kxyio;KmqI1+-|0)!PHy4Ipg#I(s-N^HLM&tS`YBFW&>n0I ztkSd#M!AV{HJdrC>yZNw(&Yh*C^ef>Us0)ttyKP}G(NA?hb;flHJD}VcFm^?G^9AF zC2BTogF>Y**Pp@7Ggj`rPTbem?yJmXX(|`fbr&zRD1B2VAL0Rry#KP-y(VAW&%3tv z-{SeWu;WGil$EKJ#k>LL2mir*Fj#zRuUL%?pj&60&gJyX($C02qO&IHD>RVwCfFax@eBY-eJ42v@1>N2_8t zbyg{qMeMWMeN{!+-g2DyX|Y3g!Oa>fv|!)ksVyUH_y$x6{3$c_T~Pva|!0Pk2I zo6Fg+aF|hx{vwuL@ol-cE8}2kbKOnc1*wd{G!A)x$YIaKj-1U5+VKhn%0y*n`Xcm4 z_H6>+F4DKMv~S<$n*@l+PFC6pk;9SA(#>3C8k!3e^STx&`u zPaqWaLHs{8?My^MVV@jk?{QIwjj%7i*(%QtQ)@<%LNL!3ur8Ju#l z92)ansPj1mWFPZ<)tI+}V=zMBA=u_sjX9u;;aG3(419MZuZe7PLQ#9B#)ni{gSkNt zMP4q4k(Gzv&EybKM+g4k$3E8yFW5=u%D~iDQ5;;&ohiDCu8+CX!@v6$=&`D_qh4r5s;R%z8NarSc`{fPgx_cCHnKnNst=%C5(4% zIb)p|)U(c_534i1!l!^5aOaLKqr$o~%#=RTN~`hLS@o#eU_F3-NOEI3sO$r^crmAS z0gmJ3W3{YH2O@2Wr;!eGL$(SZp3Rcmy7Od9?pxzdvg8g=;Xg|K*Ih?T&USs zEY0x_h?G6?_kR57rRASn7zwr?0Irdhx9`l@`U3(-Yzys3bbYlAtN$QqSjS{G{u7@DCa1=37@OI& zZ)#xb0c{m>nzp1)rdJ-#xa|+4I90Yek?6+2mMh+|{7jVC`WjThNGg#HMQ0)z@x}R!-(Tfow zi_wpwx+`|!vsl3>!v&<9g5j^`WYphDriQDE>#n!EzI^J0TJe*OD3ZAd)1Zrk(XZwO zJMowfdmuT&ul84it({jZE&&&L!jsOtNq3qbBCq$4X}Z=tA{42~NqmcSvCxkjil^Dq znaLBHFUwX18_Uo0tcnhw8v8OgGw&>*Al8@rr*cE`yoyLi`4hTe8w&gi1;<~{u855s zIz2Y>evacQb9>Izaj$YJzqln)8)AuO{ocO#W}*pKML*5jv@tktLnv}xPE~|o?fXKl z$F2^I**G(ne`3&9SgPo{p^Zy@$%AF7ZsPsmX6IVJyth#YUx|`IdT`&(wqPvZ|T0r zTcT|E;m)$aeVY;ym~0bkRX+0A@{3UdX0I5o0B475hw4Y&sd^n8*@mt)G0>5IAhM14 zP|rv9M&3*Gt%z(aJz9hQnU$kYXDf?VXdIV0wOU3Plg&PM5N(>5;UDq0QbDa_qt;I!ouN~jzExOa zgr%so7P1DYoa|ey2rBewFb7$s)ACl5cl9D<&gR6WT!xP>BslY-8m32axRootg9ZoD zn9JP*xAoG-0@49wZ_RWO%62DT-NlazEGz_=_a*y+u(HFu#a{jNPx7Nn=1Zpr$NwIn zaB3&Q<_q_g-_X@G}%p<|!hqXg% zeXGCOnReDe<}F6%eFz29dZ2%>)w?X%e>>D@j1A<$B{v>P;ssvE(l>On;bp}2EPb00 zTYK&{y+dd9VhHn_<2WNZA!2+4^%{Q`h9kGudjzwi`U>~l~u4&L@Kfvool&o~EnBbROpWcjn7^eQz zh$6m3ws}XTc2e|*WPl{1;oXK+j-&56yrp&38`!Ov*tef#;QxR3@78xdxPRDT4cj#3 zB>jWHbr{&yO@wUqao7p^xUzztd3Wh=m*T)XZ%q0qe#HI_Wv=@4J==B$n75;%|I^i|r9TyCmxa&~)YhcfY@98l zoiKAtK_FMV>s;b*3o0E7sXDhNq~!;ahrF#4S6sSO7p-3L6v~N^c6jIT znugUb9ibh*dYeY4Be_dcXh*K`pQKG0H$Mjd@9=Brj}04;_(1$BP$l^NLV0)mp6TOP z=yUi5hjy1v_+5Gx_-%jdU&3z=0+TkVz3|JdbbE8}HX{?mxx?*?`-L+< z2)DmT!>y*M^bZG}{^9DR{$b_YYt%eDcw@=2Pnu)K!0G{HFr!!Y&6vIts)WB~_7__R z-tA1ducS!%LLBf!In~5}Ac;5j$O^@jdpclmmKgg+iSz;TmCXIvXQ|AwmA7c;efLqAVazsdr|7cIEqHIQDrrSed)ojmZ9Gp-;BEu9S{->|Iq%SnitA`w+E_hdUw>s+iud3Aa5#HNZzj_|kxFY$r9I3WB2j0F zi9`hSvV(Ws6VZ-;n*HoG| zct_HhD_3KVsuta^GhvV{3f==B$FbTs4}LY29o|WHECHBz;a~>6zMDjvOh> zf0C&r^M@4r!!)Y#KlbWJY?s=pfqKVNuZT^mU~0uksdJ;l@aqA!cedKA?AhL_>g2uu zT4UW>NlXL!ipZKzpByXsAZezHZ&YA!aj_R0_7Rx}&66MbV&4bz4<}##h$-mH z?`0+oOV4vB-9tX#TQiZ_ut1P}Q5@_`$qBe}!U)AD`Lj$u$PLXepjG7(`}&e>(mI=0 zc4q9sCq_Z+yBUR@oj8FRotIHR0Q5<{hdzHxAfp7PPlP*HEYCu9H8OINqLyr z3&aRmZJFuw8ZoI+oM6AR!;)yc{1Q6*J4_0cmoq)PQ&;_&jq1;GDm;SsJCA2>56g?tsXlbTYW& zD(i7W7Bd<10qVXa5gG2pOh*?1!kztU>%*NnwO3jHmEQE2x)z(I?SIWkPJNS%@zwFP zcq1+P*Ekj!ud9v!yI4H=;a@$A{6a;}?OEjJ_!s;lJ@YSB{&t$ryzwmq!kxK+#?SKN!(SMW^V&j_6&Gos%XbW6s@DECdU*pi?}ANfIY$ZKBwH%$=$7!i{hGH z$^NC2&;!bUde8jx6Q4oitmDYNH_?4TCH}IfM+;v{oOhzklazT~&&>5f1aCJBA}=T2 zg%k8a-2C+WvXnwe$7ROP+Lcty{}3dO>>^HU0CerCJySQd29@GQs|Ld#TVE^3PEl=< zLrGL`y^toS(xgntDvTSF<7I7)v?8M|O596{MB_(o_NI^2>?}3={7bG`4Y2{%tJ(Mf z7@E81b>uE~4jTCU#VDIQN{4BVwCb z>}t*+&y7hDYCc!OnjRrJK7&7IHL}OsTx_qXv$=o7d-F$FSWZ=RFEEDHMAEp6*>-}3 z838 zSAt4GFcUrPvCQSU;xCgr@i|rZo5b0Zw4~Oaj}x9{1H(u9*ZxPM!1&LRd9{J?krj1c zPvo$(HT`bSr>RoiC!Jp1-W?;}aBjqP^*sJ@w{ZHq5VwBLV3G0rXZ`59VXKq>#(TvK z*XEV%sQXyM(R1ZW_beO)MJHap{Sr z@1Q6T1W@4Y((CBun|*ENgx3=WP8TmPepTn`c0%>$gtTB}P!FE@vHMf`8({ ziuTdZ6yb?Jm|K)?U(p{#AC6x^J?j7SuKzr`_y383u07qIY3P_w2ec3Xz#EqEB@%EQ zpaezzYUo%*Las~Lz=NvixvFpKRW;u#+_$N{zY)$u%A?fC5{P6_j)gcqjDFD3hbBys zCQP9>$8OClQZf^!!Y0fM=@aG#cGj6Y*3()1uXj}tow(r-*71!zx_4Z2;I<1oJ0qN8 zW8?6W6+<6ql-c@bRz?3;bhoRtb=iC_jOTMWcjI<;hy54#GZve;h=l(jA$##a-hS#5 z&*1gxRN@wwm_5FeSa}${)%^sNjCTNC+#8^A8!Kb8p!Z!|anOB((3lNXnQs50(H(@7 zu*ka%gj6QYE03GRJvjEAE{S__z_Qpxk8^m%e4e=BIoE$4-TU8qpl?P0okSKE|3DYh zXW4n`XHGfuraauyul^NEH@ebIy-EY=`(2P?4$}uvk^8~_iUB|Ym_L%HDmt;;RWZ3& z6`YL4RsKK)GZSyLI-m*l~EPSj_ z;GPH*5*}?CCP#o1CteE1EM!%>R^yH<0Edk~LPE24%?esvd4fmG`O6TPvdz z&LNh8trb{3Yzf@sJXC50kCmgP!Gy~e*>YT=oE2yk_v7u{K;uokr8ErkFElUEbQWpk zcEFi-_wP1^aYG;|OE(1Wo&#%XmQKey6d43iAZ$~`*t}ftu^;z@D$K!TXYC>YRRdA#^*`Vb?-v;fP>hD;$j8-STk3<4|xQV;qa~s zPDZ!=kC@hdmbc;Z0fEN(Dum*-=`*~fdYYt98~I^YFW2*hraXQi&`SKRKr^z>-~L09 z92LxBX3v%Hqg{*ejpzbLO7A$u;;6x~Di8q+S6ogzw~n1+#^%W z`I?HMorzCsA}thIE@2(=YxdUME);dIXPc`kS={PNoNfUAf^0cQEG$ znl56+P22!^{NWiRkLP)OAbCuUyvRWj9SlX@r3ZfyNP82Tcu&!sOfT9M>(SYbICt&0dBa?^rw7jfxq z4zzQ=K9S&ppwcLgDXdx2y(pdCztKAT8jla`EIiBm2WB0Jd*0hJ@8Cr64fiB|guS$S zyOe>^T7Uw6(fQ{4@2ePabzoV?JugJET}*iHEA(a;M*BOwp=Yb+R_|-7h?eeF#hu8Q zuT)}ijsbcg_B7}V$;R<@Uf9X!7qC8epe~X_eT>Y>^>QFAB)ek?)F6{}rF#mt(}gRF zB}ksfRI2-!k?@1$vzJFy09K=fCkpxFq|eFzDFUeD^Tgkr2?<}&M(pAq3oO(`J32Fn zY}LhZY$qjUfQxxkP2Iu`Jw*2R;ulID;amd~ zC>i50vyf+Vci|8J7mBaN%wa8HlkB9w)rV6yMaf;~Bng`nBC;gHK5mlVTpWJh-Gd$TQK-bZ+ z+0$8WaNHr&Ph^d+)a{Hj$uuoG=F%cSHz|!ehVAXGxmj6WQhD8_BsXiGPK}B;>h;F1*K2ttqf#p@^(gXD zZ}`AtU*SyI%Dh4c=oDfPB;9^Hb>jhNb3z zbv_8i%USL{NN_01m+^4qL7;-v=F&#@{2o}_SU>ed5MkB1S=y&px-iyyB8(X>t~oP> zfGND1vCv+x#9l4K1zoRab>%&s*Atsh`sWuCjZ%9c3_XLTGjrTa@q zk$46o(}-X+!^{45dnYFs%wjBnv5L;qOA!{=yv!)@-n`E~k4vT&O7T=2ES*+ZE4dUw z>P9kOQ#8NX8*$Z8n2z$eS_Vc(s8 z>QCwTF*G2Ql-T}O`l+At*`X*ZpU1VBOb?rW;bpdeEZtEXPZWFk@GG&QA~q(m+>i6o zyQz^A|HhWO3%%2mA1N2$Q{u5;DYsYa%7ft+<69-(qhZRsO{Z$<`f$HKz}grE(!G25 z>23a1DswFR2L)zi5FUq-!8JeRLo9o>OPZ&oD@cNZlbcsbTLs?yqpCE?G{uGs;_n_m z(EtQjvuW-M7tw0~%vNO2!C>Im1K3#f#x~`9C#KaB%_$vt!h(LD5BnZuL_Vm7|805G zA6)FuogCKZ@h#?D>|o&6L-4-WY#~d+&*Vs1(B@qzLh*lrUHG?mtldX-;?cBjr(PZX z-GM68Z=+0ORUK78DP(p<1~QI_Ihl?!&qQLzf&$`X%U_89_wa#i-p&tqWY%VDON7}| zo45IwYLiS%+Vdp?j?($&nUWccrPZfktA@XNezWA~rm=8S%w5aFZJFimt!$I{wRLKs zq76SGIZZpc*U_dMPIw7CkWrIW9^R5A^Y$RWU&~xHsRD4uLUmIfIx~Z4uAJGP`;hB% z^~r&tNCnUp;*I2=SSVLSwjZ1t_;n7~Ls}&Z=9WkEjDN>j-aECcm<)^vlXb(q+n;c~ zD`qO{8gaGRWzn_3w>RSNFH85mGQ7S-ij!b6iV+$lIErlzOq}M8OO+qj7MxTzIgk;0LF##KZ%l(!z~JGH5$c9h0p zE8b_gK-6-u+))P2X8#_TaSsFPy+<)DG;ByUD4?Txbi2pc#D~xb$6lk^BNe&zt9?^n z>Zt1wt^QA0v-3 z%P10cTjb@|V|_U%nb5vLI`q2pV~dW2pGU{l3RMMuJ)U{WXuKGVm1m9L=W3Xms=?J` z3=&xKyqW*-u_AF2`-m&(acZ{qe)&M=M)nW;Zv5r^B!7WX_h2x%+Jx)0c`xd8s*AID z554DunRu!);DhsB$qyZGgB3(#;<;Oa{Qw?Oq*dxgAe= zLz4wf5KnA!K)CTwbd7(IEyvQaB`5|1lC0>i%@W4xD_Od8pgCq7F3I#Nv%f8f`O0F3V=!grjVrJMqi-^7L4}k+^$JB_$QgQL&E!yC%<6)%@@!|XlZZ! zrN@Lxi!#kjFsxwza>ySjLreT^(496s&s9a|7vl4(4i+^z$28N3JC(6J$L6^CUsZbk z*t*w4k+EYFe@-u#e7EtvFgZTS+Rz0~&gnMT+1{e}lLPH-K6tz{@vK@YwE77jK>gd2 zb*4Yv_}$Yre&CIXX-kkVAJyJrzbxH*8|E7fmt+tEOgxv+(&0(%M74mwu$TD*M`l)-vH9)}{t_9L&d zu;-E8x2xHJH^}!TK4v-^zs0%CFWD0r_PhE}t3K?-2RGg423Qu?K289Ckq`em*9wN+ ztAhn;wZj;|o3sh6uUGsnowVZj^q9Xk|87jqKVhX*jHS@q$SIbF8O-8Ip>%r+4rWL7&-gi z`4xfPPmXOcl)9S=FuUo*RluT(M0*M9#VY~S=4Q5NvD~N5zAPh6zHQO|Wf1)H$E17J zQq9J)`)lgZ$A!GdNY^{YJZACQIJSWr)ljC_YAbm%R??7QX?ady^>m+e&kl@MPUvW7 zpy@unM2BUZK9R?$L#OdT@fFQ}Rc{!3US}e3%CvOBL&W_3(eFS>B=XKQ|y(&c} zG^-cEa|8fhG?$27=prI>Z-HGelCc{!A9N!{u?7{hHHJJvm7JGmBPyGmgelex96T_L5)3}pNT{)j=-st^6mF?*cRo5@aAAbiLQ*)G=4J&7HY8GFN zF3gKvc`-Mw3!6(jYL^CM%R9$(U?5fhZ(0Z3eakD+2wkns$0s-mz7`hcl5Y zPg_sb`mr}WDZpfKyzR6c?{yA|?LxQ~x4A?|44T(T?FiT{x8|HcBWFqyxB^E>XqYGC zXSrD;>v)kda_^URQ%z}%6Trjz;@lVLF(_T#_vLT-1Wfi{9$~O6(vq;-b$fT9@w;T` z+{)FD)&pz~4_5ZyK+{s#Urqfgy0u zgYbWogdDYqF~g#Le%Xq}YZ24bVTSefelJO!Lr#PTH~vzf`u#6FVgG+XhS>5>4j>p@&H-4Y@$X8rf7*_;}Bnk?-m6}8W@4yy0=$(TZ zoI`>41G`)YNyPI`fB@J32fO5h5|LC;%UiWbYPJYLJlGjHW}p8o% zZ{4T*g*~JXx4*8Ro}AkZW+InP*NQ=WvPkC#xbDDS75fn3@^7@sf%Kn~v<0(C(N<~) zA4)cy_+fJY{&f)Mw;`M&GgB=liilr{A*mWn7Btb9=pX2b3*9KuZoS5EOI?{8AT+2S z*J4uwa)499^F$DY-l9dxg&H}g!+(AWu_W=!^y-svCnaRf|2G_JbK>}o>dgm5|Mdkv z>^bWS>4>-HzbF!x&W`ePD4*Dy#xc9UTKUxeIk|nFo!7aoY2UJbl<%egNW#;l|EQnq zw-4Dv65(T=wTPCDfRd51k`d{Ay6!ZH@I`zIuOA}--}<`iQ_&NAl)j}pzjJF{p3sE? zLraMFhE!}_dm%}yUi0fdDnMyoqRBd9@ZaILU)T)K=&fKd?^3|l=DGMVOrB;d|gy;09_cO!c ze5eFeE$dsg7QjNWMHWx$PCRUKVX^N}h_U8Xdu!aeN5gjtC$X4vF*5> z=F)gg7nt7HxmTy+wx~D=KaBrq|Gdr_XDURX0ZMR5#@p?m*YOs_T4}pIiG0VilHW({ zH(@7vvRk{FOfLAV#iS(B)SUD9bQL{{Hj@&~L)Qan!@Y9@R2p-Zjo!=GwFC4$u7xN* zn4(;Z3NbFPAdxh8Vr9j4QKvxLn`Oi!K=8Ac_jnmE=%?NBww!9GZq46g&e(81h(&+- zQy?xwXDhesaAosUY(UBsYPNx7yg7My{RM0~vP)L(%FAqMwv5OgRL-a?;i_v6Mf*zC zF`xlOAIDAv|C$>8w=5i3C7W38bJp@e>!))%w*?v}L4s=T?YGoivL#w@HO5ETcP#E+ z(}ue76X+Pq8#D3V|Gsni%0+Sca@|)sW>0v3fLq*zm!DHm6+Ii}X`t~KBvIaQ<=Bkc z_3^*+UKzXKN7SHD!9THny3o2Z#!dd#z-r)d5`;CRZUr>cn?Pfm5t{GX0YEk2!RQYj zv4=mz7!-N-+l{{rVnh$#wT!EbY)~P(3gEAttz*3I=zROSu0iC9JEWSFNn zauHWVB$Me#isl7oFgl=<7}@OcW!`d?ro{rZ04;oy{3ZffC<@xIyi@_-AaxV+EI1I*P*|)o-n@OVm5hSAj zI5SQEvB04@iQyA5L&r_Uz`QeF?!|PBEvnZpJVyMx2zk9$c9&rM@dBSe<|Xy_XG?#d z6gG9(mhJua4dZ&O^Ii_u%@UhTeNX%f&IdkJf4>bR`)!no6lXh{gRL)6PZr8yJ2sg2 zjBQ{Dn07J@!2w>l6(%|xR@4R?vH>n_tG!Y9Fy=a&oY)^+2xZl6J<=JTG!> ztHe<7yWY;fT>^BZ!c-`pu6;2$S}4kZ^jj0Rh{hK%OK3`U`@4gA-gj?yC|&^DFLNR$ z3r8?dkZP+D8^mH8DiF;e#NKYX{nOB{CJI%1F?xwWqj&(ZGvAk;7D4Rs^J&b5KqL4W z4pffW9ey)_3JCiQW>cZoZtA9RGu{391$1}S7Ik;@5OsHez%7n{9tP$;f7s1wdn#J>kpPN)tbWvNvFMSwU%GYX1d|xk>UN=e=%UnW7+!A>vR_^{1DT_+CM2cZ( ziIm~3E-n=C)Dl@@zaO2A*YR+?HOi}=W#b_!~-JVt$HS+oS*2}3sA%gUiLxP(<| zT_W>1$f}~Z%+va} zhb)TDC_uDMJYv6}wAw3~7}fEckO!R202<+z@irlK;^+Y6scU zriJ#MM4%%2Wft0ZXyRGzPo_4$6KMKRnn-PBK45OuYgA>-EnGs?5z<8|nd)^Fwymt_fyRey zC4b148=*<`g}X~e(FHKnC>Gi%-YM&SM_ZM2L(?3YBVNu&Et9_cTB=ZX4Pcp8N>PBM zw+G421pnD_R7yX7Hnmcgxs~$b+|){`j9L#x;H;EKv78diQ?kEO>Pz}cSo9PQXj2`Rt@)lm&Yat?Tx=nP!q1B<=4>NBhWgWV#j-}U@fPS=h*gwb!o zp?{}JRb!?8wS-)2o#kea=|62DK zO`{e|L4|{Q33smEox_f>ovFJ{tsk^D6e=w>H+xXLx^Cv_nw=5|BxkBh#W=RH)ELIa zfHYG2g5UE(yqFguYxHR2WOWBIQTG8zXN~H zT|lPNwYOzyG7ByWSKC02^ylotU5 zG-9O*bu{QV7)bTpso8uI*tm{C%7|wn!+6&WlbDpGFIOTdEE&D@)MEBnn!IAX0M8hW8=9Mt)Ea>GwRV7xP;#_gcyL7M;N{ zM_{jb_lLArAdu+@s&-t%)fu%vm)uhwj9w44W}vGbgvlxrwIvD^B!;FGrzn?ErAJrT zS^Sh>bUK&E57xb{u_+2hKUd&AHpEDbQ!a@+R9!5=j26j|ct#22Tf~>IGVOLI28a!0 z=rRIU@H!-tU;VIj*j^PLtRebS{$@nqc?_a|V)02N7Mp+GzUNO&5pkqAgl4CI`AXOL z1SNDV)vgJI!_H2JX9uwX+R$Z4v?ygrG)6*_j~SNWukRKg@%uR2Brq;ElxjFZ86u^u zGGb=7!rGw9Gou4o%9`Y#H5d)IkQ2r9PbRlxau+;3{MzW|hNHs>1=1pDz?aT2Bs5bI zdUDj1XCo|r`spJ&t1;GHw@7)`%claf>uVGd~9QQAmr?S*w0j;7RM;ng{Ggp%QD)TH49at7j1O)Lj~nU%{F&eiLMb!Kx=t4)ke zQg#*G8^n{K9kR?WU`=A`d3y#Md0*hqSq%~bH`7NYq49a*q6?+8!(%cwGx7hj;YO!o z8=UVSMj*KFsgytfX0>%5lg&UhYqw*;Y1znNTlx-%(UzdCjy5-P2<`^(27y^!7>q1r zGTF)4jrf0-e+O(BMLleHn!R6q!eJU>a(S3_Gm7j&j+xa z>&FhQAKLoB779aAtssViKjs<=sLa@wp`csuE&NX6ha%da{tx|q=*gb_9iJsi#p21d z708f@;nL3@vlD63WW)o^^jI1Kc1xg%UTFE3vu^1K)I+6!fKTT%yZOKV2G?Og5NWq=7GvfA0gfK(ZgN`*<{% zRXQ`P?ktEyHz&@B1_zbS98@YzS@N<1Er(|H=rT%bV=nwbD{NV6hs?$Lw|6rzl}J9ZL74T zIxS_oijyt>^_bdS!^azoydC5`;Z2;`-9U_UyR>VFKMa2i6(=99C{Xg2F`oIH3{7a` zws-AcnF+S~q!D{J&4T;!VfFuCnSTZTfHDs?f4k;k&)M1=!2k95%*pwv<1?O|Cmf%3 z&!&^mzcxMw|Nn-*ulNx99?=cBUiOLquj#}3_u1t9wOgKxOK@_uVrVSb&io4>&8i>9 z@7lb?@JUVdrMBOs2YJ*DG~( zgr^=Gy1d_feC}l|9yorBWhHb(a1pSg6`@h_{ixfJ8Wz2E+0DV&SBP4J!%$h+5MG1c_ZLA-WgLp%r+*ct z8y8(o)U^J%uL{YX>;NkTqG$f)CJ|y%5cs~vOhxO@={?D&oo%tV3p4a zSpFkc&4uvcfoYuhI}7;S{BP>M@T6h(n0OiwZu+-qeP*xZav2+W`)QwzJnV2~^-t?j z|I@MR!XEWM`VFi9clMaLmPf=buig*3HxNxW@Z)aypCq&_z9@Lhc8nBOEN7>g8?m~E zeN_)#fX9X-mRorlapfM%Vryz9CGIcR0?@o)IavO`b@zM_e22k$0xE?-Tb45?7iT8+ zu-8iL(oN^H0^wIg&#{re2|PBUbWa@@W(WO7-k}4Jq5iO%qr+ZnR+n-Q=%My?`(Ucy zOqYH{?X99R+Iw0z=dX$7-(6AKw)8Z3!`)fU<)tm6h_`3y@&)-?e`&@^0sLrgtlUZ2vw-zdory(BH3#lli ziU1(P3-~n*JH=}FoN7=7#ok1#01FxIR`aMJE3JY7sS2Kd!GSRB56c9?nOzn9W1p|D zNLH}%=`IMi{WA$cELp*QR>7bDCk4T8dsc9FS_PM?0xfo4WwL@fR>1>Z6)fsmL3vsQ zGgA-@OjdA~RWL^tNdE$^2=y7wo${Ij2o-p@B&$OKqmRyVb!LIk6B#v%T>k!YR<}|6 zYv!35PjgD9lZ2MvGivug?~mFOONFw;Kl~o&d955AcN?^3@+Su^H-mbz)#Dre3Wlw; z3Vvo4p#LfM+qYWMMs7x0EfWV&3%6Y|y!>P>Q>>O-RZDueZ`kj;eP^<|6L$MT5(?faEkg*1yvJmOXwdfW`-s)rn@Y+{=%R z%7{NhYVE0(g|K1V9X#JMCeBUf$|sjQ`USLwtR=A;-IX3x6eKt>+hQUFE&90bsjpK^ zF#Xf5Ad8lV%4Y%r3nr`$jw86w(fmal6EpR!K@C_1r=$`mu9aBWwTo}_ZGb;5%^AjtC&vyt?jF>i!Z!y_T>%(6u-wp07 z9o$a8^DjaFRHDkDzubrZ%HGglsrVK#yUv0ES{eGAcT(`*m=6C&=syMjT7ER!zScYM zandCS$HzzuXzSM!jV<>d-t}oa`@jD*f%u1P?7Q~6!|PNK#g%V=51P`+ z$4~6}fQxS+xk$oN=LSSADFShj%JriiHS=X25#%%#x^bGQ*u-1+o&f^@e17EoC4nLChz~>DK^(ElT3%-q;YrI53fH*7&8|I$ zg*y#dgQ&Qxy_+AwY96HlMmY|SP$VyqM;qmVA+*NZ0=*UJZHeBB0(q_({U}kN-I@7- zz}oAFRUy%`G!NzUw^Jc_$Lu72WGGVYg5db!Z*2N53~~dl8t^!qmD*6EFnwGQLb(!> zrl@mcC<@;9)=X7~vLwcTGYVb$FIRNKHfq=({M{#~i@k+^OhYx-@wZE=XDok? z`cduf^Nb|W=$!o|veI3@Jusw?zRe2^>8t0$z>q0GQm0dif~;VSUYPN*^zldLWLs9fCpGcDwEj7cJC(aCf%emWs$ez zcmB-M8ju&CY>ZX(>&HJn4$d4CeWpRg+brVkMzm0uv|u}G7U(!nzzKs;Zc7^F{%rRd z8QyKn9UiTYh^Y4ZzX^|d#4RuI&VA7kS!I_rM6){663w=VW?j2}L=U6c%I!z!^y!B; z6mlsbd{<6J?I`Tjb7^mOxxQD%R(tQ#hv zsNg%o1oQV|=D#;$S2|JYuyeYF1C32cQWV#KVpk%5u7IK@6l3)ZMV;bPR6n1hIC2Y5 zE=H1=3`s47qz=}9jNFivE)lT=WnCuv$Z;CIZ6E<%GY$Tmn9{O!JV)^6A zR$@RM5hsj(R=)ipsM3g;1Ci0e&aG?;h6h$RkwcWFc`b{G7CmDVXXl=k(K!}F z)NNg3%CNnr+$*1XkW4JPQB1oClN@^xePuhnI;k1iedz-bdQmX0QO(!Qj0*f&U8 zG)O!kIDTJzJPZsUurFgx4mU32uoSob!){ZtA)J@p!b{d7LV?B;h_qz<4v(~qS1RMF zWW1ag&Q~n!k02|uUSrfXt4!PBv*~fB3?Jtdd$M0nb;RbW>yr~OQawy|U!t@Hmoxsq z4|r3BQz()xyd(SdC;V=801oS4_wNt*Rv$nqrpT_0ga35Yx>|4RRtk;pJiF5E4_(Ss zLT64e{dF{iJ=?O&FuX4#oK($~I`5npjLt&NnNSbEc^A^W;oUquA$waPB`i38_5p}E zs8h8cGBMIRKASsmSvDmWhFbS$;psAywO~KW44!4%Su--Uel!3I?{HklNO)(Wc9t1= z;C(v~lZA#`DERxN6|fg$JIwQibX~ha)E}}N-0bRflfSI267n_1hqlDd9dwbH=%srC z;n^nMXu(ss^b{Ys@pRUePyCzX0*>-$zy&79;R5s7UsXo?c&A}efGFb_B1h>-Qxq!m z7jhMhWBu1@L=#78^8W-mxzU@&6`joK6QXU0;9dqu@qI^Gkx5`81FlIqxI{lhQvJ<$My#>5i9k zhK=&~es}>=PNGf*Pb)mi;aIA1BCc5_++<*L;c797y5>-b2K{? zjqmJccjGon$^F|auquE5wuD$}+~XISi~q?H)BrXeIf15c8hfoSAw(w}`{#Ku;`6nd ztO07tBQ}9qRWv<=nCCsnvuw?yCX#Z2<`XcS@H0z3gU8EYjx?NFI)fo(u4`jshbXKY z%w!NRAu*FoeU+%1HCAsDRV%P3?nE#}evh=K>}v?nbFZ%N*sO8RXYjwuHgbWYM?`iw z&%))qUL)Xk8}^F>D;l3KHzz^m>&3;Z0#os9Yf_Z44q8RZDp3-=HHg3z%n1>}Im+q# zmO%JwpUFU1+llI&6gK{6DD&uGts@nO5HXoQzmb|pzvY}doldaT2&{F;k+GMMB|%-t zbAW~9e3j5aK7wKMLU8=|NkTGYB0t2kmuxkPXx)W1&iOiDk7eKHlI~T~aFWtQ3!@M_ zN|)!VBJc8__o5ZEZZ=~CQ9lKwbfBowOEDzKCYGl=E^~omEUdoa$ z+I(2bJYKXus%`oB&Em9bQ83nMCZXQSf9Q@iT8e9Nes-SrJKI5UMYK{`ZBBh3<-SkhVNn<)*D-dgQu&33z}iLmWrsK6wrhQm@@! zqT>17m+I$k(PuZa_8}0|Y8`7dTfXu82p*GM<|XgC>U0ono4Yo(k=C3)2aUg=t_|EP zZ<-o|bz}@hNAA)4LZu~9vGyQ58_W47c^#DvqQ2tyb=t6`-7-^?bw1R|fkf4qHm#6B zvQ+jxMV(Z=gl7(f&5=08H58TPu8ihyB5sRp=pQxX)x^+BLOE+Dt$JA^PPBFtl8H05 zMS=;eev;HmUhe*hUT8++EZ5pqkrzYbc7|GC&r$@0D!JRuA6_}`&3K1Nk{p+(uzin# z?`5u118z#ipVX=Z5VH-kX>QliJRgFp@QGzVoiM8Lk}pS+FF6#lPX#K?sN`9~V>2!; zU-??+3e>dor{X}UA14(sx=IjteSZ1j4Lt^$v$yMur)KUztG*?e`LfghRNhYA5_H}_8e02D-pQ+AHpzA?B|OD zyo}qyIA5=Ay&q1tGIK-axZQDiL^30Zv{Bzf8E;@CO!75GyK-D|oRBitD0>>y>FQq> z_h~SX>u?{CC#n;!RZgO8v7TsQn*HA*aQ%MJ|6T3>e#HMR&ZF-wJXN2%qx!b{--Q%? z-{b!l=Jeb1f9L4Q?<4+i5uSbvPeB5A76@MuVxfMATiKPr#t{Xx#l8bCPmUPJPMc4r z68}eqekd>*V*L^-WLFp7P#o-hUYAJk{U!SXKj1vtr^$J~_GxmV+Fc{~3F@$*Z{0Qx zkA7E0T6H!VYV{^nWwupuSc$*H5b;84&IyGN9D$(WpV&Vy9YXk!8?q{<27bPk5VTnp zi8WsK8y!eoEzVhA3HB+7U#MKYcVw!<^T(E?^R*GYd8hFQ7m{)oJyRw^4s6LMfWG{; zj|jHAEGMdBdWBl!fNgUQXNsZl(LOaF4~1U`?3X!PS~?t<=MI_%%)6$o;U&TGWJ|mr zBYiLQx?pcJ*tvhfU1DSb0bT3^?^#lt@n3HaKfF)!2RpyKXrETEuUrG=c4Aa2_~S1k zmU)-zd*sGEVl4OVWI`h;9m!dSSCSd9HJtNmlY?dfo!MTkg%5&#z)1=pM>e4Gsku{4 zxHT*onSmwgygy0!kj5v+o46rO`k2fu=@xND)stB50E=vD{TrYisvn^O3L{n=-rui0 z@blKGYX%i}_K6b|y%R-6RQ4dfKwW<_P=C@L)GC46c1KT8f48p-)UUOk2vpSrsC2%C zH}R}Cp3ui#KU8IYG8|FK@%imZ6DQMOC;fL}(seXvafz-m63g~Foo@u2cGR8AsT=Wo zYEaW?Z9L-rS3Pz5xB2%xZs#laVIG25lG|#c*8Hu=Rjo5lB3F5D{ik3;hi;m_E}O(S zkuTcMw9}sU8kNSx{xm;l1lQq1%^3DBxVC^hF zy_~I2sQ*DRxa~ID@CKYQ?eMPgs3JD(>ON<6tv}lXO}qRW_bYQOcMV}S)sRS`+1BlK z$^iQ}b{t!w*w-u*`kW?xHkhRo{6B*2fETW(NOTbHCb+26tvJqCPFQ}i882%6@JmqA z7C0Ife-FkUH2_kDjem8mKbIxT$Fis0iHUCJH>ALK-3UgYCDwKT2~S$RN3+GnzwoYL zLm<;!HdUJb4Tg&9yuf2zSmJ#?cX`FIwKif;!a3IfwAF=LtsQC?mV_r=stTnn^9P6h zhz2WhKARtGXsbCtrj_JpTC0*vM?V)19`d*gRUl$uctD@*PnHyGQW|kEDK*sS>%9vJ zLaOxr%vG{S%Rhn;WwyW-iVq~l^#Aa9DD)NpJv#ZGECHJM^3 zH6^@oQp28>T?Sgg zNDR#Q*QtK}Io=@*Snyzc?OWa7o7&LRETb-svZ9R9qdD5Lfh?7IutnQf`% z6bdch_0ZBnYo-hp#XlKEV7)@crufH25|=Vemx-OnrsH z_bZpQKuNcd^R-5{Kaid5#A6uh8)i|QFDb~-74J50 zGF+YeOGQ{31jAS55S}HxoRb}PnoDwU;M}jKuWlsSx8jQ{;E@kN*TOXXWblIt4Z*JIygYvsxPpVt4I-?t*xg=R#f zVRff4%)T3+0&fXBFrQXsq#4UTcNFY%LsaZjPK9BOoPX^SkAv~)dXTuOuIO;lLzV@x z>|qMRd=Qj)iFJa9Ot86x-9pasPEW!3#hwdzW5x&DKa0MdK~-ve&^Qdn5d83ltXeGL z*~yuQEl0N@MJ|iHht@vC|E~~kB@+i0hXeOK!(bBXHT>3!Pz0-oL&05dASgd-z`7f+EDilE#b^*LMdlveG?5{-ky$5ZyEQ#T*?jyRHl9P+>san* z{yc`GGwepHgNX_JElXU;-x6k3thzdZGxzF+xa3s|9>Dm^;WFtQFIN{6%M1TZI;$Fu z3g{H6fKDMGz|O=e(XZx6$Er;QY;7-ghKh!__k@Jz=u6Q}l5@nrxz=!W=wj>>8jcQO zvT$mhxQG;d9P4!~x7zBki3*l9Ckh&lp62JsZ8&)l_=Fr$=%1Ehxe**`JNcW+J&GjjVrN~4<7@}Pl_ zWoPzCv6bM$6tK7Y6W!srqYFOx%Tg>|V=J~B{iex}H(@bl+DqaypAsycUA978s!&TI zl91YF*Rn=W5O2$BbmZPsdJ3&JiuxBc*#3>Q*P;8d%A z1f8TtU#D+A{7R?Yd0y_f-Dr}HpWr`^s81X@u-zd-}EMOxZtKEwUrd7JAJXNE7Ctp;|dCV-`r_ zG!Rfh#dg`qEYbOCAZ!;xrFzp?MMoZL_I`UkeDV1Kj1aiB7E8C){gi2$ti=2E1qzxY zrI*W)hzggkG2!mlT0|k9g~7<1C+c4m9i`KLClSK^!nFS1@gd)5`rl1{M8)Geo{j@8 z=109P*r7DLvDTPs=ofeszLh?(S^yUqeaEl(;PG|yV>&wrq7vw&LaYMw0z9@q^W zgk%GamoQQs?O(wor9XT*u=;%s;5dZQSAy;Pg006e#oHCk#QeWZ`kg@I`wR`b_tDBG z|1LW3kwOvrt1R6VxL4tQFu4eXe@YH^kb??R_$B=1<$)%hIV1}2fF9%|1j5sEokXP1lys-AK@kjY7y%AW5?cp6PWXZm*yx~Y; zV3jiSc6p!?8qpgOVSmHhe0*>a8+=pz$Nb=wOC9`XP4#p_&t-x_GiM2a}-qnR_?M4~jtR3FhPU+6&E$jsZ5{!-{yxxez8*>8RP8wnPDVcTL zsZ472VfNGgD$3kq06M^lRgtyT+p3S;mtdcd(Ufw)=elxKZZ)VDszU1qE_3PKQu>k| zc!jn5YYk5AU>^~bsU>BFK}Osux&=b->>tX#;b-I96#`CrSjmFCTQLB3>m!Oxg@Vzk zyl=|Uvl6$+csmaeFcAMszqAd-i;ro05BdF!?>iYww1N>zF4(0Y5^{xc1 zKW$EVH77f@{yYNgzBt#=ksoM!Rs9MtDZ?ytlU^C>7JE8XYzU-YHIStb?EGO2KuNrkgaDx76f;j9wymmiGrg*btHL2EFp zm@9%iB^6$TRG8JA6bn0jvG65Z+(b=0Hj(oRSyUsgR67)7xm5uLReKj4-WtlH{uxLKWSMMf$ z0aSeH?NnZI4`rh}&YU-u ztwq^}`hBu&9A@5!jX_xk;jyVE=SUHGr`$NRYb0xDF8Nn$_i<2qFA zW)8hkU%mGZiBImUL(P@MTX`}3?=EErD(;KzC8!EAG|Y90ck4Oo9__c(axGb7fO#Et zSu>^8Wr43>YWy32xXD!IiWidFJ!LQ{Cnp7o1UtO7vKMiO7(X}D5vhsfPuC|9hPTkx zC6suAhS1`V&BzjbI?9c`%AlhvEUVHPu;-HwCKM6`OxAUzGdVhvfCOI%iFVWg6%}I5 z8VLU^ooFx!(U*DAkprTY1F|5(kA z>GU%*)dE~)q<4znN`nomtYc3^GDg4qg6fVhi5uC7WZaV8jby&;9sIi^f$sG3)eP5x zBGJo2b=2r(Bbj~r!e1!jSaf&_M(<-Z>XoY?U)U9It0N?eQO-i|<7Z0@#VI&Q4ECa$ zF;GKynhC~pd(ccUevC!+184>Yzr(xx=UUiXbSAf$S7x^kJhX6oZ>HhCBM&5aRnoq6e)Mdp8Zv%wYe#FL_TkPfZqk zGe{lEf(E?+qQc zJLXevLx=5-c?F`t+M3g0`^|`7Ll>XHU#qO9I59yfs*QK_%lwkIDq2&LP%f*CFN1lv z+Ia6HVPQLaeUqNNzXB&|Ei8)#y5HG_*5=jS(8@WPyPx51mnQKSEZtbUSXv8zeafos zuhj~5QyuZ5O@-kDFZwMj*JI1uVh;5_XY(;h9<7b|#YkZLfUxR5hb% zsUXm}ST(SIg*(m&G=4$JfVNOrShB`(Gov5ApNiqQb*5v8^fDboYcESxkA8;lO%qkw zW7QYWFP(L9-4Nc2c`L@GX=i*OIvb;}c|s5d$)(jL7DN`8AZ3gt_Sr|YF%Cat8Q8s- z&MNDX;iaw&;f`T})dP(7I`WB@D4`AgQ1~t$sVo1~{GrqM17F||omMaJDgF>x>juU{vz7EDA*6*n zPRA#L^(4uxSVF6db&SgXF3EF9t0{Jz#%prH;#}$BbxX{`9>mwNohd8!-aLBPgt9Ub zg~?XrVB_(;(wP(t(q6?&Gm@X}JvP#ooYM`h7%Wgs(Z+-fq6Jqahd=pDGK{WaN)DI1 z@|>iF3ML<0T8))vm8&p_sdsF(2p~G64E>-)jy3l48ld7wy?y|80T~cKCGW-Zfk-dMdFj&=jyb{oZaFq22}>r4&>FO4UlJtk|8S zH!7dIJ0~?(BT(Ea_cP=UtaWzD1l#$H&}i*ZlJ@dH2$=RXV3NEpFNOV5;DOh{>Ecr7x(YvD%4Kx%l!*YAW% zw+B|$+VBaa=t!=)9Pw6RbmQiy^e@-2Af>vwGr>|P!Sp21UmR&)`KE0CTzTuupRF$o zedEq_*jB!!tUy>+T#>ms@K|Rsb5p4FNMQADid2r<9Kv&8`>R~2=o@V9M0vD1n0dSs zlfW7r2&x^g z5fhRMogyFg9+w49bEagRItuJv1xGG5|ojG&%1L$w<3_TX;3T_?l%?w_RQ zoRQDs8Df{-W1r^qZZ32d%kEo(o$#FC3b=t_zLa!pP{9Z+T`%{Kxzmn0JdG;AjyB_?Kve)Db?}|cxL~|c_ zNd3jIS@3HDtW~Dy#HE%lg2p!PM5z?cEGAi z$_K03x7wDyQ8nqXzW+nqyMRYoUHkuuVKfLh;U2kYl%Sw!gMt!~nn2JQNHC~X6tt*F zQBk=hfQlNN1egwku|=y#+tTBuw)M2O$0CYVZgTU6QWd4A#rr!(D~Li6CBM&i?f0Eb z0@$AO{GaE~^N@Mp{qD=!YpuQZ+H0@9wu8m!uhqg2VOF-9Pv`cp8nt@YP$fX?iLy97 z!vySg-2kiXxL?VEmy!!pt^Fev8rbCB%`Skq=xYA_nk$i%aVsALj%UAq0e`KpIZ6Hv z<5lWnm71uo850n5W%=fIaVqYm#<+Kx1gnI|e_8kHZUQ`-ckDUhQGA zVUHqpvT#uZx!curGE{xJ#@iM~^U0I3(axXYd>bZ;g&mZB)a^v*NHUbiIe-_+<%#2W zxjc4ok9aMGI=M&ux*VS6WG_5pq}P4)OfU^cMq?}UqD>ns;`qXD3@_H_iUa|`Cvphz zlvVHG*bz9;RTMXb>mFozQjxq22k*Br<^ZuaJEqBfPv9$zH0aM_G?nYf$+^+kzBYFZ z)J4z(h=2Zi^$Er>JIG=WS+o{OK4`vkwt;U)A{*e#t>y7;hIb_Mn%O#`#r;908aoaP zYzdUBTh=O+m{y)}O#^j1ppM4bM_;3ZE$51?>K6AO{ZYv7J|=O|w#JJ1KfEJ#i+ll-!U7ZnZ<-tzP|B6!QyTbaG-X(aee-H7EG zwym`xG!o+sXFXD9k%+Q#)U{1N&Cbe>?K#!DDSzhAL=v%ja9|-yFf2|i5O}uf6=6}E zVvF|yP(|Xnio~@LW!QkXkISkk{w7@aJYqP?5h+fIV=rX~QSqh?A@RoxS5n5%n2vKW zcNUYwnI+9QlnOgdh)e@4XsiMTq{hDDv8y6lUA9$7ZDgme0fYMJv>7>Gl{{luQ6-NCR5IU)FlwR~OdgQ5U{Gi%)?Gx^+)O1ow^@BmjL4N8a~ekWx0$!xHM(6-pi(0j*P5SZ zw`Z~{WdDR@@5tMc!^y7iLtagTdB)9MztlX$Yrehu$-EcvE}@wXYiXYlMI*FXd6T`b z^bF)4KFF0`5g-HaKx%*F8il7|{xhJv0GT-``tIL$)fQwVK4j{4Yp}y#)h{?UbRWI2C~VxX^yUbtTd$8Q|=9f~?~?gkXCfCH}JaAz7HH1>oV z13ydoZG{)zPk%^oY{q!|8)l3pCu+vYq`Hyu4P*L+?QySuY#t84+Q9Yx9vjy{sG(--|hkPa6;E5 zC6u&|qve&8+*P15YHKpF%y6NNI4PgiYi zr2i$}TVh_)$BBa{3QrLUqDqzDc9@#$J?Q=8FdQU1d|EHYo~s4R;F^gB0tmSMmk8#a zcf;Kjo8vs&lA*@eY_onPzHSP~v3817e(6}h-V2*vRcK+|rJv8fNig!1N-~W9kNWxR zx6r)P&rhVj|Al@&B(0yn64-&~eJbU}7P=+&x6=Mjw7=7sTT3Qa-*`2mqO6~`0_-f} z(-Fwp5PEtDKQhr8{}N18W?Bp<4R-RB^=qxK*>iwEe89UT@W72LN_c&ad4gd%x3Hw) zdy=0kd9~xwfjbr`#Ebnc4GE{h1l4TRvTpGoHB})rRIVb?euE|=32|t0`_%H}#fOy_ zZ<#q>)341A7LLz?+dqjjDsgDMf<87t5Gy#+~Ndk0zJyS(8;0t}W)f(u<-^FG|g=QzPiS zIpxLMh$iOXWR3+lgQp|~=QbxFwy{qe02N%ahO45fqIk|e=tJO72tFi}hp%tb{nS%A z4%Yp!Q@J^$$XoJ}`s%LGiE#2&{kB=5_{|x3oVgA(j8PX%9z!)#H9(8&+Rg|OL6d`D zTEzGOhh>0e9+N0lWWHax{k~F_c0cwOgN( z?VhEDx8=isy91_}(1ASBq;&_{`5lN2_B#N#8J%73<_@@8e1Kb1x;^JCN$G zIg#+Z1hSoZ38wafJ5E6Tu0D>D_N*;y>|v`>-X*Lk;Dr<0jwk4Yc;cdj!~08vn(+=# zxG=(qzeLxw8XR_$*UojGqZEE;!ZOC^E9>Z=S*YFmC)+P zVa_CzB$8`PoploF^*{niG6}Gtml{And5?D_fTg#R0PLl?k(&Ce>6s4})>!G7RBd7n<7v#V z?%-ba&#{8eTU!D&m#@KY%#i_a-lD)3>@AxjylH}M9~gf9S=Q+{$51Y?fk_c42rs)h z*x$|z*EOiKi7~m6RjC}#bsiB}^+`_PU&=|CMeF!p&V9H#`n%_CoE*b!C;*B#0>mWW=2|r|>c|HD+?T@U8|E)Ck{t?mm%jNO6OJ7ep`@fCK z)zr|_&F#bGeOem(_=vLb@AeK~*gjt;I-xLMd^tZcX6V4bkgG1*qFp`@o_7Z$U2 z_cLqcnXt6c>3b0dAM1mU_bGQW)MkmPte3xSD(e}yWBy7$Yvaf3f3In*1%@B<2R>1Y z+eC*QMVtspbmS~nN&$IIS@g!^+h>R3jL9uFW)YZs^HG_PO0XaQ49*1HX+mD5_xK(a z#E6F(EXVPBcyX;@N(|Z@DIQZ){fQL#DJ?s<$izx>=ZIf&n;>>8VXu2H^w(tXdaNaA zm)GhOBQ80(X;N?aQj4-=sPj)zQEyz#WFrsf!wmio-*4{Ge`+8nL*>;RRQmX0>BG+I z9ve327c#i?(QKUT(EbWBMyM~@3_srZE41))c_WFgpI)w^&oRc(Cp@`GkfG1rqpX8p zy2pO&O1c;VZRZt#27gWMP5mF1)4whhH@S<(SWe4XdE&^#*gOPv-pFfTmp!XA_Qm++ zfQ(|d^7e+Z_yt76dG+T4G>?7RBJbgt%tAyomc~D-$X}6XVpWp1CCem3r_Rm5>Z%@w z)wA9*tajEX!|HFY7FPWpCqvKN4Pv_{4Y5@h!X|CM7qAHzV@Hl7_UlJ&pu)gh*1&A? z5bB!aP1Wy@R3!+U|+ zyjE4Vp-MJ?5V%CB=7)E{sShI?MXY|*DbC^Izro>Iy$5SXIm?9?|APGZxD!7x z_Vpbc(@9RxZa793tO76b6ap58F3>62zc&|VDc#GK?yOX*JEHc!hrE=3QI)Rc>qUaj zudxY#7ftn=x37sN?&wq>+gCIYV61XW#y`Uh@_NrmR;o67iG!r))vmN zwov71wb4p5zj@>7JXjmmY#5BPxOW$BbKf4HjVCb9DU&@TZ)o zX8>GuVo++}Hp(Sj{D68DW%_b+Th$@r2i#^}lkC67T+Zz3d_knbHN`)yZr1|RV720c zI(c2;f^YCj4mnZ;|AfPl3RNOFhT3)0Y|gE!&L^sm5gv48v*b5G2K zABPPW>$T=AB!hv~K%ZK{ekm)gnE9`8${}DxpD}&dy&nLtylB4XhDt!ORy}PVC)Zq& zIZjf$196rf7r}$ZM*)>O73Y>f&z$$^IL)_UXpa5*@v;~vQ}mvwoX9o`NUCqflCd^K zcEpCrPCsehU;nweL4qGTWwk<(Gzt9e)kHktylJ!}4)SRvqQylt5^Rj7u^2CKImMLv z>Hu_%s7hp{7MYvbafj*wQVqgL5=b+g02<95Q9#O2mb1u~xRGLaqD>NM-dbUXarJKk zV&I9cL5Et@yP-vuY5GYN;~gpa@W6yjN(!v})OpP^PxQ;h1nlT{LZ7sJn}(@OI#Lb4 zZXbIJPgulm@|93Tp`DZ9VD8|)kDv`MJA0thT?T%wu|lYrxgSVYEzGEib=gJ2X)<(m zsq~Gvy`IvAXh-f3rT})~yFC;J4}*e-vfyC|Ra%}%@GvfTn5K;wh%<*@$=7E7`CE-J z0coD8@&9S1?ehD-ysJiUawi8=2``anW>(FpzPhU5R%I7-8kIteNT|+XN>Zonlo|WK zE6v7>NpM@~vn8-ddGc{9R{DG{Zv$5nyYfbNgLT=$35C~bjfc;=Rluif-TP*Hr;b#N zLKX2gyQ1;3UD&vh>^U?YTRA0~oRKX(Z6#S{8QZ`wmW~O9H((dPv25X_!s~R)vuZ9` zIJfXx-Qulk1F*H`&7v-C@;*j-H2y|~g6|XFeNkbq8sQckW^mU0d{ya2Xs#-k+PmK} zLr|HuORZXL32wix_Q2r*+sfikk5p^ND{G#LB(KU9sq(G(M;WC0)18h~0!?4-a^=1S zsvS$3Wq17*>bBCFFnNPXKl}K;$LR$B{71O<=f_fzNuh{uS>f7YdIfI+Arfzc#yXcF zoP5$+N^i^u^LI1<^!9=B`t?ykHrTC#+QK>ZiNMfJ86Y&kyvE^1A*+sE{elVD72`}rkdv$KO zcB3t@7zdVifgdSb-u~CCL7~QXmd7c6_R-CU1x}Nb{K;~!Z8(wfsq+H3_j6u=Jc0M^ zQ93HXPDf=?y}W`62k1^TbPLz+?Zs@4=W>VC=R5^X$x}BPYvgd*PC)0WTe$9H5!>1B zQGs4>INygSGycG^%YUJhW^YB3#2--Pff9>6FvKDcR9fT#ZY?Fd2<&B zTNl4)9qP~D%KGn)v4H+BuWWicH?yaCuBVz`!V8}4*4$n7_I55U!L#1yU&1&RgzIi2 z&;POi+r*RK(fH2ACH9zSoKRleL9k z!Y+3A2quo+vu--h#p36D*?jpQvRNVuCEMWKiUOhM;#Jx>AZQ~EHAFOQ)T9K`a=;L0 z>WkYoxVK97%{AUp$4IWZ%DCkuiVj3Rmp>@)S5G}^Qlr`G$^N2w$KZ&0ss`(j@dW2a z?H9?Y2H_(0RiKGy2!SF5IEE3F_K{lk(G1#xme#B?gt=?gRi=642CdJ}=jI)(F`9RU z00{;$qXdOlJPCj9ZLIwL1OgyuhwCQfHD^WruIifVm64Lpi+y2CbKPEYGIeEP+meo@ zf58YRC=Y%^3!P=$Uh;U^Ne+9-<>d?a!qYB2Epbw9W9rf{Qp~-1$(Q^~76NOQ?}m}= z9lHTj;Nn^l+sA=#BR0GQyF^Cpv6;kns0fJd?-D&a!#5CfKSD355*hYkS0Er-K=mhm z{G(MG*Z4fr!aAR4mwPyA&N)hx55%Xb2J;8!1z16nJ@p5X>5Gjf{*kN6(ERy`{WO9u zI4X@G)nt>!TIEi*XD5-kTd8vhd>?sjFQ--Z7R>Htn%8}RX%CMHUfe&F&`>IkJQxQ% ztS4-R(L9abJ-vr+2R}*f0N~hi0ik_$ftpe+X#}6`o&$Bx}+h&od`1R^;X*H7_(WY>1HHxu}`>3X22I@fj3A4sD35c(yZy2O45_qF77fbfTB zY3#8CN_HKpIwTfd#zB`Oh2hnSdL?@E^{Hg;*W8Z@+(!f2@C}&cQQo#D;%H75L1JMp+;&9wwQ-a#nWav)~le2piZ<4 z6HVk@S9Ur(%w`L-xh!bN*Ig9;n!vcHtIp&O6fT4MyP}^J?+Gs$E{|@w zXQ7INMNe3SJ#92mOjxZwA~x*VTE?q(B`z7_-F=}(=LRo(BKf>trbdU){fLKp+Lr>^yDfxcmmzt*4)5R5g%2;|41?8(Zcl! zV8=iEgR0SLFblRRkH6o%6Li&@-A%D!`(kuJF^?Ey)WtTa|HSoZco=cM_1cVMEyIiW zDwHxLYlWI*sLw67(O2~s6A7n4ISqe(3`;-vhT=Ab(Q?- z^^we?mGQavz#7@#tNx@xYhNwwTQaomw`u1%I7?t+?ld=99-BBthu&|A4;HTE*9>c- zz0j8S*0mhKq#RfdWs{TT&>s&z=QguccomzAqjJTj==qe1kLU-BR04{3`o{+6Q33R9 zQ06vp6xa1d+m!(tiRs9rjfHrwH{RA)sQdzhixx^RPU449PSeJPkr!+Ucz}q-k9DRCZeQ5z0&Pt(@)4BawS%+oK zo{j3C3$^u6o0)n3v*|4P#$hf48sU|F$%9!($yuD?7jpr)io}LJRO62;hX{#3_rxLI z0&lW`!0xGTV;x=45DhOI+aFl)hQjGxK5YCRMOD%cQC(SMnf?4t`2}7C(vf#@=p`{!b1%fM{f4uoFzYsF6u z!t)VQ+6rT|HY?UO%IU6u0o= z-(ybK!rJx5&z@l5ol9@x&Ar)tu-=qEZ@sxsoNO67CX70zS2e|-+XlmL1moN0C_{BRutxr9qxIM{G7uU+S zT4ite)O>KVUD78?`ZGyzOS1QxoMT|W{a9k2KAx7i|Fw$nnD=sjpWB{)=_(*!pb9{c z7G4cpN_2fwbk&D#%Fqj@!Yk*-&+b1wUe@0drdh(={<-JI=k`bbATETnruAYM>6)6U zH4AXyL80q(i{pzy-6q*YYzF;uDuVW!Xv&K}4kxGR0bcD#S@{D#rn=za0#%RVqh@qX z)%A&9U-Nm6ikE-gh7wgg)_V_S+x@^^&)`#K@VW6+4}*t)qCf=EJ8wyENao4VOa){MXd;IbxTc1$3)7YbXs4T!by~% zx}NxOoW4}E>MlY454+)TVUB7|vX{p1GyHdleNq=_ zmz7d#C(tz?xQ0c{?jwOJPWU$3L}ZXf?Mc3-u$Z|r0st6IM@E7)QZ0+s^7xx&@%0tl zE?mIL3UKv1oYvu^i&*@dd>;SFx6C$sqw&{q>4dj22R8g6lVu!-oPAO=`^-JbSVthh zH7Di5OeeM1I#D`(H1+}mA9aWJqg)K>vr)hryl$mjpd-S^(fF2V{BHtX>>99AdHj>G z^fUa^-1$J+EOV_-tOJx09?G(J*Oug?+E4UIj0(6YF)9~+nnZhvQSEt}$Wwj27irRH z0T8l#D<1Xv>m$e@DAb6CC;7#r_3DA;?3i_M1~cv%M4k2CKlw|=2QZjG@Wxt}7hM)1 zuLTbZHt$r+@)&;wiMl6z2n_KcUYM9x06N8Qo)?{WeW9Mb%E@UHRdX7dJb$*abr z)7j(~Pd17s@Zt`BHOt*cy^?zx50Zy!r!;YNX(AeMDUSi0^4QF$#{b>}-()cBQ4jmf z`ial1YUQBJI_X>EL=9fClCv6=7S+Q}#;>(hYvX^Y%P8!$&S+e#_PuT{ld#r0lkx2= zW!fo7Y0EI+vn}frpKpbS)Wnv2tF(Y`|C61K=Pio|#B%e-HH5g9VXdzjQ z-b<*n-W%hx99%yA(XyQEvWV0zYB4%5wk)}15uw$+1LTwXp29mOQ$8szp!17YK<5+M zWYRhHJ+k}q>3+`VLGI9HM(*EFg4|EPPjku87nfSn3MD=2lK$b6?o-lFN%CI#Z zYHVmn!Np|%)hPrKf8%n$gSx*|2Pi# zrc#}QYjyY5aFw-$>+frNqlXO@U}vN&nW{=oq>_4X-fiw=;&OkQTB+akBD|%qjW-}kaWo^d!}TJWJ!R5g7_BoQr~LH3tRKM<%OQ!gt?m*pum0Z14@$K{HA@#!7KZSqm>-^Dq9l;+y=Wl;&d=-{fP? ze*K&0C$0VhpZ0l(meD^jF;zCv*RS{eU1Mc1P&RByb9M7Wd2&+WX6IbCCt#v^pUMNT zhBcD-P~NXDV0%`$E@#2g|9Dv@)}N>b9hCh3Rz4EyYDNM+mH;GVt8tm+|> zaw?^05A*w3#q3y<5MI{3EP25%jebPsJ~}*q3#m0<|1ey;N%`TDt@i65&LXZGEUs@_F0e#2;Nb z0+-r>qiQo}xF_d-zKRNb9@BYSdHd8unChG58AJ%&5*l8Qp_QQ<$^}iz*6=b5*CwP7hwI47o;HDt8BS$H^3EAS8Qo}M zqERyEg|6?@TO@`(P%v8^*Ce(LgXz;9N{x8TD}>hY`T zQE4*JD6NrS{S(8wy8H`B`L==dApd6NAx(Uye_9xB*Dv@BFU z_W`qm@Q+yUX`byfECx@9_TQdHi*|;ni>0`ZxGDL2d59oDTxiWq;M@)zt3G&N{nodq zi{tDwGu{+9_R9+tA!Q>sIqSr4lAtFD+tDO?!=ZyJd(5wFj#sqC^;R|F@YM#}75e#> z@Zz5QR&xlaq&TDz|K9+^8_ty^@cDCq~ou9e3$eo|D zHj<%Ru0Zy`aVb5Ay0yDdwK%pB`X-I0dz6w4ZMl$HZOrjH0)yFGOp)mD{9I&hT=9qg z!jpg4XtjIPVWai#kt@_fFS$nsiwh_bUKZ^VdpCDs1T(ykBPK4q?t_C!?>{CVL;O=1 zl`5nr!K0`^?faCm%r-YPG*Zsn{a6Vvks zHl=jQjGk25tcbDQmpg?6AGy!S9UFG|wX%;>&GaH~+Zfr$J3CYS*rN2F!fA-@Sw~0K zW8D?gyoDRup4|kmoSB;%L<>41AO6FxNPHm1v)j4P=n~?$ybG0Rdjc1{zCt(78b780<6h_OE*a zwYWAXHf+ok-!$(W{2A1bLGfl=&#RH(=8 zBI}122r5le!R#c=yNEM>A|5wb^Enhbik`V+4a^zmb;02=ue9xkvW3G*KffS0?7x3x zDCO?a0&k&fz=d=hRggMG+{85n*jvI2HmFIR^VF@k!LNV&ZH>O6zgLLuUbOyux9*li zueHO=L3e2d)cHzG{B5_XZsR!l0{8$IG`_}x)hiOYDPawKm5*>d(X_aQ4O&MF@ zy;!bk$9)QRapThqQ4QmSme|I;g&-#xnsGjYxWlp9wRv>1PbbILZtvT*NekD~ z0yoLyx&fU^4_0%1BoXHRSJhI5@nm?u*OfB3eL%B(dWPb9o~}qS`yGQiNs{yd3)%IA zUWi{fSQoIfJ~_s=cb)_V4CQ8Ftm`H((y7Tx2E5_wa__KTn%vu_PbT-KpX}tGAvzhl^U^_z@3!qClYCW| zBG10JCy;ur&iS=C<@dg(#pQ-lt!2O7eOi`R{XT8NaY}AJlBYS8DLWZ@^FxH^^mq4Y zy^HE{A|nyWy#1u!K;7YKeO$6#K!=i}OnZIw2TUNPfBm+}-{%M~TghIBTf)~h-JVLF zsAYP~vxo=6xH1jn8G`XO;RP6#d=MB<6BsWGjDJ;ceY)P~zM|fn{d$#rkb2+wfO@N4 z_kJI>?mcx8-MeZ_pp)1MMe%38mpnZv59MeD^@AWg4pDx-mcYKAz|w zYhFiiYVt6SwqLj1uJ_F*5zyB(#CUIXLoIQ!>0A#JCJElX{I_zBWo+`%o5liCk@yRF zG0@F`&Q~+(Hv_s0`R{vq-S#ErwcM7Qhg>L7?p!G*sRK)XROy#QA+T&@x4DU|MFt;& z8Mx_tEi9qkgXU&`lP>IQ2aE+PL}i*>)pko{b0EUf)Bb5y=_bnb`pvj0KF`n*`eqBG?`QdqP3ua! znsm2xC+L?_B+(W(u^e~1Fq>DT#EP?Kl|^DV=P^B$;J5IID#k<}8}|7RH4AXUmG!R@ z>$u;rp|f}YNT)9}CsSPk3nB38@)3UtFIjfufT?P>95x^MCFMzxgcNh->KA24=e75-GpDu#@J)f&+zuOjGIvh7 zQ(Tx=9xrh^0j(S7u(7d0%>}sUUE}tZ&?@Tdg9g9e2c-lo}urJ5BFE#2Y1sTFV6JDT8nPyLz6jlL=dC0)+Jv&gAC z>yx1Y7qA*RuR<4`v0-cQ9ViC=r0ZMEO|-+=YC}5k=f)fVN`O3K+S?7Z{cj484EZ6w z%vudr7yo&bkPD!5dEoc9C|&scs$iW-nVM`nD`_=}yK|u1Y+VF7b9LC6-VE zVT=2U6@Vf5m43P6cwx;?2V+W49iEN?WA?k_{J9$eH9XggFArdOekAHbY;7(fkNIOxfL3;R{&Qr|{TIxYQ{mv03UUaolIINhuFE#&|CCSUJX#0Qb>D{CY`C70 zTw(#W2?INd>!oXCzQJr@_huyr&59)Eevuc+-iPk-MXq<6){(L*__tUZys+s~)s3n$ zN4lEjKB!XM%bDJ{@+_8grUJm-KT!f>T{@y zXmA@-Z(E&_yab0e!Ukunwl}9kMoF>~D<7Dk^E3u5BGL2(1U`=@fsRal)*m7HwT*RA03ic|2 zd48610@aadRDNt&?WJ1Vuo(b~C)|^v zGXn+|G{EqNV3_DGEDW~9?mGtob%rbM(T zk{F1x_(ddpmvox(`nig5LSd_pGW9%rs_q_G%C$iCNR zzm&R})XZG0rTtu`@y(8c;rW|M#DgH0XqsJ)WPyIf$nfu0k6hTLVyMm8-ZOuaI4@%X zg|(Zpi{VMh5B*tPkTP##^Yt7T@el$e-@rpLr{JB&mJ5Wba2VXWragE{iY@d@o22Sg{1y zm_~f>zT+lhoQM}XWtZie+ev=5maPmK!qIZCql!|CmtGP71g9Bgw+hrE2yuzM7f>K|@n+GAhpQQC^^ZfxwGxr%E%=^?W zyFwFi6!6Y$?=)X2#E@c*?bqY3V+&&MXgNd08bjd)FG+aO{6rMJ5ksB*Xftyxj5NGU1kK z8!T^7hGklM-cM;nkyHGcjC z%)DtO6~17*+T_6y-oRFthRn|H!H_u->FSRU*FRlYmeId(?fum0=;JzC9)4zf?#!UO zzs60jWq14kP9v40^sc)vUPX6Hqw;SV`kSD?({bST1_-(z9Z>#D+>$fUl~DO?E5Glt zp!`6U|MYpvpGf%@=z8;h9Q~)~w!l<&C77z0r~biEwe}C%J}u#VpDMhU4SUNcbP;G$ z=vv(^K$q^TK9qzp{r>_VcLgfx<_?=iP7sj!v3Dm%VjI~HDKE_PralC*Y{merJlLne zCWIdhwh3Wz2@^tFAUa?|7!*LG!g+!=ZouDSm{kT>WEhdffnW^2cY&6u?aG$uAvdwk)m_-w)Np~O|seM@{X zZ#+BCmQAQ5x=D+9jPJMFF*l{A0Z*ORn*WwH^B>KWY0jJ=L~ioC&@o)6(?a28)6zHM z9pmH^a=>n`n^x3t8qb}oPhv7DYB+&s3w$vx<6cYB)Aw5P%)NCwx#2FR%MI7{28i%8 z@8yPLS(5YYinIP>e<{4EfwmP-iOb&!t-Ro6dsRg4e25p@+r9dB-)5;;9QlgHL2oOI z8U{{gm%S4g(dnhIRVWTW{zmI-JN-}`xz%hu<>*8f$0R}f7QeM*=%mw)Rc3x)4kGOT zKdbQ}UP^{uy%$Pe7lM-OOL93y#w^fbXI*b#rxs;NQ}6}W*1mjEc||SpcK(QwuxJW@ zKIVz)R-R@p^`|ATO4*X3|8hx(E9pv->RS=qTh!SfH5ueatbXVC3D5rqSP#j+-K+1& zK(B>5X=@lI1~y(L|2O=G4uW3|kz{DoKS-R-;S9hQl{4hK+Zw;v=;3p4kv*#>@>+GVcqpRoP1OFqGcp8a(E(*`TS`XeRL^S! z5kNOi9f*j~6J^b`GT6k_p453|kH&Xa#8*Gp#vU7qmNMl+B>Q?^;pZvfTMlL3CEOgK zrb`5SB{VpE37GxWVGgsTN+b;&mBwtP&(Oddh@>xn17=@+8q99O8&rT*f?4dltwoZy zPYPtl=x28vc-!(0Ks9y^DeTH31wTdj?L+df^viy1W;qkiEySTQI?VgD62(H=^+fx9 zuy6{$^53qvU({zyf3mQ~exG&mw4Qml?Tma|L@@MwVzwp9l>%L*YJ@RLFO+10wsusH z+I1K&8s9(+Z2}Il9p7kC1BhjXy_(R}uX23DyA+^AA8QHvC~}wRBM9WNCy1n@s!lnn zstq}*y1M_S!)ozWy7PilG_|!l4jsYI`zV-*Ir#-d}8&HHFxA*QyN~f zR_^y75Q}EYY4!Y_Q#7*ngQ{bRQvZUY)Spi2isHTDMV)xKeI(;I^%Y8k`&^Y1ZF<$d za(W8sq(1wfs(UE?u7^l(2n+TaV2s9A=IatD95jy+dn&CWQIZ$kv+`IOzzEw z^9OEgXv1}xYof)w!t;NS?@0E9dI-sOke$nJ3s}tHsluv+bOE01{TEK#HN6ghX*Do| z@tbPw#?g=355jfFktw}UsSh}_9jT}nT`J-)RrKF`&`Uh02&&Hn)n^z)4+pAslj{{6 zWBwxQ*4WOcl2M6X`;lO00{~Z#vxxL=zC=)Ry2zTC;cnqVpEuFP)$D&+tmGmCA|7KN8rHdIzh}09j8r(1{y~7T6H$6 z*38Qrt$fD%@xdZV+8f;F&Je0lsS^9WV@F25`}}+e9{BHpcQrSF3XK;@J{vb~@!GPI zs+Nn_S^!g#^!j(Uc@DbutCgfj{Zt!Z6xlEPrGS%W4zo`;mp{`lAAV|)^?KgBx(Y#v z%~IE6L$azy$sOrvZCAAE0och7e>nwZqIg49mz3f)c{eVV7S-X`N|iOq?-s+$s?f-A zJyck*`tk(iLIMDrjtJGhhh3mK&ffeiYSef2p){O#Sh%B$7sB)KJiSEdj9v=#GL9GJ zR?j(Wby)bWY@jB7+Sde=S_h`|aWhGr%DSNY$oLi=%&M=)f458Zz}my~bt_*h@JNph zdt^9saaE`CM33_L-@Q5g6L?2=rih?OH|o>97cO+i&rW-XoY|7lUl z=`AbyoWiAE{HMYQCX+d7_hd1bKrL|0=xl`0=R~WU#K)EoYe@2qR?_C^}%M zDpG6`UAC|^GIJUIr8?N}HV@2X}8h`Mw8hI)0_PEBnm+oF)P^GUl;(uMrSJiJ>wc8Uo7|`1` z;kt#?uVyE@{)fY{Yc0i1JM>>I>v{p#G97u)=Z5hHK?&U_wh^g5(ceE}W`V(9x_fOw z6@iC>{5=JdWvAaRF-Wm{v$QIch-m~yiFl8`Ng*vT3c^%CsDcuv!toq_b>Xl=8|54H z>$%e4*6h|}t2|D)U^lkPlu))N)8M)K zMH+$78eDPCLN!D=!Bh&Ny3`*qqn3uB8qMsok=bP<^J)9~@@y{usRdS=M6a4(rQlA< zF5efz`&oT$_K659c`mI51C4ePIEDURGP8Hqb4(D59cK2Ep%)46C4~`5P~cYiNb&0M z{O(jLz)Sd0p1h1;QiZFd#cQg2C{glOy>Y#L+#$ubtN$r3KNp~B~m6xO@2 z3567+d|38LqCJHdJg6_l?}hJNz(eLVDdGq@5|L=I(f)s>nQp2PJ4qLx(Jwaa$zc+B-RMInF2nHV_tAC=m-=3fTf>@YyjQ2x ztuo=!f8mU15rm>K_`F+xu5+)h#@79l{yTzl!S~b|yrBOqDSQWj(Qmm_b9-Zbc}}gJ zZANWfVy+A|!%i6@c>0P+l{DxLzC~-LU^)p}b05WBE2$3)ds^{iagcN;ExrF>bEjt5 z-_BHpA@9?hRgs&IZ2sdQ?d2+F{E83Ov0_qJoojC3M(@mDFs%iXSTf|DEt7-q-}-P?k4nlt|s3ty=^19)tKBhorT6ob(GH?@L7Hz^YBxx79S`#wR= z3}Yax9^A7Jvo9Qbh}SIfyT_~?%vuFd5j%QeS?rJ zWsSKh?f6se70g{|3RR;MXLoe=J%U{_Ki>mxMknTWEZ~*N`DVjkoAH{EK;1W*eaFNn zti(O3oweM13>PGEWA4gauV>J#0?OS=vlr%%iVs>jDn555sC6)>)|&nONk1?zZavm3 zw#P+K?wntSfnQ4K4kIup0PGiyh^55x7QGhzSsJ%0q-a(bkwhUcLta zuPYX6dY32K?BQOLJ-Oa3$ELStqw(Ho5Uj{DUh2C7hQXkUyMPn${0_POFC!6e2h4`@_PESJN&0>tp+K zs>}3cocjX$KchPFf|O;xd@1zDhTUx`_VL9$N`p- zlnv@ozodC6M|Dp^ETVtRrHxUECts4PFkDsib5&rc9mA*Q@n^YDCFzUd;k;VQ&r`=X zS*hLdl;F<}*X|RE)T_F`=?O79hZ3f`TOXLE?Ds*}OW+ZF@H|#kGzIc{7fx{UJzxP% zEh2;}N+oDYIC3;UdzN~(oDXPDkrpF`0-_R!AHRkdt}vlnP?2c=bwy&r*XR>(d)Kqe zjmI2p0KX~#;^=&$lYdQga(&;NW(R7L2!-PUwn*)lWj`5e+uID7$M;u!9^zAI$r1Xp zmnEJ;qW2g{Y}!9f+*ZzKGCuhJSNDC`34C9e`F*Iq$9LFvk9VrQG`g4Lc##IwsL_~4 z=?*VGOJLzBV&I`d3gw{GP!8D2&x##`72=CL-qvak0w+UjxSewak_!L1+ug}v`+C`2 z`})ffeC5Ow_EZ0>)z8eN`n@hBdausr&nK?79M_=%{piqBj|7MAZeXyPX=AT#vr}uZR8R*EjHF5_57za&F=NsN(r9_y@f(ZR0#{n$4*uj;dR;vGdH3d)VP}t%h3g z#q zM?y+xt)S;ZWrm)rTpElTYu0ccHqBTXY60n~jf@aop^GuW@2HdS;h1iXkS6aWf^QL^ z^O6XhPo_+DuU(AoHba3iJoCcIrQzGx63u0;L_>W;J~?u$PaKmdbl*D%pTLLoE1Z^_ z9H&p0|41_Q$A-+yYb zZgx%l-p{PYy2b_A-Ba9%sk}A!!_rRXy>`N-2PkK2TeDV>I zI@!K+IYIg7mx?FhQB`<;vVD~4`c)i+S%i`>CeaJqHCiW`#w5yLO)s?=Z&m0mW~{{R zYrS|)9;dbD_1gd=iXWQP|^tud%@4zc5 z37rU9SfGFG&7RFw#JE=!2xpvMEaF%HB;d)p$UZc%c=APDGW794UjZ&*f0+&MLm>y+ z2|N>wT=974C#n$1X$e%9s}_@?`>Z-HEd?}g@(DAS*Z3@ze6*n}T66NG(MWTFjuJ<{c%t5+u&dsV?ig=gJ zs*nvuXTudJxgsU?Z51dmf^6HWC)c2GMg+}L>R0Ml1UmCRJX#!!L*;7kGCyARc7dOW z_p>_KJ>u7oN~hYPo?#`;Zt097E*UZ6?J#uRu|2IEFg`Qve-kuH0)EyZ{8Fp3Rt<4k zi}Z4Kt!UwMo?Xz)BOPb%4vf6y1#ksS-5yludr(3N5SE~_r{z1!*C z%NDEo1n%_`_J~@YviZTgm3K9`Lp3#{_lZNGmz5@8yccdHcLqu`(Ad>HubR>5<6yDKE6w;0>0al{Lq?Aqy)qs}hu&GVV8Ry{w%H2`q9_ezp_>%SQ2p2u=G_G)n62#W@iA4(u42!*wqxb8%@&c>W}5 zIqcI;G*5Ft9ydJEi?inJJ-_rv;!Z7V_EO{0;c)E^SXM5|;>PfTtCYxYM@;Jr?f#BSOn9XYNAFmLRq0rK`%RH# zl(iY|MD@bn6r=yG0Oaq33tNv`=Qengengaspm9tR^SA2*5v>!wauXNjwgI@a6GT7} zQCw}_&L^yEx<+{hEOaMhT>Bq7naQ^JG?$Cb_95PRv>6*#aIyqCZX~$j;Q*%}A_I7z zu%Vqkew(crOn^$Uv%SqUplnl|JGXB=d5xWTd@zmKI}h`jU5nO*f|%Jt^irgN8^ruw zdGUVKhhcP8jM_{Z-IoXBU-%!qCPRyOhVkF%74Yv+rOQgQ)7yb>h?f}YM@{-QRw5f% z2We~FZ`IauYHQ!|w6*)rpsfLF>*M?VI$L%=3yfr{+p0JtUYUrd=tiaRmV)75zn)VNPiY1rtAFz~(p&~K4Kvyr- z{grf0{7+~OVu&oaU*eD2@3SsEd}2jhxGw%Y zkA`BsMk7(Ly-FRP2NkBSfQl@`-XXdW_{TKEf965p&-alhjptv%zsFqo41eB--vVQ@ z>n}ROeL6n6nC%uLg5lwg&1oED^lO5-R#6_SoZ4f8DB*l#l%i6$1PaDG+XfVRd3M`? zT5s#c>^xEkm0LMf-uBDx`j*;wVkht=p7dRu)nX^mHUiJ6&Cy4(pxX$1@B~@2*a++? zv-nNz{f)p8=eM(^kh&V-=+-{&?&~9L7 zZ*Mzkt!VXvD&9v1#`1Wd)N;yb{m52l-F|;BLcP)w)r}QbB=vynJZ8o(d6Hf$Bn9-h z<@dIX@?hn%U^i?s`=ji{9j7`SQm&@$hu1zqr?GhkO=&yOH3|mU8e=<0Jr1I9M?smOrVg9x@Pw2f?1Bs1Phgm$npq)HiVWB;fKJUmlXjb^2r=Ua&Z*FQ3}6_ zX!dF?^fp)*857i@5x*I_6ELL{L+<3G7;;>y;_rX4BNbk}R{92$b%gBNrovjkAsl-K z9aHv;5>m?voF7e8y?}z!DE@ogB$mweb1>Jlg;q!Aip10xuqnGeJfDB;@|4T@7%l!P zd}ox0NHW6iBzsa+8%5ddzyJK?*(K3cAGe9D+J8>@ar>@d%~{>8f*pmrbNmt;;FZ*)vVJlfWdR(5 z#jqOR=s4}m}DV|lL`w+ZBwY)G;UR!gj;r12aP1nq^Y;Ga1e{BwPI(14A(vC zr)r5NJ;&46>@CV@^KY^}hX!j6<=&s?p)K&D{)$u7RjqWzSYlQ&n#TAB>PYD{K)_$t zn^S2iqc?0I6@UXSIX4{q8-1xJbgyeX)teS|T~FQD#~NYERW9>T4c#O;s1fhCNXrS${10#S!fl zlY~1zTp{mgijEOv)+{bqoc~_N{Pj>cn3n^E#yHi}O=K zH2be%K55^=WZI4hYJhOvJNxr96QwrArXSwW>D+|PS_i_X;ut`lD)2;XBp<54H zEMtYgbMWyIE;B+c%X`OO{4XzOd@=d%tssTE2D!TaqPo1KsqV+Qq~9v(4U$C3Xw%CG zsqo^?Y=waPv?vns4nawfY}yn z?fgpqhycystC_3t+-4qLZu#bJju3+%=*pnN;Zy|>?29erqsusR<`?0-vdt0O2kB5G2zRg*iJ!jrovbHLgqjT=L)r!beacq>3V9O%>cd;yRCvSvwl6y zsNc{I@|>{1q;h)+YO^hvSJ{7Q z3NNk%2KnU(7Oh9r!3=qusR*~!gCBRB7demnHf)wh6dj$M+cz!0VvW%M9x#Odl~YyC zU+C3G4S_5TYsn=I5q+sH+BJg7Xh3@U)&3)N`-t+|w|D_H?@JpzXG1pik5Z8CzxjTC zV!!~G`##>%89S3vO=;MVP7ESTW80ZGvEVaxQDoE?QOtm0yHZ2iD=Sg4V4`v;354T; zWOVbSNf!#IekpSLypY;}bH3YsD6*)_JKPxWqZjVK$TBL2j)X3iKNgk!?>X-KT=)IM z_IxkmyAjs=h#^7YAG(jr^|3P_ZO>${w~(Uc@x5;R54A=&^X@&NQt=IXe8e8H)TO-3 zEO)9r{>a{o*a1RseoPN zG3+`_1&vEugpHL22s6-Jjt;Z`^T2jGeGpq(>M*YC(ACsh(^nJ^C=A#2ASKEf*;Gd! zd<%g)zp((U`}VUEcLsvf5aaxYu=waClsmrBrD_(Ufa`aqao9nYmW{^PA6{%$M!X5R1a=(mo#efq%}EzhrUKmtQ-N@k7aY}yd^U+MLI+Tzydr$q( z0XQ(D7yO^vhpb3jyAFJC_?h0!->vZDxVmHYC?P03e~@?&o`m7&y=RP=C?XKW9s*JL zhyUvR6H8Bn@~r0z_!9|_d{vy=b|(yBC-S)6x-!r|i*L;h&)=kMsy2~FZEyKiMRGc0 z9(4zxT35F-7zpW;cLYiil(**28W>4*jwC{tW+{?bud`ZI@r)1ACdz9<_CZR9X6`dG zot+DrPOOulya@YYGSu^j@aVFaTM+5$F$W`3$7+c5X)Q&Qp}wxRV?xySwoB^dl3qN5 zq;(`6oRpt#J2)v*7ap9B;$}v(Y@M8hyl3T_RwR~vldx(2`KQYcPun*OL`js5BKv*N zJUxk^$Z1O%E0=A#4lnSu6ie?L;HK*r&eLzQ>zQX9mo>bpaCLZDPHaau zs=F$`e2tqw_vg&+CEuRv5OEh8&gKzI&IDB$ey&}8!^tGHsXjase!gA9u{?*kZ|~}M z4P65Mi0wZ-Tz87H6SaXZE?L>S{Np)|cU>n}xVp0|l{dPLit>MBLuWqZh3ozcy+p9-GH;01$+OvKz;S0Q zZb$672GB5lbm7+eYVJ9!ERh0M4|zFVi++=mE2dUpfbj|En>t)9 z=){}%j^smpB4Q5XM{**tqzAH7!{MLdq!{%*6n^0#|++Xz?b zhL@}|uI*7>NcY;#RA?iPY7wYJ2Luf%t1QZa&lbthi`>WQP2Si-p8P86%acWgOAXXu z+IwyqBIW)XM1q|F{`_RlPyToSe?H_%>SK+v>;6WNA*0yhm#w`20Tt0kC`zasv9GF( z)K~8VxkN#KZyRfBf=vD?_@Zvi=%{(C7=KAhss?EhE$i}fj-};9WTNm*t{N(Z;}Y)R z&ttsFT>gapvf+?nW_Z(XKXPVreb27uqPr!9DpGS6A?W)etx)q0MJAnu{`e$Na3?5W z|707_Qt?fgH`%4HuFw81Csm8v1*74B;8yI3`1#{|ynP_Tdz0m;A8GRt?IuH=E`@Oa zwcZg<+iWN+11>lO;X*eB=eM`r4t)6UjidBUerbQM|I2xYD82qh$o`+M-~%dnhF{Rv zkK{IXaDuXP2lq9FL$x6VOq;m(sC=70YXMK4s*Q(e&$)#hrypznt9MWC0p zZnK99es$Y{6I$5z$9wAPx|aHP>PPADY<_%%|3<*H)Xz9x*u_a0r!zF+TeBIjKMkq* zH=8_KZSvzca#E-oQgc>Tb>B#GI`j4(+`(n4jeV3I$^L?nB-zy~Gpd5Of-2>IvS*D| z(2-lLJL{4TFZ~_;d!W+-h;SxXp!nA3az%G-QSX%4+4Htpq8EH%GN`ODui==Ch9ZLb zZ8Akx?LCKBKl2Iz{ske#FI=d@OSk%o>%I*dJIn+ z?1}KA%Qx$Z??ZUrYN@C4wB4SFQ?uOD6W>t;mhZ6Cqj+l6Q@Hkel&yd`85H$yJRw*i zujML?)*77mz1I)q^`01;Tj^w(uTKB|3=;VK&%SY)7L@*J`vN`X2P$m!;fUwl8OLbl zna5IF^6zQc0u(8P6%!lYQwyB}Fn*3pNU0qw`V$}NKTC_sg zdjZmN$*L9;L&ho=ItA1D=Ti`so8}yZbG~}@K+btroYSn|*Nd$24XqS>@z1QmEoCPh zQ{*fXIv>Ddi}NdX&j*VyZ!{S2rB3tGK^7Bl`hhTT{`nV~+RGebV$=`>W)Sbyr&#oo{x*JU zXz6g?hcp~rv$vZ)5~Zewm@v{Uens`FvzuRMq^RLk)p;ViQc*)6 zzq-hfhJ3#|Qah+R8sYIUPVKpvp^8#N8n<7O2Hn#=&(9<$>~~8g?AP`A7PI_UXZW+c ziHU&yrcH+ZM$ZBt$x!X5w%om8Z$Xwf#3fC4NuPX0QeT&Jg-d!%Nu5Y)E%Bhw(3cP7 z+>e`Op7G~(K5rBRrm#_BYk1U5XZUM*UtL8lq+xyF*fl8tEG&tR=BTOwJbG=()c9w;bRc|O#}&wA$G?AsaSoKfHvh7Qsnwwv>BZqY&*4cn zmr7p(PeASpY;VcAd;rW!Y2owpm5m0mX%r)~ic9y2) zq+K#p`HAsNbPwFnrV6wsL*G`weD^);n9o;hx7hJQv*6KGz#~-w*k_WVIium7&d)eH^svr!m_Okl zbhznC=rC&ffpjq5ksE10@A?e~(8Cx=cJh9y8(MRblOI2((F5fNQw;Mj)@4SfOksHss>~OG4*rJ%zKVTHQ-Nr%uNgMs^V89~24ds;sm5%)>qR8Q zhK&?xQpUQL^X_%0d5&AV8)bSIljK6fNl2o*#`bodeU;7nwM#{v*xt_7=h+dF)A%SA zAS`B%*&Hq%(^LS=g+1XfR$;y};0yR<$eW|^+g#pVu}l7;y<{5*?Y#7+Vz1|^vzBx`n5~i z?vgH5-AhPfu%(T?!mQ>GZ^a7-68FSrE_L*k^NG)&Q&hf-bxLQh)9Vev@^#0%MijRZt%v7mBDDGo1~d!CTggR)1ZkcK355Qz(leECTs5*gj5Z<|u|Eoe$c4K?Hl$zb29Vo=muJZV*=WwsXD{G|=-X@2Q=uWV*%b0eM zb4Sb+mwwhwhS4oDDH%vW<2`)^3jG-_f%Ui`^y<(mu?CZAVlDh!{q0~tW9KZ_8~wh| z%cC(`u{d;5&|2WVSy~8PMcxpOC#x!(c3Fan#`K=47?I&ZlvOuVBy;u&{PV{((`Sfq z4!Z3&Pu$8y2cub$nuRP(POa#0vW+tl(%cSn%x_Mxd zutfV#ridSw=)}J1utbTt7TuHUvFWh`t`o+1sjJq0+!;kj4YE>>EuHlZsH;X9#=T!& z?%7`3_k<2!ErKo!k9bGWIK*bn4(}P4pYS;>z3O`MiI2TKzXpa(aro#+hEVB~EyUq# z`_vFfMa&&24wrC$w09FVde^aTvP}P8e7Rd!|4ZVHI~4ICr5j(@9F%@O>5OXdiI@d) zei!|Y`t83@Klu##3mGjqSWno3fki}-7950Xh!nAY`}dX{QLTq+_J%0N^=;)GY$pEC z*Z!c$@y=iq-M?`w66YMJPt9|-8#SkV1~qqG8&I?Vqphg9bp+I$`KK1t%u(fsq~^Ly zq2{ls5&iui&E#y@+)4tr9*MuV!+hU461n6eQxA0X`yIISHb46=%`khEqgLzd|mtSt6!xB(j#n> zw-88NkLKo*-~Ecp{vUI10$ycx^?fIhKm@`GLNo|S(5S&NQPD)8CJK52iAF_5!Iq*T zwQ5lkpan6Q1WCiuRIRnu_OU*;+SU$Mi=b8$vaj4#>2P;kpIOO~N*S_yF zWI~_sd9U~7y2!bwz4w~-+H0@9_S(r~$;GEajgNnuqJ0`wQ@7eDd_Gh;6u*P)>tVJa z-;HT)WDRc&TgY3dWD)m}dL*gLGzdS$xqV4gED5H8h+j(k<7Lgp@?c z*ngq=*BE=y^<~U4N*I7icN}W`H~ipmaiu2am=@)jS$?lREBzw0{Kt0jx6myux}dRq z8?3iizxi)o5vK-+n{r}>_2UQVh2}$3IDP>If&I#RyLBH~oeem?6d~kX6J`P?$8G#b zBCXwVI~j?}U_8cqsBx*DHnuOi1}qnSD_lA^Ytf~`%nYg`Fgu5U8*j&N9A?-uL`gA! zD4mqG80Q@Ou0`k3f1@XG*g^WUjDH^ri7anu90T7ug`8@LP}?^DEP2I-!6k1q4DK*T zmbewk+&+#57pg&2yYCzsdvv@X!q8wMutkR`Kcu4MKiF!uolb3{&t2~6i|%Q*+E~V; zE<3D~#9yuINfMhAzB%bQ_1}3VzU%=}a%|KaBQ?JwtcK`zWNBI!D9eQ$7NzY{-(%m| zL{^5}v7MWa{WMUeUH&@#QAdqF48|@~9o44)K54TRv$N&OQ2x{G8xO)r?eEnK2wRl% zcTKl%T!ldMY%M2WvmY|IeK>m*`|=0}PGrQ8JshES*1tcMGugLA4`LTyNJZR}4!F$J zF;OrYxfgyY&b;VZod!~)-w~bZ=bdh_XzbcJl!f%J$YuKV(?>fs6Z>_7RGsuIy*02; zj6TF|G?*zUU)3c+pkUjce)2gEL%zdh^S&VmHiv#^w0Kv^vFoP1W`Iyxo_FEV+6*gW zqx89XBW)M#^eoc4f_yt)2YbND zzrS?-OhFfZnU~K-{QpR)j#52~^{o}1=o5V>p-mlqz60ld9wgBx;e^ORj&VYKlfV0i z8tyfo~B@Y^-oSh|6Fhu3@CQxu5?vxe%x(Hf`8sl zQg@MjMyDlsm5}PhmE+&+6#mKm?|cq%?cKag(@|F7Z9d8fcZisU$d*~)l2WBgp>z1h zrqJ^3d>ZWUVeeIF`4cJ|$(+NX9bW7g&_hzM(u`acQzhml)Emh@;sAPT>AKqa4Y-ZA zs^5pbv6Cf#wjv=ulJ-e=D5%Lyk;cEPAp*a_U~lkdjdT8~%4kb<(n#)0xvFu4(t6NH zL)t1EyZnAM;?#$AtZ;VTHK?W!X9HJc#L@0iCXdYj?`^Z^nJ;cK24BA&`Y)Sq3~qCe zF4m)3_vm--(aCx=(>=P&JsP4%XY;5d@%giip`EvXdfjjpLIm`sV5=&(*IKOwwaIr)`F=@$Q*xd_7ZgB|Wu45^0Ruwkpy|6fB`S&xJeHHY|u ziKuvQo(UWrb!1aQDdGUD%=H@#g?s7i=*NYe|AyRr^an%ruipmM2WA0saqr~BbOCycggdw4~*0$J4}VKlHfY!-4^GiJQ5qAgHn!dHU2!} zA45bwO73kj1xwy#!G~*P!DnHUEck0HoBrl)4k^#3t3tLYhVR`jsEc~*C=W5@I-ERO zp;|;>rmM^Q-?Mt4PrS1Zv6l@O*h{M<9++QyxMIMZk{)Zuzbjn4ZIw+Zmpmh^uqK1A zs9cp6w|gf~RP*=>#k>WIRuh6IKPa49j00DdckCHr8W;vaXa4g$4r72NHlIUc@r$Vi z=X4!hKYp(#ix~e|O~C?%*`1f=t@|6b=ste_``oM;Hfn$@4ovAF0CCP+@8#1}z^~N* zY}M_6$RbLBlp{tEwC$=2;;g$4v9^fqfEbC2996v23mr}7h$d45;Jl;laRwoF(+jk6 zM)_6&Lfqjx{YJ*G9!!SX9InkDsYE7IDLW8llq(WiWqMZPLR#1nz&Wa+o1O-6=0_Uv8|1#Tr;UHs zQ-7wAJC)67%oHyANFD(jDViru71a~Q1eNU`R7 zGkUCE@5K)s6PmyO2QkZtVeW#i+P~tjwEqS@)Y`wTtM+LwOQMlus=)ixuRFMm`Aw>{n+swx$Z+=rO!K%&+#_o zVz0oU^IycA4yHwA$u~zO-CVbaqM7s0+h?s$Nfj`^N-CRqeDckR_)UC&#NKT3YEv$? z@{D;W0P-H>`-{wZ!`O`p^yCk@=@Qq%)ti&xo|AktEq)X7<4^XVzmT#y^G^&~s9*hl zJOaSg+Sk?EH(oaRJ;7e@(7*lC90(O^e3^T%JfHlp$QS0bIHJB2eUcXtV9h2UJng^O zi@E-T1n{gZg`07eZ`=f`h+D1-S2 zm4+IhmdJDLnReK*y{@dTok+3Y@sN#Wr;~qn`^fUT-7Mkomo=P9@QR(JC$;SF=K4sk zfs*Tz*uh*MP`jT!-yi+QEwN*E%fUXa4SlGbn$(2C$L1BqPS%s! z$D0e}kKT4aw2HI;Kx6+f?H7}NJ*qqYSG%CR1ph6*&+(tj6#iR$pW{ET0{&O`#Q*PY z22JtJrCgJb`lh z`R7o`x4%rGqn{T!$1UpG)&!cI(X^Z4TeW-7oT6$g<(*@7d2g@zgbVCVXB~u5uW(t8 z)|vM9Qq(24v+zBS;6B5D%`LIsbYlwh8rO7iPCKSiet5qR;xkNq%s=#k<0A^KA~nb?yFXpl_BY5R}Q2Q9Hy| z^9ubX#WZb^E0fuirDa8y9eFc|UgA!i-!~@KFw{1$2J0K%wWQ6J$Yfb84e}2`0Kd{D}P>w&CPTg<``5s%6%BQT_kw!m?T-?eP5ffak2kI>Tmt~Ou zhrzTqH^H*t^Fd_^D(q7Z9rySvd4q@a6I$|qi_w$BLu(&-)O)C07-fEv()}F&=KB0A zQ@5KPUvZit0j*Z;Qx$JR?)-u8VVFf*ow}iuqByMG_{3s{7cu!hf;Mh>EGg*JUbZ~5- zZ(k5w0>fbH2U}5J<(`K2O2s0{PIiDr(4lU-r(&5bq+#v_WmFoI(n-w6jL}2z!wTh zA(GJxtkEBLaZW(e`ffD4E4+7|2;Lhf^oaKdclCt#kWQMx4P*}gHUHcAk2U;5IoXSz zz{?yucHO+bqQ-{Uzz;&x+w3wNdhFk)CVI^YIwRKg8lOO~kFfQ>fib} zPOeDiqr>Sy=QgJ(nSb=^icmV=*;|IYw+AKjs~`77s8}kY9DP3fU!YIV`eo)m^vh|| zFO8cP^&_K#==3ZHM>K7ye*XSGBhPo-xdcfqft@A*ucef^Eql!%X# zI~KD8oi3e%;W9)1KP3=wXT9FBCtn`SAH4>Sz6bOB55OyCLG`<{Z4yZ`9z5vyd-YuX zV}^T)LqzyBtgpR7CK$DA;}I%w%?v)Y(eufC6$wpTgGHKM%i05zA#7-pU683FH@?4U zU@ZrX@d}mDPqfD>qrJ+48AiWha!b}fqxdVod@t8tm&0_ttoL-H9BX}2s1FT=d6mmj z)WuJ-x?UE;(EN40s-P3bd&{%_Ot4F3uvYEJE8kZv&lr)7n5R)=zkWq0DM^~Z%tbdc2?$^2CwbeM3HqeHG( z6v=*iP@E13OAt2nU&lg+?|rRDI^6Zc9_WDleyRLGiig-YeI&)irppv#k|R@$7&K>! zxjo*Mp(lICWQAnZ_N@#()jO7}uQU1X(%yd5=hYOcxO8hp>DHQokK|(i#Zk68!)~{Y9DiZ57dtSK9IUVI|Tj#In}-befOJR2;DH{L|-!M zV9NEumDoF0#5L(|ZiQ|fnAbaowJeJ+a{}KfG!Tct06@{UzygGXg_n5ub=N4+Y`ZA|GKpY ziX-25b*6cO`T_ly?5qE~71B-;C9x~b^!{{0nq0CZ%$}Tux?Z= z@uxKqPn%C9o+hZ;=ZXWwTS%@sUw?Ktee_=bK@T`aOS>@*4Na%tmL>3GYDI*)MxAQ0 zdA4TAGu+aezq_a028Z%h`4p-OP2^~Kx#txJh<9zUkK=@`h9jdAEi97srW!TLa& zlaxg;Aa3czDzwHX`~~}B)UiEcP~8Ov|EKtK-HR?L?r)(=gP zWr+CVt5gT9ZP@ojOt39#ih7%B)Rx`V4eRxPCox_&e$lXtjHpvQlUZ)=`_4o6@9TT}+jG2l8yyk;07r zKU*E7ng#f`NdHs5Y7~!?7T}+_mIe4LT3LXqf}GMu(KxTxaqC)z#2lSwZ`nlx@4O!#B4V11p^%K5 zut@7K3l9^igu;^7w>!St0zP#p)+ZkKA|`)3VDcFo#pJ-n80YhGJofqgL_wXk?^r#P zS#P<8awV~P<99|VKK4m?y<&vGlfP-lui^FmCkiG<6z?ZbICkIEJ-Z(zsJnZ1bCg%A z&$sjVC#m;!Xv+9tLxT+xzMHuyHGGAq%vG|kBjwz)qE}JubU~T#9X3h`F}~RVU_Mnn z9!S`Yh@GeJm%QQp!@N*gK1J_7%e*exeoLriT*&*-Pk;D+Ph{A?3+)?>|Az;nU%!J< zQBgW*9mcOkQc7k7+IAM3xIN-?HW9|-ot*EmEfEvSgiKgi78bLA?bCy$(1asZLOzSz zYT9nX;RFboB{b|5y@C+R-P+Wze*7D&i3=nCmt|1kmS?Ja8oiGv zWpDRFczZWO=*B-K@#}dER~Vleqgb?L%oti3Iqg5PFDvSIr_VcF&uRumZ3_t5ca@=! z?uwb~a%B+ILzawh+q7B&+jlOT%Lm7LCuPW}ImjDiJNW_w&Eijj@!mvWw^l#~yd>2m zyRS>T!Gu(E;Yj8i{mehO@VhA!+7)a==sdO9lF!uQp`xBFU2oG(J<<1(9_TyoJ3eg- z{RL=d0=e4#6fRjN|9WpA# zUnSrR*2gR>$hmPMwtb;sv^@jovpjrvDuxx&YEZvD;Q)J4i6aaVCj+yI7% z*)1BdRgbqG_pJBUUc{D~4Sj0fN?Y+yP^VXUZ}6GE_ycc3kA~STa1Pr+h-4T}Dzhi- zR2#df7Cj<&+XE*1gcfVGRyN*y^c%^1W&H3oi+lH8u)PZY3qPl(4ZyAy*xp_{(ke}( zQoG3UYuAIvfS#aA_SEy8FWN|tt{QQ*@e)i7&w$OKEc*GAj-&!fB+Qz3;3HfE88K(^t zW%!4UChjY6oA4I6LH`8-_&Os&6W$61^kT#W^Zf!2Ty!k&#HKq12~(OD`@P$O<6-piEF#~)8ysXltMh@` zm{G)qq+1VS7$SZe*GT5Bv0}0JUWIf)klfX80i$_?S|CnXErH{VH-)3)nY6Z#h}dv^ z`I0x)dP~5LR*q(hO@eW=VccKRYqHASK~8zRB+CCs=%#Aq zq-u1ms%dM*C)+C8{?)sp?bB1MM*ZXL$nfKIx|3!Amh50+@%o9y?@lakj}4pDH09K+ z3T3KwU{^K06M%>VDs;1U@Ki;vNT1w12*h zV#B+&Y>?JzM72j4@wV#&^_-nth>Ci!N+MnUXDUx4wzg?EM}h|ua_=d_ZU2PP)YTuS zA!ghh9pfYsgP@@|L{Ntq1m)yv2nHwtWi_YSz^6Jcyj>?noz*nt)cWxwSDCD&BM+0B zr=QCCy)6G)QVh0I`bC0jquWrTP`mp0S>>OsPOB>q{ZI)-p%xovf?#Y#j)5oC$5DL1YPhmVP-pHiuu^?#fqEqWUIJ zzj2it88Kn8?N=F5O4R)B6F%Yec2A1swWkJvIo?Yw) zM4Q0Rh%RKcK6OY+xvRwgaHkubmf}vffpE!=?Z7UIg^gl?$Rr)>mxy0Yj6ZD_AEjZd z`aoMuk$#co8ESZx`glB~W!LKTnkmYm9=YJXkRLyrHGdomY4g+htqT34)XYs3e%uTG0)tnJ}^twK?8h6$9Dc(i2 zc;5-lr)5>9v!>W!!-Mb8yWN+NH$^2B1h+=wpV& z2iG?7hMZvDY|o9Mvf)zkadLPgVz?_&}nHeN+(AWonep zW2|dlq*)qn0f)bo&VtI)HH&MjA_IylHb!-R6Q{G)iOo1W=V)(I9TikChL<-FAB251 z4F9rs(uXoK-2rpjcp2s{zwZ?M%!CAO?f6U!wDXJ_Pu8)xBa0|RU zwX_aJeR{`b)8sF~pJt0hboNm<#Gk$IPbT`GNG+(xZs$kynSh~5QqrOQpIdy>)k)H& z4O_%dct857&W>59%jH}mREbzDOegP??O=o9EPyfvNwVNOQ93X-@0#+mQfQ(SX zjXY%kV0z8@aYM50J%-h+`Cnrj!qct!7yxuRP6ZB!V;pK1E@Le!Lh8+<_*+d_P$WF3 zg_svTV!J+niHqgM0R9%m`jClJ{hRsG{>?+Zj|lVgLhr*vn_egjUB@eDHy`EWk`?8^ zreOa;a{Q+ce+|*wTL1f08zUl<+v(2PiCV+$>uGt>VWAZ#W|h@_acpg-y8i)OPUEuu z+1Nk1yrgz3`#WNr&2lW=eBJQy=;ud}gEIxlYG^l-F^M|;8J_CtM($6Vl z`EGbkio)$lvfscXb?dlh8P2dJ{p3pnpF&^cVQ8pv1z&o_Qd`YRP%j@00$r!_ks8G+ z$15qpmb1i%=2JmkxSsTc9r+cGJYt37P>>%XQS@_P{+&B!Uqw65Z~h#V4?3OX&)der z$*MyHX<{;2ax#<2Hy*J0_rm=E*yi64-NCqj6|N}b?;MSm3y4pe@3=h2bV+o12S0)F zcZ%P)lKcaM;`2j10p0}yVq_{14Tp`8{WJ|Qyj@uV5JwA$cW_-hAw$3V?PtYqPe@hb zs=M}6k|ugvSe@uNqke0GwZH9t+MgG1|G^*9{uN2>-!;$S-$VPMrT2hZf(Ev6fPsB* z?Nklw8q@nG&u6gGie|CzvrqA+;$6&T!jTg><8$-ekx17+1Bc4Cm#uHKDtWK(P%(RM zqt`@4iI*XaMx;`7Z60jxFMNL4H=yU=ZwH?r9URb8OwIAu*7`V!r#aD*?z^vx@9l!W zgKPVR9_7Ft^YnQ0Sle2ap9;;kLZk1(Ujokoad;{PPv1B^#6JhH^uXT>6SNIx{DW&l zw150zZYm^qllMLWtE)z(0x|AbNV5AEfN)!%fF$d01B3=V=1#=CRZ2z6Ae^)DqxXv+1^%yXJD>_a)+cRgbsQ_?%gI>+=CD*?mXrg``2geX%m_d^T%f!@EC9tjAOIqE zOTZZa*YW2lW(PhDvzwQEKZt`wDoEcU7YC8Jj>dNK}9RbexQc)T%s`XF-ndbr*jmB^= zXrVbWW|XRqWM6zOQ=FH6B9l3Hpli+TUQcR~;wLP@1$@?}nzgb1fdBv3%+Qp7)RcR6 z&GDKMWoGNEbyxBgh|eJZ>U2G414~Zk#ayw$fDoh1Z@9}mE-!PJh5FuROw|n6?Zvyw zn|3<;V_WoN`Zoy6xSdhnR90BNw(MwV37HlZENH$k2Sat>w>I6Do|az!!I91^Y;0Zp zZh2ER88F5Q%$l5v=ISCZht+RO%B6!e7vNitWRCxt5oODp5G9g*_8d`UOjZ#TdHTmj zkhm%kOI5qz-*1`PRnIz`vg- z9Ewz5iSp)75MBVCy0s`r4HN=*I`$CzFFCqfT_+Zjh`5(tABR$&%WpOHX2a>BJAr*b zSFoSl8TRO^Yo@()nDpfQIr9+~fQM2PXUjTP6O?o6Y!Ra_w>NZ5&Ml+&I~=%_3|~ zpgV11sKC_~>l?0Lo2S#5O8*wR`6m=%{vo&VQg^PFEt9huMzhqgW}+*t62;?WD>46`vMhHKIpVL}!XyIQna2PSl^LJ(745X)oLYQGM$%I2#IX0xoVNwUDH zD%~5pSt-XSM=}l!6TMsdm(bE*AYwWJwvOjQbAbqXCpQ(50rlZa_nQ>S7}esv_b=E^ zGafGlzOeN6_Ojd=i`eh$is%^BI^J0SvP9N;VwJVy?9>$fI8bE5zjb#dI&4mb9;Z;G z3k-1nRy4I$DD6)QS)qlF^N!?WIEU&ryRUS6iX6SQ(P)`Hbkv<38SuD|k5IgaS1sOw zK3>K(1fsE=$}Gm{ZYNqRGTq#Nl%7Lh)fjF!zekHMOJ8A$9k|wU!yXp@D)3~M;2riJ zCT5_1{Db$&uSZvQIVgyK<1B5eoU(PdcdadtyBB_D5#B2^AxHb_q}H88jp*0TZ`O4E z74+{m9wsR(Z}PX3yBYD%Zk`_Wr;fjFe19Lfef^7ivSoDE$o=_ssNrs2mo>Dr5a|}7 zYZqv#cJ4ubk`0cMqcp$d^jGWAx0XIg{R{saW`K0MS9A}kvXoAYi79L1I4ZKV za_-+TgXREK4nO6wO^0QdvsmlRucDw`(#Dldrf5#TLmHg?kAuM%{rxTj@9(EE7OgGI zI#2*bvQK=Ev5PR#l=BJt_vXX5_fH|3Y51~bi->?2aAh+2oSI+3izp#NUCqHSt86~; zFm~It8~K*(D4`=&HP6bgYJ98qGAXY@@0D*!FIm2%AqAC9m$5r`DeG`rrDi}FQV@># zjxEN8tTl{uz;5H6)IC=WhT125D`i}TVZpfM88vmu(>fwo{wW=iTYIyP$BivZVzT4! z^9lauv8gE-v)``WvfdjL-9Ps6ZoP>3K!9qr%PS zlyFs|?Ox}UaaE?oh84tqO%CfEKh9Y(7e=1e1Z6M-U5+*IsW*xc?X1>v*&QZGBGkZBpm?Lvtma--Ve%n2cALP5QZtzq~wLR zV7&QPTEN0Tbf=3PRrvpg_*Bw+t8d&6T6KjFVe~uF?2)U;YZ+`mZ*eCZU(E|U+4!;! z;Jf+ZQ9k@x0sKb^ezXX>>#hxE-Qd^p<|Nvj7_=FCQVr&rbf7?yj%VVu(S^|`em+r9 z{}|Pe9)q`2>5htL-{8H!%6cK>_xdDS+BVC_F7}98Dzuhbt)<7PUyuj24ppt}-&(+t zXg_Rq`Bl8f`#>m_%(0Sxw~|}pFn$I29{PS9zFDf&gv1;BmEmhH%VEX7#fNX$mw<1Q z&!4;i)5*e=t@`~)iwXVLjC9bBwqj98F5q|zpO|3u=)f4L!5pWihg4| z(a$2BA>MgexPqJMer0LiwBLw~ulkf^BI1a7SptI6I0UyQX!$dv<(So}s<0OAs{H?47YY6_L*L|*_%Ii5Pw_jXEAiuZ(h^gk zsf_uuU}xL!-34>(SDtfbClAA;B_SPzK;*GpqD+~tA(<)uo_fPuKXo# znqV^l;?w?ud{LR^2k|%odH+4t9=Ty>k_Z2#MzN6 zAKs+#wtB;shb7O5cAB(~>!me|P!5446budOqsvyi?5oQSc6laB9Q|Th;*`P^`0IEP zjx<<%-bM5fon51-kod!lr)32DG>UUXU&I<(HJKnL{Z}&D8^P?ZA zP7@3_J zJDHk<8s64?L=#;>-$GHDSu=$GR0Yc{)00T%Up_pD7axW(T?M!I(uHz)1!3a0;Zar4 z+h#~^RLYh%C_3p!`QUkXK^@P;$gng+HOcx2xnC2(S2>z({Hn`+Al&$>I>ENM?Pq4Y zck$Pg`?kK#i>`@JdSo#_;QR;Uvi(WUk{ynGj(;MjCs>&N?zZ1Y3esSuEmjLNTl*S%Sd~nQTPbae)=X`+ z`T$viitp4bS_|uRp26jz$F}cx-GGXwy_Jy>`Ko@hOZg$UbdaCFQxjIT@+smRa57XO zr^0JNe+$~H(ww(0OElp19-I$e!9BYO@MM1~f;~%bs0GBO6DlK<+FJqxwnFQ7H~qA~ z%8KLUqgs`(!{*ni1f5hR2*U(vVHR4U6ZFz+MwTtBDPTiK>gi(MHD@r1Utw?DbiJjl zq`2nLvW8tX16RTmEqIG}bl$b(1wm4Sdz5}~Ndvv-b8J2Ng;1=%8>e}{*c83s*jr3` z@xlllda|E3=#jk#{T4iXsvl7wBok9{|JkMen5Wk7<*55b$;CO#9mTf5k9}Uyq88>K z&0lN!cAwAt$IjP_P-8zU>jwrY^~HFVu(pGTPYq7A?LQ+IhTrzH%(TTbCqAU7Dr5ZH zc>R7pF=G7}`@TYrfl1`pZ~ket(^pxJ6XdwsUPT?;gLr@T2^GlwY4*eh=jb`Q`Nu z<@al8A*VxYZN{vYh3xY_c71KHg^EWxDPZ(5{zD(=gDnF@9GMWeZCxP*upyaFP6!+_ zIThLx-D*%->Z4F&m3b%JN5Y2xIAj8pz{sz}$7m20U6j~Yt*ym5p~mMj9Z7tY22sgH zSw3F979I$Qn+!kUbxMF&u|4j!(8uc#Za2(}<29Ju)d608w80qp$Dee*RVyNiSlhZH zmL4V%>y<>MBGz+3r78U;=s*Nzg>6;J*Y<&u_Vu?^n~*eR>m3az8@AQXkZN<<-dE|; zpWd-88eDBYqflnB;+24~|J*KQGts>}HRO*}DPa8&mNsk)HQpl|rBexk z_V7H~P9DhQ)L*fZktWl7^k;h4D(_rbmM)H{84-`N3pc&&X9HsuHa{Gius1f46)Xa9 zh|#fM*@Pt;G?zi9xcSsU_d5z4(-jm&4vONAP>ilQSWuKVZA1ZAG;Q+1DBsnVUm2RP zDV8&l006`+7$z9!X2r(HR4a?yZ5@E| ziZ%b2CA&sIv>4|0{rj-cJ0V8wRAcKt1`|5#f{rM7QzNRlTd6M9>n|zQ9Y%G{5vKZS zY_UFUi8QredBc{gcI^rxy6@(j46D>n#PvDeZ9dZ;&=)Z69{VMdtxKj^jnXgPw2s`f z3J@8qfU0MEcYX{AI?@$4b%Kq_LojGmC!*uuARO177eZoRoB2vkQ`r8v_$Q z?e||``R2$Q2^IOv8=}A1`0013Vg*&Sm_OB=?l$p~R?k<|ZlPvMMc$_BPV+GJqI@j` z6l!oRihhS!$_`#6`FBD~hxdxFKjo>JLN!z5dH?{=#tNySBg3PUYq( zmp$5F_%n@eob57CY2@Pj3)^BNxjiV_ehCqIjx_*y|loI_4mzy>i-&^Z0hHh`lArlrh(MY9>(6`=99vWyIlSK z%==(|DVxYVPF27vKUL?J^VG77U$OQNwe|rroMHR z)MRmM(hW@BvJr{8wk)NKJ=hwTLwa-|^UuG7INbk<^^|*5YHVt$d0m#eL#3{DrLI(| z%+yk4U6z`mQe!E#FVVa3tbK|ed0#q;o=Kwl7ccOgmq?s{1Sq}S-^PPiz?m)n_8rE3 zbsmjOjQ50aO32G3xM@9qtX)a2Sj>9%~m$3|rrB{~z zbMZiJ86%qi)t2b=px#*TO7?G+Zdp7}71XKL$ngCYOCkEQPYWY0`d2+p-=xpjAYDeB z()*Q7TdJB?6T0VB+bqdP3CJu|pOILg%L<=izYaAWRU%Y{f$ERlh*>3?sJ{g#ag?z+ zW0TeYir>V$Hudqr!@LsGRgvN6YA`lRe#K_l-|)}tZ;o;%O8cb9xM6ZPo)sBBtST~X zXL%^6Z+U1?FZVMsjr-o*Pb5~1EjvKUjd>w+xb`pe?efeV1z(7PRZVZ=ySaf_$W766 zxvwmJCA9RvP^M?&-mAd9cUGiea1}1FoU>t)%ucZ^IQ5>CdR%8IRR0s!tr|mo|GKAlAH&C#b%58vLT&L@LySwhK z>zyKFGof$p6H!wb%JR;#-{sc6(8{y>M+^jctqQph4FX2Ws!F9SHWH~$-Q-s`t;U)! zw{806p}X0_){$58J?~RaKyPBxvyvAvJ(%B5Y~cKg!%!YZ+7kgrbYUkQ6FGHu}CqgMJk_Vwc@GhV~ntSEGpPA9z_wk6CBG z_nCiKp*pR0|Dc-|L^9{@K8VjYSF(pAEYl#8`Awb(ZG9MyEH{dKN9*1Hj6jYs;)#Jm z%?4Vt4^p!OMX^3=F*?BD-|n44KuRSE(vP>_?cS08{UQ8Tp)V>*H-{q2KNYfQ)2gOd zV_%;X$)Ky0NzCG1#d?7H#6EjUnncC*lrnlsAPgxzCVOJ>TOq~&MV0l&c>4o{{Om{p ze0@uNJ=Etbzc=L5cMnbNG_Id?WNTIA+XzZDv~(Pm37^^Y7-~?D8N%vxuWc&Tm6l2AGHTkZZn8?x1D%;_7+JmX_6Uwo?0GVE0A zEGOy-BJDnKoyF#VpMFgpCKznGr;D|Oumyuoi&~a*Sn+uG*o_Yc9mRDZ2TpXL-%$n; z$)b+3pZ$7Xx_`fiSdM*JK<7`~rvaIc&d< z9#u_GSB(C!f_x95hOokueEWi3)>WfjehR&;C33PgdPHvt!SLdWjWN0z5h+_2_pc&2 zWc2gc39$kE(H%85eH7R&GCSs2dx5>;=r0aG07+x#eHqSZpiDLgRHL+*Fsg(Zs!8i2 zzNS!w){MA*t}1;qbaMq?o*fxCykg^fRii(zh+N+ue;+R06IwdTRL50Uv!(D~85I%E zXwpDm5n%@mYHVj!@VBc1iZeKj3s?@t)(O8vDZ&wlD81B-} z>%Qwb20KwnFcu)hUF(OXZ(n~wMd^#zpCg;Hs%d)#TR3{r?E;>6FGhhi*|Bz4vFxLN zUq7U(G`g5*EPSJ~RXy*1mLHSM&E4Kf3PEYw?Hy~OD1kC@ohg8rbc6y&`a`RZb&fuq z@)EjvInNkK`h-i{LQ5Y-*w{LY@mwYo1W{m&#KNm`wg@7z4c40&_$Ej<2A;2<*N2u) zx6w*_>gjNQpkd^#;{SDdBW^VC^Eqlo*>eI%A2AHV?RYu0@i!tlj0_)1x7p5$|44-t zsLNnU^b(!;RafMvEZOo-S9fv4`=H)|LBU6-=P1liOc?-E6u$vW4iwKK)fipl$}AN{ zB!l+Kaw;PO_^rsVj0_n`TQ;!!Jh2Y%>UZX{3>KE8LQDS){r!R%g9{hf_;v~th`aV31ucnZT;LTeIPsgo{;08BX+ik}e!XM)lV~i}xJdK^Qj55tZPO2Jp_`XM zo5_)kETYwo-j7ILefejG`hWlqi!eTiZpLO?ht>)dL)J0mXqNwZG%ktEqC=C^4L zuBmpW=b=a-|IjaF@_$A;HO}*cN(K{DLiF-Des4hj2WZlnu0hTXeSLK4hQ9cm$XNRn zFjEY`ZYZiBe|@b<|2R3Nlcau~K0-!J+I=feI@5YVBy)C5(*GQh48+He9pmJmXI;y` z-a{;_tA~DIb^CK0QC`GVKM*Xb^6!NekrM3R8tZPn6ZrLx<l9l?sMZ`?_2M8H-d!LMic%l)t- zw{p(3x?=RsiqRXDhi$K1RwY%XZ8hZrFz@;yN-eUbax_uTQ`ltF9{nNaT|?TW$cf|{ zeA$0qT{(J<9A0JePkexoRE=(n{V};@m<6TjLGQ{zMi{ry#aJ$qJ>~`dB|lDXPcsp% z161CbPS)7YwQ~;K<8JT{u+kE@&nin>LlHZEIx;TDjI~VQKp=~dvKyST9)glS7iDdO zM1DB^HQzL=vl^Y+c1^iqRV@Ynfyz?G&tLN(7&4_Y>c>BGodlQlqfo=arn=bzuQC*HO1OPcIOHd@0WjJkfd@{`?@u;St9{ zJdvcufl(3(te;?Z7G-y%3=*+j{;zf3FQ%D6LjSmnD@|{qv*@pZ5ZdZzA~uIjR`bOd zJxFGNxu!%FUtio~muKcwumzKDB8d|IRi&##kxZJ$blu-3gHje4Eys7~LrJn<>ZpXa zoz3iXz|_S(ynw~b-)&0xFt^MpE^|}&afjBApKxuQ{v(b4vIdb<)+%r^*bbpeG6RVI zr@SL=u}yQqP_fa!kSC)5oH+e=6*(o*N<+yks7|l|DG%_Dvmj3_VC_Rq$|$z2ShnRU z+9b22X*>HTFLtxO!TkEuTJb?%4l_{1iHrg{mJm{L0;?r(fz<(y_<{lB7Ie8WzTD$p z;3#Zgs|+iqtg%84tdxb3Ydv82$v6qm?b1nDk^ZV0l8&ykn*5oB&jQDfdw3)J7muTk z7f)s<^8cMU{f{u^y{MqbFIF9UxQ%5fX#ebHK^7y+tkX^wTqBiTbHmGi=Y}hb+)~=@3g^@L|&U> zSB0BL4Ev-Q5@iqP#{!{C=+wR%eQ{-(uK zgZ`QQ<6XsRmQLp=NdRJCc~rB%&tu!>xY>JjK3fP~SK*yHO%Yp-4ybI-zFHqO=U&54 ztdGMI^OC{6lC6<`y4ekY@7;dkKH26KS=!#7hSKQO$VQ5jMBHFn$HDc*>z__}<8H*Y zAmp9>a5|EY2olD?bt=LBT<_J*q$yHtyW8Nh&0^bM3aZlhywi=(OB2o)85eN_hr?4F z-nIup)PirVL^8kLNWT761?n8j&4Q^by*AYND?VORmQEC!i!LS?YkL)YCqLO*(YE{4 z^7`%R73u2|`4!SbjoJ)LSA5|@mgcThb=U-TJVSyaBaUqwp0+AaU!d2Wne<4(J={D0 z*riI;9xRq!lvO`|-M8uctU5LiqJMdJouf_XBr7`)GNxOF4_uS4Ku#gaBAE{)Q*y#% zVuQ6#N=^>{b<5K%3?W}`4`O*;$vk&@!mPE}kyVj%z-x2GC$CnJ&Y_&cXsXgT5RjT) zOHQH8ULd3K?a&VBe1o;dF46IdI-&CUl|qH7{UC2M%iA6B*nV{q9&5^arN?>)&}zdS z(2i;eHQvP~>FBC^mDhieK4DpPukOLt7Rt#Nz=O9B=>YVv2_@(n=!G*o(m!lK2lOA- z8ScVlxQ$-0vg=5YU<;!bjx1F)8y4-dkaDz6xh*AQB(^_Y!Cy3S4C)0MDcOaAj4}-@uWSEq zxn?416`={QvCsA~YEKJqeuFrIvhdLL;ZYmIrC(^vFBVp`LGLIwW5TlO1!qXdF)S%L zhMgi4MBZ=KL3O{|txyatM>S2#s~`Wf*%GguO0vXxb6LYizN(r|2ZqzI_RWHW)_(jp zwZa}6;4esPD63}2xoyEUeNCOhVtqI={06{z)dP}OcQPe=l}X<23Cj)=Spz*0^t#HX zSX75^IWo6#RmnEc%I2xqaf}#hK+ z+5x~hq2SE&y4^>`4l)dXz&zOI< z^cPp9^G`u4Gl;@P%EFE9q2=58q@wAsj4KtJ-zcwtW&?8kmUv$^w7qK7-m3lHU>kO{ zKXtZHzI^UM(ZeY*5gq?u<#nHD&Oa_${#5f3)GSM@y#B4%sBgXMqZZj8f5BHsCEpD- zzQIS8k@M24N;fXf4=t^xN+fhj@AUGzy+xsh^Q;f-EeAH_*=O^iG_V=6i*i zF6r3jPcM(RIk$70bsgF)qD}9)5gl+WWY763+wt9Lcw&CwP3zQXp*0%l$4@79!ZoWy zyDO_{_q>kn9@s6O-t>-m{^_zfp3R-xyYq@v+J@EMo5MTcdH<^J=(?a&dlM7w4eQ)q zVTbm%o=tmmJGOUnx9w$hYVV~>8Bm%nDU9eI`@P$lPUJ6`O;l6nFmabbg0`Msm1AGLu#yVWyni1+ zgJjKLe30}LS2>}ZCh*1v8`8fjJV%zj9c?oD#Ahv`$+{a@G}C@dd0S+ZSL=3acr@j0o zlX|hSGPcG~rAW5baTS%#8DCV4YGug#f{~}q%6y?Rb){*w21&i}Dv2EgR8IeCPrU|+ zk^uA;V9h6zz4mm};s_l$c;`?@Y-Thrh9O+vmamN5IIq?zo7en5ex}?8D^u#x2pq0E zC9Q@@5}{n{yoU(TBp9IVFNRptv*s=crw>`HAmY+BFuQ&&#Q$5D^^~s+NseY>v!vD* z`vbeAACowE|Dx9*dO;QinJ;->&JoF?F8uRaq9h4Roe>2y7x(MpH=m_WfBuT#Rm#4R z`-=KC!@u*#Nc`YDwuH06b5X$&_P5afmV{SLoB6G|mtR_QjLIDmUUl_1Yc8FgUxf8k zS#X?Sn8U>OV73Q_+x|nI-tn88$-A)P#FN=THsoaG`@&66kYvuHzpJ@0`7_SEBpjJu zaKx%n0LA$&=L)Imyg7Z88Ei9%mCqAlXIt9Fr;g_{9qPW-C2y#9aeEkHa<>{?b`$@j z0vKh13pPrsXCsT&&!@_vU~#N3vvO&4Sh6EuU6$To#;;tgQ|^(P@`x@DYI7_JLDo`rhQ*@AAaz% zy9d0dk4U40L8EBgoJAZX)?gW=*EAHg^OEx@m%GZL-%L5Dw)0eOt4nnwKy)*=1%$^= zq=)XxrH4|+5eF-rYez8RPRaaQKYs2dj4;Z1dAm_8HpDxP<7k6hOWHjdo;CRK2{|Nv zDWnOq8n68pVj zL*V~SqJKGkO7!=<%RX&i)=;oU%{C7ppDA0ZQi_w(w2SiJ)+l7VoBi)8SM8UZYQK+I z^GWP4OXmMk@$%qj-%lPT0vS%F&uY5D+9)qLh7kRuD~UYD{3t;h8Pjqa{j~oMMSgS4 z51#v1j8yiWUkxBx)hxDH`A7!&d8Zf5T%{_!(AmP^3Act#%MOa+AY$J?hl>r~ei`UJWQQYi&ke;pjCJ@_O|PM=l=4 z`tK`q=_L-hfRJaZ;A#~NpzZ<61o<{tK(G&~%P!@3mrO0oE+vqIiRG(hGa+qYr|O>M9)@A@b`gz$(K4DC7Ju z+81V=zjV8UzH!s_qqW@~$`1`bf9X_+P;H>PuT9v=F}9n2U=$Hm$tAt!Tosj5 zuLBL+fgqwnT${Anc-CciAP0;q+2T?hB=?7B$J5|M8Z<&kYHX<0pdXwssnQy6sv3cz#rQ=h@7hhaGxI!&`TM@ElnSBP_hPKWA>Pg(j%@dq|F12j%fs>z-b1K8?eN8&fU^fQSPljOkmwpjy{5D@zG#6Fz4O?0#_YvR5PlrABw#vQb%|Q3& zUdk!Hg_6Z7C7W1BrsQdZdp|Sr{(VFu@&4fqE8i%R?)Q!o}~mgr9tvveNcAN&n{h z@6Qwl7a2bVYC?V8W~Yim5+bnX;eUaE9>#sa}@7@HCnGaKBbjGY9&M~c*kC; zEPkcp@ubS1V_mtTEt*w9zJf*njQt4!1{76tfLO(wfc7*=~{eD!iUDmPI6ydLQkE#b3w(CPc86Z6xDyF*&QBfkRw z?d>!K4S57-zdla zR1vur@AW$JrYs(){X@;9bef0Ci=B|t^u5$ce$AgzD{j`|Ih`a9kkr3-F4`V@FaU2t z^MIwDCHF#scYY7xl{?AJkmUAU)c{r1?<-an^rut=+fI`FKFRqzUxI3nd_`toM&;7a z(XUf~fKmWQYQHY!)9A@x4var_@JTR#mpd$VV2!RN;ihk&gvsBf}tL*4LBH zuPjsxC7Rur5r`CNNy8r^w-|$YTXE}?(vLes4?U#EWue>Gka~uEl*9!LK3M6Rls^D3 zPrf_>W#Rf&S$vjOJI)*P+t0}E`nR(*N$smIbYzKs!p(owH{R{6J=^l3&TP6-kIcPe z8~=V_w~@^1A&LZIGQHW$JkYI(Q~oD<8(NXGY)ZjMbm~$12sp~T^kKW&*QBMlv^q&!PTYL53hlogSgO_$}{ zV(HFss4biaq4Rx0v;O?J^3zIwyFY&+w6s6Oi~G--tAXR(eBXY+GH+1qVcqvi(n5_o zX-{CxFnToS*!iG&b*CI!J6L{Hrt_a{3%7lGYW|m|TKToCTrN@Npkco?6Rsa+GugJg=d*M@D=!IiGs7-<>!n&CBxIB~ufy5>UEW+74&wiy01Ks7NEW>$`2UcAA8DF|im;T(=Rmn)=4QC!zh)f9 zE%UPGqiyY{*1rRXzfi-d3!RTqKmP1VarIM3(jycCv1g~{dwE5sd;F#4d=jwcrzv{~ z?)>Icm_XF@uRHZnQj^we)3PyYZO(|aRVPp>@oA@#4q(N-0h4wd2b1n!1(Uq;9HvEI zCjWhC={GQoef})a9I?gNhv_(i&OR2nxdridhj7 z)f_I?hrp%JUoTFZ+`On)*4fQNdWB0rtsSek^eI0cZU#dO3YLwV-nqZ}7^$kA+zBLl z8zF5|6!yjH73b6Z!ewejK*dxtXnm%BeEXTw2K0$J`QD4im_~4C4uWHYL(sd--!&D-duYC` zNai+P>DK&<5&tpwYF)Lbn*%S4JG;mWF62+*$sz_iG(|YxF$4cd;{2~g3~J_IUs>n> zlj@qz(bp|Rm-l`5n?fLOqxGChtkLhQ0rsMsl^1azKWdv8Z4O>;c zh}~TBjCh8a&OV!!?ch#TGM)sBS?0I$4kvacArTTj#xWdP(RVxc6(`?10Ko4f`Hmb^ z=(L?G48!%!qv_ip8cbU|?O ze!gEfNJ`$5`+sQZ&HKjhws!>O`?YL2ozL>}u9~8{#ieO29Fh_l^KzlXy)YHyx;_r$ zsl&}sPsYXI&lmjL{w#FXIgAGC$$Fl2jnNBP-C%T55=H@L3H>zhSf6(}L8L0QKP}76 z8<;ZWF?_E)zw=Z<#;?Zp0~nALpC$4q15EOU0UbL$c)!X~trk=iFRP{0>*^rt_Yld;DtLF78@ z?eh?=zP{VF3S`x2{cFqOqsCOU{-K9U7O2r5HD)k0km~L*$Tz;04*yB?PON5@ zF&vqr-{%hY&ZZ-2?Sz~Q*8?gm>HRsW^3d9Uhntk?U%-uil|>LN%Pn?R+TK&ck%j5u zQG3Jb&(@FMajHxLERPazHLK#ZUC~7EW-1{&=0oq8&F##C*XS$FgPC5)5VcvxIXT`f zR>Y45F2}Gi`(-+)zeEZ(dOif1;eD$G73`BzpFkqtI-%EK?G%Dhcvp&+rge3vp35```q>|Daejwv#0h z6NOpTN+dAN8*0l=nq;}4?~dbdl1lnrW~XLN@5b(oH`w9A+CMC?PlEnS4$sqALRNgh z*!PXEGEe@HLAU*zx~)6!;Z^IlFLtOg^){#xLNM)UPEX2F|E?8(C-wV|cl(5ISOUJB z{{ejd{Qm@||H}J*RC9Ph>Er>mhmvI7@K>UCrEKTu5)!SG2-YQ9kEd+^QuF`#`4<#- zS>PdX7y0FX|I=>r%WvtO%-7`n@oCw0@X?B~>`yFR~fH*y-l;H`g5CeDcOAA?!Zl-&iHe8e!(?C z{W7RAO)%d2qU>B-c~Im6Ylq{1)HsB*E9%#WY~w&v%D_Wk<*g|jlI|BbH>93h^WJq6 zvHINQ{b{t_XkFFtn-lO}oxFbh5vPb>$d=C6-o{z15L!x#pc%$04b~W*-XYc02a?df z943EIszN|=PQJI+$_#URIxb33ArB?g{3~I9m>{SJ0<|AnsstK73}J6SW{maY?^S({ zf4OHK23xPQO8vnh^F$tTeBwWj)X$iI>W2w7OK8L*)~{wgwAGET+KL}pEufqGDayQf zTlCLHOi=LMU(@BEF~@E0KMPEfui&IY3!LAKeYV!0$6$e=0=m3vO%gHf5JFfVMQGbfUUA_wpUduYJW^140aYopO4x%d8qjJJ5R z+dpfM{4vLzTuRfke)>x+9aFdIq(e~ zkuD4dE$tgZD=G^P*DzkB4pIme3E@ln-rrDUk1bZV?fOe(_Bi>$_!(d8g-5e^xlS=p zpKJ{i_Mz`au^T7DG#TuIN1~m&-Vs3N8jrWFW(|OjZFl{7DyZJjd@=Rma&@<$CWn-R z86IZY1kU@;=OTV!wb=L<{j@8qB{51{|1a|UUflkNUZ-W*vH@J4n$!MVO`bG7j(=@1+71_o(r&B?Wd5x1Jo#!0*K9ZD$@m_?TtycR-r zV>?tymX`snM(XJI=y(CPoqt{byMb!rI+pT<%i!_j3L~S-ydu914WGjq4*f&7uGRqu zMP(&hYLjw;%I}!1pwIA<*V~B`DGROGg5x(Fnz+t{;&GxP(!5*D1GLozs-kS;L92ER z*fg8tRVV?jq(s|=a-tW13HWbJz%S><5qB_H&)k8s61^X%Rq()rSKR9DFl1V5tNb2^ zfzY^q9vx;q%QSOOZlQG3NVNHV4FWUtj zw~*g9dSwc{j=qrud~`-FngJNnkU?is(A6Rx4uK7IG!MuJs35n~JuUdLt z-SSmVbaD##spl6t*b&b$x>DYSLMe-f8OlM-*TZN>}4 zQB~(f=XYcL`tm{kBRy2=yr2sKslp770VF_%BDysJ9?|2mGB2?R^fYLg?BU+1%$t#tg!`qZiIi}V)5ak!F z-_vXUkXbFY;~?A-k4s3$6!H^0n>YP+4oU9&kJ-}?_=%PB^Z7mH7_r06Y zM3LON$K(Un8nLJ>W*Y%8$_z@jzrPPHr`p<=?b%G+wRsD>I8fQTA}AKhe*W0kw$}ZP z-qs=IsL=ktySk@+&_6>jEj4!!Ji*UynOugSq#=-^TJ9EpTsX{R}x||HGyCDfd+GK zo?xC3;FtaSN@1P*20yW51N^eLxu<{EQ*_Td?@D$|GUdATDB-sn)HonoIuGm;3-?|| zfXkN}KYy5jzc3zUx-!gDZ(%UZ zt_QmpL-fM?)_r4agX@6RQ_oKm5QBi{& zYtdZUbN^(FuHh#Z=6QdXb(^!tyQg2%)8lP?^yNGI1o!4dy|I3}dWmuR@gt1W9rzrG zHvX@jK3dTp;wzH$YbyVKdU!|v*(#0q7c3rUAE0_nzXn}bx_eM9{!a%IOn}?IQSLyD|ReBbtQ@w{kl!j+8y-kqYoSJR`Qdi zUzfP2H|l9ZzbTE|Z$|)K$z&HU5{g-VP*bBUlTVN~f+ZxT10t+lKxb!3}u&P%o zCeqnsthK0mXJdGim}*KOE(z@8Uh~bW$o~05CKdPc6Psi`8Y?XO+wSRAdU|49Z(r`7 z&eBshZ?5w`x?a@Ge)mvObF~aGv(_y>ZJir?F~HoJhDqiZ`>zS+Xz5C!*%}`GU;EWk zDQ=qGR*H!4-G}|9_=nlZoQr?Bkp&&ob4zw80KmmRXxSe}&Z#c&z=KlE;3iN8gt+i7 z(t!`m?GBq=8<&$SC&sA)=UnlqvP@R4L*L1c!~c>saa+uuv~00Ky+%67dhW5wB(O5Bf~D zy=?@zw6b8r%1@}w+!as4{5oF{lyrso@I4tdzmz;o5*v?kKpox%P(~sx)mfNCb3gL& z6BcA(Hs9^Q4gkeF=Q6}~C}R#u|J$H!P)3!BrqI5OADcawt>U5%AHp3w#f;2bMnS96 zr)$yi%l)%F{i9MNBc9I4XMfZ&Hc@+61k{>{0+u%Dmx=F41*SQw`UlIpEx~aBBALg1 z!t(s2ZTLmjmSv4rxkz@u=iMpY5mJ_%KOVP^7eH@9`7br6r&tjjNi#0bxVqO zvEEEHyCeC%z3RZ=a^KZ&D@pduE>ImbFcYPTc-T3lTD)AvLQ>H9MRk8y9f;k4CUWqBo`jY5C zKd||!n{5U2)0-Z&p=KFBN%p`w?&-ODny?2ZyQh_UYU9kS3xG3{yZK;AkIhdz&bP|C zw&+X&Dzc!+yMXO(-6}x^+!aL!1Ad$HC`h(5+1OMwX4B3tzvDf`)SjU)m%P3 zlvzF{JU*SSHjg8P@VHQ8yBy{M!EDY#JuXs_c(iqg`mL%^riv8GH^1SmJH2CxFsDqgB*9BaL_Tmq8c`?K~rGm`{Fee9o?X3k}wz1LoA z?X}lld#$yzAa%PEedZh+(55Kdtv*&ZT)Ys_Uxxn!Aezj+JoA>&amJtYYJiaRW7+-i zb!Nm~*{lA@EjJ-QgEqng%w1HOcz&E)@#u84TFM3MA3bMdjy|yUJn~PFQ?5ZnSBkt& za3t0v|NX6F%;aQ7tP-T@;QE1P#7gZEW}O`?<%GJqOsPHw)ws}qt#ahoRX6)nL+9nz z?cYqrWG#X@D|H!>WPz6xDeub)MX<&J!H4oQ12h9Airj=}UTl ze#@`;T$*qT7n$z*|NNBo)eKrCne|N%vsQoAiGQgX@9^vLmo|rF%Tc77U+Klssai(4 zsA-49M_Q(FD~hH*|2`&`kg8(53PWtr8|J`n#$ta1K{w({MCDZZ>Bwot3}A`~)X}xr}7W&nv$x z#qqI^s))Q#v(q?a-0X7*6dI8~Y23!T*Q%S=l~y-BQOZsIx2v0$|CA(D!{&6PTP&sT zJAvm@bktktCP(x)^U3)Rl=>`OUD|ZM#MNcnoN|@Gpkv)>eB&$|p{ZdFFT?omf9Esv&isvd!o83}yNm)soc9a3k@bnR+@$)Nx~`r*&ud!I z2ef1Zna!W+H5bTSKp=BLL#%wY;=8uYrq$5FXuc@_*5hbC%G=WHu)hd?XLf}4%I_BalUuUpcfXn)nN?5WO8QPshu*spFI6l15TB436fZmc_$cmXr?^%+CV_JJ{0?Q6PS< z5M~y40E^5eoq(C7?<{Ko(Qsk9NVKm|7MzytH=P)8P+GI%w2*Bc>nh3fD+B2D zordHzb>X^ndptR)g#5K@=l7p|Luwl@i5QG5mMy#P3p}2Eq@@{^+xlEp^Ul3{IM9MG zNrWoA&6AdIqm`SP@$&Xq{u)vq_yf)D)PX5kfI4Mvey*^xsNxHm9^ACLqH59jlLWqE z6FLXZIzjy?mrkEShlP6t(f1jqC4b?p_Vh9Q%sy0jA5x)Y=NSfcDXmuGega?0J$@;d z{xh4|#^QJ@?#uCqX_GuD%F0`_l9@u`4}77Q zjCHb-ntn4hws`amXOYZvR1E*GBF*6~lgQINwKS#u7Je{}hhi4!SMs|PQ z{yOhA=v};=5rSGDE8heZ^@lAfq3N+3wCH4wjE<5<6q|1ejoOyCOC*@sG21 zh}S(V(%Nat?Kbhes|_V`(X%|gO=VnakV8T)d3ZNma>_4VK8O=+Vm9XRuT)`KuZel` zA1HRQYp`#y&B@ZRfrk7e2lFPAt+xBHnU4KzYcFc1&dJhH_JwKa$!-d~6SHD41!{`W zd_T^9gLOUkTFU#kd|fY*iw~WfnALC63Cq15FM`-&Z^k7DQX;k1dkk6K@?fR`ck1tzcD$B$U8arX4eb zBu_a*O^JbRL0FjpTrtBEtE1T^ZiTY-?4Jw}Z&6uw<2J_jnbE6uf*NW*_y7=|APE0! ze>H08Yc}kU)_&agw6Jn#Ud1X4M{*l!e$f?(G;ij@@jved@DBfiQz_P&G_n9#;~9&?iXz(56Tqci!q+b1}C7r z-D_B~}P5PK{v;u25EsX|r=_hyp#Q1AfO`k4wzm4pDCW$|W6vG}bvWiaG z^)E+4m?-g1Of!*=8@`f98T8#*WaztxXYXT;^Z&fD7vgf1 z=cluJL5NAGKi>>hvih^FEo@;H_T3g*ZkI-mNb@hb3ge%6 zGMd!VJke?@Ir95IAOwFjxBg2v{M+nD_0^(um57W&td_u(p%zRv=tIVn(4#bRYD5Qh z-NSE0@h7QUxe6+<*hVOUXEfy*fG&zQy+rd>Obp1BH;hEa`w0U+T=#a8)80?7ZZ zU~zi8tKmQpO~O6%xhpasbyx1PYa%nUYRxxJ+1;!B*Vexem9<7BUR#Axx2sY|_9l8r ze14@Ll1C!Y4^J-33?Y~PlK4?<5vIJ^FOtoEK`_4()@}9+W$YKq@as>XsgF2c6u#03 z(b7Rew2GG!s*CI%>qthwRJ7M?ZKh+wV0kJB*;SdSr^=(N+hy>@LhOE4=!au;Cyo6F zdFXLaqyCwySL|Z#Fi`~ei-P;Ng8PQxzE;0MJL$Su;zf;0*Z2btSa?vK5D-e^7EkQr zgkU>T)t>&Mtj&Hom_oma`&^TB(V7Az*F?}|YMEx`IrWoY={GX#_Bm4DX6w+qSR$yK zy6&<2J55*DP^;jcWdng`*q@)*_2Nuaw4fBd)Q;7^wZ2qcbf~y91CQY2eQKSJpF0iS zSh9dr`D{(`j>H19h-h#hxT$cSHQVe`#ZslZh8TBK;l?)!t;hUup2g$4`l32FeXZ%Z z;a5MhfMj(-jfjB+h=hvOhONma49$eq=0_a#44I%FX>PV2?x#m=kVKlFC=m+S+%kCY z%%r&8rk3cD&=+SFdQIfv7mH>cYU06Ov8v#g{K?cVF3|kA^~-8CsH6uJ*1yekQ6E@q zAn!V=&;+j5*dH(MS-tuy2!sPQXM;$;d^3*UIKJ?g1KEJtSaBU3{^8fF&Yo@T8>n9G z1wH00gAlA(>o1I_=wH0$l}PgU@Bl3ij5IZHrMK#Re8wAE?8PzHQpFO1R{pwkVJxx1ebW)UzGFO}npEf0 z^!Z`?G)3F$_FX&|4Q8rpe$_{%~$#!wCj5@hU$wku7vK$L+###0lK)o1D8f` zLSMTsW07zAdDG6(k=yTM9Y@NcBO=Z7v=mED^Rx5Yo&k|tw_;irI1PL&jJ6m?H9xV# zQc_pO-{Eyf@po7q+Zwx$tUEOPp1To|mL?5ConP`dml9S$>8whfr&~F^zKN z6PO;NLv!3TS`7!rzNl{$3AihSQpco=3pr*&dfKI_F6{^8Q0k3XK88P*51vxA% z+P()Ozl7-|l6=fT+!lcBSTX$#Nv*dGoL->+{&he<-a!BGAgj(0WX$S190TMC-O`UW z+U3i$Yz6Rw&ilO`)>g^ax>;v`h zq=5g%?>N-EG9R`dA<9?o1OADtYDRal5_H%Wm)gfY_EKiYq{;!Y|9iMR(GPce^lM4)uy#P zqWxCbZe!(9~qvFHUZO9AhAVW)e|rvggP(`T5g&ePENSmlx6aUfXyyA|yo z7EdslF|vYY5Ek|6CNl`^=`NTY!!i6oKsDUHaV$N+g? zsc~sg;Nu!8r~ZouCn%(&envD|rNMj9oKwv*qII`jJjn%?uDZd>u{?yE)SHJxmgcgp zTvsePOi%jo1pmUH-+>`a;i2iF+*>g2;9GeXYc0bzLwIOv1r>M``l!LLg$>RnNN4bM z;io@R3HNC%_fzTL!)eT5l0SxBWTCVr?0e3z%MIjSep^S z*$=T03jZG$dN<+yiRrHyXl;I(AV1E??eZz{CRkSU=81X|l<+2K<2lmu14>7eHD&Bo zv90i(vgjT9PumKl09(JsYfts@l0%~We<9PgSKi?zYx{y9W{!SyP5>|XGuYp&nbLN? zS2t*h$cBIA)?$sPve^M*_L^)SoNU8hY538Bqc7?qr$uuI9%BU||xiWIgHQMKZ#yl(1v(_O6@z$#gic)E` zN~7zY0Bje|QnKg0x`7X?6R9T$8+m`tb{icft!FD>2po{>qOrp}&aK zJl%*`WCVK$Xn4=@d;=rN25vr(e){Kah$HV?P8@wymeb-R6rh2ATAIcbm=S&)7K*WZ z)bk%JGE(o!kG5MQ4(Ut(_VKp!-Cpg`naLk>BNa4a>z4_GS+PWJpUhux!ay(^x&2=K z&5X~(jP&I^^Ck?j>jnCod2ipe{EeN%Xw&YiBgud7ix;lTL0mXBwLf2?_^Cx7KQjQx zzyt%)TOLffS=rf3-sH{tq(m12EtVW4D`p@$cUH@p8vp{0U=;uIP>z@KeA+ zB^rrs%DU?0?w0nGgQ%?o)}aYsEloJfy~etXUw`*=A1{2H-smw(x@`O0|IWwU&R1y% z_`L~Az7=UMhbO%WgT%|tN=KjNPvh^F3F7Z1zxi+X4?{x?Q&M|pU$SV0wh2y~W)kS5 z^+S0F6YRqX*}Pb!#+HSFI&AZ%zk18Zi?g4nd*IA1m~4K&>|<{0w4QCf@EFF4JpbLz zA8((Yem$U1v1oGJ12p1IIMlA!bdxVb^{k}^`mq-YrP3p!(8(8mj7exWci; z+nUr=ttlrQZupFwjIIiBdiMu`erzuEzfc_Ce-fuNZ#4P%!4Uhs%{ho2@Sg_l${Twi zwy%%O4a|3;3{Aa>9R>TvghRl0{WalZcocslChVX8<>MVs3(ahkQE_O*X&+~N%(!vB2B~tI^@#KlAZ+_%^fFWIG(Rv_Pv2FIiJor_84P+1VVZ2e_vt3yU`49a;D}`jAP~S&O1gd-_IhUP2=ruidvTUitSNllB7HH%n+E%VIA} z>T8C=Hg)?mC~pHf@kFR~#XhPrKMOdZBDjG|E2@VXCH)|I|Z=>#PD^`~rW>C-&Eng1)hRnJPhtLFP{8i5BzLu}ZM%R4n}4Y%9;nSJ+h}o1pyEf=>fNXE!_D9-d5P)~L?plj9iSCsp{rnmg~uV}A%oNDRZE z8zF&VaH4ETY#E*}zY!ZB-#3oxH9qDSOw-_~VsMNo=r%Zt-^~mT?-dP>56gLO(@dcG zAUYfz<`UE%4i59obfmlrP^$rjt@>YB(&>q~8egFstv+xp4g3prGFmw{W>K)#D9ARt zev@7fKZVZs0UxOv6~~YV87`oLe>4l+33oI}w*A7?~ z=M>4iD#x)e>z~%cbIFbG%doHH_$&3ij3uuwyT|$e-G%ZR`2THI@8yJJzd@LD^1MC> z!_v7U%m{lwuk2!($|RjDCK&{nAQ#z_!u%&o^6YSO|NC`u zAKT^597tnwc-E_YH*(uw#lwotk?8KATo6H2S2nF`(R|`Wbc9@W)2@XJ`^A!%@kG>7Y*mFmiGb)RU55*jC-Nds^h?|KU#ZrMhv~ zdtE5?@mTWwJ~4vz#&gk^i^$DW(Q}ADdMa}3Ib7959vW0Jo#Ov|yuJj`VikSt`-WZr zOL&Zltn~R#drY4ly^3shHJo<9`5S*1V~61EA8=_r0+9eDo5l?vIO|O!W2!c5YQR(s zY#dY9kH1svYYD(Ye#oQ#OjEB`gm%Rl>(CNknZ1W&rG!P070Xt>IoReGUBY&%SJf1E zO;tcw@5)A~vhRP0$|fy}6?dgd7zfehlzfZd)A?K>a8ItKzH_J#IJC`oj2zQ&f!*kD zcpgMGt`uv2amA!XHAA|hT`NMs*#V4KZi(EsjG%kP!%Y!~oE=Y2gJv(z{(^jj8q_1r z1uut2l4)vd>nt%0JSA+LE!|xOg8(^)as|o}SAy3BDsf0D$Hmhpt}f^^bzVGKaFVjV z-f|+8h!f(P&yjTF^QxEqvw&%hpx2>)J$OXkIXpW(R+)-4N#_+e&#M8BMS)KDdrl)j`xyxqBmzC^;lh}Gx0J|u@;Nz>K^ zxRTbaBY(5r_Uz51Me~Pt#go?v`hvXbrfm^GE+__tktXGzS2WioVYVhfB)tW!Q;tyM zcYG}eku|hM*-V@vS?=8;rw97lQYV^36p{Uobt3y)ig9asLW(-BanJdkJk5#5@;^-+ zUseRB&LBRlr%=nemwan;@@*~92J+3gTif!2ziFO_fz1|#WF_Y`x)Nr3KaB6)rXp|@ zZngN_>86!^%P$o9%Yy)5F{BDqWeZeSP=W|>t$*$gib;T}*tncxr4$?Ee_bV#^A$07 zLm6vO{`kLsQk}ffa->dSdkZWNzN)V>RhWM+XLRX`U4zAC+pJZWBK)eSob%o)#lM&xjx&@e-Lou@SFCvd}G5qXek-t&lCUlZN2Stm?0O7e*% zqC|%RsI7pD_*H~#EPpx0_jW7ZC#Sg1SDR4c+8LJHPS_EHU$idKl9n*V^%m8-jLnU@ zYa~33hONKpS^1ASr>I{yQpfdKIHNOdt!iLJyx)<8ghv}4K zCRf>0I?uE+9U*9SD4=BIAceygRO!@MR%F&i=Rf}jvHN6~Bu-%xs|}pr5#>^erpTniO0{`IU4Ki9O;(%Vod0Di z7)`tW4-Qy?a_Y{0k9DlBzSYt zyDXncQA8~UK->_&hp}fv}T!LW?;xy-0azcq1otL${nnn?Kl}GK= zZGOuX3@#-Mg3D=P^XUtvc9@i6uB{SuNG(YiQ~GSFO0{M^;bAQC0%xj84Opf-K9yl3 zp4cNpLNS-s8Z@o~xvZMmBXAX$u6mam;JH?cTBx;guSxlAfhrj%)zGSD&1MV8gsazo z>9-CveaRX#TK-n7a(U$DM+nE2Dsbzsxljw+tP-~tmA|2Ni5By$#Rmd`++22@LBg{5 z1x?Ea7rnWQQvMFbKm%L|tjS`!Y(TRZx2nqD0g7Pkd86KuAG$gdBQg|!x0dn82;4{A zbfJXtx8ge?#!w5wkVj#Z*iF&KPUn*HNnB!BzYu?N`{70O5%0&y?ZO{dM?_i_^P>J; zr{AXCedk{@y>Z;h~%ws<@6iP?1~S>VMJLR>5##o2XJTAsR{1tg$#4}h{w3;W{1kcDstj}j~nh}M1T z6Jo@<0w;ASfFeZCyh<`PB&KUSEc4-Eur`;c9>jGivjHLcltdQ4D(4yG{Z@p#wnjy6|0=USIXZ^d9c=QysjD>7 za-V3?w7cH|oLUD*zm(g~fiN5NYTF@X0-M+O^g7kh|D)9K6KbI6ow+?{VdydK)fNZ? z$&r6}et2H$7`h4kN7oGu;6JkdM)9w~p1krSz+UEB?!oS~Y^@HRK&v!m_HYntSjEzj3LMV{Ls3f<Nu8XyL6uO!)_kRpqoYWiNDc;i71i;q-KQK(w>@QVH1RH{-x=rq z$S@$bC>9u*sl!bxy=O%HH-C*64)`HR^hG9V21%d!uHkP(pqNn5&qB?)QP<8?P-heRwY6D>bKY(zPesVy-emVR< z)c(^1ka>+=hP6A}{gag;6bZ}j6%jrfe%gd$jHSoGFKk+N9yI6RhYR&0dCG~;4bMws z$?0A))oN;TJx_9QPv)vBZj{&IVNYwUr#{ z>u>#|x)P|#$ys}HCs~}WgJG6W;>vyV4(Yvm3oPm9QnE8B3OOgEsuu%`=~sM5B}Gb;nBN$JC7*G{ZT9~}JlbH8waq3=%CMHmL3@Q))8@BTmysT#r? zO{_LzWl7r$UacywVX#3N^WAMZ31B5eP19KT`Hw&a8@o^e7J?TG)61DZE_t9E5io>g zwW~h4L;y)-q5N1WaSNWuUUJb5^fH!Q)FH{zv~yA{5@$8OY=3QqD9nzI49RK_+`g%>RN^(@HsEc!x%c;I5*5y z)Tr_695DY^j8yMdA6Zo zv3AmddUEBB^@DPH@(J}~CeM2G;^+_8i${^J9~#zM`3NauBxN3XLq4F)Bhx~*3TK4_ zRV*I!jRwfLETipHq8z3+n|6+$bz{#~s{fb4LMQgEZtbUy0Yj9tj?@ZrwMhdEM4wa%Q9B9f*y}^n>KrG^+l;Q^a z#hpMbL;F+I3Wcle*O}@3Em&eA53Qwj_8$2=x_)kUVsK+OoI5`-vO$o8!6i!1a-bFt zf<_iU2hC!GGWAn|%4Y^Dh4gX>|L3Jz)T#aSxGl8{GuZy#N`7tOJwm{|Ja7N0@X*+0 zH+QyceEN6G@3d(r2?ztVAvtthhh*6~y=2)r|7lrfZpIF zhMuxkO!*;X?Kp6q9ReR%*2Y`@5o!5?j3o-d9f|`y>z5yBVa_2`EzhAQlcurkY%KPi zIen)|bnFYAgBBdjk)eZhz^r?SwluZuoJpMeIl$i6_ZhoEe6dWupsK~+1p(QZ56xvV zB(iss33V;V3CCA*R{dYu@i4IDRZGm|MI)1*G5w`wd3_nv+W7iG4~v@~8Oa~C6*A}P zDGTH0I9q9}o!qlEp1i&*+W6iLpeJ&RmPHx|W^gAfSU>qVq%o^A0siV}?Q}BEs8VBN znf)%dvVP(r?P#%Mr-yEN$&%QrsoWH~^(xu=*bkW|)5H=rk}RCFkpus}HeaWcB3bM^ zkAq_Ot~eRh%T(t3d8pB+57Hz2KLt5e^_bIR!#DB7Sw%YAl+8b?uPuoss*2f!o>!_r z9NbvtF`Lui(7%;x$E&tVy&-Moc9a~nH}?D*S4tA;@VRD6QWpQa7PKE;lgMJgsOI8{ zMWdQA(?)mvHaY%~<}dN*8VkzR_u(O1Aq67x5TXvcvVA zEWV>nU45$`r4-9{Kf3x)Y>jlqBk{jS^Ph=Vz8sBQusSwlo9c=-t~{Q120*5k#Ix`M z6@@t&n)U{jg;kWloF2e*CjwvxfE;6lYI?Ky2re>9IIr^ANV8UOy-6K6Qa>_s|D;B~ z_;>$tf7G_|>xtyov+5SL?^ipv6_zY)T7M)8HvXaC=t=dW<-Mq`525{IqZw-$A}oop|$6Aqk3L@PpS(~GX`9 zFn-R~@*cdfgZ_Z!gkeZr)#31S+1GpG$6wY9KlcJ4`1!5vC3nM*-sIqi7WRdoQimUp za}{$&#kR+LdbOaTrhsp1~eJ|G4vJQQ`UE=lCmXC-Er*ZwCWlTmurE5Xi6K7z^S`A|Wu(`*$9mF9+C?6N zWO^HUjv_6CSR<&td-XXd#BjC%FAV}cp-A&29>iLQo>C(N2^npl)_kjZQleFQqjbJv z-Q(zTYb9SH{)<%$YE_B-E_ObioHBdnY!=BwFm}FvwD(xU!ryJeMhV;_PV^qm8}OAy zL>yxz8-JK6wAla&_BCnZeoFeE`l5KJflJ#dyPaQ4=Yl=cHR@k;6psWEpSP(aR!{Pj z8|8yg`Hr&Fpu*HVOY-3t&m^m4vS2{8-9I|IG=wIuWZC$is`+9pR@yy8^>QO5M6$3uP)+ zg?{sR-QdTs4kl0eoZKNQ-wN@v%91kA9;0OK5GlGOM2q}AWJK>LjYmw#m3aQ z+}|a$Z)JP6L@E-uX3YVpXQ0E>>ZoJt5H$fZK#|IHL%v||rzfO8bIceq`|Kk__s@|w z|C>i|Pi;?3Y2TaJ{Jiv8Fz@K{mK_7J-hWY2B&0|3l;6ud+>=Gy_Rpiedl}}K3rHOF zl6|KS$)oV*FA?6|(BprHh_9unt}tAXpgTG8d)tQR`QP{*Ze1{AgBS*8^nxL~hI{<8 z46V|f5$SG>&lu7jqs#Om)Yb=n>^_b0p6Jvo!(>0L%vsnjGC)W~O=GYMS$=q666ByB zwci!gt^)p>c7jDvyTr$%f%^eU+OJd)d*5oNvsY*KoX%!1k0u2-4ajOGm5oC!_U2p}f0aZMABu)1x{w1_%Xw~(1WTKu*3$615~wdjUYx zmNx^a9j=|JPV;A8zzXV>sCJiinKizilem`?^w@4C&G2S}qqYYe-AH#*E*zOvl_60e zJa1JqwD2DYJRspoUkxP-k5~mw5B+LSn*Q`b(e#*HnhG+_^w$Bgln7OjKH2}CCA96P zu&AVn5SET7&Lh>K`y!sW7$4MPRqVR#NUwWCNuqX4Ea8>vzAfN_SfaK(8zFb2ER~zxk%F=jhMZ^ydcsxmJI^#2*pC5q*2Ge!UJmydnGL;`br? zD)Z6Z?G!8cO&-M`)of$?A^vs5Sz{Zm`+r~ zWmT;Z;<*w^kGZiYrT_RqFG>q6(asAftqP#@eRdpMH%hByNNJT0DXlLul%A~4X32aP z@3;@hJXtW-lDxJ%jT_L4y05zBov;Ru&_;FGX$VJh7e>9i4x$`GUNYuJ$b|b_LGe2#rkur{@l!;oUPEFJ3bl| zK0svbd{XzP3Dr=k7{CuSfU`E+RA24)bS)zd*iCE;3@K?c7wkC%U!xYQDpUgUfB%~4 z>b~!*W|AbT|41KuUHQ%|5*6a#$l*ffTkMT`R;%VILUBH;EzZSR&qyFsZcJHPodMhQ zCp#S(nZ>Hwui!+%XjeNanfffK2>q`byOf}({x$7SzNG!hzv0D6iQIfEb!oWN@*tYn z7%yKD?Rp|khD7H#9~*^FqMP#1PY&rPntR~Lp4k`p$?SWV#CrPy++~~}!>!uz3Fxn5 zDHA(|f@?HL6Yb1@ciRAUHtWg|$u*qV_=|cfz`uO| zfq1DaH{j#${M%dUQQ+TBbv0$BS^FWLhmplU5Vy+{U`%UqW9M1dT|Bw&VCNsu*crd( z;>q>JOIQN9XgYk!Iid|;TUN>w@wJ`IL4L{ea6ViY_`Ei~*w@QnLv?-Y`@6U^A_q45 z3Qh8o9tq^uSX7?X(?+~PaYN^^bpskYk7vELHhq+@4R@v0{wb*v)D%kAR(Hjbb*$I> zMUvkVyadB(G;?;?<2qaJB`xI_j^J;fIbYRv{p=;Oq-PtWzFh_NB=g2{`v;FQ21z zPJWR8Pvh*X4)1aBpnnalk1F@h`2&7Bubird{|iW|vD-QSH+>4vI(j@CMPqa4$icjP zWA|8)=%^0jKycMZxj!jdxz<+RpA@^Z1rQVC&llsb@NXQXH8_tIVlhVHU8StLv;A$_ zd&Hc~T}&x0cLtasyTJY5-D7#?+x=JX>_!Fu5(``lM^oz7ED>VK%=v@gft!N(t#Bcr z6@ASj7W({Zelj71tXjss<|*kynq=De^$*d`lhY~{Et1WhZ)f*0F2jXZhyO|2W0|U` zKk0|aP^$@nj6?(lP2Wth1bj+*8wxz$zD3qQZ*8~@X} zA9(JAOZXu2AXZFTWBbr{3PtlwcHy?iM&}L4^AG+u&;eSl7<~*Rv-r~t{x4Ad>&7{N zF2$}UKGSg_>_264D&rWc^R_w-9bigP7v-H)xZtdS2gZsO8~9WRMNxYzB-uZ2qy8^b zzj%T8%&^p|RW&D(e7k%#=chR~8YP5P<$U^pKK+b+YA@^)(p}@FI-i1B@G^Oxjfwyk zP|4=NAScqN78{Xz;r9YHvhK7DK^%RJ)&N|UNmTt>E8l0aqj5`QBO|EyL|Mb3bL0Fu zU&$4+ij*<|Qfg-sTG%>!x)e+e?r}U}Fn@kAD}QU%%FF<>4;Y$*oIL9lCBq;P=3~i= z3QWGnu#T~FVFRiZH2Y3@UbJf^)!%YX9)5BhRC;H8mf#R+=Ji#r4P%=fE< z_nm>_da7hPTP{t@@q{+fjyTN>Rl^$2^dE9FbL@aFFXgiB0NT!jHynt5sf)8RJB(e_ujbD=HG%E} zo79N%h5e2lo9E|W+C{^7jMWco7&o?l2+!aAG|$VYbZMGs(wWdg02%-7l5dOr<3dQ% zzqDqo{xhupmSqe3`}f86bZNxalocEO{JVJ|tQJcrYFXwj#iFZ!3%y9J{foq3TD5<< zKImZj|K&m-z<+$GyEV)!%Bwrbe=SaF(~Y3T55Gmij^xOVKVCoHALLM1Vr+ax!cceb z4?x{vhlQv!S>m4+wrfXNrN7^+W%t0^uMgTErmbnmzW9 zV_72UJI&kig28vU{7?9-RPTX0=I}}dQ&H2&zxpD`Z(2D{2-yghkL8pq|J9MbkGxhR zrT*d>0lKm$Z>hP`)W!S4UVy(-0{ANggXfRIlhP=9#a%|x&7X4=^-%2m^UgKilX3~v zkPE@Zb@}{XFX(H$U$lvA?eV z?7Dq-HQkzR-tmVUpG|LoUO1Kkvc>Hvtl(VhAAuMD)UUxLEWn-WI0k7azmlevT;=q# zqFaOMU#J=D-(f-jiu@aAQ&Co2K)>DB22iG-$pI^KsqZ7V49?Ckxjf|9M#q7-Y+uR{ z%`+Du1P9R?@A{*@F8PIJlAWy@${=K>nR3DAmA2BK2-t?PIL0f-IPq5C^6ZUT<#F6F zNXGsQi<`l z3sC;e^nFv^rt;MP^qd8dGHws~d@ngUGhxehG=J89{V}7VErGy9`USu60|J*^SjlvKy;gbXKS)vdptKO22mI z>_M?)!I`!_pFFw5t9gVHmUcX$sk`^q7MSzW{NC-<4L zbt5as#uY#KS65eiy3kwyrtFP5&NQ#WmWAH+?~np|hxb_K)BL?Nw*Rp(FR%SgywW!O z?({x#$moN)kwD^P!9b6*5mr3Ok!#z?ykFZ_gLKIQtuKy#_sIMH?$XH}!g0U$8OQx5 zzt*?uslJwHddBuEw;q?5*ipUYdtE<$Fc$gkYG`*#b-UlEddB82775g0g?;l9FSP%& zIP%aF)l27oYk7)dYrXatOJn(KUAlixplSEo-z@d=-)YmoXyZ;6`7qm)#i*2Jp))gnwQJe&mjwSWFkzxh_0`Eu(MKTDkz9 zW~{X?Jl(qsj2b|Css~7`0jbN&-y2<;0}_I7ueW29H)H#a($9Ca%UZ){tPwjV-7^LjiaHu zLzoTU{q~6nqxBqbo>+ri%3i`b)!9=dcf*sz&%Y0hpN(xj@$<71;b*eL58fc) z$Gl;@tjkjVJHn5qv&XWIOCt_v_o-l#!%wVoSzTN+9-E(4)5ywKhe!uMhZ%kb$6Jfy zt+o7LRh%B_UohOYSe&g+nN={>6Qra}D71pfJo-U!_Ceh4)EMFTmh`T{`!ZUeenZ8UuHc znSkRwrxuj3(qU`j-``;e&Sv7JrF`JGki(gYP%EC(Ly*$n=|(ws6SQ0`8^w;z@Rvf1 zBC)qJ`|FK+b#nXcIjhb(dbZf_a<6f(4~AwBUUk+{Um3e>sg{rF2|TTu7|EOcNmjBW z!Q8igI^6h|V+`y1O<#T1$mM@D8|u=LDt<8E-nc|w-(ICrHHKK!T-b7lhsu|W*k-kW> zVrWhB@`{>8Q-`_j70$75Czmas%&Ca+39OmhHFmIqu8p8;BkqosKM#uMK9c&DWFY%9 zEgR;10Zt)ze*-9kb#|3TnxdOoFnsD!9nRkCRj!FN zebPQUYHvlVSrq~5*+jl9IIOuZ^A+gmES-JWs+y9n<0W3O&~?Co#ZtIC91m76+|xBF zIVICKHJ5mszR}E_vCL?_`W9r+j3r&);^mu_A8*#fsa6MoItLy-8sAkq`vx_Bo!~kW zxKdX!QB^m!(_Bobgi+oWfAGoiuC1OdqMm11BwoHAQ~9jN(g#r&b*6?;of#(E{dvlW zOaj+ZpzyD^8w{32r=cPEmvQf3l3OCm4eeVA@^9+>srJ78VXI*VH%rCOwtgHQ-uZ`c z740Ht86M+e0k}{8OUrKh;(>W!lC0=K0>ps786Ci<7myS_BDu^hvO>e&RmR@mp-*k; zq)G(LNr|6OLd-SBnya-s&3q=7xNEhLnb-spkyNN)N59zk$~rdh9L({O5UN@lUkNd zio}-Vt-ZbmJT<-wmX~=~t<{QzO_EYCY2a-12fqs@Q3y(%%5b60k7kX*VfSz_xq!35 zJ87+D`%Ry5`a$PS%nZTOD0k*W{4=+DjaQf1Qb_VjvkD8rQrQ-`lHL&v*=}lpvqbdy zLa(XJSt9-`cRq9Y{X!PMhFZ^zCDJLTsIqD5WDp@A@i`q$v5ZEp!Y zrGE>9dukAM%x=`1I@u+lf9dD>X;G004BvcrO>Y7RP48fm8O**Hh}4r^Nub2RPtogfWg~xuUzI+ zk#{}h&Gc5}T_*CbhrGEsp_(3RUw`H$y?WY~Is=?_?^3rr^>5Av*|Fb!*oUk21Nh44 zV?|lx_W$-ZUi?j;>jhZ)76*pI?=R600vH$&p|=w0WQES>D595^}aa$F;U7wPmOMBAI}*Rj>E^QcR;tNvyKFJCbQ^ zK55T^69YN7=$-N8%B>s7T4)I{=A|Rn$k?q}{jW2xp{r|tL~#ps1H8u0u7!DdH=Tp^ zXVjNuA3Eb~XCL~s+D{IC<&0n#ffKj&ge^~lEIHw#)?iB_*tKd}IRz5q@!`rjq-ak| zn91Siaf+?lMkv1wqI@0$!nB&)FK2YRWGVJh@iH7CWOeo_MjkeUE*%+db#A*cp5D*?ZMguvfKojqg)`I&p;g(aMh5 z?Bwla!csrQB=mE|EN6c`V+6dZ)FyO~zJaerQ%~8EXjpO0PEPTON)Wr|ILwVLN8%~D!?AQ zy?Tk>Xy&T$?_+}x^`LIBSsYo_n!pJ<&|7A}pS?j&U7M8|ZhStS9iOG@{kRsfwWh^eBpPvn*ogXFvj zCX(j7*7F85O}O-1Y|3D}ZLKZ#BQwz;6Nj-ksAdSjc{;LIT88Yk^NNT9TUkH3EwDzE zAshnJ=suR+GJ^71(}dlLpn9*^zyGVM{-CgW(=Sub|4ww2w+9mimX4vlEgi}61X>hc z9>L3GY0gr<(tkv;cML$x8tdz4kec9hmEl2!*Lq?b`%y=pqPT=z=Ck5OYM!QvSI?Y% zw0v6H-#prTJZs=2EygS?zsEq`Gn*z<3-UH*+SXac{!j;cG%=fQom-r~(Xr2Z{CA36 z`(bmxIa$r^44Yf+nnObybgCI|a#SpI!E>|itzRTe(cHPk{;$}tjwVno&ZD`B#esDk zK7esvpUU2AVYTC$GRHM{4bS14@>@c#q4c9Fy{XET*4h~vJB)K=GB)_#En#UB;Hb*} z8Zs%j?Q10aCtR@a@tgX0&wcZ72)ps2+$O;oo+r1zy95ZrmZ{5}T-=Uh?N@9VYg^iX z<#4Ls>q&0wyz_0MJ77|_mX;S;7NO6GW>6npPRr1iWb1hpws zywWk%$4CUs^I9(`VTsnYeyPRfW#dB5e2ln|FD;Z)@>I!?8Z^*k;nyw$m5a{=l}@rK z!g<845Y26APD>B=pSnRU5xlHXlqhBs4GEK+@cm|+x@=QN8g_+z0ypfxxCQ1J@FF4^hKhtx~uQq>%op1e- zed1qzlj}XhQc4{8XD_Aqw|&<2o~P>lQMY7zKaSpa*p{=~%FXHh51O*QXJ0pvwc!r$ zekTh}#^W>@SNRXw9(p&l^q4j@50BG4T$Osg8@_D*xF)MRNmJ4+uVy{bDiM`9p6oN>x6J%lgB{EYetw|Gr6cOd`GKK0m)V)TtY@Ge@p|cLSEI z07h((gmWsRzekKe>-P-{&X6DN4tR;xW#)v$#4|+U#&81Rki;MaH(LHoEP32TI^eeJ zyyTGI5ZitbVt>&5k9 zFU*&Bi9XG&Y0YbE1a4jINNBwi?OJnwa?rpy>sIb$$XO9>+@{F)Vid zOXI!#XXEADw8%v%xTIIbLBc$%c$2G`1JzF^)RmN1O?$gl?Cp4y9Si~CD&7<;e-)Xb zia+lv4hbQBnDxCuT;P?jXDxk^hZQC{ev_A6i2I@on+v!(nCHfjwz6dYF8>$^a~UX6?j{Q|#6 z54P$j?|2yj+#vh3_`XDrgZIMH(m%dg0H?8bfZr)>&SdMNOT$mt=QzZxd|_dsSNS}? zwZV7(*?eS+ww#jXYtBoK$d|p{T0ji2@}=<|-=1q>clpngu<^(JnH{BIOH?xm=a)@E zp+E=;9JJ0GkJs$^_G8>B{#X00SoS}KAt-RA+vlupRavDn7%(*HjF!z!E2r6%Irm!g z^XQmMe~*28_r52$teTpYJk!ztyj~)C|FY+VUeln-pU($lyO_0V9d1~I`_0p4#+v$L z+gb--+Hi6nL58IgMx_X&bGgT#Cp~9`(dUuL@7a`4N^fKxO%_Iv14r3)r2m6+0tnN0 zgtKn;*V-Q$w2yxR^2cjsdYOV^ArnYZFbVk=XKKlQ%$1v8%Ch?H7>Q4loT%S6JN8;5 z<~k^{M$C*>EN>bu$$~@Nq4PUgLb9meT7Ny(y+KH-Bj;Wja{<<|%GLFsYim6vz7XVW z$5j&K6pL|6K)^U2f}!8lk6`_H_r(rB%$9oFI{1#6wow$h#YOcE{)X;bYucyL+cAbf ze=VUlD^BY+kzY)m8Q-MAe&IF3X*iYHqQ97y&;KvfiA47=hlO7<12G9cakakWTAHrh z;S5_|@v160(a18ly1K;HSgWh0`{Eb1>83#QyRg{5kIzl>yBGphtIgBZ=1{enW4$U` zRaL~%r&Y>l0GL!dvBFh4ah$94W>q@f^w&$r_@4`_y^Lxng3fbmJ?+fu-$E~ODaq}> zQIa=@IHPlmnZ;a+PWuk})pelBTa9-Ju8Jtk%=&G(p_H`I-cwbqV_R}Ne_g!L}L z>yH}_z(VRCwL%AK{ntRDoBmrbWL?oQ`x{>Cg~jZ&V>Hmw^HYlno19!+>@|J8BCl>h zj8in?t;5p;qZyRadQCCHpUuAYS$FwZ;&}%VWS!A6Jns=^dGgU^3wV!((6FBs6vbS9 zntWaon>f>u$yw7_Q)m87$CAG0C~y7i${ldan^Z(jQa0ENIJy4NXyy9(q!4~Jo*qd|fB0)_OwZ)R+|QKn6(rVsx^3Qd5SsHbZe$m01)xFyd*y z9*jX%;@Kp9GDQ*}6sV+?dFC&>u3wxCWH@MyGpQs_JK$(~+7TjbcGh9J68)2mic7Dh%ocw&T*Y%VP<)?%DhHn(* z)u%O4o-DSEJa{qaV}FEI=Ny9mIk$yx+g~cgjdx%Pdx8ghXm9CiqoTyNSeYd@kr90@ z5^c=_rs5SI2!|Ahl{9ay_vtDnGhgsM;|EO7XKyUG?)q1x3wAZa=x@YCAR zJZ>&!{8c+T*!%{+@N*W-oLO+o9=!?RgLMyK|Aqv2 zb))!uM&0nhq%;;b-OKo$q@9|eQ??~P#r{sSzccy!XjubI+Qp*q!dAw~E2tv(922HY z{~bK&)a4F}DoA#-{f6i7JZiy`GU&dg=b1 zi_RZueu9hYhH<3qYv(GO`~q-Qp0Un!<#G;&aXF20 z<8HKl$iVIJ=WK;r5dBr&j3=CKeWy#=CiORYcfLJ=W)@>b@OMi2h3VBIi6L}w~b? zKqvAu7}Fu!GdER7e!Pq|5%Ta3`y_cXUq5JLQ;rnk5?iSG2anI4e8e3{eR*HkbH>)brk_B+{we4WW}-3T!*OWEbw>ts zE4K~f#@8ul`csgE7|EfoV{DkefCgh~t?lzX5xMPVN+6jE2m;<|2NOo~(?=VG{`$7v zrkR#hCzdI@G0Zy7W@3tdw*E2VDQ8`SV?_R}i?J7@gocN?*g;C{zu|%RO&;%x?${D# z(8aJ1#7C`zxblXy5j%+#7zq~Pwo~_S;RpFrf`dB$ea*JhDTYn58Z-NIs6HPZ&+0Ee8gUX5@^xfp!H#_;-=tnx- z1GPlzuem7L`lF;Zm<+S1o&fX8=hZ>b=FtQTk-l1oTs@zgy_)Er}aj0 zB1}H|kHa8RZl0gY5`p$4bM-XCLCjT+D+LW&vUUo$M3P!%7zdetlfy=1MVITe2&?s5 zZgaeZ+~Zae(MN||LQ`*9@#+_01WwZej1f$oLD^;iH4IAK|}!kiBu}VC#7S2_9uJk*8m* zx}oy)`m;F)5}Y&58Jje{%rrM-7?!5|`hyj754y&7rOs!Bx{(PIW=aQW0BnoJCRU&; z{aGm!JDxMwSDfG?lkhJ?wgua1A&vtU&0@U`w6p8>G{Yd0?4U+4Kj<(!RFo4)F3xXD zpCc(SP2$Ca3v4G&4D9z!Itt7TL(Yr{k~YYB%uL}yqro7b#?hkCV)uZ#$K$uh+Cg4`Ga|PU1ksi0arz3U-@=`RvV0wseKSeWn$KFad@~ln?3r${Q7hOS zcHZAd2j6%5bfCR6q~aGhH+KE%@v;16N>Xrk!|A8jS7%g?kQP)2aQSs3bCFNx4B2SL z2=l2Hux3OO8BW7Thyee93?xxyW(2=$-G0D+$*=-oNT#-VA767~%lZR-Z8ThMH2kZh zVF5IB^7rEWbW|i{U8@kr91)-Th5)rrvg*gI^VY<$D5TbgZIVH&k_do8tVr6MAIkNus;-yq=@vGUD7 zhd|N=rB<2LJ-5CJ*K$B5e?eC2V&&MKU&k8FT#%YAPXrHFGo`vp|C98Rwr%)-WRdtUc!AcZ7u8tt zu^gb5+N!YCVQW(IdYJD$BuGY@Zw*rDcHq|`C;G^3L#0Hhb33}aSU}g2wlDC)`GBor_S3PtIju4)!WBWQl6zY+ zZGUK-*peCh$~Px#7~_Ze64@If$&GZKIch|okg>j$pFU3vwT%~Ae%^1tnxdS1yX+Px z-)c2aSs~UmDwJh1Q&D;{8UE`-PUZhQ;#Xz4jLodbZC^1KgZ3Ia=__Q5Lbz>T2!DkS z&&{kK1@x^?YtWUGbK){&99eF*M&Ys8sOP-=X>(N6U7>EbXcZ!R*8F+8;l_+d0t;E%3*GYgd zK0f;qCh^qI@}DiOO6)0tq{*SWfZvpJ;aD-Qa;FoAnBkEaNxU3S35) zzvUW6^!23VHyQk01Lle@!+X=EFml_~Ids`7C2m7qKlU%TW)ZtJjS>evPD9+WSs51+ z_e+p&-*qR*#UjZ05QO}^=R}jSGL|Jz1Z1s7fjc*#MO|sIgfbhvvopoO{WNgjmHHXo zLaLa4_Ys5!j8X1M^3WNOi{ufe8|=n8rCI8#J*l7U=H%*ZU`8-Q(Xx35>_?oNx%YME z579SJDzbwP`qqlR9oCvVJS?DZ`erxYJdHPd9}ri|{Cg-bB2UW_S*v_o1!gGB3V+C% zy(!!;a+~~~LX4&MFwX;@8+~01W?ao zQjz`s=RC0zSjH2b5b6#U!AkR%yifS`-LI1`Te*Q0Ba9UE1yZobkDZ(uO!IRo3dKjj zz674rkHG&Xs_iNC@C+nbqP0gFeET)M{Q5?R|0%-1y$An#pOtsT5(z!!9afQE@(%bj z6YGpD?zfuu7LKp&3q#axO}!hS{``GPyX1&I0p^LKcqz4t!q6}G`#*%J#{}-=Q|g`o z`LoaOrn~v0kL{+nP2Rq51BWSkB8jt*WH(tgw-y`!M4F>Q2zwfl=2P8OpGb>o9?44v znC-jsOkAq7yXD#i!OE8$!ruKw1LOfAM+j}aE5MNDa{04S<@LXQ`;oEaPjnE1q>S{6 zoFJdSC;`7!afcn15Y)mEJ2A45N6!CCHbhh0gkysI+&cR?N6a&0EZe|c~O4$PyyF~9S6{9HPaVV ztBa!L8>6fO<4JY{TQ*>fBf1n1gA4nkRAKL1$N3ctU@c5S*AWvblNs~jjP=gChTq0P zn|?lX!oW>G&ozq{$Rr|M7|Pty6Um>LiL-K(JAuL?*jPM~AI@v(B&3;>8W-T(@jPsS zY|W3AuUWx)+~A369#@9^$Za_FLc-mB>d(z-HFTmV&~aUy!mF(-rHJSMXypcL>oKNg zcKRnh8zUo5|0N^2OMh|+x)z>cpXh%3SET9EW-H$)(_W(=ju5sWOtvNiu5WDiKEW`Y-6p5WysyS{m&<0(ZK%4D&G>1 z+M*wOi~sNol76yHYY&N$goa5%PM!JTC9fcJ9+rcxz{buMdzJ4JgQhXmI6GBu*7D!c|Aa+;zN4r%|FA`lLjQcGiDLsDwTr0>)N%!S%( zZjB8r)>kt{AZ+Ybo(yjlF9E45LDhVBc#+56A^syouQ?IG@@1oc?=owM?V8>VrN)S6 zQmezfZF0(0*8sNyMlXo!U|TkO*>#&&0{wT*)>Sdy$;2nq+gK&N9a0&qTvz{$>@)OM zyYBRx-gX4NUF(kq2;^%{he4`zcQzvVD1BFMhie8F=YV5VxA_g5lDy0RzI;TqQ}wpL zn9H0cZdUU7?|dRxV5;^Kp|&)&>-}~p9e)f$#|ZdioOpo^*sXQv+WZ7>)(>_kUvuL8Z|BMawBiYdYJ(qZ8jGjCq&+m7l zbIL#oQQ_91$>@nF9utccAvi!DfT`P!We>%kE1autBHZ=9JUt-_}87%$`B89uFtxQl_ z_;jUc)wSO`xapk=M$v?3`#GhBAHTTFea!h)ii~R6z@W!CGntPflh)bBEr`vcID6%_ zj@KptFKVeBl(97OS3W;PZaz$ovj?E$$s9f(VH_jow;pF^$J$fensF{wo_{W~z zjlul8N9VFt>d79=B>tIG*^PIW;xP^WRwK`2$--YR4Abxe7H&s#aeeLoxiA_yYpn54 z?AB2FSGn@57QV1Hlof*{iwi!D$~6xU(LI;RwdEjOj{M(O2j1VbPK;nxNxoS+Ks~|) zY1Oo9PwugV1suJ=1L{l6!wqK8iA@uJYn73NqQY-+l{tUxB6s4X+Ql!1dN-sCS`UpN zm}Uaa-Yhg<38AU*%dCQvywzD~WIv30t+bCW0c zZ<uR6yUJ;%GKb$jIiCX?m6O&FR-_ z5ahm8K#?lea@jSwE<>Y8OF!N;o<8}~8Plh?MOxefBsh+xX>aj?0WdO=jh$+=b*hG- z*IV7_RUFOV36yUM0(CV83RF;#=|c+^k$&B@tGND($b+Y`^G~``-sGiANIH8WH(J=G z58~#e`Z7yoYM5EZQ@haO$}YBX0nbfkl)r}*Wt8ugFx6pHYp783*T`4gi@*1J@q~Nv zWcL?hl*D#`e`Xn#6B~+pOy1M~ryJH2>QS4MkK*qGkW9(5&(`v<2gZ7ExWgDU+&9Kt z%1N4wBrj)<4jF>J6}c`9=-vf4e}G@KL#LlS;EWB*BnmLw)R%l6B(u=GRs#or!;E|+nMVfr-8-9xm^ZA_fMmk9O+N53!IvRr04W(+_a^UXIG3y%&VO6;rz zDYM>?db#6yDXP&?Z$*aOS)O>Bsk6XF$~;Tav(8P8uAEoU#C z{X`1HWbd(GjJfu^*ri!!Y);|cW8FH9UkG>|KZXZ^n+qxdZ0{!n3{V7jfDwWC1@_cJ z5YerHGO(t5qdLzgcTqP014;mB$dTIsAfB(Sj4HVvs2}mlo8tm(RXJ>V!j`b4 zRs9Et5*W>L-2=+Q{!dWSU$gBrttyB{e#=RZt~b%jcMdcV;_?C!e>nb%R{kq;^L);C zQ?75rSUKT{uLbCej`~+T|BYz*J6Uu++6`S2MjD^F033jMNDusv^f@6E*8V@xNIqiw zkZCiWQTxjbj$Z`K^UMLp8+#|1Y1`6Q$PGsLh?Ae{<|!6U=B9{vIUbjf+9pkO#|u#w zjqy>NqWP;?^2ZXc8TFz_&2z6hRNk@ON*PcES;M1lZjH2DYXxvqS81~W$p=1`xG(U* zBhFp3)EJ7%oJjai4N>0=l2Uu}BRjA~Q+b1R)XlVQYDZ1(bEHgf@C=b{e5fJRm7d`xr?ByT!Cq4Q`Ek@g#EsgKdV8JpWCW-HWNkzw zx`R@VL2NcV0EG&5N^~sYH;VQhw2-!K{H}DNHD%iz6cFIs)B-#4rwVbV2td#K^$>q1 zb}y2JBmS-UwQbncc(cqt3yxdbkd86;EdHxaxJiDxPq?$)i@F{!5(TVpIh;Z@F{|QF zN@uJ^8Cval9$0!DuY1j}dZ^u@3V!tu0qSv?uU%+2zv_(ygak%!4KinbRaK(33QE%G z!;ID#S$w%xDHvDqCv815^0apqy`PV}F`R0Uu_&r{qip{$A$HO=0>%O5+9EwjJh3it z;Hk!=FP`6yAxCqZ1L@8HBCNE^f^s9Jc=a|1&7{#Ua`)!m=%0 z085XHG`|f&*!Ax+24%L5-1Y)bG+7&|k@k6XL579vyz-r5rhDvtyZlv^pL*0z@kOZ$ z<#*`)JT8M->nV}Ui$KkJum5?@juy4R1T)eTjUeww%hN2gqmpLDRD+2If`v)K7GZG4Z}SQ@m}jKNfUJdp9B zXX<{dVsVD@keHZ#GXY*`ZV@Jv`NMul`Jy}>*$LQnLdwuc zNqp3;6PP5r1q-iN6@uifFl6wuz5k)KgbAp`F1lsi=H^*FHv#tcn z1)9LxZ=m4ePf?@wM5J8L23jJ5Law$<@7r8H7z7;hhG031L{J)3`osPytI!PrWR5VL z2KORqdOVcs>Mxs*H}Yc5d4~{|Zs8lTG3$!Gr3wHd&J8)7)!d6QUb*PWbazq& ztN@H9#??kM;YMSLvsk6i!hhu93lAx%(HRfjRYQ`U@uV9e}+ZYPWzBfHB+y7YkZ$xKyUL}fRQyp#a?|xqPKMr-&O%;|JtOM>K zpH6{b9}66=L9;{Q0@Q}HChI(Xqb~~ZHP{rLHwl)UvNWq!r z$W$;Y&9kQZU#DU%>iQH-aNKwd#+2Dbk;HJ3mtiI`vq-*a<0_X)6+e1vYPy&SQEhHx zQpI%d(R!O-GAQ7k*kq|Yq!C}hqyMqJa};Qo|92iq5A3V{*37HF!7>ql!2MeP{1x_n zr~gp!dq2PX(2o4vkms})I9~lfP>d*s98C2A@R$qle1D@c)$RPWXR4?~QtRIr`c@J@ zf*IG6RkLOd24*Tn|HqXC5?f$VVMqY2vn5(_%dr3LPIsXd%&G}Z{~N|nfmKP@jQ}%Q z`o~56nO`dQ1fV8)iT`P@uKOVS`~{#a3+`S|(r=cN#pyRsW_uRsHzVM9 zTDAA$3k9MnQFg{w$3B3oo&K{R%ZRP?b43$VH*$r#-B5j5O$lkn)n?^ zh{=9C?ZAr@WW?!gb|u4iCo!x3T&7|2XoBV+Ol_dd(eHp4oYXYjpjrK>`}llh?HVq` zVq{%2{zuk$YdvSIZ!uZCy1ARlKZ|$NPRQTSYkZALA)@4<;(1)B2fpD_fkKBls=oRU zjMT6Mfs+8VOid>9A1#J8yzrSW&SB0QY_$lN7grnq@2O=;In%^{IZET?UfuCkLz77} z2wpkl(mxI`KUF0YOnCUnsYD!(X`@o@Hg{{=APBdq0KK$Inz>5X-v1D|M%>`U^2JYT zIKQ#Fd3-O``Z9U6N+7*&;E`ay-XrJql;UcgN+;=hLD66yxW_m?>w>-CFqd~xN!#&OGkfMm(g8V&u+Oasx)HWGw>U%#0la|eMW z)@%F&qnexxb-K+B8_^F~QN{X+U2$Wh_Bk@f*28Mp-v*Wxa8+nc;FWwZW-Kyem9>>m{&>Te8 z`0jDhT$GlC7fpFf?o`I1>to62rtC((X7IB$$ymN^W+eL7R6ON1X?@m=`LPYEc4x3+ z)JdFgmSEIEvXpwQ_UpF$vBWk>KGUg!(e-oh`lzi1`}h&!8>&WnpK^WV-O91aPT@5HNUj{>1FBWhgbHAGd@~}mqYP!LZL-zsShgRn&py&2tRQCxtZ1O;h#v{Y1-nqjV6@gc+J`f~swVeMssaq^#W{rqy zedwO20A4h0S<-dY-Xmse?~rIQ(~h`cYeaI}(n18$j3C>NP5+ppAUp)%#+fy-sn1J5z&OL?d9R_#g)N zq)*)7@B1cK$Wa+><}{e)$(HVbsGu) z2ZV{P*STc=e_Q_o<#RH>+dy@<*I}wSsFx8unn!wm4_x ztw6rYEYMv^I(E&W_9Iis|=rs9~=dK@52OS``ICam7hzs|WjsJ}$}lXC4(Dp~3GTR5`0&fB$k zPu+scF0L>49;x&8OylihuJCN`H{l3{bvaQnp|wZBv5YfHguQ;g?M1*Tk^cnheRd}} zE$R#xz9s(q1kVjWs^2<$bc)3FsV*oPB^;Kujtn|TQa zl{DkuHJ|=$^na~oAD#Ruq4!f*6%J6Yc7Od}+vz8?;b}BqEc2EUDD!kSl9=E54X1Gb zCw@YK4j>iLhK0x_B;$%z7kEpIGK+Ws(sVW`4;E`eec%rs{jpmm@By)2aZKLoM{*?o zCAG-^j^q8?O_h*sM=Fg#|06`of1+^GR~c@FD0tqg;wikKsAqyA#UfSfn>0r9ti5#eG}BYtpQRM<}u7hmrQ>S zVhiPY8xT?Y>tJHY$-*ZTfJ~W zU2td9`=pw72P`_8cr&{A-SQ%cWy!tWk^SvHvDy_lGmK?t0kHC9SJ(`h) zrN=*-V{>lR39TPS?zht-I{$R3mg&8k7MyBXOmwDxp-pA7!QfXS>N5LoGdeV^c5Yz7Nq6sOrJ{l1f9Q!*(QfY z50MbbSwM=Q|63(Ga20U-2Iu=M8iH#{He>;3He|KL98xjG{!_OM6C3b=cx2KIox=}9ZwsMZ(p<(!G z^?fW5Mf)g4*v+-H9%>nmcm73Q<3j=cG!c(;zY&dpcO|V7??zH-~w!fH@q({E-8{Ihl#>F z^fieaaB|d7c+AY(%tItGqjY-&k#)O2=qs8f-vves8_9ZFX8Lm2;6nDfNjAGK5I|y& zpAS?9pMh2ufYv(;8Xe=(^o-1uywK>|I+i4>clVq93%oPP=LjQ;>D#?`E2 z0J>idi2;5%`Z!to8j)8VKrcZi%guTF?0$kOd3Xr|11cIZrzaFdB z1mZ`ffOr#kusRSYoMIsUja1j1M*eq}yIg}($qry8AGzPk%Jh-ksmw+R`_BX2OKd&2 ztU~t>^wm*93y&H7VixU#27d*yCeZxTLBl(&%|M;-|31BS0iX<*bW#Bkm#qh3~s>pSaqj%E? z%~|?K{MmIDe-?pQoxgDoh`-`Z*Lh9~=MOp$Y)n=H{iZY7IGAO7$H9F5Xd$FXu@?P% z4$Pn;h=X~eswz}f`;LQ2rJdtoE(j|n3g+2irC%Hc^JPmjnM5xEkCuq{xB4VvE00AyqA~P%fueb-LI-)XSvt-4O4Sh^_a%}TB{eHY6@5b~SVt{N4@sfo*R||FDkkssjr^ zF7>PT$Ci6dO=Pi7bOVG_y{38*h@KiR0RaxRb2*mY(9iROix#9VdE?|0T#X!<70tN_>N+X(ntv zbuV9OpOhN!roTG+8Rp$sjp2s0@m|yG@E4$^c`ztvJa0)7J(Z2Zd>#ygEyCaUi@he@ z3zos(m0r`0RyqnDKC^JFw`7!+T<={!R3)4H0(>Jmz}ezm<1fClzJ4&(O)_HKb@8nF zK2$X+SL09r=6j8YfIn$^hN68s>+|-Ok#*yfBVnC;x+9m6X&f^qrz+n1vrPRBI}Y)# zZ|jJPAH&>(_zKqlri)mvGJRbMSl*I));Jp<$n_$gt-I=N%~f90QnDC`pnBJp^$QrC z{TLn5_z?2OaC*DGj|w#pWV-FHx$4Txj6yH89`3%FE?o;qVVBOMOQFAi&EQpZsVIcs zb!{%0=~~~Ss`#p((Ij2E%#EKxbZ#(vMZ1%{#wi_p`z!X6baM)1=!UtrJ}NRa`VlQ2 z5mNQiNvvZwirMjL*jeK>F6&t1WNOUfZ;ID+7~F{}jq5PlpF%{zcO#eolY$zFB__H5&8yss@ZTpjtq|Kl)mwI!g#`F!R?~>(TCxzbrgC!#tj# zV@9{i_|5tO#^2#TE;++FdKdyj2A{gZ0Wh=vv=D&99rp^`Khu?W{Oh}3<3}AkFjVEU zjOb8aE!yC098WlrV?mjsgE!brPCVmo{ES;Lbj2i`{b`rE27^4-*&^0i%Y{Owi@FAN z%C)P@TqT`yecolRuViwGB`*0Zovunwe4cBAxjLfmYuw1y+;^h`W=}NnL11pK8SGe; zg(Y+VYs{9+qqxi5p|y=*0b%T!M-Q;wlnV(zu^T>w3pHt31K{*0IDA*<<`SQF$FTb2 z0n@yG|@GKc)Ui*B3l;!#dm5*C$h-%eC*8_y4zZ7Ix}Q2U^NtF*jQu z7*HGt1vO|#HXR6JlQ^$Xl^+)4{y<)JpwY$l&X8M&LCcUX=bHn>fwz;Z;;Lp zQ&;-`uwn+@rD5uNgFhzi=_`Isn7YzmmCbu_TScQ!#9gcq~IDiwX(5KQMRf@XdAq(CZ1(s?! ze?OagSvGY`HubD*>gsIj@NDXDvZ;q>Q-4J2K0??_zv3-zq$}D9`|n8`PPEYT(f{-~ z3;?oY&UP*-RA#V0Ak8bcuhZ63L1nmSqV{8V874t2VZ0UU3H730VHt> znis{jXdcbO_+mdd_EUaPsH^DsW* z-=**AZsk z9@X@7X~Tyt<;SAUpw_gkn2>TNB=Z_{-&E74>$bZpvqjCIdcu1DscxFT7?*eYr@2S# zlYcBPPTBMZ-XASloVRm>h`!n$`%ZBukMmSZ7vm6My+~LmB+B}_W9*{KW9x`ya&-Lw zB2#;}tkQj0bljb-kH4K8$^9_BA5N6r2(PIAeUiBpW3u<~$nMq2Ghu`~ddxjDx;z;2 zURC5qEWKw!@?;#!=#oWx$h)>5+4Zh636^?*4AVXAy$>(7m1LRBaPUAi8|5#!F;D7Vg8Ff%SY z!^jv$^KwzJsvehKpU7b^M4L9(7gRm2{Z)EM)#H*8xi6b2jVpI@Y<3L^Tw88D|ipgHe}t=XUiOrBwELk2!xifn({L z(p;Cfr~e%MmU$6gIUn8+SV{%Y*~!aB<<#Kr)1j6b-Fs&s`U?eAOD~*yN6gvJz3FVN z*te>CFFkNVa^bOXj*(BCl|1GQoO`V@%!J0_1sZ1^A70q~z^deRc0Q?6U42@9B+5bU zs)YtVw+8fPXO4cu$A)Y2Q1JfTp7!VIR(t9>$!n5-Ps26bjM~&>PerHIUl&Wxe=nBU z5u9wVioet6tYqI2!p_2Pj%F5)aQu( zKT~yJ1qb8HN#4( z%KWL_X5?f3mY36-8&MHp?_EYl&9fH!bw_Ju=x*RW;NOH5h}Yh_380@!-NgmnrIH1kl~!F!+7AD=1AwsJZ4^A!}w$`BHKqZss{SF@BzGQ{mO{$sPiH61rZ*!8>z?|nUQ?nX>RWU_&H ztlb5@px)g+;~#X3>X}3n7z8fSD5*wVFc=ZhHcsJJ{fPmuSW~r}SGY*^c6a?Bk=cp7 z$OYcZ!@GK8x%l?o;#ymLk5z@tW?5@Xyvq<)o#!l?iD?0BvP?Gykc-o z$2KDE?&szH#ID*P-h$eA6@B^M6r-DHS6}NfTSgKB-c6P{DXp{fEQSUph3A>kW?hhs zRL#=QbZKW+Rh`=3Y+yKn`6*QN4TDJ}yG^BQNbk0PxVvby@*U z{v8&|uAzVEFa>oWz8}+#iw5m>tPTDNyD@({Bj$c{KMsTsf9s1uW9dK0bCj#u@EmP5 z&(X(dOErhJ;=rcs6S1DVi``j$2>$u^uS7BzyK`FrQ4xh&T-^%Y_0%{G-m(%=V|`*B ztN0CbXju&f@$Ia+Us`i_b?TbEI{7l(e?;Q%MgnM@lArjPt##Psk$)yB)Dgxy+8 zsl)`j;N$)|;pODLi3KeG@Nx|@bFIVW+`ZHNQ@tVHFJWy{^m$*&Jml&UkOKIJW&$Mh~Bf`eI9v_Dv(ON(QlQa0a zjzq)HHv{}cLi`~AJN(FDV9G~^A8l{_f86fyLk1l!aQM*|G^mePx4(Qh;&;2=z~z2F z|B<>3Zf?+VJ8c~d0Yc1lhZwk+LyQ9HW=Hx<;OD_lGW0tx+n}BAQ-k})&z$cBxEUT& z@|7Z+v)MzKZ;1=@kGY(SQ~mqv)U6#QbB~N9Biq9L#ZCfLtRq8Sv84Bn{@4P%7~?vt z`Dlp{_ZM7${0C-d(9pCwM8h?7S7?YBrC)E9zPMBWCv=8yg5W#e;^#FFr^V!;%|qC- zU_ca`t~)*q88{99pu7+gzdYN1e%OBcr`g7TWsTpHZJZ~=|LH;dw)fSJS03KA*tja; z)aMq}AM8C`TRi;S;`%~uyP601(`J0s*5%GIsndX&on!j0{}H#SIG}!z_i&_OI2HHh zp~vtEJ?anOq37@kJ-u66agtr#0jPE_L3!m?`Mq-gXYk+qoqfRnEINd);6E&cAECm* zPi)8l{(!l4-32#4zsj<2IBw3L@MGKb#PpNMfA7;1a9B96ryMVE1Id4jcfV}=Zl(%B z0OayhxQQgbeASgJb>*J2a))Kg{YmAvzu&&xuUxs^KeF~d(@!G*4lDO|kFdS}Qn}?F z$}Mr_HoI~!xN`MY?zdJBD#`yY?tSc zBROjW>K*xQWGKMl@7E#z;_ue7luvCxZ4u=*rMsg%MY1dOl1rE)NEzQaW&o1d$lmd` z@LH>rwZ%p%);f{cz5*WudXVFfI6@RZA4+=InubagcBZCZC@Dz)g(czvuyV9dfV2D!!YyCd4a6t{mlfR`4j zlKjOSxU-dDc>4j(jI4XG`P=S(c*O^5j+8{2E6XCy(c%_4q-ujBC#|aqHBrTBjVLhY zl}d~&5I07*O8CH0hx>=+*qQlQvfnMe;gGiR@vq6XuCPp*vc*q78_e)@qabjNO)f*z z-sJ>#^rvmxUOe(U@JKX*u*Hj2HC1GFdt)zGh-G)FH^N3|)!vcr^H7Z_{Txky>kvvR z#+B5umq^12rjUFV@df+~iazd|)gB&p!~zqf&Se}s;a0DP-=hQAGv|k-9jo)28&AKE@6vwl6LvvV4}^q;kUxbs9$+xqcjhgO1`k+$%UlH#o&BE?H@AC}`{S2?8) zH>Tlw*pvNO_cj6=*Zo6bcM%lZo<=^|gjdGHCl?Xs^Z5Gr^!k-Zauz{ZK9s3uvpKnj zSGGh3KNrc}u2v4Bm7n#(u@A<8hR0M#83hum^s#UkQx>`L(^foyv`o(UXw#USo=&;- zW(y?BFIp_uwIjtlXB{i&nlvvj5^{)OqZW)EFI=Tj9B+>lwE@0_lsbSe3cn z!}*nbA_7ZqYeHBoYTKaTCB!Dz4cPuNZwIl4v+t9if$M$I_#GEwIh0>mo<|q7tYFC7 zwtFj!+n%Y*_YZmz7!3#hQwX3ErZ6ECy z{_FP3zo`BEFV+5-5WjxStle$#9YlA-K;hQ6-BajEa?nRPcFF{QOd&m>xJ%jMT0C#l zT!x)DRjwaj-yQ>EV#WKqAKqK~Y&-hYVH`wn(*;zQ4)-5>WH+&`xa*{;_1Z&;mgZmK zAiBgs1nnAC1&}~r&HWzw{3JyMzf7Eg#qPq=lI5o}Q3M2w2-W+)cy$jRLe-?9i#?H5 z?Z|qs#g;1iT1WBg`@j*kKJGr>^}p>f$X%ywI<=;`Gw4NqO&0zr#gBc@l0rMh_RMvA zp~OO|q;PTXig$@X6n{i|Z+EWd$WRVg{I1WVi2(=da7+Jo?%UpbY6d^@WOeC*{_Ypq zH4t>-Vltz|Gc?>%YG*0XF8qjh-6(Yn1K=I#B01{)p5Xny;QJqfcWI3D{mI~c9q%Y1 zB!V0YCYTP3pA=+F22`C=oXLdBexmAHR1$y4Q+x3>8(?-l<{lDU;}!A#{D}^XXd%O5 zuqFK@fYBtNKc2E< zFZ#J=P5VJl-=s#{{j>Hj2-=SX(odbX^3qf#w%{p)dfoWUp5=;cz>zcm@&G3I)jEHQ zV6p>#wE`>tB)fI#h3rZ4ONV)B0dXv}kN?_J?IE)nnvLv}QYazd6nx&&U(#@fM<(;n z+{1abZjXGdi*1JUe;(dx2hJ;rk4o-22|?b%t&e%rgmE>`a#8rgM{;9FwU~d@^%Q>U zVf?6*g%??e@I{}bg7y2W*F|Zhfx^Cj7Xz+DKBXQ@HV0+}hMK@?gPtQ(i+n%jjIIl4glT`4FTh_sxbvholKSb^O2jaB}r^sIv z9PBNu@1f&5-W^%(*>OU0hkig%vlbu+l>k>)0xaL3@6UIs4!Zj8==*KH1~@3e7O3lf z3()Z)AI_>2Q;M&L1FbBGe7bT++jY3s-%b9=pWArmUqfW@2R1=Bpf7_+R%qEN z#=bSgmJDMHl9Q5S3j6|2PZ~)_7O$c>&)RlyssQyHj-QdHr|UPR%Op}Me=q-KyE09f zeoXD<5am-BfmM3cv;zA@FG&2l&?Ou{^#-_{hHkAG*yvN?jnN=TYda1r&loJX)ULvqRm|rW**Y{1&!Q3$-*0iQ> zisJ3-3h(EmI(Of?J?cGJ!8OEdb(!HGqU`&Q5PRGm+=s<}f<|nwpv^|H^wgD%&-X%v zm5Xh<`2*sfeAN(l?RF41?+UP$%zw}&eOpQ2BFW)$nZ&&xwg&jb&RJTNTARhGqp!cv z`*4nR!k=*D#$7nXSh+X;gf)jhFv&(*3VW_vA8z`orkCob1=y+khFzMyiIC^9c7ktR zeT&M;OFj)P$#FT02A1fbH6Y_&4PLgLb|6m8#tN#G5r!NoTvh`#4p98o| zFVTT_=*8g6>@P%|C5>(y&7r%)iqk9hsx_O?W&I~?_20yL zBlxoQpVO)S(f@Y+-qOdj^kvIfNlSC#s!vXWe-WNwkmeYxUH${4zzin7#}zAYKCNX< z>CIz`{1>N!B(|vBzrMTM+=J@RUONei58SHrvcKvq>P!}{_(+Si3x%;cz#kOG8k^g02*s6*75EeW6pWWm)t1zN za3#;;wEdHtUvFgl&zcNTV~f0=v}N2GmgWvbk2vu)^W zQ1wTbg;Z^5qGQEQJ{|CQdwi)Q#i@5X^B*tEzccue4$km1|Kj%esmkJKYJeZFDM{Y; zIQn6O;pj*F7>>@SjV9ne&obsP>fdvcp=jHH5RZNA9JKH_^fXZTBq+4`ztv^@Xp7;5z;@Qjj{k*C2OmWk%;By$=XVL>1vv20WC(M312$21LP*g<0^r>)Ww=P z#(x%uvW*}pHzLNht*-m^AmhYMzGsQ1Z92M+>KF zSgMG2jD(B*;}*8ZBE1N=Lw?<(!I#vxJ4|Rde!TU~hyEoTah@jrJ5kdEJ{2iJ zTee=&Jl6SdebZG}=HI5%8o*x`pMOkFJ-alMCj?`%O8Udy^E-hgMUC<|%-8v1oAPU~ zHF93ZPr5fmcfIH=*{}6o_+@(%RoDGrEe|Sm^f97CciOWidzOFJcDH$-)jjCs;&+57FKciJy^H}H#$KZKL8Ab}UR>8}kIDfFYD2_)g_=PE%()s{Xc zd~29@qMc|R_U1x$anxJ9SUFbwaloi^~fd31)|5PkxgnS_6xX`emJf{w- z3IYl(-a}gDB2NNNrJOi|bbu&_|D?>BH0-;es?`urb~vHR2FeAyBBPQE$-wYVMlT>N zGuUBa_Nb_S{)2)-2(1$H#ZjVSd+f~CAN0$qu;si8kd-NQRoRCNn(0u}@81LCthjg) z5Tqc*XOrKE87-AJxZA+me8)!k)AXGR3GGTP3`@zq#)tz1S>5qPCE(X@|jUe}8ZuoNoj5UgP=DC>NoVq0*pik@DnD0f^-QFAfozziBm!4p18rZxO(`G>!l7 zX0K_yCOEws?tmP=0U%fJ2=6caWvZ{fhj5uz)D5KIq;EE;1~YVUh}7488y20ABbpsF za<1sIaFl*%!B`HsW&r>Ff$~q?`Kd7=n8e=0Ppt(3SJ0N4VJz|A{zC_*0InfO@yr^y zafdl<{PT*Y;30OWoB*BiCE|~XKiui~!)eI2#sn9?`!a}g{6YRV@-*}9 z_wgVGY8c)9_R{U7gQ>HPKh*Lf{_uEd3lF%qZiT<&{~z)PRbq~y#vk++@`rv;8jBzH z6hGn*{TkmDe;D?scf=nyc};9odGGhEgjDo~t$GElb(S2yyGwxt4iR_64v4ElhL9u7 z<=LNL@iba-P=;Uxz4(Is&lOT<2k(kdV}Q15ex%G)$P~7|sY!KBK6fH0*K;b^U=^8e zL>vP0wro^obhr3PVbt-0prXLDD)89S+<@#@-4rz`$Q%Hc1+<#m$s6Xwz6R7JRz-&b zU`}-L4r;DkgsEhi9@4$}#KDFPf7EfHQ^i#|leT1tu~({5;HaU5R$Ev)l|5{57A`ut zwWj&}q8O8K9^S$>3&!j40KL7B%2QLsq=9s%T-_cZg%PMT0fNCujL{ z#dhzev24_pJe`vY>3n+%u^r`mqv=s$a?_dZaHBRw7!x=0o@JuH@{tQrAGDXo%$R9U zb%r%5P#d60(wQHQVKhF!B&Y5gu1JZ(pIp4j6-EY^F>Q?hA^HrZ8@E`s?Wzl_2&^2c zI!(OGe&5+w##9WcH!PLyzaj@o4IxI@G?XmqZ@BdVoC&F#_fuo=jd?BjdipoCiVFtl zgmui+q8xO6`#W@9{O}g4aTq%G88Ec`L%UD*zSLBuH|NirWjt-Ze%#U#QmrG$FHNWzu%npaT%#RL zY(1eB;wrd!faHU%C>s2OtKi2b;>Vur&;6g1@g`b=D-GXA@YCXd?L)`mzhG*2!RMKu z{_fxIgVir#kqq|#U&P->aJ5Rn-;1c~%kpiX9t&o41<$jVW zmr%JG9m>sd<%YO&Wv<*6R_+p&L;hBa-&DyHJCuyMlAqhpus!-o^gDx}_^7f>i>LDL z@4|YVg|yTP^!tnb40};OiGKb0iI3X;R@g(2cYjrfa-VIo9zJ`urtYxk^poiKK8f*B z%QNNP;objUhjK5ta=&op?setXTDgWyxhGWaoDSuFZRPUcdfikqOLiaX4*mGO@XLvh z8k;Hl?}dW zX>KDZeC0VXFpOHHz%Aa}3iQhBaAju&`W;!_rqj>6U*Uz=akg1J%t zAJ~U3c%;332$2^1Q1kiafPq4pH?WC~XxO>pV$c6K3?$hB05?B>Oz%S&zQ{(Ts3nqR z84BsMqy+dP8xfI<7>*s#m~8^9%Kc|CK}QoIe!*#}_Lx4IpX&>8M z!(S)+(e>6~U_TmRE%p(t9qmU;c8H~$;#u~ib3!Pw9}Nki6wP+BAEhS>lTG)5$&CFd zykDdQ(oFx91!US!ASy?3`3u(d$4F5k#BK2luNECitFd-WfhDdTQ>5ScsEw})O?Y-3 z;QtcavCSFLydstz{6n-yrp@s0SIZsaU(FdGj2-(U-ESi8NpmFwpYh)!4gakuI*Cy` z{X=v93_E5i#LIjOOCiqp2fwmY*d7kWP(y(~jz+Ys7PO>)+JRj5dU1_SW?%C~{#!$` z{J&f+RAx4M2))|ZvM^nO$Lr!<4_)}37<;s2zcFaar2nhfP!IHDm>L%hPoKVcSGPM3 zsHunQ`gJ1%{(pRj;K!8ky)1p$;$7$6wCAaMLfQ5^JoCLkI%d8DqQ|9uzpMTx0c=A(B5a>@z8S;3rc;z(?njY|!ad(D z~W`#$HvR5t_z*y#7Ss_W3uO7V=FWPPC>K$Cu9r>2ydIaa3L)3a;UY()lW;iIZ_ z0+lZBQ0c1FM@~P5#O&|b6w@b@F$?3=S?nr{0PCuEkk2|u27~OeAxM{xu&%o20 zhYi#ZzF56&!f2c37_1R5P+D!L0l9hWc6JjO?3xWSn zZe*gEQFX+NVc_F14)bf3RFwTb`W8o%n)5&AhkHzQ@vyGah=}lw>oBctGGWw2m@FK- zRkN4z=b%43Is$&nxSAaF`JdRY6ujf~OOp)6>w@z^MO?j z3nu2&9p(Q4tD1ckZFMeanbZ09BQw$wYAif#{72y*)du%xShv{#yzFXnQFG%@)|%zj zZNBZTOBy`!=ld9w`Rux~1lQ@w)~Abuu_+OfLUhp$SYO27^^!Ji^jnAk8>GW-BK~NO z)572Aj=XH0Dq9X1b)}WwV{iBLzCZe$u6%xMQ8p#h;=A_(*mO)C4uClN`Dd1X08ctB zX$G`;gp%5bZxs*><1N*u%b|~!tzy(Cm!g!&!wHK{6n?;q#rFG9`=0@Cxxt>S?$tUi zfVRA{AT#ETkmFIRy<*hLX)u*4Drn`wRe*f9^-W_*bbQo?wMNDp`AL7%N()<^D{dHd z(_gfba!{)9O4Wq@AXA~dm;SpAhdvnn6UJ?A!Q8tR^&OgC$TTHBb_3$(_rK4YZtdC4 za)-Y{BgDtXXNYAYUFdHz12oU>b_pd%BF*@2PJ~>eptTk$9ljrTGx){8hxJ>&^NH6 zq-{||cZ)1fduv;7hh_PHA;h3dG{-Q!Bs+UMAt zSt7VUf(Z|b3M2yOPku^tGw6K%xHR!x|KhNa}DgP$* zqf#@%=0@!bG;AF7^-KREZn`z#rem=`!|}bxw)N!y0hQkOjnzRIDklOuq0OIY^vK{d z0^tk?UWxI7S8Wv8K>5G?>0WsHBL8J?=_A?sO&<(kWQ)pWb(-WM=rT{&?{7}1X|9yo z!Q#Ja*`(4TOn@Km!7_UDO-`uQj5s3i&|rUdjZ*0WIEWNYTU%M4i;+g5a1*ta-2e5W z=pEbQq=3h#2iY?o&Higxj*aivB-mQID;Hyl%Hg_aaR~P;PK+eF2^rkgwqq=|NU2>*utusfz zvb2K>Sk{cI&Bb+RO;uvM!ZWBlta6-!Z`D(w2P zV}0q7IJA%v+~QqvWXE>UG0=b44$Eiob|`rK(}~17PZpl?T7P~IdDlNgz2VY`k3cdAj%5>%n}!&>?WD zosRe8va2^2HFk@S`gF6}gyt4PR)m(GRqQ`y=4jsSx>2>Zpg35~RdL7pZoKiKpX@c~ zHQ1>EUnG4v{i3(Dq5b&FB6k4^HuRBrYXpL=FQs-!nQca-z|7oL`dkTKADhVsdDbao=Zc@liv<{%D%8uhisko><^-z%nfquC0PZs9z-I-?mMRkS71Aq>B8l7qQ9@ z)9AA#+GrMTAj$vme{G$ox_ti$52ICUvtf#8K4wArHl z)C5ED4zljT~G{l3BgRj#utgKMLb{qA^< z7TM98!HKO|a?sWX*`Z8(MZ{SDeVN{@L^6N2!ID*nk@VnrEk!~<(69%^1^eO9;yl`ByJ{hS7Vk! zYSdsS3i%S<^K1Uw2>^%$A&xRO>{IEuBl|DLkr}v!->w=C@X5H_2!wd``)-l8aUWRs zU%UksCkHq8-bb4J`9=1j-9Mv8acBSk!I!rWS^Xo$bNmNm8rDGvJr4Ix6!zgKK5FE% zjEig}g&(d!4c;3MgN$M_e;Y}-6dnTb=|{duevSq5bCEb`i6+5;{u^seeqxq!CnKr; zL8C>|dh!KG+|Cpx^H=;{qS2sRxFOEJYGk-;@$aFp%3YAYV;?QMWb5BC+4fCIp+>r| z*ZM4QVB2NB;>QPVicf2)vGe!-h_E5$D@y;aQ)^DXdX8DMcN_BKPdwwFzeX*Y%c-tC zNIesv^g!7M{1p!dD3z`m(R1STNMa(A$IU<1ONML&yo{Fi}<9 zJh681>p8FypsdWvnTwJZnGb%CDJiEL8PW?$DIw(`QcCia^6k(+!Ii0>qPz|IQcFq$ zwH)d6hrCS<>#~yN?t5KX`bgoAw>!h{1uBmYIj5DB0@avH3Xp2wHGBWX(PGJ`?)`w^ zy&-t-5xf`eMFnolb@I&ty%`y3IGz7%YInQMa3|W(tD}$7EPYgpv?gmJ)WWVm-wcBs zz61tI!tfUD4fy3sh2bs1)>-Ybhijb)a%Se9 zzxt;32v7ZCA7ZZQcZspH5A%c5?_LqiP4-6-!eI~wgV-bO;%iiKkX+};E85}K0&Spw z+FfRHDM1{C%6O~s3&gzDC6C?*h51|g-eo9`ZXG)?yR+uj5sRab_0-fJ#*F(2`d7uj zyo>MI_?JI$Z|&k=E>=pGE?j)eDj<{p>g8@5v)3W`!NK=4!|!y>wy8P}PkhVV;QNp; zx!g#BQ}X5JGKi=?g<(BwxPR)#u5n=Ud9uSea$9DHMb7y1+)UpyeemP22J3_TZw;*R zl|lPwRdVHF^MWA0=b}hG8}J3SmBSa+)*r#sM4l$r58&yXX)QdTQ;$*YA|M?-+&^|m z*O2;?I)bUF3^qWbuL?{S`-+g#TtIY{W11s*6%+F0f*;TqYg#0T-!h>{6AAgYVnXp= z;Zq!ahUYJ{^l7`VV3xbloPDIxA+yE%r~Kc=~xqwwb^3A6)J>FTY|7W)&@dx7Fye z(YeLp;$|`?fdHLUdb`_e1mdE<^C%Io3%ItXK_`7#25%2s>Vn(s@#)#7I+4d!hkU+N zr{-r|$*y#y*)VuQtA9i*22JX0Ad`3{q~jvE#hMqll9riZ-1X@-o&^g$hc|?9;r3npVmdzu7W_?VqW#rifxQa;1hoqmNo&>pu9nA zVsA8kvlDc0F~6h$0+~-{%3W+5`E>`l`X%RSE=?zLVoE9-njEOB8T&6}IBc73s^?#> z7I$Vl<-Cs(me0dP9=?h_C!h`&@huX6td)v$yrng&u=)3{N0|PCZC1qx-cnP*uY5aC ziQC8=X&!h2?VW)C1UgKwajB&Z+i8Dp?O-PXuOBKHWS@c#eoPf?|62KxW@IwEg?m>?grbj= zi~Vb;nku;~ibcS7kqPQe->cJkgLgz%Zp%BXdD4Cb#7D0iSwk5A8V=^aAznF8`v{FR zz4+uDG!P$Dsuw|8h(0C(fXquT9p8N6enqK;j5=FD{};G-NFlJ&zm2Cz8~ehAnc$Dk zQO?OPg!A)~qd|SF`Ivv=tiI^9So5RmOC&i?`on0&T5sv)2%jWtXlj}le!8Qk;(ZOT zqowp+;Zse;-@T>f>5?%RL-r3C~ho0R$V`xDv@$1q%Rh;N)NbC7y=@7GFZ1dSg zsd2PUy4UzMfRDC48LN0__P1lqMs?oeOM;J`E~aC0*!|})pyMVwdUC`=L<-jDiq`4%1ON zxjM2)$(Qu3=7j}JgOKUKY&vt4R5!A5Be$a8Z)d6yMA7&8MR5{tb4V|{z}yxy{QqCcUs?w>PxmFD{p<2l!)knF4coAn4d2O6)sT3whM^DM z>fN}_sINTIya<9C$AI?Y{KqNLiglj3Nvrb_tqZl;&J(_LjNWA4SaT1X&crj4UoNN- zHYRDPa3MwvoC98ztKvCPx)<9Msd%|=plU3ax_ScpBw>%XmCKbh6q+0l9yQ!7?XZju z4O~7}SJ*JGC+gwH%0;#LkCpHPptIN_RWpSuo}c@*XksTDy2#45GopicatB9mMLaHK zS;k>!^s>I5i?4s(M>=}Q3V{&?Cb{@e%!?K|6czaAVY@aTML85nM`@luJJi41ekr0@ z<)6!MJEHK%*rD%`3Q}@8&J23H2d)1vyY>I7?wR%fPWmAB+G@YI+q%~-=8_yO`+`CB!EpiSrmx#T`wY2i7J$ zE^Y#waIVrViln`tf3TU-U6L&}a$oDss&pqcuqqL?x?!9Ws4qVZp5J=A)ukn9_ z?$ic&YS24T8)5_ns!0y)8EZbgree$N5iuGCPupUNtqxUt?h>lj`*S7;ReX#lp0pcu zx9*KCL-9Sf-0B3t^a;tlzQ|YCm|w532*T8GCxjikLI^WqL@TxM)!TpD?8olB74ir% zGr$)i$K9YC)AdKQ3&ej10}&vu_D?c>p$!f;jE5 zpnq=k9X;%4{re(%fIx%!`^=(~MHdBC@f~3(yjR^pH5>mCFA^UOjxbL|IMsYppo8?| zW*JqS-we_^l6UGA7N)M4xSwcn90;6s;NPiQP~2|n+N0y2PasqT{F816m=8`N*u3rM z<}GL7fmBC$Qoj=^Xxd^o3+F76cstD5%FLXt|CyV!??v34#qJf(SvShJmo^w7U~>`` z4_8A|HDPy4z5+GFHL|SGZnjps!MS6(24{b<+Nm7zWv0$B(>Sl~rfK}i>6)W!G)Kp{ zIcj6Uv~5Yh6L@;O?4kwv_rH)CkB|b{XDNsfL?al}f3&!BL;tC{$@w=Cu&{s+6NJpV zQp1v0LnPd@k^>K{X(j^Lmf0iKCpxw*Gczy4O_Z65f6JL}YJ!n=Q?nydFtBM#4p(sT zshXGmTfb_D75GdCtX%&{fE5TzSn2JbcZbUkRx1WIwg=XLn?qCM?rZXC+O3gsatQjal9`MPiVRX|^m}I%+e%+ua z6tPo|t|yGYCf}bP?mWIXn9;kd@ueAhm6V_krJj%-h;U%bjxMWXN-tB}o4q17P{j^N6i_sQm={PvZn(BkwhBR%x_JGJ* zl>4CVf@v-B-Pc{WzwIs3H8iw;P7bf+%}JkLos8#{wY60(-l62VJ;G8)2q4P`)^gGZ zJNPIjbtRrDu5toXMTYL-y34j2q`D>Y?}!mLbm;bI8#gMf3XZhZ3|@IwGOs64%=M7Y zy`>5Ajb1jeXPR)N&?#|SbPJGt1)uS^zvf70s?gf0_mC&{M!LHvrXAadHQmicjZ0n_5R7^&KC|Tiusl2k^yPdJiAQE{hfMrK&A`fN)(NZCe*hJckNn(E&n4 z3|aA=G?&q7OxDi%rt%yefIMfMz?Gv+q<1x87ly2XLGKe5Mkl6`N|XGB>~aQ|GoWe2G+;eW5l{oE{Vohcjq<`=HC-;{!P{V zn+&a7CKg;4h@vzhuu#G0|K!KwzKfcOMNp5j5#E}8yU8bdcx=E@cqB72)X(C0^ z`PPKBe+uoF)NnHS0)VbRPou;j9chCkEl0l(H5#PYoLn|uqk#->`-dZJ|L_%Crw>s- z8aLJVYM6IGj`~)ZQ&$jednVl-wGter;JPFD+pWGZn)uA*law6R^ucS|&9o#rb+t?B zSx>C9&r+UyEApDQy64w?$XJ2T`YE2~_tG_2JRPUm@sd#TKHqkujFMu8m`t z1BqPv+1%$+36<5idi!=2ZVC^N#DcotmNV)>OQ4-8MyOdPj`QYgEvg7VFJ%HOa9ed2eYBHCYvxkhF*TE%jCArc(Em zr*5E-x?4Ze>1U!9pL_8?@cm3=w4d5((!I)}Gndg9!C{pQ3@X`Ep6;ni^7#XQ+;evQahmWp$=?Gy z8Y*hLiX_0VWdFz9emmLuq`cjrJ5YY*~ zfbsu%{{YT&i@c8zUx+xqV7ti;n)WrfiUZi=5_!6~$GO?Z8TM!_;^OS%c{~Q}WP&}4 zof!Q72;P?$(LwEFj?3ozsy+H@v^bkun0@T#GQ<+E`JetspuDUadRgiYrM{L;{X~z+ z{IhRibxjVMek&%l?uRL9O!??#)%}5O2ghV$iTB;aj_>BStYf7ZN?rvgUmIEeY_Q%( zK7E55891_&M}*wGhRD#>5cu3jOab$ne-+I{6R&dF%>GO`Od&1|3JYyy;=OP5LBJ$$$zAQr0j96+b)#H625M4~MQnkWm5NCkFDv(_ z)X`D+QM>Je#cyGFOHEZF&Q+fJK}Wq$NBQP8#wU=W%ET8djj0h7)TF+JPR$Y_o_-1L zn2OG1!uC#>SQ$c8?gozIEJ{V%o~xI(E%k_&PryXbt5;UU1~M*p8{-NuEDl6BZl5UJM)H*5qe9eS_* z4fV~+M`lm|SbkL!epdMhchNt;idejz2qSeYVqG}&_G|KUc`){X#4bgHRPMiF+tbhu z9QrEvH@s)vDhcFfWiB$ZG*tQDn{#!nFZwwT<` zR`0%>*y???LZhW#{5!3KE^0!%5luW5Wtw*E2m{8dSGK48%w-G9Fn|$2$Z&x&0omt} zzZ=<1{l@As%O;iWIdj=%WtcJ8jL^8WC zEuc$Cad1cL4T*63VXxdsZ@xDC%k(BDMq)joKl|uRTZwRte&F5=em@o%;1{`QqVUT! zY-&r-T{fu;99ILC;P+RYD#!w39t6tLd*;7|@&L$xfpMYKjUx(Wph0MEBSs=-q<%I( zVikM5rN;v}ccS$@Bi%bzvC~`HKX@Mj=wn;|p2vNG(F!(KAJJ7t`m)loRq;1HmFQVh z@w&HkgQ1|c8!}dDFFNkUPlP$D-_^@5D;<{|62?$Na%PetS#=60sQ;bbT8rcURd-WQ zh#@r>#1d8fKOg17)O%4bNI!mpe+s5;>`(G&i6w?QNm{fg`RbKxdut}Lofx{=Preh< zqA7DW62D(=9*T&$(Qn}qNx@&{emNwF{@@y30{La5e`WiZi+Sn1KxfS`TA|Ce+h9Y3 z?#O>=hUlQfGHu+^HvU?t%e77qmzK9O^>${lcKlJ{qyrv3Q_9c=;W-GOVGI$IvAeuX z`w&#ny5QUBx9(Wm{{*gVXI=D}9i5Vwm0-H*P8 zZUAV&W|09V8w*<*y1!osNKYz+Pqi zvaY&x(iQEIpQ;YJB>Pu`vwyvb7Rx%Z_}v`YRSH#~l>kig)T~WGpS_@Be>h|OBy!wO1fTpq`ZmW81KMK^~ z9n&Jk1L5PPPX-5C2so`Uj-Q-qJdDqASH{Teg)_xls~%TD1)~|4YGpC-9-h@(yV068 zqkDtU+_UQYskil>^{+<;A0a^^w{P&Tc*E^bYqU%XLE5A)eo|wC#zctW!c>rT4h?`T zud$CF7WAg~?;AQXxi!6IPX(lH&b+I*^nqDJp6Hi#2v^>;um5z5~m643IplU~; z&53s7v1-Jivlz~i<=pB!cJ874J+8h-l{<#{c#9J24z=}|$6BxPa7K`)Z+T5=s?hwK z=QX~~BTtjv{Ec!M{Lts*C>|TUCpL6PyfA9o0D2`L9 z(gsR|42I0w7sTj3ND!3?Ehf`z!K{^oQ7b7a&Na2s>6vvyqREMRDzEbXYi)H8t;%hP z_%Q_-4;o1|lKDSH!Lv&o3dSDuZ=t}tF5fFb*&YRBk?sD^qTshuH_?($OA4Nj$J@)y zuhb8Chsk$?=g-S6ukRjhTOUh~$&FR4oQ-tiM35-=DPDJ^G|PkS@XDQ(v4;m#IO*cz zJzBy``eZgoA!BM?3}YH`w0h#kPb1VquFT*F7~rT{Q=QXxoQx9PrMq2EQcctPMOD${ zWGwYtX1^0sd|2}|)%@B~9cy-D9}K%{PXCVEfV-=LBgJdjR*OoHQrTZn)>u>rP=a-) z9b=B=wwjW9i~kT3RoD;XlpTgA^(J9_T@(`Z_-o_AJcj?Q;5qZ*x4g7SHY)h1cc4W; zB9sq{TZvZmGT*ycZP?c$eT9aLp?_3Rd`)fShTE**6FfQjXCb`}HRSBncOIX*BZ zqHJr%)M~7+nJg(a?u?etQ12Tl$DeQOOZYecYg0LZq;rU!0d(+frJ@Xci{};LqMNhm zaH^fhftF%}0+*R0|G7m1f)k)>Ifu>U+R6ewMdHiX@l&wq7|JYf8{nmJ_9%u(FtdFB4yF2D9{(Zn^xcB(8RCe=7x?Uk$Lh*B&4a?=3l16>50`d~&)2H8b6)( z->Gy*bUFMq0DXX;h}xN|79k=Xw}*3pnYz+>KG%+BQ876niiOU$KU3Upo?rMihXJrv zjMD&-VYuJhIgkb2wVsX>Qh5q`8n-ja`|6}W`NA*gTI#gyWXKMC=E?Q%2ig8HKg=sj zaNGQ#yY!Ul;ui(|1NA}y_@6Gio$2?V=6Y2djw?C37}v>eT+4*P5>-z3*yH(=RWDEQ z1%062;f(7(2;Iij|JDUx)a4=BE`OQ+m7{f0PxtEIsh9u%>fb!o`{nxAH04Y5Z%%lB zIY<@spm(_c^J_k*Gf&4~{|YwNU47Yn#z*9E&EYfiNsng&>vx(pey@Eroc>{kWI8-( z|GdNPpTC2M>?X;R4OuZY(BH#U!~#%EvKzHcjAOf~bz>;?Dpt+5nPhWno`6DHScfbF zR|tiU59T2_%s5<#3APiq&pQA6T3b*9p6DMxFW6@3U>mVVj2A5oltvhYHW-h>y|w^# zbwS%1Tou$~Ru2}_=N{w8!GWP3Xs5sCP9bk)q&ZP0SQ9Vn8r4u86u46*M;;cFBjc{w zqlNaVBFtJrUTKz4`Ba?&#FDxbyA`+S!NCHZOhoR}q9MDE@j@#C+Y>9H2Grt6{0yV1 zx7gJzw=EEYRkq_(V3}ri(oXa1HwSA7b)@^UjrEV5>&Rz1o6Z`G)z~f4wi;#Cmf531 zblyF;zs}zbFsRxiv_RF>9TaKqsr}#9IqkQuk;Ie&Nr`80lY9d!Q8P#PlIL>jF~TB> zoU>8a?nwkx7dJnVuOUwkJC&yV-V$&O1HA_7@ju zI<=$)DA2z+|7U=(C^HiZVhN-XYa67Kw*%AnYrfv~yh%-B?dU+b!HeiOxL@HCpf&n+ z_bW)>@nhg;!*wS=YZ@NnFZ*lx!`BwXlB2t|80D^%ydWn^qu0>JQavZs|9?dg@ts?y zkgL^q)ruZbwN9h^2Ohy`iprqd%{K}8bh^mDxL%!RpKvanE|4eI+>y~_EhM*b_AwSA zZF4x5FV=(LiE2q21?aXzBlvstY)cQINa9tdlwa`Y&Ka|4KftxmVEV6NSf+i^5A8>i zQ*w=f&>O4^+r3EbZaGXn40rP)$Tc^r6HvteN8OvpM_pb2{|OKX5ty)P*fi8=iEB{Q zL`4%8oq-8Nu$qcmRBEY9MUy}jgun!3j6>6^-Rxpl{dDO_g&68_iXpvb9>-lrQWRX@oU1=W1qx9!O7<@~8D#lM?#3-kWEc0>P|Au-Vt(&1R*Pq9z*ZG%;;` zXT(yC-X^C5x(27d^P%YY$po-yAjI2Mp!nlLZv~6a!4sovp*Sa)qE+-Yfbc)-fbfD* zT_HS2wK}GEHg%bA$(WwaumHe4JJ@IG_Fg!8o(TWB zZ=}Z775-=!#uXjVgaYcqO>rpv@563V;o4wa0sLzm{LjA2hre6Bb@1=a(zuLap)@na zvf!Vl@I|)(|9vC6!v8NV2LEVFf%hcK-bUau-0dzF2meG)2SWvTj2oLwfDer z88oCCvY99>CBsD>&8E5N`!~~-8|X@gi#p&l_``A0b6r10bA#w-7Ofc{gHk0H2m?nl zL_u^wcFSqY`QO@ycOAQTr^X)0hc)wj^0VO^jX-|Pqgn*T;EqzqH?;#$rhsp}h--V_ zzeqL1#KB%+vM#;k)rn0@f195^UoCc^zCJH@V17eLha|17gnrt$vp&!V7wKuzvRu{) zNrshF3L6>XogFk|k-bdJA*r8cny~t3`nr9&NHvVlKDzSalCxHZqiW*`tmT}s9fmw| z(f{Fz;eIZ92cL6D|0ws@Sz5UZSFN1EN9jboCY}fcEb<<$@dqnfEwp2{()ou&D}KW4 z^ZQU1>$oQLWvt_- zC9`84bLvm!DzyANly`lL6Wg2jK>9nDNAh{+_0yM1t>c$^;kR>K6N}PCpD0klH%Y)J z|JZVFVjVZvH^e&TH=NtlSOe*CwD7{@cBh&xKCW^()ZxAN7n?&CK*b#D;w1C_UhR+cgHR{`Sn|k>!Iha>cIC!@ z4>aYEzlQEFDN0^O>~!j z$sOT)ZZIKmBZsFdEc!wiC_bF^b#pZJ8f^e`qgvk2wj>_70Z#gXG_YhTl2 zUikHSZmFqSKB**A-rGB&Pq%+E)=^h~k*5AAoBCL>Yb(9CU*SDLylX32AKtjABsroKe?Mn}*zwv#y-UjA&G5n={iVp{4+*0g{nBB$6o{r>YKfLDb-z%B5 z285;Wm|Vtic$m>hb!_8T_QZqy;#S+lPweBHm)xxQ;oADj*vE6~m+&C8{7=}>^gdAo z7=4>8A=lT?CE4)~vZTE?{%rg2v^B+zmjyYUXUn|5Q?Ryu=3AlqVf&nUO zuF39Svv~S#9IcDKefAfj++PoJ3a9%8fyTFRtc&)P>wz>q=GKqQc{r8r zQp{e({yvOB6zt-XwkK!?+Fqm6_M*#}01f@5Td(9T=kuDredJu%yq;z2K=&Ailo$NE zK>3sD8fZaF=F;_p1J$aF#B;Ok?WLM!12J!)k2PQL)jw@1#pmFvl!}(sLyVoC9Sg^9 zP7VbJGMKTXw$+_%N^x4h8>rUqqP2{EXCuT^Y@**%@x}y(GIKsKls{{|F*Es8`jTZP zFMU>YC@WpQmKydEtOt1nC%#yBmE{d!Lu=Z*a`zW#eZV1OZErG;5^WjeZM)VVseICm z)X@t*-c7V(OWE)f7-K;8HR6rKJ7y7%^adqjA2-&c#P6_Bn*(0YT?f&d#@{{usGRsg zyj0q2yL3wv1zTGyKiXIv4o&(1pa12&H>Gl)-w^t909l*Avxc)!aaxxdaO%TdXTUw# z;=B(xD5O4gU?c2vG_7MS(c5_+JQQdGreFPDY+P)bO~L_6{jmpQ^}7a6L#rNO1R~(s z$fO~Iv0q5rZw?1}`-+yDpej^I3 zZK7D#mQA0VSnrV1^RAt^vDc83ildk@QM2PexZQ9NZYlFNU88Astcx}*P9D=eD6xRk z=G2*V#`|Ueu8{n0P-lTxPn~APcW*}Bo{UOekhs=x3k4m7HG&8;dra0cN7Qx|s+jBy z6IT{yh=n~yOAuuiWtg1Ia;fQOS^lqMf*|a`{}r6^7@R8V{07J`A&T(&*xScM6BoYM z+8QDE&io->wTk$&01c?@bTRn$QI}WhTd;P9|b-*lCS*(4|l4E1- z#6Q$ZNVOBPG@T3PA8$g<6S+=)*51rRcW%Ea)Ldq-D|tUJwER470uNN^u_@8m`?<<~ z6mNq+k02I5d4he5r29~k4(w~{H{DjF_}>3E;b#k2Qveux7$z~iT_*9wEMaiV)!^{m zBODI(y%Pqz7W#B?n)fiv$DKVf0K8HzQ{(?QyR=M5y5k|{Wzk8opZSr?q1KopuP_Tl zfq3&K-Px@N+S)zT*@XwXduP{guFCSZc&A$LyZTxV^>tb3P__s9%r9x!hj()Q@iu_a z(8pHvwTfBj{fGr=yUh}}iJ9oP$UV-ISS#6l zrSMB%#06d0;|9|xY|3}s>Z7*M`y*@1nUSQ9G=^sKXN`{CfUmeNTe6hEsiOCyqHIoZ zlKSvK->y`2Pta6>cO6ZA0w*Xd|FW=8EfoZGxk(Mb%L(9@@?bpvWfzoJ#B;ksC*R3K`tFnUK zM}29<4Ha*q=wV)VW5a%U0G z(q{!pX@IWrrY9{1CA55{IA&ViW-Xf(5MdDy>Mxd}OzG)_piBt!dCrCj7J_mcE>`6% znSc}yYw=?c^cAhxT!;FEm))%Ft-++8bVacK(K|B?fg2N=6I^zRSg6mbwi32IvsYcNqI6(_UxhR910`zndW zZ0?mU5AN3+Yx}pwH-5f;?oD&fj>N|mY0WUdI3paUsS9rLtb}GW&24BB-LrUS>jX|4 zu@w>g2l<(~xnY@2kF-O^eB-7Fln2Ch!)0{t?VcGNx+(aFI=|%t@28*bGzI+y(^3&U z`)8O};rN8`$|*H)SvNVo+BXj#vROc?orO9GF=bxE*=n&9f0Y*^6TFgqq*S+FO6;7C3rg>+j_ zC8ZnKQdgLq#1kh!+Hc>79Y;lsM|EED49pBK7peRd?S)TZzmO-bhhw;YVO5ZVu&OXQ z5B{w6z0h*GgUr1{*22tpdw6Q^n@5^{cSdX0$A9LL`WI`zc}WP(vHlpY2(&G*0o2tO z#@grCAEEpe_z(Y~9t1UOwd*f>K-WBeEns^5Jp*(;Rv)uerLQW`THw)wuZ@IwG`6Ae z)Gk_si~G4?YW-ReLNcj<;HdYi<{S14^W|59O1BBZWc}A|>PNy^KHkl@D#dsZX*+{f z-GSCf`3;Ry6Gb>5pntAqnPl<|2QP3^Dcg6gm9w=9=-g|t$8^c-^imj{E_c^-m zf(6ZJ!-9_imGQnsDpv2;(0*qwa!CHqZT01u{GW-uSjVaKbF0_>j-yZ2Es7M4`UEQe zkbDiWOlgUd`|~BS!OmGluSHC5s~;EC`#PbeNBH&r(63kAt4qDf3sGpTPV%3fqu@0T zc^llcTB&by>I>Fr6)O1={CJHWRsKyJwMI_f3s7d~QIcvVJer*FZ}mbK7)u<~Gxcmx zUcf|LOP13_-W4C8n&TCzD^710gj21^v9X1zxM|~XTk^+_^Th)_EllQTi2_^S4DutD z1t&?DVdpYurxdl^Rvbp5W6s^zh}UbiEj-PYpC+b*tB~KbPA6;d6WY>KY3EC`{kNnf z^>m=X|Ht(w=c|6$BZ;9sdFb9>A6QY4O*?8Ie@%cizW%H6#zV%zSQnfcZ6nT05M zaNBTk=U{1x>RkxcSjWYo=EYpdf6_58)O~V(&Uu%F}`Hmlfm1K?!}Bs=YFnEje!j-~{Hj zTJdcNG-DN#O54bxL%s>C{Xsk9ALBH(Fz%PVlK@3BPlHGdEuMjMM1xu^9@sLBW8ZFM zpH=cL-6n?S*5LoN_gA|2I)T?af<@Hiv#!K3GyMw2bI%HymiZ$2Yntc>3Ue;|*jkg{ zbVci_%<3AX`_R+Fg7xe6SE;Yw6$%CQy~{M;8!GI(H+0#$HN~#FU$I{)In@<>YdW!e zrhi$TTA~R(rvCpzwH@yYt-C1b|95%s#+T6h-tPTX>G3Vr`)gd6yz5ltO+85rJ&$&* zh0Apx`mJB&LKQJ)pBOrVR;);cYs9&FkE4Y3FZoSZQ+)vILEH;eYbxEab_?S5uF&+L zu6KE79mfCg3hys=?{5m;|DN~2XCVJS+Y2CV<^TGi#<&2bZB`86U%>$Gb2Yl&-Jv>7 zK+%6!qT%+?;{xCfdi7ToP7H1GUtMjaF+*>*x;Gn2Y|uK{*y5a{a>>QFS7HwCu zF~__W7vZhgE;mGV{0|Yga8mWrGxAovk;*3lxpveNALnL@5kKp3Z?i_AS;Bnq3_^jY zM;?e8IhAYW8>`WZSTXK^37_B+>0`bStuV3~^5x&oqgwC3lW^YbI%k_3KTOB*T5YaZ zB;VCvPDk=3YAe<7yiOr~F6Zt5>bv)G< zKx&|PkTzBp(I58mBW8)Nz^a&pxM2@UAk8)6`*_83LQHq+nhc6yRhfKE&8P5S)M zsOdAh3`BYo1Nk_@KyKZe8AyOWH=x5s{av7*Nu1`h{y~S#5n^8Q*Nr$Wmp?#(%griqUGdGvCf5A;Y=Rdn=wm+9#rKyoD zz=f3G$eVS6zITuDZ2P+zFG&T^eUcL6iz!aW**Ys*~cu6aLzLf-Szj5Bwb znwHbB!2A2;Y}cK&pIml?(3A1mxB5~<;(!PLntiYSaN^bJcgiKn%PV>1?S+K2T=)OBTZ)^GcjgXD9SKjGU z&b6&Bh`SrwNfVA!KboDlr7PiFF*%!XUU;ty;ka;m|67Q_)#Wo*2uB1H5K#g!tPqYO^aqAkG$#F9D=8iN1Xf_NwT>0CVCqmJl&Cl6C4s-jO_ z|KI^9*r$$2-^90&gSP%=7KpX17Y=;FwUa>m_IERAcQn2B3Lm$pd0(686PCs32ki&- z2AgUY621^jdXg|W`Wwo)jM_!%kZpRA=#7cCe`i)!yFRT8X5G{J$w8M2yq-aqT);tE z&ReWdm?fTzdLd;kSm&8**Ks=9N6T6-b(x)uQC z-yFJNAb$teAFb>9qU6hhP3*u?3Sia6u+Z{n^(dfXTSS{eFwi=!p=q(GKBFNz1}|e> zdYQj|#Fe1ErwV9apXy3ywX=-Qv=`x&Dx)(kiCc)4Q|DN2Q_yM`A)+-Uf`JBh9N&q} z>50Tl3WIcqZ15hx&?(HDH5dS*6<_mjvFt3sWJ)b*H2|R4p|* zT~9^c@=0TJ8t^m+U>PX?2>yb?Y%z%)RTWAo>U z%}YLZhF|YxhrqA>3kJVPux-cR%6J%#e~CccYG4T5?p;)c>(9^P_{jI&-eGutkwGY^ z?LXo9ZCDZip67qDRy?1jNncff`}gq9IImkRfifZlqLPkk;FKSSok*-Ar-3ZnXb|%M zcGe&6I*&Ql$Hvr2e>gl(-Fd0c<_o-s#%Jpf=~)vr?BvERz15x6<$?4Vt`_foyX&l8 zrfSJ=O{&YxAlSsmV8gB%TN2ND$&638G%<_!5nbpd>AtJ<3;JdqeQ3b ziv7EwQQQ|!{!M_Dn3pAzkJ*sm80e&Bd9v{2O5&5NKyX^)$y>q%AQ_&|_oaW%u_>3) zc|K9&G5WtBIB3c{C8;a@pWB80|JsHAU-gw``B}d+M{NMPO-NQqZ$PdNK7k8F7_uS(DS5w|0U;sa z>}kdR(5j8Jg#VlTq;IP(U%bn-tG_J>A%M&D@C^pCB4!K*K9xj2`fNb@O_u+IuY(4% ztQPI@P#|g$?eoQ%f;Wf6VSra6AIamIfqCi+LCaz`=)Y1_D+5;ZPzBAMklmck<)f@d zETGf8cgwSD3wjeMsKqH{nq!Miw@rr$Yp|i_x%kHdJftnyg$uJR*ijiiRc2E4YMu zGGq}T@azl%1KcKmYPm)nRyz}q=u7mIZuTZM`?uG+Hv4jo-)w>R3zEKCvrYl^#nA1^ zb1h4Z&z0F1;+35Jum5Dal7E#YZ;7?l%owmT9Ygo)gX1Sp*QaO{1oo) zz&d#OLJ{Nttiqs6PO(;(sw=jHR{feraM6cW4d_t6weg}BuKJ7xt?vrOR`5QERZs7| zIOFZ%QY#MCw-IiuBfLtJJYsGGlWi!ClHi0|Eu6B)E ztv`b<{{5A%UHsFuH0poF8gw@557`J%j(?r)NQ$&OzWhJJzV!cvia$k+t`+tK$BZ_V zVJd+>?x;AU1-Z`}dRGhK=cwg(COcF+{XL+1S1zbK_&&>Mid5`!xK%vVsxu9@Gr;X- z7|Pe6cAY?;@f&6M0wv%X8N-=5t@hh_%MRvDSZCg3DN@46T!WtXWTaYhiK@y%ZvACh zT7tByPV6MAmNxF_3bRMUX*qGHYbm{9EMO7ZO!A1C6V{2zMSrVsZGjE-CcwP zb^GN5eCaLY!`8!Xn6Ri`)8FqKAZ>Bd;Wun0ZzY}~y&m25!rygWtcJ?M744x_IxdHRKWNn(AG(nt|jra6Z!pGZB*SbBjsyQGJDC zk6}cMbn1$(cy@H?vH3?;#ov#;bxb7wL3ru&O_Z+sXkBqMH0dR`L!!g&kmyicLL_m^ z$F11{zn0WXKR^)>EoebCj(Fe*de z*%%E~liGJfDvv+f^0}gNLMSJ)bbnLx(K<(uL)@_pQ+>vM1O&N`?@h&+J5|l z-W;ZVE68vNj8PiYW^4%e&Lw|KDVH?%? z^FgkTt^=y>*t+oOePMPqcn={an>Q2vwtVfPqZNn}27Ya~W9upuCf6+<`&IL(c*C+^ zQWv7fz1B1u6STYsQ%wAS4bdLmPQ$F|`lD=L+@W(YE4=3iC6CmAN>cPMN}np8&JCce^+y1IE>Dwm)?c%Q^Ru{9xBl^ciWPS5=x`5g|X9 zr?20Bwzn}lVz|U=C zfZac~{fGG3T9wAn_dop~490h*-5rwDg@o5tWf3?MLQAdUpZ-n;g4$UKsgt_E63-7EUC`b)144 z4=CsjeMvgM3=VxGrAl>iLWr#?wE-IT?0*}OY-kcM$&JKcOrA?fiq@NE!#_xtuq2;C z$(gE#!pj~i5Gy0AN(Br(a|qDvwtqxGR{3IoXeVLc{NcOaP4o3`EYMlQR7cgAi7L zRphpHO-b}3I)SLX*O?y+vEEdZ6=3)RsnHG3^fA{MkweZ0tqsEkr~P^eE2`y;L0Q6^ zxF_s}J-uxuax%Lo{!;8AA23BZj18T3k5zLR@GBnBkAGQpOg`=5h}~Ej=98QamA2Wi zu{QZSi)51%mwm6QseM@Jj%J~);`z|3g+heD9@6?(Rnx)w4aChqpZt)IxmyrgE{sQ8 zzM+msTkc=Wk0oAsa5YyXU%17JKf#T1_p`;@8SCjJ3=tuq*Ygem9>v1(J5^U~{CndC zB{ClbHhDeltm1vtnU-Iva__&7^-X2g`MVSf$Cs&y9%mqYIPw&H2*0FvoH^qsa!(K zg0h3pq<yhJl(BID@I8J*ks+HECBGIKJ&q&|n+SMwvC5tKMj( zDe^lIj!&pvd0Du5cWC+D_L%~5rjqAnMxjg)TyJ%gWx+P-C3Sy;UwX%+dKxN{IC|t$ zVD*&eGFY`a#6DF2BOt4fB5RHtE%|h5BpM%Cw2}RVlP(Sub}_~GwxrH6{wI@Z9hp-z zmLEoCEsnq2Ly>(uDPFr_!j#+%6Q&suG*a_jy4eMf5pO~Z@WBkjx-ht2)E9*i#j`zC zsEgzm5U2i=3^s15CDB}1@)32Z9~xtRRiFzc>PQf}FSP1wLWAt5S3@hFB9;gwj06eo zr-YVk2Jv0y8%wWa1}AS=_wjmv)CH-fsx9^fi%D{%VMyitm^4}kP(-?3qh`Njx`*Pl zT6S0lr?XdH7D3s&y&qeRX9Fa*8b|OTM2LRL;p3$oXZRisb+l>p>8d<1ouAH~r~P)C4stw)MJh0j&@=7WtDQ>n{gHP+4{-Ol_V ziR0x=<$Iknwd6Td!xCbGXWJb z5GF`&tgyw1SkdK z;87n%?@L~qL?Hf@+^yz4%@zsif@!JH87Dwt5(t>&gJLZvXe4g^j>ISJ*q`dlu;#N7 zreYmu5zdIh3~H)2Oo$Qy_t=c7+)d}s@qasvb)*8A*1d)&AXqHnjPRCdAv~>ZQv6l# z(yf}6KH`ZrJPd_cZ<0TNH`sT(o&UnzHl4d45UqU>RGj=``a^Gn4oLl^R)UXOlc)1l z)9Q!84NT!6e@zK^p9}I6bWs`n!0NuTyjoeuHvYG*?$QjmK(5kvSw>7Av5aqz1iMFV z5WRkauA-Fymzl)VXW6V|a_z-4s;c87hodPE&)$r_?hL4-6;DgW^C?t@Lhmahq%RXB zPqN>N=c94DSD6!9wwBFEQ6dXVG5p%X>)z-US$BYgf3}2k4@OHjNbA*nL_`e18NP!{ zg7IVP3vn*!d(@9m!p``HE!G69)WTYjPpd1{rYLh7j?6-~@i7Kh?$lDSGh0`|I)iJuDkECmWV{Q)eWxPC`KF;W- zkCt0O$Jun-EqXQFPdz@o*Lh0j=u$oPvEGs2P4?^VVTLtlP8BAXV#vrMSuF?v*|q#? zn7Y?CPu1R7r+V`9;dx^j>?BvG#HRhXozEVvFSd$eFN>#VB#@kO5 zkF)gEs=}qy+gRkHP4pxkZ6cOx;vhSH^?17OtzO?%9Q;_dx`pb6)D`eYrB7ze%umY? zZt1Jdk>ZHV<*@$g2FI*C>$g#vAFAOKX7bOrqTSUg-YLKFkBfr*#v=~tT)uTK$Zxj$ zD8GOHiguS}&C=wxv}WEG;{TP)8dF9#p68ynMfaPT+#EuQ#Y$WQkM{?pF< z@SpF=T>dq4xrf z!m(!%TewKgUiH6)SLxf(WA&V>tZ8?Sv0IgbrOu1C^pqT|iMGf`#qLJrOZ^vgA|Sfli6j$=8vvbiI)e574`M1F2A4v7z`o0pNl3`7b_`(QZe{NFeZ z>foiF57(TW=AadWvpJ~Px7s&Q*{R)`-XWj;KoB0uIqY!0J&}XMzf^J`|FcyuM8N*ez+flb@02XOdz%R5bE$fKlvf(c z^#y}#(%^*Z2XrB)vuY%PRZn4A`8FRp6s|W3(>1mLaR`LJIS2?3c}k!W&;0qds}2@vdER8U@_Y^Ey2TwpU5sRMUwoj=oo z*ol4z3cSw-9q3*Hk!|tW+1=xe`RSeW!C}y*pdW{y`Llf7u+|sG6q=gfK=-tk0$|I+ zEhECXl^R$6PHyknC5;ig*;VJ9e*ZLy4T6CSbM+Fs=pw56}8p8i3=V2Su5AzdHg?L46#v! zGq3r@hN)8d+}t4~!u$gxe4mJ(a&)4ES9VjGj!}(F9`#Oi!^{gjPnAX9uVta>6v$7b zk@J#u9H=1}lRt0(&cxZ5yopZAIe0$!#rJcKc?!?dp^{hXxZs9bAulXr&-G*i`084f z4^vfX4SIL8<+K^)`)^EDO>>SxpaoZTs<-_ zIG#zM;s#9)t@Dych*|lK2crv`P<55vROh{*4g#B+m6w-rs2+on#!HyN72$bKY?lG{IR<=2X2{2Z-Zo)w02N2{~pcDU4F< zWg1Bw`ZO>1a21nsFkSa%Q*Zq`D}y?P87i((im~&O?^u~i_W#bp(8X}njAAk}k$(!o zW*!7@yt@mfM(prf^xHC$)q|0HqwyizH2@A6uJ~XveCz%BSz*f2a@lg?Bo?|3>2wk1qG_v<+^A8d7>yFo$(sC{?*K_wyi4P&p_mbR5qOpTG z18M6AmmEv}Xhh121|!s*s%EIO*Y;>jzr7fqOLnQ;3oM5$nxb+CLMtX`muvUSE#9Rf zpSFq=h0Npa&=19X>n=`(@qX=UvEzl*mAshG8h5|F;g%sp7w{quVB`A@fUwR&vCjSI zf5eA$`Sw$4=SDX^Yi*TgBdt;Ag6*k=HmH{u9oLNgYVU1hM@!dX?MM%6v<++i3@lzZ zbQ_ZKH^#qsXKIytix@bhx0tv=SG|iA$r9i1MeMiDtMczF{QI%~eW`yx+P@#>-w)&$ zMb_(U_j|ltep?U4?+XkTm}TQviI=*??@2&~m9>6AzE=SGB0-PEt!?v}l)VgQI|;-P zA-uc@uOSab;PWqI&AzHRS8x>&UP(i1WKib7{8Q3p+C?a@q<$#tHGqiu$IemKXPmpI z+wXqwMF0L+el^+=cE86P%&!7Uy8P=re&}{Ar;>y_SOIK{#$N=#v5vgZT`>TVnjfiX z3pKCjQdzD__Za@zYjj%Zt{)3#BJk0oL}n|qc)Pu4|5Ip1Povh$x3dnZiGT6-{V>CD z=?CK9#O#C;>-gS$RNFWnzDMY;h3GWZi3z#v&$z(^y{NTgy*jY!R^BzEygUD^wW{!u zXkv=BY7_DYdf&!&=;JBzi}mp)OSN&PX=8=WJ*Kn_aUVr0 zwlCR{JeueF=q`nVfUahKK@awm|DcZFZtx@h#XtXWH+^>KdbUYMj%nc=$pFnza==Fv zUb$}n`H^+rdDV%Lg$S7*(-S4LsuR6VpO!f3%4vynl>#9@bk|i>l!jmIAox3zC$g8s z#iMM5K$Bf06UT1^P2zsuXlH{{f>6$Sa8%am;lvE^)bI4_L?l;jR3~m^R5z3~PD_mB zW>&7G+&pfM=Y}_kJpabt%qA&+G=Z4%K4TpqU!A0&dO>bm+K{+%#)jVm6dczBU$4OO zV(rD%G0?B0=0C548R~1;vt1o>RmbJXyw#a>w*h;n`6}wFD zF7m4d!n7HwJfv_mIn)qo^4bFMX5cO1dvI}Hq@zcwuLw#@u`gj$=)2AHZ!|85n7;hb z;yp?Fm@YVOO3S#d;!m1J$Anu7nscWxi)hW&O+4!+ErZw$)V!$AckJp0ekIQ5xO?;q z|G`Xqu-2Q(Z`M5V`4=`MrUa7!ew4qcT>5mOn-4u&rzFn3Ae>mjA@IN164{8k4{r%g z+M-o9bz-yA@gv*cAQ6U{6w_KtSlKOUXL4_a6;4a^yFdgUt$1O{E7itkFfXcEIA8Z> z|LU=C+EuDgaP{UuU5#dumQt;eifxN}MoPDZEB4PXisZhJ>eC*r*tFn2@(8;5uQ(QI zqx-#iTxJc;Q0eU3A&|B|Qd7R?%7<%q0#mX{*h95JcW1I0BY>z)!$$>#SYHgU``h`X zKj@+98s2s=MZ$2?4KZWh2ff}=nmMM_qKQG}b49tRdsHU}mo>!9Q$zlQaXFlBf4ns{ zMJG*^M_Wo@>?M1};86lmC#ibuN7oXcWgk%_@^9-V`N1MW6W^atZ0C^EfYe^oFBW_! z)f>drN?~d9rYi9=1TvA|f1~f2e7w)LqkZDM`34NV>%0l>JIO~Bq04WCL#9I2SqMx9^e& z#y_hLpO7Vc=MN1!i?~O=Yk1G3elAVqE2Laj7g3cmJ#zFdmg)BdWgJ6baKp_Ulb3&O zYx&IlhHJU(TRyXI!xdZJf(UBB{~{Tjw|(Z76V|Aui~4DjC% zXgHp`Q2ESI!zeBa%V!og3}Mqk5e~niCoZOC@2rJ;yY(o@zL;gZ-~#%weHU5aGyl{4 zldSLZZ2+8o#C+5;gsltm7%fCgN{>A6(QyYmyub6u(X7`is5bSR?CK7==EUp5XAXIq zc_8@BKUeKH6F~HfVe;ybC@P-~w=TYMVTZCi*(tB#jSSY(v^ExMhlp-8sTiDBZ@cce zO8p{JIadxp5)eLq%2d7*M-C~idQD~h>S5rx#nZ_AK@bJ6nj)HZ>ZoL z-)ZxEO^;4|!26kPa|`fA{!}JQrxA6&G59U;$A(&yPk8#~`aa=`P4%NvQ^|j3eX-Mz z#%A|Ki*bvfRlsl}D?vnI=Xq`L5r1AL@{axZNZhNVq63c3@m{_I7$x!w-J^I99zDyW zEcWGnXj|WcZYMt<^xDDy=nVg_6jV`@3R~U$gSrX`Vy-_f`B#t>8~@Xz1U#LQVeh?# z|MKCdQr9!`pEt+ zR~o8I^1ZG96g_btiJzmT>~MTB#EgH0fOds_S3d@?zHkRCKQsyE&dcm_QQOcJE@FM3`9D-W1j6(3y=Cp{BH;i8hLH9E4(vlPY!HmK z8wCH^F$(^-Jb)k_EcE97$#?0}2NH~Yf^-b{!>A1WpwEEBOnxozXdqvLQ3%hKG&1=J z(8R9HRXG15lns$1KKe^SkM#}5d$B$Ha*kJxa*8SP&ug#S+c7zGX~&#s%ednR&oSNs z?>0gxMQ_?Fj!Q^Gc=RTbSa~>ikE1XwZX-{sD^{neb4|rv&j?r>9yOQw8PS8mi@OR@L$KCZ3>LF)};rUfM#f!_Wfq;HD{X$ zeoGJht3y+a)G}{jeo#JVM^4Tyg^91^6f6J1(t{nx6y_`#AHD|4!#oQoCY7AzZ5X2C z0Og#g-y{;B${jv28CK35a}fljDI(Kn>b&qqR#e3MWXH62!lAdjv3vZfsGX?wx^1rf zNTXPB23^Dz+;2cSzDgmVD+asA7Z-I*F5ePrZnCjrTWOlrgiE&oXF9k(yl+Ps16Z37 zp@rN%eorng$(Ogi(5vabD{Kb&k`qITeyGS1oTM6bdaSla;SX4hNi(pf%EICBPh5%H z0Ha`_qG}@RlH;c*`W0X;=)Pxl;_6)dHlc(q##Ou#T2%m;Qu8{&tJ4iei3MsC`{eu^ zQSF};XD6IATDn=VT5-T`cSlRNMibX`0I!n<5Oy3|@enL! z1TJb-0*c1Y5}_1%GaC-UGvZy+bkRsbcQ)z*xd^nkr*sqQR}Z5W@+W80PPmlJNL9=k zXAtj~)EN#Rvo*Dy-t>daGuu(*O|nZ0?DQ%!PfxK+o2i_IF$DcFb}*Q$@RcaXrlwBP zT;)n3S4`BvjCYQPr3Y=gtWhiKMA!bMr!jTe`4!$dFT1&qkYaXIaZxgib3D*8oP4=E z!yjRHI)}?&=K($)Y=#pv9M0NG{^GMqqQ9u5$o`HQ`(kVIJ&*-sj2&3=q`DTGzQyzK zOv6^@!p8&P*^OVP*gz9s`3*f~ehT>Or$pC{@@_bT&M$>w=NuWrQN{Mfws24jpELez zybh0EuEfwb?-wU(v_TE-%lHNYpfnX{8*bW3^?8AM$h=CZ$=YuES{2_@x%R!h%FtsU zO=^igS~NNIvvrf=TsS}JVlo(y8z}x&+4OPKEm+Sl>qOw9&_LL@uEyw!0Og#}m-8TS zqStVtuM>x67vYfn_)Ba5mPhnS%fUuXDn(9V7~7p7 z6o2;5XZ?CFUx^6LXAMpeb?L>0^3|ZlP&?1gN)VPnjAbu*P#6QUDk8Vn!}iN6j69sH zmcaofYlN4ZVpA+WUq#uH#Wh>Pm=wi92{ZH6z`>4wf#7J_Z0e zsdEuqV>&tzT0C5k{_wb^1ld?A`jnG8Qn!Wr2#n;U`uO$RUU@rX?%NK^v1hP#VfEfV zKWf~;Ud#TH}N|qF%koY z`4*|zQCA{v%fy#5-SWYaFyD1v&u>fT<8cI515#>L7iCOC^gXe;Z2={CLonkU8zuNo z4d{mA_xO`Jh{(IRq!B(Opn)8LWgpxyu*o+y#ta8$6Ualj59yvN=$VwG|U#R9RhIr)Ki}dH8d#DMOwK50NcdJ zi~v#|PX0dQ&z))c!cTXhWzjJfOF+j2ao!~lCiE5Cza;eK7Oowp3{{0`R1IxS{!Z^Y z<4OSN!~&J}L#&awiLqco0os9n{--_Y=a+s9;HSAOC9MJ0cKHflnq#CBR!-{Kk?aK_ zE4>1AVes|tgSM=AG70~1SFdvAm@$q&`3rnjjL$$Bv87_c+abE%tPhmnICzXdSUoTN z-E{Wwhof@5*sYvztNEp{8TOC6S10S$TwZzC=sDh&-Ta~mbz*ehiZ))-c_*}t$0gav zm6lq8^m6eNJKX-cF&X}LKRuKRDkdeBKFxh6g4BHR?7E`~7wBU#6sb3PaMdk+`FmUF zYwJ^gpnRJ-17ykd>=>ToJ*LzxOP^J>S3JXq22`7kej~;-8;xli=74XbgYP+e1WSKL zgIMd*TAJvWt}slw6r1^)l6E+DO#+_hZ6mH zB>8g3amMF1hD%?L#1F9f#t)y?!b4*?cMBA^S)hVW@QYdRL4YrPUHG!o1t}9{hR+T%xop-3 zirH!l4)SwT&!;9x;X)uJTQu;`NF_4;E6pp!-GdNb*ppP6_2#pX>8b1b$J50eA8=b8gC1gkv)P`aH!rzDk zLHR8FQPgMnbf7c-e3+#fi@GOgq!`QnTsy{+?;Tt0_{S`MnTGW#V=eFg9sV(wO}x$~}5gkN#1wPmmyO-gSJ?nqfHJaN83X@S5b$I?3v@X+?zc~B*M=(C$zdJ^(sa$$?t&xs$MKDs1mBrio z5|hN99RnxUGR6UKH7TIII{su0O9BB01N%d5?^wV-Rbf%`(-_o(2Lxldj zn;MH`XxZvIQ6?P?`J}laekesa)b?9S%u0MEBWT09cwgGI95hS1un!F$?DS6P1`ysK zf0vD92ZdZg!Hr+C*dIS=0`!WEHz0rvThiF2okhB0?BLeklDQS-R|Il%$ zGsVeq8I)#}Z?4?rF$^D!+u&(Ce!My%I1$6{?wYn z-G+Z)m!CZ%tbKoNapFL>E}jui)S)wd5LzMs zvJ|kM9aT;Ho9aUBPw7<-eNKiNUQC@p;ag^PX=z(H7Y}&oBCd)r_X?`dFjN+qr zFe>d{YvWfT6`Sn$sgkw!>pNqx?;f^$=U0hVY_#nEkQd$Ds|mdC^1V!#uD%<;I{a&@ zP7VS!BU?btYMIAXNZfZGMnpr#^z(l57QT7YuVGE0=Ff{q`QOQ*%JS-_Mc|0`WwXd* zm~kknpp6IBPz^(};m||)7y`e{NZ&J{^Wzl7Y=v+`;v4c01EU6wSY2MN8e|lV-JKki zr)#VbX9ZyN$oo;T9s}TNY(uHX^Tbi`i10%FFy)h4o2(W;w{c>mO+{xv$mTv;AB9nn zZ+aa8_P0BQNIjr$HV_chstTCc09_0W62_Er*gD|tw}@U%Rz#RD-5UzYo06^uan5z`zYbHqv4G zATWn*H;?==zWx}l*ce*&&mJ1Rdak)I@zI?e`btT#u%75wlt#BaS&!@cicO(Aeqt46 z44xh4H4#ZZ$S@;`k-290VBdj7qrYmbpCQRveCM!D2Q1tUM1u`ch{h+wwu#^BM9DcC z2Bz?9b!W;5GN56e0y#@ripV@;<*T5%XIyBefUH>-dr3nAjbhl!p5-gw1x9=2(cB%H zWdq-FgkexsYXYRfyIT-LrSKeF-@ZWSU)scAeFQgEp7+Ors4#_ts49_H`e#$+e(?Gz+uwXG z55e9{1-vBk`ni|Od1>_JtbkyGFkSvF2IXnXpGjg zHkA~_I z&W(h^bmAX)dG@;l`(Ythtru;)<8L3;TjS4l%x| z`zSi;hijdG`z)r6b!6!~ru9J3n>1)KID&%Ma`>Vz0P?P#Ctzve%bUewl$-F0Mex|f zlGoC6SNe6y-kGc7lQpu7uyc@*&XHJAjhTW{Piba2hsDS?W#5i1>|(VY4dOma5&l=(WB4VAI+KYU*xToY~?x87@HiP}I|m!JACTA$nd z=$uxfp*Kf1J_AY=4ZYQ(p&8H%V?RO=vr&2X>oO3)-*JEd>NFWr$%tY70?!rC`22fU zK>uFZY99^BpZMChzyI^%jBO?js-<#_*DSM-5rT1|eK2PjFCjnSmR>LxiS@wlD%83z z?H6f?D85^lyaa`rp%oB;_c*C=GgB+ol9@if{iFko{XR4XD_7S}3cZBh%*pAW&f(AT zZpHxCnqsjclG)6FZ2W!T*b0(&!M7?vCXO>cDzZ!*Sh_abMIOkGRS#OxwvKJuKePWx zPLl;;W7I?5Mru2@dB5xRuZ|Q^g;M7jSDE){Px8hmhE^M=7a732$EZF?%H)mA7gtwa8-liF(k||CJ@D@-whyUSX$$;0F-xx3>QH%t7$r0N$YG zn4j~7*XK(jMxN<>6goKoyl@zJa1x|JqGD@(-q^LRDQdP%N>XpV_onadU=IKzxO)=Mjg2pOPZJZD%tbCfclUOG zaw?MWv-u8k_SYG9V0~bQ9yuXgIAL zQaadNgj+EFQ1h$wvgMXSB1hJ}*EjZ7h~V1u^K^dvUMAwG_gV46Ptp7pN?E2Y9?nG! z>f!P`dAJ(mmGKV!)kni}lHarIGrsN$)DK8qPw`*6yN1uLR@eYVi~lh!Cq-!g85jC* zCa>=8-mKrpn=5$pXBIzbqT$5VNIrd&YUj;F-aNuLlFz&xu-YJ;82avBULG&)z)%4K zbx!Hf+C`^gK^3G%1bysFA2qFPuV2j-&#((edyGbJnx5!YIj!a5_4%9^L40+`2F$e= z8(tHxE5U1sio61wyha|@&IWOr%2dIWmiqODQ(7)xU!-K)1A?}`qd|T(+%mPO1J~9j z+za+b=_@&hcQPvA(Ay{y+#4m+ajG`{pS&0W!rEShz_LUXGQb%%5>&R&Zb(MiIaK;m zxZ`=#JtFbFk$t<_m3Dq)^zKM5J8YynmcATKOed$xbCG@Qr}^jkR8>9t57QF8MoWWG zWJ{C;Vqbf6KhgsC@2eUN&1)LQNYxAfVC?zcuYVbco))yb%=EYY|9hN#FAwJb(sx#B zaPW5HWNe`;*J$0;V-C5LN(uvEdKji=s}*JrR+M)F!6lj{l{S7wi_g@&8YAwk`Zy4% zMgb#zl(Dfj#rbOeANoTX=5t=n+YpNhH>NNPplh++SUqQCAA65}Mzxy!htH(WN6M;` zijkb7rDUhF6U2*Ru5LBD00q9h&Hr+qW$gkyWinQluU-6<6n^!nx+Ppgio<-ZRC82G zExKZ~Wz=x%RR1+^(J4k(X0n8H6buZF)yw}<-&{?mynJ^sg+Y1x!vU0k987re*Od;w zqnH9V$(O#fhgJn&%cE;7Hb@#G=6YAjYkHr^``$#7-e2~8gbigqp3(MGPU&j#kE`&x z+r3rB-JXA5+|56NgKyegJ!feQEu58ZxBdU{!LS@Zb(izOrBzn%#)|}I*D=GNH%p;v zR4Hg{X4c>j4mEEx?&I?Dk?gG1+#&@s)<2aTP3%!@`~(m7$oZk{)al_JNj6tvt(C+p z9LIy6Wo<(a#Mw_F&i*3y`f{F2MO)o;Sp)=v4 zSBP51vbQ=fQJb-bXlvqzUPlz`v=&bBBC7s@wNG9rv-A$BL^lV4(2U8NAtkajB_EQAATpYfyTj)eW=Umr2Q3qCC` z?Cxy*&D+qch|QMN8lM6ByuYe>HAVcYw`Qx_XTPM{pOBx_UUc=^x-I;@2>xawv0~#N zvJb)EAaA*S1^%qpuE#Sumr5yACP0JR>(2E%4FT?a+KII@{=O9gyiTk80i;BLk@!|4 zya1Anl_TQ{ii?Y{-N;eb#dKYicNtwj*?Lf@u6sQ?cf8fy)$Op?fg48U1YlaSXIM^^ zN!5r80`#WZc}&5~^T%oEIX3xO)LMwkjQw&m@`2Ch zx(XvXjTcPe@30JwuY#nGEuz@1-U6Z*%%x)a{8+@JkSU)NQ7q|K>IZmv%?MxuK(;e} zQLPC|teYhscE5@+%-IYoi?8gjSN@+mhgN;gHY;)vHN7b~VuTcUm(ZQ`CM&#At}5H$ zW3|yz;-U^Ej||60^66yz6b-n(Fy9+yAG5=(4hkjdXYx&&2;$e3@@2c4B%sQ~pPwPL zVoGtt>@0Raf$?5e?)~B%dYS0|)~0Ux{Pfp4@%gHrX}?5QKEHgb;z8_hR(L?d?wa%0novP_iDK1O7@Gj zFSuO-H!QR@QHgc+!Qf&w7vA^JHdyT1=wP9jl9LbHufN!o=s)#2`b;Hj_1Gy#z8^Q? zy!!5pFcgKGIWr2iLb4eb3K|Lq2>j`v2Rgh<_=7yYNlhh2d0X*#9ea^l&%4|``lB8d zxD>ms$KU0AJ9=+pMyc23o31jFiZ6R?Yrm$2<@D)AF*8p z&y{y=1oBwG4C8BbBC2uzv)=Y~{|D@A)BUiuKnlIH$#$7}?}kM;=#t(wipw=unFGt-pZH)&_RV&aIr~ZGyg&X*Yb;3aB+iDp zR*yl7?lM=snJo^0>YDfc-yMlduKnxS)zVifA>Z1auZkZr6eMhF0Q|*Pq`85Ks%rGz zLTKRPHw8dEFN-Uc%1bzL}DRaTuxNaT<=W=Sjcda^&6_np}{>hwHK1*3J#zc>ese85^cSZjF#o%n*U$pQ0}-(VwX+x};v?HE;H3;;o}R;~K$n8Hp? zYOMErTLpJz*!3%Up<=d?(k}|1Ms`pfg|J9XL%wK)ZWQb$? zj2g7Q$}+uljPJ5B^!V0qBVNWmO8U0l^&`?uF?K5lyb(X!{3T$Ke33s{pUvj8^?a5Y zjvK32{Y$Niu<<*PA2R)yf73?lHyXQbOin|&cPyMdHvXwU2`org_cFy+qo8lMj4}Od zA^BHLv`IQCQjuDq0D>Oy-%)l@0rb7Mo;8D-GIC1 zc)=inQJUuG>n3;LFPHo{7b`pqbMGSu%$?QeVdJvmv#bTbU{Fk`&YRr?da+U~~q(tvKqC?&-^MV}im z=TL*w->0MjYBSs`a7|47geFoWvpSyv<2*I7^|YXgTxvkSj|7rYe7jIoRMaikeDQuh zgjj&`CvnXr>$zDD5GOx=PRkkji2^TX*u+DT7<9J7TrCH1660s`=1!E5l7Z&CG7ykc zoM!XaXUvna;w4E35iWf$lMouCj+Yx&!rt3sjRcCH?kXRde#YgHna%=0EqQX16NzpT zWQoMX!o%D6y?+M^+lL_mVe3l^GqO{n(Md{^V8quUUu+Z_Pq_&;?*Tz3k$3;kVQgzS zH9^2A(N9I9xy;?G1kfK9YyNf9kM9;rs9Y+p&~q zD+FD{ppEZ1e|(Tep)^tWA^!H1>33@s`W$;U-xtkZOVD2GSydHH{HSC$^*a~N%>1+n zEi#T>Q*ORj?O$Y5Ic)Aqe825v=(>d`(U#s-P30$tmMcDqMCz4QO^vxHH(aI?_4&4A zt2K2|BylSYc)uSB5qp~j9ikphl2nEhL(Yqh-}e$Qm7{rHnfKgNX3qJ$*2}csH+D0; zR^7Sc8QXL#z9ko(HUX4wsg7@t?AsMtcaWU++i+0iR+A-NDM3ndHGiv`{&{l!wfr4l zKb!QK=4iAn996N`Gd-DIspKoM@i$sehN~x-^EUs_$#jTyZ#gZQFKAi5=2cT>dt8z+ zNCxVE%8rRpLZdfNu{kjEDa`@@00%m5Cr!cT%*U7*b&r_QU?Vs8X`1Iwv{h<3MR0@$ zvf(Hkams|L_=OEJC$_<&n7 z3*wi^=4q~bBb}D5Fphuu3+iMb3cE>y!w%? zDQG!(u5E-3r?NeKVAFxQ4aZBs35?!;E#bF}8heEnyZWETPZr41NKx@7I_gDEHq0!0 z@)I%hrOUv~r!=rc7tH*Zc?`Q?25qvT7t5F&jOFi}BUP=|eFEsXr_!i9!Kay|ux$)N z3UH;=vbn?;h7$i!!!4H-3qHV~b)JqFZ7He&NvKswr;@V7W8>RFal7z>i~UxC^aoQd zK68?ddDRnc%qlNLy=J8XH2~J^o#YCB-Y=;7RB(?KluO*%OI7)b5#6L$t|dQm5MppX z-!z5yy&5={=yTwxc7KZ=Y+A)t+Vo{^zbtgwpcA9MzndiowD25%*oy@shJ8Pe#Hh74 z=2S+z*rdlkevPEOIVakHzq8s6c(r}!EB=5pu=}#c;pzy~-XP_FdK~{%#yCc(8pfgO z(mKgEwIFclIO?U=$tJ7#xH9zZ4Y#96K4tW(Q%lMe^)@e6mw9$!xfTs-!z~MVH@(t$ z)fRuYidRKCHbq;Gj<#HjPxnG5=cSd=+~;HC*K8B-#MgTv9BYS{U?n{5>t$_ZL76d> z6zj{;%N^&u#gdw2iTDc^r<^J{$6*or$4 z;xQ_bsUt?i@LXP)G7CiMBp*Z~-%w{Ek??;uGtMbBLaBf3-_49cuHaO^VAq*Js4MLuSUerbAJqRi^9AxKL-Fb)_g9PCh{HOy~>8SpOgW^(S((-lt?yuPRB) zncdP4y0%5~w&>^$;dO8IBH-&hTWvf!Lc$ZRHohtS=5s7GzFsZO$meg$pzIi1@_o(g zmiqGwh5zK6Hp}Js8Td6Jk*nk#8J~~SPqzUDUxz{YMeb~sD^^t`Vi zgv-32Jt}${;jFMp(mQL*yfdkg27bHaM8e@o+jJcw4F_ zTrsNWrKjdJK#oIua1m(0+q}DWK!(&bcCB|68w^&<@bE6>%2j=@U(({#C4Nz@l!TlH z2^g7`?_PUvjX#W1@AbRa2ZGpCp*TB&Pa6RCcJJqK@R1Ge!-wQF<5xXZ#;m&)MEvX1 z!*aZ$6&rN=s#qnW`+Dezt{XS<93V=7VLlUam9iu+N5Q; zmw3cizqD2~s}LxIj~a%B(|c$eC6m8W{Vn}_(FMgYNL64MB<|4$m_*(U>d+l(lcAv; zgz*+16*NhaRDW;tuLJ_FO=DJM500swbZ_V(w}-7d0jPxQMD_=bBg zQKgyY-F17ImCPH&kF5K+YLeR<^|+G!_4erzfN1Aa?zrvPvt?I2<6U#N#h)e@c8`}p z4LALJkm06f=$9{&27>C%_s8;m>UC#-1p0ZgTpOfE47cE!SxBleR?9||;_>Jj(Dc?< zv#BKYWYF57zw&>zIpuu|`jmBK={pY!Nyui&DJgX(zA^dQ?0Mj@`gX}$?p>aHOGKJF zQ>&$nJ+rLVW+Aa~bP^%cS=W5f zX;rHp6L40fY70YLD+&IotwAhob)ptp494t_#uqfid9r`_V|q+@%H<^&PHx_9sz?1T z+|Mbwz{WSZ`7iZzO)-Vx+~Y$mT4s%v=Y!h5ODCUw33ziBK5pMw6OG9@c|MlpkXYw#GZ|$q1$*n zA?WfC#`lwQFDMfw-z^GZ`~E0l(G~la^dUU!2K=||Sq!asUY#OLCu+%SNqGNj4S-7K zMMO>Z)eh2yJBs?YQB-3Fo8^so1;teC1)iCfY)VTk^NgnAURA?%4lF z-Mhd?RbG4l;Sva9m?#9ILJ1l*sMUblCL%TAq7#@13e_lHP!zG+$|V65#9)Xr9ml4p z+FG^e(AKK0)oSapcsVu^1cVm3vA-ZOV(>WZ{Q(QY@zBKH%2 zVy%*;M4WwbKfL7I7scwcJnes1e&{-rA7?UmaDO=$B(7b<{9n}kkG6Elv6F}_+2qwc zV%9z=02T8<#S~D%I;2kVPKxPJ{#sYP~<5Mg=|VOF5IPSbHB`r&-yuaaHpfz-S=tB}knOMo4v zLFlWa5{$`fHQ_v^xKrHpElZqRIg%6>>)PeN;r9*}jAKMDkPb4&CvY*jZqf^_ZH23N5=iTwr}a z5290ZxXQXGEaf@~JvE2qy#WFRZHo_f`0Gqt|6}|;(gFT{DUl?a`CsBMq5VaH8u=f9 z`kEKAK|S~3F9Nl#0g4r<*Wx_}`RnsRJ`p+EU%$`4^#gayi}}}${`EZndX|5Eon5c; zrr7m%ZxWveFAN^FLury6*~^QLgn`j-VjsdMOCn@nIQj5L(Dw!M;Q@XYVVZpSo+BIN z!@yP}eMwCOCJ`x{ysxtPZ_!LseEA?zoh2V&SrZcN_OW=zMOuoUI)za80{GilfgaEbq6IWvgsE>>k6b=XJ3@2-~LcfhW7kY z+4H#VZ)nTeRt_S$Q(;JHxfA)+^)deSQFgt`>uuNDy`Fp?G(BOzO}g#Bp)Ml#fl2JU4nta(7BSa=xRD`XxVOFp=o1HG@B> zRy~tDDzu{#AFcdD8an>X#^vR>37mE-WdgT!!@#;w=l2=%p*G|Tefx?sDm!SenniWW zv|62MtQU*9QFp*mI73 zkN7XadNDegK4bmqe3N(F&jo3cdXMzA$AqH96d8Z%@nlUgV?>G9p)nEo2sk)%GMO(& z-DC_VG6r~`$ykAwZ)z@(QW5Yyz!Y#PWKZFO=QM?X%bLQJpY1<|Zy#U^?Z%N<@1|h( z{k&f|zMaJ@XKp`KfuL%^nAxP&<^fdT#qTiy5pGb%AtE2D6H z+OZ#m+C1k6PC!hmGjp1&Gjrx?HSt@hGt*}(wG{xCTNIH@jq9sQI5l#W3eS|BtSf%L zN|k5amHmeCY1L-JSmYFI@fI>h36;rO#5q4fP;+L9=Fh@J>nC{^9=FdYOB(nTx79j~ z#)$~g(f3u{_J;b+)gEkf1Z}A;c!jvqNLE`?UFrUPJow{Ch3fF`i6NTyM>KKcYERq}eT2H%IkAt4Pz!Rip`y8equ;U!DCJTph$(#5=X&;K;Du z`3z@YOb2$peNif1P^sz?4UAgZ)SOvrM!FUwGE1dHpdA5#wFKHkEY5o@YAqa(7OLfA zlTH7ciB4_5u>K6UnU5HhBlC0sPxpjS-QX_4dcw)Hlz@*^tZ>U+VX1OltPe?M*M@F0 zSW6+PL#Wi!It;Cj^=A)tUE3=-R&J(oh2^z%Q~T4jkEu((^SB0y1u$OyS4Lu8SE}`5 zt#wZqtPw!gAS;vpFC**R3}{fBv29Lj+rd1ZY*Zp4Eo+DVlvDFx<&W*lee500SKcLY zx!2F`Zudg&me-xngOM$^z!Y4=-oyn5gJC47u zO~Ze(2yA+~2E6Zi#X0PRzP~3YX7Wo3jSor*A!s(XD<#yNJm2?nVT@4`!paFv6Nf?w z9971>quvmu;%3<`a|2hMA>xv3(a(xWh>E+Ue zo@JjDZ}gXU;aVp&Wd0a=awe#FnbsxPU+ZTNXJNjvarpEnh2JQ+r7~mJ9W~L{gx`7h z3cq-CWU5RtV~~)O#O1L$Ggr5$1BNdhJ+r*6C{73%F$INoFC}Q;c(fClHYHIZY$(h=hhMLOL)6wd;e|0 zvghVfHy}`oP~`WH#x=jBjMI|{L8SE;KUXw{#B9#~F#Df@xS~q^Rf25xJn?{y18u|R zn_JaEXPZ*viD(oI$_zm)W_o3%(C6jG;nlx|OhSu(2VPiRz6=$aNju@540}*c$SFm# z?-DVdbC$RN7c#m1K1B7c{2{Nscatva`ExLYV-ne0IrpHb$Aod>wf)v)nZiQyVRo=T zl~)s+TFlA6`lED8$l&MATW8}Ze$0EEgI&qBk@)o`MKu*CmDImh9W5zI{yDR`{k}W- zvlImQ`W@XCPKWoxe`E7PP0josj!hs}-1wqU)2+G!LuLw;`SqcHaF}h(UMs-@UPcrM zLHx*J3eNm^b?)ae!Oz9^v({H<7uTOg-DuvqxYT>}8Eb`oPitjNxof53-12(V>t(bz zqRcC$tqu!Jj{^XbHhH2ywztt=iK7q%`^`Fi!{B>mYVL%1kaI;R37DwfC)4;G?$GgE zyv6IngZD-Tw}y#ks~)tD9OC#uy&E6l@T)00ZTLQYM9#Bp^eMbh8_%p5_WU@Y9q%za zY{meSxBEk|&Q4TNcgG1Zf;v!q7SU?Xipt`g%uE>$e=5L{vd<_kLyeoF$lw*tz?ZnE zBNe$)*xXT5{#-S+>cOkfrpsW>Gndm{-;R=%gw=LEFGd9KakX?gj`cg{h_qq zxUZ738TKf0shaq+^&e0=lq^KIOwciMEue3`lHYZ%Zt&h}MB3n&!>w(E1HQ>AuQ(NCEmCXtSOEtg3IDj@*+6BQI&1~B3PdsaUKPWA7W>cJaG>KyvsHUS)z zDHs2(+6}2DsoG$UCa?7)bgBof9~>Xo1bBmhikhdMU3OyzT1Dze| zz02;fMWribfW7r~>0tzzpg#^`9C|7gGLxDNDlWF&hZFHLclFJAx{`r-Th7!(u(~vd za*jx{m40@Cerg>4?~nQ&_VVh24#(0CROMQlO8oebcpobIojzmv9}Z&+n@AR-8Avq{ z8}N>jcuODPM+rPil<34hu^)NON-S@(I`9huUhf)OmmXlwa+SI2-LMdw>lLreVKcB? zMVO!x#jy+~j^%UM>0@+42n2>h5$Z`StK*n1$uE^LYpI13+r>J+MiTy9OVqjEyH8Oo z%3sB2#)PF)c^T#5Rm{qqy2gc!;|C`nw{GJF8|%u_%M z@Hv&w_VAJYbkxlKpp)nhZ~2hO@IOp~iH%6I&*v*o%X1|S5Cr)|AV%B~wOlCPaXw47 zc;R6`Q{09#Ui3((aHls3Ebajzg+t@^iu3RID=*YtCwxIJK^UQ1GQ$heeZ&~YPv73m zxrXa>>JE~dD>@zT)|0STxiXk`+N6k$C>CLQy&Wvh<;vu_@nXYpvYWEv57~*7g4{Ne zmZ$C{H8owfPo)U2Oo8GGpj_`&$asWmrt5vE*q$(p&9W-vl(UI@=OKi}Vzr|B$$Dd2 zYQ64F{MK#`gRFgWr*UCNk7!cxe%6Mf_<#C-_%Z5DTxo>s=u@_w&%XtZbxnm8;86(= zUaN2f(s9hd6#Qf+$q=UJC5zQt@nUMGnJ!3{vkC|!Ufll> zKb)#StS7)Y`(u(qVUVXA`E0g1&}xCV{04v6YPBFi4upWBvRTZHe@%M)j4UO86pS++ zq5jD&XLYE(pkHKR{h@xGb)%&niVY|o0vX2g2lHWq6k#!QvUHM@JMDzdX-?>%f+}{@ z4b%+4y$KJfX@@rq%THJZ@w(XwRo(Q`g04WBX$K|S(&FgQ6d2l}();aq4uHr#UnGG9 zpV^fGZo}+O7ki8U3o1hWs_Lq+5zBw&^lYuLR@c#0;_rQZ!Hah~ohN^n4SKt>_RmVU zpBuZcZ_bb{-c=lnqyFE6Qc%6=q0bM>a=e$>$~LViC6(KWTW$p2E8nL1Cp&2Vk3(8A zt(EPBppM#c^z}%ZzCf;jE+*V;^wUx|U#JSZ`|;dEk{s~6 z`m!Ko&zT=`2*rp0$0Iscv%>412dBq#i=QVDZkV2o=hx9gSn+$Se*wsJeiLTW`OSGT zp`8nYB8i0raHMR>{mY|v0EIv{F7AmD8yX)l<0k`hyhvfdMn*rpe|;v|Bu;9_NQOU` zpRMsjXp{<^vHWvR69Wtn^I`05=W4wtEWFBs=We?WeA)RD2cOkx_#l5xu38$G@jz=6 zL;K+g8e#rf4-8encf7FMEk#(y>*{i~dy-Q>w>caiTQH=>Le;j1o|sU;p-nb9`m3!{ zaT8p<%3C)pNW?98gkvKsSyP0Yo1bS+ZQDbwvkKbQ)>*PyLsAj%z<@W+c4<>l+7iE* zvIH}3gz&Us15bvrglG&$Ep9k>Hzi4tpTn4HhT(H)2k;Bs_Ii5$8T5g1%(yqvY(;LL z=CT~p%)xbm92D;8h_21JQ|Ogo79Vi!U<20SKOf5ZYXjG-HygO>Z&=jDv?5a>ZWAl6 zKd^lM--iOr^*UcOf$mK5kpEjTWhl@hz`pxOG+4n8^*BcrqegaSNB!^2NcxhcY%G^*gT31c%=u zza%;vr5Jx5<;%xB5-Ik)6G1q2y#l$+4Cl-ZhSsP3vSC4PFg{NmIMc zCUIjslFu5dmJ@IhBv-?w@CSoP*Xp8)IcjmPQ^@hnqwzKNymgy7>-vJ zc<~z?Wz40ECc3~Xv^p_#4iU}(dW!pt>xyqSiB2|h*mMRgx3jKLBL<{5+K5XUa$;&GtjUgIyc28DOc)sXayawHX-BWb-klGbDq zj(_3k=jF6~DECPPwhfob|L~HCrEt@aos=Ud31=3aMnHl!`=IA(DG3QRy}>ChGr?hR z?_w5{prH3gP=MY5iCgNviIVGFE+uzZY*s-s5P;GM(Ouy|ueg&Dqk84xAKgT~?f4vy zMzqww4Mx{|{gfPUMgLFRQkfIw@^pG5p8M@nQ0c1#a-m!KefBA{EV#-`9M%yZWvq|3 zb#1pk3f3|0c1;P!mcK0=B_YrKKaqh2IgZcsW;DvWa+SdSz1Z|xC}=}=z0|}iodA-5 zO8F0eCuY(?L@)oZ@}Gs8Y_pR+$0h10=8mIz1sM5@$W-$;>m6!NN#j~$I#)Aw`>4

      Nd<`tIb#}cByqqH?}NR2usjYJO#e_O$vsW?G9haGsq;C!=eD4O2y>;6(AhGpy@~8* z>(<47=$v3`+cx#3iBpDd-;_mTb83S+u8QkeV?$iII~3(jQj{wz7q!)Mn0b@>pZ6`v zo!q;Q!)pD_1hYj~37Q;rZa*q~RE@(=Kx*2FFh^0zKHeU7hLv1|#~+3=*d;^TWTlwE z62lS#2S9-QTDCG~9s#sK_VnOwvG!aYZD^n=#&zb;P-O8-N~U|C^s~V|`*ZAsU_(E8 zNaOGy-|Mr$m^|-0Hk4E``LtHQSX!MeTC6>}R=UadG8E+UcmS{)@gk#mGj>Y*vDDeJ#i`YDX0Kioe%yw8M_eSIJ4-jNIb$Q;; zdBIY$j4$@)M0ce|L>{=^;X%8?t?zR-D{=;Bvo_ZqTTOKtm5|WctnZ$R02*B+IZqg? zBdCOBua8YU1AI%HBtAgs`Lj2sV`6657zk>;sn?}Ju&gHf*P1~at6R5q9T&U)2s(Vd z?!+2E-bwUd)AYCcH>7_i)AdI~>3X&B;24>^$=tEAQAaRWSA9ak3nrXm=Y#MWIC`tX zqFt&UBXJVfA_7e?nkkt!qoiz0y>*xGXMBhYXoz1E8#rjTzXp-~^xXNFBAvM|l8hzR`My#|3 zJnRqBUpXG_w5ZEN=&j1bq0c&FqQFG=>E(r)0QjdGL`ihQkFclr`%hB-PBH#-?sv!g z8cK@$!^ZuZ9osdXE@P=@@vZxVC3VO2_iSH(PtM4KE2p)I)DeKfER*wrk~z4lO9c~u zl?#l_d7&VIkUvh%iE$E|;tMDqp@4`lqAD4r?VO5!yh)dmKX!IUs?Wyg^#323kv~Q- zq(u>9E7SXeBcerWtMKtMCvxW&B*K!4SLRVtq_jNoV{ufWCmJsum7)12hcHclMN z%FL*=r4rL_iB@HHnZ<7Xp#GQYhNRg|!*BzN=MGW#c&A_L;~1b+$SX_SB$|#*><9FS z0a%y#Ru+wW`!2~O>O@ED$Jt-==T3{v({@a}Z7h3auE&QD{_PPt&-WC?n2KH{~^FE&9EQB(%5JFG+9YJQ3b*#jrSBV!5LP1&E`83`PSI1_^;5IYj@$U^~Px_U* zel@Wx$|Y993KSck%*VvIi{IQEVbZFHO}~elIx$ymaCNI@nWQMH71i-7kj{3o>LYHM ztWlZc)&T(B#*x)y?ve&zJuMlCeK9@keSD)Z&9x=`lYKE)XO!oQ%ke_G0p^BmfGcF@ zWG#B!a=je0zk0FEet1*O<1A*mzEf{=tY^D-5-SOEayPaVVZ#357S@ty*Z}=JhL-(E zh68!(9e+fxFJU>rAMdZGqP{Jy`rxH*89a^pkEpriWr3!w^7TYM2(kCQVON`~5XBIQ z6GMTF$g7T>R}8y@3?W4VOUTe*%e1dQ83BNBoM!y5_MPhIZ1Eq^fB)vIPCs9w9h(q1R;rTMdBY(YIOX_j0*~q43THy`W(knI5Rf)UQlEYG)zvzEE;QNgS_kJ+;E^I_-yyVs;GKP(3B4a+JkKp&*MeG%2Jh9!L z_#pkehW!PMgZ+h6{Lx4eFT&~)jCw~WTJM#5`lYkb* zw7&$jC7#>pTRCP+e-6zTGgrFpXiuZ{VLyjc(W zi>0kuQkLpd=EH2)~$|u&H&`>_L?&^l} zy1L@zHN4Ta{`iIE6VLzV=(++vXVza`m$$IIj?en)AuZ;$LH{IPSMQDca_di9Sbla@ zWI}znhPhow*A3w6itA@J+vU}Dy%v^F<+47+k5||CK-j&M_&IOlU&f)S1+^%KEHe9w z=kzwCeVYB98;;{qOCBF2+d#Pf>N|jdqu?X@iE#Cj^TU|igFuiWN(c9_wfKUWW4KQ? zD#BsNJiQ=CWRv;6+%p?F6wMfJJCUG26_Tr16T1CKeP@5TX+RD;bx_iE4Cc91=B*Yr zPS0p~4mEgtwko-E;mlDQm!E|Q!pIYb;<+P6kzDj-y%BdM7gC8Ct6uord`QtZCHt|I z9sWa4t;bgDx*AfB_s8nYt(d_chRRq3Pl!SapaM^di(BB(?6}Z!u)Uh^x+wO zV3WkUa1^CeeOc(KGIG_OeM?_q{}y3?nBLdDy6MR|DFV345x`X5>RNx?0SEw}l5PDV zANFZ#jeGu^_}?;QXQGuiwZ9Nrr1Y5*7PUgN)(bRPJg2__eKD8z^Rl{O;!l~lw%dbj+~^%^YekENXC38ts?~nsn(Jtl z<*lAicD3={mLrGkt}QBncl$@ihy%JdLK{12A8+_2Y3g7&W8M%sl)u4s4&lks~dQ*YG+GvBs7YQk(-n3-EJmJ;gBuKyx<#|(FT&5{`2N$4w`ih-Tor4 zR5$MFGUqVuiGO0bHe>bfaZdyI& z6f^SfaxC{w9&77wuJh`1Lr?Wi7KVP`J6XW>A@yDP8Gl!At*;I+wNVsd@cH*fc=Etg zyKjq4ZDPk$8(MjQsd-&Go|gz%8ONJ+7q15-QAJfIAuV%^;K`Am2V>!t1V0i z*5`&FEjhHk1|e|_4>CTbt~m76%zn{bjqgFn+rtajHZYgUohwDhD@4crjCxxL5Zt2t zmLh5d?2rw(mZ}=J4s5QbW}J(O4?XiBAX{?_miBx2x(PJ~Q zCI(FX71qRIw$A(5yQ29sb`DuKRkuqIw)8Er7k@V{S^moiS8t=k}rrN8MV z<76j4V4NTYT0iJw?v4DLVsdYwa|)ZMIpwkFcRXb$!MXYDx9le4W*yH1i65%%c;OVj zOaI^PE+_hr0j0t)KP6}K_AB_%pwlO_DsCs})?aMS1xV zwndrP*3E|ec<>B+qWA+_>WW7Z#>{iO`n%`;jM?RLsvvmjGU^YF5)#IX9yyfCH@Pa0 zp*nlG-{|OSiAN=UUHDQ1&sXhyp|~bAiV%;@RLv3Dk@OV|C)tkDgyx+sC3{bR4S;p}6|r2jq;v--OKJ>a*6A92s(LN{+bEi9f0v_jQ@mpT8!I zdnV7+jZo8{rLjWK_iRp{$PFi#dnO0+Jr_()>6z@~+o#;=MgmGb&Vf#Xyn4QhJi^f} zgM;`9;Edhj`s3Lib57=Ocg4r`Opdnk?=$(>Gx>G>9BNW7tkCa!CQF0!hx;TidnSwc zxu+CH&tyJd4-GZ_Lz>ie`omW;JI%}N6a%KYTDG13HBeV^=1GieyVU3q?$|h^pL?G! zZ6~_ikcl75YWmTuGv?#NFTehf9if6QJ3<$?BzrNmUZJKEhV}{friMccTD;wV$sFCc zprRB=szT4a)njHKeVF*@E%EW1#MCi%5aK28sH;9}Gn3CdZ}VquUPPhe0YEd@Ke#1A ztCR!O_TbB0`(mo(FC=>WM&FA`^t@2bLXXVh+?429{4ntFSGl|M>aUQXDJS&pm)Df# z5CeeaTgirbIChg3V+BwsCM@2NkVlDok&^9Ls&{Y}4k?$5h{%%k-t#{Tq_HX8K%4pAzLmQ0Y| z+iEjKsC};df`I|f>5}Gil^fv%HOV3XA7{+>hPmlm1DVPQ0)Qa9Xh@2rN5hBAGufHnFu}Tx?V;C#-mXL*4NRF(vsKIeRroOilrZV zo7_)Makuh~9|KM#Ghcqz@TCYQi$B@j$=z@`G<&Q;pEY1=P5135JERkiXGNkEUi5Kr ziEyx~u8f4@9GR_uOO0Z>+k#z~Sa~>@_}M-eFvSm~AK*7_^#ggC(Y^fTH}Nrw%x5uu zu6z{PXg2y1u1V`KlJJFh6iA@v!)kt{nvWOWKN+aRoTZ@Tem=I7-G$%+{4a`_wcZjd zKpj2(K^SDLtPyY+dH0=_Wtd!_PCaY(iTQ`F^=&&u4jajwNUR@+Nr#K163k90sIT(p zE(I9lY-Em?yZIBPi7gFW>KwwXAf)^07_Y%=`YUy zl;li}kwos{rp?~H6YveSL&|HOuN1ftbJG6_RmpoSj z2iI4-Hw(gpRs~)#McCSgxOrez-lIp*g&?tOo3)E%r#%i)%%PLlF+uy^wL8(Hx0 zFuuH}=H`9;>7F)RTOSO^wdDm6F#Htj_rSMUBFiYxTV_w=AABA6we{&e&YR{cOui)V zoZ-*Bf`2lv;L4!Q%uj27uE92z`@PFCX0rWref}fEKX=Mi^3R252mZO^x%Q4^e?9G= z>!Vw@Bf=Yp7pI>4=t^#WGAZ-9zj90Vo41eidtVU$@MY&49DV#WO&`=@nwytXKgyI} zDP&RLZ6fO*Qh)uWuo6fw6|}JAa(gU5mtYQ=UMo$>h-=?OMp(dN&<2=yK?l9oT1)3l zYS+@vyJ+dq_ANR5r&@DJ>dAZ!Nr@^^yc@q#;D#*&^;SH2L4mwW8Z%>G9sf z|FO4icpE>?>8pyh@xtH#_LLmT0vxilb#mzLR-|bx|D?}O&Ow-9Fy4FPzP4y9(lR58 zGnkmgwW!I{9f-bjal45<)EzNeqH&=5(;zzTH$I4(gUvk)4Gjq2J8oDO(f8|^w?&6q zA8mEc+jp?;4G0TAbQ5*~f+^<^WRFMh!UAPgs93*%mH;NTWH$ z3VQi^B$m53Pf8?jRP4Nh!~iWIoHI{dXp=Jc$j*wI8E}+77B2U1%j;FoqSwU64(}<7 zMVnR(>D~brYU}3*D)D{5803#MT|-)^oycvcZcpcG09PpDSGv0e*er9d6?PAv;r)<-XkQ9+D(Em) zP{P`5(R89!MD_KVDVc$|ol)#1E|ef3gSkRLE-Dr?fHdI{gBKjWY#4-5%lT3)j;-}$ zlJE@5khb_FJq)j`HqRmpavW){J5_-F#SH6?`aQ+oO|Cmvn-;Ak$jBjiai2r26Q~N86_QDNQ>lWVi;fB8BVg9hGpBwa`rP|M7w%8UOjYH z5AniDKwPvk-mE7x)68_rFr2Ct0sm5B1Rta}sTs7onnIt9zBBRZ`jXxrHv1WJMrkgwzjdcNaupY&-rG0z>G7|HjW5_ zX1q^N&y<)VYOuf$i7g$5b*5Cf>F*1C-BF;XVJH|RRtx8>Lch-Y8$B{UF2xzK?}#%9 z$WnQVQJkNjG%Jt=(dWylnAdh>3K)V zWcz%s#FF9=nm^sH?=Pvf&qXEU^+|m7(L|Fd$>3(M$3IcBftwT(u@*3@LsA{v*7 znEcW%ChbO1&8<0+WBI#ZmNsDph2UBT%hQ&|ZR@KR#nOd&udu-0J90FVBypu&T1_N4 zfduZd$?7FH96#F{L$7Ss;hu4Nc?bFjF)%82O+n&0?QfyoHZfj>^cn1$+Nz%6I;SQy zn#GFaoT{a|6A6tbpShK%yx-tU#PaANf2)bUk9@j74Xop->c&=lX>NbUvIbc&Z;<&- z@GukJj~kOfn5!(+E$SflfVEp4eK7!|ve$)e{#!zK{-`s-6B`|caQLs(m8F_bJ0uI68?YUb?_JdQNXCT zo8`vozt;N)`_;ic3x8DJi!%xE+%EEvWVV@wqich}Js$z>W=a~z$&C5EK8!hbm2&3= zZ~>duZ7(vB?FB@1Zim&Ed`ql;qVTbb4tRchv3ETKi7+_bsfi9FO%G|E_R-`I)MWIM z?NX3+Ll<>|cq>D9uZYA4>}eHD?{^!fAg@3mfB=j56#Hu<74L9UTiqEvec}u5X-{3k zl-o5o-qt>w$ac5x#|J#ns*eY34`j&BBn8C>eBW*zd(-42*}02Ee_hhRqlsO5Ua@%9 zZ5Rfu@DnE@r-dE;Y`-LqFafUe!qGRh53&XYDEV{gGPcD&C-KR@@o06$uFxU{ilG6Y zv#Ozld)LW1%JP$6&lhjiOvSD(;wM*Afn6g2hL)EjL2sm17utW#J%V>a zO-r~>1AWxM?bbj8cN8CK=8;nDpMqchSPY|ZiypNMeI_=ZG$8>H{&3lmISJ){<@=Pm z@}O~krWn^7^;h(cTyA?}iq`;lni@;Sj4uq@5854|N(A;Xs2U)ahgM&wIgU3De&Xnk3*2J&IhG?@RD&7BiGQ6DJ49 zG+z_F`6|y)AffL&mbNnC#2A{zK7omr5>7mdlZswA7!xHOTWjJcSx&38U1U*E(rsnlhLbwB zkfgRsB`wPmH?(tZVWvpNtdn79_Q~CFsK3N~xU&fI$&yX>Np%wYq!xpHQsl!vsq>;w zEeALBzzKR@!NR?X7beUKHTA-AfY9n+F7tkKsOb}X4sJPwqX;<9BC*T){~A>LDGT@h zEN}3P(CxDD7w&D1HXK!ti?Z+vuaNi(g)6^G@smgt@*y9bPBfhV2`3tk;c4u*eHZ-G zFy_W{F)C)&Rg&wt*bWhY-A8@al>4Q#zqr-pE+q$@;!mvaraHQy&-}A+M61iItV@)` z6k42ZEpl>iEV^Tp7fv@xa`Fgukg}RxxOd>Fvgbm6S^L6!i)`^2YWlrUE_a2}t*X|D z6oV8;8KaRrmkNMXqGQ-6+w!zOzoT}*v&bbqEXAsa5tc)CRxQ;N5xn&uAAzc}6t8N* z8+>6lL|k&I-%b%!I30h8x0o&N1Av6}{s$kOOh*Hf`k?xSK?=xB_`EPDaV|JsxcBCh z?|CoOWJ&wtg~PaS5F5&GHobRko;x}A8v9{`h8TN(v2Mj~6VWFroi!Sn&Th70Gx};I z`Z)~7MCNTjBB$yZn^n~FuJjRW1c;aZ!f@=j)=uv?@-0PDDa0<1xKhMqIRI4*vQxf_JSMZ4Jj&I9FNP)hu!E4gF3 ztA;Pe8yB+q;G}LOHc&Lu0A?5N9oD7$^w8}O^F7dCKEDuWRygEc!$ke%is>0Sq{S-r zt@kdzl=!)fIW`V|=n6s1pWnQ5zK9rJ|C`P44Si(H@9YHgtHSbc_Q%xJS>zcn{3<^f zHI(q9_{%6l8PQaB^+wf)Q-JYtmkia;=LYQWlez52WhA;$R=}I=881GEeV;BL@4*lY zVBi2?(F*A;FPRZ`Blm(w%7iYm|8bOrawvP?~AOHNTtWN;q?q1@8KC8*MOG z5Mn9r?9?=bMCKzY%69AJK!W%IBt}o~g3$tnU)sEPdq^xz8YG_9M+PJY?L~ekXE=FL zeN_KQ;vU-7PoQu;p$Hd@17E|?~Y2r-bCzC?fV?%`W)S^&qw#r zL%i_8_dvo=S#0tBUVXn?3$J+oW5hTn3SqL8g%`vh?vV_R=f`=#SaLhp4nL?Y>Arw1 zV*`DblZWy7x7>uV?zhyPs>zW5^D<2YWub}S|M{|+-1LD#Z=OCfpto&zAp^)sY+4zeBJuFdXZMv5%jNq@;Q66@s(zNu-6E@MX z9uJO*ckS#$>7#KH5FB+gY>qc!g3R?|MTS2g4N59NbEx;j$!- z6@TnO?+jASr)AT*G^U#;~7dz^pSzmJ9dK7+Z`Gk^nIQH zAJ4z53c`;S#&@4=&en=Tk^d-0pe0o`&p`i9)^l# zo=xguePm3kK;38$p}WnlLGUp6PDeTcU&XUEVF=|Of7O7TsJie&?5SsVBEoPBt8;|n_!8!_8rBVHGmYo)!+JFcI)WdlPr8odY< zOt{FW%fr0EY+RcKCehw08wG?|d`Hd13%ejXk#BN zp#(!D_MikpbFv4p96jV6tBxKN7kiUjN!E7U*jBxaGs`#ls`ii2Q93{~hYaRyy zv57d!O#u$3RZP*_4bo5+%W z^X9QB-hsXRRU&f^)?U8QS~WHE)u6QwtYz>vQ-h8d-u{MTuQQ!D-MjElxI{=#p+r4B z5kwG0sOkO!L=Z8AzInE|ukU(KF%*&s{W#Dyd0J2ZH9M>tu*oX@2%D@kVBJ+>*9S)m z7(1|uBZcn%7bz-(KTS@yrX3!P#+4c?!0&r~9e%N|@F@MS@teF_7x^0gPP!J;xh`(%rcNX+SlYfzEPICm%T z-Q+`!RJE2Nw)xDb`C0jt6|3mdDe&35RgLc;gWj)R_{Ro1uiE*dWYA~OxuQ!qu?V!7 zQbm{QLeZtvNc^m-@%@3#Df_Itv5i>gU*_|E=$UtV%q-Fep^A~%iBx@yzK(w-v}hJT zD-RH^+Ly(~*q1NW)ksd>qp{(~G64Y$bsfk_$$~$*2-ufX5wJGKJ(1{2lyY>XEmW~s zlGt*o3;EAY1ki3+?E#B&KAW-k;BqfjW2B54t z_;JjW2UrR$;`0!^C>PNW{&(*pYs`}C_>aj^j4)D?lYO>e+O7>`eC7E9EQxj^Y?D={_%w5XoFnGqyf(iwSXPkn)2oT`^p?LZw+RZ;hmbud2(7JF$UCK0 zEIpKPSD^9AITJo>OCG7d9HO5zM2Fn| zBfn+q(CBLG%xx90qikmaNHiu#8M755h)am;Jq&2fx=GaJT27w5KQX=JT{JmOOp-IZ z4P^D2a%VfuQ36P2RibwTC(eQRw#DFw`RP5uc~nS7$LeR`fN~zfU^l-Lx~bXpKQ< zyV?~|d;dT}NhZv-`|fmB&{=@0!c}t};~O)vuJA>OPeR@kmucjV$;XtkC!>8_*VNN^ zD{0@{;OfGAmx7)lXTRfcGzyOw7Szx_`5yDgTTrZxU`g*y_9lmGc+Iv9Y8kJ6nHGGR z8+=*J7meC%6r`&j)wQN5X*=1j{aN}$^Y%Vun+~U*j)LYHwJJzV_n#HDc^9~6Ldwp_ zGwM*!G}tpPWs4Bc-o!@;bFe*kGT_qo>` zwa|};xu?jccAV*;XZ+axf_B(9c-*7*@g4p0L7UK(mVOZxW4BQ;`s8%dTNzs;`YjcC za#&{ff&Y&4SKULmhVd6kL&S>E~fh3CK$Ur08ey>@TFB8JBcOKWZwI zex{3lenF|j{pe@inEmL7Wvf4;bu{y@q8|-G_|ee3XMSPe-ZAtG=%=rH=H-9un0_?2 z1JjS2L5hBQh7LqO<8MDm`gwoi7tznP57>l`_6OUJetz=if#_%bZ5iDog?7k(NB(pQ z-F}>CFOzQqk;R;RKMg#H|{oH{3Uu6fT8l!J-%g^k=yP7*D zomB#q6FotCFoqw99t~e6gfDv59eNNFm(Wd8;&dw_{1@vXA z^H*bdt)1=)W@xg|%ln0%2$s73)*{rq2`cuk+s0ZjSmVimG`t;5keJi}>MO`+&fp1V zFp6X~RSS2^&a9t`G4da|^5(t}YTEA4*A!I@OKS{11&9A(qvSaataMGT{ouXw^V_n{=Sed*gvNXK; zgHIk(6T4&s@n91-u$*Qahk@!ePJa`=4xFX*UW@QK|SxFFeG4`JBt9~a zRRarglGCkA*-z>GbSDha%I(`gmgBeiV~45gi`-D8gO83Z(rFuwvRNaK=XNEk&HP{c zJ_G*o{7-dT^%K53iV4*tA}~8`LjLX`DAB75s|*W{p(-e43F}pvg%Ho*Zk?V}} zM(HEXFn_5T^!7LikGPtRd77V?=E9ozH!Zg2P1n?_&BQQuS&>P10r>Z$zxfmsAlOQa z=Kbi85a5j*q?@?0i0I`|(~yKJCkHJlPw#H4mK1&2g`bN+aViwyowoJw=ft)|H#0dJ z7B^;azBl@-K-F>78GLQ-C??oqU%V|n1piS7%>Q%L>m8n(3LA94!V)fXt{Jkm3HoJU$3wAcPK% zET+G71mR5=TcL7$u+>;}mU4eYhoiCl2=->B+ex0}b}{R9R$ggvDv=alW}^|M;}dOP2R2!fz~p6NMf41asf8N~X0 zZ+CZU`)I!UN4@*$fcN31AGmplo$t3K(Cd}iSXE|YX$JG6-7+~UaR$+0 z?WsC_?apV74@kT5!^vuCx?FUELr_On0p)YeQN@Ar|Np5N)jNTBH7*v-zefVpX*O&9Rq38Q12hcwE9P#zl+4|i^e0@cH zY)8EMyb<3;5KCsWjk{UVzfL#)`mBfY8|*eJ?3?@wUyTa;CVPi|-?v%G1a^x8+ckO> z6rJ5DG$_|SkM{~KlC>GYuZUD1u?2b98^f9-v2Ft4i8?eMJk24T8fzYp3qiI8A;Y!0lw10MKVU@?|I-7HDE&7-S($o>BnDZ zO$4ItC8EuKwwUR7GqRsdQ)GwXj@!CqQmICV(B?o$I^5CVlbG~{}y+q9ZZ=WlWRUk6wDIuue;Br)`d5U7)y z5e3=lLzdBOJ)VbknBTNsHYvpyE-FY^TqJRM!Kr#|gi`aflR;U_0X7EDR-{H^9gfShy($ zpu=J_i!3DA^vAO~nTYF%PZH&{l$Pk(-yD9ANXz%RQh!TqF8T^&9S_^X*$)Mc1`o@Q+@$B?xo13&K@;;&_OZe`WR;}YT~57Vi#PKa zCP^ifB{W5%uLN6DTE0o|n!&-sfm+P&aYNr+6^4%#k%RYz(s2ATiW6>LaElU*K(*sT z1=Ke_49ew8k-kh*%I{k0gUCTZsRN17X{!3nK2leL^e2>S9rPHti}JkVzoHoTo;p&Q zysw!#%sv$B{`=dVbzg4t%KrsfLuB2@^Ov4ZE;gA}hqHghm^C9KX6ZL^g`~Z(9Cl)w zSuD{VBmH!h5E%&Z*_ONaI4x5AXCUkJGZ~c4{MA{DwS=|KQ$m+OZRnx}!vMq>7Fkwe zv8sO)oL&Q9RzVaJ<#Sgi}7 zVF7f!%2L-R8lBw!zfXV9Jey5_-+l4_Mf%%#dItSHbW}U~+t~y9JM8aS^mlC6fd0x) z{g=^Se%=4W^!NC_|0(^AP0PP&GHo4)1{;q4I*LtpNgK(%C1NC~pK4-hrC0d)YCp8% zih{)KPI_Xsey=AXSnkB9aaC$zwAmZH%n_K0E}xGP4k!8o&Pg-sOreK3Ol&Mk@v;NT zvdTb~g#%eu>&h2o$ui<9BOIMGS$6xW0WEdO^Clh9j+TDa9a?%ZnMF&RI|a1#VVO@$ zoJN&+agabXX`*u^zkD@LcPKh3Z>Q%1{k>*}QP43G4|>4FR|D|W0~z9rDW|o7ip2!y zTTR)U9FpImQH9;o;);uQUd8H)SL-fMc@?F9Oh3hQJHKQ)+B@F^8l3(;FQ`-~!IJLb#(eq2ywiU1Py6kbpnkVyx#r*#EtuR)8aQ5xL zhJFiH9hiRadMZV~*XooR0Q(xib zIMg+Tj$fOkH~rYIK+w;1huk~CVPh-x4X@I=r&-BvLM=^ zH|zR)$Y;v;^?c{8)g{y?Y2sG1+5cP0sodz+F&!)xSf7(8Nk&ui3}? zuutW`$03P*Z2K$o4g<`M%DV48&QZ1GTFa|%X_a2Hv`T-@UQo2Vvi5`gS{RV>G=QNn z+YRU^eBn%=nDS3g5=#@|o#*}PaNAZ0uhcI&D=G_IOnKw-(o2_d)d{aM2ZqgK22lDx zUYO(cTgg(%9%#2FRlM?2ec1VZjl$*;ghVglbi<^mGN>|;TSsYZ|9U#L1t|T4JiF?H& zru%hE%!2=_-nf`$LO4FNSc?lhox0LmP3?DTxT!p+t{AsH_QHrV1#I)~0$dHbH?>M@ z<;7+fBp0|**nq^Rqr4Y_ zhcU6bZUu=NzIp#REvU~5z)Jmjq$p3gDDs}zo{34dS%iHu>bE|`*)&%l;vnm{o|&efurJ>Y;QaXtF{D`)c~eA#pBP8ZVyS_6Rk8QU zE=M?}s<*_g(+Bx9gXEuKGy{QgnA?`7YTfD+QW?7IimGx{zzisdx?Lcjy_U=1to+G; z5YtqMa*#(mAv!AGw5?yvpi<-ja~;yQKJ*m#9QSC*oicxBrzqoR?R*XT+|`GTSbf;d z-c_ws;5f%nJ1 z`$)E`Q{eZ$e-(ab?n&Wy<=_6B_)Q|IeHj+W2S7xQAnH4pNsK!jyZVPJ09#c|)wdSt ze>A?l-a<4C50dkDIwXe)wP@u%xfseL{GuxX>TdN<)mQVs)D-% zC5}!cq)^&u{SS?ZoPz@D8hu69vzQ1iS-Oo)GT4`#_v$-F2H&dF;4n!oEOneiV- z1LVf#<)~}`->xO_z0T|6vvb&WNu}i>EgIzrqYRM+QQ_!|eLMW|t*EN@G3a3dfx#=L zI}9FS!Icx`#X9_1n5T_mrWb3(^dl6imAj3ubQQxWdx5p44bCBQu5#YWL`poiA0jjM zcYhlIIXgd}zcCk3x?LiP3XjI8pty|&1COnX{Y54Y1m|GD!n?!&J$J%j%(^>okTGb_ zPIS&<&`Ej+PAGs)^Q?7!!CS1;QKq2UTJ-c}nU1C5itY2a(C-NhQ}~@GPoG5kYKRfA=`1sr^99Ddf({sMsfr^x|4 zktb~MXJ(mKLezjQ0!HR3I7Wx)pp2WOx{ENSulC^ZM)a@fYpF}l@gHgWYB7)!q9FSR zJEv0Fg@{Txi#U07hHZ|V&j9_zEkty6>xYxv&Nn=+nfgDh9AWmgIbg%lnJijjgJfuP zmTRbYMRyI6LpHN$sk4SoR~J`?<64Y#P#^NSd=UWgH}TwV2`xpy8~N3?lHZmjh!Z#M z4kMmxz17@MW3{$^u=625U^;T4EakI07AB^NbfRtecMh*6+iJz;Sz|<*VYmAjKfRR6 zc-u1P5go(O*A@FiKg4^GE$sApDD{SG*>9gESL5&p^sLrLp+#4iW{qsx?M=70?38k>#S;C=G*mu(h)^??LoIS~**2+qTtN@%AKET_f@9k+zgfmFU*~h&C)HQxs z>FgU5!%|Zr1vkxyVh}u8IeO{outk8KYT@zI|Dj$$He8MrcBXyYlGb4)s}+=8aZde| z6;;I|M_Q{Au@*HudK^#4QEB7w#|8>Q{5Ye`Ys~ctP}sewOl$x-Q3le+B#@QEUCmC< z@rnvWHZHG}*R2X_uMXb8ip+Xr{};U46P$L;YK8u=fXUAe#01#9#QF@drItX(e;utq z;Xf-)Xa$%XZT(sHE===3Sbv6YQwX@vPT#=sSIe>__bcy;&Yg_* zhUCaS5L$GO1Z<2zp)F#`-Z~cL5N4>0=O+5}vzH{}k*_yv{u1dfu;_3-ug#EB;}61D z>lW}+{q=fiE)1xCAABdH-_7$KM>o(O1QX9)d@}rT%qy@N`LSn_7Jh8CftRh^cHXPNm5h~==3Yf zsMyqKVs%zPfzjtlDgD4$;7)m%oDj~~IW}iBvi*SlY9eJ`&oAm+bWxU!rMSbb&qB8i zNz-qorc|p=1n<$uNRtnEsxJ<)8THyQ_VYU%uQQ_o+s?)ekLUK`IG*>>H=r5bEcf2M zQMfScD0lNZqBZ}#QBqquRjh#hRYyrMlH|g4v%gR;GXNz^y=yu-o2*s`|0PL?fP`J~ zHB^%<$(};10CFqhsG!L4lW~R34M!heWeCi@`hlRnz$A4X&#%*c#bkvIO3T_$P*K}Pq;KCPO5_*N#y6Az^&k>R&Az;Cer z{R(`@JjOs5Bl5hZeHfe5+mBL9ExE?k{xkkHN7$Fte+=C=5L?jiW4iX29BTzZ=^S;k z*}ILBX0vC|2|ooAn6iD_UTE5Ib1^u)gByyt^d8bl0oboWuVLlc>#@Sc-SBGK9tsa{ zdkYalG~s>QKjB$`BoQP9B>Xo&FFTnv)^PPfQRlL@wM{#3K5p?PC6uwr?Z@3H$4^EP zwKM56;hJ|$h-uY%3Tx^?l4b;Za9TNbdimp8M}I@n`H2r~ChLe*4N1_JLOkfcAis9c-$XFFk)_?gKmXMdcMmJdLbFgnF9HW(_N zG z6@Zd`%{Kw+{{9FcP7#B(GVkRpMUSq>aEuHgwqlXPD*A~GmDHt$l+{FEtQoY`CGVSG zMDo5@>n7L4M_VNGwjjVzJpzo(DY1TeRLS-Tuc?GSg&zpOW{U`#n;w7*QPegXf}FR$9Yfryhge#6NKBjjIN#^(Vn3`H%2fG>F{RRzf+IJ~-H5DY zGMyWTcST^ErG|Lf%(k_^R0v05s7BR{_C``tF8NbiAMAGPgO|Xk>u7m{;%VF((vJhd zo-s;h8CuSB&gd)!mCCQ8A)qZJ#`y-?%*NEh(YO!jP8UAsisHw6iR1N#DLQ$NA&G9( z#%+M{XgsXOY4(9{yJq1bzuB;KXnA^{%O4P^Sz@o?&h^fPX8pFZ$=&-@W#+QU+~iMU zUpBlmRHJ=$^xr@aJ`NCa#CZGgCjoka2p42HM3m}e@OE!161{QwEq#1dBXGz7NFJ-% z@O`LV!Y+BXV>jZsYU}D(tX#!?f%jnvqhiUN(oBF?$~`4;6D zh`-63qU>p!!+4a~In}YQ93e6NrL!&cf`4%=OD8cx#cEE@^KGu~j}JXnS8`5rzR+PD zM48B2DmeK+s^lEsKY5}ytBx~}JxovbWvRN1J0HZeAU4P9jV4bQ4bL_Gvp!hPZkDy% zM_`OnSCY=eBi0qE{-xRWvHx`#q!?P{LF~YH^=@zZE}!h?k5UURhO2|2ZqFrZK-8D~S=V3MVb|7Vz+wH8Iw>kn2h%&u#O%SBXOWpBh&d z$m|3QtK8r-iA=FtVYI?6k81$o#^Gaa0D$ktN(bM4>;sd^hf!2&6q%@(e8y>Wq|o1I zn=>PTd2sfMmPIjSKOX6j7wZGYb?|~tr%`(da&`u2Xf#86vZR6b!=ceo0x-6b3DCiC zkz%z$^6Kh}4YxcJj(uOG?lc<$dJRpo#qzsArV_(v`cNkT$9tSU(Aq7R^| zcfDi&;S(s9f7D5z*!PX9n>O6Ss^I$?1ob`J~L zi&p}Gc>V+)w*^3=m-?jA5S{UUzV~C>!RAWVf2Psz^#A9!{~av6yhl_F&tUbIG>7Tu zz`u~%-(r7T_C0%Co*jd9ZufPR?Q#AEx2<(B``eQ5+ns#BG%)fPez@2s<8%4KeL1V| z9rm>TFnRcWllS1YZWDKWbFz;HJ6@8g+#B~TWp=eoc+wfQHL>UtT7&%%yY?6Hg6xvS z#c($388xkq>gO3ij&rAbS1s7Z64eNubPFi4l&sV*jajxl!Cy{a(7KkHt!=nz8uYY6b8ox}T9f<@ zEqY4V#9rL_sJ>_)dyO|08WYWx%d(p++oQ6%`5DP3@wqx=;d6oP-?r6t#|R{~EM?Zc zky?t_uD4$GA0M(I(W2&uXM!50Lfkjpl*cH3ZJk?>>%5i!iIyJNz%AwXZo0{&uB`vq z5kp$M!DDx{C8lx@`ae|S7J=~HB|Phe*ee$iuDn&3`j-}Ww&Rc|NDkI87cLhKT&nm0 zX{=b+jox|hX?nUsv@xY}k$9yrpPB||J8oH<_?qAl&wcA-)=2RIM|K{N<<$H$fB)`F_03sX$F+BZ=NC{*?q#ZCV>{HE&)q-mzl-bic=k;Lb7eLe)_A6mCW@ral8Udi?U1jUu$ zx9+h6k^Y#3!*% zzJd_5E6Qr37nN7<+QM7C)vf!^iVWIR6Yq~bf7&4;l)g2wYcY#9dEMBG$7rmH zUWfOeh{TIZYhpiMN_XeR`yW{opVX-)YL}AwOEijhaEL_LlJGuBK1~wOfst_I0%~Nk z+2U}LyxQ_}@gk)TWc3({2`-0!30NK#w)|GY6`SDNO^zhtqpfNW3GlFeTD#i=WwPK# z^)y-Cw(zrv!-Tr)xp3#5`%{ShzUxizwfci05NC|Y3{?AO1`gR!Lp`~Xk?2;-tp|!X zvFL-dM7_j$#xEik=oM_kY8^OTZN)|p0M6KDWs!>4Lh%U@cBt_l{zh0JFIG?f4xNly zAxN-faXViI#<``{u|6!&?{dXB*b;)^P#bt2_9wXCA<_{hi=q;3K)6ATX^+EqFjs7z z3I1Fs$s>YqfsJ_g1blGYf26W;iSE*WhX@pp(}td9Z^io^yUoEpOFudRVKa(N7cjO} zeX;8#J8pb+#rDwczhV?}PC%!OnMMD_4WHdZWBr{P`PAHaddIBC)I6h(eYQQfx$|WBF0p$~ z(+H@NLEiW4#2dUCuGkG@q#$b@31Ola;j_U$T`7qK)XiHkU`_PT)q^)gI{mOkKdZFG zDiU-iD)oD`H47G*KlDE6E|=a0VD2T6&1BrEk9CnmajuyN z@96tIG#ZKf_qcB1S|jV!uwYsa>-S$HjkFv&E8KQ2$k{$*i+8&m&XBIggRLd(H8&NuV|WtGE&*TU`f*q*u@CCS4D3yoC!$-$#|OA74qn&{Xf zpYXVWI*zbGr7z?8Qb6*AA}#M3)O1E_fq&C^q;j$@%DIbH4VTFc>);QxVH9WoQ`1;- z_hgg1KFk_#nx0dSim%M^_Dz;hy{oec)nH0m%LL$^Io-RE-FV-}gJhYG@4X45ON&V- zJnF22$M)(MV}$@W{gTwEvj`%6S@ z5ek7mo@)EgPx{TAs{n0rT4-YQ>aRcn{$3L!M zq4=V9fxa~U(P})gmT)5M-w#cRFw0YdI9LMRRxajfrRW!)eB3@!WPCPgEZ*o{(s8>hf*uBm4A9@O=;j*&fbF$JX zNR5o2Ws&$fZK(`PpgMHNk@kz+<)ilO)?#8SFGtYvD=NdCyv-Zh=%8+bW@nAJEo|ZU z^tdfNEk7`+ykD-<;9Voo$0q6L0i)tJmC<};OvP^_7&A=O%lC3w@v;ad6S&PfqHUZr)G$^`#;^y#Rg^{h_UmK zwgtqJAaE~YNeWtLV4uAkLjNk3oO1($B_6cG&7hUUtFuH!be_ifh zyZbny+qr3=uV<-9j&&4T)B_#f-0Tbyk$JEYkdDLSjEN&l@4eL`amUoMXB}p{H>;sL zwyE>jxnVmWVixzHJl$Eq3EviNw^hgHm*WfW?))taK>o{^yfy$O7j)z!xzmXV;O6O~{nph2Ss7YtT3QKJ(CoIs+%H3GKLTEwl5 zm;fqjGyyXmMq}017HzS%?`v1J`XY;M6F?TR%2E}j3ofls9BOfAY0dxpJNJ2JCLt)k zZ~veFpO0pqSAqGfzeQlZ!jCrM*z)zlcOu$ASHn`A`;zr)P z((G)GoVOD=NH5uYgK%|=gxhD_8J!G%Bg3G78qzuqC4e;4-hQRF3G779m)%l-oF3b2 zB7zPRmzr&5pRw;XW*W{>AA8#^P?a5o_S)@ye4J}sqk)4vnDg>sXu>%{y3ZZQ$Ndhq z28Hwi{c@irP~7JmNT1NVcXzg|jTBZhth?rgfCXcpBk69qS?L`zc{M8vFjNN=MF2hF zrz6#m0;>g{Hfi<=eKo2Lj#n>Ywv&|cW=$vv-^Ur;xUvEgK4Ogq$Y&{? zceJUp)Q$r)rlkk-6(e_7zqkJ;W9T>BX$-xdpA3c`v@*56*wnfm;A*8qyyM;8;pzf3 zR3}AZjg`nb)PR;9#*g>oVY@o*{9t3<>biF~yxy_yIt{aZ6pUC;>)Xw%RGX=O{$Rmx3{ZSV4LT0W>lii{+uhjEMY)t|(LLu=-GH+5IvXdO%5M5tE7IX9QiQ7(8JRz0A4!w(_$YajcRe2Y zpqQ`ksHDZuf)iDtjBvph&Qt8m`7s{5t-~lXC_YXW=Q`KvK7P!EsXsvkUmY6U>{_w; zMzz|Mpoob?t=QL5aL&~D47ou1%~Kz#7fe7mMoz!ce8((Q=gq>oo~hr^r_BPH82!*k zLxKF1f7(H_%OC4hoWq}SN=YqHyoNspDo%KA6Q6oNIUi&&2-&J55xUUeG&?u}cwSGp zCO8hrnaomlo>RUBlo7#Y{af&=Q+M9~(C@)h?m$%%yyU8X%kZcR2db#M+Vi!DQ+ukd z7GDjaH#NE^rYM=xd{n|KrYbZae_{o=3WUBiu}wFUcR1=IiKV`DG8A8S6Fo=Tm;1!w z<&R-qGi~TcTZU$NGX_f$3T#?EOgMHBWoSje@5Ud%moFUr%;t&#a5ELg;sT-qR^-i7 zh)ZmT@VgtT_CD61_xRH)j+miAMOp}p@GjPAYFLS2HBzl;WPW&&i%;qp@Z_Bkl`Chp72AWPP1o-Z(poyXg#Pka?ley78iZGP^PU5bK6TIRb|2ljDTey1-d# zoiY31mS?ReXzN<4Ivd-p*E#hDxvYU7t-Iz(0*rH!$e(8TKz{;7c^A)8Gt7a5@gN!- zUmcBowWg`;*7qcO!J5X`dgs3)9$`6ckgjTZHeCvPH8LMj7gz@n0*=(!6=M`{^Pwq# zRC`c>YPM(5Z%Jk8nmI2cN8MW2R5sLVpr02__cq|g7T;VwemZ@iK{=1zrgoJ*Za*>) zLtZuB2zK-%KOk`!LhjM{wlX}|WB%G0zU$}q?Twhfc125HW|ztP9XfE6Znpf1P*;Kj zQQts`&?P0y1)jNUiQnD`ctL6=Gv)yU7)S)q(fTgxO%79{5Mo8(P+-C#`V~Yi88@#3%~t@s3Y{ zPnVQ1gvBKhTK|$c1Yi9-l{J4&Gk81t1K%cXV`0X$6&V!h_~asQ!J<9pt_ZF`G9do- zjwu8*29vdiUpIg617&IZu}s5A6OCZKakgB(*NNXci?Vy{qRHZ|8ahVg)-Od%t7~p` zJDYtIFbS91BJlq$IN%YYk#+?ZJ17P(xdZSv^RsG96eo{DH6cN!S->d7I};c#@!t>p zpmQ28qFsHn0(?|h--T-0<(z5MYI|}x^Co?aGN`8IyxP;&}%?QenorTx323B@q>oPW4|vzm1s#{6M_ zH#qdA5+cmy*m!MHomz;!U&eHL5;ZJ}Xkp1_k0shtY;<HWl&%u#m z+M%v|3xdO&z1-H04H)1wpFmv-RjPnuOlJ#S6~itzW^ISxnEiXfZ!(c7;3x|EK%7cU zyVx;pDvb27|IyKh7;G^AE8~{~A&76isTc{f1m8qNqCdVy7L2Pg30$k$inCPi)N*+Q zw|dtDMEwFcc+7hznF`aeZ`;C=91a-dViue#CDI6O&@>t%*;+ESb019Rn*U})CTk=T z*i^8v%Rx^BVV9NNh{d&kUAp~@g1>VRWU;aZl6Vl3C$k(Pq*EMxd4xiZKo}eQt9RTx zj1@XDM?#Z`0==D3Nw*v%@><7;%FKT(_Y1PPl;LP>AREh(%kA3s2L=sL6qJ^zG+!h4 zb-mVH=WLXoU=0B;bq;_2(i6;;&nAGem=U7h_aEPP3Lx&0PdZkmIEC!j)46l@>$zAk zj1F$!rflF$n`hh!P0TIjh!r}g+i$ZwEQWi_L67Pc;W?K4v)#n2vu|x)Ch}(4=@s`m zWdh`zww4I6D-SSPUci{KDe?tWgj3dL%8`83;DQ)ugbO|i&Vt>jf+n~`@lZZQO!GJcbr~EIEGwJ z<|mhVh!NF4>x!nPv5{J3kxV$_59>!dfB6k84UT^t|6kxyCxSP!a8)Mw3$8A9ni^f!~TEMsP zFaA?gQ7LqDzTy8F;dL7JM9#tQXjq+DLA5)qLPvVds#og^Z1bI|7JSdP4@0NEa|qu* zX!Z#2SC=8fCvs+X2$<9lkTKgvQN8KXTT2X*?x%G+lQe?Pio@LB*0BPgW00^^VnVcH z_zD7O`jTJ&F!sK@Q$I&zA0-xEn}=Q!fiKp$GW-jL$V6xo@>FFk>0NcX^o+gDB=_0g zW>l&LaR-*@w2mn(nS|XOmK(h6sNhKj2?&S3t3)Oh@v$dy$i?RRnu^4%UKmtuYtth) zsWn@?EyCDdThsHr4l2S;)bS0XRoDx4Qf|i-uDk*7egrr}roS*cGU`r2j7x!tv`E8L zED@+gB2YvkP}FQI-orn0>t2C~(8MYxg32NJAg!nzbWz14kxZo%4v3&Yo6q*1z!RQINg$a@J6Uwx=$E1~(u+5(jL?VY|C&M6F9)UP(W{|_3W)@LCdC=W`azM7+xVI==%?+0JSPQ!!K(3^ZP)?{k&%1kN#?QG$b@GUI*lPUv51IJ(l^PYagW$sC7jO4Z8PJnc@?1)B z@-K|O5BF&=mj#3W*(#+SP_X(-vPp&IVji9ZPI5!{&olR@y+-v8(8@;H+BMMP$P4Y) zEwEC)#MYv0CCla4E%Etq*g2ZYrhgUhMgJbN? zz)TkWS!p^2Q%lLV1X z<@f)|*rJ$zEjvoiUamj`t_h?i%8Zc;*oITpT(d6F5c=_>Zj$?LVzpCSIMVoILXWkW zwQ{Q?lC9|gp6xZONlliVRyG^uT%ezfhiC$_Wa{okYj;Z9Tej_P->Aq}+V1IzlBB}kzNIFhZwb5lXY$xWci}e0I6p@;@r;S|Ddi6TMuz_N0bJhYuNi%m z#SjGgL_l)BN`YkE25=#v*gD;uI<{90({rg7a!R%N_tpOWxl|eAxV)qb}{rbvaB6Q+khf>^9MiubJyZlJC!P&CV!p@&AE$js( zb4mGY)PZ=;cpiF7-gFw+Z|t2LNtIbI_yE{$ziwnj#FFlfAy*rswW^@CoX@yOOWA6- zX5_ffZ4g13vogHgu9pzU4*Q*N;RzzLZ0pK{<`CEX&*h%E`nA8Lx+JjP-Gw}+MFJP> z&%l{Hca1Av{Vzh1j=jgGb|IhI)Ly#TUpJ|pV#!?Zs^4jx-L3o$7HOJRt7?!6=IW#R z1LXfYjnY-IBjn3mPqme?TBI6DUQ(MlK37%8RtZm!b1BVqvHcR`s8>8+&#(8PqTd)? zhY5F5g0ugV-+u*wHS=rT(nS8WE3hJ8)++z=u2av2`!C`Y zwT8|1-Jc72DU+?kk=O5OCu*so=4{l|6S4k zH)69YN0MivJ={EBO^fSI=d(&KX&Y5G>mfX(RlqH4#gyw{0ViMJlr%Tk&eV|ZlF#gY zB1p3Yzjg*nR*---NO~5tucW-Hsfaz>aW?DzIq_>pB0P2n=74k@Nr}`;2_@0t%cJdY zpj_4;f^zw8{k2Xa(XQW*QGXMmJFa!=?oH=swmlez?$rcr?6cd9Exls~>K=zG9+GNn z2NBzu_IFlil&L)xN;~925@xM8et~Gqd?BBuTDnMg#K78)`W-zhnNGf&3m$#>F7ie7 zzXycal>WC#)4?1}d+L8n_C^2u{{QFt9}=$gKU0;Q@>d%ue~m_W6Y2s*Fwp;|OaHsV zF{Oo+$wh(prBP2&Jv5&hX_J-?H*atpdVLqT);?gZmHxNE8Y&+0 zD9?J*|DOI|>3?i0`yBl*Jnunj4D<^vR4_!RzE;HEV-pj3QY&QC&N=7#QQ-Ekc)XwA ztN{K9@gwiK$%C?GzAtH9Z5lQ%FeYHpsQP2IAk+sRHharpqi_LE3SA?hLdNrg#G#iGCvv)!Q<{A)v6N17j zc1~8r*hklO6|anKkbJb|2l|-pNlqk`?h+Aqj9Ra>?iz|*bP4V|H+b+on*vd-`?LY! z0gZn)S5A6w>!fu}n>Ow>ZPZq8 z_*XlLha>SS*Lo~Wqx_23qm>z0jkCROuln|y4GugaRnrV;-6^VYjPc)gW z;s=#$BW4doY}I)$yu23@bgkJ}`n&QwUx5C0?KSs+IP6~S=RMG0^*vvl{+#?&lOnxs z1wvu5NWcax>f=#%!PLGbB31}5V&x(JXOvyQ;Trla21=GfXWfy5)$j|Hj{Dk)Hc(-0 za_XQ&W7##&vR1qJ`E;BS@L2%8VU z$?t<2#GgF3zJCx9$?e;0>cL|c8m|3$4^LXpy?B!2RX%@Ubr+9HY4>wG8~T#viipf} zLE?6;D!$&&WHyc>iOI$**g6dgqk*pH$jfQcil1`K#s1dX-#UMYEc($_TX`=5fna5S zrWT%L`-u9`Dz}x-Ybfz|5&cOmZQ{(`Z$eg`HP}LT-3D3Frxv}TrPdeRNP+m^+HY@_ z)cWexB2>1UP9l9T^4)2_^0fwSH&wnQhqY#EX@hLmd0)5~ZQk2b#tC+&KB#za^qY>B z@@Crpw$HV;cKmt|Ug!AFPpQeL;fRftx6*b)+I*c@Ebej(i_c+N&<;g%IiDD_(GT;H z_!JDFzVI+z73u0wU4dC~tVC$#bCPQ~;yd8 zb5ixH^2>V#2S`Nhydm@N88W;(=lgS(`FYx21Y>^!8UH@T?;GsQG}lB`pZ0Bu#G_%=FB^bcNb?b6oQ?n2vk=I{d{0(Yt9|wG$mAeH|@y9i=}<5@=eB zc~j@ms0+1h4j{C$r=w=vsR7U4>teJis3hBo(HHmPJ&mxZ)(>AJ!JBjG(MpY20pu~Z1hT>jAu;u_W!xa*iWlI zX1W5`Qwh7z~;^FPSCTMuAyiTL%feo})I2Q|k(<>aO*GOp{ClaAGllTfPjOODjl z(Y%o@MpBHZ~$E>_562XfYx@|JHuTz!mE;v>P8vz5TV^$_}CHyV;!$%hCo!NCaOD>D~v!vtV zJ*It%j%|MI)Bf>;?t>(qFZIe6=ET13A9wTPkYMR*+ScX#99u668fRag)c{ARgVB5( zp8H$lD`-Kj{?@K`_6@9JbK^mcgrmyukMl52t7NG5n7Sn;s2sZ6>C$& zp1N@3laYT96vFizXJ3{@N_Tn?Rkv&Gq08({jn!lTBd7CG(kN#PF@MQ|8hP#l*NlB9YkZF+WLJn@;PWF;(CetYxA8Z zOo(=_)%&??Z(-?CXg1Ae&WtHxNx$;P;-1~&wG$WT@(oMbt&5_uS4eg;d~#k^Yh`Kg zhPPIYzpPhsv%oNDT^yXqXJAsWvehA&QxJdLvD^kq@|l1B#l^@oHc+>3Yg0FoStO51 z?%Haap>?7@qoFx}#90~NBrARWV4<*RsoUjmL)l+Ban@$EH*6;sdcCPCbB79yVL7 zQZkJFI6h4)<^wkGM3}`Q03kcQ7~5ekkSjA3iNcBAhQLOO*+r|BXC8R>4>Vlf^%LPT zhzk@kGyODAl-KGWD{WREt?2Q-@V}}1li%5Wd(e;FI0$-L9+z&1bq$7Bo}I+yv_`L7 zy_(?IO&(Bra>U%sNSt8T)c`K0Ry!PjsFY@YDqqoVwxEj2LGs( ze91^~K7;Wou57LPvU+ObqyhDwyWMYgas_ZQ>`(Wlgvbp0Q_7B{P=Ky6NjBn=?lw<^ zbT`eAn1C;k{6|YAhOyVrob5jTpH!i9ZlVwaUKh@F;RxXaAt+aeX+$LgQRDsBLm(oN z^CJ^FO)j%FfG{=*^0gu%8Kbney4bhI8ztU80G+QYuazuX4NDWRt|KwCek?o(qK{pV zoVaRclMd$ zX*%wZxk6S?5fyA$m;@|SVCf=E z*#gN@fXZnQ8=eUHP++1yuST@pP%b|1j4&sO#eq!QsB(# z62xF?y^#>6a`@L%rA{>)9a$w|F%8mUB~FXNtiZ2s)PBLiqC@&($(}i zKvJtwyrR;nAAMS#K1dt|{(kdAz8-NFZ_(eK1p2pIkZ&Gg{uulqKW=tlf5|-mb%D)k z#kW4LkN#KZ@8qSX<~E2QyS-ELT)rs7ELbkdYJk?s29_9ol&`HtMZ%apq@!?U<$J-+ zUc)0L4;eV9p>@LI z9?5Qd6d51ebC!HA{o<*Y{44t1e$)S!ew7l@pM%AYbQxcZE%n6*X-Z*GqLX?zyU7@7 z=CsMYIU00GAy?(|oy5RZf%vdJlQI;BNt!s%VEKS9fP&)t8~<(6=>pydzXN-ADU4^} z%v(aYx}mFM980LJvU|l(5BB%<918SB=Qk9dt#x>B|5Sf?-Z++|G!J9SYS&e7Tc@Ps z#X~Qhs=cCNj8Q@nPbOtM`+Br=eYol0HgiTP>#C&=8hZ*8|D;n|D^_Por-9#RS9Gqa zEN#2x!peAmccRDz*<>f`OZaMU&L<$kWKFo~*MQ-DQ`x-Vh(i{f6CWBrCw@hk^GZyTD6m9g><;g8E-Pbey~*}ygLfXktv2@F>e>E? zW54^H^Itz}Y&2#@A19~ACK39@T;!ZpS2?D5m=K@H8G1~H9RJR*;fvOEXCJ05pJCrq z_dcr)R{y1b{mhTtXz9TXxe*dSW>&IJCIx)MUJhKI?hFRXh2L^Vw%*xsS zwnyz1d#gRSYwgV`{FkTexBib{8BEdt`PtSx#4{ZQJ`tv|o&yKGH<#?Ck3XN;rH?<{ z+st&&-Tchh-y4j zD5f}4GOM6rIKx+@_tDa`i-OTRmz801vDbfZJzL+9*|Uyv@i@rdIp>04s4^$ld(%3J})ao|NuC*grwG@pmisz(k{(PCb}TJ%lt~oS7dC& zcxZwUl0BV6ybdcW7nCuNUvTZ?{g_9)Ei27eFx_#ZClpHDvW)qjC7`(Yj9gI zZ%B5JD1a*}G=g;F@fPc13vqfvx(CPII0 zmC0nCnKPZ<@{a>Q2o}NRI!O*f$WAUu)9-&9{XX1{epCLdK);!&`eEyE`#AK8&SA&N zMU)}hrnlFeswgd;dglgJN|@#wh&%a1RbFJS=bu~UKS@^}(BDbj>F+#Ef$noBEj{j) z3cNqm^*rp!@1^EI!z0#=hg>thF#QJ=e39|p=l;PdBpvU)fB*Q_f4YC&=y!fl!58V@ zvHtj_==WIjeOd%v1;dDlvEI66QXC}d&HZLToWDyGCr1<%7A9BjNgo0KE(qw8+(*jm z=f^HGL1x*KK+a?xO z37vm6hmmEY-{g&X%IYiXB0&A>y3FxOKCI4_Sk1q(&i!|n&IR<}lYJqjf8+-Q;Z+0t zi|QXn-}@rJo!@U?<+rtu?M1Ru`_eo&nU>%7UA{Q}@h>i4yn1byYI~3`g82t4^X1ns zhZj|oz#@`Wa(=E{gQ%uMyz2e-(y>`xYxqURAPT?Xd9s1}G=#ajt^QWPAJX*3VbfY0 zcjeb#sMyYYipXkiYmmKcRsD^-4y-@8ao6C6A&S?`$M<+OX_gbe!mZ{{TcbIYW=3urh2Ie z%z@c*k2KOO&59b9gNT`(IGC&tj#HA1g*npG+%J*J(pBN6Qv(Al4jJFmHHn8fM0N596OE&_G*&qDs{3_kpt2Qj8+z zLaB&xUQN3YOvmVIWo%0Jxv{aY?&uf}o~E_ZzQN(SIuLUroyd*$+E9uAMEPI*Z@NGg zt^~T{Eed3Q&>-x&N_zg_NkQ~YW!rJocumBhICVB-fqnO?Oj5T6w&PU3%pk~amu`G# zr0omA_(GWnrUy7)U2FzKMhwZ6C@KVs zuIFb@j8$&h(Q%Z}v69*u{y_rgns| znj(ZoTo`bUx@hT|`pKHbCY;sC0vB5Pdtxg;s?jclyB306?R~z_03{E?K7N|{r`-eF zEohbpNrW=m$xR`A!y?*~Ul&rQA&_=3V3uVcGPn|_&D1-uWfM#*!V<)W=f%>I`SG2Zk}bkn=hrk#$Au6D zokZ;eX~+#XHnXrl`x8LY9M2|w1_sr0*#8d%~TV-JKS*V#m)5iV%{P+;$p7c>-?+GMDt=%g2$Y@n8RtF4 zrTREe^JD&@mS_g(j<;beCR;vN8GF%o zm*9V~;D-H0iT$F93IC$+(M?{fqxZFy!`C!z4YR_ohB@a~#rsz#26A~`KKmWR&3^!1 zd1Gl-{m(moCeVptk0DDa0aA;)$9T#|Sefv*U2*>a_Zn;t<9w_B7&M7W)pC4>oozKqP0*w>_A8YH&^u~xaJ~<-8H`4-a%CM4J=p7|` zOU(CUYeBU)f7_1EWSE83-Q)k`frwUwu3jJp1aUQE3u}$e9sN_E@RM?W)`S;T7M@{j zfUu2)yt;Hnd2_ESl2c_1e?!9ZpH-E@{u|z|qTOgONO-(T4k%wn@vQPC`WtTky$w8E zU36(xD#VW|w=Y$K=gp1AU)t}2zs%nswt@f7J^Gy<-N>Wz=Dvkh*!dxh`eUm~ugY!s z2l;0T$U|eCu||uEtJ&goQXR4>*YQ1;MejR5b?zyXlaM0R`JmrIT*gY5W@zxo%RYmT zDgJ%;XNfP)K6QL|{ql&+__TaXcp-1oHG%ogD`LZHa+T?ot)_c@j(sXTFANa}b*L`| z!UyZ79H;S#`SD`*+@d86_Kvr?VD>sKu|9ueY3UR6$s3^)4~GRAa*GiAbS+95@c` zDk9*$;`_r2=eE=LXgscr1mQ)O9D)+kxH}K&cdb4_{%}#-MUoGGu?VL1_jApRW;~+E ztMQyb!jMeji0A3w6C(o;FpJhC=MEUtsLA(=@&Cia*k2;vMd=F0sv^Is>|}kR%`Mdh z-T_vK%`Mt55H0YAD83AAG6lG@Kld_AQ;*w_zmO zx|~f%#iIjCCk|-fBtFgqD4m$wFc8_2gPd37qyK4Wjhb17>^F@DTi}W%mbk+cSMEnEaXTbNaKQ6nq*jfJYqt^PyQ{zN0#ozd4J;=q|WdGyGs;#*(+4 zkmVgkq=4;l&?FCS<`G}L_p_ny6e@k_9bw-M4Zh1+rtjXxS#00QnHYLh-!-koqUn8f z3A@yF;CVOlwe>MP?{ow^zkN|-tSP=ZU2Ac~9b#GRjhrS1YWzxal$0|m6%pw!xxb6h z%jDR~_yWm?9nOUXdz4aw#&ZEYIDt=@yJBxHX$ft?gTpE1Vf~L9OS0;JkerSRUm4q| zIQ!=Bz-?KWnpPpTu3;~S&Rb2%t{ba{uPF!+cMmrmHauG*V8io5=> zXnctTb1X1NO+(V(kvnHVwCU4GcCm|k4e<^*r{%QfO-P2GZZ016GiO`_OS#+n$<=@g5ck7T`?tz-(C{E^h88cxN++>%51zYS5*Zbg?>Q_iS~z!Ak!ptPW?XyQ~bE zR)^7#(ZSZU)xi;WtAm#6p&0r18w{%VviX{QyTkcB`5e20_v~NQw+ySpQ}!U!>ae`t z2L75B27czJJ9-{u4N9ifA#q{PW8U5B5DEl}jQt791Z_m%_9r;|f~jcO7uIXGp?YrS z7eVICtd?Nc!ZR*Q7CYg$s|=>{8h*2E4K@KgH=1zK_-O+Iu1ObP4Eq;tzi*|e4pP>lELJ4S;VG^w z-l$sjBPs@w__Y*k>V%PVGAa9byYp9h2|->6i{;63W!FXmT+Z+)w4rE{&}=D!NL z6c*15ko;Lgp{ltFr&}C7!}3-@OYqQgIf+XNjD{4R7p&-~4Sc6wWtt zHWk^IT>D(Q6ZXPCZBA?VS~gt2gvG@BNl|o)07{E7RoaZ@MQ0AjW*4AIR?GV1x{ms| z-i!Lv!98+e$Ie>eFt31l5K@!EJS{(|&bZOATj56DPV3BY_h@Mok6z+Yt9Qcvfr%j? zE@2*Kjt!+n%a7J2V_Du?)tQV+)(E#a8Kdf$mNF`se0y|CcC-AgH&Il`Na<3SoY^8eSobB>)S!mSl;($o`B4{ zP+%G?7gnvZI^?zR*t^Eu=JkcOsl&uZ*YP|V5@u^nu=|6JKT%nW&Xbd~ao3>wP~)yI zV<9OWT}f5p=KGB{w`=r@yq)*Ur|V9^X)60mf?C6K&r*p*=(m$0=-Ck?=neJ}1l`XX z#tLcrZ#{=U4f6hIzGWU5{qoFh=rG9?s!fz_x;9;tm(+|&Eq(}W5}dDNPoc_tEiH&kU#IJL~#e@@E~2D{80cVqMCAe(C`b?IlN+!$ezW%ZjZ2EH)O~Z^KW3{EBzHoZW)WSpbs92L9Dve}&(K9|^OLAr5 zAuUGYu!Sg|-wkuYsmPhK$sDiA9Ntc(QeWU3ie|E)yZ#oEg83i+qD*r}r;OP@Z-g4( z;k;%uSU08t76I@?A7GIZiYQqKG2KE+ms%^BEex037vsu zGlrHKhzZ+8pks8A=0JmX0l-*FqVbcLMu3te+4`%HJdP0Kui8;{MKec?ndx-S1xPq# z3~+9c?p}~p@`6-2ee?+FqfbTSQ?TjSn5!97RO4MOHq*4S$WQvfulGvKY@n@I+58!C z3v*!X2VLesx78=uAI=akoZVL+FJm}0e)w;@;0M$sL#-lZ;VM@m!*N>cp(zq!uooPo zBG%4waUS4DOoXt4YwOpj^Z+S2qUP%CWR96N=mh}DXAQch`1-8T*bHEP49qRbFDppu zA8Avj^m*q6p~x0?SSBW9Czrx@q##lK<(pK!s)f*5EdiHY;1HK473A-VF0>*~S0=5v z{>w<`(=fd;uQl!tkb0QzpqBc=f&e9Q@IFj=RZ=XpAd8S3St(@-C4C%27liS{gd3=e zPbFXhgl&1^r=Z|}O7?F!o22l$?7v=BkDIP7d77|NrVz zYfbjyV-vE!O3!d-GPT!(1>D#^@8v3ukFIoL{NLZT-Xp1?|82=2mQ2L?*V3>2^95D~ zLc;Ca9yk018+I8XG=uYsqfMu#)?PpL9eu9xr=ZIV19Lh7PB)h&UFY&?$0Mn=KK?r@ zCw6i<2~u7>w?A$HwMsl+Xs=kJy#8CH0yrsO^PD-(JO=3Y9c+#GMTwN$v0_p#?W{fw zl!D|??*Q{_`^O;2;pYIkC>^6U;JNSuNJU;ht%&y(wpsl*Vc#ECq*g$}}Cfl4nLE^r26A@9hHwvLqEB%!jaH!s81|q1X zvhaklj4%FA|G);iJzc^)8l8EGUHC;6dvlb}?EwH+#V^TKMpT8<97R*_x)mWMIDa5@ zF+nq80&}1iV-5$2gcCoqZwr@`Gq!O0IZ$^kX>SPyCZl?i0HkYmirE|mUBE}B%a&Be zJlhPM^BR*jrA%2k5=)@>u?6P3JnYff%h69>)08QOKBJ|t%$g!nkEVO=dK~ysgTqKt zNAHw$Oq4#TIFHG>uv=lKR`8|^k9A%L`}sN!qlm4qTOQbfR~wI3&J!;nq+Yx8eP6bK z5;K-b@8EGguaF(PGIm?9Riqq!hti3!HpDTyMXtO(viUK@-k7gv*m%pcz4LZEKy*q<{Ti4= z{-r_wjnQNM-Wl#Px?$^kkblGXKM?Hg`#G>5iu$Kydr$rOy`H!1Y&k2F|0W;HfUQf3 z37@t9!+Bf^sF8B`S`dx>x{<%xtyelRUz6yqTV@2_Hm3KkFue*-JzS2+qmc7u=g0A4Z)6f5vK0XgWpZEU%b^2Nm z>4M(>ztPwKz5fzhK4X3@IP)|6ulmFDHU_3$@{f5PBRLFv<;z-VST?3%usyjKA_6SF zvhZY>Y-~JYz*|!}5S>gX*y_+uM$eXZLKc!-FNtSbI(#DU#JhAld9DDQ)LX`YYCe=u z7Zs$FyoY@d`x}V&XQeQa z)p1k-)jc^gg}$rsNV^f({oPcHk6{QCp>zBeM>GP*xc>QIat+M2X)uSUz!dyf3Jj;^ z0j6Ijm?CfUWY=*#p0s3yfk@$R3;to(nx^f_4h$I#7-6n zH;NG(#om{@Q5@p~WE3%4rAG1I`vqO2`08aR;D5VWY8Deo=>dkLc-bHhr`9plI*t4_ zmpJ4RTS>3C)u$T#V;t8GaocXU1_PjgRDPlUese7profx*18`*bi!^}CQUHE9F92{@ z9{{X5%i-Ms9Oez~(t@iE03s0NKNjEXkQ9__Qq4HDFHr8tgmS32sV0*l6sDW;8m?{E zk7K?aG-Fr@0OgqghI!xd0XTN><_#&dml)dbt#xQ$=Ys?7B^hXcV}5}4t5wjF@HzX> zsd&~0rR>FBS66?3Ym5}>n_o4S9@eTU?m9-aq}*xMi5 zeLPe)Y@--;EWewa<=0%Sb9!(j>rc!-SxtHX+64}6DFaxbwjp1fj*hG&+0aOGy))&_ zL!OAn`9yJvIuC=;dwqhuj?^c3P0F7Tw5R*8>i5VN)j2MFapx74@sp0^poY$Ld0U@? z{XK}?&VOED=7~h!8Fb#fyh0VNTcd3)x!&93w|?@FIf+%*!xf1+gzdt$ucp{8f>G zimuYF-mO|(Gz z|5pES;k5oQ-O~A2rGI2-m?{ZpU>njo7r-PsiO^f%pp7<(lG!fjp zNMM2KCvA&Sn)WU2&%RRyy`0{&QNkm=G zCw^h>+BxugS@KJtyJ7#1N2QAMDk8W*T1VpwZpzR4Jr!U-R|I*}?%s1^X7-8K<&Wx= z@#aw1Mf7|1*Nvv%!WGfZ)zQ*VZYe=SA8;z$If`c-&)?EnM_2V~J2%m{vAn5$J$sMV zR`ps_al42&YtHkdHkL2e74gRh5+d2qZ`4Lr6S5uW&7_mtkGC39=A8wCV)t-iF!5o} zO%bC(E8|STMCid{mfDNQl1mjf@ZbsTGp(MJ{aeQYAt&RPql|xS&`Qf{(Oi zY&NStjehc%X#1yUHvPT8d;pcbI8F%)s%UEaRPCeKY>F{&wXdafjkZAC^$pBMYEiYO z`)nPUKx^xwaSp148ANHq;c7x6wEG0AT{JGUfxqHyU-$OUywz~~G_*q*J}TCx2jh7GaxS%SjNo z#pmYlQ+)2sLj(B2I}ywV@bVNu$A>op)$!qV8BEN{uT!Bq9|i~$;b|{5N-0J~!t0hp zo8iQpkXCrnNe4$7Ki$9KosNxIx{*PpD44SGST^D=4AwWp&(XbDF1`^z1;(uPj|2 zPP}4`V5(HQZRp^$lCwBI*<8`SnA1#X#3K#t7O9bgnYMN@xOP=fH$W=cmdc& z`NCI8v=} zMr~p1K`-1xSW=7TkK7U6@fHlI7orq(-9h$rj@sEcJU z;z(w7Bwt_&9mrl4DX>{6pPVi=w3Ec{GTJkx!1qp<-jP;>Cdu|RqCFYd8E$#IYv&+L^E1|HDF+{%iE ztF~*>MKsveP8)@YYNDl^Zu^m9=S^Bl_d^X~>LN^elZyTEvL5MsqrZZVlD+gz{dN7@ zKUmtyUo42zRRNu};CF&YypNy&WGaZqLfk`tJ4a6Kb;uvPKk?N-Mtmb~p8jmfC3;Ec zvKn_NeIb08(j)6jXhTjw=Ln$!&;VP0z*amfYdK* zZmAF7Y3}^k3(*nn;)9>O8g1VR%UfgX8JkD#1L#PNSEecLw@@Tf`_{fPE2AIH>4RYP zrRic|Ln`8@bL{AAPQTcK-?>VMLEMZUys0WSpif0&a<3#l;TH_LeJ_mr;1d`1>ewl4 zS!JN0IJ20BT4g(4_W2L-iMO6VV^(y;%PFtnsvY$O3wNdd! z3$4Hl(b(u8e3@+slh zIH#$9iC;gvs9gXnXZn?(`@b|;Jq&H+NB>%K{=`*NS&p@U>`FN+xi|j3g;eC}knmsG zcSNHV^wJ3WM@E6gIn=Ge3Vl6j&E?%%Q$TBmQ(Y=)9;yD?0%;apOjkc>$OqLlgm!G{B~J))Eblk`wB$U)-=?yLR7-xsy?1t(mfWNAU?B2on`=qbZ;5xV zL&bW2HGe`ca*;xXFMl-c+#iI+(Ohm2~l5xUBS`7Q}5NpLp z{IukB@|XQj)(X+Z+uVDnc4@#LdE~NOKnri5;}Gy7zZTaJGHEBgNUFD+2+vTSiLitp z{cFit!BtaP-&7sH;NE-r?95I+phsu5Y2EV^amQ9b(}~dCBhhuP9_b8CgxdmW*=0hR zS)Q*qAhJAPe6<;x_~KH&2==yG+q`4_&z<3VPWtl`Q=flzR`B_unV&Ne*x!A8rkSfO z{rLyu)dkgFl=}Ry$7j^8_IkhaKSzJ3@t@YF8vj)4^RurFYG0W7x#`c}^gnlf|GhqU zq4bM^mpq&y>s#f_WIyrYp;GHzhNZ0RD#3>h=WVXU%)I4yI}iu!ttA@sn=j_!c>9_& zJSI{uG+mFLv~rbJ4ku#X6dp?c9TF6^tuW(wO7Pu0nY`jTcberZ^uYMMtYwlQy^+H| z>0BLA3<=JI&|7dYJ?8Rt|FWsGPJ4gRlq2K=KO{G%QGk`(+G z3Jm^Mq*Q?ZBn|)J6#Q?e;NNcWr*wgTorAw>m$iSje%OCIE@=NZQ}BBO|B5vH%Tn-< zNx?5S_`C58r`vzLgFnr|ztX{=)c65>`)WO_N0ei7Jq_VnfDw}CA8U4IJ@XU*L0lCzH+%z@=t^aN5i918b1?i9^mlo*p&nVh{E~BIkynv=?&4H03Gw zy{^SR{RTia1x5c`PBwrt-&69st|iw5CB3Iyu>)PP@m-5`&H$hol9zDBPUX6(?5|Vl zu;#ZrUMtD2h|qBr^z*;XXYQV+rK$t<>bQduBRPNcxZwQJ-2*@9gkfVoJ8*Wk{$NO$ zC&2Y6f7$F`1eQfS`VmEm)TsrD(2u5pv84b2lOJ?QL_;*L2wLTWam+aX!zfjcvR1jL za6%;-H_w)$&SRmQDbh*@mc7oLS{-U*$~r+ue9uNY*inB*t2%&+xNff>z0_3L-C8Dd=M$WmDN#Q!N>-mK1ks$>C~=IrF_!XhZV;p48jt!;3bOs z!|kTn-3+puLU*&j-Q>HQ#juo?&;WPyOS{Q(H%GFJwuC;s&_EBi8_(V3*v+5ZO)tAy z?{5BWpjWyZ&u$jGn?KvlFWt>XyIJUNR@%*d?xw%pw78ppvmmsD=D3^p?557${LOBz za5sOpn;LiXlHF9gn{{>*aX0ODbCSDx(r${l*{k=$+0VB-{YQsm`T9?bjqg*o^eJD6 zV+j7qY3%b@XzzV}Ba!n_E%Q$-!TS}4R7_0aL@~D}=eV;}r`z>x#ZWz9-(DaCl#6nc zzFn)ENBuX`b>pg(7|xBBVC>hu$6~9PtwSvuRWzRSC01aJwVf0B>BJNt`iHJcU%lb9 zAWzc2&c+ z`j35ig4EAySqh?Rc|`n;O5{|j@vh5v(d<}8^a@ov8cp=&`^eUCt}F@%_R;Tj&VA7D z?C^n+T&AP&jrAuHI{pj`v0XHY5Zl*RcL}kT=^@`NDYCN`dA$$oS>ZLyQ%9k15|jO8 z=Jl!h8-y`k%wd)mpB^o(&Tpt7r&&SC`2`KMxVng4+(iv!n3V~GUKW%3O@6)e7Qd(1 zeT;bQ@lG#Yn z*To)oa2GJi)jqed?@tfDkH%ZKiZV*?)sOZhw0iDdKMezxyvmQ)0{kAE`q;3{rl!v~ zIL3#c>*ajcBB9SL;V_kIVBw!8KZJLY9$OHJcMUL->4Tn}{VK!03+12{I!B#OjuXAH z4~{$y|Clt&&7$q$C(f`84=weDBT4g6PgJ+ro~Fw1CG0QGsyTZ{j(V0D_MLMFXLZ7|i$jD|yXklV;dd)0?s z>lp5+^C&si8%VWsHiD8$GR*vr%2{|3rwqydYyxXfj!85X3?%+h| zg42w!%gQ0_>}Pr8Qr&ZYrJ}cEo0HFYlWGl#)tSR?MDHCkG;>^JbIR{{#1XiSe6 zAV1~Fa(*_>&dzGBKfoKz=1w;_wBz|xtsS9>+TAghR^Gf){=~c?jGE;~F0hO!zqf3Z zetzWeynoUkzYarfv^Ac0-UXx3|B1XNuRIZ~!Z-{;QMZZE$-Dz6|EywYCKshPVCp3- zp&CK)tuYe+BcOgG2cyM@{fT>7yP9m91UN5>j=-Z}p{V8_S&r?{TqhL?*>2H2-*ew@ zsUNFqnX9O^&VU)uYlsLOqrqMQtjg=X`UYp_MrhII+tM{Ne~=vHoA0eoKU$k}zC5pN zPa~Um@0a%&1J(a|@!5|4j}Dd=;-ifIll@#5@PD#@az~nM#cvFgw-a*EdD~L`iN^kd zKj?iDNst%d7u9qGgwtPhM%d1k&4QN5IRUoGj;8IWLS#pfDggS{#;V%{-dSX|TOg6s z&y}k_iE_JV?G#%>VX|EoGTF+f)G<{$mVLzJAO*SV0d>WoZq|jGMJ0O~pr{6@W0-xe z>YPJJFg5l-XHt4Ubq)?_-N!puUft}+jD9%r!=>+5?RsF+a~J*Wz;WIg-+%VO zod>SFtMRq>PFT@cHu++qu0OJ84Ob4{6B7fW%Gx(EqkX?MV8VJjl)Frr9RavD4-o1nNphI~N3+y1w zptXDcs{P@4vbOm+f=8xYH}SlO%IJ4u^h{02()YDVH}5-ol*zi}tw>(yK12T)Ezi!Y z-VuM1OlOX$yo>cod{~Wr*{){Qa<-X{_=NMFx)rY{L>E!d@l!3YAD+gbQayp3TJJ*( z^A%!klHw2~DuadE$BMjGWP~x3zBiNw&sJ zf(;S>g59T84b9e&B-)-ebFQhDP@O~|oxe=FZCvwYi;Y9-n!(SVB?H_I)O7j|b<%F9L<|4dkPHrU9 z*x6Z+2S2OB11R}lszj0^{-#oh|0q1+X`Qr=NA&8R>*>|}kk2%_^lH4{t3lQ)?`*$~ z=%d4qP4{WX$?E&dI(aSKpCK7#JCC%E9N>4v)=#pL+``$d0|#4Av`|@34&{Qg0@RaF zJL_NQ*bO$D$`bIAES+?gv$DkJpHuKcr@Qhi9@CXob#$e@FI|a`{*E3g{v?|q6#`vm z>tv2*z?uC+ackQZx3=9YJxxS$U6$)P(;B`#)G8F-rU1r!7pHK#vZ$-<5>l?GOFG(hDCGyG9&cc+@r;M^cDB$ zTKDLGc;w`(A@2DF?s-B*vw76&jX7v1>r=;&&vef{pW>`;$;bMy)GbG`xd!*>;$QsS z{o_EYO$Cfk*_F%_R$F)oy+=ql%eJYfShVy_D%MJI98UpQqnkV|L zOjP%(;^n-)?xy$H@Y6&0BmRa*e}@>RmA9`TNAuI0D%#(`4zy@$aqp`B_*-AAXipwQ z+U7Hfp&EKxW$D`RyvHa$zGdhERf$V_RmJ{T(f-bW@}@V=91oQpQd#RlCkv!Z?5e&tPXsYKz?m8BcP^AwOXuH}lsy(!Tr1Nw&WoyS8M9VhX=GPb;8 zM4O_WnmgzToGmn_@HTRHQd|eROwe{7#i9Zy7tdPqM@sb)uDQe|Nv8zYF#$DmKbKN<;fn@cn^$ z!60fMjK5Ca!Nh~V-OP_SQ-7}4pKJM}OrlrV?`Fj!UBab)C)uO*UWNZ#?uvM&_PfR# z<(_Nr<5B6$A$HmB9n5cQ24nUw9e>V)W_(Iz<(zUdLr>4c~c4q@gg)_*t0<3@H zkya$PV#Drp6NOW%V$W8M_*+$MTSfcdAk$|NYLNT{Oy zU%jhFY&$nG^ugBTNmYqzvhR0+zNzAqcPI_*TtK!|TaZLdLa%33nN zl9p-n9V@a6bgYQ|D>~xEs@R_^M(hq)luF+9b9$oOvBdcKHXpxxN|L&emlG2MhgOvS z@rGjsFJfv1$*Re+@>iCcSC2;+yxtyju`S+p zNTagXHUiWM+02GJAF?}#(O^TQw%;w}xl+v3C~h}e5&NTQSCz3hq9btKzLE+pd#*Au z^ve~c|DIK8_4zduE=9WZ4)6Qg*9a8Sqxwmd5(C&TiiFSlMdaHILJZB~qn*_dUoE2g zTw+=HHX7UI-NdEWz#n+zH;*$OdCG}!xx*Ljx$vjWHyN3XOLNrcAks(TNWMu{X2>y> zPZ4b;9ryIaDINWdVJLn2gY+KkLV6c>Ar4b1JEFawgHw_X_dHUMRgPf4_;VbG+ov*d zNhnQn^tR%YtHhmM(l63f`KE+iLzx>qDF5g-8ld%V=sHZK;A`cgA_3{N)?+NA+oP&*crPPKD+6_nq!t8X~bA9`^9bFE*^ zn!n+B7XgGtYQTvsGgGr8Rf)@cS^oac`UCB&rXmWAZJ9c7VDd>Kg!f11vHbKo4WVe~ zbIBiR?i7uUKOl}au5?`k(<6d-u&dY1Fn@c8o4*bh?AXLxGA((JEZEUWl8{8s(s5FP zR*S;@SbDu~4qh+Vm{~x zhIx}h_m|53r8fqI)e*FD#@|6)RTkz|w7))}s(-sZ9>nAQs`{_7H;3qHOJ(7ps@R%} z_Ks`>fcETZW6_AnuDPps{S7AHaM=f&sIWfw5$YjQpm%uQZ@C)Va#n9FXgJ84cJ>O- zTc}5>JC7H=8W)cRPl_Kox^WI=>I*6oV>-QW{=i4t+_Bw}1}G-M+_f{S4a&f=Eq#0- z^&(IId*5K1+;o2bj47be&7w^uA*~g zRq57Subw#*(iw1+5l7O|7uPxUf936M`x){lIGv2)Vi>N#W&*ydjbtlhTfMu!ui0yX zgUbHKB!uazRAThKXQg@^N%j>is2Tb2Y^E8XYE^DMCe@TftRap*_pg7)TJaXGFdD5d znR#LGUWCd)3M)ILCs)90I=%ih!YH#KU1f?g+q`$!kZrGf_3+x-kxe^LF_ws~yxk+T z60nxEd)v8e?WXGW#PLOk5pPVto*7Fwwy*Uq((w^%)SkizPcrsD+(A%;F^Su^IUkGf zmu0P9LrWz$pRI_HN4e3$z1e<))N`(oIB*-!B@!&QUk5}iW}N=pGH%pc$&oTzVJ!#( z-jQdjVk@d*&uejBFR(1m0?$fc8A~GFRE&73qUqn+;rXQyRz>U&RU=+<^y8i$!PCmb zP1#kYJHvPU8oZ`dq)H-_@5FEcD6P&oniru5mGLW6qqU~HCNP94;T>#6y=zG6^cnB*0GbvUfBJBB!JvNp=^Yu@zhhkg_Hq4R9oPT$as79e_kXp#{{{$=-4aR@k(HbJy{~ZZrGZ}^0`NFBPK;dui%6W$!PI^ZdxoQt z7a9&>s^ff3CP6v|NFqa|grQ^FEQL@0l~z*QuMq8DPb?mnuP)z7=!3`YXd>orBo zpQ^A%5n9k3WIUFAt->@zL?^+{h>F#^jeD&h9c{9NiW?za?MzYB9#zJ6RmI*(5mMjq z{59}TM@Wzm_u^fUP+udVGodF(Uq(Miax40&6a7?Y&`I5A)5&;-B}FG1`9A!~^+%r3 zcKjzb;Kxb&onGGlw=dgpjxTS2bKtoC$@2ECUmDkcv((1^%Qc#kgQwTCeRM2M)@a;9 z+q;Zw__;B$fd``q^yzp%7_w@0kWSS0Fl5nQn~bgQfi{>&owxWCC*aolBUPFT+3-iK zBF4F2FIB|WNdwr+V0BzYL-rUb?SJywOltJIvHOtDGwnYe2a$M>{-6i{>87mAI=lK$1N(LAd^bDa@C3ZRPN04I zFMA5K2d&I!0^>g)709$+>%t&+iT915Hg~?EJK}9`=NpFSg_xkee4C3Y>T8E13y{1k zUO~2^wVXeS-|n)ZS%?K}$H6;s$k8&WXO;Rk#k?^0-bNh67R;kSx14_+C97M`ustE& zkqPO~6l*G5R1!dXiF>c53#8=^(w5+H-}^V2L0{}PS4`3+*ERahb?x_5Cmh(`wy z*?;-FJz-`(k^JYMUo@H~`|{sHYj$wbP_#%=cmXc=0$t$!QEoIQ+IQ4T^Jz#fe84`E zXO(qY0swn)DWqM;6LiR8LVLv$w{1GGqBFT>(VduLu%_d&?)!50;2H?Ac=j`~1z12;L@;H>w#s-L_xD!@d97 z#VphTfBycfH)(@U!&p|FxEgr(D_67swuwh$I!hfg8Es3<9p zw{S=i0#mUD5_68?TG0FpkewzRGA{OODfkc57Nvo+4ioNcxct)00{$LYf1Hz_^|Jm;$us!PV`oLvu0ah0 zytjwqQnhOJasDiQaYzGd$HeSpwl`t~Zwcz*V43^cTrsAf74L>%TOVn0H_UdNEy{EM z41YKH_=~F9wQk~b1znjdS>%Ib+zt;X1s%~#eqc*%C-NIzH)f~uGWf~1TC8z9LDGHU z$O@Xu$dWJ@Z^(1yc7n6qy|U1$J_bM*S#4poL&jCX2(MY&3cC`78Ex%+aRWTUos65HZY{dld?RQt#+8NEy;Ou5b<#eIM)-}WDhxljJ{>p_p69c z$|k=iL_D45GM%MHbfpiV+;e z{kH9bI)j8bz=jD&|?c24Uy-uAvrDaIE(pPCv5Un8?OguSP~zmAU{i*?K_t88D=)Gxynx4 zn(fM{0^zSRs=zO;){m3VlBh>~w<~^v)@ANU*BnGX)XT5ZnmwERDjPbow?^`-v=~kW z=j2z}buueq@W`+7xYTJpzsfc6u2XkwW?%ig3tR_tDblLY6yUIs5A zfoZ409|gLHf=2%DBjisQpOT9QQYl;eik*BsnQ*mN*t>D9Y54zKm{X7c@6liENlnn- z4$tqQzkO#o^p}V!{1*CK(BDOWL!`Gx=wG?OUXjDc}!iWmObWvjfJa( z9IESf8vEx^S5FyNLp-6p0-sEOBZc6+qA?E=lDN~%1D^6Ps5$VSZQ7U4g|-g%x}z(X z$q7Mx*w5Tr%V5)MSw`vxRsXowoVVJL0#hJ8zh-{A+xJt8beW88dghR@y4=_s${m`a zbl5RzK!DOqDbP#nWdj*>tBn0bWV$MWc+um<5L&At#LI`t5p>r=4qgwoZWjY(<7D{C zSBy2VnI&gK{v;$eG+-GuN5E3rMZi*q z5Bt7b1T0rK1PkID#qCJWwBp`H<~IB4PXsRKjy7<)^f&{T?@uILB*Zx>e5{hM%i1gc z)hi(l8~~+-8bC|=XaXp5e{T7wT+C<}dOff(e%%R4*+6;GKgFO*%oYC@=>G%?px#=FBU6zT*Lf0_ zPEgh9_BUUkFf83PJr-}g9!gfC9!XY;1I4E!P_*Lm-CsucbRb~$+Vc%o?^vHb3S;vQ zcsXGzY*w$9^Hq`K_>=_$c9@dv%foI9gq%jjP5+^b_S{m6DHPvj~{?trCLj8e^{Wx093MN?DIj zu7A$K9z^Nay_w&kw61I6V9!gRwV8P;{csg|vvopOL{D(qv3Osl~*Llhxl%|BXdWz3T3b_XJI7ZX?_(y7v$7}(HC$bP*<29frT?N z5J2Yv4guhNIPNBm6pJ(u#>t0$!c}(JR!o9xMbGUF-2*o~IEp@5eGe13YZ_@M3qO4K z0oW;RFF8c`7RuzsJ`|eQ@CAy|Gl&C2vYf#KrU4UuTUMI5?W~0OKhePkKO*i|I-aWq zIDZZGJE`|fcq_m0BP$ssdT zk998%jInQih_l7JP!+ctgE`$2LtACju~~L{#{$u z?9OY&Dqh>WgH^j=>p;xO)PqP!gifA3mOp0 z{upwj!}Yox7{9H72=m{Y>RKI66PDhA78Ogs#NXc*WIxZEwHdu=J5}=sVK_OHXX6 z%&Zy0(#BN-u9llh0TH*kYacT}m>T#ErE9)Eoif3STf|EczWysZu;TXf`23vr@r)fU zCM1T`S$6@4Dncq>gp?4=p1G*?+#;+Tj-n*r{`{z19rC$3+7(}OFKAx#?^1z|iLWuC zG74JcU&Pt`4*i&VqG6U(W(c#edFn^wXs7oaCYnVVDhq{g21z;-{rx{dfPn9pj}U--PHvyi z{Vj24&Q>J;@&$H4B2L7#aX)zHo(NMwbdVi8h~}C(gQ$mKpM1T$KNa;kmq#M0tf|c2 zMUSL>C7(RE8~SH77F1dZekPKkqM!lMVUL}p|J{oI@fIrWs~)8P>1>lkBGdxez?~dn zoG6u+b(TZ?=l4{^FANWHtQItJN#`r#=WF}T`wa2N;x*PMcYyjYl{$c1$Q2tRh8I%B}Vc}Y6vNcONNyLtXPUND9nhfVB^!g~iY0I!$ zU-Sw%G-VlvIyd1#bL}tIMCgBoAYr+(o}i^F<-6K%)bwx6IXR1E(5A?@#(r#vTYu#> zr@#E@^{D!*9}4{z{q;`Jm2JN;cO=Iy9iOzf+H^|*}9*{@$6HEP22`Wzu$H9*Zgh{e}O*h@fUiE;;;RuJN)%SlHxDnEAW?yQ7dl! zXvJTAZC|s*@Ymn)8us6O@Ylg#DYokwjM4lh;|?l`X+L&Cw0^<;nvX(5+<7{5J|5E<2w7r6g0E7 zMc-_du$DJ=nZ+D;w9cdR-s=;Mh2>mq0b+Rd*$RkQ$W4>8gWQV+kUecHz4$t{7)0_4 zjuM1SbkY%vo5j!|H#5eTWX2TuknypVFZ08haTsS9r{xi2wL|h*!*%v@ZRZ&KtVele z8T3aPf)9oCu=avuSamUcTdNiYGYhW_=c1vw1`Q$V6^6m!S#0S0l}Br6>ZRAt8oo8B zMXM_dF7sRG;>g#=S>t@Ahf;1kj#*&43jp)vKZqZSS3xg4P=<|AvK=O~NDFj`_30dR z2^9#3wrj}QTXPcY`i8LwfFE$|V51)~2ZOE>o+NH5Nt#`KoUrfc^t6#8oAhI=_4}d- z{U`=oF4~*Oq)gx@USsrAp$Vvegn;O%G5btVW)1;uKo2|tjk`b9dQZp)jsP))=?iFC zbR7P-C`3=O;USPue5dYB^Lt*64a0X{*Q&6s-}72*xTmb&OY7na@ZY7Zz~8Wka#)rhr=o&9Dyq083*1_ zBBLVB9e`|3AQgo1#;I z#?}h|V-^163y*!dwDcr429p({$RTz z3|`;@!l=$^j4)2abS61|-3d{&@NP zsq`yGdmKq9Z1=M#(etxs(vAw;Ct7->gQt8TD*uF+l=dPmP^((EQiV_a)@A)K$#CqS z@`h&ty>EQ8_>jE85xuYR2EQR&`9JaGx#I)&7@Pn(Fd7iFJu$pqt<~`M7M;d#vFh9IS*a+IQrPb&&!k;|L$3=CCdZ&^Q3AjC z<;(7wZC)5RQ`%%Da(D3wjba!Wi7P6-GSdKNM<}U3H5h#gQe4uPnU6 z_*ZIM%{?EYtL3kJJCslVDLFi_us@%URFoV}FYLm{x`p`at$P#C)Pv!Z%|l=F(A_-X zaz<5#2N75p8e5CRvxV?~vpoFMzd-dbKF}o96WkPsv-5@O_v7m&n?*TLGRngWJRn_q z5dkJ1kSygt+JJ6R% z>`ZPk6wHO0`7Cz5O;_5FQH>@fU>4!+>;Wm=6GPXD&tk1&6e})+F}S<8C>fyr6n#c$ z8K9M~qaRMjMbh>$=&ezcQc`=7z|(n7Wf1I(WPQzSeQ6-agv1Yt4HfvG2ZerYxVxav z2bC!K@FeyWw0(I<0JA(bkz5KnktCmGT2AOoKk@#6E@$IY*iJD(d0oM=o|nFEGqXJp z_#p2N66u788t+7n-LD7CZ=gh~1D~u;!*HazP*lc!o-fPKB^X4uNV)8-F@2S7&ID?*MPT*B z@k;m)e3^S^^`o&k7B@a~_rV$*H~^+?g`fi|3E9KbyU-UXA&w&WLH*#aN;L0}MRR7E zUSoR@S4@#H5+VcM5jspMH(;nEFUroD2yRf-!Xp~dpZOR(Qti{S%6~BhjWctlD(|we zzWo7%yNbvBw1pMMQEIjiuLzc(ro6GYlw#UxcbOsrhI9#g3&rFI2dhnzPz9D0p0dYK z%~`)B6}Ev(+K=EVUg=Cca?SD{uCOvx2YYW5M9z<~J=GNq^ik~@5dbc$?DqRfW(LiS zVxiyb1Dr>3&Y;MId!d~d(T+c`d(aLXkh9w(aY&TYixaWWoP4A%bU#MPdsY0n z#lzPh$MA7XAK4>tVyzEOy3k+fZHWlWI@biw=GnFttcTAv@@Xd2(wPv?Yq5-+amJY% zUDAq6!2ym3`74W}h^ZHs-tV z1F=X}SsgFB;ToG7cgwf*kiAQ(spC|Y`Xr-!?XTX0|F0CO;wmd;T$eAaBS}+2vgrZ|u&B=j> z{9~D8wB48c|x zw!&5t`4R~j=inpUo!4c9iTASs$Wk^4L4#{TyqTLlix-JTTPupfi|D1&hp+}9^fO?3 z;P978|GHLoWc}0ks{vh+nulw*PlS$HomzqxasBp*IFk$SBJL#d2R^`M3D840s*4Ls zus^y9y~zFFJZ*boG3@?Axo_SF^$w}&M^1;low(}=Y7>1jB7h!l_AbnXcvqP}uswt4 zPKzap2oH_t={x8%xRhw8d|RPUF(B#aCQok;E(Sk($|z*U1j|n38yeB!j^>8G4ZREhTI4E;74|%K;F=nJ@>ODGG@On&zue7#n z;f1u{aiI<(Ub8(feUAIxW~T6=^{jTe!M;dnAcPB>&{LKVZ?Gb0Gk&}3D-IqF$WS&y zpCkW4FUS#TFw{u|(~ou_q{TFZ(-aCP5rlJjsDqu8fyr=L94^=pR-V0Qs}fj=#7~kE zotQW&BZ@X63>xDD_N zqN~rtYkC~a1~)wqor`+-tqY+uku(JEAK15i3B|bsnH=%hb#^lTcPnh?Ej=eD8=(gk z;S=xz5elnNK(yy^N_+Z)-RNFD3|O+<2*x4emSpq^Cjkb)<n;5 z!A~#;`$cqWIuzLnJ9x|rA{VdhjQz-*yw6j94_wuV;|#c~Yo20rjWqM|c2_gceTHVx zL7DDoEIJxIlz@ZW&ycY!NzLM?)#U`;hgXKA_?CU}5V_Y{;uNpOcj5~E*3H>+yJOD6 ziK$2^TfKoQgzK+~;58_Z5<;Z3rW^AjE>W-y&cyiyFk9hkBaCsxvbO-EE?$Mb^|HzwJwKI67R%UtXuj}GK)OyZ_p z`4JQ*e`67*IzjvU&<)#%)P=%E0my?r@SJ>Bi`J%Ac*=%RYy{iyfk569Z-4u#w9A`G za6lmu*M=p9l3Buvdk))*6-vB$UfJ&5wh6E6{5X~A!;}FwHjb?fSfzsw`mHW~e@-HO zY}m*7VcCpd2UUhtDBfBfH(*YnI=lfG-i*+?PiTfXiytrI2&}lv{*{c?idsM0<-0f$ z*E;18nzw(*B`qrY-*7g7jsBO7uSVhY*r*P_HeBaLB{Ea|2wisG`Sv$HI+JKSr zK#`}6_r*~NDoUgWnuWIVXeLJlCcE@W|blCMikV<al znLH|==L~E&rSPTTg4^v@!i1V+3}cbNgS}`lO&Q<_!})(?pg;1J=$whTc9x5TLClXrce$Q&sJ6couy|_Sp}f>i9)V1i@wn z+6niH*xyfuX=8g^;N(bz;u|i-D1F5bpuD8^FRu`X4Hu;ieWU}C3MFb6P2#Ul)@#!w zlRqA(=y*^FVNX`vq>UKZJr|${b;{(MmvPEuyPsE$bN?c9Kx!dU&84P>-Ph_meW>;C zUQAW@kwT*_gQ6wf8(g?TV1Q^wJc|fnWFt-#9D%BBJNq2QS073$IE&y#@qiS^L^D_+ zA?pj=4HoQ@Egx%Wk(;IL&bmEV6iw3Ae0c;8>ewByU7^<3xPQKLSIW<19QX$L{HrJZ zR*0Q?^53LB(RE4T4i)xf*@?y?m~_Ed4|9@y=J&v)`hv-*)v|pZfD^$4;1j9^K{(K8 z_@LnP7zj+mXIdoe&BQMow@a3CyL9tg7bz3+6p25l{df|&gN_&2k8r%ee$0&6k9Dvg znGrAAe(Xs5@eQ~A_?AErCI~LAo%qQqF@?OsoQ_0)@Z!WUvIV#Zl7=cEmLw4=hF?M1L2+WKaVZ}Z}w{`=q-C|tJJ>8 zp>h3wy1PG@tuB86DB1&GWNzR?>bIwWGTd!~OHDeOZR`bm;bd)5cBpP^PRqK!E5Y-lD{{P2TtnOb(@mWwuy-Prn)(4$T{esing##%>L~ua5V7a7%Oc_7hB;?X01u42 z{OInX>t1r>pY#Xi5*;-iYU8E|t}pT-Rn+=oQ^ZA*M2te7Wyt5tV%VznMIzonMV<BKfc6J_lRj#Z{}k(s%_CsHm;Ik!U!-FI{@`RR9I*Jr$GlouIN*}>P%?^e-IYa` z(F`s^a26eLOJuryE=LeYvK^}mx}@i|pf<`;zHu)+?xb5~$<2%hxq+^xIqT^xdl#3s zu&D7mPgZ&`^Z)dbT8SJI$}Q9Ty=(P8j@ijIUZb_j0=Bv=NT4;Yoa$c76w_`f*d3gp zUdT*&S*<{9^kCnxTPn-xqTcwSR-F@8{o_)sK}hDymo6@mQiJ&c!U(LeeYLziO%&?@S!M zI>E;>B5bXMR|KV^yIxK$;Sj8Z>Fo&}Eqp9fRUcEar0gQuIU^Bb_XLVS%DV-fPS z+!D26r!7Kq$R(T2;^mVX!{?!M!RPa~$j{8rMNXz|Q-|p(+veXg(YRuU<6&&d(5vQ4 zw_zhMKqdQC>34Enh7Esn44dMMY1oLZOx0$^ZMzg!&8EkJXU<&h`3ICSvz=XoII7eT?mS-65ntQGuSNS}%oO9b{rsO{$9yl@VIy&Z z5{FAGU@Xm-@a++vvP=KNb(2WBy`rQr?i(`DP+N{WVz7+p=LkeEhMB0kyb||IEBj^$ z`mI2IkbgNa$AZ!5L-Kx-c#rFwEII#ZTu?SNS@t%&fpK*E<^J`M-S7Jy`{ksyzu$f# z>1h3&M*9Ugg+bvBdcpGbjhE6x@rA+=_+42ZSu|-9+I9uC;c{zzHmlms&Q|g-1&1-O z+(%O;VJbfCz_~mP%FCO2{aL;Ki+td0tbLvQRxpl;MEe+t-9uPd9T0s6tZVxo6#;Wu zCvDMGe@n`9QsdmQi;#~pXqb@KitGP{7&P*w*B5`66MwH_Yih4P7@aFPdrYHn_);xL;|*zXY@-!K`4?bXA%Y80|H z$y-EiOraW?5RZ)}KxQlf){7&U`&YU zIyJK0gwt6+a@l-}+vMUk8!SoZt8nh2aEC3Rq!7gj#lg2KiF^F8dmuy z@e}NyUMS?Yj=jONxHowOXE<3_ZL(9B!vmt!f|xU~Zj?7G^Nxry)PB%G z)&CKhil~9Pq(2Dx3S|SqvnndYP8y*EK?X$&gsk?apszKoOh<@(if8prBscL|Dh>qe z3wz%i$|gCH!vjI05p`;XU(lGgZlW8R?`p)p_-*A^HQmgF?J;bNNR_#?+zRMhD`3L~ zU{pMzRefg5DqsP%QKqc{DlyS|FnjYP(1bh41Dq+_-@K!^E#Jj$FcRgWE*LGGs%E%> zn4j>R9$DQeIEi3E9NeUwM9L%}MHnYhC7vTD!COBXlVHyfF$vVq!n@A-d|C!A06S$F z9AaZu+@BMbWx#0KmsOa)+cH?nQh@9VReCLAog9}3e>0W=@iTdxG7bQ=DUcRc+>;lB z#U7PInT~NV_-k^Q7zbnZ>I0;rjDvJz9H0d;4yN16I8egVIi)i*Ss4d>ZJ%(3F%Bl< zwSDh}Fb;Og)-~`W9u63e%Dn-6MvMa`Iqj+RUK``!5F`o4Jw6=`eaF+R5#u1Ow__YY zdK=@wi~E%A@nf>{0$whs zAoAze?FQUvGc;xNNopi2^bBsTWZI*ia*w_qe(8Q!@q9>-0AA1hE&0Pd^SR=Q*k@F> z$gbBRVyPirUN=ORsevkGOd}2yp5o1X)3f*$P$%wSi7!2T+ik~qts7&*ZS58@hw2E2 zkFlJE@1sECF-rVk^`0n=_3Pi>{SSf|%PVhr8ffT=`}**@sHmvF`~txI=H%GuG&TD0ci0#~3)y`!)uT zR7EfXMD1}oMbj-sK3`5v!zagwBV68muH!JRV!Gwpr?OZD$Adj95tUFA@ve=k&SHUH z2dQoLM|6lDlvD}paqn99g!l*c zkRhw5#?_#! zxS|{B|Ey_KbQ1ozc6Bx!-{W+t$mz3%=1QS-phkn<1WriP8aJ_nH4zEy5;Vj}V}R22-!#pO}>o$;^xiEWrq zTx5NF6Il7{OP~P2FB$O9`9LtfU`}FU=p5?VXekQ)nfzD-atl3<$P2CFXg}-x3fCAS ztDj#%?Ujo26|xnMSjbkoV^#cFWx+8~`3<*|m8`gP-@}R&@wSrR@IrV>>_PA2rchW* z%q@Zj)ap$h$n5g4Lh5#DeJ`D>CHSK9A8iy`MUE`B5${PnSN0EC4bQTFxPoQD|BA0c zz@9{9+31uw>S&V6ibEYC;3IWqkq|**@Ns~7*Ps~^u$nSGQk)LrPtm%I@8lFT4hlMk zEE>u;J}+j;ndZTsrWzlXa{QtOsE_(0IVC71J09^vSSCPI(kE%fdG2wUU=L5CmhY9^ zjiw}>gAip3wu8T3(iJvtC2IV07Z&`7-l}2x#-;(9unrZN7!`@L{y&5w-1}BSGHo$C?h>)sX#2mU2gJfESJazuu$3XyE{sHDnBs0{H=%OD$fUCWdh@Z>c z<5}!Q74VN|{$KDw;Rr9?y7t|0e?ZBs%SKq^9#ZE^vP%wkFKU%tx^chWB*>(xah|fk zt-+UU!cIZ;H5?vVV2Hpfb_rClO9lsW2;yrz4;5Qtt6`IlfJ77!#c>|zIfMKDye4Y9 zK6mQtQ#HzJ)tVt4{de0hwBqRwL@0)+?n)2cRs^bKecs8=CUE#u1n!J*AG8K)MU!TT zFKxsS2XlylO?dBJnA53_1_SG}vhq^Quzza9PBzg(n#O3Q{M^{>^(TZ)T}0TKX-WLy zvy>{Oyxs{t`)&VcFhKmNNEvh65AwSxMA-|r)3-FS!9nXMP3$;(5z_2NP|X1*MH~=f zy+!YDDE;@OS=yI=JA?Qy0how?K?d-?0^dmo1Rrl%*#WkK5kQa%F|3i*D3k&))fqH! zcxXXa2mgO6Xp1)|ddlf#^6|d3Q_&rb%@Mfj!f&N^%H@SC8+rOFx6j*StoEn+Ge4b$ zH7C|Uj1-%OttZ|9Vhui}61aF`x*`|E$l*6%;3MJ!(t&UfT)`)zG`8BWB9&i~Wfe=5 zZpIxc=rypX@|#wkb-Mz;lz!#$TXB_fNioAQ@D})Y283;dBG6=b5C(dlI#)u}zIF^@ zVGVxdwa%hnk}(>#dY&90VbbLh+j3eSo>G{e&J$Cp*iyn1aqaRrIO7#8NdbgyHltl( zlZiT2;035YgAWo^;m0jy6@Kzsg?yWYD-u8U%;!N9fO*QqVACF{l}qDBUtcB18FmcihU0AW;VLb&$s@zCE{+ zZ>#y3A&*kvJ3LlIBs;rHa;!it0s=fQhmpmzzr;pGz%kBIf7&Pdd}hBkj(=}IfTe>a z@szVr8T*t7YMHTCFFVZ1O>>e{+xsYY0QKN;IuD2KR3H+*M{E#Bo5FtTLeZjCjg`CJfcUo;)OPI)RO-b&|H9$dZf4B5+aySrOVjpnJ~3Yg2QK{|d(@JY{d8 z-|UkA3@zx0|9?U-c*%bt4xh(c+~4|<$NC-}c@|uTP)Q0fZ*Kq3bFI$FKHiA=>p4Q~ zzCQ2aqQgG9Aj`4lJ}H`Om8eOcEtb<)h*p>5G}hp_4U|sUKep#wL26JXc@n1tHRMdz z4xYyWg`lc(_;X(vid30qKC2Z7OTyo8+Qt^lQm{VM8wZ;N=|T_z5(GRuWnT!9*Onh- z@rb~;*_Ge%HmmPO1ir@ovXBQ|&WK5hfhffxMEvjExdQ1FW=$nT5iCoE!9!*{j12Dm z61eexZ2LR-sfT=uLR3P}@DyS&Bk_N3YL1$J{W%Rca(m>$Yg--}3F%#zYh4}-3^KBu z#4sZ8pKwdT=oh3g!WXE7xPBjBbFDco{Fz5Qi?_>{2@uctU8M3Ypbt!QV!K#~V~A^p zlQ{Hq#4~?9eh2B`K3Ym`C9-dqGKk*+eSCqwJq!8>m0giKP3U8&n?9!b`+SBwGjX@n ztkI2;2c$XRhFyJ49$&2o;4ZzaY0CJ7*g`Es847DWMKL2n8REZ~{QB>q4ugoMsltH+ zsNsYYk8~3{=u0w~ObQqoO#!_)k)@X&g#t!KD4;3aivl49hz2pp$KpY8jGPcLyg?>~ z9EWIan-d7br&4;Tjc1WWHkKZ0r-Jk-fJN4i#kyebaip~pV3Eu`gUg;ud=dNZbv`V} z;w}i{N&9ajDVN}#*Xr4g+(Oxgpnre=O7F%)=lJ?;Br(R5#A0`HS~Gl^`&=g@amp1q zBI4Gw5zTHm#RBDZU>$&UO}+w_^ns-rSW=Zmv`~a}&@P2?CEJLF&5A&x8hgfOR+S9| z*vHO5^=$msrLmzWuo)~xABgA9VazD^s%^ z|MLw zZH^LuLK?K!ffgF}o^d{^~=3$Q%C+sXV zk$!JcEdK(wRSieJ$@#%kQ4A&GJZ0Pj`LTydxe%VA1hu>i#nqW1)p zFi|!&qcxNOGR}~v*Fc4&O#)>DMigUP;SGWC!3j3B=(k$+_9J1{Nn(|PhT1Itcf`VkKP;4ho(Suh*G!_$C*zu^Db(j9EcsP0;D!q(sc?C$Zr zCcB%Oy)CEvk+V}m$DuD-|D*k~zGy#m6`E*z9=o4G!(*I=vG>8L=t;mgj+9~D>jvPc zO}%lUWsYkJt9zX40){u}Qr9g=b%#*KSe-ro%w4n6#jX;VVu8)%5q`F_?V<>+h;bmJ zQE9M@3wpV%@?^~dPak$GBIL4Nf_#lgH+xCi@Jb{oykI2bpQ^c};0i!}PT@qqH4;eP zq>+rZyNdt7sMbA=Q4PYV6!s)-8h&?>JYu0giMtHh>j{p~!`SoI`W-Fb;wk?YZ+Q&3 zHBKNM4^t0^4AIlBS!X#@H{|4JPus9JugJ;thq>2-W{(KljiITCJRE=~ov5TxxNQi{ zBdgKcO=!(<9z#7*0=Pv9%s|fagx^zg(!TMM{6W1DtQl;#)5LF4E_Cw1}gv zC-FQ+oChPe9t8u1ITa20n>vPbIV7JZY)GBJRayyiPG=e^oT3^0Z%mY`|vzS2R* zRx7MTmZy3J7B#YdTLwdjCNrGjAZP9J1=F%}6k@Rxc`IV_SQ5Y(izbY?zni49hUEhX z{MNZ2>ah5ihcrbrvK7^MQ~W($1G00uB4p(o{=A1$)Nd#9KNP}2Ru3SpTK5Ri@Cb( zY)uN9RUCy0^aJ4{%RL7!;Kz-#?k9b17r4lnt-;qnfw6|hvqk-j2BnfHp(_wnLSYDBgVOB_MO3f*gBpRjmTN1a+GzAKsD_8-;mWtq0M@c&9%&(8m`v{y$=}4pV zg;f~#X)fDU7S-8-hqWp8ke`}bj)UO`dQQ;SQUaO?YkB#L?w}GQ@99CB=LaXv~0 z+D>B0tb}3f84%Xa-0KO!Gbe59x$$_%+wUYyl$(lM6T8IN^M>%M%^?_mXf_aBZ(*Xp z3jD@87hyV*;niE5Z7RF`pxB!l}Twcj2zj0}$ z!;)l=BhU1;l1gbsADQ2JuRAB>(UWTls(E zNmvOc&XcfKY!|)qU~){hI)-L-`RL!>;I??vPI^Jbyo~h*F2)JLg|BcrIBDIH>-)*l zKaNTfBXIYN88``8yck&Q^}wsd;v`^kywt*kC#Bo{)R@%`d7~UG=0mOHW{*-Q7#t8! zj5q-7#4?RL0tYRbz1PrL*nVq_c=1m7XOyAclG>D_UImFIwQUO8mDDB_98*zJ+qSUX zdTfel+9|2Mq%d*ACHQXtjjK)}DEmz3ccCJV%f7wTJ(}>njSoQ4S4Y^ShQ2t4;|e-* z4DF|)|Ad0Ls6hY9fuV+A}^ z@|2f?rdj914NjdqojSuBsgquK8p}T+<&ot90wN3eb?Rh4U%wyVpF=IDA;zlLo30Y= zRH@bpjC`6@OO)dalF&tV7wl4Ok(tq6UvzCr?bO24*~UrI2C%E;)4mmEo`V|i|9VgP zQhPn~Ds0P(aY6}!NUyYP6aLS+ENclO18Ek*CDG&dTl;`}0|D9k-lzbV3 zcF3`H`!Os~WO5aotqPeTW);qr47*EUa`^iJO%|+nwE0&A;aUOEB)y`S+H>ffB%H zjpO^Vxxi_}di`cpwC z3g!+J%WWwCD4P414qFmwX_V7ag=)!Y4^dyrcEDr{-Z;eiI6>nn?+o%NsXe>!42K9y zhYe?oQ!A7(KZr|L74m<5S|J|_gG7loONVufbpEzeFj;jDtlxBeJ*=S77F05buWjA0w5&hczo{hr!egAN9ex3B+6waSrXK;RnR8ct3RAX)o=hjUS zlSg7b<%I&F0l4{`Y>F{J1g1zEqU`n{+o^)jTdNg(;9%15DXG1saB_t=P|Pse*uoP_ zhkd=4T=ET!Q;+bQ(2ZXZcKzlM8JQu98Wb8_>pfLga7&WxZrex(!WUH?~qwl?iOy;+B)?g z2L4|>PY@{hzbJLELg9VHQPvjaW9g9=p7L25{DYAH!PM0Hce1Jt`|{GK6zJjn)u0jm ze@Wpb5$MCvn=TDF_CvB$|6*0&z(1Si4E^KMSB2l9x|4XP6VSi3DDZ#VDVVGZlKxZb z!GBdM>HnH2`VTh-|99_p!GA3TWA+B7Z?^lbj)MPved@VGy(cfHxY!PCxHUhSUU2;4>4(3b!4E;Bo1G(${| zJ@%=nX;nVwOzU3hyQyha|J_W>k}7Iim#OhKGA+kO=J+QUM@e%(+>LHaS?Ny-NF%?g z<5N9l%)ln})y7ly4W1#9J!PNDLt9T-H6F^i9Isu&NeBR+yH^2FtHr~sG!*STm^D!* z(t^GKVc+R)5Vi<42Eu3l&wvo2GwHvOKoCxa{M}DRL2|YXLI}h!gJ=qpi=Q))JXfkH zNG7R)JCM{XS*=f$iPX6$3XHECrKsR{aTNUe7WStJx&K)QH22H*eU1RZ+mNdB!2*cd;ehv~=va#sGh-R8hcRCUqKLB*en?`KLGX}BWttL1WVmC>h#t`cul=5lAEH_R={(9(C_+#jZkx$m> zs*;*EvpZR%AEJD!iJKj7jeZTEMFR=EtIZI!{!CWGfc|`9WfWRic$gFx>Gd-%Mx_eW za2~1(L%rSKy&jx*^a7l(kOQv9yvX^YF*qMs;Ewdt9=9mzb>Yk?AU_@f^6!RkThq0M?}iFP_TwID0N;N;>9EJ$ zx}1jZM-Ll1#@(0EbUeK$;M?kQHywZRS!3|62)f|A{|pDd_9Id7&67b09iJkDXbQeF zo-*(~L8>VD9==m1*erYx&iJ3f_sJ(T3mN-Qbr1Tj`C9|{-XevCeoxosG<@f(!l2*1 zUF*TO4NqjRywnZfvQHa>Z~7fB_?DdRz<1%pQSd#q%AwzP7B?p+5}!2ieO;<3_}(vd znw1mwy*K>N;5*86t>IgX+f$Y4d*g}*@a-jq1-`p=ISt>QsxaVtvjlj%96(QW2Yhq# z-SAD_-xz$W7P{b@a+(9*w7*5ccj@B}e6N>5G)2E_RvGwSDOD7F&sGC(mVVE?zIphb z=aRoAwdqQo#YiUtoOO!~5SKp~1w`$A6AP#6F-I88cghz;m#0u(CFMGZ2NL$HE~??a zQk4hXTXe2R*MpJ(_qYD+hWqM|8-sh^0vFtup$MJq&p#9e^y6g^A~b4(%@OsG#|_XA zJgPYt9`@IzPV+>)@!BY$-xU$c5%Wd)&qrw8m#B1Kk(ihB*qyQeRCf>(sSiZpkF6N& zZ$aZ2@0#)Vofp+}c$ure`j6BPvx`jsCAFs%ik599a~0gbgbP>|163`L>Ra1SSJGS> zp-ATKl@1A%I@O+tu4X^+oj7kXddE<(@3|%lR#P1>pweHxUG%A8BqVo9q`yv1e}i28 zK}(Y421m+;18O>&-p){kL2q}#_>Ho+Hg@6tn3Jct32w+ojS<|}WiEpIcNQ7_M4(0d z`$HaxqPwRaA%ukP=E+E!V)o4|4c!$>6~*kiYV^%AyYK2KSiaOK-5EL%{G0epO@Fh8 zm(*Ta&{pGDqxPqV9n`MEPPL+lckYj(2>YF|L9H0~iHOgP;P^S5G~+INylgLp%Vh}C z|HugaolI)N?Onv$ZILbqJ6&EA)g|ITnWwlu1B{IB>V7lZhM&#T*MI)zO!|53BdbY& z`q#*$HGRDwDHqh`G=06N3WL5*^VFlSOFNOiYA<%v*S-%MqptjZ;e&AaiMIyTdP z7&0Uip_BztJ%l$jM4R)bA^xy{Q^F`~g@e3<*p*hu+p@F)@{%Iu-qGbW^17+QKwe=& zJ>;$IsPlUc$#df`xwMb z(nsTu9asE8_+F{#w?z6C9ek$h7W#kgJq_TS7b(|4m(%dQNEHTr{{f#@lydu`gNE;% z3*7LX{C;EbZGEc?zK?f}g74&equ~4Ia)*BZb~|C!6nsB_z`%E@R8jD~PU#}#$cM83YXIMjNV)H^^-DZx_@1Q-1HSh#Fxd^?Ep0V?Cy#T(cgW7h z;QRGWF8H>TeKrTaL+*-#?^8=1`7log(-i$~{;Pp+u~bp?o2w?!EdBca@(1CoiZlzU#!b%_T(pYtMJXci+2>!FNHi3%;90 z{yOm8R}lr@(J~li|H)vQg74*sNKlbuNm50@_q(|=(PrTry5tYSSG&ts-0Q&YLe(wk zw|ztS7DvjRqRVOc7A-dN_kHZ=N5QvMyoT?xF>d(Id8aY>_A7G1_bX47ew%Y=6nw+? zIP|-5PIL01<$VUe>!pfAOC(yiam%=(y=bwi5Q;FAy_Vtu~hPR$|)m|$nb&CB6 z^}5x5GEX6F44vbR-Ra#~!*pyZMO_g#j)UWJYNZ5qycU9L!-E+KJB`o&EVw#Lhv5vhCt4iN z=sKi>oH>huG&3*tTCzTv zTR3Yt&8)c2_jilgAQ4Qimm`IiNR{76Zi6RkT3L+B|F`ZdB+*sqy%FabvXgMMx(p4W7%uKy z!0>gRcwyWA;CP(D=8Z1Z4Eu1Dfv2hOK;ADfg0l} zE0;>6vJjr0;SCN?^9Lu5^#;f1`2#(X$#P<9JgDWu%@~>P075MtaYPyLf88mJhug5z z?1|VKhcTKPIG1tlX}Hw305RZ%FwTq7G@o$Eb zUCHDeuTtbe{F7TL?b_RZWT)D z$8!Bdl;f6pAtbyCcNN!MI(w^S=0N~zEK_Kq*aaNe^-IjaF5|#(905tMb{FEX*Ieg> z6OP?Z!GWfE-yNu{z(oTc*+`lyin9$(Axzq1{J@+E?x_mmBq3bX z`I3{3Xe#~I8=*6Zeq3Wu9!rDZKis*fo7bB8Jp&?nf6d{}1-!q8au#2@&hCx>ynV5B zNDNczo}}=Hm&o6~1cjKuduC7k$L%#plgPx3dwDtBJv^OmhI`mK)+L*Ghi45&xgI|=8S5-|(~${Tr&i2D60u}p55;u9f(vvWj*}}> z%61hVCx>_KA9+1061+~sMG>!`fWu(Hj=>p;;dTaFUJ}JG-adQ08^3CW18E(w!;15b zl?DC0R#7bO{Z)xbL15HTrD%cpo7@KW3nrT$2GnvofNLl@aH&OjHA>ww6bH5PTBC>+ zH|{+=e>)t{IK0F-L6BR&&6N9)RsalSPNHi2yl-#_sPExlSSy*e)G zEQs{0@H>f!`^8e>42D6#Rbe1Naq@K+r5?N;HoHe$&Kay(a_ko6)in_$|wANDynFGLKd-Fn3$;eXBvuqba+*N5zBLl}C(FS)K@kry6);NzIE2D6c zx)~V9>E+D5754~&5XfKq7#yoAx>L{jk8Hf8}!6`byjNo%5e<&evh?reB@xN%zm> z1?<WDo9Dc&-LE1O*2jB_qVijrxsbZN#0~0z+@@(ViaRm)X z-ZcDy(r>k&0_2W;l1?fF6*F%#DuW&iU%22IW0 zC-xQM|K|=UIs25tex7xcVljl7$FZO87zb8=k#V%ZI70sr3PX*_Xh`78op_0_@X5f- z_suTytQ!?uQgdso+2Bnav{yedo0z(ScaI18WB*a}pU zhc)J*(mdqRcZ*i@@d=|)tqaYktNos){q-gKk3Ff{`V-&TzWrDoY!`f4g)d61Sjh8$ zFJh7*>65iql0FTpLq-C+736@yh(TY32TFplke|6PmrFvZ+`wj}!u16X_yRSQ0~Kh7 zaw!Qmu|KdtaBVFWQ6Nvg|!x#}8;E31&C6tT=5{h{$n8b=BVrow| zj5+#)tEF$D|IoGES%b?1N2w}uJ+HhOeQ&m3QhfRYUk^Hnhxka|-R^0P3c7agh& zREHdpOq~j}2AQ=EhTHf9hy8(%{k#VoH$(_YAcwl1ekDGqB7gBFkJS@Dc}f?>b7o3C z_^0os{3l$AzcInoB*MB91#_*`mbvg+;r{O$lFfF!!%dq0z*jC>IZpx}ufw!eC00%s zFszme{=jO<7bX`Rh5X$80^nr)8gN|gr=e>%Ksj^*ltU*#IW#}uum+!;zf2Jb$;Wq- zzfX>bCF4b|H7Pb1X)4c!iGc(>OjC-tfc@a4{~+-0=MG3i=O9nDi7Y&lc2A*_27w-A z?)1+Io?L4{&s^(i-fCPr?73U%Nhl(y<2h4&RtX4IQd~knKySsZ`n4;54tv291gKs7 zCz==ar>~oFhNPRpG^JSpR)Iqg)f$RRQC^#Yp^&}=QGwMx<-%n!8%E#QyFAI~AGxUliFaEDi+K=}mGQKRtWvAgR$}j4#FCcjgiLq0k zbw*3CH5<1l>&^q$rXKKG_-B7l`HYc^AR!H~JYmfl8*-$0;h>}Cw0we}%1EZW3Lu$s5loD` z0Xz8uWr-C)HOV>!bM^AdKOl*ZnbjVP4jam5`E7a?nTeuDF*Fih0$jeJKXL4+;M^8@ zzF1eKAw*k}00T)x%TiSZrH4#=xaq)S-OVx}5-AI)unB*#1$C98a=16O;Dxp7u*Pl) z3ItE08z~3LD12|lT{uDwnKQ7Tm|*U!V+a1}GB(LFi+*xrx0eq4>LwCyqCbf9>l?7! zoJ+^-gm?}>5iM!qSY!(<%>c4UQEGZqCa=ce8!jo&Ga=cL|dTHd*wE%P2c+_ST#09y*Cn~U7t zJUO1zFC7-kNmdlLrO@ZB!rhR62JzR5>G=lJW?B+|ASQGg$As);G|otD)%*mUMWO>$ z`{g@wu!wbl<(ia3HZgg>MAyR&hgER#()8mRODQT|e25{~LOxp4fNs*HrqXEhq5%Hd!Doh^iND+2`KUvsi0Td5OF^54< zlfXm((25&z76{)$K4Q`f?0`Ic+7%c4SXYt}Q!s+CwE<A4>?=>%Ih>+{h_xCKYCS~62#C;ebBGAtEHZad z>I@C1?K0Z3)MELL8MqL%7DUVGW^G)rO)~Rh+1h{)ieq4nYY9zaIkt zVVp<8fC5MUz0d1p|F0DcUR=-D=m>B>G`E~OVHh1|AA|o%g%Q6jLKSXxfL^|f99gYGDWBnsFck^xp%u+^>-mJd{5$ce5UC4fi+F1EccPYiU&C(i^fENQF|EoU&g&87KoM4T+EHhN;b!!m-a4fg6j1#v6EgdXw% z#7V`w7V7$}SGNnflsjW@=fbIs7K2fMK11zwkE(*S%nqdj@95z6vFhQ4$AS_M2gu1seydetu2rJ^Qys5O$D$5<*>P!T zM)Ck_|I?w9-QEVxf{4}9{v>AAUkKWv8X%X#P;SwLUumpiY%A_^TDX`Yy{L|b`^+c? zdt}6V7H0}EXxF7R7I9-$p84X}27_~I?2U8C4VERcH=5@nBaF=iA;wX;%!gf*lyAsu zZNKm`7sZdgee5Do|dgsp1{!cG3^n`Jd&wFi^}3QFOt38jljv?bE|^3)Oy;9^1) zqu{6j#m{U)5!qNZ6#sq_p{On%pp=s80066-$@n5rr47van?F>U9wO zJ7~tu(I=)Uj+Sbeo)ibd6c}|g*3cG?$5^R4EP10i8}_k_y=Gmc*$bQ}nhXspA%tbO zq@4vulxeI5nZHg2l<`5ylHS)x8$XonLBSC<_!+r?aQpX^%Q@w{T{f+5sPgNNu4I|aW#p2f^zXG&hqRHpqZF3?zGlF!Z2rHF6UVp zm#$GJtwE`5h&AAnO_Mp;1pP)7d=!9`XbcSP|F5YPzS3XYdltV8^2{yg-NtyJqhu_K z2@Mq7jJGRgS|iH7C@94G0xLr}LST&wv=F-LG^Zh_M@*|*AgG7HNfYjNcLXoc zO?FVc+o~U@Z>PI(8|TrqB=f`m$>NJSaqjyYWWkF({~v5_`p498oHglTOmI<4rAr|a zAk#-#J+aTSjGIPuMW_|n$BqV)_9OChmP9H-e&R~3`QxSaO13^K*j{8(6-F`2Is+q7 zJ2%w?xJ!PVZt7z+?43X(0Fd+B8)${-rMX~7Xh9Cc8H20-&*RCYTs6P~=Zt|9_RpcO zkWcuc@!qLhZ~V{e`m!YRJWy%C*bvqbRp^8GCjah$tKlyZ439^YhvA@T3>)I&b#P{G z5P274PeeN)NqSs)kRLqj76~1Nu0gt5SMwRav-uu!bP(GKXj5~XnHgBx+y4ODX2(A4 zCHKeW#)>-;)7_GsT8v-3nVW9Cmf+0emk2FqH9ZvVBh}NiFW@c_2%LiuhxQU_n2tTR ziQ7*+56Uf090(kT5Lg-Y`tn&bV6`<4*<5Vdg0{)v2C_E7x&&;T0Q+HkrXM3K6jU5Y z$I2+P;wd0XPsK>*ZJ`)t4h>$s6K>_Vyx1e&cuOM1$qY6a*dDrzv}HE)OtnALFDAHKB0qxhL-=8J6koL=- z+`xyv%pY&VCTeJoOnZlC{3Xx9nw%m6|Nu^@hXYNp*%8<=?+sx1VcW zTIZC&P0ybBezZe~OhaFzf@R4ZH71Ysm!7<4NHAhGia3>{?T6FN_%;9gn&bOM;!l1a z^9T7~*Y^i@DG{(7BEWF4p}U4Mnv*s}$4j-!)Rkd6PKKMwTcMx*xMysBPZZ6yF0RX+ zzC)v-oeK@^qR^mx+HU#SNsn)gHK3gXLfrc7ng23ynrjX1o@>2E(3cJy@n=|u9K}H#3yt~ zpLJubukKA>=FgtR13BT$A3gKO;=w=tD}}%T$8)b@Ye+xC3CG{zrbTY2cq#vt81yeU#YL}TdlTi zthmqj5uZ52P-ADnz6L&b;!S;gBL6mj1kq-(S%=)C5lYD|-Jo0vyF)n{4iL)WP-0cc zr|Ld*DYpyySBVk0#b@QD^0pwySQ0}sv;)^B67fAo5Tys~WAO=a8Jn9ilu2?5Lab}v z7L(4~VlsGJOqP8`Un0|({oWu82YCb|2veN5#iaALm<-+)lNI^^%h`y@9`(fdyDGw_L7mGbp1xjPgw}_5~Z&ikxvswDf$EdCcE$tx$qXU zf6zuhfc8jF!dyW4cKHrDP1s^ABt0`GEknrmrNb_mM0zQcOSPb;y;2@K?ouC-d-B~0 ziQWF8VfCrNe-9y!wRlJ3U{NwVr$+v?Yr8A@V4I{5j)?^c7c#o^f%jSL1L|JpfZv5p zsLABLnp19YXm@aIGU9g-{|PG)ph@L#Y!wk*{Ay{<4L zg;{6+Zh`J=RIpVt4WnYTM+I8K*}4>H6#wfweXtu6RqTss{Z=2L>6`)(N^l(wp;O@>^^`9Mw-d?^$a6Ed-_mYSrO5XoY=$d> z53o((n=UH??2tAIWM}kvh_;WYAvpdfVD6%X5VeF}2{Z-ihW?-DUA6uj_|DSx9s7Yx zh=vUF`{DaA;0us?7TqbZgup1pR!Z*l8e$*N7(xo@XQsxBf*rsJ6s zLMmucVz1?I4m4CNZZYzEpu*S=iW~4JE=W;gL^=z$>NF|laZN+bMtx2_Ly0$LAIi!nYHqZ4fl=Ye4`+N7a|Rs_iPy7#&G@YL zK*8-3fdbs$@Mi;aK-u#i1vjqw4%t_97Fhphw}SNyXXp5n?~pBeLnbB<^|_T@U+>>hzM$cwwJ3jLm3F zHNc<}^A3dE^0Sj^^}od5?%`_u3V%jDgm|~AaM#CJ>WMmN8Ta3E*9_eSxl73}p^qn9 zIrKrAEgkmg_y~U;0C&?a7i_usOeoy&SC?JjuNlV*&fDO*0e?;8Z!Z3l+6{33+oU@A zi=z?wJr2W*QlKK*Lpl0)0oWIS-0#z$=VdEgG$G3y$G@)g-|ElZS%!YKzW$y1^KM<= zk?(4K_{a6<1HVas7SUw*Bl>gqInBb{r9Yq0C7XkEL;X3+RjU}}L9O(A?32@VeFwh( zOZ^$@&UGe*HB*iJ4q@#A%Uyp`0Q8H1{&Wm@I9fj6@Qx#&w{#F*y##N_t5NcK6@UBR z%jcg(u)_ZXF(B4Jlk$0oE(vjrCGT$1}$Blf|pp^7|k>ZAVp4hn_qI~&!-;UnCE z{atBJjlrz%qSke{_^Bt#7Q@aXH!0JrEVWwNX|S$4@TOVU*(2Hu`F)HxBtK<+An*zm z?f(1?YY=4~=uw~$A;A@$v<@1g3gH4kMvdRc%6GM*%MA{|N^U@7D>+AY3w~VeGhv8k zADlnoKP}zXIg8*A=DC!#gqRZ_TB`%s`A=`V7rTj}QBN#=&eHEE=r3V%u#e4N?SUj$)oTDm><=fds|m=$69Y14aQ+1T z*-44a{RL{l0caw@nrI88vG(_)`u&r^G^YDj{7VgCugXsczCG;m$NMi%7rsvke8WZJ ze`aMJY6P`JS(GcjXvz<3uADbov(z=~R(-q?N9wn!IJRHEy^u~A{8Rev=qdHvCP%-0 z2Oo>pZ_6+n1A=iMj$G>q!(w52K&~U(R*vxQ^S*f%;{6dujVvr~9vySg$oSY)m)T7o zR!-t@I(|40lprpv_9qm0!FApN2fTqJm%1LT!f$OK`UyWjw|Tbof>8c1o#tcdug6eDKM;=RIS&Xie+vHvr0aRuZ{q%kFZjN9z>YxS z6(dD^t^gkp0wQw(5%Ms#ahV*IXOddE6u+^^es;YUmK$>DM|j3Cqn>zCo=+I8NRwGv)}@qiZQyRhY0fpgnF68v9> zE$9-JF>Jfe74Bn9Dopp2w&yvGGy`DPoR8 z@rF9b#Taljt_1(%qcQJDvu)@HcH=-d!Ty+}-}eQ#L_-X0g0TrjGc1Os2qH=-Bp|iF zNK&)mi~YsAyCKQKvmnP}(6SQGa93I(2|I7Hm5iEe2pUBs2kvrHM~ET{m6!5t`oVUm z;NuC|%;qbnrk`2P+X$gX2cV2oF$T@e_<1Tup;US3cI?K(zXthnv5ZBxs`3$O@s!Cd zlq;FTHOy{^)eR~Z(Serc5L{9&LYXv3fw*;W6hjlQP@*fZaYu3;yND;Bx1HCVlbH9Z zA#DA2BARmEv+)=6{@|GRPlvt^U81ok^aT;4M30WJFjKl>-HJVC31oG~!Ac0`!<3Mr zo@bMh6(ALqNFoBYD2Y6zI|&qibOqPHuG*y#4D@)C>mev_eVyVHp1#e(Kh~NSMDLlY zlX02iP(2kRKbP=+!eGNbw0XL;6aE1-rVnv7O*z~nUMv*s3-*+?Ml9hc^7kteNyzvM z1qDFEiN9!*`V;tjmh-+!4uO;SM01EL09){Dx(7BMT8O|E>Z^S6kaqaAP3;KIN~Cs` z7Y{8LOYJd4_O?Va(n(NzN+M5~-=oo2Pbf1Tx@v>IC&j#fI`rK`zpvycNJjC$ZNi+I zz7cG3O8S0rpkgBA{}w9xUKLN@p;zPSyZP@z-&MHWCVj8r{e;1WZ#oHmpNKZXwEeaIP%nabvODz%dEtp%2-cO-HWqHd+4;ze)yT%sPxW2Tm_BQ-;8*n=#Jpc`*vf zrMVt#0PQRO3>hJ>kwXxWnj(Wjuy5j8F%!*>i|t zPK5C?Y)FYYKN+3OD8X+MgC9>}10TPqyOVvv>Fyf*x|qLkd%C;Q{w4P+U>p0)$!?=0 zxU~df6|Abnc!hHM^2E`}nxY*@1xwK`kuIZw@>HW)?)Kw4gA-7g40Tz%1+gz2ql5Lf;t%~@zK1GAk{_XLoage?Qet5Us7XlEy%B)aR@F1Uk13t4PliV)N zT92W*NJpezGtR3wThXnmJ2tb05!KFx- z7A!D=1ELK6ml)CcDD;WwcUeE9Em9<{G79UJ=!TTpD96QWS%vOpIe_a+V}@fmUVH?& zJgC3GxCJ1C1ypP{=io}Df9My|KaF;RRqhL89U=7q z*fAChfSha-H^O~Tkxez6Kwx;y@!1X5?Vm1u54ry}`hG>f@4#1E&@Bi%Rx^&I@r<*C z%<}`_sNYMCeD%K_X|X2a4=M(;B*kc)B9;-Ss1L?_KadNJ*2OrsM@37Fn-8fchBcSD zXb{!tdYZ1UX@pJ?=;p&CMmQY%33TdbzY>n)F<`Bq6~dm7#B1fXNt<^)y+t{g8$<1K zh`TIK6f!JBU(8nO8--?|(Hq8@-A0v|-WC-7+2P%Y0^Sh9uHv0s^>OOkRX&M#=YGy3 zD{==w#%`}&2cLKkdNe>5im8!314SO|$jCX*CbjAA@^L{o!V{pU4718z;jlhV;^p%p z2?@Ln>rP}6y$v;w;Y~!i_V)R;B`BBZ3r%-tmjwUfZTcj=B=2)M`}_?1?33<1>;Ey; zezvz@$GlE(At64)M`6+#0PrS%U2^kB6j0+rbYIPMm#gw#^j*zk;e5t>I-_eteoWHi zONjqOUL$Kil-#_7jT0z{|GX5or_9e)`xaLB417fN<4jfpuY$&B2qZ_EkCoN2mu!EP zHU4X{MJ-$*wUinrij!Lfyb8J%bb{}RV^*Vy*#*NTNkv(N7NRH7qkOVj zN^NYjZtp`HM>O3g>qeZmhm@_=%w9V+0f#5XD|W5pso%L6S0wziC<$}mlsVaQTrLuc z3b<5$zpA*@7W^P$&RQ%`SWI3flmdq3NO>@tKD%O!*%PU56I+b!$0C3*Ogtonl?1mS zh8H%URfAp$FvDm;T|eC=0GZ3KLaJ#ll||RU+M|HbmYEt4AzF?y3im!4rX`4dDq#S| zf+*(%O}RJ*xG+1)05v|%0F~6xel*}vS)Bjw&^hWIjNKR9nD;G{B7$3x%is;}u$If1 zrnx<3jEFDQL)0!@ z@-O{6FXCBB36G(efPe`U`Y$09)V?kB4>>@@Ku*k5C0Q##`YkUyq(Av9A^k6Kg`|(W zFt8^mZPt&n$P5RpDLA%^ z6PEq0eVmXM!wIDS=>GLbusUP*uW5Mh262+^_sP-DxYWD4p!=1$9##&XzFo%!`-&T+ zg2)8Lmhl+Xz%TW)sZJLc)Q`(!i958dwG(xp@1G9-2J80~{(u@a8@+Q3Xo#;? zDG;^D8W-v*J}nZOL-Js2Lbi2$*3Prl{80b!`;e@Pe_geoz|BrUQi_)#Q=j`!<;YTy zZnBPtMX)Z`m(^1$l7#C+tC{x`2aDgNBhYuajyZMq=BjgIxqGPk-&P--z_VcWz|s01 z{VJMEo$@ISJ)r7GQrf*X6^$0xPjeR;12)k+R0)CH!8p9zfOpX7-(*0H_zGG$GySb2jtoI8sPH_G zA4eMcNqSE-5Bi(>$HOq~F=(mo_n|JrTQ7h@wJtf%gRc$M*ehV?^^gaAv>{L)o9~0` zTq`EKi~PsBxE6hc=l#dhs)s8hBCrnbJQxxvyLnd^$_2Kksx{0RlDMt2R-Oyyd z)8y@83MT)tbk`#K^nf4#v2Oq5WN%@UfBAzw*%{$}y2&~=89!mzrzeM8KQ{Kb)7V{M zQo8@xxv2SmY+AK9zP0$a@C_n`4;u^HyP_>0+7fhbASUW3cWepY8#AmmDC0W2|`>EeDHZK*oTLT>8`)X5Y(T+3N;<{TpfB zHKM-~vl}cuuB8h0Djwk|A_W`=7B#3GhMxo+FT*VWu;p|C*q(fa(upmTqv?<0gI<0= zP61gY5zA{-8p+#ONCz(W7tf*!<0W%aCylG^F`VhPF=PaHN)a~nwz@NV8_M2TGam15 zOv##7J!1xVH7jMt^!6a9*A$JM9U3`1p+}T{D9p)5)dyeU03Jq)Z+{%CCY%J-o6FD| z;0#~`RZ4cj@bV|YP`?KatEDCpLHn>^i)&Ff#0i9CF`-c^NO_+<)d2SS-rzCs;k{lI z+4l9{;e(0Yh<1F*IK`TC2I^ODC4AJnF*01R!ibl3a{M zh(dBhwbMa)|ofylw%C&Ou5=*J%y{Mu(T-m z@~z{ak{nLve-yEoAHMW(+{TPHaJYWWclR)t_;6C~SZxJ86MgJXPsnqml0sZVnOPGskg z#>rJ6&8tzC=4y(u-FQitrLh)$pWUi!x+YCrU*KjnLe(e3XVgel-}Z>vEQf2?q^Ud) z=d4F_scb7Ykho;5W*JbR=aJYpiqU)mbp#|#b6>41(KMpbDtzB_#dP;oEJJfErF`{G z+yo;JJM{cv_H2UpcHek21xL?;B3DKSS9j%l!+8?V zbMYMP3v6uMtD5qU5A}p^5;@4|U$>BEzj;KiNo!el3uzn|=ECPi6I+1tb!kNCEmZm^~j-%vgk zWC(i((ZVt8&n_H;4RgC{%u)_R{PQRsa}(c(o_DCvbK*hhwGN);lJA2m;mc-SVWW z6LUNV@L8~);;eO@m~^tZa#C%Ilsk`&3(efR8|e>Q;osPb=+}MlhvGP&WIi&f$kjc? zjk7awQtZxPaRpN2xZw1yyGdarN!%Kl#2;h={y@1bDfz(YVgh|}oC&Sr_&@|mmp%M!-K_Wp0oM^#B%yNAu^*tyLHHvo!3ZKc!1%7G| z!^=w-)+Ul06rUx>r`-GGs1*+KH-3_d+YzaMzgt`}n{kB<#1{-xZPQtkdGD0dxAl+x ztr$i5b_fb7jlGAb$&k8?PweA$Gxef}h_B<(_{Uv>w4S(3q^YMA(geOscpvsvc~rwM z*6~8NpjLg+ieTS1#S&|N`K`uAP?99V^SDuwSbRkp2NISO#s^6-GoZH^dVPs}itB*& zD2}Hv2x$@Li|ft$%Lk{j3Td9}@+(J95<*7*SH1FoU5zRndUN9d=0W?JB14dUDehsv z0LWGnj7($8sxjYGV_^aT_N8Nyh(;a{rj zs9;&Di>L_wg!ySt0quO)_Au8VFuP%iqoxM+0EdN_{FqGEV;AGh6kPKVTOuvl*SJs$ z6cgftaE|LrwmzeND4A+gKA+IagJUPS*eJobTaKzWJ`EKMzkS+7V_S}i#4B*k zU=sR~%*o+44P6Ac@L1505$cJxts+mu#JM>UbSx_X!L~UBmu7>MJCUmP0iW11UMI_n zeXv&{%l%X}fx=UTMU+>?ePuJOICFsX_CRD96vVJ~S{;%-&Tw@{2tvwna4e<;@*EESv>pB_q8mAL zaPAr8)qU!GbcRYs4PPe^1bKaj8}MoPjnELdE0zm`12#JuXQ08QAUF({=A$cgY(sF^ z&Ol+;3;?X^7QX67Qv?=w+OJ$h5Mj_qt)TAH*Iu6;r02Ov0#Dksh3)F@?0nS3Q#T`Lc=XjLp zD}~o!yg4ig(ThC_g*Av@B9r3RmVA)FxFizT20AYZ*`}fi1mO7%j1TcY-vbteKU}p# zV29X>g%k_g#cGKA8RbCCt93+-INv6`Er@xRSH!hs6K+0lfSCN4XOwnr1hFwnulA5F z`V2E~5+I?DD~rlEIF%JF$^e-Ex70wa_}?EV{^7s1<-dXt7&KSbVk!R*$^TgRd<^)6 z*T5waU7rFbN#Lq~MQB~sl|t)|M4`3xei2$Ec}giOcdIZ+ke3rBS5Myizb?5XVm>Oi zT;IT>jCj&BE*0+ms(rwr><+J{h9Mn2aIAwAr-v?O9?w_;7*ti1?gF^DqM zRz7V8{1&TTIUBJA5UXCnN?8pA6`mSx+x3z0?N^eVkgX)yrdE<{GEqsU0%SISi?X}~ zIziS5mx*$SDoQq*peWgPf}&&}j-vbu@-wO^r=1~4<67NDQfnRg_%ME%%a=s;r}#pAFt94-1k1v;uE*y%&(6Y9rJvh~lB z6c(nbEZT3rpc>d@eJ;mF>l5`G@<-p;i6iCxRvg?l5$odlFP4^?VJCH;U$56aGkQATj4kV0uP0a8Lv;pHHbOTtJpK~+SMS&gHC;@ z2GJ1yD@G%A2aezkT@C^ZK-Pjt%iGZq?!(a%Nf%;aj!g(4NV)J7f)Y0&I0jqsM;&?` z4a+{rCd4k-3VQRQC;WaB_r-2LJR{>)u7YLiTs9vXac+A~OYkLDz>@abF$K&$bjo-)}rgg>{fLC$hHo)|GvDP?4u9ArzoGULN#}Cx6 z18=IW4BQc~&@%OuavV0|$A1&9xl*nnGRdK1&Av@z&2I4VdUs1~F6*?}d(Z>|O*&52 z9wp~O4A!e_GCxi!P`LOzd~U*3+Y^*PGnEfOl6+X5nPlDbnh21cI48BLTebi}{3340 zjmqvcyb%=jPvJLwH^jRS`^k&`dbnkL2=p^P=myC>B^bmcxGhPVQ}(rBMbn%@`uHHW z@M9#2+Q#7w@fdwIfF1(jHl1Qrwun>Gt%NlZ{Md0Njg?X9|1YtzXa{|or$=lT{#}Tz zcRaD(H4DU+{;Ck$44fwtn{{x_i71T)^#3WGhL=f=jz-!af1zQs&FUe?eO6cfyCaV6 zv16=j*0#%l2~RvheA55cFW^QH#gy^C^$YA$2LF8hf}O9oj|^MYFPQFbRQ{2TSR8Br z$Vy@ZnvzOH7cW?fyRdJu;!)e(T4(N$+wLY7VLjpEbOa#9ZlsBqWir~JSx$*e4SGP1 z>LavN)O5#CLCg9DYKZ#E9)=I0T58VH}(8%8PdL@1Vsv9YjLy`D2mLG zlP|1DRLnJ?^B^M9L2u?F@Vb@@mFenM*-hA}?WcMHiv0jBR3+Hp1vh)~QC z*Sv&FvI`~~;XOH5z?vl28?CW8wnuMC90gsF zhV}TGc8Lz!>>lo+8Q~2uhv;2Z{#9LnCmr;xQ&^_J!p6x61pRD;oMDZDWM9EM^Z%p7 z90N;t8k6`x@HXv7690ZViy(<#o$W^w|NfHxdk9t}@o%5k(K}$fQE;GIz2uaZg z0RY+rLq2np%fb(d6(=eA+nPzGK+h5D4V<=z3Sob(Y8UZ^ABBx46c_);2TikE>94z^ z^e5wof?3A#L*Y=0I5AT2e{PcNNE4PLG8}O{&E)*4=v8G*sN{U<5}Ykf1C$DcY6uLW zV%LObDRsp@`7sSUsgj((M1Bt2siW6+wvJxIrMT#|naqJ0xRYxhKVB9x=MRcX{1AUU z9Ve=oK;F03^CID+dHC%ct{SQ2;nVXe%A5)LsBJYk8Uu&HfL!A(0*)%te{-fO__XE}*9NRp-PN_`%ggGxqCSV?cEq2b5y z#W16+-7_$shaF51}a40lx$Tz{(gv%gR%u!j+5=D@w%X z*H41!2TF;_ub(0GlaOD}u!iyG%opHgnHS07Rt5P5#1aAF=VGW5F2aH7YaaU=$LCe) z`W+-F{~ItS1tFv%+>=tb1g@J%DP%et^Oiw9;5Zc&<-~m@+tvdb6$^{Z%Q-H^@&Eg% zuX~5k1Q1*S^28P42EouaP$hgNf+VJY@|`m5aH*vD56}gW;MnjAwu)n8m{j??6!xR> zIb)FlF1}ovXeL|I&SyHK8we->yOJoYmmkx?tlC*pZU>tYj<)SidF+?pY6D5UDgb;e z5}*T7)(a2)Hz9$780@WfN5z#!&j!okP|a1q@Z3(rQ^{<#day}@;2}eCvbd%^fBWzw zP&hgw{*5|jK46l30($t784;>EDuQa@8}O zG62_zV{yGoh#|f${3gHc!;yMw)k8-OZutN5L6< zl^A1FNMuoMd-CK$ zPVIDQwyF}%d1j|LfB7~ra&wKHdwm1)dj>+xGS$4z=3?@%+ivieY%t4duqyl~2o^~< zpMaASjj$UPIvWK1Q4v9%+hZKVCf}H2kMZ{K1JWc?&Y!{?e&m~vJyE-o6VmoTzj+I- z-r=-5BRmAHVtvV6_PXDq;kMeueJ5wU?Ph<;X0x1T?+X7(#;Ehpu`F&IMdH(7iwzM; zL+7b8e>VBX>{e;$0X!4aUh7Qsqi4ovqPIm6m&7NdOTXAxgM1sh<4yEif_}kMCrw75 zj%?nR^{3=%lxsMrFZhZ{>Ev$Yl!gaD_SqTf{{?f18R>6;(cn-y>bjqwIrCw)wdm(K zVXB0mBZC;C+(Zhh549eozQZ=d?AysOkQ#8UymvbEOZJpRV*D8oi8qijs*5aswLKo43DwY@L#>BpD{y6K+567c{H1aSn}X z(YDsq0s+nNj!KKJ*$T)Ws-hg!Jz*Uo@NN)G`-%03mFy7>ywk6H@(>GOqJ9~{YOHRWwZsfsIq}TpwRo%MgXh~L$LGWpTTuIFJAC7 zm+>u7!n1I+ZpRS7biWwL~b-$bz9nJz7-=y++)4}G{=6*g(U@LUEG?roh;E~i1UKC@cdikt#FBMv8m56X1uOX3ffghT`^Zu`Mu>?5 zRd}diR7N$jd#}kdLgTWm>3E3q$AjnT2gl%Hd2n0~s~26Djd!!HW>4GIi>wZDlL}9Q zo68w>^n{}>3C+kZsrv-Qk?I<&Ivb%fj21|6(SEaZ!Ea|2e%ZQ3SKR@U2t9EdJlT*? zr5IIZmQnEa{2>j-Mo${F8*G34U$&ok?K^$l`-WV0|`8_W=VZQH~aK1fFmAeT#+x$2UE zFv2Z-1lMCA7Jq8P|ExA)qA(#i_)u`LC;sg>-<0}Ur8e!_tz9YD43%afKY#mOpgYXH z24LG}3^?W+(4++VwlS~*@*1szJ%4M#+_RKdXX{3L;);IeKBcD{SN#P;6|7dfPGQRKY@uk`08$u)jKX4Ocq(l^w^#kkEI0UjW8?}<{p2b}h`2)Mp zlJ1+N`!$4xwC_%AA9ZLzZ65shX2rE^J^!RVoj0QGp+YB^VrwF7o%XNL?dRI#ujU91 zOSE7b+pMBDzaw08V<)BQa-KWeQ(xuIVO666R?TnPrYP46 zK0<49K)8xtZUDd|0Pu6bf}ikRZOa9FE&`uXdi?qJ_~&u_r5sF|FLVvSG%=$ncyJ`e z@Y}2(N+nI=l{1F=lKA2yq zp@c$GC~83a@$#KA%hFS__l{qldY0ofdzU-wM~W*~-2|JzjW+rFU#$Q5!?rCbrN7q1 z4ZBtSN0BcRHGE;ZWw8Ea{t0crw>}ixuNO@Ts8ug)zsa=y#$>n_H=zjSW>k67s?^bA z1@R*=ZP6@8>HlAx{|`<&|0iP6*7p2sWd5Pl56fwCrSIb*n0j#CAUJdHc@NIqDinZE z4db`v!(O>J*wq^x0WF=r3zu-`kLtaZ>b=eK-f+G*qe0$$oo}8Q_vZ7sbnUts*#E@% z!m|^}!hw;%=Ms+3nlSiqOQ7(xcR8M(80O7$2O|Gx&1wz^Ybe_1saN9Kwd<@6OAfb0 z*0T|LzlV)qYY>gj1O$mrwjRYR32TVRTJ^qbAst-04G$mBH#VlYGuW16uBcYNfLCOs z>*^MiwHt!ZDRA9QYZP|*m58kGFz3wbVHo+G8wuyk8XO`;xZbrIbd+ACt`6tbi*WTU zxq7*}I*eB{tw94ZN;Ca}9lg=@+DHoRWo^I))_Yp+MzAy@I!pF7nt?2w< z)yRJA=IS#Hv)_9=EM&mIZ4J7JvmpY^%>LU6gbe^ff)#JHf&)VXvaMx5Zv_f& z?q`P&pV&fI@QJ~{pdQsQVj+PqEXgv)`VwxHHh=*bT!jgBnA4-W5Qwh%k)Z!>92#Qr zuPzVAAr}AY>M&jf{=cvAzpX9&$C+r>+Q(yO8y+0Rxx-wVKjQFTMoga_KR>mY0;IT$ zm}6kNxugZvmV_h%uFZ48FuCHFF$(|dFk8+40w3)3#Nt05KHSL5wK~E> z(ux!mT*wnYB2S<`MGRDabiHuJ4LHO=bUW{R~SZx>9TK*X8X~;j4 zf@;0H-TKDm@QMvb!^$fbSWk*Xs0bG0vo6s~M|d0#!-4h$AMMq~7<9E%h+~Eaf>>|{ z@0F2^MHz}59JJ1D;=n1I>8;~^>|LEfeN!4aOAhvM^4Z5L*TxSgUU7+lR1EUK;*(H8 z_`w7Q;r{0lwf~upjSz)|^?thF#Ul$mEE8r?v8DiOCx8u(KZ2ox`C}Vg51pUNoyjKr zB_WoN0))@d^$UyqN3l2Qfsz6Ef4@t>-xuI-uIlP#!W#Cc*G698uFObZ!CII3JUT;p zYc%B@u#GPClHeOoanZF#@-d_^&AM2B$_3>^e8K(v@`pLJ$14ERL(@2SUJlLVciBEr zu{3}_C<;D#i7pcq?DPf0BL9|1+_7DvPR&wwuR${$l$m)HmJktCL8PDzA3`!5^SA-? zL)q*77&XpV_nMoLpwvP3cGldNF|Kc?Dk2q7f=KCQRa@j{<}c8^UH6*biAFn}s|~gz z@;A1vOW4-4CuwV((^gfu5j-_Rjj!%9oZBP2*dEzOFZF=^HT5LTwZK+WL%ThECz`;} zunqY$HQ8>}BkU%f$v%W8th?y!e{mieS4OOlCHzCq28O_6p@NY!=XLO-j0~h{*Fyi+YzW`ej+Lx4Jvzd z=OsyTrLS427a!V529Jb;5{iN7XVE$oB#`mWn^x=$nuq@rxWxGgvPAFd<8Ef?f?MUZbLsAy){^K(Vdr`uq~<;Ji^&- zOzEhLSa)O*YsAR5LXVl*vYpoRc4-+STo+De8Wo06jyd;kRZY+lAH{DgC*|DT22 zi_`zyJfr^M<{@_`kwx3d^^?7%wz?hF!x{|N>c3tw>ntecEARoTbG$44^Iv*Doe!Er zGK|$poo}x{$km%U?9$gzvM$N0nu&6YqR6GGy2nA>MGFe99Oo@_)rIh5M$v-1Q%WYe z>h8mjQ?!5cuB0u$xO~B1(ZdzK8#nrr*LqhbCG{?hbbR^O_`y=LE1QR`c>n%C_ZeXX z-!~3_29N!jMpMfb@ZZY@#rrZU`fr+VjTu;4^&Q4)j%i%cxbb4&cni9_>LQrIzc3`P zIV?j#;dZApTS5RDon3Vgpaa!$iFd?A^jST($bWa*_!$k=cl`?;+pzf6S5I#k`@>+7 z1B}ISDOe(cBM3O43eV9HjmDJ4(zdbGKrD5K!P4pAL0-d?Qk=E zDJH0lIr_+tNJPdVY*mBoF(_Z~&n3Zq*0MhyYe_T(Uwsyh{}7GGnt~_g3o>xNgry08 z9e?0dTtbGD}nh31WHgyCI;0p&HX`UX@g?XN*z9vL+Y_wML(7Ub(( zgywDZWblbV;oNm_x4;!Z?u?{cgZ`7F!8v?DMi9&myEgU6v-o6EJOuij5w)Ceuj2eeediIMO2T#=Pd7#@Lq!fCDv=^?rtVkgpv((@cGNHu5J2 zaqyT;O@m?1?ID__^VU83wl02CRjmH4g9P-kQ;Wn=iRh_>Uj!?QWo! zEre=b3w9f|5XGK*%tGV(*`1@IITD|AtTHJ<(xUTfPX;L zN-QwKY9%(@hvL7GgC=9aHAuK8O5MYpH^{P(PKj;s@KE|F|ePNi{T5j-D z0KaBc3agUaJjUb*68i2zi|0T%vg_5ia?2!YwCF0{p8ko3FV%z%blW6OP zgtodw+ZrWpVLJ-;bDy}z5WSIwf&$f@@|xkw`MwWd^C}5>vaxh3MYh8x>^fryx|p@1 zwimT*lX1eoi)R~*1vME-NTQrSNDxd?hpx_CUks^Y_N#shbVFUd&3fPwP!e#4yTG@^ zfIy_K#|9TZvem541QWtP){=n6LipiC*b@;k@!ebnYT?Ia%Zy^zu2~(kz8J;V~jtYV!jN5T!N{4dKbc%#9p1Z79>?AQZtinK{=ffwh1kED_YgbH67E8fKAIM6Y&@MGKtLf~8Rb-)^= zGy_5i{x2+c=T=<{KNr5aJ8QgS9AW9zC@X>OHvJs>HE@3WSOQC1NnnD#YG;vR1qLj- zk00Fd4aFT=20Bey<3EQgRpjLO%9gO*v(PRLBz!SZ73bpGh|>i9@EwRTX+MZqh2R)a z>nE$VDC%OZ#_qSX0n`EDOB@A&lFJ1Vlgz3HLn1I^hcm5|Ws;Mk0KMbqBust|MhD#y zg~`?&E}!AFodbf~|2v3gtRbdBD!r_P1xxoVFQWSX>vm>I**xs+-&;^8>j7OK7yRNX+b9;KTEI2~HF$-3`mfG8=8p=L@c#U9q&aBG_0_$xFz9F1z4W~1PmN^2Y+29_~yo05C4bSU`% zHj3jZS@!f`6v|QK_7;TMG$bH0y0o^o-q#AB(N%TWOq6j-zZ6H|Um^NMs{At|(42q) z7w#G*!sLA(SbM0eaFBR2Ga$i=yF;QF8AbjhbE}ZEJSEu+8mklUnp}8$1X;;7kUOg!Svv3)D+f=uZWi__&9>sLBfoKgt>nO@Phqom^i{rPL4~4@7^$@rK`aU_mT|8}0r)GtBoX3q>Rs%2*TTPoo^2j8T(501 zT9DoD$3+{DA6!|EBHTq}Z2YWq@2uq%x)U(m>9 zh&LN62^mI7s1%VvWgc8Ne8JMvK;e6@P>7rbCd9=(*3)PM3-l7iL`Z5xnFp_x<259E z8s&k)-^t^!EsP3lE}ku+vB&rc@E;mvR+t*A`2RaqmB9M`Z1_NQF#;Hva=BojIJk*A zDt!xXAWnBH58yBIumqihf931#z3I2)ReK6v=woLEWCV^SyB@km^cgKj^j zN_*A^Ll!1&k-uPWHAZnf`MxW(0g;Cy5Vl0Q`sWY_JBE|%(1zU)p~!Z;%HXYm{Dx>@ z{e+e+k&!2CtP2~fYhPnX@$G>xn9Rc07NH>Mxv8X0Q7Q#0khJqYtc}%=qrIWJy;3@B zDlsB@kf>BdY%y~bh=a-JHB)*^zRGrMxWpNA%TIxn@zdhBFQxtS5@`o+8N3sL|2@rm zMfSDXM6ibnh5_&t%@p}-%95&58#Z|IlcUrLWT!d)0c$aG(AW{k)OHPs{th>{aw)~J zkk|(^9N87fPpT@-FUy#p4$5f!<)EZc=lnhQrHP=VKnT=iCBb|Qr9UtCW;6tjCNr1^ zF~C>`IN`c@R2AS8+2*`$583*3PV8vIbKri68&&j&j8Ec+;8w{dh367i`BY8@Y>F&d zAaFw!X%(m?sAIqZ2tJmgk=&2W60-LMcUb7|{-_Wbx z&womfAPl$5%u-WixhAG zRQjz;;Ck4AJ!(fEr8?MKfW!t~Q ziJl8wDQFS z_;`?Rzrkt04c@RO+FiEA7LmuI!+27L@yqD^Tno7+Z1aZ`<_CIJeeFP>c?hYo|4asAU2a`0CNtDZb z8rrdbco8^+-Z5N@yabc5dq(70>(@OTaL$&5H3$Xa4^Aal+h;1i^-6G!#IGl^kMhsv zC(Nz7oZZ`kh^1?6K?J3VROrL41(B@RqLRq^1W9U9wv}aDR0u_adWasi{(4v-9_yBm z$NzxD@r@>e^XWyBB#MbyCmWDec7n0+ljAxarus!0!ZS|4_KDD6QDXnMbGjZ|KK6|n zh^z}@L1Z24ZllT3W>GkSKkn3kiYm4!ppd^k7pRL4bCC>lfjv6;gjs_fLTaWw*jRlr zBb3U->{+ZnkZPt@-lW{zyljoQkTkg#uWbK4od?=467SyjK)^fx;~z@+)@>M-sxYUW zIjS5zUBsKfP;ho{!-4X(e}l6VWc?u@P=dj0;hwQkRi?wKoFBoFn?cI_fVF$>sh*6S zM>lIib7&#HIk?*q#y9^!%oM7AN@QUQ>Yng&1A+&g`_gu+_h&ly zGtYaD`v;5N24`kwE`E|*^^5iQS=H7Li7*E%;AGl#xq#UCX+7}}cyzl}`$GjVj{rtH zf&h3i_!%Q0ucr3H8`jD+j@pMN3O3J4X9FFasCO=97+Uc>(+>oVzG*QLP>xh+mq!UVF{Cp0qg zV=3=Aga*jQ@1I;E7UqeOY@@d~nYL0(`NQ+(9Qsan|gjtWo zdj2-3`wOEsE#;4EAz`m&5Ws@q7RFUaI@g|2oR{(wEXJ`4Kl9!$dEeq&vEl3SECozC zG!CE26ImYIM!Gm^%|ww6%9rw5G0t;?DUSuGJ(dDjZinC=?CayXuMy37=Df{_e3b7D z=h(02#lM;pEPf2wf6N#EZXtZ&N%J<~Z5e5{{q`Y5-^FyC9jtxKNI{bK6OZ|DXseCJ zyhhZI_;(IJ%Wma`_*SymN}6f~hqzXhf6q|kS#6Ie!*1!u_?9x*Qa9BS4sk8%HX31O zFod~fgAw>H#bw?H&j7Yrch1f#YTB2EHEB2OMXVj!c@wV9-vh|M2WWy1tTF_WG;kWq zW{;{$+IMSiCG+tft@Ws)40jO6gTns=#0zTtgA>HBNS_@7ow4VD`s$k_F3Nz6qT1w< zc|C(RMW8uczfscBziXMbHi-IW+ z7X_z1ER-Y8Ln60Awm49Q02Fj@HrE;%dCly6AGC`!T9mg1RM{L(!Ds}(aDKwni0^PC zhZ^5uZc(uKVS_yiy|wO9@Eq6Y=kS-r^_hV|fDU}@5v%yvDPGyS$DE>I?ZYI|qTmw` z+cesqe*X>zi0k)k3O31{|HCuWHJxkA;u3PmSOW$$x?wr_v4ldaJ zXC?MOwRQhl(m%LB`q$iW^8R~AaUFq!0HD=~jtmCZc*r&DMv^X$r`)>_F}1VD7d3sH zhRvS7XCO>=Wapi@HXoGI7}=$W7yMNMvxf1vv$LA^JC7E3M!Cfe^Y`-6_r&9T&^m$; z4So6rqfuJcIqn<8uOCNK44Y?5SH<_bSK@o;zs<%rqu*jUJpxDZ{6zhHY|lli=iPi5 zA!v&$$ zYX9UotnnytU1k^E($x4)1;9?HvGC!1YoKu0eV_R5)%Z1hbpIjrXV1PE>U(ZN|7Yo@ zPTD^J9rYih|3!>DOz0o*Zma*U3H=|h$5I=S)`25v=di>eibVdH61lIE$a^V~_d+7? z(h_+CUTRY!(m#o@uVFHw!TR(#zNXW+QOMJai^gBzN@%);$&gBzQ^ z%D_oW=!sR7NFAr)UEJim-wu94zk8q~&iL+>w7i|cy-lB?*BznB4OTEmb56h4fv4YV?&S&XCuZi^NF|N zhbq{HsJ7tFRR+dvJz%N*ET3j5S$recUxo2TgmhA95Jz_`SMjSM6DNpO57eW1qd5h_T%vHDoxv z*d8#3e2ViT0w2T=R1y9@pqEIqo=bRG@P+3OeK`86n&WRpWEtr;0w>M`?~G+ z$F_PN_+oy?w{5rIC;oZht6WwJVoy?kB0EAno26F9A%(ttjXs!-*goC+l@R!>UqlHU zH>`EAGqh<*UW;Nl>Rh88nrmGn$!o0_SWyKY?sY2se;UO<$cWnuuoJ}p2WKt5FNWJN zK$2Yxm#VW4u7yFI0lv80(Y25SA{NR*`p$5c>RMQYvl$II@8nuY3ms=?xE6ND8EGe1 zx(S`-+7h}h#f7DN6ZY^CfQhvteLZzMTnm{k04u=4*3>+APW>6ORk`qwxQb#gRNM7) zl41WI!(iyDE)H%eYO>Ob>qmFM#g4P*;C@HmPnmr^EQCl_{qJtdI@I@BDhaTOkxyTX_AF^GKvzDQ0-5yiN-2LrAqWn^ow0zA;;do z8Ov>jOHd_CDV#qRv{pDn&O!A!@b8ibZJlE^96z8ZVBI7+Y8YbVS9Bid%Qnul;yivT z+BwdYeET~9uk}whMAf2|5LNg4=-`F#Wuu?Iz(V52>^E;_FUb7eRavV%xB&cIzDNlt zc+>h_&zokc2jctldpSIh=m&;oic&!{R@a#4FTwNhU7S(x%RrVWy;z=mvypDr6%|IS zCJFpdzq87VLPHrIkN>-ts`nxT0)>knwKv;tpO4+MDR;+iwoSz)5N9@Yu$g+@-Kf`U z_Ivt)-l*@;5d$?-$Er)UxFq`dcn4tJ8j7U3FzWHNGT{|`&cnzxe4uR*QcDUcCv?i- zW4G=@A&S)mQcLwXW94(ts(;4eh>^V4*nSLIIunfn*u(wMXxiV=XO2ycc__HkdpK;E zJ@M4UR45{9zOgfF89Wh9oQ@rt59>S>0?9{(qC$(ep$o% zw1`gKV+HzSx)`7b100P3G8F>C7f!i%DEZ1Lddo?tn9DXRb2O@~K(gRzd1ezMoDLf1 zok;0AFuRXy#k}q<9)C+=RapGX3}gk64biXoalooVL`x#`DEp^O(MODbEBtg6(2Q@{ zr#3I<+CX0Lx$;u$j~)c~1_-qge@C7y_R!LcHWVkf6e8vnnP?4=zxN@%Z462jZ=UrR zO8io6vyAozj%Lpv0RE_Lu0EIHko^!236(8>YYYy5}wtM@zIoPGW z0Kg-FN>PV~`!b^=4-mw_xSckP%2Ws{`EnjG|C+))0=su1SE~asG%@gLM_H{*bXeN)Dh@MqiXj#M3pL$2yFcvjcROx*nlk+i|HT?7R5HJw)8v6Z-X^h zeLgXV^y+PM;IM_kvt6Q%;JL5I3=vR4Xi6}cL@y)87#qR*D(#~t>xcKWMxJ%<)vXaX zE{ZrUMMQqh*1S0fun{*yH zZp^>fx*shgzX8^C56b@!5i+SjBf`Vl4>hBswkS(Ng&q3BE(;Cqhy(X>2}C7kIEn;~ zVg2RGR=}f{&JNE^7^9LeEP<@YSW5c^hU7FdCc|n0jY>dc)~_LxzeKS_Vd@zhJ^7dZ zh|G$#$D=8$8N_C|e2^Lw{thMGXHF*+9chmASAfQMVHbZ2Gzf2-nVTLWkTEAp2Urqy z|KQsQ;zBpiSM^9*L#Hz4C;WSPKN6?p(`Md5$_(|Z6asB}T|M@lm!;*lSrgAeb{VYM zx~KUz+BWQVEaaVO=@Psq+X#-y2^6j~DZ>#0G%?G19J|+umM94_KV>+~nR`GW8;}C3 zV=l{S_f~N9mDclYysoAChe}#GVXCvFJr^R^Ew9}iO8`m0wG<=(wn`NjKoYZpIq`hZA%%$OM<6?UP7mR=Qu$l%Gbf|M!bIS5-(8M~sqVwk>%K%+-!@Qn0sblpRyH-O7Ps#*IU@lV^9@ zzW%JSUhY8NH*pUR>DrmO5jtZ`$B#Nn$o}mS@(7(t$RT9)qqK_yWoZ1wx*YW zZoBmZlsbxLx2@u3YdB+Fz-IZ#i}McH%%Wq5_fP?&5IjC0j&zYjtFROT1U7lGadt=+ zCyY8^`icyV+n<%{w^p5*&Gy8i!@wvbuyxgtGPv>%kXO~9lQHmHac#T}3Y?akH{ z01qtZste0wwg$8dG;&k35qGGBMeSx&-}Vt=ti<0}-G1CPK$VrRW#cS@BnnMqvQ=#> z-b*W?cwac1q5!P8mJ#d@4T-ju4%L=0?eKC!s{+PA_ZINOMn+B3%sdEpC)Bw$;(++y zNlF7ar={o`G|j2XhpCL6AH&=<&iJMxy`p>yh5@rRY$8T=Z5fsG5oL98N-X;vv%YaITN zfP}ue4iV3zvb_aIAmff;3qc$$+(aK8*OYqNoB+H0?msi~k$Ld_kD)0TtVRgAD6=6C zHuzk=4QwP6WXfs;9pW1?rxdIbXa}Sk4$4|ND#CFlKmN_4i{<#q6>0eD1e+*Uf2#RC8l9iPVU}To*;ac<&VywS+XZQ@5qP&? z(e44g?7vmjAD`P3-760h3}=a0!4p6^%$s7Uf##uD`M?OwAj7jduH@huH2G4mzmxWk z&ceXk?^x+qeAj~gYZ{<@gjlkUjX1s3Hlffk|e4{PI6& zc&|A_z2za3l=FSq*_hHQ3<=G>WA%Ou&lRLTnK3Y_+ARu^?dKwt^>JLXE`Nv>C98*W zNVrG^2;W2oK^pu}3}Hz%p=2o6nFJa@6)GZF<&LX|2rn_Lto36w(AZ=~_`SAhn{=Sy z#~e}(KbXdPVFSgrROXi`%Dy$wK2oQZYD{u%I0nSQ-GpU|! zSzk2EQy1u`fODGQiBD}*PbKN6fKryO0e~Q=`rQT30^q*?UPvIbu`S0Pc$y-++}7mQBdei3T45SQ0-Z$85`lx)&$UM*{aej4q{ga| zsz*E1RaVYiHJYjKeSzWkYt`SmZS~jCfEPB+9;6&YNb9!dZef%c2pHuf`juXx>AyDiACx~uvolnicQ&0t}r`Y{IHD*X-K`W|~d4{yYVs@)}oUgqCx9R$7<8M9_P1le$Q~!iI0)jPJ=)6Az@nZtGMpxaB1^e6_3b6#t zJsAMk(I@bDI>EKveoRW`K{n>PR!lU|$LridSuKXOYb2b|>7y4iBsTNIS{z&>;ZaJR zV|QxZZnyF!ULskr6>nRuB&$|_9&IIaDaInClOw3BMH3_&4E+}|t&M4`wO8t7Ok<<1 z4Q3{%P|jX%iXmlUqCFmLp0u9TovMY-(H72JjuwQJ9#<`JSDpI?+Nhz|PdWHb^q1C* zb-c*7{_@(gVW^+=_uJ{&5F{`7TrIHG_uHw3HW2`*Z?qlixyxXsuboAaz8zAJTVr;L zi4rJR3MXGl$586T8KSBd-vAMHhqO1(o$sjZcb^e8bz94sNfgEgITeCcJgu3J{exFo zHUzEKQ2`gITFh4aj>nj95hnHc^@xRsz5)$^g(m$80`^z;t z%6K0Zqp}5O_{A1{f0o#Sl~^{tb`6H2Z9y)TX$u|+Vb-=S2&*J3V49 zE9}-w4d#F3<6Lc_JPNg}NsOBksssol^HoU(#0%G;&m_$BRkvTAP$!2{Gp7sjte7w3 zy-YgbEt1UP6RchN;s(YaomEyC_twUI&qokF-(nKpxN#}nc?X0 z&&_1qa{M@mMvw%pNI-%eV}{=t23QuQNSUdF>ny8n{9@$W_OWq>3di{z~$>{pm<@sroD< z&usVGp*I1Bi#q{;=A;(vDWcreFj$6tX2T3|)&2x5MU)Hs0+i(hC1_nQ!OYa_l|OkIikH02{e1PAAyl_PzGRza>6{Lf z{QDf>(tTv9Z%DZ6gos&^sbFk|t8T3TbW*laP@3(kTQ0wl29NxPNx81Nr_@~!?s{Bx z%!Z_l$|0&?ZeU@BG(792cfaCy$L5M2R>fD44uqMY%Q4y3BkJ}v`!?>V+c+7MYt2%( zQGZ@cm}~Ow+c+8Hu_mkAaHg@}K%=3I@4z}^RX&De4Z(fbeaz87k%g!PwWb1Sd?}4D zWQ0GD(G5}mLMKpJB78oRIot60KtVvm=WY2Fh0km1u7=Mt{6fJfY|wa;@+TRty8loY zy!n&7t~&baaCeM~-_M^k##J|8T^gG|X>9fEHXwWTPJ!%H8#VxFEM)W5?P2!q1jwGP zZX@-tO~@YGaRSKoFNlNOjs(al67v_Xsey#3>f<&C@2Ve?+jMKQufTv&$jj&__q2zu*U{0bD#zLP`X zC*rcKi?D6Y;*Vzflv{d%Op&3kLY3&Bw!XNA(H^7o!AQTA2`K*fQxyL-6c?g&%+&w5 zS~3vJ`R3rH!z~+=W>x$M{t5Mo%}@{5mSAa0Xi^G~X`xAJJa!9B>c(S6Xi^4`SP71W zyYi^VwP+?~nK=OiI#xa>?KL*r5JA0lSsNp0gSBu6qRUm%;cw8Pl<~ngJ^6(0mHu+5 z25$I+1yO^m5$&z(X}xkIv8C;?&^<8au5UCBH*3BDk{y{!XuOo23lHNXtr3jcBZFG3BQ>hsbTTuyw$#bl;V9)YaKJDBsj(UbOl8C?2j{YYSG9E_Rz z=uDVSO85khmb>ceA($VUo5o{JN@#93IY|r6&5)CBp}9R>?*wZg zjdxYS`{f8%6*(mn*{&mr!QK$Nt6=oC1U@1byJi_K)MeWe_~?oTBUlO)8fAJBLs@91 zJ~kYKfB6D6c()pSQHPkp@4D3)Ji5k=>~L8LrnGtu)o>FTO4LCDVZ#abad?dlNk`?x zooq}>K5yiYja9+t-umjh4^}^pv85QRW>3B}pv$HB@~~KW;A2d1vO8PGaEL?iF5UAI-p8&y zJ_d>4HdLzxz2zGH)hoD#Z%pjsMm2Bal#`ot%XGXkcXZ6uTdn}J)Sai8<=@$unf{PRF^k#n`3lgHja_D>{e8^T)iFY#8G*Sz=kyL4;fDCm$E-%lGpzML8+44@w~O4U4&9Z77cV|6uVPg z-DL+zec_qvh<1*%s^AdSs)A>)_vAfu=(VNrweLO($&Hb&+#EPXO&l+m=&=zy3bR92@?D^?q3) zH=r9iS&S2Z;T6-l6sj9W_C&cV+?nTg%in?WcbNS3$=_*MS-AaB-+@oB@R_4FVJFyU zj;lw63Aiu6#5H`A*Sr%JK3M)c!?max9e4{4x)zBi6`+!dHht95Yff0H66o;(+0A2u zzHZpGp5_Kt4!&;SC4Aq4{%`1gc_VO7SyJ^~GJ=`%w=&ehwF&s285*7y zIAWf!3Q5Vya$NBjF1~@N;`+%|_l|motPcA3u;g}>2hg)qoZ*Q{ivAn0F3lIMwK}S` zCcB3jtD|abvb$KiBcy1!$-aewExvqf3*G5Flm4wG;Bq6>6BwI}Pomm<1Rai_T;Y=$ zcsYl#=IBpyXTkcVctE67txv%H*7X2k{w^DYR6IE%XRR9tX<$;-pgYLW@b4Y4I(k-X zwMz13J$naK{WxNF!xV96;1s%E{^o`}QyO-HT> z?DG`=AKJbJE~+y9AB0gfX;4A&R#;SYhpw2ifk6#6DwP##?NX`P#bgzf(h39AX`G@~ zt4()v+qSjsveue6+yVt9troTNLj5w$JQHr3nxT~Zzu)IQXU?261K95V`y_MDdwJgH z_CD|PKJVp3?#hllnG?A?C(@sd#xrxU3p$b;wW=8rAaofO(sR-pE1Pc524ga_Jlk?S zwK<-TvOGWXi*blWW_xzgznH_~%0)(u$bST{o;VMX@Bj(A4{){NcNN~b{(5inqAcf! z*L#u|=eDlTEo+IJb)d3o2?m_(>_Ho#+u1)hWDlzEddTxx%{oV9!!TbwCKMR%u*a=z zw=*ifeD=EEKm5d4maM5hBe!)OuRP1o@obXs=K^^Sjb+Vov)=IE59bSjM@78(?u&i#-F(kVv+m^4 zH8p4O6H{Q?B%|4Simm|7#?N}HX(AB9GK{pTH|QO(`0@d0-E|mv;K}oScG`yQw2w*R zVQFnc**C~ozGb~P{ea|_;P`^9u;hUt<31MQ4w>>0{VY>{I(7} zHP4B_hX)Xtr3dF5AfEtB$NDP9ucnK%BK}|@JkXHaXy}oF_J$Pu)^XbnxBH#YX5bN) zJka3sI7TqN~hZOkEZ8DMAi;_G~z^UjpHOzAA7tr zvxdbwKZ2xYwnKMsfQwKYci%boQdZqBxg+hz7sO1ZaITxt823! zJy?TO1#wO(^rCisg7c&R-4R_|lXLJV7Ti!*cd)tc-D$1e>wcd4V`N?3)a_^1{oJ$> z1p)x;em;ozM-LuH;>k>q_1NQcmI%Os&VR?${XFeUz`OOJ#xiwvpB~fz?`OjMA+qk% zsh<)a2)H#Eo)F|mq5-d3;AJ>JC%iAB>-HV|lHh9bumj*)2<}K^-M*>Y2yT6C&4gfZ zcz^WZP9z%Ob`#v*3C_Bh+APPxlgzHJa~y2O!_*(aC&$$7XMjabtrVqB5_@FrUWao% z>ck%Wp$=5n#U4DwD#uVIcIszR;{)uPg3e*E|D@Uo=N|uJ;_N-8=ITlx0uBVQo-LT2oe3pV~czhYwulpJpI4ei5{yQO49C$UR|>eIAgzMGnE#FBp9Eg8YlAkVeK*WE;OwlZQOQDxuX`E` z?Uh1DI+3nnzV3svqHa$KM_dq17loyXb~A{a%&_E;Lv-VVNXiaJQZ3AK1q((75$6g^ z94z$9Ss zuV#@j{fkq$wC}Sc_oN-qike%?Qeiq5OGTQr&~3BR0$%JfY59;P+M;DQGp)49sBRMU zHA`4Klu3%lOe-lS1zat(Q$SV}nAk_a$l9?F@+3?mqFK;Ngz09OqKRQKD>-s~ml^pcxpbcHWgN8ys`3VHmmjV+!KX?7YVlC?iwRCNQ zu0m5?C>(INzz5F{T|Z)3V^|pU^Pum$`k}GVS2xQBJTfrD^F`NBS=bmF2K_K-SJ!XR z2hjryq_E+%fg_%ey4JCkhqcAaZA~ zD}{~2u|-VH8qi;Mvy#3Ub2wDHr-HrhCiF{z@%Yom&`_s32q zZOJTRr!6o6GD%8dIV(vfF&8n@MvQgpWRgXX+D?|Z@g`l_EMk)xCtW6CE|##0i}uPS z%gq8-vN&Bc>7kcyqlc_H*2$!5Jd4<=3QY7&iYBp~RZu1^4>B`Ai*<4+_Bk@k6PXot zQ*@RG|DwjkWO?u}>bKpqJop#&a9oz>;W*4CoaL|MG^=NeXA@@$A7B=N2?2dc`22C< z{75y?3Gyc6!+MjPnVQbzZxX|Kl3;C}=|qki5Y9K|%+~ZBZ%+;DID)}HbTU218?FfF zAP3EigM8)ma5M%{H#97D)|qt>oq6Hts+` zvk#)MFdT){$)lZu=qw6PXCN{VL}N)f8iS~t6_z?{WWl8KdCsH4k;-wpF2*EwE?1wz z(u??nN$>kFNU<=JRT#OACdDfkqny1fBi3bhWqRphy7Hl*uFM!~NLLPoM$E3v<<2&{ z@>*sFx-xnprr_3~ifN!4Sk`KwYBA2%#+WAR6Be87y0|DCO4q>+riJ1THyc@W zAx(M?v4GVy)iKIr+NYx|VI?XM0y4>IW+^KNfH${|t;V%u~3??5>QQ$cZi^PfT% zV-OECw>R-A5^#E)uLGJ(P__eVXQ7BKTG#>Im8>BiR|kYIU_ts_9Z>#)paAcy1Iibp z9DT43h+d|^p(l1g`f@24@W(nJdlgD|K=4`x@MLCzL|(;HZC~gOtRWs+2ef~}g7nim zAbtnRVSL=!0qLKkn7tFzg;SxW+}U-dusdq02J?aU53#t_MClG)AkuV{MXY@~C~|N1 z>SmT}%h&yhnO5^8F@MERdfcX^iVO7&m0M<-s(6cks0J1KWTvf3WC<%_;9i|+e+RID zl`MK=COxSvV5Ntwfw>EW(ym|;J5_-d3X`IAmb2Pkla`^(w3=O6+fb~b<8M-x$Ff$c zl>24UHJU}Nbcyd}5|+;rR>HuV^(I+&uz-~;dR-3!Ge8S{EX5Q~LnOA8mgPx?^M zGUHI<^oh>&h<{CVp7bMSgY%jX>mrbP8@~UW9oB0k=i9d|S_C}=M8MGf)_Wxd?YawN`7%aJQc|PhQYTK6n9@e8mgzIzTC!1hTG*6Gu$44oi%Yy!5=bH`zwO(7vUKL z=M^|(pzn{wM)2tm;#R&Rm-D1S_bhC);7NnANm|XhJZaD$o8DRnb9*SRHuJ`Qf@0kC z>X73J?@6WYnR+ExiZ)*=@p!^IspP_87P(0k%X$&o$P4saOtox0VFxkJ|8zlzybU`x z!fXyflJLj4pE?n{Pi`EG{m~nm4`FWvzQTb0cNLM?s^U0$BlfM5dNhYk;aWDpHm%d^ zoBZ`TPGkK!M*R($g^^k_Vxj=?whcriKvbT}_e=HjuiUyNf;7&*>WAX6^Ndpq?mXkN zgzT&1>WDmW-cng9o6oRo1p8O{MW(G&fTA=OuA}9?{}vy;QysHNJ$;!BXui z6j0k#u_sUNF~HqA+9rqEkdi`iz^)?A|5@n9JYC#MKhJ}op!Wgl=ajTy{lxvjoHap5 zMaehndpKNI9eOHT?qRH4x2tf8HLRE3=u7462;J6WuPGClG)Phc1p zfD1;~HiyQTQw7qxX0oPtO4pSW=IZ=w7uM1}usDO3*)A=D?ZiO)1nUpNRPsVG)!6=st&G|rIq}9Vkzgu@5v2LwH0+9D50rgg2TFAt zQzA+%l*f<5{y%IHyf)X@y_ajtaoRoO)-wHCDqf42-!z0$gedichmc040C1dfCJ!KL zD>w4!8;f8plPq<>eI856Hz=}JorPx{(#I}W+%JbZd-p*YfoFH?^r9KPeXcJ{k4H{FV`y?wKl&F#&z;t@sh7{Sp%i{* z%+PT~(L?VnjzaCBm(I8n_zyjIMl8za4n4Oh$G-+R`dpt9K)TPhjrH;DoWt|QLoY2# z_Wzy_88Z~T$mzW%Ru0W5iuFGs^=eRd#uVI@)9LY4{EaM127JC2PeA3Ep+nI2MaBB{ zT#ljF;`$#?{d)dZWAlECqj=!ZOcc8m#jY*xDz{qU`+Sa}*QkOh(is=ll(lpzP5}O^ z(5E8SR}TFRia#b4Nmks@K}BHFj?&|uW<;k|SL)@A?iBJ%{nC{2YK{pQFC}y1iV6Kj zO=!$gw23<=j-|CWb#{B!k-ov(oKKZU!A{J11NG%(LFT+!$vNE0j2q%sM8~;(-Q(P_ zgzQaOrOoF!D|&R|9Ua3up}u?YdgoKy3h{;hg&{0RYmRo~m+oT&EmgK?C3;zw7jVIlf7#`m3ilXLE`QAf_tMHN4yTFLQz(R6l>?|vydqYIv1t8D6tAHBvB_(OR60QF<0UGMhY zAI0y7H94P{g$(!LZ=G`|;vw6)@*+&G&*b(kw2(FX=W{M|R=f&vf%q$(6^uFtvT3rS zofQo13l5!$Z&NBLe@V@ckm{Jx4ezf>PH#K`n-<`|A3ho0fDI@-H^-L;v`;u@bOzzC zHKAPI`_x~iIp@AAWeYyYs@WUu_T3zn)Ae)x`(R}G6SI)*9=z2#mmh5e{_$}@`@}hy z6?XxDo3AW#qm86u2S1aRo$c9O1#w4cck=@w7-p8?g)s}U8%yN{lE;nq$vM2_Sfq}x zxp|cqHAV5V6I>5cLGK;kdW0TC`ElP}D_Xj+I03J?%=CEYOy`1)#NWS==X-D*ot^x6 zbn$Q$E1hbfQjNQ#w4HK7>lY(J7!xZ66;4mtus;Qj;b4^_Fw1+a6_-`|ViT`~N9NfG z>ovQUJ>$;xMj7}g{f$zGudtVLosUE3J9$XFrUhqAaY(0ulsx8;TMB_X^iykmQg7v* z(E7OX*EM*Pb8c-k@B>=x^4i~w3V#Z%P;sodXJ&b8ajaYsX<#d(z$E!w;_`LB%7qUF zo{x*CYt#99-AV}4@DbOWog(u!9SV%lN*Ov)2&`pb_n_miK*smkS{z4q+&_jTk z8^xp#MydkYk?6oKbl~G%r=N!>sOND}PuFWreee$T%%;{KhklabNcsRUIth$FAc008 z68%^if$8X(V*vx*0V+QBwI&#VvF}4a*%!u1ee?zS*!O6h?&-Q&&A&$AmM^E@7}g(C*@x&Fj%@R9+-~o2vev7E3<)IPh+k}G%kp- zXzPY~*=OU9b76gTrT;N8v(z!TV>qr(bTH`7uy%1?py<%1xQ?}If5RVmb?bY{0mh+; zIKVjL50bP@C7sWt@ha&LDycVZ(9Z1t`F;S}eF9 z?J4BkN%%{d#7mz2w7*gxpH11NRjT?QsG^st`ZG~jA*-b#AGg*Mn{yO4eC&tEO4Bvx zR3TBTID#eut|;dQiGEx}78)d^|D=Ckh07EA4dAJG7YYbO%r5VDO+O%lk$?KN9`7v@OSDb>69(#*9^J_4=>nm}*zB&`} z$2F9+ey@vXIIiTHcL8H;J#jT8^?zI(<8x8Do@qFphp%1Wv>h}ELPImYX}HPjn`ok+ z2~&JoOj*W_tX$kh%uG{)+Z%nE))x@ueT3(<5uWQ}+@9{ZbW-kXSt|_l@28LBb6oZw z4mKu(gED%1P6~dF<9Tf>FN5}1vzT010!M@@7Cd`Wdi&9#P`w?4Y9W5Vkzk2$#~I(p zx{~%J!R19jA7tY5CdIhzUj+)aCo7Gs#|6J}MvG0$d2?2hd4*g5~#Sz*Ir|TlT5wtj-MG|f{ z>OUHv`G}2Rr|>u~ITsfQdL3OWutDs8h$!!iTX zPM#z1R;n~~8KfOnX@6E}m?$9a8lw;ES|pRa%rvLpT^|b5z>Fn}r8)lJF_K&)EtF(WpG(<*_cAH9jNu|Y0+HjTTRcW}l7v+AX(q^c%-ja5i zO1np;;c8NpJ6ENRQfY~j)=#AkQE7c8?R1rPo=WQ{X`NJB%S}Oga4cEm_GNI|w<>M3 zN>jS=e=2Q%aJj82ZCh};4Jz$@m8NuPjY@l6r70bHOQk&>4DV%?c298Hb1H3=N>jKz zsnUk1G}XpqD(yU#rrMaQ(pvI_UR8IZrJU*uV^vzO;5J68v{qGDwJ}VkHK{b!##Jh9 zyGm1i;R2PmUZttNaE40zyGm1ip{Gh)q|#Jh=&aJ_sx;LXPMj?=nx@iJU-(X?-K)|R z9eY&TEhMmspD{L99ikk9ug0Z1O9PUNdf#b+r$5w{~rGbbp8Wt+}uF?3y41gn~u+MO|Eve zjz3s0OAjoB0haS0ZJcJ}?+V6Wk8)=wRiy?9!6&P1o?wt5e(P^X5dK@j%R%@*L&qOj z(|ZU0g@Ng#&oL$)BoysZB0v;{x#H#PGY~ED8iGfT{ zOSCaFq330_?I{W8v8nR$PtGkfwa)FKM|Ufg4pllo43+7B*u>V_clmY-`2BwBFUD`; z{&v{+%keYrCrzP#fQh{5ftN#2f2%$b>~Nt)+nTvuK0eomG@BNOa>Yy${uu4UKFNGS z7E3UhkpAPB_OWTC&Gtol+Rg1DAv|e%)@;{!>ahLBrc-Qx>%NX;(pLM`s1=f+dUm32>s(_iTD5&KYZtOZ;@-)T!S|h zJ8-F2leCj0_oi*pZtHc9A*v?kJfP zACJeJc!5v9qbP_9&N3Wy@>XZ_r+b) zt(UFFQq(}kAbxoV<}2M=^GO9S)0%qpMFZZqUG4Dl2~Ta?@$H2dpam^L{!;#2^s=2l z*8qBH#uI(oi9cvF zry8iI*%_hyDY6vMEpzT$Lsld_WVUE|LE7Me!e|_Ci9i>mhFb{ZVXax z7-5@!?|{I9tapQ_V*!gxAnkvn>zo+nReptTI z{}_VdMX|1jopnn7lZ1Wok!mooc7Mtr`Jw#Vx4__EBL-1RpV4v&QFy@iXMO>tX?uT$ zjec)i^bcJeLO+@T{XIZ`(M@4&-Y||zqBDvAufScA};4B!?gVJ>NI6kx#gd=}~&meysJ_TeY{{z%8`*+Kyr{2Fi7{4Oyv=P5WXstA3ZR zZv3jEeHZe2gp$Yke*jx8kEpgke$jpejj^HqZ~Ou~|4;me2o4hjZwtf!egOmvU$?PR z{1;Tm;4m7dsH-O=k*K8PKe4UBf=(M)+b)U!Re~rzyI$ADjnEh|&)>H3)R{Fx) zmsg&#lh;qkySsB+_T?H5Z6bimPywL--Vu&IM}WSTAMNzrhZ-h*i?FTZRQ-nz^sAxL zMw{qAS}V;cbF`&j<2ZCF{r{^CQ}K_h#u?aZhZ;K2e=GmP`)`-qk<@;V7D_X|iYA8P z^lLT87QxVI#}N9}AGJgEt75L9Uo(%{sM7pn4T{L0{v_&@{kP!pD?EMUp0)`=TaETg zGa}ohZznCd(0A#pHe5m95Y!H(?=N!<`WF3QtD|+b&^P2?|6BUXp0d-oa}4Pl6xEje zj?=;meWU(j!xi+6L+w!d>M9KSs*c*~Xy>Db*?-1;{J*8|b)TKStOuKd(tL5@_!~;E6rGclH`T+j~8)#67qigk_}TCzgk8c z*lMXnwLSmX#E-T;Gyt{IV?z-7-w61n8E3bNUkk0V;J4+E;qV)0;#c{>e~I6jVelIw z_?7)E{DUE~u8hI{mKu`2>0mhgs%{DJ?@)aQ_&Mh^Tjv*{@$2$=HWq3xqJh$kJwE|K zXZbtf=l3gU@`Z`>|6oH>>qi7}KR=`&I>A8v>t@Lw{h`XX#xy8DJ-sr56vmC&vV;M+X}-xo)L7N27p zv@cx$o2jx#>)9dwZ=A}%;^Q{@-w@`j{#95DR-9&K#V_e!>E$*#iT@Ayr5X1$x7ELf zaI_OqJ!2uZfP z-$KUQFWATs{th8tK1V#5AF5ukzx|O9O09aORXl8rYBRCWXtC*<-)>@?QsHds~&N z?f%uK{Ep5Jp&!kF{$p*)Zx06!A$-;Ib`-BCilOrRd!Wj`{q`!o0#s?Pnl|LuhW*M6 z!M(HKKJo|R9?pK98$jfz=j@0)d85f*#?PvO%qiM0)Bg%P{wyiA@tE=(hvu;Uca*4x z^ABfod=WO^w9tmC=vU)#16?hSsJ1&k4mIpQ@Jm5gwysacgu}1Ogum>4j4y8mDHk3s z{mZ03y#M+4$88LN{*MEE(0`;&`Z=7mM}MwKKk#dx{=oWdc>MZ=!LJJNOEaR{#IKR| zUGPg=5KcZrO#BMpJ7xUB>QCuoHug#X7yRxy+!p_2{1N<~`CT~t7P$iaYxw6W;}@QP z`yaI-2>H$geE5Igw}qdKKZ4))&xXUV<%R%$ssAm0qr%|V2>9^-+QhGg_FL&+Sp3GB z_*Jg`FZs7}Rw)052!3UU+T!210Df;j6OMmX*9Z7_sOpsQ3#)%gcJ!!!ivS<-|ATGe zS4F!n{Ob`Gzy2nEc^%?s93)5#uYYrAhVri^hxE_FY`FLgjKimH&9v8#&MY16;3>~594xY}2%iHK#_vp?4E zNGST>GwDw+k96IG+XeOe8CBlDjSp-k|hg>f7%MlQR{$Zql@}X8m{KKCc#B*n_qJ7^gop!KPZQu9z zw399>py;1%(l1n{le8p|_RpsjX}FRNqMeehNJDmfvi4PTc*r zmoD3M?Wrq-7}=?;6H}E1Vx~W6oEg+EG%)wyMT8Z8FPr#fg2;RlS-=wnJOWdwU9DPN z2EAZ=`+z|}Kn6e$b$LQ3f2Ca*5O0!xKBs?Ju^8P` zolm&NaBH*?JRjvtnDZ6H0!neoTqF*g3Qo9HP>uq#hfE|+g912dpRLd_X!?5qvU(tY zr~7j7yIKyGLy719wjbl9k%Z(acS91grs0EASvEH#3KYHB4COQ-!K1wT`4uIbqfUM z3Sv&~wLm^PfV}L7XM2f3XL#+mE2`e%LB zX>Dyj55oBp_D$#U;%q!aiqqM8J_svME(IWM(mX|Q9zl@{>Ru`>Pfr&Xrb{}lvX;(t z@B(I|o3flZ`UM8ylauONvS1x7e4bvwaa5j;0V}EWh8I-1dSxiaGOyn zs_>eJ-Tc)rDB_JE#LA6NN6V0iYAy)$if`CswiI8@`ye2Q1%jd5dzRb#plSv!h`Mjc z3cyD{cFi%5ad}w*69l@AKjr`NXi%9A3C_^-5 z2V4`gouADjEBLi#;S4)0zNZdnz?fE5R`RN@E1mvJ)J+11oNxaMH}Y)AEI(G<9mB>k z?UD#>_8K{bat&ZBYwL6TAJX}Z^D`Ve@svrxk(I8E(a9(mp&d9DGN`z53a#P;XZalD z6Cqg6f&cytr&N88Uo8i-##9{?^)GOF@^Hf5|1CTQU;)8^KU2dBMR1`qfI>^Ss(AjJCtIPw9r6h*SKF`Zyyk-^JiX-a&K@&*o!1K<3rFZv&r z5Gu82e>e=_W*LBpF}sp>%iAGx;{4V>GrU}kE+qE(65VzN&fnv-<*=Aa4*#u(oHdE9 zn{m0v;VQ6O?y}WxSOyob&OC0vMULBVHed$-D*59KmtmjtmHhLBdbtxQDd3D&R^reR zC7+P6|B{IJC@@I=GUtMI1KNXqY{|;pOm$xZX2%``}Dv4t`2nB;FZFFitGI_X!q4hH*GW5F?wwMYg z^|MB)DaO(V@N_AKK-}u%k^FPQw{>JEp%05yK_$smR zt~{AM1li}|-c1p}f_)(ZV8?qD$y&@xcD#fvz~dM0#Z37U?nV}0X*pd!JsIz8fsiSJ z=eAJ<;4p5M+^xnZ^M2o-wvl6#QNXcb8OCWJcn$yl)kCdK-K0Nj&cDJZNB>H7RUG41 z5pkr}3hu7K*A(M&n$xKy5F&=6f#*wOjzFk2OG8$Rd1 zx7y4@Q-yGa2A71myzHrlQKkKF`5tOuBq-6>zp0BJ`Tx8AHy}DaMXR%-yGUB*X2M;#KfE`^>0I+w z*Qs5h3QwKhFQVx*?dhYpS(=@7`xsLP_6 zO-^>SOg^V;*#IThAy57m@IsJimp2ob$?0(!1V>X7w&G?s@7S28D2{I&N+?Yid-Nng zPrefKRb18}>Xi3Bj^TswlbR!`r8NysI~_ZoEe2x?VRr-VD?Blvf*H6?PAmSoxizgd z?U*XZ8mO)6SnaU*c-n^7bqydfaRipg(K*RK*=`Gze0~I4x_n@>aPAR?P|f`Y%;q=% zM#=>aUGIKRq7IpG$&~Rs0$Eoeg7? zKWneI@#o;caQvyXFvzPnXxNXcD}(v-<^fx4;7S9Qo>(|=Hg8BE|6+y%({`I#@ zoQQW4{d)H*Jr-o>*WU+(D*4wa@{%tqyTOReVK=hA_GC(IuDauG-N4^xeJOTS}rwiFi|4vft zME|&IE9^!+ag7~yk0?$l)%h_s2(0!RuKTd6j+Na4gfc7Dfhd{1V*ygT&klqGg;KG3 zWa&LH)#%LsSbvHvorZ#7DQ`&eIR?9JDt2XJh>D@4Ni(%$%frFi5oJMlA-;`crJ3k* z{2MX@$gY5q2eO?{71<5zbYuha|Fa?g(*mYPrb$ZvT}}C?Q2q$M;BOM;uOpo#{bJ;$ zN>CUC1M;_HuH@h8@yo@2mz{_#>RWcAle6L(C;|I0Iy-;V|QQ!)pCMZw?(o=1#3_`M4+l2Zuy952>TECb6nVx~J1 zi@8F2j8^ut!LglIjs?#y)%_~YIsDR;Ill3Ve6Y{u^3G%M1MVndbUqiFJl@ASmls!q zv3rmAW&EZ!xgIayZRw4B*u|yeIO}u#Y)@Ez5VOWnzr*|k>jS$86v`|PGp6*u*pE;i zvwMUGHtk|~0GXJ1Hl2?3J1i>8ORfiT>byitGruO(mDN^F%Zbh+xy~)({bf|_#C?% zEL>86b73gqkppTlx67Jiq=}#3L=%a66X&TWzIfPZ;@XfVCR>}p{ZN(!nG2+l3%Es6 z9RFeB_%~4Ak`BppR^W4-cQZ`HnbIPr9O~LdxWL`xd7a@-c%uQrP*ui(IL*04*Ew<9 zm4CI!YOk%@_u+?}U+dq$nT$B1D53HFoAN;XaX0Z8d}J1GX*52Hvs`_&#r?PnTE6)~i#2uRQEV zdah^d2oEl&-ZR33+cwR(K?@`zJACK_t%dPo3%2jjn+T1}$b0cfro>yeL z?LNPW&PO3`xW*OFxJ(w8`PRtvC{zyYVfn7sYN}SvMOtiEb4>5ot$NB`3@~*sKqbWa?{RI1z>TJEIk?Yr5jHRj`)$2KIno!RSPBi~;R+%CqQ(2fID zJtML`>ugi^%B*A6GI`JS976FIsxTt>VqZhqCO44mT-<{UOeZ=(3~JVNC6Z5b&i#wv zZb8@O%b4^N>tA^v>TAgdnjzzQxmk7xhWz!qVX8+j(C)odXv#!Ep=q6f!|+Md4&z_Q zrxalHSRs7}`03&urJhSsOLjaW*er~4F1V97+(Y8Z znolo|C(|GYJyz%PE6NeCiEO2%jxebTlri9l~01c7#Tw;@pNjpy4C=jGwOT>2L~)cWQU z!wAhju!O9^@W-eZ3kaFevRp>gFV?wD&bb+UQ6-3(67e-3n%YBMKSUL zn98Ob6@ww!-V(Bfx9fNbP$=0+_&$sTZ71=qP@3;C;1wxKYbzxD41ota&`1lckn zl6M)z`gaRGP5F=zQorpi*0S1eM2 z+k0Ic4ULPbaB5%&E9tFph-Esb%AY6fDaGO4JC|1|c%vew?y`{Qq);?rDZgCjDX3pZ3^ z@x83IpR?jybQ|ZIJzb}sfxlg*Ib7Z}t_XdMF3WP*IAARB%Sx~8#o#iQZV9(&|9BgE z0V~&2tXy}s<#NRlD33#1xwE-d>q!(U8u4*hRY$GVgM?HLg>ZtPC**sQHi@9b{qSDq z^88CpH^o1~TC!BDB{&}yGp>klR3?#3)(Z++YXI4Xa$*BzjXUE6O{*x-6)WrN9 z7o5X5#2)LUCf7tnwj0RS(cZje`FjL)rQsNgAdVtPRLfO;o(V5w@ZUcq{J3NYTFLhv zQ@&tn*!T-PhZ&dCif7YBoK7bNN91#B_3CX_YD7Zsy)A7}Xn(pc77JSsB}R~csf`E{O1OQuH^dx(AVcbd6X}@E-a1O$>E|d zbN|kHpzs!GRDJ7K?VQ(?$-;IzU##*{#3IpWgo6wv0bgWSfY>y#2kZ}Tjt}Y&GX9L~ zN6h3#XJyw?SvLkdh2pq9MH{!-)=P9us2SdFm7HBMXsq3`73=i!NPL63fY$e^VA|PM zqIrK2>7PDKryUA6R%#{z)wAB#mkd_-WqmO#=(VrEW5WlHBGRh$@?p*XZKK-+eg*!O z25*&G%U|OQnOHW?6l=l2VcIc`H~a=;jjr=SQS=fXLQ(SzZm_bi;vUc`* zJD*5IrM6jaQ$SzZ$f9sxtBas5f?*M2)ffE^V5S%bexuCk1GZn_XBkuHXU z%)Tf-0_W2nMgR52EM&H!sQU%|tlE1@YCpJS{LnF3)zi=QC{_)+Z&bc8r3An!;Zl9^>}j z3`%>d4G=O9M+9m!zJsJSm0<9~M6#S2~)I- z0(npuPYveh*h`ZOJsI?)t7d;R;*EV`+=J_j&d>Fg;0Eppgz}1alL63cE(}}*^t8EI zlqu5qeN433CoZ`857cUhTB#Z^8a8~!wTD{edzmPvU4RBFZ8j)K8@;mem=-FWHvZf0 zEi3)F(Fi@49VlUVR1Hk(Te4_Ng(zpm zK+vcBaH^zD8yKudD1*|d4^_%iIy447J)nSw4k7-f*DJqR@)KSkb76$r+b!Fh7bo+J zYUQ>$=e))Tq+)N1gt=sIcS#JK&J%Dt@%hE?auI#QXUp-9PqOh-)`I_u-qZUctxqw& zeR^$#bK$zCGw}+S^DLHF^G(;Oeek!-H2CV*vZF1;W<_VY%vr%+kwojTB#a!;TX0VH zP!kJjUw#XL7EF`cuymsb3UjVcZ8=5P%flC;rdK0g$}OiX0&88^bgsU65%Hl{DMzH` zdWPhBZh_jM5FW7SbXuaz1KSDMY#5!{=a{?z(C3vXm*RZ(IA82zPwA30Jh{PJ2^sa~SJ!CBxi=5IqW&CNuri~GvZ6gM4%B|TGJ;FP_C;I2^ zqVq@iZc+X7Yt=ss6ofZ!NB`WPq55Y5`)954q5cT(uF`nMfC z4iqqeP%`>$;<@@VzS@YPGn(~=RB^I0i-j=0G8U1k?Vl=RKxFY4asn!gk8sJS&GhfT zZR{(3wdfjMqu~^JhsR-Wq>863MRp*5!nn%IB-@*idRxG>r;Bz#w~Sy8M=b4We3i|f zafAWk>46NJsmAwj>x<5#t)`*gLnh`cMOc69g`%I0kSTh_c3M#LsXC3~Q{trPnFvJ?4=3uSXja_diACF_=H@!lI#2;=Rpf zAJ5gurH1qrV@y?v+SDVht->VT402<(?7$38L(kTv{wz9Vw8S=3rxxaCc1&P;JiaU>))WB`>;oETQv1VqH}Qcd2VTWxH7M>v7$4aD<12Ugy( zOf2Buf(6{`5=qz&qR68ec`;nJ?U5z%A8a^}U5&FBl}+(jX~)DKi^|%vjp#o76e8vp zx(>r$Ly0}g<{pxzyk5?VH^>yRv|bNcX)I1leq>Qnn|au#L$9Lk{NnqKyhA~7<-^PX z4h6yxvN*Y#dA``@-Fooi22cVq(vtZ=-&I^U?S_nlzL<46viRJOf^@v7n z>bs0+D94hbQ9hLMj{Z@PKtA~?WB1E|1^ZStMM1kjLEAIIfVKyVo2L$KG%=f^!#Z2R zD#$TlJ$LG`ay{8QnmOPW$bvmNGPvI9|27{-xSbYC0Kp@|=<4rpm`R{@i^Xg6R^Y|Kx|@ZU&FaYjpugH5oe z>WRLWw(UjX20x$*_Q9kmo0#i$rRRF{Qz4&R%)luhw;_}WE{jyjndSvzKwX~U>17#9 zms2SCzU%N5;6GErmE&TbVUV@arVihepXyvOU+k`P#Ro8)vM%>tWDIn~ne#C_SYBDi zXo1-SJ{$y>A|QLIPsWa>HkK><44;wqTARC&98$}L4AAuf{p>3BBHePe6Uk@1s{@KO z>Ij4?tgt=o?14B|qYFjrT@QeGk#6qI1&8EtT*6a>8SYr1uT#Q0RWhdpwy1WLnv9mv zGuNhf=6EN*FN1vZ^|dpe%tLBE>OhA~_>8CH(LYZP21C?nXdLTB26=WVlBY*$Z@ zC~}+FWyNT7X=6dZ(q=VHmO+c$-%W_J841Kn39wBx*3fh`rB2=2>c}BJy{u8!sMAsB zX}@o23;zi(!GLMU$8;PNTQGk}5?_^H3QyGrKOF2#kdNS;aX?%?2%hTy0b4*Veu42q z|Fw`kuG$5CtqxQze|{fDI*by= z{@NkSY>+Dn8sL)5vTBX@d#nv`Gm6?m@Mjw|?O8jDG>Qm#?&1YOpb};s8(9E6x$MO0 zMLo(+bSr)kQ?jJlC%fT8xxVvN7yC-+!}0k`Zx z>7CeG$rDw464lgJPS-Wi9~)R$&=pM0kK6gk3h^JVrRB|LpT?Q^u=15^;;MO3Zm zSBi^;WYZGq!m1cZyAU0A$VlJN9V2{?$K*JBT#NUaiLTZf?D^XfH`4Rqj>M6k@jDQ` zT^HvX{ITw3N+3CWxvL4i0o@`g1vm z`35>xfTzCL>965zB{o@-ehGGeKY~Xb4f~}0Wi5|nGwKpFm9SX^*%_yuSFFo}nh
      X|S4s9k~X|4WqWKh$cVJL6`bob-C;<3-0O%gqcFAc%bHCmfPdUFMs zKVcMBPBHu!bO(`|s-h$GvFrTL)c!@+;6u)*9caq!>)wfn_vZodh{2njPy7?%m5GQ? zY;w;1D;~M?mx9j4T;lw#qkPGW)V|OY*cbWot-8{GA!x^(8qyOE0wadm>J1K> zVpU?+yd@&XqK8OFgV3RGr5qf4=`|Nd6m?mH)+3s(XMeAkeA%*-&<~l$;>H%O{N01C zWryI9=#|mF6b9)8supFjKMAqeiUa^;!KDHXJo!@j=crRHNz0R$$gi;%TZp|eiG3#% zjwyyqu4@__W4L1z{K!=Dp-QG=e(wL0Adp_*^5&w3QXu%h;w>Zr1$jsnT%b|fo=#x4 zFSZf4V$t_v3F={r6o7AxU&dFfRI%lHF{zJY=`7}RoIV+g+o^2Xr$7WwxSqZ51oRq{ z)i3o8JDI4Vo95ZI>Lmo-)-6&vz*JpAW_jJVV(&dXa&?aewv+iBSN4RBOT8O5&X;i0 z-#PK(A|eprVQIZF?B>QI&ER#;r=|lH1ny>?#`}9VIG_GC-+cp0M|sEZz%2Z0XE~$q z)Y+0z-sByld>6rVPmUP{J3PWSE|FWP>1k#;<8mULJ(P2cmnc5R39K=ZBL?r9HVo=7 z8>_b%F8N1y0?!m|gfP^cQBSD1(sfbuTu&pfGGUiv`{<}6eHZOT`xpcMy_93XbgJeK zAmGOD3-YVH1|l|3gy9&EhHwQ3#X?lI<+%Pt0GbUe7@-Kzic}IR^i!Z?!#APoXzX@F z#|d+!XV%^w&Nzeo9^eIDNPm{IM^2pI3lpB}+3YXVe|ZxGcALk-Qk7zEif#UzK^sVd>9*EdtVz7(*R7*!6>7w`Z$%f}2Bp1CM;mVL$ewmoTTT2hf>Y+7kF!aJ@5$f)%0KvWT);mV&6B~(lK+4554OB|%KpJztT>zg z!C+vi6;1q){DXaOihpq1pZ=%*L6^xLNzCFOWCr|$r5K2H|3C~BOnia#v+ba0BRkdDm-WASN{JkFq*>(Ol*Wew_r(Z@>ZeKK9 z3FUC$Scdb7%jiGAaLzqL90_%T#qEoK)_p!##c;ZWUc^?K7P1dsM9*NqVK>lFe!~ty zNcS6R@|EAfY%N}nVXxK0p`m`mGO5XZ{^B=Oux`L_xLu!)Q3SN5L_)V~!F~f_=zfEL z8j7S<&Y){(^i$)BdH()azxWGRmZ~3^p7gv>6!dSwAq=U;Tw` ztWQU7V60a!u=vLCTaJN%!*6%-pZ~M*_Ym+6jK9t5MaJJ4H0}1aHU5sc4YqEnoMKiU zZ(#VN&U85bPKKS+$KM9D+0OX;^{s*Nm#Au2+!ZwbmY^-F7-57Wa4O?3VFt!uMZP}% zl72P*KBJmrINkp_-5H(y~UFm1n>SCs&WxUAv zU87Yz$?>}e=e@LR@QCsI^1U*CKlnVx@AC%ylJWca#EwRTpz-^FZT#l^u@Gr${&?n% zf$<>*t4-_xiSj!?IYoXKCnw=ox=sXaojgp!gikAa)fR>+8=6f2*jawta0(GUi2%SW z0$P177$*GH#(A;N6H}_EZcIkLFHfcnEMv^ywm6@7oFITp9QERS%!{&QIG`w9KkjhV zG+*l)gzZgw8<7nxn{J@D1ao4+bD8l_Z9L?2Uh2ab$Y1lKqdH227agrC)&Cjz!l8|Ta-BI)0Uf9`9)qPv zwBOXt?Tr|LoiHQ3uuae>6z04?Mp1aE#zNtQSJ6787@_@Gs3??jL9GW`B_L_Ft=5PR z3z5@=!rc&^IleaCMg%yx5us*uC9E1@tDkoE^DX-RtmxwS+39x`7fs;~qlBtK955T2 z&Y-@tJe7_0wX_V3GF&eC>`XR<@C{Ya=jdxC>*b{&3wo#bzy736(C#d&w206^pQchk zjK6SGXcvr}kr7R!h~NV%1|6 z_zC)AFM*u={}8;4_{oA~&BSl#LcuSl_;S~p@e?Lam^yXBco>&*)Ij~gan6c~xDCaC zw)-y$5lxfK{IZs=&WaoqaIKk8a?gXs)9#y&I>qs&B{36td zZ8f3lNXfc2uoHit0W=&4HrUouDWl6(oN3 zkPto;gdbXKAw1=;hE_d~G9-Mcjc~#UCj3 z{q&!&@}r8+4OY^8rKFhuRK%cw=xIOy&v61Py12J)IGC>?QK>49O44?0M}n@Z%&*6* zG9T~ZNolGcakzG+g*~s(T^3FK2I>M$9SlwFZ!L4kmfi1g6>%+cO7*B2Fa{CJYJr z%KdxbU5iY=_=h3Wo=|znG#xU%!CL0=KN&LpZlaQDdIvI{3#egadKCcaGW~kFiH7#$ zJ?+Z$^eRp#fL9i*SJPB=m<&G3Qd6owR4Azy_nn*d?L{TZkh7}u=gYbtD zub~qsv(*dRrzJ4FZ6-;GaTn6tT4GY-^#~=M9*1<{UjXaS@og|#vW#yjNPx;dG{qd> z5~K|4w=upQg~WWD67%w@eC12Us!P!KMMB$V&MHC8~)!(7&4JZ zkpK5B(nK2J{lCq~*2Ph+N(PDJEu<)M=>FdykYI@88L7$fZ7!aaC>W9in;(1I!sdwO zU^8q*gjP||ER8sFYT4UTV*RQksN zl48mzJPA{rnc=JoiWM{n~eO2CsaBs7$6kJTD@Az$oED9yQY zDtkF6I0D{r)iMho-)C=!rC@xn5t;?F$-`A~)>08vYQ_+>l_*1{zRIT51VP0$X3h5k zu3cJ!<#zV=GVX=Os^}Q zxXQ)QT8t;dy5EOqW!Aw(AU5`I04!t4Y0_|ITTu?z8d0#9J4XW(bb zLzw?%`&$u1Aj_=!e;W#j{_jS%=zl-|r>dmYzpF-~#lQPI5_B!6f44;H(>y$fCuJTQ zNQlqzn>Q^C>GBE~f?)&S2f0IMNF}0(JX>MoNHoGFL#RY9a-t-_iJ(})-hC==ox(wZ zF@vjRbkH}rplii2T*9@l92?!m)7M=S!>LEP^~qxqyz<|Afmx+1Ber?GA2`xpusR(S4LeQQa z3cFYD$C~KvqRlE#ZS=uKpJ%s=U5;R9U}a!=D%hD;=1*S;X1neWi`n&Dt#yaP%=3PG ze0%+AwbNVi>z80A!!!6+pmkB0WroLWJ9#!X9A*dKYY(#?f|-Gl!Mju8nRrvcY?3zl zbK%*myt*h2WLIoQ)9w^=v21TrIu5F)xi{}5Q{G(4tOEZu79o;GTT^t_2hjFV;RY6$% z8u5WiF;C&F9OT>L{ZH|e*ctGvBz~h6e!hue`FB70H##hSLps23Tv+^0rPtQ${Ck1; zE#D#h`}c&f_%*P5gfl6)Ut>-C{HuDB{Igq?Q|Y@6I(|!tU%bL^M0osuH4*rY3(LQj z)$QZgU+^=moq=Z?_)+x_=>v5`n*;R@9r2|^eB5?n>;hhVgxdD8no!yvt5sWpvHIG7 zW2_#ilW7^N6WXIvyV~=g>hNxzlw~BP@-rdjgL}g2$ZdB*2E)V1Kr30*jtI0D=Y>;{ zQ&C_|M{X67JMyU@cTsrc#;gJ7B*tK~p<3h0c93KLpZlNk?vRdNHPIWb(DU6LmUs7K z;*N_=Lrpx+KX!oMIKj`*TSJfAU>`NGS=ZkkZR&5cj(9y0U-XIa^^?28>o1|St-q?R zfd0PoPmqb_5*f)X`g`k&cBG)qnDa|jB%CqVQp192tE(Hc4J`W3(dQDbjkwgRwe>wN zr@A(71~4+%#6qF?9EX87UtN^AS+p6Y0!3vC z?Q?9@i>6qMavrJU62M?bAWhAr^hue|@lAOGHlL`ekK3b9g)n`TsS+k2oGOV4)UiyG zckG1+nViAN)ClD`<&r}%_~oXS-SVqXy|4qHQ!P+;cS29bXBMSl;~z>zFm}WVocvAgHT6Rq(q?B)vyeSWeF1Tj62zc32w9R`}%U>{b!Ucai8x~K2uuV}=c zsp_WN*$}Bm`~7wJiKNCC+g%5ru7l6i!K-&1eAU6fAmB4GJ_vlsOt=C3QGq+<%Qkh! z`Lk@G>`1=>eGe!IiN4re+7MqxH(ZI!_BW${LRU$j%fqW;u|JDEKz33Pr7*;Y9rOb zc}>W&Qxvl>+47cRgAb+zC@X|EW}k)-I7Oa_%=RztKH3skp2PX2827`|m{V3N@szWw z%+Xd(hKV0nZ)Vh(17u?ICrw7waH#|a{e#bbo01%uj!ix}OTfM;d&F{G=r{XulnSud zxfu^Tw>d0E8!^LUFG5@agBm(Cu%ll-kwNWMbrJ?us#qNdf>1Hk%w6rmGh(Y5kdM3i z+gR3bzAl2}c3hd9L;Eb1^BazG|ENC>3j{$pLM>*soSfnDKsm*R*c0L};7(J#-EXW) zi%GpuB^EpzgaE0-v!=CFt<}mehp%?RGQ+otpytQ@R&efJ5$KP=#XVqdQM1>qocItThET6YnG;6TUF>A*{*{Z_xp zY6kW18$`ezUjC&)^lu3Q21fthU26FFGnkMc=i~B!fsa^}(w2|2UpNsT|MtL1=$};V zVt4ggQ?bke?(j;T6;i2nYot<5h&7l>9a>^4m5UP{DDz4-izDz)+clTZ$+ z)WC_D|5yxFr@S&CyG67SL0MhJAf~Yu2Ubh9dIqbNf@&dBiru8YM6n;Q*P!FpYwJHw zRIkG`PoiGX$5Y(ZJ7Ii%@zlSnBWf}pgLz{uFB<5s{uQ1v^KJCA45>)=b-KN$&KoawHfs}dSO{XCw0X8l6s z(<4pfGan06+t~NVCx^>t#C4J6Gxp)2d^*)flFz_bjeKb7eq276zjZwMeD&;!Fmk&-&(Y4A{CWB7RlzBm>Uh-BbQ@tDPJe)G^ zmh~a@e`S55Kcf(=j>+-+B>K zj$%5?!L;EnRt)pc7+|ns-6Z}zBO*ra&sT@!HV_td?Sl`Cp zWB7~pzcB2)NwA8KXxP~?B1T^b#@i0bkd6AI>l$V%>64Pyp={^Tj^DiRRZ$V)s zZq{L7@AN2HH-}-H3v8|G7elP*)@5W{T|4vkKnub7W-DaGwD?*AX)|IPMnje;d~6;2 zx3Ah9X~ZOz+ycgPIl`6j&v{lY+oVWM#xtABri;Ukgp9AS8FG~%h;ikkwdCX3c&j4c zWlx=;#bEroz3k+gR z6CM|iipb+B{|1kfg$1p7EcM^MDH5Lp13+Q;(_K`)j8qVHsC>8A3hvE?5ph@U0&ciA zZ5@em5%CJTX=uh&r%Z!xe6Xf>E4GP|u`Q|twus~J?>0uNr8EA{;~X^*rbnpX(YK_2 z-}1b#w)%T>6r_D#r22UxVwC!wfi(&oePI3NMzUkHo>%aIr?yx>q
      z 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

      Z}U+=X+a= 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ⅅolC{h#!hODAU@7) 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 z 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%0AiiAugn`R+aM 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�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 c2^PVX{ZQw67 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

      #zL9;g(Q-4?%r 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 V$1| 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

      Q)0%Kk?)HCja(* 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

- +
+ {canStopDeployment(d) && ( + + )} + +
))} diff --git a/dash/src/components/deployments/deployment-monitor.tsx b/dash/src/components/deployments/deployment-monitor.tsx index 3f761fd..eae7164 100644 --- a/dash/src/components/deployments/deployment-monitor.tsx +++ b/dash/src/components/deployments/deployment-monitor.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Sheet, SheetContent, @@ -6,8 +6,10 @@ import { SheetTitle, } from '@/components/ui/sheet'; import { Badge } from '@/components/ui/badge'; -import { Terminal, CheckCircle2, XCircle, AlertCircle, Loader2 } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { Terminal, CheckCircle2, XCircle, AlertCircle, Loader2, Square } from 'lucide-react'; import { useDeploymentMonitor } from '@/hooks'; +import { deploymentsService } from '@/services'; import { LogLine } from '@/components/logs/log-line'; import { cn } from '@/lib/utils'; import { toast } from 'sonner'; @@ -23,6 +25,7 @@ export const DeploymentMonitor = ({ deploymentId, open, onClose, onComplete }: P const bottomRef = useRef(null); const completedRef = useRef(false); + const [stopping, setStopping] = useState(false); const { logs, status, error, isConnected, isLoading, isLive, reset } = useDeploymentMonitor({ deploymentId, @@ -52,6 +55,20 @@ export const DeploymentMonitor = ({ deploymentId, open, onClose, onComplete }: P onClose(); }; + const handleStop = async () => { + if (stopping) return; + try { + setStopping(true); + await deploymentsService.stopDeployment(deploymentId); + toast.success('Deployment stopped'); + } catch (err) { + console.error('Stop deployment error:', err); + toast.error(err instanceof Error ? err.message : 'Failed to stop deployment'); + } finally { + setStopping(false); + } + }; + const getStatusInfo = () => { const statusValue = status?.status || 'pending'; @@ -91,6 +108,11 @@ export const DeploymentMonitor = ({ deploymentId, open, onClose, onComplete }: P } }; + const canStop = () => { + const statusValue = status?.status || 'pending'; + return ['pending', 'building', 'deploying', 'cloning'].includes(statusValue); + }; + const statusInfo = getStatusInfo(); return ( @@ -127,6 +149,24 @@ export const DeploymentMonitor = ({ deploymentId, open, onClose, onComplete }: P #{deploymentId} + + {/* Stop Button */} + {canStop() && ( + + )} diff --git a/dash/src/services/deployments.service.ts b/dash/src/services/deployments.service.ts index 66c1608..426c494 100644 --- a/dash/src/services/deployments.service.ts +++ b/dash/src/services/deployments.service.ts @@ -68,4 +68,21 @@ export const deploymentsService = { const host = window.location.host; return `${protocol}//${host}${API_BASE}/deployments/logs/stream?id=${deploymentId}`; }, + + /** + * Stop a deployment + */ + async stopDeployment(deploymentId: number): Promise { + const response = await fetch(`${API_BASE}/deployments/stopDep`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + credentials: 'include', + body: JSON.stringify({ deploymentId }), + }); + + const data = await response.json(); + if (!response.ok) { + throw new Error(data.message || data.error || 'Failed to stop deployment'); + } + }, }; diff --git a/package.json b/package.json new file mode 100644 index 0000000..0f7714c --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": {}, + "devDependencies": { + "baseline-browser-mapping": "^2.9.15" + } +} \ No newline at end of file From 8568a09916512d0fd503c27c6c80ce553749d3e1 Mon Sep 17 00:00:00 2001 From: 07calc Date: Tue, 20 Jan 2026 20:03:12 +0530 Subject: [PATCH 42/48] fix: remove root bun.lock --- bun.lock | 14 -------------- package.json | 6 ------ 2 files changed, 20 deletions(-) delete mode 100644 bun.lock delete mode 100644 package.json diff --git a/bun.lock b/bun.lock deleted file mode 100644 index a03a348..0000000 --- a/bun.lock +++ /dev/null @@ -1,14 +0,0 @@ -{ - "lockfileVersion": 1, - "configVersion": 1, - "workspaces": { - "": { - "devDependencies": { - "baseline-browser-mapping": "^2.9.15", - }, - }, - }, - "packages": { - "baseline-browser-mapping": ["baseline-browser-mapping@2.9.15", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-kX8h7K2srmDyYnXRIppo4AH/wYgzWVCs+eKr3RusRSQ5PvRYoEFmR/I0PbdTjKFAoKqp5+kbxnNTFO9jOfSVJg=="], - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 0f7714c..0000000 --- a/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dependencies": {}, - "devDependencies": { - "baseline-browser-mapping": "^2.9.15" - } -} \ No newline at end of file From 9785aa307e834e80d31be44cd8f9193418d399d0 Mon Sep 17 00:00:00 2001 From: 07calc Date: Tue, 20 Jan 2026 21:38:55 +0530 Subject: [PATCH 43/48] fix: showing dep failed when stopped --- .../deployments/deployment-list.tsx | 53 +++++++++++++++---- .../deployments/deployment-monitor.tsx | 40 +++++++++++--- dash/src/hooks/use-deployment-monitor.ts | 15 +++++- .../handlers/deployments/getCompletedLogs.go | 2 +- .../handlers/deployments/stopDeployment.go | 33 +++++++++++- server/docker/deployer.go | 10 +++- server/docker/deployerMain.go | 5 +- server/git/clone.go | 3 ++ server/models/deployment.go | 4 ++ server/queue/handleWork.go | 12 +++++ 10 files changed, 154 insertions(+), 23 deletions(-) diff --git a/dash/src/components/deployments/deployment-list.tsx b/dash/src/components/deployments/deployment-list.tsx index a513d96..b44f58d 100644 --- a/dash/src/components/deployments/deployment-list.tsx +++ b/dash/src/components/deployments/deployment-list.tsx @@ -5,8 +5,9 @@ import { Button } from "@/components/ui/button" import { toast } from "sonner" import { DeploymentMonitor } from "@/components/deployments" import type { Deployment, App } from "@/types" -import { Loader2, Clock, CheckCircle2, XCircle, PlayCircle, AlertCircle, Square } from "lucide-react" +import { Loader2, Clock, CheckCircle2, XCircle, PlayCircle, AlertCircle, Square, SquareSlash } from "lucide-react" import { deploymentsService } from "@/services" +import { cn } from "@/lib/utils" export const DeploymentsTab = ({ appId, app }: { appId: number; app?: App }) => { const [deployments, setDeployments] = useState([]) @@ -79,14 +80,14 @@ export const DeploymentsTab = ({ appId, app }: { appId: number; app?: App }) => return () => clearInterval(interval) }, [appId]) - // Helper to get status icon and color + // Helper to get status badge with styles const getStatusBadge = (deployment: Deployment) => { const { status, stage } = deployment switch (status) { case 'success': return ( - + Success @@ -102,25 +103,47 @@ export const DeploymentsTab = ({ appId, app }: { appId: number; app?: App }) => case 'deploying': case 'cloning': return ( - + {stage.charAt(0).toUpperCase() + stage.slice(1)} ) case 'pending': return ( - + Pending ) + case 'stopped': + return ( + + + Stopped + + ) default: return {status} } } + // Check if deployment can be stopped const canStopDeployment = (deployment: Deployment) => { - return ['pending', 'building', 'deploying', 'cloning'].includes(deployment.status) + return ['pending', 'building', 'deploying', 'cloning'].includes(deployment.status) && deployment.status !== 'stopped' + } + + // Get border class based on status + const getDeploymentBorderClass = (status: string) => { + switch (status) { + case 'success': + return 'border-green-200 dark:border-green-800 bg-green-50/50 dark:bg-green-950/20' + case 'failed': + return 'border-red-200 dark:border-red-800 bg-red-50/50 dark:bg-red-950/20' + case 'stopped': + return 'border-slate-200 dark:border-slate-700 bg-slate-50/50 dark:bg-slate-900/20' + default: + return 'border-border bg-muted/20 hover:bg-muted/30' + } } return ( @@ -183,7 +206,10 @@ export const DeploymentsTab = ({ appId, app }: { appId: number; app?: App }) => {deployments.map((d) => (
@@ -194,7 +220,7 @@ export const DeploymentsTab = ({ appId, app }: { appId: number; app?: App }) => {/* Progress indicator for in-progress deployments */} - {d.status !== 'success' && d.status !== 'failed' && d.progress > 0 && ( + {d.status !== 'success' && d.status !== 'failed' && d.status !== 'stopped' && d.progress > 0 && (

)} - {d.error_message && ( + {/* Show error message for failed deployments */} + {d.error_message && d.status === 'failed' && (

{d.error_message}

)} + + {/* Show stopped message for stopped deployments */} + {d.status === 'stopped' && ( +

+ + Deployment was stopped by user +

+ )}
diff --git a/dash/src/components/deployments/deployment-monitor.tsx b/dash/src/components/deployments/deployment-monitor.tsx index eae7164..40fded0 100644 --- a/dash/src/components/deployments/deployment-monitor.tsx +++ b/dash/src/components/deployments/deployment-monitor.tsx @@ -7,7 +7,7 @@ import { } from '@/components/ui/sheet'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; -import { Terminal, CheckCircle2, XCircle, AlertCircle, Loader2, Square } from 'lucide-react'; +import { Terminal, CheckCircle2, XCircle, AlertCircle, Loader2, Square, CircleSlash, SquareSlash } from 'lucide-react'; import { useDeploymentMonitor } from '@/hooks'; import { deploymentsService } from '@/services'; import { LogLine } from '@/components/logs/log-line'; @@ -99,9 +99,15 @@ export const DeploymentMonitor = ({ deploymentId, open, onClose, onComplete }: P icon: , label: 'Pending', }; + case 'stopped': + return { + color: 'bg-slate-500 text-white', + icon: , + label: 'Stopped', + }; default: return { - color: 'bg-gray-500 text-white', + color: 'bg-slate-500 text-white', icon: null, label: statusValue, }; @@ -110,7 +116,12 @@ export const DeploymentMonitor = ({ deploymentId, open, onClose, onComplete }: P const canStop = () => { const statusValue = status?.status || 'pending'; - return ['pending', 'building', 'deploying', 'cloning'].includes(statusValue); + return ['pending', 'building', 'deploying', 'cloning'].includes(statusValue) && statusValue !== 'stopped'; + }; + + const isTerminalStatus = () => { + const statusValue = status?.status || ''; + return ['success', 'failed', 'stopped'].includes(statusValue); }; const statusInfo = getStatusInfo(); @@ -183,8 +194,8 @@ export const DeploymentMonitor = ({ deploymentId, open, onClose, onComplete }: P
- {/* Progress Bar */} - {status.status !== 'success' && status.status !== 'failed' && ( + {/* Progress Bar - Hide for terminal statuses */} + {!isTerminalStatus() && (
)} - {/* Error Banner - Only show for live deployments */} - {error && isLive && ( + {/* Stopped Banner */} + {status?.status === 'stopped' && ( +
+ + + Deployment Stopped + + {status.duration && ( + + Stopped at {status.progress}% after {status.duration}s + + )} +
+ )} + + {/* Error Banner - Only show for live deployments with failed status */} + {error && isLive && status?.status === 'failed' && (
diff --git a/dash/src/hooks/use-deployment-monitor.ts b/dash/src/hooks/use-deployment-monitor.ts index a74a2f6..78b687a 100644 --- a/dash/src/hooks/use-deployment-monitor.ts +++ b/dash/src/hooks/use-deployment-monitor.ts @@ -219,6 +219,8 @@ export const useDeploymentMonitor = ({ progress: deployment.progress, message: deployment.status === 'success' ? 'Deployment completed successfully' + : deployment.status === 'stopped' + ? 'Deployment was stopped by user' : 'Deployment failed', error_message: deployment.error_message, duration: deployment.duration, @@ -226,6 +228,8 @@ export const useDeploymentMonitor = ({ if (deployment.status === 'failed' && deployment.error_message) { setError(deployment.error_message); + } else if (deployment.status === 'stopped') { + setError('Deployment was stopped by user'); } setIsLoading(false); @@ -302,6 +306,13 @@ export const useDeploymentMonitor = ({ setError(statusData.error_message); onError?.(statusData.error_message); } + + // Handle stopped status + if (statusData.status === 'stopped' && !hasCompletedRef.current) { + console.log('[DeploymentMonitor] Deployment stopped by user'); + hasCompletedRef.current = true; + setError('Deployment was stopped by user'); + } break; } @@ -335,8 +346,8 @@ export const useDeploymentMonitor = ({ // Check the current status from state to decide on reconnection setStatus((currentStatus) => { - // Don't reconnect if deployment is complete - if (currentStatus?.status === 'success' || currentStatus?.status === 'failed') { + // Don't reconnect if deployment is complete (success, failed, or stopped) + if (currentStatus?.status === 'success' || currentStatus?.status === 'failed' || currentStatus?.status === 'stopped') { console.log('[DeploymentMonitor] Deployment complete, not reconnecting'); return currentStatus; } diff --git a/server/api/handlers/deployments/getCompletedLogs.go b/server/api/handlers/deployments/getCompletedLogs.go index e843acf..745965b 100644 --- a/server/api/handlers/deployments/getCompletedLogs.go +++ b/server/api/handlers/deployments/getCompletedLogs.go @@ -68,7 +68,7 @@ func GetCompletedDeploymentLogsHandler(w http.ResponseWriter, r *http.Request) { return } - if dep.Status != "success" && dep.Status != "failed" { + if dep.Status != "success" && dep.Status != "failed" && dep.Status != "stopped" { handlers.SendResponse(w, http.StatusBadRequest, false, nil, "deployment is still in progress, use WebSocket endpoint", "") return } diff --git a/server/api/handlers/deployments/stopDeployment.go b/server/api/handlers/deployments/stopDeployment.go index 61115f6..b9e9d66 100644 --- a/server/api/handlers/deployments/stopDeployment.go +++ b/server/api/handlers/deployments/stopDeployment.go @@ -3,10 +3,15 @@ package deployments import ( "encoding/json" "net/http" + "os" + "path/filepath" + "strconv" "github.com/corecollectives/mist/api/handlers" + "github.com/corecollectives/mist/constants" "github.com/corecollectives/mist/models" "github.com/corecollectives/mist/queue" + "github.com/rs/zerolog/log" ) type stopDeployment struct { @@ -26,19 +31,43 @@ func StopDeployment(w http.ResponseWriter, r *http.Request) { deployment, err := models.GetDeploymentByID(req.DeploymentID) if err != nil { + log.Error().Err(err).Int64("deployment_id", req.DeploymentID).Msg("Failed to get deployment details") handlers.SendResponse(w, http.StatusInternalServerError, false, nil, "Failed to get deployment details", err.Error()) return } - err = models.UpdateDeploymentStatus(req.DeploymentID, "stopped", "pending", deployment.Progress, deployment.ErrorMessage) + + logPath := filepath.Join(constants.Constants["LogPath"].(string), deployment.CommitHash+strconv.FormatInt(req.DeploymentID, 10)+"_build_logs") + + file, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { - handlers.SendResponse(w, http.StatusInternalServerError, false, nil, "Failed to stop deployment", err.Error()) + log.Error().Err(err).Int64("deployment_id", req.DeploymentID).Str("log_path", logPath).Msg("Failed to open log file") + handlers.SendResponse(w, http.StatusInternalServerError, false, nil, "Failed to open log file", err.Error()) + return + } + defer file.Close() + + logLine := "deployment was stopped by user\n" + _, err = file.WriteString(logLine) + if err != nil { + log.Error().Err(err).Int64("deployment_id", req.DeploymentID).Str("log_path", logPath).Msg("Failed to write to log file") + handlers.SendResponse(w, http.StatusInternalServerError, false, nil, "Failed to write to log file", err.Error()) return } + wasRunning := queue.Cancel(req.DeploymentID) message := "Deployment marked as stopped" if wasRunning { message = "Deployment aborted immediately" } + errorMsg := "deployment stopped by user" + err = models.UpdateDeploymentStatus(req.DeploymentID, "stopped", "stopped", deployment.Progress, &errorMsg) + if err != nil { + log.Error().Err(err).Int64("deployment_id", req.DeploymentID).Msg("Failed to update deployment status") + handlers.SendResponse(w, http.StatusInternalServerError, false, nil, "Failed to stop deployment", err.Error()) + return + } + + log.Info().Int64("deployment_id", req.DeploymentID).Bool("was_running", wasRunning).Msg("Deployment stopped successfully") handlers.SendResponse(w, http.StatusOK, true, nil, message, "") } diff --git a/server/docker/deployer.go b/server/docker/deployer.go index 06aaf51..d892c8d 100644 --- a/server/docker/deployer.go +++ b/server/docker/deployer.go @@ -150,8 +150,12 @@ func DeployApp(ctx context.Context, dep *models.Deployment, app *models.App, app models.UpdateDeploymentStatus(dep.ID, "deploying", "deploying", 80, nil) logger.Info("Stopping existing container if exists") - err = StopRemoveContainer( containerName, logfile) + err = StopRemoveContainer(containerName, logfile) if err != nil { + if ctx.Err() == context.Canceled { + logger.Info("Container stop/remove canceled") + return ctx.Err() + } logger.Error(err, "Failed to stop/remove existing container") dep.Status = "failed" dep.Stage = "failed" @@ -172,6 +176,10 @@ func DeployApp(ctx context.Context, dep *models.Deployment, app *models.App, app }) if err := RunContainer(ctx, app, imageTag, containerName, domains, port, envVars, logfile); err != nil { + if ctx.Err() == context.Canceled { + logger.Info("Container run canceled") + return ctx.Err() + } logger.Error(err, "Failed to run container") dep.Status = "failed" dep.Stage = "failed" diff --git a/server/docker/deployerMain.go b/server/docker/deployerMain.go index 7b89e37..2a854bb 100644 --- a/server/docker/deployerMain.go +++ b/server/docker/deployerMain.go @@ -47,6 +47,10 @@ func DeployerMain(ctx context.Context, Id int64, db *gorm.DB, logFile *os.File, err = DeployApp(ctx, dep, &app, appContextPath, imageTag, containerName, db, logFile, logger) if err != nil { + if ctx.Err() == context.Canceled { + logger.Info("Deployment cancelled by user") + return "", context.Canceled + } logger.Error(err, "DeployApp failed") dep.Status = "failed" dep.Stage = "failed" @@ -58,7 +62,6 @@ func DeployerMain(ctx context.Context, Id int64, db *gorm.DB, logFile *os.File, logger.Info("Deployment completed successfully") - // Run automatic cleanup if enabled in settings settings, err := models.GetSystemSettings() if err != nil { logger.Warn(fmt.Sprintf("Failed to get system settings for cleanup: %v", err)) diff --git a/server/git/clone.go b/server/git/clone.go index 6331113..1f9865f 100644 --- a/server/git/clone.go +++ b/server/git/clone.go @@ -22,6 +22,9 @@ func CloneRepo(ctx context.Context, url string, branch string, logFile *os.File, SingleBranch: true, }) if err != nil { + if ctx.Err() == context.Canceled { + return fmt.Errorf("deployment stopped by user") + } return err } diff --git a/server/models/deployment.go b/server/models/deployment.go index 1e2fe7d..242b06b 100644 --- a/server/models/deployment.go +++ b/server/models/deployment.go @@ -1,6 +1,7 @@ package models import ( + "fmt" "time" "github.com/corecollectives/mist/utils" @@ -178,6 +179,9 @@ func UpdateDeploymentStatus(depID int64, status, stage string, progress int, err updates["duration"] = &duration } } + if errorMsg != nil { + fmt.Println("updated dep status: ", *errorMsg) + } return db.Model(d).Updates(updates).Error } func MarkDeploymentStarted(depID int64) error { diff --git a/server/queue/handleWork.go b/server/queue/handleWork.go index b2f91d6..76ff2ab 100644 --- a/server/queue/handleWork.go +++ b/server/queue/handleWork.go @@ -87,6 +87,12 @@ func (q *Queue) HandleWork(id int64, db *gorm.DB) { err = github.CloneRepo(ctx, appId, logFile) if err != nil { + if ctx.Err() == context.Canceled { + logger.Info("Deployment cancelled by user") + errMsg := "deployment stopped by user" + models.UpdateDeploymentStatus(id, "stopped", "stopped", dep.Progress, &errMsg) + return + } logger.Error(err, "Failed to clone repository") errMsg := fmt.Sprintf("Failed to clone repository: %v", err) models.UpdateDeploymentStatus(id, "failed", "failed", 0, &errMsg) @@ -100,6 +106,12 @@ func (q *Queue) HandleWork(id int64, db *gorm.DB) { _, err = docker.DeployerMain(ctx, id, db, logFile, logger) if err != nil { + if ctx.Err() == context.Canceled { + logger.Info("Deployment cancelled by user") + errMsg := "deployment stopped by user" + models.UpdateDeploymentStatus(id, "stopped", "stopped", dep.Progress, &errMsg) + return + } logger.Error(err, "Deployment failed") errMsg := fmt.Sprintf("Deployment failed: %v", err) models.UpdateDeploymentStatus(id, "failed", "failed", 0, &errMsg) From 5c059bd7f34a2ba2f04d44f8836a2b0ed6ec4493 Mon Sep 17 00:00:00 2001 From: 07calc Date: Tue, 20 Jan 2026 21:41:46 +0530 Subject: [PATCH 44/48] fix: whitespace wildcard domain --- server/db/migrations.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/db/migrations.go b/server/db/migrations.go index 4201ff1..bea5f47 100644 --- a/server/db/migrations.go +++ b/server/db/migrations.go @@ -136,7 +136,7 @@ func migrateDbInternal(dbInstance *gorm.DB) error { var wildCardDomain = models.SystemSettingEntry{ Key: "wildcard_domain", - Value: " ", + Value: "", } var MistAppName = models.SystemSettingEntry{ Key: "mist_app_name", From 652a24e8600cba698588c0788a6ad0b0a616bfe3 Mon Sep 17 00:00:00 2001 From: 07calc Date: Tue, 20 Jan 2026 21:45:52 +0530 Subject: [PATCH 45/48] fix: new org name in install.sh --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 91a6b79..0827f5b 100755 --- a/install.sh +++ b/install.sh @@ -9,7 +9,7 @@ sudo rm -f "$LOG_FILE" 2>/dev/null || true REAL_USER="${SUDO_USER:-$USER}" REAL_HOME="$(getent passwd "$REAL_USER" | cut -d: -f6)" -REPO="https://github.com/corecollectives/mist" +REPO="https://github.com/trymist/mist" BRANCH="release" APP_NAME="mist" INSTALL_DIR="/opt/mist" From f27c9cd69fa208cc75efa0ff35b616a8f3c9a6a1 Mon Sep 17 00:00:00 2001 From: 07calc Date: Tue, 20 Jan 2026 21:50:21 +0530 Subject: [PATCH 46/48] fix: update env issue --- .../src/components/applications/environment-variables.tsx | 4 ++-- dash/src/hooks/use-environment-variables.ts | 5 +++-- server/api/handlers/applications/envs.go | 8 +++++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/dash/src/components/applications/environment-variables.tsx b/dash/src/components/applications/environment-variables.tsx index 9d55af0..9ec1870 100644 --- a/dash/src/components/applications/environment-variables.tsx +++ b/dash/src/components/applications/environment-variables.tsx @@ -334,7 +334,7 @@ export const EnvironmentVariables = ({ appId }: EnvironmentVariablesProps) => {

) : (
- {envVars.map((env) => ( + {envVars.map((env) => env ? (
{editingId === env.id ? (
@@ -394,7 +394,7 @@ export const EnvironmentVariables = ({ appId }: EnvironmentVariablesProps) => {
)}
- ))} + ) : null)}
)} diff --git a/dash/src/hooks/use-environment-variables.ts b/dash/src/hooks/use-environment-variables.ts index d0fda04..2f56f1a 100644 --- a/dash/src/hooks/use-environment-variables.ts +++ b/dash/src/hooks/use-environment-variables.ts @@ -30,8 +30,9 @@ export const useEnvironmentVariables = (options: UseEnvironmentVariablesOptions) try { setLoading(true); setError(null); - const data = await applicationsService.getEnvVariables(appId); - setEnvVars(data); + const data: Array = await applicationsService.getEnvVariables(appId); + // Filter out any null/undefined entries + setEnvVars(data.filter((env): env is EnvVariable => env != null)); } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to fetch environment variables'; setError(errorMessage); diff --git a/server/api/handlers/applications/envs.go b/server/api/handlers/applications/envs.go index 35ffb3b..c2d006d 100644 --- a/server/api/handlers/applications/envs.go +++ b/server/api/handlers/applications/envs.go @@ -142,12 +142,18 @@ func UpdateEnvVariable(w http.ResponseWriter, r *http.Request) { return } + updatedEnv, err := models.GetEnvVariableByID(req.ID) + if err != nil { + handlers.SendResponse(w, http.StatusInternalServerError, false, nil, "Failed to fetch updated environment variable", err.Error()) + return + } + models.LogUserAudit(userInfo.ID, "update", "env_variable", &req.ID, map[string]interface{}{ "app_id": env.AppID, "key": req.Key, }) - handlers.SendResponse(w, http.StatusOK, true, nil, "Environment variable updated successfully", "") + handlers.SendResponse(w, http.StatusOK, true, updatedEnv, "Environment variable updated successfully", "") } func DeleteEnvVariable(w http.ResponseWriter, r *http.Request) { From 6d9887ec36246208f6e5b2503c7a162e8efaae02 Mon Sep 17 00:00:00 2001 From: 07calc Date: Tue, 20 Jan 2026 21:53:25 +0530 Subject: [PATCH 47/48] fix: add audit logs for deployment stop --- .../api/handlers/deployments/stopDeployment.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/server/api/handlers/deployments/stopDeployment.go b/server/api/handlers/deployments/stopDeployment.go index b9e9d66..d310e47 100644 --- a/server/api/handlers/deployments/stopDeployment.go +++ b/server/api/handlers/deployments/stopDeployment.go @@ -8,6 +8,7 @@ import ( "strconv" "github.com/corecollectives/mist/api/handlers" + "github.com/corecollectives/mist/api/middleware" "github.com/corecollectives/mist/constants" "github.com/corecollectives/mist/models" "github.com/corecollectives/mist/queue" @@ -23,6 +24,13 @@ func StopDeployment(w http.ResponseWriter, r *http.Request) { handlers.SendResponse(w, http.StatusMethodNotAllowed, false, nil, "Method not allowed", "Only POST method is allowed") return } + + userInfo, ok := middleware.GetUser(r) + if !ok { + handlers.SendResponse(w, http.StatusUnauthorized, false, nil, "Not logged in", "Unauthorized") + return + } + var req stopDeployment if err := json.NewDecoder(r.Body).Decode(&req); err != nil { handlers.SendResponse(w, http.StatusBadRequest, false, nil, "Invalid request body", "Could not parse JSON") @@ -68,6 +76,12 @@ func StopDeployment(w http.ResponseWriter, r *http.Request) { return } - log.Info().Int64("deployment_id", req.DeploymentID).Bool("was_running", wasRunning).Msg("Deployment stopped successfully") + models.LogUserAudit(userInfo.ID, "stop", "deployment", &req.DeploymentID, map[string]interface{}{ + "app_id": deployment.AppID, + "commit_hash": deployment.CommitHash, + "was_running": wasRunning, + }) + + log.Info().Int64("deployment_id", req.DeploymentID).Int64("user_id", userInfo.ID).Bool("was_running", wasRunning).Msg("Deployment stopped successfully") handlers.SendResponse(w, http.StatusOK, true, nil, message, "") } From 89493915c94d348ed46402f73a254cd063313bb7 Mon Sep 17 00:00:00 2001 From: Tanish Date: Tue, 20 Jan 2026 21:55:38 +0530 Subject: [PATCH 48/48] v1.0.4 --- server/db/migrations.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/db/migrations.go b/server/db/migrations.go index bea5f47..89557aa 100644 --- a/server/db/migrations.go +++ b/server/db/migrations.go @@ -144,7 +144,7 @@ func migrateDbInternal(dbInstance *gorm.DB) error { } var Version = models.SystemSettingEntry{ Key: "version", - Value: "1.0.3", + Value: "1.0.4", } dbInstance.Clauses(clause.Insert{Modifier: "OR IGNORE"}).Create(&wildCardDomain)