diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..29ae255 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +github: h44z # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1aba90f..007f958 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -28,3 +28,8 @@ updates: patch: update-types: - patch + + - package-ecosystem: "docker" + directory: / + schedule: + interval: weekly diff --git a/.github/workflows/chart.yml b/.github/workflows/chart.yml index 68a9b0b..cc959b5 100644 --- a/.github/workflows/chart.yml +++ b/.github/workflows/chart.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.event_name == 'pull_request' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 @@ -35,7 +35,7 @@ jobs: # ct lint requires Python 3.x to run following packages: # - yamale (https://github.com/23andMe/Yamale) # - yamllint (https://github.com/adrienverge/yamllint) - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: '3.x' @@ -60,7 +60,7 @@ jobs: permissions: packages: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: docker/login-action@v3 with: diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 9da67f1..bc3c7da 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -110,7 +110,7 @@ jobs: contents: write steps: - name: Download binaries - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v5 with: name: binaries diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index b148619..0bc7674 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -15,11 +15,11 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: 3.x diff --git a/Dockerfile b/Dockerfile index e904d89..cee602a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ RUN npm run build ###### # Build backend ###### -FROM --platform=${BUILDPLATFORM} golang:1.24-alpine AS builder +FROM --platform=${BUILDPLATFORM} golang:1.25-alpine AS builder # Set the working directory WORKDIR /build # Download dependencies @@ -50,9 +50,9 @@ COPY --from=builder /build/dist/wg-portal / ###### # Final image ###### -FROM alpine:3.19 +FROM alpine:3.22 # Install OS-level dependencies -RUN apk add --no-cache bash curl iptables nftables openresolv wireguard-tools +RUN apk add --no-cache bash curl iptables nftables openresolv wireguard-tools tzdata # Setup timezone ENV TZ=UTC # Copy binaries diff --git a/LICENSE.txt b/LICENSE.txt index 74ca367..563c17d 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2020-2023 Christoph Haas +Copyright (c) 2020-2025 Christoph Haas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/README.md b/README.md index c5a2968..9bc044f 100644 --- a/README.md +++ b/README.md @@ -21,17 +21,18 @@ The configuration portal supports using a database (SQLite, MySQL, MsSQL, or Pos ## Features * Self-hosted - the whole application is a single binary -* Responsive multi-language web UI written in Vue.js +* Responsive multi-language web UI with dark-mode written in Vue.js * Automatically selects IP from the network pool assigned to the client * QR-Code for convenient mobile client configuration * Sends email to the client with QR-code and client config * Enable / Disable clients seamlessly * Generation of wg-quick configuration file (`wgX.conf`) if required -* User authentication (database, OAuth, or LDAP) +* User authentication (database, OAuth, or LDAP), Passkey support * IPv6 ready * Docker ready * Can be used with existing WireGuard setups * Support for multiple WireGuard interfaces +* Supports multiple WireGuard backends (wgctrl or MikroTik) * Peer Expiry Feature * Handles route and DNS settings like wg-quick does * Exposes Prometheus metrics for monitoring and alerting @@ -61,6 +62,17 @@ For the complete documentation visit [wgportal.org](https://wgportal.org). * MIT License. [MIT](LICENSE.txt) or +## Contributors and Sponsors + +Thanks so much for all your contributions! They’re truly appreciated and help keep WireGuard Portal moving ahead. + + + + + +Want to support the project? You can buy me a coffee or join as a contributor - every bit of support helps! +[Become a sponsor!](https://github.com/sponsors/h44z) + > [!IMPORTANT] > Since the project was accepted by the Docker-Sponsored Open Source Program, the Docker image location has moved to [wgportal/wg-portal](https://hub.docker.com/r/wgportal/wg-portal). diff --git a/SECURITY.md b/SECURITY.md index 559eccb..0ffebd7 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,7 +7,7 @@ If you believe you've found a security issue in one of the supported versions of | Version | Supported | |---------|--------------------| | v2.x | :white_check_mark: | -| v1.x | :white_check_mark: | +| v1.x | :x: | ## Reporting a Vulnerability diff --git a/cmd/wg-portal/main.go b/cmd/wg-portal/main.go index 456290c..cd5fd7e 100644 --- a/cmd/wg-portal/main.go +++ b/cmd/wg-portal/main.go @@ -50,9 +50,8 @@ func main() { database, err := adapters.NewSqlRepository(rawDb) internal.AssertNoError(err) - wireGuard := adapters.NewWireGuardRepository() - - wgQuick := adapters.NewWgQuickRepo() + wireGuard, err := wireguard.NewControllerManager(cfg) + internal.AssertNoError(err) mailer := adapters.NewSmtpMailRepo(cfg.Mail) @@ -87,8 +86,12 @@ func main() { authenticator, err := auth.NewAuthenticator(&cfg.Auth, cfg.Web.ExternalUrl, eventBus, userManager) internal.AssertNoError(err) + authenticator.StartBackgroundJobs(ctx) - wireGuardManager, err := wireguard.NewWireGuardManager(cfg, eventBus, wireGuard, wgQuick, database) + webAuthn, err := auth.NewWebAuthnAuthenticator(cfg, eventBus, userManager) + internal.AssertNoError(err) + + wireGuardManager, err := wireguard.NewWireGuardManager(cfg, eventBus, wireGuard, database) internal.AssertNoError(err) wireGuardManager.StartBackgroundJobs(ctx) @@ -102,7 +105,7 @@ func main() { mailManager, err := mail.NewMailManager(cfg, mailer, cfgFileManager, database, database) internal.AssertNoError(err) - routeManager, err := route.NewRouteManager(cfg, eventBus, database) + routeManager, err := route.NewRouteManager(cfg, eventBus, database, wireGuard) internal.AssertNoError(err) routeManager.StartBackgroundJobs(ctx) @@ -124,12 +127,13 @@ func main() { apiV0BackendInterfaces := backendV0.NewInterfaceService(cfg, wireGuardManager, cfgFileManager) apiV0BackendPeers := backendV0.NewPeerService(cfg, wireGuardManager, cfgFileManager, mailManager) - apiV0EndpointAuth := handlersV0.NewAuthEndpoint(cfg, apiV0Auth, apiV0Session, validatorManager, authenticator) + apiV0EndpointAuth := handlersV0.NewAuthEndpoint(cfg, apiV0Auth, apiV0Session, validatorManager, authenticator, + webAuthn) apiV0EndpointAudit := handlersV0.NewAuditEndpoint(cfg, apiV0Auth, auditManager) apiV0EndpointUsers := handlersV0.NewUserEndpoint(cfg, apiV0Auth, validatorManager, apiV0BackendUsers) apiV0EndpointInterfaces := handlersV0.NewInterfaceEndpoint(cfg, apiV0Auth, validatorManager, apiV0BackendInterfaces) apiV0EndpointPeers := handlersV0.NewPeerEndpoint(cfg, apiV0Auth, validatorManager, apiV0BackendPeers) - apiV0EndpointConfig := handlersV0.NewConfigEndpoint(cfg, apiV0Auth) + apiV0EndpointConfig := handlersV0.NewConfigEndpoint(cfg, apiV0Auth, wireGuard) apiV0EndpointTest := handlersV0.NewTestEndpoint(apiV0Auth) apiFrontend := handlersV0.NewRestApi(apiV0Session, diff --git a/docs/assets/images/interface_view.png b/docs/assets/images/interface_view.png new file mode 100644 index 0000000..09f5b1b Binary files /dev/null and b/docs/assets/images/interface_view.png differ diff --git a/docs/assets/images/landing_page.png b/docs/assets/images/landing_page.png new file mode 100644 index 0000000..4bb72bb Binary files /dev/null and b/docs/assets/images/landing_page.png differ diff --git a/docs/assets/images/passkey_setup.png b/docs/assets/images/passkey_setup.png new file mode 100644 index 0000000..af39e89 Binary files /dev/null and b/docs/assets/images/passkey_setup.png differ diff --git a/docs/assets/images/wgportal_dark.png b/docs/assets/images/wgportal_dark.png new file mode 100644 index 0000000..b72ec95 Binary files /dev/null and b/docs/assets/images/wgportal_dark.png differ diff --git a/docs/assets/images/wgportal_light.png b/docs/assets/images/wgportal_light.png new file mode 100644 index 0000000..0add328 Binary files /dev/null and b/docs/assets/images/wgportal_light.png differ diff --git a/docs/documentation/configuration/examples.md b/docs/documentation/configuration/examples.md index 1409d2b..4cf1e56 100644 --- a/docs/documentation/configuration/examples.md +++ b/docs/documentation/configuration/examples.md @@ -11,6 +11,27 @@ core: create_default_peer: true self_provisioning_allowed: true +backend: + # default backend decides where new interfaces are created + default: mikrotik + + # A prefix for resolvconf. Usually it is "tun.". If you are using systemd, the prefix should be empty. + local_resolvconf_prefix: "tun." + + mikrotik: + - id: mikrotik # unique id, not "local" + display_name: RouterOS RB5009 # optional nice name + api_url: https://10.10.10.10/rest + api_user: wgportal + api_password: a-super-secret-password + api_verify_tls: false # set to false only if using self-signed during testing + api_timeout: 30s # maximum request duration + concurrency: 5 # limit parallel REST calls to device + debug: false # verbose logging for this backend + ignored_interfaces: # ignore these interfaces during import + - wgTest1 + - wgTest2 + web: site_title: My WireGuard Server site_company_name: My Company @@ -32,6 +53,10 @@ database: type: sqlite dsn: data/sqlite.db encryption_passphrase: change-this-s3cr3t-encryption-passphrase + +auth: + webauthn: + enabled: true ``` ## LDAP Authentication and Synchronization @@ -191,3 +216,5 @@ auth: registration_enabled: true log_user_info: true ``` + +For more information, check out the usage documentation (e.g. [General Configuration](../usage/general.md) or [Backends Configuration](../usage/backends.md)). diff --git a/docs/documentation/configuration/overview.md b/docs/documentation/configuration/overview.md index bc47ba0..75331f7 100644 --- a/docs/documentation/configuration/overview.md +++ b/docs/documentation/configuration/overview.md @@ -14,8 +14,9 @@ Configuration examples are available on the [Examples](./examples.md) page. ```yaml core: admin_user: admin@wgportal.local - admin_password: wgportal + admin_password: wgportal-default admin_api_token: "" + disable_admin_user: false editable_keys: true create_default_peer: false create_default_peer_on_creation: false @@ -24,6 +25,10 @@ core: self_provisioning_allowed: false import_existing: true restore_state: true + +backend: + default: local + local_resolvconf_prefix: tun. advanced: log_level: info @@ -38,6 +43,7 @@ advanced: rule_prio_offset: 20000 route_table_offset: 20000 api_admin_only: true + limit_additional_user_peers: 0 database: debug: false @@ -67,11 +73,16 @@ mail: auth_type: plain from: Wireguard Portal link_only: false + allow_peer_email: false auth: oidc: [] oauth: [] ldap: [] + webauthn: + enabled: true + min_password_length: 16 + hide_login_form: false web: listening_address: :8888 @@ -97,6 +108,7 @@ webhook: Below you will find sections like [`core`](#core), +[`backend`](#backend), [`advanced`](#advanced), [`database`](#database), [`statistics`](#statistics), @@ -118,8 +130,13 @@ More advanced options are found in the subsequent `Advanced` section. - **Description:** The administrator user. This user will be created as a default admin if it does not yet exist. ### `admin_password` -- **Default:** `wgportal` -- **Description:** The administrator password. The default password of `wgportal` should be changed immediately. +- **Default:** `wgportal-default` +- **Description:** The administrator password. The default password should be changed immediately! +- **Important:** The password should be strong and secure. The minimum password length is specified in [auth.min_password_length](#min_password_length). By default, it is 16 characters. + +### `disable_admin_user` +- **Default:** `false` +- **Description:** If `true`, no admin user is created. This is useful if you plan to manage users exclusively through external authentication providers such as LDAP or OAuth. ### `admin_api_token` - **Default:** *(empty)* @@ -159,6 +176,80 @@ More advanced options are found in the subsequent `Advanced` section. --- +## Backend + +Configuration options for the WireGuard backend, which manages the WireGuard interfaces and peers. +The current MikroTik backend is in **BETA** and may not support all features. + +### `default` +- **Default:** `local` +- **Description:** The default backend to use for managing WireGuard interfaces. + Valid options are: `local`, or other backend id's configured in the `mikrotik` section. + +### `local_resolvconf_prefix` +- **Default:** `tun.` +- **Description:** Interface name prefix for WireGuard interfaces on the local system which is used to configure DNS servers with *resolvconf*. + It depends on the *resolvconf* implementation you are using, most use a prefix of `tun.`, but some have an empty prefix (e.g., systemd). + +### `ignored_local_interfaces` +- **Default:** *(empty)* +- **Description:** A list of interface names to exclude when enumerating local interfaces. + This is useful if you want to prevent certain interfaces from being imported from the local system. + +### Mikrotik + +The `mikrotik` array contains a list of MikroTik backend definitions. Each entry describes how to connect to a MikroTik RouterOS instance that hosts WireGuard interfaces. + +Below are the properties for each entry inside `backend.mikrotik`: + +#### `id` +- **Default:** *(empty)* +- **Description:** A unique identifier for this backend. + This value can be referenced by `backend.default` to use this backend as default. + The identifier must be unique across all backends and must not use the reserved keyword `local`. + +#### `display_name` +- **Default:** *(empty)* +- **Description:** A human-friendly display name for this backend. If omitted, the `id` will be used as the display name. + +#### `api_url` +- **Default:** *(empty)* +- **Description:** Base URL of the MikroTik REST API, including scheme and path, e.g., `https://10.10.10.10:8729/rest`. + +#### `api_user` +- **Default:** *(empty)* +- **Description:** Username for authenticating against the MikroTik API. + Ensure that the user has sufficient permissions to manage WireGuard interfaces and peers. + +#### `api_password` +- **Default:** *(empty)* +- **Description:** Password for the specified API user. + +#### `api_verify_tls` +- **Default:** `false` +- **Description:** Whether to verify the TLS certificate of the MikroTik API endpoint. Set to `false` to allow self-signed certificates (not recommended for production). + +#### `api_timeout` +- **Default:** `30s` +- **Description:** Timeout for API requests to the MikroTik device. Uses Go duration format (e.g., `10s`, `1m`). If omitted, a default of 30 seconds is used. + +#### `concurrency` +- **Default:** `5` +- **Description:** Maximum number of concurrent API requests the backend will issue when enumerating interfaces and their details. If `0` or negative, a sane default of `5` is used. + +#### `ignored_interfaces` +- **Default:** *(empty)* +- **Description:** A list of interface names to exclude during interface enumeration. + This is useful if you want to prevent specific interfaces from being imported from the MikroTik device. + +#### `debug` +- **Default:** `false` +- **Description:** Enable verbose debug logging for the MikroTik backend. + +For more details on configuring the MikroTik backend, see the [Backends](../usage/backends.md) documentation. + +--- + ## Advanced Additional or more specialized configuration options for logging and interface creation details. @@ -211,6 +302,10 @@ Additional or more specialized configuration options for logging and interface c - **Default:** `true` - **Description:** If `true`, the public REST API is accessible only to admin users. The API docs live at [`/api/v1/doc.html`](../rest-api/api-doc.md). +### `limit_additional_user_peers` +- **Default:** `0` +- **Description:** Limit additional peers a normal user can create. `0` means unlimited. + --- ## Database @@ -292,7 +387,9 @@ Controls how WireGuard Portal collects and reports usage statistics, including p ## Mail -Options for configuring email notifications or sending peer configurations via email. +Options for configuring email notifications or sending peer configurations via email. +By default, emails will only be sent to peers that have a valid user record linked. +To send emails to all peers that have a valid email-address as user-identifier, set `allow_peer_email` to `true`. ### `host` - **Default:** `127.0.0.1` @@ -330,13 +427,33 @@ Options for configuring email notifications or sending peer configurations via e - **Default:** `false` - **Description:** If `true`, emails only contain a link to WireGuard Portal, rather than attaching the full configuration. +### `allow_peer_email` +- **Default:** `false` + - **Description:** If `true`, and a peer has no valid user record linked, but the user-identifier of the peer is a valid email address, emails will be sent to that email address. + If false, and the peer has no valid user record linked, emails will not be sent. + If a peer has linked a valid user, the email address is always taken from the user record. + --- ## Auth -WireGuard Portal supports multiple authentication strategies, including **OpenID Connect** (`oidc`), **OAuth** (`oauth`), and **LDAP** (`ldap`). +WireGuard Portal supports multiple authentication strategies, including **OpenID Connect** (`oidc`), **OAuth** (`oauth`), **Passkeys** (`webauthn`) and **LDAP** (`ldap`). Each can have multiple providers configured. Below are the relevant keys. +Some core authentication options are shared across all providers, while others are specific to each provider type. + +### `min_password_length` +- **Default:** `16` +- **Description:** Minimum password length for local authentication. This is not enforced for LDAP authentication. + The default admin password strength is also enforced by this setting. +- **Important:** The password should be strong and secure. It is recommended to use a password with at least 16 characters, including uppercase and lowercase letters, numbers, and special characters. + +### `hide_login_form` +- **Default:** `false` +- **Description:** If `true`, the login form is hidden and only the OIDC, OAuth, LDAP, or WebAuthn providers are shown. This is useful if you want to enforce a specific authentication method. + If no social login providers are configured, the login form is always shown, regardless of this setting. +- **Important:** You can still access the login form by adding the `?all` query parameter to the login URL (e.g. https://wg.portal/#/login?all). + --- ### OIDC @@ -395,13 +512,18 @@ Below are the properties for each OIDC provider entry inside `auth.oidc`: - `admin_group_regex`: A regular expression to match the `user_groups` claim. Each entry in the `user_groups` claim is checked against this regex. #### `registration_enabled` -- **Default:** *(empty)* +- **Default:** `false` - **Description:** If `true`, a new user will be created in WireGuard Portal if not already present. #### `log_user_info` -- **Default:** *(empty)* +- **Default:** `false` - **Description:** If `true`, OIDC user data is logged at the trace level upon login (for debugging). +#### `log_sensitive_info` +- **Default:** `false` +- **Description:** If `true`, sensitive OIDC user data, such as tokens and raw responses, will be logged at the trace level upon login (for debugging). +- **Important:** Keep this setting disabled in production environments! Remove logs once you finished debugging authentication issues. + --- ### OAuth @@ -468,13 +590,18 @@ Below are the properties for each OAuth provider entry inside `auth.oauth`: - `admin_group_regex`: A regular expression to match the `user_groups` claim. Each entry in the `user_groups` claim is checked against this regex. #### `registration_enabled` -- **Default:** *(empty)* +- **Default:** `false` - **Description:** If `true`, new users are created automatically on successful login. #### `log_user_info` -- **Default:** *(empty)* +- **Default:** `false` - **Description:** If `true`, logs user info at the trace level upon login. +#### `log_sensitive_info` +- **Default:** `false` +- **Description:** If `true`, sensitive OIDC user data, such as tokens and raw responses, will be logged at the trace level upon login (for debugging). +- **Important:** Keep this setting disabled in production environments! Remove logs once you finished debugging authentication issues. + --- ### LDAP @@ -491,11 +618,11 @@ Below are the properties for each LDAP provider entry inside `auth.ldap`: - **Description:** The LDAP server URL (e.g., `ldap://srv-ad01.company.local:389`). #### `start_tls` -- **Default:** *(empty)* +- **Default:** `false` - **Description:** If `true`, use STARTTLS to secure the LDAP connection. #### `cert_validation` -- **Default:** *(empty)* +- **Default:** `false` - **Description:** If `true`, validate the LDAP server’s TLS certificate. #### `tls_certificate_path` @@ -540,6 +667,8 @@ Below are the properties for each LDAP provider entry inside `auth.ldap`: ```text (&(objectClass=organizationalPerson)(mail={{login_identifier}})(!userAccountControl:1.2.840.113556.1.4.803:=2)) ``` +- **Important**: The `login_filter` must always be a valid LDAP filter. It should at most return one user. + If the filter returns multiple or no users, the login will fail. #### `admin_group` - **Default:** *(empty)* @@ -563,23 +692,33 @@ Below are the properties for each LDAP provider entry inside `auth.ldap`: ``` #### `disable_missing` -- **Default:** *(empty)* +- **Default:** `false` - **Description:** If `true`, any user **not** found in LDAP (during sync) is disabled in WireGuard Portal. #### `auto_re_enable` -- **Default:** *(empty)* +- **Default:** `false` - **Description:** If `true`, users that where disabled because they were missing (see `disable_missing`) will be re-enabled once they are found again. #### `registration_enabled` -- **Default:** *(empty)* +- **Default:** `false` - **Description:** If `true`, new user accounts are created in WireGuard Portal upon first login. #### `log_user_info` -- **Default:** *(empty)* +- **Default:** `false` - **Description:** If `true`, logs LDAP user data at the trace level upon login. --- +### WebAuthn (Passkeys) + +The `webauthn` section contains configuration options for WebAuthn authentication (passkeys). + +#### `enabled` +- **Default:** `true` +- **Description:** If `true`, Passkey authentication is enabled. If `false`, WebAuthn is disabled. + Users are encouraged to use Passkeys for secure authentication instead of passwords. + If a passkey is registered, the password login is still available as a fallback. Ensure that the password is strong and secure. + ## Web The web section contains configuration options for the web server, including the listening address, session management, and CSRF protection. @@ -637,18 +776,7 @@ Without a valid `external_url`, the login process may fail due to CSRF protectio ## Webhook The webhook section allows you to configure a webhook that is called on certain events in WireGuard Portal. -A JSON object is sent in a POST request to the webhook URL with the following structure: -```json -{ - "event": "peer_created", - "entity": "peer", - "identifier": "the-peer-identifier", - "payload": { - // The payload of the event, e.g. peer data. - // Check the API documentation for the exact structure. - } -} -``` +Further details can be found in the [usage documentation](../usage/webhooks.md). ### `url` - **Default:** *(empty)* diff --git a/docs/documentation/rest-api/swagger.yaml b/docs/documentation/rest-api/swagger.yaml index fb6cd00..12ef021 100644 --- a/docs/documentation/rest-api/swagger.yaml +++ b/docs/documentation/rest-api/swagger.yaml @@ -403,6 +403,12 @@ definitions: type: object models.ProvisioningRequest: properties: + DisplayName: + description: |- + DisplayName is an optional name for the new peer. + If unset, a default template value (e.g., "API Peer ...") will be assigned. + example: API Peer xyz + type: string InterfaceIdentifier: description: InterfaceIdentifier is the identifier of the WireGuard interface the peer should be linked to. example: wg0 diff --git a/docs/documentation/usage/backends.md b/docs/documentation/usage/backends.md new file mode 100644 index 0000000..e891d95 --- /dev/null +++ b/docs/documentation/usage/backends.md @@ -0,0 +1,57 @@ +# Backends + +WireGuard Portal can manage WireGuard interfaces and peers on different backends. +Each backend represents a system where interfaces actually live. +You can register multiple backends and choose which one to use per interface. +A global default backend determines where newly created interfaces go (unless you explicitly choose another in the UI). + +**Supported backends:** +- **Local** (default): Manages interfaces on the host running WireGuard Portal (Linux WireGuard via wgctrl). Use this when the portal should directly configure wg devices on the same server. +- **MikroTik** RouterOS (_beta_): Manages interfaces and peers on MikroTik devices via the RouterOS REST API. Use this to control WG interfaces on RouterOS v7+. + +How backend selection works: +- The default backend is configured at `backend.default` (_local_ or the id of a defined MikroTik backend). + New interfaces created in the UI will use this backend by default. +- Each interface stores its backend. You can select a different backend when creating a new interface. + +## Configuring MikroTik backends (RouterOS v7+) + +> :warning: The MikroTik backend is currently marked beta. While basic functionality is implemented, some advanced features are not yet implemented or contain bugs. Please test carefully before using in production. + +The MikroTik backend uses the [REST API](https://help.mikrotik.com/docs/spaces/ROS/pages/47579162/REST+API) under a base URL ending with /rest. +You can register one or more MikroTik devices as backends for a single WireGuard Portal instance. + +### Prerequisites on MikroTik: +- RouterOS v7 with WireGuard support. +- REST API enabled and reachable over HTTP(S). A typical base URL is https://:8729/rest or https:///rest depending on your service setup. +- A dedicated RouterOS user with the following group permissions: + - **api** (for logging in via REST API) + - **rest-api** (for logging in via REST API) + - **read** (to read interface and peer data) + - **write** (to create/update interfaces and peers) + - **test** (to perform ping checks) + - **sensitive** (to read private keys) +- TLS certificate on the device is recommended. If you use a self-signed certificate during testing, set `api_verify_tls`: _false_ in wg-portal (not recommended for production). + +Example WireGuard Portal configuration (config/config.yaml): + +```yaml +backend: + # default backend decides where new interfaces are created + default: mikrotik-prod + + mikrotik: + - id: mikrotik-prod # unique id, not "local" + display_name: RouterOS RB5009 # optional nice name + api_url: https://10.10.10.10/rest + api_user: wgportal + api_password: a-super-secret-password + api_verify_tls: true # set to false only if using self-signed during testing + api_timeout: 30s # maximum request duration + concurrency: 5 # limit parallel REST calls to device + debug: false # verbose logging for this backend +``` + +### Known limitations: +- The MikroTik backend is still in beta. Some features may not work as expected. +- Not all WireGuard Portal features are supported yet (e.g., no support for interface hooks) \ No newline at end of file diff --git a/docs/documentation/usage/general.md b/docs/documentation/usage/general.md new file mode 100644 index 0000000..6ebf5be --- /dev/null +++ b/docs/documentation/usage/general.md @@ -0,0 +1,57 @@ +This documentation section describes the general usage of WireGuard Portal. +If you are looking for specific setup instructions, please refer to the *Getting Started* and [*Configuration*](../configuration/overview.md) sections, +for example, using a [Docker](../getting-started/docker.md) deployment. + +## Basic Concepts + +WireGuard Portal is a web-based configuration portal for WireGuard server management. It allows managing multiple WireGuard interfaces and users from a single web UI. +WireGuard Interfaces can be categorized into three types: + + - **Server**: A WireGuard server interface that to which multiple peers can connect. In this mode, it is possible to specify default settings for all peers, such as the IP address range, DNS servers, and MTU size. + - **Client**: A WireGuard client interface that can be used to connect to a WireGuard server. Usually, such an interface has exactly one peer. + - **Unknown**: This is the default type for imported interfaces. It is encouraged to change the type to either `Server` or `Client` after importing the interface. + +## Accessing the Web UI + +The web UI should be accessed via the URL specified in the `external_url` property of the configuration file. +By default, WireGuard Portal listens on port `8888` for HTTP connections. Check the [Security](security.md) section for more information on securing the web UI. + +So the default URL to access the web UI is: + +``` +http://localhost:8888 +``` + +A freshly set-up WireGuard Portal instance will have a default admin user with the username `admin@wgportal.local` and the password `wgportal-default`. +You can and should override the default credentials in the configuration file. Make sure to change the default password immediately after the first login! + + +### Basic UI Description + +![WireGuard Portal Web UI](../../assets/images/landing_page.png) + +As seen in the screenshot above, the web UI is divided into several sections which are accessible via the navigation bar on the top of the screen. + +1. **Home**: The landing page of WireGuard Portal. It provides a staring point for the user to access the different sections of the web UI. It also provides quick links to WireGuard Client downloads or official documentation. +2. **Interfaces**: This section allows you to manage the WireGuard interfaces. You can add, edit, or delete interfaces, as well as view their status and statistics. Peers for each interface can be managed here as well. +3. **Users**: This section allows you to manage the users of WireGuard Portal. You can add, edit, or delete users, as well as view their status and statistics. +4. **Key Generator**: This section allows you to generate WireGuard keys locally on your browser. The generated keys are never sent to the server. This is useful if you want to generate keys for a new peer without having to store the private keys in the database. +5. **Profile / Settings**: This section allows you to access your own profile page, settings, and audit logs. + + +### Interface View + +![WireGuard Portal Interface View](../../assets/images/interface_view.png) + +The interface view provides an overview of the WireGuard interfaces and peers configured in WireGuard Portal. + +The most important elements are: + +1. **Interface Selector**: This dropdown allows you to select the WireGuard interface you want to manage. + All further actions will be performed on the selected interface. +2. **Create new Interface**: This button allows you to create a new WireGuard interface. +3. **Interface Overview**: This section provides an overview of the selected WireGuard interface. It shows the interface type, number of peers, and other important information. +4. **List of Peers**: This section provides a list of all peers associated with the selected WireGuard interface. You can view, add, edit, or delete peers from this list. +5. **Add new Peer**: This button allows you to add a new peer to the selected WireGuard interface. +6. **Add multiple Peers**: This button allows you to add multiple peers to the selected WireGuard interface. + This is useful if you want to add a large number of peers at once. \ No newline at end of file diff --git a/docs/documentation/usage/ldap.md b/docs/documentation/usage/ldap.md new file mode 100644 index 0000000..d0ebc77 --- /dev/null +++ b/docs/documentation/usage/ldap.md @@ -0,0 +1,37 @@ +WireGuard Portal lets you hook up any LDAP server such as Active Directory or OpenLDAP for both authentication and user sync. +You can even register multiple LDAP servers side-by-side. When someone logs in via LDAP, their specific provider is remembered, +so there's no risk of cross-provider conflicts. Details on the log-in process can be found in the [Security](security.md#ldap-authentication) documentation. + +If you enable LDAP synchronization, all users within the LDAP directory will be created automatically in the WireGuard Portal database if they do not exist. +If a user is disabled or deleted in LDAP, the user will be disabled in WireGuard Portal as well. +The synchronization process can be fine-tuned by multiple parameters, which are described below. + +## LDAP Synchronization + +WireGuard Portal can automatically synchronize users from LDAP to the database. +To enable this feature, set the `sync_interval` property in the LDAP provider configuration to a value greater than "0". +The value is a string representing a duration, such as "15m" for 15 minutes or "1h" for 1 hour (check the [exact format definition](https://pkg.go.dev/time#ParseDuration) for details). +The synchronization process will run in the background and synchronize users from LDAP to the database at the specified interval. +Also make sure that the `sync_filter` property is a well-formed LDAP filter, or synchronization will fail. + +### Limiting Synchronization to Specific Users + +Use the `sync_filter` property in your LDAP provider block to restrict which users get synchronized. +It accepts any valid LDAP search filter, only entries matching that filter will be pulled into the portal's database. + +For example, to import only users with a `mail` attribute: +```yaml +auth: + ldap: + - id: ldap + # ... other settings + sync_filter: (mail=*) +``` + +### Disable Missing Users + +If you set the `disable_missing` property to `true`, any user that is not found in LDAP during synchronization will be disabled in WireGuard Portal. +All peers associated with that user will also be disabled. + +If you want a user and its peers to be automatically re-enabled once they are found in LDAP again, set the `auto_re_enable` property to `true`. +This will only re-enable the user if they where disabled by the synchronization process. Manually disabled users will not be re-enabled. \ No newline at end of file diff --git a/docs/documentation/usage/security.md b/docs/documentation/usage/security.md new file mode 100644 index 0000000..41f36aa --- /dev/null +++ b/docs/documentation/usage/security.md @@ -0,0 +1,160 @@ +This section describes the security features available to administrators for hardening WireGuard Portal and protecting its data. + +## Authentication + +WireGuard Portal supports multiple authentication methods, including: + +- Local user accounts +- LDAP authentication +- OAuth and OIDC authentication +- Passkey authentication (WebAuthn) + +Users can have two roles which limit their permissions in WireGuard Portal: + +- **User**: Can manage their own account and peers. +- **Admin**: Can manage all users and peers, including the ability to manage WireGuard interfaces. + +### Password Security + +WireGuard Portal supports username and password authentication for both local and LDAP-backed accounts. +Local users are stored in the database, while LDAP users are authenticated against an external LDAP server. + +On initial startup, WireGuard Portal automatically creates a local admin account with the password `wgportal-default`. +> :warning: This password must be changed immediately after the first login. + +The minimum password length for all local users can be configured in the [`auth`](../configuration/overview.md#auth) +section of the configuration file. The default value is **16** characters, see [`min_password_length`](../configuration/overview.md#min_password_length). +The minimum password length is also enforced for the default admin user. + + +### Passkey (WebAuthn) Authentication + +Besides the standard authentication mechanisms, WireGuard Portal supports Passkey authentication. +This feature is enabled by default and can be configured in the [`webauthn`](../configuration/overview.md#webauthn-passkeys) section of the configuration file. + +Users can register multiple Passkeys to their account. These Passkeys can be used to log in to the web UI as long as the user is not locked. +> :warning: Passkey authentication does not disable password authentication. The password can still be used to log in (e.g., as a fallback). + +To register a Passkey, open the settings page *(1)* in the web UI and click on the "Register Passkey" *(2)* button. + +![Passkey UI](../../assets/images/passkey_setup.png) + + +### OAuth and OIDC Authentication + +WireGuard Portal supports OAuth and OIDC authentication. You can use any OAuth or OIDC provider that supports the authorization code flow, +such as Google, GitHub, or Keycloak. + +For OAuth or OIDC to work, you need to configure the [`external_url`](../configuration/overview.md#external_url) property in the [`web`](../configuration/overview.md#web) section of the configuration file. +If you are planning to expose the portal to the internet, make sure that the `external_url` is configured to use HTTPS. + +To add OIDC or OAuth authentication to WireGuard Portal, create a Client-ID and Client-Secret in your OAuth provider and +configure a new authentication provider in the [`auth`](../configuration/overview.md#auth) section of the configuration file. +Make sure that each configured provider has a unique `provider_name` property set. Samples can be seen [here](../configuration/examples.md). + +#### Limiting Login to Specific Domains + +You can limit the login to specific domains by setting the `allowed_domains` property for OAuth or OIDC providers. +This property is a comma-separated list of domains that are allowed to log in. The user's email address is checked against this list. +For example, if you want to allow only users with an email address ending in `outlook.com` to log in, set the property as follows: + +```yaml +auth: + oidc: + - provider_name: "oidc1" + # ... other settings + allowed_domains: + - "outlook.com" +``` + +#### Limit Login to Existing Users + +You can limit the login to existing users only by setting the `registration_enabled` property to `false` for OAuth or OIDC providers. +If registration is enabled, new users will be created in the database when they log in for the first time. + +#### Admin Mapping + +You can map users to admin roles based on their attributes in the OAuth or OIDC provider. To do this, set the `admin_mapping` property for the provider. +Administrative access can either be mapped by a specific attribute or by group membership. + +**Attribute specific mapping** can be achieved by setting the `admin_value_regex` and the `is_admin` property. +The `admin_value_regex` property is a regular expression that is matched against the value of the `is_admin` attribute. +The user is granted admin access if the regex matches the attribute value. + +Example: +```yaml +auth: + oidc: + - provider_name: "oidc1" + # ... other settings + field_map: + is_admin: "wg_admin_prop" + admin_mapping: + admin_value_regex: "^true$" +``` +The example above will grant admin access to users with the `wg_admin_prop` attribute set to `true`. + +**Group membership mapping** can be achieved by setting the `admin_group_regex` and `user_groups` property. +The `admin_group_regex` property is a regular expression that is matched against the group names of the user. +The user is granted admin access if the regex matches any of the group names. + +Example: +```yaml +auth: + oidc: + - provider_name: "oidc1" + # ... other settings + field_map: + user_groups: "groups" + admin_mapping: + admin_group_regex: "^the-admin-group$" +``` +The example above will grant admin access to users who are members of the `the-admin-group` group. + + +### LDAP Authentication + +WireGuard Portal supports LDAP authentication. You can use any LDAP server that supports the LDAP protocol, such as Active Directory or OpenLDAP. +Multiple LDAP servers can be configured in the [`auth`](../configuration/overview.md#auth) section of the configuration file. +WireGuard Portal remembers the authentication provider of the user and therefore avoids conflicts between multiple LDAP providers. + +To configure LDAP authentication, create a new [`ldap`](../configuration/overview.md#ldap) authentication provider in the [`auth`](../configuration/overview.md#auth) section of the configuration file. + +#### Limiting Login to Specific Users + +You can limit the login to specific users by setting the `login_filter` property for LDAP provider. This filter uses the LDAP search filter syntax. +The username can be inserted into the query by placing the `{{login_identifier}}` placeholder in the filter. This placeholder will then be replaced with the username entered by the user during login. + +For example, if you want to allow only users with the `objectClass` attribute set to `organizationalPerson` to log in, set the property as follows: + +```yaml +auth: + ldap: + - provider_name: "ldap1" + # ... other settings + login_filter: "(&(objectClass=organizationalPerson)(uid={{login_identifier}}))" +``` + +The `login_filter` should always be designed to return at most one user. + +#### Limit Login to Existing Users + +You can limit the login to existing users only by setting the `registration_enabled` property to `false` for LDAP providers. +If registration is enabled, new users will be created in the database when they log in for the first time. + +#### Admin Mapping + +You can map users to admin roles based on their group membership in the LDAP server. To do this, set the `admin_group` and `memberof` property for the provider. +The `admin_group` property defines the distinguished name of the group that is allowed to log in as admin. +All groups that are listed in the `memberof` attribute of the user will be checked against this group. If one of the groups matches, the user is granted admin access. + + +## UI and API Access + +WireGuard Portal provides a web UI and a REST API for user interaction. It is important to secure these interfaces to prevent unauthorized access and data breaches. + +### HTTPS +It is recommended to use HTTPS for all communication with the portal to prevent eavesdropping. + +Event though, WireGuard Portal supports HTTPS out of the box, it is recommended to use a reverse proxy like Nginx or Traefik to handle SSL termination and other security features. +A detailed explanation is available in the [Reverse Proxy](../getting-started/reverse-proxy.md) section. \ No newline at end of file diff --git a/docs/documentation/usage/webhooks.md b/docs/documentation/usage/webhooks.md new file mode 100644 index 0000000..1d0c692 --- /dev/null +++ b/docs/documentation/usage/webhooks.md @@ -0,0 +1,285 @@ + +Webhooks allow WireGuard Portal to notify external services about events such as user creation, device changes, or configuration updates. This enables integration with other systems and automation workflows. + +When webhooks are configured and a specified event occurs, WireGuard Portal sends an HTTP **POST** request to the configured webhook URL. +The payload contains event-specific data in JSON format. + +## Configuration + +All available configuration options for webhooks can be found in the [configuration overview](../configuration/overview.md#webhook). + +A basic webhook configuration looks like this: + +```yaml +webhook: + url: https://your-service.example.com/webhook +``` + +### Security + +Webhooks can be secured by using a shared secret. This secret is included in the `Authorization` header of the webhook request, allowing your service to verify the authenticity of the request. +You can set the shared secret in the webhook configuration: + +```yaml +webhook: + url: https://your-service.example.com/webhook + secret: "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" +``` + +You should also make sure that your webhook endpoint is secured with HTTPS to prevent eavesdropping and tampering. + +## Available Events + +WireGuard Portal supports various events that can trigger webhooks. The following events are available: + +- `create`: Triggered when a new entity is created. +- `update`: Triggered when an existing entity is updated. +- `delete`: Triggered when an entity is deleted. +- `connect`: Triggered when a user connects to the VPN. +- `disconnect`: Triggered when a user disconnects from the VPN. + +The following entity models are supported for webhook events: + +- `user`: WireGuard Portal users support creation, update, or deletion events. +- `peer`: Peers support creation, update, or deletion events. Via the `peer_metric` entity, you can also receive connection status updates. +- `peer_metric`: Peer metrics support connection status updates, such as when a peer connects or disconnects. +- `interface`: WireGuard interfaces support creation, update, or deletion events. + +## Payload Structure + +All webhook events send a JSON payload containing relevant data. The structure of the payload depends on the event type and entity involved. +A common shell structure for webhook payloads is as follows: + +```json +{ + "event": "create", // The event type, e.g. "create", "update", "delete", "connect", "disconnect" + "entity": "user", // The entity type, e.g. "user", "peer", "peer_metric", "interface" + "identifier": "the-user-identifier", // Unique identifier of the entity, e.g. user ID or peer ID + "payload": { + // The payload of the event, e.g. a Peer model. + // Detailed model descriptions are provided below. + } +} +``` + +### Payload Models + +All payload models are encoded as JSON objects. Fields with empty values might be omitted in the payload. + +#### User Payload (entity: `user`) + +| JSON Field | Type | Description | +|----------------|-------------|-----------------------------------| +| CreatedBy | string | Creator identifier | +| UpdatedBy | string | Last updater identifier | +| CreatedAt | time.Time | Time of creation | +| UpdatedAt | time.Time | Time of last update | +| Identifier | string | Unique user identifier | +| Email | string | User email | +| Source | string | Authentication source | +| ProviderName | string | Name of auth provider | +| IsAdmin | bool | Whether user has admin privileges | +| Firstname | string | User's first name (optional) | +| Lastname | string | User's last name (optional) | +| Phone | string | Contact phone number (optional) | +| Department | string | User's department (optional) | +| Notes | string | Additional notes (optional) | +| Disabled | *time.Time | When user was disabled | +| DisabledReason | string | Reason for deactivation | +| Locked | *time.Time | When user account was locked | +| LockedReason | string | Reason for being locked | + + +#### Peer Payload (entity: `peer`) + +| JSON Field | Type | Description | +|----------------------|------------|----------------------------------------| +| CreatedBy | string | Creator identifier | +| UpdatedBy | string | Last updater identifier | +| CreatedAt | time.Time | Creation timestamp | +| UpdatedAt | time.Time | Last update timestamp | +| Endpoint | string | Peer endpoint address | +| EndpointPublicKey | string | Public key of peer endpoint | +| AllowedIPsStr | string | Allowed IPs | +| ExtraAllowedIPsStr | string | Extra allowed IPs | +| PresharedKey | string | Pre-shared key for encryption | +| PersistentKeepalive | int | Keepalive interval in seconds | +| DisplayName | string | Display name of the peer | +| Identifier | string | Unique identifier | +| UserIdentifier | string | Associated user ID (optional) | +| InterfaceIdentifier | string | Interface this peer is attached to | +| Disabled | *time.Time | When the peer was disabled | +| DisabledReason | string | Reason for being disabled | +| ExpiresAt | *time.Time | Expiration date | +| Notes | string | Notes for this peer | +| AutomaticallyCreated | bool | Whether peer was auto-generated | +| PrivateKey | string | Peer private key | +| PublicKey | string | Peer public key | +| InterfaceType | string | Type of the peer interface | +| Addresses | []string | IP addresses | +| CheckAliveAddress | string | Address used for alive checks | +| DnsStr | string | DNS servers | +| DnsSearchStr | string | DNS search domains | +| Mtu | int | MTU (Maximum Transmission Unit) | +| FirewallMark | uint32 | Firewall mark (optional) | +| RoutingTable | string | Custom routing table (optional) | +| PreUp | string | Command before bringing up interface | +| PostUp | string | Command after bringing up interface | +| PreDown | string | Command before bringing down interface | +| PostDown | string | Command after bringing down interface | + + +#### Interface Payload (entity: `interface`) + +| JSON Field | Type | Description | +|----------------------------|------------|----------------------------------------| +| CreatedBy | string | Creator identifier | +| UpdatedBy | string | Last updater identifier | +| CreatedAt | time.Time | Creation timestamp | +| UpdatedAt | time.Time | Last update timestamp | +| Identifier | string | Unique identifier | +| PrivateKey | string | Private key for the interface | +| PublicKey | string | Public key for the interface | +| ListenPort | int | Listening port | +| Addresses | []string | IP addresses | +| DnsStr | string | DNS servers | +| DnsSearchStr | string | DNS search domains | +| Mtu | int | MTU (Maximum Transmission Unit) | +| FirewallMark | uint32 | Firewall mark | +| RoutingTable | string | Custom routing table | +| PreUp | string | Command before bringing up interface | +| PostUp | string | Command after bringing up interface | +| PreDown | string | Command before bringing down interface | +| PostDown | string | Command after bringing down interface | +| SaveConfig | bool | Whether to save config to file | +| DisplayName | string | Human-readable name | +| Type | string | Type of interface | +| DriverType | string | Driver used | +| Disabled | *time.Time | When the interface was disabled | +| DisabledReason | string | Reason for being disabled | +| PeerDefNetworkStr | string | Default peer network configuration | +| PeerDefDnsStr | string | Default peer DNS servers | +| PeerDefDnsSearchStr | string | Default peer DNS search domains | +| PeerDefEndpoint | string | Default peer endpoint | +| PeerDefAllowedIPsStr | string | Default peer allowed IPs | +| PeerDefMtu | int | Default peer MTU | +| PeerDefPersistentKeepalive | int | Default keepalive value | +| PeerDefFirewallMark | uint32 | Default firewall mark for peers | +| PeerDefRoutingTable | string | Default routing table for peers | +| PeerDefPreUp | string | Default peer pre-up command | +| PeerDefPostUp | string | Default peer post-up command | +| PeerDefPreDown | string | Default peer pre-down command | +| PeerDefPostDown | string | Default peer post-down command | + + +#### Peer Metrics Payload (entity: `peer_metric`) + +| JSON Field | Type | Description | +|------------|------------|----------------------------| +| Status | PeerStatus | Current status of the peer | +| Peer | Peer | Peer data | + +`PeerStatus` sub-structure: + +| JSON Field | Type | Description | +|------------------|------------|------------------------------| +| UpdatedAt | time.Time | Time of last status update | +| IsConnected | bool | Is peer currently connected | +| IsPingable | bool | Can peer be pinged | +| LastPing | *time.Time | Time of last successful ping | +| BytesReceived | uint64 | Bytes received from peer | +| BytesTransmitted | uint64 | Bytes sent to peer | +| Endpoint | string | Last known endpoint | +| LastHandshake | *time.Time | Last successful handshake | +| LastSessionStart | *time.Time | Time the last session began | + + +### Example Payloads + +The following payload is an example of a webhook event when a peer connects to the VPN: + +```json +{ + "event": "connect", + "entity": "peer_metric", + "identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=", + "payload": { + "Status": { + "UpdatedAt": "2025-06-27T22:20:08.734900034+02:00", + "IsConnected": true, + "IsPingable": false, + "BytesReceived": 212, + "BytesTransmitted": 2884, + "Endpoint": "10.55.66.77:58756", + "LastHandshake": "2025-06-27T22:19:46.580842776+02:00", + "LastSessionStart": "2025-06-27T22:19:46.580842776+02:00" + }, + "Peer": { + "CreatedBy": "admin@wgportal.local", + "UpdatedBy": "admin@wgportal.local", + "CreatedAt": "2025-06-26T21:43:49.251839574+02:00", + "UpdatedAt": "2025-06-27T22:18:39.67763985+02:00", + "Endpoint": "10.55.66.1:51820", + "EndpointPublicKey": "eiVibpi3C2PUPcx2kwA5s09OgHx7AEaKMd33k0LQ5mM=", + "AllowedIPsStr": "10.11.12.0/24,fdfd:d3ad:c0de:1234::/64", + "ExtraAllowedIPsStr": "", + "PresharedKey": "p9DDeLUSLOdQcjS8ZsBAiqUzwDIUvTyzavRZFuzhvyE=", + "PersistentKeepalive": 16, + "DisplayName": "Peer Fb5TaziA", + "Identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=", + "UserIdentifier": "admin@wgportal.local", + "InterfaceIdentifier": "wgTesting", + "AutomaticallyCreated": false, + "PrivateKey": "QBFNBe+7J49ergH0ze2TGUJMFrL/2bOL50Z2cgluYW8=", + "PublicKey": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=", + "InterfaceType": "client", + "Addresses": [ + "10.11.12.10/32", + "fdfd:d3ad:c0de:1234::a/128" + ], + "CheckAliveAddress": "", + "DnsStr": "", + "DnsSearchStr": "", + "Mtu": 1420 + } + } +} +``` + +Here is another example of a webhook event when a peer is updated: + +```json +{ + "event": "update", + "entity": "peer", + "identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=", + "payload": { + "CreatedBy": "admin@wgportal.local", + "UpdatedBy": "admin@wgportal.local", + "CreatedAt": "2025-06-26T21:43:49.251839574+02:00", + "UpdatedAt": "2025-06-27T22:18:39.67763985+02:00", + "Endpoint": "10.55.66.1:51820", + "EndpointPublicKey": "eiVibpi3C2PUPcx2kwA5s09OgHx7AEaKMd33k0LQ5mM=", + "AllowedIPsStr": "10.11.12.0/24,fdfd:d3ad:c0de:1234::/64", + "ExtraAllowedIPsStr": "", + "PresharedKey": "p9DDeLUSLOdQcjS8ZsBAiqUzwDIUvTyzavRZFuzhvyE=", + "PersistentKeepalive": 16, + "DisplayName": "Peer Fb5TaziA", + "Identifier": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=", + "UserIdentifier": "admin@wgportal.local", + "InterfaceIdentifier": "wgTesting", + "AutomaticallyCreated": false, + "PrivateKey": "QBFNBe+7J49ergH0ze2TGUJMFrL/2bOL50Z2cgluYW8=", + "PublicKey": "Fb5TaziAs1WrPBjC/MFbWsIelVXvi0hDKZ3YQM9wmU8=", + "InterfaceType": "client", + "Addresses": [ + "10.11.12.10/32", + "fdfd:d3ad:c0de:1234::a/128" + ], + "CheckAliveAddress": "", + "DnsStr": "", + "DnsSearchStr": "", + "Mtu": 1420 + } +} +``` \ No newline at end of file diff --git a/docs/javascript/img-comparison-slider.js b/docs/javascript/img-comparison-slider.js new file mode 100644 index 0000000..2655b62 --- /dev/null +++ b/docs/javascript/img-comparison-slider.js @@ -0,0 +1,2 @@ +(()=>{"use strict";var t={792:(t,e,i)=>{i.d(e,{Z:()=>n});var s=i(609),o=i.n(s)()((function(t){return t[1]}));o.push([t.id,':host{--divider-width: 1px;--divider-color: #fff;--divider-shadow: none;--default-handle-width: 50px;--default-handle-color: #fff;--default-handle-opacity: 1;--default-handle-shadow: none;--handle-position-start: 50%;position:relative;display:inline-block;overflow:hidden;line-height:0;direction:ltr}@media screen and (-webkit-min-device-pixel-ratio: 0)and (min-resolution: 0.001dpcm){:host{outline-offset:1px}}::slotted(*){-webkit-user-drag:none;-khtml-user-drag:none;-moz-user-drag:none;-o-user-drag:none;user-drag:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.first{position:absolute;left:0;top:0;right:0;line-height:normal;font-size:100%;max-height:100%;height:100%;width:100%;--exposure: 50%;--keyboard-transition-time: 0ms;--default-transition-time: 0ms;--transition-time: var(--default-transition-time)}.first .first-overlay-container{position:relative;clip-path:inset(0 var(--exposure) 0 0);transition:clip-path var(--transition-time);height:100%}.first .first-overlay{overflow:hidden;height:100%}.first.focused{will-change:clip-path}.first.focused .first-overlay-container{will-change:clip-path}.second{position:relative}.handle-container{transform:translateX(50%);position:absolute;top:0;right:var(--exposure);height:100%;transition:right var(--transition-time),bottom var(--transition-time)}.focused .handle-container{will-change:right}.divider{position:absolute;height:100%;width:100%;left:0;top:0;display:flex;align-items:center;justify-content:center;flex-direction:column}.divider:after{content:" ";display:block;height:100%;border-left-width:var(--divider-width);border-left-style:solid;border-left-color:var(--divider-color);box-shadow:var(--divider-shadow)}.handle{position:absolute;top:var(--handle-position-start);pointer-events:none;box-sizing:border-box;margin-left:1px;transform:translate(calc(-50% - 0.5px), -50%);line-height:0}.default-handle{width:var(--default-handle-width);opacity:var(--default-handle-opacity);transition:all 1s;filter:drop-shadow(var(--default-handle-shadow))}.default-handle path{stroke:var(--default-handle-color)}.vertical .first-overlay-container{clip-path:inset(0 0 var(--exposure) 0)}.vertical .handle-container{transform:translateY(50%);height:auto;top:unset;bottom:var(--exposure);width:100%;left:0;flex-direction:row}.vertical .divider:after{height:1px;width:100%;border-top-width:var(--divider-width);border-top-style:solid;border-top-color:var(--divider-color);border-left:0}.vertical .handle{top:auto;left:var(--handle-position-start);transform:translate(calc(-50% - 0.5px), -50%) rotate(90deg)}',""]);const n=o},609:t=>{t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var i=t(e);return e[2]?"@media ".concat(e[2]," {").concat(i,"}"):i})).join("")},e.i=function(t,i,s){"string"==typeof t&&(t=[[null,t,""]]);var o={};if(s)for(var n=0;n{var e=t&&t.__esModule?()=>t.default:()=>t;return i.d(e,{a:e}),e},i.d=(t,e)=>{for(var s in e)i.o(e,s)&&!i.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:e[s]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{var t=i(792);const e="rendered",s=(t,e)=>{const i=t.getBoundingClientRect();let s,o;return"mousedown"===e.type?(s=e.clientX,o=e.clientY):(s=e.touches[0].clientX,o=e.touches[0].clientY),s>=i.x&&s<=i.x+i.width&&o>=i.y&&o<=i.y+i.height};let o;const n={ArrowLeft:-1,ArrowRight:1},r=["horizontal","vertical"],a=t=>({x:t.touches[0].pageX,y:t.touches[0].pageY}),d=t=>({x:t.pageX,y:t.pageY}),h="undefined"!=typeof window&&(null===window||void 0===window?void 0:window.HTMLElement);"undefined"!=typeof window&&(window.document&&(o=document.createElement("template"),o.innerHTML='
'),window.customElements.define("img-comparison-slider",class extends h{constructor(){super(),this.exposure=this.hasAttribute("value")?parseFloat(this.getAttribute("value")):50,this.slideOnHover=!1,this.slideDirection="horizontal",this.keyboard="enabled",this.isMouseDown=!1,this.animationDirection=0,this.isFocused=!1,this.dragByHandle=!1,this.onMouseMove=t=>{if(this.isMouseDown||this.slideOnHover){const e=d(t);this.slideToPage(e)}},this.bodyUserSelectStyle="",this.bodyWebkitUserSelectStyle="",this.onMouseDown=t=>{if(this.slideOnHover)return;if(this.handle&&!s(this.handleElement,t))return;t.preventDefault(),window.addEventListener("mousemove",this.onMouseMove),window.addEventListener("mouseup",this.onWindowMouseUp),this.isMouseDown=!0,this.enableTransition();const e=d(t);this.slideToPage(e),this.focus(),this.bodyUserSelectStyle=window.document.body.style.userSelect,this.bodyWebkitUserSelectStyle=window.document.body.style.webkitUserSelect,window.document.body.style.userSelect="none",window.document.body.style.webkitUserSelect="none"},this.onWindowMouseUp=()=>{this.isMouseDown=!1,window.document.body.style.userSelect=this.bodyUserSelectStyle,window.document.body.style.webkitUserSelect=this.bodyWebkitUserSelectStyle,window.removeEventListener("mousemove",this.onMouseMove),window.removeEventListener("mouseup",this.onWindowMouseUp)},this.touchStartPoint=null,this.isTouchComparing=!1,this.hasTouchMoved=!1,this.onTouchStart=t=>{this.dragByHandle&&!s(this.handleElement,t)||(this.touchStartPoint=a(t),this.isFocused&&(this.enableTransition(),this.slideToPage(this.touchStartPoint)))},this.onTouchMove=t=>{if(null===this.touchStartPoint)return;const e=a(t);if(this.isTouchComparing)return this.slideToPage(e),t.preventDefault(),!1;if(!this.hasTouchMoved){const i=Math.abs(e.y-this.touchStartPoint.y),s=Math.abs(e.x-this.touchStartPoint.x);if("horizontal"===this.slideDirection&&is)return this.isTouchComparing=!0,this.focus(),this.slideToPage(e),t.preventDefault(),!1;this.hasTouchMoved=!0}},this.onTouchEnd=()=>{this.isTouchComparing=!1,this.hasTouchMoved=!1,this.touchStartPoint=null},this.onBlur=()=>{this.stopSlideAnimation(),this.isFocused=!1,this.firstElement.classList.remove("focused")},this.onFocus=()=>{this.isFocused=!0,this.firstElement.classList.add("focused")},this.onKeyDown=t=>{if("disabled"===this.keyboard)return;const e=n[t.key];this.animationDirection!==e&&void 0!==e&&(this.animationDirection=e,this.startSlideAnimation())},this.onKeyUp=t=>{if("disabled"===this.keyboard)return;const e=n[t.key];void 0!==e&&this.animationDirection===e&&this.stopSlideAnimation()},this.resetDimensions=()=>{this.imageWidth=this.offsetWidth,this.imageHeight=this.offsetHeight};const e=this.attachShadow({mode:"open"}),i=document.createElement("style");i.innerHTML=t.Z,this.getAttribute("nonce")&&i.setAttribute("nonce",this.getAttribute("nonce")),e.appendChild(i),e.appendChild(o.content.cloneNode(!0)),this.firstElement=e.getElementById("first"),this.handleElement=e.getElementById("handle")}set handle(t){this.dragByHandle="false"!==t.toString().toLowerCase()}get handle(){return this.dragByHandle}get value(){return this.exposure}set value(t){const e=parseFloat(t);e!==this.exposure&&(this.exposure=e,this.enableTransition(),this.setExposure())}get hover(){return this.slideOnHover}set hover(t){this.slideOnHover="false"!==t.toString().toLowerCase(),this.removeEventListener("mousemove",this.onMouseMove),this.slideOnHover&&this.addEventListener("mousemove",this.onMouseMove)}get direction(){return this.slideDirection}set direction(t){this.slideDirection=t.toString().toLowerCase(),this.slide(0),this.firstElement.classList.remove(...r),r.includes(this.slideDirection)&&this.firstElement.classList.add(this.slideDirection)}static get observedAttributes(){return["hover","direction"]}connectedCallback(){this.hasAttribute("tabindex")||(this.tabIndex=0),this.addEventListener("dragstart",(t=>(t.preventDefault(),!1))),new ResizeObserver(this.resetDimensions).observe(this),this.setExposure(0),this.keyboard=this.hasAttribute("keyboard")&&"disabled"===this.getAttribute("keyboard")?"disabled":"enabled",this.addEventListener("keydown",this.onKeyDown),this.addEventListener("keyup",this.onKeyUp),this.addEventListener("focus",this.onFocus),this.addEventListener("blur",this.onBlur),this.addEventListener("touchstart",this.onTouchStart,{passive:!0}),this.addEventListener("touchmove",this.onTouchMove,{passive:!1}),this.addEventListener("touchend",this.onTouchEnd),this.addEventListener("mousedown",this.onMouseDown),this.handle=this.hasAttribute("handle")?this.getAttribute("handle"):this.dragByHandle,this.hover=this.hasAttribute("hover")?this.getAttribute("hover"):this.slideOnHover,this.direction=this.hasAttribute("direction")?this.getAttribute("direction"):this.slideDirection,this.resetDimensions(),this.classList.contains(e)||this.classList.add(e)}disconnectedCallback(){this.transitionTimer&&window.clearTimeout(this.transitionTimer)}attributeChangedCallback(t,e,i){"hover"===t&&(this.hover=i),"direction"===t&&(this.direction=i),"keyboard"===t&&(this.keyboard="disabled"===i?"disabled":"enabled")}setExposure(t=0){var e;this.exposure=(100,(e=this.exposure+t)<0?0:e>100?100:e),this.firstElement.style.setProperty("--exposure",100-this.exposure+"%")}slide(t=0){this.setExposure(t);const e=new Event("slide");this.dispatchEvent(e)}slideToPage(t){"horizontal"===this.slideDirection&&this.slideToPageX(t.x),"vertical"===this.slideDirection&&this.slideToPageY(t.y)}slideToPageX(t){const e=t-this.getBoundingClientRect().left-window.scrollX;this.exposure=e/this.imageWidth*100,this.slide(0)}slideToPageY(t){const e=t-this.getBoundingClientRect().top-window.scrollY;this.exposure=e/this.imageHeight*100,this.slide(0)}enableTransition(){this.firstElement.style.setProperty("--transition-time","100ms"),this.transitionTimer=window.setTimeout((()=>{this.firstElement.style.setProperty("--transition-time","var(--default-transition-time)"),this.transitionTimer=null}),100)}startSlideAnimation(){let t=null,e=this.animationDirection;this.firstElement.style.setProperty("--transition-time","var(--keyboard-transition-time)");const i=s=>{if(0===this.animationDirection||e!==this.animationDirection)return;null===t&&(t=s);const o=(s-t)/16.666666666666668*this.animationDirection;this.slide(o),setTimeout((()=>window.requestAnimationFrame(i)),0),t=s};window.requestAnimationFrame(i)}stopSlideAnimation(){this.animationDirection=0,this.firstElement.style.setProperty("--transition-time","var(--default-transition-time)")}}))})()})(); +//# sourceMappingURL=img-comparison-slider.js.map \ No newline at end of file diff --git a/docs/javascript/img-comparison-slider.js.map b/docs/javascript/img-comparison-slider.js.map new file mode 100644 index 0000000..d6cfc6f --- /dev/null +++ b/docs/javascript/img-comparison-slider.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","mappings":"sEAEIA,E,MAA0B,IAA4B,SAASC,GAAG,OAAOA,EAAE,EAAE,IAEjFD,EAAwBE,KAAK,CAACC,EAAOC,GAAI,spFAAypF,KAElsF,S,UCEAD,EAAOE,QAAU,SAAUC,GACzB,IAAIC,EAAO,GAuDX,OArDAA,EAAKC,SAAW,WACd,OAAOC,KAAKC,KAAI,SAAUC,GACxB,IAAIC,EAAUN,EAAuBK,GAErC,OAAIA,EAAK,GACA,UAAUE,OAAOF,EAAK,GAAI,MAAME,OAAOD,EAAS,KAGlDA,CACT,IAAGE,KAAK,GACV,EAIAP,EAAKN,EAAI,SAAUc,EAASC,EAAYC,GACf,iBAAZF,IAETA,EAAU,CAAC,CAAC,KAAMA,EAAS,MAG7B,IAAIG,EAAyB,CAAC,EAE9B,GAAID,EACF,IAAK,IAAIhB,EAAI,EAAGA,EAAIQ,KAAKU,OAAQlB,IAAK,CAEpC,IAAIG,EAAKK,KAAKR,GAAG,GAEP,MAANG,IACFc,EAAuBd,IAAM,EAEjC,CAGF,IAAK,IAAIgB,EAAK,EAAGA,EAAKL,EAAQI,OAAQC,IAAM,CAC1C,IAAIT,EAAO,GAAGE,OAAOE,EAAQK,IAEzBH,GAAUC,EAAuBP,EAAK,MAKtCK,IACGL,EAAK,GAGRA,EAAK,GAAK,GAAGE,OAAOG,EAAY,SAASH,OAAOF,EAAK,IAFrDA,EAAK,GAAKK,GAMdT,EAAKL,KAAKS,GACZ,CACF,EAEOJ,CACT,C,GChEIc,EAA2B,CAAC,EAGhC,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBE,IAAjBD,EACH,OAAOA,EAAanB,QAGrB,IAAIF,EAASkB,EAAyBE,GAAY,CACjDnB,GAAImB,EAEJlB,QAAS,CAAC,GAOX,OAHAqB,EAAoBH,GAAUpB,EAAQA,EAAOE,QAASiB,GAG/CnB,EAAOE,OACf,CCrBAiB,EAAoBK,EAAKxB,IACxB,IAAIyB,EAASzB,GAAUA,EAAO0B,WAC7B,IAAO1B,EAAiB,QACxB,IAAM,EAEP,OADAmB,EAAoBQ,EAAEF,EAAQ,CAAEG,EAAGH,IAC5BA,CAAM,ECLdN,EAAoBQ,EAAI,CAACzB,EAAS2B,KACjC,IAAI,IAAIC,KAAOD,EACXV,EAAoBY,EAAEF,EAAYC,KAASX,EAAoBY,EAAE7B,EAAS4B,IAC5EE,OAAOC,eAAe/B,EAAS4B,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,IAE1E,ECNDX,EAAoBY,EAAI,CAACK,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,G,mBCGlF,MCFaI,EAAiB,WCEjBC,EAAoB,CAACC,EAASC,KACvC,MAAMC,EAAOF,EAAQG,wBACrB,IAAIC,EAAQC,EASZ,MAbsB,cAKLJ,EALJK,MAMTF,EAASH,EAAEM,QACXF,EAASJ,EAAEO,UAGXJ,EAASH,EAAEQ,QAAQ,GAAGF,QACtBF,EAASJ,EAAEQ,QAAQ,GAAGD,SAElBJ,GAAUF,EAAKQ,GACnBN,GAAUF,EAAKQ,EAAIR,EAAKS,OACxBN,GAAUH,EAAKU,GACfP,GAAUH,EAAKU,EAAIV,EAAKW,MAAO,ECZvC,IAAIC,EACJ,MAAMC,EAAiB,CACnBC,WAAY,EACZC,WAAY,GAEVC,EAAkB,CAAC,aAAc,YACjCC,EAAqBlB,IAAM,CAC7BS,EAAGT,EAAEQ,QAAQ,GAAGW,MAChBR,EAAGX,EAAEQ,QAAQ,GAAGY,QAEdC,EAAqBrB,IAAM,CAC7BS,EAAGT,EAAEmB,MACLR,EAAGX,EAAEoB,QAGHE,EAAgC,oBAAXC,SAAsC,OAAXA,aAA8B,IAAXA,YAAoB,EAASA,OAAOD,aAiTvF,oBAAXC,SACHA,OAAOC,WACPX,EAAkBW,SAASC,cAAc,YACzCZ,EAAgBa,UHvUb,8mBGyUPH,OAAOI,eAAeC,OAAO,wBArT1B,cAA6CN,EAChDO,cACIC,QACApE,KAAKqE,SAAWrE,KAAKsE,aAAa,SAC5BC,WAAWvE,KAAKwE,aAAa,UAC7B,GACNxE,KAAKyE,cAAe,EACpBzE,KAAK0E,eAAiB,aACtB1E,KAAK2E,SAAW,UAChB3E,KAAK4E,aAAc,EACnB5E,KAAK6E,mBAAqB,EAC1B7E,KAAK8E,WAAY,EACjB9E,KAAK+E,cAAe,EACpB/E,KAAKgF,YAAe1C,IAChB,GAAItC,KAAK4E,aAAe5E,KAAKyE,aAAc,CACvC,MAAMQ,EAAetB,EAAkBrB,GACvCtC,KAAKkF,YAAYD,EACrB,GAEJjF,KAAKmF,oBAAsB,GAC3BnF,KAAKoF,0BAA4B,GACjCpF,KAAKqF,YAAe/C,IAChB,GAAItC,KAAKyE,aACL,OAEJ,GAAIzE,KAAKsF,SAAWlD,EAAkBpC,KAAKuF,cAAejD,GACtD,OAEJA,EAAEkD,iBACF3B,OAAO4B,iBAAiB,YAAazF,KAAKgF,aAC1CnB,OAAO4B,iBAAiB,UAAWzF,KAAK0F,iBACxC1F,KAAK4E,aAAc,EACnB5E,KAAK2F,mBACL,MAAMV,EAAetB,EAAkBrB,GACvCtC,KAAKkF,YAAYD,GACjBjF,KAAK4F,QACL5F,KAAKmF,oBAAsBtB,OAAOC,SAAS+B,KAAKC,MAAMC,WACtD/F,KAAKoF,0BACDvB,OAAOC,SAAS+B,KAAKC,MAAME,iBAC/BnC,OAAOC,SAAS+B,KAAKC,MAAMC,WAAa,OACxClC,OAAOC,SAAS+B,KAAKC,MAAME,iBAAmB,MAAM,EAExDhG,KAAK0F,gBAAkB,KACnB1F,KAAK4E,aAAc,EACnBf,OAAOC,SAAS+B,KAAKC,MAAMC,WAAa/F,KAAKmF,oBAC7CtB,OAAOC,SAAS+B,KAAKC,MAAME,iBACvBhG,KAAKoF,0BACTvB,OAAOoC,oBAAoB,YAAajG,KAAKgF,aAC7CnB,OAAOoC,oBAAoB,UAAWjG,KAAK0F,gBAAgB,EAE/D1F,KAAKkG,gBAAkB,KACvBlG,KAAKmG,kBAAmB,EACxBnG,KAAKoG,eAAgB,EACrBpG,KAAKqG,aAAgB/D,IACbtC,KAAK+E,eAAiB3C,EAAkBpC,KAAKuF,cAAejD,KAGhEtC,KAAKkG,gBAAkB1C,EAAkBlB,GACrCtC,KAAK8E,YACL9E,KAAK2F,mBACL3F,KAAKkF,YAAYlF,KAAKkG,kBAC1B,EAEJlG,KAAKsG,YAAehE,IAChB,GAA6B,OAAzBtC,KAAKkG,gBACL,OAEJ,MAAMjB,EAAezB,EAAkBlB,GACvC,GAAItC,KAAKmG,iBAGL,OAFAnG,KAAKkF,YAAYD,GACjB3C,EAAEkD,kBACK,EAEX,IAAKxF,KAAKoG,cAAe,CACrB,MAAMG,EAAUC,KAAKC,IAAIxB,EAAahC,EAAIjD,KAAKkG,gBAAgBjD,GACzDyD,EAAUF,KAAKC,IAAIxB,EAAalC,EAAI/C,KAAKkG,gBAAgBnD,GAC/D,GAA6B,eAAxB/C,KAAK0E,gBAAmC6B,EAAUG,GAC1B,aAAxB1G,KAAK0E,gBAAiC6B,EAAUG,EAKjD,OAJA1G,KAAKmG,kBAAmB,EACxBnG,KAAK4F,QACL5F,KAAKkF,YAAYD,GACjB3C,EAAEkD,kBACK,EAEXxF,KAAKoG,eAAgB,CACzB,GAEJpG,KAAK2G,WAAa,KACd3G,KAAKmG,kBAAmB,EACxBnG,KAAKoG,eAAgB,EACrBpG,KAAKkG,gBAAkB,IAAI,EAE/BlG,KAAK4G,OAAS,KACV5G,KAAK6G,qBACL7G,KAAK8E,WAAY,EACjB9E,KAAK8G,aAAaC,UAAUC,OAAO,UAAU,EAEjDhH,KAAKiH,QAAU,KACXjH,KAAK8E,WAAY,EACjB9E,KAAK8G,aAAaC,UAAUG,IAAI,UAAU,EAE9ClH,KAAKmH,UAAa7E,IACd,GAAsB,aAAlBtC,KAAK2E,SACL,OAEJ,MAAMyC,EAAYhE,EAAed,EAAEd,KAC/BxB,KAAK6E,qBAAuBuC,QAGdpG,IAAdoG,IAGJpH,KAAK6E,mBAAqBuC,EAC1BpH,KAAKqH,sBAAqB,EAE9BrH,KAAKsH,QAAWhF,IACZ,GAAsB,aAAlBtC,KAAK2E,SACL,OAEJ,MAAMyC,EAAYhE,EAAed,EAAEd,UACjBR,IAAdoG,GAGApH,KAAK6E,qBAAuBuC,GAGhCpH,KAAK6G,oBAAoB,EAE7B7G,KAAKuH,gBAAkB,KACnBvH,KAAKwH,WAAaxH,KAAKyH,YACvBzH,KAAK0H,YAAc1H,KAAK2H,YAAY,EAExC,MAAMC,EAAa5H,KAAK6H,aAAa,CAAEC,KAAM,SACvCC,EAAUjE,SAASC,cAAc,SACvCgE,EAAQ/D,UAAYgE,EAAA,EAChBhI,KAAKwE,aAAa,UAClBuD,EAAQE,aAAa,QAASjI,KAAKwE,aAAa,UAEpDoD,EAAWM,YAAYH,GACvBH,EAAWM,YAAY/E,EAAgBhD,QAAQgI,WAAU,IACzDnI,KAAK8G,aAAec,EAAWQ,eAAe,SAC9CpI,KAAKuF,cAAgBqC,EAAWQ,eAAe,SACnD,CACI9C,WAAO+C,GACPrI,KAAK+E,aAAqD,UAAtCsD,EAAStI,WAAWuI,aAC5C,CACIhD,aACA,OAAOtF,KAAK+E,YAChB,CACIwD,YACA,OAAOvI,KAAKqE,QAChB,CACIkE,UAAMF,GACN,MAAMG,EAAcjE,WAAW8D,GAC3BG,IAAgBxI,KAAKqE,WAGzBrE,KAAKqE,SAAWmE,EAChBxI,KAAK2F,mBACL3F,KAAKyI,cACT,CACIC,YACA,OAAO1I,KAAKyE,YAChB,CACIiE,UAAML,GACNrI,KAAKyE,aAAqD,UAAtC4D,EAAStI,WAAWuI,cACxCtI,KAAKiG,oBAAoB,YAAajG,KAAKgF,aACvChF,KAAKyE,cACLzE,KAAKyF,iBAAiB,YAAazF,KAAKgF,YAEhD,CACIoC,gBACA,OAAOpH,KAAK0E,cAChB,CACI0C,cAAUiB,GACVrI,KAAK0E,eAAiB2D,EAAStI,WAAWuI,cAC1CtI,KAAK2I,MAAM,GACX3I,KAAK8G,aAAaC,UAAUC,UAAUzD,GACjCA,EAAgBqF,SAAS5I,KAAK0E,iBAGnC1E,KAAK8G,aAAaC,UAAUG,IAAIlH,KAAK0E,eACzC,CACWmE,gCACP,MAAO,CAAC,QAAS,YACrB,CACAC,oBACS9I,KAAKsE,aAAa,cACnBtE,KAAK+I,SFjNO,GEmNhB/I,KAAKyF,iBAAiB,aAAcnD,IAChCA,EAAEkD,kBACK,KAEY,IAAIwD,eAAehJ,KAAKuH,iBAChC0B,QAAQjJ,MACvBA,KAAKyI,YAAY,GACjBzI,KAAK2E,SACD3E,KAAKsE,aAAa,aACoB,aAAlCtE,KAAKwE,aAAa,YAChB,WACA,UACVxE,KAAKyF,iBAAiB,UAAWzF,KAAKmH,WACtCnH,KAAKyF,iBAAiB,QAASzF,KAAKsH,SACpCtH,KAAKyF,iBAAiB,QAASzF,KAAKiH,SACpCjH,KAAKyF,iBAAiB,OAAQzF,KAAK4G,QACnC5G,KAAKyF,iBAAiB,aAAczF,KAAKqG,aAAc,CACnD6C,SAAS,IAEblJ,KAAKyF,iBAAiB,YAAazF,KAAKsG,YAAa,CACjD4C,SAAS,IAEblJ,KAAKyF,iBAAiB,WAAYzF,KAAK2G,YACvC3G,KAAKyF,iBAAiB,YAAazF,KAAKqF,aACxCrF,KAAKsF,OAAStF,KAAKsE,aAAa,UAC1BtE,KAAKwE,aAAa,UAClBxE,KAAK+E,aACX/E,KAAK0I,MAAQ1I,KAAKsE,aAAa,SACzBtE,KAAKwE,aAAa,SAClBxE,KAAKyE,aACXzE,KAAKoH,UAAYpH,KAAKsE,aAAa,aAC7BtE,KAAKwE,aAAa,aAClBxE,KAAK0E,eACX1E,KAAKuH,kBACAvH,KAAK+G,UAAUoC,SAAShH,IACzBnC,KAAK+G,UAAUG,IAAI/E,EAE3B,CACAiH,uBACQpJ,KAAKqJ,iBACLxF,OAAOyF,aAAatJ,KAAKqJ,gBAEjC,CACAE,yBAAyBC,EAAMC,EAAUpB,GACxB,UAATmB,IACAxJ,KAAK0I,MAAQL,GAEJ,cAATmB,IACAxJ,KAAKoH,UAAYiB,GAER,aAATmB,IACAxJ,KAAK2E,SAAwB,aAAb0D,EAA0B,WAAa,UAE/D,CACAI,YAAYiB,EAAY,GCzQH,IAACC,ED0QlB3J,KAAKqE,UAAmD,KC1QtCsF,ED0QQ3J,KAAKqE,SAAWqF,GAAW,ICtQrDC,EDsQwD,QCnQrDA,GDoQH3J,KAAK8G,aAAahB,MAAM8D,YAAY,aAAiB,IAAM5J,KAAKqE,SAAd,IACtD,CACAsE,MAAMe,EAAY,GACd1J,KAAKyI,YAAYiB,GACjB,MAAMG,EAAQ,IAAIC,MAAM,SACxB9J,KAAK+J,cAAcF,EACvB,CACA3E,YAAYD,GACoB,eAAxBjF,KAAK0E,gBACL1E,KAAKgK,aAAa/E,EAAalC,GAEP,aAAxB/C,KAAK0E,gBACL1E,KAAKiK,aAAahF,EAAahC,EAEvC,CACA+G,aAAavG,GACT,MAAMV,EAAIU,EAAQzD,KAAKwC,wBAAwB0H,KAAOrG,OAAOsG,QAC7DnK,KAAKqE,SAAYtB,EAAI/C,KAAKwH,WAAc,IACxCxH,KAAK2I,MAAM,EACf,CACAsB,aAAavG,GACT,MAAMT,EAAIS,EAAQ1D,KAAKwC,wBAAwB4H,IAAMvG,OAAOwG,QAC5DrK,KAAKqE,SAAYpB,EAAIjD,KAAK0H,YAAe,IACzC1H,KAAK2I,MAAM,EACf,CACAhD,mBAEI3F,KAAK8G,aAAahB,MAAM8D,YAAY,oBAAqB,SACzD5J,KAAKqJ,gBAAkBxF,OAAOyG,YAAW,KACrCtK,KAAK8G,aAAahB,MAAM8D,YAAY,oBAAqB,kCACzD5J,KAAKqJ,gBAAkB,IAAI,GAJR,IAM3B,CACAhC,sBACI,IAAIkD,EAAgB,KAChBC,EAAmBxK,KAAK6E,mBAC5B7E,KAAK8G,aAAahB,MAAM8D,YAAY,oBAAqB,mCACzD,MAAMjB,EAAS8B,IACX,GAAgC,IAA5BzK,KAAK6E,oBACL2F,IAAqBxK,KAAK6E,mBAC1B,OAEkB,OAAlB0F,IACAA,EAAgBE,GAEpB,MAAsCC,GAArBD,EAAMF,GArSN,mBAqSoEvK,KAAK6E,mBAC1F7E,KAAK2I,MAAM+B,GAEXJ,YAAW,IAAMzG,OAAO8G,sBAAsBhC,IAAQ,GACtD4B,EAAgBE,CAAG,EAEvB5G,OAAO8G,sBAAsBhC,EACjC,CACA9B,qBACI7G,KAAK6E,mBAAqB,EAC1B7E,KAAK8G,aAAahB,MAAM8D,YAAY,oBAAqB,iCAC7D,I","sources":["webpack://img-comparison-slider/./src/styles.scss","webpack://img-comparison-slider/../../node_modules/css-loader/dist/runtime/api.js","webpack://img-comparison-slider/webpack/bootstrap","webpack://img-comparison-slider/webpack/runtime/compat get default export","webpack://img-comparison-slider/webpack/runtime/define property getters","webpack://img-comparison-slider/webpack/runtime/hasOwnProperty shorthand","webpack://img-comparison-slider/./src/template.html","webpack://img-comparison-slider/./src/defaults.ts","webpack://img-comparison-slider/./src/isElementAffected.ts","webpack://img-comparison-slider/./src/index.ts","webpack://img-comparison-slider/./src/inBetween.ts"],"sourcesContent":["// Imports\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(function(i){return i[1]});\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \":host{--divider-width: 1px;--divider-color: #fff;--divider-shadow: none;--default-handle-width: 50px;--default-handle-color: #fff;--default-handle-opacity: 1;--default-handle-shadow: none;--handle-position-start: 50%;position:relative;display:inline-block;overflow:hidden;line-height:0;direction:ltr}@media screen and (-webkit-min-device-pixel-ratio: 0)and (min-resolution: 0.001dpcm){:host{outline-offset:1px}}:host(:focus){outline:2px solid -webkit-focus-ring-color}::slotted(*){-webkit-user-drag:none;-khtml-user-drag:none;-moz-user-drag:none;-o-user-drag:none;user-drag:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.first{position:absolute;left:0;top:0;right:0;line-height:normal;font-size:100%;max-height:100%;height:100%;width:100%;--exposure: 50%;--keyboard-transition-time: 0ms;--default-transition-time: 0ms;--transition-time: var(--default-transition-time)}.first .first-overlay-container{position:relative;clip-path:inset(0 var(--exposure) 0 0);transition:clip-path var(--transition-time);height:100%}.first .first-overlay{overflow:hidden;height:100%}.first.focused{will-change:clip-path}.first.focused .first-overlay-container{will-change:clip-path}.second{position:relative}.handle-container{transform:translateX(50%);position:absolute;top:0;right:var(--exposure);height:100%;transition:right var(--transition-time),bottom var(--transition-time)}.focused .handle-container{will-change:right}.divider{position:absolute;height:100%;width:100%;left:0;top:0;display:flex;align-items:center;justify-content:center;flex-direction:column}.divider:after{content:\\\" \\\";display:block;height:100%;border-left-width:var(--divider-width);border-left-style:solid;border-left-color:var(--divider-color);box-shadow:var(--divider-shadow)}.handle{position:absolute;top:var(--handle-position-start);pointer-events:none;box-sizing:border-box;margin-left:1px;transform:translate(calc(-50% - 0.5px), -50%);line-height:0}.default-handle{width:var(--default-handle-width);opacity:var(--default-handle-opacity);transition:all 1s;filter:drop-shadow(var(--default-handle-shadow))}.default-handle path{stroke:var(--default-handle-color)}.vertical .first-overlay-container{clip-path:inset(0 0 var(--exposure) 0)}.vertical .handle-container{transform:translateY(50%);height:auto;top:unset;bottom:var(--exposure);width:100%;left:0;flex-direction:row}.vertical .divider:after{height:1px;width:100%;border-top-width:var(--divider-width);border-top-style:solid;border-top-color:var(--divider-color);border-left:0}.vertical .handle{top:auto;left:var(--handle-position-start);transform:translate(calc(-50% - 0.5px), -50%) rotate(90deg)}\", \"\"]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\n// eslint-disable-next-line func-names\nmodule.exports = function (cssWithMappingToString) {\n var list = []; // return the list of modules as css string\n\n list.toString = function toString() {\n return this.map(function (item) {\n var content = cssWithMappingToString(item);\n\n if (item[2]) {\n return \"@media \".concat(item[2], \" {\").concat(content, \"}\");\n }\n\n return content;\n }).join(\"\");\n }; // import a list of modules into the list\n // eslint-disable-next-line func-names\n\n\n list.i = function (modules, mediaQuery, dedupe) {\n if (typeof modules === \"string\") {\n // eslint-disable-next-line no-param-reassign\n modules = [[null, modules, \"\"]];\n }\n\n var alreadyImportedModules = {};\n\n if (dedupe) {\n for (var i = 0; i < this.length; i++) {\n // eslint-disable-next-line prefer-destructuring\n var id = this[i][0];\n\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n\n for (var _i = 0; _i < modules.length; _i++) {\n var item = [].concat(modules[_i]);\n\n if (dedupe && alreadyImportedModules[item[0]]) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (mediaQuery) {\n if (!item[2]) {\n item[2] = mediaQuery;\n } else {\n item[2] = \"\".concat(mediaQuery, \" and \").concat(item[2]);\n }\n }\n\n list.push(item);\n }\n };\n\n return list;\n};","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// Module\nvar code = \"
\";\n// Exports\nexport default code;","export const TABINDEX = 0;\nexport const RENDERED_CLASS = 'rendered';\n","export const isMouseEvent = (event) => {\n return event.type === 'mousedown';\n};\nexport const isElementAffected = (element, e) => {\n const rect = element.getBoundingClientRect();\n let eventX, eventY;\n if (isMouseEvent(e)) {\n eventX = e.clientX;\n eventY = e.clientY;\n }\n else {\n eventX = e.touches[0].clientX;\n eventY = e.touches[0].clientY;\n }\n return (eventX >= rect.x &&\n eventX <= rect.x + rect.width &&\n eventY >= rect.y &&\n eventY <= rect.y + rect.height);\n};\n","import styles from './styles.scss';\nimport { inBetween } from './inBetween';\nimport templateHtml from './template.html';\nimport { TABINDEX, RENDERED_CLASS } from './defaults';\nimport { isElementAffected } from './isElementAffected';\nlet templateElement;\nconst KeySlideOffset = {\n ArrowLeft: -1,\n ArrowRight: 1,\n};\nconst slideDirections = ['horizontal', 'vertical'];\nconst getTouchPagePoint = (e) => ({\n x: e.touches[0].pageX,\n y: e.touches[0].pageY,\n});\nconst getMousePagePoint = (e) => ({\n x: e.pageX,\n y: e.pageY,\n});\nconst slideAnimationPeriod = 1000 / 60;\nconst HTMLElement = typeof window !== 'undefined' && (window === null || window === void 0 ? void 0 : window.HTMLElement);\nexport class HTMLImgComparisonSliderElement extends HTMLElement {\n constructor() {\n super();\n this.exposure = this.hasAttribute('value')\n ? parseFloat(this.getAttribute('value'))\n : 50;\n this.slideOnHover = false;\n this.slideDirection = 'horizontal';\n this.keyboard = 'enabled';\n this.isMouseDown = false;\n this.animationDirection = 0;\n this.isFocused = false;\n this.dragByHandle = false;\n this.onMouseMove = (e) => {\n if (this.isMouseDown || this.slideOnHover) {\n const currentPoint = getMousePagePoint(e);\n this.slideToPage(currentPoint);\n }\n };\n this.bodyUserSelectStyle = '';\n this.bodyWebkitUserSelectStyle = '';\n this.onMouseDown = (e) => {\n if (this.slideOnHover) {\n return;\n }\n if (this.handle && !isElementAffected(this.handleElement, e)) {\n return;\n }\n e.preventDefault();\n window.addEventListener('mousemove', this.onMouseMove);\n window.addEventListener('mouseup', this.onWindowMouseUp);\n this.isMouseDown = true;\n this.enableTransition();\n const currentPoint = getMousePagePoint(e);\n this.slideToPage(currentPoint);\n this.focus();\n this.bodyUserSelectStyle = window.document.body.style.userSelect;\n this.bodyWebkitUserSelectStyle =\n window.document.body.style.webkitUserSelect;\n window.document.body.style.userSelect = 'none';\n window.document.body.style.webkitUserSelect = 'none';\n };\n this.onWindowMouseUp = () => {\n this.isMouseDown = false;\n window.document.body.style.userSelect = this.bodyUserSelectStyle;\n window.document.body.style.webkitUserSelect =\n this.bodyWebkitUserSelectStyle;\n window.removeEventListener('mousemove', this.onMouseMove);\n window.removeEventListener('mouseup', this.onWindowMouseUp);\n };\n this.touchStartPoint = null;\n this.isTouchComparing = false;\n this.hasTouchMoved = false;\n this.onTouchStart = (e) => {\n if (this.dragByHandle && !isElementAffected(this.handleElement, e)) {\n return;\n }\n this.touchStartPoint = getTouchPagePoint(e);\n if (this.isFocused) {\n this.enableTransition();\n this.slideToPage(this.touchStartPoint);\n }\n };\n this.onTouchMove = (e) => {\n if (this.touchStartPoint === null) {\n return;\n }\n const currentPoint = getTouchPagePoint(e);\n if (this.isTouchComparing) {\n this.slideToPage(currentPoint);\n e.preventDefault();\n return false;\n }\n if (!this.hasTouchMoved) {\n const offsetY = Math.abs(currentPoint.y - this.touchStartPoint.y);\n const offsetX = Math.abs(currentPoint.x - this.touchStartPoint.x);\n if ((this.slideDirection === 'horizontal' && offsetY < offsetX) ||\n (this.slideDirection === 'vertical' && offsetY > offsetX)) {\n this.isTouchComparing = true;\n this.focus();\n this.slideToPage(currentPoint);\n e.preventDefault();\n return false;\n }\n this.hasTouchMoved = true;\n }\n };\n this.onTouchEnd = () => {\n this.isTouchComparing = false;\n this.hasTouchMoved = false;\n this.touchStartPoint = null;\n };\n this.onBlur = () => {\n this.stopSlideAnimation();\n this.isFocused = false;\n this.firstElement.classList.remove('focused');\n };\n this.onFocus = () => {\n this.isFocused = true;\n this.firstElement.classList.add('focused');\n };\n this.onKeyDown = (e) => {\n if (this.keyboard === 'disabled') {\n return;\n }\n const direction = KeySlideOffset[e.key];\n if (this.animationDirection === direction) {\n return;\n }\n if (direction === undefined) {\n return;\n }\n this.animationDirection = direction;\n this.startSlideAnimation();\n };\n this.onKeyUp = (e) => {\n if (this.keyboard === 'disabled') {\n return;\n }\n const direction = KeySlideOffset[e.key];\n if (direction === undefined) {\n return;\n }\n if (this.animationDirection !== direction) {\n return;\n }\n this.stopSlideAnimation();\n };\n this.resetDimensions = () => {\n this.imageWidth = this.offsetWidth;\n this.imageHeight = this.offsetHeight;\n };\n const shadowRoot = this.attachShadow({ mode: 'open' });\n const styleEl = document.createElement('style');\n styleEl.innerHTML = styles;\n if (this.getAttribute('nonce')) {\n styleEl.setAttribute('nonce', this.getAttribute('nonce'));\n }\n shadowRoot.appendChild(styleEl);\n shadowRoot.appendChild(templateElement.content.cloneNode(true));\n this.firstElement = shadowRoot.getElementById('first');\n this.handleElement = shadowRoot.getElementById('handle');\n }\n set handle(newValue) {\n this.dragByHandle = newValue.toString().toLowerCase() !== 'false';\n }\n get handle() {\n return this.dragByHandle;\n }\n get value() {\n return this.exposure;\n }\n set value(newValue) {\n const newExposure = parseFloat(newValue);\n if (newExposure === this.exposure) {\n return;\n }\n this.exposure = newExposure;\n this.enableTransition();\n this.setExposure();\n }\n get hover() {\n return this.slideOnHover;\n }\n set hover(newValue) {\n this.slideOnHover = newValue.toString().toLowerCase() !== 'false';\n this.removeEventListener('mousemove', this.onMouseMove);\n if (this.slideOnHover) {\n this.addEventListener('mousemove', this.onMouseMove);\n }\n }\n get direction() {\n return this.slideDirection;\n }\n set direction(newValue) {\n this.slideDirection = newValue.toString().toLowerCase();\n this.slide(0);\n this.firstElement.classList.remove(...slideDirections);\n if (!slideDirections.includes(this.slideDirection)) {\n return;\n }\n this.firstElement.classList.add(this.slideDirection);\n }\n static get observedAttributes() {\n return ['hover', 'direction'];\n }\n connectedCallback() {\n if (!this.hasAttribute('tabindex')) {\n this.tabIndex = TABINDEX;\n }\n this.addEventListener('dragstart', (e) => {\n e.preventDefault();\n return false;\n });\n const resizeObserver = new ResizeObserver(this.resetDimensions);\n resizeObserver.observe(this);\n this.setExposure(0);\n this.keyboard =\n this.hasAttribute('keyboard') &&\n this.getAttribute('keyboard') === 'disabled'\n ? 'disabled'\n : 'enabled';\n this.addEventListener('keydown', this.onKeyDown);\n this.addEventListener('keyup', this.onKeyUp);\n this.addEventListener('focus', this.onFocus);\n this.addEventListener('blur', this.onBlur);\n this.addEventListener('touchstart', this.onTouchStart, {\n passive: true,\n });\n this.addEventListener('touchmove', this.onTouchMove, {\n passive: false,\n });\n this.addEventListener('touchend', this.onTouchEnd);\n this.addEventListener('mousedown', this.onMouseDown);\n this.handle = this.hasAttribute('handle')\n ? this.getAttribute('handle')\n : this.dragByHandle;\n this.hover = this.hasAttribute('hover')\n ? this.getAttribute('hover')\n : this.slideOnHover;\n this.direction = this.hasAttribute('direction')\n ? this.getAttribute('direction')\n : this.slideDirection;\n this.resetDimensions();\n if (!this.classList.contains(RENDERED_CLASS)) {\n this.classList.add(RENDERED_CLASS);\n }\n }\n disconnectedCallback() {\n if (this.transitionTimer) {\n window.clearTimeout(this.transitionTimer);\n }\n }\n attributeChangedCallback(name, oldValue, newValue) {\n if (name === 'hover') {\n this.hover = newValue;\n }\n if (name === 'direction') {\n this.direction = newValue;\n }\n if (name === 'keyboard') {\n this.keyboard = newValue === 'disabled' ? 'disabled' : 'enabled';\n }\n }\n setExposure(increment = 0) {\n this.exposure = inBetween(this.exposure + increment, 0, 100);\n this.firstElement.style.setProperty('--exposure', `${100 - this.exposure}%`);\n }\n slide(increment = 0) {\n this.setExposure(increment);\n const event = new Event('slide');\n this.dispatchEvent(event);\n }\n slideToPage(currentPoint) {\n if (this.slideDirection === 'horizontal') {\n this.slideToPageX(currentPoint.x);\n }\n if (this.slideDirection === 'vertical') {\n this.slideToPageY(currentPoint.y);\n }\n }\n slideToPageX(pageX) {\n const x = pageX - this.getBoundingClientRect().left - window.scrollX;\n this.exposure = (x / this.imageWidth) * 100;\n this.slide(0);\n }\n slideToPageY(pageY) {\n const y = pageY - this.getBoundingClientRect().top - window.scrollY;\n this.exposure = (y / this.imageHeight) * 100;\n this.slide(0);\n }\n enableTransition() {\n const transitionTime = 100;\n this.firstElement.style.setProperty('--transition-time', `${transitionTime}ms`);\n this.transitionTimer = window.setTimeout(() => {\n this.firstElement.style.setProperty('--transition-time', `var(--default-transition-time)`);\n this.transitionTimer = null;\n }, transitionTime);\n }\n startSlideAnimation() {\n let lastTimestamp = null;\n let initialDirection = this.animationDirection;\n this.firstElement.style.setProperty('--transition-time', `var(--keyboard-transition-time)`);\n const slide = (now) => {\n if (this.animationDirection === 0 ||\n initialDirection !== this.animationDirection) {\n return;\n }\n if (lastTimestamp === null) {\n lastTimestamp = now;\n }\n const interval = now - lastTimestamp, distance = (interval / slideAnimationPeriod) * this.animationDirection;\n this.slide(distance);\n // This is necessary to speed up the key up event in Desktop Safari\n setTimeout(() => window.requestAnimationFrame(slide), 0);\n lastTimestamp = now;\n };\n window.requestAnimationFrame(slide);\n }\n stopSlideAnimation() {\n this.animationDirection = 0;\n this.firstElement.style.setProperty('--transition-time', `var(--default-transition-time)`);\n }\n}\nif (typeof window !== 'undefined') {\n if (window.document) {\n templateElement = document.createElement('template');\n templateElement.innerHTML = templateHtml;\n }\n window.customElements.define('img-comparison-slider', HTMLImgComparisonSliderElement);\n}\n","export const inBetween = (actual, min, max) => {\n if (actual < min) {\n return min;\n }\n if (actual > max) {\n return max;\n }\n return actual;\n};\n"],"names":["___CSS_LOADER_EXPORT___","i","push","module","id","exports","cssWithMappingToString","list","toString","this","map","item","content","concat","join","modules","mediaQuery","dedupe","alreadyImportedModules","length","_i","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","n","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","RENDERED_CLASS","isElementAffected","element","e","rect","getBoundingClientRect","eventX","eventY","type","clientX","clientY","touches","x","width","y","height","templateElement","KeySlideOffset","ArrowLeft","ArrowRight","slideDirections","getTouchPagePoint","pageX","pageY","getMousePagePoint","HTMLElement","window","document","createElement","innerHTML","customElements","define","constructor","super","exposure","hasAttribute","parseFloat","getAttribute","slideOnHover","slideDirection","keyboard","isMouseDown","animationDirection","isFocused","dragByHandle","onMouseMove","currentPoint","slideToPage","bodyUserSelectStyle","bodyWebkitUserSelectStyle","onMouseDown","handle","handleElement","preventDefault","addEventListener","onWindowMouseUp","enableTransition","focus","body","style","userSelect","webkitUserSelect","removeEventListener","touchStartPoint","isTouchComparing","hasTouchMoved","onTouchStart","onTouchMove","offsetY","Math","abs","offsetX","onTouchEnd","onBlur","stopSlideAnimation","firstElement","classList","remove","onFocus","add","onKeyDown","direction","startSlideAnimation","onKeyUp","resetDimensions","imageWidth","offsetWidth","imageHeight","offsetHeight","shadowRoot","attachShadow","mode","styleEl","styles","setAttribute","appendChild","cloneNode","getElementById","newValue","toLowerCase","value","newExposure","setExposure","hover","slide","includes","observedAttributes","connectedCallback","tabIndex","ResizeObserver","observe","passive","contains","disconnectedCallback","transitionTimer","clearTimeout","attributeChangedCallback","name","oldValue","increment","actual","setProperty","event","Event","dispatchEvent","slideToPageX","slideToPageY","left","scrollX","top","scrollY","setTimeout","lastTimestamp","initialDirection","now","distance","requestAnimationFrame"],"sourceRoot":""} \ No newline at end of file diff --git a/docs/stylesheets/img-comparison-slider.css b/docs/stylesheets/img-comparison-slider.css new file mode 100644 index 0000000..f73d40f --- /dev/null +++ b/docs/stylesheets/img-comparison-slider.css @@ -0,0 +1,15 @@ +img-comparison-slider { + visibility: hidden; +} + +img-comparison-slider [slot='second'] { + display: none; +} + +img-comparison-slider.rendered { + visibility: inherit; +} + +img-comparison-slider.rendered [slot='second'] { + display: unset; +} diff --git a/docs/theme-overrides/layouts/home.html b/docs/theme-overrides/layouts/home.html index 447ab19..b9b654d 100644 --- a/docs/theme-overrides/layouts/home.html +++ b/docs/theme-overrides/layouts/home.html @@ -68,7 +68,7 @@ } .tx-hero__image { max-width: 1000px; - min-width: 600px; + min-width: 0; width: 100%; height: auto; margin: 0 auto; @@ -218,7 +218,7 @@ .secondary-section .g .section .component-wrapper .responsive-grid .card { position: relative; - background-color: #fff none repeat scroll 0% 0%; + background-color: #fff; padding: 1.5rem; display: flex; flex-direction: row; @@ -300,6 +300,59 @@ background: var(--md-accent-fg-color--transparent); } +.before, +.after { + margin: 0; +} + +.after figcaption { + background: #fff; + font-weight: bold; + border: 1px solid #c0c0c0; + color: #000000; + opacity: 0.9; + padding: 9px; + position: absolute; + top: 100%; + transform: translateY(-100%); + line-height: 100%; +} + +.before figcaption { + background: #000; + font-weight: bold; + border: 1px solid #c0c0c0; + color: #ffffff; + opacity: 0.9; + padding: 9px; + position: absolute; + top: 100%; + transform: translateY(-100%); + line-height: 100%; +} + +.before figcaption { + left: 0px; +} +.after figcaption { + right: 0px; +} +.custom-animated-handle { + transition: transform 0.2s; +} + +.slider-with-animated-handle:hover .custom-animated-handle { + transform: scale(1.2); +} +.md-typeset img-comparison-slider figure { + margin: initial; +} + +.first-overlay { + color: #000; +} + + @@ -310,7 +363,6 @@

A beautiful and simple UI to manage your WireGuard peers and interfaces

WireGuard Portal is an open source web-based user interface that makes it easy to setup and manage WireGuard VPN connections. It's built on top of WireGuard's official wgctrl library.

-

- +
+ +
+ Light Mode +
Light Mode
+
+
+ Dark Mode +
Dark Mode
+
+ + + + + + + + +
+
diff --git a/frontend/index.html b/frontend/index.html index fd8033f..287ef99 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,5 +1,5 @@ - + diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f12f2f7..326c5e1 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -12,9 +12,10 @@ "@fortawesome/fontawesome-free": "^6.7.2", "@kyvg/vue3-notification": "^3.4.1", "@popperjs/core": "^2.11.8", + "@simplewebauthn/browser": "^13.1.0", "@vojtechlanka/vue-tags-input": "^3.1.1", - "bootstrap": "^5.3.5", - "bootswatch": "^5.3.5", + "bootstrap": "^5.3.7", + "bootswatch": "^5.3.7", "flag-icons": "^7.3.2", "ip-address": "^10.0.1", "is-cidr": "^5.1.1", @@ -29,34 +30,34 @@ "devDependencies": { "@vitejs/plugin-vue": "^5.2.3", "sass-embedded": "^1.86.3", - "vite": "6.3.4" + "vite": "^6.3.6" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", - "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.26.9" + "@babel/types": "^7.28.4" }, "bin": { "parser": "bin/babel-parser.js" @@ -66,29 +67,29 @@ } }, "node_modules/@babel/types": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", - "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@bufbuild/protobuf": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.2.3.tgz", - "integrity": "sha512-tFQoXHJdkEOSwj5tRIZSPNUuXK3RaR7T1nUrPgbYX1pUbvqqaaZAsfo+NXBPsz5rZMSKVFrgK1WL8Q/MSLvprg==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.9.0.tgz", + "integrity": "sha512-rnJenoStJ8nvmt9Gzye8nkYd6V22xUAnu4086ER7h1zJ508vStko4pMvDeQ446ilDTFpV5wnoc5YS7XvMwwMqA==", "dev": true, "license": "(Apache-2.0 AND BSD-3-Clause)" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", - "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", "cpu": [ "ppc64" ], @@ -103,9 +104,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", - "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", "cpu": [ "arm" ], @@ -120,9 +121,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", - "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", "cpu": [ "arm64" ], @@ -137,9 +138,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", - "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", "cpu": [ "x64" ], @@ -154,9 +155,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", - "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", "cpu": [ "arm64" ], @@ -171,9 +172,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", - "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", "cpu": [ "x64" ], @@ -188,9 +189,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", - "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", "cpu": [ "arm64" ], @@ -205,9 +206,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", - "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", "cpu": [ "x64" ], @@ -222,9 +223,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", - "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", "cpu": [ "arm" ], @@ -239,9 +240,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", - "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", "cpu": [ "arm64" ], @@ -256,9 +257,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", - "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", "cpu": [ "ia32" ], @@ -273,9 +274,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", - "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", "cpu": [ "loong64" ], @@ -290,9 +291,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", - "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", "cpu": [ "mips64el" ], @@ -307,9 +308,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", - "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", "cpu": [ "ppc64" ], @@ -324,9 +325,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", - "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", "cpu": [ "riscv64" ], @@ -341,9 +342,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", - "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", "cpu": [ "s390x" ], @@ -358,9 +359,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", - "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", "cpu": [ "x64" ], @@ -375,9 +376,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", - "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", "cpu": [ "arm64" ], @@ -392,9 +393,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", - "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", "cpu": [ "x64" ], @@ -409,9 +410,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", - "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", "cpu": [ "arm64" ], @@ -426,9 +427,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", - "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", "cpu": [ "x64" ], @@ -442,10 +443,27 @@ "node": ">=18" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", - "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", "cpu": [ "x64" ], @@ -460,9 +478,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", - "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", "cpu": [ "arm64" ], @@ -477,9 +495,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", - "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", "cpu": [ "ia32" ], @@ -494,9 +512,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", - "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", + "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", "cpu": [ "x64" ], @@ -511,9 +529,9 @@ } }, "node_modules/@fontsource/nunito-sans": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/@fontsource/nunito-sans/-/nunito-sans-5.2.5.tgz", - "integrity": "sha512-QE2I4PmR9CHoAXxfpz4L+o35X4jg64i+5/J8Aa0G24mY9xs2VPr0a4igDcZkjIMhGfFfPAvcaR+hf/NpXVhZuw==", + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@fontsource/nunito-sans/-/nunito-sans-5.2.7.tgz", + "integrity": "sha512-Vh+xhMsrH1eA9Q83Va82su3rDmNilYg+ur/TfHAOyr5kTpCOWMB8B1tDoJvSe+yJPpZ2jEWtnBHGqI2LUPVxUA==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" @@ -529,13 +547,13 @@ } }, "node_modules/@intlify/core-base": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.1.3.tgz", - "integrity": "sha512-cMuHunYO7LE80azTitcvEbs1KJmtd6g7I5pxlApV3Jo547zdO3h31/0uXpqHc+Y3RKt1wo2y68RGSx77Z1klyA==", + "version": "11.1.12", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.1.12.tgz", + "integrity": "sha512-whh0trqRsSqVLNEUCwU59pyJZYpU8AmSWl8M3Jz2Mv5ESPP6kFh4juas2NpZ1iCvy7GlNRffUD1xr84gceimjg==", "license": "MIT", "dependencies": { - "@intlify/message-compiler": "11.1.3", - "@intlify/shared": "11.1.3" + "@intlify/message-compiler": "11.1.12", + "@intlify/shared": "11.1.12" }, "engines": { "node": ">= 16" @@ -545,12 +563,12 @@ } }, "node_modules/@intlify/message-compiler": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.1.3.tgz", - "integrity": "sha512-7rbqqpo2f5+tIcwZTAG/Ooy9C8NDVwfDkvSeDPWUPQW+Dyzfw2o9H103N5lKBxO7wxX9dgCDjQ8Umz73uYw3hw==", + "version": "11.1.12", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.1.12.tgz", + "integrity": "sha512-Fv9iQSJoJaXl4ZGkOCN1LDM3trzze0AS2zRz2EHLiwenwL6t0Ki9KySYlyr27yVOj5aVz0e55JePO+kELIvfdQ==", "license": "MIT", "dependencies": { - "@intlify/shared": "11.1.3", + "@intlify/shared": "11.1.12", "source-map-js": "^1.0.2" }, "engines": { @@ -561,9 +579,9 @@ } }, "node_modules/@intlify/shared": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.1.3.tgz", - "integrity": "sha512-pTFBgqa/99JRA2H1qfyqv97MKWJrYngXBA/I0elZcYxvJgcCw3mApAoPW3mJ7vx3j+Ti0FyKUFZ4hWxdjKaxvA==", + "version": "11.1.12", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.1.12.tgz", + "integrity": "sha512-Om86EjuQtA69hdNj3GQec9ZC0L0vPSAnXzB3gP/gyJ7+mA7t06d9aOAiqMZ+xEOsumGP4eEBlfl8zF2LOTzf2A==", "license": "MIT", "engines": { "node": ">= 16" @@ -573,9 +591,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, "node_modules/@kyvg/vue3-notification": { @@ -587,20 +605,331 @@ "vue": "^3.0.0" } }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.9.tgz", - "integrity": "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", + "integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==", "cpu": [ "arm" ], @@ -612,9 +941,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.9.tgz", - "integrity": "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz", + "integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==", "cpu": [ "arm64" ], @@ -626,9 +955,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz", - "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz", + "integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==", "cpu": [ "arm64" ], @@ -640,9 +969,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz", - "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz", + "integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==", "cpu": [ "x64" ], @@ -654,9 +983,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.9.tgz", - "integrity": "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz", + "integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==", "cpu": [ "arm64" ], @@ -668,9 +997,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.9.tgz", - "integrity": "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz", + "integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==", "cpu": [ "x64" ], @@ -682,9 +1011,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.9.tgz", - "integrity": "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz", + "integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==", "cpu": [ "arm" ], @@ -696,9 +1025,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.9.tgz", - "integrity": "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz", + "integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==", "cpu": [ "arm" ], @@ -710,9 +1039,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz", - "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz", + "integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==", "cpu": [ "arm64" ], @@ -724,9 +1053,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz", - "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz", + "integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==", "cpu": [ "arm64" ], @@ -737,10 +1066,10 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.9.tgz", - "integrity": "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz", + "integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==", "cpu": [ "loong64" ], @@ -751,10 +1080,10 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.9.tgz", - "integrity": "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz", + "integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==", "cpu": [ "ppc64" ], @@ -766,9 +1095,23 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.9.tgz", - "integrity": "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz", + "integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz", + "integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==", "cpu": [ "riscv64" ], @@ -780,9 +1123,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.9.tgz", - "integrity": "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz", + "integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==", "cpu": [ "s390x" ], @@ -794,9 +1137,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz", - "integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz", + "integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==", "cpu": [ "x64" ], @@ -808,9 +1151,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz", - "integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz", + "integrity": "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==", "cpu": [ "x64" ], @@ -821,10 +1164,24 @@ "linux" ] }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz", + "integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz", - "integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz", + "integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==", "cpu": [ "arm64" ], @@ -836,9 +1193,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.9.tgz", - "integrity": "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz", + "integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==", "cpu": [ "ia32" ], @@ -849,10 +1206,10 @@ "win32" ] }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz", - "integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==", + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz", + "integrity": "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==", "cpu": [ "x64" ], @@ -863,17 +1220,37 @@ "win32" ] }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz", + "integrity": "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@simplewebauthn/browser": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@simplewebauthn/browser/-/browser-13.2.0.tgz", + "integrity": "sha512-N3fuA1AAnTo5gCStYoIoiasPccC+xPLx2YU88Dv0GeAmPQTWHETlZQq5xZ0DgUq1H9loXMWQH5qqUjcI7BHJ1A==", + "license": "MIT" + }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, "node_modules/@vitejs/plugin-vue": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.3.tgz", - "integrity": "sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", + "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", "dev": true, "license": "MIT", "engines": { @@ -899,151 +1276,151 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", - "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.22.tgz", + "integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.25.3", - "@vue/shared": "3.5.13", + "@babel/parser": "^7.28.4", + "@vue/shared": "3.5.22", "entities": "^4.5.0", "estree-walker": "^2.0.2", - "source-map-js": "^1.2.0" + "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", - "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz", + "integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.13", - "@vue/shared": "3.5.13" + "@vue/compiler-core": "3.5.22", + "@vue/shared": "3.5.22" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz", - "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz", + "integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.25.3", - "@vue/compiler-core": "3.5.13", - "@vue/compiler-dom": "3.5.13", - "@vue/compiler-ssr": "3.5.13", - "@vue/shared": "3.5.13", + "@babel/parser": "^7.28.4", + "@vue/compiler-core": "3.5.22", + "@vue/compiler-dom": "3.5.22", + "@vue/compiler-ssr": "3.5.22", + "@vue/shared": "3.5.22", "estree-walker": "^2.0.2", - "magic-string": "^0.30.11", - "postcss": "^8.4.48", - "source-map-js": "^1.2.0" + "magic-string": "^0.30.19", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz", - "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz", + "integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.13", - "@vue/shared": "3.5.13" + "@vue/compiler-dom": "3.5.22", + "@vue/shared": "3.5.22" } }, "node_modules/@vue/devtools-api": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.2.tgz", - "integrity": "sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.7.tgz", + "integrity": "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==", "license": "MIT", "dependencies": { - "@vue/devtools-kit": "^7.7.2" + "@vue/devtools-kit": "^7.7.7" } }, "node_modules/@vue/devtools-kit": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.2.tgz", - "integrity": "sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz", + "integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==", "license": "MIT", "dependencies": { - "@vue/devtools-shared": "^7.7.2", - "birpc": "^0.2.19", + "@vue/devtools-shared": "^7.7.7", + "birpc": "^2.3.0", "hookable": "^5.5.3", "mitt": "^3.0.1", "perfect-debounce": "^1.0.0", "speakingurl": "^14.0.1", - "superjson": "^2.2.1" + "superjson": "^2.2.2" } }, "node_modules/@vue/devtools-shared": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.2.tgz", - "integrity": "sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz", + "integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==", "license": "MIT", "dependencies": { "rfdc": "^1.4.1" } }, "node_modules/@vue/reactivity": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz", - "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==", + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.22.tgz", + "integrity": "sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==", "license": "MIT", "dependencies": { - "@vue/shared": "3.5.13" + "@vue/shared": "3.5.22" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.13.tgz", - "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==", + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.22.tgz", + "integrity": "sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.13", - "@vue/shared": "3.5.13" + "@vue/reactivity": "3.5.22", + "@vue/shared": "3.5.22" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz", - "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==", + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.22.tgz", + "integrity": "sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.13", - "@vue/runtime-core": "3.5.13", - "@vue/shared": "3.5.13", + "@vue/reactivity": "3.5.22", + "@vue/runtime-core": "3.5.22", + "@vue/shared": "3.5.22", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.13.tgz", - "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==", + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.22.tgz", + "integrity": "sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==", "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.13", - "@vue/shared": "3.5.13" + "@vue/compiler-ssr": "3.5.22", + "@vue/shared": "3.5.22" }, "peerDependencies": { - "vue": "3.5.13" + "vue": "3.5.22" } }, "node_modules/@vue/shared": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz", - "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.22.tgz", + "integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==", "license": "MIT" }, "node_modules/birpc": { - "version": "0.2.19", - "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.19.tgz", - "integrity": "sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.6.1.tgz", + "integrity": "sha512-LPnFhlDpdSH6FJhJyn4M0kFO7vtQ5iPw24FnG0y21q09xC7e8+1LeR31S1MAIrDAHp4m7aas4bEkTDTvMAtebQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/bootstrap": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.5.tgz", - "integrity": "sha512-ct1CHKtiobRimyGzmsSldEtM03E8fcEX4Tb3dGXz1V8faRwM50+vfHwTzOxB3IlKO7m+9vTH3s/3C6T2EAPeTA==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", "funding": [ { "type": "github", @@ -1060,11 +1437,25 @@ } }, "node_modules/bootswatch": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/bootswatch/-/bootswatch-5.3.5.tgz", - "integrity": "sha512-1z8LNoUL5NHmv/hNROALQ6qtjw9OJIjMgP8ovBlIft+oI15b/mvnzxGL896iO9LtoDZH0Vdm+D2YW+j03GduSg==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootswatch/-/bootswatch-5.3.8.tgz", + "integrity": "sha512-88mnH9tv+x6DV+scBxYFOpM4YSDVhyfEgbhqaEfvkHNctKI9qRcACxIP9nmBZ5mSeLXtsgax1VsRkUs1eWjlAQ==", "license": "MIT" }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/buffer-builder": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/buffer-builder/-/buffer-builder-0.2.0.tgz", @@ -1072,6 +1463,23 @@ "dev": true, "license": "MIT/X11" }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/cidr-regex": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/cidr-regex/-/cidr-regex-4.1.3.tgz", @@ -1139,6 +1547,20 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -1152,9 +1574,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", - "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", + "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1165,31 +1587,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.0", - "@esbuild/android-arm": "0.25.0", - "@esbuild/android-arm64": "0.25.0", - "@esbuild/android-x64": "0.25.0", - "@esbuild/darwin-arm64": "0.25.0", - "@esbuild/darwin-x64": "0.25.0", - "@esbuild/freebsd-arm64": "0.25.0", - "@esbuild/freebsd-x64": "0.25.0", - "@esbuild/linux-arm": "0.25.0", - "@esbuild/linux-arm64": "0.25.0", - "@esbuild/linux-ia32": "0.25.0", - "@esbuild/linux-loong64": "0.25.0", - "@esbuild/linux-mips64el": "0.25.0", - "@esbuild/linux-ppc64": "0.25.0", - "@esbuild/linux-riscv64": "0.25.0", - "@esbuild/linux-s390x": "0.25.0", - "@esbuild/linux-x64": "0.25.0", - "@esbuild/netbsd-arm64": "0.25.0", - "@esbuild/netbsd-x64": "0.25.0", - "@esbuild/openbsd-arm64": "0.25.0", - "@esbuild/openbsd-x64": "0.25.0", - "@esbuild/sunos-x64": "0.25.0", - "@esbuild/win32-arm64": "0.25.0", - "@esbuild/win32-ia32": "0.25.0", - "@esbuild/win32-x64": "0.25.0" + "@esbuild/aix-ppc64": "0.25.10", + "@esbuild/android-arm": "0.25.10", + "@esbuild/android-arm64": "0.25.10", + "@esbuild/android-x64": "0.25.10", + "@esbuild/darwin-arm64": "0.25.10", + "@esbuild/darwin-x64": "0.25.10", + "@esbuild/freebsd-arm64": "0.25.10", + "@esbuild/freebsd-x64": "0.25.10", + "@esbuild/linux-arm": "0.25.10", + "@esbuild/linux-arm64": "0.25.10", + "@esbuild/linux-ia32": "0.25.10", + "@esbuild/linux-loong64": "0.25.10", + "@esbuild/linux-mips64el": "0.25.10", + "@esbuild/linux-ppc64": "0.25.10", + "@esbuild/linux-riscv64": "0.25.10", + "@esbuild/linux-s390x": "0.25.10", + "@esbuild/linux-x64": "0.25.10", + "@esbuild/netbsd-arm64": "0.25.10", + "@esbuild/netbsd-x64": "0.25.10", + "@esbuild/openbsd-arm64": "0.25.10", + "@esbuild/openbsd-x64": "0.25.10", + "@esbuild/openharmony-arm64": "0.25.10", + "@esbuild/sunos-x64": "0.25.10", + "@esbuild/win32-arm64": "0.25.10", + "@esbuild/win32-ia32": "0.25.10", + "@esbuild/win32-x64": "0.25.10" } }, "node_modules/estree-walker": { @@ -1204,25 +1627,24 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, - "node_modules/fdir": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", - "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" + "optional": true, + "dependencies": { + "to-regex-range": "^5.0.1" }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "engines": { + "node": ">=8" } }, "node_modules/flag-icons": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/flag-icons/-/flag-icons-7.3.2.tgz", - "integrity": "sha512-QkaZ6Zvai8LIjx+UNAHUJ5Dhz9OLZpBDwCRWxF6YErxIcR16jTkIFm3bFu54EkvKQy4+wicW+Gm7/0631wVQyQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/flag-icons/-/flag-icons-7.5.0.tgz", + "integrity": "sha512-kd+MNXviFIg5hijH766tt+3x76ele1AXlo4zDdCxIvqWZhKt4T83bOtxUOOMlTx/EcFdUMH5yvQgYlFh1EqqFg==", "license": "MIT" }, "node_modules/fsevents": { @@ -1269,9 +1691,9 @@ "license": "MIT" }, "node_modules/immutable": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", - "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", "dev": true, "license": "MIT" }, @@ -1308,6 +1730,31 @@ "node": ">=14" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-ip": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-5.0.1.tgz", @@ -1324,6 +1771,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/is-regexp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz", @@ -1349,12 +1807,27 @@ } }, "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "version": "0.30.19", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" } }, "node_modules/mitt": { @@ -1364,9 +1837,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "funding": [ { "type": "github", @@ -1381,6 +1854,14 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/perfect-debounce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", @@ -1394,22 +1875,23 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", + "optional": true, "engines": { - "node": ">=12" + "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pinia": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.2.tgz", - "integrity": "sha512-sH2JK3wNY809JOeiiURUR0wehJ9/gd9qFN2Y828jCbxEzKEmEt0pzCXwqiSTfuRsK9vQsOflSdnbdBOGrhtn+g==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.3.tgz", + "integrity": "sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==", "license": "MIT", "dependencies": { "@vue/devtools-api": "^7.7.2" @@ -1428,9 +1910,9 @@ } }, "node_modules/postcss": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "funding": [ { "type": "opencollective", @@ -1447,7 +1929,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.8", + "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -1464,6 +1946,21 @@ "node": ">=6" } }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/rfdc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", @@ -1471,13 +1968,13 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.34.9", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.9.tgz", - "integrity": "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==", + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz", + "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.6" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -1487,25 +1984,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.34.9", - "@rollup/rollup-android-arm64": "4.34.9", - "@rollup/rollup-darwin-arm64": "4.34.9", - "@rollup/rollup-darwin-x64": "4.34.9", - "@rollup/rollup-freebsd-arm64": "4.34.9", - "@rollup/rollup-freebsd-x64": "4.34.9", - "@rollup/rollup-linux-arm-gnueabihf": "4.34.9", - "@rollup/rollup-linux-arm-musleabihf": "4.34.9", - "@rollup/rollup-linux-arm64-gnu": "4.34.9", - "@rollup/rollup-linux-arm64-musl": "4.34.9", - "@rollup/rollup-linux-loongarch64-gnu": "4.34.9", - "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9", - "@rollup/rollup-linux-riscv64-gnu": "4.34.9", - "@rollup/rollup-linux-s390x-gnu": "4.34.9", - "@rollup/rollup-linux-x64-gnu": "4.34.9", - "@rollup/rollup-linux-x64-musl": "4.34.9", - "@rollup/rollup-win32-arm64-msvc": "4.34.9", - "@rollup/rollup-win32-ia32-msvc": "4.34.9", - "@rollup/rollup-win32-x64-msvc": "4.34.9", + "@rollup/rollup-android-arm-eabi": "4.52.4", + "@rollup/rollup-android-arm64": "4.52.4", + "@rollup/rollup-darwin-arm64": "4.52.4", + "@rollup/rollup-darwin-x64": "4.52.4", + "@rollup/rollup-freebsd-arm64": "4.52.4", + "@rollup/rollup-freebsd-x64": "4.52.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.4", + "@rollup/rollup-linux-arm-musleabihf": "4.52.4", + "@rollup/rollup-linux-arm64-gnu": "4.52.4", + "@rollup/rollup-linux-arm64-musl": "4.52.4", + "@rollup/rollup-linux-loong64-gnu": "4.52.4", + "@rollup/rollup-linux-ppc64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-musl": "4.52.4", + "@rollup/rollup-linux-s390x-gnu": "4.52.4", + "@rollup/rollup-linux-x64-gnu": "4.52.4", + "@rollup/rollup-linux-x64-musl": "4.52.4", + "@rollup/rollup-openharmony-arm64": "4.52.4", + "@rollup/rollup-win32-arm64-msvc": "4.52.4", + "@rollup/rollup-win32-ia32-msvc": "4.52.4", + "@rollup/rollup-win32-x64-gnu": "4.52.4", + "@rollup/rollup-win32-x64-msvc": "4.52.4", "fsevents": "~2.3.2" } }, @@ -1519,14 +2019,37 @@ "tslib": "^2.1.0" } }, - "node_modules/sass-embedded": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.86.3.tgz", - "integrity": "sha512-3pZSp24ibO1hdopj+W9DuiWsZOb2YY6AFRo/jjutKLBkqJGM1nJjXzhAYfzRV+Xn5BX1eTI4bBTE09P0XNHOZg==", + "node_modules/sass": { + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.93.2.tgz", + "integrity": "sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@bufbuild/protobuf": "^2.0.0", + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-embedded": { + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.93.2.tgz", + "integrity": "sha512-FvQdkn2dZ8DGiLgi0Uf4zsj7r/BsiLImNa5QJ10eZalY6NfZyjrmWGFcuCN5jNwlDlXFJnftauv+UtvBKLvepQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@bufbuild/protobuf": "^2.5.0", "buffer-builder": "^0.2.0", "colorjs.io": "^0.5.0", "immutable": "^5.0.2", @@ -1542,32 +2065,47 @@ "node": ">=16.0.0" }, "optionalDependencies": { - "sass-embedded-android-arm": "1.86.3", - "sass-embedded-android-arm64": "1.86.3", - "sass-embedded-android-ia32": "1.86.3", - "sass-embedded-android-riscv64": "1.86.3", - "sass-embedded-android-x64": "1.86.3", - "sass-embedded-darwin-arm64": "1.86.3", - "sass-embedded-darwin-x64": "1.86.3", - "sass-embedded-linux-arm": "1.86.3", - "sass-embedded-linux-arm64": "1.86.3", - "sass-embedded-linux-ia32": "1.86.3", - "sass-embedded-linux-musl-arm": "1.86.3", - "sass-embedded-linux-musl-arm64": "1.86.3", - "sass-embedded-linux-musl-ia32": "1.86.3", - "sass-embedded-linux-musl-riscv64": "1.86.3", - "sass-embedded-linux-musl-x64": "1.86.3", - "sass-embedded-linux-riscv64": "1.86.3", - "sass-embedded-linux-x64": "1.86.3", - "sass-embedded-win32-arm64": "1.86.3", - "sass-embedded-win32-ia32": "1.86.3", - "sass-embedded-win32-x64": "1.86.3" + "sass-embedded-all-unknown": "1.93.2", + "sass-embedded-android-arm": "1.93.2", + "sass-embedded-android-arm64": "1.93.2", + "sass-embedded-android-riscv64": "1.93.2", + "sass-embedded-android-x64": "1.93.2", + "sass-embedded-darwin-arm64": "1.93.2", + "sass-embedded-darwin-x64": "1.93.2", + "sass-embedded-linux-arm": "1.93.2", + "sass-embedded-linux-arm64": "1.93.2", + "sass-embedded-linux-musl-arm": "1.93.2", + "sass-embedded-linux-musl-arm64": "1.93.2", + "sass-embedded-linux-musl-riscv64": "1.93.2", + "sass-embedded-linux-musl-x64": "1.93.2", + "sass-embedded-linux-riscv64": "1.93.2", + "sass-embedded-linux-x64": "1.93.2", + "sass-embedded-unknown-all": "1.93.2", + "sass-embedded-win32-arm64": "1.93.2", + "sass-embedded-win32-x64": "1.93.2" + } + }, + "node_modules/sass-embedded-all-unknown": { + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-all-unknown/-/sass-embedded-all-unknown-1.93.2.tgz", + "integrity": "sha512-GdEuPXIzmhRS5J7UKAwEvtk8YyHQuFZRcpnEnkA3rwRUI27kwjyXkNeIj38XjUQ3DzrfMe8HcKFaqWGHvblS7Q==", + "cpu": [ + "!arm", + "!arm64", + "!riscv64", + "!x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "sass": "1.93.2" } }, "node_modules/sass-embedded-android-arm": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.86.3.tgz", - "integrity": "sha512-UyeXrFzZSvrGbvrWUBcspbsbivGgAgebLGJdSqJulgSyGbA6no3DWQ5Qpdd6+OAUC39BlpPu74Wx9s4RrVuaFw==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.93.2.tgz", + "integrity": "sha512-I8bpO8meZNo5FvFx5FIiE7DGPVOYft0WjuwcCCdeJ6duwfkl6tZdatex1GrSigvTsuz9L0m4ngDcX/Tj/8yMow==", "cpu": [ "arm" ], @@ -1582,9 +2120,9 @@ } }, "node_modules/sass-embedded-android-arm64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.86.3.tgz", - "integrity": "sha512-q+XwFp6WgAv+UgnQhsB8KQ95kppvWAB7DSoJp+8Vino8b9ND+1ai3cUUZPE5u4SnLZrgo5NtrbPvN5KLc4Pfyg==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.93.2.tgz", + "integrity": "sha512-346f4iVGAPGcNP6V6IOOFkN5qnArAoXNTPr5eA/rmNpeGwomdb7kJyQ717r9rbJXxOG8OAAUado6J0qLsjnjXQ==", "cpu": [ "arm64" ], @@ -1598,27 +2136,10 @@ "node": ">=14.0.0" } }, - "node_modules/sass-embedded-android-ia32": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-android-ia32/-/sass-embedded-android-ia32-1.86.3.tgz", - "integrity": "sha512-gTJjVh2cRzvGujXj5ApPk/owUTL5SiO7rDtNLrzYAzi1N5HRuLYXqk3h1IQY3+eCOBjGl7mQ9XyySbJs/3hDvg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/sass-embedded-android-riscv64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.86.3.tgz", - "integrity": "sha512-Po3JnyiCS16kd6REo1IMUbFGYtvL9O0rmKaXx5vOuBaJD1LPy2LiSSp7TU7wkJ9IxsTDGzFaSeP1I9qb6D8VVg==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.93.2.tgz", + "integrity": "sha512-hSMW1s4yJf5guT9mrdkumluqrwh7BjbZ4MbBW9tmi1DRDdlw1Wh9Oy1HnnmOG8x9XcI1qkojtPL6LUuEJmsiDg==", "cpu": [ "riscv64" ], @@ -1633,9 +2154,9 @@ } }, "node_modules/sass-embedded-android-x64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.86.3.tgz", - "integrity": "sha512-+7h3jdDv/0kUFx0BvxYlq2fa7CcHiDPlta6k5OxO5K6jyqJwo9hc0Z052BoYEauWTqZ+vK6bB5rv2BIzq4U9nA==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.93.2.tgz", + "integrity": "sha512-JqktiHZduvn+ldGBosE40ALgQ//tGCVNAObgcQ6UIZznEJbsHegqStqhRo8UW3x2cgOO2XYJcrInH6cc7wdKbw==", "cpu": [ "x64" ], @@ -1650,9 +2171,9 @@ } }, "node_modules/sass-embedded-darwin-arm64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.86.3.tgz", - "integrity": "sha512-EgLwV4ORm5Hr0DmIXo0Xw/vlzwLnfAiqD2jDXIglkBsc5czJmo4/IBdGXOP65TRnsgJEqvbU3aQhuawX5++x9A==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.93.2.tgz", + "integrity": "sha512-qI1X16qKNeBJp+M/5BNW7v/JHCDYWr1/mdoJ7+UMHmP0b5AVudIZtimtK0hnjrLnBECURifd6IkulybR+h+4UA==", "cpu": [ "arm64" ], @@ -1667,9 +2188,9 @@ } }, "node_modules/sass-embedded-darwin-x64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.86.3.tgz", - "integrity": "sha512-dfKhfrGPRNLWLC82vy/vQGmNKmAiKWpdFuWiePRtg/E95pqw+sCu6080Y6oQLfFu37Iq3MpnXiSpDuSo7UnPWA==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.93.2.tgz", + "integrity": "sha512-4KeAvlkQ0m0enKUnDGQJZwpovYw99iiMb8CTZRSsQm8Eh7halbJZVmx67f4heFY/zISgVOCcxNg19GrM5NTwtA==", "cpu": [ "x64" ], @@ -1684,9 +2205,9 @@ } }, "node_modules/sass-embedded-linux-arm": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.86.3.tgz", - "integrity": "sha512-+fVCIH+OR0SMHn2NEhb/VfbpHuUxcPtqMS34OCV3Ka99LYZUJZqth4M3lT/ppGl52mwIVLNYzR4iLe6mdZ6mYA==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.93.2.tgz", + "integrity": "sha512-N3+D/ToHtzwLDO+lSH05Wo6/KRxFBPnbjVHASOlHzqJnK+g5cqex7IFAp6ozzlRStySk61Rp6d+YGrqZ6/P0PA==", "cpu": [ "arm" ], @@ -1701,9 +2222,9 @@ } }, "node_modules/sass-embedded-linux-arm64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.86.3.tgz", - "integrity": "sha512-tYq5rywR53Qtc+0KI6pPipOvW7a47ETY69VxfqI9BR2RKw2hBbaz0bIw6OaOgEBv2/XNwcWb7a4sr7TqgkqKAA==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.93.2.tgz", + "integrity": "sha512-9ftX6nd5CsShJqJ2WRg+ptaYvUW+spqZfJ88FbcKQBNFQm6L87luj3UI1rB6cP5EWrLwHA754OKxRJyzWiaN6g==", "cpu": [ "arm64" ], @@ -1717,27 +2238,10 @@ "node": ">=14.0.0" } }, - "node_modules/sass-embedded-linux-ia32": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-ia32/-/sass-embedded-linux-ia32-1.86.3.tgz", - "integrity": "sha512-CmQ5OkqnaeLdaF+bMqlYGooBuenqm3LvEN9H8BLhjkpWiFW8hnYMetiqMcJjhrXLvDw601KGqA5sr/Rsg5s45g==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/sass-embedded-linux-musl-arm": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.86.3.tgz", - "integrity": "sha512-SEm65SQknI4pl+mH5Xf231hOkHJyrlgh5nj4qDbiBG6gFeutaNkNIeRgKEg3cflXchCr8iV/q/SyPgjhhzQb7w==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.93.2.tgz", + "integrity": "sha512-XBTvx66yRenvEsp3VaJCb3HQSyqCsUh7R+pbxcN5TuzueybZi0LXvn9zneksdXcmjACMlMpIVXi6LyHPQkYc8A==", "cpu": [ "arm" ], @@ -1752,9 +2256,9 @@ } }, "node_modules/sass-embedded-linux-musl-arm64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.86.3.tgz", - "integrity": "sha512-4zOr2C/eW89rxb4ozTfn7lBzyyM5ZigA1ZSRTcAR26Qbg/t2UksLdGnVX9/yxga0d6aOi0IvO/7iM2DPPRRotg==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.93.2.tgz", + "integrity": "sha512-+3EHuDPkMiAX5kytsjEC1bKZCawB9J6pm2eBIzzLMPWbf5xdx++vO1DpT7hD4bm4ZGn0eVHgSOKIfP6CVz6tVg==", "cpu": [ "arm64" ], @@ -1768,27 +2272,10 @@ "node": ">=14.0.0" } }, - "node_modules/sass-embedded-linux-musl-ia32": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-ia32/-/sass-embedded-linux-musl-ia32-1.86.3.tgz", - "integrity": "sha512-84Tcld32LB1loiqUvczWyVBQRCChm0wNLlkT59qF29nxh8njFIVf9yaPgXcSyyjpPoD9Tu0wnq3dvVzoMCh9AQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/sass-embedded-linux-musl-riscv64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.86.3.tgz", - "integrity": "sha512-IxEqoiD7vdNpiOwccybbV93NljBy64wSTkUOknGy21SyV43C8uqESOwTwW9ywa3KufImKm8L3uQAW/B0KhJMWg==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.93.2.tgz", + "integrity": "sha512-0sB5kmVZDKTYzmCSlTUnjh6mzOhzmQiW/NNI5g8JS4JiHw2sDNTvt1dsFTuqFkUHyEOY3ESTsfHHBQV8Ip4bEA==", "cpu": [ "riscv64" ], @@ -1803,9 +2290,9 @@ } }, "node_modules/sass-embedded-linux-musl-x64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.86.3.tgz", - "integrity": "sha512-ePeTPXUxPK6JgHcUfnrkIyDtyt+zlAvF22mVZv6y1g/PZFm1lSfX+Za7TYHg9KaYqaaXDiw6zICX4i44HhR8rA==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.93.2.tgz", + "integrity": "sha512-t3ejQ+1LEVuHy7JHBI2tWHhoMfhedUNDjGJR2FKaLgrtJntGnyD1RyX0xb3nuqL/UXiEAtmTmZY+Uh3SLUe1Hg==", "cpu": [ "x64" ], @@ -1820,9 +2307,9 @@ } }, "node_modules/sass-embedded-linux-riscv64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.86.3.tgz", - "integrity": "sha512-NuXQ72dwfNLe35E+RaXJ4Noq4EkFwM65eWwCwxEWyJO9qxOx1EXiCAJii6x8kkOh5daWuMU0VAI1B9RsJaqqQQ==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.93.2.tgz", + "integrity": "sha512-e7AndEwAbFtXaLy6on4BfNGTr3wtGZQmypUgYpSNVcYDO+CWxatKVY4cxbehMPhxG9g5ru+eaMfynvhZt7fLaA==", "cpu": [ "riscv64" ], @@ -1837,9 +2324,9 @@ } }, "node_modules/sass-embedded-linux-x64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.86.3.tgz", - "integrity": "sha512-t8be9zJ5B82+og9bQmIQ83yMGYZMTMrlGA+uGWtYacmwg6w3093dk91Fx0YzNSZBp3Tk60qVYjCZnEIwy60x0g==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.93.2.tgz", + "integrity": "sha512-U3EIUZQL11DU0xDDHXexd4PYPHQaSQa2hzc4EzmhHqrAj+TyfYO94htjWOd+DdTPtSwmLp+9cTWwPZBODzC96w==", "cpu": [ "x64" ], @@ -1853,10 +2340,27 @@ "node": ">=14.0.0" } }, + "node_modules/sass-embedded-unknown-all": { + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-unknown-all/-/sass-embedded-unknown-all-1.93.2.tgz", + "integrity": "sha512-7VnaOmyewcXohiuoFagJ3SK5ddP9yXpU0rzz+pZQmS1/+5O6vzyFCUoEt3HDRaLctH4GT3nUGoK1jg0ae62IfQ==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "!android", + "!darwin", + "!linux", + "!win32" + ], + "dependencies": { + "sass": "1.93.2" + } + }, "node_modules/sass-embedded-win32-arm64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.86.3.tgz", - "integrity": "sha512-4ghuAzjX4q8Nksm0aifRz8hgXMMxS0SuymrFfkfJlrSx68pIgvAge6AOw0edoZoe0Tf5ZbsWUWamhkNyNxkTvw==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.93.2.tgz", + "integrity": "sha512-Y90DZDbQvtv4Bt0GTXKlcT9pn4pz8AObEjFF8eyul+/boXwyptPZ/A1EyziAeNaIEIfxyy87z78PUgCeGHsx3Q==", "cpu": [ "arm64" ], @@ -1870,27 +2374,10 @@ "node": ">=14.0.0" } }, - "node_modules/sass-embedded-win32-ia32": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-win32-ia32/-/sass-embedded-win32-ia32-1.86.3.tgz", - "integrity": "sha512-tCaK4zIRq9mLRPxLzBAdYlfCuS/xLNpmjunYxeWkIwlJo+k53h1udyXH/FInnQ2GgEz0xMXyvH3buuPgzwWYsw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/sass-embedded-win32-x64": { - "version": "1.86.3", - "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.86.3.tgz", - "integrity": "sha512-zS+YNKfTF4SnOfpC77VTb0qNZyTXrxnAezSoRV0xnw6HlY+1WawMSSB6PbWtmbvyfXNgpmJUttoTtsvJjRCucg==", + "version": "1.93.2", + "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.93.2.tgz", + "integrity": "sha512-BbSucRP6PVRZGIwlEBkp+6VQl2GWdkWFMN+9EuOTPrLxCJZoq+yhzmbjspd3PeM8+7WJ7AdFu/uRYdO8tor1iQ==", "cpu": [ "x64" ], @@ -2012,14 +2499,14 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", - "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { "node": ">=12.0.0" @@ -2028,6 +2515,52 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -2043,11 +2576,12 @@ "license": "MIT" }, "node_modules/vite": { - "version": "6.3.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.4.tgz", - "integrity": "sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==", + "version": "6.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.6.tgz", + "integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -2117,17 +2651,50 @@ } } }, - "node_modules/vue": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz", - "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vue": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.22.tgz", + "integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==", + "license": "MIT", + "peer": true, "dependencies": { - "@vue/compiler-dom": "3.5.13", - "@vue/compiler-sfc": "3.5.13", - "@vue/runtime-dom": "3.5.13", - "@vue/server-renderer": "3.5.13", - "@vue/shared": "3.5.13" + "@vue/compiler-dom": "3.5.22", + "@vue/compiler-sfc": "3.5.22", + "@vue/runtime-dom": "3.5.22", + "@vue/server-renderer": "3.5.22", + "@vue/shared": "3.5.22" }, "peerDependencies": { "typescript": "*" @@ -2139,13 +2706,13 @@ } }, "node_modules/vue-i18n": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.1.3.tgz", - "integrity": "sha512-Pcylh9z9S5+CJAqgbRZ3EKxFIBIrtY5YUppU722GIT65+Nukm0TCqiQegZnNLCZkXGthxe0cpqj0AoM51H+6Gw==", + "version": "11.1.12", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.1.12.tgz", + "integrity": "sha512-BnstPj3KLHLrsqbVU2UOrPmr0+Mv11bsUZG0PyCOzsawCivk8W00GMXHeVUWIDOgNaScCuZah47CZFE+Wnl8mw==", "license": "MIT", "dependencies": { - "@intlify/core-base": "11.1.3", - "@intlify/shared": "11.1.3", + "@intlify/core-base": "11.1.12", + "@intlify/shared": "11.1.12", "@vue/devtools-api": "^6.5.0" }, "engines": { @@ -2170,9 +2737,9 @@ "license": "MIT" }, "node_modules/vue-router": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.0.tgz", - "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz", + "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==", "license": "MIT", "dependencies": { "@vue/devtools-api": "^6.6.4" diff --git a/frontend/package.json b/frontend/package.json index baf850f..f9d54a8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,9 +12,10 @@ "@fortawesome/fontawesome-free": "^6.7.2", "@kyvg/vue3-notification": "^3.4.1", "@popperjs/core": "^2.11.8", + "@simplewebauthn/browser": "^13.1.0", "@vojtechlanka/vue-tags-input": "^3.1.1", - "bootstrap": "^5.3.5", - "bootswatch": "^5.3.5", + "bootstrap": "^5.3.7", + "bootswatch": "^5.3.7", "flag-icons": "^7.3.2", "ip-address": "^10.0.1", "is-cidr": "^5.1.1", @@ -29,6 +30,6 @@ "devDependencies": { "@vitejs/plugin-vue": "^5.2.3", "sass-embedded": "^1.86.3", - "vite": "6.3.4" + "vite": "^6.3.6" } } diff --git a/frontend/src/App.vue b/frontend/src/App.vue index b2c3da5..7908168 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,6 +1,6 @@