diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
index 1cea2f5..0000000
--- a/.github/workflows/build.yml
+++ /dev/null
@@ -1,56 +0,0 @@
-name: Gameyfin CI Pipeline
-
-on:
- push:
- branches:
- - main
- pull_request:
- types: [opened, synchronize, reopened]
- workflow_dispatch:
-
-jobs:
- build:
- name: Build, Test & Scan
- runs-on: ubuntu-latest
- if: "!contains(github.event.head_commit.message, '[ci skip]')"
- steps:
- - name: Git checkout
- uses: actions/checkout@v4
- with:
- fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
-
- - name: Set up JDK
- uses: actions/setup-java@v4
- with:
- java-version: '21'
- distribution: 'temurin'
-
- - name: Cache SonarCloud packages
- uses: actions/cache@v4
- with:
- path: ~/.sonar/cache
- key: ${{ runner.os }}-sonar
- restore-keys: ${{ runner.os }}-sonar
-
- - name: Cache Maven packages
- uses: actions/cache@v4
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2
-
- - name: Extract Maven project version
- id: project
- run: echo "GAMEYFIN_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_OUTPUT
-
- - name: Build and analyze
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
- SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=grimsi_gameyfin
-
- - name: Upload build artifact
- uses: actions/upload-artifact@v4
- with:
- name: gameyfin-${{ steps.project.outputs.GAMEYFIN_VERSION }}.jar
- path: backend/target/gameyfin-*.jar
diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml
deleted file mode 100644
index c745f41..0000000
--- a/.github/workflows/docker-build-push.yml
+++ /dev/null
@@ -1,92 +0,0 @@
-name: Gameyfin Docker Build & Push
-
-on:
- workflow_dispatch:
- inputs:
- branch:
- description: "The branch to checkout when cutting the release."
- required: true
- default: "main"
- tag:
- description: "Docker image tag."
- required: true
- default: "X.Y.Z"
-
-jobs:
- release:
- runs-on: ubuntu-latest
- name: Release
- steps:
- - name: Git checkout
- uses: actions/checkout@v4
- with:
- ref: ${{ github.event.inputs.branch }}
-
- - name: Set up JDK
- uses: actions/setup-java@v4
- with:
- java-version: '21'
- distribution: 'temurin'
- cache: 'maven'
-
- - name: Configure Git User
- run: |
- git config user.email "actions@github.com"
- git config user.name "GitHub Actions"
-
- - name: Maven Package
- run: mvn package -B -s .maven_settings.xml -DreleaseVersion=${{ github.event.inputs.tag }} -Darguments="-Dmaven.deploy.skip=true -Dmaven.test.skip=true -Dmaven.javadoc.skip=true"
- env:
- GITHUB_ACTOR: ${{ github.actor }}
- GITHUB_TOKEN: ${{ github.token }}
-
- - name: Docker meta
- id: meta
- uses: docker/metadata-action@v5
- with:
- images: |
- grimsi/gameyfin
- tags: |
- type=semver,pattern={{version}},value=${{ github.event.inputs.tag }}
- type=semver,pattern={{major}}.{{minor}},value=${{ github.event.inputs.tag }}
- type=semver,pattern={{major}},value=${{ github.event.inputs.tag }}
-
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v3
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Cache Docker layers
- uses: actions/cache@v4
- with:
- path: /tmp/.buildx-cache
- key: ${{ runner.os }}-buildx-${{ github.sha }}
- restore-keys: |
- ${{ runner.os }}-buildx-
-
- - name: Login to Docker Hub
- uses: docker/login-action@v3
- with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_TOKEN }}
-
- - name: Build and push
- uses: docker/build-push-action@v5
- with:
- context: .
- file: ./docker/Dockerfile
- platforms: linux/amd64,linux/arm64
- push: true
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
- cache-from: type=local,src=/tmp/.buildx-cache
- cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
-
- - # Temp fix
- # https://github.com/docker/build-push-action/issues/252
- # https://github.com/moby/buildkit/issues/1896
- name: Move Docker cache (temp fix)
- run: |
- rm -rf /tmp/.buildx-cache
- mv /tmp/.buildx-cache-new /tmp/.buildx-cache
diff --git a/.github/workflows/pluginapi-release.yml b/.github/workflows/pluginapi-release.yml
new file mode 100644
index 0000000..5d45f2e
--- /dev/null
+++ b/.github/workflows/pluginapi-release.yml
@@ -0,0 +1,35 @@
+name: Plugin-API Release
+
+on:
+ push:
+ tags:
+ - '*'
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Set up Java
+ uses: actions/setup-java@v4
+ with:
+ distribution: temurin
+ java-version: 17
+ cache: gradle
+
+ - name: Decrypt and import GPG key
+ run: |
+ echo "$GPG_PRIVATE_KEY" | gpg --batch --import
+ env:
+ GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
+
+ - name: Build and deploy with JReleaser
+ run: ./gradlew jreleaserFullRelease
+ env:
+ GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
+ MAVENCENTRAL_USERNAME: ${{ secrets.MAVENCENTRAL_USERNAME }}
+ MAVENCENTRAL_TOKEN: ${{ secrets.MAVENCENTRAL_TOKEN }}
+ JRELEASER_GITHUB_TOKEN: ${{ GITHUB_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index ba192e7..0000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,114 +0,0 @@
-name: Gameyfin Release
-
-on:
- workflow_dispatch:
- inputs:
- branch:
- description: "The branch to checkout when cutting the release."
- required: true
- default: "main"
- releaseVersion:
- description: "Default version to use when preparing a release."
- required: true
- default: "X.Y.Z"
- developmentVersion:
- description: "Default version to use for new local working copy."
- required: true
- default: "X.Y.Z-SNAPSHOT"
-
-jobs:
- release:
- runs-on: ubuntu-latest
- name: Release
- steps:
- - name: Git checkout
- uses: actions/checkout@v4
- with:
- ref: ${{ github.event.inputs.branch }}
-
- - name: Set up JDK
- uses: actions/setup-java@v4
- with:
- java-version: '21'
- distribution: 'temurin'
- cache: 'maven'
-
- - name: Configure Git User
- run: |
- git config user.email "actions@github.com"
- git config user.name "GitHub Actions"
-
- - name: Maven Release
- run: mvn release:prepare release:perform -B -s .maven_settings.xml -DreleaseVersion=${{ github.event.inputs.releaseVersion }} -DdevelopmentVersion=${{ github.event.inputs.developmentVersion }} -Darguments="-Dmaven.deploy.skip=true -Dmaven.test.skip=true -Dmaven.javadoc.skip=true"
- env:
- GITHUB_ACTOR: ${{ github.actor }}
- GITHUB_TOKEN: ${{ github.token }}
-
- - name: Git tag
- uses: mathieudutour/github-tag-action@v6.2
- with:
- github_token: ${{ github.token }}
- default_bump: false
- custom_tag: ${{ github.event.inputs.releaseVersion }}
-
- - name: Github Release
- uses: "marvinpinto/action-automatic-releases@v1.2.1"
- with:
- repo_token: ${{ github.token }}
- prerelease: false
- automatic_release_tag: v${{ github.event.inputs.releaseVersion }}
- files: |
- LICENSE.md
- backend/target/gameyfin-*.jar
- config/gameyfin.properties
-
- - name: Docker meta
- id: meta
- uses: docker/metadata-action@v5
- with:
- images: |
- grimsi/gameyfin
- tags: |
- type=semver,pattern={{version}},value=${{ github.event.inputs.releaseVersion }}
- type=semver,pattern={{major}}.{{minor}},value=${{ github.event.inputs.releaseVersion }}
- type=semver,pattern={{major}},value=${{ github.event.inputs.releaseVersion }}
-
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v3
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Cache Docker layers
- uses: actions/cache@v4
- with:
- path: /tmp/.buildx-cache
- key: ${{ runner.os }}-buildx-${{ github.sha }}
- restore-keys: |
- ${{ runner.os }}-buildx-
-
- - name: Login to Docker Hub
- uses: docker/login-action@v3
- with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_TOKEN }}
-
- - name: Build and push
- uses: docker/build-push-action@v5
- with:
- context: .
- file: ./docker/Dockerfile
- platforms: linux/amd64,linux/arm64
- push: true
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
- cache-from: type=local,src=/tmp/.buildx-cache
- cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
-
- - # Temp fix
- # https://github.com/docker/build-push-action/issues/252
- # https://github.com/moby/buildkit/issues/1896
- name: Move Docker cache (temp fix)
- run: |
- rm -rf /tmp/.buildx-cache
- mv /tmp/.buildx-cache-new /tmp/.buildx-cache
diff --git a/.gitignore b/.gitignore
index bbaa093..4991fba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,10 @@
+node_modules
HELP.md
-target/
-!.mvn/wrapper/maven-wrapper.jar
-!**/src/main/**/target/
-!**/src/test/**/target/
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
### STS ###
.apt_generated
@@ -12,12 +14,18 @@ target/
.settings
.springBeans
.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
### NetBeans ###
/nbproject/private/
@@ -25,16 +33,22 @@ target/
/dist/
/nbdist/
/.nb-gradle/
-build/
-!**/src/main/**/build/
-!**/src/test/**/build/
### VS Code ###
.vscode/
-/.mvn/
+
+### Kotlin ###
+.kotlin
### Custom ###
-/data/
-/backend/src/main/resources/static/
-/docker/docker-compose.yml
-/.gameyfin/
+/generated
+/db
+/data
+/packaged_plugins
+/logs
+/templates
+/app/src/main/bundles/
+/app/src/main/frontend/**/*.js
+/app/src/main/frontend/**/*.js.map
+/app/src/main/frontend/generated/
+/torrent_dotfiles/
diff --git a/.maven_settings.xml b/.maven_settings.xml
deleted file mode 100644
index 2d0b3b8..0000000
--- a/.maven_settings.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- github
- ${env.GITHUB_ACTOR}
- ${env.GITHUB_TOKEN}
-
-
-
diff --git a/.run/Angular Application.run.xml b/.run/Angular Application.run.xml
deleted file mode 100644
index 4346cac..0000000
--- a/.run/Angular Application.run.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.run/Angular CLI Server.run.xml b/.run/Angular CLI Server.run.xml
deleted file mode 100644
index 60749b4..0000000
--- a/.run/Angular CLI Server.run.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.run/GameyfinApplication.run.xml b/.run/GameyfinApplication.run.xml
new file mode 100644
index 0000000..1c36705
--- /dev/null
+++ b/.run/GameyfinApplication.run.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/Generate Hilla sources.run.xml b/.run/Generate Hilla sources.run.xml
new file mode 100644
index 0000000..7f6f729
--- /dev/null
+++ b/.run/Generate Hilla sources.run.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ false
+ false
+
+
+
\ No newline at end of file
diff --git a/.run/Production build.run.xml b/.run/Production build.run.xml
new file mode 100644
index 0000000..c83bfc6
--- /dev/null
+++ b/.run/Production build.run.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ false
+ false
+
+
+
\ No newline at end of file
diff --git a/.run/Publish Plugin API.run.xml b/.run/Publish Plugin API.run.xml
new file mode 100644
index 0000000..67a2c3f
--- /dev/null
+++ b/.run/Publish Plugin API.run.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ false
+ false
+
+
+
\ No newline at end of file
diff --git a/.run/Rebuild all.run.xml b/.run/Rebuild all.run.xml
new file mode 100644
index 0000000..7e8ed26
--- /dev/null
+++ b/.run/Rebuild all.run.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ false
+ false
+
+
+
\ No newline at end of file
diff --git a/.run/Rebuild plugins.run.xml b/.run/Rebuild plugins.run.xml
new file mode 100644
index 0000000..caef427
--- /dev/null
+++ b/.run/Rebuild plugins.run.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ false
+ false
+
+
+
\ No newline at end of file
diff --git a/.run/UI debug.run.xml b/.run/UI debug.run.xml
new file mode 100644
index 0000000..ccfbe55
--- /dev/null
+++ b/.run/UI debug.run.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 2555f0c..f388138 100644
--- a/README.md
+++ b/README.md
@@ -1,46 +1,41 @@
-
-
Gameyfin
-
A simple game library manager.
+
+
Gameyfin
+
Manage your video games.
-# Overview
+> [!IMPORTANT]
+> Gameyfin v2 currently in beta stage.
+> Expect bugs and breaking changes until the `2.0.0` release.
+
+## Overview
Name and functionality inspired by [Jellyfin](https://jellyfin.org/).
-## Video
+### Features
-Click [this link](https://youtu.be/BSaccEm0tpo) to watch how to install and set up Gameyfin on your machine.
+✨ Automatically scans and indexes your game libraries
+⬇️ Access your library via your web browser & download games directly from there
+👥 Share your library with friends & family
+⚛️ LAN-friendly (everything is cached locally)
+🐋 Runs in a container or as single on bare metal
+🌈 Themes (including light and dark mode)
+🔌 Easily expandable with plugins
+🔒 Integrates into your SSO solution via OAuth2 / OpenID Connect
-## Features
+### Documentation
-* Automatically scans your game library folder and downloads additional metadata from IGDB
-* Access your library via your Web-Browser
-* Download games directly from your browser
-* LAN-friendly (everything is cached locally)
-* Native Docker support (alternatively it's only one .jar file to run on bare metal)
-* Light and dark theme
+The documentation is available at [gameyfin.org](https://gameyfin.org/).
-## Preview
+### Contribute to Gameyfin
-https://user-images.githubusercontent.com/9295182/197277953-d69464a4-d280-407b-9274-ae62e6917981.mp4
+Currently, no contribution guide is available. After the `2.0.0` release, contributions will be welcome.
-## Installation
+### Technical Details
-### General
+Gameyfin v2 is written in Kotlin and uses the following libraries/frameworks:
-Since Gameyfin loads information from IGDB, you need to register yourself there. Follow [this guide](https://api-docs.igdb.com/#account-creation).
-
-### Docker
-
-1. Download the `docker-compose.example.yml` file from this repository and rename it to just `docker-compose.yml`
-2. Edit the configuration values to your liking
-3. Run `docker-compose up -d`
-
-### Bare metal
-
-1. Make sure you have a JRE or JDK with version 18 or greater installed
-2. Download the latest `gameyfin.jar` and `gameyfin.properties` file from the releases page
-3. Edit the config options in the `gameyfin.properties` file
-4. Use the following command to start Gameyfin: `java -jar gameyfin.jar`
-5. Open the address of your Gameyfin host in your browser, Gameyfin runs under port 8080 by default
+* Spring Boot 3 for the backend
+* Vaadin Hilla & React for the frontend
+* PF4J for the plugin system
+* H2 database for persistence
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
new file mode 100644
index 0000000..17ba943
--- /dev/null
+++ b/app/build.gradle.kts
@@ -0,0 +1,93 @@
+group = "de.grimsi"
+val appMainClass = "org.gameyfin.GameyfinApplicationKt"
+
+plugins {
+ id("org.springframework.boot")
+ id("io.spring.dependency-management")
+ id("com.vaadin")
+ kotlin("jvm")
+ kotlin("plugin.spring")
+ kotlin("plugin.jpa")
+ id("com.google.devtools.ksp")
+ application
+}
+
+application {
+ mainClass.set(appMainClass)
+}
+
+allOpen {
+ annotations("javax.persistence.Entity", "javax.persistence.MappedSuperclass", "javax.persistence.Embedabble")
+}
+
+repositories {
+ maven {
+ setUrl("https://maven.vaadin.com/vaadin-addons")
+ }
+}
+
+dependencies {
+ // Spring Boot
+ implementation("org.springframework.boot:spring-boot-starter-actuator")
+ implementation("org.springframework.boot:spring-boot-starter-security")
+ implementation("org.springframework.boot:spring-boot-starter-validation")
+ implementation("org.springframework.cloud:spring-cloud-starter")
+ implementation("jakarta.validation:jakarta.validation-api:3.1.0")
+
+ // Kotlin extensions
+ implementation(kotlin("reflect"))
+
+ // Reactive
+ implementation("org.springframework.boot:spring-boot-starter-webflux")
+ implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
+
+ // Vaadin Hilla
+ implementation("com.vaadin:vaadin-core") {
+ exclude("com.vaadin:flow-react")
+ }
+ implementation("com.vaadin:vaadin-spring-boot-starter")
+
+ // Logging
+ implementation("io.github.oshai:kotlin-logging-jvm:7.0.3")
+
+ // Persistence & I/O
+ implementation("org.springframework.boot:spring-boot-starter-data-jpa")
+ implementation("com.github.paulcwarren:spring-content-fs-boot-starter:3.0.17")
+ implementation("commons-io:commons-io:2.18.0")
+
+ // SSO
+ implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
+ implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
+ implementation("org.springframework.security:spring-security-oauth2-jose")
+
+ // Notifications
+ implementation("org.springframework.boot:spring-boot-starter-mail")
+ implementation("ch.digitalfondue.mjml4j:mjml4j:1.0.3")
+
+ // Plugins
+ implementation(project(":plugin-api"))
+
+ // Utils
+ implementation("org.apache.tika:tika-core:3.1.0")
+ implementation("me.xdrop:fuzzywuzzy:1.4.0")
+
+ // Development
+ developmentOnly("org.springframework.boot:spring-boot-devtools")
+ annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
+ runtimeOnly("com.h2database:h2")
+ runtimeOnly("io.micrometer:micrometer-registry-prometheus")
+ testImplementation("org.springframework.boot:spring-boot-starter-test")
+ testImplementation("org.springframework.security:spring-security-test")
+}
+
+dependencyManagement {
+ imports {
+ mavenBom("com.vaadin:vaadin-bom:${rootProject.extra["vaadinVersion"]}")
+ mavenBom("org.springframework.cloud:spring-cloud-dependencies:${rootProject.extra["springCloudVersion"]}")
+ }
+}
+
+tasks.withType {
+ useJUnitPlatform()
+}
\ No newline at end of file
diff --git a/app/gradle/libs.versions.toml b/app/gradle/libs.versions.toml
new file mode 100644
index 0000000..d0de2ed
--- /dev/null
+++ b/app/gradle/libs.versions.toml
@@ -0,0 +1,26 @@
+# This file was generated by the Gradle 'init' task.
+# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format
+
+[versions]
+com-h2database-h2 = "2.2.224"
+dev-hilla-hilla-react = "2.5.6"
+dev-hilla-hilla-spring-boot-starter = "2.5.6"
+org-parttio-line-awesome = "2.0.0"
+org-springframework-boot-spring-boot-devtools = "3.2.2"
+org-springframework-boot-spring-boot-starter-data-jpa = "3.2.2"
+org-springframework-boot-spring-boot-starter-oauth2-resource-server = "3.2.2"
+org-springframework-boot-spring-boot-starter-security = "3.2.2"
+org-springframework-boot-spring-boot-starter-test = "3.2.2"
+org-springframework-boot-spring-boot-starter-validation = "3.2.2"
+
+[libraries]
+com-h2database-h2 = { module = "com.h2database:h2", version.ref = "com-h2database-h2" }
+dev-hilla-hilla-react = { module = "dev.hilla:hilla-react", version.ref = "dev-hilla-hilla-react" }
+dev-hilla-hilla-spring-boot-starter = { module = "dev.hilla:hilla-spring-boot-starter", version.ref = "dev-hilla-hilla-spring-boot-starter" }
+org-parttio-line-awesome = { module = "org.parttio:line-awesome", version.ref = "org-parttio-line-awesome" }
+org-springframework-boot-spring-boot-devtools = { module = "org.springframework.boot:spring-boot-devtools", version.ref = "org-springframework-boot-spring-boot-devtools" }
+org-springframework-boot-spring-boot-starter-data-jpa = { module = "org.springframework.boot:spring-boot-starter-data-jpa", version.ref = "org-springframework-boot-spring-boot-starter-data-jpa" }
+org-springframework-boot-spring-boot-starter-oauth2-resource-server = { module = "org.springframework.boot:spring-boot-starter-oauth2-resource-server", version.ref = "org-springframework-boot-spring-boot-starter-oauth2-resource-server" }
+org-springframework-boot-spring-boot-starter-security = { module = "org.springframework.boot:spring-boot-starter-security", version.ref = "org-springframework-boot-spring-boot-starter-security" }
+org-springframework-boot-spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test", version.ref = "org-springframework-boot-spring-boot-starter-test" }
+org-springframework-boot-spring-boot-starter-validation = { module = "org.springframework.boot:spring-boot-starter-validation", version.ref = "org-springframework-boot-spring-boot-starter-validation" }
diff --git a/app/gradle/wrapper/gradle-wrapper.jar b/app/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e644113
Binary files /dev/null and b/app/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/app/gradle/wrapper/gradle-wrapper.properties b/app/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..df97d72
--- /dev/null
+++ b/app/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/app/gradlew b/app/gradlew
new file mode 100644
index 0000000..b740cf1
--- /dev/null
+++ b/app/gradlew
@@ -0,0 +1,249 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/app/gradlew.bat b/app/gradlew.bat
new file mode 100644
index 0000000..25da30d
--- /dev/null
+++ b/app/gradlew.bat
@@ -0,0 +1,92 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/app/heroui.ts b/app/heroui.ts
new file mode 100644
index 0000000..cbbf6ee
--- /dev/null
+++ b/app/heroui.ts
@@ -0,0 +1,7 @@
+import {HeroUIPluginConfig} from "@heroui/react";
+import {compileThemes, themes} from "./src/main/frontend/theming/themes"
+
+export const HeroUIConfig: HeroUIPluginConfig = {
+ prefix: "gf",
+ themes: compileThemes(themes)
+};
\ No newline at end of file
diff --git a/app/package-lock.json b/app/package-lock.json
new file mode 100644
index 0000000..558b7bd
--- /dev/null
+++ b/app/package-lock.json
@@ -0,0 +1,17764 @@
+{
+ "name": "gameyfin",
+ "version": "2.0.0-ALPHA",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "gameyfin",
+ "version": "2.0.0-ALPHA",
+ "dependencies": {
+ "@heroui/react": "2.7.9",
+ "@material-tailwind/react": "^2.1.10",
+ "@phosphor-icons/react": "^2.1.7",
+ "@polymer/polymer": "3.5.2",
+ "@react-stately/data": "^3.12.2",
+ "@react-types/shared": "^3.28.0",
+ "@vaadin/bundles": "24.8.0-rc1",
+ "@vaadin/common-frontend": "0.0.19",
+ "@vaadin/hilla-file-router": "24.8.0-rc1",
+ "@vaadin/hilla-frontend": "24.8.0-rc1",
+ "@vaadin/hilla-lit-form": "24.8.0-rc1",
+ "@vaadin/hilla-react-auth": "24.8.0-rc1",
+ "@vaadin/hilla-react-crud": "24.8.0-rc1",
+ "@vaadin/hilla-react-form": "24.8.0-rc1",
+ "@vaadin/hilla-react-i18n": "24.8.0-rc1",
+ "@vaadin/hilla-react-signals": "24.8.0-rc1",
+ "@vaadin/polymer-legacy-adapter": "24.8.0-rc1",
+ "@vaadin/react-components": "24.8.0-rc1",
+ "@vaadin/vaadin-development-mode-detector": "2.0.7",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "@vaadin/vaadin-usage-statistics": "2.1.3",
+ "classnames": "^2.5.1",
+ "construct-style-sheets-polyfill": "3.1.0",
+ "cron-validator": "^1.3.1",
+ "date-fns": "2.29.3",
+ "formik": "^2.4.6",
+ "framer-motion": "^12.5.0",
+ "fzf": "^0.5.2",
+ "http-status-codes": "^2.3.0",
+ "lit": "3.3.0",
+ "moment": "^2.30.1",
+ "moment-timezone": "^0.5.47",
+ "next-themes": "^0.4.6",
+ "rand-seed": "^2.1.7",
+ "react": "18.3.1",
+ "react-accessible-treeview": "^2.11.1",
+ "react-aria-components": "^1.7.1",
+ "react-confetti-boom": "^1.0.0",
+ "react-dom": "18.3.1",
+ "react-markdown": "^10.1.0",
+ "react-player": "^2.16.0",
+ "react-router": "7.6.1",
+ "remark-breaks": "^4.0.0",
+ "swiper": "^11.2.6",
+ "valtio": "^2.1.5",
+ "valtio-reactive": "^0.1.2",
+ "yup": "^1.6.1"
+ },
+ "devDependencies": {
+ "@babel/preset-react": "7.27.1",
+ "@lit-labs/react": "^2.1.3",
+ "@preact/signals-react-transform": "0.5.1",
+ "@rollup/plugin-replace": "6.0.2",
+ "@rollup/pluginutils": "5.1.4",
+ "@types/node": "^22.4.0",
+ "@types/react": "18.3.23",
+ "@types/react-dom": "18.3.7",
+ "@vaadin/hilla-generator-cli": "24.8.0-rc1",
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-backbone": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-barrel": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-client": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-model": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-push": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-signals": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-subtypes": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-transfertypes": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "@vitejs/plugin-react": "4.5.0",
+ "@vitejs/plugin-react-swc": "^3.7.0",
+ "async": "3.2.6",
+ "autoprefixer": "^10.4.20",
+ "glob": "11.0.2",
+ "magic-string": "0.30.17",
+ "postcss": "^8.4.41",
+ "postcss-import": "^16.1.0",
+ "rollup-plugin-brotli": "3.1.0",
+ "rollup-plugin-visualizer": "5.14.0",
+ "strip-css-comments": "5.0.0",
+ "tailwindcss": "^3.4.13",
+ "transform-ast": "2.4.4",
+ "typescript": "5.8.3",
+ "vite": "6.3.5",
+ "vite-plugin-checker": "0.9.3",
+ "workbox-build": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-precaching": "7.3.0"
+ }
+ },
+ "node_modules/@alloc/quick-lru": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@apideck/better-ajv-errors": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz",
+ "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-schema": "^0.4.0",
+ "jsonpointer": "^5.0.0",
+ "leven": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "ajv": ">=8"
+ }
+ },
+ "node_modules/@apidevtools/json-schema-ref-parser": {
+ "version": "11.7.2",
+ "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.2.tgz",
+ "integrity": "sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jsdevtools/ono": "^7.1.3",
+ "@types/json-schema": "^7.0.15",
+ "js-yaml": "^4.1.0"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/philsturgeon"
+ }
+ },
+ "node_modules/@apidevtools/openapi-schemas": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz",
+ "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@apidevtools/swagger-methods": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz",
+ "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@apidevtools/swagger-parser": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.1.1.tgz",
+ "integrity": "sha512-u/kozRnsPO/x8QtKYJOqoGtC4kH6yg1lfYkB9Au0WhYB0FNLpyFusttQtvhlwjtG3rOwiRz4D8DnnXa8iEpIKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@apidevtools/json-schema-ref-parser": "11.7.2",
+ "@apidevtools/openapi-schemas": "^2.1.0",
+ "@apidevtools/swagger-methods": "^3.0.2",
+ "@jsdevtools/ono": "^7.1.3",
+ "ajv": "^8.17.1",
+ "ajv-draft-04": "^1.0.0",
+ "call-me-maybe": "^1.0.2"
+ },
+ "peerDependencies": {
+ "openapi-types": ">=7"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.1.tgz",
+ "integrity": "sha512-Q+E+rd/yBzNQhXkG+zQnF58e4zoZfBedaxwzPmicKsiK3nt8iJYrSrDbjwFFDGC4f+rPafqRaPH6TsDoSvMf7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz",
+ "integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.27.1",
+ "@babel/helper-compilation-targets": "^7.27.1",
+ "@babel/helper-module-transforms": "^7.27.1",
+ "@babel/helpers": "^7.27.1",
+ "@babel/parser": "^7.27.1",
+ "@babel/template": "^7.27.1",
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.1.tgz",
+ "integrity": "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.27.1",
+ "@babel/types": "^7.27.1",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.27.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+ "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.27.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.1.tgz",
+ "integrity": "sha512-2YaDd/Rd9E598B5+WIc8wJPmWETiiJXFYVE60oX8FDohv7rAUU3CQj+A1MgeEmcsk2+dQuEjIe/GDvig0SqL4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.27.1",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz",
+ "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-member-expression-to-functions": "^7.25.9",
+ "@babel/helper-optimise-call-expression": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin": {
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz",
+ "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "regexpu-core": "^6.2.0",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz",
+ "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.22.6",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "debug": "^4.1.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.14.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz",
+ "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
+ "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.1.tgz",
+ "integrity": "sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/traverse": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz",
+ "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
+ "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz",
+ "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-wrap-function": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz",
+ "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-member-expression-to-functions": "^7.25.9",
+ "@babel/helper-optimise-call-expression": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
+ "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz",
+ "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz",
+ "integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.1.tgz",
+ "integrity": "sha512-I0dZ3ZpCrJ1c04OqlNsQcKiZlsrXf/kkE4FXzID9rIOYICsAbA8mMDzhW/luRNAHdCNt7os/u8wenklZDlUVUQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.27.1"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz",
+ "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz",
+ "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz",
+ "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz",
+ "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+ "@babel/plugin-transform-optional-chaining": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.13.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz",
+ "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-private-property-in-object": {
+ "version": "7.21.0-placeholder-for-preset-env.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+ "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-assertions": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz",
+ "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
+ "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz",
+ "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+ "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-arrow-functions": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz",
+ "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-generator-functions": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz",
+ "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-remap-async-to-generator": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz",
+ "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-remap-async-to-generator": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz",
+ "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz",
+ "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-properties": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz",
+ "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-class-static-block": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz",
+ "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.12.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz",
+ "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-computed-properties": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz",
+ "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/template": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-destructuring": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz",
+ "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dotall-regex": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz",
+ "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-keys": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz",
+ "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz",
+ "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dynamic-import": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz",
+ "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz",
+ "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-export-namespace-from": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz",
+ "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-for-of": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz",
+ "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz",
+ "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-json-strings": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz",
+ "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-literals": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz",
+ "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz",
+ "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-member-expression-literals": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz",
+ "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-amd": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz",
+ "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz",
+ "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-systemjs": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz",
+ "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-umd": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz",
+ "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz",
+ "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-new-target": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz",
+ "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz",
+ "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-numeric-separator": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz",
+ "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-rest-spread": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz",
+ "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/plugin-transform-parameters": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-super": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz",
+ "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-catch-binding": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz",
+ "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-optional-chaining": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz",
+ "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-parameters": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz",
+ "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-methods": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz",
+ "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-private-property-in-object": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz",
+ "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-property-literals": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz",
+ "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-display-name": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.27.1.tgz",
+ "integrity": "sha512-p9+Vl3yuHPmkirRrg021XiP+EETmPMQTLr6Ayjj85RLNEbb3Eya/4VI0vAdzQG9SEAl2Lnt7fy5lZyMzjYoZQQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz",
+ "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-development": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz",
+ "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/plugin-transform-react-jsx": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz",
+ "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz",
+ "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-pure-annotations": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz",
+ "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regenerator": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz",
+ "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "regenerator-transform": "^0.15.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regexp-modifiers": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz",
+ "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-reserved-words": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
+ "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-shorthand-properties": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz",
+ "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-spread": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz",
+ "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-sticky-regex": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz",
+ "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-template-literals": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz",
+ "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typeof-symbol": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz",
+ "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-escapes": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz",
+ "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-property-regex": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz",
+ "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-regex": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz",
+ "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-sets-regex": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz",
+ "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/preset-env": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz",
+ "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.26.0",
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-validator-option": "^7.25.9",
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9",
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9",
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9",
+ "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
+ "@babel/plugin-syntax-import-assertions": "^7.26.0",
+ "@babel/plugin-syntax-import-attributes": "^7.26.0",
+ "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
+ "@babel/plugin-transform-arrow-functions": "^7.25.9",
+ "@babel/plugin-transform-async-generator-functions": "^7.25.9",
+ "@babel/plugin-transform-async-to-generator": "^7.25.9",
+ "@babel/plugin-transform-block-scoped-functions": "^7.25.9",
+ "@babel/plugin-transform-block-scoping": "^7.25.9",
+ "@babel/plugin-transform-class-properties": "^7.25.9",
+ "@babel/plugin-transform-class-static-block": "^7.26.0",
+ "@babel/plugin-transform-classes": "^7.25.9",
+ "@babel/plugin-transform-computed-properties": "^7.25.9",
+ "@babel/plugin-transform-destructuring": "^7.25.9",
+ "@babel/plugin-transform-dotall-regex": "^7.25.9",
+ "@babel/plugin-transform-duplicate-keys": "^7.25.9",
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9",
+ "@babel/plugin-transform-dynamic-import": "^7.25.9",
+ "@babel/plugin-transform-exponentiation-operator": "^7.25.9",
+ "@babel/plugin-transform-export-namespace-from": "^7.25.9",
+ "@babel/plugin-transform-for-of": "^7.25.9",
+ "@babel/plugin-transform-function-name": "^7.25.9",
+ "@babel/plugin-transform-json-strings": "^7.25.9",
+ "@babel/plugin-transform-literals": "^7.25.9",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.25.9",
+ "@babel/plugin-transform-member-expression-literals": "^7.25.9",
+ "@babel/plugin-transform-modules-amd": "^7.25.9",
+ "@babel/plugin-transform-modules-commonjs": "^7.25.9",
+ "@babel/plugin-transform-modules-systemjs": "^7.25.9",
+ "@babel/plugin-transform-modules-umd": "^7.25.9",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9",
+ "@babel/plugin-transform-new-target": "^7.25.9",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9",
+ "@babel/plugin-transform-numeric-separator": "^7.25.9",
+ "@babel/plugin-transform-object-rest-spread": "^7.25.9",
+ "@babel/plugin-transform-object-super": "^7.25.9",
+ "@babel/plugin-transform-optional-catch-binding": "^7.25.9",
+ "@babel/plugin-transform-optional-chaining": "^7.25.9",
+ "@babel/plugin-transform-parameters": "^7.25.9",
+ "@babel/plugin-transform-private-methods": "^7.25.9",
+ "@babel/plugin-transform-private-property-in-object": "^7.25.9",
+ "@babel/plugin-transform-property-literals": "^7.25.9",
+ "@babel/plugin-transform-regenerator": "^7.25.9",
+ "@babel/plugin-transform-regexp-modifiers": "^7.26.0",
+ "@babel/plugin-transform-reserved-words": "^7.25.9",
+ "@babel/plugin-transform-shorthand-properties": "^7.25.9",
+ "@babel/plugin-transform-spread": "^7.25.9",
+ "@babel/plugin-transform-sticky-regex": "^7.25.9",
+ "@babel/plugin-transform-template-literals": "^7.25.9",
+ "@babel/plugin-transform-typeof-symbol": "^7.25.9",
+ "@babel/plugin-transform-unicode-escapes": "^7.25.9",
+ "@babel/plugin-transform-unicode-property-regex": "^7.25.9",
+ "@babel/plugin-transform-unicode-regex": "^7.25.9",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.25.9",
+ "@babel/preset-modules": "0.1.6-no-external-plugins",
+ "babel-plugin-polyfill-corejs2": "^0.4.10",
+ "babel-plugin-polyfill-corejs3": "^0.10.6",
+ "babel-plugin-polyfill-regenerator": "^0.6.1",
+ "core-js-compat": "^3.38.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-modules": {
+ "version": "0.1.6-no-external-plugins",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
+ "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/@babel/preset-react": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.27.1.tgz",
+ "integrity": "sha512-oJHWh2gLhU9dW9HHr42q0cI0/iHHXTLGe39qvpAZZzagHy0MzYLCnCVV0symeRvzmjHyVU7mw2K06E6u/JwbhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/helper-validator-option": "^7.27.1",
+ "@babel/plugin-transform-react-display-name": "^7.27.1",
+ "@babel/plugin-transform-react-jsx": "^7.27.1",
+ "@babel/plugin-transform-react-jsx-development": "^7.27.1",
+ "@babel/plugin-transform-react-pure-annotations": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
+ "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
+ "license": "MIT",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.1.tgz",
+ "integrity": "sha512-Fyo3ghWMqkHHpHQCoBs2VnYjR4iWFFjguTDEqA5WgZDOrFesVjMhMM2FSqTKSoUSDO1VQtavj8NFpdRBEvJTtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/parser": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.1.tgz",
+ "integrity": "sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.27.1",
+ "@babel/parser": "^7.27.1",
+ "@babel/template": "^7.27.1",
+ "@babel/types": "^7.27.1",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.27.3",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.3.tgz",
+ "integrity": "sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz",
+ "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz",
+ "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz",
+ "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz",
+ "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz",
+ "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz",
+ "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz",
+ "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz",
+ "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz",
+ "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz",
+ "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz",
+ "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz",
+ "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz",
+ "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz",
+ "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz",
+ "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz",
+ "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz",
+ "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz",
+ "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz",
+ "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz",
+ "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz",
+ "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz",
+ "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz",
+ "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz",
+ "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz",
+ "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.6.8",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz",
+ "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.8"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.6.12",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz",
+ "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.6.0",
+ "@floating-ui/utils": "^0.2.8"
+ }
+ },
+ "node_modules/@floating-ui/react": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.19.0.tgz",
+ "integrity": "sha512-fgYvN4ksCi5OvmPXkyOT8o5a8PSKHMzPHt+9mR6KYWdF16IAjWRLZPAAziI2sznaWT23drRFrYw64wdvYqqaQw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react-dom": "^1.2.2",
+ "aria-hidden": "^1.1.3",
+ "tabbable": "^6.0.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@floating-ui/react-dom": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.3.0.tgz",
+ "integrity": "sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.2.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
+ "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==",
+ "license": "MIT"
+ },
+ "node_modules/@formatjs/ecma402-abstract": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.4.tgz",
+ "integrity": "sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/fast-memoize": "2.2.7",
+ "@formatjs/intl-localematcher": "0.6.1",
+ "decimal.js": "^10.4.3",
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@formatjs/fast-memoize": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz",
+ "integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@formatjs/icu-messageformat-parser": {
+ "version": "2.11.2",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.2.tgz",
+ "integrity": "sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.3.4",
+ "@formatjs/icu-skeleton-parser": "1.8.14",
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@formatjs/icu-skeleton-parser": {
+ "version": "1.8.14",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.14.tgz",
+ "integrity": "sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.3.4",
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@formatjs/intl-localematcher": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.1.tgz",
+ "integrity": "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@heroui/accordion": {
+ "version": "2.2.17",
+ "resolved": "https://registry.npmjs.org/@heroui/accordion/-/accordion-2.2.17.tgz",
+ "integrity": "sha512-HrFl5cVtmNt+5pVboMmw0Eo21Ikx+pPZjvxm1GaFayCaaQD1gvLcISPSQF4rOft+197FA8vuk9Ke5UsBy0Ylig==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/aria-utils": "2.2.17",
+ "@heroui/divider": "2.2.14",
+ "@heroui/dom-animation": "2.1.9",
+ "@heroui/framer-utils": "2.1.16",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-aria-accordion": "2.2.12",
+ "@react-aria/button": "3.13.1",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/tree": "3.8.10",
+ "@react-types/accordion": "3.0.0-alpha.26",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/accordion/node_modules/@react-aria/button": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.13.1.tgz",
+ "integrity": "sha512-E49qcbBRgofXYfWbli50bepWVNtQBq7qewL9XsX7nHkwPPUe1IRwJOnWZqYMgwwhUBOXfnsR6/TssiXqZsrJdw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/toolbar": "3.0.0-beta.16",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/toggle": "^3.8.4",
+ "@react-types/button": "^3.12.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/accordion/node_modules/@react-aria/toolbar": {
+ "version": "3.0.0-beta.16",
+ "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.16.tgz",
+ "integrity": "sha512-TnNvtxADalMzs9Et51hWPpGyiHr1dt++UYR7pIo1H7vO+HwXl6uH4HxbFDS5CyV69j2cQlcGrkj13LoWFkBECw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/alert": {
+ "version": "2.2.20",
+ "resolved": "https://registry.npmjs.org/@heroui/alert/-/alert-2.2.20.tgz",
+ "integrity": "sha512-qGrZ3NkbKs30CzbAabLwJT4wzafJPZb7YCLpK8V1NwEEkwCGVZUsnAV6XmYHqJ7yiDyx9saq/W3laOeDyDT7Fw==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/button": "2.2.20",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/utils": "3.10.6"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/aria-utils": {
+ "version": "2.2.17",
+ "resolved": "https://registry.npmjs.org/@heroui/aria-utils/-/aria-utils-2.2.17.tgz",
+ "integrity": "sha512-DIUYSpMPb8NeKHIFqS/xfHR5uBtBFG2hdcVXgZ3DBIqiXKAiNQ6L+vSf9h3P3wXFzupqaRPvmpqQ31Oh7830Dg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-rsc-utils": "2.1.7",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/system": "2.4.16",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/collections": "3.12.4",
+ "@react-stately/overlays": "3.6.16",
+ "@react-types/overlays": "3.8.15",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/autocomplete": {
+ "version": "2.3.21",
+ "resolved": "https://registry.npmjs.org/@heroui/autocomplete/-/autocomplete-2.3.21.tgz",
+ "integrity": "sha512-tpLO22HVV09TTtRTvFf3yLozxPiFEHBGsWTQ7WM5XzM264YtwUjuXS669rw/tGsOqhjxXF9+WgQ8cnfssTk8yw==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/aria-utils": "2.2.17",
+ "@heroui/button": "2.2.20",
+ "@heroui/form": "2.1.19",
+ "@heroui/input": "2.4.20",
+ "@heroui/listbox": "2.3.19",
+ "@heroui/popover": "2.3.20",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/scroll-shadow": "2.3.13",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/spinner": "2.2.17",
+ "@heroui/use-aria-button": "2.2.14",
+ "@heroui/use-safe-layout-effect": "2.1.7",
+ "@react-aria/combobox": "3.12.3",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/i18n": "3.12.9",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-aria/visually-hidden": "3.8.23",
+ "@react-stately/combobox": "3.10.5",
+ "@react-types/combobox": "3.13.5",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/autocomplete/node_modules/@react-aria/combobox": {
+ "version": "3.12.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.12.3.tgz",
+ "integrity": "sha512-nCLFSQjOR3r3tB1AURtZKSZhi2euBMw0QxsIjnMVF73BQOfwfHMrIFctNULbL070gEnXofzeBd3ykJQpnsGH+Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/listbox": "^3.14.4",
+ "@react-aria/live-announcer": "^3.4.2",
+ "@react-aria/menu": "^3.18.3",
+ "@react-aria/overlays": "^3.27.1",
+ "@react-aria/selection": "^3.24.1",
+ "@react-aria/textfield": "^3.17.3",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/collections": "^3.12.4",
+ "@react-stately/combobox": "^3.10.5",
+ "@react-stately/form": "^3.1.4",
+ "@react-types/button": "^3.12.1",
+ "@react-types/combobox": "^3.13.5",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/avatar": {
+ "version": "2.2.16",
+ "resolved": "https://registry.npmjs.org/@heroui/avatar/-/avatar-2.2.16.tgz",
+ "integrity": "sha512-txhzfQf4krNvEWLRk8DCU2kzIJO+CaaWpr/CGyB1XuyHYM9jRpS2G7PwxsQs7BRyAv//Pk3mFBYqsb0lSti/2g==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-image": "2.1.9",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/utils": "3.29.0"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/badge": {
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/@heroui/badge/-/badge-2.2.12.tgz",
+ "integrity": "sha512-JVvsmgHzvNDHMSW0/51LaikjTIxm59dU7Bvgp6bN5MuWgMvdhVcrrBskyy98uk7B4i8yYEfzfKBOPU3apZGAug==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/breadcrumbs": {
+ "version": "2.2.16",
+ "resolved": "https://registry.npmjs.org/@heroui/breadcrumbs/-/breadcrumbs-2.2.16.tgz",
+ "integrity": "sha512-F+jc/0oKv0yagWaWg+/VGwBxS5yacDFlMQOXDdCDL4ra2ky8/lb/o6VV/RfLLafazLsIj9WN1i9voSfw4aMMLA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@react-aria/breadcrumbs": "3.5.24",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/utils": "3.29.0",
+ "@react-types/breadcrumbs": "3.7.13",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/breadcrumbs/node_modules/@react-aria/breadcrumbs": {
+ "version": "3.5.24",
+ "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.24.tgz",
+ "integrity": "sha512-CRheGyyM8afPJvDHLXn/mmGG/WAr/z2LReK3DlPdxVKcsOn7g3NIRxAcAIAJQlDLdOiu1SXHiZe6uu2jPhHrxA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/link": "^3.8.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/breadcrumbs": "^3.7.13",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/button": {
+ "version": "2.2.20",
+ "resolved": "https://registry.npmjs.org/@heroui/button/-/button-2.2.20.tgz",
+ "integrity": "sha512-EAh+W518U1Im2/jSTfJqiKxlnQP/I2eSZSdUOVs83HEaFRnUBq7fHw+JxVNroqxxb+A6vzpiCeyX1m4tm53xNA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/ripple": "2.2.15",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/spinner": "2.2.17",
+ "@heroui/use-aria-button": "2.2.14",
+ "@react-aria/button": "3.13.1",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-types/button": "3.12.1",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/button/node_modules/@react-aria/button": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.13.1.tgz",
+ "integrity": "sha512-E49qcbBRgofXYfWbli50bepWVNtQBq7qewL9XsX7nHkwPPUe1IRwJOnWZqYMgwwhUBOXfnsR6/TssiXqZsrJdw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/toolbar": "3.0.0-beta.16",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/toggle": "^3.8.4",
+ "@react-types/button": "^3.12.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/button/node_modules/@react-aria/toolbar": {
+ "version": "3.0.0-beta.16",
+ "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.16.tgz",
+ "integrity": "sha512-TnNvtxADalMzs9Et51hWPpGyiHr1dt++UYR7pIo1H7vO+HwXl6uH4HxbFDS5CyV69j2cQlcGrkj13LoWFkBECw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/calendar": {
+ "version": "2.2.20",
+ "resolved": "https://registry.npmjs.org/@heroui/calendar/-/calendar-2.2.20.tgz",
+ "integrity": "sha512-WJKGeFuZtUgsgVIP9psBw9+S2Fk0dhMzfs3K2OZIODIfTifq7vXzMnEWOYOVqiD/v0oKNvb6uPyIuW18bXWVVg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/button": "2.2.20",
+ "@heroui/dom-animation": "2.1.9",
+ "@heroui/framer-utils": "2.1.16",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-aria-button": "2.2.14",
+ "@internationalized/date": "3.8.1",
+ "@react-aria/calendar": "3.8.1",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/i18n": "3.12.9",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-aria/visually-hidden": "3.8.23",
+ "@react-stately/calendar": "3.8.1",
+ "@react-stately/utils": "3.10.6",
+ "@react-types/button": "3.12.1",
+ "@react-types/calendar": "3.7.1",
+ "@react-types/shared": "3.29.1",
+ "@types/lodash.debounce": "^4.0.7",
+ "scroll-into-view-if-needed": "3.0.10"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/calendar/node_modules/@react-aria/calendar": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.8.1.tgz",
+ "integrity": "sha512-S931yi8jJ6CgUQJk+h/PEl+V0n1dUYr9n6nKXmZeU3940to4DauqwvmD9sg67hFHJ0QGroHT/s29yIfa5MfQcg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/date": "^3.8.1",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/live-announcer": "^3.4.2",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/calendar": "^3.8.1",
+ "@react-types/button": "^3.12.1",
+ "@react-types/calendar": "^3.7.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/card": {
+ "version": "2.2.19",
+ "resolved": "https://registry.npmjs.org/@heroui/card/-/card-2.2.19.tgz",
+ "integrity": "sha512-WF+9skswUw9N9Qtvi6AfdfPY6dR6+pK+jjbOQr37839pymW767Sz53S1CjVXBO5t2lqJdq+CXcgB1MxmE+8+6w==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/ripple": "2.2.15",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-aria-button": "2.2.14",
+ "@react-aria/button": "3.13.1",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/card/node_modules/@react-aria/button": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.13.1.tgz",
+ "integrity": "sha512-E49qcbBRgofXYfWbli50bepWVNtQBq7qewL9XsX7nHkwPPUe1IRwJOnWZqYMgwwhUBOXfnsR6/TssiXqZsrJdw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/toolbar": "3.0.0-beta.16",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/toggle": "^3.8.4",
+ "@react-types/button": "^3.12.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/card/node_modules/@react-aria/toolbar": {
+ "version": "3.0.0-beta.16",
+ "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.16.tgz",
+ "integrity": "sha512-TnNvtxADalMzs9Et51hWPpGyiHr1dt++UYR7pIo1H7vO+HwXl6uH4HxbFDS5CyV69j2cQlcGrkj13LoWFkBECw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/checkbox": {
+ "version": "2.3.19",
+ "resolved": "https://registry.npmjs.org/@heroui/checkbox/-/checkbox-2.3.19.tgz",
+ "integrity": "sha512-TUc4YRsCS1G4YrnheTLdaGNbQZ5F5+arv5afk4NNyQ2TQgcXohWRmlPrjDaluU8vAJKquGr/Bwvsxwu8WhEFrg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/form": "2.1.19",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-callback-ref": "2.1.7",
+ "@heroui/use-safe-layout-effect": "2.1.7",
+ "@react-aria/checkbox": "3.15.5",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-aria/visually-hidden": "3.8.23",
+ "@react-stately/checkbox": "3.6.14",
+ "@react-stately/toggle": "3.8.4",
+ "@react-types/checkbox": "3.9.4",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.3",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/checkbox/node_modules/@react-aria/checkbox": {
+ "version": "3.15.5",
+ "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.15.5.tgz",
+ "integrity": "sha512-b9c76DBSYTdacSogbsvjkdZomTo5yhBNMmR5ufO544HQ718Ry8q8JmVbtmF/+dkZN7KGnBQCltzGLzXH0Vc0Zg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/form": "^3.0.16",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/label": "^3.7.18",
+ "@react-aria/toggle": "^3.11.3",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/checkbox": "^3.6.14",
+ "@react-stately/form": "^3.1.4",
+ "@react-stately/toggle": "^3.8.4",
+ "@react-types/checkbox": "^3.9.4",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/chip": {
+ "version": "2.2.16",
+ "resolved": "https://registry.npmjs.org/@heroui/chip/-/chip-2.2.16.tgz",
+ "integrity": "sha512-DpwClZ+CHclOG9b9gOG/zK6c6hfdtBaHw5V09TqF4PP4nujw3WZWufPEL3EGKyItyALD20tKHUqG2lYygi8Zbg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-types/checkbox": "3.9.4"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/code": {
+ "version": "2.2.15",
+ "resolved": "https://registry.npmjs.org/@heroui/code/-/code-2.2.15.tgz",
+ "integrity": "sha512-PRO82ExPFAHmAshGtK3P26REojIMoR0u8z0LRPcC+PIpO3cYgxhr4PxA4lBusk4NGvoZyYMGd/SE/GmN3+dRNg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/system-rsc": "2.3.14"
+ },
+ "peerDependencies": {
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/date-input": {
+ "version": "2.3.19",
+ "resolved": "https://registry.npmjs.org/@heroui/date-input/-/date-input-2.3.19.tgz",
+ "integrity": "sha512-UBh57ZsRMCtwtfeICALnP1rCynZ6L8bGMsn6eiGUjR0orQe+yxek+XoOXnWHUtLGw40a1vsyaFumhuHNLrDwaw==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/form": "2.1.19",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@internationalized/date": "3.8.1",
+ "@react-aria/datepicker": "3.14.3",
+ "@react-aria/i18n": "3.12.9",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/datepicker": "3.14.1",
+ "@react-types/datepicker": "3.12.1",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.10",
+ "@heroui/theme": ">=2.4.9",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/date-input/node_modules/@react-aria/datepicker": {
+ "version": "3.14.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.14.3.tgz",
+ "integrity": "sha512-gDc+bM0EaY3BuIW8IJu/ARJV78bRpOaHp+B08EW4N2qJvc7Bs+EmGLnxMrB6Ny+YxNxsYdQRA/FqiytVYOEk8w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/date": "^3.8.1",
+ "@internationalized/number": "^3.6.2",
+ "@internationalized/string": "^3.2.6",
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/form": "^3.0.16",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/label": "^3.7.18",
+ "@react-aria/spinbutton": "^3.6.15",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/datepicker": "^3.14.1",
+ "@react-stately/form": "^3.1.4",
+ "@react-types/button": "^3.12.1",
+ "@react-types/calendar": "^3.7.1",
+ "@react-types/datepicker": "^3.12.1",
+ "@react-types/dialog": "^3.5.18",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/date-picker": {
+ "version": "2.3.20",
+ "resolved": "https://registry.npmjs.org/@heroui/date-picker/-/date-picker-2.3.20.tgz",
+ "integrity": "sha512-YHmE2TrzKyFj4r3s40CIpLkQYgJ3duLhTkYQV6DY26v2+NtavmOKSE3EUqIGgEYKPG1PdbUBYwlqCJlstfTeVg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/aria-utils": "2.2.17",
+ "@heroui/button": "2.2.20",
+ "@heroui/calendar": "2.2.20",
+ "@heroui/date-input": "2.3.19",
+ "@heroui/form": "2.1.19",
+ "@heroui/popover": "2.3.20",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@internationalized/date": "3.8.1",
+ "@react-aria/datepicker": "3.14.3",
+ "@react-aria/i18n": "3.12.9",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/datepicker": "3.14.1",
+ "@react-stately/overlays": "3.6.16",
+ "@react-stately/utils": "3.10.6",
+ "@react-types/datepicker": "3.12.1",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.10",
+ "@heroui/theme": ">=2.4.9",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/date-picker/node_modules/@react-aria/datepicker": {
+ "version": "3.14.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.14.3.tgz",
+ "integrity": "sha512-gDc+bM0EaY3BuIW8IJu/ARJV78bRpOaHp+B08EW4N2qJvc7Bs+EmGLnxMrB6Ny+YxNxsYdQRA/FqiytVYOEk8w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/date": "^3.8.1",
+ "@internationalized/number": "^3.6.2",
+ "@internationalized/string": "^3.2.6",
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/form": "^3.0.16",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/label": "^3.7.18",
+ "@react-aria/spinbutton": "^3.6.15",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/datepicker": "^3.14.1",
+ "@react-stately/form": "^3.1.4",
+ "@react-types/button": "^3.12.1",
+ "@react-types/calendar": "^3.7.1",
+ "@react-types/datepicker": "^3.12.1",
+ "@react-types/dialog": "^3.5.18",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/divider": {
+ "version": "2.2.14",
+ "resolved": "https://registry.npmjs.org/@heroui/divider/-/divider-2.2.14.tgz",
+ "integrity": "sha512-PWKbRZSjrxx0TLPj5T7FLVqG5Wlj7pDu1VxHNK3vRWKGpu31IqczraKnRMnG0ljzhpZkhW3aEKkYtDWaZF3LIw==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-rsc-utils": "2.1.7",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/system-rsc": "2.3.14",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/dom-animation": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/@heroui/dom-animation/-/dom-animation-2.1.9.tgz",
+ "integrity": "sha512-uqYosEn7nDFWQnpZgLkI4AaaGyOpsHv1lQs8ONsaPdPd6FVJ8vfWw3V5/ofQ+nK4Kb66fU7ujlkx1uGoPxLC1Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1"
+ }
+ },
+ "node_modules/@heroui/drawer": {
+ "version": "2.2.17",
+ "resolved": "https://registry.npmjs.org/@heroui/drawer/-/drawer-2.2.17.tgz",
+ "integrity": "sha512-6zTKyDNHw0XcuFoBQBQQao1m3G2IAWTJkLHA891c03a9jARgjATtbYOoqK/MUx0U4Ovb8DR7kH/t71ESnPgrSA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/framer-utils": "2.1.16",
+ "@heroui/modal": "2.2.17",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/dropdown": {
+ "version": "2.3.20",
+ "resolved": "https://registry.npmjs.org/@heroui/dropdown/-/dropdown-2.3.20.tgz",
+ "integrity": "sha512-dbLtE8Ulc0rf18o76AsnNm4w1wmACbT3KKK4cReYlJn/nVWf4vh2z3WdH9BY4X1ogrqkk0KPJXGtFzscf03yXg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/aria-utils": "2.2.17",
+ "@heroui/menu": "2.2.19",
+ "@heroui/popover": "2.3.20",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/menu": "3.18.3",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/menu": "3.9.4",
+ "@react-types/menu": "3.10.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/form": {
+ "version": "2.1.19",
+ "resolved": "https://registry.npmjs.org/@heroui/form/-/form-2.1.19.tgz",
+ "integrity": "sha512-Q3w9hQcrqfU8Y2eSJdei4Jg54sgiGtglWD7/LuH5k33gjY9Vjiscxdn3Ll6k+I0VI9JKu7rzRmabE8W3SaRLPg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/system": "2.4.16",
+ "@heroui/theme": "2.4.16",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/form": "3.1.4",
+ "@react-types/form": "3.7.12",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/@heroui/framer-utils": {
+ "version": "2.1.16",
+ "resolved": "https://registry.npmjs.org/@heroui/framer-utils/-/framer-utils-2.1.16.tgz",
+ "integrity": "sha512-xE6YA2LZ2NEGzqGqOmzunLFwWOjpSo8lIr4Sdg332CRC1bbr7OZ9wkmgo7kqPWtJz4CdxOePIzr2TAghTGlHlA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/system": "2.4.16",
+ "@heroui/use-measure": "2.1.7"
+ },
+ "peerDependencies": {
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/image": {
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/@heroui/image/-/image-2.2.12.tgz",
+ "integrity": "sha512-WJmdp86ibq0XJzi64a/n/c5xEDHNvBD5VU7hinyasRLQBa159Hw4Mab7sueFVBX6ELWj/MIyRb9GK8wz9n3Pwg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-image": "2.1.9"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/input": {
+ "version": "2.4.20",
+ "resolved": "https://registry.npmjs.org/@heroui/input/-/input-2.4.20.tgz",
+ "integrity": "sha512-uJRI+rrP0T80RAbXELCHPsQUi2nPczLMSGEpkZVzbcLr59KMNvkwHFTTXJHnB1q36YjaK8RtvJJXsjUXTe6SZQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/form": "2.1.19",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-safe-layout-effect": "2.1.7",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/textfield": "3.17.3",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/utils": "3.10.6",
+ "@react-types/shared": "3.29.1",
+ "@react-types/textfield": "3.12.2",
+ "react-textarea-autosize": "^8.5.3"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.10",
+ "@heroui/theme": ">=2.4.12",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/input-otp": {
+ "version": "2.1.19",
+ "resolved": "https://registry.npmjs.org/@heroui/input-otp/-/input-otp-2.1.19.tgz",
+ "integrity": "sha512-XyvwzoAaHnY36vMVrLkVbrHPQLjNRe8o8eT5od3F+DXlosHBseYyzzQTz9Z4qyZySKUqqCW4KRbRnt84SwRE7A==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/form": "2.1.19",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/form": "3.0.16",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/form": "3.1.4",
+ "@react-stately/utils": "3.10.6",
+ "@react-types/textfield": "3.12.2",
+ "input-otp": "1.4.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.13",
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/@heroui/kbd": {
+ "version": "2.2.16",
+ "resolved": "https://registry.npmjs.org/@heroui/kbd/-/kbd-2.2.16.tgz",
+ "integrity": "sha512-I/q+ZB/8P+rqGV2AM/f6wicUEq+aMdMZVB1BOPmuwNTBBv2qF/UddoxSdCPYWtZi512BU6TZQfxjexVDpREeiA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/system-rsc": "2.3.14",
+ "@react-aria/utils": "3.29.0"
+ },
+ "peerDependencies": {
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/link": {
+ "version": "2.2.17",
+ "resolved": "https://registry.npmjs.org/@heroui/link/-/link-2.2.17.tgz",
+ "integrity": "sha512-v7if0/+76qLQs5Oj05U2a7BJVFHfQVG+SrxzGtQsqlLMVSN8lUhCl2YoJgESpXXExUfnUGz1t7mjua5op8SMAA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-aria-link": "2.2.15",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/link": "3.8.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-types/link": "3.6.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/listbox": {
+ "version": "2.3.19",
+ "resolved": "https://registry.npmjs.org/@heroui/listbox/-/listbox-2.3.19.tgz",
+ "integrity": "sha512-euKI1562mVYwbrHwVE+02uhpPEJzdmw9cncT646ZM9oK0k7i1yoinqIKeAUWHTMN7EXVQkrmUZPPthgbFKBiHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/aria-utils": "2.2.17",
+ "@heroui/divider": "2.2.14",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-is-mobile": "2.2.9",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/listbox": "3.14.4",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/list": "3.12.2",
+ "@react-types/menu": "3.10.1",
+ "@react-types/shared": "3.29.1",
+ "@tanstack/react-virtual": "3.11.3"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/menu": {
+ "version": "2.2.19",
+ "resolved": "https://registry.npmjs.org/@heroui/menu/-/menu-2.2.19.tgz",
+ "integrity": "sha512-n/OUf7/SLovqsc+kPpkJ7uenYXAXgIy+fe9KRgZ3ALIx9261HQ2pFfGLNzNQT/DFRlkdiXsua29hblsq1RVoHg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/aria-utils": "2.2.17",
+ "@heroui/divider": "2.2.14",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-is-mobile": "2.2.9",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/menu": "3.18.3",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/menu": "3.9.4",
+ "@react-stately/tree": "3.8.10",
+ "@react-types/menu": "3.10.1",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/modal": {
+ "version": "2.2.17",
+ "resolved": "https://registry.npmjs.org/@heroui/modal/-/modal-2.2.17.tgz",
+ "integrity": "sha512-IWlYvtxvCGbGKrd6pjV/RDOIACibd7o/mJVDBImmvVe1+nA88exLDI+NdZAlQqjcBooDd7KyU1S9MTXio6aRRw==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/dom-animation": "2.1.9",
+ "@heroui/framer-utils": "2.1.16",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-aria-button": "2.2.14",
+ "@heroui/use-aria-modal-overlay": "2.2.13",
+ "@heroui/use-disclosure": "2.2.12",
+ "@heroui/use-draggable": "2.1.12",
+ "@react-aria/dialog": "3.5.25",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/overlays": "3.27.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/overlays": "3.6.16",
+ "@react-types/overlays": "3.8.15"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/modal/node_modules/@react-aria/dialog": {
+ "version": "3.5.25",
+ "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.25.tgz",
+ "integrity": "sha512-hVP/TvjUnPgckg4qibc/TDH54O+BzW95hxApxBw1INyViRm95PxdCQDqBdQ/ZW7Gv6J2aUBCGihX7kINPf70ow==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/overlays": "^3.27.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/dialog": "^3.5.18",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/navbar": {
+ "version": "2.2.18",
+ "resolved": "https://registry.npmjs.org/@heroui/navbar/-/navbar-2.2.18.tgz",
+ "integrity": "sha512-g3m0u0WHrb2AnIBI6kjmUIpgENjp5Jt8vCQ62kWbDv2Hm5fSTdTCcY56h3vc/P4yBBng++pFlUtIp2AECU76wA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/dom-animation": "2.1.9",
+ "@heroui/framer-utils": "2.1.16",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-scroll-position": "2.1.7",
+ "@react-aria/button": "3.13.1",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/overlays": "3.27.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/toggle": "3.8.4",
+ "@react-stately/utils": "3.10.6"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/navbar/node_modules/@react-aria/button": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.13.1.tgz",
+ "integrity": "sha512-E49qcbBRgofXYfWbli50bepWVNtQBq7qewL9XsX7nHkwPPUe1IRwJOnWZqYMgwwhUBOXfnsR6/TssiXqZsrJdw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/toolbar": "3.0.0-beta.16",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/toggle": "^3.8.4",
+ "@react-types/button": "^3.12.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/navbar/node_modules/@react-aria/toolbar": {
+ "version": "3.0.0-beta.16",
+ "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.16.tgz",
+ "integrity": "sha512-TnNvtxADalMzs9Et51hWPpGyiHr1dt++UYR7pIo1H7vO+HwXl6uH4HxbFDS5CyV69j2cQlcGrkj13LoWFkBECw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/number-input": {
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/@heroui/number-input/-/number-input-2.0.10.tgz",
+ "integrity": "sha512-gDIyK5lSy/VGIr2ZBni28nIKeVHZJcI9xR+li6dySzvlL1htrzvEzTRY6rcgya/ojycdYggqa89jsYJ5fsPCRA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/button": "2.2.20",
+ "@heroui/form": "2.1.19",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-safe-layout-effect": "2.1.7",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/i18n": "3.12.9",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/numberfield": "3.11.14",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/numberfield": "3.9.12",
+ "@react-stately/utils": "3.10.6",
+ "@react-types/button": "3.12.1",
+ "@react-types/numberfield": "3.8.11",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.10",
+ "@heroui/theme": ">=2.4.9",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/pagination": {
+ "version": "2.2.18",
+ "resolved": "https://registry.npmjs.org/@heroui/pagination/-/pagination-2.2.18.tgz",
+ "integrity": "sha512-Bw5UcMqaQS1YDHWhnCHT/JzeA2kH8mzCr0rMnV82dYJgw9ZOBCXiINueJ9IJOpANbDXdNrMsR33oPTLWaDTLPA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-intersection-observer": "2.2.12",
+ "@heroui/use-pagination": "2.2.13",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/i18n": "3.12.9",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/utils": "3.29.0",
+ "scroll-into-view-if-needed": "3.0.10"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/popover": {
+ "version": "2.3.20",
+ "resolved": "https://registry.npmjs.org/@heroui/popover/-/popover-2.3.20.tgz",
+ "integrity": "sha512-XfiKucInmsXfW277bZ9ypoYUPKMBn+SQU7oUre54KwEUH0J93B58dSjxYKnS/NLKac9CPk244XwAyBlFJROKZA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/aria-utils": "2.2.17",
+ "@heroui/button": "2.2.20",
+ "@heroui/dom-animation": "2.1.9",
+ "@heroui/framer-utils": "2.1.16",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-aria-button": "2.2.14",
+ "@heroui/use-safe-layout-effect": "2.1.7",
+ "@react-aria/dialog": "3.5.25",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/overlays": "3.27.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/overlays": "3.6.16",
+ "@react-types/button": "3.12.1",
+ "@react-types/overlays": "3.8.15"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/popover/node_modules/@react-aria/dialog": {
+ "version": "3.5.25",
+ "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.25.tgz",
+ "integrity": "sha512-hVP/TvjUnPgckg4qibc/TDH54O+BzW95hxApxBw1INyViRm95PxdCQDqBdQ/ZW7Gv6J2aUBCGihX7kINPf70ow==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/overlays": "^3.27.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/dialog": "^3.5.18",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/progress": {
+ "version": "2.2.16",
+ "resolved": "https://registry.npmjs.org/@heroui/progress/-/progress-2.2.16.tgz",
+ "integrity": "sha512-LFcu2OvFedG82rR5gY69wUJQ5/zByFNQT/puxLukJTvnELbjdghpif8XomKWmgBBPYHBjZSWrpq+Rj+s9OkpIQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-is-mounted": "2.1.7",
+ "@react-aria/i18n": "3.12.9",
+ "@react-aria/progress": "3.4.23",
+ "@react-aria/utils": "3.29.0",
+ "@react-types/progress": "3.5.12"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/progress/node_modules/@react-aria/progress": {
+ "version": "3.4.23",
+ "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.23.tgz",
+ "integrity": "sha512-uSQBVY64k+CCey82U67KyWnjAfuuHF0fG6y76kIB8GHI8tGfd1NkXo4ioaxiY0SS+BYGqwqJYYMUzQMpOBTN1A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/label": "^3.7.18",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/progress": "^3.5.12",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/radio": {
+ "version": "2.3.19",
+ "resolved": "https://registry.npmjs.org/@heroui/radio/-/radio-2.3.19.tgz",
+ "integrity": "sha512-MBEZkR+aHPiwNuPFdynRiGe4MzGwtVexueE+XgCkQ6hGAj0R8Y27WcqcLOuFaeR94l8nswjkkTx0CwHwSEZXJw==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/form": "2.1.19",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/radio": "3.11.3",
+ "@react-aria/utils": "3.29.0",
+ "@react-aria/visually-hidden": "3.8.23",
+ "@react-stately/radio": "3.10.13",
+ "@react-types/radio": "3.8.9",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.3",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/radio/node_modules/@react-aria/radio": {
+ "version": "3.11.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.11.3.tgz",
+ "integrity": "sha512-o10G8RUuHnAGZYzkc5PQw7mj4LMZqmGkoihDeHF2NDa9h44Ce5oeCPwRvCKYbumZDOyDY15ZIZhTUzjHt2w6fA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/form": "^3.0.16",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/label": "^3.7.18",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/radio": "^3.10.13",
+ "@react-types/radio": "^3.8.9",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/react": {
+ "version": "2.7.9",
+ "resolved": "https://registry.npmjs.org/@heroui/react/-/react-2.7.9.tgz",
+ "integrity": "sha512-9CU4EKxj5DiGbqaoxDqpxcnMQs1eDxgFYNma1jch048xEFAod5B7MnlFGBSSkH1ngzgX3N4ONSyC85b6CdVsww==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/accordion": "2.2.17",
+ "@heroui/alert": "2.2.20",
+ "@heroui/autocomplete": "2.3.21",
+ "@heroui/avatar": "2.2.16",
+ "@heroui/badge": "2.2.12",
+ "@heroui/breadcrumbs": "2.2.16",
+ "@heroui/button": "2.2.20",
+ "@heroui/calendar": "2.2.20",
+ "@heroui/card": "2.2.19",
+ "@heroui/checkbox": "2.3.19",
+ "@heroui/chip": "2.2.16",
+ "@heroui/code": "2.2.15",
+ "@heroui/date-input": "2.3.19",
+ "@heroui/date-picker": "2.3.20",
+ "@heroui/divider": "2.2.14",
+ "@heroui/drawer": "2.2.17",
+ "@heroui/dropdown": "2.3.20",
+ "@heroui/form": "2.1.19",
+ "@heroui/framer-utils": "2.1.16",
+ "@heroui/image": "2.2.12",
+ "@heroui/input": "2.4.20",
+ "@heroui/input-otp": "2.1.19",
+ "@heroui/kbd": "2.2.16",
+ "@heroui/link": "2.2.17",
+ "@heroui/listbox": "2.3.19",
+ "@heroui/menu": "2.2.19",
+ "@heroui/modal": "2.2.17",
+ "@heroui/navbar": "2.2.18",
+ "@heroui/number-input": "2.0.10",
+ "@heroui/pagination": "2.2.18",
+ "@heroui/popover": "2.3.20",
+ "@heroui/progress": "2.2.16",
+ "@heroui/radio": "2.3.19",
+ "@heroui/ripple": "2.2.15",
+ "@heroui/scroll-shadow": "2.3.13",
+ "@heroui/select": "2.4.20",
+ "@heroui/skeleton": "2.2.12",
+ "@heroui/slider": "2.4.17",
+ "@heroui/snippet": "2.2.21",
+ "@heroui/spacer": "2.2.15",
+ "@heroui/spinner": "2.2.17",
+ "@heroui/switch": "2.2.18",
+ "@heroui/system": "2.4.16",
+ "@heroui/table": "2.2.19",
+ "@heroui/tabs": "2.2.17",
+ "@heroui/theme": "2.4.16",
+ "@heroui/toast": "2.0.10",
+ "@heroui/tooltip": "2.2.17",
+ "@heroui/user": "2.2.16",
+ "@react-aria/visually-hidden": "3.8.23"
+ },
+ "peerDependencies": {
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/react-rsc-utils": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@heroui/react-rsc-utils/-/react-rsc-utils-2.1.7.tgz",
+ "integrity": "sha512-NYKKOLs+KHA8v0+PxkkhVXxTD0WNvC4QMlMjUVshzpWhjnOHIrtXjAtqO6XezWmiKNKY76FAjnMZP+Be5+j5uw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/react-utils": {
+ "version": "2.1.10",
+ "resolved": "https://registry.npmjs.org/@heroui/react-utils/-/react-utils-2.1.10.tgz",
+ "integrity": "sha512-Wj3BSQnNFrDzDnN44vYEwTScMpdbylbZwO8UxIY02AoQCBD5QW7Wf0r2FVlrsrjPjMOVeogwlVvCBYvZz5hHnQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-rsc-utils": "2.1.7",
+ "@heroui/shared-utils": "2.1.9"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/ripple": {
+ "version": "2.2.15",
+ "resolved": "https://registry.npmjs.org/@heroui/ripple/-/ripple-2.2.15.tgz",
+ "integrity": "sha512-akIT/wvatGeyZKyLiYVMjUjzM04v2hQ6zTUjijU3G3MfUq8I56LHNvqdbTgbibMnd7d8+tsPE+x7B6iQWxAQTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/dom-animation": "2.1.9",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/scroll-shadow": {
+ "version": "2.3.13",
+ "resolved": "https://registry.npmjs.org/@heroui/scroll-shadow/-/scroll-shadow-2.3.13.tgz",
+ "integrity": "sha512-RfYfVewf6UR4vr4sIPI2NaNoyK5lLgJwdWNGufE1Km7INelXf3BVdVKLW/Qlq/cES+B4TV3gq5Nto8aen3R1Sg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-data-scroll-overflow": "2.2.10"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/select": {
+ "version": "2.4.20",
+ "resolved": "https://registry.npmjs.org/@heroui/select/-/select-2.4.20.tgz",
+ "integrity": "sha512-sbCwHNBW+zaM0416zL9xBPrNFaGscrNT4ItKZB1A/xELDr5eSvVlQA/uJsivvEzH864ic+rAFEQSVwHU9kz+hg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/aria-utils": "2.2.17",
+ "@heroui/form": "2.1.19",
+ "@heroui/listbox": "2.3.19",
+ "@heroui/popover": "2.3.20",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/scroll-shadow": "2.3.13",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/spinner": "2.2.17",
+ "@heroui/use-aria-button": "2.2.14",
+ "@heroui/use-aria-multiselect": "2.4.13",
+ "@heroui/use-safe-layout-effect": "2.1.7",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/form": "3.0.16",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/overlays": "3.27.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-aria/visually-hidden": "3.8.23",
+ "@react-types/shared": "3.29.1",
+ "@tanstack/react-virtual": "3.11.3"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.10",
+ "@heroui/theme": ">=2.4.12",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/shared-icons": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/@heroui/shared-icons/-/shared-icons-2.1.8.tgz",
+ "integrity": "sha512-97/i6yTl2fSh5jKp8mIig8de8AsP+I/7/AkatLQ1FyxxkabERSWisTXrgdQrfUBimXSNujXMj1tN1vt8kt1zsQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/shared-utils": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/@heroui/shared-utils/-/shared-utils-2.1.9.tgz",
+ "integrity": "sha512-mM/Ep914cYMbw3T/b6+6loYhuNfzDaph76mzw/oIS05gw1Dhp9luCziSiIhqDGgzYck2d74oWTZlahyCsxf47w==",
+ "hasInstallScript": true,
+ "license": "MIT"
+ },
+ "node_modules/@heroui/skeleton": {
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/@heroui/skeleton/-/skeleton-2.2.12.tgz",
+ "integrity": "sha512-HlRKMVLgMAfe9wX7BPhTN84Xu+SdJWCtmxLzBWUZVNpLZdjnu2lLOcbkzwo+84tSjsxbLP4tqBW8hdJnxTQVVA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/slider": {
+ "version": "2.4.17",
+ "resolved": "https://registry.npmjs.org/@heroui/slider/-/slider-2.4.17.tgz",
+ "integrity": "sha512-PUv1Yz4xX5WTZkDJKCxjU8bfHmrIj1qgGqy+4e0xiu7sGYZiywtNx1ahlmjlDsq/I59egaGm97iIYJ9CKBKX2Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/tooltip": "2.2.17",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/i18n": "3.12.9",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/slider": "3.7.19",
+ "@react-aria/utils": "3.29.0",
+ "@react-aria/visually-hidden": "3.8.23",
+ "@react-stately/slider": "3.6.4"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/slider/node_modules/@react-aria/slider": {
+ "version": "3.7.19",
+ "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.19.tgz",
+ "integrity": "sha512-GONrMMz9zsx0ySbUTebWdqRjAuu6EEW+lLf3qUzcqkIYR8QZVTS8RLPt7FmGHKCTDIaBs8D2yv9puIfKAo1QAA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/label": "^3.7.18",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/slider": "^3.6.4",
+ "@react-types/shared": "^3.29.1",
+ "@react-types/slider": "^3.7.11",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/snippet": {
+ "version": "2.2.21",
+ "resolved": "https://registry.npmjs.org/@heroui/snippet/-/snippet-2.2.21.tgz",
+ "integrity": "sha512-9jvBWBL7hyoHw9iF1Zfbk90btTqg7+i0NOtdyl96iezCc9qVHyL1z1Jnh8MMIchOiHzArb5MS+1lDR+OsXU1qQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/button": "2.2.20",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/tooltip": "2.2.17",
+ "@heroui/use-clipboard": "2.1.8",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/utils": "3.29.0"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/spacer": {
+ "version": "2.2.15",
+ "resolved": "https://registry.npmjs.org/@heroui/spacer/-/spacer-2.2.15.tgz",
+ "integrity": "sha512-UaW+9V4wiR3YXb+UfvBWu1PRPq07YblTyHeoiOP7cB1rNwrMHy0CF8U0uQOj+78e78KdrbK4QLSMdxC3v/Lorw==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/system-rsc": "2.3.14"
+ },
+ "peerDependencies": {
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/spinner": {
+ "version": "2.2.17",
+ "resolved": "https://registry.npmjs.org/@heroui/spinner/-/spinner-2.2.17.tgz",
+ "integrity": "sha512-N7VnYAZU3vPm42Ab78QFS153qBf93Kwhnm9+F02bjCLA5709uvGbAEvwFRwh/u5pNOrDpv1SauschrRzpGsmgg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/system": "2.4.16",
+ "@heroui/system-rsc": "2.3.14"
+ },
+ "peerDependencies": {
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/switch": {
+ "version": "2.2.18",
+ "resolved": "https://registry.npmjs.org/@heroui/switch/-/switch-2.2.18.tgz",
+ "integrity": "sha512-JQYajZ/vHFTdsln8UqwPY+Rtr/T6XbN1TKPXCsrdwa5OswQK0mv2BuNjW/8FGl0XQvS44K3ObcKW2JO3fzpS0A==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-safe-layout-effect": "2.1.7",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/switch": "3.7.3",
+ "@react-aria/utils": "3.29.0",
+ "@react-aria/visually-hidden": "3.8.23",
+ "@react-stately/toggle": "3.8.4",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.3",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/switch/node_modules/@react-aria/switch": {
+ "version": "3.7.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.7.3.tgz",
+ "integrity": "sha512-tFdJmcHaLgW23cS2R713vcJdVbsjDTRk8OLdG/sMziPBY3C00/exuSIb57xTS7KrE0hBYfnLJQTcmDNqdM8+9Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/toggle": "^3.11.3",
+ "@react-stately/toggle": "^3.8.4",
+ "@react-types/shared": "^3.29.1",
+ "@react-types/switch": "^3.5.11",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/system": {
+ "version": "2.4.16",
+ "resolved": "https://registry.npmjs.org/@heroui/system/-/system-2.4.16.tgz",
+ "integrity": "sha512-kk8XQsejHv4/vZBm7936D9+YkKV/meUp2tY49auS0wLsrGOQ2vvBKiwzQ0r+ibTvSNyCe5SX9tLfEGVgaGIY7g==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/system-rsc": "2.3.14",
+ "@internationalized/date": "3.8.1",
+ "@react-aria/i18n": "3.12.9",
+ "@react-aria/overlays": "3.27.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/utils": "3.10.6",
+ "@react-types/datepicker": "3.12.1"
+ },
+ "peerDependencies": {
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/system-rsc": {
+ "version": "2.3.14",
+ "resolved": "https://registry.npmjs.org/@heroui/system-rsc/-/system-rsc-2.3.14.tgz",
+ "integrity": "sha512-2H1PZXbArdbhbfdcoCWSqqZLVPsbV9lAnIYysTSjt0YT4YzG6cIN/8seDCbi04Bg1n65kPLEVqnTlgMVnGn1Uw==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-types/shared": "3.29.1",
+ "clsx": "^1.2.1"
+ },
+ "peerDependencies": {
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/system-rsc/node_modules/clsx": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
+ "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@heroui/table": {
+ "version": "2.2.19",
+ "resolved": "https://registry.npmjs.org/@heroui/table/-/table-2.2.19.tgz",
+ "integrity": "sha512-h1kpw8uQdAzM9NUDWp6mOZIJSv5SS00G9vE26usO+vXrhEiPFQaeqvspnsvirBOftyadMwfdX77o4hLr5KjDkg==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/checkbox": "2.3.19",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/spacer": "2.2.15",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/table": "3.17.3",
+ "@react-aria/utils": "3.29.0",
+ "@react-aria/visually-hidden": "3.8.23",
+ "@react-stately/table": "3.14.2",
+ "@react-stately/virtualizer": "4.4.0",
+ "@react-types/grid": "3.3.2",
+ "@react-types/table": "3.13.0",
+ "@tanstack/react-virtual": "3.11.3"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/table/node_modules/@react-aria/table": {
+ "version": "3.17.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.17.3.tgz",
+ "integrity": "sha512-hs3akyNMeeAPIfa+YKMxJyupSjywW5OGzJtOw/Z0j6pV8KXSeMEXNYkSuJY+m5Q1mdunoiiogs0kE3B0r2izQA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/grid": "^3.14.0",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/live-announcer": "^3.4.2",
+ "@react-aria/utils": "^3.29.0",
+ "@react-aria/visually-hidden": "^3.8.23",
+ "@react-stately/collections": "^3.12.4",
+ "@react-stately/flags": "^3.1.1",
+ "@react-stately/table": "^3.14.2",
+ "@react-types/checkbox": "^3.9.4",
+ "@react-types/grid": "^3.3.2",
+ "@react-types/shared": "^3.29.1",
+ "@react-types/table": "^3.13.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/table/node_modules/@react-stately/virtualizer": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-4.4.0.tgz",
+ "integrity": "sha512-y2jefrW0ffJpv0685IEKId6/wy0kgD/bxYuny9r9Z3utvcjjFl9fX9cBKsXII7ZxPiu0CP+wA6HQ53GU3BqCsw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/tabs": {
+ "version": "2.2.17",
+ "resolved": "https://registry.npmjs.org/@heroui/tabs/-/tabs-2.2.17.tgz",
+ "integrity": "sha512-7kA5Dre8kmAbCq5ObcVNlUc1NTbnfaH4FhrwUd9lNg6pnE+EdEROt+Jegk0+0oWrx6ERjr+1vOUc1zgRPs657A==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/aria-utils": "2.2.17",
+ "@heroui/framer-utils": "2.1.16",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-is-mounted": "2.1.7",
+ "@heroui/use-update-effect": "2.1.7",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/tabs": "3.10.3",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/tabs": "3.8.2",
+ "@react-types/shared": "3.29.1",
+ "@react-types/tabs": "3.3.15",
+ "scroll-into-view-if-needed": "3.0.10"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/tabs/node_modules/@react-aria/tabs": {
+ "version": "3.10.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.10.3.tgz",
+ "integrity": "sha512-TYfwaRrI0mQMefmoHeTKXdczpb53qpPr+3nnveGl+BocG94wmjIqK6kncboVbPdykgQCIAMd2d9GFpK01+zXrA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/selection": "^3.24.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/tabs": "^3.8.2",
+ "@react-types/shared": "^3.29.1",
+ "@react-types/tabs": "^3.3.15",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/theme": {
+ "version": "2.4.16",
+ "resolved": "https://registry.npmjs.org/@heroui/theme/-/theme-2.4.16.tgz",
+ "integrity": "sha512-XWRr1MJNBGIESxOCgPgQMq3gt8VfWoYzDnBpIdIHjSlin+4oK8LRqLsP6CeVTpGSwv6lurQk11jVKY6MTI7JTw==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/shared-utils": "2.1.9",
+ "clsx": "^1.2.1",
+ "color": "^4.2.3",
+ "color2k": "^2.0.3",
+ "deepmerge": "4.3.1",
+ "flat": "^5.0.2",
+ "tailwind-merge": "2.5.4",
+ "tailwind-variants": "0.3.0"
+ },
+ "peerDependencies": {
+ "tailwindcss": ">=3.4.0"
+ }
+ },
+ "node_modules/@heroui/theme/node_modules/clsx": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
+ "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@heroui/theme/node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@heroui/toast": {
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/@heroui/toast/-/toast-2.0.10.tgz",
+ "integrity": "sha512-NefTDL6Thtw169uBEXseVgVBOCx66BQKLU3BahhQ/a41LpXshfQksRxXxldB0kqEJ21g295Df11z2bLi2wIwyQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-icons": "2.1.8",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/spinner": "2.2.17",
+ "@heroui/use-is-mobile": "2.2.9",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/toast": "3.0.3",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/toast": "3.1.0",
+ "@react-stately/utils": "3.10.6"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.10",
+ "@heroui/theme": ">=2.4.12",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/tooltip": {
+ "version": "2.2.17",
+ "resolved": "https://registry.npmjs.org/@heroui/tooltip/-/tooltip-2.2.17.tgz",
+ "integrity": "sha512-HcCwjKxQL6O64dbfZ/bmUpOFn0OCT7duET5Y5YWpq/zdnLVDp35EiFK/FQemBiZHSh74qomxCX58mdMIhTYN9A==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/aria-utils": "2.2.17",
+ "@heroui/dom-animation": "2.1.9",
+ "@heroui/framer-utils": "2.1.16",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@heroui/use-safe-layout-effect": "2.1.7",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/overlays": "3.27.1",
+ "@react-aria/tooltip": "3.8.3",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/tooltip": "3.5.4",
+ "@react-types/overlays": "3.8.15",
+ "@react-types/tooltip": "3.4.17"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/tooltip/node_modules/@react-aria/tooltip": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.8.3.tgz",
+ "integrity": "sha512-8JHRqffH5vUw7og6mlCRzb4h95/R5RpOxGFfEGw7aami14XMo6tZg7wMgwDUAEiVqNerRWYaw+tk7nCUQXo1Sg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/tooltip": "^3.5.4",
+ "@react-types/shared": "^3.29.1",
+ "@react-types/tooltip": "^3.4.17",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/use-aria-accordion": {
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/@heroui/use-aria-accordion/-/use-aria-accordion-2.2.12.tgz",
+ "integrity": "sha512-7xnsf48Zdke4UfZGd4jTYPGbtmlc94jTkMdmWxaulfQN0O1bwLicwqxWxB3R7WzrDcL93TBvOYPRrjFIUHRXfg==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-aria/button": "3.13.1",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/selection": "3.24.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/tree": "3.8.10",
+ "@react-types/accordion": "3.0.0-alpha.26",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-aria-accordion/node_modules/@react-aria/button": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.13.1.tgz",
+ "integrity": "sha512-E49qcbBRgofXYfWbli50bepWVNtQBq7qewL9XsX7nHkwPPUe1IRwJOnWZqYMgwwhUBOXfnsR6/TssiXqZsrJdw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/toolbar": "3.0.0-beta.16",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/toggle": "^3.8.4",
+ "@react-types/button": "^3.12.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/use-aria-accordion/node_modules/@react-aria/toolbar": {
+ "version": "3.0.0-beta.16",
+ "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.16.tgz",
+ "integrity": "sha512-TnNvtxADalMzs9Et51hWPpGyiHr1dt++UYR7pIo1H7vO+HwXl6uH4HxbFDS5CyV69j2cQlcGrkj13LoWFkBECw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@heroui/use-aria-button": {
+ "version": "2.2.14",
+ "resolved": "https://registry.npmjs.org/@heroui/use-aria-button/-/use-aria-button-2.2.14.tgz",
+ "integrity": "sha512-MAwv37AicSe22ygN+3VQKm6aDUt4o5koVIgo5sNiPzlVaa4KuWlbHJ2qE4WoTQ87shWzwfZOJpzCmOKK61Ls2Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/shared-utils": "2.1.9",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-types/button": "3.12.1",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-aria-link": {
+ "version": "2.2.15",
+ "resolved": "https://registry.npmjs.org/@heroui/use-aria-link/-/use-aria-link-2.2.15.tgz",
+ "integrity": "sha512-pvtv1ovlOoaxtBDgoMoD4GbVZ+YpPDacgmbKZFZW4gzTCl9BS5jsZYTaEZ5odKBirp+Uca9OIc/0g+odrNe+WA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/shared-utils": "2.1.9",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-types/link": "3.6.1",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-aria-modal-overlay": {
+ "version": "2.2.13",
+ "resolved": "https://registry.npmjs.org/@heroui/use-aria-modal-overlay/-/use-aria-modal-overlay-2.2.13.tgz",
+ "integrity": "sha512-8csUzC5kH03pxEbbJgzfgTJpsh/d0dKdhYfzkzzP6d6u+h92PqcEjfQKZZhRPd42lWiS1rF8j68nPPPUiuJIbw==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-aria/overlays": "3.27.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/overlays": "3.6.16",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-aria-multiselect": {
+ "version": "2.4.13",
+ "resolved": "https://registry.npmjs.org/@heroui/use-aria-multiselect/-/use-aria-multiselect-2.4.13.tgz",
+ "integrity": "sha512-HeF8XMBPCUuQd/98/vKw5V5LJJZODmuVLUQpAC3il3k7BC6MJWiZD0DDJtbPYewyiRBwNIKX7akBFBmmtj26Aw==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-aria/i18n": "3.12.9",
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/label": "3.7.18",
+ "@react-aria/listbox": "3.14.4",
+ "@react-aria/menu": "3.18.3",
+ "@react-aria/selection": "3.24.1",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/form": "3.1.4",
+ "@react-stately/list": "3.12.2",
+ "@react-stately/menu": "3.9.4",
+ "@react-types/button": "3.12.1",
+ "@react-types/overlays": "3.8.15",
+ "@react-types/select": "3.9.12",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-callback-ref": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@heroui/use-callback-ref/-/use-callback-ref-2.1.7.tgz",
+ "integrity": "sha512-AKMb+zV8um9y7gnsPgmVPm5WRx0oJc/3XU+banr8qla27+3HhnQZVqk3nlSHIplkseQzMRt3xHj5RPnwKbs71w==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/use-safe-layout-effect": "2.1.7"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-clipboard": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/@heroui/use-clipboard/-/use-clipboard-2.1.8.tgz",
+ "integrity": "sha512-itT5PCoMRoa6rjV51Z9wxeDQpSYMZj2sDFYrM7anGFO/4CAsQ/NfQoPwl5+kX0guqCcCGMqgFnNzNyQuNNsPtg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-data-scroll-overflow": {
+ "version": "2.2.10",
+ "resolved": "https://registry.npmjs.org/@heroui/use-data-scroll-overflow/-/use-data-scroll-overflow-2.2.10.tgz",
+ "integrity": "sha512-Lza9S7ZWhY3PliahSgDRubrpeT7gnySH67GSTrGQMzYggTDMo2I1Pky7ZaHUnHHYB9Y7WHryB26ayWBOgRtZUQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/shared-utils": "2.1.9"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-disclosure": {
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/@heroui/use-disclosure/-/use-disclosure-2.2.12.tgz",
+ "integrity": "sha512-SMwJmpIruY8TnYHuqprKyLqYfvT670gAOjsMqi6qhL8UdWiL0c/DI34LEwiVUmtcUoKbDtWJ0dGv5+mhK4FAkA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/use-callback-ref": "2.1.7",
+ "@react-aria/utils": "3.29.0",
+ "@react-stately/utils": "3.10.6"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-draggable": {
+ "version": "2.1.12",
+ "resolved": "https://registry.npmjs.org/@heroui/use-draggable/-/use-draggable-2.1.12.tgz",
+ "integrity": "sha512-6VxsuivP3FBXxwaFlVSp/84tmNn5Xg8fpgRVji2EzEEsc0nOmUu41dHiFRw8+42ikyjXQBTbO+e5TrFBSQYoEg==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-aria/interactions": "3.25.1"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-image": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/@heroui/use-image/-/use-image-2.1.9.tgz",
+ "integrity": "sha512-rHfPv4PkRN6mUG3eoBZBi8P8FnM37Kb/lOUM5M5kWtPMRpdfpgDxGQjf24K2lwSQM5xVG1H8WlF1Wipcd0kpmA==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/use-safe-layout-effect": "2.1.7"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-intersection-observer": {
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/@heroui/use-intersection-observer/-/use-intersection-observer-2.2.12.tgz",
+ "integrity": "sha512-9A0ZJMyrYRWrIAaqaKDHrP7UiHRRWd1FOdrbM4YBGs4sMNnoFNfzldad68UZzUTR3oRYaBPNWWTcCwfIZNl8+w==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-aria/interactions": "3.25.1",
+ "@react-aria/ssr": "3.9.8",
+ "@react-aria/utils": "3.29.0",
+ "@react-types/shared": "3.29.1"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-is-mobile": {
+ "version": "2.2.9",
+ "resolved": "https://registry.npmjs.org/@heroui/use-is-mobile/-/use-is-mobile-2.2.9.tgz",
+ "integrity": "sha512-UVc9wKK3kg2bIAQPaKuCA53qd1Snrd8yxIf/dtbh3PqYjqoyN7c1hUFZxe9ZW8Vb3AovquWDnPYbx4vjdzcQiQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@react-aria/ssr": "3.9.8"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-is-mounted": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@heroui/use-is-mounted/-/use-is-mounted-2.1.7.tgz",
+ "integrity": "sha512-Msf4eWWUEDofPmvaFfS4azftO9rIuKyiagxsYE73PSMcdB+7+PJSMTY5ZTM3cf/lwUJzy1FQvyTiCKx0RQ5neA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-measure": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@heroui/use-measure/-/use-measure-2.1.7.tgz",
+ "integrity": "sha512-H586tr/bOH08MAufeiT35E1QmF8SPQy5Ghmat1Bb+vh/6KZ5S0K0o95BE2to7sXE9UCJWa7nDFuizXAGbveSiA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-pagination": {
+ "version": "2.2.13",
+ "resolved": "https://registry.npmjs.org/@heroui/use-pagination/-/use-pagination-2.2.13.tgz",
+ "integrity": "sha512-QuoSW1ZLQ7kgi8P3/7UjNZaLATLaLOsVyiMx3WOJKBlKJofjFVTbVk8xnUGFHK5EfrZKd9svazwXQ6f5i3mXRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/shared-utils": "2.1.9",
+ "@react-aria/i18n": "3.12.9"
+ },
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-safe-layout-effect": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@heroui/use-safe-layout-effect/-/use-safe-layout-effect-2.1.7.tgz",
+ "integrity": "sha512-ZiMc+nVjcE5aArC4PEmnLHSJj0WgAXq3udr7FZaosP/jrRdn5VPcfF9z9cIGNJD6MkZp+YP0XGslrIFKZww0Hw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-scroll-position": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@heroui/use-scroll-position/-/use-scroll-position-2.1.7.tgz",
+ "integrity": "sha512-c91Elycrq51nhpWqFIEBy04P+KBJjnEz4u1+1c7txnjs/k0FOD5EBD8+Jf8GJbh4WYp5N936XFvCcE7gB1C9JQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/use-update-effect": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@heroui/use-update-effect/-/use-update-effect-2.1.7.tgz",
+ "integrity": "sha512-G7Crf4vdJh2bwyQQ5+dN+IfvtHpRNkNlEXVDE87Kb15fJ7Rnokt3webnogBreZ9l7SbHpEGvx5sZPsgUHgrTMg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@heroui/user": {
+ "version": "2.2.16",
+ "resolved": "https://registry.npmjs.org/@heroui/user/-/user-2.2.16.tgz",
+ "integrity": "sha512-tHlyt2On5p62/UN57G+MVbWIa15YfaZYcFWVvf7NyjKzzN9BtL/urcqoyz06lMiQ1aZ2ilaKQdaHu0NUaZ/Z6w==",
+ "license": "MIT",
+ "dependencies": {
+ "@heroui/avatar": "2.2.16",
+ "@heroui/react-utils": "2.1.10",
+ "@heroui/shared-utils": "2.1.9",
+ "@react-aria/focus": "3.20.3",
+ "@react-aria/utils": "3.29.0"
+ },
+ "peerDependencies": {
+ "@heroui/system": ">=2.4.7",
+ "@heroui/theme": ">=2.4.6",
+ "react": ">=18 || >=19.0.0-rc.0",
+ "react-dom": ">=18 || >=19.0.0-rc.0"
+ }
+ },
+ "node_modules/@internationalized/date": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.8.1.tgz",
+ "integrity": "sha512-PgVE6B6eIZtzf9Gu5HvJxRK3ufUFz9DhspELuhW/N0GuMGMTLvPQNRkHP2hTuP9lblOk+f+1xi96sPiPXANXAA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
+ "node_modules/@internationalized/message": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.7.tgz",
+ "integrity": "sha512-gLQlhEW4iO7DEFPf/U7IrIdA3UyLGS0opeqouaFwlMObLUzwexRjbygONHDVbC9G9oFLXsLyGKYkJwqXw/QADg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0",
+ "intl-messageformat": "^10.1.0"
+ }
+ },
+ "node_modules/@internationalized/number": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.2.tgz",
+ "integrity": "sha512-E5QTOlMg9wo5OrKdHD6edo1JJlIoOsylh0+mbf0evi1tHJwMZfJSaBpGtnJV9N7w3jeiioox9EG/EWRWPh82vg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
+ "node_modules/@internationalized/string": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.6.tgz",
+ "integrity": "sha512-LR2lnM4urJta5/wYJVV7m8qk5DrMZmLRTuFhbQO5b9/sKLHgty6unQy1Li4+Su2DWydmB4aZdS5uxBRXIq2aAw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+ "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@jsdevtools/ono": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
+ "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@lit-labs/react": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-2.1.3.tgz",
+ "integrity": "sha512-OD9h2JynerBQUMNzb563jiVpxfvPF0HjQkKY2mx0lpVYvD7F+rtJpOGz6ek+6ufMidV3i+MPT9SX62OKWHFrQg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit/react": "^1.0.3"
+ }
+ },
+ "node_modules/@lit-labs/ssr-dom-shim": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz",
+ "integrity": "sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@lit/react": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@lit/react/-/react-1.0.7.tgz",
+ "integrity": "sha512-cencnwwLXQKiKxjfFzSgZRngcWJzUDZi/04E0fSaF86wZgchMdvTyu+lE36DrUfvuus3bH8+xLPrhM1cTjwpzw==",
+ "license": "BSD-3-Clause",
+ "peerDependencies": {
+ "@types/react": "17 || 18 || 19"
+ }
+ },
+ "node_modules/@lit/reactive-element": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.0.tgz",
+ "integrity": "sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit-labs/ssr-dom-shim": "^1.2.0"
+ }
+ },
+ "node_modules/@material-tailwind/react": {
+ "version": "2.1.10",
+ "resolved": "https://registry.npmjs.org/@material-tailwind/react/-/react-2.1.10.tgz",
+ "integrity": "sha512-xGU/mLDKDBp/qZ8Dp2XR7fKcTpDuFeZEBqoL9Bk/29kakKxNxjUGYSRHEFLsyOFf4VIhU6WGHdIS7tOA3QGJHA==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react": "0.19.0",
+ "classnames": "2.3.2",
+ "deepmerge": "4.2.2",
+ "framer-motion": "6.5.1",
+ "material-ripple-effects": "2.0.1",
+ "prop-types": "15.8.1",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "tailwind-merge": "1.8.1"
+ },
+ "peerDependencies": {
+ "react": "^16 || ^17 || ^18",
+ "react-dom": "^16 || ^17 || ^18"
+ }
+ },
+ "node_modules/@material-tailwind/react/node_modules/tailwind-merge": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.8.1.tgz",
+ "integrity": "sha512-+fflfPxvHFr81hTJpQ3MIwtqgvefHZFUHFiIHpVIRXvG/nX9+gu2P7JNlFu2bfDMJ+uHhi/pUgzaYacMoXv+Ww==",
+ "license": "MIT"
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@open-wc/dedupe-mixin": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@open-wc/dedupe-mixin/-/dedupe-mixin-1.4.0.tgz",
+ "integrity": "sha512-Sj7gKl1TLcDbF7B6KUhtvr+1UCxdhMbNY5KxdU5IfMFWqL8oy1ZeAcCANjoB1TL0AJTcPmcCFsCbHf8X2jGDUA==",
+ "license": "MIT"
+ },
+ "node_modules/@phosphor-icons/react": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@phosphor-icons/react/-/react-2.1.7.tgz",
+ "integrity": "sha512-g2e2eVAn1XG2a+LI09QU3IORLhnFNAFkNbo2iwbX6NOKSLOwvEMmTa7CgOzEbgNWR47z8i8kwjdvYZ5fkGx1mQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8",
+ "react-dom": ">= 16.8"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@polymer/polymer": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/@polymer/polymer/-/polymer-3.5.2.tgz",
+ "integrity": "sha512-fWwImY/UH4bb2534DVSaX+Azs2yKg8slkMBHOyGeU2kKx7Xmxp6Lee0jP8p6B3d7c1gFUPB2Z976dTUtX81pQA==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@webcomponents/shadycss": "^1.9.1"
+ }
+ },
+ "node_modules/@preact/signals-core": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.8.0.tgz",
+ "integrity": "sha512-OBvUsRZqNmjzCZXWLxkZfhcgT+Fk8DDcT/8vD6a1xhDemodyy87UJRJfASMuSD8FaAIeGgGm85ydXhm7lr4fyA==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
+ "node_modules/@preact/signals-react": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@preact/signals-react/-/signals-react-3.0.1.tgz",
+ "integrity": "sha512-HkM5Q2IsETO1M0bUzy4JB0EPQCf99SMbWP9K6GYlYVHfOX1HLKJ6Dl9L1/1rQnmrQpUsTw0R+IJQDh6tYWar2g==",
+ "license": "MIT",
+ "dependencies": {
+ "@preact/signals-core": "^1.7.0",
+ "use-sync-external-store": "^1.2.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ },
+ "peerDependencies": {
+ "react": "^16.14.0 || 17.x || 18.x || 19.x"
+ }
+ },
+ "node_modules/@preact/signals-react-transform": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/@preact/signals-react-transform/-/signals-react-transform-0.5.1.tgz",
+ "integrity": "sha512-/w1rgu7i/qDk8dhDj+6AVVVJ+b1W11YkP3vfPPPyrn1tDCPb8orYwETa3JCvYxMtJBHbvIYEjhXvZ8Ab2cWC8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.22.5",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@preact/signals-react": "^3.0.0",
+ "debug": "^4.3.4",
+ "use-sync-external-store": "^1.2.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0",
+ "react": "^16.14.0 || 17.x || 18.x || 19.x"
+ }
+ },
+ "node_modules/@react-aria/autocomplete": {
+ "version": "3.0.0-beta.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/autocomplete/-/autocomplete-3.0.0-beta.1.tgz",
+ "integrity": "sha512-ZeVR1tKJOZK5/RTuN8eprlP1lyeihdDfDYPBkdg2iT5h775LSZyOingPux9aLtdqt/uj6JIS5amK9ErI7+axug==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/combobox": "^3.12.1",
+ "@react-aria/focus": "^3.20.1",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/listbox": "^3.14.2",
+ "@react-aria/searchfield": "^3.8.2",
+ "@react-aria/textfield": "^3.17.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/autocomplete": "3.0.0-beta.0",
+ "@react-stately/combobox": "^3.10.3",
+ "@react-types/autocomplete": "3.0.0-alpha.29",
+ "@react-types/button": "^3.11.0",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/breadcrumbs": {
+ "version": "3.5.22",
+ "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.22.tgz",
+ "integrity": "sha512-Jhx3eJqvuSUFL5/TzJ7EteluySdgKVkYGJ72Jz6AdEkiuoQAFbRZg4ferRIXQlmFL2cj7Z3jo8m8xGitebMtgw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/link": "^3.7.10",
+ "@react-aria/utils": "^3.28.1",
+ "@react-types/breadcrumbs": "^3.7.11",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/button": {
+ "version": "3.12.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.12.1.tgz",
+ "integrity": "sha512-IgCENCVUzjfI4nVgJ8T1z2oD81v3IO2Ku96jVljqZ/PWnFACsRikfLeo8xAob3F0LkRW4CTK4Tjy6BRDsy2l6A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/toolbar": "3.0.0-beta.14",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/toggle": "^3.8.2",
+ "@react-types/button": "^3.11.0",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/calendar": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.7.2.tgz",
+ "integrity": "sha512-q16jWzBCoMoohOF75rJbqh+4xlKOhagPC96jsARZmaqWOEHpFYGK/1rH9steC5+Dqe7y1nipAoLRynm18rrt3w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/date": "^3.7.0",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/live-announcer": "^3.4.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/calendar": "^3.7.1",
+ "@react-types/button": "^3.11.0",
+ "@react-types/calendar": "^3.6.1",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/checkbox": {
+ "version": "3.15.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.15.3.tgz",
+ "integrity": "sha512-/m5JYoGsi5L0NZnacgqEcMqBo6CcTmsJ9nAY/07MDCUJBcL/Xokd8cL/1K21n6K69MiCPcxORbSBdxJDm9dR0A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/form": "^3.0.14",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/label": "^3.7.16",
+ "@react-aria/toggle": "^3.11.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/checkbox": "^3.6.12",
+ "@react-stately/form": "^3.1.2",
+ "@react-stately/toggle": "^3.8.2",
+ "@react-types/checkbox": "^3.9.2",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/collections": {
+ "version": "3.0.0-beta.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/collections/-/collections-3.0.0-beta.1.tgz",
+ "integrity": "sha512-udrHajGknkDioGbuqOdWjQ2P7J6fYGlkVGuIJwLxML+WgrroC+i76A4BBOD4ifJKxVAZ8TMyGSztt4RUdn+jDA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/ssr": "^3.9.7",
+ "@react-aria/utils": "^3.28.1",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0",
+ "use-sync-external-store": "^1.4.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/color": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.0.5.tgz",
+ "integrity": "sha512-F+by1SOvH+qr47jhaZUYLCYMjRFxEBiG2UpNyd0iByIOweeXnU9sRHRAjLSWx/nULB6ZrUhNzE3XhI0SoZyHUw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/numberfield": "^3.11.12",
+ "@react-aria/slider": "^3.7.17",
+ "@react-aria/spinbutton": "^3.6.13",
+ "@react-aria/textfield": "^3.17.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-aria/visually-hidden": "^3.8.21",
+ "@react-stately/color": "^3.8.3",
+ "@react-stately/form": "^3.1.2",
+ "@react-types/color": "^3.0.3",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/color/node_modules/@react-aria/numberfield": {
+ "version": "3.11.12",
+ "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.12.tgz",
+ "integrity": "sha512-VQ4dfaf+k7n2tbP8iB1OLFYTLCh9ReyV7dNLrDvH24V7ByaHakobZjwP8tF6CpvafNYaXPUflxnHpIgXvN3QYA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/spinbutton": "^3.6.13",
+ "@react-aria/textfield": "^3.17.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/form": "^3.1.2",
+ "@react-stately/numberfield": "^3.9.10",
+ "@react-types/button": "^3.11.0",
+ "@react-types/numberfield": "^3.8.9",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/combobox": {
+ "version": "3.12.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.12.1.tgz",
+ "integrity": "sha512-Al43cVQ2XiuPTCZ8jhz5Vmoj5Vqm6GADBtrL+XHZd7lM1gkD3q27GhKYiEt0jrcoBjjdqIiYWEaFLYg5LSQPzA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.1",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/listbox": "^3.14.2",
+ "@react-aria/live-announcer": "^3.4.1",
+ "@react-aria/menu": "^3.18.1",
+ "@react-aria/overlays": "^3.26.1",
+ "@react-aria/selection": "^3.23.1",
+ "@react-aria/textfield": "^3.17.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/collections": "^3.12.2",
+ "@react-stately/combobox": "^3.10.3",
+ "@react-stately/form": "^3.1.2",
+ "@react-types/button": "^3.11.0",
+ "@react-types/combobox": "^3.13.3",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/datepicker": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.14.1.tgz",
+ "integrity": "sha512-77HaB+dFaMu7OpDQqjDiyZdaJlkwMgQHjTRvplBVc3Pau1sfQ1LdFC4+ZAXSbQTVSYt6GaN9S2tL4qoc+bO05w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/date": "^3.7.0",
+ "@internationalized/number": "^3.6.0",
+ "@internationalized/string": "^3.2.5",
+ "@react-aria/focus": "^3.20.1",
+ "@react-aria/form": "^3.0.14",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/label": "^3.7.16",
+ "@react-aria/spinbutton": "^3.6.13",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/datepicker": "^3.13.0",
+ "@react-stately/form": "^3.1.2",
+ "@react-types/button": "^3.11.0",
+ "@react-types/calendar": "^3.6.1",
+ "@react-types/datepicker": "^3.11.0",
+ "@react-types/dialog": "^3.5.16",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/dialog": {
+ "version": "3.5.23",
+ "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.23.tgz",
+ "integrity": "sha512-ud8b4G5vcFEZPEjzdXrjOadwRMBKBDLiok6lIl1rsPkd1qnLMFxsl3787kct1Ex0PVVKOPlcH7feFw+1T7NsLw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/overlays": "^3.26.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-types/dialog": "^3.5.16",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/disclosure": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/disclosure/-/disclosure-3.0.3.tgz",
+ "integrity": "sha512-YMZG6NYugRMTElq4bspstML15KFUwZ+ZVUTSQHLLLLnwxkj+R9NbsDonMkH6lpgC02ru0Kgo2+1NljIGz9a5/Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/ssr": "^3.9.7",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/disclosure": "^3.0.2",
+ "@react-types/button": "^3.11.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/dnd": {
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.9.1.tgz",
+ "integrity": "sha512-Rg43C+MQSr7IN1wv0iAemW59RANE39TsVs1QX9ryRh0Unc14jnm+GhZ928XNuu/rJ6BMUM8Cb9uQuYcVPgeDxA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/string": "^3.2.5",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/live-announcer": "^3.4.1",
+ "@react-aria/overlays": "^3.26.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/dnd": "^3.5.2",
+ "@react-types/button": "^3.11.0",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/focus": {
+ "version": "3.20.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.20.3.tgz",
+ "integrity": "sha512-rR5uZUMSY4xLHmpK/I8bP1V6vUNHFo33gTvrvNUsAKKqvMfa7R2nu5A6v97dr5g6tVH6xzpdkPsOJCWh90H2cw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0",
+ "clsx": "^2.0.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/form": {
+ "version": "3.0.16",
+ "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.16.tgz",
+ "integrity": "sha512-N1bDsJfmnyDesayK0Ii6UPH6JWiF6Wz8WSveQ2y5004XHoIWn5LpWmOqnRedvyw4Yedw33schlvrY7ENEwMdpg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/form": "^3.1.4",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/grid": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.14.0.tgz",
+ "integrity": "sha512-/tJB7xnSruORJ8tlFHja4SfL8/EW5v4cBLiyD5z48m7IdG33jXR8Cv4Pi5uQqs8zKdnpqZ1wDG3GQxNDwZavpg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/live-announcer": "^3.4.2",
+ "@react-aria/selection": "^3.24.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/collections": "^3.12.4",
+ "@react-stately/grid": "^3.11.2",
+ "@react-stately/selection": "^3.20.2",
+ "@react-types/checkbox": "^3.9.4",
+ "@react-types/grid": "^3.3.2",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/gridlist": {
+ "version": "3.11.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.11.1.tgz",
+ "integrity": "sha512-x2lrQO0kC+kdoCH+iUY6VsgoJlZ/x/w10dKc66npXeVC2EHo2InJDINt9VEIaANnh9i7TiTthdQVeePCP22tMQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.1",
+ "@react-aria/grid": "^3.12.1",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/selection": "^3.23.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/collections": "^3.12.2",
+ "@react-stately/list": "^3.12.0",
+ "@react-stately/tree": "^3.8.8",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/i18n": {
+ "version": "3.12.9",
+ "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.9.tgz",
+ "integrity": "sha512-Fim0FLfY05kcpIILdOtqcw58c3sksvmVY8kICSwKCuSek4wYfwJdU28p/sRptw4adJhqN8Cbssvkf/J8zL2GgA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/date": "^3.8.1",
+ "@internationalized/message": "^3.1.7",
+ "@internationalized/number": "^3.6.2",
+ "@internationalized/string": "^3.2.6",
+ "@react-aria/ssr": "^3.9.8",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/interactions": {
+ "version": "3.25.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.25.1.tgz",
+ "integrity": "sha512-ntLrlgqkmZupbbjekz3fE/n3eQH2vhncx8gUp0+N+GttKWevx7jos11JUBjnJwb1RSOPgRUFcrluOqBp0VgcfQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/ssr": "^3.9.8",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/flags": "^3.1.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/label": {
+ "version": "3.7.18",
+ "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.18.tgz",
+ "integrity": "sha512-Ht9D+xkI2Aysn+JNiHE+UZT4FUOGPF7Lfrmp7xdJCA/tEqqF3xW/pAh+UCNOnnWmH8jTYnUg3bCp4G6GQUxKCQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/landmark": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/landmark/-/landmark-3.0.3.tgz",
+ "integrity": "sha512-mcmHijInDZZY3W9r0SeRuXsHW8Km9rBWKB3eoBz+PVuyJYMuabhQ2mUB5xTbqbnV++Srr7j/59g+Lbw5gAN4lw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0",
+ "use-sync-external-store": "^1.4.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/link": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.8.1.tgz",
+ "integrity": "sha512-ujq7+XIP7OXHu7m2NObvHsl41B/oIBAYI0D+hsxEQo3+x6Q/OUxp9EX2sX4d7TBWvchFmhr6jJdER0QMmeSO/A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/link": "^3.6.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/listbox": {
+ "version": "3.14.4",
+ "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.14.4.tgz",
+ "integrity": "sha512-bW3D7KcnQIF77F3zDRMIGQ6e5e1wHTNUtbKJLE423u1Dhc7K2x0pksir0gLGwElhiBW544lY1jv3kFLOeKa6ng==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/label": "^3.7.18",
+ "@react-aria/selection": "^3.24.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/collections": "^3.12.4",
+ "@react-stately/list": "^3.12.2",
+ "@react-types/listbox": "^3.7.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/live-announcer": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/live-announcer/-/live-announcer-3.4.2.tgz",
+ "integrity": "sha512-6+yNF9ZrZ4YJ60Oxy2gKI4/xy6WUv1iePDCFJkgpNVuOEYi8W8czff8ctXu/RPB25OJx5v2sCw9VirRogTo2zA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
+ "node_modules/@react-aria/menu": {
+ "version": "3.18.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.18.3.tgz",
+ "integrity": "sha512-D0C4CM/QaxhCo2pLWNP+nfgnAeaSZWOdPMo9pnH/toRsoeTbnD6xO1hLhYsOx5ge+hrzjQvthjUrsjPB1AM/BQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/overlays": "^3.27.1",
+ "@react-aria/selection": "^3.24.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/collections": "^3.12.4",
+ "@react-stately/menu": "^3.9.4",
+ "@react-stately/selection": "^3.20.2",
+ "@react-stately/tree": "^3.8.10",
+ "@react-types/button": "^3.12.1",
+ "@react-types/menu": "^3.10.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/meter": {
+ "version": "3.4.21",
+ "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.21.tgz",
+ "integrity": "sha512-IjV4RdotPG3QC9Zjc8VaT+rvypB6yh9pUiEAjJEFhga+ORN/EWBLI8LHKhfep+50z8hH6AP3HLaKBUdZu+4WyQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/progress": "^3.4.21",
+ "@react-types/meter": "^3.4.7",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/numberfield": {
+ "version": "3.11.14",
+ "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.14.tgz",
+ "integrity": "sha512-UvhPlRwVmbNEBBqfgL41P10H1jL4C7P2hWqsVw72tZQJl5k5ujeOzRWk8mkmg+D4FCZvv4iSPJhmyEP8HkgsWg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/spinbutton": "^3.6.15",
+ "@react-aria/textfield": "^3.17.3",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/form": "^3.1.4",
+ "@react-stately/numberfield": "^3.9.12",
+ "@react-types/button": "^3.12.1",
+ "@react-types/numberfield": "^3.8.11",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/overlays": {
+ "version": "3.27.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.27.1.tgz",
+ "integrity": "sha512-wepzwNLkgem6kVlLm6yk7zNIMAt0KPy8vAWlxdfpXWD/hBI30ULl71gL/BxRa5EYG1GMvlOwNti3whzy9lm3eQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/ssr": "^3.9.8",
+ "@react-aria/utils": "^3.29.0",
+ "@react-aria/visually-hidden": "^3.8.23",
+ "@react-stately/overlays": "^3.6.16",
+ "@react-types/button": "^3.12.1",
+ "@react-types/overlays": "^3.8.15",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/progress": {
+ "version": "3.4.21",
+ "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.21.tgz",
+ "integrity": "sha512-KNjoJTY2AU3L+3rozwC81lwDWn6Yk2XQbcQaxEs5frRBbuiCD7hEdrerLIgKa/J85e61MDuEel0Onc0kV9kpyw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/label": "^3.7.16",
+ "@react-aria/utils": "^3.28.1",
+ "@react-types/progress": "^3.5.10",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/radio": {
+ "version": "3.11.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.11.1.tgz",
+ "integrity": "sha512-plAO5MW+QD9/kMe5NNKBzKf/+b6CywdoZ5a1T/VbvkBQYYcHaYQeBuKQ4l+hF+OY2tKAWP0rrjv7tEtacPc9TA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.1",
+ "@react-aria/form": "^3.0.14",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/label": "^3.7.16",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/radio": "^3.10.11",
+ "@react-types/radio": "^3.8.7",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/searchfield": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.8.2.tgz",
+ "integrity": "sha512-xOhmzDd04CAl2d5L/g+PPqUSFCN7Ue11M9qTHnjoQ3HDJ4D82vY7Qik/crKGpJ2bV5ZoRxRuFaebqGRKCiJhSQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/textfield": "^3.17.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/searchfield": "^3.5.10",
+ "@react-types/button": "^3.11.0",
+ "@react-types/searchfield": "^3.6.0",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/select": {
+ "version": "3.15.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.15.3.tgz",
+ "integrity": "sha512-HNtDZTASz6Zt9cFUK+9rmS3XmTwVz/tx1+7W3NNGy5Xx4J8hua0BymcbKiC+Pp/ibPGJT4b7KYyE2N9J17/95w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/form": "^3.0.14",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/label": "^3.7.16",
+ "@react-aria/listbox": "^3.14.2",
+ "@react-aria/menu": "^3.18.1",
+ "@react-aria/selection": "^3.23.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-aria/visually-hidden": "^3.8.21",
+ "@react-stately/select": "^3.6.11",
+ "@react-types/button": "^3.11.0",
+ "@react-types/select": "^3.9.10",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/selection": {
+ "version": "3.24.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.24.1.tgz",
+ "integrity": "sha512-nHUksgjg92iHgseH9L+krk9rX19xGJLTDeobKBX7eoAXQMqQjefu+oDwT0VYdI/qqNURNELE/KPZIVLC4PB81w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.3",
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/selection": "^3.20.2",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/separator": {
+ "version": "3.4.7",
+ "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.4.7.tgz",
+ "integrity": "sha512-zALorCd1my7AAYjRCgR1RdI/w8usVH4GCD8d8MsNyKhZUSDn+TxeriDioNllfgL51rxFRFtnWFhD3/qYVK/vCg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/utils": "^3.28.1",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/slider": {
+ "version": "3.7.17",
+ "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.17.tgz",
+ "integrity": "sha512-B+pdHiuM9G6zLYqvkMWAEiP2AppyC3IU032yUxBUrzh3DDoHPgU8HyFurFKS0diwigzcCBcq0yQ1YTalPzWV5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/label": "^3.7.16",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/slider": "^3.6.2",
+ "@react-types/shared": "^3.28.0",
+ "@react-types/slider": "^3.7.9",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/spinbutton": {
+ "version": "3.6.15",
+ "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.15.tgz",
+ "integrity": "sha512-dVKaRgrSU2utxCd4kqAA8BPrC1PVI1eiJ8gvlVbg25LbwK4dg1WPXQUK+80TbrJc9mOEooPiJvzw59IoQLMNRg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/live-announcer": "^3.4.2",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/button": "^3.12.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/ssr": {
+ "version": "3.9.8",
+ "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.8.tgz",
+ "integrity": "sha512-lQDE/c9uTfBSDOjaZUJS8xP2jCKVk4zjQeIlCH90xaLhHDgbpCdns3xvFpJJujfj3nI4Ll9K7A+ONUBDCASOuw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ },
+ "engines": {
+ "node": ">= 12"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/switch": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.7.1.tgz",
+ "integrity": "sha512-CE7G9pPeltbE5wEVIPlrbjarYoMNS8gsb3+RD4Be/ghKSpwppmQyn12WIs6oQl3YQSBD/GZhfA6OTyOBo0Ro9A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/toggle": "^3.11.1",
+ "@react-stately/toggle": "^3.8.2",
+ "@react-types/shared": "^3.28.0",
+ "@react-types/switch": "^3.5.9",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/table": {
+ "version": "3.17.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.17.1.tgz",
+ "integrity": "sha512-yRZoeNwg+7ZNdq7kP9x+u9yMBL4spIdWvY9XTrYGq2XzNzl1aUUBNVszOV3hOwiU0DEF2zzUuuc8gc8Wys40zw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.1",
+ "@react-aria/grid": "^3.12.1",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/live-announcer": "^3.4.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-aria/visually-hidden": "^3.8.21",
+ "@react-stately/collections": "^3.12.2",
+ "@react-stately/flags": "^3.1.0",
+ "@react-stately/table": "^3.14.0",
+ "@react-types/checkbox": "^3.9.2",
+ "@react-types/grid": "^3.3.0",
+ "@react-types/shared": "^3.28.0",
+ "@react-types/table": "^3.11.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/tabs": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.10.1.tgz",
+ "integrity": "sha512-9tcmp4L0cCTSkJAVvsw5XkjTs4MP4ajJsWPc9IUXYoutZWSDs2igqx3/7KKjRM4OrjSolNXFf8uWyr9Oqg+vCg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.1",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/selection": "^3.23.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/tabs": "^3.8.0",
+ "@react-types/shared": "^3.28.0",
+ "@react-types/tabs": "^3.3.13",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/tag": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.5.1.tgz",
+ "integrity": "sha512-dFB7bFeCoCZmyiTKwCsXPcQgqPMtqCtdF9B2gn9S/P6esXrPPr5jCvZKyKFZidbKpqiaQnj+SAln5qPBEftoSg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/gridlist": "^3.11.1",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/label": "^3.7.16",
+ "@react-aria/selection": "^3.23.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/list": "^3.12.0",
+ "@react-types/button": "^3.11.0",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/textfield": {
+ "version": "3.17.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.17.3.tgz",
+ "integrity": "sha512-p/Z0fyE0CnzIrnCf42gxeSCNYon7//XkcbPwUS4U9dz2VLk2GnEn9NZXPYgTp+08ebQEn0pB1QIchX79yFEguw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/form": "^3.0.16",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/label": "^3.7.18",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/form": "^3.1.4",
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/shared": "^3.29.1",
+ "@react-types/textfield": "^3.12.2",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/toast": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/toast/-/toast-3.0.3.tgz",
+ "integrity": "sha512-7HWTKIVwS1JFC8//BQbRtGFaAdq4SljvI3yI5amLr90CyVM0sugTtcSX9a8BPnp1j9ao+6bmOi/wrV48mze1PA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.9",
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/landmark": "^3.0.3",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/toast": "^3.1.0",
+ "@react-types/button": "^3.12.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/toggle": {
+ "version": "3.11.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.11.3.tgz",
+ "integrity": "sha512-S6ShToNR6TukRJh8qDdyl9b2Bcsx43eurUB5USANn4ycPov8+bIxQnxiknjssZx7jD8vX4jruuNh7BjFbNsGFw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-stately/toggle": "^3.8.4",
+ "@react-types/checkbox": "^3.9.4",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/toolbar": {
+ "version": "3.0.0-beta.14",
+ "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.14.tgz",
+ "integrity": "sha512-F9wFYhcbVUveo6+JfAjKyz19BnBaXBYG7YyZdGurhn5E1bD+Zrwz/ZCTrrx40xJsbofciCiiwnKiXmzB20Kl5Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/focus": "^3.20.1",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/utils": "^3.28.1",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/tooltip": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.8.1.tgz",
+ "integrity": "sha512-g5Vr5HFGfLQRxdYs8nZeXeNrni5YcRGegRjnEDUZwW+Gwvu8KTrD7IeXrBDndS+XoTzKC4MzfvtyXWWpYmT0KQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/tooltip": "^3.5.2",
+ "@react-types/shared": "^3.28.0",
+ "@react-types/tooltip": "^3.4.15",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/tree": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/tree/-/tree-3.0.1.tgz",
+ "integrity": "sha512-USYRpbpbUChDFSquCc6eYQ+czTuge5m9XH1F/xfSJD0gEe9BG7dRJ9GB/dy6yBoZoNy3VWpTNrHUfPnmiKpgUw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/gridlist": "^3.11.1",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/selection": "^3.23.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/tree": "^3.8.8",
+ "@react-types/button": "^3.11.0",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/utils": {
+ "version": "3.28.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.28.1.tgz",
+ "integrity": "sha512-mnHFF4YOVu9BRFQ1SZSKfPhg3z+lBRYoW5mLcYTQihbKhz48+I1sqRkP7ahMITr8ANH3nb34YaMME4XWmK2Mgg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/ssr": "^3.9.7",
+ "@react-stately/flags": "^3.1.0",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0",
+ "clsx": "^2.0.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/virtualizer": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/@react-aria/virtualizer/-/virtualizer-4.1.3.tgz",
+ "integrity": "sha512-WzxqQa0mVw96EKHWZIJYQlZfmpOJNpj7PX2Bliawm4rkSS1hpw38waQEHyR95Aexk4vTo5OQnO3w8pun0LXfqg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/virtualizer": "^4.3.1",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-aria/visually-hidden": {
+ "version": "3.8.23",
+ "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.23.tgz",
+ "integrity": "sha512-D37GHtAcxCck8BtCiGTNDniGqtldJuN0cRlW1PJ684zM4CdmkSPqKbt5IUKUfqheS9Vt7HxYsj1VREDW+0kaGA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/interactions": "^3.25.1",
+ "@react-aria/utils": "^3.29.0",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/autocomplete": {
+ "version": "3.0.0-beta.0",
+ "resolved": "https://registry.npmjs.org/@react-stately/autocomplete/-/autocomplete-3.0.0-beta.0.tgz",
+ "integrity": "sha512-nWRbDzqHzdZySIqwoEBMIdineoQxR1Wzmb86r+NICBX9cNv0tZBLNnHywHsul/MN61/TthdOpay1QwZUoQSrXw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/utils": "^3.10.4",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/calendar": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.8.1.tgz",
+ "integrity": "sha512-pTPRmPRD/0JeKhCRvXhVIH/yBimtIHnZGUxH12dcTl3MLxjXQDTn6/LWK0s4rzJcjsC+EzGUCVBBXgESb7PUlw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/date": "^3.8.1",
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/calendar": "^3.7.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/checkbox": {
+ "version": "3.6.14",
+ "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.14.tgz",
+ "integrity": "sha512-eGl0GP/F/nUrA33gDCYikyXK+Yer7sFOx8T4EU2AF4E8n1VQIRiVNaxDg7Ar6L3CMKor01urppFHFJsBUnSgyw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/form": "^3.1.4",
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/checkbox": "^3.9.4",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/collections": {
+ "version": "3.12.4",
+ "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.12.4.tgz",
+ "integrity": "sha512-H+47fRkwYX2/BdSA+NLTzbR+8QclZXyBgC7tHH3dzljyxNimhrMDnbmk520nvGCebNf3nuxtFHq9iVTLpazSVA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/color": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.8.3.tgz",
+ "integrity": "sha512-0KaVN2pIOxdAKanFxkx/8zl+73tCoUn2+k7nvK7SpAsFpWScteEHW6hMdmQVwQ2+X+OtQRYHyhhTXULMIIY6iw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/number": "^3.6.0",
+ "@internationalized/string": "^3.2.5",
+ "@react-stately/form": "^3.1.2",
+ "@react-stately/numberfield": "^3.9.10",
+ "@react-stately/slider": "^3.6.2",
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/color": "^3.0.3",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/combobox": {
+ "version": "3.10.5",
+ "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.10.5.tgz",
+ "integrity": "sha512-27SkClMqbMAKuVnmXhYzYisbLfzV7MO/DEiqWO4/3l+PZ+whL7Wi/Ek7Wqlfluid/y4pN4EkHCKNt4HJ2mhORQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/collections": "^3.12.4",
+ "@react-stately/form": "^3.1.4",
+ "@react-stately/list": "^3.12.2",
+ "@react-stately/overlays": "^3.6.16",
+ "@react-stately/select": "^3.6.13",
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/combobox": "^3.13.5",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/data": {
+ "version": "3.12.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/data/-/data-3.12.2.tgz",
+ "integrity": "sha512-u0yQkISnPyR5RjpNJCSxyC28bx/UvUKtVYRH5yx/MtXbP+2Byn7ItQ+evRqpJB5XsWFlyohGebgbXvL3JSBVsg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/datepicker": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.14.1.tgz",
+ "integrity": "sha512-ad3IOrRppy/F8FZpznGacsaWWHdzUGZ4vpymD+y6TYeQ+RQvS9PLA5Z1TanH9iqLZgkf6bvVggJFg/hhDh2hmg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/date": "^3.8.1",
+ "@internationalized/string": "^3.2.6",
+ "@react-stately/form": "^3.1.4",
+ "@react-stately/overlays": "^3.6.16",
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/datepicker": "^3.12.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/disclosure": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/disclosure/-/disclosure-3.0.2.tgz",
+ "integrity": "sha512-hiArGiJY2y9HcLaGaO1WaXgrTsowd64ZMh8ADVSmxr9drqiMSZ1GXmKuf3DDRHfqKMXX96HNkx5nbv2pczWCsg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/dnd": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.5.2.tgz",
+ "integrity": "sha512-W3Q3O3eIMPHGVKSvkswY8+WCXEli6Wr+LLXYizwAl0dt2+dKKE4r91YugSVnJxXq3cw1/Z4nccmsAPRZa31plQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/selection": "^3.20.0",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/flags": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/flags/-/flags-3.1.1.tgz",
+ "integrity": "sha512-XPR5gi5LfrPdhxZzdIlJDz/B5cBf63l4q6/AzNqVWFKgd0QqY5LvWJftXkklaIUpKSJkIKQb8dphuZXDtkWNqg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
+ "node_modules/@react-stately/form": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.1.4.tgz",
+ "integrity": "sha512-A6GOaZ9oEIo5/XOE+JT9Z8OBt0osIOfes4EcIxGS1C9ght/Smg0gNcIJ2/Wle8qmro4RoJcza2yJ+EglVOuE0w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/grid": {
+ "version": "3.11.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.11.2.tgz",
+ "integrity": "sha512-P0vfK5B1NW8glYD6QMrR2X/7UMXx2J8v48QIQV6KgLZjFbyXhzRb+MY0BoIy4tUfJL0yQU2GKbKKVSUIQxbv0g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/collections": "^3.12.4",
+ "@react-stately/selection": "^3.20.2",
+ "@react-types/grid": "^3.3.2",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/layout": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-4.2.1.tgz",
+ "integrity": "sha512-8ndL33URRyDm6Z+NUR2gS0eVOZQB2mP4pGyvSaM8W68RKF5+XXaPY4QLBuCo2+TsNlqsBNbI2qAznQW1SPQ3+g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/collections": "^3.12.2",
+ "@react-stately/table": "^3.14.0",
+ "@react-stately/virtualizer": "^4.3.1",
+ "@react-types/grid": "^3.3.0",
+ "@react-types/shared": "^3.28.0",
+ "@react-types/table": "^3.11.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/list": {
+ "version": "3.12.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.12.2.tgz",
+ "integrity": "sha512-XPGvdPidOV4hnpmaUNc4C/1jX7ZhBwmAI9p6bEXDA3du3XrWess6MWcaQvPxXbrZ6ZX8/OyOC2wp7ixJoJRGyA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/collections": "^3.12.4",
+ "@react-stately/selection": "^3.20.2",
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/menu": {
+ "version": "3.9.4",
+ "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.9.4.tgz",
+ "integrity": "sha512-sqYcSBuTEtCebZuByUou2aZzwlnrrOlrvmGwFNJy49N3LXXXPENCcCERuWa8TE9eBevIVTQorBZlID6rFG+wdQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/overlays": "^3.6.16",
+ "@react-types/menu": "^3.10.1",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/numberfield": {
+ "version": "3.9.12",
+ "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.9.12.tgz",
+ "integrity": "sha512-E56RuRRdu/lzd8e5aEifP4n8CL/as0sZqIQFSyMv/ZUIIGeksqy+zykzo01skaHKY8u2NixrVHPVDtvPcRuooA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/number": "^3.6.2",
+ "@react-stately/form": "^3.1.4",
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/numberfield": "^3.8.11",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/overlays": {
+ "version": "3.6.16",
+ "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.16.tgz",
+ "integrity": "sha512-+Ve/TBlUNg3otVC4ZfCq1a8q8FwC7xNebWkVOCGviTqiYodPCGqBwR9Z1xonuFLF/HuQYqALHHTOZtxceU+nVQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/overlays": "^3.8.15",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/radio": {
+ "version": "3.10.13",
+ "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.13.tgz",
+ "integrity": "sha512-q7UKcVYY7rqpxKfYRzvKVEqFhxElDFX2c+xliZQtjXuSexhxRb2xjEh+bDkhzbXzrJkrBT6VmE/rSYPurC3xTw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/form": "^3.1.4",
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/radio": "^3.8.9",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/searchfield": {
+ "version": "3.5.10",
+ "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.10.tgz",
+ "integrity": "sha512-6K0+k/8BO/Iq+ODC5mUSIb+tymemliSiSG6B5auWWOZjnnQ0+9M0MYCUdsiJDPk5aUml5aNYI6rlMZO13uHmVw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/utils": "^3.10.5",
+ "@react-types/searchfield": "^3.6.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/select": {
+ "version": "3.6.13",
+ "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.13.tgz",
+ "integrity": "sha512-saZo67CreQZPdmqvz9+P6N4kjohpwdVncH98qBi0Q2FvxGAMnpJQgx97rtfDvnSziST5Yx1JnMI4kSSndbtFwg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/form": "^3.1.4",
+ "@react-stately/list": "^3.12.2",
+ "@react-stately/overlays": "^3.6.16",
+ "@react-types/select": "^3.9.12",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/selection": {
+ "version": "3.20.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.20.2.tgz",
+ "integrity": "sha512-Fw6nnG+VKMsncsY4SNxGYOhnHojVFzFv+Uhy6P39QBp6AXtSaRKMg2VR4MPxQ7XgOjHh5ZuSvCY1RwocweqjwQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/collections": "^3.12.4",
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/slider": {
+ "version": "3.6.4",
+ "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.6.4.tgz",
+ "integrity": "sha512-6SdG0VJZLMRIBnPjqkbIsdyQcW9zJ5Br716cl/7kLT9owiIwMJiAdjdYHab5+8ShWzU2D8Ae+LdQk8ZxIiIjkg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/shared": "^3.29.1",
+ "@react-types/slider": "^3.7.11",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/table": {
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.14.2.tgz",
+ "integrity": "sha512-SqE5A/Ve5H2ApnAblMGBMGRzY7cgdQmNPzXB8tGVc38NsC/STmMkq9m54gAl8dBVNbLzzd6HJBe9lqz5keYIhQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/collections": "^3.12.4",
+ "@react-stately/flags": "^3.1.1",
+ "@react-stately/grid": "^3.11.2",
+ "@react-stately/selection": "^3.20.2",
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/grid": "^3.3.2",
+ "@react-types/shared": "^3.29.1",
+ "@react-types/table": "^3.13.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/tabs": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.8.2.tgz",
+ "integrity": "sha512-lNpby7zUVdAeqo3mjGdPBxppEskOLyqR82LWBtP8Xg4olnjA5RmDFOuoJkIFttDX689zamjN3OE+Ra6WWgJczg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/list": "^3.12.2",
+ "@react-types/shared": "^3.29.1",
+ "@react-types/tabs": "^3.3.15",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/toast": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@react-stately/toast/-/toast-3.1.0.tgz",
+ "integrity": "sha512-9W2+evz+EARrjkR1QPLlOL5lcNpVo6PjMAIygRSaCPJ6ftQAZ6B+7xTFGPFabWh83gwXQDUgoSwC3/vosvxZaQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0",
+ "use-sync-external-store": "^1.4.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/toggle": {
+ "version": "3.8.4",
+ "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.8.4.tgz",
+ "integrity": "sha512-JbKoXhkJ5P5nCrNXChMos3yNqkIeGXPDEMS/dfkHlsjQYxJfylRm4j/nWoDXxxkUmfkvXcNEMofMn9iO1+H0DQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/checkbox": "^3.9.4",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/tooltip": {
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.5.4.tgz",
+ "integrity": "sha512-HxNTqn9nMBuGbEVeeuZyhrzNbyW7sgwk+8o0mN/BrMrk7E/UBhyL2SUxXnAUQftpTjX+29hmx1sPhIprIDzR3Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/overlays": "^3.6.16",
+ "@react-types/tooltip": "^3.4.17",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/tree": {
+ "version": "3.8.10",
+ "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.10.tgz",
+ "integrity": "sha512-sMqBRKAAZMiXJwlzAFpkXqUaGlNBfKnL8usAiKdoeGcLLJt2Ni9gPoPOLBJSPqLOAFCgLWtr5IYjdhel9aXRzQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/collections": "^3.12.4",
+ "@react-stately/selection": "^3.20.2",
+ "@react-stately/utils": "^3.10.6",
+ "@react-types/shared": "^3.29.1",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/utils": {
+ "version": "3.10.6",
+ "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.6.tgz",
+ "integrity": "sha512-O76ip4InfTTzAJrg8OaZxKU4vvjMDOpfA/PGNOytiXwBbkct2ZeZwaimJ8Bt9W1bj5VsZ81/o/tW4BacbdDOMA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-stately/virtualizer": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-4.3.1.tgz",
+ "integrity": "sha512-yWRR9NhaD9NQezRUm1n0cQAYAOAYLOJSxVrCAKyhz/AYvG5JMMvFk3kzgrX8YZXoZKjybcdvy3YZ+jbCSprR6g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/utils": "^3.28.1",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/accordion": {
+ "version": "3.0.0-alpha.26",
+ "resolved": "https://registry.npmjs.org/@react-types/accordion/-/accordion-3.0.0-alpha.26.tgz",
+ "integrity": "sha512-OXf/kXcD2vFlEnkcZy/GG+a/1xO9BN7Uh3/5/Ceuj9z2E/WwD55YwU3GFM5zzkZ4+DMkdowHnZX37XnmbyD3Mg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.27.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/autocomplete": {
+ "version": "3.0.0-alpha.29",
+ "resolved": "https://registry.npmjs.org/@react-types/autocomplete/-/autocomplete-3.0.0-alpha.29.tgz",
+ "integrity": "sha512-brP6fb7RAdfu/liaE4gFZIZQJLXksgtOzdu/I5cmcHfpqScAFmgedZHkJoeutK9wTWtNnfuKAFQ2w9KKlIBj9w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/combobox": "^3.13.3",
+ "@react-types/searchfield": "^3.6.0",
+ "@react-types/shared": "^3.28.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/breadcrumbs": {
+ "version": "3.7.13",
+ "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.13.tgz",
+ "integrity": "sha512-x94KEZaLIeHt9lqAkuaOopX5+rqCTMSHsciThUsBHK7QT64zrw6x2G1WKQ4zB4h52RGF5b+3sFXeR4bgX2sVLQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/link": "^3.6.1",
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/button": {
+ "version": "3.12.1",
+ "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.12.1.tgz",
+ "integrity": "sha512-z87stl4llWTi4C5qhUK1PKcEsG59uF/ZQpkRhMzX0KfgXobJY6yiIrry2xrpnlTPIVST6K1+kARhhSDOZ8zhLw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/calendar": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.7.1.tgz",
+ "integrity": "sha512-a/wGT9vZewPNL72Xni8T/gv4IS2w6iRtryqMF425OL+kaCQrxJYlkDxb74bQs9+k9ZYabrxJgz9vFcFnY7S9gw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/date": "^3.8.1",
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/checkbox": {
+ "version": "3.9.4",
+ "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.9.4.tgz",
+ "integrity": "sha512-fU3Q1Nw+zbXKm68ba8V7cQzpiX0rIiAUKrBTl2BK97QiTlGBDvMCf4TfEuaNoGbJq+gx+X3n/3yr6c3IAb0ZIg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/color": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@react-types/color/-/color-3.0.3.tgz",
+ "integrity": "sha512-oIVdluqe4jYW6tHEHX80tuhhjCA93HElTzbzIGhDezgEbC/EEhWnoC3sGlkUTqIGdzhZG0T+HAkf3AZbCrXqZA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.28.0",
+ "@react-types/slider": "^3.7.9"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/combobox": {
+ "version": "3.13.5",
+ "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.13.5.tgz",
+ "integrity": "sha512-wqHBF0YDkrp4Ylyxpd3xhnDECe5eao27bsu+4AvjlVKtaxaoppNq2MwSzkuSSS/GEUXT6K9DDjrGFcp07ad5gA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/datepicker": {
+ "version": "3.12.1",
+ "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.12.1.tgz",
+ "integrity": "sha512-+wv57fVd6Y/+KnHNEmVzfrQtWs85Ga1Xb63AIkBk+E294aMqFYqRg0dQds6V/qrP758TWnXUrhKza1zMbjHalw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/date": "^3.8.1",
+ "@react-types/calendar": "^3.7.1",
+ "@react-types/overlays": "^3.8.15",
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/dialog": {
+ "version": "3.5.18",
+ "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.18.tgz",
+ "integrity": "sha512-g18CzT5xmiX/numpS6MrOGEGln8Xp9rr+zO70Dg+jM4GBOjXZp3BeclYQr9uisxGaj2uFLnORv9gNMMKxLNF6A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/overlays": "^3.8.15",
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/form": {
+ "version": "3.7.12",
+ "resolved": "https://registry.npmjs.org/@react-types/form/-/form-3.7.12.tgz",
+ "integrity": "sha512-EZ6jZDa9FbLmqvukrLoUp3LUEVE0ZnBB5H6MHhE+QmjYRAvtWljx70xOqnn7sHweuS4+O1kDt1Ec1X5DU+U+BA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/grid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.3.2.tgz",
+ "integrity": "sha512-NwfydUbPc1zVi/Rp7+oRN2+vE1xMokc2J+nr0VcHwFGt1bR1psakHu45Pk/t763BDvPr/A3xIHc1rk3eWEhxJw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/link": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.6.1.tgz",
+ "integrity": "sha512-IZDSc10AuVKe7V8Te+3q8d220oANE4N43iljQe3yHg7GZOfH/51bv8FPUukreLs1t2fgtGeNAzG71Ep+j/jXIw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/listbox": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.7.0.tgz",
+ "integrity": "sha512-26Lp0Gou502VJLDSrIpMg7LQuVHznxzyuSY/zzyNX9eopukXvHn682u90fwDqgmZz7dzxUOWtuwDea+bp/UjtA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/menu": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.10.1.tgz",
+ "integrity": "sha512-wkyWzIqaCbUYiD7YXr8YvdimB1bxQHqgj6uE4MKzryCbVqb4L8fRUM0V6AHkQS1TxBYNkNn1h4g7XNd5Vmyf3Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/overlays": "^3.8.15",
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/meter": {
+ "version": "3.4.7",
+ "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.4.7.tgz",
+ "integrity": "sha512-2GwNJ65+jd8lvrHMel/kiU8o7oPAOt1Sd+kezaeGBTbzKxUhCOAAlp9+zMha8vHQwmMvqcmfAHAqIBGaaCfh5w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/progress": "^3.5.10"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/numberfield": {
+ "version": "3.8.11",
+ "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.8.11.tgz",
+ "integrity": "sha512-D66Bop7M3JKzBV2vsECsVYfPrx8eRIx4/K2KLo/XjwMA7C34+Ou07f/bnD1TQQ/wr6XwiFxZTi6JsKDwnST+9Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/overlays": {
+ "version": "3.8.15",
+ "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.15.tgz",
+ "integrity": "sha512-ppDfezvVYOJDHLZmTSmIXajxAo30l2a1jjy4G65uBYy8J8kTZU7mcfQql5Pii1TwybcNMsayf2WtPItiWmJnOA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/progress": {
+ "version": "3.5.12",
+ "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.12.tgz",
+ "integrity": "sha512-wvhFz6vdlfKBtnzKvD/89N+0PF3yPQ+IVFRQvZ2TBrP7nF+ZA2pNLcZVcEYbKjHzmvEZRGu//ePC9hRJD9K30w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/radio": {
+ "version": "3.8.9",
+ "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.8.9.tgz",
+ "integrity": "sha512-l4uzlxmGGuR8IkWrMYdKj1sc3Pgo/LdfEGuIgK+d8kjPu0AZcnSgp5Oz035bCosZUabY6dEWxQHIoAH2zN7YZA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/searchfield": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.6.0.tgz",
+ "integrity": "sha512-eHQSP85j0hWhWEauPDdr+4kmLB3hUEWxU4ANNubalkupXKhGeRge5/ysHrWjEsLmoodfQ+RS6QIRLQRDsQF/4g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.28.0",
+ "@react-types/textfield": "^3.12.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/select": {
+ "version": "3.9.12",
+ "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.9.12.tgz",
+ "integrity": "sha512-qo+9JS1kfMxuibmSmMp0faGKbeVftYnSk1f7Rh5PKi4tzMe3C0A9IAr27hUOfWeJMBOdetaoTpYmoXW6+CgW3g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/shared": {
+ "version": "3.28.0",
+ "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.28.0.tgz",
+ "integrity": "sha512-9oMEYIDc3sk0G5rysnYvdNrkSg7B04yTKl50HHSZVbokeHpnU0yRmsDaWb9B/5RprcKj8XszEk5guBO8Sa/Q+Q==",
+ "license": "Apache-2.0",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/slider": {
+ "version": "3.7.11",
+ "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.7.11.tgz",
+ "integrity": "sha512-uNhNLhVrt/2teXBOJSoZXyXg308A72qe1HOmlGdJcnh8iXA35y5ZHzeK1P6ZOJ37Aeh7bYGm3/UdURmFgSlW7w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/switch": {
+ "version": "3.5.11",
+ "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.11.tgz",
+ "integrity": "sha512-PJbZHwlE98OSuLzI6b1ei6Qa+FaiwlCRH3tOTdx/wPSdqmD3mRWEn7E9ftM6FC8hnxl/LrGLszQMT62yEQp5vQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/table": {
+ "version": "3.13.0",
+ "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.13.0.tgz",
+ "integrity": "sha512-kn+OsEWJfUSSb4N4J0yl+tqx5grDpcaWcu2J8hA62hQCr/Leuj946ScYaKA9a/p0MAaOAaeCWx/Zcss6F8gJIQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/grid": "^3.3.2",
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/tabs": {
+ "version": "3.3.15",
+ "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.15.tgz",
+ "integrity": "sha512-VLgh9YLQdS4FQSk0sGTNHEVN2jeC0fZvOqEFHaEDgDyDgVOukxYuHjqVIx2IavYu1yNBrGO2b6P4M6dF+hcgwQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/textfield": {
+ "version": "3.12.2",
+ "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.12.2.tgz",
+ "integrity": "sha512-dMm0cGLG5bkJYvt6lqXIty5HXTZjuIpa9I8jAIYua//J8tESAOE9BA285Zl43kx7cZGtgrHKHVFjITDLNUrNhA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@react-types/tooltip": {
+ "version": "3.4.17",
+ "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.17.tgz",
+ "integrity": "sha512-yjySKA1uzJAbio+xGv03DUoWIajteqtsXMd4Y3AJEdBFqSYhXbyrgAxw0oJDgRAgRxY4Rx5Hrhvbt/z7Di94QQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-types/overlays": "^3.8.15",
+ "@react-types/shared": "^3.29.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.9",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz",
+ "integrity": "sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/plugin-node-resolve": {
+ "version": "15.3.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz",
+ "integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "@types/resolve": "1.20.2",
+ "deepmerge": "^4.2.2",
+ "is-module": "^1.0.0",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.78.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-replace": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-6.0.2.tgz",
+ "integrity": "sha512-7QaYCf8bqF04dOy7w/eHmJeNExxTYwvKAmlSAH/EaWWUzbT0h5sbF6bktFoX/0F/0qwng5/dWFMyf3gzaM8DsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.0.1",
+ "magic-string": "^0.30.3"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/plugin-terser": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
+ "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "serialize-javascript": "^6.0.1",
+ "smob": "^1.0.0",
+ "terser": "^5.17.4"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
+ "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz",
+ "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz",
+ "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz",
+ "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz",
+ "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz",
+ "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz",
+ "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz",
+ "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz",
+ "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz",
+ "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz",
+ "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz",
+ "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz",
+ "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz",
+ "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.38.0.tgz",
+ "integrity": "sha512-9EYTX+Gus2EGPbfs+fh7l95wVADtSQyYw4DfSBcYdUEAmP2lqSZY0Y17yX/3m5VKGGJ4UmIH5LHLkMJft3bYoA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz",
+ "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz",
+ "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz",
+ "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz",
+ "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz",
+ "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "peer": true
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz",
+ "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "peer": true
+ },
+ "node_modules/@surma/rollup-plugin-off-main-thread": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
+ "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "ejs": "^3.1.6",
+ "json5": "^2.2.0",
+ "magic-string": "^0.25.0",
+ "string.prototype.matchall": "^4.0.6"
+ }
+ },
+ "node_modules/@surma/rollup-plugin-off-main-thread/node_modules/magic-string": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+ "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sourcemap-codec": "^1.4.8"
+ }
+ },
+ "node_modules/@swc/core": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.1.tgz",
+ "integrity": "sha512-rQ4dS6GAdmtzKiCRt3LFVxl37FaY1cgL9kSUTnhQ2xc3fmHOd7jdJK/V4pSZMG1ruGTd0bsi34O2R0Olg9Zo/w==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/counter": "^0.1.3",
+ "@swc/types": "^0.1.17"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/swc"
+ },
+ "optionalDependencies": {
+ "@swc/core-darwin-arm64": "1.10.1",
+ "@swc/core-darwin-x64": "1.10.1",
+ "@swc/core-linux-arm-gnueabihf": "1.10.1",
+ "@swc/core-linux-arm64-gnu": "1.10.1",
+ "@swc/core-linux-arm64-musl": "1.10.1",
+ "@swc/core-linux-x64-gnu": "1.10.1",
+ "@swc/core-linux-x64-musl": "1.10.1",
+ "@swc/core-win32-arm64-msvc": "1.10.1",
+ "@swc/core-win32-ia32-msvc": "1.10.1",
+ "@swc/core-win32-x64-msvc": "1.10.1"
+ },
+ "peerDependencies": {
+ "@swc/helpers": "*"
+ },
+ "peerDependenciesMeta": {
+ "@swc/helpers": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@swc/core-darwin-arm64": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.1.tgz",
+ "integrity": "sha512-NyELPp8EsVZtxH/mEqvzSyWpfPJ1lugpTQcSlMduZLj1EASLO4sC8wt8hmL1aizRlsbjCX+r0PyL+l0xQ64/6Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-darwin-x64": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.1.tgz",
+ "integrity": "sha512-L4BNt1fdQ5ZZhAk5qoDfUnXRabDOXKnXBxMDJ+PWLSxOGBbWE6aJTnu4zbGjJvtot0KM46m2LPAPY8ttknqaZA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm-gnueabihf": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.1.tgz",
+ "integrity": "sha512-Y1u9OqCHgvVp2tYQAJ7hcU9qO5brDMIrA5R31rwWQIAKDkJKtv3IlTHF0hrbWk1wPR0ZdngkQSJZple7G+Grvw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-gnu": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.1.tgz",
+ "integrity": "sha512-tNQHO/UKdtnqjc7o04iRXng1wTUXPgVd8Y6LI4qIbHVoVPwksZydISjMcilKNLKIwOoUQAkxyJ16SlOAeADzhQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-musl": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.1.tgz",
+ "integrity": "sha512-x0L2Pd9weQ6n8dI1z1Isq00VHFvpBClwQJvrt3NHzmR+1wCT/gcYl1tp9P5xHh3ldM8Cn4UjWCw+7PaUgg8FcQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-gnu": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.1.tgz",
+ "integrity": "sha512-yyYEwQcObV3AUsC79rSzN9z6kiWxKAVJ6Ntwq2N9YoZqSPYph+4/Am5fM1xEQYf/kb99csj0FgOelomJSobxQA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-musl": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.1.tgz",
+ "integrity": "sha512-tcaS43Ydd7Fk7sW5ROpaf2Kq1zR+sI5K0RM+0qYLYYurvsJruj3GhBCaiN3gkzd8m/8wkqNqtVklWaQYSDsyqA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-arm64-msvc": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.1.tgz",
+ "integrity": "sha512-D3Qo1voA7AkbOzQ2UGuKNHfYGKL6eejN8VWOoQYtGHHQi1p5KK/Q7V1ku55oxXBsj79Ny5FRMqiRJpVGad7bjQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-ia32-msvc": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.1.tgz",
+ "integrity": "sha512-WalYdFoU3454Og+sDKHM1MrjvxUGwA2oralknXkXL8S0I/8RkWZOB++p3pLaGbTvOO++T+6znFbQdR8KRaa7DA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-x64-msvc": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.1.tgz",
+ "integrity": "sha512-JWobfQDbTnoqaIwPKQ3DVSywihVXlQMbDuwik/dDWlj33A8oEHcjPOGs4OqcA3RHv24i+lfCQpM3Mn4FAMfacA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.17",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
+ "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@swc/types": {
+ "version": "0.1.17",
+ "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz",
+ "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/counter": "^0.1.3"
+ }
+ },
+ "node_modules/@tanstack/react-virtual": {
+ "version": "3.11.3",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.11.3.tgz",
+ "integrity": "sha512-vCU+OTylXN3hdC8RKg68tPlBPjjxtzon7Ys46MgrSLE+JhSjSTPvoQifV6DQJeJmA8Q3KT6CphJbejupx85vFw==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/virtual-core": "3.11.3"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/@tanstack/virtual-core": {
+ "version": "3.11.3",
+ "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.11.3.tgz",
+ "integrity": "sha512-v2mrNSnMwnPJtcVqNvV0c5roGCBqeogN8jDtgtuHCphdwBasOZ17x8UV8qpHUh+u0MLfX43c0uUHKje0s+Zb0w==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.6.8",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+ "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.20.6",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
+ "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "node_modules/@types/debug": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
+ "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/ms": "*"
+ }
+ },
+ "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==",
+ "license": "MIT"
+ },
+ "node_modules/@types/estree-jsx": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz",
+ "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/hast": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+ "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/hoist-non-react-statics": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz",
+ "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/lodash": {
+ "version": "4.17.17",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.17.tgz",
+ "integrity": "sha512-RRVJ+J3J+WmyOTqnz3PiBLA501eKwXl2noseKOrNo/6+XEHjTAxO4xHvxQB6QuNm+s4WRbn6rSiap8+EA+ykFQ==",
+ "license": "MIT"
+ },
+ "node_modules/@types/lodash.debounce": {
+ "version": "4.0.9",
+ "resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz",
+ "integrity": "sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/lodash": "*"
+ }
+ },
+ "node_modules/@types/mdast": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
+ "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
+ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "22.10.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz",
+ "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.14",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
+ "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
+ "license": "MIT"
+ },
+ "node_modules/@types/react": {
+ "version": "18.3.23",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
+ "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.3.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
+ "devOptional": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^18.0.0"
+ }
+ },
+ "node_modules/@types/resolve": {
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
+ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/unist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
+ "license": "MIT"
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
+ "license": "ISC"
+ },
+ "node_modules/@ungap/with-resolvers": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@ungap/with-resolvers/-/with-resolvers-0.1.0.tgz",
+ "integrity": "sha512-g7f0IkJdPW2xhY7H4iE72DAsIyfuwEFc6JWc2tYFwKDMWWAF699vGjrM348cwQuOXgHpe1gWFe+Eiyjx/ewvvw==",
+ "license": "ISC"
+ },
+ "node_modules/@vaadin/a11y-base": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/a11y-base/-/a11y-base-24.8.0-rc1.tgz",
+ "integrity": "sha512-a+eAWWtLrump0RSARCFLlcKpIcHalHye5zIkYAJmol1URNh8G1/RPeVmamN3nkzdpineS2f3VKVNETI39hmcDQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/accordion": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/accordion/-/accordion-24.8.0-rc1.tgz",
+ "integrity": "sha512-G7KSPsYCvXPwc/ag8OzL+vbdcVezjq/3RkE+2inTYwWyvbCuhkRDt9Yu79XqEAIhXVszGwmpRCJhrjcZQ5HE5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/details": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/app-layout": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/app-layout/-/app-layout-24.8.0-rc1.tgz",
+ "integrity": "sha512-Kz7SOYPc0q5XgPkhTW5V1j+I83b+dAMUslUwzrUN+5P7DIg0pwq6zuR+4KqiPIfsuVDzTQKcu2mUWBub6zGnsA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/avatar": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/avatar/-/avatar-24.8.0-rc1.tgz",
+ "integrity": "sha512-4j3YnUsswJGJUVDUgtWDP627WW6dF6hnvxJ/iuhIZC1+gqTfvCPbbjVX25KNR5RE49Np0GebXUjTHaewGI1ESg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/tooltip": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/avatar-group": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/avatar-group/-/avatar-group-24.8.0-rc1.tgz",
+ "integrity": "sha512-0fd4aLvNfsS/8h8EIZ1Av280PH+BLXbFv09ZqqK9KPMEtTgSnhXB7iWM5chHDhrMgsSoG68togsC2EUChxiffg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/avatar": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/item": "24.8.0-rc1",
+ "@vaadin/list-box": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/tooltip": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/bundles": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/bundles/-/bundles-24.8.0-rc1.tgz",
+ "integrity": "sha512-5Cs20osk3O5/ZipbamBN9/SkUIvHeeJ2HSbDlnIIVVW2296pKIOynGUax06BKX+vy14NW4bwYW7M8rPWabp9Rw==",
+ "license": "(Apache-2.0 OR SEE LICENSE IN https://vaadin.com/license/cvdl-4.0)",
+ "peerDependencies": {
+ "@open-wc/dedupe-mixin": "1.4.0",
+ "@polymer/polymer": "3.5.2",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/accordion": "24.8.0-rc1",
+ "@vaadin/app-layout": "24.8.0-rc1",
+ "@vaadin/avatar": "24.8.0-rc1",
+ "@vaadin/avatar-group": "24.8.0-rc1",
+ "@vaadin/board": "24.8.0-rc1",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/card": "24.8.0-rc1",
+ "@vaadin/charts": "24.8.0-rc1",
+ "@vaadin/checkbox": "24.8.0-rc1",
+ "@vaadin/checkbox-group": "24.8.0-rc1",
+ "@vaadin/combo-box": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/confirm-dialog": "24.8.0-rc1",
+ "@vaadin/context-menu": "24.8.0-rc1",
+ "@vaadin/cookie-consent": "24.8.0-rc1",
+ "@vaadin/crud": "24.8.0-rc1",
+ "@vaadin/custom-field": "24.8.0-rc1",
+ "@vaadin/dashboard": "24.8.0-rc1",
+ "@vaadin/date-picker": "24.8.0-rc1",
+ "@vaadin/date-time-picker": "24.8.0-rc1",
+ "@vaadin/details": "24.8.0-rc1",
+ "@vaadin/dialog": "24.8.0-rc1",
+ "@vaadin/email-field": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/field-highlighter": "24.8.0-rc1",
+ "@vaadin/form-layout": "24.8.0-rc1",
+ "@vaadin/grid": "24.8.0-rc1",
+ "@vaadin/grid-pro": "24.8.0-rc1",
+ "@vaadin/horizontal-layout": "24.8.0-rc1",
+ "@vaadin/icon": "24.8.0-rc1",
+ "@vaadin/icons": "24.8.0-rc1",
+ "@vaadin/input-container": "24.8.0-rc1",
+ "@vaadin/integer-field": "24.8.0-rc1",
+ "@vaadin/item": "24.8.0-rc1",
+ "@vaadin/list-box": "24.8.0-rc1",
+ "@vaadin/lit-renderer": "24.8.0-rc1",
+ "@vaadin/login": "24.8.0-rc1",
+ "@vaadin/map": "24.8.0-rc1",
+ "@vaadin/markdown": "24.8.0-rc1",
+ "@vaadin/master-detail-layout": "24.8.0-rc1",
+ "@vaadin/menu-bar": "24.8.0-rc1",
+ "@vaadin/message-input": "24.8.0-rc1",
+ "@vaadin/message-list": "24.8.0-rc1",
+ "@vaadin/multi-select-combo-box": "24.8.0-rc1",
+ "@vaadin/notification": "24.8.0-rc1",
+ "@vaadin/number-field": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/password-field": "24.8.0-rc1",
+ "@vaadin/polymer-legacy-adapter": "24.8.0-rc1",
+ "@vaadin/popover": "24.8.0-rc1",
+ "@vaadin/progress-bar": "24.8.0-rc1",
+ "@vaadin/radio-group": "24.8.0-rc1",
+ "@vaadin/rich-text-editor": "24.8.0-rc1",
+ "@vaadin/scroller": "24.8.0-rc1",
+ "@vaadin/select": "24.8.0-rc1",
+ "@vaadin/side-nav": "24.8.0-rc1",
+ "@vaadin/split-layout": "24.8.0-rc1",
+ "@vaadin/tabs": "24.8.0-rc1",
+ "@vaadin/tabsheet": "24.8.0-rc1",
+ "@vaadin/text-area": "24.8.0-rc1",
+ "@vaadin/text-field": "24.8.0-rc1",
+ "@vaadin/time-picker": "24.8.0-rc1",
+ "@vaadin/tooltip": "24.8.0-rc1",
+ "@vaadin/upload": "24.8.0-rc1",
+ "@vaadin/vaadin-development-mode-detector": "2.0.7",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "@vaadin/vaadin-usage-statistics": "2.1.3",
+ "@vaadin/vertical-layout": "24.8.0-rc1",
+ "@vaadin/virtual-list": "24.8.0-rc1",
+ "cookieconsent": "3.1.1",
+ "dompurify": "3.2.6",
+ "highcharts": "9.2.2",
+ "lit": "3.3.0",
+ "marked": "15.0.12",
+ "ol": "6.13.0",
+ "quickselect": "2.0.0",
+ "rbush": "3.0.1"
+ },
+ "peerDependenciesMeta": {
+ "@open-wc/dedupe-mixin": {
+ "optional": true
+ },
+ "@polymer/polymer": {
+ "optional": true
+ },
+ "@vaadin/a11y-base": {
+ "optional": true
+ },
+ "@vaadin/accordion": {
+ "optional": true
+ },
+ "@vaadin/app-layout": {
+ "optional": true
+ },
+ "@vaadin/avatar": {
+ "optional": true
+ },
+ "@vaadin/avatar-group": {
+ "optional": true
+ },
+ "@vaadin/board": {
+ "optional": true
+ },
+ "@vaadin/button": {
+ "optional": true
+ },
+ "@vaadin/card": {
+ "optional": true
+ },
+ "@vaadin/charts": {
+ "optional": true
+ },
+ "@vaadin/checkbox": {
+ "optional": true
+ },
+ "@vaadin/checkbox-group": {
+ "optional": true
+ },
+ "@vaadin/combo-box": {
+ "optional": true
+ },
+ "@vaadin/component-base": {
+ "optional": true
+ },
+ "@vaadin/confirm-dialog": {
+ "optional": true
+ },
+ "@vaadin/context-menu": {
+ "optional": true
+ },
+ "@vaadin/cookie-consent": {
+ "optional": true
+ },
+ "@vaadin/crud": {
+ "optional": true
+ },
+ "@vaadin/custom-field": {
+ "optional": true
+ },
+ "@vaadin/dashboard": {
+ "optional": true
+ },
+ "@vaadin/date-picker": {
+ "optional": true
+ },
+ "@vaadin/date-time-picker": {
+ "optional": true
+ },
+ "@vaadin/details": {
+ "optional": true
+ },
+ "@vaadin/dialog": {
+ "optional": true
+ },
+ "@vaadin/email-field": {
+ "optional": true
+ },
+ "@vaadin/field-base": {
+ "optional": true
+ },
+ "@vaadin/field-highlighter": {
+ "optional": true
+ },
+ "@vaadin/form-layout": {
+ "optional": true
+ },
+ "@vaadin/grid": {
+ "optional": true
+ },
+ "@vaadin/grid-pro": {
+ "optional": true
+ },
+ "@vaadin/horizontal-layout": {
+ "optional": true
+ },
+ "@vaadin/icon": {
+ "optional": true
+ },
+ "@vaadin/icons": {
+ "optional": true
+ },
+ "@vaadin/input-container": {
+ "optional": true
+ },
+ "@vaadin/integer-field": {
+ "optional": true
+ },
+ "@vaadin/item": {
+ "optional": true
+ },
+ "@vaadin/list-box": {
+ "optional": true
+ },
+ "@vaadin/lit-renderer": {
+ "optional": true
+ },
+ "@vaadin/login": {
+ "optional": true
+ },
+ "@vaadin/map": {
+ "optional": true
+ },
+ "@vaadin/markdown": {
+ "optional": true
+ },
+ "@vaadin/master-detail-layout": {
+ "optional": true
+ },
+ "@vaadin/menu-bar": {
+ "optional": true
+ },
+ "@vaadin/message-input": {
+ "optional": true
+ },
+ "@vaadin/message-list": {
+ "optional": true
+ },
+ "@vaadin/multi-select-combo-box": {
+ "optional": true
+ },
+ "@vaadin/notification": {
+ "optional": true
+ },
+ "@vaadin/number-field": {
+ "optional": true
+ },
+ "@vaadin/overlay": {
+ "optional": true
+ },
+ "@vaadin/password-field": {
+ "optional": true
+ },
+ "@vaadin/polymer-legacy-adapter": {
+ "optional": true
+ },
+ "@vaadin/popover": {
+ "optional": true
+ },
+ "@vaadin/progress-bar": {
+ "optional": true
+ },
+ "@vaadin/radio-group": {
+ "optional": true
+ },
+ "@vaadin/rich-text-editor": {
+ "optional": true
+ },
+ "@vaadin/scroller": {
+ "optional": true
+ },
+ "@vaadin/select": {
+ "optional": true
+ },
+ "@vaadin/side-nav": {
+ "optional": true
+ },
+ "@vaadin/split-layout": {
+ "optional": true
+ },
+ "@vaadin/tabs": {
+ "optional": true
+ },
+ "@vaadin/tabsheet": {
+ "optional": true
+ },
+ "@vaadin/text-area": {
+ "optional": true
+ },
+ "@vaadin/text-field": {
+ "optional": true
+ },
+ "@vaadin/time-picker": {
+ "optional": true
+ },
+ "@vaadin/tooltip": {
+ "optional": true
+ },
+ "@vaadin/upload": {
+ "optional": true
+ },
+ "@vaadin/vaadin-development-mode-detector": {
+ "optional": true
+ },
+ "@vaadin/vaadin-lumo-styles": {
+ "optional": true
+ },
+ "@vaadin/vaadin-themable-mixin": {
+ "optional": true
+ },
+ "@vaadin/vaadin-usage-statistics": {
+ "optional": true
+ },
+ "@vaadin/vertical-layout": {
+ "optional": true
+ },
+ "@vaadin/virtual-list": {
+ "optional": true
+ },
+ "cookieconsent": {
+ "optional": true
+ },
+ "dompurify": {
+ "optional": true
+ },
+ "highcharts": {
+ "optional": true
+ },
+ "lit": {
+ "optional": true
+ },
+ "marked": {
+ "optional": true
+ },
+ "ol": {
+ "optional": true
+ },
+ "quickselect": {
+ "optional": true
+ },
+ "rbush": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vaadin/button": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/button/-/button-24.8.0-rc1.tgz",
+ "integrity": "sha512-Gyc9uL7P35Qqj8+jfK8auRxE9OfpgAHwxrAug1jzK7mFbWZZjNeXV3IL+6dNXGdlo3emntfs7sgIQcIJQzRGqQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/card": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/card/-/card-24.8.0-rc1.tgz",
+ "integrity": "sha512-V71Xl7M0NP64k9G6Fhh48vRX3tAz9MFvduP/+12suAmdf6CtWee6p5cJtHvfGeTVloZPj0x6RK3OJd04xbiysQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/checkbox": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/checkbox/-/checkbox-24.8.0-rc1.tgz",
+ "integrity": "sha512-/xy1OfpCrUOjJIyNw1WVcOhbFNsP9+euMSkx/aKsH+szrwv25wzcu4/jcX6E8G7HKxvcOnJIrrbxudQEBzy9cA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/checkbox-group": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/checkbox-group/-/checkbox-group-24.8.0-rc1.tgz",
+ "integrity": "sha512-j2T8eot8ccc1oxYuF7HEUwVIzRyZWOX+HENgUDdIpiOKWfgRjHz++hijhg8Kb49WiMi6rVsAvwYeZwFjKDqOyg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/checkbox": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/combo-box": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/combo-box/-/combo-box-24.8.0-rc1.tgz",
+ "integrity": "sha512-iKrTsryGu8+Qs/UbBLB56TrrvfRMCaSbsXiEJBkPtHd6AtrDObfAIGVCyzYzuEOKWwA+L5LEMg4vT4IhbV4wmA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/input-container": "24.8.0-rc1",
+ "@vaadin/item": "24.8.0-rc1",
+ "@vaadin/lit-renderer": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/common-frontend": {
+ "version": "0.0.19",
+ "resolved": "https://registry.npmjs.org/@vaadin/common-frontend/-/common-frontend-0.0.19.tgz",
+ "integrity": "sha512-e6KOPTr1Zj9prX0HvV89+HehsB5x8aPT35JS8r9EktG8ZvVuCv1IM4PZJ7bpttZj0jiRbb9d8iYq+eFDjQWyEQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.3.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/component-base": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/component-base/-/component-base-24.8.0-rc1.tgz",
+ "integrity": "sha512-psL5WFPdDaMsogr2/N0KOhKl25xf2cXC7pz340qF1IOrc6tBUiIpsAGr9WZqYUwB22GuCcB0tNJeoJELmrlnSg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/vaadin-development-mode-detector": "^2.0.0",
+ "@vaadin/vaadin-usage-statistics": "^2.1.0",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/confirm-dialog": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/confirm-dialog/-/confirm-dialog-24.8.0-rc1.tgz",
+ "integrity": "sha512-sW5pz4ywhPGsKvIyOMwpVdFEk3fmUCg+B4LJ11ZmSr/9KmAFrGRH8/uTN4WFb8LZuv8SUEK6ZPJdgFmh8z4N5A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/dialog": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/context-menu": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/context-menu/-/context-menu-24.8.0-rc1.tgz",
+ "integrity": "sha512-w3ltoqnx3orDCi5LyitTRenPj3blgqFe4RqnaA0LfwmgNCrHJUvz5sptge5pqeqcoohcsUHkAeIgW0LLaFTDKQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/item": "24.8.0-rc1",
+ "@vaadin/list-box": "24.8.0-rc1",
+ "@vaadin/lit-renderer": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/custom-field": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/custom-field/-/custom-field-24.8.0-rc1.tgz",
+ "integrity": "sha512-LT4zEwF0dRf9LTuzNGI/Ncv94Q9j35J3Nn9vUH5C/shn8Luiq1n/+Z+jFbqOy7gBpVrvUuC6mGmMnTcw3kg/JQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/date-picker": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/date-picker/-/date-picker-24.8.0-rc1.tgz",
+ "integrity": "sha512-mtmym8JgF39Rcu5IDWVGSTPLm4wXFznUOWCWUKnOM8iEXT+ySDTljujJGNWOiHueZsFYdupU3NftRJ/irVJJEw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.2.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/input-container": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/date-time-picker": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/date-time-picker/-/date-time-picker-24.8.0-rc1.tgz",
+ "integrity": "sha512-RJHiyZvpmlpEaeKZegypozc/GUA39HiylGyEYYPLHisTRZanriykwUOUtTTBKucb1xH7phpPVCPmBhrPIhflZA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/custom-field": "24.8.0-rc1",
+ "@vaadin/date-picker": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/time-picker": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/details": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/details/-/details-24.8.0-rc1.tgz",
+ "integrity": "sha512-mZnBZaS3DDoLJ3MALOJwBfrylXAZWPxUFTSzOsF5Dn9nFhCLyqjr3x8ljIwfAuJU2FSy1vEW6paN49P29m1kRQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/dialog": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/dialog/-/dialog-24.8.0-rc1.tgz",
+ "integrity": "sha512-3EeiZnlNbtJh/Ea7dWX5rd9v7GcKZ2ejF2MjLu33cTei9+s5vrjhogxybm03Qyl4MKN1HKWtcbPdMfXCc5i8Ug==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/lit-renderer": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/email-field": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/email-field/-/email-field-24.8.0-rc1.tgz",
+ "integrity": "sha512-apUAKXkVPfXFf64L6nHBGfM2ZNixSes+r7DroVBbbjtTJuFlH12SQ8lbHhyB3/NWDtsWu1dbLlU7+8KSppHGug==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/text-field": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/field-base": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/field-base/-/field-base-24.8.0-rc1.tgz",
+ "integrity": "sha512-oT3P9hEei15kvTezgVFqvGSxhkGgL52+E4P2RKpHPlPnYcJJ1m00C+6cQAectWewns3GJv3r9vNGe/9v/ibF+A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/field-highlighter": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/field-highlighter/-/field-highlighter-24.8.0-rc1.tgz",
+ "integrity": "sha512-94SteL1HbDxepWTSbvsOUrVPfUh74B0ey4U0mdRnWwtU+kE26RiI3ofzE8hpi2pFY3eqM+/PUDrB7//rDeh7nA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/form-layout": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/form-layout/-/form-layout-24.8.0-rc1.tgz",
+ "integrity": "sha512-Q9AwdTUgJQEh9xQseMHr3xhDq3KteUMJCPnIDOR27kI55DQxi/LL1fXaeELZ1f1FR8iE78Vuzk597TcrH5hQDQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/grid": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/grid/-/grid-24.8.0-rc1.tgz",
+ "integrity": "sha512-O4UQq9V8yXfHNz7rGyS5RZ3piopp9qMJinkkYV7j2gi2QhNb4tyZCR+bi9rewCN4xuRbXtcwDium5dNTnQ732A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/checkbox": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/lit-renderer": "24.8.0-rc1",
+ "@vaadin/text-field": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/hilla-file-router": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-file-router/-/hilla-file-router-24.8.0-rc1.tgz",
+ "integrity": "sha512-c0wNyxI5lvt/9ic6CXWdnApmzTrhyfWgGJxbRsPLebjYT+EMuyFLtecKYY4cKdqC79HoQ+UFRqV6kblPCz2TEQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@ungap/with-resolvers": "0.1.0",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "@vaadin/hilla-react-auth": "24.8.0-rc1",
+ "@vaadin/hilla-react-signals": "24.8.0-rc1",
+ "tsc-template": "0.2.3",
+ "typescript": "5.8.3"
+ },
+ "peerDependencies": {
+ "react": "18 || 19",
+ "react-dom": "18 || 19",
+ "react-router": "7"
+ }
+ },
+ "node_modules/@vaadin/hilla-frontend": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-frontend/-/hilla-frontend-24.8.0-rc1.tgz",
+ "integrity": "sha512-neBwj4HKjFW1B6KgBHIArxwxyX1SSAPo60GA0ExBiXbzPzVFNoXYkd7z8I5Ped5q/Cn8vvmlr+5TVs1eY3hvlg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@vaadin/common-frontend": "0.0.19",
+ "atmosphere.js": "3.1.3",
+ "js-cookie": "3.0.5"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-cli": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-generator-cli/-/hilla-generator-cli-24.8.0-rc1.tgz",
+ "integrity": "sha512-TXIFZUjaSYm1FQjAIFGiIPg5f2eqaFPgMKMxEHCdi89SrPQ/h+ELxgMZwU9l8ihufu5i+AeV2pxmJul/ddZsdw==",
+ "dev": true,
+ "license": "Apache 2.0",
+ "dependencies": {
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1"
+ },
+ "bin": {
+ "tsgen": "bin/index.js"
+ },
+ "engines": {
+ "node": ">= 16.13"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-core": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-generator-core/-/hilla-generator-core-24.8.0-rc1.tgz",
+ "integrity": "sha512-9xOsbJ7F8sJNYD2UTrPDz+dGFCPBblIsDZjQhmos+HX+apNK6OQdk6RPxuQmLCvIK0u+ErWaIPuD9OiRmzH7PA==",
+ "dev": true,
+ "license": "Apache 2.0",
+ "dependencies": {
+ "@apidevtools/swagger-parser": "10.1.1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "meow": "13.2.0",
+ "openapi-types": "12.1.3",
+ "typescript": "5.8.3"
+ },
+ "engines": {
+ "node": ">= 16.13"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-core/node_modules/meow": {
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz",
+ "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-plugin-backbone": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-generator-plugin-backbone/-/hilla-generator-plugin-backbone-24.8.0-rc1.tgz",
+ "integrity": "sha512-qKHqlmJAVINZuVVSuLYoL1+wJ5NqOFFB/6kG2fMalgj1+BC+f9mfF82/UM8hm9+Fqqrhclq9D9GWOZq/yTfy9w==",
+ "dev": true,
+ "license": "Apache 2.0",
+ "dependencies": {
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-client": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "fast-deep-equal": "3.1.3",
+ "openapi-types": "12.1.3",
+ "typescript": "5.8.3"
+ },
+ "engines": {
+ "node": ">= 16.13"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-plugin-barrel": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-generator-plugin-barrel/-/hilla-generator-plugin-barrel-24.8.0-rc1.tgz",
+ "integrity": "sha512-+dKrZGllehJjegNkceLkZxzwJpe3f/p1fRHKEctXYvQBaXbPK17i0qn8euenIAmv6LprcL+O57M0Y5XWkDhQAQ==",
+ "dev": true,
+ "license": "Apache 2.0",
+ "dependencies": {
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-backbone": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "typescript": "5.8.3"
+ },
+ "engines": {
+ "node": ">= 16.13"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-plugin-client": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-generator-plugin-client/-/hilla-generator-plugin-client-24.8.0-rc1.tgz",
+ "integrity": "sha512-/oIpsrg373Ncn76IowJYoSl8Os+LdEy+O3B9UzlY015gR98dR636xEaasEWFHDGuMsquoRxNgQ2Us9TYZvVw2A==",
+ "dev": true,
+ "license": "Apache 2.0",
+ "dependencies": {
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "typescript": "5.8.3"
+ },
+ "engines": {
+ "node": ">= 16.13"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-plugin-model": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-generator-plugin-model/-/hilla-generator-plugin-model-24.8.0-rc1.tgz",
+ "integrity": "sha512-agHoCvT1oCtuQlHXQoSCT6kS3L7oWEpOWGhwXpr2aere1YoyuNDxTstv7hW9QpeKMmuBUH+CD46O/ufWGKwo6A==",
+ "dev": true,
+ "license": "Apache 2.0",
+ "dependencies": {
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-backbone": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "@vaadin/hilla-lit-form": "24.8.0-rc1",
+ "fast-deep-equal": "3.1.3",
+ "openapi-types": "12.1.3",
+ "typescript": "5.8.3"
+ },
+ "engines": {
+ "node": ">= 16.13"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-plugin-push": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-generator-plugin-push/-/hilla-generator-plugin-push-24.8.0-rc1.tgz",
+ "integrity": "sha512-YHpYK8zSWRjKF3xRlBWx9NY8bWe9yinxLmq/979JfSAI1DI/aQy5lwGKGKCKUxRrpWL5LFipcsSnREaOlc3h8w==",
+ "dev": true,
+ "license": "Apache 2.0",
+ "dependencies": {
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-client": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "fast-deep-equal": "3.1.3",
+ "openapi-types": "12.1.3",
+ "typescript": "5.8.3"
+ },
+ "engines": {
+ "node": ">= 16.13"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-plugin-signals": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-generator-plugin-signals/-/hilla-generator-plugin-signals-24.8.0-rc1.tgz",
+ "integrity": "sha512-VHQjpVJLYNyGTioKpTxCOu9m9V0q/LOEvuiZ6QWsUpZA27KUZ913wiTzzB+852dWNAgZKi3TOfPtGp4ntqD32A==",
+ "dev": true,
+ "license": "Apache 2.0",
+ "dependencies": {
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "fast-deep-equal": "3.1.3",
+ "iterator-helpers-polyfill": "3.0.1",
+ "openapi-types": "12.1.3",
+ "tsc-template": "0.2.3",
+ "typescript": "5.8.3"
+ },
+ "engines": {
+ "node": ">= 16.13"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-plugin-subtypes": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-generator-plugin-subtypes/-/hilla-generator-plugin-subtypes-24.8.0-rc1.tgz",
+ "integrity": "sha512-qvjPkkfOjGaqmo5p0la8VQXyMDmoBMHe+BgaJOdAu1Lz32c0vEl2CTEXXmQOpbToeAwB2wq1u7SzqTwLarxhlQ==",
+ "dev": true,
+ "license": "Apache 2.0",
+ "dependencies": {
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-client": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-model": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "fast-deep-equal": "^3.1.3",
+ "openapi-types": "^12.1.3",
+ "typescript": "5.8.3"
+ },
+ "engines": {
+ "node": ">= 16.13"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-plugin-transfertypes": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-generator-plugin-transfertypes/-/hilla-generator-plugin-transfertypes-24.8.0-rc1.tgz",
+ "integrity": "sha512-9BqtN1tPVS07lMZO7f0H0D3l13HlcPD98BDjqomE/P9LyGQd08nO7i3StRjsVYaWSP5O7aMoZJqoBtEyaihShw==",
+ "dev": true,
+ "license": "Apache 2.0",
+ "dependencies": {
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-client": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-model": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "fast-deep-equal": "3.1.3",
+ "openapi-types": "12.1.3",
+ "typescript": "5.8.3"
+ },
+ "engines": {
+ "node": ">= 16.13"
+ }
+ },
+ "node_modules/@vaadin/hilla-generator-utils": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-generator-utils/-/hilla-generator-utils-24.8.0-rc1.tgz",
+ "integrity": "sha512-jZKgUKQxeD8l0T0ULVIul5kA869MLU+2IE3BTGReC/HzGp3ONRRfqiMPGBUh671jCPWh4lGkvxVaJVu+HgPu0A==",
+ "license": "Apache 2.0",
+ "dependencies": {
+ "pino": "9.6.0",
+ "pino-pretty": "10.3.1",
+ "typescript": "5.8.3"
+ },
+ "engines": {
+ "node": ">= 16.13"
+ }
+ },
+ "node_modules/@vaadin/hilla-lit-form": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-lit-form/-/hilla-lit-form-24.8.0-rc1.tgz",
+ "integrity": "sha512-PT9q1LHrg03Ys+G36RUxsSJogTcM3q/nWB0qDjxO2w1V2JrhdxwVwpimGUZGFpIQ1wN4dtYhwxEqrAxH2IZltg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@vaadin/hilla-frontend": "24.8.0-rc1",
+ "validator": "13.12.0"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/hilla-react-auth": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-react-auth/-/hilla-react-auth-24.8.0-rc1.tgz",
+ "integrity": "sha512-7+k7nLevhzerJrHlrrBDlme1scsKYSKdVpr9+301Ra8DnUoe8U8W1mIzXBxSMCsec4R/Rdpw/W5r00E0YCdxqA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@vaadin/hilla-frontend": "24.8.0-rc1"
+ },
+ "peerDependencies": {
+ "react": "18 || 19",
+ "react-dom": "18 || 19",
+ "react-router": "7"
+ }
+ },
+ "node_modules/@vaadin/hilla-react-crud": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-react-crud/-/hilla-react-crud-24.8.0-rc1.tgz",
+ "integrity": "sha512-k8MRLGKFRyyGvkBwJ1He5azqf9wqPlh6SXWuHGRMG4+Aj0WEv7SbAq3/yghf3vE/7RJsZZzJasDTI235G1B+TQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@vaadin/hilla-frontend": "24.8.0-rc1",
+ "@vaadin/hilla-lit-form": "24.8.0-rc1",
+ "@vaadin/hilla-react-form": "24.8.0-rc1",
+ "@vaadin/react-components": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "type-fest": "4.35.0"
+ },
+ "peerDependencies": {
+ "react": "18 || 19",
+ "react-dom": "18 || 19"
+ }
+ },
+ "node_modules/@vaadin/hilla-react-form": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-react-form/-/hilla-react-form-24.8.0-rc1.tgz",
+ "integrity": "sha512-bzz8yfNLhol+4ogBzIScncKd0jgRVjsE6oWCZwxCXk72Kbrz2dLByZB9+UrNBVJR8jX+5wRNUR9+1P5WsGXYxA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@vaadin/hilla-lit-form": "24.8.0-rc1"
+ },
+ "peerDependencies": {
+ "react": "18 || 19",
+ "react-dom": "18 || 19"
+ }
+ },
+ "node_modules/@vaadin/hilla-react-i18n": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-react-i18n/-/hilla-react-i18n-24.8.0-rc1.tgz",
+ "integrity": "sha512-Cra1/Y3bDpzg2fePG/DNy6hUdfgzFNW5bhRhdF1HGj4uctmG3Fe8zZIAbo10GOG6fEuAOlwlQ3EVwpbNFYEBPA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@vaadin/hilla-frontend": "24.8.0-rc1",
+ "@vaadin/hilla-react-signals": "24.8.0-rc1",
+ "intl-messageformat": "10.7.11"
+ },
+ "peerDependencies": {
+ "react": "18 || 19",
+ "react-dom": "18 || 19"
+ }
+ },
+ "node_modules/@vaadin/hilla-react-i18n/node_modules/@formatjs/ecma402-abstract": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.2.tgz",
+ "integrity": "sha512-6sE5nyvDloULiyOMbOTJEEgWL32w+VHkZQs8S02Lnn8Y/O5aQhjOEXwWzvR7SsBE/exxlSpY2EsWZgqHbtLatg==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/fast-memoize": "2.2.6",
+ "@formatjs/intl-localematcher": "0.5.10",
+ "decimal.js": "10",
+ "tslib": "2"
+ }
+ },
+ "node_modules/@vaadin/hilla-react-i18n/node_modules/@formatjs/fast-memoize": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.6.tgz",
+ "integrity": "sha512-luIXeE2LJbQnnzotY1f2U2m7xuQNj2DA8Vq4ce1BY9ebRZaoPB1+8eZ6nXpLzsxuW5spQxr7LdCg+CApZwkqkw==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/@vaadin/hilla-react-i18n/node_modules/@formatjs/icu-messageformat-parser": {
+ "version": "2.9.8",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.8.tgz",
+ "integrity": "sha512-hZlLNI3+Lev8IAXuwehLoN7QTKqbx3XXwFW1jh0AdIA9XJdzn9Uzr+2LLBspPm/PX0+NLIfykj/8IKxQqHUcUQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.3.2",
+ "@formatjs/icu-skeleton-parser": "1.8.12",
+ "tslib": "2"
+ }
+ },
+ "node_modules/@vaadin/hilla-react-i18n/node_modules/@formatjs/icu-skeleton-parser": {
+ "version": "1.8.12",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.12.tgz",
+ "integrity": "sha512-QRAY2jC1BomFQHYDMcZtClqHR55EEnB96V7Xbk/UiBodsuFc5kujybzt87+qj1KqmJozFhk6n4KiT1HKwAkcfg==",
+ "license": "MIT",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.3.2",
+ "tslib": "2"
+ }
+ },
+ "node_modules/@vaadin/hilla-react-i18n/node_modules/@formatjs/intl-localematcher": {
+ "version": "0.5.10",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.10.tgz",
+ "integrity": "sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "2"
+ }
+ },
+ "node_modules/@vaadin/hilla-react-i18n/node_modules/intl-messageformat": {
+ "version": "10.7.11",
+ "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.11.tgz",
+ "integrity": "sha512-IB2N1tmI24k2EFH3PWjU7ivJsnWyLwOWOva0jnXFa29WzB6fb0JZ5EMQGu+XN5lDtjHYFo0/UooP67zBwUg7rQ==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.3.2",
+ "@formatjs/fast-memoize": "2.2.6",
+ "@formatjs/icu-messageformat-parser": "2.9.8",
+ "tslib": "2"
+ }
+ },
+ "node_modules/@vaadin/hilla-react-signals": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/hilla-react-signals/-/hilla-react-signals-24.8.0-rc1.tgz",
+ "integrity": "sha512-3qBaEngJaICQbPWJjTyU233+PTdvYL93a6GiYG7wkq4cDdo29NQs+ZtljhFQIIBE7fgVWbTvHdnYSMokCE0wxw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@preact/signals-react": "3.0.1",
+ "@vaadin/hilla-frontend": "24.8.0-rc1",
+ "nanoid": "5.0.9"
+ },
+ "peerDependencies": {
+ "react": "18 || 19",
+ "react-dom": "18 || 19"
+ }
+ },
+ "node_modules/@vaadin/horizontal-layout": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/horizontal-layout/-/horizontal-layout-24.8.0-rc1.tgz",
+ "integrity": "sha512-S8VqedgDRtvCqmtnnQKjiHj52ZT0p7uuDFVAyLHPgAF8DbAdn54AsxtqQ7gc52/9G4TicYbi67C3cgP4rlSSag==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/icon": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/icon/-/icon-24.8.0-rc1.tgz",
+ "integrity": "sha512-/v5X9pEIh4JaO7zDHBQJKGRO/4+jjHbZzsKmmOyaC4YMCDcPlyGXHamUfUYJJ1t01Z5BO42GQfVTTUkvckYHDA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/icons": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/icons/-/icons-24.8.0-rc1.tgz",
+ "integrity": "sha512-jd0jNJD4/KvbtEdyL7jKw533vvO7H9mfM9T3TbnoBiiOKhr+n+Ok/e5l9LOyMG6jSevdZU8TMg63e4Y7ytr3yA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/icon": "24.8.0-rc1"
+ }
+ },
+ "node_modules/@vaadin/input-container": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/input-container/-/input-container-24.8.0-rc1.tgz",
+ "integrity": "sha512-ZXN3XKXbuofOHxdFy4D2jlr2GKMfjKI0hlR2bUCU2bOK+vj1BnYTOxijpC+j6Idh5VBhb/kmlDNguJcvKBsOGQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/integer-field": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/integer-field/-/integer-field-24.8.0-rc1.tgz",
+ "integrity": "sha512-lf2JP9ZPt1xrIgJL1R4Q1mlxsU/gdEOk0oxAy0X2xB6J5NKtP9cKsuG17t8q3QWYJJIitWWEsMAyIfAGyDcjyQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/number-field": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1"
+ }
+ },
+ "node_modules/@vaadin/item": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/item/-/item-24.8.0-rc1.tgz",
+ "integrity": "sha512-z38kG8VEB9LDRjIP7RMTUV68LDKeG30PoS68EvdCkVNNLiX4+dKuUtD859swA594wCRr3qPPjaE9jwdS+0ZhGQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/list-box": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/list-box/-/list-box-24.8.0-rc1.tgz",
+ "integrity": "sha512-ZcLyS3RubYOOS8vSK7Z2Ukf6YonpSwazvKQyVNt8/89xP/2RhCmtjqvf7wVtMerEJueLZECpF4U5+EQz+h/Nag==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/item": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/lit-renderer": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/lit-renderer/-/lit-renderer-24.8.0-rc1.tgz",
+ "integrity": "sha512-w3AbrEJWI6hq78OwzANtCl8w/Dkrhlh8uXT/AbC2RR2LNlBxo5SLNHVk1FToKMdZEVk66XtsGdoB+Kb7EYX3fw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/login": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/login/-/login-24.8.0-rc1.tgz",
+ "integrity": "sha512-hjAr27EmIyPdR7QMRkij+8AzOgqzzWMvf6cmcRc0AHN5yQYaDoj/E1tvUtN+cbfyN7aw8sh0YxQnQ+IHDOvENg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/password-field": "24.8.0-rc1",
+ "@vaadin/text-field": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/markdown": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/markdown/-/markdown-24.8.0-rc1.tgz",
+ "integrity": "sha512-itS3qYXkQIW3FWCfHBSMgXc6/OuZVPE7o6L8AQ1DuxP1gCMkSQ8Gu8FMDiPKZycB46qzmzCr/U78GYFUgMfdxQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "dompurify": "^3.2.5",
+ "lit": "^3.0.0",
+ "marked": "^15.0.11"
+ }
+ },
+ "node_modules/@vaadin/master-detail-layout": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/master-detail-layout/-/master-detail-layout-24.8.0-rc1.tgz",
+ "integrity": "sha512-Qgbb1VeHey1b6txzxHfLuYDnGYfzJw+daPnPwkGPMnYYTzStuKrzL+kVTfjgvtiL/6Lbz7lvKBTcPOA3rabU3w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/menu-bar": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/menu-bar/-/menu-bar-24.8.0-rc1.tgz",
+ "integrity": "sha512-18pLVQL7SX4Av9Fxg9kk1VdvmUb5YnaR/wpPY4Ds6/dczWFP3oSsW5GRqs9CCNcgnNvuJiPitpYoFIgGGqUQsg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/context-menu": "24.8.0-rc1",
+ "@vaadin/item": "24.8.0-rc1",
+ "@vaadin/list-box": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/message-input": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/message-input/-/message-input-24.8.0-rc1.tgz",
+ "integrity": "sha512-LrYwFkaG7KH5rsAXTBAoKI1iAVCrtze94PwRBRjVAQJmG+L5pRFFrZrkjufA0AIKNFC/Sa9Odg+pAaiySwC4eg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/text-area": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/message-list": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/message-list/-/message-list-24.8.0-rc1.tgz",
+ "integrity": "sha512-98WUMXBZ483pBlqPJb3z3rGADzISFZAbcNbcaZE7jAlXLR/1XPa3D70Pi7IHZdA8Ihp8RZegCrKG2+QLXZJM2w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/avatar": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/markdown": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/multi-select-combo-box": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/multi-select-combo-box/-/multi-select-combo-box-24.8.0-rc1.tgz",
+ "integrity": "sha512-BBLHiy5gkTVOl0X1aO41s/h5sBPSZ7jTWwbqUnDbTlMheG4AhDtrVjAnG2A4ssstnU8XbCNQ+6aMEVnryi0aNw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/combo-box": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/input-container": "24.8.0-rc1",
+ "@vaadin/item": "24.8.0-rc1",
+ "@vaadin/lit-renderer": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/notification": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/notification/-/notification-24.8.0-rc1.tgz",
+ "integrity": "sha512-vgu2qzbEGZN9VxN9kiyhh3OyqbvclCbL9GL+fdDWToxOgw4G3FVgDx83yRuWyyyZwPfRbnBDoj5yUDpvmQSiCw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/lit-renderer": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/number-field": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/number-field/-/number-field-24.8.0-rc1.tgz",
+ "integrity": "sha512-PzqRPqPWwzM4VftLVUDxpksLFcSajALFup7qvNNtVpAulQsvzrj6bgNFOwxvZsPM7euSKneFGBeiuNIcJ9YcFA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/input-container": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/overlay": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/overlay/-/overlay-24.8.0-rc1.tgz",
+ "integrity": "sha512-xN3Hvhp8neE0/i5JmpeGnhjZhY1cd+bm0d25e+o14IAsKrG1sJ0T+Pu+nkGQQFzBYcN0QS8PGJS9N2SCWLxynw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/password-field": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/password-field/-/password-field-24.8.0-rc1.tgz",
+ "integrity": "sha512-LOFn6lpOAe/lygMxGGBOQIPGhYNFWe3yrKkIhy3vrl6bogz8Es/WdDTPr9GQ9BOJTVGWQIpcWrwiIUWN6NFBTg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/text-field": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/polymer-legacy-adapter": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/polymer-legacy-adapter/-/polymer-legacy-adapter-24.8.0-rc1.tgz",
+ "integrity": "sha512-34wni8MkATNuzkZTsRvErm4hY9F1umFMfH+unIIK5PHIKTjOIhKyw5r2E2++5kLOo+hmH0yRz9QV4fsbfQUgQg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/popover": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/popover/-/popover-24.8.0-rc1.tgz",
+ "integrity": "sha512-/5Y1ZB1+PwzVfC8hfClWkJQYWaeS1+mcnnU4efP2UG2vaqrwEQAcnnWDO57BVfpP1xJel0OnicWBxhQKwIv+rg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/lit-renderer": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/progress-bar": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/progress-bar/-/progress-bar-24.8.0-rc1.tgz",
+ "integrity": "sha512-wQVXzIUHfXkHdLVhab4ObZe0VisZTScJW6ON9CbzFexIljbQLvs23Bx8BQLQIWVkL87/hecGLfZ/yAYJ2RT9zA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/radio-group": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/radio-group/-/radio-group-24.8.0-rc1.tgz",
+ "integrity": "sha512-WfCgd18j82ekbr6r++h4Y2NnGIiopQxmZ6Ge6aL71vahsGMVHrOjb2dvQ5wJKr/BmauxqJUabqNCG+14LPJJNA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/react-components": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/react-components/-/react-components-24.8.0-rc1.tgz",
+ "integrity": "sha512-UiAA51KLCz1RlODl8ffhMA9zkyeMCk6SzG2EhtCOv0/xCOfn6+kaXWKO9c1hbE3fZg4X3cnL1cRquMKS/jBtlg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@lit/react": "^1.0.7",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/accordion": "24.8.0-rc1",
+ "@vaadin/app-layout": "24.8.0-rc1",
+ "@vaadin/avatar": "24.8.0-rc1",
+ "@vaadin/avatar-group": "24.8.0-rc1",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/card": "24.8.0-rc1",
+ "@vaadin/checkbox": "24.8.0-rc1",
+ "@vaadin/checkbox-group": "24.8.0-rc1",
+ "@vaadin/combo-box": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/confirm-dialog": "24.8.0-rc1",
+ "@vaadin/context-menu": "24.8.0-rc1",
+ "@vaadin/custom-field": "24.8.0-rc1",
+ "@vaadin/date-picker": "24.8.0-rc1",
+ "@vaadin/date-time-picker": "24.8.0-rc1",
+ "@vaadin/details": "24.8.0-rc1",
+ "@vaadin/dialog": "24.8.0-rc1",
+ "@vaadin/email-field": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/field-highlighter": "24.8.0-rc1",
+ "@vaadin/form-layout": "24.8.0-rc1",
+ "@vaadin/grid": "24.8.0-rc1",
+ "@vaadin/horizontal-layout": "24.8.0-rc1",
+ "@vaadin/icon": "24.8.0-rc1",
+ "@vaadin/icons": "24.8.0-rc1",
+ "@vaadin/input-container": "24.8.0-rc1",
+ "@vaadin/integer-field": "24.8.0-rc1",
+ "@vaadin/item": "24.8.0-rc1",
+ "@vaadin/list-box": "24.8.0-rc1",
+ "@vaadin/lit-renderer": "24.8.0-rc1",
+ "@vaadin/login": "24.8.0-rc1",
+ "@vaadin/markdown": "24.8.0-rc1",
+ "@vaadin/master-detail-layout": "24.8.0-rc1",
+ "@vaadin/menu-bar": "24.8.0-rc1",
+ "@vaadin/message-input": "24.8.0-rc1",
+ "@vaadin/message-list": "24.8.0-rc1",
+ "@vaadin/multi-select-combo-box": "24.8.0-rc1",
+ "@vaadin/notification": "24.8.0-rc1",
+ "@vaadin/number-field": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/password-field": "24.8.0-rc1",
+ "@vaadin/popover": "24.8.0-rc1",
+ "@vaadin/progress-bar": "24.8.0-rc1",
+ "@vaadin/radio-group": "24.8.0-rc1",
+ "@vaadin/scroller": "24.8.0-rc1",
+ "@vaadin/select": "24.8.0-rc1",
+ "@vaadin/side-nav": "24.8.0-rc1",
+ "@vaadin/split-layout": "24.8.0-rc1",
+ "@vaadin/tabs": "24.8.0-rc1",
+ "@vaadin/tabsheet": "24.8.0-rc1",
+ "@vaadin/text-area": "24.8.0-rc1",
+ "@vaadin/text-field": "24.8.0-rc1",
+ "@vaadin/time-picker": "24.8.0-rc1",
+ "@vaadin/tooltip": "24.8.0-rc1",
+ "@vaadin/upload": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "@vaadin/vertical-layout": "24.8.0-rc1",
+ "@vaadin/virtual-list": "24.8.0-rc1"
+ },
+ "peerDependencies": {
+ "@types/react": "^18.2.37 || ^19",
+ "@types/react-dom": "^18.2.15 || ^19",
+ "react": "^18.2.0 || ^19",
+ "react-dom": "^18.2.0 || ^19"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vaadin/scroller": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/scroller/-/scroller-24.8.0-rc1.tgz",
+ "integrity": "sha512-AYJCmfrowXHaFgNkQtCmUgZ3JL+2cBasP2T0vZLZ0IlerJP/F0ENH7T3lAs/gpuFbmJmZGqh9FbY2z0Nva6zdg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/select": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/select/-/select-24.8.0-rc1.tgz",
+ "integrity": "sha512-UhWt+clV9h6grerZ5waxUEbP56JC+JUVZwgfVy7hHVd7Z6t6JAjkhd2xAMjqTkrS1P5bu10bRAx/YFllMJKGkw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.2.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/input-container": "24.8.0-rc1",
+ "@vaadin/item": "24.8.0-rc1",
+ "@vaadin/list-box": "24.8.0-rc1",
+ "@vaadin/lit-renderer": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/side-nav": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/side-nav/-/side-nav-24.8.0-rc1.tgz",
+ "integrity": "sha512-PH9/luG2QF8Chl1Td4qnQT/xFpT2pa4JrHxvq//5NAjxPCjuwnvzQ7jkqDqi790iUmRC59ERCV2ASicUVQQb2A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/split-layout": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/split-layout/-/split-layout-24.8.0-rc1.tgz",
+ "integrity": "sha512-nh1DQ4Fc/xfCf1MkEgTtQYDopwC4nTlpN2xniMyrTH9PsUchIpokBcNwEIZNGr0jKJ9S2wk4NQBaQkjLseqTUQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/tabs": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/tabs/-/tabs-24.8.0-rc1.tgz",
+ "integrity": "sha512-y0wSRq9i8qFH20nM1rvRsaPJl+uPefoBIWhkhoiSDUZu1gYERMiV6HFGSOITgrJ+GX4ykXYf2f2kJ9bNahtyGg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/item": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/tabsheet": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/tabsheet/-/tabsheet-24.8.0-rc1.tgz",
+ "integrity": "sha512-LtvA8Y9hDaSsoxoIgQVg6dXmHEsQygqpmKsEhVo3ly1XTgZLZA6MB1sRToGbKkKqtwr5QL8H1auBaaQ8Iu4leQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/scroller": "24.8.0-rc1",
+ "@vaadin/tabs": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/text-area": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/text-area/-/text-area-24.8.0-rc1.tgz",
+ "integrity": "sha512-BFfEaLIyDF6CrFef/RADu7NWkZtlQWZEjUQz51uoUIewrFI/CjzwVdI0BJ8Qjfy8g4wiPD3Vm1aHkmPGy2SgJw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/input-container": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/text-field": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/text-field/-/text-field-24.8.0-rc1.tgz",
+ "integrity": "sha512-P43sOsG/4fEM9R6cHYZTrRRT3jwb8adb/pIsPn0aw/IxXl5V6qhArf3GR9RhsoDCfAivOXSUryM6Ub/0nd1hcg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/input-container": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/time-picker": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/time-picker/-/time-picker-24.8.0-rc1.tgz",
+ "integrity": "sha512-zlltqL2WnH82/KNrsVVx+J1wcpc+A0BM8bWGlgVisLibUzLhRD9oky9TFhqQPb+ksJweFllNCivoX1DB4SjL3Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/combo-box": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/field-base": "24.8.0-rc1",
+ "@vaadin/input-container": "24.8.0-rc1",
+ "@vaadin/item": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/tooltip": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/tooltip/-/tooltip-24.8.0-rc1.tgz",
+ "integrity": "sha512-hbivo8mHI26eIe/tQXiT4JWUvVvqxrOhfHnoJAwQrlj/zAw9PsYbGRJ0s98aau0eoUiaqatQyaCwX+aFRKFCAA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/overlay": "24.8.0-rc1",
+ "@vaadin/popover": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/upload": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/upload/-/upload-24.8.0-rc1.tgz",
+ "integrity": "sha512-Qzj5BKoup5ZhPckm/s9fGculibrSUNOqlkXyH3HjKS8v0yHBAdTmcPPoxGL6sBmB+O4DETAKB8LHPfhswMN/YQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/a11y-base": "24.8.0-rc1",
+ "@vaadin/button": "24.8.0-rc1",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/progress-bar": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/vaadin-development-mode-detector": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@vaadin/vaadin-development-mode-detector/-/vaadin-development-mode-detector-2.0.7.tgz",
+ "integrity": "sha512-9FhVhr0ynSR3X2ao+vaIEttcNU5XfzCbxtmYOV8uIRnUCtNgbvMOIcyGBvntsX9I5kvIP2dV3cFAOG9SILJzEA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@vaadin/vaadin-lumo-styles": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/vaadin-lumo-styles/-/vaadin-lumo-styles-24.8.0-rc1.tgz",
+ "integrity": "sha512-P9NIM8LQtEBPVnamULUvrWUFVE73pfybMcs3DWRL41UfX6icumwvPYf8+sCiiJj5UE+ihjjo/b0x0gFH7F0b+w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/icon": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1"
+ }
+ },
+ "node_modules/@vaadin/vaadin-material-styles": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/vaadin-material-styles/-/vaadin-material-styles-24.8.0-rc1.tgz",
+ "integrity": "sha512-Mle8GpJ2ridpIakDV2EE8R+d9tfkkRmqPv/m3Aj9Xt5qTqNKDzC0pIffMs7GkooBWN4x3T+4AyoEWUFSbEVhoA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1"
+ }
+ },
+ "node_modules/@vaadin/vaadin-themable-mixin": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/vaadin-themable-mixin/-/vaadin-themable-mixin-24.8.0-rc1.tgz",
+ "integrity": "sha512-Tkjww70/Aefsn8pOTmNzLGcSY6RukRKQelHgz0pykoI6g3TkYR6XdAo/4Y2laoWqf11Q5y9N1dbsFmHAYkI28w==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "lit": "^3.0.0",
+ "style-observer": "^0.0.8"
+ }
+ },
+ "node_modules/@vaadin/vaadin-usage-statistics": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@vaadin/vaadin-usage-statistics/-/vaadin-usage-statistics-2.1.3.tgz",
+ "integrity": "sha512-8r4TNknD7OJQADe3VygeofFR7UNAXZ2/jjBFP5dgI8+2uMfnuGYgbuHivasKr9WSQ64sPej6m8rDoM1uSllXjQ==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@vaadin/vaadin-development-mode-detector": "^2.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/@vaadin/vertical-layout": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/vertical-layout/-/vertical-layout-24.8.0-rc1.tgz",
+ "integrity": "sha512-Iizgermd+I5zPYFKSdrM68RLwjLjsHWHqe+3vxiUd1CiMyZ5fFc3TED/OhPonEJUNXzk9gEnCmsBdRsoBIP2Og==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vaadin/virtual-list": {
+ "version": "24.8.0-rc1",
+ "resolved": "https://registry.npmjs.org/@vaadin/virtual-list/-/virtual-list-24.8.0-rc1.tgz",
+ "integrity": "sha512-by6p8uqXYXUNGmD3SLtRMhQF4l6evymzH7c5+Q4r/DD3bXaSA+z8rtdQybTpa9Oq8xjLdUxhWS0eGQAyCg92cA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@open-wc/dedupe-mixin": "^1.3.0",
+ "@polymer/polymer": "^3.0.0",
+ "@vaadin/component-base": "24.8.0-rc1",
+ "@vaadin/lit-renderer": "24.8.0-rc1",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.5.0.tgz",
+ "integrity": "sha512-JuLWaEqypaJmOJPLWwO335Ig6jSgC1FTONCWAxnqcQthLTK/Yc9aH6hr9z/87xciejbQcnP3GnA1FWUSWeXaeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.26.10",
+ "@babel/plugin-transform-react-jsx-self": "^7.25.9",
+ "@babel/plugin-transform-react-jsx-source": "^7.25.9",
+ "@rolldown/pluginutils": "1.0.0-beta.9",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.17.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0"
+ }
+ },
+ "node_modules/@vitejs/plugin-react-swc": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.2.tgz",
+ "integrity": "sha512-y0byko2b2tSVVf5Gpng1eEhX1OvPC7x8yns1Fx8jDzlJp4LS6CMkCPfLw47cjyoMrshQDoQw4qcgjsU9VvlCew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@swc/core": "^1.7.26"
+ },
+ "peerDependencies": {
+ "vite": "^4 || ^5 || ^6"
+ }
+ },
+ "node_modules/@webcomponents/shadycss": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.11.2.tgz",
+ "integrity": "sha512-vRq+GniJAYSBmTRnhCYPAPq6THYqovJ/gzGThWbgEZUQaBccndGTi1hdiUP15HzEco0I6t4RCtXyX0rsSmwgPw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/abort-controller": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+ "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "license": "MIT",
+ "dependencies": {
+ "event-target-shim": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=6.5"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-node": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
+ "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "acorn": "^7.0.0",
+ "acorn-walk": "^7.0.0",
+ "xtend": "^4.0.2"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-draft-04": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz",
+ "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "ajv": "^8.5.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "license": "MIT"
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/anymatch/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "license": "MIT"
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/aria-hidden": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
+ "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
+ "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.5",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/async-limiter": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+ "license": "MIT"
+ },
+ "node_modules/at-least-node": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/atmosphere.js": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/atmosphere.js/-/atmosphere.js-3.1.3.tgz",
+ "integrity": "sha512-5+GC5e03vElWI4x7zkAtuyeSGYjgN0KzDhJA0Rs/sVT37sHSOioQ6RxIzd9dYYx1AtEi9MVDKWitHBXQBgSWzQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "eventsource": "^1.0.7",
+ "ws": "^6.1.0",
+ "xmlhttprequest": "^1.8.0"
+ }
+ },
+ "node_modules/atomic-sleep": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
+ "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/autoprefixer": {
+ "version": "10.4.20",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
+ "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.23.3",
+ "caniuse-lite": "^1.0.30001646",
+ "fraction.js": "^4.3.7",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.0.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2": {
+ "version": "0.4.12",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz",
+ "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.22.6",
+ "@babel/helper-define-polyfill-provider": "^0.6.3",
+ "semver": "^6.3.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.10.6",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz",
+ "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.2",
+ "core-js-compat": "^3.38.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-regenerator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz",
+ "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
+ "node_modules/bail": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
+ "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-process-hrtime": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz",
+ "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/browserslist": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz",
+ "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001688",
+ "electron-to-chromium": "^1.5.73",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.1"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
+ "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
+ "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-me-maybe": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
+ "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/camelcase-css": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+ "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001720",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001720.tgz",
+ "integrity": "sha512-Ec/2yV2nNPwb4DnTANEV99ZWwm3ZWfdlfkQbWSDDt+PsXEVYwlhPH8tdMaPunYTKKmz7AnHi2oNEi1GcmKCD8g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chalk/node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chalk/node_modules/strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/character-entities": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+ "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-html4": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
+ "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-reference-invalid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+ "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/classnames": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
+ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
+ "license": "MIT"
+ },
+ "node_modules/client-only": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
+ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
+ "license": "MIT"
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/cliui/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/color": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
+ "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1",
+ "color-string": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=12.5.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "license": "MIT"
+ },
+ "node_modules/color-string": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+ "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
+ "node_modules/color2k": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz",
+ "integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==",
+ "license": "MIT"
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "license": "MIT"
+ },
+ "node_modules/comma-separated-tokens": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+ "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/common-tags": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+ "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/compute-scroll-into-view": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz",
+ "integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==",
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/construct-style-sheets-polyfill": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/construct-style-sheets-polyfill/-/construct-style-sheets-polyfill-3.1.0.tgz",
+ "integrity": "sha512-HBLKP0chz8BAY6rBdzda11c3wAZeCZ+kIG4weVC2NM3AXzxx09nhe8t0SQNdloAvg5GLuHwq/0SPOOSPvtCcKw==",
+ "license": "MIT"
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
+ "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/core-js-compat": {
+ "version": "3.39.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz",
+ "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.24.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/cron-validator": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/cron-validator/-/cron-validator-1.3.1.tgz",
+ "integrity": "sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A==",
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/crypto-random-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
+ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
+ },
+ "node_modules/dash-ast": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz",
+ "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/data-view-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
+ "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
+ "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/date-fns": {
+ "version": "2.29.3",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
+ "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.11"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/date-fns"
+ }
+ },
+ "node_modules/dateformat": {
+ "version": "4.6.3",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz",
+ "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decimal.js": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
+ "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
+ "license": "MIT"
+ },
+ "node_modules/decode-named-character-reference": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz",
+ "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==",
+ "license": "MIT",
+ "dependencies": {
+ "character-entities": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-lazy-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+ "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/didyoumean": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
+ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/dlv": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+ "license": "MIT"
+ },
+ "node_modules/dompurify": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz",
+ "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==",
+ "license": "(MPL-2.0 OR Apache-2.0)",
+ "optionalDependencies": {
+ "@types/trusted-types": "^2.0.7"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "license": "MIT"
+ },
+ "node_modules/ejs": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
+ "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "jake": "^10.8.5"
+ },
+ "bin": {
+ "ejs": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.74",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.74.tgz",
+ "integrity": "sha512-ck3//9RC+6oss/1Bh9tiAVFy5vfSKbRHAFh7Z3/eTRkEqJeWgymloShB17Vg3Z4nmDNp35vAd1BZ6CMW4Wt6Iw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "license": "MIT"
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.23.6",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.6.tgz",
+ "integrity": "sha512-Ifco6n3yj2tMZDWNLyloZrytt9lqqlwvS83P3HtaETR0NUOYnIULGGHpktqYGObGy+8wc1okO25p8TjemhImvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "arraybuffer.prototype.slice": "^1.0.4",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "data-view-buffer": "^1.0.1",
+ "data-view-byte-length": "^1.0.1",
+ "data-view-byte-offset": "^1.0.0",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.0.3",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.7",
+ "get-intrinsic": "^1.2.6",
+ "get-symbol-description": "^1.0.2",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.4",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.2",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.2.1",
+ "is-shared-array-buffer": "^1.0.3",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.13",
+ "is-weakref": "^1.1.0",
+ "math-intrinsics": "^1.0.0",
+ "object-inspect": "^1.13.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.5",
+ "regexp.prototype.flags": "^1.5.3",
+ "safe-array-concat": "^1.1.3",
+ "safe-regex-test": "^1.1.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.2",
+ "typed-array-byte-length": "^1.0.1",
+ "typed-array-byte-offset": "^1.0.3",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
+ "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
+ "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.4",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz",
+ "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.2",
+ "@esbuild/android-arm": "0.25.2",
+ "@esbuild/android-arm64": "0.25.2",
+ "@esbuild/android-x64": "0.25.2",
+ "@esbuild/darwin-arm64": "0.25.2",
+ "@esbuild/darwin-x64": "0.25.2",
+ "@esbuild/freebsd-arm64": "0.25.2",
+ "@esbuild/freebsd-x64": "0.25.2",
+ "@esbuild/linux-arm": "0.25.2",
+ "@esbuild/linux-arm64": "0.25.2",
+ "@esbuild/linux-ia32": "0.25.2",
+ "@esbuild/linux-loong64": "0.25.2",
+ "@esbuild/linux-mips64el": "0.25.2",
+ "@esbuild/linux-ppc64": "0.25.2",
+ "@esbuild/linux-riscv64": "0.25.2",
+ "@esbuild/linux-s390x": "0.25.2",
+ "@esbuild/linux-x64": "0.25.2",
+ "@esbuild/netbsd-arm64": "0.25.2",
+ "@esbuild/netbsd-x64": "0.25.2",
+ "@esbuild/openbsd-arm64": "0.25.2",
+ "@esbuild/openbsd-x64": "0.25.2",
+ "@esbuild/sunos-x64": "0.25.2",
+ "@esbuild/win32-arm64": "0.25.2",
+ "@esbuild/win32-ia32": "0.25.2",
+ "@esbuild/win32-x64": "0.25.2"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/estree-util-is-identifier-name": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz",
+ "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/event-target-shim": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/eventsource": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz",
+ "integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "license": "MIT"
+ },
+ "node_modules/fast-copy": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz",
+ "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==",
+ "license": "MIT"
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-redact": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz",
+ "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fast-safe-stringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
+ "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
+ "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fastq": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
+ "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.4.4",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz",
+ "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/filelist": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+ "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "minimatch": "^5.0.1"
+ }
+ },
+ "node_modules/filelist/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "license": "BSD-3-Clause",
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/formik": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz",
+ "integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://opencollective.com/formik"
+ }
+ ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/hoist-non-react-statics": "^3.3.1",
+ "deepmerge": "^2.1.1",
+ "hoist-non-react-statics": "^3.3.0",
+ "lodash": "^4.17.21",
+ "lodash-es": "^4.17.21",
+ "react-fast-compare": "^2.0.1",
+ "tiny-warning": "^1.0.2",
+ "tslib": "^2.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/formik/node_modules/deepmerge": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
+ "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fraction.js": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/framer-motion": {
+ "version": "12.5.0",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.5.0.tgz",
+ "integrity": "sha512-buPlioFbH9/W7rDzYh1C09AuZHAk2D1xTA1BlounJ2Rb9aRg84OXexP0GLd+R83v0khURdMX7b5MKnGTaSg5iA==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^12.5.0",
+ "motion-utils": "^12.5.0",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.7.tgz",
+ "integrity": "sha512-2g4x+HqTJKM9zcJqBSpjoRmdcPFtJM60J3xJisTQSXBWka5XqyBN/2tNUgma1mztTXyDuUsEtYe5qcs7xYzYQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "functions-have-names": "^1.2.3",
+ "hasown": "^2.0.2",
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/fzf": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fzf/-/fzf-0.5.2.tgz",
+ "integrity": "sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz",
+ "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "dunder-proto": "^1.0.0",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "function-bind": "^1.1.2",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-own-enumerable-property-symbols": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
+ "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob": {
+ "version": "11.0.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.2.tgz",
+ "integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^4.0.1",
+ "minimatch": "^10.0.0",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^2.0.0"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-ansi/node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hast-util-to-jsx-runtime": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz",
+ "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "devlop": "^1.0.0",
+ "estree-util-is-identifier-name": "^3.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "mdast-util-mdx-expression": "^2.0.0",
+ "mdast-util-mdx-jsx": "^3.0.0",
+ "mdast-util-mdxjs-esm": "^2.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "style-to-js": "^1.0.0",
+ "unist-util-position": "^5.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-whitespace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+ "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/help-me": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz",
+ "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==",
+ "license": "MIT"
+ },
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/html-url-attributes": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
+ "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/http-status-codes": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz",
+ "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==",
+ "license": "MIT"
+ },
+ "node_modules/idb": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
+ "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/inline-style-parser": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz",
+ "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
+ "license": "MIT"
+ },
+ "node_modules/input-otp": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.1.tgz",
+ "integrity": "sha512-+yvpmKYKHi9jIGngxagY9oWiiblPB7+nEO75F2l2o4vs+6vpPZZmUl4tBNYuTCvQjhvEIbdNeJu70bhfYP2nbw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/intl-messageformat": {
+ "version": "10.7.16",
+ "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.16.tgz",
+ "integrity": "sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "2.3.4",
+ "@formatjs/fast-memoize": "2.2.7",
+ "@formatjs/icu-messageformat-parser": "2.11.2",
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+ "license": "MIT"
+ },
+ "node_modules/is-async-function": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
+ "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz",
+ "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-buffer": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz",
+ "integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==",
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+ "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-hexadecimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+ "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
+ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+ "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-regexp": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz",
+ "integrity": "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.14.tgz",
+ "integrity": "sha512-lQUsHzcTb7rH57dajbOuZEuMDXjs9f04ZloER4QOpjpKcaw4f98BRUrs8aiO9Z4G7i7B0Xhgarg6SCgYcYi8Nw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz",
+ "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "license": "ISC"
+ },
+ "node_modules/iterator-helpers-polyfill": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/iterator-helpers-polyfill/-/iterator-helpers-polyfill-3.0.1.tgz",
+ "integrity": "sha512-9uSoKErC0+TG7uoXlv5k7rs196/l/VGr9hb9KbptpMhszsSksxJCwetp0p7FvgM3SwxlxgEkvokmeOi02PARlQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "chrome": ">=63",
+ "firefox": ">=57",
+ "node": ">=10.0.0",
+ "safari": ">=11"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz",
+ "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/jake": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
+ "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async": "^3.2.3",
+ "chalk": "^4.0.2",
+ "filelist": "^1.0.4",
+ "minimatch": "^3.1.2"
+ },
+ "bin": {
+ "jake": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/jake/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jake/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/jake/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jake/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/jake/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+ "license": "MIT",
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
+ },
+ "node_modules/joycon": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
+ "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/js-cookie": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
+ "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
+ "dev": true,
+ "license": "(AFL-2.1 OR BSD-3-Clause)"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jsonpointer": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz",
+ "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "license": "MIT"
+ },
+ "node_modules/lit": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.0.tgz",
+ "integrity": "sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit/reactive-element": "^2.1.0",
+ "lit-element": "^4.2.0",
+ "lit-html": "^3.3.0"
+ }
+ },
+ "node_modules/lit-element": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.0.tgz",
+ "integrity": "sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit-labs/ssr-dom-shim": "^1.2.0",
+ "@lit/reactive-element": "^2.1.0",
+ "lit-html": "^3.3.0"
+ }
+ },
+ "node_modules/lit-html": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.0.tgz",
+ "integrity": "sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@types/trusted-types": "^2.0.2"
+ }
+ },
+ "node_modules/load-script": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz",
+ "integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==",
+ "license": "MIT"
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "license": "MIT"
+ },
+ "node_modules/lodash-es": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/longest-streak": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
+ "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/marked": {
+ "version": "15.0.12",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz",
+ "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==",
+ "license": "MIT",
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/material-ripple-effects": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/material-ripple-effects/-/material-ripple-effects-2.0.1.tgz",
+ "integrity": "sha512-hHlUkZAuXbP94lu02VgrPidbZ3hBtgXBtjlwR8APNqOIgDZMV8MCIcsclL8FmGJQHvnORyvoQgC965vPsiyXLQ==",
+ "license": "MIT"
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz",
+ "integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/mdast-util-find-and-replace": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz",
+ "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "escape-string-regexp": "^5.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mdast-util-from-markdown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz",
+ "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-to-string": "^4.0.0",
+ "micromark": "^4.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-decode-string": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-expression": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz",
+ "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-jsx": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz",
+ "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "devlop": "^1.1.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0",
+ "parse-entities": "^4.0.0",
+ "stringify-entities": "^4.0.0",
+ "unist-util-stringify-position": "^4.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdxjs-esm": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz",
+ "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-newline-to-break": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-newline-to-break/-/mdast-util-newline-to-break-2.0.0.tgz",
+ "integrity": "sha512-MbgeFca0hLYIEx/2zGsszCSEJJ1JSCdiY5xQxRcLDDGa8EPvlLPupJ4DSajbMPAnC0je8jfb9TiUATnxxrHUog==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-find-and-replace": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-phrasing": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz",
+ "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-hast": {
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz",
+ "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@ungap/structured-clone": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "trim-lines": "^3.0.0",
+ "unist-util-position": "^5.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-markdown": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz",
+ "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "longest-streak": "^3.0.0",
+ "mdast-util-phrasing": "^4.0.0",
+ "mdast-util-to-string": "^4.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-decode-string": "^2.0.0",
+ "unist-util-visit": "^5.0.0",
+ "zwitch": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
+ "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/memoize-one": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
+ "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==",
+ "license": "MIT"
+ },
+ "node_modules/merge-source-map": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz",
+ "integrity": "sha512-PGSmS0kfnTnMJCzJ16BLLCEe6oeYCamKFFdQKshi4BmM6FUwipjVOcBFGxqtQtirtAG4iZvHlqST9CpZKqlRjA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "source-map": "^0.5.6"
+ }
+ },
+ "node_modules/merge-source-map/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromark": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
+ "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@types/debug": "^4.0.0",
+ "debug": "^4.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-combine-extensions": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-core-commonmark": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
+ "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-factory-destination": "^2.0.0",
+ "micromark-factory-label": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-factory-title": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-html-tag-name": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-destination": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
+ "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-label": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
+ "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-space": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-title": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
+ "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-whitespace": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
+ "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-character": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-chunked": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
+ "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-classify-character": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
+ "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-combine-extensions": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
+ "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-decode-numeric-character-reference": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
+ "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-decode-string": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz",
+ "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-encode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-html-tag-name": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
+ "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-normalize-identifier": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
+ "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-resolve-all": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
+ "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-sanitize-uri": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-subtokenize": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
+ "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-symbol": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
+ "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/micromatch/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
+ "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/moment": {
+ "version": "2.30.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
+ "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/moment-timezone": {
+ "version": "0.5.47",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.47.tgz",
+ "integrity": "sha512-UbNt/JAWS0m/NJOebR0QMRHBk0hu03r5dx9GK8Cs0AS3I81yDcOc9k+DytPItgVvBP7J6Mf6U2n3BPAacAV9oA==",
+ "license": "MIT",
+ "dependencies": {
+ "moment": "^2.29.4"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/motion-dom": {
+ "version": "12.5.0",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.5.0.tgz",
+ "integrity": "sha512-uH2PETDh7m+Hjd1UQQ56yHqwn83SAwNjimNPE/kC+Kds0t4Yh7+29rfo5wezVFpPOv57U4IuWved5d1x0kNhbQ==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^12.5.0"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "12.5.0",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.5.0.tgz",
+ "integrity": "sha512-+hFFzvimn0sBMP9iPxBa9OtRX35ZQ3py0UHnb8U29VD+d8lQ8zH3dTygJWqK7av2v6yhg7scj9iZuvTS0f4+SA==",
+ "license": "MIT"
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/mutexify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/mutexify/-/mutexify-1.4.0.tgz",
+ "integrity": "sha512-pbYSsOrSB/AKN5h/WzzLRMFgZhClWccf2XIB4RSMC8JbquiB0e0/SH5AIfdQMdyHmYtv4seU7yV/TvAwPLJ1Yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "queue-tick": "^1.0.0"
+ }
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/nanobench": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nanobench/-/nanobench-2.1.1.tgz",
+ "integrity": "sha512-z+Vv7zElcjN+OpzAxAquUayFLGK3JI/ubCl0Oh64YQqsTGG09CGqieJVQw4ui8huDnnAgrvTv93qi5UaOoNj8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browser-process-hrtime": "^0.1.2",
+ "chalk": "^1.1.3",
+ "mutexify": "^1.1.0",
+ "pretty-hrtime": "^1.0.2"
+ },
+ "bin": {
+ "nanobench": "run.js",
+ "nanobench-compare": "compare.js"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "5.0.9",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz",
+ "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.js"
+ },
+ "engines": {
+ "node": "^18 || >=20"
+ }
+ },
+ "node_modules/next-themes": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz",
+ "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz",
+ "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^4.0.0",
+ "unicorn-magic": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-path/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
+ "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
+ "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-exit-leak-free": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz",
+ "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/open": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
+ "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-lazy-prop": "^2.0.0",
+ "is-docker": "^2.1.1",
+ "is-wsl": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/openapi-types": {
+ "version": "12.1.3",
+ "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
+ "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/parse-entities": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
+ "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "character-entities-legacy": "^3.0.0",
+ "character-reference-invalid": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0",
+ "is-hexadecimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/parse-entities/node_modules/@types/unist": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+ "license": "MIT"
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "license": "MIT"
+ },
+ "node_modules/path-scurry": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
+ "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz",
+ "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pino": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/pino/-/pino-9.6.0.tgz",
+ "integrity": "sha512-i85pKRCt4qMjZ1+L7sy2Ag4t1atFcdbEt76+7iRJn1g2BvsnRMGu9p8pivl9fs63M2kF/A0OacFZhTub+m/qMg==",
+ "license": "MIT",
+ "dependencies": {
+ "atomic-sleep": "^1.0.0",
+ "fast-redact": "^3.1.1",
+ "on-exit-leak-free": "^2.1.0",
+ "pino-abstract-transport": "^2.0.0",
+ "pino-std-serializers": "^7.0.0",
+ "process-warning": "^4.0.0",
+ "quick-format-unescaped": "^4.0.3",
+ "real-require": "^0.2.0",
+ "safe-stable-stringify": "^2.3.1",
+ "sonic-boom": "^4.0.1",
+ "thread-stream": "^3.0.0"
+ },
+ "bin": {
+ "pino": "bin.js"
+ }
+ },
+ "node_modules/pino-abstract-transport": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz",
+ "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==",
+ "license": "MIT",
+ "dependencies": {
+ "split2": "^4.0.0"
+ }
+ },
+ "node_modules/pino-pretty": {
+ "version": "10.3.1",
+ "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.3.1.tgz",
+ "integrity": "sha512-az8JbIYeN/1iLj2t0jR9DV48/LQ3RC6hZPpapKPkb84Q+yTidMCpgWxIT3N0flnBDilyBQ1luWNpOeJptjdp/g==",
+ "license": "MIT",
+ "dependencies": {
+ "colorette": "^2.0.7",
+ "dateformat": "^4.6.3",
+ "fast-copy": "^3.0.0",
+ "fast-safe-stringify": "^2.1.1",
+ "help-me": "^5.0.0",
+ "joycon": "^3.1.1",
+ "minimist": "^1.2.6",
+ "on-exit-leak-free": "^2.1.0",
+ "pino-abstract-transport": "^1.0.0",
+ "pump": "^3.0.0",
+ "readable-stream": "^4.0.0",
+ "secure-json-parse": "^2.4.0",
+ "sonic-boom": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "bin": {
+ "pino-pretty": "bin.js"
+ }
+ },
+ "node_modules/pino-pretty/node_modules/pino-abstract-transport": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz",
+ "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "^4.0.0",
+ "split2": "^4.0.0"
+ }
+ },
+ "node_modules/pino-pretty/node_modules/sonic-boom": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz",
+ "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==",
+ "license": "MIT",
+ "dependencies": {
+ "atomic-sleep": "^1.0.0"
+ }
+ },
+ "node_modules/pino-std-serializers": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz",
+ "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==",
+ "license": "MIT"
+ },
+ "node_modules/pirates": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
+ "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
+ "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.49",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
+ "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-import": {
+ "version": "16.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-16.1.0.tgz",
+ "integrity": "sha512-7hsAZ4xGXl4MW+OKEWCnF6T5jqBw80/EE9aXg1r2yyn1RsVEU8EtKXbijEODa+rg7iih4bKf7vlvTGYR4CnPNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.0"
+ }
+ },
+ "node_modules/postcss-js": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
+ "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
+ "license": "MIT",
+ "dependencies": {
+ "camelcase-css": "^2.0.1"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >= 16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.21"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
+ "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "lilconfig": "^3.0.0",
+ "yaml": "^2.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "peerDependencies": {
+ "postcss": ">=8.0.9",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "postcss": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss-nested": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
+ "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^6.1.1"
+ },
+ "engines": {
+ "node": ">=12.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.14"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "license": "MIT"
+ },
+ "node_modules/postcss/node_modules/nanoid": {
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/pretty-bytes": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
+ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pretty-hrtime": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+ "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/process-warning": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.1.tgz",
+ "integrity": "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/property-expr": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
+ "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==",
+ "license": "MIT"
+ },
+ "node_modules/property-information": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
+ "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/proxy-compare": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.1.tgz",
+ "integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==",
+ "license": "MIT"
+ },
+ "node_modules/pump": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
+ "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/queue-tick": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
+ "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/quick-format-unescaped": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
+ "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==",
+ "license": "MIT"
+ },
+ "node_modules/rand-seed": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/rand-seed/-/rand-seed-2.1.7.tgz",
+ "integrity": "sha512-Yaz75D2fTWtIr69iDd+PGwtQkFkqOIMQZl+W8U3NMR6F2a1UEk2FmnQkNd6Z1eNtL96Z5nznw5PKYk1Z9m6lxw==",
+ "license": "MIT"
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/react": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-accessible-treeview": {
+ "version": "2.11.1",
+ "resolved": "https://registry.npmjs.org/react-accessible-treeview/-/react-accessible-treeview-2.11.1.tgz",
+ "integrity": "sha512-lFegHjFJp2OvtoHMtbIqjby7N3MGDRASlbJsMLqElxQHwZ97xIYho2S4QvXKK7l3/nII0IKDQFJXZNBj6ecG3g==",
+ "license": "MIT",
+ "peerDependencies": {
+ "classnames": "^2.2.6",
+ "prop-types": "^15.7.2",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/react-aria": {
+ "version": "3.38.1",
+ "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.38.1.tgz",
+ "integrity": "sha512-DDdWsAlHPKVQ5E8G0kfDHNs0Lk1Xrs3G7soz6Ew8Ls5vNfp1BusbR2b1wC7ppqq2jDQiyJS816UNmDuGyQVyxA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/string": "^3.2.5",
+ "@react-aria/breadcrumbs": "^3.5.22",
+ "@react-aria/button": "^3.12.1",
+ "@react-aria/calendar": "^3.7.2",
+ "@react-aria/checkbox": "^3.15.3",
+ "@react-aria/color": "^3.0.5",
+ "@react-aria/combobox": "^3.12.1",
+ "@react-aria/datepicker": "^3.14.1",
+ "@react-aria/dialog": "^3.5.23",
+ "@react-aria/disclosure": "^3.0.3",
+ "@react-aria/dnd": "^3.9.1",
+ "@react-aria/focus": "^3.20.1",
+ "@react-aria/gridlist": "^3.11.1",
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/label": "^3.7.16",
+ "@react-aria/landmark": "^3.0.1",
+ "@react-aria/link": "^3.7.10",
+ "@react-aria/listbox": "^3.14.2",
+ "@react-aria/menu": "^3.18.1",
+ "@react-aria/meter": "^3.4.21",
+ "@react-aria/numberfield": "^3.11.12",
+ "@react-aria/overlays": "^3.26.1",
+ "@react-aria/progress": "^3.4.21",
+ "@react-aria/radio": "^3.11.1",
+ "@react-aria/searchfield": "^3.8.2",
+ "@react-aria/select": "^3.15.3",
+ "@react-aria/selection": "^3.23.1",
+ "@react-aria/separator": "^3.4.7",
+ "@react-aria/slider": "^3.7.17",
+ "@react-aria/ssr": "^3.9.7",
+ "@react-aria/switch": "^3.7.1",
+ "@react-aria/table": "^3.17.1",
+ "@react-aria/tabs": "^3.10.1",
+ "@react-aria/tag": "^3.5.1",
+ "@react-aria/textfield": "^3.17.1",
+ "@react-aria/toast": "^3.0.1",
+ "@react-aria/tooltip": "^3.8.1",
+ "@react-aria/tree": "^3.0.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-aria/visually-hidden": "^3.8.21",
+ "@react-types/shared": "^3.28.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/react-aria-components": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.7.1.tgz",
+ "integrity": "sha512-kTAlrxcW7n+rQDwlZSz5+o+HknjPGv/pn0OQ1FF92WsjoTaqQMJtWbEAHXrhrQaiW/3T4CANTpdR1soai4uK6g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@internationalized/date": "^3.7.0",
+ "@internationalized/string": "^3.2.5",
+ "@react-aria/autocomplete": "3.0.0-beta.1",
+ "@react-aria/collections": "3.0.0-beta.1",
+ "@react-aria/dnd": "^3.9.1",
+ "@react-aria/focus": "^3.20.1",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/live-announcer": "^3.4.1",
+ "@react-aria/toolbar": "3.0.0-beta.14",
+ "@react-aria/utils": "^3.28.1",
+ "@react-aria/virtualizer": "^4.1.3",
+ "@react-stately/autocomplete": "3.0.0-beta.0",
+ "@react-stately/layout": "^4.2.1",
+ "@react-stately/selection": "^3.20.0",
+ "@react-stately/table": "^3.14.0",
+ "@react-stately/utils": "^3.10.5",
+ "@react-stately/virtualizer": "^4.3.1",
+ "@react-types/form": "^3.7.10",
+ "@react-types/grid": "^3.3.0",
+ "@react-types/shared": "^3.28.0",
+ "@react-types/table": "^3.11.0",
+ "@swc/helpers": "^0.5.0",
+ "client-only": "^0.0.1",
+ "react-aria": "^3.38.1",
+ "react-stately": "^3.36.1",
+ "use-sync-external-store": "^1.4.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/react-aria/node_modules/@react-aria/landmark": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/landmark/-/landmark-3.0.1.tgz",
+ "integrity": "sha512-rsbpmDfI8wmTcsOCaLdI2WuvM4z4yBZyOhMSdIxzKxxD0XPM03BBlegPqxZ/VisSwvXT8VB38r5STzmpH3ocLg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/utils": "^3.28.1",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0",
+ "use-sync-external-store": "^1.4.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/react-aria/node_modules/@react-aria/numberfield": {
+ "version": "3.11.12",
+ "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.12.tgz",
+ "integrity": "sha512-VQ4dfaf+k7n2tbP8iB1OLFYTLCh9ReyV7dNLrDvH24V7ByaHakobZjwP8tF6CpvafNYaXPUflxnHpIgXvN3QYA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/spinbutton": "^3.6.13",
+ "@react-aria/textfield": "^3.17.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/form": "^3.1.2",
+ "@react-stately/numberfield": "^3.9.10",
+ "@react-types/button": "^3.11.0",
+ "@react-types/numberfield": "^3.8.9",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/react-aria/node_modules/@react-aria/toast": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/toast/-/toast-3.0.1.tgz",
+ "integrity": "sha512-WDzKvQsroIowe4y/5dsZDakG4g0mDju4ZhcEPY3SFVnEBbAH1k0fwSgfygDWZdwg9FS3+oA1IYcbVt4ClK3Vfg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-aria/i18n": "^3.12.7",
+ "@react-aria/interactions": "^3.24.1",
+ "@react-aria/landmark": "^3.0.1",
+ "@react-aria/utils": "^3.28.1",
+ "@react-stately/toast": "^3.0.0",
+ "@react-types/button": "^3.11.0",
+ "@react-types/shared": "^3.28.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1",
+ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/react-aria/node_modules/@react-stately/toast": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@react-stately/toast/-/toast-3.0.0.tgz",
+ "integrity": "sha512-g7e4hNO9E6kOqyBeLRAfZBihp1EIQikmaH3Uj/OZJXKvIDKJlNlpvwstUIcmEuEzqA1Uru78ozxIVWh3pg9ubg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0",
+ "use-sync-external-store": "^1.4.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/react-confetti-boom": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/react-confetti-boom/-/react-confetti-boom-1.1.0.tgz",
+ "integrity": "sha512-OV/NPSV3L9xyTTiFY/QAYtbIq8UYxkm3UBP4K7AjNNeOgI66NVOQHBV1hM26/urVGfBXcQDMh4znD5Iyu2hHjQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
+ "node_modules/react-fast-compare": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz",
+ "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==",
+ "license": "MIT"
+ },
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT"
+ },
+ "node_modules/react-markdown": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz",
+ "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "hast-util-to-jsx-runtime": "^2.0.0",
+ "html-url-attributes": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "remark-parse": "^11.0.0",
+ "remark-rehype": "^11.0.0",
+ "unified": "^11.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18",
+ "react": ">=18"
+ }
+ },
+ "node_modules/react-player": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/react-player/-/react-player-2.16.0.tgz",
+ "integrity": "sha512-mAIPHfioD7yxO0GNYVFD1303QFtI3lyyQZLY229UEAp/a10cSW+hPcakg0Keq8uWJxT2OiT/4Gt+Lc9bD6bJmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "deepmerge": "^4.0.0",
+ "load-script": "^1.0.0",
+ "memoize-one": "^5.1.1",
+ "prop-types": "^15.7.2",
+ "react-fast-compare": "^3.0.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0"
+ }
+ },
+ "node_modules/react-player/node_modules/react-fast-compare": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
+ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
+ "license": "MIT"
+ },
+ "node_modules/react-refresh": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
+ "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-router": {
+ "version": "7.6.1",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.1.tgz",
+ "integrity": "sha512-hPJXXxHJZEsPFNVbtATH7+MMX43UDeOauz+EAU4cgqTn7ojdI9qQORqS8Z0qmDlL1TclO/6jLRYUEtbWidtdHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "cookie": "^1.0.1",
+ "set-cookie-parser": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-stately": {
+ "version": "3.36.1",
+ "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.36.1.tgz",
+ "integrity": "sha512-H9kiGAylNec/iE5qk7qQLV1cvtSAIVq3mgt87zx2EA+f+/sYy2oBtchFPaDiBf/m7xMEKf0Fr9zSLU6G99xQ8g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@react-stately/calendar": "^3.7.1",
+ "@react-stately/checkbox": "^3.6.12",
+ "@react-stately/collections": "^3.12.2",
+ "@react-stately/color": "^3.8.3",
+ "@react-stately/combobox": "^3.10.3",
+ "@react-stately/data": "^3.12.2",
+ "@react-stately/datepicker": "^3.13.0",
+ "@react-stately/disclosure": "^3.0.2",
+ "@react-stately/dnd": "^3.5.2",
+ "@react-stately/form": "^3.1.2",
+ "@react-stately/list": "^3.12.0",
+ "@react-stately/menu": "^3.9.2",
+ "@react-stately/numberfield": "^3.9.10",
+ "@react-stately/overlays": "^3.6.14",
+ "@react-stately/radio": "^3.10.11",
+ "@react-stately/searchfield": "^3.5.10",
+ "@react-stately/select": "^3.6.11",
+ "@react-stately/selection": "^3.20.0",
+ "@react-stately/slider": "^3.6.2",
+ "@react-stately/table": "^3.14.0",
+ "@react-stately/tabs": "^3.8.0",
+ "@react-stately/toast": "^3.0.0",
+ "@react-stately/toggle": "^3.8.2",
+ "@react-stately/tooltip": "^3.5.2",
+ "@react-stately/tree": "^3.8.8",
+ "@react-types/shared": "^3.28.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/react-stately/node_modules/@react-stately/toast": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@react-stately/toast/-/toast-3.0.0.tgz",
+ "integrity": "sha512-g7e4hNO9E6kOqyBeLRAfZBihp1EIQikmaH3Uj/OZJXKvIDKJlNlpvwstUIcmEuEzqA1Uru78ozxIVWh3pg9ubg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0",
+ "use-sync-external-store": "^1.4.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
+ }
+ },
+ "node_modules/react-textarea-autosize": {
+ "version": "8.5.9",
+ "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.9.tgz",
+ "integrity": "sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "use-composed-ref": "^1.3.0",
+ "use-latest": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+ "license": "MIT",
+ "dependencies": {
+ "pify": "^2.3.0"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz",
+ "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==",
+ "license": "MIT",
+ "dependencies": {
+ "abort-controller": "^3.0.0",
+ "buffer": "^6.0.3",
+ "events": "^3.3.0",
+ "process": "^0.11.10",
+ "string_decoder": "^1.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/real-require": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz",
+ "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12.13.0"
+ }
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.8.tgz",
+ "integrity": "sha512-B5dj6usc5dkk8uFliwjwDHM8To5/QwdKz9JcBZ8Ic4G1f0YmeeJTtE/ZTdgRFPAfxZFiUaPhZ1Jcs4qeagItGQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "dunder-proto": "^1.0.0",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.2.0",
+ "which-builtin-type": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regenerate": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/regenerate-unicode-properties": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
+ "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regenerate": "^1.4.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
+ "license": "MIT"
+ },
+ "node_modules/regenerator-transform": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
+ "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.8.4"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
+ "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexpu-core": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
+ "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regenerate": "^1.4.2",
+ "regenerate-unicode-properties": "^10.2.0",
+ "regjsgen": "^0.8.0",
+ "regjsparser": "^0.12.0",
+ "unicode-match-property-ecmascript": "^2.0.0",
+ "unicode-match-property-value-ecmascript": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regjsgen": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
+ "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/regjsparser": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
+ "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "jsesc": "~3.0.2"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/regjsparser/node_modules/jsesc": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+ "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/remark-breaks": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/remark-breaks/-/remark-breaks-4.0.0.tgz",
+ "integrity": "sha512-IjEjJOkH4FuJvHZVIW0QCDWxcG96kCq7An/KVH2NfJe6rKZU2AsHeB3OEjPNRxi4QC34Xdx7I2KGYn6IpT7gxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-newline-to-break": "^2.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-parse": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
+ "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-rehype": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz",
+ "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "unified": "^11.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.9",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.9.tgz",
+ "integrity": "sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==",
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.1.tgz",
+ "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@types/estree": "1.0.6"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.28.1",
+ "@rollup/rollup-android-arm64": "4.28.1",
+ "@rollup/rollup-darwin-arm64": "4.28.1",
+ "@rollup/rollup-darwin-x64": "4.28.1",
+ "@rollup/rollup-freebsd-arm64": "4.28.1",
+ "@rollup/rollup-freebsd-x64": "4.28.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.28.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.28.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.28.1",
+ "@rollup/rollup-linux-arm64-musl": "4.28.1",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.28.1",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.28.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.28.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.28.1",
+ "@rollup/rollup-linux-x64-gnu": "4.28.1",
+ "@rollup/rollup-linux-x64-musl": "4.28.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.28.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.28.1",
+ "@rollup/rollup-win32-x64-msvc": "4.28.1",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rollup-plugin-brotli": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-brotli/-/rollup-plugin-brotli-3.1.0.tgz",
+ "integrity": "sha512-vXRPVd9B1x+aaXeBdmLKNNsai9AH3o0Qikf4u0m1icKqgi3qVA4UhOfwGaPYoAHML1GLMUnR//PDhiMHXN/M6g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=11.7.0"
+ }
+ },
+ "node_modules/rollup-plugin-visualizer": {
+ "version": "5.14.0",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.14.0.tgz",
+ "integrity": "sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "open": "^8.4.0",
+ "picomatch": "^4.0.2",
+ "source-map": "^0.7.4",
+ "yargs": "^17.5.1"
+ },
+ "bin": {
+ "rollup-plugin-visualizer": "dist/bin/cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "rolldown": "1.x",
+ "rollup": "2.x || 3.x || 4.x"
+ },
+ "peerDependenciesMeta": {
+ "rolldown": {
+ "optional": true
+ },
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-stable-stringify": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
+ "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/scroll-into-view-if-needed": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.0.10.tgz",
+ "integrity": "sha512-t44QCeDKAPf1mtQH3fYpWz8IM/DyvHLjs8wUvvwMYxk5moOqCzrMSxK6HQVD0QVmVjXFavoFIPRVrMuJPKAvtg==",
+ "license": "MIT",
+ "dependencies": {
+ "compute-scroll-into-view": "^3.0.2"
+ }
+ },
+ "node_modules/secure-json-parse": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz",
+ "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
+ "license": "MIT"
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.3.1"
+ }
+ },
+ "node_modules/smob": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz",
+ "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/sonic-boom": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz",
+ "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==",
+ "license": "MIT",
+ "dependencies": {
+ "atomic-sleep": "^1.0.0"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/source-map-support/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sourcemap-codec": {
+ "version": "1.4.8",
+ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+ "deprecated": "Please use @jridgewell/sourcemap-codec instead",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/space-separated-tokens": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.matchall": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz",
+ "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.7",
+ "regexp.prototype.flags": "^1.5.2",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/stringify-entities": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
+ "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
+ "license": "MIT",
+ "dependencies": {
+ "character-entities-html4": "^2.0.0",
+ "character-entities-legacy": "^3.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/stringify-object": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
+ "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "get-own-enumerable-property-symbols": "^3.0.0",
+ "is-obj": "^1.0.1",
+ "is-regexp": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/stringify-object/node_modules/is-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
+ "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz",
+ "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/strip-css-comments": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/strip-css-comments/-/strip-css-comments-5.0.0.tgz",
+ "integrity": "sha512-943vUh0ZxvxO6eK+TzY2F4nVN7a+ZdRK4KIdwHaGMvMrXTrAsJBRudOR3Zi0bLTuVSbF0CQXis4uw04uCabWkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-regexp": "^3.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/style-observer": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/style-observer/-/style-observer-0.0.8.tgz",
+ "integrity": "sha512-UaIPn33Sx4BJ+goia51Q++VFWoplWK1995VdxQYzwwbFa+FUNLKlG+aiIdG2Vw7VyzIUBi8tqu8mTyg0Ppu6Yg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/LeaVerou"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/leaverou"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/style-to-js": {
+ "version": "1.1.16",
+ "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz",
+ "integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==",
+ "license": "MIT",
+ "dependencies": {
+ "style-to-object": "1.0.8"
+ }
+ },
+ "node_modules/style-to-object": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz",
+ "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==",
+ "license": "MIT",
+ "dependencies": {
+ "inline-style-parser": "0.2.4"
+ }
+ },
+ "node_modules/sucrase": {
+ "version": "3.35.0",
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "commander": "^4.0.0",
+ "glob": "^10.3.10",
+ "lines-and-columns": "^1.1.6",
+ "mz": "^2.7.0",
+ "pirates": "^4.0.1",
+ "ts-interface-checker": "^0.1.9"
+ },
+ "bin": {
+ "sucrase": "bin/sucrase",
+ "sucrase-node": "bin/sucrase-node"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/sucrase/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/sucrase/node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/sucrase/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "license": "ISC"
+ },
+ "node_modules/sucrase/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/sucrase/node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/swiper": {
+ "version": "11.2.6",
+ "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.6.tgz",
+ "integrity": "sha512-8aXpYKtjy3DjcbzZfz+/OX/GhcU5h+looA6PbAzHMZT6ESSycSp9nAjPCenczgJyslV+rUGse64LMGpWE3PX9Q==",
+ "funding": [
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/swiperjs"
+ },
+ {
+ "type": "open_collective",
+ "url": "http://opencollective.com/swiper"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.7.0"
+ }
+ },
+ "node_modules/tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
+ "license": "MIT"
+ },
+ "node_modules/tailwind-merge": {
+ "version": "2.5.4",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.4.tgz",
+ "integrity": "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/dcastil"
+ }
+ },
+ "node_modules/tailwind-variants": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-0.3.0.tgz",
+ "integrity": "sha512-ho2k5kn+LB1fT5XdNS3Clb96zieWxbStE9wNLK7D0AV64kdZMaYzAKo0fWl6fXLPY99ffF9oBJnIj5escEl/8A==",
+ "license": "MIT",
+ "dependencies": {
+ "tailwind-merge": "^2.5.4"
+ },
+ "engines": {
+ "node": ">=16.x",
+ "pnpm": ">=7.x"
+ },
+ "peerDependencies": {
+ "tailwindcss": "*"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "3.4.17",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
+ "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
+ "license": "MIT",
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "arg": "^5.0.2",
+ "chokidar": "^3.6.0",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.3.2",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "jiti": "^1.21.6",
+ "lilconfig": "^3.1.3",
+ "micromatch": "^4.0.8",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.1.1",
+ "postcss": "^8.4.47",
+ "postcss-import": "^15.1.0",
+ "postcss-js": "^4.0.1",
+ "postcss-load-config": "^4.0.2",
+ "postcss-nested": "^6.2.0",
+ "postcss-selector-parser": "^6.1.2",
+ "resolve": "^1.22.8",
+ "sucrase": "^3.35.0"
+ },
+ "bin": {
+ "tailwind": "lib/cli.js",
+ "tailwindcss": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tailwindcss/node_modules/postcss-import": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
+ "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.0.0",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.0"
+ }
+ },
+ "node_modules/temp-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz",
+ "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tempy": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz",
+ "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-stream": "^2.0.0",
+ "temp-dir": "^2.0.0",
+ "type-fest": "^0.16.0",
+ "unique-string": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/tempy/node_modules/type-fest": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz",
+ "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.37.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz",
+ "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser/node_modules/acorn": {
+ "version": "8.14.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "license": "MIT",
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/thread-stream": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz",
+ "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==",
+ "license": "MIT",
+ "dependencies": {
+ "real-require": "^0.2.0"
+ }
+ },
+ "node_modules/tiny-case": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
+ "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
+ "license": "MIT"
+ },
+ "node_modules/tiny-invariant": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tiny-warning": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
+ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==",
+ "license": "MIT"
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz",
+ "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toposort": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
+ "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==",
+ "license": "MIT"
+ },
+ "node_modules/tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/transform-ast": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/transform-ast/-/transform-ast-2.4.4.tgz",
+ "integrity": "sha512-AxjeZAcIOUO2lev2GDe3/xZ1Q0cVGjIMk5IsriTy8zbWlsEnjeB025AhkhBJHoy997mXpLd4R+kRbvnnQVuQHQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn-node": "^1.3.0",
+ "convert-source-map": "^1.5.1",
+ "dash-ast": "^1.0.0",
+ "is-buffer": "^2.0.0",
+ "magic-string": "^0.23.2",
+ "merge-source-map": "1.0.4",
+ "nanobench": "^2.1.1"
+ }
+ },
+ "node_modules/transform-ast/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/transform-ast/node_modules/magic-string": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.23.2.tgz",
+ "integrity": "sha512-oIUZaAxbcxYIp4AyLafV6OVKoB3YouZs0UTCJ8mOKBHNyJgGDaMJ4TgA+VylJh6fx7EQCC52XkbURxxG9IoJXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sourcemap-codec": "^1.4.1"
+ }
+ },
+ "node_modules/trim-lines": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+ "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/trough": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz",
+ "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/ts-interface-checker": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/tsc-template": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/tsc-template/-/tsc-template-0.2.3.tgz",
+ "integrity": "sha512-wuT2Rxl16IfqVAQv2EuJr56nZXACR8Nda2VFNSL+VL2K3XhBKr5cF6ccoW8CvOEyTv11BHuAmT2WWxfCEjJUBA==",
+ "license": "Apache-2.0",
+ "peerDependencies": {
+ "typescript": "5"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/type-fest": {
+ "version": "4.35.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz",
+ "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==",
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "for-each": "^0.3.3",
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.3.tgz",
+ "integrity": "sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13",
+ "reflect.getprototypeof": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
+ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0",
+ "reflect.getprototypeof": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.3",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unicode-canonical-property-names-ecmascript": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
+ "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-ecmascript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+ "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "unicode-canonical-property-names-ecmascript": "^2.0.0",
+ "unicode-property-aliases-ecmascript": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-value-ecmascript": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
+ "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-property-aliases-ecmascript": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
+ "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicorn-magic": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
+ "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/unified": {
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
+ "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "bail": "^2.0.0",
+ "devlop": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-plain-obj": "^4.0.0",
+ "trough": "^2.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unique-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
+ "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "crypto-random-string": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/unist-util-is": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz",
+ "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-position": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz",
+ "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-stringify-position": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
+ "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
+ "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit-parents": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz",
+ "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/upath": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4",
+ "yarn": "*"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
+ "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/use-composed-ref": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.4.0.tgz",
+ "integrity": "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-isomorphic-layout-effect": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.1.tgz",
+ "integrity": "sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-latest": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.3.0.tgz",
+ "integrity": "sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "use-isomorphic-layout-effect": "^1.1.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-sync-external-store": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz",
+ "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
+ "node_modules/validator": {
+ "version": "13.12.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz",
+ "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/valtio": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/valtio/-/valtio-2.1.5.tgz",
+ "integrity": "sha512-vsh1Ixu5mT0pJFZm+Jspvhga5GzHUTYv0/+Th203pLfh3/wbHwxhu/Z2OkZDXIgHfjnjBns7SN9HNcbDvPmaGw==",
+ "license": "MIT",
+ "dependencies": {
+ "proxy-compare": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=12.20.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18.0.0",
+ "react": ">=18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/valtio-reactive": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/valtio-reactive/-/valtio-reactive-0.1.2.tgz",
+ "integrity": "sha512-9Zv/tFiFWQWEBzfDikJgY9lkQ6CXf4T+Rsk08AKQMMZVmI5YvkAS7qFnRtwd1uVPNT/wsK+QcKiFHBvjCRohYQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "valtio": ">=2.0.0"
+ }
+ },
+ "node_modules/vfile": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
+ "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vfile-message": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz",
+ "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/vite": {
+ "version": "6.3.5",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
+ "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2",
+ "postcss": "^8.5.3",
+ "rollup": "^4.34.9",
+ "tinyglobby": "^0.2.13"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-checker": {
+ "version": "0.9.3",
+ "resolved": "https://registry.npmjs.org/vite-plugin-checker/-/vite-plugin-checker-0.9.3.tgz",
+ "integrity": "sha512-Tf7QBjeBtG7q11zG0lvoF38/2AVUzzhMNu+Wk+mcsJ00Rk/FpJ4rmUviVJpzWkagbU13cGXvKpt7CMiqtxVTbQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "chokidar": "^4.0.3",
+ "npm-run-path": "^6.0.0",
+ "picocolors": "^1.1.1",
+ "picomatch": "^4.0.2",
+ "strip-ansi": "^7.1.0",
+ "tiny-invariant": "^1.3.3",
+ "tinyglobby": "^0.2.13",
+ "vscode-uri": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "peerDependencies": {
+ "@biomejs/biome": ">=1.7",
+ "eslint": ">=7",
+ "meow": "^13.2.0",
+ "optionator": "^0.9.4",
+ "stylelint": ">=16",
+ "typescript": "*",
+ "vite": ">=2.0.0",
+ "vls": "*",
+ "vti": "*",
+ "vue-tsc": "~2.2.10"
+ },
+ "peerDependenciesMeta": {
+ "@biomejs/biome": {
+ "optional": true
+ },
+ "eslint": {
+ "optional": true
+ },
+ "meow": {
+ "optional": true
+ },
+ "optionator": {
+ "optional": true
+ },
+ "stylelint": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ },
+ "vls": {
+ "optional": true
+ },
+ "vti": {
+ "optional": true
+ },
+ "vue-tsc": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-checker/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",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/vite-plugin-checker/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",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.38.0.tgz",
+ "integrity": "sha512-ldomqc4/jDZu/xpYU+aRxo3V4mGCV9HeTgUBANI3oIQMOL+SsxB+S2lxMpkFp5UamSS3XuTMQVbsS24R4J4Qjg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.38.0.tgz",
+ "integrity": "sha512-VUsgcy4GhhT7rokwzYQP+aV9XnSLkkhlEJ0St8pbasuWO/vwphhZQxYEKUP3ayeCYLhk6gEtacRpYP/cj3GjyQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.38.0.tgz",
+ "integrity": "sha512-buA17AYXlW9Rn091sWMq1xGUvWQFOH4N1rqUxGJtEQzhChxWjldGCCup7r/wUnaI6Au8sKXpoh0xg58a7cgcpg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.38.0.tgz",
+ "integrity": "sha512-Mgcmc78AjunP1SKXl624vVBOF2bzwNWFPMP4fpOu05vS0amnLcX8gHIge7q/lDAHy3T2HeR0TqrriZDQS2Woeg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.38.0.tgz",
+ "integrity": "sha512-zzJACgjLbQTsscxWqvrEQAEh28hqhebpRz5q/uUd1T7VTwUNZ4VIXQt5hE7ncs0GrF+s7d3S4on4TiXUY8KoQA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.38.0.tgz",
+ "integrity": "sha512-hCY/KAeYMCyDpEE4pTETam0XZS4/5GXzlLgpi5f0IaPExw9kuB+PDTOTLuPtM10TlRG0U9OSmXJ+Wq9J39LvAg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.38.0.tgz",
+ "integrity": "sha512-mimPH43mHl4JdOTD7bUMFhBdrg6f9HzMTOEnzRmXbOZqjijCw8LA5z8uL6LCjxSa67H2xiLFvvO67PT05PRKGg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.38.0.tgz",
+ "integrity": "sha512-tPiJtiOoNuIH8XGG8sWoMMkAMm98PUwlriOFCCbZGc9WCax+GLeVRhmaxjJtz6WxrPKACgrwoZ5ia/uapq3ZVg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.38.0.tgz",
+ "integrity": "sha512-wZco59rIVuB0tjQS0CSHTTUcEde+pXQWugZVxWaQFdQQ1VYub/sTrNdY76D1MKdN2NB48JDuGABP6o6fqos8mA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.38.0.tgz",
+ "integrity": "sha512-fQgqwKmW0REM4LomQ+87PP8w8xvU9LZfeLBKybeli+0yHT7VKILINzFEuggvnV9M3x1Ed4gUBmGUzCo/ikmFbQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.38.0.tgz",
+ "integrity": "sha512-hz5oqQLXTB3SbXpfkKHKXLdIp02/w3M+ajp8p4yWOWwQRtHWiEOCKtc9U+YXahrwdk+3qHdFMDWR5k+4dIlddg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.38.0.tgz",
+ "integrity": "sha512-NXqygK/dTSibQ+0pzxsL3r4Xl8oPqVoWbZV9niqOnIHV/J92fe65pOir0xjkUZDRSPyFRvu+4YOpJF9BZHQImw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.38.0.tgz",
+ "integrity": "sha512-GEAIabR1uFyvf/jW/5jfu8gjM06/4kZ1W+j1nWTSSB3w6moZEBm7iBtzwQ3a1Pxos2F7Gz+58aVEnZHU295QTg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.38.0.tgz",
+ "integrity": "sha512-Mpp6+Z5VhB9VDk7RwZXoG2qMdERm3Jw07RNlXHE0bOnEeX+l7Fy4bg+NxfyN15ruuY3/7Vrbpm75J9QHFqj5+Q==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.38.0.tgz",
+ "integrity": "sha512-vPvNgFlZRAgO7rwncMeE0+8c4Hmc+qixnp00/Uv3ht2x7KYrJ6ERVd3/R0nUtlE6/hu7/HiiNHJ/rP6knRFt1w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.38.0.tgz",
+ "integrity": "sha512-q5Zv+goWvQUGCaL7fU8NuTw8aydIL/C9abAVGCzRReuj5h30TPx4LumBtAidrVOtXnlB+RZkBtExMsfqkMfb8g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.38.0.tgz",
+ "integrity": "sha512-u/Jbm1BU89Vftqyqbmxdq14nBaQjQX1HhmsdBWqSdGClNaKwhjsg5TpW+5Ibs1mb8Es9wJiMdl86BcmtUVXNZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.38.0.tgz",
+ "integrity": "sha512-mqu4PzTrlpNHHbu5qleGvXJoGgHpChBlrBx/mEhTPpnAL1ZAYFlvHD7rLK839LLKQzqEQMFJfGrrOHItN4ZQqA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/vite/node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.38.0.tgz",
+ "integrity": "sha512-jjqy3uWlecfB98Psxb5cD6Fny9Fupv9LrDSPTQZUROqjvZmcCqNu4UMl7qqhlUUGpwiAkotj6GYu4SZdcr/nLw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/vite/node_modules/@types/estree": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
+ "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vite/node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/vite/node_modules/postcss": {
+ "version": "8.5.3",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
+ "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.8",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/vite/node_modules/rollup": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.38.0.tgz",
+ "integrity": "sha512-5SsIRtJy9bf1ErAOiFMFzl64Ex9X5V7bnJ+WlFMb+zmP459OSWCEG7b0ERZ+PEU7xPt4OG3RHbrp1LJlXxYTrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.7"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.38.0",
+ "@rollup/rollup-android-arm64": "4.38.0",
+ "@rollup/rollup-darwin-arm64": "4.38.0",
+ "@rollup/rollup-darwin-x64": "4.38.0",
+ "@rollup/rollup-freebsd-arm64": "4.38.0",
+ "@rollup/rollup-freebsd-x64": "4.38.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.38.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.38.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.38.0",
+ "@rollup/rollup-linux-arm64-musl": "4.38.0",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.38.0",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.38.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.38.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.38.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.38.0",
+ "@rollup/rollup-linux-x64-gnu": "4.38.0",
+ "@rollup/rollup-linux-x64-musl": "4.38.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.38.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.38.0",
+ "@rollup/rollup-win32-x64-msvc": "4.38.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/vscode-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
+ "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.16",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.16.tgz",
+ "integrity": "sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/workbox-background-sync": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz",
+ "integrity": "sha512-PCSk3eK7Mxeuyatb22pcSx9dlgWNv3+M8PqPaYDokks8Y5/FX4soaOqj3yhAZr5k6Q5JWTOMYgaJBpbw11G9Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "idb": "^7.0.1",
+ "workbox-core": "7.3.0"
+ }
+ },
+ "node_modules/workbox-broadcast-update": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.3.0.tgz",
+ "integrity": "sha512-T9/F5VEdJVhwmrIAE+E/kq5at2OY6+OXXgOWQevnubal6sO92Gjo24v6dCVwQiclAF5NS3hlmsifRrpQzZCdUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.3.0"
+ }
+ },
+ "node_modules/workbox-build": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.3.0.tgz",
+ "integrity": "sha512-JGL6vZTPlxnlqZRhR/K/msqg3wKP+m0wfEUVosK7gsYzSgeIxvZLi1ViJJzVL7CEeI8r7rGFV973RiEqkP3lWQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@apideck/better-ajv-errors": "^0.3.1",
+ "@babel/core": "^7.24.4",
+ "@babel/preset-env": "^7.11.0",
+ "@babel/runtime": "^7.11.2",
+ "@rollup/plugin-babel": "^5.2.0",
+ "@rollup/plugin-node-resolve": "^15.2.3",
+ "@rollup/plugin-replace": "^2.4.1",
+ "@rollup/plugin-terser": "^0.4.3",
+ "@surma/rollup-plugin-off-main-thread": "^2.2.3",
+ "ajv": "^8.6.0",
+ "common-tags": "^1.8.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "fs-extra": "^9.0.1",
+ "glob": "^7.1.6",
+ "lodash": "^4.17.20",
+ "pretty-bytes": "^5.3.0",
+ "rollup": "^2.43.1",
+ "source-map": "^0.8.0-beta.0",
+ "stringify-object": "^3.3.0",
+ "strip-comments": "^2.0.1",
+ "tempy": "^0.6.0",
+ "upath": "^1.2.0",
+ "workbox-background-sync": "7.3.0",
+ "workbox-broadcast-update": "7.3.0",
+ "workbox-cacheable-response": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-expiration": "7.3.0",
+ "workbox-google-analytics": "7.3.0",
+ "workbox-navigation-preload": "7.3.0",
+ "workbox-precaching": "7.3.0",
+ "workbox-range-requests": "7.3.0",
+ "workbox-recipes": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0",
+ "workbox-streams": "7.3.0",
+ "workbox-sw": "7.3.0",
+ "workbox-window": "7.3.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/workbox-build/node_modules/@rollup/plugin-babel": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
+ "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.10.4",
+ "@rollup/pluginutils": "^3.1.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0",
+ "@types/babel__core": "^7.1.9",
+ "rollup": "^1.20.0||^2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/babel__core": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/workbox-build/node_modules/@rollup/plugin-replace": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz",
+ "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^3.1.0",
+ "magic-string": "^0.25.7"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0 || ^2.0.0"
+ }
+ },
+ "node_modules/workbox-build/node_modules/@rollup/pluginutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
+ "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "0.0.39",
+ "estree-walker": "^1.0.1",
+ "picomatch": "^2.2.2"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0"
+ }
+ },
+ "node_modules/workbox-build/node_modules/@types/estree": {
+ "version": "0.0.39",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
+ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-build/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/workbox-build/node_modules/estree-walker": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
+ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-build/node_modules/fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/workbox-build/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/workbox-build/node_modules/magic-string": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+ "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sourcemap-codec": "^1.4.8"
+ }
+ },
+ "node_modules/workbox-build/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/workbox-build/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/workbox-build/node_modules/rollup": {
+ "version": "2.79.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
+ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/workbox-build/node_modules/source-map": {
+ "version": "0.8.0-beta.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
+ "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "whatwg-url": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/workbox-cacheable-response": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.3.0.tgz",
+ "integrity": "sha512-eAFERIg6J2LuyELhLlmeRcJFa5e16Mj8kL2yCDbhWE+HUun9skRQrGIFVUagqWj4DMaaPSMWfAolM7XZZxNmxA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.3.0"
+ }
+ },
+ "node_modules/workbox-core": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.3.0.tgz",
+ "integrity": "sha512-Z+mYrErfh4t3zi7NVTvOuACB0A/jA3bgxUN3PwtAVHvfEsZxV9Iju580VEETug3zYJRc0Dmii/aixI/Uxj8fmw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-expiration": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.3.0.tgz",
+ "integrity": "sha512-lpnSSLp2BM+K6bgFCWc5bS1LR5pAwDWbcKt1iL87/eTSJRdLdAwGQznZE+1czLgn/X05YChsrEegTNxjM067vQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "idb": "^7.0.1",
+ "workbox-core": "7.3.0"
+ }
+ },
+ "node_modules/workbox-google-analytics": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.3.0.tgz",
+ "integrity": "sha512-ii/tSfFdhjLHZ2BrYgFNTrb/yk04pw2hasgbM70jpZfLk0vdJAXgaiMAWsoE+wfJDNWoZmBYY0hMVI0v5wWDbg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-background-sync": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0"
+ }
+ },
+ "node_modules/workbox-navigation-preload": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.3.0.tgz",
+ "integrity": "sha512-fTJzogmFaTv4bShZ6aA7Bfj4Cewaq5rp30qcxl2iYM45YD79rKIhvzNHiFj1P+u5ZZldroqhASXwwoyusnr2cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.3.0"
+ }
+ },
+ "node_modules/workbox-precaching": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.3.0.tgz",
+ "integrity": "sha512-ckp/3t0msgXclVAYaNndAGeAoWQUv7Rwc4fdhWL69CCAb2UHo3Cef0KIUctqfQj1p8h6aGyz3w8Cy3Ihq9OmIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0"
+ }
+ },
+ "node_modules/workbox-range-requests": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.3.0.tgz",
+ "integrity": "sha512-EyFmM1KpDzzAouNF3+EWa15yDEenwxoeXu9bgxOEYnFfCxns7eAxA9WSSaVd8kujFFt3eIbShNqa4hLQNFvmVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.3.0"
+ }
+ },
+ "node_modules/workbox-recipes": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.3.0.tgz",
+ "integrity": "sha512-BJro/MpuW35I/zjZQBcoxsctgeB+kyb2JAP5EB3EYzePg8wDGoQuUdyYQS+CheTb+GhqJeWmVs3QxLI8EBP1sg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-cacheable-response": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-expiration": "7.3.0",
+ "workbox-precaching": "7.3.0",
+ "workbox-routing": "7.3.0",
+ "workbox-strategies": "7.3.0"
+ }
+ },
+ "node_modules/workbox-routing": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.3.0.tgz",
+ "integrity": "sha512-ZUlysUVn5ZUzMOmQN3bqu+gK98vNfgX/gSTZ127izJg/pMMy4LryAthnYtjuqcjkN4HEAx1mdgxNiKJMZQM76A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.3.0"
+ }
+ },
+ "node_modules/workbox-strategies": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.3.0.tgz",
+ "integrity": "sha512-tmZydug+qzDFATwX7QiEL5Hdf7FrkhjaF9db1CbB39sDmEZJg3l9ayDvPxy8Y18C3Y66Nrr9kkN1f/RlkDgllg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.3.0"
+ }
+ },
+ "node_modules/workbox-streams": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.3.0.tgz",
+ "integrity": "sha512-SZnXucyg8x2Y61VGtDjKPO5EgPUG5NDn/v86WYHX+9ZqvAsGOytP0Jxp1bl663YUuMoXSAtsGLL+byHzEuMRpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "workbox-core": "7.3.0",
+ "workbox-routing": "7.3.0"
+ }
+ },
+ "node_modules/workbox-sw": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.3.0.tgz",
+ "integrity": "sha512-aCUyoAZU9IZtH05mn0ACUpyHzPs0lMeJimAYkQkBsOWiqaJLgusfDCR+yllkPkFRxWpZKF8vSvgHYeG7LwhlmA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/workbox-window": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.3.0.tgz",
+ "integrity": "sha512-qW8PDy16OV1UBaUNGlTVcepzrlzyzNW/ZJvFQQs2j2TzGsg6IKjcpZC1RSquqQnTOafl5pCj5bGfAHlCjOOjdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/trusted-types": "^2.0.2",
+ "workbox-core": "7.3.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "license": "ISC"
+ },
+ "node_modules/ws": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
+ "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
+ "license": "MIT",
+ "dependencies": {
+ "async-limiter": "~1.0.0"
+ }
+ },
+ "node_modules/xmlhttprequest": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
+ "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yaml": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz",
+ "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==",
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yup": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/yup/-/yup-1.6.1.tgz",
+ "integrity": "sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==",
+ "license": "MIT",
+ "dependencies": {
+ "property-expr": "^2.0.5",
+ "tiny-case": "^1.0.3",
+ "toposort": "^2.0.2",
+ "type-fest": "^2.19.0"
+ }
+ },
+ "node_modules/yup/node_modules/type-fest": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+ "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zwitch": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ }
+ }
+}
diff --git a/app/package.json b/app/package.json
new file mode 100644
index 0000000..6bf7f7c
--- /dev/null
+++ b/app/package.json
@@ -0,0 +1,211 @@
+{
+ "name": "gameyfin",
+ "version": "2.0.0-ALPHA",
+ "type": "module",
+ "dependencies": {
+ "@heroui/react": "2.7.9",
+ "@material-tailwind/react": "^2.1.10",
+ "@phosphor-icons/react": "^2.1.7",
+ "@polymer/polymer": "3.5.2",
+ "@react-stately/data": "^3.12.2",
+ "@react-types/shared": "^3.28.0",
+ "@vaadin/bundles": "24.8.0-rc1",
+ "@vaadin/common-frontend": "0.0.19",
+ "@vaadin/hilla-file-router": "24.8.0-rc1",
+ "@vaadin/hilla-frontend": "24.8.0-rc1",
+ "@vaadin/hilla-lit-form": "24.8.0-rc1",
+ "@vaadin/hilla-react-auth": "24.8.0-rc1",
+ "@vaadin/hilla-react-crud": "24.8.0-rc1",
+ "@vaadin/hilla-react-form": "24.8.0-rc1",
+ "@vaadin/hilla-react-i18n": "24.8.0-rc1",
+ "@vaadin/hilla-react-signals": "24.8.0-rc1",
+ "@vaadin/polymer-legacy-adapter": "24.8.0-rc1",
+ "@vaadin/react-components": "24.8.0-rc1",
+ "@vaadin/vaadin-development-mode-detector": "2.0.7",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "@vaadin/vaadin-usage-statistics": "2.1.3",
+ "classnames": "^2.5.1",
+ "construct-style-sheets-polyfill": "3.1.0",
+ "cron-validator": "^1.3.1",
+ "date-fns": "2.29.3",
+ "formik": "^2.4.6",
+ "framer-motion": "^12.5.0",
+ "fzf": "^0.5.2",
+ "http-status-codes": "^2.3.0",
+ "lit": "3.3.0",
+ "moment": "^2.30.1",
+ "moment-timezone": "^0.5.47",
+ "next-themes": "^0.4.6",
+ "rand-seed": "^2.1.7",
+ "react": "18.3.1",
+ "react-accessible-treeview": "^2.11.1",
+ "react-aria-components": "^1.7.1",
+ "react-confetti-boom": "^1.0.0",
+ "react-dom": "18.3.1",
+ "react-markdown": "^10.1.0",
+ "react-player": "^2.16.0",
+ "react-router": "7.6.1",
+ "remark-breaks": "^4.0.0",
+ "swiper": "^11.2.6",
+ "valtio": "^2.1.5",
+ "valtio-reactive": "^0.1.2",
+ "yup": "^1.6.1"
+ },
+ "devDependencies": {
+ "@babel/preset-react": "7.27.1",
+ "@lit-labs/react": "^2.1.3",
+ "@preact/signals-react-transform": "0.5.1",
+ "@rollup/plugin-replace": "6.0.2",
+ "@rollup/pluginutils": "5.1.4",
+ "@types/node": "^22.4.0",
+ "@types/react": "18.3.23",
+ "@types/react-dom": "18.3.7",
+ "@vaadin/hilla-generator-cli": "24.8.0-rc1",
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-backbone": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-barrel": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-client": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-model": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-push": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-signals": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-subtypes": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-transfertypes": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "@vitejs/plugin-react": "4.5.0",
+ "@vitejs/plugin-react-swc": "^3.7.0",
+ "async": "3.2.6",
+ "autoprefixer": "^10.4.20",
+ "glob": "11.0.2",
+ "magic-string": "0.30.17",
+ "postcss": "^8.4.41",
+ "postcss-import": "^16.1.0",
+ "rollup-plugin-brotli": "3.1.0",
+ "rollup-plugin-visualizer": "5.14.0",
+ "strip-css-comments": "5.0.0",
+ "tailwindcss": "^3.4.13",
+ "transform-ast": "2.4.4",
+ "typescript": "5.8.3",
+ "vite": "6.3.5",
+ "vite-plugin-checker": "0.9.3",
+ "workbox-build": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-precaching": "7.3.0"
+ },
+ "overrides": {
+ "@react-aria/utils": "^3.28.1",
+ "classnames": "$classnames",
+ "react": "$react",
+ "react-dom": "$react-dom",
+ "@vaadin/bundles": "$@vaadin/bundles",
+ "@vaadin/common-frontend": "$@vaadin/common-frontend",
+ "construct-style-sheets-polyfill": "$construct-style-sheets-polyfill",
+ "lit": "$lit",
+ "@polymer/polymer": "$@polymer/polymer",
+ "@phosphor-icons/react": "$@phosphor-icons/react",
+ "formik": "$formik",
+ "yup": "$yup",
+ "next-themes": "$next-themes",
+ "@heroui/react": "$@heroui/react",
+ "framer-motion": "$framer-motion",
+ "@material-tailwind/react": "$@material-tailwind/react",
+ "http-status-codes": "$http-status-codes",
+ "@vaadin/polymer-legacy-adapter": "$@vaadin/polymer-legacy-adapter",
+ "@vaadin/vaadin-development-mode-detector": "$@vaadin/vaadin-development-mode-detector",
+ "@vaadin/vaadin-usage-statistics": "$@vaadin/vaadin-usage-statistics",
+ "@vaadin/react-components": "$@vaadin/react-components",
+ "@vaadin/hilla-frontend": "$@vaadin/hilla-frontend",
+ "@vaadin/hilla-react-auth": "$@vaadin/hilla-react-auth",
+ "@vaadin/hilla-react-crud": "$@vaadin/hilla-react-crud",
+ "@vaadin/hilla-file-router": "$@vaadin/hilla-file-router",
+ "@vaadin/hilla-react-i18n": "$@vaadin/hilla-react-i18n",
+ "@vaadin/hilla-lit-form": "$@vaadin/hilla-lit-form",
+ "@vaadin/hilla-react-form": "$@vaadin/hilla-react-form",
+ "@vaadin/hilla-react-signals": "$@vaadin/hilla-react-signals",
+ "cron-validator": "$cron-validator",
+ "moment": "$moment",
+ "moment-timezone": "$moment-timezone",
+ "react-confetti-boom": "$react-confetti-boom",
+ "date-fns": "$date-fns",
+ "@vaadin/vaadin-themable-mixin": "$@vaadin/vaadin-themable-mixin",
+ "@vaadin/vaadin-lumo-styles": "$@vaadin/vaadin-lumo-styles",
+ "@vaadin/vaadin-material-styles": "$@vaadin/vaadin-material-styles",
+ "@react-types/shared": "$@react-types/shared",
+ "@react-stately/data": "$@react-stately/data",
+ "react-aria-components": "$react-aria-components",
+ "react-accessible-treeview": "$react-accessible-treeview",
+ "rand-seed": "$rand-seed",
+ "react-router": "$react-router",
+ "swiper": "$swiper",
+ "react-player": "$react-player",
+ "react-markdown": "$react-markdown",
+ "remark-breaks": "$remark-breaks",
+ "valtio": "$valtio",
+ "valtio-reactive": "$valtio-reactive",
+ "fzf": "$fzf"
+ },
+ "vaadin": {
+ "disableUsageStatistics": true,
+ "dependencies": {
+ "@polymer/polymer": "3.5.2",
+ "@vaadin/bundles": "24.8.0-rc1",
+ "@vaadin/common-frontend": "0.0.19",
+ "@vaadin/hilla-file-router": "24.8.0-rc1",
+ "@vaadin/hilla-frontend": "24.8.0-rc1",
+ "@vaadin/hilla-lit-form": "24.8.0-rc1",
+ "@vaadin/hilla-react-auth": "24.8.0-rc1",
+ "@vaadin/hilla-react-crud": "24.8.0-rc1",
+ "@vaadin/hilla-react-form": "24.8.0-rc1",
+ "@vaadin/hilla-react-i18n": "24.8.0-rc1",
+ "@vaadin/hilla-react-signals": "24.8.0-rc1",
+ "@vaadin/polymer-legacy-adapter": "24.8.0-rc1",
+ "@vaadin/react-components": "24.8.0-rc1",
+ "@vaadin/vaadin-development-mode-detector": "2.0.7",
+ "@vaadin/vaadin-lumo-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-material-styles": "24.8.0-rc1",
+ "@vaadin/vaadin-themable-mixin": "24.8.0-rc1",
+ "@vaadin/vaadin-usage-statistics": "2.1.3",
+ "construct-style-sheets-polyfill": "3.1.0",
+ "date-fns": "2.29.3",
+ "lit": "3.3.0",
+ "react": "18.3.1",
+ "react-dom": "18.3.1",
+ "react-router": "7.6.1"
+ },
+ "devDependencies": {
+ "@babel/preset-react": "7.27.1",
+ "@preact/signals-react-transform": "0.5.1",
+ "@rollup/plugin-replace": "6.0.2",
+ "@rollup/pluginutils": "5.1.4",
+ "@types/react": "18.3.23",
+ "@types/react-dom": "18.3.7",
+ "@vaadin/hilla-generator-cli": "24.8.0-rc1",
+ "@vaadin/hilla-generator-core": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-backbone": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-barrel": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-client": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-model": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-push": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-signals": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-subtypes": "24.8.0-rc1",
+ "@vaadin/hilla-generator-plugin-transfertypes": "24.8.0-rc1",
+ "@vaadin/hilla-generator-utils": "24.8.0-rc1",
+ "@vitejs/plugin-react": "4.5.0",
+ "async": "3.2.6",
+ "glob": "11.0.2",
+ "magic-string": "0.30.17",
+ "rollup-plugin-brotli": "3.1.0",
+ "rollup-plugin-visualizer": "5.14.0",
+ "strip-css-comments": "5.0.0",
+ "transform-ast": "2.4.4",
+ "typescript": "5.8.3",
+ "vite": "6.3.5",
+ "vite-plugin-checker": "0.9.3",
+ "workbox-build": "7.3.0",
+ "workbox-core": "7.3.0",
+ "workbox-precaching": "7.3.0"
+ },
+ "hash": "b2ffd3ce9b28bc9b88c070ed3a53ff5a6db02bd4f3127932d7c0be123cf7be25"
+ }
+}
\ No newline at end of file
diff --git a/app/postcss.config.js b/app/postcss.config.js
new file mode 100644
index 0000000..851f619
--- /dev/null
+++ b/app/postcss.config.js
@@ -0,0 +1,6 @@
+export default {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
\ No newline at end of file
diff --git a/app/src/main/bundles/prod.bundle b/app/src/main/bundles/prod.bundle
new file mode 100644
index 0000000..25fcf28
Binary files /dev/null and b/app/src/main/bundles/prod.bundle differ
diff --git a/app/src/main/frontend/App.tsx b/app/src/main/frontend/App.tsx
new file mode 100644
index 0000000..f145d6d
--- /dev/null
+++ b/app/src/main/frontend/App.tsx
@@ -0,0 +1,64 @@
+import {Outlet, useHref, useNavigate} from 'react-router';
+import "./main.css";
+import "Frontend/util/custom-validators";
+import {HeroUIProvider} from "@heroui/react";
+import {ThemeProvider as NextThemesProvider} from "next-themes";
+import {themeNames} from "Frontend/theming/themes";
+import {AuthProvider, useAuth} from "Frontend/util/auth";
+import {IconContext, X} from "@phosphor-icons/react";
+import client from "Frontend/generated/connect-client.default";
+import {ErrorHandlingMiddleware} from "Frontend/util/middleware";
+import {initializeLibraryState} from "Frontend/state/LibraryState";
+import {initializeGameState} from "Frontend/state/GameState";
+import {initializeScanState} from "Frontend/state/ScanState";
+import {ToastProvider} from "@heroui/toast";
+import {initializePluginState} from "Frontend/state/PluginState";
+import {isAdmin} from "Frontend/util/utils";
+
+export default function App() {
+ client.middlewares = [ErrorHandlingMiddleware];
+
+ const navigate = useNavigate();
+
+ return (
+
+
+
+
+
+
+
+ );
+}
+
+function ViewWithAuth() {
+ const auth = useAuth();
+
+ initializeLibraryState();
+ initializeGameState();
+
+ if (isAdmin(auth)) {
+ initializeScanState();
+ initializePluginState();
+ }
+
+ return <>
+
+
+ ,
+ classNames: {
+ closeButton: "opacity-100 absolute right-4 top-1/2 -translate-y-1/2",
+ progressTrack: "h-1",
+ }
+ }}
+ toastOffset={64}
+ />
+
+ >;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/ProfileMenu.tsx b/app/src/main/frontend/components/ProfileMenu.tsx
new file mode 100644
index 0000000..cc2823d
--- /dev/null
+++ b/app/src/main/frontend/components/ProfileMenu.tsx
@@ -0,0 +1,85 @@
+import {useAuth} from "Frontend/util/auth";
+import {GearFine, Question, SignOut, User} from "@phosphor-icons/react";
+import {Dropdown, DropdownItem, DropdownMenu, DropdownTrigger} from "@heroui/react";
+import {useNavigate} from "react-router";
+import {ConfigEndpoint} from "Frontend/generated/endpoints";
+import Avatar from "Frontend/components/general/Avatar";
+import {CollectionElement} from "@react-types/shared";
+import {isAdmin} from "Frontend/util/utils";
+
+export default function ProfileMenu() {
+ const auth = useAuth();
+ const navigate = useNavigate();
+
+ async function logout() {
+ if (auth.state.user?.managedBySso) {
+ window.location.href = (await ConfigEndpoint.getLogoutUrl()) || "/";
+ } else {
+ await auth.logout();
+ }
+ }
+
+ const profileMenuItems = [
+ {
+ label: "My Profile",
+ icon: ,
+ onClick: () => navigate("/settings/profile")
+ },
+ {
+ label: "Administration",
+ icon: ,
+ onClick: () => navigate("/administration/libraries"),
+ showIf: isAdmin(auth)
+ },
+ {
+ label: "Help",
+ icon: ,
+ onClick: () => window.open("https://gameyfin.org", "_blank")
+ },
+ {
+ label: "Sign Out",
+ icon: ,
+ onClick: logout,
+ color: "primary"
+ },
+ ];
+
+ // @ts-ignore
+ return (
+
+
+ {/* div is necessary so dropdown menu will appear in the correct place */}
+
+
+
+
+ Signed in as {auth.state.user?.username}
+
+ {profileMenuItems.filter(item => item.showIf !== false).map(({label, icon, onClick, color}) => {
+ return (
+ {icon}}
+ /* @ts-ignore */
+ color={color ? color : ""}
+ className={`text-${color} hover:bg-primary/20`}
+ textValue={label}
+ >
+ {label}
+
+ );
+ }) as unknown as CollectionElement}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/ConfigFormField.tsx b/app/src/main/frontend/components/administration/ConfigFormField.tsx
new file mode 100644
index 0000000..9efa46f
--- /dev/null
+++ b/app/src/main/frontend/components/administration/ConfigFormField.tsx
@@ -0,0 +1,48 @@
+import ConfigEntryDto from "Frontend/generated/org/gameyfin/app/config/dto/ConfigEntryDto";
+import React from "react";
+import Input from "Frontend/components/general/input/Input";
+import CheckboxInput from "Frontend/components/general/input/CheckboxInput";
+import SelectInput from "Frontend/components/general/input/SelectInput";
+import ArrayInput from "Frontend/components/general/input/ArrayInput";
+
+export default function ConfigFormField({configElement, ...props}: any) {
+ function inputElement(configElement: ConfigEntryDto) {
+
+ if (configElement.allowedValues != null && configElement.allowedValues.length > 0) {
+ return (
+
+ );
+ }
+
+ switch (configElement.type.toLowerCase()) {
+ case "boolean":
+ return (
+
+ );
+ case "string":
+ return (
+
+ );
+ case "float":
+ return (
+
+ );
+ case "int":
+ return (
+
+ );
+ case "array":
+ return (
+
+ );
+ default:
+ return Unsupported type: {configElement.type} for key {configElement.key} ;
+ }
+ }
+
+ return inputElement(configElement!);
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/LibraryManagement.tsx b/app/src/main/frontend/components/administration/LibraryManagement.tsx
new file mode 100644
index 0000000..11fa2e8
--- /dev/null
+++ b/app/src/main/frontend/components/administration/LibraryManagement.tsx
@@ -0,0 +1,102 @@
+import React from "react";
+import ConfigFormField from "Frontend/components/administration/ConfigFormField";
+import withConfigPage from "Frontend/components/administration/withConfigPage";
+import Section from "Frontend/components/general/Section";
+import * as Yup from 'yup';
+import {addToast, Button, Divider, Tooltip, useDisclosure} from "@heroui/react";
+import {Plus} from "@phosphor-icons/react";
+import {LibraryEndpoint} from "Frontend/generated/endpoints";
+import {LibraryOverviewCard} from "Frontend/components/general/cards/LibraryOverviewCard";
+import LibraryCreationModal from "Frontend/components/general/modals/LibraryCreationModal";
+import LibraryUpdateDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryUpdateDto";
+import LibraryDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryDto";
+import {useSnapshot} from "valtio/react";
+import {libraryState} from "Frontend/state/LibraryState";
+
+function LibraryManagementLayout({getConfig, formik}: any) {
+ const libraryCreationModal = useDisclosure();
+ const state = useSnapshot(libraryState);
+
+ async function updateLibrary(library: LibraryUpdateDto) {
+ await LibraryEndpoint.updateLibrary(library);
+ addToast({
+ title: "Library updated",
+ description: `Library ${library.name} has been updated.`,
+ color: "success"
+ })
+ }
+
+ async function removeLibrary(library: LibraryDto) {
+ await LibraryEndpoint.deleteLibrary(library.id);
+ addToast({
+ title: "Library removed",
+ description: `Library ${library.name} has been removed.`,
+ color: "success"
+ })
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {state.sorted.length > 0 ?
+ // Aspect ratio of cover = 12/17 -> 5 covers = 60/17 -> 353px * 100px
+
+ {state.sorted.map((library) =>
+ // @ts-ignore
+
+ )}
+
:
+
No libraries found
+ }
+
+
+
+ );
+}
+
+const validationSchema = Yup.object({
+ library: Yup.object({
+ metadata: Yup.object({
+ update: Yup.object({
+ // @ts-ignore
+ schedule: Yup.string().cron()
+ })
+ })
+ })
+});
+
+export const LibraryManagement = withConfigPage(LibraryManagementLayout, "Library Management", validationSchema);
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/LogManagement.tsx b/app/src/main/frontend/components/administration/LogManagement.tsx
new file mode 100644
index 0000000..f7dedc2
--- /dev/null
+++ b/app/src/main/frontend/components/administration/LogManagement.tsx
@@ -0,0 +1,97 @@
+import React, {useEffect, useRef, useState} from "react";
+import {LogEndpoint} from "Frontend/generated/endpoints";
+import withConfigPage from "Frontend/components/administration/withConfigPage";
+import * as Yup from 'yup';
+import ConfigFormField from "Frontend/components/administration/ConfigFormField";
+import {addToast, Button, Code, Divider, Tooltip} from "@heroui/react";
+import {ArrowUDownLeft, SortAscending} from "@phosphor-icons/react";
+
+function LogManagementLayout({getConfig, formik}: any) {
+ const [logEntries, setLogEntries] = useState([]);
+ const [autoScroll, setAutoScroll] = useState(true);
+ const [softWrap, setSoftWrap] = useState(false);
+ const logEndRef = useRef(null);
+
+ useEffect(() => {
+ const sub = LogEndpoint.getApplicationLogs().onNext((newEntry: string | undefined) =>
+ setLogEntries((currentEntries) => [...currentEntries, newEntry as string])
+ );
+
+ return () => sub.cancel();
+ }, []);
+
+ useEffect(() => {
+ if (formik.isSubmitting == false && formik.submitCount > 0) {
+ LogEndpoint.reloadLogConfig()
+ .catch(() => addToast({
+ title: "Error",
+ description: "Failed to apply log configuration",
+ color: "danger"
+ }));
+ }
+ }, [formik.isSubmitting]);
+
+ useEffect(() => {
+ if (autoScroll) {
+ scrollToBottom();
+ }
+ }, [logEntries, autoScroll, softWrap]);
+
+ function scrollToBottom() {
+ logEndRef.current?.scrollIntoView();
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
Application logs
+
+
+ setSoftWrap(!softWrap)}
+ variant={softWrap ? "solid" : "ghost"}
+ >
+
+
+
+
+ setAutoScroll(!autoScroll)}
+ variant={autoScroll ? "solid" : "ghost"}
+ >
+
+
+
+
+
+
+
+
+ {logEntries.map((entry, index) => {entry}
)}
+
+
+
+ );
+}
+
+const validationSchema = Yup.object({
+ logs: Yup.object({
+ folder: Yup.string().required("Required"),
+ "max-history-days": Yup.number().required("Required"),
+ level: Yup.object({
+ gameyfin: Yup.string().required("Required"),
+ root: Yup.string().required("Required")
+ })
+ })
+});
+
+export const LogManagement = withConfigPage(LogManagementLayout, "Logging", validationSchema);
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/MessageManagement.tsx b/app/src/main/frontend/components/administration/MessageManagement.tsx
new file mode 100644
index 0000000..8ad552b
--- /dev/null
+++ b/app/src/main/frontend/components/administration/MessageManagement.tsx
@@ -0,0 +1,129 @@
+import React, {useEffect, useState} from "react";
+import withConfigPage from "Frontend/components/administration/withConfigPage";
+import ConfigFormField from "Frontend/components/administration/ConfigFormField";
+import Section from "Frontend/components/general/Section";
+import {addToast, Button, Card, Tooltip, useDisclosure} from "@heroui/react";
+import {MessageEndpoint, MessageTemplateEndpoint} from "Frontend/generated/endpoints";
+import {PaperPlaneRight, Pencil} from "@phosphor-icons/react";
+import MessageTemplateDto from "Frontend/generated/org/gameyfin/app/messages/templates/MessageTemplateDto";
+import SendTestNotificationModal from "Frontend/components/administration/messages/SendTestNotificationModal";
+import EditTemplateModal from "Frontend/components/administration/messages/EditTemplateModel";
+
+function MessageManagementLayout({getConfig, formik}: any) {
+
+ const editorModal = useDisclosure();
+ const testNotificationModal = useDisclosure();
+ const [availableTemplates, setAvailableTemplates] = useState([]);
+ const [selectedTemplate, setSelectedTemplate] = useState();
+
+ useEffect(() => {
+ MessageTemplateEndpoint.getAll().then((response: any) => {
+ setAvailableTemplates(response as MessageTemplateDto[]);
+ });
+ }, []);
+
+ async function verifyCredentials(provider: string) {
+ const credentials: Record = {
+ host: formik.values.messages.providers.email.host,
+ port: formik.values.messages.providers.email.port,
+ username: formik.values.messages.providers.email.username,
+ password: formik.values.messages.providers.email.password
+ }
+
+ const areCredentialsValid = await MessageEndpoint.verifyCredentials(provider, credentials);
+
+ if (areCredentialsValid) {
+ addToast({
+ title: "Credentials are valid",
+ color: "success"
+ });
+ } else {
+ addToast({
+ title: "Credentials are invalid",
+ color: "warning"
+ });
+ }
+ }
+
+ async function openEditor(template: MessageTemplateDto) {
+ setSelectedTemplate(template);
+ editorModal.onOpen();
+ }
+
+ function openTestNotification(template: MessageTemplateDto) {
+ setSelectedTemplate(template);
+ testNotificationModal.onOpen();
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ verifyCredentials("email")}
+ isDisabled={!(
+ formik.values.messages.providers.email.enabled &&
+ formik.values.messages.providers.email.host &&
+ formik.values.messages.providers.email.port &&
+ formik.values.messages.providers.email.username)}>Test
+
+
+
+
+ {availableTemplates.map((template: MessageTemplateDto) =>
+
+
+ openEditor(template)}
+ >
+
+
+
+
+ openTestNotification(template)}
+ isDisabled={!formik.values.messages.providers.email.enabled}
+ >
+
+
+
+ {template.description}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export const MessageManagement = withConfigPage(MessageManagementLayout, "Messages", "messages");
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/PluginManagement.tsx b/app/src/main/frontend/components/administration/PluginManagement.tsx
new file mode 100644
index 0000000..33f54b3
--- /dev/null
+++ b/app/src/main/frontend/components/administration/PluginManagement.tsx
@@ -0,0 +1,27 @@
+import React from "react";
+import {PluginManagementSection} from "Frontend/components/general/plugin/PluginManagementSection";
+import {pluginState} from "Frontend/state/PluginState";
+import {useSnapshot} from "valtio/react";
+
+export default function PluginManagement() {
+
+ // Defined manually for now to control the layout (order of categories)
+ const pluginTypes = ["GameMetadataProvider", "DownloadProvider"];
+
+ const state = useSnapshot(pluginState);
+
+ return state.isLoaded && (
+
+
+
Plugins
+
+
+
+ {pluginTypes.map(type =>
+ // @ts-ignore
+
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/ProfileManagement.tsx b/app/src/main/frontend/components/administration/ProfileManagement.tsx
new file mode 100644
index 0000000..c965cc1
--- /dev/null
+++ b/app/src/main/frontend/components/administration/ProfileManagement.tsx
@@ -0,0 +1,173 @@
+import Section from "Frontend/components/general/Section";
+import Input from "Frontend/components/general/input/Input";
+import {addToast, Button, Input as NextUiInput, Tooltip} from "@heroui/react";
+import {Form, Formik} from "formik";
+import {ArrowCounterClockwise, Check, Info, Trash} from "@phosphor-icons/react";
+import React, {useEffect, useState} from "react";
+import {useAuth} from "Frontend/util/auth";
+import * as Yup from "yup";
+import UserUpdateDto from "Frontend/generated/org/gameyfin/app/users/dto/UserUpdateDto";
+import {EmailConfirmationEndpoint, MessageEndpoint, UserEndpoint} from "Frontend/generated/endpoints";
+import {SmallInfoField} from "Frontend/components/general/SmallInfoField";
+import {removeAvatar, uploadAvatar} from "Frontend/endpoints/AvatarEndpoint";
+import Avatar from "Frontend/components/general/Avatar";
+
+export default function ProfileManagement() {
+ const auth = useAuth();
+ const [avatar, setAvatar] = useState();
+ const [configSaved, setConfigSaved] = useState(false);
+ const [messagesEnabled, setMessagesEnabled] = useState(false);
+
+ useEffect(() => {
+ MessageEndpoint.isEnabled().then(setMessagesEnabled);
+ }, []);
+
+ useEffect(() => {
+ if (configSaved) {
+ setTimeout(() => setConfigSaved(false), 2000);
+ }
+ }, [configSaved])
+
+
+ function onFileSelected(event: any) {
+ setAvatar(event.target.files[0]);
+ }
+
+ async function handleSubmit(values: any) {
+ const userUpdate: UserUpdateDto = {
+ username: values.username,
+ email: values.email
+ }
+
+ if (values.newPassword.length > 0) {
+ userUpdate.password = values.newPassword;
+ }
+
+ await UserEndpoint.updateUser(userUpdate);
+ setConfigSaved(true);
+
+ if (values.newPassword.length > 0) {
+ addToast({
+ title: "Password changed",
+ description: "Please log in again",
+ color: "success"
+ });
+ setTimeout(() => {
+ auth.logout();
+ }, 500);
+ }
+ }
+
+ return (
+ <>
+
+ {(formik: { values: any; isSubmitting: any; dirty: boolean; }) => (
+
+ )}
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/SsoManagement.tsx b/app/src/main/frontend/components/administration/SsoManagement.tsx
new file mode 100644
index 0000000..78568f2
--- /dev/null
+++ b/app/src/main/frontend/components/administration/SsoManagement.tsx
@@ -0,0 +1,124 @@
+import React, {useEffect} from "react";
+import withConfigPage from "Frontend/components/administration/withConfigPage";
+import * as Yup from 'yup';
+import ConfigFormField from "Frontend/components/administration/ConfigFormField";
+import Section from "Frontend/components/general/Section";
+import {addToast, Button} from "@heroui/react";
+import {MagicWand} from "@phosphor-icons/react";
+
+function SsoManagementLayout({getConfig, formik, setSaveMessage}: any) {
+
+ useEffect(() => {
+ if (formik.dirty) {
+ setSaveMessage("Gameyfin must be restarted for the changes to take effect");
+ } else {
+ setSaveMessage(null);
+ }
+ }, [formik.dirty]);
+
+ function isAutoPopulateDisabled() {
+ return !formik.values.sso.oidc.enabled || !formik.values.sso.oidc["issuer-url"];
+ }
+
+ async function autoPopulate() {
+ let issuerUrl: string = formik.values.sso.oidc["issuer-url"];
+ if (issuerUrl.endsWith("/")) issuerUrl = issuerUrl.slice(0, -1);
+
+ try {
+ const response = await fetch(issuerUrl + "/.well-known/openid-configuration");
+ const data = await response.json();
+
+ formik.setFieldValue("sso.oidc.authorize-url", data.authorization_endpoint);
+ formik.setFieldValue("sso.oidc.token-url", data.token_endpoint);
+ formik.setFieldValue("sso.oidc.userinfo-url", data.userinfo_endpoint);
+ formik.setFieldValue("sso.oidc.logout-url", data.end_session_endpoint);
+ formik.setFieldValue("sso.oidc.jwks-url", data.jwks_uri);
+ } catch (e) {
+ addToast({
+ title: "Failed to auto-populate SSO configuration",
+ color: "warning"
+ });
+ }
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto-populate
+
+
+
+
+
+
+
+
+
+ );
+}
+
+const validationSchema = Yup.object({
+ sso: Yup.object({
+ oidc: Yup.object({
+ enabled: Yup.boolean(),
+ "auto-register-new-users": Yup.boolean().required(),
+ "match-existing-users-by": Yup.string().required(),
+ "client-id": Yup.string().when("enabled", ([enabled], schema) =>
+ enabled ? schema.required("Client ID is required") : schema
+ ),
+ "client-secret": Yup.string().when("enabled", ([enabled], schema) =>
+ enabled ? schema.required("Client Secret is required") : schema
+ ),
+ "issuer-url": Yup.string().when("enabled", ([enabled], schema) =>
+ enabled ? schema.required("Issuer URL is required") : schema
+ ),
+ "authorize-url": Yup.string().when("enabled", ([enabled], schema) =>
+ enabled ? schema.required("Authorize URL is required") : schema
+ ),
+ "token-url": Yup.string().when("enabled", ([enabled], schema) =>
+ enabled ? schema.required("Token URL is required") : schema
+ ),
+ "userinfo-url": Yup.string().when("enabled", ([enabled], schema) =>
+ enabled ? schema.required("Userinfo URL is required") : schema
+ ),
+ "logout-url": Yup.string().when("enabled", ([enabled], schema) =>
+ enabled ? schema.required("Logout URL is required") : schema
+ ),
+ "jwks-url": Yup.string().when("enabled", ([enabled], schema) =>
+ enabled ? schema.required("JWKS URL is required") : schema
+ )
+ })
+ })
+});
+
+export const SsoManagement = withConfigPage(SsoManagementLayout, "Single Sign-On", validationSchema);
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/SystemManagement.tsx b/app/src/main/frontend/components/administration/SystemManagement.tsx
new file mode 100644
index 0000000..40da042
--- /dev/null
+++ b/app/src/main/frontend/components/administration/SystemManagement.tsx
@@ -0,0 +1,29 @@
+import React, {useEffect} from "react";
+import {SystemEndpoint} from "Frontend/generated/endpoints";
+import withConfigPage from "Frontend/components/administration/withConfigPage";
+import {Button} from "@heroui/react";
+import ConfigFormField from "Frontend/components/administration/ConfigFormField";
+import Section from "Frontend/components/general/Section";
+
+function SystemManagementLayout({getConfig, formik, setSaveMessage}: any) {
+
+ useEffect(() => {
+ if (formik.dirty && (formik.initialValues.system.cors["allowed-origins"] !== formik.values.system.cors["allowed-origins"])) {
+ setSaveMessage("Gameyfin must be restarted for the changes to take effect");
+ } else {
+ setSaveMessage(null);
+ }
+ }, [formik.dirty]);
+
+ return (
+
+
+
+
+
+ SystemEndpoint.restart()}>Restart
+
+ );
+}
+
+export const SystemManagement = withConfigPage(SystemManagementLayout, "System");
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/UserManagement.tsx b/app/src/main/frontend/components/administration/UserManagement.tsx
new file mode 100644
index 0000000..4c38313
--- /dev/null
+++ b/app/src/main/frontend/components/administration/UserManagement.tsx
@@ -0,0 +1,54 @@
+import React, {useEffect, useState} from "react";
+import ConfigFormField from "Frontend/components/administration/ConfigFormField";
+import withConfigPage from "Frontend/components/administration/withConfigPage";
+import Section from "Frontend/components/general/Section";
+import {UserEndpoint} from "Frontend/generated/endpoints";
+import UserInfoDto from "Frontend/generated/org/gameyfin/app/users/dto/UserInfoDto";
+import {UserManagementCard} from "Frontend/components/general/cards/UserManagementCard";
+import {SmallInfoField} from "Frontend/components/general/SmallInfoField";
+import {Info, UserPlus} from "@phosphor-icons/react";
+import {Button, Divider, Tooltip, useDisclosure} from "@heroui/react";
+import InviteUserModal from "Frontend/components/general/modals/InviteUserModal";
+
+function UserManagementLayout({getConfig, formik}: any) {
+ const inviteUserModal = useDisclosure();
+ const [users, setUsers] = useState([]);
+
+ useEffect(() => {
+ UserEndpoint.getAllUsers().then(
+ (response) => setUsers(response)
+ );
+ }, []);
+
+ return (
+
+
+
+
+
+
+
+
+
+
Users
+ {!getConfig("sso.oidc.auto-register-new-users").value &&
+
+ }
+
+
+
+
+
+
+
+
+ {users.map((user) => )}
+
+
+
+ );
+}
+
+export const UserManagement = withConfigPage(UserManagementLayout, "User Management");
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/messages/EditTemplateModel.tsx b/app/src/main/frontend/components/administration/messages/EditTemplateModel.tsx
new file mode 100644
index 0000000..63604df
--- /dev/null
+++ b/app/src/main/frontend/components/administration/messages/EditTemplateModel.tsx
@@ -0,0 +1,130 @@
+import React, {useEffect, useState} from "react";
+import {
+ addToast,
+ Button,
+ Chip,
+ Link,
+ Modal,
+ ModalBody,
+ ModalContent,
+ ModalFooter,
+ ModalHeader,
+ Textarea
+} from "@heroui/react";
+import {MessageTemplateEndpoint} from "Frontend/generated/endpoints";
+import MessageTemplateDto from "Frontend/generated/org/gameyfin/app/messages/templates/MessageTemplateDto";
+import TemplateType from "Frontend/generated/org/gameyfin/app/messages/templates/TemplateType";
+
+interface EditTemplateModalProps {
+ isOpen: boolean;
+ onOpenChange: () => void;
+ selectedTemplate: MessageTemplateDto | null;
+}
+
+export default function EditTemplateModal({isOpen, onOpenChange, selectedTemplate}: EditTemplateModalProps) {
+ const [templateContent, setTemplateContent] = useState("");
+ const [defaultPlaceholders, setDefaultPlaceholders] = useState([]);
+
+ useEffect(() => {
+ if (!isOpen) return;
+
+ MessageTemplateEndpoint.read(selectedTemplate?.key as string, TemplateType.MJML).then((response: any) => {
+ setTemplateContent(response as string);
+ });
+
+ MessageTemplateEndpoint.getDefaultPlaceholders(TemplateType.MJML).then((response: any) => {
+ setDefaultPlaceholders(response as string[]);
+ });
+ }, [isOpen]);
+
+ async function saveTemplate(template: MessageTemplateDto) {
+ await MessageTemplateEndpoint.save(template.key, TemplateType.MJML, templateContent);
+ }
+
+ function templateContainsAllRequiredPlaceholders(): boolean {
+ if (!selectedTemplate || !selectedTemplate.availablePlaceholders) return false;
+ return selectedTemplate.availablePlaceholders
+ .every((p) => templateContent.includes(`{${p}}`))
+ }
+
+ return (
+
+
+ {(onClose) => (
+ <>
+ Edit {selectedTemplate?.name} Template
+
+
+
+
+
+ Required placeholders:
+
+
+ {selectedTemplate?.availablePlaceholders?.map((placeholder) =>
+ {placeholder}
+ )}
+
+
+
+
+ Optional placeholders:
+
+
+ {defaultPlaceholders.map((placeholder) =>
+ {placeholder}
+ )}
+
+
+
+
+
+
Powered by mjml.io
+
+
+
+
+ Cancel
+
+ {
+ if (selectedTemplate) {
+ await saveTemplate(selectedTemplate);
+ addToast({
+ title: "Template saved",
+ description: "Template has been saved",
+ color: "success"
+ });
+ onClose();
+ }
+ }}>
+ Save
+
+
+ >
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/messages/SendTestNotificationModal.tsx b/app/src/main/frontend/components/administration/messages/SendTestNotificationModal.tsx
new file mode 100644
index 0000000..7c2d065
--- /dev/null
+++ b/app/src/main/frontend/components/administration/messages/SendTestNotificationModal.tsx
@@ -0,0 +1,76 @@
+import React from "react";
+import {Form, Formik} from "formik";
+import {addToast, Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react";
+import Input from "Frontend/components/general/input/Input";
+import {MessageEndpoint} from "Frontend/generated/endpoints";
+import * as Yup from "yup";
+import MessageTemplateDto from "Frontend/generated/org/gameyfin/app/messages/templates/MessageTemplateDto";
+
+interface SendTestNotificationModalProps {
+ isOpen: boolean;
+ onOpenChange: () => void;
+ selectedTemplate: MessageTemplateDto;
+}
+
+export default function SendTestNotificationModal({
+ isOpen,
+ onOpenChange,
+ selectedTemplate
+ }: SendTestNotificationModalProps) {
+
+ function generateValidationSchema(placeholders: string[]) {
+ const shape: { [key: string]: Yup.StringSchema } = {};
+ placeholders.forEach(placeholder => {
+ shape[placeholder] = Yup.string().required(`Placeholder ${placeholder} is required`);
+ });
+ return Yup.object().shape(shape);
+ }
+
+ return (
+
+
+ {(onClose) => (
+ <>
+ {
+ await MessageEndpoint.sendTestNotification(selectedTemplate.key, values);
+ addToast({
+ title: "Notification sent",
+ description: "Test notification to you has been sent",
+ color: "success"
+ });
+ onClose();
+ }}
+ validationSchema={generateValidationSchema(selectedTemplate.availablePlaceholders)}
+ >
+ {(formik) => (
+
+ )}
+
+ >
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/administration/withConfigPage.tsx b/app/src/main/frontend/components/administration/withConfigPage.tsx
new file mode 100644
index 0000000..b49b766
--- /dev/null
+++ b/app/src/main/frontend/components/administration/withConfigPage.tsx
@@ -0,0 +1,136 @@
+import React, {useEffect, useState} from "react";
+import {ConfigEndpoint} from "Frontend/generated/endpoints";
+import ConfigEntryDto from "Frontend/generated/org/gameyfin/app/config/dto/ConfigEntryDto";
+import {Form, Formik} from "formik";
+import {Button, Skeleton} from "@heroui/react";
+import {Check, Info} from "@phosphor-icons/react";
+import {SmallInfoField} from "Frontend/components/general/SmallInfoField";
+import {configState, initializeConfigState, NestedConfig} from "Frontend/state/ConfigState";
+import {useSnapshot} from "valtio/react";
+
+export default function withConfigPage(WrappedComponent: React.ComponentType, title: String, validationSchema?: any) {
+ return function ConfigPage(props: any) {
+ const [configSaved, setConfigSaved] = useState(false);
+ const [saveMessage, setSaveMessage] = useState();
+
+ const state = useSnapshot(configState);
+
+ useEffect(() => {
+ initializeConfigState();
+ }, []);
+
+ useEffect(() => {
+ if (configSaved) {
+ setTimeout(() => setConfigSaved(false), 2000);
+ }
+ }, [configSaved])
+
+ async function handleSubmit(values: NestedConfig): Promise {
+ const changed = getChangedValues(state.config, values);
+ await ConfigEndpoint.update({updates: changed});
+ setConfigSaved(true);
+ }
+
+ function getConfig(key: string): ConfigEntryDto | undefined {
+ // @ts-ignore
+ return state.state[key];
+ }
+
+ function getChangedValues(initial: NestedConfig, current: NestedConfig): Record {
+ const flatten = (obj: NestedConfig, parentKey = ''): Record => {
+ let result: Record = {};
+ for (const key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ const newKey = parentKey ? `${parentKey}.${key}` : key;
+ if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
+ Object.assign(result, flatten(obj[key], newKey));
+ } else {
+ result[newKey] = obj[key];
+ }
+ }
+ }
+ return result;
+ };
+
+ const arraysEqual = (a: any[], b: any[]): boolean => {
+ if (a.length !== b.length) return false;
+ for (let i = 0; i < a.length; i++) {
+ if (Array.isArray(a[i]) && Array.isArray(b[i])) {
+ if (!arraysEqual(a[i], b[i])) return false;
+ } else if (a[i] !== b[i]) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ const flatInitial = flatten(initial);
+ const flatCurrent = flatten(current);
+
+ const changed: Record = {};
+ for (const key in flatCurrent) {
+ const valA = flatCurrent[key];
+ const valB = flatInitial[key];
+ if (Array.isArray(valA) && Array.isArray(valB)) {
+ if (!arraysEqual(valA, valB)) {
+ changed[key] = valA;
+ }
+ } else if (valA !== valB) {
+ changed[key] = valA;
+ }
+ }
+ return changed;
+ }
+
+ return (
+ <>
+ {state.isLoaded ?
+
+ {(formik) => (
+
+ )}
+ :
+ [...Array(4)].map((_e, i) =>
+
+ )
+ }
+ >
+ );
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/Avatar.tsx b/app/src/main/frontend/components/general/Avatar.tsx
new file mode 100644
index 0000000..78df1de
--- /dev/null
+++ b/app/src/main/frontend/components/general/Avatar.tsx
@@ -0,0 +1,27 @@
+import {useAuth} from "Frontend/util/auth";
+import {Avatar as NextUiAvatar} from "@heroui/react";
+
+// @ts-ignore
+const Avatar = ({...props}) => {
+ const auth = useAuth();
+ const username = getUsername();
+
+ function getUsername() {
+ if (props.username === undefined || props.username === null || props.username == "") {
+ return auth.state.user?.username;
+ }
+
+ return props.username;
+ }
+
+ // TODO: Check if avatar can be loaded from SSO
+ return (
+
+ );
+}
+
+export default Avatar;
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/IconBackgroundPattern.tsx b/app/src/main/frontend/components/general/IconBackgroundPattern.tsx
new file mode 100644
index 0000000..91bceb9
--- /dev/null
+++ b/app/src/main/frontend/components/general/IconBackgroundPattern.tsx
@@ -0,0 +1,32 @@
+import {
+ Alien,
+ CastleTurret,
+ GameController,
+ Ghost,
+ Joystick,
+ Lego,
+ Skull,
+ SoccerBall,
+ Strategy,
+ Sword,
+ TreasureChest,
+ Trophy
+} from "@phosphor-icons/react";
+import React from "react";
+
+export default function IconBackgroundPattern() {
+ return
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/RoleChip.tsx b/app/src/main/frontend/components/general/RoleChip.tsx
new file mode 100644
index 0000000..ffd535f
--- /dev/null
+++ b/app/src/main/frontend/components/general/RoleChip.tsx
@@ -0,0 +1,10 @@
+import {Chip} from "@heroui/react";
+import {roleToColor, roleToRoleName} from "Frontend/util/utils";
+
+export default function RoleChip({role}: { role: string }) {
+ return (
+
+ {roleToRoleName(role)}
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/ScanProgressPopover.tsx b/app/src/main/frontend/components/general/ScanProgressPopover.tsx
new file mode 100644
index 0000000..449cb4c
--- /dev/null
+++ b/app/src/main/frontend/components/general/ScanProgressPopover.tsx
@@ -0,0 +1,111 @@
+import {
+ Button,
+ Divider,
+ Link,
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+ Progress,
+ ScrollShadow,
+ Spinner
+} from "@heroui/react";
+import {useSnapshot} from "valtio/react";
+import {scanState} from "Frontend/state/ScanState";
+import LibraryScanProgress from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryScanProgress";
+import {libraryState} from "Frontend/state/LibraryState";
+import {Target} from "@phosphor-icons/react";
+import {timeBetween, timeUntil} from "Frontend/util/utils";
+import LibraryScanStatus from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryScanStatus";
+import {useEffect, useState} from "react";
+
+export default function ScanProgressPopover() {
+ const libraries = useSnapshot(libraryState).state;
+ const scans = useSnapshot(scanState).sortedByStartTime as LibraryScanProgress[];
+ const scanInProgress = useSnapshot(scanState).isScanning;
+
+ // Add state to track current time and force re-renders
+ const [currentTime, setCurrentTime] = useState(Date.now());
+
+ // Set up an interval to update the time every second
+ useEffect(() => {
+ const intervalId = setInterval(() => {
+ setCurrentTime(Date.now());
+ }, 1000);
+
+ // Clean up the interval when component unmounts
+ return () => clearInterval(intervalId);
+ }, []);
+
+ return (
+
+
+
+ {scanInProgress ?
+ :
+
+ }
+
+
+
+
+ {scans.length === 0 ?
+
+ No scans in progress or in history.
+
:
+
+ {scans.map((scan, index) =>
+
+
+
Scan for library
+
+ {libraries[scan.libraryId].name}
+
+
+ {scan.finishedAt ?
+
+ Finished {timeUntil(scan.finishedAt)}
+
:
+
+ Started {timeUntil(scan.startedAt)}
+
+ }
+
+ {scan.status === LibraryScanStatus.IN_PROGRESS ?
+ scan.currentStep.current && scan.currentStep.total ?
+
+
+ {`${scan.currentStep.description} (${scan.currentStep.current}/${scan.currentStep.total})`}
+
+
+
:
+
+
{scan.currentStep.description}
+
+
+ :
+
+ {scan.result?.new} new /
+ {scan.result?.removed} removed /
+ {scan.result?.unmatched} unmatched
+ (in {timeBetween(scan.startedAt, scan.finishedAt!)})
+
+ }
+ {scans.length > 1 && index < (scans.length - 1) &&
}
+
+ )}
+
+ }
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/SearchBar.tsx b/app/src/main/frontend/components/general/SearchBar.tsx
new file mode 100644
index 0000000..877e7dd
--- /dev/null
+++ b/app/src/main/frontend/components/general/SearchBar.tsx
@@ -0,0 +1,62 @@
+import {Autocomplete, AutocompleteItem} from "@heroui/react";
+import {CaretRight, MagnifyingGlass} from "@phosphor-icons/react";
+import {useSnapshot} from "valtio/react";
+import {gameState} from "Frontend/state/GameState";
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import {useNavigate} from "react-router";
+import {GameCover} from "Frontend/components/general/covers/GameCover";
+
+export default function SearchBar() {
+
+ const navigate = useNavigate();
+ const state = useSnapshot(gameState);
+ const games = state.recentlyUpdated as GameDto[];
+
+ return }
+ isVirtualized={true}
+ maxListboxHeight={300}
+ itemHeight={91} // 75px (cover) + 16px (margin top/bottom) = 91px
+ >
+ {(item) => (
+ navigate("/game/" + item.id)}>
+
+
+
+
{item.title} ({item.release && new Date(item.release).getFullYear()})
+
{item.developers && [...item.developers].sort().join(" / ")}
+
+
+
+
+ )}
+
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/Section.tsx b/app/src/main/frontend/components/general/Section.tsx
new file mode 100644
index 0000000..34f4fd6
--- /dev/null
+++ b/app/src/main/frontend/components/general/Section.tsx
@@ -0,0 +1,10 @@
+import {Divider} from "@heroui/react";
+
+export default function Section({title}: { title: string }) {
+ return (
+ <>
+ {title}
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/SmallInfoField.tsx b/app/src/main/frontend/components/general/SmallInfoField.tsx
new file mode 100644
index 0000000..6e7b0e7
--- /dev/null
+++ b/app/src/main/frontend/components/general/SmallInfoField.tsx
@@ -0,0 +1,12 @@
+import React from 'react';
+
+// @ts-ignore
+export function SmallInfoField({icon: IconComponent, message, ...props}) {
+ return (
+
+
+ {message}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/cards/LibraryOverviewCard.tsx b/app/src/main/frontend/components/general/cards/LibraryOverviewCard.tsx
new file mode 100644
index 0000000..a773b31
--- /dev/null
+++ b/app/src/main/frontend/components/general/cards/LibraryOverviewCard.tsx
@@ -0,0 +1,76 @@
+import {Button, Card, Chip, Tooltip} from "@heroui/react";
+import LibraryDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryDto";
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import React from "react";
+import {LibraryEndpoint} from "Frontend/generated/endpoints";
+import {GameCover} from "Frontend/components/general/covers/GameCover";
+import {MagnifyingGlass, SlidersHorizontal} from "@phosphor-icons/react";
+import ScanType from "Frontend/generated/org/gameyfin/app/libraries/enums/ScanType";
+import {useNavigate} from "react-router";
+import {useSnapshot} from "valtio/react";
+import {gameState} from "Frontend/state/GameState";
+import IconBackgroundPattern from "Frontend/components/general/IconBackgroundPattern";
+
+interface LibraryOverviewCardProps {
+ library: LibraryDto;
+}
+
+export function LibraryOverviewCard({library}: LibraryOverviewCardProps) {
+ const MAX_COVER_COUNT = 5;
+ const navigate = useNavigate();
+ const state = useSnapshot(gameState);
+ const randomGames = getRandomGames();
+
+ function getRandomGames() {
+ const games = state.randomlyOrderedGamesByLibraryId[library.id] as GameDto[];
+ if (!games) return [];
+ return games.slice(0, MAX_COVER_COUNT);
+ }
+
+ async function triggerScan() {
+ await LibraryEndpoint.triggerScan(ScanType.QUICK, [library]);
+ }
+
+ return (
+
+
+
+
+ {randomGames.length > 0 &&
+
+ {randomGames.map((game) => (
+
+ ))}
+
+ }
+
+
+
{library.name}
+
+
+
+
+
+
+
+
+ navigate('library/' + library.id)}>
+
+
+
+
+
+
+ {library.stats &&
+
+
Games
+
Downloads
+
Platforms
+
{library.stats.gamesCount}
+
{library.stats.downloadedGamesCount}
+
PC
+
+ }
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/cards/PluginManagementCard.tsx b/app/src/main/frontend/components/general/cards/PluginManagementCard.tsx
new file mode 100644
index 0000000..1dbb71a
--- /dev/null
+++ b/app/src/main/frontend/components/general/cards/PluginManagementCard.tsx
@@ -0,0 +1,180 @@
+import {Button, Card, Chip, Tooltip, useDisclosure} from "@heroui/react";
+import {
+ CheckCircle,
+ IconContext,
+ PauseCircle,
+ PlayCircle,
+ Power,
+ Question,
+ QuestionMark,
+ SealCheck,
+ SealQuestion,
+ SealWarning,
+ SlidersHorizontal,
+ StopCircle,
+ WarningCircle,
+ XCircle
+} from "@phosphor-icons/react";
+import PluginState from "Frontend/generated/org/pf4j/PluginState";
+import React, {ReactNode} from "react";
+import PluginDetailsModal from "Frontend/components/general/modals/PluginDetailsModal";
+import PluginLogo from "Frontend/components/general/plugin/PluginLogo";
+import PluginTrustLevel from "Frontend/generated/org/gameyfin/app/core/plugins/management/PluginTrustLevel";
+import {PluginEndpoint} from "Frontend/generated/endpoints";
+import PluginDto from "Frontend/generated/org/gameyfin/app/core/plugins/dto/PluginDto";
+import PluginConfigValidationResult
+ from "Frontend/generated/org/gameyfin/pluginapi/core/config/PluginConfigValidationResult";
+import PluginConfigValidationResultType
+ from "Frontend/generated/org/gameyfin/pluginapi/core/config/PluginConfigValidationResultType";
+
+export function PluginManagementCard({plugin}: { plugin: PluginDto }) {
+ const pluginDetailsModal = useDisclosure();
+
+ function borderColor(state: PluginState | undefined, trustLevel: PluginTrustLevel | undefined): "success" | "warning" | "danger" | "default" {
+ if (trustLevel === PluginTrustLevel.UNTRUSTED) return "danger";
+
+ if (isDisabled(state)) return "warning";
+ return stateToColor(state);
+ }
+
+ function stateToColor(state: PluginState | undefined): "success" | "warning" | "danger" | "default" {
+ switch (state) {
+ case PluginState.STARTED:
+ return "success";
+ case PluginState.DISABLED:
+ return "warning";
+ case PluginState.FAILED:
+ case PluginState.STOPPED:
+ return "danger";
+ default:
+ return "default";
+ }
+ }
+
+ function stateToIcon(state: PluginState | undefined): ReactNode {
+ switch (state) {
+ case PluginState.STARTED:
+ return ;
+ case PluginState.DISABLED:
+ return ;
+ case PluginState.STOPPED:
+ case PluginState.FAILED:
+ return ;
+ case PluginState.UNLOADED:
+ case PluginState.RESOLVED:
+ return ;
+ default:
+ return ;
+ }
+ }
+
+ function configValidationResultToChip(validationResult: PluginConfigValidationResult | undefined): ReactNode {
+ switch (validationResult?.result) {
+ case PluginConfigValidationResultType.VALID:
+ return
+
+
+
+
+ case PluginConfigValidationResultType.INVALID:
+ return
+
+
+
+ ;
+ default:
+ return
+
+
+
+
+ }
+ }
+
+ function trustLevelToBadge(trustLevel: PluginTrustLevel | undefined): React.ReactNode {
+ switch (trustLevel) {
+ case PluginTrustLevel.OFFICIAL:
+ return
+
+ ;
+ case PluginTrustLevel.BUNDLED:
+ return
+
+ ;
+ case PluginTrustLevel.THIRD_PARTY:
+ return
+
+ ;
+ case PluginTrustLevel.UNTRUSTED:
+ return
+
+ ;
+ default:
+ return
+
+ ;
+ }
+ }
+
+ function isDisabled(state: PluginState | undefined): boolean {
+ return state === PluginState.DISABLED;
+ }
+
+ function togglePluginEnabled() {
+ if (isDisabled(plugin.state)) {
+ PluginEndpoint.enablePlugin(plugin.id);
+ } else {
+ PluginEndpoint.disablePlugin(plugin.id);
+ }
+ }
+
+ // @ts-ignore
+ return (
+ <>
+
+
+
+ togglePluginEnabled()}
+ isDisabled={plugin.state == PluginState.UNLOADED || plugin.state == PluginState.RESOLVED}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+ {plugin.name}
+
+ {trustLevelToBadge(plugin.trustLevel)}
+
+
+
+ {plugin.version}
+
+
+ {stateToIcon(plugin.state)}
+
+
+ {configValidationResultToChip(plugin.configValidation)}
+
+
+
+
+ >
+
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/cards/UserManagementCard.tsx b/app/src/main/frontend/components/general/cards/UserManagementCard.tsx
new file mode 100644
index 0000000..cd33c65
--- /dev/null
+++ b/app/src/main/frontend/components/general/cards/UserManagementCard.tsx
@@ -0,0 +1,158 @@
+import {Card, Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, useDisclosure} from "@heroui/react";
+import {DotsThreeVertical} from "@phosphor-icons/react";
+import {useAuth} from "Frontend/util/auth";
+import {useEffect, useState} from "react";
+import {MessageEndpoint, PasswordResetEndpoint, UserEndpoint} from "Frontend/generated/endpoints";
+import {AvatarEndpoint} from "Frontend/endpoints/endpoints";
+import Avatar from "Frontend/components/general/Avatar";
+import ConfirmUserDeletionModal from "Frontend/components/general/modals/ConfirmUserDeletionModal";
+import PasswordResetTokenModal from "Frontend/components/general/modals/PasswortResetTokenModal";
+import TokenDto from "Frontend/generated/org/gameyfin/app/shared/token/TokenDto";
+import UserInfoDto from "Frontend/generated/org/gameyfin/app/users/dto/UserInfoDto";
+import RoleChip from "Frontend/components/general/RoleChip";
+import AssignRolesModal from "Frontend/components/general/modals/AssignRolesModal";
+
+export function UserManagementCard({user}: { user: UserInfoDto }) {
+ const userDeletionConfirmationModal = useDisclosure();
+ const passwordResetTokenModal = useDisclosure();
+ const roleAssignmentModal = useDisclosure();
+ const [userEnabled, setUserEnabled] = useState(true);
+ const [disabledKeys, setDisabledKeys] = useState([]);
+ const [dropdownItems, setDropdownItems] = useState([]);
+ const [passwordResetToken, setPasswordResetToken] = useState();
+ const auth = useAuth();
+
+ useEffect(() => {
+ setUserEnabled(user.enabled);
+ let keysToBeDisabled: string[] = [];
+ MessageEndpoint.isEnabled().then((isEnabled) => {
+ if (isEnabled) keysToBeDisabled.push("resetPassword");
+ if (!user.hasAvatar) keysToBeDisabled.push("removeAvatar");
+ setDisabledKeys(keysToBeDisabled);
+ });
+ UserEndpoint.canCurrentUserManage(user.username).then((canManage) => {
+ if (!canManage) keysToBeDisabled.push("assignRole", "disableUser", "delete");
+ setDisabledKeys(keysToBeDisabled);
+ });
+ }, []);
+
+ useEffect(() => {
+ setDropdownItems(getDropdownItems());
+ }, [userEnabled]);
+
+ async function resetPassword() {
+ let token = await PasswordResetEndpoint.createPasswordResetTokenForUser(user.username);
+ if (token === undefined) return;
+ setPasswordResetToken(token);
+ passwordResetTokenModal.onOpen();
+ }
+
+ function getDropdownItems() {
+ let items = [];
+
+ if (!user.managedBySso) {
+ if (!userEnabled) {
+ items.push(
+ {
+ key: "enableUser",
+ onPress: () => {
+ UserEndpoint.setUserEnabled(user.username, true).then(() => {
+ setUserEnabled(true);
+ })
+ },
+ label: "Enable user"
+ }
+ );
+ } else {
+ items.push(
+ {
+ key: "disableUser",
+ onPress: () => {
+ UserEndpoint.setUserEnabled(user.username, false).then(() => {
+ setUserEnabled(false);
+ })
+ },
+ label: "Disable user"
+ }
+ );
+ }
+
+ items.push(
+ {
+ key: "removeAvatar",
+ onPress: () => AvatarEndpoint.removeAvatarByName(user.username!),
+ label: "Remove avatar"
+ },
+ {
+ key: "assignRole",
+ onPress: roleAssignmentModal.onOpen,
+ label: "Assign role"
+ },
+ {
+ key: "resetPassword",
+ onPress: resetPassword,
+ label: "Reset password"
+ }
+ );
+ }
+
+ items.push({
+ key: "delete",
+ onPress: userDeletionConfirmationModal.onOpen,
+ label: "Delete user"
+ }
+ );
+
+ return items;
+ }
+
+ return (
+ <>
+
+
+
+
+
{user.username}
+
{user.email}
+ {user.roles?.map((role) => (
+
+ ))}
+
+
+
+
+
+
+
+
+ {(item) => (
+
+ {item.label}
+
+ )}
+
+
+
+
+
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/covers/CoverGrid.tsx b/app/src/main/frontend/components/general/covers/CoverGrid.tsx
new file mode 100644
index 0000000..303703a
--- /dev/null
+++ b/app/src/main/frontend/components/general/covers/CoverGrid.tsx
@@ -0,0 +1,16 @@
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import {GameCover} from "Frontend/components/general/covers/GameCover";
+
+interface CoverGridProps {
+ games: GameDto[];
+}
+
+export default function CoverGrid({games}: CoverGridProps) {
+ return (
+
+ {games.map((game) => (
+
+ ))}
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/covers/CoverRow.tsx b/app/src/main/frontend/components/general/covers/CoverRow.tsx
new file mode 100644
index 0000000..dbe1c1a
--- /dev/null
+++ b/app/src/main/frontend/components/general/covers/CoverRow.tsx
@@ -0,0 +1,70 @@
+import React, {useEffect, useRef, useState} from "react";
+import {GameCover} from "Frontend/components/general/covers/GameCover";
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import {ArrowRight} from "@phosphor-icons/react";
+import {useNavigate} from "react-router";
+
+interface CoverRowProps {
+ games: GameDto[];
+ title: string;
+ onPressShowMore: () => void;
+}
+
+const aspectRatio = 12 / 17; // aspect ratio of the game cover
+const defaultImageHeight = 300; // default height for the image
+const defaultImageWidth = aspectRatio * defaultImageHeight; // default width for the image
+
+export function CoverRow({games, title, onPressShowMore}: CoverRowProps) {
+
+ const navigate = useNavigate();
+ const containerRef = useRef(null);
+ const [visibleCount, setVisibleCount] = useState(games.length);
+
+ useEffect(() => {
+ const calculateVisible = () => {
+ if (containerRef.current) {
+ const containerWidth = containerRef.current.offsetWidth;
+ const maxFit = Math.floor((containerWidth - defaultImageWidth) / defaultImageWidth) + 1;
+ setVisibleCount(maxFit < games.length ? maxFit : games.length);
+ }
+ };
+
+ const resizeObserver = new ResizeObserver(calculateVisible);
+ if (containerRef.current) {
+ resizeObserver.observe(containerRef.current);
+ }
+
+ calculateVisible(); // initial calculation
+
+ return () => resizeObserver.disconnect();
+ }, [games.length]);
+
+ const showMore = visibleCount < games.length;
+
+ return (
+
+
{title}
+
+
+ {games.slice(0, visibleCount).map((game, index) => (
+
+ ))}
+
+
+ {showMore && (
+
+ )}
+
+
+ );
+}
diff --git a/app/src/main/frontend/components/general/covers/GameCover.tsx b/app/src/main/frontend/components/general/covers/GameCover.tsx
new file mode 100644
index 0000000..00e99d7
--- /dev/null
+++ b/app/src/main/frontend/components/general/covers/GameCover.tsx
@@ -0,0 +1,33 @@
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import {Image} from "@heroui/react";
+import {GameCoverFallback} from "Frontend/components/general/covers/GameCoverFallback";
+
+interface GameCoverProps {
+ game: GameDto;
+ size?: number;
+ radius?: "none" | "sm" | "md" | "lg";
+ interactive?: boolean;
+}
+
+export function GameCover({game, size = 300, radius = "sm", interactive = false}: GameCoverProps) {
+ const coverContent = Number.isInteger(game.coverId) ? (
+
+ }
+ />
+
+ ) : (
+
+ );
+
+ return interactive ? (
+
+ {coverContent}
+
+ ) : coverContent;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/covers/GameCoverFallback.tsx b/app/src/main/frontend/components/general/covers/GameCoverFallback.tsx
new file mode 100644
index 0000000..7c6bc1d
--- /dev/null
+++ b/app/src/main/frontend/components/general/covers/GameCoverFallback.tsx
@@ -0,0 +1,20 @@
+import {Card} from "@heroui/react";
+
+interface GameCoverFallbackProps {
+ title: string;
+ size?: number;
+ radius?: "none" | "sm" | "md" | "lg";
+ hover?: boolean;
+}
+
+export function GameCoverFallback({title, size = 300, radius = "sm", hover = false}: GameCoverFallbackProps) {
+ return (
+
+
+ {title}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/covers/ImageCarousel.tsx b/app/src/main/frontend/components/general/covers/ImageCarousel.tsx
new file mode 100644
index 0000000..8b4325c
--- /dev/null
+++ b/app/src/main/frontend/components/general/covers/ImageCarousel.tsx
@@ -0,0 +1,152 @@
+import {Autoplay, Navigation, Pagination} from 'swiper/modules';
+import {Swiper, SwiperSlide} from "swiper/react";
+import {Card, Image, Modal, ModalContent, useDisclosure} from "@heroui/react";
+import ReactPlayer from 'react-player';
+
+import "swiper/css";
+import "swiper/css/navigation";
+import "swiper/css/pagination";
+import "swiper/css/autoplay";
+import {useEffect, useState} from "react";
+import {CaretLeft, CaretRight, IconContext, Play} from "@phosphor-icons/react";
+
+
+interface ImageCarouselProps {
+ imageUrls?: string[];
+ videosUrls?: string[];
+ className?: string;
+}
+
+interface SlideData {
+ isActive: boolean;
+ isVisible: boolean;
+ isPrev: boolean;
+ isNext: boolean;
+}
+
+export default function ImageCarousel({imageUrls, videosUrls, className}: ImageCarouselProps) {
+
+ interface CarouselElement {
+ type: "image" | "video";
+ url: string;
+ }
+
+ const DEFAULT_SLIDES_PER_VIEW = 3;
+
+ const [elements, setElements] = useState();
+ const [selectedImageUrl, setSelectedImageUrl] = useState();
+ const imagePopup = useDisclosure();
+
+ useEffect(() => {
+ const images = imageUrls?.map((imageUrl) => ({
+ type: "image" as const,
+ url: imageUrl
+ })) || [];
+ const videos = videosUrls?.map((videoUrl) => ({
+ type: "video" as const,
+ url: videoUrl
+ })) || [];
+
+ setElements([...images, ...videos]);
+ }, [imageUrls, videosUrls])
+
+ function showImagePopup(imageUrl: string) {
+ setSelectedImageUrl(imageUrl);
+ imagePopup.onOpen();
+ }
+
+ return (
+
+ {elements && elements.length > 0 &&
+
+
+
+
+ elements.length ? elements.length : DEFAULT_SLIDES_PER_VIEW}
+ pagination={{
+ clickable: true,
+ el: ".swiper-custom-pagination"
+ }}
+ navigation={{
+ prevEl: ".swiper-custom-button-prev",
+ nextEl: ".swiper-custom-button-next"
+ }}
+ centeredSlides={true}
+ loop={true}
+ spaceBetween={0}
+ autoplay={{
+ delay: 10000,
+ disableOnInteraction: true
+ }}
+ className="w-full"
+ >
+ {elements && elements.map((e, index) => (
+
+ {({isActive}: SlideData) => {
+ if (e.type === "image") {
+ return (
+ showImagePopup(e.url)}
+ />
+ )
+ }
+ return (
+
+ }
+ />
+
+ )
+ }}
+
+ ))}
+
+
+
+
+
+
+ {/* Wrap the pagination in a div because it gets replaced at runtime be SwiperJS and loses all styling */}
+
+
+
+ }
+
+ );
+}
+
+function ImagePopup({imageUrl, isOpen, onOpenChange}: {
+ imageUrl?: string,
+ isOpen: boolean,
+ onOpenChange: (isOpen: boolean) => void
+}) {
+ return (imageUrl &&
+
+
+ {(onClose) => (
+
+
+
+ )}
+
+
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/covers/LibraryHeader.tsx b/app/src/main/frontend/components/general/covers/LibraryHeader.tsx
new file mode 100644
index 0000000..963195d
--- /dev/null
+++ b/app/src/main/frontend/components/general/covers/LibraryHeader.tsx
@@ -0,0 +1,50 @@
+import LibraryDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryDto";
+import React from "react";
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import {useSnapshot} from "valtio/react";
+import {gameState} from "Frontend/state/GameState";
+import IconBackgroundPattern from "Frontend/components/general/IconBackgroundPattern";
+import {Card} from "@heroui/react";
+
+interface LibraryHeaderProps {
+ library: LibraryDto;
+ className?: string;
+}
+
+export default function LibraryHeader({library, className}: LibraryHeaderProps) {
+ const MAX_COVER_COUNT = 5;
+ const state = useSnapshot(gameState);
+ const randomGames = getRandomGames();
+
+ function getRandomGames() {
+ const games = state.randomlyOrderedGamesByLibraryId[library.id] as GameDto[];
+ if (!games) return [];
+ return games.slice(0, MAX_COVER_COUNT);
+ }
+
+ return (
+
+
+
+ {randomGames.map((game, idx) => (
+
+
+
+ ))}
+
+
+
{library.name}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/input/ArrayInput.tsx b/app/src/main/frontend/components/general/input/ArrayInput.tsx
new file mode 100644
index 0000000..d5c904b
--- /dev/null
+++ b/app/src/main/frontend/components/general/input/ArrayInput.tsx
@@ -0,0 +1,70 @@
+import {FieldArray, useField} from "formik";
+import {Button, Chip, Input, Popover, PopoverContent, PopoverTrigger} from "@heroui/react";
+import {KeyboardEvent, useState} from "react";
+import {Plus} from "@phosphor-icons/react";
+
+// @ts-ignore
+const ArrayInput = ({label, ...props}) => {
+ // @ts-ignore
+ const [field, meta] = useField(props);
+ const [newElementValue, setNewElementValue] = useState("");
+
+ return (
+ {
+ function handleKeyDown(event: KeyboardEvent) {
+ if (event.key === "Enter" || event.key == "Tab" || event.key === ",") {
+ event.preventDefault();
+
+ newElementValue
+ .split(",")
+ .map((value) => value.trim())
+ .filter((value) => value !== "")
+ .forEach((value) => arrayHelpers.push(value));
+
+ setNewElementValue("");
+ }
+ }
+
+ return (
+
+
+
{label}
+
{field.value.length} {field.value.length == 1 ? "element" : "elements"}
+
+
+
+ {field.value.map((element: any, index: number) => (
+
arrayHelpers.remove(index)}>
+ {element}
+
+ ))}
+
+
+
+
+
+ setNewElementValue(e.target.value)}
+ onKeyDown={handleKeyDown}
+ placeholder="New element..."
+ variant="bordered"
+ />
+
+
+
+
+
+ {meta.touched && meta.error && meta.error.trim().length > 0 && (
+ meta.error
+ )}
+
+
+ );
+ }}
+ />
+ );
+}
+
+export default ArrayInput;
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/input/CheckboxInput.tsx b/app/src/main/frontend/components/general/input/CheckboxInput.tsx
new file mode 100644
index 0000000..7e972f5
--- /dev/null
+++ b/app/src/main/frontend/components/general/input/CheckboxInput.tsx
@@ -0,0 +1,29 @@
+import {useField} from "formik";
+import {Checkbox, CheckboxGroup} from "@heroui/react";
+
+// @ts-ignore
+const CheckboxInput = ({label, ...props}) => {
+ // @ts-ignore
+ const [field, meta] = useField(props);
+
+ return (
+
+
+ {label}
+
+
+ );
+}
+
+export default CheckboxInput;
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/input/ComboButton.tsx b/app/src/main/frontend/components/general/input/ComboButton.tsx
new file mode 100644
index 0000000..b23817f
--- /dev/null
+++ b/app/src/main/frontend/components/general/input/ComboButton.tsx
@@ -0,0 +1,85 @@
+import {useEffect, useState} from "react";
+import {
+ Button,
+ ButtonGroup,
+ Dropdown,
+ DropdownItem,
+ DropdownMenu,
+ DropdownTrigger,
+ SharedSelection
+} from "@heroui/react";
+import {CaretDown} from "@phosphor-icons/react";
+import {UserPreferenceService} from "Frontend/util/user-preference-service";
+
+export interface ComboButtonOption {
+ label: string;
+ description: string;
+ action: () => void;
+ isDisabled?: boolean;
+}
+
+export interface ComboButtonProps {
+ description?: string;
+ options: Record;
+ preferredOptionKey?: string;
+}
+
+export default function ComboButton({options, preferredOptionKey, description}: ComboButtonProps) {
+ const [selectedOption, setSelectedOption] = useState(new Set([Object.keys(options)[0]]));
+ const selectedOptionValue = Array.from(selectedOption)[0];
+
+ useEffect(() => {
+ if (!preferredOptionKey) return;
+
+ UserPreferenceService.get(preferredOptionKey).then((key) => {
+ if (key && options[key]) {
+ setSelectedOption(new Set([key]));
+ } else {
+ setSelectedOption(new Set([Object.keys(options)[0]]));
+ }
+ })
+ }, []);
+
+ async function onSelectionChange(keys: SharedSelection) {
+ if (!keys.currentKey) return;
+
+ if (preferredOptionKey) {
+ await UserPreferenceService.set(preferredOptionKey, keys.currentKey);
+ }
+
+ setSelectedOption(new Set([keys.currentKey]));
+ }
+
+ return options[selectedOptionValue] && (
+
+
+
+
{options[selectedOptionValue].label}
+
{description}
+
+
+
+
+
+
+
+
+
+ {Object.entries(options).map(([key, option]) => (
+
+ {option.label}
+
+ ))}
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/input/DatePickerInput.tsx b/app/src/main/frontend/components/general/input/DatePickerInput.tsx
new file mode 100644
index 0000000..9fb3a12
--- /dev/null
+++ b/app/src/main/frontend/components/general/input/DatePickerInput.tsx
@@ -0,0 +1,35 @@
+import {useField} from "formik";
+import {DatePicker, DateValue} from "@heroui/react";
+import {parseDate} from "@internationalized/date";
+import {useState} from "react";
+
+// @ts-ignore
+export default function DatePickerInput({label, showErrorUntouched = false, ...props}) {
+ // @ts-ignore
+ const [field, meta] = useField(props);
+ const [value, setValue] = useState(field.value ? parseDate(field.value) : null);
+
+ return (
+ {
+ setValue(date);
+ field.onChange({
+ target: {
+ name: field.name,
+ value: date ? date.toString() : ''
+ }
+ });
+ }}
+ id={label}
+ label={label}
+ isInvalid={(meta.touched || showErrorUntouched) && !!meta.error}
+ errorMessage={meta.initialError || meta.error}
+ />
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/input/DirectoryMappingInput.tsx b/app/src/main/frontend/components/general/input/DirectoryMappingInput.tsx
new file mode 100644
index 0000000..4174997
--- /dev/null
+++ b/app/src/main/frontend/components/general/input/DirectoryMappingInput.tsx
@@ -0,0 +1,79 @@
+import React from "react";
+import {Button, Code, useDisclosure} from "@heroui/react";
+import {ArrowRight, Minus, Plus, XCircle} from "@phosphor-icons/react";
+import PathPickerModal from "Frontend/components/general/modals/PathPickerModal";
+import {SmallInfoField} from "Frontend/components/general/SmallInfoField";
+import DirectoryMappingDto from "Frontend/generated/org/gameyfin/app/libraries/dto/DirectoryMappingDto";
+import {useField} from "formik";
+
+interface DirectoryMappingInputProps {
+ name: string;
+}
+
+export default function DirectoryMappingInput({name}: DirectoryMappingInputProps) {
+ const pathPickerModal = useDisclosure();
+ const [field, meta, helpers] = useField({name});
+
+ function addDirectoryMapping(directory: DirectoryMappingDto) {
+ helpers.setValue([...(field.value || []), directory]);
+ }
+
+ function removeDirectoryMapping(directory: DirectoryMappingDto) {
+ helpers.setValue((field.value || []).filter((d) => d !== directory));
+ }
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/input/FileTreeView.tsx b/app/src/main/frontend/components/general/input/FileTreeView.tsx
new file mode 100644
index 0000000..08f4738
--- /dev/null
+++ b/app/src/main/frontend/components/general/input/FileTreeView.tsx
@@ -0,0 +1,154 @@
+import TreeView, {flattenTree, INode, NodeId} from "react-accessible-treeview";
+import {File, Folder, FolderOpen, IconContext} from "@phosphor-icons/react";
+import {useEffect, useState} from "react";
+import {FilesystemEndpoint} from "Frontend/generated/endpoints";
+import FileDto from "Frontend/generated/org/gameyfin/app/core/filesystem/FileDto";
+import FileType from "Frontend/generated/org/gameyfin/app/core/filesystem/FileType";
+import {IFlatMetadata} from "react-accessible-treeview/dist/TreeView/utils";
+import OperatingSystemType from "Frontend/generated/org/gameyfin/app/core/filesystem/OperatingSystemType";
+
+interface ITreeNode {
+ id?: NodeId;
+ name: string;
+ isBranch?: boolean;
+ children?: ITreeNode[];
+ metadata?: M;
+}
+
+export default function FileTreeView({onPathChange}: { onPathChange: (file: string) => void }) {
+ const rootNode: INode = {
+ id: "root",
+ name: "",
+ children: [],
+ parent: null
+ }
+
+ const [hostOSType, setHostOSType] = useState();
+ const [fileTree, setFileTree] = useState();
+ const [flattenedFileTree, setFlattenedFileTree] = useState([rootNode]);
+
+ useEffect(() => {
+ FilesystemEndpoint.getHostOperatingSystem().then((response) => {
+ setHostOSType(response);
+ })
+
+ FilesystemEndpoint.listSubDirectories("").then(
+ result => {
+ if (result === undefined) return;
+ const nodes = fileDtosToTree(result as FileDto[]);
+ const tree = flattenTree(nodes);
+ setFileTree(nodes);
+ setFlattenedFileTree(tree);
+ }
+ )
+ }, []);
+
+ function getAbsolutePath(node: INode, path: string = ""): string {
+ let pathSeparator = "/";
+
+ if (hostOSType === OperatingSystemType.WINDOWS) {
+ pathSeparator = "\\";
+ if (path.startsWith(pathSeparator)) path = path.substring(1);
+ }
+
+ path = path.replace(`${pathSeparator}${pathSeparator}`, pathSeparator);
+
+ if (node.parent === null) {
+ if (hostOSType === OperatingSystemType.WINDOWS) return path;
+ return `${pathSeparator}${path}`;
+ }
+
+ const parentNode = flattenedFileTree.find(n => n.id === node.parent);
+ if (!parentNode) {
+ throw new Error(`Parent node with id ${node.parent} not found`);
+ }
+ return getAbsolutePath(parentNode, `${node.name}${pathSeparator}${path}`);
+ }
+
+ async function onLoadData({element}: { element: INode }) {
+ const absolutePath = getAbsolutePath(element);
+
+ let subDirectories = await FilesystemEndpoint.listSubDirectories(absolutePath);
+ if (subDirectories === undefined) return;
+
+ const newNodes = fileDtosToNodes(subDirectories as FileDto[]);
+ const updatedTree = updateTreeWithNewNodes(fileTree!!, element.id, newNodes);
+
+ setFileTree(updatedTree);
+ setFlattenedFileTree(flattenTree(updatedTree));
+ onPathChange(absolutePath);
+ }
+
+ function updateTreeWithNewNodes(tree: ITreeNode, nodeId: NodeId, newNodes: ITreeNode[]): ITreeNode {
+ if (tree.id === nodeId) {
+ return {...tree, children: newNodes};
+ }
+
+ if (tree.children) {
+ return {
+ ...tree,
+ children: tree.children.map(child => updateTreeWithNewNodes(child, nodeId, newNodes))
+ };
+ }
+
+ return tree;
+ }
+
+ function fileDtosToTree(fileDtos: FileDto[], parent: (INode | null) = null): ITreeNode {
+ const nodes = fileDtosToNodes(fileDtos);
+
+ if (parent === null) {
+ return {...rootNode, children: nodes};
+ }
+
+ return {...parent, children: nodes};
+ }
+
+ function fileDtosToNodes(fileDtos: FileDto[]): ITreeNode[] {
+ return fileDtos.map(fileDto => ({
+ id: fileDto.hash,
+ name: fileDto.name || "",
+ isBranch: fileDto.type === FileType.DIRECTORY,
+ children: []
+ }));
+ }
+
+ return (
+
+
(
+
+
+ {isBranch ? : }
+ {element.name}
+
+
+ )}
+ />
+
+ );
+}
+
+function FolderIcon({isOpen}: { isOpen: boolean }) {
+ return isOpen ? : ;
+}
+
+function FileIcon({fileName}: { fileName: string }) {
+ return ;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/input/GameCoverPicker.tsx b/app/src/main/frontend/components/general/input/GameCoverPicker.tsx
new file mode 100644
index 0000000..7049322
--- /dev/null
+++ b/app/src/main/frontend/components/general/input/GameCoverPicker.tsx
@@ -0,0 +1,45 @@
+import {Image, useDisclosure} from "@heroui/react";
+import {GameCoverFallback} from "Frontend/components/general/covers/GameCoverFallback";
+import React from "react";
+import {useField} from "formik";
+import {GameCoverPickerModal} from "Frontend/components/general/modals/GameCoverPickerModal";
+import {Pencil} from "@phosphor-icons/react";
+
+
+// @ts-ignore
+export default function GameCoverPicker({game, label, showErrorUntouched = false, ...props}) {
+
+ // @ts-ignore
+ const [field] = useField(props);
+
+ const gameCoverPickerModal = useDisclosure();
+
+ return (<>
+
+ field.onChange({target: {name: field.name, value: coverUrl}})}
+ />
+ >);
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/input/Input.tsx b/app/src/main/frontend/components/general/input/Input.tsx
new file mode 100644
index 0000000..6acfa03
--- /dev/null
+++ b/app/src/main/frontend/components/general/input/Input.tsx
@@ -0,0 +1,23 @@
+import {useField} from "formik";
+import {Input as NextUiInput} from "@heroui/react";
+
+// @ts-ignore
+const Input = ({label, showErrorUntouched = false, ...props}) => {
+ // @ts-ignore
+ const [field, meta] = useField(props);
+
+ return (
+
+ );
+}
+
+export default Input;
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/input/SelectInput.tsx b/app/src/main/frontend/components/general/input/SelectInput.tsx
new file mode 100644
index 0000000..db27286
--- /dev/null
+++ b/app/src/main/frontend/components/general/input/SelectInput.tsx
@@ -0,0 +1,30 @@
+import {useField} from "formik";
+import {Select, SelectItem} from "@heroui/react";
+
+// @ts-ignore
+const SelectInput = ({label, values, ...props}) => {
+ // @ts-ignore
+ const [field, meta] = useField(props);
+
+ const items = values.map((v: string) => ({key: v, label: v}));
+
+ return (
+
+
+ {(item: { key: string, label: string }) => {item.label} }
+
+
+ );
+}
+
+export default SelectInput;
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/input/TextAreaInput.tsx b/app/src/main/frontend/components/general/input/TextAreaInput.tsx
new file mode 100644
index 0000000..2d58425
--- /dev/null
+++ b/app/src/main/frontend/components/general/input/TextAreaInput.tsx
@@ -0,0 +1,21 @@
+import {useField} from "formik";
+import {Textarea} from "@heroui/react";
+
+// @ts-ignore
+export default function TextAreaInput({label, showErrorUntouched = false, ...props}) {
+ // @ts-ignore
+ const [field, meta] = useField(props);
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/library/LibraryManagementDetails.tsx b/app/src/main/frontend/components/general/library/LibraryManagementDetails.tsx
new file mode 100644
index 0000000..23cbb23
--- /dev/null
+++ b/app/src/main/frontend/components/general/library/LibraryManagementDetails.tsx
@@ -0,0 +1,92 @@
+import LibraryDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryDto";
+import {Check} from "@phosphor-icons/react";
+import {addToast, Button} from "@heroui/react";
+import React from "react";
+import {Form, Formik} from "formik";
+import {deepDiff} from "Frontend/util/utils";
+import LibraryUpdateDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryUpdateDto";
+import {LibraryEndpoint} from "Frontend/generated/endpoints";
+import Input from "Frontend/components/general/input/Input";
+import DirectoryMappingInput from "Frontend/components/general/input/DirectoryMappingInput";
+import Section from "Frontend/components/general/Section";
+import {useNavigate} from "react-router";
+import * as Yup from "yup";
+
+interface LibraryManagementDetailsProps {
+ library: LibraryDto;
+}
+
+export default function LibraryManagementDetails({library}: LibraryManagementDetailsProps) {
+ const navigate = useNavigate();
+ const [librarySaved, setLibrarySaved] = React.useState(false);
+
+ async function handleSubmit(values: LibraryDto): Promise {
+ const changed = deepDiff(library, values) as LibraryUpdateDto;
+
+ if (Object.keys(changed).length === 0) return;
+
+ changed.id = library.id;
+ await LibraryEndpoint.updateLibrary(changed);
+ setLibrarySaved(true);
+ setTimeout(() => setLibrarySaved(false), 2000);
+ }
+
+ async function handleDelete(): Promise {
+ try {
+ await LibraryEndpoint.deleteLibrary(library.id);
+
+ addToast({
+ title: "Library deleted",
+ description: `Library ${library.name} deleted!`,
+ color: "success"
+ });
+
+ navigate("/administration/libraries");
+ } catch (e) {
+ addToast({
+ title: "Error deleting library",
+ description: `Library ${library.name} could not be deleted!`,
+ color: "warning"
+ });
+ }
+ }
+
+ return
+ {(formik) => (
+
+ )}
+ ;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/library/LibraryManagementGames.tsx b/app/src/main/frontend/components/general/library/LibraryManagementGames.tsx
new file mode 100644
index 0000000..de50c1b
--- /dev/null
+++ b/app/src/main/frontend/components/general/library/LibraryManagementGames.tsx
@@ -0,0 +1,233 @@
+import LibraryDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryDto";
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import {
+ Button,
+ Input,
+ Link,
+ Pagination,
+ Select,
+ SelectItem,
+ SortDescriptor,
+ Table,
+ TableBody,
+ TableCell,
+ TableColumn,
+ TableHeader,
+ TableRow,
+ Tooltip,
+ useDisclosure
+} from "@heroui/react";
+import {CheckCircle, MagnifyingGlass, Pencil, Trash} from "@phosphor-icons/react";
+import {useSnapshot} from "valtio/react";
+import {gameState} from "Frontend/state/GameState";
+import {GameEndpoint} from "Frontend/generated/endpoints";
+import GameUpdateDto from "Frontend/generated/org/gameyfin/app/games/dto/GameUpdateDto";
+import {useMemo, useState} from "react";
+import EditGameMetadataModal from "Frontend/components/general/modals/EditGameMetadataModal";
+import MatchGameModal from "Frontend/components/general/modals/MatchGameModal";
+
+interface LibraryManagementGamesProps {
+ library: LibraryDto;
+}
+
+export default function LibraryManagementGames({library}: LibraryManagementGamesProps) {
+ const rowsPerPage = 25;
+
+ const state = useSnapshot(gameState);
+ const games = state.gamesByLibraryId[library.id] ? state.gamesByLibraryId[library.id] as GameDto[] : [];
+ const [searchTerm, setSearchTerm] = useState("");
+ const [filter, setFilter] = useState<"all" | "confirmed" | "nonConfirmed">("all");
+ const [sortDescriptor, setSortDescriptor] = useState({column: "title", direction: "ascending"});
+
+ const [selectedGame, setSelectedGame] = useState(games[0]);
+ const editGameModal = useDisclosure();
+ const matchGameModal = useDisclosure();
+
+ const [page, setPage] = useState(1);
+ const pages = useMemo(() => {
+ return Math.ceil(getFilteredGames().length / rowsPerPage);
+ }, [games, filter]);
+
+ const filteredItems = useMemo(() => {
+ return getFilteredGames();
+ }, [games, filter, searchTerm]);
+
+ const sortedItems = useMemo(() => {
+ return filteredItems.slice().sort((a, b) => {
+ let cmp: number;
+
+ switch (sortDescriptor.column) {
+ case "title":
+ cmp = a.title.localeCompare(b.title);
+ break;
+ case "addedToLibrary":
+ cmp = new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
+ break;
+ case "downloadCount":
+ cmp = a.metadata.downloadCount - b.metadata.downloadCount;
+ break;
+ default:
+ return 0; // No sorting if the column is not recognized
+ }
+
+ if (sortDescriptor.direction === "descending") {
+ cmp *= -1; // Reverse the comparison if sorting in descending order
+ }
+
+ return cmp;
+ });
+ }, [filteredItems, sortDescriptor]);
+
+ const pagedItems = useMemo(() => {
+ const start = (page - 1) * rowsPerPage;
+ const end = start + rowsPerPage;
+ return sortedItems.slice(start, end);
+ }, [page, sortedItems]);
+
+
+ function getFilteredGames() {
+ let filteredGames = games.filter((game) =>
+ game.metadata.path!!.toLowerCase().includes(searchTerm.toLowerCase()) ||
+ game.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
+ game.publishers?.some(publisher => publisher.toLowerCase().includes(searchTerm.toLowerCase())) ||
+ game.developers?.some(developer => developer.toLowerCase().includes(searchTerm.toLowerCase()))
+ )
+
+ if (filter === "confirmed") {
+ return filteredGames.filter(g => g.metadata.matchConfirmed);
+ }
+ if (filter === "nonConfirmed") {
+ return filteredGames.filter(g => !g.metadata.matchConfirmed);
+ }
+ return filteredGames;
+ }
+
+ async function toggleMatchConfirmed(game: GameDto) {
+ await GameEndpoint.updateGame(
+ {
+ id: game.id,
+ metadata: {matchConfirmed: !game.metadata.matchConfirmed}
+ } as GameUpdateDto
+ )
+ }
+
+ async function deleteGame(game: GameDto) {
+ await GameEndpoint.deleteGame(game.id);
+ }
+
+ return selectedGame &&
+
Manage games in library
+
+ setSearchTerm(e.target.value)}
+ onClear={() => setSearchTerm("")}
+ />
+ setFilter(Array.from(keys)[0] as any)}
+ className="w-64"
+ >
+ Show all
+ Show only confirmed
+ Show only non confirmed
+
+
+
+ {pagedItems.length > 0 &&
+ setPage(page)}
+ />}
+
+ }>
+
+ Game
+ Added to library
+ Download count
+ Path
+ {/* width={1} keeps the column as far to the right as possible*/}
+ Actions
+
+
+ {(item) => (
+
+
+ {item.title} ({item.release !== undefined ? new Date(item.release).getFullYear() : "unknown"})
+
+
+
+ {new Date(item.createdAt).toLocaleString()}
+
+
+ {item.metadata.downloadCount}
+
+
+ {item.metadata.path}
+
+
+
+
toggleMatchConfirmed(item)}>
+ {item.metadata.matchConfirmed ?
+
+
+ :
+
+
+ }
+
+
{
+ setSelectedGame(item);
+ editGameModal.onOpenChange();
+ }}>
+
+
+
+
+
{
+ setSelectedGame(item);
+ matchGameModal.onOpenChange();
+ }}>
+
+
+
+
+
deleteGame(item)}>
+
+
+
+
+
+
+
+ )}
+
+
+
+
+ ;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/library/LibraryManagementUnmatchedPaths.tsx b/app/src/main/frontend/components/general/library/LibraryManagementUnmatchedPaths.tsx
new file mode 100644
index 0000000..d1925f6
--- /dev/null
+++ b/app/src/main/frontend/components/general/library/LibraryManagementUnmatchedPaths.tsx
@@ -0,0 +1,148 @@
+import LibraryDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryDto";
+import {
+ Button,
+ Input,
+ Pagination,
+ SortDescriptor,
+ Table,
+ TableBody,
+ TableCell,
+ TableColumn,
+ TableHeader,
+ TableRow,
+ Tooltip,
+ useDisclosure
+} from "@heroui/react";
+import {MagnifyingGlass, Trash} from "@phosphor-icons/react";
+import {LibraryEndpoint} from "Frontend/generated/endpoints";
+import {useMemo, useState} from "react";
+import LibraryUpdateDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryUpdateDto";
+import {fileNameFromPath, hashCode} from "Frontend/util/utils";
+import MatchGameModal from "Frontend/components/general/modals/MatchGameModal";
+
+interface LibraryManagementUnmatchedPathsProps {
+ library: LibraryDto;
+}
+
+export default function LibraryManagementUnmatchedPaths({library}: LibraryManagementUnmatchedPathsProps) {
+ const matchGameModal = useDisclosure();
+ const [page, setPage] = useState(1);
+ const rowsPerPage = 25;
+
+ const [searchTerm, setSearchTerm] = useState("");
+ const [selectedPath, setSelectedPath] = useState(library.unmatchedPaths ? library.unmatchedPaths[0] : null);
+ const [sortDescriptor, setSortDescriptor] = useState({column: "path", direction: "ascending"});
+
+ const pages = useMemo(() => {
+ return Math.ceil(getFilteredPaths().length / rowsPerPage);
+ }, [library.unmatchedPaths, searchTerm]);
+
+ const filteredPaths = useMemo(() => {
+ return library.unmatchedPaths!
+ .filter((path) => path.toLowerCase().includes(searchTerm.toLowerCase()))
+ .map((path) => ({key: hashCode(path), path}));
+ }, [library, searchTerm]);
+
+ const sortedPaths = useMemo(() => {
+ return filteredPaths.slice().sort((a, b) => {
+ let cmp: number;
+ switch (sortDescriptor.column) {
+ case "path":
+ cmp = a.path.localeCompare(b.path);
+ break;
+ default:
+ cmp = 0;
+ }
+ if (sortDescriptor.direction === "descending") {
+ cmp *= -1;
+ }
+ return cmp;
+ });
+ }, [filteredPaths, sortDescriptor]);
+
+ const pagedPaths = useMemo(() => {
+ const start = (page - 1) * rowsPerPage;
+ const end = start + rowsPerPage;
+ return sortedPaths.slice(start, end);
+ }, [page, sortedPaths]);
+
+ async function deleteUnmatchedPath(unmatchedPath: string) {
+ const libraryUpdateDto: LibraryUpdateDto = {
+ id: library.id,
+ unmatchedPaths: library.unmatchedPaths!.filter((path) => path !== unmatchedPath)
+ }
+ await LibraryEndpoint.updateLibrary(libraryUpdateDto);
+ }
+
+ function getFilteredPaths() {
+ return library.unmatchedPaths!!.filter((path) =>
+ path.toLowerCase().includes(searchTerm.toLowerCase())
+ )
+ }
+
+ return
+
Manage unmatched paths
+
setSearchTerm(e.target.value)}
+ onClear={() => setSearchTerm("")}
+ />
+
+ {pagedPaths.length > 0 &&
+ setPage(page)}
+ />}
+
+ }>
+
+ Path
+ Actions
+
+
+ {(item) => (
+
+
+ {item.path}
+
+
+
+
+ {
+ setSelectedPath(item.path);
+ matchGameModal.onOpenChange();
+ }}>
+
+
+
+
+ deleteUnmatchedPath(item.path)}>
+
+
+
+
+
+ )}
+
+
+ {selectedPath &&
+ }
+ ;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/AssignRolesModal.tsx b/app/src/main/frontend/components/general/modals/AssignRolesModal.tsx
new file mode 100644
index 0000000..58598c1
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/AssignRolesModal.tsx
@@ -0,0 +1,117 @@
+import React, {useEffect, useState} from "react";
+import {
+ Button,
+ Modal,
+ ModalBody,
+ ModalContent,
+ ModalFooter,
+ ModalHeader,
+ Select,
+ SelectedItems,
+ Selection,
+ SelectItem
+} from "@heroui/react";
+import {UserEndpoint} from "Frontend/generated/endpoints";
+import UserInfoDto from "Frontend/generated/org/gameyfin/app/users/dto/UserInfoDto";
+import RoleChip from "Frontend/components/general/RoleChip";
+import RoleAssignmentResult from "Frontend/generated/org/gameyfin/app/users/enums/RoleAssignmentResult";
+
+interface AssignRolesModalProps {
+ isOpen: boolean;
+ onOpenChange: () => void;
+ user: UserInfoDto;
+}
+
+interface Role {
+ id: string;
+}
+
+export default function AssignRolesModal({isOpen, onOpenChange, user}: AssignRolesModalProps) {
+ const [availableRoles, setAvailableRoles] = useState([]);
+ const [selectedRole, setSelectedRole] = useState();
+ const [error, setError] = useState();
+
+ useEffect(() => {
+ setSelectedRole(rolesToSelection(user.roles));
+ UserEndpoint.getRolesBelow().then((availableRoles) => {
+ setAvailableRoles(availableRoles.map((role) => ({id: role.toString()})));
+ });
+ }, []);
+
+ function rolesToSelection(roles: Array): Selection {
+ return new Set(roles.map((role) => role.toString()));
+ }
+
+ async function assignRoles() {
+ if (!selectedRole) return;
+
+ let selectedRolesArray = Array.from(selectedRole).map((role) => role.toString());
+ let result = await UserEndpoint.assignRoles(user.username, selectedRolesArray);
+ switch (result) {
+ case RoleAssignmentResult.SUCCESS:
+ window.location.reload();
+ break;
+ case RoleAssignmentResult.NO_ROLES_PROVIDED:
+ setError("Select at least one role");
+ break;
+ case RoleAssignmentResult.TARGET_POWER_LEVEL_TOO_HIGH:
+ setError("Power level of user too high");
+ break;
+ case RoleAssignmentResult.ASSIGNED_ROLE_POWER_LEVEL_TOO_HIGH:
+ setError("Power level of assigned role too high");
+ break;
+ default:
+ setError("An error occurred");
+ break;
+ }
+ }
+
+ return (
+
+
+ {(onClose) => (
+ <>
+ Assign roles to {user.username}
+
+ ) => {
+ return (
+
+ {items.map((item) => (
+
+ ))}
+
+ );
+ }}
+ >
+ {(role) => (
+
+
+
+ )}
+
+ {error &&
+ {error}
+ }
+
+
+
+ Cancel
+
+
+ Assign roles
+
+
+ >
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/ConfirmUserDeletionModal.tsx b/app/src/main/frontend/components/general/modals/ConfirmUserDeletionModal.tsx
new file mode 100644
index 0000000..066a383
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/ConfirmUserDeletionModal.tsx
@@ -0,0 +1,52 @@
+import React, {useEffect, useState} from "react";
+import {Button, Code, Input, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react";
+import {UserEndpoint} from "Frontend/generated/endpoints";
+import UserInfoDto from "Frontend/generated/org/gameyfin/app/users/dto/UserInfoDto";
+
+interface ConfirmUserDeletionModalProps {
+ isOpen: boolean;
+ onOpenChange: () => void;
+ user: UserInfoDto;
+}
+
+export default function ConfirmUserDeletionModal({isOpen, onOpenChange, user}: ConfirmUserDeletionModalProps) {
+ const [confirmUsername, setConfirmUsername] = useState("");
+
+ useEffect(() => {
+ setConfirmUsername("");
+ }, []);
+
+ async function deleteUser() {
+ await UserEndpoint.deleteUserByName(user.username);
+ window.location.reload();
+ }
+
+ return (
+
+
+ {(onClose) => (
+ <>
+ Confirm user deletion
+
+
+ Confirm deletion of user {user.username} by entering the username
+ below
+
+ setConfirmUsername(e.target.value)}/>
+
+
+
+ Cancel
+
+
+ Confirm deletion
+
+
+ >
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/EditGameMetadataModal.tsx b/app/src/main/frontend/components/general/modals/EditGameMetadataModal.tsx
new file mode 100644
index 0000000..b4886c7
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/EditGameMetadataModal.tsx
@@ -0,0 +1,112 @@
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import {
+ Accordion,
+ AccordionItem,
+ Button,
+ Modal,
+ ModalBody,
+ ModalContent,
+ ModalFooter,
+ ModalHeader
+} from "@heroui/react";
+import {Form, Formik} from "formik";
+import Input from "Frontend/components/general/input/Input";
+import React from "react";
+import GameUpdateDto from "Frontend/generated/org/gameyfin/app/games/dto/GameUpdateDto";
+import {deepDiff} from "Frontend/util/utils";
+import {GameEndpoint} from "Frontend/generated/endpoints";
+import TextAreaInput from "Frontend/components/general/input/TextAreaInput";
+import * as Yup from "yup";
+import GameCoverPicker from "Frontend/components/general/input/GameCoverPicker";
+import DatePickerInput from "Frontend/components/general/input/DatePickerInput";
+import ArrayInput from "Frontend/components/general/input/ArrayInput";
+
+interface EditGameMetadataModalProps {
+ game: GameDto;
+ isOpen: boolean;
+ onOpenChange: () => void;
+}
+
+export default function EditGameMetadataModal({game, isOpen, onOpenChange}: EditGameMetadataModalProps) {
+ return (
+
+
+ {(onClose) => {
+
+ async function updateGame(values: GameUpdateDto) {
+ //@ts-ignore
+ const changed = deepDiff(game, values) as GameUpdateDto;
+ if (Object.keys(changed).length === 0) return;
+
+ changed.id = game.id;
+ await GameEndpoint.updateGame(changed);
+ onClose();
+ }
+
+ return (
+
+ {(formik: any) => (
+
+ )}
+
+ )
+ }}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/GameCoverPickerModal.tsx b/app/src/main/frontend/components/general/modals/GameCoverPickerModal.tsx
new file mode 100644
index 0000000..cab5ff9
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/GameCoverPickerModal.tsx
@@ -0,0 +1,110 @@
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import {Button, Image, Input, Modal, ModalBody, ModalContent, ModalHeader, ScrollShadow} from "@heroui/react";
+import React, {useEffect, useState} from "react";
+import GameSearchResultDto from "Frontend/generated/org/gameyfin/app/games/dto/GameSearchResultDto";
+import {GameEndpoint} from "Frontend/generated/endpoints";
+import {ArrowRight, MagnifyingGlass} from "@phosphor-icons/react";
+
+interface GameCoverPickerModalProps {
+ game: GameDto;
+ isOpen: boolean;
+ onOpenChange: () => void;
+ setCoverUrl: (url: string) => void;
+}
+
+export function GameCoverPickerModal({game, isOpen, onOpenChange, setCoverUrl}: GameCoverPickerModalProps) {
+ const [coverUrl, setCoverUrlState] = useState("");
+
+ const [searchTerm, setSearchTerm] = useState(game.title);
+ const [searchResults, setSearchResults] = useState([]);
+ const [isSearching, setIsSearching] = useState(false)
+
+ useEffect(() => {
+ if (isOpen && searchTerm.length > 0 && searchResults.length === 0) {
+ search();
+ }
+ }, [isOpen]);
+
+ async function search() {
+ setIsSearching(true);
+ const results = await GameEndpoint.getPotentialMatches(searchTerm, false);
+ let validResults = results.filter(result => result.coverUrl && result.coverUrl.length > 0 && result.coverUrl !== "null");
+ setSearchResults(validResults);
+ setIsSearching(false);
+ }
+
+ return (
+
+
+ {(onClose) => {
+ return (<>
+
+ Enter a URL or search for a cover
+
+
+
+
setCoverUrlState("")}
+ />
+
{
+ setCoverUrl(coverUrl);
+ onClose();
+ }}>
+
+
+
+
+ {
+ if (e.key === "Enter") {
+ e.preventDefault();
+ await search();
+ }
+ }}
+ />
+
+
+
+
+ {searchResults.length === 0 && !isSearching &&
+ No results found.
+ }
+ {searchResults.length === 0 && isSearching &&
+ Searching...
+ }
+
+ {searchResults.map((result) => (
+ {
+ setCoverUrl(result.coverUrl!);
+ onClose();
+ }}>
+
+
+
+ ))}
+
+
+ >)
+ }}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/InviteUserModal.tsx b/app/src/main/frontend/components/general/modals/InviteUserModal.tsx
new file mode 100644
index 0000000..13b5bdf
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/InviteUserModal.tsx
@@ -0,0 +1,65 @@
+import React, {useEffect, useState} from "react";
+import {addToast, Button, Input, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react";
+import {RegistrationEndpoint, UserEndpoint} from "Frontend/generated/endpoints";
+
+interface InviteUserModalProps {
+ isOpen: boolean;
+ onOpenChange: () => void;
+}
+
+export default function InviteUserModal({isOpen, onOpenChange}: InviteUserModalProps) {
+ const [email, setEmail] = useState();
+ const [error, setError] = useState();
+
+ useEffect(() => {
+ setEmail(null);
+ setError(null);
+ }, []);
+
+ async function inviteUser(onClose: () => void) {
+ if (!email) return;
+
+ if (await UserEndpoint.existsByMail(email)) {
+ setError("User with this email already exists");
+ return;
+ }
+
+ try {
+ await RegistrationEndpoint.createInvitation(email);
+ addToast({
+ title: "Invitation sent",
+ description: "The user will receive an email with further instructions shortly.",
+ color: "success"
+ });
+ onClose();
+ } catch (e) {
+ setError("Failed to create invitation");
+ }
+ }
+
+ return (
+
+
+ {(onClose) => (
+ <>
+ Invite a new user
+
+ Enter the email address of the user you want to invite:
+ setEmail(e.target.value)} type="email"/>
+ {error && {error} }
+
+
+
+ Cancel
+
+ inviteUser(onClose)}
+ isDisabled={email === null || email === undefined || email.length < 1}>
+ Send invitation
+
+
+ >
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/LibraryCreationModal.tsx b/app/src/main/frontend/components/general/modals/LibraryCreationModal.tsx
new file mode 100644
index 0000000..bc4f2d1
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/LibraryCreationModal.tsx
@@ -0,0 +1,103 @@
+import React, {useState} from "react";
+import {addToast, Button, Checkbox, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react";
+import {Form, Formik} from "formik";
+import LibraryDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryDto";
+import {LibraryEndpoint} from "Frontend/generated/endpoints";
+import Input from "Frontend/components/general/input/Input";
+import * as Yup from "yup";
+import DirectoryMappingInput from "Frontend/components/general/input/DirectoryMappingInput";
+
+interface LibraryCreationModalProps {
+ libraries: LibraryDto[];
+ setLibraries: (libraries: LibraryDto[]) => void;
+ isOpen: boolean;
+ onOpenChange: () => void;
+}
+
+export default function LibraryCreationModal({
+ libraries,
+ isOpen,
+ onOpenChange
+ }: LibraryCreationModalProps) {
+
+ const [scanAfterCreation, setScanAfterCreation] = useState(true);
+
+ async function createLibrary(library: LibraryDto) {
+ try {
+ await LibraryEndpoint.createLibrary(library as LibraryDto, scanAfterCreation);
+
+ addToast({
+ title: "New library created",
+ description: `Library ${library.name} created!`,
+ color: "success"
+ });
+ } catch (e) {
+ addToast({
+ title: "Error creating library",
+ description: `Library ${library.name} could not be created!`,
+ color: "warning"
+ });
+ throw "Error creating library: " + e;
+ }
+ }
+
+ return (
+ <>
+
+
+ {(onClose) => (
+ {
+ await createLibrary(values);
+ onClose();
+ }}
+ >
+ {(formik) =>
+
+ }
+
+ )}
+
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/MatchGameModal.tsx b/app/src/main/frontend/components/general/modals/MatchGameModal.tsx
new file mode 100644
index 0000000..bacc7c1
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/MatchGameModal.tsx
@@ -0,0 +1,152 @@
+import {
+ Button,
+ Input,
+ Modal,
+ ModalBody,
+ ModalContent,
+ Table,
+ TableBody,
+ TableCell,
+ TableColumn,
+ TableHeader,
+ TableRow,
+ Tooltip
+} from "@heroui/react";
+import React, {useEffect, useState} from "react";
+import {ArrowRight, MagnifyingGlass} from "@phosphor-icons/react";
+import {GameEndpoint} from "Frontend/generated/endpoints";
+import GameSearchResultDto from "Frontend/generated/org/gameyfin/app/games/dto/GameSearchResultDto";
+import PluginIcon from "../plugin/PluginIcon";
+
+interface EditGameMetadataModalProps {
+ path: string;
+ libraryId: number;
+ replaceGameId?: number;
+ initialSearchTerm: string;
+ isOpen: boolean;
+ onOpenChange: () => void;
+}
+
+export default function MatchGameModal({
+ path,
+ libraryId,
+ replaceGameId,
+ initialSearchTerm,
+ isOpen,
+ onOpenChange
+ }: EditGameMetadataModalProps) {
+ const [searchTerm, setSearchTerm] = useState("");
+ const [searchResults, setSearchResults] = useState([]);
+ const [isSearching, setIsSearching] = useState(false);
+ const [isMatching, setIsMatching] = useState(null);
+
+ useEffect(() => {
+ setSearchTerm(initialSearchTerm);
+ setSearchResults([]);
+ }, [isOpen]);
+
+ async function matchGame(result: GameSearchResultDto) {
+ await GameEndpoint.matchManually(result.originalIds, path, libraryId, replaceGameId);
+ }
+
+ async function search() {
+ setIsSearching(true);
+ const results = await GameEndpoint.getPotentialMatches(searchTerm, true);
+ setSearchResults(results);
+ setIsSearching(false);
+ }
+
+ return (
+
+
+ {(onClose) => (
+
+
+
+ {
+ if (e.key === "Enter") {
+ e.preventDefault();
+ await search();
+ }
+ }}
+ />
+
+
+
+
+
+
+
+
+ Title & Release
+ Developer(s)
+ Publisher(s)
+ {/* width={1} keeps the column as far to the right as possible*/}
+ Sources
+
+
+
+ {(item) => (
+
+
+ {item.title} ({item.release ? new Date(item.release).getFullYear() : "unknown"})
+
+
+
+ {item.developers ? item.developers.map(
+ developer =>
{developer}
+ ) : "unknown"}
+
+
+
+
+ {item.publishers ? item.publishers.map(
+ publisher =>
{publisher}
+ ) : "unknown"}
+
+
+
+
+ {Object.values(item.originalIds).map(
+ originalId =>
+ )}
+
+
+
+
+ {
+ setIsMatching(item.id);
+ await matchGame(item);
+ setIsMatching(null);
+ onClose();
+ }}>
+
+
+
+
+
+ )}
+
+
+
+
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/PasswordResetModal.tsx b/app/src/main/frontend/components/general/modals/PasswordResetModal.tsx
new file mode 100644
index 0000000..d3d3411
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/PasswordResetModal.tsx
@@ -0,0 +1,76 @@
+import React, {useEffect, useState} from "react";
+import {addToast, Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react";
+import {Input as NextInput} from "@heroui/input";
+import {WarningCircle} from "@phosphor-icons/react";
+import {MessageEndpoint, PasswordResetEndpoint} from "Frontend/generated/endpoints";
+
+interface PasswordResetModalProps {
+ isOpen: boolean;
+ onOpenChange: () => void;
+}
+
+export default function PasswordResetModal({
+ isOpen,
+ onOpenChange
+ }: PasswordResetModalProps) {
+ const [canResetPassword, setCanResetPassword] = useState(false);
+ const [resetEmail, setResetEmail] = useState();
+
+ useEffect(() => {
+ MessageEndpoint.isEnabled().then(setCanResetPassword);
+ }, []);
+
+ async function resetPassword() {
+ if (!resetEmail) return;
+
+ await PasswordResetEndpoint.requestPasswordReset(resetEmail);
+ addToast({
+ title: "Password reset requested",
+ description: "If the email address is registered, you will receive a message with further instructions.",
+ color: "success"
+ });
+ }
+
+ return (
+
+
+ {(onClose) => (
+ <>
+ Request a password reset
+
+ {canResetPassword ?
+ {
+ setResetEmail(event.target.value);
+ }}
+ type="email"
+ placeholder="Email"
+ /> :
+
+
+
+ Password self-service is disabled.
+ To reset your password please contact your administrator.
+
+
+ }
+
+
+
+ Cancel
+
+ {
+ await resetPassword();
+ onClose();
+ }}>
+ Send request
+
+
+ >
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/PasswortResetTokenModal.tsx b/app/src/main/frontend/components/general/modals/PasswortResetTokenModal.tsx
new file mode 100644
index 0000000..6574079
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/PasswortResetTokenModal.tsx
@@ -0,0 +1,65 @@
+import React, {useEffect, useState} from "react";
+import {Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, Snippet} from "@heroui/react";
+import TokenDto from "Frontend/generated/org/gameyfin/app/shared/token/TokenDto";
+import {timeUntil} from "Frontend/util/utils";
+
+interface PasswordResetTokenModalProps {
+ isOpen: boolean;
+ onOpenChange: () => void;
+ token: TokenDto;
+}
+
+export default function PasswordResetTokenModal({isOpen, onOpenChange, token}: PasswordResetTokenModalProps) {
+ const [timeUntilExpiry, setTimeUntilExpiry] = useState("");
+
+ const timeoutRefresh = setInterval(updateTimeUntilExpiry, 1000);
+
+ useEffect(updateTimeUntilExpiry, [token]);
+
+ useEffect(() => {
+ return () => {
+ clearInterval(timeoutRefresh);
+ };
+ }, []);
+
+ function passwordResetLink() {
+ return `${document.baseURI}reset-password?token=${token.secret}`;
+ }
+
+ function updateTimeUntilExpiry() {
+ if (!token) return;
+ setTimeUntilExpiry(timeUntil(token.expiresAt as string));
+ }
+
+ return (
+
+
+ {(onClose) => (
+ <>
+
+ The user can reset their password using the following link
+
+
+ {passwordResetLink()}
+ {
+ !timeUntilExpiry.endsWith("ago")
+ ?
+ This link will expire {timeUntilExpiry}
+
+ :
+ This link has expired {timeUntilExpiry}
+
+ }
+
+
+
+ OK
+
+
+ >
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/PathPickerModal.tsx b/app/src/main/frontend/components/general/modals/PathPickerModal.tsx
new file mode 100644
index 0000000..3db7420
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/PathPickerModal.tsx
@@ -0,0 +1,80 @@
+import {Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react";
+import {Form, Formik} from "formik";
+import React, {useEffect, useState} from "react";
+import Input from "Frontend/components/general/input/Input";
+import FileTreeView from "Frontend/components/general/input/FileTreeView";
+import DirectoryMappingDto from "Frontend/generated/org/gameyfin/app/libraries/dto/DirectoryMappingDto";
+import {ArrowRight} from "@phosphor-icons/react";
+
+interface PathPickerModalProps {
+ returnSelectedPath: (path: DirectoryMappingDto) => void;
+ isOpen: boolean;
+ onOpenChange: () => void;
+}
+
+export default function PathPickerModal({returnSelectedPath, isOpen, onOpenChange}: PathPickerModalProps) {
+ const [internalPath, setInternalPath] = useState("");
+ const [externalPath, setExternalPath] = useState("");
+
+ return (
+
+
+ {(onClose) => (
+ {
+ returnSelectedPath(values);
+ setInternalPath("");
+ setExternalPath("");
+ onClose();
+ }}>
+ {(formik) => {
+ useEffect(() => {
+ formik.setFieldValue("internalPath", internalPath);
+ }, [internalPath]);
+
+ return (
+
+ );
+ }}
+
+ )}
+
+
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/PluginDetailsModal.tsx b/app/src/main/frontend/components/general/modals/PluginDetailsModal.tsx
new file mode 100644
index 0000000..bc8cb72
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/PluginDetailsModal.tsx
@@ -0,0 +1,201 @@
+import React, {useState} from "react";
+import {addToast, Button, Link, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, Tooltip} from "@heroui/react";
+import {Form, Formik} from "formik";
+import PluginLogo from "Frontend/components/general/plugin/PluginLogo";
+import Markdown from "react-markdown";
+import remarkBreaks from "remark-breaks";
+import {PluginEndpoint} from "Frontend/generated/endpoints";
+import PluginDto from "Frontend/generated/org/gameyfin/app/core/plugins/dto/PluginDto";
+import {ArrowClockwise} from "@phosphor-icons/react";
+import PluginConfigMetadataDto from "Frontend/generated/org/gameyfin/app/core/plugins/dto/PluginConfigMetadataDto";
+import PluginConfigFormField from "Frontend/components/general/plugin/PluginConfigFormField";
+
+interface PluginDetailsModalProps {
+ plugin: PluginDto;
+ isOpen: boolean;
+ onOpenChange: () => void;
+}
+
+enum ValidationState {
+ UNCHECKED,
+ VALID,
+ INVALID,
+ IN_PROGRESS
+}
+
+export default function PluginDetailsModal({plugin, isOpen, onOpenChange}: PluginDetailsModalProps) {
+ const [configValidated, setConfigValidated] = useState(ValidationState.UNCHECKED);
+
+ async function saveConfig(values: Record) {
+ await PluginEndpoint.updateConfig(plugin.id, values);
+ addToast({
+ title: "Configuration saved",
+ description: `Configuration for plugin ${plugin.name} saved!`,
+ color: "success"
+ });
+ }
+
+ function getEffectiveConfig(): Record {
+ const effectiveConfig: Record = {};
+ if (!plugin.configMetadata) return effectiveConfig;
+
+ for (const meta of plugin.configMetadata) {
+ const key = meta.key;
+ let value = plugin.config?.[key] ?? meta.default;
+
+ if (value != null) {
+ switch (meta.type.toLowerCase()) {
+ case "float":
+ case "int":
+ effectiveConfig[key] = Number(value);
+ break;
+ case "boolean":
+ effectiveConfig[key] = value === true || value === "true";
+ break;
+ default:
+ effectiveConfig[key] = value.toString();
+ }
+ }
+ }
+ return effectiveConfig;
+ }
+
+ return (
+
+
+ {(onClose) => {
+
+ async function handleSubmit(values: Record): Promise {
+ await saveConfig(values);
+ onClose();
+ }
+
+ return (
+
+ {(formik: any) => (
+
+ )
+ }
+
+ )
+ }}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/PluginPrioritiesModal.tsx b/app/src/main/frontend/components/general/modals/PluginPrioritiesModal.tsx
new file mode 100644
index 0000000..9152608
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/PluginPrioritiesModal.tsx
@@ -0,0 +1,113 @@
+import React from "react";
+import {addToast, Button, Chip, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react";
+import {ListBox, ListBoxItem, useDragAndDrop} from "react-aria-components";
+import {CaretUpDown} from "@phosphor-icons/react";
+import {useListData} from "@react-stately/data";
+import PluginDto from "Frontend/generated/org/gameyfin/app/core/plugins/dto/PluginDto";
+import {PluginEndpoint} from "Frontend/generated/endpoints";
+
+interface PluginPrioritiesModalProps {
+ plugins: PluginDto[];
+ isOpen: boolean;
+ onOpenChange: () => void;
+}
+
+export default function PluginPrioritiesModal({plugins, isOpen, onOpenChange}: PluginPrioritiesModalProps) {
+
+ const sortedPlugins = useListData({
+ initialItems: plugins, // Already sorted in parent
+ getKey: (plugin) => plugin.id
+ });
+
+ let {dragAndDropHooks} = useDragAndDrop({
+ getItems: (keys) =>
+ [...keys].map((key) => ({'text/plain': sortedPlugins.getItem(key)!.name})),
+ onReorder(e) {
+ if (e.keys.has(e.target.key)) return;
+
+ if (e.target.dropPosition === 'before' || e.target.dropPosition === 'on') {
+ sortedPlugins.moveBefore(e.target.key, e.keys);
+ } else if (e.target.dropPosition === 'after') {
+ sortedPlugins.moveAfter(e.target.key, e.keys);
+ }
+
+ // Recalculate priority based on new position (reversed)
+ sortedPlugins.items.forEach((plugin, index) => {
+ const reversedPriority = sortedPlugins.items.length - index;
+ sortedPlugins.update(plugin.id, {...plugin, priority: reversedPriority});
+ });
+ }
+ });
+
+ function generatePrioritiesMap(): Record {
+ let map: Record = {};
+ const totalPlugins = sortedPlugins.items.length;
+ sortedPlugins.items.forEach((plugin, index) => {
+ map[plugin.id] = totalPlugins - index; // Reverse order
+ });
+ return map;
+ }
+
+ async function setPluginPriorities(onClose: () => void) {
+ try {
+ const prioritiesMap = generatePrioritiesMap();
+ await PluginEndpoint.setPluginPriorities(prioritiesMap);
+
+ addToast({
+ title: "Plugin order updated",
+ description: "Plugin order has been updated successfully.",
+ color: "success"
+ });
+ onClose();
+ } catch (e) {
+ addToast({
+ title: "Error",
+ description: "An error occurred while updating plugin order.",
+ color: "warning"
+ });
+ }
+ }
+
+ return (
+
+
+ {(onClose) => (
+ <>
+
+ Edit plugin order
+ Plugins higher on the list are preferred
+
+
+
+ {(plugin: PluginDto) => (
+
+
+
+ {sortedPlugins.items.findIndex(p => p.id === plugin.id) + 1}
+
+
{plugin.name}
+
+
+
+ )}
+
+
+
+
+
+ Cancel
+
+ setPluginPriorities(onClose)}>
+ Save
+
+
+ >
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/modals/SignUpModal.tsx b/app/src/main/frontend/components/general/modals/SignUpModal.tsx
new file mode 100644
index 0000000..4c07005
--- /dev/null
+++ b/app/src/main/frontend/components/general/modals/SignUpModal.tsx
@@ -0,0 +1,111 @@
+import React from "react";
+import {addToast, Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react";
+import {RegistrationEndpoint} from "Frontend/generated/endpoints";
+import UserRegistrationDto from "Frontend/generated/org/gameyfin/app/users/dto/UserRegistrationDto";
+import {Form, Formik} from "formik";
+import * as Yup from "yup";
+import Input from "Frontend/components/general/input/Input";
+
+interface SignUpModalProps {
+ isOpen: boolean;
+ onOpenChange: () => void;
+}
+
+export default function SignUpModal({
+ isOpen,
+ onOpenChange
+ }: SignUpModalProps) {
+
+ async function signUp(registration: UserRegistrationDto, onClose: () => void) {
+ try {
+ await RegistrationEndpoint.registerUser({
+ username: registration.username,
+ password: registration.password,
+ email: registration.email
+ });
+
+ onClose();
+
+ addToast({
+ title: "Account created",
+ description: "You will receive an email with further instructions shortly.",
+ color: "success"
+ });
+ } catch (_) {
+ addToast({
+ title: "Registration failed",
+ description: "An error occurred while registering your account.",
+ color: "danger"
+ });
+ return;
+ }
+ }
+
+ return (
+
+
+ {(onClose) => (
+ {
+ let usernameAvailable = await RegistrationEndpoint.isUsernameAvailable(values.username);
+ if (!usernameAvailable) {
+ setFieldError('username', 'Username already taken');
+ return;
+ } else {
+ await signUp(values, onClose);
+ }
+ }}
+ validationSchema={Yup.object({
+ username: Yup.string()
+ .required('Required'),
+ password: Yup.string()
+ .min(8, 'Password must be at least 8 characters long')
+ .required('Required'),
+ email: Yup.string()
+ .email()
+ .required('Required'),
+ passwordRepeat: Yup.string()
+ .equals([Yup.ref('password')], 'Passwords do not match')
+ .required('Required')
+ })}>
+
+
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/plugin/PluginConfigFormField.tsx b/app/src/main/frontend/components/general/plugin/PluginConfigFormField.tsx
new file mode 100644
index 0000000..652e45b
--- /dev/null
+++ b/app/src/main/frontend/components/general/plugin/PluginConfigFormField.tsx
@@ -0,0 +1,59 @@
+import SelectInput from "Frontend/components/general/input/SelectInput";
+import CheckboxInput from "Frontend/components/general/input/CheckboxInput";
+import Input from "Frontend/components/general/input/Input";
+import React from "react";
+import PluginConfigMetadataDto from "Frontend/generated/org/gameyfin/app/core/plugins/dto/PluginConfigMetadataDto";
+
+export default function PluginConfigFormField({pluginConfigMetadata, ...props}: any) {
+ function inputElement(metadata: PluginConfigMetadataDto) {
+
+ if (metadata.allowedValues != null && metadata.allowedValues.length > 0) {
+ return (
+
+ );
+ }
+
+ switch (metadata.type.toLowerCase()) {
+ case "boolean":
+ return (
+
+ );
+ case "string":
+ return (
+
+ );
+ case "float":
+ return (
+
+ );
+ case "int":
+ return (
+
+ );
+ default:
+ return Unsupported type: {metadata.type} for key {metadata.key} ;
+ }
+ }
+
+ return inputElement(pluginConfigMetadata!);
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/plugin/PluginIcon.tsx b/app/src/main/frontend/components/general/plugin/PluginIcon.tsx
new file mode 100644
index 0000000..ec76dd2
--- /dev/null
+++ b/app/src/main/frontend/components/general/plugin/PluginIcon.tsx
@@ -0,0 +1,21 @@
+import {Image, Tooltip} from "@heroui/react";
+import {Plug} from "@phosphor-icons/react";
+import {pluginState} from "Frontend/state/PluginState";
+import {useSnapshot} from "valtio/react";
+
+interface PluginLogoProps {
+ pluginId: string;
+}
+
+export default function PluginIcon({pluginId}: PluginLogoProps) {
+ const state = useSnapshot(pluginState);
+
+ return state.isLoaded && (
+
+ {state.state[pluginId].hasLogo ?
+ :
+
+ }
+
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/plugin/PluginLogo.tsx b/app/src/main/frontend/components/general/plugin/PluginLogo.tsx
new file mode 100644
index 0000000..f4c2a95
--- /dev/null
+++ b/app/src/main/frontend/components/general/plugin/PluginLogo.tsx
@@ -0,0 +1,19 @@
+import {Plug} from "@phosphor-icons/react";
+import React from "react";
+import {Image} from "@heroui/react";
+import PluginDto from "Frontend/generated/org/gameyfin/app/core/plugins/dto/PluginDto";
+
+interface PluginLogoProps {
+ plugin: PluginDto;
+}
+
+export default function PluginLogo({plugin}: PluginLogoProps) {
+ return (
+ <>
+ {plugin.hasLogo ?
+ :
+
+ }
+ >
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/plugin/PluginManagementSection.tsx b/app/src/main/frontend/components/general/plugin/PluginManagementSection.tsx
new file mode 100644
index 0000000..62ca5e8
--- /dev/null
+++ b/app/src/main/frontend/components/general/plugin/PluginManagementSection.tsx
@@ -0,0 +1,42 @@
+import {Button, Tooltip, useDisclosure} from "@heroui/react";
+import {ListNumbers} from "@phosphor-icons/react";
+import {PluginManagementCard} from "Frontend/components/general/cards/PluginManagementCard";
+import React from "react";
+import PluginPrioritiesModal from "Frontend/components/general/modals/PluginPrioritiesModal";
+import {camelCaseToTitle} from "Frontend/util/utils";
+import PluginDto from "Frontend/generated/org/gameyfin/app/core/plugins/dto/PluginDto";
+
+interface PluginManagementSectionProps {
+ type: string;
+ plugins: PluginDto[];
+}
+
+export function PluginManagementSection({type, plugins}: PluginManagementSectionProps) {
+ const pluginPrioritiesModal = useDisclosure();
+
+ return (
+
+
+
{camelCaseToTitle(type)}
+
+
+
+
+
+
+
+
+
+ {plugins.map((plugin) =>
+
+ )}
+
+
+
p.id + p.priority).join(',')} // force re-mount if plugin order changes
+ plugins={[...plugins].sort((a, b) => b.priority - a.priority)}
+ isOpen={pluginPrioritiesModal.isOpen}
+ onOpenChange={pluginPrioritiesModal.onOpenChange}
+ />
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/general/withSideMenu.tsx b/app/src/main/frontend/components/general/withSideMenu.tsx
new file mode 100644
index 0000000..05e1f7e
--- /dev/null
+++ b/app/src/main/frontend/components/general/withSideMenu.tsx
@@ -0,0 +1,62 @@
+import {Outlet} from "react-router";
+import {Icon} from "@phosphor-icons/react";
+import {Listbox, ListboxItem} from "@heroui/react";
+import {ReactElement, useState} from "react";
+
+export type MenuItem = {
+ title: string,
+ url: string,
+ icon: ReactElement
+}
+
+export default function withSideMenu(baseUrl: string, menuItems: MenuItem[]) {
+ return function PageWithSideMenu() {
+ const [selectedItem, setSelectedItem] = useState(initialSelected)
+
+ /**
+ * Remove a "/" at the start if it exists
+ */
+ function key(k: string): string {
+ return k.replace(/^(\/)/, "");
+ }
+
+ /**
+ * If the key starts with "/" assume it's an absolute link, else assume it's relative
+ */
+ function link(l: string): string {
+ if (l.startsWith("/")) return baseUrl + l;
+ return baseUrl + "/" + l;
+ }
+
+ /**
+ * Match the initially selected item by current URL path
+ */
+ function initialSelected(): string {
+ const p = window.location.pathname;
+ const idx = p.indexOf(baseUrl);
+ if (idx === -1) return "";
+ const afterBase = p.substring(idx + baseUrl.length);
+ // Remove leading slash, then split and take the first segment
+ return afterBase.replace(/^\/+/, "").split("/")[0] || "";
+ }
+
+ return (
+
+
+
+ {menuItems.map((i) => (
+ setSelectedItem(i.url)}
+ className={`h-12 ${key(i.url) === selectedItem ? "bg-primary" : ""}`}>
+ {i.title}
+
+ ))}
+
+
+
+
+
+
+ );
+ };
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/theming/GameyfinLogo.tsx b/app/src/main/frontend/components/theming/GameyfinLogo.tsx
new file mode 100644
index 0000000..71b86db
--- /dev/null
+++ b/app/src/main/frontend/components/theming/GameyfinLogo.tsx
@@ -0,0 +1,16 @@
+export default function GameyfinLogo({className}: {
+ className?: string
+}) {
+ return (
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/theming/ThemePreview.tsx b/app/src/main/frontend/components/theming/ThemePreview.tsx
new file mode 100644
index 0000000..aac0125
--- /dev/null
+++ b/app/src/main/frontend/components/theming/ThemePreview.tsx
@@ -0,0 +1,23 @@
+import {Theme} from "Frontend/theming/theme";
+import {Tooltip} from "@heroui/react";
+
+export default function ThemePreview({theme, isSelected}: {
+ theme: Theme,
+ isSelected?: boolean
+}) {
+ return (
+ {theme.name?.replace("-", " ")}} placement="bottom">
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/theming/ThemeSelector.tsx b/app/src/main/frontend/components/theming/ThemeSelector.tsx
new file mode 100644
index 0000000..6d2aaed
--- /dev/null
+++ b/app/src/main/frontend/components/theming/ThemeSelector.tsx
@@ -0,0 +1,82 @@
+import {useTheme} from "next-themes";
+import React, {useEffect, useState} from "react";
+import {Button, Card, Divider, Select, Selection, SelectItem} from "@heroui/react";
+import {themes} from "Frontend/theming/themes";
+import {Theme} from "Frontend/theming/theme";
+import ThemePreview from "Frontend/components/theming/ThemePreview";
+import {toTitleCase} from "Frontend/util/utils";
+import {UserPreferenceService} from "Frontend/util/user-preference-service";
+
+export function ThemeSelector() {
+
+ const {theme, setTheme} = useTheme();
+ const [selectedTheme, setSelectedTheme] = useState(theme?.substring(0, theme?.lastIndexOf("-")));
+ const [selectedMode, setSelectedMode] = useState();
+
+ useEffect(() => {
+ if (!selectedMode)
+ setSelectedMode(new Set([theme?.split('-').pop() ?? "dark"]));
+ }, [theme]);
+
+ useEffect(updateTheme, [selectedTheme, selectedMode]);
+
+ function updateTheme() {
+ if (selectedMode instanceof Set) {
+ let theme = `${selectedTheme}-${selectedMode.values().next().value}`;
+ setTheme(theme);
+ UserPreferenceService.set("preferred-theme", theme).catch(console.error);
+ }
+ }
+
+ return (
+
+
+
+ Light
+
+
+ Dark
+
+
+
+ {
+ //min-w-[468px]
+ themes.map(((t: Theme) => (
+
setSelectedTheme(t.name)}>
+
+
+ )))
+ }
+
+
Preview for theme
+ "{toTitleCase(theme!.replaceAll("-", " "))}"
+
+
+
+
+ Primary
+ Secondary
+ Success
+ Warning
+ Danger
+
+
+ Primary
+ Secondary
+ Success
+ Warning
+ Danger
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/components/wizard/Wizard.tsx b/app/src/main/frontend/components/wizard/Wizard.tsx
new file mode 100644
index 0000000..db9cdb9
--- /dev/null
+++ b/app/src/main/frontend/components/wizard/Wizard.tsx
@@ -0,0 +1,101 @@
+import React, {ReactNode, useState} from "react";
+import {Form, Formik, FormikBag, FormikHelpers} from "formik";
+import {ArrowLeft, ArrowRight, Check} from "@phosphor-icons/react";
+import {Button} from "@heroui/react";
+import {Step, Stepper} from "@material-tailwind/react";
+
+const Wizard = ({children, initialValues, onSubmit}: {
+ children: ReactNode,
+ initialValues: any,
+ onSubmit: (values: any, bag: FormikHelpers | FormikBag) => Promise
+}) => {
+ const [stepNumber, setStepNumber] = useState(0);
+ const steps = React.Children.toArray(children);
+ const [snapshot, setSnapshot] = useState(initialValues);
+
+ const step = steps[stepNumber];
+ const totalSteps = steps.length;
+ const isFirstStep = stepNumber === 0;
+ const isLastStep = stepNumber === totalSteps - 1;
+
+ const next = (values: any) => {
+ setSnapshot(values);
+ setStepNumber(Math.min(stepNumber + 1, totalSteps - 1));
+ };
+
+ const previous = (values: any) => {
+ setSnapshot(values);
+ setStepNumber(Math.max(stepNumber - 1, 0));
+ };
+
+ const handleSubmit = async (values: any, bag: FormikBag | FormikHelpers) => {
+ /*// @ts-ignore*/
+ if (step.props.onSubmit) {
+ /*// @ts-ignore*/
+ await step.props.onSubmit(values, bag);
+ }
+ if (isLastStep) {
+ return onSubmit(values, bag);
+ } else {
+ await bag.setTouched({});
+ next(values);
+ }
+ };
+
+ return (
+
+ {(formik) => (
+
+ )}
+
+ );
+};
+
+export default Wizard;
\ No newline at end of file
diff --git a/app/src/main/frontend/components/wizard/WizardStep.tsx b/app/src/main/frontend/components/wizard/WizardStep.tsx
new file mode 100644
index 0000000..36b2c52
--- /dev/null
+++ b/app/src/main/frontend/components/wizard/WizardStep.tsx
@@ -0,0 +1,11 @@
+import {JSX, ReactNode} from "react";
+import * as Yup from 'yup';
+
+export default function WizardStep({children, icon, validationSchema}: {
+ children: ReactNode,
+ icon: JSX.Element,
+ validationSchema?: Yup.Schema,
+ onSubmit?: (...values: any) => Promise
+}) {
+ return children;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/endpoints/AvatarEndpoint.ts b/app/src/main/frontend/endpoints/AvatarEndpoint.ts
new file mode 100644
index 0000000..86be057
--- /dev/null
+++ b/app/src/main/frontend/endpoints/AvatarEndpoint.ts
@@ -0,0 +1,53 @@
+import {fetchWithAuth} from "Frontend/util/utils";
+import {addToast} from "@heroui/react";
+
+export async function uploadAvatar(avatar: any) {
+ const formData = new FormData();
+ formData.append("file", avatar);
+
+ const response = await fetchWithAuth("images/avatar/upload", formData);
+
+ const result = await response.text();
+
+ if (response.ok) {
+ window.location.reload();
+ } else {
+ addToast({
+ title: "Error uploading avatar",
+ description: result,
+ color: "danger"
+ });
+ }
+}
+
+export async function removeAvatar() {
+ const response = await fetchWithAuth("images/avatar/delete")
+
+ const result = await response.text();
+
+ if (response.ok) {
+ window.location.reload();
+ } else {
+ addToast({
+ title: "Error removing avatar",
+ description: result,
+ color: "danger"
+ });
+ }
+}
+
+export async function removeAvatarByName(name: string) {
+ const response = await fetchWithAuth("images/avatar/deleteByName?" + new URLSearchParams({name: name}))
+
+ const result = await response.text();
+
+ if (response.ok) {
+ window.location.reload();
+ } else {
+ addToast({
+ title: "Error removing avatar",
+ description: result,
+ color: "danger"
+ });
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/endpoints/DownloadEndpoint.ts b/app/src/main/frontend/endpoints/DownloadEndpoint.ts
new file mode 100644
index 0000000..84bd65f
--- /dev/null
+++ b/app/src/main/frontend/endpoints/DownloadEndpoint.ts
@@ -0,0 +1,3 @@
+export function downloadGame(gameId: number, provider: string) {
+ window.open(`/download/${gameId}?provider=${provider}`, '_top');
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/endpoints/endpoints.ts b/app/src/main/frontend/endpoints/endpoints.ts
new file mode 100644
index 0000000..fffe569
--- /dev/null
+++ b/app/src/main/frontend/endpoints/endpoints.ts
@@ -0,0 +1,4 @@
+import * as AvatarEndpoint from './AvatarEndpoint'
+import * as DownloadEndpoint from './DownloadEndpoint'
+
+export {AvatarEndpoint, DownloadEndpoint}
\ No newline at end of file
diff --git a/app/src/main/frontend/index.html b/app/src/main/frontend/index.html
new file mode 100644
index 0000000..cf58aea
--- /dev/null
+++ b/app/src/main/frontend/index.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+ Gameyfin
+
+
+
+
+
+
+
+
diff --git a/app/src/main/frontend/index.tsx b/app/src/main/frontend/index.tsx
new file mode 100644
index 0000000..0c4daa5
--- /dev/null
+++ b/app/src/main/frontend/index.tsx
@@ -0,0 +1,13 @@
+import {createRoot} from 'react-dom/client';
+import {StrictMode} from "react";
+import {RouterProvider} from "react-router";
+import {router} from './routes';
+
+const container = document.getElementById('outlet')!;
+const root = createRoot(container);
+
+root.render(
+
+
+
+);
diff --git a/app/src/main/frontend/main.css b/app/src/main/frontend/main.css
new file mode 100644
index 0000000..602071e
--- /dev/null
+++ b/app/src/main/frontend/main.css
@@ -0,0 +1,74 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer utilities {
+ .gradient-primary {
+ @apply bg-gradient-to-br from-primary-400 to-primary-700;
+ }
+
+ .button-secondary {
+ @apply bg-primary-300 text-background/80;
+ }
+}
+
+/* Custom CSS */
+
+:root {
+ /* Overwrite default Hilla styles (e.g. loading indicator) */
+ --lumo-primary-color: theme(colors.primary);
+
+ /* Overwrite SwiperJS styles */
+ --swiper-navigation-color: theme(colors.primary);
+ --swiper-pagination-color: theme(colors.primary);
+
+ .swiper-pagination-bullet {
+ background-color: theme(colors.primary);
+ }
+
+}
+
+/* List box drag & drop */
+.react-aria-ListBoxItem {
+ &[data-dragging] {
+ opacity: 0.6;
+ }
+}
+
+.react-aria-DropIndicator[data-drop-target] {
+ outline: 1px solid theme(colors.primary);
+}
+
+.shine {
+ position: relative;
+ overflow: hidden;
+}
+
+.shine::before {
+ background: linear-gradient(
+ to right,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(255, 255, 255, 0.7) 100%
+ );
+ content: "";
+ display: block;
+ height: 100%;
+ left: -100%;
+ position: absolute;
+ top: 0;
+ transform: skewX(-25deg);
+ width: 50%;
+ z-index: 2;
+ pointer-events: none;
+}
+
+.shine:hover::before,
+.shine:focus::before {
+ animation: shine 0.85s;
+}
+
+@keyframes shine {
+ 100% {
+ left: 125%;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/routes.tsx b/app/src/main/frontend/routes.tsx
new file mode 100644
index 0000000..bc0cc12
--- /dev/null
+++ b/app/src/main/frontend/routes.tsx
@@ -0,0 +1,105 @@
+import LoginView from "Frontend/views/LoginView";
+import MainLayout from "Frontend/views/MainLayout";
+import HomeView from "Frontend/views/HomeView";
+import SetupView from "Frontend/views/SetupView";
+import {ThemeSelector} from "Frontend/components/theming/ThemeSelector";
+import App from "Frontend/App";
+import {LibraryManagement} from "Frontend/components/administration/LibraryManagement";
+import {UserManagement} from "Frontend/components/administration/UserManagement";
+import ProfileManagement from "Frontend/components/administration/ProfileManagement";
+import {SsoManagement} from "Frontend/components/administration/SsoManagement";
+import {AdministrationView} from "Frontend/views/AdministrationView";
+import {ProfileView} from "Frontend/views/ProfileView";
+import {MessageManagement} from "Frontend/components/administration/MessageManagement";
+import {LogManagement} from "Frontend/components/administration/LogManagement";
+import PasswordResetView from "Frontend/views/PasswordResetView";
+import EmailConfirmationView from "Frontend/views/EmailConfirmationView";
+import InvitationRegistrationView from "Frontend/views/InvitationRegistrationView";
+import PluginManagement from "Frontend/components/administration/PluginManagement";
+import {SystemManagement} from "Frontend/components/administration/SystemManagement";
+import GameView from "Frontend/views/GameView";
+import LibraryManagementView from "Frontend/views/LibraryManagementView";
+import SearchView from "Frontend/views/SearchView";
+import RecentlyAddedView from "Frontend/views/RecentlyAddedView";
+import LibraryView from "Frontend/views/LibraryView";
+import {RouterConfigurationBuilder} from "@vaadin/hilla-file-router/runtime.js";
+
+export const {router, routes} = new RouterConfigurationBuilder()
+ .withReactRoutes([
+ {
+ element: ,
+ handle: {requiresLogin: false},
+ children: [
+ {
+ element: ,
+ handle: {requiresLogin: true},
+ children: [
+ {
+ index: true, element:
+ },
+ {
+ path: 'search',
+ element:
+ },
+ {
+ path: 'recently-added',
+ element:
+ },
+ {
+ path: 'library/:libraryId',
+ element:
+ },
+ {
+ path: 'game/:gameId',
+ element:
+ },
+ {
+ path: 'settings',
+ element: ,
+ children: [
+ {path: 'profile', element: },
+ {path: 'appearance', element: }
+ ]
+ },
+ {
+ path: 'administration',
+ element: ,
+ children: [
+ {
+ path: 'libraries',
+ element:
+ },
+ {
+ path: 'libraries/library/:libraryId',
+ element:
+ },
+ {path: 'users', element: },
+ {path: 'sso', element: },
+ {path: 'messages', element: },
+ {path: 'plugins', element: },
+ {path: 'logs', element: },
+ {path: 'system', element: }
+ ]
+ }
+ ]
+ },
+ {
+ path: 'login', element: , handle: {requiresLogin: false}
+ },
+ {
+ path: 'setup', element: , handle: {requiresLogin: false}
+ },
+ {
+ path: 'accept-invitation', element: , handle: {requiresLogin: false}
+ },
+ {
+ path: 'reset-password', element: , handle: {requiresLogin: false}
+ },
+ {
+ path: 'confirm-email', element: , handle: {requiresLogin: true}
+ },
+ ]
+ }
+ ])
+ .protect("/login")
+ .build();
diff --git a/app/src/main/frontend/state/ConfigState.ts b/app/src/main/frontend/state/ConfigState.ts
new file mode 100644
index 0000000..5bc4078
--- /dev/null
+++ b/app/src/main/frontend/state/ConfigState.ts
@@ -0,0 +1,72 @@
+import {proxy} from 'valtio';
+import ConfigEntryDto from "Frontend/generated/org/gameyfin/app/config/dto/ConfigEntryDto";
+import {ConfigEndpoint} from "Frontend/generated/endpoints";
+import ConfigUpdateDto from "Frontend/generated/org/gameyfin/app/config/dto/ConfigUpdateDto";
+import {Subscription} from "@vaadin/hilla-frontend";
+
+type ConfigState = {
+ subscription?: Subscription;
+ isLoaded: boolean;
+ state: Record;
+ config: NestedConfig;
+};
+
+export const configState = proxy({
+ get isLoaded() {
+ return this.subscription != null;
+ },
+ state: {},
+ get config() {
+ return toNestedConfig(Object.values(this.state));
+ }
+});
+
+/** Subscribe to and process state updates from backend **/
+export async function initializeConfigState() {
+ if (configState.isLoaded) return;
+
+ // Fetch initial configuration data
+ const initialEntries = await ConfigEndpoint.getAll();
+ initialEntries.forEach((entry) => {
+ configState.state[entry.key] = entry;
+ });
+
+ // Subscribe to real-time updates
+ configState.subscription = ConfigEndpoint.subscribe().onNext((updateDtos: ConfigUpdateDto[]) => {
+ updateDtos.forEach((updateDto: ConfigUpdateDto) => {
+ Object.entries(updateDto.updates).forEach(([key, value]) => {
+ if (configState.state[key]) {
+ configState.state[key].value = value;
+ }
+ });
+ })
+ });
+}
+
+/** Computed properties **/
+
+export type NestedConfig = {
+ [field: string]: any;
+}
+
+function toNestedConfig(entries: ConfigEntryDto[]): NestedConfig {
+ const result: Record = {};
+
+ for (const entry of entries) {
+ const keys = entry.key.split('.');
+ let current = result;
+
+ for (let i = 0; i < keys.length; i++) {
+ const key = keys[i];
+
+ if (i === keys.length - 1) {
+ current[key] = entry.value;
+ } else {
+ current[key] = current[key] || {};
+ current = current[key];
+ }
+ }
+ }
+
+ return result;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/state/GameState.ts b/app/src/main/frontend/state/GameState.ts
new file mode 100644
index 0000000..23e097d
--- /dev/null
+++ b/app/src/main/frontend/state/GameState.ts
@@ -0,0 +1,145 @@
+import {Subscription} from "@vaadin/hilla-frontend";
+import {proxy} from "valtio/index";
+import {GameEndpoint} from "Frontend/generated/endpoints";
+import GameEvent from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryEvent";
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import Rand from "rand-seed";
+
+type GameState = {
+ subscription?: Subscription;
+ isLoaded: boolean;
+ state: Record;
+ games: GameDto[];
+ gamesByLibraryId: Record;
+ sortedAlphabetically: GameDto[];
+ recentlyAdded: GameDto[];
+ recentlyUpdated: GameDto[];
+ randomlyOrderedGamesByLibraryId: Record;
+ knownPublishers: Set;
+ knownDevelopers: Set;
+ knownGenres: Set;
+ knownThemes: Set;
+ knownKeywords: Set;
+ knownFeatures: Set;
+ knownPerspectives: Set;
+};
+
+export const gameState = proxy({
+ get isLoaded() {
+ return this.subscription != null;
+ },
+ state: {},
+ get games() {
+ return Object.values(this.state);
+ },
+ get gamesByLibraryId() {
+ return this.sortedAlphabetically.reduce((acc: Record, game: GameDto) => {
+ (acc[game.libraryId] ||= []).push(game);
+ return acc;
+ }, {});
+ },
+ get sortedAlphabetically() {
+ return this.games
+ .sort((a: GameDto, b: GameDto) => a.title.localeCompare(b.title, undefined, {sensitivity: 'base'}));
+ },
+ get recentlyAdded() {
+ return this.games
+ .sort((a: GameDto, b: GameDto) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
+ .slice(0, 25);
+ },
+ get recentlyUpdated() {
+ return this.games
+ .sort((a: GameDto, b: GameDto) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())
+ .slice(0, 25);
+ },
+ get randomlyOrderedGamesByLibraryId() {
+ const result: Record = {};
+ for (const libraryId in this.gamesByLibraryId) {
+ const rand = new Rand(libraryId.toString());
+ result[libraryId] = this.gamesByLibraryId[libraryId]
+ .filter((g: GameDto) => g.coverId && g.imageIds && g.imageIds.length > 0)
+ .sort((a: GameDto, b: GameDto) => a.id - b.id)
+ .sort(() => rand.next() - 0.5);
+ }
+ return result;
+ },
+ get knownPublishers() {
+ return new Set(
+ this.games
+ .flatMap((game: GameDto) => game.publishers ? game.publishers : [])
+ .sort()
+ );
+ },
+ get knownDevelopers() {
+ return new Set(
+ this.games
+ .flatMap((game: GameDto) => game.developers ? game.developers : [])
+ .sort()
+ );
+ },
+ get knownGenres() {
+ return new Set(
+ this.games
+ .flatMap((game: GameDto) => game.genres ? game.genres : [])
+ .sort()
+ );
+ },
+ get knownThemes() {
+ return new Set(
+ this.games
+ .flatMap((game: GameDto) => game.themes ? game.themes : [])
+ .sort()
+ );
+ },
+ get knownKeywords() {
+ return new Set(
+ this.games
+ .flatMap((game: GameDto) => game.keywords ? game.keywords : [])
+ .sort()
+ );
+ },
+ get knownFeatures() {
+ return new Set(
+ this.games
+ .flatMap((game: GameDto) => game.features ? game.features : [])
+ .sort()
+ );
+ },
+ get knownPerspectives() {
+ return new Set(
+ this.games
+ .flatMap((game: GameDto) => game.perspectives ? game.perspectives : [])
+ .sort()
+ );
+ }
+});
+
+/** Subscribe to and process state updates from backend **/
+export async function initializeGameState() {
+ if (gameState.isLoaded) return gameState;
+
+ // Fetch initial library list
+ const initialEntries = await GameEndpoint.getAll();
+ initialEntries.forEach((game: GameDto) => {
+ gameState.state[game.id] = game;
+ });
+
+ // Subscribe to real-time updates
+ gameState.subscription = GameEndpoint.subscribe().onNext((gameEvents: GameEvent[]) => {
+ gameEvents.forEach((gameEvent: GameEvent) => {
+ switch (gameEvent.type) {
+ case "created":
+ case "updated":
+ //@ts-ignore
+ gameState.state[gameEvent.game.id] = gameEvent.game;
+ break;
+ case "deleted":
+ //@ts-ignore
+ delete gameState.state[gameEvent.gameId];
+ break;
+ }
+ })
+ });
+
+ return gameState;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/state/LibraryState.ts b/app/src/main/frontend/state/LibraryState.ts
new file mode 100644
index 0000000..a4a651d
--- /dev/null
+++ b/app/src/main/frontend/state/LibraryState.ts
@@ -0,0 +1,62 @@
+import {Subscription} from "@vaadin/hilla-frontend";
+import {proxy} from "valtio/index";
+import {LibraryEndpoint} from "Frontend/generated/endpoints";
+import LibraryDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryDto";
+import LibraryEvent from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryEvent";
+import {handleLibraryDeletion} from "./ScanState";
+
+type LibraryState = {
+ subscription?: Subscription;
+ isLoaded: boolean;
+ state: Record;
+ libraries: LibraryDto[];
+ sorted: LibraryDto[];
+};
+
+export const libraryState = proxy({
+ get isLoaded() {
+ return this.subscription != null;
+ },
+ state: {},
+ get libraries() {
+ return Object.values(this.state);
+ },
+ get sorted() {
+ return Object.values(this.state).sort((a, b) => {
+ if (a.name === undefined || b.name === undefined) return 0;
+ return a.name.localeCompare(b.name);
+ });
+ }
+});
+
+/** Subscribe to and process state updates from backend **/
+export async function initializeLibraryState() {
+ if (libraryState.isLoaded) return libraryState;
+
+ // Fetch initial library list
+ const initialEntries = await LibraryEndpoint.getAll();
+ initialEntries.forEach((library: LibraryDto) => {
+ libraryState.state[library.id] = library;
+ });
+
+ // Subscribe to real-time updates
+ libraryState.subscription = LibraryEndpoint.subscribeToLibraryEvents().onNext((libraryEvents: LibraryEvent[]) => {
+ libraryEvents.forEach((libraryEvent: LibraryEvent) => {
+ switch (libraryEvent.type) {
+ case "created":
+ case "updated":
+ //@ts-ignore
+ libraryState.state[libraryEvent.library.id] = libraryEvent.library;
+ break;
+ case "deleted":
+ //@ts-ignore
+ handleLibraryDeletion(libraryEvent.libraryId);
+ //@ts-ignore
+ delete libraryState.state[libraryEvent.libraryId];
+ break;
+ }
+ })
+ });
+
+ return libraryState;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/state/PluginState.ts b/app/src/main/frontend/state/PluginState.ts
new file mode 100644
index 0000000..aecc300
--- /dev/null
+++ b/app/src/main/frontend/state/PluginState.ts
@@ -0,0 +1,76 @@
+import {Subscription} from "@vaadin/hilla-frontend";
+import PluginDto from "Frontend/generated/org/gameyfin/app/core/plugins/dto/PluginDto";
+import PluginUpdateDto from "Frontend/generated/org/gameyfin/app/core/plugins/dto/PluginUpdateDto";
+import {proxy} from "valtio/index";
+import {PluginEndpoint} from "Frontend/generated/endpoints";
+
+type PluginState = {
+ subscription?: Subscription;
+ isLoaded: boolean;
+ state: Record;
+ plugins: PluginDto[];
+ pluginsByType: Record;
+};
+
+export const pluginState = proxy({
+ get isLoaded() {
+ return this.subscription != null;
+ },
+ state: {},
+ get plugins() {
+ return Object.values(this.state);
+ },
+ get pluginsByType() {
+ return groupPluginsByType(this.state);
+ }
+});
+
+/** Subscribe to and process state updates from backend **/
+export async function initializePluginState() {
+ if (pluginState.isLoaded) return;
+
+ // Fetch initial plugin list
+ const initialEntries = await PluginEndpoint.getAll();
+ initialEntries.forEach((plugin: PluginDto) => {
+ pluginState.state[plugin.id] = plugin;
+ });
+
+ // Subscribe to real-time updates
+ pluginState.subscription = PluginEndpoint.subscribe().onNext((updateDtos: PluginUpdateDto[]) => {
+ updateDtos.forEach((updateDto: PluginUpdateDto) => {
+ // Make sure the plugin exists in the state
+ if (pluginState.state[updateDto.id]) {
+ // Update the existing plugin by merging the new data using destructuring
+ pluginState.state[updateDto.id] = {
+ ...pluginState.state[updateDto.id],
+ ...updateDto
+ };
+ }
+ })
+ });
+}
+
+/** Computed **/
+
+function groupPluginsByType(pluginsMap: Record): Record {
+ const pluginsByType: Record = {};
+
+ // Convert map to array of plugins
+ const plugins = Object.values(pluginsMap);
+
+ // Iterate through each plugin
+ for (const plugin of plugins) {
+ // Each plugin can have multiple types
+ for (const type of plugin.types) {
+ // Initialize array for this type if it doesn't exist
+ if (!pluginsByType[type]) {
+ pluginsByType[type] = [];
+ }
+
+ // Add plugin to the appropriate type array
+ pluginsByType[type].push(plugin);
+ }
+ }
+
+ return pluginsByType;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/state/ScanState.ts b/app/src/main/frontend/state/ScanState.ts
new file mode 100644
index 0000000..48a31bc
--- /dev/null
+++ b/app/src/main/frontend/state/ScanState.ts
@@ -0,0 +1,53 @@
+import {proxy} from 'valtio';
+import type LibraryScanProgress from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryScanProgress";
+import {LibraryEndpoint} from "Frontend/generated/endpoints";
+import {Subscription} from "@vaadin/hilla-frontend";
+import LibraryScanStatus from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryScanStatus";
+import {libraryState} from "Frontend/state/LibraryState";
+
+type ScanState = {
+ subscription?: Subscription;
+ state: Record;
+ hasContent: boolean,
+ isScanning: boolean,
+ sortedByStartTime: LibraryScanProgress[];
+};
+
+export const scanState = proxy({
+ state: {},
+ get hasContent(): boolean {
+ return Object.values(this.state).length > 0;
+ },
+ get isScanning(): boolean {
+ return Object.values(this.state)
+ .some((scanProgress: LibraryScanProgress) => scanProgress.status === LibraryScanStatus.IN_PROGRESS);
+ },
+ get sortedByStartTime(): LibraryScanProgress[] {
+ return Object.values(this.state).sort((a: LibraryScanProgress, b: LibraryScanProgress) => {
+ return new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime();
+ });
+ }
+});
+
+/** Subscribe to and process state updates from backend **/
+export function initializeScanState() {
+ if (scanState.subscription) return;
+
+ // Subscribe to real-time updates
+ scanState.subscription = LibraryEndpoint.subscribeToScanProgressEvents().onNext((scanProgresses: LibraryScanProgress[]) => {
+ scanProgresses.forEach((scanProgress: LibraryScanProgress) => {
+ // Filter out scans for libraries that are not in the current state
+ if (!libraryState.state[scanProgress.libraryId]) return;
+
+ scanState.state[scanProgress.scanId] = scanProgress;
+ })
+ });
+}
+
+export function handleLibraryDeletion(libraryId: number) {
+ for (const scanId in scanState.state) {
+ if (scanState.state[scanId].libraryId === libraryId) {
+ delete scanState.state[scanId];
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/theme.ts b/app/src/main/frontend/theming/theme.ts
new file mode 100644
index 0000000..0e55b55
--- /dev/null
+++ b/app/src/main/frontend/theming/theme.ts
@@ -0,0 +1,26 @@
+type ColorPalette = {
+ 100: string,
+ 200: string,
+ 300: string,
+ 400: string,
+ 500: string,
+ 600: string,
+ 700: string,
+ 800: string,
+ 900: string,
+ DEFAULT: string
+}
+
+export type Theme = {
+ name?: string,
+ colors: {
+ background?: string,
+ foreground?: string,
+ primary: ColorPalette,
+ secondary?: ColorPalette,
+ success?: ColorPalette,
+ warning?: ColorPalette,
+ danger?: ColorPalette,
+ focus?: string,
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes.ts b/app/src/main/frontend/theming/themes.ts
new file mode 100644
index 0000000..6d19bbf
--- /dev/null
+++ b/app/src/main/frontend/theming/themes.ts
@@ -0,0 +1,47 @@
+import {GameyfinClassic} from "./themes/gameyfin-classic";
+import {GameyfinBlue} from "./themes/gameyfin-blue";
+import {GameyfinViolet} from "./themes/gameyfin-violet";
+import {Purple} from "./themes/purple";
+import {Neutral} from "./themes/neutral";
+import {Slate} from "./themes/slate";
+import {Red} from "./themes/red";
+import {Rose} from "./themes/rose";
+import {Blue} from "./themes/blue";
+import {Yellow} from "./themes/yellow";
+import {Violet} from "./themes/violet";
+import {Orange} from "./themes/orange";
+import {Colorblind} from "./themes/colorblind";
+import {Theme} from "./theme";
+import {ConfigTheme, ConfigThemes} from "@heroui/react";
+
+
+function light(c: Theme): ConfigTheme {
+ let t: Theme = structuredClone(c);
+ delete t.name;
+ (t as ConfigTheme).extend = "light";
+ return t;
+}
+
+function dark(c: Theme): ConfigTheme {
+ let t: Theme = structuredClone(c);
+ delete t.name;
+ (t as ConfigTheme).extend = "dark";
+ return t;
+}
+
+export function compileThemes(themes: Theme[]): ConfigThemes {
+ let compiledThemes: any = {};
+
+ themes.forEach((c: Theme) => {
+ compiledThemes[`${c.name}-light`] = light(c);
+ compiledThemes[`${c.name}-dark`] = dark(c);
+ })
+
+ return compiledThemes;
+}
+
+export function themeNames(): string[] {
+ return Object.keys(compileThemes(themes));
+}
+
+export const themes: Theme[] = [GameyfinBlue, GameyfinViolet, GameyfinClassic, Neutral, Slate, Red, Rose, Orange, Purple, Blue, Yellow, Violet, Colorblind];
diff --git a/app/src/main/frontend/theming/themes/blue.ts b/app/src/main/frontend/theming/themes/blue.ts
new file mode 100644
index 0000000..de46c99
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/blue.ts
@@ -0,0 +1,31 @@
+import {Theme} from '../theme';
+
+export const Blue: Theme = {
+ name: 'blue',
+ colors: {
+ primary: {
+ DEFAULT: '#2563EB',
+ 100: '#b6cdfe',
+ 200: '#88abf7',
+ 300: '#5b8af1',
+ 400: '#2d69ec',
+ 500: '#134fd2',
+ 600: '#0b3da4',
+ 700: '#052c77',
+ 800: '#001a4a',
+ 900: '#00091e'
+ },
+ secondary: {
+ DEFAULT: '#d29613',
+ 100: '#faebcc',
+ 200: '#f5d898',
+ 300: '#f1c465',
+ 400: '#ecb132',
+ 500: '#d29613',
+ 600: '#a87810',
+ 700: '#7e5a0c',
+ 800: '#543c08',
+ 900: '#2a1e04'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/colorblind.ts b/app/src/main/frontend/theming/themes/colorblind.ts
new file mode 100644
index 0000000..47cbf92
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/colorblind.ts
@@ -0,0 +1,67 @@
+import {Theme} from '../theme';
+
+export const Colorblind: Theme = {
+ name: 'colorblind',
+ colors: {
+ primary: {
+ DEFAULT: '#cc79a7',
+ 900: '#2f1222',
+ 800: '#5f2444',
+ 700: '#8e3666',
+ 600: '#bb4b88',
+ 500: '#cc79a7',
+ 400: '#d795b9',
+ 300: '#e1afca',
+ 200: '#ebcadc',
+ 100: '#f5e4ed'
+ },
+ secondary: {
+ DEFAULT: '#0072b2',
+ 900: '#001724',
+ 800: '#002d47',
+ 700: '#00446b',
+ 600: '#005a8f',
+ 500: '#0072b2',
+ 400: '#009bf5',
+ 300: '#38b6ff',
+ 200: '#7aceff',
+ 100: '#bde7ff'
+ },
+ success: {
+ DEFAULT: '#009e73',
+ 900: '#002017',
+ 800: '#003f2e',
+ 700: '#005f46',
+ 600: '#007e5d',
+ 500: '#009e73',
+ 400: '#00e4a8',
+ 300: '#2cffc7',
+ 200: '#72ffd9',
+ 100: '#b9ffec'
+ },
+ warning: {
+ DEFAULT: '#e69f00',
+ 900: '#2e1f00',
+ 800: '#5c3f00',
+ 700: '#8a5e00',
+ 600: '#b87d00',
+ 500: '#e69f00',
+ 400: '#ffb81f',
+ 300: '#ffca57',
+ 200: '#ffdb8f',
+ 100: '#ffedc7'
+ },
+ danger: {
+ DEFAULT: '#d55e00',
+ 900: '#2b1300',
+ 800: '#562500',
+ 700: '#813800',
+ 600: '#ab4a00',
+ 500: '#d55e00',
+ 400: '#ff7912',
+ 300: '#ff9a4e',
+ 200: '#ffbc89',
+ 100: '#ffddc4'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/gameyfin-blue.ts b/app/src/main/frontend/theming/themes/gameyfin-blue.ts
new file mode 100644
index 0000000..728f5a8
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/gameyfin-blue.ts
@@ -0,0 +1,31 @@
+import {Theme} from '../theme';
+
+export const GameyfinBlue: Theme = {
+ name: 'gameyfin-blue',
+ colors: {
+ primary: {
+ DEFAULT: '#2332c8',
+ 100: '#bdc3f9',
+ 200: '#919bee',
+ 300: '#6672e5',
+ 400: '#3c4add',
+ 500: '#2231c3',
+ 600: '#1a2699',
+ 700: '#101b6f',
+ 800: '#070f45',
+ 900: '#02041d'
+ },
+ secondary: {
+ DEFAULT: '#c3b422',
+ 100: '#f7f3cf',
+ 200: '#eee6a0',
+ 300: '#e6da70',
+ 400: '#ddce40',
+ 500: '#c3b422',
+ 600: '#9c8f1c',
+ 700: '#756b15',
+ 800: '#4e480e',
+ 900: '#272407',
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/gameyfin-classic.ts b/app/src/main/frontend/theming/themes/gameyfin-classic.ts
new file mode 100644
index 0000000..3e528d0
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/gameyfin-classic.ts
@@ -0,0 +1,31 @@
+import {Theme} from '../theme';
+
+export const GameyfinClassic: Theme = {
+ name: 'gameyfin-classic',
+ colors: {
+ primary: {
+ DEFAULT: '#16A34A',
+ 100: '#b8f7cf',
+ 200: '#8ef0b2',
+ 300: '#62ea94',
+ 400: '#38e476',
+ 500: '#20ca5d',
+ 600: '#159d47',
+ 700: '#0b7032',
+ 800: '#02431d',
+ 900: '#001804'
+ },
+ secondary: {
+ DEFAULT: '#ca208d',
+ 100: '#f8cfe9',
+ 200: '#f0a0d3',
+ 300: '#e970bc',
+ 400: '#e140a6',
+ 500: '#ca208d',
+ 600: '#a21970',
+ 700: '#7a1354',
+ 800: '#510d38',
+ 900: '#29061c'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/gameyfin-violet.ts b/app/src/main/frontend/theming/themes/gameyfin-violet.ts
new file mode 100644
index 0000000..b9780f9
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/gameyfin-violet.ts
@@ -0,0 +1,31 @@
+import {Theme} from '../theme';
+
+export const GameyfinViolet: Theme = {
+ name: 'gameyfin-violet',
+ colors: {
+ primary: {
+ DEFAULT: '#6441a5',
+ 100: '#d5c7ed',
+ 200: '#b7a4dd',
+ 300: '#9a7fce',
+ 400: '#7d5abe',
+ 500: '#6441a5',
+ 600: '#4e3281',
+ 700: '#37235d',
+ 800: '#21153a',
+ 900: '#0d0519'
+ },
+ secondary: {
+ DEFAULT: '#82a541',
+ 100: '#e7efd7',
+ 200: '#cedfaf',
+ 300: '#b6cf87',
+ 400: '#9dbf5f',
+ 500: '#82a541',
+ 600: '#688334',
+ 700: '#4e6227',
+ 800: '#34421a',
+ 900: '#1a210d'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/neutral.ts b/app/src/main/frontend/theming/themes/neutral.ts
new file mode 100644
index 0000000..3db702d
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/neutral.ts
@@ -0,0 +1,31 @@
+import {Theme} from '../theme';
+
+export const Neutral: Theme = {
+ name: 'neutral',
+ colors: {
+ primary: {
+ DEFAULT: '#525252',
+ 100: '#ddd7d9',
+ 200: '#c1bfbf',
+ 300: '#a6a6a6',
+ 400: '#8c8c8c',
+ 500: '#737373',
+ 600: '#595959',
+ 700: '#413f40',
+ 800: '#292526',
+ 900: '#16090d'
+ },
+ secondary: {
+ DEFAULT: '#8d8d8d',
+ 100: '#e8e8e8',
+ 200: '#d1d1d1',
+ 300: '#bababa',
+ 400: '#a3a3a3',
+ 500: '#8d8d8d',
+ 600: '#707070',
+ 700: '#545454',
+ 800: '#383838',
+ 900: '#1c1c1c'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/orange.ts b/app/src/main/frontend/theming/themes/orange.ts
new file mode 100644
index 0000000..f52092b
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/orange.ts
@@ -0,0 +1,31 @@
+import {Theme} from '../theme';
+
+export const Orange: Theme = {
+ name: 'orange',
+ colors: {
+ primary: {
+ DEFAULT: '#EA580C',
+ 100: '#ffcdb2',
+ 200: '#fbac84',
+ 300: '#f78c54',
+ 400: '#f46c25',
+ 500: '#da520b',
+ 600: '#ab3f07',
+ 700: '#7a2d03',
+ 800: '#4b1900',
+ 900: '#1f0600'
+ },
+ secondary: {
+ DEFAULT: '#0b93da',
+ 100: '#caebfc',
+ 200: '#94d6f9',
+ 300: '#5fc2f7',
+ 400: '#2aadf4',
+ 500: '#0b93da',
+ 600: '#0975ae',
+ 700: '#075783',
+ 800: '#053a57',
+ 900: '#021d2c'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/purple.ts b/app/src/main/frontend/theming/themes/purple.ts
new file mode 100644
index 0000000..541388f
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/purple.ts
@@ -0,0 +1,31 @@
+import {Theme} from "../theme";
+
+export const Purple: Theme = {
+ name: 'purple',
+ colors: {
+ primary: {
+ DEFAULT: '#DD62ED',
+ 100: '#f2b9f9',
+ 200: '#e78df3',
+ 300: '#dc5fed',
+ 400: '#d132e6',
+ 500: '#b91acd',
+ 600: '#9012a0',
+ 700: '#670b73',
+ 800: '#3f0547',
+ 900: '#19001b'
+ },
+ secondary: {
+ DEFAULT: '#2ecd1a',
+ 100: '#d2f9cd',
+ 200: '#a6f29c',
+ 300: '#79ec6a',
+ 400: '#4de538',
+ 500: '#2ecd1a',
+ 600: '#26a215',
+ 700: '#1c7a10',
+ 800: '#13510b',
+ 900: '#092905'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/red.ts b/app/src/main/frontend/theming/themes/red.ts
new file mode 100644
index 0000000..a362dee
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/red.ts
@@ -0,0 +1,31 @@
+import {Theme} from '../theme';
+
+export const Red: Theme = {
+ name: 'red',
+ colors: {
+ primary: {
+ DEFAULT: '#DC2626',
+ 100: '#f9bbbb',
+ 200: '#ef9090',
+ 300: '#e76464',
+ 400: '#df3939',
+ 500: '#c62020',
+ 600: '#9b1718',
+ 700: '#6f0f11',
+ 800: '#450708',
+ 900: '#1e0000'
+ },
+ secondary: {
+ DEFAULT: '#20c6c6',
+ 100: '#cff7f7',
+ 200: '#9fefef',
+ 300: '#6ee7e7',
+ 400: '#3ee0e0',
+ 500: '#20c6c6',
+ 600: '#1a9e9e',
+ 700: '#137676',
+ 800: '#0d4f4f',
+ 900: '#062727'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/rose.ts b/app/src/main/frontend/theming/themes/rose.ts
new file mode 100644
index 0000000..efb213f
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/rose.ts
@@ -0,0 +1,31 @@
+import {Theme} from "../theme";
+
+export const Rose: Theme = {
+ name: 'rose',
+ colors: {
+ primary: {
+ DEFAULT: '#E11D48',
+ 100: '#fbb9c8',
+ 200: '#f28da4',
+ 300: '#ec607f',
+ 400: '#e5345b',
+ 500: '#cb1a41',
+ 600: '#9f1233',
+ 700: '#730b23',
+ 800: '#470415',
+ 900: '#1e0006'
+ },
+ secondary: {
+ DEFAULT: '#1acba4',
+ 100: '#cdf9ef',
+ 200: '#9cf2df',
+ 300: '#6aecd0',
+ 400: '#38e5c0',
+ 500: '#1acba4',
+ 600: '#15a284',
+ 700: '#107a63',
+ 800: '#0b5142',
+ 900: '#052921'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/slate.ts b/app/src/main/frontend/theming/themes/slate.ts
new file mode 100644
index 0000000..613cf5c
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/slate.ts
@@ -0,0 +1,31 @@
+import {Theme} from "../theme";
+
+export const Slate: Theme = {
+ name: 'slate',
+ colors: {
+ primary: {
+ DEFAULT: '#475569',
+ 100: '#cfd7e4',
+ 200: '#b2bdcd',
+ 300: '#95a3b7',
+ 400: '#7788a1',
+ 500: '#5e6f88',
+ 600: '#48566a',
+ 700: '#323e4d',
+ 800: '#1d2531',
+ 900: '#040d17'
+ },
+ secondary: {
+ DEFAULT: '#88775e',
+ 100: '#e8e4de',
+ 200: '#d1c9bd',
+ 300: '#baae9c',
+ 400: '#a3937b',
+ 500: '#88775e',
+ 600: '#6c5f4b',
+ 700: '#514738',
+ 800: '#363026',
+ 900: '#1b1813'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/violet.ts b/app/src/main/frontend/theming/themes/violet.ts
new file mode 100644
index 0000000..d01c3ba
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/violet.ts
@@ -0,0 +1,31 @@
+import {Theme} from '../theme';
+
+export const Violet: Theme = {
+ name: 'violet',
+ colors: {
+ primary: {
+ DEFAULT: '#6D28D9',
+ 100: '#d4bdf8',
+ 200: '#b592ee',
+ 300: '#9867e5',
+ 400: '#7b3cdd',
+ 500: '#6122c3',
+ 600: '#4b1a99',
+ 700: '#36126e',
+ 800: '#200944',
+ 900: '#0d021c'
+ },
+ secondary: {
+ DEFAULT: '#84c322',
+ 100: '#e8f7cf',
+ 200: '#d0eea0',
+ 300: '#b9e670',
+ 400: '#a1dd40',
+ 500: '#84c322',
+ 600: '#6b9c1c',
+ 700: '#507515',
+ 800: '#354e0e',
+ 900: '#1b2707'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/theming/themes/yellow.ts b/app/src/main/frontend/theming/themes/yellow.ts
new file mode 100644
index 0000000..0720496
--- /dev/null
+++ b/app/src/main/frontend/theming/themes/yellow.ts
@@ -0,0 +1,31 @@
+import {Theme} from '../theme';
+
+export const Yellow: Theme = {
+ name: 'yellow',
+ colors: {
+ primary: {
+ DEFAULT: '#FACC15',
+ 100: '#feefae',
+ 200: '#fce47f',
+ 300: '#fbd94e',
+ 400: '#face1e',
+ 500: '#e1b505',
+ 600: '#af8c00',
+ 700: '#7d6400',
+ 800: '#4c3c00',
+ 900: '#1c1400'
+ },
+ secondary: {
+ DEFAULT: '#0531e1',
+ 100: '#c8d3fe',
+ 200: '#91a7fd',
+ 300: '#5a7afc',
+ 400: '#234efb',
+ 500: '#0531e1',
+ 600: '#0427b4',
+ 700: '#031d87',
+ 800: '#02135a',
+ 900: '#010a2d'
+ }
+ }
+};
\ No newline at end of file
diff --git a/app/src/main/frontend/util/auth.ts b/app/src/main/frontend/util/auth.ts
new file mode 100644
index 0000000..7bd547e
--- /dev/null
+++ b/app/src/main/frontend/util/auth.ts
@@ -0,0 +1,16 @@
+import {configureAuth} from '@vaadin/hilla-react-auth';
+import {UserEndpoint} from 'Frontend/generated/endpoints';
+
+// Configure auth to use `UserInfoService.getUserInfo`
+const auth = configureAuth(UserEndpoint.getUserInfo);
+
+// Export auth provider and useAuth hook, which are automatically
+// typed to the result of `UserInfoService.getUserInfo`
+export const useAuth = auth.useAuth;
+export const AuthProvider = auth.AuthProvider;
+
+
+export function getCsrfToken() {
+ const token = document.querySelector('meta[name="_csrf"]')?.getAttribute('content');
+ return token || '';
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/util/custom-validators.ts b/app/src/main/frontend/util/custom-validators.ts
new file mode 100644
index 0000000..d6963f6
--- /dev/null
+++ b/app/src/main/frontend/util/custom-validators.ts
@@ -0,0 +1,10 @@
+import * as Yup from "yup";
+import {isValidCron} from "cron-validator";
+
+// Custom validator for cron expressions
+Yup.addMethod(Yup.string, 'cron', function (message) {
+ return this.test('cron', message, function (value) {
+ const {path, createError} = this;
+ return isValidCron(value as string) || createError({path, message: message || 'Invalid cron expression'});
+ });
+});
\ No newline at end of file
diff --git a/app/src/main/frontend/util/middleware.ts b/app/src/main/frontend/util/middleware.ts
new file mode 100644
index 0000000..a72b911
--- /dev/null
+++ b/app/src/main/frontend/util/middleware.ts
@@ -0,0 +1,39 @@
+import {Middleware, MiddlewareContext, MiddlewareNext} from '@vaadin/hilla-frontend';
+import {addToast} from "@heroui/react";
+import {getReasonPhrase} from "http-status-codes";
+
+export const ErrorHandlingMiddleware: Middleware = async function (
+ context: MiddlewareContext,
+ next: MiddlewareNext
+) {
+ const {endpoint, method} = context;
+
+ let originalResponse = (await next(context));
+
+ if (!originalResponse.ok) {
+ // .clone() is necessary because response.json() is one-time only and Hilla accesses it in its internal error handler
+ // @see https://developer.mozilla.org/en-US/docs/Web/API/Response/clone
+ let response: Response = originalResponse.clone();
+
+ //Ignore calls to UserEndpoint.getUserInfo since they are managed by Hilla and called on initial load
+ if (endpoint == "UserEndpoint" && method == "getUserInfo") return originalResponse;
+
+ let json: any = await response.json();
+
+ if (json.type == "dev.hilla.exception.EndpointException") {
+ addToast({
+ title: getReasonPhrase(response.status),
+ description: json.message,
+ color: "danger"
+ })
+ } else {
+ addToast({
+ title: getReasonPhrase(response.status),
+ description: `${endpoint}.${method}`,
+ color: "danger"
+ })
+ }
+ }
+
+ return originalResponse;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/util/routing.ts b/app/src/main/frontend/util/routing.ts
new file mode 100644
index 0000000..90703b6
--- /dev/null
+++ b/app/src/main/frontend/util/routing.ts
@@ -0,0 +1,15 @@
+import {useMatches} from 'react-router';
+
+type RouteMetadata = {
+ [key: string]: any;
+};
+
+/**
+ * Returns the `handle` object containing the metadata for the current route,
+ * or undefined if the route does not have defined a handle.
+ */
+export function useRouteMetadata(): RouteMetadata | undefined {
+ const matches = useMatches();
+ const match = matches[matches.length - 1];
+ return match?.handle as RouteMetadata | undefined;
+}
diff --git a/app/src/main/frontend/util/user-preference-service.ts b/app/src/main/frontend/util/user-preference-service.ts
new file mode 100644
index 0000000..0d6e6c5
--- /dev/null
+++ b/app/src/main/frontend/util/user-preference-service.ts
@@ -0,0 +1,39 @@
+import {UserPreferencesEndpoint} from "Frontend/generated/endpoints";
+
+export class UserPreferenceService {
+ static LOCAL_STORAGE_PREFIX = "gameyfin.";
+
+ static async sync(): Promise {
+ let keys = Object.keys(localStorage);
+ for (let key of keys) {
+ if (!key.startsWith(`${this.LOCAL_STORAGE_PREFIX}`)) {
+ continue;
+ }
+ let value = await UserPreferencesEndpoint.get(key.replace(this.LOCAL_STORAGE_PREFIX, ""));
+ if (value) {
+ localStorage.setItem(key, value);
+ }
+ }
+ }
+
+ static async get(key: string): Promise {
+ let localPreference = localStorage.getItem(`${this.LOCAL_STORAGE_PREFIX}${key}`);
+
+ if (localPreference) {
+ return localPreference;
+ } else {
+ let syncedPreference = await UserPreferencesEndpoint.get(key);
+ if (syncedPreference) {
+ localStorage.setItem(`${this.LOCAL_STORAGE_PREFIX}${key}`, syncedPreference);
+ return syncedPreference;
+ }
+ }
+
+ return undefined;
+ }
+
+ static async set(key: string, value: string) {
+ await UserPreferencesEndpoint.set(key, value);
+ localStorage.setItem(`${this.LOCAL_STORAGE_PREFIX}${key}`, value);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/util/utils.ts b/app/src/main/frontend/util/utils.ts
new file mode 100644
index 0000000..5aac492
--- /dev/null
+++ b/app/src/main/frontend/util/utils.ts
@@ -0,0 +1,210 @@
+import {getCsrfToken} from "Frontend/util/auth";
+import moment from 'moment-timezone';
+
+export function isAdmin(auth: any): boolean {
+ return auth.state.user?.roles?.some((a: string) => a?.includes("ADMIN"));
+}
+
+export function roleToRoleName(role: string) {
+ role = role.replace("ROLE_", "").toLowerCase();
+ return role.charAt(0).toUpperCase() + role.slice(1);
+}
+
+export function toTitleCase(str: string) {
+ return str.replaceAll("_", " ").toLowerCase().split(' ').map((word: string) => {
+ return (word.charAt(0).toUpperCase() + word.slice(1));
+ }).join(' ');
+}
+
+export function camelCaseToTitle(text: string): string {
+ return text
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
+ .replace(/^./, str => str.toUpperCase());
+}
+
+export function hashCode(string: string) {
+ let hash = 0, i, chr;
+ if (string.length === 0) return hash;
+ for (i = 0; i < string.length; i++) {
+ chr = string.charCodeAt(i);
+ hash = ((hash << 5) - hash) + chr;
+ hash |= 0; // Convert to 32bit integer
+ }
+ return hash;
+}
+
+export function roleToColor(role: string) {
+ switch (role) {
+ case "ROLE_SUPERADMIN":
+ return "red";
+ case "ROLE_ADMIN":
+ return "orange";
+ case "ROLE_USER":
+ return "blue";
+ default:
+ return "gray";
+ }
+}
+
+export async function fetchWithAuth(url: string, body: any = null, method = "POST"): Promise {
+ return await fetch(url, {
+ headers: {
+ "X-CSRF-Token": getCsrfToken()
+ },
+ credentials: "same-origin",
+ method: method,
+ body: body
+ });
+}
+
+/**
+ * Calculate the time difference between a given Instant and the current time in the user's timezone.
+ * @param {string} instantString - The Instant string returned by the backend.
+ * @param {string} timeZone - The user's timezone.
+ * @returns {string} - The time difference in a human-readable format.
+ */
+export function timeUntil(instantString: string, timeZone: string = moment.tz.guess()): string {
+ const givenDate = moment.tz(instantString, timeZone);
+ const now = moment.tz(timeZone);
+ const diffInSeconds = givenDate.diff(now, 'seconds');
+
+ const units = [
+ {name: "year", seconds: 31536000},
+ {name: "month", seconds: 2592000},
+ {name: "day", seconds: 86400},
+ {name: "hour", seconds: 3600},
+ {name: "minute", seconds: 60},
+ {name: "second", seconds: 1}
+ ];
+
+ const isPast = diffInSeconds < 0;
+ const absDiffInSeconds = Math.abs(diffInSeconds);
+
+ for (const unit of units) {
+ const value = Math.floor(absDiffInSeconds / unit.seconds);
+ if (value >= 1) {
+ return `${isPast ? '' : 'in'} ${value} ${unit.name}${value > 1 ? 's' : ''} ${isPast ? 'ago' : ''}`;
+ }
+ }
+
+ return "just now";
+}
+
+export function timeBetween(start: string, end: string, timeZone: string = moment.tz.guess()): string {
+ const startDate = moment.tz(start, timeZone);
+ const endDate = moment.tz(end, timeZone);
+ const diffInSeconds = startDate.diff(endDate, 'seconds');
+
+ const units = [
+ {name: "year", seconds: 31536000},
+ {name: "month", seconds: 2592000},
+ {name: "day", seconds: 86400},
+ {name: "hour", seconds: 3600},
+ {name: "minute", seconds: 60},
+ {name: "second", seconds: 1}
+ ];
+
+ const absDiffInSeconds = Math.abs(diffInSeconds);
+
+ for (const unit of units) {
+ const value = Math.floor(absDiffInSeconds / unit.seconds);
+ if (value >= 1) {
+ return `${value} ${unit.name}${value > 1 ? 's' : ''}`;
+ }
+ }
+
+ return "under a second";
+}
+
+/**
+ * Format bytes as human-readable text.
+ *
+ * @param bytes Number of bytes.
+ * @param si True to use metric (SI) units, aka powers of 1000. False to use
+ * binary (IEC), aka powers of 1024.
+ * @param dp Number of decimal places to display.
+ *
+ * @return Formatted string.
+ */
+export function humanFileSize(bytes: number, si: boolean = false, dp: number = 1) {
+ const thresh = si ? 1000 : 1024;
+
+ if (Math.abs(bytes) < thresh) {
+ return bytes + ' B';
+ }
+
+ const units = si
+ ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
+ : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
+ let u = -1;
+ const r = 10 ** dp;
+
+ do {
+ bytes /= thresh;
+ ++u;
+ } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);
+
+
+ return bytes.toFixed(dp) + ' ' + units[u];
+}
+
+/**
+ * Return an object with the changed fields between two objects.
+ * The returned object will only contain the changed fields with values from the current object.
+ * @param initial
+ * @param current
+ */
+export function deepDiff(initial: T, current: T): Partial {
+ function compareObjects(obj1: any, obj2: any): any {
+ if (typeof obj1 !== 'object' || typeof obj2 !== 'object' || obj1 === null || obj2 === null) {
+ if (obj1 !== obj2) {
+ return obj2;
+ }
+ return undefined;
+ }
+
+ if (Array.isArray(obj1) && Array.isArray(obj2)) {
+ if (obj1.length !== obj2.length) {
+ return obj2;
+ } else {
+ const arrayDiff = obj1.map((item: any, index: number) => compareObjects(item, obj2[index]));
+ if (arrayDiff.some(item => item !== undefined)) {
+ return arrayDiff;
+ }
+ return undefined;
+ }
+ }
+
+ const keys = new Set([...Object.keys(obj1), ...Object.keys(obj2)]);
+ const objDiff: any = {};
+ keys.forEach(key => {
+ const valueDiff = compareObjects(obj1[key], obj2[key]);
+ if (valueDiff !== undefined) {
+ objDiff[key] = valueDiff;
+ }
+ });
+
+ if (Object.keys(objDiff).length > 0) {
+ return objDiff;
+ }
+ return undefined;
+ }
+
+ const result = compareObjects(initial, current);
+ return result || {};
+}
+
+/**
+ * Extract the file name from a given path.
+ * Supports both Windows and Unix-style paths.
+ * @param path
+ * @param includeExtension
+ */
+export function fileNameFromPath(path: string, includeExtension: boolean = true): string {
+ let fileName = (path.split('\\').pop() ?? '').split('/').pop() ?? '';
+ if (includeExtension) {
+ return fileName;
+ }
+ const dotIndex = fileName.lastIndexOf('.');
+ return dotIndex < 0 ? fileName : fileName.substring(0, dotIndex);
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/AdministrationView.tsx b/app/src/main/frontend/views/AdministrationView.tsx
new file mode 100644
index 0000000..456bdb5
--- /dev/null
+++ b/app/src/main/frontend/views/AdministrationView.tsx
@@ -0,0 +1,43 @@
+import {Envelope, GameController, LockKey, Log, Plug, Users, Wrench} from "@phosphor-icons/react";
+import withSideMenu, {MenuItem} from "Frontend/components/general/withSideMenu";
+
+const menuItems: MenuItem[] = [
+ {
+ title: "Libraries",
+ url: "libraries",
+ icon:
+ },
+ {
+ title: "Users",
+ url: "users",
+ icon:
+ },
+ {
+ title: "SSO",
+ url: "sso",
+ icon:
+ },
+ {
+ title: "Messages",
+ url: "messages",
+ icon:
+ },
+ {
+ title: "Plugins",
+ url: "plugins",
+ icon:
+ },
+ {
+ title: "Logs",
+ url: "logs",
+ icon:
+ },
+ {
+ title: "System",
+ url: "system",
+ icon:
+ }
+]
+
+export const AdministrationView = withSideMenu("/administration", menuItems);
+export default AdministrationView;
\ No newline at end of file
diff --git a/app/src/main/frontend/views/EmailConfirmationView.tsx b/app/src/main/frontend/views/EmailConfirmationView.tsx
new file mode 100644
index 0000000..468706c
--- /dev/null
+++ b/app/src/main/frontend/views/EmailConfirmationView.tsx
@@ -0,0 +1,76 @@
+import {Card, CardBody, CardHeader} from "@heroui/react";
+import {useNavigate, useSearchParams} from "react-router";
+import React, {useEffect, useState} from "react";
+import {CheckCircle, Warning, WarningCircle} from "@phosphor-icons/react";
+import TokenValidationResult from "Frontend/generated/org/gameyfin/app/shared/token/TokenValidationResult";
+import {EmailConfirmationEndpoint} from "Frontend/generated/endpoints";
+import {useAuth} from "Frontend/util/auth";
+
+export default function EmailConfirmationView() {
+ const auth = useAuth();
+ const [searchParams, setSearchParams] = useSearchParams();
+ const navigate = useNavigate();
+ const [validationResult, setValidationResult] = useState(TokenValidationResult.INVALID);
+
+ useEffect(() => {
+ if (auth.state.user?.emailConfirmed === true) {
+ navigate("/");
+ }
+ }, []);
+
+ useEffect(() => {
+ let token = searchParams.get("token");
+ if (token) confirmEmail(token).then((result) => setValidationResult(result));
+ }, [searchParams]);
+
+ async function confirmEmail(token: string): Promise {
+ let result = await EmailConfirmationEndpoint.confirmEmail(token) as TokenValidationResult;
+
+ if (result === TokenValidationResult.VALID) {
+ setTimeout(() => window.location.reload(), 5000);
+ }
+
+ return result;
+ }
+
+ return (
+
+
+
+
+
+
+ {validationResult === TokenValidationResult.VALID ?
+
+
+
+ Email confirmed
+ You will be redirected shortly
+
+
+ : validationResult === TokenValidationResult.EXPIRED ?
+
+
+
+ Expired token
+ Please request a new one
+
+
+ :
+
+
+
+ Invalid token
+ Please try again
+
+
+ }
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/GameView.tsx b/app/src/main/frontend/views/GameView.tsx
new file mode 100644
index 0000000..d866847
--- /dev/null
+++ b/app/src/main/frontend/views/GameView.tsx
@@ -0,0 +1,287 @@
+import React, {useEffect, useState} from "react";
+import {DownloadProviderEndpoint, GameEndpoint} from "Frontend/generated/endpoints";
+import {useNavigate, useParams} from "react-router";
+import {GameCover} from "Frontend/components/general/covers/GameCover";
+import ComboButton, {ComboButtonOption} from "Frontend/components/general/input/ComboButton";
+import ImageCarousel from "Frontend/components/general/covers/ImageCarousel";
+import {Accordion, AccordionItem, addToast, Button, Chip, Link, Tooltip, useDisclosure} from "@heroui/react";
+import {humanFileSize, isAdmin, toTitleCase} from "Frontend/util/utils";
+import {DownloadEndpoint} from "Frontend/endpoints/endpoints";
+import {gameState, initializeGameState} from "Frontend/state/GameState";
+import {useSnapshot} from "valtio/react";
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import {CheckCircle, Info, MagnifyingGlass, Pencil, Trash, TriangleDashed} from "@phosphor-icons/react";
+import {useAuth} from "Frontend/util/auth";
+import MatchGameModal from "Frontend/components/general/modals/MatchGameModal";
+import EditGameMetadataModal from "Frontend/components/general/modals/EditGameMetadataModal";
+import GameUpdateDto from "Frontend/generated/org/gameyfin/app/games/dto/GameUpdateDto";
+import Markdown from "react-markdown";
+import remarkBreaks from "remark-breaks";
+
+export default function GameView() {
+ const {gameId} = useParams();
+
+ const navigate = useNavigate();
+ const auth = useAuth();
+
+ const editGameModal = useDisclosure();
+ const matchGameModal = useDisclosure();
+
+ const state = useSnapshot(gameState);
+ const game = gameId ? state.state[parseInt(gameId)] as GameDto : undefined;
+
+ const [downloadOptions, setDownloadOptions] = useState>();
+
+ useEffect(() => {
+ DownloadProviderEndpoint.getProviders().then((providers) => {
+ const options: Record = providers.reduce((acc, provider) => {
+ acc[provider.key] = {
+ label: provider.name,
+ description: provider.shortDescription ?? provider.description,
+ action: () => {
+ if (gameId) DownloadEndpoint.downloadGame(parseInt(gameId), provider.key);
+ },
+ };
+ return acc;
+ }, {} as Record);
+ setDownloadOptions(options);
+ });
+ }, []);
+
+ useEffect(() => {
+ initializeGameState().then((state) => {
+ if (!gameId || !state.state[parseInt(gameId)]) {
+ navigate("/", {replace: true});
+ }
+ });
+ }, [gameId]);
+
+ async function toggleMatchConfirmed() {
+ if (!game) return;
+ await GameEndpoint.updateGame(
+ {
+ id: game.id,
+ metadata: {matchConfirmed: !game.metadata.matchConfirmed}
+ } as GameUpdateDto
+ )
+ }
+
+ async function deleteGame() {
+ if (!game) return;
+ await GameEndpoint.deleteGame(game.id);
+ addToast({
+ title: "Game deleted",
+ description: `${game.title} removed from Gameyfin!`,
+ color: "success"
+ });
+ }
+
+ return game && (
+
+
+ {(game.imageIds && game.imageIds.length > 0) ?
+
:
+
+ }
+
+
+
+
+
+
+
+
+
+
{game.title}
+
+
+ {game.release !== undefined ? new Date(game.release).getFullYear() :
+
no data
}
+
+
+
+
+
+
+
+
+ {isAdmin(auth) &&
+
+ {game.metadata.matchConfirmed ?
+
+
+ :
+
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ await deleteGame();
+ navigate("/");
+ }}>
+
+
+
+
}
+ {downloadOptions &&
}
+
+
+
+ {game.comment &&
+
+ }>
+
+ {props.children}
+
+ }
+ }}
+ >{game.comment}
+
+
+ }
+
+
+
Summary
+ {game.summary ?
+
:
+
No summary available
+ }
+
+
+
Details
+
+
+
+ Developed by
+
+ {game.developers && game.developers.length > 0
+ ? [...game.developers].sort().map((dev, index) =>
+ <>
+
+ {dev}
+
+ {index !== game.developers!!.length - 1 && /
}
+ >
+ )
+ :
+
+
+ }
+
+
+
+ Published by
+
+ {game.publishers && game.publishers.length > 0
+ ? [...game.publishers].sort().join(" / ")
+ :
+
+
+ }
+
+
+
+ Genres
+
+ {game.genres && game.genres.length > 0
+ ? [...game.genres].sort().map(genre =>
+
+ {toTitleCase(genre)}
+
+ )
+ :
+
+
+ }
+
+
+
+ Themes
+
+ {game.themes && game.themes.length > 0
+ ? [...game.themes].sort().map(theme =>
+
+ {toTitleCase(theme)}
+
+ )
+ :
+
+
+ }
+
+
+
+ Features
+
+ {game.features && game.features.length > 0
+ ? [...game.features].sort().map(feature =>
+
+ {toTitleCase(feature)}
+
+ )
+ :
+
+
+ }
+
+
+
+
+
+
+
+
Media
+
`/images/screenshot/${id}`)}
+ videosUrls={game.videoUrls}
+ className="-mx-24"
+ />
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/HomeView.tsx b/app/src/main/frontend/views/HomeView.tsx
new file mode 100644
index 0000000..93f63bc
--- /dev/null
+++ b/app/src/main/frontend/views/HomeView.tsx
@@ -0,0 +1,29 @@
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import {CoverRow} from "Frontend/components/general/covers/CoverRow";
+import {useSnapshot} from "valtio/react";
+import {libraryState} from "Frontend/state/LibraryState";
+import {gameState} from "Frontend/state/GameState";
+import {useNavigate} from "react-router";
+
+export default function HomeView() {
+ const navigate = useNavigate();
+ const librariesState = useSnapshot(libraryState);
+ const gamesState = useSnapshot(gameState);
+ const recentlyAddedGames = gamesState.recentlyAdded as GameDto[];
+ const gamesByLibrary = gamesState.gamesByLibraryId as Record;
+
+ return (
+
+
+ navigate("/recently-added")}/>
+ {librariesState.libraries.map((library) => (
+ navigate("/library/" + library.id)}
+ />
+ ))}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/InvitationRegistrationView.tsx b/app/src/main/frontend/views/InvitationRegistrationView.tsx
new file mode 100644
index 0000000..0d7e475
--- /dev/null
+++ b/app/src/main/frontend/views/InvitationRegistrationView.tsx
@@ -0,0 +1,126 @@
+import {addToast, Button, Card, CardBody, CardHeader} from "@heroui/react";
+import {useNavigate, useSearchParams} from "react-router";
+import {Form, Formik} from "formik";
+import Input from "Frontend/components/general/input/Input";
+import * as Yup from "yup";
+import {RegistrationEndpoint} from "Frontend/generated/endpoints";
+import React, {useEffect, useState} from "react";
+import {Warning} from "@phosphor-icons/react";
+import UserInvitationAcceptanceResult
+ from "Frontend/generated/org/gameyfin/app/users/enums/UserInvitationAcceptanceResult";
+
+export default function InvitationRegistrationView() {
+ const [searchParams] = useSearchParams();
+ const [token, setToken] = useState();
+ const [email, setEmail] = useState();
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ let token = searchParams.get("token");
+ if (token) {
+ setToken(token);
+ RegistrationEndpoint.getInvitationRecipientEmail(token).then(setEmail);
+ }
+ }, [searchParams]);
+
+ async function register(values: any, formik: any) {
+ if (!token || !email) return;
+
+ let result = await RegistrationEndpoint.acceptInvitation(token, {
+ email: email,
+ username: values.username,
+ password: values.password
+ });
+
+ switch (result) {
+ case UserInvitationAcceptanceResult.SUCCESS:
+ addToast({
+ title: "Registration successful",
+ description: "Your account has been created",
+ color: "success"
+ });
+ navigate("/", {replace: true});
+ break;
+ case UserInvitationAcceptanceResult.USERNAME_TAKEN:
+ formik.setFieldError("username", "Username is already taken");
+ break;
+ case UserInvitationAcceptanceResult.TOKEN_EXPIRED:
+ addToast({
+ title: "Token expired",
+ description: "Token is expired",
+ color: "warning"
+ });
+ break;
+ case UserInvitationAcceptanceResult.TOKEN_INVALID:
+ default:
+ addToast({
+ title: "Invalid token",
+ description: "Token is invalid",
+ color: "danger"
+ });
+ break;
+ }
+ }
+
+ return (
+
+
+
+
+
+
+ {token ?
+
+ {(formik: { values: any; isSubmitting: any; isValid: boolean; }) => (
+
+ )}
+
+ :
+
+
+ Invalid token
+
+ }
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/LibraryManagementView.tsx b/app/src/main/frontend/views/LibraryManagementView.tsx
new file mode 100644
index 0000000..288ffc9
--- /dev/null
+++ b/app/src/main/frontend/views/LibraryManagementView.tsx
@@ -0,0 +1,54 @@
+import {useLocation, useNavigate, useParams} from "react-router";
+import React, {useEffect} from "react";
+import LibraryHeader from "Frontend/components/general/covers/LibraryHeader";
+import {Button, Tab, Tabs} from "@heroui/react";
+import {ArrowLeft} from "@phosphor-icons/react";
+import LibraryManagementDetails from "Frontend/components/general/library/LibraryManagementDetails";
+import LibraryManagementGames from "Frontend/components/general/library/LibraryManagementGames";
+import {useSnapshot} from "valtio/react";
+import {initializeLibraryState, libraryState} from "Frontend/state/LibraryState";
+import LibraryManagementUnmatchedPaths from "Frontend/components/general/library/LibraryManagementUnmatchedPaths";
+
+
+export default function LibraryManagementView() {
+ const {libraryId} = useParams();
+ const {hash} = useLocation();
+ const navigate = useNavigate();
+ const state = useSnapshot(libraryState);
+
+ useEffect(() => {
+ initializeLibraryState().then((state) => {
+ if (!libraryId || !state.state[parseInt(libraryId)]) {
+ navigate("/administration/libraries");
+ }
+ });
+ }, [libraryId]);
+
+ return libraryId && state.state[parseInt(libraryId)] &&
+
+
navigate("/administration/libraries")}>
+
+
+
Manage library
+
+ {/* @ts-ignore */}
+
+ {/* @ts-ignore */}
+
0 ? hash : "#details"}
+ onSelectionChange={(newKey) => navigate(newKey.toString(), {replace: true})}>
+
+ {/* @ts-ignore */}
+
+
+
+ {/* @ts-ignore */}
+
+
+
+ {/* @ts-ignore */}
+
+
+
+
;
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/LibraryView.tsx b/app/src/main/frontend/views/LibraryView.tsx
new file mode 100644
index 0000000..d52badf
--- /dev/null
+++ b/app/src/main/frontend/views/LibraryView.tsx
@@ -0,0 +1,29 @@
+import {useSnapshot} from "valtio/react";
+import {initializeLibraryState, libraryState} from "Frontend/state/LibraryState";
+import {gameState} from "Frontend/state/GameState";
+import React, {useEffect} from "react";
+import {useNavigate, useParams} from "react-router";
+import CoverGrid from "Frontend/components/general/covers/CoverGrid";
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+
+export default function LibraryView() {
+ const {libraryId} = useParams();
+ const navigate = useNavigate();
+ const libraries = useSnapshot(libraryState);
+ const games = (libraryId ? useSnapshot(gameState).gamesByLibraryId[parseInt(libraryId!!)] || [] : []) as GameDto[];
+
+ useEffect(() => {
+ initializeLibraryState().then((state) => {
+ if (!libraryId || !state.state[parseInt(libraryId)]) {
+ navigate("/", {replace: true});
+ }
+ });
+ }, [libraryId]);
+
+ return (
+
+
{libraries.state[parseInt(libraryId!!)]?.name}
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/LoginView.tsx b/app/src/main/frontend/views/LoginView.tsx
new file mode 100644
index 0000000..536f150
--- /dev/null
+++ b/app/src/main/frontend/views/LoginView.tsx
@@ -0,0 +1,97 @@
+import {useAuth} from "Frontend/util/auth";
+import {useEffect, useState} from "react";
+import {Button, Card, CardBody, CardHeader, Link, useDisclosure} from "@heroui/react";
+import {Form, Formik} from "formik";
+import Input from "Frontend/components/general/input/Input";
+import PasswordResetModal from "Frontend/components/general/modals/PasswordResetModal";
+import SignUpModal from "Frontend/components/general/modals/SignUpModal";
+import {RegistrationEndpoint} from "Frontend/generated/endpoints";
+import {useNavigate} from "react-router";
+
+export default function LoginView() {
+ const {state, login} = useAuth();
+ const navigate = useNavigate();
+
+ const passwordResetModal = useDisclosure();
+ const signUpModal = useDisclosure();
+
+ const [signUpAllowed, setSignUpAllowed] = useState(false);
+
+ useEffect(() => {
+ if (state.user) {
+ redirectAfterLogin();
+ } else {
+ RegistrationEndpoint.isSelfRegistrationAllowed().then(setSignUpAllowed);
+ }
+ }, [state.user]);
+
+ async function tryLogin(values: any, formik: any) {
+ const {defaultUrl, error, redirectUrl} = await login(values.username, values.password);
+ if (error) {
+ formik.setFieldError("username", " "); // Mark the field red, but don't show an error message
+ formik.setFieldError("password", "Invalid username and/or password.");
+ } else {
+ redirectAfterLogin(redirectUrl, defaultUrl);
+ }
+ }
+
+ function redirectAfterLogin(redirectUrl?: string, defaultUrl?: string) {
+ const url = redirectUrl ?? defaultUrl ?? '/';
+ navigate(url, {replace: true});
+ }
+
+ return (
+
+
+
+
+
+
+
+ {(formik: { isSubmitting: any; }) => (
+
+ )}
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/MainLayout.tsx b/app/src/main/frontend/views/MainLayout.tsx
new file mode 100644
index 0000000..8c02d61
--- /dev/null
+++ b/app/src/main/frontend/views/MainLayout.tsx
@@ -0,0 +1,135 @@
+import {useRouteMetadata} from 'Frontend/util/routing.js';
+import {useEffect, useState} from 'react';
+import ProfileMenu from "Frontend/components/ProfileMenu";
+import {Button, Divider, Link, Navbar, NavbarBrand, NavbarContent, NavbarItem, Tooltip} from "@heroui/react";
+import GameyfinLogo from "Frontend/components/theming/GameyfinLogo";
+import * as PackageJson from "../../../../package.json";
+import {Outlet, useLocation, useNavigate} from "react-router";
+import {useAuth} from "Frontend/util/auth";
+import {ArrowLeft, DiceSix, Heart, House, ListMagnifyingGlass} from "@phosphor-icons/react";
+import Confetti, {ConfettiProps} from "react-confetti-boom";
+import {useTheme} from "next-themes";
+import {UserPreferenceService} from "Frontend/util/user-preference-service";
+import SearchBar from "Frontend/components/general/SearchBar";
+import {useSnapshot} from "valtio/react";
+import {gameState} from "Frontend/state/GameState";
+import {scanState} from "Frontend/state/ScanState";
+import ScanProgressPopover from "Frontend/components/general/ScanProgressPopover";
+import {isAdmin} from "Frontend/util/utils";
+
+export default function MainLayout() {
+ const navigate = useNavigate();
+ const location = useLocation();
+ const auth = useAuth();
+ const routeMetadata = useRouteMetadata();
+ const {setTheme} = useTheme();
+ const isSearchPage = location.pathname.startsWith("/search");
+ const isHomePage = location.pathname === "/";
+ const [isExploding, setIsExploding] = useState(false);
+ const games = useSnapshot(gameState).games;
+ const scans = useSnapshot(scanState);
+
+ useEffect(() => {
+ let newTitle = `Gameyfin - ${routeMetadata?.title}`;
+ window.addEventListener('popstate', () => document.title = newTitle);
+
+ UserPreferenceService.sync()
+ .then(() => loadUserTheme().catch(console.error))
+ .catch(console.error);
+ }, []);
+
+ const confettiProps: ConfettiProps = {
+ mode: 'boom',
+ x: 0.5,
+ y: 1,
+ particleCount: 1000,
+ spreadDeg: 90,
+ launchSpeed: 4,
+ effectInterval: 10000
+ }
+
+ async function loadUserTheme() {
+ let syncedTheme = await UserPreferenceService.get("preferred-theme")
+ if (syncedTheme !== undefined) {
+ setTheme(syncedTheme);
+ }
+ }
+
+ function easterEgg() {
+ if (isExploding) return;
+ setIsExploding(true);
+ if (confettiProps.mode === "boom") {
+ setTimeout(() => setIsExploding(false), confettiProps.effectInterval);
+ }
+ }
+
+ function getRandomGameId() {
+ return games[Math.floor(Math.random() * games.length)].id;
+ }
+
+ return (
+
+ {isExploding ?
: <>>}
+
+
+
+ {isHomePage ? :
+
+
history.back()} variant="light">
+
+
+
navigate("/")} variant="light">
+
+
+
+ }
+
+ {!isSearchPage &&
+
+ navigate("/game/" + getRandomGameId())}
+ isDisabled={gameState.games.length === 0}>
+
+
+
+
+
+ navigate("/search")}>
+
+
+
+ }
+
+ {isAdmin(auth) &&
+
+
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/PasswordResetView.tsx b/app/src/main/frontend/views/PasswordResetView.tsx
new file mode 100644
index 0000000..223bbea
--- /dev/null
+++ b/app/src/main/frontend/views/PasswordResetView.tsx
@@ -0,0 +1,103 @@
+import {addToast, Button, Card, CardBody, CardHeader} from "@heroui/react";
+import {useNavigate, useSearchParams} from "react-router";
+import {Form, Formik} from "formik";
+import Input from "Frontend/components/general/input/Input";
+import * as Yup from "yup";
+import {PasswordResetEndpoint} from "Frontend/generated/endpoints";
+import React, {useEffect, useState} from "react";
+import {Warning} from "@phosphor-icons/react";
+import TokenValidationResult from "Frontend/generated/org/gameyfin/app/shared/token/TokenValidationResult";
+
+export default function PasswordResetView() {
+ const [searchParams, setSearchParams] = useSearchParams();
+ const [token, setToken] = useState();
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ let token = searchParams.get("token");
+ if (token) setToken(token);
+ }, [searchParams]);
+
+ async function resetPassword(values: any) {
+ let token = searchParams.get("token") as string;
+ let result = await PasswordResetEndpoint.resetPassword(token, values.password) as TokenValidationResult;
+
+ switch (result) {
+ case TokenValidationResult.VALID:
+ addToast({
+ title: "Password reset",
+ description: "Password reset successfully",
+ color: "success"
+ })
+ navigate("/", {replace: true});
+ break;
+ case TokenValidationResult.EXPIRED:
+ addToast({
+ title: "Token expired",
+ description: "Token is expired",
+ color: "warning"
+ })
+ break;
+ case TokenValidationResult.INVALID:
+ default:
+ addToast({
+ title: "Invalid token",
+ description: "Token is invalid",
+ color: "danger"
+ })
+ break
+ }
+ }
+
+ return (
+
+
+
+
+
+
+ {token ?
+
+ {(formik: { values: any; isSubmitting: any; isValid: boolean; }) => (
+
+ )}
+
+ :
+
+
+ Invalid token
+
+ }
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/ProfileView.tsx b/app/src/main/frontend/views/ProfileView.tsx
new file mode 100644
index 0000000..4e1fa8d
--- /dev/null
+++ b/app/src/main/frontend/views/ProfileView.tsx
@@ -0,0 +1,24 @@
+import {Palette, User} from "@phosphor-icons/react";
+import withSideMenu from "Frontend/components/general/withSideMenu";
+
+const menuItems = [
+ {
+ title: "My Profile",
+ url: "profile",
+ icon:
+ },
+ {
+ title: "Appearance",
+ url: "appearance",
+ icon:
+ },
+ /* TODO: Implement account self management
+ {
+ title: "Manage account",
+ url: "account-management",
+ icon:
+ }*/
+]
+
+export const ProfileView = withSideMenu("/settings", menuItems);
+export default ProfileView;
\ No newline at end of file
diff --git a/app/src/main/frontend/views/RecentlyAddedView.tsx b/app/src/main/frontend/views/RecentlyAddedView.tsx
new file mode 100644
index 0000000..8a02161
--- /dev/null
+++ b/app/src/main/frontend/views/RecentlyAddedView.tsx
@@ -0,0 +1,16 @@
+import {useSnapshot} from "valtio/react";
+import {gameState} from "Frontend/state/GameState";
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import React from "react";
+import CoverGrid from "Frontend/components/general/covers/CoverGrid";
+
+export default function RecentlyAddedView() {
+ const games = useSnapshot(gameState).recentlyAdded as GameDto[];
+
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/SearchView.tsx b/app/src/main/frontend/views/SearchView.tsx
new file mode 100644
index 0000000..261141b
--- /dev/null
+++ b/app/src/main/frontend/views/SearchView.tsx
@@ -0,0 +1,281 @@
+import {Input, Select, SelectItem} from "@heroui/react";
+import {MagnifyingGlass} from "@phosphor-icons/react";
+import {useSnapshot} from "valtio/react";
+import {gameState} from "Frontend/state/GameState";
+import {libraryState} from "Frontend/state/LibraryState";
+import {useSearchParams} from "react-router";
+import {useEffect, useMemo, useState} from "react";
+import {Fzf} from "fzf";
+import GameDto from "Frontend/generated/org/gameyfin/app/games/dto/GameDto";
+import LibraryDto from "Frontend/generated/org/gameyfin/app/libraries/dto/LibraryDto";
+import CoverGrid from "Frontend/components/general/covers/CoverGrid";
+import {toTitleCase} from "Frontend/util/utils";
+
+export default function SearchView() {
+ const games = useSnapshot(gameState).sortedAlphabetically as GameDto[];
+ const knownDevelopers = useSnapshot(gameState).knownDevelopers as Set;
+ const knownGenres = useSnapshot(gameState).knownGenres;
+ const knownThemes = useSnapshot(gameState).knownThemes;
+ const knownFeatures = useSnapshot(gameState).knownFeatures;
+ const knownPerspectives = useSnapshot(gameState).knownPerspectives;
+ const libraries = useSnapshot(libraryState).libraries as LibraryDto[];
+
+ const [searchParams, setSearchParams] = useSearchParams();
+ const [initialLoadComplete, setInitialLoadComplete] = useState(false);
+
+ // State to track selected filter values
+ const [searchTerm, setSearchTerm] = useState("");
+ const [selectedLibraries, setSelectedLibraries] = useState>(new Set());
+ const [selectedDevelopers, setSelectedDevelopers] = useState>(new Set());
+ const [selectedGenres, setSelectedGenres] = useState>(new Set());
+ const [selectedThemes, setSelectedThemes] = useState>(new Set());
+ const [selectedFeatures, setSelectedFeatures] = useState>(new Set());
+ const [selectedPerspectives, setSelectedPerspectives] = useState>(new Set());
+
+ // Load initial filter values from URL parameters on component mount
+ useEffect(() => {
+ // Get all parameters from the URL
+ const term = searchParams.get("term") || "";
+ const libs = searchParams.getAll("lib");
+ const devs = searchParams.getAll("dev");
+ const genres = searchParams.getAll("genre");
+ const themes = searchParams.getAll("theme");
+ const features = searchParams.getAll("feature");
+ const perspectives = searchParams.getAll("perspective");
+
+ setSearchTerm(term);
+ setSelectedLibraries(new Set(libs));
+ setSelectedDevelopers(new Set(devs));
+ setSelectedGenres(new Set(genres));
+ setSelectedThemes(new Set(themes));
+ setSelectedFeatures(new Set(features));
+ setSelectedPerspectives(new Set(perspectives));
+
+ setInitialLoadComplete(true);
+ }, []);
+
+ // Update search parameters whenever the filters change
+ useEffect(() => {
+ if (!initialLoadComplete) return;
+
+ const newParams = new URLSearchParams();
+
+ // Preserve search term if exists
+ if (searchTerm && searchTerm.trim() !== "") {
+ newParams.set("term", searchTerm);
+ }
+
+ // Only add parameters for non-empty filters
+ if (selectedLibraries.size > 0) {
+ selectedLibraries.forEach(lib => {
+ newParams.append("lib", lib.toString());
+ });
+ }
+
+ if (selectedDevelopers.size > 0) {
+ selectedDevelopers.forEach(dev => {
+ newParams.append("dev", dev);
+ });
+ }
+
+ if (selectedGenres.size > 0) {
+ selectedGenres.forEach(genre => {
+ newParams.append("genre", genre);
+ });
+ }
+
+ if (selectedThemes.size > 0) {
+ selectedThemes.forEach(theme => {
+ newParams.append("theme", theme);
+ });
+ }
+
+ if (selectedFeatures.size > 0) {
+ selectedFeatures.forEach(feature => {
+ newParams.append("feature", feature);
+ });
+ }
+
+ if (selectedPerspectives.size > 0) {
+ selectedPerspectives.forEach(perspective => {
+ newParams.append("perspective", perspective);
+ });
+ }
+
+ setSearchParams(newParams, {replace: true});
+ }, [searchTerm, selectedLibraries, selectedDevelopers, selectedGenres,
+ selectedThemes, selectedFeatures, selectedPerspectives]);
+
+ const filteredGames = useMemo(() => filterGames(), [
+ games, searchTerm,
+ selectedLibraries, selectedDevelopers,
+ selectedGenres, selectedThemes,
+ selectedFeatures, selectedPerspectives
+ ]);
+
+ function filterGames(): GameDto[] {
+ let filtered = games;
+
+ // Apply text search filter if term exists
+ if (searchTerm !== "") {
+ const fzf = new Fzf(filtered, {
+ selector: (game: GameDto) => game.title
+ });
+ filtered = fzf.find(searchTerm).map(result => result.item);
+ }
+
+ // Apply library filter
+ if (selectedLibraries.size > 0) {
+ filtered = filtered.filter(game => selectedLibraries.has(game.libraryId.toString()));
+ }
+
+ // Apply developer filter
+ if (selectedDevelopers.size > 0) {
+ filtered = filtered.filter(game =>
+ game.developers?.some(developer => selectedDevelopers.has(developer))
+ );
+ }
+
+ // Apply genre filter
+ if (selectedGenres.size > 0) {
+ filtered = filtered.filter(game =>
+ game.genres?.some(genre => selectedGenres.has(genre))
+ );
+ }
+
+ // Apply theme filter
+ if (selectedThemes.size > 0) {
+ filtered = filtered.filter(game =>
+ game.themes?.some(theme => selectedThemes.has(theme))
+ );
+ }
+
+ // Apply feature filter
+ if (selectedFeatures.size > 0) {
+ filtered = filtered.filter(game =>
+ game.features?.some(feature => selectedFeatures.has(feature))
+ );
+ }
+
+ // Apply perspective filter
+ if (selectedPerspectives.size > 0) {
+ filtered = filtered.filter(game =>
+ game.perspectives?.some(perspective => selectedPerspectives.has(perspective))
+ );
+ }
+
+ return filtered;
+ }
+
+ return
+
}
+ type="search"
+ value={searchTerm}
+ isClearable
+ onChange={(event) => setSearchTerm(event.target.value)}
+ onClear={() => setSearchTerm("")}
+ />
+
+
+ {libraries.map((library) => (
+ {library.name}
+ ))}
+
+
+ {Array.from(knownDevelopers).map((developer) => (
+ {developer}
+ ))}
+
+
+ {Array.from(knownGenres).map((genre) => (
+ {toTitleCase(genre)}
+ ))}
+
+
+ {Array.from(knownThemes).map((theme) => (
+ {toTitleCase(theme)}
+ ))}
+
+
+ {Array.from(knownFeatures).map((feature) => (
+ {toTitleCase(feature)}
+ ))}
+
+
+ {Array.from(knownPerspectives).map((perspective) => (
+ {toTitleCase(perspective)}
+ ))}
+
+
+
+
+ {filteredGames.length === 0 && (
+
+ No games found matching your filters
+
+ )}
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/frontend/views/SetupView.tsx b/app/src/main/frontend/views/SetupView.tsx
new file mode 100644
index 0000000..38d9a4c
--- /dev/null
+++ b/app/src/main/frontend/views/SetupView.tsx
@@ -0,0 +1,132 @@
+import React from 'react';
+import * as Yup from 'yup';
+import Wizard from "Frontend/components/wizard/Wizard";
+import WizardStep from "Frontend/components/wizard/WizardStep";
+import Input from "Frontend/components/general/input/Input";
+import {HandWaving, Palette, User} from "@phosphor-icons/react";
+import {addToast, Card} from "@heroui/react";
+import {SetupEndpoint} from "Frontend/generated/endpoints";
+import {ThemeSelector} from "Frontend/components/theming/ThemeSelector";
+import {useNavigate} from "react-router";
+
+function WelcomeStep() {
+ return (
+
+
+
Welcome to Gameyfin 👋
+
+ Gameyfin is a cutting-edge software tailored for gamers seeking efficient management of their
+ video
+ game collections. With its intuitive interface and comprehensive features, Gameyfin
+ simplifies the organization of game libraries. Users can effortlessly add games through manual
+ input
+ or
+ automated recognition, categorize them based on various criteria like genre or platform, track
+ in-game
+ progress, and share achievements with friends. Notably, Gameyfin stands out for its
+ user-friendly
+ design and adaptability, offering ample customization options to meet diverse user preferences.
+
+
Let's get started!
+
+
+ );
+}
+
+function ThemeStep() {
+ return (
+
+ );
+}
+
+function UserStep() {
+ return (
+
+ );
+}
+
+function SetupView() {
+ const navigate = useNavigate();
+
+ return (
+
+
+ {
+ await SetupEndpoint.registerSuperAdmin({
+ username: values.username,
+ password: values.password,
+ email: values.email
+ });
+ addToast({
+ title: "Setup finished",
+ description: "Have fun with Gameyfin!",
+ color: "success"
+ })
+ navigate('/login');
+ }
+ }
+ >
+ }>
+
+
+ }>
+
+
+ }
+ >
+
+
+
+
+
+ );
+}
+
+export default SetupView;
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/GameyfinApplication.kt b/app/src/main/kotlin/org/gameyfin/app/GameyfinApplication.kt
new file mode 100644
index 0000000..358b1ef
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/GameyfinApplication.kt
@@ -0,0 +1,18 @@
+package org.gameyfin.app
+
+import org.springframework.boot.autoconfigure.SpringBootApplication
+import org.springframework.boot.runApplication
+import org.springframework.scheduling.annotation.EnableAsync
+import org.springframework.scheduling.annotation.EnableScheduling
+import org.springframework.transaction.annotation.EnableTransactionManagement
+
+
+@SpringBootApplication
+@EnableScheduling
+@EnableTransactionManagement
+@EnableAsync
+class GameyfinApplication
+
+fun main(args: Array) {
+ runApplication(*args)
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/config/ConfigEndpoint.kt b/app/src/main/kotlin/org/gameyfin/app/config/ConfigEndpoint.kt
new file mode 100644
index 0000000..0077b70
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/config/ConfigEndpoint.kt
@@ -0,0 +1,44 @@
+package org.gameyfin.app.config
+
+import com.vaadin.hilla.Endpoint
+import io.github.oshai.kotlinlogging.KotlinLogging
+import jakarta.annotation.security.PermitAll
+import jakarta.annotation.security.RolesAllowed
+import org.gameyfin.app.config.dto.ConfigEntryDto
+import org.gameyfin.app.config.dto.ConfigUpdateDto
+import org.gameyfin.app.core.Role
+import org.gameyfin.app.users.util.isAdmin
+import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.security.core.userdetails.UserDetails
+import reactor.core.publisher.Flux
+
+@Endpoint
+@RolesAllowed(Role.Names.ADMIN)
+class ConfigEndpoint(
+ private val configService: ConfigService
+) {
+ companion object {
+ val log = KotlinLogging.logger { }
+ }
+
+ /** CRUD endpoints for admins **/
+
+ @PermitAll
+ fun subscribe(): Flux> {
+ val user = SecurityContextHolder.getContext().authentication.principal as UserDetails
+ return if (user.isAdmin()) ConfigService.subscribe()
+ else Flux.empty()
+ }
+
+ fun getAll(): List = configService.getAll()
+
+ fun update(update: ConfigUpdateDto) = configService.update(update)
+
+ /** Specific read-only endpoint for all users **/
+
+ @PermitAll
+ fun isSsoEnabled(): Boolean? = configService.get(ConfigProperties.SSO.OIDC.Enabled)
+
+ @PermitAll
+ fun getLogoutUrl(): String? = configService.get(ConfigProperties.SSO.OIDC.LogoutUrl)
+}
diff --git a/app/src/main/kotlin/org/gameyfin/app/config/ConfigProperties.kt b/app/src/main/kotlin/org/gameyfin/app/config/ConfigProperties.kt
new file mode 100644
index 0000000..6034db7
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/config/ConfigProperties.kt
@@ -0,0 +1,275 @@
+package org.gameyfin.app.config
+
+import org.springframework.boot.logging.LogLevel
+import java.io.Serializable
+import kotlin.reflect.KClass
+
+sealed class ConfigProperties(
+ val type: KClass,
+ val key: String,
+ val description: String,
+ val default: T? = null,
+ val allowedValues: List? = null
+) {
+
+ /** Libraries */
+ sealed class Libraries {
+ data object AllowPublicAccess : ConfigProperties(
+ Boolean::class,
+ "library.allow-public-access",
+ "Allow access to game libraries without login (coming soon™)",
+ false
+ )
+
+ sealed class Scan {
+ data object EnableFilesystemWatcher : ConfigProperties(
+ Boolean::class,
+ "library.scan.enable-filesystem-watcher",
+ "Enable automatic library scanning using file system watchers (coming soon™)",
+ false
+ )
+
+ data object ScanEmptyDirectories : ConfigProperties(
+ Boolean::class,
+ "library.scan.scan-empty-directories",
+ "Scan empty directories",
+ false
+ )
+
+ data object TitleMatchMinRatio : ConfigProperties(
+ Int::class,
+ "library.scan.title-match-min-ratio",
+ "Minimum ratio for title matching (0-100). Higher values mean stricter matching.",
+ 90
+ )
+
+ data object GameFileExtensions : ConfigProperties>(
+ Array::class,
+ "library.scan.game-file-extensions",
+ "File extensions to consider as games",
+ arrayOf(
+ "zip",
+ "tar",
+ "gz",
+ "rar",
+ "7z",
+ "bz2",
+ "xz",
+ "iso",
+ "jar",
+ "tgz",
+ "exe",
+ "bat",
+ "cmd",
+ "com",
+ "msi",
+ "bin",
+ "run",
+ "app",
+ "dmg",
+ "elf"
+ )
+ )
+ }
+
+ sealed class Metadata {
+ data object UpdateEnabled : ConfigProperties(
+ Boolean::class,
+ "library.metadata.update.enabled",
+ "Enable periodic refresh of video game metadata (coming soon™)",
+ false
+ )
+
+ data object UpdateSchedule : ConfigProperties(
+ String::class,
+ "library.metadata.update.schedule",
+ "Schedule for periodic metadata refresh in cron format",
+ "0 0 * * 0"
+ )
+ }
+ }
+
+ /** User management */
+ sealed class Users {
+ sealed class SignUps {
+ data object Allow : ConfigProperties(
+ Boolean::class,
+ "users.sign-ups.allow",
+ "Allow new users to sign up by themselves",
+ false
+ )
+
+ data object ConfirmationRequired : ConfigProperties(
+ Boolean::class,
+ "users.sign-ups.confirmation-required",
+ "Admins need to confirm new users",
+ true
+ )
+ }
+ }
+
+ /** Single Sign-On */
+ sealed class SSO {
+ sealed class OIDC {
+ data object Enabled : ConfigProperties(
+ Boolean::class,
+ "sso.oidc.enabled",
+ "Enable SSO via OIDC/OAuth2",
+ false
+ )
+
+ data object MatchExistingUsersBy : ConfigProperties(
+ MatchUsersBy::class,
+ "sso.oidc.match-existing-users-by",
+ "Match existing users by",
+ MatchUsersBy.username,
+ MatchUsersBy.entries
+ )
+
+ data object AutoRegisterNewUsers : ConfigProperties(
+ Boolean::class,
+ "sso.oidc.auto-register-new-users",
+ "Automatically create new users after registration",
+ true
+ )
+
+ data object ClientId : ConfigProperties(
+ String::class,
+ "sso.oidc.client-id",
+ "Client ID"
+ )
+
+ data object ClientSecret : ConfigProperties(
+ String::class,
+ "sso.oidc.client-secret",
+ "Client secret"
+ )
+
+ data object IssuerUrl : ConfigProperties(
+ String::class,
+ "sso.oidc.issuer-url",
+ "Issuer URL"
+ )
+
+ data object AuthorizeUrl : ConfigProperties(
+ String::class,
+ "sso.oidc.authorize-url",
+ "Authorize URL"
+ )
+
+ data object TokenUrl : ConfigProperties(
+ String::class,
+ "sso.oidc.token-url",
+ "Token URL"
+ )
+
+ data object UserInfoUrl : ConfigProperties(
+ String::class,
+ "sso.oidc.userinfo-url",
+ "Userinfo URL"
+ )
+
+ data object JwksUrl : ConfigProperties(
+ String::class,
+ "sso.oidc.jwks-url",
+ "JWKS URL"
+ )
+
+ data object LogoutUrl : ConfigProperties(
+ String::class,
+ "sso.oidc.logout-url",
+ "Logout URL"
+ )
+ }
+ }
+
+ /** Messages */
+ sealed class Messages {
+ sealed class Providers {
+ sealed class Email {
+ data object Enabled : ConfigProperties(
+ Boolean::class,
+ "messages.providers.email.enabled",
+ "Enable E-Mail notifications",
+ false
+ )
+
+ data object Host : ConfigProperties(
+ String::class,
+ "messages.providers.email.host",
+ "URL of the email server"
+ )
+
+ data object Port : ConfigProperties(
+ Int::class,
+ "messages.providers.email.port",
+ "Port of the email server",
+ 587
+ )
+
+ data object Username : ConfigProperties(
+ String::class,
+ "messages.providers.email.username",
+ "Username for the email account"
+ )
+
+ data object Password : ConfigProperties(
+ String::class,
+ "messages.providers.email.password",
+ "Password for the email account"
+ )
+ }
+ }
+ }
+
+ /** Logs */
+ sealed class Logs {
+ data object Folder : ConfigProperties(
+ String::class,
+ "logs.folder",
+ "Storage folder for log files",
+ "./logs"
+ )
+
+ data object MaxHistoryDays : ConfigProperties(
+ Int::class,
+ "logs.max-history-days",
+ "Log retention in days",
+ 30
+ )
+
+ sealed class Level {
+ data object Gameyfin : ConfigProperties(
+ LogLevel::class,
+ "logs.level.gameyfin",
+ "Log level (Gameyfin)",
+ LogLevel.INFO,
+ LogLevel.entries
+ )
+
+ data object Root : ConfigProperties(
+ LogLevel::class,
+ "logs.level.root",
+ "Log level (Root)",
+ LogLevel.WARN,
+ LogLevel.entries
+ )
+ }
+ }
+
+ /** System */
+ sealed class System {
+ sealed class Cors {
+ data object AllowedOrigins : ConfigProperties>(
+ Array::class,
+ "system.cors.allowed-origins",
+ "List of allowed CORS origins",
+ emptyArray()
+ )
+ }
+ }
+}
+
+enum class MatchUsersBy {
+ username, email
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/config/ConfigService.kt b/app/src/main/kotlin/org/gameyfin/app/config/ConfigService.kt
new file mode 100644
index 0000000..2caa883
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/config/ConfigService.kt
@@ -0,0 +1,227 @@
+package org.gameyfin.app.config
+
+import io.github.oshai.kotlinlogging.KotlinLogging
+import org.gameyfin.app.config.dto.ConfigEntryDto
+import org.gameyfin.app.config.dto.ConfigUpdateDto
+import org.gameyfin.app.config.entities.ConfigEntry
+import org.gameyfin.app.config.persistence.ConfigRepository
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Service
+import reactor.core.publisher.Flux
+import reactor.core.publisher.Sinks
+import java.io.Serializable
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.toJavaDuration
+
+@Service
+class ConfigService(
+ private val appConfigRepository: ConfigRepository
+) {
+ companion object {
+ private val log = KotlinLogging.logger {}
+
+ /* Websockets */
+ private val configUpdates = Sinks.many().multicast().onBackpressureBuffer(1024, false)
+
+ fun subscribe(): Flux> {
+ log.debug { "New subscription for configUpdates (#${configUpdates.currentSubscriberCount()})" }
+ return configUpdates.asFlux()
+ .buffer(100.milliseconds.toJavaDuration())
+ .doOnSubscribe { log.debug { "Subscriber added to configUpdates [${configUpdates.currentSubscriberCount()}]" } }
+ .doFinally {
+ log.debug { "Subscriber removed from configUpdates with signal type $it [${configUpdates.currentSubscriberCount()}]" }
+ }
+ }
+
+ fun emit(update: ConfigUpdateDto) {
+ configUpdates.tryEmitNext(update)
+ }
+ }
+
+ /**
+ * Get the current value of a config property in a type-safe way.
+ *
+ * @param configProperty: The config property containing necessary type information
+ * @return The current value if set or the default value or null if no value is set and no default value exists
+ */
+ fun get(configProperty: ConfigProperties): T? {
+
+ log.debug { "Getting config value '${configProperty.key}'" }
+
+ val appConfig = appConfigRepository.findByIdOrNull(configProperty.key)
+ return if (appConfig != null) {
+ getValue(appConfig.value, configProperty)
+ } else {
+ configProperty.default ?: return null
+ }
+ }
+
+ /**
+ * Get the current value of a config property in a *not* type-safe way.
+ * Used for the external API.
+ *
+ * @param key: The key of the config property
+ * @return The current value if set or the default value or null if no value is set and no default value exists
+ */
+ fun get(key: String): Serializable? {
+
+ log.debug { "Getting config value '$key'" }
+
+ val configProperty = findConfigProperty(key)
+
+ return get(configProperty)
+ }
+
+ /**
+ * Get all known config values.
+ *
+ * @return A map of all config values
+ */
+ fun getAll(): List {
+
+ log.debug { "Getting all config values" }
+
+ val configProperties = ConfigProperties::class.sealedSubclasses.flatMap { subclass ->
+ subclass.objectInstance?.let { listOf(it) } ?: listOf()
+ }
+
+ return configProperties.map { configProperty ->
+ ConfigEntryDto(
+ key = configProperty.key,
+ value = get(configProperty),
+ defaultValue = configProperty.default,
+ type = configProperty.type.simpleName ?: "Unknown",
+ elementType = configProperty.type.java.componentType?.simpleName,
+ allowedValues = configProperty.allowedValues?.map { it.toString() },
+ description = configProperty.description
+ )
+ }
+ }
+
+ /**
+ * Set the value for a specified key.
+ * Checks if the value can be cast to the type defined for the config property.
+ *
+ * @param key: Key of the target config property
+ * @param value: Value to set the config property to
+ * @throws IllegalArgumentException if the value can't be cast to the type defined for the config property
+ */
+ @Suppress("UNCHECKED_CAST")
+ fun set(key: String, value: T) {
+ log.debug { "Set config value '$key'" }
+
+ val configProperty = findConfigProperty(key)
+
+ var configEntry = appConfigRepository.findByIdOrNull(key)
+
+ val parsedValue =
+ if (value.javaClass.isArray) {
+ (value as Array).joinToString(",")
+ } else
+ value.toString()
+
+ if (configEntry == null) {
+ configEntry = ConfigEntry(configProperty.key, parsedValue)
+ } else {
+ configEntry.value = parsedValue
+ }
+
+ appConfigRepository.save(configEntry)
+ }
+
+ /**
+ * Set multiple config values at once.
+ * Configs with a null value will be deleted.
+ *
+ * @param update: A [ConfigUpdateDto] containing a map of key-value pairs to set
+ */
+ fun update(update: ConfigUpdateDto) {
+ update.updates.forEach { (key, value) ->
+ if (value == null) {
+ delete(key)
+ } else {
+ set(key, value)
+ }
+ }
+ emit(update)
+ }
+
+ /**
+ * Set the value for a specified key in a type-safe way.
+ *
+ * @param configProperty: The target config property
+ * @param value: Value to set the config property to
+ * @throws IllegalArgumentException if the value can't be cast to the type defined for the config property
+ */
+ fun set(configProperty: ConfigProperties, value: T) {
+ return set(configProperty.key, value)
+ }
+
+ /**
+ * Remove a config property from the database.
+ * This will also cause it to reset to its default value.
+ *
+ * @param key: Key of the config property
+ */
+ fun delete(key: String) {
+
+ log.debug { "Delete config value '$key'" }
+
+ val configKey = findConfigProperty(key)
+ appConfigRepository.deleteById(configKey.key)
+ }
+
+ /**
+ * Get the value of the config property in a type-safe way.
+ */
+ @Suppress("UNCHECKED_CAST")
+ private fun getValue(value: Serializable, configProperty: ConfigProperties): T {
+ val value = value.toString()
+ return when {
+ configProperty.type == String::class -> value as T
+ configProperty.type == Boolean::class -> value.toBoolean() as T
+ configProperty.type == Int::class -> value.toFloat().toInt() as T
+ configProperty.type == Float::class -> value.toFloat() as T
+
+ configProperty.type.java.isEnum -> {
+ val enumConstants = configProperty.type.java.enumConstants
+ enumConstants.firstOrNull { it.toString() == value }
+ ?: throw IllegalArgumentException("Unknown enum value '$value' for key ${configProperty.key}")
+ }
+
+ configProperty.type.java.isArray -> {
+ val componentType = configProperty.type.java.componentType
+ // Remove the brackets and split the string by commas
+ val elements = value
+ .removeSurrounding("[", "]")
+ .split(",")
+ .filter { it.isNotBlank() }
+
+ when (componentType) {
+ String::class.java -> elements.toTypedArray() as T
+ Boolean::class.java -> elements.map { it.toBoolean() }.toTypedArray() as T
+ Int::class.java -> elements.map { it.toInt() }.toTypedArray() as T
+ Float::class.java -> elements.map { it.toFloat() }.toTypedArray() as T
+ else -> throw IllegalArgumentException("Unsupported array type: ${componentType.name}")
+ }
+ }
+
+ else -> throw IllegalArgumentException("Unknown config type ${configProperty.type}: '$value' for key ${configProperty.key}")
+ }
+ }
+
+ /**
+ * Returns a config property
+ */
+ private fun findConfigProperty(key: String): ConfigProperties<*> {
+ // Use reflection to get all objects defined within ConfigKey
+ val configProperties = ConfigProperties::class.sealedSubclasses.flatMap { subclass ->
+ subclass.objectInstance?.let { listOf(it) } ?: listOf()
+ }
+
+ // Find the matching config key based on the string key
+ return configProperties.find { it.key == key }
+ ?: throw IllegalArgumentException("Unknown configuration key: $key")
+ }
+}
+
diff --git a/app/src/main/kotlin/org/gameyfin/app/config/dto/ConfigEntryDto.kt b/app/src/main/kotlin/org/gameyfin/app/config/dto/ConfigEntryDto.kt
new file mode 100644
index 0000000..30f632a
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/config/dto/ConfigEntryDto.kt
@@ -0,0 +1,15 @@
+package org.gameyfin.app.config.dto
+
+import com.fasterxml.jackson.annotation.JsonInclude
+import java.io.Serializable
+
+@JsonInclude(JsonInclude.Include.ALWAYS)
+data class ConfigEntryDto(
+ val key: String,
+ val description: String,
+ val value: Serializable?,
+ val defaultValue: Serializable?,
+ val type: String,
+ val elementType: String?,
+ val allowedValues: List?
+)
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/config/dto/ConfigUpdateDto.kt b/app/src/main/kotlin/org/gameyfin/app/config/dto/ConfigUpdateDto.kt
new file mode 100644
index 0000000..182c53f
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/config/dto/ConfigUpdateDto.kt
@@ -0,0 +1,10 @@
+package org.gameyfin.app.config.dto
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize
+import org.gameyfin.app.core.serialization.ArrayDeserializer
+import java.io.Serializable
+
+data class ConfigUpdateDto(
+ @get:JsonDeserialize(contentUsing = ArrayDeserializer::class)
+ val updates: Map
+)
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/config/entities/ConfigEntry.kt b/app/src/main/kotlin/org/gameyfin/app/config/entities/ConfigEntry.kt
new file mode 100644
index 0000000..64fe3cf
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/config/entities/ConfigEntry.kt
@@ -0,0 +1,16 @@
+package org.gameyfin.app.config.entities
+
+import jakarta.persistence.*
+import org.gameyfin.app.core.security.EncryptionConverter
+
+@Entity
+@Table(name = "app_config")
+class ConfigEntry(
+ @Id
+ @Column(name = "`key`", unique = true)
+ val key: String,
+
+ @Column(name = "`value`")
+ @Convert(converter = EncryptionConverter::class)
+ var value: String
+)
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/config/persistence/ConfigRepository.kt b/app/src/main/kotlin/org/gameyfin/app/config/persistence/ConfigRepository.kt
new file mode 100644
index 0000000..76e0c21
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/config/persistence/ConfigRepository.kt
@@ -0,0 +1,6 @@
+package org.gameyfin.app.config.persistence
+
+import org.gameyfin.app.config.entities.ConfigEntry
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface ConfigRepository : JpaRepository
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/Role.kt b/app/src/main/kotlin/org/gameyfin/app/core/Role.kt
new file mode 100644
index 0000000..0401300
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/Role.kt
@@ -0,0 +1,42 @@
+package org.gameyfin.app.core
+
+import com.fasterxml.jackson.annotation.JsonCreator
+import com.fasterxml.jackson.annotation.JsonValue
+import org.gameyfin.app.users.RoleService
+import java.lang.Enum
+
+enum class Role(val roleName: String, val powerLevel: Int) {
+
+ SUPERADMIN(Names.SUPERADMIN, 3),
+ ADMIN(Names.ADMIN, 2),
+ USER(Names.USER, 1);
+
+ @JsonValue
+ override fun toString(): String {
+ return this.roleName
+ }
+
+ companion object {
+
+ @JsonCreator
+ @JvmStatic
+ fun fromValue(value: String): Role? {
+ val enumString = value.removePrefix(RoleService.Companion.INTERNAL_ROLE_PREFIX)
+ return entries.find { it.roleName == enumString }
+ }
+
+ fun safeValueOf(type: String): Role? {
+ val enumString = type.removePrefix(RoleService.Companion.INTERNAL_ROLE_PREFIX)
+ return Enum.valueOf(Role::class.java, enumString)
+ }
+ }
+
+ // necessary for the ability to use the Roles class in the @RolesAllowed annotation
+ class Names {
+ companion object {
+ const val SUPERADMIN = "${RoleService.Companion.INTERNAL_ROLE_PREFIX}SUPERADMIN"
+ const val ADMIN = "${RoleService.Companion.INTERNAL_ROLE_PREFIX}ADMIN"
+ const val USER = "${RoleService.Companion.INTERNAL_ROLE_PREFIX}USER"
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/SetupDataLoader.kt b/app/src/main/kotlin/org/gameyfin/app/core/SetupDataLoader.kt
new file mode 100644
index 0000000..6ef13a3
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/SetupDataLoader.kt
@@ -0,0 +1,72 @@
+package org.gameyfin.app.core
+
+import org.gameyfin.app.setup.SetupService
+import org.gameyfin.app.users.UserService
+import io.github.oshai.kotlinlogging.KotlinLogging
+import org.gameyfin.app.users.entities.User
+import org.springframework.boot.context.event.ApplicationReadyEvent
+import org.springframework.context.event.EventListener
+import org.springframework.core.env.Environment
+import org.springframework.stereotype.Service
+import java.net.InetAddress
+
+
+@Service
+class SetupDataLoader(
+ private val userService: UserService,
+ private val setupService: SetupService,
+ private val env: Environment
+) {
+ private val log = KotlinLogging.logger {}
+
+ @EventListener(ApplicationReadyEvent::class)
+ fun initialSetup() {
+ if (setupService.isSetupCompleted()) return
+
+ log.info { "Looks like this is the first time you're starting Gameyfin." }
+
+ if ("dev" in env.activeProfiles) {
+ log.info { "We will now set up some data for local development..." }
+ setupUsers()
+ log.info { "Setup completed..." }
+ }
+
+ val protocol = if (env.getProperty("server.ssl.key-store") != null) "https" else "http"
+
+ log.info { "Visit $protocol://${InetAddress.getLocalHost().hostName}:${env.getProperty("server.port")}/setup to complete the setup" }
+ }
+
+ fun setupUsers() {
+ log.info { "Setting up users..." }
+
+ val superadmin = User(
+ username = "admin",
+ password = "admin",
+ email = "admin@gameyfin.org",
+ emailConfirmed = true,
+ enabled = true,
+ roles = listOf(Role.SUPERADMIN)
+ )
+
+ registerUserIfNotFound(superadmin)
+
+ val user = User(
+ username = "user",
+ password = "user",
+ email = "user@gameyfin.org",
+ emailConfirmed = true,
+ enabled = true,
+ roles = listOf(Role.USER)
+ )
+
+ registerUserIfNotFound(user)
+
+ log.info { "User setup completed." }
+ }
+
+ fun registerUserIfNotFound(user: User) {
+ if (userService.existsByUsername(user.username)) return
+
+ userService.registerOrUpdateUser(user)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/Utils.kt b/app/src/main/kotlin/org/gameyfin/app/core/Utils.kt
new file mode 100644
index 0000000..6409c68
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/Utils.kt
@@ -0,0 +1,109 @@
+package org.gameyfin.app.core
+
+import org.apache.tika.Tika
+import org.springframework.core.io.ByteArrayResource
+import org.springframework.http.HttpHeaders
+import org.springframework.http.MediaType
+import org.springframework.http.ResponseEntity
+import org.springframework.web.context.request.RequestContextHolder
+import org.springframework.web.context.request.ServletRequestAttributes
+import kotlin.text.iterator
+
+
+class Utils {
+ companion object {
+ private val tika = Tika()
+
+ fun maskEmail(email: String): String {
+ val regex = """(?:\G(?!^)|(?<=^[^@]{2}|@))[^@](?!\.[^.]+$)""".toRegex()
+ return email.replace(regex, "*")
+ }
+
+ fun getBaseUrl(): String {
+ val request = (RequestContextHolder.getRequestAttributes() as ServletRequestAttributes).request
+ val scheme = request.scheme
+ val serverName = request.serverName
+ val serverPort = request.serverPort
+
+ return if (serverPort == 80 || serverPort == 443) {
+ "$scheme://$serverName"
+ } else {
+ "$scheme://$serverName:$serverPort"
+ }
+ }
+
+ fun inputStreamToResponseEntity(bytes: ByteArray?): ResponseEntity {
+ if (bytes == null) return ResponseEntity.notFound().build()
+
+ val byteArrayResource = ByteArrayResource(bytes)
+
+ val headers = HttpHeaders()
+ val contentLength = bytes.size.toLong()
+ val contentType = tika.detect(bytes)
+
+ headers.contentLength = contentLength
+ headers.contentType = MediaType.parseMediaType(contentType)
+
+ return ResponseEntity.ok()
+ .headers(headers)
+ .body(byteArrayResource)
+ }
+ }
+}
+
+/**
+ * Converts a map with nullable values to a map with non-nullable values by filtering out null values
+ */
+@Suppress("UNCHECKED_CAST")
+fun Map.filterValuesNotNull() = filterValues { it != null } as Map
+
+/**
+ * Converts a string to an alphanumeric string by removing all non-alphanumeric characters (except whitespaces)
+ * and converting it to lowercase
+ */
+fun String.alphaNumeric() = filter { it.isLetterOrDigit() || it.isWhitespace() }.lowercase()
+
+/**
+ * Replaces standalone Roman numerals in a string with their corresponding integer values.
+ *
+ * Roman numerals are detected only when they appear as separate "words"—
+ * i.e., they are preceded by whitespace or the start of the string,
+ * and followed by a word boundary, whitespace, or the end of the string.
+ *
+ * Valid Roman numerals are assumed to be in the range 1 to 3999 (inclusive),
+ * in line with standard Roman numeral notation. Any match outside this range
+ * is ignored and left unchanged to avoid false positives.
+ *
+ * Example:
+ * "Helldivers II" -> "Helldivers 2"
+ * "Age of Empires III" -> "Age of Empires 3"
+ * "IVy League" -> "IVy League" (unchanged)
+ */
+fun String.replaceRomanNumerals(): String {
+ val romanNumeralMap = mapOf(
+ 'M' to 1000, 'D' to 500, 'C' to 100,
+ 'L' to 50, 'X' to 10, 'V' to 5, 'I' to 1
+ )
+
+ fun romanToInt(roman: String): Int {
+ var sum = 0
+ var prev = 0
+ for (char in roman.reversed()) {
+ val value = romanNumeralMap[char] ?: return -1
+ if (value < prev) sum -= value else sum += value
+ prev = value
+ }
+ return sum
+ }
+
+ val regex = Regex(
+ """(?<=\s|^)(M{0,4}(CM|CD|D?C{0,3})?(XC|XL|L?X{0,3})?(IX|IV|V?I{0,3})?)(?=\b|\s|$)""",
+ RegexOption.IGNORE_CASE
+ )
+
+ return regex.replace(this) { match ->
+ val roman = match.value.uppercase()
+ val number = romanToInt(roman)
+ if (number in 1..3999) number.toString() else match.value
+ }
+}
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/annotations/DynamicAccessInterceptor.kt b/app/src/main/kotlin/org/gameyfin/app/core/annotations/DynamicAccessInterceptor.kt
new file mode 100644
index 0000000..8595a18
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/annotations/DynamicAccessInterceptor.kt
@@ -0,0 +1,38 @@
+package org.gameyfin.app.core.annotations
+
+import org.gameyfin.app.config.ConfigService
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
+import org.gameyfin.app.config.ConfigProperties
+import org.springframework.stereotype.Component
+import org.springframework.web.method.HandlerMethod
+import org.springframework.web.servlet.HandlerInterceptor
+
+@Component
+class DynamicAccessInterceptor(
+ private val configService: ConfigService
+) : HandlerInterceptor {
+
+ override fun preHandle(
+ request: HttpServletRequest,
+ response: HttpServletResponse,
+ handler: Any
+ ): Boolean {
+ val handlerMethod = (handler as? HandlerMethod) ?: return true
+ val method = handlerMethod.method
+
+ // Check if method is annotated with @DynamicPublicAccess
+ if (method.isAnnotationPresent(DynamicPublicAccess::class.java)) {
+ // Check if user is authenticated or public access is enabled
+ if (request.userPrincipal != null || configService.get(ConfigProperties.Libraries.AllowPublicAccess) == true) {
+ return true
+ }
+
+ // Deny access if user is not logged in and public access is disabled
+ response.status = HttpServletResponse.SC_UNAUTHORIZED
+ return false
+ }
+
+ return true
+ }
+}
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/annotations/DynamicPublicAccess.kt b/app/src/main/kotlin/org/gameyfin/app/core/annotations/DynamicPublicAccess.kt
new file mode 100644
index 0000000..4176bc5
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/annotations/DynamicPublicAccess.kt
@@ -0,0 +1,15 @@
+package org.gameyfin.app.core.annotations
+
+import kotlin.annotation.AnnotationRetention.RUNTIME
+import kotlin.annotation.AnnotationTarget.CLASS
+import kotlin.annotation.AnnotationTarget.FUNCTION
+
+/**
+ * This annotation is used on endpoint methods which can be switched between publicly accessible and
+ * only accessible for registered users.
+ * One example would be the main library view.
+ */
+
+@Target(FUNCTION, CLASS)
+@Retention(RUNTIME)
+annotation class DynamicPublicAccess
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/annotations/NullOrNotBlank.kt b/app/src/main/kotlin/org/gameyfin/app/core/annotations/NullOrNotBlank.kt
new file mode 100644
index 0000000..a6f0913
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/annotations/NullOrNotBlank.kt
@@ -0,0 +1,15 @@
+package org.gameyfin.app.core.annotations
+
+import jakarta.validation.Constraint
+import jakarta.validation.Payload
+import kotlin.reflect.KClass
+
+@MustBeDocumented
+@Constraint(validatedBy = [NullOrNotBlankValidator::class])
+@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER)
+@Retention(AnnotationRetention.RUNTIME)
+annotation class NullOrNotBlank(
+ val message: String = "must be null or not blank",
+ val groups: Array> = [],
+ val payload: Array> = []
+)
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/annotations/NullOrNotBlankValidator.kt b/app/src/main/kotlin/org/gameyfin/app/core/annotations/NullOrNotBlankValidator.kt
new file mode 100644
index 0000000..a58b5e5
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/annotations/NullOrNotBlankValidator.kt
@@ -0,0 +1,11 @@
+package org.gameyfin.app.core.annotations
+
+import jakarta.validation.ConstraintValidator
+import jakarta.validation.ConstraintValidatorContext
+
+class NullOrNotBlankValidator : ConstraintValidator {
+
+ override fun isValid(value: String?, context: ConstraintValidatorContext): Boolean {
+ return value == null || value.isNotBlank()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/development/DelayInterceptor.kt b/app/src/main/kotlin/org/gameyfin/app/core/development/DelayInterceptor.kt
new file mode 100644
index 0000000..89c55c9
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/development/DelayInterceptor.kt
@@ -0,0 +1,19 @@
+package org.gameyfin.app.core.development
+
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
+import org.springframework.context.annotation.Profile
+import org.springframework.stereotype.Component
+import org.springframework.web.servlet.HandlerInterceptor
+
+
+@Component
+@Profile("delay")
+class DelayInterceptor : HandlerInterceptor {
+
+ override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
+ if (request.requestURI.startsWith("/connect")) Thread.sleep(2000)
+ return true
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadEndpoint.kt b/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadEndpoint.kt
new file mode 100644
index 0000000..b5f604d
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadEndpoint.kt
@@ -0,0 +1,41 @@
+package org.gameyfin.app.core.download
+
+import org.gameyfin.app.core.annotations.DynamicPublicAccess
+import org.gameyfin.app.games.GameService
+import org.gameyfin.pluginapi.download.FileDownload
+import org.gameyfin.pluginapi.download.LinkDownload
+import org.springframework.http.ResponseEntity
+import org.springframework.web.bind.annotation.*
+import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody
+
+@RestController
+@RequestMapping("/download")
+@DynamicPublicAccess
+class DownloadEndpoint(
+ private val downloadService: DownloadService,
+ private val gameService: GameService
+) {
+ @GetMapping("/{gameId}")
+ fun downloadGame(
+ @PathVariable gameId: Long,
+ @RequestParam provider: String
+ ): ResponseEntity {
+ val game = gameService.getById(gameId)
+ gameService.incrementDownloadCount(game)
+ val download = downloadService.getDownload(game.metadata.path, provider)
+
+ return when (download) {
+ is FileDownload -> {
+ ResponseEntity.ok()
+ .header("Content-Disposition", "attachment; filename=\"${game.title}.${download.fileExtension}\"")
+ .body(StreamingResponseBody { outputStream ->
+ download.data.copyTo(outputStream)
+ })
+ }
+
+ is LinkDownload -> {
+ TODO("Handle download link")
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadProviderDto.kt b/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadProviderDto.kt
new file mode 100644
index 0000000..ce828d8
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadProviderDto.kt
@@ -0,0 +1,12 @@
+package org.gameyfin.app.core.download
+
+import com.fasterxml.jackson.annotation.JsonInclude
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+data class DownloadProviderDto(
+ val key: String,
+ val name: String,
+ val priority: Int,
+ val description: String,
+ val shortDescription: String? = null
+)
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadProviderEndpoint.kt b/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadProviderEndpoint.kt
new file mode 100644
index 0000000..933b1f8
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadProviderEndpoint.kt
@@ -0,0 +1,14 @@
+package org.gameyfin.app.core.download
+
+import com.vaadin.hilla.Endpoint
+import jakarta.annotation.security.PermitAll
+
+@Endpoint
+@PermitAll
+class DownloadProviderEndpoint(
+ private val downloadService: DownloadService
+) {
+ fun getProviders(): List {
+ return downloadService.getProviders().sortedByDescending { it.priority }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadService.kt b/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadService.kt
new file mode 100644
index 0000000..efed758
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/download/DownloadService.kt
@@ -0,0 +1,39 @@
+package org.gameyfin.app.core.download
+
+import org.gameyfin.app.core.plugins.management.GameyfinPluginDescriptor
+import org.gameyfin.app.core.plugins.management.GameyfinPluginManager
+import org.gameyfin.pluginapi.download.Download
+import org.gameyfin.pluginapi.download.DownloadProvider
+import org.springframework.stereotype.Service
+import kotlin.io.path.Path
+
+@Service
+class DownloadService(
+ private val pluginManager: GameyfinPluginManager,
+) {
+ private val downloadPlugins: List
+ get() = pluginManager.getExtensions(DownloadProvider::class.java)
+
+ fun getProviders(): List {
+ return downloadPlugins.map {
+ val plugin = pluginManager.whichPlugin(it.javaClass.enclosingClass)
+ val managementEntry = pluginManager.getManagementEntry(plugin.pluginId)
+ val descriptor = plugin.descriptor as GameyfinPluginDescriptor
+
+ DownloadProviderDto(
+ key = it.javaClass.name,
+ name = descriptor.pluginName,
+ priority = managementEntry.priority,
+ description = descriptor.pluginDescription,
+ shortDescription = descriptor.pluginShortDescription,
+ )
+ }
+ }
+
+ fun getDownload(path: String, provider: String): Download {
+ val provider = downloadPlugins.firstOrNull { it.javaClass.name == provider }
+ ?: throw IllegalArgumentException("Download provider $provider not found")
+
+ return provider.download(Path(path))
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/events/Events.kt b/app/src/main/kotlin/org/gameyfin/app/core/events/Events.kt
new file mode 100644
index 0000000..db5131b
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/events/Events.kt
@@ -0,0 +1,28 @@
+package org.gameyfin.app.core.events
+
+import org.gameyfin.app.shared.token.Token
+import org.gameyfin.app.shared.token.TokenType
+import org.gameyfin.app.users.entities.User
+import org.springframework.context.ApplicationEvent
+
+class UserInvitationEvent(source: Any, val token: Token, val baseUrl: String, val email: String) :
+ ApplicationEvent(source)
+
+class UserRegistrationWaitingForApprovalEvent(source: Any, val newUser: User) : ApplicationEvent(source)
+
+class AccountStatusChangedEvent(source: Any, val user: User, val baseUrl: String) : ApplicationEvent(source)
+
+class EmailNeedsConfirmationEvent(source: Any, val token: Token, val baseUrl: String) :
+ ApplicationEvent(source)
+
+class RegistrationAttemptWithExistingEmailEvent(source: Any, val existingUser: User, val baseUrl: String) :
+ ApplicationEvent(source)
+
+class PasswordResetRequestEvent(source: Any, val token: Token, val baseUrl: String) :
+ ApplicationEvent(source)
+
+class AccountDeletedEvent(source: Any, val user: User, val baseUrl: String) : ApplicationEvent(source)
+
+class GameRequestEvent(source: Any) : ApplicationEvent(source)
+
+class GameRequestApprovalEvent(source: Any) : ApplicationEvent(source)
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FileDto.kt b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FileDto.kt
new file mode 100644
index 0000000..d8e216d
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FileDto.kt
@@ -0,0 +1,7 @@
+package org.gameyfin.app.core.filesystem
+
+data class FileDto(
+ val name: String,
+ val type: FileType,
+ val hash: Int
+)
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FileType.kt b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FileType.kt
new file mode 100644
index 0000000..d24b102
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FileType.kt
@@ -0,0 +1,6 @@
+package org.gameyfin.app.core.filesystem
+
+enum class FileType {
+ FILE,
+ DIRECTORY,
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FilesystemEndpoint.kt b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FilesystemEndpoint.kt
new file mode 100644
index 0000000..8c935b7
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FilesystemEndpoint.kt
@@ -0,0 +1,18 @@
+package org.gameyfin.app.core.filesystem
+
+import com.vaadin.hilla.Endpoint
+import jakarta.annotation.security.RolesAllowed
+import org.gameyfin.app.core.Role
+
+@Endpoint
+@RolesAllowed(Role.Names.ADMIN)
+class FilesystemEndpoint(
+ private val filesystemService: FilesystemService
+) {
+
+ fun listContents(path: String) = filesystemService.listContents(path)
+
+ fun listSubDirectories(path: String) = filesystemService.listSubDirectories(path)
+
+ fun getHostOperatingSystem() = filesystemService.getHostOperatingSystem()
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FilesystemScanResult.kt b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FilesystemScanResult.kt
new file mode 100644
index 0000000..8bb0f7f
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FilesystemScanResult.kt
@@ -0,0 +1,9 @@
+package org.gameyfin.app.core.filesystem
+
+import java.nio.file.Path
+
+data class FilesystemScanResult(
+ val newPaths: List,
+ val removedGamePaths: List,
+ val removedUnmatchedPaths: List
+)
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FilesystemService.kt b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FilesystemService.kt
new file mode 100644
index 0000000..f126d77
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/FilesystemService.kt
@@ -0,0 +1,171 @@
+package org.gameyfin.app.core.filesystem
+
+import org.gameyfin.app.config.ConfigService
+import io.github.oshai.kotlinlogging.KotlinLogging
+import org.apache.commons.io.FilenameUtils
+import org.gameyfin.app.config.ConfigProperties
+import org.gameyfin.app.libraries.Library
+import org.springframework.stereotype.Service
+import java.io.File
+import java.nio.file.FileSystems
+import java.nio.file.Path
+import kotlin.io.path.*
+
+@Service
+class FilesystemService(
+ private val config: ConfigService
+) {
+
+ private val log = KotlinLogging.logger {}
+
+ private val gameFileExtensions
+ get() = config.get(ConfigProperties.Libraries.Scan.GameFileExtensions)!!.map { it.trim().lowercase() }
+
+ /**
+ * Lists all files and directories in the given path.
+ * If the path is null or empty, it lists all root directories.
+ *
+ * @param path The path to list files and directories from.
+ * @return A list of FileDto objects representing the files and directories.
+ */
+ fun listContents(path: String?): List {
+ if (path == null || path.isEmpty()) {
+ val roots = FileSystems.getDefault().rootDirectories.toList()
+
+ if (getHostOperatingSystem() == OperatingSystemType.WINDOWS) return roots.map {
+ FileDto(
+ it.root.toString(),
+ if (it.isDirectory()) FileType.DIRECTORY else FileType.FILE,
+ it.hashCode()
+ )
+ }
+
+ // UNIX file systems only have one root, so return its contents directly
+ return safeReadDirectoryContents(roots.first().toString())
+ }
+
+ val path = FilenameUtils.separatorsToSystem(path)
+
+ return safeReadDirectoryContents(path)
+ }
+
+ /**
+ * Lists all subdirectories in the given path.
+ * If the path is null or empty, it lists all root directories.
+ *
+ * @param path The path to list subdirectories from.
+ * @return A list of FileDto objects representing the subdirectories.
+ */
+ fun listSubDirectories(path: String?): List {
+ return listContents(path).filter { it.type == FileType.DIRECTORY }
+ }
+
+ fun getHostOperatingSystem(): OperatingSystemType {
+ val os = System.getProperty("os.name").lowercase()
+ return when {
+ os.contains("win") -> OperatingSystemType.WINDOWS
+ os.contains("mac") -> OperatingSystemType.MAC
+ os.contains("nux") -> OperatingSystemType.LINUX
+ else -> OperatingSystemType.UNKNOWN
+ }
+ }
+
+ /**
+ * Scans the given library for files and directories potentially containing games.
+ *
+ * @param library The library to scan.
+ * @return A list of paths representing game files and directories.
+ */
+ fun scanLibraryForGamefiles(library: Library): FilesystemScanResult {
+ // Cache the game file extensions to avoid reading them multiple times in the same scan
+ val gamefileExtensions = gameFileExtensions
+
+ // Filter out invalid directories (directories could have been changed externally after the library was created)
+ val validPaths = library.directories.map { Path(it.internalPath) }
+ .filter { path ->
+ if (!path.isDirectory()) {
+ log.warn { "Invalid directory '$path' in library '${library.name}'" }
+ false
+ } else {
+ true
+ }
+ }
+
+ // Get all paths that are directories or match the game file extensions
+ // Also check if the directory is empty and if empty directories should be included
+ val currentFilesystemPaths = validPaths.flatMap { validDirectory ->
+ safeReadDirectoryContents(validDirectory)
+ .filter { it.isDirectory() || it.extension.lowercase() in gamefileExtensions }
+ .filter {
+ if (!it.isDirectory()) return@filter true
+
+ val contents = safeReadDirectoryContents(it)
+ if (contents.isEmpty() && !config.get(ConfigProperties.Libraries.Scan.ScanEmptyDirectories)!!) {
+ log.debug { "Directory '$it' is empty and will be ignored" }
+ return@filter false
+ } else {
+ return@filter true
+ }
+ }
+ }
+
+ // Get all paths already in the library as game files or as unmatched paths
+ val currentLibraryGamePaths = library.games.map { Path(it.metadata.path) }
+ val currentLibraryUnmatchedPaths = library.unmatchedPaths.map { Path(it) }
+ val allCurrentLibraryPaths = currentLibraryGamePaths + currentLibraryUnmatchedPaths
+
+ //Get all paths that are on the filesystem, but not in the library (either as game or as unmatched path)
+ val newPaths = currentFilesystemPaths.filter { path ->
+ val isInLibrary = allCurrentLibraryPaths.any { it == path }
+ !isInLibrary
+ }
+
+ //Get all paths that are in the library (either as game or as unmatched path), but not on the filesystem
+ val removedGamePaths = currentLibraryGamePaths.filter { path ->
+ val isOnFilesystem = currentFilesystemPaths.any { it == path }
+ !isOnFilesystem
+ }
+
+ val removedUnmatchedPaths = currentLibraryUnmatchedPaths.filter { path ->
+ val isOnFilesystem = currentFilesystemPaths.any { it == path }
+ !isOnFilesystem
+ }
+
+ return FilesystemScanResult(
+ newPaths = newPaths,
+ removedGamePaths = removedGamePaths,
+ removedUnmatchedPaths = removedUnmatchedPaths
+ )
+ }
+
+ fun calculateFileSize(path: String): Long {
+ return try {
+ val file = File(path)
+ if (file.isFile) {
+ file.length()
+ } else if (file.isDirectory) {
+ File(path).walkTopDown().filter { it.isFile }.map { it.length() }.sum()
+ } else {
+ 0L
+ }
+ } catch (e: Exception) {
+ log.warn { "Error calculating file size for $path: ${e.message}" }
+ 0L
+ }
+ }
+
+ private fun safeReadDirectoryContents(path: String): List {
+ return safeReadDirectoryContents(Path(path))
+ .map { FileDto(it.name, if (it.isDirectory()) FileType.DIRECTORY else FileType.FILE, it.hashCode()) }
+ }
+
+ private fun safeReadDirectoryContents(path: Path): List {
+ return try {
+ path.listDirectoryEntries()
+ .filter { !it.isHidden() }
+ } catch (_: Exception) {
+ log.warn { "Error reading directory contents of $path" }
+ emptyList()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/filesystem/OperatingSystemType.kt b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/OperatingSystemType.kt
new file mode 100644
index 0000000..ec3b269
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/filesystem/OperatingSystemType.kt
@@ -0,0 +1,8 @@
+package org.gameyfin.app.core.filesystem
+
+enum class OperatingSystemType {
+ WINDOWS,
+ MAC,
+ LINUX,
+ UNKNOWN,
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/logging/LogEndpoint.kt b/app/src/main/kotlin/org/gameyfin/app/core/logging/LogEndpoint.kt
new file mode 100644
index 0000000..d455884
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/logging/LogEndpoint.kt
@@ -0,0 +1,28 @@
+package org.gameyfin.app.core.logging
+
+import com.vaadin.hilla.Endpoint
+import jakarta.annotation.security.PermitAll
+import jakarta.annotation.security.RolesAllowed
+import org.gameyfin.app.core.Role
+import org.gameyfin.app.users.util.isAdmin
+import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.security.core.userdetails.UserDetails
+import reactor.core.publisher.Flux
+
+@Endpoint
+@RolesAllowed(Role.Names.ADMIN)
+class LogEndpoint(
+ private val logService: LogService
+) {
+
+ fun reloadLogConfig() {
+ logService.configureFileLogging()
+ }
+
+ @PermitAll
+ fun getApplicationLogs(): Flux {
+ val user = SecurityContextHolder.getContext().authentication.principal as UserDetails
+ return if (user.isAdmin()) logService.streamLogs()
+ else Flux.empty()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/logging/LogService.kt b/app/src/main/kotlin/org/gameyfin/app/core/logging/LogService.kt
new file mode 100644
index 0000000..3518963
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/logging/LogService.kt
@@ -0,0 +1,94 @@
+package org.gameyfin.app.core.logging
+
+import ch.qos.logback.classic.LoggerContext
+import ch.qos.logback.classic.joran.JoranConfigurator
+import org.gameyfin.app.config.ConfigService
+import io.github.oshai.kotlinlogging.KotlinLogging
+import org.gameyfin.app.config.ConfigProperties
+import org.gameyfin.app.core.logging.util.AsyncFileTailer
+import org.slf4j.LoggerFactory
+import org.springframework.boot.context.event.ApplicationStartedEvent
+import org.springframework.boot.logging.LogLevel
+import org.springframework.context.event.EventListener
+import org.springframework.stereotype.Service
+import reactor.core.publisher.Flux
+import reactor.core.publisher.Sinks
+import java.io.InputStream
+import java.nio.file.Path
+import java.nio.file.Paths
+import kotlin.time.Duration.Companion.seconds
+
+@Service
+class LogService(
+ private val config: ConfigService
+) {
+
+ companion object {
+ private const val LOG_CONFIG_TEMPLATE = "templates/log-config-template.xml"
+ private const val LOG_FILE_NAME = "gameyfin"
+ private val LOG_REFRESH_INTERVAL = 5.seconds
+ private const val LOG_STREAM_RETENTION = 1000
+ }
+
+ private val log = KotlinLogging.logger {}
+
+ private var logFilePath: Path? = null
+ private val sink: Sinks.Many = Sinks.many().replay().limit(LOG_STREAM_RETENTION)
+ private var tailer: AsyncFileTailer? = null
+
+ @EventListener(ApplicationStartedEvent::class)
+ fun configureFileLogging() {
+ return configureFileLogging(
+ config.get(ConfigProperties.Logs.Folder)!!,
+ config.get(ConfigProperties.Logs.MaxHistoryDays)!!,
+ config.get(ConfigProperties.Logs.Level.Gameyfin)!!,
+ config.get(ConfigProperties.Logs.Level.Root)!!
+ )
+ }
+
+ fun configureFileLogging(folder: String, maxHistoryDays: Int, levelGameyfin: LogLevel, levelRoot: LogLevel) {
+ val context = LoggerFactory.getILoggerFactory() as LoggerContext
+ val configurator = JoranConfigurator()
+ configurator.context = context
+ context.reset()
+
+ generateLogConfigXml(folder.removeSuffix("/"), maxHistoryDays, levelGameyfin, levelRoot).use {
+ log.info { "Setting log level for Gameyfin to $levelGameyfin" }
+ log.info { "Setting log level for Root to $levelRoot" }
+ log.info { "Setting log retention to $maxHistoryDays days" }
+ configurator.doConfigure(it)
+
+ val newLogFilePath = Paths.get(folder, "$LOG_FILE_NAME.log")
+ if (newLogFilePath != logFilePath) {
+ logFilePath = newLogFilePath
+
+ tailer?.stopTailing()
+ tailer = AsyncFileTailer(newLogFilePath.toFile(), LOG_REFRESH_INTERVAL, sink)
+ tailer?.startTailing()
+ }
+ }
+ }
+
+ fun streamLogs(): Flux {
+ return sink.asFlux()
+ }
+
+ private fun generateLogConfigXml(
+ folder: String,
+ maxHistoryDays: Int,
+ levelGameyfin: LogLevel,
+ levelRoot: LogLevel
+ ): InputStream {
+ val template = javaClass.classLoader.getResourceAsStream(LOG_CONFIG_TEMPLATE)
+ ?: throw IllegalStateException("Log config template not found")
+
+ val templateString = template.bufferedReader().use { it.readText() }
+ return templateString
+ .replace("{LOG_FOLDER}", folder)
+ .replace("{LOG_FILE_NAME}", LOG_FILE_NAME)
+ .replace("{LOG_MAX_HISTORY_DAYS}", maxHistoryDays.toString())
+ .replace("{LOG_LEVEL_GAMEYFIN}", levelGameyfin.toString())
+ .replace("{LOG_LEVEL_ROOT}", levelRoot.toString())
+ .byteInputStream()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/logging/dto/LogConfigDto.kt b/app/src/main/kotlin/org/gameyfin/app/core/logging/dto/LogConfigDto.kt
new file mode 100644
index 0000000..4d89ccd
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/logging/dto/LogConfigDto.kt
@@ -0,0 +1,9 @@
+package org.gameyfin.app.core.logging.dto
+
+import org.springframework.boot.logging.LogLevel
+
+data class LogConfigDto(
+ val logFolder: String,
+ val maxHistoryDays: Int,
+ val logLevel: LogLevel
+)
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/logging/util/AsyncFileTailer.kt b/app/src/main/kotlin/org/gameyfin/app/core/logging/util/AsyncFileTailer.kt
new file mode 100644
index 0000000..f143963
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/logging/util/AsyncFileTailer.kt
@@ -0,0 +1,64 @@
+package org.gameyfin.app.core.logging.util
+
+import io.github.oshai.kotlinlogging.KotlinLogging
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import org.apache.commons.io.input.Tailer
+import org.apache.commons.io.input.TailerListenerAdapter
+import reactor.core.publisher.Sinks
+import java.io.File
+import kotlin.time.Duration
+import kotlin.time.toJavaDuration
+
+/**
+ * Wraps Tailer from Apache Commons IO to tail a file asynchronously using Kotlin Coroutines.
+ * Results are emitted to a sink
+ *
+ * @param file The file to tail
+ * @param interval The interval to check for new lines
+ * @param sink The sink to emit new lines to
+ * @see Tailer
+ */
+class AsyncFileTailer(
+ private val file: File,
+ interval: Duration,
+ private val sink: Sinks.Many
+) {
+ private val log = KotlinLogging.logger {}
+
+ private var tailerJob: Job? = null
+
+ private val tailer = Tailer.builder()
+ .setFile(file)
+ .setTailerListener(object : TailerListenerAdapter() {
+ override fun handle(line: String?) {
+ line?.let { sink.tryEmitNext(it) }
+ }
+ })
+ // Who tf thought it was a good idea to start a thread by default?
+ .setStartThread(false)
+ .setDelayDuration(interval.toJavaDuration())
+ .get()
+
+ fun startTailing() {
+ if (tailerJob == null || tailerJob?.isCancelled == true) {
+ tailerJob = CoroutineScope(Dispatchers.IO).launch {
+ tailer.run()
+ }
+
+ log.debug { "Started tailing the file: ${file.name}" }
+ } else {
+ log.error { "File tailing for file ${file.name} is already running!" }
+ }
+ }
+
+ fun stopTailing() {
+ tailerJob?.let {
+ it.cancel()
+ tailerJob = null
+ log.debug { "Stopped tailing the file: ${file.name}" }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/PluginEndpoint.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/PluginEndpoint.kt
new file mode 100644
index 0000000..75df853
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/PluginEndpoint.kt
@@ -0,0 +1,44 @@
+package org.gameyfin.app.core.plugins
+
+import com.vaadin.hilla.Endpoint
+import jakarta.annotation.security.PermitAll
+import jakarta.annotation.security.RolesAllowed
+import org.gameyfin.app.core.Role
+import org.gameyfin.app.core.plugins.dto.PluginUpdateDto
+import org.gameyfin.app.users.util.isAdmin
+import org.gameyfin.pluginapi.core.config.PluginConfigValidationResult
+import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.security.core.userdetails.UserDetails
+import reactor.core.publisher.Flux
+
+@Endpoint
+@RolesAllowed(Role.Names.ADMIN)
+class PluginEndpoint(
+ private val pluginService: PluginService
+) {
+
+ @PermitAll
+ fun subscribe(): Flux> {
+ val user = SecurityContextHolder.getContext().authentication.principal as UserDetails
+ return if (user.isAdmin()) PluginService.subscribe()
+ else Flux.empty()
+ }
+
+ fun getAll() = pluginService.getAll().sortedByDescending { it.priority }
+
+ fun enablePlugin(pluginId: String) = pluginService.enablePlugin(pluginId)
+
+ fun disablePlugin(pluginId: String) = pluginService.disablePlugin(pluginId)
+
+ fun setPluginPriorities(pluginPriorities: Map) =
+ pluginService.setPluginPriorities(pluginPriorities)
+
+ fun validatePluginConfig(pluginId: String): PluginConfigValidationResult =
+ pluginService.validatePluginConfig(pluginId, true)
+
+ fun validateNewConfig(pluginId: String, config: Map): PluginConfigValidationResult =
+ pluginService.validatePluginConfig(pluginId, config)
+
+ fun updateConfig(pluginId: String, updatedConfig: Map) =
+ pluginService.updateConfig(pluginId, updatedConfig)
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/PluginService.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/PluginService.kt
new file mode 100644
index 0000000..bd15f64
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/PluginService.kt
@@ -0,0 +1,191 @@
+package org.gameyfin.app.core.plugins
+
+import io.github.oshai.kotlinlogging.KotlinLogging
+import org.gameyfin.app.core.plugins.config.PluginConfigEntry
+import org.gameyfin.app.core.plugins.config.PluginConfigEntryKey
+import org.gameyfin.app.core.plugins.config.PluginConfigRepository
+import org.gameyfin.app.core.plugins.dto.PluginConfigMetadataDto
+import org.gameyfin.app.core.plugins.dto.PluginDto
+import org.gameyfin.app.core.plugins.dto.PluginUpdateDto
+import org.gameyfin.app.core.plugins.management.GameyfinPluginDescriptor
+import org.gameyfin.app.core.plugins.management.GameyfinPluginManager
+import org.gameyfin.app.core.plugins.management.PluginManagementEntry
+import org.gameyfin.app.core.plugins.management.PluginManagementRepository
+import org.gameyfin.pluginapi.core.config.Configurable
+import org.gameyfin.pluginapi.core.config.PluginConfigValidationResult
+import org.gameyfin.pluginapi.core.wrapper.GameyfinPlugin
+import org.pf4j.ExtensionPoint
+import org.pf4j.PluginWrapper
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Service
+import reactor.core.publisher.Flux
+import reactor.core.publisher.Sinks
+import kotlin.time.Duration.Companion.milliseconds
+import kotlin.time.toJavaDuration
+
+@Service
+class PluginService(
+ private val pluginManager: GameyfinPluginManager,
+ private val pluginManagementRepository: PluginManagementRepository,
+ private val pluginConfigRepository: PluginConfigRepository
+) {
+ companion object {
+ private val log = KotlinLogging.logger {}
+
+ /* Websockets */
+ private val pluginUpdates = Sinks.many().multicast().onBackpressureBuffer(1024, false)
+
+ fun subscribe(): Flux> {
+ log.debug { "New subscription for pluginUpdates" }
+ return pluginUpdates.asFlux()
+ .buffer(100.milliseconds.toJavaDuration())
+ .doOnSubscribe { log.debug { "Subscriber added to pluginUpdates [${pluginUpdates.currentSubscriberCount()}]" } }
+ .doFinally {
+ log.debug { "Subscriber removed from pluginUpdates with signal type $it [${pluginUpdates.currentSubscriberCount()}]" }
+ }
+ }
+
+ fun emit(update: PluginUpdateDto) {
+ pluginUpdates.tryEmitNext(update)
+ }
+ }
+
+ private val pluginConfigValidationCache = mutableMapOf()
+
+ init {
+ pluginManager.addPluginStateListener { event ->
+ val update = PluginUpdateDto(id = event.plugin.pluginId, state = event.pluginState)
+ emit(update)
+ }
+ }
+
+ fun getSupportedPluginTypes(): List {
+ return pluginManager.plugins
+ .flatMap { pluginManager.getExtensionTypes(it.pluginId) }
+ }
+
+ fun getAll(): List {
+ return pluginManager.plugins
+ .map { toDto(it) }
+ }
+
+ fun getPluginManagementEntry(clazz: Class): PluginManagementEntry {
+ val pluginWrapper = pluginManager.whichPlugin(clazz)
+ return pluginManagementRepository.findByIdOrNull(pluginWrapper.pluginId)
+ ?: throw IllegalArgumentException("Plugin with class $clazz not found")
+ }
+
+ fun enablePlugin(pluginId: String) {
+ pluginManager.enablePlugin(pluginId)
+ }
+
+ fun disablePlugin(pluginId: String) {
+ pluginManager.disablePlugin(pluginId)
+ }
+
+ fun setPluginPriorities(pluginPriorities: Map) {
+ pluginPriorities.forEach { (pluginId, priority) ->
+ val pluginManagementEntry = pluginManager.getManagementEntry(pluginId)
+ pluginManagementEntry.priority = priority
+ pluginManagementRepository.save(pluginManagementEntry)
+ }
+ }
+
+ fun getLogo(pluginId: String): ByteArray? {
+ val plugin = pluginManager.getPlugin(pluginId).plugin as GameyfinPlugin
+ return plugin.getLogo()
+ }
+
+ fun getConfigMetadata(pluginWrapper: PluginWrapper): List? {
+ log.debug { "Getting config metadata for plugin ${pluginWrapper.pluginId}" }
+ val plugin = pluginWrapper.plugin
+
+ if (plugin !is Configurable) return null
+
+ return plugin.configMetadata.map { meta ->
+ PluginConfigMetadataDto(
+ key = meta.key,
+ type = meta.type.simpleName ?: "Unknown",
+ label = meta.label,
+ description = meta.description,
+ default = meta.default,
+ isSecret = meta.isSecret,
+ isRequired = meta.isRequired,
+ allowedValues = meta.allowedValues?.map { it.toString() }
+ )
+ }
+ }
+
+ fun getConfig(pluginWrapper: PluginWrapper): Map {
+ log.debug { "Getting config for plugin ${pluginWrapper.pluginId}" }
+ return pluginConfigRepository.findAllById_PluginId(pluginWrapper.pluginId).associate { it.id.key to it.value }
+ }
+
+ fun updateConfig(pluginId: String, config: Map) {
+ log.debug { "Setting config entries for plugin $pluginId" }
+ val entries = config.map { PluginConfigEntry(PluginConfigEntryKey(pluginId, it.key), it.value) }
+
+ // Persist new config
+ pluginConfigRepository.saveAll(entries)
+
+ // Restart plugin to apply new config
+ pluginManager.restart(pluginId)
+
+ // Validate new config
+ val result = validatePluginConfig(pluginId, true)
+
+ // Emit update event
+ val update = PluginUpdateDto(pluginId, config = config, configValidation = result)
+ emit(update)
+ }
+
+ fun validatePluginConfig(pluginId: String, forceRevalidation: Boolean = false): PluginConfigValidationResult {
+ if (forceRevalidation || !pluginConfigValidationCache.containsKey(pluginId)) {
+ log.debug { "Validating config for plugin $pluginId" }
+ val result = pluginManager.validatePluginConfig(pluginId)
+ pluginConfigValidationCache[pluginId] = result
+ return result
+ } else {
+ log.debug { "Using cached validation result for plugin $pluginId" }
+ return pluginConfigValidationCache[pluginId]!!
+ }
+ }
+
+ fun validatePluginConfig(pluginId: String, configToValidate: Map): PluginConfigValidationResult {
+ return pluginManager.validatePluginConfig(pluginId, configToValidate)
+ }
+
+ private fun toDto(pluginWrapper: PluginWrapper): PluginDto {
+ val pluginManagementEntry = pluginManager.getManagementEntry(pluginWrapper.pluginId)
+
+ val hasLogo = try {
+ when (pluginWrapper.plugin is GameyfinPlugin) {
+ true -> (pluginWrapper.plugin as GameyfinPlugin).hasLogo()
+ false -> false
+ }
+ } catch (_: NoClassDefFoundError) {
+ false
+ }
+
+ val descriptor = pluginWrapper.descriptor as GameyfinPluginDescriptor
+
+ return PluginDto(
+ id = descriptor.pluginId,
+ types = pluginManager.getExtensionTypes(pluginWrapper.pluginId),
+ name = descriptor.pluginName,
+ description = descriptor.pluginDescription,
+ shortDescription = descriptor.pluginShortDescription,
+ version = descriptor.version,
+ author = descriptor.author,
+ license = descriptor.license,
+ url = descriptor.pluginUrl,
+ hasLogo = hasLogo,
+ state = pluginWrapper.pluginState,
+ configMetadata = getConfigMetadata(pluginWrapper),
+ config = getConfig(pluginWrapper),
+ configValidation = validatePluginConfig(descriptor.pluginId),
+ priority = pluginManagementEntry.priority,
+ trustLevel = pluginManagementEntry.trustLevel
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/config/PluginConfigEntry.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/config/PluginConfigEntry.kt
new file mode 100644
index 0000000..87c2174
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/config/PluginConfigEntry.kt
@@ -0,0 +1,25 @@
+package org.gameyfin.app.core.plugins.config
+
+import jakarta.persistence.*
+import org.gameyfin.app.core.security.EncryptionConverter
+import java.io.Serializable
+
+@Entity
+@Table(name = "plugin_config")
+data class PluginConfigEntry(
+ @EmbeddedId
+ val id: PluginConfigEntryKey,
+
+ @Column(name = "`value`")
+ @Convert(converter = EncryptionConverter::class)
+ val value: String
+)
+
+@Embeddable
+data class PluginConfigEntryKey(
+ @Column(name = "plugin_id")
+ val pluginId: String,
+
+ @Column(name = "`key`")
+ val key: String
+) : Serializable
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/config/PluginConfigRepository.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/config/PluginConfigRepository.kt
new file mode 100644
index 0000000..e64b79e
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/config/PluginConfigRepository.kt
@@ -0,0 +1,8 @@
+package org.gameyfin.app.core.plugins.config
+
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface PluginConfigRepository : JpaRepository {
+ fun findAllById_PluginId(pluginId: String): List
+ fun findById_PluginIdAndId_Key(pluginId: String, key: String): PluginConfigEntry?
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/dto/PluginConfigMetadataDto.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/dto/PluginConfigMetadataDto.kt
new file mode 100644
index 0000000..5e7b1c6
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/dto/PluginConfigMetadataDto.kt
@@ -0,0 +1,16 @@
+package org.gameyfin.app.core.plugins.dto
+
+import com.fasterxml.jackson.annotation.JsonInclude
+import java.io.Serializable
+
+@JsonInclude(JsonInclude.Include.ALWAYS)
+class PluginConfigMetadataDto(
+ val key: String,
+ val type: String,
+ val label: String,
+ val description: String,
+ val default: Serializable?,
+ val isSecret: Boolean,
+ val isRequired: Boolean,
+ val allowedValues: List?
+)
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/dto/PluginDto.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/dto/PluginDto.kt
new file mode 100644
index 0000000..c0112ee
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/dto/PluginDto.kt
@@ -0,0 +1,24 @@
+package org.gameyfin.app.core.plugins.dto
+
+import org.gameyfin.app.core.plugins.management.PluginTrustLevel
+import org.gameyfin.pluginapi.core.config.PluginConfigValidationResult
+import org.pf4j.PluginState
+
+data class PluginDto(
+ val id: String,
+ val types: List,
+ val name: String,
+ val description: String,
+ val shortDescription: String? = null,
+ val version: String,
+ val author: String,
+ val license: String? = null,
+ val url: String? = null,
+ val hasLogo: Boolean,
+ val state: PluginState,
+ val configMetadata: List? = null,
+ val config: Map? = null,
+ val configValidation: PluginConfigValidationResult? = null,
+ val priority: Int,
+ val trustLevel: PluginTrustLevel,
+)
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/dto/PluginUpdateDto.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/dto/PluginUpdateDto.kt
new file mode 100644
index 0000000..2501aa6
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/dto/PluginUpdateDto.kt
@@ -0,0 +1,14 @@
+package org.gameyfin.app.core.plugins.dto
+
+import com.fasterxml.jackson.annotation.JsonInclude
+import org.gameyfin.pluginapi.core.config.PluginConfigValidationResult
+import org.pf4j.PluginState
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+data class PluginUpdateDto(
+ val id: String,
+ val state: PluginState? = null,
+ val config: Map? = null,
+ val configValidation: PluginConfigValidationResult? = null,
+ val priority: Int? = null
+)
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/DatabasePluginStatusProvider.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/DatabasePluginStatusProvider.kt
new file mode 100644
index 0000000..a827ae9
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/DatabasePluginStatusProvider.kt
@@ -0,0 +1,35 @@
+package org.gameyfin.app.core.plugins.management
+
+import org.pf4j.PluginStatusProvider
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Component
+
+@Component
+class DatabasePluginStatusProvider(
+ private val pluginManagementRepository: PluginManagementRepository
+) : PluginStatusProvider {
+
+ override fun isPluginDisabled(pluginId: String): Boolean {
+ val pluginManagement = pluginManagementRepository.findByIdOrNull(pluginId)
+
+ if (pluginManagement == null) return true
+
+ return !pluginManagement.enabled
+ }
+
+ override fun disablePlugin(pluginId: String) {
+ val pluginManagement = pluginManagementRepository.findByIdOrNull(pluginId)
+ if (pluginManagement != null) {
+ pluginManagement.enabled = false
+ pluginManagementRepository.save(pluginManagement)
+ }
+ }
+
+ override fun enablePlugin(pluginId: String) {
+ val pluginManagement = pluginManagementRepository.findByIdOrNull(pluginId)
+ if (pluginManagement != null) {
+ pluginManagement.enabled = true
+ pluginManagementRepository.save(pluginManagement)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinDevelopmentPluginLoader.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinDevelopmentPluginLoader.kt
new file mode 100644
index 0000000..431a257
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinDevelopmentPluginLoader.kt
@@ -0,0 +1,20 @@
+package org.gameyfin.app.core.plugins.management
+
+import org.pf4j.DevelopmentPluginLoader
+import org.pf4j.PluginClassLoader
+import org.pf4j.PluginDescriptor
+import org.pf4j.PluginManager
+import java.nio.file.Path
+
+/**
+ * @see https://stackoverflow.com/questions/73654174/my-application-cant-find-the-extension-with-pf4j
+ */
+class GameyfinDevelopmentPluginLoader(
+ pluginManager: PluginManager,
+ private val parentClassLoader: ClassLoader
+) : DevelopmentPluginLoader(pluginManager) {
+
+ override fun createPluginClassLoader(pluginPath: Path, pluginDescriptor: PluginDescriptor): PluginClassLoader {
+ return PluginClassLoader(pluginManager, pluginDescriptor, parentClassLoader)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinExtensionFinder.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinExtensionFinder.kt
new file mode 100644
index 0000000..c2cf86d
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinExtensionFinder.kt
@@ -0,0 +1,63 @@
+package org.gameyfin.app.core.plugins.management
+
+import io.github.oshai.kotlinlogging.KotlinLogging
+import org.pf4j.ExtensionDescriptor
+import org.pf4j.ExtensionWrapper
+import org.pf4j.LegacyExtensionFinder
+import org.pf4j.PluginManager
+
+class GameyfinExtensionFinder(pluginManager: PluginManager) : LegacyExtensionFinder(pluginManager) {
+ companion object {
+ private val log = KotlinLogging.logger { }
+ }
+
+ override fun find(pluginId: String?): MutableList?> {
+ log.debug { "Finding extensions from plugin '$pluginId'" }
+ val result: MutableList?> = ArrayList()
+
+ val classNames = findClassNames(pluginId)
+ if (classNames.isEmpty()) {
+ return result
+ }
+
+ if (pluginId != null) {
+ log.trace { "Checking extensions from plugin '$pluginId'" }
+ } else {
+ log.trace { "Checking extensions from classpath" }
+ }
+
+ val classLoader =
+ if (pluginId != null) pluginManager.getPluginClassLoader(pluginId) else javaClass.getClassLoader()
+
+ for (className in classNames) {
+ try {
+ log.debug { "Loading class '$className' using class loader '$classLoader'" }
+ val extensionClass = classLoader.loadClass(className)
+
+ val extensionWrapper: ExtensionWrapper<*> = createExtensionWrapper(extensionClass)
+ result.add(extensionWrapper)
+ log.debug { "Added extension '$className' with ordinal ${extensionWrapper.ordinal}" }
+ } catch (e: ClassNotFoundException) {
+ log.error(e) { e.message }
+ } catch (e: NoClassDefFoundError) {
+ log.error(e) { e.message }
+ }
+ }
+
+ if (result.isEmpty()) {
+ log.debug { "No extensions found for plugin '$pluginId'" }
+ } else {
+ log.debug { "Found ${result.size} extensions for plugin '$pluginId'" }
+ }
+
+ return result
+ }
+
+ private fun createExtensionWrapper(extensionClass: Class<*>): ExtensionWrapper<*> {
+ val extensionAnnotation = findExtensionAnnotation(extensionClass)
+ val ordinal = extensionAnnotation?.ordinal ?: 0
+ val descriptor = ExtensionDescriptor(ordinal, extensionClass)
+
+ return ExtensionWrapper(descriptor, pluginManager.extensionFactory)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinJarPluginLoader.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinJarPluginLoader.kt
new file mode 100644
index 0000000..15171f0
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinJarPluginLoader.kt
@@ -0,0 +1,31 @@
+package org.gameyfin.app.core.plugins.management
+
+import org.pf4j.DevelopmentPluginLoader
+import org.pf4j.PluginDescriptor
+import org.pf4j.PluginManager
+import org.pf4j.util.FileUtils
+import java.nio.file.Files
+import java.nio.file.Path
+
+/**
+ * JAR plugin loader using a [GameyfinPluginClassLoader]
+ */
+class GameyfinJarPluginLoader(
+ pluginManager: PluginManager
+) : DevelopmentPluginLoader(pluginManager) {
+
+ override fun isApplicable(pluginPath: Path): Boolean {
+ return Files.exists(pluginPath) && FileUtils.isJarFile(pluginPath)
+ }
+
+ override fun loadPlugin(pluginPath: Path, pluginDescriptor: PluginDescriptor?): ClassLoader {
+ if (pluginDescriptor == null) {
+ throw IllegalArgumentException("Plugin descriptor cannot be null")
+ }
+
+ val pluginClassLoader = GameyfinPluginClassLoader(pluginManager, pluginDescriptor, javaClass.getClassLoader())
+ pluginClassLoader.addFile(pluginPath.toFile())
+
+ return pluginClassLoader
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinManifestPluginDescriptorFinder.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinManifestPluginDescriptorFinder.kt
new file mode 100644
index 0000000..eadcf0b
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinManifestPluginDescriptorFinder.kt
@@ -0,0 +1,32 @@
+package org.gameyfin.app.core.plugins.management
+
+import org.pf4j.ManifestPluginDescriptorFinder
+import java.util.jar.Manifest
+
+class GameyfinManifestPluginDescriptorFinder() : ManifestPluginDescriptorFinder() {
+
+ companion object {
+ const val PLUGIN_NAME: String = "Plugin-Name"
+ const val PLUGIN_AUTHOR: String = "Plugin-Author"
+ const val PLUGIN_SHORT_DESCRIPTION: String = "Plugin-Short-Description"
+ const val PLUGIN_URL: String = "Plugin-Url"
+ }
+
+ override fun createPluginDescriptor(manifest: Manifest?): GameyfinPluginDescriptor {
+ if (manifest == null) throw IllegalArgumentException("Manifest cannot be null")
+
+ val pluginDescriptor = super.createPluginDescriptor(manifest)
+
+ val attributes = manifest.mainAttributes
+
+ return GameyfinPluginDescriptor(
+ descriptor = pluginDescriptor,
+ name = attributes.getValue(PLUGIN_NAME)
+ ?: throw IllegalStateException("Plugin-Name not found in manifest"),
+ shortDescription = attributes.getValue(PLUGIN_SHORT_DESCRIPTION),
+ author = attributes.getValue(PLUGIN_AUTHOR)
+ ?: throw IllegalStateException("Plugin-Author not found in manifest"),
+ url = attributes.getValue(PLUGIN_URL),
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinPluginClassLoader.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinPluginClassLoader.kt
new file mode 100644
index 0000000..bf7a7f7
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinPluginClassLoader.kt
@@ -0,0 +1,24 @@
+package org.gameyfin.app.core.plugins.management
+
+import org.pf4j.PluginClassLoader
+import org.pf4j.PluginDescriptor
+import org.pf4j.PluginManager
+
+/**
+ * Adds custom functionality to the [PluginClassLoader] for Gameyfin (mostly related to JAR signature validation).
+ */
+class GameyfinPluginClassLoader(
+ pluginManager: PluginManager,
+ pluginDescriptor: PluginDescriptor,
+ parentClassLoader: ClassLoader,
+) : PluginClassLoader(pluginManager, pluginDescriptor, parentClassLoader) {
+
+ override fun loadClass(className: String?): Class<*>? {
+ try {
+ return super.loadClass(className)
+ } catch (_: SecurityException) {
+ }
+
+ return null
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinPluginDescriptor.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinPluginDescriptor.kt
new file mode 100644
index 0000000..c9f952e
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinPluginDescriptor.kt
@@ -0,0 +1,46 @@
+package org.gameyfin.app.core.plugins.management
+
+import org.pf4j.DefaultPluginDescriptor
+import org.pf4j.PluginDescriptor
+
+data class GameyfinPluginDescriptor(
+ var pluginUrl: String?,
+ var pluginName: String,
+ var pluginShortDescription: String?,
+ var author: String
+) : DefaultPluginDescriptor() {
+
+ companion object {
+ const val NEWLINE_INDICATOR = " "
+ }
+
+ constructor(
+ descriptor: PluginDescriptor,
+ url: String?,
+ name: String,
+ shortDescription: String?,
+ author: String
+ ) : this(
+ pluginUrl = url,
+ pluginName = name,
+ pluginShortDescription = shortDescription,
+ author = author
+ ) {
+ this.pluginId = descriptor.pluginId
+ // The Manifest spec does not account for line breaks in values
+ this.pluginDescription = descriptor.pluginDescription.replace(NEWLINE_INDICATOR, "\n")
+ this.pluginClass = descriptor.pluginClass
+ this.setPluginVersion(descriptor.version)
+ this.requires = descriptor.requires
+ this.license = descriptor.license
+
+ // Use reflection to access the private 'dependencies' field
+ // This is because the internal (List) and external (List) representation of the field differ
+ this.javaClass.superclass.getDeclaredField("dependencies").let {
+ it.isAccessible = true
+ it.set(this, descriptor.dependencies)
+ }
+ }
+
+ override fun getProvider() = author
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinPluginManager.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinPluginManager.kt
new file mode 100644
index 0000000..8946ae4
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/GameyfinPluginManager.kt
@@ -0,0 +1,287 @@
+package org.gameyfin.app.core.plugins.management
+
+import io.github.oshai.kotlinlogging.KotlinLogging
+import org.gameyfin.app.core.plugins.config.PluginConfigRepository
+import org.gameyfin.pluginapi.core.config.Configurable
+import org.gameyfin.pluginapi.core.config.PluginConfigValidationResult
+import org.gameyfin.pluginapi.core.config.PluginConfigValidationResultType
+import org.pf4j.*
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Component
+import java.io.InputStream
+import java.nio.file.Path
+import java.security.PublicKey
+import java.security.cert.CertificateFactory
+import java.security.cert.X509Certificate
+import java.util.jar.JarFile
+import kotlin.io.path.Path
+import kotlin.io.path.extension
+
+
+/**
+ * @see https://stackoverflow.com/questions/73654174/my-application-cant-find-the-extension-with-pf4j
+ */
+@Component
+class GameyfinPluginManager(
+ val pluginConfigRepository: PluginConfigRepository,
+ val dbPluginStatusProvider: DatabasePluginStatusProvider,
+ val pluginManagementRepository: PluginManagementRepository
+) : DefaultPluginManager(Path(System.getProperty("pf4j.pluginsDir", "plugins"))) {
+
+ companion object {
+ private const val PUBLIC_KEY_FILE = "certificates/gameyfin-plugins.pem"
+ }
+
+ private val log = KotlinLogging.logger {}
+ private val publicKey: PublicKey = loadPluginSignaturePublicKey()
+
+ init {
+ // This took me way too long to figure out...
+ // But I learned a lot about Kotlin and Java interoperability in the process
+ pluginStatusProvider = dbPluginStatusProvider
+
+ pluginStateListeners.add { event ->
+ if (event is PluginStateEvent) {
+ log.info { "Plugin ${event.plugin.pluginId} changed state to ${event.pluginState}" }
+ if (event.oldState == PluginState.DISABLED) {
+ startPlugin(event.plugin.pluginId)
+ } else if (event.pluginState == PluginState.DISABLED) {
+ stopPlugin(event.plugin.pluginId)
+ }
+ }
+ }
+ }
+
+ override fun createPluginLoader(): PluginLoader {
+ return when (this.isDevelopment) {
+ true -> GameyfinDevelopmentPluginLoader(this, javaClass.classLoader)
+ false -> GameyfinJarPluginLoader(this)
+ }
+ }
+
+ override fun createPluginStatusProvider(): PluginStatusProvider {
+ return dbPluginStatusProvider
+ }
+
+ override fun createPluginDescriptorFinder(): PluginDescriptorFinder {
+ return GameyfinManifestPluginDescriptorFinder()
+ }
+
+ override fun createExtensionFinder(): ExtensionFinder? {
+ val extensionFinder = GameyfinExtensionFinder(this)
+ addPluginStateListener(extensionFinder)
+ return extensionFinder
+ }
+
+ override fun loadPluginFromPath(pluginPath: Path?): PluginWrapper? {
+ val pluginWrapper = try {
+ super.loadPluginFromPath(pluginPath)
+ } catch (e: Exception) {
+ log.error { "Failed to load plugin $pluginPath: ${e.message}" }
+ null
+ }
+
+ if (pluginWrapper == null || pluginPath == null) return null
+
+ var pluginManagementEntry = pluginManagementRepository.findByIdOrNull(pluginWrapper.pluginId)
+
+ if (pluginManagementEntry == null) {
+ // Create a new entry
+
+ // Set priority to the max value of the current plugins + 1 (which is the lowest priority) or 1 if there are no entries
+ val currentMaxPriority = pluginManagementRepository.findMaxPriority() ?: 0
+
+ pluginManagementEntry =
+ PluginManagementEntry(pluginId = pluginWrapper.pluginId, priority = currentMaxPriority + 1)
+
+ pluginManagementEntry.trustLevel = when (pluginPath.extension) {
+ "jar" -> verifyPluginSignature(pluginPath)
+ else -> PluginTrustLevel.BUNDLED
+ }
+
+ // If the plugin is official or bundled, we can enable it and start it by default
+ if (pluginManagementEntry.trustLevel == PluginTrustLevel.OFFICIAL
+ || pluginManagementEntry.trustLevel == PluginTrustLevel.BUNDLED
+ ) {
+ pluginManagementEntry.enabled = true
+ log.info { "Plugin ${pluginWrapper.pluginId} verified, starting" }
+ startPlugin(pluginWrapper.pluginId)
+ }
+ } else {
+ // Just re-verify the plugin if it was already in the database
+ pluginManagementEntry.trustLevel = when (pluginPath.extension) {
+ "jar" -> verifyPluginSignature(pluginPath)
+ else -> PluginTrustLevel.BUNDLED
+ }
+ }
+
+ // If the plugin is untrusted, we disable it regardless of the previous state
+ if (pluginManagementEntry.trustLevel == PluginTrustLevel.UNTRUSTED) {
+ log.warn { "Plugin ${pluginWrapper.pluginId} is untrusted, disabling" }
+ pluginManagementEntry.enabled = false
+ }
+
+ // Inject config after loading and verification, before starting
+ // Note: If the plugin is untrusted, we don't want to inject the config
+ if (pluginManagementEntry.trustLevel != PluginTrustLevel.UNTRUSTED) configurePlugin(pluginWrapper)
+
+ log.debug { "Plugin ${pluginWrapper.pluginId} verification status: ${pluginManagementEntry.trustLevel}" }
+ pluginManagementRepository.save(pluginManagementEntry)
+
+ return pluginWrapper
+ }
+
+ override fun startPlugin(pluginId: String?): PluginState? {
+ if (pluginId == null) return PluginState.FAILED
+
+ val trustLevel = pluginManagementRepository.findByIdOrNull(pluginId)?.trustLevel ?: PluginTrustLevel.UNKNOWN
+ if (trustLevel == PluginTrustLevel.UNTRUSTED) {
+ val pluginWrapper = getPlugin(pluginId)
+ val pluginState = PluginState.UNLOADED
+
+ this.firePluginStateEvent(PluginStateEvent(this, pluginWrapper, pluginState))
+ return pluginState
+ }
+
+ // Validate config before starting the plugin
+ if (validatePluginConfig(pluginId).result == PluginConfigValidationResultType.INVALID) {
+ log.warn { "Plugin $pluginId has invalid configuration" }
+
+ val pluginWrapper = getPlugin(pluginId)
+ pluginWrapper.pluginState = PluginState.FAILED
+ this.firePluginStateEvent(PluginStateEvent(this, pluginWrapper, pluginWrapper.pluginState))
+ return pluginWrapper.pluginState
+ }
+
+ return super.startPlugin(pluginId)
+ }
+
+ override fun startPlugins() {
+ val pluginsToStart = resolvedPlugins.filter { !it.pluginState.isDisabled && !it.pluginState.isStarted }
+ pluginsToStart.forEach { startPlugin(it.pluginId) }
+ }
+
+ fun restart(pluginId: String) {
+ val plugin = getPlugin(pluginId)?.plugin ?: return
+ stopPlugin(pluginId)
+ if (plugin is Configurable) plugin.loadConfig(getConfig(pluginId))
+ startPlugin(pluginId)
+ }
+
+ fun validatePluginConfig(pluginId: String): PluginConfigValidationResult {
+ val plugin = try {
+ getPlugin(pluginId)?.plugin
+ } catch (_: NoClassDefFoundError) {
+ return PluginConfigValidationResult(PluginConfigValidationResultType.UNKNWOWN)
+ }
+
+ if (plugin !is Configurable) {
+ return PluginConfigValidationResult(PluginConfigValidationResultType.VALID)
+ }
+
+ return plugin.validateConfig()
+ }
+
+ fun validatePluginConfig(pluginId: String, configToValidate: Map): PluginConfigValidationResult {
+ val plugin = try {
+ getPlugin(pluginId)?.plugin
+ } catch (_: NoClassDefFoundError) {
+ return PluginConfigValidationResult(PluginConfigValidationResultType.UNKNWOWN)
+ }
+
+ if (plugin !is Configurable) {
+ return PluginConfigValidationResult(PluginConfigValidationResultType.VALID)
+ }
+
+ return plugin.validateConfig(configToValidate)
+ }
+
+ fun getExtensionTypeClasses(pluginId: String): List> {
+ return getExtensionClasses(pluginId)
+ .flatMap { it.interfaces.toList() }
+ .filterIsInstance>()
+ }
+
+ fun getExtensionTypes(pluginId: String): List {
+ return getExtensionClasses(pluginId)
+ .flatMap { it.interfaces.toList() }
+ .filterIsInstance>()
+ .map { it.simpleName }
+ }
+
+ fun getPluginForExtension(extensionClass: Class): PluginWrapper? {
+ return getPlugins().firstOrNull { pluginWrapper ->
+ getExtensionTypeClasses(pluginWrapper.pluginId).any { it == extensionClass.javaClass }
+ }
+ }
+
+ fun getManagementEntry(pluginId: String): PluginManagementEntry {
+ return pluginManagementRepository.findByIdOrNull(pluginId)
+ ?: throw IllegalArgumentException("Plugin with ID $pluginId not found")
+ }
+
+ private fun configurePlugin(pluginWrapper: PluginWrapper) {
+ val plugin = pluginWrapper.plugin
+ if (plugin is Configurable) {
+ val config = getConfig(pluginWrapper.pluginId)
+ plugin.loadConfig(config)
+ }
+ }
+
+ private fun getConfig(pluginId: String): Map {
+ return pluginConfigRepository.findAllById_PluginId(pluginId).associate { it.id.key to it.value }
+ }
+
+ private fun loadPluginSignaturePublicKey(): PublicKey {
+ val certFactory: CertificateFactory = CertificateFactory.getInstance("X.509")
+ val certFileInputStream = javaClass.classLoader.getResourceAsStream(PUBLIC_KEY_FILE)
+ val cert: X509Certificate = certFactory.generateCertificate(certFileInputStream) as X509Certificate
+ certFileInputStream?.close()
+ return cert.publicKey
+ }
+
+ private fun verifyPluginSignature(pluginPath: Path): PluginTrustLevel {
+ val jarFile = JarFile(pluginPath.toFile(), true)
+ val entries = jarFile.entries()
+
+ while (entries.hasMoreElements()) {
+ val entry = entries.nextElement()
+ if (entry.isDirectory || entry.name.startsWith("META-INF/")) continue
+
+ try {
+ val buffer = ByteArray(8192)
+ val entryInputStream: InputStream = jarFile.getInputStream(entry)
+ while ((entryInputStream.read(buffer, 0, buffer.size)) != -1) {
+ // We just read
+ // This will throw a SecurityException if a signature/digest check fails
+ }
+ } catch (_: SecurityException) {
+ // Signature verification failed
+ return PluginTrustLevel.UNTRUSTED
+ }
+
+ val codeSigners = entry.codeSigners
+
+ if (codeSigners == null || codeSigners.isEmpty()) {
+ // No code signers, so we can't verify the signature
+ return PluginTrustLevel.THIRD_PARTY
+ }
+
+ for (codeSigner in codeSigners) {
+ val certs = codeSigner.signerCertPath.certificates
+
+ for (cert in certs) {
+ if (cert is X509Certificate) {
+ try {
+ cert.verify(publicKey)
+ } catch (_: Exception) {
+ // Signature verification failed
+ return PluginTrustLevel.UNTRUSTED
+ }
+ }
+ }
+ }
+ }
+ return PluginTrustLevel.OFFICIAL
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginManagementEntry.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginManagementEntry.kt
new file mode 100644
index 0000000..b2cf1b6
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginManagementEntry.kt
@@ -0,0 +1,16 @@
+package org.gameyfin.app.core.plugins.management
+
+import jakarta.persistence.Entity
+import jakarta.persistence.Id
+
+@Entity
+data class PluginManagementEntry(
+ @Id
+ val pluginId: String,
+
+ var enabled: Boolean = false,
+
+ var priority: Int = 0,
+
+ var trustLevel: PluginTrustLevel = PluginTrustLevel.UNKNOWN,
+)
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginManagementRepository.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginManagementRepository.kt
new file mode 100644
index 0000000..6c3f570
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginManagementRepository.kt
@@ -0,0 +1,9 @@
+package org.gameyfin.app.core.plugins.management
+
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.data.jpa.repository.Query
+
+interface PluginManagementRepository : JpaRepository {
+ @Query("SELECT MAX(p.priority) FROM PluginManagementEntry p")
+ fun findMaxPriority(): Int?
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginManagerConfig.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginManagerConfig.kt
new file mode 100644
index 0000000..b167663
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginManagerConfig.kt
@@ -0,0 +1,20 @@
+package org.gameyfin.app.core.plugins.management
+
+import io.github.oshai.kotlinlogging.KotlinLogging
+import org.springframework.boot.context.event.ApplicationReadyEvent
+import org.springframework.context.annotation.Configuration
+import org.springframework.context.event.EventListener
+
+@Configuration
+class PluginManagerConfig(
+ private val pluginManager: GameyfinPluginManager
+) {
+ private val log = KotlinLogging.logger {}
+
+ @EventListener(ApplicationReadyEvent::class)
+ fun loadPlugins() {
+ pluginManager.loadPlugins()
+ pluginManager.startPlugins()
+ log.info { "Loaded plugins: ${pluginManager.plugins.map { it.pluginId }}" }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginTrustLevel.kt b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginTrustLevel.kt
new file mode 100644
index 0000000..dcfe4a8
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/plugins/management/PluginTrustLevel.kt
@@ -0,0 +1,9 @@
+package org.gameyfin.app.core.plugins.management
+
+enum class PluginTrustLevel {
+ BUNDLED,
+ OFFICIAL,
+ THIRD_PARTY,
+ UNTRUSTED,
+ UNKNOWN,
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/security/AppKeyValidator.kt b/app/src/main/kotlin/org/gameyfin/app/core/security/AppKeyValidator.kt
new file mode 100644
index 0000000..c082c92
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/security/AppKeyValidator.kt
@@ -0,0 +1,31 @@
+package org.gameyfin.app.core.security
+
+import io.github.oshai.kotlinlogging.KotlinLogging
+import org.springframework.boot.CommandLineRunner
+import org.springframework.stereotype.Component
+import java.util.*
+import kotlin.system.exitProcess
+
+@Component
+class AppKeyValidator : CommandLineRunner {
+ companion object {
+ val log = KotlinLogging.logger {}
+ }
+
+ override fun run(vararg args: String?) {
+ val base64Key = System.getenv("APP_KEY")
+
+ if (base64Key.isNullOrBlank()) {
+ log.error { "APP_KEY environment variable is not set or empty" }
+ exitProcess(1)
+ }
+
+ val decodedKey = Base64.getDecoder().decode(base64Key)
+
+ // Ensure the key length is valid for AES (128, 192, or 256 bits)
+ if (decodedKey.size !in listOf(16, 24, 32)) {
+ log.error { "Invalid AES key length in APP_KEY. Key must be 128, 192, or 256 bits." }
+ exitProcess(1)
+ }
+ }
+}
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/security/AuthenticationProviderConfig.kt b/app/src/main/kotlin/org/gameyfin/app/core/security/AuthenticationProviderConfig.kt
new file mode 100644
index 0000000..83095e4
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/security/AuthenticationProviderConfig.kt
@@ -0,0 +1,25 @@
+package org.gameyfin.app.core.security
+
+import org.gameyfin.app.users.UserService
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.security.access.hierarchicalroles.RoleHierarchy
+import org.springframework.security.access.hierarchicalroles.RoleHierarchyAuthoritiesMapper
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider
+import org.springframework.security.crypto.password.PasswordEncoder
+
+@Configuration
+class AuthenticationProviderConfig {
+ @Bean
+ fun hierarchicalUserAuthenticationProvider(
+ userService: UserService,
+ roleHierarchy: RoleHierarchy,
+ passwordEncoder: PasswordEncoder
+ ): DaoAuthenticationProvider {
+ val provider = DaoAuthenticationProvider()
+ provider.setUserDetailsService(userService)
+ provider.setPasswordEncoder(passwordEncoder)
+ provider.setAuthoritiesMapper(RoleHierarchyAuthoritiesMapper(roleHierarchy))
+ return provider
+ }
+}
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/security/AuthorityMapperConfig.kt b/app/src/main/kotlin/org/gameyfin/app/core/security/AuthorityMapperConfig.kt
new file mode 100644
index 0000000..a83f629
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/security/AuthorityMapperConfig.kt
@@ -0,0 +1,16 @@
+package org.gameyfin.app.core.security
+
+import org.gameyfin.app.users.RoleService
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper
+
+@Configuration
+class AuthorityMapperConfig(
+ private val roleService: RoleService
+) {
+ @Bean
+ fun userAuthoritiesMapper(): GrantedAuthoritiesMapper {
+ return GrantedAuthoritiesMapper { authorities -> roleService.extractGrantedAuthorities(authorities) }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/org/gameyfin/app/core/security/EncryptionConverter.kt b/app/src/main/kotlin/org/gameyfin/app/core/security/EncryptionConverter.kt
new file mode 100644
index 0000000..408260a
--- /dev/null
+++ b/app/src/main/kotlin/org/gameyfin/app/core/security/EncryptionConverter.kt
@@ -0,0 +1,15 @@
+package org.gameyfin.app.core.security
+
+import jakarta.persistence.AttributeConverter
+import jakarta.persistence.Converter
+
+@Converter
+class EncryptionConverter : AttributeConverter