diff --git a/.env.example b/.env.example index 7d0ad4e..92d251f 100644 --- a/.env.example +++ b/.env.example @@ -7,13 +7,3 @@ DB_NAME=mailserver # Security - JWT secret must be at least 32 characters JWT_SECRET=your-secret-key-at-least-32-chars - -# SMTP settings for password reset emails -SMTP_HOST=localhost -SMTP_PORT=587 -SMTP_USER= -SMTP_PASSWORD= -SMTP_FROM=noreply@yourdomain.com - -# Application URL -BASE_URL=http://localhost:8080 diff --git a/.gitignore b/.gitignore index e66c983..67e5508 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ build/ backend/cmd/server/embed/ backend/tmp/ .env -backend/imc-vibe +backend/imc node_modules/ frontend/node_modules/ frontend/build/ diff --git a/Makefile b/Makefile index 736b2ec..dcad2d6 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,22 @@ -.PHONY: all dev dev-frontend dev-backend build build-frontend build-backend clean test lint +.PHONY: all dev dev-frontend dev-backend build build-frontend build-backend clean test lint sqlc # Variables -APP_NAME := imc-vibe +APP_NAME := imc FRONTEND_DIR := frontend BACKEND_DIR := backend BUILD_DIR := build +GOBIN := $(shell go env GOPATH)/bin # Default target all: build +# Generate Go code from SQL queries using sqlc +# Requires: go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest +sqlc: + @echo "Generating Go code from SQL queries..." + cd $(BACKEND_DIR) && $(GOBIN)/sqlc generate + @echo "SQL code generated successfully" + # Build everything (frontend + backend + embed) build: build-frontend build-backend @@ -20,7 +28,7 @@ build-frontend: @echo "Frontend built successfully" # Build backend only (copies frontend build into embed directory) -build-backend: build-frontend +build-backend: sqlc build-frontend @echo "Copying frontend to embed directory..." rm -rf $(BACKEND_DIR)/cmd/server/embed cp -r $(FRONTEND_DIR)/build $(BACKEND_DIR)/cmd/server/embed @@ -30,8 +38,11 @@ build-backend: build-frontend @echo "Backend built successfully" # Development targets -dev: dev-frontend dev-backend - @echo "Development mode running..." +dev: + @echo "Starting backend dev server (hot-reload enabled)..." + cd $(BACKEND_DIR) && USE_EMBEDDED=false $(GOBIN)/air & + @echo "Starting frontend dev server..." + cd $(FRONTEND_DIR) && bun run dev dev-frontend: @echo "Starting frontend dev server..." @@ -39,7 +50,7 @@ dev-frontend: dev-backend: @echo "Starting backend dev server (hot-reload enabled)..." - cd $(BACKEND_DIR) && USE_EMBEDDED=false PATH=$(PATH):$$HOME/go/bin air + cd $(BACKEND_DIR) && USE_EMBEDDED=false $(GOBIN)/air # Clean build artifacts clean: @@ -65,10 +76,12 @@ help: @echo " all - Build frontend and backend (default)" @echo " build - Build frontend and backend" @echo " build-frontend - Build frontend only" - @echo " build-backend - Build backend only" + @echo " build-backend - Build backend only (runs sqlc first)" + @echo " sqlc - Generate Go code from SQL queries" @echo " dev - Start both frontend and backend with hot-reload" @echo " dev-frontend - Start frontend dev server" @echo " dev-backend - Start backend dev server (requires: go install github.com/air-verse/air@latest)" + @echo " sqlc - Generate Go code from SQL queries (requires: go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest)" @echo " clean - Remove build artifacts" @echo " test - Run backend tests" @echo " lint - Run Go vet" diff --git a/README.md b/README.md index e5b2c64..d720264 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# IMC Vibe +# IMC A self-sufficient web application to manage an ISPmail (Postfix, Dovecot, Rspamd) mail server. @@ -9,11 +9,11 @@ A self-sufficient web application to manage an ISPmail (Postfix, Dovecot, Rspamd - **Alias Management** - Create and manage email aliases per domain - **Mail Queue** - View, requeue, and delete queued emails - **Mail Logs** - View postfix logs with filtering -- **Password Reset** - SMTP-based password reset functionality +- **Password Management** - Change password for admin users ## Tech Stack -- **Backend**: Go with net/http (no framework), GORM for database +- **Backend**: Go with Gin framework, sqlc for type-safe SQL - **Frontend**: SvelteKit - **Database**: MariaDB/MySQL (shared with mail server ISPmail schema) - **Auth**: JWT-based authentication @@ -25,6 +25,38 @@ A self-sufficient web application to manage an ISPmail (Postfix, Dovecot, Rspamd - Permissions controlled via `imc_users2domains` table - Admin users have access to all domains; non-admin users only to assigned domains +## Directory Structure + +``` +imc-vibe/ +├── backend/ # Go backend +│ ├── cmd/server/ # Application entry point +│ │ ├── main.go # Main function, CLI flags, HTTP server setup +│ │ ├── frontend.go # Embedding the SvelteKit build +│ │ └── embed/ # Embedded frontend files (generated) +│ └── internal/ # Internal packages +│ ├── api/ # HTTP API routing and handlers +│ │ ├── router.go # Gin route definitions +│ │ └── handlers/ # HTTP handlers +│ ├── auth/ # JWT authentication +│ ├── config/ # Configuration loading +│ ├── db/ # Database access layer +│ │ ├── queries/ # SQL query files (sqlc source) +│ │ └── sqlc/ # Generated type-safe Go code +│ └── mail/ # Mail server integration (postqueue, logs, quota) +├── frontend/ # SvelteKit frontend +│ ├── src/ +│ │ ├── app.css # Global CSS (Tailwind + daisyUI) +│ │ ├── app.html # HTML template +│ │ ├── lib/ # Shared utilities +│ │ └── routes/ # SvelteKit routes (pages) +│ ├── vite.config.ts # Vite configuration +│ └── package.json # Frontend dependencies +├── build/ # Built binary output (gitignored) +├── Makefile # Build automation +└── .env # Environment configuration (gitignored) +``` + ## Quick Start ### 1. Build @@ -33,18 +65,18 @@ A self-sufficient web application to manage an ISPmail (Postfix, Dovecot, Rspamd make build ``` -### 2. Setup Admin User +### 2. Create Admin User ```bash -./build/imc-vibe --setup -# Or with custom credentials: -./build/imc-vibe --setup --admin-user=admin --admin-password=yourpassword +./build/imc --reset-admin-password +# This creates an admin user or resets the password +# Output: Username: admin, Password: (randomly generated) ``` ### 3. Run ```bash -./build/imc-vibe --bind=0.0.0.0 --port=8080 +./build/imc --bind=0.0.0.0 --port=8080 ``` ### 4. Access @@ -64,31 +96,21 @@ Open `http://your-server:8080` and login with the admin credentials. | `DB_NAME` | Database name | `mailserver` | | `BIND` | IP to bind to | `0.0.0.0` | | `PORT` | Port to listen on | `8080` | -| `JWT_SECRET` | JWT signing secret | (required) | -| `SMTP_HOST` | SMTP server for password reset | `localhost` | -| `SMTP_PORT` | SMTP port | `587` | -| `SMTP_USER` | SMTP username | | -| `SMTP_PASSWORD` | SMTP password | | -| `SMTP_FROM` | From address for emails | `noreply@localhost` | -| `BASE_URL` | Base URL for password reset links | `http://localhost:8080` | +| `JWT_SECRET` | JWT signing secret (min 32 chars) | (required) | ### CLI Flags ```bash -./imc-vibe --help +./imc --help ``` ``` - -admin-password string - Admin password for setup (required with --setup) - -admin-user string - Admin username for setup (default "admin") -bind string IP address to bind to (default: 0.0.0.0) -port string Port to listen on (default: 8080) - -setup - Create admin user and exit + -reset-admin-password + Reset admin password to a random value and exit ``` ## Database Tables @@ -98,17 +120,36 @@ The app creates these tables automatically: - `imc_users` - App admin users - `imc_login_attempts` - Brute force protection - `imc_users2domains` - User-domain permissions -- `imc_password_reset_tokens` - Password reset tokens Existing ISPmail tables (`virtual_domains`, `virtual_users`, `virtual_aliases`) are used for mail data. +### Database Access with sqlc + +The app uses [sqlc](https://sqlc.dev/) for type-safe database access: + +- SQL queries are defined in `backend/internal/db/queries/*.sql` +- Type-safe Go code is generated with `sqlc generate` into `backend/internal/db/sqlc/` +- **Do not edit files in `sqlc/`** - they are regenerated from queries + +To regenerate after changing queries: + +```bash +cd backend && sqlc generate +``` + +Enable SQL query logging in development: + +```bash +USE_EMBEDDED=false ./build/imc +``` + ## Systemd Service -Example service file at `/etc/systemd/system/imc-vibe.service`: +Example service file at `/etc/systemd/system/imc.service`: ```ini [Unit] -Description=IMC Vibe Mail Admin +Description=IMC Mail Admin After=network.target mariadb.service postfix.service [Service] @@ -122,7 +163,7 @@ Environment=DB_NAME=mailserver Environment=JWT_SECRET=your_secret Environment=BIND=0.0.0.0 Environment=PORT=8080 -ExecStart=/opt/imc-vibe/imc-vibe +ExecStart=/opt/imc/imc [Install] WantedBy=multi-user.target @@ -138,15 +179,48 @@ WantedBy=multi-user.target ## Development +### Tool Requirements + +- [air](https://github.com/air-verse/air) for Go hot-reload: `go install github.com/air-verse/air@latest` +- [sqlc](https://sqlc.dev/) for SQL code generation: `go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest` + +### Running Development Server + +Start both frontend and backend with hot-reload: + +```sh +make dev +``` + +This starts: +- **Frontend** on http://localhost:5173 (SvelteKit with HMR - frontend changes auto-reload) +- **Backend** on http://localhost:8080 (Go API with hot-reload) + +**During development, access the app at http://localhost:5173** - the Vite dev server proxies `/api` requests to the backend and enables instant frontend updates. + +### Running Servers Separately + +```sh +# Backend only (port 8080, serves frontend from frontend/build/) +make dev-backend + +# Frontend only (port 5173) +make dev-frontend +``` + +### Building + +Build the binary into the build/ directory: + ```bash -# Build frontend and backend make build +``` -# Run backend only (uses filesystem frontend) -cd backend && go run ./cmd/server +Build only frontend or backend: -# Run frontend dev server -cd frontend && bun run dev +```sh +make build-frontend +make build-backend ``` ## License diff --git a/backend/.air.toml b/backend/.air.toml index 4e66da4..ae922e9 100644 --- a/backend/.air.toml +++ b/backend/.air.toml @@ -2,8 +2,8 @@ # Install air: go install github.com/air-verse/air@latest [build] - bin = "./tmp/imc-vibe" - cmd = "go build -o ./tmp/imc-vibe ./cmd/server" + bin = "./tmp/imc" + cmd = "go build -o ./tmp/imc ./cmd/server" stop_on_error = true [log] diff --git a/backend/.env.example b/backend/.env.example deleted file mode 100644 index bd088e4..0000000 --- a/backend/.env.example +++ /dev/null @@ -1,20 +0,0 @@ -# Database -DB_HOST=localhost -DB_PORT=3306 -DB_USER=mailadmin -DB_PASSWORD=your-password -DB_NAME=mailserver - -# App -PORT=8080 -USE_EMBEDDED=true -JWT_SECRET=your-random-secret-at-least-32-chars -TRUSTED_PROXIES=127.0.0.1 - -# Mail server paths -MAIL_DATA_DIR=/var/vmail -POSTQUEUE_PATH=/usr/sbin/postqueue -POSTSUPER_PATH=/usr/sbin/postsuper -DOVECOT_QUOTA_CMD=/usr/bin/doveadm -JOURNALCTL_PATH=/usr/bin/journalctl -RSPMAD_API=http://127.0.0.1:11334 diff --git a/backend/cmd/server/frontend.go b/backend/cmd/server/frontend.go index 75f5c52..1574ece 100644 --- a/backend/cmd/server/frontend.go +++ b/backend/cmd/server/frontend.go @@ -4,16 +4,22 @@ import ( "embed" "io/fs" "net/http" + "os" ) //go:embed all:embed -//go:embed all:embed/_app var Files embed.FS -func FrontendFileSystem() http.FileSystem { - return http.FS(Files) +func FrontendFileSystem() (http.FileSystem, string) { + if os.Getenv("USE_EMBEDDED") == "false" { + return http.Dir("../frontend/build"), "" + } + return http.FS(Files), "embed/" } func FrontendFS() fs.FS { + if os.Getenv("USE_EMBEDDED") == "false" { + return os.DirFS("../frontend/build") + } return Files } diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index f04a0d0..de8272a 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -1,8 +1,9 @@ -// Package main is the entry point for the imc-vibe mail server admin application. +// Package main is the entry point for the IMC mail server admin application. // This single binary contains both the Go backend API and the embedded SvelteKit frontend. package main import ( + "context" // context for cancellation and timeouts "crypto/rand" // cryptographically secure random number generator "flag" // standard library for parsing command-line flags "fmt" // formatted I/O, used here for printing output @@ -11,11 +12,11 @@ import ( "os" // OS-level operations like reading command-line args "strings" // string manipulation utilities - "github.com/gin-gonic/gin" // web framework - "github.com/imc-vibe/backend/internal/api" // HTTP API routing and handlers - "github.com/imc-vibe/backend/internal/auth" // password hashing - "github.com/imc-vibe/backend/internal/config" // configuration loading - "github.com/imc-vibe/backend/internal/db" // database connection and operations + "git.workaround.org/chaas/imc/backend/internal/api" // HTTP API routing and handlers + "git.workaround.org/chaas/imc/backend/internal/auth" // password hashing + "git.workaround.org/chaas/imc/backend/internal/config" // configuration loading + "git.workaround.org/chaas/imc/backend/internal/db" // database connection and operations + "github.com/gin-gonic/gin" // web framework ) // main is the entry point of the application. @@ -24,7 +25,7 @@ import ( func main() { // Parse command-line flags. // Flags are optional arguments passed after the program name. - // Example: ./imc-vibe --bind=0.0.0.0 --port=8080 + // Example: ./imc --bind=0.0.0.0 --port=8080 // --bind: The IP address the server should listen on. // 0.0.0.0 means listen on all network interfaces (accessible from other machines). @@ -69,14 +70,14 @@ func main() { // Connect to the database (MariaDB/MySQL). // The database stores both ISPmail data (virtual_users, virtual_domains, etc.) - // and imc-vibe's own data (imc_users, imc_users2domains, etc.). + // and IMC's own data (imc_users, imc_users2domains, etc.). database, err := db.Connect(cfg) if err != nil { log.Fatalf("Failed to connect to database: %v", err) // Fatal = print and exit } // Create database tables if they don't exist. - // This only creates imc-vibe's own tables, not the ISPmail tables. + // This only creates IMC's own tables, not the ISPmail tables. if err := database.InitSchema(); err != nil { log.Printf("Warning: Could not initialize schema: %v", err) // Non-fatal = continue } @@ -89,7 +90,23 @@ func main() { if err != nil { log.Fatalf("Failed to hash password: %v", err) } - if err := database.UpsertAdminUser("admin", hash); err != nil { + + ctx := context.Background() + + // Get or create a default domain for the admin user. + domains, err := database.GetAllDomains(ctx) + if err != nil || len(domains) == 0 { + // Create a default domain if none exist. + err := database.CreateDomain(ctx, "localhost") + if err != nil { + log.Fatalf("Failed to create default domain: %v", err) + } + domains, err = database.GetAllDomains(ctx) + if err != nil || len(domains) == 0 { + log.Fatalf("Failed to get domain: %v", err) + } + } + if err := database.UpsertAdminUser(ctx, "admin", hash, domains[0].ID); err != nil { log.Fatalf("Failed to reset admin password: %v", err) } fmt.Printf("Admin password reset successfully.\n") @@ -103,14 +120,20 @@ func main() { // Get the embedded filesystem containing the frontend. // The frontend is compiled into the binary during build time. - frontendFS := FrontendFileSystem() + frontendFS, frontendPrefix := FrontendFileSystem() - // Set Gin to release mode for production. - // This disables debug logging and other development features. - gin.SetMode(gin.ReleaseMode) + // Set Gin mode based on environment. + // USE_EMBEDDED=false means development mode (e.g., via air hot-reloader). + // Release mode disables debug logging and other development features. + if os.Getenv("USE_EMBEDDED") == "false" { + gin.SetMode(gin.DebugMode) + } else { + gin.SetMode(gin.ReleaseMode) + } // Create a new Gin engine (router). engine := gin.New() + engine.Use(gin.Logger()) // Log HTTP requests (shows method, path, status, latency) engine.Use(gin.Recovery()) // Register API routes from the router. @@ -120,31 +143,31 @@ func main() { // Set up SPA fallback for non-API routes. // This must be the last route to catch all unmatched paths. engine.NoRoute(func(c *gin.Context) { - path := c.Request.URL.Path + reqPath := c.Request.URL.Path // If it's an API path, return 404. // The API router should have handled /api/* routes. - if strings.HasPrefix(path, "/api/") { + if strings.HasPrefix(reqPath, "/api/") { c.JSON(http.StatusNotFound, gin.H{"error": "not found"}) return } // Serve SvelteKit hashed assets at /_app/* - if strings.HasPrefix(path, "/_app/") { - assetPath := "embed/_app/" + strings.TrimPrefix(path, "/_app/") - serveGinStaticFile(c, frontendFS, assetPath) + if strings.HasPrefix(reqPath, "/_app/") { + filePath := frontendPrefix + "_app/" + strings.TrimPrefix(reqPath, "/_app/") + serveGinStaticFile(c, frontendFS, filePath) return } // Serve favicon - if path == "/favicon.png" { - serveGinStaticFile(c, frontendFS, "embed/favicon.png") + if reqPath == "/favicon.png" { + serveGinStaticFile(c, frontendFS, frontendPrefix+"favicon.png") return } // For all other paths, serve the SPA index.html. // This allows client-side routing (e.g., /domains/example.org). - serveGinStaticFile(c, frontendFS, "embed/index.html") + serveGinStaticFile(c, frontendFS, frontendPrefix+"index.html") }) // Build the address string for binding: "IP:PORT" diff --git a/backend/go.mod b/backend/go.mod index 4c2ea4d..26ca250 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,14 +1,13 @@ -module github.com/imc-vibe/backend +module git.workaround.org/chaas/imc/backend go 1.25.0 require ( github.com/gin-gonic/gin v1.10.0 + github.com/go-sql-driver/mysql v1.9.3 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/joho/godotenv v1.5.1 golang.org/x/crypto v0.49.0 - gorm.io/driver/mysql v1.6.0 - gorm.io/gorm v1.31.1 ) require ( @@ -22,10 +21,7 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect - github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/goccy/go-json v0.10.2 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/leodido/go-urn v1.4.0 // indirect diff --git a/backend/go.sum b/backend/go.sum index ed4dee7..6664ccb 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -34,10 +34,6 @@ github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArs github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -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/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -97,9 +93,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 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/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg= -gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo= -gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg= -gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/backend/internal/api/handlers/aliases.go b/backend/internal/api/handlers/aliases.go index 879dfa6..93028ff 100644 --- a/backend/internal/api/handlers/aliases.go +++ b/backend/internal/api/handlers/aliases.go @@ -3,9 +3,10 @@ package handlers import ( "net/http" "strconv" + "strings" + "git.workaround.org/chaas/imc/backend/internal/db" "github.com/gin-gonic/gin" - "github.com/imc-vibe/backend/internal/db" ) type AliasHandler struct { @@ -34,19 +35,19 @@ func (h *AliasHandler) List(c *gin.Context) { return } - canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin()) + canAccess, _ := h.db.CanAccessDomain(c.Request.Context(), uint32(authCtx.UserID), domainName, authCtx.IsAdmin()) if !canAccess { Error(c, http.StatusForbidden, "access denied") return } - domain, err := h.db.GetDomainByName(domainName) + domain, err := h.db.GetDomainByName(c.Request.Context(), domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return } - aliases, err := h.db.GetAliasesByDomain(domain.ID) + aliases, err := h.db.GetAliasesByDomain(c.Request.Context(), domain.ID) if err != nil { Error(c, http.StatusInternalServerError, "database error") return @@ -68,13 +69,13 @@ func (h *AliasHandler) Create(c *gin.Context) { return } - canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin()) + canAccess, _ := h.db.CanAccessDomain(c.Request.Context(), uint32(authCtx.UserID), domainName, authCtx.IsAdmin()) if !canAccess { Error(c, http.StatusForbidden, "access denied") return } - domain, err := h.db.GetDomainByName(domainName) + domain, err := h.db.GetDomainByName(c.Request.Context(), domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return @@ -86,13 +87,52 @@ func (h *AliasHandler) Create(c *gin.Context) { return } - alias, err := h.db.CreateAliasInDomain(req.Source, req.Destination, domain.ID) + // Validate source email format + if err := validateEmailLocalPart(req.Source); err != nil { + Error(c, http.StatusBadRequest, "source "+err.Error()) + return + } + + // Ensure source is in the correct domain + if !strings.HasSuffix(req.Source, "@"+domainName) { + Error(c, http.StatusBadRequest, "source must be in domain "+domainName) + return + } + + // Validate destination - can be single email or comma-separated list + destinations := strings.Split(req.Destination, ",") + for _, dest := range destinations { + dest = strings.TrimSpace(dest) + if dest == "" { + Error(c, http.StatusBadRequest, "destination cannot be empty") + return + } + // Destination doesn't need @domain validation since it can be external + if strings.Contains(dest, "@") { + if err := validateEmailLocalPart(dest); err != nil { + Error(c, http.StatusBadRequest, "destination "+err.Error()) + return + } + } + } + + // Check for duplicate alias + _, err = h.db.GetAliasBySource(c.Request.Context(), req.Source) + if err == nil { + Error(c, http.StatusConflict, "alias already exists") + return + } + if err != nil && !strings.Contains(err.Error(), "sql: no rows") { + // Only error if it's not "no rows" error + } + + err = h.db.CreateAlias(c.Request.Context(), domain.ID, req.Source, req.Destination) if err != nil { Error(c, http.StatusInternalServerError, "failed to create alias") return } - Created(c, alias) + Created(c, map[string]string{"message": "alias created"}) } func (h *AliasHandler) Delete(c *gin.Context) { @@ -110,7 +150,7 @@ func (h *AliasHandler) Delete(c *gin.Context) { return } - canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin()) + canAccess, _ := h.db.CanAccessDomain(c.Request.Context(), uint32(authCtx.UserID), domainName, authCtx.IsAdmin()) if !canAccess { Error(c, http.StatusForbidden, "access denied") return @@ -122,7 +162,8 @@ func (h *AliasHandler) Delete(c *gin.Context) { return } - if err := h.db.DeleteAlias(uint(id)); err != nil { + err = h.db.DeleteAlias(c.Request.Context(), uint32(id)) + if err != nil { Error(c, http.StatusInternalServerError, "failed to delete alias") return } diff --git a/backend/internal/api/handlers/auth.go b/backend/internal/api/handlers/auth.go index 5dab840..cf8daef 100644 --- a/backend/internal/api/handlers/auth.go +++ b/backend/internal/api/handlers/auth.go @@ -1,15 +1,12 @@ package handlers import ( - "log" "net/http" - "strings" "time" + "git.workaround.org/chaas/imc/backend/internal/auth" + "git.workaround.org/chaas/imc/backend/internal/db" "github.com/gin-gonic/gin" - "github.com/imc-vibe/backend/internal/auth" - "github.com/imc-vibe/backend/internal/db" - "github.com/imc-vibe/backend/internal/mail" ) const MaxLoginAttempts = 5 @@ -17,15 +14,13 @@ const MaxLoginAttempts = 5 type AuthHandler struct { db *db.DB jwtManager *auth.JWTManager - emailService *mail.EmailService trustedProxies []string } -func NewAuthHandler(database *db.DB, jwtManager *auth.JWTManager, emailService *mail.EmailService, trustedProxies []string) *AuthHandler { +func NewAuthHandler(database *db.DB, jwtManager *auth.JWTManager, trustedProxies []string) *AuthHandler { return &AuthHandler{ db: database, jwtManager: jwtManager, - emailService: emailService, trustedProxies: trustedProxies, } } @@ -40,15 +35,10 @@ type ChangePasswordRequest struct { NewPassword string `json:"newPassword" binding:"required,min=8"` } -type ForgotPasswordRequest struct { - Identifier string `json:"identifier" binding:"required"` -} - type UserResponse struct { - ID uint `json:"id"` - Username string `json:"username"` - Role string `json:"role"` - Domains []string `json:"domains"` + ID uint `json:"id"` + Username string `json:"username"` + Role string `json:"role"` } func (h *AuthHandler) Login(c *gin.Context) { @@ -58,32 +48,13 @@ func (h *AuthHandler) Login(c *gin.Context) { return } - h.cleanupOldAttempts() - - ip := h.getClientIP(c) - - if isLockedOut(ip, req.Username, h.db) { - Error(c, http.StatusTooManyRequests, "too many failed attempts, try again later") - return - } - - user, err := h.db.GetImcUserByUsername(req.Username) - if err != nil || user == nil || !auth.CheckPassword(req.Password, user.PasswordHash) { - recordFailedAttempt(req.Username, ip, h.db) + user, err := h.db.GetImcUserByUsername(c.Request.Context(), req.Username) + if err != nil || !auth.CheckPassword(req.Password, user.PasswordHash) { Error(c, http.StatusUnauthorized, "invalid credentials") return } - clearFailedAttempts(req.Username, ip, h.db) - - domains, _ := h.db.GetUserAccessibleDomains(user.ID, user.Role == "admin") - - domainNames := make([]string, len(domains)) - for i, d := range domains { - domainNames[i] = d.Name - } - - token, err := h.jwtManager.GenerateToken(user.ID, user.Username, user.Role, 24*time.Hour) + token, err := h.jwtManager.GenerateToken(uint(user.ID), user.Username, string(user.Role.ImcUsersRole), 24*time.Hour) if err != nil { Error(c, http.StatusInternalServerError, "failed to generate token") return @@ -92,10 +63,9 @@ func (h *AuthHandler) Login(c *gin.Context) { Success(c, map[string]interface{}{ "token": token, "user": UserResponse{ - ID: user.ID, + ID: uint(user.ID), Username: user.Username, - Role: user.Role, - Domains: domainNames, + Role: string(user.Role.ImcUsersRole), }, }) } @@ -107,65 +77,16 @@ func (h *AuthHandler) Me(c *gin.Context) { return } - user, err := h.db.GetImcUserByID(authCtx.UserID) + user, err := h.db.GetImcUserByID(c.Request.Context(), uint32(authCtx.UserID)) if err != nil || user == nil { Error(c, http.StatusNotFound, "user not found") return } - domains, _ := h.db.GetUserAccessibleDomains(user.ID, user.Role == "admin") - - domainNames := make([]string, len(domains)) - for i, d := range domains { - domainNames[i] = d.Name - } - Success(c, UserResponse{ - ID: user.ID, + ID: uint(user.ID), Username: user.Username, - Role: user.Role, - Domains: domainNames, - }) -} - -func (h *AuthHandler) ForgotPassword(c *gin.Context) { - var req ForgotPasswordRequest - if err := c.ShouldBindJSON(&req); err != nil { - Error(c, http.StatusBadRequest, "invalid request") - return - } - - req.Identifier = strings.TrimSpace(strings.ToLower(req.Identifier)) - if req.Identifier == "" { - Error(c, http.StatusBadRequest, "identifier required") - return - } - - user, err := h.db.GetImcUserByUsername(req.Identifier) - if err != nil { - Success(c, map[string]string{ - "message": "If the account exists, a password reset link will be sent", - }) - return - } - - token := mail.GenerateToken() - expiresAt := time.Now().Add(1 * time.Hour) - - if err := h.db.CreatePasswordResetToken(user.ID, token, expiresAt); err != nil { - log.Printf("Failed to create password reset token: %v", err) - Error(c, http.StatusInternalServerError, "failed to create reset token") - return - } - - if err := h.emailService.SendPasswordReset(user.Username, token); err != nil { - log.Printf("Failed to send password reset email: %v", err) - Error(c, http.StatusInternalServerError, "failed to send email") - return - } - - Success(c, map[string]string{ - "message": "If the account exists, a password reset link will be sent", + Role: string(user.Role.ImcUsersRole), }) } @@ -178,11 +99,11 @@ func (h *AuthHandler) ChangePassword(c *gin.Context) { var req ChangePasswordRequest if err := c.ShouldBindJSON(&req); err != nil { - Error(c, http.StatusBadRequest, "invalid request") + Error(c, http.StatusBadRequest, "invalid request body") return } - user, err := h.db.GetImcUserByID(authCtx.UserID) + user, err := h.db.GetImcUserByID(c.Request.Context(), uint32(authCtx.UserID)) if err != nil || user == nil { Error(c, http.StatusNotFound, "user not found") return @@ -199,7 +120,7 @@ func (h *AuthHandler) ChangePassword(c *gin.Context) { return } - err = h.db.UpdateImcUserPassword(user.ID, newHash) + err = h.db.UpdateImcUserPassword(c.Request.Context(), user.ID, newHash) if err != nil { Error(c, http.StatusInternalServerError, "failed to update password") return @@ -212,57 +133,6 @@ func (h *AuthHandler) Logout(c *gin.Context) { Success(c, map[string]string{"message": "logged out"}) } -func isLockedOut(ip, identifier string, database *db.DB) bool { - var count int64 - cutoff := time.Now().Add(-15 * time.Minute) - - database.Model(&db.ImcLoginAttempt{}). - Where("ip_address = ? AND attempted_at > ? AND successful = false", ip, cutoff). - Count(&count) - - if count >= MaxLoginAttempts { - return true - } - - database.Model(&db.ImcLoginAttempt{}). - Where("email = ? AND attempted_at > ? AND successful = false", identifier, cutoff). - Count(&count) - - return count >= MaxLoginAttempts -} - -func recordFailedAttempt(identifier, ip string, database *db.DB) { - database.Create(&db.ImcLoginAttempt{ - Email: identifier, - IPAddress: ip, - Successful: false, - }) -} - -func clearFailedAttempts(identifier, ip string, database *db.DB) { - database.Model(&db.ImcLoginAttempt{}). - Where("email = ? OR ip_address = ?", identifier, ip). - Update("successful", true) -} - -func (h *AuthHandler) cleanupOldAttempts() { - cutoff := time.Now().Add(-24 * time.Hour) - h.db.Where("attempted_at < ? AND successful = false", cutoff).Delete(&db.ImcLoginAttempt{}) -} - func (h *AuthHandler) getClientIP(c *gin.Context) string { - remoteIP := c.ClientIP() - - if len(h.trustedProxies) > 0 { - for _, proxy := range h.trustedProxies { - if remoteIP == proxy { - forwarded := c.GetHeader("X-Forwarded-For") - if forwarded != "" { - return strings.Split(forwarded, ",")[0] - } - } - } - } - - return remoteIP + return c.ClientIP() } diff --git a/backend/internal/api/handlers/domains.go b/backend/internal/api/handlers/domains.go index 40ea8d7..43323cc 100644 --- a/backend/internal/api/handlers/domains.go +++ b/backend/internal/api/handlers/domains.go @@ -6,8 +6,8 @@ import ( "strconv" "strings" + "git.workaround.org/chaas/imc/backend/internal/db" "github.com/gin-gonic/gin" - "github.com/imc-vibe/backend/internal/db" ) type DomainHandler struct { @@ -22,13 +22,6 @@ type CreateDomainRequest struct { Name string `json:"name" binding:"required"` } -type DomainPermissions struct { - DomainID uint `json:"domainId"` - DomainName string `json:"domainName"` - UserID uint `json:"userId"` - CanManage bool `json:"canManage"` -} - func (h *DomainHandler) List(c *gin.Context) { authCtx := GetAuthContext(c) if authCtx == nil { @@ -37,7 +30,19 @@ func (h *DomainHandler) List(c *gin.Context) { } isAdmin := authCtx.IsAdmin() - domains, err := h.db.GetUserAccessibleDomains(authCtx.UserID, isAdmin) + ctx := c.Request.Context() + + if isAdmin { + domainStats, err := h.db.GetAllDomainsWithCounts(ctx) + if err != nil { + Error(c, http.StatusInternalServerError, "database error") + return + } + Success(c, domainStats) + return + } + + domains, err := h.db.GetUserAccessibleDomains(ctx, uint32(authCtx.UserID), isAdmin) if err != nil { Error(c, http.StatusInternalServerError, "database error") return @@ -45,9 +50,8 @@ func (h *DomainHandler) List(c *gin.Context) { domainStats := make([]db.DomainStats, len(domains)) for i, d := range domains { - var userCount, aliasCount int64 - h.db.Model(&db.User{}).Where("domain_id = ?", d.ID).Count(&userCount) - h.db.Model(&db.Alias{}).Where("domain_id = ?", d.ID).Count(&aliasCount) + userCount, _ := h.db.CountUsersByDomain(ctx, d.ID) + aliasCount, _ := h.db.CountAliasesByDomain(ctx, d.ID) domainStats[i] = db.DomainStats{ ID: d.ID, Name: d.Name, @@ -66,7 +70,8 @@ func (h *DomainHandler) Get(c *gin.Context) { return } - domain, err := h.db.GetDomainByName(domainName) + ctx := c.Request.Context() + domain, err := h.db.GetDomainByName(ctx, domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return @@ -78,7 +83,7 @@ func (h *DomainHandler) Get(c *gin.Context) { return } - canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin()) + canAccess, _ := h.db.CanAccessDomain(ctx, uint32(authCtx.UserID), domainName, authCtx.IsAdmin()) if !canAccess { Error(c, http.StatusForbidden, "access denied") return @@ -106,19 +111,20 @@ func (h *DomainHandler) Create(c *gin.Context) { return } - existing, err := h.db.GetDomainByName(name) - if err == nil && existing != nil { + ctx := c.Request.Context() + _, err := h.db.GetDomainByName(ctx, name) + if err == nil { Error(c, http.StatusConflict, "domain already exists") return } - domain, err := h.db.CreateDomain(name) + err = h.db.CreateDomain(ctx, name) if err != nil { Error(c, http.StatusInternalServerError, "failed to create domain") return } - Created(c, domain) + Created(c, map[string]string{"message": "domain created"}) } func validateDomainName(name string) error { @@ -174,13 +180,15 @@ func (h *DomainHandler) Delete(c *gin.Context) { return } - domain, err := h.db.GetDomainByName(domainName) + ctx := c.Request.Context() + domain, err := h.db.GetDomainByName(ctx, domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return } - if err := h.db.DeleteDomain(domain.ID); err != nil { + err = h.db.DeleteDomain(ctx, domain.ID) + if err != nil { Error(c, http.StatusInternalServerError, "failed to delete domain") return } @@ -188,14 +196,16 @@ func (h *DomainHandler) Delete(c *gin.Context) { NoContent(c) } +type DomainPermissions struct { + DomainID uint32 `json:"domainId"` + DomainName string `json:"domainName"` + UserID uint32 `json:"userId"` + CanManage bool `json:"canManage"` +} + func (h *DomainHandler) GetPermissions(c *gin.Context) { authCtx := GetAuthContext(c) - if authCtx == nil { - Error(c, http.StatusUnauthorized, "authentication required") - return - } - - if !authCtx.IsAdmin() { + if authCtx == nil || !authCtx.IsAdmin() { Error(c, http.StatusForbidden, "admin access required") return } @@ -206,13 +216,14 @@ func (h *DomainHandler) GetPermissions(c *gin.Context) { return } - domain, err := h.db.GetDomainByName(domainName) + ctx := c.Request.Context() + domain, err := h.db.GetDomainByName(ctx, domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return } - users, err := h.db.GetUsersForDomain(domain.ID) + users, err := h.db.GetUsersForDomain(ctx, domain.ID) if err != nil { Error(c, http.StatusInternalServerError, "database error") return @@ -244,21 +255,23 @@ func (h *DomainHandler) AddPermission(c *gin.Context) { return } - domain, err := h.db.GetDomainByName(domainName) + ctx := c.Request.Context() + domain, err := h.db.GetDomainByName(ctx, domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return } var req struct { - UserID uint `json:"userId" binding:"required"` + UserID uint32 `json:"userId" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { Error(c, http.StatusBadRequest, "invalid request") return } - if err := h.db.AddUserToDomain(req.UserID, domain.ID); err != nil { + err = h.db.AddUserToDomain(ctx, req.UserID, domain.ID) + if err != nil { Error(c, http.StatusInternalServerError, "failed to add user to domain") return } @@ -279,7 +292,8 @@ func (h *DomainHandler) RemovePermission(c *gin.Context) { return } - domain, err := h.db.GetDomainByName(domainName) + ctx := c.Request.Context() + domain, err := h.db.GetDomainByName(ctx, domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return @@ -292,7 +306,8 @@ func (h *DomainHandler) RemovePermission(c *gin.Context) { return } - if err := h.db.RemoveUserFromDomain(uint(userID), domain.ID); err != nil { + err = h.db.RemoveUserFromDomain(ctx, uint32(userID), domain.ID) + if err != nil { Error(c, http.StatusInternalServerError, "failed to remove user from domain") return } diff --git a/backend/internal/api/handlers/logs.go b/backend/internal/api/handlers/logs.go index e4b2001..410ea83 100644 --- a/backend/internal/api/handlers/logs.go +++ b/backend/internal/api/handlers/logs.go @@ -4,8 +4,8 @@ import ( "net/http" "strconv" + "git.workaround.org/chaas/imc/backend/internal/mail" "github.com/gin-gonic/gin" - "github.com/imc-vibe/backend/internal/mail" ) type LogsHandler struct{} diff --git a/backend/internal/api/handlers/middleware.go b/backend/internal/api/handlers/middleware.go index 850804f..93ece02 100644 --- a/backend/internal/api/handlers/middleware.go +++ b/backend/internal/api/handlers/middleware.go @@ -5,8 +5,8 @@ import ( "net/http" "strings" + "git.workaround.org/chaas/imc/backend/internal/auth" "github.com/gin-gonic/gin" - "github.com/imc-vibe/backend/internal/auth" ) // AuthContextKey is the key used to store auth context in gin.Context. diff --git a/backend/internal/api/handlers/queue.go b/backend/internal/api/handlers/queue.go index 1392e80..e214921 100644 --- a/backend/internal/api/handlers/queue.go +++ b/backend/internal/api/handlers/queue.go @@ -4,8 +4,8 @@ import ( "log" "net/http" + "git.workaround.org/chaas/imc/backend/internal/mail" "github.com/gin-gonic/gin" - "github.com/imc-vibe/backend/internal/mail" ) type QueueHandler struct{} diff --git a/backend/internal/api/handlers/stats.go b/backend/internal/api/handlers/stats.go index b4002d4..f8a6aa8 100644 --- a/backend/internal/api/handlers/stats.go +++ b/backend/internal/api/handlers/stats.go @@ -1,8 +1,8 @@ package handlers import ( + "git.workaround.org/chaas/imc/backend/internal/db" "github.com/gin-gonic/gin" - "github.com/imc-vibe/backend/internal/db" ) type StatsHandler struct { @@ -21,19 +21,21 @@ type Stats struct { } func (h *StatsHandler) Get(c *gin.Context) { - domains, err := h.db.GetAllDomains() + ctx := c.Request.Context() + + domains, err := h.db.GetAllDomains(ctx) if err != nil { - domains = []db.DomainStats{} + domains = nil } - users, err := h.db.GetAllMailUsers() + users, err := h.db.GetAllMailUsers(ctx) if err != nil { - users = []db.User{} + users = nil } - aliases, err := h.db.GetAllAliases() + aliases, err := h.db.GetAllAliases(ctx) if err != nil { - aliases = []db.AliasWithDomain{} + aliases = nil } stats := Stats{ diff --git a/backend/internal/api/handlers/users.go b/backend/internal/api/handlers/users.go index 779e309..16a14c2 100644 --- a/backend/internal/api/handlers/users.go +++ b/backend/internal/api/handlers/users.go @@ -7,9 +7,10 @@ import ( "strconv" "strings" + "git.workaround.org/chaas/imc/backend/internal/auth" + "git.workaround.org/chaas/imc/backend/internal/db" + "git.workaround.org/chaas/imc/backend/internal/mail" "github.com/gin-gonic/gin" - "github.com/imc-vibe/backend/internal/db" - "github.com/imc-vibe/backend/internal/mail" ) type UserHandler struct { @@ -22,7 +23,7 @@ func NewUserHandler(database *db.DB) *UserHandler { type CreateUserRequest struct { Email string `json:"email" binding:"required"` - Password string `json:"password" binding:"required"` + Password string `json:"password"` Quota int64 `json:"quota"` } @@ -32,7 +33,7 @@ type UpdateUserRequest struct { } type UserWithQuota struct { - ID uint `json:"id"` + ID uint32 `json:"id"` Email string `json:"email"` Quota int64 `json:"quota"` UsedQuota *int64 `json:"usedQuota"` @@ -51,19 +52,20 @@ func (h *UserHandler) List(c *gin.Context) { return } - canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin()) + ctx := c.Request.Context() + canAccess, _ := h.db.CanAccessDomain(ctx, uint32(authCtx.UserID), domainName, authCtx.IsAdmin()) if !canAccess { Error(c, http.StatusForbidden, "access denied") return } - domain, err := h.db.GetDomainByName(domainName) + domain, err := h.db.GetDomainByName(ctx, domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return } - users, err := h.db.GetUsersByDomain(domain.ID) + users, err := h.db.GetUsersByDomain(ctx, domain.ID) if err != nil { Error(c, http.StatusInternalServerError, "database error") return @@ -71,16 +73,17 @@ func (h *UserHandler) List(c *gin.Context) { result := make([]UserWithQuota, len(users)) for i, user := range users { + quota := user.Quota.Int64 result[i] = UserWithQuota{ ID: user.ID, Email: user.Email, - Quota: user.Quota, + Quota: quota, } - quota, err := mail.GetQuota(user.Email) - if err == nil && quota != nil { - result[i].Quota = quota.Limit - result[i].UsedQuota = "a.Used + mailQuota, err := mail.GetQuota(user.Email) + if err == nil && mailQuota != nil { + result[i].Quota = mailQuota.Limit + result[i].UsedQuota = &mailQuota.Used } } @@ -102,7 +105,8 @@ func (h *UserHandler) Get(c *gin.Context) { return } - canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin()) + ctx := c.Request.Context() + canAccess, _ := h.db.CanAccessDomain(ctx, uint32(authCtx.UserID), domainName, authCtx.IsAdmin()) if !canAccess { Error(c, http.StatusForbidden, "access denied") return @@ -114,7 +118,7 @@ func (h *UserHandler) Get(c *gin.Context) { return } - user, err := h.db.GetUserByID(uint(id)) + user, err := h.db.GetUserByID(ctx, uint32(id)) if err != nil { Error(c, http.StatusNotFound, "user not found") return @@ -136,13 +140,14 @@ func (h *UserHandler) Create(c *gin.Context) { return } - canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin()) + ctx := c.Request.Context() + canAccess, _ := h.db.CanAccessDomain(ctx, uint32(authCtx.UserID), domainName, authCtx.IsAdmin()) if !canAccess { Error(c, http.StatusForbidden, "access denied") return } - domain, err := h.db.GetDomainByName(domainName) + domain, err := h.db.GetDomainByName(ctx, domainName) if err != nil { Error(c, http.StatusNotFound, "domain not found") return @@ -154,28 +159,31 @@ func (h *UserHandler) Create(c *gin.Context) { return } - // Validate email local part (before @) if err := validateEmailLocalPart(req.Email); err != nil { Error(c, http.StatusBadRequest, err.Error()) return } - existing, _ := h.db.GetUserByEmail(req.Email) - if existing != nil { + _, err = h.db.GetUserByEmail(ctx, req.Email) + if err == nil { Error(c, http.StatusConflict, "user already exists") return } - passwordHash := "{BLF-CRYPT}" + req.Password + password := req.Password + if password == "" { + password = auth.GenerateRandomPassword(16) + } + passwordHash := "{BLF-CRYPT}" + password - user, err := h.db.CreateUserInDomain(req.Email, passwordHash, req.Quota, domain.ID) + err = h.db.CreateUser(ctx, domain.ID, req.Email, passwordHash, req.Quota) if err != nil { - log.Printf("CreateUserInDomain error: email=%s, domain=%s, err=%v", req.Email, domainName, err) + log.Printf("CreateUser error: email=%s, domain=%s, err=%v", req.Email, domainName, err) Error(c, http.StatusInternalServerError, "failed to create user") return } - Created(c, user) + Created(c, map[string]interface{}{"message": "user created", "password": password}) } func (h *UserHandler) Update(c *gin.Context) { @@ -193,7 +201,8 @@ func (h *UserHandler) Update(c *gin.Context) { return } - canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin()) + ctx := c.Request.Context() + canAccess, _ := h.db.CanAccessDomain(ctx, uint32(authCtx.UserID), domainName, authCtx.IsAdmin()) if !canAccess { Error(c, http.StatusForbidden, "access denied") return @@ -205,7 +214,7 @@ func (h *UserHandler) Update(c *gin.Context) { return } - user, err := h.db.GetUserByID(uint(id)) + user, err := h.db.GetUserByID(ctx, uint32(id)) if err != nil { Error(c, http.StatusNotFound, "user not found") return @@ -219,14 +228,14 @@ func (h *UserHandler) Update(c *gin.Context) { if req.Password != "" { passwordHash := "{BLF-CRYPT}" + req.Password - if err := h.db.UpdateUserPassword(user.ID, passwordHash); err != nil { + if err := h.db.UpdateUserPassword(ctx, user.ID, passwordHash); err != nil { Error(c, http.StatusInternalServerError, "failed to update password") return } } if req.Quota >= 0 { - if err := h.db.UpdateUserQuota(user.ID, req.Quota); err != nil { + if err := h.db.UpdateUserQuota(ctx, user.ID, req.Quota); err != nil { Error(c, http.StatusInternalServerError, "failed to update quota") return } @@ -250,7 +259,8 @@ func (h *UserHandler) Delete(c *gin.Context) { return } - canAccess, _ := h.db.CanAccessDomain(authCtx.UserID, domainName, authCtx.IsAdmin()) + ctx := c.Request.Context() + canAccess, _ := h.db.CanAccessDomain(ctx, uint32(authCtx.UserID), domainName, authCtx.IsAdmin()) if !canAccess { Error(c, http.StatusForbidden, "access denied") return @@ -262,7 +272,8 @@ func (h *UserHandler) Delete(c *gin.Context) { return } - if err := h.db.DeleteUser(uint(id)); err != nil { + err = h.db.DeleteUser(ctx, uint32(id)) + if err != nil { Error(c, http.StatusInternalServerError, "failed to delete user") return } @@ -270,23 +281,7 @@ func (h *UserHandler) Delete(c *gin.Context) { NoContent(c) } -func (h *UserHandler) ListAll(c *gin.Context) { - authCtx := GetAuthContext(c) - if authCtx == nil || !authCtx.IsAdmin() { - Error(c, http.StatusForbidden, "admin access required") - return - } - - users, err := h.db.GetAllMailUsers() - if err != nil { - Error(c, http.StatusInternalServerError, "database error") - return - } - - Success(c, users) -} - -var emailLocalPartRegex = regexp.MustCompile("^[a-zA-Z0-9!#$%&'*+\\-/=?^_`{|}~-]+$") +var emailLocalPartRegex = regexp.MustCompile("^[a-zA-Z0-9!#$%&'*+\\-=?^_~-]+$") func validateEmailLocalPart(email string) error { parts := strings.Split(email, "@") @@ -299,17 +294,14 @@ func validateEmailLocalPart(email string) error { return &ValidationError{Message: "username must be between 1 and 64 characters"} } - // RFC 5321: local-part cannot start or end with a dot if strings.HasPrefix(localPart, ".") || strings.HasSuffix(localPart, ".") { return &ValidationError{Message: "username cannot start or end with a dot"} } - // RFC 5321: local-part cannot contain consecutive dots if strings.Contains(localPart, "..") { return &ValidationError{Message: "username cannot contain consecutive dots"} } - // Check valid characters (RFC 5321: letters, digits, and special chars !#$%&'*+/=?^_`{|}~-) if !emailLocalPartRegex.MatchString(localPart) { return &ValidationError{Message: "username contains invalid characters"} } diff --git a/backend/internal/api/router.go b/backend/internal/api/router.go index 1756d22..eb5180a 100644 --- a/backend/internal/api/router.go +++ b/backend/internal/api/router.go @@ -3,12 +3,11 @@ package api import ( "net/http" + "git.workaround.org/chaas/imc/backend/internal/api/handlers" + "git.workaround.org/chaas/imc/backend/internal/auth" + "git.workaround.org/chaas/imc/backend/internal/config" + "git.workaround.org/chaas/imc/backend/internal/db" "github.com/gin-gonic/gin" - "github.com/imc-vibe/backend/internal/api/handlers" - "github.com/imc-vibe/backend/internal/auth" - "github.com/imc-vibe/backend/internal/config" - "github.com/imc-vibe/backend/internal/db" - "github.com/imc-vibe/backend/internal/mail" ) type Router struct { @@ -23,11 +22,10 @@ type Router struct { } func New(database *db.DB, cfg *config.Config) *Router { - jwtManager := auth.NewJWTManager(cfg.JWTSecret, "imc-vibe") - emailService := mail.NewEmailService(cfg) + jwtManager := auth.NewJWTManager(cfg.JWTSecret, "imc") r := &Router{ - authHandler: handlers.NewAuthHandler(database, jwtManager, emailService, cfg.TrustedProxies), + authHandler: handlers.NewAuthHandler(database, jwtManager, cfg.TrustedProxies), domainHandler: handlers.NewDomainHandler(database), userHandler: handlers.NewUserHandler(database), aliasHandler: handlers.NewAliasHandler(database), @@ -46,7 +44,6 @@ func (r *Router) RegisterRoutes(engine *gin.Engine) { }) engine.POST("/api/auth/login", r.authHandler.Login) - engine.POST("/api/auth/forgot", r.authHandler.ForgotPassword) engine.POST("/api/auth/logout", r.authHandler.Logout) authGroup := engine.Group("/api") diff --git a/backend/internal/auth/jwt.go b/backend/internal/auth/jwt.go index 425b468..9c05e8f 100644 --- a/backend/internal/auth/jwt.go +++ b/backend/internal/auth/jwt.go @@ -3,8 +3,10 @@ package auth import ( - "errors" // standard errors package - "time" // time handling + "crypto/rand" // cryptographically secure random number generator + "errors" // standard errors package + "log" // logging + "time" // time handling "github.com/golang-jwt/jwt/v5" // JWT library for token handling "golang.org/x/crypto/bcrypt" // bcrypt for secure password hashing @@ -125,3 +127,16 @@ func CheckPassword(password, hash string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil } + +// GenerateRandomPassword creates a cryptographically secure random password. +func GenerateRandomPassword(length int) string { + const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*" + result := make([]byte, length) + if _, err := rand.Read(result); err != nil { + log.Fatalf("Failed to generate random password: %v", err) + } + for i := range result { + result[i] = charset[int(result[i])%len(charset)] + } + return string(result) +} diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index bb2268b..59f7762 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -39,16 +39,6 @@ type Config struct { // Rspamd settings (spam filter) RspamdAPI string // URL of the Rspamd web interface - - // SMTP settings (for sending password reset emails) - SMTPHost string // SMTP server hostname - SMTPPort string // SMTP server port (587 for submission, 465 for SMTPS) - SMTPUser string // SMTP username - SMTPPassword string // SMTP password - SMTPFrom string // From address in outgoing emails - - // Application settings - BaseURL string // Base URL of this application (used for generating links in emails) } // Load reads configuration from environment variables and .env files. @@ -98,16 +88,6 @@ func Load() *Config { // External services RspamdAPI: getEnv("RSPAMD_API", "http://127.0.0.1:11334"), - // SMTP settings (for password reset emails) - SMTPHost: getEnv("SMTP_HOST", "localhost"), - SMTPPort: getEnv("SMTP_PORT", "587"), - SMTPUser: getEnv("SMTP_USER", ""), - SMTPPassword: getEnv("SMTP_PASSWORD", ""), - SMTPFrom: getEnv("SMTP_FROM", "noreply@localhost"), - - // Application URL (for generating links in emails) - BaseURL: getEnv("BASE_URL", "http://localhost:8080"), - // Trusted proxies (comma-separated IPs) TrustedProxies: parseTrustedProxies(getEnv("TRUSTED_PROXIES", "")), } @@ -132,6 +112,9 @@ func (c *Config) Validate() error { if len(c.JWTSecret) < 32 { return fmt.Errorf("JWT_SECRET must be at least 32 characters long") } + if c.JWTSecret == "your-secret-key-at-least-32-chars" { + return fmt.Errorf("JWT_SECRET must not be the default value") + } return nil } diff --git a/backend/internal/db/aliases.go b/backend/internal/db/aliases.go deleted file mode 100644 index e531103..0000000 --- a/backend/internal/db/aliases.go +++ /dev/null @@ -1,70 +0,0 @@ -package db - -func (d *DB) GetAllAliases() ([]AliasWithDomain, error) { - var aliases []Alias - if err := d.Preload("Domain").Find(&aliases).Error; err != nil { - return nil, err - } - - result := make([]AliasWithDomain, len(aliases)) - for i, a := range aliases { - result[i] = AliasWithDomain{ - Alias: a, - DomainName: "", - } - if a.Domain != nil { - result[i].DomainName = a.Domain.Name - } - } - - if result == nil { - result = []AliasWithDomain{} - } - return result, nil -} - -func (d *DB) GetAliasesByDomain(domainID uint) ([]Alias, error) { - var aliases []Alias - if err := d.Where("domain_id = ?", domainID).Find(&aliases).Error; err != nil { - return nil, err - } - if aliases == nil { - aliases = []Alias{} - } - return aliases, nil -} - -func (d *DB) GetAliasByID(id uint) (*Alias, error) { - var alias Alias - if err := d.Preload("Domain").First(&alias, id).Error; err != nil { - return nil, err - } - return &alias, nil -} - -func (d *DB) CreateAlias(source, destination string) (*Alias, error) { - alias := Alias{ - Source: source, - Destination: destination, - } - if err := d.Create(&alias).Error; err != nil { - return nil, err - } - return &alias, nil -} - -func (d *DB) CreateAliasInDomain(source, destination string, domainID uint) (*Alias, error) { - alias := Alias{ - DomainID: domainID, - Source: source, - Destination: destination, - } - if err := d.Create(&alias).Error; err != nil { - return nil, err - } - return &alias, nil -} - -func (d *DB) DeleteAlias(id uint) error { - return d.Delete(&Alias{}, id).Error -} diff --git a/backend/internal/db/db.go b/backend/internal/db/db.go index 0106612..13fa388 100644 --- a/backend/internal/db/db.go +++ b/backend/internal/db/db.go @@ -1,248 +1,90 @@ -// Package db provides database access for the imc-vibe application. -// It uses GORM (Go ORM) for database operations. -// -// The database contains two sets of tables: -// 1. ISPmail tables (virtual_domains, virtual_users, virtual_aliases) - existing mail data -// 2. imc tables (imc_users, imc_users2domains, etc.) - application-specific data +// Package db provides database access for the IMC application. +// It uses sqlc for type-safe SQL queries. package db import ( - "fmt" // formatted error messages - "time" // time package for timestamps + "database/sql" + "fmt" + "time" - "gorm.io/driver/mysql" // GORM MySQL driver - "gorm.io/gorm" // GORM ORM library - "gorm.io/gorm/logger" // GORM logger configuration - - "github.com/imc-vibe/backend/internal/config" // configuration + "git.workaround.org/chaas/imc/backend/internal/config" + imcdb "git.workaround.org/chaas/imc/backend/internal/db/sqlc" + _ "github.com/go-sql-driver/mysql" ) -// DB wraps GORM's database connection with helper methods. -// This is the main database access point for the application. type DB struct { - *gorm.DB // Embeds GORM's DB type, giving us all GORM methods + *imcdb.Queries + db *sql.DB } -// ============================================================================= -// ISPmail Models (existing mail server tables) -// These tables are shared with the ISPmail system and must not be modified. -// ============================================================================= - -// Domain represents a mail domain (e.g., "example.org"). -// This corresponds to the existing ISPmail virtual_domains table. -type Domain struct { - ID uint `gorm:"primaryKey" json:"id"` // Primary key, auto-increment - Name string `gorm:"uniqueIndex;size:50;not null" json:"name"` // Domain name, must be unique - CreatedAt time.Time `json:"createdAt"` // When the domain was added - Users []User `gorm:"foreignKey:DomainID" json:"users,omitempty"` // Mail users in this domain - Aliases []Alias `gorm:"foreignKey:DomainID" json:"aliases,omitempty"` // Aliases in this domain -} - -// TableName tells GORM to use the existing ISPmail table name. -func (Domain) TableName() string { return "virtual_domains" } - -// User represents a mail user (e.g., "user@example.org"). -// This corresponds to the existing ISPmail virtual_users table. -type User struct { - ID uint `gorm:"primaryKey" json:"id"` // Primary key - DomainID uint `gorm:"not null" json:"domainId"` // Foreign key to Domain - Email string `gorm:"uniqueIndex;size:100;not null" json:"email"` // Full email address, must be unique - Password string `gorm:"size:150;not null" json:"-"` // Mailbox password (bcrypt hash, - means exclude from JSON) - Quota int64 `gorm:"default:0" json:"quota"` // Mailbox size limit in bytes (0 = default) - Domain *Domain `gorm:"foreignKey:DomainID" json:"domain,omitempty"` // Associated domain -} - -// TableName tells GORM to use the existing ISPmail table name. -func (User) TableName() string { return "virtual_users" } - -// Alias represents an email alias/forwarding rule. -// Maps one email address (source) to another (destination). -// This corresponds to the existing ISPmail virtual_aliases table. -type Alias struct { - ID uint `gorm:"primaryKey" json:"id"` // Primary key - DomainID uint `gorm:"not null" json:"domainId"` // Foreign key to Domain - Source string `gorm:"size:100;not null" json:"source"` // Original email address (alias) - Destination string `gorm:"size:100;not null" json:"destination"` // Forward-to email address - Domain *Domain `gorm:"foreignKey:DomainID" json:"domain,omitempty"` // Associated domain -} - -// TableName tells GORM to use the existing ISPmail table name. -func (Alias) TableName() string { return "virtual_aliases" } - -// ============================================================================= -// imc-vibe Application Models (tables created by this app) -// ============================================================================= - -// ImcUser represents an admin user who can log into this application. -// This is separate from mail users - it's for the web admin interface. -type ImcUser struct { - ID uint `gorm:"primaryKey" json:"id"` // Primary key - Username string `gorm:"uniqueIndex;size:100;not null" json:"username"` // Login username - PasswordHash string `gorm:"size:255;not null" json:"-"` // Bcrypt hash of password (- means exclude from JSON) - Role string `gorm:"type:enum('admin','user');default:'user'" json:"role"` // Role: admin or regular user - CreatedAt time.Time `json:"createdAt"` // When account was created - Domains []ImcUserDomain `gorm:"foreignKey:UserID" json:"domains,omitempty"` // Domains this user can access -} - -// TableName specifies the database table name for ImcUser. -func (ImcUser) TableName() string { return "imc_users" } - -// ImcUserDomain represents the many-to-many relationship between admin users and domains. -// An admin user can have access to multiple domains, and a domain can be accessed by multiple users. -type ImcUserDomain struct { - ID uint `gorm:"primaryKey" json:"id"` // Primary key - UserID uint `gorm:"not null" json:"userId"` // Foreign key to ImcUser - DomainID uint `gorm:"not null" json:"domainId"` // Foreign key to Domain - CreatedAt time.Time `json:"createdAt"` // When access was granted - Domain *Domain `gorm:"foreignKey:DomainID" json:"domain,omitempty"` // Associated domain (for preloading) -} - -// TableName specifies the database table name for ImcUserDomain. -func (ImcUserDomain) TableName() string { return "imc_users2domains" } - -// ImcLoginAttempt records login attempts for brute-force protection. -// Used to track failed login attempts and implement rate limiting. -type ImcLoginAttempt struct { - ID uint `gorm:"primaryKey" json:"id"` // Primary key - Email string `gorm:"size:100;not null" json:"email"` // Email/username that was used - IPAddress string `gorm:"size:45;not null" json:"ipAddress"` // IP address of the requester (IPv6 compatible) - AttemptedAt time.Time `json:"attemptedAt"` // When the attempt occurred - Successful bool `gorm:"default:false" json:"successful"` // Whether the login succeeded -} - -// TableName specifies the database table name for ImcLoginAttempt. -func (ImcLoginAttempt) TableName() string { return "imc_login_attempts" } - -// PasswordResetToken stores one-time tokens for password reset functionality. -type PasswordResetToken struct { - ID uint `gorm:"primaryKey" json:"id"` // Primary key - UserID uint `gorm:"not null" json:"userId"` // Foreign key to ImcUser - Token string `gorm:"size:64;not null;uniqueIndex" json:"token"` // The reset token (unique index for fast lookup) - ExpiresAt time.Time `gorm:"not null" json:"expiresAt"` // When this token expires - Used bool `gorm:"default:false" json:"used"` // Whether this token has been used - CreatedAt time.Time `json:"createdAt"` // When the token was created -} - -// TableName specifies the database table name for PasswordResetToken. -func (PasswordResetToken) TableName() string { return "imc_password_reset_tokens" } - -// ============================================================================= -// Helper/View Models (not stored in database) -// ============================================================================= - -// DomainStats holds statistics about a domain (user count, alias count). -// Used for displaying dashboard information. type DomainStats struct { - ID uint `json:"id"` // Domain ID - Name string `json:"name"` // Domain name - UserCount int64 `json:"userCount"` // Number of mail users - AliasCount int64 `json:"aliasCount"` // Number of aliases + ID uint32 `json:"id"` + Name string `json:"name"` + UserCount int64 `json:"userCount"` + AliasCount int64 `json:"aliasCount"` } -// AliasWithDomain combines an alias with its domain name for API responses. type AliasWithDomain struct { - Alias // Embed Alias struct - DomainName string `json:"domainName"` // Denormalized domain name for convenience + imcdb.VirtualAlias + DomainName string `json:"domainName"` } -// UserWithDomain combines a user with their domain name for API responses. -type UserWithDomain struct { - User // Embed User struct - DomainName string `json:"domainName"` // Denormalized domain name for convenience -} - -// ============================================================================= -// Database Connection -// ============================================================================= - -// Connect establishes a connection to the MySQL/MariaDB database. -// cfg: configuration containing database credentials and connection settings. -// Returns: a DB wrapper around the GORM connection, or an error if connection fails. func Connect(cfg *config.Config) (*DB, error) { - // Build the Data Source Name (DSN) string. - // Format: username:password@protocol(address:port)/dbname?options - // parseTime=true: automatically convert time.Time to/from SQL DATETIME - // charset=utf8mb4: use full UTF-8 encoding (supports emojis, etc.) dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?parseTime=true&charset=utf8mb4", cfg.DBUser, cfg.DBPassword, cfg.DBHost, cfg.DBPort, cfg.DBName) - // Open a connection to the database using GORM. - // We configure GORM to be silent (no auto-logging) to reduce noise. - db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ - Logger: logger.Default.LogMode(logger.Silent), - }) + mysqlDB, err := sql.Open("mysql", dsn) if err != nil { - return nil, fmt.Errorf("failed to connect to database: %w", err) + return nil, fmt.Errorf("failed to open database: %w", err) } - // Get the underlying sql.DB object from GORM. - // GORM wraps the standard database/sql package. - sqlDB, err := db.DB() - if err != nil { - return nil, err + mysqlDB.SetMaxOpenConns(25) + mysqlDB.SetMaxIdleConns(5) + mysqlDB.SetConnMaxLifetime(5 * time.Minute) + + if err := mysqlDB.Ping(); err != nil { + return nil, fmt.Errorf("failed to ping database: %w", err) } - // Configure connection pool settings for performance. - // These settings help balance between connection reuse and resource usage. - - // SetMaxOpenConns: maximum number of open connections to the database. - // Too few = slow requests, too many = database overload. - // 25 is a reasonable default for most applications. - sqlDB.SetMaxOpenConns(25) - - // SetMaxIdleConns: maximum number of idle connections in the pool. - // Idle connections are kept open even when not in use. - // This avoids the overhead of opening new connections. - sqlDB.SetMaxIdleConns(5) - - // SetConnMaxLifetime: maximum time a connection can be reused. - // Connections older than this are closed and replaced. - // This helps avoid issues with stale connections. - sqlDB.SetConnMaxLifetime(5 * time.Minute) - - return &DB{db}, nil + return &DB{ + Queries: imcdb.New(mysqlDB), + db: mysqlDB, + }, nil } -// InitSchema creates imc-vibe's database tables if they don't exist. -// This only creates the imc_* tables, not the ISPmail virtual_* tables. -// Called during application startup. func (d *DB) InitSchema() error { - // Create imc_users table for admin accounts. - // This table stores admin users who can log into the web interface. imcUsersSQL := ` CREATE TABLE IF NOT EXISTS imc_users ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, username VARCHAR(100) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, role ENUM('admin','user') DEFAULT 'user', + domain_id INT UNSIGNED NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_username (username), - INDEX idx_role (role) + INDEX idx_role (role), + INDEX idx_domain_id (domain_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ` - if err := d.Exec(imcUsersSQL).Error; err != nil { + if _, err := d.db.Exec(imcUsersSQL); err != nil { return err } - // Create imc_login_attempts table for tracking login attempts. - // Used for brute-force protection (rate limiting). loginAttemptsSQL := ` CREATE TABLE IF NOT EXISTS imc_login_attempts ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, - email VARCHAR(100) NOT NULL, + username VARCHAR(100) NOT NULL, ip_address VARCHAR(45) NOT NULL, attempted_at DATETIME DEFAULT CURRENT_TIMESTAMP, successful BOOLEAN DEFAULT FALSE, - INDEX idx_email_time (email, attempted_at), + INDEX idx_username_time (username, attempted_at), INDEX idx_ip_time (ip_address, attempted_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ` - if err := d.Exec(loginAttemptsSQL).Error; err != nil { + if _, err := d.db.Exec(loginAttemptsSQL); err != nil { return err } - // Create imc_users2domains table for user-domain permissions. - // This implements many-to-many: a user can access multiple domains. users2DomainsSQL := ` CREATE TABLE IF NOT EXISTS imc_users2domains ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, @@ -254,23 +96,13 @@ func (d *DB) InitSchema() error { INDEX idx_domain_id (domain_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ` - if err := d.Exec(users2DomainsSQL).Error; err != nil { + if _, err := d.db.Exec(users2DomainsSQL); err != nil { return err } - // Create imc_password_reset_tokens table for password reset functionality. - // Stores temporary tokens for resetting forgotten passwords. - resetTokensSQL := ` - CREATE TABLE IF NOT EXISTS imc_password_reset_tokens ( - id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, - user_id INT UNSIGNED NOT NULL, - token VARCHAR(64) NOT NULL UNIQUE, - expires_at DATETIME NOT NULL, - used BOOLEAN DEFAULT FALSE, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - INDEX idx_token (token), - INDEX idx_user_id (user_id) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 - ` - return d.Exec(resetTokensSQL).Error + return nil +} + +func (d *DB) Close() error { + return d.db.Close() } diff --git a/backend/internal/db/domains.go b/backend/internal/db/domains.go deleted file mode 100644 index 5ccd230..0000000 --- a/backend/internal/db/domains.go +++ /dev/null @@ -1,68 +0,0 @@ -package db - -func (d *DB) GetAllDomains() ([]DomainStats, error) { - var domains []Domain - if err := d.Order("name ASC").Find(&domains).Error; err != nil { - return nil, err - } - - stats := make([]DomainStats, len(domains)) - for i, dom := range domains { - var userCount, aliasCount int64 - d.Model(&User{}).Where("domain_id = ?", dom.ID).Count(&userCount) - d.Model(&Alias{}).Where("domain_id = ?", dom.ID).Count(&aliasCount) - - stats[i] = DomainStats{ - ID: dom.ID, - Name: dom.Name, - UserCount: userCount, - AliasCount: aliasCount, - } - } - - if stats == nil { - stats = []DomainStats{} - } - return stats, nil -} - -func (d *DB) GetDomainByID(id uint) (*Domain, error) { - var domain Domain - if err := d.Where("id = ?", id).First(&domain).Error; err != nil { - return nil, err - } - return &domain, nil -} - -func (d *DB) GetDomainByName(name string) (*Domain, error) { - var domain Domain - if err := d.Where("name = ?", name).First(&domain).Error; err != nil { - return nil, err - } - return &domain, nil -} - -func (d *DB) CreateDomain(name string) (*Domain, error) { - domain := Domain{Name: name} - if err := d.Create(&domain).Error; err != nil { - return nil, err - } - return &domain, nil -} - -func (d *DB) DeleteDomain(id uint) error { - tx := d.Begin() - defer func() { tx.Rollback() }() - - if err := tx.Where("domain_id = ?", id).Delete(&User{}).Error; err != nil { - return err - } - if err := tx.Where("domain_id = ?", id).Delete(&Alias{}).Error; err != nil { - return err - } - if err := tx.Delete(&Domain{}, id).Error; err != nil { - return err - } - - return tx.Commit().Error -} diff --git a/backend/internal/db/imc_users.go b/backend/internal/db/imc_users.go index a02c837..d228ca1 100644 --- a/backend/internal/db/imc_users.go +++ b/backend/internal/db/imc_users.go @@ -1,228 +1,166 @@ package db -import "time" +import ( + "context" + "errors" -// ============================================================================= -// Admin User (ImcUser) Operations -// These functions manage admin users who can log into the web interface. -// ============================================================================= + imcdb "git.workaround.org/chaas/imc/backend/internal/db/sqlc" +) -// GetImcUserByUsername looks up an admin user by their username. -// Returns the user with their associated domain permissions preloaded. -// username: the username to search for. -// Returns: the user and any error. -func (d *DB) GetImcUserByUsername(username string) (*ImcUser, error) { - var user ImcUser - // Preload loads related data (Domains) to avoid N+1 queries. - // Where creates a SQL WHERE clause, ? is a placeholder for the username. - if err := d.Preload("Domains.Domain").Where("username = ?", username).First(&user).Error; err != nil { - return nil, err // Return nil user and the error - } - return &user, nil -} +var ErrNotFound = errors.New("record not found") -// GetImcUserByID looks up an admin user by their ID. -// Returns the user with their associated domain permissions preloaded. -// id: the user's primary key ID. -// Returns: the user and any error. -func (d *DB) GetImcUserByID(id uint) (*ImcUser, error) { - var user ImcUser - // First(&user, id) looks up by primary key. - if err := d.Preload("Domains.Domain").First(&user, id).Error; err != nil { - return nil, err - } - return &user, nil -} - -// CreateImcUser creates a new admin user account. -// username: the login username (must be unique). -// passwordHash: the bcrypt hash of the password (NOT the plain password). -// role: "admin" or "user". -// Returns: the created user and any error. -func (d *DB) CreateImcUser(username, passwordHash, role string) (*ImcUser, error) { - user := ImcUser{ - Username: username, - PasswordHash: passwordHash, - Role: role, - } - // Create inserts the record into the database. - if err := d.Create(&user).Error; err != nil { - return nil, err - } - return &user, nil -} - -// UpdateImcUserPassword updates the password hash for a user. -// id: the user's ID. -// passwordHash: the new bcrypt hash of the password. -func (d *DB) UpdateImcUserPassword(id uint, passwordHash string) error { - // Model specifies which table/struct to update. - // Where filters which rows to update. - // Update only changes the specified fields. - return d.Model(&ImcUser{}).Where("id = ?", id).Update("password_hash", passwordHash).Error -} - -// DeleteImcUser removes an admin user from the database. -// id: the user's ID to delete. -func (d *DB) DeleteImcUser(id uint) error { - return d.Delete(&ImcUser{}, id).Error // Delete by primary key -} - -// UpsertAdminUser creates the admin user if it doesn't exist, or updates the password if it does. -func (d *DB) UpsertAdminUser(username, passwordHash string) error { - var user ImcUser - err := d.Where("username = ? AND role = ?", username, "admin").First(&user).Error - if err == nil { - return d.Model(&ImcUser{}).Where("id = ?", user.ID).Update("password_hash", passwordHash).Error - } - _, err = d.CreateImcUser(username, passwordHash, "admin") - return err -} - -// ============================================================================= -// Domain Access Control -// These functions manage which domains users can access. -// ============================================================================= - -// GetUserAccessibleDomains returns all domains a user can access. -// Admin users can access all domains; regular users only their assigned domains. -// userID: the ID of the user. -// isAdmin: whether the user has admin privileges. -// Returns: a list of accessible domains. -func (d *DB) GetUserAccessibleDomains(userID uint, isAdmin bool) ([]Domain, error) { - // Admins get access to all domains. - if isAdmin { - var domains []Domain - if err := d.Order("name ASC").Find(&domains).Error; err != nil { - return nil, err - } - return domains, nil - } - - // Regular users query the imc_users2domains table. - // We use raw SQL with Joins because GORM's association methods - // don't handle our cross-database queries well. - var domains []Domain - err := d.Table("imc_users2domains"). // Query from this table - Select("virtual_domains.*"). // Select all columns from domains - Joins("JOIN virtual_domains ON virtual_domains.id = imc_users2domains.domain_id"). // Join to get domain details - Where("imc_users2domains.user_id = ?", userID). // Only this user's domains - Order("name ASC"). - Find(&domains).Error +func (d *DB) GetImcUserByUsername(ctx context.Context, username string) (*imcdb.ImcUser, error) { + user, err := d.Queries.GetImcUserByUsername(ctx, username) if err != nil { return nil, err } - if domains == nil { - domains = []Domain{} // Return empty slice, not nil - } - return domains, nil + return &user, nil } -// CanAccessDomain checks if a user can access a specific domain. -// userID: the ID of the user. -// domainName: the name of the domain (e.g., "example.org"). -// isAdmin: whether the user has admin privileges. -// Returns: true if the user can access the domain, false otherwise. -func (d *DB) CanAccessDomain(userID uint, domainName string, isAdmin bool) (bool, error) { - // Admins can access all domains. +func (d *DB) GetImcUserByID(ctx context.Context, id uint32) (*imcdb.ImcUser, error) { + user, err := d.Queries.GetImcUserByID(ctx, id) + if err != nil { + return nil, err + } + return &user, nil +} + +func (d *DB) CreateImcUser(ctx context.Context, username, passwordHash, role string, domainID uint32) error { + roleNull := imcdb.NullImcUsersRole{ImcUsersRole: imcdb.ImcUsersRole(role), Valid: true} + return d.Queries.CreateImcUser(ctx, imcdb.CreateImcUserParams{ + Username: username, + PasswordHash: passwordHash, + Role: roleNull, + DomainID: domainID, + }) +} + +func (d *DB) UpdateImcUserPassword(ctx context.Context, id uint32, passwordHash string) error { + return d.Queries.UpdateImcUserPassword(ctx, imcdb.UpdateImcUserPasswordParams{ + PasswordHash: passwordHash, + ID: id, + }) +} + +func (d *DB) DeleteImcUser(ctx context.Context, id uint32) error { + return d.Queries.DeleteImcUser(ctx, id) +} + +func (d *DB) UpsertAdminUser(ctx context.Context, username, passwordHash string, domainID uint32) error { + user, err := d.Queries.GetImcUserByUsername(ctx, username) + if err == nil && user.ID != 0 { + return d.Queries.UpdateImcUserPassword(ctx, imcdb.UpdateImcUserPasswordParams{ + PasswordHash: passwordHash, + ID: user.ID, + }) + } + return d.CreateImcUser(ctx, username, passwordHash, "admin", domainID) +} + +func (d *DB) GetUserAccessibleDomains(ctx context.Context, userID uint32, isAdmin bool) ([]imcdb.VirtualDomain, error) { + if isAdmin { + return d.Queries.GetAllDomains(ctx) + } + + user, err := d.Queries.GetImcUserByID(ctx, userID) + if err != nil { + return nil, err + } + + primaryDomain, err := d.Queries.GetDomainByID(ctx, user.DomainID) + if err != nil { + return nil, err + } + + additionalDomains, err := d.Queries.GetAdditionalDomainsForUser(ctx, userID) + if err != nil { + return nil, err + } + + domainMap := make(map[uint32]imcdb.VirtualDomain) + domainMap[primaryDomain.ID] = primaryDomain + for _, d := range additionalDomains { + domainMap[d.ID] = d + } + + result := make([]imcdb.VirtualDomain, 0, len(domainMap)) + for _, d := range domainMap { + result = append(result, d) + } + return result, nil +} + +func (d *DB) CanAccessDomain(ctx context.Context, userID uint32, domainName string, isAdmin bool) (bool, error) { if isAdmin { return true, nil } - // Count matching records - if count > 0, access is granted. - var count int64 - err := d.Table("imc_users2domains"). - Select("COUNT(*)"). // Count matching rows - Joins("JOIN virtual_domains ON virtual_domains.id = imc_users2domains.domain_id"). // Join to domain table - Where("imc_users2domains.user_id = ? AND virtual_domains.name = ?", userID, domainName). // Match user and domain name - Count(&count).Error + user, err := d.Queries.GetImcUserByID(ctx, userID) if err != nil { return false, err } - return count > 0, nil // True if at least one match found + + primaryDomain, err := d.Queries.GetDomainByID(ctx, user.DomainID) + if err == nil && primaryDomain.Name == domainName { + return true, nil + } + + count, err := d.Queries.IsUserInDomain(ctx, imcdb.IsUserInDomainParams{UserID: userID}) + if err != nil { + return false, err + } + return count > 0, nil } -// AddUserToDomain grants a user access to a domain. -// userID: the ID of the user. -// domainID: the ID of the domain. -func (d *DB) AddUserToDomain(userID, domainID uint) error { - ud := ImcUserDomain{ +func (d *DB) GetUsersForDomain(ctx context.Context, domainID uint32) ([]imcdb.ImcUser, error) { + users, err := d.Queries.GetUsersForDomain(ctx, domainID) + if err != nil { + return nil, err + } + + additionalUsers, err := d.Queries.GetUsersForDomainViaJoin(ctx, domainID) + if err != nil { + return nil, err + } + + userMap := make(map[uint32]imcdb.ImcUser) + for _, u := range users { + userMap[u.ID] = u + } + for _, u := range additionalUsers { + if _, exists := userMap[u.ID]; !exists { + userMap[u.ID] = u + } + } + + result := make([]imcdb.ImcUser, 0, len(userMap)) + for _, u := range userMap { + result = append(result, u) + } + return result, nil +} + +func (d *DB) AddUserToDomain(ctx context.Context, userID, domainID uint32) error { + return d.Queries.AddUserToDomain(ctx, imcdb.AddUserToDomainParams{ UserID: userID, DomainID: domainID, - } - return d.Create(&ud).Error + }) } -// RemoveUserFromDomain revokes a user's access to a domain. -// userID: the ID of the user. -// domainID: the ID of the domain. -func (d *DB) RemoveUserFromDomain(userID, domainID uint) error { - // Delete records matching both user_id and domain_id. - return d.Where("user_id = ? AND domain_id = ?", userID, domainID).Delete(&ImcUserDomain{}).Error +func (d *DB) RemoveUserFromDomain(ctx context.Context, userID, domainID uint32) error { + return d.Queries.RemoveUserFromDomain(ctx, imcdb.RemoveUserFromDomainParams{ + UserID: userID, + DomainID: domainID, + }) } -// GetUsersForDomain returns all admin users who can access a specific domain. -// domainID: the ID of the domain. -// Returns: a list of users who can access this domain. -func (d *DB) GetUsersForDomain(domainID uint) ([]ImcUser, error) { - var users []ImcUser - err := d.Table("imc_users2domains"). - Select("imc_users.*"). // Select all columns from imc_users - Joins("JOIN imc_users ON imc_users.id = imc_users2domains.user_id"). // Join to users table - Where("imc_users2domains.domain_id = ?", domainID). - Find(&users).Error +func (d *DB) IsUserInDomain(ctx context.Context, userID, domainID uint32) (bool, error) { + count, err := d.Queries.IsUserInDomain(ctx, imcdb.IsUserInDomainParams{ + UserID: userID, + DomainID: domainID, + }) if err != nil { - return nil, err + return false, err } - if users == nil { - users = []ImcUser{} - } - return users, nil -} - -// IsUserInDomain checks if a user already has access to a domain. -// userID: the ID of the user. -// domainID: the ID of the domain. -// Returns: true if the user already has access, false otherwise. -func (d *DB) IsUserInDomain(userID, domainID uint) (bool, error) { - var count int64 - err := d.Model(&ImcUserDomain{}).Where("user_id = ? AND domain_id = ?", userID, domainID).Count(&count).Error - return count > 0, err -} - -// ============================================================================= -// Password Reset Tokens -// These functions manage one-time tokens for password reset. -// ============================================================================= - -// CreatePasswordResetToken creates a new password reset token. -// userID: the ID of the user requesting password reset. -// token: the random token string. -// expiresAt: when this token becomes invalid. -func (d *DB) CreatePasswordResetToken(userID uint, token string, expiresAt time.Time) error { - resetToken := PasswordResetToken{ - UserID: userID, - Token: token, - ExpiresAt: expiresAt, - } - return d.Create(&resetToken).Error -} - -// GetValidPasswordResetToken looks up a valid (unused, not expired) reset token. -// token: the token string to look up. -// Returns: the token if valid, or an error if not found/expired/used. -func (d *DB) GetValidPasswordResetToken(token string) (*PasswordResetToken, error) { - var resetToken PasswordResetToken - // Check token exists, hasn't been used, and hasn't expired. - err := d.Where("token = ? AND used = false AND expires_at > ?", token, time.Now()).First(&resetToken).Error - if err != nil { - return nil, err - } - return &resetToken, nil -} - -// MarkResetTokenUsed marks a token as used (prevents reuse). -// token: the token string to mark as used. -func (d *DB) MarkResetTokenUsed(token string) error { - return d.Model(&PasswordResetToken{}).Where("token = ?", token).Update("used", true).Error + return count > 0, nil } diff --git a/backend/internal/db/queries/aliases.sql b/backend/internal/db/queries/aliases.sql new file mode 100644 index 0000000..d303e84 --- /dev/null +++ b/backend/internal/db/queries/aliases.sql @@ -0,0 +1,20 @@ +-- name: GetAllAliases :many +SELECT * FROM virtual_aliases; + +-- name: GetAliasesByDomain :many +SELECT * FROM virtual_aliases WHERE domain_id = ?; + +-- name: GetAliasByID :one +SELECT * FROM virtual_aliases WHERE id = ?; + +-- name: GetAliasBySource :one +SELECT * FROM virtual_aliases WHERE source = ?; + +-- name: CreateAlias :exec +INSERT INTO virtual_aliases (domain_id, source, destination) VALUES (?, ?, ?); + +-- name: DeleteAlias :exec +DELETE FROM virtual_aliases WHERE id = ?; + +-- name: CountAliasesByDomain :one +SELECT COUNT(*) as count FROM virtual_aliases WHERE domain_id = ?; diff --git a/backend/internal/db/queries/domains.sql b/backend/internal/db/queries/domains.sql new file mode 100644 index 0000000..798d6fa --- /dev/null +++ b/backend/internal/db/queries/domains.sql @@ -0,0 +1,26 @@ +-- name: GetAllDomains :many +SELECT * FROM virtual_domains ORDER BY name ASC; + +-- name: GetDomainByID :one +SELECT * FROM virtual_domains WHERE id = ?; + +-- name: GetDomainByName :one +SELECT * FROM virtual_domains WHERE name = ?; + +-- name: CreateDomain :exec +INSERT INTO virtual_domains (name) VALUES (?); + +-- name: DeleteDomain :exec +DELETE FROM virtual_domains WHERE id = ?; + +-- name: GetAllDomainsWithCounts :many +SELECT + d.id, + d.name, + d.created_at, + COALESCE(u.user_count, 0) as user_count, + COALESCE(a.alias_count, 0) as alias_count +FROM virtual_domains d +LEFT JOIN (SELECT domain_id, COUNT(*) as user_count FROM virtual_users GROUP BY domain_id) u ON u.domain_id = d.id +LEFT JOIN (SELECT domain_id, COUNT(*) as alias_count FROM virtual_aliases GROUP BY domain_id) a ON a.domain_id = d.id +ORDER BY d.name ASC; diff --git a/backend/internal/db/queries/imc_users.sql b/backend/internal/db/queries/imc_users.sql new file mode 100644 index 0000000..91596b2 --- /dev/null +++ b/backend/internal/db/queries/imc_users.sql @@ -0,0 +1,36 @@ +-- name: GetImcUserByUsername :one +SELECT * FROM imc_users WHERE username = ?; + +-- name: GetImcUserByID :one +SELECT * FROM imc_users WHERE id = ?; + +-- name: CreateImcUser :exec +INSERT INTO imc_users (username, password_hash, role, domain_id) VALUES (?, ?, ?, ?); + +-- name: UpdateImcUserPassword :exec +UPDATE imc_users SET password_hash = ? WHERE id = ?; + +-- name: DeleteImcUser :exec +DELETE FROM imc_users WHERE id = ?; + +-- name: GetUsersForDomain :many +SELECT imc_users.* FROM imc_users WHERE domain_id = ?; + +-- name: GetUsersForDomainViaJoin :many +SELECT imc_users.* FROM imc_users +JOIN imc_users2domains ON imc_users.id = imc_users2domains.user_id +WHERE imc_users2domains.domain_id = ?; + +-- name: AddUserToDomain :exec +INSERT INTO imc_users2domains (user_id, domain_id) VALUES (?, ?); + +-- name: RemoveUserFromDomain :exec +DELETE FROM imc_users2domains WHERE user_id = ? AND domain_id = ?; + +-- name: IsUserInDomain :one +SELECT COUNT(*) as count FROM imc_users2domains WHERE user_id = ? AND domain_id = ?; + +-- name: GetAdditionalDomainsForUser :many +SELECT virtual_domains.* FROM virtual_domains +JOIN imc_users2domains ON virtual_domains.id = imc_users2domains.domain_id +WHERE imc_users2domains.user_id = ?; diff --git a/backend/internal/db/queries/schema.sql b/backend/internal/db/queries/schema.sql new file mode 100644 index 0000000..a639c75 --- /dev/null +++ b/backend/internal/db/queries/schema.sql @@ -0,0 +1,52 @@ +-- ISPmail tables (existing) +CREATE TABLE IF NOT EXISTS virtual_domains ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(50) NOT NULL UNIQUE, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS virtual_users ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + domain_id INT UNSIGNED NOT NULL, + email VARCHAR(100) NOT NULL UNIQUE, + password VARCHAR(150) NOT NULL, + quota BIGINT DEFAULT 0, + FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS virtual_aliases ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + domain_id INT UNSIGNED NOT NULL, + source VARCHAR(100) NOT NULL, + destination VARCHAR(100) NOT NULL, + FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- IMC application tables +CREATE TABLE IF NOT EXISTS imc_users ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + username VARCHAR(100) NOT NULL UNIQUE, + password_hash VARCHAR(255) NOT NULL, + role ENUM('admin','user') DEFAULT 'user', + domain_id INT UNSIGNED NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS imc_login_attempts ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + username VARCHAR(100) NOT NULL, + ip_address VARCHAR(45) NOT NULL, + attempted_at DATETIME DEFAULT CURRENT_TIMESTAMP, + successful BOOLEAN DEFAULT FALSE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS imc_users2domains ( + id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + user_id INT UNSIGNED NOT NULL, + domain_id INT UNSIGNED NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + UNIQUE KEY unique_user_domain (user_id, domain_id), + FOREIGN KEY (user_id) REFERENCES imc_users(id) ON DELETE CASCADE, + FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/backend/internal/db/queries/users.sql b/backend/internal/db/queries/users.sql new file mode 100644 index 0000000..6bd8cc5 --- /dev/null +++ b/backend/internal/db/queries/users.sql @@ -0,0 +1,26 @@ +-- name: GetAllMailUsers :many +SELECT * FROM virtual_users; + +-- name: GetUsersByDomain :many +SELECT * FROM virtual_users WHERE domain_id = ?; + +-- name: GetUserByID :one +SELECT * FROM virtual_users WHERE id = ?; + +-- name: GetUserByEmail :one +SELECT * FROM virtual_users WHERE email = ?; + +-- name: CreateUser :exec +INSERT INTO virtual_users (domain_id, email, password, quota) VALUES (?, ?, ?, ?); + +-- name: UpdateUserPassword :exec +UPDATE virtual_users SET password = ? WHERE id = ?; + +-- name: UpdateUserQuota :exec +UPDATE virtual_users SET quota = ? WHERE id = ?; + +-- name: DeleteUser :exec +DELETE FROM virtual_users WHERE id = ?; + +-- name: CountUsersByDomain :one +SELECT COUNT(*) as count FROM virtual_users WHERE domain_id = ?; diff --git a/backend/internal/db/sqlc/aliases.sql.go b/backend/internal/db/sqlc/aliases.sql.go new file mode 100644 index 0000000..2abb332 --- /dev/null +++ b/backend/internal/db/sqlc/aliases.sql.go @@ -0,0 +1,141 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: aliases.sql + +package db + +import ( + "context" +) + +const countAliasesByDomain = `-- name: CountAliasesByDomain :one +SELECT COUNT(*) as count FROM virtual_aliases WHERE domain_id = ? +` + +func (q *Queries) CountAliasesByDomain(ctx context.Context, domainID uint32) (int64, error) { + row := q.db.QueryRowContext(ctx, countAliasesByDomain, domainID) + var count int64 + err := row.Scan(&count) + return count, err +} + +const createAlias = `-- name: CreateAlias :exec +INSERT INTO virtual_aliases (domain_id, source, destination) VALUES (?, ?, ?) +` + +type CreateAliasParams struct { + DomainID uint32 `json:"domain_id"` + Source string `json:"source"` + Destination string `json:"destination"` +} + +func (q *Queries) CreateAlias(ctx context.Context, arg CreateAliasParams) error { + _, err := q.db.ExecContext(ctx, createAlias, arg.DomainID, arg.Source, arg.Destination) + return err +} + +const deleteAlias = `-- name: DeleteAlias :exec +DELETE FROM virtual_aliases WHERE id = ? +` + +func (q *Queries) DeleteAlias(ctx context.Context, id uint32) error { + _, err := q.db.ExecContext(ctx, deleteAlias, id) + return err +} + +const getAliasByID = `-- name: GetAliasByID :one +SELECT id, domain_id, source, destination FROM virtual_aliases WHERE id = ? +` + +func (q *Queries) GetAliasByID(ctx context.Context, id uint32) (VirtualAlias, error) { + row := q.db.QueryRowContext(ctx, getAliasByID, id) + var i VirtualAlias + err := row.Scan( + &i.ID, + &i.DomainID, + &i.Source, + &i.Destination, + ) + return i, err +} + +const getAliasBySource = `-- name: GetAliasBySource :one +SELECT id, domain_id, source, destination FROM virtual_aliases WHERE source = ? +` + +func (q *Queries) GetAliasBySource(ctx context.Context, source string) (VirtualAlias, error) { + row := q.db.QueryRowContext(ctx, getAliasBySource, source) + var i VirtualAlias + err := row.Scan( + &i.ID, + &i.DomainID, + &i.Source, + &i.Destination, + ) + return i, err +} + +const getAliasesByDomain = `-- name: GetAliasesByDomain :many +SELECT id, domain_id, source, destination FROM virtual_aliases WHERE domain_id = ? +` + +func (q *Queries) GetAliasesByDomain(ctx context.Context, domainID uint32) ([]VirtualAlias, error) { + rows, err := q.db.QueryContext(ctx, getAliasesByDomain, domainID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []VirtualAlias + for rows.Next() { + var i VirtualAlias + if err := rows.Scan( + &i.ID, + &i.DomainID, + &i.Source, + &i.Destination, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getAllAliases = `-- name: GetAllAliases :many +SELECT id, domain_id, source, destination FROM virtual_aliases +` + +func (q *Queries) GetAllAliases(ctx context.Context) ([]VirtualAlias, error) { + rows, err := q.db.QueryContext(ctx, getAllAliases) + if err != nil { + return nil, err + } + defer rows.Close() + var items []VirtualAlias + for rows.Next() { + var i VirtualAlias + if err := rows.Scan( + &i.ID, + &i.DomainID, + &i.Source, + &i.Destination, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/backend/internal/db/sqlc/db.go b/backend/internal/db/sqlc/db.go new file mode 100644 index 0000000..cd5bbb8 --- /dev/null +++ b/backend/internal/db/sqlc/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 + +package db + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/backend/internal/db/sqlc/domains.sql.go b/backend/internal/db/sqlc/domains.sql.go new file mode 100644 index 0000000..2304bb7 --- /dev/null +++ b/backend/internal/db/sqlc/domains.sql.go @@ -0,0 +1,128 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: domains.sql + +package db + +import ( + "context" + "database/sql" +) + +const createDomain = `-- name: CreateDomain :exec +INSERT INTO virtual_domains (name) VALUES (?) +` + +func (q *Queries) CreateDomain(ctx context.Context, name string) error { + _, err := q.db.ExecContext(ctx, createDomain, name) + return err +} + +const deleteDomain = `-- name: DeleteDomain :exec +DELETE FROM virtual_domains WHERE id = ? +` + +func (q *Queries) DeleteDomain(ctx context.Context, id uint32) error { + _, err := q.db.ExecContext(ctx, deleteDomain, id) + return err +} + +const getAllDomains = `-- name: GetAllDomains :many +SELECT id, name, created_at FROM virtual_domains ORDER BY name ASC +` + +func (q *Queries) GetAllDomains(ctx context.Context) ([]VirtualDomain, error) { + rows, err := q.db.QueryContext(ctx, getAllDomains) + if err != nil { + return nil, err + } + defer rows.Close() + var items []VirtualDomain + for rows.Next() { + var i VirtualDomain + if err := rows.Scan(&i.ID, &i.Name, &i.CreatedAt); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getAllDomainsWithCounts = `-- name: GetAllDomainsWithCounts :many +SELECT + d.id, + d.name, + d.created_at, + COALESCE(u.user_count, 0) as user_count, + COALESCE(a.alias_count, 0) as alias_count +FROM virtual_domains d +LEFT JOIN (SELECT domain_id, COUNT(*) as user_count FROM virtual_users GROUP BY domain_id) u ON u.domain_id = d.id +LEFT JOIN (SELECT domain_id, COUNT(*) as alias_count FROM virtual_aliases GROUP BY domain_id) a ON a.domain_id = d.id +ORDER BY d.name ASC +` + +type GetAllDomainsWithCountsRow struct { + ID uint32 `json:"id"` + Name string `json:"name"` + CreatedAt sql.NullTime `json:"created_at"` + UserCount int64 `json:"user_count"` + AliasCount int64 `json:"alias_count"` +} + +func (q *Queries) GetAllDomainsWithCounts(ctx context.Context) ([]GetAllDomainsWithCountsRow, error) { + rows, err := q.db.QueryContext(ctx, getAllDomainsWithCounts) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetAllDomainsWithCountsRow + for rows.Next() { + var i GetAllDomainsWithCountsRow + if err := rows.Scan( + &i.ID, + &i.Name, + &i.CreatedAt, + &i.UserCount, + &i.AliasCount, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getDomainByID = `-- name: GetDomainByID :one +SELECT id, name, created_at FROM virtual_domains WHERE id = ? +` + +func (q *Queries) GetDomainByID(ctx context.Context, id uint32) (VirtualDomain, error) { + row := q.db.QueryRowContext(ctx, getDomainByID, id) + var i VirtualDomain + err := row.Scan(&i.ID, &i.Name, &i.CreatedAt) + return i, err +} + +const getDomainByName = `-- name: GetDomainByName :one +SELECT id, name, created_at FROM virtual_domains WHERE name = ? +` + +func (q *Queries) GetDomainByName(ctx context.Context, name string) (VirtualDomain, error) { + row := q.db.QueryRowContext(ctx, getDomainByName, name) + var i VirtualDomain + err := row.Scan(&i.ID, &i.Name, &i.CreatedAt) + return i, err +} diff --git a/backend/internal/db/sqlc/imc_users.sql.go b/backend/internal/db/sqlc/imc_users.sql.go new file mode 100644 index 0000000..dbb707d --- /dev/null +++ b/backend/internal/db/sqlc/imc_users.sql.go @@ -0,0 +1,233 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: imc_users.sql + +package db + +import ( + "context" +) + +const addUserToDomain = `-- name: AddUserToDomain :exec +INSERT INTO imc_users2domains (user_id, domain_id) VALUES (?, ?) +` + +type AddUserToDomainParams struct { + UserID uint32 `json:"user_id"` + DomainID uint32 `json:"domain_id"` +} + +func (q *Queries) AddUserToDomain(ctx context.Context, arg AddUserToDomainParams) error { + _, err := q.db.ExecContext(ctx, addUserToDomain, arg.UserID, arg.DomainID) + return err +} + +const createImcUser = `-- name: CreateImcUser :exec +INSERT INTO imc_users (username, password_hash, role, domain_id) VALUES (?, ?, ?, ?) +` + +type CreateImcUserParams struct { + Username string `json:"username"` + PasswordHash string `json:"password_hash"` + Role NullImcUsersRole `json:"role"` + DomainID uint32 `json:"domain_id"` +} + +func (q *Queries) CreateImcUser(ctx context.Context, arg CreateImcUserParams) error { + _, err := q.db.ExecContext(ctx, createImcUser, + arg.Username, + arg.PasswordHash, + arg.Role, + arg.DomainID, + ) + return err +} + +const deleteImcUser = `-- name: DeleteImcUser :exec +DELETE FROM imc_users WHERE id = ? +` + +func (q *Queries) DeleteImcUser(ctx context.Context, id uint32) error { + _, err := q.db.ExecContext(ctx, deleteImcUser, id) + return err +} + +const getAdditionalDomainsForUser = `-- name: GetAdditionalDomainsForUser :many +SELECT virtual_domains.id, virtual_domains.name, virtual_domains.created_at FROM virtual_domains +JOIN imc_users2domains ON virtual_domains.id = imc_users2domains.domain_id +WHERE imc_users2domains.user_id = ? +` + +func (q *Queries) GetAdditionalDomainsForUser(ctx context.Context, userID uint32) ([]VirtualDomain, error) { + rows, err := q.db.QueryContext(ctx, getAdditionalDomainsForUser, userID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []VirtualDomain + for rows.Next() { + var i VirtualDomain + if err := rows.Scan(&i.ID, &i.Name, &i.CreatedAt); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getImcUserByID = `-- name: GetImcUserByID :one +SELECT id, username, password_hash, role, domain_id, created_at FROM imc_users WHERE id = ? +` + +func (q *Queries) GetImcUserByID(ctx context.Context, id uint32) (ImcUser, error) { + row := q.db.QueryRowContext(ctx, getImcUserByID, id) + var i ImcUser + err := row.Scan( + &i.ID, + &i.Username, + &i.PasswordHash, + &i.Role, + &i.DomainID, + &i.CreatedAt, + ) + return i, err +} + +const getImcUserByUsername = `-- name: GetImcUserByUsername :one +SELECT id, username, password_hash, role, domain_id, created_at FROM imc_users WHERE username = ? +` + +func (q *Queries) GetImcUserByUsername(ctx context.Context, username string) (ImcUser, error) { + row := q.db.QueryRowContext(ctx, getImcUserByUsername, username) + var i ImcUser + err := row.Scan( + &i.ID, + &i.Username, + &i.PasswordHash, + &i.Role, + &i.DomainID, + &i.CreatedAt, + ) + return i, err +} + +const getUsersForDomain = `-- name: GetUsersForDomain :many +SELECT imc_users.id, imc_users.username, imc_users.password_hash, imc_users.role, imc_users.domain_id, imc_users.created_at FROM imc_users WHERE domain_id = ? +` + +func (q *Queries) GetUsersForDomain(ctx context.Context, domainID uint32) ([]ImcUser, error) { + rows, err := q.db.QueryContext(ctx, getUsersForDomain, domainID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ImcUser + for rows.Next() { + var i ImcUser + if err := rows.Scan( + &i.ID, + &i.Username, + &i.PasswordHash, + &i.Role, + &i.DomainID, + &i.CreatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getUsersForDomainViaJoin = `-- name: GetUsersForDomainViaJoin :many +SELECT imc_users.id, imc_users.username, imc_users.password_hash, imc_users.role, imc_users.domain_id, imc_users.created_at FROM imc_users +JOIN imc_users2domains ON imc_users.id = imc_users2domains.user_id +WHERE imc_users2domains.domain_id = ? +` + +func (q *Queries) GetUsersForDomainViaJoin(ctx context.Context, domainID uint32) ([]ImcUser, error) { + rows, err := q.db.QueryContext(ctx, getUsersForDomainViaJoin, domainID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ImcUser + for rows.Next() { + var i ImcUser + if err := rows.Scan( + &i.ID, + &i.Username, + &i.PasswordHash, + &i.Role, + &i.DomainID, + &i.CreatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const isUserInDomain = `-- name: IsUserInDomain :one +SELECT COUNT(*) as count FROM imc_users2domains WHERE user_id = ? AND domain_id = ? +` + +type IsUserInDomainParams struct { + UserID uint32 `json:"user_id"` + DomainID uint32 `json:"domain_id"` +} + +func (q *Queries) IsUserInDomain(ctx context.Context, arg IsUserInDomainParams) (int64, error) { + row := q.db.QueryRowContext(ctx, isUserInDomain, arg.UserID, arg.DomainID) + var count int64 + err := row.Scan(&count) + return count, err +} + +const removeUserFromDomain = `-- name: RemoveUserFromDomain :exec +DELETE FROM imc_users2domains WHERE user_id = ? AND domain_id = ? +` + +type RemoveUserFromDomainParams struct { + UserID uint32 `json:"user_id"` + DomainID uint32 `json:"domain_id"` +} + +func (q *Queries) RemoveUserFromDomain(ctx context.Context, arg RemoveUserFromDomainParams) error { + _, err := q.db.ExecContext(ctx, removeUserFromDomain, arg.UserID, arg.DomainID) + return err +} + +const updateImcUserPassword = `-- name: UpdateImcUserPassword :exec +UPDATE imc_users SET password_hash = ? WHERE id = ? +` + +type UpdateImcUserPasswordParams struct { + PasswordHash string `json:"password_hash"` + ID uint32 `json:"id"` +} + +func (q *Queries) UpdateImcUserPassword(ctx context.Context, arg UpdateImcUserPasswordParams) error { + _, err := q.db.ExecContext(ctx, updateImcUserPassword, arg.PasswordHash, arg.ID) + return err +} diff --git a/backend/internal/db/sqlc/models.go b/backend/internal/db/sqlc/models.go new file mode 100644 index 0000000..21d0a66 --- /dev/null +++ b/backend/internal/db/sqlc/models.go @@ -0,0 +1,98 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 + +package db + +import ( + "database/sql" + "database/sql/driver" + "fmt" +) + +type ImcUsersRole string + +const ( + ImcUsersRoleAdmin ImcUsersRole = "admin" + ImcUsersRoleUser ImcUsersRole = "user" +) + +func (e *ImcUsersRole) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = ImcUsersRole(s) + case string: + *e = ImcUsersRole(s) + default: + return fmt.Errorf("unsupported scan type for ImcUsersRole: %T", src) + } + return nil +} + +type NullImcUsersRole struct { + ImcUsersRole ImcUsersRole `json:"imc_users_role"` + Valid bool `json:"valid"` // Valid is true if ImcUsersRole is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullImcUsersRole) Scan(value interface{}) error { + if value == nil { + ns.ImcUsersRole, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.ImcUsersRole.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullImcUsersRole) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.ImcUsersRole), nil +} + +type ImcLoginAttempt struct { + ID uint32 `json:"id"` + Username string `json:"username"` + IpAddress string `json:"ip_address"` + AttemptedAt sql.NullTime `json:"attempted_at"` + Successful sql.NullBool `json:"successful"` +} + +type ImcUser struct { + ID uint32 `json:"id"` + Username string `json:"username"` + PasswordHash string `json:"password_hash"` + Role NullImcUsersRole `json:"role"` + DomainID uint32 `json:"domain_id"` + CreatedAt sql.NullTime `json:"created_at"` +} + +type ImcUsers2domain struct { + ID uint32 `json:"id"` + UserID uint32 `json:"user_id"` + DomainID uint32 `json:"domain_id"` + CreatedAt sql.NullTime `json:"created_at"` +} + +type VirtualAlias struct { + ID uint32 `json:"id"` + DomainID uint32 `json:"domain_id"` + Source string `json:"source"` + Destination string `json:"destination"` +} + +type VirtualDomain struct { + ID uint32 `json:"id"` + Name string `json:"name"` + CreatedAt sql.NullTime `json:"created_at"` +} + +type VirtualUser struct { + ID uint32 `json:"id"` + DomainID uint32 `json:"domain_id"` + Email string `json:"email"` + Password string `json:"password"` + Quota sql.NullInt64 `json:"quota"` +} diff --git a/backend/internal/db/sqlc/users.sql.go b/backend/internal/db/sqlc/users.sql.go new file mode 100644 index 0000000..0d8a4b1 --- /dev/null +++ b/backend/internal/db/sqlc/users.sql.go @@ -0,0 +1,180 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: users.sql + +package db + +import ( + "context" + "database/sql" +) + +const countUsersByDomain = `-- name: CountUsersByDomain :one +SELECT COUNT(*) as count FROM virtual_users WHERE domain_id = ? +` + +func (q *Queries) CountUsersByDomain(ctx context.Context, domainID uint32) (int64, error) { + row := q.db.QueryRowContext(ctx, countUsersByDomain, domainID) + var count int64 + err := row.Scan(&count) + return count, err +} + +const createUser = `-- name: CreateUser :exec +INSERT INTO virtual_users (domain_id, email, password, quota) VALUES (?, ?, ?, ?) +` + +type CreateUserParams struct { + DomainID uint32 `json:"domain_id"` + Email string `json:"email"` + Password string `json:"password"` + Quota sql.NullInt64 `json:"quota"` +} + +func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) error { + _, err := q.db.ExecContext(ctx, createUser, + arg.DomainID, + arg.Email, + arg.Password, + arg.Quota, + ) + return err +} + +const deleteUser = `-- name: DeleteUser :exec +DELETE FROM virtual_users WHERE id = ? +` + +func (q *Queries) DeleteUser(ctx context.Context, id uint32) error { + _, err := q.db.ExecContext(ctx, deleteUser, id) + return err +} + +const getAllMailUsers = `-- name: GetAllMailUsers :many +SELECT id, domain_id, email, password, quota FROM virtual_users +` + +func (q *Queries) GetAllMailUsers(ctx context.Context) ([]VirtualUser, error) { + rows, err := q.db.QueryContext(ctx, getAllMailUsers) + if err != nil { + return nil, err + } + defer rows.Close() + var items []VirtualUser + for rows.Next() { + var i VirtualUser + if err := rows.Scan( + &i.ID, + &i.DomainID, + &i.Email, + &i.Password, + &i.Quota, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getUserByEmail = `-- name: GetUserByEmail :one +SELECT id, domain_id, email, password, quota FROM virtual_users WHERE email = ? +` + +func (q *Queries) GetUserByEmail(ctx context.Context, email string) (VirtualUser, error) { + row := q.db.QueryRowContext(ctx, getUserByEmail, email) + var i VirtualUser + err := row.Scan( + &i.ID, + &i.DomainID, + &i.Email, + &i.Password, + &i.Quota, + ) + return i, err +} + +const getUserByID = `-- name: GetUserByID :one +SELECT id, domain_id, email, password, quota FROM virtual_users WHERE id = ? +` + +func (q *Queries) GetUserByID(ctx context.Context, id uint32) (VirtualUser, error) { + row := q.db.QueryRowContext(ctx, getUserByID, id) + var i VirtualUser + err := row.Scan( + &i.ID, + &i.DomainID, + &i.Email, + &i.Password, + &i.Quota, + ) + return i, err +} + +const getUsersByDomain = `-- name: GetUsersByDomain :many +SELECT id, domain_id, email, password, quota FROM virtual_users WHERE domain_id = ? +` + +func (q *Queries) GetUsersByDomain(ctx context.Context, domainID uint32) ([]VirtualUser, error) { + rows, err := q.db.QueryContext(ctx, getUsersByDomain, domainID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []VirtualUser + for rows.Next() { + var i VirtualUser + if err := rows.Scan( + &i.ID, + &i.DomainID, + &i.Email, + &i.Password, + &i.Quota, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const updateUserPassword = `-- name: UpdateUserPassword :exec +UPDATE virtual_users SET password = ? WHERE id = ? +` + +type UpdateUserPasswordParams struct { + Password string `json:"password"` + ID uint32 `json:"id"` +} + +func (q *Queries) UpdateUserPassword(ctx context.Context, arg UpdateUserPasswordParams) error { + _, err := q.db.ExecContext(ctx, updateUserPassword, arg.Password, arg.ID) + return err +} + +const updateUserQuota = `-- name: UpdateUserQuota :exec +UPDATE virtual_users SET quota = ? WHERE id = ? +` + +type UpdateUserQuotaParams struct { + Quota sql.NullInt64 `json:"quota"` + ID uint32 `json:"id"` +} + +func (q *Queries) UpdateUserQuota(ctx context.Context, arg UpdateUserQuotaParams) error { + _, err := q.db.ExecContext(ctx, updateUserQuota, arg.Quota, arg.ID) + return err +} diff --git a/backend/internal/db/users.go b/backend/internal/db/users.go deleted file mode 100644 index 7653f51..0000000 --- a/backend/internal/db/users.go +++ /dev/null @@ -1,76 +0,0 @@ -package db - -func (d *DB) GetAllMailUsers() ([]User, error) { - var users []User - if err := d.Preload("Domain").Find(&users).Error; err != nil { - return nil, err - } - if users == nil { - users = []User{} - } - return users, nil -} - -func (d *DB) GetUsersByDomain(domainID uint) ([]User, error) { - var users []User - if err := d.Where("domain_id = ?", domainID).Find(&users).Error; err != nil { - return nil, err - } - if users == nil { - users = []User{} - } - return users, nil -} - -func (d *DB) GetUserByID(id uint) (*User, error) { - var user User - if err := d.Preload("Domain").First(&user, id).Error; err != nil { - return nil, err - } - return &user, nil -} - -func (d *DB) GetUserByEmail(email string) (*User, error) { - var user User - if err := d.Where("email = ?", email).First(&user).Error; err != nil { - return nil, err - } - return &user, nil -} - -func (d *DB) CreateUser(email, passwordHash string, quota int64) (*User, error) { - user := User{ - Email: email, - Password: passwordHash, - Quota: quota, - } - if err := d.Create(&user).Error; err != nil { - return nil, err - } - return &user, nil -} - -func (d *DB) CreateUserInDomain(email, passwordHash string, quota int64, domainID uint) (*User, error) { - user := User{ - DomainID: domainID, - Email: email, - Password: passwordHash, - Quota: quota, - } - if err := d.Create(&user).Error; err != nil { - return nil, err - } - return &user, nil -} - -func (d *DB) UpdateUserPassword(id uint, passwordHash string) error { - return d.Model(&User{}).Where("id = ?", id).Update("password", passwordHash).Error -} - -func (d *DB) UpdateUserQuota(id uint, quota int64) error { - return d.Model(&User{}).Where("id = ?", id).Update("quota", quota).Error -} - -func (d *DB) DeleteUser(id uint) error { - return d.Delete(&User{}, id).Error -} diff --git a/backend/internal/db/virtual_aliases.go b/backend/internal/db/virtual_aliases.go new file mode 100644 index 0000000..70e51ed --- /dev/null +++ b/backend/internal/db/virtual_aliases.go @@ -0,0 +1,35 @@ +package db + +import ( + "context" + + imcdb "git.workaround.org/chaas/imc/backend/internal/db/sqlc" +) + +func (d *DB) GetAllAliases(ctx context.Context) ([]imcdb.VirtualAlias, error) { + return d.Queries.GetAllAliases(ctx) +} + +func (d *DB) GetAliasesByDomain(ctx context.Context, domainID uint32) ([]imcdb.VirtualAlias, error) { + return d.Queries.GetAliasesByDomain(ctx, domainID) +} + +func (d *DB) GetAliasByID(ctx context.Context, id uint32) (imcdb.VirtualAlias, error) { + return d.Queries.GetAliasByID(ctx, id) +} + +func (d *DB) GetAliasBySource(ctx context.Context, source string) (imcdb.VirtualAlias, error) { + return d.Queries.GetAliasBySource(ctx, source) +} + +func (d *DB) CreateAlias(ctx context.Context, domainID uint32, source, destination string) error { + return d.Queries.CreateAlias(ctx, imcdb.CreateAliasParams{ + DomainID: domainID, + Source: source, + Destination: destination, + }) +} + +func (d *DB) DeleteAlias(ctx context.Context, id uint32) error { + return d.Queries.DeleteAlias(ctx, id) +} diff --git a/backend/internal/db/virtual_domains.go b/backend/internal/db/virtual_domains.go new file mode 100644 index 0000000..79d38e2 --- /dev/null +++ b/backend/internal/db/virtual_domains.go @@ -0,0 +1,53 @@ +package db + +import ( + "context" + + imcdb "git.workaround.org/chaas/imc/backend/internal/db/sqlc" +) + +func (d *DB) GetAllDomains(ctx context.Context) ([]imcdb.VirtualDomain, error) { + return d.Queries.GetAllDomains(ctx) +} + +func (d *DB) GetDomainByID(ctx context.Context, id uint32) (imcdb.VirtualDomain, error) { + return d.Queries.GetDomainByID(ctx, id) +} + +func (d *DB) GetDomainByName(ctx context.Context, name string) (imcdb.VirtualDomain, error) { + return d.Queries.GetDomainByName(ctx, name) +} + +func (d *DB) CreateDomain(ctx context.Context, name string) error { + return d.Queries.CreateDomain(ctx, name) +} + +func (d *DB) DeleteDomain(ctx context.Context, id uint32) error { + return d.Queries.DeleteDomain(ctx, id) +} + +func (d *DB) GetAllDomainsWithCounts(ctx context.Context) ([]DomainStats, error) { + results, err := d.Queries.GetAllDomainsWithCounts(ctx) + if err != nil { + return nil, err + } + + stats := make([]DomainStats, len(results)) + for i, r := range results { + stats[i] = DomainStats{ + ID: r.ID, + Name: r.Name, + UserCount: r.UserCount, + AliasCount: r.AliasCount, + } + } + return stats, nil +} + +func (d *DB) CountUsersByDomain(ctx context.Context, domainID uint32) (int64, error) { + return d.Queries.CountUsersByDomain(ctx, domainID) +} + +func (d *DB) CountAliasesByDomain(ctx context.Context, domainID uint32) (int64, error) { + return d.Queries.CountAliasesByDomain(ctx, domainID) +} diff --git a/backend/internal/db/virtual_users.go b/backend/internal/db/virtual_users.go new file mode 100644 index 0000000..9150b38 --- /dev/null +++ b/backend/internal/db/virtual_users.go @@ -0,0 +1,54 @@ +package db + +import ( + "context" + + "database/sql" + + imcdb "git.workaround.org/chaas/imc/backend/internal/db/sqlc" +) + +func (d *DB) GetAllMailUsers(ctx context.Context) ([]imcdb.VirtualUser, error) { + return d.Queries.GetAllMailUsers(ctx) +} + +func (d *DB) GetUsersByDomain(ctx context.Context, domainID uint32) ([]imcdb.VirtualUser, error) { + return d.Queries.GetUsersByDomain(ctx, domainID) +} + +func (d *DB) GetUserByID(ctx context.Context, id uint32) (imcdb.VirtualUser, error) { + return d.Queries.GetUserByID(ctx, id) +} + +func (d *DB) GetUserByEmail(ctx context.Context, email string) (imcdb.VirtualUser, error) { + return d.Queries.GetUserByEmail(ctx, email) +} + +func (d *DB) CreateUser(ctx context.Context, domainID uint32, email, passwordHash string, quota int64) error { + quotaNull := sql.NullInt64{Int64: quota, Valid: true} + return d.Queries.CreateUser(ctx, imcdb.CreateUserParams{ + DomainID: domainID, + Email: email, + Password: passwordHash, + Quota: quotaNull, + }) +} + +func (d *DB) UpdateUserPassword(ctx context.Context, id uint32, passwordHash string) error { + return d.Queries.UpdateUserPassword(ctx, imcdb.UpdateUserPasswordParams{ + Password: passwordHash, + ID: id, + }) +} + +func (d *DB) UpdateUserQuota(ctx context.Context, id uint32, quota int64) error { + quotaNull := sql.NullInt64{Int64: quota, Valid: true} + return d.Queries.UpdateUserQuota(ctx, imcdb.UpdateUserQuotaParams{ + Quota: quotaNull, + ID: id, + }) +} + +func (d *DB) DeleteUser(ctx context.Context, id uint32) error { + return d.Queries.DeleteUser(ctx, id) +} diff --git a/backend/internal/mail/email.go b/backend/internal/mail/email.go deleted file mode 100644 index 64e0f45..0000000 --- a/backend/internal/mail/email.go +++ /dev/null @@ -1,190 +0,0 @@ -// Package mail provides email sending functionality for password reset emails. -// Uses Go's net/smtp package for sending emails via SMTP protocol. -package mail - -import ( - "crypto/rand" // cryptographically secure random number generator - "crypto/tls" // TLS/SSL encryption for secure email sending - "encoding/hex" // hex encoding for token generation - "fmt" // string formatting for URLs and messages - "net/smtp" // simple mail transfer protocol package - - "github.com/imc-vibe/backend/internal/config" -) - -// EmailService handles sending emails through SMTP. -// Stores SMTP configuration and provides methods for different email types. -type EmailService struct { - host string // SMTP server hostname (e.g., "smtp.example.com") - port string // SMTP server port (e.g., "587" for TLS, "465" for SSL) - username string // SMTP authentication username - password string // SMTP authentication password - from string // Sender email address (e.g., "noreply@example.com") - baseURL string // Base URL of the web application (for building reset links) -} - -// NewEmailService creates a new EmailService instance from configuration. -// cfg: application configuration containing SMTP settings and base URL. -func NewEmailService(cfg *config.Config) *EmailService { - return &EmailService{ - host: cfg.SMTPHost, - port: cfg.SMTPPort, - username: cfg.SMTPUser, - password: cfg.SMTPPassword, - from: cfg.SMTPFrom, - baseURL: cfg.BaseURL, - } -} - -// SendPasswordReset sends a password reset email to the user. -// to: recipient email address -// token: unique reset token that was generated and stored in the database -// The email contains a clickable link to reset the password. -func (s *EmailService) SendPasswordReset(to, token string) error { - // Build the reset URL with the token as a query parameter. - // Example: https://mail.example.com/auth/reset-password?token=abc123... - resetURL := fmt.Sprintf("%s/auth/reset-password?token=%s", s.baseURL, token) - - // Compose the email subject and body. - subject := "Password Reset Request" - body := fmt.Sprintf(`Hi, - -You requested a password reset for your account. - -Click the link below to reset your password: -%s - -This link will expire in 1 hour. - -If you didn't request this, please ignore this email. - -Best regards, -IMC Vibe Mail Server Admin -`, resetURL) - - // Send the email using the send method. - return s.send(to, subject, body) -} - -// send is the internal method that actually sends the email via SMTP. -// Handles both port 587 (TLS) and port 465 (SSL) connections. -func (s *EmailService) send(to, subject, body string) error { - // Check if SMTP is configured. If not, return an error. - if s.host == "" || s.username == "" { - return fmt.Errorf("SMTP not configured") - } - - // Build the server address in host:port format. - addr := fmt.Sprintf("%s:%s", s.host, s.port) - - // Build the email message with headers. - // \r\n is the standard line ending for email headers and body. - msg := fmt.Sprintf("From: %s\r\n"+ - "To: %s\r\n"+ - "Subject: %s\r\n"+ - "MIME-Version: 1.0\r\n"+ - "Content-Type: text/plain; charset=\"UTF-8\"\r\n"+ - "\r\n"+ - "%s", s.from, to, subject, body) - - // Port 465 uses implicit SSL/TLS, port 587 uses STARTTLS. - // Both are secure, but they work differently. - var auth smtp.Auth - if s.port == "465" { - // For port 465, we need to establish a TLS connection first - // before sending anything, then upgrade the connection. - err := s.sendWithTLS(addr, to, msg) - return err - } else { - // For other ports (usually 587), use STARTTLS which upgrades - // a plain connection to TLS after connecting. - auth = smtp.PlainAuth("", s.username, s.password, s.host) - err := smtp.SendMail(addr, auth, s.from, []string{to}, []byte(msg)) - return err - } -} - -// sendWithTLS sends an email using an explicit TLS connection on port 465. -// Port 465 uses implicit TLS - the entire connection is encrypted from the start. -func (s *EmailService) sendWithTLS(addr, to, msg string) error { - // Create a TLS configuration for the secure connection. - // ServerName must match the SMTP server's certificate. - tlsConfig := &tls.Config{ - ServerName: s.host, - } - - // Establish a TLS connection to the SMTP server. - // This creates an encrypted tunnel from the start. - conn, err := tls.Dial("tcp", addr, tlsConfig) - if err != nil { - return err - } - defer conn.Close() // Ensure connection is closed when we're done - - // Create an SMTP client on top of the TLS connection. - client, err := smtp.NewClient(conn, s.host) - if err != nil { - return err - } - defer client.Close() - - // Authenticate with the SMTP server using PLAIN authentication. - // The empty string "" is the identity (usually same as username). - auth := smtp.PlainAuth("", s.username, s.password, s.host) - if err := client.Auth(auth); err != nil { - return err - } - - // Set the sender (MAIL FROM command). - if err := client.Mail(s.from); err != nil { - return err - } - - // Set the recipient (RCPT TO command). - if err := client.Rcpt(to); err != nil { - return err - } - - // Start sending the message body (DATA command). - w, err := client.Data() - if err != nil { - return err - } - - // Write the email body to the data stream. - _, err = w.Write([]byte(msg)) - if err != nil { - return err - } - - // Close the data writer to finish the message. - err = w.Close() - if err != nil { - return err - } - - // Send the QUIT command to gracefully close the connection. - return client.Quit() -} - -// GenerateToken creates a cryptographically random token for password reset links. -// Returns a 64-character hexadecimal string (32 bytes encoded as hex). -// Uses crypto/rand for security-sensitive token generation. -func GenerateToken() string { - b := make([]byte, 32) - if _, err := rand.Read(b); err != nil { - panic("crypto/rand failed: " + err.Error()) - } - return hex.EncodeToString(b) -} - -// ValidateToken checks if a token has the correct format. -// Returns true if the token is exactly 64 characters of valid hex. -// This is a quick validation before checking the database. -func ValidateToken(token string) bool { - if len(token) != 64 { - return false - } - _, err := hex.DecodeString(token) - return err == nil -} diff --git a/backend/sqlc.yaml b/backend/sqlc.yaml new file mode 100644 index 0000000..83c02dd --- /dev/null +++ b/backend/sqlc.yaml @@ -0,0 +1,13 @@ +version: "2" +sql: + - engine: "mysql" + queries: "./internal/db/queries" + schema: "./internal/db/queries/schema.sql" + gen: + go: + package: "db" + out: "./internal/db/sqlc" + sql_package: "database/sql" + emit_json_tags: true + emit_interface: false + emit_exact_table_names: false diff --git a/frontend/bun.lock b/frontend/bun.lock index 87e06b4..112a1ad 100644 --- a/frontend/bun.lock +++ b/frontend/bun.lock @@ -3,7 +3,7 @@ "configVersion": 1, "workspaces": { "": { - "name": "imc-vibe-frontend", + "name": "imc-frontend", "devDependencies": { "@sveltejs/adapter-static": "^3.0.0", "@sveltejs/kit": "^2.0.0", @@ -14,6 +14,7 @@ "daisyui": "^5.5.19", "postcss": "^8.5.8", "svelte": "^5.0.0", + "svelte-heros": "^8.0.1", "tailwindcss": "^4.2.2", "typescript": "^5.0.0", "vite": "^5.0.0", @@ -79,55 +80,55 @@ "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.1", "", { "os": "android", "cpu": "arm" }, "sha512-xB0b51TB7IfDEzAojXahmr+gfA00uYVInJGgNNkeQG6RPnCPGr7udsylFLTubuIUSRE6FkcI1NElyRt83PP5oQ=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.0", "", { "os": "android", "cpu": "arm" }, "sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.1", "", { "os": "android", "cpu": "arm64" }, "sha512-XOjPId0qwSDKHaIsdzHJtKCxX0+nH8MhBwvrNsT7tVyKmdTx1jJ4XzN5RZXCdTzMpufLb+B8llTC0D8uCrLhcw=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.60.0", "", { "os": "android", "cpu": "arm64" }, "sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.59.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-vQuRd28p0gQpPrS6kppd8IrWmFo42U8Pz1XLRjSZXq5zCqyMDYFABT7/sywL11mO1EL10Qhh7MVPEwkG8GiBeg=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.60.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.59.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-x6VG6U29+Ivlnajrg1IHdzXeAwSoEHBFVO+CtC9Brugx6de712CUJobRUxsIA0KYrQvCmzNrMPFTT1A4CCqNTg=="], + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.60.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.59.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-Sgi0Uo6t1YCHJMNO3Y8+bm+SvOanUGkoZKn/VJPwYUe2kp31X5KnXmzKd/NjW8iA3gFcfNZ64zh14uOGrIllCQ=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.60.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.59.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-AM4xnwEZwukdhk7laMWfzWu9JGSVnJd+Fowt6Fd7QW1nrf3h0Hp7Qx5881M4aqrUlKBCybOxz0jofvIIfl7C5g=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.60.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.59.1", "", { "os": "linux", "cpu": "arm" }, "sha512-KUizqxpwaR2AZdAUsMWfL/C94pUu7TKpoPd88c8yFVixJ+l9hejkrwoK5Zj3wiNh65UeyryKnJyxL1b7yNqFQA=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.60.0", "", { "os": "linux", "cpu": "arm" }, "sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.59.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MZoQ/am77ckJtZGFAtPucgUuJWiop3m2R3lw7tC0QCcbfl4DRhQUBUkHWCkcrT3pqy5Mzv5QQgY6Dmlba6iTWg=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.60.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.59.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-Sez95TP6xGjkWB1608EfhCX1gdGrO5wzyN99VqzRtC17x/1bhw5VU1V0GfKUwbW/Xr1J8mSasoFoJa6Y7aGGSA=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.60.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.59.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-9Cs2Seq98LWNOJzR89EGTZoiP8EkZ9UbQhBlDgfAkM6asVna1xJ04W2CLYWDN/RpUgOjtQvcv8wQVi1t5oQazA=="], + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.60.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ=="], - "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.59.1", "", { "os": "linux", "cpu": "none" }, "sha512-n9yqttftgFy7IrNEnHy1bOp6B4OSe8mJDiPkT7EqlM9FnKOwUMnCK62ixW0Kd9Clw0/wgvh8+SqaDXMFvw3KqQ=="], + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.60.0", "", { "os": "linux", "cpu": "none" }, "sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw=="], - "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.59.1", "", { "os": "linux", "cpu": "none" }, "sha512-SfpNXDzVTqs/riak4xXcLpq5gIQWsqGWMhN1AGRQKB4qGSs4r0sEs3ervXPcE1O9RsQ5bm8Muz6zmQpQnPss1g=="], + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.60.0", "", { "os": "linux", "cpu": "none" }, "sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog=="], - "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.59.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-LjaChED0wQnjKZU+tsmGbN+9nN1XhaWUkAlSbTdhpEseCS4a15f/Q8xC2BN4GDKRzhhLZpYtJBZr2NZhR0jvNw=="], + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.60.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ=="], - "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.59.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-ojW7iTJSIs4pwB2xV6QXGwNyDctvXOivYllttuPbXguuKDX5vwpqYJsHc6D2LZzjDGHML414Tuj3LvVPe1CT1A=="], + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.60.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.59.1", "", { "os": "linux", "cpu": "none" }, "sha512-FP+Q6WTcxxvsr0wQczhSE+tOZvFPV8A/mUE6mhZYFW9/eea/y/XqAgRoLLMuE9Cz0hfX5bi7p116IWoB+P237A=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.60.0", "", { "os": "linux", "cpu": "none" }, "sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA=="], - "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.59.1", "", { "os": "linux", "cpu": "none" }, "sha512-L1uD9b/Ig8Z+rn1KttCJjwhN1FgjRMBKsPaBsDKkfUl7GfFq71pU4vWCnpOsGljycFEbkHWARZLf4lMYg3WOLw=="], + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.60.0", "", { "os": "linux", "cpu": "none" }, "sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.59.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-EZc9NGTk/oSUzzOD4nYY4gIjteo2M3CiozX6t1IXGCOdgxJTlVu/7EdPeiqeHPSIrxkLhavqpBAUCfvC6vBOug=="], + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.60.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.59.1", "", { "os": "linux", "cpu": "x64" }, "sha512-NQ9KyU1Anuy59L8+HHOKM++CoUxrQWrZWXRik4BJFm+7i5NP6q/SW43xIBr80zzt+PDBJ7LeNmloQGfa0JGk0w=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.60.0", "", { "os": "linux", "cpu": "x64" }, "sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.59.1", "", { "os": "linux", "cpu": "x64" }, "sha512-GZkLk2t6naywsveSFBsEb0PLU+JC9ggVjbndsbG20VPhar6D1gkMfCx4NfP9owpovBXTN+eRdqGSkDGIxPHhmQ=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.60.0", "", { "os": "linux", "cpu": "x64" }, "sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw=="], - "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.59.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-1hjG9Jpl2KDOetr64iQd8AZAEjkDUUK5RbDkYWsViYLC1op1oNzdjMJeFiofcGhqbNTaY2kfgqowE7DILifsrA=="], + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.60.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw=="], - "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.59.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ARoKfflk0SiiYm3r1fmF73K/yB+PThmOwfWCk1sr7x/k9dc3uGLWuEE9if+Pw21el8MSpp3TMnG5vLNsJ/MMGQ=="], + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.60.0", "", { "os": "none", "cpu": "arm64" }, "sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.59.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-oOST61G6VM45Mz2vdzWMr1s2slI7y9LqxEV5fCoWi2MDONmMvgsJVHSXxce/I2xOSZPTZ47nDPOl1tkwKWSHcw=="], + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.60.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.59.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-x5WgLi5dWpRz7WclKBGEF15LcWTh0ewrHM6Cq4A+WUbkysUMZNeqt05bwPonOQ3ihPS/WMhAZV5zB1DfnI4Sxg=="], + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.60.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w=="], - "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.59.1", "", { "os": "win32", "cpu": "x64" }, "sha512-wS+zHAJRVP5zOL0e+a3V3E/NTEwM2HEvvNKoDy5Xcfs0o8lljxn+EAFPkUsxihBdmDq1JWzXmmB9cbssCPdxxw=="], + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.60.0", "", { "os": "win32", "cpu": "x64" }, "sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.59.1", "", { "os": "win32", "cpu": "x64" }, "sha512-rhHyrMeLpErT/C7BxcEsU4COHQUzHyrPYW5tOZUeUhziNtRuYxmDWvqQqzpuUt8xpOgmbKa1btGXfnA/ANVO+g=="], + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.60.0", "", { "os": "win32", "cpu": "x64" }, "sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w=="], "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], @@ -179,7 +180,7 @@ "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], - "@typescript-eslint/types": ["@typescript-eslint/types@8.57.1", "", {}, "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ=="], + "@typescript-eslint/types": ["@typescript-eslint/types@8.57.2", "", {}, "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA=="], "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], @@ -211,7 +212,7 @@ "devalue": ["devalue@5.6.4", "", {}, "sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA=="], - "electron-to-chromium": ["electron-to-chromium@1.5.321", "", {}, "sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ=="], + "electron-to-chromium": ["electron-to-chromium@1.5.322", "", {}, "sha512-vFU34OcrvMcH66T+dYC3G4nURmgfDVewMIu6Q2urXpumAPSMmzvcn04KVVV8Opikq8Vs5nUbO/8laNhNRqSzYw=="], "enhanced-resolve": ["enhanced-resolve@5.20.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA=="], @@ -279,7 +280,7 @@ "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], - "rollup": ["rollup@4.59.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.1", "@rollup/rollup-android-arm64": "4.59.1", "@rollup/rollup-darwin-arm64": "4.59.1", "@rollup/rollup-darwin-x64": "4.59.1", "@rollup/rollup-freebsd-arm64": "4.59.1", "@rollup/rollup-freebsd-x64": "4.59.1", "@rollup/rollup-linux-arm-gnueabihf": "4.59.1", "@rollup/rollup-linux-arm-musleabihf": "4.59.1", "@rollup/rollup-linux-arm64-gnu": "4.59.1", "@rollup/rollup-linux-arm64-musl": "4.59.1", "@rollup/rollup-linux-loong64-gnu": "4.59.1", "@rollup/rollup-linux-loong64-musl": "4.59.1", "@rollup/rollup-linux-ppc64-gnu": "4.59.1", "@rollup/rollup-linux-ppc64-musl": "4.59.1", "@rollup/rollup-linux-riscv64-gnu": "4.59.1", "@rollup/rollup-linux-riscv64-musl": "4.59.1", "@rollup/rollup-linux-s390x-gnu": "4.59.1", "@rollup/rollup-linux-x64-gnu": "4.59.1", "@rollup/rollup-linux-x64-musl": "4.59.1", "@rollup/rollup-openbsd-x64": "4.59.1", "@rollup/rollup-openharmony-arm64": "4.59.1", "@rollup/rollup-win32-arm64-msvc": "4.59.1", "@rollup/rollup-win32-ia32-msvc": "4.59.1", "@rollup/rollup-win32-x64-gnu": "4.59.1", "@rollup/rollup-win32-x64-msvc": "4.59.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-iZKH8BeoCwTCBTZBZWQQMreekd4mdomwdjIQ40GC1oZm6o+8PnNMIxFOiCsGMWeS8iDJ7KZcl7KwmKk/0HOQpA=="], + "rollup": ["rollup@4.60.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.0", "@rollup/rollup-android-arm64": "4.60.0", "@rollup/rollup-darwin-arm64": "4.60.0", "@rollup/rollup-darwin-x64": "4.60.0", "@rollup/rollup-freebsd-arm64": "4.60.0", "@rollup/rollup-freebsd-x64": "4.60.0", "@rollup/rollup-linux-arm-gnueabihf": "4.60.0", "@rollup/rollup-linux-arm-musleabihf": "4.60.0", "@rollup/rollup-linux-arm64-gnu": "4.60.0", "@rollup/rollup-linux-arm64-musl": "4.60.0", "@rollup/rollup-linux-loong64-gnu": "4.60.0", "@rollup/rollup-linux-loong64-musl": "4.60.0", "@rollup/rollup-linux-ppc64-gnu": "4.60.0", "@rollup/rollup-linux-ppc64-musl": "4.60.0", "@rollup/rollup-linux-riscv64-gnu": "4.60.0", "@rollup/rollup-linux-riscv64-musl": "4.60.0", "@rollup/rollup-linux-s390x-gnu": "4.60.0", "@rollup/rollup-linux-x64-gnu": "4.60.0", "@rollup/rollup-linux-x64-musl": "4.60.0", "@rollup/rollup-openbsd-x64": "4.60.0", "@rollup/rollup-openharmony-arm64": "4.60.0", "@rollup/rollup-win32-arm64-msvc": "4.60.0", "@rollup/rollup-win32-ia32-msvc": "4.60.0", "@rollup/rollup-win32-x64-gnu": "4.60.0", "@rollup/rollup-win32-x64-msvc": "4.60.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ=="], "set-cookie-parser": ["set-cookie-parser@3.1.0", "", {}, "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw=="], @@ -287,11 +288,13 @@ "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], - "svelte": ["svelte@5.54.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.4", "esm-env": "^1.2.1", "esrap": "^2.2.2", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-TTDxwYnHkova6Wsyj1PGt9TByuWqvMoeY1bQiuAf2DM/JeDSMw7FjRKzk8K/5mJ99vGOKhbCqTDpyAKwjp4igg=="], + "svelte": ["svelte@5.55.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.6.4", "esm-env": "^1.2.1", "esrap": "^2.2.2", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-SThllKq6TRMBwPtat7ASnm/9CDXnIhBR0NPGw0ujn2DVYx9rVwsPZxDaDQcYGdUz/3BYVsCzdq7pZarRQoGvtw=="], + + "svelte-heros": ["svelte-heros@8.0.1", "", { "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-67rDThxmdbjvJxKDqDUnkTsmyI5JtXcS0S0Ryg/EmTlHscFyJNgJyEARX5/xt3ONsZA0i6+dWnq+EX5jH9Wq1Q=="], "tailwindcss": ["tailwindcss@4.2.2", "", {}, "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q=="], - "tapable": ["tapable@2.3.1", "", {}, "sha512-b+u3CEM6FjDHru+nhUSjDofpWSBp2rINziJWgApm72wwGasQ/wKXftZe4tI2Y5HPv6OpzXSZHOFq87H4vfsgsw=="], + "tapable": ["tapable@2.3.2", "", {}, "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA=="], "totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="], diff --git a/frontend/node_modules/@rollup/rollup-linux-x64-gnu/package.json b/frontend/node_modules/@rollup/rollup-linux-x64-gnu/package.json index 73c5d95..ed14735 100644 --- a/frontend/node_modules/@rollup/rollup-linux-x64-gnu/package.json +++ b/frontend/node_modules/@rollup/rollup-linux-x64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@rollup/rollup-linux-x64-gnu", - "version": "4.59.1", + "version": "4.60.0", "os": [ "linux" ], diff --git a/frontend/node_modules/@rollup/rollup-linux-x64-gnu/rollup.linux-x64-gnu.node b/frontend/node_modules/@rollup/rollup-linux-x64-gnu/rollup.linux-x64-gnu.node index 2fd5af4..a71e754 100644 Binary files a/frontend/node_modules/@rollup/rollup-linux-x64-gnu/rollup.linux-x64-gnu.node and b/frontend/node_modules/@rollup/rollup-linux-x64-gnu/rollup.linux-x64-gnu.node differ diff --git a/frontend/node_modules/@rollup/rollup-linux-x64-musl/package.json b/frontend/node_modules/@rollup/rollup-linux-x64-musl/package.json index 1919beb..df5f5a6 100644 --- a/frontend/node_modules/@rollup/rollup-linux-x64-musl/package.json +++ b/frontend/node_modules/@rollup/rollup-linux-x64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@rollup/rollup-linux-x64-musl", - "version": "4.59.1", + "version": "4.60.0", "os": [ "linux" ], diff --git a/frontend/node_modules/@rollup/rollup-linux-x64-musl/rollup.linux-x64-musl.node b/frontend/node_modules/@rollup/rollup-linux-x64-musl/rollup.linux-x64-musl.node index 84546fa..418e89f 100644 Binary files a/frontend/node_modules/@rollup/rollup-linux-x64-musl/rollup.linux-x64-musl.node and b/frontend/node_modules/@rollup/rollup-linux-x64-musl/rollup.linux-x64-musl.node differ diff --git a/frontend/node_modules/@typescript-eslint/types/package.json b/frontend/node_modules/@typescript-eslint/types/package.json index f3d1bab..81f4f1b 100644 --- a/frontend/node_modules/@typescript-eslint/types/package.json +++ b/frontend/node_modules/@typescript-eslint/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "8.57.1", + "version": "8.57.2", "description": "Types for the TypeScript-ESTree AST spec", "files": [ "dist", diff --git a/frontend/node_modules/rollup/dist/bin/rollup b/frontend/node_modules/rollup/dist/bin/rollup index 7d642e3..d2f8b49 100755 --- a/frontend/node_modules/rollup/dist/bin/rollup +++ b/frontend/node_modules/rollup/dist/bin/rollup @@ -1,8 +1,8 @@ #!/usr/bin/env node /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup @@ -27,7 +27,7 @@ require('node:perf_hooks'); require('node:url'); require('../getLogFilter.js'); -const help = "rollup version 4.59.1\n=====================================\n\nUsage: rollup [options] \n\nOptions:\n\n-c, --config Use this config file (if argument is used but value\n is unspecified, Rollup will try to load configuration files in\n the following order:\n rollup.config.mjs -> rollup.config.cjs -> rollup.config.js)\n-d, --dir Directory for chunks (if absent, prints to stdout)\n-e, --external Comma-separate list of module IDs to exclude\n-f, --format Type of output (amd, cjs, es, iife, umd, system)\n-g, --globals Comma-separate list of `moduleID:Global` pairs\n-h, --help Show this help message\n-i, --input Input (alternative to )\n-m, --sourcemap Generate sourcemap (`-m inline` for inline map)\n-n, --name Name for UMD export\n-o, --file Single output file (if absent, prints to stdout)\n-p, --plugin Use the plugin specified (may be repeated)\n-v, --version Show version number\n-w, --watch Watch files in bundle and rebuild on changes\n--amd.autoId Generate the AMD ID based off the chunk name\n--amd.basePath Path to prepend to auto generated AMD ID\n--amd.define Function to use in place of `define`\n--amd.forceJsExtensionForImports Use `.js` extension in AMD imports\n--amd.id ID for AMD module (default is anonymous)\n--assetFileNames Name pattern for emitted assets\n--banner Code to insert at top of bundle (outside wrapper)\n--chunkFileNames Name pattern for emitted secondary chunks\n--compact Minify wrapper code\n--context Specify top-level `this` value\n--no-dynamicImportInCjs Write external dynamic CommonJS imports as require\n--entryFileNames Name pattern for emitted entry chunks\n--environment Settings passed to config file (see example)\n--no-esModule Do not add __esModule property\n--exports Specify export mode (auto, default, named, none)\n--extend Extend global variable defined by --name\n--no-externalImportAttributes Omit import attributes in \"es\" output\n--no-externalLiveBindings Do not generate code to support live bindings\n--failAfterWarnings Exit with an error if the build produced warnings\n--filterLogs Filter log messages\n--footer Code to insert at end of bundle (outside wrapper)\n--forceExit Force exit the process when done\n--no-freeze Do not freeze namespace objects\n--generatedCode Which code features to use (es5/es2015)\n--generatedCode.arrowFunctions Use arrow functions in generated code\n--generatedCode.constBindings Use \"const\" in generated code\n--generatedCode.objectShorthand Use shorthand properties in generated code\n--no-generatedCode.reservedNamesAsProps Always quote reserved names as props\n--generatedCode.symbols Use symbols in generated code\n--hashCharacters Use the specified character set for file hashes\n--no-hoistTransitiveImports Do not hoist transitive imports into entry chunks\n--importAttributesKey Use the specified keyword for import attributes\n--no-indent Don't indent result\n--inlineDynamicImports Create single bundle when using dynamic imports\n--no-interop Do not include interop block\n--intro Code to insert at top of bundle (inside wrapper)\n--logLevel Which kind of logs to display\n--no-makeAbsoluteExternalsRelative Prevent normalization of external imports\n--maxParallelFileOps How many files to read in parallel\n--minifyInternalExports Force or disable minification of internal exports\n--noConflict Generate a noConflict method for UMD globals\n--outro Code to insert at end of bundle (inside wrapper)\n--perf Display performance timings\n--no-preserveEntrySignatures Avoid facade chunks for entry points\n--preserveModules Preserve module structure\n--preserveModulesRoot Put preserved modules under this path at root level\n--preserveSymlinks Do not follow symlinks when resolving files\n--no-reexportProtoFromExternal Ignore `__proto__` in star re-exports\n--no-sanitizeFileName Do not replace invalid characters in file names\n--shimMissingExports Create shim variables for missing exports\n--silent Don't print warnings\n--sourcemapBaseUrl Emit absolute sourcemap URLs with given base\n--sourcemapDebugIds Emit unique debug ids in source and sourcemaps\n--sourcemapExcludeSources Do not include source code in source maps\n--sourcemapFile Specify bundle position for source maps\n--sourcemapFileNames Name pattern for emitted sourcemaps\n--stdin=ext Specify file extension used for stdin input\n--no-stdin Do not read \"-\" from stdin\n--no-strict Don't emit `\"use strict\";` in the generated modules\n--strictDeprecations Throw errors for deprecated features\n--no-systemNullSetters Do not replace empty SystemJS setters with `null`\n--no-treeshake Disable tree-shaking optimisations\n--no-treeshake.annotations Ignore pure call annotations\n--treeshake.correctVarValueBeforeDeclaration Deoptimize variables until declared\n--treeshake.manualPureFunctions Manually declare functions as pure\n--no-treeshake.moduleSideEffects Assume modules have no side effects\n--no-treeshake.propertyReadSideEffects Ignore property access side effects\n--no-treeshake.tryCatchDeoptimization Do not turn off try-catch-tree-shaking\n--no-treeshake.unknownGlobalSideEffects Assume unknown globals do not throw\n--validate Validate output\n--waitForBundleInput Wait for bundle input files\n--watch.allowInputInsideOutputPath Whether the input path is allowed to be a\n subpath of the output path\n--watch.buildDelay Throttle watch rebuilds\n--no-watch.clearScreen Do not clear the screen when rebuilding\n--watch.exclude Exclude files from being watched\n--watch.include Limit watching to specified files\n--watch.onBundleEnd Shell command to run on `\"BUNDLE_END\"` event\n--watch.onBundleStart Shell command to run on `\"BUNDLE_START\"` event\n--watch.onEnd Shell command to run on `\"END\"` event\n--watch.onError Shell command to run on `\"ERROR\"` event\n--watch.onStart Shell command to run on `\"START\"` event\n--watch.skipWrite Do not write files to disk when watching\n\nExamples:\n\n# use settings in config file\nrollup -c\n\n# in config file, process.env.INCLUDE_DEPS === 'true'\n# and process.env.BUILD === 'production'\nrollup -c --environment INCLUDE_DEPS,BUILD:production\n\n# create CommonJS bundle.js from src/main.js\nrollup --format=cjs --file=bundle.js -- src/main.js\n\n# create self-executing IIFE using `window.jQuery`\n# and `window._` as external globals\nrollup -f iife --globals jquery:jQuery,lodash:_ \\\n -i src/app.js -o build/app.js -m build/app.js.map\n\nNotes:\n\n* When piping to stdout, only inline sourcemaps are permitted\n\nFor more information visit https://rollupjs.org\n"; +const help = "rollup version 4.60.0\n=====================================\n\nUsage: rollup [options] \n\nOptions:\n\n-c, --config Use this config file (if argument is used but value\n is unspecified, Rollup will try to load configuration files in\n the following order:\n rollup.config.mjs -> rollup.config.cjs -> rollup.config.js)\n-d, --dir Directory for chunks (if absent, prints to stdout)\n-e, --external Comma-separate list of module IDs to exclude\n-f, --format Type of output (amd, cjs, es, iife, umd, system)\n-g, --globals Comma-separate list of `moduleID:Global` pairs\n-h, --help Show this help message\n-i, --input Input (alternative to )\n-m, --sourcemap Generate sourcemap (`-m inline` for inline map)\n-n, --name Name for UMD export\n-o, --file Single output file (if absent, prints to stdout)\n-p, --plugin Use the plugin specified (may be repeated)\n-v, --version Show version number\n-w, --watch Watch files in bundle and rebuild on changes\n--amd.autoId Generate the AMD ID based off the chunk name\n--amd.basePath Path to prepend to auto generated AMD ID\n--amd.define Function to use in place of `define`\n--amd.forceJsExtensionForImports Use `.js` extension in AMD imports\n--amd.id ID for AMD module (default is anonymous)\n--assetFileNames Name pattern for emitted assets\n--banner Code to insert at top of bundle (outside wrapper)\n--chunkFileNames Name pattern for emitted secondary chunks\n--compact Minify wrapper code\n--context Specify top-level `this` value\n--no-dynamicImportInCjs Write external dynamic CommonJS imports as require\n--entryFileNames Name pattern for emitted entry chunks\n--environment Settings passed to config file (see example)\n--no-esModule Do not add __esModule property\n--exports Specify export mode (auto, default, named, none)\n--extend Extend global variable defined by --name\n--no-externalImportAttributes Omit import attributes in \"es\" output\n--no-externalLiveBindings Do not generate code to support live bindings\n--failAfterWarnings Exit with an error if the build produced warnings\n--filterLogs Filter log messages\n--footer Code to insert at end of bundle (outside wrapper)\n--forceExit Force exit the process when done\n--no-freeze Do not freeze namespace objects\n--generatedCode Which code features to use (es5/es2015)\n--generatedCode.arrowFunctions Use arrow functions in generated code\n--generatedCode.constBindings Use \"const\" in generated code\n--generatedCode.objectShorthand Use shorthand properties in generated code\n--no-generatedCode.reservedNamesAsProps Always quote reserved names as props\n--generatedCode.symbols Use symbols in generated code\n--hashCharacters Use the specified character set for file hashes\n--no-hoistTransitiveImports Do not hoist transitive imports into entry chunks\n--importAttributesKey Use the specified keyword for import attributes\n--no-indent Don't indent result\n--inlineDynamicImports Create single bundle when using dynamic imports\n--no-interop Do not include interop block\n--intro Code to insert at top of bundle (inside wrapper)\n--logLevel Which kind of logs to display\n--no-makeAbsoluteExternalsRelative Prevent normalization of external imports\n--maxParallelFileOps How many files to read in parallel\n--minifyInternalExports Force or disable minification of internal exports\n--noConflict Generate a noConflict method for UMD globals\n--outro Code to insert at end of bundle (inside wrapper)\n--perf Display performance timings\n--no-preserveEntrySignatures Avoid facade chunks for entry points\n--preserveModules Preserve module structure\n--preserveModulesRoot Put preserved modules under this path at root level\n--preserveSymlinks Do not follow symlinks when resolving files\n--no-reexportProtoFromExternal Ignore `__proto__` in star re-exports\n--no-sanitizeFileName Do not replace invalid characters in file names\n--shimMissingExports Create shim variables for missing exports\n--silent Don't print warnings\n--sourcemapBaseUrl Emit absolute sourcemap URLs with given base\n--sourcemapDebugIds Emit unique debug ids in source and sourcemaps\n--sourcemapExcludeSources Do not include source code in source maps\n--sourcemapFile Specify bundle position for source maps\n--sourcemapFileNames Name pattern for emitted sourcemaps\n--stdin=ext Specify file extension used for stdin input\n--no-stdin Do not read \"-\" from stdin\n--no-strict Don't emit `\"use strict\";` in the generated modules\n--strictDeprecations Throw errors for deprecated features\n--no-systemNullSetters Do not replace empty SystemJS setters with `null`\n--no-treeshake Disable tree-shaking optimisations\n--no-treeshake.annotations Ignore pure call annotations\n--treeshake.correctVarValueBeforeDeclaration Deoptimize variables until declared\n--treeshake.manualPureFunctions Manually declare functions as pure\n--no-treeshake.moduleSideEffects Assume modules have no side effects\n--no-treeshake.propertyReadSideEffects Ignore property access side effects\n--no-treeshake.tryCatchDeoptimization Do not turn off try-catch-tree-shaking\n--no-treeshake.unknownGlobalSideEffects Assume unknown globals do not throw\n--validate Validate output\n--waitForBundleInput Wait for bundle input files\n--watch.allowInputInsideOutputPath Whether the input path is allowed to be a\n subpath of the output path\n--watch.buildDelay Throttle watch rebuilds\n--no-watch.clearScreen Do not clear the screen when rebuilding\n--watch.exclude Exclude files from being watched\n--watch.include Limit watching to specified files\n--watch.onBundleEnd Shell command to run on `\"BUNDLE_END\"` event\n--watch.onBundleStart Shell command to run on `\"BUNDLE_START\"` event\n--watch.onEnd Shell command to run on `\"END\"` event\n--watch.onError Shell command to run on `\"ERROR\"` event\n--watch.onStart Shell command to run on `\"START\"` event\n--watch.skipWrite Do not write files to disk when watching\n\nExamples:\n\n# use settings in config file\nrollup -c\n\n# in config file, process.env.INCLUDE_DEPS === 'true'\n# and process.env.BUILD === 'production'\nrollup -c --environment INCLUDE_DEPS,BUILD:production\n\n# create CommonJS bundle.js from src/main.js\nrollup --format=cjs --file=bundle.js -- src/main.js\n\n# create self-executing IIFE using `window.jQuery`\n# and `window._` as external globals\nrollup -f iife --globals jquery:jQuery,lodash:_ \\\n -i src/app.js -o build/app.js -m build/app.js.map\n\nNotes:\n\n* When piping to stdout, only inline sourcemaps are permitted\n\nFor more information visit https://rollupjs.org\n"; /** * @license diff --git a/frontend/node_modules/rollup/dist/es/getLogFilter.js b/frontend/node_modules/rollup/dist/es/getLogFilter.js index f040563..ebece54 100644 --- a/frontend/node_modules/rollup/dist/es/getLogFilter.js +++ b/frontend/node_modules/rollup/dist/es/getLogFilter.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/es/parseAst.js b/frontend/node_modules/rollup/dist/es/parseAst.js index 3d7fa0b..1efef2d 100644 --- a/frontend/node_modules/rollup/dist/es/parseAst.js +++ b/frontend/node_modules/rollup/dist/es/parseAst.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/es/rollup.js b/frontend/node_modules/rollup/dist/es/rollup.js index dffd3ef..bf9146f 100644 --- a/frontend/node_modules/rollup/dist/es/rollup.js +++ b/frontend/node_modules/rollup/dist/es/rollup.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/es/shared/node-entry.js b/frontend/node_modules/rollup/dist/es/shared/node-entry.js index f8eb080..befb30a 100644 --- a/frontend/node_modules/rollup/dist/es/shared/node-entry.js +++ b/frontend/node_modules/rollup/dist/es/shared/node-entry.js @@ -1,13 +1,13 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup Released under the MIT License. */ -import { EMPTY_OBJECT, ExportDefaultDeclaration as ExportDefaultDeclaration$1, CallExpression as CallExpression$1, EMPTY_ARRAY, LOGLEVEL_WARN, logUnusedExternalImports, ANNOTATION_KEY, INVALID_ANNOTATION_KEY, ExpressionStatement as ExpressionStatement$1, AwaitExpression as AwaitExpression$1, MemberExpression as MemberExpression$1, Identifier as Identifier$1, FunctionExpression as FunctionExpression$1, ArrowFunctionExpression as ArrowFunctionExpression$1, ObjectExpression as ObjectExpression$1, Property as Property$1, Program as Program$1, logIllegalImportReassignment, BLANK, logRedeclarationError, StaticBlock as StaticBlock$1, CatchClause as CatchClause$1, logDuplicateArgumentNameError, logModuleLevelDirective, ReturnStatement as ReturnStatement$1, VariableDeclarator as VariableDeclarator$1, logMissingExport, normalize, getImportPath, logMissingNodeBuiltins, logReservedNamespace, error, logIllegalIdentifierAsName, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, RestElement as RestElement$1, logConstVariableReassignError, EMPTY_SET, logCannotCallNamespace, logEval, BlockStatement as BlockStatement$1, getRollupError, logModuleParseError, logParseError, LOGLEVEL_INFO, logFirstSideEffect, locate, logInvalidAnnotation, logThisIsUndefined, getAstBuffer, convertAnnotations, FIXED_STRINGS, convertNode as convertNode$1, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logMissingEntryExport, logSyntheticNamedExportsNeedNamespaceExport, logDuplicateExportError, logInvalidSourcemapForError, augmentCodeLocation, logInconsistentImportAttributes, logMissingJsxExport, logNamespaceConflict, logAmbiguousExternalNamespaces, logShimmedExport, parseAst, TemplateLiteral as TemplateLiteral$1, Literal as Literal$1, logCircularReexport, logInvalidFormatForTopLevelAwait, logAddonNotGenerated, logIncompatibleExportOptionValue, logMixedExport, logFailedValidation, isPathFragment, logCyclicCrossChunkReexport, getAliasName, logUnexpectedNamedImport, isAbsolute as isAbsolute$1, relative as relative$1, logUnexpectedNamespaceReexport, logEmptyChunk, logMissingGlobalName, logOptimizeChunkStatus, logSourcemapBroken, logConflictingSourcemapSources, logChunkInvalid, logInvalidOption, URL_OUTPUT_FORMAT, URL_OUTPUT_DIR, URL_OUTPUT_SOURCEMAPFILE, URL_OUTPUT_AMD_ID, logFileNameOutsideOutputDirectory, logCannotAssignModuleToChunk, logCircularChunk, logUnknownOption, printQuotedStringList, LOGLEVEL_ERROR, logLevelPriority, LOGLEVEL_DEBUG, logAnonymousPluginCache, logDuplicatePluginName, logInvalidSetAssetSourceCall, logPluginError, logNoTransformMapOrAstWithoutCode, warnDeprecation, URL_TRANSFORM, relativeId, logBadLoader, logInternalIdCannotBeExternal, isRelative, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logExternalSyntheticExports, logUnresolvedEntry, logUnresolvedImplicitDependant, logExternalModulesCannotBeIncludedInManualChunks, logEntryCannotBeExternal, logImplicitDependantCannotBeExternal, logExternalModulesCannotBeTransformedToModules, URL_LOAD, logNoAssetSourceSet, logFileReferenceIdNotFoundForFilename, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logInvalidRollupPhaseForChunkEmission, logChunkNotGeneratedForFileName, logAssetNotFinalisedForFileName, logFileNameConflict, URL_GENERATEBUNDLE, logInvalidLogPosition, logInputHookInOutputPlugin, logInvalidAddonPluginHook, logInvalidFunctionPluginHook, logImplicitDependantIsNotIncluded, logCircularDependency, augmentLogMessage, URL_JSX, URL_TREESHAKE, URL_TREESHAKE_MODULESIDEEFFECTS, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_PRESERVEENTRYSIGNATURES, URL_OUTPUT_GENERATEDCODE, isValidUrl, addTrailingSlashIfMissed, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_MANUALCHUNKS, logInvalidExportOptionValue, URL_OUTPUT_AMD_BASEPATH, URL_OUTPUT_INTEROP, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, logAlreadyClosed, logMissingFileOrDirOption, logCannotEmitFromOptionsHook, URL_WATCH } from './parseAst.js'; +import { EMPTY_OBJECT, ExportDefaultDeclaration as ExportDefaultDeclaration$1, CallExpression as CallExpression$1, EMPTY_ARRAY, LOGLEVEL_WARN, logUnusedExternalImports, ANNOTATION_KEY, INVALID_ANNOTATION_KEY, ExpressionStatement as ExpressionStatement$1, AwaitExpression as AwaitExpression$1, MemberExpression as MemberExpression$1, Identifier as Identifier$1, FunctionExpression as FunctionExpression$1, ArrowFunctionExpression as ArrowFunctionExpression$1, ObjectExpression as ObjectExpression$1, Property as Property$1, Program as Program$1, logIllegalImportReassignment, BLANK, logRedeclarationError, StaticBlock as StaticBlock$1, CatchClause as CatchClause$1, logDuplicateArgumentNameError, logModuleLevelDirective, ReturnStatement as ReturnStatement$1, VariableDeclarator as VariableDeclarator$1, logMissingExport, normalize, getImportPath, error, logSourcePhaseFormatUnsupported, logMissingNodeBuiltins, logReservedNamespace, logIllegalIdentifierAsName, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, RestElement as RestElement$1, logConstVariableReassignError, EMPTY_SET, logCannotCallNamespace, logEval, BlockStatement as BlockStatement$1, getRollupError, logModuleParseError, logParseError, LOGLEVEL_INFO, logFirstSideEffect, locate, logInvalidAnnotation, logThisIsUndefined, getAstBuffer, convertAnnotations, FIXED_STRINGS, convertNode as convertNode$1, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logMissingEntryExport, logSyntheticNamedExportsNeedNamespaceExport, logDuplicateExportError, logInvalidSourcemapForError, augmentCodeLocation, logInconsistentImportAttributes, logMissingJsxExport, logNamespaceConflict, logAmbiguousExternalNamespaces, logShimmedExport, parseAst, TemplateLiteral as TemplateLiteral$1, Literal as Literal$1, logCircularReexport, logInvalidFormatForTopLevelAwait, logAddonNotGenerated, logIncompatibleExportOptionValue, logMixedExport, logFailedValidation, isPathFragment, logCyclicCrossChunkReexport, getAliasName, logUnexpectedNamedImport, isAbsolute as isAbsolute$1, relative as relative$1, logUnexpectedNamespaceReexport, logEmptyChunk, logMissingGlobalName, logOptimizeChunkStatus, logSourcemapBroken, logConflictingSourcemapSources, logChunkInvalid, logInvalidOption, URL_OUTPUT_FORMAT, URL_OUTPUT_DIR, URL_OUTPUT_SOURCEMAPFILE, URL_OUTPUT_AMD_ID, logFileNameOutsideOutputDirectory, logCannotAssignModuleToChunk, logCircularChunk, logUnknownOption, printQuotedStringList, LOGLEVEL_ERROR, logLevelPriority, LOGLEVEL_DEBUG, logAnonymousPluginCache, logDuplicatePluginName, logInvalidSetAssetSourceCall, logPluginError, logNoTransformMapOrAstWithoutCode, warnDeprecation, URL_TRANSFORM, relativeId, logBadLoader, logNonExternalSourcePhaseImport, logInternalIdCannotBeExternal, isRelative, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logExternalSyntheticExports, logUnresolvedEntry, logUnresolvedImplicitDependant, logExternalModulesCannotBeIncludedInManualChunks, logEntryCannotBeExternal, logImplicitDependantCannotBeExternal, logExternalModulesCannotBeTransformedToModules, URL_LOAD, logNoAssetSourceSet, logFileReferenceIdNotFoundForFilename, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logInvalidRollupPhaseForChunkEmission, logChunkNotGeneratedForFileName, logAssetNotFinalisedForFileName, logFileNameConflict, URL_GENERATEBUNDLE, logInvalidLogPosition, logInputHookInOutputPlugin, logInvalidAddonPluginHook, logInvalidFunctionPluginHook, logImplicitDependantIsNotIncluded, logCircularDependency, augmentLogMessage, URL_JSX, URL_TREESHAKE, URL_TREESHAKE_MODULESIDEEFFECTS, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_PRESERVEENTRYSIGNATURES, URL_OUTPUT_GENERATEDCODE, isValidUrl, addTrailingSlashIfMissed, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_MANUALCHUNKS, logInvalidExportOptionValue, URL_OUTPUT_AMD_BASEPATH, URL_OUTPUT_INTEROP, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, logAlreadyClosed, logMissingFileOrDirOption, logCannotEmitFromOptionsHook, URL_WATCH } from './parseAst.js'; import { relative, dirname, basename, extname, resolve as resolve$1, join } from 'node:path'; import { posix, isAbsolute, resolve, win32 } from 'path'; import { parseAsync, xxhashBase16, xxhashBase64Url, xxhashBase36 } from '../../native.js'; @@ -27,7 +27,7 @@ function _mergeNamespaces(n, m) { return Object.defineProperty(n, Symbol.toStringTag, { value: 'Module' }); } -var version = "4.59.1"; +var version = "4.60.0"; // src/vlq.ts var comma = ",".charCodeAt(0); @@ -2464,12 +2464,15 @@ class Variable extends ExpressionEntity { } } +/** Synthetic import name for source phase imports, similar to '*' for namespaces */ +const SOURCE_PHASE_IMPORT = '*source'; class ExternalVariable extends Variable { constructor(module, name) { super(name); this.referenced = false; this.module = module; this.isNamespace = name === '*'; + this.isSourcePhase = name === SOURCE_PHASE_IMPORT; } addReference(identifier) { this.referenced = true; @@ -8432,6 +8435,13 @@ function getInteropBlock(dependencies, interop, externalLiveBindings, freeze, sy return `${getHelpersBlock(neededInteropHelpers, accessedGlobals, indent, snippets, externalLiveBindings, freeze, symbols)}${interopStatements.length > 0 ? `${interopStatements.join(n)}${n}${n}` : ''}`; } +function throwOnPhase(outputFormat, chunkId, dependencies) { + const sourcePhaseDependency = dependencies.find(dependency => dependency.sourcePhaseImport); + if (sourcePhaseDependency) { + error(logSourcePhaseFormatUnsupported(outputFormat, chunkId, sourcePhaseDependency.importPath)); + } +} + function addJsExtension(name) { return name.endsWith('.js') ? name : name + '.js'; } @@ -8570,6 +8580,7 @@ function warnOnBuiltins(log, dependencies) { function amd(magicString, { accessedGlobals, dependencies, exports: exports$1, hasDefaultExport, hasExports, id, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, log, outro, snippets }, { amd, esModule, externalLiveBindings, freeze, generatedCode: { symbols }, interop, reexportProtoFromExternal, strict }) { warnOnBuiltins(log, dependencies); + throwOnPhase('amd', id, dependencies); const deps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`); const parameters = dependencies.map(m => m.name); const { n, getNonArrowFunctionIntro, _ } = snippets; @@ -8607,7 +8618,8 @@ function amd(magicString, { accessedGlobals, dependencies, exports: exports$1, h .append(`${n}${n}}));`); } -function cjs(magicString, { accessedGlobals, dependencies, exports: exports$1, hasDefaultExport, hasExports, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, outro, snippets }, { compact, esModule, externalLiveBindings, freeze, interop, generatedCode: { symbols }, reexportProtoFromExternal, strict }) { +function cjs(magicString, { accessedGlobals, dependencies, exports: exports$1, hasDefaultExport, hasExports, id, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, outro, snippets }, { compact, esModule, externalLiveBindings, freeze, interop, generatedCode: { symbols }, reexportProtoFromExternal, strict }) { + throwOnPhase('cjs', id, dependencies); const { _, n } = snippets; const useStrict = strict ? `'use strict';${n}${n}` : ''; let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets); @@ -8660,11 +8672,16 @@ function es(magicString, { accessedGlobals, indent: t, intro, outro, dependencie } function getImportBlock(dependencies, importAttributesKey, { _ }) { const importBlock = []; - for (const { importPath, reexports, imports, name, attributes } of dependencies) { + for (const { importPath, reexports, imports, name, attributes, sourcePhaseImport } of dependencies) { const assertion = attributes ? `${_}${importAttributesKey}${_}${attributes}` : ''; const pathWithAssertion = `'${importPath}'${assertion};`; + if (sourcePhaseImport) { + importBlock.push(`import source ${sourcePhaseImport} from${_}${pathWithAssertion}`); + } if (!reexports && !imports) { - importBlock.push(`import${_}${pathWithAssertion}`); + if (!sourcePhaseImport) { + importBlock.push(`import${_}${pathWithAssertion}`); + } continue; } if (imports) { @@ -8818,7 +8835,8 @@ function trimEmptyImports(dependencies) { return []; } -function iife(magicString, { accessedGlobals, dependencies, exports: exports$1, hasDefaultExport, hasExports, indent: t, intro, namedExportsMode, log, outro, snippets }, { compact, esModule, extend, freeze, externalLiveBindings, reexportProtoFromExternal, globals, interop, name, generatedCode: { symbols }, strict }) { +function iife(magicString, { accessedGlobals, dependencies, exports: exports$1, hasDefaultExport, hasExports, id, indent: t, intro, namedExportsMode, log, outro, snippets }, { compact, esModule, extend, freeze, externalLiveBindings, reexportProtoFromExternal, globals, interop, name, generatedCode: { symbols }, strict }) { + throwOnPhase('iife', id, dependencies); const { _, getNonArrowFunctionIntro, getPropertyAccess, n } = snippets; const isNamespaced = name && name.includes('.'); const useVariableAssignment = !extend && !isNamespaced; @@ -8877,7 +8895,8 @@ function iife(magicString, { accessedGlobals, dependencies, exports: exports$1, const MISSING_EXPORT_SHIM_VARIABLE = '_missingExportShim'; -function system(magicString, { accessedGlobals, dependencies, exports: exports$1, hasExports, indent: t, intro, snippets, outro, usesTopLevelAwait }, { externalLiveBindings, freeze, name, generatedCode: { symbols }, strict, systemNullSetters }) { +function system(magicString, { accessedGlobals, dependencies, exports: exports$1, hasExports, id, indent: t, intro, snippets, outro, usesTopLevelAwait }, { externalLiveBindings, freeze, name, generatedCode: { symbols }, strict, systemNullSetters }) { + throwOnPhase('system', id, dependencies); const { _, getFunctionIntro, getNonArrowFunctionIntro, n, s } = snippets; const { importBindings, setters, starExcludes } = analyzeDependencies(dependencies, exports$1, t, snippets); const registeredName = name ? `'${name}',${_}` : ''; @@ -9045,6 +9064,7 @@ function umd(magicString, { accessedGlobals, dependencies, exports: exports$1, h if (hasExports && !name) { return error(logMissingNameOptionForUmdExport()); } + throwOnPhase('umd', id, dependencies); warnOnBuiltins(log, dependencies); const amdDeps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`); const cjsDeps = dependencies.map(m => `require('${m.importPath}')`); @@ -16120,6 +16140,8 @@ const bufferParsers = [ node.specifiers = convertNodeList(node, scope, buffer[position], buffer); node.source = convertNode(node, scope, buffer[position + 1], buffer); node.attributes = convertNodeList(node, scope, buffer[position + 2], buffer); + const phaseIndex = buffer[position + 3]; + node.phase = phaseIndex === 0 ? undefined : FIXED_STRINGS[phaseIndex]; }, function importDefaultSpecifier(node, position, buffer) { const { scope } = node; @@ -16131,6 +16153,8 @@ const bufferParsers = [ node.sourceAstNode = convertNode$1(buffer[position], buffer); const optionsPosition = buffer[position + 1]; node.options = optionsPosition === 0 ? null : convertNode(node, scope, optionsPosition, buffer); + const phaseIndex = buffer[position + 2]; + node.phase = phaseIndex === 0 ? undefined : FIXED_STRINGS[phaseIndex]; }, function importNamespaceSpecifier(node, position, buffer) { const { scope } = node; @@ -16916,6 +16940,7 @@ class Module { this.isUserDefinedEntryPoint = false; this.needsExportShim = false; this.sideEffectDependenciesByVariable = new Map(); + this.sourcePhaseSources = new Set(); this.sourcesWithAttributes = new Map(); this.allExportsIncluded = false; this.ast = null; @@ -17566,16 +17591,19 @@ class Module { if (this.scope.variables.has(localName) || this.importDescriptions.has(localName)) { this.error(logRedeclarationError(localName), specifier.local.start); } - const name = specifier instanceof ImportDefaultSpecifier - ? 'default' - : specifier instanceof ImportNamespaceSpecifier - ? '*' - : specifier.imported instanceof Identifier - ? specifier.imported.name - : specifier.imported.value; + const name = node.phase === 'source' + ? SOURCE_PHASE_IMPORT + : specifier instanceof ImportDefaultSpecifier + ? 'default' + : specifier instanceof ImportNamespaceSpecifier + ? '*' + : specifier.imported instanceof Identifier + ? specifier.imported.name + : specifier.imported.value; this.importDescriptions.set(localName, { module: null, // filled in later name, + phase: node.phase === 'source' ? 'source' : 'instance', source, start: specifier.start }); @@ -17648,6 +17676,9 @@ class Module { else { this.sourcesWithAttributes.set(source, parsedAttributes); } + if (declaration.phase === 'source') { + this.sourcePhaseSources.add(source); + } } getImportedJsxFactoryVariable(baseName, nodeStart, importSource) { const { id } = this.resolvedIds[importSource]; @@ -17861,6 +17892,9 @@ function deconflictImportsEsmOrSystem(usedNames, imports, dependenciesToBeDeconf ? externalChunkByModule.get(module) : chunkByModule.get(module)).variableName); } + else if (module instanceof ExternalModule && variable.isSourcePhase) { + variable.setRenderNames(null, getSafeName(module.suggestedVariableName + '__source', usedNames, variable.forbiddenNames)); + } else if (module instanceof ExternalModule && name === 'default') { variable.setRenderNames(null, getSafeName([...module.exportedVariables].some(([exportedVariable, exportedName]) => exportedName === '*' && exportedVariable.included) ? module.suggestedVariableName + '__default' @@ -18907,10 +18941,14 @@ class Chunk { const module = variable.module; let dependency; let imported; + const isSourcePhase = module instanceof ExternalModule && variable.isSourcePhase; if (module instanceof ExternalModule) { dependency = this.externalChunkByModule.get(module); imported = variable.name; - if (imported !== 'default' && imported !== '*' && interop(module.id) === 'defaultOnly') { + if (!isSourcePhase && + imported !== 'default' && + imported !== '*' && + interop(module.id) === 'defaultOnly') { return error(logUnexpectedNamedImport(module.id, imported, false)); } } @@ -18920,7 +18958,8 @@ class Chunk { } getOrCreate(importsByDependency, dependency, getNewArray).push({ imported, - local: variable.getName(this.snippets.getPropertyAccess) + local: variable.getName(this.snippets.getPropertyAccess), + phase: isSourcePhase ? 'source' : 'instance' }); } return importsByDependency; @@ -19071,6 +19110,9 @@ class Chunk { const reexports = reexportSpecifiers.get(dependency) || null; const namedExportsMode = dependency instanceof ExternalChunk || dependency.exportMode !== 'default'; const importPath = dependency.getImportPath(fileName); + // Separate source-phase imports from regular imports + const sourcePhaseImport = imports?.find(index => index.phase === 'source'); + const instanceImports = imports?.filter(index => index.phase !== 'source') ?? null; renderedDependencies.set(dependency, { attributes: dependency instanceof ExternalChunk ? dependency.getImportAttributes(this.snippets) @@ -19080,12 +19122,13 @@ class Chunk { (this.outputOptions.format === 'umd' || this.outputOptions.format === 'iife') && getGlobalName(dependency, this.outputOptions.globals, (imports || reexports) !== null, this.inputOptions.onLog), importPath, - imports, + imports: instanceImports && instanceImports.length > 0 ? instanceImports : null, isChunk: dependency instanceof Chunk, name: dependency.variableName, namedExportsMode, namespaceVariableName: dependency.namespaceVariableName, - reexports + reexports, + sourcePhaseImport: sourcePhaseImport?.local }); } return (this.renderedDependencies = renderedDependencies); @@ -21519,13 +21562,16 @@ class ModuleLoader { return loadNewModulesPromise; } async fetchDynamicDependencies(module, resolveDynamicImportPromises) { - const dependencies = await Promise.all(resolveDynamicImportPromises.map(resolveDynamicImportPromise => resolveDynamicImportPromise.then(async ([{ node }, resolvedId]) => { + const dependencies = await Promise.all(resolveDynamicImportPromises.map(resolveDynamicImportPromise => resolveDynamicImportPromise.then(async ([{ argument, node }, resolvedId]) => { if (resolvedId === null) return null; if (typeof resolvedId === 'string') { node.resolution = resolvedId; return null; } + if (node.phase === 'source' && !resolvedId.external) { + return error(logNonExternalSourcePhaseImport(typeof argument === 'string' ? argument : relativeId(resolvedId.id), module.id)); + } return (node.resolution = await this.fetchResolvedDependency(relativeId(resolvedId.id), module.id, resolvedId)); }))); for (const dependency of dependencies) { @@ -21605,7 +21651,12 @@ class ModuleLoader { return this.fetchModule(resolvedId, importer, false, false); } async fetchStaticDependencies(module, resolveStaticDependencyPromises) { - for (const dependency of await Promise.all(resolveStaticDependencyPromises.map(resolveStaticDependencyPromise => resolveStaticDependencyPromise.then(([source, resolvedId]) => this.fetchResolvedDependency(source, module.id, resolvedId))))) { + for (const dependency of await Promise.all(resolveStaticDependencyPromises.map(resolveStaticDependencyPromise => resolveStaticDependencyPromise.then(([source, resolvedId]) => { + if (module.sourcePhaseSources.has(source) && !resolvedId.external) { + return error(logNonExternalSourcePhaseImport(source, module.id)); + } + return this.fetchResolvedDependency(source, module.id, resolvedId); + })))) { module.dependencies.add(dependency); dependency.importers.push(module.id); } @@ -22874,7 +22925,7 @@ class Graph { warnForMissingExports() { for (const module of this.modules) { for (const importDescription of module.importDescriptions.values()) { - if (importDescription.name !== '*') { + if (importDescription.name !== '*' && importDescription.phase !== 'source') { const [variable, options] = importDescription.module.getVariableForExportName(importDescription.name, { importChain: [module.id] }); if (!variable) { module.log(LOGLEVEL_WARN, logMissingExport(importDescription.name, module.id, importDescription.module.id, !!options?.missingButExportExists), importDescription.start); diff --git a/frontend/node_modules/rollup/dist/es/shared/parseAst.js b/frontend/node_modules/rollup/dist/es/shared/parseAst.js index 2b80083..e9d7217 100644 --- a/frontend/node_modules/rollup/dist/es/shared/parseAst.js +++ b/frontend/node_modules/rollup/dist/es/shared/parseAst.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup @@ -108,7 +108,9 @@ const FIXED_STRINGS = [ 'noSideEffects', 'sourcemap', 'using', - 'await using' + 'await using', + 'source', + 'defer' ]; const ANNOTATION_KEY = '_rollupAnnotations'; @@ -390,6 +392,8 @@ const URL_TREESHAKE_PURE = 'configuration-options/#pure'; const URL_TREESHAKE_NOSIDEEFFECTS = 'configuration-options/#no-side-effects'; const URL_TREESHAKE_MODULESIDEEFFECTS = 'configuration-options/#treeshake-modulesideeffects'; const URL_WATCH = 'configuration-options/#watch'; +// es-module-syntax +const URL_SOURCE_PHASE_IMPORTS = 'es-module-syntax/#source-phase-import'; const URL_GENERATEBUNDLE = 'plugin-development/#generatebundle'; const URL_LOAD = 'plugin-development/#load'; const URL_TRANSFORM = 'plugin-development/#transform'; @@ -447,7 +451,7 @@ function augmentLogMessage(log) { } // Error codes should be sorted alphabetically while errors should be sorted by // error code below -const ADDON_ERROR = 'ADDON_ERROR', ALREADY_CLOSED = 'ALREADY_CLOSED', AMBIGUOUS_EXTERNAL_NAMESPACES = 'AMBIGUOUS_EXTERNAL_NAMESPACES', ANONYMOUS_PLUGIN_CACHE = 'ANONYMOUS_PLUGIN_CACHE', ASSET_NOT_FINALISED = 'ASSET_NOT_FINALISED', ASSET_NOT_FOUND = 'ASSET_NOT_FOUND', ASSET_SOURCE_ALREADY_SET = 'ASSET_SOURCE_ALREADY_SET', ASSET_SOURCE_MISSING = 'ASSET_SOURCE_MISSING', BAD_LOADER = 'BAD_LOADER', CANNOT_CALL_NAMESPACE = 'CANNOT_CALL_NAMESPACE', CANNOT_EMIT_FROM_OPTIONS_HOOK = 'CANNOT_EMIT_FROM_OPTIONS_HOOK', CHUNK_NOT_GENERATED = 'CHUNK_NOT_GENERATED', CHUNK_INVALID = 'CHUNK_INVALID', CIRCULAR_CHUNK = 'CIRCULAR_CHUNK', CIRCULAR_DEPENDENCY = 'CIRCULAR_DEPENDENCY', CIRCULAR_REEXPORT = 'CIRCULAR_REEXPORT', CONST_REASSIGN = 'CONST_REASSIGN', CYCLIC_CROSS_CHUNK_REEXPORT = 'CYCLIC_CROSS_CHUNK_REEXPORT', DEPRECATED_FEATURE = 'DEPRECATED_FEATURE', DUPLICATE_ARGUMENT_NAME = 'DUPLICATE_ARGUMENT_NAME', DUPLICATE_EXPORT = 'DUPLICATE_EXPORT', DUPLICATE_PLUGIN_NAME = 'DUPLICATE_PLUGIN_NAME', EMPTY_BUNDLE = 'EMPTY_BUNDLE', EVAL = 'EVAL', EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS = 'EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS', EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES = 'EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES', EXTERNAL_SYNTHETIC_EXPORTS = 'EXTERNAL_SYNTHETIC_EXPORTS', FILE_NAME_CONFLICT = 'FILE_NAME_CONFLICT', FILE_NAME_OUTSIDE_OUTPUT_DIRECTORY = 'FILE_NAME_OUTSIDE_OUTPUT_DIRECTORY', FILE_NOT_FOUND = 'FILE_NOT_FOUND', FIRST_SIDE_EFFECT = 'FIRST_SIDE_EFFECT', ILLEGAL_IDENTIFIER_AS_NAME = 'ILLEGAL_IDENTIFIER_AS_NAME', ILLEGAL_REASSIGNMENT = 'ILLEGAL_REASSIGNMENT', INCONSISTENT_IMPORT_ATTRIBUTES = 'INCONSISTENT_IMPORT_ATTRIBUTES', INVALID_ANNOTATION = 'INVALID_ANNOTATION', INPUT_HOOK_IN_OUTPUT_PLUGIN = 'INPUT_HOOK_IN_OUTPUT_PLUGIN', INVALID_CHUNK = 'INVALID_CHUNK', INVALID_EXPORT_OPTION = 'INVALID_EXPORT_OPTION', INVALID_EXTERNAL_ID = 'INVALID_EXTERNAL_ID', INVALID_IMPORT_ATTRIBUTE = 'INVALID_IMPORT_ATTRIBUTE', INVALID_LOG_POSITION = 'INVALID_LOG_POSITION', INVALID_OPTION = 'INVALID_OPTION', INVALID_PLUGIN_HOOK = 'INVALID_PLUGIN_HOOK', INVALID_ROLLUP_PHASE = 'INVALID_ROLLUP_PHASE', INVALID_SETASSETSOURCE = 'INVALID_SETASSETSOURCE', INVALID_TLA_FORMAT = 'INVALID_TLA_FORMAT', MISSING_EXPORT = 'MISSING_EXPORT', MISSING_GLOBAL_NAME = 'MISSING_GLOBAL_NAME', MISSING_IMPLICIT_DEPENDANT = 'MISSING_IMPLICIT_DEPENDANT', MISSING_JSX_EXPORT = 'MISSING_JSX_EXPORT', MISSING_NAME_OPTION_FOR_IIFE_EXPORT = 'MISSING_NAME_OPTION_FOR_IIFE_EXPORT', MISSING_NODE_BUILTINS = 'MISSING_NODE_BUILTINS', MISSING_OPTION = 'MISSING_OPTION', MIXED_EXPORTS = 'MIXED_EXPORTS', MODULE_LEVEL_DIRECTIVE = 'MODULE_LEVEL_DIRECTIVE', NAMESPACE_CONFLICT = 'NAMESPACE_CONFLICT', NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE = 'NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE', OPTIMIZE_CHUNK_STATUS = 'OPTIMIZE_CHUNK_STATUS', PARSE_ERROR = 'PARSE_ERROR', PLUGIN_ERROR = 'PLUGIN_ERROR', REDECLARATION_ERROR = 'REDECLARATION_ERROR', RESERVED_NAMESPACE = 'RESERVED_NAMESPACE', SHIMMED_EXPORT = 'SHIMMED_EXPORT', SOURCEMAP_BROKEN = 'SOURCEMAP_BROKEN', SOURCEMAP_ERROR = 'SOURCEMAP_ERROR', SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT = 'SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT', THIS_IS_UNDEFINED = 'THIS_IS_UNDEFINED', UNEXPECTED_NAMED_IMPORT = 'UNEXPECTED_NAMED_IMPORT', UNKNOWN_OPTION = 'UNKNOWN_OPTION', UNRESOLVED_ENTRY = 'UNRESOLVED_ENTRY', UNRESOLVED_IMPORT = 'UNRESOLVED_IMPORT', UNUSED_EXTERNAL_IMPORT = 'UNUSED_EXTERNAL_IMPORT', VALIDATION_ERROR = 'VALIDATION_ERROR'; +const ADDON_ERROR = 'ADDON_ERROR', ALREADY_CLOSED = 'ALREADY_CLOSED', AMBIGUOUS_EXTERNAL_NAMESPACES = 'AMBIGUOUS_EXTERNAL_NAMESPACES', ANONYMOUS_PLUGIN_CACHE = 'ANONYMOUS_PLUGIN_CACHE', ASSET_NOT_FINALISED = 'ASSET_NOT_FINALISED', ASSET_NOT_FOUND = 'ASSET_NOT_FOUND', ASSET_SOURCE_ALREADY_SET = 'ASSET_SOURCE_ALREADY_SET', ASSET_SOURCE_MISSING = 'ASSET_SOURCE_MISSING', BAD_LOADER = 'BAD_LOADER', CANNOT_CALL_NAMESPACE = 'CANNOT_CALL_NAMESPACE', CANNOT_EMIT_FROM_OPTIONS_HOOK = 'CANNOT_EMIT_FROM_OPTIONS_HOOK', CHUNK_NOT_GENERATED = 'CHUNK_NOT_GENERATED', CHUNK_INVALID = 'CHUNK_INVALID', CIRCULAR_CHUNK = 'CIRCULAR_CHUNK', CIRCULAR_DEPENDENCY = 'CIRCULAR_DEPENDENCY', CIRCULAR_REEXPORT = 'CIRCULAR_REEXPORT', CONST_REASSIGN = 'CONST_REASSIGN', CYCLIC_CROSS_CHUNK_REEXPORT = 'CYCLIC_CROSS_CHUNK_REEXPORT', DEPRECATED_FEATURE = 'DEPRECATED_FEATURE', DUPLICATE_ARGUMENT_NAME = 'DUPLICATE_ARGUMENT_NAME', DUPLICATE_EXPORT = 'DUPLICATE_EXPORT', DUPLICATE_PLUGIN_NAME = 'DUPLICATE_PLUGIN_NAME', EMPTY_BUNDLE = 'EMPTY_BUNDLE', EVAL = 'EVAL', EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS = 'EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS', EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES = 'EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES', EXTERNAL_SYNTHETIC_EXPORTS = 'EXTERNAL_SYNTHETIC_EXPORTS', FILE_NAME_CONFLICT = 'FILE_NAME_CONFLICT', FILE_NAME_OUTSIDE_OUTPUT_DIRECTORY = 'FILE_NAME_OUTSIDE_OUTPUT_DIRECTORY', FILE_NOT_FOUND = 'FILE_NOT_FOUND', FIRST_SIDE_EFFECT = 'FIRST_SIDE_EFFECT', ILLEGAL_IDENTIFIER_AS_NAME = 'ILLEGAL_IDENTIFIER_AS_NAME', ILLEGAL_REASSIGNMENT = 'ILLEGAL_REASSIGNMENT', INCONSISTENT_IMPORT_ATTRIBUTES = 'INCONSISTENT_IMPORT_ATTRIBUTES', INVALID_ANNOTATION = 'INVALID_ANNOTATION', INPUT_HOOK_IN_OUTPUT_PLUGIN = 'INPUT_HOOK_IN_OUTPUT_PLUGIN', INVALID_CHUNK = 'INVALID_CHUNK', INVALID_EXPORT_OPTION = 'INVALID_EXPORT_OPTION', INVALID_EXTERNAL_ID = 'INVALID_EXTERNAL_ID', INVALID_IMPORT_ATTRIBUTE = 'INVALID_IMPORT_ATTRIBUTE', INVALID_LOG_POSITION = 'INVALID_LOG_POSITION', INVALID_OPTION = 'INVALID_OPTION', INVALID_PLUGIN_HOOK = 'INVALID_PLUGIN_HOOK', INVALID_ROLLUP_PHASE = 'INVALID_ROLLUP_PHASE', INVALID_SETASSETSOURCE = 'INVALID_SETASSETSOURCE', INVALID_TLA_FORMAT = 'INVALID_TLA_FORMAT', MISSING_EXPORT = 'MISSING_EXPORT', MISSING_GLOBAL_NAME = 'MISSING_GLOBAL_NAME', MISSING_IMPLICIT_DEPENDANT = 'MISSING_IMPLICIT_DEPENDANT', MISSING_JSX_EXPORT = 'MISSING_JSX_EXPORT', MISSING_NAME_OPTION_FOR_IIFE_EXPORT = 'MISSING_NAME_OPTION_FOR_IIFE_EXPORT', MISSING_NODE_BUILTINS = 'MISSING_NODE_BUILTINS', MISSING_OPTION = 'MISSING_OPTION', MIXED_EXPORTS = 'MIXED_EXPORTS', MODULE_LEVEL_DIRECTIVE = 'MODULE_LEVEL_DIRECTIVE', NAMESPACE_CONFLICT = 'NAMESPACE_CONFLICT', NON_EXTERNAL_SOURCE_PHASE_IMPORT = 'NON_EXTERNAL_SOURCE_PHASE_IMPORT', NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE = 'NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE', OPTIMIZE_CHUNK_STATUS = 'OPTIMIZE_CHUNK_STATUS', PARSE_ERROR = 'PARSE_ERROR', PLUGIN_ERROR = 'PLUGIN_ERROR', REDECLARATION_ERROR = 'REDECLARATION_ERROR', RESERVED_NAMESPACE = 'RESERVED_NAMESPACE', SHIMMED_EXPORT = 'SHIMMED_EXPORT', SOURCE_PHASE_FORMAT_UNSUPPORTED = 'SOURCE_PHASE_FORMAT_UNSUPPORTED', SOURCEMAP_BROKEN = 'SOURCEMAP_BROKEN', SOURCEMAP_ERROR = 'SOURCEMAP_ERROR', SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT = 'SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT', THIS_IS_UNDEFINED = 'THIS_IS_UNDEFINED', UNEXPECTED_NAMED_IMPORT = 'UNEXPECTED_NAMED_IMPORT', UNKNOWN_OPTION = 'UNKNOWN_OPTION', UNRESOLVED_ENTRY = 'UNRESOLVED_ENTRY', UNRESOLVED_IMPORT = 'UNRESOLVED_IMPORT', UNUSED_EXTERNAL_IMPORT = 'UNUSED_EXTERNAL_IMPORT', VALIDATION_ERROR = 'VALIDATION_ERROR'; function logAddonNotGenerated(message, hook, plugin) { return { code: ADDON_ERROR, @@ -892,6 +896,13 @@ function logNamespaceConflict(binding, reexportingModuleId, sources) { reexporter: reexportingModuleId }; } +function logNonExternalSourcePhaseImport(source, importer) { + return { + code: NON_EXTERNAL_SOURCE_PHASE_IMPORT, + message: `Source phase import "${source}" in "${relativeId(importer)}" must be external. Source phase imports are only supported for external modules. Use the "external" option to mark this module as external.`, + url: getRollupUrl(URL_SOURCE_PHASE_IMPORTS) + }; +} function logNoTransformMapOrAstWithoutCode(pluginName) { return { code: NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE, @@ -963,6 +974,13 @@ function logShimmedExport(id, binding) { message: `Missing export "${binding}" has been shimmed in module "${relativeId(id)}".` }; } +function logSourcePhaseFormatUnsupported(outputFormat, chunkId, dependencyId) { + return { + code: SOURCE_PHASE_FORMAT_UNSUPPORTED, + message: `Source phase imports are not supported for the "${outputFormat}" output format, importing "${dependencyId}" in "${chunkId}". Use the "es" output format to support source phase imports.`, + url: getRollupUrl(URL_SOURCE_PHASE_IMPORTS) + }; +} function logSourcemapBroken(plugin) { return { code: SOURCEMAP_BROKEN, @@ -1496,13 +1514,15 @@ const nodeConverters = [ }; }, function importDeclaration(position, buffer) { + const phaseIndex = buffer[position + 5]; return { type: 'ImportDeclaration', start: buffer[position], end: buffer[position + 1], specifiers: convertNodeList(buffer[position + 2], buffer), source: convertNode(buffer[position + 3], buffer), - attributes: convertNodeList(buffer[position + 4], buffer) + attributes: convertNodeList(buffer[position + 4], buffer), + ...(phaseIndex === 0 ? {} : { phase: FIXED_STRINGS[phaseIndex] }) }; }, function importDefaultSpecifier(position, buffer) { @@ -1515,12 +1535,14 @@ const nodeConverters = [ }, function importExpression(position, buffer) { const optionsPosition = buffer[position + 3]; + const phaseIndex = buffer[position + 4]; return { type: 'ImportExpression', start: buffer[position], end: buffer[position + 1], source: convertNode(buffer[position + 2], buffer), - options: optionsPosition === 0 ? null : convertNode(optionsPosition, buffer) + options: optionsPosition === 0 ? null : convertNode(optionsPosition, buffer), + ...(phaseIndex === 0 ? {} : { phase: FIXED_STRINGS[phaseIndex] }) }; }, function importNamespaceSpecifier(position, buffer) { @@ -2099,4 +2121,4 @@ function getAstBuffer(astBuffer) { const parseAst = (input, { allowReturnOutsideFunction = false, jsx = false } = {}) => convertProgram(getAstBuffer(parse(input, allowReturnOutsideFunction, jsx))); const parseAstAsync = async (input, { allowReturnOutsideFunction = false, jsx = false, signal } = {}) => convertProgram(getAstBuffer(await parseAsync(input, allowReturnOutsideFunction, jsx, signal))); -export { ANNOTATION_KEY, ArrowFunctionExpression, AwaitExpression, BLANK, BlockStatement, CallExpression, CatchClause, EMPTY_ARRAY, EMPTY_OBJECT, EMPTY_SET, ExportDefaultDeclaration, ExpressionStatement, FIXED_STRINGS, FunctionExpression, INVALID_ANNOTATION_KEY, Identifier, LOGLEVEL_DEBUG, LOGLEVEL_ERROR, LOGLEVEL_INFO, LOGLEVEL_WARN, Literal, MemberExpression, ObjectExpression, Program, Property, RestElement, ReturnStatement, StaticBlock, TemplateLiteral, URL_GENERATEBUNDLE, URL_JSX, URL_LOAD, URL_OUTPUT_AMD_BASEPATH, URL_OUTPUT_AMD_ID, URL_OUTPUT_DIR, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, URL_OUTPUT_FORMAT, URL_OUTPUT_GENERATEDCODE, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_OUTPUT_INTEROP, URL_OUTPUT_MANUALCHUNKS, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_SOURCEMAPFILE, URL_PRESERVEENTRYSIGNATURES, URL_TRANSFORM, URL_TREESHAKE, URL_TREESHAKE_MODULESIDEEFFECTS, URL_WATCH, VariableDeclarator, addTrailingSlashIfMissed, augmentCodeLocation, augmentLogMessage, convertAnnotations, convertNode, error, getAliasName, getAstBuffer, getImportPath, getRollupError, isAbsolute, isPathFragment, isRelative, isValidUrl, locate, logAddonNotGenerated, logAlreadyClosed, logAmbiguousExternalNamespaces, logAnonymousPluginCache, logAssetNotFinalisedForFileName, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logBadLoader, logCannotAssignModuleToChunk, logCannotCallNamespace, logCannotEmitFromOptionsHook, logChunkInvalid, logChunkNotGeneratedForFileName, logCircularChunk, logCircularDependency, logCircularReexport, logConflictingSourcemapSources, logConstVariableReassignError, logCyclicCrossChunkReexport, logDuplicateArgumentNameError, logDuplicateExportError, logDuplicatePluginName, logEmptyChunk, logEntryCannotBeExternal, logEval, logExternalModulesCannotBeIncludedInManualChunks, logExternalModulesCannotBeTransformedToModules, logExternalSyntheticExports, logFailedValidation, logFileNameConflict, logFileNameOutsideOutputDirectory, logFileReferenceIdNotFoundForFilename, logFirstSideEffect, logIllegalIdentifierAsName, logIllegalImportReassignment, logImplicitDependantCannotBeExternal, logImplicitDependantIsNotIncluded, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logIncompatibleExportOptionValue, logInconsistentImportAttributes, logInputHookInOutputPlugin, logInternalIdCannotBeExternal, logInvalidAddonPluginHook, logInvalidAnnotation, logInvalidExportOptionValue, logInvalidFormatForTopLevelAwait, logInvalidFunctionPluginHook, logInvalidLogPosition, logInvalidOption, logInvalidRollupPhaseForChunkEmission, logInvalidSetAssetSourceCall, logInvalidSourcemapForError, logLevelPriority, logMissingEntryExport, logMissingExport, logMissingFileOrDirOption, logMissingGlobalName, logMissingJsxExport, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, logMissingNodeBuiltins, logMixedExport, logModuleLevelDirective, logModuleParseError, logNamespaceConflict, logNoAssetSourceSet, logNoTransformMapOrAstWithoutCode, logOptimizeChunkStatus, logParseError, logPluginError, logRedeclarationError, logReservedNamespace, logShimmedExport, logSourcemapBroken, logSyntheticNamedExportsNeedNamespaceExport, logThisIsUndefined, logUnexpectedNamedImport, logUnexpectedNamespaceReexport, logUnknownOption, logUnresolvedEntry, logUnresolvedImplicitDependant, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logUnusedExternalImports, normalize, parseAst, parseAstAsync, printQuotedStringList, relative, relativeId, warnDeprecation }; +export { ANNOTATION_KEY, ArrowFunctionExpression, AwaitExpression, BLANK, BlockStatement, CallExpression, CatchClause, EMPTY_ARRAY, EMPTY_OBJECT, EMPTY_SET, ExportDefaultDeclaration, ExpressionStatement, FIXED_STRINGS, FunctionExpression, INVALID_ANNOTATION_KEY, Identifier, LOGLEVEL_DEBUG, LOGLEVEL_ERROR, LOGLEVEL_INFO, LOGLEVEL_WARN, Literal, MemberExpression, ObjectExpression, Program, Property, RestElement, ReturnStatement, StaticBlock, TemplateLiteral, URL_GENERATEBUNDLE, URL_JSX, URL_LOAD, URL_OUTPUT_AMD_BASEPATH, URL_OUTPUT_AMD_ID, URL_OUTPUT_DIR, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, URL_OUTPUT_FORMAT, URL_OUTPUT_GENERATEDCODE, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_OUTPUT_INTEROP, URL_OUTPUT_MANUALCHUNKS, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_SOURCEMAPFILE, URL_PRESERVEENTRYSIGNATURES, URL_TRANSFORM, URL_TREESHAKE, URL_TREESHAKE_MODULESIDEEFFECTS, URL_WATCH, VariableDeclarator, addTrailingSlashIfMissed, augmentCodeLocation, augmentLogMessage, convertAnnotations, convertNode, error, getAliasName, getAstBuffer, getImportPath, getRollupError, isAbsolute, isPathFragment, isRelative, isValidUrl, locate, logAddonNotGenerated, logAlreadyClosed, logAmbiguousExternalNamespaces, logAnonymousPluginCache, logAssetNotFinalisedForFileName, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logBadLoader, logCannotAssignModuleToChunk, logCannotCallNamespace, logCannotEmitFromOptionsHook, logChunkInvalid, logChunkNotGeneratedForFileName, logCircularChunk, logCircularDependency, logCircularReexport, logConflictingSourcemapSources, logConstVariableReassignError, logCyclicCrossChunkReexport, logDuplicateArgumentNameError, logDuplicateExportError, logDuplicatePluginName, logEmptyChunk, logEntryCannotBeExternal, logEval, logExternalModulesCannotBeIncludedInManualChunks, logExternalModulesCannotBeTransformedToModules, logExternalSyntheticExports, logFailedValidation, logFileNameConflict, logFileNameOutsideOutputDirectory, logFileReferenceIdNotFoundForFilename, logFirstSideEffect, logIllegalIdentifierAsName, logIllegalImportReassignment, logImplicitDependantCannotBeExternal, logImplicitDependantIsNotIncluded, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logIncompatibleExportOptionValue, logInconsistentImportAttributes, logInputHookInOutputPlugin, logInternalIdCannotBeExternal, logInvalidAddonPluginHook, logInvalidAnnotation, logInvalidExportOptionValue, logInvalidFormatForTopLevelAwait, logInvalidFunctionPluginHook, logInvalidLogPosition, logInvalidOption, logInvalidRollupPhaseForChunkEmission, logInvalidSetAssetSourceCall, logInvalidSourcemapForError, logLevelPriority, logMissingEntryExport, logMissingExport, logMissingFileOrDirOption, logMissingGlobalName, logMissingJsxExport, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, logMissingNodeBuiltins, logMixedExport, logModuleLevelDirective, logModuleParseError, logNamespaceConflict, logNoAssetSourceSet, logNoTransformMapOrAstWithoutCode, logNonExternalSourcePhaseImport, logOptimizeChunkStatus, logParseError, logPluginError, logRedeclarationError, logReservedNamespace, logShimmedExport, logSourcePhaseFormatUnsupported, logSourcemapBroken, logSyntheticNamedExportsNeedNamespaceExport, logThisIsUndefined, logUnexpectedNamedImport, logUnexpectedNamespaceReexport, logUnknownOption, logUnresolvedEntry, logUnresolvedImplicitDependant, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logUnusedExternalImports, normalize, parseAst, parseAstAsync, printQuotedStringList, relative, relativeId, warnDeprecation }; diff --git a/frontend/node_modules/rollup/dist/es/shared/watch.js b/frontend/node_modules/rollup/dist/es/shared/watch.js index b3cfa85..e43261f 100644 --- a/frontend/node_modules/rollup/dist/es/shared/watch.js +++ b/frontend/node_modules/rollup/dist/es/shared/watch.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/getLogFilter.js b/frontend/node_modules/rollup/dist/getLogFilter.js index 66b33e4..8e8920e 100644 --- a/frontend/node_modules/rollup/dist/getLogFilter.js +++ b/frontend/node_modules/rollup/dist/getLogFilter.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/loadConfigFile.js b/frontend/node_modules/rollup/dist/loadConfigFile.js index a578b35..c8abec2 100644 --- a/frontend/node_modules/rollup/dist/loadConfigFile.js +++ b/frontend/node_modules/rollup/dist/loadConfigFile.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/parseAst.js b/frontend/node_modules/rollup/dist/parseAst.js index d3e8dbb..3e00fb6 100644 --- a/frontend/node_modules/rollup/dist/parseAst.js +++ b/frontend/node_modules/rollup/dist/parseAst.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/rollup.js b/frontend/node_modules/rollup/dist/rollup.js index c1a1637..b597eb7 100644 --- a/frontend/node_modules/rollup/dist/rollup.js +++ b/frontend/node_modules/rollup/dist/rollup.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/shared/fsevents-importer.js b/frontend/node_modules/rollup/dist/shared/fsevents-importer.js index 4c7597c..2f92cf6 100644 --- a/frontend/node_modules/rollup/dist/shared/fsevents-importer.js +++ b/frontend/node_modules/rollup/dist/shared/fsevents-importer.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/shared/index.js b/frontend/node_modules/rollup/dist/shared/index.js index f77f07f..9537946 100644 --- a/frontend/node_modules/rollup/dist/shared/index.js +++ b/frontend/node_modules/rollup/dist/shared/index.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/shared/loadConfigFile.js b/frontend/node_modules/rollup/dist/shared/loadConfigFile.js index 1e04863..0a66645 100644 --- a/frontend/node_modules/rollup/dist/shared/loadConfigFile.js +++ b/frontend/node_modules/rollup/dist/shared/loadConfigFile.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/shared/parseAst.js b/frontend/node_modules/rollup/dist/shared/parseAst.js index 0c58249..36c4a95 100644 --- a/frontend/node_modules/rollup/dist/shared/parseAst.js +++ b/frontend/node_modules/rollup/dist/shared/parseAst.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup @@ -272,6 +272,8 @@ const URL_TREESHAKE_PURE = 'configuration-options/#pure'; const URL_TREESHAKE_NOSIDEEFFECTS = 'configuration-options/#no-side-effects'; const URL_TREESHAKE_MODULESIDEEFFECTS = 'configuration-options/#treeshake-modulesideeffects'; const URL_WATCH = 'configuration-options/#watch'; +// es-module-syntax +const URL_SOURCE_PHASE_IMPORTS = 'es-module-syntax/#source-phase-import'; // command-line-interface const URL_BUNDLE_CONFIG_AS_CJS = 'command-line-interface/#bundleconfigascjs'; const URL_CONFIGURATION_FILES = 'command-line-interface/#configuration-files'; @@ -332,7 +334,7 @@ function augmentLogMessage(log) { } // Error codes should be sorted alphabetically while errors should be sorted by // error code below -const ADDON_ERROR = 'ADDON_ERROR', ALREADY_CLOSED = 'ALREADY_CLOSED', AMBIGUOUS_EXTERNAL_NAMESPACES = 'AMBIGUOUS_EXTERNAL_NAMESPACES', ANONYMOUS_PLUGIN_CACHE = 'ANONYMOUS_PLUGIN_CACHE', ASSET_NOT_FINALISED = 'ASSET_NOT_FINALISED', ASSET_NOT_FOUND = 'ASSET_NOT_FOUND', ASSET_SOURCE_ALREADY_SET = 'ASSET_SOURCE_ALREADY_SET', ASSET_SOURCE_MISSING = 'ASSET_SOURCE_MISSING', BAD_LOADER = 'BAD_LOADER', CANNOT_CALL_NAMESPACE = 'CANNOT_CALL_NAMESPACE', CANNOT_EMIT_FROM_OPTIONS_HOOK = 'CANNOT_EMIT_FROM_OPTIONS_HOOK', CHUNK_NOT_GENERATED = 'CHUNK_NOT_GENERATED', CHUNK_INVALID = 'CHUNK_INVALID', CIRCULAR_CHUNK = 'CIRCULAR_CHUNK', CIRCULAR_DEPENDENCY = 'CIRCULAR_DEPENDENCY', CIRCULAR_REEXPORT = 'CIRCULAR_REEXPORT', CONST_REASSIGN = 'CONST_REASSIGN', CYCLIC_CROSS_CHUNK_REEXPORT = 'CYCLIC_CROSS_CHUNK_REEXPORT', DEPRECATED_FEATURE = 'DEPRECATED_FEATURE', DUPLICATE_ARGUMENT_NAME = 'DUPLICATE_ARGUMENT_NAME', DUPLICATE_EXPORT = 'DUPLICATE_EXPORT', DUPLICATE_IMPORT_OPTIONS = 'DUPLICATE_IMPORT_OPTIONS', DUPLICATE_PLUGIN_NAME = 'DUPLICATE_PLUGIN_NAME', EMPTY_BUNDLE = 'EMPTY_BUNDLE', EVAL = 'EVAL', EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS = 'EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS', EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES = 'EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES', EXTERNAL_SYNTHETIC_EXPORTS = 'EXTERNAL_SYNTHETIC_EXPORTS', FAIL_AFTER_WARNINGS = 'FAIL_AFTER_WARNINGS', FILE_NAME_CONFLICT = 'FILE_NAME_CONFLICT', FILE_NAME_OUTSIDE_OUTPUT_DIRECTORY = 'FILE_NAME_OUTSIDE_OUTPUT_DIRECTORY', FILE_NOT_FOUND = 'FILE_NOT_FOUND', FIRST_SIDE_EFFECT = 'FIRST_SIDE_EFFECT', ILLEGAL_IDENTIFIER_AS_NAME = 'ILLEGAL_IDENTIFIER_AS_NAME', ILLEGAL_REASSIGNMENT = 'ILLEGAL_REASSIGNMENT', INCONSISTENT_IMPORT_ATTRIBUTES = 'INCONSISTENT_IMPORT_ATTRIBUTES', INVALID_ANNOTATION = 'INVALID_ANNOTATION', INPUT_HOOK_IN_OUTPUT_PLUGIN = 'INPUT_HOOK_IN_OUTPUT_PLUGIN', INVALID_CHUNK = 'INVALID_CHUNK', INVALID_CONFIG_MODULE_FORMAT = 'INVALID_CONFIG_MODULE_FORMAT', INVALID_EXPORT_OPTION = 'INVALID_EXPORT_OPTION', INVALID_EXTERNAL_ID = 'INVALID_EXTERNAL_ID', INVALID_IMPORT_ATTRIBUTE = 'INVALID_IMPORT_ATTRIBUTE', INVALID_LOG_POSITION = 'INVALID_LOG_POSITION', INVALID_OPTION = 'INVALID_OPTION', INVALID_PLUGIN_HOOK = 'INVALID_PLUGIN_HOOK', INVALID_ROLLUP_PHASE = 'INVALID_ROLLUP_PHASE', INVALID_SETASSETSOURCE = 'INVALID_SETASSETSOURCE', INVALID_TLA_FORMAT = 'INVALID_TLA_FORMAT', MISSING_CONFIG = 'MISSING_CONFIG', MISSING_EXPORT = 'MISSING_EXPORT', MISSING_EXTERNAL_CONFIG = 'MISSING_EXTERNAL_CONFIG', MISSING_GLOBAL_NAME = 'MISSING_GLOBAL_NAME', MISSING_IMPLICIT_DEPENDANT = 'MISSING_IMPLICIT_DEPENDANT', MISSING_JSX_EXPORT = 'MISSING_JSX_EXPORT', MISSING_NAME_OPTION_FOR_IIFE_EXPORT = 'MISSING_NAME_OPTION_FOR_IIFE_EXPORT', MISSING_NODE_BUILTINS = 'MISSING_NODE_BUILTINS', MISSING_OPTION = 'MISSING_OPTION', MIXED_EXPORTS = 'MIXED_EXPORTS', MODULE_LEVEL_DIRECTIVE = 'MODULE_LEVEL_DIRECTIVE', NAMESPACE_CONFLICT = 'NAMESPACE_CONFLICT', NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE = 'NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE', ONLY_INLINE_SOURCEMAPS = 'ONLY_INLINE_SOURCEMAPS', OPTIMIZE_CHUNK_STATUS = 'OPTIMIZE_CHUNK_STATUS', PARSE_ERROR = 'PARSE_ERROR', PLUGIN_ERROR = 'PLUGIN_ERROR', REDECLARATION_ERROR = 'REDECLARATION_ERROR', RESERVED_NAMESPACE = 'RESERVED_NAMESPACE', SHIMMED_EXPORT = 'SHIMMED_EXPORT', SOURCEMAP_BROKEN = 'SOURCEMAP_BROKEN', SOURCEMAP_ERROR = 'SOURCEMAP_ERROR', SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT = 'SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT', THIS_IS_UNDEFINED = 'THIS_IS_UNDEFINED', UNEXPECTED_NAMED_IMPORT = 'UNEXPECTED_NAMED_IMPORT', UNKNOWN_OPTION = 'UNKNOWN_OPTION', UNRESOLVED_ENTRY = 'UNRESOLVED_ENTRY', UNRESOLVED_IMPORT = 'UNRESOLVED_IMPORT', UNUSED_EXTERNAL_IMPORT = 'UNUSED_EXTERNAL_IMPORT', VALIDATION_ERROR = 'VALIDATION_ERROR'; +const ADDON_ERROR = 'ADDON_ERROR', ALREADY_CLOSED = 'ALREADY_CLOSED', AMBIGUOUS_EXTERNAL_NAMESPACES = 'AMBIGUOUS_EXTERNAL_NAMESPACES', ANONYMOUS_PLUGIN_CACHE = 'ANONYMOUS_PLUGIN_CACHE', ASSET_NOT_FINALISED = 'ASSET_NOT_FINALISED', ASSET_NOT_FOUND = 'ASSET_NOT_FOUND', ASSET_SOURCE_ALREADY_SET = 'ASSET_SOURCE_ALREADY_SET', ASSET_SOURCE_MISSING = 'ASSET_SOURCE_MISSING', BAD_LOADER = 'BAD_LOADER', CANNOT_CALL_NAMESPACE = 'CANNOT_CALL_NAMESPACE', CANNOT_EMIT_FROM_OPTIONS_HOOK = 'CANNOT_EMIT_FROM_OPTIONS_HOOK', CHUNK_NOT_GENERATED = 'CHUNK_NOT_GENERATED', CHUNK_INVALID = 'CHUNK_INVALID', CIRCULAR_CHUNK = 'CIRCULAR_CHUNK', CIRCULAR_DEPENDENCY = 'CIRCULAR_DEPENDENCY', CIRCULAR_REEXPORT = 'CIRCULAR_REEXPORT', CONST_REASSIGN = 'CONST_REASSIGN', CYCLIC_CROSS_CHUNK_REEXPORT = 'CYCLIC_CROSS_CHUNK_REEXPORT', DEPRECATED_FEATURE = 'DEPRECATED_FEATURE', DUPLICATE_ARGUMENT_NAME = 'DUPLICATE_ARGUMENT_NAME', DUPLICATE_EXPORT = 'DUPLICATE_EXPORT', DUPLICATE_IMPORT_OPTIONS = 'DUPLICATE_IMPORT_OPTIONS', DUPLICATE_PLUGIN_NAME = 'DUPLICATE_PLUGIN_NAME', EMPTY_BUNDLE = 'EMPTY_BUNDLE', EVAL = 'EVAL', EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS = 'EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS', EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES = 'EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES', EXTERNAL_SYNTHETIC_EXPORTS = 'EXTERNAL_SYNTHETIC_EXPORTS', FAIL_AFTER_WARNINGS = 'FAIL_AFTER_WARNINGS', FILE_NAME_CONFLICT = 'FILE_NAME_CONFLICT', FILE_NAME_OUTSIDE_OUTPUT_DIRECTORY = 'FILE_NAME_OUTSIDE_OUTPUT_DIRECTORY', FILE_NOT_FOUND = 'FILE_NOT_FOUND', FIRST_SIDE_EFFECT = 'FIRST_SIDE_EFFECT', ILLEGAL_IDENTIFIER_AS_NAME = 'ILLEGAL_IDENTIFIER_AS_NAME', ILLEGAL_REASSIGNMENT = 'ILLEGAL_REASSIGNMENT', INCONSISTENT_IMPORT_ATTRIBUTES = 'INCONSISTENT_IMPORT_ATTRIBUTES', INVALID_ANNOTATION = 'INVALID_ANNOTATION', INPUT_HOOK_IN_OUTPUT_PLUGIN = 'INPUT_HOOK_IN_OUTPUT_PLUGIN', INVALID_CHUNK = 'INVALID_CHUNK', INVALID_CONFIG_MODULE_FORMAT = 'INVALID_CONFIG_MODULE_FORMAT', INVALID_EXPORT_OPTION = 'INVALID_EXPORT_OPTION', INVALID_EXTERNAL_ID = 'INVALID_EXTERNAL_ID', INVALID_IMPORT_ATTRIBUTE = 'INVALID_IMPORT_ATTRIBUTE', INVALID_LOG_POSITION = 'INVALID_LOG_POSITION', INVALID_OPTION = 'INVALID_OPTION', INVALID_PLUGIN_HOOK = 'INVALID_PLUGIN_HOOK', INVALID_ROLLUP_PHASE = 'INVALID_ROLLUP_PHASE', INVALID_SETASSETSOURCE = 'INVALID_SETASSETSOURCE', INVALID_TLA_FORMAT = 'INVALID_TLA_FORMAT', MISSING_CONFIG = 'MISSING_CONFIG', MISSING_EXPORT = 'MISSING_EXPORT', MISSING_EXTERNAL_CONFIG = 'MISSING_EXTERNAL_CONFIG', MISSING_GLOBAL_NAME = 'MISSING_GLOBAL_NAME', MISSING_IMPLICIT_DEPENDANT = 'MISSING_IMPLICIT_DEPENDANT', MISSING_JSX_EXPORT = 'MISSING_JSX_EXPORT', MISSING_NAME_OPTION_FOR_IIFE_EXPORT = 'MISSING_NAME_OPTION_FOR_IIFE_EXPORT', MISSING_NODE_BUILTINS = 'MISSING_NODE_BUILTINS', MISSING_OPTION = 'MISSING_OPTION', MIXED_EXPORTS = 'MIXED_EXPORTS', MODULE_LEVEL_DIRECTIVE = 'MODULE_LEVEL_DIRECTIVE', NAMESPACE_CONFLICT = 'NAMESPACE_CONFLICT', NON_EXTERNAL_SOURCE_PHASE_IMPORT = 'NON_EXTERNAL_SOURCE_PHASE_IMPORT', NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE = 'NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE', ONLY_INLINE_SOURCEMAPS = 'ONLY_INLINE_SOURCEMAPS', OPTIMIZE_CHUNK_STATUS = 'OPTIMIZE_CHUNK_STATUS', PARSE_ERROR = 'PARSE_ERROR', PLUGIN_ERROR = 'PLUGIN_ERROR', REDECLARATION_ERROR = 'REDECLARATION_ERROR', RESERVED_NAMESPACE = 'RESERVED_NAMESPACE', SHIMMED_EXPORT = 'SHIMMED_EXPORT', SOURCE_PHASE_FORMAT_UNSUPPORTED = 'SOURCE_PHASE_FORMAT_UNSUPPORTED', SOURCEMAP_BROKEN = 'SOURCEMAP_BROKEN', SOURCEMAP_ERROR = 'SOURCEMAP_ERROR', SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT = 'SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT', THIS_IS_UNDEFINED = 'THIS_IS_UNDEFINED', UNEXPECTED_NAMED_IMPORT = 'UNEXPECTED_NAMED_IMPORT', UNKNOWN_OPTION = 'UNKNOWN_OPTION', UNRESOLVED_ENTRY = 'UNRESOLVED_ENTRY', UNRESOLVED_IMPORT = 'UNRESOLVED_IMPORT', UNUSED_EXTERNAL_IMPORT = 'UNUSED_EXTERNAL_IMPORT', VALIDATION_ERROR = 'VALIDATION_ERROR'; function logAddonNotGenerated(message, hook, plugin) { return { code: ADDON_ERROR, @@ -829,6 +831,13 @@ function logNamespaceConflict(binding, reexportingModuleId, sources) { reexporter: reexportingModuleId }; } +function logNonExternalSourcePhaseImport(source, importer) { + return { + code: NON_EXTERNAL_SOURCE_PHASE_IMPORT, + message: `Source phase import "${source}" in "${relativeId(importer)}" must be external. Source phase imports are only supported for external modules. Use the "external" option to mark this module as external.`, + url: getRollupUrl(URL_SOURCE_PHASE_IMPORTS) + }; +} function logNoTransformMapOrAstWithoutCode(pluginName) { return { code: NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE, @@ -906,6 +915,13 @@ function logShimmedExport(id, binding) { message: `Missing export "${binding}" has been shimmed in module "${relativeId(id)}".` }; } +function logSourcePhaseFormatUnsupported(outputFormat, chunkId, dependencyId) { + return { + code: SOURCE_PHASE_FORMAT_UNSUPPORTED, + message: `Source phase imports are not supported for the "${outputFormat}" output format, importing "${dependencyId}" in "${chunkId}". Use the "es" output format to support source phase imports.`, + url: getRollupUrl(URL_SOURCE_PHASE_IMPORTS) + }; +} function logSourcemapBroken(plugin) { return { code: SOURCEMAP_BROKEN, @@ -1143,7 +1159,9 @@ const FIXED_STRINGS = [ 'noSideEffects', 'sourcemap', 'using', - 'await using' + 'await using', + 'source', + 'defer' ]; const ANNOTATION_KEY = '_rollupAnnotations'; @@ -1559,13 +1577,15 @@ const nodeConverters = [ }; }, function importDeclaration(position, buffer) { + const phaseIndex = buffer[position + 5]; return { type: 'ImportDeclaration', start: buffer[position], end: buffer[position + 1], specifiers: convertNodeList(buffer[position + 2], buffer), source: convertNode(buffer[position + 3], buffer), - attributes: convertNodeList(buffer[position + 4], buffer) + attributes: convertNodeList(buffer[position + 4], buffer), + ...(phaseIndex === 0 ? {} : { phase: FIXED_STRINGS[phaseIndex] }) }; }, function importDefaultSpecifier(position, buffer) { @@ -1578,12 +1598,14 @@ const nodeConverters = [ }, function importExpression(position, buffer) { const optionsPosition = buffer[position + 3]; + const phaseIndex = buffer[position + 4]; return { type: 'ImportExpression', start: buffer[position], end: buffer[position + 1], source: convertNode(buffer[position + 2], buffer), - options: optionsPosition === 0 ? null : convertNode(optionsPosition, buffer) + options: optionsPosition === 0 ? null : convertNode(optionsPosition, buffer), + ...(phaseIndex === 0 ? {} : { phase: FIXED_STRINGS[phaseIndex] }) }; }, function importNamespaceSpecifier(position, buffer) { @@ -2309,6 +2331,7 @@ exports.logModuleParseError = logModuleParseError; exports.logNamespaceConflict = logNamespaceConflict; exports.logNoAssetSourceSet = logNoAssetSourceSet; exports.logNoTransformMapOrAstWithoutCode = logNoTransformMapOrAstWithoutCode; +exports.logNonExternalSourcePhaseImport = logNonExternalSourcePhaseImport; exports.logOnlyInlineSourcemapsForStdout = logOnlyInlineSourcemapsForStdout; exports.logOptimizeChunkStatus = logOptimizeChunkStatus; exports.logParseError = logParseError; @@ -2316,6 +2339,7 @@ exports.logPluginError = logPluginError; exports.logRedeclarationError = logRedeclarationError; exports.logReservedNamespace = logReservedNamespace; exports.logShimmedExport = logShimmedExport; +exports.logSourcePhaseFormatUnsupported = logSourcePhaseFormatUnsupported; exports.logSourcemapBroken = logSourcemapBroken; exports.logSyntheticNamedExportsNeedNamespaceExport = logSyntheticNamedExportsNeedNamespaceExport; exports.logThisIsUndefined = logThisIsUndefined; diff --git a/frontend/node_modules/rollup/dist/shared/rollup.js b/frontend/node_modules/rollup/dist/shared/rollup.js index 79c77b3..e2a4648 100644 --- a/frontend/node_modules/rollup/dist/shared/rollup.js +++ b/frontend/node_modules/rollup/dist/shared/rollup.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup @@ -42,7 +42,7 @@ function _mergeNamespaces(n, m) { const promises__namespace = /*#__PURE__*/_interopNamespaceDefault(promises); -var version = "4.59.1"; +var version = "4.60.0"; function ensureArray$1(items) { if (Array.isArray(items)) { @@ -6255,12 +6255,15 @@ class Variable extends ExpressionEntity { } } +/** Synthetic import name for source phase imports, similar to '*' for namespaces */ +const SOURCE_PHASE_IMPORT = '*source'; class ExternalVariable extends Variable { constructor(module, name) { super(name); this.referenced = false; this.module = module; this.isNamespace = name === '*'; + this.isSourcePhase = name === SOURCE_PHASE_IMPORT; } addReference(identifier) { this.referenced = true; @@ -12209,6 +12212,13 @@ function getInteropBlock(dependencies, interop, externalLiveBindings, freeze, sy return `${getHelpersBlock(neededInteropHelpers, accessedGlobals, indent, snippets, externalLiveBindings, freeze, symbols)}${interopStatements.length > 0 ? `${interopStatements.join(n)}${n}${n}` : ''}`; } +function throwOnPhase(outputFormat, chunkId, dependencies) { + const sourcePhaseDependency = dependencies.find(dependency => dependency.sourcePhaseImport); + if (sourcePhaseDependency) { + parseAst_js.error(parseAst_js.logSourcePhaseFormatUnsupported(outputFormat, chunkId, sourcePhaseDependency.importPath)); + } +} + function addJsExtension(name) { return name.endsWith('.js') ? name : name + '.js'; } @@ -12347,6 +12357,7 @@ function warnOnBuiltins(log, dependencies) { function amd(magicString, { accessedGlobals, dependencies, exports: exports$1, hasDefaultExport, hasExports, id, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, log, outro, snippets }, { amd, esModule, externalLiveBindings, freeze, generatedCode: { symbols }, interop, reexportProtoFromExternal, strict }) { warnOnBuiltins(log, dependencies); + throwOnPhase('amd', id, dependencies); const deps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`); const parameters = dependencies.map(m => m.name); const { n, getNonArrowFunctionIntro, _ } = snippets; @@ -12384,7 +12395,8 @@ function amd(magicString, { accessedGlobals, dependencies, exports: exports$1, h .append(`${n}${n}}));`); } -function cjs(magicString, { accessedGlobals, dependencies, exports: exports$1, hasDefaultExport, hasExports, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, outro, snippets }, { compact, esModule, externalLiveBindings, freeze, interop, generatedCode: { symbols }, reexportProtoFromExternal, strict }) { +function cjs(magicString, { accessedGlobals, dependencies, exports: exports$1, hasDefaultExport, hasExports, id, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, outro, snippets }, { compact, esModule, externalLiveBindings, freeze, interop, generatedCode: { symbols }, reexportProtoFromExternal, strict }) { + throwOnPhase('cjs', id, dependencies); const { _, n } = snippets; const useStrict = strict ? `'use strict';${n}${n}` : ''; let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets); @@ -12437,11 +12449,16 @@ function es(magicString, { accessedGlobals, indent: t, intro, outro, dependencie } function getImportBlock(dependencies, importAttributesKey, { _ }) { const importBlock = []; - for (const { importPath, reexports, imports, name, attributes } of dependencies) { + for (const { importPath, reexports, imports, name, attributes, sourcePhaseImport } of dependencies) { const assertion = attributes ? `${_}${importAttributesKey}${_}${attributes}` : ''; const pathWithAssertion = `'${importPath}'${assertion};`; + if (sourcePhaseImport) { + importBlock.push(`import source ${sourcePhaseImport} from${_}${pathWithAssertion}`); + } if (!reexports && !imports) { - importBlock.push(`import${_}${pathWithAssertion}`); + if (!sourcePhaseImport) { + importBlock.push(`import${_}${pathWithAssertion}`); + } continue; } if (imports) { @@ -12595,7 +12612,8 @@ function trimEmptyImports(dependencies) { return []; } -function iife(magicString, { accessedGlobals, dependencies, exports: exports$1, hasDefaultExport, hasExports, indent: t, intro, namedExportsMode, log, outro, snippets }, { compact, esModule, extend, freeze, externalLiveBindings, reexportProtoFromExternal, globals, interop, name, generatedCode: { symbols }, strict }) { +function iife(magicString, { accessedGlobals, dependencies, exports: exports$1, hasDefaultExport, hasExports, id, indent: t, intro, namedExportsMode, log, outro, snippets }, { compact, esModule, extend, freeze, externalLiveBindings, reexportProtoFromExternal, globals, interop, name, generatedCode: { symbols }, strict }) { + throwOnPhase('iife', id, dependencies); const { _, getNonArrowFunctionIntro, getPropertyAccess, n } = snippets; const isNamespaced = name && name.includes('.'); const useVariableAssignment = !extend && !isNamespaced; @@ -12654,7 +12672,8 @@ function iife(magicString, { accessedGlobals, dependencies, exports: exports$1, const MISSING_EXPORT_SHIM_VARIABLE = '_missingExportShim'; -function system(magicString, { accessedGlobals, dependencies, exports: exports$1, hasExports, indent: t, intro, snippets, outro, usesTopLevelAwait }, { externalLiveBindings, freeze, name, generatedCode: { symbols }, strict, systemNullSetters }) { +function system(magicString, { accessedGlobals, dependencies, exports: exports$1, hasExports, id, indent: t, intro, snippets, outro, usesTopLevelAwait }, { externalLiveBindings, freeze, name, generatedCode: { symbols }, strict, systemNullSetters }) { + throwOnPhase('system', id, dependencies); const { _, getFunctionIntro, getNonArrowFunctionIntro, n, s } = snippets; const { importBindings, setters, starExcludes } = analyzeDependencies(dependencies, exports$1, t, snippets); const registeredName = name ? `'${name}',${_}` : ''; @@ -12822,6 +12841,7 @@ function umd(magicString, { accessedGlobals, dependencies, exports: exports$1, h if (hasExports && !name) { return parseAst_js.error(parseAst_js.logMissingNameOptionForUmdExport()); } + throwOnPhase('umd', id, dependencies); warnOnBuiltins(log, dependencies); const amdDeps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`); const cjsDeps = dependencies.map(m => `require('${m.importPath}')`); @@ -17730,6 +17750,8 @@ const bufferParsers = [ node.specifiers = convertNodeList(node, scope, buffer[position], buffer); node.source = convertNode(node, scope, buffer[position + 1], buffer); node.attributes = convertNodeList(node, scope, buffer[position + 2], buffer); + const phaseIndex = buffer[position + 3]; + node.phase = phaseIndex === 0 ? undefined : parseAst_js.FIXED_STRINGS[phaseIndex]; }, function importDefaultSpecifier(node, position, buffer) { const { scope } = node; @@ -17741,6 +17763,8 @@ const bufferParsers = [ node.sourceAstNode = parseAst_js.convertNode(buffer[position], buffer); const optionsPosition = buffer[position + 1]; node.options = optionsPosition === 0 ? null : convertNode(node, scope, optionsPosition, buffer); + const phaseIndex = buffer[position + 2]; + node.phase = phaseIndex === 0 ? undefined : parseAst_js.FIXED_STRINGS[phaseIndex]; }, function importNamespaceSpecifier(node, position, buffer) { const { scope } = node; @@ -18519,6 +18543,7 @@ class Module { this.isUserDefinedEntryPoint = false; this.needsExportShim = false; this.sideEffectDependenciesByVariable = new Map(); + this.sourcePhaseSources = new Set(); this.sourcesWithAttributes = new Map(); this.allExportsIncluded = false; this.ast = null; @@ -19169,16 +19194,19 @@ class Module { if (this.scope.variables.has(localName) || this.importDescriptions.has(localName)) { this.error(parseAst_js.logRedeclarationError(localName), specifier.local.start); } - const name = specifier instanceof ImportDefaultSpecifier - ? 'default' - : specifier instanceof ImportNamespaceSpecifier - ? '*' - : specifier.imported instanceof Identifier - ? specifier.imported.name - : specifier.imported.value; + const name = node.phase === 'source' + ? SOURCE_PHASE_IMPORT + : specifier instanceof ImportDefaultSpecifier + ? 'default' + : specifier instanceof ImportNamespaceSpecifier + ? '*' + : specifier.imported instanceof Identifier + ? specifier.imported.name + : specifier.imported.value; this.importDescriptions.set(localName, { module: null, // filled in later name, + phase: node.phase === 'source' ? 'source' : 'instance', source, start: specifier.start }); @@ -19251,6 +19279,9 @@ class Module { else { this.sourcesWithAttributes.set(source, parsedAttributes); } + if (declaration.phase === 'source') { + this.sourcePhaseSources.add(source); + } } getImportedJsxFactoryVariable(baseName, nodeStart, importSource) { const { id } = this.resolvedIds[importSource]; @@ -19464,6 +19495,9 @@ function deconflictImportsEsmOrSystem(usedNames, imports, dependenciesToBeDeconf ? externalChunkByModule.get(module) : chunkByModule.get(module)).variableName); } + else if (module instanceof ExternalModule && variable.isSourcePhase) { + variable.setRenderNames(null, getSafeName(module.suggestedVariableName + '__source', usedNames, variable.forbiddenNames)); + } else if (module instanceof ExternalModule && name === 'default') { variable.setRenderNames(null, getSafeName([...module.exportedVariables].some(([exportedVariable, exportedName]) => exportedName === '*' && exportedVariable.included) ? module.suggestedVariableName + '__default' @@ -20401,10 +20435,14 @@ class Chunk { const module = variable.module; let dependency; let imported; + const isSourcePhase = module instanceof ExternalModule && variable.isSourcePhase; if (module instanceof ExternalModule) { dependency = this.externalChunkByModule.get(module); imported = variable.name; - if (imported !== 'default' && imported !== '*' && interop(module.id) === 'defaultOnly') { + if (!isSourcePhase && + imported !== 'default' && + imported !== '*' && + interop(module.id) === 'defaultOnly') { return parseAst_js.error(parseAst_js.logUnexpectedNamedImport(module.id, imported, false)); } } @@ -20414,7 +20452,8 @@ class Chunk { } getOrCreate(importsByDependency, dependency, getNewArray).push({ imported, - local: variable.getName(this.snippets.getPropertyAccess) + local: variable.getName(this.snippets.getPropertyAccess), + phase: isSourcePhase ? 'source' : 'instance' }); } return importsByDependency; @@ -20565,6 +20604,9 @@ class Chunk { const reexports = reexportSpecifiers.get(dependency) || null; const namedExportsMode = dependency instanceof ExternalChunk || dependency.exportMode !== 'default'; const importPath = dependency.getImportPath(fileName); + // Separate source-phase imports from regular imports + const sourcePhaseImport = imports?.find(index => index.phase === 'source'); + const instanceImports = imports?.filter(index => index.phase !== 'source') ?? null; renderedDependencies.set(dependency, { attributes: dependency instanceof ExternalChunk ? dependency.getImportAttributes(this.snippets) @@ -20574,12 +20616,13 @@ class Chunk { (this.outputOptions.format === 'umd' || this.outputOptions.format === 'iife') && getGlobalName(dependency, this.outputOptions.globals, (imports || reexports) !== null, this.inputOptions.onLog), importPath, - imports, + imports: instanceImports && instanceImports.length > 0 ? instanceImports : null, isChunk: dependency instanceof Chunk, name: dependency.variableName, namedExportsMode, namespaceVariableName: dependency.namespaceVariableName, - reexports + reexports, + sourcePhaseImport: sourcePhaseImport?.local }); } return (this.renderedDependencies = renderedDependencies); @@ -22748,13 +22791,16 @@ class ModuleLoader { return loadNewModulesPromise; } async fetchDynamicDependencies(module, resolveDynamicImportPromises) { - const dependencies = await Promise.all(resolveDynamicImportPromises.map(resolveDynamicImportPromise => resolveDynamicImportPromise.then(async ([{ node }, resolvedId]) => { + const dependencies = await Promise.all(resolveDynamicImportPromises.map(resolveDynamicImportPromise => resolveDynamicImportPromise.then(async ([{ argument, node }, resolvedId]) => { if (resolvedId === null) return null; if (typeof resolvedId === 'string') { node.resolution = resolvedId; return null; } + if (node.phase === 'source' && !resolvedId.external) { + return parseAst_js.error(parseAst_js.logNonExternalSourcePhaseImport(typeof argument === 'string' ? argument : parseAst_js.relativeId(resolvedId.id), module.id)); + } return (node.resolution = await this.fetchResolvedDependency(parseAst_js.relativeId(resolvedId.id), module.id, resolvedId)); }))); for (const dependency of dependencies) { @@ -22834,7 +22880,12 @@ class ModuleLoader { return this.fetchModule(resolvedId, importer, false, false); } async fetchStaticDependencies(module, resolveStaticDependencyPromises) { - for (const dependency of await Promise.all(resolveStaticDependencyPromises.map(resolveStaticDependencyPromise => resolveStaticDependencyPromise.then(([source, resolvedId]) => this.fetchResolvedDependency(source, module.id, resolvedId))))) { + for (const dependency of await Promise.all(resolveStaticDependencyPromises.map(resolveStaticDependencyPromise => resolveStaticDependencyPromise.then(([source, resolvedId]) => { + if (module.sourcePhaseSources.has(source) && !resolvedId.external) { + return parseAst_js.error(parseAst_js.logNonExternalSourcePhaseImport(source, module.id)); + } + return this.fetchResolvedDependency(source, module.id, resolvedId); + })))) { module.dependencies.add(dependency); dependency.importers.push(module.id); } @@ -23246,7 +23297,7 @@ class Graph { warnForMissingExports() { for (const module of this.modules) { for (const importDescription of module.importDescriptions.values()) { - if (importDescription.name !== '*') { + if (importDescription.name !== '*' && importDescription.phase !== 'source') { const [variable, options] = importDescription.module.getVariableForExportName(importDescription.name, { importChain: [module.id] }); if (!variable) { module.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingExport(importDescription.name, module.id, importDescription.module.id, !!options?.missingButExportExists), importDescription.start); diff --git a/frontend/node_modules/rollup/dist/shared/watch-cli.js b/frontend/node_modules/rollup/dist/shared/watch-cli.js index 63baf27..03f6829 100644 --- a/frontend/node_modules/rollup/dist/shared/watch-cli.js +++ b/frontend/node_modules/rollup/dist/shared/watch-cli.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/dist/shared/watch.js b/frontend/node_modules/rollup/dist/shared/watch.js index 06f4531..4cbaf90 100644 --- a/frontend/node_modules/rollup/dist/shared/watch.js +++ b/frontend/node_modules/rollup/dist/shared/watch.js @@ -1,7 +1,7 @@ /* @license - Rollup.js v4.59.1 - Sat, 21 Mar 2026 06:45:31 GMT - commit 0cba9e079e1d6e56882558827b37557f36c52966 + Rollup.js v4.60.0 + Sun, 22 Mar 2026 06:57:22 GMT - commit 6ecd69fb2ce736c8aabb50829edd227d1792c957 https://github.com/rollup/rollup diff --git a/frontend/node_modules/rollup/package.json b/frontend/node_modules/rollup/package.json index bd4f4e2..5cfc78f 100644 --- a/frontend/node_modules/rollup/package.json +++ b/frontend/node_modules/rollup/package.json @@ -1,6 +1,6 @@ { "name": "rollup", - "version": "4.59.1", + "version": "4.60.0", "description": "Next-generation ES module bundler", "main": "dist/rollup.js", "module": "dist/es/rollup.js", @@ -114,31 +114,31 @@ "homepage": "https://rollupjs.org/", "optionalDependencies": { "fsevents": "~2.3.2", - "@rollup/rollup-darwin-arm64": "4.59.1", - "@rollup/rollup-android-arm64": "4.59.1", - "@rollup/rollup-win32-arm64-msvc": "4.59.1", - "@rollup/rollup-freebsd-arm64": "4.59.1", - "@rollup/rollup-linux-arm64-gnu": "4.59.1", - "@rollup/rollup-linux-arm64-musl": "4.59.1", - "@rollup/rollup-android-arm-eabi": "4.59.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.1", - "@rollup/rollup-linux-arm-musleabihf": "4.59.1", - "@rollup/rollup-win32-ia32-msvc": "4.59.1", - "@rollup/rollup-linux-loong64-gnu": "4.59.1", - "@rollup/rollup-linux-loong64-musl": "4.59.1", - "@rollup/rollup-linux-riscv64-gnu": "4.59.1", - "@rollup/rollup-linux-riscv64-musl": "4.59.1", - "@rollup/rollup-linux-ppc64-gnu": "4.59.1", - "@rollup/rollup-linux-ppc64-musl": "4.59.1", - "@rollup/rollup-linux-s390x-gnu": "4.59.1", - "@rollup/rollup-darwin-x64": "4.59.1", - "@rollup/rollup-win32-x64-gnu": "4.59.1", - "@rollup/rollup-win32-x64-msvc": "4.59.1", - "@rollup/rollup-freebsd-x64": "4.59.1", - "@rollup/rollup-linux-x64-gnu": "4.59.1", - "@rollup/rollup-linux-x64-musl": "4.59.1", - "@rollup/rollup-openbsd-x64": "4.59.1", - "@rollup/rollup-openharmony-arm64": "4.59.1" + "@rollup/rollup-darwin-arm64": "4.60.0", + "@rollup/rollup-android-arm64": "4.60.0", + "@rollup/rollup-win32-arm64-msvc": "4.60.0", + "@rollup/rollup-freebsd-arm64": "4.60.0", + "@rollup/rollup-linux-arm64-gnu": "4.60.0", + "@rollup/rollup-linux-arm64-musl": "4.60.0", + "@rollup/rollup-android-arm-eabi": "4.60.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.0", + "@rollup/rollup-linux-arm-musleabihf": "4.60.0", + "@rollup/rollup-win32-ia32-msvc": "4.60.0", + "@rollup/rollup-linux-loong64-gnu": "4.60.0", + "@rollup/rollup-linux-loong64-musl": "4.60.0", + "@rollup/rollup-linux-riscv64-gnu": "4.60.0", + "@rollup/rollup-linux-riscv64-musl": "4.60.0", + "@rollup/rollup-linux-ppc64-gnu": "4.60.0", + "@rollup/rollup-linux-ppc64-musl": "4.60.0", + "@rollup/rollup-linux-s390x-gnu": "4.60.0", + "@rollup/rollup-darwin-x64": "4.60.0", + "@rollup/rollup-win32-x64-gnu": "4.60.0", + "@rollup/rollup-win32-x64-msvc": "4.60.0", + "@rollup/rollup-freebsd-x64": "4.60.0", + "@rollup/rollup-linux-x64-gnu": "4.60.0", + "@rollup/rollup-linux-x64-musl": "4.60.0", + "@rollup/rollup-openbsd-x64": "4.60.0", + "@rollup/rollup-openharmony-arm64": "4.60.0" }, "dependencies": { "@types/estree": "1.0.8" @@ -176,6 +176,7 @@ "@vue/language-server": "^3.2.5", "acorn": "^8.16.0", "acorn-import-assertions": "^1.9.0", + "acorn-import-phases": "^1.0.4", "acorn-jsx": "^5.3.2", "buble": "^0.20.0", "builtin-modules": "^5.0.0", @@ -186,7 +187,7 @@ "date-time": "^4.0.0", "es5-shim": "^4.6.7", "es6-shim": "^0.35.8", - "eslint": "^10.0.3", + "eslint": "^10.1.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-unicorn": "^63.0.0", diff --git a/frontend/node_modules/svelte/compiler/index.js b/frontend/node_modules/svelte/compiler/index.js index 7eced71..f08280b 100644 --- a/frontend/node_modules/svelte/compiler/index.js +++ b/frontend/node_modules/svelte/compiler/index.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).svelte={})}(this,(function(e){"use strict";function t(e,t,s){const r=s._;let a=!1;function i(e,{next:t,state:n}){t(n)}return function e(t,o,l){if(a)return;if(!t.type)return;let c;const p={},u={path:o,state:l,next:(s=l)=>{o.push(t);for(const n in t){if("type"===n)continue;const r=t[n];if(r&&"object"==typeof r)if(Array.isArray(r)){const t={};r.forEach(((n,r)=>{if(n&&"object"==typeof n){const a=e(n,o,s);a&&(t[r]=a)}})),Object.keys(t).length>0&&(p[n]=r.map(((e,n)=>t[n]??e)))}else{const t=e(r,o,s);t&&(p[n]=t)}}if(o.pop(),Object.keys(p).length>0)return n(t,p)},stop:()=>{a=!0},visit:(n,s=l)=>{o.push(t);const r=e(n,o,s)??n;return o.pop(),r}};let d=s[t.type]??i;if(r){let e;c=r(t,{...u,next:(n=l)=>(l=n,e=d(t,{...u,state:n}),e)}),!c&&e&&(c=e)}else c=d(t,u);return c||Object.keys(p).length>0&&(c=n(t,p)),c||void 0}(e,[],t)??e}function n(e,t){const n={},s=Object.getOwnPropertyDescriptors(e);for(const e in s)Object.defineProperty(n,e,s[e]);for(const e in t)n[e]=t[e];return n}const s=/\s/,r=/\s+/,a=/^\r?\n/,i=/^\s/,o=/^[ \t\r\n]+/,l=/\s$/,c=/[ \t\r\n]+$/,p=/[^ \t\r\n]/,u=/[ \t\n\r\f]+/g,d=/^[ \t\n\r\f]+$/,h=/[^\n]/g,m=/^[a-zA-Z_$][a-zA-Z_$0-9]*$/,f=/(^[^a-zA-Z_$]|[^a-zA-Z0-9_$])/g,y=/^[aeiou]/,v=/^h[1-6]$/,g=/(^[0-9-.])|[\^$@%&#?!|()[\]{}^*+~;]/,b=/[\u202a\u202b\u202c\u202d\u202e\u2066\u2067\u2068\u2069]+/g,_=/^\W*javascript:/i,x=/\b(image|picture|photo)\b/i,w=1,k=2,C=4,S=8,P=16,E=4,T=8,A=1,$=2,R=4,I="http://www.w3.org/2000/svg",M="http://www.w3.org/1998/Math/MathML";function q(e,t){if(0===t.length)return null;const n=new j(t).get(e);return n&&n[0][0]>.7?n[0][1]:null}function L(e,t){if(null===e&&null===t)throw"Trying to compare two null values";if(null===e||null===t)return 0;const n=function(e,t){const n=[];let s=0;for(let r=0;r<=t.length;r++)for(let a=0;a<=e.length;a++){let i;i=r&&a?e.charAt(a-1)===t.charAt(r-1)?s:Math.min(n[a],n[a-1],s)+1:r+a,s=n[a],n[a]=i}return n.pop()}(e=String(e),t=String(t));return 1-n/Math.max(e.length,t.length)}const O=/[^\w, ]+/;function N(e,t=2){const n={},s=function(e,t=2){const n="-"+e.toLowerCase().replace(O,"")+"-",s=t-n.length,r=[];if(s>0)for(let t=0;t=2;--t){const n=this.__get(e,t);if(n.length>0)return n}return null}__get(e,t){const n=e.toLowerCase(),s={},r=N(n,t),a=this.items[t];let i,o,l,c,p,u=0;for(i in r)if(o=r[i],u+=Math.pow(o,2),i in this.match_dict)for(l=0;l{const n=r+e.length+1,s={start:r,end:n,line:t};return r=n,s}));let i=0;return function(t,r){if("string"==typeof t&&(t=e.indexOf(t,r??0)),-1===t)return;let o=a[i];const l=t>=o.end?1:-1;for(;o;){if(B(o,t))return{line:n+o.line,column:s+t-o.start,character:t};i+=l,o=a[i]}}}const V=/\r/g;function H(e){let t=5381,n=(e=e.replace(V,"")).length;for(;n--;)t=(t<<5)-t^e.charCodeAt(n);return(t>>>0).toString(36)}const U=["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"];function z(e){return U.includes(e)||"!doctype"===e.toLowerCase()}const W=["arguments","await","break","case","catch","class","const","continue","debugger","default","delete","do","else","enum","eval","export","extends","false","finally","for","function","if","implements","import","in","instanceof","interface","let","new","null","package","private","protected","public","return","static","super","switch","this","throw","true","try","typeof","var","void","while","with","yield"];function G(e){return W.includes(e)}const K=["beforeinput","click","change","dblclick","contextmenu","focusin","focusout","input","keydown","keyup","mousedown","mousemove","mouseout","mouseover","mouseup","pointerdown","pointermove","pointerout","pointerover","pointerup","touchend","touchmove","touchstart"];const X=["allowfullscreen","async","autofocus","autoplay","checked","controls","default","disabled","formnovalidate","indeterminate","inert","ismap","loop","multiple","muted","nomodule","novalidate","open","playsinline","readonly","required","reversed","seamless","selected","webkitdirectory","defer","disablepictureinpicture","disableremoteplayback"];function Q(e){return X.includes(e)}const Y={formnovalidate:"formNoValidate",ismap:"isMap",nomodule:"noModule",playsinline:"playsInline",readonly:"readOnly",defaultvalue:"defaultValue",defaultchecked:"defaultChecked",srcobject:"srcObject",novalidate:"noValidate",allowfullscreen:"allowFullscreen",disablepictureinpicture:"disablePictureInPicture",disableremoteplayback:"disableRemotePlayback"};const J=[...X,"formNoValidate","isMap","noModule","playsInline","readOnly","value","volume","defaultValue","defaultChecked","srcObject","noValidate","allowFullscreen","disablePictureInPicture","disableRemotePlayback"];const Z=["autofocus","muted","defaultValue","defaultChecked"];function ee(e){return Z.includes(e)}const te=["touchstart","touchmove"];const ne=["textContent","innerHTML","innerText"];function se(e){return ne.includes(e)}const re=["body","embed","iframe","img","link","object","script","style","track"];function ae(e){return re.includes(e)}const ie=["altGlyph","altGlyphDef","altGlyphItem","animate","animateColor","animateMotion","animateTransform","circle","clipPath","color-profile","cursor","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","font","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignObject","g","glyph","glyphRef","hatch","hatchpath","hkern","image","line","linearGradient","marker","mask","mesh","meshgradient","meshpatch","meshrow","metadata","missing-glyph","mpath","path","pattern","polygon","polyline","radialGradient","rect","set","solidcolor","stop","svg","switch","symbol","text","textPath","tref","tspan","unknown","use","view","vkern"];function oe(e){return ie.includes(e)}const le=["annotation","annotation-xml","maction","math","merror","mfrac","mi","mmultiscripts","mn","mo","mover","mpadded","mphantom","mprescripts","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msubsup","msup","mtable","mtd","mtext","mtr","munder","munderover","semantics"];function ce(e){return le.includes(e)}const pe=["$state","$state.raw","$derived","$derived.by"],ue=[...pe,"$state.eager","$state.snapshot","$props","$props.id","$bindable","$effect","$effect.pre","$effect.tracking","$effect.root","$effect.pending","$inspect","$inspect().with","$inspect.trace","$host"];function de(e){return ue.includes(e)}const he=/^[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9.\-_\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u{10000}-\u{EFFFF}]+)*$/u;let me,fe=[];const ye="(unknown)";let ve,ge,be,_e,xe="",we=[],ke=!1;function Ce(e){ve=e,we=ve.split("\n");const t=F(ve,{offsetLine:1});be=e=>{const n=t(e);if(!n)throw new Error("An impossible situation occurred");return n}}function Se(e){const t=be(e.start);return`${n=me,n?.replace(/\//g,"/​")}:${t?.line}:${t.column}`;var n}let Pe=[],Ee=new Map,Te=null;function Ae(e,t){return ge&&!!Ee.get(e)?.some((e=>e.has(t)))}function $e(e){ge=!1,ke=!1,xe=ye,ve="",we=[],me=(e.filename??ye).replace(/\\/g,"/"),_e=e.warning??(()=>!0),fe=[]}function Re(e){const t=e.rootDir?.replace(/\\/g,"/");ge=e.dev,ke=e.runes,xe=e.component_name??ye,"string"==typeof t&&me.startsWith(t)&&(me=me.replace(t,"").replace(/^[/\\]/,"")),Pe=[],Ee.clear(),Te=null}const Ie=/^\t+/;function Me(e){return e.replace(Ie,(e=>e.split("\t").join(" ")))}class qe{name="CompileDiagnostic";constructor(e,t,n){this.code=e,this.message=t,me!==ye&&(this.filename=me),n&&(this.position=n,this.start=be(n[0]),this.end=be(n[1]),this.start&&this.end&&(this.frame=function(e,t){const n=we,s=Math.max(0,e-2),r=Math.min(e+3,n.length),a=String(r+1).length;return n.slice(s,r).map(((n,r)=>{const i=s+r===e,o=String(r+s+1).padStart(a," ");if(i){const e=" ".repeat(a+2+Me(n.slice(0,t)).length)+"^";return`${o}: ${Me(n)}\n${e}`}return`${o}: ${Me(n)}`})).join("\n")}(this.start.line-1,this.end.column)))}toString(){let e=`${this.code}: ${this.message}`;return this.filename&&(e+=`\n${this.filename}`,this.start&&(e+=`:${this.start.line}:${this.start.column}`)),this.frame&&(e+=`\n${this.frame}`),e}toJSON(){return{code:this.code,message:this.message,filename:this.filename,start:this.start,end:this.end,position:this.position,frame:this.frame}}}class Le extends qe{name="CompileWarning";constructor(e,t,n){super(e,t,n)}}function Oe(e,t,n){let s=Pe;if(e&&(s=Ee.get(e)??Pe),s&&s.at(-1)?.has(t))return;const r=new Le(t,n,e&&void 0!==e.start?[e.start,e.end??e.start]:void 0);_e(r)&&fe.push(r)}function Ne(e){Oe(e,"a11y_accesskey","Avoid using accesskey\nhttps://svelte.dev/e/a11y_accesskey")}function De(e){Oe(e,"a11y_aria_activedescendant_has_tabindex","An element with an aria-activedescendant attribute should have a tabindex value\nhttps://svelte.dev/e/a11y_aria_activedescendant_has_tabindex")}function je(e,t){Oe(e,"a11y_aria_attributes",`\`<${t}>\` should not have aria-* attributes\nhttps://svelte.dev/e/a11y_aria_attributes`)}function Be(e){Oe(e,"a11y_autofocus","Avoid using autofocus\nhttps://svelte.dev/e/a11y_autofocus")}function Fe(e,t){Oe(e,"a11y_hidden",`\`<${t}>\` element should not be hidden\nhttps://svelte.dev/e/a11y_hidden`)}function Ve(e,t,n){Oe(e,"a11y_incorrect_aria_attribute_type",`The value of '${t}' must be a ${n}\nhttps://svelte.dev/e/a11y_incorrect_aria_attribute_type`)}function He(e,t){Oe(e,"a11y_interactive_supports_focus",`Elements with the '${t}' interactive role must have a tabindex value\nhttps://svelte.dev/e/a11y_interactive_supports_focus`)}function Ue(e,t){Oe(e,"a11y_misplaced_role",`\`<${t}>\` should not have role attribute\nhttps://svelte.dev/e/a11y_misplaced_role`)}function ze(e){Oe(e,"a11y_misplaced_scope","The scope attribute should only be used with `` elements\nhttps://svelte.dev/e/a11y_misplaced_scope")}function We(e,t,n){Oe(e,"a11y_mouse_events_have_key_events",`'${t}' event must be accompanied by '${n}' event\nhttps://svelte.dev/e/a11y_mouse_events_have_key_events`)}function Ge(e,t){Oe(e,"a11y_no_abstract_role",`Abstract role '${t}' is forbidden\nhttps://svelte.dev/e/a11y_no_abstract_role`)}function Ke(e,t,n){Oe(e,"a11y_no_interactive_element_to_noninteractive_role",`\`<${t}>\` cannot have role '${n}'\nhttps://svelte.dev/e/a11y_no_interactive_element_to_noninteractive_role`)}function Xe(e,t,n){Oe(e,"a11y_no_noninteractive_element_to_interactive_role",`Non-interactive element \`<${t}>\` cannot have interactive role '${n}'\nhttps://svelte.dev/e/a11y_no_noninteractive_element_to_interactive_role`)}function Qe(e,t){Oe(e,"a11y_no_redundant_roles",`Redundant role '${t}'\nhttps://svelte.dev/e/a11y_no_redundant_roles`)}function Ye(e){Oe(e,"a11y_positive_tabindex","Avoid tabindex values above zero\nhttps://svelte.dev/e/a11y_positive_tabindex")}function Je(e,t,n){Oe(e,"a11y_role_has_required_aria_props",`Elements with the ARIA role "${t}" must have the following attributes defined: ${n}\nhttps://svelte.dev/e/a11y_role_has_required_aria_props`)}function Ze(e,t,n){Oe(e,"a11y_role_supports_aria_props",`The attribute '${t}' is not supported by the role '${n}'\nhttps://svelte.dev/e/a11y_role_supports_aria_props`)}function et(e,t,n,s){Oe(e,"a11y_role_supports_aria_props_implicit",`The attribute '${t}' is not supported by the role '${n}'. This role is implicit on the element \`<${s}>\`\nhttps://svelte.dev/e/a11y_role_supports_aria_props_implicit`)}function tt(e,t,n){Oe(e,"a11y_unknown_aria_attribute",(n?`Unknown aria attribute 'aria-${t}'. Did you mean '${n}'?`:`Unknown aria attribute 'aria-${t}'`)+"\nhttps://svelte.dev/e/a11y_unknown_aria_attribute")}function nt(e,t,n){Oe(e,"a11y_unknown_role",(n?`Unknown role '${t}'. Did you mean '${n}'?`:`Unknown role '${t}'`)+"\nhttps://svelte.dev/e/a11y_unknown_role")}function st(e){Oe(e,"bidirectional_control_characters","A bidirectional control character was detected in your code. These characters can be used to alter the visual direction of your code and could have unintended consequences\nhttps://svelte.dev/e/bidirectional_control_characters")}function rt(e,t,n){Oe(e,"legacy_code",`\`${t}\` is no longer valid — please use \`${n}\` instead\nhttps://svelte.dev/e/legacy_code`)}function at(e,t,n){Oe(e,"unknown_code",(n?`\`${t}\` is not a recognised code (did you mean \`${n}\`?)`:`\`${t}\` is not a recognised code`)+"\nhttps://svelte.dev/e/unknown_code")}function it(e){Oe(e,"options_deprecated_accessors","The `accessors` option has been deprecated. It will have no effect in runes mode\nhttps://svelte.dev/e/options_deprecated_accessors")}function ot(e){Oe(e,"options_deprecated_immutable","The `immutable` option has been deprecated. It will have no effect in runes mode\nhttps://svelte.dev/e/options_deprecated_immutable")}function lt(e){Oe(e,"options_missing_custom_element","The `customElement` option is used when generating a custom element. Did you forget the `customElement: true` compile option?\nhttps://svelte.dev/e/options_missing_custom_element")}function ct(e){Oe(e,"options_renamed_ssr_dom",'`generate: "dom"` and `generate: "ssr"` options have been renamed to "client" and "server" respectively\nhttps://svelte.dev/e/options_renamed_ssr_dom')}function pt(e,t){Oe(e,"export_let_unused",`Component has unused export property '${t}'. If it is for external reference only, please consider using \`export const ${t}\`\nhttps://svelte.dev/e/export_let_unused`)}function ut(e,t){Oe(e,"non_reactive_update",`\`${t}\` is updated, but is not declared with \`$state(...)\`. Changing its value will not correctly trigger updates\nhttps://svelte.dev/e/non_reactive_update`)}function dt(e,t){Oe(e,"store_rune_conflict",`It looks like you're using the \`$${t}\` rune, but there is a local binding called \`${t}\`. Referencing a local variable with a \`$\` prefix will create a store subscription. Please rename \`${t}\` to avoid the ambiguity\nhttps://svelte.dev/e/store_rune_conflict`)}function ht(e){Oe(e,"attribute_avoid_is",'The "is" attribute is not supported cross-browser and should be avoided\nhttps://svelte.dev/e/attribute_avoid_is')}function mt(e,t){Oe(e,"attribute_global_event_reference",`You are referencing \`globalThis.${t}\`. Did you forget to declare a variable with that name?\nhttps://svelte.dev/e/attribute_global_event_reference`)}function ft(e,t,n){Oe(e,"attribute_invalid_property_name",`'${t}' is not a valid HTML attribute. Did you mean '${n}'?\nhttps://svelte.dev/e/attribute_invalid_property_name`)}function yt(e,t,n){Oe(e,"element_implicitly_closed",`This element is implicitly closed by the following \`${t}\`, which can cause an unexpected DOM structure. Add an explicit \`${n}\` to avoid surprises.\nhttps://svelte.dev/e/element_implicitly_closed`)}function vt(e,t){Oe(e,"node_invalid_placement_ssr",`${t}. When rendering this component on the server, the resulting HTML will be modified by the browser (by moving, removing, or inserting elements), likely resulting in a \`hydration_mismatch\` warning\nhttps://svelte.dev/e/node_invalid_placement_ssr`)}function gt(e){Oe(e,"script_unknown_attribute","Unrecognized attribute — should be one of `generics`, `lang` or `module`. If this exists for a preprocessor, ensure that the preprocessor removes it\nhttps://svelte.dev/e/script_unknown_attribute")}const bt=/^\s*svelte-ignore\s/,_t={"non-top-level-reactive-declaration":"reactive_declaration_invalid_placement","module-script-reactive-declaration":"reactive_declaration_module_script","empty-block":"block_empty","avoid-is":"attribute_avoid_is","invalid-html-attribute":"attribute_invalid_property_name","a11y-structure":"a11y_figcaption_parent","illegal-attribute-character":"attribute_illegal_colon","invalid-rest-eachblock-binding":"bind_invalid_each_rest","unused-export-let":"export_let_unused"},xt=["a11y_accesskey","a11y_aria_activedescendant_has_tabindex","a11y_aria_attributes","a11y_autocomplete_valid","a11y_autofocus","a11y_click_events_have_key_events","a11y_consider_explicit_label","a11y_distracting_elements","a11y_figcaption_index","a11y_figcaption_parent","a11y_hidden","a11y_img_redundant_alt","a11y_incorrect_aria_attribute_type","a11y_incorrect_aria_attribute_type_boolean","a11y_incorrect_aria_attribute_type_id","a11y_incorrect_aria_attribute_type_idlist","a11y_incorrect_aria_attribute_type_integer","a11y_incorrect_aria_attribute_type_token","a11y_incorrect_aria_attribute_type_tokenlist","a11y_incorrect_aria_attribute_type_tristate","a11y_interactive_supports_focus","a11y_invalid_attribute","a11y_label_has_associated_control","a11y_media_has_caption","a11y_misplaced_role","a11y_misplaced_scope","a11y_missing_attribute","a11y_missing_content","a11y_mouse_events_have_key_events","a11y_no_abstract_role","a11y_no_interactive_element_to_noninteractive_role","a11y_no_noninteractive_element_interactions","a11y_no_noninteractive_element_to_interactive_role","a11y_no_noninteractive_tabindex","a11y_no_redundant_roles","a11y_no_static_element_interactions","a11y_positive_tabindex","a11y_role_has_required_aria_props","a11y_role_supports_aria_props","a11y_role_supports_aria_props_implicit","a11y_unknown_aria_attribute","a11y_unknown_role","bidirectional_control_characters","legacy_code","unknown_code","options_deprecated_accessors","options_deprecated_immutable","options_missing_custom_element","options_removed_enable_sourcemap","options_removed_hydratable","options_removed_loop_guard_timeout","options_renamed_ssr_dom","custom_element_props_identifier","export_let_unused","legacy_component_creation","non_reactive_update","perf_avoid_inline_class","perf_avoid_nested_class","reactive_declaration_invalid_placement","reactive_declaration_module_script_dependency","state_referenced_locally","store_rune_conflict","css_unused_selector","attribute_avoid_is","attribute_global_event_reference","attribute_illegal_colon","attribute_invalid_property_name","attribute_quoted","bind_invalid_each_rest","block_empty","component_name_lowercase","element_implicitly_closed","element_invalid_self_closing_tag","event_directive_deprecated","node_invalid_placement_ssr","script_context_deprecated","script_unknown_attribute","slot_element_deprecated","svelte_component_deprecated","svelte_element_invalid_this","svelte_self_deprecated"].concat(["await_waterfall","await_reactivity_loss","state_snapshot_uncloneable","binding_property_non_reactive","hydration_attribute_changed","hydration_html_changed","ownership_invalid_binding","ownership_invalid_mutation"]);function wt(e,t,n){const s=bt.exec(t);if(!s)return[];let r=s[0].length;e+=r;const a=[];if(n)for(const n of t.slice(r).matchAll(/([\w$-]+)(,)?/gm)){const t=n[1];if(xt.includes(t))a.push(t);else{const s=_t[t]??t.replace(/-/g,"_"),r=e+n.index,a=r+t.length;if(xt.includes(s))rt({start:r,end:a},t,s);else{at({start:r,end:a},t,q(t,xt))}}if(!n[2])break}else for(const e of t.slice(r).matchAll(/[\w$-]+/gm)){const t=e[0];if(a.push(t),!xt.includes(t)){const e=_t[t]??t.replace(/-/g,"_");xt.includes(e)&&a.push(e)}}return a}function kt(e){const t=bt.exec(e);if(!t)return e;const n=t[0].length;return e.substring(0,n)+e.substring(n).replace(/\w+-\w+(-\w+)*/g,((t,s,r)=>{let a=_t[t]??t.replace(/-/g,"_");return/\w+-\w+/.test(e.substring(n+r+t.length))&&(a+=","),a}))}function Ct(e){const t=e.at(0),n=e.at(-1);"Text"===t?.type&&(p.test(t.data)?t.data=t.data.replace(o,""):e.shift()),"Text"===n?.type&&(p.test(n.data)?n.data=n.data.replace(c,""):e.pop())}var St=[509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,7,9,32,4,318,1,80,3,71,10,50,3,123,2,54,14,32,10,3,1,11,3,46,10,8,0,46,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,2,11,83,11,7,0,3,0,158,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,68,8,2,0,3,0,2,3,2,4,2,0,15,1,83,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,7,19,58,14,5,9,243,14,166,9,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,343,9,54,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,10,1,2,0,49,6,4,4,14,10,5350,0,7,14,11465,27,2343,9,87,9,39,4,60,6,26,9,535,9,470,0,2,54,8,3,82,0,12,1,19628,1,4178,9,519,45,3,22,543,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,101,0,161,6,10,9,357,0,62,13,499,13,245,1,2,9,726,6,110,6,6,9,4759,9,787719,239],Pt=[0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,13,10,2,14,2,6,2,1,2,10,2,14,2,6,2,1,4,51,13,310,10,21,11,7,25,5,2,41,2,8,70,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,39,27,10,22,251,41,7,1,17,2,60,28,11,0,9,21,43,17,47,20,28,22,13,52,58,1,3,0,14,44,33,24,27,35,30,0,3,0,9,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,20,1,64,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,31,9,2,0,3,0,2,37,2,0,26,0,2,0,45,52,19,3,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,38,6,186,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,19,72,200,32,32,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,16,0,2,12,2,33,125,0,80,921,103,110,18,195,2637,96,16,1071,18,5,26,3994,6,582,6842,29,1763,568,8,30,18,78,18,29,19,47,17,3,32,20,6,18,433,44,212,63,129,74,6,0,67,12,65,1,2,0,29,6135,9,1237,42,9,8936,3,2,6,2,1,2,290,16,0,30,2,3,0,15,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,1845,30,7,5,262,61,147,44,11,6,17,0,322,29,19,43,485,27,229,29,3,0,496,6,2,3,2,1,2,14,2,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42719,33,4153,7,221,3,5761,15,7472,16,621,2467,541,1507,4938,6,4191],Et="ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙՠ-ֈא-תׯ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࡠ-ࡪࡰ-ࢇࢉ-ࢎࢠ-ࣉऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱৼਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡૹଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘ-ౚౝౠౡಀಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೝೞೠೡೱೲഄ-ഌഎ-ഐഒ-ഺഽൎൔ-ൖൟ-ൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄຆ-ຊຌ-ຣລວ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜑᜟ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡸᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭌᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᲀ-ᲊᲐ-ᲺᲽ-Ჿᳩ-ᳬᳮ-ᳳᳵᳶᳺᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄯㄱ-ㆎㆠ-ㆿㇰ-ㇿ㐀-䶿一-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꟍꟐꟑꟓꟕ-Ƛꟲ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꣽꣾꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭩꭰ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ",Tt={3:"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",5:"class enum extends super const export import",6:"enum",strict:"implements interface let package private protected public static yield",strictBind:"eval arguments"},At="break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this",$t={5:At,"5module":At+" export import",6:At+" const class extends export import super"},Rt=/^in(stanceof)?$/,It=new RegExp("["+Et+"]"),Mt=new RegExp("["+Et+"‌‍·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࢗ-࢟࣊-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍୕-ୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఄ఼ా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ೳഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ඁ-ඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ຼ່-໎໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜕ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠏-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᪿ-ᫎᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭᳴᳷-᳹᷀-᷿‌‍‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯・꘠-꘩꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧ꠬ꢀꢁꢴ-ꣅ꣐-꣙꣠-꣱ꣿ-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︯︳︴﹍-﹏0-9_・]");function qt(e,t){for(var n=65536,s=0;se)return!1;if((n+=t[s+1])>=e)return!0}return!1}function Lt(e,t){return e<65?36===e:e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&It.test(String.fromCharCode(e)):!1!==t&&qt(e,Pt)))}function Ot(e,t){return e<48?36===e:e<58||!(e<65)&&(e<91||(e<97?95===e:e<123||(e<=65535?e>=170&&Mt.test(String.fromCharCode(e)):!1!==t&&(qt(e,Pt)||qt(e,St)))))}var Nt=function(e,t){void 0===t&&(t={}),this.label=e,this.keyword=t.keyword,this.beforeExpr=!!t.beforeExpr,this.startsExpr=!!t.startsExpr,this.isLoop=!!t.isLoop,this.isAssign=!!t.isAssign,this.prefix=!!t.prefix,this.postfix=!!t.postfix,this.binop=t.binop||null,this.updateContext=null};function Dt(e,t){return new Nt(e,{beforeExpr:!0,binop:t})}var jt={beforeExpr:!0},Bt={startsExpr:!0},Ft={};function Vt(e,t){return void 0===t&&(t={}),t.keyword=e,Ft[e]=new Nt(e,t)}var Ht={num:new Nt("num",Bt),regexp:new Nt("regexp",Bt),string:new Nt("string",Bt),name:new Nt("name",Bt),privateId:new Nt("privateId",Bt),eof:new Nt("eof"),bracketL:new Nt("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new Nt("]"),braceL:new Nt("{",{beforeExpr:!0,startsExpr:!0}),braceR:new Nt("}"),parenL:new Nt("(",{beforeExpr:!0,startsExpr:!0}),parenR:new Nt(")"),comma:new Nt(",",jt),semi:new Nt(";",jt),colon:new Nt(":",jt),dot:new Nt("."),question:new Nt("?",jt),questionDot:new Nt("?."),arrow:new Nt("=>",jt),template:new Nt("template"),invalidTemplate:new Nt("invalidTemplate"),ellipsis:new Nt("...",jt),backQuote:new Nt("`",Bt),dollarBraceL:new Nt("${",{beforeExpr:!0,startsExpr:!0}),eq:new Nt("=",{beforeExpr:!0,isAssign:!0}),assign:new Nt("_=",{beforeExpr:!0,isAssign:!0}),incDec:new Nt("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new Nt("!/~",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:Dt("||",1),logicalAND:Dt("&&",2),bitwiseOR:Dt("|",3),bitwiseXOR:Dt("^",4),bitwiseAND:Dt("&",5),equality:Dt("==/!=/===/!==",6),relational:Dt("/<=/>=",7),bitShift:Dt("<>/>>>",8),plusMin:new Nt("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:Dt("%",10),star:Dt("*",10),slash:Dt("/",10),starstar:new Nt("**",{beforeExpr:!0}),coalesce:Dt("??",1),_break:Vt("break"),_case:Vt("case",jt),_catch:Vt("catch"),_continue:Vt("continue"),_debugger:Vt("debugger"),_default:Vt("default",jt),_do:Vt("do",{isLoop:!0,beforeExpr:!0}),_else:Vt("else",jt),_finally:Vt("finally"),_for:Vt("for",{isLoop:!0}),_function:Vt("function",Bt),_if:Vt("if"),_return:Vt("return",jt),_switch:Vt("switch"),_throw:Vt("throw",jt),_try:Vt("try"),_var:Vt("var"),_const:Vt("const"),_while:Vt("while",{isLoop:!0}),_with:Vt("with"),_new:Vt("new",{beforeExpr:!0,startsExpr:!0}),_this:Vt("this",Bt),_super:Vt("super",Bt),_class:Vt("class",Bt),_extends:Vt("extends",jt),_export:Vt("export"),_import:Vt("import",Bt),_null:Vt("null",Bt),_true:Vt("true",Bt),_false:Vt("false",Bt),_in:Vt("in",{beforeExpr:!0,binop:7}),_instanceof:Vt("instanceof",{beforeExpr:!0,binop:7}),_typeof:Vt("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:Vt("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:Vt("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},Ut=/\r\n?|\n|\u2028|\u2029/,zt=new RegExp(Ut.source,"g");function Wt(e){return 10===e||13===e||8232===e||8233===e}function Gt(e,t,n){void 0===n&&(n=e.length);for(var s=t;s>10),56320+(1023&e)))}var rn=/(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/,an=function(e,t){this.line=e,this.column=t};an.prototype.offset=function(e){return new an(this.line,this.column+e)};var on=function(e,t,n){this.start=t,this.end=n,null!==e.sourceFile&&(this.source=e.sourceFile)};function ln(e,t){for(var n=1,s=0;;){var r=Gt(e,s,t);if(r<0)return new an(n,t-s);++n,s=r}}var cn={ecmaVersion:null,sourceType:"script",onInsertedSemicolon:null,onTrailingComma:null,allowReserved:null,allowReturnOutsideFunction:!1,allowImportExportEverywhere:!1,allowAwaitOutsideFunction:null,allowSuperOutsideMethod:null,allowHashBang:!1,checkPrivateFields:!0,locations:!1,onToken:null,onComment:null,ranges:!1,program:null,sourceFile:null,directSourceFile:null,preserveParens:!1},pn=!1;function un(e){var t={};for(var n in cn)t[n]=e&&Zt(e,n)?e[n]:cn[n];if("latest"===t.ecmaVersion?t.ecmaVersion=1e8:null==t.ecmaVersion?(!pn&&"object"==typeof console&&console.warn&&(pn=!0,console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future.")),t.ecmaVersion=11):t.ecmaVersion>=2015&&(t.ecmaVersion-=2009),null==t.allowReserved&&(t.allowReserved=t.ecmaVersion<5),e&&null!=e.allowHashBang||(t.allowHashBang=t.ecmaVersion>=14),en(t.onToken)){var s=t.onToken;t.onToken=function(e){return s.push(e)}}return en(t.onComment)&&(t.onComment=function(e,t){return function(n,s,r,a,i,o){var l={type:n?"Block":"Line",value:s,start:r,end:a};e.locations&&(l.loc=new on(this,i,o)),e.ranges&&(l.range=[r,a]),t.push(l)}}(t,t.onComment)),t}var dn=256,hn=259;function mn(e,t){return 2|(e?4:0)|(t?8:0)}var fn=function(e,t,n){this.options=e=un(e),this.sourceFile=e.sourceFile,this.keywords=nn($t[e.ecmaVersion>=6?6:"module"===e.sourceType?"5module":5]);var s="";!0!==e.allowReserved&&(s=Tt[e.ecmaVersion>=6?6:5===e.ecmaVersion?5:3],"module"===e.sourceType&&(s+=" await")),this.reservedWords=nn(s);var r=(s?s+" ":"")+Tt.strict;this.reservedWordsStrict=nn(r),this.reservedWordsStrictBind=nn(r+" "+Tt.strictBind),this.input=String(t),this.containsEsc=!1,n?(this.pos=n,this.lineStart=this.input.lastIndexOf("\n",n-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(Ut).length):(this.pos=this.lineStart=0,this.curLine=1),this.type=Ht.eof,this.value=null,this.start=this.end=this.pos,this.startLoc=this.endLoc=this.curPosition(),this.lastTokEndLoc=this.lastTokStartLoc=null,this.lastTokStart=this.lastTokEnd=this.pos,this.context=this.initialContext(),this.exprAllowed=!0,this.inModule="module"===e.sourceType,this.strict=this.inModule||this.strictDirective(this.pos),this.potentialArrowAt=-1,this.potentialArrowInForAwait=!1,this.yieldPos=this.awaitPos=this.awaitIdentPos=0,this.labels=[],this.undefinedExports=Object.create(null),0===this.pos&&e.allowHashBang&&"#!"===this.input.slice(0,2)&&this.skipLineComment(2),this.scopeStack=[],this.enterScope(1),this.regexpState=null,this.privateNameStack=[]},yn={inFunction:{configurable:!0},inGenerator:{configurable:!0},inAsync:{configurable:!0},canAwait:{configurable:!0},allowSuper:{configurable:!0},allowDirectSuper:{configurable:!0},treatFunctionsAsVar:{configurable:!0},allowNewDotTarget:{configurable:!0},inClassStaticBlock:{configurable:!0}};fn.prototype.parse=function(){var e=this.options.program||this.startNode();return this.nextToken(),this.parseTopLevel(e)},yn.inFunction.get=function(){return(2&this.currentVarScope().flags)>0},yn.inGenerator.get=function(){return(8&this.currentVarScope().flags)>0},yn.inAsync.get=function(){return(4&this.currentVarScope().flags)>0},yn.canAwait.get=function(){for(var e=this.scopeStack.length-1;e>=0;e--){var t=this.scopeStack[e].flags;if(768&t)return!1;if(2&t)return(4&t)>0}return this.inModule&&this.options.ecmaVersion>=13||this.options.allowAwaitOutsideFunction},yn.allowSuper.get=function(){return(64&this.currentThisScope().flags)>0||this.options.allowSuperOutsideMethod},yn.allowDirectSuper.get=function(){return(128&this.currentThisScope().flags)>0},yn.treatFunctionsAsVar.get=function(){return this.treatFunctionsAsVarInScope(this.currentScope())},yn.allowNewDotTarget.get=function(){for(var e=this.scopeStack.length-1;e>=0;e--){var t=this.scopeStack[e].flags;if(768&t||2&t&&!(16&t))return!0}return!1},yn.inClassStaticBlock.get=function(){return(this.currentVarScope().flags&dn)>0},fn.extend=function(){for(var e=[],t=arguments.length;t--;)e[t]=arguments[t];for(var n=this,s=0;s=,?^&]/.test(r)||"!"===r&&"="===this.input.charAt(s+1))}e+=t[0].length,Xt.lastIndex=e,e+=Xt.exec(this.input)[0].length,";"===this.input[e]&&e++}},vn.eat=function(e){return this.type===e&&(this.next(),!0)},vn.isContextual=function(e){return this.type===Ht.name&&this.value===e&&!this.containsEsc},vn.eatContextual=function(e){return!!this.isContextual(e)&&(this.next(),!0)},vn.expectContextual=function(e){this.eatContextual(e)||this.unexpected()},vn.canInsertSemicolon=function(){return this.type===Ht.eof||this.type===Ht.braceR||Ut.test(this.input.slice(this.lastTokEnd,this.start))},vn.insertSemicolon=function(){if(this.canInsertSemicolon())return this.options.onInsertedSemicolon&&this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc),!0},vn.semicolon=function(){this.eat(Ht.semi)||this.insertSemicolon()||this.unexpected()},vn.afterTrailingComma=function(e,t){if(this.type===e)return this.options.onTrailingComma&&this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc),t||this.next(),!0},vn.expect=function(e){this.eat(e)||this.unexpected()},vn.unexpected=function(e){this.raise(null!=e?e:this.start,"Unexpected token")};var bn=function(){this.shorthandAssign=this.trailingComma=this.parenthesizedAssign=this.parenthesizedBind=this.doubleProto=-1};vn.checkPatternErrors=function(e,t){if(e){e.trailingComma>-1&&this.raiseRecoverable(e.trailingComma,"Comma is not permitted after the rest element");var n=t?e.parenthesizedAssign:e.parenthesizedBind;n>-1&&this.raiseRecoverable(n,t?"Assigning to rvalue":"Parenthesized pattern")}},vn.checkExpressionErrors=function(e,t){if(!e)return!1;var n=e.shorthandAssign,s=e.doubleProto;if(!t)return n>=0||s>=0;n>=0&&this.raise(n,"Shorthand property assignments are valid only in destructuring patterns"),s>=0&&this.raiseRecoverable(s,"Redefinition of __proto__ property")},vn.checkYieldAwaitInDefaultParams=function(){this.yieldPos&&(!this.awaitPos||this.yieldPos55295&&s<56320)return!0;if(Lt(s,!0)){for(var r=n+1;Ot(s=this.input.charCodeAt(r),!0);)++r;if(92===s||s>55295&&s<56320)return!0;var a=this.input.slice(n,r);if(!Rt.test(a))return!0}return!1},_n.isAsyncFunction=function(){if(this.options.ecmaVersion<8||!this.isContextual("async"))return!1;Xt.lastIndex=this.pos;var e,t=Xt.exec(this.input),n=this.pos+t[0].length;return!(Ut.test(this.input.slice(this.pos,n))||"function"!==this.input.slice(n,n+8)||n+8!==this.input.length&&(Ot(e=this.input.charCodeAt(n+8))||e>55295&&e<56320))},_n.isUsingKeyword=function(e,t){if(this.options.ecmaVersion<17||!this.isContextual(e?"await":"using"))return!1;Xt.lastIndex=this.pos;var n=Xt.exec(this.input),s=this.pos+n[0].length;if(Ut.test(this.input.slice(this.pos,s)))return!1;if(e){var r,a=s+5;if("using"!==this.input.slice(s,a)||a===this.input.length||Ot(r=this.input.charCodeAt(a))||r>55295&&r<56320)return!1;Xt.lastIndex=a;var i=Xt.exec(this.input);if(i&&Ut.test(this.input.slice(a,a+i[0].length)))return!1}if(t){var o,l=s+2;if(!("of"!==this.input.slice(s,l)||l!==this.input.length&&(Ot(o=this.input.charCodeAt(l))||o>55295&&o<56320)))return!1}var c=this.input.charCodeAt(s);return Lt(c,!0)||92===c},_n.isAwaitUsing=function(e){return this.isUsingKeyword(!0,e)},_n.isUsing=function(e){return this.isUsingKeyword(!1,e)},_n.parseStatement=function(e,t,n){var s,r=this.type,a=this.startNode();switch(this.isLet(e)&&(r=Ht._var,s="let"),r){case Ht._break:case Ht._continue:return this.parseBreakContinueStatement(a,r.keyword);case Ht._debugger:return this.parseDebuggerStatement(a);case Ht._do:return this.parseDoStatement(a);case Ht._for:return this.parseForStatement(a);case Ht._function:return e&&(this.strict||"if"!==e&&"label"!==e)&&this.options.ecmaVersion>=6&&this.unexpected(),this.parseFunctionStatement(a,!1,!e);case Ht._class:return e&&this.unexpected(),this.parseClass(a,!0);case Ht._if:return this.parseIfStatement(a);case Ht._return:return this.parseReturnStatement(a);case Ht._switch:return this.parseSwitchStatement(a);case Ht._throw:return this.parseThrowStatement(a);case Ht._try:return this.parseTryStatement(a);case Ht._const:case Ht._var:return s=s||this.value,e&&"var"!==s&&this.unexpected(),this.parseVarStatement(a,s);case Ht._while:return this.parseWhileStatement(a);case Ht._with:return this.parseWithStatement(a);case Ht.braceL:return this.parseBlock(!0,a);case Ht.semi:return this.parseEmptyStatement(a);case Ht._export:case Ht._import:if(this.options.ecmaVersion>10&&r===Ht._import){Xt.lastIndex=this.pos;var i=Xt.exec(this.input),o=this.pos+i[0].length,l=this.input.charCodeAt(o);if(40===l||46===l)return this.parseExpressionStatement(a,this.parseExpression())}return this.options.allowImportExportEverywhere||(t||this.raise(this.start,"'import' and 'export' may only appear at the top level"),this.inModule||this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")),r===Ht._import?this.parseImport(a):this.parseExport(a,n);default:if(this.isAsyncFunction())return e&&this.unexpected(),this.next(),this.parseFunctionStatement(a,!0,!e);var c=this.isAwaitUsing(!1)?"await using":this.isUsing(!1)?"using":null;if(c)return t&&"script"===this.options.sourceType&&this.raise(this.start,"Using declaration cannot appear in the top level when source type is `script`"),"await using"===c&&(this.canAwait||this.raise(this.start,"Await using cannot appear outside of async function"),this.next()),this.next(),this.parseVar(a,!1,c),this.semicolon(),this.finishNode(a,"VariableDeclaration");var p=this.value,u=this.parseExpression();return r===Ht.name&&"Identifier"===u.type&&this.eat(Ht.colon)?this.parseLabeledStatement(a,p,u,e):this.parseExpressionStatement(a,u)}},_n.parseBreakContinueStatement=function(e,t){var n="break"===t;this.next(),this.eat(Ht.semi)||this.insertSemicolon()?e.label=null:this.type!==Ht.name?this.unexpected():(e.label=this.parseIdent(),this.semicolon());for(var s=0;s=6?this.eat(Ht.semi):this.semicolon(),this.finishNode(e,"DoWhileStatement")},_n.parseForStatement=function(e){this.next();var t=this.options.ecmaVersion>=9&&this.canAwait&&this.eatContextual("await")?this.lastTokStart:-1;if(this.labels.push(xn),this.enterScope(0),this.expect(Ht.parenL),this.type===Ht.semi)return t>-1&&this.unexpected(t),this.parseFor(e,null);var n=this.isLet();if(this.type===Ht._var||this.type===Ht._const||n){var s=this.startNode(),r=n?"let":this.value;return this.next(),this.parseVar(s,!0,r),this.finishNode(s,"VariableDeclaration"),this.parseForAfterInit(e,s,t)}var a=this.isContextual("let"),i=!1,o=this.isUsing(!0)?"using":this.isAwaitUsing(!0)?"await using":null;if(o){var l=this.startNode();return this.next(),"await using"===o&&this.next(),this.parseVar(l,!0,o),this.finishNode(l,"VariableDeclaration"),this.parseForAfterInit(e,l,t)}var c=this.containsEsc,p=new bn,u=this.start,d=t>-1?this.parseExprSubscripts(p,"await"):this.parseExpression(!0,p);return this.type===Ht._in||(i=this.options.ecmaVersion>=6&&this.isContextual("of"))?(t>-1?(this.type===Ht._in&&this.unexpected(t),e.await=!0):i&&this.options.ecmaVersion>=8&&(d.start!==u||c||"Identifier"!==d.type||"async"!==d.name?this.options.ecmaVersion>=9&&(e.await=!1):this.unexpected()),a&&i&&this.raise(d.start,"The left-hand side of a for-of loop may not start with 'let'."),this.toAssignable(d,!1,p),this.checkLValPattern(d),this.parseForIn(e,d)):(this.checkExpressionErrors(p,!0),t>-1&&this.unexpected(t),this.parseFor(e,d))},_n.parseForAfterInit=function(e,t,n){return(this.type===Ht._in||this.options.ecmaVersion>=6&&this.isContextual("of"))&&1===t.declarations.length?(this.options.ecmaVersion>=9&&(this.type===Ht._in?n>-1&&this.unexpected(n):e.await=n>-1),this.parseForIn(e,t)):(n>-1&&this.unexpected(n),this.parseFor(e,t))},_n.parseFunctionStatement=function(e,t,n){return this.next(),this.parseFunction(e,Cn|(n?0:Sn),!1,t)},_n.parseIfStatement=function(e){return this.next(),e.test=this.parseParenExpression(),e.consequent=this.parseStatement("if"),e.alternate=this.eat(Ht._else)?this.parseStatement("if"):null,this.finishNode(e,"IfStatement")},_n.parseReturnStatement=function(e){return this.inFunction||this.options.allowReturnOutsideFunction||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(Ht.semi)||this.insertSemicolon()?e.argument=null:(e.argument=this.parseExpression(),this.semicolon()),this.finishNode(e,"ReturnStatement")},_n.parseSwitchStatement=function(e){var t;this.next(),e.discriminant=this.parseParenExpression(),e.cases=[],this.expect(Ht.braceL),this.labels.push(wn),this.enterScope(0);for(var n=!1;this.type!==Ht.braceR;)if(this.type===Ht._case||this.type===Ht._default){var s=this.type===Ht._case;t&&this.finishNode(t,"SwitchCase"),e.cases.push(t=this.startNode()),t.consequent=[],this.next(),s?t.test=this.parseExpression():(n&&this.raiseRecoverable(this.lastTokStart,"Multiple default clauses"),n=!0,t.test=null),this.expect(Ht.colon)}else t||this.unexpected(),t.consequent.push(this.parseStatement(null));return this.exitScope(),t&&this.finishNode(t,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(e,"SwitchStatement")},_n.parseThrowStatement=function(e){return this.next(),Ut.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),e.argument=this.parseExpression(),this.semicolon(),this.finishNode(e,"ThrowStatement")};var kn=[];_n.parseCatchClauseParam=function(){var e=this.parseBindingAtom(),t="Identifier"===e.type;return this.enterScope(t?32:0),this.checkLValPattern(e,t?4:2),this.expect(Ht.parenR),e},_n.parseTryStatement=function(e){if(this.next(),e.block=this.parseBlock(),e.handler=null,this.type===Ht._catch){var t=this.startNode();this.next(),this.eat(Ht.parenL)?t.param=this.parseCatchClauseParam():(this.options.ecmaVersion<10&&this.unexpected(),t.param=null,this.enterScope(0)),t.body=this.parseBlock(!1),this.exitScope(),e.handler=this.finishNode(t,"CatchClause")}return e.finalizer=this.eat(Ht._finally)?this.parseBlock():null,e.handler||e.finalizer||this.raise(e.start,"Missing catch or finally clause"),this.finishNode(e,"TryStatement")},_n.parseVarStatement=function(e,t,n){return this.next(),this.parseVar(e,!1,t,n),this.semicolon(),this.finishNode(e,"VariableDeclaration")},_n.parseWhileStatement=function(e){return this.next(),e.test=this.parseParenExpression(),this.labels.push(xn),e.body=this.parseStatement("while"),this.labels.pop(),this.finishNode(e,"WhileStatement")},_n.parseWithStatement=function(e){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),e.object=this.parseParenExpression(),e.body=this.parseStatement("with"),this.finishNode(e,"WithStatement")},_n.parseEmptyStatement=function(e){return this.next(),this.finishNode(e,"EmptyStatement")},_n.parseLabeledStatement=function(e,t,n,s){for(var r=0,a=this.labels;r=0;o--){var l=this.labels[o];if(l.statementStart!==e.start)break;l.statementStart=this.start,l.kind=i}return this.labels.push({name:t,kind:i,statementStart:this.start}),e.body=this.parseStatement(s?-1===s.indexOf("label")?s+"label":s:"label"),this.labels.pop(),e.label=n,this.finishNode(e,"LabeledStatement")},_n.parseExpressionStatement=function(e,t){return e.expression=t,this.semicolon(),this.finishNode(e,"ExpressionStatement")},_n.parseBlock=function(e,t,n){for(void 0===e&&(e=!0),void 0===t&&(t=this.startNode()),t.body=[],this.expect(Ht.braceL),e&&this.enterScope(0);this.type!==Ht.braceR;){var s=this.parseStatement(null);t.body.push(s)}return n&&(this.strict=!1),this.next(),e&&this.exitScope(),this.finishNode(t,"BlockStatement")},_n.parseFor=function(e,t){return e.init=t,this.expect(Ht.semi),e.test=this.type===Ht.semi?null:this.parseExpression(),this.expect(Ht.semi),e.update=this.type===Ht.parenR?null:this.parseExpression(),this.expect(Ht.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,"ForStatement")},_n.parseForIn=function(e,t){var n=this.type===Ht._in;return this.next(),"VariableDeclaration"===t.type&&null!=t.declarations[0].init&&(!n||this.options.ecmaVersion<8||this.strict||"var"!==t.kind||"Identifier"!==t.declarations[0].id.type)&&this.raise(t.start,(n?"for-in":"for-of")+" loop variable declaration may not have an initializer"),e.left=t,e.right=n?this.parseExpression():this.parseMaybeAssign(),this.expect(Ht.parenR),e.body=this.parseStatement("for"),this.exitScope(),this.labels.pop(),this.finishNode(e,n?"ForInStatement":"ForOfStatement")},_n.parseVar=function(e,t,n,s){for(e.declarations=[],e.kind=n;;){var r=this.startNode();if(this.parseVarId(r,n),this.eat(Ht.eq)?r.init=this.parseMaybeAssign(t):s||"const"!==n||this.type===Ht._in||this.options.ecmaVersion>=6&&this.isContextual("of")?s||"using"!==n&&"await using"!==n||!(this.options.ecmaVersion>=17)||this.type===Ht._in||this.isContextual("of")?s||"Identifier"===r.id.type||t&&(this.type===Ht._in||this.isContextual("of"))?r.init=null:this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):this.raise(this.lastTokEnd,"Missing initializer in "+n+" declaration"):this.unexpected(),e.declarations.push(this.finishNode(r,"VariableDeclarator")),!this.eat(Ht.comma))break}return e},_n.parseVarId=function(e,t){e.id="using"===t||"await using"===t?this.parseIdent():this.parseBindingAtom(),this.checkLValPattern(e.id,"var"===t?1:2,!1)};var Cn=1,Sn=2;function Pn(e,t){var n=t.key.name,s=e[n],r="true";return"MethodDefinition"!==t.type||"get"!==t.kind&&"set"!==t.kind||(r=(t.static?"s":"i")+t.kind),"iget"===s&&"iset"===r||"iset"===s&&"iget"===r||"sget"===s&&"sset"===r||"sset"===s&&"sget"===r?(e[n]="true",!1):!!s||(e[n]=r,!1)}function En(e,t){var n=e.computed,s=e.key;return!n&&("Identifier"===s.type&&s.name===t||"Literal"===s.type&&s.value===t)}_n.parseFunction=function(e,t,n,s,r){this.initFunction(e),(this.options.ecmaVersion>=9||this.options.ecmaVersion>=6&&!s)&&(this.type===Ht.star&&t&Sn&&this.unexpected(),e.generator=this.eat(Ht.star)),this.options.ecmaVersion>=8&&(e.async=!!s),t&Cn&&(e.id=4&t&&this.type!==Ht.name?null:this.parseIdent(),!e.id||t&Sn||this.checkLValSimple(e.id,this.strict||e.generator||e.async?this.treatFunctionsAsVar?1:2:3));var a=this.yieldPos,i=this.awaitPos,o=this.awaitIdentPos;return this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(mn(e.async,e.generator)),t&Cn||(e.id=this.type===Ht.name?this.parseIdent():null),this.parseFunctionParams(e),this.parseFunctionBody(e,n,!1,r),this.yieldPos=a,this.awaitPos=i,this.awaitIdentPos=o,this.finishNode(e,t&Cn?"FunctionDeclaration":"FunctionExpression")},_n.parseFunctionParams=function(e){this.expect(Ht.parenL),e.params=this.parseBindingList(Ht.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams()},_n.parseClass=function(e,t){this.next();var n=this.strict;this.strict=!0,this.parseClassId(e,t),this.parseClassSuper(e);var s=this.enterClassBody(),r=this.startNode(),a=!1;for(r.body=[],this.expect(Ht.braceL);this.type!==Ht.braceR;){var i=this.parseClassElement(null!==e.superClass);i&&(r.body.push(i),"MethodDefinition"===i.type&&"constructor"===i.kind?(a&&this.raiseRecoverable(i.start,"Duplicate constructor in the same class"),a=!0):i.key&&"PrivateIdentifier"===i.key.type&&Pn(s,i)&&this.raiseRecoverable(i.key.start,"Identifier '#"+i.key.name+"' has already been declared"))}return this.strict=n,this.next(),e.body=this.finishNode(r,"ClassBody"),this.exitClassBody(),this.finishNode(e,t?"ClassDeclaration":"ClassExpression")},_n.parseClassElement=function(e){if(this.eat(Ht.semi))return null;var t=this.options.ecmaVersion,n=this.startNode(),s="",r=!1,a=!1,i="method",o=!1;if(this.eatContextual("static")){if(t>=13&&this.eat(Ht.braceL))return this.parseClassStaticBlock(n),n;this.isClassElementNameStart()||this.type===Ht.star?o=!0:s="static"}if(n.static=o,!s&&t>=8&&this.eatContextual("async")&&(!this.isClassElementNameStart()&&this.type!==Ht.star||this.canInsertSemicolon()?s="async":a=!0),!s&&(t>=9||!a)&&this.eat(Ht.star)&&(r=!0),!s&&!a&&!r){var l=this.value;(this.eatContextual("get")||this.eatContextual("set"))&&(this.isClassElementNameStart()?i=l:s=l)}if(s?(n.computed=!1,n.key=this.startNodeAt(this.lastTokStart,this.lastTokStartLoc),n.key.name=s,this.finishNode(n.key,"Identifier")):this.parseClassElementName(n),t<13||this.type===Ht.parenL||"method"!==i||r||a){var c=!n.static&&En(n,"constructor"),p=c&&e;c&&"method"!==i&&this.raise(n.key.start,"Constructor can't have get/set modifier"),n.kind=c?"constructor":i,this.parseClassMethod(n,r,a,p)}else this.parseClassField(n);return n},_n.isClassElementNameStart=function(){return this.type===Ht.name||this.type===Ht.privateId||this.type===Ht.num||this.type===Ht.string||this.type===Ht.bracketL||this.type.keyword},_n.parseClassElementName=function(e){this.type===Ht.privateId?("constructor"===this.value&&this.raise(this.start,"Classes can't have an element named '#constructor'"),e.computed=!1,e.key=this.parsePrivateIdent()):this.parsePropertyName(e)},_n.parseClassMethod=function(e,t,n,s){var r=e.key;"constructor"===e.kind?(t&&this.raise(r.start,"Constructor can't be a generator"),n&&this.raise(r.start,"Constructor can't be an async method")):e.static&&En(e,"prototype")&&this.raise(r.start,"Classes may not have a static property named prototype");var a=e.value=this.parseMethod(t,n,s);return"get"===e.kind&&0!==a.params.length&&this.raiseRecoverable(a.start,"getter should have no params"),"set"===e.kind&&1!==a.params.length&&this.raiseRecoverable(a.start,"setter should have exactly one param"),"set"===e.kind&&"RestElement"===a.params[0].type&&this.raiseRecoverable(a.params[0].start,"Setter cannot use rest params"),this.finishNode(e,"MethodDefinition")},_n.parseClassField=function(e){return En(e,"constructor")?this.raise(e.key.start,"Classes can't have a field named 'constructor'"):e.static&&En(e,"prototype")&&this.raise(e.key.start,"Classes can't have a static field named 'prototype'"),this.eat(Ht.eq)?(this.enterScope(576),e.value=this.parseMaybeAssign(),this.exitScope()):e.value=null,this.semicolon(),this.finishNode(e,"PropertyDefinition")},_n.parseClassStaticBlock=function(e){e.body=[];var t=this.labels;for(this.labels=[],this.enterScope(320);this.type!==Ht.braceR;){var n=this.parseStatement(null);e.body.push(n)}return this.next(),this.exitScope(),this.labels=t,this.finishNode(e,"StaticBlock")},_n.parseClassId=function(e,t){this.type===Ht.name?(e.id=this.parseIdent(),t&&this.checkLValSimple(e.id,2,!1)):(!0===t&&this.unexpected(),e.id=null)},_n.parseClassSuper=function(e){e.superClass=this.eat(Ht._extends)?this.parseExprSubscripts(null,!1):null},_n.enterClassBody=function(){var e={declared:Object.create(null),used:[]};return this.privateNameStack.push(e),e.declared},_n.exitClassBody=function(){var e=this.privateNameStack.pop(),t=e.declared,n=e.used;if(this.options.checkPrivateFields)for(var s=this.privateNameStack.length,r=0===s?null:this.privateNameStack[s-1],a=0;a=11&&(this.eatContextual("as")?(e.exported=this.parseModuleExportName(),this.checkExport(t,e.exported,this.lastTokStart)):e.exported=null),this.expectContextual("from"),this.type!==Ht.string&&this.unexpected(),e.source=this.parseExprAtom(),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause()),this.semicolon(),this.finishNode(e,"ExportAllDeclaration")},_n.parseExport=function(e,t){if(this.next(),this.eat(Ht.star))return this.parseExportAllDeclaration(e,t);if(this.eat(Ht._default))return this.checkExport(t,"default",this.lastTokStart),e.declaration=this.parseExportDefaultDeclaration(),this.finishNode(e,"ExportDefaultDeclaration");if(this.shouldParseExportStatement())e.declaration=this.parseExportDeclaration(e),"VariableDeclaration"===e.declaration.type?this.checkVariableExport(t,e.declaration.declarations):this.checkExport(t,e.declaration.id,e.declaration.id.start),e.specifiers=[],e.source=null,this.options.ecmaVersion>=16&&(e.attributes=[]);else{if(e.declaration=null,e.specifiers=this.parseExportSpecifiers(t),this.eatContextual("from"))this.type!==Ht.string&&this.unexpected(),e.source=this.parseExprAtom(),this.options.ecmaVersion>=16&&(e.attributes=this.parseWithClause());else{for(var n=0,s=e.specifiers;n=16&&(e.attributes=[])}this.semicolon()}return this.finishNode(e,"ExportNamedDeclaration")},_n.parseExportDeclaration=function(e){return this.parseStatement(null)},_n.parseExportDefaultDeclaration=function(){var e;if(this.type===Ht._function||(e=this.isAsyncFunction())){var t=this.startNode();return this.next(),e&&this.next(),this.parseFunction(t,4|Cn,!1,e)}if(this.type===Ht._class){var n=this.startNode();return this.parseClass(n,"nullableID")}var s=this.parseMaybeAssign();return this.semicolon(),s},_n.checkExport=function(e,t,n){e&&("string"!=typeof t&&(t="Identifier"===t.type?t.name:t.value),Zt(e,t)&&this.raiseRecoverable(n,"Duplicate export '"+t+"'"),e[t]=!0)},_n.checkPatternExport=function(e,t){var n=t.type;if("Identifier"===n)this.checkExport(e,t,t.start);else if("ObjectPattern"===n)for(var s=0,r=t.properties;s=16&&(e.attributes=this.parseWithClause()),this.semicolon(),this.finishNode(e,"ImportDeclaration")},_n.parseImportSpecifier=function(){var e=this.startNode();return e.imported=this.parseModuleExportName(),this.eatContextual("as")?e.local=this.parseIdent():(this.checkUnreserved(e.imported),e.local=e.imported),this.checkLValSimple(e.local,2),this.finishNode(e,"ImportSpecifier")},_n.parseImportDefaultSpecifier=function(){var e=this.startNode();return e.local=this.parseIdent(),this.checkLValSimple(e.local,2),this.finishNode(e,"ImportDefaultSpecifier")},_n.parseImportNamespaceSpecifier=function(){var e=this.startNode();return this.next(),this.expectContextual("as"),e.local=this.parseIdent(),this.checkLValSimple(e.local,2),this.finishNode(e,"ImportNamespaceSpecifier")},_n.parseImportSpecifiers=function(){var e=[],t=!0;if(this.type===Ht.name&&(e.push(this.parseImportDefaultSpecifier()),!this.eat(Ht.comma)))return e;if(this.type===Ht.star)return e.push(this.parseImportNamespaceSpecifier()),e;for(this.expect(Ht.braceL);!this.eat(Ht.braceR);){if(t)t=!1;else if(this.expect(Ht.comma),this.afterTrailingComma(Ht.braceR))break;e.push(this.parseImportSpecifier())}return e},_n.parseWithClause=function(){var e=[];if(!this.eat(Ht._with))return e;this.expect(Ht.braceL);for(var t={},n=!0;!this.eat(Ht.braceR);){if(n)n=!1;else if(this.expect(Ht.comma),this.afterTrailingComma(Ht.braceR))break;var s=this.parseImportAttribute(),r="Identifier"===s.key.type?s.key.name:s.key.value;Zt(t,r)&&this.raiseRecoverable(s.key.start,"Duplicate attribute key '"+r+"'"),t[r]=!0,e.push(s)}return e},_n.parseImportAttribute=function(){var e=this.startNode();return e.key=this.type===Ht.string?this.parseExprAtom():this.parseIdent("never"!==this.options.allowReserved),this.expect(Ht.colon),this.type!==Ht.string&&this.unexpected(),e.value=this.parseExprAtom(),this.finishNode(e,"ImportAttribute")},_n.parseModuleExportName=function(){if(this.options.ecmaVersion>=13&&this.type===Ht.string){var e=this.parseLiteral(this.value);return rn.test(e.value)&&this.raise(e.start,"An export name cannot include a lone surrogate."),e}return this.parseIdent(!0)},_n.adaptDirectivePrologue=function(e){for(var t=0;t=5&&"ExpressionStatement"===e.type&&"Literal"===e.expression.type&&"string"==typeof e.expression.value&&('"'===this.input[e.start]||"'"===this.input[e.start])};var Tn=fn.prototype;Tn.toAssignable=function(e,t,n){if(this.options.ecmaVersion>=6&&e)switch(e.type){case"Identifier":this.inAsync&&"await"===e.name&&this.raise(e.start,"Cannot use 'await' as identifier inside an async function");break;case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":case"RestElement":break;case"ObjectExpression":e.type="ObjectPattern",n&&this.checkPatternErrors(n,!0);for(var s=0,r=e.properties;s=8&&!o&&"async"===l.name&&!this.canInsertSemicolon()&&this.eat(Ht._function))return this.overrideContext($n.f_expr),this.parseFunction(this.startNodeAt(a,i),0,!1,!0,t);if(r&&!this.canInsertSemicolon()){if(this.eat(Ht.arrow))return this.parseArrowExpression(this.startNodeAt(a,i),[l],!1,t);if(this.options.ecmaVersion>=8&&"async"===l.name&&this.type===Ht.name&&!o&&(!this.potentialArrowInForAwait||"of"!==this.value||this.containsEsc))return l=this.parseIdent(!1),!this.canInsertSemicolon()&&this.eat(Ht.arrow)||this.unexpected(),this.parseArrowExpression(this.startNodeAt(a,i),[l],!0,t)}return l;case Ht.regexp:var c=this.value;return(s=this.parseLiteral(c.value)).regex={pattern:c.pattern,flags:c.flags},s;case Ht.num:case Ht.string:return this.parseLiteral(this.value);case Ht._null:case Ht._true:case Ht._false:return(s=this.startNode()).value=this.type===Ht._null?null:this.type===Ht._true,s.raw=this.type.keyword,this.next(),this.finishNode(s,"Literal");case Ht.parenL:var p=this.start,u=this.parseParenAndDistinguishExpression(r,t);return e&&(e.parenthesizedAssign<0&&!this.isSimpleAssignTarget(u)&&(e.parenthesizedAssign=p),e.parenthesizedBind<0&&(e.parenthesizedBind=p)),u;case Ht.bracketL:return s=this.startNode(),this.next(),s.elements=this.parseExprList(Ht.bracketR,!0,!0,e),this.finishNode(s,"ArrayExpression");case Ht.braceL:return this.overrideContext($n.b_expr),this.parseObj(!1,e);case Ht._function:return s=this.startNode(),this.next(),this.parseFunction(s,0);case Ht._class:return this.parseClass(this.startNode(),!1);case Ht._new:return this.parseNew();case Ht.backQuote:return this.parseTemplate();case Ht._import:return this.options.ecmaVersion>=11?this.parseExprImport(n):this.unexpected();default:return this.parseExprAtomDefault()}},In.parseExprAtomDefault=function(){this.unexpected()},In.parseExprImport=function(e){var t=this.startNode();if(this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword import"),this.next(),this.type===Ht.parenL&&!e)return this.parseDynamicImport(t);if(this.type===Ht.dot){var n=this.startNodeAt(t.start,t.loc&&t.loc.start);return n.name="import",t.meta=this.finishNode(n,"Identifier"),this.parseImportMeta(t)}this.unexpected()},In.parseDynamicImport=function(e){if(this.next(),e.source=this.parseMaybeAssign(),this.options.ecmaVersion>=16)this.eat(Ht.parenR)?e.options=null:(this.expect(Ht.comma),this.afterTrailingComma(Ht.parenR)?e.options=null:(e.options=this.parseMaybeAssign(),this.eat(Ht.parenR)||(this.expect(Ht.comma),this.afterTrailingComma(Ht.parenR)||this.unexpected())));else if(!this.eat(Ht.parenR)){var t=this.start;this.eat(Ht.comma)&&this.eat(Ht.parenR)?this.raiseRecoverable(t,"Trailing comma is not allowed in import()"):this.unexpected(t)}return this.finishNode(e,"ImportExpression")},In.parseImportMeta=function(e){this.next();var t=this.containsEsc;return e.property=this.parseIdent(!0),"meta"!==e.property.name&&this.raiseRecoverable(e.property.start,"The only valid meta property for import is 'import.meta'"),t&&this.raiseRecoverable(e.start,"'import.meta' must not contain escaped characters"),"module"===this.options.sourceType||this.options.allowImportExportEverywhere||this.raiseRecoverable(e.start,"Cannot use 'import.meta' outside a module"),this.finishNode(e,"MetaProperty")},In.parseLiteral=function(e){var t=this.startNode();return t.value=e,t.raw=this.input.slice(this.start,this.end),110===t.raw.charCodeAt(t.raw.length-1)&&(t.bigint=null!=t.value?t.value.toString():t.raw.slice(0,-1).replace(/_/g,"")),this.next(),this.finishNode(t,"Literal")},In.parseParenExpression=function(){this.expect(Ht.parenL);var e=this.parseExpression();return this.expect(Ht.parenR),e},In.shouldParseArrow=function(e){return!this.canInsertSemicolon()},In.parseParenAndDistinguishExpression=function(e,t){var n,s=this.start,r=this.startLoc,a=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var i,o=this.start,l=this.startLoc,c=[],p=!0,u=!1,d=new bn,h=this.yieldPos,m=this.awaitPos;for(this.yieldPos=0,this.awaitPos=0;this.type!==Ht.parenR;){if(p?p=!1:this.expect(Ht.comma),a&&this.afterTrailingComma(Ht.parenR,!0)){u=!0;break}if(this.type===Ht.ellipsis){i=this.start,c.push(this.parseParenItem(this.parseRestBinding())),this.type===Ht.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element");break}c.push(this.parseMaybeAssign(!1,d,this.parseParenItem))}var f=this.lastTokEnd,y=this.lastTokEndLoc;if(this.expect(Ht.parenR),e&&this.shouldParseArrow(c)&&this.eat(Ht.arrow))return this.checkPatternErrors(d,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=h,this.awaitPos=m,this.parseParenArrowList(s,r,c,t);c.length&&!u||this.unexpected(this.lastTokStart),i&&this.unexpected(i),this.checkExpressionErrors(d,!0),this.yieldPos=h||this.yieldPos,this.awaitPos=m||this.awaitPos,c.length>1?((n=this.startNodeAt(o,l)).expressions=c,this.finishNodeAt(n,"SequenceExpression",f,y)):n=c[0]}else n=this.parseParenExpression();if(this.options.preserveParens){var v=this.startNodeAt(s,r);return v.expression=n,this.finishNode(v,"ParenthesizedExpression")}return n},In.parseParenItem=function(e){return e},In.parseParenArrowList=function(e,t,n,s){return this.parseArrowExpression(this.startNodeAt(e,t),n,!1,s)};var Ln=[];In.parseNew=function(){this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword new");var e=this.startNode();if(this.next(),this.options.ecmaVersion>=6&&this.type===Ht.dot){var t=this.startNodeAt(e.start,e.loc&&e.loc.start);t.name="new",e.meta=this.finishNode(t,"Identifier"),this.next();var n=this.containsEsc;return e.property=this.parseIdent(!0),"target"!==e.property.name&&this.raiseRecoverable(e.property.start,"The only valid meta property for new is 'new.target'"),n&&this.raiseRecoverable(e.start,"'new.target' must not contain escaped characters"),this.allowNewDotTarget||this.raiseRecoverable(e.start,"'new.target' can only be used in functions and class static block"),this.finishNode(e,"MetaProperty")}var s=this.start,r=this.startLoc;return e.callee=this.parseSubscripts(this.parseExprAtom(null,!1,!0),s,r,!0,!1),this.eat(Ht.parenL)?e.arguments=this.parseExprList(Ht.parenR,this.options.ecmaVersion>=8,!1):e.arguments=Ln,this.finishNode(e,"NewExpression")},In.parseTemplateElement=function(e){var t=e.isTagged,n=this.startNode();return this.type===Ht.invalidTemplate?(t||this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal"),n.value={raw:this.value.replace(/\r\n?/g,"\n"),cooked:null}):n.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,"\n"),cooked:this.value},this.next(),n.tail=this.type===Ht.backQuote,this.finishNode(n,"TemplateElement")},In.parseTemplate=function(e){void 0===e&&(e={});var t=e.isTagged;void 0===t&&(t=!1);var n=this.startNode();this.next(),n.expressions=[];var s=this.parseTemplateElement({isTagged:t});for(n.quasis=[s];!s.tail;)this.type===Ht.eof&&this.raise(this.pos,"Unterminated template literal"),this.expect(Ht.dollarBraceL),n.expressions.push(this.parseExpression()),this.expect(Ht.braceR),n.quasis.push(s=this.parseTemplateElement({isTagged:t}));return this.next(),this.finishNode(n,"TemplateLiteral")},In.isAsyncProp=function(e){return!e.computed&&"Identifier"===e.key.type&&"async"===e.key.name&&(this.type===Ht.name||this.type===Ht.num||this.type===Ht.string||this.type===Ht.bracketL||this.type.keyword||this.options.ecmaVersion>=9&&this.type===Ht.star)&&!Ut.test(this.input.slice(this.lastTokEnd,this.start))},In.parseObj=function(e,t){var n=this.startNode(),s=!0,r={};for(n.properties=[],this.next();!this.eat(Ht.braceR);){if(s)s=!1;else if(this.expect(Ht.comma),this.options.ecmaVersion>=5&&this.afterTrailingComma(Ht.braceR))break;var a=this.parseProperty(e,t);e||this.checkPropClash(a,r,t),n.properties.push(a)}return this.finishNode(n,e?"ObjectPattern":"ObjectExpression")},In.parseProperty=function(e,t){var n,s,r,a,i=this.startNode();if(this.options.ecmaVersion>=9&&this.eat(Ht.ellipsis))return e?(i.argument=this.parseIdent(!1),this.type===Ht.comma&&this.raiseRecoverable(this.start,"Comma is not permitted after the rest element"),this.finishNode(i,"RestElement")):(i.argument=this.parseMaybeAssign(!1,t),this.type===Ht.comma&&t&&t.trailingComma<0&&(t.trailingComma=this.start),this.finishNode(i,"SpreadElement"));this.options.ecmaVersion>=6&&(i.method=!1,i.shorthand=!1,(e||t)&&(r=this.start,a=this.startLoc),e||(n=this.eat(Ht.star)));var o=this.containsEsc;return this.parsePropertyName(i),!e&&!o&&this.options.ecmaVersion>=8&&!n&&this.isAsyncProp(i)?(s=!0,n=this.options.ecmaVersion>=9&&this.eat(Ht.star),this.parsePropertyName(i)):s=!1,this.parsePropertyValue(i,e,n,s,r,a,t,o),this.finishNode(i,"Property")},In.parseGetterSetter=function(e){var t=e.key.name;this.parsePropertyName(e),e.value=this.parseMethod(!1),e.kind=t;var n="get"===e.kind?0:1;if(e.value.params.length!==n){var s=e.value.start;"get"===e.kind?this.raiseRecoverable(s,"getter should have no params"):this.raiseRecoverable(s,"setter should have exactly one param")}else"set"===e.kind&&"RestElement"===e.value.params[0].type&&this.raiseRecoverable(e.value.params[0].start,"Setter cannot use rest params")},In.parsePropertyValue=function(e,t,n,s,r,a,i,o){(n||s)&&this.type===Ht.colon&&this.unexpected(),this.eat(Ht.colon)?(e.value=t?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,i),e.kind="init"):this.options.ecmaVersion>=6&&this.type===Ht.parenL?(t&&this.unexpected(),e.method=!0,e.value=this.parseMethod(n,s),e.kind="init"):t||o||!(this.options.ecmaVersion>=5)||e.computed||"Identifier"!==e.key.type||"get"!==e.key.name&&"set"!==e.key.name||this.type===Ht.comma||this.type===Ht.braceR||this.type===Ht.eq?this.options.ecmaVersion>=6&&!e.computed&&"Identifier"===e.key.type?((n||s)&&this.unexpected(),this.checkUnreserved(e.key),"await"!==e.key.name||this.awaitIdentPos||(this.awaitIdentPos=r),t?e.value=this.parseMaybeDefault(r,a,this.copyNode(e.key)):this.type===Ht.eq&&i?(i.shorthandAssign<0&&(i.shorthandAssign=this.start),e.value=this.parseMaybeDefault(r,a,this.copyNode(e.key))):e.value=this.copyNode(e.key),e.kind="init",e.shorthand=!0):this.unexpected():((n||s)&&this.unexpected(),this.parseGetterSetter(e))},In.parsePropertyName=function(e){if(this.options.ecmaVersion>=6){if(this.eat(Ht.bracketL))return e.computed=!0,e.key=this.parseMaybeAssign(),this.expect(Ht.bracketR),e.key;e.computed=!1}return e.key=this.type===Ht.num||this.type===Ht.string?this.parseExprAtom():this.parseIdent("never"!==this.options.allowReserved)},In.initFunction=function(e){e.id=null,this.options.ecmaVersion>=6&&(e.generator=e.expression=!1),this.options.ecmaVersion>=8&&(e.async=!1)},In.parseMethod=function(e,t,n){var s=this.startNode(),r=this.yieldPos,a=this.awaitPos,i=this.awaitIdentPos;return this.initFunction(s),this.options.ecmaVersion>=6&&(s.generator=e),this.options.ecmaVersion>=8&&(s.async=!!t),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(64|mn(t,s.generator)|(n?128:0)),this.expect(Ht.parenL),s.params=this.parseBindingList(Ht.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(s,!1,!0,!1),this.yieldPos=r,this.awaitPos=a,this.awaitIdentPos=i,this.finishNode(s,"FunctionExpression")},In.parseArrowExpression=function(e,t,n,s){var r=this.yieldPos,a=this.awaitPos,i=this.awaitIdentPos;return this.enterScope(16|mn(n,!1)),this.initFunction(e),this.options.ecmaVersion>=8&&(e.async=!!n),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,e.params=this.toAssignableList(t,!0),this.parseFunctionBody(e,!0,!1,s),this.yieldPos=r,this.awaitPos=a,this.awaitIdentPos=i,this.finishNode(e,"ArrowFunctionExpression")},In.parseFunctionBody=function(e,t,n,s){var r=t&&this.type!==Ht.braceL,a=this.strict,i=!1;if(r)e.body=this.parseMaybeAssign(s),e.expression=!0,this.checkParams(e,!1);else{var o=this.options.ecmaVersion>=7&&!this.isSimpleParamList(e.params);a&&!o||(i=this.strictDirective(this.end))&&o&&this.raiseRecoverable(e.start,"Illegal 'use strict' directive in function with non-simple parameter list");var l=this.labels;this.labels=[],i&&(this.strict=!0),this.checkParams(e,!a&&!i&&!t&&!n&&this.isSimpleParamList(e.params)),this.strict&&e.id&&this.checkLValSimple(e.id,5),e.body=this.parseBlock(!1,void 0,i&&!a),e.expression=!1,this.adaptDirectivePrologue(e.body.body),this.labels=l}this.exitScope()},In.isSimpleParamList=function(e){for(var t=0,n=e;t-1||r.functions.indexOf(e)>-1||r.var.indexOf(e)>-1,r.lexical.push(e),this.inModule&&1&r.flags&&delete this.undefinedExports[e]}else if(4===t){this.currentScope().lexical.push(e)}else if(3===t){var a=this.currentScope();s=this.treatFunctionsAsVar?a.lexical.indexOf(e)>-1:a.lexical.indexOf(e)>-1||a.var.indexOf(e)>-1,a.functions.push(e)}else for(var i=this.scopeStack.length-1;i>=0;--i){var o=this.scopeStack[i];if(o.lexical.indexOf(e)>-1&&!(32&o.flags&&o.lexical[0]===e)||!this.treatFunctionsAsVarInScope(o)&&o.functions.indexOf(e)>-1){s=!0;break}if(o.var.push(e),this.inModule&&1&o.flags&&delete this.undefinedExports[e],o.flags&hn)break}s&&this.raiseRecoverable(n,"Identifier '"+e+"' has already been declared")},Nn.checkLocalExport=function(e){-1===this.scopeStack[0].lexical.indexOf(e.name)&&-1===this.scopeStack[0].var.indexOf(e.name)&&(this.undefinedExports[e.name]=e)},Nn.currentScope=function(){return this.scopeStack[this.scopeStack.length-1]},Nn.currentVarScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(771&t.flags)return t}},Nn.currentThisScope=function(){for(var e=this.scopeStack.length-1;;e--){var t=this.scopeStack[e];if(771&t.flags&&!(16&t.flags))return t}};var jn=function(e,t,n){this.type="",this.start=t,this.end=0,e.options.locations&&(this.loc=new on(e,n)),e.options.directSourceFile&&(this.sourceFile=e.options.directSourceFile),e.options.ranges&&(this.range=[t,0])},Bn=fn.prototype;function Fn(e,t,n,s){return e.type=t,e.end=n,this.options.locations&&(e.loc.end=s),this.options.ranges&&(e.range[1]=n),e}Bn.startNode=function(){return new jn(this,this.start,this.startLoc)},Bn.startNodeAt=function(e,t){return new jn(this,e,t)},Bn.finishNode=function(e,t){return Fn.call(this,e,t,this.lastTokEnd,this.lastTokEndLoc)},Bn.finishNodeAt=function(e,t,n,s){return Fn.call(this,e,t,n,s)},Bn.copyNode=function(e){var t=new jn(this,e.start,this.startLoc);for(var n in e)t[n]=e[n];return t};var Vn="ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS",Hn=Vn+" Extended_Pictographic",Un=Hn+" EBase EComp EMod EPres ExtPict",zn={9:Vn,10:Hn,11:Hn,12:Un,13:Un,14:Un},Wn={9:"",10:"",11:"",12:"",13:"",14:"Basic_Emoji Emoji_Keycap_Sequence RGI_Emoji_Modifier_Sequence RGI_Emoji_Flag_Sequence RGI_Emoji_Tag_Sequence RGI_Emoji_ZWJ_Sequence RGI_Emoji"},Gn="Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu",Kn="Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb",Xn=Kn+" Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd",Qn=Xn+" Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho",Yn=Qn+" Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi",Jn=Yn+" Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith",Zn={9:Kn,10:Xn,11:Qn,12:Yn,13:Jn,14:Jn+" Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sunu Sunuwar Todhri Todr Tulu_Tigalari Tutg Unknown Zzzz"},es={};function ts(e){var t=es[e]={binary:nn(zn[e]+" "+Gn),binaryOfStrings:nn(Wn[e]),nonBinary:{General_Category:nn(Gn),Script:nn(Zn[e])}};t.nonBinary.Script_Extensions=t.nonBinary.Script,t.nonBinary.gc=t.nonBinary.General_Category,t.nonBinary.sc=t.nonBinary.Script,t.nonBinary.scx=t.nonBinary.Script_Extensions}for(var ns=0,ss=[9,10,11,12,13,14];ns=6?"uy":"")+(e.options.ecmaVersion>=9?"s":"")+(e.options.ecmaVersion>=13?"d":"")+(e.options.ecmaVersion>=15?"v":""),this.unicodeProperties=es[e.options.ecmaVersion>=14?14:e.options.ecmaVersion],this.source="",this.flags="",this.start=0,this.switchU=!1,this.switchV=!1,this.switchN=!1,this.pos=0,this.lastIntValue=0,this.lastStringValue="",this.lastAssertionIsQuantifiable=!1,this.numCapturingParens=0,this.maxBackReference=0,this.groupNames=Object.create(null),this.backReferenceNames=[],this.branchID=null};function os(e){return 105===e||109===e||115===e}function ls(e){return 36===e||e>=40&&e<=43||46===e||63===e||e>=91&&e<=94||e>=123&&e<=125}function cs(e){return e>=65&&e<=90||e>=97&&e<=122}is.prototype.reset=function(e,t,n){var s=-1!==n.indexOf("v"),r=-1!==n.indexOf("u");this.start=0|e,this.source=t+"",this.flags=n,s&&this.parser.options.ecmaVersion>=15?(this.switchU=!0,this.switchV=!0,this.switchN=!0):(this.switchU=r&&this.parser.options.ecmaVersion>=6,this.switchV=!1,this.switchN=r&&this.parser.options.ecmaVersion>=9)},is.prototype.raise=function(e){this.parser.raiseRecoverable(this.start,"Invalid regular expression: /"+this.source+"/: "+e)},is.prototype.at=function(e,t){void 0===t&&(t=!1);var n=this.source,s=n.length;if(e>=s)return-1;var r=n.charCodeAt(e);if(!t&&!this.switchU||r<=55295||r>=57344||e+1>=s)return r;var a=n.charCodeAt(e+1);return a>=56320&&a<=57343?(r<<10)+a-56613888:r},is.prototype.nextIndex=function(e,t){void 0===t&&(t=!1);var n=this.source,s=n.length;if(e>=s)return s;var r,a=n.charCodeAt(e);return!t&&!this.switchU||a<=55295||a>=57344||e+1>=s||(r=n.charCodeAt(e+1))<56320||r>57343?e+1:e+2},is.prototype.current=function(e){return void 0===e&&(e=!1),this.at(this.pos,e)},is.prototype.lookahead=function(e){return void 0===e&&(e=!1),this.at(this.nextIndex(this.pos,e),e)},is.prototype.advance=function(e){void 0===e&&(e=!1),this.pos=this.nextIndex(this.pos,e)},is.prototype.eat=function(e,t){return void 0===t&&(t=!1),this.current(t)===e&&(this.advance(t),!0)},is.prototype.eatChars=function(e,t){void 0===t&&(t=!1);for(var n=this.pos,s=0,r=e;s-1&&this.raise(e.start,"Duplicate regular expression flag"),"u"===i&&(s=!0),"v"===i&&(r=!0)}this.options.ecmaVersion>=15&&s&&r&&this.raise(e.start,"Invalid regular expression flag")},rs.validateRegExpPattern=function(e){this.regexp_pattern(e),!e.switchN&&this.options.ecmaVersion>=9&&function(e){for(var t in e)return!0;return!1}(e.groupNames)&&(e.switchN=!0,this.regexp_pattern(e))},rs.regexp_pattern=function(e){e.pos=0,e.lastIntValue=0,e.lastStringValue="",e.lastAssertionIsQuantifiable=!1,e.numCapturingParens=0,e.maxBackReference=0,e.groupNames=Object.create(null),e.backReferenceNames.length=0,e.branchID=null,this.regexp_disjunction(e),e.pos!==e.source.length&&(e.eat(41)&&e.raise("Unmatched ')'"),(e.eat(93)||e.eat(125))&&e.raise("Lone quantifier brackets")),e.maxBackReference>e.numCapturingParens&&e.raise("Invalid escape");for(var t=0,n=e.backReferenceNames;t=16;for(t&&(e.branchID=new as(e.branchID,null)),this.regexp_alternative(e);e.eat(124);)t&&(e.branchID=e.branchID.sibling()),this.regexp_alternative(e);t&&(e.branchID=e.branchID.parent),this.regexp_eatQuantifier(e,!0)&&e.raise("Nothing to repeat"),e.eat(123)&&e.raise("Lone quantifier brackets")},rs.regexp_alternative=function(e){for(;e.pos=9&&(n=e.eat(60)),e.eat(61)||e.eat(33))return this.regexp_disjunction(e),e.eat(41)||e.raise("Unterminated group"),e.lastAssertionIsQuantifiable=!n,!0}return e.pos=t,!1},rs.regexp_eatQuantifier=function(e,t){return void 0===t&&(t=!1),!!this.regexp_eatQuantifierPrefix(e,t)&&(e.eat(63),!0)},rs.regexp_eatQuantifierPrefix=function(e,t){return e.eat(42)||e.eat(43)||e.eat(63)||this.regexp_eatBracedQuantifier(e,t)},rs.regexp_eatBracedQuantifier=function(e,t){var n=e.pos;if(e.eat(123)){var s=0,r=-1;if(this.regexp_eatDecimalDigits(e)&&(s=e.lastIntValue,e.eat(44)&&this.regexp_eatDecimalDigits(e)&&(r=e.lastIntValue),e.eat(125)))return-1!==r&&r=16){var n=this.regexp_eatModifiers(e),s=e.eat(45);if(n||s){for(var r=0;r-1&&e.raise("Duplicate regular expression modifiers")}if(s){var i=this.regexp_eatModifiers(e);n||i||58!==e.current()||e.raise("Invalid regular expression modifiers");for(var o=0;o-1||n.indexOf(l)>-1)&&e.raise("Duplicate regular expression modifiers")}}}}if(e.eat(58)){if(this.regexp_disjunction(e),e.eat(41))return!0;e.raise("Unterminated group")}}e.pos=t}return!1},rs.regexp_eatCapturingGroup=function(e){if(e.eat(40)){if(this.options.ecmaVersion>=9?this.regexp_groupSpecifier(e):63===e.current()&&e.raise("Invalid group"),this.regexp_disjunction(e),e.eat(41))return e.numCapturingParens+=1,!0;e.raise("Unterminated group")}return!1},rs.regexp_eatModifiers=function(e){for(var t="",n=0;-1!==(n=e.current())&&os(n);)t+=sn(n),e.advance();return t},rs.regexp_eatExtendedAtom=function(e){return e.eat(46)||this.regexp_eatReverseSolidusAtomEscape(e)||this.regexp_eatCharacterClass(e)||this.regexp_eatUncapturingGroup(e)||this.regexp_eatCapturingGroup(e)||this.regexp_eatInvalidBracedQuantifier(e)||this.regexp_eatExtendedPatternCharacter(e)},rs.regexp_eatInvalidBracedQuantifier=function(e){return this.regexp_eatBracedQuantifier(e,!0)&&e.raise("Nothing to repeat"),!1},rs.regexp_eatSyntaxCharacter=function(e){var t=e.current();return!!ls(t)&&(e.lastIntValue=t,e.advance(),!0)},rs.regexp_eatPatternCharacters=function(e){for(var t=e.pos,n=0;-1!==(n=e.current())&&!ls(n);)e.advance();return e.pos!==t},rs.regexp_eatExtendedPatternCharacter=function(e){var t=e.current();return!(-1===t||36===t||t>=40&&t<=43||46===t||63===t||91===t||94===t||124===t)&&(e.advance(),!0)},rs.regexp_groupSpecifier=function(e){if(e.eat(63)){this.regexp_eatGroupName(e)||e.raise("Invalid group");var t=this.options.ecmaVersion>=16,n=e.groupNames[e.lastStringValue];if(n)if(t)for(var s=0,r=n;s=11,s=e.current(n);return e.advance(n),92===s&&this.regexp_eatRegExpUnicodeEscapeSequence(e,n)&&(s=e.lastIntValue),function(e){return Lt(e,!0)||36===e||95===e}(s)?(e.lastIntValue=s,!0):(e.pos=t,!1)},rs.regexp_eatRegExpIdentifierPart=function(e){var t=e.pos,n=this.options.ecmaVersion>=11,s=e.current(n);return e.advance(n),92===s&&this.regexp_eatRegExpUnicodeEscapeSequence(e,n)&&(s=e.lastIntValue),function(e){return Ot(e,!0)||36===e||95===e||8204===e||8205===e}(s)?(e.lastIntValue=s,!0):(e.pos=t,!1)},rs.regexp_eatAtomEscape=function(e){return!!(this.regexp_eatBackReference(e)||this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)||e.switchN&&this.regexp_eatKGroupName(e))||(e.switchU&&(99===e.current()&&e.raise("Invalid unicode escape"),e.raise("Invalid escape")),!1)},rs.regexp_eatBackReference=function(e){var t=e.pos;if(this.regexp_eatDecimalEscape(e)){var n=e.lastIntValue;if(e.switchU)return n>e.maxBackReference&&(e.maxBackReference=n),!0;if(n<=e.numCapturingParens)return!0;e.pos=t}return!1},rs.regexp_eatKGroupName=function(e){if(e.eat(107)){if(this.regexp_eatGroupName(e))return e.backReferenceNames.push(e.lastStringValue),!0;e.raise("Invalid named reference")}return!1},rs.regexp_eatCharacterEscape=function(e){return this.regexp_eatControlEscape(e)||this.regexp_eatCControlLetter(e)||this.regexp_eatZero(e)||this.regexp_eatHexEscapeSequence(e)||this.regexp_eatRegExpUnicodeEscapeSequence(e,!1)||!e.switchU&&this.regexp_eatLegacyOctalEscapeSequence(e)||this.regexp_eatIdentityEscape(e)},rs.regexp_eatCControlLetter=function(e){var t=e.pos;if(e.eat(99)){if(this.regexp_eatControlLetter(e))return!0;e.pos=t}return!1},rs.regexp_eatZero=function(e){return 48===e.current()&&!ds(e.lookahead())&&(e.lastIntValue=0,e.advance(),!0)},rs.regexp_eatControlEscape=function(e){var t=e.current();return 116===t?(e.lastIntValue=9,e.advance(),!0):110===t?(e.lastIntValue=10,e.advance(),!0):118===t?(e.lastIntValue=11,e.advance(),!0):102===t?(e.lastIntValue=12,e.advance(),!0):114===t&&(e.lastIntValue=13,e.advance(),!0)},rs.regexp_eatControlLetter=function(e){var t=e.current();return!!cs(t)&&(e.lastIntValue=t%32,e.advance(),!0)},rs.regexp_eatRegExpUnicodeEscapeSequence=function(e,t){void 0===t&&(t=!1);var n,s=e.pos,r=t||e.switchU;if(e.eat(117)){if(this.regexp_eatFixedHexDigits(e,4)){var a=e.lastIntValue;if(r&&a>=55296&&a<=56319){var i=e.pos;if(e.eat(92)&&e.eat(117)&&this.regexp_eatFixedHexDigits(e,4)){var o=e.lastIntValue;if(o>=56320&&o<=57343)return e.lastIntValue=1024*(a-55296)+(o-56320)+65536,!0}e.pos=i,e.lastIntValue=a}return!0}if(r&&e.eat(123)&&this.regexp_eatHexDigits(e)&&e.eat(125)&&((n=e.lastIntValue)>=0&&n<=1114111))return!0;r&&e.raise("Invalid unicode escape"),e.pos=s}return!1},rs.regexp_eatIdentityEscape=function(e){if(e.switchU)return!!this.regexp_eatSyntaxCharacter(e)||!!e.eat(47)&&(e.lastIntValue=47,!0);var t=e.current();return!(99===t||e.switchN&&107===t)&&(e.lastIntValue=t,e.advance(),!0)},rs.regexp_eatDecimalEscape=function(e){e.lastIntValue=0;var t=e.current();if(t>=49&&t<=57){do{e.lastIntValue=10*e.lastIntValue+(t-48),e.advance()}while((t=e.current())>=48&&t<=57);return!0}return!1};function ps(e){return cs(e)||95===e}function us(e){return ps(e)||ds(e)}function ds(e){return e>=48&&e<=57}function hs(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function ms(e){return e>=65&&e<=70?e-65+10:e>=97&&e<=102?e-97+10:e-48}function fs(e){return e>=48&&e<=55}rs.regexp_eatCharacterClassEscape=function(e){var t=e.current();if(function(e){return 100===e||68===e||115===e||83===e||119===e||87===e}(t))return e.lastIntValue=-1,e.advance(),1;var n=!1;if(e.switchU&&this.options.ecmaVersion>=9&&((n=80===t)||112===t)){var s;if(e.lastIntValue=-1,e.advance(),e.eat(123)&&(s=this.regexp_eatUnicodePropertyValueExpression(e))&&e.eat(125))return n&&2===s&&e.raise("Invalid property name"),s;e.raise("Invalid property name")}return 0},rs.regexp_eatUnicodePropertyValueExpression=function(e){var t=e.pos;if(this.regexp_eatUnicodePropertyName(e)&&e.eat(61)){var n=e.lastStringValue;if(this.regexp_eatUnicodePropertyValue(e)){var s=e.lastStringValue;return this.regexp_validateUnicodePropertyNameAndValue(e,n,s),1}}if(e.pos=t,this.regexp_eatLoneUnicodePropertyNameOrValue(e)){var r=e.lastStringValue;return this.regexp_validateUnicodePropertyNameOrValue(e,r)}return 0},rs.regexp_validateUnicodePropertyNameAndValue=function(e,t,n){Zt(e.unicodeProperties.nonBinary,t)||e.raise("Invalid property name"),e.unicodeProperties.nonBinary[t].test(n)||e.raise("Invalid property value")},rs.regexp_validateUnicodePropertyNameOrValue=function(e,t){return e.unicodeProperties.binary.test(t)?1:e.switchV&&e.unicodeProperties.binaryOfStrings.test(t)?2:void e.raise("Invalid property name")},rs.regexp_eatUnicodePropertyName=function(e){var t=0;for(e.lastStringValue="";ps(t=e.current());)e.lastStringValue+=sn(t),e.advance();return""!==e.lastStringValue},rs.regexp_eatUnicodePropertyValue=function(e){var t=0;for(e.lastStringValue="";us(t=e.current());)e.lastStringValue+=sn(t),e.advance();return""!==e.lastStringValue},rs.regexp_eatLoneUnicodePropertyNameOrValue=function(e){return this.regexp_eatUnicodePropertyValue(e)},rs.regexp_eatCharacterClass=function(e){if(e.eat(91)){var t=e.eat(94),n=this.regexp_classContents(e);return e.eat(93)||e.raise("Unterminated character class"),t&&2===n&&e.raise("Negated character class may contain strings"),!0}return!1},rs.regexp_classContents=function(e){return 93===e.current()?1:e.switchV?this.regexp_classSetExpression(e):(this.regexp_nonEmptyClassRanges(e),1)},rs.regexp_nonEmptyClassRanges=function(e){for(;this.regexp_eatClassAtom(e);){var t=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassAtom(e)){var n=e.lastIntValue;!e.switchU||-1!==t&&-1!==n||e.raise("Invalid character class"),-1!==t&&-1!==n&&t>n&&e.raise("Range out of order in character class")}}},rs.regexp_eatClassAtom=function(e){var t=e.pos;if(e.eat(92)){if(this.regexp_eatClassEscape(e))return!0;if(e.switchU){var n=e.current();(99===n||fs(n))&&e.raise("Invalid class escape"),e.raise("Invalid escape")}e.pos=t}var s=e.current();return 93!==s&&(e.lastIntValue=s,e.advance(),!0)},rs.regexp_eatClassEscape=function(e){var t=e.pos;if(e.eat(98))return e.lastIntValue=8,!0;if(e.switchU&&e.eat(45))return e.lastIntValue=45,!0;if(!e.switchU&&e.eat(99)){if(this.regexp_eatClassControlLetter(e))return!0;e.pos=t}return this.regexp_eatCharacterClassEscape(e)||this.regexp_eatCharacterEscape(e)},rs.regexp_classSetExpression=function(e){var t,n=1;if(this.regexp_eatClassSetRange(e));else if(t=this.regexp_eatClassSetOperand(e)){2===t&&(n=2);for(var s=e.pos;e.eatChars([38,38]);)38!==e.current()&&(t=this.regexp_eatClassSetOperand(e))?2!==t&&(n=1):e.raise("Invalid character in character class");if(s!==e.pos)return n;for(;e.eatChars([45,45]);)this.regexp_eatClassSetOperand(e)||e.raise("Invalid character in character class");if(s!==e.pos)return n}else e.raise("Invalid character in character class");for(;;)if(!this.regexp_eatClassSetRange(e)){if(!(t=this.regexp_eatClassSetOperand(e)))return n;2===t&&(n=2)}},rs.regexp_eatClassSetRange=function(e){var t=e.pos;if(this.regexp_eatClassSetCharacter(e)){var n=e.lastIntValue;if(e.eat(45)&&this.regexp_eatClassSetCharacter(e)){var s=e.lastIntValue;return-1!==n&&-1!==s&&n>s&&e.raise("Range out of order in character class"),!0}e.pos=t}return!1},rs.regexp_eatClassSetOperand=function(e){return this.regexp_eatClassSetCharacter(e)?1:this.regexp_eatClassStringDisjunction(e)||this.regexp_eatNestedClass(e)},rs.regexp_eatNestedClass=function(e){var t=e.pos;if(e.eat(91)){var n=e.eat(94),s=this.regexp_classContents(e);if(e.eat(93))return n&&2===s&&e.raise("Negated character class may contain strings"),s;e.pos=t}if(e.eat(92)){var r=this.regexp_eatCharacterClassEscape(e);if(r)return r;e.pos=t}return null},rs.regexp_eatClassStringDisjunction=function(e){var t=e.pos;if(e.eatChars([92,113])){if(e.eat(123)){var n=this.regexp_classStringDisjunctionContents(e);if(e.eat(125))return n}else e.raise("Invalid escape");e.pos=t}return null},rs.regexp_classStringDisjunctionContents=function(e){for(var t=this.regexp_classString(e);e.eat(124);)2===this.regexp_classString(e)&&(t=2);return t},rs.regexp_classString=function(e){for(var t=0;this.regexp_eatClassSetCharacter(e);)t++;return 1===t?1:2},rs.regexp_eatClassSetCharacter=function(e){var t=e.pos;if(e.eat(92))return!(!this.regexp_eatCharacterEscape(e)&&!this.regexp_eatClassSetReservedPunctuator(e))||(e.eat(98)?(e.lastIntValue=8,!0):(e.pos=t,!1));var n=e.current();return!(n<0||n===e.lookahead()&&function(e){return 33===e||e>=35&&e<=38||e>=42&&e<=44||46===e||e>=58&&e<=64||94===e||96===e||126===e}(n))&&(!function(e){return 40===e||41===e||45===e||47===e||e>=91&&e<=93||e>=123&&e<=125}(n)&&(e.advance(),e.lastIntValue=n,!0))},rs.regexp_eatClassSetReservedPunctuator=function(e){var t=e.current();return!!function(e){return 33===e||35===e||37===e||38===e||44===e||45===e||e>=58&&e<=62||64===e||96===e||126===e}(t)&&(e.lastIntValue=t,e.advance(),!0)},rs.regexp_eatClassControlLetter=function(e){var t=e.current();return!(!ds(t)&&95!==t)&&(e.lastIntValue=t%32,e.advance(),!0)},rs.regexp_eatHexEscapeSequence=function(e){var t=e.pos;if(e.eat(120)){if(this.regexp_eatFixedHexDigits(e,2))return!0;e.switchU&&e.raise("Invalid escape"),e.pos=t}return!1},rs.regexp_eatDecimalDigits=function(e){var t=e.pos,n=0;for(e.lastIntValue=0;ds(n=e.current());)e.lastIntValue=10*e.lastIntValue+(n-48),e.advance();return e.pos!==t},rs.regexp_eatHexDigits=function(e){var t=e.pos,n=0;for(e.lastIntValue=0;hs(n=e.current());)e.lastIntValue=16*e.lastIntValue+ms(n),e.advance();return e.pos!==t},rs.regexp_eatLegacyOctalEscapeSequence=function(e){if(this.regexp_eatOctalDigit(e)){var t=e.lastIntValue;if(this.regexp_eatOctalDigit(e)){var n=e.lastIntValue;t<=3&&this.regexp_eatOctalDigit(e)?e.lastIntValue=64*t+8*n+e.lastIntValue:e.lastIntValue=8*t+n}else e.lastIntValue=t;return!0}return!1},rs.regexp_eatOctalDigit=function(e){var t=e.current();return fs(t)?(e.lastIntValue=t-48,e.advance(),!0):(e.lastIntValue=0,!1)},rs.regexp_eatFixedHexDigits=function(e,t){var n=e.pos;e.lastIntValue=0;for(var s=0;s=this.input.length?this.finishToken(Ht.eof):e.override?e.override(this):void this.readToken(this.fullCharCodeAtPos())},vs.readToken=function(e){return Lt(e,this.options.ecmaVersion>=6)||92===e?this.readWord():this.getTokenFromCode(e)},vs.fullCharCodeAtPos=function(){var e=this.input.charCodeAt(this.pos);if(e<=55295||e>=56320)return e;var t=this.input.charCodeAt(this.pos+1);return t<=56319||t>=57344?e:(e<<10)+t-56613888},vs.skipBlockComment=function(){var e=this.options.onComment&&this.curPosition(),t=this.pos,n=this.input.indexOf("*/",this.pos+=2);if(-1===n&&this.raise(this.pos-2,"Unterminated comment"),this.pos=n+2,this.options.locations)for(var s=void 0,r=t;(s=Gt(this.input,r,this.pos))>-1;)++this.curLine,r=this.lineStart=s;this.options.onComment&&this.options.onComment(!0,this.input.slice(t+2,n),t,this.pos,e,this.curPosition())},vs.skipLineComment=function(e){for(var t=this.pos,n=this.options.onComment&&this.curPosition(),s=this.input.charCodeAt(this.pos+=e);this.pos8&&e<14||e>=5760&&Kt.test(String.fromCharCode(e))))break e;++this.pos}}},vs.finishToken=function(e,t){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var n=this.type;this.type=e,this.value=t,this.updateContext(n)},vs.readToken_dot=function(){var e=this.input.charCodeAt(this.pos+1);if(e>=48&&e<=57)return this.readNumber(!0);var t=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&46===e&&46===t?(this.pos+=3,this.finishToken(Ht.ellipsis)):(++this.pos,this.finishToken(Ht.dot))},vs.readToken_slash=function(){var e=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):61===e?this.finishOp(Ht.assign,2):this.finishOp(Ht.slash,1)},vs.readToken_mult_modulo_exp=function(e){var t=this.input.charCodeAt(this.pos+1),n=1,s=42===e?Ht.star:Ht.modulo;return this.options.ecmaVersion>=7&&42===e&&42===t&&(++n,s=Ht.starstar,t=this.input.charCodeAt(this.pos+2)),61===t?this.finishOp(Ht.assign,n+1):this.finishOp(s,n)},vs.readToken_pipe_amp=function(e){var t=this.input.charCodeAt(this.pos+1);if(t===e){if(this.options.ecmaVersion>=12)if(61===this.input.charCodeAt(this.pos+2))return this.finishOp(Ht.assign,3);return this.finishOp(124===e?Ht.logicalOR:Ht.logicalAND,2)}return 61===t?this.finishOp(Ht.assign,2):this.finishOp(124===e?Ht.bitwiseOR:Ht.bitwiseAND,1)},vs.readToken_caret=function(){return 61===this.input.charCodeAt(this.pos+1)?this.finishOp(Ht.assign,2):this.finishOp(Ht.bitwiseXOR,1)},vs.readToken_plus_min=function(e){var t=this.input.charCodeAt(this.pos+1);return t===e?45!==t||this.inModule||62!==this.input.charCodeAt(this.pos+2)||0!==this.lastTokEnd&&!Ut.test(this.input.slice(this.lastTokEnd,this.pos))?this.finishOp(Ht.incDec,2):(this.skipLineComment(3),this.skipSpace(),this.nextToken()):61===t?this.finishOp(Ht.assign,2):this.finishOp(Ht.plusMin,1)},vs.readToken_lt_gt=function(e){var t=this.input.charCodeAt(this.pos+1),n=1;return t===e?(n=62===e&&62===this.input.charCodeAt(this.pos+2)?3:2,61===this.input.charCodeAt(this.pos+n)?this.finishOp(Ht.assign,n+1):this.finishOp(Ht.bitShift,n)):33!==t||60!==e||this.inModule||45!==this.input.charCodeAt(this.pos+2)||45!==this.input.charCodeAt(this.pos+3)?(61===t&&(n=2),this.finishOp(Ht.relational,n)):(this.skipLineComment(4),this.skipSpace(),this.nextToken())},vs.readToken_eq_excl=function(e){var t=this.input.charCodeAt(this.pos+1);return 61===t?this.finishOp(Ht.equality,61===this.input.charCodeAt(this.pos+2)?3:2):61===e&&62===t&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(Ht.arrow)):this.finishOp(61===e?Ht.eq:Ht.prefix,1)},vs.readToken_question=function(){var e=this.options.ecmaVersion;if(e>=11){var t=this.input.charCodeAt(this.pos+1);if(46===t){var n=this.input.charCodeAt(this.pos+2);if(n<48||n>57)return this.finishOp(Ht.questionDot,2)}if(63===t){if(e>=12)if(61===this.input.charCodeAt(this.pos+2))return this.finishOp(Ht.assign,3);return this.finishOp(Ht.coalesce,2)}}return this.finishOp(Ht.question,1)},vs.readToken_numberSign=function(){var e=35;if(this.options.ecmaVersion>=13&&(++this.pos,Lt(e=this.fullCharCodeAtPos(),!0)||92===e))return this.finishToken(Ht.privateId,this.readWord1());this.raise(this.pos,"Unexpected character '"+sn(e)+"'")},vs.getTokenFromCode=function(e){switch(e){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(Ht.parenL);case 41:return++this.pos,this.finishToken(Ht.parenR);case 59:return++this.pos,this.finishToken(Ht.semi);case 44:return++this.pos,this.finishToken(Ht.comma);case 91:return++this.pos,this.finishToken(Ht.bracketL);case 93:return++this.pos,this.finishToken(Ht.bracketR);case 123:return++this.pos,this.finishToken(Ht.braceL);case 125:return++this.pos,this.finishToken(Ht.braceR);case 58:return++this.pos,this.finishToken(Ht.colon);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(Ht.backQuote);case 48:var t=this.input.charCodeAt(this.pos+1);if(120===t||88===t)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(111===t||79===t)return this.readRadixNumber(8);if(98===t||66===t)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(e);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(e);case 124:case 38:return this.readToken_pipe_amp(e);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(e);case 60:case 62:return this.readToken_lt_gt(e);case 61:case 33:return this.readToken_eq_excl(e);case 63:return this.readToken_question();case 126:return this.finishOp(Ht.prefix,1);case 35:return this.readToken_numberSign()}this.raise(this.pos,"Unexpected character '"+sn(e)+"'")},vs.finishOp=function(e,t){var n=this.input.slice(this.pos,this.pos+t);return this.pos+=t,this.finishToken(e,n)},vs.readRegexp=function(){for(var e,t,n=this.pos;;){this.pos>=this.input.length&&this.raise(n,"Unterminated regular expression");var s=this.input.charAt(this.pos);if(Ut.test(s)&&this.raise(n,"Unterminated regular expression"),e)e=!1;else{if("["===s)t=!0;else if("]"===s&&t)t=!1;else if("/"===s&&!t)break;e="\\"===s}++this.pos}var r=this.input.slice(n,this.pos);++this.pos;var a=this.pos,i=this.readWord1();this.containsEsc&&this.unexpected(a);var o=this.regexpState||(this.regexpState=new is(this));o.reset(n,r,i),this.validateRegExpFlags(o),this.validateRegExpPattern(o);var l=null;try{l=new RegExp(r,i)}catch(e){}return this.finishToken(Ht.regexp,{pattern:r,flags:i,value:l})},vs.readInt=function(e,t,n){for(var s=this.options.ecmaVersion>=12&&void 0===t,r=n&&48===this.input.charCodeAt(this.pos),a=this.pos,i=0,o=0,l=0,c=null==t?1/0:t;l=97?p-97+10:p>=65?p-65+10:p>=48&&p<=57?p-48:1/0)>=e)break;o=p,i=i*e+u}}return s&&95===o&&this.raiseRecoverable(this.pos-1,"Numeric separator is not allowed at the last of digits"),this.pos===a||null!=t&&this.pos-a!==t?null:i},vs.readRadixNumber=function(e){var t=this.pos;this.pos+=2;var n=this.readInt(e);return null==n&&this.raise(this.start+2,"Expected number in radix "+e),this.options.ecmaVersion>=11&&110===this.input.charCodeAt(this.pos)?(n=gs(this.input.slice(t,this.pos)),++this.pos):Lt(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(Ht.num,n)},vs.readNumber=function(e){var t=this.pos;e||null!==this.readInt(10,void 0,!0)||this.raise(t,"Invalid number");var n=this.pos-t>=2&&48===this.input.charCodeAt(t);n&&this.strict&&this.raise(t,"Invalid number");var s=this.input.charCodeAt(this.pos);if(!n&&!e&&this.options.ecmaVersion>=11&&110===s){var r=gs(this.input.slice(t,this.pos));return++this.pos,Lt(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(Ht.num,r)}n&&/[89]/.test(this.input.slice(t,this.pos))&&(n=!1),46!==s||n||(++this.pos,this.readInt(10),s=this.input.charCodeAt(this.pos)),69!==s&&101!==s||n||(43!==(s=this.input.charCodeAt(++this.pos))&&45!==s||++this.pos,null===this.readInt(10)&&this.raise(t,"Invalid number")),Lt(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var a,i=(a=this.input.slice(t,this.pos),n?parseInt(a,8):parseFloat(a.replace(/_/g,"")));return this.finishToken(Ht.num,i)},vs.readCodePoint=function(){var e;if(123===this.input.charCodeAt(this.pos)){this.options.ecmaVersion<6&&this.unexpected();var t=++this.pos;e=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,e>1114111&&this.invalidStringToken(t,"Code point out of bounds")}else e=this.readHexChar(4);return e},vs.readString=function(e){for(var t="",n=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var s=this.input.charCodeAt(this.pos);if(s===e)break;92===s?(t+=this.input.slice(n,this.pos),t+=this.readEscapedChar(!1),n=this.pos):8232===s||8233===s?(this.options.ecmaVersion<10&&this.raise(this.start,"Unterminated string constant"),++this.pos,this.options.locations&&(this.curLine++,this.lineStart=this.pos)):(Wt(s)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return t+=this.input.slice(n,this.pos++),this.finishToken(Ht.string,t)};var bs={};vs.tryReadTemplateToken=function(){this.inTemplateElement=!0;try{this.readTmplToken()}catch(e){if(e!==bs)throw e;this.readInvalidTemplateToken()}this.inTemplateElement=!1},vs.invalidStringToken=function(e,t){if(this.inTemplateElement&&this.options.ecmaVersion>=9)throw bs;this.raise(e,t)},vs.readTmplToken=function(){for(var e="",t=this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated template");var n=this.input.charCodeAt(this.pos);if(96===n||36===n&&123===this.input.charCodeAt(this.pos+1))return this.pos!==this.start||this.type!==Ht.template&&this.type!==Ht.invalidTemplate?(e+=this.input.slice(t,this.pos),this.finishToken(Ht.template,e)):36===n?(this.pos+=2,this.finishToken(Ht.dollarBraceL)):(++this.pos,this.finishToken(Ht.backQuote));if(92===n)e+=this.input.slice(t,this.pos),e+=this.readEscapedChar(!0),t=this.pos;else if(Wt(n)){switch(e+=this.input.slice(t,this.pos),++this.pos,n){case 13:10===this.input.charCodeAt(this.pos)&&++this.pos;case 10:e+="\n";break;default:e+=String.fromCharCode(n)}this.options.locations&&(++this.curLine,this.lineStart=this.pos),t=this.pos}else++this.pos}},vs.readInvalidTemplateToken=function(){for(;this.pos=48&&t<=55){var s=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],r=parseInt(s,8);return r>255&&(s=s.slice(0,-1),r=parseInt(s,8)),this.pos+=s.length-1,t=this.input.charCodeAt(this.pos),"0"===s&&56!==t&&57!==t||!this.strict&&!e||this.invalidStringToken(this.pos-1-s.length,e?"Octal literal in template string":"Octal literal in strict mode"),String.fromCharCode(r)}return Wt(t)?(this.options.locations&&(this.lineStart=this.pos,++this.curLine),""):String.fromCharCode(t)}},vs.readHexChar=function(e){var t=this.pos,n=this.readInt(16,e);return null===n&&this.invalidStringToken(t,"Bad character escape sequence"),n},vs.readWord1=function(){this.containsEsc=!1;for(var e="",t=!0,n=this.pos,s=this.options.ecmaVersion>=6;this.pos...",!0,!0)},p=new RegExp(`^(?:${Object.keys(o).join("|")})$`);l.jsxTagStart.updateContext=function(){this.context.push(c.tc_expr),this.context.push(c.tc_oTag),this.exprAllowed=!1},l.jsxTagEnd.updateContext=function(e){let t=this.context.pop();t===c.tc_oTag&&e===Ht.slash||t===c.tc_cTag?(this.context.pop(),this.exprAllowed=this.curContext()===c.tc_expr):this.exprAllowed=!0},n={tokTypes:{...o,...l},tokContexts:{...c},keywordsRegExp:p,tokenIsLiteralPropertyName:e,tokenIsKeywordOrIdentifier:t,tokenIsIdentifier:s,tokenIsTSDeclarationStart:r,tokenIsTSTypeOperator:a,tokenIsTemplate:i}}return n}var Ps=1024,Es=new RegExp("(?=("+/(?:[^\S\n\r\u2028\u2029]|\/\/.*|\/\*.*?\*\/)*/y.source+"))\\1"+/(?=[\n\r\u2028\u2029]|\/\*(?!.*?\*\/)|$)/.source,"y"),Ts=class{constructor(){this.shorthandAssign=this.trailingComma=this.parenthesizedAssign=this.parenthesizedBind=this.doubleProto=-1}};function As(e,t){const n=t.key.name,s=e[n];let r="true";return"MethodDefinition"!==t.type||"get"!==t.kind&&"set"!==t.kind||(r=(t.static?"s":"i")+t.kind),"iget"===s&&"iset"===r||"iset"===s&&"iget"===r||"sget"===s&&"sset"===r||"sset"===s&&"sget"===r?(e[n]="true",!1):!!s||(e[n]=r,!1)}function $s(e,t){const{computed:n,key:s}=e;return!n&&("Identifier"===s.type&&s.name===t||"Literal"===s.type&&s.value===t)}var Rs={AbstractMethodHasImplementation:({methodName:e})=>`Method '${e}' cannot have an implementation because it is marked abstract.`,AbstractPropertyHasInitializer:({propertyName:e})=>`Property '${e}' cannot have an initializer because it is marked abstract.`,AccesorCannotDeclareThisParameter:"'get' and 'set' accessors cannot declare 'this' parameters.",AccesorCannotHaveTypeParameters:"An accessor cannot have type parameters.",CannotFindName:({name:e})=>`Cannot find name '${e}'.`,ClassMethodHasDeclare:"Class methods cannot have the 'declare' modifier.",ClassMethodHasReadonly:"Class methods cannot have the 'readonly' modifier.",ConstInitiailizerMustBeStringOrNumericLiteralOrLiteralEnumReference:"A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference.",ConstructorHasTypeParameters:"Type parameters cannot appear on a constructor declaration.",DeclareAccessor:({kind:e})=>`'declare' is not allowed in ${e}ters.`,DeclareClassFieldHasInitializer:"Initializers are not allowed in ambient contexts.",DeclareFunctionHasImplementation:"An implementation cannot be declared in ambient contexts.",DuplicateAccessibilityModifier:()=>"Accessibility modifier already seen.",DuplicateModifier:({modifier:e})=>`Duplicate modifier: '${e}'.`,EmptyHeritageClauseType:({token:e})=>`'${e}' list cannot be empty.`,EmptyTypeArguments:"Type argument list cannot be empty.",EmptyTypeParameters:"Type parameter list cannot be empty.",ExpectedAmbientAfterExportDeclare:"'export declare' must be followed by an ambient declaration.",ImportAliasHasImportType:"An import alias can not use 'import type'.",IncompatibleModifiers:({modifiers:e})=>`'${e[0]}' modifier cannot be used with '${e[1]}' modifier.`,IndexSignatureHasAbstract:"Index signatures cannot have the 'abstract' modifier.",IndexSignatureHasAccessibility:({modifier:e})=>`Index signatures cannot have an accessibility modifier ('${e}').`,IndexSignatureHasDeclare:"Index signatures cannot have the 'declare' modifier.",IndexSignatureHasOverride:"'override' modifier cannot appear on an index signature.",IndexSignatureHasStatic:"Index signatures cannot have the 'static' modifier.",InitializerNotAllowedInAmbientContext:"Initializers are not allowed in ambient contexts.",InvalidModifierOnTypeMember:({modifier:e})=>`'${e}' modifier cannot appear on a type member.`,InvalidModifierOnTypeParameter:({modifier:e})=>`'${e}' modifier cannot appear on a type parameter.`,InvalidModifierOnTypeParameterPositions:({modifier:e})=>`'${e}' modifier can only appear on a type parameter of a class, interface or type alias.`,InvalidModifiersOrder:({orderedModifiers:e})=>`'${e[0]}' modifier must precede '${e[1]}' modifier.`,InvalidPropertyAccessAfterInstantiationExpression:"Invalid property access after an instantiation expression. You can either wrap the instantiation expression in parentheses, or delete the type arguments.",InvalidTupleMemberLabel:"Tuple members must be labeled with a simple identifier.",MissingInterfaceName:"'interface' declarations must be followed by an identifier.",MixedLabeledAndUnlabeledElements:"Tuple members must all have names or all not have names.",NonAbstractClassHasAbstractMethod:"Abstract methods can only appear within an abstract class.",NonClassMethodPropertyHasAbstractModifer:"'abstract' modifier can only appear on a class, method, or property declaration.",OptionalTypeBeforeRequired:"A required element cannot follow an optional element.",OverrideNotInSubClass:"This member cannot have an 'override' modifier because its containing class does not extend another class.",PatternIsOptional:"A binding pattern parameter cannot be optional in an implementation signature.",PrivateElementHasAbstract:"Private elements cannot have the 'abstract' modifier.",PrivateElementHasAccessibility:({modifier:e})=>`Private elements cannot have an accessibility modifier ('${e}').`,PrivateMethodsHasAccessibility:({modifier:e})=>`Private methods cannot have an accessibility modifier ('${e}').`,ReadonlyForMethodSignature:"'readonly' modifier can only appear on a property declaration or index signature.",ReservedArrowTypeParam:"This syntax is reserved in files with the .mts or .cts extension. Add a trailing comma, as in `() => ...`.",ReservedTypeAssertion:"This syntax is reserved in files with the .mts or .cts extension. Use an `as` expression instead.",SetAccesorCannotHaveOptionalParameter:"A 'set' accessor cannot have an optional parameter.",SetAccesorCannotHaveRestParameter:"A 'set' accessor cannot have rest parameter.",SetAccesorCannotHaveReturnType:"A 'set' accessor cannot have a return type annotation.",SingleTypeParameterWithoutTrailingComma:({typeParameterName:e})=>`Single type parameter ${e} should have a trailing comma. Example usage: <${e},>.`,StaticBlockCannotHaveModifier:"Static class blocks cannot have any modifier.",TypeAnnotationAfterAssign:"Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`.",TypeImportCannotSpecifyDefaultAndNamed:"A type-only import can specify a default import or named bindings, but not both.",TypeModifierIsUsedInTypeExports:"The 'type' modifier cannot be used on a named export when 'export type' is used on its export statement.",TypeModifierIsUsedInTypeImports:"The 'type' modifier cannot be used on a named import when 'import type' is used on its import statement.",UnexpectedParameterModifier:"A parameter property is only allowed in a constructor implementation.",UnexpectedReadonly:"'readonly' type modifier is only permitted on array and tuple literal types.",GenericsEndWithComma:"Trailing comma is not allowed at the end of generics.",UnexpectedTypeAnnotation:"Did not expect a type annotation here.",UnexpectedTypeCastInParameter:"Unexpected type cast in parameter position.",UnsupportedImportTypeArgument:"Argument in a type import must be a string literal.",UnsupportedParameterPropertyKind:"A parameter property may not be declared using a binding pattern.",UnsupportedSignatureParameterKind:({type:e})=>`Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got ${e}.`,LetInLexicalBinding:"'let' is not allowed to be used as a name in 'let' or 'const' declarations."},Is={UnexpectedLeadingDecorator:"Leading decorators must be attached to a class declaration.",DecoratorConstructor:"Decorators can't be used with a constructor. Did you mean '@dec class { ... }'?",TrailingDecorator:"Decorators must be attached to a class element.",SpreadElementDecorator:"Decorators can't be used with SpreadElement"};var Ms=/(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;function qs(e){if(!e)throw new Error("Assert fail")}function Ls(e){return"accessor"===e}function Os(e){return"in"===e||"out"===e}var Ns={SCOPE_TOP:1,SCOPE_FUNCTION:2,SCOPE_ASYNC:4,SCOPE_GENERATOR:8,SCOPE_ARROW:16,SCOPE_SIMPLE_CATCH:32,SCOPE_SUPER:64,SCOPE_DIRECT_SUPER:128,BIND_NONE:0,BIND_VAR:1,BIND_LEXICAL:2,BIND_FUNCTION:3,BIND_SIMPLE_CATCH:4,BIND_TS_TYPE:6,BIND_TS_INTERFACE:7,BIND_TS_NAMESPACE:8,BIND_FLAGS_TS_EXPORT_ONLY:1024,BIND_FLAGS_TS_IMPORT:4096,BIND_FLAGS_TS_ENUM:256,BIND_FLAGS_TS_CONST_ENUM:512,BIND_FLAGS_CLASS:128};function Ds(e,t){return Ns.SCOPE_FUNCTION|(e?Ns.SCOPE_ASYNC:0)|(t?Ns.SCOPE_GENERATOR:0)}function js(e){if("MemberExpression"!==e.type)return!1;const{computed:t,property:n}=e;return(!t||!("TemplateLiteral"!==n.type||n.expressions.length>0))&&Bs(e.object)}function Bs(e){return"Identifier"===e.type||"MemberExpression"===e.type&&(!e.computed&&Bs(e.object))}function Fs(e){return"private"===e||"public"===e||"protected"===e}const Vs=fn.extend(function(e){const{dts:t=!1}={};return function(e){const n=e.acorn||xs,s=Ss(n),r=n.tokTypes,a=n.keywordTypes,i=n.isIdentifierStart,o=n.lineBreak,l=n.isNewLine,c=n.tokContexts,p=n.isIdentifierChar,{tokTypes:u,tokContexts:d,keywordsRegExp:h,tokenIsLiteralPropertyName:m,tokenIsTemplate:f,tokenIsTSDeclarationStart:y,tokenIsIdentifier:v,tokenIsKeywordOrIdentifier:g,tokenIsTSTypeOperator:b}=s;function _(e,t,n=e.length){for(let s=t;s{this.tsParseModifiers({modified:e,allowedModifiers:["const"],disallowedModifiers:["in","out"],errorTemplate:Rs.InvalidModifierOnTypeParameterPositions})},this.ecmaVersion=this.options.ecmaVersion}static get acornTypeScript(){return s}get acornTypeScript(){return s}getTokenFromCodeInType(e){return 62===e||60===e?this.finishOp(r.relational,1):super.getTokenFromCode(e)}readToken(e){if(!this.inType){let t=this.curContext();if(t===d.tc_expr)return this.jsx_readToken();if(t===d.tc_oTag||t===d.tc_cTag){if(i(e))return this.jsx_readWord();if(62==e)return++this.pos,this.finishToken(u.jsxTagEnd);if((34===e||39===e)&&t==d.tc_oTag)return this.jsx_readString(e)}if(60===e&&this.exprAllowed&&33!==this.input.charCodeAt(this.pos+1))return++this.pos,this.finishToken(r.relational,"<")}return super.readToken(e)}getTokenFromCode(e){return this.inType?this.getTokenFromCodeInType(e):64===e?(++this.pos,this.finishToken(u.at)):super.getTokenFromCode(e)}isAbstractClass(){return this.ts_isContextual(u.abstract)&&this.lookahead().type===r._class}finishNode(e,t){return""!==e.type&&0!==e.end?e:super.finishNode(e,t)}tryParse(e,t=this.cloneCurLookaheadState()){const n={node:null};try{return{node:e(((e=null)=>{throw n.node=e,n})),error:null,thrown:!1,aborted:!1,failState:null}}catch(e){const s=this.getCurLookaheadState();if(this.setLookaheadState(t),e instanceof SyntaxError)return{node:null,error:e,thrown:!0,aborted:!1,failState:s};if(e===n)return{node:n.node,error:null,thrown:!1,aborted:!0,failState:s};throw e}}setOptionalParametersError(e,t){e.optionalParametersLoc=t?.loc??this.startLoc}reScan_lt_gt(){this.type===r.relational&&(this.pos-=1,this.readToken_lt_gt(this.fullCharCodeAtPos()))}reScan_lt(){const{type:e}=this;return e===r.bitShift?(this.pos-=2,this.finishOp(r.relational,1),r.relational):e}resetEndLocation(e,t=this.lastTokEnd,n=this.lastTokEndLoc){e.end=t,e.loc.end=n,this.options.ranges&&(e.range[1]=t)}startNodeAtNode(e){return super.startNodeAt(e.start,e.loc.start)}nextTokenStart(){return this.nextTokenStartSince(this.pos)}tsHasSomeModifiers(e,t){return t.some((t=>Fs(t)?e.accessibility===t:!!e[t]))}tsIsStartOfStaticBlocks(){return this.isContextual("static")&&123===this.lookaheadCharCode()}tsCheckForInvalidTypeCasts(e){e.forEach((e=>{"TSTypeCastExpression"===e?.type&&this.raise(e.typeAnnotation.start,Rs.UnexpectedTypeAnnotation)}))}atPossibleAsyncArrow(e){return"Identifier"===e.type&&"async"===e.name&&this.lastTokEndLoc.column===e.end&&!this.canInsertSemicolon()&&e.end-e.start==5&&e.start===this.potentialArrowAt}tsIsIdentifier(){return v(this.type)}tsTryParseTypeOrTypePredicateAnnotation(){return this.match(r.colon)?this.tsParseTypeOrTypePredicateAnnotation(r.colon):void 0}tsTryParseGenericAsyncArrowFunction(e,t,n){if(!this.tsMatchLeftRelational())return;const s=this.maybeInArrowParameters;this.maybeInArrowParameters=!0;const a=this.tsTryParseAndCatch((()=>{const n=this.startNodeAt(e,t);return n.typeParameters=this.tsParseTypeParameters(this.tsParseConstModifier),super.parseFunctionParams(n),n.returnType=this.tsTryParseTypeOrTypePredicateAnnotation(),this.expect(r.arrow),n}));return this.maybeInArrowParameters=s,a?super.parseArrowExpression(a,null,!0,n):void 0}tsParseTypeArgumentsInExpression(){if(this.reScan_lt()===r.relational)return this.tsParseTypeArguments()}tsInNoContext(e){const t=this.context;this.context=[t[0]];try{return e()}finally{this.context=t}}tsTryParseTypeAnnotation(){return this.match(r.colon)?this.tsParseTypeAnnotation():void 0}isUnparsedContextual(e,t){const n=e+t.length;if(this.input.slice(e,n)===t){const e=this.input.charCodeAt(n);return!(p(e)||55296==(64512&e))}return!1}isAbstractConstructorSignature(){return this.ts_isContextual(u.abstract)&&this.lookahead().type===r._new}nextTokenStartSince(e){return Ms.lastIndex=e,Ms.test(this.input)?Ms.lastIndex:e}lookaheadCharCode(){return this.input.charCodeAt(this.nextTokenStart())}compareLookaheadState(e,t){for(const n of Object.keys(e))if(e[n]!==t[n])return!1;return!0}createLookaheadState(){this.value=null,this.context=[this.curContext()]}getCurLookaheadState(){return{endLoc:this.endLoc,lastTokEnd:this.lastTokEnd,lastTokStart:this.lastTokStart,lastTokStartLoc:this.lastTokStartLoc,pos:this.pos,value:this.value,type:this.type,start:this.start,end:this.end,context:this.context,startLoc:this.startLoc,lastTokEndLoc:this.lastTokEndLoc,curLine:this.curLine,lineStart:this.lineStart,curPosition:this.curPosition,containsEsc:this.containsEsc}}cloneCurLookaheadState(){return{pos:this.pos,value:this.value,type:this.type,start:this.start,end:this.end,context:this.context&&this.context.slice(),startLoc:this.startLoc,lastTokEndLoc:this.lastTokEndLoc,endLoc:this.endLoc,lastTokEnd:this.lastTokEnd,lastTokStart:this.lastTokStart,lastTokStartLoc:this.lastTokStartLoc,curLine:this.curLine,lineStart:this.lineStart,curPosition:this.curPosition,containsEsc:this.containsEsc}}setLookaheadState(e){this.pos=e.pos,this.value=e.value,this.endLoc=e.endLoc,this.lastTokEnd=e.lastTokEnd,this.lastTokStart=e.lastTokStart,this.lastTokStartLoc=e.lastTokStartLoc,this.type=e.type,this.start=e.start,this.end=e.end,this.context=e.context,this.startLoc=e.startLoc,this.lastTokEndLoc=e.lastTokEndLoc,this.curLine=e.curLine,this.lineStart=e.lineStart,this.curPosition=e.curPosition,this.containsEsc=e.containsEsc}tsLookAhead(e){const t=this.getCurLookaheadState(),n=e();return this.setLookaheadState(t),n}lookahead(e){const t=this.getCurLookaheadState();if(this.createLookaheadState(),this.isLookahead=!0,void 0!==e)for(let t=0;t-1;)++this.curLine,n=this.lineStart=e;this.isLookahead||this.options.onComment&&this.options.onComment(!0,this.input.slice(t+2,n),t,this.pos,e,this.curPosition())}skipLineComment(e){let t,n=this.pos;this.isLookahead||(t=this.options.onComment&&this.curPosition());let s=this.input.charCodeAt(this.pos+=e);for(;this.pos{if(n===r._function)return e.declare=!0,this.parseFunctionStatement(e,!1,!0);if(n===r._class)return e.declare=!0,this.parseClass(e,!0);if(n===u.enum)return this.tsParseEnumDeclaration(e,{declare:!0});if(n===u.global)return this.tsParseAmbientExternalModuleDeclaration(e);if(n===r._const||n===r._var)return this.match(r._const)&&this.isLookaheadContextual("enum")?(this.expect(r._const),this.tsParseEnumDeclaration(e,{const:!0,declare:!0})):(e.declare=!0,this.parseVarStatement(e,t||this.value,!0));if(n===u.interface){const t=this.tsParseInterfaceDeclaration(e,{declare:!0});if(t)return t}return v(n)?this.tsParseDeclaration(e,this.value,!0):void 0}))}tsIsListTerminator(e){switch(e){case"EnumMembers":case"TypeMembers":return this.match(r.braceR);case"HeritageClauseElement":return this.match(r.braceL);case"TupleElementTypes":return this.match(r.bracketR);case"TypeParametersOrArguments":return this.tsMatchRightRelational()}}tsParseDelimitedListWorker(e,t,n,s){const a=[];let i=-1;for(;!this.tsIsListTerminator(e);){i=-1;const s=t();if(null==s)return;if(a.push(s),!this.eat(r.comma)){if(this.tsIsListTerminator(e))break;return void(n&&this.expect(r.comma))}i=this.lastTokStart}return s&&(s.value=i),a}tsParseDelimitedList(e,t,n){return function(e){if(null==e)throw new Error(`Unexpected ${e} value.`);return e}(this.tsParseDelimitedListWorker(e,t,!0,n))}tsParseBracketedList(e,t,n,s,a){s||(n?this.expect(r.bracketL):this.expect(r.relational));const i=this.tsParseDelimitedList(e,t,a);return n?this.expect(r.bracketR):this.expect(r.relational),i}tsParseTypeParameterName(){return this.parseIdent().name}tsEatThenParseType(e){return this.match(e)?this.tsNextThenParseType():void 0}tsExpectThenParseType(e){return this.tsDoThenParseType((()=>this.expect(e)))}tsNextThenParseType(){return this.tsDoThenParseType((()=>this.next()))}tsDoThenParseType(e){return this.tsInType((()=>(e(),this.tsParseType())))}tsSkipParameterStart(){if(v(this.type)||this.match(r._this))return this.next(),!0;if(this.match(r.braceL))try{return this.parseObj(!0),!0}catch{return!1}if(this.match(r.bracketL)){this.next();try{return this.parseBindingList(r.bracketR,!0,!0),!0}catch{return!1}}return!1}tsIsUnambiguouslyStartOfFunctionType(){if(this.next(),this.match(r.parenR)||this.match(r.ellipsis))return!0;if(this.tsSkipParameterStart()){if(this.match(r.colon)||this.match(r.comma)||this.match(r.question)||this.match(r.eq))return!0;if(this.match(r.parenR)&&(this.next(),this.match(r.arrow)))return!0}return!1}tsIsStartOfFunctionType(){return!!this.tsMatchLeftRelational()||this.match(r.parenL)&&this.tsLookAhead(this.tsIsUnambiguouslyStartOfFunctionType.bind(this))}tsInAllowConditionalTypesContext(e){const t=this.inDisallowConditionalTypesContext;this.inDisallowConditionalTypesContext=!1;try{return e()}finally{this.inDisallowConditionalTypesContext=t}}tsParseBindingListForSignature(){return super.parseBindingList(r.parenR,!0,!0).map((e=>("Identifier"!==e.type&&"RestElement"!==e.type&&"ObjectPattern"!==e.type&&"ArrayPattern"!==e.type&&this.raise(e.start,Rs.UnsupportedSignatureParameterKind(e.type)),e)))}tsParseTypePredicateAsserts(){if(this.type!==u.asserts)return!1;const e=this.containsEsc;return this.next(),!(!v(this.type)&&!this.match(r._this))&&(e&&this.raise(this.lastTokStart,"Escape sequence in keyword asserts"),!0)}tsParseThisTypeNode(){const e=this.startNode();return this.next(),this.finishNode(e,"TSThisType")}tsParseTypeAnnotation(e=!0,t=this.startNode()){return this.tsInType((()=>{e&&this.expect(r.colon),t.typeAnnotation=this.tsParseType()})),this.finishNode(t,"TSTypeAnnotation")}tsParseThisTypePredicate(e){this.next();const t=this.startNodeAtNode(e);return t.parameterName=e,t.typeAnnotation=this.tsParseTypeAnnotation(!1),t.asserts=!1,this.finishNode(t,"TSTypePredicate")}tsParseThisTypeOrThisTypePredicate(){const e=this.tsParseThisTypeNode();return this.isContextual("is")&&!this.hasPrecedingLineBreak()?this.tsParseThisTypePredicate(e):e}tsParseTypePredicatePrefix(){const e=this.parseIdent();if(this.isContextual("is")&&!this.hasPrecedingLineBreak())return this.next(),e}tsParseTypeOrTypePredicateAnnotation(e){return this.tsInType((()=>{const t=this.startNode();this.expect(e);const n=this.startNode(),s=!!this.tsTryParse(this.tsParseTypePredicateAsserts.bind(this));if(s&&this.match(r._this)){let e=this.tsParseThisTypeOrThisTypePredicate();return"TSThisType"===e.type?(n.parameterName=e,n.asserts=!0,n.typeAnnotation=null,e=this.finishNode(n,"TSTypePredicate")):(this.resetStartLocationFromNode(e,n),e.asserts=!0),t.typeAnnotation=e,this.finishNode(t,"TSTypeAnnotation")}const a=this.tsIsIdentifier()&&this.tsTryParse(this.tsParseTypePredicatePrefix.bind(this));if(!a)return s?(n.parameterName=this.parseIdent(),n.asserts=s,n.typeAnnotation=null,t.typeAnnotation=this.finishNode(n,"TSTypePredicate"),this.finishNode(t,"TSTypeAnnotation")):this.tsParseTypeAnnotation(!1,t);const i=this.tsParseTypeAnnotation(!1);return n.parameterName=a,n.typeAnnotation=i,n.asserts=s,t.typeAnnotation=this.finishNode(n,"TSTypePredicate"),this.finishNode(t,"TSTypeAnnotation")}))}tsFillSignature(e,t){const n=e===r.arrow,s="typeAnnotation";t.typeParameters=this.tsTryParseTypeParameters(),this.expect(r.parenL),t.parameters=this.tsParseBindingListForSignature(),(n||this.match(e))&&(t[s]=this.tsParseTypeOrTypePredicateAnnotation(e))}tsTryNextParseConstantContext(){if(this.lookahead().type!==r._const)return null;this.next();const e=this.tsParseTypeReference();return(e.typeParameters||e.typeArguments)&&this.raise(e.typeName.start,Rs.CannotFindName({name:"const"})),e}tsParseFunctionOrConstructorType(e,t){const n=this.startNode();return"TSConstructorType"===e&&(n.abstract=!!t,t&&this.next(),this.next()),this.tsInAllowConditionalTypesContext((()=>this.tsFillSignature(r.arrow,n))),this.finishNode(n,e)}tsParseUnionOrIntersectionType(e,t,n){const s=this.startNode(),r=this.eat(n),a=[];do{a.push(t())}while(this.eat(n));return 1!==a.length||r?(s.types=a,this.finishNode(s,e)):a[0]}tsCheckTypeAnnotationForReadOnly(e){switch(e.typeAnnotation.type){case"TSTupleType":case"TSArrayType":return;default:this.raise(e.start,Rs.UnexpectedReadonly)}}tsParseTypeOperator(){const e=this.startNode(),t=this.value;return this.next(),e.operator=t,e.typeAnnotation=this.tsParseTypeOperatorOrHigher(),"readonly"===t&&this.tsCheckTypeAnnotationForReadOnly(e),this.finishNode(e,"TSTypeOperator")}tsParseConstraintForInferType(){if(this.eat(r._extends)){const e=this.tsInDisallowConditionalTypesContext((()=>this.tsParseType()));if(this.inDisallowConditionalTypesContext||!this.match(r.question))return e}}tsParseInferType(){const e=this.startNode();this.expectContextual("infer");const t=this.startNode();return t.name=this.tsParseTypeParameterName(),t.constraint=this.tsTryParse((()=>this.tsParseConstraintForInferType())),e.typeParameter=this.finishNode(t,"TSTypeParameter"),this.finishNode(e,"TSInferType")}tsParseLiteralTypeNode(){const e=this.startNode();return e.literal=(()=>{switch(this.type){case r.num:case r.string:case r._true:case r._false:return this.parseExprAtom();default:this.unexpected()}})(),this.finishNode(e,"TSLiteralType")}tsParseImportType(){const e=this.startNode();return this.expect(r._import),this.expect(r.parenL),this.match(r.string)||this.raise(this.start,Rs.UnsupportedImportTypeArgument),e.argument=this.parseExprAtom(),this.expect(r.parenR),this.eat(r.dot)&&(e.qualifier=this.tsParseEntityName()),this.tsMatchLeftRelational()&&(e.typeArguments=this.tsParseTypeArguments()),this.finishNode(e,"TSImportType")}tsParseTypeQuery(){const e=this.startNode();return this.expect(r._typeof),this.match(r._import)?e.exprName=this.tsParseImportType():e.exprName=this.tsParseEntityName(),!this.hasPrecedingLineBreak()&&this.tsMatchLeftRelational()&&(e.typeArguments=this.tsParseTypeArguments()),this.finishNode(e,"TSTypeQuery")}tsParseMappedTypeParameter(){const e=this.startNode();return e.name=this.tsParseTypeParameterName(),e.constraint=this.tsExpectThenParseType(r._in),this.finishNode(e,"TSTypeParameter")}tsParseMappedType(){const e=this.startNode();return this.expect(r.braceL),this.match(r.plusMin)?(e.readonly=this.value,this.next(),this.expectContextual("readonly")):this.eatContextual("readonly")&&(e.readonly=!0),this.expect(r.bracketL),e.typeParameter=this.tsParseMappedTypeParameter(),e.nameType=this.eatContextual("as")?this.tsParseType():null,this.expect(r.bracketR),this.match(r.plusMin)?(e.optional=this.value,this.next(),this.expect(r.question)):this.eat(r.question)&&(e.optional=!0),e.typeAnnotation=this.tsTryParseType(),this.semicolon(),this.expect(r.braceR),this.finishNode(e,"TSMappedType")}tsParseTypeLiteral(){const e=this.startNode();return e.members=this.tsParseObjectTypeMembers(),this.finishNode(e,"TSTypeLiteral")}tsParseTupleElementType(){const e=this.startLoc,t=this.start,n=this.eat(r.ellipsis);let s=this.tsParseType();const a=this.eat(r.question);if(this.eat(r.colon)){const e=this.startNodeAtNode(s);e.optional=a,"TSTypeReference"!==s.type||s.typeArguments||"Identifier"!==s.typeName.type?(this.raise(s.start,Rs.InvalidTupleMemberLabel),e.label=s):e.label=s.typeName,e.elementType=this.tsParseType(),s=this.finishNode(e,"TSNamedTupleMember")}else if(a){const e=this.startNodeAtNode(s);e.typeAnnotation=s,s=this.finishNode(e,"TSOptionalType")}if(n){const n=this.startNodeAt(t,e);n.typeAnnotation=s,s=this.finishNode(n,"TSRestType")}return s}tsParseTupleType(){const e=this.startNode();e.elementTypes=this.tsParseBracketedList("TupleElementTypes",this.tsParseTupleElementType.bind(this),!0,!1);let t=!1,n=null;return e.elementTypes.forEach((e=>{const{type:s}=e;!t||"TSRestType"===s||"TSOptionalType"===s||"TSNamedTupleMember"===s&&e.optional||this.raise(e.start,Rs.OptionalTypeBeforeRequired),t||="TSNamedTupleMember"===s&&e.optional||"TSOptionalType"===s;let r=s;"TSRestType"===s&&(r=(e=e.typeAnnotation).type);const a="TSNamedTupleMember"===r;n??=a,n!==a&&this.raise(e.start,Rs.MixedLabeledAndUnlabeledElements)})),this.finishNode(e,"TSTupleType")}tsParseTemplateLiteralType(){const e=this.startNode();return e.literal=this.parseTemplate({isTagged:!1}),this.finishNode(e,"TSLiteralType")}tsParseTypeReference(){const e=this.startNode();return e.typeName=this.tsParseEntityName(),!this.hasPrecedingLineBreak()&&this.tsMatchLeftRelational()&&(e.typeArguments=this.tsParseTypeArguments()),this.finishNode(e,"TSTypeReference")}tsMatchLeftRelational(){return this.match(r.relational)&&"<"===this.value}tsMatchRightRelational(){return this.match(r.relational)&&">"===this.value}tsParseParenthesizedType(){const e=this.startNode();return this.expect(r.parenL),e.typeAnnotation=this.tsParseType(),this.expect(r.parenR),this.finishNode(e,"TSParenthesizedType")}tsParseNonArrayType(){switch(this.type){case r.string:case r.num:case r._true:case r._false:return this.tsParseLiteralTypeNode();case r.plusMin:if("-"===this.value){const e=this.startNode();return this.lookahead().type!==r.num&&this.unexpected(),e.literal=this.parseMaybeUnary(),this.finishNode(e,"TSLiteralType")}break;case r._this:return this.tsParseThisTypeOrThisTypePredicate();case r._typeof:return this.tsParseTypeQuery();case r._import:return this.tsParseImportType();case r.braceL:return this.tsLookAhead(this.tsIsStartOfMappedType.bind(this))?this.tsParseMappedType():this.tsParseTypeLiteral();case r.bracketL:return this.tsParseTupleType();case r.parenL:return this.tsParseParenthesizedType();case r.backQuote:case r.dollarBraceL:return this.tsParseTemplateLiteralType();default:{const{type:e}=this;if(v(e)||e===r._void||e===r._null){const t=e===r._void?"TSVoidKeyword":e===r._null?"TSNullKeyword":function(e){switch(e){case"any":return"TSAnyKeyword";case"boolean":return"TSBooleanKeyword";case"bigint":return"TSBigIntKeyword";case"never":return"TSNeverKeyword";case"number":return"TSNumberKeyword";case"object":return"TSObjectKeyword";case"string":return"TSStringKeyword";case"symbol":return"TSSymbolKeyword";case"undefined":return"TSUndefinedKeyword";case"unknown":return"TSUnknownKeyword";default:return}}(this.value);if(void 0!==t&&46!==this.lookaheadCharCode()){const e=this.startNode();return this.next(),this.finishNode(e,t)}return this.tsParseTypeReference()}}}this.unexpected()}tsParseArrayTypeOrHigher(){let e=this.tsParseNonArrayType();for(;!this.hasPrecedingLineBreak()&&this.eat(r.bracketL);)if(this.match(r.bracketR)){const t=this.startNodeAtNode(e);t.elementType=e,this.expect(r.bracketR),e=this.finishNode(t,"TSArrayType")}else{const t=this.startNodeAtNode(e);t.objectType=e,t.indexType=this.tsParseType(),this.expect(r.bracketR),e=this.finishNode(t,"TSIndexedAccessType")}return e}tsParseTypeOperatorOrHigher(){return b(this.type)&&!this.containsEsc?this.tsParseTypeOperator():this.isContextual("infer")?this.tsParseInferType():this.tsInAllowConditionalTypesContext((()=>this.tsParseArrayTypeOrHigher()))}tsParseIntersectionTypeOrHigher(){return this.tsParseUnionOrIntersectionType("TSIntersectionType",this.tsParseTypeOperatorOrHigher.bind(this),r.bitwiseAND)}tsParseUnionTypeOrHigher(){return this.tsParseUnionOrIntersectionType("TSUnionType",this.tsParseIntersectionTypeOrHigher.bind(this),r.bitwiseOR)}tsParseNonConditionalType(){return this.tsIsStartOfFunctionType()?this.tsParseFunctionOrConstructorType("TSFunctionType"):this.match(r._new)?this.tsParseFunctionOrConstructorType("TSConstructorType"):this.isAbstractConstructorSignature()?this.tsParseFunctionOrConstructorType("TSConstructorType",!0):this.tsParseUnionTypeOrHigher()}tsParseType(){qs(this.inType);const e=this.tsParseNonConditionalType();if(this.inDisallowConditionalTypesContext||this.hasPrecedingLineBreak()||!this.eat(r._extends))return e;const t=this.startNodeAtNode(e);return t.checkType=e,t.extendsType=this.tsInDisallowConditionalTypesContext((()=>this.tsParseNonConditionalType())),this.expect(r.question),t.trueType=this.tsInAllowConditionalTypesContext((()=>this.tsParseType())),this.expect(r.colon),t.falseType=this.tsInAllowConditionalTypesContext((()=>this.tsParseType())),this.finishNode(t,"TSConditionalType")}tsIsUnambiguouslyIndexSignature(){return this.next(),!!v(this.type)&&(this.next(),this.match(r.colon))}tsInType(e){const t=this.inType;this.inType=!0;try{return e()}finally{this.inType=t}}tsTryParseIndexSignature(e){if(!this.match(r.bracketL)||!this.tsLookAhead(this.tsIsUnambiguouslyIndexSignature.bind(this)))return;this.expect(r.bracketL);const t=this.parseIdent();t.typeAnnotation=this.tsParseTypeAnnotation(),this.resetEndLocation(t),this.expect(r.bracketR),e.parameters=[t];const n=this.tsTryParseTypeAnnotation();return n&&(e.typeAnnotation=n),this.tsParseTypeMemberSemicolon(),this.finishNode(e,"TSIndexSignature")}tsParseNoneModifiers(e){this.tsParseModifiers({modified:e,allowedModifiers:[],disallowedModifiers:["in","out"],errorTemplate:Rs.InvalidModifierOnTypeParameterPositions})}tsParseTypeParameter(e=this.tsParseNoneModifiers.bind(this)){const t=this.startNode();return e(t),t.name=this.tsParseTypeParameterName(),t.constraint=this.tsEatThenParseType(r._extends),t.default=this.tsEatThenParseType(r.eq),this.finishNode(t,"TSTypeParameter")}tsParseTypeParameters(e){const t=this.startNode();this.tsMatchLeftRelational()||this.matchJsx("jsxTagStart")?this.next():this.unexpected();const n={value:-1};return t.params=this.tsParseBracketedList("TypeParametersOrArguments",this.tsParseTypeParameter.bind(this,e),!1,!0,n),0===t.params.length&&this.raise(this.start,Rs.EmptyTypeParameters),-1!==n.value&&this.addExtra(t,"trailingComma",n.value),this.finishNode(t,"TSTypeParameterDeclaration")}tsTryParseTypeParameters(e){if(this.tsMatchLeftRelational())return this.tsParseTypeParameters(e)}tsTryParse(e){const t=this.getCurLookaheadState(),n=e();return void 0!==n&&!1!==n?n:void this.setLookaheadState(t)}tsTokenCanFollowModifier(){return(this.match(r.bracketL)||this.match(r.braceL)||this.match(r.star)||this.match(r.ellipsis)||this.match(r.privateId)||this.isLiteralPropertyName())&&!this.hasPrecedingLineBreak()}tsNextTokenCanFollowModifier(){return this.next(!0),this.tsTokenCanFollowModifier()}tsParseModifier(e,t){const n=this.value;if(-1!==e.indexOf(n)&&!this.containsEsc){if(t&&this.tsIsStartOfStaticBlocks())return;if(this.tsTryParse(this.tsNextTokenCanFollowModifier.bind(this)))return n}}tsParseModifiersByMap({modified:e,map:t}){for(const n of Object.keys(t))e[n]=t[n]}tsParseModifiers({modified:e,allowedModifiers:t,disallowedModifiers:n,stopOnStartOfClassStaticBlock:s,errorTemplate:r=Rs.InvalidModifierOnTypeMember}){const a={},i=(t,n,s,r)=>{n===s&&e[r]&&this.raise(t.column,Rs.InvalidModifiersOrder({orderedModifiers:[s,r]}))},o=(t,n,s,r)=>{(e[s]&&n===r||e[r]&&n===s)&&this.raise(t.column,Rs.IncompatibleModifiers({modifiers:[s,r]}))};for(;;){const l=this.startLoc,c=this.tsParseModifier(t.concat(n??[]),s);if(!c)break;Fs(c)?e.accessibility?this.raise(this.start,Rs.DuplicateAccessibilityModifier()):(i(l,c,c,"override"),i(l,c,c,"static"),i(l,c,c,"readonly"),i(l,c,c,"accessor"),a.accessibility=c,e.accessibility=c):Os(c)?e[c]?this.raise(this.start,Rs.DuplicateModifier({modifier:c})):(i(l,c,"in","out"),a[c]=c,e[c]=!0):Ls(c)?e[c]?this.raise(this.start,Rs.DuplicateModifier({modifier:c})):(o(l,c,"accessor","readonly"),o(l,c,"accessor","static"),o(l,c,"accessor","override"),a[c]=c,e[c]=!0):"const"===c?e[c]?this.raise(this.start,Rs.DuplicateModifier({modifier:c})):(a[c]=c,e[c]=!0):Object.hasOwnProperty.call(e,c)?this.raise(this.start,Rs.DuplicateModifier({modifier:c})):(i(l,c,"static","readonly"),i(l,c,"static","override"),i(l,c,"override","readonly"),i(l,c,"abstract","override"),o(l,c,"declare","override"),o(l,c,"static","abstract"),a[c]=c,e[c]=!0),n?.includes(c)&&this.raise(this.start,r)}return a}tsParseInOutModifiers(e){this.tsParseModifiers({modified:e,allowedModifiers:["in","out"],disallowedModifiers:["public","private","protected","readonly","declare","abstract","override"],errorTemplate:Rs.InvalidModifierOnTypeParameter})}parseMaybeUnary(e,t,n,s){return this.tsMatchLeftRelational()?this.tsParseTypeAssertion():super.parseMaybeUnary(e,t,n,s)}tsParseTypeAssertion(){const e=this.tryParse((()=>{const e=this.startNode(),t=this.tsTryNextParseConstantContext();return e.typeAnnotation=t||this.tsNextThenParseType(),this.expect(r.relational),e.expression=this.parseMaybeUnary(),this.finishNode(e,"TSTypeAssertion")}));return e.error?this.tsParseTypeParameters(this.tsParseConstModifier):e.node}tsParseTypeArguments(){const e=this.startNode();return e.params=this.tsInType((()=>this.tsInNoContext((()=>(this.expect(r.relational),this.tsParseDelimitedList("TypeParametersOrArguments",this.tsParseType.bind(this))))))),0===e.params.length&&this.raise(this.start,Rs.EmptyTypeArguments),this.exprAllowed=!1,this.expect(r.relational),this.finishNode(e,"TSTypeParameterInstantiation")}tsParseHeritageClause(e){const t=this.start,n=this.tsParseDelimitedList("HeritageClauseElement",(()=>{const e=this.startNode();return e.expression=this.tsParseEntityName(),this.tsMatchLeftRelational()&&(e.typeParameters=this.tsParseTypeArguments()),this.finishNode(e,"TSExpressionWithTypeArguments")}));return n.length||this.raise(t,Rs.EmptyHeritageClauseType({token:e})),n}tsParseTypeMemberSemicolon(){this.eat(r.comma)||this.isLineTerminator()||this.expect(r.semi)}tsTryParseAndCatch(e){const t=this.tryParse((t=>e()||t()));if(!t.aborted&&t.node)return t.error&&this.setLookaheadState(t.failState),t.node}tsParseSignatureMember(e,t){return this.tsFillSignature(r.colon,t),this.tsParseTypeMemberSemicolon(),this.finishNode(t,e)}tsParsePropertyOrMethodSignature(e,t){this.eat(r.question)&&(e.optional=!0);const n=e;if(this.match(r.parenL)||this.tsMatchLeftRelational()){t&&this.raise(e.start,Rs.ReadonlyForMethodSignature);const s=n;s.kind&&this.tsMatchLeftRelational()&&this.raise(this.start,Rs.AccesorCannotHaveTypeParameters),this.tsFillSignature(r.colon,s),this.tsParseTypeMemberSemicolon();const a="parameters",i="typeAnnotation";if("get"===s.kind)s[a].length>0&&(this.raise(this.start,"A 'get' accesor must not have any formal parameters."),this.isThisParam(s[a][0])&&this.raise(this.start,Rs.AccesorCannotDeclareThisParameter));else if("set"===s.kind){if(1!==s[a].length)this.raise(this.start,"A 'get' accesor must not have any formal parameters.");else{const e=s[a][0];this.isThisParam(e)&&this.raise(this.start,Rs.AccesorCannotDeclareThisParameter),"Identifier"===e.type&&e.optional&&this.raise(this.start,Rs.SetAccesorCannotHaveOptionalParameter),"RestElement"===e.type&&this.raise(this.start,Rs.SetAccesorCannotHaveRestParameter)}s[i]&&this.raise(s[i].start,Rs.SetAccesorCannotHaveReturnType)}else s.kind="method";return this.finishNode(s,"TSMethodSignature")}{const e=n;t&&(e.readonly=!0);const s=this.tsTryParseTypeAnnotation();return s&&(e.typeAnnotation=s),this.tsParseTypeMemberSemicolon(),this.finishNode(e,"TSPropertySignature")}}tsParseTypeMember(){const e=this.startNode();if(this.match(r.parenL)||this.tsMatchLeftRelational())return this.tsParseSignatureMember("TSCallSignatureDeclaration",e);if(this.match(r._new)){const t=this.startNode();return this.next(),this.match(r.parenL)||this.tsMatchLeftRelational()?this.tsParseSignatureMember("TSConstructSignatureDeclaration",e):(e.key=this.createIdentifier(t,"new"),this.tsParsePropertyOrMethodSignature(e,!1))}this.tsParseModifiers({modified:e,allowedModifiers:["readonly"],disallowedModifiers:["declare","abstract","private","protected","public","static","override"]});const t=this.tsTryParseIndexSignature(e);return t||(this.parsePropertyName(e),e.computed||"Identifier"!==e.key.type||"get"!==e.key.name&&"set"!==e.key.name||!this.tsTokenCanFollowModifier()||(e.kind=e.key.name,this.parsePropertyName(e)),this.tsParsePropertyOrMethodSignature(e,!!e.readonly))}tsParseList(e,t){const n=[];for(;!this.tsIsListTerminator(e);)n.push(t());return n}tsParseObjectTypeMembers(){this.expect(r.braceL);const e=this.tsParseList("TypeMembers",this.tsParseTypeMember.bind(this));return this.expect(r.braceR),e}tsParseInterfaceDeclaration(e,t={}){if(this.hasFollowingLineBreak())return null;this.expectContextual("interface"),t.declare&&(e.declare=!0),v(this.type)?(e.id=this.parseIdent(),this.checkLValSimple(e.id,Ns.BIND_TS_INTERFACE)):(e.id=null,this.raise(this.start,Rs.MissingInterfaceName)),e.typeParameters=this.tsTryParseTypeParameters(this.tsParseInOutModifiers.bind(this)),this.eat(r._extends)&&(e.extends=this.tsParseHeritageClause("extends"));const n=this.startNode();return n.body=this.tsInType(this.tsParseObjectTypeMembers.bind(this)),e.body=this.finishNode(n,"TSInterfaceBody"),this.finishNode(e,"TSInterfaceDeclaration")}tsParseAbstractDeclaration(e){if(this.match(r._class))return e.abstract=!0,this.parseClass(e,!0);if(this.ts_isContextual(u.interface)){if(!this.hasFollowingLineBreak())return e.abstract=!0,this.tsParseInterfaceDeclaration(e)}else this.unexpected(e.start)}tsIsDeclarationStart(){return y(this.type)}tsParseExpressionStatement(e,t){switch(t.name){case"declare":{const t=this.tsTryParseDeclare(e);if(t)return t.declare=!0,t;break}case"global":if(this.match(r.braceL)){this.enterScope(Ps);const n=e;return n.global=!0,n.id=t,n.body=this.tsParseModuleBlock(),super.exitScope(),this.finishNode(n,"TSModuleDeclaration")}break;default:return this.tsParseDeclaration(e,t.name,!1)}}tsParseModuleReference(){return this.tsIsExternalModuleReference()?this.tsParseExternalModuleReference():this.tsParseEntityName(!1)}tsIsExportDefaultSpecifier(){const{type:e}=this,t=this.isAsyncFunction(),n=this.isLet();if(v(e)){if(t&&!this.containsEsc||n)return!1;if((e===u.type||e===u.interface)&&!this.containsEsc){const e=this.lookahead();if(v(e.type)&&!this.isContextualWithState("from",e)||e.type===r.braceL)return!1}}else if(!this.match(r._default))return!1;const s=this.nextTokenStart(),a=this.isUnparsedContextual(s,"from");if(44===this.input.charCodeAt(s)||v(this.type)&&a)return!0;if(this.match(r._default)&&a){const e=this.input.charCodeAt(this.nextTokenStartSince(s+4));return 34===e||39===e}return!1}tsInAmbientContext(e){const t=this.isAmbientContext;this.isAmbientContext=!0;try{return e()}finally{this.isAmbientContext=t}}tsCheckLineTerminator(e){return e?!this.hasFollowingLineBreak()&&(this.next(),!0):!this.isLineTerminator()}tsParseModuleOrNamespaceDeclaration(e,t=!1){if(e.id=this.parseIdent(),t||this.checkLValSimple(e.id,Ns.BIND_TS_NAMESPACE),this.eat(r.dot)){const t=this.startNode();this.tsParseModuleOrNamespaceDeclaration(t,!0),e.body=t}else this.enterScope(Ps),e.body=this.tsParseModuleBlock(),super.exitScope();return this.finishNode(e,"TSModuleDeclaration")}checkLValSimple(e,t=Ns.BIND_NONE,n){return"TSNonNullExpression"!==e.type&&"TSAsExpression"!==e.type||(e=e.expression),super.checkLValSimple(e,t,n)}tsParseTypeAliasDeclaration(e){return e.id=this.parseIdent(),this.checkLValSimple(e.id,Ns.BIND_TS_TYPE),e.typeAnnotation=this.tsInType((()=>{if(e.typeParameters=this.tsTryParseTypeParameters(this.tsParseInOutModifiers.bind(this)),this.expect(r.eq),this.ts_isContextual(u.interface)&&this.lookahead().type!==r.dot){const e=this.startNode();return this.next(),this.finishNode(e,"TSIntrinsicKeyword")}return this.tsParseType()})),this.semicolon(),this.finishNode(e,"TSTypeAliasDeclaration")}tsParseDeclaration(e,t,n){switch(t){case"abstract":if(this.tsCheckLineTerminator(n)&&(this.match(r._class)||v(this.type)))return this.tsParseAbstractDeclaration(e);break;case"module":if(this.tsCheckLineTerminator(n)){if(this.match(r.string))return this.tsParseAmbientExternalModuleDeclaration(e);if(v(this.type))return this.tsParseModuleOrNamespaceDeclaration(e)}break;case"namespace":if(this.tsCheckLineTerminator(n)&&v(this.type))return this.tsParseModuleOrNamespaceDeclaration(e);break;case"type":if(this.tsCheckLineTerminator(n)&&v(this.type))return this.tsParseTypeAliasDeclaration(e)}}tsTryParseExportDeclaration(){return this.tsParseDeclaration(this.startNode(),this.value,!0)}tsParseImportEqualsDeclaration(e,t){e.isExport=t||!1,e.id=this.parseIdent(),this.checkLValSimple(e.id,Ns.BIND_LEXICAL),super.expect(r.eq);const n=this.tsParseModuleReference();return"type"===e.importKind&&"TSExternalModuleReference"!==n.type&&this.raise(n.start,Rs.ImportAliasHasImportType),e.moduleReference=n,super.semicolon(),this.finishNode(e,"TSImportEqualsDeclaration")}isExportDefaultSpecifier(){if(this.tsIsDeclarationStart())return!1;const{type:e}=this;if(v(e)){if(this.isContextual("async")||this.isContextual("let"))return!1;if((e===u.type||e===u.interface)&&!this.containsEsc){const e=this.lookahead();if(v(e.type)&&!this.isContextualWithState("from",e)||e.type===r.braceL)return!1}}else if(!this.match(r._default))return!1;const t=this.nextTokenStart(),n=this.isUnparsedContextual(t,"from");if(44===this.input.charCodeAt(t)||v(this.type)&&n)return!0;if(this.match(r._default)&&n){const e=this.input.charCodeAt(this.nextTokenStartSince(t+4));return 34===e||39===e}return!1}parseTemplate({isTagged:e=!1}={}){let t=this.startNode();this.next(),t.expressions=[];let n=this.parseTemplateElement({isTagged:e});for(t.quasis=[n];!n.tail;)this.type===r.eof&&this.raise(this.pos,"Unterminated template literal"),this.expect(r.dollarBraceL),t.expressions.push(this.inType?this.tsParseType():this.parseExpression()),this.expect(r.braceR),t.quasis.push(n=this.parseTemplateElement({isTagged:e}));return this.next(),this.finishNode(t,"TemplateLiteral")}parseFunction(e,t,n,s,a){this.initFunction(e),(this.ecmaVersion>=9||this.ecmaVersion>=6&&!s)&&(this.type===r.star&&2&t&&this.unexpected(),e.generator=this.eat(r.star)),this.ecmaVersion>=8&&(e.async=!!s),1&t&&(e.id=4&t&&this.type!==r.name?null:this.parseIdent());let i=this.yieldPos,o=this.awaitPos,l=this.awaitIdentPos;const c=this.maybeInArrowParameters;this.maybeInArrowParameters=!1,this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(Ds(e.async,e.generator)),1&t||(e.id=this.type===r.name?this.parseIdent():null),this.parseFunctionParams(e);const p=1&t;return this.parseFunctionBody(e,n,!1,a,{isFunctionDeclaration:p}),this.yieldPos=i,this.awaitPos=o,this.awaitIdentPos=l,1&t&&e.id&&!(2&t)&&(e.body?this.checkLValSimple(e.id,this.strict||e.generator||e.async?this.treatFunctionsAsVar?Ns.BIND_VAR:Ns.BIND_LEXICAL:Ns.BIND_FUNCTION):this.checkLValSimple(e.id,Ns.BIND_NONE)),this.maybeInArrowParameters=c,this.finishNode(e,p?"FunctionDeclaration":"FunctionExpression")}parseFunctionBody(e,t=!1,n=!1,s=!1,a){this.match(r.colon)&&(e.returnType=this.tsParseTypeOrTypePredicateAnnotation(r.colon));const i=a?.isFunctionDeclaration?"TSDeclareFunction":a?.isClassMethod?"TSDeclareMethod":void 0;return i&&!this.match(r.braceL)&&this.isLineTerminator()?this.finishNode(e,i):"TSDeclareFunction"===i&&this.isAmbientContext&&(this.raise(e.start,Rs.DeclareFunctionHasImplementation),e.declare)?(super.parseFunctionBody(e,t,n,!1),this.finishNode(e,i)):(super.parseFunctionBody(e,t,n,s),e)}parseNew(){this.containsEsc&&this.raiseRecoverable(this.start,"Escape sequence in keyword new");let e=this.startNode(),t=this.parseIdent(!0);if(this.ecmaVersion>=6&&this.eat(r.dot)){e.meta=t;let n=this.containsEsc;return e.property=this.parseIdent(!0),"target"!==e.property.name&&this.raiseRecoverable(e.property.start,"The only valid meta property for new is 'new.target'"),n&&this.raiseRecoverable(e.start,"'new.target' must not contain escaped characters"),this.allowNewDotTarget||this.raiseRecoverable(e.start,"'new.target' can only be used in functions and class static block"),this.finishNode(e,"MetaProperty")}let n=this.start,s=this.startLoc,a=this.type===r._import;e.callee=this.parseSubscripts(this.parseExprAtom(),n,s,!0,!1),a&&"ImportExpression"===e.callee.type&&this.raise(n,"Cannot use new with import()");const{callee:i}=e;return"TSInstantiationExpression"!==i.type||i.extra?.parenthesized||(e.typeArguments=i.typeArguments,e.callee=i.expression),this.eat(r.parenL)?e.arguments=this.parseExprList(r.parenR,this.ecmaVersion>=8,!1):e.arguments=[],this.finishNode(e,"NewExpression")}parseExprOp(e,t,n,s,a){if(r._in.binop>s&&!this.hasPrecedingLineBreak()){let r;if(this.isContextual("as")&&(r="TSAsExpression"),this.isContextual("satisfies")&&(r="TSSatisfiesExpression"),r){const i=this.startNodeAt(t,n);i.expression=e;const o=this.tsTryNextParseConstantContext();return i.typeAnnotation=o||this.tsNextThenParseType(),this.finishNode(i,r),this.reScan_lt_gt(),this.parseExprOp(i,t,n,s,a)}}return super.parseExprOp(e,t,n,s,a)}parseImportSpecifiers(){let e=[],t=!0;if(s.tokenIsIdentifier(this.type)&&(e.push(this.parseImportDefaultSpecifier()),!this.eat(r.comma)))return e;if(this.type===r.star)return e.push(this.parseImportNamespaceSpecifier()),e;for(this.expect(r.braceL);!this.eat(r.braceR);){if(t)t=!1;else if(this.expect(r.comma),this.afterTrailingComma(r.braceR))break;e.push(this.parseImportSpecifier())}return e}parseImport(e){let t=this.lookahead();if(e.importKind="value",this.importOrExportOuterKind="value",v(t.type)||this.match(r.star)||this.match(r.braceL)){let n=this.lookahead(2);if(n.type!==r.comma&&!this.isContextualWithState("from",n)&&n.type!==r.eq&&this.ts_eatContextualWithState("type",1,t)&&(this.importOrExportOuterKind="type",e.importKind="type",t=this.lookahead(),n=this.lookahead(2)),v(t.type)&&n.type===r.eq){this.next();const t=this.tsParseImportEqualsDeclaration(e);return this.importOrExportOuterKind="value",t}}return this.next(),this.type===r.string?(e.specifiers=[],e.source=this.parseExprAtom()):(e.specifiers=this.parseImportSpecifiers(),this.expectContextual("from"),e.source=this.type===r.string?this.parseExprAtom():this.unexpected()),this.parseMaybeImportAttributes(e),this.semicolon(),this.finishNode(e,"ImportDeclaration"),this.importOrExportOuterKind="value","type"===e.importKind&&e.specifiers.length>1&&"ImportDefaultSpecifier"===e.specifiers[0].type&&this.raise(e.start,Rs.TypeImportCannotSpecifyDefaultAndNamed),e}parseExportDefaultDeclaration(){if(this.isAbstractClass()){const e=this.startNode();return this.next(),e.abstract=!0,this.parseClass(e,!0)}if(this.match(u.interface)){const e=this.tsParseInterfaceDeclaration(this.startNode());if(e)return e}return super.parseExportDefaultDeclaration()}parseExportAllDeclaration(e,t){return this.ecmaVersion>=11&&(this.eatContextual("as")?(e.exported=this.parseModuleExportName(),this.checkExport(t,e.exported,this.lastTokStart)):e.exported=null),this.expectContextual("from"),this.type!==r.string&&this.unexpected(),e.source=this.parseExprAtom(),this.parseMaybeImportAttributes(e),this.semicolon(),this.finishNode(e,"ExportAllDeclaration")}parseDynamicImport(e){if(this.next(),e.source=this.parseMaybeAssign(),this.eat(r.comma)){const t=this.parseExpression();e.arguments=[t]}if(!this.eat(r.parenR)){const e=this.start;this.eat(r.comma)&&this.eat(r.parenR)?this.raiseRecoverable(e,"Trailing comma is not allowed in import()"):this.unexpected(e)}return this.finishNode(e,"ImportExpression")}parseExport(e,t){let n=this.lookahead();if(this.ts_eatWithState(r._import,2,n)){this.ts_isContextual(u.type)&&61!==this.lookaheadCharCode()?(e.importKind="type",this.importOrExportOuterKind="type",this.next()):(e.importKind="value",this.importOrExportOuterKind="value");const t=this.tsParseImportEqualsDeclaration(e,!0);return this.importOrExportOuterKind=void 0,t}if(this.ts_eatWithState(r.eq,2,n)){const t=e;return t.expression=this.parseExpression(),this.semicolon(),this.importOrExportOuterKind=void 0,this.finishNode(t,"TSExportAssignment")}if(this.ts_eatContextualWithState("as",2,n)){const t=e;return this.expectContextual("namespace"),t.id=this.parseIdent(),this.semicolon(),this.importOrExportOuterKind=void 0,this.finishNode(t,"TSNamespaceExportDeclaration")}if(this.ts_isContextualWithState(n,u.type)&&this.lookahead(2).type===r.braceL?(this.next(),this.importOrExportOuterKind="type",e.exportKind="type"):(this.importOrExportOuterKind="value",e.exportKind="value"),this.next(),this.eat(r.star))return this.parseExportAllDeclaration(e,t);if(this.eat(r._default))return this.checkExport(t,"default",this.lastTokStart),e.declaration=this.parseExportDefaultDeclaration(),this.finishNode(e,"ExportDefaultDeclaration");if(this.shouldParseExportStatement())e.declaration=this.parseExportDeclaration(e),"VariableDeclaration"===e.declaration.type?this.checkVariableExport(t,e.declaration.declarations):this.checkExport(t,e.declaration.id,e.declaration.id.start),e.specifiers=[],e.source=null;else{if(e.declaration=null,e.specifiers=this.parseExportSpecifiers(t),this.eatContextual("from"))this.type!==r.string&&this.unexpected(),e.source=this.parseExprAtom(),this.parseMaybeImportAttributes(e);else{for(let t of e.specifiers)this.checkUnreserved(t.local),this.checkLocalExport(t.local),"Literal"===t.local.type&&this.raise(t.local.start,"A string literal cannot be used as an exported binding without `from`.");e.source=null}this.semicolon()}return this.finishNode(e,"ExportNamedDeclaration")}checkExport(e,t,n){e&&("string"!=typeof t&&(t="Identifier"===t.type?t.name:t.value),e[t]=!0)}parseMaybeDefault(e,t,n){const s=super.parseMaybeDefault(e,t,n);return"AssignmentPattern"===s.type&&s.typeAnnotation&&s.right.start=8&&!a&&"async"===i.name&&!this.canInsertSemicolon()&&this.eat(r._function))return this.overrideContext(c.f_expr),this.parseFunction(this.startNodeAt(n,s),0,!1,!0,t);if(e&&!this.canInsertSemicolon()){if(this.eat(r.arrow))return this.parseArrowExpression(this.startNodeAt(n,s),[i],!1,t);if(this.ecmaVersion>=8&&"async"===i.name&&this.type===r.name&&!a&&(!this.potentialArrowInForAwait||"of"!==this.value||this.containsEsc))return i=this.parseIdent(!1),!this.canInsertSemicolon()&&this.eat(r.arrow)||this.unexpected(),this.parseArrowExpression(this.startNodeAt(n,s),[i],!0,t)}return i}return super.parseExprAtom(e,t,n)}parseExprAtomDefault(){if(v(this.type)){const e=this.potentialArrowAt===this.start,t=this.containsEsc,n=this.parseIdent();if(!t&&"async"===n.name&&!this.canInsertSemicolon()){const{type:e}=this;if(e===r._function)return this.next(),this.parseFunction(this.startNodeAtNode(n),void 0,!0,!0);if(v(e)){if(61===this.lookaheadCharCode()){const e=this.parseIdent(!1);return!this.canInsertSemicolon()&&this.eat(r.arrow)||this.unexpected(),this.parseArrowExpression(this.startNodeAtNode(n),[e],!0)}return n}}return e&&this.match(r.arrow)&&!this.canInsertSemicolon()?(this.next(),this.parseArrowExpression(this.startNodeAtNode(n),[n],!1)):n}this.unexpected()}parseIdentNode(){let e=this.startNode();return g(this.type)&&("class"!==this.type.keyword&&"function"!==this.type.keyword||this.lastTokEnd===this.lastTokStart+1&&46===this.input.charCodeAt(this.lastTokStart))?(e.name=this.value,e):super.parseIdentNode()}parseVarStatement(e,t,n=!1){const{isAmbientContext:s}=this;this.next(),super.parseVar(e,!1,t,n||s),this.semicolon();const r=this.finishNode(e,"VariableDeclaration");if(!s)return r;for(const{id:e,init:n}of r.declarations)n&&("const"!==t||e.typeAnnotation?this.raise(n.start,Rs.InitializerNotAllowedInAmbientContext):"StringLiteral"!==n.type&&"BooleanLiteral"!==n.type&&"NumericLiteral"!==n.type&&"BigIntLiteral"!==n.type&&("TemplateLiteral"!==n.type||n.expressions.length>0)&&!js(n)&&this.raise(n.start,Rs.ConstInitiailizerMustBeStringOrNumericLiteralOrLiteralEnumReference));return r}parseStatement(e,t,n){if(this.match(u.at)&&this.parseDecorators(!0),this.match(r._const)&&this.isLookaheadContextual("enum")){const e=this.startNode();return this.expect(r._const),this.tsParseEnumDeclaration(e,{const:!0})}if(this.ts_isContextual(u.enum))return this.tsParseEnumDeclaration(this.startNode());if(this.ts_isContextual(u.interface)){const e=this.tsParseInterfaceDeclaration(this.startNode());if(e)return e}return super.parseStatement(e,t,n)}parseAccessModifier(){return this.tsParseModifier(["public","protected","private"])}parsePostMemberNameModifiers(e){this.eat(r.question)&&(e.optional=!0),e.readonly&&this.match(r.parenL)&&this.raise(e.start,Rs.ClassMethodHasReadonly),e.declare&&this.match(r.parenL)&&this.raise(e.start,Rs.ClassMethodHasDeclare)}parseExpressionStatement(e,t){return("Identifier"===t.type?this.tsParseExpressionStatement(e,t):void 0)||super.parseExpressionStatement(e,t)}shouldParseExportStatement(){return!!this.tsIsDeclarationStart()||(!!this.match(u.at)||super.shouldParseExportStatement())}parseConditional(e,t,n,s,a){if(this.eat(r.question)){let a=this.startNodeAt(t,n);return a.test=e,a.consequent=this.parseMaybeAssign(),this.expect(r.colon),a.alternate=this.parseMaybeAssign(s),this.finishNode(a,"ConditionalExpression")}return e}parseMaybeConditional(e,t){let n=this.start,s=this.startLoc,a=this.parseExprOps(e,t);if(this.checkExpressionErrors(t))return a;if(!this.maybeInArrowParameters||!this.match(r.question))return this.parseConditional(a,n,s,e,t);const i=this.tryParse((()=>this.parseConditional(a,n,s,e,t)));return i.node?(i.error&&this.setLookaheadState(i.failState),i.node):(i.error&&this.setOptionalParametersError(t,i.error),a)}parseParenItem(e){const t=this.start,n=this.startLoc;if(e=super.parseParenItem(e),this.eat(r.question)&&(e.optional=!0,this.resetEndLocation(e)),this.match(r.colon)){const s=this.startNodeAt(t,n);return s.expression=e,s.typeAnnotation=this.tsParseTypeAnnotation(),this.finishNode(s,"TSTypeCastExpression")}return e}parseExportDeclaration(e){if(!this.isAmbientContext&&this.ts_isContextual(u.declare))return this.tsInAmbientContext((()=>this.parseExportDeclaration(e)));const t=this.start,n=this.startLoc,s=this.eatContextual("declare");!s||!this.ts_isContextual(u.declare)&&this.shouldParseExportStatement()||this.raise(this.start,Rs.ExpectedAmbientAfterExportDeclare);const r=v(this.type)&&this.tsTryParseExportDeclaration()||this.parseStatement(null);return r?(("TSInterfaceDeclaration"===r.type||"TSTypeAliasDeclaration"===r.type||s)&&(e.exportKind="type"),s&&(this.resetStartLocation(r,t,n),r.declare=!0),r):null}parseClassId(e,t){if(!t&&this.isContextual("implements"))return;super.parseClassId(e,t);const n=this.tsTryParseTypeParameters(this.tsParseInOutModifiers.bind(this));n&&(e.typeParameters=n)}parseClassPropertyAnnotation(e){e.optional||("!"===this.value&&this.eat(r.prefix)?e.definite=!0:this.eat(r.question)&&(e.optional=!0));const t=this.tsTryParseTypeAnnotation();t&&(e.typeAnnotation=t)}parseClassField(e){if("PrivateIdentifier"===e.key.type)e.abstract&&this.raise(e.start,Rs.PrivateElementHasAbstract),e.accessibility&&this.raise(e.start,Rs.PrivateElementHasAccessibility({modifier:e.accessibility})),this.parseClassPropertyAnnotation(e);else if(this.parseClassPropertyAnnotation(e),this.isAmbientContext&&(!e.readonly||e.typeAnnotation)&&this.match(r.eq)&&this.raise(this.start,Rs.DeclareClassFieldHasInitializer),e.abstract&&this.match(r.eq)){const{key:t}=e;this.raise(this.start,Rs.AbstractPropertyHasInitializer({propertyName:"Identifier"!==t.type||e.computed?`[${this.input.slice(t.start,t.end)}]`:t.name}))}return super.parseClassField(e)}parseClassMethod(e,t,n,s){const r="constructor"===e.kind,a="PrivateIdentifier"===e.key.type,i=this.tsTryParseTypeParameters(this.tsParseConstModifier);a?(i&&(e.typeParameters=i),e.accessibility&&this.raise(e.start,Rs.PrivateMethodsHasAccessibility({modifier:e.accessibility}))):i&&r&&this.raise(i.start,Rs.ConstructorHasTypeParameters);const{declare:o=!1,kind:l}=e;!o||"get"!==l&&"set"!==l||this.raise(e.start,Rs.DeclareAccessor({kind:l})),i&&(e.typeParameters=i);const c=e.key;"constructor"===e.kind?(t&&this.raise(c.start,"Constructor can't be a generator"),n&&this.raise(c.start,"Constructor can't be an async method")):e.static&&$s(e,"prototype")&&this.raise(c.start,"Classes may not have a static property named prototype");const p=e.value=this.parseMethod(t,n,s,!0,e);return"get"===e.kind&&0!==p.params.length&&this.raiseRecoverable(p.start,"getter should have no params"),"set"===e.kind&&1!==p.params.length&&this.raiseRecoverable(p.start,"setter should have exactly one param"),"set"===e.kind&&"RestElement"===p.params[0].type&&this.raiseRecoverable(p.params[0].start,"Setter cannot use rest params"),this.finishNode(e,"MethodDefinition")}isClassMethod(){return this.match(r.relational)}parseClassElement(e){if(this.eat(r.semi))return null;let t=this.startNode(),n="",s=!1,a=!1,i="method",o=!1;const l=["declare","private","public","protected","accessor","override","abstract","readonly","static"],c=this.tsParseModifiers({modified:t,allowedModifiers:l,disallowedModifiers:["in","out"],stopOnStartOfClassStaticBlock:!0,errorTemplate:Rs.InvalidModifierOnTypeParameterPositions});o=Boolean(c.static);const p=()=>{if(!this.tsIsStartOfStaticBlocks()){const l=this.tsTryParseIndexSignature(t);if(l)return t.abstract&&this.raise(t.start,Rs.IndexSignatureHasAbstract),t.accessibility&&this.raise(t.start,Rs.IndexSignatureHasAccessibility({modifier:t.accessibility})),t.declare&&this.raise(t.start,Rs.IndexSignatureHasDeclare),t.override&&this.raise(t.start,Rs.IndexSignatureHasOverride),l;if(!this.inAbstractClass&&t.abstract&&this.raise(t.start,Rs.NonAbstractClassHasAbstractMethod),t.override&&(e||this.raise(t.start,Rs.OverrideNotInSubClass)),t.static=o,o&&(this.isClassElementNameStart()||this.type===r.star||(n="static")),!n&&this.ecmaVersion>=8&&this.eatContextual("async")&&(!this.isClassElementNameStart()&&this.type!==r.star||this.canInsertSemicolon()?n="async":a=!0),!n&&(this.ecmaVersion>=9||!a)&&this.eat(r.star)&&(s=!0),!n&&!a&&!s){const e=this.value;(this.eatContextual("get")||this.eatContextual("set"))&&(this.isClassElementNameStart()?i=e:n=e)}if(n?(t.computed=!1,t.key=this.startNodeAt(this.lastTokStart,this.lastTokStartLoc),t.key.name=n,this.finishNode(t.key,"Identifier")):this.parseClassElementName(t),this.parsePostMemberNameModifiers(t),this.isClassMethod()||this.ecmaVersion<13||this.type===r.parenL||"method"!==i||s||a){const n=!t.static&&$s(t,"constructor"),r=n&&e;n&&"method"!==i&&this.raise(t.key.start,"Constructor can't have get/set modifier"),t.kind=n?"constructor":i,this.parseClassMethod(t,s,a,r)}else this.parseClassField(t);return t}if(this.next(),this.next(),this.tsHasSomeModifiers(t,l)&&this.raise(this.start,Rs.StaticBlockCannotHaveModifier),this.ecmaVersion>=13)return super.parseClassStaticBlock(t),t};return t.declare?this.tsInAmbientContext(p):p(),t}isClassElementNameStart(){return!!this.tsIsIdentifier()||super.isClassElementNameStart()}parseClassSuper(e){super.parseClassSuper(e),e.superClass&&(this.tsMatchLeftRelational()||this.match(r.bitShift))&&(e.superTypeParameters=this.tsParseTypeArgumentsInExpression()),this.eatContextual("implements")&&(e.implements=this.tsParseHeritageClause("implements"))}parseFunctionParams(e){const t=this.tsTryParseTypeParameters(this.tsParseConstModifier);t&&(e.typeParameters=t),super.parseFunctionParams(e)}parseVarId(e,t){super.parseVarId(e,t),"Identifier"===e.id.type&&!this.hasPrecedingLineBreak()&&"!"===this.value&&this.eat(r.prefix)&&(e.definite=!0);const n=this.tsTryParseTypeAnnotation();n&&(e.id.typeAnnotation=n,this.resetEndLocation(e.id))}parseArrowExpression(e,t,n,s){this.match(r.colon)&&(e.returnType=this.tsParseTypeAnnotation());let a=this.yieldPos,i=this.awaitPos,o=this.awaitIdentPos;this.enterScope(Ds(n,!1)|Ns.SCOPE_ARROW),this.initFunction(e);const l=this.maybeInArrowParameters;return this.ecmaVersion>=8&&(e.async=!!n),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.maybeInArrowParameters=!0,e.params=this.toAssignableList(t,!0),this.maybeInArrowParameters=!1,this.parseFunctionBody(e,!0,!1,s),this.yieldPos=a,this.awaitPos=i,this.awaitIdentPos=o,this.maybeInArrowParameters=l,this.finishNode(e,"ArrowFunctionExpression")}parseMaybeAssignOrigin(e,t,n){if(this.isContextual("yield")){if(this.inGenerator)return this.parseYield(e);this.exprAllowed=!1}let s=!1,a=-1,i=-1,o=-1;t?(a=t.parenthesizedAssign,i=t.trailingComma,o=t.doubleProto,t.parenthesizedAssign=t.trailingComma=-1):(t=new Ts,s=!0);let l=this.start,c=this.startLoc;(this.type===r.parenL||v(this.type))&&(this.potentialArrowAt=this.start,this.potentialArrowInForAwait="await"===e);let p=this.parseMaybeConditional(e,t);if(n&&(p=n.call(this,p,l,c)),this.type.isAssign){let n=this.startNodeAt(l,c);return n.operator=this.value,this.type===r.eq&&(p=this.toAssignable(p,!0,t)),s||(t.parenthesizedAssign=t.trailingComma=t.doubleProto=-1),t.shorthandAssign>=p.start&&(t.shorthandAssign=-1),this.maybeInArrowParameters||(this.type===r.eq?this.checkLValPattern(p):this.checkLValSimple(p)),n.left=p,this.next(),n.right=this.parseMaybeAssign(e),o>-1&&(t.doubleProto=o),this.finishNode(n,"AssignmentExpression")}return s&&this.checkExpressionErrors(t,!0),a>-1&&(t.parenthesizedAssign=a),i>-1&&(t.trailingComma=i),p}parseMaybeAssign(e,t,n){let s,r,a;if(!this.tsMatchLeftRelational())return this.parseMaybeAssignOrigin(e,t,n);s&&!this.compareLookaheadState(s,this.getCurLookaheadState())||(s=this.cloneCurLookaheadState());const i=this.tryParse((s=>{a=this.tsParseTypeParameters(this.tsParseConstModifier);const r=this.parseMaybeAssignOrigin(e,t,n);return("ArrowFunctionExpression"!==r.type||r.extra?.parenthesized)&&s(),0!==a?.params.length&&this.resetStartLocationFromNode(r,a),r.typeParameters=a,r}),s);if(!i.error&&!i.aborted)return a&&this.reportReservedArrowTypeParam(a),i.node;if(qs(!0),r=this.tryParse((()=>this.parseMaybeAssignOrigin(e,t,n)),s),!r.error)return r.node;if(i.node)return this.setLookaheadState(i.failState),a&&this.reportReservedArrowTypeParam(a),i.node;if(r?.node)return this.setLookaheadState(r.failState),r.node;if(i.thrown)throw i.error;if(r?.thrown)throw r.error;throw i.error||r?.error}parseAssignableListItem(e){const t=[];for(;this.match(u.at);)t.push(this.parseDecorator());const n=this.start,s=this.startLoc;let r,a=!1,i=!1;if(void 0!==e){const t={};this.tsParseModifiers({modified:t,allowedModifiers:["public","private","protected","override","readonly"]}),r=t.accessibility,i=t.override,a=t.readonly,!1===e&&(r||a||i)&&this.raise(s.start,Rs.UnexpectedParameterModifier)}const o=this.parseMaybeDefault(n,s);this.parseBindingListItem(o);const l=this.parseMaybeDefault(o.start,o.loc,o);if(t.length&&(l.decorators=t),r||a||i){const e=this.startNodeAt(n,s);return r&&(e.accessibility=r),a&&(e.readonly=a),i&&(e.override=i),"Identifier"!==l.type&&"AssignmentPattern"!==l.type&&this.raise(e.start,Rs.UnsupportedParameterPropertyKind),e.parameter=l,this.finishNode(e,"TSParameterProperty")}return l}checkLValInnerPattern(e,t=Ns.BIND_NONE,n){if("TSParameterProperty"===e.type)this.checkLValInnerPattern(e.parameter,t,n);else super.checkLValInnerPattern(e,t,n)}parseBindingListItem(e){this.eat(r.question)&&("Identifier"===e.type||this.isAmbientContext||this.inType||this.raise(e.start,Rs.PatternIsOptional),e.optional=!0);const t=this.tsTryParseTypeAnnotation();return t&&(e.typeAnnotation=t),this.resetEndLocation(e),e}isAssignable(e,t){switch(e.type){case"TSTypeCastExpression":return this.isAssignable(e.expression,t);case"TSParameterProperty":case"Identifier":case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":case"RestElement":return!0;case"ObjectExpression":{const t=e.properties.length-1;return e.properties.every(((e,n)=>"ObjectMethod"!==e.type&&(n===t||"SpreadElement"!==e.type)&&this.isAssignable(e)))}case"Property":case"ObjectProperty":return this.isAssignable(e.value);case"SpreadElement":return this.isAssignable(e.argument);case"ArrayExpression":return e.elements.every((e=>null===e||this.isAssignable(e)));case"AssignmentExpression":return"="===e.operator;case"ParenthesizedExpression":return this.isAssignable(e.expression);case"MemberExpression":case"OptionalMemberExpression":return!t;default:return!1}}toAssignable(e,t=!1,n=new Ts){switch(e.type){case"ParenthesizedExpression":return this.toAssignableParenthesizedExpression(e,t,n);case"TSAsExpression":case"TSSatisfiesExpression":case"TSNonNullExpression":case"TSTypeAssertion":return t||this.raise(e.start,Rs.UnexpectedTypeCastInParameter),this.toAssignable(e.expression,t,n);case"MemberExpression":break;case"AssignmentExpression":return t||"TSTypeCastExpression"!==e.left.type||(e.left=this.typeCastToParameter(e.left)),super.toAssignable(e,t,n);case"TSTypeCastExpression":return this.typeCastToParameter(e);default:return super.toAssignable(e,t,n)}return e}toAssignableParenthesizedExpression(e,t,n){switch(e.expression.type){case"TSAsExpression":case"TSSatisfiesExpression":case"TSNonNullExpression":case"TSTypeAssertion":case"ParenthesizedExpression":return this.toAssignable(e.expression,t,n);default:return super.toAssignable(e,t,n)}}parseBindingAtom(){return this.type===r._this?this.parseIdent(!0):super.parseBindingAtom()}shouldParseArrow(e){let t;if(t=this.match(r.colon)?e.every((e=>this.isAssignable(e,!0))):!this.canInsertSemicolon(),t){if(this.match(r.colon)){const e=this.tryParse((e=>{const t=this.tsParseTypeOrTypePredicateAnnotation(r.colon);return!this.canInsertSemicolon()&&this.match(r.arrow)||e(),t}));if(e.aborted)return this.shouldParseArrowReturnType=void 0,!1;e.thrown||(e.error&&this.setLookaheadState(e.failState),this.shouldParseArrowReturnType=e.node)}return!!this.match(r.arrow)||(this.shouldParseArrowReturnType=void 0,!1)}return this.shouldParseArrowReturnType=void 0,t}parseParenArrowList(e,t,n,s){const r=this.startNodeAt(e,t);return r.returnType=this.shouldParseArrowReturnType,this.shouldParseArrowReturnType=void 0,this.parseArrowExpression(r,n,!1,s)}parseParenAndDistinguishExpression(e,t){let n,s=this.start,a=this.startLoc,i=this.ecmaVersion>=8;if(this.ecmaVersion>=6){const o=this.maybeInArrowParameters;this.maybeInArrowParameters=!0,this.next();let l,c=this.start,p=this.startLoc,u=[],d=!0,h=!1,m=new Ts,f=this.yieldPos,y=this.awaitPos;for(this.yieldPos=0,this.awaitPos=0;this.type!==r.parenR;){if(d?d=!1:this.expect(r.comma),i&&this.afterTrailingComma(r.parenR,!0)){h=!0;break}if(this.type===r.ellipsis){l=this.start,u.push(this.parseParenItem(this.parseRestBinding())),this.type===r.comma&&this.raise(this.start,"Comma is not permitted after the rest element");break}u.push(this.parseMaybeAssign(t,m,this.parseParenItem))}let v=this.lastTokEnd,g=this.lastTokEndLoc;if(this.expect(r.parenR),this.maybeInArrowParameters=o,e&&this.shouldParseArrow(u)&&this.eat(r.arrow))return this.checkPatternErrors(m,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=f,this.awaitPos=y,this.parseParenArrowList(s,a,u,t);u.length&&!h||this.unexpected(this.lastTokStart),l&&this.unexpected(l),this.checkExpressionErrors(m,!0),this.yieldPos=f||this.yieldPos,this.awaitPos=y||this.awaitPos,u.length>1?(n=this.startNodeAt(c,p),n.expressions=u,this.finishNodeAt(n,"SequenceExpression",v,g)):n=u[0]}else n=this.parseParenExpression();if(this.options.preserveParens){let e=this.startNodeAt(s,a);return e.expression=n,this.finishNode(e,"ParenthesizedExpression")}return n}parseTaggedTemplateExpression(e,t,n,s){const r=this.startNodeAt(t,n);return r.tag=e,r.quasi=this.parseTemplate({isTagged:!0}),s&&this.raise(t,"Tagged Template Literals are not allowed in optionalChain."),this.finishNode(r,"TaggedTemplateExpression")}shouldParseAsyncArrow(){if(!this.match(r.colon))return!this.canInsertSemicolon()&&this.eat(r.arrow);{const e=this.tryParse((e=>{const t=this.tsParseTypeOrTypePredicateAnnotation(r.colon);return!this.canInsertSemicolon()&&this.match(r.arrow)||e(),t}));if(e.aborted)return this.shouldParseAsyncArrowReturnType=void 0,!1;if(!e.thrown)return e.error&&this.setLookaheadState(e.failState),this.shouldParseAsyncArrowReturnType=e.node,!this.canInsertSemicolon()&&this.eat(r.arrow)}}parseSubscriptAsyncArrow(e,t,n,s){const r=this.startNodeAt(e,t);return r.returnType=this.shouldParseAsyncArrowReturnType,this.shouldParseAsyncArrowReturnType=void 0,this.parseArrowExpression(r,n,!0,s)}parseExprList(e,t,n,s){let a=[],i=!0;for(;!this.eat(e);){if(i)i=!1;else if(this.expect(r.comma),t&&this.afterTrailingComma(e))break;let o;n&&this.type===r.comma?o=null:this.type===r.ellipsis?(o=this.parseSpread(s),this.maybeInArrowParameters&&this.match(r.colon)&&(o.typeAnnotation=this.tsParseTypeAnnotation()),s&&this.type===r.comma&&s.trailingComma<0&&(s.trailingComma=this.start)):o=this.parseMaybeAssign(!1,s,this.parseParenItem),a.push(o)}return a}parseSubscript(e,t,n,s,a,i,o){let l=i;if(!this.hasPrecedingLineBreak()&&"!"===this.value&&this.match(r.prefix)){this.exprAllowed=!1,this.next();const s=this.startNodeAt(t,n);return s.expression=e,e=this.finishNode(s,"TSNonNullExpression")}let c=!1;if(this.match(r.questionDot)&&60===this.lookaheadCharCode()){if(s)return e;e.optional=!0,l=c=!0,this.next()}if(this.tsMatchLeftRelational()||this.match(r.bitShift)){let a;const i=this.tsTryParseAndCatch((()=>{if(!s&&this.atPossibleAsyncArrow(e)){const s=this.tsTryParseGenericAsyncArrowFunction(t,n,o);if(s)return e=s}const i=this.tsParseTypeArgumentsInExpression();if(!i)return e;if(c&&!this.match(r.parenL))return a=this.curPosition(),e;if(f(this.type)||this.type===r.backQuote){const s=this.parseTaggedTemplateExpression(e,t,n,l);return s.typeArguments=i,s}if(!s&&this.eat(r.parenL)){let s=new Ts;const a=this.startNodeAt(t,n);return a.callee=e,a.arguments=this.parseExprList(r.parenR,this.ecmaVersion>=8,!1,s),this.tsCheckForInvalidTypeCasts(a.arguments),a.typeArguments=i,l&&(a.optional=c),this.checkExpressionErrors(s,!0),e=this.finishNode(a,"CallExpression")}const p=this.type;if(this.tsMatchRightRelational()||p===r.bitShift||p!==r.parenL&&Boolean(p.startsExpr)&&!this.hasPrecedingLineBreak())return;const u=this.startNodeAt(t,n);return u.expression=e,u.typeArguments=i,this.finishNode(u,"TSInstantiationExpression")}));if(a&&this.unexpected(a),i)return"TSInstantiationExpression"===i.type&&(this.match(r.dot)||this.match(r.questionDot)&&40!==this.lookaheadCharCode())&&this.raise(this.start,Rs.InvalidPropertyAccessAfterInstantiationExpression),e=i}let p=this.ecmaVersion>=11,u=p&&this.eat(r.questionDot);s&&u&&this.raise(this.lastTokStart,"Optional chaining cannot appear in the callee of new expressions");let d=this.eat(r.bracketL);if(d||u&&this.type!==r.parenL&&this.type!==r.backQuote||this.eat(r.dot)){let s=this.startNodeAt(t,n);s.object=e,d?(s.property=this.parseExpression(),this.expect(r.bracketR)):this.type===r.privateId&&"Super"!==e.type?s.property=this.parsePrivateIdent():s.property=this.parseIdent("never"!==this.options.allowReserved),s.computed=!!d,p&&(s.optional=u),e=this.finishNode(s,"MemberExpression")}else if(!s&&this.eat(r.parenL)){const s=this.maybeInArrowParameters;this.maybeInArrowParameters=!0;let i=new Ts,l=this.yieldPos,c=this.awaitPos,d=this.awaitIdentPos;this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0;let h=this.parseExprList(r.parenR,this.ecmaVersion>=8,!1,i);if(a&&!u&&this.shouldParseAsyncArrow())this.checkPatternErrors(i,!1),this.checkYieldAwaitInDefaultParams(),this.awaitIdentPos>0&&this.raise(this.awaitIdentPos,"Cannot use 'await' as identifier inside an async function"),this.yieldPos=l,this.awaitPos=c,this.awaitIdentPos=d,e=this.parseSubscriptAsyncArrow(t,n,h,o);else{this.checkExpressionErrors(i,!0),this.yieldPos=l||this.yieldPos,this.awaitPos=c||this.awaitPos,this.awaitIdentPos=d||this.awaitIdentPos;let s=this.startNodeAt(t,n);s.callee=e,s.arguments=h,p&&(s.optional=u),e=this.finishNode(s,"CallExpression")}this.maybeInArrowParameters=s}else if(this.type===r.backQuote){(u||l)&&this.raise(this.start,"Optional chaining cannot appear in the tag of tagged template expressions");let s=this.startNodeAt(t,n);s.tag=e,s.quasi=this.parseTemplate({isTagged:!0}),e=this.finishNode(s,"TaggedTemplateExpression")}return e}parseGetterSetter(e){e.kind=e.key.name,this.parsePropertyName(e),e.value=this.parseMethod(!1);let t="get"===e.kind?0:1;const n=e.value.params[0];if(t=n&&this.isThisParam(n)?t+1:t,e.value.params.length!==t){let t=e.value.start;"get"===e.kind?this.raiseRecoverable(t,"getter should have no params"):this.raiseRecoverable(t,"setter should have exactly one param")}else"set"===e.kind&&"RestElement"===e.value.params[0].type&&this.raiseRecoverable(e.value.params[0].start,"Setter cannot use rest params")}parseProperty(e,t){if(!e){let n=[];if(this.match(u.at))for(;this.match(u.at);)n.push(this.parseDecorator());const s=super.parseProperty(e,t);return"SpreadElement"===s.type&&n.length&&this.raise(s.start,Is.SpreadElementDecorator),n.length&&(s.decorators=n,n=[]),s}return super.parseProperty(e,t)}parseCatchClauseParam(){const e=this.parseBindingAtom();let t="Identifier"===e.type;this.enterScope(t?Ns.SCOPE_SIMPLE_CATCH:0),this.checkLValPattern(e,t?Ns.BIND_SIMPLE_CATCH:Ns.BIND_LEXICAL);const n=this.tsTryParseTypeAnnotation();return n&&(e.typeAnnotation=n,this.resetEndLocation(e)),this.expect(r.parenR),e}parseClass(e,t){const n=this.inAbstractClass;this.inAbstractClass=!!e.abstract;try{this.next(),this.takeDecorators(e);const n=this.strict;this.strict=!0,this.parseClassId(e,t),this.parseClassSuper(e);const s=this.enterClassBody(),a=this.startNode();let i=!1;a.body=[];let o=[];for(this.expect(r.braceL);this.type!==r.braceR;){if(this.match(u.at)){o.push(this.parseDecorator());continue}const t=this.parseClassElement(null!==e.superClass);o.length&&(t.decorators=o,this.resetStartLocationFromNode(t,o[0]),o=[]),t&&(a.body.push(t),"MethodDefinition"===t.type&&"constructor"===t.kind&&"FunctionExpression"===t.value.type?(i&&this.raiseRecoverable(t.start,"Duplicate constructor in the same class"),i=!0,t.decorators&&t.decorators.length>0&&this.raise(t.start,Is.DecoratorConstructor)):t.key&&"PrivateIdentifier"===t.key.type&&As(s,t)&&this.raiseRecoverable(t.key.start,`Identifier '#${t.key.name}' has already been declared`))}return this.strict=n,this.next(),o.length&&this.raise(this.start,Is.TrailingDecorator),e.body=this.finishNode(a,"ClassBody"),this.exitClassBody(),this.finishNode(e,t?"ClassDeclaration":"ClassExpression")}finally{this.inAbstractClass=n}}parseClassFunctionParams(){const e=this.tsTryParseTypeParameters();let t=this.parseBindingList(r.parenR,!1,this.ecmaVersion>=8,!0);return e&&(t.typeParameters=e),t}parseMethod(e,t,n,s,a){let i=this.startNode(),o=this.yieldPos,l=this.awaitPos,c=this.awaitIdentPos;if(this.initFunction(i),this.ecmaVersion>=6&&(i.generator=e),this.ecmaVersion>=8&&(i.async=!!t),this.yieldPos=0,this.awaitPos=0,this.awaitIdentPos=0,this.enterScope(Ds(t,i.generator)|Ns.SCOPE_SUPER|(n?Ns.SCOPE_DIRECT_SUPER:0)),this.expect(r.parenL),i.params=this.parseClassFunctionParams(),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(i,!1,!0,!1,{isClassMethod:s}),this.yieldPos=o,this.awaitPos=l,this.awaitIdentPos=c,a&&a.abstract){if(!!i.body){const{key:e}=a;this.raise(a.start,Rs.AbstractMethodHasImplementation({methodName:"Identifier"!==e.type||a.computed?`[${this.input.slice(e.start,e.end)}]`:e.name}))}}return this.finishNode(i,"FunctionExpression")}static parse(e,n){if(!1===n.locations)throw new Error("You have to enable options.locations while using acorn-typescript");n.locations=!0;const s=new this(n,e);return t&&(s.isAmbientContext=!0),s.parse()}static parseExpressionAt(e,n,s){if(!1===s.locations)throw new Error("You have to enable options.locations while using acorn-typescript");s.locations=!0;const r=new this(s,e,n);return t&&(r.isAmbientContext=!0),r.nextToken(),r.parseExpression()}parseImportSpecifier(){if(this.ts_isContextual(u.type)){let e=this.startNode();return e.imported=this.parseModuleExportName(),this.parseTypeOnlyImportExportSpecifier(e,!0,"type"===this.importOrExportOuterKind),this.finishNode(e,"ImportSpecifier")}{const e=super.parseImportSpecifier();return e.importKind="value",e}}parseExportSpecifier(e){const t=this.ts_isContextual(u.type);if(!this.match(r.string)&&t){let t=this.startNode();return t.local=this.parseModuleExportName(),this.parseTypeOnlyImportExportSpecifier(t,!1,"type"===this.importOrExportOuterKind),this.finishNode(t,"ExportSpecifier"),this.checkExport(e,t.exported,t.exported.start),t}{const t=super.parseExportSpecifier(e);return t.exportKind="value",t}}parseTypeOnlyImportExportSpecifier(e,t,n){const s=t?"imported":"local",r=t?"local":"exported";let a,i=e[s],o=!1,l=!0;const c=i.start;if(this.isContextual("as")){const e=this.parseIdent();if(this.isContextual("as")){const n=this.parseIdent();g(this.type)?(o=!0,i=e,a=t?this.parseIdent():this.parseModuleExportName(),l=!1):(a=n,l=!1)}else g(this.type)?(l=!1,a=t?this.parseIdent():this.parseModuleExportName()):(o=!0,i=e)}else g(this.type)&&(o=!0,t?(i=super.parseIdent(!0),this.isContextual("as")||this.checkUnreserved(i)):i=this.parseModuleExportName());o&&n&&this.raise(c,t?Rs.TypeModifierIsUsedInTypeImports:Rs.TypeModifierIsUsedInTypeExports),e[s]=i,e[r]=a;e[t?"importKind":"exportKind"]=o?"type":"value",l&&this.eatContextual("as")&&(e[r]=t?this.parseIdent():this.parseModuleExportName()),e[r]||(e[r]=this.copyNode(e[s])),t&&this.checkLValSimple(e[r],Ns.BIND_LEXICAL)}raiseCommonCheck(e,t,n){return"Comma is not permitted after the rest element"===t?this.isAmbientContext&&this.match(r.comma)&&41===this.lookaheadCharCode()?void this.next():super.raise(e,t):n?super.raiseRecoverable(e,t):super.raise(e,t)}raiseRecoverable(e,t){return this.raiseCommonCheck(e,t,!0)}raise(e,t){return this.raiseCommonCheck(e,t,!0)}updateContext(e){const{type:t}=this;if(t==r.braceL){var n=this.curContext();n==d.tc_oTag?this.context.push(c.b_expr):n==d.tc_expr?this.context.push(c.b_tmpl):super.updateContext(e),this.exprAllowed=!0}else{if(t!==r.slash||e!==u.jsxTagStart)return super.updateContext(e);this.context.length-=2,this.context.push(d.tc_cTag),this.exprAllowed=!1}}jsx_parseOpeningElementAt(e,t){let n=this.startNodeAt(e,t),s=this.jsx_parseElementName();if(s&&(n.name=s),this.match(r.relational)||this.match(r.bitShift)){const e=this.tsTryParseAndCatch((()=>this.tsParseTypeArgumentsInExpression()));e&&(n.typeArguments=e)}for(n.attributes=[];this.type!==r.slash&&this.type!==u.jsxTagEnd;)n.attributes.push(this.jsx_parseAttribute());return n.selfClosing=this.eat(r.slash),this.expect(u.jsxTagEnd),this.finishNode(n,s?"JSXOpeningElement":"JSXOpeningFragment")}enterScope(e){e===Ps&&this.importsStack.push([]),super.enterScope(e);const t=super.currentScope();t.types=[],t.enums=[],t.constEnums=[],t.classes=[],t.exportOnlyBindings=[]}exitScope(){super.currentScope().flags===Ps&&this.importsStack.pop(),super.exitScope()}hasImport(e,t){const n=this.importsStack.length;if(this.importsStack[n-1].indexOf(e)>-1)return!0;if(!t&&n>1)for(let t=0;t-1)return!0;return!1}maybeExportDefined(e,t){this.inModule&&e.flags&Ns.SCOPE_TOP&&this.undefinedExports.delete(t)}declareName(e,t,n){if(t&Ns.BIND_FLAGS_TS_IMPORT)return this.hasImport(e,!0)&&this.raise(n,`Identifier '${e}' has already been declared.`),void this.importsStack[this.importsStack.length-1].push(e);const s=this.currentScope();if(t&Ns.BIND_FLAGS_TS_EXPORT_ONLY)return this.maybeExportDefined(s,e),void s.exportOnlyBindings.push(e);t===Ns.BIND_TS_TYPE||t===Ns.BIND_TS_INTERFACE?(t===Ns.BIND_TS_TYPE&&s.types.includes(e)&&this.raise(n,`type '${e}' has already been declared.`),s.types.push(e)):super.declareName(e,t,n),t&Ns.BIND_FLAGS_TS_ENUM&&s.enums.push(e),t&Ns.BIND_FLAGS_TS_CONST_ENUM&&s.constEnums.push(e),t&Ns.BIND_FLAGS_CLASS&&s.classes.push(e)}checkLocalExport(e){const{name:t}=e;if(this.hasImport(t))return;for(let e=this.scopeStack.length-1;e>=0;e--){const n=this.scopeStack[e];if(n.types.indexOf(t)>-1||n.exportOnlyBindings.indexOf(t)>-1)return}super.checkLocalExport(e)}}}}());function Hs(e,t,n,s){const r=n?Vs:fn,{onComment:a,add_comments:i}=zs(e,t),o=r.prototype.parseStatement;let l;s&&(r.prototype.parseStatement=function(...e){const t=o.call(this,...e);return this.undefinedExports={},t});try{l=r.parse(e,{onComment:a,sourceType:"module",ecmaVersion:16,locations:!0})}finally{s&&(r.prototype.parseStatement=o)}return i(l),l}function Us(e,t,n,s){const r=n?Vs:fn,{onComment:a,add_comments:i}=zs(e,t,s),o=r.parseExpressionAt(e,s,{onComment:a,sourceType:"module",ecmaVersion:16,locations:!0});return i(o),o}function zs(e,n,s=0){return{onComment:(t,s,r,a,i,o)=>{if(t&&/\n/.test(s)){let t=r;for(;t>0&&"\n"!==e[t-1];)t-=1;let n=t;for(;/[ \t]/.test(e[n]);)n+=1;const a=e.slice(t,n);s=s.replace(new RegExp(`^${a}`,"gm"),"")}n.push({type:t?"Block":"Line",value:s,start:r,end:a,loc:{start:i,end:o}})},add_comments(r){0!==n.length&&(n=n.filter((e=>e.start>=s)).map((({type:e,value:t,start:n,end:s})=>({type:e,value:t,start:n,end:s}))),t(r,null,{_(t,{next:s,path:r}){let a;for(;n[0]&&n[0].start=s.end)break;(t.trailingComments||=[]).push(e),n.shift(),e.end}else t.end<=n[0].start&&/^[,) \t]*$/.test(r)&&(t.trailingComments=[n.shift()])}}}}),n.length>0&&(n[0].start>=r.end||"Program"===r.type)&&(r.trailingComments||=[]).push(...n.splice(0)))}}}class Ws extends Error{message="";#e;constructor(e,t,n){super(t),this.stack="",this.#e=new qe(e,t,n),Object.assign(this,this.#e),this.name="CompileError"}toString(){return this.#e.toString()}toJSON(){return this.#e.toJSON()}}function Gs(e,t,n){const s="number"==typeof e?e:e?.start;throw new Ws(t,n,void 0!==s?[s,("number"==typeof e?e:e?.end)??s]:void 0)}function Ks(e,t){Gs(e,"options_unrecognised",`Unrecognised compiler option ${t}\nhttps://svelte.dev/e/options_unrecognised`)}function Xs(e,t){Gs(e,"constant_assignment",`Cannot assign to ${t}\nhttps://svelte.dev/e/constant_assignment`)}function Qs(e){Gs(e,"declaration_duplicate_module_import","Cannot declare a variable with the same name as an import inside ` * ``` */ - static of(fn: () => U, options?: SpringOpts): Spring; + static of(fn: () => U, options?: SpringOptions): Spring; /** * Sets `spring.target` to `value` and returns a `Promise` that resolves if and when `spring.current` catches up to it. @@ -2067,7 +2101,7 @@ declare module 'svelte/motion' { * If `options.preserveMomentum` is provided, the spring will continue on its current trajectory for * the specified number of milliseconds. This is useful for things like 'fling' gestures. */ - set(value: T, options?: SpringUpdateOpts): Promise; + set(value: T, options?: SpringUpdateOptions): Promise; damping: number; precision: number; @@ -2085,8 +2119,8 @@ declare module 'svelte/motion' { } export interface Tweened extends Readable { - set(value: T, opts?: TweenedOptions): Promise; - update(updater: Updater, opts?: TweenedOptions): Promise; + set(value: T, opts?: TweenOptions): Promise; + update(updater: Updater, opts?: TweenOptions): Promise; } /** Callback to inform of a value updates. */ type Subscriber = (value: T) => void; @@ -2103,39 +2137,6 @@ declare module 'svelte/motion' { */ subscribe(this: void, run: Subscriber, invalidate?: () => void): Unsubscriber; } - interface SpringOpts { - stiffness?: number; - damping?: number; - precision?: number; - } - - interface SpringUpdateOpts { - /** - * @deprecated Only use this for the spring store; does nothing when set on the Spring class - */ - hard?: any; - /** - * @deprecated Only use this for the spring store; does nothing when set on the Spring class - */ - soft?: string | number | boolean; - /** - * Only use this for the Spring class; does nothing when set on the spring store - */ - instant?: boolean; - /** - * Only use this for the Spring class; does nothing when set on the spring store - */ - preserveMomentum?: number; - } - - type Updater = (target_value: T, value: T) => T; - - interface TweenedOptions { - delay?: number; - duration?: number | ((from: T, to: T) => number); - easing?: (t: number) => number; - interpolate?: (a: T, b: T) => (t: number) => T; - } /** * A [media query](https://svelte.dev/docs/svelte/svelte-reactivity#MediaQuery) that matches if the user [prefers reduced motion](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion). * @@ -2165,13 +2166,13 @@ declare module 'svelte/motion' { * * @deprecated Use [`Spring`](https://svelte.dev/docs/svelte/svelte-motion#Spring) instead * */ - export function spring(value?: T | undefined, opts?: SpringOpts | undefined): Spring; + export function spring(value?: T | undefined, opts?: SpringOptions | undefined): Spring; /** * A tweened store in Svelte is a special type of store that provides smooth transitions between state values over time. * * @deprecated Use [`Tween`](https://svelte.dev/docs/svelte/svelte-motion#Tween) instead * */ - export function tweened(value?: T | undefined, defaults?: TweenedOptions | undefined): Tweened; + export function tweened(value?: T | undefined, defaults?: TweenOptions | undefined): Tweened; /** * A wrapper for a value that tweens smoothly to its target value. Changes to `tween.target` will cause `tween.current` to * move towards it over time, taking account of the `delay`, `duration` and `easing` options. @@ -2204,15 +2205,15 @@ declare module 'svelte/motion' { * ``` * */ - static of(fn: () => U, options?: TweenedOptions | undefined): Tween; + static of(fn: () => U, options?: TweenOptions | undefined): Tween; - constructor(value: T, options?: TweenedOptions); + constructor(value: T, options?: TweenOptions); /** * Sets `tween.target` to `value` and returns a `Promise` that resolves if and when `tween.current` catches up to it. * * If `options` are provided, they will override the tween's defaults. * */ - set(value: T, options?: TweenedOptions | undefined): Promise; + set(value: T, options?: TweenOptions | undefined): Promise; get current(): T; set target(v: T); get target(): T; diff --git a/frontend/node_modules/svelte/types/index.d.ts.map b/frontend/node_modules/svelte/types/index.d.ts.map index 4e842fb..eb9de91 100644 --- a/frontend/node_modules/svelte/types/index.d.ts.map +++ b/frontend/node_modules/svelte/types/index.d.ts.map @@ -111,15 +111,15 @@ "preventDefault", "passive", "nonpassive", + "SpringOptions", + "SpringUpdateOptions", + "Updater", + "TweenOptions", "Spring", "Tweened", "Subscriber", "Unsubscriber", "Readable", - "SpringOpts", - "SpringUpdateOpts", - "Updater", - "TweenedOptions", "prefersReducedMotion", "spring", "tweened", @@ -204,7 +204,6 @@ "../src/internal/client/dom/legacy/event-modifiers.js", "../src/motion/public.d.ts", "../src/store/public.d.ts", - "../src/motion/private.d.ts", "../src/motion/index.js", "../src/motion/spring.js", "../src/motion/tweened.js", @@ -272,9 +271,8 @@ null, null, null, - null, null ], - "mappings": ";;;;;;;;;kBAUiBA,2BAA2BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAmC/BC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAwEhBC,kBAAkBA;;;;;;;;;;;;;;;;;;;;;;;;kBAwBbC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoCbC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;aAwBrBC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAiCfC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA6BdC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;kBAuBRC,OAAOA;;;;;;;;;;;;;;;;kBAgBPC,eAAeA;;;;;;;;;;;;;;;;aAgBpBC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA+CPC,IAAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCzSLC,cAAcA;;;;;;;;;;;;iBAsBdC,OAAOA;;;;;;;;iBAwBPC,SAASA;;;;;;;;;;;;;;;;;;;;;;iBA0CTC,qBAAqBA;;;;;;;;;;iBA2CrBC,YAAYA;;;;;;;;;;iBAuBZC,WAAWA;iBClNXC,UAAUA;;;;iBC4DVC,gBAAgBA;;;;;MCvEpBC,WAAWA;;;;;iBCqqBPC,SAASA;;;;;;;;;;;;;;;;;;iBA8VTC,IAAIA;;;;;;;;iBCp7BJC,aAAaA;;;;;;;;iBAyBbC,UAAUA;;;;;;;;;;;iBAoBVC,UAAUA;;;;;;iBA2BVC,UAAUA;;;;;;;iBAaVC,cAAcA;;;;;;iBCnGdC,KAAKA;;;;;iBA6BLC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8NPC,OAAOA;;;;;;iBC4KDC,IAAIA;;;;;;iBAwBVC,OAAOA;;;;;;;;;;;;;;iBAyOPC,OAAOA;MCruBXC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBCqBFC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA6BZC,MAAMA;;;;;;;;;;;;;;;;;;;;kBCtDNC,eAAeA;;;;;;;;kBAQfC,UAAUA;;;;;;;;;;iBCGXC,IAAIA;;;;;;;;;;;;;;;;kBCLHC,UAAUA;;;;;;;;;;;;;;;;;;;;;;;;;iBCsBXC,mBAAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WJHlBN,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA6BZC,MAAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBKjCPM,OAAOA;;;;;;iBA8CPC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8DbC,QAAQA;;;;iBA+DRC,IAAIA;;;;kBC9LHC,SAASA;;;;;;;;;;;;;;;;;;;;;;;aAuBdC,kBAAkBA;;;;;;;;;;;;;;aAclBC,YAAYA;;;;;;;;;;;;;;;;;;;;;;kBAsBPC,iBAAiBA;;;;;;;;kBCjDjBC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsCbC,OAAOA;;kBAEPC,YAAYA;;MAEjBC,aAAaA;;;;;;;kBAWRC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAuIdC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MC9KzBC,SAASA;;kBAEJC,GAAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCoTUC,UAAUA;;;;;;;;;;;iBC9TxBC,KAAKA;;;;;;;cCbRC,OAAOA;;;;;;iBCqHJC,OAAOA;;;;;;;;;;;;;;;;WCzHNC,IAAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MCCTC,OAAOA;;;;;;;;;iBCMHC,MAAMA;;iBAQNC,SAASA;;iBAUTC,MAAMA;;iBASNC,OAAOA;;iBASPC,SAASA;;iBAqBTC,WAAWA;;iBAQXC,QAAQA;;iBAQRC,SAASA;;iBASTC,MAAMA;;iBAQNC,OAAOA;;iBAQPC,UAAUA;;iBAQVC,OAAOA;;iBAQPC,QAAQA;;iBASRC,YAAYA;;iBAaZC,SAASA;;iBAQTC,UAAUA;;iBAQVC,SAASA;;iBAYTC,MAAMA;;iBAQNC,OAAOA;;iBAQPC,SAASA;;iBAWTC,MAAMA;;iBAQNC,OAAOA;;iBAQPC,UAAUA;;iBAQVC,OAAOA;;iBAQPC,QAAQA;;iBAQRC,UAAUA;;iBASVC,OAAOA;;iBAQPC,QAAQA;;iBAQRC,SAASA;;iBAQTC,MAAMA;;iBAUNC,OAAOA;;;;;;;;;;;;;iBC5PPC,oBAAoBA;;;;;;;;;iBAkBpBC,gBAAgBA;;;;;;iBA4IhBC,GAAGA;;;;;iBAuBHC,QAAQA;;;;;iBAqCRC,aAAaA;;;;aAzLkKC,mBAAmBA;;;;;;;;iBCtDlMC,OAAOA;;;;;iBAgBPC,IAAIA;;;;;iBAiBJC,eAAeA;;;;;iBAefC,IAAIA;;;;;iBAkBJC,wBAAwBA;;;;;iBAexBC,cAAcA;;;;;iBAedC,OAAOA;;;;;iBAcPC,UAAUA;;;;;;;;;;;kBClFbC,MAAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAANA,MAAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA4CFC,OAAOA;;;;;MCjFZC,UAAUA;;;MAGVC,YAAYA;;;WAoBPC,QAAQA;;;;;;;;WCbRC,UAAUA;;;;;;WAMVC,gBAAgBA;;;;;;;;;;;;;;;;;;;MAmBrBC,OAAOA;;WAEFC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCTlBC,oBAAoBA;;;;;;iBCsCjBC,MAAMA;;;;;;iBCsBNC,OAAOA;;;;;;;;;;;;;;;;;cAyFVC,KAAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCzILC,UAAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCKVC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCMTC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCXTC,SAASA;;;;OCnCTC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;cA4BPC,qBAAqBA;;;;;;;;;;;;;;;;;;;;;;;cCErBC,UAAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCiBPC,gBAAgBA;OChDnBC,aAAaA;;;;;;;;;;;;;;;cCMbC,OAAOA;;;;;cASPC,OAAOA;;;;;cASPC,UAAUA;;;;;cASVC,WAAWA;;;;;cASXC,UAAUA;;;;;cASVC,WAAWA;;;;;cASXC,UAAUA;;;;;cAuBVC,SAASA;;;;;cAuBTC,MAAMA;;;;;;;cAmBNC,gBAAgBA;;;OD7HhBV,aAAaA;;;;;;;;;;;;;;;;iBEEVW,MAAMA;;;;;;;;;;;;;;;;;;;;;;;;;;MCUVC,GAAGA;;MAoBHC,YAAYA;;WAEPC,gBAAgBA;;;;;;;;;;;;MAYrBC,YAAYA;;;;;;;aflDZlC,UAAUA;;;aAGVC,YAAYA;;;aAGZI,OAAOA;;;;;;;;;;;aAWP8B,iBAAiBA;;;;;;kBAMZjC,QAAQA;;;;;;;;;;kBAURkC,QAAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBgBfTC,QAAQA;;;;;;iBAcRC,QAAQA;;;;;;;;;;;;;;;;;;iBA4JRC,QAAQA;;;;;iBAcRC,GAAGA;;;;;;;;;;;;aC3MPC,cAAcA;;kBAETC,gBAAgBA;;;;;;;;kBAQhBC,UAAUA;;;;;;;;kBAQVC,UAAUA;;;;;;kBAMVC,SAASA;;;;;;;;;kBASTC,WAAWA;;;;;;;kBAOXC,WAAWA;;;;;;;;kBAQXC,UAAUA;;;;;;;kBAOVC,eAAeA;;;;;;;;;iBClBhBC,IAAIA;;;;;iBAwBJC,IAAIA;;;;;iBAiBJC,GAAGA;;;;;iBA6BHC,KAAKA;;;;;iBAmDLC,KAAKA;;;;;iBA2BLC,IAAIA;;;;;;;iBA+CJC,SAASA;;;;;;;;;;;;;;;;;;;iBCrLTC,EAAEA;;;;;;;;;;;iBAAFA,EAAEA;;;;;;;;;;;iBAAFA,EAAEA;;;;;;;;;;;iBAAFA,EAAEA;;;;;;;;;;;iBAAFA,EAAEA;;;;;;;;;;;;ahCzBNzH,kBAAkBA;;aAclBC,YAAYA;;aAsBPC,iBAAiBA;;aA3DjBH,SAASA;;aAuET2H,kBAAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aCRlBnH,cAAcA;;aAfdH,OAAOA;;;MAIZE,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAkJRE,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MC9KzBC,SAASA", + "mappings": ";;;;;;;;;kBAUiBA,2BAA2BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAmC/BC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAwEhBC,kBAAkBA;;;;;;;;;;;;;;;;;;;;;;;;kBAwBbC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoCbC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;aAwBrBC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAiCfC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA6BdC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;kBAuBRC,OAAOA;;;;;;;;;;;;;;;;kBAgBPC,eAAeA;;;;;;;;;;;;;;;;aAgBpBC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA+CPC,IAAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCzSLC,cAAcA;;;;;;;;;;;;iBAsBdC,OAAOA;;;;;;;;iBAwBPC,SAASA;;;;;;;;;;;;;;;;;;;;;;iBA0CTC,qBAAqBA;;;;;;;;;;iBA2CrBC,YAAYA;;;;;;;;;;iBAuBZC,WAAWA;iBClNXC,UAAUA;;;;iBC4DVC,gBAAgBA;;;;;MCvEpBC,WAAWA;;;;;iBC2vBPC,SAASA;;;;;;;;;;;;;;;;;;iBA8VTC,IAAIA;;;;;;;;iBC1gCJC,aAAaA;;;;;;;;iBAyBbC,UAAUA;;;;;;;;;;;iBAoBVC,UAAUA;;;;;;iBA2BVC,UAAUA;;;;;;;iBAaVC,cAAcA;;;;;;iBCnGdC,KAAKA;;;;;iBA6BLC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8NPC,OAAOA;;;;;;iBC4KDC,IAAIA;;;;;;iBAwBVC,OAAOA;;;;;;;;;;;;;;iBAyOPC,OAAOA;MCruBXC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBCqBFC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA6BZC,MAAMA;;;;;;;;;;;;;;;;;;;;kBCtDNC,eAAeA;;;;;;;;kBAQfC,UAAUA;;;;;;;;;;iBCGXC,IAAIA;;;;;;;;;;;;;;;;kBCLHC,UAAUA;;;;;;;;;;;;;;;;;;;;;;;;;iBCsBXC,mBAAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WJHlBN,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA6BZC,MAAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBKjCPM,OAAOA;;;;;;iBA8CPC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8DbC,QAAQA;;;;iBA+DRC,IAAIA;;;;kBC9LHC,SAASA;;;;;;;;;;;;;;;;;;;;;;;aAuBdC,kBAAkBA;;;;;;;;;;;;;;aAclBC,YAAYA;;;;;;;;;;;;;;;;;;;;;;kBAsBPC,iBAAiBA;;;;;;;;kBCjDjBC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsCbC,OAAOA;;kBAEPC,YAAYA;;MAEjBC,aAAaA;;;;;;;kBAWRC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAuIdC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MC9KzBC,SAASA;;kBAEJC,GAAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCoTUC,UAAUA;;;;;;;;;;;iBC9TxBC,KAAKA;;;;;;;cCbRC,OAAOA;;;;;;iBCqHJC,OAAOA;;;;;;;;;;;;;;;;WCzHNC,IAAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MCCTC,OAAOA;;;;;;;;;iBCMHC,MAAMA;;iBAQNC,SAASA;;iBAUTC,MAAMA;;iBASNC,OAAOA;;iBASPC,SAASA;;iBAqBTC,WAAWA;;iBAQXC,QAAQA;;iBAQRC,SAASA;;iBASTC,MAAMA;;iBAQNC,OAAOA;;iBAQPC,UAAUA;;iBAQVC,OAAOA;;iBAQPC,QAAQA;;iBASRC,YAAYA;;iBAaZC,SAASA;;iBAQTC,UAAUA;;iBAQVC,SAASA;;iBAYTC,MAAMA;;iBAQNC,OAAOA;;iBAQPC,SAASA;;iBAWTC,MAAMA;;iBAQNC,OAAOA;;iBAQPC,UAAUA;;iBAQVC,OAAOA;;iBAQPC,QAAQA;;iBAQRC,UAAUA;;iBASVC,OAAOA;;iBAQPC,QAAQA;;iBAQRC,SAASA;;iBAQTC,MAAMA;;iBAUNC,OAAOA;;;;;;;;;;;;;iBC5PPC,oBAAoBA;;;;;;;;;iBAkBpBC,gBAAgBA;;;;;;iBA4IhBC,GAAGA;;;;;iBAuBHC,QAAQA;;;;;iBAqCRC,aAAaA;;;;aAzLkKC,mBAAmBA;;;;;;;;iBCtDlMC,OAAOA;;;;;iBAgBPC,IAAIA;;;;;iBAiBJC,eAAeA;;;;;iBAefC,IAAIA;;;;;iBAkBJC,wBAAwBA;;;;;iBAexBC,cAAcA;;;;;iBAedC,OAAOA;;;;;iBAcPC,UAAUA;;;;;;;kBCtHTC,aAAaA;;;;;;kBAMbC,mBAAmBA;;;;;;;;;;;;;;;;;;;aAmBxBC,OAAOA;;kBAEFC,YAAYA;;;;;;;;;;;kBA0ChBC,MAAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAANA,MAAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA4CFC,OAAOA;;;;;MClHZC,UAAUA;;;MAGVC,YAAYA;;;WAoBPC,QAAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCKZC,oBAAoBA;;;;;;iBCsCjBC,MAAMA;;;;;;iBCqBNC,OAAOA;;;;;;;;;;;;;;;;;cAyFVC,KAAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCxILC,UAAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCKVC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCMTC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCXTC,SAASA;;;;OCnCTC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;cA4BPC,qBAAqBA;;;;;;;;;;;;;;;;;;;;;;;cCErBC,UAAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCiBPC,gBAAgBA;OChDnBC,aAAaA;;;;;;;;;;;;;;;cCMbC,OAAOA;;;;;cASPC,OAAOA;;;;;cASPC,UAAUA;;;;;cASVC,WAAWA;;;;;cASXC,UAAUA;;;;;cASVC,WAAWA;;;;;cASXC,UAAUA;;;;;cAuBVC,SAASA;;;;;cAuBTC,MAAMA;;;;;;;cAmBNC,gBAAgBA;;;OD7HhBV,aAAaA;;;;;;;;;;;;;;;;iBEEVW,MAAMA;;;;;;;;;;;;;;;;;;;;;;;;;;MCUVC,GAAGA;;MAoBHC,YAAYA;;WAEPC,gBAAgBA;;;;;;;;;;;;MAYrBC,YAAYA;;;;;;;adlDZ9B,UAAUA;;;aAGVC,YAAYA;;;aAGZL,OAAOA;;;;;;;;;;;aAWPmC,iBAAiBA;;;;;;kBAMZ7B,QAAQA;;;;;;;;;;kBAUR8B,QAAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBefTC,QAAQA;;;;;;iBAcRC,QAAQA;;;;;;;;;;;;;;;;;;iBA4JRC,QAAQA;;;;;iBAcRC,GAAGA;;;;;;;;;;;;aC3MPC,cAAcA;;kBAETC,gBAAgBA;;;;;;;;kBAQhBC,UAAUA;;;;;;;;kBAQVC,UAAUA;;;;;;kBAMVC,SAASA;;;;;;;;;kBASTC,WAAWA;;;;;;;kBAOXC,WAAWA;;;;;;;;kBAQXC,UAAUA;;;;;;;kBAOVC,eAAeA;;;;;;;;;iBClBhBC,IAAIA;;;;;iBAwBJC,IAAIA;;;;;iBAiBJC,GAAGA;;;;;iBA6BHC,KAAKA;;;;;iBAmDLC,KAAKA;;;;;iBA2BLC,IAAIA;;;;;;;iBA+CJC,SAASA;;;;;;;;;;;;;;;;;;;iBCrLTC,EAAEA;;;;;;;;;;;iBAAFA,EAAEA;;;;;;;;;;;iBAAFA,EAAEA;;;;;;;;;;;iBAAFA,EAAEA;;;;;;;;;;;iBAAFA,EAAEA;;;;;;;;;;;;a/BzBNzH,kBAAkBA;;aAclBC,YAAYA;;aAsBPC,iBAAiBA;;aA3DjBH,SAASA;;aAuET2H,kBAAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aCRlBnH,cAAcA;;aAfdH,OAAOA;;;MAIZE,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAkJRE,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MC9KzBC,SAASA", "ignoreList": [] } \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index bc74a39..e0f2a6b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,5 +1,5 @@ { - "name": "imc-vibe-frontend", + "name": "imc-frontend", "version": "0.0.1", "private": true, "type": "module", @@ -18,6 +18,7 @@ "daisyui": "^5.5.19", "postcss": "^8.5.8", "svelte": "^5.0.0", + "svelte-heros": "^8.0.1", "tailwindcss": "^4.2.2", "typescript": "^5.0.0", "vite": "^5.0.0" diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index ee04475..8294628 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -3,6 +3,13 @@ import { goto } from '$app/navigation'; import { onMount } from 'svelte'; import { decodeJWT, isTokenValid } from '$lib/auth'; + import DocumentText from 'svelte-heros/DocumentText.svelte'; + import GlobeAlt from 'svelte-heros/GlobeAlt.svelte'; + import Home from 'svelte-heros/Home.svelte'; + import Mail from 'svelte-heros/Mail.svelte'; + import MenuAlt4 from 'svelte-heros/MenuAlt4.svelte'; + import Refresh from 'svelte-heros/Refresh.svelte'; + import Users from 'svelte-heros/Users.svelte'; import '../app.css'; let { children } = $props(); @@ -31,9 +38,9 @@ $effect(() => { const path = $page.url.pathname; - // Auth-only routes (login, forgot) - no auth required, no layout chrome + // Auth-only routes (login) - no auth required, no layout chrome // /auth/change-password requires auth, so treat it like a regular route - const isAuthOnlyRoute = path === '/auth/login' || path === '/auth/forgot'; + const isAuthOnlyRoute = path === '/auth/login'; if (isAuthOnlyRoute) { loading = false; } else { @@ -84,16 +91,20 @@