From 6140bc0ca1faf2aad457b01a592006d944ed1f63 Mon Sep 17 00:00:00 2001 From: Marty Pitt Date: Mon, 15 Jun 2026 07:21:20 +0100 Subject: [PATCH 1/5] updated exit --- NEBULA-AGENT.md | 521 ++++++++++++++++++ .../com/orbitalhq/nebula/cli/NebulaCli.kt | 3 +- 2 files changed, 523 insertions(+), 1 deletion(-) create mode 100644 NEBULA-AGENT.md diff --git a/NEBULA-AGENT.md b/NEBULA-AGENT.md new file mode 100644 index 0000000..15d815d --- /dev/null +++ b/NEBULA-AGENT.md @@ -0,0 +1,521 @@ +# NEBULA-AGENT.md + +Instructions for AI agents that write **Nebula stacks** — Kotlin-scripted test/demo ecosystems used by Orbital. + +Read this document top-to-bottom before writing your first stack. It is self-contained: every DSL function, import, and convention you need is here. + +--- + +## 1. What a Nebula stack is + +A Nebula stack is a single Kotlin script that stands up a set of Dockerised infrastructure components (Kafka, Postgres, HTTP servers, S3 on LocalStack, MongoDB, Hazelcast, etc.) with seeded data and live behaviours (producers, endpoints). Orbital uses stacks to drive integration demos and local dev against realistic pipelines. + +**File extension, naming, location:** + +- File extension MUST be `.nebula.kts`. The script is compiled as a `NebulaScript` — the extension is how the Kotlin scripting host recognises it. +- **Convention: the file is named `stack.nebula.kts`.** A stack file that is not called `stack` is unusual — only deviate if the user explicitly asks. +- Each file produces exactly **one** top-level `stack { ... }` block. Do not write multiple `stack { }` blocks in one file. + +--- + +## 2. Placement inside an Orbital taxi project + +Nebula is always consumed by Orbital inside a taxi project. The stack file MUST be discoverable by `taxi.conf`. + +**Required wiring in `taxi.conf`:** + +```hocon +name: com.acme/csv-to-api +version: 0.1.0 +sourceRoot: src/ +additionalSources: { + "@orbital/config" : "orbital/config/*.conf", + "@orbital/nebula" : "orbital/nebula/*.nebula.kts" +} +dependencies: { + "com.orbitalhq/core" : "github:orbitalapi/orbital-core-taxi#0.34.0" +} +``` + +**Rules:** +- The `@orbital/nebula` key under `additionalSources` is **mandatory**. Without it Orbital will not discover the stack. +- By convention the file lives at `orbital/nebula/stack.nebula.kts` (preferred) or `nebula/stack.nebula.kts`. +- Declare the glob with a wildcard (`*.nebula.kts`), not a single explicit file — future stacks in the same folder will be picked up automatically. +- If `taxi.conf` already exists and lacks the `@orbital/nebula` entry, add it. Do not remove unrelated `additionalSources` keys. + +**Minimal project layout:** + +``` +my-project/ +├── taxi.conf +├── src/ +│ └── ... (taxi files) +└── orbital/ + └── nebula/ + └── stack.nebula.kts +``` + +--- + +## 3. Script structure + +The entire script is a Kotlin file. You may freely: +- import additional classes, +- declare `data class`, `enum class`, top-level `val`, top-level `fun`, +- use any JVM library that is on Nebula's classpath (Jackson, Ktor server types, JOOQ, Avro, Wire/Protobuf, kotlinx-coroutines, Reactor — all available without extra setup). + +Everything runtime-related goes **inside** the `stack { ... }` block at the bottom. + +```kotlin +// 1. Imports (if not covered by defaults — see §4) +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.orbitalhq.nebula.utils.duration + +// 2. Optional top-level data/types/helpers +data class Customer(val id: String, val name: String) +val customers = listOf(Customer("C-1", "Jane")) + +// 3. Exactly one stack block +stack { + // component declarations go here + http { /* ... */ } + kafka { /* ... */ } + postgres { /* ... */ } +} +``` + +You can also declare `data class`, `val`, and `fun` *inside* the `stack { }` block — both styles appear across real stacks. Put data classes at the top level if they are reused across components; put them inside `stack` if they are a local implementation detail. + +--- + +## 4. Default imports (do NOT re-import) + +The compilation config auto-imports: + +- `com.orbitalhq.nebula.stack` — the top-level `stack { }` function +- `kotlin.random.Random` +- `io.ktor.server.request.*` — gives you `call.receiveText()`, `call.request.*`, etc. +- `io.ktor.server.response.*` — gives you `call.respondText()`, `call.respond()`, etc. + +Do not re-import these. Everything else must be imported explicitly. Common extra imports you WILL need: + +```kotlin +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import com.orbitalhq.nebula.utils.duration // "500ms".duration() -> kotlin.time.Duration +import com.orbitalhq.nebula.kafka.MessageSerializer // .ByteArray / .String +import com.orbitalhq.nebula.io.avro.avroSchema +import com.orbitalhq.nebula.io.protobuf.protobufSchema +import io.ktor.http.* // HttpStatusCode, ContentType +import kotlin.time.Duration.Companion.milliseconds // 100.milliseconds syntax (alternative to "100ms".duration()) +``` + +--- + +## 5. Components — full reference + +All components are added by calling DSL functions inside `stack { }`. Each has an optional `componentName` parameter — set it when you have **more than one of the same type** (e.g. two Postgres databases) so each has a stable identifier. + +### 5.1 `http { ... }` — HTTP server (Ktor) + +```kotlin +http { + get("/flights") { call -> + call.respondText("""{"flights":[]}""") + } + get("/flights/{id}") { call -> + val id = call.parameters["id"]!! + call.respondText("""{"id":"$id"}""") + } + post("/orders") { call -> + val body = call.receiveText() + call.respondText(body, status = HttpStatusCode.Created) + } + put("/orders/{id}") { call -> /* ... */ } + delete("/orders/{id}") { call -> /* ... */ } +} +``` + +Signature: +```kotlin +fun http(port: Int = 0, componentName: String = "http", dsl: HttpApiBuilder.(KLogger) -> Unit) +``` + +Inside the block you have: `get`, `post`, `put`, `delete`. Each takes a path and a suspend lambda with a `PipelineContext` receiver. The single argument is the `ApplicationCall` (named `call` by convention). + +**Handler patterns:** +- `call.parameters["id"]` — path params (e.g. `/users/{id}`). +- `call.request.queryParameters["q"]` — query params. +- `call.request.headers.toMap()` — headers. +- `call.receiveText()` — raw request body as string. +- `call.respondText(body)` — 200 OK text response. +- `call.respondText(body, status = HttpStatusCode.NotFound)` — custom status. +- `call.respondText(body, contentType = ContentType.parse("application/json"))`. +- `call.respond(HttpStatusCode.NoContent)` — empty response. + +**Port:** default `0` (random free port) — Orbital discovers the port from the returned `ComponentInfo`. Only pin a port if the stack instructions explicitly need it. + +**JSON:** use Jackson explicitly — there is NO automatic JSON serialization: +```kotlin +val mapper = jacksonObjectMapper() +call.respondText(mapper.writeValueAsString(myMap), ContentType.parse("application/json")) +``` + +To parse a request body as a typed class: +```kotlin +val request = jacksonObjectMapper().readValue(call.receiveText()) +``` + +### 5.2 `kafka { ... }` — Kafka broker with producers + +```kotlin +kafka { + producer("500ms".duration(), "orders") { + jsonMessage { + mapOf("orderId" to "ORD-1", "amount" to 42) + } + } +} +``` + +Signature: +```kotlin +fun kafka(imageName: String = "confluentinc/cp-kafka:6.2.2", + componentName: ComponentName = "kafka", + dsl: KafkaBuilder.(KLogger) -> Unit) +``` + +**`producer(...)` signature:** +```kotlin +fun producer(frequency: Duration, + topic: String, + partitions: Int = 1, + keySerializer: MessageSerializer = MessageSerializer.String, + valueSerializer: MessageSerializer = MessageSerializer.String, + init: ProducerBuilder.() -> Unit) +``` + +Frequency — prefer `"500ms".duration()` or `1.milliseconds` / `2.seconds` (using `kotlin.time.Duration`). Both appear in real stacks. + +**Message generators** — pick ONE inside the producer block: + +| Function | Output | Use when | +|---|---|---| +| `message { … }` | Raw value from the lambda (`String`, `ByteArray`, etc.) — sent as-is | You are producing plain text/XML/already-encoded bytes | +| `jsonMessage { … }` | `Map`/object → JSON string | Most JSON producers | +| `jsonMessages { … }` | `List` → one Kafka message per list element | You want a batch each tick (see state-sharing pattern below) | +| `avroMessage(schema) { … }` | `Map`/JSON string → Avro binary. Use for standard JSON. | Avro output, standard JSON input | +| `avroJsonMessage(schema) { … }` | Avro-specific JSON string → Avro binary. Avro-JSON uses `{"string":"x"}` union nesting. | Avro output, Avro-JSON input | +| `protoMessage(schema, "TypeName") { … }` | `Map` → protobuf binary | Protobuf output, one message per tick | +| `protoMessages(schema, "TypeName") { … }` | `List` → protobuf binary, one per list element | Protobuf batches | + +**Critical: for Avro and Protobuf you MUST set `valueSerializer = MessageSerializer.ByteArray`:** +```kotlin +producer("500ms".duration(), "orders", valueSerializer = MessageSerializer.ByteArray) { + protoMessage(schema, "com.example.Order") { + mapOf("orderId" to "ORD-1") + } +} +``` + +**Schema helpers:** +```kotlin +val avro = avroSchema(""" { "type":"record", "name":"...", ... } """) + +// Single file: +val proto = protobufSchema(""" syntax = "proto3"; message Foo { string x = 1; } """) + +// Multiple files (for imports across .proto files): +val proto = protobufSchema(mapOf( + "taxi/dataType.proto" to """syntax = "proto3"; ...""", + "orders.proto" to """syntax = "proto3"; import "taxi/dataType.proto"; ...""" +)) +``` + +**State across producers** — both producers run in the same JVM, so share state with thread-safe containers: +```kotlin +kafka { + val counter = java.util.concurrent.atomic.AtomicInteger(0) + val pending = java.util.concurrent.ConcurrentHashMap() + + producer("1s".duration(), "orders") { + jsonMessage { + val id = "ORD-${counter.incrementAndGet()}" + // ... add to pending + } + } + producer("500ms".duration(), "updates") { + jsonMessages { + // drain from pending, emit updates + } + } +} +``` + +### 5.3 `postgres { ... }` and `mysql { ... }` — SQL databases + +```kotlin +postgres(componentName = "products-db") { + table("suppliers", """ + CREATE TABLE suppliers ( + supplier_id VARCHAR PRIMARY KEY, + name VARCHAR NOT NULL, + tier VARCHAR NOT NULL + ) + """.trimIndent(), + data = listOf( + mapOf("supplier_id" to "SUP-1", "name" to "Acme", "tier" to "GOLD"), + mapOf("supplier_id" to "SUP-2", "name" to "Beta", "tier" to "SILVER") + )) +} +``` + +Signatures: +```kotlin +fun postgres(imageName: String = "postgres:13", + databaseName: String = "testDb", + componentName: ComponentName = "postgres", + dsl: DatabaseBuilder.(KLogger) -> Unit) + +fun mysql(imageName: String = "mysql:9", + databaseName: String = "testDb", + componentName: ComponentName = "mysql", + dsl: DatabaseBuilder.(KLogger) -> Unit) +``` + +Inside the block: +```kotlin +fun table(name: String, ddl: String, data: List> = emptyList()) +fun table(name: String, ddl: String, vararg data: Map) +``` + +**Rules:** +- `ddl` is a raw SQL `CREATE TABLE ...` string. Use `.trimIndent()` to keep it readable. +- Column names in the `data` maps must match the DDL columns exactly (case-sensitive on Postgres if you quote them; otherwise lowercase). +- Values can be `String`, `Int`, `Long`, `Boolean`, `BigDecimal`, `java.time.Instant`, `java.time.LocalDate`, `java.util.UUID`, etc. — JOOQ handles the conversion. +- An **empty table** is fine (use `data = emptyList()`) — Orbital may write into it later. +- To get a second database, give it a distinct `componentName` AND (usually) a distinct `databaseName`: + ```kotlin + postgres(componentName = "orders-db", databaseName = "orders") { … } + postgres(componentName = "products-db", databaseName = "products") { … } + ``` + +### 5.4 `mongo(...) { ... }` — MongoDB + +```kotlin +mongo(databaseName = "customers") { + collection("tier", data = listOf( + mapOf("_id" to "gold", "description" to "Gold Tier"), + mapOf("_id" to "silver", "description" to "Silver Tier") + )) + collection("order-updates") // empty collection — Orbital writes to it +} +``` + +Signature: +```kotlin +fun mongo(imageName: String = "mongo:7.0.16", + databaseName: String, // REQUIRED — no default + componentName: ComponentName = "mongo", + dsl: MongoBuilder.(KLogger) -> Unit) + +fun collection(name: String, data: List> = emptyList()) +``` + +`databaseName` is mandatory. Use the Mongo field name `_id` in seed data if you want to pin document IDs. + +### 5.5 `s3 { ... }` — S3 (LocalStack-backed) + +```kotlin +s3 { + bucket("tickets") { + file("sales.csv", """Title,FilmId,Tickets +A New Hope,XHXCO,249 +Empire Strikes Back,LXILO,189 +""") + } + bucket("reports") { + file("/absolute/path/to/local.csv") // read from disk + file("large.csv", generateSequence()) // Sequence for large/streamed files + } +} +``` + +Signature: +```kotlin +fun s3(imageName: String = "localstack/localstack:latest", + componentName: String = "s3", + dsl: S3Builder.(KLogger) -> Unit) +``` + +Inside a `bucket(name)` block: +```kotlin +fun file(name: String, content: String) // inline content +fun file(name: String, content: Sequence) // streaming — for large files +fun file(path: String) // read file from local disk; uses the filename as the S3 key +``` + +Use the `Sequence` form for files larger than a few MB (the seeder uses S3 multipart upload — minimum part size is 5 MB, which is already handled by default). + +### 5.6 `hazelcast { ... }` — Hazelcast + +Almost always empty-configured. Orbital connects and uses it as a cache. + +```kotlin +hazelcast { } +``` + +Signature: +```kotlin +fun hazelcast(imageName: String = "hazelcast/hazelcast:5", + componentName: ComponentName = "hazelcast", + dsl: HazelcastBuilder.(KLogger) -> Unit) +``` + +### 5.7 `taxiPublisher(...) { ... }` — publish taxi/proto/avro schemas to a running Orbital + +Registers schema sources against a running Orbital instance on startup. Use this when the stack needs to push protobuf/avro/taxi sources into Orbital alongside the runtime infra (e.g. so Orbital can decode messages). + +```kotlin +taxiPublisher(url = "http://localhost:9022", packageUri = "com.foo/publishing-test/1.0.0") { + taxi("foo.taxi") { + """ + type CustomerId inherits String + """.trimIndent() + } + additionalSource("@orbital/protobuf", "orders.proto" to protoSourceString) + // or with a builder lambda: + additionalSource("@orbital/config", "connections.conf") { + """ connection settings here """.trimIndent() + } +} +``` + +Use this sparingly — most stacks do NOT need it. Only include when the user asks for programmatic schema publishing. + +--- + +## 6. Writing style — patterns that work + +### 6.1 Define seed data at the top, reference it everywhere + +Putting test data at the top (or as top-level `val`s) lets multiple components share it: + +```kotlin +data class Supplier(val id: String, val name: String, val tier: String) +val suppliers = listOf( + Supplier("SUP-1", "Acme", "GOLD"), + Supplier("SUP-2", "Beta", "SILVER") +) + +stack { + postgres { + table("suppliers", "CREATE TABLE suppliers(id VARCHAR, name VARCHAR, tier VARCHAR)", + data = suppliers.map { mapOf("id" to it.id, "name" to it.name, "tier" to it.tier) }) + } + http { + val mapper = jacksonObjectMapper() + get("/suppliers/{id}") { call -> + val s = suppliers.first { it.id == call.parameters["id"] } + call.respondText(mapper.writeValueAsString(s)) + } + } +} +``` + +### 6.2 One `http { }` block with multiple routes — not one per route + +Group all HTTP endpoints into a single `http { }` block. Multiple `http { }` blocks would stand up multiple servers. + +### 6.3 Use `jacksonObjectMapper()` for JSON everywhere + +Create a mapper once per `http { }` (or reuse a script-level one). There is no automatic JSON content negotiation. + +### 6.4 Use `componentName` when you have duplicates + +If you have two Postgres databases, two S3 instances, etc., each MUST have a distinct `componentName`. Without it, the default name collides and the second component shadows the first. + +### 6.5 Jackson + `java.time.Instant` gotcha + +Jackson inside the Nebula runtime occasionally fails to serialise `Instant` cleanly. Convert to string at the boundary: +```kotlin +"orderTime" to Instant.now().toString() +``` + +### 6.6 Logging + +`kafka { logger -> … }`, `http { logger -> … }`, etc. all receive a `KLogger` as the block receiver argument. You can use it, or just use `println` (both end up in the Nebula log stream). + +### 6.7 Don't invoke `.start()` or wire `StackRunner` yourself + +A Nebula script's only job is to declare the `stack { }`. The Nebula runtime (inside the CLI or Orbital) runs and manages it. Never call `.start()`, `StackRunner(...)`, `shutDownAll()`, etc. inside a stack script — those are for the host. + +--- + +## 7. A complete minimal stack (reference) + +```kotlin +// orbital/nebula/stack.nebula.kts +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.orbitalhq.nebula.utils.duration +import io.ktor.http.* + +data class Film(val id: Int, val title: String) +val films = listOf(Film(1, "A New Hope"), Film(2, "Empire Strikes Back")) + +stack { + val mapper = jacksonObjectMapper() + + postgres(databaseName = "films") { + table("film", """ + CREATE TABLE film ( + id INT PRIMARY KEY, + title VARCHAR NOT NULL + ) + """.trimIndent(), + data = films.map { mapOf("id" to it.id, "title" to it.title) } + ) + } + + http { + get("/films") { call -> + call.respondText(mapper.writeValueAsString(films), + ContentType.parse("application/json")) + } + get("/films/{id}") { call -> + val id = call.parameters["id"]!!.toInt() + val film = films.firstOrNull { it.id == id } + if (film == null) { + call.respondText("""{"error":"not found"}""", status = HttpStatusCode.NotFound) + } else { + call.respondText(mapper.writeValueAsString(film), + ContentType.parse("application/json")) + } + } + } + + kafka { + producer("1s".duration(), "film-announcements") { + jsonMessage { + val f = films.random() + mapOf("filmId" to f.id, "title" to f.title, "event" to "rerelease") + } + } + } +} +``` + +--- + +## 8. Quick checklist before returning a stack + +- [ ] File is named `stack.nebula.kts` (unless user specified otherwise) and placed at `orbital/nebula/stack.nebula.kts`. +- [ ] `taxi.conf` contains `"@orbital/nebula" : "orbital/nebula/*.nebula.kts"` under `additionalSources`. +- [ ] Exactly one top-level `stack { }` block. +- [ ] No re-imports of `stack`, `Random`, `io.ktor.server.request.*`, `io.ktor.server.response.*`. +- [ ] Duplicate component types (two Postgres, two S3, etc.) each have distinct `componentName`s. +- [ ] Avro/Protobuf producers set `valueSerializer = MessageSerializer.ByteArray`. +- [ ] Mongo call passes `databaseName = "..."` — it has no default. +- [ ] No `.start()`, `StackRunner`, or lifecycle calls in the script. +- [ ] JSON responses use `jacksonObjectMapper().writeValueAsString(...)` — no Ktor auto-content-negotiation is configured. +- [ ] DDL strings use `.trimIndent()` and column names match the seed data map keys. diff --git a/nebula-cli/src/main/kotlin/com/orbitalhq/nebula/cli/NebulaCli.kt b/nebula-cli/src/main/kotlin/com/orbitalhq/nebula/cli/NebulaCli.kt index 10c6650..ff5f7b3 100644 --- a/nebula-cli/src/main/kotlin/com/orbitalhq/nebula/cli/NebulaCli.kt +++ b/nebula-cli/src/main/kotlin/com/orbitalhq/nebula/cli/NebulaCli.kt @@ -22,6 +22,7 @@ import java.io.File import java.lang.Thread.sleep import java.util.concurrent.Callable import kotlin.script.experimental.api.isError +import kotlin.system.exitProcess @Command( name = "nebula", @@ -203,7 +204,7 @@ class Nebula : Callable { } } -fun main(args: Array): Unit = System.exit(CommandLine(Nebula()).execute(*args)) +fun main(args: Array): Unit = exitProcess(CommandLine(Nebula()).execute(*args)) class ExistingDockerNetwork(private val id: String) : Network { override fun close() { From 21f880280c81da65f4a20292497fc7be9b3d3170 Mon Sep 17 00:00:00 2001 From: Marty Pitt Date: Mon, 22 Jun 2026 11:21:03 +0100 Subject: [PATCH 2/5] add build of front-end to maven build --- nebula-runtime/pom.xml | 80 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/nebula-runtime/pom.xml b/nebula-runtime/pom.xml index 88c32c0..ed643ce 100644 --- a/nebula-runtime/pom.xml +++ b/nebula-runtime/pom.xml @@ -110,4 +110,84 @@ + + + + false + v22.12.0 + ${project.basedir}/../nebula-ui + + + + + + + com.github.eirslett + frontend-maven-plugin + 1.15.1 + + ${nebula.ui.dir} + ${project.build.directory} + ${frontend.skip} + + + + install-node-and-npm + + install-node-and-npm + + generate-resources + + ${frontend.node.version} + + + + npm-install + + npm + + generate-resources + + install + + + + npm-build + + npm + + generate-resources + + run build + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-ui + + copy-resources + + generate-resources + + ${frontend.skip} + ${project.build.outputDirectory}/web + + + ${nebula.ui.dir}/dist + + + + + + + + \ No newline at end of file From 62a5fc1d16ca6ab63da91d32cebc292edfc19fdc Mon Sep 17 00:00:00 2001 From: Marty Pitt Date: Mon, 22 Jun 2026 11:21:16 +0100 Subject: [PATCH 3/5] add endpoint for failed stacks --- .../com/orbitalhq/nebula/StackRunner.kt | 83 +++++++++ .../nebula/runtime/server/NebulaServer.kt | 176 ++++++++++++++++++ 2 files changed, 259 insertions(+) diff --git a/nebula-dsl/src/main/kotlin/com/orbitalhq/nebula/StackRunner.kt b/nebula-dsl/src/main/kotlin/com/orbitalhq/nebula/StackRunner.kt index 6846aec..fc26238 100644 --- a/nebula-dsl/src/main/kotlin/com/orbitalhq/nebula/StackRunner.kt +++ b/nebula-dsl/src/main/kotlin/com/orbitalhq/nebula/StackRunner.kt @@ -1,7 +1,9 @@ package com.orbitalhq.nebula import com.orbitalhq.nebula.core.ComponentInfo +import com.orbitalhq.nebula.core.ComponentState import com.orbitalhq.nebula.core.StackStateEvent +import com.orbitalhq.nebula.events.computeStackStateEventFor import com.orbitalhq.nebula.logging.LogMessage import io.github.oshai.kotlinlogging.KotlinLogging import org.testcontainers.containers.Network @@ -76,6 +78,12 @@ class StackRunner(private val config: NebulaConfig = NebulaConfig()) { return stateState[name] } + /** The source script a stack was submitted with, or null if no such stack exists. */ + fun sourceFor(name: StackName): String? = this.stacks[name]?.source + + /** Whether a stack with this name has been submitted (regardless of running state). */ + fun isSubmitted(name: StackName): Boolean = this.stacks.containsKey(name) + fun stackEvents(name:String):Flux { val stack = this.stacks[name] ?: error("Stack $name not found") @@ -86,6 +94,51 @@ class StackRunner(private val config: NebulaConfig = NebulaConfig()) { return stack.stack.logMessages } + /** + * Returns a point-in-time snapshot of every known stack and the current + * lifecycle state of its components. + * + * Unlike [stateState], this includes each component's current lifecycle state, + * making it suitable for driving an admin UI that polls for status. + */ + fun snapshot(): List = this.stacks.keys.mapNotNull { snapshot(it) } + + /** + * Returns a point-in-time snapshot of a single stack, or null if no stack + * with the given name exists. + */ + fun snapshot(name: StackName): StackStateEvent? { + val stack = this.stacks[name] ?: return null + val components = stack.stack.components + val stateMap = components.associateWith { it.currentState.state } + return computeStackStateEventFor(name, stateMap, components) + } + + private fun findComponent(stackName: StackName, componentId: String): InfrastructureComponent<*> { + val stack = this.stacks[stackName] ?: error("Stack $stackName not found") + return stack.stack.components.find { it.id == componentId } + ?: error("Component $componentId not found in stack $stackName") + } + + /** + * Stops a single component within a stack, leaving the rest of the stack running. + */ + fun stopComponent(stackName: StackName, componentId: String) { + val component = findComponent(stackName, componentId) + logger.info { "Stopping component $componentId in stack $stackName" } + component.stop() + } + + /** + * (Re)starts a single component within a stack that was previously stopped. + */ + fun startComponent(stackName: StackName, componentId: String) { + val stackWithSource = this.stacks[stackName] ?: error("Stack $stackName not found") + val component = findComponent(stackName, componentId) + logger.info { "Starting component $componentId in stack $stackName" } + component.start(config, stackWithSource.hostConfig) + } + private fun start(name: String) { val stackWithSource = this.stacks[name] ?: error("Stack $name not found") @@ -106,6 +159,36 @@ class StackRunner(private val config: NebulaConfig = NebulaConfig()) { } } + /** + * (Re)starts every not-yet-running component in a previously-submitted stack. + * Use this to bring a stopped stack back up without resubmitting its script. + */ + fun startStack(name: StackName) { + val stackWithSource = this.stacks[name] ?: error("Stack $name not found") + logger.info { "Starting stack $name" } + stackWithSource.stack.components.forEach { component -> + if (component.currentState.state != ComponentState.Running) { + try { + component.start(config, stackWithSource.hostConfig) + } catch (e: Exception) { + logger.error(e) { "Error starting component ${component.name} in stack $name" } + } + } + } + } + + /** + * Stops a stack (if running) and removes it entirely from the runner, so it + * no longer appears in [stateState] / snapshots. Tolerant of unknown names. + */ + fun removeStack(name: StackName) { + if (this.stacks.containsKey(name)) { + shutDown(name) + } + this.stacks.remove(name) + this._stackState.remove(name) + } + fun shutDownAll() { this.stacks.keys.forEach { shutDown(it) } } diff --git a/nebula-runtime/src/main/kotlin/com/orbitalhq/nebula/runtime/server/NebulaServer.kt b/nebula-runtime/src/main/kotlin/com/orbitalhq/nebula/runtime/server/NebulaServer.kt index 73c51eb..118f46f 100644 --- a/nebula-runtime/src/main/kotlin/com/orbitalhq/nebula/runtime/server/NebulaServer.kt +++ b/nebula-runtime/src/main/kotlin/com/orbitalhq/nebula/runtime/server/NebulaServer.kt @@ -15,6 +15,7 @@ import io.ktor.http.* import io.ktor.serialization.jackson.* import io.ktor.server.application.* import io.ktor.server.engine.* +import io.ktor.server.http.content.* import io.ktor.server.netty.* import io.ktor.server.plugins.contentnegotiation.* import io.ktor.server.request.* @@ -25,6 +26,7 @@ import io.ktor.websocket.* import io.rsocket.kotlin.ktor.server.RSocketSupport import kotlinx.coroutines.channels.consumeEach import kotlinx.coroutines.runBlocking +import java.util.concurrent.ConcurrentHashMap import reactor.core.publisher.Flux import reactor.core.publisher.Hooks @@ -46,6 +48,27 @@ class NebulaServer( } private val objectMapper = jacksonObjectMapper().findAndRegisterModules() + + // Submissions that failed to compile, keyed by stack name. Surfaced in the + // admin snapshot until a valid version replaces them (or they're deleted). + private val failedSubmissions = ConcurrentHashMap() + + private fun buildAdminSnapshot(): List { + val compiled = stackExecutor.snapshot().map { event -> + AdminStackView( + name = event.stackName, + stackState = event, + source = stackExecutor.sourceFor(event.stackName) ?: "", + compilationErrors = emptyList() + ) + } + val compiledNames = compiled.map { it.name }.toSet() + val failed = failedSubmissions.values + .filter { it.name !in compiledNames } + .map { AdminStackView(it.name, null, it.source, it.compilationErrors) } + return compiled + failed + } + fun start(wait: Boolean = true): NettyApplicationEngine { return embeddedServer(Netty, port = port) { install(WebSockets) @@ -98,6 +121,118 @@ class NebulaServer( call.respond(stackExecutor.stateState) } } + // Admin API for the management UI. + // Distinct from the Orbital-facing /stacks + /stream/stacks contract above, + // which is left untouched. + route("/api/stacks") { + // Unified snapshot: compiled stacks (with live state) plus any + // submissions that failed to compile (with their source + errors). + get { + call.respond(buildAdminSnapshot()) + } + // Submit a stack from the admin UI. On compilation failure the + // submission (source + errors) is recorded so it appears in the + // snapshot, and is replaced once a valid version is submitted + // under the same name. + put("/{id}") { + val id = call.parameters["id"] ?: return@put call.respond( + HttpStatusCode.BadRequest, + "Missing or malformed id" + ) + val script = call.receiveText() + scriptExecutor.compileToStackWithSource(script, call.hostConfig()).fold( + { exception -> + val failure = FailedSubmission( + id, + script, + exception.errors.map { it.toCompilationErrorDto() } + ) + failedSubmissions[id] = failure + call.respond(HttpStatusCode.UnprocessableEntity, failure) + }, + { stackWithSource -> + failedSubmissions.remove(id) + stackExecutor.submit(stackWithSource.withName(id), startAsync = true) + call.respond(buildAdminSnapshot()) + } + ) + } + // Start a whole stack that was previously stopped. + post("/{id}/start") { + handleStackAction(call) { id -> stackExecutor.startStack(id) } + } + // Stop a whole stack (components stopped, stack stays listed as Stopped). + post("/{id}/stop") { + handleStackAction(call) { id -> stackExecutor.shutDown(id) } + } + // Remove a stack entirely (stopping it first), or clear a failed submission. + delete("/{id}") { + val id = call.parameters["id"] ?: return@delete call.respond( + HttpStatusCode.BadRequest, + "Missing or malformed id" + ) + failedSubmissions.remove(id) + stackExecutor.removeStack(id) + call.respond(buildAdminSnapshot()) + } + // Stop a single component, leaving the rest of the stack running. + post("/{id}/components/{componentId}/stop") { + handleComponentAction(call) { id, componentId -> + stackExecutor.stopComponent(id, componentId) + } + } + // (Re)start a single component. + post("/{id}/components/{componentId}/start") { + handleComponentAction(call) { id, componentId -> + stackExecutor.startComponent(id, componentId) + } + } + } + // Live log stream for a stack. + webSocket("/api/stacks/{id}/logs") { + val id = call.parameters["id"] ?: return@webSocket close( + CloseReason(CloseReason.Codes.CANNOT_ACCEPT, "Missing id") + ) + val disposable = try { + stackExecutor.logs(id).subscribe { message -> + runBlocking { + send(Frame.Text(objectMapper.writeValueAsString(message))) + } + } + } catch (e: Exception) { + return@webSocket close( + CloseReason(CloseReason.Codes.CANNOT_ACCEPT, e.message ?: "Stack not found") + ) + } + try { + incoming.consumeEach { /* ignore inbound frames */ } + } finally { + disposable.dispose() + } + } + // Live state-event stream for a stack. + webSocket("/api/stacks/{id}/events") { + val id = call.parameters["id"] ?: return@webSocket close( + CloseReason(CloseReason.Codes.CANNOT_ACCEPT, "Missing id") + ) + val host = call.request.host() + val disposable = try { + stackExecutor.stackEvents(id).subscribe { event -> + runBlocking { + send(Frame.Text(objectMapper.writeValueAsString(event.updateHostReferences(host)))) + } + } + } catch (e: Exception) { + return@webSocket close( + CloseReason(CloseReason.Codes.CANNOT_ACCEPT, e.message ?: "Stack not found") + ) + } + try { + incoming.consumeEach { /* ignore inbound frames */ } + } finally { + disposable.dispose() + } + } webSocket("/stream/stacks") { val call = call // We capture the host on the request. That's the address that the caller is contacting this server on. @@ -127,10 +262,51 @@ class NebulaServer( } } } + // Serve the management UI (bundled into the jar under resources/web). + // Declared last so its catch-all fallback never shadows the API routes above. + singlePageApplication { + useResources = true + filesPath = "web" + } } }.start(wait = wait) } + private suspend fun handleStackAction( + call: ApplicationCall, + action: (id: String) -> Unit + ) { + val id = call.parameters["id"] + ?: return call.respond(HttpStatusCode.BadRequest, "Missing or malformed id") + try { + action(id) + } catch (e: IllegalStateException) { + return call.respond(HttpStatusCode.NotFound, e.message ?: "Not found") + } + call.respond(buildAdminSnapshot()) + } + + private suspend fun handleComponentAction( + call: ApplicationCall, + action: (id: String, componentId: String) -> Unit + ) { + val id = call.parameters["id"] + ?: return call.respond(HttpStatusCode.BadRequest, "Missing or malformed id") + val componentId = call.parameters["componentId"] + ?: return call.respond(HttpStatusCode.BadRequest, "Missing or malformed componentId") + try { + action(id, componentId) + } catch (e: IllegalStateException) { + return call.respond(HttpStatusCode.NotFound, e.message ?: "Not found") + } + val snapshot = stackExecutor.snapshot(id) + if (snapshot == null) { + call.respond(HttpStatusCode.NotFound, "Stack $id not found") + } else { + call.respond(snapshot) + } + } + private fun compile(updateStacksRequest: UpdateStackRSocketRequest, hostConfig: HostConfig): Map { return updateStacksRequest.stacks.mapValues { (key, stackScript) -> scriptExecutor.toStackWithSource(stackScript, hostConfig).withName(key) From 8cf75fe685871c9ca78064e12d001825dc5db19a Mon Sep 17 00:00:00 2001 From: Marty Pitt Date: Mon, 22 Jun 2026 11:21:49 +0100 Subject: [PATCH 4/5] add nebula ui --- .../nebula/runtime/server/AdminModels.kt | 45 + nebula-ui/.gitignore | 24 + nebula-ui/README.md | 49 + nebula-ui/components.json | 22 + nebula-ui/eslint.config.js | 23 + nebula-ui/index.html | 16 + nebula-ui/package-lock.json | 4909 +++++++++++++++++ nebula-ui/package.json | 50 + nebula-ui/public/favicon-16x16.png | Bin 0 -> 439 bytes nebula-ui/public/favicon-32x32.png | Bin 0 -> 766 bytes nebula-ui/public/favicon.ico | Bin 0 -> 15406 bytes .../favicons/android-chrome-192x192.png | Bin 0 -> 5430 bytes .../favicons/android-chrome-512x512.png | Bin 0 -> 19388 bytes .../public/favicons/apple-touch-icon.png | Bin 0 -> 4802 bytes nebula-ui/public/favicons/favicon-16x16.png | Bin 0 -> 439 bytes nebula-ui/public/favicons/favicon-32x32.png | Bin 0 -> 766 bytes nebula-ui/public/favicons/favicon.ico | Bin 0 -> 15406 bytes nebula-ui/public/favicons/site.webmanifest | 1 + nebula-ui/public/logo-192x192.png | Bin 0 -> 4026 bytes nebula-ui/src/App.tsx | 14 + nebula-ui/src/assets/github.svg | 1 + nebula-ui/src/assets/react.svg | 1 + nebula-ui/src/components/Layout.tsx | 78 + .../src/components/SubmitStackDialog.tsx | 135 + nebula-ui/src/components/ui/avatar.tsx | 53 + nebula-ui/src/components/ui/breadcrumb.tsx | 109 + nebula-ui/src/components/ui/button.tsx | 60 + nebula-ui/src/components/ui/collapsible.tsx | 33 + nebula-ui/src/components/ui/dialog.tsx | 141 + nebula-ui/src/components/ui/dropdown-menu.tsx | 255 + nebula-ui/src/components/ui/input.tsx | 21 + nebula-ui/src/components/ui/label.tsx | 24 + nebula-ui/src/components/ui/resizable.tsx | 54 + nebula-ui/src/components/ui/scroll-area.tsx | 56 + nebula-ui/src/components/ui/separator.tsx | 26 + nebula-ui/src/components/ui/sheet.tsx | 139 + nebula-ui/src/components/ui/sidebar.tsx | 725 +++ nebula-ui/src/components/ui/skeleton.tsx | 13 + nebula-ui/src/components/ui/table.tsx | 114 + nebula-ui/src/components/ui/tabs.tsx | 64 + nebula-ui/src/components/ui/textarea.tsx | 18 + nebula-ui/src/components/ui/tooltip.tsx | 59 + nebula-ui/src/hooks/use-mobile.ts | 19 + nebula-ui/src/index.css | 167 + nebula-ui/src/lib/api-error.ts | 46 + nebula-ui/src/lib/api.ts | 116 + nebula-ui/src/lib/display.tsx | 57 + nebula-ui/src/lib/toast.ts | 39 + nebula-ui/src/lib/types/stack.ts | 134 + nebula-ui/src/lib/utils.ts | 6 + nebula-ui/src/lib/websocket.ts | 111 + nebula-ui/src/main.tsx | 12 + nebula-ui/src/pages/StackDetail.tsx | 171 + nebula-ui/src/pages/StacksList.tsx | 211 + .../stack-detail/CompilationErrorsView.tsx | 58 + .../src/pages/stack-detail/ComponentsView.tsx | 196 + nebula-ui/src/pages/stack-detail/LogsView.tsx | 163 + nebula-ui/tsconfig.app.json | 34 + nebula-ui/tsconfig.json | 15 + nebula-ui/tsconfig.node.json | 26 + nebula-ui/vite.config.ts | 26 + 61 files changed, 8939 insertions(+) create mode 100644 nebula-runtime/src/main/kotlin/com/orbitalhq/nebula/runtime/server/AdminModels.kt create mode 100644 nebula-ui/.gitignore create mode 100644 nebula-ui/README.md create mode 100644 nebula-ui/components.json create mode 100644 nebula-ui/eslint.config.js create mode 100644 nebula-ui/index.html create mode 100644 nebula-ui/package-lock.json create mode 100644 nebula-ui/package.json create mode 100644 nebula-ui/public/favicon-16x16.png create mode 100644 nebula-ui/public/favicon-32x32.png create mode 100644 nebula-ui/public/favicon.ico create mode 100644 nebula-ui/public/favicons/android-chrome-192x192.png create mode 100644 nebula-ui/public/favicons/android-chrome-512x512.png create mode 100644 nebula-ui/public/favicons/apple-touch-icon.png create mode 100644 nebula-ui/public/favicons/favicon-16x16.png create mode 100644 nebula-ui/public/favicons/favicon-32x32.png create mode 100644 nebula-ui/public/favicons/favicon.ico create mode 100644 nebula-ui/public/favicons/site.webmanifest create mode 100644 nebula-ui/public/logo-192x192.png create mode 100644 nebula-ui/src/App.tsx create mode 100644 nebula-ui/src/assets/github.svg create mode 100644 nebula-ui/src/assets/react.svg create mode 100644 nebula-ui/src/components/Layout.tsx create mode 100644 nebula-ui/src/components/SubmitStackDialog.tsx create mode 100644 nebula-ui/src/components/ui/avatar.tsx create mode 100644 nebula-ui/src/components/ui/breadcrumb.tsx create mode 100644 nebula-ui/src/components/ui/button.tsx create mode 100644 nebula-ui/src/components/ui/collapsible.tsx create mode 100644 nebula-ui/src/components/ui/dialog.tsx create mode 100644 nebula-ui/src/components/ui/dropdown-menu.tsx create mode 100644 nebula-ui/src/components/ui/input.tsx create mode 100644 nebula-ui/src/components/ui/label.tsx create mode 100644 nebula-ui/src/components/ui/resizable.tsx create mode 100644 nebula-ui/src/components/ui/scroll-area.tsx create mode 100644 nebula-ui/src/components/ui/separator.tsx create mode 100644 nebula-ui/src/components/ui/sheet.tsx create mode 100644 nebula-ui/src/components/ui/sidebar.tsx create mode 100644 nebula-ui/src/components/ui/skeleton.tsx create mode 100644 nebula-ui/src/components/ui/table.tsx create mode 100644 nebula-ui/src/components/ui/tabs.tsx create mode 100644 nebula-ui/src/components/ui/textarea.tsx create mode 100644 nebula-ui/src/components/ui/tooltip.tsx create mode 100644 nebula-ui/src/hooks/use-mobile.ts create mode 100644 nebula-ui/src/index.css create mode 100644 nebula-ui/src/lib/api-error.ts create mode 100644 nebula-ui/src/lib/api.ts create mode 100644 nebula-ui/src/lib/display.tsx create mode 100644 nebula-ui/src/lib/toast.ts create mode 100644 nebula-ui/src/lib/types/stack.ts create mode 100644 nebula-ui/src/lib/utils.ts create mode 100644 nebula-ui/src/lib/websocket.ts create mode 100644 nebula-ui/src/main.tsx create mode 100644 nebula-ui/src/pages/StackDetail.tsx create mode 100644 nebula-ui/src/pages/StacksList.tsx create mode 100644 nebula-ui/src/pages/stack-detail/CompilationErrorsView.tsx create mode 100644 nebula-ui/src/pages/stack-detail/ComponentsView.tsx create mode 100644 nebula-ui/src/pages/stack-detail/LogsView.tsx create mode 100644 nebula-ui/tsconfig.app.json create mode 100644 nebula-ui/tsconfig.json create mode 100644 nebula-ui/tsconfig.node.json create mode 100644 nebula-ui/vite.config.ts diff --git a/nebula-runtime/src/main/kotlin/com/orbitalhq/nebula/runtime/server/AdminModels.kt b/nebula-runtime/src/main/kotlin/com/orbitalhq/nebula/runtime/server/AdminModels.kt new file mode 100644 index 0000000..1c56bef --- /dev/null +++ b/nebula-runtime/src/main/kotlin/com/orbitalhq/nebula/runtime/server/AdminModels.kt @@ -0,0 +1,45 @@ +package com.orbitalhq.nebula.runtime.server + +import com.orbitalhq.nebula.StackName +import com.orbitalhq.nebula.core.StackStateEvent +import kotlin.script.experimental.api.ScriptDiagnostic + +/** A single compilation diagnostic, flattened for the admin API. */ +data class CompilationErrorDto( + val message: String, + val line: Int?, + val column: Int?, + val severity: String +) + +/** + * A stack that was submitted but failed to compile. Held in memory until a + * valid version is submitted under the same name (which replaces it). + */ +data class FailedSubmission( + val name: StackName, + val source: String, + val compilationErrors: List +) + +/** + * Unified admin view of a submitted stack: either a compiled stack (with its + * live component state and source) or a failed submission (no state, but with + * its source and the compilation errors). `compilationErrors` is empty for a + * stack that compiled successfully. + */ +data class AdminStackView( + val name: StackName, + val stackState: StackStateEvent?, + val source: String, + val compilationErrors: List +) { + val failedCompilation: Boolean get() = compilationErrors.isNotEmpty() +} + +fun ScriptDiagnostic.toCompilationErrorDto(): CompilationErrorDto = CompilationErrorDto( + message = message, + line = location?.start?.line, + column = location?.start?.col, + severity = severity.name +) diff --git a/nebula-ui/.gitignore b/nebula-ui/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/nebula-ui/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/nebula-ui/README.md b/nebula-ui/README.md new file mode 100644 index 0000000..8e9033c --- /dev/null +++ b/nebula-ui/README.md @@ -0,0 +1,49 @@ +# nebula-ui + +A lightweight management UI for a Nebula server. It lets you see which stacks are +submitted and running, inspect and control individual components, and stream logs. + +It talks to the HTTP API exposed when Nebula is started with an HTTP port: + +```bash +nebula --http=8099 # 8099 is the default +``` + +## Tech + +React 19 + Vite + TypeScript + Tailwind 4 + shadcn/ui. + +## Development + +```bash +npm install +npm run dev # http://localhost:5173 +``` + +The dev server proxies `/api` and `/health` (including websockets) to the Nebula +server. By default it targets `http://localhost:8099`; override with: + +```bash +NEBULA_SERVER=http://localhost:9000 npm run dev +``` + +## Production + +You normally don't build this by hand. The `nebula-runtime` Maven module builds +this app (via `frontend-maven-plugin`) and bundles `dist/` into its jar under +`/web`, where `NebulaServer` serves it at the HTTP port. So `mvn install` from the +repo root produces a Nebula build that serves this UI at `http://localhost:8099/`. + +To build manually: + +```bash +npm run build # outputs to dist/ +``` + +## API surface used + +- `GET /api/stacks` — snapshot of all stacks + per-component lifecycle state +- `PUT /stacks/{id}` — submit & start a stack from a script +- `DELETE /api/stacks/{id}` — stop & remove a stack +- `POST /api/stacks/{id}/components/{componentId}/{start|stop}` — per-component control +- `WS /api/stacks/{id}/logs` — live log stream diff --git a/nebula-ui/components.json b/nebula-ui/components.json new file mode 100644 index 0000000..8f00892 --- /dev/null +++ b/nebula-ui/components.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/index.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "registries": {} +} diff --git a/nebula-ui/eslint.config.js b/nebula-ui/eslint.config.js new file mode 100644 index 0000000..b19330b --- /dev/null +++ b/nebula-ui/eslint.config.js @@ -0,0 +1,23 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs['recommended-latest'], + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + }, +]) diff --git a/nebula-ui/index.html b/nebula-ui/index.html new file mode 100644 index 0000000..c807adf --- /dev/null +++ b/nebula-ui/index.html @@ -0,0 +1,16 @@ + + + + + + + + + + Nebula + + +
+ + + diff --git a/nebula-ui/package-lock.json b/nebula-ui/package-lock.json new file mode 100644 index 0000000..628ffb2 --- /dev/null +++ b/nebula-ui/package-lock.json @@ -0,0 +1,4909 @@ +{ + "name": "nebula-ui", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nebula-ui", + "version": "0.0.0", + "dependencies": { + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-collapsible": "^1.1.12", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-tabs": "^1.1.13", + "@radix-ui/react-tooltip": "^1.2.8", + "@tailwindcss/vite": "^4.1.14", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-react": "^0.545.0", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-resizable-panels": "^3.0.6", + "react-router-dom": "^7.9.3", + "sonner": "^2.0.7", + "tailwind-merge": "^3.3.1", + "tailwindcss": "^4.1.14" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/node": "^24.6.0", + "@types/react": "^19.1.16", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.4", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.22", + "globals": "^16.4.0", + "tw-animate-css": "^1.4.0", + "typescript": "~5.9.3", + "typescript-eslint": "^8.45.0", + "vite": "^7.1.7" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "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.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", + "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", + "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.5", + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", + "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.6" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "license": "MIT" + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "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/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.2.tgz", + "integrity": "sha512-ceTwaxc4I5IOi97DgCotl3pqiyRGvffcc0oOsE2dQYaJOFIDsDt4VWG6xEbg1QePv9QWausCEIppud/tJ1wNig==", + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.4.tgz", + "integrity": "sha512-7AdCK9PQyiljKoBDbN8OuctCbd/esdwZPQ8RtOE3SsyQtUpiPb+ND75q0jEhC1m1ecBI0MFNeLJvwIh9iKHRcQ==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.9.tgz", + "integrity": "sha512-yqHW5WQ/cTpU/un7dqqIKNy2iRU8BC0JB78PEzTfCCYvZu1U6W9KwObAniMk9nhSfyotKPQTYaUD/HB0f5muig==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-avatar": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.12.tgz", + "integrity": "sha512-NQCQyWC7QrDPhjMn8hUqFeU0lUrprIgm1AyMgLbzuQJibNnatdc3SSMo3/UGFu/eUkJUU1cEcKCnyhXTQzq6tA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-is-hydrated": "0.1.1", + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.13.tgz", + "integrity": "sha512-F0s8+p2XNpfc3k02zBfB0jPWbkHVG162+p7BdUMyJ2308QMqZ+oaclX+FAzKFovgL5OqRU+Rvy6f/vbdlJVaqA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-controllable-state": "1.2.3", + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.9.tgz", + "integrity": "sha512-zuSVi7ziP7uQRqc+yGxsKJfNkdyHv3ZKDaHe0gzg4dRgws96TPKWIiz84tVHP4GEcEl8bC0mdt17NkcxaJHmaQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-slot": "1.2.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.3.tgz", + "integrity": "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.4.tgz", + "integrity": "sha512-QwH4PO5urrbO+FaGd5Aglg+YJgWTyyuZ3g/6mKvsqraLkglDdckw9JafgL5McL5VEJ6EPNduPaT3ZE9BttDAqg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.16.tgz", + "integrity": "sha512-l9ok83YBclEZhbjgzt76Hw733e6cvRKPNgO6GJ/IETlufXG9p+fRu2wlvpImQvR6xdJ8h7J8J2DBvsPEiEsKMw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-dismissable-layer": "1.1.12", + "@radix-ui/react-focus-guards": "1.1.4", + "@radix-ui/react-focus-scope": "1.1.9", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-portal": "1.1.11", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-slot": "1.2.5", + "@radix-ui/react-use-controllable-state": "1.2.3", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.2.tgz", + "integrity": "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.12.tgz", + "integrity": "sha512-MhoruH6xEzsbvOmo4TNgMfmtvRGyDZw4MDSdf4ybMHfezjqwzv6hyd4lsMzBp8K9Sn6sGzCF62x1I7BYUECXOg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-escape-keydown": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.17.tgz", + "integrity": "sha512-S6b3Jm57sY5EdDyOMLkacbB0qMnKhy1RCKZCt795ZkmtUOAvojYIZ5p7dXHIh5Cyr3jCLLI5/g64V3FKLudZmw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-menu": "2.1.17", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-controllable-state": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.4.tgz", + "integrity": "sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.9.tgz", + "integrity": "sha512-9Se8t+Zry+1rEOL7Y6l/4ANYU/TOtAtf8O2fKdwLltcaMcm6kOqYGbzO4tMFQ0bvzO920pRAoHpFZ4W85S3keQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.2.tgz", + "integrity": "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.9.tgz", + "integrity": "sha512-rDoTeMbCwRVcnmo7NGT9IlPo1yXmEI+xc1URP3oeewwZEV4mdTp1dYUhYbQdo4D1q2SjKVvv4N1gNY77QAQtjA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.17.tgz", + "integrity": "sha512-fmbNnFyf+JYCN0DhhWnEdUTDnZD1mXaPQWivdsPIb8oOSbARfD3LIQJbLCG8a8QLCwoMxiJ7GVPIFcC8Dw8v2Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-collection": "1.1.9", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.12", + "@radix-ui/react-focus-guards": "1.1.4", + "@radix-ui/react-focus-scope": "1.1.9", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-popper": "1.3.0", + "@radix-ui/react-portal": "1.1.11", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-roving-focus": "1.1.12", + "@radix-ui/react-slot": "1.2.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.7.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.3.0.tgz", + "integrity": "sha512-9PB589e1aWZbrlFUHdz6WiPCL+xLZHQFX7oibqG/6Q0SwOkxDyQX9W/cyPa+sAPPKuC8cpLCpRczE5a/1DiwVQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.9", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.2", + "@radix-ui/react-use-rect": "1.1.2", + "@radix-ui/react-use-size": "1.1.2", + "@radix-ui/rect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.11.tgz", + "integrity": "sha512-UEytdjgEh2tJGgD/gZK4FUx6t1rNIlM3U0DENhSrG7I75FGm1DnaDuVUWF1pWAWUwGmn1sCJ1VGHn8LhN1aTOw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.6.tgz", + "integrity": "sha512-zdTk4PlUO0E18HnZ3wYbW0KkJJxWCdiNYp6g6X1PtONFhxVkg01vliTJAmwIszU6mHiyBOoW9P0rAugl5/hULQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.5.tgz", + "integrity": "sha512-zifXeB8Y88qCYx8PLZ5oQb32KwZub+s925mMoZsBBq9KUQqWKkREubTfs6ASjRPPBe7Jt9O8OHH89+95VG+grA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.12.tgz", + "integrity": "sha512-FvgPt1bRmg8Xt2QpF7NUZW3dE0ZQHGm41dAdgT2J2GJPoIXz+9Em3NobAxf4fupcxhgHu03E5CRiU2MWvObXyg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-collection": "1.1.9", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.11.tgz", + "integrity": "sha512-DS39ziOgea75U/TrXKU2/oKp0be2jrDHnzFLvahg/0iNAT1Zq16e4Uw0WXwyXvsK+mG3BRyMb7A3NRZMDuEXtQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.2", + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.9.tgz", + "integrity": "sha512-gvgW+JV/Mbjj6darztTetnmElpQEzZrXpJvfj+dOxNAxiyHEAyUvEjjl4zxblvmjmKmi3jfPoy7ZdxzCuUBJSA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.5.tgz", + "integrity": "sha512-rCMO3QsIVKv5JTY5CVbo2MvO77SpEqqYc8AvRE7OWqRDOIqAKjsp+DrmnY9uc8NPdxB5E2z47HTYGeE2+NTptg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.14.tgz", + "integrity": "sha512-D5jwp9JNuwDeCw3CYD2Fz+sSHo0droQjC8u75dJHe4aWr5q6yBiXZU+hurXnKudRgEpUkD5TsI6bjHPo5ThUxA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-roving-focus": "1.1.12", + "@radix-ui/react-use-controllable-state": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.9.tgz", + "integrity": "sha512-u6F9MmTtBSLkiXNVDrtB/yPCZarM9smNswC24YYLV/M+bth6J3Gs3vlJezEoFwKZvPvxhCpUYdUnOsNG/0XOlA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.4", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.1.4", + "@radix-ui/react-dismissable-layer": "1.1.12", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-popper": "1.3.0", + "@radix-ui/react-portal": "1.1.11", + "@radix-ui/react-presence": "1.1.6", + "@radix-ui/react-primitive": "2.1.5", + "@radix-ui/react-slot": "1.2.5", + "@radix-ui/react-use-controllable-state": "1.2.3", + "@radix-ui/react-visually-hidden": "1.2.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.2.tgz", + "integrity": "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.3.tgz", + "integrity": "sha512-PLzC90MS+ReootmjC597dvopoelpZ8Q61HJkDXZSExitIq7PL55vHNnesAHwguHK0aPfBnpdNzQtv1uliaqQrA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.3", + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.3.tgz", + "integrity": "sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.2.tgz", + "integrity": "sha512-2uVLvLjgO7NZCWw01/FdqRwmA42J0BcjPMUCA+koFEOAb+zjqIP7SiFz/7zWPrKnVmSqr76Omq2ALyCuX4dhLw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.1.tgz", + "integrity": "sha512-qwOiz4Tjo8CNnrOLAYUMXeZwDzXgXpvK4TKQPmWLECM9XoWvA6+0Z2/7Ag3A4ivjS4ovbLJPbskkxioFyBhr8A==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.2.tgz", + "integrity": "sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.2.tgz", + "integrity": "sha512-d8a+bBY/FxikNPlgJJoaBHZX+zKVbWHYJGTLnLvveQgFSTntkGdEKv3JDtHrMS0DNYpllz2nRsTLGLKYttbpmw==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.2.tgz", + "integrity": "sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.5.tgz", + "integrity": "sha512-tPcHNI3FajdDBFpl/Ez1m2WL0ufJqBKyHxMDBvKitopamK36WwBGOMicuMEZKkM5Wce41QxUyv6BsiqfrWBiGg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.2.tgz", + "integrity": "sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA==", + "license": "MIT" + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.0.tgz", + "integrity": "sha512-IPIQ55ythEHkfEd9jMEi32OQ7SxURsGA43JI22lj01OLZNt2NUbJX8YUHxkVWyQ6daHPNn0truF5nSj3DQp6YQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.0.tgz", + "integrity": "sha512-M6s9cr10MibETyo8JsOkq+Lo1+lU6hcvb1MApnUql5qte/5hMEgzlN8/ReIKNfRV8rrqX50W1BX9zoUhC192RA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.0.tgz", + "integrity": "sha512-BqCoMoIbn0keKys+dEAdBa70EtOwV1bEsQCUgU9FdiZmmMge/Zk7LlkYGqbrdHR+Frnt0E1FOanly+rlwvvQzw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.0.tgz", + "integrity": "sha512-SIMzST3VFNXDAbeIWDWiFCNM5qncUBDWaEV7NfE7oZbDt2mgfW4MvbKdbYiGOLoM32gbTv608UMd0XktEYSD7w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.0.tgz", + "integrity": "sha512-ezjfSQMP7ArdUsbBwbQIfwAlhE84I2iVnzQNCFSveqV42q+BmKlzVpf7mxv5EchLcoWU4y6/heFzVg1F+hodUQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.0.tgz", + "integrity": "sha512-9+qTWGW9AZRhnUgwtTwzNwcPlL87ngkeN0LA+q1bADvmY9aNvWaF2TFW8BZgnQPYxpDI7+rMVLivcd4V737TAQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.0.tgz", + "integrity": "sha512-T1dMEQhXA/jkJ/jyMIw9IovK8bSUq7A8kLIlvZTb/6YIVsp2zLavr4F3oyllHWo7eIVJRyE5n3tUjQJEbE1IuQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.0.tgz", + "integrity": "sha512-2as0LgT7qQpyceQq6VUJYnumUMUrgGQCWIiDIN9DE0/tglsk6o66uCB4f3djRawAltvfCNLyZZrsqbPA6inCsA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.0.tgz", + "integrity": "sha512-bVURMg+6eNN9C/yc0aVjooZcwTTtYF4YW3xta5pP0//r3o1V8gXEHXWCndj47w/HhwsFroZrFhR+6uQP5T0n0g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.0.tgz", + "integrity": "sha512-Ful8pM/2yYI83PViWdFdpZhdI8HJ5qsXANe5atypbHDf+KIBBDsZsbyy8hbXnULVvW9NsTh5DHwbcBftyLTfiw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.0.tgz", + "integrity": "sha512-9Gp/DgrkzfUBmNPVTyPTvay+4xEP7M/clXpj3efXBcm6uTIVIgDg4rqUpqKXvLEuFRVuEpSAOkhgNeecvaZ4Cg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.0.tgz", + "integrity": "sha512-m9tsJz54LUXkSYM8+8PG81B9IKK5r+2T0clMq4QrS16xFosufU7firBDAZEsDheDs7wTlP7h3++S7lMsU955HA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.0.tgz", + "integrity": "sha512-3UvJ5PNVU16aJf6M3tFI24pWzAl2/ynfbyRN3ICyQajK1lSkrnVYNnLz3v04J32qKa0FczJc22zeToc0lr2A3w==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.0.tgz", + "integrity": "sha512-vRWUAbYLGHBZS6Q8Msb2sfnf1fvJf+47t8l/TwOerM2qArzy+IeNMTHrYLHXh95h8MoatPHI5hhSZNs+mGXKPg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.0.tgz", + "integrity": "sha512-c00T5SYENHAt86cfW47URaP3Us5vLC/4QO7GYud1G5VNRffCwwCuBspwqYrriuJB+5m0WFzClCn9wed0FBjKvg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.0.tgz", + "integrity": "sha512-krrCDilhXOwFkSkO3Wm9I/f9H0L92XHHwy2fwxjukxIbh0dem8gZqOW5Y8BsHrpJv5qwlRBV+Wl4ZFyRWhUpwg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.0.tgz", + "integrity": "sha512-7pfYFSTc4/rUC/FtAI0Qp6QthDBCIi6/AuP1xYqFk5vanI6KnL5dWKP60OM/05LOsbwTmIcvr6eXC4CJuJ75IA==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.0.tgz", + "integrity": "sha512-7SDIalKeIpG0Ifogbbdn58HmSotYMlf23K3dCJEmiVd9Fg36Vmni82iPQec27N3wY4Bvbxftkxz6vSx9OcouTg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.0.tgz", + "integrity": "sha512-eRZevouTH2i1HeAVLqJuLnt256krQkGY0TN6WsTmsIhuzbh457HuWDMakKwmi0Cjadux983CoSr8Lim2QhUIFw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.0.tgz", + "integrity": "sha512-3oVS7FLGa4U1qcvao9ylGxrjXZyUQqR8UwxEcnUEyPX53O/C/mKDZegNXTdHCP+h3e6ta/f1EN38Yif1mmZHYg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.0.tgz", + "integrity": "sha512-yTB9TgfWj5wHe5QgktAgXTLLot1gvEjl1NiPPAUiCs4oPrIWFl5V4nC3GrkNdj9LaAU4s94nVrGbGOCqUpyWsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.0.tgz", + "integrity": "sha512-5LOhoaesY3doG1c+ac/2JtgREpKoJr5bUHH8tKY0V8di7+uSV6BwLs2PlR0/yzefGOkR+wE7ZolZphHCsyG5Rw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.0.tgz", + "integrity": "sha512-yYkWHhmbhRTWTnWos5HC4GcPQfjlzzCNbM9e/+GXrLuaBXYA3qSDR9f0Vgufd5S8yX81U8jPKp7ZnAjZFMtRnw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.0.tgz", + "integrity": "sha512-SoTb6lPg25xZlA2ibwQ++ahCCnH+FP0qmEuafMJ4gznZKOlXioKEAeJLgCrqjM98ACziXM9V1amFjICVL4IFoA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.0.tgz", + "integrity": "sha512-5L+T1fMX4RIEBoZzT0+sQ0PhTS36NULFmMXtl1TZo44TMAROIMHbZufSOjVWt/Y622BtxgxtaNOokbTDvfsrZA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.1.tgz", + "integrity": "sha512-6NDaqRoAMSXD1mr/RXu0HBvNE9a2n5tHPsxu9XHLws8o4Twes5rBM2205SUUiJ9goAtadrN6xTGX0UDEwp/N4A==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "5.21.6", + "jiti": "^2.7.0", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.1" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.1.tgz", + "integrity": "sha512-yVPyo8RNkabVr3O2EhHEE0Rewu7YKzc1DhIqfL46LKveFrmu9XbDazNOJY7/GRuvw1h6u3utWnR29H/p5JPlgA==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.1", + "@tailwindcss/oxide-darwin-arm64": "4.3.1", + "@tailwindcss/oxide-darwin-x64": "4.3.1", + "@tailwindcss/oxide-freebsd-x64": "4.3.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.1", + "@tailwindcss/oxide-linux-x64-musl": "4.3.1", + "@tailwindcss/oxide-wasm32-wasi": "4.3.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.1" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.1.tgz", + "integrity": "sha512-SVlyf61g374l5cHyg8x9kf5xmLcOaxvOTsbsqDnSsDJaKOEFZ7GCvi84VAVGpxojYOs1+3K6M0UjXfqPU8vmOQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.1.tgz", + "integrity": "sha512-hVnWLwv+e/l7c4WKyVtHVrIPvYdqWHjRB3MDIqARynzFtnQg85kmQEFCbV9Ja0VVx4xXTIiDWY60Y7iz/iNoDA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.1.tgz", + "integrity": "sha512-Cf7abu0WVgbhU7ANgPUnSAvm7nCvMweusHb8FnaHlLfv/Caq4GYaEZg7ZImzzmjx4lIAfuS8q+eLIS7A7IzxIg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.1.tgz", + "integrity": "sha512-ZZqzX2Y+GXtXXfqSfpJhDm60OoZfvLHLCgm+J7NVqgHHJjG/m9ugZI77RwTsVd4fnBJuCFP6Ae6kTJb71UdS8g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.1.tgz", + "integrity": "sha512-/Ah/xik0LaMYfv9DZ0S/t4pBlBNYOcqtRwusjgovHkvT8ixueWCLyJjsaF5kQIckjb4IT8Q6K6p/iPmZMixYgg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.1.tgz", + "integrity": "sha512-gqdFoVJlw444GvpnheZLHmvTzSxI/cOUUh2KSNejQjTcYkW062SVD+En0rUgD+QV91bz1XGIGtt1HJd48xUGbQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.1.tgz", + "integrity": "sha512-Bwv9KwOvE0VKa86xPFif9b9c3Y1NxOV1P0gLti/IYaWEsQYZXDlxfGEtA8mdDZ7SG3wyNXAWYT5SIn3giL57oA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.1.tgz", + "integrity": "sha512-Ymi8O8T15HYQdOUWUtTI6ldN0neHP85FC+Qz32xTcZ7iJXtem/x8ITev0o1e9e5rkqj4lONZfTRLvkmin1+tKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.1.tgz", + "integrity": "sha512-M+P/91qJ6uILLw4k2G93GMDRAXj61SMvFQYt39AqvUqYgExXpLL5aepfns7sj4HiAQeolirQF9E0lzRvdf4zPQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.1.tgz", + "integrity": "sha512-zsM8uOeqvVGHsAXsJxsT28ttosFahLJKCLOTUBqRAtKnVgGSRitds9T432QiT8b77Yga7JIBkulIRRlJPtYhRA==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.10.0", + "@emnapi/runtime": "^1.10.0", + "@emnapi/wasi-threads": "^1.2.1", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.2", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.1.tgz", + "integrity": "sha512-aiNvSq9BsVk8V513lDKlrCFAgf8qBMPZTpgEhInL+NwQqs97mYmupVMrPrgBBSL8Pv/0zXu9MrMF9rMun1ZeNg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.1.tgz", + "integrity": "sha512-xDEyu1rg290472FEGaKHnzyDyh5QH+AlWvsU5hMoMtPpzmKlRI0jaYKCgSHDYtaQWZOYbMaduSyCwFwY4n1HmA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.1.tgz", + "integrity": "sha512-hItDHuIIlEV61R+faXu66s1K36aTurO/Qw0e45Vskz57gXl9pWOT6eg3zmcEui6CZXddbN7zd41bwmvag4JGwQ==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.3.1", + "@tailwindcss/oxide": "4.3.1", + "tailwindcss": "4.3.1" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "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.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "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.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "license": "MIT" + }, + "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/node": { + "version": "24.13.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.2.tgz", + "integrity": "sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.0.tgz", + "integrity": "sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/type-utils": "8.61.0", + "@typescript-eslint/utils": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.61.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.0.tgz", + "integrity": "sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.0.tgz", + "integrity": "sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.61.0", + "@typescript-eslint/types": "^8.61.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.0.tgz", + "integrity": "sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.0.tgz", + "integrity": "sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.0.tgz", + "integrity": "sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/utils": "8.61.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.0.tgz", + "integrity": "sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.0.tgz", + "integrity": "sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.61.0", + "@typescript-eslint/tsconfig-utils": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/visitor-keys": "8.61.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.0.tgz", + "integrity": "sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.61.0", + "@typescript-eslint/types": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.0.tgz", + "integrity": "sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz", + "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "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/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.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.37", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.37.tgz", + "integrity": "sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "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": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001799", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", + "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", + "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/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/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "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-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==", + "dev": true, + "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==", + "dev": true, + "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/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.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.372", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.372.tgz", + "integrity": "sha512-M3yhbAlilnwqC8D21t28UCDGHyitShTmmLRU/H+b74P6Ski16Nb9HONYEaVpMj/pwC7BEo5B95FpjODLCWbtfA==", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.21.6", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.6.tgz", + "integrity": "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "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": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.26", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.26.tgz", + "integrity": "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "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/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-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-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "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/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-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "ISC" + }, + "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/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", + "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "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-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "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/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "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/lucide-react": { + "version": "0.545.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.545.0.tgz", + "integrity": "sha512-7r1/yUuflQDSt4f1bpn5ZAocyIxcTyVyBBChSVtBKn5M+392cPmI5YJMWOJKk/HUWGm5wg83chlAZtCcGbEZtw==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "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/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", + "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "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.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "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/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", + "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-resizable-panels": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-3.0.6.tgz", + "integrity": "sha512-b3qKHQ3MLqOgSS+FRYKapNkJZf5EQzuf6+RLiq1/IlTHw99YrZ2NJZLk4hQIzTnnIkRg2LUqyVinu6YWWpUYew==", + "license": "MIT", + "peerDependencies": { + "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/react-router": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.17.0.tgz", + "integrity": "sha512-FDELK7rTMlCHO5+reyXsPlmfr7N1F91lPHsWYfMEGQm/KQ+F4JFM8jGoeQDmDvdTs93Fw9aSilH+uKRb4/jXvQ==", + "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-router-dom": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.17.0.tgz", + "integrity": "sha512-fyU2yjGups/hE6Xz0I5ZYbVL8Gx29eCjgpHaRaTaVU+OOAdfRX05KsvyRm0GO8YQwOkhpU3MurW1jyMUJn+zSw==", + "license": "MIT", + "dependencies": { + "react-router": "7.17.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/rollup": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.0.tgz", + "integrity": "sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.0", + "@rollup/rollup-android-arm64": "4.62.0", + "@rollup/rollup-darwin-arm64": "4.62.0", + "@rollup/rollup-darwin-x64": "4.62.0", + "@rollup/rollup-freebsd-arm64": "4.62.0", + "@rollup/rollup-freebsd-x64": "4.62.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.0", + "@rollup/rollup-linux-arm-musleabihf": "4.62.0", + "@rollup/rollup-linux-arm64-gnu": "4.62.0", + "@rollup/rollup-linux-arm64-musl": "4.62.0", + "@rollup/rollup-linux-loong64-gnu": "4.62.0", + "@rollup/rollup-linux-loong64-musl": "4.62.0", + "@rollup/rollup-linux-ppc64-gnu": "4.62.0", + "@rollup/rollup-linux-ppc64-musl": "4.62.0", + "@rollup/rollup-linux-riscv64-gnu": "4.62.0", + "@rollup/rollup-linux-riscv64-musl": "4.62.0", + "@rollup/rollup-linux-s390x-gnu": "4.62.0", + "@rollup/rollup-linux-x64-gnu": "4.62.0", + "@rollup/rollup-linux-x64-musl": "4.62.0", + "@rollup/rollup-openbsd-x64": "4.62.0", + "@rollup/rollup-openharmony-arm64": "4.62.0", + "@rollup/rollup-win32-arm64-msvc": "4.62.0", + "@rollup/rollup-win32-ia32-msvc": "4.62.0", + "@rollup/rollup-win32-x64-gnu": "4.62.0", + "@rollup/rollup-win32-x64-msvc": "4.62.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "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/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sonner": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz", + "integrity": "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "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/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/tailwind-merge": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", + "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.1.tgz", + "integrity": "sha512-hk+TB1m+K8CYNrP6rjQaq/Y+4Zylwpa87mLYBKCunwnnQ9p+fHb7kmSfGqyEJoxF/O6CDyABWVFEafNSYKll+Q==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "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/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.61.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.61.0.tgz", + "integrity": "sha512-8y31Rd0eGTrDKqhy6vT0HtzhN+YLjQizwX3aA3hPXP/ynSfnrBXcQY5IzsP9/DM7+klX4IUncZZjkchP0z+rUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.61.0", + "@typescript-eslint/parser": "8.61.0", + "@typescript-eslint/typescript-estree": "8.61.0", + "@typescript-eslint/utils": "8.61.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "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.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/vite": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.5.tgz", + "integrity": "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "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/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/nebula-ui/package.json b/nebula-ui/package.json new file mode 100644 index 0000000..4e4499d --- /dev/null +++ b/nebula-ui/package.json @@ -0,0 +1,50 @@ +{ + "name": "nebula-ui", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@radix-ui/react-avatar": "^1.1.10", + "@radix-ui/react-collapsible": "^1.1.12", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-separator": "^1.1.7", + "@radix-ui/react-slot": "^1.2.3", + "@radix-ui/react-tabs": "^1.1.13", + "@radix-ui/react-tooltip": "^1.2.8", + "@tailwindcss/vite": "^4.1.14", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-react": "^0.545.0", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-resizable-panels": "^3.0.6", + "react-router-dom": "^7.9.3", + "sonner": "^2.0.7", + "tailwind-merge": "^3.3.1", + "tailwindcss": "^4.1.14" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/node": "^24.6.0", + "@types/react": "^19.1.16", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.4", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.22", + "globals": "^16.4.0", + "tw-animate-css": "^1.4.0", + "typescript": "~5.9.3", + "typescript-eslint": "^8.45.0", + "vite": "^7.1.7" + } +} diff --git a/nebula-ui/public/favicon-16x16.png b/nebula-ui/public/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..61847f8c2736699eda7e6192f720d486ce0c7a54 GIT binary patch literal 439 zcmV;o0Z9IdP)CMS){6Xi$9fkaJBA{;1dj*k8T2PfjPvz!&>LJpDxmt~3- zV+t=GX1nY+H@1_aWRv|O1gTk+OejW> zv|W^V#1i+x0ptb;+`SV_)s+^;A9VDvdbWFv)wzKKL=!Q1`lp!|2jW_Ke~H<88yJvslsDBqN#n!pff4xbv^(06V?|xYj+mQ9^8R|Kb?V)p?Ar zxe-goSuZzmfS?iv)nhE8&)sU@M|)~U)qB~517wXtZxJLDAR4(S5%ua900960`Zu_a h00006Nkl#}7A_O6@8)0D& z3u1_6g&7E%6iIEiQc{^{TB7T=y6R5nKeZ!gWp`#4(;oKheCPcCfBy6RA7}O)Mpn`@ zkEX8JG@7zUv{;qPvMRxbd1_Q!o~PPc*_eRX z4j9@2S&|S6gft1#j2v16ou(^bku3#J%Bs;;UMs+!wL_rZpR*e+4yTY)UwWI#l7zfa zM_0g*cNjOCYha192sn{<2+3AO;kykX{0Ub}WgRp1i zB0FP4&^0_pC1BX+!L`S?gd&n8!Lg?p8EH#}xSkW003xk@-H10|Tx4okwRkxQTEKu| zNPxsHRN@MbWUH!*^L3R79y^Lf149CogoT`2vHlsk!@3WBpFmeIGoyYC3CLNU%?qq! zw_cJ}{DiE0dKUu*Z#_;D(nS;?vE=f-B`Dlpz%0O)kcg_Hi`e#85Cuoaf8lCF6`4^X zq5zdqzUX?1vIiGXdjBlP^`?8E3yDo>Pkl!dN~+KB`Cwk}P`@@G$%rU`7Cv*eAQasL zUujCf^UhWw&okx~=EFI<0>Ukvt$0kpf3X8&v-LjB@~~s>lLO;EM_|(L4@^$rUm!fE w-#_8^I(`EH0RR7GC*3Ll000I_L_t&o0Ii_@% literal 0 HcmV?d00001 diff --git a/nebula-ui/public/favicon.ico b/nebula-ui/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..cc4460922168470c6713e98250867b92d4418895 GIT binary patch literal 15406 zcmeHN3s6*57`{!-)QoE`DJ84nf;?6UR6r0!Knyfr!D#pbQ5h5rMX`5Fd%8 z7$^@BEvv~MYR;r-KGM=sOlf>;jn$Yn)AX9Azw_Vi+&TB$yN|mp>^9w<`RAN-_y5oL zo&Wy#yanMN;aDgD03{pK2m&^Xz`VvA!jxG z*XCEi-PWtHaNGn@cTq+r{JiUiDB~l89ojz`JpeAedQ{XK^;loHwB?j0d&Fql__1hT zzhIeY`(1N8pg4n1?WZLSg*!X0i1zDpi^V#fwQt{i96nj~mS}sf`Vb@ycvzD?_18~3 zuR}pvn%I`}HHQiR5QqN5cSr5tF5e{Tr-nZYx0^0Nep;$S`~1;quyJm=D73xLO`0y2 z*XNcvwAT{LYVp(6_R)dHHp)Y58f`YVsdfq)9%4UZCX!49`zKq!fu`;yq_6oSCeR37 zDTrz5)9u-)fF8eTc{lFVjS4XSO7LZ|=g#^a)rHtPzV3f}aZ;K-8F<0In71jOm?6_k zi|D7&;cXnpUr%_w^c88m!v6ov`U6n-#8_F~&ri;h#s)e@WGBVRba-qmJI1%pUup|p z6zj*ahHqDDxIbL2`@B=}^T}9=?K(onUcMboMXMCpsO!%5&rFIJG4@w9$?&ri_Fysa>IGXgn{pt)5$^YKv!&yuLGK?fiSe`I;l}ZR1ypb^8x3m!N&qG02P? zqTqt-)fHL!3LCoTQbP8^o#D&tXyuRgxX-+7S}xpbI49$Sd(ji3LdjZNxvrlvA_gvO zIx5qr+%fG+{@8}30gp)gL5P2ma2pxsr|QFz1O1?J;R^ALo#o8tyP7|?Va@C!$)9hO zRjYDGy*XrG^5(X)k}k`e<~_l`e9|K~RQacb^?}1HcT0MdFQ0mXKb}2N9@Tke zs{HXD1HUIsZP?Tk{1KCKP~)GK7z>w~yC76oE%i43qe$Ge6tA{<288!z?(DcMwcp$L z=RKYR-!z_=`0+k(Dq0E6&s0kPdlUbZFcX}pvVHz_cEd-IJ~Rxf^A>p>e;j8wFuZub z<39GwGoJ>$m*tK8XOB!I_qR?;e&zXpTJ;``9%MZm@HYM!H@iyL0iGA~ys?bF$L|8i zG!$>+zhLY*xV23_C!+1ZF`%xnLgMai{7+WBPwvZE&xa{zHa)d=uk3!JxAAAW@_CG# zm!{__=B3^gKRjo)d}#SD7&ACP7CTn|mr37=r~7}FFPq0TO?Kii1$X3MJAaA9e^Gj- zst)Se6Ia$Rw7$~xrzCuqGtJ{1p=MsWP5d_(*GTp_CeV7dq#fa3nNuj?Q_gI9g4{uw zNY-O&d~kk*YfY+;XTo@AR!!I5GgtZJ8WP7MiqEIFn=eAelv(1rEsu|Dw=E=g*m2?} z>34BHuD15%?b)&`{P9i$uEp_wGjdRqgXEh9SMG6m zHqX}S3jgGRy`d~)3b|jr*rsHSh*fY$+;KyKY}(NJ?49eg+%fM8e`_7&OdrqnZ3vIU zmTlS4=d7-yyzBh!_iK)D-SxlD-?Q&Q_rLD{j(p2{{OIx1(fA4X@BVv7>hPp3a<`Za yt#QFVe|wULE7-`HaBuN5KG4t7+t7+_q2IH&r=s8e3_FlJxgMndbPu@ffqwuCyV_I$ literal 0 HcmV?d00001 diff --git a/nebula-ui/public/favicons/android-chrome-192x192.png b/nebula-ui/public/favicons/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..2c8bc157b9a908533e8e0a29506020d95b3de317 GIT binary patch literal 5430 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 GMf@Lf0s>6{ literal 0 HcmV?d00001 diff --git a/nebula-ui/public/favicons/android-chrome-512x512.png b/nebula-ui/public/favicons/android-chrome-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..df68287a2f6d6a971ded1743345faba20fa36a15 GIT binary patch literal 19388 zcmYg&Wk3|l_xA3x2!eDeUDBn}xgZkK(#-`FP`aB1L_}@_0CuI1mT~PflkyN|Hyt~$RqJoUo>F2nUWRlByMV#8^ zc|(e`$DiB%N1Ns+KO+{prlYti6m^mcIyfGgZ>7VpBV~D;#=UoW9)uA?3H84AH*b9< z_=(fL`SnC{;J|pt&;8f*L`?iVr-6{$<7)RERH%-c9$m?MDQd-$G`vpYv$u}?&-8UZ zY{sTyU%R(c@GaxsX?G1GJ%W3FG{tu@j9sd_XRbH6R^H9*eU6KnP`uzZNDsrN zM?zp7I0X$FeXpOERxf{L@!3qX8h9&|*EHE0vtgr87tX3G_bjC~`3>LFHLF5%%KjX6$ZHhM==tk@>Mfa`_C)Ou*=t$5-0c4h3Y>o$6??Cl7rS@dElh2Z zSzDf^$HTQ>d;uMRW?+b8dE#$Vd;b0h=}}+u(@iZG>)dP>^EUg^E`q!~EAL6Egf-Cv zTYimQ?`HR(%T$!VMkDiYvK2xK$}%e3PF?NAb~Y9Rq#teK(|Ol zvoHNAeo1nL>`0n{h)wCcUwTUK8O_zjMFk0*xt1Jsz5| z{LOo>J7a*tIa%bbd%0{(L(Gaw+5mit^7mA+mj!N2K_SQrixEacgkh!9TG+6^b?^XQV2+2W%Qy4KR`IY5sb}64Xl$sd$mxyMsYv+GBOs;|JdN zak7`%6a0pZ2{qY8L@fS>AyOAQiCxcbrl0+5PT_I7mTDUJ{uFhrOe;esjc>q{tdlJZ zk|(AjM#2=EbQO?LfqsM7-*zXHzAP;rIPxUdeSX#rNGJ&F*bJO7ZF;};Yh?mD4mL$3 z!?{kXn^NLNr_#!Cp`4^8JyzGYzPi<&PA`Qc|Fd#(!)6%s*mu}z_-Z%rsh#co%_wY4 zIbNNa$6Ws-#U&T9t?A7Mx}VxdjVTig=)PP?NO-zgYuX;bJ|yhd(ZuAtT*rV5sR^Zz zTR%$m74-9ABUaMl?~k#59IQ9rCFZk3@^2fatY6jwy1M-R@#_30HUsk>c_)qMCyr2j zeTeJ+J5-h5ILgmFq=+LtE+GAEAtn`njOXAA2eKEoHVqr<5iPWS!?XX{IDG(rhN9U1 zRLSf2@1G7yU)REp3ke=SI%{KzEi1Nu!!ooc*A%(^m&XWLdR$2pkTUSDEK+MkcA+MYnKW#|&~QKUN~ZK?QOL&w z^G;2WH_Wd+-M&ham2>C}Z#yhzm(}4Si^53qEl*Bpc@}pQ{)qbQMC)J|pM_j$*jLhW zuIpbom`#NA*Be?`QYjBz?|%}bqyOs;jZq{&Z1n;@fPagPCeDi98bmg7UCI)F0Jp6!Dd>=(2I4^d^nl~I-zy5lr`;lg; zD=c0+30Rh){Q{#m5nDP7QT8?v)**W2KvypFrHR+}lgE|n^JyXaR-fAIy7=)d7dHh`x(hr1K8@%z6vv$9`W;G97Zzv`U|;cseohMNv!lCpEk;I? zihB{4;5p93I;B{jI==>!xznNPq0EJcYL|yOSJ*ya*L~)(ipQA4zAS@&==8SiR1DW&0Qy?CS{4;eu8YtWON^hWdShbU5meLq~PR>*$a4 zE3l-2OxWCxoNeGG#anPTh_6sC^KfbItVmG$0 z?Bqjkrjr<6N^Fi3iUTplW9`1c4>vZeKGKA|(h1+V^rzdeA(+VMYjIi^AA@-Kj!)Sk zat>b-FCiVuAz|%8_Z2S@N>kiaIwyr#44E5V>ZC6t0y-BL$c%T%INVp<0XWDCuL=P) zP6(`(5WxPz7Yo0DJ&4(nB8Azm_hp>+3N|)?ZAPdFy@G84V4JN!S-*n)2jJ=;V7Puo zcvd{1?4gDQ-R03YD6$}YzL4v5SBu{*sX^6KsC+I_n^gl?L!acgFX)h_U=sj@Jz5$k zxI8%+lMQl%R$N9N%|Yx.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 literal 0 HcmV?d00001 diff --git a/nebula-ui/public/favicons/apple-touch-icon.png b/nebula-ui/public/favicons/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f70ce1888f3fa9f1fda76474fa29db7cf189c3b8 GIT binary patch literal 4802 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 PdjL9``WiKAc2WNYc9stB literal 0 HcmV?d00001 diff --git a/nebula-ui/public/favicons/favicon-16x16.png b/nebula-ui/public/favicons/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..61847f8c2736699eda7e6192f720d486ce0c7a54 GIT binary patch literal 439 zcmV;o0Z9IdP)CMS){6Xi$9fkaJBA{;1dj*k8T2PfjPvz!&>LJpDxmt~3- zV+t=GX1nY+H@1_aWRv|O1gTk+OejW> zv|W^V#1i+x0ptb;+`SV_)s+^;A9VDvdbWFv)wzKKL=!Q1`lp!|2jW_Ke~H<88yJvslsDBqN#n!pff4xbv^(06V?|xYj+mQ9^8R|Kb?V)p?Ar zxe-goSuZzmfS?iv)nhE8&)sU@M|)~U)qB~517wXtZxJLDAR4(S5%ua900960`Zu_a h00006Nkl#}7A_O6@8)0D& z3u1_6g&7E%6iIEiQc{^{TB7T=y6R5nKeZ!gWp`#4(;oKheCPcCfBy6RA7}O)Mpn`@ zkEX8JG@7zUv{;qPvMRxbd1_Q!o~PPc*_eRX z4j9@2S&|S6gft1#j2v16ou(^bku3#J%Bs;;UMs+!wL_rZpR*e+4yTY)UwWI#l7zfa zM_0g*cNjOCYha192sn{<2+3AO;kykX{0Ub}WgRp1i zB0FP4&^0_pC1BX+!L`S?gd&n8!Lg?p8EH#}xSkW003xk@-H10|Tx4okwRkxQTEKu| zNPxsHRN@MbWUH!*^L3R79y^Lf149CogoT`2vHlsk!@3WBpFmeIGoyYC3CLNU%?qq! zw_cJ}{DiE0dKUu*Z#_;D(nS;?vE=f-B`Dlpz%0O)kcg_Hi`e#85Cuoaf8lCF6`4^X zq5zdqzUX?1vIiGXdjBlP^`?8E3yDo>Pkl!dN~+KB`Cwk}P`@@G$%rU`7Cv*eAQasL zUujCf^UhWw&okx~=EFI<0>Ukvt$0kpf3X8&v-LjB@~~s>lLO;EM_|(L4@^$rUm!fE w-#_8^I(`EH0RR7GC*3Ll000I_L_t&o0Ii_@% literal 0 HcmV?d00001 diff --git a/nebula-ui/public/favicons/favicon.ico b/nebula-ui/public/favicons/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..cc4460922168470c6713e98250867b92d4418895 GIT binary patch literal 15406 zcmeHN3s6*57`{!-)QoE`DJ84nf;?6UR6r0!Knyfr!D#pbQ5h5rMX`5Fd%8 z7$^@BEvv~MYR;r-KGM=sOlf>;jn$Yn)AX9Azw_Vi+&TB$yN|mp>^9w<`RAN-_y5oL zo&Wy#yanMN;aDgD03{pK2m&^Xz`VvA!jxG z*XCEi-PWtHaNGn@cTq+r{JiUiDB~l89ojz`JpeAedQ{XK^;loHwB?j0d&Fql__1hT zzhIeY`(1N8pg4n1?WZLSg*!X0i1zDpi^V#fwQt{i96nj~mS}sf`Vb@ycvzD?_18~3 zuR}pvn%I`}HHQiR5QqN5cSr5tF5e{Tr-nZYx0^0Nep;$S`~1;quyJm=D73xLO`0y2 z*XNcvwAT{LYVp(6_R)dHHp)Y58f`YVsdfq)9%4UZCX!49`zKq!fu`;yq_6oSCeR37 zDTrz5)9u-)fF8eTc{lFVjS4XSO7LZ|=g#^a)rHtPzV3f}aZ;K-8F<0In71jOm?6_k zi|D7&;cXnpUr%_w^c88m!v6ov`U6n-#8_F~&ri;h#s)e@WGBVRba-qmJI1%pUup|p z6zj*ahHqDDxIbL2`@B=}^T}9=?K(onUcMboMXMCpsO!%5&rFIJG4@w9$?&ri_Fysa>IGXgn{pt)5$^YKv!&yuLGK?fiSe`I;l}ZR1ypb^8x3m!N&qG02P? zqTqt-)fHL!3LCoTQbP8^o#D&tXyuRgxX-+7S}xpbI49$Sd(ji3LdjZNxvrlvA_gvO zIx5qr+%fG+{@8}30gp)gL5P2ma2pxsr|QFz1O1?J;R^ALo#o8tyP7|?Va@C!$)9hO zRjYDGy*XrG^5(X)k}k`e<~_l`e9|K~RQacb^?}1HcT0MdFQ0mXKb}2N9@Tke zs{HXD1HUIsZP?Tk{1KCKP~)GK7z>w~yC76oE%i43qe$Ge6tA{<288!z?(DcMwcp$L z=RKYR-!z_=`0+k(Dq0E6&s0kPdlUbZFcX}pvVHz_cEd-IJ~Rxf^A>p>e;j8wFuZub z<39GwGoJ>$m*tK8XOB!I_qR?;e&zXpTJ;``9%MZm@HYM!H@iyL0iGA~ys?bF$L|8i zG!$>+zhLY*xV23_C!+1ZF`%xnLgMai{7+WBPwvZE&xa{zHa)d=uk3!JxAAAW@_CG# zm!{__=B3^gKRjo)d}#SD7&ACP7CTn|mr37=r~7}FFPq0TO?Kii1$X3MJAaA9e^Gj- zst)Se6Ia$Rw7$~xrzCuqGtJ{1p=MsWP5d_(*GTp_CeV7dq#fa3nNuj?Q_gI9g4{uw zNY-O&d~kk*YfY+;XTo@AR!!I5GgtZJ8WP7MiqEIFn=eAelv(1rEsu|Dw=E=g*m2?} z>34BHuD15%?b)&`{P9i$uEp_wGjdRqgXEh9SMG6m zHqX}S3jgGRy`d~)3b|jr*rsHSh*fY$+;KyKY}(NJ?49eg+%fM8e`_7&OdrqnZ3vIU zmTlS4=d7-yyzBh!_iK)D-SxlD-?Q&Q_rLD{j(p2{{OIx1(fA4X@BVv7>hPp3a<`Za yt#QFVe|wULE7-`HaBuN5KG4t7+t7+_q2IH&r=s8e3_FlJxgMndbPu@ffqwuCyV_I$ literal 0 HcmV?d00001 diff --git a/nebula-ui/public/favicons/site.webmanifest b/nebula-ui/public/favicons/site.webmanifest new file mode 100644 index 0000000..45dc8a2 --- /dev/null +++ b/nebula-ui/public/favicons/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/nebula-ui/public/logo-192x192.png b/nebula-ui/public/logo-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..214021b7ad533876f4c2748b2648d3e4bc89c174 GIT binary patch literal 4026 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 Lu`nz}JB9uS7H~rE literal 0 HcmV?d00001 diff --git a/nebula-ui/src/App.tsx b/nebula-ui/src/App.tsx new file mode 100644 index 0000000..afa37b6 --- /dev/null +++ b/nebula-ui/src/App.tsx @@ -0,0 +1,14 @@ +import { BrowserRouter, Routes, Route } from 'react-router-dom'; +import StacksList from '@/pages/StacksList'; +import StackDetail from '@/pages/StackDetail'; + +export default function App() { + return ( + + + } /> + } /> + + + ); +} diff --git a/nebula-ui/src/assets/github.svg b/nebula-ui/src/assets/github.svg new file mode 100644 index 0000000..538ec5b --- /dev/null +++ b/nebula-ui/src/assets/github.svg @@ -0,0 +1 @@ +GitHub \ No newline at end of file diff --git a/nebula-ui/src/assets/react.svg b/nebula-ui/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/nebula-ui/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/nebula-ui/src/components/Layout.tsx b/nebula-ui/src/components/Layout.tsx new file mode 100644 index 0000000..cb13311 --- /dev/null +++ b/nebula-ui/src/components/Layout.tsx @@ -0,0 +1,78 @@ +import type { ReactNode } from 'react'; +import { Link } from 'react-router-dom'; +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from '@/components/ui/breadcrumb'; +import { Separator } from '@/components/ui/separator'; +import { Button } from '@/components/ui/button'; +import { BookOpen, Boxes } from 'lucide-react'; +import GithubIcon from '@/assets/github.svg'; + +export interface Crumb { + label: string; + href?: string; +} + +interface LayoutProps { + children: ReactNode; + breadcrumbs: Crumb[]; +} + +export function Layout({ children, breadcrumbs }: LayoutProps) { + return ( +
+
+
+ + + Nebula + + + + + {breadcrumbs.map((crumb, index) => { + const isLast = index === breadcrumbs.length - 1; + return ( +
+ 0 ? 'hidden md:block' : undefined}> + {isLast ? ( + {crumb.label} + ) : crumb.href ? ( + + {crumb.label} + + ) : ( + {crumb.label} + )} + + {!isLast && } +
+ ); + })} +
+
+
+ +
+
{children}
+
+ ); +} diff --git a/nebula-ui/src/components/SubmitStackDialog.tsx b/nebula-ui/src/components/SubmitStackDialog.tsx new file mode 100644 index 0000000..88595d2 --- /dev/null +++ b/nebula-ui/src/components/SubmitStackDialog.tsx @@ -0,0 +1,135 @@ +import { useState, type ReactNode } from 'react'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Textarea } from '@/components/ui/textarea'; +import { Plus, Loader2 } from 'lucide-react'; +import { submitStack } from '@/lib/api'; +import { showSuccessToast, showWarningToast } from '@/lib/toast'; + +const PLACEHOLDER = `stack { + http { + get("/hello") { it.respondText("Hello from nebula") } + } +}`; + +interface SubmitStackDialogProps { + onSubmitted: () => void; + /** Prefill the stack name (and lock it — used when fixing a failed stack). */ + initialName?: string; + /** Prefill the script body. */ + initialScript?: string; + /** Custom trigger; defaults to a "Submit stack" button. */ + trigger?: ReactNode; +} + +export function SubmitStackDialog({ + onSubmitted, + initialName, + initialScript, + trigger, +}: SubmitStackDialogProps) { + const lockName = initialName !== undefined; + const [open, setOpen] = useState(false); + const [name, setName] = useState(initialName ?? ''); + const [script, setScript] = useState(initialScript ?? ''); + const [submitting, setSubmitting] = useState(false); + + const reset = () => { + setName(initialName ?? ''); + setScript(initialScript ?? ''); + setSubmitting(false); + }; + + const handleSubmit = async () => { + if (!name.trim() || !script.trim()) return; + setSubmitting(true); + try { + const result = await submitStack(name.trim(), script); + if (result.ok) { + showSuccessToast(`Submitted stack "${name.trim()}"`); + } else { + showWarningToast( + `Stack "${name.trim()}" has compilation errors — see its page for details.`, + ); + } + setOpen(false); + reset(); + onSubmitted(); + } catch { + // handleApiError already surfaced a toast for transport-level failures + setSubmitting(false); + } + }; + + return ( + { + setOpen(next); + if (!next) reset(); + }} + > + + {trigger ?? ( + + )} + + + + {lockName ? `Edit “${initialName}”` : 'Submit a stack'} + + {lockName + ? 'Fix the script and resubmit. A successful compile replaces the failed stack.' + : 'Give the stack a name and paste a Nebula script. It will be compiled and started immediately.'} + + +
+
+ + setName(e.target.value)} + autoComplete="off" + disabled={lockName} + /> +
+
+ +