From ca2e4d62b99a145528d11dfd3038a3bb1a71a621 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Mon, 10 Nov 2025 13:13:03 +0200 Subject: [PATCH 001/131] fix: Repair broken urls and fix typos Signed-off-by: Alex-Andrei Cioc --- pages/faq.mdx | 18 +++++----- pages/features/autoscale.mdx | 13 ++++--- pages/features/load-balancing.mdx | 18 +++++----- pages/features/scale-to-zero.mdx | 22 ++++++------ pages/features/snapshots.mdx | 8 ++--- pages/integrations/kubernetes.mdx | 6 ++-- pages/introduction.mdx | 5 ++- pages/platform/certificates.mdx | 6 ++-- pages/platform/domains.mdx | 4 +-- pages/platform/images.mdx | 16 ++++----- pages/platform/instances.mdx | 2 +- pages/platform/services.mdx | 8 ++--- pages/platform/troubleshooting.mdx | 14 ++++---- pages/platform/volumes.mdx | 6 ++-- pages/use-cases/api-gateways.mdx | 19 ++++++++--- pages/use-cases/headless-browsers.mdx | 14 ++++---- pages/use-cases/remote-ides.mdx | 18 +++++++--- pages/use-cases/serverless-databases.mdx | 43 ++++++++++++------------ 18 files changed, 128 insertions(+), 112 deletions(-) diff --git a/pages/faq.mdx b/pages/faq.mdx index d5926677..0c17363b 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -57,13 +57,13 @@ Yes, especially stemming from the fact that they have a minimal Trusted Computin Definitely. Every instance on Unikraft Cloud has a private IP and DNS name. You can plug instances together. -Follow this [guide](/docs/guides/features/idns/) for instructions. +Follow this [guide](/platform/services) for instructions. #### With an access token and an app, what should you do? You'll need a Dockerfile and Kraftfile. -See any of the apps/langs guides (here)[/docs/guides/] to see examples. +See any of the apps/langs guides [here](/guides/bun) to see examples. #### What's `kraft`? @@ -82,7 +82,7 @@ For observability, Unikraft ships a Prometheus library so a unikernel can export #### How's millisecond scale-to-zero achieved? -Magic πŸͺ„ +Magic πŸͺ„. Kidding, it's the combination of using Unikraft unikernels to run workloads and a custom node ingress controller. This controller can be reactive in milliseconds and scale to thousands of instances. Other optimizations to the underlying host also help. @@ -115,7 +115,7 @@ Stateful scale-to-zero in milliseconds anyone? #### What do you need to get started? [Sign up](https://console.unikraft.cloud/signup) to get an access token. -If you're interested in an enterprise solution please [write to us](/contact). +If you're interested in an enterprise solution please [write to us](https://unikraft.com/contact). #### What about usability? @@ -160,7 +160,7 @@ It's ready to run with hardware-level isolation and extreme efficiency. #### Are you a competing technology to WASM? No. -You can read more about [how Unikraft and WASM complement each other in our dedicated blog post on the matter](/blog/unikernels-and-wasm/). +You can read more about [how Unikraft and WASM complement each other in our dedicated blog post on the matter](https://unikraft.com/blog/unikernels-and-wasm/). In short, WASM provides language-level isolation, whereas Unikraft provides hardware-level. When you deploy WASM to the public cloud, there will be a VM underneath for isolation. Maybe even a container runtime. @@ -171,7 +171,7 @@ The VM (the unikernel) itself has only the minimal code needed to run the WASM r #### Can you deploy within hyperscaler infra and connect to their services with Unikraft Cloud? Yes. -Unikraft supports [metros](/docs/metros) / regions within existing hyperscaler infra, and also connectivity to their services. +Unikraft supports [metros](/platform/metros) (regions) within existing hyperscaler infra, and also connectivity to their services. For example, you could run an API server on Unikraft Cloud and connect to S3 as a storage back end. Contact information is available for more details. @@ -179,7 +179,7 @@ Contact information is available for more details. #### Can you try Unikraft open source first? Yes. -Head on over to [unikraft.org](http://www.unikraft.org/), install the `kraft` tool with the one-liner there, and use `kraft run` to build, package and run your app locally. +Head on over to [unikraft.org](https://unikraft.org/docs/cli/install), install the `kraft` tool with the one-liner there, and use `kraft run` to build, package and run your app locally. When you're ready to deploy to cloud, set your Unikraft Cloud token and deploy via `kraft cloud deploy`. @@ -201,9 +201,9 @@ Other unikernel projects exist, but most are research efforts, unmaintained, or #### Do you have a Kubernetes integration? -[Yes!](/docs/integrations/kubernetes/) +[Yes!](/integrations/kubernetes/) #### Do you have a Terraform integration? -[Yes!](/docs/integrations/terraform/) +[Yes!](https://github.com/unikraft-cloud/terraform-provider-ukc) diff --git a/pages/features/autoscale.mdx b/pages/features/autoscale.mdx index 8ce3ae55..bdcc7222 100644 --- a/pages/features/autoscale.mdx +++ b/pages/features/autoscale.mdx @@ -3,7 +3,7 @@ title: Autoscale navigation_icon: square-stack --- -Autoscaling is [load balancing](/docs/features/load-balancing) where the *number of instances* used to handle your traffic is automatically adapted to match the current traffic load. +Autoscaling is [load balancing](/features/load-balancing) where the *number of instances* used to handle your traffic is automatically adapted to match the current traffic load. On Unikraft Cloud, scale out (the process of adding instances to cope with increased load) happens in milliseconds. You can transparently and effortlessly handle load increase including traffic peaks. No more headaches due to slow autoscale like keeping hot instances around to deal with peaks, coming up with complex predictive algorithms, or other painful workarounds. @@ -12,7 +12,7 @@ You can set autoscale on and let Unikraft Cloud handle your traffic increases an ## The basics -As with [load balancing](/docs/features/load-balancing), autoscaling in Unikraft Cloud takes care of a *service*. +As with [load balancing](/features/load-balancing), autoscaling in Unikraft Cloud takes care of a *service*. Services allow you to load balance traffic for an Internet-facing service like a web server by creating many instances within the same service. While you can add or remove instances to a service to scale your service, doing this manually makes it hard to react to changes in traffic load. @@ -100,15 +100,14 @@ Note the following: :::note The intervals that autoscale uses for making scale-out and scale-in decisions use the `--warmup-time` and `--cooldown-time` parameters of `kraft cloud scale init`, in units of milliseconds. -Refer to the API autoscale [reference](/docs/api/v1/autoscale/#step) for more details. +Refer to the API autoscale [reference](/api/platform/v1/autoscale) for more details. ::: :::note Keep in mind that there are a few restrictions on how to define scale-in/scale-out steps. -The documentation is available [here](/docs/api/v1/autoscale/#step) at the bottom of the section. -General information about autoscale is available [here](/docs/api/v1/autoscale) +The documentation is available [here](/api/platform/v1/autoscale) at the bottom of the section. ::: @@ -199,5 +198,5 @@ watch --color -n 0.5 Unikraft Cloud instance list ## Learn more -* The `kraft cloud` [command-line tool reference](/docs/cli/), and in particular the [scale](/docs/cli/scale) subcommand. -* Unikraft Cloud's [REST API reference](/docs/api/v1), and in particular the section on [autoscale](/docs/api/v1/autoscale). +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [scale](/cli/scale) subcommand. +* Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the section on [autoscale](/api/platform/v1/autoscale). diff --git a/pages/features/load-balancing.mdx b/pages/features/load-balancing.mdx index d81468da..87b6c06a 100644 --- a/pages/features/load-balancing.mdx +++ b/pages/features/load-balancing.mdx @@ -3,7 +3,7 @@ title: Load Balancing navigation_icon: split --- -Load balancing in Unikraft Cloud is easy: as soon as you attach more than one instance to a [service](/docs/guides/features/service), Unikraft Cloud will automatically start balancing traffic between many instances. +Load balancing in Unikraft Cloud is easy: as soon as you attach more than one instance to a [service](/platform/services), Unikraft Cloud will automatically start balancing traffic between many instances. The load balancing happens based on the number of connections (in TCP mode) or requests (in HTTP mode). More on that below. @@ -11,15 +11,15 @@ Because of load balancing, instances in a service must be of the same kind (for You can remove instances from a service at any time, and, when you do, Unikraft Cloud will immediately take the instance out of the load balancing service. -## Soft-/hard-limits +## Soft and hard limits -[Services](/docs/platform/services) have soft and hard limits for the number of concurrent requests and connections. +[Services](/platform/services) have soft and hard limits for the number of concurrent requests and connections. The limits apply **per instance**. -For HTTP services (that is, using the `http` [handler](#handlers)) the system checks each individual in-flight request against the limit, but not the underlying TCP connection. +For HTTP services (that is, using the `http` [handler](/platform/services#handlers)) the system checks each individual in-flight request against the limit, but not the underlying TCP connection. For TCP services the individual open connections get counted. In the following, the term request refers to both requests and connections. -The load balancer uses the soft limit to decide when to wake up another [standby](/docs/api/v1/instances#states) instance. +The load balancer uses the soft limit to decide when to wake up another [standby](/platform/instances#instance-states) instance. For example, if you set the soft limit to 5 and the service consists of 2 standby instances, one of the instances receives up to 5 concurrent requests. The 6th parallel request wakes up the second instance. If there are no more standby instances to wake up, the number of requests assigned to each instance will exceed the soft limit. @@ -116,7 +116,7 @@ You're now load balancing across 2 NGINX instances! Currently it's impossible to set the service's name via `kraft cloud deploy`. If you'd like to set the service's name, first use the `kraft cloud service` command to create the service. -You can use the `--service` flag of `kraft cloud deploy` to attach the instance to the service, as outlined in this [guide](/docs/guides/features/service) +You can use the `--service` flag of `kraft cloud deploy` to attach the instance to the service, as outlined in this [guide](/platform/services). ::: @@ -129,7 +129,7 @@ If you want to ensure that no existing connections get dropped when stopping an ## Load balancing algorithm The load balancing algorithm is a variant of `least_conn`. -For every instance, the number of current in-flight TCP connections (if in `tcp` [mode](/docs/cli/service/create)) or requests (if in `http` [mode](/docs/cli/service/create)). +For every instance, the number of current in-flight TCP connections (if in `tcp` [mode](/platform/services#handlers)) or requests (if in `http` [mode](/platform/services#handlers)). To select an instance, the system goes over all instances in the service. It finds the set of instances that have the least amount of in-flight requests/connections, and picks from that set. @@ -150,5 +150,5 @@ This is because it would now be the only instance with only 1 connection (assumi ## Learn more -* The `kraft cloud` [command-line tool reference](/docs/cli/), and in particular the services subcommand. -* Unikraft Cloud's [REST API reference](/docs/api/v1), and in particular the section on services. +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the services subcommand. +* Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the section on services. diff --git a/pages/features/scale-to-zero.mdx b/pages/features/scale-to-zero.mdx index 013e2b98..98b03847 100644 --- a/pages/features/scale-to-zero.mdx +++ b/pages/features/scale-to-zero.mdx @@ -17,11 +17,11 @@ All within a negligible amount of time for Internet round-trip times and so unbe By default, Unikraft Cloud reduces network and cloud stack cold start time to a min time. Some apps take a while to initialize (for example, Spring Boot, Puppeteer, etc). If you need to deploy such an app and still want millisecond cold starts, Unikraft Cloud provides a *stateful* feature. -Please check out [this guide](/docs/guides/features/stateful/) for more information on how to set this up. +Please check out [this guide](/features/scale-to-zero#stateful-scale-to-zero) for more information on how to set this up. :::tip -If you add instances to a [service](/docs/guides/features/service), the service will load balance traffic across all them and Unikraft Cloud will ensure each instance gets woken up as needed. -This differs from [autoscale](/docs/guides/features/autoscale), in which you *don't* specify the number of instances. +If you add instances to a [service](/platform/services), the service will load balance traffic across all them and Unikraft Cloud will ensure each instance gets woken up as needed. +This differs from [autoscale](/features/autoscale), in which you *don't* specify the number of instances. The platform does this for you based on traffic load. ::: @@ -36,7 +36,7 @@ Unikraft Cloud currently supports the following scale-to-zero policies: |--------|-------------| | `off` | Scale-to-zero isn't enabled. The instance keeps on running until manually stopped. | | `on` | Enables scale-to-zero. When there are no TCP connections or HTTP requests during the cool-down time, the instance goes into standby. | -| `idle` | Same as `on`, but also puts the instance into standby when there are TCP connections established that have been inactive during the cool-down time. The connections remain established and incoming packets wake up the instance. Scale-to-zero doesn't happen while there are active HTTP requests (that is, traffic on ports, which use the `http` [handler](/docs/api/v1/services#handlers)). | +| `idle` | Same as `on`, but also puts the instance into standby when there are TCP connections established that have been inactive during the cool-down time. The connections remain established and incoming packets wake up the instance. Scale-to-zero doesn't happen while there are active HTTP requests (that is, traffic on ports, which use the `http` [handler](/platform/services#handlers)). | :::note Unikraft Cloud only considers network traffic that's going through its proxy to control scale-to-zero. @@ -71,7 +71,7 @@ To control scale-to-zero from within your app, instances on Unikraft Cloud provi |`/uk/libukp/scale_to_zero_disable` | Allows to temporarily disable scale-to-zero. | The `scale_to_zero_disable` pseudo file keeps track of the count of concurrent disable requests. -If the count is `0`, scale-to-zero remains active[^1]. +If the count is `0`, scale-to-zero remains active[^2]. Any number larger than `0` means scale-to-zero is temporarily inactive. Using a count instead of a boolean value helps many independent workers. Your app workers can disable scale-to-zero individually by incrementing and decrementing the count without having to synchronize. @@ -106,7 +106,7 @@ For example, to run just-in-time compilation and fill caches. Using stateful scale-to-zero can dramatically reduce the response time of your service. With stateful scale-to-zero Unikraft Cloud takes a snapshot of the instance state before putting it into standby. When incoming network traffic triggers a wake-up, the snapshot gets loaded. -The instance resumes execution where it left off - with caches already warm. +The instance resumes execution where it left offβ€”with caches already warm. Stateful scale-to-zero can also enable scale-to-zero for apps that need to keep state for functional correctness. This works even if cold boot times are no concern. @@ -244,16 +244,16 @@ nginx-1a747 twilight-gorilla-ui5b6kwt.fra.unikraft.app running You can use scale-to-zero *in conjunction with* autoscale. This ensures that as you scale back down, if traffic dies, your last instance gets removed. You're not charged for the service. -For more on autoscale please see the autoscale [guide](/docs/guides/features/autoscale) +For more on autoscale please see the autoscale [guide](/features/autoscale) ::: ## Learn more -* The `kraft cloud` [command-line tool reference](/docs/cli/), and in particular the services and scale subcommands -* Unikraft Cloud's [REST API reference](/docs/api/v1), and in particular the section [on scale-to-zero](/docs/api/v1/instances/#scaletozero). +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) and [instance create](/cli/instance/create) subcommands. +* Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the [scale-to-zero schema](/api/platform/v1/~schemas#instance-scale-to-zero). -[^1]: This is never the case for ports of your service that have the `http` handler set. -[^2]: If it's actually enabled depends on the instance configuration. +[^1]: This is never the case for ports of your service that have the `http` [handler](/platform/services#handlers) set. +[^2]: If it's actually enabled, depends on the instance configuration. diff --git a/pages/features/snapshots.mdx b/pages/features/snapshots.mdx index 706d37f1..233bbec0 100644 --- a/pages/features/snapshots.mdx +++ b/pages/features/snapshots.mdx @@ -4,7 +4,7 @@ navigation_icon: pause --- Unikraft Cloud supports the ability to deploy **stateful** apps. -These apps can keep state across different [scale-to-zero](/docs/guides/features/scaletozero) incarnations. +These apps can keep state across different [scale-to-zero](/features/scale-to-zero) incarnations. This mechanism also reduces app init time. Heavy-weight apps take a while to get started when cold started (for example, Spring Boot, Ruby on Rails, etc.). Taking a snapshot of the app memory and restoring it when the app starts again does this. @@ -26,7 +26,7 @@ labels: ``` You can see an example of such a `Kraftfile` and label in the [Spring Boot -example](/docs/guides/springboot). +example](/guides/springboot). Once deployed, you can check that this mechanism is actually enabled for your app via the `kraft cloud instance get ` command: @@ -52,5 +52,5 @@ but also eliminating any long initialization times from heavyweight apps. ## Learn More -* The `kraft cloud` [command-line tool reference](/docs/cli/), and in particular the `deploy` and `instance` subcommands. -* Unikraft Cloud's [REST API reference](/docs/api/v1), and in particular the section on [stateful scale-to-zero](/docs/api/v1/instances/#scaletozero_stateful). +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the `deploy` and `instance` subcommands. +* Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the [scale-to-zero schema](/api/platform/v1/~schemas#instance-scale-to-zero). diff --git a/pages/integrations/kubernetes.mdx b/pages/integrations/kubernetes.mdx index fecc9f37..7dbe909c 100644 --- a/pages/integrations/kubernetes.mdx +++ b/pages/integrations/kubernetes.mdx @@ -239,17 +239,17 @@ my-claim 8 minutes ago 10 MiB nginx-pod-nginx nginx-pod-nginx mounted true ## Notes -* [**Instances**](https://unikraft.cloud/docs/api/v1/instances/) +* [**Instances**](/platform/instances) For each Pod scheduled on Kraftlet, Kraftlet runs its containers as separate Unikraft Cloud instances rather than running them as containers. Kraftlet ensures it assigns instances to the correct Unikraft Cloud services and attaches them to the corresponding Unikraft Cloud volumes. -* [**Services**](https://unikraft.cloud/docs/api/v1/services/) +* [**Services**](/platform/services) When a Pod gets scheduled on the Kraftlet node, Kraftlet fetches the existing Kubernetes service that the given Pod is backing and **creates a corresponding Unikraft Cloud Service**. Kraftlet allows cluster admins to manage Unikraft Cloud Services by defining a Kubernetes service backed by Pods running on Kraftlet. -* [**Volumes**](https://unikraft.cloud/docs/api/v1/volumes/) +* [**Volumes**](/platform/volumes) Kraftlet listens for changes on [PersistentVolumeClaim objects](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) with storageClass `ukc-volume`. For each creation of such Persistent Volume Claim (PVC) object, the Kraftlet will create a corresponding Unikraft Cloud volume and a `PersistentVolume` object to bind the PVC object to. diff --git a/pages/introduction.mdx b/pages/introduction.mdx index 4c2d5c59..17156592 100644 --- a/pages/introduction.mdx +++ b/pages/introduction.mdx @@ -30,7 +30,7 @@ Expect higher server density, cost-savings, I/O performance boosts, active vCPU ``` - ```bash title="Shell" + ```bash title="zsh" brew install unikraft/cli/kraftkit ``` @@ -68,8 +68,7 @@ Expect higher server density, cost-savings, I/O performance boosts, active vCPU - See [alternative installation instructions](/docs/cli/install) for other - platforms. + See [alternative installation instructions](https://unikraft.org/docs/cli/install) for other platforms. 1. Login to your account by setting your access token (received via email): ```bash diff --git a/pages/platform/certificates.mdx b/pages/platform/certificates.mdx index 680ef001..0e14828d 100644 --- a/pages/platform/certificates.mdx +++ b/pages/platform/certificates.mdx @@ -62,6 +62,6 @@ kraft cloud cert rm mydomain.com-sa4x9 ## Learn more -* The `kraft cloud` [CLI reference](/docs/cli/) -* Unikraft Cloud's [REST API reference](/docs/api/v1) -* Many more guides [here](/docs/guides) +* The `kraft cloud` [CLI reference](/cli/) +* Unikraft Cloud's [REST API reference](/api/platform/v1) +* Many more guides [here](/guides/bun) diff --git a/pages/platform/domains.mdx b/pages/platform/domains.mdx index c1faee13..0bc54b13 100644 --- a/pages/platform/domains.mdx +++ b/pages/platform/domains.mdx @@ -37,7 +37,7 @@ You can find information about the Unikraft Cloud metros available to you, as we :::note You can have many domains for the same service. Unikraft Cloud also supports wildcard domains. -See the [certificates API](/docs/api/v1/certificates)) for details. +See the [certificates API](/api/platform/v1/certificates) for details. ::: ## Launching your app @@ -49,7 +49,7 @@ git clone https://github.com/unikraft-cloud/examples cd examples/nginx ``` -Log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ). Set the following: diff --git a/pages/platform/images.mdx b/pages/platform/images.mdx index 3a1389bf..3ebefb03 100644 --- a/pages/platform/images.mdx +++ b/pages/platform/images.mdx @@ -14,7 +14,7 @@ At a high level, you use `kraft` to build and push an image to the registry, and The simplest way to run this workflow is to use `kraft cloud deploy`, which combines all steps into one command. Internally, the deploy command calls other subcommands. The service in the diagram is the mechanism to connect apps to the Internet. -Read more in the [services guide](/docs/guides/features/service). +Read more in the [services guide](/platform/services). ## `Dockerfiles`, `Kraftfiles` and runtimes @@ -56,7 +56,7 @@ COPY ./server.py /src/server.py If you're familiar with `Dockerfiles` there is nothing unusual here, other than that by default Unikraft Cloud uses `FROM scratch` to keep images lean. To add your app's code to the build, change the `COPY` commands as needed. -All [guides](/docs/guides/) on Unikraft Cloud, and the [examples](https://github.com/unikraft-cloud/examples) they rely on underneath come with `Kraftfile`s and `Dockerfile`s for you to get started. +All [guides](/guides/bun) on Unikraft Cloud, and the [examples](https://github.com/unikraft-cloud/examples) they rely on underneath come with `Kraftfile`s and `Dockerfile`s for you to get started. :::tip You can also try a standard base image (for example, `FROM python:alpine`). @@ -66,16 +66,16 @@ This choice may increase image size, memory use, and boot time. ## Example workflows -This guide uses a Python [app](/docs/guides/python) as an example to show three workflows: +This guide uses a Python [app](/guides/python) as an example to show three workflows: 1. How to create an image and launch an instance from it. -1. How to create an image and launch many instances from it. -1. How to launch instances from an existing image. +2. How to create an image and launch many instances from it. +3. How to launch instances from an existing image. ### Create an image and an instance from it -Start with the simplest workflow: create an image from a Python app (following the Python app [guide](/docs/guides/python)) and start an instance from it with a single `kraft cloud deploy` command: +Start with the simplest workflow: create an image from a Python app (following the Python app [guide](/guides/python)) and start an instance from it with a single `kraft cloud deploy` command: ```bash title="" git clone https://github.com/unikraft-cloud/examples @@ -187,5 +187,5 @@ You now have a new instance created from the existing image. ## Learn more -* The `kraft cloud` [CLI reference](/docs/cli/) -* Unikraft Cloud's [REST API reference](/docs/api/v1) +* The `kraft cloud` [CLI reference](/cli/) +* Unikraft Cloud's [REST API reference](/api/platform/v1) diff --git a/pages/platform/instances.mdx b/pages/platform/instances.mdx index b63f6fea..60dfd3a9 100644 --- a/pages/platform/instances.mdx +++ b/pages/platform/instances.mdx @@ -41,7 +41,7 @@ For example, the `stop_reason` has the following values in these scenarios: | `28` | `11100`/`FUP--` | Forced user-initiated shutdown. | | `15` | `01111`/`-UPAK` | Regular user-initiated shutdown. The app and kernel have exited. The `exit_code` and `stop_code` show if the app and kernel shut down cleanly. | | `13` | `01101`/`-UP-K` | The user initiated a shutdown but the app was forcefully killed by the kernel during shutdown. This can be the case if the image doesn't support a clean app exit or the app crashed after receiving a termination signal. Unikraft Cloud ignores the `exit_code` in this scenario. | -| `7` | `00111`/`--PAK` | Unikraft Cloud initiated the shutdown (for example, due to [scale-to-zero](/docs/api/v1/autoscale#scaletozero)). The app and kernel have exited. The `exit_code` and `stop_code` show if the app and kernel shut down cleanly. | +| `7` | `00111`/`--PAK` | Unikraft Cloud initiated the shutdown (for example, due to [scale-to-zero](/features/scale-to-zero)). The app and kernel have exited. The `exit_code` and `stop_code` show if the app and kernel shut down cleanly. | | `3` | `00011`/`---AK` | The app exited. The `exit_code` and `stop_code` show if the app and kernel shut down cleanly. | | `1` | `00001`/`----K` | The instance likely experienced a fatal crash and the `stop_code` contains more information about the cause of the crash. | | `0` | `00000`/`-----` | The stop reason is unknown. | diff --git a/pages/platform/services.mdx b/pages/platform/services.mdx index 908a6e14..28a1e2b1 100644 --- a/pages/platform/services.mdx +++ b/pages/platform/services.mdx @@ -10,7 +10,7 @@ It connects them to the Internet through a *service*: create a service and attac A service defines how to reach a group of instances from the outside world. It maps an external FQDN port to an internal port common to all instances. -The platform [load balances](/docs/guides/features/lb/) incoming connections across instances. +The platform [load balances](/features/load-balancing) incoming connections across instances. Avoid placing apps that expose different ports in the same service. ::: @@ -35,7 +35,7 @@ Unikraft Cloud terminates TLS and sends HTTP to port 8080. This example assumes that the app opens port 8080. Now use `kraft cloud deploy` with the `--service` flag to attach the instance to the `my-service` service. -For example, from the [Go web server guide](/docs/guides/go) (see all guides [here](/docs/guides/)): +For example, from the [Go web server guide](/guides/go): ```bash title="" git clone https://github.com/unikraft-cloud/examples @@ -93,5 +93,5 @@ kraft cloud service remove my-service ## Learn more -* The `kraft cloud` [CLI reference](/docs/cli/), in particular the services subcommand -* Unikraft Cloud's [REST API reference](/docs/api/v1), in particular the section on services +* The `kraft cloud` [CLI reference](/cli/), in particular the [service](/cli/service) subcommand +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [service groups](/api/platform/v1/service-groups) diff --git a/pages/platform/troubleshooting.mdx b/pages/platform/troubleshooting.mdx index 60c44394..18296a41 100644 --- a/pages/platform/troubleshooting.mdx +++ b/pages/platform/troubleshooting.mdx @@ -72,7 +72,7 @@ There is no service on this URL. ``` This happens when you connect with an HTTPS client (port `443`) and the app doesn't expose that port. -Database services such as [MongoDB](/docs/guides/mongodb) or [MariaDB](/docs/guides/mariadb) use different ports (for example, `27017`, `3306`). +Database services such as [MongoDB](/guides/mongodb) or [MariaDB](/guides/mariadb) use different ports (for example, `27017`, `3306`). Use the correct exposed port. You may need a TLS tunnel (see below). @@ -81,9 +81,9 @@ You may need a TLS tunnel (see below). ## Connect to a non-TLS app Unikraft Cloud uses TLS to expose services to the outside world. -Some apps (such as [MongoDB](/docs/guides/mongodb) or [MariaDB](/docs/guides/mariadb)) don't use TLS. +Some apps (such as [MongoDB](/guides/mongodb) or [MariaDB](/guides/mariadb)) don't use TLS. Create a TLS tunnel via `kraft cloud tunnel`, which opens a local endpoint (`localhost` / `127.0.0.1`) and forwards traffic over TLS. -See the [MariaDB guide](/docs/guides/mariadb) for an example. +See the [MariaDB guide](/guides/mariadb) for an example. ## "No such file or directory" when building or deploying an image @@ -350,13 +350,13 @@ Contact Unikraft Cloud on the [Discord server](/discord) and include this output While you debug an issue you can mitigate crashes by setting a restart policy. For example, use `kraft cloud deploy --restart on-failure` to have the platform restart the app if it crashes. -Find more info on [restart policies here](/docs/api/v1/instances/#restart-policy). +Find more info on [restart policies here](/cli/deploy#options). ::: ## Learn more -* The `kraft cloud` [CLI reference](/docs/cli/) -* Unikraft Cloud's [REST API reference](/docs/api/v1) -* Many more guides [here](/docs/guides) +* The `kraft cloud` [CLI reference](/cli/) +* Unikraft Cloud's [REST API reference](/api/platform/v1) +* Many more guides [here](/guides/bun) diff --git a/pages/platform/volumes.mdx b/pages/platform/volumes.mdx index 00f6ba94..8e52294f 100644 --- a/pages/platform/volumes.mdx +++ b/pages/platform/volumes.mdx @@ -111,7 +111,7 @@ On every request, this simple server will write a timestamp to a file on the mounted persistent volume and print out the current contents of the file. Start the Flask web server, create a -[service](/docs/platform/services) for it via the `-p` flag, and mount the `my-volume` volume at `/mnt`: +[service](/platform/services) for it via the `-p` flag, and mount the `my-volume` volume at `/mnt`: ```bash title="" kraft cloud deploy -M 512 -p 443:8080 --volume my-volume:/mnt . @@ -226,5 +226,5 @@ kraft cloud volume remove ## Learn more -* The `kraft cloud` [CLI reference](/docs/cli/), in particular the [deploy](/docs/cli/deploy) and [volumes](/docs/cli/volume) subcommands -* Unikraft Cloud's [REST API reference](/docs/api/v1), in particular the section on [volumes](/docs/api/v1/volumes) +* The `kraft cloud` [CLI reference](/cli/), in particular the [deploy](/cli/deploy) and [volume](/cli/volume) subcommands +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [volumes](/api/platform/v1/volumes) diff --git a/pages/use-cases/api-gateways.mdx b/pages/use-cases/api-gateways.mdx index d82d8f40..dfd6afff 100644 --- a/pages/use-cases/api-gateways.mdx +++ b/pages/use-cases/api-gateways.mdx @@ -59,16 +59,16 @@ It offers open standards, scalability, governance, and AI-ready features for API To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine (for example, Docker). +1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, Docker). -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/tyk/` directory: +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/tyk/` directory: ```bash title="" -git clone https://github.com/kraftcloud/examples +git clone https://github.com/unikraft-cloud/examples cd examples/tyk/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): ```bash title="" @@ -88,7 +88,7 @@ After deploying, you can query the service using the provided address. Use the `/hello` path after the address, such as below: ```bash title="" -curl https://..kraft.host/hello | jq +curl https:///hello | jq ``` ```json title="" { @@ -105,3 +105,12 @@ curl https://..kraft.host/hello | jq } ``` +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + +```bash +kraft cloud --help +``` + +Or visit the [CLI Reference](/cli). diff --git a/pages/use-cases/headless-browsers.mdx b/pages/use-cases/headless-browsers.mdx index e54e8f9e..45f5d84a 100644 --- a/pages/use-cases/headless-browsers.mdx +++ b/pages/use-cases/headless-browsers.mdx @@ -16,7 +16,7 @@ They're resource-intensive, security-sensitive, and often run in short burstsβ€” Instances on Unikraft Cloud boot in microseconds, so browsers spin up only when needed: * Perfect for on-demand scraping and CI/CD testing. -* No idle costs when browsers aren’t running. +* No idle costs when browsers aren't running. ### πŸ”’ Strong security @@ -52,16 +52,16 @@ option to run them headless (no UI). To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine (for example, Docker). +1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, Docker). -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node-express-puppeteer/` directory: +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node-express-puppeteer/` directory: ```bash -git clone https://github.com/kraftcloud/examples +git clone https://github.com/unikraft-cloud/examples cd examples/node-express-puppeteer/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): ```bash @@ -107,7 +107,7 @@ They're different for each run. Use a browser to access the landing page of the Puppeteer (that uses [ExpressJS](https://expressjs.com/)). The app and the landing page are part of [this repository](https://github.com/christopher-talke/node-express-puppeteer-pdf-example). -In the example run above, the landing page is at the address https://nameless-fog-0tvh1uov.fra.unikraft.app +In the example run above, the landing page is at the address `https://nameless-fog-0tvh1uov.fra.unikraft.app`. You can use the landing page to generate the PDF version of a remote page. At any time, you can list information about the instance: @@ -141,4 +141,4 @@ Use the `--help` option for detailed information on using Unikraft Cloud: kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). +Or visit the [CLI Reference](/cli). diff --git a/pages/use-cases/remote-ides.mdx b/pages/use-cases/remote-ides.mdx index ae1fb757..6b710d59 100644 --- a/pages/use-cases/remote-ides.mdx +++ b/pages/use-cases/remote-ides.mdx @@ -48,16 +48,16 @@ When not in use, the instance will [scale-to-zero](/docs/features/scale-to-zero) To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine (for example, Docker). +1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, Docker). -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/code-server/` directory: +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/code-server/` directory: ```bash -git clone https://github.com/kraftcloud/examples +git clone https://github.com/unikraft-cloud/examples cd examples/code-server/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): ```bash @@ -101,3 +101,13 @@ To remove the volume, you can use: ```bash kraft cloud volume rm code-workspace ``` + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + +```bash +kraft cloud --help +``` + +Or visit the [CLI Reference](/cli). diff --git a/pages/use-cases/serverless-databases.mdx b/pages/use-cases/serverless-databases.mdx index a368b225..f46a4009 100644 --- a/pages/use-cases/serverless-databases.mdx +++ b/pages/use-cases/serverless-databases.mdx @@ -6,7 +6,7 @@ navigation_icon: database-zap import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" Databases are central to modern apps, but they're notoriously resource-hungry, slow to scale, and costly to operate at low utilisation. -Traditional VM- or container-based solutions keep idle resources running, resulting in waste and inefficiency. +Traditional VM or container-based solutions keep idle resources running, resulting in waste and inefficiency. With **Unikraft Cloud**, serverless databases gain the advantages of **unikernels**, combining **extreme performance** with **true scale-to-zero efficiency**. ## Why run serverless databases on Unikraft Cloud @@ -18,7 +18,7 @@ This ensures the system uses resources **only when needed**, without cold-start ### πŸ”’ Stronger security by design -Each database instance runs as a **specialised, single-process unikernel**, drastically reducing the attack surface compared to general-purpose OSes. +Each database instance runs as a **specialised, single-process unikernel**, drastically reducing the attack surface compared to general-purpose operating systems. This isolation protects customer data with **built-in, lightweight security**. ### πŸ’° Cost-efficient scale-to-zero @@ -40,22 +40,22 @@ These instances optimise both Online Transaction Processing (OLTP) and Online An ## Getting started This guide shows you how to use [PostgreSQL](https://www.postgresql.org/), a powerful, open source object-relational database system, in a serverless fashion. -With Unikraft Cloud, you can run PostgreSQL in a lightweight virtual machine, with minimal overhead and millisecond fast startup times. -The instance will [scale-to-zero](/docs/features/scale-to-zero) when not in use. +With Unikraft Cloud, you can run PostgreSQL in a lightweight virtual machine, with minimal overhead and millisecond-fast startup times. +The instance will [scale-to-zero](/features/scale-to-zero) when not in use. To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine (for example, Docker). +1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, Docker). -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/postgres/` directory: ```bash -git clone https://github.com/kraftcloud/examples +git clone https://github.com/unikraft-cloud/examples cd examples/postgres/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): ```bash @@ -75,12 +75,12 @@ kraft cloud deploy -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -M 1024 . The output shows the instance address and other details: ```ansi -[90m[[0m[92m●[0m[90m][0m Deployed successfully! - [90mβ”‚[0m - [90mβ”œ[0m[90m──────────[0m [90mname[0m: postgres-saan9 - [90mβ”œ[0m[90m──────────[0m [90muuid[0m: 3a1371f2-68c6-4187-84f8-c080f2b028ca - [90mβ”œ[0m[90m─────────[0m [90mstate[0m: [92mstarting[0m - [90mβ”œ[0m[90m──────────[0m [90mfqdn[0m: young-thunder-fbafrsxj.fra.unikraft.app +[●] Deployed successfully! + β”‚ + β”œ────────── name: postgres-saan9 + β”œ────────── uuid: 3a1371f2-68c6-4187-84f8-c080f2b028ca + β”œ───────── state: starting + β”œ────────── fqdn: young-thunder-fbafrsxj.fra.unikraft.app β”œ───────── image: postgres@sha256:2476c0373d663d7604def7c35ffcb4ed4de8ab231309b4f20104b84f31570766 β”œ──────── memory: 1024 MiB β”œ─────── service: young-thunder-fbafrsxj @@ -92,7 +92,7 @@ The output shows the instance address and other details: In this case, the instance name is `postgres-saan9` and the service `young-thunder-fbafrsxj`. They're different for each run. -If you use port 5432/tls according to the example above you can now directly connect to postgres: +If you use port `5432/tls`, according to the example above, you can now directly connect to postgres: ```console psql -U postgres -h young-thunder-fbafrsxj.fra.unikraft.app @@ -114,19 +114,18 @@ postgres=# Use SQL and `psql` commands for your work. :::tip[Idle scale-to-zero] -This example uses the [`idle` scale-to-zero policy](/docs/api/v1/instances#scaletozero_policy) by default (see the `labels` section in the `Kraftfile`). +This example uses the [`idle` scale-to-zero policy](/features/scale-to-zero) by default (see the `labels` section in the `Kraftfile`). This means that the instance will use scale-to-zero even in the presence of `psql` connections. The PostgreSQL example makes use of scale-to-zero app support. This ensures that the instance isn't put into standby even for long running queries (during which the connections are also idle). -To this end, the [`pg_ukc_scaletozero`](https://github.com/kraftcloud/pg_ukc_scaletozero) module is loaded into Postgres. +To this end, the [`pg_ukc_scaletozero`](https://github.com/unikraft-cloud/pg_ukc_scaletozero) module is loaded into Postgres. This module suspends scale-to-zero during query processing. You can see this in action by running `SELECT pg_sleep(10);` and verifying that the instance keeps on running. ::: :::note -If you'd like to use a port other than `5432/tls` you'll need to use the `kraft cloud tunnel` command to connect to Postgres. -See [the tunneling guide](/docs/guides/features/tunnel) for more information. +If you'd like to use a port other than `5432/tls`, you'll need to use the [`kraft cloud tunnel`](/cli/tunnel) command to connect to Postgres. You need to explicitly disable scale-to-zero. You can do this by either changing the label in the `Kraftfile` or by using `--scale-to-zero off` in the deploy command. @@ -151,7 +150,7 @@ kraft cloud instance remove postgres-saan9 ### Using volumes -You can use [volumes](/docs/guides/features/volumes) for data persistence for your PostgreSQL instance. +You can use [volumes](/platform/volumes) for data persistence for your PostgreSQL instance. For that you would first create a volume: @@ -175,7 +174,7 @@ For that you use a different `POSTGRES_PASSWORD` environment variable when start You could also use a different location to mount your volume or set more configuration options. -And, you can use the PostgreSQL instance in conjunction with a frontend service, [see the guide here](/docs/guides/features/idns). +And, you can use the PostgreSQL instance in conjunction with a frontend service, [see the guide here](/platform/services). But, in that case make sure to disable scale-to-zero if you plan to use the DB internally. :::note @@ -193,4 +192,4 @@ Use the `--help` option for detailed information on using Unikraft Cloud: kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). +Or visit the [CLI Reference](/cli). From e50ff0db610ebe9a759041708cc220af5f01a07b Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Mon, 10 Nov 2025 14:27:00 +0200 Subject: [PATCH 002/131] feat(services): Add section about port handlers Signed-off-by: Alex-Andrei Cioc --- pages/platform/services.mdx | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/pages/platform/services.mdx b/pages/platform/services.mdx index 28a1e2b1..02057b8a 100644 --- a/pages/platform/services.mdx +++ b/pages/platform/services.mdx @@ -3,6 +3,8 @@ title: Services navigation_icon: group --- +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + On creation, Unikraft Cloud assigns each instance a private IP address and private FQDN for internal connectivity. It connects them to the Internet through a *service*: create a service and attach instances to it. @@ -91,6 +93,52 @@ In the end, if you want to remove a service, use: kraft cloud service remove my-service ``` +## Handlers + +Handlers define how the service will handle incoming connections and forward traffic from the Internet to your app. +For example, you can configure a service to terminate TLS connections, redirect HTTP traffic, or enable HTTP mode for load balancing. +You configure the handlers for every published service port individually. + +Currently, there are 3 supported handlers: + + + + tls + http + redirect + + + Terminate the TLS connection at the Unikraft Cloud gateway using the wildcard certificate issued for the `unikraft.cloud` domain. + The gateway forwards the unencrypted traffic to your app. + + + Enable HTTP mode on the load balancer to load balance on the level of individual HTTP requests. + In this mode, only HTTP connections are accepted. + If this option is not set, the load balancer works in TCP mode and distributes TCP connections. + + + Redirect traffic from the source port to the destination port. + + + +:::note +The following set of constraints apply when publishing ports: +- Port 80: **must** have `http` and **must not** have `tls` set. +- Port 443: **must** have `http` and `tls` set. +- The `redirect` handler can only be set on port 80 (HTTP) to redirect to + port 443 (HTTPS). +- All other ports **must** have `tls` and **must not** have `http` set. +::: + +For example, the following creates the service `my-service` with three published ports: +- Port 443 with both `http` and `tls` handlers (HTTP mode). +- Port 80 with the `http` and `redirect` handlers (HTTP mode). +- Port 10000 with only the `tls` handler (TCP mode). + +```bash title="" +kraft cloud service create --name my-service 443:8080/http+tls 80:8080/http+redirect 10000:10000/tls +``` + ## Learn more * The `kraft cloud` [CLI reference](/cli/), in particular the [service](/cli/service) subcommand From b332129b95f542cc5397b521446869675e85c00d Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Mon, 3 Nov 2025 18:52:36 +0200 Subject: [PATCH 003/131] fix(guides/ferretdb): Fix urls Signed-off-by: Alex-Andrei Cioc --- pages/guides/ferretdb.mdx | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/pages/guides/ferretdb.mdx b/pages/guides/ferretdb.mdx index ef156162..5a32f58a 100644 --- a/pages/guides/ferretdb.mdx +++ b/pages/guides/ferretdb.mdx @@ -8,17 +8,17 @@ This guide shows you how to use [FerretDB](https://www.ferretdb.com/) an open so To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/cli/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples). +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples). ```bash - git clone https://github.com/kraftcloud/examples + git clone https://github.com/unikraft-cloud/examples ``` This guide uses both the `postgres16.2/` example and the `ferretdb/` example. -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): ```bash @@ -28,7 +28,7 @@ export UKC_TOKEN=token export UKC_METRO=fra ``` -This guide deploys FerretDB as a frontend and PostgreSQL as a database server, running them together inside a [service](/docs/guides/features/idns). +This guide deploys FerretDB as a frontend and PostgreSQL as a database server, running them together inside a [service](/platform/services). For that, follow these steps: 1. Run an instance of PostgreSQL using the `postgres16.2/` example: @@ -46,19 +46,19 @@ For that, follow these steps: ``` ```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: ferretdb-rdj6z - β”œ────────── uuid: 0b18a36d-9d43-4907-833d-7242f0e75f78 - β”œ───────── state: running - β”œ────────── fqdn: restless-resonance-jcc4ulc3.fra.unikraft.app - β”œ───────── image: ferretdb@sha256:27c59539fa3b6b7d2948ee4ceb2ceb75309328a9055a394bf949bede96aa7e27 - β”œ───── boot time: 37.11 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: restless-resonance-jcc4ulc3 - β”œ── private fqdn: ferretdb-rdj6z.internal - β”œ──── private ip: 172.16.3.5 - β””────────── args: /usr/bin/ferretdb +[●] Deployed successfully! + β”‚ + β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ name: ferretdb-rdj6z + β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ uuid: 0b18a36d-9d43-4907-833d-7242f0e75f78 + β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€ state: running + β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ fqdn: restless-resonance-jcc4ulc3.fra.unikraft.app + β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€ image: ferretdb@sha256:27c59539fa3b6b7d2948ee4ceb2ceb75309328a9055a394bf949bede96aa7e27 + β”œβ”€β”€β”€β”€β”€ boot time: 37.11 ms + β”œβ”€β”€β”€β”€β”€β”€β”€β”€ memory: 512 MiB + β”œβ”€β”€β”€β”€β”€β”€β”€ service: restless-resonance-jcc4ulc3 + β”œβ”€β”€ private fqdn: ferretdb-rdj6z.internal + β”œβ”€β”€β”€β”€ private ip: 172.16.3.5 + └────────── args: /usr/bin/ferretdb ``` In this case, the instance name is `ferretdb-rdj6z` which is different for each run. @@ -126,7 +126,7 @@ kraft cloud instance remove postgres ## Customize your deployment -One example customization is to use [volumes](/docs/guides/features/volumes) with PostgreSQL for persistence. +One example customization is to use [volumes](/platform/volumes) with PostgreSQL for persistence. For that, you would first create a volume: ```bash @@ -147,4 +147,4 @@ Use the `--help` option for detailed information on using Unikraft Cloud: kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). +Or visit the [CLI Reference](/cli). From bc22a38eaf21cf0021ab658ad255150d36fa3460 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Mon, 8 Dec 2025 12:03:53 +0200 Subject: [PATCH 004/131] chore(use-cases): Add links to Docker install page Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/api-gateways.mdx | 2 +- pages/use-cases/headless-browsers.mdx | 2 +- pages/use-cases/remote-ides.mdx | 2 +- pages/use-cases/serverless-databases.mdx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pages/use-cases/api-gateways.mdx b/pages/use-cases/api-gateways.mdx index dfd6afff..d252b231 100644 --- a/pages/use-cases/api-gateways.mdx +++ b/pages/use-cases/api-gateways.mdx @@ -59,7 +59,7 @@ It offers open standards, scalability, governance, and AI-ready features for API To run it, follow these steps: -1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, Docker). +1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)). 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/tyk/` directory: diff --git a/pages/use-cases/headless-browsers.mdx b/pages/use-cases/headless-browsers.mdx index 45f5d84a..245c9246 100644 --- a/pages/use-cases/headless-browsers.mdx +++ b/pages/use-cases/headless-browsers.mdx @@ -52,7 +52,7 @@ option to run them headless (no UI). To run it, follow these steps: -1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, Docker). +1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)). 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node-express-puppeteer/` directory: diff --git a/pages/use-cases/remote-ides.mdx b/pages/use-cases/remote-ides.mdx index 6b710d59..f3db168f 100644 --- a/pages/use-cases/remote-ides.mdx +++ b/pages/use-cases/remote-ides.mdx @@ -48,7 +48,7 @@ When not in use, the instance will [scale-to-zero](/docs/features/scale-to-zero) To run it, follow these steps: -1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, Docker). +1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)). 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/code-server/` directory: diff --git a/pages/use-cases/serverless-databases.mdx b/pages/use-cases/serverless-databases.mdx index f46a4009..929c979d 100644 --- a/pages/use-cases/serverless-databases.mdx +++ b/pages/use-cases/serverless-databases.mdx @@ -45,7 +45,7 @@ The instance will [scale-to-zero](/features/scale-to-zero) when not in use. To run it, follow these steps: -1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, Docker). +1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)). 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/postgres/` directory: From 3716fd614f7ae419d09c8cd5b6d85c82dfa74e10 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Fri, 21 Nov 2025 22:39:05 +0200 Subject: [PATCH 005/131] feat(use-cases): Add 2 MCP servers use cases Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/mcp-servers.mdx | 199 ++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 pages/use-cases/mcp-servers.mdx diff --git a/pages/use-cases/mcp-servers.mdx b/pages/use-cases/mcp-servers.mdx new file mode 100644 index 00000000..dd9db89a --- /dev/null +++ b/pages/use-cases/mcp-servers.mdx @@ -0,0 +1,199 @@ +--- +title: MCP Servers +navigation_icon: plug +--- + +[MCP (Model Context Protocol)](https://modelcontextprotocol.io/docs/getting-started/intro) servers enable AI assistants and LLMs to access external tools, data sources, and capabilities in a standardized way. +They act as bridges between AI models and real-world resourcesβ€”file systems, databases, APIs, search engines, and custom business logic. +As AI assistants become more capable, MCP servers are becoming critical infrastructure for grounding AI in reality. + +With **Unikraft Cloud**, you are enhancing your MCP servers with instant deployment, scale-to-zero economics, and millisecond-level cold startsβ€”perfect for the on-demand nature of AI interactions. + +## Why run MCP servers on Unikraft Cloud + +### ⚑ Zero-latency context injection + +AI assistants need instant access to tools and data. +Every millisecond of latency impacts the user experience. +Unikraft Cloud's unikernel architecture reduces OS overhead: + +* Sub-millisecond cold starts mean MCP servers are ready instantly. +* Minimal memory footprint allows dense packing of specialized servers. + +### πŸ”’ Isolated execution + +MCP servers often access sensitive dataβ€”file systems, databases, proprietary APIs. +Unikraft Cloud provides VM-level isolation for each server instance: + +* Strong isolation prevents cross-contamination between different MCP contexts. +* Immutable unikernel images mitigate runtime tampering risks. +* Minimal attack surface with only essential components included. + +### πŸ’Έ Pay-per-query economics + +AI interactions are inherently burstyβ€”periods of intense activity followed by silence. +Traditional server architectures waste resources during idle periods. +With Unikraft Cloud: + +* MCP servers scale-to-zero when not in use, costing nothing. +* Instant wake-up ensures your queries have no noticeable delay. +* Fine-grained billing means you only pay for actual AI interactions. + +### 🌍 Edge-ready deployment + +Unikraft Cloud help you reduce the latency of your applications: + +* Choose to deploy to your closest [metro](/platform/metros). +* Lightweight footprint enables cost-effective multi-region deployment. +* Fast startup times ensure consistent performance across all locations. + +## Getting started + +MCP servers on Unikraft Cloud provide the perfect runtime for AI tool integration, being fast, secure, and cost-efficient. +Scale-to-zero economics meet instant availability, ensuring your AI assistants always have the tools they need, exactly when they need them. + +This guide shows you how to deploy two types of MCP servers: + +### Example 1: ArXiv MCP server + +The [arXiv MCP Server](https://github.com/blazickjp/arxiv-mcp-server) is a community-made MCP server that connects AI tools directly to the [arXiv](https://arxiv.org/) archive of scientific articles and publications. +It allows MCP clients to browse and analyze papers. + +To run an example based on it, follow these steps: + +1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)). + +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/mcp-server-arxiv/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/mcp-server-arxiv/ +``` + +Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + +```bash +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + +Follow the instructions in the example's README to set it up and grab the server's FQDN. + +You can use the included example client to test the server, or connect to it using your favourite MCP client. +For example, using [Visual Studio Code](https://code.visualstudio.com/docs/copilot/customization/mcp-servers#_add-an-mcp-server), you can add the following to your `.vscode/mcp.json` file: + +```json +{ + "servers": { + "arxiv-mcp": { + "type": "http", + "url": "https:///mcp" + } + } +} +``` + +The tool will then show up in Copilot Chat. +You can find similar instructions for [Claude Code](https://code.claude.com/docs/en/mcp#option-1:-add-a-remote-http-server) and other MCP-compatible clients. + +Example query that will trigger a tool call: + +> **Q:** *Could you download the original Unikraft paper for me?* +> +> **A:** The original Unikraft paper (β€œUnikraft: Fast, Specialized Unikernels the Easy Way”) is being downloaded and converted. I will notify you as soon as it is ready for reading or further actions. + +> **Q:** *Dump the whole first section of the paper here.* +> +> **A:** Here is the full first section (β€œIntroduction”) from the Unikraft paper: +> +> **1 Introduction** +> +> Specialization is arguably the most effective way to achieve outstanding performance, whether it is for achieving high throughput in network-bound applications, making language runtime environments more efficient, or providing efficient container environments, to give some examples. +> Even in the hardware domain, and especially with the demise of Moore’s law, manufacturers are increasingly leaning towards hardware specialization to achieve ever better performance; the machine learning field is a primary exponent of this. +> ... + +### Example 2: Custom MCP server + +This example demonstrates how to build a minimal custom MCP server from scratch. +It provides weather information and time utilitiesβ€”showing the core patterns for building your own MCP tools. + +To run it, follow these steps: + +1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)). + +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/mcp-server-simple/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/mcp-server-simple/ +``` + +Make sure to set your Unikraft Cloud token and metro: + +```bash +export UKC_TOKEN=token +export UKC_METRO=fra +``` + +Follow the instructions in the example's README to set it up and grab the server's FQDN. + +You can use the included example client to test the server, or connect to it using your favourite MCP client. +For example, using [Visual Studio Code](https://code.visualstudio.com/docs/copilot/customization/mcp-servers#_add-an-mcp-server), you can add the following to your `.vscode/mcp.json` file: + +```json +{ + "servers": { + "custom-mcp": { + "type": "http", + "url": "https:///mcp" + } + } +} +``` + +The tool will then show up in Copilot Chat. +You can find similar instructions for [Claude Code](https://code.claude.com/docs/en/mcp#option-1:-add-a-remote-http-server) and other MCP-compatible clients. + +Example query that will trigger a tool call: + +> **Q**: What is the current weather in Paris, and what time is it there? +> +> **A**: The current weather in Paris is 21Β°C, partly cloudy, with 62% humidity. +> The local time in Paris is 23:21 (11:21 PM), Tuesday, December 2, 2025 (UTC+1). + +## Building your own MCP server + +MCP servers follow a simple pattern: + +1. **Define tools**: Specify what capabilities your server provides (functions, APIs, data sources). +1. **Handle requests**: Process MCP protocol requests from AI assistants. +1. **Return results**: Format responses in the MCP protocol format. + +Common use cases for custom MCP servers: + +* **Database access**: Query internal databases, data warehouses, or analytics platforms. +* **API integration**: Connect AI assistants to third-party services (CRM, ticketing, monitoring). +* **Custom business logic**: Integrate company-specific calculations, validations, or workflows. +* **Document retrieval**: Search and retrieve from internal knowledge bases or document stores. + +Unikraft Cloud's instant deployment and scale-to-zero model makes it ideal for hosting dozens of specialized MCP servers. + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + +```bash +kraft cloud --help +``` + +Or visit the [CLI Reference](/cli). + +For more information about the Model Context Protocol: + +- [MCP Documentation](https://modelcontextprotocol.io/) +- [Reference MCP Servers](https://github.com/modelcontextprotocol/servers) +- [Building MCP Servers](https://modelcontextprotocol.io/docs/develop/build-server) +- [Building MCP Clients](https://modelcontextprotocol.io/docs/develop/build-client) From 3bf2de75f1c4ff65c2a3ef390d92d22a3610ee1f Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Wed, 17 Dec 2025 21:03:02 +0200 Subject: [PATCH 006/131] feat(use-cases): Add GitHub webhook use case Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/webhooks.mdx | 107 +++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 pages/use-cases/webhooks.mdx diff --git a/pages/use-cases/webhooks.mdx b/pages/use-cases/webhooks.mdx new file mode 100644 index 00000000..1298f3dc --- /dev/null +++ b/pages/use-cases/webhooks.mdx @@ -0,0 +1,107 @@ +--- +title: Webhooks +navigation_icon: plug +--- + +Webhooks, also known as reverse APIs, enable real-time, event-driven communication between services. +Instead of constantly polling for updates, webhooks allow services to push data to your app the moment something happensβ€”a commit is pushed, a payment is processed, or an issue is created. +This makes webhooks essential for building reactive, event-driven architectures. + +With **Unikraft Cloud**, you can deploy webhook receivers that combine instant availability with scale-to-zero economicsβ€”paying only when events arrive, while maintaining millisecond-level response times. + +## Why run webhook receivers on Unikraft Cloud + +### ⚑ Instant wake-up for bursty events + +Webhooks are inherently sporadicβ€”events can arrive in bursts or be silent for hours. +Traditional servers waste resources running every day, waiting for events. +Unikraft Cloud's unikernel architecture provides: + +* Single-digit-millisecond cold starts ensure instant response when events arrive. +* No noticeable delay for webhook senders, maintaining reliable integrations. +* Minimal memory footprint allows running many specialized webhook receivers. + +### πŸ”’ Isolated and secure + +Webhook receivers often process sensitive data from external services. +Unikraft Cloud provides VM-level isolation for each instance: + +* Strong isolation prevents cross-contamination between different webhook handlers. +* Immutable unikernel images reduce the attack surface. +* Built-in HTTPS endpoints with automatic TLS certificate management. + +### πŸ’Έ Pay only for events + +Why pay for idle servers when webhooks only fire occasionally? +With Unikraft Cloud: + +* Webhook receivers scale-to-zero when not processing events, costing nothing. +* Instant wake-up ensures events are processed immediately upon arrival. +* Fine-grained billing means you only pay for actual event processing. + + +## Getting started + +This guide shows you how to deploy a GitHub webhook receiver that listens for repository events. +The example uses Node.js with Express and the official [Octokit webhooks library](https://www.npmjs.com/package/@octokit/webhooks). +To run it, follow these steps: + +1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)). + +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/webhook-github-node/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/webhook-github-node/ +``` + +Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + +```bash +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + +Follow the instructions in the example's README to set it up and grab the server's FQDN. +After that, check that the service is up: + +```bash +curl https:///health +``` + +```text +{"status":"healthy","timestamp":"2025-12-17T14:55:20.953Z","uptime":0.063799807} +``` + +To create a webhook in GitHub, follow the [official documentation](https://docs.github.com/en/webhooks/using-webhooks/creating-webhooks) and the indications in the example's README. + +The example includes: + +* **Signature validation** using GitHub's webhook secret (via Octokit library). +* **Event logging** with timestamps for debugging and auditing. +* **Health check** endpoint for monitoring and load balancer integration. +* **Scale-to-zero configuration** in the `Kraftfile`. + +To customize for other webhook sources ([Stripe](https://docs.stripe.com/webhooks), [Slack](https://docs.slack.dev/tools/node-slack-sdk/webhook/), [GitLab](https://docs.gitlab.com/user/project/integrations/webhooks/), etc.), it's best to refer to their specific libraries and signature validation methods. +Unfortunately, webhooks are not a standardized protocol, so each service has its own conventions. +We recommend to also follow [Webhooks.fyi](https://webhooks.fyi/) for best practices. + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + +```bash +kraft cloud --help +``` + +Or visit the [CLI Reference](/cli). + +For more information, check out these resources: + +- [Express docunmentation](https://expressjs.com/) +- [GitHub Webhooks Documentation](https://docs.github.com/en/webhooks) +- [Securing GitHub Webhooks](https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries) +- [Webhook Best Practices](https://webhooks.fyi/) From bd2687d56c8f3fc6eb52a4f054ec484c29bbe65a Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Wed, 17 Dec 2025 21:05:17 +0200 Subject: [PATCH 007/131] fix(use-cases): Rectify claims about sub-millisecond boot times Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/api-gateways.mdx | 6 +++--- pages/use-cases/headless-browsers.mdx | 5 +++-- pages/use-cases/mcp-servers.mdx | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pages/use-cases/api-gateways.mdx b/pages/use-cases/api-gateways.mdx index d252b231..afc931ac 100644 --- a/pages/use-cases/api-gateways.mdx +++ b/pages/use-cases/api-gateways.mdx @@ -16,7 +16,7 @@ With **Unikraft Cloud**, API Gateways gain advantage from a unikernel-based, sca Unikernels remove the overhead of general-purpose operating systems by compiling only the required OS components alongside the API Gateway app. This results in: -* Sub-millisecond cold-start times (perfect for bursty API traffic). +* Single-digit-millisecond cold-start times (perfect for bursty API traffic). * Minimal memory footprint, allowing more requests per node. * Consistent, predictable response latency at scale. @@ -35,8 +35,8 @@ Traffic to APIs often fluctuatesβ€”peaking during business hours, quiet overnigh Traditional gateway clusters waste resources when idle. With Unikraft Cloud: -* API Gateways use scale-to-zero when not in use, reducing idle costs to **zero**. -* Instant cold-starts ensure gateways are ready in microseconds when traffic resumes. +* API Gateways scale-to-zero when not in use, reducing idle costs to **zero**. +* Instant cold-starts ensure gateways are ready in milliseconds when traffic resumes. * Fine-grained billing: pay only for requests and runtime, not for idle VMs. ### πŸ”„ Serverless-ready diff --git a/pages/use-cases/headless-browsers.mdx b/pages/use-cases/headless-browsers.mdx index 245c9246..c34e9bac 100644 --- a/pages/use-cases/headless-browsers.mdx +++ b/pages/use-cases/headless-browsers.mdx @@ -13,7 +13,7 @@ They're resource-intensive, security-sensitive, and often run in short burstsβ€” ### ⚑ Instant startups -Instances on Unikraft Cloud boot in microseconds, so browsers spin up only when needed: +Instances on Unikraft Cloud boot in milliseconds, so browsers spin up only when needed: * Perfect for on-demand scraping and CI/CD testing. * No idle costs when browsers aren't running. @@ -31,7 +31,7 @@ With Unikraft Cloud: Scraping jobs or test suites often run in short, irregular bursts: -* Browsers use scale-to-zero when idle, cutting infrastructure waste. +* Browsers scale-to-zero when idle, cutting infrastructure waste. * Pay only for the seconds of actual execution. ### 🌍 Serverless-ready @@ -41,6 +41,7 @@ Integrate with pipelines and workloads that demand ephemeral execution: * Trigger browsers via APIs or serverless functions. * Distribute workloads globally to run close to data sources. + ## Getting started Headless browsers on **Unikraft Cloud** run faster, safer, and cheaper. diff --git a/pages/use-cases/mcp-servers.mdx b/pages/use-cases/mcp-servers.mdx index dd9db89a..e4c358aa 100644 --- a/pages/use-cases/mcp-servers.mdx +++ b/pages/use-cases/mcp-servers.mdx @@ -17,7 +17,7 @@ AI assistants need instant access to tools and data. Every millisecond of latency impacts the user experience. Unikraft Cloud's unikernel architecture reduces OS overhead: -* Sub-millisecond cold starts mean MCP servers are ready instantly. +* Single-digit-millisecond cold starts mean MCP servers are ready instantly. * Minimal memory footprint allows dense packing of specialized servers. ### πŸ”’ Isolated execution @@ -47,6 +47,7 @@ Unikraft Cloud help you reduce the latency of your applications: * Lightweight footprint enables cost-effective multi-region deployment. * Fast startup times ensure consistent performance across all locations. + ## Getting started MCP servers on Unikraft Cloud provide the perfect runtime for AI tool integration, being fast, secure, and cost-efficient. From 9bdd84220a19329fc6e5a5d767cfd4c51cfcb3c3 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Fri, 19 Dec 2025 15:07:59 +0200 Subject: [PATCH 008/131] fix(docs): Adjust content to fix linting errors Signed-off-by: Alex-Andrei Cioc --- .vale.ini | 2 +- pages/platform/services.mdx | 8 ++++---- pages/use-cases/mcp-servers.mdx | 15 ++++++++++++--- pages/use-cases/webhooks.mdx | 9 +++++---- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/.vale.ini b/.vale.ini index c60d6e2b..086e2968 100644 --- a/.vale.ini +++ b/.vale.ini @@ -21,7 +21,7 @@ TokenIgnores = (?sm)((?:import|export) .+?$), \ (`[^`]*`), \ (```[\s\S]*?```) -BlockIgnores = (?sm)```[\s\S]*?```$ +BlockIgnores = (?sm)```[\s\S]*?```$, (?s)\{/\*\s*vale off\s*\*/\}.*?\{/\*\s*vale on\s*\*/\} CommentDelimiters = {/*, */} diff --git a/pages/platform/services.mdx b/pages/platform/services.mdx index 02057b8a..c9b3a530 100644 --- a/pages/platform/services.mdx +++ b/pages/platform/services.mdx @@ -96,7 +96,7 @@ kraft cloud service remove my-service ## Handlers Handlers define how the service will handle incoming connections and forward traffic from the Internet to your app. -For example, you can configure a service to terminate TLS connections, redirect HTTP traffic, or enable HTTP mode for load balancing. +For example, you can configure a service to end TLS connections, redirect HTTP traffic, or enable HTTP mode for load balancing. You configure the handlers for every published service port individually. Currently, there are 3 supported handlers: @@ -113,8 +113,8 @@ Currently, there are 3 supported handlers: Enable HTTP mode on the load balancer to load balance on the level of individual HTTP requests. - In this mode, only HTTP connections are accepted. - If this option is not set, the load balancer works in TCP mode and distributes TCP connections. + In this mode, the load balancer accepts only HTTP connections. + If you don't set this option, the load balancer works in TCP mode and distributes TCP connections. Redirect traffic from the source port to the destination port. @@ -125,7 +125,7 @@ Currently, there are 3 supported handlers: The following set of constraints apply when publishing ports: - Port 80: **must** have `http` and **must not** have `tls` set. - Port 443: **must** have `http` and `tls` set. -- The `redirect` handler can only be set on port 80 (HTTP) to redirect to +- You can only set the `redirect` handler on port 80 (HTTP) to redirect to port 443 (HTTPS). - All other ports **must** have `tls` and **must not** have `http` set. ::: diff --git a/pages/use-cases/mcp-servers.mdx b/pages/use-cases/mcp-servers.mdx index dd9db89a..50322907 100644 --- a/pages/use-cases/mcp-servers.mdx +++ b/pages/use-cases/mcp-servers.mdx @@ -101,6 +101,8 @@ You can find similar instructions for [Claude Code](https://code.claude.com/docs Example query that will trigger a tool call: +{/* vale off */} + > **Q:** *Could you download the original Unikraft paper for me?* > > **A:** The original Unikraft paper (β€œUnikraft: Fast, Specialized Unikernels the Easy Way”) is being downloaded and converted. I will notify you as soon as it is ready for reading or further actions. @@ -115,10 +117,13 @@ Example query that will trigger a tool call: > Even in the hardware domain, and especially with the demise of Moore’s law, manufacturers are increasingly leaning towards hardware specialization to achieve ever better performance; the machine learning field is a primary exponent of this. > ... +{/* vale on */} + ### Example 2: Custom MCP server This example demonstrates how to build a minimal custom MCP server from scratch. -It provides weather information and time utilitiesβ€”showing the core patterns for building your own MCP tools. +It provides weather information and time utilities. +This shows the core patterns for building your own MCP tools. To run it, follow these steps: @@ -159,11 +164,15 @@ You can find similar instructions for [Claude Code](https://code.claude.com/docs Example query that will trigger a tool call: +{/* vale off */} + > **Q**: What is the current weather in Paris, and what time is it there? -> +> > **A**: The current weather in Paris is 21Β°C, partly cloudy, with 62% humidity. > The local time in Paris is 23:21 (11:21 PM), Tuesday, December 2, 2025 (UTC+1). +{/* vale on */} + ## Building your own MCP server MCP servers follow a simple pattern: @@ -175,7 +184,7 @@ MCP servers follow a simple pattern: Common use cases for custom MCP servers: * **Database access**: Query internal databases, data warehouses, or analytics platforms. -* **API integration**: Connect AI assistants to third-party services (CRM, ticketing, monitoring). +* **API integration**: Connect AI assistants to third-party services (customer relationship management, ticketing, monitoring). * **Custom business logic**: Integrate company-specific calculations, validations, or workflows. * **Document retrieval**: Search and retrieve from internal knowledge bases or document stores. diff --git a/pages/use-cases/webhooks.mdx b/pages/use-cases/webhooks.mdx index 1298f3dc..46baf29e 100644 --- a/pages/use-cases/webhooks.mdx +++ b/pages/use-cases/webhooks.mdx @@ -4,7 +4,8 @@ navigation_icon: plug --- Webhooks, also known as reverse APIs, enable real-time, event-driven communication between services. -Instead of constantly polling for updates, webhooks allow services to push data to your app the moment something happensβ€”a commit is pushed, a payment is processed, or an issue is created. +Instead of constantly polling for updates, webhooks allow services to push data to your app the moment something happens. +This could be when someone pushes a commit, processes a payment, or creates an issue. This makes webhooks essential for building reactive, event-driven architectures. With **Unikraft Cloud**, you can deploy webhook receivers that combine instant availability with scale-to-zero economicsβ€”paying only when events arrive, while maintaining millisecond-level response times. @@ -36,7 +37,7 @@ Why pay for idle servers when webhooks only fire occasionally? With Unikraft Cloud: * Webhook receivers scale-to-zero when not processing events, costing nothing. -* Instant wake-up ensures events are processed immediately upon arrival. +* Instant wake-up ensures the system processes events immediately upon arrival. * Fine-grained billing means you only pay for actual event processing. @@ -86,8 +87,8 @@ The example includes: * **Scale-to-zero configuration** in the `Kraftfile`. To customize for other webhook sources ([Stripe](https://docs.stripe.com/webhooks), [Slack](https://docs.slack.dev/tools/node-slack-sdk/webhook/), [GitLab](https://docs.gitlab.com/user/project/integrations/webhooks/), etc.), it's best to refer to their specific libraries and signature validation methods. -Unfortunately, webhooks are not a standardized protocol, so each service has its own conventions. -We recommend to also follow [Webhooks.fyi](https://webhooks.fyi/) for best practices. +Webhooks aren't a standardized protocol, so each service has its own conventions. +Also follow [Webhooks.fyi](https://webhooks.fyi/) for best practices. ## Learn more From 3d28911f4c16b0e5d0b31e1b650a2f0817817cc9 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 4 Nov 2025 15:40:12 +0200 Subject: [PATCH 009/131] feat(scripts): Add more features like ansi coloring This commit replaces the bash script with a more powerful Python script that performs the transformations to the examples READMEs. This new script comes with the following features added: - Code blocks ANSI coloring - Conversion from md H1 to mdx title - Addition of necessary mdx imports - Conversion of md quotes to mdx admonitions - Transform of docs urls to relative syntax It also adds a guard in the Makefile to only transform into guides the examples that have been updated, currently marked by the presence of the substring 'Set metro to Frankfurt, DE'. Signed-off-by: Alex-Andrei Cioc --- Makefile | 11 +- scripts/transform-readme.sh | 25 --- scripts/transform_readme.py | 336 ++++++++++++++++++++++++++++++++++++ 3 files changed, 344 insertions(+), 28 deletions(-) delete mode 100755 scripts/transform-readme.sh create mode 100755 scripts/transform_readme.py diff --git a/Makefile b/Makefile index e8012171..5d28e6d8 100644 --- a/Makefile +++ b/Makefile @@ -49,9 +49,14 @@ sync: name=$$(basename "$$example"); \ readme="$$example/README.md"; \ if [ -f "$$readme" ]; then \ - guide="$(GUIDES_DIR)/$$name.mdx"; \ - echo " πŸ“„ $$name -> $$(basename $$guide)"; \ - $(WORKDIR)/scripts/transform-readme.sh "$$readme" "$$guide" "$$name"; \ + # TODO: remove - Only transform updated READMEs \ + if grep -q "# Set metro to Frankfurt, DE" "$$readme" ; then \ + guide="$(GUIDES_DIR)/$$name.mdx" ;\ + echo " πŸ“„ $$name -> $$(basename $$guide)" ;\ + $(WORKDIR)/scripts/transform_readme.py "$$readme" "$$guide" "$$name" ;\ + else \ + echo "⏭ Skipping $$name (metro line not present)" ;\ + fi ;\ fi; \ done diff --git a/scripts/transform-readme.sh b/scripts/transform-readme.sh deleted file mode 100755 index d8849d96..00000000 --- a/scripts/transform-readme.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: BSD-3-Clause -# Copyright (c) 2025, Unikraft GmbH. -# Licensed under the BSD-3-Clause License (the "License"). -# You may not use this file except in compliance with the License. - -set -euo pipefail - -INPUT_FILE="${1:?Input file required}" -OUTPUT_FILE="${2:?Output file required}" -EXAMPLE_NAME="${3:-}" - -# Extract title from first H1 line, or use example name -TITLE="$(grep -m1 -E '^# ' "$INPUT_FILE" | sed 's/^# //' || echo "$EXAMPLE_NAME")" - -# Convert README.md to .mdx format -# This can be extended to: -# - Add front-matter -# - Convert markdown fenced code blocks if needed -# - Rewrite relative links -# - Add custom components - -# For now, just copy the content -# You can add transformations here as needed -cp "$INPUT_FILE" "$OUTPUT_FILE" diff --git a/scripts/transform_readme.py b/scripts/transform_readme.py new file mode 100755 index 00000000..53d447ca --- /dev/null +++ b/scripts/transform_readme.py @@ -0,0 +1,336 @@ +#!/usr/bin/env python3 +""" +Convert an examples README.md into an MDX guide with small post-processing. + +Behavior: +- Read INPUT_FILE and determine TITLE from the first H1 (or use example name) +- Insert the Tabs import immediately after the H1 (or create an H1 from TITLE) +- Convert blockquote-style admonitions like: + > **Note:**\n+ > line1\n+ > line2 + into: + :::note\n line1\n line2\n ::: +- Rewrite absolute docs URLs back to site-relative paths +- Append a Source block when EXAMPLE_NAME is provided + +Usage: transform_readme.py INPUT_FILE OUTPUT_FILE [EXAMPLE_NAME] +""" +from __future__ import annotations +import argparse +import os +import re +from pathlib import Path + + +# ANSI color codes +ANSI_RESET = '\x1b[0m' +ANSI_BOLD = '\x1b[1m' +ANSI_DARK_GRAY = '\x1b[90m' +ANSI_GREEN = '\x1b[92m' + +# Import statement for Tabs component +TABS_IMPORT = 'import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs"\n\n' + +# Regex patterns +FENCE_PATTERN = re.compile(r"(^```([^\n]*)\n)(.*?)(\n```)$", flags=re.M | re.S) +FRONT_MATTER_PATTERN = re.compile(r"^---\n.*?\n---\n\s*", flags=re.S) +ADMONITION_PATTERN = re.compile(r"^>\s*\*\*([^*]+)\*\*:\s*$") + + +def extract_title(text: str, example_name: str | None) -> str: + m = re.search(r"^# (.+)$", text, flags=re.M) + if m: + return m.group(1).strip() + if example_name: + return example_name + return "" + + +def ensure_front_matter(text: str, title: str) -> str: + """Ensure YAML front-matter with title at the top, replacing existing if present.""" + fm = f"---\ntitle: \"{title}\"\n---\n\n" + m = FRONT_MATTER_PATTERN.match(text) + if m: + return fm + text[m.end():] + return fm + text + + +def insert_tabs_import(text: str, title: str) -> str: + """Insert Tabs import after front-matter or H1, avoiding duplicates.""" + # If import already exists, do nothing + if "zudoku/ui/Tabs" in text: + return text + # If there's YAML front-matter at the top, insert after it. + m_fm = FRONT_MATTER_PATTERN.match(text) + if m_fm: + insert_at = m_fm.end() + return text[:insert_at] + TABS_IMPORT + text[insert_at:] + + # Find first H1 and insert after it + m = re.search(r"(^# .+)$", text, flags=re.M) + if m: + insert_at = m.end(1) + return text[:insert_at] + "\n" + TABS_IMPORT + text[insert_at:] + + # No front-matter nor H1: create H1 from title if available + if title: + return f"# {title}\n\n{TABS_IMPORT}\n" + text + + # Fallback: prepend import + return TABS_IMPORT + "\n" + text + + +def convert_admonitions(text: str) -> str: + """Convert blockquote-style admonitions to ::: syntax.""" + lines = text.splitlines() + out = [] + i = 0 + + while i < len(lines): + m = ADMONITION_PATTERN.match(lines[i]) + if m: + label = m.group(1).strip() + key = label.lower().replace(" ", "-") + i += 1 + block = [] + while i < len(lines) and re.match(r"^> ?", lines[i]): + line = re.sub(r"^> ?", "", lines[i]) + block.append(line) + i += 1 + # Start admonition block + out.append(f":::{key}") + out.extend(block) + out.append(":::") + else: + out.append(lines[i]) + i += 1 + return "\n".join(out) + ("\n" if text.endswith("\n") else "") + + +def rewrite_urls(text: str) -> str: + """Rewrite absolute docs URLs to site-relative paths.""" + # General rule for any other /docs/ link + text = re.sub(r"https://unikraft.com/docs/([^\s\)]+)", r"/\1", text) + return text + + +def color_bracket_and_bullet(line: str) -> str: + """Color the [●] Deployed successfully! line.""" + line = line.replace('[', f'{ANSI_DARK_GRAY}[{ANSI_RESET}') + line = line.replace('●', f'{ANSI_GREEN}●{ANSI_RESET}') + line = line.replace(']', f'{ANSI_DARK_GRAY}]{ANSI_RESET}') + return line + + +def color_box_drawing_line(line: str) -> str: + """Color lines with box-drawing characters and labels.""" + # Match pattern like " β”œβ”€β”€β”€β”€β”€β”€ name: value" or " β”‚" (empty line) + colon_match = re.search(r'^(\s*)((?:β”‚|β”œ|β””))((?:─*)\s*)([^:]+)(:)(.*)$', line) + + if colon_match: + leading_space = colon_match.group(1) # leading whitespace + box_char = colon_match.group(2) # β”‚, β”œ, or β”” + dashes = colon_match.group(3) # ─── and spaces + label = colon_match.group(4) # the label (e.g., "name") + colon = colon_match.group(5) # the colon + value = colon_match.group(6) # the value after colon + + # Color the box character + box_colored = f'{ANSI_DARK_GRAY}{box_char}{ANSI_RESET}' + + # Color all dashes + dashes_colored = dashes.replace('─', f'{ANSI_DARK_GRAY}─{ANSI_RESET}') + + # Color the label in dark gray (but not the colon) + label_colored = f'{ANSI_DARK_GRAY}{label}{ANSI_RESET}{colon}' + + # Check if this is the state line and color the value in green + if 'state' in label.lower(): + # Color the state value (first word after colon and spaces) + value_match = re.search(r'^(\s*)(\S+)(.*)$', value) + if value_match: + value_spaces = value_match.group(1) + state_value = value_match.group(2) + rest = value_match.group(3) + value = f'{value_spaces}{ANSI_GREEN}{state_value}{ANSI_RESET}{rest}' + + return leading_space + box_colored + dashes_colored + label_colored + value + else: + # No colon, just color the box-drawing characters + for char in ['β”‚', 'β”œ', 'β””', '─']: + line = line.replace(char, f'{ANSI_DARK_GRAY}{char}{ANSI_RESET}') + return line + + +def color_deployed_block(text: str) -> str: + """Find and colorize deployed successfully blocks with ANSI codes.""" + def repl(m): + fence_start = m.group(1) + lang = (m.group(2) or "").strip() + body = m.group(3) + fence_end = m.group(4) + + # Only operate on blocks that contain the deployed-success marker text. + if 'deployed successfully!' not in body.lower(): + return m.group(0) + + # Check if this block already has proper ANSI coloring applied + if f'{ANSI_DARK_GRAY}β”‚{ANSI_RESET}' in body or f'{ANSI_DARK_GRAY}β”œ{ANSI_RESET}' in body: + return m.group(0) + + # Ensure the fence is marked as 'ansi' for proper rendering + if 'ansi' not in lang.lower(): + fence_start = "```ansi\n" + + # Process line by line to add colors + lines = body.split('\n') + colored_lines = [] + + for line in lines: + # Skip empty lines + if not line.strip(): + colored_lines.append(line) + continue + + # Color the bracket and bullet line: [●] Deployed successfully! + if '●' in line and 'deployed successfully' in line.lower(): + colored_lines.append(color_bracket_and_bullet(line)) + continue + + # Color lines with box-drawing characters (β”‚, β”œ, β””, ─) + if any(char in line for char in ['β”‚', 'β”œ', 'β””', '─']): + colored_lines.append(color_box_drawing_line(line)) + else: + colored_lines.append(line) + + body = '\n'.join(colored_lines) + return fence_start + body + fence_end + + return FENCE_PATTERN.sub(repl, text) + + +def find_state_column_index(header_line: str) -> int | None: + """Find the index of the STATE column in a table header.""" + header_tokens = re.split(r"\s{2,}", header_line.strip()) + for i, token in enumerate(header_tokens): + if token.strip().upper() == "STATE": + return i + return None + + +def bold_table_header(header_line: str) -> str: + """Make each token in the table header bold.""" + pieces = re.split(r'(\s{2,})', header_line) + cols = pieces[0::2] + seps = pieces[1::2] + + for i, col in enumerate(cols): + token = col.strip() + if token and ANSI_BOLD not in token: + cols[i] = col.replace(token, f"{ANSI_BOLD}{token}{ANSI_RESET}", 1) + + result = "" + for i, col in enumerate(cols): + result += col + if i < len(seps): + result += seps[i] + return result + + +def color_state_value_in_row(line: str, state_col: int) -> str: + """Color the state value in a table row.""" + pieces = re.split(r'(\s{2,})', line) + cols = pieces[0::2] + seps = pieces[1::2] + + if len(cols) > state_col: + raw_val = cols[state_col] + val = raw_val.strip() + if val and ANSI_GREEN not in val: + colored = f"{ANSI_GREEN}{val}{ANSI_RESET}" + cols[state_col] = raw_val.replace(val, colored, 1) + + # Reconstruct using original separators to preserve spacing + result = "" + for i, col in enumerate(cols): + result += col + if i < len(seps): + result += seps[i] + return result + + +def color_state_in_table_blocks(text: str) -> str: + """Color state values in table-style fenced blocks (STATE column) with light green.""" + def repl(m): + fence_start = m.group(1) + body = m.group(3) + fence_end = m.group(4) + + lines = body.splitlines() + + # Find header line that contains NAME and STATE (case-insensitive) + header_idx = None + for idx, line in enumerate(lines): + if re.search(r"\bNAME\b", line, flags=re.I) and re.search(r"\bSTATE\b", line, flags=re.I): + header_idx = idx + break + + if header_idx is None: + return m.group(0) + + # Find the STATE column index + state_col = find_state_column_index(lines[header_idx]) + if state_col is None: + return m.group(0) + + # Process header: make each header token bold + new_lines = lines[:header_idx] + new_lines.append(bold_table_header(lines[header_idx]).rstrip('\n')) + + # Process data rows + j = header_idx + 1 + while j < len(lines) and lines[j].strip() != "": + new_lines.append(color_state_value_in_row(lines[j], state_col).rstrip('\n')) + j += 1 + + # Append any remaining lines + new_lines.extend(lines[j:]) + new_body = "\n".join(new_lines) + return fence_start + new_body + fence_end + + return FENCE_PATTERN.sub(repl, text) + + +def main(argv: list[str] | None = None) -> int: + """Main entry point for the README to MDX transformation script.""" + p = argparse.ArgumentParser( + description="Convert examples README.md into an MDX guide with ANSI coloring" + ) + p.add_argument("input_file", help="Path to input README.md file") + p.add_argument("output_file", help="Path to output MDX file") + p.add_argument("example_name", nargs="?", default="", help="Optional example name for title") + args = p.parse_args(argv) + + inp = Path(args.input_file) + out = Path(args.output_file) + example_name = args.example_name or None + + txt = inp.read_text(encoding="utf-8") + + # Determine title + title = os.environ.get('TITLE') or extract_title(txt, example_name) + + # Apply transformations in sequence + content = ensure_front_matter(txt, title) + content = re.sub(r"(?m)^# .+\n", "", content, count=1) # Remove first H1 + content = insert_tabs_import(content, title) + content = convert_admonitions(content) + content = rewrite_urls(content) + content = color_deployed_block(content) + content = color_state_in_table_blocks(content) + + out.write_text(content, encoding="utf-8") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From b9bca606445dccef201c28ecc73df4a5db5e1ca1 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Mon, 22 Dec 2025 15:10:26 +0200 Subject: [PATCH 010/131] fix(features): Fix spelling mistakes Signed-off-by: Alex-Andrei Cioc --- pages/features/autoscale.mdx | 42 +++++++++---------- pages/features/load-balancing.mdx | 40 ++++++++---------- pages/features/scale-to-zero.mdx | 67 +++++++++++++------------------ pages/features/snapshots.mdx | 28 ++++++------- pages/platform/services.mdx | 4 +- 5 files changed, 82 insertions(+), 99 deletions(-) diff --git a/pages/features/autoscale.mdx b/pages/features/autoscale.mdx index bdcc7222..3db9fa8c 100644 --- a/pages/features/autoscale.mdx +++ b/pages/features/autoscale.mdx @@ -3,8 +3,8 @@ title: Autoscale navigation_icon: square-stack --- -Autoscaling is [load balancing](/features/load-balancing) where the *number of instances* used to handle your traffic is automatically adapted to match the current traffic load. -On Unikraft Cloud, scale out (the process of adding instances to cope with increased load) happens in milliseconds. +Autoscaling is [load balancing](/features/load-balancing) where the *number of instances* used to handle your traffic automatically adapts to match the current traffic load. +On Unikraft Cloud, scale-out (the process of adding instances to cope with increased load) happens in milliseconds. You can transparently and effortlessly handle load increase including traffic peaks. No more headaches due to slow autoscale like keeping hot instances around to deal with peaks, coming up with complex predictive algorithms, or other painful workarounds. You can set autoscale on and let Unikraft Cloud handle your traffic increases and peaks. @@ -21,15 +21,15 @@ This is where autoscale comes into play. With autoscale enabled, Unikraft Cloud takes care of the heavy lifting for you by continuously monitoring the load of your service and automatically creating or deleting instances as needed. +{/* vale off */} :::caution[Limited Access] - -At the moment, autoscale **isn't** enabled by default on Unikraft Cloud accounts (you might get a "Autoscale not enabled for your account" error). -If you would like to enable it for you please reach out to the Unikraft Cloud Discord or send an email to `support@unikraft.com`. - +At the moment, autoscale **is not** enabled by default (you might get an "Autoscale not enabled for your account" error). +If you would like to enable it, please reach out to the [Unikraft Cloud Discord](https://kraft.cloud/discord) or send an email to `support@unikraft.com`. ::: +{/* vale on */} :::note -Autoscale as well as load balancing in general is currently only available for Internet-facing services. +Autoscale, as well as load balancing in general, currently supports only Internet-facing services. ::: ## Setting up autoscale @@ -39,7 +39,7 @@ First, use the `kraft cloud deploy` command to create an instance, in this examp ```bash title="" git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ -kraft cloud deploy -p 443:8080 . +kraft cloud deploy -p 443:8080 -M 256 . ``` ```ansi title="" @@ -51,18 +51,18 @@ kraft cloud deploy -p 443:8080 . β”œ─────────── url: https://small-leaf-rafirkw7.fra.unikraft.app β”œ───────── image: nginx@sha256:389bfa6be6455c92b61cfe429b50491373731dbdd8bd8dc79c08f985d6114758 β”œ───── boot time: 20.36 ms - β”œ──────── memory: 128 MiB + β”œ──────── memory: 256 MiB β”œ─────── service: small-leaf-rafirkw7 β”œ── private fqdn: nginx-4d7u3.internal β”œ──── private ip: 172.16.6.5 β””────────── args: /usr/bin/nginx -c /etc/nginx/nginx.conf ``` -With this single `kraft cloud deploy` command, 3 things happen: +This single `kraft cloud deploy` command does 3 things: 1. Creates an instance of NGINX which will serve as the **autoscale master** instance. 1. Creates a service via the `-p` flag (named `small-leaf-rafirkw7`). -1. Attaches the instance to the service (automatically done by the `-p` flag too). +1. Attaches the instance to the service (the `-p` flag also does this automatically). All that's left to do now to set up autoscale is to set an autoscale configuration *policy* and to set the instance as master. Unikraft Cloud then takes care of cloning this master instance whenever load increases. @@ -92,10 +92,10 @@ kraft cloud scale add small-leaf-rafirkw7 \ Note the following: -* The first command sets the master to the instance created, and sets it to scale up to a maximum of 8 instances and a minimum of 1; the warm up and cool down time are also set to 1 second each, so it's not constantly fluctuating up and down. -* The second command sets the *scale out* policy based on CPU utilization (in millicores): between 60% and 80% utilization, an increase by 50% of instances occurs. +* The first command sets the master to the created instance, and configures it to scale up to a maximum of 8 instances and a minimum of 1; the command also sets the warm up and cool down time to 1 second each, so it doesn't constantly fluctuate up and down. +* The second command sets the *scale-out* policy based on CPU utilization (in millicores): between 60% and 80% utilization, the system increases instances by 50%. From 80% onward, the number of instances doubles. -* The third command sets the *scale in* policy: below 50% utilization, reduce the number of instances by half (note the `-` sign for scale in). +* The third command sets the *scale-in* policy: below 50% utilization, the system reduces the number of instances by half (note the `-` sign for scale-in). :::note @@ -106,8 +106,8 @@ Refer to the API autoscale [reference](/api/platform/v1/autoscale) for more deta :::note -Keep in mind that there are a few restrictions on how to define scale-in/scale-out steps. -The documentation is available [here](/api/platform/v1/autoscale) at the bottom of the section. +Keep in mind that a few restrictions apply to how you define scale-in/scale-out steps. +You can find the documentation [here](/api/platform/v1/autoscale) at the bottom of the section. ::: @@ -157,7 +157,7 @@ steps: type: step ``` -You can further check that the master instance is on `standby` (scaled to zero) assuming your service isn't receiving any traffic yet. +You can further check that the master instance is on `standby` (scaled to zero), assuming your service hasn't received any traffic yet. You can get the UUID of your master instance from the `kraft cloud scale get` command above. ```bash title="" @@ -174,7 +174,7 @@ You should see output like: state: standby created at: 30 minutes ago image: nginx@sha256:d4325c1f1a472c511723148adc380d491029f4c98a2367fbeff628c6456d4180 - memory: 128 MiB + memory: 256 MiB args: /usr/bin/nginx -c /etc/nginx/nginx.conf env: volumes: @@ -185,15 +185,15 @@ You should see output like: Note the value of the `state` field. Now to make sure the service is up, `curl` the service address: -```bash +```bash title="" curl https://small-leaf-rafirkw7.fra.unikraft.app ``` You should get an immediate response, even though the instance was on `standby`. -You can use the `watch` tool to see if you manage to see the instance change state from `standby` to `running`: +You can use the `watch` tool to see if you catch the instance changing state from `standby` to `running`: ```ansi title="" -watch --color -n 0.5 Unikraft Cloud instance list +watch --color -n 0.5 kraft cloud instance list ``` ## Learn more diff --git a/pages/features/load-balancing.mdx b/pages/features/load-balancing.mdx index 87b6c06a..e9f29e5f 100644 --- a/pages/features/load-balancing.mdx +++ b/pages/features/load-balancing.mdx @@ -15,12 +15,12 @@ You can remove instances from a service at any time, and, when you do, Unikraft [Services](/platform/services) have soft and hard limits for the number of concurrent requests and connections. The limits apply **per instance**. -For HTTP services (that is, using the `http` [handler](/platform/services#handlers)) the system checks each individual in-flight request against the limit, but not the underlying TCP connection. -For TCP services the individual open connections get counted. +For HTTP services (that is, using the `http` [handler](/platform/services#handlers)), the system checks each individual in-flight request against the limit, but not the underlying TCP connection. +For TCP services, the system counts the individual open connections. In the following, the term request refers to both requests and connections. The load balancer uses the soft limit to decide when to wake up another [standby](/platform/instances#instance-states) instance. -For example, if you set the soft limit to 5 and the service consists of 2 standby instances, one of the instances receives up to 5 concurrent requests. +For example, if you set the soft limit to 5 and the service consists of 2 standby instances, one of the instances can receive up to 5 concurrent requests. The 6th parallel request wakes up the second instance. If there are no more standby instances to wake up, the number of requests assigned to each instance will exceed the soft limit. The load balancer ensures that when the number of in-flight requests goes down again, instances go into standby as fast as possible. @@ -38,7 +38,7 @@ For example, use NGINX as the app: ```bash title="" git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ -kraft cloud deploy -p 443:8080 . +kraft cloud deploy -p 443:8080 -M 256 . ``` This single command will (a) create a service via the `-p` flag and (b) start an NGINX instance: @@ -52,7 +52,7 @@ This single command will (a) create a service via the `-p` flag and (b) start an β”œ─────────── url: https://wandering-shape-n6mhimgn.fra.unikraft.app β”œ───────── image: nginx@sha256:269192f523dca7498423bc54676ab08e415e9c7442d1bd3d65f07ab5e50a43d β”œ───── boot time: 20.18 ms - β”œ──────── memory: 128 Mi + β”œ──────── memory: 256 MiB β”œ─────── service: wandering-shape-n6mhimgn β”œ── private fqdn: nginx-8ujeu.internal β”œ──── private ip: 172.16.6.7 @@ -63,18 +63,16 @@ With this in place, it's now time to start a second instance and attach it to th ```bash title="" cd examples/nginx/ -kraft cloud deploy --service wandering-shape-n6mhimgn . +kraft cloud deploy --service wandering-shape-n6mhimgn -M 256 . ``` :::tip - -If you get a prompt saying "deployment already exists: what would you like to do with the 1 existing instances," choose `keep`. - +If a prompt appears saying "deployment already exists: what would you like to do with the 1 existing instances," choose `keep`. ::: The command's output should look like this: -```ansi +```ansi title="" [●] Deployed successfully! β”‚ β”œ────────── name: nginx-djta3 @@ -83,14 +81,14 @@ The command's output should look like this: β”œ─────────── url: https://wandering-shape-n6mhimgn.fra.unikraft.app β”œ───────── image: nginx@sha256:c00c11a5cbd6a3020dd4d9703fbeb2a2f2aab37f18f7a0ba9c66db5a71897c3a β”œ───── boot time: 20.46 ms - β”œ──────── memory: 128 MiB + β”œ──────── memory: 256 MiB β”œ______─ service: wandering-shape-n6mhimgn β”œ── private fqdn: nginx-djta3.internal β”œ──── private ip: 172.16.6.3 β””────────── args: /usr/bin/nginx -c /etc/nginx/nginx.conf ``` -Both the `url` and `service` fields in the 2 instances are the same, as they should be. +Both the `url` and `service` fields in the 2 instances are the same. To check that it worked, run the following command: ```bash title="" @@ -113,26 +111,22 @@ Note the two instances (their UUIDs) under the `instances` field. You're now load balancing across 2 NGINX instances! :::tip - Currently it's impossible to set the service's name via `kraft cloud deploy`. If you'd like to set the service's name, first use the `kraft cloud service` command to create the service. You can use the `--service` flag of `kraft cloud deploy` to attach the instance to the service, as outlined in this [guide](/platform/services). - ::: :::tip - -If you want to ensure that no existing connections get dropped when stopping an instance, use Unikraft Cloud's draining feature by stopping an instance through `kraft cloud instance stop -w ` - +To ensure that stopping an instance doesn't drop existing connections, use Unikraft Cloud's draining feature by stopping an instance through `kraft cloud instance stop -w ` ::: ## Load balancing algorithm The load balancing algorithm is a variant of `least_conn`. -For every instance, the number of current in-flight TCP connections (if in `tcp` [mode](/platform/services#handlers)) or requests (if in `http` [mode](/platform/services#handlers)). +For every instance, the system tracks the number of current in-flight TCP connections (if in `tcp` [mode](/platform/services#handlers)) or requests (if in `http` [mode](/platform/services#handlers)). To select an instance, the system goes over all instances in the service. -It finds the set of instances that have the least amount of in-flight requests/connections, and picks from that set. +It finds the set of instances with the least amount of in-flight requests/connections, and picks from that set. To illustrate, imagine this scenario: @@ -143,10 +137,10 @@ To illustrate, imagine this scenario: | `i-2` | 2 | | `i-3` | 1 | -In this case, the algorithm would first choose instances `i-1` and `i-3`, since they both have the least number of connections at the moment (only 1 each). -After that, the algorithm would choose between these 2 instances and assign the new connection to it. -For example, if it chose `i-1`, the next new connection would go to `i-3`. -This is because it would now be the only instance with only 1 connection (assuming none of the connections that the other instances handle close). +In this case, the algorithm first chooses instances `i-1` and `i-3`, since they both have the least number of connections at the moment (only 1 each). +After that, it chooses between these 2 instances and assigns the new connection to one of them. +For example, if it chose `i-1`, the next new connection goes to `i-3`. +This is because `i-3` now becomes the only instance with only 1 connection (assuming none of the connections that the other instances handle close). ## Learn more diff --git a/pages/features/scale-to-zero.mdx b/pages/features/scale-to-zero.mdx index 98b03847..25a76b96 100644 --- a/pages/features/scale-to-zero.mdx +++ b/pages/features/scale-to-zero.mdx @@ -11,16 +11,16 @@ Instances on Unikraft Cloud can cold boot within milliseconds, while providing t Millisecond cold boots allow performing low-latency scale-to-zero. As long as no traffic is flowing through your instance, it consumes **no** resources. -When the next connection arrives, Unikraft Cloud takes care of transparently cold booting (it's called cold booting if it's milliseconds?) your instance and replying. -All within a negligible amount of time for Internet round-trip times and so unbeknownst to your end users. +When the next connection arrives, Unikraft Cloud takes care of transparently cold booting (is it cold booting if it's milliseconds?) your instance and replying. +All within a negligible amount of time compared to Internet round-trip times, and so unbeknownst to your end users. -By default, Unikraft Cloud reduces network and cloud stack cold start time to a min time. +By default, Unikraft Cloud reduces network and cloud stack cold start time to a minimum. Some apps take a while to initialize (for example, Spring Boot, Puppeteer, etc). -If you need to deploy such an app and still want millisecond cold starts, Unikraft Cloud provides a *stateful* feature. +If you need to deploy such an app and still want millisecond cold starts, Unikraft Cloud offers a *stateful* feature. Please check out [this guide](/features/scale-to-zero#stateful-scale-to-zero) for more information on how to set this up. :::tip -If you add instances to a [service](/platform/services), the service will load balance traffic across all them and Unikraft Cloud will ensure each instance gets woken up as needed. +If you add instances to a [service](/platform/services), the service will load balance traffic across them and Unikraft Cloud will wake up each instance as needed. This differs from [autoscale](/features/autoscale), in which you *don't* specify the number of instances. The platform does this for you based on traffic load. ::: @@ -34,9 +34,9 @@ Unikraft Cloud currently supports the following scale-to-zero policies: | Policy | Description | |--------|-------------| -| `off` | Scale-to-zero isn't enabled. The instance keeps on running until manually stopped. | -| `on` | Enables scale-to-zero. When there are no TCP connections or HTTP requests during the cool-down time, the instance goes into standby. | -| `idle` | Same as `on`, but also puts the instance into standby when there are TCP connections established that have been inactive during the cool-down time. The connections remain established and incoming packets wake up the instance. Scale-to-zero doesn't happen while there are active HTTP requests (that is, traffic on ports, which use the `http` [handler](/platform/services#handlers)). | +| `off` | Disables scale-to-zero. The instance keeps on running until manually stopped. | +| `on` | Enables scale-to-zero. When there are no TCP connections or HTTP requests during the cooldown time, the instance goes into standby. | +| `idle` | Same as `on`, but also puts the instance into standby when there are TCP connections established that have been inactive during the cooldown time. The connections remain established and incoming packets wake up the instance. Scale-to-zero doesn't happen while there are active HTTP requests (that is, traffic on ports which use the `http` [handler](/platform/services#handlers)). | :::note Unikraft Cloud only considers network traffic that's going through its proxy to control scale-to-zero. @@ -52,18 +52,17 @@ Cases exist where making your app aware of scale-to-zero makes sense. - **Background Jobs**: For example, you want to run background jobs after your app has responded to a request (for example, send trace information to a logging server). In this case, you may want to temporarily disable scale-to-zero to ensure your instance isn't put to sleep while still performing work. - Cases exist where making your app aware of scale-to-zero makes sense. - **Long Request Processing**: The same is true if your app can have long request processing times. - Consider a setup where you use the `idle` policy with plain TCP connections and configure a cool-down time of 10s. + Consider a setup where you use the `idle` policy with plain TCP connections and configure a cooldown time of 10s. Sometimes if it takes your app 15s to process a request until the first response data gets sent, Unikraft Cloud will prematurely scale your instance to zero[^1]. -Configuring a longer cool-down time can be a simple solution sometimes. +Configuring a longer cooldown time can be a simple solution sometimes. But this isn't possible if the max duration of background jobs or request processing phases is unknown. It also means that you have to compromise between cost efficiency and reliability of your service. Unikraft Cloud allows your app to temporarily disable scale-to-zero. -You can have both a short cool-down phase and reliable operation no matter how long things may take. +You can have both a short cooldown phase and reliable operation no matter how long things may take. To control scale-to-zero from within your app, instances on Unikraft Cloud provide a special file-based interface: | Path | Description | @@ -71,13 +70,13 @@ To control scale-to-zero from within your app, instances on Unikraft Cloud provi |`/uk/libukp/scale_to_zero_disable` | Allows to temporarily disable scale-to-zero. | The `scale_to_zero_disable` pseudo file keeps track of the count of concurrent disable requests. -If the count is `0`, scale-to-zero remains active[^2]. +If the count reaches `0`, scale-to-zero remains active[^2]. Any number larger than `0` means scale-to-zero is temporarily inactive. -Using a count instead of a boolean value helps many independent workers. +Using a count instead of a boolean value is helpful when you have many independent workers. Your app workers can disable scale-to-zero individually by incrementing and decrementing the count without having to synchronize. Reading the file returns the current count. -The value gets a prefix with an equals sign (that is, `=X` with `X` being the current count). +The system prefixes the value with an equals sign (that is, `=X` with `X` being the current count). Writing to the file modifies the count. You can use the following strings: @@ -95,7 +94,7 @@ Any attempt to set a count less than `0` or larger than `2^64` returns an `ERANG :::caution Writing to the file to disable scale-to-zero doesn't atomically disable scale-to-zero. There can be a short delay (a few milliseconds) until the Unikraft Cloud controller receives the changed value and makes scale-to-zero decisions accordingly. -Ensure you configure a cool-down time large enough to accommodate for potential signal delay. +Ensure you configure a cooldown time large enough to accommodate for potential signal delay. ::: @@ -105,7 +104,7 @@ Some apps have a long cold boot phase or experience large first response latency For example, to run just-in-time compilation and fill caches. Using stateful scale-to-zero can dramatically reduce the response time of your service. With stateful scale-to-zero Unikraft Cloud takes a snapshot of the instance state before putting it into standby. -When incoming network traffic triggers a wake-up, the snapshot gets loaded. +When incoming network traffic triggers a wake-up, Unikraft Cloud loads the snapshot. The instance resumes execution where it left offβ€”with caches already warm. Stateful scale-to-zero can also enable scale-to-zero for apps that need to keep state for functional correctness. @@ -113,8 +112,8 @@ This works even if cold boot times are no concern. :::note The time to load an instance snapshot is constant and in the order of a few milliseconds. -This is what gets reported in the boot time metrics. -The actual memory contents gets loaded from the snapshot only at first access. +This is what the boot time metrics report. +The system loads the actual memory contents from the snapshot only at first access. This reduces response latency by loading only what's necessary to process the request. This means that the first few requests might take longer until all required memory comes back. @@ -124,7 +123,7 @@ The time to take an instance snapshot during scale-to-zero depends on the amount ## Getting started -Millisecond scale-to-zero applies via a **label** in each of +You can enable millisecond scale-to-zero via a **label** in each of the subdirectories' `Kraftfile` or with the `--scale-to-zero` flag in relevant command-line tool subcommands. @@ -135,8 +134,8 @@ labels: ``` :::tip -The `cool-down` flag tells Unikraft Cloud how long the instance must be idle before scaling to zero. -In the examples, values that work for each of them appear so you don't have to worry about this label if you don't want to. +The `--scale-to-zero-cooldown` flag tells Unikraft Cloud how long the instance must be idle before scaling to zero. +The examples include appropriate values so you don't have to worry about this label if you don't want to. ::: :::tip @@ -146,9 +145,9 @@ You can disable scale-to-zero either by setting the label to `false`, or with th Since Unikraft Cloud has scale-to-zero on by default, all you need to do is to start an instance normally: ```bash title="" -git clone https://github.com/kraft-cloud/examples +git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ -kraft cloud deploy -p 443:8080 . +kraft cloud deploy -p 443:8080 -M 256 . ``` This command will create the NGINX instance with scale-to-zero enabled: @@ -162,7 +161,7 @@ This command will create the NGINX instance with scale-to-zero enabled: β”œ─────────── url: https://twilight-gorilla-ui5b6kwt.fra.unikraft.app β”œ───────── image: nginx@sha256:19854a12fe97f138313cb9b4806828cae9cecf2d050077a0268d98129863f954 β”œ───── boot time: 19.81 ms - β”œ──────── memory: 128 MiB + β”œ──────── memory: 256 MiB β”œ─────── service: twilight-gorilla-ui5b6kwt β”œ── private fqdn: nginx-1a747.internal β”œ──── private ip: 172.16.6.1 @@ -184,7 +183,7 @@ nginx-1a747 twilight-gorilla-ui5b6kwt.fra.unikraft.app standby ``` Notice the state is now set to `standby`? -At first `kraft cloud deploy` sets the state to `running`, but then Unikraft Cloud puts the instance immediately to sleep (more accurately, it stopped it, but it keeps state to start it again when needed). +At first `kraft cloud deploy` sets the state to `running`, but then Unikraft Cloud puts the instance immediately to sleep (more accurately, it stops it, but it keeps state to start it again when needed). You can also check that scale-to-zero gets enabled through the `kraft cloud scale` command: @@ -206,20 +205,12 @@ which outputs: policies: ``` -Note the `min size` (0) and `max size` (1) fields -- these mean that the service can scale from max 1 instance to min 0 instances, meaning that the system enables scale-to-zero. +Note the `min size` (0) and `max size` (1) fields -- these mean that the service can scale between 0 and 1 instances, which enables scale-to-zero. ### Testing scale-to-zero -Now take this out for a spin. -``` - -Note the `min size` (0) and `max size` (1) fields -- these mean that the service can scale from max 1 instance to min 0 instances, meaning that scale-to-zero is enabled. - - -### Testing scale-to-zero - -Try using `curl` or your browser to see scale-to-zero (well, scale to 1 in this case!) in action: +Try using `curl` or your browser to see scale-to-zero (well, scale-to-1 in this case!) in action: ```bash title="" curl https://twilight-gorilla-ui5b6kwt.fra.unikraft.app @@ -243,8 +234,8 @@ nginx-1a747 twilight-gorilla-ui5b6kwt.fra.unikraft.app running :::note You can use scale-to-zero *in conjunction with* autoscale. This ensures that as you scale back down, if traffic dies, your last instance gets removed. -You're not charged for the service. -For more on autoscale please see the autoscale [guide](/features/autoscale) +You're not charged for the service in this state. +For more on autoscale please see the autoscale [guide](/features/autoscale). ::: diff --git a/pages/features/snapshots.mdx b/pages/features/snapshots.mdx index 233bbec0..627aedd8 100644 --- a/pages/features/snapshots.mdx +++ b/pages/features/snapshots.mdx @@ -7,46 +7,44 @@ Unikraft Cloud supports the ability to deploy **stateful** apps. These apps can keep state across different [scale-to-zero](/features/scale-to-zero) incarnations. This mechanism also reduces app init time. Heavy-weight apps take a while to get started when cold started (for example, Spring Boot, Ruby on Rails, etc.). -Taking a snapshot of the app memory and restoring it when the app starts again does this. +You can reduce this initialization time by taking a snapshot of the app memory and restoring it when the app starts again. ## Setting it up The quickest way to set this up is via the `--scale-to-zero-stateful` flag of the `kraft cloud deploy` or `kraft cloud instance create` commands, for example: -```bash +```bash title="" kraft cloud deploy --metro fra --scale-to-zero-stateful . ``` As an alternative, you can add a `label` to your example's `Kraftfile` as follows: -```yaml +```yaml title="" labels: cloud.unikraft.v1.instances/scale_to_zero.stateful: "true" ``` -You can see an example of such a `Kraftfile` and label in the [Spring Boot -example](/guides/springboot). +You can see an example of such a `Kraftfile` and label in the [Spring Boot example](/guides/springboot). -Once deployed, you can check that this mechanism is actually enabled for your -app via the `kraft cloud instance get ` command: +Once deployed, you can check whether this mechanism works for your app via the `kraft cloud instance get ` command: -```ansi +```ansi title="" stateful: enabled ``` ## How it works -With stateful enabled, when you first deploy your app Unikraft Cloud will bring it up -normally and let it fully initialize (which may be fast, or take seconds or -minutes, depending on your app's init time). Unikraft Cloud will wait until the app's port -gets up, and then start the scale-to-zero process (assuming no traffic is coming -to that port). At this point, Unikraft Cloud will save the state of your app, and set the +When you enable stateful mode and first deploy your app, Unikraft Cloud brings it up +normally and lets it fully initialize (which may be fast, or take seconds or +minutes, depending on your app's init time). Unikraft Cloud waits until the app's exposed port +becomes available, and then starts the scale-to-zero process (assuming no traffic is coming +to that port). At this point, Unikraft Cloud saves the state of your app, and sets the app to standby (consuming no resources). -Next, when traffic arrives, Unikraft Cloud will bring up the app including its saved state, -ensuring statefulness across different scale-to-zero and scale to one cycles, +Next, when traffic arrives, Unikraft Cloud brings up the app including its saved state, +ensuring statefulness across different scale-to-zero and scale-to-one cycles, but also eliminating any long initialization times from heavyweight apps. diff --git a/pages/platform/services.mdx b/pages/platform/services.mdx index c9b3a530..98bed32a 100644 --- a/pages/platform/services.mdx +++ b/pages/platform/services.mdx @@ -42,7 +42,7 @@ For example, from the [Go web server guide](/guides/go): ```bash title="" git clone https://github.com/unikraft-cloud/examples cd examples/http-go1.21/ -kraft cloud deploy --service my-service . +kraft cloud deploy --service my-service -M 256 . ``` This creates a new Go web server instance and immediately attaches it to the `my-service` service. @@ -57,7 +57,7 @@ The output shows the instance address and other details: β”œ─────────── url: https://my-service-rrtckyyi.fra.unikraft.app β”œ───────── image: http-go121@sha256:4d536236d226781874c3ad930dbc936c4f407aa3483a1f8e961ba63a7a72c78d β”œ───── boot time: 17.14 ms - β”œ──────── memory: 128 MiB + β”œ──────── memory: 256 MiB β”œ─────── service: my-service β”œ── private fqdn: http-go121-fkt1x.internal β”œ──── private ip: 172.16.6.6 From f4f20fe0b83dd0e01009b50e658ef3d47b58fe01 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 23 Dec 2025 18:32:18 +0200 Subject: [PATCH 011/131] chore: Ensure consistent syntax of kraft cloud deploy This commit ensures that wherever `kraft cloud deploy` is used in the documentation, the order of the arguments is consistent. Additionally, it ensures that the memory specification of the instance follows these rules: - For values below 1Gi, it is specified in Mi, without explicit measuring unit (e.g., `-M 512`) - For values above 1Gi, it is specified in Gi, with explicit measuring unit (e.g., `-M 2Gi`). Signed-off-by: Alex-Andrei Cioc --- pages/guides/ferretdb.mdx | 12 ++++++------ pages/use-cases/headless-browsers.mdx | 2 +- pages/use-cases/remote-ides.mdx | 2 +- pages/use-cases/serverless-databases.mdx | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pages/guides/ferretdb.mdx b/pages/guides/ferretdb.mdx index 5a32f58a..94474002 100644 --- a/pages/guides/ferretdb.mdx +++ b/pages/guides/ferretdb.mdx @@ -35,14 +35,14 @@ For that, follow these steps: ```bash cd postgres16.2/ - kraft cloud deploy -M 1024 -e POSTGRES_PASSWORD=unikraft --name postgres . + kraft cloud deploy -M 1Gi -e POSTGRES_PASSWORD=unikraft --name postgres . ``` 1. Run an instance of FerretDB: ```bash cd ../ferretdb/ - kraft cloud deploy -M 512 -p 27017:27017/tls -e FERRETDB_HANDLER=pg -e FERRETDB_POSTGRESQL_address=postgres://postgres.internal:5432 -e FERRETDB_LISTEN_ADDR=0.0.0.0:27017 . + kraft cloud deploy -p 27017:27017/tls -M 512 -e FERRETDB_HANDLER=pg -e FERRETDB_POSTGRESQL_address=postgres://postgres.internal:5432 -e FERRETDB_LISTEN_ADDR=0.0.0.0:27017 . ``` ```ansi @@ -112,9 +112,9 @@ kraft cloud instance list ``` ```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -ferretdb-rdj6z restless-resonance-jcc4ulc3.fra.unikraft.app running 11 minutes ago ferretdb@sha256:27c59539fa3b6b7... 512 MiB /usr/bin/ferretdb 37.11 ms -postgres running 14 minutes ago postgres@sha256:c1f1100176be97f... 1.0 GiB wrapper.sh docker-entrypoint.sh postgres 593.15 ms +NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME +ferretdb-rdj6z restless-resonance-jcc4ulc3.fra.unikraft.app running 11 minutes ago ferretdb@sha256:27c59539fa3b6b7... 512 MiB /usr/bin/ferretdb 37.11 ms +postgres running 14 minutes ago postgres@sha256:c1f1100176be97f... 1.0 GiB wrapper.sh docker-entrypoint.sh postgres 593.15 ms ``` When done, you can remove the FerretDB and the Postgres instances: @@ -136,7 +136,7 @@ kraft cloud volume create --name ferret-postgres --size 200 And then, when, starting the PostgreSQL instance, you would attach the volume to a mount point: ```bash -kraft cloud deploy -M 1024 -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres --name postgres -v ferret-postgres:/volume . +kraft cloud deploy -M 1Gi -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres --name postgres -v ferret-postgres:/volume . ``` ## Learn more diff --git a/pages/use-cases/headless-browsers.mdx b/pages/use-cases/headless-browsers.mdx index c34e9bac..23e57fc5 100644 --- a/pages/use-cases/headless-browsers.mdx +++ b/pages/use-cases/headless-browsers.mdx @@ -82,7 +82,7 @@ Request an increase in the instance memory quota when you need more memory. When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash -kraft cloud deploy -p 443:3000 -M 4096 . +kraft cloud deploy -p 443:3000 -M 4Gi . ``` The output shows the instance address and other details: diff --git a/pages/use-cases/remote-ides.mdx b/pages/use-cases/remote-ides.mdx index f3db168f..27b30d07 100644 --- a/pages/use-cases/remote-ides.mdx +++ b/pages/use-cases/remote-ides.mdx @@ -78,9 +78,9 @@ kraft cloud deploy \ --scale-to-zero on \ --scale-to-zero-stateful \ --scale-to-zero-cooldown 4s \ - -M 2048 \ --name code-server \ -p 443:8443 \ + -M 2Gi \ -v code-workspace:/workspace \ -e PGUID=0 \ -e PGID=0 \ diff --git a/pages/use-cases/serverless-databases.mdx b/pages/use-cases/serverless-databases.mdx index 929c979d..702d39d3 100644 --- a/pages/use-cases/serverless-databases.mdx +++ b/pages/use-cases/serverless-databases.mdx @@ -69,7 +69,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash -kraft cloud deploy -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -M 1024 . +kraft cloud deploy -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -M 1Gi . ``` The output shows the instance address and other details: @@ -161,7 +161,7 @@ kraft cloud volume create --name postgres --size 200 Then start the PostgreSQL instance and mount that volume: ```console -kraft cloud deploy -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume -p 5432:5432/tls -M 1024 . +kraft cloud deploy -p 5432:5432/tls -M 1Gi -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume . ``` ### Customize your deployment From 3790b4a9dc9b1e14972bbb89ed8aa4170e607df0 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Mon, 22 Dec 2025 21:39:54 +0200 Subject: [PATCH 012/131] feat(features): Add ROMs feature Signed-off-by: Alex-Andrei Cioc --- .../config/vocabularies/Unikraft/accept.txt | 2 + pages/features/roms.mdx | 425 ++++++++++++++++++ 2 files changed, 427 insertions(+) create mode 100644 pages/features/roms.mdx diff --git a/.vale/styles/config/vocabularies/Unikraft/accept.txt b/.vale/styles/config/vocabularies/Unikraft/accept.txt index cdd951f3..ebf9f748 100644 --- a/.vale/styles/config/vocabularies/Unikraft/accept.txt +++ b/.vale/styles/config/vocabularies/Unikraft/accept.txt @@ -12,6 +12,7 @@ (?i)minimum (?i)namespaced? (?i)performant +(?i)ROM(s)? (?i)rootfs (?i)tokenizer (?i)unikraft @@ -49,6 +50,7 @@ Unikraft Cloud POSIX PV PVC +EROFS # ============================================================================== # NAMES OF THINGS diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx new file mode 100644 index 00000000..69fc85ff --- /dev/null +++ b/pages/features/roms.mdx @@ -0,0 +1,425 @@ +--- +title: ROMs +navigation_icon: hard-drive +--- + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +:::caution[Disclaimer] +The ROM feature isn't currently enabled for the public Unikraft Cloud offering. +As such, the [KraftKit CLI tool](/cli/) can't entirely leverage this feature. +For boxes where it's enabled, use it via the [Unikraft Cloud API](/api/platform/v1). +::: + +Unikraft Cloud supports the ability to attach **Read-Only Memory (ROM)** blobs to instances. +It allows you to create a general-purpose base image and then customize individual instances by attaching code or data as separate ROM blobs. +This enables quick deployment of custom functionality to preexisting language environments without rebuilding the entire image. + + +## Overview + +With ROMs, you can: + +- Deploy variations of an app from a single base image. +- Update app code without rebuilding the base image. +- Reduce image size and deployment time. + +The ROM workflow consists of two main components: + +1. **Base Image**: A general-purpose image containing the runtime environment (for example, Python interpreter, Node.js, etc.). +1. **ROM Blobs**: Separate, lightweight images containing your app code or any other data you want to customize. + +This separation allows you to maintain one base image while deploying many different instances with different data. + +:::note +The app running inside the base image is responsible to read the data from the attached ROM devices. +ROM blobs appear as block devices at paths like `/dev/ukp_rom`, where `` is the ROM name you specify when creating the instance. +::: + + +## Setup + +This example shows how to deploy Python functions using ROMs on Unikraft Cloud. +Ensure you have the `kraft` CLI installed and configured with your Unikraft Cloud account. +Set the following environment variables: + +```bash title="" +export UKC_USER="" +export UKC_TOKEN="" +export UKC_METRO="fra" # or your preferred metro +``` + +### Base Image + +First, create a base image with a Python HTTP server that loads and executes custom Python programs from a ROM. + + + + Dockerfile + Kraftfile + server.py + wrapper.sh + + +```dockerfile title="Dockerfile" +FROM python:3.12 AS build + +RUN set -xe; \ + /usr/sbin/ldconfig /usr/local/lib + +FROM scratch + +# Python binary +COPY --from=build /usr/local/bin/python3 /usr/bin/python3 + +# System binaries +COPY --from=build /usr/bin/mount /usr/bin/mount +COPY --from=build /usr/bin/sh /usr/bin/sh +COPY --from=build /usr/bin/mkdir /usr/bin/mkdir + +# System Libraries +COPY --from=build /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 +COPY --from=build /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/libm.so.6 +COPY --from=build /lib/x86_64-linux-gnu/libmount.so.1 /lib/x86_64-linux-gnu/libmount.so.1 +COPY --from=build /lib/x86_64-linux-gnu/libselinux.so.1 /lib/x86_64-linux-gnu/libselinux.so.1 +COPY --from=build /lib/x86_64-linux-gnu/libblkid.so.1 /lib/x86_64-linux-gnu/libblkid.so.1 +COPY --from=build /lib/x86_64-linux-gnu/libpcre2-8.so.0 /lib/x86_64-linux-gnu/libpcre2-8.so.0 +COPY --from=build /usr/lib/x86_64-linux-gnu/libz.so.1 /usr/lib/x86_64-linux-gnu/libz.so.1 +COPY --from=build /usr/lib/x86_64-linux-gnu/libcrypto.so.3 /usr/lib/x86_64-linux-gnu/libcrypto.so.3 + +# Dynamic linker / loader +COPY --from=build /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 +COPY --from=build /etc/ld.so.cache /etc/ld.so.cache + +# Python (and other) libraries +COPY --from=build /usr/local/lib /usr/local/lib + +# Python application +COPY ./wrapper.sh /wrapper.sh +COPY ./server.py /src/server.py +``` + + +```yaml title="Kraftfile" +spec: v0.6 + +runtime: base-compat:latest + +rootfs: ./Dockerfile + +cmd: [ "/wrapper.sh", "/usr/bin/python3", "/src/server.py" ] +``` + + +```python title="server.py" +import argparse +import importlib.util +import sys +from http.server import HTTPServer, BaseHTTPRequestHandler + +rom_module = None + +def load_rom_module(): + global rom_module + module_name = 'rom' + module_path = '/tmp/rom.py' + + spec = importlib.util.spec_from_file_location(module_name, module_path) + rom_module = importlib.util.module_from_spec(spec) + sys.modules[module_name] = rom_module + spec.loader.exec_module(rom_module) + +class MyServer(BaseHTTPRequestHandler): + global rom_module + def do_GET(self): + self.send_response(200) + self.send_header("Content-type", "text/html") + self.end_headers() + msg = rom_module.function() + self.wfile.write(bytes(msg, "utf-8")) + +def main(args): + load_rom_module() + server = HTTPServer((args.host, args.port), MyServer) + + print("starting server at %s:%s" % (args.host, args.port)) + + try: + server.serve_forever() + + except KeyboardInterrupt: + pass + + print("server stopped") + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("--host", type=str, default="0.0.0.0") + parser.add_argument("--port", type=int, default=8080) + return parser.parse_args() + +if __name__ == "__main__": + main(parse_args()) +``` + + +```bash title="wrapper.sh" +#!/usr/bin/sh + +/usr/bin/mkdir -p /tmp/ +/usr/bin/mount -t erofs /dev/ukp_rom_python_function.py /tmp/ +exec "$@" +``` + + + +Ensure that the `wrapper.sh` script is executable: + +```bash title="" +chmod a+x wrapper.sh +``` + +Package and push the base image: + +```bash title="" +kraft pkg \ + --plat kraftcloud \ + --arch x86_64 \ + --name index.unikraft.io/"$UKC_USER"/http-python:latest \ + --rootfs-type erofs \ + --push . +``` + +Wait a few seconds for propagation and check that the image is present: + +```bash title="" +kraft cloud image ls +``` + +{/* vale off */} +### ROM files +{/* vale on */} + +To showcase the benefits of using ROMs, create two files, each containing a Python function that the base image will load and execute. +Create a separate directory for each of the ROMs: + +```bash title="" +mkdir -p rom1/fs rom2/fs +``` + + + + rom 1 + Kraftfile 1 + rom 2 + Kraftfile 2 + + +```python title="rom1/fs/rom.py" +def function(): + return "Hi from 1st ROM!\n" +``` + + +```yaml title="rom1/Kraftfile" +spec: v0.6 + +roms: + - ./fs +``` + + +```python title="rom2/fs/rom.py" +def function(): + return "Hi from 2nd ROM!\n" +``` + + +```yaml title="rom2/Kraftfile" +spec: v0.6 + +roms: + - ./fs +``` + + + +Package and push the ROMs: + +```bash title="" +cd rom1/ +kraft pkg \ + --no-kernel \ + --plat kraftcloud \ + --arch x86_64 \ + --name index.unikraft.io/"$UKC_USER"/my-rom1:latest \ + --rootfs-type erofs \ + --push . + +cd ../rom2/ +kraft pkg \ + --no-kernel \ + --plat kraftcloud \ + --arch x86_64 \ + --name index.unikraft.io/"$UKC_USER"/my-rom2:latest \ + --rootfs-type erofs \ + --push . +``` + +Wait a few seconds for propagation and check that the ROMs are present: + +```bash title="" +kraft cloud image ls +``` + +:::tip +The `--no-kernel` flag tells `kraft` to package only the ROM files, without the kernel, since this is data that will get attached to another image. +::: + +:::caution +This example packages the ROMs as EROFS filesystems. +If packaging the ROMs as a cpio archives (that is, `--rootfs-type cpio`), or as standalone files, you must align their size to 4096 bytes. +::: + +### Services + +Create two services to expose your instances: + +```bash title="" +curl -X POST \ + -H "Authorization: Bearer ${UKC_TOKEN}" \ + -H "Content-Type: application/json" \ + "${UKC_METRO}/services" \ + -d "[ + { + 'name': 'test-http-python-rom1', + 'services': [ + { + 'port': 443, + 'destination_port': 8080, + 'handlers': ['tls', 'http'] + } + ], + 'domains': [ + { + 'name': 'test-http-python-rom1' + } + ] + }, + { + 'name': 'test-http-python-rom2', + 'services': [ + { + 'port': 443, + 'destination_port': 8080, + 'handlers': ['tls', 'http'] + } + ], + 'domains': [ + { + 'name': 'test-http-python-rom2' + } + ] + } + ]" +``` + +Check that the services are up: + +```bash title="" +kraft cloud service get test-http-python-rom1 +kraft cloud service get test-http-python-rom2 +``` + +### Instances + +Create two instances from the same base image and attach different ROMs: + +```bash title="" +curl -X POST \ + -H "Authorization: Bearer ${UKC_TOKEN}" \ + -H "Content-Type: application/json" \ + "${UKC_METRO}/instances" \ + -d "[ + { + 'name': 'test-http-python-rom1', + 'image': '${UKC_USER}/http-python:latest', + 'service_group': { + 'name': 'test-http-python-rom1' + }, + 'memory_mb': 512, + 'scale_to_zero': { + 'policy': 'on', + 'stateful': false, + 'cooldown_time_ms': 1000 + }, + 'autostart': true, + 'roms': [ + { + 'name': 'python_function.py', + 'image': '$UKC_USER/my-rom1:latest' + } + ] + }, + { + 'name': 'test-http-python-rom2', + 'image': '${UKC_USER}/http-python:latest', + 'service_group': { + 'name': 'test-http-python-rom2' + }, + 'memory_mb': 512, + 'scale_to_zero': { + 'policy': 'on', + 'stateful': false, + 'cooldown_time_ms': 1000 + }, + 'autostart': true, + 'roms': [ + { + 'name': 'python_function.py', + 'image': '$UKC_USER/my-rom2:latest' + } + ] + } + ]" +``` + +Check that the instances are up: + +```bash title="" +kraft cloud instance get test-http-python-rom1 +kraft cloud instance get test-http-python-rom2 +``` + +Note the `roms` array in the instances configurations. +Each ROM is available as a readable device at `/dev/ukp_rom_python_function.py` (in the form of an EROFS filesystem in this case), which the server program mounts at `/tmp/rom.py` and executes. + +### Testing + +Query the instances to call the Python function from the ROM. +You should see different responses: + +```console title="" +$ curl https://test-http-python-rom1.fra.kraft.cloud +Hi from 1st ROM! +``` + +```console title="" +$ curl https://test-http-python-rom2.fra.kraft.cloud +Hi from 2nd ROM! +``` + +### Cleanup + +When done, remove the instances and services: + +```bash title="" +kraft cloud instance rm test-http-python-rom1 test-http-python-rom2 +kraft cloud service rm test-http-python-rom1 test-http-python-rom2 +``` + +## Learn more + +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [instance create](/cli/instance/create) subcommand. +* Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the [instances API](/api/platform/v1/instances). +* The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images and ROMs. From 48f8bdc99efdc343b6c8f1b619238819e47108de Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Wed, 24 Dec 2025 19:01:20 +0200 Subject: [PATCH 013/131] chore(use-cases): Change navigation_icon of MCP Servers This commit changes the navigation icon that is displayed on the MCP Servers use case page to an icon representing a toolcase. This better aligns with the concept of "tools" that is relevant to this technology. Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/mcp-servers.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/use-cases/mcp-servers.mdx b/pages/use-cases/mcp-servers.mdx index 732f9fd5..823429d9 100644 --- a/pages/use-cases/mcp-servers.mdx +++ b/pages/use-cases/mcp-servers.mdx @@ -1,6 +1,6 @@ --- title: MCP Servers -navigation_icon: plug +navigation_icon: tool-case --- [MCP (Model Context Protocol)](https://modelcontextprotocol.io/docs/getting-started/intro) servers enable AI assistants and LLMs to access external tools, data sources, and capabilities in a standardized way. From e62709939f08fe79910467e85c4a23218334865d Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Mon, 12 Jan 2026 14:46:16 +0200 Subject: [PATCH 014/131] feat(pages): Add two new questions to FAQ Signed-off-by: Cezar Craciunoiu --- pages/faq.mdx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pages/faq.mdx b/pages/faq.mdx index 0c17363b..f65c88bc 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -207,3 +207,15 @@ Other unikernel projects exist, but most are research efforts, unmaintained, or #### Do you have a Terraform integration? [Yes!](https://github.com/unikraft-cloud/terraform-provider-ukc) + + +#### When should you use Kraftkit stable and/or staging? + +You should use stable versions when initially trying out the Unikraft Platform and its features. +Any time you encounter a problem, it's good to first try out the latest staging version before forwarding the problem as it might have been already fixed. +There's also a chance that Kraft staging contains changes available only on non-stable nodes. + + +#### What keywords does Kraftkit ignore from a Dockerfile? + +This is the current list of ignored keywords: EXPOSE, HEALTHCHECK, ONBUILD, SHELL, STOPSIGNAL, VOLUME. From 362d3a082c07a7902c95e249b8e53cd389cc8e8e Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Mon, 12 Jan 2026 17:23:30 +0200 Subject: [PATCH 015/131] chore: Disable linter for false positives Signed-off-by: Cezar Craciunoiu --- pages/faq.mdx | 2 ++ pages/platform/troubleshooting.mdx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pages/faq.mdx b/pages/faq.mdx index f65c88bc..d3a5ed10 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -218,4 +218,6 @@ There's also a chance that Kraft staging contains changes available only on non- #### What keywords does Kraftkit ignore from a Dockerfile? +{/* vale off */} This is the current list of ignored keywords: EXPOSE, HEALTHCHECK, ONBUILD, SHELL, STOPSIGNAL, VOLUME. +{/* vale on */} diff --git a/pages/platform/troubleshooting.mdx b/pages/platform/troubleshooting.mdx index 18296a41..7f7a1631 100644 --- a/pages/platform/troubleshooting.mdx +++ b/pages/platform/troubleshooting.mdx @@ -221,6 +221,7 @@ kraft cloud inst logs In case of a crash, you'll see a full crash output: +{/* vale off */} ```text title="" Powered by Unikraft Telesto (0.16.2~9c264902) [ 0.066949] CRIT: [libukvmem] Cannot handle write page fault at 0x1000bb8024 (ec: 0x2): -12 @@ -252,6 +253,7 @@ It looks like the instance exited fatally. To see more details about why, run: kraft cloud instance get http-python312-hb7ij ``` +{/* vale on */} Use the recommended command for detailed output. This yields output like: From 9a95f0a0689378c41fe51656d7b2b933c28c6c43 Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Mon, 12 Jan 2026 19:19:43 +0200 Subject: [PATCH 016/131] feat(pages): Add extra questions to FAQ Signed-off-by: Cezar Craciunoiu --- pages/faq.mdx | 64 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/pages/faq.mdx b/pages/faq.mdx index d3a5ed10..2959ee6f 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -218,6 +218,64 @@ There's also a chance that Kraft staging contains changes available only on non- #### What keywords does Kraftkit ignore from a Dockerfile? -{/* vale off */} -This is the current list of ignored keywords: EXPOSE, HEALTHCHECK, ONBUILD, SHELL, STOPSIGNAL, VOLUME. -{/* vale on */} +This is the current list of ignored keywords: `EXPOSE`, `HEALTHCHECK`, `ONBUILD`, `SHELL`, `STOPSIGNAL`, `VOLUME`. + + +#### How does the image size and memory relate to boot times? + +When using `CPIO`, there is a [strong correlation](/tutorials/rootfs-formats) between the image size and the boot time. +This is because it needs to load the whole image into memory first. + +When using `EROFS`, there is no such correlation, as the operating system loads pages directly from disk, on demand. + +At the same time, there is a slight correlation between big memory allocations and higher boot times, though not significant. +This is irrespective of the file system used. + + +#### What's the key difference between cold boots and warm boots? + +End-result wise, cold and warm boots are no different, the instance still works. +The server handles the request in both cases if the app is stateless. +The main difference appears in [stateful](/features/snapshots) apps and when considering latency, hence the `--scale-to-zero-stateful` flag. + +A cold boot equates to starting the instance every time and then stopping it if no traffic hit it for a while. + +A warm boot resembles the suspend and resume operations in virtual machines. +The platform saves the system memory to disk and loads it when a request comes. + +Warm boots offer clear advantages over cold boots, having lower boot times, no setup time, and are better in general, with the trade off of using space on the disk. +Thus, for most use cases, using [stateful scale-to-zero](/features/scale-to-zero#stateful-scale-to-zero) is the better alternative. + +Cases exist where short lived VMs are small enough to have a small boot time, but they use a lot of memory. +In this case it might be better to use cold boots, to use disk efficiently. +This should be first experimented or discussed with a Unikraft Engineer to verify it. + + +#### What can you push as an image? + +An image is specifically a pair of a kernel and a rootfs bundled together as different layers of an OCI package. +To keep things light, certain optimizations are in place to not repush existing kernels and to reuse them from your account. +If these aren't automatically detected, kraft pushes the kernel again. + +At the same time, things like ROMs use the same packaging systems, but push images with a missing kernel and only a rootfs. +These have specific metadata that identifies them as ROMs. + +Finally, kernels can also run without a rootfs. +They don't do anything, but support exists to run them. + + +#### How to replicate the `ENV`/`ENTRYPOINT` of a container? + +To reproduce the starting environment without specifying extra arguments in the command line you can replace your Kraftfile's `cmd:` with the path to a script. +In there you can place all `ENV`s from the dockerfile and call the binary as you want. +You can also use the `env:` field in the Kraftfile. + +When building a rootfs directly from a DockerHub image, or a `Dockerfile` which starts from a DockerHub image, you should inspect the environment set by said image (example with `library/node`): + +```bash +docker inspect library/node --format='{{json .Config.Env}}' | jq +``` + +If you are using the Unikraft OS, you need to specify those in the command like with `--env`. + +Note: `ENV` and `ENTRYPOINT` are recognised keywords in the Dockerfile so they should propagate up into the image. From 1d8c1912aac101e4716481353b27e879c5a5945a Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Tue, 13 Jan 2026 17:00:30 +0200 Subject: [PATCH 017/131] fix(pages): Mention that 'ENV' is not supported Signed-off-by: Cezar Craciunoiu --- pages/faq.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pages/faq.mdx b/pages/faq.mdx index 2959ee6f..44637b12 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -220,6 +220,7 @@ There's also a chance that Kraft staging contains changes available only on non- This is the current list of ignored keywords: `EXPOSE`, `HEALTHCHECK`, `ONBUILD`, `SHELL`, `STOPSIGNAL`, `VOLUME`. +Currently, `kraft` parses the `ENV` keyword, but the platform discards the result in the current stable version. #### How does the image size and memory relate to boot times? @@ -278,4 +279,4 @@ docker inspect library/node --format='{{json .Config.Env}}' | jq If you are using the Unikraft OS, you need to specify those in the command like with `--env`. -Note: `ENV` and `ENTRYPOINT` are recognised keywords in the Dockerfile so they should propagate up into the image. +Note: `ENTRYPOINT` is a recognised keyword in the Dockerfile so it should propagate up into the image. From c1793712425f65cf62a99ed54d01055078ffa3a2 Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Tue, 13 Jan 2026 13:04:32 +0200 Subject: [PATCH 018/131] feat(pages): Add tutorial for comparing CPIO with EROFS Signed-off-by: Cezar Craciunoiu --- pages/tutorials/rootfs-formats.mdx | 103 +++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 pages/tutorials/rootfs-formats.mdx diff --git a/pages/tutorials/rootfs-formats.mdx b/pages/tutorials/rootfs-formats.mdx new file mode 100644 index 00000000..0545ac7e --- /dev/null +++ b/pages/tutorials/rootfs-formats.mdx @@ -0,0 +1,103 @@ +--- +title: Rootfs Formats +navigation_icon: book +--- + +Every virtual machine consists of at least two components: a kernel, and a root file system. +This tutorial focuses on the latter, the rootfs (also known as initrd). + +Currently, on the Unikraft Cloud platform, two types of file systems are usable: `CPIO` (Copy In, Copy Out) and `EROFS` (Enhanced Read-Only File System). +`CPIO` (Copy In, Copy Out) and `EROFS` are packaging formats used by the Kernel to load a simple file system right before finishing setting up. +They contain the same files and result in the same file contents upon unpacking. +They consist mainly of metadata and file content without any advanced formatting to keep them as simple as possible. + +The CLI tool offers both formats for direct usage when packaging. +Already packaged archives with external tools are also usable (for example `mkfs.erofs`, `cpio`, `bsdcpio`). +If provided as a file, the CLI tool passes the file in as is, without any extra formatting. +Right now the default for the CLI tool is `cpio` with `erofs` being an alternative, as the former is simpler, widely adoped, and better tested. + +Main difference between the two is performance-wise. +`CPIO` is a simple format which translates in the need to read and unpack the archive first into memory. +This extra step means more time spent booting, and more memory used. +`EROFS` mitigates this behaviour if correctly formatted. +It allows kernels to directly map the archive contents into memory. +This behaviour, called `DAX` (Direct Access), is especially beneficial if the platform enables the feature to share rootfs memory (not on public metros). + +These two features combined lead to less memory used (use only what you need, and when you need it). +They also decrease used memory (100 instances will unpack their rootfs only once). +Boot time also goes down as the instance spends less time on unpacking images. + +After unpacking there is no content difference between the two, but metadata stored is different. +It also differs from implementation to implementation, though the only downside to less space-efficient implementations is the time it takes to push the image. +Below there are four different methods of packing the rootfs: +```console title="Filesystem Packing Formats" +$ du -hs * +755M initrd # Directory unpacked +751M kraft_cpio # CPIO packed with kraft +757M kraft_erofs # EROFS packed with kraft +751M mkfs_cpio # CPIO packed with cpio +754M mkfs_erofs # EROFS packed with mkfs.erofs +``` + +All packing methods slightly decrease the size. +The kraft implementation is almost identical to the cpio reference one, `CPIO` wise. +For `EROFS`, kraft generates images that are slightly bigger, but makes up with its ease of use. +Also, all `EROFS` images are slightly larger as they contain more metadata for each file and files must align. +All images result in the same files after unpacking, with the advantages mentioned earlier. + +Below are two attempts at starting the same image. +The kraft tool packs the first one in the `EROFS` format, the latter in the `CPIO` format. +```console title="Create Instance EROFS" +$ kraft cloud instance create \ + -p 443:8080 \ + -M 900Mi \ + --start \ + demo/node-playwright-chromium +[●] Deployed successfully! + β”‚ + β”œβ”€β”€β”€β”€β”€β”€ name: node-playwright-chromium-q9ynl + β”œβ”€β”€β”€β”€β”€β”€ uuid: cb7a1770-6d6a-4f53-a98a-f021ae796313 + β”œβ”€β”€β”€β”€β”€ metro: fra + β”œβ”€β”€β”€β”€β”€ state: running + β”œβ”€β”€β”€β”€ domain: https://proud-dream-udqhbav3.fra.unikraft.app + β”œβ”€β”€β”€β”€β”€ image: demo/node-playwright-chromium@sha256:056d5daa3e0f8a91ac18930a9a7714203515a6fae1244b1ecea831f64f593e79 + β”œβ”€ boot time: 191.55 ms + β”œβ”€β”€β”€β”€ memory: 900 MiB + β”œβ”€β”€β”€ service: proud-dream-udqhbav3 + β”œ private ip: 10.0.3.133 + └────── args: /usr/bin/wrapper.sh /usr/bin/node /app/server.js + +$ curl https://proud-dream-udqhbav3.fra.unikraft.app +Nothing to do. +``` + +```console title="Create Instance CPIO" +$ kraft cloud instance create \ + -p 443:8080 \ + -M 2400Mi \ + --start \ + demo/node-playwright-chromium +[●] Deployed successfully! + β”‚ + β”œβ”€β”€β”€β”€β”€β”€β”€ name: node-playwright-chromium-4rrxr + β”œβ”€β”€β”€β”€β”€β”€β”€ uuid: aeff2d28-d718-4068-9e24-4e2bb203022c + β”œβ”€β”€β”€β”€β”€β”€ metro: fra + β”œβ”€β”€β”€β”€β”€β”€ state: starting + β”œβ”€β”€β”€β”€β”€ domain: https://dry-fire-vhmh9z8u.fra.unikraft.app + β”œβ”€β”€β”€β”€β”€β”€ image: demo/node-playwright-chromium@sha256:57d1773398bc6d4ff94f063d6e9b7400dca66171d04ce78cd8a45789ba0a7d93 + β”œβ”€β”€β”€β”€β”€ memory: 2400 MiB + β”œβ”€β”€β”€β”€ service: dry-fire-vhmh9z8u + β”œβ”€ private ip: 10.0.3.133 + └─────── args: /usr/bin/wrapper.sh /usr/bin/node /app/server.js + +$ curl https://dry-fire-vhmh9z8u.fra.unikraft.app +Nothing to do. +``` +The `EROFS` case requires at least 900MiB to work, and the `CPIO` case requires 2400MiB. +This makes sense and you can derive this mathematically. +In the `CPIO` case the kernel needs to first map the archive in memory and then unarchive it. +In this case the `CPIO` has around 750MiB which means the instance needs at least 1500MiB more RAM compared to `EROFS`. +Adding 1500MiB to the 900MiB gives 2400MiB which is exactly the amount of memory needed in order for the instance to respond. +Finally, related to boot times, both cases have similar warm boot times, but the extra copies mentioned increase the cold boot time in the `CPIO` case. + +All in all, using `EROFS` is recommended in every case where possible, as the upsides definitely outweigh the small downsides. From 83fc88e0de7c0511c5f3d69818301d9efca732a0 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 13 Jan 2026 15:11:11 +0200 Subject: [PATCH 019/131] feat(pages/tutorial): Add more in-depth explanations Signed-off-by: Alex-Andrei Cioc --- .../config/vocabularies/Unikraft/accept.txt | 1 + pages/tutorials/rootfs-formats.mdx | 190 ++++++++++-------- 2 files changed, 108 insertions(+), 83 deletions(-) diff --git a/.vale/styles/config/vocabularies/Unikraft/accept.txt b/.vale/styles/config/vocabularies/Unikraft/accept.txt index ebf9f748..a7a88c77 100644 --- a/.vale/styles/config/vocabularies/Unikraft/accept.txt +++ b/.vale/styles/config/vocabularies/Unikraft/accept.txt @@ -51,6 +51,7 @@ POSIX PV PVC EROFS +CPIO # ============================================================================== # NAMES OF THINGS diff --git a/pages/tutorials/rootfs-formats.mdx b/pages/tutorials/rootfs-formats.mdx index 0545ac7e..e3c71f3a 100644 --- a/pages/tutorials/rootfs-formats.mdx +++ b/pages/tutorials/rootfs-formats.mdx @@ -1,103 +1,127 @@ --- title: Rootfs Formats -navigation_icon: book +navigation_icon: files --- Every virtual machine consists of at least two components: a kernel, and a root file system. -This tutorial focuses on the latter, the rootfs (also known as initrd). +This tutorial focuses on the latter, the **rootfs** (also known as initrd). -Currently, on the Unikraft Cloud platform, two types of file systems are usable: `CPIO` (Copy In, Copy Out) and `EROFS` (Enhanced Read-Only File System). -`CPIO` (Copy In, Copy Out) and `EROFS` are packaging formats used by the Kernel to load a simple file system right before finishing setting up. -They contain the same files and result in the same file contents upon unpacking. +Currently, on the Unikraft Cloud platform, two types of file system archives are usable: `CPIO` (Copy In, Copy Out) and `EROFS` (Enhanced Read-Only File System). +They're packaging formats used for loading the root file system in the instance. They consist mainly of metadata and file content without any advanced formatting to keep them as simple as possible. +The kernel loads and mounts the data from them at boot time. -The CLI tool offers both formats for direct usage when packaging. -Already packaged archives with external tools are also usable (for example `mkfs.erofs`, `cpio`, `bsdcpio`). -If provided as a file, the CLI tool passes the file in as is, without any extra formatting. -Right now the default for the CLI tool is `cpio` with `erofs` being an alternative, as the former is simpler, widely adoped, and better tested. - -Main difference between the two is performance-wise. -`CPIO` is a simple format which translates in the need to read and unpack the archive first into memory. -This extra step means more time spent booting, and more memory used. -`EROFS` mitigates this behaviour if correctly formatted. -It allows kernels to directly map the archive contents into memory. -This behaviour, called `DAX` (Direct Access), is especially beneficial if the platform enables the feature to share rootfs memory (not on public metros). - -These two features combined lead to less memory used (use only what you need, and when you need it). -They also decrease used memory (100 instances will unpack their rootfs only once). -Boot time also goes down as the instance spends less time on unpacking images. - -After unpacking there is no content difference between the two, but metadata stored is different. -It also differs from implementation to implementation, though the only downside to less space-efficient implementations is the time it takes to push the image. -Below there are four different methods of packing the rootfs: -```console title="Filesystem Packing Formats" -$ du -hs * -755M initrd # Directory unpacked -751M kraft_cpio # CPIO packed with kraft -757M kraft_erofs # EROFS packed with kraft -751M mkfs_cpio # CPIO packed with cpio -754M mkfs_erofs # EROFS packed with mkfs.erofs -``` +## Getting started + +The main difference between the rootfs formats is performance-wise. + +### CPIO + +`CPIO` is a simple format which translates in the need to copy and unpack the entire archive into guest memory when starting the instance. +This incurs a double memory usage during boot time, as the archive is first loaded into memory, then unpacked into a ramfs for the kernel to load. +At runtime, the guest can reclaim the initial memory allocated for the archive, and will only use the unpacked ramfs. +The boot times will still proportionally increase with the size of the `CPIO` archive. +Another consequence of using a `CPIO` initrd is that [snapshots](/features/snapshots) must include them, since Unikraft Cloud can't track where they're stored in guest memory. + +### EROFS + +`EROFS` wins on startup efficiency by not needing to unpack the archive at all into guest memory. +This means that you don't need to accomodate for double the memory usage during boot time, and boot times are faster as well. + +Another significant benefit of `EROFS` (although not available yet on public metros) is that Unikraft Cloud can enable `DAX` (Direct Access) on instances using `EROFS` rootfs. +This means that the host side loads the initrd, and the guest gets a map (**not a copy**) of it into its memory. +Thus, boot times aren't affected by the size of the rootfs at all. +Memory usage is also drastically reduced at boot, and only increases as the guest accesses files. +This also means that snapshots can exclude the original initrd. +Writing to the rootfs is still possible, because Unikraft Cloud uses **overlayfs** to mount the ramfs. +Any file changes are present in the snapshot. +Finally, `DAX` enables sharing the same rootfs image between many instances, increasing scalability. + +## Packaging the Rootfs + +The [KraftKit CLI tool](/cli/) supports both formats out of the box. +With it, you can package a rootfs from these sources: +- a simple file +- a directory +- a Dockerfile +- a remote OCI image + +If provided as a file, the CLI tool passes the file as-is, without any extra packaging. +Otherwise, you need to package the rootfs into a supported format (either `CPIO` or `EROFS`). +Already packaged archives with external tools (for example `mkfs.erofs`, `cpio`, `bsdcpio`) are also usable. +Right now the default format for the CLI tool is `CPIO`, with `EROFS` being an alternative, as the former is simpler, widely adoped, and better tested. +It's worth mentioning that after unpacking, there is no difference in the produced file contents between the formats. +They may only differ metadata-wise, depending on the implementation. +You may observe that a `CPIO` archive is typically smaller on disk than an `EROFS` one. +The only effect this has is on the time it takes to push the image. + +Below are two attempts at creating and starting an instance from the same [image](https://github.com/unikraft-cloud/examples/tree/main/node-playwright-chromium), packaged using both formats. -All packing methods slightly decrease the size. -The kraft implementation is almost identical to the cpio reference one, `CPIO` wise. -For `EROFS`, kraft generates images that are slightly bigger, but makes up with its ease of use. -Also, all `EROFS` images are slightly larger as they contain more metadata for each file and files must align. -All images result in the same files after unpacking, with the advantages mentioned earlier. +### EROFS deployment -Below are two attempts at starting the same image. -The kraft tool packs the first one in the `EROFS` format, the latter in the `CPIO` format. -```console title="Create Instance EROFS" -$ kraft cloud instance create \ +```bash +kraft cloud instance create \ -p 443:8080 \ -M 900Mi \ --start \ demo/node-playwright-chromium -[●] Deployed successfully! - β”‚ - β”œβ”€β”€β”€β”€β”€β”€ name: node-playwright-chromium-q9ynl - β”œβ”€β”€β”€β”€β”€β”€ uuid: cb7a1770-6d6a-4f53-a98a-f021ae796313 - β”œβ”€β”€β”€β”€β”€ metro: fra - β”œβ”€β”€β”€β”€β”€ state: running - β”œβ”€β”€β”€β”€ domain: https://proud-dream-udqhbav3.fra.unikraft.app - β”œβ”€β”€β”€β”€β”€ image: demo/node-playwright-chromium@sha256:056d5daa3e0f8a91ac18930a9a7714203515a6fae1244b1ecea831f64f593e79 - β”œβ”€ boot time: 191.55 ms - β”œβ”€β”€β”€β”€ memory: 900 MiB - β”œβ”€β”€β”€ service: proud-dream-udqhbav3 - β”œ private ip: 10.0.3.133 - └────── args: /usr/bin/wrapper.sh /usr/bin/node /app/server.js - -$ curl https://proud-dream-udqhbav3.fra.unikraft.app -Nothing to do. ``` -```console title="Create Instance CPIO" -$ kraft cloud instance create \ +```ansi title="Create Instance EROFS" +[●] Deployed successfully! + β”‚ + β”œ────────── name: node-playwright-chromium-q9ynl + β”œ────────── uuid: cb7a1770-6d6a-4f53-a98a-f021ae796313 + β”œ───────── metro: fra + β”œ───────── state: running + β”œ──────── domain: https://proud-dream-udqhbav3.fra.unikraft.app + β”œ───────── image: demo/node-playwright-chromium@sha256:056d5daa3e0f8a91ac18930a9a7714203515a6fae1244b1ecea831f64f593e79 + β”œ───── boot time: 191.55 ms + β”œ──────── memory: 900 MiB + β”œ─────── service: proud-dream-udqhbav3 + β”œ──── private ip: 10.0.3.133 + β””────────── args: /usr/bin/wrapper.sh /usr/bin/node /app/server.js +``` + +### CPIO deployment + +```bash +kraft cloud instance create \ -p 443:8080 \ - -M 2400Mi \ + -M 900Mi \ --start \ demo/node-playwright-chromium -[●] Deployed successfully! - β”‚ - β”œβ”€β”€β”€β”€β”€β”€β”€ name: node-playwright-chromium-4rrxr - β”œβ”€β”€β”€β”€β”€β”€β”€ uuid: aeff2d28-d718-4068-9e24-4e2bb203022c - β”œβ”€β”€β”€β”€β”€β”€ metro: fra - β”œβ”€β”€β”€β”€β”€β”€ state: starting - β”œβ”€β”€β”€β”€β”€ domain: https://dry-fire-vhmh9z8u.fra.unikraft.app - β”œβ”€β”€β”€β”€β”€β”€ image: demo/node-playwright-chromium@sha256:57d1773398bc6d4ff94f063d6e9b7400dca66171d04ce78cd8a45789ba0a7d93 - β”œβ”€β”€β”€β”€β”€ memory: 2400 MiB - β”œβ”€β”€β”€β”€ service: dry-fire-vhmh9z8u - β”œβ”€ private ip: 10.0.3.133 - └─────── args: /usr/bin/wrapper.sh /usr/bin/node /app/server.js - -$ curl https://dry-fire-vhmh9z8u.fra.unikraft.app -Nothing to do. ``` -The `EROFS` case requires at least 900MiB to work, and the `CPIO` case requires 2400MiB. -This makes sense and you can derive this mathematically. -In the `CPIO` case the kernel needs to first map the archive in memory and then unarchive it. -In this case the `CPIO` has around 750MiB which means the instance needs at least 1500MiB more RAM compared to `EROFS`. -Adding 1500MiB to the 900MiB gives 2400MiB which is exactly the amount of memory needed in order for the instance to respond. -Finally, related to boot times, both cases have similar warm boot times, but the extra copies mentioned increase the cold boot time in the `CPIO` case. - -All in all, using `EROFS` is recommended in every case where possible, as the upsides definitely outweigh the small downsides. + +```ansi title="Create Instance CPIO" +[●] Deployed successfully! + β”‚ + β”œ────────── name: node-playwright-chromium-4rrxr + β”œ────────── uuid: aeff2d28-d718-4068-9e24-4e2bb203022c + β”œ───────── metro: fra + β”œ───────── state: running + β”œ──────── domain: https://dry-fire-vhmh9z8u.fra.unikraft.app + β”œ───────── image: demo/node-playwright-chromium@sha256:57d1773398bc6d4ff94f063d6e9b7400dca66171d04ce78cd8a45789ba0a7d93 + β”œ───── boot time: 607.34 ms + β”œ──────── memory: 2400 MiB + β”œ─────── service: dry-fire-vhmh9z8u + β”œ──── private ip: 10.0.3.133 + β””────────── args: /usr/bin/wrapper.sh /usr/bin/node /app/server.js +``` + +The packaged archives have a size of around 750MiB each. +The `EROFS`-packaged instance requires at least 900MiB to work, and the `CPIO` one requires 2400MiB. +Simple arithmetic backs this. +In the `CPIO` case, the kernel gets a copy of the archive in memory and needs to remove it into ramfs. +This extraction process requires double the memory of the archive size. +This means the instance needs at least an extra 750x2=1500MiB of memory compared to `EROFS` to boot. +Finally, related to boot times, both cases have similar [warm boot](/features/snapshots) times, but the extra copies mentioned increase the cold boot time in the `CPIO` case. + +## Conclusion + +Bottom-line is, using `EROFS` is recommended in every case where possible, as the upsides definitely outweigh the small downsides. + +## Learn more + +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. From cac4c56fc8be514f6361c44a3b4fb4a889bc88dc Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Tue, 13 Jan 2026 19:07:38 +0200 Subject: [PATCH 020/131] feat(tutorials): Add tutorial for running rootless Signed-off-by: Cezar Craciunoiu --- pages/tutorials/rootless.mdx | 106 +++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 pages/tutorials/rootless.mdx diff --git a/pages/tutorials/rootless.mdx b/pages/tutorials/rootless.mdx new file mode 100644 index 00000000..7144e95e --- /dev/null +++ b/pages/tutorials/rootless.mdx @@ -0,0 +1,106 @@ +--- +title: Rootless Instances +navigation_icon: user-lock +--- + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +Unikraft Cloud instances use the `root` user by default when nothing specific sets it. +Because Unikraft Cloud images assume a single user, and set ownership accordingly, there can be inconsistencies between the expected result and the actual result permission-wise. + +## Getting started + +:::caution[Disclaimer] +This tutorial assumes that you need/want to create your own user inside the Unikraft Cloud instance. +If you are actually looking to convert a Docker image to run inside Unikraft Cloud, please refer to the [Docker to Unikraft Cloud tutorial](/tutorials/docker-to-unikraft-cloud) instead. +::: + +To get different users to work inside Unikraft Cloud instances you need to do some configuration changes to your deployment process. +The usual flow is to package your rootfs using either a `Dockerfile` or some other sources (for example, a file, a directory or an OCI image). +Thus, you would either create your user inside the `Dockerfile` or use a wrapper script that would create the user before starting your main app. +The workflow would be as follows: + +1. Create the user and register it: + + + + Dockerfile + Script + + + ```dockerfile + # ... + + ARG USER_ID=1000 + ARG GROUP_ID=1000 + ARG USERNAME=appuser + + # Create group and user + RUN groupadd --gid $GROUP_ID $USERNAME \ + && useradd --uid $USER_ID --gid $GROUP_ID -m -s /bin/bash $USERNAME + + # Copy files and set ownership + COPY --chown=$USERNAME:$USERNAME . /app + + # Switch to the non-root user before doing other operations + USER $USERNAME + + # ... + ``` + + + ```bash + #!/bin/bash + + set -e + + USER_ID=1000 + GROUP_ID=1000 + USERNAME=appuser + + # Create group and user + groupadd --gid $GROUP_ID $USERNAME + useradd --uid $USER_ID --gid $GROUP_ID -m -s /bin/bash $USERNAME + + # Change ownership of app files + chown -R $USERNAME:$USERNAME /app + + # ... + ``` + + + + Keep in mind that `useradd` and `groupadd` might not be available in all base images. + For example, if you are using `alpine` as a base image (which comes with BusyBox), you would need to use `adduser` and `addgroup` instead. + +1. Depending on how you [package your rootfs](/tutorials/rootfs-formats), you might need specific options: + + * (EROFS) Use the `--keep-file-owners` when packaging the rootfs as EROFS (that is, `kraft pkg ... --rootfs-type erofs --keep-file-owners ...`). + + * (CPIO) You shouldn't use CPIO as the rootfs type if you need user support. + You **can't** preserve user IDs when packaging as CPIO. + +1. Before running the app, switch to the new user and make sure to preserve the environment in your entrypoint script: + + ```bash + su -m appuser + ``` + +If your environment variables are correctly set, after doing the steps above you should be running things as a different user. +You can check this by running the following command before starting your main app: + +```bash +whoami +``` + +## Conclusion + +Users are a consacrated way of reducing capabilities and for Unikraft Cloud this is no different. +You can already enhance security of your deployments with the reduced attack surface of unikernels, as well as isolation through virtualization. +You can further reduce the impact of a potential compromise by running as a non-root user. +Furthermore, for quick deployments (for example, converting an existing Docker image to Unikraft Cloud), running as a non-root user is often expected from the original image. + +## Learn more + +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. \ No newline at end of file From 28d7c1046fa7b5887812972f1e75d24b476b8261 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 13 Jan 2026 22:36:48 +0200 Subject: [PATCH 021/131] fix(rootfs-formats): Add missing --rootfs-type flags Signed-off-by: Alex-Andrei Cioc --- pages/tutorials/rootfs-formats.mdx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pages/tutorials/rootfs-formats.mdx b/pages/tutorials/rootfs-formats.mdx index e3c71f3a..8255b199 100644 --- a/pages/tutorials/rootfs-formats.mdx +++ b/pages/tutorials/rootfs-formats.mdx @@ -60,10 +60,11 @@ Below are two attempts at creating and starting an instance from the same [image ### EROFS deployment ```bash -kraft cloud instance create \ +kraft cloud deploy \ -p 443:8080 \ -M 900Mi \ - --start \ + --rootfs-type erofs \ + --keep-file-owners \ demo/node-playwright-chromium ``` @@ -86,10 +87,10 @@ kraft cloud instance create \ ### CPIO deployment ```bash -kraft cloud instance create \ +kraft cloud deploy \ -p 443:8080 \ -M 900Mi \ - --start \ + --rootfs-type cpio \ demo/node-playwright-chromium ``` From 7efa50a37be638c3b688e20ed00e9775229130ca Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Mon, 19 Jan 2026 12:52:40 +0200 Subject: [PATCH 022/131] feat(faq): Add question about running on Unikraft/Tinyx Signed-off-by: Cezar Craciunoiu --- pages/faq.mdx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pages/faq.mdx b/pages/faq.mdx index 44637b12..4fce407f 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -280,3 +280,17 @@ docker inspect library/node --format='{{json .Config.Env}}' | jq If you are using the Unikraft OS, you need to specify those in the command like with `--env`. Note: `ENTRYPOINT` is a recognised keyword in the Dockerfile so it should propagate up into the image. + +#### How to tell if an app can run in the Unikraft kernel or TinyX? + +No exact suite can determine if your app can run on one or another. + +Tinyx is a slimmed down Linux Kernel, which means that most cloud-compatible apps work out of the box as long as it has all files available. +Some virtual devices and virtual file system entries are missing, but you can contact a Unikraft staff member to look into adding them. + +If your app successfully runs on TinyX and Unikraft Cloud, you have the option to also try running it on the Unikraft operating system. +This kernel removes even more unused features so the chance that the app isn't compatible increases, but the performance and boot times are better. +For example, if your app uses extensive process cloning, it has a low chance to work on the Unikraft kernel, as it supports running a single process at a time. +Other examples of unsupported formats are 32bit executables and non-`PIE` (Position Independent Executable) executables, as the Unikraft kernel can't load them in memory at the moment. + +Other small differences exist, which you should report to the Unikraft Team for fixing, as the Unikraft kernel tries to follow Linux and the POSIX format. From 378f6651d70d20bcc93db84818e4d740557d7f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Rasc=C3=B3n?= Date: Thu, 22 Jan 2026 17:48:04 +0100 Subject: [PATCH 023/131] fix(docs): Change /install to /docs/introduction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: JesΓΊs RascΓ³n --- pages/guides/bun.mdx | 2 +- pages/guides/caddy.mdx | 2 +- pages/guides/cpp-boost.mdx | 2 +- pages/guides/cpp.mdx | 2 +- pages/guides/django.mdx | 2 +- pages/guides/dotnet.mdx | 2 +- pages/guides/dragonfly.mdx | 2 +- pages/guides/duckdb.mdx | 2 +- pages/guides/elixir.mdx | 2 +- pages/guides/erlang.mdx | 2 +- pages/guides/ferretdb.mdx | 2 +- pages/guides/flask-sqlite.mdx | 2 +- pages/guides/flask.mdx | 2 +- pages/guides/go.mdx | 2 +- pages/guides/grafana.mdx | 2 +- pages/guides/haproxy.mdx | 2 +- pages/guides/hugo.mdx | 2 +- pages/guides/imaginary.mdx | 2 +- pages/guides/java.mdx | 2 +- pages/guides/llama2.mdx | 2 +- pages/guides/lua.mdx | 2 +- pages/guides/mariadb.mdx | 2 +- pages/guides/memcached.mdx | 2 +- pages/guides/minio.mdx | 2 +- pages/guides/mongodb.mdx | 2 +- pages/guides/nextjs.mdx | 2 +- pages/guides/nginx.mdx | 2 +- pages/guides/node.mdx | 2 +- pages/guides/opentelemetry-collector.mdx | 2 +- pages/guides/perl.mdx | 2 +- pages/guides/php.mdx | 2 +- pages/guides/postgres.mdx | 2 +- pages/guides/prisma.mdx | 2 +- pages/guides/puppeteer.mdx | 2 +- pages/guides/python.mdx | 2 +- pages/guides/rails.mdx | 2 +- pages/guides/redis.mdx | 2 +- pages/guides/remix.mdx | 2 +- pages/guides/ruby.mdx | 2 +- pages/guides/rust-actix.mdx | 2 +- pages/guides/rust-rocket.mdx | 2 +- pages/guides/rust-tokio.mdx | 2 +- pages/guides/skipper.mdx | 2 +- pages/guides/solidjs.mdx | 2 +- pages/guides/spin.mdx | 2 +- pages/guides/springboot.mdx | 2 +- pages/guides/sveltekit.mdx | 2 +- pages/guides/traefik.mdx | 2 +- pages/guides/tyk.mdx | 2 +- pages/guides/wazero.mdx | 2 +- pages/guides/wordpress.mdx | 2 +- 51 files changed, 51 insertions(+), 51 deletions(-) diff --git a/pages/guides/bun.mdx b/pages/guides/bun.mdx index 18d18636..085df88c 100644 --- a/pages/guides/bun.mdx +++ b/pages/guides/bun.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a Bun app. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/bun` directory: diff --git a/pages/guides/caddy.mdx b/pages/guides/caddy.mdx index 69f1dac3..6f6235df 100644 --- a/pages/guides/caddy.mdx +++ b/pages/guides/caddy.mdx @@ -9,7 +9,7 @@ Caddy can be used with Unikraft / Unikraft Cloud to serve static web content. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/caddy/` directory: diff --git a/pages/guides/cpp-boost.mdx b/pages/guides/cpp-boost.mdx index 02da7c26..c1ae33a4 100644 --- a/pages/guides/cpp-boost.mdx +++ b/pages/guides/cpp-boost.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a C++-based HTTP web server using the [Boost](https://www.boost.org/) libraries. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 2. Clone the [example repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-cpp-boost/` directory: diff --git a/pages/guides/cpp.mdx b/pages/guides/cpp.mdx index ac03cf39..022ca070 100644 --- a/pages/guides/cpp.mdx +++ b/pages/guides/cpp.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple C++-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 2. Clone the [example repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-cpp/` directory: diff --git a/pages/guides/django.mdx b/pages/guides/django.mdx index 2b3fba56..0275ce92 100644 --- a/pages/guides/django.mdx +++ b/pages/guides/django.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a Python Django web app. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-python3.12-django5.0/` directory: diff --git a/pages/guides/dotnet.mdx b/pages/guides/dotnet.mdx index 0b07bab0..613c2104 100644 --- a/pages/guides/dotnet.mdx +++ b/pages/guides/dotnet.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple .NET-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-dotnet8.0/` directory: diff --git a/pages/guides/dragonfly.mdx b/pages/guides/dragonfly.mdx index 84960a64..41e3c78e 100644 --- a/pages/guides/dragonfly.mdx +++ b/pages/guides/dragonfly.mdx @@ -8,7 +8,7 @@ This guides shows you how to deploy [Dragonfly](https://www.dragonflydb.io/), a To run it example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/dragonflydb/` directory: diff --git a/pages/guides/duckdb.mdx b/pages/guides/duckdb.mdx index 85f4ee15..a3d75bc9 100644 --- a/pages/guides/duckdb.mdx +++ b/pages/guides/duckdb.mdx @@ -8,7 +8,7 @@ This guide shows you how to use [DuckDB](https://duckdb.org), an in-process SQL To run it example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/duckdb-go/` directory: diff --git a/pages/guides/elixir.mdx b/pages/guides/elixir.mdx index 3778d9bd..8450f7e3 100644 --- a/pages/guides/elixir.mdx +++ b/pages/guides/elixir.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Elixir-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-elixir1.16/` directory: diff --git a/pages/guides/erlang.mdx b/pages/guides/erlang.mdx index 2fa970a0..3ed05c00 100644 --- a/pages/guides/erlang.mdx +++ b/pages/guides/erlang.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Erlang-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-erlang26.2/` directory: diff --git a/pages/guides/ferretdb.mdx b/pages/guides/ferretdb.mdx index 94474002..fe155440 100644 --- a/pages/guides/ferretdb.mdx +++ b/pages/guides/ferretdb.mdx @@ -8,7 +8,7 @@ This guide shows you how to use [FerretDB](https://www.ferretdb.com/) an open so To run it, follow these steps: -1. Install the [`kraft` CLI tool](/cli/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples). diff --git a/pages/guides/flask-sqlite.mdx b/pages/guides/flask-sqlite.mdx index 519a7f77..578e123c 100644 --- a/pages/guides/flask-sqlite.mdx +++ b/pages/guides/flask-sqlite.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a Python Flask app using SQLite. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/python3.12-flask3.0-sqlite/` directory: diff --git a/pages/guides/flask.mdx b/pages/guides/flask.mdx index 57b8daf7..06dd8d72 100644 --- a/pages/guides/flask.mdx +++ b/pages/guides/flask.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a [Flask](https://flask.palletsprojects.com/en/3.0.x/) web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-python3.12-flask3.0/` directory: diff --git a/pages/guides/go.mdx b/pages/guides/go.mdx index d6dc4fba..f02fe3dd 100644 --- a/pages/guides/go.mdx +++ b/pages/guides/go.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Go-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-go1.21/` directory: diff --git a/pages/guides/grafana.mdx b/pages/guides/grafana.mdx index 3b637d5a..0663ade9 100644 --- a/pages/guides/grafana.mdx +++ b/pages/guides/grafana.mdx @@ -8,7 +8,7 @@ This guide shows you how to use [Grafana](https://grafana.com), the open source To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/grafana/` directory: diff --git a/pages/guides/haproxy.mdx b/pages/guides/haproxy.mdx index aeb7ea40..7bf043a8 100644 --- a/pages/guides/haproxy.mdx +++ b/pages/guides/haproxy.mdx @@ -9,7 +9,7 @@ HAProxy is a free and open source software that provides a high availability loa To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/haproxy/` directory: diff --git a/pages/guides/hugo.mdx b/pages/guides/hugo.mdx index 78167cd0..7adc525b 100644 --- a/pages/guides/hugo.mdx +++ b/pages/guides/hugo.mdx @@ -8,7 +8,7 @@ This guide shows you how to use [Hugo](https://gohugo.io/commands/hugo_server/), To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/hugo/` directory: diff --git a/pages/guides/imaginary.mdx b/pages/guides/imaginary.mdx index d74223b5..81f75c6c 100644 --- a/pages/guides/imaginary.mdx +++ b/pages/guides/imaginary.mdx @@ -8,7 +8,7 @@ This example uses [`imaginary`](https://github.com/h2non/imaginary), an HTTP mic To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/imaginary/` directory: diff --git a/pages/guides/java.mdx b/pages/guides/java.mdx index e269f07f..e6ab2606 100644 --- a/pages/guides/java.mdx +++ b/pages/guides/java.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Java-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-java17/` directory: diff --git a/pages/guides/llama2.mdx b/pages/guides/llama2.mdx index 6b6ba9b5..bb342ddf 100644 --- a/pages/guides/llama2.mdx +++ b/pages/guides/llama2.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a llama2 inference server and expose an API to it. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/llama2/` directory: diff --git a/pages/guides/lua.mdx b/pages/guides/lua.mdx index 45b3c3fd..4aecd3a6 100644 --- a/pages/guides/lua.mdx +++ b/pages/guides/lua.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Lua-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-lua5.1/` directory: diff --git a/pages/guides/mariadb.mdx b/pages/guides/mariadb.mdx index 0655a56d..1d867f50 100644 --- a/pages/guides/mariadb.mdx +++ b/pages/guides/mariadb.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide shows you how to use [MariaDB](https://mariadb.org), one of the most popular open source relational databases. To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/mariadb/` directory: diff --git a/pages/guides/memcached.mdx b/pages/guides/memcached.mdx index b7ea48de..0783f276 100644 --- a/pages/guides/memcached.mdx +++ b/pages/guides/memcached.mdx @@ -9,7 +9,7 @@ Memcached is an in-memory key-value store for small chunks of arbitrary data (st To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/memcached/` directory: diff --git a/pages/guides/minio.mdx b/pages/guides/minio.mdx index 53461f67..5e3c8365 100644 --- a/pages/guides/minio.mdx +++ b/pages/guides/minio.mdx @@ -9,7 +9,7 @@ Open Source, Amazon S3 compatible, Kubernetes Native and works for cloud native To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/minio/` directory: diff --git a/pages/guides/mongodb.mdx b/pages/guides/mongodb.mdx index 7507b075..2a74ac0a 100644 --- a/pages/guides/mongodb.mdx +++ b/pages/guides/mongodb.mdx @@ -8,7 +8,7 @@ This guide shows you how to use [MongoDB](https://www.mongodb.com), a source-ava To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/mongodb/` directory: diff --git a/pages/guides/nextjs.mdx b/pages/guides/nextjs.mdx index e3901408..bf955d96 100644 --- a/pages/guides/nextjs.mdx +++ b/pages/guides/nextjs.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a Next.js app. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node21-nextjs` directory: diff --git a/pages/guides/nginx.mdx b/pages/guides/nginx.mdx index 0569a39f..4e4a0937 100644 --- a/pages/guides/nginx.mdx +++ b/pages/guides/nginx.mdx @@ -9,7 +9,7 @@ Nginx can be used with Unikraft / Unikraft Cloud to serve static web content. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/nginx/` directory: diff --git a/pages/guides/node.mdx b/pages/guides/node.mdx index 8f9107af..39a3e810 100644 --- a/pages/guides/node.mdx +++ b/pages/guides/node.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Node-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-node21/` directory: diff --git a/pages/guides/opentelemetry-collector.mdx b/pages/guides/opentelemetry-collector.mdx index 01d201fe..7d74db8f 100644 --- a/pages/guides/opentelemetry-collector.mdx +++ b/pages/guides/opentelemetry-collector.mdx @@ -12,7 +12,7 @@ telemetry data. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/opentelemetry-collector/` directory: diff --git a/pages/guides/perl.mdx b/pages/guides/perl.mdx index 3bde5b7c..7c98921a 100644 --- a/pages/guides/perl.mdx +++ b/pages/guides/perl.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Perl-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-perl5.38/` directory: diff --git a/pages/guides/php.mdx b/pages/guides/php.mdx index 893b6dc7..48078907 100644 --- a/pages/guides/php.mdx +++ b/pages/guides/php.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple PHP-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-php8.2/` directory: diff --git a/pages/guides/postgres.mdx b/pages/guides/postgres.mdx index 69ed1569..108d3065 100644 --- a/pages/guides/postgres.mdx +++ b/pages/guides/postgres.mdx @@ -8,7 +8,7 @@ This guide shows you how to use [PostgreSQL](https://www.postgresql.org/), a pow To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/postgres/` directory: diff --git a/pages/guides/prisma.mdx b/pages/guides/prisma.mdx index d0fac6e2..8fd6af9c 100644 --- a/pages/guides/prisma.mdx +++ b/pages/guides/prisma.mdx @@ -8,7 +8,7 @@ This app comes from [Prisma's REST API Example](https://github.com/prisma/prisma It uses a SQLite database file with some initial dummy data which you can find at [`./prisma/store.db`](./prisma/store.db). To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node18-prisma-rest-express/` directory: diff --git a/pages/guides/puppeteer.mdx b/pages/guides/puppeteer.mdx index 263e63ad..f403a9d3 100644 --- a/pages/guides/puppeteer.mdx +++ b/pages/guides/puppeteer.mdx @@ -8,7 +8,7 @@ This guide shows you how to use [Puppeteer](https://pptr.dev/), a Node.js librar To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node-express-puppeteer/` directory: diff --git a/pages/guides/python.mdx b/pages/guides/python.mdx index 03686062..114c953b 100644 --- a/pages/guides/python.mdx +++ b/pages/guides/python.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Python-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-python3.12/` directory: diff --git a/pages/guides/rails.mdx b/pages/guides/rails.mdx index 0d6218ad..f16951c8 100644 --- a/pages/guides/rails.mdx +++ b/pages/guides/rails.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a [Ruby on Rails](https://rubyonrails.org/) app. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/ruby3.2-rails/` directory: diff --git a/pages/guides/redis.mdx b/pages/guides/redis.mdx index 2a47688b..a9353bf1 100644 --- a/pages/guides/redis.mdx +++ b/pages/guides/redis.mdx @@ -8,7 +8,7 @@ This guides shows you how to use [Redis](https://redis.io), an open source in-m To run it example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/redis/` directory: diff --git a/pages/guides/remix.mdx b/pages/guides/remix.mdx index 51c4cd13..4ee7cd74 100644 --- a/pages/guides/remix.mdx +++ b/pages/guides/remix.mdx @@ -8,7 +8,7 @@ This guide shows how to deploy a [Remix](https://remix.run/) app. To do so, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node21-remix/` directory: diff --git a/pages/guides/ruby.mdx b/pages/guides/ruby.mdx index 2a82a45e..1d960209 100644 --- a/pages/guides/ruby.mdx +++ b/pages/guides/ruby.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Ruby-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-ruby3.2/` directory: diff --git a/pages/guides/rust-actix.mdx b/pages/guides/rust-actix.mdx index b5872d2e..74ade950 100644 --- a/pages/guides/rust-actix.mdx +++ b/pages/guides/rust-actix.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This example uses [`actix-web`](https://actix.rs), a popular Rust web framework. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-rust1.75-actix-web4/` directory: diff --git a/pages/guides/rust-rocket.mdx b/pages/guides/rust-rocket.mdx index b0520a77..cd0e149d 100644 --- a/pages/guides/rust-rocket.mdx +++ b/pages/guides/rust-rocket.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This example uses [`Rocket`](https://rocket.rs/), a popular Rust web framework. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-rust1.75-rocket0.5/` directory: diff --git a/pages/guides/rust-tokio.mdx b/pages/guides/rust-tokio.mdx index 3c29b6fa..c02548df 100644 --- a/pages/guides/rust-tokio.mdx +++ b/pages/guides/rust-tokio.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This example uses [`Tokio`](https://tokio.rs/), a popular Rust asynchronous runtime. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-rust1.75-tokio/` directory: diff --git a/pages/guides/skipper.mdx b/pages/guides/skipper.mdx index 63acd702..bb91d347 100644 --- a/pages/guides/skipper.mdx +++ b/pages/guides/skipper.mdx @@ -8,7 +8,7 @@ This example uses [`Skipper`](https://opensource.zalando.com/skipper/), an HTTP To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/skipper/` directory: diff --git a/pages/guides/solidjs.mdx b/pages/guides/solidjs.mdx index 1027146b..42d96bbf 100644 --- a/pages/guides/solidjs.mdx +++ b/pages/guides/solidjs.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide shows how to deploy a [Solid Start](https://start.solidjs.com) app. To do so, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node21-solid-start/` directory: diff --git a/pages/guides/spin.mdx b/pages/guides/spin.mdx index d1e2cc44..e8eae4d9 100644 --- a/pages/guides/spin.mdx +++ b/pages/guides/spin.mdx @@ -10,7 +10,7 @@ It shows how to run a Spin app serving routes from two programs written in diffe Both the Spin executor and the Wagi executor on Unikraft Cloud. To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/spin-wagi-http/` directory: diff --git a/pages/guides/springboot.mdx b/pages/guides/springboot.mdx index 2d466241..b3009965 100644 --- a/pages/guides/springboot.mdx +++ b/pages/guides/springboot.mdx @@ -7,7 +7,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a Spring Boot web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/java17-springboot3.2.x/` directory: diff --git a/pages/guides/sveltekit.mdx b/pages/guides/sveltekit.mdx index 1cad997e..4b259a93 100644 --- a/pages/guides/sveltekit.mdx +++ b/pages/guides/sveltekit.mdx @@ -9,7 +9,7 @@ This guide explains how to create and deploy a [SvelteKit](https://kit.svelte.de To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node21-sveltekit/` directory: diff --git a/pages/guides/traefik.mdx b/pages/guides/traefik.mdx index 389abc67..2fa046d9 100644 --- a/pages/guides/traefik.mdx +++ b/pages/guides/traefik.mdx @@ -8,7 +8,7 @@ This example uses the [`Traefik`](https://traefik.io/traefik/) cloud native app To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/traefik/` directory: diff --git a/pages/guides/tyk.mdx b/pages/guides/tyk.mdx index 4f59bc2c..7ccc56ce 100644 --- a/pages/guides/tyk.mdx +++ b/pages/guides/tyk.mdx @@ -9,7 +9,7 @@ Tyk is used together with Redis to store API tokens and OAuth clients. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/tyk/` directory: diff --git a/pages/guides/wazero.mdx b/pages/guides/wazero.mdx index add6fb17..0ef1b20d 100644 --- a/pages/guides/wazero.mdx +++ b/pages/guides/wazero.mdx @@ -8,7 +8,7 @@ This example comes from [Wazero's "import go" example](https://github.com/tetrat and shows how to define, import and call a wasm blob from Go and run it on Unikraft Cloud. To run this it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/wazero-import-go/` directory: diff --git a/pages/guides/wordpress.mdx b/pages/guides/wordpress.mdx index c4d38dd6..46b9e24b 100644 --- a/pages/guides/wordpress.mdx +++ b/pages/guides/wordpress.mdx @@ -8,7 +8,7 @@ This guide shows you how to use [Wordpress](https://wordpress.com/), a web conte To run it, follow these steps: -1. Install the [`kraft` CLI tool](/install) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/wordpress-all-in-one/` directory: From eec600dd2db6bb22d5560a1a08ab468a671720ab Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Tue, 20 Jan 2026 18:12:50 +0200 Subject: [PATCH 024/131] feat(tutorials): Add tutorial comparing rootfses to volumes and roms Signed-off-by: Cezar Craciunoiu --- .../config/vocabularies/Unikraft/accept.txt | 2 + pages/tutorials/rootfs-volumes-roms.mdx | 180 ++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 pages/tutorials/rootfs-volumes-roms.mdx diff --git a/.vale/styles/config/vocabularies/Unikraft/accept.txt b/.vale/styles/config/vocabularies/Unikraft/accept.txt index a7a88c77..ffee8206 100644 --- a/.vale/styles/config/vocabularies/Unikraft/accept.txt +++ b/.vale/styles/config/vocabularies/Unikraft/accept.txt @@ -129,6 +129,7 @@ CPIO (?i)GraphQL (?i)gui (?i)haproxy +(?i)HDD(s)? (?i)Heroku (?i)Hightouch (?i)href @@ -226,6 +227,7 @@ CPIO (?i)Singleline (?i)Spring (?i)sql +(?i)SSD(s)? (?i)ssh (?i)ssl (?i)stderr diff --git a/pages/tutorials/rootfs-volumes-roms.mdx b/pages/tutorials/rootfs-volumes-roms.mdx new file mode 100644 index 00000000..59215093 --- /dev/null +++ b/pages/tutorials/rootfs-volumes-roms.mdx @@ -0,0 +1,180 @@ +--- +title: Rootfses, Volumes and ROMs +navigation_icon: square-stack +--- + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +Rootfses, volumes and ROMs (Read-Only Memory) are storage types that share many similarities, but have different use cases and results. +Below, this tutorial discusses each one of them and how to use them, and then does a quick comparison between the three. + +## Storage types + +### Rootfses + +The rootfs, also known as the initrd, is the main component in any instance running on Unikraft Cloud, and any UNIX-based operating system. +It's used for configuring its default behaviour and contains all files needed for it to boot. +On Unikraft Cloud it's used to also start a default app (without any specific configuration). +When booting, the system loads rootfs pages in memory, which incurs a small access time characteristic to RAM read/write operations. + +At the same time, because the rootfs resides in volatile memory, changes aren't persistent across reboots. +Because of this it's best to put only essential information in there to keep the size down (1-2GB maximum), to save on boot times and on used RAM. +For persistent storage, consider using [volumes](/platform/volumes) instead. + +A rootfs can be of two types: `CPIO` or `EROFS`. +Each type has its own advantages and disadvantages, but overall `EROFS` is better suited for Unikraft Cloud. +The [rootfs formats](/tutorials/rootfs-formats) documentation page details both types. +You can create a rootfs with the [`kraft` CLI](/cli/) for both types, for example: + + + + CPIO + EROFS + + + ```bash + kraft cloud deploy \ + -p 443:8080 \ + -M 900Mi \ + --rootfs-type cpio \ + demo/node-playwright-chromium + ``` + + + ```bash + kraft cloud deploy \ + -p 443:8080 \ + -M 900Mi \ + --rootfs-type erofs \ + --keep-file-owners \ + demo/node-playwright-chromium + ``` + + + +### Volumes + +[Volumes](/platform/volumes) are a non-essential, persistent, large storage component on Unikraft Cloud. +You attach volumes to stopped instances or before you create them through the [API](/api/platform/v1/volumes#create-volume). +They're automatically mounted in the instance at the specified path either `RW` (Read-Write) or `RO` (Read-Only). +They're backed up on SSD (Solid State Drive) disks and offer redundancy without compromising on access latency. +As such you can use them for persistent data, secrets, storage, logs, and more, and you can share them between instances. + +To create and use a volume, you can use the `kraft cloud volume` commands. +For example, you need to first create a volume: + +```bash title="Creating a Volume" +kraft cloud volume create --size 100 --name my-volume +``` + +Then you can optionally populate it with local data: + +```bash title="Importing Data into Volume" +kraft cloud volume import --volume my-volume --source my-data/ +``` + +Finally, when you deploy an instance you can attach the volume to it: + +```bash title="Attaching Volume to Instance" +kraft cloud deploy \ + -M 512 \ + -p 443:8080 \ + --volume my-volume:/mnt \ + . +``` + +### ROMs + +[ROMs](/features/roms) are an extension of the rootfs concept and a good way to customize generic rootfses for many instances. +They're attached on stopped instances, but aren't mounted automatically on boot as they can have any format (`ext4`, `cpio`, `erofs`, `xfs`, `ntfs`, etc). +They're not persistent and are `RO` (Read-Only), and as such should contain only custom rootfs code/data. +They're intended to be small, fast, and flexible as opposed to volumes. + +For example, you can use ROMs in the context of a web server that offers different index pages based on the ROM attached for localization. +By using ROMs, you can have a single slim image to which you can attach different ROMs depending on the language you want to serve. +Finally, it's considered good practice to keep ROMs small and focused, and the instance shouldn't depend on them to boot correctly. + +You need to first package ROMs as an OCI image and push them to the registry. +They show up as any other image in the registry, but don't have a kernel. +To package them you can either use `kraft`, or package it yourself and pass it to `kraft` for pushing: + +```bash title="Kraft Packaging and Pushing" +kraft pkg \ + --plat kraftcloud \ + --arch x86_64 \ + --name index.unikraft.io/function-hello:latest \ + --rootfs-type erofs \ + --push \ + . +``` + +You can then specify ROMs through the API when creating or updating an instance: + + + + Update Instance + Create Instance + + + ```bash title="Updating Instance with ROMs" + curl -X PATCH "$UKC_METRO/instances/$id" \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -d '{ + "prop": "roms", + "op": "add", + "value": [ + { + "name": "function-hello", + "image": "demo/function-hello:latest" + } + ] + }' + ``` + + + ```json title="Creating Instance with ROMs" + ... + "roms": [ + { + "name": "function-hello", + "image": "demo/function-hello:latest" + } + ], + ... + ``` + + + +Finally, in the instance you need to mount them like any other disk and you can find them under `/dev/` with their specified name: + +```bash title="Mounting ROMs in Instance" +mkdir /mnt/rom +mount -t erofs /dev/function-hello /mnt/rom +``` + +## Comparison + +| Type / Metric | Rootfses | Volumes | ROMs | +|---------------|----------|---------|------| +| I/O Speed | Fast | Decent | Fast | +| I/O Latency | Small | Noticeable | Small | +| Storage Medium | RAM | SSD/HDD | RAM | +| Intended Size | Medium | (up to) Large | Small | +| File System | `CPIO`/`EROFS` | `ext4`/`virtio-fs` | Any | +| Mounting | Automatic | Automatic | Manual | +| Persistence | No | Yes | No | +| Mandatory | Yes | No | No | + +## Conclusion + +As expected, each storage type has its own advantages and disadvantages. +Rootfses are mandatory and fast, but you should keep them small and only contain essential information. +Volumes are persistent and large, but have noticeable access latency. +ROMs are a flexible way to customize rootfses, but you should also keep them small and not be essential for booting. + +## Learn more + +* [Volumes](/platform/volumes) and how to use them. +* [Rootfs formats](/tutorials/rootfs-formats) and how to create them. +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. From 829486f3263a52ad6305ed4eace4c20b3e9b0024 Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Mon, 19 Jan 2026 12:53:16 +0200 Subject: [PATCH 025/131] feat(faq): Add question about the correlation between rootfs/size/memory Signed-off-by: Cezar Craciunoiu --- .../config/vocabularies/Unikraft/accept.txt | 1 + pages/faq.mdx | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.vale/styles/config/vocabularies/Unikraft/accept.txt b/.vale/styles/config/vocabularies/Unikraft/accept.txt index a7a88c77..db7e3350 100644 --- a/.vale/styles/config/vocabularies/Unikraft/accept.txt +++ b/.vale/styles/config/vocabularies/Unikraft/accept.txt @@ -12,6 +12,7 @@ (?i)minimum (?i)namespaced? (?i)performant +(?i)PIE (?i)ROM(s)? (?i)rootfs (?i)tokenizer diff --git a/pages/faq.mdx b/pages/faq.mdx index 4fce407f..2ce06b52 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -285,12 +285,25 @@ Note: `ENTRYPOINT` is a recognised keyword in the Dockerfile so it should propag No exact suite can determine if your app can run on one or another. -Tinyx is a slimmed down Linux Kernel, which means that most cloud-compatible apps work out of the box as long as it has all files available. +TinyX is a slimmed down Linux Kernel, which means that most cloud-compatible apps work out of the box as long as it has all files available. Some virtual devices and virtual file system entries are missing, but you can contact a Unikraft staff member to look into adding them. -If your app successfully runs on TinyX and Unikraft Cloud, you have the option to also try running it on the Unikraft operating system. +If your app successfully runs on TinyX and Unikraft Cloud, you have the option to also try running it on the Unikraft kernel. This kernel removes even more unused features so the chance that the app isn't compatible increases, but the performance and boot times are better. For example, if your app uses extensive process cloning, it has a low chance to work on the Unikraft kernel, as it supports running a single process at a time. -Other examples of unsupported formats are 32bit executables and non-`PIE` (Position Independent Executable) executables, as the Unikraft kernel can't load them in memory at the moment. +Other examples of unsupported formats are 32bit executables and non-PIE (Position Independent Executable) executables, as the Unikraft kernel can't load them in memory at the moment. Other small differences exist, which you should report to the Unikraft Team for fixing, as the Unikraft kernel tries to follow Linux and the POSIX format. + +#### How does the [rootfs format](/tutorials/rootfs-formats) and size equate to the memory used? + +When using the `CPIO` file system, the memory allocated to the instance needs to be at least twice as big as the image size. +This is because the system must load and unpack the `CPIO` rootfs format in memory before using it. +This is a bare minimum and to this you need to add also the memory your app needs to run. + +When using `EROFS`, there is no direct correlation between the image size and the memory needed. +Ideally, the memory should be at least the image size to make sure the system can load all files in memory before using. +The system loads files on demand and maps them directly from disk, ensuring lower memory usage and overhead. +If you have files that you know are never used, it's better to remove them from the image to slim it down. +Thus, in theory, `EROFS` uses only the allocated pages, but it's also highly dependent on the workload. +An instance with a 3GB image might use 128MB of RAM at one point, whilst an instance with a 300MB image might use 1GB of RAM at some point. From 84aea9fc972f709087b6889dee8c9bed691e8348 Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Wed, 14 Jan 2026 13:33:52 +0200 Subject: [PATCH 026/131] feat(tutorials): Add tutorial for triggering scale-to-zero Signed-off-by: Cezar Craciunoiu --- pages/tutorials/scale-to-zero-triggers.mdx | 141 +++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 pages/tutorials/scale-to-zero-triggers.mdx diff --git a/pages/tutorials/scale-to-zero-triggers.mdx b/pages/tutorials/scale-to-zero-triggers.mdx new file mode 100644 index 00000000..21908679 --- /dev/null +++ b/pages/tutorials/scale-to-zero-triggers.mdx @@ -0,0 +1,141 @@ +--- +title: Scale To Zero Triggers +navigation_icon: arrow-down-1-0 +--- + +Unikraft Cloud supports scaling instances to zero based on different triggers. +This allows you to optimize resource usage and costs by automatically setting instances to standby when they're not needed. +They will automatically resume when required with minimal delay. +The platform can scale down instances automatically, or you can scale them down manually. +To read more about Scale To Zero, check the [Scale To Zero](/features/scale-to-zero) page. + +## Automatic triggers + +Automatic triggers are the most common and easiest way to use scale-to-zero with your instances on Unikraft Cloud. +By default, instances scale down automatically when there is no traffic coming to them for a specified period. +You can also configure scale-to-zero to consider idle active connections when determining whether to scale down an instance. + +### No traffic + +When you enable this trigger, Unikraft Cloud will track incoming connections to your instance. +If there is no traffic for the configured duration, the instance scales down to zero. +You can use the [`kraft` CLI tool](/cli/) or the [API](/api/platform/v1/instances#create-instance) to enable this trigger: + + + + Kraftkit + API + + +```bash +kraft cloud instance create \ + --scale-to-zero on \ + --scale-to-zero-cooldown 5s \ + ... +``` + + +```json +{ + ... + "scale_to_zero": { + "policy": "on", + "cooldown_time_ms": "5000 + } +} +``` + + + +### Idle connections + +When enabling this trigger, the platform will consider all active connections to your instance, so all traffic going to them. +The instance will scale down if you make no new network connections and all existing connections have been idle for the configured duration. + +You can enable this trigger using the [`kraft` CLI tool](/cli/) or the [API](/api/platform/v1/instances#create-instance) as follows: + + + + Kraftkit + API + + +```bash +kraft cloud instance create \ + --scale-to-zero idle \ + --scale-to-zero-cooldown 5s \ + --scale-to-zero-stateful \ + ... +``` + + +```json +{ + ... + "scale_to_zero": { + "policy": "idle", + "cooldown_time_ms": "5000", + "stateful": true + } +} +``` + + + +:::tip +If your app uses [keep-alive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Keep-Alive) messages over this active connection, your instance won't scale down. +You will have to either disable keep-alive or configure them with an interval high enough to allow scaling down. +For example, with a 5 seconds cooldown, you can set keep-alive to once per minute. +::: + +## Manual triggers + +For specific use cases, you might want to manually scale your instances to zero, or to manually disable scale-to-zero. +Unikraft Cloud supports two ways to manually trigger scale-to-zero. + +### API + +You can use the Unikraft Cloud API to manually scale down an instance. +You will have to use the `/instances/suspend` endpoint to scale down an instance. +This happens instantly, regardless of the configured automatic triggers. + +First, set the required environment variables: + +```bash +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + +Then invoke the following `curl` command to scale down an instance named `my-instance`: + +```bash +curl -X POST https://api.$UKC_METRO.unikraft.cloud/v1/instances/suspend \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "my-instance" + }' +``` + +### Device file + +You can also manually scale down an instance by writing '+'/'-' to a special device file available inside the instance. +Every instance has this file at `/uk/libukp/scale_to_zero_disable`. +By writing '+' to this file, you disable automatic scale-to-zero for the instance until the number of '-' written matches the number of '+' written. +For example, to disable automatic scale-to-zero, run the following command inside the instance: + +```bash +echo '+' > /uk/libukp/scale_to_zero_disable +``` + +:::tip +If your app starts listening for incoming connections before being ready to serve them, you can use this mechanism to disable scale-to-zero during startup. +Once your app is ready to serve requests, you can write '-' to the file to re-enable automatic scale-to-zero. +::: + +## Learn more + +* The [Scale To Zero](/features/scale-to-zero) feature page. +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. From 82f039b6af782795289956e78f351335ed456d1a Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Wed, 14 Jan 2026 13:33:52 +0200 Subject: [PATCH 027/131] fix(tutorials): Add necessary imports for scale-to-zero page Signed-off-by: Cezar Craciunoiu --- pages/tutorials/scale-to-zero-triggers.mdx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pages/tutorials/scale-to-zero-triggers.mdx b/pages/tutorials/scale-to-zero-triggers.mdx index 21908679..029b98e1 100644 --- a/pages/tutorials/scale-to-zero-triggers.mdx +++ b/pages/tutorials/scale-to-zero-triggers.mdx @@ -3,11 +3,13 @@ title: Scale To Zero Triggers navigation_icon: arrow-down-1-0 --- +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + Unikraft Cloud supports scaling instances to zero based on different triggers. This allows you to optimize resource usage and costs by automatically setting instances to standby when they're not needed. They will automatically resume when required with minimal delay. The platform can scale down instances automatically, or you can scale them down manually. -To read more about Scale To Zero, check the [Scale To Zero](/features/scale-to-zero) page. +You can read more about Scale To Zero [here](/features/scale-to-zero). ## Automatic triggers @@ -138,4 +140,4 @@ Once your app is ready to serve requests, you can write '-' to the file to re-en ## Learn more * The [Scale To Zero](/features/scale-to-zero) feature page. -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [instance create](/cli/instance/create) subcommand. From 3d6644b4963081867d43dd3163e385e50aa87aef Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Tue, 20 Jan 2026 18:39:07 +0200 Subject: [PATCH 028/131] feat(tutorials): Add tutorial comparing internal/external networks Signed-off-by: Cezar Craciunoiu --- pages/tutorials/network-communication.mdx | 55 +++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 pages/tutorials/network-communication.mdx diff --git a/pages/tutorials/network-communication.mdx b/pages/tutorials/network-communication.mdx new file mode 100644 index 00000000..530ebbd4 --- /dev/null +++ b/pages/tutorials/network-communication.mdx @@ -0,0 +1,55 @@ +--- +title: Network Communication +navigation_icon: network +--- + +:::caution[Disclaimer] +As of writing this, [scale-to-zero triggers](/tutorials/scale-to-zero-triggers) are unavailable on internal networking and, as such you must use external networking. +Moreover, there is no load balancing on internal networks, this being up to the user. +::: + +## Communication types + +The platform separates Unikraft Cloud instances on a per-user level. +This means that all instances part of the scope of a user can "see" each other in the private internal network and they can communicate with each other. +This communication is private and unencrypted, and doesn't reach the outside world. +You can communicate internally by using the Private IP or Private FQDN. + +At the same time, when using the Public FQDN the connection goes through the external load balancer applied to every public instance. +This means that an entirely different code path resolves the connection, and also the connection is always TLS encrypted. + +### External communication + +External communication refers to every request going over the public FQDN of an instance. +This means that the request goes through the external load balancer, and as such TLS encryption is mandatory. +This also means that the instance will be load balanced with all other public instances behind the same [service](/features/load-balancing). +The request will do a round trip from the client through the load balancer and to the instance. +This communication is best suited for frontend-to-service communication, public APIs, web services, and more. + +### Internal communication + +Internal communication refers to every request going over the private network of a user. +Every instance, by default, receives a private IP and a private FQDN (of the format `.internal`). +This means that the request stays within the user internal network, and doesn't go through the external load balancer. +This also means that the system won't encrypt the connection by default. +This communication is best suited for service-to-service communication, microservices, databases, caches, and more. +For example, you wouldn't want to expose your database publicly, but you would want your app to be able to connect to it internally. + +:::note +When using [`kraft cloud tunnel`](/cli/tunnel) to connect to your instances you are using the internal network to reach your instance. +The command creates a public-facing instance that tunnels your requests to the private instance over the internal network. +This is a good way to keep your instances private while still being able to access them from your local machine. +::: + +## Conclusion + +When building your app architecture on Unikraft Cloud, it's important to understand the differences between internal and external communication. +External communication is best suited for public-facing services, while internal communication is ideal for private interactions between services within your app. +By leveraging both types of communication, you can deploy a robust and efficient app architecture on Unikraft Cloud. + +## Learn more + +* [Load balancing](/features/load-balancing) of services. +* [Platform services](/platform/services) and how they work. +* [Scale to zero triggers](/tutorials/scale-to-zero-triggers) for automatic instance scaling. +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [tunnel](/cli/tunnel) subcommand. From 30ecbe6981758105198823bc17d42d684161cdde Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Mon, 19 Jan 2026 21:45:13 +0200 Subject: [PATCH 029/131] feat(tutorials): Add tutorial on setting environment variables Signed-off-by: Cezar Craciunoiu --- pages/tutorials/environment-variables.mdx | 122 ++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 pages/tutorials/environment-variables.mdx diff --git a/pages/tutorials/environment-variables.mdx b/pages/tutorials/environment-variables.mdx new file mode 100644 index 00000000..35f0f0f4 --- /dev/null +++ b/pages/tutorials/environment-variables.mdx @@ -0,0 +1,122 @@ +--- +title: Environment Variables +navigation_icon: cog +--- + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +Environment variables are a common way to configure applications at runtime. +Unikraft Cloud supports passing environment variables to instances during deployment through many methods. +This tutorial discusses each below and orders them by superseeding precedence (from most powerful to weakest). + +## Setting environment variables + +Below are all the ways you can set environment variables for your Unikraft Cloud instances. +The order they're presented is from the least precedence to the highest precedence. + +### Dockerfile ENV + +:::caution[Disclaimer] +At the moment environment variables from the `Dockerfile` are passed in the image but not read by the Unikraft Cloud platform. +Please use the other methods described below in the meantime. +::: + +You can set environment variables in your `Dockerfile` using the `ENV` instruction in your target `FROM` stage. +The [`kraft` CLI](/cli/) automatically reads them when building the image and sets them in the resulting packaged image. + +```dockerfile +# ... +FROM ubuntu:latest +ENV MY_ENV_VAR=my_value +# ... +``` + +### Kraftfile env + +:::caution[Disclaimer] +At the moment environment variables from the `Kraftfile` are passed in the image but not read by the Unikraft Cloud platform. +Nonetheless, `kraft cloud deploy` can still read them and set them in the instance. +For other use cases, please use the other methods described below in the meantime. +::: + +You can set environment variables in your `Kraftfile` using the `env` field. +`kraft` automatically reads them when building the image and sets them in the resulting packaged image. + +```yaml +# ... +env: + MY_ENV_VAR: my_value +``` + +:::tip +This method takes precedence over the `Dockerfile`. +It will override environment variables with the same name set in the `Dockerfile`. +::: + +### Kraft flags + +When deploying an instance using the `kraft cloud deploy` or `kraft cloud instance create` commands, you can pass environment variables using the `--env` (or `-e`) flag. +You can specify many environment variables by using the flag many times. +The flag works similarly to the `docker run -e` flag. + +```bash +kraft cloud deploy my-app --env MY_ENV_VAR=my_value +``` + +:::tip +This method takes precedence over the `Dockerfile` and `Kraftfile`. +It will override environment variables with the same name set in the previous two methods. +::: + +### Wrapper script + +Create a wrapper script that sets the environment variables before executing the main app. +Check what the original entrypoint of your app is and call it after setting the variables. +For example, if the original entrypoint is `/entrypoint.sh`, you can create a new script `wrapper.sh` like this: + +```bash +#!/bin/sh + +export MY_ENV_VAR="my_value" + +exec /entrypoint.sh "$@" +``` + +Then you change either your `Dockerfile` or `Kraftfile` to use this wrapper script as the entrypoint: + + + + Dockerfile + Kraftfile + + + ```Dockerfile + # ... + COPY wrapper.sh /wrapper.sh + RUN chmod +x /wrapper.sh + ENTRYPOINT ["/wrapper.sh"] + ``` + + + ```yaml + # ... + cmd: "/wrapper.sh" + ``` + + + +:::tip +This method has the highest precedence and will override environment variables set in the cli, `Dockerfile`, or `Kraftfile` as it hardcodes them in the script. +Thus it's recommended to do this only for variables that you set and don't change. +::: + +## Conclusion + +Out of the four ways to set environment variables in Unikraft Cloud instances you should pick the ones that work best for you. +Consider that the `Dockerfile` and `Kraftfile` can set variables for the image itself, while the `kraft` CLI and wrapper script set them at runtime. + +## Learn more + +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* The [Dockerfile reference](https://docs.docker.com/reference/dockerfile/) for understanding how to set environment variables in Dockerfiles. +* The [Kraftfile reference](https://unikraft.org/docs/cli/reference/kraftfile) for understanding how to set environment variables in Kraftfiles. From 27647e715bc7191e490562281351ffe19f5e0d87 Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Mon, 19 Jan 2026 14:44:22 +0200 Subject: [PATCH 030/131] feat(tutorials): Add tutorial on rootfs compression Signed-off-by: Cezar Craciunoiu --- pages/tutorials/rootfs-compression.mdx | 178 +++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 pages/tutorials/rootfs-compression.mdx diff --git a/pages/tutorials/rootfs-compression.mdx b/pages/tutorials/rootfs-compression.mdx new file mode 100644 index 00000000..2c489a57 --- /dev/null +++ b/pages/tutorials/rootfs-compression.mdx @@ -0,0 +1,178 @@ +--- +title: Rootfs Compression +navigation_icon: file-archive +--- + +Compressing the root file system represents using an algorithm like `gzip`, `zstd`, etc. to reduce the size of the rootfs on disk. +This has the added benefit of reducing the time it takes to push the image to the Unikraft Cloud platform, as you transfer less data. +It also means that the size on disk on the host side reduces, which can be beneficial when dealing with many images or large images. +This size can drop depending on the contents of the rootfs and the compression algorithm used. +For example, text files often compress by up to 90% and more, whilst already compressed files like images or videos don't compress well at all. + +## Getting started + +The Unikraft Platform supports both compressed and uncompressed rootfses, but it's highly recommended to use uncompressed ones if size allows. +Decompressing is a step done by the kernel at boot time, resulting in slower access times across the board. +That's why the first attempt at using the platform should always be with uncompressed rootfses. + +Both formats, [`CPIO` and `EROFS`](/tutorials/rootfs-formats), support compression. +`CPIO` does full file system compression (like running `zip` on the file). +`EROFS` does per-block compression meaning that the system decompresses only the accessed blocks on-the-fly. +Both of them support most compression algorithms, but the recommended ones are those that have fast decompression speeds like `lz4hc`. + +As presented in the [rootfs formats tutorial](/tutorials/rootfs-formats) and in the [FAQ](/faq), the performance characteristics of the two formats differ. +When using compression, the system amplifies these differences further. +For `CPIO`, the system must decompress the entire archive first before using it. +This means that boot times increase further, and memory usage during boot is also higher negating the benefit of using compression in the first place. +`EROFS` is better, as the system decompresses only the accessed blocks on-the-fly, meaning that boot times are less affected, and memory usage is also kept lower. +This has the added downside that Direct Access (`DAX`) isn't possible when using compression, as the host side can't map a compressed image into guest memory. +This caveat results in having to load the entire compressed rootfs into guest memory, increasing memory usage by at least the size of the compressed rootfs. +Still, if many files aren't accessed in boot, the cold boot time might decrease compared to an uncompressed `EROFS` rootfs. + +## Packaging a Compressed rootfs + +Packaging a compressed rootfs is different depending on the format used. +The [`kraft` CLI](/cli/) implements `CPIO` compression directly, while `EROFS` compression must happen externally using the `mkfs.erofs` tool. + +### CPIO Compression + +To package a compressed `CPIO` rootfs using `kraft`, you can use the `--compress` flag when running the `kraft pkg` or `kraft cloud deploy` command. +This uses `gzip` compression to compress the initrd file before packaging it into a `OCI` image and uploading it to the Unikraft Cloud platform. + +```bash +kraft cloud deploy \ + --rootfs-type cpio \ + --compress \ + ... +``` + +### EROFS Compression + +Currently, `kraft` has no direct support for compressing `EROFS` rootfses. +To package a compressed `EROFS` rootfs, you need to use the `mkfs.erofs` tool before packaging it with `kraft`. + +To do this you will also have to first export the image built from the `Dockerfile` into a `tar` archive: + +```bash +docker build -o type=tar,dest=rootfs -t my-docker-image -f Dockerfile . +``` + +You can then use the resulting `tar` archive to create a compressed `EROFS` rootfs using the following command. +Note that you can change the compression algorithm and level by modifying the `-z` option. +In this example the level is `9` (maximum) and the algorithm is `lz4hc` (high compression lz4): + +```bash +mkfs.erofs --all-root -b 4096 -d2 -E noinline_data -z lz4hc,9 rootfs.erofs --tar=rootfs rootfs.tar +``` + +Finally, you can package and deploy the compressed EROFS rootfs using kraft: + +```bash +kraft cloud deploy \ + --rootfs-type erofs \ + --rootfs ./rootfs.erofs \ + ... +``` +## Performance of Compressed rootfs vs. Uncompressed rootfs Images + +To illustrate the performance differences between compressed and uncompressed rootfses, below you can see the same [`node-22` image](https://github.com/unikraft-cloud/examples/tree/main/node-playwright-chromium) packaged and deployed four times: + +1. Uncompressed `CPIO` + ```ansi title="Uncompressed CPIO" + [●] Deployed successfully! + β”‚ + β”œ─────── name: node-playwright-chromium-gjv31 + β”œ─────── uuid: 7ef181a3-8264-4418-82e9-4690ed75a030 + β”œ────── metro: fra + β”œ────── state: running + β”œ───── domain: https://dark-feather-7drf2jvp.fra.unikraft.app + β”œ────── image: demo/node-playwright-chromium@sha256:eafb34e104efe139234f5aa753f3d380afea2c5b78a3011ccd2017a25a5172c0 + β”œ── boot time: 621.28 ms + β”œ───── memory: 2400 MiB + β”œ──── service: dark-feather-7drf2jvp + β”œ─ private ip: 10.0.1.233 + β””─────── args: /usr/bin/wrapper.sh /usr/bin/node /app/server.js + ``` + +1. Compressed `CPIO` + + ```ansi title="Compressed CPIO" + [●] Deployed successfully! + β”‚ + β”œ─────── name: node-playwright-chromium-bt6r9 + β”œ─────── uuid: 1ebc4ee0-2fb1-4272-81d5-7adc76bfb566 + β”œ────── metro: fra + β”œ────── state: running + β”œ───── domain: https://old-cloud-em09h6ue.fra.unikraft.app + β”œ────── image: demo/node-playwright-chromium@sha256:ac6cde1c766162a3c1bc376985c2442eafacd5b18b26b599a25d3095c0a5f5ed + β”œ── boot time: 2079.74 ms + β”œ───── memory: 2400 MiB + β”œ──── service: old-cloud-em09h6ue + β”œ─ private ip: 10.0.1.233 + β””─────── args: /usr/bin/wrapper.sh /usr/bin/node /app/server.js + ``` + +1. Uncompressed `EROFS` + + ```ansi title="Uncompressed EROFS" + [●] Deployed successfully! + β”‚ + β”œ─────── name: node-playwright-chromium-o4ds4 + β”œ─────── uuid: 967b66fd-f71c-4b2b-8982-88e4c0373d02 + β”œ────── metro: fra + β”œ────── state: running + β”œ───── domain: https://damp-water-8ubacykw.fra.unikraft.app + β”œ────── image: cezar.unikraft.io/node-playwright-chromium@sha256:65bf231a557a0dd938592d0fd67f4d5f5e83c0df1ca27b8f8d8675253138ae4b + β”œ── boot time: 121.75 ms + β”œ───── memory: 900 MiB + β”œ──── service: damp-water-8ubacykw + β”œ─ private ip: 10.0.4.1 + β””─────── args: /usr/bin/wrapper.sh /usr/bin/node /app/server.js + ``` + +1. Compressed `EROFS` + + ```ansi title="Compressed EROFS" + [●] Deployed successfully! + β”‚ + β”œ────── name: node-playwright-chromium-9yb9y + β”œ────── uuid: d7255b2c-394c-4578-a21b-2f879f823cd9 + β”œ───── metro: fra + β”œ───── state: running + β”œ──── domain: https://damp-dream-rpmyh0h0.fra.unikraft.app + β”œ───── image: cezar.unikraft.io/node-playwright-chromium@sha256:7a93fbfa414eb958cd4f61b9cbe4874eb4fe6836e74fb292bca3e2927df71a88 + β”œ─ boot time: 92.36 ms + β”œ──── memory: 900 MiB + β”œ─── service: damp-dream-rpmyh0h0 + β”œ private ip: 10.0.3.253 + β””────── args: /usr/bin/wrapper.sh /usr/bin/node /app/server.js + ``` + +### Results + +| rootfs Type | Compression | Image Size | Boot Time | Instance Memory Usage | +|---------------|-------------|------------|------------|-----------------------| +| CPIO | No | 824 MiB | 621.28 ms | 2400 MiB | +| CPIO | Yes (gzip) | 299 MiB | 2079.74 ms | 2400 MiB | +| EROFS | No | 830 MiB | 121.75 ms | 900 MiB | +| EROFS | Yes (lz4hc) | 410 MiB | 92.36 ms | 900 MiB | + +As expected from the previous assumptions, the compressed CPIO rootfs boots slower than the uncompressed one. +This happens due to the need to decompress the entire archive before use. +EROFS performs better in both compressed and uncompressed forms, compared to CPIO. +The compressed EROFS rootfs boots even faster than the uncompressed one. +This is likely due to the reduced amount of data that the system reads from disk, resulting in faster access times despite the decompression overhead. +This only happens in the cold boot scenario. +In [warm boots](/features/snapshots), the uncompressed EROFS rootfs tops the charts as the system needs no decompression at all on demand. + +## Conclusion + +As a rule of thumb, use uncompressed rootfses whenever possible and try to always use `EROFS` over `CPIO` for better performance. +If limited by size constraints, try using compressed `EROFS` rootfses with a fast decompression algorithm like `lz4hc`. + +## Learn more + +* The [rootfs formats tutorial](/tutorials/rootfs-formats) for understanding the differences between `CPIO` and `EROFS`. +* The [`mkfs.erofs` documentation](https://man.archlinux.org/man/extra/erofs-utils/mkfs.erofs.1.en) for more information on creating compressed `EROFS` file systems. +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. From 2ea8f16424c0b78738f59e992e67f130840ae124 Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Mon, 19 Jan 2026 19:53:24 +0200 Subject: [PATCH 031/131] feat(features): Add best practices for optimal scale-to-zero configuration Signed-off-by: Cezar Craciunoiu --- .../config/vocabularies/Unikraft/accept.txt | 1 + pages/features/scale-to-zero.mdx | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/.vale/styles/config/vocabularies/Unikraft/accept.txt b/.vale/styles/config/vocabularies/Unikraft/accept.txt index 8f2625fe..76086426 100644 --- a/.vale/styles/config/vocabularies/Unikraft/accept.txt +++ b/.vale/styles/config/vocabularies/Unikraft/accept.txt @@ -29,6 +29,7 @@ DCO EOF FROM HIPPA +HMR IATA ISO LLM diff --git a/pages/features/scale-to-zero.mdx b/pages/features/scale-to-zero.mdx index 25a76b96..003b4cfd 100644 --- a/pages/features/scale-to-zero.mdx +++ b/pages/features/scale-to-zero.mdx @@ -109,6 +109,7 @@ The instance resumes execution where it left offβ€”with caches already warm. Stateful scale-to-zero can also enable scale-to-zero for apps that need to keep state for functional correctness. This works even if cold boot times are no concern. +If your app doesn't require maintaining state and has a satisfactorily short boot time, you might prefer to disable stateful scale-to-zero to save disk space. :::note The time to load an instance snapshot is constant and in the order of a few milliseconds. @@ -121,6 +122,41 @@ The time to take an instance snapshot during scale-to-zero depends on the amount ::: +## Best practices + +### Cooldown configuration + +Choosing the optimal cooldown period depends on your app's start-up time and traffic patterns. +The default cooldown is 1 second, which works well for simple apps. +For larger apps with longer boot times, start with a conservative cooldown (for example, 5-10 seconds) and gradually lower it while monitoring behavior. + +If your app takes a long time to initialize, you might encounter issues where it scales down before serving the first request if the cooldown is too short. +Strategies to mitigate this include: +1. **Stateful Scale-to-Zero**: [Enabling stateful mode](#stateful-scale-to-zero) saves memory to disk, reducing wake-up time for complex apps. +2. **Startup Protection**: Use the [manual disable mechanism](#application-support-for-scale-to-zero) to temporarily turn off scale-to-zero during your app's boot sequence, then re-enable it once ready to serve. + +### Managing connectivity and state + +#### Continuous connections + +Apps using long-lived connections with frequent keep-alive messages (for example, WebSockets, HTTP/2, HMR) may prevent the instance from scaling to zero. +To allow the instance to sleep: +* Increase the interval between keep-alive messages. +* Use a more aggressive cooldown period if appropriate. +* If requiring continuous connectivity, consider disabling scale-to-zero for these workloads. + +#### Internal communication + +:::info +This feature is currently under active development and may change in future releases. +::: + +Currently, internal traffic via Private FQDNs doesn't trigger the scale-to-zero wake-up mechanism. +Services attempting to reach a standby instance via its Private FQDN will fail to wake it. +To ensure wake-on-request behavior for creating service-to-service communication, use the instance's **Public FQDN**. +Note that this also applies to [`kraft cloud tunnel`](/cli/tunnel), which relies on internal connectivity. + + ## Getting started You can enable millisecond scale-to-zero via a **label** in each of From d7080602a908a63f5dea8f0d48fa916762247c6e Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 10 Feb 2026 15:34:16 +0200 Subject: [PATCH 032/131] fix(faq): Add mention about Dockerfile USER keyword Signed-off-by: Alex-Andrei Cioc --- pages/faq.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pages/faq.mdx b/pages/faq.mdx index 2ce06b52..931f342c 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -219,9 +219,12 @@ There's also a chance that Kraft staging contains changes available only on non- #### What keywords does Kraftkit ignore from a Dockerfile? This is the current list of ignored keywords: `EXPOSE`, `HEALTHCHECK`, `ONBUILD`, `SHELL`, `STOPSIGNAL`, `VOLUME`. +The `USER` keyword is relevant for running subsequent `RUN` instructions in the Dockerfile, but not for the `ENTRYPOINT` and `CMD` commands. +At runtime, Unikraft Cloud instances run as `root` user, unless explicitly switching to another user. Currently, `kraft` parses the `ENV` keyword, but the platform discards the result in the current stable version. + #### How does the image size and memory relate to boot times? When using `CPIO`, there is a [strong correlation](/tutorials/rootfs-formats) between the image size and the boot time. @@ -281,6 +284,7 @@ If you are using the Unikraft OS, you need to specify those in the command like Note: `ENTRYPOINT` is a recognised keyword in the Dockerfile so it should propagate up into the image. + #### How to tell if an app can run in the Unikraft kernel or TinyX? No exact suite can determine if your app can run on one or another. From af518811665a78a5672f19f6106dffa88e03a35f Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Wed, 25 Feb 2026 10:21:16 +0200 Subject: [PATCH 033/131] fix(features): Fix ROM device path Signed-off-by: Alex-Andrei Cioc --- pages/features/roms.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index 69fc85ff..99649171 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -33,7 +33,7 @@ This separation allows you to maintain one base image while deploying many diffe :::note The app running inside the base image is responsible to read the data from the attached ROM devices. -ROM blobs appear as block devices at paths like `/dev/ukp_rom`, where `` is the ROM name you specify when creating the instance. +ROM blobs appear as block devices at paths like `/dev/ukp_rom_`, where `` is the ROM name you specify when creating the instance. ::: From 12cd33e391b662a98a10033ccfb610c8e506fb0a Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 10 Mar 2026 16:41:42 +0200 Subject: [PATCH 034/131] fix(use-cases): Fix typo in Webhooks Learn More Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/webhooks.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/use-cases/webhooks.mdx b/pages/use-cases/webhooks.mdx index 46baf29e..6450e09c 100644 --- a/pages/use-cases/webhooks.mdx +++ b/pages/use-cases/webhooks.mdx @@ -102,7 +102,7 @@ Or visit the [CLI Reference](/cli). For more information, check out these resources: -- [Express docunmentation](https://expressjs.com/) +- [Express Documentation](https://expressjs.com/) - [GitHub Webhooks Documentation](https://docs.github.com/en/webhooks) - [Securing GitHub Webhooks](https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries) - [Webhook Best Practices](https://webhooks.fyi/) From 62474828c7c2fd21e4e6d52d5852b3806c90e3d5 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 15:07:04 +0100 Subject: [PATCH 035/131] docs: add instance forking reference page Signed-off-by: Jerome Jaggi --- pages/features/forking.mdx | 102 +++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 pages/features/forking.mdx diff --git a/pages/features/forking.mdx b/pages/features/forking.mdx new file mode 100644 index 00000000..2d2d3f0b --- /dev/null +++ b/pages/features/forking.mdx @@ -0,0 +1,102 @@ +--- +title: Instance Forking +navigation_icon: git-fork +--- + +:::caution +Instance forking is a preview feature and isn't yet available on stable. +The interface described here reflects the current implementation and may change before general availability. +::: + +Instance forking allows a running instance to create an independent copy of itself at a snapshot boundary. +Both the original instance (the **parent**) and the copy (the **child**) resume execution from the same memory state. + +This is conceptually similar to `fork(2)` in a POSIX process. +After the call, two independent instances run with identical state, and each can determine its own role by inspecting the messages it receives from the platform. + +## How it works + +Forking is **guest-initiated**: the app inside an instance triggers the fork programmatically by sending a request over the platform's guest communication channel. +No REST API endpoint or CLI command exists to fork an instance externally. + +When the guest triggers a fork: + +1. The platform takes a snapshot of the parent instance. +2. The platform creates a new child instance from that snapshot with a fresh network interface. +3. Both parent and child start from the same snapshot. +4. The platform notifies each instance of its role via messages over [vsock](https://man7.org/linux/man-pages/man7/vsock.7.html) port `137`. + +The child has [delete-on-stop](/platform/instances#delete-on-stop) set automaticallyβ€”it's ephemeral and the platform removes it when it stops. + +## Guest notifications + +After a fork completes, both the parent and child receive vsock messages on port `137`. + +### Parent receives: `FORK_CREATED` + +The parent receives a `FORK_CREATED` message with the following fields: + +| Field | Type | Description | +|-------|------|-------------| +| `msg_type` | uint32 | `0x2`β€”identifies this as a `FORK_CREATED` message. | +| `correlation_id` | uint32 | Echoed from the original fork request. | +| `child_id` | UUID (16 bytes) | UUID of the newly created child instance. | +| `snapshot_id` | UUID (16 bytes) | UUID of the snapshot the child originates from. | +| `creation_time` | uint64 | Child creation timestamp (UTC, seconds since Unix epoch). | +| `fqdn_len` | uint16 | Length of the child's FQDN string (may be 0). | +| `fqdn` | char[] | Child's private FQDN (variable-length, follows the fixed header). | + +### Child receives: `PARENT_ID` + +The child receives a `PARENT_ID` message telling it which instance it originates from: + +| Field | Type | Description | +|-------|------|-------------| +| `msg_type` | uint32 | `0x3`β€”identifies this as a `PARENT_ID` message. | +| `correlation_id` | uint32 | Echoed from the original fork request. | +| `parent_id` | UUID (16 bytes) | UUID of the parent instance. | + +### Ongoing child lifecycle updates (parent) + +After the fork, the parent continues to receive state change notifications for each of its children over the same vsock port: + +**`STATUS` message** (`msg_type = 0x4`)β€”sent when a child changes state: + +| Field | Type | Description | +|-------|------|-------------| +| `uuid` | UUID (16 bytes) | UUID of the child instance. | +| `state` | uint32 | New instance state (same values as the `state` field in `GET /v1/instances`). | + +**`EXIT_STATUS` message** (`msg_type = 0x5`)β€”sent when a child stops: + +| Field | Type | Description | +|-------|------|-------------| +| `uuid` | UUID (16 bytes) | UUID of the child instance. | +| `exit_status` | uint32 | Exit code of the child. | + +All messages share a common 8-byte header (`msg_type` uint32 + `correlation_id` uint32) followed by the message-specific payload. + +## Child lifecycle + +- Children have `delete-on-stop` set automaticallyβ€”they're removed from the platform when they stop. +- The platform clears a child's relationship to its parent when the child stops or transitions to a template state. Later lifecycle messages for that child aren't sent to the parent. +- A parent can have more than one child alive at the same time. +- A child can itself become a parent by issuing its own fork request. + +## Parent behaviour during fork + +- While the platform snapshots the parent, it temporarily pauses the parent's [scale-to-zero autostart](/features/scale-to-zero) to prevent a race condition. +- If the parent had autostart configured, the platform re-enables it after the fork completes. +- The parent resumes execution immediately after the snapshot. The pause is brief. + +## Constraints + +- The parent must support snapshotting (this requires [stateful scale-to-zero](/features/scale-to-zero#stateful-scale-to-zero) to be on or a snapshot otherwise available). A fork request on a parent without a snapshot fails. +- The REST API and CLI can't trigger a fork; the guest must do it from within the instance. +- Fork state doesn't survive a reboot of the child instance. + +## Learn more + +* [Instance templates](/platform/instances#instance-templates): a related snapshot-based feature for cloning instances from a stopped state +* [Scale-to-zero](/features/scale-to-zero): stateful mode must be on for forking to work +* [Instances](/platform/instances) From 9ef69e0cc2b2303408fa799e1874cb83ad8b8002 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 15:13:25 +0100 Subject: [PATCH 036/131] docs: add Go SDK reference page Signed-off-by: Jerome Jaggi --- pages/integrations/sdks/go.mdx | 217 +++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 pages/integrations/sdks/go.mdx diff --git a/pages/integrations/sdks/go.mdx b/pages/integrations/sdks/go.mdx new file mode 100644 index 00000000..80fa3e36 --- /dev/null +++ b/pages/integrations/sdks/go.mdx @@ -0,0 +1,217 @@ +--- +title: Go SDK +navigation_icon: code +--- + +The Unikraft Cloud Go SDK is an autogenerated client library that interfaces with the Unikraft Cloud platform API, based on the public OpenAPI specification. +It's on the `prod-stable` branch and is the most mature of the available SDKs. + +## Installation + +```bash title="" +go get unikraft.com/cloud/sdk +``` + +Requires Go 1.24 or later. + +## Quickstart + +```go title="main.go" +package main + +import ( + "context" + "fmt" + + ukp "unikraft.com/cloud/sdk/platform" +) + +func main() { + ctx := context.Background() + + client := ukp.NewClient( + ukp.WithDefaultMetro("fra0"), + ukp.WithToken("your-api-token"), + ) + + resp, err := client.GetInstances(ctx, nil, true) + if err != nil { + panic(err) + } + + for _, instance := range resp.Data.Instances { + fmt.Printf("UUID: %s\n", *instance.Uuid) + fmt.Printf("Name: %s\n", *instance.Name) + fmt.Printf("State: %s\n", *instance.State) + fmt.Println("---") + } +} +``` + +## Authentication + +Pass your token via `ukp.WithToken()`: + +```go title="" +client := ukp.NewClient( + ukp.WithToken("your-api-token"), +) +``` + +Or set one of the following environment variables. +`NewClient` reads them automatically in order of preference: + +1. `UKC_TOKEN` +2. `UNIKRAFT_CLOUD_TOKEN` +3. `KRAFTCLOUD_TOKEN` (legacy name) + +```go title="" +// No WithToken needed β€” NewClient reads the environment automatically. +client := ukp.NewClient( + ukp.WithDefaultMetro("fra0"), +) +``` + +## Client options + +| Option | Description | +|--------|-------------| +| `WithDefaultMetro(string)` | Metro to use when you don't specify one per-request (default: `fra0`) | +| `WithToken(string)` | API token | +| `WithHTTPClient(...)` | Custom `http.Client` | +| `WithUserAgent(string)` | Override the `User-Agent` header | +| `WithAllowInsecure(bool)` | Skip TLS verification (development only) | + +The base address is `https://api..kraft.cloud`. + +## Resources + +The `platform.Client` interface covers the full Unikraft Cloud REST API surface. + +### Instances + +```go title="" +// Create +client.CreateInstance(ctx, req) + +// Read +client.GetInstances(ctx, names, details) +client.GetInstanceByUUID(ctx, uuid, details) + +// Start / stop +client.StartInstanceByUUID(ctx, uuid) +client.StartInstances(ctx, names) +client.StopInstanceByUUID(ctx, uuid, force, drainTimeoutMs) +client.StopInstances(ctx, names, force, drainTimeoutMs) + +// Update (PATCH) +client.UpdateInstanceByUUID(ctx, uuid, req) +client.UpdateInstances(ctx, req) + +// Delete +client.DeleteInstanceByUUID(ctx, uuid) +client.DeleteInstances(ctx, names) + +// Logs and metrics +client.GetInstanceLogsByUUID(ctx, uuid) +client.GetInstanceLogs(ctx, names) +client.GetInstanceMetricsByUUID(ctx, uuid) +client.GetInstanceMetrics(ctx, names) + +// Wait for a target state +client.WaitInstanceByUUID(ctx, uuid, state, timeoutMs) +client.WaitInstances(ctx, names, state, timeoutMs) +``` + +### Instance templates + +```go title="" +client.CreateTemplateInstances(ctx, req) +client.GetTemplateInstances(ctx, fromUuid, count, tags) +client.GetTemplateInstanceByUUID(ctx, uuid, details) +client.UpdateTemplateInstanceByUUID(ctx, uuid, req) +client.UpdateTemplateInstances(ctx, req) +client.DeleteTemplateInstanceByUUID(ctx, uuid) +client.DeleteTemplateInstances(ctx, names) +``` + +### Service groups + +```go title="" +client.CreateServiceGroup(ctx, req) +client.GetServiceGroups(ctx, names, details) +client.GetServiceGroupByUUID(ctx, uuid, details) +client.UpdateServiceGroupByUUID(ctx, uuid, req) +client.UpdateServiceGroups(ctx, req) +client.DeleteServiceGroupByUUID(ctx, uuid) +client.DeleteServiceGroups(ctx, names) +``` + +### Autoscale + +```go title="" +// Configuration +client.CreateAutoscaleConfigurationByServiceGroupUUID(ctx, uuid, req) +client.GetAutoscaleConfigurationsByServiceGroupUUID(ctx, uuid) +client.DeleteAutoscaleConfigurationsByServiceGroupUUID(ctx, uuid) + +// Policies +client.CreateAutoscaleConfigurationPolicy(ctx, serviceGroupUUID, req) +client.GetAutoscaleConfigurationPolicies(ctx, serviceGroupUUID) +client.GetAutoscaleConfigurationPolicyByName(ctx, serviceGroupUUID, name) +client.DeleteAutoscaleConfigurationPolicies(ctx, serviceGroupUUID) +client.DeleteAutoscaleConfigurationPolicyByName(ctx, serviceGroupUUID, name) +``` + +### Volumes + +```go title="" +client.CreateVolume(ctx, req) +client.GetVolumes(ctx, names, details) +client.GetVolumeByUUID(ctx, uuid, details) +client.AttachVolumeByUUID(ctx, uuid, req) +client.AttachVolumes(ctx, req) +client.DetachVolumeByUUID(ctx, uuid) +client.DetachVolumes(ctx, names) +client.UpdateVolumeByUUID(ctx, uuid, req) +client.UpdateVolumes(ctx, req) +client.DeleteVolumeByUUID(ctx, uuid) +client.DeleteVolumes(ctx, names) +``` + +### Certificates + +```go title="" +client.CreateCertificate(ctx, req) +client.GetCertificates(ctx, names, details) +client.GetCertificateByUUID(ctx, uuid, details) +client.DeleteCertificateByUUID(ctx, uuid) +client.DeleteCertificates(ctx, names) +``` + +### Images + +```go title="" +client.GetImageByTag(ctx, tag) +client.GetImageByDigest(ctx, digest) +``` + +### Users and quotas + +```go title="" +client.GetUser(ctx) +client.GetUserByUUID(ctx, uuid) +client.AddUsers(ctx, req) +``` + +### Health + +```go title="" +client.Healthz(ctx) +``` + +## Source + +The SDK source and full API reference are available at +[github.com/unikraft-cloud/go-sdk](https://github.com/unikraft-cloud/go-sdk) +and [pkg.go.dev/unikraft.com/cloud/sdk](https://pkg.go.dev/unikraft.com/cloud/sdk). From 1108fbff027b4616bc2d5bf214cbd074c8c9f218 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 15:16:49 +0100 Subject: [PATCH 037/131] docs: add user quotas reference page Signed-off-by: Jerome Jaggi --- pages/platform/quotas.mdx | 123 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 pages/platform/quotas.mdx diff --git a/pages/platform/quotas.mdx b/pages/platform/quotas.mdx new file mode 100644 index 00000000..e1ce0cc5 --- /dev/null +++ b/pages/platform/quotas.mdx @@ -0,0 +1,123 @@ +--- +title: Quotas +navigation_icon: gauge +description: | + Understand and track your Unikraft Cloud resource quotas. +--- + +Unikraft Cloud enforces per-account resource quotas to govern how many instances, service groups, volumes, and compute resources you can provision. +Use the quotas endpoint to inspect your current usage and limits. + +## Endpoints + +``` +GET /v1/users/quotas +GET /v1/users/{uuid}/quotas +``` + +`GET /v1/users/quotas` (no UUID) returns the quota for the authenticated user. + +## Response structure + +The response contains a top-level `quotas` array. +Each element has three sections: `used`, `hard`, and `limits`. + +### `used`: Current resource usage + +| Field | Type | Description | +|-------|------|-------------| +| `instances` | int | Total number of instances (stopped + running). | +| `live_instances` | int | Number of currently running instances. | +| `live_vcpus` | int | Number of vCPUs in use across running instances. | +| `live_memory_mb` | int | Memory (MB) in use across running instances. | +| `service_groups` | int | Number of allocated service groups. | +| `services` | int | Number of allocated services (published ports). | +| `volumes` | int | Number of allocated volumes. | +| `total_volume_mb` | int | Total volume storage in use (MB). | + +### `hard`: Maximum allowed allocations + +| Field | Type | Description | +|-------|------|-------------| +| `instances` | int | Maximum number of instances. | +| `live_vcpus` | int | Maximum vCPUs running simultaneously. | +| `live_memory_mb` | int | Maximum memory (MB) running simultaneously. | +| `service_groups` | int | Maximum number of service groups. | +| `services` | int | Maximum number of services. | +| `volumes` | int | Maximum number of volumes. | +| `total_volume_mb` | int | Maximum total volume storage (MB). | + +### `limits`: Per-resource range constraints + +These define the minimum and maximum values you can specify when creating individual resources. + +| Field | Type | Description | +|-------|------|-------------| +| `min_memory_mb` | int | Minimum memory (MB) per instance. | +| `max_memory_mb` | int | Maximum memory (MB) per instance. | +| `min_vcpus` | int | Minimum vCPUs per instance. | +| `max_vcpus` | int | Maximum vCPUs per instance. | +| `min_volume_mb` | int | Minimum volume size (MB). | +| `max_volume_mb` | int | Maximum volume size (MB). | +| `min_autoscale_size` | int | Minimum autoscale group size. | +| `max_autoscale_size` | int | Maximum autoscale group size. | + +## Example + +```bash title="" +curl -H "Authorization: Bearer $UKC_TOKEN" \ + "https://api.unikraft.io/v1/users/quotas" +``` + +```json title="" +{ + "quotas": [ + { + "status": "ok", + "uuid": "a1b2c3d4-...", + "used": { + "instances": 3, + "live_instances": 2, + "live_vcpus": 2, + "live_memory_mb": 512, + "service_groups": 2, + "services": 4, + "volumes": 1, + "total_volume_mb": 512 + }, + "hard": { + "instances": 50, + "live_vcpus": 16, + "live_memory_mb": 4096, + "service_groups": 20, + "services": 40, + "volumes": 20, + "total_volume_mb": 20480 + }, + "limits": { + "min_memory_mb": 16, + "max_memory_mb": 4096, + "min_vcpus": 1, + "max_vcpus": 8, + "min_volume_mb": 128, + "max_volume_mb": 10240, + "min_autoscale_size": 0, + "max_autoscale_size": 10 + } + } + ] +} +``` + +:::note +The `hard.live_instances` field is a compatibility alias for `hard.live_vcpus`. +It's kept for backward compatibility and the platform may drop it in a future API version. +Prefer `hard.live_vcpus`. +::: + +## Learn more + +* Unikraft Cloud's [REST API reference](/api/platform/v1) +* [Instances](/platform/instances) +* [Volumes](/platform/volumes) +* [Services](/platform/services) From 73c16a2d348cc614c578a125ccb33325766b2519 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 15:29:19 +0100 Subject: [PATCH 038/131] docs: add notification signal section to scale-to-zero page Signed-off-by: Jerome Jaggi --- pages/features/scale-to-zero.mdx | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/pages/features/scale-to-zero.mdx b/pages/features/scale-to-zero.mdx index 003b4cfd..a32c191d 100644 --- a/pages/features/scale-to-zero.mdx +++ b/pages/features/scale-to-zero.mdx @@ -97,6 +97,37 @@ There can be a short delay (a few milliseconds) until the Unikraft Cloud control Ensure you configure a cooldown time large enough to accommodate for potential signal delay. ::: +## Notification signal + +Before the platform suspends an instance, it can send a notification signal to the guest, giving it time to finish in-flight work before suspension begins. + +The platform delivers the notification over [vsock](https://man7.org/linux/man-pages/man7/vsock.7.html) on port `138`. +The platform sends the literal string `scaletozero` to the guest at the configured lead time before suspension. + +Your app can listen on vsock port `138` and use the signal to: +- Drain in-flight requests +- Flush write buffers +- Update any external state + +### Configuring the notification lead time + +Use the `notify_time_ms` field in the `scale_to_zero` configuration when creating or updating an instance: + +```json title="POST /v1/instances" +{ + "scale_to_zero": { + "cooldown_time_ms": 5000, + "notify_time_ms": 2000 + } +} +``` + +This sends the notification 2 seconds before the cooldown expires and suspension begins. + +:::note +`notify_time_ms` must be less than `cooldown_time_ms`. +If `notify_time_ms` is `0` (the default), the platform skips the notification and suspends the instance immediately when the cooldown expires. +::: ## Stateful scale-to-zero From eba3e894a9827b718f9e0292fdc9464e6890ad8a Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 15:29:29 +0100 Subject: [PATCH 039/131] docs: add REST API reference section to images page Signed-off-by: Jerome Jaggi --- pages/platform/images.mdx | 51 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/pages/platform/images.mdx b/pages/platform/images.mdx index 3ebefb03..7c9f9a2c 100644 --- a/pages/platform/images.mdx +++ b/pages/platform/images.mdx @@ -185,6 +185,57 @@ kraft cloud instance create \ You now have a new instance created from the existing image. +## REST API reference + +### List images + +``` +GET /v1/images +``` + +Returns all images in your account. +Each image object includes: + +| Field | Type | Description | +|-------|------|-------------| +| `uuid` | string | Image UUID. | +| `name` | string | Image name (if present). | +| `created_at` | timestamp | Creation time. | +| `url` | string | Full image address (includes digest). | +| `initrd_or_rom` | bool | Whether the image includes an initrd or ROM component. | +| `size_in_bytes` | int64 | Total image size in bytes. | +| `args` | array of strings | Default arguments (omitted if none). | + +### Look up by UUID + +``` +GET /v1/images?uuid=[,…] +``` + +Returns one or more images by UUID. + +### Look up by digest + +``` +GET /v1/images/list +``` + +Pass a `digest` string in the request body to return the image matching that digest: + +```json title="GET /v1/images/list" +{ + "digest": "sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472" +} +``` + +The response includes `digest`, `tags`, `initrd`, `size_in_bytes`, and `args`. + +:::note +Tag-based filtering (`tag` field in the list body) appears in the API schema but the platform doesn't act on it yet. +The platform accepts and ignores the field. +Use the digest or UUID endpoints to look up a specific image. +::: + ## Learn more * The `kraft cloud` [CLI reference](/cli/) From 091f5424fd0ac300eae8e94d0d64eec2e21cb7bb Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 22:44:23 +0100 Subject: [PATCH 040/131] fix(introduction): Replace 'unikernels' with 'MicroVMs' Signed-off-by: Jerome Jaggi --- pages/introduction.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/introduction.mdx b/pages/introduction.mdx index 17156592..1d4c8bae 100644 --- a/pages/introduction.mdx +++ b/pages/introduction.mdx @@ -5,7 +5,7 @@ navigation_icon: book-check import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" -Unikraft is a from-first-principles virtualization solution and cloud platform based on **unikernels** which provides best-in-class performance, security, and scalability. +Unikraft is a from-first-principles virtualization solution and cloud platform based on **MicroVMs** which provides best-in-class performance, security, and scalability. Running your app on Unikraft is like running a container but with hardware isolation, millisecond cold starts, and stateful scale-to-zero. From 30cecc57ec083d72eec9a2331987f20ea8da3b9c Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Sun, 15 Mar 2026 10:38:09 +0100 Subject: [PATCH 041/131] fix(use-cases): replace unikernel with microVM Replace unikernel architecture with microVM architecture in webhooks and MCP servers pages. Remove immutable unikernel images bullet points from both. Signed-off-by: Jerome Jaggi --- pages/use-cases/mcp-servers.mdx | 3 +-- pages/use-cases/webhooks.mdx | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pages/use-cases/mcp-servers.mdx b/pages/use-cases/mcp-servers.mdx index 823429d9..72ae53d5 100644 --- a/pages/use-cases/mcp-servers.mdx +++ b/pages/use-cases/mcp-servers.mdx @@ -15,7 +15,7 @@ With **Unikraft Cloud**, you are enhancing your MCP servers with instant deploym AI assistants need instant access to tools and data. Every millisecond of latency impacts the user experience. -Unikraft Cloud's unikernel architecture reduces OS overhead: +Unikraft Cloud's microVM architecture reduces OS overhead: * Single-digit-millisecond cold starts mean MCP servers are ready instantly. * Minimal memory footprint allows dense packing of specialized servers. @@ -26,7 +26,6 @@ MCP servers often access sensitive dataβ€”file systems, databases, proprietary A Unikraft Cloud provides VM-level isolation for each server instance: * Strong isolation prevents cross-contamination between different MCP contexts. -* Immutable unikernel images mitigate runtime tampering risks. * Minimal attack surface with only essential components included. ### πŸ’Έ Pay-per-query economics diff --git a/pages/use-cases/webhooks.mdx b/pages/use-cases/webhooks.mdx index 6450e09c..662aa15d 100644 --- a/pages/use-cases/webhooks.mdx +++ b/pages/use-cases/webhooks.mdx @@ -16,7 +16,7 @@ With **Unikraft Cloud**, you can deploy webhook receivers that combine instant a Webhooks are inherently sporadicβ€”events can arrive in bursts or be silent for hours. Traditional servers waste resources running every day, waiting for events. -Unikraft Cloud's unikernel architecture provides: +Unikraft Cloud's microVM architecture provides: * Single-digit-millisecond cold starts ensure instant response when events arrive. * No noticeable delay for webhook senders, maintaining reliable integrations. @@ -28,7 +28,6 @@ Webhook receivers often process sensitive data from external services. Unikraft Cloud provides VM-level isolation for each instance: * Strong isolation prevents cross-contamination between different webhook handlers. -* Immutable unikernel images reduce the attack surface. * Built-in HTTPS endpoints with automatic TLS certificate management. ### πŸ’Έ Pay only for events From caf01bc101c13bb91ae0a4f153c4acf59ef78822 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Sun, 15 Mar 2026 10:38:13 +0100 Subject: [PATCH 042/131] chore(tutorials): remove rootless instances tutorial The rootless instances tutorial is no longer needed as part of the docs content cleanup. Signed-off-by: Jerome Jaggi --- pages/tutorials/rootless.mdx | 106 ----------------------------------- 1 file changed, 106 deletions(-) delete mode 100644 pages/tutorials/rootless.mdx diff --git a/pages/tutorials/rootless.mdx b/pages/tutorials/rootless.mdx deleted file mode 100644 index 7144e95e..00000000 --- a/pages/tutorials/rootless.mdx +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: Rootless Instances -navigation_icon: user-lock ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -Unikraft Cloud instances use the `root` user by default when nothing specific sets it. -Because Unikraft Cloud images assume a single user, and set ownership accordingly, there can be inconsistencies between the expected result and the actual result permission-wise. - -## Getting started - -:::caution[Disclaimer] -This tutorial assumes that you need/want to create your own user inside the Unikraft Cloud instance. -If you are actually looking to convert a Docker image to run inside Unikraft Cloud, please refer to the [Docker to Unikraft Cloud tutorial](/tutorials/docker-to-unikraft-cloud) instead. -::: - -To get different users to work inside Unikraft Cloud instances you need to do some configuration changes to your deployment process. -The usual flow is to package your rootfs using either a `Dockerfile` or some other sources (for example, a file, a directory or an OCI image). -Thus, you would either create your user inside the `Dockerfile` or use a wrapper script that would create the user before starting your main app. -The workflow would be as follows: - -1. Create the user and register it: - - - - Dockerfile - Script - - - ```dockerfile - # ... - - ARG USER_ID=1000 - ARG GROUP_ID=1000 - ARG USERNAME=appuser - - # Create group and user - RUN groupadd --gid $GROUP_ID $USERNAME \ - && useradd --uid $USER_ID --gid $GROUP_ID -m -s /bin/bash $USERNAME - - # Copy files and set ownership - COPY --chown=$USERNAME:$USERNAME . /app - - # Switch to the non-root user before doing other operations - USER $USERNAME - - # ... - ``` - - - ```bash - #!/bin/bash - - set -e - - USER_ID=1000 - GROUP_ID=1000 - USERNAME=appuser - - # Create group and user - groupadd --gid $GROUP_ID $USERNAME - useradd --uid $USER_ID --gid $GROUP_ID -m -s /bin/bash $USERNAME - - # Change ownership of app files - chown -R $USERNAME:$USERNAME /app - - # ... - ``` - - - - Keep in mind that `useradd` and `groupadd` might not be available in all base images. - For example, if you are using `alpine` as a base image (which comes with BusyBox), you would need to use `adduser` and `addgroup` instead. - -1. Depending on how you [package your rootfs](/tutorials/rootfs-formats), you might need specific options: - - * (EROFS) Use the `--keep-file-owners` when packaging the rootfs as EROFS (that is, `kraft pkg ... --rootfs-type erofs --keep-file-owners ...`). - - * (CPIO) You shouldn't use CPIO as the rootfs type if you need user support. - You **can't** preserve user IDs when packaging as CPIO. - -1. Before running the app, switch to the new user and make sure to preserve the environment in your entrypoint script: - - ```bash - su -m appuser - ``` - -If your environment variables are correctly set, after doing the steps above you should be running things as a different user. -You can check this by running the following command before starting your main app: - -```bash -whoami -``` - -## Conclusion - -Users are a consacrated way of reducing capabilities and for Unikraft Cloud this is no different. -You can already enhance security of your deployments with the reduced attack surface of unikernels, as well as isolation through virtualization. -You can further reduce the impact of a potential compromise by running as a non-root user. -Furthermore, for quick deployments (for example, converting an existing Docker image to Unikraft Cloud), running as a non-root user is often expected from the original image. - -## Learn more - -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. -* The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. \ No newline at end of file From 75b3404259b15d39adcded39c75c3a99cc15879d Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Sun, 15 Mar 2026 10:28:53 +0100 Subject: [PATCH 043/131] fix(faq): replace unikernel refs with microVM, restructure Add microVM definition FAQ near top. Move unikernel-specific entries to bottom. Remove 'How does Unikraft differ from Linux' entry. Replace unikernel with microVM in top section for consistent terminology. Signed-off-by: Jerome Jaggi --- pages/faq.mdx | 58 ++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/pages/faq.mdx b/pages/faq.mdx index 931f342c..7b7ea74b 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -5,30 +5,29 @@ navigation_icon: circle-question-mark #### What's Unikraft? -Unikraft is the company behind Unikraft Cloud, a next-generation compute platform that leverages unikernel technology. +Unikraft is the company behind Unikraft Cloud, a next-generation compute platform that leverages microVM technology. It delivers millisecond cold boots and scale-to-zero autoscaling so you never pay for idle resources. -#### Can you do cloud-prem, or on-prem deployments? +{/* vale off */} +#### What's a microVM? -Yes. -Please [get in touch](https://unikraft.com/contact) to discuss dedicated hosting. +Definitionally, a microVM is any virtual machine launched with Firecracker, an open source Virtual Machine Monitor (VMM) from Amazon, originally done for AWS Lambda. +{/* vale on */} +The VM itself can still be chunky: as long as Firecracker launched it, it's considered a microVM. +And any microVM *is* a VM, so it has the same strong, hardware-level isolation as any VM does. -#### What's a unikernel? +#### Can you do cloud-prem, or on-prem deployments? -A unikernel is a specialized virtual machine. -Each target app gets a distro and kernel containing only the code it needs. -Everything builds at compile time, before deployment. -If an app doesn't need a line of code to run, it doesn't get deployed. -This packages as any other virtual machine, with strong, hardware-level isolation. -Unikraft packages unikernels as OCI images. +Yes. +Please [get in touch](https://unikraft.com/contact) to discuss dedicated hosting. #### Aren't virtual machines heavyweight? They need not be! -Unikraft unikernels are proof you can have strong, hardware-level isolation. +Unikraft microVMs are proof you can have strong, hardware-level isolation. This isolation is the workhorse of public cloud deployments. It combines with the lightweight characteristics of containers or processes, such as millisecond cold boot times. @@ -44,10 +43,10 @@ For example, an NGINX Unikraft image is under 2MBs in size. When you deploy a container on the public cloud, it gets deployed on top of a virtual machine to have strong, hardware-level isolation. The container thus adds yet another layer of overhead between your app and the hardware. At Unikraft, `Dockerfile`s create the filesystem at build time. -Then, a lean unikernel provides the best efficiency at deploy time. +Then, a lean microVM provides the best efficiency at deploy time. -#### Do Unikraft unikernels come with security benefits? +#### Do Unikraft microVMs come with security benefits? Yes, especially stemming from the fact that they have a minimal Trusted Computing Base (TCB), and everything is off by default (services, ports, etc). @@ -72,18 +71,10 @@ See any of the apps/langs guides [here](/guides/bun) to see examples. You can control Unikraft Cloud with it as well as build unikernels and try things out locally. -#### How does Unikraft differ from Linux, and what about debugging? - -Unikraft implements the Linux API so apps and languages run unmodified. -A common concern is that unikernels are hard to debug. -Unikraft includes a full GDB server, tracing, and other facilities, so debugging feels like Linux (see [here](https://unikraft.org/docs/internals/debugging)). -For observability, Unikraft ships a Prometheus library so a unikernel can export metrics to Grafana dashboards. - - #### How's millisecond scale-to-zero achieved? -Magic πŸͺ„. -Kidding, it's the combination of using Unikraft unikernels to run workloads and a custom node ingress controller. +Magic πŸͺ„ +Kidding, it's the combination of using Unikraft microVMs to run workloads and a custom node ingress controller. This controller can be reactive in milliseconds and scale to thousands of instances. Other optimizations to the underlying host also help. When traffic dies, your app will stop, consume no resources, and get charged $0. @@ -153,7 +144,7 @@ When you're ready to deploy, switch to `kraft cloud deploy`. Definitely not! Docker is great for dev environments and for building images. In fact, Unikraft relies on `Dockerfile` to specify the filesystem of images on Unikraft Cloud. -Having said that, when it's time to deploy, Unikraft places the resulting filesystem on a lean unikernel. +Having said that, when it's time to deploy, Unikraft places the resulting filesystem on a lean microVM. It's ready to run with hardware-level isolation and extreme efficiency. @@ -194,7 +185,22 @@ Unikraft provides full log support for all users. Paying customers get access to Prometheus metrics. -#### Are there other unikernel cloud platforms? +#### What's a unikernel? + +A unikernel is a specialized virtual machine. +Each target app gets a distro and kernel containing only the code it needs. +Everything builds at compile time, before deployment. +If an app doesn't need a line of code to run, it doesn't get deployed. +This packages as any other virtual machine, with strong, hardware-level isolation. +Unikraft packages unikernels as OCI images. + + +#### Does Unikraft Cloud only support unikernels? + +No, Unikraft Cloud also supports minimalistic, Linux-based microVMs. + + +#### Are there other platforms supporting unikernels? Other unikernel projects exist, but most are research efforts, unmaintained, or limited to a single app or language and aren't POSIX (Portable Operating System Interface) compliant. From 214887c46054a547a5342d90aec54d5afbce6097 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Sun, 15 Mar 2026 10:28:58 +0100 Subject: [PATCH 044/131] fix(use-cases): replace unikernel with microVM Replace all unikernel mentions with microVM across remote IDEs, serverless databases, API gateways, and headless browsers pages. Remove immutable unikernel images bullet from headless browsers. Signed-off-by: Jerome Jaggi --- pages/use-cases/api-gateways.mdx | 6 +++--- pages/use-cases/headless-browsers.mdx | 3 +-- pages/use-cases/remote-ides.mdx | 8 ++++---- pages/use-cases/serverless-databases.mdx | 12 ++++++------ 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/pages/use-cases/api-gateways.mdx b/pages/use-cases/api-gateways.mdx index afc931ac..01cb872c 100644 --- a/pages/use-cases/api-gateways.mdx +++ b/pages/use-cases/api-gateways.mdx @@ -7,13 +7,13 @@ API Gateways are the critical entry point to your services. They manage authentication, routing, rate-limiting, observability, and security at the edge of your infrastructure. In modern architecturesβ€”especially microservices and serverless platformsβ€”the API Gateway is the first line of defence and performance optimisation. -With **Unikraft Cloud**, API Gateways gain advantage from a unikernel-based, scale-to-zero infrastructure that delivers the performance of specialised systems with the flexibility of serverless deployment. +With **Unikraft Cloud**, API Gateways gain advantage from a microVM-based, scale-to-zero infrastructure that delivers the performance of specialised systems with the flexibility of serverless deployment. ## Why run an API gateway on Unikraft Cloud ### ⚑ Ultra-low latency -Unikernels remove the overhead of general-purpose operating systems by compiling only the required OS components alongside the API Gateway app. +MicroVMs remove the overhead of general-purpose operating systems by compiling only the required OS components alongside the API Gateway app. This results in: * Single-digit-millisecond cold-start times (perfect for bursty API traffic). @@ -25,7 +25,7 @@ This results in: The open internet exposes API Gateways, making them often the most attacked component. Unikraft Cloud isolates each instance at the virtual machine level while keeping footprint minimal: -* Immutable, single-purpose unikernel images reduce attack surface. +* Immutable, single-purpose microVM images reduce attack surface. * Strong VM-level isolation without container overhead. * Built-in memory safety and image signing to ensure trust at deployment. diff --git a/pages/use-cases/headless-browsers.mdx b/pages/use-cases/headless-browsers.mdx index 23e57fc5..2ff44729 100644 --- a/pages/use-cases/headless-browsers.mdx +++ b/pages/use-cases/headless-browsers.mdx @@ -6,7 +6,7 @@ navigation_icon: app-window import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" Headless browsers power web scraping, automated testing, Search Engine Optimization (SEO) rendering, and synthetic monitoring. -They're resource-intensive, security-sensitive, and often run in short burstsβ€”making them ideal candidates for unikernel-based, scale-to-zero infrastructure. +They're resource-intensive, security-sensitive, and often run in short burstsβ€”making them ideal candidates for microVM-based, scale-to-zero infrastructure. ## Why headless browsers on Unikraft Cloud @@ -25,7 +25,6 @@ With Unikraft Cloud: * Each browser runs in its own VM, isolated by design. * Minimal OS footprint drastically reduces attack surface. -* Immutable unikernel images prevent tampering. ### πŸ’Έ Cost-efficient scale-to-zero diff --git a/pages/use-cases/remote-ides.mdx b/pages/use-cases/remote-ides.mdx index 27b30d07..209cbca1 100644 --- a/pages/use-cases/remote-ides.mdx +++ b/pages/use-cases/remote-ides.mdx @@ -5,19 +5,19 @@ navigation_icon: square-chevron-right Remote Integrated Development Environments (IDEs) have become essential for cloud-native development, collaboration, and education. But traditional setups often suffer from **slow startup times, high idle costs, and complex resource management**. -With **Unikraft Cloud**, remote IDEs gain the advantages of **unikernels**, making them **fast, secure, and truly serverless**. +With **Unikraft Cloud**, remote IDEs gain the advantages of **microVMs**, making them **fast, secure, and truly serverless**. ## Why run remote IDEs on Unikraft Cloud ### ⚑ Instant developer environments -Unikraft unikernels boot in milliseconds, enabling **instant spin-up of full-featured IDEs** on demand. +Unikraft microVMs boot in milliseconds, enabling **instant spin-up of full-featured IDEs** on demand. Developers start coding immediately without waiting for heavy VMs or containers to initialise. ### πŸ”’ Secure, isolated workspaces -Each IDE runs as a **dedicated unikernel instance**, ensuring strong workload isolation and reducing the risk of cross-tenant data leaks. +Each IDE runs as a **dedicated microVM instance**, ensuring strong workload isolation and reducing the risk of cross-tenant data leaks. Sensitive code stays protected in a **minimal, hardened environment**. @@ -34,7 +34,7 @@ Perfect for **pair programming, CI/CD pipelines, or education platforms**. ### πŸš€ High performance with low overhead -Unikernels run closer to bare metal than containers, providing developers with +MicroVMs run closer to bare metal than containers, providing developers with **snappy, low-latency environments** that feel as fast as local codingβ€”without sacrificing portability or scalability. diff --git a/pages/use-cases/serverless-databases.mdx b/pages/use-cases/serverless-databases.mdx index 702d39d3..ef88d1ff 100644 --- a/pages/use-cases/serverless-databases.mdx +++ b/pages/use-cases/serverless-databases.mdx @@ -6,24 +6,24 @@ navigation_icon: database-zap import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" Databases are central to modern apps, but they're notoriously resource-hungry, slow to scale, and costly to operate at low utilisation. -Traditional VM or container-based solutions keep idle resources running, resulting in waste and inefficiency. -With **Unikraft Cloud**, serverless databases gain the advantages of **unikernels**, combining **extreme performance** with **true scale-to-zero efficiency**. +Traditional VM- or container-based solutions keep idle resources running, resulting in waste and inefficiency. +With **Unikraft Cloud**, serverless databases gain the advantages of **microVMs**, combining **extreme performance** with **true scale-to-zero efficiency**. ## Why run serverless databases on Unikraft Cloud ### ⚑ Instant boot, millisecond latency -Unikraft unikernels start in milliseconds, enabling databases to **scale up instantly** when requests arrive and **shut down to zero** when idle. +Unikraft microVMs start in milliseconds, enabling databases to **scale up instantly** when requests arrive and **shut down to zero** when idle. This ensures the system uses resources **only when needed**, without cold-start penalties. ### πŸ”’ Stronger security by design -Each database instance runs as a **specialised, single-process unikernel**, drastically reducing the attack surface compared to general-purpose operating systems. +Each database instance runs as a **specialised, single-process microVM**, drastically reducing the attack surface compared to general-purpose OSes. This isolation protects customer data with **built-in, lightweight security**. ### πŸ’° Cost-efficient scale-to-zero -Unikraft's unikernel architecture allows serverless databases to **consume no resources when idle** and scale to thousands of instances under load. +Unikraft's microVM architecture allows serverless databases to **consume no resources when idle** and scale to thousands of instances under load. You pay only for active queries, making it ideal for **spiky workloads, dev/test environments, and SaaS platforms**. ### πŸ›  Seamless serverless integration @@ -33,7 +33,7 @@ Databases can integrate with API gateways, event triggers, and headless services ### πŸ“ˆ Performance without trade-offs -Unlike traditional serverless platforms where databases often suffer from high overhead, unikernel-based instances deliver **bare-metal-like throughput and predictable latency**. +Unlike traditional serverless platforms where databases often suffer from high overhead, microVM-based instances deliver **bare-metal-like throughput and predictable latency**. These instances optimise both Online Transaction Processing (OLTP) and Online Analytical Processing (OLAP) workloads. From 5f18e7bd8a3fee1f495c51c1d1c21429295513cc Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Sun, 15 Mar 2026 10:29:01 +0100 Subject: [PATCH 045/131] fix(kubernetes): replace unikernel with microVM Replace unikernel terminology with microVM in the Kubernetes integration page including the Kraftlet description. Signed-off-by: Jerome Jaggi --- pages/integrations/kubernetes.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pages/integrations/kubernetes.mdx b/pages/integrations/kubernetes.mdx index 7dbe909c..60b98a0d 100644 --- a/pages/integrations/kubernetes.mdx +++ b/pages/integrations/kubernetes.mdx @@ -5,16 +5,16 @@ navigation_icon: ship-wheel Unikraft Cloud integrates seamlessly with any Kubernetes cluster through a virtual [kubelet](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) known as **Kraftlet**. This is a lightweight Kubernetes node implementation which connects your cluster to Unikraft Cloud's high-performance compute instead of running real pods locally. -This enables developers to deploy and manage Unikraft unikernels as if they were native Kubernetes pods. +This enables developers to deploy and manage Unikraft microVMs as if they were native Kubernetes pods. This integration extends Kubernetes' scheduling and orchestration capabilities to the Unikraft Cloud platform. -This allows workloads to take advantage of unikernel-level I/O performance, security, cold start and transparent scale-to-zero efficiency while retaining full compatibility with existing Kubernetes tooling. +This allows workloads to take advantage of microVM-level I/O performance, security, cold start and transparent scale-to-zero efficiency while retaining full compatibility with existing Kubernetes tooling. Upon startup, Kraftlet will register itself as a worker node with the Kubernetes API. Once Kraftlet registers itself as a node, Kubernetes can schedule Pods onto it. Any Pod scheduled to the Kraftlet node won't run as a container within the cluster. -Instead, it will run a highly optimized, ultra lightweight unikernel VM instance on Unikraft Cloud. +Instead, it will run a highly optimized microVM on Unikraft Cloud. Kraftlet will manage the Pod lifecycle to make sure the apps are up and running. From 5c93dfa7296944341158cd54c362aaec98e1c352 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Sun, 15 Mar 2026 10:29:05 +0100 Subject: [PATCH 046/131] fix(troubleshooting): replace unikernel with microVM Replace 'runtimes (unikernels)' with 'runtimes (microVMs)' in the Kraftfile explanation. Signed-off-by: Jerome Jaggi --- pages/platform/troubleshooting.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/platform/troubleshooting.mdx b/pages/platform/troubleshooting.mdx index 7f7a1631..4d4a9f1e 100644 --- a/pages/platform/troubleshooting.mdx +++ b/pages/platform/troubleshooting.mdx @@ -163,7 +163,7 @@ labels: cloud.unikraft.v1.instances/scale_to_zero.cooldown_time_ms: 1000 ``` -The `runtime` specifies one of the Unikraft Cloud runtimes (unikernels) built to run different languages and apps. +The `runtime` specifies one of the Unikraft Cloud runtimes (microVMs) built to run different languages and apps. Here it specifies a Python runtime. The `rootfs` parameter tells `kraft` to use a `Dockerfile` in the same directory to build the root filesystem, and the `cmd` parameter which command to run when deployed (although you can also specify this in the `Dockerfile`). From 784993da8e5fc006a31036ee32a92cbdd8b323f8 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 15:29:24 +0100 Subject: [PATCH 047/131] docs: add behavioural notes and platform features to kubernetes page Signed-off-by: Jerome Jaggi --- pages/integrations/kubernetes.mdx | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/pages/integrations/kubernetes.mdx b/pages/integrations/kubernetes.mdx index 7dbe909c..8a41885c 100644 --- a/pages/integrations/kubernetes.mdx +++ b/pages/integrations/kubernetes.mdx @@ -237,6 +237,41 @@ NAME CREATED AT SIZE ATTACHED TO MOUNTED BY STATE PERS my-claim 8 minutes ago 10 MiB nginx-pod-nginx nginx-pod-nginx mounted true ``` +## Kraftlet internals + +This section describes how Kraftlet translates Kubernetes objects into Unikraft Cloud resources. + +### Ports and handlers + +When Kraftlet maps a Kubernetes Service port to a Unikraft Cloud service, it derives the [handler](/platform/services#handlers) from the port number automatically: + +| Port | Handler applied | +|------|-----------------| +| `80` | `http` | +| `443` | `tls + http` | +| Any other port | `tls` | + +This is why the example above produces `443:8080/tls+http` in `kraft cloud service list`. +Kraftlet infers `tls+http` from port 443. + +### Multi-container pods + +Kraftlet maps each container in a pod to a **separate Unikraft Cloud instance**. +When a Pod has a single container, the Unikraft Cloud service takes the Kubernetes Service name directly. +When a Pod has more than one container, each container gets its own Unikraft Cloud service, named `-` (for example, `my-svc-app` and `my-svc-sidecar`). + +Kraftlet supports init containers. +Kraftlet schedules both regular containers and init containers as Unikraft Cloud instances, and deletes them together when you delete the Pod. + +### Resource lifecycle + +When you delete a Kubernetes object, Kraftlet deletes the corresponding Unikraft Cloud resource: + +| Kubernetes object deleted | Unikraft Cloud resource deleted | +|---|---| +| Pod / Deployment replica | Instance (and service group if no other Pods are backing it) | +| PersistentVolumeClaim | Unikraft Cloud volume | + ## Notes * [**Instances**](/platform/instances) @@ -255,6 +290,40 @@ my-claim 8 minutes ago 10 MiB nginx-pod-nginx nginx-pod-nginx mounted true For each creation of such Persistent Volume Claim (PVC) object, the Kraftlet will create a corresponding Unikraft Cloud volume and a `PersistentVolume` object to bind the PVC object to. Kraftlet allows for volume management through Kubernetes clusters. +## Platform features + +Kraftlet supports the following Unikraft Cloud platform features on Kraftlet-managed resources: + +* [**Instance templates**](/platform/instances#instance-templates) + + Frequently deployed workloads can go into instance templates. + Templates pre-warm the snapshot, reducing cold-start latency for every new instance created from the template. + When Kraftlet creates an instance from a Pod spec, you can pre-position an instance template to speed up scheduling. + +* [**Scale-to-zero**](/features/scale-to-zero) + + Instances attached to a Unikraft Cloud service suspend automatically when idle. + Scale-to-zero runs by default for service-backed pods and you can configure it via Pod annotations (see [Annotations](#annotations) below). + +## Annotations + +Kraftlet reads the following annotations from Pod and Service objects to configure Unikraft Cloud resources. + +### Pod annotations + +| Annotation | Type | Default | Description | +|---|---|---|---| +| `cloud.unikraft.v1.instances/autostart` | boolean | `true` | Whether the instance starts automatically when Kraftlet schedules the Pod. | +| `cloud.unikraft.v1.instances/template` | string | β€” | Name of a pre-existing Unikraft Cloud instance template to use instead of the container image. | +| `cloud.unikraft.v1.instances/scale_to_zero.policy` | `on` \| `off` \| `idle` | `on` | Enables or disables scale-to-zero for service-backed instances. | +| `cloud.unikraft.v1.instances/scale_to_zero.stateful` | boolean | `false` | When `true`, Kraftlet retains the instance state when scaling to zero. | +| `cloud.unikraft.v1.instances/scale_to_zero.cooldown_time_ms` | integer | `1000` | Idle time in milliseconds before Kraftlet suspends the instance. | + +### Service annotations + +| Annotation | Type | Default | Description | +|---|---|---|---| +| `cloud.unikraft.v1.services/domain` | string | β€” | Custom domain for the Unikraft Cloud service. For multi-container pods, prefix with the container name (`cloud.unikraft.v1.services/domain.`) to set a per-container domain, or use the global annotation to derive `-` automatically. | ## Resources From c5f7ffa55af877924b787f6587541bdd397ecaae Mon Sep 17 00:00:00 2001 From: Maria Sfiraiala Date: Mon, 16 Mar 2026 16:02:38 +0200 Subject: [PATCH 048/131] docs: Emphasize s20 notif usage Signed-off-by: Maria Sfiraiala --- pages/features/scale-to-zero.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/features/scale-to-zero.mdx b/pages/features/scale-to-zero.mdx index a32c191d..727e80a6 100644 --- a/pages/features/scale-to-zero.mdx +++ b/pages/features/scale-to-zero.mdx @@ -111,7 +111,7 @@ Your app can listen on vsock port `138` and use the signal to: ### Configuring the notification lead time -Use the `notify_time_ms` field in the `scale_to_zero` configuration when creating or updating an instance: +Use the `notify_time_ms` field in the `scale_to_zero` configuration when creating or updating an instance to specify the number of milliseconds before the scaletozero event, when the platform should send the notification signal: ```json title="POST /v1/instances" { @@ -126,7 +126,7 @@ This sends the notification 2 seconds before the cooldown expires and suspension :::note `notify_time_ms` must be less than `cooldown_time_ms`. -If `notify_time_ms` is `0` (the default), the platform skips the notification and suspends the instance immediately when the cooldown expires. +If `notify_time_ms` is `0` (the default), the platform skips the notification and suspends the instance immediately when the cooldown expires, without informing the guest. ::: ## Stateful scale-to-zero From 5cd464abfb7ba26209bfbf3b78db1072728405f6 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 15:09:09 +0100 Subject: [PATCH 049/131] docs: add CLI registries reference page Signed-off-by: Jerome Jaggi --- pages/cli/registries.mdx | 217 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 pages/cli/registries.mdx diff --git a/pages/cli/registries.mdx b/pages/cli/registries.mdx new file mode 100644 index 00000000..44541f58 --- /dev/null +++ b/pages/cli/registries.mdx @@ -0,0 +1,217 @@ +--- +title: Registries +navigation_icon: package +--- + +Unikraft Cloud uses a central OCI registry at `index.unikraft.io` to store images. +Every image you build and push lands in this registry under your account's namespace. +When you start an instance, the platform pulls the image from this registry automatically. + +Each node has a local registry also running for directly pushing to a specific node. +These registries have the address formatted as `index..unikraft.cloud`. +The main advantage of pushing to a node's registry is that it avoids the round trip to the central registry. +This speeds up deployments and reduces bandwidth usage. + +Directly pushing to a node's registry or using the central registry is interchangeable. +The platform handles synchronization between them. + +## Image naming + +The platform addresses images using the standard OCI reference format: + +``` +index.unikraft.io//: +index..unikraft.cloud//: +``` + +For example: + +``` +index.unikraft.io/alice/http-python312:latest +index.unikraft.io/alice/http-python312@sha256:278cb8b1... + +index.node1.unikraft.cloud/alice/http-python312:latest +index.node1.unikraft.cloud/alice/http-python312@sha256:278cb8b1... +``` + +The `` segment is your Unikraft Cloud account name, available as the `UKC_USER` environment variable in most guides. +Tags are arbitrary strings. +The platform defaults to `latest` when you don't specify a tag. +You can also refer to images by digest to pin to an exact version. + +## Authentication + +Registry authentication uses the same API token as the rest of the platform. +Set `UKC_TOKEN` before running any `kraft` command: + +```bash title="" +export UKC_TOKEN= +``` + +`kraft` reads this token automatically and uses it for both the platform API and registry operations. +You will also need to use the `kraft login` command for `kraft pkg` operations: + + + + ```bash title="" + kraft login -u "$UKC_USER" -t "$UKC_TOKEN" index.unikraft.io + ``` + + + ```bash title="" + kraft login -u "$UKC_USER" -t "$UKC_TOKEN" index..unikraft.cloud + ``` + + + +## Pushing images + +### Via `kraft cloud deploy` (recommended) + +The simplest way to push an image is `kraft cloud deploy`, which builds, packages, pushes, and starts an instance in one command: + + + + ```bash title="" + kraft cloud deploy -p 443:8080 -M 256 --name . + ``` + + + ```bash title="" + kraft cloud deploy -p 443:8080 -M 256 --name --image index..unikraft.cloud// . + ``` + + + +During deployment you will see output confirming the push: + + + + ```ansi title="" + [+] packaging index.unikraft.io/alice/my-app:latest... done! + [+] pushing index.unikraft.io/alice/my-app:latest (kraftcloud/x86_64)... done! + ``` + + + ```ansi title="" + [+] packaging index..unikraft.cloud/alice/my-app:latest... done! + [+] pushing index..unikraft.cloud/alice/my-app:latest (kraftcloud/x86_64)... done! + ``` + + + +### Via `kraft pkg --push` + +For more control, for example when packaging [ROMs](/features/roms) or base images, use `kraft pkg` with the `--push` flag: + + + + ```bash title="" + kraft pkg \ + --plat kraftcloud \ + --arch x86_64 \ + --name index.unikraft.io/"$UKC_USER"/my-app:latest \ + --push \ + . + ``` + + + ```bash title="" + kraft pkg \ + --plat kraftcloud \ + --arch x86_64 \ + --name index..unikraft.cloud/"$UKC_USER"/my-app:latest \ + --push \ + . + ``` + + + +## Listing images + +```bash title="" +kraft cloud image ls +``` + + + + ```text title="" + NAME VERSION SIZE + alice/http-python312 latest 77 MB + alice/my-app latest 42 MB + ``` + + + ```text title="" + NAME VERSION SIZE + alice/http-python312 latest 77 MB + index..unikraft.cloud/alice/my-app latest 42 MB + ``` + + + +:::note +There may be a delay of a few minutes between pushing or removing an image and `kraft cloud image ls` reflecting the change. +::: + +## Removing images + + + + ```bash title="" + kraft cloud img rm my-app + ``` + + + ```bash title="" + # Not supported yet for direct pushing to node registries. + # Remove images from the node itself periodically. + ``` + + + +## Kernel layer deduplication + +An image has two OCI layers: a kernel layer and a rootfs layer. +When you push an update to an existing image, `kraft` checks whether the kernel layer is already present in the registry and skips re-uploading it if so. +Only the rootfs layer travels over the wire. +This makes iterative pushes faster and cheaper on bandwidth. + +[ROMs](/features/roms) follow the same packaging system but go out without a kernel layer. +They only have a rootfs. +They appear in `kraft cloud image ls` alongside regular images. + +## Image addresses in instance creation + +When creating an instance directly from an existing image, reference it by tag or digest: + + + + ```bash title="" + # By tag + kraft cloud instance create --port 443:8080 --start -M 256 \ + index.unikraft.io/alice/my-app:latest + + # By digest (exact version pinning) + kraft cloud instance create --port 443:8080 --start -M 256 \ + index.unikraft.io/alice/my-app@sha256:278cb8b1... + ``` + + + ```bash title="" + # By tag + kraft cloud instance create --port 443:8080 --start -M 256 \ + index..unikraft.cloud/alice/my-app:latest + + # By digest (exact version pinning) + kraft cloud instance create --port 443:8080 --start -M 256 \ + index..unikraft.cloud/alice/my-app@sha256:278cb8b1... + ``` + + + +## Learn more + +* [Images](/platform/images): build, package, and deploy workflow +* The `kraft cloud` [CLI reference](/cli/) +* Unikraft Cloud's [REST API reference](/api/platform/v1) From b1c4e194db882eed7a6a0a3ae7431f851d3eb2e5 Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Mon, 16 Mar 2026 17:43:48 +0200 Subject: [PATCH 050/131] fix(pages): Remove references to the broken 'ENV' in the FAQ This is fixed on staging and will be moved to stable soon. Signed-off-by: Cezar Craciunoiu --- pages/faq.mdx | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/pages/faq.mdx b/pages/faq.mdx index 7b7ea74b..e79e0b25 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -226,9 +226,7 @@ There's also a chance that Kraft staging contains changes available only on non- This is the current list of ignored keywords: `EXPOSE`, `HEALTHCHECK`, `ONBUILD`, `SHELL`, `STOPSIGNAL`, `VOLUME`. The `USER` keyword is relevant for running subsequent `RUN` instructions in the Dockerfile, but not for the `ENTRYPOINT` and `CMD` commands. -At runtime, Unikraft Cloud instances run as `root` user, unless explicitly switching to another user. - -Currently, `kraft` parses the `ENV` keyword, but the platform discards the result in the current stable version. +At runtime, Unikraft Cloud instances run as `root` user, unless explicitly switching to another user. #### How does the image size and memory relate to boot times? @@ -274,23 +272,6 @@ Finally, kernels can also run without a rootfs. They don't do anything, but support exists to run them. -#### How to replicate the `ENV`/`ENTRYPOINT` of a container? - -To reproduce the starting environment without specifying extra arguments in the command line you can replace your Kraftfile's `cmd:` with the path to a script. -In there you can place all `ENV`s from the dockerfile and call the binary as you want. -You can also use the `env:` field in the Kraftfile. - -When building a rootfs directly from a DockerHub image, or a `Dockerfile` which starts from a DockerHub image, you should inspect the environment set by said image (example with `library/node`): - -```bash -docker inspect library/node --format='{{json .Config.Env}}' | jq -``` - -If you are using the Unikraft OS, you need to specify those in the command like with `--env`. - -Note: `ENTRYPOINT` is a recognised keyword in the Dockerfile so it should propagate up into the image. - - #### How to tell if an app can run in the Unikraft kernel or TinyX? No exact suite can determine if your app can run on one or another. @@ -305,6 +286,7 @@ Other examples of unsupported formats are 32bit executables and non-PIE (Positio Other small differences exist, which you should report to the Unikraft Team for fixing, as the Unikraft kernel tries to follow Linux and the POSIX format. + #### How does the [rootfs format](/tutorials/rootfs-formats) and size equate to the memory used? When using the `CPIO` file system, the memory allocated to the instance needs to be at least twice as big as the image size. From 1ee1c2777f109f407cc77597b61df95b240285bd Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Tue, 17 Mar 2026 09:49:22 +0000 Subject: [PATCH 051/131] docs: Update Go SDK page to be up-to-date Signed-off-by: Justin Chadwell --- pages/integrations/sdks/go.mdx | 257 +++++++++++++++++++++++---------- 1 file changed, 177 insertions(+), 80 deletions(-) diff --git a/pages/integrations/sdks/go.mdx b/pages/integrations/sdks/go.mdx index 80fa3e36..ce019a50 100644 --- a/pages/integrations/sdks/go.mdx +++ b/pages/integrations/sdks/go.mdx @@ -3,8 +3,9 @@ title: Go SDK navigation_icon: code --- -The Unikraft Cloud Go SDK is an autogenerated client library that interfaces with the Unikraft Cloud platform API, based on the public OpenAPI specification. -It's on the `prod-stable` branch and is the most mature of the available SDKs. +The Unikraft Cloud Go SDK is an autogenerated client library that interfaces +with the Unikraft Cloud platform API, based on the public OpenAPI +specification at . ## Installation @@ -12,7 +13,7 @@ It's on the `prod-stable` branch and is the most mature of the available SDKs. go get unikraft.com/cloud/sdk ``` -Requires Go 1.24 or later. +Requires Go 1.25 or later. ## Quickstart @@ -20,41 +21,47 @@ Requires Go 1.24 or later. package main import ( - "context" - "fmt" + "context" + "fmt" - ukp "unikraft.com/cloud/sdk/platform" + "unikraft.com/cloud/sdk/platform" ) func main() { - ctx := context.Background() - - client := ukp.NewClient( - ukp.WithDefaultMetro("fra0"), - ukp.WithToken("your-api-token"), - ) - - resp, err := client.GetInstances(ctx, nil, true) - if err != nil { - panic(err) - } - - for _, instance := range resp.Data.Instances { - fmt.Printf("UUID: %s\n", *instance.Uuid) - fmt.Printf("Name: %s\n", *instance.Name) - fmt.Printf("State: %s\n", *instance.State) - fmt.Println("---") - } + ctx := context.Background() + + // Create a new client. The token and default metro are automatically + // read from environment variables (UKC_TOKEN and UKC_METRO). + client := platform.NewClient() + + // List all instances + resp, err := client.GetInstances(ctx, nil, nil) + if err != nil { + panic(err) + } + + // Check for API-level errors + if resp.Status != "success" { + panic(resp.Message) + } + + for _, inst := range resp.Data.Instances { + fmt.Printf("Name: %s\n", *inst.Name) + fmt.Printf("UUID: %s\n", *inst.Uuid) + fmt.Printf("State: %s\n", *inst.State) + fmt.Printf("Image: %s\n", *inst.Image) + fmt.Println("---") + } } ``` ## Authentication -Pass your token via `ukp.WithToken()`: +Pass your token via `platform.WithToken()`: ```go title="" -client := ukp.NewClient( - ukp.WithToken("your-api-token"), +client := platform.NewClient( + platform.WithToken("your-api-token"), ) ``` @@ -65,24 +72,29 @@ Or set one of the following environment variables. 2. `UNIKRAFT_CLOUD_TOKEN` 3. `KRAFTCLOUD_TOKEN` (legacy name) +You can also set the default metro via the `UKC_METRO` environment variable. +If not specified, the SDK defaults to `fra`. + ```go title="" -// No WithToken needed β€” NewClient reads the environment automatically. -client := ukp.NewClient( - ukp.WithDefaultMetro("fra0"), -) +// No WithToken/WithDefaultMetro needed, NewClient reads the environment automatically +client := platform.NewClient() ``` ## Client options -| Option | Description | -|--------|-------------| -| `WithDefaultMetro(string)` | Metro to use when you don't specify one per-request (default: `fra0`) | -| `WithToken(string)` | API token | -| `WithHTTPClient(...)` | Custom `http.Client` | -| `WithUserAgent(string)` | Override the `User-Agent` header | -| `WithAllowInsecure(bool)` | Skip TLS verification (development only) | +| Option | Description | +| ----------------------------- | -------------------------------------------------------------- | +| `WithDefaultEndpoint(string)` | Full API endpoint address (for example, `https://api.fra.unikraft.cloud`) | +| `WithDefaultMetro(string)` | Metro shorthandβ€”converted to endpoint address automatically | +| `WithToken(string)` | API token | +| `WithHTTPClient(...)` | Custom `http.Client` | +| `WithUserAgent(string)` | Override the `User-Agent` header | +| `WithAllowInsecure(bool)` | Skip TLS verification (development only) | -The base address is `https://api..kraft.cloud`. +`WithDefaultEndpoint` and `WithDefaultMetro` both set the API endpoint. +Use `WithDefaultMetro("fra")` as a shorthand for `WithDefaultEndpoint("https://api.fra.unikraft.cloud")`. + +The base address is `https://api..unikraft.cloud`. ## Resources @@ -90,123 +102,208 @@ The `platform.Client` interface covers the full Unikraft Cloud REST API surface. ### Instances -```go title="" +```go // Create client.CreateInstance(ctx, req) +``` +```go // Read -client.GetInstances(ctx, names, details) +client.GetInstances(ctx, ids, details) client.GetInstanceByUUID(ctx, uuid, details) +``` -// Start / stop +```go +// Start / Stop client.StartInstanceByUUID(ctx, uuid) -client.StartInstances(ctx, names) -client.StopInstanceByUUID(ctx, uuid, force, drainTimeoutMs) -client.StopInstances(ctx, names, force, drainTimeoutMs) +client.StartInstances(ctx, ids) +client.StopInstanceByUUID(ctx, uuid, req) +client.StopInstances(ctx, req) +``` -// Update (PATCH) +```go +// Update client.UpdateInstanceByUUID(ctx, uuid, req) client.UpdateInstances(ctx, req) +``` +```go // Delete client.DeleteInstanceByUUID(ctx, uuid) -client.DeleteInstances(ctx, names) +client.DeleteInstances(ctx, ids) +``` +```go // Logs and metrics -client.GetInstanceLogsByUUID(ctx, uuid) -client.GetInstanceLogs(ctx, names) +client.GetInstanceLogsByUUID(ctx, uuid, req) +client.GetInstanceLogs(ctx, req) client.GetInstanceMetricsByUUID(ctx, uuid) -client.GetInstanceMetrics(ctx, names) +client.GetInstanceMetrics(ctx, ids) +``` +```go // Wait for a target state -client.WaitInstanceByUUID(ctx, uuid, state, timeoutMs) -client.WaitInstances(ctx, names, state, timeoutMs) +client.WaitInstanceByUUID(ctx, uuid, req) +client.WaitInstances(ctx, req) ``` ### Instance templates -```go title="" +```go +// Create client.CreateTemplateInstances(ctx, req) -client.GetTemplateInstances(ctx, fromUuid, count, tags) +``` + +```go +// Read +client.GetTemplateInstances(ctx, ids, details, count, tags) client.GetTemplateInstanceByUUID(ctx, uuid, details) +``` + +```go +// Update client.UpdateTemplateInstanceByUUID(ctx, uuid, req) client.UpdateTemplateInstances(ctx, req) +``` + +```go +// Delete client.DeleteTemplateInstanceByUUID(ctx, uuid) -client.DeleteTemplateInstances(ctx, names) +client.DeleteTemplateInstances(ctx, ids) ``` ### Service groups -```go title="" +```go +// Create client.CreateServiceGroup(ctx, req) -client.GetServiceGroups(ctx, names, details) +``` + +```go +// Read +client.GetServiceGroups(ctx, ids, details) client.GetServiceGroupByUUID(ctx, uuid, details) +``` + +```go +// Update client.UpdateServiceGroupByUUID(ctx, uuid, req) client.UpdateServiceGroups(ctx, req) +``` + +```go +// Delete client.DeleteServiceGroupByUUID(ctx, uuid) -client.DeleteServiceGroups(ctx, names) +client.DeleteServiceGroups(ctx, ids) ``` ### Autoscale -```go title="" -// Configuration +```go +// Configuration (by service group UUID) client.CreateAutoscaleConfigurationByServiceGroupUUID(ctx, uuid, req) client.GetAutoscaleConfigurationsByServiceGroupUUID(ctx, uuid) client.DeleteAutoscaleConfigurationsByServiceGroupUUID(ctx, uuid) +``` + +```go +// Configuration (batch) +client.CreateAutoscaleConfigurations(ctx, req) +client.GetAutoscaleConfigurations(ctx, ids) +client.DeleteAutoscaleConfigurations(ctx, ids) +``` +```go // Policies -client.CreateAutoscaleConfigurationPolicy(ctx, serviceGroupUUID, req) -client.GetAutoscaleConfigurationPolicies(ctx, serviceGroupUUID) -client.GetAutoscaleConfigurationPolicyByName(ctx, serviceGroupUUID, name) -client.DeleteAutoscaleConfigurationPolicies(ctx, serviceGroupUUID) -client.DeleteAutoscaleConfigurationPolicyByName(ctx, serviceGroupUUID, name) +client.CreateAutoscaleConfigurationPolicy(ctx, uuid, req) +client.GetAutoscaleConfigurationPolicies(ctx, uuid, req) +client.GetAutoscaleConfigurationPolicyByName(ctx, uuid, name) +client.DeleteAutoscaleConfigurationPolicies(ctx, uuid, req) +client.DeleteAutoscaleConfigurationPolicyByName(ctx, uuid, name) ``` ### Volumes -```go title="" +```go +// Create client.CreateVolume(ctx, req) -client.GetVolumes(ctx, names, details) +``` + +```go +// Read +client.GetVolumes(ctx, ids, details) client.GetVolumeByUUID(ctx, uuid, details) +``` + +```go +// Attach / Detach client.AttachVolumeByUUID(ctx, uuid, req) client.AttachVolumes(ctx, req) -client.DetachVolumeByUUID(ctx, uuid) -client.DetachVolumes(ctx, names) +client.DetachVolumeByUUID(ctx, uuid, req) +client.DetachVolumes(ctx, req) +``` + +```go +// Clone +client.CloneVolumeByUUID(ctx, uuid, req) +client.CloneVolumes(ctx, req) +``` + +```go +// Update client.UpdateVolumeByUUID(ctx, uuid, req) client.UpdateVolumes(ctx, req) +``` + +```go +// Delete client.DeleteVolumeByUUID(ctx, uuid) -client.DeleteVolumes(ctx, names) +client.DeleteVolumes(ctx, ids) ``` ### Certificates -```go title="" +```go +// Create client.CreateCertificate(ctx, req) -client.GetCertificates(ctx, names, details) -client.GetCertificateByUUID(ctx, uuid, details) +``` + +```go +// Read +client.GetCertificates(ctx, ids, details) +client.GetCertificateByUUID(ctx, uuid) +``` + +```go +// Delete client.DeleteCertificateByUUID(ctx, uuid) -client.DeleteCertificates(ctx, names) +client.DeleteCertificates(ctx, ids) ``` ### Images -```go title="" -client.GetImageByTag(ctx, tag) -client.GetImageByDigest(ctx, digest) +```go +// Read +client.GetImages(ctx, req, namespace) ``` ### Users and quotas -```go title="" +```go +// Read quotas client.GetUser(ctx) client.GetUserByUUID(ctx, uuid) -client.AddUsers(ctx, req) +``` + +```go +// Create users +client.AddUsers(ctx) ``` ### Health -```go title="" +```go +// Check node health client.Healthz(ctx) ``` From dc178755f65db2c09cd7465adc2de3b10886e94c Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Tue, 17 Mar 2026 13:17:36 +0100 Subject: [PATCH 052/131] docs(features/forking): Rewrite with user-facing filesystem interface Rewrites forking doc to focus on the /uk/libukp FUSE filesystem that applications actually interact with. Moves vsock wire protocol details to a Protocol Internals section at the bottom. New sections: UKP filesystem overview, triggering a fork, monitoring children, waiting for exit, preventing scale-to-zero, error handling, concurrent fork requests. Source: unikraft-cloud/linux-base tlandsberg/vm-fork Generated-by: OpenCode documentation agent (manual run) Signed-off-by: Jerome Jaggi --- pages/features/forking.mdx | 274 +++++++++++++++++++++++++++++-------- 1 file changed, 215 insertions(+), 59 deletions(-) diff --git a/pages/features/forking.mdx b/pages/features/forking.mdx index 2d2d3f0b..91cb13a5 100644 --- a/pages/features/forking.mdx +++ b/pages/features/forking.mdx @@ -4,99 +4,255 @@ navigation_icon: git-fork --- :::caution -Instance forking is a preview feature and isn't yet available on stable. +Instance forking is a preview feature and is not yet available on stable. The interface described here reflects the current implementation and may change before general availability. ::: Instance forking allows a running instance to create an independent copy of itself at a snapshot boundary. Both the original instance (the **parent**) and the copy (the **child**) resume execution from the same memory state. - This is conceptually similar to `fork(2)` in a POSIX process. -After the call, two independent instances run with identical state, and each can determine its own role by inspecting the messages it receives from the platform. - -## How it works -Forking is **guest-initiated**: the app inside an instance triggers the fork programmatically by sending a request over the platform's guest communication channel. +Forking is **guest-initiated**: the application inside an instance triggers the fork through a filesystem interface. No REST API endpoint or CLI command exists to fork an instance externally. -When the guest triggers a fork: +## The UKP filesystem -1. The platform takes a snapshot of the parent instance. -2. The platform creates a new child instance from that snapshot with a fresh network interface. -3. Both parent and child start from the same snapshot. -4. The platform notifies each instance of its role via messages over [vsock](https://man7.org/linux/man-pages/man7/vsock.7.html) port `137`. +The fork interface is exposed through a FUSE filesystem mounted at `/uk/libukp` inside every instance. +Applications trigger forks and monitor child instances by reading and writing files in this filesystem. -The child has [delete-on-stop](/platform/instances#delete-on-stop) set automaticallyβ€”it's ephemeral and the platform removes it when it stops. +The filesystem exposes the following top-level entries: -## Guest notifications +| Path | Read | Write | Description | +|------|------|-------|-------------| +| `/uk/libukp/fork` | Returns the child UUID after a fork (for the parent), or empty (for the child). | Triggers a new fork operation. | Main entry point for forking. | +| `/uk/libukp/vm/` | Directory listing of all child instance UUIDs. | β€” | Each child gets a subdirectory named by its UUID. | +| `/uk/libukp/scale_to_zero_disable` | Returns the current counter value (e.g. `=3`). | Modify the counter: `+1`, `-1`, `+N`, `-N`, or `=N`. | Prevents scale-to-zero suspension while the counter is non-zero. | +| `/uk/libukp/template_instance` | β€” | Write any value to convert the current instance into a template. | Write-only. | -After a fork completes, both the parent and child receive vsock messages on port `137`. +## Triggering a fork -### Parent receives: `FORK_CREATED` +To fork the current instance, write any value to the `fork` file: -The parent receives a `FORK_CREATED` message with the following fields: +```bash +echo "1" > /uk/libukp/fork +``` -| Field | Type | Description | -|-------|------|-------------| -| `msg_type` | uint32 | `0x2`β€”identifies this as a `FORK_CREATED` message. | -| `correlation_id` | uint32 | Echoed from the original fork request. | -| `child_id` | UUID (16 bytes) | UUID of the newly created child instance. | -| `snapshot_id` | UUID (16 bytes) | UUID of the snapshot the child originates from. | -| `creation_time` | uint64 | Child creation timestamp (UTC, seconds since Unix epoch). | -| `fqdn_len` | uint16 | Length of the child's FQDN string (may be 0). | -| `fqdn` | char[] | Child's private FQDN (variable-length, follows the fixed header). | +The write blocks until the platform completes the fork. +When it returns, the parent can read the child's UUID from the same file: -### Child receives: `PARENT_ID` +```bash +# Returns the UUID of the newly created child (parent only) +cat /uk/libukp/fork +``` -The child receives a `PARENT_ID` message telling it which instance it originates from: +For the child instance, reading `/uk/libukp/fork` returns an empty response (a zero UUID). +This is how an application determines whether it is the parent or the child after a fork. -| Field | Type | Description | -|-------|------|-------------| -| `msg_type` | uint32 | `0x3`β€”identifies this as a `PARENT_ID` message. | -| `correlation_id` | uint32 | Echoed from the original fork request. | -| `parent_id` | UUID (16 bytes) | UUID of the parent instance. | +### What happens during a fork -### Ongoing child lifecycle updates (parent) +1. The application writes to `/uk/libukp/fork`. +2. The `ukp-fuse` daemon sends a `ForkRequest` message (type `0x6`) to the platform via the boot timer device, including a `correlation_id` to match the response. +3. The platform snapshots the parent instance and creates a new child instance from that snapshot with a fresh network interface. +4. The platform sends a response back to the instance over [vsock](https://man7.org/linux/man-pages/man7/vsock.7.html) port `137`: + - The **parent** receives a `ForkCreated` message containing the child's UUID, snapshot ID, creation timestamp, and FQDN. + - The **child** receives a `ParentId` message containing the parent's UUID. +5. The `ukp-fuse` daemon completes the blocked write and makes the result available via a subsequent read. -After the fork, the parent continues to receive state change notifications for each of its children over the same vsock port: +### Concurrent fork requests -**`STATUS` message** (`msg_type = 0x4`)β€”sent when a child changes state: +Fork operations are serialized by a request gate inside the `ukp-fuse` daemon. +Only one fork can be in flight at a time. +If a second fork request arrives while one is already in progress, it is queued (up to 32 pending requests). +If the queue is full, the write returns `EBUSY`. -| Field | Type | Description | -|-------|------|-------------| -| `uuid` | UUID (16 bytes) | UUID of the child instance. | -| `state` | uint32 | New instance state (same values as the `state` field in `GET /v1/instances`). | +Queued requests are processed in order once the current fork completes. -**`EXIT_STATUS` message** (`msg_type = 0x5`)β€”sent when a child stops: +## Monitoring child instances -| Field | Type | Description | -|-------|------|-------------| -| `uuid` | UUID (16 bytes) | UUID of the child instance. | -| `exit_status` | uint32 | Exit code of the child. | +After a fork, a new directory appears at `/uk/libukp/vm//` containing files that reflect the child's state: + +| File | Read | Write | Description | +|------|------|-------|-------------| +| `snapshot` | Snapshot UUID the child was created from. | β€” | Read-only. | +| `creation_time` | Unix timestamp (seconds since epoch) of child creation. | β€” | Read-only. | +| `status` | Current state: `Starting`, `Running`, `Draining`, `Stopping`, `Stopped`, or `Template`. | β€” | Read-only. Updated automatically as the platform sends state change notifications. | +| `wait` | Exit code of the child (available once stopped). | Write any value to begin waiting for the child to stop. | Supports `poll()` for non-blocking use. Returns `POLLIN` when the exit code is available. | + +### Waiting for a child to stop + +To block until a child instance exits: + +```bash +# Write to begin the wait, then read the exit code +echo "1" > /uk/libukp/vm//wait +cat /uk/libukp/vm//wait +``` + +The write to `wait` blocks until the child stops and the platform delivers an `ExitStatus` message. +After the write completes, reading `wait` returns the numeric exit code. + +If the child has already stopped by the time you write to `wait`, the write completes immediately. + +Multiple processes can wait on the same child concurrently; all are notified when the child exits. + +For non-blocking usage, `poll()` on the `wait` file descriptor returns `POLLIN` when the exit status becomes available. + +### Checking child status + +To inspect a child's current state without blocking: + +```bash +cat /uk/libukp/vm//status +# Output: Running +``` + +The status file is updated in real time as the platform sends `Status` messages (state changes) and `ExitStatus` messages (termination). + +Possible states and their numeric values: + +| State | Value | Description | +|-------|-------|-------------| +| `Stopped` | 0 | Instance has exited. | +| `Starting` | 1 | Instance is booting. | +| `Running` | 2 | Instance is running. | +| `Draining` | 3 | Instance is draining connections before stopping. | +| `Stopping` | 4 | Instance is in the process of shutting down. | +| `Template` | 5 | Instance has been converted to a template. | + +## Preventing scale-to-zero during fork operations + +If your instance uses [scale-to-zero](/features/scale-to-zero), the platform could suspend it while a fork is in progress or while children are running. +Use the `scale_to_zero_disable` counter to prevent this: + +```bash +# Increment the counter to prevent suspension +echo "+1" > /uk/libukp/scale_to_zero_disable + +# ... perform fork and work with children ... + +# Decrement the counter to allow suspension again +echo "-1" > /uk/libukp/scale_to_zero_disable +``` -All messages share a common 8-byte header (`msg_type` uint32 + `correlation_id` uint32) followed by the message-specific payload. +The counter supports: +- `+1` or `+N` β€” increment by 1 or N. +- `-1` or `-N` β€” decrement by 1 or N (returns `ERANGE` on underflow). +- `=N` β€” set to an exact value. + +Suspension is allowed only when the counter reaches zero. +Reading the file returns the current value (e.g. `=3`). ## Child lifecycle -- Children have `delete-on-stop` set automaticallyβ€”they're removed from the platform when they stop. -- The platform clears a child's relationship to its parent when the child stops or transitions to a template state. Later lifecycle messages for that child aren't sent to the parent. -- A parent can have more than one child alive at the same time. -- A child can itself become a parent by issuing its own fork request. +- Children have `delete-on-stop` set automatically β€” they are removed from the platform when they stop. +- The child's `/uk/libukp/vm/` directory starts empty. Any children the parent had before the fork are not inherited β€” the child only sees its own children from forks it initiates itself. +- A parent can have multiple children alive at the same time. +- A child can itself fork, becoming a parent to its own children. +- When a child stops or transitions to a template state, the platform clears its relationship to the parent. The corresponding directory under `/uk/libukp/vm/` is removed on the next access. + +## Error handling -## Parent behaviour during fork +| Error | Cause | +|-------|-------| +| `EBUSY` | Fork queue is full (more than 32 pending requests). | +| `EIO` | Hardware signal to the platform failed, or the request belonged to a parent before a fork occurred. | +| `ESTALE` | A child VM directory was accessed after the child was cleaned up (e.g. after the current instance became a child via fork). | +| Numeric error code from platform | The platform rejected the fork request (e.g. no snapshot available). Returned via the `Error` message type (`0x1`). | -- While the platform snapshots the parent, it temporarily pauses the parent's [scale-to-zero autostart](/features/scale-to-zero) to prevent a race condition. -- If the parent had autostart configured, the platform re-enables it after the fork completes. -- The parent resumes execution immediately after the snapshot. The pause is brief. +When a fork fails, the request gate reopens and queued requests are processed normally. + +When the current instance discovers it is a child (via a `ParentId` message), all pending fork and wait requests from the parent's context are failed with `EIO`, and the fork queue is drained. This prevents stale parent operations from blocking the child. ## Constraints -- The parent must support snapshotting (this requires [stateful scale-to-zero](/features/scale-to-zero#stateful-scale-to-zero) to be on or a snapshot otherwise available). A fork request on a parent without a snapshot fails. -- The REST API and CLI can't trigger a fork; the guest must do it from within the instance. -- Fork state doesn't survive a reboot of the child instance. +- The parent must support snapshotting. This requires [stateful scale-to-zero](/features/scale-to-zero) to be enabled or a snapshot to be otherwise available. A fork request on a parent without a snapshot fails. +- The REST API and CLI cannot trigger a fork; it must be initiated from within the instance via the `/uk/libukp/fork` file. +- Fork state does not survive a reboot of the child instance. +- While the platform snapshots the parent during a fork, it temporarily pauses the parent's [scale-to-zero](/features/scale-to-zero) autostart to prevent a race condition. Autostart is re-enabled after the fork completes. + +## Protocol internals + +This section documents the wire protocol between the `ukp-fuse` daemon and the platform. +Application developers do not need to interact with this layer directly β€” the filesystem interface described above handles it. + +### vsock communication + +The `ukp-fuse` daemon listens on [vsock](https://man7.org/linux/man-pages/man7/vsock.7.html) port `137` (`VMADDR_CID_ANY`) for incoming messages from the platform. +Fork requests are sent to the platform via the boot timer device (`/dev/uio0` or `/dev/mem` as fallback) using a message queue at `/sys/class/uio/uio0/device/msg_queue`. + +### Message format + +All vsock messages share an 8-byte header: + +| Field | Type | Description | +|-------|------|-------------| +| `msg_type` | uint32 | Message type identifier. | +| `correlation_id` | uint32 | Links a response to its request. `0` indicates an unsolicited message. | + +### Message types + +| Type | Value | Direction | Description | +|------|-------|-----------|-------------| +| `Error` | `0x1` | Platform to guest | Fork request failed. Contains an `error_code` (int32, negated errno). | +| `ForkCreated` | `0x2` | Platform to parent | Fork succeeded. Contains child UUID, snapshot UUID, creation time, and FQDN. | +| `ParentId` | `0x3` | Platform to child | Tells the child which instance is its parent. Contains parent UUID. | +| `Status` | `0x4` | Platform to parent (unsolicited) | Child state changed. Contains child UUID and new state (uint32). | +| `ExitStatus` | `0x5` | Platform to parent (unsolicited) | Child stopped. Contains child UUID and exit code (uint32). | +| `ForkRequest` | `0x6` | Guest to platform | Requests a fork. Contains `correlation_id`. Sent via boot timer message queue. | + +### ForkCreated payload + +| Field | Type | Size | Description | +|-------|------|------|-------------| +| `header` | Header | 8 bytes | `msg_type = 0x2`, `correlation_id` from request. | +| `child_id` | UUID | 16 bytes | UUID of the newly created child instance. | +| `snapshot_id` | UUID | 16 bytes | UUID of the snapshot the child was created from. | +| `creation_time` | uint64 | 8 bytes | Child creation timestamp (UTC, seconds since Unix epoch). | +| `fqdn_len` | uint16 | 2 bytes | Length of the FQDN string (may be 0). | +| `fqdn` | char[] | variable | Child's private FQDN. | + +Total fixed size: 56 bytes (plus variable-length FQDN). + +### ParentId payload + +| Field | Type | Size | Description | +|-------|------|------|-------------| +| `header` | Header | 8 bytes | `msg_type = 0x3`, `correlation_id` from request. | +| `parent_id` | UUID | 16 bytes | UUID of the parent instance. | + +Total size: 24 bytes. + +### Status payload + +| Field | Type | Size | Description | +|-------|------|------|-------------| +| `header` | Header | 8 bytes | `msg_type = 0x4`, `correlation_id = 0` (unsolicited). | +| `uuid` | UUID | 16 bytes | UUID of the child instance. | +| `state` | uint32 | 4 bytes | New instance state (0=Stopped, 1=Starting, 2=Running, 3=Draining, 4=Stopping, 5=Template). | + +Total size: 32 bytes (4 bytes padding due to alignment). + +### ExitStatus payload + +| Field | Type | Size | Description | +|-------|------|------|-------------| +| `header` | Header | 8 bytes | `msg_type = 0x5`, `correlation_id = 0` (unsolicited). | +| `uuid` | UUID | 16 bytes | UUID of the child instance. | +| `exit_status` | uint32 | 4 bytes | Exit code of the child. | + +Total size: 32 bytes (4 bytes padding due to alignment). + +### Error payload + +| Field | Type | Size | Description | +|-------|------|------|-------------| +| `header` | Header | 8 bytes | `msg_type = 0x1`, `correlation_id` from request. | +| `error_code` | int32 | 4 bytes | Negated errno value (e.g. `-ENOMEM`). | + +Total size: 12 bytes. ## Learn more -* [Instance templates](/platform/instances#instance-templates): a related snapshot-based feature for cloning instances from a stopped state -* [Scale-to-zero](/features/scale-to-zero): stateful mode must be on for forking to work -* [Instances](/platform/instances) +- [Instance templates](/platform/instances#instance-templates): a related snapshot-based feature for creating instances from a stopped template +- [Scale-to-zero](/features/scale-to-zero): stateful mode must be enabled for forking to work +- [Instances](/platform/instances) From 3a1bae7e229dc5f1ad2abd739edc22b8559ab97f Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Tue, 17 Mar 2026 13:27:05 +0100 Subject: [PATCH 053/131] docs(features/forking): Fix all vale lint errors Reword headings to sentence-style capitalization, replace passive voice, use contractions, fix wordy phrases, use em dashes without spaces, one sentence per line, and replace application with app. Signed-off-by: Jerome Jaggi --- pages/features/forking.mdx | 124 ++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 57 deletions(-) diff --git a/pages/features/forking.mdx b/pages/features/forking.mdx index 91cb13a5..f5ed9d7a 100644 --- a/pages/features/forking.mdx +++ b/pages/features/forking.mdx @@ -4,21 +4,21 @@ navigation_icon: git-fork --- :::caution -Instance forking is a preview feature and is not yet available on stable. +Instance forking is a preview feature and isn't yet available on stable. The interface described here reflects the current implementation and may change before general availability. ::: -Instance forking allows a running instance to create an independent copy of itself at a snapshot boundary. +Instance forking lets a running instance create an independent copy of itself at a snapshot boundary. Both the original instance (the **parent**) and the copy (the **child**) resume execution from the same memory state. -This is conceptually similar to `fork(2)` in a POSIX process. +This works like `fork(2)` in a POSIX process. -Forking is **guest-initiated**: the application inside an instance triggers the fork through a filesystem interface. -No REST API endpoint or CLI command exists to fork an instance externally. +The app inside an instance triggers the fork through a filesystem interface. +No REST API endpoint or `kraft` command exists to fork an instance externally. -## The UKP filesystem +## Filesystem interface -The fork interface is exposed through a FUSE filesystem mounted at `/uk/libukp` inside every instance. -Applications trigger forks and monitor child instances by reading and writing files in this filesystem. +The fork interface uses a FUSE (Filesystem in Userspace) filesystem mounted at `/uk/libukp` inside every instance. +Apps trigger forks and track child instances by reading and writing files in this filesystem. The filesystem exposes the following top-level entries: @@ -26,7 +26,7 @@ The filesystem exposes the following top-level entries: |------|------|-------|-------------| | `/uk/libukp/fork` | Returns the child UUID after a fork (for the parent), or empty (for the child). | Triggers a new fork operation. | Main entry point for forking. | | `/uk/libukp/vm/` | Directory listing of all child instance UUIDs. | β€” | Each child gets a subdirectory named by its UUID. | -| `/uk/libukp/scale_to_zero_disable` | Returns the current counter value (e.g. `=3`). | Modify the counter: `+1`, `-1`, `+N`, `-N`, or `=N`. | Prevents scale-to-zero suspension while the counter is non-zero. | +| `/uk/libukp/scale_to_zero_disable` | Returns the current counter value (for example `=3`). | Change the counter: `+1`, `-1`, `+N`, `-N`, or `=N`. | Prevents scale-to-zero suspension while the counter isn't zero. | | `/uk/libukp/template_instance` | β€” | Write any value to convert the current instance into a template. | Write-only. | ## Triggering a fork @@ -46,37 +46,37 @@ cat /uk/libukp/fork ``` For the child instance, reading `/uk/libukp/fork` returns an empty response (a zero UUID). -This is how an application determines whether it is the parent or the child after a fork. +This is how an app determines whether it's the parent or the child after a fork. ### What happens during a fork -1. The application writes to `/uk/libukp/fork`. +1. The app writes to `/uk/libukp/fork`. 2. The `ukp-fuse` daemon sends a `ForkRequest` message (type `0x6`) to the platform via the boot timer device, including a `correlation_id` to match the response. 3. The platform snapshots the parent instance and creates a new child instance from that snapshot with a fresh network interface. 4. The platform sends a response back to the instance over [vsock](https://man7.org/linux/man-pages/man7/vsock.7.html) port `137`: - - The **parent** receives a `ForkCreated` message containing the child's UUID, snapshot ID, creation timestamp, and FQDN. - - The **child** receives a `ParentId` message containing the parent's UUID. -5. The `ukp-fuse` daemon completes the blocked write and makes the result available via a subsequent read. + - The **parent** gets a `ForkCreated` message containing the child's UUID, snapshot ID, creation timestamp, and FQDN. + - The **child** gets a `ParentId` message containing the parent's UUID. +5. The `ukp-fuse` daemon completes the blocked write and makes the result available via a follow-up read. ### Concurrent fork requests -Fork operations are serialized by a request gate inside the `ukp-fuse` daemon. -Only one fork can be in flight at a time. -If a second fork request arrives while one is already in progress, it is queued (up to 32 pending requests). -If the queue is full, the write returns `EBUSY`. +The `ukp-fuse` daemon serializes fork operations with a request gate. +Only one fork can run at a time. +If a second fork request arrives while one runs, the daemon queues it (up to 32 pending requests). +If the queue fills up, the write returns `EBUSY`. -Queued requests are processed in order once the current fork completes. +The daemon processes queued requests in order once the current fork completes. -## Monitoring child instances +## Tracking child instances After a fork, a new directory appears at `/uk/libukp/vm//` containing files that reflect the child's state: | File | Read | Write | Description | |------|------|-------|-------------| -| `snapshot` | Snapshot UUID the child was created from. | β€” | Read-only. | +| `snapshot` | Snapshot UUID the child originates from. | β€” | Read-only. | | `creation_time` | Unix timestamp (seconds since epoch) of child creation. | β€” | Read-only. | -| `status` | Current state: `Starting`, `Running`, `Draining`, `Stopping`, `Stopped`, or `Template`. | β€” | Read-only. Updated automatically as the platform sends state change notifications. | -| `wait` | Exit code of the child (available once stopped). | Write any value to begin waiting for the child to stop. | Supports `poll()` for non-blocking use. Returns `POLLIN` when the exit code is available. | +| `status` | Current state: `Starting`, `Running`, `Draining`, `Stopping`, `Stopped`, or `Template`. | β€” | Read-only. Updates automatically as the platform sends state change notifications. | +| `wait` | Exit code of the child (available once stopped). | Write any value to begin waiting for the child to stop. | Supports `poll()` for non-blocking use. Returns `POLLIN` when the exit code becomes available. | ### Waiting for a child to stop @@ -93,7 +93,8 @@ After the write completes, reading `wait` returns the numeric exit code. If the child has already stopped by the time you write to `wait`, the write completes immediately. -Multiple processes can wait on the same child concurrently; all are notified when the child exits. +Many processes can wait on the same child concurrently. +The daemon notifies each one when the child exits. For non-blocking usage, `poll()` on the `wait` file descriptor returns `POLLIN` when the exit status becomes available. @@ -106,7 +107,7 @@ cat /uk/libukp/vm//status # Output: Running ``` -The status file is updated in real time as the platform sends `Status` messages (state changes) and `ExitStatus` messages (termination). +The platform updates the status file in real time via `Status` messages (state changes) and `ExitStatus` messages (termination). Possible states and their numeric values: @@ -116,12 +117,12 @@ Possible states and their numeric values: | `Starting` | 1 | Instance is booting. | | `Running` | 2 | Instance is running. | | `Draining` | 3 | Instance is draining connections before stopping. | -| `Stopping` | 4 | Instance is in the process of shutting down. | -| `Template` | 5 | Instance has been converted to a template. | +| `Stopping` | 4 | Instance is shutting down. | +| `Template` | 5 | Instance has become a template. | ## Preventing scale-to-zero during fork operations -If your instance uses [scale-to-zero](/features/scale-to-zero), the platform could suspend it while a fork is in progress or while children are running. +If your instance uses [scale-to-zero](/features/scale-to-zero), the platform could suspend it while a fork runs or while children are running. Use the `scale_to_zero_disable` counter to prevent this: ```bash @@ -135,20 +136,23 @@ echo "-1" > /uk/libukp/scale_to_zero_disable ``` The counter supports: -- `+1` or `+N` β€” increment by 1 or N. -- `-1` or `-N` β€” decrement by 1 or N (returns `ERANGE` on underflow). -- `=N` β€” set to an exact value. +- `+1` or `+N`β€”increment by 1 or N. +- `-1` or `-N`β€”decrement by 1 or N (returns `ERANGE` on underflow). +- `=N`β€”set to an exact value. -Suspension is allowed only when the counter reaches zero. -Reading the file returns the current value (e.g. `=3`). +The platform allows suspension only when the counter reaches zero. +Reading the file returns the current value (for example `=3`). ## Child lifecycle -- Children have `delete-on-stop` set automatically β€” they are removed from the platform when they stop. -- The child's `/uk/libukp/vm/` directory starts empty. Any children the parent had before the fork are not inherited β€” the child only sees its own children from forks it initiates itself. -- A parent can have multiple children alive at the same time. +- Children have `delete-on-stop` enabled automatically. +The platform removes them when they stop. +- The child's `/uk/libukp/vm/` directory starts empty. +The child doesn't inherit any children from the parentβ€”it only sees children from forks it starts itself. +- A parent can have many children alive at the same time. - A child can itself fork, becoming a parent to its own children. -- When a child stops or transitions to a template state, the platform clears its relationship to the parent. The corresponding directory under `/uk/libukp/vm/` is removed on the next access. +- When a child stops or transitions to a template state, the platform clears its relationship to the parent. +The daemon removes the corresponding directory under `/uk/libukp/vm/` on the next access. ## Error handling @@ -156,29 +160,35 @@ Reading the file returns the current value (e.g. `=3`). |-------|-------| | `EBUSY` | Fork queue is full (more than 32 pending requests). | | `EIO` | Hardware signal to the platform failed, or the request belonged to a parent before a fork occurred. | -| `ESTALE` | A child VM directory was accessed after the child was cleaned up (e.g. after the current instance became a child via fork). | -| Numeric error code from platform | The platform rejected the fork request (e.g. no snapshot available). Returned via the `Error` message type (`0x1`). | +| `ESTALE` | A child VM directory access occurred after the child's cleanup (for example, after the current instance became a child via fork). | +| Numeric error code from platform | The platform rejected the fork request (for example, no snapshot available). The `Error` message type (`0x1`) carries the code. | -When a fork fails, the request gate reopens and queued requests are processed normally. +When a fork fails, the request gate reopens and the daemon processes queued requests normally. -When the current instance discovers it is a child (via a `ParentId` message), all pending fork and wait requests from the parent's context are failed with `EIO`, and the fork queue is drained. This prevents stale parent operations from blocking the child. +When the current instance discovers it's a child (via a `ParentId` message), the daemon fails all pending fork and wait requests from the parent's context with `EIO`. +It also drains the fork queue. +This prevents stale parent operations from blocking the child. ## Constraints -- The parent must support snapshotting. This requires [stateful scale-to-zero](/features/scale-to-zero) to be enabled or a snapshot to be otherwise available. A fork request on a parent without a snapshot fails. -- The REST API and CLI cannot trigger a fork; it must be initiated from within the instance via the `/uk/libukp/fork` file. -- Fork state does not survive a reboot of the child instance. -- While the platform snapshots the parent during a fork, it temporarily pauses the parent's [scale-to-zero](/features/scale-to-zero) autostart to prevent a race condition. Autostart is re-enabled after the fork completes. +- The parent must support snapshotting. +This requires you to enable [stateful scale-to-zero](/features/scale-to-zero) or have a snapshot otherwise available. +A fork request on a parent without a snapshot fails. +- The REST API and `kraft` can't trigger a fork. +You must start it from within the instance via the `/uk/libukp/fork` file. +- Fork state doesn't survive a reboot of the child instance. +- While the platform snapshots the parent during a fork, it temporarily pauses the parent's [scale-to-zero](/features/scale-to-zero) autostart to prevent a race condition. +Autostart resumes after the fork completes. ## Protocol internals This section documents the wire protocol between the `ukp-fuse` daemon and the platform. -Application developers do not need to interact with this layer directly β€” the filesystem interface described above handles it. +App developers don't need to interact with this layer directlyβ€”the filesystem interface described above handles it. -### vsock communication +### Vsock communication The `ukp-fuse` daemon listens on [vsock](https://man7.org/linux/man-pages/man7/vsock.7.html) port `137` (`VMADDR_CID_ANY`) for incoming messages from the platform. -Fork requests are sent to the platform via the boot timer device (`/dev/uio0` or `/dev/mem` as fallback) using a message queue at `/sys/class/uio/uio0/device/msg_queue`. +The daemon sends fork requests to the platform via the boot timer device (`/dev/uio0` or `/dev/mem` as fallback) using a message queue at `/sys/class/uio/uio0/device/msg_queue`. ### Message format @@ -198,22 +208,22 @@ All vsock messages share an 8-byte header: | `ParentId` | `0x3` | Platform to child | Tells the child which instance is its parent. Contains parent UUID. | | `Status` | `0x4` | Platform to parent (unsolicited) | Child state changed. Contains child UUID and new state (uint32). | | `ExitStatus` | `0x5` | Platform to parent (unsolicited) | Child stopped. Contains child UUID and exit code (uint32). | -| `ForkRequest` | `0x6` | Guest to platform | Requests a fork. Contains `correlation_id`. Sent via boot timer message queue. | +| `ForkRequest` | `0x6` | Guest to platform | Requests a fork. Contains `correlation_id`. The daemon sends this via the boot timer message queue. | -### ForkCreated payload +### Fork created message | Field | Type | Size | Description | |-------|------|------|-------------| | `header` | Header | 8 bytes | `msg_type = 0x2`, `correlation_id` from request. | | `child_id` | UUID | 16 bytes | UUID of the newly created child instance. | -| `snapshot_id` | UUID | 16 bytes | UUID of the snapshot the child was created from. | +| `snapshot_id` | UUID | 16 bytes | UUID of the snapshot the child originates from. | | `creation_time` | uint64 | 8 bytes | Child creation timestamp (UTC, seconds since Unix epoch). | | `fqdn_len` | uint16 | 2 bytes | Length of the FQDN string (may be 0). | | `fqdn` | char[] | variable | Child's private FQDN. | Total fixed size: 56 bytes (plus variable-length FQDN). -### ParentId payload +### Parent ID message | Field | Type | Size | Description | |-------|------|------|-------------| @@ -222,7 +232,7 @@ Total fixed size: 56 bytes (plus variable-length FQDN). Total size: 24 bytes. -### Status payload +### Status message | Field | Type | Size | Description | |-------|------|------|-------------| @@ -232,7 +242,7 @@ Total size: 24 bytes. Total size: 32 bytes (4 bytes padding due to alignment). -### ExitStatus payload +### Exit status message | Field | Type | Size | Description | |-------|------|------|-------------| @@ -242,17 +252,17 @@ Total size: 32 bytes (4 bytes padding due to alignment). Total size: 32 bytes (4 bytes padding due to alignment). -### Error payload +### Error message | Field | Type | Size | Description | |-------|------|------|-------------| | `header` | Header | 8 bytes | `msg_type = 0x1`, `correlation_id` from request. | -| `error_code` | int32 | 4 bytes | Negated errno value (e.g. `-ENOMEM`). | +| `error_code` | int32 | 4 bytes | Negated errno value (for example `-ENOMEM`). | Total size: 12 bytes. ## Learn more - [Instance templates](/platform/instances#instance-templates): a related snapshot-based feature for creating instances from a stopped template -- [Scale-to-zero](/features/scale-to-zero): stateful mode must be enabled for forking to work +- [Scale-to-zero](/features/scale-to-zero): you must enable stateful mode for forking to work - [Instances](/platform/instances) From 99f615ad6d45eede3a7c6848f33eca56f8812275 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Tue, 17 Mar 2026 13:40:03 +0100 Subject: [PATCH 054/131] docs(vale): Add FUSE to accepted vocabulary CI lint fails because reviewdog treats the FUSE acronym suggestion as a violation in added lines. Signed-off-by: Jerome Jaggi --- .vale/styles/config/vocabularies/Unikraft/accept.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.vale/styles/config/vocabularies/Unikraft/accept.txt b/.vale/styles/config/vocabularies/Unikraft/accept.txt index 76086426..cca712b2 100644 --- a/.vale/styles/config/vocabularies/Unikraft/accept.txt +++ b/.vale/styles/config/vocabularies/Unikraft/accept.txt @@ -6,6 +6,7 @@ (?i)autoscale (?i)autoscaling (?i)FQDN +FUSE (?i)just-in-time (?i)kraftkit (?i)maximum From 0ad32ffbfba950673820eea67e66356e0da9ee38 Mon Sep 17 00:00:00 2001 From: mdaria11 Date: Tue, 17 Mar 2026 15:13:25 +0100 Subject: [PATCH 055/131] docs: add UDP, connection limits, and persistent groups to services Signed-off-by: Jerome Jaggi --- pages/platform/services.mdx | 83 +++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/pages/platform/services.mdx b/pages/platform/services.mdx index 98bed32a..de095746 100644 --- a/pages/platform/services.mdx +++ b/pages/platform/services.mdx @@ -139,6 +139,89 @@ For example, the following creates the service `my-service` with three published kraft cloud service create --name my-service 443:8080/http+tls 80:8080/http+redirect 10000:10000/tls ``` +## `UDP` Support + +`UDP` is a defined service protocol alongside `TCP`. +Unikraft Cloud stores and reports it in the `protocol` field of each published port. + +You can use `UDP` for both internal VM-to-VM traffic and external traffic. + +### External `UDP` requirements + +To expose `UDP` externally for an user, the box must have an assigned IP address (primary or another assigned IP). +That IP must appear in the `addresses` array in `users.json` for that user: + +```json title="users.json" +{ + [ + "name": "user", + "addresses": [ + { + "ip": "a.b.c.d", + "internal_ip": "x.y.z.w", + "host": "host_name" + } + ] + ] +} +``` + +The `internal_ip` field is optional and used when the box routes traffic through an internal IP. + +You must also list the `UDP` IPs in the `additional_ip_addresses` directive in `nginx.conf.template` (space-separated). + +### Creating a `UDP` service + +To create a `UDP` service, set both `protocol` and `ip`: + +```json title="POST /v1/services" +{ + "services": [ + { + "port": 7777, + "destination_port": 8080, + "protocol": "udp", + "ip": "a.b.c.d" + } + ] +} +``` + +The service `ip` must match an `addresses[].ip` value in `users.json` for the user. + +## Connection limits + +Every service group has a soft and a hard connection limit that the load balancer enforces. + +| Field | Default | Range | Description | +|-------|---------|-------|-------------| +| `soft_limit` | `1` | 1–65535 | The load balancer starts queuing new connections once the number of active connections reaches this value. | +| `hard_limit` | `65535` | 1–65535 | The load balancer rejects new connections once the number of active connections reaches this value. | + +`soft_limit` must be less than or equal to `hard_limit`. +Setting `soft_limit > hard_limit` returns a `400` error. + +You can set both fields at service group creation time and update them later with `PATCH /v1/services/{name}`. + +```json title="POST /v1/services" +{ + "name": "my-service", + "soft_limit": 100, + "hard_limit": 500 +} +``` + +## Persistent service groups + +A service group is **persistent** when your user account owns it rather than a specific instance. + +- A service group created with `kraft cloud service create` (or `POST /v1/services`) is persistent. + It survives independently of any instances attached to it. +- A service group created implicitly via `kraft cloud deploy -p …` (shorthand port forwarding) belongs to the instance. + The platform deletes it when you delete that instance. + +The `GET /v1/services/{name}` response includes a `persistent` field (`bool`) that indicates which case applies. + ## Learn more * The `kraft cloud` [CLI reference](/cli/), in particular the [service](/cli/service) subcommand From 5e8a4fb480f84b3977f224b46044355ef9b317a1 Mon Sep 17 00:00:00 2001 From: Tobias Landsberg Date: Tue, 17 Mar 2026 15:49:37 +0100 Subject: [PATCH 056/131] docs(features/forking): Remove unrelated info/implementation details Remove unrelated information (mostly related to scale to zero) and implementation details (mostly the vsock message protocol). Signed-off-by: Tobias Landsberg --- pages/features/forking.mdx | 156 +++---------------------------------- 1 file changed, 12 insertions(+), 144 deletions(-) diff --git a/pages/features/forking.mdx b/pages/features/forking.mdx index f5ed9d7a..f4b877ad 100644 --- a/pages/features/forking.mdx +++ b/pages/features/forking.mdx @@ -26,8 +26,6 @@ The filesystem exposes the following top-level entries: |------|------|-------|-------------| | `/uk/libukp/fork` | Returns the child UUID after a fork (for the parent), or empty (for the child). | Triggers a new fork operation. | Main entry point for forking. | | `/uk/libukp/vm/` | Directory listing of all child instance UUIDs. | β€” | Each child gets a subdirectory named by its UUID. | -| `/uk/libukp/scale_to_zero_disable` | Returns the current counter value (for example `=3`). | Change the counter: `+1`, `-1`, `+N`, `-N`, or `=N`. | Prevents scale-to-zero suspension while the counter isn't zero. | -| `/uk/libukp/template_instance` | β€” | Write any value to convert the current instance into a template. | Write-only. | ## Triggering a fork @@ -48,21 +46,11 @@ cat /uk/libukp/fork For the child instance, reading `/uk/libukp/fork` returns an empty response (a zero UUID). This is how an app determines whether it's the parent or the child after a fork. -### What happens during a fork - -1. The app writes to `/uk/libukp/fork`. -2. The `ukp-fuse` daemon sends a `ForkRequest` message (type `0x6`) to the platform via the boot timer device, including a `correlation_id` to match the response. -3. The platform snapshots the parent instance and creates a new child instance from that snapshot with a fresh network interface. -4. The platform sends a response back to the instance over [vsock](https://man7.org/linux/man-pages/man7/vsock.7.html) port `137`: - - The **parent** gets a `ForkCreated` message containing the child's UUID, snapshot ID, creation timestamp, and FQDN. - - The **child** gets a `ParentId` message containing the parent's UUID. -5. The `ukp-fuse` daemon completes the blocked write and makes the result available via a follow-up read. - ### Concurrent fork requests The `ukp-fuse` daemon serializes fork operations with a request gate. Only one fork can run at a time. -If a second fork request arrives while one runs, the daemon queues it (up to 32 pending requests). +If a second fork request arrives while one runs, the daemon queues it. If the queue fills up, the write returns `EBUSY`. The daemon processes queued requests in order once the current fork completes. @@ -88,7 +76,7 @@ echo "1" > /uk/libukp/vm//wait cat /uk/libukp/vm//wait ``` -The write to `wait` blocks until the child stops and the platform delivers an `ExitStatus` message. +The write to `wait` blocks until the child stops. After the write completes, reading `wait` returns the numeric exit code. If the child has already stopped by the time you write to `wait`, the write completes immediately. @@ -107,41 +95,18 @@ cat /uk/libukp/vm//status # Output: Running ``` -The platform updates the status file in real time via `Status` messages (state changes) and `ExitStatus` messages (termination). +The platform updates the status file in real time. Possible states and their numeric values: -| State | Value | Description | -|-------|-------|-------------| -| `Stopped` | 0 | Instance has exited. | -| `Starting` | 1 | Instance is booting. | -| `Running` | 2 | Instance is running. | -| `Draining` | 3 | Instance is draining connections before stopping. | -| `Stopping` | 4 | Instance is shutting down. | -| `Template` | 5 | Instance has become a template. | - -## Preventing scale-to-zero during fork operations - -If your instance uses [scale-to-zero](/features/scale-to-zero), the platform could suspend it while a fork runs or while children are running. -Use the `scale_to_zero_disable` counter to prevent this: - -```bash -# Increment the counter to prevent suspension -echo "+1" > /uk/libukp/scale_to_zero_disable - -# ... perform fork and work with children ... - -# Decrement the counter to allow suspension again -echo "-1" > /uk/libukp/scale_to_zero_disable -``` - -The counter supports: -- `+1` or `+N`β€”increment by 1 or N. -- `-1` or `-N`β€”decrement by 1 or N (returns `ERANGE` on underflow). -- `=N`β€”set to an exact value. - -The platform allows suspension only when the counter reaches zero. -Reading the file returns the current value (for example `=3`). +| State | Description | +|-------|-------------| +| `Stopped` | Instance has exited. | +| `Starting` | Instance is booting. | +| `Running` | Instance is running. | +| `Draining` | Instance is draining connections before stopping. | +| `Stopping` | Instance is shutting down. | +| `Template` | Instance has become a template. | ## Child lifecycle @@ -151,118 +116,21 @@ The platform removes them when they stop. The child doesn't inherit any children from the parentβ€”it only sees children from forks it starts itself. - A parent can have many children alive at the same time. - A child can itself fork, becoming a parent to its own children. -- When a child stops or transitions to a template state, the platform clears its relationship to the parent. -The daemon removes the corresponding directory under `/uk/libukp/vm/` on the next access. ## Error handling | Error | Cause | |-------|-------| -| `EBUSY` | Fork queue is full (more than 32 pending requests). | +| `EBUSY` | Fork queue is full. | | `EIO` | Hardware signal to the platform failed, or the request belonged to a parent before a fork occurred. | | `ESTALE` | A child VM directory access occurred after the child's cleanup (for example, after the current instance became a child via fork). | -| Numeric error code from platform | The platform rejected the fork request (for example, no snapshot available). The `Error` message type (`0x1`) carries the code. | - -When a fork fails, the request gate reopens and the daemon processes queued requests normally. - -When the current instance discovers it's a child (via a `ParentId` message), the daemon fails all pending fork and wait requests from the parent's context with `EIO`. -It also drains the fork queue. -This prevents stale parent operations from blocking the child. ## Constraints -- The parent must support snapshotting. -This requires you to enable [stateful scale-to-zero](/features/scale-to-zero) or have a snapshot otherwise available. -A fork request on a parent without a snapshot fails. - The REST API and `kraft` can't trigger a fork. You must start it from within the instance via the `/uk/libukp/fork` file. -- Fork state doesn't survive a reboot of the child instance. -- While the platform snapshots the parent during a fork, it temporarily pauses the parent's [scale-to-zero](/features/scale-to-zero) autostart to prevent a race condition. -Autostart resumes after the fork completes. - -## Protocol internals - -This section documents the wire protocol between the `ukp-fuse` daemon and the platform. -App developers don't need to interact with this layer directlyβ€”the filesystem interface described above handles it. - -### Vsock communication - -The `ukp-fuse` daemon listens on [vsock](https://man7.org/linux/man-pages/man7/vsock.7.html) port `137` (`VMADDR_CID_ANY`) for incoming messages from the platform. -The daemon sends fork requests to the platform via the boot timer device (`/dev/uio0` or `/dev/mem` as fallback) using a message queue at `/sys/class/uio/uio0/device/msg_queue`. - -### Message format - -All vsock messages share an 8-byte header: - -| Field | Type | Description | -|-------|------|-------------| -| `msg_type` | uint32 | Message type identifier. | -| `correlation_id` | uint32 | Links a response to its request. `0` indicates an unsolicited message. | - -### Message types - -| Type | Value | Direction | Description | -|------|-------|-----------|-------------| -| `Error` | `0x1` | Platform to guest | Fork request failed. Contains an `error_code` (int32, negated errno). | -| `ForkCreated` | `0x2` | Platform to parent | Fork succeeded. Contains child UUID, snapshot UUID, creation time, and FQDN. | -| `ParentId` | `0x3` | Platform to child | Tells the child which instance is its parent. Contains parent UUID. | -| `Status` | `0x4` | Platform to parent (unsolicited) | Child state changed. Contains child UUID and new state (uint32). | -| `ExitStatus` | `0x5` | Platform to parent (unsolicited) | Child stopped. Contains child UUID and exit code (uint32). | -| `ForkRequest` | `0x6` | Guest to platform | Requests a fork. Contains `correlation_id`. The daemon sends this via the boot timer message queue. | - -### Fork created message - -| Field | Type | Size | Description | -|-------|------|------|-------------| -| `header` | Header | 8 bytes | `msg_type = 0x2`, `correlation_id` from request. | -| `child_id` | UUID | 16 bytes | UUID of the newly created child instance. | -| `snapshot_id` | UUID | 16 bytes | UUID of the snapshot the child originates from. | -| `creation_time` | uint64 | 8 bytes | Child creation timestamp (UTC, seconds since Unix epoch). | -| `fqdn_len` | uint16 | 2 bytes | Length of the FQDN string (may be 0). | -| `fqdn` | char[] | variable | Child's private FQDN. | - -Total fixed size: 56 bytes (plus variable-length FQDN). - -### Parent ID message - -| Field | Type | Size | Description | -|-------|------|------|-------------| -| `header` | Header | 8 bytes | `msg_type = 0x3`, `correlation_id` from request. | -| `parent_id` | UUID | 16 bytes | UUID of the parent instance. | - -Total size: 24 bytes. - -### Status message - -| Field | Type | Size | Description | -|-------|------|------|-------------| -| `header` | Header | 8 bytes | `msg_type = 0x4`, `correlation_id = 0` (unsolicited). | -| `uuid` | UUID | 16 bytes | UUID of the child instance. | -| `state` | uint32 | 4 bytes | New instance state (0=Stopped, 1=Starting, 2=Running, 3=Draining, 4=Stopping, 5=Template). | - -Total size: 32 bytes (4 bytes padding due to alignment). - -### Exit status message - -| Field | Type | Size | Description | -|-------|------|------|-------------| -| `header` | Header | 8 bytes | `msg_type = 0x5`, `correlation_id = 0` (unsolicited). | -| `uuid` | UUID | 16 bytes | UUID of the child instance. | -| `exit_status` | uint32 | 4 bytes | Exit code of the child. | - -Total size: 32 bytes (4 bytes padding due to alignment). - -### Error message - -| Field | Type | Size | Description | -|-------|------|------|-------------| -| `header` | Header | 8 bytes | `msg_type = 0x1`, `correlation_id` from request. | -| `error_code` | int32 | 4 bytes | Negated errno value (for example `-ENOMEM`). | - -Total size: 12 bytes. ## Learn more - [Instance templates](/platform/instances#instance-templates): a related snapshot-based feature for creating instances from a stopped template -- [Scale-to-zero](/features/scale-to-zero): you must enable stateful mode for forking to work - [Instances](/platform/instances) From 21f5507ea808ac3d3f2eb815e8c6be6568309ad2 Mon Sep 17 00:00:00 2001 From: Tobias Landsberg Date: Tue, 17 Mar 2026 16:14:50 +0100 Subject: [PATCH 057/131] docs(features/forking): Clarify details Add missing information about encoding (ASCII) and thread-specific data. Signed-off-by: Tobias Landsberg --- .vale/styles/config/vocabularies/Unikraft/accept.txt | 1 + pages/features/forking.mdx | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.vale/styles/config/vocabularies/Unikraft/accept.txt b/.vale/styles/config/vocabularies/Unikraft/accept.txt index cca712b2..151fe038 100644 --- a/.vale/styles/config/vocabularies/Unikraft/accept.txt +++ b/.vale/styles/config/vocabularies/Unikraft/accept.txt @@ -24,6 +24,7 @@ FUSE (?i)webservers? ALIAS ANAME +ASCII CNAME COPY DCO diff --git a/pages/features/forking.mdx b/pages/features/forking.mdx index f4b877ad..5fa51227 100644 --- a/pages/features/forking.mdx +++ b/pages/features/forking.mdx @@ -13,12 +13,11 @@ Both the original instance (the **parent**) and the copy (the **child**) resume This works like `fork(2)` in a POSIX process. The app inside an instance triggers the fork through a filesystem interface. -No REST API endpoint or `kraft` command exists to fork an instance externally. ## Filesystem interface The fork interface uses a FUSE (Filesystem in Userspace) filesystem mounted at `/uk/libukp` inside every instance. -Apps trigger forks and track child instances by reading and writing files in this filesystem. +Apps trigger forks and track child instances by reading and writing (ASCII) files in this filesystem. The filesystem exposes the following top-level entries: @@ -40,15 +39,16 @@ When it returns, the parent can read the child's UUID from the same file: ```bash # Returns the UUID of the newly created child (parent only) +# To support parallel forks, only the thread initiating the fork can read the return value from the file. cat /uk/libukp/fork ``` -For the child instance, reading `/uk/libukp/fork` returns an empty response (a zero UUID). +For the child instance, reading `/uk/libukp/fork` returns a zero UUID. This is how an app determines whether it's the parent or the child after a fork. ### Concurrent fork requests -The `ukp-fuse` daemon serializes fork operations with a request gate. +The `ukp-fuse` daemon serializes fork operations. Only one fork can run at a time. If a second fork request arrives while one runs, the daemon queues it. If the queue fills up, the write returns `EBUSY`. @@ -63,7 +63,7 @@ After a fork, a new directory appears at `/uk/libukp/vm//` containin |------|------|-------|-------------| | `snapshot` | Snapshot UUID the child originates from. | β€” | Read-only. | | `creation_time` | Unix timestamp (seconds since epoch) of child creation. | β€” | Read-only. | -| `status` | Current state: `Starting`, `Running`, `Draining`, `Stopping`, `Stopped`, or `Template`. | β€” | Read-only. Updates automatically as the platform sends state change notifications. | +| `status` | Current state: `Starting`, `Running`, `Draining`, `Stopping`, `Stopped`, or `Template`. | β€” | Read-only. | | `wait` | Exit code of the child (available once stopped). | Write any value to begin waiting for the child to stop. | Supports `poll()` for non-blocking use. Returns `POLLIN` when the exit code becomes available. | ### Waiting for a child to stop From 73e5e37b1997af42c62b2b3d6e1230152410ff56 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 14:42:20 +0100 Subject: [PATCH 058/131] docs: Add resource tagging documentation Signed-off-by: Jerome Jaggi Signed-off-by: Florian Rommel --- pages/platform/tagging.mdx | 91 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 pages/platform/tagging.mdx diff --git a/pages/platform/tagging.mdx b/pages/platform/tagging.mdx new file mode 100644 index 00000000..8cb879cb --- /dev/null +++ b/pages/platform/tagging.mdx @@ -0,0 +1,91 @@ +--- +title: Tagging +navigation_icon: tag +--- + +Tags are labels that you can attach to instances, volumes, instance templates, and volume templates to organize and filter your resources. + +Don't confuse them with image tags which serve a different purpose (see [images](/api/platform/v1/images)). + +## Tag format + +Tags can be up to 256 characters long and may contain alphanumeric characters plus `-`, `+`, `_`, `.`, `:`, and `=`. +Each resource (instance, volume, instance template, volume template) can have up to 16 tags. +You can currently only manage tags via the API. +Kraftkit neither displays them nor allows you to edit them. + +## Adding tags + +Add tags to a resource at creation time: + +```json title="POST /v1/instances" +{ + "image": "...", + "memory_mb": ..., + "tags": [ "production", "customer_A" ] +} +``` + +Add tags to an existing resource (`"op": "set"` will replace all existing tags): + +```json title="PATCH /v1/instances" +{ + "name": "example-instance", + "prop": "tags", + "op": "set", + "value": ["testsystem", "customer_B"] +} +``` + +:::note +Use `/v1/volumes` for volumes, `/v1/instances/templates` for instance templates, and `/v1/volumes/templates` for volume templates. +::: + +Add tags to a resource without replacing existing ones (`"op": "add"`): + +```json title="PATCH /v1/instances" +{ + "name": "example-instance", + "prop": "tags", + "op": "add", + "value": ["legacy"] +} +``` + +:::note +Tags are automatically deduplicated. +Repeating the same tag adds it only once. +Adding a tag already attached to a resource has no effect. +::: + +## Removing tags + +Remove specific tags from a resource (`"op": "del"`): + +```json title="PATCH /v1/instances" +{ + "name": "example-instance", + "prop": "tags", + "op": "del", + "value": ["legacy"] +} +``` + +## Filtering by tag + +Filter the instance list, volume list, instance template list, or volume template list by one or more tags. +Only resources that have _all_ the specified tags appear in the results. + +``` +GET /v1/instances?tags=production,customer_A +``` + +Separate tags by commas (`,`). + +## Tags in API responses + +Each instance, volume, instance template, or volume template status response includes a `tags` array if at least one tag is present. + +## Learn more + +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the sections on [instances](/api/platform/v1/instances) and [volumes](/api/platform/v1/volumes) From 04c0132dea6a555bda86c6b0ca948b4c7c15dfb5 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 15:05:13 +0100 Subject: [PATCH 059/131] docs: add cron jobs and scheduled wake-ups reference page Signed-off-by: Jerome Jaggi Signed-off-by: Pascal Ellinger --- pages/features/cron-jobs.mdx | 97 ++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 pages/features/cron-jobs.mdx diff --git a/pages/features/cron-jobs.mdx b/pages/features/cron-jobs.mdx new file mode 100644 index 00000000..e2b7e001 --- /dev/null +++ b/pages/features/cron-jobs.mdx @@ -0,0 +1,97 @@ +--- +title: Cron Jobs / Scheduled Wake-ups +navigation_icon: clock +--- + +Scheduled operations let you automatically start, stop, or delete instances on a calendar-based schedule. +Each scheduled operation specifies a name, a calendar expression, and an action (`start`, `stop`, or `delete`). + +Each instance stores its own schedules, and cloning preserves them. + +## Calendar expression format + +Unikraft Cloud uses systemd calendar events (see [systemd.time(7)](https://www.man7.org/linux/man-pages/man7/systemd.time.7.html)). +Calendar expressions have the following fields: + +``` +[weekday] [[year-]month-day] [hour:minute[:second]] +``` + +The expression syntax supports ranges, steps, and comma-separated lists: + +| Syntax | Description | +|--------|-------------| +| `*` | Any value | +| `5` | Exact value | +| `1..5` | Range | +| `1..5/2` | Range with step | +| `1,2,5` | Comma-separated list | + +## Setting a schedule at instance creation + +Pass `schedules` in the create request. +For example, to start an instance every day at 09:00 UTC and stop it at 18:00 UTC: + +```json title="POST /v1/instances" +{ + "image": "...", + "schedules": [ + { + "name": "morning-start", + "when": "*-*-* 09:00:00", + "action": "start" + }, + { + "name": "evening-stop", + "when": "*-*-* 18:00:00", + "action": "stop" + } + ] +} +``` + +## Updating schedules of an existing instance + +Add, set, or remove scheduled operations via `PATCH`: + +```json title="PATCH /v1/instances/{uuid}" +{ + "prop": "schedules", + "op": "add", + "value": [ + { + "name": "weekend-stop", + "when": "Sat,Sun *-*-* 20:00:00", + "action": "stop" + } + ] +} +``` + +```json title="PATCH /v1/instances/{uuid}" +{ + "prop": "schedules", + "op": "del", + "value": [ + "morning-start" + ] +} +``` + +## Actions + +| Action | Description | +|--------|-------------| +| `start` | Start the instance at the scheduled time | +| `stop` | Stop the instance at the scheduled time | +| `delete` | Delete the instance at the scheduled time | + +## Notes + +- Each schedule has a name that must be unique within an instance. +- An instance can have more than one scheduled operation. +- When you clone an instance from a template, the clone inherits its scheduled operations. + +## Learn more + +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [instances](/api/platform/v1/instances) From 3b6fbc37a064b80f52bf88e5f2b0792787440d34 Mon Sep 17 00:00:00 2001 From: Maria Sfiraiala Date: Tue, 17 Mar 2026 23:22:42 +0200 Subject: [PATCH 060/131] docs: Fix minor inconsistencies with images Signed-off-by: Maria Sfiraiala --- pages/platform/images.mdx | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/pages/platform/images.mdx b/pages/platform/images.mdx index 7c9f9a2c..57d4bdb1 100644 --- a/pages/platform/images.mdx +++ b/pages/platform/images.mdx @@ -193,18 +193,21 @@ You now have a new instance created from the existing image. GET /v1/images ``` -Returns all images in your account. +Returns all images accessible for your account and known by the platform. Each image object includes: | Field | Type | Description | |-------|------|-------------| | `uuid` | string | Image UUID. | -| `name` | string | Image name (if present). | | `created_at` | timestamp | Creation time. | +| `owner` | string | Owner of the image (omitted if not root account). | | `url` | string | Full image address (includes digest). | +| `tags` | array of strings | List of shortened tags. | | `initrd_or_rom` | bool | Whether the image includes an initrd or ROM component. | | `size_in_bytes` | int64 | Total image size in bytes. | | `args` | array of strings | Default arguments (omitted if none). | +| `env` | map of strings | Default environmental variables (omitted if none). | +| `users` | array of strings | Users with access to the image (omitted if not root account). | ### Look up by UUID @@ -217,24 +220,34 @@ Returns one or more images by UUID. ### Look up by digest ``` -GET /v1/images/list +GET /v1/images ``` Pass a `digest` string in the request body to return the image matching that digest: -```json title="GET /v1/images/list" +```json title="GET /v1/images" { - "digest": "sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472" + "digest": "user/image@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472" } ``` -The response includes `digest`, `tags`, `initrd`, `size_in_bytes`, and `args`. +The response includes `url`, `tags`, `initrd_or_rom`, `size_in_bytes`, args` and `env`. -:::note -Tag-based filtering (`tag` field in the list body) appears in the API schema but the platform doesn't act on it yet. -The platform accepts and ignores the field. -Use the digest or UUID endpoints to look up a specific image. -::: +### Look up by tag + +``` +GET /v1/images +``` + +Pass a `tag` string in the request body to return the image matching that tag: + +```json title="GET /v1/images" +{ + "tag": "user/image:tag" +} +``` + +The response includes `url`, `tags`, `initrd_or_rom`, `size_in_bytes`, args` and `env`. ## Learn more From c3e207b179a664aca3944a655be48c3d3e7e4121 Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Wed, 18 Mar 2026 16:12:53 +0200 Subject: [PATCH 061/131] feat(tutorials): Add tutorial describing metrics and how to use them Signed-off-by: Cezar Craciunoiu --- pages/tutorials/instance-metrics.mdx | 401 +++++++++++++++++++++++++++ 1 file changed, 401 insertions(+) create mode 100644 pages/tutorials/instance-metrics.mdx diff --git a/pages/tutorials/instance-metrics.mdx b/pages/tutorials/instance-metrics.mdx new file mode 100644 index 00000000..53c105cd --- /dev/null +++ b/pages/tutorials/instance-metrics.mdx @@ -0,0 +1,401 @@ +--- +title: Instance Metrics +navigation_icon: bar-chart +--- + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +Unikraft Cloud provides an endpoint to retrieve real-time hardware and network metrics for your running instances. +These metrics are useful for monitoring the performance, memory usage, and network traffic handled by your app. + +## Prerequisites + +To access the instance metrics, you must have the **`developer`** permission role for your user. + +## Retrieving metrics + +You can retrieve the metrics of one or more instances by making a `GET` request to the `/v1/instances/metrics` endpoint. +The request body must contain an array of instance UUIDs or names. +Use a tool like `curl` for ad-hoc queries, or configure your monitoring system to consume the endpoint's Prometheus-formatted output. + +### Example + +The following example creates an instance and retrieves its metrics using `curl`. + +First, provision a new instance (set `$UKC_TOKEN` and `$UKC_METRO` as appropriate): + +```bash title="" +git clone https://github.com/unikraft-cloud/examples +cd examples/nginx/ +kraft cloud deploy -p 443:8080 -M 256 . +``` + +This command will create the NGINX instance with scale-to-zero enabled: + +```ansi title="" +[90m[[0m[92m●[0m[90m][0m Deployed successfully! + [90mβ”‚[0m + [90mβ”œ[0m[90m──────────[0m [90mname[0m: nginx-26g86 + [90mβ”œ[0m[90m──────────[0m [90muuid[0m: 3605978e-5feb-4209-8f9e-de45f00a7d66 + [90mβ”œ[0m[90m─────────[0m [90mstate[0m: [92mrunning[0m + [90mβ”œ[0m[90m───────────[0m [90murl[0m: https://black-snowflake-iy7509ap.fra.unikraft.app + [90mβ”œ[0m[90m─────────[0m [90mimage[0m: nginx@sha256:19854a12fe97f138313cb9b4806828cae9cecf2d050077a0268d98129863f954 + [90mβ”œ[0m[90m─────[0m [90mboot time[0m: 7.77 ms + [90mβ”œ[0m[90m────────[0m [90mmemory[0m: 256 MiB + [90mβ”œ[0m[90m───────[0m [90mservice[0m: black-snowflake-iy7509ap + [90mβ”œ[0m[90m──[0m [90mprivate fqdn[0m: nginx-26g86.internal + [90mβ”œ[0m[90m────[0m [90mprivate ip[0m: 172.16.6.1 + [90mβ””[0m[90m──────────[0m [90margs[0m: /usr/bin/nginx -c /etc/nginx/nginx.conf +``` + +Now, request the metrics for that instance: + + + + JSON + Prometheus + + +```bash title="" +curl -X GET "https://api.$UKC_METRO.unikraft.cloud/v1/instances/metrics" \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + -d '[{"name":"nginx-26g86"}]' +``` + + +```bash title="" +curl -X GET "https://api.$UKC_METRO.unikraft.cloud/v1/instances/metrics" \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + -d '[{"name":"nginx-26g86"}]' +``` + + + + + + JSON + Prometheus + + +```json +{ + "status": "success", + "data": { + "instances": [ + { + "status": "success", + "uuid": "3605978e-5feb-4209-8f9e-de45f00a7d66", + "name": "nginx-26g86", + "state": "standby", + "start_count": 2, + "started_at": "2026-03-18T12:31:49Z", + "stopped_at": "2026-03-18T12:31:50Z", + "uptime_s": 7.817000, + "boot_time_s": 0.005900, + "net_time_s": 0.025256, + "rss_bytes": 0, + "cpu_time_s": 0, + "rx_bytes": 1614, + "rx_packets": 10, + "tx_bytes": 537, + "tx_packets": 5, + "nconns": 0, + "nreqs": 0, + "nqueued": 0, + "ntotal": 1, + "wakeup_latency_seconds": [ + { + "bucket_s": 0.001000, + "count": 0 + }, + { + "bucket_s": 0.002000, + "count": 0 + }, + { + "bucket_s": 0.004000, + "count": 0 + }, + { + "bucket_s": 0.008000, + "count": 0 + }, + { + "bucket_s": 0.016000, + "count": 0 + }, + { + "bucket_s": 0.032000, + "count": 1 + }, + { + "bucket_s": 0.064000, + "count": 0 + }, + { + "bucket_s": 0.128000, + "count": 0 + }, + { + "bucket_s": 0.256000, + "count": 0 + }, + { + "bucket_s": 0.512000, + "count": 0 + }, + { + "bucket_s": 1.024000, + "count": 0 + }, + { + "bucket_s": 2.048000, + "count": 0 + }, + { + "bucket_s": 4.096000, + "count": 0 + }, + { + "bucket_s": null, + "count": 0 + } + ], + "wakeup_latency_seconds_sum": 0.023 + } + ] + }, + "op_time_us": 125 +} +``` + + +```prom +# HELP instance_state 0=stopped,1=starting,2=running,3=draining,4=stopping,5=standby,6=template +# TYPE instance_state gauge +instance_state{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 5 + +# HELP instance_start_count Number of times the instance has been started +# TYPE instance_start_count counter +instance_start_count{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 2 + +# HELP instance_restart_count Number of times the instance has been restarted +# TYPE instance_restart_count counter +instance_restart_count{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 0 + +# HELP instance_started_at Time when the instance started +# TYPE instance_started_at gauge +instance_started_at{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 1773840567 + +# HELP instance_stopped_at Time when the instance stopped +# TYPE instance_stopped_at gauge +instance_stopped_at{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 1773840567 + +# HELP instance_uptime_s Uptime in seconds +# TYPE instance_uptime_s gauge +instance_uptime_s{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 7.817000 + +# HELP instance_boot_time_s Boot time in seconds +# TYPE instance_boot_time_s gauge +instance_boot_time_s{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 0.005900 + +# HELP instance_net_time_s Net time in seconds +# TYPE instance_net_time_s gauge +instance_net_time_s{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 0.025256 + +# HELP instance_rss_bytes Resident set size in bytes +# TYPE instance_rss_bytes gauge +instance_rss_bytes{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 0 + +# HELP instance_cpu_time_s Consumed CPU time in seconds +# TYPE instance_cpu_time_s counter +instance_cpu_time_s{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 0.000000 + +# HELP instance_rx_bytes Amount of bytes received over network +# TYPE instance_rx_bytes counter +instance_rx_bytes{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 1614 + +# HELP instance_tx_bytes Amount of bytes transmitted over network +# TYPE instance_tx_bytes counter +instance_tx_bytes{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 543 + +# HELP instance_rx_packets Count of packets received from network +# TYPE instance_rx_packets counter +instance_rx_packets{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 10 + +# HELP instance_tx_packets Count of packets transmitted over network +# TYPE instance_tx_packets counter +instance_tx_packets{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 5 + +# HELP instance_nconns Number of active connections +# TYPE instance_nconns gauge +instance_nconns{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 0 + +# HELP instance_nreqs Number of active requests +# TYPE instance_nreqs gauge +instance_nreqs{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 0 + +# HELP instance_nqueued Number of queued connections/requests +# TYPE instance_nqueued gauge +instance_nqueued{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 0 + +# HELP instance_ntotal Number of processed connections/requests +# TYPE instance_ntotal counter +instance_ntotal{instance_uuid="3605978e-5feb-4209-8f9e-de45f00a7d66"} 1 + +# HELP instance_wakeup_latency_seconds Wakeup latencies in seconds +# TYPE instance_wakeup_latency_seconds histogram +instance_wakeup_latency_seconds{le="0.001000"} 0 +instance_wakeup_latency_seconds{le="0.002000"} 0 +instance_wakeup_latency_seconds{le="0.004000"} 0 +instance_wakeup_latency_seconds{le="0.008000"} 0 +instance_wakeup_latency_seconds{le="0.016000"} 0 +instance_wakeup_latency_seconds{le="0.032000"} 1 +instance_wakeup_latency_seconds{le="0.064000"} 1 +instance_wakeup_latency_seconds{le="0.128000"} 1 +instance_wakeup_latency_seconds{le="0.256000"} 1 +instance_wakeup_latency_seconds{le="0.512000"} 1 +instance_wakeup_latency_seconds{le="1.024000"} 1 +instance_wakeup_latency_seconds{le="2.048000"} 1 +instance_wakeup_latency_seconds{le="4.096000"} 1 +instance_wakeup_latency_seconds{le="+Inf"} 1 +instance_wakeup_latency_seconds_sum 23 +instance_wakeup_latency_seconds_count 1 +``` + + + +If the request is successful, you will receive a response reporting the instance's performance and network data. + +## Understanding the Response + +The metrics response contains fields for CPU, memory, boot time, and networking. +The Prometheus output comments contain details about each metric. +Below is a detailed breakdown of each field returned in the metrics object. + +### Instance Info + +#### **`uuid`** + +The UUID of the instance. + +#### **`name`** + +The name of the instance. + +#### **`state`** + +The current state of the instance. +Possible values: `stopped`, `starting`, `running`, `draining`, `stopping`, `standby`, `template`. + +### Lifecycle and uptime + +#### **`start_count`** + +Number of times the instance started, including scale-to-zero wakeups. + +#### **`started_at`** + +Timestamp of the most recent instance start, in [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) format. + +#### **`stopped_at`** + +Timestamp of the most recent instance stop, in [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) format. + +#### **`uptime_s`** + +Total accumulated uptime of the instance in seconds across all starts. + +### Memory & CPU + +#### **`rss_bytes`** + +Resident set size in bytes. +This is the amount of physical memory that the instance has touched and is currently reserved for it. +It grows as the instance uses more memory up to the configured limit. +This metric drops to `0` when the instance is in standby. + +#### **`cpu_time_s`** + +Consumed CPU time in seconds for the last second. +This metric drops to `0` when the instance is in standby. + +### Boot and network initialization times + +#### **`boot_time_s`** + +Boot time in seconds. +Calculated as the time between the virtualization toolstack responding to a boot request and the moment the guest OS starts executing user code. + +#### **`net_time_s`** + +Network initialization time in seconds. +This is the time from when the instance started until the user-level app starts listening on a non-localhost port. + +### Network traffic + +#### **`rx_bytes`** + +Total amount of network bytes received. + +#### **`rx_packets`** + +Total count of network packets received. + +#### **`tx_bytes`** + +Total amount of network bytes transmitted. + +#### **`tx_packets`** + +Total count of network packets transmitted. + +### Connections & Requests + +#### **`nconns`** + +Number of currently established inbound connections (non-HTTP). +This metric drops to `0` when the instance is in standby. + +#### **`nreqs`** + +Number of in-flight HTTP requests. +This metric drops to `0` when the instance is in standby. + +#### **`nqueued`** + +Number of queued inbound connections and HTTP requests. +This metric drops to `0` when the instance is in standby. + +#### **`ntotal`** + +Total number of inbound connections and HTTP requests handled. + +### Wakeup latency + +#### **`wakeup_latency_seconds`** + +A histogram of scale-to-zero wakeup latencies. +Each entry contains a `bucket_s` threshold (in seconds) and the `count` of wakeups that fell within that bucket. +The final bucket has `bucket_s: null`, representing the `+Inf` overflow bucket for wakeups exceeding all defined thresholds. + +#### **`wakeup_latency_seconds_sum`** + +The sum of all wakeup latencies in seconds. +Together with the histogram buckets this allows computing a mean wakeup latency: `wakeup_latency_seconds_sum / ntotal`. + +## Conclusion + +Instance metrics give you a real-time view into the performance and health of your Unikraft Cloud instances. +By monitoring memory usage, CPU time, boot and network initialization times, and connection statistics, you can understand how your app behaves under load. +The Prometheus format lets you plug these metrics directly into monitoring tools such as Grafana or any other Prometheus-compatible system. + +## Learn more + +* [Scale to zero](/features/scale-to-zero) and how it affects instance lifecycle. +* [Scale to zero triggers](/tutorials/scale-to-zero-triggers) for controlling when instances wake up. +* [Platform instances](/platform/instances) for managing and inspecting your instances. +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [instance create](/cli/instance/create) subcommand. From 08a6a1cff2eb6ef9faac4126139950b2ab600b4f Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Wed, 18 Mar 2026 18:44:11 +0200 Subject: [PATCH 062/131] chore(sdks): Remove '<>' to get page to compile again Signed-off-by: Cezar Craciunoiu --- pages/integrations/sdks/go.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/integrations/sdks/go.mdx b/pages/integrations/sdks/go.mdx index ce019a50..837fd5ac 100644 --- a/pages/integrations/sdks/go.mdx +++ b/pages/integrations/sdks/go.mdx @@ -5,7 +5,7 @@ navigation_icon: code The Unikraft Cloud Go SDK is an autogenerated client library that interfaces with the Unikraft Cloud platform API, based on the public OpenAPI -specification at . +specification at https://github.com/unikraft-cloud/openapi. ## Installation From 098aa16baa22c553fb8220dcb023e01ba84e3951 Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Wed, 18 Mar 2026 18:59:09 +0200 Subject: [PATCH 063/131] fix(cli): Add missing 'tabs' import Signed-off-by: Cezar Craciunoiu --- pages/cli/registries.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pages/cli/registries.mdx b/pages/cli/registries.mdx index 44541f58..aa929603 100644 --- a/pages/cli/registries.mdx +++ b/pages/cli/registries.mdx @@ -3,6 +3,8 @@ title: Registries navigation_icon: package --- +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + Unikraft Cloud uses a central OCI registry at `index.unikraft.io` to store images. Every image you build and push lands in this registry under your account's namespace. When you start an instance, the platform pulls the image from this registry automatically. From c0107c91ae898486c2b30d9ec79bc710cc320aaa Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 15:16:44 +0100 Subject: [PATCH 064/131] docs: add instance metrics reference page Signed-off-by: Jerome Jaggi --- pages/platform/metrics.mdx | 160 +++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 pages/platform/metrics.mdx diff --git a/pages/platform/metrics.mdx b/pages/platform/metrics.mdx new file mode 100644 index 00000000..e0476d8f --- /dev/null +++ b/pages/platform/metrics.mdx @@ -0,0 +1,160 @@ +--- +title: Metrics +navigation_icon: chart-bar +description: | + Retrieve runtime statistics for your Unikraft Cloud instances. +--- + +Unikraft Cloud exposes runtime metrics for each instance: CPU time, memory usage, network I/O, connection counts, and scale-to-zero wakeup latencies. + +## Endpoints + +``` +GET /v1/instances/{uuid}/metrics +GET /v1/instances/metrics?uuid=[,…] +POST /v1/instances/metrics (UUIDs or names in request body) +``` + +With no identifiers, the platform returns metrics for all instances in your account. +You can also pass a list of names or UUIDs in the `POST` body. + +## Response formats + +Set the `Accept` header to control the response format: + +| `Accept` header | Format | +|-----------------|--------| +| `application/json` | JSON object with an `instances` array. | +| Any other value (or omitted) | Prometheus text exposition format. | + +## Response fields + +Each entry in the `instances` array contains the following fields: + +### Identity + +| Field | Type | Description | +|-------|------|-------------| +| `uuid` | string | Instance UUID. | +| `name` | string | Instance name. | + +### Lifecycle + +| Field | Type | Description | +|-------|------|-------------| +| `state` | string | Current instance state. | +| `start_count` | int | Number of times the instance has started. | +| `restart_count` | int | Number of automatic restarts. Omitted if `0`. | +| `started_at` | timestamp | Time of last start. Omitted if unset. | +| `stopped_at` | timestamp | Time of last stop. Omitted if unset. | +| `uptime_ms` | int64 | Current uptime in milliseconds. | + +### Boot timing + +| Field | Type | Description | +|-------|------|-------------| +| `boot_time_us` | int | Time from boot trigger to app entry point, in microseconds. Omitted if `0`. | +| `net_time_us` | int | Time to set up the network interface, in microseconds. Omitted if `0`. | + +### Resource usage + +| Field | Type | Description | +|-------|------|-------------| +| `rss_bytes` | int64 | Resident set size: physical memory in use, in bytes. | +| `cpu_time_ms` | int64 | Total CPU time consumed since last start, in milliseconds. | + +### Network throughput + +| Field | Type | Description | +|-------|------|-------------| +| `rx_bytes` | int64 | Bytes received since last start. | +| `rx_packets` | int64 | Packets received since last start. | +| `tx_bytes` | int64 | Bytes transmitted since last start. | +| `tx_packets` | int64 | Packets transmitted since last start. | + +### Connection activity + +These fields reflect the view from the Unikraft Cloud load balancer, not the instance itself. + +| Field | Type | Description | +|-------|------|-------------| +| `nconns` | int | Number of active TCP connections. | +| `nreqs` | int | Number of active HTTP requests (non-zero only for HTTP-mode services). | +| `nqueued` | int | Number of connections or requests waiting for acceptance. | +| `ntotal` | int64 | Total connections or requests processed since last start. | + +### Wakeup latency histogram + +For instances with [scale-to-zero](/features/scale-to-zero) enabled, the `wakeup_latency` field contains a histogram of the time between an incoming connection and the instance resuming execution. + +| Field | Type | Description | +|-------|------|-------------| +| `wakeup_latency` | array | Histogram buckets. Each bucket has `bucket_ms` (upper bound in ms, or `null` for the overflow bucket) and `count` (number of wakeups in that bucket). | +| `wakeup_latency_sum` | uint64 | Sum of all recorded wakeup latencies in milliseconds. | + +## Prometheus metrics + +When not requesting JSON, the endpoint returns standard Prometheus text format. +The available metric names are: + +``` +instance_state +instance_start_count +instance_restart_count +instance_started_at +instance_stopped_at +instance_uptime_s +instance_boot_time_s +instance_net_time_s +instance_rss_bytes +instance_cpu_time_s +instance_rx_bytes +instance_tx_bytes +instance_rx_packets +instance_tx_packets +instance_nconns +instance_nreqs +instance_nqueued +instance_ntotal +instance_wakeup_latency_seconds (histogram) +``` + +The platform labels all metrics with `uuid` and `name`. + +## Example + +```bash title="" +curl -H "Accept: application/json" \ + "https://api.unikraft.io/v1/instances/metrics?uuid=66d05e09-1436-4d1f-bbe6-6dc03ae48d7a" +``` + +```json title="" +{ + "instances": [ + { + "uuid": "66d05e09-1436-4d1f-bbe6-6dc03ae48d7a", + "name": "nginx-1a747", + "state": "running", + "start_count": 3, + "uptime_ms": 42310, + "boot_time_us": 19810, + "rss_bytes": 12582912, + "cpu_time_ms": 14, + "rx_bytes": 4096, + "rx_packets": 8, + "tx_bytes": 8192, + "tx_packets": 12, + "nconns": 1, + "nreqs": 0, + "nqueued": 0, + "ntotal": 7 + } + ] +} +``` + +## Learn more + +* Unikraft Cloud's [REST API reference](/api/platform/v1) +* [Instance states](/platform/instances#instance-states) +* [Scale-to-zero](/features/scale-to-zero) From 50f4fa9da362c047aeac3ab07e6e5634f9cc0fd0 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 14:53:05 +0100 Subject: [PATCH 065/131] docs: Add autokill documentation Signed-off-by: Jerome Jaggi --- pages/features/autokill.mdx | 93 +++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 pages/features/autokill.mdx diff --git a/pages/features/autokill.mdx b/pages/features/autokill.mdx new file mode 100644 index 00000000..21646263 --- /dev/null +++ b/pages/features/autokill.mdx @@ -0,0 +1,93 @@ +--- +title: Autokill +navigation_icon: timer-off +--- + +Autokill automatically terminates instances or service groups when a configured condition triggers. +It helps avoid unnecessary resource usage when instances or groups are no longer needed. + +You can configure autokill on: +- **Instances**: killed after a time, or after reaching a request limit +- **Instance templates**: killed if nobody clones them within a specified time +- **Service groups**: killed after the group has been empty for a specified time + +## Instance autokill + +### Kill after stopped duration + +Automatically kill an instance after it stops and remains stopped for a given number of milliseconds: + +```json title="POST /v1/instances" +{ + "autokill": { + "time_ms": 3600000 + } +} +``` + +This example kills the instance 1 hour after it stops. + +### Kill after a request count + +Kill an instance after it serves a specified request count: + +```json title="POST /v1/instances" +{ + "autokill": { + "num_requests": 1000 + } +} +``` + +### Updating autokill on a stopped instance + +```json title="PATCH /v1/instances/{uuid}" +{ + "prop": "autokill", + "op": "set", + "value": { + "time_ms": 10000 + } +} +``` + +## Service group autokill + +Automatically kill a service group after it stays empty (no instances) for a given number of milliseconds: + +```json title="POST /v1/services" +{ + "autokill": { + "time_ms": 300000 + } +} +``` + +This example kills the service group 5 minutes after its last instance leaves. + +## Instance template autokill + +Automatically kill an instance template if nobody clones it within a given number of milliseconds: + +```json title="POST /v1/instances/templates" +{ + "autokill": { + "time_ms": 86400000 + } +} +``` + +This example removes the template after 24 hours without a clone. + +## Interaction with delete locks + +Autokill skips any instance that has a [delete lock](/platform/delete-locks) set. +The autokill timer doesn't fire while a delete lock is active. + +## Autokill on instance clone + +When you clone an instance from a template, the new instance inherits the autokill configuration. + +## Learn more + +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the sections on [instances](/api/platform/v1/instances) and [services](/api/platform/v1/service-groups) From 31b6fda177347ca1739dfa6b6e078f390c1eacf6 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Fri, 20 Mar 2026 16:32:53 +0200 Subject: [PATCH 066/131] fix(docs): Fix ansi coloring for instance metrics tutorial Signed-off-by: Alex-Andrei Cioc --- pages/tutorials/instance-metrics.mdx | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pages/tutorials/instance-metrics.mdx b/pages/tutorials/instance-metrics.mdx index 53c105cd..7eb6f5ee 100644 --- a/pages/tutorials/instance-metrics.mdx +++ b/pages/tutorials/instance-metrics.mdx @@ -33,19 +33,19 @@ kraft cloud deploy -p 443:8080 -M 256 . This command will create the NGINX instance with scale-to-zero enabled: ```ansi title="" -[90m[[0m[92m●[0m[90m][0m Deployed successfully! - [90mβ”‚[0m - [90mβ”œ[0m[90m──────────[0m [90mname[0m: nginx-26g86 - [90mβ”œ[0m[90m──────────[0m [90muuid[0m: 3605978e-5feb-4209-8f9e-de45f00a7d66 - [90mβ”œ[0m[90m─────────[0m [90mstate[0m: [92mrunning[0m - [90mβ”œ[0m[90m───────────[0m [90murl[0m: https://black-snowflake-iy7509ap.fra.unikraft.app - [90mβ”œ[0m[90m─────────[0m [90mimage[0m: nginx@sha256:19854a12fe97f138313cb9b4806828cae9cecf2d050077a0268d98129863f954 - [90mβ”œ[0m[90m─────[0m [90mboot time[0m: 7.77 ms - [90mβ”œ[0m[90m────────[0m [90mmemory[0m: 256 MiB - [90mβ”œ[0m[90m───────[0m [90mservice[0m: black-snowflake-iy7509ap - [90mβ”œ[0m[90m──[0m [90mprivate fqdn[0m: nginx-26g86.internal - [90mβ”œ[0m[90m────[0m [90mprivate ip[0m: 172.16.6.1 - [90mβ””[0m[90m──────────[0m [90margs[0m: /usr/bin/nginx -c /etc/nginx/nginx.conf +[●] Deployed successfully! + β”‚ + β”œ────────── name: nginx-26g86 + β”œ────────── uuid: 3605978e-5feb-4209-8f9e-de45f00a7d66 + β”œ───────── state: running + β”œ─────────── url: https://black-snowflake-iy7509ap.fra.unikraft.app + β”œ───────── image: nginx@sha256:19854a12fe97f138313cb9b4806828cae9cecf2d050077a0268d98129863f954 + β”œ───── boot time: 7.77 ms + β”œ──────── memory: 256 MiB + β”œ─────── service: black-snowflake-iy7509ap + β”œ── private fqdn: nginx-26g86.internal + β”œ──── private ip: 172.16.6.1 + β””────────── args: /usr/bin/nginx -c /etc/nginx/nginx.conf ``` Now, request the metrics for that instance: From 790a7b3f15ae7fa251352316fcf440cc3aa8866c Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 14:10:31 +0100 Subject: [PATCH 067/131] docs: Add delete locks documentation Signed-off-by: Jerome Jaggi Co-authored-by: Alex-Andrei Cioc --- pages/features/roms.mdx | 4 +- pages/platform/delete-locks.mdx | 169 ++++++++++++++++++++++++++++++++ 2 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 pages/platform/delete-locks.mdx diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index 99649171..b4f500d4 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -5,7 +5,7 @@ navigation_icon: hard-drive import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" -:::caution[Disclaimer] +:::caution[**DISCLAIMER**] The ROM feature isn't currently enabled for the public Unikraft Cloud offering. As such, the [KraftKit CLI tool](/cli/) can't entirely leverage this feature. For boxes where it's enabled, use it via the [Unikraft Cloud API](/api/platform/v1). @@ -15,7 +15,6 @@ Unikraft Cloud supports the ability to attach **Read-Only Memory (ROM)** blobs t It allows you to create a general-purpose base image and then customize individual instances by attaching code or data as separate ROM blobs. This enables quick deployment of custom functionality to preexisting language environments without rebuilding the entire image. - ## Overview With ROMs, you can: @@ -36,7 +35,6 @@ The app running inside the base image is responsible to read the data from the a ROM blobs appear as block devices at paths like `/dev/ukp_rom_`, where `` is the ROM name you specify when creating the instance. ::: - ## Setup This example shows how to deploy Python functions using ROMs on Unikraft Cloud. diff --git a/pages/platform/delete-locks.mdx b/pages/platform/delete-locks.mdx new file mode 100644 index 00000000..8c675652 --- /dev/null +++ b/pages/platform/delete-locks.mdx @@ -0,0 +1,169 @@ +--- +title: Delete Locks +navigation_icon: lock +--- + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +:::caution[**DISCLAIMER**] +The [KraftKit CLI tool](/cli/) does not expose this feature to users yet. +Use it via the [Unikraft Cloud API](/api/platform/v1). +::: + +Delete locks prevent accidental deletion of instances and volumes. +When you set a delete lock on a resource, any attempt to delete it returns an error until you remove it. + +Delete locks apply to: +- Instances +- [Instance templates](TODO: link to instance templates doc) +- Volumes +- [Volume templates](TODO: link to volume templates doc) + +## Enabling a delete lock + +You can set a delete lock on a resource via a `PATCH` operation: + + + + Instance + Instance Template + Volume + Volume Template + + +```bash title="Locking an instance" +curl -X PATCH \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + "https://api.$UKC_METRO.unikraft.cloud/instances" \ + -d "[{ + 'name': '', + 'prop': 'delete_lock', + 'op': 'set', + 'value': true + }]" +``` + + +```bash title="Locking an instance template" +curl -X PATCH \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + "https://api.$UKC_METRO.unikraft.cloud/instance/templates" \ + -d "[{ + 'name': '', + 'prop': 'delete_lock', + 'op': 'set', + 'value': true + }]" +``` + + +```bash title="Locking a volume" +curl -X PATCH \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + "https://api.$UKC_METRO.unikraft.cloud/volumes" \ + -d "[{ + 'name': '', + 'prop': 'delete_lock', + 'op': 'set', + 'value': true + }]" +``` + + +```bash title="Locking a volume template" +curl -X PATCH \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + "https://api.$UKC_METRO.unikraft.cloud/volume/templates" \ + -d "[{ + 'name': '', + 'prop': 'delete_lock', + 'op': 'set', + 'value': true + }]" +``` + + + +## Removing a delete lock + +Before you can delete a resource, you need to remove the delete lock by setting its value to `false`: + + + + Instance + Instance Template + Volume + Volume Template + + +```bash title="Unlocking an instance" +curl -X PATCH \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + "https://api.$UKC_METRO.unikraft.cloud/instances" \ + -d "[{ + 'name': '', + 'prop': 'delete_lock', + 'op': 'set', + 'value': false + }]" +``` + + +```bash title="Unlocking an instance template" +curl -X PATCH \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + "https://api.$UKC_METRO.unikraft.cloud/instance/templates" \ + -d "[{ + 'name': '', + 'prop': 'delete_lock', + 'op': 'set', + 'value': false + }]" +``` + + +```bash title="Unlocking a volume" +curl -X PATCH \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + "https://api.$UKC_METRO.unikraft.cloud/volumes" \ + -d "[{ + 'name': '', + 'prop': 'delete_lock', + 'op': 'set', + 'value': false + }]" +``` + + +```bash title="Unlocking a volume template" +curl -X PATCH \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + "https://api.$UKC_METRO.unikraft.cloud/volume/templates" \ + -d "[{ + 'name': '', + 'prop': 'delete_lock', + 'op': 'set', + 'value': false + }]" +``` + + + +## Behaviour + +- **Deletion blocked**: Any `DELETE` request on a locked resource returns an error. +- **Autokill skipped**: The [autokill](/features/autokill) subsystem skips instances and service groups that have a delete lock set. +- **Templates**: Delete locks are independently configurable on instance templates and volume templates via their respective `PATCH` endpoints. + +## Learn more + +* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the sections on [instances](/api/platform/v1/instances) and [volumes](/api/platform/v1/volumes). From d655eeb917f2b0d107fc95c00eb7f479a9c674c8 Mon Sep 17 00:00:00 2001 From: Razvan Deaconescu Date: Wed, 28 Jan 2026 23:13:36 +0200 Subject: [PATCH 068/131] fix(pages): Improve introduction page Improve introduction page to make it easier to newcomers: - Use "Unikraft Cloud" instead of "Unikraft". - Mention the initialization of the `UKC_METRO` and `UKC_TOKEN` variables. - Include step for installing Docker and optional (but recommended step) of using BuildKit. - Use the `examples` repository. - Reference the Unikraft Cloud console as the default way to create an account and access the token. Signed-off-by: Razvan Deaconescu --- pages/introduction.mdx | 50 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/pages/introduction.mdx b/pages/introduction.mdx index 1d4c8bae..ba2fed42 100644 --- a/pages/introduction.mdx +++ b/pages/introduction.mdx @@ -5,9 +5,9 @@ navigation_icon: book-check import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" -Unikraft is a from-first-principles virtualization solution and cloud platform based on **MicroVMs** which provides best-in-class performance, security, and scalability. +Unikraft Cloud is a from-first-principles virtualization solution and cloud platform based on **MicroVMs** which provides best-in-class performance, security, and scalability. -Running your app on Unikraft is like running a container but with hardware isolation, millisecond cold starts, and stateful scale-to-zero. +Running your app on Unikraft Cloud is like running a container but with hardware isolation, millisecond cold starts, and stateful scale-to-zero. Expect higher server density, cost-savings, I/O performance boosts, active vCPU pricing and _much more_. @@ -17,7 +17,8 @@ Expect higher server density, cost-savings, I/O performance boosts, active vCPU 1. [Create a free account](https://console.unikraft.cloud/signup). -1. Install the `kraft` CLI. +1. Install the `kraft` CLI: + Shell 1-liner @@ -70,14 +71,51 @@ Expect higher server density, cost-savings, I/O performance boosts, active vCPU See [alternative installation instructions](https://unikraft.org/docs/cli/install) for other platforms. -1. Login to your account by setting your access token (received via email): +1. Set a metro you want to use, e.g. `fra`: + + ```bash + export UKC_METRO=fra + ``` + +1. Set your access token (from the [console](https://console.unikraft.cloud/), go to `Settings` and see the `API TOKEN`): + ```bash - export UKC_TOKEN= + export UKC_TOKEN= + ``` + +1. Install Docker on your system, by following [the official instructions](https://docs.docker.com/get-started/get-docker/). + You require Docker to build the app image that you will then deploy on Unikraft Cloud. + + Be sure to follow the [post-installation steps](https://docs.docker.com/engine/install/linux-postinstall/). + +1. (optional, but recommended) Configure BuildKit on your system. + BuildKit is useful to cache the Unikraft Cloud builds and reduce the build time. + + See instructions [here](/platform/troubleshooting#how-can-you-cache-the-apps-filesystem-for-faster-builds). + +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples): + + ```bash + git clone https://github.com/unikraft-cloud/examples + cd examples/ + ``` + +1. Navigate to your favorite example, for example Nginx: + + ```bash + cd nginx/ ``` 1. Deploy your first scale-to-zero, serverless app with Unikraft Cloud: + + ```bash + kraft cloud deploy --port 443:8080 --memory 256Mi . + ``` + +1. Use `curl` or a browser to access the Unikraft Cloud instance of Nginx, at the address shown by the `kraft cloud deploy` command: + ```bash - kraft cloud deploy -p 443:8080 nginx:latest + curl https:// ``` From 771d81afacfcc3c16aae65b388adb50ceef43a1b Mon Sep 17 00:00:00 2001 From: Razvan Deaconescu Date: Mon, 2 Feb 2026 14:22:13 +0200 Subject: [PATCH 069/131] fix(platform): Reduce sentence size Signed-off-by: Razvan Deaconescu --- pages/introduction.mdx | 6 +++--- pages/platform/troubleshooting.mdx | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pages/introduction.mdx b/pages/introduction.mdx index ba2fed42..e1d2546e 100644 --- a/pages/introduction.mdx +++ b/pages/introduction.mdx @@ -17,7 +17,7 @@ Expect higher server density, cost-savings, I/O performance boosts, active vCPU 1. [Create a free account](https://console.unikraft.cloud/signup). -1. Install the `kraft` CLI: +1. Install the [`kraft`](/cli/) CLI: @@ -88,7 +88,7 @@ Expect higher server density, cost-savings, I/O performance boosts, active vCPU Be sure to follow the [post-installation steps](https://docs.docker.com/engine/install/linux-postinstall/). -1. (optional, but recommended) Configure BuildKit on your system. +1. _(optional, but recommended)_ Configure BuildKit on your system. BuildKit is useful to cache the Unikraft Cloud builds and reduce the build time. See instructions [here](/platform/troubleshooting#how-can-you-cache-the-apps-filesystem-for-faster-builds). @@ -112,7 +112,7 @@ Expect higher server density, cost-savings, I/O performance boosts, active vCPU kraft cloud deploy --port 443:8080 --memory 256Mi . ``` -1. Use `curl` or a browser to access the Unikraft Cloud instance of Nginx, at the address shown by the `kraft cloud deploy` command: +1. Use `curl` or a browser to access the Unikraft Cloud instance of Nginx, at the address shown by the `kraft cloud deploy` command (or, use `kraft cloud instance ls` and `kraft cloud instance get ` to get the address): ```bash curl https:// diff --git a/pages/platform/troubleshooting.mdx b/pages/platform/troubleshooting.mdx index 4d4a9f1e..d2bd7d18 100644 --- a/pages/platform/troubleshooting.mdx +++ b/pages/platform/troubleshooting.mdx @@ -291,7 +291,8 @@ Here the cause is insufficient memory. If the stop reason lacks detail, enable debug tracing for the instance. -To do that, in your app of choice in the [examples repository](https://github.com/unikraft-cloud/examples/), or in an app directory you created, update the `runtime` entry in the `Kraftfile` to reference the debug build of the image you use by adding `-dbg` to the name of the runtime. +To do that, in your app of choice in the [examples repository](https://github.com/unikraft-cloud/examples/), or in an app directory you created, update the `runtime` entry in the `Kraftfile`. +The entry should reference the debug build of the image you use by adding `-dbg` to the name of the runtime. For example, if you want to run the [http-go1.21 example](https://github.com/unikraft-cloud/examples/tree/main/http-go1.21) with debug output, update its `Kraftfile` as follows: ```yaml title="Kraftfile" From dff7b1c967141b218593d2410927dc4fd7b7f390 Mon Sep 17 00:00:00 2001 From: mdaria11 Date: Tue, 17 Mar 2026 15:25:11 +0100 Subject: [PATCH 070/131] docs: add templates, cgroups, listing, and metrics to instances Signed-off-by: Jerome Jaggi Co-authored-by: Alex-Andrei Cioc --- pages/platform/domains.mdx | 5 + pages/platform/instances.mdx | 182 +++++++++++++++++++++++++++++++++-- 2 files changed, 177 insertions(+), 10 deletions(-) diff --git a/pages/platform/domains.mdx b/pages/platform/domains.mdx index 0bc54b13..b0502255 100644 --- a/pages/platform/domains.mdx +++ b/pages/platform/domains.mdx @@ -101,3 +101,8 @@ Test the deployment with `curl`: ```bash curl https://mydomain.com ``` + +## Learn more + +* The `kraft cloud` [CLI reference](/cli/), in particular the [deploy](/cli/deploy) and [instance](/cli/instance) subcommands +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the sections on [instances](/api/platform/v1/instances) and [service groups](/api/platform/v1/service-groups) diff --git a/pages/platform/instances.mdx b/pages/platform/instances.mdx index 60dfd3a9..437bc9c7 100644 --- a/pages/platform/instances.mdx +++ b/pages/platform/instances.mdx @@ -6,9 +6,9 @@ description: | --- This document describes the Unikraft Cloud Instances API (v1) for managing Unikraft instances. -An *instance* is a Unikraft virtual machine running a single instance of your app. +An *instance* is a MicroVM running a single instance of your app. -### Instance states +## Instance states An instance can be in one of the following states: @@ -16,21 +16,20 @@ An instance can be in one of the following states: |------------|-------------| | `stopped` | The instance isn't running and doesn't count against live resource quotas. Connections can't establish. | | `starting` | The instance is booting up. This typically takes just a few milliseconds. | -| `running` | Your app reaches its main entry point. | +| `running` | Your app reached its main entry point. | | `draining` | The instance is draining connections before shutting down. No new connections can establish. | | `stopping` | The instance is shutting down. | | `standby` | The instance has scaled-to-zero. The instance isn't running, but will be automatically started when there are incoming requests. | Unikraft Cloud reports these as instance `state` values via the endpoints. -LSB (least significant bit) is the lowest order bit in a binary number. -### Stop reason +## Stop reason To understand why Unikraft Cloud stopped an instance or is shutting it down, it provides information about the stop reason. -You can retrieve this information via the [`GET /v1/instances`](#status) endpoint when an instance is in the `draining`, `stopping`, `stopped` or `standby` state. +You can retrieve this information via the [`GET /instances`](/api/platform/v1/instances#list-instances) endpoint when an instance is in the `draining`, `stopping`, `stopped` or `standby` state. The `stop_reason` contains a bitmask that tells you the origin of the shutdown: -| Bit | 4 [F] | 3 [U] | 2 [P] | 1 [A] | 0 [K] (least significant bit, LSB) | +| Bit | 4 [F] | 3 [U] | 2 [P] | 1 [A] | 0 [K] | |------|---------------------------|----------------------------|----------------------------|------------------------------------|---------------------------------------| |Desc. | This was a force stop[^1] | Stop initiated by user[^2] | Stop initiated by platform | App exited - `exit_code` available | Kernel exited - `stop_code` available | @@ -65,7 +64,7 @@ Unikraft Cloud defines the `stop_code` by the kernel and has the following encod |------|------------------|------------------|----------------|-----------------|----------------| | Desc.| Reserved[^3] | `errno` | `shutdown_bit` | `initlvl` | `reason` | -### Reason +#### Reason The `reason` can be any of the following values: @@ -98,7 +97,7 @@ A level of `127` means the instance was executing the app. :::note For example, an out-of-memory (OOM) situation triggers a page fault `PGFAULT(4)` with `errno` set to `ENOMEM(12)`. -In that case the `stop_code` is `0x000C7F04=818948` and the `stop_reason` is `----K(1)` if the stop occurred during app execution. +In that case the `stop_code` is `0x000C7F04=818948` and the `stop_reason` is `----K (1)` if the stop occurred during app execution. ::: @@ -117,7 +116,8 @@ When an instance stops, Unikraft Cloud evaluates the stop reason and the restart It uses an exponential back-off delay (immediate, 5s, 10s, 20s, 40s, 5m) to slow down restarts in tight crash loops. If an instance runs without problems for 10s, Unikraft Cloud resets the back-off delay and the restart sequence ends. -The `restart.attempt` value in [`GET /v1/instances`](#status) counts restarts in the current sequence. +The `restart.attempt` value in [`GET /instances`](/api/platform/v1/instances#list-instances) counts restarts in the current sequence. +The number of completed restarts is `restart_count`. The `restart.next_at` field indicates when the next restart occurs if a back-off delay is in effect. A manual start or stop of the instance aborts the restart sequence and resets the back-off delay. @@ -129,3 +129,165 @@ A manual start or stop of the instance aborts the restart sequence and resets th [^2]: A stop command originating from the user travels through the platform controller. This is why bit 2 [P] will also always occur for user-initiated stops. [^3]: The system sets reserved bits to 0. Ignore them. + +## Instance templates + +An instance template is a snapshotted instance that acts as a source for cloning new instances. +Cloning a template creates a new instance that resumes from the exact original system state. +It preserves memory contents, open files, and populated caches to bypass the standard boot sequence. +Once you convert an instance into a template, you can't reverse the process. + +To transition an actively running instance into a template, from the guest write the value 1 to `/uk/libukp/template_instance`: + +```bash title="Convert instance to template" +echo 1 > /uk/libukp/template_instance +``` + +This action instructs the controller to freeze running processes and save the instance as a reusable template. + +Templates support [delete locks](/platform/delete-locks), [tags](/platform/tagging), and [autokill](/features/autokill). +The platform measures autokill on a template from the time of last clone, not from instance stop time. + +### Nested templates + +You can clone a template from another template, creating a hierarchy. +Each clone inherits the parent's full state at clone time and can independently accumulate further state before you convert it into its own template. +This enables layered configurations, for example a base template with a warm database connection pool, and child templates specialized for different query workloads. + +No depth limit applies to nesting, and circular references aren't possible because the template state is immutable once set. + +For more information, check out the API reference for instance templates [here](/api/platform/v1/instances#create-template-instances-from-instances). + +## Creating instances + +### Replicas + +The [`POST /instances`](/api/platform/v1/instances#create-instance) request accepts a `replicas` field (default 0) that creates more copies of the instance alongside the base one. + +| Value | Instances created | +|-------|-------------------| +| `0` | 1 (the base instance) | +| `1` | 2 (base + 1 replica) | +| `N` | N + 1 | + +All instances share the same image, memory, arguments, and service group configuration. +Replicas receive independent names and UUIDs. + +### Wait for running + +By default [`POST /instances`](/api/platform/v1/instances#create-instance) returns as soon as the platform queues the instance. +Set `timeout_s` non-zero to block until the instance reaches the `running` state or the timeout expires. +For example: + +```json title="POST /instances" +{ + ... + "image": "nginx:latest", + "memory_mb": 256, + "timeout_s": 10, + ... +} +``` + +:::note +`wait_timeout_ms` is a deprecated compatibility field. +When set, the platform rounds the value up to the next full second. +Use `timeout_s` instead. +::: + +### Delete on stop + +Pass `delete-on-stop` in the features array to automatically delete the instance when it stops: + +```json title="POST /instances" +{ + ... + "image": "nginx:latest", + "memory_mb": 256, + "features": ["delete-on-stop"], + "restart_policy": "never", + ... +} +``` + +This is useful for ephemeral workloadsβ€”batch jobs, one-shot tasksβ€”where you don't need to keep the stopped instance. + +:::note +To use the "delete-on-stop" feature, set the `restart_policy` to `never`. +::: + +## Stopping instances + +### Drain timeout + +By default [`PUT /instances/stop`](/api/platform/v1/instances#stop-instances) stops the instance immediately. +Set `drain_timeout_ms` to allow the instance to finish serving in-flight connections before it stops. + +| Value | Behaviour | +|-------|-----------| +| `0` | Stop immediately (default). | +| `-1` | Use the platform's maximum drain timeout. | +| `N` | Drain for up to N milliseconds, then stop. | + +```json title="PUT /instances/stop" +{ + ... + "name": "my-instance", + "drain_timeout_ms": 5000, + ... +} +``` + +While draining, the instance enters the `draining` state. +The platform accepts no new connections. +The instance stops once all connections close or the timeout elapses. + +:::note +You can't combine `drain_timeout_ms` with `force: true`. +Setting both returns a `400` error. +::: + +## Instance metrics + +Use the [`GET /instances/metrics`](/api/platform/v1/instances#get-instances-metrics) endpoint to retrieve runtime statistics for one or more instances. +With no identifiers, the platform returns metrics for all instances in your account. + +### Response format + +Include the header `Accept: application/json` to receive a JSON response. +Otherwise, you will receive metrics in Prometheus text format, that you can parse with Prometheus client libraries. + +**JSON response**: each instance object contains: + +| Field | Type | Description | +|-------|------|-------------| +| `state` | string | Current instance state. | +| `start_count` | int | Number of times the instance has started. | +| `restart_count` | int | Number of restarts (omitted if 0). | +| `started_at` | timestamp | Time of last start (omitted if unset). | +| `stopped_at` | timestamp | Time of last stop (omitted if unset). | +| `uptime_ms` | int64 | Current uptime in milliseconds. | +| `boot_time_us` | int | Boot time in microseconds (omitted if 0). | +| `net_time_us` | int | Network setup time in microseconds (omitted if 0). | +| `rss_bytes` | int64 | Resident set size in bytes. | +| `cpu_time_ms` | int64 | Consumed CPU time in milliseconds. | +| `rx_bytes` | int64 | Bytes received over the network. | +| `rx_packets` | int64 | Packets received from the network. | +| `tx_bytes` | int64 | Bytes transmitted over the network. | +| `tx_packets` | int64 | Packets transmitted over the network. | +| `nconns` | int | Number of active connections. | +| `nreqs` | int | Number of active HTTP requests. | +| `nqueued` | int | Number of queued connections or requests. | +| `ntotal` | int64 | Total connections or requests processed since start. | +| `wakeup_latency` | array | Histogram buckets. Each bucket has `bucket_ms` (upper bound, or `null` for overflow) and `count`. | +| `wakeup_latency_sum` | uint64 | Sum of all recorded wakeup latencies. | + +## Instance logs + +Use the [`GET /instances/logs`](/api/platform/v1/instances#get-instances-logs) endpoint to retrieve logs for one or more instances. +The logs capture the instance's `stdout` and `stderr` output, and they're preserved across restarts and stops. + +## Learn more + +* The `kraft cloud` [CLI reference](/cli/), in particular the [deploy](/cli/deploy) and [instance](/cli/instance) subcommands +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [instances](/api/platform/v1/instances) From c76b4b1f5be58accd22cabb277282e87e27067da Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 15:29:46 +0100 Subject: [PATCH 071/131] docs: add volume templates, cloning, and shared volumes sections Signed-off-by: Jerome Jaggi Co-authored-by: Alex-Andrei Cioc --- pages/features/roms.mdx | 2 +- pages/platform/delete-locks.mdx | 4 +- pages/platform/volumes.mdx | 125 +++++++++++++++++----- pages/tutorials/environment-variables.mdx | 4 +- pages/tutorials/network-communication.mdx | 2 +- 5 files changed, 106 insertions(+), 31 deletions(-) diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index b4f500d4..2524e08d 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -5,7 +5,7 @@ navigation_icon: hard-drive import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" -:::caution[**DISCLAIMER**] +:::caution The ROM feature isn't currently enabled for the public Unikraft Cloud offering. As such, the [KraftKit CLI tool](/cli/) can't entirely leverage this feature. For boxes where it's enabled, use it via the [Unikraft Cloud API](/api/platform/v1). diff --git a/pages/platform/delete-locks.mdx b/pages/platform/delete-locks.mdx index 8c675652..7dd6abe5 100644 --- a/pages/platform/delete-locks.mdx +++ b/pages/platform/delete-locks.mdx @@ -5,8 +5,8 @@ navigation_icon: lock import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" -:::caution[**DISCLAIMER**] -The [KraftKit CLI tool](/cli/) does not expose this feature to users yet. +:::caution +The [KraftKit CLI tool](/cli/) doesn't expose this feature to users yet. Use it via the [Unikraft Cloud API](/api/platform/v1). ::: diff --git a/pages/platform/volumes.mdx b/pages/platform/volumes.mdx index 8e52294f..6b679f66 100644 --- a/pages/platform/volumes.mdx +++ b/pages/platform/volumes.mdx @@ -3,21 +3,17 @@ title: Volumes navigation_icon: cylinder --- -A volume is a persistent storage device that keeps data across restarts. +A volume is a persistent storage device that keeps data across restarts and even redeployments. -In this guide you will create a volume, attach it to a web server instance, and write to it. +This documents presents a guide where you will create a volume, attach it to a web server instance, and write to it. Then you will detach it, remove that instance, attach it to a new instance, and confirm the data persisted. -Finally, the guide covers how to share volumes across instances (read-only at present). +Finally, the guide covers how to share volumes across instances (*read-only* at present). -:::note +## Volume workflow -You can also share a volume across many instances as a read-only mount (read-write sharing is in progress). +### Setting up the volume -::: - -## Setting up the volume - -To start, create the volume via `kraft cloud volume`, with size in MBs and name `my-volume`: +To start, create the volume via [`kraft cloud volume`](/cli/kraft/volume), with size in MBs and name `my-volume`: ```bash title="" kraft cloud volume create --size 100 --name my-volume @@ -39,9 +35,9 @@ my-volume 15 seconds ago 100 MiB available true The `ATTACHED TO` field is empty because the platform hasn't attached it to any instance yet. -## Populating the volume with local data (Optional) +### Populating the volume with local data (optional) -If you'd like to populate your empty volume with local data, you can use the `kraft cloud volume import` command. +If you'd like to populate your empty volume with local data, you can use the [`kraft cloud volume import`](/cli/kraft/volume/import) command. For example, assuming the volume's name is `my-volume` and that the data you want to import are in your `my-data` directory, you would run: ```bash title="" @@ -51,18 +47,14 @@ kraft cloud volume import --volume my-volume --source my-data You should see output like: ```ansi title="" -[+] Packaging source as a CPIO archive... done! [0.0s] -[+] Spawning temporary volume data import instance... done! [0.1s] -[+] Importing data (256 B) β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’ 100% [0.1s] - -[●] Import complete - β”‚ - β”œβ”€β”€β”€ volume: my-volume - β”œβ”€ imported: 256 B - └─ capacity: 100 MiB +[●] Import complete + β”‚ + β”œ─ volume: my-volume + β”œ─── free: 99 MiB + β””── total: 100 MiB ``` -## Setting up the web server +### Setting up a web server Use a Flask web server to write to the volume: @@ -148,7 +140,7 @@ NAME CREATED AT SIZE ATTACHED TO STATE PERSI my-volume 34 minutes ago 100 MiB http-python312-flask30-2h608 mounted true ``` -## Testing it +### Testing the server The Flask server writes the time and date to `/mnt/log.txt` for each request. Test it by running `curl` several times. @@ -207,7 +199,7 @@ Run one final `curl` to this new address. You should see the previous contents plus a new entry at the bottom: ```bash title="" -$ curl https://holy-bonobo-px345skl.fra.unikraft.app +$ curl https://winter-field-v6m37jgs.fra.unikraft.app Log file created. 2024-02-24 08:15:32 2024-02-24 08:15:34 @@ -215,7 +207,7 @@ Log file created. 2024-02-24 08:20:58 ``` -## Cleaning up +### Cleaning up To clean up, first detach the volume from all instances and then remove it: @@ -224,6 +216,89 @@ kraft cloud volume detach kraft cloud volume remove ``` +## Volume templates + +A volume template is a volume in the `TEMPLATE` state. +Once a volume transitions to template state, it's immutable: you can clone it but not write to it or delete it while active clones exist. + +The platform creates volume templates automatically when you convert an instance into an [instance template](/platform/instances#instance-templates): the platform converts all volumes attached to that instance into volume templates as an atomic operation. + +Volume templates have their own create, read, update, and delete endpoints at [`/v1/volumes/templates`](/api/v1/volumes#create-template-volumes). +They support [delete locks](/platform/delete-locks) and [tags](/platform/tagging). + +## Volume cloning + +A volume clone is an independent copy of an existing volume. +The clone operation is **asynchronous**: the platform creates the new volume immediately in a pending state, and the data copy completes in the background. +To clone one or more volumes, you can use the [`POST /v1/volumes/clone`](/api/v1/volumes#clone-volumes) endpoint. + +The platform also clones volumes implicitly when you clone an instance or create one from a template. +It clones each attached volume and attaches the clone to the new instance. + +You can't delete a source volume or template while it has active clones. + +## Shared volumes + +More than one instance can mount the same volume simultaneously as long as all mounts are in *read-only* mode. +Read-only sharing is always permitted regardless of how many other instances have the volume mounted. + +A *read-write* mount is **exclusive**. +You can't add one while any other mount exists on that volume, and a volume can't have two *read-write* mounts at once. + +Specify `readonly: true` when attaching a volume at instance creation or via the attach endpoint: + +```json title="POST /v1/instances" +{ + ... + "volumes": [ + { + "name": "my-shared-volume", + "at": "/data", + "readonly": true + } + ], + ... +} +``` + +## Custom filesystems + +By default, volumes use a platform-configured filesystem (typically `ext4` for block volumes and `virtiofs` for hosted volumes). +If the platform operator has registered more named filesystems, you can select one by passing its name in the `filesystem` field when creating a volume: + +```json title="POST /v1/volumes" +{ + "name": "my-volume", + "size_mb": 512, + "filesystem": "virtiofs" +} +``` + +### Managed volumes + +:::caution +This is an advanced feature that's only available on the self-hosted platform. +Quotas aren't yet enforced by the platform for managed volumes, so use them with caution to avoid filling up your host's disk. +::: + +A managed volume points to an existing directory on the host rather than a platform-allocated storage file. + +Create a managed volume with a `host_path` field instead of `size_mb`: + +```json title="POST /v1/volumes" +{ + "name": "my-managed-volume", + "host_path": "/srv/data/mydir", + "uid": 1000, + "gid": 1000 +} +``` + +- `host_path` must be an absolute, normalised path to an existing directory on the host (no `.`, `..`, or `:` components). +- `uid` and `gid` set the ownership used when accessing the volume from the guest. Both default to `0` if not specified. +- `size_mb` and `template` are mutually exclusive with `host_path`. +- The platform doesn't create, format, resize, or delete the backing directory for managed volumes. + ## Learn more * The `kraft cloud` [CLI reference](/cli/), in particular the [deploy](/cli/deploy) and [volume](/cli/volume) subcommands diff --git a/pages/tutorials/environment-variables.mdx b/pages/tutorials/environment-variables.mdx index 35f0f0f4..1d21be00 100644 --- a/pages/tutorials/environment-variables.mdx +++ b/pages/tutorials/environment-variables.mdx @@ -16,7 +16,7 @@ The order they're presented is from the least precedence to the highest preceden ### Dockerfile ENV -:::caution[Disclaimer] +:::caution At the moment environment variables from the `Dockerfile` are passed in the image but not read by the Unikraft Cloud platform. Please use the other methods described below in the meantime. ::: @@ -33,7 +33,7 @@ ENV MY_ENV_VAR=my_value ### Kraftfile env -:::caution[Disclaimer] +:::caution At the moment environment variables from the `Kraftfile` are passed in the image but not read by the Unikraft Cloud platform. Nonetheless, `kraft cloud deploy` can still read them and set them in the instance. For other use cases, please use the other methods described below in the meantime. diff --git a/pages/tutorials/network-communication.mdx b/pages/tutorials/network-communication.mdx index 530ebbd4..f6ee1383 100644 --- a/pages/tutorials/network-communication.mdx +++ b/pages/tutorials/network-communication.mdx @@ -3,7 +3,7 @@ title: Network Communication navigation_icon: network --- -:::caution[Disclaimer] +:::caution As of writing this, [scale-to-zero triggers](/tutorials/scale-to-zero-triggers) are unavailable on internal networking and, as such you must use external networking. Moreover, there is no load balancing on internal networks, this being up to the user. ::: From 93a416c73b6358cb1ede30df6e1a600e28f74844 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 24 Mar 2026 16:56:23 +0200 Subject: [PATCH 072/131] fix: Remove v1 from endpoints references Signed-off-by: Alex-Andrei Cioc --- pages/features/autokill.mdx | 10 +++++----- pages/features/cron-jobs.mdx | 6 +++--- pages/features/scale-to-zero.mdx | 2 +- pages/platform/images.mdx | 12 ++++++------ pages/platform/metrics.mdx | 6 +++--- pages/platform/quotas.mdx | 6 +++--- pages/platform/services.mdx | 10 +++++----- pages/platform/tagging.mdx | 10 +++++----- pages/platform/volumes.mdx | 18 ++++++++++++------ 9 files changed, 43 insertions(+), 37 deletions(-) diff --git a/pages/features/autokill.mdx b/pages/features/autokill.mdx index 21646263..e4fe5a9a 100644 --- a/pages/features/autokill.mdx +++ b/pages/features/autokill.mdx @@ -17,7 +17,7 @@ You can configure autokill on: Automatically kill an instance after it stops and remains stopped for a given number of milliseconds: -```json title="POST /v1/instances" +```json title="POST /instances" { "autokill": { "time_ms": 3600000 @@ -31,7 +31,7 @@ This example kills the instance 1 hour after it stops. Kill an instance after it serves a specified request count: -```json title="POST /v1/instances" +```json title="POST /instances" { "autokill": { "num_requests": 1000 @@ -41,7 +41,7 @@ Kill an instance after it serves a specified request count: ### Updating autokill on a stopped instance -```json title="PATCH /v1/instances/{uuid}" +```json title="PATCH /instances/{uuid}" { "prop": "autokill", "op": "set", @@ -55,7 +55,7 @@ Kill an instance after it serves a specified request count: Automatically kill a service group after it stays empty (no instances) for a given number of milliseconds: -```json title="POST /v1/services" +```json title="POST /services" { "autokill": { "time_ms": 300000 @@ -69,7 +69,7 @@ This example kills the service group 5 minutes after its last instance leaves. Automatically kill an instance template if nobody clones it within a given number of milliseconds: -```json title="POST /v1/instances/templates" +```json title="POST /instances/templates" { "autokill": { "time_ms": 86400000 diff --git a/pages/features/cron-jobs.mdx b/pages/features/cron-jobs.mdx index e2b7e001..bbfd7a28 100644 --- a/pages/features/cron-jobs.mdx +++ b/pages/features/cron-jobs.mdx @@ -32,7 +32,7 @@ The expression syntax supports ranges, steps, and comma-separated lists: Pass `schedules` in the create request. For example, to start an instance every day at 09:00 UTC and stop it at 18:00 UTC: -```json title="POST /v1/instances" +```json title="POST /instances" { "image": "...", "schedules": [ @@ -54,7 +54,7 @@ For example, to start an instance every day at 09:00 UTC and stop it at 18:00 UT Add, set, or remove scheduled operations via `PATCH`: -```json title="PATCH /v1/instances/{uuid}" +```json title="PATCH /instances/{uuid}" { "prop": "schedules", "op": "add", @@ -68,7 +68,7 @@ Add, set, or remove scheduled operations via `PATCH`: } ``` -```json title="PATCH /v1/instances/{uuid}" +```json title="PATCH /instances/{uuid}" { "prop": "schedules", "op": "del", diff --git a/pages/features/scale-to-zero.mdx b/pages/features/scale-to-zero.mdx index 727e80a6..2f08d041 100644 --- a/pages/features/scale-to-zero.mdx +++ b/pages/features/scale-to-zero.mdx @@ -113,7 +113,7 @@ Your app can listen on vsock port `138` and use the signal to: Use the `notify_time_ms` field in the `scale_to_zero` configuration when creating or updating an instance to specify the number of milliseconds before the scaletozero event, when the platform should send the notification signal: -```json title="POST /v1/instances" +```json title="POST /instances" { "scale_to_zero": { "cooldown_time_ms": 5000, diff --git a/pages/platform/images.mdx b/pages/platform/images.mdx index 57d4bdb1..261c1011 100644 --- a/pages/platform/images.mdx +++ b/pages/platform/images.mdx @@ -190,7 +190,7 @@ You now have a new instance created from the existing image. ### List images ``` -GET /v1/images +GET /images ``` Returns all images accessible for your account and known by the platform. @@ -212,7 +212,7 @@ Each image object includes: ### Look up by UUID ``` -GET /v1/images?uuid=[,…] +GET /images?uuid=[,…] ``` Returns one or more images by UUID. @@ -220,12 +220,12 @@ Returns one or more images by UUID. ### Look up by digest ``` -GET /v1/images +GET /images ``` Pass a `digest` string in the request body to return the image matching that digest: -```json title="GET /v1/images" +```json title="GET /images" { "digest": "user/image@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472" } @@ -236,12 +236,12 @@ The response includes `url`, `tags`, `initrd_or_rom`, `size_in_bytes`, args` and ### Look up by tag ``` -GET /v1/images +GET /images ``` Pass a `tag` string in the request body to return the image matching that tag: -```json title="GET /v1/images" +```json title="GET /images" { "tag": "user/image:tag" } diff --git a/pages/platform/metrics.mdx b/pages/platform/metrics.mdx index e0476d8f..8bfbf53a 100644 --- a/pages/platform/metrics.mdx +++ b/pages/platform/metrics.mdx @@ -10,9 +10,9 @@ Unikraft Cloud exposes runtime metrics for each instance: CPU time, memory usage ## Endpoints ``` -GET /v1/instances/{uuid}/metrics -GET /v1/instances/metrics?uuid=[,…] -POST /v1/instances/metrics (UUIDs or names in request body) +GET /instances/{uuid}/metrics +GET /instances/metrics?uuid=[,…] +POST /instances/metrics (UUIDs or names in request body) ``` With no identifiers, the platform returns metrics for all instances in your account. diff --git a/pages/platform/quotas.mdx b/pages/platform/quotas.mdx index e1ce0cc5..2a98b132 100644 --- a/pages/platform/quotas.mdx +++ b/pages/platform/quotas.mdx @@ -11,11 +11,11 @@ Use the quotas endpoint to inspect your current usage and limits. ## Endpoints ``` -GET /v1/users/quotas -GET /v1/users/{uuid}/quotas +GET /users/quotas +GET /users/{uuid}/quotas ``` -`GET /v1/users/quotas` (no UUID) returns the quota for the authenticated user. +`GET /users/quotas` (no UUID) returns the quota for the authenticated user. ## Response structure diff --git a/pages/platform/services.mdx b/pages/platform/services.mdx index de095746..5dc63d6c 100644 --- a/pages/platform/services.mdx +++ b/pages/platform/services.mdx @@ -174,7 +174,7 @@ You must also list the `UDP` IPs in the `additional_ip_addresses` directive in ` To create a `UDP` service, set both `protocol` and `ip`: -```json title="POST /v1/services" +```json title="POST /services" { "services": [ { @@ -201,9 +201,9 @@ Every service group has a soft and a hard connection limit that the load balance `soft_limit` must be less than or equal to `hard_limit`. Setting `soft_limit > hard_limit` returns a `400` error. -You can set both fields at service group creation time and update them later with `PATCH /v1/services/{name}`. +You can set both fields at service group creation time and update them later with `PATCH /services/{name}`. -```json title="POST /v1/services" +```json title="POST /services" { "name": "my-service", "soft_limit": 100, @@ -215,12 +215,12 @@ You can set both fields at service group creation time and update them later wit A service group is **persistent** when your user account owns it rather than a specific instance. -- A service group created with `kraft cloud service create` (or `POST /v1/services`) is persistent. +- A service group created with `kraft cloud service create` (or `POST /services`) is persistent. It survives independently of any instances attached to it. - A service group created implicitly via `kraft cloud deploy -p …` (shorthand port forwarding) belongs to the instance. The platform deletes it when you delete that instance. -The `GET /v1/services/{name}` response includes a `persistent` field (`bool`) that indicates which case applies. +The `GET /services/{name}` response includes a `persistent` field (`bool`) that indicates which case applies. ## Learn more diff --git a/pages/platform/tagging.mdx b/pages/platform/tagging.mdx index 8cb879cb..c1c21baf 100644 --- a/pages/platform/tagging.mdx +++ b/pages/platform/tagging.mdx @@ -18,7 +18,7 @@ Kraftkit neither displays them nor allows you to edit them. Add tags to a resource at creation time: -```json title="POST /v1/instances" +```json title="POST /instances" { "image": "...", "memory_mb": ..., @@ -28,7 +28,7 @@ Add tags to a resource at creation time: Add tags to an existing resource (`"op": "set"` will replace all existing tags): -```json title="PATCH /v1/instances" +```json title="PATCH /instances" { "name": "example-instance", "prop": "tags", @@ -43,7 +43,7 @@ Use `/v1/volumes` for volumes, `/v1/instances/templates` for instance templates, Add tags to a resource without replacing existing ones (`"op": "add"`): -```json title="PATCH /v1/instances" +```json title="PATCH /instances" { "name": "example-instance", "prop": "tags", @@ -62,7 +62,7 @@ Adding a tag already attached to a resource has no effect. Remove specific tags from a resource (`"op": "del"`): -```json title="PATCH /v1/instances" +```json title="PATCH /instances" { "name": "example-instance", "prop": "tags", @@ -77,7 +77,7 @@ Filter the instance list, volume list, instance template list, or volume templat Only resources that have _all_ the specified tags appear in the results. ``` -GET /v1/instances?tags=production,customer_A +GET /instances?tags=production,customer_A ``` Separate tags by commas (`,`). diff --git a/pages/platform/volumes.mdx b/pages/platform/volumes.mdx index 6b679f66..b006a9c1 100644 --- a/pages/platform/volumes.mdx +++ b/pages/platform/volumes.mdx @@ -7,10 +7,16 @@ A volume is a persistent storage device that keeps data across restarts and even This documents presents a guide where you will create a volume, attach it to a web server instance, and write to it. Then you will detach it, remove that instance, attach it to a new instance, and confirm the data persisted. -Finally, the guide covers how to share volumes across instances (*read-only* at present). + +Then, it presents some features of volumes. ## Volume workflow +:::note +You can create an instance with attached volumes in the same call - see the `volumes` field for the [`POST /instances`](/api/platform/v1/instances#create-instance) endpoint. +In this case, the volume's lifetime is tied to the instance - when you delete the instance, the volume disappears. +::: + ### Setting up the volume To start, create the volume via [`kraft cloud volume`](/cli/kraft/volume), with size in MBs and name `my-volume`: @@ -223,14 +229,14 @@ Once a volume transitions to template state, it's immutable: you can clone it bu The platform creates volume templates automatically when you convert an instance into an [instance template](/platform/instances#instance-templates): the platform converts all volumes attached to that instance into volume templates as an atomic operation. -Volume templates have their own create, read, update, and delete endpoints at [`/v1/volumes/templates`](/api/v1/volumes#create-template-volumes). +Volume templates have their own create, read, update, and delete endpoints at [`/volumes/templates`](/api/v1/volumes#create-template-volumes). They support [delete locks](/platform/delete-locks) and [tags](/platform/tagging). ## Volume cloning A volume clone is an independent copy of an existing volume. The clone operation is **asynchronous**: the platform creates the new volume immediately in a pending state, and the data copy completes in the background. -To clone one or more volumes, you can use the [`POST /v1/volumes/clone`](/api/v1/volumes#clone-volumes) endpoint. +To clone one or more volumes, you can use the [`POST /volumes/clone`](/api/v1/volumes#clone-volumes) endpoint. The platform also clones volumes implicitly when you clone an instance or create one from a template. It clones each attached volume and attaches the clone to the new instance. @@ -247,7 +253,7 @@ You can't add one while any other mount exists on that volume, and a volume can' Specify `readonly: true` when attaching a volume at instance creation or via the attach endpoint: -```json title="POST /v1/instances" +```json title="POST /instances" { ... "volumes": [ @@ -266,7 +272,7 @@ Specify `readonly: true` when attaching a volume at instance creation or via the By default, volumes use a platform-configured filesystem (typically `ext4` for block volumes and `virtiofs` for hosted volumes). If the platform operator has registered more named filesystems, you can select one by passing its name in the `filesystem` field when creating a volume: -```json title="POST /v1/volumes" +```json title="POST /volumes" { "name": "my-volume", "size_mb": 512, @@ -285,7 +291,7 @@ A managed volume points to an existing directory on the host rather than a platf Create a managed volume with a `host_path` field instead of `size_mb`: -```json title="POST /v1/volumes" +```json title="POST /volumes" { "name": "my-managed-volume", "host_path": "/srv/data/mydir", From fa747c815eaf6e2e3f3ed939c67c16db66425090 Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Fri, 13 Mar 2026 15:29:14 +0100 Subject: [PATCH 073/131] docs: add policy types and step constraints to autoscale page Signed-off-by: Jerome Jaggi Co-authored-by: Dragos Gheorghioiu --- pages/features/autoscale.mdx | 100 +++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/pages/features/autoscale.mdx b/pages/features/autoscale.mdx index 3db9fa8c..0bf6e56a 100644 --- a/pages/features/autoscale.mdx +++ b/pages/features/autoscale.mdx @@ -196,6 +196,106 @@ You can use the `watch` tool to see if you catch the instance changing state fro watch --color -n 0.5 kraft cloud instance list ``` +## Policy types + +Four autoscale policy types are available. +A service can have more than one policy active at the same time. + +### Step policy + +The `step` policy scales instances based on metric thresholds. +You define up to **4 steps**, each specifying a lower bound, upper bound, and the scaling change to apply when the metric falls in that range. + +You should order steps by lower bound with no gaps between them and no overlaps. + +```bash title="" +kraft cloud scale add \ + --name my-step-policy \ + --type step \ + --metric cpu \ + --adjustment-type change \ + --step 600:800/2 \ + --step 800:/4 +``` + +#### Metrics + +The following metrics can drive a step policy: + +| Metric | Description | +|--------|-------------| +| `cpu` | CPU utilization in millicores | +| `inflight_reqs` | Number of requests the platform is processing across all instances | +| `reqs_per_sec` | Request throughput in requests per second | + +#### Scale change types + +Step policies support three scaling change types: + +| Type | Description | +|------|-------------| +| `change` | Change the instance count by the specified value (positive to scale out, negative to scale in) | +| `exact` | Set the instance count to exactly the specified value | +| `percent` | Change the instance count by the specified percentage of the current count | + + +### On-demand policy + +The `on-demand` policy creates a new instance immediately when an incoming request finds no available instances. +This prevents request queuing but introduces cold start delays. + +```json title="POST /services" +{ + ... + "policies": [ + { + "name": "scale-out", + "type": "on_demand" + } + ] + ... +} +``` + +### Create policy + +The `create` policy provisions a new VM when an instance exceeds the `num_requests` threshold. +Setting `replace` to true deletes the original VM after the new one starts. + +```json title="POST /services" +{ + ... + "policies": [ + { + "name": "create", + "type": "create", + "replace": true, + "num_requests": 100 + } + ] + ... +} +``` + + +### Idle policy + +The `idle` policy scales in (removes instances) when the service has been idleβ€”receiving no requestsβ€”for a configurable period. + +```json title="POST /services" +{ + ... + "policies": [ + { + "name": "scale-in", + "type": "idle", + "idle_time_ms": 1000 + } + ] + ... +} +``` + ## Learn more * The `kraft cloud` [command-line tool reference](/cli/), and in particular the [scale](/cli/scale) subcommand. From 24dd7ba8e5e5826d8f09f2872178053b204f71b8 Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Wed, 25 Mar 2026 16:52:10 +0200 Subject: [PATCH 074/131] feat(tutorials): Add tutorial on how to port docker images to ukc Signed-off-by: Cezar Craciunoiu --- pages/tutorials/docker-to-ukc.mdx | 328 ++++++++++++++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 pages/tutorials/docker-to-ukc.mdx diff --git a/pages/tutorials/docker-to-ukc.mdx b/pages/tutorials/docker-to-ukc.mdx new file mode 100644 index 00000000..cd4d1e95 --- /dev/null +++ b/pages/tutorials/docker-to-ukc.mdx @@ -0,0 +1,328 @@ +--- +title: Docker To Unikraft Cloud +navigation_icon: package +--- + +This tutorial shows how to take an existing container image and turn it into a Unikraft Cloud deployment. +It starts with a safe first pass that keeps the upstream filesystem intact. +It then shows how to slim the image down to a bare minimum deployment. + +The examples use `FROM image:latest` as a placeholder for the upstream OCI image. +They follow the same general pattern used in the [Unikraft Cloud example repository](https://github.com/unikraft-cloud/examples). + +## Prerequisites + +Make sure you have the [`kraft` CLI](/cli/install) installed. +You also need a container runtime such as Docker because the `Dockerfile` builds the root filesystem. + +Set your Unikraft Cloud access token and preferred metro before deploying: + +```bash +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + +## Use the upstream image + +The fastest way to get an existing container running on Unikraft Cloud is to keep its root filesystem as-is. +For that, BuildKit fetches the upstream image through a `FROM image:latest` line and the `Kraftfile` reproduces the original start command. + +### Inspect the upstream image + +Before writing the `Kraftfile`, inspect the original image and record its effective startup command. +In Docker terms, the final process arguments are usually `ENTRYPOINT` followed by `CMD`. + +```bash +docker pull image:latest +docker image inspect image:latest --format '{{json .Config.Entrypoint}}' +docker image inspect image:latest --format '{{json .Config.Cmd}}' +docker image inspect image:latest --format '{{json .Config.WorkingDir}}' +docker image inspect image:latest --format '{{json .Config.ExposedPorts}}' +``` + +Use the values you get as follows: + +* If `Entrypoint` is empty, use `Cmd` as the full `cmd` value in the `Kraftfile`. +* If both are present, concatenate them in the same order and use the result as the `cmd` value. +* If the image starts through a wrapper such as `docker-entrypoint.sh`, keep that wrapper in the command line. +* Prefer absolute paths in `cmd` so the deployment doesn't depend on a specific working directory. + +### Create the initial files + +Start with the smallest possible `Dockerfile`: + +```dockerfile title="Dockerfile" +FROM image:latest +``` + +Then create a matching `Kraftfile`: + +```yaml title="Kraftfile" +spec: v0.6 + +runtime: base-compat:latest + +rootfs: ./Dockerfile + +cmd: ["/path/from-entrypoint", "arg1", "arg2"] +``` + +In this first-pass `Kraftfile`: + +* `runtime: base-compat:latest` selects the generic compatibility runtime. +* `rootfs: ./Dockerfile` tells `kraft` to build the root filesystem from the `Dockerfile`. +* `cmd: [...]` explicitly sets the process arguments that should run inside the instance. + +Replace the placeholder command with the exact values extracted from `docker image inspect`. +For example, if the image reports `Entrypoint=["/usr/local/bin/docker-entrypoint.sh"]` and `Cmd=["postgres"]`, then use `cmd: ["/usr/local/bin/docker-entrypoint.sh", "postgres"]`. + +:::caution +These Dockerfile keywords aren't deployment controls on Unikraft Cloud. +In particular, `EXPOSE`, `HEALTHCHECK`, `ONBUILD`, `SHELL`, `STOPSIGNAL`, and `VOLUME` are ignored as Docker deployment semantics. +Also note that instances run as `root` unless you explicitly switch users at runtime. +::: + +### Deploy the first pass + +Run an initial deployment before optimizing anything. +This confirms that the runtime, filesystem, and command line are valid. + +```bash +kraft cloud deploy \ + -p 443: \ + -M 512Mi \ + . +``` + +Replace [``](/platform/services) with the app's listen port. +Take this value from the image documentation or from the `ExposedPorts` field you inspected earlier. + +If the instance fails to boot, inspect the logs and fix the command line first. +In most broken first attempts, the issue is either a wrong executable path, a missing wrapper script, or insufficient memory. + +:::note +If the upstream image depends on a specific `WORKDIR`, verify whether absolute paths are enough. +If not, add a small wrapper script that changes directory and then `exec`s the original command. +::: + +## Slim the root filesystem + +Once the first pass works, the next step is to stop shipping the entire upstream image. +The goal is to copy only the files needed at runtime into a minimal final stage. + +In practice, that often means removing: + +* package manager caches; +* compilers and build tools; +* test data and documentation; +* shells you no longer need; +* temporary build artifacts. + +### Find the files you actually need + +For native or mixed-language workloads, the difficult part is identifying the runtime dependencies that must stay in the image. +The exact list depends on the upstream image. + +Use the upstream container to inspect the binary and its dependencies: + +```bash +docker run --rm --entrypoint sh image:latest -lc ' + command -v your-app || true + ldd /path/to/executable || true +' +``` + +If the image doesn't contain a shell, use a temporary debug image or inspect the filesystem with `docker create` and `docker cp`. +The goal is the same in both cases: copy only what the final process needs at runtime. + +:::tip +Verify whether the upstream image is glibc-based or musl-based before copying the loader and shared libraries. +The sample paths above use musl-flavoured locations because that's a common pattern in the examples, but your image may differ. +::: + +### Strip binaries and libraries + +Once you know which files the app needs, the next step is to reduce the size of the native executables and shared libraries themselves. +This helps most with native apps and compiled dependencies. + +The common tool for this is `strip` from `binutils`. +It removes symbol and debug information that the app doesn't need at runtime. + +:::note +Use stripping only after the app already boots correctly. +::: + +Start with the main executable and the libraries you identified with `ldd`: + +```dockerfile title="Dockerfile" +FROM image:latest AS upstream + +RUN strip --strip-unneeded /path/to/executable && \ + strip --strip-unneeded /usr/lib/libexample.so.1 +``` + +If the upstream image doesn't include `strip`, install the required tooling only in the build stage. +Don't copy that tooling into the final `scratch` stage. + +For example, on Debian-based images: + +```dockerfile title="Dockerfile" +FROM image:latest AS upstream + +RUN apt-get update && \ + apt-get install -y --no-install-recommends binutils + +RUN strip --strip-unneeded /path/to/executable && \ + strip --strip-unneeded /usr/lib/libexample.so.1 +``` + +As a rule of thumb, strip these files only when they're part of your runtime path: + +* the main executable; +* helper executables started by wrapper scripts; +* shared libraries reported by `ldd`. + +:::warning +Don't strip files if you will need them for debugging later. +::: + +### Convert the Dockerfile to a multi-stage build + +Start from the upstream image in a build stage. +Then copy only the final executable, its direct shared libraries, and the app files into a `scratch` stage. + +```dockerfile title="Dockerfile" +FROM image:latest AS upstream + +# Add framework-specific build steps here if the image needs a compile step. +# Remove caches here if the upstream image leaves package manager data behind. + +FROM scratch + +# Copy the main executable or wrapper script used by the app. +COPY --from=upstream /path/to/executable /path/to/executable + +# Copy the dynamic loader and shared libraries required by the executable. +COPY --from=upstream /lib/ld-musl-x86_64.so.1 /lib/ld-musl-x86_64.so.1 +COPY --from=upstream /usr/lib/libgcc_s.so.1 /usr/lib/libgcc_s.so.1 +COPY --from=upstream /usr/lib/libstdc++.so.6 /usr/lib/libstdc++.so.6 + +# Distribution metadata is often useful for runtime compatibility checks. +COPY --from=upstream /etc/os-release /etc/os-release + +# Copy only the app files that are needed at runtime. +COPY --from=upstream /app /app +``` + +This is the same shape used by examples such as [`node21-nextjs`](https://github.com/unikraft-cloud/examples/blob/main/node21-nextjs/Dockerfile), where the final image keeps only the Node binary, its required libraries, `/etc/os-release`, and the built app output. + +## Recommended deployment settings for the slim image + +After reducing the filesystem, deploy it with [`EROFS`](/tutorials/rootfs-formats) when possible. +This often gives better cold-boot behaviour and lower memory pressure than `CPIO` for larger images. + +```bash +kraft cloud deploy \ + -p 443: \ + -M 256Mi \ + --rootfs-type erofs \ + . +``` + +Treat the memory value as a starting point. +Tune it after the first successful deployment by looking at the actual boot behaviour and logs. + +## Bare minimum checklist + +Before calling the image minimized, check the following: + +* the `cmd` line uses the final executable path; +* copy only runtime files into the final stage; +* no package manager cache or compiler output remains; +* expose the instance port through `kraft cloud deploy -p`; +* use [`EROFS`](/tutorials/rootfs-formats) unless you have a reason to stay on `CPIO`. + +## More configurations + +### Environment variables + +If the upstream image depends on environment variables, you can optionally carry them over explicitly. +The most reliable method at deployment time is to pass them through the CLI with `--env` or `-e`. + +```bash +kraft cloud deploy \ + -p 443: \ + -M 256Mi \ + --rootfs-type erofs \ + -e APP_ENV=production \ + -e LOG_LEVEL=info \ + . +``` + +If the image expects a wrapper entrypoint that prepares environment variables before starting the main process, keep that wrapper in your `cmd` line or replace it with your own script. +The [Environment Variables](/tutorials/environment-variables) tutorial describes the wrapper pattern in more detail. + +:::note +Dockerfile `ENV` instructions carry over into the image, but you might want to set them explicitly at deployment time for better visibility and control. +::: + +### Users and permissions + +Container images often include a `USER` directive to avoid running as `root`. +On Unikraft Cloud, that directive only affects subsequent `RUN` steps while building the root filesystem. +It doesn't automatically change the user that runs `ENTRYPOINT` or `CMD` at instance boot. + +In practice, this means the deployed process runs as `root` unless you switch users explicitly inside your startup command or wrapper script. + +When slimming the image, check permission-sensitive paths such as: + +* runtime directories under `/var` or `/run`; +* app state directories under `/app`, `/srv`, or `/data`; +* Unix sockets or process ID files created by the upstream entrypoint. + +If the original image relied on a specific unprivileged user, you may need to preserve passwd and group metadata files as well: + +```dockerfile +COPY --from=upstream /etc/passwd /etc/passwd +COPY --from=upstream /etc/group /etc/group +``` + +If the app still assumes a particular user context, add a small wrapper that prepares the filesystem and then starts the original process. + +### Scale to zero + +After the image boots correctly and the slimmed filesystem works, scale-to-zero is a good final validation step. +It tests whether the app can suspend cleanly and resume on the next request. + +The simplest way to test scale-to-zero is to deploy with an explicit scale-to-zero policy and a short cooldown: + +```bash +kraft cloud deploy \ + -p 443: \ + -M 256Mi \ + --rootfs-type erofs \ + --scale-to-zero on \ + --scale-to-zero-stateful \ + --scale-to-zero-cooldown 5s \ + . +``` + +After deployment, wait a few seconds and then list the instances: + +```bash +kraft cloud instance list +``` + +If everything is working, the instance should transition to `standby` when idle and wake up again on the next request. + +Apps with long initialization phases, background work, or long-lived connections may need extra adjustments before scale-to-zero behaves well. +In those cases, review the [Scale-to-Zero](/features/scale-to-zero) feature page and consider a longer cooldown, stateful mode, or temporarily disabling scale-to-zero from inside the app during startup. + +## Learn more + +* [Images](/platform/images) and how `Dockerfile`s, `Kraftfile`s, and runtimes fit together. +* [Rootfs Formats](/tutorials/rootfs-formats) for understanding the `CPIO` and `EROFS` tradeoffs. +* The [Kraftfile reference](https://unikraft.org/docs/cli/reference/kraftfile) for all supported top-level fields. +* The [Next.js guide](/guides/nextjs) as a concrete example of a multi-stage Docker build trimmed down for deployment. From 484a56ac9acf2c790c82c5b40cb1009b13bccde8 Mon Sep 17 00:00:00 2001 From: Dragos Gheorghioiu Date: Thu, 26 Mar 2026 16:24:40 +0200 Subject: [PATCH 075/131] feat(roms): Fixed Kraftfile example used for the two ROMs Signed-off-by: Dragos Gheorghioiu --- pages/features/roms.mdx | 85 ++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 57 deletions(-) diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index 2524e08d..5c5a6116 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -223,7 +223,7 @@ def function(): spec: v0.6 roms: - - ./fs +- ./fs ``` @@ -237,7 +237,7 @@ def function(): spec: v0.6 roms: - - ./fs +- ./fs ``` @@ -281,57 +281,7 @@ If packaging the ROMs as a cpio archives (that is, `--rootfs-type cpio`), or as ### Services -Create two services to expose your instances: - -```bash title="" -curl -X POST \ - -H "Authorization: Bearer ${UKC_TOKEN}" \ - -H "Content-Type: application/json" \ - "${UKC_METRO}/services" \ - -d "[ - { - 'name': 'test-http-python-rom1', - 'services': [ - { - 'port': 443, - 'destination_port': 8080, - 'handlers': ['tls', 'http'] - } - ], - 'domains': [ - { - 'name': 'test-http-python-rom1' - } - ] - }, - { - 'name': 'test-http-python-rom2', - 'services': [ - { - 'port': 443, - 'destination_port': 8080, - 'handlers': ['tls', 'http'] - } - ], - 'domains': [ - { - 'name': 'test-http-python-rom2' - } - ] - } - ]" -``` - -Check that the services are up: - -```bash title="" -kraft cloud service get test-http-python-rom1 -kraft cloud service get test-http-python-rom2 -``` - -### Instances - -Create two instances from the same base image and attach different ROMs: +Create two instances with the same base image and attach different ROMs: ```bash title="" curl -X POST \ @@ -343,7 +293,18 @@ curl -X POST \ 'name': 'test-http-python-rom1', 'image': '${UKC_USER}/http-python:latest', 'service_group': { - 'name': 'test-http-python-rom1' + 'services': [ + { + 'port': 443, + 'destination_port': 8080, + 'handlers': ['tls', 'http'] + } + ], + 'domains': [ + { + 'name': 'test-http-python-rom1' + } + ] }, 'memory_mb': 512, 'scale_to_zero': { @@ -363,7 +324,18 @@ curl -X POST \ 'name': 'test-http-python-rom2', 'image': '${UKC_USER}/http-python:latest', 'service_group': { - 'name': 'test-http-python-rom2' + 'services': [ + { + 'port': 443, + 'destination_port': 8080, + 'handlers': ['tls', 'http'] + } + ], + 'domains': [ + { + 'name': 'test-http-python-rom2' + } + ] }, 'memory_mb': 512, 'scale_to_zero': { @@ -409,11 +381,10 @@ Hi from 2nd ROM! ### Cleanup -When done, remove the instances and services: +When done, remove the instances: ```bash title="" kraft cloud instance rm test-http-python-rom1 test-http-python-rom2 -kraft cloud service rm test-http-python-rom1 test-http-python-rom2 ``` ## Learn more From 0c25ec1c559850c3ec769b058d246950e2d1c127 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Mon, 30 Mar 2026 14:32:52 +0100 Subject: [PATCH 076/131] ci: Add pr preview placeholder Signed-off-by: Justin Chadwell --- .github/workflows/pr-preview.yaml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/pr-preview.yaml diff --git a/.github/workflows/pr-preview.yaml b/.github/workflows/pr-preview.yaml new file mode 100644 index 00000000..b9d087ab --- /dev/null +++ b/.github/workflows/pr-preview.yaml @@ -0,0 +1,23 @@ +name: pr/preview + +on: + pull_request: + types: + - opened + - synchronize + - reopened + - closed + branches: + - prod-staging + +permissions: + deployments: write + contents: read + pull-requests: write + +jobs: + noop: + runs-on: ubuntu-latest + steps: + - run: | + echo "pr/preview placeholder" From 234ce6e17f365579dc6c756436a9680c960396cc Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Mon, 30 Mar 2026 11:21:17 +0100 Subject: [PATCH 077/131] docs: Add CLI tabs for new unikraft CLI This commit adds support for both the new `unikraft` CLI and the legacy `kraft` CLI throughout the documentation using CodeTabs. Changes: - Migrated all guide pages to use CodeTabs component - Updated feature pages with dual CLI support - Converted tutorial pages (including docker-to-ukc) - Updated platform and use-case pages - Introduction page shows only the new unikraft CLI - Made all CLI references CLI-agnostic where appropriate Exempted pages (as per PR #97) remain legacy-only and are not updated in this commit. Signed-off-by: Justin Chadwell Co-authored-by: Dragos Gheorghioiu --- pages/cli/registries.mdx | 212 +++++++++++---------- pages/faq.mdx | 6 +- pages/features/autoscale.mdx | 68 +++++-- pages/features/load-balancing.mdx | 53 +++++- pages/features/roms.mdx | 102 +++++----- pages/features/scale-to-zero.mdx | 52 ++++- pages/features/snapshots.mdx | 46 +++-- pages/guides/bun.mdx | 89 ++++++--- pages/guides/caddy.mdx | 92 ++++++--- pages/guides/cpp-boost.mdx | 61 +++++- pages/guides/cpp.mdx | 60 +++++- pages/guides/django.mdx | 71 ++++++- pages/guides/dotnet.mdx | 60 +++++- pages/guides/dragonfly.mdx | 60 +++++- pages/guides/duckdb.mdx | 64 ++++++- pages/guides/elixir.mdx | 60 +++++- pages/guides/erlang.mdx | 60 +++++- pages/guides/ferretdb.mdx | 104 ++++++++-- pages/guides/flask-sqlite.mdx | 60 +++++- pages/guides/flask.mdx | 60 +++++- pages/guides/go.mdx | 60 +++++- pages/guides/grafana.mdx | 60 +++++- pages/guides/haproxy.mdx | 60 +++++- pages/guides/hugo.mdx | 60 +++++- pages/guides/imaginary.mdx | 64 +++++-- pages/guides/java.mdx | 60 +++++- pages/guides/llama2.mdx | 60 +++++- pages/guides/lua.mdx | 60 +++++- pages/guides/mariadb.mdx | 71 +++++-- pages/guides/memcached.mdx | 68 ++++++- pages/guides/minio.mdx | 60 +++++- pages/guides/mongodb.mdx | 68 ++++++- pages/guides/nextjs.mdx | 71 ++++++- pages/guides/nginx.mdx | 62 +++++- pages/guides/node.mdx | 60 +++++- pages/guides/opentelemetry-collector.mdx | 62 +++++- pages/guides/perl.mdx | 60 +++++- pages/guides/php.mdx | 60 +++++- pages/guides/postgres.mdx | 88 +++++++-- pages/guides/prisma.mdx | 62 +++++- pages/guides/puppeteer.mdx | 62 +++++- pages/guides/python.mdx | 71 ++++++- pages/guides/rails.mdx | 60 +++++- pages/guides/redis.mdx | 68 ++++++- pages/guides/remix.mdx | 60 +++++- pages/guides/ruby.mdx | 60 +++++- pages/guides/rust-actix.mdx | 60 +++++- pages/guides/rust-rocket.mdx | 60 +++++- pages/guides/rust-tokio.mdx | 60 +++++- pages/guides/skipper.mdx | 62 +++++- pages/guides/solidjs.mdx | 60 +++++- pages/guides/spin.mdx | 60 +++++- pages/guides/springboot.mdx | 52 ++++- pages/guides/sveltekit.mdx | 60 +++++- pages/guides/traefik.mdx | 62 +++++- pages/guides/tyk.mdx | 50 ++++- pages/guides/wazero.mdx | 62 +++++- pages/guides/wordpress.mdx | 64 +++++-- pages/integrations/kubernetes.mdx | 46 ++++- pages/introduction.mdx | 132 +++++-------- pages/platform/certificates.mdx | 52 ++++- pages/platform/domains.mdx | 49 ++++- pages/platform/images.mdx | 80 ++++++-- pages/platform/metros.mdx | 40 +++- pages/platform/services.mdx | 77 ++++++-- pages/platform/troubleshooting.mdx | 118 +++++++++--- pages/platform/volumes.mdx | 116 +++++++++-- pages/tutorials/docker-to-ukc.mdx | 81 +++++++- pages/tutorials/environment-variables.mdx | 20 +- pages/tutorials/instance-metrics.mdx | 19 +- pages/tutorials/network-communication.mdx | 4 +- pages/tutorials/rootfs-compression.mdx | 22 ++- pages/tutorials/rootfs-formats.mdx | 16 +- pages/tutorials/rootfs-volumes-roms.mdx | 35 +++- pages/tutorials/scale-to-zero-triggers.mdx | 9 +- pages/use-cases/api-gateways.mdx | 35 +++- pages/use-cases/headless-browsers.mdx | 62 +++++- pages/use-cases/mcp-servers.mdx | 12 +- pages/use-cases/remote-ides.mdx | 54 +++++- pages/use-cases/serverless-databases.mdx | 78 ++++++-- pages/use-cases/webhooks.mdx | 12 +- 81 files changed, 4003 insertions(+), 975 deletions(-) diff --git a/pages/cli/registries.mdx b/pages/cli/registries.mdx index aa929603..cfc057fd 100644 --- a/pages/cli/registries.mdx +++ b/pages/cli/registries.mdx @@ -44,71 +44,75 @@ You can also refer to images by digest to pin to an exact version. ## Authentication Registry authentication uses the same API token as the rest of the platform. -Set `UKC_TOKEN` before running any `kraft` command: +The new CLI uses profiles, while the legacy CLI reads `UKC_TOKEN` directly. -```bash title="" -export UKC_TOKEN= -``` + -`kraft` reads this token automatically and uses it for both the platform API and registry operations. -You will also need to use the `kraft login` command for `kraft pkg` operations: + ```bash title="unikraft" + unikraft login + ``` - - - ```bash title="" - kraft login -u "$UKC_USER" -t "$UKC_TOKEN" index.unikraft.io - ``` - - - ```bash title="" - kraft login -u "$UKC_USER" -t "$UKC_TOKEN" index..unikraft.cloud - ``` - - + ```bash title="kraft" + export UKC_TOKEN= + ``` + + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only used by the legacy CLI. + +You will also need to use the legacy CLI login command for `kraft pkg` operations: + + + + ```bash title="central registry" + kraft login -u "$UKC_USER" -t "$UKC_TOKEN" index.unikraft.io + ``` + + ```bash title="local registry" + kraft login -u "$UKC_USER" -t "$UKC_TOKEN" index..unikraft.cloud + ``` + + ## Pushing images -### Via `kraft cloud deploy` (recommended) +### Via the CLI (recommended) -The simplest way to push an image is `kraft cloud deploy`, which builds, packages, pushes, and starts an instance in one command: +The simplest way to push an image is to use the CLI to build, package, push, and start an instance in one flow: - - - ```bash title="" - kraft cloud deploy -p 443:8080 -M 256 --name . - ``` - - - ```bash title="" - kraft cloud deploy -p 443:8080 -M 256 --name --image index..unikraft.cloud// . - ``` - - + + ```bash title="central registry" + unikraft build . --output index.unikraft.io//:latest + unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --name index.unikraft.io//:latest + ``` + ```bash title="local registry" + unikraft build . --output index..unikraft.cloud//:latest + unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --name index..unikraft.cloud//:latest + ``` + During deployment you will see output confirming the push: - - - ```ansi title="" - [+] packaging index.unikraft.io/alice/my-app:latest... done! - [+] pushing index.unikraft.io/alice/my-app:latest (kraftcloud/x86_64)... done! - ``` - - - ```ansi title="" - [+] packaging index..unikraft.cloud/alice/my-app:latest... done! - [+] pushing index..unikraft.cloud/alice/my-app:latest (kraftcloud/x86_64)... done! - ``` - - + + + ```ansi title="central registry" + [+] packaging index.unikraft.io/alice/my-app:latest... done! + [+] pushing index.unikraft.io/alice/my-app:latest (kraftcloud/x86_64)... done! + ``` + + ```ansi title="local registry" + [+] packaging index..unikraft.cloud/alice/my-app:latest... done! + [+] pushing index..unikraft.cloud/alice/my-app:latest (kraftcloud/x86_64)... done! + ``` + ### Via `kraft pkg --push` -For more control, for example when packaging [ROMs](/features/roms) or base images, use `kraft pkg` with the `--push` flag: +For more control, for example when packaging [ROMs](/features/roms) or base images, use the legacy CLI with the `--push` flag: - - - ```bash title="" + + + ```bash title="central registry" kraft pkg \ --plat kraftcloud \ --arch x86_64 \ @@ -116,9 +120,8 @@ For more control, for example when packaging [ROMs](/features/roms) or base imag --push \ . ``` - - - ```bash title="" + + ```bash title="local registry" kraft pkg \ --plat kraftcloud \ --arch x86_64 \ @@ -126,51 +129,57 @@ For more control, for example when packaging [ROMs](/features/roms) or base imag --push \ . ``` - - + + ## Listing images -```bash title="" -kraft cloud image ls -``` + - - - ```text title="" - NAME VERSION SIZE - alice/http-python312 latest 77 MB - alice/my-app latest 42 MB - ``` - - - ```text title="" - NAME VERSION SIZE - alice/http-python312 latest 77 MB - index..unikraft.cloud/alice/my-app latest 42 MB - ``` - - + ```bash title="unikraft" + unikraft images list + ``` + + ```bash title="kraft" + kraft cloud image ls + ``` + + + + + + ```text title="central registry" + NAME VERSION SIZE + alice/http-python312 latest 77 MB + alice/my-app latest 42 MB + ``` + + ```text title="local registry" + NAME VERSION SIZE + alice/http-python312 latest 77 MB + index..unikraft.cloud/alice/my-app latest 42 MB + ``` + + :::note -There may be a delay of a few minutes between pushing or removing an image and `kraft cloud image ls` reflecting the change. +There may be a delay of a few minutes between pushing or removing an image and the image list reflecting the change. ::: ## Removing images - - - ```bash title="" - kraft cloud img rm my-app - ``` - - - ```bash title="" - # Not supported yet for direct pushing to node registries. - # Remove images from the node itself periodically. - ``` - - + + + ```bash title="unikraft" + # Not supported yet for direct pushing to node registries. + # Remove images from the node itself periodically. + ``` + + ```bash title="kraft" + kraft cloud img rm my-app + ``` + + ## Kernel layer deduplication @@ -181,39 +190,38 @@ This makes iterative pushes faster and cheaper on bandwidth. [ROMs](/features/roms) follow the same packaging system but go out without a kernel layer. They only have a rootfs. -They appear in `kraft cloud image ls` alongside regular images. +They appear in the image list alongside regular images. ## Image addresses in instance creation When creating an instance directly from an existing image, reference it by tag or digest: - - - ```bash title="" + + + ```bash title="central registry" # By tag - kraft cloud instance create --port 443:8080 --start -M 256 \ + unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB \ index.unikraft.io/alice/my-app:latest # By digest (exact version pinning) - kraft cloud instance create --port 443:8080 --start -M 256 \ + unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB \ index.unikraft.io/alice/my-app@sha256:278cb8b1... ``` - - - ```bash title="" + + ```bash title="local registry" # By tag - kraft cloud instance create --port 443:8080 --start -M 256 \ + unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB \ index..unikraft.cloud/alice/my-app:latest # By digest (exact version pinning) - kraft cloud instance create --port 443:8080 --start -M 256 \ + unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB \ index..unikraft.cloud/alice/my-app@sha256:278cb8b1... ``` - - + + ## Learn more * [Images](/platform/images): build, package, and deploy workflow -* The `kraft cloud` [CLI reference](/cli/) +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview) * Unikraft Cloud's [REST API reference](/api/platform/v1) diff --git a/pages/faq.mdx b/pages/faq.mdx index e79e0b25..7cd44d45 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -136,7 +136,7 @@ Unikraft can provide cost savings in many ways: #### What's the relationship between the Unikraft open source project and Unikraft Cloud? Unikraft OSS allows you to build and run unikernels locally via `kraft run` (and even hack the Unikraft OS itself if you like tinkering!). -When you're ready to deploy, switch to `kraft cloud deploy`. +When you're ready to deploy, use the `unikraft` CLI (or the legacy `kraft cloud` CLI). #### Are you a replacement for Docker? @@ -170,8 +170,8 @@ Contact information is available for more details. #### Can you try Unikraft open source first? Yes. -Head on over to [unikraft.org](https://unikraft.org/docs/cli/install), install the `kraft` tool with the one-liner there, and use `kraft run` to build, package and run your app locally. -When you're ready to deploy to cloud, set your Unikraft Cloud token and deploy via `kraft cloud deploy`. +Head on over to [unikraft.org](https://unikraft.org/docs/cli/install) to install the legacy `kraft` tool, and use `kraft run` to build, package and run your app locally. +When you're ready to deploy to cloud, use the `unikraft` CLI profiles or the legacy `kraft cloud` CLI. #### Does Unikraft Cloud work on Mac/Windows/Linux? diff --git a/pages/features/autoscale.mdx b/pages/features/autoscale.mdx index 0bf6e56a..61e7c886 100644 --- a/pages/features/autoscale.mdx +++ b/pages/features/autoscale.mdx @@ -34,14 +34,24 @@ Autoscale, as well as load balancing in general, currently supports only Interne ## Setting up autoscale -First, use the `kraft cloud deploy` command to create an instance, in this example using NGINX: +First, create an instance, in this example using NGINX: -```bash title="" + + +```bash title="unikraft" +git clone https://github.com/unikraft-cloud/examples +cd examples/nginx/ +unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB nginx:latest +``` + +```bash title="kraft" git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ kraft cloud deploy -p 443:8080 -M 256 . ``` + + ```ansi title="" [●] Deployed successfully! β”‚ @@ -58,7 +68,7 @@ kraft cloud deploy -p 443:8080 -M 256 . β””────────── args: /usr/bin/nginx -c /etc/nginx/nginx.conf ``` -This single `kraft cloud deploy` command does 3 things: +This single deploy or run flow does 3 things: 1. Creates an instance of NGINX which will serve as the **autoscale master** instance. 1. Creates a service via the `-p` flag (named `small-leaf-rafirkw7`). @@ -66,9 +76,11 @@ This single `kraft cloud deploy` command does 3 things: All that's left to do now to set up autoscale is to set an autoscale configuration *policy* and to set the instance as master. Unikraft Cloud then takes care of cloning this master instance whenever load increases. -To achieve this, use the `kraft cloud scale` command: +To achieve this, use the legacy CLI scale command: -```bash title="" + + +```bash title="kraft" kraft cloud scale init small-leaf-rafirkw7 \ --master nginx-4d7u3 \ --min-size 1 \ @@ -90,6 +102,8 @@ kraft cloud scale add small-leaf-rafirkw7 \ --step :50/-50 ``` + + Note the following: * The first command sets the master to the created instance, and configures it to scale up to a maximum of 8 instances and a minimum of 1; the command also sets the warm up and cool down time to 1 second each, so it doesn't constantly fluctuate up and down. @@ -99,7 +113,7 @@ Note the following: :::note -The intervals that autoscale uses for making scale-out and scale-in decisions use the `--warmup-time` and `--cooldown-time` parameters of `kraft cloud scale init`, in units of milliseconds. +The intervals that autoscale uses for making scale-out and scale-in decisions use the `--warmup-time` and `--cooldown-time` parameters of the scale init command, in units of milliseconds. Refer to the API autoscale [reference](/api/platform/v1/autoscale) for more details. ::: @@ -114,12 +128,16 @@ You can find the documentation [here](/api/platform/v1/autoscale) at the bottom ## Testing it -To check it's working, you can use the `kraft cloud scale get` command to list the autoscale properties of the service: +To check it's working, you can use the legacy CLI scale get command to list the autoscale properties of the service: -```bash title="" + + +```bash title="kraft" kraft cloud scale get small-leaf-rafirkw7 ``` + + You should see output like: ```ansi title="" @@ -134,12 +152,16 @@ You should see output like: policies: scale-out-policy;scale-in-policy ``` -To list an individual policy, you can further use the `kraft cloud scale get` command as follows: +To list an individual policy, use the legacy CLI scale get command as follows: -```bash title="" + + +```bash title="kraft" kraft cloud scale get --policy scale-out-policy small-leaf-rafirkw7 ``` + + You should see output like: ```ansi title="" @@ -158,12 +180,20 @@ type: step ``` You can further check that the master instance is on `standby` (scaled to zero), assuming your service hasn't received any traffic yet. -You can get the UUID of your master instance from the `kraft cloud scale get` command above. +You can get the UUID of your master instance from the legacy CLI scale get command above. -```bash title="" + + +```bash title="unikraft" +unikraft instances get f840ac12-f485-4f02-9f33-6a0a7de46f1f -o list +``` + +```bash title="kraft" kraft cloud instance get f840ac12-f485-4f02-9f33-6a0a7de46f1f -o list ``` + + You should see output like: ```ansi title="" @@ -190,12 +220,20 @@ curl https://small-leaf-rafirkw7.fra.unikraft.app ``` You should get an immediate response, even though the instance was on `standby`. -You can use the `watch` tool to see if you catch the instance changing state from `standby` to `running`: +You can use a watch command to see if you catch the instance changing state from `standby` to `running`: -```ansi title="" + + +```bash title="unikraft" +unikraft instances list --watch +``` + +```bash title="kraft" watch --color -n 0.5 kraft cloud instance list ``` + + ## Policy types Four autoscale policy types are available. @@ -298,5 +336,5 @@ The `idle` policy scales in (removes instances) when the service has been idle ## Learn more -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [scale](/cli/scale) subcommand. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the section on [autoscale](/api/platform/v1/autoscale). diff --git a/pages/features/load-balancing.mdx b/pages/features/load-balancing.mdx index e9f29e5f..6e5a7063 100644 --- a/pages/features/load-balancing.mdx +++ b/pages/features/load-balancing.mdx @@ -32,15 +32,25 @@ In case there are no other instances available, the load balancer blocks excess ## Setup -To set load balancing up, first use `kraft cloud deploy` with the `-p` flag to create the service as part of the instance creation. +To set load balancing up, first use the deploy or run flow with the publish flag to create the service as part of the instance creation. For example, use NGINX as the app: -```bash title="" + + +```bash title="unikraft" +git clone https://github.com/unikraft-cloud/examples +cd examples/nginx/ +unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB nginx:latest +``` + +```bash title="kraft" git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ kraft cloud deploy -p 443:8080 -M 256 . ``` + + This single command will (a) create a service via the `-p` flag and (b) start an NGINX instance: ```ansi title="" @@ -61,11 +71,20 @@ This single command will (a) create a service via the `-p` flag and (b) start an With this in place, it's now time to start a second instance and attach it to the created service (in this case, named `wandering-shape-n6mhimgn`): -```bash title="" + + +```bash title="unikraft" +cd examples/nginx/ +unikraft run --metro=fra --service wandering-shape-n6mhimgn -m 256MiB nginx:latest +``` + +```bash title="kraft" cd examples/nginx/ kraft cloud deploy --service wandering-shape-n6mhimgn -M 256 . ``` + + :::tip If a prompt appears saying "deployment already exists: what would you like to do with the 1 existing instances," choose `keep`. ::: @@ -91,10 +110,18 @@ The command's output should look like this: Both the `url` and `service` fields in the 2 instances are the same. To check that it worked, run the following command: -```bash title="" + + +```bash title="unikraft" +unikraft services list +``` + +```bash title="kraft" kraft cloud service list -o list ``` + + You should see output such as: ```ansi title="" @@ -111,13 +138,21 @@ Note the two instances (their UUIDs) under the `instances` field. You're now load balancing across 2 NGINX instances! :::tip -Currently it's impossible to set the service's name via `kraft cloud deploy`. -If you'd like to set the service's name, first use the `kraft cloud service` command to create the service. -You can use the `--service` flag of `kraft cloud deploy` to attach the instance to the service, as outlined in this [guide](/platform/services). +Currently it's impossible to set the service's name via the deploy or run flow. +If you'd like to set the service's name, first use the CLI to create the service. +You can use the `--service` flag to attach the instance to the service, as outlined in this [guide](/platform/services). ::: :::tip -To ensure that stopping an instance doesn't drop existing connections, use Unikraft Cloud's draining feature by stopping an instance through `kraft cloud instance stop -w ` +To ensure that stopping an instance doesn't drop existing connections, use Unikraft Cloud's draining feature by stopping an instance with a drain timeout. + + + +```bash title="kraft" +kraft cloud instance stop -w +``` + + ::: ## Load balancing algorithm @@ -144,5 +179,5 @@ This is because `i-3` now becomes the only instance with only 1 connection (assu ## Learn more -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the services subcommand. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the section on services. diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index 5c5a6116..a180584d 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -3,11 +3,9 @@ title: ROMs navigation_icon: hard-drive --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -:::caution +:::caution[**DISCLAIMER**] The ROM feature isn't currently enabled for the public Unikraft Cloud offering. -As such, the [KraftKit CLI tool](/cli/) can't entirely leverage this feature. +As such, the legacy [KraftKit CLI tool](/docs/cli/kraft/overview) can't entirely leverage this feature. For boxes where it's enabled, use it via the [Unikraft Cloud API](/api/platform/v1). ::: @@ -51,14 +49,8 @@ export UKC_METRO="fra" # or your preferred metro First, create a base image with a Python HTTP server that loads and executes custom Python programs from a ROM. - - - Dockerfile - Kraftfile - server.py - wrapper.sh - - + + ```dockerfile title="Dockerfile" FROM python:3.12 AS build @@ -96,8 +88,6 @@ COPY --from=build /usr/local/lib /usr/local/lib COPY ./wrapper.sh /wrapper.sh COPY ./server.py /src/server.py ``` - - ```yaml title="Kraftfile" spec: v0.6 @@ -107,8 +97,7 @@ rootfs: ./Dockerfile cmd: [ "/wrapper.sh", "/usr/bin/python3", "/src/server.py" ] ``` - - + ```python title="server.py" import argparse import importlib.util @@ -159,8 +148,7 @@ def parse_args(): if __name__ == "__main__": main(parse_args()) ``` - - + ```bash title="wrapper.sh" #!/usr/bin/sh @@ -168,8 +156,7 @@ if __name__ == "__main__": /usr/bin/mount -t erofs /dev/ukp_rom_python_function.py /tmp/ exec "$@" ``` - - + Ensure that the `wrapper.sh` script is executable: @@ -190,10 +177,18 @@ kraft pkg \ Wait a few seconds for propagation and check that the image is present: -```bash title="" + + +```bash title="unikraft" +unikraft images list +``` + +```bash title="kraft" kraft cloud image ls ``` + + {/* vale off */} ### ROM files {/* vale on */} @@ -205,42 +200,32 @@ Create a separate directory for each of the ROMs: mkdir -p rom1/fs rom2/fs ``` - - - rom 1 - Kraftfile 1 - rom 2 - Kraftfile 2 - - + + ```python title="rom1/fs/rom.py" def function(): return "Hi from 1st ROM!\n" ``` - - + ```yaml title="rom1/Kraftfile" spec: v0.6 roms: -- ./fs + - ./fs ``` - - + ```python title="rom2/fs/rom.py" def function(): return "Hi from 2nd ROM!\n" ``` - - + ```yaml title="rom2/Kraftfile" spec: v0.6 roms: -- ./fs + - ./fs ``` - - + Package and push the ROMs: @@ -266,10 +251,18 @@ kraft pkg \ Wait a few seconds for propagation and check that the ROMs are present: -```bash title="" + + +```bash title="unikraft" +unikraft images list +``` + +```bash title="kraft" kraft cloud image ls ``` + + :::tip The `--no-kernel` flag tells `kraft` to package only the ROM files, without the kernel, since this is data that will get attached to another image. ::: @@ -279,7 +272,7 @@ This example packages the ROMs as EROFS filesystems. If packaging the ROMs as a cpio archives (that is, `--rootfs-type cpio`), or as standalone files, you must align their size to 4096 bytes. ::: -### Services +### Instances Create two instances with the same base image and attach different ROMs: @@ -356,10 +349,19 @@ curl -X POST \ Check that the instances are up: -```bash title="" -kraft cloud instance get test-http-python-rom1 -kraft cloud instance get test-http-python-rom2 -``` + + + ```bash title="unikraft" + unikraft instances get test-http-python-rom1 + unikraft instances get test-http-python-rom2 + ``` + + ```bash title="kraft" + kraft cloud instance get test-http-python-rom1 + kraft cloud instance get test-http-python-rom2 + ``` + + Note the `roms` array in the instances configurations. Each ROM is available as a readable device at `/dev/ukp_rom_python_function.py` (in the form of an EROFS filesystem in this case), which the server program mounts at `/tmp/rom.py` and executes. @@ -383,10 +385,18 @@ Hi from 2nd ROM! When done, remove the instances: -```bash title="" + + +```bash title="unikraft" +unikraft instances delete test-http-python-rom1 test-http-python-rom2 +``` + +```bash title="kraft" kraft cloud instance rm test-http-python-rom1 test-http-python-rom2 ``` + + ## Learn more * The `kraft cloud` [command-line tool reference](/cli/), and in particular the [instance create](/cli/instance/create) subcommand. diff --git a/pages/features/scale-to-zero.mdx b/pages/features/scale-to-zero.mdx index 2f08d041..1884b547 100644 --- a/pages/features/scale-to-zero.mdx +++ b/pages/features/scale-to-zero.mdx @@ -185,7 +185,7 @@ This feature is currently under active development and may change in future rele Currently, internal traffic via Private FQDNs doesn't trigger the scale-to-zero wake-up mechanism. Services attempting to reach a standby instance via its Private FQDN will fail to wake it. To ensure wake-on-request behavior for creating service-to-service communication, use the instance's **Public FQDN**. -Note that this also applies to [`kraft cloud tunnel`](/cli/tunnel), which relies on internal connectivity. +Note that this also applies to the legacy CLI tunnel command, which relies on internal connectivity. ## Getting started @@ -211,12 +211,23 @@ You can disable scale-to-zero either by setting the label to `false`, or with th Since Unikraft Cloud has scale-to-zero on by default, all you need to do is to start an instance normally: -```bash title="" + + +```bash title="unikraft" +git clone https://github.com/unikraft-cloud/examples +cd examples/nginx/ +unikraft build . --output my-org/nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/nginx:latest +``` + +```bash title="kraft" git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ kraft cloud deploy -p 443:8080 -M 256 . ``` + + This command will create the NGINX instance with scale-to-zero enabled: ```ansi title="" @@ -235,13 +246,21 @@ This command will create the NGINX instance with scale-to-zero enabled: β””────────── args: /usr/bin/nginx -c /etc/nginx/nginx.conf ``` -Note that at first the system lists the status as `running` in the output of the `kraft cloud deploy` command. +Note that at first the system lists the status as `running` in the output of the deploy or run flow. Check the instance's status: -```bash title="" + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instances list ``` + + You should see output like: ```ansi title="" @@ -250,14 +269,19 @@ nginx-1a747 twilight-gorilla-ui5b6kwt.fra.unikraft.app standby ``` Notice the state is now set to `standby`? -At first `kraft cloud deploy` sets the state to `running`, but then Unikraft Cloud puts the instance immediately to sleep (more accurately, it stops it, but it keeps state to start it again when needed). +At first the deploy or run flow sets the state to `running`. +Unikraft Cloud then puts the instance to sleep (it stops it, but keeps state to start it again when needed). -You can also check that scale-to-zero gets enabled through the `kraft cloud scale` command: +You can also check that scale-to-zero gets enabled through the legacy CLI scale command: -```bash title="" + + +```bash title="kraft" kraft cloud scale get twilight-gorilla-ui5b6kw ``` + + which outputs: ```ansi title="" @@ -284,12 +308,20 @@ curl https://twilight-gorilla-ui5b6kwt.fra.unikraft.app ``` You should get an NGINX response with no noticeable delay. -For fun, try to use the following command to see if you can catch the instance's `STATE` field changing from `standby` to `running` +For fun, try to use the following command to see if you can catch the instance's `STATE` field changing from `standby` to `running`: -```bash title="" + + +```bash title="unikraft" +unikraft instances list --watch +``` + +```bash title="kraft" watch --color -n 0.5 kraft cloud instance list ``` + + If you `curl` enough, you should see the `STATE` turn to a green `running` from time to time: @@ -308,7 +340,7 @@ For more on autoscale please see the autoscale [guide](/features/autoscale). ## Learn more -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) and [instance create](/cli/instance/create) subcommands. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the [scale-to-zero schema](/api/platform/v1/~schemas#instance-scale-to-zero). diff --git a/pages/features/snapshots.mdx b/pages/features/snapshots.mdx index 627aedd8..37982db7 100644 --- a/pages/features/snapshots.mdx +++ b/pages/features/snapshots.mdx @@ -11,13 +11,16 @@ You can reduce this initialization time by taking a snapshot of the app memory a ## Setting it up -The quickest way to set this up is via the `--scale-to-zero-stateful` flag of -the `kraft cloud deploy` or `kraft cloud instance create` commands, for example: +The quickest way to set this up is via the legacy CLI `--scale-to-zero-stateful` flag: -```bash title="" + + +```bash title="kraft" kraft cloud deploy --metro fra --scale-to-zero-stateful . ``` + + As an alternative, you can add a `label` to your example's `Kraftfile` as follows: ```yaml title="" @@ -27,28 +30,39 @@ labels: You can see an example of such a `Kraftfile` and label in the [Spring Boot example](/guides/springboot). -Once deployed, you can check whether this mechanism works for your app via the `kraft cloud instance get ` command: +Once deployed, you can check whether this mechanism works for your app via the CLI: + + + +```bash title="unikraft" +unikraft instances get +``` + +```bash title="kraft" +kraft cloud instance get +``` + + -```ansi title="" +```ansi stateful: enabled ``` ## How it works -When you enable stateful mode and first deploy your app, Unikraft Cloud brings it up -normally and lets it fully initialize (which may be fast, or take seconds or -minutes, depending on your app's init time). Unikraft Cloud waits until the app's exposed port -becomes available, and then starts the scale-to-zero process (assuming no traffic is coming -to that port). At this point, Unikraft Cloud saves the state of your app, and sets the -app to standby (consuming no resources). +When you enable stateful mode and first deploy your app, Unikraft Cloud brings it up normally and lets it fully initialize. +This may be fast or take seconds or minutes, depending on your app's init time. +Unikraft Cloud waits until the app's exposed port becomes available, and then starts the scale-to-zero process. +This assumes no traffic is coming to that port. +At this point, Unikraft Cloud saves the state of your app and sets the app to standby (consuming no resources). -Next, when traffic arrives, Unikraft Cloud brings up the app including its saved state, -ensuring statefulness across different scale-to-zero and scale-to-one cycles, -but also eliminating any long initialization times from heavyweight apps. +Next, when traffic arrives, Unikraft Cloud brings up the app including its saved state. +This ensures statefulness across scale-to-zero and scale-to-one cycles. +It also eliminates long initialization times from heavyweight apps. -## Learn More +## Learn more -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the `deploy` and `instance` subcommands. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the [scale-to-zero schema](/api/platform/v1/~schemas#instance-scale-to-zero). diff --git a/pages/guides/bun.mdx b/pages/guides/bun.mdx index 085df88c..2471a54b 100644 --- a/pages/guides/bun.mdx +++ b/pages/guides/bun.mdx @@ -2,12 +2,11 @@ title: "Bun" --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - This guide explains how to create and deploy a Bun app. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/bun` directory: @@ -16,22 +15,41 @@ git clone https://github.com/kraftcloud/examples cd examples/bun/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy the app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/bun:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 512MiB my-org/bun:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,10 +82,18 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME bun-700mp quiet-pond-ao44imcg.fra.unikraft.app running since 3mins bun@sha256:dfcbee1efe0d8a1d43ab... 512 MiB /usr/bin/bun run /usr/src/server.ts 289.03 ms @@ -75,10 +101,18 @@ bun-700mp quiet-pond-ao44imcg.fra.unikraft.app running since 3mins bun@sha25 When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete bun-700mp +``` + +```bash title="kraft" kraft cloud instance remove bun-700mp ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -87,14 +121,8 @@ To customize the app, update the files in the repository, listed below: * `Dockerfile`: the Docker-specified app filesystem * `server.ts`: the Bun server implementation - - - Kratfile - Dockerfile - server.ts - - - ```yaml + +```yaml title="Kraftfile" spec: v0.6 name: bun @@ -104,10 +132,9 @@ runtime: base-compat:latest rootfs: ./Dockerfile cmd: ["/usr/bin/bun," "run," "/usr/src/server.ts"] - ``` - - - ```dockerfile +``` + +```dockerfile title="Dockerfile" FROM oven/bun:1 AS bun RUN set -xe; \ @@ -147,9 +174,8 @@ COPY --from=sys /blank /tmp COPY ./server.ts /usr/src/server.ts ``` - - - ```dockerfile + +```js title="server.js" const port = process.env.PORT || 3000; console.log( @@ -162,9 +188,8 @@ Bun.serve({ return new Response("Hello, World!\n"); }, }); - ``` - - +``` + Lines in the `Kraftfile` have the following roles: @@ -199,8 +224,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/caddy.mdx b/pages/guides/caddy.mdx index 6f6235df..54092061 100644 --- a/pages/guides/caddy.mdx +++ b/pages/guides/caddy.mdx @@ -2,14 +2,13 @@ title: Caddy --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - This example uses [`Caddy`](https://caddyserver.com/), one of the most popular web servers. Caddy can be used with Unikraft / Unikraft Cloud to serve static web content. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/caddy/` directory: @@ -18,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/caddy/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/caddy:latest +unikraft run --metro=fra -p 443:2015/http+tls -m 128MiB my-org/caddy:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:2015 . ``` + + The output shows the instance address and other details: ```ansi @@ -66,9 +84,17 @@ Hello World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME caddy-vhf4m frosty-sky-vz8kwsmb.fra.unikraft.app running 1 minute ago caddy@sha25:25df97e3c43147c683f... 128 MiB /usr/bin/caddy run --config /e... 20180us @@ -76,10 +102,18 @@ caddy-vhf4m frosty-sky-vz8kwsmb.fra.unikraft.app running When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete caddy-vhf4m +``` + +```bash title="kraft" kraft cloud instance remove caddy-vhf4m ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -88,23 +122,20 @@ To customize the app, update the files in the repository, listed below: * `rootfs/var/www/index.html`: the index page of the content served * `rootfs/etc/caddy/Caddyfile`: the Caddy configuration file - - - ```yaml - spec: v0.6 + +```yaml title="Kraftfile" +spec: v0.6 - runtime: caddy:latest +runtime: caddy:latest + +rootfs: ./rootfs +``` - rootfs: ./rootfs - ``` - - - ```html +```html title="rootfs/var/www/index.html" Hello, world! - ``` - - - ```text +``` + +```text title="rootfs/etc/caddy/Caddyfile" :2015 root * /var/www @@ -114,9 +145,8 @@ encode gzip templates file_server - ``` - - +``` + Update the contents of the `rootfs/var/www` directory to serve different static web content. For example, you could change the contents of `rootfs/var/www/index.html` to: @@ -144,8 +174,16 @@ You can set a new webroot (different than `rootfs`), or a different internal por Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/cpp-boost.mdx b/pages/guides/cpp-boost.mdx index c1ae33a4..cbd52c74 100644 --- a/pages/guides/cpp-boost.mdx +++ b/pages/guides/cpp-boost.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a C++-based HTTP web server using the [Boost](https://www.boost.org/) libraries. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 2. Clone the [example repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-cpp-boost/` directory: @@ -16,22 +17,40 @@ git clone https://github.com/kraftcloud/examples cd examples/http-cpp-boost/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` -x + + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-cpp-boost:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-cpp-boost:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +83,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-cpp-boost-rae7s red-snow-3bn7bzc8.fra.unikraft.app running 1 minute ago http-cpp-boost@sha256:61cf86b89fed46351af53689e27189315e... 128 MiB /http_server 15000us @@ -74,10 +101,18 @@ http-cpp-boost-rae7s red-snow-3bn7bzc8.fra.unikraft.app running 1 minute ago When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-cpp-boost-rae7s +``` + +```bash title="kraft" kraft cloud instance remove http-cpp-boost-rae7s ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -279,8 +314,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/cpp.mdx b/pages/guides/cpp.mdx index 022ca070..a15f19ac 100644 --- a/pages/guides/cpp.mdx +++ b/pages/guides/cpp.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple C++-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 2. Clone the [example repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-cpp/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-cpp/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-cpp:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-cpp:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-cpp-jzbuo throbbing-wave-grxjih4t.fra.unikraft.app running 1 minute ago http-cpp@sha256:a58873987104b52c13b79168a2e2f1a81876ba6efac... 128 MiB /http_server 15614us @@ -74,10 +102,18 @@ http-cpp-jzbuo throbbing-wave-grxjih4t.fra.unikraft.app running 1 minut When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-cpp-jzbuo +``` + +```bash title="kraft" kraft cloud instance remove http-cpp-jzbuo ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -240,8 +276,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/django.mdx b/pages/guides/django.mdx index 0275ce92..0f87dfa8 100644 --- a/pages/guides/django.mdx +++ b/pages/guides/django.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a Python Django web app. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-python3.12-django5.0/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-python3.12-django5.0/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-python312-django:latest +unikraft run --metro=fra -p 443:80/http+tls -m 512MiB my-org/http-python312-django:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:80 -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -87,9 +107,17 @@ For a production site, ensure you read the recommended deployment guides of the You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-python312-ma2i9 young-night-5fpf0jj8.fra.unikraft.app running 1 minute ago http-python312@sha256:278cb8b14f9faf9c27... 512 MiB /usr/bin/python /src/server.py 15094us @@ -98,10 +126,18 @@ http-python312-ma2i9 young-night-5fpf0jj8.fra.unikraft.app running 1 minute a When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-python312-django50-vt56c +``` + +```bash title="kraft" kraft cloud instance remove http-python312-django50-vt56c ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -197,10 +233,19 @@ The [`http-python3.12-flask3.0`](/docs/guides/flask-sqlite/) guide details the u Run the command below to deploy the app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-python312-django:latest +unikraft run --metro=fra -p 443:80/http+tls -m 512MiB my-org/http-python312-django:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:80 -M 512 . ``` + + Differences from the Django app are also the steps required to create an `pip`-based app: 1. Add the `requirements.txt` file used by `pip`. @@ -295,8 +340,16 @@ See also the [`http-python3.12-django5.0`](https://github.com/kraftcloud/example Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/dotnet.mdx b/pages/guides/dotnet.mdx index 613c2104..eba90baf 100644 --- a/pages/guides/dotnet.mdx +++ b/pages/guides/dotnet.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple .NET-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-dotnet8.0/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-dotnet8.0/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-dotnet80:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-dotnet80:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,10 +84,18 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-dotnet80-dsmkh cold-fog-hl98aw6q.fra.unikraft.app running 2 minutes ago http-dotnet80@sha256:4fad7453995ae... 512 MiB /usr/bin/app/src 328.69 ms @@ -75,10 +103,18 @@ http-dotnet80-dsmkh cold-fog-hl98aw6q.fra.unikraft.app running 2 minutes When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-dotnet80-dsmkh +``` + +```bash title="kraft" kraft cloud instance remove http-dotnet80-dsmkh ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -211,8 +247,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/dragonfly.mdx b/pages/guides/dragonfly.mdx index 41e3c78e..bf260c3e 100644 --- a/pages/guides/dragonfly.mdx +++ b/pages/guides/dragonfly.mdx @@ -8,7 +8,8 @@ This guides shows you how to deploy [Dragonfly](https://www.dragonflydb.io/), a To run it example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/dragonflydb/` directory: @@ -17,22 +18,41 @@ git clone https://github.com/kraftcloud/examples cd examples/dragonflydb/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/dragonflydb:latest +unikraft run --metro=fra -p 443:6379/tls -m 512MiB my-org/dragonflydb:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:6379 -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -88,9 +108,17 @@ document.querySelector('.left_panel').innerHTML = JsonToHTML(json_text1); You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME dragonflydb-10zgk dry-moon-x6bgl6c0.fra.unikraft.app running 1 minute ago dragonflydb@sha256:21e6d3... 512 MiB /usr/bin/dragonfly --maxmemor... 28740us @@ -98,10 +126,18 @@ dragonflydb-10zgk dry-moon-x6bgl6c0.fra.unikraft.app running 1 minute ago dr When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete dragonflydb-10zgk +``` + +```bash title="kraft" kraft cloud instance remove dragonflydb-10zgk ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -140,8 +176,16 @@ FROM scratch Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/duckdb.mdx b/pages/guides/duckdb.mdx index a3d75bc9..00c2e496 100644 --- a/pages/guides/duckdb.mdx +++ b/pages/guides/duckdb.mdx @@ -1,5 +1,5 @@ --- -title: DuckDB with a Go +title: DuckDB with a Go Server --- import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" @@ -8,7 +8,8 @@ This guide shows you how to use [DuckDB](https://duckdb.org), an in-process SQL To run it example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/duckdb-go/` directory: @@ -17,22 +18,41 @@ git clone https://github.com/kraftcloud/examples cd examples/duckdb-go/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash -kraft cloud deploy -p 443:8080 . + + +```bash title="unikraft" +unikraft build . --output my-org/duckdb-go:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 256 my-org/duckdb-go:latest +``` + +```bash title="kraft" +kraft cloud deploy -M 256 -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -65,9 +85,17 @@ id: %d, name: %s 42 John You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME duckdb-go-qfd8x autumn-gorilla-hg4h6sup.fra.unikraft.app running 1 minute ago duckdb-go... 128 MiB /server 32118us @@ -75,10 +103,18 @@ duckdb-go-qfd8x autumn-gorilla-hg4h6sup.fra.unikraft.app running 1 minute a When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete duckdb-go-qfd8x +``` + +```bash title="kraft" kraft cloud instance remove duckdb-go-qfd8x ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -174,8 +210,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/elixir.mdx b/pages/guides/elixir.mdx index 8450f7e3..747fac83 100644 --- a/pages/guides/elixir.mdx +++ b/pages/guides/elixir.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Elixir-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-elixir1.16/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-elixir1.16/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-elixir116:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 1024MiB my-org/http-elixir116:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 1024 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,10 +84,18 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME elixir-qo9k3 small-water-tl8lr8am.fra.unikraft.app running since 9mins sha256:67f5df0... 1.0 GiB /usr/bin/wrapper.sh /usr/local/bin/mix r... 437.43 ms @@ -75,10 +103,18 @@ elixir-qo9k3 small-water-tl8lr8am.fra.unikraft.app running since 9mins sha25 When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete elixir-qo9k3 +``` + +```bash title="kraft" kraft cloud instance remove elixir-qo9k3 ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -288,8 +324,16 @@ Then update it and deploy it on Unikraft Cloud using the above instructions. Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/erlang.mdx b/pages/guides/erlang.mdx index 3ed05c00..9813fc3e 100644 --- a/pages/guides/erlang.mdx +++ b/pages/guides/erlang.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Erlang-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-erlang26.2/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-erlang26.2/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-erlang:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-erlang:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,10 +84,18 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME erlang-sw2bp patient-field-ck629jsu.fra.unikraft.app running since 35secs erlang@sha256:d99feefa7973ba43f72... 512 MiB /usr/bin/wrapper.sh /usr/bin/erl -noshell -s http_se... 404.04 ms @@ -75,10 +103,18 @@ erlang-sw2bp patient-field-ck629jsu.fra.unikraft.app running since 35sec When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete erlang-sw2bp +``` + +```bash title="kraft" kraft cloud instance remove erlang-sw2bp ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -202,8 +238,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/ferretdb.mdx b/pages/guides/ferretdb.mdx index fe155440..a7227cc2 100644 --- a/pages/guides/ferretdb.mdx +++ b/pages/guides/ferretdb.mdx @@ -2,13 +2,12 @@ title: FerretDB --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - This guide shows you how to use [FerretDB](https://www.ferretdb.com/) an open source proxy that translates MongoDB wire protocol queries to SQL. To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples). @@ -18,33 +17,63 @@ To run it, follow these steps: This guide uses both the `postgres16.2/` example and the `ferretdb/` example. -Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + This guide deploys FerretDB as a frontend and PostgreSQL as a database server, running them together inside a [service](/platform/services). For that, follow these steps: 1. Run an instance of PostgreSQL using the `postgres16.2/` example: - ```bash + + + ```bash title="unikraft" + cd postgres16.2/ + unikraft build . --output my-org/postgres16-2:latest + unikraft run --metro=fra -m 1024MiB -e POSTGRES_PASSWORD=unikraft --name postgres my-org/postgres16-2:latest + ``` + + ```bash title="kraft" cd postgres16.2/ kraft cloud deploy -M 1Gi -e POSTGRES_PASSWORD=unikraft --name postgres . ``` + + 1. Run an instance of FerretDB: - ```bash + + + ```bash title="unikraft" + cd ../ferretdb/ + unikraft build . --output my-org/ferretdb:latest + unikraft run --metro=fra -p 27017:27017/tls -m 512MiB -e FERRETDB_HANDLER=pg -e FERRETDB_POSTGRESQL_address=postgres://postgres.internal:5432 -e FERRETDB_LISTEN_ADDR=0.0.0.0:27017 my-org/ferretdb:latest + ``` + + ```bash title="kraft" cd ../ferretdb/ kraft cloud deploy -p 27017:27017/tls -M 512 -e FERRETDB_HANDLER=pg -e FERRETDB_POSTGRESQL_address=postgres://postgres.internal:5432 -e FERRETDB_LISTEN_ADDR=0.0.0.0:27017 . ``` + + ```ansi [●] Deployed successfully! β”‚ @@ -63,12 +92,16 @@ For that, follow these steps: In this case, the instance name is `ferretdb-rdj6z` which is different for each run. -To test the deployment, first forward the port with the `kraft cloud tunnel` command: +To test the deployment, first forward the port with the legacy CLI tunnel command: -```bash + + +```bash title="kraft" kraft cloud tunnel 27017:memcached-arkv7:27017 ``` + + Then, on a separate console, you can use the `mongosh` client to connect to the server using the `postgres` username and the `unikraft` password configured above: ```bash @@ -107,10 +140,18 @@ For example, when a PostgreSQL instance serves as a database server to another i At this point, you can list information about the PostgreSQL and FerretDB instances: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME ferretdb-rdj6z restless-resonance-jcc4ulc3.fra.unikraft.app running 11 minutes ago ferretdb@sha256:27c59539fa3b6b7... 512 MiB /usr/bin/ferretdb 37.11 ms @@ -119,32 +160,65 @@ postgres running 14 minute When done, you can remove the FerretDB and the Postgres instances: -```bash + + +```bash title="unikraft" +unikraft instances delete ferretdb-rdj6z +unikraft instances delete postgres +``` + +```bash title="kraft" kraft cloud instance remove ferretdb-rdj6z kraft cloud instance remove postgres ``` + + ## Customize your deployment One example customization is to use [volumes](/platform/volumes) with PostgreSQL for persistence. For that, you would first create a volume: -```bash + + +```bash title="unikraft" +unikraft volumes create --set name=ferret-postgres --set size=200 --set metro=fra +``` + +```bash title="kraft" kraft cloud volume create --name ferret-postgres --size 200 ``` + + And then, when, starting the PostgreSQL instance, you would attach the volume to a mount point: -```bash + + +```bash title="unikraft" +unikraft run --metro=fra -m 1024MiB -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres --name postgres -v ferret-postgres:/volume my-org/postgres16-2:latest +``` + +```bash title="kraft" kraft cloud deploy -M 1Gi -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres --name postgres -v ferret-postgres:/volume . ``` + + ## Learn more Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/flask-sqlite.mdx b/pages/guides/flask-sqlite.mdx index 578e123c..486a5190 100644 --- a/pages/guides/flask-sqlite.mdx +++ b/pages/guides/flask-sqlite.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a Python Flask app using SQLite. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/python3.12-flask3.0-sqlite/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/python3.12-flask3.0-sqlite/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/python312-flask30-sqlite:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/python312-flask30-sqlite:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -M 512 . ``` + + ```ansi [●] Deployed successfully! β”‚ @@ -79,9 +99,17 @@ curl https://young-night-5fpf0jj8.fra.unikraft.app You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME python312-flask30-sqlite-qodkd lingering-orangutan-840mmdvd.fra.unikraft.app running 1 minute ago python312-flask30-sqlite@sha256... 512 MiB /usr/bin/python3 /app/server.py 166250us @@ -89,10 +117,18 @@ python312-flask30-sqlite-qodkd lingering-orangutan-840mmdvd.fra.unikraft.app r When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete python312-flask30-sqlite-qodkd +``` + +```bash title="kraft" kraft cloud instance remove python312-flask30-sqlite-qodkd ``` + + ## Implementation details The app uses the following files: @@ -246,8 +282,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/flask.mdx b/pages/guides/flask.mdx index 06dd8d72..e5ec89b0 100644 --- a/pages/guides/flask.mdx +++ b/pages/guides/flask.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a [Flask](https://flask.palletsprojects.com/en/3.0.x/) web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-python3.12-flask3.0/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-python3.12-flask3.0/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-python312-flask30:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-python312-flask30:latest +``` + +```bash title="kraft" kraft cloud deploy -M 512 -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-python312-flask30-bxwxm damp-sunset-azd6dtyt.fra.unikraft.app running 1 minute ago http-python312-flask30@sha256:d6c8e... 512 MiB /usr/bin/python3 /app/server.py 222273us @@ -74,10 +102,18 @@ http-python312-flask30-bxwxm damp-sunset-azd6dtyt.fra.unikraft.app running 1 When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-python312-flask30-bxwxm +``` + +```bash title="kraft" kraft cloud instance remove http-python312-flask30-bxwxm ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -251,8 +287,16 @@ See also the [`http-python3.12-django5.0`](https://github.com/kraftcloud/example Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/go.mdx b/pages/guides/go.mdx index f02fe3dd..be9d4e44 100644 --- a/pages/guides/go.mdx +++ b/pages/guides/go.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Go-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-go1.21/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-go1.21/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/docs/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/docs/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-go121:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-go121:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ hello, world! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-go121-9a2wv red-dew-jtk6yxk1.fra.unikraft.app running 1 minute ago alex/http-go121@sha256:b16d61bb7898e764d... 128 MiB 9324us @@ -74,10 +102,18 @@ http-go121-9a2wv red-dew-jtk6yxk1.fra.unikraft.app running 1 minute ago alex When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-go121-9a2wv +``` + +```bash title="kraft" kraft cloud instance delete http-go121-9a2wv ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -160,8 +196,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/grafana.mdx b/pages/guides/grafana.mdx index 0663ade9..7a09e36c 100644 --- a/pages/guides/grafana.mdx +++ b/pages/guides/grafana.mdx @@ -8,7 +8,8 @@ This guide shows you how to use [Grafana](https://grafana.com), the open source To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/grafana/` directory: @@ -17,22 +18,41 @@ git clone https://github.com/kraftcloud/examples cd examples/grafana/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/grafana:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 1024MiB my-org/grafana:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 1024 . ``` + + The output shows the instance address and other details: ```ansi @@ -59,9 +79,17 @@ The default account/password are `admin/admin` (the system will prompt you to ch You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME memcached-arkv7 weathered-smoke-hehsdinv.fra.... running 11 minutes ago memcached@sha256:f53cdbce4... 256 MiB /usr/bin/memcached -u root 19266us @@ -69,10 +97,18 @@ memcached-arkv7 weathered-smoke-hehsdinv.fra.... running 11 minutes ago memc When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete grafana-sikrv +``` + +```bash title="kraft" kraft cloud instance remove grafana-sikrv ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -120,8 +156,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/haproxy.mdx b/pages/guides/haproxy.mdx index 7bf043a8..1f9748ab 100644 --- a/pages/guides/haproxy.mdx +++ b/pages/guides/haproxy.mdx @@ -9,7 +9,8 @@ HAProxy is a free and open source software that provides a high availability loa To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/haproxy/` directory: @@ -18,22 +19,41 @@ git clone https://github.com/kraftcloud/examples cd examples/haproxy/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/haproxy:latest +unikraft run --metro=fra -p 443:8404/http+tls -m 256MiB my-org/haproxy:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8404 -M 256 . ``` + + The output shows the instance address and other details: ```ansi @@ -59,9 +79,17 @@ To test, point your browser at the `/stats` endpoint (for example, `https://cool You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME haproxy-rfx6z cool-paper-svzzr3qq.fra.unikraft.app running 1 minute ago haproxy@sha256:32296847231c1515... 256 MiB /usr/bin/haproxy -f /etc/hapro... 26596us @@ -69,10 +97,18 @@ haproxy-rfx6z cool-paper-svzzr3qq.fra.unikraft.app running 1 minute ago hapr When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete haproxy-rfx6z +``` + +```bash title="kraft" kraft cloud instance remove haproxy-rfx6z ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -111,8 +147,16 @@ FROM scratch Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/hugo.mdx b/pages/guides/hugo.mdx index 7adc525b..0c768d98 100644 --- a/pages/guides/hugo.mdx +++ b/pages/guides/hugo.mdx @@ -8,7 +8,8 @@ This guide shows you how to use [Hugo](https://gohugo.io/commands/hugo_server/), To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/hugo/` directory: @@ -17,22 +18,41 @@ git clone https://github.com/kraftcloud/examples cd examples/hugo/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/hugo:latest +unikraft run --metro=fra -p 443:1313/http+tls -m 512MiB my-org/hugo:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:1313 -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -70,9 +90,17 @@ curl https://morning-rain-jikpfy3t.fra.unikraft.app You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME hugo-zpabu morning-rain-jikpfy3t.fra.unikraft.app running 1 minute ago hugo@sha256:68d20fdb707076b1cd0f2848b17cc75670d8a... 512 MiB /usr/bin/hugo server --bind=... 77166us @@ -80,10 +108,18 @@ hugo-zpabu morning-rain-jikpfy3t.fra.unikraft.app running 1 minute ago hugo When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete hugo-zpabu +``` + +```bash title="kraft" kraft cloud instance remove hugo-zpabu ``` + + ## Customize your app To customize the Hugo app, update the files in the repository, listed below: @@ -129,8 +165,16 @@ Tools like [`Jekyll`](https://jekyllrb.com/) or [`Hugo`](https://gohugo.io/) can Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/imaginary.mdx b/pages/guides/imaginary.mdx index 81f75c6c..4a45794e 100644 --- a/pages/guides/imaginary.mdx +++ b/pages/guides/imaginary.mdx @@ -2,13 +2,12 @@ title: Imaginary --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - This example uses [`imaginary`](https://github.com/h2non/imaginary), an HTTP microservice for high-level image processing. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/imaginary/` directory: @@ -17,22 +16,41 @@ git clone https://github.com/kraftcloud/examples cd examples/imaginary/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/imaginary:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB my-org/imaginary:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -M 256 . ``` + + The output shows the instance address and other details: ```ansi @@ -83,9 +101,17 @@ The API provides endpoints, together with parameters, for different image proces You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME imaginary-mwb4y divine-wind-1ycjvhqs.fra.unikraft.app running 54 seconds ago sha256:673834bc531038bb621266f7fd635a04e5... 256 MiB /usr/bin/imaginary -p 8080 32262us @@ -93,10 +119,18 @@ imaginary-mwb4y divine-wind-1ycjvhqs.fra.unikraft.app running 54 seconds ago When done, you can remove the instance: -```bash -kraft cloud instance remove divine-wind-1ycjvhqs + + +```bash title="unikraft" +unikraft instances delete imaginary-mwb4y +``` + +```bash title="kraft" +kraft cloud instance remove imaginary-mwb4y ``` + + The Imaginary Unikraft Cloud service works as is: you deploy it and then you query [the endpoints of the HTTP API](https://github.com/h2non/imaginary/blob/master/README.md#get). You can customize the command line options used to start the service, by updating the `cmd` line in the `Kraftfile`: @@ -114,8 +148,16 @@ You can update the `cmd` line with [command line option for Imaginary](https://g Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/java.mdx b/pages/guides/java.mdx index e6ab2606..cc5cf45b 100644 --- a/pages/guides/java.mdx +++ b/pages/guides/java.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Java-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-java17/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-java17/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-java17:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-java17:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-java17-k7eca holy-waterfall-p6yu0q7s.fra.unikraft.app running 1 minute ago http-java17@sha256:6f4cb7632ecbab952feb072e37a1a9... 1.0 GiB /usr/lib/jvm/java-17-openjdk... 157154us @@ -74,10 +102,18 @@ http-java17-k7eca holy-waterfall-p6yu0q7s.fra.unikraft.app running 1 minute a When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-java17-xx739 +``` + +```bash title="kraft" kraft cloud instance remove http-java17-xx739 ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -198,8 +234,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/llama2.mdx b/pages/guides/llama2.mdx index bb342ddf..9d1a6325 100644 --- a/pages/guides/llama2.mdx +++ b/pages/guides/llama2.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a llama2 inference server and expose an API to it. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/llama2/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/llama2/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/llama2:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 1024MiB my-org/llama2:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -M 1024 . ``` + + Note that in this example the system assigns 1GB of memory. The amount required will vary depending on the model (the section below covers how to deploy different models). @@ -69,9 +89,17 @@ Lily went to the tower and pushed the rock with the stick. The rock moved! She w You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME llama2-cl5bw funky-rain-xds8dxbg.fra.unikraft.app running 1 minute ago llama2@sha256:5af77e73819... 1.0 GiB 8080 38286us @@ -79,10 +107,18 @@ llama2-cl5bw funky-rain-xds8dxbg.fra.unikraft.app running 1 minute a When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete llama2-cl5bw +``` + +```bash title="kraft" kraft cloud instance remove llama2-cl5bw ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -165,8 +201,16 @@ curl -o - https://funky-rain-xds8dxbg.fra.unikraft.app/api/llama2 -d '{ "model": Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/lua.mdx b/pages/guides/lua.mdx index 4aecd3a6..0a16d798 100644 --- a/pages/guides/lua.mdx +++ b/pages/guides/lua.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Lua-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-lua5.1/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-lua5.1/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-lua51:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-lua51:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-lua51-ma2i9 young-night-5fpf0jj8.fra.unikraft.app running 1 minute ago http-lua51@sha256:278cb8b14f9faf9c27... 128 MiB /usr/bin/lua /http_server.lua 15094us @@ -74,10 +102,18 @@ http-lua51-ma2i9 young-night-5fpf0jj8.fra.unikraft.app running 1 minute ago When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-lua51-ma2i9 +``` + +```bash title="kraft" kraft cloud instance remove http-lua51-ma2i9 ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -187,8 +223,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/mariadb.mdx b/pages/guides/mariadb.mdx index 1d867f50..3f1f712a 100644 --- a/pages/guides/mariadb.mdx +++ b/pages/guides/mariadb.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide shows you how to use [MariaDB](https://mariadb.org), one of the most popular open source relational databases. To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/mariadb/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/mariadb ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/mariadb:latest +unikraft run --metro=fra -p 3306:3306/tls -m 1Gi my-org/mariadb:latest +``` + +```bash title="kraft" kraft cloud deploy -p 3306:3306/tls -M 1024 . ``` + + The output shows the instance address and other details: ```ansi @@ -52,12 +72,16 @@ The output shows the instance address and other details: In this case, the instance name is `mariadb-w2g2z` which is different for each run. -To test the deployment, first forward the port with the `kraft cloud tunnel` command. +To test the deployment, first forward the port with the legacy CLI tunnel command. -```bash + + +```bash title="kraft" kraft cloud tunnel 3306:mariadb-w2g2z:3306 ``` + + You can now, on a separate console, use the `mysql` command line tool to test that the set up works: ```bash @@ -80,16 +104,25 @@ count(*) To disconnect, kill the `tunnel` command using `Ctrl+c`. :::note -This guide uses `kraft cloud tunnel` only when a service doesn't support TLS and isn't HTTP-based (TLS/SNI determines the correct instance to send traffic to). +This guide uses the legacy tunnel command only when a service doesn't support TLS and isn't HTTP-based. +TLS/SNI determines the correct instance to send traffic to. Also note that the `tunnel` command isn't needed when connecting via an instance's private IP/FQDN. For example when the MariaDB instance serves as a database server to another instance that acts as a frontend and which **does** support TLS. ::: You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME mariadb-w2g2z twilight-sun-82lt4ddk.fra.unikraft.app running 1 minute ago mariadb@s... 1.0 GiB /usr/sbin/mariadbd --user=ro... 159065us @@ -97,10 +130,18 @@ mariadb-w2g2z twilight-sun-82lt4ddk.fra.unikraft.app running 1 minute ago ma When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete mariadb-w2g2z +``` + +```bash title="kraft" kraft cloud instance remove mariadb-w2g2z ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -139,8 +180,16 @@ FROM scratch Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/memcached.mdx b/pages/guides/memcached.mdx index 0783f276..798f7539 100644 --- a/pages/guides/memcached.mdx +++ b/pages/guides/memcached.mdx @@ -9,7 +9,8 @@ Memcached is an in-memory key-value store for small chunks of arbitrary data (st To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/memcached/` directory: @@ -18,22 +19,41 @@ git clone https://github.com/kraftcloud/examples cd examples/memcached/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/memcached:latest +unikraft run --metro=fra -p 11211:11211/tls -m 256MiB my-org/memcached:latest +``` + +```bash title="kraft" kraft cloud deploy -p 11211:11211/tls -M 256 . ``` + + The output shows the instance address and other details: ```ansi @@ -55,12 +75,16 @@ The output shows the instance address and other details: In this case, the instance name is `memcached-arkv7` which is different for each run. -To test the deployment, first forward the port with the `kraft cloud tunnel` command: +To test the deployment, first forward the port with the legacy CLI tunnel command: -```bash + + +```bash title="kraft" kraft cloud tunnel 11211:memcached-arkv7:11211 ``` + + Now, on a separate console, run the following commands to test that it works (you should see output when incrementing): ```console @@ -88,9 +112,17 @@ For example when a Memcached instance serves as a cache server to another instan You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME memcached-arkv7 weathered-smoke-hehsdinv.fra.unikraft.app running 11 minutes ago memcached@sha256:f53cdbce4... 256 MiB /usr/bin/memcached -u root 19266us @@ -98,10 +130,18 @@ memcached-arkv7 weathered-smoke-hehsdinv.fra.unikraft.app running 11 minutes When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete memcached-arkv7 +``` + +```bash title="kraft" kraft cloud instance remove memcached-arkv7 ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -142,8 +182,16 @@ FROM scratch Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/minio.mdx b/pages/guides/minio.mdx index 5e3c8365..d9edd7db 100644 --- a/pages/guides/minio.mdx +++ b/pages/guides/minio.mdx @@ -9,7 +9,8 @@ Open Source, Amazon S3 compatible, Kubernetes Native and works for cloud native To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/minio/` directory: @@ -18,22 +19,41 @@ git clone https://github.com/kraftcloud/examples cd examples/minio/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/minio:latest +unikraft run --metro=fra -p 443:9001/http+tls -p 9000:9000/tls -m 512MiB my-org/minio:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:9001/http+tls -p 9000:9000/tls -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -60,9 +80,17 @@ The default account/password are `minioadmin/minioadmin`. You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME minio-w2my8 icy-bird-tregaga9.fra.unikraft.app running 1 minute ago minio@sha256:ba4657c607495326b0e29b51... 512 MiB /usr/bin/minio server --addres... 73651us @@ -70,10 +98,18 @@ minio-w2my8 icy-bird-tregaga9.fra.unikraft.app running 1 minute ago minio@sh When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete minio-w2my8 +``` + +```bash title="kraft" kraft cloud instance remove minio-w2my8 ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -120,8 +156,16 @@ FROM scratch Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/mongodb.mdx b/pages/guides/mongodb.mdx index 2a74ac0a..10299f06 100644 --- a/pages/guides/mongodb.mdx +++ b/pages/guides/mongodb.mdx @@ -8,7 +8,8 @@ This guide shows you how to use [MongoDB](https://www.mongodb.com), a source-ava To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/mongodb/` directory: @@ -17,22 +18,41 @@ git clone https://github.com/kraftcloud/examples cd examples/mongodb/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/mongodb:latest +unikraft run --metro=fra -p 27017:27017/tls -m 1024MiB my-org/mongodb:latest +``` + +```bash title="kraft" kraft cloud deploy -p 27017:27017/tls -M 1024 . ``` + + The output shows the instance address and other details: ```ansi @@ -53,12 +73,16 @@ The output shows the instance address and other details: In this case, the instance name is `mongodb-6tiuu` which is different for each run. -To test the deployment, first forward the port with the `kraft cloud tunnel` command: +To test the deployment, first forward the port with the legacy CLI tunnel command: -```bash + + +```bash title="kraft" kraft cloud tunnel 27017:mongodb-6tiuu:27017 ``` + + Then, on a separate console, you can use the `mongosh` client to connect to the server: ```console mongosh mongodb://localhost @@ -94,9 +118,17 @@ For example when a MongoDB instance serves as a database server to another insta You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME mongodb-6tiuu bold-brook-khkwv7of.fra.unikraft.app running 20 minutes ago mongodb@sha256:e6ff5153f106e2... 1.0 GiB /usr/bin/mongod --bind_ip_all... 82410us @@ -104,10 +136,18 @@ mongodb-6tiuu bold-brook-khkwv7of.fra.unikraft.app running 20 minutes ago mo When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete mongodb-6tiuu +``` + +```bash title="kraft" kraft cloud instance remove mongodb-6tiuu ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -148,8 +188,16 @@ FROM scratch Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/nextjs.mdx b/pages/guides/nextjs.mdx index bf955d96..e56ba339 100644 --- a/pages/guides/nextjs.mdx +++ b/pages/guides/nextjs.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a Next.js app. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node21-nextjs` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/node21-nextjs/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy the app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/node21-nextjs:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 256MiB my-org/node21-nextjs:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 256 . ``` + + The output shows the instance address and other details: ```ansi @@ -66,9 +86,17 @@ Or even better, point a browser at it πŸ˜€. You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME node21-nextjs-bfrq0 small-frog-ri8c1vtw.fra.unikraft.app running 1 minute ago node21-nextjs@sha256... 256 MiB /usr/bin/node /usr/src/server.js 83600us @@ -76,10 +104,18 @@ node21-nextjs-bfrq0 small-frog-ri8c1vtw.fra.unikraft.app running 1 minute ago When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete node21-nextjs-bfrq0 +``` + +```bash title="kraft" kraft cloud instance remove node21-nextjs-bfrq0 ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -161,10 +197,19 @@ cd examples/node21-expressjs/ Run the command below to deploy the app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/node21-nextjs:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 256MiB my-org/node21-nextjs:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 256 . ``` + + Differences from the `http-node21` app are also the steps required to create an `npm`-based app: 1. Add the `package.json` file used by `npm`. @@ -271,8 +316,16 @@ See also other Node examples: [`node18-prisma-rest-express`](https://github.com/ Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/nginx.mdx b/pages/guides/nginx.mdx index 4e4a0937..eea6f4fa 100644 --- a/pages/guides/nginx.mdx +++ b/pages/guides/nginx.mdx @@ -9,7 +9,8 @@ Nginx can be used with Unikraft / Unikraft Cloud to serve static web content. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/nginx/` directory: @@ -18,22 +19,41 @@ git clone https://github.com/kraftcloud/examples cd examples/nginx/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/nginx:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -70,9 +90,17 @@ curl https://nameless-fog-0tvh1uov.fra.unikraft.app You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME nginx-67zbu nameless-fog-0tvh1uov.fra.unikraft.app running 5 minutes ago nginx@sha256:f51ecc121c9ca34abb... 128 MiB /usr/bin/nginx -c /etc/nginx/nginx.conf 11129us @@ -80,10 +108,18 @@ nginx-67zbu nameless-fog-0tvh1uov.fra.unikraft.app running When done, you can remove the instance: -```bash -kraft cloud instance remove nameless-fog-0tvh1uov.fra.unikraft.app + + +```bash title="unikraft" +unikraft instances delete nginx-67zbu +``` + +```bash title="kraft" +kraft cloud instance remove nginx-67zbu ``` + + ## Customize your app To customize the Nginx app, update the files in the repository, listed below: @@ -194,8 +230,16 @@ You can set a new webroot (different than `wwwroot`), or a different internal po Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/node.mdx b/pages/guides/node.mdx index 39a3e810..9c64b1aa 100644 --- a/pages/guides/node.mdx +++ b/pages/guides/node.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Node-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-node21/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-node21/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy the app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-node21:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB my-org/http-node21:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -M 256 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-node21-ubl8g ancient-haze-sd3wwi0x.fra.unikraft.app running 50 seconds ago http-node21@sha256:de174e3703c79a04... 256 MiB /usr/bin/node /usr/src/server.js 31654us @@ -74,10 +102,18 @@ http-node21-ubl8g ancient-haze-sd3wwi0x.fra.unikraft.app running 50 seconds a When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-node21-ubl8g +``` + +```bash title="kraft" kraft cloud instance remove http-node21-ubl8g ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -281,8 +317,16 @@ See also other Node examples: [`node18-prisma-rest-express`](https://github.com/ Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/opentelemetry-collector.mdx b/pages/guides/opentelemetry-collector.mdx index 7d74db8f..e18fe785 100644 --- a/pages/guides/opentelemetry-collector.mdx +++ b/pages/guides/opentelemetry-collector.mdx @@ -12,7 +12,8 @@ telemetry data. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/opentelemetry-collector/` directory: @@ -21,22 +22,41 @@ git clone https://github.com/kraftcloud/examples cd examples/opentelemetry-collector/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/opentelemetry-collector:latest +unikraft run --metro=fra -m 1024MiB my-org/opentelemetry-collector:latest +``` + +```bash title="kraft" kraft cloud deploy -M 1024M . ``` + + The output shows the instance address and other details: ```ansi @@ -62,21 +82,37 @@ Feel free to change and redeploy! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text -razvand@mantis:~/.../examples/opentelemetry-collector$ kraft cloud inst ls +unikraft instances list NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME opentelemetry-collector-bvtnh running since 11mins opentelemetry... 976 MiB /usr/bin/otelcontribcol --config... 177.62 ms ``` When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete opentelemetry-collector-bvtnh +``` + +```bash title="kraft" kraft cloud instance remove opentelemetry-collector-bvtnh ``` + + ## Customize your app To customize the OpenTelemetry Collector app, update `Kraftfile` or, more likely, the `rootfs/etc/otel/config.yaml` files: @@ -145,8 +181,16 @@ Such as adding another export, apart from the debug exporter. Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/perl.mdx b/pages/guides/perl.mdx index 7c98921a..c9d82e2f 100644 --- a/pages/guides/perl.mdx +++ b/pages/guides/perl.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Perl-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-perl5.38/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-perl5.38/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-perl538:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-perl538:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-perl538-1p4ml cold-brook-ba71jc16.fra.unikraft.app stopped 37 seconds ago http-perl538@sha256:8c2c1f536b349c... 512 MiB /usr/bin/perl /usr/src/server.pl 64556us @@ -74,10 +102,18 @@ http-perl538-1p4ml cold-brook-ba71jc16.fra.unikraft.app stopped 37 seconds ag When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-perl538-1p4ml +``` + +```bash title="kraft" kraft cloud instance remove http-perl538-1p4ml ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -144,8 +180,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/php.mdx b/pages/guides/php.mdx index 48078907..7f3ffc9f 100644 --- a/pages/guides/php.mdx +++ b/pages/guides/php.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple PHP-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-php8.2/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-php8.2/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-php82:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-php82:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-php82-g00si aged-fire-rh0oi0tj.fra.unikraft.app running 50 seconds ago http-php82@sha256:dccaac05398267376... 256 MiB /usr/local/bin/php /usr/src/server.php 32801us @@ -74,10 +102,18 @@ http-php82-g00si aged-fire-rh0oi0tj.fra.unikraft.app running 50 seconds ago When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-php82-g00si +``` + +```bash title="kraft" kraft cloud instance remove http-php82-g00si ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -181,8 +217,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/postgres.mdx b/pages/guides/postgres.mdx index 108d3065..100dce55 100644 --- a/pages/guides/postgres.mdx +++ b/pages/guides/postgres.mdx @@ -2,13 +2,12 @@ title: PostgreSQL --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - This guide shows you how to use [PostgreSQL](https://www.postgresql.org/), a powerful, open source object-relational database system. To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/postgres/` directory: @@ -17,22 +16,41 @@ git clone https://github.com/kraftcloud/examples cd examples/postgres/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/postgres:latest +unikraft run --metro=fra -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -m 1Gi my-org/postgres:latest +``` + +```bash title="kraft" kraft cloud deploy -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -M 1024 . ``` + + The output shows the instance address and other details: ```ansi @@ -85,17 +103,25 @@ You can see this in action by running `SELECT pg_sleep(10);` and verifying that ::: :::note -If you'd like to use a port other than `5432/tls` you'll need to use the `kraft cloud tunnel` command to connect to PostgreSQL. +If you'd like to use a port other than `5432/tls` you'll need to use the legacy CLI tunnel command to connect to PostgreSQL. See [the tunneling guide](/docs/guides/features/tunnel) for more information. Additionally, you need to explicitly disable scale-to-zero by either changing the label in the `Kraftfile` or use `--scale-to-zero off` in the deploy command. ::: You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME postgres-saan9 young-thunder-fbafrsxj.fra.unikraft.app running 6 minutes ago postgres@sha256:2476c0373d663d7604d... 1.0 GiB wrapper.sh docker-entrypoint.sh postgres 603.42 ms @@ -103,26 +129,54 @@ postgres-saan9 young-thunder-fbafrsxj.fra.unikraft.app running 6 minutes ago When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete postgres-saan9 +``` + +```bash title="kraft" kraft cloud instance remove postgres-saan9 ``` + + ## Using volumes You can use [volumes](/docs/guides/features/volumes) for data persistence for you PostgreSQL instance. For that you would first create a volume: -```console + + +```console title="unikraft" +unikraft volumes create \ + --set name=postgres \ + --set size=200 \ + --set metro=fra +``` + +```console title="kraft" kraft cloud volume create --name postgres --size 200 ``` + + Then start the PostgreSQL instance and mount that volume: -```console + + +```console title="unikraft" +unikraft build . --output my-org/postgres:latest +unikraft run --metro=fra -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume -p 5432:5432/tls -m 1Gi my-org/postgres:latest +``` + +```console title="kraft" kraft cloud deploy -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume -p 5432:5432/tls -M 1024 . ``` + + ## Customize your deployment Your deployment is a standard PostgreSQL installation. @@ -144,8 +198,16 @@ Support for scale-to-zero for internal instances is coming soon. Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/prisma.mdx b/pages/guides/prisma.mdx index 8fd6af9c..c024a7d0 100644 --- a/pages/guides/prisma.mdx +++ b/pages/guides/prisma.mdx @@ -2,13 +2,12 @@ title: Prisma --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - This app comes from [Prisma's REST API Example](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-express) and shows how to create a **REST API** using [Express](https://expressjs.com/) and [Prisma Client](https://www.prisma.io/docs/concepts/components/prisma-client) and deploy it onto Unikraft Cloud. It uses a SQLite database file with some initial dummy data which you can find at [`./prisma/store.db`](./prisma/store.db). To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node18-prisma-rest-express/` directory: @@ -17,22 +16,41 @@ git clone https://github.com/kraftcloud/examples cd examples/node18-prisma-rest-express/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/node18-prisma:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 512MiB my-org/node18-prisma:latest +``` + +```bash title="kraft" kraft cloud deploy -M 512 -p 443:3000 . ``` + + The output shows the instance address and other details: ```ansi @@ -68,10 +86,18 @@ curl https://funky-sun-4bf8v7g9.fra.unikraft.app/users You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME node18-prisma-hdof1 funky-sun-4bf8v7g9.fra.unikraft.app running 1 minute ago node18-prisma@sha25... 512 MiB /usr/bin/node /usr/src/server.js 37935us @@ -79,10 +105,18 @@ node18-prisma-hdof1 funky-sun-4bf8v7g9.fra.unikraft.app running 1 minute a When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete node18-prisma-hdof1 +``` + +```bash title="kraft" kraft cloud instance remove node18-prisma-hdof1 ``` + + If you would like to test the server locally before deploying to Unikraft Cloud, follow the instructions [here](https://github.com/kraftcloud/examples/tree/main/node18-prisma-rest-express). ## Using the app @@ -334,8 +368,16 @@ datasource db { Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/puppeteer.mdx b/pages/guides/puppeteer.mdx index f403a9d3..0a5c9e4a 100644 --- a/pages/guides/puppeteer.mdx +++ b/pages/guides/puppeteer.mdx @@ -2,13 +2,12 @@ title: Puppeteer --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - This guide shows you how to use [Puppeteer](https://pptr.dev/), a Node.js library which provides a high-level API to control browsers, including the option to run them headless (no UI). To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node-express-puppeteer/` directory: @@ -17,16 +16,26 @@ git clone https://github.com/kraftcloud/examples cd examples/node-express-puppeteer/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + :::note A Puppeteer instance on Unikraft Cloud requires 4GB to run. Request an increase in the instance memory quota when you need more memory. @@ -34,10 +43,19 @@ Request an increase in the instance memory quota when you need more memory. When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/node-express-puppeteer:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 4Gi my-org/node-express-puppeteer:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 4096 . ``` + + The output shows the instance address and other details: ```ansi @@ -66,10 +84,18 @@ You can use the landing page to generate the PDF version of a remote page. You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list node-express-puppeteer-7afg3 +``` + +```bash title="kraft" kraft cloud instance list node-express-puppeteer-7afg3 ``` + + ```text NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME node-express-puppeteer-7afg3 node-express-puppeteer-7afg3.fra.unikraft.app running since 6mins node-express-puppeteer-7afg3@s... 4.0 GiB /usr/bin/wrapper.sh /usr/bin/n... 15.27 ms @@ -77,10 +103,18 @@ node-express-puppeteer-7afg3 node-express-puppeteer-7afg3.fra.unikraft.app runn When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete node-express-puppeteer-7afg3 +``` + +```bash title="kraft" kraft cloud instance remove node-express-puppeteer-7afg3 ``` + + ## Customize your deployment The current deployment uses an ExpressJS service that uses the [PDF generating functionality of Puppeteer](https://devdocs.io/puppeteer/). @@ -91,8 +125,16 @@ You can update the service to provide a REST-like interface. Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/python.mdx b/pages/guides/python.mdx index 114c953b..3c19d4a9 100644 --- a/pages/guides/python.mdx +++ b/pages/guides/python.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Python-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-python3.12/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-python3.12/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-python312:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-python312:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-python312-ma2i9 young-night-5fpf0jj8.fra.unikraft.app running 1 minute ago http-python312@sha256:278cb8b14f9faf9c27... 512 MiB /usr/bin/python /src/server.py 15094us @@ -74,10 +102,18 @@ http-python312-ma2i9 young-night-5fpf0jj8.fra.unikraft.app running 1 minute a When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-python312-ma2i9 +``` + +```bash title="kraft" kraft cloud instance remove http-python312-ma2i9 ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -178,10 +214,19 @@ The [`http-python3.12-flask3.0`](/docs/guides/flask-sqlite/) guide details the u Run the command below to deploy the app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-python312-flask:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-python312-flask:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -M 512 . ``` + + Differences from the `http-python3.12` app are also the steps required to create an `pip`-based app: 1. Add the `requirements.txt` file used by `pip`. @@ -273,8 +318,16 @@ See also the [`http-python3.12-django5.0`](https://github.com/kraftcloud/example Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/rails.mdx b/pages/guides/rails.mdx index f16951c8..d570fcf1 100644 --- a/pages/guides/rails.mdx +++ b/pages/guides/rails.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a [Ruby on Rails](https://rubyonrails.org/) app. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/ruby3.2-rails/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/ruby3.2-rails/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/ruby32-rails:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 1024MiB -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle my-org/ruby32-rails:latest +``` + +```bash title="kraft" kraft cloud deploy -M 1024 -p 443:3000 -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle . ``` + + The output shows the instance address and other details: ```ansi @@ -70,9 +90,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME ruby32-rails-apa93 aged-waterfall-qraz0s7d.fra.unikraft.app running 2 minutes ago ruby32-rails@sha256:fdd46011408fdee... 1.0 GiB /usr/bin/ruby /app/bin/rails server -b 0.0.0.0 577.34 ms @@ -80,10 +108,18 @@ ruby32-rails-apa93 aged-waterfall-qraz0s7d.fra.unikraft.app running 2 minutes When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete ruby32-rails-apa93 +``` + +```bash title="kraft" kraft cloud instance remove ruby32-rails-apa93 ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -184,8 +220,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/redis.mdx b/pages/guides/redis.mdx index a9353bf1..ef304c9a 100644 --- a/pages/guides/redis.mdx +++ b/pages/guides/redis.mdx @@ -8,7 +8,8 @@ This guides shows you how to use [Redis](https://redis.io), an open source in-m To run it example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/redis/` directory: @@ -17,22 +18,41 @@ git clone https://github.com/kraftcloud/examples cd examples/redis/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/redis:latest +unikraft run --metro=fra -p 6379:6379/tls -m 512MiB my-org/redis:latest +``` + +```bash title="kraft" kraft cloud deploy -p 6379:6379/tls -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -53,12 +73,16 @@ The output shows the instance address and other details: In this case, the instance name is `redis-alb4r` which is different for every run. -To test the deployment, first forward the port with the `kraft cloud tunnel` command: +To test the deployment, first forward the port with the legacy CLI tunnel command: -```bash + + +```bash title="kraft" kraft cloud tunnel 6379:memcached-arkv7:6379 ``` + + Then, from another console, you can now use the `redis-benchmark` client to connect to Redis, for example: ```console redis-benchmark -t ping,set,get -n 10000 @@ -99,9 +123,17 @@ another instance that acts as a frontend and which **does** support TLS. You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME redis-alb4r rough-wind-8vxrd1ms.fra.unikraft.app running 1 minute ago redis@sha256:9665c5... 512 MiB /usr/bin/redis-server /etc/red... 26131us @@ -109,10 +141,18 @@ redis-alb4r rough-wind-8vxrd1ms.fra.unikraft.app running 1 minute ago redis@ When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete redis-alb4r +``` + +```bash title="kraft" kraft cloud instance remove redis-alb4r ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -153,8 +193,16 @@ FROM scratch Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/remix.mdx b/pages/guides/remix.mdx index 4ee7cd74..c97703bd 100644 --- a/pages/guides/remix.mdx +++ b/pages/guides/remix.mdx @@ -8,7 +8,8 @@ This guide shows how to deploy a [Remix](https://remix.run/) app. To do so, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node21-remix/` directory: @@ -17,22 +18,41 @@ git clone https://github.com/kraftcloud/examples cd examples/node21-remix/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy the app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/node21-remix:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 512MiB my-org/node21-remix:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 512 . ``` + + The output shows the instance address and other details: ```ansi @@ -57,9 +77,17 @@ You can now point your browser at the address to see your deployed instance. You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME node21-remix-jvj6b long-star-1tms9h1z.fra.unikraft.app running 1 minutes ago node21-rem... 256 MiB /usr/bin/node /usr/src/server... 67.65 ms @@ -67,10 +95,18 @@ node21-remix-jvj6b long-star-1tms9h1z.fra.unikraft.app running 1 minute When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete node21-remix-jvj6b +``` + +```bash title="kraft" kraft cloud instance remove node21-remix-jvj6b ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -124,8 +160,16 @@ COPY --from=build /usr/src/package.json /usr/src/package.json Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/ruby.mdx b/pages/guides/ruby.mdx index 1d960209..ede460bb 100644 --- a/pages/guides/ruby.mdx +++ b/pages/guides/ruby.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a simple Ruby-based HTTP web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-ruby3.2/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-ruby3.2/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-ruby32:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB my-org/http-ruby32:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -M 256 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-ruby32-s6l8n silent-resonance-1jtz5c66.fra.unikraft.app running 12 minutes ago http-ruby32@sha256:4cf3b341898e6ebff18ff2b68353ef... 256 MiB /usr/bin/ruby /src/server.rb 71191us @@ -74,10 +102,18 @@ http-ruby32-s6l8n silent-resonance-1jtz5c66.fra.unikraft.app running 12 minut When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-ruby32-s6l8n +``` + +```bash title="kraft" kraft cloud instance remove http-ruby32-s6l8n ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -142,8 +178,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/rust-actix.mdx b/pages/guides/rust-actix.mdx index 74ade950..17d892b9 100644 --- a/pages/guides/rust-actix.mdx +++ b/pages/guides/rust-actix.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This example uses [`actix-web`](https://actix.rs), a popular Rust web framework. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-rust1.75-actix-web4/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-rust1.75-actix-web4/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-rust175-actix-web4:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-rust175-actix-web4:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -66,9 +86,17 @@ Hey there! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-rust175-actix-web4-3pj27 autumn-silence-wupu2nus.fra.unikraft.app running 10 minutes ago http-rust175-actix-web4@sha256:11723705230f0f4545d2be7... 128 MiB /server 11672us @@ -76,10 +104,18 @@ http-rust175-actix-web4-3pj27 autumn-silence-wupu2nus.fra.unikraft.app running When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-rust175-actix-web4-3pj27 +``` + +```bash title="kraft" kraft cloud instance remove http-rust175-actix-web4-3pj27 ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -181,8 +217,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/rust-rocket.mdx b/pages/guides/rust-rocket.mdx index cd0e149d..2bce4b4b 100644 --- a/pages/guides/rust-rocket.mdx +++ b/pages/guides/rust-rocket.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This example uses [`Rocket`](https://rocket.rs/), a popular Rust web framework. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-rust1.75-rocket0.5/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-rust1.75-rocket0.5 ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-rust175-rocket05:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-rust175-rocket05:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ curl https://empty-bobo-n3htmpye.fra.unikraft.app/wave/Rocketeer/100 You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-rust175-rocket05-tuwq3 empty-bobo-n3htmpye.fra.unikraft.app running 1 minute ago http-rust175-rocket05@sha256:23a7a6... 128 MiB /server 17412us @@ -74,10 +102,18 @@ http-rust175-rocket05-tuwq3 empty-bobo-n3htmpye.fra.unikraft.app running 1 mi When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-rust175-rocket05-tuwq3 +``` + +```bash title="kraft" kraft cloud instance remove http-rust175-rocket05-tuwq3 ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -234,8 +270,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/rust-tokio.mdx b/pages/guides/rust-tokio.mdx index c02548df..5ef3221e 100644 --- a/pages/guides/rust-tokio.mdx +++ b/pages/guides/rust-tokio.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This example uses [`Tokio`](https://tokio.rs/), a popular Rust asynchronous runtime. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-rust1.75-tokio/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/http-rust1.75-tokio/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/http-rust175-tokio:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-rust175-tokio:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,9 +84,17 @@ Hello, World! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-rust175-tokio-6gxsp empty-dawn-3coedrce.fra.unikraft.app running 1 minute ago http-rust175-tokio@sha256:0ce75912... 128 MiB /server 21412us @@ -74,10 +102,18 @@ http-rust175-tokio-6gxsp empty-dawn-3coedrce.fra.unikraft.app running 1 minut When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete http-rust175-tokio-6gxsp +``` + +```bash title="kraft" kraft cloud instance remove http-rust175-tokio-6gxsp ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -179,8 +215,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/skipper.mdx b/pages/guides/skipper.mdx index bb91d347..d3f02639 100644 --- a/pages/guides/skipper.mdx +++ b/pages/guides/skipper.mdx @@ -2,13 +2,12 @@ title: Skipper --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - This example uses [`Skipper`](https://opensource.zalando.com/skipper/), an HTTP router and reverse proxy for service composition To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/skipper/` directory: @@ -17,22 +16,41 @@ git clone https://github.com/kraftcloud/examples cd examples/skipper/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/skipper:latest +unikraft run --metro=fra -p 443:9090/http+tls -m 128MiB my-org/skipper:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:9090 . ``` + + The output shows the instance address and other details: ```ansi @@ -65,9 +83,17 @@ Hello, world from Skipper on Unikraft! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME skipper-mx4ai aged-sea-o7d3c42s.fra.unikraft.app running 1 minute ago skipper@sha256:5483eaf... 128 MiB /usr/bin/skipper -address :9090 -routes-f... 43709us @@ -75,10 +101,18 @@ skipper-mx4ai aged-sea-o7d3c42s.fra.unikraft.app running 1 minute ago When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete skipper-mx4ai +``` + +```bash title="kraft" kraft cloud instance remove skipper-mx4ai ``` + + ## Customize your app To customize Skipper you can change the `example.eskip` configuration file. @@ -87,8 +121,16 @@ To customize Skipper you can change the `example.eskip` configuration file. Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/solidjs.mdx b/pages/guides/solidjs.mdx index 42d96bbf..0b0b2dc3 100644 --- a/pages/guides/solidjs.mdx +++ b/pages/guides/solidjs.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide shows how to deploy a [Solid Start](https://start.solidjs.com) app. To do so, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node21-solid-start/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/node21-solid-start/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy the app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/node21-solid-start:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 256MiB my-org/node21-solid-start:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 256 . ``` + + The output shows the instance address and other details: ```ansi @@ -56,9 +76,17 @@ You can now point your browser at the address to see your deployed instance. You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME node21-solid-start-lvoa2 long-star-1tms9h1z.fra.unikraft.app running 1 minutes ago node21-sol... 256 MiB /usr/bin/node /usr/src/server... 67.65 ms @@ -66,10 +94,18 @@ node21-solid-start-lvoa2 long-star-1tms9h1z.fra.unikraft.app running 1 minute When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete node21-solid-start-lvoa2 +``` + +```bash title="kraft" kraft cloud instance remove node21-solid-start-lvoa2 ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -113,8 +149,16 @@ COPY --from=build /usr/src/.output/ /usr/src/ Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/spin.mdx b/pages/guides/spin.mdx index e8eae4d9..a91caef9 100644 --- a/pages/guides/spin.mdx +++ b/pages/guides/spin.mdx @@ -10,7 +10,8 @@ It shows how to run a Spin app serving routes from two programs written in diffe Both the Spin executor and the Wagi executor on Unikraft Cloud. To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/spin-wagi-http/` directory: @@ -19,22 +20,41 @@ git clone https://github.com/kraftcloud/examples cd examples/spin-wagi-http/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/spin-wagi-http:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 2048MiB my-org/spin-wagi-http:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 2048 . ``` + + The output shows the instance address and other details: ```ansi @@ -74,9 +94,17 @@ Goodbye, Fermyon! You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME spin-wagi-http-is72r damp-bobo-wg43p36e.fra.unikraft.app running 1 minute ago spin-wagi-http@sha2... 2.0 GiB /usr/bin/spin up --from /app/spin.tom... 300064us @@ -84,10 +112,18 @@ spin-wagi-http-is72r damp-bobo-wg43p36e.fra.unikraft.app running 1 minute a When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete spin-wagi-http-is72r +``` + +```bash title="kraft" kraft cloud instance remove spin-wagi-http-is72r ``` + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -213,8 +249,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/springboot.mdx b/pages/guides/springboot.mdx index b3009965..1cb19ea7 100644 --- a/pages/guides/springboot.mdx +++ b/pages/guides/springboot.mdx @@ -7,7 +7,8 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a Spring Boot web server. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/java17-springboot3.2.x/` directory: @@ -16,22 +17,41 @@ git clone https://github.com/kraftcloud/examples cd examples/java17-springboot3.2.x/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/java17-springboot32x:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 1024MiB my-org/java17-springboot32x:latest +``` + +```bash title="kraft" kraft cloud deploy -M 1024 -p 443:8080 . ``` + + The output shows the instance address and other details: ```ansi @@ -64,10 +84,18 @@ Hello World! When done, you can remove the instance: -```bash -kraft cloud instance remove + + +```bash title="unikraft" +unikraft instances delete java17-springboot32x-qseeo ``` +```bash title="kraft" +kraft cloud instance remove java17-springboot32x-qseeo +``` + + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -185,8 +213,16 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/sveltekit.mdx b/pages/guides/sveltekit.mdx index 4b259a93..b8185f9a 100644 --- a/pages/guides/sveltekit.mdx +++ b/pages/guides/sveltekit.mdx @@ -9,7 +9,8 @@ This guide explains how to create and deploy a [SvelteKit](https://kit.svelte.de To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node21-sveltekit/` directory: @@ -18,22 +19,41 @@ git clone https://github.com/kraftcloud/examples cd examples/node21-sveltekit/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy the app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/node21-sveltekit:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 256MiB my-org/node21-sveltekit:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 256 . ``` + + The output shows the instance address and other details: ```ansi @@ -74,10 +94,18 @@ This will get you to play with the SvelteKit demo app. You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT MEMORY ARGS BOOT TIME node21-sveltekit-zmt39 dark-fog-z18n0ej1.fra.unikraft.app running 5 minutes ago node21-sveltekit@sha256:4cea210ae... 256 MiB /usr/bin/node /app/build/index.js 72.86 ms @@ -85,10 +113,18 @@ node21-sveltekit-zmt39 dark-fog-z18n0ej1.fra.unikraft.app running 5 minutes When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete node21-sveltekit-zmt39 +``` + +```bash title="kraft" kraft cloud instance remove node21-sveltekit-zmt39 ``` + + ## Customize your app @@ -229,8 +265,16 @@ Still, if required, apps may require extending the `Dockerfile` with extra [`Doc Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/traefik.mdx b/pages/guides/traefik.mdx index 2fa046d9..ed6ceabd 100644 --- a/pages/guides/traefik.mdx +++ b/pages/guides/traefik.mdx @@ -2,13 +2,12 @@ title: Traefik --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - This example uses the [`Traefik`](https://traefik.io/traefik/) cloud native app proxy. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/traefik/` directory: @@ -17,22 +16,41 @@ git clone https://github.com/kraftcloud/examples cd examples/traefik/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/traefik:latest +unikraft run --metro=fra -p 443:80/http+tls -p 8080:8080/tls -m 512MiB my-org/traefik:latest +``` + +```bash title="kraft" kraft cloud deploy -M 512 -p 443:80/tls+http -p 8080:8080/tls . ``` + + The output shows the instance address and other details: ```ansi @@ -72,9 +90,17 @@ Please change default.toml as needed. You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME traefik-wqe7e holy-cherry-rye39b1x.fra.unikraft.app running 8 minutes ago traefik@sha256:f6dd913a8... 512 MiB /usr/bin/traefik -configFile /etc/traefik/... 53661us @@ -82,10 +108,18 @@ traefik-wqe7e holy-cherry-rye39b1x.fra.unikraft.app running 8 minutes ago When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete traefik-wqe7e +``` + +```bash title="kraft" kraft cloud instance remove traefik-wqe7e ``` + + ## Customize your app To customize Traefik app you can change the `default.toml` configuration file. @@ -94,8 +128,16 @@ To customize Traefik app you can change the `default.toml` configuration file. Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/tyk.mdx b/pages/guides/tyk.mdx index 7ccc56ce..8a678055 100644 --- a/pages/guides/tyk.mdx +++ b/pages/guides/tyk.mdx @@ -9,7 +9,8 @@ Tyk is used together with Redis to store API tokens and OAuth clients. To run this example, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/tyk/` directory: @@ -18,22 +19,37 @@ git clone https://github.com/kraftcloud/examples cd examples/tyk/ ``` -Make sure to log into KraftCloud by setting your token and a [metro](/docs/metros#available) close to you. +Make sure to log into KraftCloud and pick a [metro](/docs/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set KraftCloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` -When done, invoke the following command to deploy this app on KraftCloud: + -```bash +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + +When done, invoke the following command to deploy this app on KraftCloud. +Compose is only available in the legacy CLI: + + + +```bash title="kraft" kraft cloud compose up ``` + + The output shows the [Compose](/docs/guides/features/compose) output: ```text @@ -51,9 +67,13 @@ The output shows the [Compose](/docs/guides/features/compose) output: To list information about the instances, use: -```bash + + +```bash title="kraft" kraft cloud compose ps ``` + + ```text NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME tyk-tyk funky-pond-45usfkxx.fra.unikraft.app running since 45secs tyk-tyk@sha256:06f8ba3... 128 MiB /usr/bin/tyk start --conf /etc/tyk.conf 38.12 ms @@ -76,10 +96,14 @@ curl https://funky-pond-45usfkxx.fra-test.unikraft.app/hello When done, you can bring down the instances: -```bash + + +```bash title="kraft" kraft cloud compose down ``` + + ## Customize your app To customize the Tyk app, you can update: @@ -179,8 +203,16 @@ The `compose.yaml` file can be update to assign different names, ports, network Use the `--help` option for detailed information on using KraftCloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/wazero.mdx b/pages/guides/wazero.mdx index 0ef1b20d..33170504 100644 --- a/pages/guides/wazero.mdx +++ b/pages/guides/wazero.mdx @@ -2,13 +2,12 @@ title: Wazero --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - This example comes from [Wazero's "import go" example](https://github.com/tetratelabs/wazero/tree/main/examples/import-go) and shows how to define, import and call a wasm blob from Go and run it on Unikraft Cloud. To run this it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/wazero-import-go/` directory: @@ -17,22 +16,41 @@ git clone https://github.com/kraftcloud/examples cd examples/wazero-import-go/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/wazero-import-go:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/wazero-import-go:latest /age-calculator 2000 +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 . /age-calculator 2000 ``` + + The output shows the instance address and other details: ```ansi @@ -66,9 +84,17 @@ log_i32 >> 24 You can list information about the instance by running: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME wazero-import-go-r4dx8 cool-morning-camrrhsa.fra.unikraft.app running 1 minutes ag wazero-import-go@s... 512 MiB /age-calculator 2000 20040us @@ -76,10 +102,18 @@ wazero-import-go-r4dx8 cool-morning-camrrhsa.fra.unikraft.app running 1 minu When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete wazero-import-go-r4dx8 +``` + +```bash title="kraft" kraft cloud instance remove wazero-import-go-r4dx8 ``` + + ## Background @@ -112,8 +146,16 @@ To customize the app, update the files in the repository, listed below: Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/wordpress.mdx b/pages/guides/wordpress.mdx index 46b9e24b..6787230b 100644 --- a/pages/guides/wordpress.mdx +++ b/pages/guides/wordpress.mdx @@ -2,13 +2,12 @@ title: Wordpress --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - This guide shows you how to use [Wordpress](https://wordpress.com/), a web content management system. To run it, follow these steps: -1. Install the [`kraft` CLI tool](/docs/introduction) and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/wordpress-all-in-one/` directory: @@ -17,16 +16,26 @@ git clone https://github.com/kraftcloud/examples cd examples/wordpress-all-in-one/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + :::note A Wordpress instance on Unikraft Cloud requires 3GB to run. Request an increase in the instance memory quota when you need more memory. @@ -34,10 +43,19 @@ Request an increase in the instance memory quota when you need more memory. When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/wordpress:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 3072MiB my-org/wordpress:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 3072 . ``` + + The output shows the instance address and other details: ```ansi @@ -63,10 +81,18 @@ Fill out the form and complete the Wordpress install. You can list information about the instance by running: -```bash -kraft cloud inst list + + +```bash title="unikraft" +unikraft instances list ``` +```bash title="kraft" +kraft cloud instance list +``` + + + ```text NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME wordpress-fx5rb cool-silence-h5c1es4z.fra.unikraft.app running since 2mins wordpress@sha256:... 3.0 GiB /usr/local/bin/wrapper.sh 1708.17 ms @@ -74,10 +100,18 @@ wordpress-fx5rb cool-silence-h5c1es4z.fra.unikraft.app running since 2mins When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete wordpress-fx5rb +``` + +```bash title="kraft" kraft cloud instance remove wordpress-fx5rb ``` + + ## Customize your deployment The current deployment uses the current stable version of Wordpress (6.5.5). @@ -91,8 +125,16 @@ You can deploy WordPress modules in the WordPress instance without affecting the Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/docs/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/integrations/kubernetes.mdx b/pages/integrations/kubernetes.mdx index cc483874..fe5eb2f5 100644 --- a/pages/integrations/kubernetes.mdx +++ b/pages/integrations/kubernetes.mdx @@ -29,6 +29,8 @@ $ helm install kraftlet \ --set ukc.token=$UKC_TOKEN \ oci://ghcr.io/unikraft-cloud/helm-charts/kraftlet ``` +The `UKC_METRO` and `UKC_TOKEN` variables are only for these values and the legacy CLI. +The `unikraft` CLI uses profiles instead. You can check if Kraftlet is running by checking its pods: ```bash title="" @@ -127,10 +129,18 @@ Your app is now managed from the Kubernetes cluster, but is actually running on To check the instances, run: -``` shell + + +```shell title="unikraft" +$ unikraft instances list +``` + +```shell title="kraft" $ kraft cloud instance list ``` + + Which will return a list of instances created from pods above: ``` @@ -145,12 +155,20 @@ As you can see, all instances have the same FQDN. This is because Kraftlet created a corresponding Unikraft Cloud service for the Kubernetes service defined in YAML above. You can check the created service with the following command: + + +```shell title="unikraft" +$ unikraft services list ``` + +```shell title="kraft" $ kraft cloud service list NAME FQDN SERVICES INSTANCES CREATED AT PERSISTENT my-service my-service-orjlyrac.fra.unikraft.app 443:8080/tls+http my-app-78c766fb67-k2dgk-nginx my-app-78c766fb67-tkkxq-nginx my-a... 6 minutes ago true ``` + + You can now manage your app running in Unikraft Cloud via Kubernetes resources! ### Stateful apps @@ -185,12 +203,20 @@ my-claim Bound pv-7ab06383-ac03-4a81-968a-1b0cff03c23a 10Mi RWO Also, you can check the volumes on the Unikraft Cloud: + + +```shell title="unikraft" +$ unikraft volumes list ``` + +```shell title="kraft" $ kraft cloud volume list NAME CREATED AT SIZE ATTACHED TO MOUNTED BY STATE PERSISTENT my-claim 5 minutes ago 10 MiB available true ``` + + At the moment, the volume isn't attached or mounted by an instance. To create an instance that would use the volume, you can create a Kubernetes Pod that would reference the PVC: @@ -223,20 +249,36 @@ spec: If you check the instances again, you will see a new instance created from the Pod: + + +```shell title="unikraft" +$ unikraft instances list ``` + +```shell title="kraft" $ kraft cloud instance list NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME nginx-pod-nginx fragrant-breeze-llesxdta.fra.unikraft.app running since 1min nginx@sha256:49d8fb7a9934a87e93f9eb326... 128 MiB 1 /usr/bin/nginx -c /etc/nginx/nginx.conf 15.14 ms ``` + + And if you check the volume now, you will see it's attached and mounted by the created instance: + + +```shell title="unikraft" +$ unikraft volumes list ``` + +```shell title="kraft" $ kraft cloud volume list NAME CREATED AT SIZE ATTACHED TO MOUNTED BY STATE PERSISTENT my-claim 8 minutes ago 10 MiB nginx-pod-nginx nginx-pod-nginx mounted true ``` + + ## Kraftlet internals This section describes how Kraftlet translates Kubernetes objects into Unikraft Cloud resources. @@ -251,7 +293,7 @@ When Kraftlet maps a Kubernetes Service port to a Unikraft Cloud service, it der | `443` | `tls + http` | | Any other port | `tls` | -This is why the example above produces `443:8080/tls+http` in `kraft cloud service list`. +This is why the example above produces `443:8080/tls+http` in the service list. Kraftlet infers `tls+http` from port 443. ### Multi-container pods diff --git a/pages/introduction.mdx b/pages/introduction.mdx index e1d2546e..a2826df6 100644 --- a/pages/introduction.mdx +++ b/pages/introduction.mdx @@ -3,9 +3,8 @@ title: Introduction navigation_icon: book-check --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" -Unikraft Cloud is a from-first-principles virtualization solution and cloud platform based on **MicroVMs** which provides best-in-class performance, security, and scalability. +Unikraft is a from-first-principles virtualization solution and cloud platform based on **MicroVMs** which provides best-in-class performance, security, and scalability. Running your app on Unikraft Cloud is like running a container but with hardware isolation, millisecond cold starts, and stateful scale-to-zero. @@ -17,105 +16,68 @@ Expect higher server density, cost-savings, I/O performance boosts, active vCPU 1. [Create a free account](https://console.unikraft.cloud/signup). -1. Install the [`kraft`](/cli/) CLI: - - - - Shell 1-liner - macOS - Debian/Ubuntu - - - ```bash title="Run on any *NIX shell" - curl -sSfL https://get.kraftkit.sh | sh - ``` - - - ```bash title="zsh" - brew install unikraft/cli/kraftkit - ``` - - - ```bash - sudo apt-get update - sudo apt-get install \ - ca-certificates \ - curl \ - gnupg \ - lsb-release - ``` - - Add Unikraft's official GPG key: - - ```bash - sudo mkdir -p /etc/apt/keyrings - curl -fsSL https://deb.pkg.kraftkit.sh/gpg.key | \ - sudo gpg --dearmor -o /etc/apt/keyrings/unikraft.gpg - ``` - - Use the following command to set up the APT repository: - - ```bash - echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/unikraft.gpg] https://deb.pkg.kraftkit.sh /" | \ - sudo tee /etc/apt/sources.list.d/unikraft.list > /dev/null - ``` - - Update the APT package index, and install the latest version of `kraftkit`: - - ```bash - sudo apt-get update - sudo apt-get install kraftkit - ``` - - - - See [alternative installation instructions](https://unikraft.org/docs/cli/install) for other platforms. - -1. Set a metro you want to use, e.g. `fra`: +1. Install the Unikraft CLI. - ```bash - export UKC_METRO=fra - ``` - -1. Set your access token (from the [console](https://console.unikraft.cloud/), go to `Settings` and see the `API TOKEN`): + - ```bash - export UKC_TOKEN= + ```bash title="1-liner (macOS & Linux)" + curl --proto '=https' --tlsv1.2 -fsSL https://unikraft.com/cli/install.sh | sh ``` -1. Install Docker on your system, by following [the official instructions](https://docs.docker.com/get-started/get-docker/). - You require Docker to build the app image that you will then deploy on Unikraft Cloud. - - Be sure to follow the [post-installation steps](https://docs.docker.com/engine/install/linux-postinstall/). - -1. _(optional, but recommended)_ Configure BuildKit on your system. - BuildKit is useful to cache the Unikraft Cloud builds and reduce the build time. - - See instructions [here](/platform/troubleshooting#how-can-you-cache-the-apps-filesystem-for-faster-builds). + ```bash title="macOS" + brew install unikraft/cli/unikraft + ``` -1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples): + ```bash title="Debian/Ubuntu" + sudo apt-get update + sudo apt-get install \ + ca-certificates \ + curl \ + gnupg \ + lsb-release + + # Add Unikraft's official GPG key + sudo mkdir -p /etc/apt/keyrings + curl -fsSL https://deb.pkg.unikraft.com/gpg.key | \ + sudo gpg --dearmor -o /etc/apt/keyrings/unikraft.gpg + + # Set up the APT repository + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/unikraft.gpg] https://deb.pkg.unikraft.com /" | \ + sudo tee /etc/apt/sources.list.d/unikraft.list > /dev/null + + # Install unikraft CLI + sudo apt-get update + sudo apt-get install unikraft + ``` - ```bash - git clone https://github.com/unikraft-cloud/examples - cd examples/ + ```bash title="Fedora/RHEL/Rocky/Alma" + # Add the Unikraft CLI repository + sudo tee /etc/yum.repos.d/unikraft-cli-rpm.repo < - ```bash - cd nginx/ - ``` + See [alternative installation instructions](https://github.com/unikraft/cli/?tab=readme-ov-file#installation) for other platforms. -1. Deploy your first scale-to-zero, serverless app with Unikraft Cloud: +1. Authenticate with your account. ```bash - kraft cloud deploy --port 443:8080 --memory 256Mi . + unikraft login ``` -1. Use `curl` or a browser to access the Unikraft Cloud instance of Nginx, at the address shown by the `kraft cloud deploy` command (or, use `kraft cloud instance ls` and `kraft cloud instance get ` to get the address): +1. Deploy your first scale-to-zero, serverless app with Unikraft Cloud. ```bash - curl https:// + unikraft run --metro=fra -p 443:8080/http+tls nginx:latest ``` diff --git a/pages/platform/certificates.mdx b/pages/platform/certificates.mdx index 0e14828d..f77ec630 100644 --- a/pages/platform/certificates.mdx +++ b/pages/platform/certificates.mdx @@ -3,9 +3,19 @@ title: Certificates navigation_icon: shield-check --- -To use a custom certificate instead of the automatically generated one from the default public certificate authority, run the `create` command: +To use a custom certificate instead of the automatically generated one from the default public certificate authority, create a certificate with the CLI: -```ansi title="" + + +```ansi title="unikraft" +unikraft certificates create \ + --cn *.mydomain.com \ + --name mydomain-cert \ + --pkey /path/to/private.key \ + --chain /path/to/chain.pem +``` + +```ansi title="kraft" kraft cloud cert create \ --cn *.mydomain.com \ --name mydomain-cert \ @@ -13,16 +23,26 @@ kraft cloud cert create \ --chain /path/to/chain.pem ``` + + The provided common name (CN) must match the one for which Unikraft Cloud issued the certificate. It can also be a wildcard domain. -Use the `kraft cloud cert` command to view and manage certificates. -For example, to list certificates, run: +Use the CLI to view and manage certificates. +For example, to list certificates: -```bash title="" + + +```bash title="unikraft" +unikraft certificates list +``` + +```bash title="kraft" kraft cloud cert ls ``` + + You should see output like: ```text title="" @@ -33,10 +53,18 @@ mydomain-cert valid *.mydomain.com 2 days ago Retrieve full information about a certificate with: -```bash title="" + + +```bash title="unikraft" +unikraft certificates get mydomain.com-sa4x9 +``` + +```bash title="kraft" kraft cloud cert get mydomain.com-sa4x9 ``` + + You should see output like: ```ansi title="" @@ -56,12 +84,20 @@ serial number: 0455BBAEC140EACBA5FEEAE6D817E73EF266 To remove a certificate, first remove any instances from the relevant service and then remove the service. Remove the certificate with: -```bash title="" + + +```bash title="unikraft" +unikraft certificates delete mydomain.com-sa4x9 +``` + +```bash title="kraft" kraft cloud cert rm mydomain.com-sa4x9 ``` + + ## Learn more -* The `kraft cloud` [CLI reference](/cli/) +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview) * Unikraft Cloud's [REST API reference](/api/platform/v1) * Many more guides [here](/guides/bun) diff --git a/pages/platform/domains.mdx b/pages/platform/domains.mdx index b0502255..20f05ea8 100644 --- a/pages/platform/domains.mdx +++ b/pages/platform/domains.mdx @@ -8,7 +8,7 @@ This guide shows how to deploy an app and link it to a domain you own (for examp :::note Unikraft Cloud can take a few seconds before issuing the certificate. If there are misconfigurations or DNS changes that your external DNS provider hasn't propagated yet, this can take much longer. -You can check the validation status of the certificate with `kraft cloud cert get` (more on this command below). +You can check the validation status of the certificate with the CLI (more on this command below). The controller retries at these intervals: [1,5,10,30] minutes, then [1,6,12,24] hours, then it fails. ::: @@ -31,7 +31,19 @@ ALIAS (apex alias) and ANAME (authoritative alias) are DNS record types some pro If the provider doesn't support these record types, add an A record pointing to the metro IP address. :::tip -You can find information about the Unikraft Cloud metros available to you, as well as their IP addresses, via the cmd `kraft cloud metro ls`. +You can find information about the Unikraft Cloud metros available to you, as well as their IP addresses, via the CLI. + + + +```bash title="unikraft" +unikraft metros list +``` + +```bash title="kraft" +kraft cloud metro ls +``` + + ::: :::note @@ -49,24 +61,43 @@ git clone https://github.com/unikraft-cloud/examples cd examples/nginx ``` -Log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. +Log into Unikraft Cloud and select a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ). Set the following: -```bash title="" + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` -With this in place, use the `kraft cloud deploy` command to create an instance of the web server and to link it to a custom name. -Unikraft Cloud does this through the `-d` flag: + -```bash title="" +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + +With this in place, use the CLI to create an instance of the web server and link it to a custom name. +Unikraft Cloud does this through the domain flag: + + + +```bash title="unikraft" +unikraft build . --output my-org/nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls --domain mydomain.com my-org/nginx:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:8080 -d mydomain.com . ``` + + The resulting output of the `deploy` command should be like: ```ansi title="" @@ -85,13 +116,13 @@ The resulting output of the `deploy` command should be like: β””────────── args: /usr/bin/nginx -c /etc/nginx/nginx.conf ``` -When you issue the `-d` flag, Unikraft Cloud requests a +When you issue the domain flag, Unikraft Cloud requests a new certificate from the public certificate authority. :::note Issuing the certificate can take a few seconds. If there are misconfigurations or pending DNS changes, it can take longer. -Check the validation status with `kraft cloud cert get` (more on this command below). +Check the validation status with the CLI (more on this command below). The Unikraft Cloud controller retries at these intervals: [1,5,10,30] minutes, then [1,6,12,24] hours, then it fails. ::: diff --git a/pages/platform/images.mdx b/pages/platform/images.mdx index 261c1011..c872cc12 100644 --- a/pages/platform/images.mdx +++ b/pages/platform/images.mdx @@ -4,15 +4,15 @@ navigation_icon: package --- Unikraft Cloud uses a **registry** to store images used to instantiate apps. -At a high level, you use `kraft` to build and push an image to the registry, and then ask the controller to start an app from it. +At a high level, you use the CLI to build and push an image to the registry, and then ask the controller to start an app from it. 1. **build**: `kraft` builds the app locally according to a `Dockerfile`. 1. **pkg**: `kraft` packages the app locally into an OCI image. 1. **push**: `kraft` pushes the OCI image to the Unikraft Cloud registry. 1. **create**: The controller instantiates your app from the image according to a `Kraftfile`. -The simplest way to run this workflow is to use `kraft cloud deploy`, which combines all steps into one command. -Internally, the deploy command calls other subcommands. +The simplest way to run this workflow is to use a single deploy or run command, which combines all steps into one flow. +Internally, the command calls other subcommands. The service in the diagram is the mechanism to connect apps to the Internet. Read more in the [services guide](/platform/services). @@ -75,14 +75,25 @@ This guide uses a Python [app](/guides/python) as an example to show three workf ### Create an image and an instance from it -Start with the simplest workflow: create an image from a Python app (following the Python app [guide](/guides/python)) and start an instance from it with a single `kraft cloud deploy` command: +Start with the simplest workflow: create an image from a Python app (following the Python app [guide](/guides/python)) and start an instance from it: -```bash title="" + + +```bash title="unikraft" +git clone https://github.com/unikraft-cloud/examples +cd examples/http-python3.12 +unikraft build . --output my-org/http-python312:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-python312:latest +``` + +```bash title="kraft" git clone https://github.com/unikraft-cloud/examples cd examples/http-python3.12 kraft cloud deploy -p 443:8080 -M 512 . ``` + + The output should look like: ```ansi title="" @@ -107,10 +118,18 @@ The controller fetches the image from the registry to start the instance. You can see your images by running the following command: -```bash title="" + + +```bash title="unikraft" +unikraft images list +``` + +```bash title="kraft" kraft cloud image ls ``` + + You should see output like: ```text title="" @@ -118,27 +137,42 @@ IMAGE TAG SIZE [username]]/http-python312 latest 77 MB ``` -And you can remove an image from the registry via: +And you can remove an image from the registry via the legacy CLI: -```bash title="" + + +```bash title="kraft" kraft cloud img rm http-python312 ``` + + :::note -There may be a delay of a few minutes between removing an image from the registry and `kraft cloud image ls` reflecting the change. +There may be a delay of a few minutes between removing an image from the registry and the image list reflecting the change. ::: ### Create an image and many instances from it -For the next workflow, use `kraft cloud deploy` again, this time with the `-R` flag to start many instances: +For the next workflow, start many instances: -```bash title="" + + +```bash title="unikraft" +git clone https://github.com/unikraft-cloud/examples +cd examples/http-python3.12 +unikraft build . --output my-org/http-python312:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB --replicas 2 my-org/http-python312:latest +``` + +```bash title="kraft" git clone https://github.com/unikraft-cloud/examples cd examples/http-python3.12 kraft cloud deploy -p 443:8080 -M 512 -R 2 . ``` + + ```ansi title="" [●] Deployed successfully! β”‚ @@ -157,10 +191,18 @@ kraft cloud deploy -p 443:8080 -M 512 -R 2 . Check that it worked by listing all instances with: -```bash title="" + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text title="" NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME http-python312-w4bcp sparkling-surf-qphxdk0j.fra.unikraft.app running 45 seconds ago http-python312@sha256... 512 MiB /usr/bin/python3 /src/server.py 153794us @@ -172,9 +214,15 @@ Three instances run: the original plus two replicas. ### Create instances from an existing image -In this final workflow, take the existing image and start new instances using the `kraft cloud instance` command: +In this final workflow, take the existing image and start new instances from it: -```bash title="" + + +```bash title="unikraft" +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB [username]/http-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca +``` + +```bash title="kraft" kraft cloud instance create \ --start \ --port 443:8080 \ @@ -182,6 +230,8 @@ kraft cloud instance create \ [username]/http-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca ``` + + You now have a new instance created from the existing image. @@ -251,5 +301,5 @@ The response includes `url`, `tags`, `initrd_or_rom`, `size_in_bytes`, args` and ## Learn more -* The `kraft cloud` [CLI reference](/cli/) +* The legacy [CLI reference](/docs/cli/kraft/overview) * Unikraft Cloud's [REST API reference](/api/platform/v1) diff --git a/pages/platform/metros.mdx b/pages/platform/metros.mdx index 0062d560..de26f00b 100644 --- a/pages/platform/metros.mdx +++ b/pages/platform/metros.mdx @@ -15,7 +15,19 @@ By default, at present, Unikraft Cloud supports the following metros: :::tip -You can list the metros available to your account via the `kraft cloud metro ls` command. +You can list the metros available to your account via the CLI. + + + +```bash title="unikraft" +unikraft metros list +``` + +```bash title="kraft" +kraft cloud metro ls +``` + + ::: @@ -67,18 +79,26 @@ If you require running solutions in-house or on-premise, either for SOC/ISO/HIPP ## Usage -When using `kraft`, you can set the metro you wish to use by either setting the CLI flag `--metro` in any `kraft cloud` subcommand or by setting the environmental variable `UKC_METRO`. +You can set the metro you wish to use by setting the `--metro` flag. +The legacy CLI also supports the `UKC_METRO` environment variable. Use the IATA code descriptor to target the specific metro. For example with `fra`: -```bash title="" -# Via CLI flag -kraft cloud --metro fra run -p 443:8080 nginx:latest - -# or via environmental variable -export UKC_METRO=fra -kraft cloud run -p 443:8080 nginx:latest -``` + + ```bash title="unikraft" + unikraft run --metro=fra -p 443:8080/http+tls nginx:latest + ``` + + ```bash title="kraft" + # Via CLI flag + kraft cloud --metro fra run -p 443:8080 nginx:latest + + # or via environmental variable + export UKC_METRO=fra + kraft cloud run -p 443:8080 nginx:latest + ``` + The `UKC_METRO` environment variable is only supported by the legacy CLI. + For on-premise or enterprise users, set the FQDN of the API endpoint as the metro argument, e.g.: diff --git a/pages/platform/services.mdx b/pages/platform/services.mdx index 5dc63d6c..49814c46 100644 --- a/pages/platform/services.mdx +++ b/pages/platform/services.mdx @@ -17,34 +17,56 @@ Avoid placing apps that expose different ports in the same service. ::: -If you use the `kraft cloud deploy` command, part of the output lists a service, for example: +If you use the deploy or run flow, part of the output lists a service, for example: ```ansi title="" β”œ─ service: frosty-sky-vz8kwsm ``` -Because `kraft cloud deploy` is a single command to deploy a service, it automatically creates a service and attaches the new instance to it. -The rest of this guide shows how to create a service first, then use `kraft cloud deploy` to create and attach instances to it. +Because the deploy or run flow is a single command to deploy a service, it automatically creates a service and attaches the new instance to it. +The rest of this guide shows how to create a service first, then use the CLI to create and attach instances to it. -First, create a new service with the `kraft cloud service` command: +First, create a new service with the CLI: -```bash title="" + + +```bash title="unikraft" +unikraft services create \ + --set name=my-service \ + --set metro=fra \ + --set services=443:8080/tls+http +``` + +```bash title="kraft" kraft cloud service create --name my-service 443:8080/http+tls ``` + + This creates a new service named `my-service` listening on port 443. Unikraft Cloud terminates TLS and sends HTTP to port 8080. This example assumes that the app opens port 8080. -Now use `kraft cloud deploy` with the `--service` flag to attach the instance to the `my-service` service. +Now use the CLI with the service flag to attach the instance to the `my-service` service. For example, from the [Go web server guide](/guides/go): -```bash title="" + + +```bash title="unikraft" +git clone https://github.com/unikraft-cloud/examples +cd examples/http-go1.21/ +unikraft build . --output my-org/http-go121:latest +unikraft run --metro=fra --service my-service -m 256MiB my-org/http-go121:latest +``` + +```bash title="kraft" git clone https://github.com/unikraft-cloud/examples cd examples/http-go1.21/ kraft cloud deploy --service my-service -M 256 . ``` + + This creates a new Go web server instance and immediately attaches it to the `my-service` service. The output shows the instance address and other details: @@ -80,7 +102,7 @@ hello, world! :::tip -If you specify a port with the `-p` option when using `kraft cloud deploy`, the command creates a service automatically. +If you specify a port with the publish flag when using the deploy or run flow, the command creates a service automatically. In that case the platform deletes the service when the instance ends, and you can't define the service name. ::: @@ -89,10 +111,18 @@ That's it. In the end, if you want to remove a service, use: -```bash title="" + + +```bash title="unikraft" +unikraft services delete my-service +``` + +```bash title="kraft" kraft cloud service remove my-service ``` + + ## Handlers Handlers define how the service will handle incoming connections and forward traffic from the Internet to your app. @@ -135,10 +165,23 @@ For example, the following creates the service `my-service` with three published - Port 80 with the `http` and `redirect` handlers (HTTP mode). - Port 10000 with only the `tls` handler (TCP mode). -```bash title="" + + +```bash title="unikraft" +unikraft services create \ + --set name=my-service \ + --set metro=fra \ + --set services=443:8080/tls+http \ + --set services=80:8080/http+redirect \ + --set services=10000:10000/tls +``` + +```bash title="kraft" kraft cloud service create --name my-service 443:8080/http+tls 80:8080/http+redirect 10000:10000/tls ``` + + ## `UDP` Support `UDP` is a defined service protocol alongside `TCP`. @@ -174,7 +217,7 @@ You must also list the `UDP` IPs in the `additional_ip_addresses` directive in ` To create a `UDP` service, set both `protocol` and `ip`: -```json title="POST /services" +```json title="POST /v1/services" { "services": [ { @@ -201,9 +244,9 @@ Every service group has a soft and a hard connection limit that the load balance `soft_limit` must be less than or equal to `hard_limit`. Setting `soft_limit > hard_limit` returns a `400` error. -You can set both fields at service group creation time and update them later with `PATCH /services/{name}`. +You can set both fields at service group creation time and update them later with `PATCH /v1/services/{name}`. -```json title="POST /services" +```json title="POST /v1/services" { "name": "my-service", "soft_limit": 100, @@ -215,14 +258,14 @@ You can set both fields at service group creation time and update them later wit A service group is **persistent** when your user account owns it rather than a specific instance. -- A service group created with `kraft cloud service create` (or `POST /services`) is persistent. +- A service group created with the CLI (or `POST /v1/services`) is persistent. It survives independently of any instances attached to it. -- A service group created implicitly via `kraft cloud deploy -p …` (shorthand port forwarding) belongs to the instance. +- A service group created implicitly via the publish flag on instance creation belongs to the instance. The platform deletes it when you delete that instance. -The `GET /services/{name}` response includes a `persistent` field (`bool`) that indicates which case applies. +The `GET /v1/services/{name}` response includes a `persistent` field (`bool`) that indicates which case applies. ## Learn more -* The `kraft cloud` [CLI reference](/cli/), in particular the [service](/cli/service) subcommand +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview) * Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [service groups](/api/platform/v1/service-groups) diff --git a/pages/platform/troubleshooting.mdx b/pages/platform/troubleshooting.mdx index d2bd7d18..620bb2cb 100644 --- a/pages/platform/troubleshooting.mdx +++ b/pages/platform/troubleshooting.mdx @@ -13,12 +13,22 @@ If you need help, reach out to Unikraft Cloud Support. An app may crash, freeze, or misbehave. To inspect it, try either: -```bash title="" + + +```bash title="unikraft" +unikraft instances logs +# or +unikraft instances get +``` + +```bash title="kraft" kraft cloud inst logs # or kraft cloud inst get ``` + + This may, in certain times, provide insufficient information. @@ -82,7 +92,7 @@ You may need a TLS tunnel (see below). Unikraft Cloud uses TLS to expose services to the outside world. Some apps (such as [MongoDB](/guides/mongodb) or [MariaDB](/guides/mariadb)) don't use TLS. -Create a TLS tunnel via `kraft cloud tunnel`, which opens a local endpoint (`localhost` / `127.0.0.1`) and forwards traffic over TLS. +Create a TLS tunnel via the legacy CLI, which opens a local endpoint (`localhost` / `127.0.0.1`) and forwards traffic over TLS. See the [MariaDB guide](/guides/mariadb) for an example. @@ -96,33 +106,42 @@ When building / deploying an image, you may get the error below: This often means the local `kraft` cache is in an inconsistent state. -To solve this, remove the local `kraft` cache and local packages: +To solve this, remove the local legacy CLI cache and local packages: -```bash title="" + + +```bash title="kraft" kraft pkg rm --all rm -fr ~/.local/share/kraftkit ``` + + ## Launched app not visible in list The most common reason is that you deployed an app to one metro but listed a different one. -Set the metro for a session with an env variable: +Use the `--metro` flag per command, or use the legacy CLI environment variable for a session: -```bash title="" -export UKC_METRO= -``` + -or for each indvidual command via the `--metro` flag, for example: +```bash title="unikraft" +unikraft instances list --metro +``` -```bash title="" +```bash title="kraft" +export UKC_METRO= kraft cloud instance list --metro ``` + + +> **Note:** The `UKC_METRO` environment variable is only supported by the legacy CLI. + ## How can you cache the app's filesystem for faster builds When using a `Dockerfile` for the app filesystem, Unikraft Cloud passes the commands to [BuildKit](https://docs.docker.com/build/buildkit/). -By default, each `kraft cloud deploy` command starts an ephemeral BuildKit container. +By default, each legacy deploy command starts an ephemeral BuildKit container. The platform then removes the filesystem app data, so each deploy starts from zero. To prevent this, follow the instructions [here](https://unikraft.org/guides/building-dockerfile-images-with-buildkit): @@ -144,7 +163,7 @@ Here `$HOME/.buildkit-cache` is a local path on your machine where BuildKit stor ## What's a `Kraftfile` -A `Kraftfile` is used by the `kraft` CLI tool to understand how to build and deploy your instance. +A `Kraftfile` is used by the CLI toolchain to understand how to build and deploy your instance. Typically you can use the default `Kraftfile` found in each Unikraft Cloud example. Below is a sample `Kraftfile` with a brief explanation: @@ -166,25 +185,27 @@ labels: The `runtime` specifies one of the Unikraft Cloud runtimes (microVMs) built to run different languages and apps. Here it specifies a Python runtime. -The `rootfs` parameter tells `kraft` to use a `Dockerfile` in the same directory to build the root filesystem, and the `cmd` parameter which command to run when deployed (although you can also specify this in the `Dockerfile`). +The `rootfs` parameter tells the CLI to use a `Dockerfile` in the same directory to build the root filesystem, and the `cmd` parameter which command to run when deployed (although you can also specify this in the `Dockerfile`). Finally the `labels` specify runtime options. In the example above, the configuration enables stateful scale-to-zero and the platform waits 1 second with no requests before putting the instance to sleep. ## Debugging the build, packaging and pushing steps -The `kraft cloud deploy` command performs steps on your local device before actually deploying your app to Unikraft Cloud: +The legacy deploy command performs steps on your local device before actually deploying your app to Unikraft Cloud: 1. Downloads the runtime image (defined in the `Kraftfile`) from the Unikraft Cloud registry. 1. Builds the app filesystem using the `Dockerfile` via [BuildKit](https://unikraft.org/guides/building-dockerfile-images-with-buildkit). 1. Packages the app filesystem and the runtime in an Open Container Initiative (OCI) image. 1. Pushes the OCI image to the to the Unikraft Cloud registry under your username's namespace. -If any of these steps fail, enable `kraft` debugging with the `--log-level` and `--log-type` flags: +If any of these steps fail, enable legacy CLI debugging with the `--log-level` and `--log-type` flags: -```bash title="" -kraft cloud deploy --log-level debug --log-type basic [...] -``` + + ```bash title="kraft" + kraft cloud deploy --log-level debug --log-type basic [...] + ``` + You should then see debug output for the 4 steps above. @@ -213,12 +234,20 @@ If not, report it with the output on the [Discord server](/discord). ## Debugging running apps The most direct way to debug an app is to use the app console output, which may include kernel output. -To see it, after starting the Unikraft Cloud instance (via `kraft cloud deploy` or `kraft cloud inst create`), use: +To see it, after starting the Unikraft Cloud instance, use: -```bash title="" + + +```bash title="unikraft" +unikraft instances logs +``` + +```bash title="kraft" kraft cloud inst logs ``` + + In case of a crash, you'll see a full crash output: {/* vale off */} @@ -249,9 +278,10 @@ Powered by Unikraft Telesto (0.16.2~9c264902) [ 0.080871] CRIT: [appelfloader] [0x000000100041fdcb] [ 0.081311] CRIT: [appelfloader] Bad frame pointer -It looks like the instance exited fatally. To see more details about why, run: +It looks like the instance exited fatally. +Run this for more details: - kraft cloud instance get http-python312-hb7ij + unikraft instances get http-python312-hb7ij ``` {/* vale on */} @@ -291,8 +321,8 @@ Here the cause is insufficient memory. If the stop reason lacks detail, enable debug tracing for the instance. -To do that, in your app of choice in the [examples repository](https://github.com/unikraft-cloud/examples/), or in an app directory you created, update the `runtime` entry in the `Kraftfile`. -The entry should reference the debug build of the image you use by adding `-dbg` to the name of the runtime. +To do that, pick an app from the [examples repository](https://github.com/unikraft-cloud/examples/) or an app directory you created. +Update the `runtime` entry in the `Kraftfile` to reference the debug build by adding `-dbg` to the runtime name. For example, if you want to run the [http-go1.21 example](https://github.com/unikraft-cloud/examples/tree/main/http-go1.21) with debug output, update its `Kraftfile` as follows: ```yaml title="Kraftfile" @@ -308,16 +338,33 @@ cmd: ["/server"] That is, change `base:latest` to `base:latest-dbg`. Now Unikraft Cloud is ready to re-deploy: -```bash title="" + + +```bash title="unikraft" +unikraft build . --output my-org/http-go-strace:latest +unikraft run --metro=fra --name http-go-strace -p 443:8080/http+tls my-org/http-go-strace:latest +``` + +```bash title="kraft" kraft cloud deploy --name http-go-strace -p 443:8080 . ``` + + You can now inspect the logs as before and view system call tracing: -```bash title="" + + +```bash title="unikraft" +unikraft instances logs http-go-strace +``` + +```bash title="kraft" kraft cloud inst logs http-go-strace ``` + + ```ansi title="" [ 0.000000] Info: [libkvmplat] Unikraft Telesto (0.16.2~5b96d531) [ 0.000000] Info: [libkvmplat] Architecture: x86_64 @@ -352,14 +399,27 @@ Contact Unikraft Cloud on the [Discord server](/discord) and include this output :::tip While you debug an issue you can mitigate crashes by setting a restart policy. -For example, use `kraft cloud deploy --restart on-failure` to have the platform restart the app if it crashes. -Find more info on [restart policies here](/cli/deploy#options). +For example, use the CLI to set `--restart on-failure` so the platform restarts the app if it crashes. + + + +```bash title="unikraft" +unikraft run --metro=fra --restart=on-failure my-app:latest +``` + +```bash title="kraft" +kraft cloud deploy --restart on-failure . +``` + + + +Find more info in the [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). ::: ## Learn more -* The `kraft cloud` [CLI reference](/cli/) +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview) * Unikraft Cloud's [REST API reference](/api/platform/v1) * Many more guides [here](/guides/bun) diff --git a/pages/platform/volumes.mdx b/pages/platform/volumes.mdx index b006a9c1..8ab0ee00 100644 --- a/pages/platform/volumes.mdx +++ b/pages/platform/volumes.mdx @@ -19,19 +19,40 @@ In this case, the volume's lifetime is tied to the instance - when you delete th ### Setting up the volume -To start, create the volume via [`kraft cloud volume`](/cli/kraft/volume), with size in MBs and name `my-volume`: +To start, create the volume with the CLI, with size in MBs and name `my-volume`: -```bash title="" -kraft cloud volume create --size 100 --name my-volume + + +```bash title="unikraft" +unikraft volumes create \ + --set name=my-volume \ + --set size=100 \ + --set metro=fra +``` + +```bash title="kraft" +kraft cloud volume create \ + --size 100 \ + --name my-volume ``` + + The command should return the volume's UUID, and you can check the operation worked via: -```bash title="" + + +```bash title="unikraft" +unikraft volumes list +``` + +```bash title="kraft" kraft cloud volume list ``` + + which should output something like: ```ansi title="" @@ -43,24 +64,32 @@ The `ATTACHED TO` field is empty because the platform hasn't attached it to any ### Populating the volume with local data (optional) -If you'd like to populate your empty volume with local data, you can use the [`kraft cloud volume import`](/cli/kraft/volume/import) command. +To populate an empty volume with local data, use the legacy CLI volume import command. For example, assuming the volume's name is `my-volume` and that the data you want to import are in your `my-data` directory, you would run: -```bash title="" + + +```bash title="kraft" kraft cloud volume import --volume my-volume --source my-data ``` + + You should see output like: ```ansi title="" -[●] Import complete - β”‚ - β”œ─ volume: my-volume - β”œ─── free: 99 MiB - β””── total: 100 MiB +[+] Packaging source as a CPIO archive... done! [0.0s] +[+] Spawning temporary volume data import instance... done! [0.1s] +[+] Importing data (256 B) β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’ 100% [0.1s] + +[●] Import complete + β”‚ + β”œβ”€β”€β”€ volume: my-volume + β”œβ”€ imported: 256 B + └─ capacity: 100 MiB ``` -### Setting up a web server +## Setting up the web server Use a Flask web server to write to the volume: @@ -109,12 +138,21 @@ On every request, this simple server will write a timestamp to a file on the mounted persistent volume and print out the current contents of the file. Start the Flask web server, create a -[service](/platform/services) for it via the `-p` flag, and mount the `my-volume` volume at `/mnt`: +[service](/platform/services) for it via the publish flag, and mount the `my-volume` volume at `/mnt`: -```bash title="" + + +```bash title="unikraft" +unikraft build . --output my-org/http-python312-flask30:latest +unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt my-org/http-python312-flask30:latest +``` + +```bash title="kraft" kraft cloud deploy -M 512 -p 443:8080 --volume my-volume:/mnt . ``` + + You should see output like: ```ansi title="" @@ -135,10 +173,18 @@ You should see output like: To confirm that the platform attached the volume, run: -```bash title="" + + +```bash title="unikraft" +unikraft volumes get my-volume +``` + +```bash title="kraft" kraft cloud volume get my-volume ``` + + You should see output like: ```text title="" @@ -146,7 +192,7 @@ NAME CREATED AT SIZE ATTACHED TO STATE PERSI my-volume 34 minutes ago 100 MiB http-python312-flask30-2h608 mounted true ``` -### Testing the server +## Testing it The Flask server writes the time and date to `/mnt/log.txt` for each request. Test it by running `curl` several times. @@ -171,18 +217,38 @@ Log file created. To test data persistence, first stop the instance, detach the volume, and remove the instance: -```bash title="" + + +```bash title="unikraft" +unikraft instances stop http-python312-flask30-2h608 +unikraft instances delete http-python312-flask30-2h608 +``` + +```bash title="kraft" kraft cloud instance stop http-python312-flask30-2h608 kraft cloud volumes detach my-volume kraft cloud instance rm http-python312-flask30-2h608 ``` + + +The explicit volume detach command is only available in the legacy CLI. + Now start another instance and, like before, mount the same volume: -```bash title="" + + +```bash title="unikraft" +unikraft build . --output my-org/http-python312-flask30:latest +unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt my-org/http-python312-flask30:latest +``` + +```bash title="kraft" kraft cloud deploy -M 512 -p 443:8080 --volume my-volume:/mnt . ``` + + This should output something like: ```ansi title="" @@ -213,15 +279,25 @@ Log file created. 2024-02-24 08:20:58 ``` -### Cleaning up +## Cleaning up To clean up, first detach the volume from all instances and then remove it: -```bash title="" + + +```bash title="unikraft" +unikraft volumes delete +``` + +```bash title="kraft" kraft cloud volume detach kraft cloud volume remove ``` + + +The explicit volume detach command is only available in the legacy CLI. + ## Volume templates A volume template is a volume in the `TEMPLATE` state. diff --git a/pages/tutorials/docker-to-ukc.mdx b/pages/tutorials/docker-to-ukc.mdx index cd4d1e95..6ab744ae 100644 --- a/pages/tutorials/docker-to-ukc.mdx +++ b/pages/tutorials/docker-to-ukc.mdx @@ -12,18 +12,29 @@ They follow the same general pattern used in the [Unikraft Cloud example reposit ## Prerequisites -Make sure you have the [`kraft` CLI](/cli/install) installed. +Make sure you have the CLI installed. +Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). You also need a container runtime such as Docker because the `Dockerfile` builds the root filesystem. -Set your Unikraft Cloud access token and preferred metro before deploying: +Set your Unikraft Cloud credentials and preferred metro before deploying: -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + ## Use the upstream image The fastest way to get an existing container running on Unikraft Cloud is to keep its root filesystem as-is. @@ -72,7 +83,7 @@ cmd: ["/path/from-entrypoint", "arg1", "arg2"] In this first-pass `Kraftfile`: * `runtime: base-compat:latest` selects the generic compatibility runtime. -* `rootfs: ./Dockerfile` tells `kraft` to build the root filesystem from the `Dockerfile`. +* `rootfs: ./Dockerfile` tells the CLI to build the root filesystem from the `Dockerfile`. * `cmd: [...]` explicitly sets the process arguments that should run inside the instance. Replace the placeholder command with the exact values extracted from `docker image inspect`. @@ -89,13 +100,22 @@ Also note that instances run as `root` unless you explicitly switch users at run Run an initial deployment before optimizing anything. This confirms that the runtime, filesystem, and command line are valid. -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/docker-port:latest +unikraft run --metro=fra -p 443: -m 512MiB my-org/docker-port:latest +``` + +```bash title="kraft" kraft cloud deploy \ -p 443: \ -M 512Mi \ . ``` + + Replace [``](/platform/services) with the app's listen port. Take this value from the image documentation or from the `ExposedPorts` field you inspected earlier. @@ -223,7 +243,14 @@ This is the same shape used by examples such as [`node21-nextjs`](https://github After reducing the filesystem, deploy it with [`EROFS`](/tutorials/rootfs-formats) when possible. This often gives better cold-boot behaviour and lower memory pressure than `CPIO` for larger images. -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/docker-port:latest +unikraft run --metro=fra -p 443: -m 256MiB my-org/docker-port:latest +``` + +```bash title="kraft" kraft cloud deploy \ -p 443: \ -M 256Mi \ @@ -231,6 +258,8 @@ kraft cloud deploy \ . ``` + + Treat the memory value as a starting point. Tune it after the first successful deployment by looking at the actual boot behaviour and logs. @@ -241,7 +270,7 @@ Before calling the image minimized, check the following: * the `cmd` line uses the final executable path; * copy only runtime files into the final stage; * no package manager cache or compiler output remains; -* expose the instance port through `kraft cloud deploy -p`; +* expose the instance port through the CLI `-p` flag; * use [`EROFS`](/tutorials/rootfs-formats) unless you have a reason to stay on `CPIO`. ## More configurations @@ -251,7 +280,17 @@ Before calling the image minimized, check the following: If the upstream image depends on environment variables, you can optionally carry them over explicitly. The most reliable method at deployment time is to pass them through the CLI with `--env` or `-e`. -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/docker-port:latest +unikraft run --metro=fra -p 443: -m 256MiB \ + -e APP_ENV=production \ + -e LOG_LEVEL=info \ + my-org/docker-port:latest +``` + +```bash title="kraft" kraft cloud deploy \ -p 443: \ -M 256Mi \ @@ -261,6 +300,8 @@ kraft cloud deploy \ . ``` + + If the image expects a wrapper entrypoint that prepares environment variables before starting the main process, keep that wrapper in your `cmd` line or replace it with your own script. The [Environment Variables](/tutorials/environment-variables) tutorial describes the wrapper pattern in more detail. @@ -298,7 +339,17 @@ It tests whether the app can suspend cleanly and resume on the next request. The simplest way to test scale-to-zero is to deploy with an explicit scale-to-zero policy and a short cooldown: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/docker-port:latest +unikraft run --metro=fra -p 443: -m 256MiB \ + --scale-to-zero \ + --scale-to-zero-cooldown-time-ms=5000 \ + my-org/docker-port:latest +``` + +```bash title="kraft" kraft cloud deploy \ -p 443: \ -M 256Mi \ @@ -309,12 +360,22 @@ kraft cloud deploy \ . ``` + + After deployment, wait a few seconds and then list the instances: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + If everything is working, the instance should transition to `standby` when idle and wake up again on the next request. Apps with long initialization phases, background work, or long-lived connections may need extra adjustments before scale-to-zero behaves well. diff --git a/pages/tutorials/environment-variables.mdx b/pages/tutorials/environment-variables.mdx index 1d21be00..cfb9eed3 100644 --- a/pages/tutorials/environment-variables.mdx +++ b/pages/tutorials/environment-variables.mdx @@ -22,7 +22,7 @@ Please use the other methods described below in the meantime. ::: You can set environment variables in your `Dockerfile` using the `ENV` instruction in your target `FROM` stage. -The [`kraft` CLI](/cli/) automatically reads them when building the image and sets them in the resulting packaged image. +The CLI automatically reads them when building the image and sets them in the resulting packaged image. ```dockerfile # ... @@ -35,7 +35,7 @@ ENV MY_ENV_VAR=my_value :::caution At the moment environment variables from the `Kraftfile` are passed in the image but not read by the Unikraft Cloud platform. -Nonetheless, `kraft cloud deploy` can still read them and set them in the instance. +Nonetheless, the legacy deploy command can still read them and set them in the instance. For other use cases, please use the other methods described below in the meantime. ::: @@ -55,14 +55,22 @@ It will override environment variables with the same name set in the `Dockerfile ### Kraft flags -When deploying an instance using the `kraft cloud deploy` or `kraft cloud instance create` commands, you can pass environment variables using the `--env` (or `-e`) flag. +When deploying an instance, you can pass environment variables using the `--env` (or `-e`) flag. You can specify many environment variables by using the flag many times. The flag works similarly to the `docker run -e` flag. -```bash + + +```bash title="unikraft" +unikraft run --metro=fra -e MY_ENV_VAR=my_value my-app:latest +``` + +```bash title="kraft" kraft cloud deploy my-app --env MY_ENV_VAR=my_value ``` + + :::tip This method takes precedence over the `Dockerfile` and `Kraftfile`. It will override environment variables with the same name set in the previous two methods. @@ -113,10 +121,10 @@ Thus it's recommended to do this only for variables that you set and don't chang ## Conclusion Out of the four ways to set environment variables in Unikraft Cloud instances you should pick the ones that work best for you. -Consider that the `Dockerfile` and `Kraftfile` can set variables for the image itself, while the `kraft` CLI and wrapper script set them at runtime. +Consider that the `Dockerfile` and `Kraftfile` can set variables for the image itself, while the CLI and wrapper script set them at runtime. ## Learn more -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). * The [Dockerfile reference](https://docs.docker.com/reference/dockerfile/) for understanding how to set environment variables in Dockerfiles. * The [Kraftfile reference](https://unikraft.org/docs/cli/reference/kraftfile) for understanding how to set environment variables in Kraftfiles. diff --git a/pages/tutorials/instance-metrics.mdx b/pages/tutorials/instance-metrics.mdx index 7eb6f5ee..fe86778e 100644 --- a/pages/tutorials/instance-metrics.mdx +++ b/pages/tutorials/instance-metrics.mdx @@ -22,14 +22,24 @@ Use a tool like `curl` for ad-hoc queries, or configure your monitoring system t The following example creates an instance and retrieves its metrics using `curl`. -First, provision a new instance (set `$UKC_TOKEN` and `$UKC_METRO` as appropriate): +First, provision a new instance: -```bash title="" + + +```bash title="unikraft" +git clone https://github.com/unikraft-cloud/examples +cd examples/nginx/ +unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB nginx:latest +``` + +```bash title="kraft" git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ kraft cloud deploy -p 443:8080 -M 256 . ``` + + This command will create the NGINX instance with scale-to-zero enabled: ```ansi title="" @@ -48,7 +58,8 @@ This command will create the NGINX instance with scale-to-zero enabled: β””────────── args: /usr/bin/nginx -c /etc/nginx/nginx.conf ``` -Now, request the metrics for that instance: +Now, request the metrics for that instance. +Set `UKC_TOKEN` and `UKC_METRO` for the API call (the `unikraft` CLI uses profiles instead). @@ -398,4 +409,4 @@ The Prometheus format lets you plug these metrics directly into monitoring tools * [Scale to zero](/features/scale-to-zero) and how it affects instance lifecycle. * [Scale to zero triggers](/tutorials/scale-to-zero-triggers) for controlling when instances wake up. * [Platform instances](/platform/instances) for managing and inspecting your instances. -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [instance create](/cli/instance/create) subcommand. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). diff --git a/pages/tutorials/network-communication.mdx b/pages/tutorials/network-communication.mdx index f6ee1383..55fd3cd7 100644 --- a/pages/tutorials/network-communication.mdx +++ b/pages/tutorials/network-communication.mdx @@ -36,7 +36,7 @@ This communication is best suited for service-to-service communication, microser For example, you wouldn't want to expose your database publicly, but you would want your app to be able to connect to it internally. :::note -When using [`kraft cloud tunnel`](/cli/tunnel) to connect to your instances you are using the internal network to reach your instance. +When using the legacy CLI tunnel command to connect to your instances you are using the internal network to reach your instance. The command creates a public-facing instance that tunnels your requests to the private instance over the internal network. This is a good way to keep your instances private while still being able to access them from your local machine. ::: @@ -52,4 +52,4 @@ By leveraging both types of communication, you can deploy a robust and efficient * [Load balancing](/features/load-balancing) of services. * [Platform services](/platform/services) and how they work. * [Scale to zero triggers](/tutorials/scale-to-zero-triggers) for automatic instance scaling. -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [tunnel](/cli/tunnel) subcommand. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). diff --git a/pages/tutorials/rootfs-compression.mdx b/pages/tutorials/rootfs-compression.mdx index 2c489a57..011d5259 100644 --- a/pages/tutorials/rootfs-compression.mdx +++ b/pages/tutorials/rootfs-compression.mdx @@ -32,23 +32,27 @@ Still, if many files aren't accessed in boot, the cold boot time might decrease ## Packaging a Compressed rootfs Packaging a compressed rootfs is different depending on the format used. -The [`kraft` CLI](/cli/) implements `CPIO` compression directly, while `EROFS` compression must happen externally using the `mkfs.erofs` tool. +The legacy [`kraft` CLI](https://unikraft.org/docs/cli/install) implements `CPIO` compression directly, while `EROFS` compression must happen externally using the `mkfs.erofs` tool. ### CPIO Compression -To package a compressed `CPIO` rootfs using `kraft`, you can use the `--compress` flag when running the `kraft pkg` or `kraft cloud deploy` command. +To package a compressed `CPIO` rootfs using the legacy CLI, you can use the `--compress` flag when running the `kraft pkg` or `kraft cloud deploy` command. This uses `gzip` compression to compress the initrd file before packaging it into a `OCI` image and uploading it to the Unikraft Cloud platform. -```bash + + +```bash title="kraft" kraft cloud deploy \ --rootfs-type cpio \ --compress \ ... ``` + + ### EROFS Compression -Currently, `kraft` has no direct support for compressing `EROFS` rootfses. +Currently, the legacy CLI has no direct support for compressing `EROFS` rootfses. To package a compressed `EROFS` rootfs, you need to use the `mkfs.erofs` tool before packaging it with `kraft`. To do this you will also have to first export the image built from the `Dockerfile` into a `tar` archive: @@ -65,14 +69,18 @@ In this example the level is `9` (maximum) and the algorithm is `lz4hc` (high co mkfs.erofs --all-root -b 4096 -d2 -E noinline_data -z lz4hc,9 rootfs.erofs --tar=rootfs rootfs.tar ``` -Finally, you can package and deploy the compressed EROFS rootfs using kraft: +Finally, you can package and deploy the compressed EROFS rootfs using the legacy CLI: -```bash + + +```bash title="kraft" kraft cloud deploy \ --rootfs-type erofs \ --rootfs ./rootfs.erofs \ ... ``` + + ## Performance of Compressed rootfs vs. Uncompressed rootfs Images To illustrate the performance differences between compressed and uncompressed rootfses, below you can see the same [`node-22` image](https://github.com/unikraft-cloud/examples/tree/main/node-playwright-chromium) packaged and deployed four times: @@ -174,5 +182,5 @@ If limited by size constraints, try using compressed `EROFS` rootfses with a fas * The [rootfs formats tutorial](/tutorials/rootfs-formats) for understanding the differences between `CPIO` and `EROFS`. * The [`mkfs.erofs` documentation](https://man.archlinux.org/man/extra/erofs-utils/mkfs.erofs.1.en) for more information on creating compressed `EROFS` file systems. -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). * The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. diff --git a/pages/tutorials/rootfs-formats.mdx b/pages/tutorials/rootfs-formats.mdx index 8255b199..7df3c536 100644 --- a/pages/tutorials/rootfs-formats.mdx +++ b/pages/tutorials/rootfs-formats.mdx @@ -39,7 +39,7 @@ Finally, `DAX` enables sharing the same rootfs image between many instances, inc ## Packaging the Rootfs -The [KraftKit CLI tool](/cli/) supports both formats out of the box. +The [unikraft CLI tool](/docs/cli/unikraft) supports both formats out of the box. With it, you can package a rootfs from these sources: - a simple file - a directory @@ -59,7 +59,9 @@ Below are two attempts at creating and starting an instance from the same [image ### EROFS deployment -```bash + + +```bash title="kraft" kraft cloud deploy \ -p 443:8080 \ -M 900Mi \ @@ -68,6 +70,8 @@ kraft cloud deploy \ demo/node-playwright-chromium ``` + + ```ansi title="Create Instance EROFS" [●] Deployed successfully! β”‚ @@ -86,7 +90,9 @@ kraft cloud deploy \ ### CPIO deployment -```bash + + +```bash title="kraft" kraft cloud deploy \ -p 443:8080 \ -M 900Mi \ @@ -94,6 +100,8 @@ kraft cloud deploy \ demo/node-playwright-chromium ``` + + ```ansi title="Create Instance CPIO" [●] Deployed successfully! β”‚ @@ -124,5 +132,5 @@ Bottom-line is, using `EROFS` is recommended in every case where possible, as th ## Learn more -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). * The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. diff --git a/pages/tutorials/rootfs-volumes-roms.mdx b/pages/tutorials/rootfs-volumes-roms.mdx index 59215093..e4d5fece 100644 --- a/pages/tutorials/rootfs-volumes-roms.mdx +++ b/pages/tutorials/rootfs-volumes-roms.mdx @@ -24,7 +24,7 @@ For persistent storage, consider using [volumes](/platform/volumes) instead. A rootfs can be of two types: `CPIO` or `EROFS`. Each type has its own advantages and disadvantages, but overall `EROFS` is better suited for Unikraft Cloud. The [rootfs formats](/tutorials/rootfs-formats) documentation page details both types. -You can create a rootfs with the [`kraft` CLI](/cli/) for both types, for example: +You can create a rootfs with the legacy [`kraft` CLI](https://unikraft.org/docs/cli/install) for both types, for example (legacy CLI only): @@ -60,22 +60,43 @@ They're automatically mounted in the instance at the specified path either `RW` They're backed up on SSD (Solid State Drive) disks and offer redundancy without compromising on access latency. As such you can use them for persistent data, secrets, storage, logs, and more, and you can share them between instances. -To create and use a volume, you can use the `kraft cloud volume` commands. +To create and use a volume, you can use the CLI volume commands. For example, you need to first create a volume: -```bash title="Creating a Volume" + + +```bash title="unikraft" +unikraft volumes create \ + --set name=my-volume \ + --set size=100 \ + --set metro=fra +``` + +```bash title="kraft" kraft cloud volume create --size 100 --name my-volume ``` + + Then you can optionally populate it with local data: -```bash title="Importing Data into Volume" + + +```bash title="kraft" kraft cloud volume import --volume my-volume --source my-data/ ``` + + Finally, when you deploy an instance you can attach the volume to it: -```bash title="Attaching Volume to Instance" + + +```bash title="unikraft" +unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt my-app:latest +``` + +```bash title="kraft" kraft cloud deploy \ -M 512 \ -p 443:8080 \ @@ -83,6 +104,8 @@ kraft cloud deploy \ . ``` + + ### ROMs [ROMs](/features/roms) are an extension of the rootfs concept and a good way to customize generic rootfses for many instances. @@ -176,5 +199,5 @@ ROMs are a flexible way to customize rootfses, but you should also keep them sma * [Volumes](/platform/volumes) and how to use them. * [Rootfs formats](/tutorials/rootfs-formats) and how to create them. -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* The legacy [CLI reference](/docs/cli/kraft/overview). * The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. diff --git a/pages/tutorials/scale-to-zero-triggers.mdx b/pages/tutorials/scale-to-zero-triggers.mdx index 029b98e1..3145cc46 100644 --- a/pages/tutorials/scale-to-zero-triggers.mdx +++ b/pages/tutorials/scale-to-zero-triggers.mdx @@ -21,7 +21,7 @@ You can also configure scale-to-zero to consider idle active connections when de When you enable this trigger, Unikraft Cloud will track incoming connections to your instance. If there is no traffic for the configured duration, the instance scales down to zero. -You can use the [`kraft` CLI tool](/cli/) or the [API](/api/platform/v1/instances#create-instance) to enable this trigger: +You can use the legacy CLI tool or the [API](/api/platform/v1/instances#create-instance) to enable this trigger: @@ -54,7 +54,7 @@ kraft cloud instance create \ When enabling this trigger, the platform will consider all active connections to your instance, so all traffic going to them. The instance will scale down if you make no new network connections and all existing connections have been idle for the configured duration. -You can enable this trigger using the [`kraft` CLI tool](/cli/) or the [API](/api/platform/v1/instances#create-instance) as follows: +You can enable this trigger using the legacy CLI tool or the [API](/api/platform/v1/instances#create-instance) as follows: @@ -101,7 +101,8 @@ You can use the Unikraft Cloud API to manually scale down an instance. You will have to use the `/instances/suspend` endpoint to scale down an instance. This happens instantly, regardless of the configured automatic triggers. -First, set the required environment variables: +First, set the required environment variables. +These are for the API call and the legacy CLI, not the `unikraft` profile system: ```bash # Set Unikraft Cloud access token @@ -140,4 +141,4 @@ Once your app is ready to serve requests, you can write '-' to the file to re-en ## Learn more * The [Scale To Zero](/features/scale-to-zero) feature page. -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [instance create](/cli/instance/create) subcommand. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). diff --git a/pages/use-cases/api-gateways.mdx b/pages/use-cases/api-gateways.mdx index 01cb872c..13ea88ba 100644 --- a/pages/use-cases/api-gateways.mdx +++ b/pages/use-cases/api-gateways.mdx @@ -68,22 +68,37 @@ git clone https://github.com/unikraft-cloud/examples cd examples/tyk/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash title="" + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` -Then invoke: + -```bash title="" +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + +Then invoke. +Compose is only available in the legacy CLI: + + + +```bash title="kraft" kraft cloud compose up ``` + + After deploying, you can query the service using the provided address. Use the `/hello` path after the address, such as below: @@ -109,8 +124,16 @@ curl https:///hello | jq Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/use-cases/headless-browsers.mdx b/pages/use-cases/headless-browsers.mdx index 2ff44729..2c5a24ef 100644 --- a/pages/use-cases/headless-browsers.mdx +++ b/pages/use-cases/headless-browsers.mdx @@ -3,8 +3,6 @@ title: Headless Browsers navigation_icon: app-window --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - Headless browsers power web scraping, automated testing, Search Engine Optimization (SEO) rendering, and synthetic monitoring. They're resource-intensive, security-sensitive, and often run in short burstsβ€”making them ideal candidates for microVM-based, scale-to-zero infrastructure. @@ -52,7 +50,8 @@ option to run them headless (no UI). To run it, follow these steps: -1. Install the [`kraft` CLI tool](https://unikraft.org/docs/cli/install) and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)). +1. Install the CLI and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node-express-puppeteer/` directory: @@ -61,16 +60,26 @@ git clone https://github.com/unikraft-cloud/examples cd examples/node-express-puppeteer/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + :::note A Puppeteer instance on Unikraft Cloud requires 4GB to run. @@ -80,10 +89,19 @@ Request an increase in the instance memory quota when you need more memory. When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft build . --output my-org/node-express-puppeteer:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 4Gi my-org/node-express-puppeteer:latest +``` + +```bash title="kraft" kraft cloud deploy -p 443:3000 -M 4Gi . ``` + + The output shows the instance address and other details: ```ansi @@ -112,10 +130,18 @@ You can use the landing page to generate the PDF version of a remote page. At any time, you can list information about the instance: -```bash + + +```bash title="unikraft" +unikraft instances list node-express-puppeteer-7afg3 +``` + +```bash title="kraft" kraft cloud instance list node-express-puppeteer-7afg3 ``` + + ```text NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME node-express-puppeteer-7afg3 node-express-puppeteer-7afg3.fra.unikraft.app running since 6mins node-express-puppeteer-7afg3@s... 4.0 GiB /usr/bin/wrapper.sh /usr/bin/n... 15.27 ms @@ -123,10 +149,18 @@ node-express-puppeteer-7afg3 node-express-puppeteer-7afg3.fra.unikraft.app run When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete node-express-puppeteer-7afg3 +``` + +```bash title="kraft" kraft cloud instance remove node-express-puppeteer-7afg3 ``` + + ### Customize your deployment The current deployment uses an ExpressJS service that uses the [PDF generating functionality of Puppeteer](https://devdocs.io/puppeteer/). @@ -137,8 +171,16 @@ You can update the service itself to provide a Representational State Transfer ( Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/use-cases/mcp-servers.mdx b/pages/use-cases/mcp-servers.mdx index 72ae53d5..ac96568f 100644 --- a/pages/use-cases/mcp-servers.mdx +++ b/pages/use-cases/mcp-servers.mdx @@ -194,11 +194,19 @@ Unikraft Cloud's instant deployment and scale-to-zero model makes it ideal for h Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). For more information about the Model Context Protocol: diff --git a/pages/use-cases/remote-ides.mdx b/pages/use-cases/remote-ides.mdx index 209cbca1..c6bbc5f3 100644 --- a/pages/use-cases/remote-ides.mdx +++ b/pages/use-cases/remote-ides.mdx @@ -57,19 +57,39 @@ git clone https://github.com/unikraft-cloud/examples cd examples/code-server/ ``` -Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ). +The deployment commands below use the legacy CLI: -```bash + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra ``` + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + When done, invoke the following command to deploy this app on Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft volumes create \ + --set name=code-workspace \ + --set size=1024 \ + --set metro=fra +``` + +```bash title="kraft" kraft cloud volume create \ --name code-workspace \ --size 1Gi @@ -90,24 +110,42 @@ kraft cloud deploy \ . ``` + + Now, you can access the Code Server in the browser, at the provided address. ### Volume This deployment creates a volume for data persistence: `code-workspace`. -Upon deleting the instance (for example, `kraft cloud instance rm code-server`), this volume will persist, allowing you to create another instance without losing data. +Upon deleting the instance, this volume will persist, allowing you to create another instance without losing data. To remove the volume, you can use: -```bash + + +```bash title="unikraft" +unikraft volumes delete code-workspace +``` + +```bash title="kraft" kraft cloud volume rm code-workspace ``` + + ## Learn more Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/use-cases/serverless-databases.mdx b/pages/use-cases/serverless-databases.mdx index ef88d1ff..348a4cc8 100644 --- a/pages/use-cases/serverless-databases.mdx +++ b/pages/use-cases/serverless-databases.mdx @@ -3,8 +3,6 @@ title: Serverless Databases navigation_icon: database-zap --- -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - Databases are central to modern apps, but they're notoriously resource-hungry, slow to scale, and costly to operate at low utilisation. Traditional VM- or container-based solutions keep idle resources running, resulting in waste and inefficiency. With **Unikraft Cloud**, serverless databases gain the advantages of **microVMs**, combining **extreme performance** with **true scale-to-zero efficiency**. @@ -58,19 +56,25 @@ cd examples/postgres/ Make sure to log into Unikraft Cloud by setting your token and a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash + + +```bash title="unikraft" +unikraft login +unikraft build . --output my-org/postgres:latest +unikraft run --metro=fra -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -m 1Gi my-org/postgres:latest +``` + +```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token # Set metro to Frankfurt, DE export UKC_METRO=fra +kraft cloud deploy -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -M 1Gi . ``` -When done, invoke the following command to deploy this app on Unikraft -Cloud: + -```bash -kraft cloud deploy -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -M 1Gi . -``` +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. The output shows the instance address and other details: @@ -125,7 +129,7 @@ You can see this in action by running `SELECT pg_sleep(10);` and verifying that ::: :::note -If you'd like to use a port other than `5432/tls`, you'll need to use the [`kraft cloud tunnel`](/cli/tunnel) command to connect to Postgres. +If you'd like to use a port other than `5432/tls`, you'll need to use the legacy CLI tunnel command to connect to Postgres. You need to explicitly disable scale-to-zero. You can do this by either changing the label in the `Kraftfile` or by using `--scale-to-zero off` in the deploy command. @@ -133,10 +137,18 @@ You can do this by either changing the label in the `Kraftfile` or by using `--s At any time, you can list information about the instance: -```bash + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" kraft cloud instance list ``` + + ```text NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME postgres-saan9 young-thunder-fbafrsxj.fra.unikraft.app running 6 minutes ago postgres@sha256:2476c0373d663d7604d... 1.0 GiB wrapper.sh docker-entrypoint.sh postgres 603.42 ms @@ -144,26 +156,54 @@ postgres-saan9 young-thunder-fbafrsxj.fra.unikraft.app running 6 minutes ag When done, you can remove the instance: -```bash + + +```bash title="unikraft" +unikraft instances delete postgres-saan9 +``` + +```bash title="kraft" kraft cloud instance remove postgres-saan9 ``` + + ### Using volumes You can use [volumes](/platform/volumes) for data persistence for your PostgreSQL instance. For that you would first create a volume: -```console + + +```console title="unikraft" +unikraft volumes create \ + --set name=postgres \ + --set size=200 \ + --set metro=fra +``` + +```console title="kraft" kraft cloud volume create --name postgres --size 200 ``` + + Then start the PostgreSQL instance and mount that volume: -```console + + +```console title="unikraft" +unikraft build . --output my-org/postgres:latest +unikraft run --metro=fra -p 5432:5432/tls -m 1Gi -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume my-org/postgres:latest +``` + +```console title="kraft" kraft cloud deploy -p 5432:5432/tls -M 1Gi -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume . ``` + + ### Customize your deployment Your deployment is a standard PostgreSQL installation. @@ -188,8 +228,16 @@ Support for scale-to-zero for internal instances is coming soon. Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/use-cases/webhooks.mdx b/pages/use-cases/webhooks.mdx index 662aa15d..30de8dcb 100644 --- a/pages/use-cases/webhooks.mdx +++ b/pages/use-cases/webhooks.mdx @@ -93,11 +93,19 @@ Also follow [Webhooks.fyi](https://webhooks.fyi/) for best practices. Use the `--help` option for detailed information on using Unikraft Cloud: -```bash + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" kraft cloud --help ``` -Or visit the [CLI Reference](/cli). + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). For more information, check out these resources: From 02041fd74427e4ecf4496e6349b850e84760ada7 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 31 Mar 2026 21:54:59 +0300 Subject: [PATCH 078/131] feat: Add guides overview page Signed-off-by: Alex-Andrei Cioc --- .../config/vocabularies/Unikraft/accept.txt | 2 + pages/guides/overview.mdx | 123 ++++++++++++++++++ scripts/transform_readme.py | 18 ++- 3 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 pages/guides/overview.mdx diff --git a/.vale/styles/config/vocabularies/Unikraft/accept.txt b/.vale/styles/config/vocabularies/Unikraft/accept.txt index 151fe038..7cd3a654 100644 --- a/.vale/styles/config/vocabularies/Unikraft/accept.txt +++ b/.vale/styles/config/vocabularies/Unikraft/accept.txt @@ -56,6 +56,8 @@ PV PVC EROFS CPIO +CDP +FTP # ============================================================================== # NAMES OF THINGS diff --git a/pages/guides/overview.mdx b/pages/guides/overview.mdx new file mode 100644 index 00000000..46f68b1c --- /dev/null +++ b/pages/guides/overview.mdx @@ -0,0 +1,123 @@ +--- +title: Guides +navigation_icon: book-open-text +--- + +This section contains step-by-step guides for deploying popular languages, frameworks, databases, and tools on Unikraft Cloud. + +Every guide points to a ready-to-run example in the **[`unikraft-cloud/examples`](https://github.com/unikraft-cloud/examples)** repository on GitHub. +Clone it once and you'll have all examples at your fingertips: + +```bash +git clone https://github.com/unikraft-cloud/examples +``` + +Each example directory contains a `Kraftfile` and a `Dockerfile` that are the only files you need to deploy. +Refer to the individual guide for the exact `kraft cloud deploy` command and a walkthrough of the configuration. + +## Languages & runtimes + +| Guide | Runtime | +|---|---| +| [Bun](/guides/bun) | Bun | +| [C (HTTP debug server)](/guides/http-c-debug) | GCC / C | +| [C++ (Boost)](/guides/httpserver-boost1.74-g++13.2) | g++ 13.2 / Boost 1.74 | +| [C++ (g++)](/guides/httpserver-g++13.2) | g++ 13.2 | +| [C++ (gcc)](/guides/httpserver-gcc13.2) | GCC 13.2 | +| [Elixir 1.16](/guides/httpserver-elixir1.16) | Elixir 1.16 | +| [Elixir 1.17](/guides/http-elixir1.17) | Elixir 1.17 | +| [Erlang 26.2](/guides/httpserver-erlang26.2) | Erlang 26.2 | +| [Go 1.21](/guides/httpserver-go1.21) | Go 1.21 | +| [Java 17](/guides/httpserver-java17) | Java 17 | +| [Java 21](/guides/http-java21) | Java 21 | +| [Lua 5.1](/guides/httpserver-lua5.1) | Lua 5.1 | +| [.NET 8.0](/guides/httpserver-dotnet8.0) | .NET 8.0 | +| [Node.js 21](/guides/httpserver-nodejs21) | Node.js 21 | +| [Node.js 25](/guides/http-node25) | Node.js 25 | +| [Perl 5.38](/guides/httpserver-perl5.38) | Perl 5.38 | +| [Perl 5.42](/guides/http-perl5.42) | Perl 5.42 | +| [PHP 8.2](/guides/httpserver-php8.2) | PHP 8.2 | +| [Python 3.12](/guides/httpserver-python3.12) | Python 3.12 | +| [Ruby 3.2](/guides/httpserver-ruby3.2) | Ruby 3.2 | +| [Rust 1.73](/guides/httpserver-rust1.73) | Rust 1.73 | +| [Rust 1.75](/guides/httpserver-rust1.75) | Rust 1.75 | +| [Rust 1.79 (Axum, scale-to-zero)](/guides/http-rust-1.79-axum-scale-to-zero) | Rust 1.79 / Axum | +| [Rust 1.81 (Rocket)](/guides/httpserver-rust1.81-rocket0.5) | Rust 1.81 / Rocket 0.5 | +| [Rust 1.87 (Actix Web)](/guides/httpserver-rust1.87-actix-web4) | Rust 1.87 / Actix Web 4 | +| [Rust 1.91](/guides/http-rust1.91) | Rust 1.91 | +| [Wazero (Go / WASM)](/guides/wazero-import-go) | Wazero / Go | +| [WebAssembly (Spin / WAGI)](/guides/spin-wagi-http) | Spin / WAGI | + +## Frameworks & full-stack apps + +| Guide | Stack | +|---|---| +| [AllKaraoke (Node 24)](/guides/node24-karaoke) | Node.js 24 | +| [Django 5.0](/guides/httpserver-python3.12-django5.0) | Python 3.12 / Django 5.0 | +| [Express.js 4.18](/guides/expressjs4.18-node21) | Node.js 21 / Express 4.18 | +| [Express.js 4.19 + Prisma](/guides/prisma-expressjs4.19-node18) | Node.js 18 / Prisma | +| [FastAPI 0.121](/guides/http-python3.12-FastAPI-0.121.3) | Python 3.12 / FastAPI | +| [Flask 3.0 + Python 3.12 + SQLite](/guides/flask3.0-python3.12-sqlite3) | Python 3.12 / Flask 3.0 | +| [Flask 3.0 + SQLite](/guides/python3.12-flask3.0-sqlite) | Python 3.12 / Flask 3.0 | +| [Flask + Redis](/guides/database-redis7.2) | Python / Flask / Redis 7.2 | +| [Hugo 0.122](/guides/hugo0.122) | Hugo 0.122 | +| [Next.js (Node 21)](/guides/node21-nextjs) | Node.js 21 / Next.js | +| [Puppeteer (Node)](/guides/node-express-puppeteer) | Node.js / Puppeteer | +| [Rails (Ruby 3.2)](/guides/ruby3.2-rails) | Ruby 3.2 / Rails | +| [Remix (Node 21)](/guides/node21-remix) | Node.js 21 / Remix | +| [SolidStart (Node 21)](/guides/node21-solid-start) | Node.js 21 / SolidStart | +| [Spring Boot 3.2 (Java 17)](/guides/java17-springboot3.2.x) | Java 17 / Spring Boot 3.2 | +| [SvelteKit (Node 21)](/guides/node21-sveltekit) | Node.js 21 / SvelteKit | +| [Vite + nginx](/guides/nginx-vite-vanilla) | Node.js / Vite / nginx | +| [Webhook handler (GitHub / Node)](/guides/webhook-github-node) | Node.js | +| [WordPress (all-in-one)](/guides/wordpress-all-in-one) | WordPress / PHP | + +## Databases & storage + +| Guide | Technology | +|---|---| +| [DragonflyDB](/guides/dragonflydb) | DragonflyDB | +| [DuckDB (Go 1.21)](/guides/duckdb-go1.21) | Go 1.21 / DuckDB | +| [MariaDB](/guides/mariadb) | MariaDB | +| [Memcached 1.6](/guides/memcached1.6) | Memcached 1.6 | +| [MinIO](/guides/minio) | MinIO | +| [MongoDB](/guides/mongodb) | MongoDB | +| [PostgreSQL](/guides/postgres) | PostgreSQL | +| [Redis 7.2](/guides/database-redis7.2) | Redis 7.2 | + +## Networking & infrastructure + +| Guide | Technology | +|---|---| +| [Caddy 2.7 (Go 1.21)](/guides/caddy2.7-go1.21) | Caddy 2.7 | +| [Grafana](/guides/grafana) | Grafana | +| [HAProxy](/guides/haproxy) | HAProxy | +| [nginx](/guides/nginx) | nginx | +| [OpenTelemetry Collector](/guides/opentelemetry-collector) | OpenTelemetry | +| [Skipper 0.18](/guides/skipper0.18) | Skipper 0.18 | +| [Traefik](/guides/traefik) | Traefik | +| [vsftpd](/guides/vsftpd) | vsftpd | + +## AI & LLMs + +| Guide | Technology | +|---|---| +| [MCP server (arXiv)](/guides/mcp-server-arxiv) | Node.js / MCP | +| [MCP server (simple)](/guides/mcp-server-simple) | Node.js / MCP | + +## Developer tools & utilities + +| Guide | Technology | +|---|---| +| [Chromium (Chrome DevTools Protocol)](/guides/chromium-cdp) | Chromium / CDP | +| [code-server](/guides/code-server) | VS Code in the browser | +| [Debian SSH](/guides/debian-ssh) | Debian / SSH | +| [Imaginary](/guides/imaginary) | Imaginary | +| [noVNC](/guides/vnc-browser) | Virtual Network Computing (VNC) | + +## Learn more + +- **[`unikraft-cloud/examples` on GitHub](https://github.com/unikraft-cloud/examples)**: browse all example source files +- [Tutorials](/tutorials/): deeper dives into specific Unikraft Cloud capabilities +- [Use cases](/use-cases/): architecture patterns and production scenarios +- [CLI Reference](/cli/): full `kraft` CLI documentation diff --git a/scripts/transform_readme.py b/scripts/transform_readme.py index 53d447ca..b7fb1cab 100755 --- a/scripts/transform_readme.py +++ b/scripts/transform_readme.py @@ -26,6 +26,12 @@ ANSI_BOLD = '\x1b[1m' ANSI_DARK_GRAY = '\x1b[90m' ANSI_GREEN = '\x1b[92m' +ANSI_LIGHT_BLUE = '\x1b[94m' + +STATE_COLORS: dict[str, str] = { + "running": ANSI_GREEN, + "standby": ANSI_LIGHT_BLUE, +} # Import statement for Tabs component TABS_IMPORT = 'import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs"\n\n' @@ -143,7 +149,7 @@ def color_box_drawing_line(line: str) -> str: # Color the label in dark gray (but not the colon) label_colored = f'{ANSI_DARK_GRAY}{label}{ANSI_RESET}{colon}' - # Check if this is the state line and color the value in green + # Check if this is the state line and color the value if 'state' in label.lower(): # Color the state value (first word after colon and spaces) value_match = re.search(r'^(\s*)(\S+)(.*)$', value) @@ -151,7 +157,8 @@ def color_box_drawing_line(line: str) -> str: value_spaces = value_match.group(1) state_value = value_match.group(2) rest = value_match.group(3) - value = f'{value_spaces}{ANSI_GREEN}{state_value}{ANSI_RESET}{rest}' + color = STATE_COLORS.get(state_value.lower(), ANSI_GREEN) + value = f'{value_spaces}{color}{state_value}{ANSI_RESET}{rest}' return leading_space + box_colored + dashes_colored + label_colored + value else: @@ -245,8 +252,9 @@ def color_state_value_in_row(line: str, state_col: int) -> str: if len(cols) > state_col: raw_val = cols[state_col] val = raw_val.strip() - if val and ANSI_GREEN not in val: - colored = f"{ANSI_GREEN}{val}{ANSI_RESET}" + if val and ANSI_GREEN not in val and ANSI_LIGHT_BLUE not in val: + color = STATE_COLORS.get(val.lower(), ANSI_GREEN) + colored = f"{color}{val}{ANSI_RESET}" cols[state_col] = raw_val.replace(val, colored, 1) # Reconstruct using original separators to preserve spacing @@ -259,7 +267,7 @@ def color_state_value_in_row(line: str, state_col: int) -> str: def color_state_in_table_blocks(text: str) -> str: - """Color state values in table-style fenced blocks (STATE column) with light green.""" + """Color state values in table-style fenced blocks (STATE column) based on STATE_COLORS.""" def repl(m): fence_start = m.group(1) body = m.group(3) From 32eb7a02364a6094a8d620036ca9ce39927d8ba0 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Tue, 31 Mar 2026 10:42:50 +0100 Subject: [PATCH 079/131] ci: import setup-www action Signed-off-by: Justin Chadwell --- .github/actions/setup-www/action.yaml | 125 ++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 .github/actions/setup-www/action.yaml diff --git a/.github/actions/setup-www/action.yaml b/.github/actions/setup-www/action.yaml new file mode 100644 index 00000000..a6089a13 --- /dev/null +++ b/.github/actions/setup-www/action.yaml @@ -0,0 +1,125 @@ +name: setup-www + +description: | + Deploys the Unikraft landing and docs website (www). + +inputs: + environment: + required: true + description: The environment to use. + name: + required: true + description: Name of the service. + domain: + required: false + description: The domain to use for the deployment. + metro: + required: false + description: Unikraft Cloud Metro. + default: http://api.dal2.unikraft.cloud/v1 + memory: + required: false + description: Set the memory size. + default: 1Gi + args: + required: false + description: Optional arguments you pass to kraft cloud deploy. + port: + required: false + description: The port the service listens on. + default: "2015" + log-level: + required: false + default: error + description: Set the logging level. + posthog-host: + required: false + description: The host address for the PostHog API. + posthog-key: + required: false + description: The key to authenticate with PostHog. + +outputs: + domain: + description: | + Either the input domain if set or the automatically generated value + otherwise. + value: ${{ steps.service.outputs.domain }} + +runs: + using: composite + steps: + - name: Create Deployment + uses: bobheadxi/deployments@v1 + id: init-deploy + with: + step: start + token: ${{ github.token }} + env: ${{ inputs.environment }} + + - name: Create Service Group + id: service + shell: bash + run: | + set -xe; + + # Create the service if it does not exist. + _SVC=$(kraft cloud --metro "${{ inputs.metro }}" service get "${{ inputs.name }}" -o raw | jq -r '.data.service_groups[].error') + if [[ "${_SVC}" == "8" ]]; then + if [[ "${{ inputs.domain }}" == "" ]]; then + kraft cloud --metro "${{ inputs.metro }}" service create \ + --subdomain "${{ inputs.name }}" \ + --name "${{ inputs.name }}" \ + "443:${{ inputs.port }}" \ + ; + else + kraft cloud --metro "${{ inputs.metro }}" service create \ + --domain "${{ inputs.domain }}" \ + --name "${{ inputs.name }}" \ + "443:${{ inputs.port }}" \ + ; + fi + fi + + # Save the generated domain as an output variable + echo "domain=$(kraft cloud --metro ${{ inputs.metro }} service get ${{ inputs.name }} -o raw | jq -r '.data.service_groups[0].domains[0].fqdn')" >> $GITHUB_OUTPUT + + - name: Deploy + id: deploy + shell: bash + run: | + kraft cloud deploy \ + --rollout remove \ + --build-arg API_URL="https://${{ steps.service.outputs.domain }}" \ + --build-arg PUBLIC_API_URL="https://${{ steps.service.outputs.domain }}" \ + --build-arg VITE_PUBLIC_SITE_URL="https://${{ steps.service.outputs.domain }}" \ + --build-arg PUBLIC_STATUS_PAGE_SUMMARY_URL="https://status.unikraft.cloud/api/v1/summary" \ + --build-arg PUBLIC_POSTHOG_HOST="${{ inputs.posthog-host }}" \ + --build-arg PUBLIC_POSTHOG_KEY="${{ inputs.posthog-key }}" \ + --memory "${{ inputs.memory }}" \ + --service "${{ inputs.name }}" \ + --image "${{ inputs.name }}" \ + --as kraftfile-runtime \ + .; + + - name: Test liveliness + id: liveliness + continue-on-error: true + shell: bash + run: | + sleep 10; + curl -Lk --fail "https://${{ steps.service.outputs.domain }}/" + + - name: Dump instance logs on failure + if: ${{ steps.liveliness.outcome == 'failure' }} + shell: bash + run: | + kraft cloud service logs "${{ inputs.name }}" + exit 1 + + - name: Update Deployment + uses: bobheadxi/deployments@v1 + with: + step: start + token: ${{ github.token }} + env: ${{ inputs.environment }} From 6dee2da2d812f2aadf9d5374a9ea3ac43b92bd7f Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Mon, 30 Mar 2026 12:49:56 +0100 Subject: [PATCH 080/131] feat: Add PR preview Signed-off-by: Justin Chadwell --- .eslintrc.cjs | 35 + .github/actions/cleanup-www/action.yaml | 39 + .github/actions/setup-kraftkit/action.yaml | 17 + .github/actions/setup-www/action.yaml | 11 +- .github/workflows/pr-preview.yaml | 105 +- .github/workflows/prod-stable.yaml | 85 + .github/workflows/prod-staging.yaml | 85 + .gitignore | 40 + Caddyfile | 18 + Dockerfile | 64 + Kraftfile | 7 + apis/.gitkeep | 0 docker-compose.yaml | 7 + package-lock.json | 11871 +++++++++++++++++++ package.json | 26 + pages/cli/overview.mdx | 70 + public/logo-dark.svg | 29 + public/logo-light.svg | 29 + public/pagefind/pagefind.js | 1 + tsconfig.json | 16 + vite.config.ts | 6 + zudoku.config.tsx | 540 + 22 files changed, 13095 insertions(+), 6 deletions(-) create mode 100644 .eslintrc.cjs create mode 100644 .github/actions/cleanup-www/action.yaml create mode 100644 .github/actions/setup-kraftkit/action.yaml create mode 100644 .github/workflows/prod-stable.yaml create mode 100644 .github/workflows/prod-staging.yaml create mode 100644 Caddyfile create mode 100644 Dockerfile create mode 100644 Kraftfile create mode 100644 apis/.gitkeep create mode 100644 docker-compose.yaml create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 pages/cli/overview.mdx create mode 100644 public/logo-dark.svg create mode 100644 public/logo-light.svg create mode 100644 public/pagefind/pagefind.js create mode 100644 tsconfig.json create mode 100644 vite.config.ts create mode 100644 zudoku.config.tsx diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 00000000..bf021ee7 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,35 @@ +module.exports = { + env: { + browser: true, + es2021: true, + node: true, + }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended' + ], + overrides: [ + { + env: { + node: true + }, + files: [ + '.eslintrc.{js,cjs}', + 'scripts/**/*.js' + ], + parserOptions: { + sourceType: 'module' + } + } + ], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module' + }, + plugins: [ + '@typescript-eslint' + ], + rules: { + } +} diff --git a/.github/actions/cleanup-www/action.yaml b/.github/actions/cleanup-www/action.yaml new file mode 100644 index 00000000..142d6d14 --- /dev/null +++ b/.github/actions/cleanup-www/action.yaml @@ -0,0 +1,39 @@ +name: cleanup-www + +description: | + Destroys the Unikraft landing and docs website (www). + +inputs: + name: + required: true + description: Name of the service. + metro: + required: false + description: Unikraft Cloud Metro. + default: was1 + delete-image: + required: false + description: Also delete the image. + default: "false" + +runs: + using: composite + steps: + - name: Delete Service + if: always() + id: service + shell: bash + run: | + kraft cloud --metro "${{ inputs.metro }}" service remove \ + --drain \ + "${{ inputs.name }}" \ + ; + + - name: Delete Image + if: ${{ inputs.delete-image }} + id: image + shell: bash + run: | + kraft cloud --metro "${{ inputs.metro }}" image remove \ + "${{ inputs.name }}" \ + ; diff --git a/.github/actions/setup-kraftkit/action.yaml b/.github/actions/setup-kraftkit/action.yaml new file mode 100644 index 00000000..4f483832 --- /dev/null +++ b/.github/actions/setup-kraftkit/action.yaml @@ -0,0 +1,17 @@ +name: setup-kraftkit + +description: Setup KraftKit. + +runs: + using: composite + steps: + - name: Install + shell: bash + run: | + if [[ -z $(command -v kraft) ]]; then + _VERSION=$(curl https://get.kraftkit.sh/latest.txt); + wget -nv -LO kraft.tar.gz https://github.com/unikraft/kraftkit/releases/download/v${_VERSION}/kraft_${_VERSION}_linux_amd64.tar.gz; + tar xzf kraft.tar.gz kraft; + sudo mv kraft /usr/bin/; + rm kraft.tar.gz; + fi diff --git a/.github/actions/setup-www/action.yaml b/.github/actions/setup-www/action.yaml index a6089a13..f0122aa9 100644 --- a/.github/actions/setup-www/action.yaml +++ b/.github/actions/setup-www/action.yaml @@ -38,6 +38,10 @@ inputs: posthog-key: required: false description: The key to authenticate with PostHog. + docs-channel: + required: false + default: prod-staging + description: The docs channel to use for the OpenAPI spec. outputs: domain: @@ -61,7 +65,7 @@ runs: id: service shell: bash run: | - set -xe; + set -e; # Create the service if it does not exist. _SVC=$(kraft cloud --metro "${{ inputs.metro }}" service get "${{ inputs.name }}" -o raw | jq -r '.data.service_groups[].error') @@ -96,6 +100,7 @@ runs: --build-arg PUBLIC_STATUS_PAGE_SUMMARY_URL="https://status.unikraft.cloud/api/v1/summary" \ --build-arg PUBLIC_POSTHOG_HOST="${{ inputs.posthog-host }}" \ --build-arg PUBLIC_POSTHOG_KEY="${{ inputs.posthog-key }}" \ + --build-arg DOCS_CHANNEL="${{ inputs.docs-channel }}" \ --memory "${{ inputs.memory }}" \ --service "${{ inputs.name }}" \ --image "${{ inputs.name }}" \ @@ -120,6 +125,8 @@ runs: - name: Update Deployment uses: bobheadxi/deployments@v1 with: - step: start + step: finish token: ${{ github.token }} env: ${{ inputs.environment }} + deployment_id: ${{ steps.init-deploy.outputs.deployment_id }} + status: ${{ job.status }} diff --git a/.github/workflows/pr-preview.yaml b/.github/workflows/pr-preview.yaml index b9d087ab..ea7b74e3 100644 --- a/.github/workflows/pr-preview.yaml +++ b/.github/workflows/pr-preview.yaml @@ -10,14 +10,111 @@ on: branches: - prod-staging +# Automatically cancel in-progress actions on the same branch +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request_target' && github.head_ref || github.ref }} + cancel-in-progress: true + +env: + UKC_TOKEN: ${{ secrets.UKC_TOKEN }} + UKC_METRO: ${{ vars.UKC_METRO }} + KRAFTKIT_LOG_LEVEL: error + KRAFTKIT_NO_CHECK_UPDATES: "true" + permissions: deployments: write contents: read pull-requests: write jobs: - noop: - runs-on: ubuntu-latest + deploy: + environment: pull-requests + runs-on: arc-ubuntu24.04-big + if: ${{ github.event.action != 'closed' }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Validate required secrets + shell: bash + run: | + if [[ -z "${{ vars.UKC_METRO }}" ]]; then + echo "Missing UKC_METRO variable" >&2 + exit 1 + fi + + + - name: Setup KraftKit + uses: ./.github/actions/setup-kraftkit + + - name: Setup docs website + id: www + uses: ./.github/actions/setup-www + continue-on-error: true + with: + environment: pull-requests + name: com-docs-pr-${{ github.event.number }} + metro: ${{ vars.UKC_METRO }} + log-level: trace + docs-channel: prod-staging + + - uses: chrnorm/deployment-action@v2 + name: Create GitHub deployment + if: always() + id: pr-deploy-github + with: + token: '${{ github.token }}' + environment-url: 'https://${{ steps.www.outputs.domain }}' + environment: pull-requests + + - name: Update PR deployment status (success) + if: ${{ steps.www.outcome == 'success' }} + uses: chrnorm/deployment-status@v2 + with: + token: '${{ github.token }}' + environment-url: 'https://${{ steps.www.outputs.domain }}' + deployment-id: '${{ steps.pr-deploy-github.outputs.deployment_id }}' + state: 'success' + + - name: Update PR deployment status (failure) + if: ${{ steps.www.outcome == 'failure' }} + uses: chrnorm/deployment-status@v2 + with: + token: '${{ github.token }}' + environment-url: 'https://${{ steps.www.outputs.domain }}' + deployment-id: '${{ steps.pr-deploy-github.outputs.deployment_id }}' + state: 'failure' + + - name: Fail job if deploy failed + if: ${{ steps.www.outcome == 'failure' }} + shell: bash + run: | + exit 1 + + cleanup: + environment: pull-requests + runs-on: arc-ubuntu24.04-big + if: ${{ github.event.action == 'closed' }} steps: - - run: | - echo "pr/preview placeholder" + - name: Checkout + uses: actions/checkout@v4 + + - name: Validate required secrets + shell: bash + run: | + if [[ -z "${{ vars.UKC_METRO }}" ]]; then + echo "Missing UKC_METRO variable" >&2 + exit 1 + fi + + - name: Setup KraftKit + uses: ./.github/actions/setup-kraftkit + + - name: Cleanup deployment + id: cleanup-www + uses: ./.github/actions/cleanup-www + with: + name: com-docs-pr-${{ github.event.number }} + metro: ${{ vars.UKC_METRO }} + delete-image: true diff --git a/.github/workflows/prod-stable.yaml b/.github/workflows/prod-stable.yaml new file mode 100644 index 00000000..67ba4a05 --- /dev/null +++ b/.github/workflows/prod-stable.yaml @@ -0,0 +1,85 @@ +name: prod-stable + +on: + push: + branches: [prod-stable] + paths: + - '**' + - '!.github/workflows/**/*' + - '.github/workflows/prod-stable.yaml' + - '!README.md' + +env: + UKC_TOKEN: ${{ secrets.UKC_TOKEN }} + UKC_METRO: ${{ vars.UKC_METRO }} + KRAFTKIT_LOG_LEVEL: debug + KRAFTKIT_NO_CHECK_UPDATES: "true" + +permissions: + deployments: write + contents: read + +jobs: + deploy: + environment: prod-stable + runs-on: arc-ubuntu24.04-big + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Validate required secrets + shell: bash + run: | + if [[ -z "${{ vars.UKC_METRO }}" ]]; then + echo "Missing UKC_METRO variable" >&2 + exit 1 + fi + + + - name: Setup KraftKit + uses: ./.github/actions/setup-kraftkit + + - name: Setup docs website + id: www + uses: ./.github/actions/setup-www + continue-on-error: true + with: + environment: prod-stable + name: com-docs-stable + metro: ${{ vars.UKC_METRO }} + log-level: trace + docs-channel: prod-stable + + - uses: chrnorm/deployment-action@v2 + name: Create GitHub deployment + if: always() + id: deploy-github + with: + token: '${{ github.token }}' + environment-url: 'https://com-docs-stable.ukp-stable.apw.unikraft.internal' + environment: prod-stable + + - name: Update deployment status (success) + if: ${{ steps.www.outcome == 'success' }} + uses: chrnorm/deployment-status@v2 + with: + token: '${{ github.token }}' + environment-url: 'https://com-docs-stable.ukp-stable.apw.unikraft.internal' + deployment-id: '${{ steps.deploy-github.outputs.deployment_id }}' + state: 'success' + + - name: Update deployment status (failure) + if: ${{ steps.www.outcome == 'failure' }} + uses: chrnorm/deployment-status@v2 + with: + token: '${{ github.token }}' + environment-url: 'https://com-docs-stable.ukp-stable.apw.unikraft.internal' + deployment-id: '${{ steps.deploy-github.outputs.deployment_id }}' + state: 'failure' + + - name: Fail job if deploy failed + if: ${{ steps.www.outcome == 'failure' }} + shell: bash + run: | + exit 1 diff --git a/.github/workflows/prod-staging.yaml b/.github/workflows/prod-staging.yaml new file mode 100644 index 00000000..49d353d7 --- /dev/null +++ b/.github/workflows/prod-staging.yaml @@ -0,0 +1,85 @@ +name: prod-staging + +on: + push: + branches: [prod-staging] + paths: + - '**' + - '!.github/workflows/**/*' + - '.github/workflows/prod-staging.yaml' + - '!README.md' + +env: + UKC_TOKEN: ${{ secrets.UKC_TOKEN }} + UKC_METRO: ${{ vars.UKC_METRO }} + KRAFTKIT_LOG_LEVEL: debug + KRAFTKIT_NO_CHECK_UPDATES: "true" + +permissions: + deployments: write + contents: read + +jobs: + deploy: + environment: prod-staging + runs-on: arc-ubuntu24.04-big + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Validate required secrets + shell: bash + run: | + if [[ -z "${{ vars.UKC_METRO }}" ]]; then + echo "Missing UKC_METRO variable" >&2 + exit 1 + fi + + + - name: Setup KraftKit + uses: ./.github/actions/setup-kraftkit + + - name: Setup docs website + id: www + uses: ./.github/actions/setup-www + continue-on-error: true + with: + environment: prod-staging + name: com-docs-staging + metro: ${{ vars.UKC_METRO }} + log-level: trace + docs-channel: prod-staging + + - uses: chrnorm/deployment-action@v2 + name: Create GitHub deployment + if: always() + id: deploy-github + with: + token: '${{ github.token }}' + environment-url: 'https://com-docs-staging.ukp-stable.apw.unikraft.internal' + environment: prod-staging + + - name: Update deployment status (success) + if: ${{ steps.www.outcome == 'success' }} + uses: chrnorm/deployment-status@v2 + with: + token: '${{ github.token }}' + environment-url: 'https://com-docs-staging.ukp-stable.apw.unikraft.internal' + deployment-id: '${{ steps.deploy-github.outputs.deployment_id }}' + state: 'success' + + - name: Update deployment status (failure) + if: ${{ steps.www.outcome == 'failure' }} + uses: chrnorm/deployment-status@v2 + with: + token: '${{ github.token }}' + environment-url: 'https://com-docs-staging.ukp-stable.apw.unikraft.internal' + deployment-id: '${{ steps.deploy-github.outputs.deployment_id }}' + state: 'failure' + + - name: Fail job if deploy failed + if: ${{ steps.www.outcome == 'failure' }} + shell: bash + run: | + exit 1 diff --git a/.gitignore b/.gitignore index 119089b5..4dc3d799 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,43 @@ .vale/styles/* !.vale/styles/Unikraft/* !.vale/styles/config/vocabularies/Unikraft/accept.txt + +# Node/Zudoku +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# zudoku +/dist/ +/.zudoku/ + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# env files (can opt-in for commiting if needed) +.env* + +# typescript +*.tsbuildinfo + +# build outputs +dist/ + +# generated files +apis/platform.yaml +build.log diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 00000000..b8b8fb10 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,18 @@ +:2015 + +header { + Server "UnikraftCloud" +} + +redir / /docs + +handle /docs* { + root * /var/www + encode gzip + file_server + try_files {path}/index.html {path}.html {path} +} + +handle { + respond 404 +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..170632ed --- /dev/null +++ b/Dockerfile @@ -0,0 +1,64 @@ +# syntax=docker/dockerfile:1.7 + +################################################################################ +# Build kraft docs +################################################################################ +FROM golang:1.26 AS build-kraft-docs + +WORKDIR /kraftkit +ADD https://github.com/unikraft/kraftkit.git /kraftkit + +RUN make docs + +################################################################################ +# Build unikraft docs +################################################################################ +FROM golang:1.26 AS build-cli-docs + +WORKDIR /cli +ADD https://github.com/unikraft/cli.git /cli + +RUN make docs + +################################################################################ +# Dependencies + build +################################################################################ +FROM node:24-alpine AS build +WORKDIR /docs + +ENV CI=true + +RUN set -xe; \ + apk --no-cache add \ + ca-certificates \ + git \ + wget \ + ; + +COPY package.json package-lock.json ./ + +RUN npm ci + +COPY . . + +# Grab the latest OpenAPI spec based on the desired channel. +ARG DOCS_CHANNEL=prod-staging +RUN set -xe; \ + wget -O apis/platform.yaml https://raw.githubusercontent.com/unikraft-cloud/openapi/refs/heads/${DOCS_CHANNEL}/platform.yaml; + +# Kraft (old CLI) docs -> /cli/kraft/ +COPY --from=build-kraft-docs /kraftkit/docs/kraft/cloud /docs/pages/cli/kraft +COPY --from=build-kraft-docs /kraftkit/docs/kraft/cloud.mdx /docs/pages/cli/kraft/overview.mdx + +# Unikraft (new CLI) docs -> /cli/unikraft/ +COPY --from=build-cli-docs /cli/dist/docs/mdx/unikraft/ /docs/pages/cli/unikraft/ +COPY --from=build-cli-docs /cli/dist/docs/mdx/unikraft.mdx /docs/pages/cli/unikraft.mdx + +RUN npm run build + +################################################################################ +# Production filesystem +################################################################################ +FROM caddy:2.10.2-alpine AS prod +COPY Caddyfile /etc/caddy/Caddyfile +COPY --from=build /docs/dist/docs /var/www/docs diff --git a/Kraftfile b/Kraftfile new file mode 100644 index 00000000..6fd52cc6 --- /dev/null +++ b/Kraftfile @@ -0,0 +1,7 @@ +spec: v0.6 + +runtime: base-compat:latest + +rootfs: ./Dockerfile + +cmd: ["/usr/bin/caddy", "run", "--config", "/etc/caddy/Caddyfile"] diff --git a/apis/.gitkeep b/apis/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 00000000..3a62a2b7 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,7 @@ +services: + docs: + build: + context: . + target: prod + ports: + - "2015:2015" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..3226c279 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11871 @@ +{ + "name": "docs", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "docs", + "version": "0.1.0", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "hast-util-to-html": "^9.0.5", + "oniguruma-parser": "^0.12.1", + "react": ">=19.0.0", + "react-dom": ">=19.0.0", + "regex-utilities": "^2.3.0", + "zudoku": "^0.71.9" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "eslint": "^9.14.0" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-15.3.1.tgz", + "integrity": "sha512-FIweGOR9zrNuskfDXn8dfsA4eJEe8LmmGsGSDikEZvgYm36SO36yMhasXSOX7/OTGZ3b7I9iPhOxB24D8xL5uQ==", + "license": "MIT", + "dependencies": { + "js-yaml": "^4.1.1" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@types/json-schema": "^7.0.15" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@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/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@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.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@envelop/core": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@envelop/core/-/core-5.5.1.tgz", + "integrity": "sha512-3DQg8sFskDo386TkL5j12jyRAdip/8yzK3x7YGbZBgobZ4aKXrvDU0GppU0SnmrpQnNaiTUsxBs9LKkwQ/eyvw==", + "license": "MIT", + "dependencies": { + "@envelop/instrumentation": "^1.0.0", + "@envelop/types": "^5.2.1", + "@whatwg-node/promise-helpers": "^1.2.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@envelop/instrumentation": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@envelop/instrumentation/-/instrumentation-1.0.0.tgz", + "integrity": "sha512-cxgkB66RQB95H3X27jlnxCRNTmPuSTgmBAq6/4n2Dtv4hsk4yz8FadA1ggmd0uZzvKqWD6CR+WFgTjhDqg7eyw==", + "license": "MIT", + "dependencies": { + "@whatwg-node/promise-helpers": "^1.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@envelop/types": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@envelop/types/-/types-5.2.1.tgz", + "integrity": "sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg==", + "license": "MIT", + "dependencies": { + "@whatwg-node/promise-helpers": "^1.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", + "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", + "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", + "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", + "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", + "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", + "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", + "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", + "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", + "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", + "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", + "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", + "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", + "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", + "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", + "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", + "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", + "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", + "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", + "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", + "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", + "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", + "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", + "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", + "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", + "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", + "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", + "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/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-array/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/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/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/@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/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "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/@eslint/eslintrc/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/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/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/@eslint/eslintrc/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/@eslint/eslintrc/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/@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/@fastify/busboy": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.2.0.tgz", + "integrity": "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==", + "license": "MIT" + }, + "node_modules/@fastify/otel": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@fastify/otel/-/otel-0.16.0.tgz", + "integrity": "sha512-2304BdM5Q/kUvQC9qJO1KZq3Zn1WWsw+WWkVmFEaj1UE2hEIiuFqrPeglQOwEtw/ftngisqfQ3v70TWMmwhhHA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/semantic-conventions": "^1.28.0", + "minimatch": "^10.0.3" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" + } + }, + "node_modules/@fastify/otel/node_modules/@opentelemetry/api-logs": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.208.0.tgz", + "integrity": "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@fastify/otel/node_modules/@opentelemetry/instrumentation": { + "version": "0.208.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.208.0.tgz", + "integrity": "sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.208.0", + "import-in-the-middle": "^2.0.0", + "require-in-the-middle": "^8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.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/@graphql-tools/executor": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.5.1.tgz", + "integrity": "sha512-n94Qcu875Mji9GQ52n5UbgOTxlgvFJicBPYD+FRks9HKIQpdNPjkkrKZUYNG51XKa+bf03rxNflm4+wXhoHHrA==", + "license": "MIT", + "dependencies": { + "@graphql-tools/utils": "^11.0.0", + "@graphql-typed-document-node/core": "^3.2.0", + "@repeaterjs/repeater": "^3.0.4", + "@whatwg-node/disposablestack": "^0.0.6", + "@whatwg-node/promise-helpers": "^1.0.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/executor/node_modules/@graphql-tools/utils": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-11.0.0.tgz", + "integrity": "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA==", + "license": "MIT", + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "@whatwg-node/promise-helpers": "^1.0.0", + "cross-inspect": "1.0.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/merge": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.1.7.tgz", + "integrity": "sha512-Y5E1vTbTabvcXbkakdFUt4zUIzB1fyaEnVmIWN0l0GMed2gdD01TpZWLUm4RNAxpturvolrb24oGLQrBbPLSoQ==", + "license": "MIT", + "dependencies": { + "@graphql-tools/utils": "^11.0.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/merge/node_modules/@graphql-tools/utils": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-11.0.0.tgz", + "integrity": "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA==", + "license": "MIT", + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "@whatwg-node/promise-helpers": "^1.0.0", + "cross-inspect": "1.0.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/schema": { + "version": "10.0.31", + "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.31.tgz", + "integrity": "sha512-ZewRgWhXef6weZ0WiP7/MV47HXiuFbFpiDUVLQl6mgXsWSsGELKFxQsyUCBos60Qqy1JEFAIu3Ns6GGYjGkqkQ==", + "license": "MIT", + "dependencies": { + "@graphql-tools/merge": "^9.1.7", + "@graphql-tools/utils": "^11.0.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/schema/node_modules/@graphql-tools/utils": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-11.0.0.tgz", + "integrity": "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA==", + "license": "MIT", + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "@whatwg-node/promise-helpers": "^1.0.0", + "cross-inspect": "1.0.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-tools/utils": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.11.0.tgz", + "integrity": "sha512-iBFR9GXIs0gCD+yc3hoNswViL1O5josI33dUqiNStFI/MHLCEPduasceAcazRH77YONKNiviHBV8f7OgcT4o2Q==", + "license": "MIT", + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "@whatwg-node/promise-helpers": "^1.0.0", + "cross-inspect": "1.0.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "license": "MIT", + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@graphql-yoga/logger": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@graphql-yoga/logger/-/logger-2.0.1.tgz", + "integrity": "sha512-Nv0BoDGLMg9QBKy9cIswQ3/6aKaKjlTh87x3GiBg2Z4RrjyrM48DvOOK0pJh1C1At+b0mUIM67cwZcFTDLN4sA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@graphql-yoga/subscription": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@graphql-yoga/subscription/-/subscription-5.0.5.tgz", + "integrity": "sha512-oCMWOqFs6QV96/NZRt/ZhTQvzjkGB4YohBOpKM4jH/lDT4qb7Lex/aGCxpi/JD9njw3zBBtMqxbaC22+tFHVvw==", + "license": "MIT", + "dependencies": { + "@graphql-yoga/typed-event-target": "^3.0.2", + "@repeaterjs/repeater": "^3.0.4", + "@whatwg-node/events": "^0.1.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@graphql-yoga/typed-event-target": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@graphql-yoga/typed-event-target/-/typed-event-target-3.0.2.tgz", + "integrity": "sha512-ZpJxMqB+Qfe3rp6uszCQoag4nSw42icURnBRfFYSOmTgEeOe4rD0vYlbA8spvCu2TlCesNTlEN9BLWtQqLxabA==", + "license": "MIT", + "dependencies": { + "@repeaterjs/repeater": "^3.0.4", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@hono/node-server": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", + "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.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/@lekoarts/rehype-meta-as-attributes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@lekoarts/rehype-meta-as-attributes/-/rehype-meta-as-attributes-3.0.3.tgz", + "integrity": "sha512-DyG740U2y8ZWU5ZsAGzKfdVKOENg9UZsCBUJ3DVaWT7ZMHhDG5U0CjLj40CsEsJJ1gauaQPlrU9QUg5uSa4RFg==", + "license": "MIT", + "dependencies": { + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", + "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@mdx-js/rollup": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/rollup/-/rollup-3.1.1.tgz", + "integrity": "sha512-v8satFmBB+DqDzYohnm1u2JOvxx6Hl3pUvqzJvfs2Zk/ngZ1aRUhsWpXvwPkNeGN9c2NCm/38H29ZqXQUjf8dw==", + "license": "MIT", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@rollup/pluginutils": "^5.0.0", + "source-map": "^0.7.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "rollup": ">=2" + } + }, + "node_modules/@napi-rs/nice": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.1.1.tgz", + "integrity": "sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.1.1", + "@napi-rs/nice-android-arm64": "1.1.1", + "@napi-rs/nice-darwin-arm64": "1.1.1", + "@napi-rs/nice-darwin-x64": "1.1.1", + "@napi-rs/nice-freebsd-x64": "1.1.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.1.1", + "@napi-rs/nice-linux-arm64-gnu": "1.1.1", + "@napi-rs/nice-linux-arm64-musl": "1.1.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.1.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.1.1", + "@napi-rs/nice-linux-s390x-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-musl": "1.1.1", + "@napi-rs/nice-openharmony-arm64": "1.1.1", + "@napi-rs/nice-win32-arm64-msvc": "1.1.1", + "@napi-rs/nice-win32-ia32-msvc": "1.1.1", + "@napi-rs/nice-win32-x64-msvc": "1.1.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.1.1.tgz", + "integrity": "sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.1.1.tgz", + "integrity": "sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.1.1.tgz", + "integrity": "sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.1.1.tgz", + "integrity": "sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.1.1.tgz", + "integrity": "sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.1.1.tgz", + "integrity": "sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.1.1.tgz", + "integrity": "sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.1.1.tgz", + "integrity": "sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.1.1.tgz", + "integrity": "sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.1.1.tgz", + "integrity": "sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.1.1.tgz", + "integrity": "sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.1.1.tgz", + "integrity": "sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.1.1.tgz", + "integrity": "sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-openharmony-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-openharmony-arm64/-/nice-openharmony-arm64-1.1.1.tgz", + "integrity": "sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.1.1.tgz", + "integrity": "sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.1.1.tgz", + "integrity": "sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.1.1.tgz", + "integrity": "sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", + "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.211.0.tgz", + "integrity": "sha512-swFdZq8MCdmdR22jTVGQDhwqDzcI4M10nhjXkLr1EsIzXgZBqm4ZlmmcWsg3TSNf+3mzgOiqveXmBLZuDi2Lgg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.6.1.tgz", + "integrity": "sha512-XHzhwRNkBpeP8Fs/qjGrAf9r9PRv67wkJQ/7ZPaBQQ68DYlTBBx5MF9LvPx7mhuXcDessKK2b+DcxqwpgkcivQ==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.6.1.tgz", + "integrity": "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.211.0.tgz", + "integrity": "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.211.0", + "import-in-the-middle": "^2.0.0", + "require-in-the-middle": "^8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.58.0.tgz", + "integrity": "sha512-fjpQtH18J6GxzUZ+cwNhWUpb71u+DzT7rFkg5pLssDGaEber91Y2WNGdpVpwGivfEluMlNMZumzjEqfg8DeKXQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.54.0.tgz", + "integrity": "sha512-43RmbhUhqt3uuPnc16cX6NsxEASEtn8z/cYV8Zpt6EP4p2h9s4FNuJ4Q9BbEQ2C0YlCCB/2crO1ruVz/hWt8fA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.38" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.28.0.tgz", + "integrity": "sha512-ExXGBp0sUj8yhm6Znhf9jmuOaGDsYfDES3gswZnKr4MCqoBWQdEFn6EoDdt5u+RdbxQER+t43FoUihEfTSqsjA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.59.0.tgz", + "integrity": "sha512-pMKV/qnHiW/Q6pmbKkxt0eIhuNEtvJ7sUAyee192HErlr+a1Jx+FZ3WjfmzhQL1geewyGEiPGkmjjAgNY8TgDA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.30.0.tgz", + "integrity": "sha512-n3Cf8YhG7reaj5dncGlRIU7iT40bxPOjsBEA5Bc1a1g6e9Qvb+JFJ7SEiMlPbUw4PBmxE3h40ltE8LZ3zVt6OA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.54.0.tgz", + "integrity": "sha512-8dXMBzzmEdXfH/wjuRvcJnUFeWzZHUnExkmFJ2uPfa31wmpyBCMxO59yr8f/OXXgSogNgi/uPo9KW9H7LMIZ+g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.58.0.tgz", + "integrity": "sha512-+yWVVY7fxOs3j2RixCbvue8vUuJ1inHxN2q1sduqDB0Wnkr4vOzVKRYl/Zy7B31/dcPS72D9lo/kltdOTBM3bQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.57.0.tgz", + "integrity": "sha512-Os4THbvls8cTQTVA8ApLfZZztuuqGEeqog0XUnyRW7QVF0d/vOVBEcBCk1pazPFmllXGEdNbbat8e2fYIWdFbw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.211.0.tgz", + "integrity": "sha512-n0IaQ6oVll9PP84SjbOCwDjaJasWRHi6BLsbMLiT6tNj7QbVOkuA5sk/EfZczwI0j5uTKl1awQPivO/ldVtsqA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/instrumentation": "0.211.0", + "@opentelemetry/semantic-conventions": "^1.29.0", + "forwarded-parse": "2.1.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.59.0.tgz", + "integrity": "sha512-875UxzBHWkW+P4Y45SoFM2AR8f8TzBMD8eO7QXGCyFSCUMP5s9vtt/BS8b/r2kqLyaRPK6mLbdnZznK3XzQWvw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/redis-common": "^0.38.2", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.20.0.tgz", + "integrity": "sha512-yJXOuWZROzj7WmYCUiyT27tIfqBrVtl1/TwVbQyWPz7rL0r1Lu7kWjD0PiVeTCIL6CrIZ7M2s8eBxsTAOxbNvw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.30.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.55.0.tgz", + "integrity": "sha512-FtTL5DUx5Ka/8VK6P1VwnlUXPa3nrb7REvm5ddLUIeXXq4tb9pKd+/ThB1xM/IjefkRSN3z8a5t7epYw1JLBJQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.59.0.tgz", + "integrity": "sha512-K9o2skADV20Skdu5tG2bogPKiSpXh4KxfLjz6FuqIVvDJNibwSdu5UvyyBzRVp1rQMV6UmoIk6d3PyPtJbaGSg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.36.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.55.0.tgz", + "integrity": "sha512-FDBfT7yDGcspN0Cxbu/k8A0Pp1Jhv/m7BMTzXGpcb8ENl3tDj/51U65R5lWzUH15GaZA15HQ5A5wtafklxYj7g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.64.0.tgz", + "integrity": "sha512-pFlCJjweTqVp7B220mCvCld1c1eYKZfQt1p3bxSbcReypKLJTwat+wbL2YZoX9jPi5X2O8tTKFEOahO5ehQGsA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.57.0.tgz", + "integrity": "sha512-MthiekrU/BAJc5JZoZeJmo0OTX6ycJMiP6sMOSRTkvz5BrPMYDqaJos0OgsLPL/HpcgHP7eo5pduETuLguOqcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.57.0.tgz", + "integrity": "sha512-HFS/+FcZ6Q7piM7Il7CzQ4VHhJvGMJWjx7EgCkP5AnTntSN5rb5Xi3TkYJHBKeR27A0QqPlGaCITi93fUDs++Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@types/mysql": "2.15.27" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.57.0.tgz", + "integrity": "sha512-nHSrYAwF7+aV1E1V9yOOP9TchOodb6fjn4gFvdrdQXiRE7cMuffyLLbCZlZd4wsspBzVwOXX8mpURdRserAhNA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@opentelemetry/sql-common": "^0.41.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.63.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.63.0.tgz", + "integrity": "sha512-dKm/ODNN3GgIQVlbD6ZPxwRc3kleLf95hrRWXM+l8wYo+vSeXtEpQPT53afEf6VFWDVzJK55VGn8KMLtSve/cg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@opentelemetry/sql-common": "^0.41.2", + "@types/pg": "8.15.6", + "@types/pg-pool": "2.0.7" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.59.0.tgz", + "integrity": "sha512-JKv1KDDYA2chJ1PC3pLP+Q9ISMQk6h5ey+99mB57/ARk0vQPGZTTEb4h4/JlcEpy7AYT8HIGv7X6l+br03Neeg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/redis-common": "^0.38.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.30.0.tgz", + "integrity": "sha512-bZy9Q8jFdycKQ2pAsyuHYUHNmCxCOGdG6eg1Mn75RvQDccq832sU5OWOBnc12EFUELI6icJkhR7+EQKMBam2GA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.21.0.tgz", + "integrity": "sha512-gok0LPUOTz2FQ1YJMZzaHcOzDFyT64XJ8M9rNkugk923/p6lDGms/cRW1cqgqp6N6qcd6K6YdVHwPEhnx9BWbw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.24.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.38.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.2.tgz", + "integrity": "sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.6.1.tgz", + "integrity": "sha512-lID/vxSuKWXM55XhAKNoYXu9Cutoq5hFdkbTdI/zDKQktXzcWBVhNsOkiZFTMU9UtEWuGRNe0HUgmsFldIdxVA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.6.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.6.1.tgz", + "integrity": "sha512-r86ut4T1e8vNwB35CqCcKd45yzqH6/6Wzvpk2/cZB8PsPLlZFTvrh8yfOS3CYZYcUmAx4hHTZJ8AO8Dj8nrdhw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.6.1", + "@opentelemetry/resources": "2.6.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.40.0.tgz", + "integrity": "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.41.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz", + "integrity": "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, + "node_modules/@pagefind/darwin-arm64": { + "version": "1.5.0-beta.1", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.5.0-beta.1.tgz", + "integrity": "sha512-oOcnXy83NK+utpeHN3igrug7RpZpu0lLNpGOXfTKJaOc44lIvxnDI0ceJnwvRqDCl+KLSGpqn4uWczmEMtnikQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/darwin-x64": { + "version": "1.5.0-beta.1", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.5.0-beta.1.tgz", + "integrity": "sha512-ZL2+L+rtjPv0sZ1CcrtuDqJgorkGr6DTcm3KargL2gvlIfup73GEZ1S0rNSLPIR1azUa+fuiW2dI8SEacCRcBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@pagefind/freebsd-x64": { + "version": "1.5.0-beta.1", + "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.5.0-beta.1.tgz", + "integrity": "sha512-OYUJUAipl8PX2kl5GJUd0Jt1lmzbeG2Ld0J6FWNZw3eEQ9Qs58bviuo7bg99xJEV8K//GO3PrD6JHzFI5umUJA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@pagefind/linux-arm64": { + "version": "1.5.0-beta.1", + "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.5.0-beta.1.tgz", + "integrity": "sha512-xaHp0iBnhC/jWRmwLZ5+x1f/DK1G9Z2rdXgNh7YTEes0hSaQwwu6JzAKjhH9K1rYClWnRDfHIF+SBu5MY48ecQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/linux-x64": { + "version": "1.5.0-beta.1", + "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.5.0-beta.1.tgz", + "integrity": "sha512-3UzHImmoMC1xTN3uD6myxKMDxygEQu+i4f1qRGAyetXudkK5ItlLZycAso6+e5Te0jNlDRDosTE5ulj+MuR4dg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@pagefind/windows-x64": { + "version": "1.5.0-beta.1", + "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.5.0-beta.1.tgz", + "integrity": "sha512-A+D7zCNPdXXaUw2TIyTdrMSK61wq7yRluXL/b/dxFyBP/qycFV8wqIiLx14vQH+pKgXOeMdIkiLAA+HUnbPWwg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@posthog/core": { + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.23.1.tgz", + "integrity": "sha512-GViD5mOv/mcbZcyzz3z9CS0R79JzxVaqEz4sP5Dsea178M/j3ZWe6gaHDZB9yuyGfcmIMQ/8K14yv+7QrK4sQQ==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.6" + } + }, + "node_modules/@pothos/core": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@pothos/core/-/core-4.12.0.tgz", + "integrity": "sha512-PeiODrj3GjQ7Nbs/5p65DEyBWZTSGGjgGO/BgaMEqS1jBNX/2zJTEQJA9zM5uPmCHUCDjE7Qn2U7lOi0ALp/8A==", + "license": "ISC", + "peerDependencies": { + "graphql": "^16.10.0" + } + }, + "node_modules/@prisma/instrumentation": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-7.2.0.tgz", + "integrity": "sha512-Rh9Z4x5kEj1OdARd7U18AtVrnL6rmLSI0qYShaB4W7Wx5BKbgzndWF+QnuzMb7GLfVdlT5aYCXoPQVYuYtVu0g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.207.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.8" + } + }, + "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/api-logs": { + "version": "0.207.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.207.0.tgz", + "integrity": "sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/instrumentation": { + "version": "0.207.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.207.0.tgz", + "integrity": "sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.207.0", + "import-in-the-middle": "^2.0.0", + "require-in-the-middle": "^8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.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-alert-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", + "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dialog": "1.1.15", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "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-alert-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "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-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.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-aspect-ratio": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.8.tgz", + "integrity": "sha512-5nZrJTF7gH+e0nZS7/QxFz6tJV4VimhQb1avEgtsJxvvIp5JilL+c58HICsKzPxghdwaDt48hEfPM1au4zGy+w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.4" + }, + "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-aspect-ratio/node_modules/@radix-ui/react-primitive": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", + "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.4" + }, + "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-checkbox": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "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.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "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.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "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-collection/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "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-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "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.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "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.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.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-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "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-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "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.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "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.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", + "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.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-focus-guards": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "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.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "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-hover-card": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.15.tgz", + "integrity": "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.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.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "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.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.8.tgz", + "integrity": "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.4" + }, + "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-label/node_modules/@radix-ui/react-primitive": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", + "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.4" + }, + "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.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", + "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.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-menu/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "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-navigation-menu": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.14.tgz", + "integrity": "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "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-navigation-menu/node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.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-popover": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", + "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.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-popover/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "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-popper": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "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.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "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.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "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.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "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-primitive/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "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-progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.8.tgz", + "integrity": "sha512-+gISHcSPUJ7ktBy9RnTqbdKW78bcGke3t6taawyZ71pio1JewwGSJizycs7rLhGTvMJYCQB1DBK4KQsxs7U8dA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.1.3", + "@radix-ui/react-primitive": "2.1.4" + }, + "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-progress/node_modules/@radix-ui/react-context": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.3.tgz", + "integrity": "sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw==", + "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-progress/node_modules/@radix-ui/react-primitive": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", + "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.4" + }, + "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-radio-group": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", + "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "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.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.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-scroll-area": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", + "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "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-select": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", + "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.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-select/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "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-select/node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.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-separator": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.8.tgz", + "integrity": "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.4" + }, + "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/node_modules/@radix-ui/react-primitive": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", + "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.4" + }, + "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-slider": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz", + "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "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.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", + "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "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-switch": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", + "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "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-tabs": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.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-toggle": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", + "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.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-toggle-group": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz", + "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-toggle": "1.1.10", + "@radix-ui/react-use-controllable-state": "1.2.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-tooltip": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-visually-hidden": "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/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "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-tooltip/node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.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-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "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.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "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.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "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.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "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.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "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-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "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.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.1" + }, + "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.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "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.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.4.tgz", + "integrity": "sha512-kaeiyGCe844dkb9AVF+rb4yTyb1LiLN/e3es3nLiRyN4dC8AduBYPMnnNlDjX2VDOcvDEiPnRNMJeWCfsX0txg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.4" + }, + "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-visually-hidden/node_modules/@radix-ui/react-primitive": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", + "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.4" + }, + "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.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "license": "MIT" + }, + "node_modules/@repeaterjs/repeater": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.6.tgz", + "integrity": "sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==", + "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==", + "license": "MIT" + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@scalar/helpers": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@scalar/helpers/-/helpers-0.2.7.tgz", + "integrity": "sha512-uFTcdi3XYDDuaJLWiMuM3ijQit1OBw7AkuOuujReY8L9UmUQHY56erYg0+Db3llTsinuIYFh+eS/WX/sYuevYQ==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/@scalar/json-magic": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@scalar/json-magic/-/json-magic-0.9.0.tgz", + "integrity": "sha512-aSWd8rd3O73Ak9Ylson2TywvOuTjjOYiXydl9Cn8Ip/r7fi+h0QqAGom5gqo/WewrhySF9v+H/sW/Qmd05T/Kg==", + "license": "MIT", + "dependencies": { + "@scalar/helpers": "0.2.7", + "yaml": "^2.8.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@scalar/openapi-parser": { + "version": "0.23.13", + "resolved": "https://registry.npmjs.org/@scalar/openapi-parser/-/openapi-parser-0.23.13.tgz", + "integrity": "sha512-YsljPOKOgQgZL/kBcEouwz2CUa+2hFfThlUZRWC2DFI2Fnw5Ur8F1IvGgPqCAHr9p2XMH+Z/Pag2jZUfLcxcww==", + "license": "MIT", + "dependencies": { + "@scalar/json-magic": "0.9.0", + "@scalar/openapi-types": "0.5.3", + "@scalar/openapi-upgrader": "0.1.7", + "ajv": "^8.17.1", + "ajv-draft-04": "^1.0.0", + "ajv-formats": "^3.0.1", + "jsonpointer": "^5.0.1", + "leven": "^4.0.0", + "yaml": "^2.8.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@scalar/openapi-types": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@scalar/openapi-types/-/openapi-types-0.5.3.tgz", + "integrity": "sha512-m4n/Su3K01d15dmdWO1LlqecdSPKuNjuokrJLdiQ485kW/hRHbXW1QP6tJL75myhw/XhX5YhYAR+jrwnGjXiMw==", + "license": "MIT", + "dependencies": { + "zod": "^4.1.11" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@scalar/openapi-upgrader": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@scalar/openapi-upgrader/-/openapi-upgrader-0.1.7.tgz", + "integrity": "sha512-065froUtqvaHjyeJtyitf8tb+k7oh7nU0OinAHYbj1Bqgwb1s2+uKMqHYHEES5CNpp+2xtL4lxup6Aq29yW+sQ==", + "license": "MIT", + "dependencies": { + "@scalar/openapi-types": "0.5.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@sentry/core": { + "version": "10.42.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.42.0.tgz", + "integrity": "sha512-L4rMrXMqUKBanpjpMT+TuAVk6xAijz6AWM6RiEYpohAr7SGcCEc1/T0+Ep1eLV8+pwWacfU27OvELIyNeOnGzA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node": { + "version": "10.42.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.42.0.tgz", + "integrity": "sha512-ZZfU3Fnni7Aj0lTX4e3QpY3UxK4FGuzfM20316UAJycBGnripm+sDHwcekPMGfLnk/FrN9wa1atspVlHvOI0WQ==", + "license": "MIT", + "dependencies": { + "@fastify/otel": "0.16.0", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^2.5.1", + "@opentelemetry/core": "^2.5.1", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation-amqplib": "0.58.0", + "@opentelemetry/instrumentation-connect": "0.54.0", + "@opentelemetry/instrumentation-dataloader": "0.28.0", + "@opentelemetry/instrumentation-express": "0.59.0", + "@opentelemetry/instrumentation-fs": "0.30.0", + "@opentelemetry/instrumentation-generic-pool": "0.54.0", + "@opentelemetry/instrumentation-graphql": "0.58.0", + "@opentelemetry/instrumentation-hapi": "0.57.0", + "@opentelemetry/instrumentation-http": "0.211.0", + "@opentelemetry/instrumentation-ioredis": "0.59.0", + "@opentelemetry/instrumentation-kafkajs": "0.20.0", + "@opentelemetry/instrumentation-knex": "0.55.0", + "@opentelemetry/instrumentation-koa": "0.59.0", + "@opentelemetry/instrumentation-lru-memoizer": "0.55.0", + "@opentelemetry/instrumentation-mongodb": "0.64.0", + "@opentelemetry/instrumentation-mongoose": "0.57.0", + "@opentelemetry/instrumentation-mysql": "0.57.0", + "@opentelemetry/instrumentation-mysql2": "0.57.0", + "@opentelemetry/instrumentation-pg": "0.63.0", + "@opentelemetry/instrumentation-redis": "0.59.0", + "@opentelemetry/instrumentation-tedious": "0.30.0", + "@opentelemetry/instrumentation-undici": "0.21.0", + "@opentelemetry/resources": "^2.5.1", + "@opentelemetry/sdk-trace-base": "^2.5.1", + "@opentelemetry/semantic-conventions": "^1.39.0", + "@prisma/instrumentation": "7.2.0", + "@sentry/core": "10.42.0", + "@sentry/node-core": "10.42.0", + "@sentry/opentelemetry": "10.42.0", + "import-in-the-middle": "^2.0.6" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sentry/node-core": { + "version": "10.42.0", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.42.0.tgz", + "integrity": "sha512-9tf3fPV6M071aps72D+PEtdQPTuj+SuqO2+PpTfdPP5ZL4TTKYo3VK0li76SL+5wGdTFGV5qmsokHq9IRBA0iA==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.42.0", + "@sentry/opentelemetry": "10.42.0", + "import-in-the-middle": "^2.0.6" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0", + "@opentelemetry/instrumentation": ">=0.57.1 <1", + "@opentelemetry/resources": "^1.30.1 || ^2.1.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", + "@opentelemetry/semantic-conventions": "^1.39.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/context-async-hooks": { + "optional": true + }, + "@opentelemetry/core": { + "optional": true + }, + "@opentelemetry/instrumentation": { + "optional": true + }, + "@opentelemetry/resources": { + "optional": true + }, + "@opentelemetry/sdk-trace-base": { + "optional": true + }, + "@opentelemetry/semantic-conventions": { + "optional": true + } + } + }, + "node_modules/@sentry/opentelemetry": { + "version": "10.42.0", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.42.0.tgz", + "integrity": "sha512-5vsYz683iihzlIj3sT1+tEixf0awwXK86a+aYsnMHrTXJDrkBDq4U0ZT+yxdPfJlkaxRtYycFR08SXr2pSm7Eg==", + "license": "MIT", + "dependencies": { + "@sentry/core": "10.42.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", + "@opentelemetry/semantic-conventions": "^1.39.0" + } + }, + "node_modules/@shikijs/core": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.23.0.tgz", + "integrity": "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.23.0.tgz", + "integrity": "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.4" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", + "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", + "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/rehype": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/rehype/-/rehype-3.23.0.tgz", + "integrity": "sha512-GepKJxXHbXFfAkiZZZ+4V7x71Lw3s0ALYmydUxJRdvpKjSx9FOMSaunv6WRLFBXR6qjYerUq1YZQno+2gLEPwA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0", + "@types/hast": "^3.0.4", + "hast-util-to-string": "^3.0.1", + "shiki": "3.23.0", + "unified": "^11.0.5", + "unist-util-visit": "^5.1.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", + "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/transformers": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-3.23.0.tgz", + "integrity": "sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.23.0", + "@shikijs/types": "3.23.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", + "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" + }, + "node_modules/@tailwindcss/node": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", + "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", + "jiti": "^2.6.1", + "lightningcss": "1.31.1", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.2.1" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", + "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-arm64": "4.2.1", + "@tailwindcss/oxide-darwin-x64": "4.2.1", + "@tailwindcss/oxide-freebsd-x64": "4.2.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@tailwindcss/oxide-linux-x64-musl": "4.2.1", + "@tailwindcss/oxide-wasm32-wasi": "4.2.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", + "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", + "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", + "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", + "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", + "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", + "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", + "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", + "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", + "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", + "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", + "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.8.1", + "@emnapi/runtime": "^1.8.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.8.1", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.8.1", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.1", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "inBundle": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", + "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", + "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.19.tgz", + "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.1.tgz", + "integrity": "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.2.1", + "@tailwindcss/oxide": "4.2.1", + "tailwindcss": "4.2.1" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, + "node_modules/@tanem/react-nprogress": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@tanem/react-nprogress/-/react-nprogress-6.0.2.tgz", + "integrity": "sha512-SkBexef8gs8aquOMdyOFN/oSDsDUatDWDhH4R74KCjYc9ffsQJnReXVQKlbkyB9yv+B9MuG6+2g5YpvBNNQ7Vg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.6", + "hoist-non-react-statics": "^3.3.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.90.20", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz", + "integrity": "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.90.21", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz", + "integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.90.20" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "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==", + "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==", + "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==", + "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==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/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==", + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/mysql": { + "version": "2.15.27", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", + "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", + "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/pg": { + "version": "8.15.6", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.6.tgz", + "integrity": "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.7.tgz", + "integrity": "sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==", + "license": "MIT", + "dependencies": { + "@types/pg": "*" + } + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "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==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.0.tgz", + "integrity": "sha512-RLkVSiNuUP1C2ROIWfqX+YcUfLaSnxGE/8M+Y57lopVwg9VTYYfhuz15Yf1IzCKgZj6/rIbYTmJCUSqr76r0Wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.58.0", + "@typescript-eslint/type-utils": "8.58.0", + "@typescript-eslint/utils": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.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.58.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.0.tgz", + "integrity": "sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.0.tgz", + "integrity": "sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.58.0", + "@typescript-eslint/types": "^8.58.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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.0.tgz", + "integrity": "sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.0.tgz", + "integrity": "sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A==", + "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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.0.tgz", + "integrity": "sha512-aGsCQImkDIqMyx1u4PrVlbi/krmDsQUs4zAcCV6M7yPcPev+RqVlndsJy9kJ8TLihW9TZ0kbDAzctpLn5o+lOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0", + "@typescript-eslint/utils": "8.58.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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.0.tgz", + "integrity": "sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==", + "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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.0.tgz", + "integrity": "sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.58.0", + "@typescript-eslint/tsconfig-utils": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.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/utils": { + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.0.tgz", + "integrity": "sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.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.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.0.tgz", + "integrity": "sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.58.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/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", + "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", + "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" + } + }, + "node_modules/@whatwg-node/disposablestack": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@whatwg-node/disposablestack/-/disposablestack-0.0.6.tgz", + "integrity": "sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==", + "license": "MIT", + "dependencies": { + "@whatwg-node/promise-helpers": "^1.0.0", + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@whatwg-node/events": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.2.tgz", + "integrity": "sha512-ApcWxkrs1WmEMS2CaLLFUEem/49erT3sxIVjpzU5f6zmVcnijtDSrhoK2zVobOIikZJdH63jdAXOrvjf6eOUNQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@whatwg-node/fetch": { + "version": "0.10.13", + "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.13.tgz", + "integrity": "sha512-b4PhJ+zYj4357zwk4TTuF2nEe0vVtOrwdsrNo5hL+u1ojXNhh1FgJ6pg1jzDlwlT4oBdzfSwaBwMCtFCsIWg8Q==", + "license": "MIT", + "dependencies": { + "@whatwg-node/node-fetch": "^0.8.3", + "urlpattern-polyfill": "^10.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@whatwg-node/node-fetch": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.8.5.tgz", + "integrity": "sha512-4xzCl/zphPqlp9tASLVeUhB5+WJHbuWGYpfoC2q1qh5dw0AqZBW7L27V5roxYWijPxj4sspRAAoOH3d2ztaHUQ==", + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^3.1.1", + "@whatwg-node/disposablestack": "^0.0.6", + "@whatwg-node/promise-helpers": "^1.3.2", + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@whatwg-node/promise-helpers": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@whatwg-node/promise-helpers/-/promise-helpers-1.3.2.tgz", + "integrity": "sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@whatwg-node/server": { + "version": "0.10.18", + "resolved": "https://registry.npmjs.org/@whatwg-node/server/-/server-0.10.18.tgz", + "integrity": "sha512-kMwLlxUbduttIgaPdSkmEarFpP+mSY8FEm+QWMBRJwxOHWkri+cxd8KZHO9EMrB9vgUuz+5WEaCawaL5wGVoXg==", + "license": "MIT", + "dependencies": { + "@envelop/instrumentation": "^1.0.0", + "@whatwg-node/disposablestack": "^0.0.6", + "@whatwg-node/fetch": "^0.10.13", + "@whatwg-node/promise-helpers": "^1.3.2", + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@x0k/json-schema-merge": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@x0k/json-schema-merge/-/json-schema-merge-1.0.2.tgz", + "integrity": "sha512-1734qiJHNX3+cJGDMMw2yz7R+7kpbAtl5NdPs1c/0gO5kYT6s4dMbLXiIfpZNsOYhGZI3aH7FWrj4Zxz7epXNg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.15" + } + }, + "node_modules/@zudoku/httpsnippet": { + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@zudoku/httpsnippet/-/httpsnippet-10.0.9.tgz", + "integrity": "sha512-qmxuSxmTEEt6bc5j1cChljbztIphkuYMj3bbmT2W54ePGwCk6Iea7vPutHVw7NnCIW6cRI//w+u7xGOfOhwPCw==", + "license": "MIT", + "dependencies": { + "qs": "^6.11.2", + "stringify-object": "^3.3.0", + "url": "^0.11.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@zudoku/react-helmet-async": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@zudoku/react-helmet-async/-/react-helmet-async-2.0.5.tgz", + "integrity": "sha512-wDakXPJEiQb4JmacSqPyAiJPdOBFqp6e3VUbm1BtTEkXo6FrC2nN+GmIniQ2OimBEC042rSZ9JdQBX+wou/MKw==", + "license": "Apache-2.0", + "dependencies": { + "invariant": "^2.2.4", + "react-fast-compare": "^3.2.2", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@zuplo/mcp": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@zuplo/mcp/-/mcp-0.0.32.tgz", + "integrity": "sha512-rpLTpwL+g1sXtylu2gZwCTXdNIV2L0LPOcCdwogpP5hdyp/JMLSAVtd7H5fs5Wt2cq3jTm6nn7ZZvsBAECdl3A==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.6", + "zod": "^3.25.0" + } + }, + "node_modules/@zuplo/mcp/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "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==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "license": "MIT", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "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/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base-x": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.1.tgz", + "integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==", + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.12", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.12.tgz", + "integrity": "sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "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.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs58": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", + "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", + "license": "MIT", + "dependencies": { + "base-x": "^5.0.0" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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.30001782", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001782.tgz", + "integrity": "sha512-dZcaJLJeDMh4rELYFw1tvSn1bhZWYFOt468FcbHHxx/Z/dFidd1I6ciyFdi3iwfQCyOjqo9upF6lGQYtMiJWxw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "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/chalk/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/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cjs-module-lexer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "license": "MIT" + }, + "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/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "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/cmdk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz", + "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "^1.1.1", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-id": "^1.1.0", + "@radix-ui/react-primitive": "^2.0.2" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/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==", + "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-inspect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cross-inspect/-/cross-inspect-1.0.1.tgz", + "integrity": "sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/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/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dotenv": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz", + "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.328", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.328.tgz", + "integrity": "sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==", + "license": "ISC" + }, + "node_modules/embla-carousel": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz", + "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==", + "license": "MIT" + }, + "node_modules/embla-carousel-react": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.6.0.tgz", + "integrity": "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==", + "license": "MIT", + "dependencies": { + "embla-carousel": "8.6.0", + "embla-carousel-reactive-utils": "8.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/embla-carousel-reactive-utils": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz", + "integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==", + "license": "MIT", + "peerDependencies": { + "embla-carousel": "8.6.0" + } + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", + "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esbuild": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", + "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.4", + "@esbuild/android-arm": "0.27.4", + "@esbuild/android-arm64": "0.27.4", + "@esbuild/android-x64": "0.27.4", + "@esbuild/darwin-arm64": "0.27.4", + "@esbuild/darwin-x64": "0.27.4", + "@esbuild/freebsd-arm64": "0.27.4", + "@esbuild/freebsd-x64": "0.27.4", + "@esbuild/linux-arm": "0.27.4", + "@esbuild/linux-arm64": "0.27.4", + "@esbuild/linux-ia32": "0.27.4", + "@esbuild/linux-loong64": "0.27.4", + "@esbuild/linux-mips64el": "0.27.4", + "@esbuild/linux-ppc64": "0.27.4", + "@esbuild/linux-riscv64": "0.27.4", + "@esbuild/linux-s390x": "0.27.4", + "@esbuild/linux-x64": "0.27.4", + "@esbuild/netbsd-arm64": "0.27.4", + "@esbuild/netbsd-x64": "0.27.4", + "@esbuild/openbsd-arm64": "0.27.4", + "@esbuild/openbsd-x64": "0.27.4", + "@esbuild/openharmony-arm64": "0.27.4", + "@esbuild/sunos-x64": "0.27.4", + "@esbuild/win32-arm64": "0.27.4", + "@esbuild/win32-ia32": "0.27.4", + "@esbuild/win32-x64": "0.27.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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-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": "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/node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "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/eslint/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/eslint/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/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/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/eslint/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/eslint/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/eslint/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/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/espree/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/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "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/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.5.0.tgz", + "integrity": "sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.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/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "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==", + "license": "MIT" + }, + "node_modules/fast-equals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-6.0.0.tgz", + "integrity": "sha512-PFhhIGgdM79r5Uztdj9Zb6Tt1zKafqVfdMGwVca1z5z6fbX7DmsySSuJd8HiP6I1j505DCS83cLxo5rmSNeVEA==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "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/fast-printf": { + "version": "1.6.10", + "resolved": "https://registry.npmjs.org/fast-printf/-/fast-printf-1.6.10.tgz", + "integrity": "sha512-GwTgG9O4FVIdShhbVF3JxOgSBY2+ePGsu2V/UONgoCPzF9VY6ZdBMKsHKCYQHZwNk3qNouUolRDsgVxcVA5G1w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=10.0" + } + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "license": "MIT" + }, + "node_modules/framer-motion": { + "version": "12.38.0", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz", + "integrity": "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.38.0", + "motion-utils": "^12.36.0", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "license": "ISC" + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "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/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphql": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.1.tgz", + "integrity": "sha512-gGgrVCoDKlIZ8fIqXBBb0pPKqDgki0Z/FSKNiQzSGj2uEYHr1tq5wmBegGwJx6QB5S5cM0khSBpi/JFHMCvsmQ==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-type-json": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz", + "integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==", + "license": "MIT", + "peerDependencies": { + "graphql": ">=0.8.0" + } + }, + "node_modules/graphql-yoga": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/graphql-yoga/-/graphql-yoga-5.18.0.tgz", + "integrity": "sha512-xFt1DVXS1BZ3AvjnawAGc5OYieSe56WuQuyk3iEpBwJ3QDZJWQGLmU9z/L5NUZ+pUcyprsz/bOwkYIV96fXt/g==", + "license": "MIT", + "dependencies": { + "@envelop/core": "^5.3.0", + "@envelop/instrumentation": "^1.0.0", + "@graphql-tools/executor": "^1.5.0", + "@graphql-tools/schema": "^10.0.11", + "@graphql-tools/utils": "^10.11.0", + "@graphql-yoga/logger": "^2.0.1", + "@graphql-yoga/subscription": "^5.0.5", + "@whatwg-node/fetch": "^0.10.6", + "@whatwg-node/promise-helpers": "^1.3.2", + "@whatwg-node/server": "^0.10.14", + "lru-cache": "^10.0.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "graphql": "^15.2.0 || ^16.0.0" + } + }, + "node_modules/graphql-yoga/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-heading-rank": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", + "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-properties-to-mdx-jsx-attributes": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/hast-util-properties-to-mdx-jsx-attributes/-/hast-util-properties-to-mdx-jsx-attributes-1.1.1.tgz", + "integrity": "sha512-MMrAoGgvhYULEqMB/r6AlcVz1D3Cyml/9cMB2NIqZsIsEJ+XEXPMqH0gjba8dVs9AnQUYvPReAS+OIYx4ip+Ug==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "estree-util-value-to-estree": "^3.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "property-information": "^7.0.0", + "style-to-js": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", + "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/hono": { + "version": "4.12.5", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.5.tgz", + "integrity": "sha512-3qq+FUBtlTHhtYxbxheZgY8NIFnkkC/MR8u5TTsr7YZ3wixryQ3cCwn3iZbg8p8B88iDBBAYSfZDS75t8MN7Vg==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/html-url-attributes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-terminator": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/http-terminator/-/http-terminator-3.2.0.tgz", + "integrity": "sha512-JLjck1EzPaWjsmIf8bziM3p9fgR1Y3JoUKAkyYEbZmFrIvJM6I8vVJfBGWlEtV9IWOvzNnaTtjuwZeBY2kwB4g==", + "license": "BSD-3-Clause", + "dependencies": { + "delay": "^5.0.0", + "p-wait-for": "^3.2.0", + "roarr": "^7.0.4", + "type-fest": "^2.3.3" + }, + "engines": { + "node": ">=14" + } + }, + "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/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/import-in-the-middle": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", + "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.15.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^2.2.0", + "module-details-from-path": "^1.0.4" + } + }, + "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/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "license": "MIT", + "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==", + "license": "ISC" + }, + "node_modules/javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "license": "MIT" + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "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==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "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==", + "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-to-typescript-lite": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript-lite/-/json-schema-to-typescript-lite-15.0.0.tgz", + "integrity": "sha512-5mMORSQm9oTLyjM4mWnyNBi2T042Fhg1/0gCIB6X8U/LVpM2A+Nmj2yEyArqVouDmFThDxpEXcnTgSrjkGJRFA==", + "license": "MIT", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^14.1.1", + "@types/json-schema": "^7.0.15" + } + }, + "node_modules/json-schema-to-typescript-lite/node_modules/@apidevtools/json-schema-ref-parser": { + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-14.2.1.tgz", + "integrity": "sha512-HmdFw9CDYqM6B25pqGBpNeLCKvGPlIx1EbLrVL0zPvj50CJQUHyBNBw45Muk0kEIkogo1VZvOKHajdMuAzSxRg==", + "license": "MIT", + "dependencies": { + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 20" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + }, + "peerDependencies": { + "@types/json-schema": "^7.0.15" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "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==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leven": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-4.1.0.tgz", + "integrity": "sha512-KZ9W9nWDT7rF7Dazg8xyLHGLrmpgq2nVNFUckhqdW3szVP6YhCpp/RAnpmVExA9JvrMynjwSLVrEj3AepHR6ew==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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.31.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", + "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", + "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.31.1", + "lightningcss-darwin-arm64": "1.31.1", + "lightningcss-darwin-x64": "1.31.1", + "lightningcss-freebsd-x64": "1.31.1", + "lightningcss-linux-arm-gnueabihf": "1.31.1", + "lightningcss-linux-arm64-gnu": "1.31.1", + "lightningcss-linux-arm64-musl": "1.31.1", + "lightningcss-linux-x64-gnu": "1.31.1", + "lightningcss-linux-x64-musl": "1.31.1", + "lightningcss-win32-arm64-msvc": "1.31.1", + "lightningcss-win32-x64-msvc": "1.31.1" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", + "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", + "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.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", + "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", + "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.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", + "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", + "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.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", + "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", + "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.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", + "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", + "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.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", + "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "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.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", + "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "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.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", + "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "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.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", + "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "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.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", + "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", + "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.31.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", + "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", + "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/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "0.577.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.577.0.tgz", + "integrity": "sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==", + "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/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", + "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "license": "MIT", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", + "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", + "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "license": "MIT" + }, + "node_modules/motion": { + "version": "12.35.1", + "resolved": "https://registry.npmjs.org/motion/-/motion-12.35.1.tgz", + "integrity": "sha512-yEt/49kWC0VU/IEduDfeZw82eDemlPwa1cyo/gcEEUCN4WgpSJpUcxz6BUwakGabvJiTzLQ58J73515I5tfykQ==", + "license": "MIT", + "dependencies": { + "framer-motion": "^12.35.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/motion-dom": { + "version": "12.38.0", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.38.0.tgz", + "integrity": "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.36.0" + } + }, + "node_modules/motion-utils": { + "version": "12.36.0", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.36.0.tgz", + "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoevents": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/nanoevents/-/nanoevents-9.1.0.tgz", + "integrity": "sha512-Jd0fILWG44a9luj8v5kED4WI+zfkkgwKyRQKItTtlPfEsh7Lznfi1kr8/iZ+XAIss4Qq5GqRB0qtWbaz9ceO/A==", + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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/next-themes": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", + "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/node-releases": { + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", + "license": "MIT" + }, + "node_modules/oauth4webapi": { + "version": "3.8.5", + "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.5.tgz", + "integrity": "sha512-A8jmyUckVhRJj5lspguklcl90Ydqk61H3dcU0oLhH3Yv13KpAliKTt5hknpGGPZSSfOwGyraNEFmofDYH+1kSg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.5.tgz", + "integrity": "sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==", + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.1.0", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "license": "MIT" + }, + "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-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-wait-for": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-3.2.0.tgz", + "integrity": "sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA==", + "license": "MIT", + "dependencies": { + "p-timeout": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pagefind": { + "version": "1.5.0-beta.1", + "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.5.0-beta.1.tgz", + "integrity": "sha512-TOOP7e1C7Nd82wWFu2P5ElIFbNLiqdrKlBz6/BpyeJ6t17NtldrQyPmsBiHsv+eu7E6uXo7lG9MYsUcLMk+6ew==", + "license": "MIT", + "bin": { + "pagefind": "lib/runner/bin.cjs" + }, + "optionalDependencies": { + "@pagefind/darwin-arm64": "1.5.0-beta.1", + "@pagefind/darwin-x64": "1.5.0-beta.1", + "@pagefind/freebsd-x64": "1.5.0-beta.1", + "@pagefind/linux-arm64": "1.5.0-beta.1", + "@pagefind/linux-x64": "1.5.0-beta.1", + "@pagefind/windows-x64": "1.5.0-beta.1" + } + }, + "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/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-srcset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", + "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==", + "license": "MIT" + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", + "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "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/piscina": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.1.4.tgz", + "integrity": "sha512-7uU4ZnKeQq22t9AsmHGD2w4OYQGonwFnTypDypaWi7Qr2EvQIFVtG8J5D/3bE7W123Wdc9+v4CZDu5hJXVCtBg==", + "license": "MIT", + "engines": { + "node": ">=20.x" + }, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/posthog-node": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-5.26.0.tgz", + "integrity": "sha512-DK1XF/RiunhvT57cFyPxW9OaliZzl5aREHFwY/AISL3MVOaDUb4wIccMn0G3ws3Ounen8iGH7xvzZQ0x2vEOEQ==", + "license": "MIT", + "dependencies": { + "@posthog/core": "1.23.1" + }, + "engines": { + "node": "^20.20.0 || >=22.22.0" + } + }, + "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/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/react": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.4" + } + }, + "node_modules/react-error-boundary": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.1.1.tgz", + "integrity": "sha512-BrYwPOdXi5mqkk5lw+Uvt0ThHx32rCt3BkukS4X23A2AIWDPSGX6iaWTc0y9TU/mHDA/6qOSGel+B2ERkOvD1w==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-hook-form": { + "version": "7.71.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.2.tgz", + "integrity": "sha512-1CHvcDYzuRUNOflt4MOq3ZM46AronNJtQ1S7tnX6YN4y72qhgiUItpacZUAQ0TyWYci3yz1X+rXaSxiuEm86PA==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-is": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.4.tgz", + "integrity": "sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==", + "license": "MIT" + }, + "node_modules/react-markdown": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", + "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "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-router": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz", + "integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==", + "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-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/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", + "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", + "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "license": "MIT" + }, + "node_modules/rehype-mdx-import-media": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/rehype-mdx-import-media/-/rehype-mdx-import-media-1.2.0.tgz", + "integrity": "sha512-rf+2qnPv3LTqLtCr8GjhHUja2TEbmwWtD1o4jigrmGWbVDggOMxyNeqJhGpC4E3vtH+sY+a+u9WPSEaskEWPFA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-properties-to-mdx-jsx-attributes": "^1.0.0", + "parse-srcset": "^1.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-slug": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", + "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "github-slugger": "^2.0.0", + "hast-util-heading-rank": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-k8YPo5MGvl8l4gGxOH6Zk4Fa2AhDACN5eqKnKZcHDORZQS15hlnezlBHj2lqyDiqzApNmYOMTibkEJbMSKU25w==", + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "node_modules/remark-comment/node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/remark-comment/node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/remark-comment/node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/remark-comment/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/remark-directive": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", + "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-directive-rehype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remark-directive-rehype/-/remark-directive-rehype-1.0.0.tgz", + "integrity": "sha512-10XpgKG/v5pqSpp/lLXEqqJ+EeHY1mhmcgSgno1Zw+PygBvkMguY9X39dj5sMkaMt0GbUmlhWidbBqLzFLZmXg==", + "license": "Unlicense", + "dependencies": { + "hastscript": "^9.0.1", + "unist-util-map": "^4.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", + "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx-frontmatter": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/remark-mdx-frontmatter/-/remark-mdx-frontmatter-5.2.0.tgz", + "integrity": "sha512-U/hjUYTkQqNjjMRYyilJgLXSPF65qbLPdoESOkXyrwz2tVyhAnm4GUKhfXqOOS9W34M3545xEMq+aMpHgVjEeQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "estree-util-value-to-estree": "^3.0.0", + "toml": "^3.0.0", + "unified": "^11.0.0", + "unist-util-mdx-define": "^1.0.0", + "yaml": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-in-the-middle": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-8.0.1.tgz", + "integrity": "sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3" + }, + "engines": { + "node": ">=9.3.0 || >=8.10.0 <9.0.0" + } + }, + "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/roarr": { + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-7.21.4.tgz", + "integrity": "sha512-qvfUKCrpPzhWmQ4NxRYnuwhkI5lwmObhBU06BCK/lpj6PID9nL4Hk6XDwek2foKI+TMaV+Yw//XZshGF2Lox/Q==", + "license": "BSD-3-Clause", + "dependencies": { + "fast-printf": "^1.6.9", + "safe-stable-stringify": "^2.4.3", + "semver-compare": "^1.0.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "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/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "license": "MIT" + }, + "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/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "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==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.23.0.tgz", + "integrity": "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.23.0", + "@shikijs/engine-javascript": "3.23.0", + "@shikijs/engine-oniguruma": "3.23.0", + "@shikijs/langs": "3.23.0", + "@shikijs/themes": "3.23.0", + "@shikijs/types": "3.23.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sitemap": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-9.0.1.tgz", + "integrity": "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==", + "license": "MIT", + "dependencies": { + "@types/node": "^24.9.2", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.4.1" + }, + "bin": { + "sitemap": "dist/esm/cli.js" + }, + "engines": { + "node": ">=20.19.5", + "npm": ">=10.8.2" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "24.12.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz", + "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/sitemap/node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "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/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "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/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "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.5.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.5.0.tgz", + "integrity": "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", + "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz", + "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "license": "MIT" + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-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==", + "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/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", + "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-map/-/unist-util-map-4.0.0.tgz", + "integrity": "sha512-HJs1tpkSmRJUzj6fskQrS5oYhBYlmtcvy4SepdDEEsL04FjBrgF0Mgggvxc1/qGBGgW7hRh9+UBK1aqTEnBpIA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-mdx-define": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-mdx-define/-/unist-util-mdx-define-1.1.2.tgz", + "integrity": "sha512-9ncH7i7TN5Xn7/tzX5bE3rXgz1X/u877gYVAUB3mLeTKYJmQHmqKTDBi6BTGXV7AeolBCI9ErcVsOt2qryoD0g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "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==", + "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/uri-js/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/url": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", + "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", + "license": "MIT", + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.12.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz", + "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==", + "license": "MIT" + }, + "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/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vaul": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz", + "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-dialog": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "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/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/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/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "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" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zudoku": { + "version": "0.71.10", + "resolved": "https://registry.npmjs.org/zudoku/-/zudoku-0.71.10.tgz", + "integrity": "sha512-mt0KwH7XhIJB9qFGSXa2SBQaeYVEsxChOfgZ3PNCo6gJEkQnSj185vfNVWCLYkVGochllxTbf274jxqUf6fRew==", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "15.3.1", + "@envelop/core": "5.5.1", + "@graphql-typed-document-node/core": "3.2.0", + "@hono/node-server": "1.19.11", + "@lekoarts/rehype-meta-as-attributes": "3.0.3", + "@mdx-js/react": "3.1.1", + "@mdx-js/rollup": "3.1.1", + "@pothos/core": "4.12.0", + "@radix-ui/react-accordion": "1.2.12", + "@radix-ui/react-alert-dialog": "1.1.15", + "@radix-ui/react-aspect-ratio": "1.1.8", + "@radix-ui/react-checkbox": "1.3.3", + "@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-hover-card": "1.1.15", + "@radix-ui/react-label": "2.1.8", + "@radix-ui/react-navigation-menu": "1.2.14", + "@radix-ui/react-popover": "1.1.15", + "@radix-ui/react-progress": "1.1.8", + "@radix-ui/react-radio-group": "1.3.8", + "@radix-ui/react-scroll-area": "1.2.10", + "@radix-ui/react-select": "2.2.6", + "@radix-ui/react-separator": "^1.1.8", + "@radix-ui/react-slider": "1.3.6", + "@radix-ui/react-slot": "1.2.4", + "@radix-ui/react-switch": "1.2.6", + "@radix-ui/react-tabs": "1.1.13", + "@radix-ui/react-toggle": "1.1.10", + "@radix-ui/react-toggle-group": "1.1.11", + "@radix-ui/react-tooltip": "1.2.8", + "@radix-ui/react-visually-hidden": "1.2.4", + "@scalar/openapi-parser": "0.23.13", + "@sentry/node": "10.42.0", + "@shikijs/langs": "3.23.0", + "@shikijs/rehype": "3.23.0", + "@shikijs/themes": "3.23.0", + "@shikijs/transformers": "3.23.0", + "@tailwindcss/typography": "0.5.19", + "@tailwindcss/vite": "4.2.1", + "@tanem/react-nprogress": "6.0.2", + "@tanstack/react-query": "5.90.21", + "@types/react": "19.2.14", + "@types/react-dom": "19.2.3", + "@vitejs/plugin-react": "5.1.4", + "@x0k/json-schema-merge": "1.0.2", + "@zudoku/httpsnippet": "10.0.9", + "@zudoku/react-helmet-async": "2.0.5", + "@zuplo/mcp": "0.0.32", + "bs58": "6.0.0", + "class-variance-authority": "0.7.1", + "clsx": "2.1.1", + "cmdk": "1.1.1", + "dotenv": "17.3.1", + "embla-carousel-react": "8.6.0", + "esbuild": "^0.27.4", + "estree-util-is-identifier-name": "3.0.0", + "estree-util-value-to-estree": "3.5.0", + "fast-equals": "6.0.0", + "glob": "13.0.6", + "glob-parent": "6.0.2", + "graphql": "16.13.1", + "graphql-type-json": "0.3.2", + "graphql-yoga": "5.18.0", + "gray-matter": "4.0.3", + "hast-util-heading-rank": "3.0.0", + "hast-util-to-jsx-runtime": "2.3.6", + "hast-util-to-string": "3.0.1", + "hono": "4.12.5", + "http-terminator": "3.2.0", + "javascript-stringify": "2.1.0", + "json-schema-to-typescript-lite": "15.0.0", + "loglevel": "1.9.2", + "lucide-react": "0.577.0", + "mdast-util-from-markdown": "2.0.2", + "mdast-util-mdx": "3.0.0", + "mdast-util-mdx-jsx": "3.2.0", + "micromark-extension-mdxjs": "3.0.0", + "motion": "12.35.1", + "nanoevents": "9.1.0", + "next-themes": "0.4.6", + "oauth4webapi": "3.8.5", + "openapi-types": "12.1.3", + "pagefind": "1.5.0-beta.1", + "picocolors": "1.1.1", + "piscina": "5.1.4", + "posthog-node": "5.26.0", + "react-error-boundary": "6.1.1", + "react-hook-form": "7.71.2", + "react-is": "19.2.4", + "react-markdown": "10.1.0", + "react-router": "7.13.0", + "rehype-mdx-import-media": "1.2.0", + "rehype-raw": "7.0.0", + "rehype-slug": "6.0.0", + "remark-comment": "1.0.0", + "remark-directive": "3.0.1", + "remark-directive-rehype": "1.0.0", + "remark-frontmatter": "5.0.0", + "remark-gfm": "4.0.1", + "remark-mdx-frontmatter": "5.2.0", + "rollup": "4.59.0", + "semver": "7.7.4", + "shiki": "3.23.0", + "sitemap": "9.0.1", + "strip-ansi": "7.2.0", + "tailwind-merge": "3.5.0", + "tailwindcss": "4.2.1", + "tw-animate-css": "1.4.0", + "unified": "11.0.5", + "unist-util-visit": "5.1.0", + "vaul": "1.1.2", + "vfile": "6.0.3", + "vite": "7.3.1", + "yaml": "2.8.2", + "yargs": "18.0.0", + "zod": "4.3.6", + "zustand": "5.0.11" + }, + "bin": { + "zudoku": "cli.js" + }, + "peerDependencies": { + "@azure/msal-browser": "^4.13.0", + "@sentry/react": "^10.0.0", + "@supabase/supabase-js": "^2.49.4", + "firebase": "^12.6.0", + "mermaid": "^11.0.0", + "react": ">=19.2.0", + "react-dom": ">=19.2.0" + }, + "peerDependenciesMeta": { + "@azure/msal-browser": { + "optional": true + }, + "@sentry/react": { + "optional": true + }, + "@supabase/supabase-js": { + "optional": true + }, + "firebase": { + "optional": true + }, + "mermaid": { + "optional": true + } + } + }, + "node_modules/zustand": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.11.tgz", + "integrity": "sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..867d8302 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "docs", + "version": "0.1.0", + "type": "module", + "private": true, + "scripts": { + "dev": "zudoku dev --port 3131", + "build": "zudoku build", + "preview": "zudoku preview", + "lint": "eslint" + }, + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "hast-util-to-html": "^9.0.5", + "oniguruma-parser": "^0.12.1", + "react": ">=19.0.0", + "react-dom": ">=19.0.0", + "regex-utilities": "^2.3.0", + "zudoku": "^0.71.9" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "eslint": "^9.14.0" + } +} diff --git a/pages/cli/overview.mdx b/pages/cli/overview.mdx new file mode 100644 index 00000000..9eecac58 --- /dev/null +++ b/pages/cli/overview.mdx @@ -0,0 +1,70 @@ +--- +title: CLI Overview +description: Command-line interfaces for Unikraft Cloud +--- + +Unikraft Cloud provides two command-line interfaces for managing your unikernel deployments: + +## unikraft CLI (recommended) + +The **unikraft** CLI is the new, official command-line interface for [Unikraft Cloud](https://unikraft.cloud). +It provides a modern, streamlined experience for deploying and managing unikernels globally. + +### Features + +- **Deploy Instantly** - Run unikernel images as serverless instances with `unikraft run` +- **Global Infrastructure** - Deploy across supported metros with automatic multi-region support +- **Resource Management** - Create, read, update, and delete instances, volumes, services, certificates, and images +- **Scale-to-Zero** - Built-in support for scale-to-zero policies to optimize costs +- **Output Formats** - Machine-readable JSON or human-friendly text output +- **Profile Management** - Switch between accounts and configurations +- **Shell Completions** - Tab completion for Bash, Zsh, Fish, and PowerShell + +### Quick start + +```sh +# Login to Unikraft Cloud +unikraft login + +# Deploy an instance +unikraft run --metro=fra -p 443:8080/http+tls nginx:latest + +# List instances +unikraft instances list +``` + +[View unikraft CLI documentation](/docs/cli/unikraft) + +--- + +## Kraft cloud CLI (legacy) + +The **kraft cloud** CLI is part of the [KraftKit](https://github.com/unikraft/kraftkit) toolchain. +It remains fully supported, and new users should use the `unikraft` CLI above. + +### Quick start + +```sh +# Deploy an instance +kraft cloud deploy -p 443:8080/http+tls -M 512 . + +# List instances +kraft cloud instance list +``` + +[View kraft cloud CLI documentation](/docs/cli/kraft/overview) + +--- + +## Choosing a CLI + +| Feature | unikraft | kraft cloud | +|---------|----------|-------------| +| Recommended for new users | Yes | No | +| Profile management | Yes | Limited | +| Scale-to-zero support | Yes | Yes | +| Compose support | No | Yes | +| Build from source | No | Yes | + +If you are getting started with Unikraft Cloud, use the **unikraft** CLI. +If you need Docker Compose-style workflows or building images from source, use the **kraft cloud** CLI. diff --git a/public/logo-dark.svg b/public/logo-dark.svg new file mode 100644 index 00000000..0609474b --- /dev/null +++ b/public/logo-dark.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/logo-light.svg b/public/logo-light.svg new file mode 100644 index 00000000..81bf2f29 --- /dev/null +++ b/public/logo-light.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/pagefind/pagefind.js b/public/pagefind/pagefind.js new file mode 100644 index 00000000..b37bb638 --- /dev/null +++ b/public/pagefind/pagefind.js @@ -0,0 +1 @@ +throw new Error("NOT_BUILT_YET"); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..07158f5c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ESNext", "DOM", "DOM.Iterable", "WebWorker"], + "module": "ESNext", + "moduleResolution": "Bundler", + "useDefineForClassFields": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "resolveJsonModule": true, + "isolatedModules": true, + "useUnknownInCatchVariables": false, + "jsx": "react-jsx" + }, + "include": ["src", "zudoku.config.tsx"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 00000000..b0235333 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,6 @@ +/** @type {import('vite').UserConfig} */ +export default { + // This is used at build-time to adjust all the paths. This is necessary as + // the site is built statically and placed inside of a /docs subdirectory. + base: '/docs', +}; diff --git a/zudoku.config.tsx b/zudoku.config.tsx new file mode 100644 index 00000000..3e895498 --- /dev/null +++ b/zudoku.config.tsx @@ -0,0 +1,540 @@ +import type { ZudokuConfig } from "zudoku"; + +const config: ZudokuConfig = { + metadata: { + title: "%s | Unikraft Cloud Docs", + favicon: "/favicon.ico", + }, + basePath: "/docs", + site: { + logo: { + src: { light: "/logo-light.svg", dark: "/logo-dark.svg" }, + alt: "Zudoku", + width: "130px", + }, + showPoweredBy: false, + }, + docs: { + files: "/pages/**/*.{md,mdx}", + defaultOptions: { + showLastModified: true, + suggestEdit: { + text: "Edit this page", + url: "https://github.com/unikraft-cloud/docs/edit/prod-stable/{filePath}", + }, + }, + llms: { + llmsTxt: true, // Generate llms.txt + llmsTxtFull: true, // Generate llms-full.txt + includeProtected: false, // Exclude protected routes + }, + }, + syntaxHighlighting: { + languages: [ + "c", + "go", + "html", + "javascript", + "json", + "python", + "rust", + "shellscript", + "typescript", + "yaml", + ], + themes: { + light: "github-light", + dark: "github-dark-high-contrast", + }, + }, + navigation: [ + { + type: "category", + label: "Documentation", + icon: "book-open-text", + items: [ + { + type: "category", + label: "Getting Started", + icon: "star", + collapsed: false, + items: [ + "/introduction", + "/faq", + ], + }, + { + type: "category", + label: "Features", + icon: "rocket", + collapsed: false, + items: [ + "/features/scale-to-zero", + "/features/load-balancing", + "/features/snapshots", + "/features/autoscale", + "/features/roms", + "/features/autokill", + "/features/cron-jobs", + "/features/forking", + ], + }, + { + type: "category", + label: "Use Cases", + icon: "lightbulb", + collapsed: false, + items: [ + "/use-cases/headless-browsers", + "/use-cases/mcp-servers", + "/use-cases/serverless-databases", + "/use-cases/remote-ides", + "/use-cases/api-gateways", + "/use-cases/webhooks", + ], + }, + { + type: "category", + label: "Cloud Platform", + icon: "cloud", + collapsed: false, + items: [ + "/platform/metros", + "/platform/instances", + "/platform/domains", + "/platform/certificates", + "/platform/services", + "/platform/volumes", + "/platform/images", + "/platform/troubleshooting", + "/platform/delete-locks", + "/platform/quotas", + "/platform/metrics", + "/platform/tagging", + ], + }, + { + type: "category", + label: "Integrations", + icon: "blocks", + collapsed: false, + items: [ + "/integrations/kubernetes", + "/integrations/sdks/go", + ], + }, + ], + }, + { + type: "category", + label: "Guides", + icon: "graduation-cap", + items: [ + "/guides/overview", + "/guides/bun", + "/guides/caddy", + "/guides/cpp-boost", + "/guides/cpp", + "/guides/django", + "/guides/dotnet", + "/guides/dragonfly", + "/guides/duckdb", + "/guides/elixir", + "/guides/erlang", + "/guides/ferretdb", + "/guides/flask-sqlite", + "/guides/flask", + "/guides/go", + "/guides/grafana", + "/guides/haproxy", + "/guides/hugo", + "/guides/imaginary", + "/guides/java", + "/guides/llama2", + "/guides/lua", + "/guides/mariadb", + "/guides/memcached", + "/guides/minio", + "/guides/mongodb", + "/guides/nextjs", + "/guides/nginx", + "/guides/node", + "/guides/opentelemetry-collector", + "/guides/perl", + "/guides/php", + "/guides/postgres", + "/guides/prisma", + "/guides/puppeteer", + "/guides/python", + "/guides/rails", + "/guides/redis", + "/guides/remix", + "/guides/ruby", + "/guides/rust-rocket", + "/guides/rust-tokio", + "/guides/rust-actix", + "/guides/skipper", + "/guides/solidjs", + "/guides/spin", + "/guides/springboot", + "/guides/sveltekit", + "/guides/traefik", + "/guides/tyk", + "/guides/wazero", + "/guides/wordpress", + ] + }, + { + type: "category", + label: "Tutorials", + icon: "book", + items: [ + "/tutorials/environment-variables", + "/tutorials/docker-to-ukc", + "/tutorials/instance-metrics", + "/tutorials/rootfs-formats", + "/tutorials/rootfs-compression", + "/tutorials/rootfs-volumes-roms", + "/tutorials/scale-to-zero-triggers", + "/tutorials/network-communication" + ] + }, + { + type: "category", + label: "CLI Reference", + icon: "terminal", + items: [ + "/cli/overview", + { + type: "category", + label: "unikraft", + icon: "terminal", + collapsed: false, + items: [ + "/cli/unikraft", + "/cli/unikraft/login", + "/cli/unikraft/logout", + "/cli/unikraft/completion", + "/cli/unikraft/run", + "/cli/unikraft/build", + "/cli/unikraft/tui", + "/cli/unikraft/upgrade", + "/cli/unikraft/version", + { + type: "category", + label: "unikraft config", + icon: "settings", + collapsed: false, + items: [ + "/cli/unikraft/config", + "/cli/unikraft/config/get", + ], + }, + { + type: "category", + label: "unikraft profile", + icon: "user-circle", + collapsed: false, + items: [ + "/cli/unikraft/profile", + "/cli/unikraft/profile/get", + "/cli/unikraft/profile/list", + "/cli/unikraft/profile/use", + ], + }, + { + type: "category", + label: "unikraft metros", + icon: "earth", + collapsed: false, + items: [ + "/cli/unikraft/metros", + "/cli/unikraft/metros/get", + "/cli/unikraft/metros/list", + ], + }, + { + type: "category", + label: "unikraft instances", + icon: "rocket", + collapsed: false, + items: [ + "/cli/unikraft/instances", + "/cli/unikraft/instances/create", + "/cli/unikraft/instances/delete", + "/cli/unikraft/instances/edit", + "/cli/unikraft/instances/get", + "/cli/unikraft/instances/list", + "/cli/unikraft/instances/logs", + "/cli/unikraft/instances/restart", + "/cli/unikraft/instances/start", + "/cli/unikraft/instances/stop", + "/cli/unikraft/instances/wait", + ], + }, + { + type: "category", + label: "unikraft volumes", + icon: "cylinder", + collapsed: false, + items: [ + "/cli/unikraft/volumes", + "/cli/unikraft/volumes/clone", + "/cli/unikraft/volumes/create", + "/cli/unikraft/volumes/delete", + "/cli/unikraft/volumes/edit", + "/cli/unikraft/volumes/get", + "/cli/unikraft/volumes/list", + "/cli/unikraft/volumes/wait", + ], + }, + { + type: "category", + label: "unikraft services", + icon: "split", + collapsed: false, + items: [ + "/cli/unikraft/services", + "/cli/unikraft/services/create", + "/cli/unikraft/services/delete", + "/cli/unikraft/services/edit", + "/cli/unikraft/services/get", + "/cli/unikraft/services/list", + "/cli/unikraft/services/wait", + ], + }, + { + type: "category", + label: "unikraft certificates", + icon: "shield-check", + collapsed: false, + items: [ + "/cli/unikraft/certificates", + "/cli/unikraft/certificates/create", + "/cli/unikraft/certificates/delete", + "/cli/unikraft/certificates/get", + "/cli/unikraft/certificates/list", + "/cli/unikraft/certificates/wait", + ], + }, + { + type: "category", + label: "unikraft images", + icon: "package", + collapsed: false, + items: [ + "/cli/unikraft/images", + "/cli/unikraft/images/copy", + "/cli/unikraft/images/get", + "/cli/unikraft/images/list", + ], + }, + ] + }, + { + type: "category", + label: "kraft cloud", + icon: "terminal", + collapsed: false, + items: [ + "/cli/kraft/overview", + "/cli/kraft/deploy", + "/cli/kraft/quota", + "/cli/kraft/tunnel", + { + type: "category", + label: "kraft cloud cert", + icon: "shield-check", + collapsed: false, + items: [ + "/cli/kraft/cert", + "/cli/kraft/cert/create", + "/cli/kraft/cert/get", + "/cli/kraft/cert/list", + "/cli/kraft/cert/remove", + ], + }, + { + type: "category", + label: "kraft cloud compose", + icon: "book-open", + collapsed: false, + items: [ + "/cli/kraft/compose", + "/cli/kraft/compose/build", + "/cli/kraft/compose/create", + "/cli/kraft/compose/down", + "/cli/kraft/compose/log", + "/cli/kraft/compose/ls", + "/cli/kraft/compose/ps", + "/cli/kraft/compose/push", + "/cli/kraft/compose/start", + "/cli/kraft/compose/stop", + "/cli/kraft/compose/up", + ], + }, + { + type: "category", + label: "kraft cloud image", + icon: "package", + collapsed: false, + items: [ + "/cli/kraft/image", + "/cli/kraft/image/list", + "/cli/kraft/image/remove", + ], + }, + { + type: "category", + label: "kraft cloud instance", + icon: "rocket", + collapsed: false, + items: [ + "/cli/kraft/instance", + "/cli/kraft/instance/create", + "/cli/kraft/instance/get", + "/cli/kraft/instance/list", + "/cli/kraft/instance/logs", + "/cli/kraft/instance/remove", + "/cli/kraft/instance/start", + "/cli/kraft/instance/stop", + ], + }, + { + type: "category", + label: "kraft cloud metro", + icon: "earth", + collapsed: false, + items: [ + "/cli/kraft/metro", + "/cli/kraft/metro/list", + ], + }, + { + type: "category", + label: "kraft cloud scale", + icon: "arrow-up-1-0", + collapsed: false, + items: [ + "/cli/kraft/scale", + "/cli/kraft/scale/add", + "/cli/kraft/scale/get", + "/cli/kraft/scale/init", + "/cli/kraft/scale/remove", + "/cli/kraft/scale/reset", + ], + }, + { + type: "category", + label: "kraft cloud service", + icon: "split", + collapsed: false, + items: [ + "/cli/kraft/service", + "/cli/kraft/service/create", + "/cli/kraft/service/get", + "/cli/kraft/service/list", + "/cli/kraft/service/remove", + ], + }, + { + type: "category", + label: "kraft cloud volume", + icon: "cylinder", + collapsed: false, + items: [ + "/cli/kraft/volume", + "/cli/kraft/volume/attach", + "/cli/kraft/volume/create", + "/cli/kraft/volume/detach", + "/cli/kraft/volume/get", + "/cli/kraft/volume/import", + "/cli/kraft/volume/list", + "/cli/kraft/volume/remove", + ], + }, + ] + }, + ], + } as any, + { + type: "link", + label: "Platform API", + icon: "unplug", + to: "/api/platform/v1", + }, + ], + search: { + type: "pagefind", + }, + redirects: [ + { from: "/", to: "/introduction" }, + { from: "/cli", to: "/cli/overview" }, + { from: "/guides", to: "/guides/overview" }, + ], + apis: [ + { + type: "file", + input: "./apis/platform.yaml", + path: "/api/platform/v1", + }, + ], + theme: { + fonts: { + sans: { + fontFamily: "Inter, sans-serif", + url: "https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap", + }, + mono: { + fontFamily: "IBM Plex Mono, monospace", + url: "https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;700&display=swap", + }, + }, + light: { + background: "#ffffff", // Main background color + foreground: "#020817", // Main text color + card: "#ffffff", // Card background color + cardForeground: "#020817", // Card text color + popover: "#ffffff", // Popover background color + popoverForeground: "#020817", // Popover text color + primary: "#2563eb", // Primary action color + primaryForeground: "#ffffff", // Text color on primary backgrounds + secondary: "#f1f5f9", // Secondary action color + secondaryForeground: "#020817", // Text color on secondary backgrounds + muted: "#f1f5f9", // Muted/subtle background color + mutedForeground: "#64748b", // Text color for muted elements + accent: "#f1f5f9", // Accent color for highlights + accentForeground: "#020817", // Text color on accent backgrounds + destructive: "#ef4444", // Color for destructive actions + destructiveForeground: "#ffffff", // Text color on destructive backgrounds + border: "#cbd5e1", // Border color + input: "#e2e8f0", // Input field border color + ring: "#0284c7", // Focus ring color + radius: "0.4rem", // Border radius value + }, + dark: { + background: "#000000", // Main background color + foreground: "#dbeafe", // Main text color + card: "#000000", // Card background color + cardForeground: "#dbeafe", // Card text color + popover: "hsl(20 14.3% 4.1%)", // Popover background color + popoverForeground: "hsl(60 9.1% 97.8%)", // Popover text color + primary: "#2563eb", // Primary action color + primaryForeground: "#ffffff", // Text color on primary backgrounds + secondary: "var(--color-slate-800)", // Secondary action color + secondaryForeground: "hsl(60 9.1% 97.8%)", // Text color on secondary backgrounds + muted: "var(--color-slate-900)", // Muted/subtle background color + mutedForeground: "var(--color-slate-600)", // Text color for muted elements + accent: "var(--color-slate-800)", // Accent color for highlights + accentForeground: "hsl(60 9.1% 97.8%)", // Text color on accent backgrounds + destructive: "var(--color-rose-800)", // Color for destructive actions + destructiveForeground: "hsl(60 9.1% 97.8%)", // Text color on destructive backgrounds + border: "#1e293b", // Border color + input: "#334155", // Input field border color + ring: "var(--color-amber-500)", // Focus ring color + radius: "0.4rem", // Border radius value + }, + }, +}; + +export default config; From bf7e3d55d61c95875a72a1d83950332548c3f087 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Wed, 1 Apr 2026 15:30:36 +0300 Subject: [PATCH 081/131] fix(docs): General fixes and touch-ups Signed-off-by: Alex-Andrei Cioc --- pages/cli/registries.mdx | 20 ++++++------- pages/faq.mdx | 33 +++++++++++++--------- pages/features/load-balancing.mdx | 5 ++-- pages/features/roms.mdx | 10 +++---- pages/features/scale-to-zero.mdx | 6 ++-- pages/introduction.mdx | 2 +- pages/platform/certificates.mdx | 6 ++-- pages/platform/delete-locks.mdx | 25 ++++++++-------- pages/platform/domains.mdx | 10 +++---- pages/platform/images.mdx | 20 ++++++------- pages/platform/instances.mdx | 4 +-- pages/platform/metrics.mdx | 8 ++++-- pages/platform/quotas.mdx | 8 ++++-- pages/platform/services.mdx | 18 ++++++------ pages/platform/tagging.mdx | 2 +- pages/platform/troubleshooting.mdx | 10 +++---- pages/platform/volumes.mdx | 24 ++++++++-------- pages/tutorials/docker-to-ukc.mdx | 16 +++++------ pages/tutorials/instance-metrics.mdx | 4 +-- pages/tutorials/rootfs-formats.mdx | 2 +- pages/tutorials/rootfs-volumes-roms.mdx | 4 +-- pages/tutorials/scale-to-zero-triggers.mdx | 3 +- pages/use-cases/api-gateways.mdx | 13 +-------- pages/use-cases/headless-browsers.mdx | 4 +-- pages/use-cases/mcp-servers.mdx | 12 +++----- pages/use-cases/remote-ides.mdx | 1 - pages/use-cases/serverless-databases.mdx | 10 +++---- pages/use-cases/webhooks.mdx | 12 +++----- 28 files changed, 144 insertions(+), 148 deletions(-) diff --git a/pages/cli/registries.mdx b/pages/cli/registries.mdx index cfc057fd..5e992d6f 100644 --- a/pages/cli/registries.mdx +++ b/pages/cli/registries.mdx @@ -22,8 +22,8 @@ The platform handles synchronization between them. The platform addresses images using the standard OCI reference format: ``` -index.unikraft.io//: -index..unikraft.cloud//: +index.unikraft.io//: +index..unikraft.cloud//: ``` For example: @@ -36,7 +36,7 @@ index.node1.unikraft.cloud/alice/http-python312:latest index.node1.unikraft.cloud/alice/http-python312@sha256:278cb8b1... ``` -The `` segment is your Unikraft Cloud account name, available as the `UKC_USER` environment variable in most guides. +The `` segment is your Unikraft Cloud organization, available as the `UKC_USER` environment variable in most guides. Tags are arbitrary strings. The platform defaults to `latest` when you don't specify a tag. You can also refer to images by digest to pin to an exact version. @@ -82,12 +82,12 @@ The simplest way to push an image is to use the CLI to build, package, push, and ```bash title="central registry" - unikraft build . --output index.unikraft.io//:latest - unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --name index.unikraft.io//:latest + unikraft build . --output index.unikraft.io//:latest + unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --name index.unikraft.io//:latest ``` ```bash title="local registry" - unikraft build . --output index..unikraft.cloud//:latest - unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --name index..unikraft.cloud//:latest + unikraft build . --output index..unikraft.cloud//:latest + unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --name index..unikraft.cloud//:latest ``` @@ -222,6 +222,6 @@ When creating an instance directly from an existing image, reference it by tag o ## Learn more -* [Images](/platform/images): build, package, and deploy workflow -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview) -* Unikraft Cloud's [REST API reference](/api/platform/v1) +* [Images](/platform/images): build, package, and deploy workflow. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* Unikraft Cloud's [REST API reference](/api/platform/v1). diff --git a/pages/faq.mdx b/pages/faq.mdx index 7cd44d45..cb18b734 100644 --- a/pages/faq.mdx +++ b/pages/faq.mdx @@ -3,14 +3,16 @@ title: FAQ navigation_icon: circle-question-mark --- -#### What's Unikraft? +{/* vale off */} +#### What is Unikraft? +{/* vale on */} Unikraft is the company behind Unikraft Cloud, a next-generation compute platform that leverages microVM technology. It delivers millisecond cold boots and scale-to-zero autoscaling so you never pay for idle resources. {/* vale off */} -#### What's a microVM? +#### What is a microVM? Definitionally, a microVM is any virtual machine launched with Firecracker, an open source Virtual Machine Monitor (VMM) from Amazon, originally done for AWS Lambda. {/* vale on */} @@ -65,10 +67,13 @@ You'll need a Dockerfile and Kraftfile. See any of the apps/langs guides [here](/guides/bun) to see examples. -#### What's `kraft`? +{/* vale off */} +#### What is `kraft`? +{/* vale on */} -`kraft` is Unikraft Cloud's [open source CLI tool written in Go](https://github.com/unikraft/kraftkit). +`kraft` is Unikraft Cloud's legacy [open source CLI tool written in Go](https://github.com/unikraft/kraftkit). You can control Unikraft Cloud with it as well as build unikernels and try things out locally. +If you want to interact with the latest features of Unikraft Cloud, you should use the new [open source `unikraft` CLI tool](https://github.com/unikraft/cli), written in Go as well. #### How's millisecond scale-to-zero achieved? @@ -136,7 +141,7 @@ Unikraft can provide cost savings in many ways: #### What's the relationship between the Unikraft open source project and Unikraft Cloud? Unikraft OSS allows you to build and run unikernels locally via `kraft run` (and even hack the Unikraft OS itself if you like tinkering!). -When you're ready to deploy, use the `unikraft` CLI (or the legacy `kraft cloud` CLI). +When you're ready to deploy to cloud, use the `unikraft` CLI (or the legacy `kraft cloud` CLI). #### Are you a replacement for Docker? @@ -171,12 +176,12 @@ Contact information is available for more details. Yes. Head on over to [unikraft.org](https://unikraft.org/docs/cli/install) to install the legacy `kraft` tool, and use `kraft run` to build, package and run your app locally. -When you're ready to deploy to cloud, use the `unikraft` CLI profiles or the legacy `kraft cloud` CLI. +When you're ready to deploy to cloud, use the [`unikraft`](https://github.com/unikraft/cli) CLI or the legacy `kraft cloud` CLI. #### Does Unikraft Cloud work on Mac/Windows/Linux? -Yes, the kraft tool can run on Mac, Windows or Linux. +Yes, the CLI can run on Mac, Windows or Linux. #### How can you track instances on Unikraft Cloud? @@ -185,7 +190,9 @@ Unikraft provides full log support for all users. Paying customers get access to Prometheus metrics. -#### What's a unikernel? +{/* vale off */} +#### What is a unikernel? +{/* vale on */} A unikernel is a specialized virtual machine. Each target app gets a distro and kernel containing only the code it needs. @@ -215,14 +222,14 @@ Other unikernel projects exist, but most are research efforts, unmaintained, or [Yes!](https://github.com/unikraft-cloud/terraform-provider-ukc) -#### When should you use Kraftkit stable and/or staging? +#### When should you use the CLI stable and/or staging? -You should use stable versions when initially trying out the Unikraft Platform and its features. +You should use stable versions when initially trying out the Unikraft Cloud Platform and its features. Any time you encounter a problem, it's good to first try out the latest staging version before forwarding the problem as it might have been already fixed. -There's also a chance that Kraft staging contains changes available only on non-stable nodes. +There's also a chance that staging contains changes available only on non-stable nodes. -#### What keywords does Kraftkit ignore from a Dockerfile? +#### What keywords does the CLI ignore from a Dockerfile? This is the current list of ignored keywords: `EXPOSE`, `HEALTHCHECK`, `ONBUILD`, `SHELL`, `STOPSIGNAL`, `VOLUME`. The `USER` keyword is relevant for running subsequent `RUN` instructions in the Dockerfile, but not for the `ENTRYPOINT` and `CMD` commands. @@ -263,7 +270,7 @@ This should be first experimented or discussed with a Unikraft Engineer to verif An image is specifically a pair of a kernel and a rootfs bundled together as different layers of an OCI package. To keep things light, certain optimizations are in place to not repush existing kernels and to reuse them from your account. -If these aren't automatically detected, kraft pushes the kernel again. +If these aren't automatically detected, the CLI pushes the kernel again. At the same time, things like ROMs use the same packaging systems, but push images with a missing kernel and only a rootfs. These have specific metadata that identifies them as ROMs. diff --git a/pages/features/load-balancing.mdx b/pages/features/load-balancing.mdx index 6e5a7063..ff800106 100644 --- a/pages/features/load-balancing.mdx +++ b/pages/features/load-balancing.mdx @@ -40,7 +40,8 @@ For example, use NGINX as the app: ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ -unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB nginx:latest +unikraft build . --output /nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB /nginx:latest ``` ```bash title="kraft" @@ -75,7 +76,7 @@ With this in place, it's now time to start a second instance and attach it to th ```bash title="unikraft" cd examples/nginx/ -unikraft run --metro=fra --service wandering-shape-n6mhimgn -m 256MiB nginx:latest +unikraft run --metro=fra --service wandering-shape-n6mhimgn -m 256MiB /nginx:latest ``` ```bash title="kraft" diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index a180584d..98953604 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -5,7 +5,7 @@ navigation_icon: hard-drive :::caution[**DISCLAIMER**] The ROM feature isn't currently enabled for the public Unikraft Cloud offering. -As such, the legacy [KraftKit CLI tool](/docs/cli/kraft/overview) can't entirely leverage this feature. +As such, the CLI can't entirely leverage this feature. For boxes where it's enabled, use it via the [Unikraft Cloud API](/api/platform/v1). ::: @@ -170,7 +170,7 @@ Package and push the base image: kraft pkg \ --plat kraftcloud \ --arch x86_64 \ - --name index.unikraft.io/"$UKC_USER"/http-python:latest \ + --name "$UKC_USER"/http-python:latest \ --rootfs-type erofs \ --push . ``` @@ -235,7 +235,7 @@ kraft pkg \ --no-kernel \ --plat kraftcloud \ --arch x86_64 \ - --name index.unikraft.io/"$UKC_USER"/my-rom1:latest \ + --name "$UKC_USER"/my-rom1:latest \ --rootfs-type erofs \ --push . @@ -244,7 +244,7 @@ kraft pkg \ --no-kernel \ --plat kraftcloud \ --arch x86_64 \ - --name index.unikraft.io/"$UKC_USER"/my-rom2:latest \ + --name "$UKC_USER"/my-rom2:latest \ --rootfs-type erofs \ --push . ``` @@ -399,6 +399,6 @@ kraft cloud instance rm test-http-python-rom1 test-http-python-rom2 ## Learn more -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [instance create](/cli/instance/create) subcommand. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the [instances API](/api/platform/v1/instances). * The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images and ROMs. diff --git a/pages/features/scale-to-zero.mdx b/pages/features/scale-to-zero.mdx index 1884b547..9be21953 100644 --- a/pages/features/scale-to-zero.mdx +++ b/pages/features/scale-to-zero.mdx @@ -185,7 +185,7 @@ This feature is currently under active development and may change in future rele Currently, internal traffic via Private FQDNs doesn't trigger the scale-to-zero wake-up mechanism. Services attempting to reach a standby instance via its Private FQDN will fail to wake it. To ensure wake-on-request behavior for creating service-to-service communication, use the instance's **Public FQDN**. -Note that this also applies to the legacy CLI tunnel command, which relies on internal connectivity. +Note that this also applies to the legacy [CLI tunnel](/docs/cli/kraft/tunnel) command, which relies on internal connectivity. ## Getting started @@ -216,8 +216,8 @@ Since Unikraft Cloud has scale-to-zero on by default, all you need to do is to s ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ -unikraft build . --output my-org/nginx:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/nginx:latest +unikraft build . --output /nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB /nginx:latest ``` ```bash title="kraft" diff --git a/pages/introduction.mdx b/pages/introduction.mdx index a2826df6..d1c70fdf 100644 --- a/pages/introduction.mdx +++ b/pages/introduction.mdx @@ -4,7 +4,7 @@ navigation_icon: book-check --- -Unikraft is a from-first-principles virtualization solution and cloud platform based on **MicroVMs** which provides best-in-class performance, security, and scalability. +Unikraft Cloud is a from-first-principles virtualization solution and cloud platform based on **MicroVMs** which provides best-in-class performance, security, and scalability. Running your app on Unikraft Cloud is like running a container but with hardware isolation, millisecond cold starts, and stateful scale-to-zero. diff --git a/pages/platform/certificates.mdx b/pages/platform/certificates.mdx index f77ec630..df19793b 100644 --- a/pages/platform/certificates.mdx +++ b/pages/platform/certificates.mdx @@ -98,6 +98,6 @@ kraft cloud cert rm mydomain.com-sa4x9 ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview) -* Unikraft Cloud's [REST API reference](/api/platform/v1) -* Many more guides [here](/guides/bun) +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* Unikraft Cloud's [REST API reference](/api/platform/v1). +* Many more guides [here](/guides/bun). diff --git a/pages/platform/delete-locks.mdx b/pages/platform/delete-locks.mdx index 7dd6abe5..77feacbb 100644 --- a/pages/platform/delete-locks.mdx +++ b/pages/platform/delete-locks.mdx @@ -15,13 +15,14 @@ When you set a delete lock on a resource, any attempt to delete it returns an er Delete locks apply to: - Instances -- [Instance templates](TODO: link to instance templates doc) +- Instance templates - Volumes -- [Volume templates](TODO: link to volume templates doc) +- Volume templates ## Enabling a delete lock -You can set a delete lock on a resource via a `PATCH` operation: +You can set a delete lock on a resource via a `PATCH` operation. +Set `UKC_TOKEN` and `UKC_METRO` for the API calls: @@ -35,7 +36,7 @@ You can set a delete lock on a resource via a `PATCH` operation: curl -X PATCH \ -H "Authorization: Bearer $UKC_TOKEN" \ -H "Content-Type: application/json" \ - "https://api.$UKC_METRO.unikraft.cloud/instances" \ + "https://api.$UKC_METRO.unikraft.cloud/v1/instances" \ -d "[{ 'name': '', 'prop': 'delete_lock', @@ -49,7 +50,7 @@ curl -X PATCH \ curl -X PATCH \ -H "Authorization: Bearer $UKC_TOKEN" \ -H "Content-Type: application/json" \ - "https://api.$UKC_METRO.unikraft.cloud/instance/templates" \ + "https://api.$UKC_METRO.unikraft.cloud/v1/instance/templates" \ -d "[{ 'name': '', 'prop': 'delete_lock', @@ -63,7 +64,7 @@ curl -X PATCH \ curl -X PATCH \ -H "Authorization: Bearer $UKC_TOKEN" \ -H "Content-Type: application/json" \ - "https://api.$UKC_METRO.unikraft.cloud/volumes" \ + "https://api.$UKC_METRO.unikraft.cloud/v1/volumes" \ -d "[{ 'name': '', 'prop': 'delete_lock', @@ -77,7 +78,7 @@ curl -X PATCH \ curl -X PATCH \ -H "Authorization: Bearer $UKC_TOKEN" \ -H "Content-Type: application/json" \ - "https://api.$UKC_METRO.unikraft.cloud/volume/templates" \ + "https://api.$UKC_METRO.unikraft.cloud/v1/volume/templates" \ -d "[{ 'name': '', 'prop': 'delete_lock', @@ -104,7 +105,7 @@ Before you can delete a resource, you need to remove the delete lock by setting curl -X PATCH \ -H "Authorization: Bearer $UKC_TOKEN" \ -H "Content-Type: application/json" \ - "https://api.$UKC_METRO.unikraft.cloud/instances" \ + "https://api.$UKC_METRO.unikraft.cloud/v1/instances" \ -d "[{ 'name': '', 'prop': 'delete_lock', @@ -118,7 +119,7 @@ curl -X PATCH \ curl -X PATCH \ -H "Authorization: Bearer $UKC_TOKEN" \ -H "Content-Type: application/json" \ - "https://api.$UKC_METRO.unikraft.cloud/instance/templates" \ + "https://api.$UKC_METRO.unikraft.cloud/v1/instance/templates" \ -d "[{ 'name': '', 'prop': 'delete_lock', @@ -132,7 +133,7 @@ curl -X PATCH \ curl -X PATCH \ -H "Authorization: Bearer $UKC_TOKEN" \ -H "Content-Type: application/json" \ - "https://api.$UKC_METRO.unikraft.cloud/volumes" \ + "https://api.$UKC_METRO.unikraft.cloud/v1/volumes" \ -d "[{ 'name': '', 'prop': 'delete_lock', @@ -146,7 +147,7 @@ curl -X PATCH \ curl -X PATCH \ -H "Authorization: Bearer $UKC_TOKEN" \ -H "Content-Type: application/json" \ - "https://api.$UKC_METRO.unikraft.cloud/volume/templates" \ + "https://api.$UKC_METRO.unikraft.cloud/v1/volume/templates" \ -d "[{ 'name': '', 'prop': 'delete_lock', @@ -165,5 +166,5 @@ curl -X PATCH \ ## Learn more -* The `kraft cloud` [command-line tool reference](/cli/), and in particular the [deploy](/cli/deploy) subcommand. +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the sections on [instances](/api/platform/v1/instances) and [volumes](/api/platform/v1/volumes). diff --git a/pages/platform/domains.mdx b/pages/platform/domains.mdx index 20f05ea8..5cc843a8 100644 --- a/pages/platform/domains.mdx +++ b/pages/platform/domains.mdx @@ -8,7 +8,7 @@ This guide shows how to deploy an app and link it to a domain you own (for examp :::note Unikraft Cloud can take a few seconds before issuing the certificate. If there are misconfigurations or DNS changes that your external DNS provider hasn't propagated yet, this can take much longer. -You can check the validation status of the certificate with the CLI (more on this command below). +You can check the validation status of the certificate with the CLI (more on this below). The controller retries at these intervals: [1,5,10,30] minutes, then [1,6,12,24] hours, then it fails. ::: @@ -88,8 +88,8 @@ Unikraft Cloud does this through the domain flag: ```bash title="unikraft" -unikraft build . --output my-org/nginx:latest -unikraft run --metro=fra -p 443:8080/http+tls --domain mydomain.com my-org/nginx:latest +unikraft build . --output /nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls --domain mydomain.com /nginx:latest ``` ```bash title="kraft" @@ -135,5 +135,5 @@ curl https://mydomain.com ## Learn more -* The `kraft cloud` [CLI reference](/cli/), in particular the [deploy](/cli/deploy) and [instance](/cli/instance) subcommands -* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the sections on [instances](/api/platform/v1/instances) and [service groups](/api/platform/v1/service-groups) +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the sections on [instances](/api/platform/v1/instances) and [service groups](/api/platform/v1/service-groups). diff --git a/pages/platform/images.mdx b/pages/platform/images.mdx index c872cc12..0eb51c77 100644 --- a/pages/platform/images.mdx +++ b/pages/platform/images.mdx @@ -82,8 +82,8 @@ Start with the simplest workflow: create an image from a Python app (following t ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples cd examples/http-python3.12 -unikraft build . --output my-org/http-python312:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-python312:latest +unikraft build . --output /http-python312:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB /http-python312:latest ``` ```bash title="kraft" @@ -103,7 +103,7 @@ The output should look like: β”œ────────── uuid: e7389eee-9808-4152-b2ec-1f3c0541fd05 β”œ───────── state: running β”œ─────────── url: https://young-night-5fpf0jj8.fra.unikraft.app - β”œ───────── image: [username]]/http-python312@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472 + β”œ───────── image: /http-python312@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472 β”œ───── boot time: 15.09 ms β”œ──────── memory: 512 MiB β”œ─────── service: young-night-5fpf0jj8 @@ -134,7 +134,7 @@ You should see output like: ```text title="" IMAGE TAG SIZE -[username]]/http-python312 latest 77 MB +/http-python312 latest 77 MB ``` And you can remove an image from the registry via the legacy CLI: @@ -161,8 +161,8 @@ For the next workflow, start many instances: ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples cd examples/http-python3.12 -unikraft build . --output my-org/http-python312:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB --replicas 2 my-org/http-python312:latest +unikraft build . --output /http-python312:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB --replicas 2 /http-python312:latest ``` ```bash title="kraft" @@ -219,7 +219,7 @@ In this final workflow, take the existing image and start new instances from it: ```bash title="unikraft" -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB [username]/http-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB /http-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca ``` ```bash title="kraft" @@ -227,7 +227,7 @@ kraft cloud instance create \ --start \ --port 443:8080 \ -M 512 \ - [username]/http-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca + /http-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca ``` @@ -301,5 +301,5 @@ The response includes `url`, `tags`, `initrd_or_rom`, `size_in_bytes`, args` and ## Learn more -* The legacy [CLI reference](/docs/cli/kraft/overview) -* Unikraft Cloud's [REST API reference](/api/platform/v1) +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* Unikraft Cloud's [REST API reference](/api/platform/v1). diff --git a/pages/platform/instances.mdx b/pages/platform/instances.mdx index 437bc9c7..a5cac20f 100644 --- a/pages/platform/instances.mdx +++ b/pages/platform/instances.mdx @@ -289,5 +289,5 @@ The logs capture the instance's `stdout` and `stderr` output, and they're preser ## Learn more -* The `kraft cloud` [CLI reference](/cli/), in particular the [deploy](/cli/deploy) and [instance](/cli/instance) subcommands -* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [instances](/api/platform/v1/instances) +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [instances](/api/platform/v1/instances). diff --git a/pages/platform/metrics.mdx b/pages/platform/metrics.mdx index 8bfbf53a..3094acac 100644 --- a/pages/platform/metrics.mdx +++ b/pages/platform/metrics.mdx @@ -123,9 +123,13 @@ The platform labels all metrics with `uuid` and `name`. ## Example +Set `UKC_TOKEN` and `UKC_METRO` for the API call: + ```bash title="" -curl -H "Accept: application/json" \ - "https://api.unikraft.io/v1/instances/metrics?uuid=66d05e09-1436-4d1f-bbe6-6dc03ae48d7a" +curl -X GET \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + "https://api.$UKC_METRO.unikraft.cloud/v1/instances/metrics?uuid=66d05e09-1436-4d1f-bbe6-6dc03ae48d7a" ``` ```json title="" diff --git a/pages/platform/quotas.mdx b/pages/platform/quotas.mdx index 2a98b132..68e27fc7 100644 --- a/pages/platform/quotas.mdx +++ b/pages/platform/quotas.mdx @@ -64,9 +64,13 @@ These define the minimum and maximum values you can specify when creating indivi ## Example +Set `UKC_TOKEN` and `UKC_METRO` for the API call: + ```bash title="" -curl -H "Authorization: Bearer $UKC_TOKEN" \ - "https://api.unikraft.io/v1/users/quotas" +curl -X GET \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + "https://api.$UKC_METRO.unikraft.cloud/v1/users/quotas" ``` ```json title="" diff --git a/pages/platform/services.mdx b/pages/platform/services.mdx index 49814c46..2fb8b32f 100644 --- a/pages/platform/services.mdx +++ b/pages/platform/services.mdx @@ -55,8 +55,8 @@ For example, from the [Go web server guide](/guides/go): ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples cd examples/http-go1.21/ -unikraft build . --output my-org/http-go121:latest -unikraft run --metro=fra --service my-service -m 256MiB my-org/http-go121:latest +unikraft build . --output /http-go121:latest +unikraft run --metro=fra --service my-service -m 256MiB /http-go121:latest ``` ```bash title="kraft" @@ -217,7 +217,7 @@ You must also list the `UDP` IPs in the `additional_ip_addresses` directive in ` To create a `UDP` service, set both `protocol` and `ip`: -```json title="POST /v1/services" +```json title="POST /services" { "services": [ { @@ -244,9 +244,9 @@ Every service group has a soft and a hard connection limit that the load balance `soft_limit` must be less than or equal to `hard_limit`. Setting `soft_limit > hard_limit` returns a `400` error. -You can set both fields at service group creation time and update them later with `PATCH /v1/services/{name}`. +You can set both fields at service group creation time and update them later with `PATCH /services/{name}`. -```json title="POST /v1/services" +```json title="POST /services" { "name": "my-service", "soft_limit": 100, @@ -258,14 +258,14 @@ You can set both fields at service group creation time and update them later wit A service group is **persistent** when your user account owns it rather than a specific instance. -- A service group created with the CLI (or `POST /v1/services`) is persistent. +- A service group created with the CLI (or `POST /services`) is persistent. It survives independently of any instances attached to it. - A service group created implicitly via the publish flag on instance creation belongs to the instance. The platform deletes it when you delete that instance. -The `GET /v1/services/{name}` response includes a `persistent` field (`bool`) that indicates which case applies. +The `GET /services/{name}` response includes a `persistent` field (`bool`) that indicates which case applies. ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview) -* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [service groups](/api/platform/v1/service-groups) +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [service groups](/api/platform/v1/service-groups). diff --git a/pages/platform/tagging.mdx b/pages/platform/tagging.mdx index c1c21baf..1c6fb9f8 100644 --- a/pages/platform/tagging.mdx +++ b/pages/platform/tagging.mdx @@ -38,7 +38,7 @@ Add tags to an existing resource (`"op": "set"` will replace all existing tags): ``` :::note -Use `/v1/volumes` for volumes, `/v1/instances/templates` for instance templates, and `/v1/volumes/templates` for volume templates. +Use `/volumes` for volumes, `/instances/templates` for instance templates, and `/volumes/templates` for volume templates. ::: Add tags to a resource without replacing existing ones (`"op": "add"`): diff --git a/pages/platform/troubleshooting.mdx b/pages/platform/troubleshooting.mdx index 620bb2cb..2ac871c0 100644 --- a/pages/platform/troubleshooting.mdx +++ b/pages/platform/troubleshooting.mdx @@ -341,8 +341,8 @@ Now Unikraft Cloud is ready to re-deploy: ```bash title="unikraft" -unikraft build . --output my-org/http-go-strace:latest -unikraft run --metro=fra --name http-go-strace -p 443:8080/http+tls my-org/http-go-strace:latest +unikraft build . --output /http-go-strace:latest +unikraft run --metro=fra --name http-go-strace -p 443:8080/http+tls /http-go-strace:latest ``` ```bash title="kraft" @@ -420,6 +420,6 @@ Find more info in the [CLI reference](/docs/cli/unikraft) and the legacy [CLI re ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview) -* Unikraft Cloud's [REST API reference](/api/platform/v1) -* Many more guides [here](/guides/bun) +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* Unikraft Cloud's [REST API reference](/api/platform/v1). +* Many more guides [here](/guides/bun). diff --git a/pages/platform/volumes.mdx b/pages/platform/volumes.mdx index 8ab0ee00..d41f73b6 100644 --- a/pages/platform/volumes.mdx +++ b/pages/platform/volumes.mdx @@ -82,11 +82,11 @@ You should see output like: [+] Spawning temporary volume data import instance... done! [0.1s] [+] Importing data (256 B) β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’β€’ 100% [0.1s] -[●] Import complete - β”‚ - β”œβ”€β”€β”€ volume: my-volume - β”œβ”€ imported: 256 B - └─ capacity: 100 MiB +[●] Import complete + β”‚ + β”œ─── volume: my-volume + β”œ─ imported: 256 B + β””─ capacity: 100 MiB ``` ## Setting up the web server @@ -143,8 +143,8 @@ Start the Flask web server, create a ```bash title="unikraft" -unikraft build . --output my-org/http-python312-flask30:latest -unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt my-org/http-python312-flask30:latest +unikraft build . --output /http-python312-flask30:latest +unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt /http-python312-flask30:latest ``` ```bash title="kraft" @@ -192,7 +192,7 @@ NAME CREATED AT SIZE ATTACHED TO STATE PERSI my-volume 34 minutes ago 100 MiB http-python312-flask30-2h608 mounted true ``` -## Testing it +## Testing the server The Flask server writes the time and date to `/mnt/log.txt` for each request. Test it by running `curl` several times. @@ -239,8 +239,8 @@ Now start another instance and, like before, mount the same volume: ```bash title="unikraft" -unikraft build . --output my-org/http-python312-flask30:latest -unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt my-org/http-python312-flask30:latest +unikraft build . --output /http-python312-flask30:latest +unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt /http-python312-flask30:latest ``` ```bash title="kraft" @@ -383,5 +383,5 @@ Create a managed volume with a `host_path` field instead of `size_mb`: ## Learn more -* The `kraft cloud` [CLI reference](/cli/), in particular the [deploy](/cli/deploy) and [volume](/cli/volume) subcommands -* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [volumes](/api/platform/v1/volumes) +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [volumes](/api/platform/v1/volumes). diff --git a/pages/tutorials/docker-to-ukc.mdx b/pages/tutorials/docker-to-ukc.mdx index 6ab744ae..2947103b 100644 --- a/pages/tutorials/docker-to-ukc.mdx +++ b/pages/tutorials/docker-to-ukc.mdx @@ -103,8 +103,8 @@ This confirms that the runtime, filesystem, and command line are valid. ```bash title="unikraft" -unikraft build . --output my-org/docker-port:latest -unikraft run --metro=fra -p 443: -m 512MiB my-org/docker-port:latest +unikraft build . --output /docker-port:latest +unikraft run --metro=fra -p 443: -m 512MiB /docker-port:latest ``` ```bash title="kraft" @@ -246,8 +246,8 @@ This often gives better cold-boot behaviour and lower memory pressure than `CPIO ```bash title="unikraft" -unikraft build . --output my-org/docker-port:latest -unikraft run --metro=fra -p 443: -m 256MiB my-org/docker-port:latest +unikraft build . --output /docker-port:latest +unikraft run --metro=fra -p 443: -m 256MiB /docker-port:latest ``` ```bash title="kraft" @@ -283,11 +283,11 @@ The most reliable method at deployment time is to pass them through the CLI with ```bash title="unikraft" -unikraft build . --output my-org/docker-port:latest +unikraft build . --output /docker-port:latest unikraft run --metro=fra -p 443: -m 256MiB \ -e APP_ENV=production \ -e LOG_LEVEL=info \ - my-org/docker-port:latest + /docker-port:latest ``` ```bash title="kraft" @@ -342,11 +342,11 @@ The simplest way to test scale-to-zero is to deploy with an explicit scale-to-ze ```bash title="unikraft" -unikraft build . --output my-org/docker-port:latest +unikraft build . --output /docker-port:latest unikraft run --metro=fra -p 443: -m 256MiB \ --scale-to-zero \ --scale-to-zero-cooldown-time-ms=5000 \ - my-org/docker-port:latest + /docker-port:latest ``` ```bash title="kraft" diff --git a/pages/tutorials/instance-metrics.mdx b/pages/tutorials/instance-metrics.mdx index fe86778e..1c754b8f 100644 --- a/pages/tutorials/instance-metrics.mdx +++ b/pages/tutorials/instance-metrics.mdx @@ -14,7 +14,7 @@ To access the instance metrics, you must have the **`developer`** permission rol ## Retrieving metrics -You can retrieve the metrics of one or more instances by making a `GET` request to the `/v1/instances/metrics` endpoint. +You can retrieve the metrics of one or more instances by making a `GET` request to the `/instances/metrics` endpoint. The request body must contain an array of instance UUIDs or names. Use a tool like `curl` for ad-hoc queries, or configure your monitoring system to consume the endpoint's Prometheus-formatted output. @@ -59,7 +59,7 @@ This command will create the NGINX instance with scale-to-zero enabled: ``` Now, request the metrics for that instance. -Set `UKC_TOKEN` and `UKC_METRO` for the API call (the `unikraft` CLI uses profiles instead). +Set `UKC_TOKEN` and `UKC_METRO` for the API calls: diff --git a/pages/tutorials/rootfs-formats.mdx b/pages/tutorials/rootfs-formats.mdx index 7df3c536..9bbf4584 100644 --- a/pages/tutorials/rootfs-formats.mdx +++ b/pages/tutorials/rootfs-formats.mdx @@ -39,7 +39,7 @@ Finally, `DAX` enables sharing the same rootfs image between many instances, inc ## Packaging the Rootfs -The [unikraft CLI tool](/docs/cli/unikraft) supports both formats out of the box. +The legacy `kraft` CLI supports both formats out of the box. With it, you can package a rootfs from these sources: - a simple file - a directory diff --git a/pages/tutorials/rootfs-volumes-roms.mdx b/pages/tutorials/rootfs-volumes-roms.mdx index e4d5fece..2e140e6c 100644 --- a/pages/tutorials/rootfs-volumes-roms.mdx +++ b/pages/tutorials/rootfs-volumes-roms.mdx @@ -125,7 +125,7 @@ To package them you can either use `kraft`, or package it yourself and pass it t kraft pkg \ --plat kraftcloud \ --arch x86_64 \ - --name index.unikraft.io/function-hello:latest \ + --name function-hello:latest \ --rootfs-type erofs \ --push \ . @@ -199,5 +199,5 @@ ROMs are a flexible way to customize rootfses, but you should also keep them sma * [Volumes](/platform/volumes) and how to use them. * [Rootfs formats](/tutorials/rootfs-formats) and how to create them. -* The legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). * The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. diff --git a/pages/tutorials/scale-to-zero-triggers.mdx b/pages/tutorials/scale-to-zero-triggers.mdx index 3145cc46..d0a67e78 100644 --- a/pages/tutorials/scale-to-zero-triggers.mdx +++ b/pages/tutorials/scale-to-zero-triggers.mdx @@ -101,8 +101,7 @@ You can use the Unikraft Cloud API to manually scale down an instance. You will have to use the `/instances/suspend` endpoint to scale down an instance. This happens instantly, regardless of the configured automatic triggers. -First, set the required environment variables. -These are for the API call and the legacy CLI, not the `unikraft` profile system: +First, set the required environment variables: ```bash # Set Unikraft Cloud access token diff --git a/pages/use-cases/api-gateways.mdx b/pages/use-cases/api-gateways.mdx index 13ea88ba..1bd54109 100644 --- a/pages/use-cases/api-gateways.mdx +++ b/pages/use-cases/api-gateways.mdx @@ -73,10 +73,6 @@ This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): -```bash title="unikraft" -unikraft login -``` - ```bash title="kraft" # Set Unikraft Cloud access token export UKC_TOKEN=token @@ -86,10 +82,7 @@ export UKC_METRO=fra -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -Then invoke. -Compose is only available in the legacy CLI: +Then invoke: @@ -126,10 +119,6 @@ Use the `--help` option for detailed information on using Unikraft Cloud: -```bash title="unikraft" -unikraft --help -``` - ```bash title="kraft" kraft cloud --help ``` diff --git a/pages/use-cases/headless-browsers.mdx b/pages/use-cases/headless-browsers.mdx index 2c5a24ef..bc9f5cd3 100644 --- a/pages/use-cases/headless-browsers.mdx +++ b/pages/use-cases/headless-browsers.mdx @@ -92,8 +92,8 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output my-org/node-express-puppeteer:latest -unikraft run --metro=fra -p 443:3000/http+tls -m 4Gi my-org/node-express-puppeteer:latest +unikraft build . --output /node-express-puppeteer:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 4Gi /node-express-puppeteer:latest ``` ```bash title="kraft" diff --git a/pages/use-cases/mcp-servers.mdx b/pages/use-cases/mcp-servers.mdx index ac96568f..7551b6ca 100644 --- a/pages/use-cases/mcp-servers.mdx +++ b/pages/use-cases/mcp-servers.mdx @@ -196,10 +196,6 @@ Use the `--help` option for detailed information on using Unikraft Cloud: -```bash title="unikraft" -unikraft --help -``` - ```bash title="kraft" kraft cloud --help ``` @@ -210,7 +206,7 @@ Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/ For more information about the Model Context Protocol: -- [MCP Documentation](https://modelcontextprotocol.io/) -- [Reference MCP Servers](https://github.com/modelcontextprotocol/servers) -- [Building MCP Servers](https://modelcontextprotocol.io/docs/develop/build-server) -- [Building MCP Clients](https://modelcontextprotocol.io/docs/develop/build-client) +* [MCP Documentation](https://modelcontextprotocol.io/). +* [Reference MCP Servers](https://github.com/modelcontextprotocol/servers). +* [Building MCP Servers](https://modelcontextprotocol.io/docs/develop/build-server). +* [Building MCP Clients](https://modelcontextprotocol.io/docs/develop/build-client). diff --git a/pages/use-cases/remote-ides.mdx b/pages/use-cases/remote-ides.mdx index c6bbc5f3..d73592d6 100644 --- a/pages/use-cases/remote-ides.mdx +++ b/pages/use-cases/remote-ides.mdx @@ -59,7 +59,6 @@ cd examples/code-server/ Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ). -The deployment commands below use the legacy CLI: diff --git a/pages/use-cases/serverless-databases.mdx b/pages/use-cases/serverless-databases.mdx index 348a4cc8..90304070 100644 --- a/pages/use-cases/serverless-databases.mdx +++ b/pages/use-cases/serverless-databases.mdx @@ -60,8 +60,8 @@ This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): ```bash title="unikraft" unikraft login -unikraft build . --output my-org/postgres:latest -unikraft run --metro=fra -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -m 1Gi my-org/postgres:latest +unikraft build . --output /postgres:latest +unikraft run --metro=fra -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -m 1Gi /postgres:latest ``` ```bash title="kraft" @@ -129,7 +129,7 @@ You can see this in action by running `SELECT pg_sleep(10);` and verifying that ::: :::note -If you'd like to use a port other than `5432/tls`, you'll need to use the legacy CLI tunnel command to connect to Postgres. +If you'd like to use a port other than `5432/tls`, you'll need to use the legacy [CLI tunnel](/docs/cli/kraft/tunnel) command to connect to Postgres. You need to explicitly disable scale-to-zero. You can do this by either changing the label in the `Kraftfile` or by using `--scale-to-zero off` in the deploy command. @@ -194,8 +194,8 @@ Then start the PostgreSQL instance and mount that volume: ```console title="unikraft" -unikraft build . --output my-org/postgres:latest -unikraft run --metro=fra -p 5432:5432/tls -m 1Gi -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume my-org/postgres:latest +unikraft build . --output /postgres:latest +unikraft run --metro=fra -p 5432:5432/tls -m 1Gi -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume /postgres:latest ``` ```console title="kraft" diff --git a/pages/use-cases/webhooks.mdx b/pages/use-cases/webhooks.mdx index 30de8dcb..10cb7d6c 100644 --- a/pages/use-cases/webhooks.mdx +++ b/pages/use-cases/webhooks.mdx @@ -95,10 +95,6 @@ Use the `--help` option for detailed information on using Unikraft Cloud: -```bash title="unikraft" -unikraft --help -``` - ```bash title="kraft" kraft cloud --help ``` @@ -109,7 +105,7 @@ Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/ For more information, check out these resources: -- [Express Documentation](https://expressjs.com/) -- [GitHub Webhooks Documentation](https://docs.github.com/en/webhooks) -- [Securing GitHub Webhooks](https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries) -- [Webhook Best Practices](https://webhooks.fyi/) +* [Express Documentation](https://expressjs.com/). +* [GitHub Webhooks Documentation](https://docs.github.com/en/webhooks). +* [Securing GitHub Webhooks](https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries). +* [Webhook Best Practices](https://webhooks.fyi/). From 319fcb5dc77c67d202da889d6f9dfbba00d0d7d2 Mon Sep 17 00:00:00 2001 From: Dragos Gheorghioiu Date: Thu, 2 Apr 2026 10:43:32 +0300 Subject: [PATCH 082/131] feat(transform-script): added CLI CodeTabs to the generator script Signed-off-by: Dragos Gheorghioiu --- scripts/transform_readme.py | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/scripts/transform_readme.py b/scripts/transform_readme.py index b7fb1cab..1fcf8b75 100755 --- a/scripts/transform_readme.py +++ b/scripts/transform_readme.py @@ -10,6 +10,7 @@ into: :::note\n line1\n line2\n ::: - Rewrite absolute docs URLs back to site-relative paths +- Group adjacent titled code blocks into wrappers with syncKey - Append a Source block when EXAMPLE_NAME is provided Usage: transform_readme.py INPUT_FILE OUTPUT_FILE [EXAMPLE_NAME] @@ -119,6 +120,45 @@ def rewrite_urls(text: str) -> str: return text +def convert_code_tabs(text: str) -> str: + """Group adjacent code blocks containing title="..." inside a wrapper.""" + block_pattern = re.compile(r"(```([^\n]*?title=\"([^\"]+)\"[^\n]*)\n.*?\n```)", flags=re.S) + + matches = list(block_pattern.finditer(text)) + if not matches: + return text + + groups = [] + current_group = [matches[0]] + + for i in range(1, len(matches)): + prev = current_group[-1] + curr = matches[i] + + # Check if only whitespace or the word "or" exists between blocks + between = text[prev.end():curr.start()].strip().lower() + if between in ["", "or"]: + current_group.append(curr) + else: + groups.append(current_group) + current_group = [curr] + groups.append(current_group) + + out = text + for group in reversed(groups): + if len(group) > 1: + blocks = [m.group(1) for m in group] + + # Reconstruct the matched area with and syncKey + tabs_str = '\n\n' + "\n\n".join(blocks) + "\n\n" + + start = group[0].start() + end = group[-1].end() + out = out[:start] + tabs_str + out[end:] + + return out + + def color_bracket_and_bullet(line: str) -> str: """Color the [●] Deployed successfully! line.""" line = line.replace('[', f'{ANSI_DARK_GRAY}[{ANSI_RESET}') @@ -333,6 +373,7 @@ def main(argv: list[str] | None = None) -> int: content = insert_tabs_import(content, title) content = convert_admonitions(content) content = rewrite_urls(content) + content = convert_code_tabs(content) content = color_deployed_block(content) content = color_state_in_table_blocks(content) From d65c2197d8619df81478b86f71a4efdd7ab71bed Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Thu, 2 Apr 2026 10:27:54 +0100 Subject: [PATCH 083/131] fix: Pin kraftkit to v0.12.6 Signed-off-by: Justin Chadwell --- .github/actions/setup-kraftkit/action.yaml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/actions/setup-kraftkit/action.yaml b/.github/actions/setup-kraftkit/action.yaml index 4f483832..e23a1313 100644 --- a/.github/actions/setup-kraftkit/action.yaml +++ b/.github/actions/setup-kraftkit/action.yaml @@ -2,6 +2,12 @@ name: setup-kraftkit description: Setup KraftKit. +inputs: + version: + description: KraftKit version to install (use latest to auto-detect). + required: false + default: 0.12.6 + runs: using: composite steps: @@ -9,7 +15,10 @@ runs: shell: bash run: | if [[ -z $(command -v kraft) ]]; then - _VERSION=$(curl https://get.kraftkit.sh/latest.txt); + _VERSION="${{ inputs.version }}" + if [[ -z "${_VERSION}" || "${_VERSION}" == "latest" ]]; then + _VERSION=$(curl -fsSL https://get.kraftkit.sh/latest.txt) + fi wget -nv -LO kraft.tar.gz https://github.com/unikraft/kraftkit/releases/download/v${_VERSION}/kraft_${_VERSION}_linux_amd64.tar.gz; tar xzf kraft.tar.gz kraft; sudo mv kraft /usr/bin/; From f295d6d7044fdd013ca098b3c252e98c2f39e470 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Thu, 2 Apr 2026 15:18:23 +0300 Subject: [PATCH 084/131] feat(features): Add exec action to cron jobs Signed-off-by: Alex-Andrei Cioc --- pages/features/cron-jobs.mdx | 56 ++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/pages/features/cron-jobs.mdx b/pages/features/cron-jobs.mdx index bbfd7a28..0bf2f428 100644 --- a/pages/features/cron-jobs.mdx +++ b/pages/features/cron-jobs.mdx @@ -3,8 +3,8 @@ title: Cron Jobs / Scheduled Wake-ups navigation_icon: clock --- -Scheduled operations let you automatically start, stop, or delete instances on a calendar-based schedule. -Each scheduled operation specifies a name, a calendar expression, and an action (`start`, `stop`, or `delete`). +Scheduled operations let you automatically start, stop, delete, or exec a command in instances on a calendar-based schedule. +Each scheduled operation specifies a name, a calendar expression, and an action (`start`, `stop`, `delete`, or `exec`). Each instance stores its own schedules, and cloning preserves them. @@ -50,6 +50,22 @@ For example, to start an instance every day at 09:00 UTC and stop it at 18:00 UT } ``` +To run a command inside the instance every night at midnight, use the `exec` action with an `args` array: + +```json title="POST /instances" +{ + "image": "...", + "schedules": [ + { + "name": "nightly-cleanup", + "when": "*-*-* 00:00:00", + "action": "exec", + "args": ["/bin/sh", "-c", "rm -rf /tmp/*"] + } + ] +} +``` + ## Updating schedules of an existing instance Add, set, or remove scheduled operations via `PATCH`: @@ -68,6 +84,23 @@ Add, set, or remove scheduled operations via `PATCH`: } ``` +Add an `exec` schedule the same way, but include `args` with the command to run: + +```json title="PATCH /instances/{uuid}" +{ + "prop": "schedules", + "op": "add", + "value": [ + { + "name": "hourly-healthcheck", + "when": "*-*-* *:00:00", + "action": "exec", + "args": ["/usr/bin/healthcheck"] + } + ] +} +``` + ```json title="PATCH /instances/{uuid}" { "prop": "schedules", @@ -85,6 +118,23 @@ Add, set, or remove scheduled operations via `PATCH`: | `start` | Start the instance at the scheduled time | | `stop` | Stop the instance at the scheduled time | | `delete` | Delete the instance at the scheduled time | +| `exec` | Execute a command inside the instance at the scheduled time. Requires the `args` field. | + +### The `args` field + +The `args` field is an array of strings specifying the command to run when using the `exec` action. +The first element is the executable and the remaining elements are its arguments. + +```json +{ + "name": "daily-report", + "when": "*-*-* 06:00:00", + "action": "exec", + "args": ["/usr/bin/python3", "/app/report.py", "--daily"] +} +``` + +No need to specify it for all other actions. ## Notes @@ -94,4 +144,4 @@ Add, set, or remove scheduled operations via `PATCH`: ## Learn more -* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [instances](/api/platform/v1/instances) +* Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [instances](/api/platform/v1/instances). From 0063c891299b1421c607305c7e326fe6ee508a52 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Thu, 2 Apr 2026 15:51:27 +0300 Subject: [PATCH 085/131] feat(features): Add ROM automounting Signed-off-by: Alex-Andrei Cioc --- pages/features/roms.mdx | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index 98953604..7f1f7c71 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -29,8 +29,11 @@ The ROM workflow consists of two main components: This separation allows you to maintain one base image while deploying many different instances with different data. :::note -The app running inside the base image is responsible to read the data from the attached ROM devices. +By default, the app running inside the base image needs to mount the attached ROM device. ROM blobs appear as block devices at paths like `/dev/ukp_rom_`, where `` is the ROM name you specify when creating the instance. + +For convenience, you can use **automounting** by setting the `at` field on a ROM entry. +When `at` is present, the platform automatically mounts the ROM at the given path before the instance starts, so your app can read files from it directly without any manual mount step. ::: ## Setup @@ -84,7 +87,7 @@ COPY --from=build /etc/ld.so.cache /etc/ld.so.cache # Python (and other) libraries COPY --from=build /usr/local/lib /usr/local/lib -# Python application +# Python app COPY ./wrapper.sh /wrapper.sh COPY ./server.py /src/server.py ``` @@ -158,6 +161,10 @@ exec "$@" ``` +:::tip +If you use the `at` field when attaching the ROM (see [Automounting](#automounting)), the platform handles the mount for you and you can remove `wrapper.sh` and the `mount`/`mkdir` calls entirely. +::: + Ensure that the `wrapper.sh` script is executable: ```bash title="" @@ -366,6 +373,31 @@ Check that the instances are up: Note the `roms` array in the instances configurations. Each ROM is available as a readable device at `/dev/ukp_rom_python_function.py` (in the form of an EROFS filesystem in this case), which the server program mounts at `/tmp/rom.py` and executes. +## Automounting + +Instead of mounting the ROM device manually inside the guest, you can set the optional `at` field on any ROM entry. +The platform will then mount the ROM at the specified path before the instance starts. + +```json title="POST /instances" +{ + "image": "...", + "roms": [ + { + "name": "python_function.py", + "image": "myuser/my-rom1:latest", + "at": "/tmp" + } + ] +} +``` + +{/* vale off */} +With this configuration the EROFS filesystem is mounted at `/tmp` automatically, so `/tmp/rom.py` is available to the app without any `mount` call in a wrapper script. +In this case you can simplify or remove the `wrapper.sh` from the base image, since the platform handles the mount for you. +{/* vale on */} + +The `at` field is optional--omitting it leaves the ROM as a raw block device at `/dev/ukp_rom_` and the guest remains responsible for mounting it. + ### Testing Query the instances to call the Python function from the ROM. @@ -402,3 +434,4 @@ kraft cloud instance rm test-http-python-rom1 test-http-python-rom2 * The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the [instances API](/api/platform/v1/instances). * The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images and ROMs. +* The [systemd `mount` man page](https://www.man7.org/linux/man-pages/man8/mount.8.html) for filesystem mount options relevant to manual mounting scenarios. From af70fe7b42d40c548af3d44f57ee8efc3577e163 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Thu, 2 Apr 2026 14:34:58 +0100 Subject: [PATCH 086/131] ci: Switch Dockerfile to use for getting platform APIs Signed-off-by: Justin Chadwell --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 170632ed..06707d9a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,8 +43,7 @@ COPY . . # Grab the latest OpenAPI spec based on the desired channel. ARG DOCS_CHANNEL=prod-staging -RUN set -xe; \ - wget -O apis/platform.yaml https://raw.githubusercontent.com/unikraft-cloud/openapi/refs/heads/${DOCS_CHANNEL}/platform.yaml; +ADD https://raw.githubusercontent.com/unikraft-cloud/openapi/refs/heads/${DOCS_CHANNEL}/platform.yaml apis/platform.yaml # Kraft (old CLI) docs -> /cli/kraft/ COPY --from=build-kraft-docs /kraftkit/docs/kraft/cloud /docs/pages/cli/kraft From ce545def5903d821e4e26fe48a6e3626d53e5fd1 Mon Sep 17 00:00:00 2001 From: Unikraft Bot Date: Thu, 2 Apr 2026 14:13:39 +0000 Subject: [PATCH 087/131] chore: Update guides from examples repository Signed-off-by: Unikraft Bot --- .github/workflows/sync.yaml | 4 +- .../config/vocabularies/Unikraft/accept.txt | 1 + pages/guides/bun.mdx | 239 ------------ pages/guides/caddy.mdx | 189 ---------- pages/guides/caddy2.7-go1.21.mdx | 166 ++++++++ pages/guides/cpp-boost.mdx | 329 ---------------- pages/guides/cpp.mdx | 291 -------------- pages/guides/debian-ssh.mdx | 139 +++++++ pages/guides/django.mdx | 355 ------------------ pages/guides/dotnet.mdx | 262 ------------- .../guides/{dragonfly.mdx => dragonflydb.mdx} | 88 ++--- pages/guides/duckdb-go1.21.mdx | 155 ++++++++ pages/guides/duckdb.mdx | 225 ----------- pages/guides/elixir.mdx | 339 ----------------- pages/guides/erlang.mdx | 253 ------------- pages/guides/ferretdb.mdx | 224 ----------- pages/guides/flask-sqlite.mdx | 297 --------------- pages/guides/flask.mdx | 302 --------------- pages/guides/github-webhook-node.mdx | 217 +++++++++++ pages/guides/go.mdx | 211 ----------- pages/guides/grafana.mdx | 87 ++--- pages/guides/haproxy.mdx | 89 ++--- pages/guides/httpserver-boost1.74-g++13.2.mdx | 164 ++++++++ pages/guides/httpserver-bun.mdx | 169 +++++++++ pages/guides/httpserver-c-debug.mdx | 150 ++++++++ pages/guides/httpserver-dotnet10.0.mdx | 175 +++++++++ pages/guides/httpserver-elixir1.16.mdx | 159 ++++++++ pages/guides/httpserver-erlang26.2.mdx | 149 ++++++++ .../httpserver-expressjs4.18-node21.mdx | 175 +++++++++ pages/guides/httpserver-g++13.2.mdx | 166 ++++++++ pages/guides/httpserver-gcc13.2.mdx | 134 +++++++ pages/guides/httpserver-go1.21.mdx | 154 ++++++++ .../httpserver-java17-springboot3.2.x.mdx | 176 +++++++++ pages/guides/httpserver-java21.mdx | 179 +++++++++ pages/guides/httpserver-lua5.1.mdx | 150 ++++++++ .../guides/httpserver-nginx-vite-vanilla.mdx | 188 ++++++++++ .../httpserver-node-express-puppeteer.mdx | 127 +++++++ pages/guides/httpserver-node21-nextjs.mdx | 241 ++++++++++++ pages/guides/httpserver-node21-remix.mdx | 134 +++++++ .../guides/httpserver-node21-solid-start.mdx | 133 +++++++ ...it.mdx => httpserver-node21-sveltekit.mdx} | 118 ++---- pages/guides/httpserver-node25.mdx | 175 +++++++++ pages/guides/httpserver-perl5.42.mdx | 172 +++++++++ pages/guides/httpserver-php8.2.mdx | 152 ++++++++ ...ttpserver-prisma-expressjs4.19-node18.mdx} | 87 ++--- .../httpserver-python3.12-FastAPI-0.121.3.mdx | 226 +++++++++++ .../httpserver-python3.12-django5.0.mdx | 248 ++++++++++++ .../httpserver-python3.12-flask3.0-sqlite.mdx | 207 ++++++++++ .../guides/httpserver-python3.12-flask3.0.mdx | 211 +++++++++++ pages/guides/httpserver-python3.12.mdx | 229 +++++++++++ pages/guides/httpserver-ruby3.2.mdx | 150 ++++++++ pages/guides/httpserver-rust1.75-tokio.mdx | 154 ++++++++ .../guides/httpserver-rust1.81-rocket0.5.mdx | 154 ++++++++ .../guides/httpserver-rust1.87-actix-web4.mdx | 156 ++++++++ pages/guides/httpserver-rust1.91.mdx | 133 +++++++ pages/guides/hugo.mdx | 180 --------- pages/guides/hugo0.122.mdx | 154 ++++++++ pages/guides/imaginary.mdx | 63 ++-- pages/guides/java.mdx | 249 ------------ pages/guides/llama2.mdx | 216 ----------- pages/guides/lua.mdx | 238 ------------ pages/guides/mariadb.mdx | 138 +++---- pages/guides/mcp-server-arxiv.mdx | 192 ++++++++++ pages/guides/mcp-server-simple.mdx | 222 +++++++++++ pages/guides/memcached.mdx | 197 ---------- pages/guides/memcached1.6.mdx | 164 ++++++++ pages/guides/minio.mdx | 95 ++--- pages/guides/mongodb.mdx | 119 +++--- pages/guides/nextjs.mdx | 331 ---------------- pages/guides/nginx.mdx | 137 ++----- pages/guides/node.mdx | 332 ---------------- pages/guides/node24-karaoke.mdx | 187 +++++++++ pages/guides/novnc-browser.mdx | 145 +++++++ pages/guides/opentelemetry-collector.mdx | 116 ++---- pages/guides/overview.mdx | 123 ------ pages/guides/perl.mdx | 195 ---------- pages/guides/php.mdx | 232 ------------ pages/guides/postgres.mdx | 122 +++--- pages/guides/puppeteer.mdx | 140 ------- pages/guides/python.mdx | 333 ---------------- pages/guides/redis.mdx | 208 ---------- pages/guides/remix.mdx | 175 --------- pages/guides/ruby.mdx | 193 ---------- pages/guides/{rails.mdx => ruby3.2-rails.mdx} | 99 ++--- pages/guides/rust-actix.mdx | 232 ------------ pages/guides/rust-rocket.mdx | 285 -------------- pages/guides/rust-tokio.mdx | 230 ------------ pages/guides/skipper.mdx | 136 ------- pages/guides/skipper0.18.mdx | 139 +++++++ pages/guides/solidjs.mdx | 164 -------- pages/guides/spin-wagi-http.mdx | 171 +++++++++ pages/guides/spin.mdx | 264 ------------- pages/guides/springboot.mdx | 228 ----------- pages/guides/traefik.mdx | 70 ++-- pages/guides/tyk.mdx | 218 ----------- pages/guides/visual-studio-code-server.mdx | 168 +++++++++ pages/guides/vsftpd.mdx | 173 +++++++++ .../{wazero.mdx => wazero-import-go.mdx} | 66 ++-- pages/guides/wordpress-all-in-one.mdx | 95 +++++ pages/guides/wordpress.mdx | 140 ------- 100 files changed, 8344 insertions(+), 9687 deletions(-) delete mode 100644 pages/guides/bun.mdx delete mode 100644 pages/guides/caddy.mdx create mode 100644 pages/guides/caddy2.7-go1.21.mdx delete mode 100644 pages/guides/cpp-boost.mdx delete mode 100644 pages/guides/cpp.mdx create mode 100644 pages/guides/debian-ssh.mdx delete mode 100644 pages/guides/django.mdx delete mode 100644 pages/guides/dotnet.mdx rename pages/guides/{dragonfly.mdx => dragonflydb.mdx} (51%) create mode 100644 pages/guides/duckdb-go1.21.mdx delete mode 100644 pages/guides/duckdb.mdx delete mode 100644 pages/guides/elixir.mdx delete mode 100644 pages/guides/erlang.mdx delete mode 100644 pages/guides/ferretdb.mdx delete mode 100644 pages/guides/flask-sqlite.mdx delete mode 100644 pages/guides/flask.mdx create mode 100644 pages/guides/github-webhook-node.mdx delete mode 100644 pages/guides/go.mdx create mode 100644 pages/guides/httpserver-boost1.74-g++13.2.mdx create mode 100644 pages/guides/httpserver-bun.mdx create mode 100644 pages/guides/httpserver-c-debug.mdx create mode 100644 pages/guides/httpserver-dotnet10.0.mdx create mode 100644 pages/guides/httpserver-elixir1.16.mdx create mode 100644 pages/guides/httpserver-erlang26.2.mdx create mode 100644 pages/guides/httpserver-expressjs4.18-node21.mdx create mode 100644 pages/guides/httpserver-g++13.2.mdx create mode 100644 pages/guides/httpserver-gcc13.2.mdx create mode 100644 pages/guides/httpserver-go1.21.mdx create mode 100644 pages/guides/httpserver-java17-springboot3.2.x.mdx create mode 100644 pages/guides/httpserver-java21.mdx create mode 100644 pages/guides/httpserver-lua5.1.mdx create mode 100644 pages/guides/httpserver-nginx-vite-vanilla.mdx create mode 100644 pages/guides/httpserver-node-express-puppeteer.mdx create mode 100644 pages/guides/httpserver-node21-nextjs.mdx create mode 100644 pages/guides/httpserver-node21-remix.mdx create mode 100644 pages/guides/httpserver-node21-solid-start.mdx rename pages/guides/{sveltekit.mdx => httpserver-node21-sveltekit.mdx} (61%) create mode 100644 pages/guides/httpserver-node25.mdx create mode 100644 pages/guides/httpserver-perl5.42.mdx create mode 100644 pages/guides/httpserver-php8.2.mdx rename pages/guides/{prisma.mdx => httpserver-prisma-expressjs4.19-node18.mdx} (69%) create mode 100644 pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx create mode 100644 pages/guides/httpserver-python3.12-django5.0.mdx create mode 100644 pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx create mode 100644 pages/guides/httpserver-python3.12-flask3.0.mdx create mode 100644 pages/guides/httpserver-python3.12.mdx create mode 100644 pages/guides/httpserver-ruby3.2.mdx create mode 100644 pages/guides/httpserver-rust1.75-tokio.mdx create mode 100644 pages/guides/httpserver-rust1.81-rocket0.5.mdx create mode 100644 pages/guides/httpserver-rust1.87-actix-web4.mdx create mode 100644 pages/guides/httpserver-rust1.91.mdx delete mode 100644 pages/guides/hugo.mdx create mode 100644 pages/guides/hugo0.122.mdx delete mode 100644 pages/guides/java.mdx delete mode 100644 pages/guides/llama2.mdx delete mode 100644 pages/guides/lua.mdx create mode 100644 pages/guides/mcp-server-arxiv.mdx create mode 100644 pages/guides/mcp-server-simple.mdx delete mode 100644 pages/guides/memcached.mdx create mode 100644 pages/guides/memcached1.6.mdx delete mode 100644 pages/guides/nextjs.mdx delete mode 100644 pages/guides/node.mdx create mode 100644 pages/guides/node24-karaoke.mdx create mode 100644 pages/guides/novnc-browser.mdx delete mode 100644 pages/guides/overview.mdx delete mode 100644 pages/guides/perl.mdx delete mode 100644 pages/guides/php.mdx delete mode 100644 pages/guides/puppeteer.mdx delete mode 100644 pages/guides/python.mdx delete mode 100644 pages/guides/redis.mdx delete mode 100644 pages/guides/remix.mdx delete mode 100644 pages/guides/ruby.mdx rename pages/guides/{rails.mdx => ruby3.2-rails.mdx} (57%) delete mode 100644 pages/guides/rust-actix.mdx delete mode 100644 pages/guides/rust-rocket.mdx delete mode 100644 pages/guides/rust-tokio.mdx delete mode 100644 pages/guides/skipper.mdx create mode 100644 pages/guides/skipper0.18.mdx delete mode 100644 pages/guides/solidjs.mdx create mode 100644 pages/guides/spin-wagi-http.mdx delete mode 100644 pages/guides/spin.mdx delete mode 100644 pages/guides/springboot.mdx delete mode 100644 pages/guides/tyk.mdx create mode 100644 pages/guides/visual-studio-code-server.mdx create mode 100644 pages/guides/vsftpd.mdx rename pages/guides/{wazero.mdx => wazero-import-go.mdx} (53%) create mode 100644 pages/guides/wordpress-all-in-one.mdx delete mode 100644 pages/guides/wordpress.mdx diff --git a/.github/workflows/sync.yaml b/.github/workflows/sync.yaml index 9ab85345..6dd05134 100644 --- a/.github/workflows/sync.yaml +++ b/.github/workflows/sync.yaml @@ -53,8 +53,8 @@ jobs: with: token: ${{ secrets.GH_PAT }} base: ${{ inputs.docs_branch || 'main' }} - commit-message: "sync: Update guides from examples repository" - title: "sync: Update guides from examples repository" + commit-message: "chore: Update guides from examples repository" + title: "chore: Update guides from examples repository" body: | Automated sync of example READMEs from [`unikraft/examples@${{ inputs.examples_branch }}`](https://github.com/unikraft/examples/tree/${{ inputs.examples_branch }}). diff --git a/.vale/styles/config/vocabularies/Unikraft/accept.txt b/.vale/styles/config/vocabularies/Unikraft/accept.txt index 7cd3a654..19a13328 100644 --- a/.vale/styles/config/vocabularies/Unikraft/accept.txt +++ b/.vale/styles/config/vocabularies/Unikraft/accept.txt @@ -280,6 +280,7 @@ FTP (?i)vite (?i)VS Code (?i)vscode +(?i)vsftpd (?i)Vue (?i)Vuex (?i)wagi diff --git a/pages/guides/bun.mdx b/pages/guides/bun.mdx deleted file mode 100644 index 2471a54b..00000000 --- a/pages/guides/bun.mdx +++ /dev/null @@ -1,239 +0,0 @@ ---- -title: "Bun" ---- - -This guide explains how to create and deploy a Bun app. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/bun` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/bun/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy the app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/bun:latest -unikraft run --metro=fra -p 443:3000/http+tls -m 512MiB my-org/bun:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:3000 -M 512 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: bun-700mp - β”œ────────── uuid: e467a880-075c-41e0-97ac-88e3e938523e - β”œ───────── state: starting - β”œ──────── domain: https://quiet-pond-ao44imcg.fra.unikraft.app - β”œ───────── image: bun@sha256:dfcbee1efe0d8a1d43ab2dab70cf1cc5066bb1353aa1c528c745533d2cc33276 - β”œ──────── memory: 512 MiB - β”œ─────── service: quiet-pond-ao44imcg - β”œ── private fqdn: bun-700mp.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/bun run /usr/src/server.ts -``` - -In this case, the instance name is `bun-700mp` and the address is `https://quiet-pond-ao44imcg.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the Bun instance: - -```bash -curl https://quiet-pond-ao44imcg.fra.unikraft.app -``` - -```text -Hello, World! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - - -```text -NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME -bun-700mp quiet-pond-ao44imcg.fra.unikraft.app running since 3mins bun@sha256:dfcbee1efe0d8a1d43ab... 512 MiB /usr/bin/bun run /usr/src/server.ts 289.03 ms -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete bun-700mp -``` - -```bash title="kraft" -kraft cloud instance remove bun-700mp -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem -* `server.ts`: the Bun server implementation - - -```yaml title="Kraftfile" -spec: v0.6 - -name: bun - -runtime: base-compat:latest - -rootfs: ./Dockerfile - -cmd: ["/usr/bin/bun," "run," "/usr/src/server.ts"] -``` - -```dockerfile title="Dockerfile" -FROM oven/bun:1 AS bun - -RUN set -xe; \ - mv /usr/local/bin/bun /usr/bin/bun; \ - mkdir /self; \ - ln -sfn /usr/bin/bun /self/exe - -FROM alpine:3 AS sys - -RUN set -xe; \ - mkdir -p /target/etc; \ - mkdir -p /blank; \ - apk --no-cache add \ - ca-certificates \ - tzdata \ - ; \ - update-ca-certificates; \ - ln -sf /usr/share/zoneinfo/Etc/UTC /target/etc/localtime; \ - echo "Etc/UTC" > /target/etc/timezone; - -FROM scratch - -COPY --from=bun /self /proc/self -COPY --from=bun /usr/bin/bun /usr/bin/bun - -COPY --from=bun /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 -COPY --from=bun /lib/x86_64-linux-gnu/libdl.so.2 /lib/x86_64-linux-gnu/libdl.so.2 -COPY --from=bun /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/libm.so.6 -COPY --from=bun /lib/x86_64-linux-gnu/libpthread.so.0 /lib/x86_64-linux-gnu/libpthread.so.0 -COPY --from=bun /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 - -COPY --from=sys /target/etc /etc -COPY --from=sys /usr/share/zoneinfo/UTC /usr/share/zoneinfo/UTC -COPY --from=sys /usr/share/zoneinfo/Etc/UTC /usr/share/zoneinfo/Etc/UTC -COPY --from=sys /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt -COPY --from=sys /blank /tmp - -COPY ./server.ts /usr/src/server.ts - ``` - -```js title="server.js" -const port = process.env.PORT || 3000; - -console.log( - `Launching Bun HTTP server on port: ${port}, url: http://0.0.0.0:${port} πŸš€` -); - -Bun.serve({ - port: port, - fetch(_request) { - return new Response("Hello, World!\n"); - }, -}); -``` - - -Lines in the `Kraftfile` have the following roles: - -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. - -* `runtime: base-compat:latest`: The kernel to use. - -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. - -* `cmd: ["/usr/bin/bun", "run", "/usr/src/server.ts"]`: Use `/usr/bin/bun run /usr/src/server.ts` as the starting command of the instance. - -Lines in the `Dockerfile` have the following roles: - -* `FROM scratch`: Build the filesystem from the [`scratch` container image](https://hub.docker.com/_/scratch/), to [create a base image](https://docs.docker.com/build/building/base-images/). - -* `COPY ...`: Copy required files to the app filesystem: the `bun` binary executable, libraries, configuration files, the `/usr/src/server.ts` implementation. - -* `RUN ...`: Run specific commands to generate or to prepare the filesystem contents. - -The following options are available for customizing the app: - -* If you only update the implementation in the `server.ts` source file, you don't need to make any other changes. - -* If you want to add extra files, you need to copy them into the filesystem using the `COPY` command in the `Dockerfile`. - -* If you want to replace `server.ts` with a different source file, update the `cmd` line in the `Kraftfile` and replace `/usr/src/server.ts` with the path to your new source file. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/caddy.mdx b/pages/guides/caddy.mdx deleted file mode 100644 index 54092061..00000000 --- a/pages/guides/caddy.mdx +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: Caddy ---- - -This example uses [`Caddy`](https://caddyserver.com/), one of the most popular web servers. -Caddy can be used with Unikraft / Unikraft Cloud to serve static web content. - -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/caddy/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/caddy/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/caddy:latest -unikraft run --metro=fra -p 443:2015/http+tls -m 128MiB my-org/caddy:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:2015 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: caddy-vhf4m - β”œ────────── uuid: db624eff-4739-4500-873c-f7c58e4eefd7 - β”œ───────── state: running - β”œ─────────── url: https://frosty-sky-vz8kwsmb.fra.unikraft.app - β”œ───────── image: caddy@sha256:25df97e3c43147c683f31dd062d0fa75122358b596de5804ca246c4e8613dd56 - β”œ───── boot time: 20.18ms - β”œ──────── memory: 128 MiB - β”œ─────── service: frosty-sky-vz8kwsm - β”œ── private fqdn: caddy-vhf4m.internal - β”œ──── private ip: 172.16.6.2 - β””────────── args: /usr/bin/caddy run --config /etc/caddy/Caddyfile -``` - -In this case, the instance name is `caddy-vhf4m` and the address is `https://frosty-sky-vz8kwsmb.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of Caddy. - -```bash -curl https://frosty-sky-vz8kwsmb.fra.unikraft.app -``` -```text -Hello World! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -caddy-vhf4m frosty-sky-vz8kwsmb.fra.unikraft.app running 1 minute ago caddy@sha25:25df97e3c43147c683f... 128 MiB /usr/bin/caddy run --config /e... 20180us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete caddy-vhf4m -``` - -```bash title="kraft" -kraft cloud instance remove caddy-vhf4m -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `Kraftfile`: the Unikraft Cloud specification -* `rootfs/var/www/index.html`: the index page of the content served -* `rootfs/etc/caddy/Caddyfile`: the Caddy configuration file - - -```yaml title="Kraftfile" -spec: v0.6 - -runtime: caddy:latest - -rootfs: ./rootfs -``` - -```html title="rootfs/var/www/index.html" -Hello, world! -``` - -```text title="rootfs/etc/caddy/Caddyfile" -:2015 - -root * /var/www - -encode gzip - -templates - -file_server -``` - - -Update the contents of the `rootfs/var/www` directory to serve different static web content. -For example, you could change the contents of `rootfs/var/www/index.html` to: - -```html - - - -Hello - - -

Hello, World!

- - -``` - -After re-deploying the Caddy image on Unikraft Cloud, using `curl` or a browser to query it will present the new page contents. - -You can generate the static web content in `rootfs/var/www/` offline with tools such as [`Jekyll`](https://jekyllrb.com/) or [`Hugo`](https://gohugo.io/). - -If required, you can also customize the configuration of Caddy in `rootfs/etc/caddy/Caddyfile`. -You can set a new webroot (different than `rootfs`), or a different internal port, or a different index page, etc. - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/caddy2.7-go1.21.mdx b/pages/guides/caddy2.7-go1.21.mdx new file mode 100644 index 00000000..00d4e8b5 --- /dev/null +++ b/pages/guides/caddy2.7-go1.21.mdx @@ -0,0 +1,166 @@ +--- +title: "Caddy" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +This example uses [`Caddy`](https://caddyserver.com/), one of the most popular web servers. +Caddy can be used with Unikraft / Unikraft Cloud to serve static web content. + +To run this example, follow these steps: + +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/caddy2.7-go1.21/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/caddy2.7-go1.21/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /caddy27-go121:latest +unikraft run --metro=fra -p 443:2015/http+tls -m 256M /caddy27-go121:latest +``` + +```bash title="kraft" +kraft cloud deploy -p 443:2015/http+tls -M 256M . +``` + + + +The output shows the instance address and other details: + +```ansi +[●] Deployed successfully! + β”‚ + β”œ────────── name: caddy27-go121-vhf4m + β”œ────────── uuid: db624eff-4739-4500-873c-f7c58e4eefd7 + β”œ───────── state: running + β”œ─────────── url: https://frosty-sky-vz8kwsmb.fra.unikraft.app + β”œ───────── image: caddy27-go121@sha256:25df97e3c43147c683f31dd062d0fa75122358b596de5804ca246c4e8613dd56 + β”œ───── boot time: 20.18ms + β”œ──────── memory: 256 MiB + β”œ─────── service: frosty-sky-vz8kwsmb + β”œ── private fqdn: caddy27-go121-vhf4m.internal + β”œ──── private ip: 172.16.6.2 + β””────────── args: /usr/bin/caddy run --config /etc/caddy/Caddyfile +``` + +In this case, the instance name is `caddy27-go121-vhf4m` and the address is `https://frosty-sky-vz8kwsmb.fra.unikraft.app`. +They're different for each run. + +Use `curl` to query the Unikraft Cloud instance of Caddy. + +```bash +curl https://frosty-sky-vz8kwsmb.fra.unikraft.app +``` + +```text +Hello World! +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +caddy27-go121-vhf4m frosty-sky-vz8kwsmb.fra.unikraft.app running 1 minute ago caddy27-go121@sha256:25df97e3c... 256 MiB 1 /usr/bin/caddy run --config /e... 20180us +``` + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete caddy27-go121-vhf4m +``` + +```bash title="kraft" +kraft cloud instance remove caddy27-go121-vhf4m +``` + + + +## Customize your app + +To customize the app, update the files in the repository, listed below: + +* `Kraftfile`: the Unikraft Cloud specification +* `rootfs/var/www/index.html`: the index page of the content served +* `rootfs/etc/caddy/Caddyfile`: the Caddy configuration file + +Update the contents of the `rootfs/var/www` directory to serve different static web content. +For example, you could change the contents of `rootfs/var/www/index.html` to: + +```html + + + +Hello + + +

Hello, World!

+ + +``` + +After re-deploying the Caddy image on Unikraft Cloud, using `curl` or a browser to query it will present the new page contents. + +You can generate the static web content in `rootfs/var/www/` offline with tools such as [`Jekyll`](https://jekyllrb.com/) or [`Hugo`](https://gohugo.io/). + +If required, you can also customize the configuration of Caddy in `rootfs/etc/caddy/Caddyfile`. +You can set a new webroot (different than `rootfs`), or a different internal port, or a different index page, etc. + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/cpp-boost.mdx b/pages/guides/cpp-boost.mdx deleted file mode 100644 index cbd52c74..00000000 --- a/pages/guides/cpp-boost.mdx +++ /dev/null @@ -1,329 +0,0 @@ ---- -title: C++ Boost ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a C++-based HTTP web server using the [Boost](https://www.boost.org/) libraries. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -2. Clone the [example repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-cpp-boost/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/http-cpp-boost/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-cpp-boost:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-cpp-boost:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: http-cpp-boost-rae7s - β”œ────────── uuid: 5a9886fa-f8a3-4860-afcf-d5eb13fdc38d - β”œ───────── state: running - β”œ─────────── url: https://red-snow-3bn7bzc8.fra.unikraft.app - β”œ───────── image: http-cpp-boost@sha256:61cf86b89fed46351af53689e27189315e466576475f61c7240bf17644613489 - β”œ───── boot time: 15.00 ms - β”œ──────── memory: 128 MiB - β”œ─────── service: red-snow-3bn7bzc8 - β”œ── private fqdn: http-cpp-boost-rae7s.internal - β”œ──── private ip: 172.16.6.4 - β””────────── args: /http_server -``` - -In this case, the instance name is `http-cpp-boost-rae7s` and the address is `https://red-snow-3bn7bzc8.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the C++ Boost HTTP web server: - -```bash -curl https://red-snow-3bn7bzc8.fra.unikraft.app -``` -```text -Hello, World! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -http-cpp-boost-rae7s red-snow-3bn7bzc8.fra.unikraft.app running 1 minute ago http-cpp-boost@sha256:61cf86b89fed46351af53689e27189315e... 128 MiB /http_server 15000us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete http-cpp-boost-rae7s -``` - -```bash title="kraft" -kraft cloud instance remove http-cpp-boost-rae7s -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `http_server.cpp`: the C++ HTTP server -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - - - - ```cpp -/** - * Compile with: g++ async_http_server.cpp -o async_http_server -lboost_system -lboost_thread -lpthread - * - * https://gist.github.com/danilogr/990efa4ab3b5bce29b883b931ac55507 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using boost::asio::ip::tcp; - -class HttpServer; // forward declaration - -class Request : public boost::enable_shared_from_this -{ - // member variables - HttpServer& server; - boost::asio::streambuf request; - boost::asio::streambuf response; - - void afterRead(const boost::system::error_code& ec, std::size_t bytes_transferred) - { - // done reading, writes answer (yes, we ignore the request); - std::ostream res_stream(&response); - - boost::system::error_code err; - res_stream << "HTTP/1.0 200 OK\r\n" - << "Content-Type: text/html; charset=UTF-8\r\n" - << "Content-Length: 14\r\n" - << "\r\n" - << "Hello, World!\n" << "\r\n"; - boost::asio::async_write(*socket, response, boost::bind(&Request::afterWrite, shared_from_this(), err, bytes_transferred)); - } - - void afterWrite(const boost::system::error_code& ec, std::size_t bytes_transferred) - { - // done writing, closing connection - socket->close(); - } - - public: - - boost::shared_ptr socket; - Request(HttpServer& server); - void answer() - { - if (!socket) return; - - // reads request till the end - boost::system::error_code err; - boost::asio::async_read_until(*socket, request, "\r\n\r\n", - boost::bind(&Request::afterRead, shared_from_this(), err, 0)); - } -}; - - -class HttpServer -{ - public: - - HttpServer(unsigned int port) : acceptor(io_service, tcp::endpoint(tcp::v4(), port)) {} - ~HttpServer() { if (sThread) sThread->join(); } - - void Run() - { - sThread.reset(new boost::thread(boost::bind(&HttpServer::thread_main, this))); - } - - boost::asio::io_service io_service; - - private: - tcp::acceptor acceptor; - boost::shared_ptr sThread; - - void thread_main() - { - // adds some work to the io_service - start_accept(); - io_service.run(); - } - void start_accept() - { - boost::system::error_code err; - boost::shared_ptr req (new Request(*this)); - acceptor.async_accept(*req->socket, - boost::bind(&HttpServer::handle_accept, this, req, err)); - } - - void handle_accept(boost::shared_ptr req, const boost::system::error_code& error) - { - if (!error) { req->answer(); } - start_accept(); - } -}; - -Request::Request(HttpServer& server): server(server) -{ - socket.reset(new tcp::socket(server.io_service)); -} - - -int main() -{ - HttpServer server(8080); - server.Run(); -} -} - ``` - - - ```yaml -spec: v0.6 - -runtime: base:latest - -rootfs: ./Dockerfile - -cmd: ["/http_server"] - ``` - - - ```dockerfile -FROM --platform=linux/x86_64 debian:bookworm AS build - -RUN set -xe ; \ - apt -yqq update ; \ - apt -yqq install build-essential ; \ - apt -yqq install libboost-all-dev - -WORKDIR /src - -COPY ./http_server.cpp /src/http_server.cpp - -RUN set -xe; \ - g++ \ - -Wall -Wextra \ - -fPIC -pie \ - -o /http_server http_server.cpp \ - -lboost_system -lboost_thread -lpthread - -FROM scratch - -# System/C++ libraries -COPY --from=build /lib/x86_64-linux-gnu/libboost_thread.so.1.74.0 /lib/x86_64-linux-gnu/libboost_thread.so.1.74.0 -COPY --from=build /lib/x86_64-linux-gnu/libstdc++.so.6 /lib/x86_64-linux-gnu/libstdc++.so.6 -COPY --from=build /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib/x86_64-linux-gnu/libgcc_s.so.1 -COPY --from=build /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 -COPY --from=build /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/libm.so.6 -COPY --from=build /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 - -# C++ HTTP server -COPY --from=build /http_server /http_server - ``` - - - -Lines in the `Kraftfile` have the following roles: - -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. - -* `runtime: base`: The Unikraft runtime kernel to use is its base one. - -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. - -* `cmd: ["/http_server"]`: Use `/http_server` as the starting command of the instance. - -Lines in the `Dockerfile` have the following roles: - -* `COPY ./http_server.cpp /src/http_server.cpp`: Copy the server implementation file (`http_server.cpp`) in the Docker filesystem (in `/src/http_server.cpp`). - -The following options are available for customizing the app: - -* If you only update the implementation in the `http_server.cpp` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/cpp.mdx b/pages/guides/cpp.mdx deleted file mode 100644 index a15f19ac..00000000 --- a/pages/guides/cpp.mdx +++ /dev/null @@ -1,291 +0,0 @@ ---- -title: C++ ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a simple C++-based HTTP web server. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -2. Clone the [example repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-cpp/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/http-cpp/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-cpp:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-cpp:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: http-cpp-jzbuo - β”œ────────── uuid: b8e015fd-d006-49d5-849e-3fd497c9159a - β”œ───────── state: running - β”œ─────────── url: https://throbbing-wave-grxjih4t.fra.unikraft.app - β”œ───────── image: http-cpp@sha256:a58873987104b52c13b79168a2e2f1a81876ba6efacd6dbc98e996afe5c09699 - β”œ───── boot time: 15.61 ms - β”œ──────── memory: 128 MiB - β”œ─────── service: throbbing-wave-grxjih4t - β”œ── private fqdn: http-cpp-jzbuo.internal - β”œ──── private ip: 172.16.6.5 - β””────────── args: /http_server -``` - -In this case, the instance name is ` http-cpp-jzbuo` and the address is `https://throbbing-wave-grxjih4t.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the C++ HTTP web server: - -```bash -curl https://throbbing-wave-grxjih4t.fra.unikraft.app -``` -```text -Hello, World! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -http-cpp-jzbuo throbbing-wave-grxjih4t.fra.unikraft.app running 1 minute ago http-cpp@sha256:a58873987104b52c13b79168a2e2f1a81876ba6efac... 128 MiB /http_server 15614us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete http-cpp-jzbuo -``` - -```bash title="kraft" -kraft cloud instance remove http-cpp-jzbuo -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `http_server.cpp`: the actual C++ HTTP server -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - - - - ```cpp - /* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Copyright (c) 2023, Unikraft GmbH and the Unikraft Authors. - */ - -#include -#include -#include -#include -#include -#include - -#define LISTEN_PORT 8080 - -static std::string reply = "HTTP/1.1 200 OK\r\n" \ - "Content-Type: text/html\r\n" \ - "Content-Length: 14\r\n" \ - "Connection: close\r\n" \ - "\r\n" \ - "Hello, World!\n"; - -#define BUFLEN 2048 -static char recvbuf[BUFLEN]; - -int main(int argc __attribute__((unused)), - char *argv[] __attribute__((unused))) -{ - int rc = 0; - int srv, client; - ssize_t n; - struct sockaddr_in srv_addr; - - srv = socket(AF_INET, SOCK_STREAM, 0); - if (srv < 0) { - std::cerr << "Failed to create socket: " << errno << std::endl; - goto out; - } - - srv_addr.sin_family = AF_INET; - srv_addr.sin_addr.s_addr = INADDR_ANY; - srv_addr.sin_port = htons(LISTEN_PORT); - - rc = bind(srv, (struct sockaddr *) &srv_addr, sizeof(srv_addr)); - if (rc < 0) { - std::cerr << "Failed to bind socket: " << errno << std::endl; - goto out; - } - - /* Accept one simultaneous connection */ - rc = listen(srv, 1); - if (rc < 0) { - std::cerr << "Failed to listen on socket: " << errno << std::endl; - goto out; - } - - std::cout << "Listening on port " << LISTEN_PORT << std::endl; - while (1) { - client = accept(srv, NULL, 0); - if (client < 0) { - std::cerr << "Failed to accept incoming connection: " << errno << std::endl; - goto out; - } - - /* Receive some bytes (ignore errors) */ - read(client, recvbuf, BUFLEN); - - /* Send reply */ - n = write(client, reply.c_str(), reply.length()); - if (n < 0) - std::cerr << "Failed to send reply" << std::endl; - else - std::cout << "Sent a reply" << std::endl; - - /* Close connection */ - close(client); - } - -out: - return rc; -} - ``` - - - ```yaml - spec: v0.6 - - runtime: base:latest - - rootfs: ./Dockerfile - - cmd: ["/http_server"] - ``` - - - ```dockerfile - FROM --platform=linux/x86_64 gcc:13.2.0-bookworm AS build - -WORKDIR /src - -COPY ./http_server.cpp /src/http_server.cpp - -RUN set -xe; \ - g++ \ - -Wall -Wextra \ - -fPIC -pie \ - -o /http_server http_server.cpp - -FROM scratch - -# System/C++ libraries -COPY --from=build /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/ -COPY --from=build /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/libm.so.6 -COPY --from=build /usr/local/lib64/libgcc_s.so.1 /usr/local/lib64/libgcc_s.so.1 -COPY --from=build /usr/local/lib64/libstdc++.so.6 /usr/local/lib64/libstdc++.so.6 -COPY --from=build /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 -COPY --from=build /etc/ld.so.cache /etc/ld.so.cache - -# C++ HTTP server -COPY --from=build /http_server /http_server - ``` - - - -Lines in the `Kraftfile` have the following roles: - -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. - -* `runtime: base`: The Unikraft runtime kernel to use is its base one. - -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. - -* `cmd: ["/http_server"]`: Use `/http_server` as the starting command of the instance. - -Lines in the `Dockerfile` have the following roles: - -* `FROM --platform=linux/x86_64 gcc:13.2.0-bookworm AS build`: Build the filesystem from the `bookworm gcc` container image, to [create a base image](https://docs.docker.com/build/building/base-images/). - -* `COPY ./http_server.cpp /src/http_server.cpp`: Copy the server implementation file (`http_server.cpp`) in the Docker filesystem (in `/src/http_server.cpp`). - -The following options are available for customizing the app: - -* If you only update the implementation in the `http_server.cpp` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/debian-ssh.mdx b/pages/guides/debian-ssh.mdx new file mode 100644 index 00000000..390e242d --- /dev/null +++ b/pages/guides/debian-ssh.mdx @@ -0,0 +1,139 @@ +--- +title: "Debian SSH server" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +This guide explains how to create and deploy a Debian app with SSH enabled. +To run this example, follow these steps: + +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/debian-ssh` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/debian-ssh/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /debian-ssh:latest +unikraft run --metro=fra -p 2222:2222/tls -m 1G -e PUBKEY="...." /debian-ssh:latest +``` + +```bash title="kraft" +kraft cloud deploy -p 2222:2222/tls -M 1G -e PUBKEY="...." . +``` + + + +The output shows the instance address and other details: + +```ansi +[●] Deployed successfully! + β”‚ + β”œ─────── name: debian-ssh-2uwg5 + β”œ─────── uuid: b3d158c5-fb52-4685-a76b-2497973308dc + β”œ────── metro: https://api.fra.unikraft.cloud/v1 + β”œ────── state: starting + β”œ───── domain: nameless-cherry-sw2e9ul2.fra.unikraft.app + β”œ────── image: debian-ssh@sha256:2442b4d5e078e7bc9ccd887fac65623511551592315d341a219f34a2c6628949 + β”œ───── memory: 1024 MiB + β”œ──── service: nameless-cherry-sw2e9ul2 + β”œ─ private ip: 10.0.0.109 + β””─────── args: /usr/bin/wrapper.sh +``` + +In this case, the instance name is `debian-ssh-2uwg5` and the address is `nameless-cherry-sw2e9ul2.fra.unikraft.app`. +They're different for each run. + +You need to set up a tunnel that handles the TLS connection to the Unikraft Cloud instance. +This way, you have a non-TLS port that your SSH client can connect to: + +```bash +socat TCP-LISTEN:2222,reuseaddr,fork OPENSSL:nameless-cherry-sw2e9ul2.fra.unikraft.app:2222,verify=0 +``` + +Then connect to the instance via SSH using: + +```bash +ssh -l root localhost -p 2222 +``` + +You might see warnings like `REMOTE HOST IDENTIFICATION HAS CHANGED`. +This is normal if you have set up tunnels to connect with SSH on `localhost`, so don't worry. + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +debian-ssh-2uwg5 nameless-cherry-sw2e9ul2.fra.unikraft.app running since 5mins debian-ssh@sha256:2442... 1.0 GiB 1 /usr/bin/wrapper.sh 217.26 ms +``` + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete debian-ssh-2uwg5 +``` + +```bash title="kraft" +kraft cloud instance remove debian-ssh-2uwg5 +``` + + + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). \ No newline at end of file diff --git a/pages/guides/django.mdx b/pages/guides/django.mdx deleted file mode 100644 index 0f87dfa8..00000000 --- a/pages/guides/django.mdx +++ /dev/null @@ -1,355 +0,0 @@ ---- -title: Django ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a Python Django web app. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-python3.12-django5.0/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/http-python3.12-django5.0/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-python312-django:latest -unikraft run --metro=fra -p 443:80/http+tls -m 512MiB my-org/http-python312-django:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:80 -M 512 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: http-python312-django50-vt56c - β”œ────────── uuid: d8469447-fdf6-4caf-9fea-494218ca6f72 - β”œ───────── state: running - β”œ─────────── url: https://dawn-sound-n5wrkxi2.fra.unikraft.app - β”œ───────── image: http-python312-django50@sha256:221666d414299aff54dbf10020b3d540270ee0c5907c1c6a728ca254ce8b0e50 - β”œ───── boot time: 80.32 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: dawn-sound-n5wrkxi2 - β”œ── private fqdn: http-python312-django50-vt56c.internal - β”œ──── private ip: 172.16.6.5 - β””────────── args: /usr/bin/python3 /app/main.py -``` - -In this case, the instance name is `http-python312-django50-vt56c` and the address is `https://dawn-sound-n5wrkxi2.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the Django web app server: - -```bash -curl https://dawn-sound-n5wrkxi2.fra.unikraft.app -``` -```html - - - - - - - The install worked successfully! Congratulations! - - - - -

Welcome to nginx!

-

If you see this page, the nginx web server is successfully installed and - working. Further configuration is required.

- -

For online documentation and support please refer to - nginx.org.
- Commercial support is available at - nginx.com.

- -

Thank you for using nginx.

- - - ``` - - - ```text - worker_processes 1; - daemon off; - master_process off; - user root root; - - events { - worker_connections 64; - } - - http { - include mime.types; - default_type app/octet-stream; - - open_file_cache max=10000 inactive=30s; - open_file_cache_min_uses 2; - open_file_cache_errors on; - - error_log stderr error; - access_log off; - - keepalive_timeout 10s; - keepalive_requests 10000; - send_timeout 10s; - - server { - listen 8080; - server_name localhost; - root /wwwroot; - index index.html; - } - } - ``` - -
- Update the contents of the `rootfs/wwwroot/` directory to serve different static web content. For example, you could change the contents of `rootfs/wwwroot/index.html` to: @@ -230,7 +155,7 @@ You can set a new webroot (different than `wwwroot`), or a different internal po Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help @@ -242,4 +167,4 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/node.mdx b/pages/guides/node.mdx deleted file mode 100644 index 9c64b1aa..00000000 --- a/pages/guides/node.mdx +++ /dev/null @@ -1,332 +0,0 @@ ---- -title: Node ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a simple Node-based HTTP web server. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-node21/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/http-node21/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy the app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-node21:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB my-org/http-node21:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080 -M 256 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: http-node21-ubl8g - β”œ────────── uuid: 6985f8e7-72c2-4726-941c-3c568a83722e - β”œ───────── state: running - β”œ─────────── url: https://ancient-haze-sd3wwi0x.fra.unikraft.app - β”œ───────── image: http-node21@sha256:de174e3703c79a048f0af52344c373296b55f3ca2b96cd29e16c1f014cefd232 - β”œ───── boot time: 41.65 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: ancient-haze-sd3wwi0x - β”œ── private fqdn: http-node21-ubl8g.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/node /usr/src/server.js -``` - -In this case, the instance name is `http-node21-ubl8g` and the address is `https://ancient-haze-sd3wwi0x.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the Node-based HTTP web server: - -```bash -curl https://ancient-haze-sd3wwi0x.fra.unikraft.app -``` -```text -Hello, World! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -http-node21-ubl8g ancient-haze-sd3wwi0x.fra.unikraft.app running 50 seconds ago http-node21@sha256:de174e3703c79a04... 256 MiB /usr/bin/node /usr/src/server.js 31654us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete http-node21-ubl8g -``` - -```bash title="kraft" -kraft cloud instance remove http-node21-ubl8g -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `server.js`: the actual Node HTTP server -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - - - - ```js - const http = require('http'); // Loads the http module - - http.createServer((request, response) => { - - // 1. Tell the browser everything is OK (Status code 200), and the data is in plain text - response.writeHead(200, { - 'Content-Type': 'text/plain' - }); - - // 2. Write the announced text to the body of the page - response.write('Hello, World!\n'); - - // 3. Tell the server that all of the response headers and body have been sent - response.end(); - - }).listen(8080); // 4. Tells the server what port to be on - ``` - - - ```yaml - spec: v0.6 - - runtime: node:21 - - rootfs: ./Dockerfile - - cmd: ["/usr/bin/node", "/usr/src/server.js"] - ``` - - - ```dockerfile - FROM scratch - - # Simple Node HTTP server - COPY ./server.js /usr/src/server.js - ``` - - - -Lines in the `Kraftfile` have the following roles: - -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. - -* `runtime: node:21`: The Unikraft runtime kernel to use is Node 21. - -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. - -* `cmd: ["/usr/bin/node", "/usr/src/server.js"]`: Use `/usr/bin/node /usr/src/server.js` as the starting command of the instance. - -Lines in the `Dockerfile` have the following roles: - -* `FROM scratch`: Build the filesystem from the [`scratch` container image](https://hub.docker.com/_/scratch/), to [create a base image](https://docs.docker.com/build/building/base-images/). - -* `COPY ./server.js /usr/src/server.js`: Copy the server implementation file (`server.js`) in the Docker filesystem (in `/usr/src/server.js`). - -The following options are available for customizing the app: - -* If you only update the implementation in the `server.js` source file, you don't need to make any other changes. - -* If you want to add extra files, you need to copy them into the filesystem using the `COPY` command in the `Dockerfile`. - -* If you want to replace `server.js` with a different source file, update the `cmd` line in the `Kraftfile` and replace `/usr/src/server.js` with the path to your new source file. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - This includes the use of Node frameworks and the use of [`npm`](https://www.npmjs.com/), as shown in the next section. - -## Using `npm` - -[`npm`](https://www.npmjs.com/) is a package manager for Node. -It's used to install dependencies for Node apps. -`npm` uses a `package.json` file to list required dependencies (with versions). - -The [`node21-expressjs`](https://github.com/kraftcloud/examples/tree/main/node21-expressjs) example in the [`examples`](https://github.com/kraftcloud/examples) repository details the use of `npm` to deploy an app using the [ExpressJS](https://expressjs.com/) framework on Unikraft Cloud. -Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `node21-expressjs` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/node21-expressjs/ -``` - -Run the command below to deploy the app on Unikraft Cloud: - -```bash -kraft cloud deploy -p 443:3000 -M 256 . -``` - -Differences from the `http-node21` app are also the steps required to create an `npm`-based app: - -1. Add the `package.json` file used by `npm`. - -1. Add framework-specific source files. - In this case, this means `app/index.js`. - -1. Update the `Dockerfile` to: - - 1. `COPY` the local files. - - 1. `RUN` the `npm install` command to install dependencies. - - 1. `COPY` of the resulting and required files (`node_modules/` and `app/index.js`) in the app filesystem, using the [`scratch` container](https://hub.docker.com/_/scratch/). - -The following lists the files: - - - - ```js - const express = require('express') - const app = express() - const port = 3000 - - app.get('/', (req, res) => { - res.send('Hello, World!\n') - }) - - app.listen(port, () => { - console.log(`Example app listening on port ${port}`) - }) - ``` - - - ```json - { - "dependencies": { - "express": "^4.18.2" - } - } - ``` - - - ```yaml - spec: v0.6 - - runtime: node:21 - - rootfs: ./Dockerfile - - cmd: ["/usr/bin/node", "/usr/src/server.js"] - ``` - - - ```dockerfile - FROM node:21-alpine AS build - - WORKDIR /usr/src - - COPY . /usr/src/ - - RUN npm install - - FROM scratch - - # Distribution configuration - COPY --from=build /etc/os-release /etc/os-release - - # Express.js - COPY --from=build /usr/src/app/index.js /usr/src/server.js - COPY --from=build /usr/src/node_modules /usr/src/node_modules - ``` - - - -The `package.json` file lists the `express` [dependency](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#dependencies). - -The `Kraftfile` is the same one used for `http-node21`. - -For `Dockerfile` newly added lines have the following roles: - -* `FROM node:21-alpine AS build`: Use the base image of the `node:21-alpine` container. - This provides the `npm` binary and other Node-related components. - Name the current image `build`. - -* `WORKDIR /usr/src`: Use `/usr/src` as working directory. - All other commands in the `Dockerfile` run inside this directory. - -* `COPY . /usr/src/`: Copy the contents of the local current directory to the Docker filesystem. - Note that paths in the `.dockerignore` file aren't copied. - This means that `package.json` and `app/index.js` are copied. - -* `RUN npm install`: Install `npm` components listed in `packages.json`. - -* `COPY --from=build ...`: Copy existing files in the new `build` image in the `scratch`-based image. - `/etc/os-release` must copy to provide the distribution information required by node. - `/usr/src/node_modules` are the `npm`-generated files. - `/usrc/src/app/index.js` is the original `ExpressJS` source code file. - -Similar actions apply to other `npm`-based apps. -See also other Node examples: [`node18-prisma-rest-express`](https://github.com/kraftcloud/examples/tree/main/node18-prisma-rest-express) and [`node21-nextjs`](https://github.com/kraftcloud/examples/tree/main/node21-nextjs). - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/node24-karaoke.mdx b/pages/guides/node24-karaoke.mdx new file mode 100644 index 00000000..7e7e0cba --- /dev/null +++ b/pages/guides/node24-karaoke.mdx @@ -0,0 +1,187 @@ +--- +title: "Node AllKaraoke" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +[Allkaraoke](https://github.com/Asvarox/allkaraoke) offers an ultrastar deluxe-like online platform for karaoke. + +To run this example, follow these steps: + +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node24-karaoke` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/node24-karaoke/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /node24-karaoke:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 2G /node24-karaoke:latest +``` + +```bash title="kraft" +kraft cloud deploy -p 443:8080/tls+http -M 2G . +``` + + + +The output shows the instance address and other details: + +```ansi +[●] Deployed successfully! + β”‚ + β”œ────────── name: node24-karaoke-9lw5q + β”œ────────── uuid: e5f6a7b8-c9d0-1234-efab-345678901234 + β”œ───────── state: starting + β”œ──────── domain: https://wild-song-p5q2nrwx.fra.unikraft.app + β”œ───────── image: node24-karaoke@sha256:1a3c5e7b9d2f4a6c8e0b2d4f6a8c0e2b4d6f8a0b2c4e6f8a0b2d4f6a8c0e2b + β”œ──────── memory: 2 GiB + β”œ─────── service: wild-song-p5q2nrwx + β”œ── private fqdn: node24-karaoke-9lw5q.internal + β”œ──── private ip: 172.16.3.8 + β””────────── args: /entrypoint.sh +``` + +In this case, the instance name is `node24-karaoke-9lw5q` and the address is `https://wild-song-p5q2nrwx.fra.unikraft.app`. +They're different for each run. + +Use `curl` to query the Unikraft Cloud instance of the AllKaraoke instance: + +```bash +curl https://wild-song-p5q2nrwx.fra.unikraft.app +``` + +```text + + + + + + + AllKaraoke.Party - Free Online Karaoke + ... + + ... + +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +node24-karaoke-9lw5q wild-song-p5q2nrwx.fra.unikraft.app running since 3mins node24-karaoke@sha256:1a3c5e7b9d2f4a... 2 GiB 1 /entrypoint.sh 1.24 s +``` + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete node24-karaoke-9lw5q +``` + +```bash title="kraft" +kraft cloud instance remove node24-karaoke-9lw5q +``` + + + +## Customize your app + +To customize the app, update the files in the repository, listed below: + +* `Kraftfile`: the Unikraft Cloud specification +* `Dockerfile`: the Docker-specified app filesystem +* `entrypoint.sh`: the shell script used to start the AllKaraoke server + +Lines in the `Kraftfile` have the following roles: + +* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. + +* `runtime: base-compat:latest`: The kernel to use. + +* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. + +* `cmd: ["/entrypoint.sh"]`: Use `/entrypoint.sh` as the starting command of the instance. + +Lines in the `Dockerfile` have the following roles: + +* `FROM node:24-bookworm-slim AS build`: Build the AllKaraoke project using the Node.js 24 Bookworm slim image. + +* `RUN git clone ...; pnpm install; pnpm build`: Clone the AllKaraoke repository, install dependencies, and build it for production. + +* `FROM node:24-bookworm-slim AS prod`: Use a fresh Node.js 24 Bookworm slim image for the runtime. + +* `COPY ...`: Copy required files to the app filesystem: the `node` binary executable, system libraries, the built AllKaraoke artifacts, and the entrypoint script. + +The following options are available for customizing the app: + +* If you want to use a specific version of AllKaraoke, update the `git clone` command in the `Dockerfile` to pin a particular commit or tag. + +* If you want to add extra files, you need to copy them into the filesystem using the `COPY` command in the `Dockerfile`. + +* If you want to change the startup behavior, update the `entrypoint.sh` script. + +* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). + +## Learn more + +- [Allkaraoke official deployment](https://allkaraoke.party/) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) +- [Building `Dockerfile` images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/novnc-browser.mdx b/pages/guides/novnc-browser.mdx new file mode 100644 index 00000000..c631231f --- /dev/null +++ b/pages/guides/novnc-browser.mdx @@ -0,0 +1,145 @@ +--- +title: "noVNC" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +This guide explains how to create and deploy a [noVNC](https://novnc.com/info.html) app, allowing you to access remote desktops through +a web interface inside a modern browser. + +**Note**: Anthropic's [Computer Use Demo](https://github.com/anthropics/claude-quickstarts/tree/main/computer-use-demo) inspired this example. + +To run this example, follow these steps: + +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/novnc-browser` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/novnc-browser/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /novnc-browser:latest +unikraft run --scale-to-zero policy=on,cooldown-time=40000,stateful=true --metro=fra -p 443:6080/tls+http -m 4G /novnc-browser:latest +``` + +```bash title="kraft" +kraft cloud deploy \ + --scale-to-zero on \ + --scale-to-zero-stateful \ + --scale-to-zero-cooldown 4s \ + -p 443:6080/tls+http \ + -M 4G \ + -n vnc-browser \ + . +``` + + + +The output shows the instance address and other details: + +```ansi +[●] Deployed successfully! + β”‚ + β”œ─────── name: vnc-browser + β”œ─────── uuid: 90a59b05-0ae1-4ca6-8383-79c5115355ee + β”œ────── metro: https://api.fra.unikraft.cloud/v1 + β”œ────── state: starting + β”œ───── domain: https://weathered-fog-y5jjmwfd.fra.unikraft.app + β”œ────── image: novnc-browser@sha256:fdb4887e84362ebbaf54c713e0d85f547e8ee173fe63a6ab39e94b7e612a9892 + β”œ───── memory: 4096 MiB + β”œ──── service: weathered-fog-y5jjmwfd + β”œ─ private ip: 10.0.0.49 + β””─────── args: /wrapper.sh +``` + +In this case, the instance name is `vnc-browser` and the address is `https://weathered-fog-y5jjmwfd.fra.unikraft.app`. +The name was preset, but the address is different for each run. +Enter the provided address into your browser of choice to access the remote desktop interface. + +Use `curl` to query the Unikraft Cloud instance: + +```bash +curl https://weathered-fog-y5jjmwfd.fra.unikraft.app +``` + +```text +Hello, World! +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +vnc-browser weathered-fog-y5jjmwfd.fra.unikraft.app standby standby novnc-browser@sha256:fdb4887e84362ebbaf5... 4.0 GiB 1 /wrapper.sh 7.17 ms +``` + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete vnc-browser +``` + +```bash title="kraft" +kraft cloud instance remove vnc-browser +``` + + + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/opentelemetry-collector.mdx b/pages/guides/opentelemetry-collector.mdx index e18fe785..e648ef69 100644 --- a/pages/guides/opentelemetry-collector.mdx +++ b/pages/guides/opentelemetry-collector.mdx @@ -2,30 +2,29 @@ title: "OpenTelemetry Collector" --- + import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" -This example uses [OpenTelemetry -Collector](https://opentelemetry.io/docs/collector/), a vendor-agnostic +This example uses [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/), a vendor-agnostic implementation of how to receive, process and export telemetry data. -OpenTelemetry Collector works with Unikraft / Unikraft Cloud to process -telemetry data. +OpenTelemetry Collector works with Unikraft / Unikraft Cloud to process telemetry data. To run this example, follow these steps: 1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/opentelemetry-collector/` directory: +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/opentelemetry-collector/` directory: ```bash -git clone https://github.com/kraftcloud/examples +git clone https://github.com/unikraft-cloud/examples cd examples/opentelemetry-collector/ ``` -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - + ```bash title="unikraft" unikraft login @@ -40,19 +39,17 @@ export UKC_METRO=fra -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - When done, invoke the following command to deploy this app on Unikraft Cloud: - + ```bash title="unikraft" -unikraft build . --output my-org/opentelemetry-collector:latest -unikraft run --metro=fra -m 1024MiB my-org/opentelemetry-collector:latest +unikraft build . --output /opentelemetry-collector:latest +unikraft run --metro=fra -p 443:4318/tls+http -m 1536M /opentelemetry-collector:latest ``` ```bash title="kraft" -kraft cloud deploy -M 1024M . +kraft cloud deploy -p 443:4318/tls+http -M 1536M . ``` @@ -62,14 +59,14 @@ The output shows the instance address and other details: ```ansi [●] Deployed successfully! β”‚ - β”œ────────── name: opentelemetry-collector-bvtnh - β”œ────────── uuid: 40e8b154-b3b6-4312-ae69-2cdb794b15e4 - β”œ───────── state: starting - β”œ───────── image: opentelemetry-collector@sha256:64f73ea5fe208f54e5212f57979f24bebcf36276495462c52b380d15dd539ced - β”œ──────── memory: 976 MiB - β”œ── private fqdn: opentelemetry-collector-bvtnh.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/otelcontribcol --config /etc/otel/config.yaml + β”œ────────── name: opentelemetry-collector-bvtnh + β”œ────────── uuid: 40e8b154-b3b6-4312-ae69-2cdb794b15e4 + β”œ───────── state: starting + β”œ───────── image: opentelemetry-collector@sha256:64f73ea5fe208f54e5212f57979f24bebcf36276495462c52b380d15dd539ced + β”œ──────── memory: 1536 MiB + β”œ── private fqdn: opentelemetry-collector-bvtnh.internal + β”œ──── private ip: 172.16.3.3 + β””────────── args: /usr/bin/otelcontribcol --config /etc/otel/config.yaml ``` In this case, the instance name is `opentelemetry-collector-bvtnh`. @@ -82,7 +79,7 @@ Feel free to change and redeploy! You can list information about the instance by running: - + ```bash title="unikraft" unikraft instances list @@ -93,15 +90,15 @@ kraft cloud instance list ``` -```text -unikraft instances list -NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME -opentelemetry-collector-bvtnh running since 11mins opentelemetry... 976 MiB /usr/bin/otelcontribcol --config... 177.62 ms + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +opentelemetry-collector-bvtnh running since 11mins opentelemetry... 1536 MiB 1 /usr/bin/otelcontribcol --config... 177.62 ms ``` When done, you can remove the instance: - + ```bash title="unikraft" unikraft instances delete opentelemetry-collector-bvtnh @@ -117,63 +114,6 @@ kraft cloud instance remove opentelemetry-collector-bvtnh To customize the OpenTelemetry Collector app, update `Kraftfile` or, more likely, the `rootfs/etc/otel/config.yaml` files: - - - Kratfile - rootfs/etc/otel/config.yaml - - - ```yaml -spec: v0.6 - -runtime: opentelemetry-collector:latest - -rootfs: ./rootfs - ``` - - - ```yaml title="" -receivers: - otlp: - protocols: - grpc: - endpoint: "0.0.0.0:4317" - http: - endpoint: "0.0.0.0:4318" - -exporters: - debug: - verbosity: detailed - -processors: - batch: - -extensions: - health_check: - -service: - extensions: [health_check] - # Disable the self telemetry which requires process-level data - telemetry: - metrics: - level: none - pipelines: - traces: - receivers: [otlp] - processors: [batch] - exporters: [debug] - metrics: - receivers: [otlp] - processors: [batch] - exporters: [debug] - logs: - receivers: [otlp] - processors: [batch] - exporters: [debug] - ``` - - - You can update the `rootfs/etc/otel/config.yaml` file as detailed in the [documentation](https://opentelemetry.io/docs/collector/configuration/). Such as adding another export, apart from the debug exporter. @@ -181,7 +121,7 @@ Such as adding another export, apart from the debug exporter. Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help @@ -193,4 +133,4 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/overview.mdx b/pages/guides/overview.mdx deleted file mode 100644 index 46f68b1c..00000000 --- a/pages/guides/overview.mdx +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: Guides -navigation_icon: book-open-text ---- - -This section contains step-by-step guides for deploying popular languages, frameworks, databases, and tools on Unikraft Cloud. - -Every guide points to a ready-to-run example in the **[`unikraft-cloud/examples`](https://github.com/unikraft-cloud/examples)** repository on GitHub. -Clone it once and you'll have all examples at your fingertips: - -```bash -git clone https://github.com/unikraft-cloud/examples -``` - -Each example directory contains a `Kraftfile` and a `Dockerfile` that are the only files you need to deploy. -Refer to the individual guide for the exact `kraft cloud deploy` command and a walkthrough of the configuration. - -## Languages & runtimes - -| Guide | Runtime | -|---|---| -| [Bun](/guides/bun) | Bun | -| [C (HTTP debug server)](/guides/http-c-debug) | GCC / C | -| [C++ (Boost)](/guides/httpserver-boost1.74-g++13.2) | g++ 13.2 / Boost 1.74 | -| [C++ (g++)](/guides/httpserver-g++13.2) | g++ 13.2 | -| [C++ (gcc)](/guides/httpserver-gcc13.2) | GCC 13.2 | -| [Elixir 1.16](/guides/httpserver-elixir1.16) | Elixir 1.16 | -| [Elixir 1.17](/guides/http-elixir1.17) | Elixir 1.17 | -| [Erlang 26.2](/guides/httpserver-erlang26.2) | Erlang 26.2 | -| [Go 1.21](/guides/httpserver-go1.21) | Go 1.21 | -| [Java 17](/guides/httpserver-java17) | Java 17 | -| [Java 21](/guides/http-java21) | Java 21 | -| [Lua 5.1](/guides/httpserver-lua5.1) | Lua 5.1 | -| [.NET 8.0](/guides/httpserver-dotnet8.0) | .NET 8.0 | -| [Node.js 21](/guides/httpserver-nodejs21) | Node.js 21 | -| [Node.js 25](/guides/http-node25) | Node.js 25 | -| [Perl 5.38](/guides/httpserver-perl5.38) | Perl 5.38 | -| [Perl 5.42](/guides/http-perl5.42) | Perl 5.42 | -| [PHP 8.2](/guides/httpserver-php8.2) | PHP 8.2 | -| [Python 3.12](/guides/httpserver-python3.12) | Python 3.12 | -| [Ruby 3.2](/guides/httpserver-ruby3.2) | Ruby 3.2 | -| [Rust 1.73](/guides/httpserver-rust1.73) | Rust 1.73 | -| [Rust 1.75](/guides/httpserver-rust1.75) | Rust 1.75 | -| [Rust 1.79 (Axum, scale-to-zero)](/guides/http-rust-1.79-axum-scale-to-zero) | Rust 1.79 / Axum | -| [Rust 1.81 (Rocket)](/guides/httpserver-rust1.81-rocket0.5) | Rust 1.81 / Rocket 0.5 | -| [Rust 1.87 (Actix Web)](/guides/httpserver-rust1.87-actix-web4) | Rust 1.87 / Actix Web 4 | -| [Rust 1.91](/guides/http-rust1.91) | Rust 1.91 | -| [Wazero (Go / WASM)](/guides/wazero-import-go) | Wazero / Go | -| [WebAssembly (Spin / WAGI)](/guides/spin-wagi-http) | Spin / WAGI | - -## Frameworks & full-stack apps - -| Guide | Stack | -|---|---| -| [AllKaraoke (Node 24)](/guides/node24-karaoke) | Node.js 24 | -| [Django 5.0](/guides/httpserver-python3.12-django5.0) | Python 3.12 / Django 5.0 | -| [Express.js 4.18](/guides/expressjs4.18-node21) | Node.js 21 / Express 4.18 | -| [Express.js 4.19 + Prisma](/guides/prisma-expressjs4.19-node18) | Node.js 18 / Prisma | -| [FastAPI 0.121](/guides/http-python3.12-FastAPI-0.121.3) | Python 3.12 / FastAPI | -| [Flask 3.0 + Python 3.12 + SQLite](/guides/flask3.0-python3.12-sqlite3) | Python 3.12 / Flask 3.0 | -| [Flask 3.0 + SQLite](/guides/python3.12-flask3.0-sqlite) | Python 3.12 / Flask 3.0 | -| [Flask + Redis](/guides/database-redis7.2) | Python / Flask / Redis 7.2 | -| [Hugo 0.122](/guides/hugo0.122) | Hugo 0.122 | -| [Next.js (Node 21)](/guides/node21-nextjs) | Node.js 21 / Next.js | -| [Puppeteer (Node)](/guides/node-express-puppeteer) | Node.js / Puppeteer | -| [Rails (Ruby 3.2)](/guides/ruby3.2-rails) | Ruby 3.2 / Rails | -| [Remix (Node 21)](/guides/node21-remix) | Node.js 21 / Remix | -| [SolidStart (Node 21)](/guides/node21-solid-start) | Node.js 21 / SolidStart | -| [Spring Boot 3.2 (Java 17)](/guides/java17-springboot3.2.x) | Java 17 / Spring Boot 3.2 | -| [SvelteKit (Node 21)](/guides/node21-sveltekit) | Node.js 21 / SvelteKit | -| [Vite + nginx](/guides/nginx-vite-vanilla) | Node.js / Vite / nginx | -| [Webhook handler (GitHub / Node)](/guides/webhook-github-node) | Node.js | -| [WordPress (all-in-one)](/guides/wordpress-all-in-one) | WordPress / PHP | - -## Databases & storage - -| Guide | Technology | -|---|---| -| [DragonflyDB](/guides/dragonflydb) | DragonflyDB | -| [DuckDB (Go 1.21)](/guides/duckdb-go1.21) | Go 1.21 / DuckDB | -| [MariaDB](/guides/mariadb) | MariaDB | -| [Memcached 1.6](/guides/memcached1.6) | Memcached 1.6 | -| [MinIO](/guides/minio) | MinIO | -| [MongoDB](/guides/mongodb) | MongoDB | -| [PostgreSQL](/guides/postgres) | PostgreSQL | -| [Redis 7.2](/guides/database-redis7.2) | Redis 7.2 | - -## Networking & infrastructure - -| Guide | Technology | -|---|---| -| [Caddy 2.7 (Go 1.21)](/guides/caddy2.7-go1.21) | Caddy 2.7 | -| [Grafana](/guides/grafana) | Grafana | -| [HAProxy](/guides/haproxy) | HAProxy | -| [nginx](/guides/nginx) | nginx | -| [OpenTelemetry Collector](/guides/opentelemetry-collector) | OpenTelemetry | -| [Skipper 0.18](/guides/skipper0.18) | Skipper 0.18 | -| [Traefik](/guides/traefik) | Traefik | -| [vsftpd](/guides/vsftpd) | vsftpd | - -## AI & LLMs - -| Guide | Technology | -|---|---| -| [MCP server (arXiv)](/guides/mcp-server-arxiv) | Node.js / MCP | -| [MCP server (simple)](/guides/mcp-server-simple) | Node.js / MCP | - -## Developer tools & utilities - -| Guide | Technology | -|---|---| -| [Chromium (Chrome DevTools Protocol)](/guides/chromium-cdp) | Chromium / CDP | -| [code-server](/guides/code-server) | VS Code in the browser | -| [Debian SSH](/guides/debian-ssh) | Debian / SSH | -| [Imaginary](/guides/imaginary) | Imaginary | -| [noVNC](/guides/vnc-browser) | Virtual Network Computing (VNC) | - -## Learn more - -- **[`unikraft-cloud/examples` on GitHub](https://github.com/unikraft-cloud/examples)**: browse all example source files -- [Tutorials](/tutorials/): deeper dives into specific Unikraft Cloud capabilities -- [Use cases](/use-cases/): architecture patterns and production scenarios -- [CLI Reference](/cli/): full `kraft` CLI documentation diff --git a/pages/guides/perl.mdx b/pages/guides/perl.mdx deleted file mode 100644 index c9d82e2f..00000000 --- a/pages/guides/perl.mdx +++ /dev/null @@ -1,195 +0,0 @@ ---- -title: Perl ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a simple Perl-based HTTP web server. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-perl5.38/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/http-perl5.38/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-perl538:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-perl538:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080 -M 512 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: http-perl538-1p4ml - β”œ────────── uuid: eabb0080-0065-40ff-81a8-f790f1b218ee - β”œ───────── state: running - β”œ─────────── url: https://cold-brook-ba71jc16.fra.unikraft.app - β”œ───────── image: http-perl538@sha256:8c2c1f536b349c24e04ab4fec508b69f7f2349302d42a02855318ee55c12e37c - β”œ───── boot time: 64.56 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: cold-brook-ba71jc16 - β”œ── private fqdn: http-perl538-1p4ml.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/perl /usr/src/server.pl -``` - -In this case, the instance name is `http-perl538-1p4ml` and the address is `https://cold-brook-ba71jc16.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the Perl-based HTTP web server: - -```bash -curl https://cold-brook-ba71jc16.fra.unikraft.app -``` -```text -Hello, World! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -http-perl538-1p4ml cold-brook-ba71jc16.fra.unikraft.app stopped 37 seconds ago http-perl538@sha256:8c2c1f536b349c... 512 MiB /usr/bin/perl /usr/src/server.pl 64556us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete http-perl538-1p4ml -``` - -```bash title="kraft" -kraft cloud instance remove http-perl538-1p4ml -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `server.pl`: the actual Perl HTTP server -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - - - - ```pl - #!/usr/bin/perl - - use warnings; - use strict; - - use HTTP::Daemon; - use HTTP::Status; - use HTTP::Response; - - my $daemon = HTTP::Daemon->new( - LocalAddr => '0.0.0.0', - LocalPort => 8080, - ) or die; - - while (my $client_connection = $daemon->accept) { - my $request = $client_connection->get_request; - my $response = HTTP::Response->new(200); - $response->content("Hello, World!\n"); - $client_connection->send_response($response); - } - ``` - - - ```yaml - spec: v0.6 - - runtime: perl:5.38 - - rootfs: ./Dockerfile - - cmd: ["/usr/bin/perl", "/usr/src/server.pl"] - ``` - - - ```dockerfile - FROM scratch - - # Simple Perl HTTP server - COPY ./server.pl /usr/src/server.pl - ``` - - - -The following options are available for customizing the app: - -* If you only update the implementation in the `server.pl` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/php.mdx b/pages/guides/php.mdx deleted file mode 100644 index 7f3ffc9f..00000000 --- a/pages/guides/php.mdx +++ /dev/null @@ -1,232 +0,0 @@ ---- -title: PHP ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a simple PHP-based HTTP web server. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-php8.2/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/http-php8.2/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-php82:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-php82:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: http-php82-g00si - β”œ────────── uuid: 033b2f4b-72ff-414d-b0de-63571477c657 - β”œ───────── state: running - β”œ─────────── url: https://aged-fire-rh0oi0tj.fra.unikraft.app - β”œ───────── image: http-php82@sha256:dccaac053982673765b8f00497a9736c31458ab23ad59a550b09aa8dedfabb34 - β”œ───── boot time: 32.80 ms - β”œ──────── memory: 128 MiB - β”œ─────── service: aged-fire-rh0oi0tj - β”œ── private fqdn: http-php82-g00si.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/local/bin/php /usr/src/server.php -``` - -In this case, the instance name is `http-php82-g00si` and the address is `https://aged-fire-rh0oi0tj.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the PHP-based HTTP web server: - -```bash -curl https://aged-fire-rh0oi0tj.fra.unikraft.app -``` -```text -Hello, World! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -http-php82-g00si aged-fire-rh0oi0tj.fra.unikraft.app running 50 seconds ago http-php82@sha256:dccaac05398267376... 256 MiB /usr/local/bin/php /usr/src/server.php 32801us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete http-php82-g00si -``` - -```bash title="kraft" -kraft cloud instance remove http-php82-g00si -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `server.php`: the actual PHP HTTP server -* `php.ini`: the PHP configuration -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - - - - ```php - #!/usr/local/bin/php -q - - ``` - - - ```ini - [PHP] - - extension=sockets - ``` - - - ```yaml - spec: v0.6 - - runtime: php:8.2 - - rootfs: ./Dockerfile - - cmd: ["/usr/local/bin/php", "/usr/src/server.php"] - ``` - - - ```dockerfile - FROM scratch - - # PHP configuration - COPY ./php.ini /usr/local/etc/php/php.ini - - # Simple PHP HTTP server - COPY ./server.php /usr/src/server.php - ``` - - - -The following options are available for customizing the app: - -* If you only update the implementation in the `server.php` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - If you need new extensions, that may require updating the `php.ini` file. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/postgres.mdx b/pages/guides/postgres.mdx index 100dce55..022169cf 100644 --- a/pages/guides/postgres.mdx +++ b/pages/guides/postgres.mdx @@ -1,25 +1,28 @@ --- -title: PostgreSQL +title: "PostgreSQL" --- + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + This guide shows you how to use [PostgreSQL](https://www.postgresql.org/), a powerful, open source object-relational database system. To run it, follow these steps: 1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/postgres/` directory: +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/postgres/` directory: ```bash -git clone https://github.com/kraftcloud/examples +git clone https://github.com/unikraft-cloud/examples cd examples/postgres/ ``` -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - + ```bash title="unikraft" unikraft login @@ -34,19 +37,17 @@ export UKC_METRO=fra -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - When done, invoke the following command to deploy this app on Unikraft Cloud: - + ```bash title="unikraft" -unikraft build . --output my-org/postgres:latest -unikraft run --metro=fra -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -m 1Gi my-org/postgres:latest +unikraft build . --output /postgres:latest +unikraft run --metro=fra -p 5432:5432/tls -m 1G -e POSTGRES_PASSWORD=unikraft /postgres:latest ``` ```bash title="kraft" -kraft cloud deploy -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -M 1024 . +kraft cloud deploy -p 5432:5432/tls -M 1G -e POSTGRES_PASSWORD=unikraft . ``` @@ -56,16 +57,16 @@ The output shows the instance address and other details: ```ansi [●] Deployed successfully! β”‚ - β”œ────────── name: postgres-saan9 - β”œ────────── uuid: 3a1371f2-68c6-4187-84f8-c080f2b028ca - β”œ───────── state: starting - β”œ────────── fqdn: young-thunder-fbafrsxj.fra.unikraft.app - β”œ───────── image: postgres@sha256:2476c0373d663d7604def7c35ffcb4ed4de8ab231309b4f20104b84f31570766 - β”œ──────── memory: 1024 MiB - β”œ─────── service: young-thunder-fbafrsxj - β”œ── private fqdn: postgres-saan9.internal - β”œ──── private ip: 172.16.3.1 - β””────────── args: wrapper.sh docker-entrypoint.sh postgres -c shared_preload_libraries='pg_ukc_scaletozero' + β”œ────────── name: postgres-saan9 + β”œ────────── uuid: 3a1371f2-68c6-4187-84f8-c080f2b028ca + β”œ───────── state: starting + β”œ────────── fqdn: young-thunder-fbafrsxj.fra.unikraft.app + β”œ───────── image: postgres@sha256:2476c0373d663d7604def7c35ffcb4ed4de8ab231309b4f20104b84f31570766 + β”œ──────── memory: 1024 MiB + β”œ─────── service: young-thunder-fbafrsxj + β”œ── private fqdn: postgres-saan9.internal + β”œ──── private ip: 172.16.3.1 + β””────────── args: wrapper.sh docker-entrypoint.sh postgres -c shared_preload_libraries='pg_ukc_scaletozero' ``` In this case, the instance name is `postgres-saan9` and the service `young-thunder-fbafrsxj`. @@ -92,25 +93,23 @@ postgres=# Use SQL and `psql` commands for your work. -:::tip[Idle Scale-to-Zero] -This example uses the [`idle` scale-to-zero policy](/docs/api/v1/instances#scaletozero_policy) by default (see the `labels` section in the `Kraftfile`). -It means that the instance will scale-to-zero even in the presence of `psql` connections. -To ensure that the instance isn't put into standby even for long running queries -(during which the connections are also idle). -The PostgreSQL example makes use of scale-to-zero app support. -To this end, the example loads the [`pg_ukc_scaletozero`](https://github.com/kraftcloud/pg_ukc_scaletozero) module into PostgreSQL, which suspends scale-to-zero during query processing. -You can see this in action by running `SELECT pg_sleep(10);` and verifying that the instance keeps on running. -::: - -:::note -If you'd like to use a port other than `5432/tls` you'll need to use the legacy CLI tunnel command to connect to PostgreSQL. -See [the tunneling guide](/docs/guides/features/tunnel) for more information. -Additionally, you need to explicitly disable scale-to-zero by either changing the label in the `Kraftfile` or use `--scale-to-zero off` in the deploy command. -::: +> **Tip:** +> This example uses the [`idle` scale-to-zero policy](/api/platform/v1/instances#scaletozero_policy) by default (see the `labels` section in the `Kraftfile`). +> It means that the instance will scale-to-zero even in the presence of `psql` connections. +> To ensure that the instance isn't put into standby even for long running queries +> (during which the connections are also idle). +> The PostgreSQL example makes use of scale-to-zero app support. +> To this end, the example loads the [`pg_ukc_scaletozero`](https://github.com/unikraft-cloud/pg_ukc_scaletozero) module into PostgreSQL, which suspends scale-to-zero during query processing. +> You can see this in action by running `SELECT pg_sleep(10);` and verifying that the instance keeps on running. + +> **Note:** +> If you'd like to use a port other than `5432/tls` you'll need to use the `kraft cloud tunnel` command to connect to PostgreSQL. +> See [the tunneling guide](/cli/tunnel) for more information. +> Additionally, you need to explicitly disable scale-to-zero by either changing the label in the `Kraftfile` or use `--scale-to-zero off` in the deploy command. You can list information about the instance by running: - + ```bash title="unikraft" unikraft instances list @@ -122,17 +121,17 @@ kraft cloud instance list -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -postgres-saan9 young-thunder-fbafrsxj.fra.unikraft.app running 6 minutes ago postgres@sha256:2476c0373d663d7604d... 1.0 GiB wrapper.sh docker-entrypoint.sh postgres 603.42 ms +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +postgres-saan9 young-thunder-fbafrsxj.fra.unikraft.app running 6 minutes ago postgres@sha256:2476c0373d663d7604d... 1.0 GiB 1 wrapper.sh docker-entrypoint.sh postgres 603.42 ms ``` When done, you can remove the instance: - + ```bash title="unikraft" -unikraft instances delete postgres-saan9 +unikraft instance remove postgres-saan9 ``` ```bash title="kraft" @@ -143,20 +142,16 @@ kraft cloud instance remove postgres-saan9 ## Using volumes -You can use [volumes](/docs/guides/features/volumes) for data persistence for you PostgreSQL instance. - +You can use [volumes](/platform/volumes) for data persistence for your PostgreSQL instance. For that you would first create a volume: - + -```console title="unikraft" -unikraft volumes create \ - --set name=postgres \ - --set size=200 \ - --set metro=fra +```bash title="unikraft" +unikraft volume create --set metro=fra --set name=postgres --set size=200M ``` -```console title="kraft" +```bash title="kraft" kraft cloud volume create --name postgres --size 200 ``` @@ -164,15 +159,15 @@ kraft cloud volume create --name postgres --size 200 Then start the PostgreSQL instance and mount that volume: - + -```console title="unikraft" -unikraft build . --output my-org/postgres:latest -unikraft run --metro=fra -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume -p 5432:5432/tls -m 1Gi my-org/postgres:latest +```bash title="unikraft" +unikraft build . --output /postgres:latest +unikraft run --metro=fra -p 5432:5432/tls -m 1G -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres --volume postgres:/volume /postgres:latest ``` -```console title="kraft" -kraft cloud deploy -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume -p 5432:5432/tls -M 1024 . +```bash title="kraft" +kraft cloud deploy -p 5432:5432/tls -M 1G -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume . ``` @@ -187,18 +182,17 @@ For that you use a different `POSTGRES_PASSWORD` environment variable when start You could also a different location to mount your volume or set extra configuration options. -You can use the PostgreSQL instance in conjunction with a frontend service, [see the guide here](/docs/guides/features/idns). +You can use the PostgreSQL instance in conjunction with a frontend service, [see the guide here](/platform/services). But in that case make sure to disable scale-to-zero if you plan to use the DB internally. -:::note -Support for scale-to-zero for internal instances is coming soon. -::: +> **Note:** +> Support for scale-to-zero for internal instances is coming soon. ## Learn more Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help @@ -210,4 +204,4 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/puppeteer.mdx b/pages/guides/puppeteer.mdx deleted file mode 100644 index 0a5c9e4a..00000000 --- a/pages/guides/puppeteer.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: Puppeteer ---- - -This guide shows you how to use [Puppeteer](https://pptr.dev/), a Node.js library which provides a high-level API to control browsers, including the option to run them headless (no UI). - -To run it, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node-express-puppeteer/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/node-express-puppeteer/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -:::note -A Puppeteer instance on Unikraft Cloud requires 4GB to run. -Request an increase in the instance memory quota when you need more memory. -::: - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/node-express-puppeteer:latest -unikraft run --metro=fra -p 443:3000/http+tls -m 4Gi my-org/node-express-puppeteer:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:3000 -M 4096 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: node-express-puppeteer-7afg3 - β”œ────────── uuid: 7bb479d7-5b3e-444f-b07c-eae4da6f57cc - β”œ───────── state: starting - β”œ──────── domain: https://nameless-fog-0tvh1uov.fra.unikraft.app - β”œ───────── image: node-express-puppeteer@sha256:78d0b180161c876f17d05116b93011ddcd44c76758d6fa0359f05938e67cea65 - β”œ──────── memory: 4096 MiB - β”œ─────── service: little-snow-7qwu6vv5 - β”œ── private fqdn: node-express-puppeteer-7afg3.internal - β”œ──── private ip: 172.16.3.1 - β””────────── args: /usr/bin/wrapper.sh /usr/bin/node /app/bin/www -``` - -In this case, the instance name is `node-express-puppeteer-7afg3`. -They're different for each run. - -Use a browser to access the landing page of the Puppeteer (that uses [ExpressJS](https://expressjs.com/)). -The app and the landing page are part of [this repository](https://github.com/christopher-talke/node-express-puppeteer-pdf-example). - -In the example run above the landing page is at https://nameless-fog-0tvh1uov.fra.unikraft.app -You can use the landing page to generate the PDF version of a remote page. - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list node-express-puppeteer-7afg3 -``` - -```bash title="kraft" -kraft cloud instance list node-express-puppeteer-7afg3 -``` - - - -```text -NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME -node-express-puppeteer-7afg3 node-express-puppeteer-7afg3.fra.unikraft.app running since 6mins node-express-puppeteer-7afg3@s... 4.0 GiB /usr/bin/wrapper.sh /usr/bin/n... 15.27 ms -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete node-express-puppeteer-7afg3 -``` - -```bash title="kraft" -kraft cloud instance remove node-express-puppeteer-7afg3 -``` - - - -## Customize your deployment - -The current deployment uses an ExpressJS service that uses the [PDF generating functionality of Puppeteer](https://devdocs.io/puppeteer/). -Customizing the deployment means updating the service, such as adding new functionalities provided by Puppeteer. -You can update the service to provide a REST-like interface. - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/python.mdx b/pages/guides/python.mdx deleted file mode 100644 index 3c19d4a9..00000000 --- a/pages/guides/python.mdx +++ /dev/null @@ -1,333 +0,0 @@ ---- -title: Python ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a simple Python-based HTTP web server. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-python3.12/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/http-python3.12/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-python312:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-python312:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080 -M 512 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: http-python312-ma2i9 - β”œ────────── uuid: e7389eee-9808-4152-b2ec-1f3c0541fd05 - β”œ───────── state: running - β”œ─────────── url: https://young-night-5fpf0jj8.fra.unikraft.app - β”œ───────── image: http-python312@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472 - β”œ───── boot time: 15.09 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: young-night-5fpf0jj8 - β”œ── private fqdn: http-python312-ma2i9.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/python /src/server.py -``` - -In this case, the instance name is `http-python312-ma2i9` and the address is `https://young-night-5fpf0jj8.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the Python-based HTTP web server: - -```bash -curl https://young-night-5fpf0jj8.fra.unikraft.app -``` -```text -Hello, World! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -http-python312-ma2i9 young-night-5fpf0jj8.fra.unikraft.app running 1 minute ago http-python312@sha256:278cb8b14f9faf9c27... 512 MiB /usr/bin/python /src/server.py 15094us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete http-python312-ma2i9 -``` - -```bash title="kraft" -kraft cloud instance remove http-python312-ma2i9 -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `server.py`: the actual Python HTTP server -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - - - - ```py - import argparse - from http.server import HTTPServer, BaseHTTPRequestHandler - - class MyServer(BaseHTTPRequestHandler): - def do_GET(self): - self.send_response(200) - self.send_header("Content-type", "text/html") - self.end_headers() - self.wfile.write(bytes("Hello, World!\n", "utf-8")) - - def main(args): - server = HTTPServer((args.host, args.port), MyServer) - - print("starting server at %s:%s" % (args.host, args.port)) - - try: - server.serve_forever() - - except KeyboardInterrupt: - pass - - print("server stopped") - - def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument("--host", type=str, default="0.0.0.0") - parser.add_argument("--port", type=int, default=8080) - return parser.parse_args() - - if __name__ == "__main__": - main(parse_args()) - ``` - - - ```yaml -spec: v0.6 - -runtime: python:3.12 - -rootfs: ./Dockerfile - -cmd: ["/usr/bin/python3", "/src/server.py"] - ``` - - - ```dockerfile -FROM scratch - -# Python HTTP server -COPY ./server.py /src/server.py - ``` - - - -Lines in the `Kraftfile` have the following roles: - -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. - -* `runtime: python:3.12`: The Unikraft runtime kernel to use is Python 3.12. - -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. - -* `cmd: ["/usr/bin/python3", "/src/server.py"]`: Use `/usr/bin/python3 /src/server.py` as the starting command of the instance. - -Lines in the `Dockerfile` have the following roles: - -* `FROM scratch`: Build the filesystem from the [`scratch` container image](https://hub.docker.com/_/scratch/), to [create a base image](https://docs.docker.com/build/building/base-images/). - -* `COPY ./server.py /src/server.py`: Copy the server implementation file (`server.py`) in the Docker filesystem (in `/src/server.py`). - -The following options are available for customizing the app: - -* If you only update the implementation in the `server.py` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - This includes the use of Python frameworks and the use of [`pip`](), as shown in the next section. - -## Using `pip` - -[`pip`]() is a package manager for Python. -It's used to install dependencies for Python apps. -`pip` uses the `requirements.txt` file to list required dependencies (with versions). - -The [`http-python3.12-flask3.0`](/docs/guides/flask-sqlite/) guide details the use of `pip` to deploy an app using the [`Flask`](https://flask.palletsprojects.com/en/3.0.x/) framework on Unikraft Cloud. - -Run the command below to deploy the app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-python312-flask:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/http-python312-flask:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080 -M 512 . -``` - - - -Differences from the `http-python3.12` app are also the steps required to create an `pip`-based app: - -1. Add the `requirements.txt` file used by `pip`. - -1. Add framework-specific source files. - In this case, this means the `server.py` file. - -1. Update the `Dockerfile` to: - - 1. `COPY` the local files. - - 1. `RUN` the `pip3 install` command to install dependencies. - - 1. `COPY` of the resulting and required files (`/usr/local/lib/pyhon3.12` and `server.py`) in the app filesystem, using the [`scratch` container](https://hub.docker.com/_/scratch/). - -The following lists the files: - - - - ```py - from flask import Flask - app = Flask(__name__) - - @app.route('/') - def hello(): - return "Hello, World!\n" - - if __name__ == '__main__': - app.run(host='0.0.0.0', port=8080) - ``` - - - ```text - flask>=3.0,<3.1 - ``` - - - ```yaml - spec: v0.6 - - runtime: python:3.12 - - rootfs: ./Dockerfile - - cmd: ["/usr/bin/python3", "/app/server.py"] - ``` - - - ```dockerfile - FROM python:3.12-bookworm AS base - - WORKDIR /app - - COPY requirements.txt /app - - RUN pip3 install -r requirements.txt --no-cache-dir - - FROM scratch - - COPY --from=base /usr/local/lib/python3.12 /usr/local/lib/python3.12 - COPY ./server.py /app/server.py - ``` - - - -The `requirements.txt` file lists the `flask` dependency. - -The `Kraftfile` is the same one used for `http-python3.12`. - -For `Dockerfile` newly added lines have the following roles: - -* `FROM python:3.12-bookworm AS base`: Use the base image of the `python:3.12-bookworm` container. - This provides the `pip3` binary and other Python-related components. - Name the current image `base`. - -* `WORKDIR /app`: Use `/app` as working directory. - All other commands in the `Dockerfile` run inside this directory. - -* `COPY requirements.txt /app`: Copy the package configuration file to the Docker filesystem. - -* `RUN pip3 install ...`: Install `pip` components listed in `requirements.txt`. - -* `COPY --from=base ...`: Copy generated Python files in the new `base` image in the `scratch`-based image. - -Similar actions apply to other `pip3`-based apps. -See also the [`http-python3.12-django5.0`](https://github.com/kraftcloud/examples/tree/main/http-python3.12-django5.0) example. - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/redis.mdx b/pages/guides/redis.mdx deleted file mode 100644 index ef304c9a..00000000 --- a/pages/guides/redis.mdx +++ /dev/null @@ -1,208 +0,0 @@ ---- -title: Redis ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guides shows you how to use [Redis](https://redis.io), an open source in-memory storage, used as a distributed, in-memory key–value database, cache and message broker, with optional durability. - -To run it example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/redis/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/redis/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/redis:latest -unikraft run --metro=fra -p 6379:6379/tls -m 512MiB my-org/redis:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 6379:6379/tls -M 512 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: redis-alb4r - β”œ────────── uuid: d3c3141b-97b2-4e1d-87ae-39e4f14ab49e - β”œ───────── state: running - β”œ────────── fqdn: rough-wind-8vxrd1ms.fra.unikraft.app - β”œ───────── image: redis@sha256:9665c51faf7deb538cf7907b012b55700cad08cd391f5ba099d95d018c8da7d - β”œ───── boot time: 26.13 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: rough-wind-8vxrd1ms - β”œ── private fqdn: redis-alb4r.internal - β”œ──── private ip: 172.16.6.2 - β””────────── args: /usr/bin/redis-server /etc/redis/redis.conf -``` - -In this case, the instance name is `redis-alb4r` which is different for every run. - -To test the deployment, first forward the port with the legacy CLI tunnel command: - - - -```bash title="kraft" -kraft cloud tunnel 6379:memcached-arkv7:6379 -``` - - - -Then, from another console, you can now use the `redis-benchmark` client to connect to Redis, for example: -```console -redis-benchmark -t ping,set,get -n 10000 -``` - -You should see output like: - -```ansi -====== PING_INLINE ====== - 10000 requests completed in 32.03 seconds - 50 parallel clients - 3 bytes payload - keep alive: 1 - host configuration "save": - host configuration "appendonly": no - multi-thread: no - -0.01% <= 138 milliseconds -0.05% <= 139 milliseconds -2.34% <= 140 milliseconds -4.49% <= 141 milliseconds -8.57% <= 142 milliseconds -16.06% <= 143 milliseconds -21.83% <= 144 milliseconds -26.25% <= 145 milliseconds -34.54% <= 146 milliseconds -... -``` - -To disconnect, kill the `tunnel` command with ctrl-C. - -:::note -This guide uses `kraft cloud tunnel` only when a service doesn't support TLS and isn't HTTP-based (TLS/SNI determines the correct instance to send traffic to). -Also note that the `tunnel` command isn't needed when connecting via an instance's private IP/FQDN. -For example, when a Redis instance serves as a cache server to -another instance that acts as a frontend and which **does** support TLS. -::: - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -redis-alb4r rough-wind-8vxrd1ms.fra.unikraft.app running 1 minute ago redis@sha256:9665c5... 512 MiB /usr/bin/redis-server /etc/red... 26131us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete redis-alb4r -``` - -```bash title="kraft" -kraft cloud instance remove redis-alb4r -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `Kraftfile`: the Unikraft Cloud specification, including command-line arguments -* `Dockerfile`: In case you need to add files to your instance's rootfs - - - - ```yaml -spec: v0.6 - -runtime: redis:latest - -rootfs: ./Dockerfile - -cmd: ["/usr/bin/redis-server", "/etc/redis/redis.conf"] - ``` - - -```Dockerfile -FROM debian:bookworm AS build - -RUN set -xe; \ - echo "Your code here"; - -FROM scratch - -# Copy your files here -# COPY --from=build / / -``` - - - - - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/remix.mdx b/pages/guides/remix.mdx deleted file mode 100644 index c97703bd..00000000 --- a/pages/guides/remix.mdx +++ /dev/null @@ -1,175 +0,0 @@ ---- -title: Remix ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide shows how to deploy a [Remix](https://remix.run/) app. - -To do so, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node21-remix/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/node21-remix/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy the app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/node21-remix:latest -unikraft run --metro=fra -p 443:3000/http+tls -m 512MiB my-org/node21-remix:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:3000 -M 512 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: node21-remix-jvj6b - β”œ────────── uuid: 4e6ccb1f-0533-4dc1-be67-eca8dfc1f8c6 - β”œ───────── state: running - β”œ─────────── url: https://long-star-1tms9h1z.fra.unikraft.app - β”œ───────── image: node21-remix@sha256:300eefce3de136ad9c782f010b69da01100ae5f0ca17f038f92321d735d6675f - β”œ───── boot time: 153.47 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: long-star-1tms9h1z - β”œ── private fqdn: node21-remix-jvj6b.internal - β”œ──── private ip: 172.16.6.8 - β””────────── args: /usr/bin/node /usr/src/server.js -``` - -In this case, the instance name is `node21-remix-jvj6b` and the address is `https://long-star-1tms9h1z.fra.unikraft.app`. -They're different for each run. -You can now point your browser at the address to see your deployed instance. - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -node21-remix-jvj6b long-star-1tms9h1z.fra.unikraft.app running 1 minutes ago node21-rem... 256 MiB /usr/bin/node /usr/src/server... 67.65 ms -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete node21-remix-jvj6b -``` - -```bash title="kraft" -kraft cloud instance remove node21-remix-jvj6b -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem -* `server.js`: the server itself - - - ```yaml -spec: v0.6 - -runtime: node:21 - -rootfs: ./Dockerfile - -cmd: ["/usr/bin/node", "/usr/src/server.js"] - ``` - - - ```dockerfile -FROM node:21-alpine AS base - -WORKDIR /usr/src - -FROM base AS build - -COPY package.json /usr/src/package.json -RUN npm install - -COPY . /usr/src/ -RUN npm run build - -FROM base AS runtime - -COPY package.json /usr/src/package.json -RUN npm install --omit dev - -FROM scratch - -COPY --from=runtime /usr/src/node_modules /usr/src/node_modules -COPY --from=build /usr/src/build/ /usr/src/build/ -COPY --from=build /usr/src/public /usr/src/public -COPY --from=build /usr/src/server.js /usr/src/server.js -COPY --from=build /usr/src/package.json /usr/src/package.json - ``` - - - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/ruby.mdx b/pages/guides/ruby.mdx deleted file mode 100644 index ede460bb..00000000 --- a/pages/guides/ruby.mdx +++ /dev/null @@ -1,193 +0,0 @@ ---- -title: Ruby ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a simple Ruby-based HTTP web server. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-ruby3.2/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/http-ruby3.2/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-ruby32:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB my-org/http-ruby32:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080 -M 256 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: http-ruby32-s6l8n - β”œ────────── uuid: b1ebbbc0-5efa-476c-adb6-99866773245c - β”œ───────── state: running - β”œ─────────── url: https://silent-resonance-1jtz5c66.fra.unikraft.app - β”œ───────── image: http-ruby32@sha256:4cf3b341898e6ebff18ff2b68353ef872dded650c9d16a6f005a8fbe8a7cbb3d - β”œ───── boot time: 71.19 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: silent-resonance-1jtz5c66 - β”œ── private fqdn: http-ruby32-s6l8n.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/ruby /src/server.rb -``` - -In this case, the instance name is `http-ruby32-s6l8n` and the address is `https://silent-resonance-1jtz5c66.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the Ruby-based HTTP web server: - -```bash -curl https://silent-resonance-1jtz5c66.fra.unikraft.app -``` -```text -Hello, World! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -http-ruby32-s6l8n silent-resonance-1jtz5c66.fra.unikraft.app running 12 minutes ago http-ruby32@sha256:4cf3b341898e6ebff18ff2b68353ef... 256 MiB /usr/bin/ruby /src/server.rb 71191us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete http-ruby32-s6l8n -``` - -```bash title="kraft" -kraft cloud instance remove http-ruby32-s6l8n -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `server.rb`: the actual Ruby HTTP server -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - - - - ```rb - require 'socket' - - socket = TCPServer.new(8080) - - loop do - client = socket.accept - - request = client.gets - - response = "HTTP/1.1 200 OK\r\n" \ - "Content-type: text/html\r\n" \ - "Connection: close\r\n" \ - "\r\n" \ - "Hello, World!" - client.puts(response) - - client.close - end - ``` - - - ```yaml - spec: v0.6 - - runtime: ruby:3.2 - - rootfs: ./Dockerfile - - cmd: ["/usr/bin/ruby", "/src/server.rb"] - ``` - - - ```dockerfile - FROM scratch - - # Simple Ruby HTTP server - COPY ./server.rb /src/server.rb - ``` - - - -The following options are available for customizing the app: - -* If you only update the implementation in the `server.rb` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/rails.mdx b/pages/guides/ruby3.2-rails.mdx similarity index 57% rename from pages/guides/rails.mdx rename to pages/guides/ruby3.2-rails.mdx index d570fcf1..d9ac3c04 100644 --- a/pages/guides/rails.mdx +++ b/pages/guides/ruby3.2-rails.mdx @@ -1,26 +1,27 @@ --- -title: Ruby on Rails +title: "Ruby on Rails" --- + import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" This guide explains how to create and deploy a [Ruby on Rails](https://rubyonrails.org/) app. To run this example, follow these steps: 1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/ruby3.2-rails/` directory: +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/ruby3.2-rails/` directory: ```bash -git clone https://github.com/kraftcloud/examples +git clone https://github.com/unikraft-cloud/examples cd examples/ruby3.2-rails/ ``` -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - + ```bash title="unikraft" unikraft login @@ -35,19 +36,17 @@ export UKC_METRO=fra -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - When done, invoke the following command to deploy this app on Unikraft Cloud: - + ```bash title="unikraft" -unikraft build . --output my-org/ruby32-rails:latest -unikraft run --metro=fra -p 443:3000/http+tls -m 1024MiB -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle my-org/ruby32-rails:latest +unikraft build . --output /ruby3.2-rails:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 1G -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle /ruby3.2-rails:latest ``` ```bash title="kraft" -kraft cloud deploy -M 1024 -p 443:3000 -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle . +kraft cloud deploy -p 443:3000/tls+http -M 1G -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle . ``` @@ -57,17 +56,17 @@ The output shows the instance address and other details: ```ansi [●] Deployed successfully! β”‚ - β”œ────────── name: ruby32-rails-apa93 - β”œ────────── uuid: 2f85b9db-94f8-45d2-8e38-ed9b56cb8695 - β”œ───────── state: running - β”œ─────────── url: https://aged-waterfall-qraz0s7d.fra.unikraft.app - β”œ───────── image: ruby32-rails@sha256:fdd46011408fdee05644665ad59b24115737e3fdb352169ec2f3f16a45d4f31d - β”œ───── boot time: 577.34 ms - β”œ──────── memory: 1024 MiB - β”œ─────── service: aged-waterfall-qraz0s7d - β”œ── private fqdn: ruby32-rails-apa93.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/ruby /app/bin/rails server -b 0.0.0.0 + β”œ────────── name: ruby32-rails-apa93 + β”œ────────── uuid: 2f85b9db-94f8-45d2-8e38-ed9b56cb8695 + β”œ───────── state: running + β”œ─────────── url: https://aged-waterfall-qraz0s7d.fra.unikraft.app + β”œ───────── image: ruby32-rails@sha256:fdd46011408fdee05644665ad59b24115737e3fdb352169ec2f3f16a45d4f31d + β”œ───── boot time: 577.34 ms + β”œ──────── memory: 1024 MiB + β”œ─────── service: aged-waterfall-qraz0s7d + β”œ── private fqdn: ruby32-rails-apa93.internal + β”œ──── private ip: 172.16.3.3 + β””────────── args: /usr/bin/ruby /app/bin/rails server -b 0.0.0.0 ``` In this case, the instance name is `ruby32-rails-apa93` and the address is `https://aged-waterfall-qraz0s7d.fra.unikraft.app`. @@ -78,6 +77,7 @@ Use `curl` to query the Unikraft Cloud instance of the Python-based HTTP web ser ```bash curl https://aged-waterfall-qraz0s7d.fra.unikraft.app/hello ``` + ```text [...] @@ -90,7 +90,7 @@ Hello, World! You can list information about the instance by running: - + ```bash title="unikraft" unikraft instances list @@ -101,14 +101,15 @@ kraft cloud instance list ``` -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -ruby32-rails-apa93 aged-waterfall-qraz0s7d.fra.unikraft.app running 2 minutes ago ruby32-rails@sha256:fdd46011408fdee... 1.0 GiB /usr/bin/ruby /app/bin/rails server -b 0.0.0.0 577.34 ms + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +ruby32-rails-apa93 aged-waterfall-qraz0s7d.fra.unikraft.app running 2 minutes ago ruby32-rails@sha256:fdd46011408fdee... 1.0 GiB 1 /usr/bin/ruby /app/bin/rails server -b 0.0.0.0 577.34 ms ``` When done, you can remove the instance: - + ```bash title="unikraft" unikraft instances delete ruby32-rails-apa93 @@ -128,48 +129,12 @@ To customize the app, update the files in the repository, listed below: * `Kraftfile`: the Unikraft Cloud specification * `Dockerfile`: the Docker-specified app filesystem - - - ```yaml - spec: v0.6 - - runtime: ruby:3.2 - - rootfs: ./Dockerfile - - cmd: ["/usr/bin/ruby", "/app/bin/rails", "server", "-b", "0.0.0.0"] - ``` - - - ```dockerfile - FROM ruby:3.2.2-bookworm AS build - - RUN gem install rails - RUN rails new app - - WORKDIR /app - RUN rails generate controller hello - - COPY . /app/ - - FROM scratch - - # Ruby Gems & Rails contents - COPY --from=build /usr/local/bundle /usr/local/bundle - - # System libraries - [...] - - COPY --from=build /app /app - ``` - - - The `app/` and `config/` directories contain files that are to overwrite generated Rails files: ```bash tree app/ config/ ``` + ```text app/ |-- controllers/ @@ -220,7 +185,7 @@ The following options are available for customizing the app: Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help @@ -232,4 +197,4 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/rust-actix.mdx b/pages/guides/rust-actix.mdx deleted file mode 100644 index 17d892b9..00000000 --- a/pages/guides/rust-actix.mdx +++ /dev/null @@ -1,232 +0,0 @@ ---- -title: Rust (Actix Web) ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This example uses [`actix-web`](https://actix.rs), a popular Rust web framework. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-rust1.75-actix-web4/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/http-rust1.75-actix-web4/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-rust175-actix-web4:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-rust175-actix-web4:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: http-rust175-actix-web4-3pj27 - β”œ────────── uuid:33e9b4ba-58d7-4b3a-b9dd-4c406c0e7b07 - β”œ───────── state: running - β”œ─────────── url: https://autumn-silence-wupu2nus.fra.unikraft.app - β”œ───────── image: http-rust175-actix-web4@sha256:11723705230f0f4545d2be7e4867dc67b396870769e91f05e2fa6d9da94f9b59 - β”œ───── boot time: 11.67 ms - β”œ──────── memory: 128 MiB - β”œ─────── service: autumn-silence-wupu2nus - β”œ── private fqdn: http-rust175-actix-web4-3pj27.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /server -``` - -In this case, the instance name is `http-rust175-actix-web4-3pj27` and the address is `https://autumn-silence-wupu2nus.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the Rust-based HTTP web server: - -```bash -curl https://autumn-silence-wupu2nus.fra.unikraft.app -curl https://autumn-silence-wupu2nus.fra.unikraft.app/hey -``` -```text -Hello world! -Hey there! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -http-rust175-actix-web4-3pj27 autumn-silence-wupu2nus.fra.unikraft.app running 10 minutes ago http-rust175-actix-web4@sha256:11723705230f0f4545d2be7... 128 MiB /server 11672us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete http-rust175-actix-web4-3pj27 -``` - -```bash title="kraft" -kraft cloud instance remove http-rust175-actix-web4-3pj27 -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `src/main.rs`: the actual implementation -* `Cargo.toml`: the Cargo package manager configuration file -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - - - - ```yaml - spec: v0.6 - - runtime: base:latest - - rootfs: ./Dockerfile - - cmd: ["/server"] - ``` - - - ```rust - use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder}; - - #[get("/")] - async fn hello() -> impl Responder { - HttpResponse::Ok().body("Hello world!") - } - - #[post("/echo")] - async fn echo(req_body: String) -> impl Responder { - HttpResponse::Ok().body(req_body) - } - - async fn manual_hello() -> impl Responder { - HttpResponse::Ok().body("Hey there!") - } - - #[actix_web::main] - async fn main() -> std::io::Result<()> { - HttpServer::new(|| { - App::new() - .service(hello) - .service(echo) - .route("/hey", web::get().to(manual_hello)) - }) - .bind(("0.0.0.0", 8080))? - .run() - .await - } - ``` - - - ```toml - [package] - name = "hello" - version = "0.0.0" - edition = "2021" - publish = false - - [dependencies] - actix-web = "4" - ``` - - - ```dockerfile - FROM rust:1.75.0-bookworm AS build - - RUN cargo new --bin app - WORKDIR /app - COPY Cargo.toml ./ - COPY src ./src - RUN cargo build --release - - # This stage is optional but reduces overall image size - FROM scratch - COPY --from=build /app/target/release/hello /server - COPY --from=build /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/ - COPY --from=build /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/ - COPY --from=build /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib/x86_64-linux-gnu/ - COPY --from=build /lib64/ld-linux-x86-64.so.2 /lib64/ - ``` - - - -The following options are available for customizing the app: - -* If you only update the implementation in the `src/main.rs` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - If you add new Rust source code files, be sure to configure required dependencies in the `Cargo.toml` file. - -* If you build a new executable, update the `cmd` line in the `Kraftfile` and replace `/server` with the path to the new executable. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/rust-rocket.mdx b/pages/guides/rust-rocket.mdx deleted file mode 100644 index 2bce4b4b..00000000 --- a/pages/guides/rust-rocket.mdx +++ /dev/null @@ -1,285 +0,0 @@ ---- -title: Rust (Rocket) ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This example uses [`Rocket`](https://rocket.rs/), a popular Rust web framework. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-rust1.75-rocket0.5/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/http-rust1.75-rocket0.5 -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-rust175-rocket05:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-rust175-rocket05:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: http-rust175-rocket05-tuwq3 - β”œ────────── uuid: b6fe13e4-93b7-402b-bdec-1bc4d81bc275 - β”œ───────── state: running - β”œ─────────── url: https://empty-bobo-n3htmpye.fra.unikraft.app - β”œ───────── image: http-rust175-rocket05@sha256:23a7a6e155758e6e8f75e9570f0aec5fb744f08c1bad2454d7386367c5ea45d6 - β”œ───── boot time: 17.41 ms - β”œ──────── memory: 128 MiB - β”œ─────── service: empty-bobo-n3htmpye - β”œ── private fqdn: http-rust175-rocket05-tuwq3.internal - β”œ──── private ip: 172.16.6.6 - β””────────── args: /server -``` - -In this case, the instance name is `http-rust175-rocket05-tuwq3` and the address is `https://empty-bobo-n3htmpye.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query any of the Rocket server's paths, for example: - -```bash -curl https://empty-bobo-n3htmpye.fra.unikraft.app/wave/Rocketeer/100 -``` -```text -πŸ‘‹ Hello, 100 year old named Rocketeer! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -http-rust175-rocket05-tuwq3 empty-bobo-n3htmpye.fra.unikraft.app running 1 minute ago http-rust175-rocket05@sha256:23a7a6... 128 MiB /server 17412us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete http-rust175-rocket05-tuwq3 -``` - -```bash title="kraft" -kraft cloud instance remove http-rust175-rocket05-tuwq3 -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `src/main.rs`: the actual server -* `Cargo.toml`: the Cargo package manager configuration file -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - - - - ```yaml -spec: v0.6 - -runtime: base:latest - -rootfs: ./Dockerfile - -cmd: ["/server"] - ``` - - - ```rust -#[macro_use] extern crate rocket; - -#[cfg(test)] mod tests; - -#[derive(FromFormField)] -enum Lang { - #[field(value = "en")] - English, - #[field(value = "ru")] - #[field(value = "Ρ€Ρƒ")] - Russian -} - -#[derive(FromForm)] -struct Options<'r> { - emoji: bool, - name: Option<&'r str>, -} - -// Try visiting: -// http://127.0.0.1:8000/hello/world -#[get("/world")] -fn world() -> &'static str { - "Hello, world!" -} - -// Try visiting: -// http://127.0.0.1:8000/hello/ΠΌΠΈΡ€ -#[get("/ΠΌΠΈΡ€")] -fn mir() -> &'static str { - "ΠŸΡ€ΠΈΠ²Π΅Ρ‚, ΠΌΠΈΡ€!" -} - -// Try visiting: -// http://127.0.0.1:8000/wave/Rocketeer/100 -#[get("//")] -fn wave(name: &str, age: u8) -> String { - format!("πŸ‘‹ Hello, {} year old named {}!", age, name) -} - -// Note: without the `..` in `opt..`, we'd need to pass `opt.emoji`, `opt.name`. -// -// Try visiting: -// http://127.0.0.1:8000/?emoji -// http://127.0.0.1:8000/?name=Rocketeer -// http://127.0.0.1:8000/?lang=Ρ€Ρƒ -// http://127.0.0.1:8000/?lang=Ρ€Ρƒ&emoji -// http://127.0.0.1:8000/?emoji&lang=en -// http://127.0.0.1:8000/?name=Rocketeer&lang=en -// http://127.0.0.1:8000/?emoji&name=Rocketeer -// http://127.0.0.1:8000/?name=Rocketeer&lang=en&emoji -// http://127.0.0.1:8000/?lang=ru&emoji&name=Rocketeer -#[get("/?&")] -fn hello(lang: Option, opt: Options<'_>) -> String { - let mut greeting = String::new(); - if opt.emoji { - greeting.push_str("πŸ‘‹ "); - } - - match lang { - Some(Lang::Russian) => greeting.push_str("ΠŸΡ€ΠΈΠ²Π΅Ρ‚"), - Some(Lang::English) => greeting.push_str("Hello"), - None => greeting.push_str("Hi"), - } - - if let Some(name) = opt.name { - greeting.push_str(", "); - greeting.push_str(name); - } - - greeting.push('!'); - greeting -} - -#[launch] -fn rocket() -> _ { - rocket::build() - .mount("/", routes![hello]) - .mount("/hello", routes![world, mir]) - .mount("/wave", routes![wave]) -} - ``` - - - ```toml -[package] -name = "hello" -version = "0.0.0" -edition = "2021" -publish = false - -[dependencies] -rocket = "0.5.0" - ``` - - - ```dockerfile -FROM rust:1.75.0-bookworm AS build - -RUN cargo new --bin app -WORKDIR /app -COPY Cargo.toml ./ -COPY Rocket.toml ./ -COPY src ./src -RUN cargo build --release - -FROM scratch - -COPY ./Rocket.toml /Rocket.toml -COPY --from=build /app/target/release/hello /server -COPY --from=build /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/ -COPY --from=build /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/ -COPY --from=build /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib/x86_64-linux-gnu/ -COPY --from=build /lib64/ld-linux-x86-64.so.2 /lib64/ - ``` - - - -The following options are available for customizing the app: - -* If you only update the implementation in the `src/main.rs` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - If you add new Rust source code files, be sure to configure required dependencies in the `Cargo.toml` file. - -* If you build a new executable, update the `cmd` line in the `Kraftfile` and replace `/server` with the path to the new executable. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/rust-tokio.mdx b/pages/guides/rust-tokio.mdx deleted file mode 100644 index 5ef3221e..00000000 --- a/pages/guides/rust-tokio.mdx +++ /dev/null @@ -1,230 +0,0 @@ ---- -title: Rust (Tokio) ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This example uses [`Tokio`](https://tokio.rs/), a popular Rust asynchronous runtime. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/http-rust1.75-tokio/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/http-rust1.75-tokio/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/http-rust175-tokio:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB my-org/http-rust175-tokio:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: http-rust175-tokio-6gxsp - β”œ────────── uuid: d5719f64-0653-42d7-b2de-aa6dee0ce467 - β”œ───────── state: running - β”œ─────────── url: https://empty-dawn-3coedrce.fra.unikraft.app - β”œ───────── image: http-rust175-tokio@sha256:0ce75912711aa2329232a2ca6c3ccb7a244b6d546fafc081f815c2fde8224856 - β”œ───── boot time: 21.41 ms - β”œ──────── memory: 128 Mi - β”œ─────── service: empty-dawn-3coedrce - β”œ── private fqdn: http-rust175-tokio-6gxsp.internal - β”œ──── private ip: 172.16.6.3 - β””────────── args: /server -``` - -In this case, the instance name is `http-rust175-tokio-6gxsp` and the address is `https://empty-dawn-3coedrce.fra.unikraft.app. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the Tokio-based HTTP web server: - -```bash -curl https://empty-dawn-3coedrce.fra.unikraft.app -``` -```text -Hello, World! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -http-rust175-tokio-6gxsp empty-dawn-3coedrce.fra.unikraft.app running 1 minute ago http-rust175-tokio@sha256:0ce75912... 128 MiB /server 21412us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete http-rust175-tokio-6gxsp -``` - -```bash title="kraft" -kraft cloud instance remove http-rust175-tokio-6gxsp -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `src/main.rs`: the actual server -* `Cargo.toml`: the Cargo package manager configuration file -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - - - - ```yaml -spec: v0.6 - -runtime: base:latest - -rootfs: ./Dockerfile - -cmd: ["/server"] - ``` - - - ```rust -use std::net::SocketAddr; -use tokio::net::TcpListener; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; - -#[tokio::main] -async fn main() -> Result<(), Box> { - let addr = SocketAddr::from(([0, 0, 0, 0], 8080)); - let listener = TcpListener::bind(&addr).await?; - - println!("Listening on: http://{}", addr); - - loop { - let (mut stream, _) = listener.accept().await?; - - tokio::spawn(async move { - loop { - let mut buffer = [0; 1024]; - let _ = stream.read(&mut buffer).await; - - let contents = "Hello, World!\r\n"; - let content_length = contents.len(); - let response = format!("HTTP/1.1 200 OK\r\nContent-Length: {content_length}\r\n\r\n{contents}"); - let _ = stream.write_all(response.as_bytes()).await; - } - }); - } -} - ``` - - - ```toml -[package] -name = "http-tokio" -version = "0.1.0" -edition = "2021" - - -[dependencies] -tokio = {version = "1", features = ["rt-multi-thread", "net", "time", "macros", "io-util"] } - ``` - - - ```dockerfile -FROM rust:1.75.0-bookworm AS build - -WORKDIR /src - -COPY ./src /src/src -COPY ./Cargo.toml /src/Cargo.toml - -RUN cargo build - -FROM scratch - -COPY --from=build src/target/debug/http-tokio /server -COPY --from=build /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 -COPY --from=build /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/libm.so.6 -COPY --from=build /lib/x86_64-linux-gnu/libgcc_s.so.1 /lib/x86_64-linux-gnu/libgcc_s.so.1 -COPY --from=build /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 - ``` - - - -The following options are available for customizing the app: - -* If you only update the implementation in the `src/main.rs` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - If you add new Rust source code files, be sure to configure required dependencies in the `Cargo.toml` file. - -* If you build a new executable, update the `cmd` line in the `Kraftfile` and replace `/server` with the path to the new executable. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/skipper.mdx b/pages/guides/skipper.mdx deleted file mode 100644 index d3f02639..00000000 --- a/pages/guides/skipper.mdx +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: Skipper ---- - -This example uses [`Skipper`](https://opensource.zalando.com/skipper/), an HTTP router and reverse proxy for service composition - -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/skipper/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/skipper/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/skipper:latest -unikraft run --metro=fra -p 443:9090/http+tls -m 128MiB my-org/skipper:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:9090 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: skipper-mx4ai - β”œ────────── uuid: 34e3d740-c2b0-4644-b7e1-647350f688dc - β”œ───────── state: running - β”œ─────────── url: https://aged-sea-o7d3c42s.fra.unikraft.app - β”œ───────── image: skipper@sha256:5483eaf3612cca2116ceaab9be42557686324f1d30337ae15d0495eef63d0386 - β”œ───── boot time: 43.71 ms - β”œ──────── memory: 128 MiB - β”œ─────── service: aged-sea-o7d3c42s - β”œ── private fqdn: skipper-mx4ai.internal - β”œ──── private ip: 172.16.6.4 - β””────────── args: /usr/bin/skipper -address :9090 -routes-file /etc/skipper/example.eskip -``` - -In this case, the instance name is `skipper-mx4ai` and the address is `https://aged-sea-o7d3c42s.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of Skipper. - -```bash -curl https://aged-sea-o7d3c42s.fra.unikraft.app -``` -```text -Hello, world from Skipper on Unikraft! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -skipper-mx4ai aged-sea-o7d3c42s.fra.unikraft.app running 1 minute ago skipper@sha256:5483eaf... 128 MiB /usr/bin/skipper -address :9090 -routes-f... 43709us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete skipper-mx4ai -``` - -```bash title="kraft" -kraft cloud instance remove skipper-mx4ai -``` - - - -## Customize your app - -To customize Skipper you can change the `example.eskip` configuration file. - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/skipper0.18.mdx b/pages/guides/skipper0.18.mdx new file mode 100644 index 00000000..f2d3e11e --- /dev/null +++ b/pages/guides/skipper0.18.mdx @@ -0,0 +1,139 @@ +--- +title: "Skipper" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +This example uses [`Skipper`](https://opensource.zalando.com/skipper/), an HTTP router and reverse proxy for service composition + +To run this example, follow these steps: + +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/skipper0.18/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/skipper0.18/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /skipper0.18:latest +unikraft run --metro=fra -p 443:9090/tls+http -m 256M /skipper0.18:latest +``` + +```bash title="kraft" +kraft cloud deploy -p 443:9090/tls+http -M 256M . +``` + + + +The output shows the instance address and other details: + +```ansi +[●] Deployed successfully! + β”‚ + β”œ────────── name: skipper018-mx4ai + β”œ────────── uuid: 34e3d740-c2b0-4644-b7e1-647350f688dc + β”œ───────── state: running + β”œ─────────── url: https://aged-sea-o7d3c42s.fra.unikraft.app + β”œ───────── image: skipper018@sha256:5483eaf3612cca2116ceaab9be42557686324f1d30337ae15d0495eef63d0386 + β”œ───── boot time: 43.71 ms + β”œ──────── memory: 256 MiB + β”œ─────── service: aged-sea-o7d3c42s + β”œ── private fqdn: skipper018-mx4ai.internal + β”œ──── private ip: 172.16.6.4 + β””────────── args: /usr/bin/skipper -address :9090 -routes-file /etc/skipper/example.eskip +``` + +In this case, the instance name is `skipper018-mx4ai` and the address is `https://aged-sea-o7d3c42s.fra.unikraft.app`. +They're different for each run. + +Use `curl` to query the Unikraft Cloud instance of Skipper. + +```bash +curl https://aged-sea-o7d3c42s.fra.unikraft.app +``` + +```text +Hello, world from Skipper on Unikraft! +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +skipper018-mx4ai aged-sea-o7d3c42s.fra.unikraft.app running 1 minute ago skipper018@sha256:5483eaf... 256 MiB 1 /usr/bin/skipper -address :9090 -routes-f... 43709us +``` + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete skipper018-mx4ai +``` + +```bash title="kraft" +kraft cloud instance remove skipper018-mx4ai +``` + + + +## Customize your app + +To customize Skipper you can change the `example.eskip` configuration file. + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/solidjs.mdx b/pages/guides/solidjs.mdx deleted file mode 100644 index 0b0b2dc3..00000000 --- a/pages/guides/solidjs.mdx +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: SolidJS ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide shows how to deploy a [Solid Start](https://start.solidjs.com) app. -To do so, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/node21-solid-start/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/node21-solid-start/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy the app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/node21-solid-start:latest -unikraft run --metro=fra -p 443:3000/http+tls -m 256MiB my-org/node21-solid-start:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:3000 -M 256 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: node21-solid-start-lvoa2 - β”œ────────── uuid: 4e6ccb1f-0533-4dc1-be67-eca8dfc1f8c6 - β”œ───────── state: running - β”œ─────────── url: https://long-star-1tms9h1z.fra.unikraft.app - β”œ───────── image: node21-solid-start@sha256:eb2e79b2fc5c28bb43923a1fc4931db94ebc3f939a6fbe00d06189c0ae2e02fd - β”œ───── boot time: 67.65 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: long-star-1tms9h1z - β”œ── private fqdn: node21-solid-start-lvoa2.internal - β”œ──── private ip: 172.16.6.8 - β””────────── args: /usr/bin/node /usr/src/server/index.mjs -``` - -In this case, the instance name is `node21-solid-start-lvoa2` and the address is `https://long-star-1tms9h1z.fra.unikraft.app`. -They're different for each run. -You can now point your browser at the address to see your deployed instance. - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -node21-solid-start-lvoa2 long-star-1tms9h1z.fra.unikraft.app running 1 minutes ago node21-sol... 256 MiB /usr/bin/node /usr/src/server... 67.65 ms -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete node21-solid-start-lvoa2 -``` - -```bash title="kraft" -kraft cloud instance remove node21-solid-start-lvoa2 -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem -* `src/`: server source files - - - ```yaml - spec: v0.6 - - runtime: node:21 - - rootfs: ./Dockerfile - - cmd: ["/usr/bin/node", "/usr/src/server.js"] - ``` - - - ```dockerfile -FROM node:21-alpine AS build - -WORKDIR /usr/src - -COPY . /usr/src/ - -RUN set -xe && \ - npm instal -g pnpm && \ - pnpm install && \ - pnpm build - -FROM scratch - -COPY --from=build /usr/src/.output/ /usr/src/ - ``` - - - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/spin-wagi-http.mdx b/pages/guides/spin-wagi-http.mdx new file mode 100644 index 00000000..45457903 --- /dev/null +++ b/pages/guides/spin-wagi-http.mdx @@ -0,0 +1,171 @@ +--- +title: "Spin" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +This guide explains how to create and deploy a simple Spin HTTP app. +This guide comes from [Spin's `spin-wagi-http` example](https://github.com/fermyon/spin/tree/v2.1.0/examples/spin-wagi-http). +It shows how to run a Spin app serving routes from two programs written in different languages (Rust and C++). +Both the Spin executor and the Wagi executor on Unikraft Cloud. +To run it, follow these steps: + +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/spin-wagi-http/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/spin-wagi-http/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /spin-wagi-http:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 4G /spin-wagi-http:latest +``` + +```bash title="kraft" +kraft cloud deploy -p 443:3000/tls+http -M 4G . +``` + + + +The output shows the instance address and other details: + +```ansi +[●] Deployed successfully! + β”‚ + β”œ────────── name: spin-wagi-http-is72r + β”œ────────── uuid: 045c1bda-0f2e-4f8b-98c7-a208bfa7d143 + β”œ───────── state: running + β”œ─────────── url: https://damp-bobo-wg43p36e.fra.unikraft.app + β”œ───────── image: spin-wagi-http@sha256:57a5151996d83332af6da521e1cd92271a8c3ac7ae26bc44a7c0dbbc0a30e577 + β”œ───── boot time: 300.06 ms + β”œ──────── memory: 4096 MiB + β”œ─────── service: damp-bobo-wg43p36e + β”œ── private fqdn: spin-wagi-http-is72r.internal + β”œ──── private ip: 172.16.28.16 + β””────────── args: /usr/bin/spin up --from /app/spin.toml --listen 0.0.0.0:3000 +``` + +In this case, the instance name is `spin-wagi-http-is72r` and the address is `https://damp-bobo-wg43p36e.fra.unikraft.app`. +They're different for each run. + +Then `curl` the hello route: + +```bash +curl -i https://damp-bobo-wg43p36e.fra.unikraft.app/hello + +Hello, Fermyon! +``` + +And `curl` the goodbye route: + +```bash +curl -i https://damp-bobo-wg43p36e.fra.unikraft.app/goodbye + +Goodbye, Fermyon! +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +spin-wagi-http-is72r damp-bobo-wg43p36e.fra.unikraft.app running 1 minute ago spin-wagi-http@sha2... 4.0 GiB 1 /usr/bin/spin up --from /app/spin.tom... 300064us +``` + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete spin-wagi-http-is72r +``` + +```bash title="kraft" +kraft cloud instance remove spin-wagi-http-is72r +``` + + + +## Customize your app + +To customize the app, update the files in the repository, listed below: + +* `wagi-http-cpp`: C++ server handling the hello route +* `http-rust`: Rust server handling the goodbye route +* `Kraftfile`: the Unikraft Cloud specification +* `Dockerfile`: the Docker-specified app filesystem +* `spin.toml`: The Spin TOML configuration file + +Lines in the `Kraftfile` have the following roles: + +* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. + +* `runtime: spin:latest`: The Unikraft runtime kernel to use is Spin. + +* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. + +* `cmd: ["/usr/bin/spin", "up", "--from", "/app/spin.toml", "--listen", "0.0.0.0:3000"]`: Use `spin` as the command to start the app, with the given parameters. + +The following options are available for customizing the app: + +* If only updating the existing files under the `wagi-http-cpp` and `http-rust` directories, you don't need to make any other changes. + +* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. + +* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/spin.mdx b/pages/guides/spin.mdx deleted file mode 100644 index a91caef9..00000000 --- a/pages/guides/spin.mdx +++ /dev/null @@ -1,264 +0,0 @@ ---- -title: Spin ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a simple Spin HTTP app. -This guide comes from [Spin's `spin-wagi-http` example](https://github.com/fermyon/spin/tree/v2.1.0/examples/spin-wagi-http). -It shows how to run a Spin app serving routes from two programs written in different languages (Rust and C++). -Both the Spin executor and the Wagi executor on Unikraft Cloud. -To run it, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/spin-wagi-http/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/spin-wagi-http/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/spin-wagi-http:latest -unikraft run --metro=fra -p 443:3000/http+tls -m 2048MiB my-org/spin-wagi-http:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:3000 -M 2048 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: spin-wagi-http-is72r - β”œ────────── uuid: 045c1bda-0f2e-4f8b-98c7-a208bfa7d143 - β”œ───────── state: running - β”œ─────────── url: https://damp-bobo-wg43p36e.fra.unikraft.app - β”œ───────── image: spin-wagi-http@sha256:57a5151996d83332af6da521e1cd92271a8c3ac7ae26bc44a7c0dbbc0a30e577 - β”œ───── boot time: 300.06 ms - β”œ──────── memory: 2048 MiB - β”œ─────── service: damp-bobo-wg43p36e - β”œ── private fqdn: spin-wagi-http-is72r.internal - β”œ──── private ip: 172.16.28.16 - β””────────── args: /usr/bin/spin up --from /app/spin.toml --listen 0.0.0.0:3000 -``` - -In this case, the instance name is `spin-wagi-http-is72r` and the address is `https://damp-bobo-wg43p36e.fra.unikraft.app`. -They're different for each run. - -Then `curl` the hello route: - -```bash -curl -i https://damp-bobo-wg43p36e.fra.unikraft.app/hello - -Hello, Fermyon! -``` - -And `curl` the goodbye route: - -```bash -curl -i https://damp-bobo-wg43p36e.fra.unikraft.app/goodbye - -Goodbye, Fermyon! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -spin-wagi-http-is72r damp-bobo-wg43p36e.fra.unikraft.app running 1 minute ago spin-wagi-http@sha2... 2.0 GiB /usr/bin/spin up --from /app/spin.tom... 300064us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete spin-wagi-http-is72r -``` - -```bash title="kraft" -kraft cloud instance remove spin-wagi-http-is72r -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `wagi-http-cpp`: C++ server handling the hello route -* `http-rust`: Rust server handling the goodbye route -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem -* `spin.toml`: The Spin TOML configuration file - - - - ```yaml -spec: v0.6 - -runtime: spin:latest - -rootfs: ./Dockerfile - -cmd: ["/usr/bin/spin", "up", "--from", "/app/spin.toml", "--listen", "0.0.0.0:3000"] - ``` - - - ```dockerfile -FROM rust:1.75.0-bookworm AS spin - -ARG SPIN_VERSION=2.1.0 - -WORKDIR /spin - -RUN set -xe; \ - apt-get update; \ - apt-get install -y --no-install-recommends \ - ca-certificates \ - make \ - wget; - -RUN set -xe; \ - wget -q -O spin.tar.gz "https://github.com/fermyon/spin/releases/download/v${SPIN_VERSION}/spin-v${SPIN_VERSION}-linux-amd64.tar.gz"; \ - tar xzvf ./spin.tar.gz; \ - mv ./spin /usr/bin/spin; \ - rm -rf spin.tar.gz; \ - rustup target add wasm32-wasi - -ARG WASI_SDK_VERSION=21 - -WORKDIR /wasi - -RUN set -xe; \ - wget -q -O wasi-sdk.tar.gz "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-linux.tar.gz"; \ - mkdir -p /opt/wasi-sdk; \ - tar xzvf ./wasi-sdk.tar.gz --strip-components 1 -C /opt/wasi-sdk/; \ - rm -rf ./wasi-sdk.tar.gz; - -FROM spin AS build - -COPY ./http-rust /app/http-rust -WORKDIR /app/http-rust -RUN cargo build --release - -COPY ./wagi-http-cpp /app/wagi-http-cpp -WORKDIR /app/wagi-http-cpp -RUN make build - -FROM scratch - -COPY --from=build /app /app -COPY ./spin.toml /app/spin.toml - ``` - - - ```toml - spin_manifest_version = 2 - -[app] -description = "A hello world app that serves content from a C++ program and a Rust program" -name = "spin-wagi-hello" -version = "1.0.0" - -[[trigger.http]] -route = "/hello" -component = "hello" -executor = { type = "wagi" } # _start (the default entrypoint) is automatically mapped to main() - -[[trigger.http]] -route = "/goodbye" -component = "goodbye" -executor = { type = "http" } - -[component.hello] -source = "wagi-http-cpp/main.wasm" -[component.hello.build] -command = "make build -C wagi-http-cpp" - -[component.goodbye] -source = "http-rust/target/wasm32-wasi/release/goodbyerust.wasm" -[component.goodbye.build] -command = "cargo build --target wasm32-wasi --release --manifest-path http-rust/Cargo.toml" - ``` - - - -Lines in the `Kraftfile` have the following roles: - -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. - -* `runtime: spin:latest`: The Unikraft runtime kernel to use is Spin. - -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. - -* `cmd: ["/usr/bin/spin", "up", "--from", "/app/spin.toml", "--listen", "0.0.0.0:3000"]`: Use `spin` as the command to start the app, with the given parameters. - -The following options are available for customizing the app: - -* If only updating the existing files under the `wagi-http-cpp` and `http-rust` directories, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/springboot.mdx b/pages/guides/springboot.mdx deleted file mode 100644 index 1cb19ea7..00000000 --- a/pages/guides/springboot.mdx +++ /dev/null @@ -1,228 +0,0 @@ ---- -title: "Run a Spring Boot app" ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a Spring Boot web server. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/java17-springboot3.2.x/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/java17-springboot3.2.x/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/java17-springboot32x:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 1024MiB my-org/java17-springboot32x:latest -``` - -```bash title="kraft" -kraft cloud deploy -M 1024 -p 443:8080 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: java17-springboot32x-qseeo - β”œ────────── uuid: b081166d-a2a0-43af-982d-1aa17f06b5c4 - β”œ───────── state: running - β”œ─────────── url: https://long-dust-si7xsngk.fra.unikraft.app - β”œ───────── image: java17-springboot32x@sha256:cc2f2ad18ce8e36b8e8f4debee096fef7b0bb8b47762575a2ba5a9de8199c64a - β”œ───── boot time: 153.97 ms - β”œ──────── memory: 1024 MiB - β”œ─────── service: long-dust-si7xsngk - β”œ── private fqdn: java17-springboot32x-qseeo.internal - β”œ──── private ip: 172.16.6.2 - β””────────── args: /usr/lib/jvm/java-17-openjdk-amd64/bin/java -jar /usr/src/demo-0.0.1-SNAPSHOT.jar -``` - -In this case, the instance name is `java17-springboot32x-qseeo` and the address is `https://long-dust-si7xsngk.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Spring Boot server's `hello` endpoint: - -```bash -curl https://long-dust-si7xsngk.fra.unikraft.app/hello -``` -```text -Hello World! -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete java17-springboot32x-qseeo -``` - -```bash title="kraft" -kraft cloud instance remove java17-springboot32x-qseeo -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `DemoApplication.java`: the server -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - - - - ```java -package com.example.demo; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@SpringBootApplication -@RestController -public class DemoApplication { - public static void main(String[] args) { - SpringApplication.run(DemoApplication.class, args); - } - @GetMapping("/hello") - public String hello(@RequestParam(value = "name", defaultValue = "World") String name) { - return String.format("Hello %s!", name); - } -} - ``` - - - ```yaml -spec: v0.6 - -runtime: java:17 - -rootfs: ./Dockerfile - -cmd: ["/usr/lib/jvm/java-17-openjdk-amd64/bin/java", "-jar", "/usr/src/demo-0.0.1-SNAPSHOT.jar"] - ``` - - - ```dockerfile -FROM --platform=linux/x86_64 debian:bookworm AS build - -RUN set -xe ; \ - apt -yqq update ; \ - apt -yqq install default-jre default-jdk curl unzip ; - -RUN ldconfig /usr/lib/jvm/java-17-openjdk-amd64/lib/ - -WORKDIR /src - -RUN set -xe ; \ - curl -G https://start.spring.io/starter.zip \ - -d appName=DemoApplication \ - -d artifactId=demo \ - -d bootVersion=3.2.2 \ - -d dependencies=web \ - -d description=com.example \ - -d javaVersion=17 \ - -d language=java \ - -d name=demo \ - -d packageName=com.example.demo \ - -d packaging=jar \ - -d type=maven-project \ - -d version=0.0.1-SNAPSHOT \ - -o demo.zip ; \ - unzip demo.zip \ - ; - -COPY DemoApplication.java src/main/java/com/example/demo/ - -RUN set -xe ; \ - ./mvnw compile package install - -RUN set -xe ; \ - mkdir /tmpdir - -FROM scratch - -COPY --from=build /tmpdir /tmp -COPY --from=build /src/target/demo-0.0.1-SNAPSHOT.jar /usr/src/demo-0.0.1-SNAPSHOT.jar - ``` - - - -Lines in the `Kraftfile` have the following roles: - -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. - -* `runtime: java:17`: The Unikraft runtime kernel to use is Java. - -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. - -* `cmd: ["/usr/lib/jvm/java-17-openjdk-amd64/bin/java", "-jar", "/usr/src/demo-0.0.1-SNAPSHOT.jar"]`: Use as the starting command of the instance. - -Lines in the `Dockerfile` have the following roles: - -* `FROM scratch`: Build the filesystem from the [`scratch` container image](https://hub.docker.com/_/scratch/), to [create a base image](https://docs.docker.com/build/building/base-images/). - -* `COPY DemoApplication.java src/main/java/com/example/demo/`: Copy the server implementation file in the Docker filesystem. - - -The following options are available for customizing the app: - -* If you only update the implementation in the `DemoApplication.java` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/traefik.mdx b/pages/guides/traefik.mdx index ed6ceabd..b1d54826 100644 --- a/pages/guides/traefik.mdx +++ b/pages/guides/traefik.mdx @@ -1,25 +1,28 @@ --- -title: Traefik +title: "Traefik" --- + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + This example uses the [`Traefik`](https://traefik.io/traefik/) cloud native app proxy. To run this example, follow these steps: 1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/traefik/` directory: +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/traefik/` directory: ```bash -git clone https://github.com/kraftcloud/examples +git clone https://github.com/unikraft-cloud/examples cd examples/traefik/ ``` -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - + ```bash title="unikraft" unikraft login @@ -34,19 +37,17 @@ export UKC_METRO=fra -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - When done, invoke the following command to deploy this app on Unikraft Cloud: - + ```bash title="unikraft" -unikraft build . --output my-org/traefik:latest -unikraft run --metro=fra -p 443:80/http+tls -p 8080:8080/tls -m 512MiB my-org/traefik:latest +unikraft build . --output /traefik:latest +unikraft run --metro=fra -p 443:80/tls+http -p 8080:8080/tls -m 1G /traefik:latest ``` ```bash title="kraft" -kraft cloud deploy -M 512 -p 443:80/tls+http -p 8080:8080/tls . +kraft cloud deploy -p 443:80/tls+http -p 8080:8080/tls -M 1G . ``` @@ -56,17 +57,17 @@ The output shows the instance address and other details: ```ansi [●] Deployed successfully! β”‚ - β”œ────────── name: traefik-wqe7e - β”œ────────── uuid: 69d25b0b-1813-4a3f-88e6-64abbc78b359 - β”œ───────── state: running - β”œ─────────── url: https://holy-cherry-rye39b1x.fra.unikraft.app - β”œ───────── image: traefik@sha256:f6dd913a81f6a057ceb9db7844222d7287b2a83f668cca88c73c2e85554cb526 - β”œ───── boot time: 53.66 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: holy-cherry-rye39b1x - β”œ── private fqdn: traefik-wqe7e.internal - β”œ──── private ip: 172.16.28.16 - β””────────── args: /usr/bin/traefik -configFile /etc/traefik/default.toml + β”œ────────── name: traefik-wqe7e + β”œ────────── uuid: 69d25b0b-1813-4a3f-88e6-64abbc78b359 + β”œ───────── state: running + β”œ─────────── url: https://holy-cherry-rye39b1x.fra.unikraft.app + β”œ───────── image: traefik@sha256:f6dd913a81f6a057ceb9db7844222d7287b2a83f668cca88c73c2e85554cb526 + β”œ───── boot time: 53.66 ms + β”œ──────── memory: 1024 MiB + β”œ─────── service: holy-cherry-rye39b1x + β”œ── private fqdn: traefik-wqe7e.internal + β”œ──── private ip: 172.16.28.16 + β””────────── args: /usr/bin/traefik -configFile /etc/traefik/default.toml ``` In this case, the instance name is `traefik-wqe7e` and the address is `https://holy-cherry-rye39b1x.fra.unikraft.app`. @@ -77,20 +78,20 @@ Use `curl` to query the Unikraft Cloud instance of Traefik. ```bash curl https://holy-cherry-rye39b1x.fra.unikraft.app:8080/dashboard ``` + ```text Traefik ... ``` Or better yet, point a browser at the dashboard. -:::danger -This set up exposes the dashboard on port 8080 without authentication. -Please change default.toml as needed. -::: +> **Danger:** +> This set up exposes the dashboard on port 8080 without authentication. +> Please change default.toml as needed. You can list information about the instance by running: - + ```bash title="unikraft" unikraft instances list @@ -101,14 +102,15 @@ kraft cloud instance list ``` -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -traefik-wqe7e holy-cherry-rye39b1x.fra.unikraft.app running 8 minutes ago traefik@sha256:f6dd913a8... 512 MiB /usr/bin/traefik -configFile /etc/traefik/... 53661us + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +traefik-wqe7e holy-cherry-rye39b1x.fra.unikraft.app running 8 minutes ago traefik@sha256:f6dd913a8... 1024 MiB 1 /usr/bin/traefik -configFile /etc/traefik/... 53661us ``` When done, you can remove the instance: - + ```bash title="unikraft" unikraft instances delete traefik-wqe7e @@ -128,7 +130,7 @@ To customize Traefik app you can change the `default.toml` configuration file. Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help @@ -140,4 +142,4 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/tyk.mdx b/pages/guides/tyk.mdx deleted file mode 100644 index 8a678055..00000000 --- a/pages/guides/tyk.mdx +++ /dev/null @@ -1,218 +0,0 @@ ---- -title: Tyk ---- - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This example uses [`Tyk`](https://tyk.io/), an API gateway and management platform. -Tyk is used together with Redis to store API tokens and OAuth clients. - -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/tyk/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/tyk/ -``` - -Make sure to log into KraftCloud and pick a [metro](/docs/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set KraftCloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -When done, invoke the following command to deploy this app on KraftCloud. -Compose is only available in the legacy CLI: - - - -```bash title="kraft" -kraft cloud compose up -``` - - - -The output shows the [Compose](/docs/guides/features/compose) output: - -```text - i building service=tyk - i packaging service=tyk -[+] building rootfs... done! -[+] packaging index.unikraft.io/tyk-tyk... done! -[+] pushing index.unikraft.io/tyk-tyk:latest (kraftcloud/x86_64)... done! - i creating instance image=redis:latest - i no ports or service specified, disabling scale to zero - i creating instance image=index.unikraft.io/tyk-tyk@sha256:06f8ba3f2350e57717bd947f43f04a1ac44ab65010c8994488223eb042c30feb - i no ports or service specified, disabling scale to zero - i starting 2 instance(s) -``` - -To list information about the instances, use: - - - -```bash title="kraft" -kraft cloud compose ps -``` - - -```text -NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME -tyk-tyk funky-pond-45usfkxx.fra.unikraft.app running since 45secs tyk-tyk@sha256:06f8ba3... 128 MiB /usr/bin/tyk start --conf /etc/tyk.conf 38.12 ms -tyk-redis running since 45secs redis@sha256:d4604c6d80e7d57590f2c46659f2... 512 MiB /usr/bin/redis-server /etc/redis/redis.conf 18.69 ms -``` - -The Tyk and Redis instances are named `tyk-tyk` and `tyk-redis` (as defined in the `compose.yaml` file). -Only the Tyk instance is available as a public service. -Its address is `https://funky-pond-45usfkxx.fra.unikraft.app`. -It's different for each run. - -Use `curl` to query the Tyk instance on KraftCloud on the available address: - -```bash -curl https://funky-pond-45usfkxx.fra-test.unikraft.app/hello -``` -```text -{"status":"pass","version":"v5.3.0-dev","description":"Tyk GW","details":{"redis":{"status":"pass","componentType":"datastore","time":"2024-07-12T05:57:44Z"}}} -``` - -When done, you can bring down the instances: - - - -```bash title="kraft" -kraft cloud compose down -``` - - - -## Customize your app - -To customize the Tyk app, you can update: - -* `Kraftfile`: the KraftCloud specification -* `Dockerfile` / `rootfs/`: the Tyk filesystem (in this case the configuration file `/etc/tyk.conf`) -* `compose.yaml`: the Compose specification - - - - ```yaml - spec: v0.6 - - runtime: tyk:latest - - rootfs: ./Dockerfile - - cmd: ["/usr/bin/tyk", "start", "--conf", "/etc/tyk.conf"] - ``` - - - ```dockerfile - FROM scratch - - COPY ./rootfs / - ``` - - - ```text - { - "listen_address": "", - "listen_port": 8080, - "secret": "352d20ee67be67f6340b4c0605b044b7", - "template_path": "/tyk/templates", - "use_db_app_configs": false, - "app_path": "/opt/tyk-gateway/apps", - "middleware_path": "/opt/tyk-gateway/middleware", - "storage": { - "type": "redis", - "host": "tyk-redis.internal", - "port": 6379, - "username": "", - "password": "", - "database": 0, - "optimisation_max_idle": 2000, - "optimisation_max_active": 4000 - }, - "enable_analytics": false, - "analytics_config": { - "type": "", - "ignored_ips": [] - }, - "dns_cache": { - "enabled": false, - "ttl": 3600, - "check_interval": 60 - }, - "allow_master_keys": false, - "policies": { - "policy_source": "file" - }, - "hash_keys": true, - "hash_key_function": "murmur64", - "suppress_redis_signal_reload": false, - "force_global_session_lifetime": false, - "max_idle_connections_per_host": 500 - } - ``` - - - ```yaml - services: - - tyk: - build: . - ports: - - 443:8080 - - redis: - image: redis:latest - mem_reservation: 512M - networks: - tyk-network: - ``` - - - -It's unlikely you will have to update the `Kraftfile` specification. - -Update the contents of the `rootfs/etc/tyk.conf` file for a different configuration. - -You can also update the `Dockerfile` in order to extend the Tyk filesystem with extra data files or configuration files. - -The `compose.yaml` file can be update to assign different names, ports, network names or other [Compose](/docs/guides/features/compose)-specific configurations. - -## Learn more - -Use the `--help` option for detailed information on using KraftCloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). diff --git a/pages/guides/visual-studio-code-server.mdx b/pages/guides/visual-studio-code-server.mdx new file mode 100644 index 00000000..f8d60ca4 --- /dev/null +++ b/pages/guides/visual-studio-code-server.mdx @@ -0,0 +1,168 @@ +--- +title: "Visual Studio Code Server" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +[Visual Studio Code](https://code.visualstudio.com/) is a source-code editor developed by Microsoft. +It includes support for debugging, syntax highlighting, intelligent code completion, snippets, code refactoring, and embedded Git. +It features a [Code server](https://code.visualstudio.com/docs/remote/vscode-server), which allows you to run Visual Studio Code remotely and access it through a web browser or your local Visual Studio Code client. + +This guide explains how to create and deploy a Visual Studio Code server app. +To run this example, follow these steps: + +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/visual-studio-code-server` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/visual-studio-code-server/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft volume create --set metro=fra --set name=code-workspace --set size=1G + +unikraft build . --output /visual-studio-code-server:latest +unikraft run --metro=fra -p 443:8443/tls+http -m 2G --volume code-workspace:/workspace --scale-to-zero policy=on,cooldown-time=4000,stateful=true -e PGUID=0 -e PGID=0 -e PASSWORD=unikraft -e SUDO_PASSWORD=unikraft -e DEFAULT_WORKSPACE="/workspace" /visual-studio-code-server:latest +``` + +```bash title="kraft" +kraft cloud volume create --name code-workspace --size 1G + +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 4s --name code-server -p 443:8443/tls+http -M 2G -v code-workspace:/workspace -e PGUID=0 -e PGID=0 -e PASSWORD=unikraft -e SUDO_PASSWORD=unikraft -e DEFAULT_WORKSPACE="/workspace" . +``` + + + +The output shows the instance address and other details: + +```ansi +[●] Deployed successfully! + β”‚ + β”œ─────── name: code-server + β”œ─────── uuid: c1a619a0-e222-4042-94b8-ba4b39353417 + β”œ────── metro: https://api.fra.unikraft.cloud/v1 + β”œ────── state: starting + β”œ───── domain: https://blue-shape-chmxf1g4.fra.unikraft.app + β”œ────── image: visual-studio-code-server@sha256:633ec8a8dcb342b093c6f055f84fc056ee1abe40ff56e98bd612c4b9d4ddffcb + β”œ───── memory: 2048 MiB + β”œ──── service: blue-shape-chmxf1g4 + β”œ─ private ip: 10.0.0.49 + β””─────── args: /app/code-server/bin/code-server --host 0.0.0.0 --port 8443 --auth password +``` + +This will create a volume for data persistence, and mount it at `/workspace` inside the VM. + +In this case, the instance name is `code-server` and the address is `https://blue-shape-chmxf1g4.fra.unikraft.app`. +The name was preset, but the address is different for each run. +Enter the provided address into your browser of choice to access the Code server instance. + +You can list information about the volume by running: + + + +```bash title="unikraft" +unikraft volumes list +``` + +```bash title="kraft" +kraft cloud volume list +``` + + + +```ansi +NAME CREATED AT SIZE ATTACHED TO MOUNTED BY STATE PERSISTENT +code-workspace 13 minutes ago 1.0 GiB code-server code-server mounted true +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +code-server blue-shape-chmxf1g4.fra.unikraft.app standby standby visual-studio-code-server@sha256:633ec8a8dcb342b0... 2.0 GiB 1 /app/code-server/bin/code-server... 8.45 ms +``` + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete code-server +``` + +```bash title="kraft" +kraft cloud instance remove code-server +``` + + + +The volume isn't removed by default, so you can recreate the instance and still have access to your old data. +Remove it using: + + + +```bash title="unikraft" +unikraft volume delete code-workspace +``` + +```bash title="kraft" +kraft cloud volume remove code-workspace +``` + + + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/vsftpd.mdx b/pages/guides/vsftpd.mdx new file mode 100644 index 00000000..1e45c320 --- /dev/null +++ b/pages/guides/vsftpd.mdx @@ -0,0 +1,173 @@ +--- +title: "vsftpd" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +This guide explains how to create and deploy a [vsftpd](https://security.appspot.com/vsftpd.html) app, to secure access to the files of your VM. +To run this example, follow these steps: + +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/vsftpd` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/vsftpd/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft volume create --set metro=fra --set name=vsftpd-workspace --set size=1G + +unikraft build . --output /vsftpd:latest +unikraft run --metro=fra --scale-to-zero policy=on,cooldown-time=40000,stateful=true -p 20:20/tls -p 21:21/tls -p 222:22/tls -p 990:990/tls -p 10100:10100/tls -m 1G --volume vsftpd-workspace:/root /vsftpd:latest +``` + +```bash title="kraft" +kraft cloud volume create --name vsftpd-workspace --size 1G + +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 3s --name vsftpd -p 20:20/tls -p 21:21/tls -p 222:22/tls -p 990:990/tls -p 10100:10100/tls -M 1G -v vsftpd-workspace:/root . +``` + + + +The output shows the instance address and other details: + +```ansi +[●] Deployed successfully! + β”‚ + β”œ─────── name: vsftpd + β”œ─────── uuid: 186a46a0-7c89-4bfd-83a8-649bcc60a96e + β”œ────── metro: https://api.fra.unikraft.cloud/v1 + β”œ────── state: starting + β”œ───── domain: broken-orangutan-jypu2z53.fra.unikraft.app + β”œ────── image: vsftpd@sha256:31aad1619c31f499b11f1bef8fead6e6df76f235a57add011e5e414a3f51ee64 + β”œ───── memory: 1024 MiB + β”œ──── service: broken-orangutan-jypu2z53 + β”œ─ private ip: 10.0.0.109 + β””─────── args: /wrapper.sh +``` + +This will create a volume for data persistence, and mount it at `/root` inside the VM. + +In this case, the instance name is `vsftpd` and the address is `https://broken-orangutan-jypu2z53.fra.unikraft.app`. +The name was preset, but the address is different for each run. + +**Note**: The `root` password defaults to `rootpass`. +Don't forget to change it inside the `Dockerfile` and update the commands below. + +You can access the FTP server using a client like `lftp`: + +```bash +lftp -u root,rootpass ftps://broken-orangutan-jypu2z53.fra.unikraft.app:21 +lftp root@broken-orangutan-jypu2z53.fra.unikraft.app:~> ls +``` + +You can list information about the volume by running: + + + +```bash title="unikraft" +unikraft volumes list +``` + +```bash title="kraft" +kraft cloud volume list +``` + + + +```ansi +NAME CREATED AT SIZE ATTACHED TO MOUNTED BY STATE PERSISTENT +vsftpd-workspace 9 minutes ago 1.0 GiB vsftpd vsftpd mounted true +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +vsftpd broken-orangutan-jypu2z53.fra.unikraft.app standby standby vsftpd@sha256:3c448f1e1596a2f017871aa9a7... 1.0 GiB 1 /wrapper.sh 7.19 ms +``` + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete vsftpd +``` + +```bash title="kraft" +kraft cloud instance remove vsftpd +``` + + + +The volume isn't removed by default, so you can recreate the instance and still have access to your old data. +Remove it using: + + + +```bash title="unikraft" +unikraft volume delete vsftpd-workspace +``` + +```bash title="kraft" +kraft cloud volume remove vsftpd-workspace +``` + + + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/wazero.mdx b/pages/guides/wazero-import-go.mdx similarity index 53% rename from pages/guides/wazero.mdx rename to pages/guides/wazero-import-go.mdx index 33170504..693b1460 100644 --- a/pages/guides/wazero.mdx +++ b/pages/guides/wazero-import-go.mdx @@ -1,25 +1,28 @@ --- -title: Wazero +title: "Wazero" --- + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + This example comes from [Wazero's "import go" example](https://github.com/tetratelabs/wazero/tree/main/examples/import-go) and shows how to define, import and call a wasm blob from Go and run it on Unikraft Cloud. To run this it, follow these steps: 1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/wazero-import-go/` directory: +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/wazero-import-go/` directory: ```bash -git clone https://github.com/kraftcloud/examples +git clone https://github.com/unikraft-cloud/examples cd examples/wazero-import-go/ ``` -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - + ```bash title="unikraft" unikraft login @@ -34,19 +37,17 @@ export UKC_METRO=fra -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - When done, invoke the following command to deploy this app on Unikraft Cloud: - + ```bash title="unikraft" -unikraft build . --output my-org/wazero-import-go:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB my-org/wazero-import-go:latest /age-calculator 2000 +unikraft build . --output /wazero-import-go:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M /wazero-import-go:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080 . /age-calculator 2000 +kraft cloud deploy -p 443:8080/tls+http -M 512M . ``` @@ -56,17 +57,17 @@ The output shows the instance address and other details: ```ansi [●] Deployed successfully! β”‚ - β”œ────────── name: wazero-import-go-r4dx8 - β”œ────────── uuid: a763e1c3-bb38-475f-95b6-1e78d8ca74fc - β”œ───────── state: running - β”œ─────────── url: https://cool-morning-camrrhsa.fra.unikraft.app - β”œ───────── image: wazero-import-go@sha256:865700d358ffb2751888798ec8f302d23310b1fcf84f4d3f17f79fc25ff71153 - β”œ───── boot time: 20.04 m - β”œ──────── memory: 512 MiB - β”œ─────── service: cool-morning-camrrhsa - β”œ── private fqdn: wazero-import-go-r4dx8.internal - β”œ──── private ip: 172.16.6.7 - β””────────── args: /age-calculator 2000 + β”œ────────── name: wazero-import-go-r4dx8 + β”œ────────── uuid: a763e1c3-bb38-475f-95b6-1e78d8ca74fc + β”œ───────── state: running + β”œ─────────── url: https://cool-morning-camrrhsa.fra.unikraft.app + β”œ───────── image: wazero-import-go@sha256:865700d358ffb2751888798ec8f302d23310b1fcf84f4d3f17f79fc25ff71153 + β”œ───── boot time: 20.04 m + β”œ──────── memory: 512 MiB + β”œ─────── service: cool-morning-camrrhsa + β”œ── private fqdn: wazero-import-go-r4dx8.internal + β”œ──── private ip: 172.16.6.7 + β””────────── args: /age-calculator 2000 ``` In this case, the instance name is `wazero-import-go-r4dx8` and the address is `https://cool-morning-camrrhsa.fra.unikraft.app`. @@ -77,6 +78,7 @@ Use `curl` to query the Unikraft Cloud instance of the Go/wazero server: ```bash curl https://cool-morning-camrrhsa.fra.unikraft.app ``` + ```text println >> 24 log_i32 >> 24 @@ -84,7 +86,7 @@ log_i32 >> 24 You can list information about the instance by running: - + ```bash title="unikraft" unikraft instances list @@ -95,14 +97,15 @@ kraft cloud instance list ``` -```text -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -wazero-import-go-r4dx8 cool-morning-camrrhsa.fra.unikraft.app running 1 minutes ag wazero-import-go@s... 512 MiB /age-calculator 2000 20040us + +```ansi +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +wazero-import-go-r4dx8 cool-morning-camrrhsa.fra.unikraft.app running 1 minutes ag wazero-import-go@s... 512 MiB 1 /age-calculator 2000 20040us ``` When done, you can remove the instance: - + ```bash title="unikraft" unikraft instances delete wazero-import-go-r4dx8 @@ -114,7 +117,6 @@ kraft cloud instance remove wazero-import-go-r4dx8 - ## Background WebAssembly has neither a mechanism to get the current year, nor one to print to the console, so this example defines these in Go. @@ -125,7 +127,6 @@ This only uses the text format for demonstration purposes, to show you what's go It's likely, you will use another language to compile a Wasm (WebAssembly Module) binary, such as TinyGo. Regardless of how wasm produces, the export/import mechanics are the same! - ### Using WASI WebAssembly System Interface (WASI) is a modular system interface for WebAssembly. @@ -133,7 +134,6 @@ This uses an ad-hoc Go-defined function to print to the console. An emerging specification standardizes system calls (like Go's [x/sys](https://pkg.go.dev/golang.org/x/sys/unix)) called WebAssembly System Interface [(WASI)](https://github.com/WebAssembly/WASI). While this isn't yet a W3C standard, wazero includes a [wasi package](https://pkg.go.dev/github.com/tetratelabs/wazero/wasi). - ## Customize your app To customize the app, update the files in the repository, listed below: @@ -146,7 +146,7 @@ To customize the app, update the files in the repository, listed below: Use the `--help` option for detailed information on using Unikraft Cloud: - + ```bash title="unikraft" unikraft --help @@ -158,4 +158,4 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/wordpress-all-in-one.mdx b/pages/guides/wordpress-all-in-one.mdx new file mode 100644 index 00000000..55f09923 --- /dev/null +++ b/pages/guides/wordpress-all-in-one.mdx @@ -0,0 +1,95 @@ +--- +title: "Wordpress" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +This guide shows you how to use [Wordpress](https://wordpress.com/), a web content management system. + +To run it, follow these steps: + +1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/wordpress-all-in-one/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/wordpress-all-in-one/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /wordpress-all-in-one:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 4G /wordpress-all-in-one:latest +``` + +```bash title="kraft" +kraft cloud deploy -p 443:3000/tls+http -M 4G . +``` + + + + +The output shows the instance address and other details: + +```ansi +[●] Deployed successfully! + β”‚ + β”œ────────── name: wordpress-fx5rb + β”œ────────── uuid: bfb9d151-1604-452a-b2e0-f737486744df + β”œ───────── state: starting + β”œ──────── domain: https://cool-silence-h5c1es4z.fra.unikraft.app + β”œ───────── image: wordpress@sha256:3e116e6c74dd04e19d4062a14f8173974ba625179ace3c10a2c96546638c4cd8 + β”œ──────── memory: 4096 MiB + β”œ─────── service: cool-silence-h5c1es4z + β”œ── private fqdn: wordpress-fx5rb.internal + β”œ──── private ip: 172.16.3.1 + β””────────── args: /usr/local/bin/wrapper.sh +``` + +In this case, the instance name is `wordpress-fx5rb`. +They're different for each run. + +Use a browser to access the install page of Wordpress. +Fill out the form and complete the Wordpress install. + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). diff --git a/pages/guides/wordpress.mdx b/pages/guides/wordpress.mdx deleted file mode 100644 index 6787230b..00000000 --- a/pages/guides/wordpress.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: Wordpress ---- - -This guide shows you how to use [Wordpress](https://wordpress.com/), a web content management system. - -To run it, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/kraftcloud/examples) and `cd` into the `examples/wordpress-all-in-one/` directory: - -```bash -git clone https://github.com/kraftcloud/examples -cd examples/wordpress-all-in-one/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/metros#available) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. - -:::note -A Wordpress instance on Unikraft Cloud requires 3GB to run. -Request an increase in the instance memory quota when you need more memory. -::: - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output my-org/wordpress:latest -unikraft run --metro=fra -p 443:3000/http+tls -m 3072MiB my-org/wordpress:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:3000 -M 3072 . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: wordpress-fx5rb - β”œ────────── uuid: bfb9d151-1604-452a-b2e0-f737486744df - β”œ───────── state: starting - β”œ──────── domain: https://cool-silence-h5c1es4z.fra.unikraft.app - β”œ───────── image: wordpress@sha256:3e116e6c74dd04e19d4062a14f8173974ba625179ace3c10a2c96546638c4cd8 - β”œ──────── memory: 3072 MiB - β”œ─────── service: cool-silence-h5c1es4z - β”œ── private fqdn: wordpress-fx5rb.internal - β”œ──── private ip: 172.16.3.1 - β””────────── args: /usr/local/bin/wrapper.sh -``` - -In this case, the instance name is `wordpress-fx5rb`. -They're different for each run. - -Use a browser to access the install page of Wordpress. -Fill out the form and complete the Wordpress install. - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - - -```text -NAME FQDN STATE STATUS IMAGE MEMORY ARGS BOOT TIME -wordpress-fx5rb cool-silence-h5c1es4z.fra.unikraft.app running since 2mins wordpress@sha256:... 3.0 GiB /usr/local/bin/wrapper.sh 1708.17 ms -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete wordpress-fx5rb -``` - -```bash title="kraft" -kraft cloud instance remove wordpress-fx5rb -``` - - - -## Customize your deployment - -The current deployment uses the current stable version of Wordpress (6.5.5). -It also uses hard-coded values for the database name, user name, passwords. -You can update the `Dockerfile` with other names. -Or expand the configuration to feature non-hard-coded values. - -You can deploy WordPress modules in the WordPress instance without affecting the build. - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). From eb3649309849afce9d2a381fa10a163ec6594bb4 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Mon, 6 Apr 2026 13:16:39 +0300 Subject: [PATCH 088/131] feat(guides): Add overview page Signed-off-by: Alex-Andrei Cioc --- pages/guides/httpserver-elixir1.16.mdx | 2 +- pages/guides/httpserver-erlang26.2.mdx | 2 +- pages/guides/httpserver-rust1.91.mdx | 2 +- pages/guides/novnc-browser.mdx | 2 +- pages/guides/overview.mdx | 156 +++++++++++++++++++++++++ zudoku.config.tsx | 115 +++++++++--------- 6 files changed, 223 insertions(+), 56 deletions(-) create mode 100644 pages/guides/overview.mdx diff --git a/pages/guides/httpserver-elixir1.16.mdx b/pages/guides/httpserver-elixir1.16.mdx index af78136e..62d04bcd 100644 --- a/pages/guides/httpserver-elixir1.16.mdx +++ b/pages/guides/httpserver-elixir1.16.mdx @@ -118,7 +118,7 @@ kraft cloud instance remove httpserver-elixir116-qo9k3 To customize the app, update the files in the repository, listed below: -* `lib/`, `mix.esx`: the actual Elixir HTTP server implementation +* `lib/`, `mix.exs`: the actual Elixir HTTP server implementation * `Kraftfile`: the Unikraft Cloud specification * `Dockerfile`: the Docker-specified app filesystem diff --git a/pages/guides/httpserver-erlang26.2.mdx b/pages/guides/httpserver-erlang26.2.mdx index 8785ddb5..96d79379 100644 --- a/pages/guides/httpserver-erlang26.2.mdx +++ b/pages/guides/httpserver-erlang26.2.mdx @@ -97,7 +97,7 @@ kraft cloud instance list ```ansi NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-erlang26.2-sw2bp patient-field-ck629jsu.fra.unikraft.app running since 35secs httpserver-erlang26.2@sha256:4372... 512 MiB 1 /usr/bin/wrapper.sh /usr/bin/erl ... 404.04 ms +httpserver-erlang26.2-sw2bp patient-field-ck629j2u.fra.unikraft.app running since 35secs httpserver-erlang26.2@sha256:4372... 512 MiB 1 /usr/bin/wrapper.sh /usr/bin/erl ... 404.04 ms ``` When done, you can remove the instance: diff --git a/pages/guides/httpserver-rust1.91.mdx b/pages/guides/httpserver-rust1.91.mdx index 21175520..73d1aa03 100644 --- a/pages/guides/httpserver-rust1.91.mdx +++ b/pages/guides/httpserver-rust1.91.mdx @@ -74,7 +74,7 @@ They're different for each run. Use `curl` to query the Unikraft Cloud instance: ```bash -curl snowy-feather-k4pfgl8t.fra.unikraft.app +curl https://snowy-feather-k4pfgl8t.fra.unikraft.app ``` ```text diff --git a/pages/guides/novnc-browser.mdx b/pages/guides/novnc-browser.mdx index c631231f..b35bba14 100644 --- a/pages/guides/novnc-browser.mdx +++ b/pages/guides/novnc-browser.mdx @@ -46,7 +46,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /novnc-browser:latest -unikraft run --scale-to-zero policy=on,cooldown-time=40000,stateful=true --metro=fra -p 443:6080/tls+http -m 4G /novnc-browser:latest +unikraft run --scale-to-zero policy=on,cooldown-time=4000,stateful=true --metro=fra -p 443:6080/tls+http -m 4G /novnc-browser:latest ``` ```bash title="kraft" diff --git a/pages/guides/overview.mdx b/pages/guides/overview.mdx new file mode 100644 index 00000000..57c5550b --- /dev/null +++ b/pages/guides/overview.mdx @@ -0,0 +1,156 @@ +--- +title: "Guides Overview" +--- + +This page lists all available guides for deploying applications and services on Unikraft Cloud, grouped by category. +These guides mimic the [examples](https://github.com/unikraft-cloud/examples) repository, and are constantly updated with new content. + +{/* vale off */} + +## HTTP Servers + +Deploy HTTP servers written in your language of choice on Unikraft Cloud. + +### C / C++ + +- [C HTTP Server](/guides/httpserver-gcc13.2) +- [C++ HTTP Server](/guides/httpserver-g++13.2) +- [C++ Boost HTTP Server](/guides/httpserver-boost1.74-g++13.2) +- [SSH and HTTP Server with C and Debugging Tools](/guides/httpserver-c-debug) + +### .NET + +- [.NET HTTP Server](/guides/httpserver-dotnet10.0) + +### Elixir / Erlang + +- [Elixir HTTP Server](/guides/httpserver-elixir1.16) +- [Erlang HTTP Server](/guides/httpserver-erlang26.2) + +### Go + +- [Go HTTP Server](/guides/httpserver-go1.21) + +### Java + +- [Java HTTP Server](/guides/httpserver-java21) +- [Spring Boot HTTP Server](/guides/httpserver-java17-springboot3.2.x) + +### JavaScript / TypeScript + +- [Node HTTP Server](/guides/httpserver-node25) +- [Bun HTTP Server](/guides/httpserver-bun) +- [Express HTTP Server](/guides/httpserver-expressjs4.18-node21) +- [Puppeteer HTTP Server](/guides/httpserver-node-express-puppeteer) +- [Prisma HTTP Server](/guides/httpserver-prisma-expressjs4.19-node18) +- [Next.js HTTP Server](/guides/httpserver-node21-nextjs) +- [Remix HTTP Server](/guides/httpserver-node21-remix) +- [SolidJS HTTP Server](/guides/httpserver-node21-solid-start) +- [SvelteKit HTTP Server](/guides/httpserver-node21-sveltekit) +- [Vite HTTP Server](/guides/httpserver-nginx-vite-vanilla) + +### Lua + +- [Lua HTTP Server](/guides/httpserver-lua5.1) + +### Perl + +- [Perl HTTP Server](/guides/httpserver-perl5.42) + +### PHP + +- [PHP HTTP Server](/guides/httpserver-php8.2) + +### Python + +- [Python HTTP Server](/guides/httpserver-python3.12) +- [Django HTTP Server](/guides/httpserver-python3.12-django5.0) +- [FastAPI HTTP Server](/guides/httpserver-python3.12-FastAPI-0.121.3) +- [Flask HTTP Server](/guides/httpserver-python3.12-flask3.0) +- [Flask and SQLite HTTP Server](/guides/httpserver-python3.12-flask3.0-sqlite) + +### Ruby + +- [Ruby HTTP Server](/guides/httpserver-ruby3.2) + +### Rust + +- [Rust HTTP Server](/guides/httpserver-rust1.91) +- [Rust (Tokio) HTTP Server](/guides/httpserver-rust1.75-tokio) +- [Rust (Rocket) HTTP Server](/guides/httpserver-rust1.81-rocket0.5) +- [Rust (Actix Web) HTTP Server](/guides/httpserver-rust1.87-actix-web4) + +## Web Servers & Reverse Proxies + +Serve static content or route traffic with popular web server and proxy tools. + +- [Caddy](/guides/caddy2.7-go1.21) +- [HAProxy](/guides/haproxy) +- [Nginx](/guides/nginx) +- [Skipper](/guides/skipper0.18) +- [Traefik](/guides/traefik) + +## Databases & Caching + +Run databases and caching layers on Unikraft Cloud. + +- [DragonflyDB](/guides/dragonflydb) +- [DuckDB with Go](/guides/duckdb-go1.21) +- [MariaDB](/guides/mariadb) +- [Memcached](/guides/memcached1.6) +- [MongoDB](/guides/mongodb) +- [PostgreSQL](/guides/postgres) + +## Storage & Media + +Host object storage and image processing services. + +- [MinIO](/guides/minio) +- [Imaginary](/guides/imaginary) + +## WebAssembly Runtimes + +Run WebAssembly workloads on Unikraft Cloud. + +- [Spin (WAGI)](/guides/spin-wagi-http) +- [Wazero](/guides/wazero-import-go) + +## AI & MCP Servers + +Deploy Model Context Protocol (MCP) servers and AI-enabled services. + +- [Simple MCP Server](/guides/mcp-server-simple) +- [ArXiv MCP Server](/guides/mcp-server-arxiv) + +## Observability & Monitoring + +Collect metrics and visualise them with standard tools. + +- [Grafana](/guides/grafana) +- [OpenTelemetry Collector](/guides/opentelemetry-collector) + +## Developer Tools & Remote Access + +Access remote development environments and file transfer services. + +- [Visual Studio Code Server](/guides/visual-studio-code-server) +- [noVNC](/guides/novnc-browser) +- [Debian SSH Server](/guides/debian-ssh) +- [vsftpd](/guides/vsftpd) + +## Full-Stack Applications & CMS + +Deploy complete web applications and content management systems. + +- [WordPress](/guides/wordpress-all-in-one) +- [Ruby on Rails](/guides/ruby3.2-rails) +- [Hugo](/guides/hugo0.122) + +## Integration & Automation + +Examples for webhooks, background jobs, and creative applications. + +- [GitHub Webhook Receiver](/guides/github-webhook-node) +- [Node AllKaraoke](/guides/node24-karaoke) + +{/* vale on */} diff --git a/zudoku.config.tsx b/zudoku.config.tsx index 3e895498..7096d997 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -130,58 +130,69 @@ const config: ZudokuConfig = { label: "Guides", icon: "graduation-cap", items: [ - "/guides/overview", - "/guides/bun", - "/guides/caddy", - "/guides/cpp-boost", - "/guides/cpp", - "/guides/django", - "/guides/dotnet", - "/guides/dragonfly", - "/guides/duckdb", - "/guides/elixir", - "/guides/erlang", - "/guides/ferretdb", - "/guides/flask-sqlite", - "/guides/flask", - "/guides/go", - "/guides/grafana", - "/guides/haproxy", - "/guides/hugo", - "/guides/imaginary", - "/guides/java", - "/guides/llama2", - "/guides/lua", - "/guides/mariadb", - "/guides/memcached", - "/guides/minio", - "/guides/mongodb", - "/guides/nextjs", - "/guides/nginx", - "/guides/node", - "/guides/opentelemetry-collector", - "/guides/perl", - "/guides/php", - "/guides/postgres", - "/guides/prisma", - "/guides/puppeteer", - "/guides/python", - "/guides/rails", - "/guides/redis", - "/guides/remix", - "/guides/ruby", - "/guides/rust-rocket", - "/guides/rust-tokio", - "/guides/rust-actix", - "/guides/skipper", - "/guides/solidjs", - "/guides/spin", - "/guides/springboot", - "/guides/sveltekit", - "/guides/traefik", - "/guides/tyk", - "/guides/wazero", - "/guides/wordpress", + //TODO: Please keep this list sorted by titles, not filenames !! + "/guides/overview", // Guides Overview + "/guides/httpserver-dotnet10.0", // .NET HTTP Server + "/guides/mcp-server-arxiv", // ArXiv MCP Server + "/guides/httpserver-bun", // Bun HTTP Server + "/guides/httpserver-gcc13.2", // C HTTP Server + "/guides/httpserver-boost1.74-g++13.2", // C++ Boost HTTP Server + "/guides/httpserver-g++13.2", // C++ HTTP Server + "/guides/caddy2.7-go1.21", // Caddy + "/guides/debian-ssh", // Debian SSH server + "/guides/httpserver-python3.12-django5.0", // Django HTTP Server + "/guides/dragonflydb", // DragonflyDB + "/guides/duckdb-go1.21", // DuckDB with Go + "/guides/httpserver-elixir1.16", // Elixir HTTP Server + "/guides/httpserver-erlang26.2", // Erlang HTTP Server + "/guides/httpserver-expressjs4.18-node21", // Express HTTP Server + "/guides/httpserver-python3.12-FastAPI-0.121.3", // FastAPI HTTP Server + "/guides/httpserver-python3.12-flask3.0-sqlite", // Flask and SQLite HTTP Server + "/guides/httpserver-python3.12-flask3.0", // Flask HTTP Server + "/guides/github-webhook-node", // GitHub Webhook receiver + "/guides/httpserver-go1.21", // Go HTTP Server + "/guides/grafana", // Grafana + "/guides/haproxy", // HAProxy + "/guides/hugo0.122", // Hugo + "/guides/imaginary", // Imaginary + "/guides/httpserver-java21", // Java HTTP Server + "/guides/httpserver-lua5.1", // Lua HTTP Server + "/guides/mariadb", // MariaDB + "/guides/memcached1.6", // Memcached + "/guides/minio", // Minio + "/guides/mongodb", // MongoDB + "/guides/httpserver-node21-nextjs", // Next.js HTTP Server + "/guides/nginx", // Nginx + "/guides/node24-karaoke", // Node AllKaraoke + "/guides/httpserver-node25", // Node HTTP Server + "/guides/novnc-browser", // noVNC + "/guides/opentelemetry-collector", // OpenTelemetry Collector + "/guides/httpserver-perl5.42", // Perl HTTP Server + "/guides/httpserver-php8.2", // PHP HTTP Server + "/guides/postgres", // PostgreSQL + "/guides/httpserver-prisma-expressjs4.19-node18", // Prisma HTTP Server + "/guides/httpserver-node-express-puppeteer", // Puppeteer HTTP Server + "/guides/httpserver-python3.12", // Python HTTP Server + "/guides/httpserver-node21-remix", // Remix HTTP Server + "/guides/httpserver-ruby3.2", // Ruby HTTP Server + "/guides/ruby3.2-rails", // Ruby on Rails + "/guides/httpserver-rust1.87-actix-web4", // Rust (Actix Web) HTTP Server + "/guides/httpserver-rust1.81-rocket0.5", // Rust (Rocket) HTTP Server + "/guides/httpserver-rust1.75-tokio", // Rust (Tokio) HTTP Server + "/guides/httpserver-rust1.91", // Rust HTTP Server + "/guides/mcp-server-simple", // Simple MCP Server + "/guides/skipper0.18", // Skipper + "/guides/httpserver-node21-solid-start", // SolidJS HTTP Server + "/guides/spin-wagi-http", // Spin + "/guides/httpserver-java17-springboot3.2.x", // Spring Boot HTTP Server + "/guides/httpserver-c-debug", // SSH and HTTP Server with C and Debugging Tools + "/guides/httpserver-node21-sveltekit", // SvelteKit HTTP Server + "/guides/traefik", // Traefik + "/guides/visual-studio-code-server", // Visual Studio Code Server + "/guides/httpserver-nginx-vite-vanilla", // Vite HTTP Server + "/guides/vsftpd", // vsftpd + "/guides/wazero-import-go", // Wazero + "/guides/wordpress-all-in-one", // Wordpress ] }, { From b6c42ad33cf8fbd16e51042bd43d6c283dd968d4 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Mon, 6 Apr 2026 14:03:21 +0300 Subject: [PATCH 089/131] fix(guides): Fix kraft cli docs url Signed-off-by: Alex-Andrei Cioc --- pages/cli/registries.mdx | 2 +- pages/features/autoscale.mdx | 2 +- pages/features/load-balancing.mdx | 2 +- pages/features/roms.mdx | 2 +- pages/features/scale-to-zero.mdx | 2 +- pages/features/snapshots.mdx | 2 +- pages/guides/caddy2.7-go1.21.mdx | 2 +- pages/guides/debian-ssh.mdx | 2 +- pages/guides/dragonflydb.mdx | 2 +- pages/guides/duckdb-go1.21.mdx | 2 +- pages/guides/github-webhook-node.mdx | 2 +- pages/guides/grafana.mdx | 2 +- pages/guides/haproxy.mdx | 2 +- pages/guides/httpserver-boost1.74-g++13.2.mdx | 2 +- pages/guides/httpserver-bun.mdx | 2 +- pages/guides/httpserver-c-debug.mdx | 2 +- pages/guides/httpserver-dotnet10.0.mdx | 2 +- pages/guides/httpserver-elixir1.16.mdx | 2 +- pages/guides/httpserver-erlang26.2.mdx | 2 +- pages/guides/httpserver-expressjs4.18-node21.mdx | 2 +- pages/guides/httpserver-g++13.2.mdx | 2 +- pages/guides/httpserver-gcc13.2.mdx | 2 +- pages/guides/httpserver-go1.21.mdx | 2 +- pages/guides/httpserver-java17-springboot3.2.x.mdx | 2 +- pages/guides/httpserver-java21.mdx | 2 +- pages/guides/httpserver-lua5.1.mdx | 2 +- pages/guides/httpserver-nginx-vite-vanilla.mdx | 2 +- pages/guides/httpserver-node-express-puppeteer.mdx | 2 +- pages/guides/httpserver-node21-nextjs.mdx | 2 +- pages/guides/httpserver-node21-remix.mdx | 2 +- pages/guides/httpserver-node21-solid-start.mdx | 2 +- pages/guides/httpserver-node21-sveltekit.mdx | 2 +- pages/guides/httpserver-node25.mdx | 2 +- pages/guides/httpserver-perl5.42.mdx | 2 +- pages/guides/httpserver-php8.2.mdx | 2 +- pages/guides/httpserver-prisma-expressjs4.19-node18.mdx | 2 +- pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx | 2 +- pages/guides/httpserver-python3.12-django5.0.mdx | 2 +- pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx | 2 +- pages/guides/httpserver-python3.12-flask3.0.mdx | 2 +- pages/guides/httpserver-python3.12.mdx | 2 +- pages/guides/httpserver-ruby3.2.mdx | 2 +- pages/guides/httpserver-rust1.75-tokio.mdx | 2 +- pages/guides/httpserver-rust1.81-rocket0.5.mdx | 2 +- pages/guides/httpserver-rust1.87-actix-web4.mdx | 2 +- pages/guides/httpserver-rust1.91.mdx | 2 +- pages/guides/hugo0.122.mdx | 2 +- pages/guides/imaginary.mdx | 2 +- pages/guides/mariadb.mdx | 2 +- pages/guides/mcp-server-arxiv.mdx | 2 +- pages/guides/mcp-server-simple.mdx | 2 +- pages/guides/memcached1.6.mdx | 2 +- pages/guides/minio.mdx | 2 +- pages/guides/mongodb.mdx | 2 +- pages/guides/nginx.mdx | 2 +- pages/guides/node24-karaoke.mdx | 2 +- pages/guides/novnc-browser.mdx | 2 +- pages/guides/opentelemetry-collector.mdx | 2 +- pages/guides/postgres.mdx | 2 +- pages/guides/ruby3.2-rails.mdx | 2 +- pages/guides/skipper0.18.mdx | 2 +- pages/guides/spin-wagi-http.mdx | 2 +- pages/guides/traefik.mdx | 2 +- pages/guides/visual-studio-code-server.mdx | 2 +- pages/guides/vsftpd.mdx | 2 +- pages/guides/wazero-import-go.mdx | 2 +- pages/guides/wordpress-all-in-one.mdx | 2 +- pages/platform/certificates.mdx | 2 +- pages/platform/delete-locks.mdx | 2 +- pages/platform/domains.mdx | 2 +- pages/platform/images.mdx | 2 +- pages/platform/instances.mdx | 2 +- pages/platform/services.mdx | 2 +- pages/platform/troubleshooting.mdx | 4 ++-- pages/platform/volumes.mdx | 2 +- pages/tutorials/environment-variables.mdx | 2 +- pages/tutorials/instance-metrics.mdx | 2 +- pages/tutorials/network-communication.mdx | 2 +- pages/tutorials/rootfs-compression.mdx | 2 +- pages/tutorials/rootfs-formats.mdx | 2 +- pages/tutorials/rootfs-volumes-roms.mdx | 2 +- pages/tutorials/scale-to-zero-triggers.mdx | 2 +- pages/use-cases/api-gateways.mdx | 2 +- pages/use-cases/headless-browsers.mdx | 2 +- pages/use-cases/mcp-servers.mdx | 2 +- pages/use-cases/remote-ides.mdx | 2 +- pages/use-cases/serverless-databases.mdx | 2 +- pages/use-cases/webhooks.mdx | 2 +- 88 files changed, 89 insertions(+), 89 deletions(-) diff --git a/pages/cli/registries.mdx b/pages/cli/registries.mdx index 5e992d6f..4404d24f 100644 --- a/pages/cli/registries.mdx +++ b/pages/cli/registries.mdx @@ -223,5 +223,5 @@ When creating an instance directly from an existing image, reference it by tag o ## Learn more * [Images](/platform/images): build, package, and deploy workflow. -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1). diff --git a/pages/features/autoscale.mdx b/pages/features/autoscale.mdx index 61e7c886..3fd7cb15 100644 --- a/pages/features/autoscale.mdx +++ b/pages/features/autoscale.mdx @@ -336,5 +336,5 @@ The `idle` policy scales in (removes instances) when the service has been idle ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the section on [autoscale](/api/platform/v1/autoscale). diff --git a/pages/features/load-balancing.mdx b/pages/features/load-balancing.mdx index ff800106..a39913ce 100644 --- a/pages/features/load-balancing.mdx +++ b/pages/features/load-balancing.mdx @@ -180,5 +180,5 @@ This is because `i-3` now becomes the only instance with only 1 connection (assu ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the section on services. diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index 7f1f7c71..8c166dc0 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -431,7 +431,7 @@ kraft cloud instance rm test-http-python-rom1 test-http-python-rom2 ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the [instances API](/api/platform/v1/instances). * The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images and ROMs. * The [systemd `mount` man page](https://www.man7.org/linux/man-pages/man8/mount.8.html) for filesystem mount options relevant to manual mounting scenarios. diff --git a/pages/features/scale-to-zero.mdx b/pages/features/scale-to-zero.mdx index 9be21953..b8df2286 100644 --- a/pages/features/scale-to-zero.mdx +++ b/pages/features/scale-to-zero.mdx @@ -340,7 +340,7 @@ For more on autoscale please see the autoscale [guide](/features/autoscale). ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the [scale-to-zero schema](/api/platform/v1/~schemas#instance-scale-to-zero). diff --git a/pages/features/snapshots.mdx b/pages/features/snapshots.mdx index 37982db7..1e7256e8 100644 --- a/pages/features/snapshots.mdx +++ b/pages/features/snapshots.mdx @@ -64,5 +64,5 @@ It also eliminates long initialization times from heavyweight apps. ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), and in particular the [scale-to-zero schema](/api/platform/v1/~schemas#instance-scale-to-zero). diff --git a/pages/guides/caddy2.7-go1.21.mdx b/pages/guides/caddy2.7-go1.21.mdx index 00d4e8b5..3c611a56 100644 --- a/pages/guides/caddy2.7-go1.21.mdx +++ b/pages/guides/caddy2.7-go1.21.mdx @@ -163,4 +163,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/debian-ssh.mdx b/pages/guides/debian-ssh.mdx index 390e242d..16a26afd 100644 --- a/pages/guides/debian-ssh.mdx +++ b/pages/guides/debian-ssh.mdx @@ -136,4 +136,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). \ No newline at end of file +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). \ No newline at end of file diff --git a/pages/guides/dragonflydb.mdx b/pages/guides/dragonflydb.mdx index 0d3c1bc5..18680359 100644 --- a/pages/guides/dragonflydb.mdx +++ b/pages/guides/dragonflydb.mdx @@ -162,4 +162,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/duckdb-go1.21.mdx b/pages/guides/duckdb-go1.21.mdx index 6d7498a5..eb7053b6 100644 --- a/pages/guides/duckdb-go1.21.mdx +++ b/pages/guides/duckdb-go1.21.mdx @@ -152,4 +152,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/github-webhook-node.mdx b/pages/guides/github-webhook-node.mdx index cd309770..61f52f82 100644 --- a/pages/guides/github-webhook-node.mdx +++ b/pages/guides/github-webhook-node.mdx @@ -214,4 +214,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/grafana.mdx b/pages/guides/grafana.mdx index e7d2e0e9..fd494609 100644 --- a/pages/guides/grafana.mdx +++ b/pages/guides/grafana.mdx @@ -141,4 +141,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/haproxy.mdx b/pages/guides/haproxy.mdx index 98b6c0a6..0f4692be 100644 --- a/pages/guides/haproxy.mdx +++ b/pages/guides/haproxy.mdx @@ -132,4 +132,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-boost1.74-g++13.2.mdx b/pages/guides/httpserver-boost1.74-g++13.2.mdx index 203e2a14..d8d3a449 100644 --- a/pages/guides/httpserver-boost1.74-g++13.2.mdx +++ b/pages/guides/httpserver-boost1.74-g++13.2.mdx @@ -161,4 +161,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-bun.mdx b/pages/guides/httpserver-bun.mdx index a60f77a5..5fec6274 100644 --- a/pages/guides/httpserver-bun.mdx +++ b/pages/guides/httpserver-bun.mdx @@ -166,4 +166,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-c-debug.mdx b/pages/guides/httpserver-c-debug.mdx index 4f2986bd..95931711 100644 --- a/pages/guides/httpserver-c-debug.mdx +++ b/pages/guides/httpserver-c-debug.mdx @@ -147,4 +147,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-dotnet10.0.mdx b/pages/guides/httpserver-dotnet10.0.mdx index e472f502..94aab94c 100644 --- a/pages/guides/httpserver-dotnet10.0.mdx +++ b/pages/guides/httpserver-dotnet10.0.mdx @@ -172,4 +172,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-elixir1.16.mdx b/pages/guides/httpserver-elixir1.16.mdx index 62d04bcd..ef6d95d6 100644 --- a/pages/guides/httpserver-elixir1.16.mdx +++ b/pages/guides/httpserver-elixir1.16.mdx @@ -156,4 +156,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-erlang26.2.mdx b/pages/guides/httpserver-erlang26.2.mdx index 96d79379..e8e04212 100644 --- a/pages/guides/httpserver-erlang26.2.mdx +++ b/pages/guides/httpserver-erlang26.2.mdx @@ -146,4 +146,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-expressjs4.18-node21.mdx b/pages/guides/httpserver-expressjs4.18-node21.mdx index 58d67cf6..431bfcfa 100644 --- a/pages/guides/httpserver-expressjs4.18-node21.mdx +++ b/pages/guides/httpserver-expressjs4.18-node21.mdx @@ -172,4 +172,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-g++13.2.mdx b/pages/guides/httpserver-g++13.2.mdx index 02e5fdfa..e88b446d 100644 --- a/pages/guides/httpserver-g++13.2.mdx +++ b/pages/guides/httpserver-g++13.2.mdx @@ -163,4 +163,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-gcc13.2.mdx b/pages/guides/httpserver-gcc13.2.mdx index 9b253e04..d484d209 100644 --- a/pages/guides/httpserver-gcc13.2.mdx +++ b/pages/guides/httpserver-gcc13.2.mdx @@ -131,4 +131,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-go1.21.mdx b/pages/guides/httpserver-go1.21.mdx index 2c52d65e..147e351c 100644 --- a/pages/guides/httpserver-go1.21.mdx +++ b/pages/guides/httpserver-go1.21.mdx @@ -151,4 +151,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-java17-springboot3.2.x.mdx b/pages/guides/httpserver-java17-springboot3.2.x.mdx index 8ad0af92..12bae032 100644 --- a/pages/guides/httpserver-java17-springboot3.2.x.mdx +++ b/pages/guides/httpserver-java17-springboot3.2.x.mdx @@ -173,4 +173,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-java21.mdx b/pages/guides/httpserver-java21.mdx index 3b1093c1..d0c60975 100644 --- a/pages/guides/httpserver-java21.mdx +++ b/pages/guides/httpserver-java21.mdx @@ -176,4 +176,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-lua5.1.mdx b/pages/guides/httpserver-lua5.1.mdx index a15f0890..3bfa5455 100644 --- a/pages/guides/httpserver-lua5.1.mdx +++ b/pages/guides/httpserver-lua5.1.mdx @@ -147,4 +147,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-nginx-vite-vanilla.mdx b/pages/guides/httpserver-nginx-vite-vanilla.mdx index 9b0d6bbf..4f80775c 100644 --- a/pages/guides/httpserver-nginx-vite-vanilla.mdx +++ b/pages/guides/httpserver-nginx-vite-vanilla.mdx @@ -185,4 +185,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-node-express-puppeteer.mdx b/pages/guides/httpserver-node-express-puppeteer.mdx index 792000be..a3f95171 100644 --- a/pages/guides/httpserver-node-express-puppeteer.mdx +++ b/pages/guides/httpserver-node-express-puppeteer.mdx @@ -124,4 +124,4 @@ Use the `--help` option for detailed information on using Unikraft Cloud: kraft cloud --help ``` -Or visit the [CLI Reference](/cli/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-node21-nextjs.mdx b/pages/guides/httpserver-node21-nextjs.mdx index 37564477..3e3f7a2b 100644 --- a/pages/guides/httpserver-node21-nextjs.mdx +++ b/pages/guides/httpserver-node21-nextjs.mdx @@ -238,4 +238,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-node21-remix.mdx b/pages/guides/httpserver-node21-remix.mdx index 3d221509..abc5000d 100644 --- a/pages/guides/httpserver-node21-remix.mdx +++ b/pages/guides/httpserver-node21-remix.mdx @@ -131,4 +131,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-node21-solid-start.mdx b/pages/guides/httpserver-node21-solid-start.mdx index 6083a9bb..f4722b94 100644 --- a/pages/guides/httpserver-node21-solid-start.mdx +++ b/pages/guides/httpserver-node21-solid-start.mdx @@ -130,4 +130,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-node21-sveltekit.mdx b/pages/guides/httpserver-node21-sveltekit.mdx index d87023f8..f059da0a 100644 --- a/pages/guides/httpserver-node21-sveltekit.mdx +++ b/pages/guides/httpserver-node21-sveltekit.mdx @@ -233,4 +233,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-node25.mdx b/pages/guides/httpserver-node25.mdx index c10e977e..e3b67274 100644 --- a/pages/guides/httpserver-node25.mdx +++ b/pages/guides/httpserver-node25.mdx @@ -172,4 +172,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-perl5.42.mdx b/pages/guides/httpserver-perl5.42.mdx index 6e111399..98343654 100644 --- a/pages/guides/httpserver-perl5.42.mdx +++ b/pages/guides/httpserver-perl5.42.mdx @@ -169,4 +169,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-php8.2.mdx b/pages/guides/httpserver-php8.2.mdx index 01556435..7de82d85 100644 --- a/pages/guides/httpserver-php8.2.mdx +++ b/pages/guides/httpserver-php8.2.mdx @@ -149,4 +149,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx b/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx index ef07778a..fdecd7ff 100644 --- a/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx +++ b/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx @@ -369,4 +369,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx b/pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx index 785f3b00..c773f4d0 100644 --- a/pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx +++ b/pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx @@ -223,4 +223,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-python3.12-django5.0.mdx b/pages/guides/httpserver-python3.12-django5.0.mdx index ba8da326..2f1f6ee3 100644 --- a/pages/guides/httpserver-python3.12-django5.0.mdx +++ b/pages/guides/httpserver-python3.12-django5.0.mdx @@ -245,4 +245,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx b/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx index 821d0e42..045aa894 100644 --- a/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx +++ b/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx @@ -204,4 +204,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-python3.12-flask3.0.mdx b/pages/guides/httpserver-python3.12-flask3.0.mdx index 834ea5a0..862b6c0e 100644 --- a/pages/guides/httpserver-python3.12-flask3.0.mdx +++ b/pages/guides/httpserver-python3.12-flask3.0.mdx @@ -208,4 +208,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-python3.12.mdx b/pages/guides/httpserver-python3.12.mdx index 808c9b65..c36fd18d 100644 --- a/pages/guides/httpserver-python3.12.mdx +++ b/pages/guides/httpserver-python3.12.mdx @@ -226,4 +226,4 @@ kraft cloud --help
-Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-ruby3.2.mdx b/pages/guides/httpserver-ruby3.2.mdx index 88e87174..ba5d9e29 100644 --- a/pages/guides/httpserver-ruby3.2.mdx +++ b/pages/guides/httpserver-ruby3.2.mdx @@ -147,4 +147,4 @@ kraft cloud --help
-Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-rust1.75-tokio.mdx b/pages/guides/httpserver-rust1.75-tokio.mdx index a9af6700..4cbd02dd 100644 --- a/pages/guides/httpserver-rust1.75-tokio.mdx +++ b/pages/guides/httpserver-rust1.75-tokio.mdx @@ -151,4 +151,4 @@ kraft cloud --help
-Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-rust1.81-rocket0.5.mdx b/pages/guides/httpserver-rust1.81-rocket0.5.mdx index fb15d834..96ee2430 100644 --- a/pages/guides/httpserver-rust1.81-rocket0.5.mdx +++ b/pages/guides/httpserver-rust1.81-rocket0.5.mdx @@ -151,4 +151,4 @@ kraft cloud --help
-Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-rust1.87-actix-web4.mdx b/pages/guides/httpserver-rust1.87-actix-web4.mdx index 17cedead..fef2b827 100644 --- a/pages/guides/httpserver-rust1.87-actix-web4.mdx +++ b/pages/guides/httpserver-rust1.87-actix-web4.mdx @@ -153,4 +153,4 @@ kraft cloud --help
-Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-rust1.91.mdx b/pages/guides/httpserver-rust1.91.mdx index 73d1aa03..dbe60501 100644 --- a/pages/guides/httpserver-rust1.91.mdx +++ b/pages/guides/httpserver-rust1.91.mdx @@ -130,4 +130,4 @@ kraft cloud --help
-Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/hugo0.122.mdx b/pages/guides/hugo0.122.mdx index b6134eff..11e0497b 100644 --- a/pages/guides/hugo0.122.mdx +++ b/pages/guides/hugo0.122.mdx @@ -151,4 +151,4 @@ kraft cloud --help
-Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/imaginary.mdx b/pages/guides/imaginary.mdx index fb31f2ca..ec3ff413 100644 --- a/pages/guides/imaginary.mdx +++ b/pages/guides/imaginary.mdx @@ -163,4 +163,4 @@ kraft cloud --help
-Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/mariadb.mdx b/pages/guides/mariadb.mdx index 0e13e1bc..c3c1dba5 100644 --- a/pages/guides/mariadb.mdx +++ b/pages/guides/mariadb.mdx @@ -200,4 +200,4 @@ kraft cloud --help
-Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/mcp-server-arxiv.mdx b/pages/guides/mcp-server-arxiv.mdx index 4cd42073..45c4a39c 100644 --- a/pages/guides/mcp-server-arxiv.mdx +++ b/pages/guides/mcp-server-arxiv.mdx @@ -189,4 +189,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/mcp-server-simple.mdx b/pages/guides/mcp-server-simple.mdx index 82a15ba9..bbd526c2 100644 --- a/pages/guides/mcp-server-simple.mdx +++ b/pages/guides/mcp-server-simple.mdx @@ -219,4 +219,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/memcached1.6.mdx b/pages/guides/memcached1.6.mdx index 8c687550..01920762 100644 --- a/pages/guides/memcached1.6.mdx +++ b/pages/guides/memcached1.6.mdx @@ -161,4 +161,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/minio.mdx b/pages/guides/minio.mdx index 99e3a001..a006d44e 100644 --- a/pages/guides/minio.mdx +++ b/pages/guides/minio.mdx @@ -133,4 +133,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/mongodb.mdx b/pages/guides/mongodb.mdx index 70de92d5..c6219c04 100644 --- a/pages/guides/mongodb.mdx +++ b/pages/guides/mongodb.mdx @@ -167,4 +167,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/nginx.mdx b/pages/guides/nginx.mdx index f2a8b419..fc2e8bb7 100644 --- a/pages/guides/nginx.mdx +++ b/pages/guides/nginx.mdx @@ -167,4 +167,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/node24-karaoke.mdx b/pages/guides/node24-karaoke.mdx index 7e7e0cba..d8cd488e 100644 --- a/pages/guides/node24-karaoke.mdx +++ b/pages/guides/node24-karaoke.mdx @@ -184,4 +184,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/novnc-browser.mdx b/pages/guides/novnc-browser.mdx index b35bba14..5d6da0a8 100644 --- a/pages/guides/novnc-browser.mdx +++ b/pages/guides/novnc-browser.mdx @@ -142,4 +142,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/opentelemetry-collector.mdx b/pages/guides/opentelemetry-collector.mdx index e648ef69..6cf2b356 100644 --- a/pages/guides/opentelemetry-collector.mdx +++ b/pages/guides/opentelemetry-collector.mdx @@ -133,4 +133,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/postgres.mdx b/pages/guides/postgres.mdx index 022169cf..370d85b0 100644 --- a/pages/guides/postgres.mdx +++ b/pages/guides/postgres.mdx @@ -204,4 +204,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/ruby3.2-rails.mdx b/pages/guides/ruby3.2-rails.mdx index d9ac3c04..86039600 100644 --- a/pages/guides/ruby3.2-rails.mdx +++ b/pages/guides/ruby3.2-rails.mdx @@ -197,4 +197,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/skipper0.18.mdx b/pages/guides/skipper0.18.mdx index f2d3e11e..bfdb1dd2 100644 --- a/pages/guides/skipper0.18.mdx +++ b/pages/guides/skipper0.18.mdx @@ -136,4 +136,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/spin-wagi-http.mdx b/pages/guides/spin-wagi-http.mdx index 45457903..15b534aa 100644 --- a/pages/guides/spin-wagi-http.mdx +++ b/pages/guides/spin-wagi-http.mdx @@ -168,4 +168,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/traefik.mdx b/pages/guides/traefik.mdx index b1d54826..812b4357 100644 --- a/pages/guides/traefik.mdx +++ b/pages/guides/traefik.mdx @@ -142,4 +142,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/visual-studio-code-server.mdx b/pages/guides/visual-studio-code-server.mdx index f8d60ca4..ed59563b 100644 --- a/pages/guides/visual-studio-code-server.mdx +++ b/pages/guides/visual-studio-code-server.mdx @@ -165,4 +165,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/vsftpd.mdx b/pages/guides/vsftpd.mdx index 1e45c320..cd669028 100644 --- a/pages/guides/vsftpd.mdx +++ b/pages/guides/vsftpd.mdx @@ -170,4 +170,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/wazero-import-go.mdx b/pages/guides/wazero-import-go.mdx index 693b1460..a454da11 100644 --- a/pages/guides/wazero-import-go.mdx +++ b/pages/guides/wazero-import-go.mdx @@ -158,4 +158,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/wordpress-all-in-one.mdx b/pages/guides/wordpress-all-in-one.mdx index 55f09923..9a04e860 100644 --- a/pages/guides/wordpress-all-in-one.mdx +++ b/pages/guides/wordpress-all-in-one.mdx @@ -92,4 +92,4 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the legacy [CLI Reference](https://unikraft.org/docs/cli/kraft/overview). +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/platform/certificates.mdx b/pages/platform/certificates.mdx index df19793b..8ccf9393 100644 --- a/pages/platform/certificates.mdx +++ b/pages/platform/certificates.mdx @@ -98,6 +98,6 @@ kraft cloud cert rm mydomain.com-sa4x9 ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1). * Many more guides [here](/guides/bun). diff --git a/pages/platform/delete-locks.mdx b/pages/platform/delete-locks.mdx index 77feacbb..da8964ad 100644 --- a/pages/platform/delete-locks.mdx +++ b/pages/platform/delete-locks.mdx @@ -166,5 +166,5 @@ curl -X PATCH \ ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the sections on [instances](/api/platform/v1/instances) and [volumes](/api/platform/v1/volumes). diff --git a/pages/platform/domains.mdx b/pages/platform/domains.mdx index 5cc843a8..8884e954 100644 --- a/pages/platform/domains.mdx +++ b/pages/platform/domains.mdx @@ -135,5 +135,5 @@ curl https://mydomain.com ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the sections on [instances](/api/platform/v1/instances) and [service groups](/api/platform/v1/service-groups). diff --git a/pages/platform/images.mdx b/pages/platform/images.mdx index 0eb51c77..76b3f942 100644 --- a/pages/platform/images.mdx +++ b/pages/platform/images.mdx @@ -301,5 +301,5 @@ The response includes `url`, `tags`, `initrd_or_rom`, `size_in_bytes`, args` and ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1). diff --git a/pages/platform/instances.mdx b/pages/platform/instances.mdx index a5cac20f..c4fd097e 100644 --- a/pages/platform/instances.mdx +++ b/pages/platform/instances.mdx @@ -289,5 +289,5 @@ The logs capture the instance's `stdout` and `stderr` output, and they're preser ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [instances](/api/platform/v1/instances). diff --git a/pages/platform/services.mdx b/pages/platform/services.mdx index 2fb8b32f..16002155 100644 --- a/pages/platform/services.mdx +++ b/pages/platform/services.mdx @@ -267,5 +267,5 @@ The `GET /services/{name}` response includes a `persistent` field (`bool`) that ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [service groups](/api/platform/v1/service-groups). diff --git a/pages/platform/troubleshooting.mdx b/pages/platform/troubleshooting.mdx index 2ac871c0..223b32aa 100644 --- a/pages/platform/troubleshooting.mdx +++ b/pages/platform/troubleshooting.mdx @@ -413,13 +413,13 @@ kraft cloud deploy --restart on-failure . -Find more info in the [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +Find more info in the [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). ::: ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1). * Many more guides [here](/guides/bun). diff --git a/pages/platform/volumes.mdx b/pages/platform/volumes.mdx index d41f73b6..ce3e5da5 100644 --- a/pages/platform/volumes.mdx +++ b/pages/platform/volumes.mdx @@ -383,5 +383,5 @@ Create a managed volume with a `host_path` field instead of `size_mb`: ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * Unikraft Cloud's [REST API reference](/api/platform/v1), in particular the section on [volumes](/api/platform/v1/volumes). diff --git a/pages/tutorials/environment-variables.mdx b/pages/tutorials/environment-variables.mdx index cfb9eed3..9a5cab48 100644 --- a/pages/tutorials/environment-variables.mdx +++ b/pages/tutorials/environment-variables.mdx @@ -125,6 +125,6 @@ Consider that the `Dockerfile` and `Kraftfile` can set variables for the image i ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * The [Dockerfile reference](https://docs.docker.com/reference/dockerfile/) for understanding how to set environment variables in Dockerfiles. * The [Kraftfile reference](https://unikraft.org/docs/cli/reference/kraftfile) for understanding how to set environment variables in Kraftfiles. diff --git a/pages/tutorials/instance-metrics.mdx b/pages/tutorials/instance-metrics.mdx index 1c754b8f..454f4a50 100644 --- a/pages/tutorials/instance-metrics.mdx +++ b/pages/tutorials/instance-metrics.mdx @@ -409,4 +409,4 @@ The Prometheus format lets you plug these metrics directly into monitoring tools * [Scale to zero](/features/scale-to-zero) and how it affects instance lifecycle. * [Scale to zero triggers](/tutorials/scale-to-zero-triggers) for controlling when instances wake up. * [Platform instances](/platform/instances) for managing and inspecting your instances. -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). diff --git a/pages/tutorials/network-communication.mdx b/pages/tutorials/network-communication.mdx index 55fd3cd7..a4c28f67 100644 --- a/pages/tutorials/network-communication.mdx +++ b/pages/tutorials/network-communication.mdx @@ -52,4 +52,4 @@ By leveraging both types of communication, you can deploy a robust and efficient * [Load balancing](/features/load-balancing) of services. * [Platform services](/platform/services) and how they work. * [Scale to zero triggers](/tutorials/scale-to-zero-triggers) for automatic instance scaling. -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). diff --git a/pages/tutorials/rootfs-compression.mdx b/pages/tutorials/rootfs-compression.mdx index 011d5259..c008bb25 100644 --- a/pages/tutorials/rootfs-compression.mdx +++ b/pages/tutorials/rootfs-compression.mdx @@ -182,5 +182,5 @@ If limited by size constraints, try using compressed `EROFS` rootfses with a fas * The [rootfs formats tutorial](/tutorials/rootfs-formats) for understanding the differences between `CPIO` and `EROFS`. * The [`mkfs.erofs` documentation](https://man.archlinux.org/man/extra/erofs-utils/mkfs.erofs.1.en) for more information on creating compressed `EROFS` file systems. -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. diff --git a/pages/tutorials/rootfs-formats.mdx b/pages/tutorials/rootfs-formats.mdx index 9bbf4584..2b51ac47 100644 --- a/pages/tutorials/rootfs-formats.mdx +++ b/pages/tutorials/rootfs-formats.mdx @@ -132,5 +132,5 @@ Bottom-line is, using `EROFS` is recommended in every case where possible, as th ## Learn more -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. diff --git a/pages/tutorials/rootfs-volumes-roms.mdx b/pages/tutorials/rootfs-volumes-roms.mdx index 2e140e6c..e5609104 100644 --- a/pages/tutorials/rootfs-volumes-roms.mdx +++ b/pages/tutorials/rootfs-volumes-roms.mdx @@ -199,5 +199,5 @@ ROMs are a flexible way to customize rootfses, but you should also keep them sma * [Volumes](/platform/volumes) and how to use them. * [Rootfs formats](/tutorials/rootfs-formats) and how to create them. -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). * The `kraft pkg` [command reference](https://unikraft.org/docs/cli/reference/kraft/pkg) for packaging images. diff --git a/pages/tutorials/scale-to-zero-triggers.mdx b/pages/tutorials/scale-to-zero-triggers.mdx index d0a67e78..54d52632 100644 --- a/pages/tutorials/scale-to-zero-triggers.mdx +++ b/pages/tutorials/scale-to-zero-triggers.mdx @@ -140,4 +140,4 @@ Once your app is ready to serve requests, you can write '-' to the file to re-en ## Learn more * The [Scale To Zero](/features/scale-to-zero) feature page. -* The [CLI reference](/docs/cli/unikraft) and the legacy [CLI reference](/docs/cli/kraft/overview). +* The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). diff --git a/pages/use-cases/api-gateways.mdx b/pages/use-cases/api-gateways.mdx index 1bd54109..11a82edc 100644 --- a/pages/use-cases/api-gateways.mdx +++ b/pages/use-cases/api-gateways.mdx @@ -125,4 +125,4 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/docs/cli/unikraft) or the [legacy CLI reference](/docs/cli/kraft/overview). diff --git a/pages/use-cases/headless-browsers.mdx b/pages/use-cases/headless-browsers.mdx index bc9f5cd3..761c3229 100644 --- a/pages/use-cases/headless-browsers.mdx +++ b/pages/use-cases/headless-browsers.mdx @@ -183,4 +183,4 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/docs/cli/unikraft) or the [legacy CLI reference](/docs/cli/kraft/overview). diff --git a/pages/use-cases/mcp-servers.mdx b/pages/use-cases/mcp-servers.mdx index 7551b6ca..e4db862e 100644 --- a/pages/use-cases/mcp-servers.mdx +++ b/pages/use-cases/mcp-servers.mdx @@ -202,7 +202,7 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/docs/cli/unikraft) or the [legacy CLI reference](/docs/cli/kraft/overview). For more information about the Model Context Protocol: diff --git a/pages/use-cases/remote-ides.mdx b/pages/use-cases/remote-ides.mdx index d73592d6..9300ee91 100644 --- a/pages/use-cases/remote-ides.mdx +++ b/pages/use-cases/remote-ides.mdx @@ -147,4 +147,4 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/docs/cli/unikraft) or the [legacy CLI reference](/docs/cli/kraft/overview). diff --git a/pages/use-cases/serverless-databases.mdx b/pages/use-cases/serverless-databases.mdx index 90304070..fb4b6fd0 100644 --- a/pages/use-cases/serverless-databases.mdx +++ b/pages/use-cases/serverless-databases.mdx @@ -240,4 +240,4 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/docs/cli/unikraft) or the [legacy CLI reference](/docs/cli/kraft/overview). diff --git a/pages/use-cases/webhooks.mdx b/pages/use-cases/webhooks.mdx index 10cb7d6c..92234015 100644 --- a/pages/use-cases/webhooks.mdx +++ b/pages/use-cases/webhooks.mdx @@ -101,7 +101,7 @@ kraft cloud --help -Or visit the [CLI Reference](/docs/cli/unikraft) or the legacy [CLI Reference](/docs/cli/kraft/overview). +Or visit the [CLI Reference](/docs/cli/unikraft) or the [legacy CLI reference](/docs/cli/kraft/overview). For more information, check out these resources: From a80625f0a70334daf5a05c7063c525dca0555af1 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Mon, 6 Apr 2026 14:50:18 +0300 Subject: [PATCH 090/131] chore: Reorder zudoku pages Signed-off-by: Alex-Andrei Cioc --- zudoku.config.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/zudoku.config.tsx b/zudoku.config.tsx index 7096d997..cd4d7ce4 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -87,10 +87,10 @@ const config: ZudokuConfig = { items: [ "/use-cases/headless-browsers", "/use-cases/mcp-servers", - "/use-cases/serverless-databases", - "/use-cases/remote-ides", "/use-cases/api-gateways", + "/use-cases/serverless-databases", "/use-cases/webhooks", + "/use-cases/remote-ides", ], }, { @@ -101,16 +101,16 @@ const config: ZudokuConfig = { items: [ "/platform/metros", "/platform/instances", + "/platform/services", "/platform/domains", "/platform/certificates", - "/platform/services", "/platform/volumes", "/platform/images", - "/platform/troubleshooting", - "/platform/delete-locks", "/platform/quotas", "/platform/metrics", "/platform/tagging", + "/platform/delete-locks", + "/platform/troubleshooting", ], }, { @@ -200,13 +200,13 @@ const config: ZudokuConfig = { label: "Tutorials", icon: "book", items: [ - "/tutorials/environment-variables", "/tutorials/docker-to-ukc", - "/tutorials/instance-metrics", + "/tutorials/environment-variables", "/tutorials/rootfs-formats", "/tutorials/rootfs-compression", "/tutorials/rootfs-volumes-roms", "/tutorials/scale-to-zero-triggers", + "/tutorials/instance-metrics", "/tutorials/network-communication" ] }, From c2309872dc2b7aff539c782dee07966cb1f5e134 Mon Sep 17 00:00:00 2001 From: Alexander Jung Date: Wed, 15 Apr 2026 15:38:52 +0200 Subject: [PATCH 091/131] fix(introduction): Correct Deb/RPM installation instructions Signed-off-by: Alexander Jung --- pages/introduction.mdx | 43 ++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/pages/introduction.mdx b/pages/introduction.mdx index d1c70fdf..dd69f0dc 100644 --- a/pages/introduction.mdx +++ b/pages/introduction.mdx @@ -29,32 +29,35 @@ Expect higher server density, cost-savings, I/O performance boosts, active vCPU ``` ```bash title="Debian/Ubuntu" + # Update and install dependencies + sudo apt update + sudo apt install ca-certificates curl + + # Download and add the GPG key + sudo install -d -m 0755 /etc/apt/keyrings + + sudo curl -fsSL \ + -o /etc/apt/keyrings/unikraft-cli.gpg \ + https://pkg.unikraft.com/debian/cli-apt/keys/cli-apt.gpg + + sudo tee /etc/apt/sources.list.d/unikraft-cli.sources < /dev/null - - # Install unikraft CLI - sudo apt-get update - sudo apt-get install unikraft + sudo apt-get install unikraft-cli ``` ```bash title="Fedora/RHEL/Rocky/Alma" # Add the Unikraft CLI repository sudo tee /etc/yum.repos.d/unikraft-cli-rpm.repo < Date: Thu, 16 Apr 2026 09:57:29 +0100 Subject: [PATCH 092/131] chore: Update zudoku to v0.74.3 Signed-off-by: Justin Chadwell --- package-lock.json | 72 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3226c279..d0b5e2f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "react": ">=19.0.0", "react-dom": ">=19.0.0", "regex-utilities": "^2.3.0", - "zudoku": "^0.71.9" + "zudoku": "^0.74.3" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0", @@ -1284,9 +1284,9 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.11", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", - "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", + "version": "1.19.13", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.13.tgz", + "integrity": "sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ==", "license": "MIT", "engines": { "node": ">=18.14.1" @@ -5032,9 +5032,9 @@ } }, "node_modules/@tanem/react-nprogress": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@tanem/react-nprogress/-/react-nprogress-6.0.2.tgz", - "integrity": "sha512-SkBexef8gs8aquOMdyOFN/oSDsDUatDWDhH4R74KCjYc9ffsQJnReXVQKlbkyB9yv+B9MuG6+2g5YpvBNNQ7Vg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@tanem/react-nprogress/-/react-nprogress-6.0.3.tgz", + "integrity": "sha512-OT3KZiJv/zGI/lEwX3gD9nzNnyUQuSdSL0BK3OJIUC3Prx3JD18u13TZRvzasEXxHPGzm6AtBEr6gYxPeVWjWw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.28.6", @@ -5046,9 +5046,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.90.20", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz", - "integrity": "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==", + "version": "5.97.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.97.0.tgz", + "integrity": "sha512-QdpLP5VzVMgo4VtaPppRA2W04UFjIqX+bxke/ZJhE5cfd5UPkRzqIAJQt9uXkQJjqE8LBOMbKv7f8HCsZltXlg==", "license": "MIT", "funding": { "type": "github", @@ -5056,12 +5056,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.90.21", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz", - "integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==", + "version": "5.97.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.97.0.tgz", + "integrity": "sha512-y4So4eGcQoK2WVMAcDNZE9ofB/p5v1OlKvtc1F3uqHwrtifobT7q+ZnXk2mRkc8E84HKYSlAE9z6HXl2V0+ySQ==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.90.20" + "@tanstack/query-core": "5.97.0" }, "funding": { "type": "github", @@ -7605,9 +7605,9 @@ "license": "MIT" }, "node_modules/hono": { - "version": "4.12.5", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.5.tgz", - "integrity": "sha512-3qq+FUBtlTHhtYxbxheZgY8NIFnkkC/MR8u5TTsr7YZ3wixryQ3cCwn3iZbg8p8B88iDBBAYSfZDS75t8MN7Vg==", + "version": "4.12.12", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.12.tgz", + "integrity": "sha512-p1JfQMKaceuCbpJKAPKVqyqviZdS0eUxH9v82oWo1kb9xjQ5wA6iP3FNVAPDFlz5/p7d45lO+BpSk1tuSZMF4Q==", "license": "MIT", "engines": { "node": ">=16.9.0" @@ -11462,9 +11462,9 @@ } }, "node_modules/vite": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", - "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", + "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", "license": "MIT", "dependencies": { "esbuild": "^0.27.0", @@ -11612,9 +11612,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -11675,14 +11675,14 @@ } }, "node_modules/zudoku": { - "version": "0.71.10", - "resolved": "https://registry.npmjs.org/zudoku/-/zudoku-0.71.10.tgz", - "integrity": "sha512-mt0KwH7XhIJB9qFGSXa2SBQaeYVEsxChOfgZ3PNCo6gJEkQnSj185vfNVWCLYkVGochllxTbf274jxqUf6fRew==", + "version": "0.74.3", + "resolved": "https://registry.npmjs.org/zudoku/-/zudoku-0.74.3.tgz", + "integrity": "sha512-uhyOi9XvPboWl5YtTc0Kfg6JywmSK9WA0QrQCcldV5XyDguWnQ5IhuNuuQgXTISdCp0vKAEwwerdF7Xbjrkfrg==", "dependencies": { "@apidevtools/json-schema-ref-parser": "15.3.1", "@envelop/core": "5.5.1", "@graphql-typed-document-node/core": "3.2.0", - "@hono/node-server": "1.19.11", + "@hono/node-server": "1.19.13", "@lekoarts/rehype-meta-as-attributes": "3.0.3", "@mdx-js/react": "3.1.1", "@mdx-js/rollup": "3.1.1", @@ -11719,8 +11719,8 @@ "@shikijs/transformers": "3.23.0", "@tailwindcss/typography": "0.5.19", "@tailwindcss/vite": "4.2.1", - "@tanem/react-nprogress": "6.0.2", - "@tanstack/react-query": "5.90.21", + "@tanem/react-nprogress": "6.0.3", + "@tanstack/react-query": "5.97.0", "@types/react": "19.2.14", "@types/react-dom": "19.2.3", "@vitejs/plugin-react": "5.1.4", @@ -11747,7 +11747,7 @@ "hast-util-heading-rank": "3.0.0", "hast-util-to-jsx-runtime": "2.3.6", "hast-util-to-string": "3.0.1", - "hono": "4.12.5", + "hono": "4.12.12", "http-terminator": "3.2.0", "javascript-stringify": "2.1.0", "json-schema-to-typescript-lite": "15.0.0", @@ -11792,11 +11792,11 @@ "unist-util-visit": "5.1.0", "vaul": "1.1.2", "vfile": "6.0.3", - "vite": "7.3.1", - "yaml": "2.8.2", + "vite": "7.3.2", + "yaml": "2.8.3", "yargs": "18.0.0", "zod": "4.3.6", - "zustand": "5.0.11" + "zustand": "5.0.12" }, "bin": { "zudoku": "cli.js" @@ -11829,9 +11829,9 @@ } }, "node_modules/zustand": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.11.tgz", - "integrity": "sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.12.tgz", + "integrity": "sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==", "license": "MIT", "engines": { "node": ">=12.20.0" diff --git a/package.json b/package.json index 867d8302..99b62fcf 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "react": ">=19.0.0", "react-dom": ">=19.0.0", "regex-utilities": "^2.3.0", - "zudoku": "^0.71.9" + "zudoku": "^0.74.3" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0", From a6c90bfe5db8a65705b791eb1661ca1abe042108 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Thu, 16 Apr 2026 10:21:37 +0100 Subject: [PATCH 093/131] ci: Unpin kraftkit Signed-off-by: Justin Chadwell --- .github/actions/setup-kraftkit/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup-kraftkit/action.yaml b/.github/actions/setup-kraftkit/action.yaml index e23a1313..f4872f85 100644 --- a/.github/actions/setup-kraftkit/action.yaml +++ b/.github/actions/setup-kraftkit/action.yaml @@ -6,7 +6,7 @@ inputs: version: description: KraftKit version to install (use latest to auto-detect). required: false - default: 0.12.6 + default: latest runs: using: composite From 2af4b9afff6e4db64a9521b61fbacfb2950cc33a Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Mon, 20 Apr 2026 10:33:34 +0200 Subject: [PATCH 094/131] docs(features): Add inline ROMs to the ROMs page Document inline ROMs: providing file contents directly in the instance creation API instead of pre-packaging a ROM image. Covers API format, encoding options, combining with image-based ROMs, and platform limits. Signed-off-by: Jerome Jaggi --- pages/features/roms.mdx | 77 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index 8c166dc0..821478f7 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -373,6 +373,83 @@ Check that the instances are up: Note the `roms` array in the instances configurations. Each ROM is available as a readable device at `/dev/ukp_rom_python_function.py` (in the form of an EROFS filesystem in this case), which the server program mounts at `/tmp/rom.py` and executes. +## Inline ROMs + +Instead of pre-packaging and pushing a ROM image to a registry, you can provide file contents directly in the instance creation request. +This is useful when you create instances from a template where the snapshot locks ENV and ARGS, but you still need to inject instance-specific data. + +### API format + +Add a `files` array to a ROM entry instead of an `image` field: + +```json title="POST /instances" +{ + "image": "myuser/my-base:latest", + "roms": [ + { + "name": "my-rom", + "files": [ + { + "path": "config/settings.json", + "encoding": "text", + "data": "{\"debug\": false, \"port\": 8080}" + }, + { + "path": "certs/client.pem", + "encoding": "base64", + "data": "LS0tLS1CRUdJTi..." + } + ], + "at": "/roms/my-rom" + } + ] +} +``` + +Each file in the `files` array has three fields: + +| Field | Description | +|-------|-------------| +| `path` | File path inside the ROM filesystem. The platform creates directories automatically. | +| `encoding` | Either `text` (UTF-8 string) or `base64` (base64-encoded binary data). | +| `data` | The file contents in the specified encoding. | + +The platform packages the provided files into an EROFS filesystem and attaches it as a ROM device, the same way image-based ROMs work. +The `at` field is optional and works the same as for image-based ROMsβ€”when present, the platform mounts the ROM at the given path automatically. + +### Combining with image-based ROMs + +You can mix inline ROMs and image-based ROMs in the same request: + +```json title="POST /instances" +{ + "image": "myuser/my-base:latest", + "roms": [ + { + "name": "app-code", + "image": "myuser/my-rom:latest", + "at": "/app" + }, + { + "name": "instance-config", + "files": [ + { + "path": "config.json", + "encoding": "text", + "data": "{\"instance_id\": \"abc-123\"}" + } + ], + "at": "/config" + } + ] +} +``` + +### Limits + +The platform enforces limits on inline ROM size and file count. +Contact your administrator for the configured limits on your deployment. + ## Automounting Instead of mounting the ROM device manually inside the guest, you can set the optional `at` field on any ROM entry. From 92c1ffc9d7b32e292057d7a7231e727aa645009d Mon Sep 17 00:00:00 2001 From: Jerome Jaggi Date: Mon, 20 Apr 2026 11:09:10 +0200 Subject: [PATCH 095/131] docs(features): Add inline ROM limits table Add concrete limits: 8 ROMs per instance, 16 files per ROM, 1 MB total per ROM, 8 MB max request body. Signed-off-by: Jerome Jaggi --- pages/features/roms.mdx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index 821478f7..03879a97 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -447,8 +447,18 @@ You can mix inline ROMs and image-based ROMs in the same request: ### Limits -The platform enforces limits on inline ROM size and file count. -Contact your administrator for the configured limits on your deployment. +The platform enforces the following default limits on inline ROMs: + +| Limit | Default | +|-------|---------| +| ROMs per instance | 8 (inline and image-based combined) | +| Files per inline ROM | 16 | +| Total size per inline ROM | 1 MB (across all files) | +| Max API request body | 8 MB | + +No per-file size limit exists. +The total size limit applies to the combined size of all files in a single inline ROM. +Since inline ROM data is base64-encoded in the JSON request body, the 8 MB request body limit is the practical upper bound on total data per API call. ## Automounting From 048b8cd8aae88f785e66b877ec0c26eff7e9fa11 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Mon, 20 Apr 2026 13:02:24 +0300 Subject: [PATCH 096/131] fix(scripts): Group multiple code blocks into CodeTabs Signed-off-by: Alex-Andrei Cioc --- scripts/transform_readme.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/scripts/transform_readme.py b/scripts/transform_readme.py index 1fcf8b75..9841b8dd 100755 --- a/scripts/transform_readme.py +++ b/scripts/transform_readme.py @@ -123,39 +123,50 @@ def rewrite_urls(text: str) -> str: def convert_code_tabs(text: str) -> str: """Group adjacent code blocks containing title="..." inside a wrapper.""" block_pattern = re.compile(r"(```([^\n]*?title=\"([^\"]+)\"[^\n]*)\n.*?\n```)", flags=re.S) - + matches = list(block_pattern.finditer(text)) if not matches: return text - + groups = [] current_group = [matches[0]] - + for i in range(1, len(matches)): prev = current_group[-1] curr = matches[i] - + # Check if only whitespace or the word "or" exists between blocks between = text[prev.end():curr.start()].strip().lower() - if between in ["", "or"]: + + prev_info = prev.group(2).strip().lower() + curr_info = curr.group(2).strip().lower() + + # "or" between an ansi (output) block and a bash (command) block marks + # the boundary between two CLI alternatives (e.g. listing cmd+output for + # unikraft followed by cmd+output for kraft). Break the group here so + # each CLI's command+output pair ends up in its own . + if between == "or" and prev_info.startswith("ansi") and curr_info.startswith("bash"): + groups.append(current_group) + current_group = [curr] + elif between in ["", "or"]: current_group.append(curr) else: groups.append(current_group) current_group = [curr] groups.append(current_group) - + out = text for group in reversed(groups): if len(group) > 1: blocks = [m.group(1) for m in group] - + # Reconstruct the matched area with and syncKey tabs_str = '\n\n' + "\n\n".join(blocks) + "\n\n" - + start = group[0].start() end = group[-1].end() out = out[:start] + tabs_str + out[end:] - + return out From adadcce579c38aea88e89fc226eaf7e4babf495f Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Mon, 20 Apr 2026 13:18:11 +0300 Subject: [PATCH 097/131] feat(features): Add inline roms Signed-off-by: Alex-Andrei Cioc --- pages/features/roms.mdx | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/pages/features/roms.mdx b/pages/features/roms.mdx index 8c166dc0..3a121fe8 100644 --- a/pages/features/roms.mdx +++ b/pages/features/roms.mdx @@ -398,6 +398,45 @@ In this case you can simplify or remove the `wrapper.sh` from the base image, si The `at` field is optional--omitting it leaves the ROM as a raw block device at `/dev/ukp_rom_` and the guest remains responsible for mounting it. +## Inline ROMs + +Instead of referencing a pre-built image, you can supply file contents directly in the instance creation request using **inline ROMs**. +You specify an inline ROM by a `files` array instead of an `image` field. +Each entry in the array specifies the file `path` inside the ROM filesystem, the `encoding` of the provided data (`"base64"` or `"text"`), and the raw `data` string. + +```json title="POST /instances" +{ + "image": "...", + "roms": [ + { + "name": "my-rom", + "files": [ + { + "path": "test/file.txt", + "encoding": "base64", + "data": "VGhpcyBpcyBhIHRlc3QgZmlsZS4=" + }, + { + "path": "another-file.txt", + "encoding": "text", + "data": "This is another test file." + } + ], + "at": "/roms/my-rom" + } + ] +} +``` + +Inline ROMs are particularly useful when working with **instances created from templates**, where you can't change the environment variables and startup arguments of the original template. +By attaching an inline ROM you can inject configuration files, scripts, or other data into the instance at creation time without modifying the base image or the template. + +{/* vale off */} +:::note +An inline ROM is ephemeral: it's automatically deleted once the last reference to it is closed. +::: +{/* vale on */} + ### Testing Query the instances to call the Python function from the ROM. From b21d76de2e6b850306bdb9ce161ff73f0d824ac4 Mon Sep 17 00:00:00 2001 From: Alexander Jung Date: Fri, 10 Apr 2026 22:46:41 +0200 Subject: [PATCH 098/131] fix: Correct syntax for specifying image with `unikraft run` Signed-off-by: Alexander Jung --- pages/cli/overview.mdx | 2 +- pages/cli/registries.mdx | 12 ++++++------ pages/features/autoscale.mdx | 2 +- pages/features/load-balancing.mdx | 4 ++-- pages/features/scale-to-zero.mdx | 2 +- pages/guides/caddy2.7-go1.21.mdx | 2 +- pages/guides/debian-ssh.mdx | 2 +- pages/guides/dragonflydb.mdx | 2 +- pages/guides/duckdb-go1.21.mdx | 2 +- pages/guides/github-webhook-node.mdx | 2 +- pages/guides/grafana.mdx | 2 +- pages/guides/haproxy.mdx | 2 +- pages/guides/httpserver-boost1.74-g++13.2.mdx | 2 +- pages/guides/httpserver-bun.mdx | 2 +- pages/guides/httpserver-c-debug.mdx | 2 +- pages/guides/httpserver-dotnet10.0.mdx | 2 +- pages/guides/httpserver-elixir1.16.mdx | 2 +- pages/guides/httpserver-erlang26.2.mdx | 2 +- pages/guides/httpserver-expressjs4.18-node21.mdx | 2 +- pages/guides/httpserver-g++13.2.mdx | 2 +- pages/guides/httpserver-gcc13.2.mdx | 2 +- pages/guides/httpserver-go1.21.mdx | 2 +- pages/guides/httpserver-java17-springboot3.2.x.mdx | 2 +- pages/guides/httpserver-java21.mdx | 2 +- pages/guides/httpserver-lua5.1.mdx | 2 +- pages/guides/httpserver-nginx-vite-vanilla.mdx | 2 +- pages/guides/httpserver-node-express-puppeteer.mdx | 2 +- pages/guides/httpserver-node21-nextjs.mdx | 4 ++-- pages/guides/httpserver-node21-remix.mdx | 2 +- pages/guides/httpserver-node21-solid-start.mdx | 2 +- pages/guides/httpserver-node21-sveltekit.mdx | 2 +- pages/guides/httpserver-node25.mdx | 2 +- pages/guides/httpserver-perl5.42.mdx | 2 +- pages/guides/httpserver-php8.2.mdx | 2 +- .../httpserver-prisma-expressjs4.19-node18.mdx | 2 +- .../guides/httpserver-python3.12-FastAPI-0.121.3.mdx | 4 ++-- pages/guides/httpserver-python3.12-django5.0.mdx | 4 ++-- .../guides/httpserver-python3.12-flask3.0-sqlite.mdx | 2 +- pages/guides/httpserver-python3.12-flask3.0.mdx | 2 +- pages/guides/httpserver-python3.12.mdx | 4 ++-- pages/guides/httpserver-ruby3.2.mdx | 2 +- pages/guides/httpserver-rust1.75-tokio.mdx | 2 +- pages/guides/httpserver-rust1.81-rocket0.5.mdx | 2 +- pages/guides/httpserver-rust1.87-actix-web4.mdx | 2 +- pages/guides/httpserver-rust1.91.mdx | 2 +- pages/guides/hugo0.122.mdx | 2 +- pages/guides/imaginary.mdx | 2 +- pages/guides/mariadb.mdx | 4 ++-- pages/guides/mcp-server-arxiv.mdx | 4 ++-- pages/guides/mcp-server-simple.mdx | 2 +- pages/guides/memcached1.6.mdx | 2 +- pages/guides/minio.mdx | 2 +- pages/guides/mongodb.mdx | 2 +- pages/guides/nginx.mdx | 2 +- pages/guides/node24-karaoke.mdx | 2 +- pages/guides/novnc-browser.mdx | 2 +- pages/guides/opentelemetry-collector.mdx | 2 +- pages/guides/postgres.mdx | 4 ++-- pages/guides/ruby3.2-rails.mdx | 2 +- pages/guides/skipper0.18.mdx | 2 +- pages/guides/spin-wagi-http.mdx | 2 +- pages/guides/traefik.mdx | 2 +- pages/guides/visual-studio-code-server.mdx | 2 +- pages/guides/vsftpd.mdx | 2 +- pages/guides/wazero-import-go.mdx | 2 +- pages/guides/wordpress-all-in-one.mdx | 2 +- pages/introduction.mdx | 2 +- pages/platform/domains.mdx | 2 +- pages/platform/images.mdx | 6 +++--- pages/platform/metros.mdx | 2 +- pages/platform/services.mdx | 2 +- pages/platform/troubleshooting.mdx | 4 ++-- pages/platform/volumes.mdx | 4 ++-- pages/tutorials/docker-to-ukc.mdx | 8 ++++---- pages/tutorials/environment-variables.mdx | 2 +- pages/tutorials/instance-metrics.mdx | 2 +- pages/tutorials/rootfs-volumes-roms.mdx | 2 +- pages/use-cases/headless-browsers.mdx | 2 +- pages/use-cases/serverless-databases.mdx | 4 ++-- 79 files changed, 100 insertions(+), 100 deletions(-) diff --git a/pages/cli/overview.mdx b/pages/cli/overview.mdx index 9eecac58..37a49618 100644 --- a/pages/cli/overview.mdx +++ b/pages/cli/overview.mdx @@ -27,7 +27,7 @@ It provides a modern, streamlined experience for deploying and managing unikerne unikraft login # Deploy an instance -unikraft run --metro=fra -p 443:8080/http+tls nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls --image=nginx:latest # List instances unikraft instances list diff --git a/pages/cli/registries.mdx b/pages/cli/registries.mdx index 4404d24f..d18df6fc 100644 --- a/pages/cli/registries.mdx +++ b/pages/cli/registries.mdx @@ -83,11 +83,11 @@ The simplest way to push an image is to use the CLI to build, package, push, and ```bash title="central registry" unikraft build . --output index.unikraft.io//:latest - unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --name index.unikraft.io//:latest + unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --name --image=index.unikraft.io//:latest ``` ```bash title="local registry" unikraft build . --output index..unikraft.cloud//:latest - unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --name index..unikraft.cloud//:latest + unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --name --image=index..unikraft.cloud//:latest ``` @@ -201,21 +201,21 @@ When creating an instance directly from an existing image, reference it by tag o ```bash title="central registry" # By tag unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB \ - index.unikraft.io/alice/my-app:latest + --image=index.unikraft.io/alice/my-app:latest # By digest (exact version pinning) unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB \ - index.unikraft.io/alice/my-app@sha256:278cb8b1... + --image=index.unikraft.io/alice/my-app@sha256:278cb8b1... ``` ```bash title="local registry" # By tag unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB \ - index..unikraft.cloud/alice/my-app:latest + --image=index..unikraft.cloud/alice/my-app:latest # By digest (exact version pinning) unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB \ - index..unikraft.cloud/alice/my-app@sha256:278cb8b1... + --image=index..unikraft.cloud/alice/my-app@sha256:278cb8b1... ``` diff --git a/pages/features/autoscale.mdx b/pages/features/autoscale.mdx index 3fd7cb15..3effb5ed 100644 --- a/pages/features/autoscale.mdx +++ b/pages/features/autoscale.mdx @@ -41,7 +41,7 @@ First, create an instance, in this example using NGINX: ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ -unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --image=nginx:latest ``` ```bash title="kraft" diff --git a/pages/features/load-balancing.mdx b/pages/features/load-balancing.mdx index a39913ce..110a758f 100644 --- a/pages/features/load-balancing.mdx +++ b/pages/features/load-balancing.mdx @@ -41,7 +41,7 @@ For example, use NGINX as the app: git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ unikraft build . --output /nginx:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB /nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --image=/nginx:latest ``` ```bash title="kraft" @@ -76,7 +76,7 @@ With this in place, it's now time to start a second instance and attach it to th ```bash title="unikraft" cd examples/nginx/ -unikraft run --metro=fra --service wandering-shape-n6mhimgn -m 256MiB /nginx:latest +unikraft run --metro=fra --service wandering-shape-n6mhimgn -m 256MiB --image=/nginx:latest ``` ```bash title="kraft" diff --git a/pages/features/scale-to-zero.mdx b/pages/features/scale-to-zero.mdx index b8df2286..3632cbcc 100644 --- a/pages/features/scale-to-zero.mdx +++ b/pages/features/scale-to-zero.mdx @@ -217,7 +217,7 @@ Since Unikraft Cloud has scale-to-zero on by default, all you need to do is to s git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ unikraft build . --output /nginx:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB /nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 128MiB --image=/nginx:latest ``` ```bash title="kraft" diff --git a/pages/guides/caddy2.7-go1.21.mdx b/pages/guides/caddy2.7-go1.21.mdx index 3c611a56..919a71b5 100644 --- a/pages/guides/caddy2.7-go1.21.mdx +++ b/pages/guides/caddy2.7-go1.21.mdx @@ -44,7 +44,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /caddy27-go121:latest -unikraft run --metro=fra -p 443:2015/http+tls -m 256M /caddy27-go121:latest +unikraft run --metro=fra -p 443:2015/http+tls -m 256M --image=/caddy27-go121:latest ``` ```bash title="kraft" diff --git a/pages/guides/debian-ssh.mdx b/pages/guides/debian-ssh.mdx index 16a26afd..65a774be 100644 --- a/pages/guides/debian-ssh.mdx +++ b/pages/guides/debian-ssh.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /debian-ssh:latest -unikraft run --metro=fra -p 2222:2222/tls -m 1G -e PUBKEY="...." /debian-ssh:latest +unikraft run --metro=fra -p 2222:2222/tls -m 1G -e PUBKEY="...." --image=/debian-ssh:latest ``` ```bash title="kraft" diff --git a/pages/guides/dragonflydb.mdx b/pages/guides/dragonflydb.mdx index 18680359..5b26e998 100644 --- a/pages/guides/dragonflydb.mdx +++ b/pages/guides/dragonflydb.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /dragonflydb:latest -unikraft run --metro=fra -p 443:6379/http+tls -m 512M /dragonflydb:latest +unikraft run --metro=fra -p 443:6379/http+tls -m 512M --image=/dragonflydb:latest ``` ```bash title="kraft" diff --git a/pages/guides/duckdb-go1.21.mdx b/pages/guides/duckdb-go1.21.mdx index eb7053b6..d045e6ba 100644 --- a/pages/guides/duckdb-go1.21.mdx +++ b/pages/guides/duckdb-go1.21.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /duckdb-go1.21:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /duckdb-go1.21:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/duckdb-go1.21:latest ``` ```bash title="kraft" diff --git a/pages/guides/github-webhook-node.mdx b/pages/guides/github-webhook-node.mdx index 61f52f82..fd3259b5 100644 --- a/pages/guides/github-webhook-node.mdx +++ b/pages/guides/github-webhook-node.mdx @@ -44,7 +44,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /github-webhook-node:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 1G -e GITHUB_WEBHOOK_SECRET=your_secret_here /github-webhook-node:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 1G -e GITHUB_WEBHOOK_SECRET=your_secret_here --image=/github-webhook-node:latest ``` ```bash title="kraft" diff --git a/pages/guides/grafana.mdx b/pages/guides/grafana.mdx index fd494609..329a7bfb 100644 --- a/pages/guides/grafana.mdx +++ b/pages/guides/grafana.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /grafana:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 2G /grafana:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 2G --image=/grafana:latest ``` ```bash title="kraft" diff --git a/pages/guides/haproxy.mdx b/pages/guides/haproxy.mdx index 0f4692be..aeb5c6b0 100644 --- a/pages/guides/haproxy.mdx +++ b/pages/guides/haproxy.mdx @@ -44,7 +44,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /haproxy:latest -unikraft run --metro=fra -p 443:8404/tls+http -m 256M /haproxy:latest +unikraft run --metro=fra -p 443:8404/tls+http -m 256M --image=/haproxy:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-boost1.74-g++13.2.mdx b/pages/guides/httpserver-boost1.74-g++13.2.mdx index d8d3a449..6752aac5 100644 --- a/pages/guides/httpserver-boost1.74-g++13.2.mdx +++ b/pages/guides/httpserver-boost1.74-g++13.2.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-boost1.74-g++13.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /httpserver-boost1.74-g++13.2:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-boost1.74-g++13.2:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-bun.mdx b/pages/guides/httpserver-bun.mdx index 5fec6274..9ddc478b 100644 --- a/pages/guides/httpserver-bun.mdx +++ b/pages/guides/httpserver-bun.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-bun:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 512M /httpserver-bun:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 512M --image=/httpserver-bun:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-c-debug.mdx b/pages/guides/httpserver-c-debug.mdx index 95931711..8895fb2e 100644 --- a/pages/guides/httpserver-c-debug.mdx +++ b/pages/guides/httpserver-c-debug.mdx @@ -42,7 +42,7 @@ For extensive debug information with `strace`, add the `USE_STRACE=1` environmen ```bash title="unikraft" unikraft build . --output /httpserver-c-debug:latest -unikraft run --metro=fra -p 443:8080/tls+http -p 2222:2222/tls -e PUBKEY=.... -e USE_STRACE=1 -m 256M /httpserver-c-debug:latest +unikraft run --metro=fra -p 443:8080/tls+http -p 2222:2222/tls -e PUBKEY=.... -e USE_STRACE=1 -m 256M --image=/httpserver-c-debug:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-dotnet10.0.mdx b/pages/guides/httpserver-dotnet10.0.mdx index 94aab94c..77a0713b 100644 --- a/pages/guides/httpserver-dotnet10.0.mdx +++ b/pages/guides/httpserver-dotnet10.0.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-dotnet10.0:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /httpserver-dotnet10.0:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-dotnet10.0:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-elixir1.16.mdx b/pages/guides/httpserver-elixir1.16.mdx index ef6d95d6..e8417b7d 100644 --- a/pages/guides/httpserver-elixir1.16.mdx +++ b/pages/guides/httpserver-elixir1.16.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-elixir1.16:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 1G /httpserver-elixir1.16:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 1G --image=/httpserver-elixir1.16:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-erlang26.2.mdx b/pages/guides/httpserver-erlang26.2.mdx index e8e04212..b0b3944b 100644 --- a/pages/guides/httpserver-erlang26.2.mdx +++ b/pages/guides/httpserver-erlang26.2.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-erlang26.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /httpserver-erlang26.2:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-erlang26.2:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-expressjs4.18-node21.mdx b/pages/guides/httpserver-expressjs4.18-node21.mdx index 431bfcfa..6e06d070 100644 --- a/pages/guides/httpserver-expressjs4.18-node21.mdx +++ b/pages/guides/httpserver-expressjs4.18-node21.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-expressjs4.18-node21:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 512M /httpserver-expressjs4.18-node21:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 512M --image=/httpserver-expressjs4.18-node21:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-g++13.2.mdx b/pages/guides/httpserver-g++13.2.mdx index e88b446d..0958d3d3 100644 --- a/pages/guides/httpserver-g++13.2.mdx +++ b/pages/guides/httpserver-g++13.2.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-g++13.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /httpserver-g++13.2:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-g++13.2:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-gcc13.2.mdx b/pages/guides/httpserver-gcc13.2.mdx index d484d209..d4dde2d2 100644 --- a/pages/guides/httpserver-gcc13.2.mdx +++ b/pages/guides/httpserver-gcc13.2.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-gcc13.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /httpserver-gcc13.2:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-gcc13.2:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-go1.21.mdx b/pages/guides/httpserver-go1.21.mdx index 147e351c..8789313b 100644 --- a/pages/guides/httpserver-go1.21.mdx +++ b/pages/guides/httpserver-go1.21.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-go1.21:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /httpserver-go1.21:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-go1.21:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-java17-springboot3.2.x.mdx b/pages/guides/httpserver-java17-springboot3.2.x.mdx index 12bae032..683438ac 100644 --- a/pages/guides/httpserver-java17-springboot3.2.x.mdx +++ b/pages/guides/httpserver-java17-springboot3.2.x.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-java17-springboot3.2.x:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 1G /httpserver-java17-springboot3.2.x:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 1G --image=/httpserver-java17-springboot3.2.x:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-java21.mdx b/pages/guides/httpserver-java21.mdx index d0c60975..a88b7cd3 100644 --- a/pages/guides/httpserver-java21.mdx +++ b/pages/guides/httpserver-java21.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-java21:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 1G /httpserver-java21:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 1G --image=/httpserver-java21:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-lua5.1.mdx b/pages/guides/httpserver-lua5.1.mdx index 3bfa5455..3ebb4bd8 100644 --- a/pages/guides/httpserver-lua5.1.mdx +++ b/pages/guides/httpserver-lua5.1.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-lua5.1:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /httpserver-lua5.1:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-lua5.1:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-nginx-vite-vanilla.mdx b/pages/guides/httpserver-nginx-vite-vanilla.mdx index 4f80775c..2bcc4a15 100644 --- a/pages/guides/httpserver-nginx-vite-vanilla.mdx +++ b/pages/guides/httpserver-nginx-vite-vanilla.mdx @@ -45,7 +45,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-nginx-vite-vanilla:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /httpserver-nginx-vite-vanilla:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-nginx-vite-vanilla:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-node-express-puppeteer.mdx b/pages/guides/httpserver-node-express-puppeteer.mdx index a3f95171..af18cbc4 100644 --- a/pages/guides/httpserver-node-express-puppeteer.mdx +++ b/pages/guides/httpserver-node-express-puppeteer.mdx @@ -50,7 +50,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node-express-puppeteer:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 4G /httpserver-node-express-puppeteer:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 4G --image=/httpserver-node-express-puppeteer:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-node21-nextjs.mdx b/pages/guides/httpserver-node21-nextjs.mdx index 3e3f7a2b..6dcfefa0 100644 --- a/pages/guides/httpserver-node21-nextjs.mdx +++ b/pages/guides/httpserver-node21-nextjs.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node21-nextjs:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 768M /httpserver-node21-nextjs:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 768M --image=/httpserver-node21-nextjs:latest ``` ```bash title="kraft" @@ -169,7 +169,7 @@ Run the command below to deploy the app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-expressjs4.18-node21:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 256M /httpserver-expressjs4.18-node21:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 256M --image=/httpserver-expressjs4.18-node21:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-node21-remix.mdx b/pages/guides/httpserver-node21-remix.mdx index abc5000d..e0a144c3 100644 --- a/pages/guides/httpserver-node21-remix.mdx +++ b/pages/guides/httpserver-node21-remix.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node21-remix:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 768M /httpserver-node21-remix:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 768M --image=/httpserver-node21-remix:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-node21-solid-start.mdx b/pages/guides/httpserver-node21-solid-start.mdx index f4722b94..519daa9e 100644 --- a/pages/guides/httpserver-node21-solid-start.mdx +++ b/pages/guides/httpserver-node21-solid-start.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node21-solid-start:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 512M /httpserver-node21-solid-start:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 512M --image=/httpserver-node21-solid-start:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-node21-sveltekit.mdx b/pages/guides/httpserver-node21-sveltekit.mdx index f059da0a..22698185 100644 --- a/pages/guides/httpserver-node21-sveltekit.mdx +++ b/pages/guides/httpserver-node21-sveltekit.mdx @@ -44,7 +44,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node21-sveltekit:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 256M /httpserver-node21-sveltekit:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 256M --image=/httpserver-node21-sveltekit:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-node25.mdx b/pages/guides/httpserver-node25.mdx index e3b67274..6f87953b 100644 --- a/pages/guides/httpserver-node25.mdx +++ b/pages/guides/httpserver-node25.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node25:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /httpserver-node25:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-node25:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-perl5.42.mdx b/pages/guides/httpserver-perl5.42.mdx index 98343654..dfbd7a72 100644 --- a/pages/guides/httpserver-perl5.42.mdx +++ b/pages/guides/httpserver-perl5.42.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-perl5.42:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /httpserver-perl5.42:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-perl5.42:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-php8.2.mdx b/pages/guides/httpserver-php8.2.mdx index 7de82d85..cda7258c 100644 --- a/pages/guides/httpserver-php8.2.mdx +++ b/pages/guides/httpserver-php8.2.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-php8.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /httpserver-php8.2:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-php8.2:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx b/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx index fdecd7ff..6fa0bcce 100644 --- a/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx +++ b/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-prisma-expressjs4.19-node18:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 512M /httpserver-prisma-expressjs4.19-node18:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 512M --image=/httpserver-prisma-expressjs4.19-node18:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx b/pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx index c773f4d0..59557e9c 100644 --- a/pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx +++ b/pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-python3.12-FastAPI-0.121.3:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /httpserver-python3.12-FastAPI-0.121.3:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-python3.12-FastAPI-0.121.3:latest ``` ```bash title="kraft" @@ -159,7 +159,7 @@ Run the command below to deploy the app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-python3.12-FastAPI-0.121.3:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /httpserver-python3.12-FastAPI-0.121.3:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-python3.12-FastAPI-0.121.3:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-python3.12-django5.0.mdx b/pages/guides/httpserver-python3.12-django5.0.mdx index 2f1f6ee3..ea0c7cd8 100644 --- a/pages/guides/httpserver-python3.12-django5.0.mdx +++ b/pages/guides/httpserver-python3.12-django5.0.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-python3.12-django5.0:latest -unikraft run --metro=fra -p 443:80/tls+http -m 1G /httpserver-python3.12-django5.0:latest +unikraft run --metro=fra -p 443:80/tls+http -m 1G --image=/httpserver-python3.12-django5.0:latest ``` ```bash title="kraft" @@ -182,7 +182,7 @@ Run the command below to deploy the app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-python3.12-django5.0:latest -unikraft run --metro=fra -p 443:80/tls+http -m 1G /httpserver-python3.12-django5.0:latest +unikraft run --metro=fra -p 443:80/tls+http -m 1G --image=/httpserver-python3.12-django5.0:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx b/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx index 045aa894..1a8353e2 100644 --- a/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx +++ b/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-python3.12-flask3.0-sqlite:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 768M /httpserver-python3.12-flask3.0-sqlite:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 768M --image=/httpserver-python3.12-flask3.0-sqlite:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-python3.12-flask3.0.mdx b/pages/guides/httpserver-python3.12-flask3.0.mdx index 862b6c0e..8150163d 100644 --- a/pages/guides/httpserver-python3.12-flask3.0.mdx +++ b/pages/guides/httpserver-python3.12-flask3.0.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-python3.12-flask3.0:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /httpserver-python3.12-flask3.0:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-python3.12-flask3.0:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-python3.12.mdx b/pages/guides/httpserver-python3.12.mdx index c36fd18d..d81d98c6 100644 --- a/pages/guides/httpserver-python3.12.mdx +++ b/pages/guides/httpserver-python3.12.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-python3.12:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /httpserver-python3.12:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-python3.12:latest ``` ```bash title="kraft" @@ -162,7 +162,7 @@ Run the command below to deploy the app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-python3.12:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /httpserver-python3.12:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-python3.12:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-ruby3.2.mdx b/pages/guides/httpserver-ruby3.2.mdx index ba5d9e29..d31e122f 100644 --- a/pages/guides/httpserver-ruby3.2.mdx +++ b/pages/guides/httpserver-ruby3.2.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-ruby3.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /httpserver-ruby3.2:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-ruby3.2:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-rust1.75-tokio.mdx b/pages/guides/httpserver-rust1.75-tokio.mdx index 4cbd02dd..adbb6b70 100644 --- a/pages/guides/httpserver-rust1.75-tokio.mdx +++ b/pages/guides/httpserver-rust1.75-tokio.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-rust1.75-tokio:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /httpserver-rust1.75-tokio:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-rust1.75-tokio:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-rust1.81-rocket0.5.mdx b/pages/guides/httpserver-rust1.81-rocket0.5.mdx index 96ee2430..b8279190 100644 --- a/pages/guides/httpserver-rust1.81-rocket0.5.mdx +++ b/pages/guides/httpserver-rust1.81-rocket0.5.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-rust1.81-rocket0.5:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /httpserver-rust1.81-rocket0.5:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-rust1.81-rocket0.5:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-rust1.87-actix-web4.mdx b/pages/guides/httpserver-rust1.87-actix-web4.mdx index fef2b827..82dcd107 100644 --- a/pages/guides/httpserver-rust1.87-actix-web4.mdx +++ b/pages/guides/httpserver-rust1.87-actix-web4.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-rust1.87-actix-web4:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /httpserver-rust1.87-actix-web4:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-rust1.87-actix-web4:latest ``` ```bash title="kraft" diff --git a/pages/guides/httpserver-rust1.91.mdx b/pages/guides/httpserver-rust1.91.mdx index dbe60501..5804978b 100644 --- a/pages/guides/httpserver-rust1.91.mdx +++ b/pages/guides/httpserver-rust1.91.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-rust1.91:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 384M /httpserver-rust1.91:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 384M --image=/httpserver-rust1.91:latest ``` ```bash title="kraft" diff --git a/pages/guides/hugo0.122.mdx b/pages/guides/hugo0.122.mdx index 11e0497b..5a8563b1 100644 --- a/pages/guides/hugo0.122.mdx +++ b/pages/guides/hugo0.122.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /hugo0.122:latest -unikraft run --metro=fra -p 443:1313/tls+http -m 512M /hugo0.122:latest +unikraft run --metro=fra -p 443:1313/tls+http -m 512M --image=/hugo0.122:latest ``` ```bash title="kraft" diff --git a/pages/guides/imaginary.mdx b/pages/guides/imaginary.mdx index ec3ff413..6f230f6f 100644 --- a/pages/guides/imaginary.mdx +++ b/pages/guides/imaginary.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /imaginary:latest -unikraft run --metro=fra -p 443:8088/tls+http -m 256M /imaginary:latest +unikraft run --metro=fra -p 443:8088/tls+http -m 256M --image=/imaginary:latest ``` ```bash title="kraft" diff --git a/pages/guides/mariadb.mdx b/pages/guides/mariadb.mdx index c3c1dba5..a208e25f 100644 --- a/pages/guides/mariadb.mdx +++ b/pages/guides/mariadb.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /mariadb:latest -unikraft run --metro=fra -p 3306:3306/tls -m 1G -e MARIADB_ROOT_PASSWORD="unikraft" /mariadb:latest +unikraft run --metro=fra -p 3306:3306/tls -m 1G -e MARIADB_ROOT_PASSWORD="unikraft" --image=/mariadb:latest ``` ```bash title="kraft" @@ -168,7 +168,7 @@ Then start the MariaDB instance and mount that volume: ```bash title="unikraft" unikraft build . --output /mariadb:latest -unikraft run --metro=fra -p 3306:3306/tls -m 1G -e MARIADB_ROOT_PASSWORD="unikraft" --volume mariadb-store:/var/lib /mariadb:latest +unikraft run --metro=fra -p 3306:3306/tls -m 1G -e MARIADB_ROOT_PASSWORD="unikraft" --volume mariadb-store:/var/lib --image=/mariadb:latest ``` ```bash title="kraft" diff --git a/pages/guides/mcp-server-arxiv.mdx b/pages/guides/mcp-server-arxiv.mdx index 45c4a39c..36dfa504 100644 --- a/pages/guides/mcp-server-arxiv.mdx +++ b/pages/guides/mcp-server-arxiv.mdx @@ -55,7 +55,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /mcp-server-arxiv:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 2G /mcp-server-arxiv:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 2G --image=/mcp-server-arxiv:latest ``` ```bash title="kraft" @@ -149,7 +149,7 @@ Then start the MCP server instance and mount that volume (while specifying the s ```bash title="unikraft" unikraft build . --output /mcp-server-arxiv:latest -unikraft run --metro=fra -v mcp-server-arxiv-data:/volume -p 443:8080/tls+http -m 2G /mcp-server-arxiv:latest -- "/usr/local/bin/python /src/server.py --storage-path /volume" +unikraft run --metro=fra -v mcp-server-arxiv-data:/volume -p 443:8080/tls+http -m 2G --image=/mcp-server-arxiv:latest -- "/usr/local/bin/python /src/server.py --storage-path /volume" ``` ```bash title="kraft" diff --git a/pages/guides/mcp-server-simple.mdx b/pages/guides/mcp-server-simple.mdx index bbd526c2..3b67e84a 100644 --- a/pages/guides/mcp-server-simple.mdx +++ b/pages/guides/mcp-server-simple.mdx @@ -47,7 +47,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /mcp-server-simple:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /mcp-server-simple:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/mcp-server-simple:latest ``` ```bash title="kraft" diff --git a/pages/guides/memcached1.6.mdx b/pages/guides/memcached1.6.mdx index 01920762..7bd17bb6 100644 --- a/pages/guides/memcached1.6.mdx +++ b/pages/guides/memcached1.6.mdx @@ -44,7 +44,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /memcached1.6:latest -unikraft run --metro=fra -p 11211:11211/tls -m 256M /memcached1.6:latest +unikraft run --metro=fra -p 11211:11211/tls -m 256M --image=/memcached1.6:latest ``` ```bash title="kraft" diff --git a/pages/guides/minio.mdx b/pages/guides/minio.mdx index a006d44e..d1838f01 100644 --- a/pages/guides/minio.mdx +++ b/pages/guides/minio.mdx @@ -44,7 +44,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /minio:latest -unikraft run --metro=fra -p 443:9001/tls+http -p 9000:9000/tls -m 512M /minio:latest +unikraft run --metro=fra -p 443:9001/tls+http -p 9000:9000/tls -m 512M --image=/minio:latest ``` ```bash title="kraft" diff --git a/pages/guides/mongodb.mdx b/pages/guides/mongodb.mdx index c6219c04..48c6f1c6 100644 --- a/pages/guides/mongodb.mdx +++ b/pages/guides/mongodb.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /mongodb:latest -unikraft run --metro=fra -p 27017:27017/tls -m 1G /mongodb:latest +unikraft run --metro=fra -p 27017:27017/tls -m 1G --image=/mongodb:latest ``` ```bash title="kraft" diff --git a/pages/guides/nginx.mdx b/pages/guides/nginx.mdx index fc2e8bb7..49947914 100644 --- a/pages/guides/nginx.mdx +++ b/pages/guides/nginx.mdx @@ -44,7 +44,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /nginx:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M /nginx:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/nginx:latest ``` ```bash title="kraft" diff --git a/pages/guides/node24-karaoke.mdx b/pages/guides/node24-karaoke.mdx index d8cd488e..c5c66c2d 100644 --- a/pages/guides/node24-karaoke.mdx +++ b/pages/guides/node24-karaoke.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /node24-karaoke:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 2G /node24-karaoke:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 2G --image=/node24-karaoke:latest ``` ```bash title="kraft" diff --git a/pages/guides/novnc-browser.mdx b/pages/guides/novnc-browser.mdx index 5d6da0a8..eb4eb038 100644 --- a/pages/guides/novnc-browser.mdx +++ b/pages/guides/novnc-browser.mdx @@ -46,7 +46,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /novnc-browser:latest -unikraft run --scale-to-zero policy=on,cooldown-time=4000,stateful=true --metro=fra -p 443:6080/tls+http -m 4G /novnc-browser:latest +unikraft run --scale-to-zero policy=on,cooldown-time=4000,stateful=true --metro=fra -p 443:6080/tls+http -m 4G --image=/novnc-browser:latest ``` ```bash title="kraft" diff --git a/pages/guides/opentelemetry-collector.mdx b/pages/guides/opentelemetry-collector.mdx index 6cf2b356..b7b45d2d 100644 --- a/pages/guides/opentelemetry-collector.mdx +++ b/pages/guides/opentelemetry-collector.mdx @@ -45,7 +45,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /opentelemetry-collector:latest -unikraft run --metro=fra -p 443:4318/tls+http -m 1536M /opentelemetry-collector:latest +unikraft run --metro=fra -p 443:4318/tls+http -m 1536M --image=/opentelemetry-collector:latest ``` ```bash title="kraft" diff --git a/pages/guides/postgres.mdx b/pages/guides/postgres.mdx index 370d85b0..d7fecda1 100644 --- a/pages/guides/postgres.mdx +++ b/pages/guides/postgres.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /postgres:latest -unikraft run --metro=fra -p 5432:5432/tls -m 1G -e POSTGRES_PASSWORD=unikraft /postgres:latest +unikraft run --metro=fra -p 5432:5432/tls -m 1G -e POSTGRES_PASSWORD=unikraft --image=/postgres:latest ``` ```bash title="kraft" @@ -163,7 +163,7 @@ Then start the PostgreSQL instance and mount that volume: ```bash title="unikraft" unikraft build . --output /postgres:latest -unikraft run --metro=fra -p 5432:5432/tls -m 1G -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres --volume postgres:/volume /postgres:latest +unikraft run --metro=fra -p 5432:5432/tls -m 1G -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres --volume postgres:/volume --image=/postgres:latest ``` ```bash title="kraft" diff --git a/pages/guides/ruby3.2-rails.mdx b/pages/guides/ruby3.2-rails.mdx index 86039600..fc358714 100644 --- a/pages/guides/ruby3.2-rails.mdx +++ b/pages/guides/ruby3.2-rails.mdx @@ -42,7 +42,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /ruby3.2-rails:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 1G -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle /ruby3.2-rails:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 1G -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle --image=/ruby3.2-rails:latest ``` ```bash title="kraft" diff --git a/pages/guides/skipper0.18.mdx b/pages/guides/skipper0.18.mdx index bfdb1dd2..e978647b 100644 --- a/pages/guides/skipper0.18.mdx +++ b/pages/guides/skipper0.18.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /skipper0.18:latest -unikraft run --metro=fra -p 443:9090/tls+http -m 256M /skipper0.18:latest +unikraft run --metro=fra -p 443:9090/tls+http -m 256M --image=/skipper0.18:latest ``` ```bash title="kraft" diff --git a/pages/guides/spin-wagi-http.mdx b/pages/guides/spin-wagi-http.mdx index 15b534aa..76a321af 100644 --- a/pages/guides/spin-wagi-http.mdx +++ b/pages/guides/spin-wagi-http.mdx @@ -45,7 +45,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /spin-wagi-http:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 4G /spin-wagi-http:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 4G --image=/spin-wagi-http:latest ``` ```bash title="kraft" diff --git a/pages/guides/traefik.mdx b/pages/guides/traefik.mdx index 812b4357..13423026 100644 --- a/pages/guides/traefik.mdx +++ b/pages/guides/traefik.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /traefik:latest -unikraft run --metro=fra -p 443:80/tls+http -p 8080:8080/tls -m 1G /traefik:latest +unikraft run --metro=fra -p 443:80/tls+http -p 8080:8080/tls -m 1G --image=/traefik:latest ``` ```bash title="kraft" diff --git a/pages/guides/visual-studio-code-server.mdx b/pages/guides/visual-studio-code-server.mdx index ed59563b..fc02979e 100644 --- a/pages/guides/visual-studio-code-server.mdx +++ b/pages/guides/visual-studio-code-server.mdx @@ -48,7 +48,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: unikraft volume create --set metro=fra --set name=code-workspace --set size=1G unikraft build . --output /visual-studio-code-server:latest -unikraft run --metro=fra -p 443:8443/tls+http -m 2G --volume code-workspace:/workspace --scale-to-zero policy=on,cooldown-time=4000,stateful=true -e PGUID=0 -e PGID=0 -e PASSWORD=unikraft -e SUDO_PASSWORD=unikraft -e DEFAULT_WORKSPACE="/workspace" /visual-studio-code-server:latest +unikraft run --metro=fra -p 443:8443/tls+http -m 2G --volume code-workspace:/workspace --scale-to-zero policy=on,cooldown-time=4000,stateful=true -e PGUID=0 -e PGID=0 -e PASSWORD=unikraft -e SUDO_PASSWORD=unikraft -e DEFAULT_WORKSPACE="/workspace" --image=/visual-studio-code-server:latest ``` ```bash title="kraft" diff --git a/pages/guides/vsftpd.mdx b/pages/guides/vsftpd.mdx index cd669028..79ba453c 100644 --- a/pages/guides/vsftpd.mdx +++ b/pages/guides/vsftpd.mdx @@ -44,7 +44,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: unikraft volume create --set metro=fra --set name=vsftpd-workspace --set size=1G unikraft build . --output /vsftpd:latest -unikraft run --metro=fra --scale-to-zero policy=on,cooldown-time=40000,stateful=true -p 20:20/tls -p 21:21/tls -p 222:22/tls -p 990:990/tls -p 10100:10100/tls -m 1G --volume vsftpd-workspace:/root /vsftpd:latest +unikraft run --metro=fra --scale-to-zero policy=on,cooldown-time=40000,stateful=true -p 20:20/tls -p 21:21/tls -p 222:22/tls -p 990:990/tls -p 10100:10100/tls -m 1G --volume vsftpd-workspace:/root --image=/vsftpd:latest ``` ```bash title="kraft" diff --git a/pages/guides/wazero-import-go.mdx b/pages/guides/wazero-import-go.mdx index a454da11..9b75b187 100644 --- a/pages/guides/wazero-import-go.mdx +++ b/pages/guides/wazero-import-go.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /wazero-import-go:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M /wazero-import-go:latest +unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/wazero-import-go:latest ``` ```bash title="kraft" diff --git a/pages/guides/wordpress-all-in-one.mdx b/pages/guides/wordpress-all-in-one.mdx index 9a04e860..0d73571f 100644 --- a/pages/guides/wordpress-all-in-one.mdx +++ b/pages/guides/wordpress-all-in-one.mdx @@ -43,7 +43,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /wordpress-all-in-one:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 4G /wordpress-all-in-one:latest +unikraft run --metro=fra -p 443:3000/tls+http -m 4G --image=/wordpress-all-in-one:latest ``` ```bash title="kraft" diff --git a/pages/introduction.mdx b/pages/introduction.mdx index dd69f0dc..52b1ffc5 100644 --- a/pages/introduction.mdx +++ b/pages/introduction.mdx @@ -80,7 +80,7 @@ Expect higher server density, cost-savings, I/O performance boosts, active vCPU 1. Deploy your first scale-to-zero, serverless app with Unikraft Cloud. ```bash - unikraft run --metro=fra -p 443:8080/http+tls nginx:latest + unikraft run --metro=fra -p 443:8080/http+tls --image=nginx:latest ``` diff --git a/pages/platform/domains.mdx b/pages/platform/domains.mdx index 8884e954..875f718f 100644 --- a/pages/platform/domains.mdx +++ b/pages/platform/domains.mdx @@ -89,7 +89,7 @@ Unikraft Cloud does this through the domain flag: ```bash title="unikraft" unikraft build . --output /nginx:latest -unikraft run --metro=fra -p 443:8080/http+tls --domain mydomain.com /nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls --domain mydomain.com --image=/nginx:latest ``` ```bash title="kraft" diff --git a/pages/platform/images.mdx b/pages/platform/images.mdx index 76b3f942..b8b5270d 100644 --- a/pages/platform/images.mdx +++ b/pages/platform/images.mdx @@ -83,7 +83,7 @@ Start with the simplest workflow: create an image from a Python app (following t git clone https://github.com/unikraft-cloud/examples cd examples/http-python3.12 unikraft build . --output /http-python312:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB /http-python312:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB --image=/http-python312:latest ``` ```bash title="kraft" @@ -162,7 +162,7 @@ For the next workflow, start many instances: git clone https://github.com/unikraft-cloud/examples cd examples/http-python3.12 unikraft build . --output /http-python312:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB --replicas 2 /http-python312:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB --replicas 2 --image=/http-python312:latest ``` ```bash title="kraft" @@ -219,7 +219,7 @@ In this final workflow, take the existing image and start new instances from it: ```bash title="unikraft" -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB /http-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca +unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB --image=/http-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca ``` ```bash title="kraft" diff --git a/pages/platform/metros.mdx b/pages/platform/metros.mdx index de26f00b..7fe18e8e 100644 --- a/pages/platform/metros.mdx +++ b/pages/platform/metros.mdx @@ -86,7 +86,7 @@ For example with `fra`: ```bash title="unikraft" - unikraft run --metro=fra -p 443:8080/http+tls nginx:latest + unikraft run --metro=fra -p 443:8080/http+tls --image=nginx:latest ``` ```bash title="kraft" diff --git a/pages/platform/services.mdx b/pages/platform/services.mdx index 16002155..57c241c7 100644 --- a/pages/platform/services.mdx +++ b/pages/platform/services.mdx @@ -56,7 +56,7 @@ For example, from the [Go web server guide](/guides/go): git clone https://github.com/unikraft-cloud/examples cd examples/http-go1.21/ unikraft build . --output /http-go121:latest -unikraft run --metro=fra --service my-service -m 256MiB /http-go121:latest +unikraft run --metro=fra --service my-service -m 256MiB --image=/http-go121:latest ``` ```bash title="kraft" diff --git a/pages/platform/troubleshooting.mdx b/pages/platform/troubleshooting.mdx index 223b32aa..151094fb 100644 --- a/pages/platform/troubleshooting.mdx +++ b/pages/platform/troubleshooting.mdx @@ -342,7 +342,7 @@ Now Unikraft Cloud is ready to re-deploy: ```bash title="unikraft" unikraft build . --output /http-go-strace:latest -unikraft run --metro=fra --name http-go-strace -p 443:8080/http+tls /http-go-strace:latest +unikraft run --metro=fra --name http-go-strace -p 443:8080/http+tls --image=/http-go-strace:latest ``` ```bash title="kraft" @@ -404,7 +404,7 @@ For example, use the CLI to set `--restart on-failure` so the platform restarts ```bash title="unikraft" -unikraft run --metro=fra --restart=on-failure my-app:latest +unikraft run --metro=fra --restart=on-failure --image=my-app:latest ``` ```bash title="kraft" diff --git a/pages/platform/volumes.mdx b/pages/platform/volumes.mdx index ce3e5da5..e2b5071e 100644 --- a/pages/platform/volumes.mdx +++ b/pages/platform/volumes.mdx @@ -144,7 +144,7 @@ Start the Flask web server, create a ```bash title="unikraft" unikraft build . --output /http-python312-flask30:latest -unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt /http-python312-flask30:latest +unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt --image=/http-python312-flask30:latest ``` ```bash title="kraft" @@ -240,7 +240,7 @@ Now start another instance and, like before, mount the same volume: ```bash title="unikraft" unikraft build . --output /http-python312-flask30:latest -unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt /http-python312-flask30:latest +unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt --image=/http-python312-flask30:latest ``` ```bash title="kraft" diff --git a/pages/tutorials/docker-to-ukc.mdx b/pages/tutorials/docker-to-ukc.mdx index 2947103b..accb3129 100644 --- a/pages/tutorials/docker-to-ukc.mdx +++ b/pages/tutorials/docker-to-ukc.mdx @@ -104,7 +104,7 @@ This confirms that the runtime, filesystem, and command line are valid. ```bash title="unikraft" unikraft build . --output /docker-port:latest -unikraft run --metro=fra -p 443: -m 512MiB /docker-port:latest +unikraft run --metro=fra -p 443: -m 512MiB --image=/docker-port:latest ``` ```bash title="kraft" @@ -247,7 +247,7 @@ This often gives better cold-boot behaviour and lower memory pressure than `CPIO ```bash title="unikraft" unikraft build . --output /docker-port:latest -unikraft run --metro=fra -p 443: -m 256MiB /docker-port:latest +unikraft run --metro=fra -p 443: -m 256MiB --image=/docker-port:latest ``` ```bash title="kraft" @@ -287,7 +287,7 @@ unikraft build . --output /docker-port:latest unikraft run --metro=fra -p 443: -m 256MiB \ -e APP_ENV=production \ -e LOG_LEVEL=info \ - /docker-port:latest + --image=/docker-port:latest ``` ```bash title="kraft" @@ -346,7 +346,7 @@ unikraft build . --output /docker-port:latest unikraft run --metro=fra -p 443: -m 256MiB \ --scale-to-zero \ --scale-to-zero-cooldown-time-ms=5000 \ - /docker-port:latest + --image=/docker-port:latest ``` ```bash title="kraft" diff --git a/pages/tutorials/environment-variables.mdx b/pages/tutorials/environment-variables.mdx index 9a5cab48..bdefc26d 100644 --- a/pages/tutorials/environment-variables.mdx +++ b/pages/tutorials/environment-variables.mdx @@ -62,7 +62,7 @@ The flag works similarly to the `docker run -e` flag. ```bash title="unikraft" -unikraft run --metro=fra -e MY_ENV_VAR=my_value my-app:latest +unikraft run --metro=fra -e MY_ENV_VAR=my_value --image=my-app:latest ``` ```bash title="kraft" diff --git a/pages/tutorials/instance-metrics.mdx b/pages/tutorials/instance-metrics.mdx index 454f4a50..f5537372 100644 --- a/pages/tutorials/instance-metrics.mdx +++ b/pages/tutorials/instance-metrics.mdx @@ -29,7 +29,7 @@ First, provision a new instance: ```bash title="unikraft" git clone https://github.com/unikraft-cloud/examples cd examples/nginx/ -unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB nginx:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 256MiB --image=nginx:latest ``` ```bash title="kraft" diff --git a/pages/tutorials/rootfs-volumes-roms.mdx b/pages/tutorials/rootfs-volumes-roms.mdx index e5609104..f09a49b1 100644 --- a/pages/tutorials/rootfs-volumes-roms.mdx +++ b/pages/tutorials/rootfs-volumes-roms.mdx @@ -93,7 +93,7 @@ Finally, when you deploy an instance you can attach the volume to it: ```bash title="unikraft" -unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt my-app:latest +unikraft run --metro=fra -m 512MiB -p 443:8080/http+tls -v my-volume:/mnt --image=my-app:latest ``` ```bash title="kraft" diff --git a/pages/use-cases/headless-browsers.mdx b/pages/use-cases/headless-browsers.mdx index 761c3229..e1b8a847 100644 --- a/pages/use-cases/headless-browsers.mdx +++ b/pages/use-cases/headless-browsers.mdx @@ -93,7 +93,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /node-express-puppeteer:latest -unikraft run --metro=fra -p 443:3000/http+tls -m 4Gi /node-express-puppeteer:latest +unikraft run --metro=fra -p 443:3000/http+tls -m 4Gi --image=/node-express-puppeteer:latest ``` ```bash title="kraft" diff --git a/pages/use-cases/serverless-databases.mdx b/pages/use-cases/serverless-databases.mdx index fb4b6fd0..3fff680f 100644 --- a/pages/use-cases/serverless-databases.mdx +++ b/pages/use-cases/serverless-databases.mdx @@ -61,7 +61,7 @@ This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): ```bash title="unikraft" unikraft login unikraft build . --output /postgres:latest -unikraft run --metro=fra -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -m 1Gi /postgres:latest +unikraft run --metro=fra -e POSTGRES_PASSWORD=unikraft -p 5432:5432/tls -m 1Gi --image=/postgres:latest ``` ```bash title="kraft" @@ -195,7 +195,7 @@ Then start the PostgreSQL instance and mount that volume: ```console title="unikraft" unikraft build . --output /postgres:latest -unikraft run --metro=fra -p 5432:5432/tls -m 1Gi -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume /postgres:latest +unikraft run --metro=fra -p 5432:5432/tls -m 1Gi -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume --image=/postgres:latest ``` ```console title="kraft" From bfb593edfa121d52dea11e3e9a52f6a1a5c16825 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Wed, 22 Apr 2026 14:50:21 +0100 Subject: [PATCH 099/131] chore: Update zudoku to version v0.76.0 Signed-off-by: Justin Chadwell --- package-lock.json | 1632 ++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 793 insertions(+), 841 deletions(-) diff --git a/package-lock.json b/package-lock.json index d0b5e2f2..a69ddd14 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "react": ">=19.0.0", "react-dom": ">=19.0.0", "regex-utilities": "^2.3.0", - "zudoku": "^0.74.3" + "zudoku": "^0.76.0" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0", @@ -37,294 +37,104 @@ "@types/json-schema": "^7.0.15" } }, - "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/core": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "node_modules/@base-ui/react": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@base-ui/react/-/react-1.4.1.tgz", + "integrity": "sha512-Ab5/LIhcmL8BQcsBUYiOfkSDRdLpvgUBzMK30cu684JPcLclYlztharvCZyNNgzJtbAiREzI9q0pI5erHCMgCw==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.29.0", - "@babel/types": "^7.29.0", - "@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" + "@babel/runtime": "^7.29.2", + "@base-ui/utils": "0.2.8", + "@floating-ui/react-dom": "^2.1.8", + "@floating-ui/utils": "^0.2.11", + "use-sync-external-store": "^1.6.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=14.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.0", - "@babel/types": "^7.29.0", - "@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.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", - "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0" + "@date-fns/tz": "^1.2.0", + "@types/react": "^17 || ^18 || ^19", + "date-fns": "^4.0.0", + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", - "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" + "peerDependenciesMeta": { + "@date-fns/tz": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "date-fns": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "node_modules/@base-ui/utils": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@base-ui/utils/-/utils-0.2.8.tgz", + "integrity": "sha512-jvOi+c+ftGlGotNcKnzPVg2IhCaDTB6/6R3JeqdjdXktuAJi3wKH9T7+svuaKh1mmfVU11UWzUZVH74JDfi/wQ==", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.29.2", + "@floating-ui/utils": "^0.2.11", + "reselect": "^5.1.1", + "use-sync-external-store": "^1.6.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@types/react": "^17 || ^18 || ^19", + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", - "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@babel/template": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "node_modules/@emnapi/core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", + "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", "license": "MIT", + "optional": true, "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" } }, - "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "node_modules/@emnapi/runtime": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", + "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", "license": "MIT", + "optional": true, "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" + "tslib": "^2.4.0" } }, - "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "license": "MIT", + "optional": true, "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" + "tslib": "^2.4.0" } }, "node_modules/@envelop/core": { @@ -369,9 +179,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", - "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", + "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" ], @@ -385,9 +195,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", - "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", "cpu": [ "arm" ], @@ -401,9 +211,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", - "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", + "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" ], @@ -417,9 +227,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", - "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", + "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" ], @@ -433,9 +243,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", - "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", + "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" ], @@ -449,9 +259,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", - "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", + "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" ], @@ -465,9 +275,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", - "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", + "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" ], @@ -481,9 +291,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", - "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", + "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" ], @@ -497,9 +307,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", - "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", + "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" ], @@ -513,9 +323,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", - "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", "cpu": [ "arm64" ], @@ -529,9 +339,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", - "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", + "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" ], @@ -545,9 +355,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", - "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", "cpu": [ "loong64" ], @@ -561,9 +371,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", - "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", + "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" ], @@ -577,9 +387,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", - "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", + "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" ], @@ -593,9 +403,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", - "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", + "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" ], @@ -609,9 +419,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", - "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", "cpu": [ "s390x" ], @@ -625,9 +435,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", - "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", + "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" ], @@ -641,9 +451,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", - "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", + "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" ], @@ -657,9 +467,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", - "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", + "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" ], @@ -673,9 +483,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", - "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", "cpu": [ "arm64" ], @@ -689,9 +499,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", - "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", + "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" ], @@ -705,9 +515,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", - "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", + "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" ], @@ -721,9 +531,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", - "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", + "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" ], @@ -737,9 +547,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", - "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", + "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" ], @@ -753,9 +563,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", - "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", + "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" ], @@ -769,9 +579,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", - "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", + "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" ], @@ -1803,6 +1613,24 @@ "node": ">= 10" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, "node_modules/@opentelemetry/api": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", @@ -2316,10 +2144,19 @@ "@opentelemetry/api": "^1.1.0" } }, + "node_modules/@oxc-project/types": { + "version": "0.124.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz", + "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, "node_modules/@pagefind/darwin-arm64": { - "version": "1.5.0-beta.1", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.5.0-beta.1.tgz", - "integrity": "sha512-oOcnXy83NK+utpeHN3igrug7RpZpu0lLNpGOXfTKJaOc44lIvxnDI0ceJnwvRqDCl+KLSGpqn4uWczmEMtnikQ==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.5.2.tgz", + "integrity": "sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==", "cpu": [ "arm64" ], @@ -2330,9 +2167,9 @@ ] }, "node_modules/@pagefind/darwin-x64": { - "version": "1.5.0-beta.1", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.5.0-beta.1.tgz", - "integrity": "sha512-ZL2+L+rtjPv0sZ1CcrtuDqJgorkGr6DTcm3KargL2gvlIfup73GEZ1S0rNSLPIR1azUa+fuiW2dI8SEacCRcBQ==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.5.2.tgz", + "integrity": "sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==", "cpu": [ "x64" ], @@ -2343,9 +2180,9 @@ ] }, "node_modules/@pagefind/freebsd-x64": { - "version": "1.5.0-beta.1", - "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.5.0-beta.1.tgz", - "integrity": "sha512-OYUJUAipl8PX2kl5GJUd0Jt1lmzbeG2Ld0J6FWNZw3eEQ9Qs58bviuo7bg99xJEV8K//GO3PrD6JHzFI5umUJA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.5.2.tgz", + "integrity": "sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==", "cpu": [ "x64" ], @@ -2356,9 +2193,9 @@ ] }, "node_modules/@pagefind/linux-arm64": { - "version": "1.5.0-beta.1", - "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.5.0-beta.1.tgz", - "integrity": "sha512-xaHp0iBnhC/jWRmwLZ5+x1f/DK1G9Z2rdXgNh7YTEes0hSaQwwu6JzAKjhH9K1rYClWnRDfHIF+SBu5MY48ecQ==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.5.2.tgz", + "integrity": "sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==", "cpu": [ "arm64" ], @@ -2369,9 +2206,9 @@ ] }, "node_modules/@pagefind/linux-x64": { - "version": "1.5.0-beta.1", - "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.5.0-beta.1.tgz", - "integrity": "sha512-3UzHImmoMC1xTN3uD6myxKMDxygEQu+i4f1qRGAyetXudkK5ItlLZycAso6+e5Te0jNlDRDosTE5ulj+MuR4dg==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.5.2.tgz", + "integrity": "sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==", "cpu": [ "x64" ], @@ -2381,10 +2218,23 @@ "linux" ] }, + "node_modules/@pagefind/windows-arm64": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/windows-arm64/-/windows-arm64-1.5.2.tgz", + "integrity": "sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@pagefind/windows-x64": { - "version": "1.5.0-beta.1", - "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.5.0-beta.1.tgz", - "integrity": "sha512-A+D7zCNPdXXaUw2TIyTdrMSK61wq7yRluXL/b/dxFyBP/qycFV8wqIiLx14vQH+pKgXOeMdIkiLAA+HUnbPWwg==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.5.2.tgz", + "integrity": "sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==", "cpu": [ "x64" ], @@ -4017,10 +3867,270 @@ "integrity": "sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==", "license": "MIT" }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz", + "integrity": "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz", + "integrity": "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz", + "integrity": "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz", + "integrity": "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz", + "integrity": "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz", + "integrity": "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz", + "integrity": "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz", + "integrity": "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz", + "integrity": "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz", + "integrity": "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz", + "integrity": "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz", + "integrity": "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz", + "integrity": "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.9.2", + "@emnapi/runtime": "1.9.2", + "@napi-rs/wasm-runtime": "^1.1.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz", + "integrity": "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz", + "integrity": "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "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==", + "version": "1.0.0-rc.7", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz", + "integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==", "license": "MIT" }, "node_modules/@rollup/pluginutils": { @@ -4062,7 +4172,8 @@ "optional": true, "os": [ "android" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-android-arm64": { "version": "4.59.0", @@ -4075,7 +4186,8 @@ "optional": true, "os": [ "android" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.59.0", @@ -4088,7 +4200,8 @@ "optional": true, "os": [ "darwin" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-darwin-x64": { "version": "4.59.0", @@ -4101,7 +4214,8 @@ "optional": true, "os": [ "darwin" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-freebsd-arm64": { "version": "4.59.0", @@ -4114,7 +4228,8 @@ "optional": true, "os": [ "freebsd" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-freebsd-x64": { "version": "4.59.0", @@ -4127,7 +4242,8 @@ "optional": true, "os": [ "freebsd" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { "version": "4.59.0", @@ -4143,7 +4259,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { "version": "4.59.0", @@ -4159,7 +4276,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-arm64-gnu": { "version": "4.59.0", @@ -4175,7 +4293,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-arm64-musl": { "version": "4.59.0", @@ -4191,7 +4310,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-loong64-gnu": { "version": "4.59.0", @@ -4207,7 +4327,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-loong64-musl": { "version": "4.59.0", @@ -4223,7 +4344,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { "version": "4.59.0", @@ -4239,7 +4361,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-ppc64-musl": { "version": "4.59.0", @@ -4255,7 +4378,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { "version": "4.59.0", @@ -4271,7 +4395,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-riscv64-musl": { "version": "4.59.0", @@ -4287,7 +4412,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-s390x-gnu": { "version": "4.59.0", @@ -4303,7 +4429,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.59.0", @@ -4319,7 +4446,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-linux-x64-musl": { "version": "4.59.0", @@ -4335,7 +4463,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-openbsd-x64": { "version": "4.59.0", @@ -4348,7 +4477,8 @@ "optional": true, "os": [ "openbsd" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-openharmony-arm64": { "version": "4.59.0", @@ -4361,7 +4491,8 @@ "optional": true, "os": [ "openharmony" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-win32-arm64-msvc": { "version": "4.59.0", @@ -4374,7 +4505,8 @@ "optional": true, "os": [ "win32" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-win32-ia32-msvc": { "version": "4.59.0", @@ -4387,7 +4519,8 @@ "optional": true, "os": [ "win32" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-win32-x64-gnu": { "version": "4.59.0", @@ -4400,7 +4533,8 @@ "optional": true, "os": [ "win32" - ] + ], + "peer": true }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.59.0", @@ -4413,7 +4547,8 @@ "optional": true, "os": [ "win32" - ] + ], + "peer": true }, "node_modules/@scalar/helpers": { "version": "0.2.7", @@ -4693,47 +4828,53 @@ "license": "MIT" }, "node_modules/@tailwindcss/node": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", - "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz", + "integrity": "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==", "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", - "lightningcss": "1.31.1", + "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.2.1" + "tailwindcss": "4.2.2" } }, + "node_modules/@tailwindcss/node/node_modules/tailwindcss": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz", + "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==", + "license": "MIT" + }, "node_modules/@tailwindcss/oxide": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", - "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.2.tgz", + "integrity": "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==", "license": "MIT", "engines": { "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-x64": "4.2.1", - "@tailwindcss/oxide-freebsd-x64": "4.2.1", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", - "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-x64-musl": "4.2.1", - "@tailwindcss/oxide-wasm32-wasi": "4.2.1", - "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", - "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" + "@tailwindcss/oxide-android-arm64": "4.2.2", + "@tailwindcss/oxide-darwin-arm64": "4.2.2", + "@tailwindcss/oxide-darwin-x64": "4.2.2", + "@tailwindcss/oxide-freebsd-x64": "4.2.2", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.2", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", + "@tailwindcss/oxide-linux-x64-musl": "4.2.2", + "@tailwindcss/oxide-wasm32-wasi": "4.2.2", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.2" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", - "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz", + "integrity": "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==", "cpu": [ "arm64" ], @@ -4747,9 +4888,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", - "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz", + "integrity": "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==", "cpu": [ "arm64" ], @@ -4763,9 +4904,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", - "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz", + "integrity": "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==", "cpu": [ "x64" ], @@ -4779,9 +4920,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", - "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz", + "integrity": "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==", "cpu": [ "x64" ], @@ -4795,9 +4936,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", - "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz", + "integrity": "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==", "cpu": [ "arm" ], @@ -4811,9 +4952,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", - "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz", + "integrity": "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==", "cpu": [ "arm64" ], @@ -4830,9 +4971,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", - "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz", + "integrity": "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==", "cpu": [ "arm64" ], @@ -4849,9 +4990,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", - "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz", + "integrity": "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==", "cpu": [ "x64" ], @@ -4868,9 +5009,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", - "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz", + "integrity": "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==", "cpu": [ "x64" ], @@ -4887,9 +5028,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", - "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz", + "integrity": "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -4915,68 +5056,10 @@ "node": ">=14.0.0" } }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.8.1", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.1.0", - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.8.1", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.1.0", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.1", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", - "@tybys/wasm-util": "^0.10.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { - "version": "2.8.1", - "inBundle": true, - "license": "0BSD", - "optional": true - }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", - "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz", + "integrity": "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==", "cpu": [ "arm64" ], @@ -4990,9 +5073,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", - "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz", + "integrity": "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==", "cpu": [ "x64" ], @@ -5018,19 +5101,25 @@ } }, "node_modules/@tailwindcss/vite": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.1.tgz", - "integrity": "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.2.tgz", + "integrity": "sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==", "license": "MIT", "dependencies": { - "@tailwindcss/node": "4.2.1", - "@tailwindcss/oxide": "4.2.1", - "tailwindcss": "4.2.1" + "@tailwindcss/node": "4.2.2", + "@tailwindcss/oxide": "4.2.2", + "tailwindcss": "4.2.2" }, "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7" + "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, + "node_modules/@tailwindcss/vite/node_modules/tailwindcss": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz", + "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==", + "license": "MIT" + }, "node_modules/@tanem/react-nprogress": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@tanem/react-nprogress/-/react-nprogress-6.0.3.tgz", @@ -5071,45 +5160,14 @@ "react": "^18 || ^19" } }, - "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==", - "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==", - "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==", - "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==", + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", "license": "MIT", + "optional": true, "dependencies": { - "@babel/types": "^7.28.2" + "tslib": "^2.4.0" } }, "node_modules/@types/connect": { @@ -5501,23 +5559,28 @@ "license": "ISC" }, "node_modules/@vitejs/plugin-react": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", - "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz", + "integrity": "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==", "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" + "@rolldown/pluginutils": "1.0.0-rc.7" }, "engines": { "node": "^20.19.0 || >=22.12.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } } }, "node_modules/@whatwg-node/disposablestack": { @@ -5816,18 +5879,6 @@ "integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==", "license": "MIT" }, - "node_modules/baseline-browser-mapping": { - "version": "2.10.12", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.12.tgz", - "integrity": "sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==", - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/brace-expansion": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", @@ -5840,39 +5891,6 @@ "node": "18 || 20 || >=22" } }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "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.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, "node_modules/bs58": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", @@ -5921,26 +5939,6 @@ "node": ">=6" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001782", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001782.tgz", - "integrity": "sha512-dZcaJLJeDMh4rELYFw1tvSn1bhZWYFOt468FcbHHxx/Z/dFidd1I6ciyFdi3iwfQCyOjqo9upF6lGQYtMiJWxw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", @@ -6128,12 +6126,6 @@ "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==", - "license": "MIT" - }, "node_modules/cookie": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", @@ -6303,12 +6295,6 @@ "node": ">= 0.4" } }, - "node_modules/electron-to-chromium": { - "version": "1.5.328", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.328.tgz", - "integrity": "sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==", - "license": "ISC" - }, "node_modules/embla-carousel": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz", @@ -6431,9 +6417,9 @@ } }, "node_modules/esbuild": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", - "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -6443,32 +6429,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.4", - "@esbuild/android-arm": "0.27.4", - "@esbuild/android-arm64": "0.27.4", - "@esbuild/android-x64": "0.27.4", - "@esbuild/darwin-arm64": "0.27.4", - "@esbuild/darwin-x64": "0.27.4", - "@esbuild/freebsd-arm64": "0.27.4", - "@esbuild/freebsd-x64": "0.27.4", - "@esbuild/linux-arm": "0.27.4", - "@esbuild/linux-arm64": "0.27.4", - "@esbuild/linux-ia32": "0.27.4", - "@esbuild/linux-loong64": "0.27.4", - "@esbuild/linux-mips64el": "0.27.4", - "@esbuild/linux-ppc64": "0.27.4", - "@esbuild/linux-riscv64": "0.27.4", - "@esbuild/linux-s390x": "0.27.4", - "@esbuild/linux-x64": "0.27.4", - "@esbuild/netbsd-arm64": "0.27.4", - "@esbuild/netbsd-x64": "0.27.4", - "@esbuild/openbsd-arm64": "0.27.4", - "@esbuild/openbsd-x64": "0.27.4", - "@esbuild/openharmony-arm64": "0.27.4", - "@esbuild/sunos-x64": "0.27.4", - "@esbuild/win32-arm64": "0.27.4", - "@esbuild/win32-ia32": "0.27.4", - "@esbuild/win32-x64": "0.27.4" + "@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": { @@ -7092,15 +7078,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -7241,9 +7218,9 @@ "license": "ISC" }, "node_modules/graphql": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.1.tgz", - "integrity": "sha512-gGgrVCoDKlIZ8fIqXBBb0pPKqDgki0Z/FSKNiQzSGj2uEYHr1tq5wmBegGwJx6QB5S5cM0khSBpi/JFHMCvsmQ==", + "version": "16.13.2", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.2.tgz", + "integrity": "sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==", "license": "MIT", "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" @@ -7605,9 +7582,9 @@ "license": "MIT" }, "node_modules/hono": { - "version": "4.12.12", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.12.tgz", - "integrity": "sha512-p1JfQMKaceuCbpJKAPKVqyqviZdS0eUxH9v82oWo1kb9xjQ5wA6iP3FNVAPDFlz5/p7d45lO+BpSk1tuSZMF4Q==", + "version": "4.12.14", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.14.tgz", + "integrity": "sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==", "license": "MIT", "engines": { "node": ">=16.9.0" @@ -7855,18 +7832,6 @@ "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==", - "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", @@ -7915,18 +7880,6 @@ "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==", - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/jsonpointer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", @@ -7982,9 +7935,9 @@ } }, "node_modules/lightningcss": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", - "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", + "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" @@ -7997,23 +7950,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.31.1", - "lightningcss-darwin-arm64": "1.31.1", - "lightningcss-darwin-x64": "1.31.1", - "lightningcss-freebsd-x64": "1.31.1", - "lightningcss-linux-arm-gnueabihf": "1.31.1", - "lightningcss-linux-arm64-gnu": "1.31.1", - "lightningcss-linux-arm64-musl": "1.31.1", - "lightningcss-linux-x64-gnu": "1.31.1", - "lightningcss-linux-x64-musl": "1.31.1", - "lightningcss-win32-arm64-msvc": "1.31.1", - "lightningcss-win32-x64-msvc": "1.31.1" + "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.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", - "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", + "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" ], @@ -8031,9 +7984,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", - "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", + "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" ], @@ -8051,9 +8004,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", - "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", + "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" ], @@ -8071,9 +8024,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", - "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", + "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" ], @@ -8091,9 +8044,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", - "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", + "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" ], @@ -8111,9 +8064,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", - "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", + "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" ], @@ -8134,9 +8087,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", - "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", + "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" ], @@ -8157,9 +8110,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", - "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", + "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" ], @@ -8180,9 +8133,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", - "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", + "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" ], @@ -8203,9 +8156,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", - "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", + "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" ], @@ -8223,9 +8176,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", - "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", + "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" ], @@ -8300,15 +8253,6 @@ "loose-envify": "cli.js" } }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, "node_modules/lucide-react": { "version": "0.577.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.577.0.tgz", @@ -9557,12 +9501,6 @@ "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, - "node_modules/node-releases": { - "version": "2.0.36", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", - "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", - "license": "MIT" - }, "node_modules/oauth4webapi": { "version": "3.8.5", "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.5.tgz", @@ -9694,20 +9632,21 @@ } }, "node_modules/pagefind": { - "version": "1.5.0-beta.1", - "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.5.0-beta.1.tgz", - "integrity": "sha512-TOOP7e1C7Nd82wWFu2P5ElIFbNLiqdrKlBz6/BpyeJ6t17NtldrQyPmsBiHsv+eu7E6uXo7lG9MYsUcLMk+6ew==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.5.2.tgz", + "integrity": "sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==", "license": "MIT", "bin": { "pagefind": "lib/runner/bin.cjs" }, "optionalDependencies": { - "@pagefind/darwin-arm64": "1.5.0-beta.1", - "@pagefind/darwin-x64": "1.5.0-beta.1", - "@pagefind/freebsd-x64": "1.5.0-beta.1", - "@pagefind/linux-arm64": "1.5.0-beta.1", - "@pagefind/linux-x64": "1.5.0-beta.1", - "@pagefind/windows-x64": "1.5.0-beta.1" + "@pagefind/darwin-arm64": "1.5.2", + "@pagefind/darwin-x64": "1.5.2", + "@pagefind/freebsd-x64": "1.5.2", + "@pagefind/linux-arm64": "1.5.2", + "@pagefind/linux-x64": "1.5.2", + "@pagefind/windows-arm64": "1.5.2", + "@pagefind/windows-x64": "1.5.2" } }, "node_modules/parent-module": { @@ -9872,9 +9811,9 @@ } }, "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", "funding": [ { "type": "opencollective", @@ -10057,9 +9996,9 @@ } }, "node_modules/react-is": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.4.tgz", - "integrity": "sha512-W+EWGn2v0ApPKgKKCy/7s7WHXkboGcsrXE+2joLyVxkbyVQfO3MUEaUQDHoSmb8TFFrSKYa9mw64WZHNHSDzYA==", + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.5.tgz", + "integrity": "sha512-Dn0t8IQhCmeIT3wu+Apm1/YVsJXsGWi6k4sPdnBIdqMVtHtv0IGi6dcpNpNkNac0zB2uUAqNX3MHzN8c+z2rwQ==", "license": "MIT" }, "node_modules/react-markdown": { @@ -10089,15 +10028,6 @@ "react": ">=18" } }, - "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==", - "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", @@ -10587,6 +10517,12 @@ "node": ">=9.3.0 || >=8.10.0 <9.0.0" } }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -10611,11 +10547,51 @@ "node": ">=18.0" } }, + "node_modules/rolldown": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.15.tgz", + "integrity": "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==", + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.124.0", + "@rolldown/pluginutils": "1.0.0-rc.15" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-rc.15", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", + "@rolldown/binding-darwin-x64": "1.0.0-rc.15", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.15", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz", + "integrity": "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==", + "license": "MIT" + }, "node_modules/rollup": { "version": "4.59.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -11029,9 +11005,9 @@ "license": "MIT" }, "node_modules/tapable": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz", - "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==", + "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" @@ -11288,36 +11264,6 @@ "url": "https://opencollective.com/unified" } }, - "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==", - "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", @@ -11400,6 +11346,15 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -11462,16 +11417,15 @@ } }, "node_modules/vite": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", - "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", + "version": "8.0.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.8.tgz", + "integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==", "license": "MIT", "dependencies": { - "esbuild": "^0.27.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.8", + "rolldown": "1.0.0-rc.15", "tinyglobby": "^0.2.15" }, "bin": { @@ -11488,9 +11442,10 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.0", + "esbuild": "^0.27.0 || ^0.28.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", @@ -11503,13 +11458,16 @@ "@types/node": { "optional": true }, - "jiti": { + "@vitejs/devtools": { "optional": true }, - "less": { + "esbuild": { + "optional": true + }, + "jiti": { "optional": true }, - "lightningcss": { + "less": { "optional": true }, "sass": { @@ -11605,12 +11563,6 @@ "node": ">=10" } }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "license": "ISC" - }, "node_modules/yaml": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", @@ -11675,11 +11627,12 @@ } }, "node_modules/zudoku": { - "version": "0.74.3", - "resolved": "https://registry.npmjs.org/zudoku/-/zudoku-0.74.3.tgz", - "integrity": "sha512-uhyOi9XvPboWl5YtTc0Kfg6JywmSK9WA0QrQCcldV5XyDguWnQ5IhuNuuQgXTISdCp0vKAEwwerdF7Xbjrkfrg==", + "version": "0.76.0", + "resolved": "https://registry.npmjs.org/zudoku/-/zudoku-0.76.0.tgz", + "integrity": "sha512-8OdEQ7153hmBmszbKJGyPmr2vapZ7nvGsFmC/YDpkUU6rYghJBVWkV0DRWPGhHLAM3820QxtrILnBxLyVP/eNw==", "dependencies": { "@apidevtools/json-schema-ref-parser": "15.3.1", + "@base-ui/react": "^1.4.0", "@envelop/core": "5.5.1", "@graphql-typed-document-node/core": "3.2.0", "@hono/node-server": "1.19.13", @@ -11718,12 +11671,12 @@ "@shikijs/themes": "3.23.0", "@shikijs/transformers": "3.23.0", "@tailwindcss/typography": "0.5.19", - "@tailwindcss/vite": "4.2.1", + "@tailwindcss/vite": "4.2.2", "@tanem/react-nprogress": "6.0.3", "@tanstack/react-query": "5.97.0", "@types/react": "19.2.14", "@types/react-dom": "19.2.3", - "@vitejs/plugin-react": "5.1.4", + "@vitejs/plugin-react": "6.0.1", "@x0k/json-schema-merge": "1.0.2", "@zudoku/httpsnippet": "10.0.9", "@zudoku/react-helmet-async": "2.0.5", @@ -11740,14 +11693,14 @@ "fast-equals": "6.0.0", "glob": "13.0.6", "glob-parent": "6.0.2", - "graphql": "16.13.1", + "graphql": "16.13.2", "graphql-type-json": "0.3.2", "graphql-yoga": "5.18.0", "gray-matter": "4.0.3", "hast-util-heading-rank": "3.0.0", "hast-util-to-jsx-runtime": "2.3.6", "hast-util-to-string": "3.0.1", - "hono": "4.12.12", + "hono": "4.12.14", "http-terminator": "3.2.0", "javascript-stringify": "2.1.0", "json-schema-to-typescript-lite": "15.0.0", @@ -11762,13 +11715,13 @@ "next-themes": "0.4.6", "oauth4webapi": "3.8.5", "openapi-types": "12.1.3", - "pagefind": "1.5.0-beta.1", + "pagefind": "1.5.2", "picocolors": "1.1.1", "piscina": "5.1.4", "posthog-node": "5.26.0", "react-error-boundary": "6.1.1", "react-hook-form": "7.71.2", - "react-is": "19.2.4", + "react-is": "19.2.5", "react-markdown": "10.1.0", "react-router": "7.13.0", "rehype-mdx-import-media": "1.2.0", @@ -11780,7 +11733,6 @@ "remark-frontmatter": "5.0.0", "remark-gfm": "4.0.1", "remark-mdx-frontmatter": "5.2.0", - "rollup": "4.59.0", "semver": "7.7.4", "shiki": "3.23.0", "sitemap": "9.0.1", @@ -11792,7 +11744,7 @@ "unist-util-visit": "5.1.0", "vaul": "1.1.2", "vfile": "6.0.3", - "vite": "7.3.2", + "vite": "8.0.8", "yaml": "2.8.3", "yargs": "18.0.0", "zod": "4.3.6", diff --git a/package.json b/package.json index 99b62fcf..501fa2b6 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "react": ">=19.0.0", "react-dom": ">=19.0.0", "regex-utilities": "^2.3.0", - "zudoku": "^0.74.3" + "zudoku": "^0.76.0" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0", From 0edd8e94f4e9ee4b2f18b4db1a9865720bd7bd1c Mon Sep 17 00:00:00 2001 From: Dragos Gheorghioiu Date: Thu, 16 Apr 2026 16:16:43 +0300 Subject: [PATCH 100/131] feat(cli): Added cli installation instructions to overview page Signed-off-by: Dragos Gheorghioiu --- pages/cli/legacy-overview.mdx | 96 +++++++++++++++++++++++++++++++++++ pages/cli/overview.mdx | 92 ++++++++++++++++++++------------- 2 files changed, 152 insertions(+), 36 deletions(-) create mode 100644 pages/cli/legacy-overview.mdx diff --git a/pages/cli/legacy-overview.mdx b/pages/cli/legacy-overview.mdx new file mode 100644 index 00000000..dd6f1be5 --- /dev/null +++ b/pages/cli/legacy-overview.mdx @@ -0,0 +1,96 @@ +--- +title: Kraft cloud CLI (legacy) +description: Legacy Kraft cloud CLI installation and quick start +--- + +The **kraft cloud** CLI is part of the [KraftKit](https://github.com/unikraft/kraftkit) toolchain. +While it remains fully supported with ongoing bug fixes, it won't receive any new functionality. +New users should use the unikraft CLI instead. + +## Installation + +For Windows, KraftKit currently requires Windows Subsystem for Linux 2 (WSL2). +Please ensure you set up WSL2 on your host (for example: run `wsl --install -d ubuntu` in PowerShell). + + + +```bash title="1-liner (macOS & Linux)" +curl --proto '=https' --tlsv1.2 -sSf https://get.kraftkit.sh | sh +``` + +```bash title="macOS" +brew install unikraft/tap/kraftkit +``` + +```bash title="Debian/Ubuntu" +# Update and install dependencies +sudo apt-get update +sudo apt-get install \ + ca-certificates \ + curl \ + gnupg \ + lsb-release + +# Add Unikraft's official GPG key: +sudo mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.pkg.kraftkit.sh/gpg.key | \ + sudo gpg --dearmor -o /etc/apt/keyrings/unikraft.gpg + +# Use the following command to set up the APT repository: +echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/unikraft.gpg] https://deb.pkg.kraftkit.sh /" | \ + sudo tee /etc/apt/sources.list.d/unikraft.list > /dev/null + +# Update the APT package index, and install the latest version of kraftkit: +sudo apt-get update +sudo apt-get install kraftkit +``` + +```bash title="Fedora/RHEL/Rocky/Alma" +# Add the Kraftkit repository +sudo tee /etc/yum.repos.d/kraftkit.repo < + +## Quick start + +```sh +# Deploy an instance +kraft cloud deploy -p 443:8080/http+tls -M 512 . + +# List instances +kraft cloud instance list +``` + +## Choosing a CLI + +| Feature | unikraft | kraft cloud | +|---------|----------|-------------| +| Recommended for new users | Yes | No | +| Profile management | Yes | Limited | +| Scale-to-zero support | Yes | Yes | +| Compose support | No | Yes | + +If you are getting started with Unikraft Cloud, use the **unikraft** CLI. +If you need Docker Compose-style workflows use the **kraft cloud** CLI. + +[Back to CLI overview](/docs/cli/overview) diff --git a/pages/cli/overview.mdx b/pages/cli/overview.mdx index 9eecac58..89932fc3 100644 --- a/pages/cli/overview.mdx +++ b/pages/cli/overview.mdx @@ -3,14 +3,10 @@ title: CLI Overview description: Command-line interfaces for Unikraft Cloud --- -Unikraft Cloud provides two command-line interfaces for managing your unikernel deployments: - -## unikraft CLI (recommended) - The **unikraft** CLI is the new, official command-line interface for [Unikraft Cloud](https://unikraft.cloud). It provides a modern, streamlined experience for deploying and managing unikernels globally. -### Features +## Features - **Deploy Instantly** - Run unikernel images as serverless instances with `unikraft run` - **Global Infrastructure** - Deploy across supported metros with automatic multi-region support @@ -20,51 +16,75 @@ It provides a modern, streamlined experience for deploying and managing unikerne - **Profile Management** - Switch between accounts and configurations - **Shell Completions** - Tab completion for Bash, Zsh, Fish, and PowerShell -### Quick start +## Installation -```sh -# Login to Unikraft Cloud -unikraft login + -# Deploy an instance -unikraft run --metro=fra -p 443:8080/http+tls nginx:latest +```bash title="1-liner (macOS & Linux)" +curl --proto '=https' --tlsv1.2 -fsSL https://unikraft.com/cli/install.sh | sh +``` -# List instances -unikraft instances list +```bash title="macOS" +brew install unikraft/cli/unikraft ``` -[View unikraft CLI documentation](/docs/cli/unikraft) +```bash title="Debian/Ubuntu" +# Update and install dependencies +sudo apt update +sudo apt install ca-certificates curl + +# Download and add the GPG key +sudo install -d -m 0755 /etc/apt/keyrings + +sudo curl -fsSL \ + -o /etc/apt/keyrings/unikraft-cli.gpg \ + https://pkg.unikraft.com/debian/cli-apt/keys/cli-apt.gpg + +sudo tee /etc/apt/sources.list.d/unikraft-cli.sources < -The **kraft cloud** CLI is part of the [KraftKit](https://github.com/unikraft/kraftkit) toolchain. -It remains fully supported, and new users should use the `unikraft` CLI above. +See [alternative installation instructions](https://github.com/unikraft/cli/?tab=readme-ov-file#installation) for other platforms. -### Quick start +## Quick start ```sh +# Login to Unikraft Cloud +unikraft login + # Deploy an instance -kraft cloud deploy -p 443:8080/http+tls -M 512 . +unikraft run --metro=fra -p 443:8080/http+tls nginx:latest # List instances -kraft cloud instance list +unikraft instances list ``` -[View kraft cloud CLI documentation](/docs/cli/kraft/overview) - ---- - -## Choosing a CLI - -| Feature | unikraft | kraft cloud | -|---------|----------|-------------| -| Recommended for new users | Yes | No | -| Profile management | Yes | Limited | -| Scale-to-zero support | Yes | Yes | -| Compose support | No | Yes | -| Build from source | No | Yes | +[View unikraft CLI documentation](/docs/cli/unikraft) -If you are getting started with Unikraft Cloud, use the **unikraft** CLI. -If you need Docker Compose-style workflows or building images from source, use the **kraft cloud** CLI. +Looking for the legacy `kraft cloud` CLI? +See the [Kraft cloud CLI (legacy)](/docs/cli/legacy-overview) page for installation instructions. From 5f4d2860298371f47a32675bb891971380eb1261 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Mon, 27 Apr 2026 13:08:34 +0100 Subject: [PATCH 101/131] feat: Publish markdown pages as well Signed-off-by: Justin Chadwell --- zudoku.config.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/zudoku.config.tsx b/zudoku.config.tsx index cd4d7ce4..94ffd513 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -23,6 +23,7 @@ const config: ZudokuConfig = { url: "https://github.com/unikraft-cloud/docs/edit/prod-stable/{filePath}", }, }, + publishMarkdown: true, llms: { llmsTxt: true, // Generate llms.txt llmsTxtFull: true, // Generate llms-full.txt From 09a12deaf3ceefa593cd32dfe604b276e3bcd20b Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Mon, 27 Apr 2026 14:04:14 +0100 Subject: [PATCH 102/131] chore: Update CLI sidebar Include the registries page, and rename the overview page for easier navigation. Signed-off-by: Justin Chadwell --- pages/cli/overview.mdx | 3 ++- zudoku.config.tsx | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pages/cli/overview.mdx b/pages/cli/overview.mdx index 5209594b..a84cfd4a 100644 --- a/pages/cli/overview.mdx +++ b/pages/cli/overview.mdx @@ -1,6 +1,7 @@ --- -title: CLI Overview +title: Overview description: Command-line interfaces for Unikraft Cloud +navigation_icon: book-open --- The **unikraft** CLI is the new, official command-line interface for [Unikraft Cloud](https://unikraft.cloud). diff --git a/zudoku.config.tsx b/zudoku.config.tsx index cd4d7ce4..c49878cf 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -216,6 +216,15 @@ const config: ZudokuConfig = { icon: "terminal", items: [ "/cli/overview", + { + type: "category", + label: "Concepts", + icon: "lightbulb", + collapsed: false, + items: [ + "/cli/registries", + ], + }, { type: "category", label: "unikraft", From 82f29d4da78ebc0ef52902948f2bdde5c4c9eda3 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Mon, 27 Apr 2026 14:08:13 +0100 Subject: [PATCH 103/131] feat: Add cli filter docs Signed-off-by: Justin Chadwell --- pages/cli/filters.mdx | 163 ++++++++++++++++++++++++++++++++++++++++++ zudoku.config.tsx | 1 + 2 files changed, 164 insertions(+) create mode 100644 pages/cli/filters.mdx diff --git a/pages/cli/filters.mdx b/pages/cli/filters.mdx new file mode 100644 index 00000000..720860de --- /dev/null +++ b/pages/cli/filters.mdx @@ -0,0 +1,163 @@ +--- +title: Filters +description: Filter expression language for the --filter and --until flags +navigation_icon: filter +--- + +The `unikraft` CLI's `--filter` and `--until` flags accept filter expressions that match resources based on their field values. +These flags are available on `list`, `wait`, and `delete` subcommands throughout the `unikraft` CLI. +They aren't available in the legacy `kraft cloud` CLI. + +The syntax extends the [containerd filter grammar](https://github.com/containerd/containerd/blob/main/pkg/filters/filter.go) with negated regex matching, wildcards, and alternative quoting. + +## Grammar + +``` +expression := selector ( "," selector )* +selector := fieldpath [ operator value ] + | fieldpath? "*" ( "." selector | operator value )? +fieldpath := field ( "." field )* +field := quoted-string | identifier +identifier := [A-Za-z] [A-Za-z0-9_]+ +operator := "=" | "==" | "!=" | "!==" | "~=" | "!~=" +value := quoted-string | regex-string | unquoted-string +``` + +A **quoted-string** uses Go string syntax (double quotes with standard +backslash escapes: `\n`, `\t`, `\\`, `\"`, `\xNN`, `\uNNNN`, `\UNNNNNNNN`, +octal `\NNN`). + +A **regex-string** may only appear after `~=` or `!~=`. +You can delimit it with `/` or `|` instead of `"`, which is convenient when the pattern contains double-quotes or backslashes (for example, `name~=/[abc]{0,2}/` or `path~=|foo/bar|`). + +An **unquoted-string** is any run of non-whitespace, non-comma characters. + +## Operators + +| Operator | Alias | Description | Example | +| -------- | ----- | --------------------------------- | ----------------- | +| `==` | `=` | Equals | `state==running` | +| `!=` | `!==` | Not equals | `state!=stopped` | +| `~=` | | Matches regular expression | `name~="^web-.*"` | +| `!~=` | | Doesn't match regular expression | `name!~="^test-"` | +| _(none)_ | | Field is present and non-empty | `description` | + +Regular expressions use Go `regexp` syntax. + +## Field paths + +Fields use their output name (the name shown in `kv` or `table` output). +Nested fields use dot-separated paths. + +``` +name # top-level field +settings.bar # nested field +timestamps.created-at # hyphenated field name +labels."my complex key" # quoted path segment +``` + +### Wildcards + +A `*` in a field path iterates over all entries of a map or array field. +The wildcard can appear at any level, and you can chain wildcards. + +``` +labels.* # true if any label entry exists +labels.*==value # true if any label entry equals "value" +authors.*.email==a@b.com # true if any author's email matches +nested.*.*==true # double wildcard +``` + +**Negation semantics with wildcards:** positive operators (`==`, `~=`) match if +**any** entry meets the condition. +Negated operators (`!=`, `!~=`) match only if **all** entries meet the condition (that is, no entry matches the negated pattern). + +### Indexed access + +You can also access array elements by zero-based numeric index. + +``` +authors.0.name==Alice # first author's name +authors.1.email==b@b.com # second author's email +``` + +## Combining expressions + +### And (comma-separated within one flag) + +Comma-separated selectors within a single `--filter` value must **all** match for the filter to include a resource. + +```bash +--filter 'state==running,name~="^web"' +``` + +### Or (repeated flags) + +When you specify `--filter` several times, the filter includes a resource if it matches **any** of the expressions. + +```bash +--filter 'state==running' --filter 'state==stopped' +``` + +### Combining both operators + +The two mechanisms compose: + +```bash +--filter 'state==running,metro==fra0' --filter 'state==stopped,metro==was1' +``` + +This matches resources that are (running in fra0) **or** (stopped in was1). + +## The `--until` flag + +The `--until` flag uses the same expression syntax as `--filter`. +It's available on `wait` subcommands (and aliases to `--filter` there). +The command polls until every targeted resource matches the expression. + +```bash +unikraft instance wait my-instance --until state==running +``` + +## Special fields + +The `metro` field receives special handling: when present in a filter, it restricts which metros the CLI queries rather than filtering results after the fact. +This means `--filter metro==fra0` avoids fetching data from other metros entirely. + +## Examples + +```bash +# List only running instances +unikraft instance list --filter state==running + +# List instances NOT in the "stopped" state +unikraft instance list --filter 'state!=stopped' + +# List images whose ref contains "nginx" +unikraft image list --filter 'ref~="/nginx"' + +# Exclude images matching a pattern +unikraft image list --filter 'ref!~="test"' + +# Regex with slash delimiters (avoids escaping issues) +unikraft image list --filter 'ref~=/nginx[0-9]{1,3}/' + +# Wait for an instance to reach the running state +unikraft instance wait my-instance --until state==running + +# Delete all stopped instances (with confirmation) +unikraft instance remove --filter state==stopped + +# Combine filters: running instances in fra0, OR stopped in was1 +unikraft instance list --filter 'state==running,metro==fra0' \ + --filter 'state==stopped,metro==was1' + +# Filter on nested fields +unikraft instance list --filter 'settings.autoscale==true' + +# Filter using array wildcard +unikraft instance list --filter 'volumes.*.name==data' + +# Check that no label matches a pattern (all must satisfy !=) +unikraft instance list --filter 'labels.*!=temporary' +``` diff --git a/zudoku.config.tsx b/zudoku.config.tsx index c49878cf..d8ddb55c 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -223,6 +223,7 @@ const config: ZudokuConfig = { collapsed: false, items: [ "/cli/registries", + "/cli/filters", ], }, { From a45df9e4a0c1fe0d1596c844dfdc095010dabad2 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Wed, 29 Apr 2026 09:47:07 +0100 Subject: [PATCH 104/131] chore: Remove reference to public roadmap Signed-off-by: Justin Chadwell --- README.md | 1 - pages/integrations/kubernetes.mdx | 3 --- 2 files changed, 4 deletions(-) diff --git a/README.md b/README.md index 8091a6f1..a787c0f0 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ This repository contains the markdown contents of the documentation site at http ## Contributing to the docs Contributions to the documentation are welcome! -If you're looking to file an issue or bug report for anything other than these documentations, please [visit the roadmap](https://roadmap.unikraft.com/). ### Table of contents diff --git a/pages/integrations/kubernetes.mdx b/pages/integrations/kubernetes.mdx index fe5eb2f5..e1c9d13e 100644 --- a/pages/integrations/kubernetes.mdx +++ b/pages/integrations/kubernetes.mdx @@ -367,6 +367,3 @@ Kraftlet reads the following annotations from Pod and Service objects to configu |---|---|---|---| | `cloud.unikraft.v1.services/domain` | string | β€” | Custom domain for the Unikraft Cloud service. For multi-container pods, prefix with the container name (`cloud.unikraft.v1.services/domain.`) to set a per-container domain, or use the global annotation to derive `-` automatically. | -## Resources - -- See [Unikraft public roadmap](https://roadmap.unikraft.com) for planned features or to suggest use cases and ideas. From 4fad14f22369a7c26559bc1d61b48bf57cafac64 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Thu, 30 Apr 2026 11:01:43 +0100 Subject: [PATCH 105/131] feat: Add kraftfile docs tab Signed-off-by: Justin Chadwell --- Dockerfile | 3 +++ zudoku.config.tsx | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/Dockerfile b/Dockerfile index 06707d9a..9f39e146 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,6 +45,9 @@ COPY . . ARG DOCS_CHANNEL=prod-staging ADD https://raw.githubusercontent.com/unikraft-cloud/openapi/refs/heads/${DOCS_CHANNEL}/platform.yaml apis/platform.yaml +# Kraftfile v0.7 schema docs (from unikraft-cloud/x) +ADD https://raw.githubusercontent.com/unikraft-cloud/x/refs/heads/${DOCS_CHANNEL}/kraftfile/schema.md pages/kraftfile/v0.7.md + # Kraft (old CLI) docs -> /cli/kraft/ COPY --from=build-kraft-docs /kraftkit/docs/kraft/cloud /docs/pages/cli/kraft COPY --from=build-kraft-docs /kraftkit/docs/kraft/cloud.mdx /docs/pages/cli/kraft/overview.mdx diff --git a/zudoku.config.tsx b/zudoku.config.tsx index 639a39db..45fdbd67 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -479,6 +479,24 @@ const config: ZudokuConfig = { }, ], } as any, + { + type: "category", + label: "Kraftfile", + icon: "file-text", + items: [ + "/kraftfile/v0.7", + { + type: "link", + label: "Kraftfile Reference (v0.6)", + to: "https://unikraft.org/docs/cli/reference/kraftfile/v0.6", + }, + { + type: "link", + label: "Kraftfile Reference (v0.5)", + to: "https://unikraft.org/docs/cli/reference/kraftfile/v0.5", + }, + ], + } as any, { type: "link", label: "Platform API", @@ -492,6 +510,7 @@ const config: ZudokuConfig = { redirects: [ { from: "/", to: "/introduction" }, { from: "/cli", to: "/cli/overview" }, + { from: "/kraftfile", to: "/kraftfile/v0.7" }, { from: "/guides", to: "/guides/overview" }, ], apis: [ From 2baba81bfedd0262839fcb7d2220098f55546e4c Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Wed, 6 May 2026 10:03:14 +0100 Subject: [PATCH 106/131] chore: Update zudoku to version v0.77.0 Signed-off-by: Justin Chadwell --- package-lock.json | 998 ++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 516 insertions(+), 484 deletions(-) diff --git a/package-lock.json b/package-lock.json index a69ddd14..d1010efc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "react": ">=19.0.0", "react-dom": ">=19.0.0", "regex-utilities": "^2.3.0", - "zudoku": "^0.76.0" + "zudoku": "^0.77.0" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0", @@ -23,9 +23,9 @@ } }, "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-15.3.1.tgz", - "integrity": "sha512-FIweGOR9zrNuskfDXn8dfsA4eJEe8LmmGsGSDikEZvgYm36SO36yMhasXSOX7/OTGZ3b7I9iPhOxB24D8xL5uQ==", + "version": "15.3.5", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-15.3.5.tgz", + "integrity": "sha512-orNOYXw3hYXxxisXMldjzjBzqqTLBPbwOtHg7ovBPvfBHDue1qM9YJENZ3W2BQuS+7z4ThogMbEzEsov57Itkg==", "license": "MIT", "dependencies": { "js-yaml": "^4.1.1" @@ -179,9 +179,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", "cpu": [ "ppc64" ], @@ -195,9 +195,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", "cpu": [ "arm" ], @@ -211,9 +211,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", "cpu": [ "arm64" ], @@ -227,9 +227,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", "cpu": [ "x64" ], @@ -243,9 +243,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", "cpu": [ "arm64" ], @@ -259,9 +259,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", "cpu": [ "x64" ], @@ -275,9 +275,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", "cpu": [ "arm64" ], @@ -291,9 +291,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", "cpu": [ "x64" ], @@ -307,9 +307,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", "cpu": [ "arm" ], @@ -323,9 +323,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", "cpu": [ "arm64" ], @@ -339,9 +339,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", "cpu": [ "ia32" ], @@ -355,9 +355,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", "cpu": [ "loong64" ], @@ -371,9 +371,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", "cpu": [ "mips64el" ], @@ -387,9 +387,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", "cpu": [ "ppc64" ], @@ -403,9 +403,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", "cpu": [ "riscv64" ], @@ -419,9 +419,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", "cpu": [ "s390x" ], @@ -435,9 +435,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", "cpu": [ "x64" ], @@ -451,9 +451,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", "cpu": [ "arm64" ], @@ -467,9 +467,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", "cpu": [ "x64" ], @@ -483,9 +483,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", "cpu": [ "arm64" ], @@ -499,9 +499,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", "cpu": [ "x64" ], @@ -515,9 +515,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", "cpu": [ "arm64" ], @@ -531,9 +531,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", "cpu": [ "x64" ], @@ -547,9 +547,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", "cpu": [ "arm64" ], @@ -563,9 +563,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", "cpu": [ "ia32" ], @@ -579,9 +579,9 @@ } }, "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==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", "cpu": [ "x64" ], @@ -828,9 +828,9 @@ "license": "MIT" }, "node_modules/@fastify/otel": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/@fastify/otel/-/otel-0.16.0.tgz", - "integrity": "sha512-2304BdM5Q/kUvQC9qJO1KZq3Zn1WWsw+WWkVmFEaj1UE2hEIiuFqrPeglQOwEtw/ftngisqfQ3v70TWMmwhhHA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@fastify/otel/-/otel-0.18.0.tgz", + "integrity": "sha512-3TASCATfw+ctICSb4ymrv7iCm0qJ0N9CarB+CZ7zIJ7KqNbwI5JjyDL1/sxoC0ccTO1Zyd1iQ+oqncPg5FJXaA==", "funding": [ { "type": "github", @@ -844,18 +844,18 @@ "license": "MIT", "dependencies": { "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.208.0", + "@opentelemetry/instrumentation": "^0.212.0", "@opentelemetry/semantic-conventions": "^1.28.0", - "minimatch": "^10.0.3" + "minimatch": "^10.2.4" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0" } }, "node_modules/@fastify/otel/node_modules/@opentelemetry/api-logs": { - "version": "0.208.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.208.0.tgz", - "integrity": "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==", + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.212.0.tgz", + "integrity": "sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/api": "^1.3.0" @@ -865,13 +865,13 @@ } }, "node_modules/@fastify/otel/node_modules/@opentelemetry/instrumentation": { - "version": "0.208.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.208.0.tgz", - "integrity": "sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA==", + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.212.0.tgz", + "integrity": "sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/api-logs": "0.208.0", - "import-in-the-middle": "^2.0.0", + "@opentelemetry/api-logs": "0.212.0", + "import-in-the-middle": "^2.0.6", "require-in-the-middle": "^8.0.0" }, "engines": { @@ -881,6 +881,18 @@ "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@fastify/otel/node_modules/import-in-the-middle": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", + "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.15.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^2.2.0", + "module-details-from-path": "^1.0.4" + } + }, "node_modules/@floating-ui/core": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", @@ -1641,9 +1653,9 @@ } }, "node_modules/@opentelemetry/api-logs": { - "version": "0.211.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.211.0.tgz", - "integrity": "sha512-swFdZq8MCdmdR22jTVGQDhwqDzcI4M10nhjXkLr1EsIzXgZBqm4ZlmmcWsg3TSNf+3mzgOiqveXmBLZuDi2Lgg==", + "version": "0.214.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.214.0.tgz", + "integrity": "sha512-40lSJeqYO8Uz2Yj7u94/SJWE/wONa7rmMKjI1ZcIjgf3MHNHv1OZUCrCETGuaRF62d5pQD1wKIW+L4lmSMTzZA==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/api": "^1.3.0" @@ -1652,22 +1664,10 @@ "node": ">=8.0.0" } }, - "node_modules/@opentelemetry/context-async-hooks": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.6.1.tgz", - "integrity": "sha512-XHzhwRNkBpeP8Fs/qjGrAf9r9PRv67wkJQ/7ZPaBQQ68DYlTBBx5MF9LvPx7mhuXcDessKK2b+DcxqwpgkcivQ==", - "license": "Apache-2.0", - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" - } - }, "node_modules/@opentelemetry/core": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.6.1.tgz", - "integrity": "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.1.tgz", + "integrity": "sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" @@ -1680,13 +1680,13 @@ } }, "node_modules/@opentelemetry/instrumentation": { - "version": "0.211.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.211.0.tgz", - "integrity": "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q==", + "version": "0.214.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.214.0.tgz", + "integrity": "sha512-MHqEX5Dk59cqVah5LiARMACku7jXSVk9iVDWOea4x3cr7VfdByeDCURK6o1lntT1JS/Tsovw01UJrBhN3/uC5w==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/api-logs": "0.211.0", - "import-in-the-middle": "^2.0.0", + "@opentelemetry/api-logs": "0.214.0", + "import-in-the-middle": "^3.0.0", "require-in-the-middle": "^8.0.0" }, "engines": { @@ -1697,13 +1697,13 @@ } }, "node_modules/@opentelemetry/instrumentation-amqplib": { - "version": "0.58.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.58.0.tgz", - "integrity": "sha512-fjpQtH18J6GxzUZ+cwNhWUpb71u+DzT7rFkg5pLssDGaEber91Y2WNGdpVpwGivfEluMlNMZumzjEqfg8DeKXQ==", + "version": "0.61.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.61.0.tgz", + "integrity": "sha512-mCKoyTGfRNisge4br0NpOFSy2Z1NnEW8hbCJdUDdJFHrPqVzc4IIBPA/vX0U+LUcQqrQvJX+HMIU0dbDRe0i0Q==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.33.0" }, "engines": { @@ -1714,13 +1714,13 @@ } }, "node_modules/@opentelemetry/instrumentation-connect": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.54.0.tgz", - "integrity": "sha512-43RmbhUhqt3uuPnc16cX6NsxEASEtn8z/cYV8Zpt6EP4p2h9s4FNuJ4Q9BbEQ2C0YlCCB/2crO1ruVz/hWt8fA==", + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.57.0.tgz", + "integrity": "sha512-FMEBChnI4FLN5TE9DHwfH7QpNir1JzXno1uz/TAucVdLCyrG0jTrKIcNHt/i30A0M2AunNBCkcd8Ei26dIPKdg==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.27.0", "@types/connect": "3.4.38" }, @@ -1732,29 +1732,12 @@ } }, "node_modules/@opentelemetry/instrumentation-dataloader": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.28.0.tgz", - "integrity": "sha512-ExXGBp0sUj8yhm6Znhf9jmuOaGDsYfDES3gswZnKr4MCqoBWQdEFn6EoDdt5u+RdbxQER+t43FoUihEfTSqsjA==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-express": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.59.0.tgz", - "integrity": "sha512-pMKV/qnHiW/Q6pmbKkxt0eIhuNEtvJ7sUAyee192HErlr+a1Jx+FZ3WjfmzhQL1geewyGEiPGkmjjAgNY8TgDA==", + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.31.0.tgz", + "integrity": "sha512-f654tZFQXS5YeLDNb9KySrwtg7SnqZN119FauD7acBoTzuLduaiGTNz88ixcVSOOMGZ+EjJu/RFtx5klObC95g==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.211.0", - "@opentelemetry/semantic-conventions": "^1.27.0" + "@opentelemetry/instrumentation": "^0.214.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" @@ -1764,13 +1747,13 @@ } }, "node_modules/@opentelemetry/instrumentation-fs": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.30.0.tgz", - "integrity": "sha512-n3Cf8YhG7reaj5dncGlRIU7iT40bxPOjsBEA5Bc1a1g6e9Qvb+JFJ7SEiMlPbUw4PBmxE3h40ltE8LZ3zVt6OA==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.33.0.tgz", + "integrity": "sha512-sCZWXGalQ01wr3tAhSR9ucqFJ0phidpAle6/17HVjD6gN8FLmZMK/8sKxdXYHy3PbnlV1P4zeiSVFNKpbFMNLA==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.211.0" + "@opentelemetry/instrumentation": "^0.214.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" @@ -1780,12 +1763,12 @@ } }, "node_modules/@opentelemetry/instrumentation-generic-pool": { - "version": "0.54.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.54.0.tgz", - "integrity": "sha512-8dXMBzzmEdXfH/wjuRvcJnUFeWzZHUnExkmFJ2uPfa31wmpyBCMxO59yr8f/OXXgSogNgi/uPo9KW9H7LMIZ+g==", + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.57.0.tgz", + "integrity": "sha512-orhmlaK+ZIW9hKU+nHTbXrCSXZcH83AescTqmpamHRobRmYSQwRbD0a1odc0yAzuzOtxYiHiXAnpnIpaSSY7Ow==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0" + "@opentelemetry/instrumentation": "^0.214.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" @@ -1795,12 +1778,12 @@ } }, "node_modules/@opentelemetry/instrumentation-graphql": { - "version": "0.58.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.58.0.tgz", - "integrity": "sha512-+yWVVY7fxOs3j2RixCbvue8vUuJ1inHxN2q1sduqDB0Wnkr4vOzVKRYl/Zy7B31/dcPS72D9lo/kltdOTBM3bQ==", + "version": "0.62.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.62.0.tgz", + "integrity": "sha512-3YNuLVPUxafXkH1jBAbGsKNsP3XVzcFDhCDCE3OqBwCwShlqQbLMRMFh1T/d5jaVZiGVmSsfof+ICKD2iOV8xg==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0" + "@opentelemetry/instrumentation": "^0.214.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" @@ -1810,13 +1793,13 @@ } }, "node_modules/@opentelemetry/instrumentation-hapi": { - "version": "0.57.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.57.0.tgz", - "integrity": "sha512-Os4THbvls8cTQTVA8ApLfZZztuuqGEeqog0XUnyRW7QVF0d/vOVBEcBCk1pazPFmllXGEdNbbat8e2fYIWdFbw==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.60.0.tgz", + "integrity": "sha512-aNljZKYrEa7obLAxd1bCEDxF7kzCLGXTuTJZ8lMR9rIVEjmuKBXN1gfqpm/OB//Zc2zP4iIve1jBp7sr3mQV6w==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.27.0" }, "engines": { @@ -1827,13 +1810,13 @@ } }, "node_modules/@opentelemetry/instrumentation-http": { - "version": "0.211.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.211.0.tgz", - "integrity": "sha512-n0IaQ6oVll9PP84SjbOCwDjaJasWRHi6BLsbMLiT6tNj7QbVOkuA5sk/EfZczwI0j5uTKl1awQPivO/ldVtsqA==", + "version": "0.214.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.214.0.tgz", + "integrity": "sha512-FlkDhZDRjDJDcO2LcSCtjRpkal1NJ8y0fBqBhTvfAR3JSYY2jAIj1kSS5IjmEBt4c3aWv+u/lqLuoCDrrKCSKg==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "2.5.0", - "@opentelemetry/instrumentation": "0.211.0", + "@opentelemetry/core": "2.6.1", + "@opentelemetry/instrumentation": "0.214.0", "@opentelemetry/semantic-conventions": "^1.29.0", "forwarded-parse": "2.1.2" }, @@ -1845,9 +1828,9 @@ } }, "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/core": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", - "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.6.1.tgz", + "integrity": "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" @@ -1860,12 +1843,12 @@ } }, "node_modules/@opentelemetry/instrumentation-ioredis": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.59.0.tgz", - "integrity": "sha512-875UxzBHWkW+P4Y45SoFM2AR8f8TzBMD8eO7QXGCyFSCUMP5s9vtt/BS8b/r2kqLyaRPK6mLbdnZznK3XzQWvw==", + "version": "0.62.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.62.0.tgz", + "integrity": "sha512-ZYt//zcPve8qklaZX+5Z4MkU7UpEkFRrxsf2cnaKYBitqDnsCN69CPAuuMOX6NYdW2rG9sFy7V/QWtBlP5XiNQ==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/redis-common": "^0.38.2", "@opentelemetry/semantic-conventions": "^1.33.0" }, @@ -1877,12 +1860,12 @@ } }, "node_modules/@opentelemetry/instrumentation-kafkajs": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.20.0.tgz", - "integrity": "sha512-yJXOuWZROzj7WmYCUiyT27tIfqBrVtl1/TwVbQyWPz7rL0r1Lu7kWjD0PiVeTCIL6CrIZ7M2s8eBxsTAOxbNvw==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.23.0.tgz", + "integrity": "sha512-4K+nVo+zI+aDz0Z85SObwbdixIbzS9moIuKJaYsdlzcHYnKOPtB7ya8r8Ezivy/GVIBHiKJVq4tv+BEkgOMLaQ==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.30.0" }, "engines": { @@ -1893,12 +1876,12 @@ } }, "node_modules/@opentelemetry/instrumentation-knex": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.55.0.tgz", - "integrity": "sha512-FtTL5DUx5Ka/8VK6P1VwnlUXPa3nrb7REvm5ddLUIeXXq4tb9pKd+/ThB1xM/IjefkRSN3z8a5t7epYw1JLBJQ==", + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.58.0.tgz", + "integrity": "sha512-Hc/o8fSsaWxZ8r1Yw4rNDLwTpUopTf4X32y4W6UhlHmW8Wizz8wfhgOKIelSeqFVTKBBPIDUOsQWuIMxBmu8Bw==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.33.1" }, "engines": { @@ -1909,13 +1892,13 @@ } }, "node_modules/@opentelemetry/instrumentation-koa": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.59.0.tgz", - "integrity": "sha512-K9o2skADV20Skdu5tG2bogPKiSpXh4KxfLjz6FuqIVvDJNibwSdu5UvyyBzRVp1rQMV6UmoIk6d3PyPtJbaGSg==", + "version": "0.62.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.62.0.tgz", + "integrity": "sha512-uVip0VuGUQXZ+vFxkKxAUNq8qNl+VFlyHDh/U6IQ8COOEDfbEchdaHnpFrMYF3psZRUuoSIgb7xOeXj00RdwDA==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.36.0" }, "engines": { @@ -1926,12 +1909,12 @@ } }, "node_modules/@opentelemetry/instrumentation-lru-memoizer": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.55.0.tgz", - "integrity": "sha512-FDBfT7yDGcspN0Cxbu/k8A0Pp1Jhv/m7BMTzXGpcb8ENl3tDj/51U65R5lWzUH15GaZA15HQ5A5wtafklxYj7g==", + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.58.0.tgz", + "integrity": "sha512-6grM3TdMyHzlGY1cUA+mwoPueB1F3dYKgKtZIH6jOFXqfHAByyLTc+6PFjGM9tKh52CFBJaDwodNlL/Td39z7Q==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0" + "@opentelemetry/instrumentation": "^0.214.0" }, "engines": { "node": "^18.19.0 || >=20.6.0" @@ -1941,12 +1924,12 @@ } }, "node_modules/@opentelemetry/instrumentation-mongodb": { - "version": "0.64.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.64.0.tgz", - "integrity": "sha512-pFlCJjweTqVp7B220mCvCld1c1eYKZfQt1p3bxSbcReypKLJTwat+wbL2YZoX9jPi5X2O8tTKFEOahO5ehQGsA==", + "version": "0.67.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.67.0.tgz", + "integrity": "sha512-1WJp5N1lYfHq2IhECOTewFs5Tf2NfUOwQRqs/rZdXKTezArMlucxgzAaqcgp3A3YREXopXTpXHsxZTGHjNhMdQ==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.33.0" }, "engines": { @@ -1957,13 +1940,13 @@ } }, "node_modules/@opentelemetry/instrumentation-mongoose": { - "version": "0.57.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.57.0.tgz", - "integrity": "sha512-MthiekrU/BAJc5JZoZeJmo0OTX6ycJMiP6sMOSRTkvz5BrPMYDqaJos0OgsLPL/HpcgHP7eo5pduETuLguOqcg==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.60.0.tgz", + "integrity": "sha512-8BahAZpKsOoc+lrZGb7Ofn4g3z8qtp5IxDfvAVpKXsEheQN7ONMH5djT5ihy6yf8yyeQJGS0gXFfpEAEeEHqQg==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.33.0" }, "engines": { @@ -1974,12 +1957,12 @@ } }, "node_modules/@opentelemetry/instrumentation-mysql": { - "version": "0.57.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.57.0.tgz", - "integrity": "sha512-HFS/+FcZ6Q7piM7Il7CzQ4VHhJvGMJWjx7EgCkP5AnTntSN5rb5Xi3TkYJHBKeR27A0QqPlGaCITi93fUDs++Q==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.60.0.tgz", + "integrity": "sha512-08pO8GFPEIz2zquKDGteBZDNmwketdgH8hTe9rVYgW9kCJXq1Psj3wPQGx+VaX4ZJKCfPeoLMYup9+cxHvZyVQ==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.33.0", "@types/mysql": "2.15.27" }, @@ -1991,12 +1974,12 @@ } }, "node_modules/@opentelemetry/instrumentation-mysql2": { - "version": "0.57.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.57.0.tgz", - "integrity": "sha512-nHSrYAwF7+aV1E1V9yOOP9TchOodb6fjn4gFvdrdQXiRE7cMuffyLLbCZlZd4wsspBzVwOXX8mpURdRserAhNA==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.60.0.tgz", + "integrity": "sha512-m/5d3bxQALllCzezYDk/6vajh0tj5OijMMvOZGr+qN1NMXm1dzMNwyJ0gNZW7Fo3YFRyj/jJMxIw+W7d525dlw==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.33.0", "@opentelemetry/sql-common": "^0.41.2" }, @@ -2008,13 +1991,13 @@ } }, "node_modules/@opentelemetry/instrumentation-pg": { - "version": "0.63.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.63.0.tgz", - "integrity": "sha512-dKm/ODNN3GgIQVlbD6ZPxwRc3kleLf95hrRWXM+l8wYo+vSeXtEpQPT53afEf6VFWDVzJK55VGn8KMLtSve/cg==", + "version": "0.66.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.66.0.tgz", + "integrity": "sha512-KxfLGXBb7k2ueaPJfq2GXBDXBly8P+SpR/4Mj410hhNgmQF3sCqwXvUBQxZQkDAmsdBAoenM+yV1LhtsMRamcA==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.34.0", "@opentelemetry/sql-common": "^0.41.2", "@types/pg": "8.15.6", @@ -2028,12 +2011,12 @@ } }, "node_modules/@opentelemetry/instrumentation-redis": { - "version": "0.59.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.59.0.tgz", - "integrity": "sha512-JKv1KDDYA2chJ1PC3pLP+Q9ISMQk6h5ey+99mB57/ARk0vQPGZTTEb4h4/JlcEpy7AYT8HIGv7X6l+br03Neeg==", + "version": "0.62.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.62.0.tgz", + "integrity": "sha512-y3pPpot7WzR/8JtHcYlTYsyY8g+pbFhAqbwAuG5bLPnR6v6pt1rQc0DpH0OlGP/9CZbWBP+Zhwp9yFoygf/ZXQ==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/redis-common": "^0.38.2", "@opentelemetry/semantic-conventions": "^1.27.0" }, @@ -2045,12 +2028,12 @@ } }, "node_modules/@opentelemetry/instrumentation-tedious": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.30.0.tgz", - "integrity": "sha512-bZy9Q8jFdycKQ2pAsyuHYUHNmCxCOGdG6eg1Mn75RvQDccq832sU5OWOBnc12EFUELI6icJkhR7+EQKMBam2GA==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.33.0.tgz", + "integrity": "sha512-Q6WQwAD01MMTub31GlejoiFACYNw26J426wyjvU7by7fDIr2nZXNW4vhTGs7i7F0TnXBO3xN688g1tdUgYwJ5w==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.33.0", "@types/tedious": "^4.0.14" }, @@ -2062,13 +2045,13 @@ } }, "node_modules/@opentelemetry/instrumentation-undici": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.21.0.tgz", - "integrity": "sha512-gok0LPUOTz2FQ1YJMZzaHcOzDFyT64XJ8M9rNkugk923/p6lDGms/cRW1cqgqp6N6qcd6K6YdVHwPEhnx9BWbw==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.24.0.tgz", + "integrity": "sha512-oKzZ3uvqP17sV0EsoQcJgjEfIp0kiZRbYu/eD8p13Cbahumf8lb/xpYeNr/hfAJ4owzEtIDcGIjprfLcYbIKBQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation": "^0.214.0", "@opentelemetry/semantic-conventions": "^1.24.0" }, "engines": { @@ -2079,21 +2062,21 @@ } }, "node_modules/@opentelemetry/redis-common": { - "version": "0.38.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.2.tgz", - "integrity": "sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==", + "version": "0.38.3", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.3.tgz", + "integrity": "sha512-VCghU1JYs/4gP6Gqf/xro9MEsZ7LrMv2uONVsaESKL38ZOB9BqnI98FfS23wjMnHlpuE+TTaWSoAVNpTwYXzjw==", "license": "Apache-2.0", "engines": { "node": "^18.19.0 || >=20.6.0" } }, "node_modules/@opentelemetry/resources": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.6.1.tgz", - "integrity": "sha512-lID/vxSuKWXM55XhAKNoYXu9Cutoq5hFdkbTdI/zDKQktXzcWBVhNsOkiZFTMU9UtEWuGRNe0HUgmsFldIdxVA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.1.tgz", + "integrity": "sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "2.6.1", + "@opentelemetry/core": "2.7.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { @@ -2104,13 +2087,13 @@ } }, "node_modules/@opentelemetry/sdk-trace-base": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.6.1.tgz", - "integrity": "sha512-r86ut4T1e8vNwB35CqCcKd45yzqH6/6Wzvpk2/cZB8PsPLlZFTvrh8yfOS3CYZYcUmAx4hHTZJ8AO8Dj8nrdhw==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.7.1.tgz", + "integrity": "sha512-NAYIlsF8MPUsKqJMiDQJTMPOmlbawC1Iz/omMLygZ1C9am8fTKYjTaI+OZM+WTY3t3Glo0wnOg/6/pac6RGPPw==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "2.6.1", - "@opentelemetry/resources": "2.6.1", + "@opentelemetry/core": "2.7.1", + "@opentelemetry/resources": "2.7.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { @@ -2145,9 +2128,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.124.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz", - "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==", + "version": "0.126.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.126.0.tgz", + "integrity": "sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" @@ -2263,9 +2246,9 @@ } }, "node_modules/@prisma/instrumentation": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-7.2.0.tgz", - "integrity": "sha512-Rh9Z4x5kEj1OdARd7U18AtVrnL6rmLSI0qYShaB4W7Wx5BKbgzndWF+QnuzMb7GLfVdlT5aYCXoPQVYuYtVu0g==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-7.6.0.tgz", + "integrity": "sha512-ZPW2gRiwpPzEfgeZgaekhqXrbW+Y2RJKHVqUmlhZhKzRNCcvR6DykzylDrynpArKKRQtLxoZy36fK7U0p3pdgQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/instrumentation": "^0.207.0" @@ -2303,6 +2286,18 @@ "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@prisma/instrumentation/node_modules/import-in-the-middle": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", + "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.15.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^2.2.0", + "module-details-from-path": "^1.0.4" + } + }, "node_modules/@radix-ui/number": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", @@ -3868,9 +3863,9 @@ "license": "MIT" }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.16.tgz", + "integrity": "sha512-rhY3k7Bsae9qQfOtph2Pm2jZEA+s8Gmjoz4hhmx70K9iMQ/ddeae+xhRQcM5IuVx5ry1+bGfkvMn7D6MJggVSA==", "cpu": [ "arm64" ], @@ -3884,9 +3879,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.16.tgz", + "integrity": "sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ==", "cpu": [ "arm64" ], @@ -3900,9 +3895,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz", - "integrity": "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.16.tgz", + "integrity": "sha512-r/OmdR00HmD4i79Z//xO06uEPOq5hRXdhw7nzkxQxwSavs3PSHa1ijntdpOiZ2mzOQ3fVVu8C1M19FoNM+dMUQ==", "cpu": [ "x64" ], @@ -3916,9 +3911,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz", - "integrity": "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.16.tgz", + "integrity": "sha512-KcRE5w8h0OnjUatG8pldyD14/CQ5Phs1oxfR+3pKDjboHRo9+MkqQaiIZlZRpsxC15paeXme/I127tUa9TXJ6g==", "cpu": [ "x64" ], @@ -3932,9 +3927,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz", - "integrity": "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.16.tgz", + "integrity": "sha512-bT0guA1bpxEJ/ZhTRniQf7rNF8ybvXOuWbNIeLABaV5NGjx4EtOWBTSRGWFU9ZWVkPOZ+HNFP8RMcBokBiZ0Kg==", "cpu": [ "arm" ], @@ -3948,9 +3943,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.16.tgz", + "integrity": "sha512-+tHktCHWV8BDQSjemUqm/Jl/TPk3QObCTIjmdDy/nlupcujZghmKK2962LYrqFpWu+ai01AN/REOH3NEpqvYQg==", "cpu": [ "arm64" ], @@ -3967,9 +3962,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz", - "integrity": "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.16.tgz", + "integrity": "sha512-3fPzdREH806oRLxpTWW1Gt4tQHs0TitZFOECB2xzCFLPKnSOy90gwA7P29cksYilFO6XVRY1kzga0cL2nRjKPg==", "cpu": [ "arm64" ], @@ -3986,9 +3981,9 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.16.tgz", + "integrity": "sha512-EKwI1tSrLs7YVw+JPJT/G2dJQ1jl9qlTTTEG0V2Ok/RdOenRfBw2PQdLPyjhIu58ocdBfP7vIRN/pvMsPxs/AQ==", "cpu": [ "ppc64" ], @@ -4005,9 +4000,9 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.16.tgz", + "integrity": "sha512-Uknladnb3Sxqu6SEcqBldQyJUpk8NleooZEc0MbRBJ4inEhRYWZX0NJu12vNf2mqAq7gsofAxHrGghiUYjhaLQ==", "cpu": [ "s390x" ], @@ -4024,9 +4019,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz", - "integrity": "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.16.tgz", + "integrity": "sha512-FIb8+uG49sZBtLTn+zt1AJ20TqVcqWeSIyoVt0or7uAWesgKaHbiBh6OpA/k9v0LTt+PTrb1Lao133kP4uVxkg==", "cpu": [ "x64" ], @@ -4043,9 +4038,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz", - "integrity": "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.16.tgz", + "integrity": "sha512-RuERhF9/EgWxZEXYWCOaViUWHIboceK4/ivdtQ3R0T44NjLkIIlGIAVAuCddFxsZ7vnRHtNQUrt2vR2n2slB2w==", "cpu": [ "x64" ], @@ -4062,9 +4057,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz", - "integrity": "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.16.tgz", + "integrity": "sha512-mXcXnvd9GpazCxeUCCnZ2+YF7nut+ZOEbE4GtaiPtyY6AkhZWbK70y1KK3j+RDhjVq5+U8FySkKRb/+w0EeUwA==", "cpu": [ "arm64" ], @@ -4078,9 +4073,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz", - "integrity": "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.16.tgz", + "integrity": "sha512-3Q2KQxnC8IJOLqXmUMoYwyIPZU9hzRbnHaoV3Euz+VVnjZKcY8ktnNP8T9R4/GGQtb27C/UYKABxesKWb8lsvQ==", "cpu": [ "wasm32" ], @@ -4089,16 +4084,16 @@ "dependencies": { "@emnapi/core": "1.9.2", "@emnapi/runtime": "1.9.2", - "@napi-rs/wasm-runtime": "^1.1.3" + "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { - "node": ">=14.0.0" + "node": "^20.19.0 || >=22.12.0" } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz", - "integrity": "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.16.tgz", + "integrity": "sha512-tj7XRemQcOcFwv7qhpUxMTBbI5mWMlE4c1Omhg5+h8GuLXzyj8HviYgR+bB2DMDgRqUE+jiDleqSCRjx4aYk/Q==", "cpu": [ "arm64" ], @@ -4112,9 +4107,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz", - "integrity": "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.16.tgz", + "integrity": "sha512-PH5DRZT+F4f2PTXRXR8uJxnBq2po/xFtddyabTJVJs/ZYVHqXPEgNIr35IHTEa6bpa0Q8Awg+ymkTaGnKITw4g==", "cpu": [ "x64" ], @@ -4617,79 +4612,75 @@ } }, "node_modules/@sentry/core": { - "version": "10.42.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.42.0.tgz", - "integrity": "sha512-L4rMrXMqUKBanpjpMT+TuAVk6xAijz6AWM6RiEYpohAr7SGcCEc1/T0+Ep1eLV8+pwWacfU27OvELIyNeOnGzA==", + "version": "10.49.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.49.0.tgz", + "integrity": "sha512-UaFeum3LUM1mB0d67jvKnqId1yWQjyqmaDV6kWngG03x+jqXb08tJdGpSoxjXZe13jFBbiBL/wKDDYIK7rCK4g==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@sentry/node": { - "version": "10.42.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.42.0.tgz", - "integrity": "sha512-ZZfU3Fnni7Aj0lTX4e3QpY3UxK4FGuzfM20316UAJycBGnripm+sDHwcekPMGfLnk/FrN9wa1atspVlHvOI0WQ==", - "license": "MIT", - "dependencies": { - "@fastify/otel": "0.16.0", - "@opentelemetry/api": "^1.9.0", - "@opentelemetry/context-async-hooks": "^2.5.1", - "@opentelemetry/core": "^2.5.1", - "@opentelemetry/instrumentation": "^0.211.0", - "@opentelemetry/instrumentation-amqplib": "0.58.0", - "@opentelemetry/instrumentation-connect": "0.54.0", - "@opentelemetry/instrumentation-dataloader": "0.28.0", - "@opentelemetry/instrumentation-express": "0.59.0", - "@opentelemetry/instrumentation-fs": "0.30.0", - "@opentelemetry/instrumentation-generic-pool": "0.54.0", - "@opentelemetry/instrumentation-graphql": "0.58.0", - "@opentelemetry/instrumentation-hapi": "0.57.0", - "@opentelemetry/instrumentation-http": "0.211.0", - "@opentelemetry/instrumentation-ioredis": "0.59.0", - "@opentelemetry/instrumentation-kafkajs": "0.20.0", - "@opentelemetry/instrumentation-knex": "0.55.0", - "@opentelemetry/instrumentation-koa": "0.59.0", - "@opentelemetry/instrumentation-lru-memoizer": "0.55.0", - "@opentelemetry/instrumentation-mongodb": "0.64.0", - "@opentelemetry/instrumentation-mongoose": "0.57.0", - "@opentelemetry/instrumentation-mysql": "0.57.0", - "@opentelemetry/instrumentation-mysql2": "0.57.0", - "@opentelemetry/instrumentation-pg": "0.63.0", - "@opentelemetry/instrumentation-redis": "0.59.0", - "@opentelemetry/instrumentation-tedious": "0.30.0", - "@opentelemetry/instrumentation-undici": "0.21.0", - "@opentelemetry/resources": "^2.5.1", - "@opentelemetry/sdk-trace-base": "^2.5.1", - "@opentelemetry/semantic-conventions": "^1.39.0", - "@prisma/instrumentation": "7.2.0", - "@sentry/core": "10.42.0", - "@sentry/node-core": "10.42.0", - "@sentry/opentelemetry": "10.42.0", - "import-in-the-middle": "^2.0.6" + "version": "10.49.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.49.0.tgz", + "integrity": "sha512-xr+HXABCiO5mgAJRQxsXRdNOLO0+Ee6CvXAAIqovL2A1GlhxNWc5ooPWeIrrLDJ/KGyT8zI91O5scpVXdXs0uQ==", + "license": "MIT", + "dependencies": { + "@fastify/otel": "0.18.0", + "@opentelemetry/api": "^1.9.1", + "@opentelemetry/core": "^2.6.1", + "@opentelemetry/instrumentation": "^0.214.0", + "@opentelemetry/instrumentation-amqplib": "0.61.0", + "@opentelemetry/instrumentation-connect": "0.57.0", + "@opentelemetry/instrumentation-dataloader": "0.31.0", + "@opentelemetry/instrumentation-fs": "0.33.0", + "@opentelemetry/instrumentation-generic-pool": "0.57.0", + "@opentelemetry/instrumentation-graphql": "0.62.0", + "@opentelemetry/instrumentation-hapi": "0.60.0", + "@opentelemetry/instrumentation-http": "0.214.0", + "@opentelemetry/instrumentation-ioredis": "0.62.0", + "@opentelemetry/instrumentation-kafkajs": "0.23.0", + "@opentelemetry/instrumentation-knex": "0.58.0", + "@opentelemetry/instrumentation-koa": "0.62.0", + "@opentelemetry/instrumentation-lru-memoizer": "0.58.0", + "@opentelemetry/instrumentation-mongodb": "0.67.0", + "@opentelemetry/instrumentation-mongoose": "0.60.0", + "@opentelemetry/instrumentation-mysql": "0.60.0", + "@opentelemetry/instrumentation-mysql2": "0.60.0", + "@opentelemetry/instrumentation-pg": "0.66.0", + "@opentelemetry/instrumentation-redis": "0.62.0", + "@opentelemetry/instrumentation-tedious": "0.33.0", + "@opentelemetry/instrumentation-undici": "0.24.0", + "@opentelemetry/sdk-trace-base": "^2.6.1", + "@opentelemetry/semantic-conventions": "^1.40.0", + "@prisma/instrumentation": "7.6.0", + "@sentry/core": "10.49.0", + "@sentry/node-core": "10.49.0", + "@sentry/opentelemetry": "10.49.0", + "import-in-the-middle": "^3.0.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry/node-core": { - "version": "10.42.0", - "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.42.0.tgz", - "integrity": "sha512-9tf3fPV6M071aps72D+PEtdQPTuj+SuqO2+PpTfdPP5ZL4TTKYo3VK0li76SL+5wGdTFGV5qmsokHq9IRBA0iA==", + "version": "10.49.0", + "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.49.0.tgz", + "integrity": "sha512-7WO0KuCDPSq3G54TVUSI1CKFJwB67LasG+n/gDMBqbrarzs/Yh/s34OOMU5gfVQpncxQAmQsy4nEboQms8iNqA==", "license": "MIT", "dependencies": { - "@sentry/core": "10.42.0", - "@sentry/opentelemetry": "10.42.0", - "import-in-the-middle": "^2.0.6" + "@sentry/core": "10.49.0", + "@sentry/opentelemetry": "10.49.0", + "import-in-the-middle": "^3.0.0" }, "engines": { "node": ">=18" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", - "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0", + "@opentelemetry/exporter-trace-otlp-http": ">=0.57.0 <1", "@opentelemetry/instrumentation": ">=0.57.1 <1", - "@opentelemetry/resources": "^1.30.1 || ^2.1.0", "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", "@opentelemetry/semantic-conventions": "^1.39.0" }, @@ -4697,16 +4688,13 @@ "@opentelemetry/api": { "optional": true }, - "@opentelemetry/context-async-hooks": { - "optional": true - }, "@opentelemetry/core": { "optional": true }, - "@opentelemetry/instrumentation": { + "@opentelemetry/exporter-trace-otlp-http": { "optional": true }, - "@opentelemetry/resources": { + "@opentelemetry/instrumentation": { "optional": true }, "@opentelemetry/sdk-trace-base": { @@ -4718,107 +4706,145 @@ } }, "node_modules/@sentry/opentelemetry": { - "version": "10.42.0", - "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.42.0.tgz", - "integrity": "sha512-5vsYz683iihzlIj3sT1+tEixf0awwXK86a+aYsnMHrTXJDrkBDq4U0ZT+yxdPfJlkaxRtYycFR08SXr2pSm7Eg==", + "version": "10.49.0", + "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.49.0.tgz", + "integrity": "sha512-XNLm4dXmtegXQf+EEE2Cs84Ymlo/f5wMx+lg2S2XS4qLbXaPN/HttjhwKftd8D+8iUNfmH+xNMCSshx4s1B/1w==", "license": "MIT", "dependencies": { - "@sentry/core": "10.42.0" + "@sentry/core": "10.49.0" }, "engines": { "node": ">=18" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", - "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0", "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", "@opentelemetry/semantic-conventions": "^1.39.0" } }, "node_modules/@shikijs/core": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.23.0.tgz", - "integrity": "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.0.2.tgz", + "integrity": "sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.23.0", + "@shikijs/primitive": "4.0.2", + "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" + }, + "engines": { + "node": ">=20" } }, "node_modules/@shikijs/engine-javascript": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.23.0.tgz", - "integrity": "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.0.2.tgz", + "integrity": "sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.23.0", + "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" + }, + "engines": { + "node": ">=20" } }, "node_modules/@shikijs/engine-oniguruma": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", - "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.0.2.tgz", + "integrity": "sha512-UpCB9Y2sUKlS9z8juFSKz7ZtysmeXCgnRF0dlhXBkmQnek7lAToPte8DkxmEYGNTMii72zU/lyXiCB6StuZeJg==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.23.0", + "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2" + }, + "engines": { + "node": ">=20" } }, "node_modules/@shikijs/langs": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz", - "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.0.2.tgz", + "integrity": "sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.0.2" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/primitive": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.0.2.tgz", + "integrity": "sha512-M6UMPrSa3fN5ayeJwFVl9qWofl273wtK1VG8ySDZ1mQBfhCpdd8nEx7nPZ/tk7k+TYcpqBZzj/AnwxT9lO+HJw==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.23.0" + "@shikijs/types": "4.0.2", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + }, + "engines": { + "node": ">=20" } }, "node_modules/@shikijs/rehype": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/rehype/-/rehype-3.23.0.tgz", - "integrity": "sha512-GepKJxXHbXFfAkiZZZ+4V7x71Lw3s0ALYmydUxJRdvpKjSx9FOMSaunv6WRLFBXR6qjYerUq1YZQno+2gLEPwA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/rehype/-/rehype-4.0.2.tgz", + "integrity": "sha512-cmPlKLD8JeojasNFoY64162ScpEdEdQUMuVodPCrv1nx1z3bjmGwoKWDruQWa/ejSznImlaeB0Ty6Q3zPaVQAA==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.23.0", + "@shikijs/types": "4.0.2", "@types/hast": "^3.0.4", "hast-util-to-string": "^3.0.1", - "shiki": "3.23.0", + "shiki": "4.0.2", "unified": "^11.0.5", "unist-util-visit": "^5.1.0" + }, + "engines": { + "node": ">=20" } }, "node_modules/@shikijs/themes": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz", - "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.0.2.tgz", + "integrity": "sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.23.0" + "@shikijs/types": "4.0.2" + }, + "engines": { + "node": ">=20" } }, "node_modules/@shikijs/transformers": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-3.23.0.tgz", - "integrity": "sha512-F9msZVxdF+krQNSdQ4V+Ja5QemeAoTQ2jxt7nJCwhDsdF1JWS3KxIQXA3lQbyKwS3J61oHRUSv4jYWv3CkaKTQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-4.0.2.tgz", + "integrity": "sha512-1+L0gf9v+SdDXs08vjaLb3mBFa8U7u37cwcBQIv/HCocLwX69Tt6LpUCjtB+UUTvQxI7BnjZKhN/wMjhHBcJGg==", "license": "MIT", "dependencies": { - "@shikijs/core": "3.23.0", - "@shikijs/types": "3.23.0" + "@shikijs/core": "4.0.2", + "@shikijs/types": "4.0.2" + }, + "engines": { + "node": ">=20" } }, "node_modules/@shikijs/types": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz", - "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.0.2.tgz", + "integrity": "sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg==", "license": "MIT", "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" + }, + "engines": { + "node": ">=20" } }, "node_modules/@shikijs/vscode-textmate": { @@ -6417,9 +6443,9 @@ } }, "node_modules/esbuild": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", - "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -6429,32 +6455,32 @@ "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" + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" } }, "node_modules/escalade": { @@ -7653,15 +7679,18 @@ } }, "node_modules/import-in-the-middle": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", - "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.0.1.tgz", + "integrity": "sha512-pYkiyXVL2Mf3pozdlDGV6NAObxQx13Ae8knZk1UJRJ6uRW/ZRmTGHlQYtrsSl7ubuE5F8CD1z+s1n4RHNuTtuA==", "license": "Apache-2.0", "dependencies": { "acorn": "^8.15.0", "acorn-import-attributes": "^1.9.5", "cjs-module-lexer": "^2.2.0", "module-details-from-path": "^1.0.4" + }, + "engines": { + "node": ">=18" } }, "node_modules/imurmurhash": { @@ -8254,9 +8283,9 @@ } }, "node_modules/lucide-react": { - "version": "0.577.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.577.0.tgz", - "integrity": "sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.8.0.tgz", + "integrity": "sha512-WuvlsjngSk7TnTBJ1hsCy3ql9V9VOdcPkd3PKcSmM34vJD8KG6molxz7m7zbYFgICwsanQWmJ13JlYs4Zp7Arw==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -9523,18 +9552,18 @@ } }, "node_modules/oniguruma-parser": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", - "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz", + "integrity": "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==", "license": "MIT" }, "node_modules/oniguruma-to-es": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.5.tgz", - "integrity": "sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.6.tgz", + "integrity": "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==", "license": "MIT", "dependencies": { - "oniguruma-parser": "^0.12.1", + "oniguruma-parser": "^0.12.2", "regex": "^6.1.0", "regex-recursion": "^6.0.2" } @@ -10076,9 +10105,9 @@ } }, "node_modules/react-router": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz", - "integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.1.tgz", + "integrity": "sha512-5BCvFskyAAVumqhEKh/iPhLOIkfxcEUz8WqFIARCkMg8hZZzDYX9CtwxXA0e+qT8zAxmMC0x3Ckb9iMONwc5jg==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -10548,13 +10577,13 @@ } }, "node_modules/rolldown": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.15.tgz", - "integrity": "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.16.tgz", + "integrity": "sha512-rzi5WqKzEZw3SooTt7cgm4eqIoujPIyGcJNGFL7iPEuajQw7vxMHUkXylu4/vhCkJGXsgRmxqMKXUpT6FEgl0g==", "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.124.0", - "@rolldown/pluginutils": "1.0.0-rc.15" + "@oxc-project/types": "=0.126.0", + "@rolldown/pluginutils": "1.0.0-rc.16" }, "bin": { "rolldown": "bin/cli.mjs" @@ -10563,27 +10592,27 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0-rc.15", - "@rolldown/binding-darwin-arm64": "1.0.0-rc.15", - "@rolldown/binding-darwin-x64": "1.0.0-rc.15", - "@rolldown/binding-freebsd-x64": "1.0.0-rc.15", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15", - "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15", - "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15", - "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15", - "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15", - "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15" + "@rolldown/binding-android-arm64": "1.0.0-rc.16", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.16", + "@rolldown/binding-darwin-x64": "1.0.0-rc.16", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.16", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.16", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.16", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.16", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.16", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.16", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.16", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.16", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.16", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.16", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.16", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.16" } }, "node_modules/rolldown/node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.15", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz", - "integrity": "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==", + "version": "1.0.0-rc.16", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.16.tgz", + "integrity": "sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA==", "license": "MIT" }, "node_modules/rollup": { @@ -10720,19 +10749,22 @@ } }, "node_modules/shiki": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.23.0.tgz", - "integrity": "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.0.2.tgz", + "integrity": "sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ==", "license": "MIT", "dependencies": { - "@shikijs/core": "3.23.0", - "@shikijs/engine-javascript": "3.23.0", - "@shikijs/engine-oniguruma": "3.23.0", - "@shikijs/langs": "3.23.0", - "@shikijs/themes": "3.23.0", - "@shikijs/types": "3.23.0", + "@shikijs/core": "4.0.2", + "@shikijs/engine-javascript": "4.0.2", + "@shikijs/engine-oniguruma": "4.0.2", + "@shikijs/langs": "4.0.2", + "@shikijs/themes": "4.0.2", + "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" + }, + "engines": { + "node": ">=20" } }, "node_modules/side-channel": { @@ -11018,13 +11050,13 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -11417,16 +11449,16 @@ } }, "node_modules/vite": { - "version": "8.0.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.8.tgz", - "integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==", + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.9.tgz", + "integrity": "sha512-t7g7GVRpMXjNpa67HaVWI/8BWtdVIQPCL2WoozXXA7LBGEFK4AkkKkHx2hAQf5x1GZSlcmEDPkVLSGahxnEEZw==", "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", - "postcss": "^8.5.8", - "rolldown": "1.0.0-rc.15", - "tinyglobby": "^0.2.15" + "postcss": "^8.5.10", + "rolldown": "1.0.0-rc.16", + "tinyglobby": "^0.2.16" }, "bin": { "vite": "bin/vite.js" @@ -11627,11 +11659,11 @@ } }, "node_modules/zudoku": { - "version": "0.76.0", - "resolved": "https://registry.npmjs.org/zudoku/-/zudoku-0.76.0.tgz", - "integrity": "sha512-8OdEQ7153hmBmszbKJGyPmr2vapZ7nvGsFmC/YDpkUU6rYghJBVWkV0DRWPGhHLAM3820QxtrILnBxLyVP/eNw==", + "version": "0.77.0", + "resolved": "https://registry.npmjs.org/zudoku/-/zudoku-0.77.0.tgz", + "integrity": "sha512-3zFmWFCYejA8GND904r902zrU11f4A1xsYnKIXOLXnllHwGZCU8rYjyW5cViUFs6bMEN2aN2kOJ13HKNxwfo8Q==", "dependencies": { - "@apidevtools/json-schema-ref-parser": "15.3.1", + "@apidevtools/json-schema-ref-parser": "15.3.5", "@base-ui/react": "^1.4.0", "@envelop/core": "5.5.1", "@graphql-typed-document-node/core": "3.2.0", @@ -11665,11 +11697,11 @@ "@radix-ui/react-tooltip": "1.2.8", "@radix-ui/react-visually-hidden": "1.2.4", "@scalar/openapi-parser": "0.23.13", - "@sentry/node": "10.42.0", - "@shikijs/langs": "3.23.0", - "@shikijs/rehype": "3.23.0", - "@shikijs/themes": "3.23.0", - "@shikijs/transformers": "3.23.0", + "@sentry/node": "10.49.0", + "@shikijs/langs": "4.0.2", + "@shikijs/rehype": "4.0.2", + "@shikijs/themes": "4.0.2", + "@shikijs/transformers": "4.0.2", "@tailwindcss/typography": "0.5.19", "@tailwindcss/vite": "4.2.2", "@tanem/react-nprogress": "6.0.3", @@ -11687,7 +11719,7 @@ "cmdk": "1.1.1", "dotenv": "17.3.1", "embla-carousel-react": "8.6.0", - "esbuild": "^0.27.4", + "esbuild": "^0.28.0", "estree-util-is-identifier-name": "3.0.0", "estree-util-value-to-estree": "3.5.0", "fast-equals": "6.0.0", @@ -11705,7 +11737,7 @@ "javascript-stringify": "2.1.0", "json-schema-to-typescript-lite": "15.0.0", "loglevel": "1.9.2", - "lucide-react": "0.577.0", + "lucide-react": "1.8.0", "mdast-util-from-markdown": "2.0.2", "mdast-util-mdx": "3.0.0", "mdast-util-mdx-jsx": "3.2.0", @@ -11723,7 +11755,7 @@ "react-hook-form": "7.71.2", "react-is": "19.2.5", "react-markdown": "10.1.0", - "react-router": "7.13.0", + "react-router": "7.14.1", "rehype-mdx-import-media": "1.2.0", "rehype-raw": "7.0.0", "rehype-slug": "6.0.0", @@ -11734,7 +11766,7 @@ "remark-gfm": "4.0.1", "remark-mdx-frontmatter": "5.2.0", "semver": "7.7.4", - "shiki": "3.23.0", + "shiki": "4.0.2", "sitemap": "9.0.1", "strip-ansi": "7.2.0", "tailwind-merge": "3.5.0", @@ -11744,7 +11776,7 @@ "unist-util-visit": "5.1.0", "vaul": "1.1.2", "vfile": "6.0.3", - "vite": "8.0.8", + "vite": "8.0.9", "yaml": "2.8.3", "yargs": "18.0.0", "zod": "4.3.6", diff --git a/package.json b/package.json index 501fa2b6..adf84137 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "react": ">=19.0.0", "react-dom": ">=19.0.0", "regex-utilities": "^2.3.0", - "zudoku": "^0.76.0" + "zudoku": "^0.77.0" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0", From a467758de06c2d32eac0e70ef10d2d9347f7e4ef Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Wed, 6 May 2026 14:11:12 +0100 Subject: [PATCH 107/131] chore: Switch to using pnpm This is already what we're using for www. But we just weren't using them in this repo, so we couldn't use all the cool functionality here. Signed-off-by: Justin Chadwell --- Dockerfile | 13 +- package-lock.json | 11855 -------------------------------------------- pnpm-lock.yaml | 8010 ++++++++++++++++++++++++++++++ 3 files changed, 8020 insertions(+), 11858 deletions(-) delete mode 100644 package-lock.json create mode 100644 pnpm-lock.yaml diff --git a/Dockerfile b/Dockerfile index 06707d9a..b0c13f06 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,6 +27,7 @@ FROM node:24-alpine AS build WORKDIR /docs ENV CI=true +ENV PNPM_HOME="/pnpm" RUN set -xe; \ apk --no-cache add \ @@ -35,9 +36,15 @@ RUN set -xe; \ wget \ ; -COPY package.json package-lock.json ./ +RUN set -xe; \ + corepack enable; \ + corepack prepare pnpm@latest --activate + +COPY package.json pnpm-lock.yaml ./ -RUN npm ci +RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ + pnpm install --prefer-frozen-lockfile; \ + pnpm install --prod --prefer-frozen-lockfile COPY . . @@ -53,7 +60,7 @@ COPY --from=build-kraft-docs /kraftkit/docs/kraft/cloud.mdx /docs/pages/cli/kraf COPY --from=build-cli-docs /cli/dist/docs/mdx/unikraft/ /docs/pages/cli/unikraft/ COPY --from=build-cli-docs /cli/dist/docs/mdx/unikraft.mdx /docs/pages/cli/unikraft.mdx -RUN npm run build +RUN pnpm run build ################################################################################ # Production filesystem diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index d1010efc..00000000 --- a/package-lock.json +++ /dev/null @@ -1,11855 +0,0 @@ -{ - "name": "docs", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "docs", - "version": "0.1.0", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "hast-util-to-html": "^9.0.5", - "oniguruma-parser": "^0.12.1", - "react": ">=19.0.0", - "react-dom": ">=19.0.0", - "regex-utilities": "^2.3.0", - "zudoku": "^0.77.0" - }, - "devDependencies": { - "@typescript-eslint/eslint-plugin": "^8.0.0", - "@typescript-eslint/parser": "^8.0.0", - "eslint": "^9.14.0" - } - }, - "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "15.3.5", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-15.3.5.tgz", - "integrity": "sha512-orNOYXw3hYXxxisXMldjzjBzqqTLBPbwOtHg7ovBPvfBHDue1qM9YJENZ3W2BQuS+7z4ThogMbEzEsov57Itkg==", - "license": "MIT", - "dependencies": { - "js-yaml": "^4.1.1" - }, - "engines": { - "node": ">=20" - }, - "peerDependencies": { - "@types/json-schema": "^7.0.15" - } - }, - "node_modules/@babel/runtime": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", - "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@base-ui/react": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@base-ui/react/-/react-1.4.1.tgz", - "integrity": "sha512-Ab5/LIhcmL8BQcsBUYiOfkSDRdLpvgUBzMK30cu684JPcLclYlztharvCZyNNgzJtbAiREzI9q0pI5erHCMgCw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.29.2", - "@base-ui/utils": "0.2.8", - "@floating-ui/react-dom": "^2.1.8", - "@floating-ui/utils": "^0.2.11", - "use-sync-external-store": "^1.6.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@date-fns/tz": "^1.2.0", - "@types/react": "^17 || ^18 || ^19", - "date-fns": "^4.0.0", - "react": "^17 || ^18 || ^19", - "react-dom": "^17 || ^18 || ^19" - }, - "peerDependenciesMeta": { - "@date-fns/tz": { - "optional": true - }, - "@types/react": { - "optional": true - }, - "date-fns": { - "optional": true - } - } - }, - "node_modules/@base-ui/utils": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@base-ui/utils/-/utils-0.2.8.tgz", - "integrity": "sha512-jvOi+c+ftGlGotNcKnzPVg2IhCaDTB6/6R3JeqdjdXktuAJi3wKH9T7+svuaKh1mmfVU11UWzUZVH74JDfi/wQ==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.29.2", - "@floating-ui/utils": "^0.2.11", - "reselect": "^5.1.1", - "use-sync-external-store": "^1.6.0" - }, - "peerDependencies": { - "@types/react": "^17 || ^18 || ^19", - "react": "^17 || ^18 || ^19", - "react-dom": "^17 || ^18 || ^19" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emnapi/core": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", - "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", - "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@envelop/core": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@envelop/core/-/core-5.5.1.tgz", - "integrity": "sha512-3DQg8sFskDo386TkL5j12jyRAdip/8yzK3x7YGbZBgobZ4aKXrvDU0GppU0SnmrpQnNaiTUsxBs9LKkwQ/eyvw==", - "license": "MIT", - "dependencies": { - "@envelop/instrumentation": "^1.0.0", - "@envelop/types": "^5.2.1", - "@whatwg-node/promise-helpers": "^1.2.4", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@envelop/instrumentation": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@envelop/instrumentation/-/instrumentation-1.0.0.tgz", - "integrity": "sha512-cxgkB66RQB95H3X27jlnxCRNTmPuSTgmBAq6/4n2Dtv4hsk4yz8FadA1ggmd0uZzvKqWD6CR+WFgTjhDqg7eyw==", - "license": "MIT", - "dependencies": { - "@whatwg-node/promise-helpers": "^1.2.1", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@envelop/types": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@envelop/types/-/types-5.2.1.tgz", - "integrity": "sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg==", - "license": "MIT", - "dependencies": { - "@whatwg-node/promise-helpers": "^1.0.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", - "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", - "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", - "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", - "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", - "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", - "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", - "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", - "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", - "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", - "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", - "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", - "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", - "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", - "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", - "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", - "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", - "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", - "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", - "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", - "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", - "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", - "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", - "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", - "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", - "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", - "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", - "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/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-array/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/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/config-array/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/@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/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", - "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/@eslint/eslintrc/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/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/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/@eslint/eslintrc/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/@eslint/eslintrc/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/@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/@fastify/busboy": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.2.0.tgz", - "integrity": "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==", - "license": "MIT" - }, - "node_modules/@fastify/otel": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@fastify/otel/-/otel-0.18.0.tgz", - "integrity": "sha512-3TASCATfw+ctICSb4ymrv7iCm0qJ0N9CarB+CZ7zIJ7KqNbwI5JjyDL1/sxoC0ccTO1Zyd1iQ+oqncPg5FJXaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "MIT", - "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.212.0", - "@opentelemetry/semantic-conventions": "^1.28.0", - "minimatch": "^10.2.4" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0" - } - }, - "node_modules/@fastify/otel/node_modules/@opentelemetry/api-logs": { - "version": "0.212.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.212.0.tgz", - "integrity": "sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api": "^1.3.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@fastify/otel/node_modules/@opentelemetry/instrumentation": { - "version": "0.212.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.212.0.tgz", - "integrity": "sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api-logs": "0.212.0", - "import-in-the-middle": "^2.0.6", - "require-in-the-middle": "^8.0.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@fastify/otel/node_modules/import-in-the-middle": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", - "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", - "license": "Apache-2.0", - "dependencies": { - "acorn": "^8.15.0", - "acorn-import-attributes": "^1.9.5", - "cjs-module-lexer": "^2.2.0", - "module-details-from-path": "^1.0.4" - } - }, - "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/@graphql-tools/executor": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.5.1.tgz", - "integrity": "sha512-n94Qcu875Mji9GQ52n5UbgOTxlgvFJicBPYD+FRks9HKIQpdNPjkkrKZUYNG51XKa+bf03rxNflm4+wXhoHHrA==", - "license": "MIT", - "dependencies": { - "@graphql-tools/utils": "^11.0.0", - "@graphql-typed-document-node/core": "^3.2.0", - "@repeaterjs/repeater": "^3.0.4", - "@whatwg-node/disposablestack": "^0.0.6", - "@whatwg-node/promise-helpers": "^1.0.0", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-tools/executor/node_modules/@graphql-tools/utils": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-11.0.0.tgz", - "integrity": "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA==", - "license": "MIT", - "dependencies": { - "@graphql-typed-document-node/core": "^3.1.1", - "@whatwg-node/promise-helpers": "^1.0.0", - "cross-inspect": "1.0.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-tools/merge": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.1.7.tgz", - "integrity": "sha512-Y5E1vTbTabvcXbkakdFUt4zUIzB1fyaEnVmIWN0l0GMed2gdD01TpZWLUm4RNAxpturvolrb24oGLQrBbPLSoQ==", - "license": "MIT", - "dependencies": { - "@graphql-tools/utils": "^11.0.0", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-tools/merge/node_modules/@graphql-tools/utils": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-11.0.0.tgz", - "integrity": "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA==", - "license": "MIT", - "dependencies": { - "@graphql-typed-document-node/core": "^3.1.1", - "@whatwg-node/promise-helpers": "^1.0.0", - "cross-inspect": "1.0.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-tools/schema": { - "version": "10.0.31", - "resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.31.tgz", - "integrity": "sha512-ZewRgWhXef6weZ0WiP7/MV47HXiuFbFpiDUVLQl6mgXsWSsGELKFxQsyUCBos60Qqy1JEFAIu3Ns6GGYjGkqkQ==", - "license": "MIT", - "dependencies": { - "@graphql-tools/merge": "^9.1.7", - "@graphql-tools/utils": "^11.0.0", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-tools/schema/node_modules/@graphql-tools/utils": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-11.0.0.tgz", - "integrity": "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA==", - "license": "MIT", - "dependencies": { - "@graphql-typed-document-node/core": "^3.1.1", - "@whatwg-node/promise-helpers": "^1.0.0", - "cross-inspect": "1.0.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-tools/utils": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.11.0.tgz", - "integrity": "sha512-iBFR9GXIs0gCD+yc3hoNswViL1O5josI33dUqiNStFI/MHLCEPduasceAcazRH77YONKNiviHBV8f7OgcT4o2Q==", - "license": "MIT", - "dependencies": { - "@graphql-typed-document-node/core": "^3.1.1", - "@whatwg-node/promise-helpers": "^1.0.0", - "cross-inspect": "1.0.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-typed-document-node/core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", - "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", - "license": "MIT", - "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@graphql-yoga/logger": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@graphql-yoga/logger/-/logger-2.0.1.tgz", - "integrity": "sha512-Nv0BoDGLMg9QBKy9cIswQ3/6aKaKjlTh87x3GiBg2Z4RrjyrM48DvOOK0pJh1C1At+b0mUIM67cwZcFTDLN4sA==", - "license": "MIT", - "dependencies": { - "tslib": "^2.8.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@graphql-yoga/subscription": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@graphql-yoga/subscription/-/subscription-5.0.5.tgz", - "integrity": "sha512-oCMWOqFs6QV96/NZRt/ZhTQvzjkGB4YohBOpKM4jH/lDT4qb7Lex/aGCxpi/JD9njw3zBBtMqxbaC22+tFHVvw==", - "license": "MIT", - "dependencies": { - "@graphql-yoga/typed-event-target": "^3.0.2", - "@repeaterjs/repeater": "^3.0.4", - "@whatwg-node/events": "^0.1.0", - "tslib": "^2.8.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@graphql-yoga/typed-event-target": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@graphql-yoga/typed-event-target/-/typed-event-target-3.0.2.tgz", - "integrity": "sha512-ZpJxMqB+Qfe3rp6uszCQoag4nSw42icURnBRfFYSOmTgEeOe4rD0vYlbA8spvCu2TlCesNTlEN9BLWtQqLxabA==", - "license": "MIT", - "dependencies": { - "@repeaterjs/repeater": "^3.0.4", - "tslib": "^2.8.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@hono/node-server": { - "version": "1.19.13", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.13.tgz", - "integrity": "sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ==", - "license": "MIT", - "engines": { - "node": ">=18.14.1" - }, - "peerDependencies": { - "hono": "^4" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.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/@lekoarts/rehype-meta-as-attributes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@lekoarts/rehype-meta-as-attributes/-/rehype-meta-as-attributes-3.0.3.tgz", - "integrity": "sha512-DyG740U2y8ZWU5ZsAGzKfdVKOENg9UZsCBUJ3DVaWT7ZMHhDG5U0CjLj40CsEsJJ1gauaQPlrU9QUg5uSa4RFg==", - "license": "MIT", - "dependencies": { - "unist-util-visit": "^5.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@mdx-js/mdx": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", - "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "acorn": "^8.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-scope": "^1.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "recma-build-jsx": "^1.0.0", - "recma-jsx": "^1.0.0", - "recma-stringify": "^1.0.0", - "rehype-recma": "^1.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/react": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", - "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", - "license": "MIT", - "dependencies": { - "@types/mdx": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=16", - "react": ">=16" - } - }, - "node_modules/@mdx-js/rollup": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@mdx-js/rollup/-/rollup-3.1.1.tgz", - "integrity": "sha512-v8satFmBB+DqDzYohnm1u2JOvxx6Hl3pUvqzJvfs2Zk/ngZ1aRUhsWpXvwPkNeGN9c2NCm/38H29ZqXQUjf8dw==", - "license": "MIT", - "dependencies": { - "@mdx-js/mdx": "^3.0.0", - "@rollup/pluginutils": "^5.0.0", - "source-map": "^0.7.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "rollup": ">=2" - } - }, - "node_modules/@napi-rs/nice": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.1.1.tgz", - "integrity": "sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "optionalDependencies": { - "@napi-rs/nice-android-arm-eabi": "1.1.1", - "@napi-rs/nice-android-arm64": "1.1.1", - "@napi-rs/nice-darwin-arm64": "1.1.1", - "@napi-rs/nice-darwin-x64": "1.1.1", - "@napi-rs/nice-freebsd-x64": "1.1.1", - "@napi-rs/nice-linux-arm-gnueabihf": "1.1.1", - "@napi-rs/nice-linux-arm64-gnu": "1.1.1", - "@napi-rs/nice-linux-arm64-musl": "1.1.1", - "@napi-rs/nice-linux-ppc64-gnu": "1.1.1", - "@napi-rs/nice-linux-riscv64-gnu": "1.1.1", - "@napi-rs/nice-linux-s390x-gnu": "1.1.1", - "@napi-rs/nice-linux-x64-gnu": "1.1.1", - "@napi-rs/nice-linux-x64-musl": "1.1.1", - "@napi-rs/nice-openharmony-arm64": "1.1.1", - "@napi-rs/nice-win32-arm64-msvc": "1.1.1", - "@napi-rs/nice-win32-ia32-msvc": "1.1.1", - "@napi-rs/nice-win32-x64-msvc": "1.1.1" - } - }, - "node_modules/@napi-rs/nice-android-arm-eabi": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.1.1.tgz", - "integrity": "sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-android-arm64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.1.1.tgz", - "integrity": "sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-darwin-arm64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.1.1.tgz", - "integrity": "sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-darwin-x64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.1.1.tgz", - "integrity": "sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-freebsd-x64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.1.1.tgz", - "integrity": "sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.1.1.tgz", - "integrity": "sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-arm64-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.1.1.tgz", - "integrity": "sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-arm64-musl": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.1.1.tgz", - "integrity": "sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-ppc64-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.1.1.tgz", - "integrity": "sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==", - "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-riscv64-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.1.1.tgz", - "integrity": "sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==", - "cpu": [ - "riscv64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-s390x-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.1.1.tgz", - "integrity": "sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==", - "cpu": [ - "s390x" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-x64-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.1.1.tgz", - "integrity": "sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-linux-x64-musl": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.1.1.tgz", - "integrity": "sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-openharmony-arm64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-openharmony-arm64/-/nice-openharmony-arm64-1.1.1.tgz", - "integrity": "sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-win32-arm64-msvc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.1.1.tgz", - "integrity": "sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-win32-ia32-msvc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.1.1.tgz", - "integrity": "sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/nice-win32-x64-msvc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.1.1.tgz", - "integrity": "sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", - "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", - "license": "MIT", - "optional": true, - "dependencies": { - "@tybys/wasm-util": "^0.10.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" - } - }, - "node_modules/@opentelemetry/api": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", - "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", - "license": "Apache-2.0", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/api-logs": { - "version": "0.214.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.214.0.tgz", - "integrity": "sha512-40lSJeqYO8Uz2Yj7u94/SJWE/wONa7rmMKjI1ZcIjgf3MHNHv1OZUCrCETGuaRF62d5pQD1wKIW+L4lmSMTzZA==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api": "^1.3.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/core": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.1.tgz", - "integrity": "sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/instrumentation": { - "version": "0.214.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.214.0.tgz", - "integrity": "sha512-MHqEX5Dk59cqVah5LiARMACku7jXSVk9iVDWOea4x3cr7VfdByeDCURK6o1lntT1JS/Tsovw01UJrBhN3/uC5w==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api-logs": "0.214.0", - "import-in-the-middle": "^3.0.0", - "require-in-the-middle": "^8.0.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-amqplib": { - "version": "0.61.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.61.0.tgz", - "integrity": "sha512-mCKoyTGfRNisge4br0NpOFSy2Z1NnEW8hbCJdUDdJFHrPqVzc4IIBPA/vX0U+LUcQqrQvJX+HMIU0dbDRe0i0Q==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.33.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-connect": { - "version": "0.57.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.57.0.tgz", - "integrity": "sha512-FMEBChnI4FLN5TE9DHwfH7QpNir1JzXno1uz/TAucVdLCyrG0jTrKIcNHt/i30A0M2AunNBCkcd8Ei26dIPKdg==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.27.0", - "@types/connect": "3.4.38" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-dataloader": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.31.0.tgz", - "integrity": "sha512-f654tZFQXS5YeLDNb9KySrwtg7SnqZN119FauD7acBoTzuLduaiGTNz88ixcVSOOMGZ+EjJu/RFtx5klObC95g==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-fs": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.33.0.tgz", - "integrity": "sha512-sCZWXGalQ01wr3tAhSR9ucqFJ0phidpAle6/17HVjD6gN8FLmZMK/8sKxdXYHy3PbnlV1P4zeiSVFNKpbFMNLA==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.214.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-generic-pool": { - "version": "0.57.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.57.0.tgz", - "integrity": "sha512-orhmlaK+ZIW9hKU+nHTbXrCSXZcH83AescTqmpamHRobRmYSQwRbD0a1odc0yAzuzOtxYiHiXAnpnIpaSSY7Ow==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-graphql": { - "version": "0.62.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.62.0.tgz", - "integrity": "sha512-3YNuLVPUxafXkH1jBAbGsKNsP3XVzcFDhCDCE3OqBwCwShlqQbLMRMFh1T/d5jaVZiGVmSsfof+ICKD2iOV8xg==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-hapi": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.60.0.tgz", - "integrity": "sha512-aNljZKYrEa7obLAxd1bCEDxF7kzCLGXTuTJZ8lMR9rIVEjmuKBXN1gfqpm/OB//Zc2zP4iIve1jBp7sr3mQV6w==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.27.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-http": { - "version": "0.214.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.214.0.tgz", - "integrity": "sha512-FlkDhZDRjDJDcO2LcSCtjRpkal1NJ8y0fBqBhTvfAR3JSYY2jAIj1kSS5IjmEBt4c3aWv+u/lqLuoCDrrKCSKg==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.6.1", - "@opentelemetry/instrumentation": "0.214.0", - "@opentelemetry/semantic-conventions": "^1.29.0", - "forwarded-parse": "2.1.2" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/core": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.6.1.tgz", - "integrity": "sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/instrumentation-ioredis": { - "version": "0.62.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.62.0.tgz", - "integrity": "sha512-ZYt//zcPve8qklaZX+5Z4MkU7UpEkFRrxsf2cnaKYBitqDnsCN69CPAuuMOX6NYdW2rG9sFy7V/QWtBlP5XiNQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/redis-common": "^0.38.2", - "@opentelemetry/semantic-conventions": "^1.33.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-kafkajs": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.23.0.tgz", - "integrity": "sha512-4K+nVo+zI+aDz0Z85SObwbdixIbzS9moIuKJaYsdlzcHYnKOPtB7ya8r8Ezivy/GVIBHiKJVq4tv+BEkgOMLaQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.30.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-knex": { - "version": "0.58.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.58.0.tgz", - "integrity": "sha512-Hc/o8fSsaWxZ8r1Yw4rNDLwTpUopTf4X32y4W6UhlHmW8Wizz8wfhgOKIelSeqFVTKBBPIDUOsQWuIMxBmu8Bw==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.33.1" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-koa": { - "version": "0.62.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.62.0.tgz", - "integrity": "sha512-uVip0VuGUQXZ+vFxkKxAUNq8qNl+VFlyHDh/U6IQ8COOEDfbEchdaHnpFrMYF3psZRUuoSIgb7xOeXj00RdwDA==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.36.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0" - } - }, - "node_modules/@opentelemetry/instrumentation-lru-memoizer": { - "version": "0.58.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.58.0.tgz", - "integrity": "sha512-6grM3TdMyHzlGY1cUA+mwoPueB1F3dYKgKtZIH6jOFXqfHAByyLTc+6PFjGM9tKh52CFBJaDwodNlL/Td39z7Q==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-mongodb": { - "version": "0.67.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.67.0.tgz", - "integrity": "sha512-1WJp5N1lYfHq2IhECOTewFs5Tf2NfUOwQRqs/rZdXKTezArMlucxgzAaqcgp3A3YREXopXTpXHsxZTGHjNhMdQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.33.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-mongoose": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.60.0.tgz", - "integrity": "sha512-8BahAZpKsOoc+lrZGb7Ofn4g3z8qtp5IxDfvAVpKXsEheQN7ONMH5djT5ihy6yf8yyeQJGS0gXFfpEAEeEHqQg==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.33.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-mysql": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.60.0.tgz", - "integrity": "sha512-08pO8GFPEIz2zquKDGteBZDNmwketdgH8hTe9rVYgW9kCJXq1Psj3wPQGx+VaX4ZJKCfPeoLMYup9+cxHvZyVQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.33.0", - "@types/mysql": "2.15.27" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-mysql2": { - "version": "0.60.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.60.0.tgz", - "integrity": "sha512-m/5d3bxQALllCzezYDk/6vajh0tj5OijMMvOZGr+qN1NMXm1dzMNwyJ0gNZW7Fo3YFRyj/jJMxIw+W7d525dlw==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.33.0", - "@opentelemetry/sql-common": "^0.41.2" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-pg": { - "version": "0.66.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.66.0.tgz", - "integrity": "sha512-KxfLGXBb7k2ueaPJfq2GXBDXBly8P+SpR/4Mj410hhNgmQF3sCqwXvUBQxZQkDAmsdBAoenM+yV1LhtsMRamcA==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.34.0", - "@opentelemetry/sql-common": "^0.41.2", - "@types/pg": "8.15.6", - "@types/pg-pool": "2.0.7" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-redis": { - "version": "0.62.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.62.0.tgz", - "integrity": "sha512-y3pPpot7WzR/8JtHcYlTYsyY8g+pbFhAqbwAuG5bLPnR6v6pt1rQc0DpH0OlGP/9CZbWBP+Zhwp9yFoygf/ZXQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/redis-common": "^0.38.2", - "@opentelemetry/semantic-conventions": "^1.27.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-tedious": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.33.0.tgz", - "integrity": "sha512-Q6WQwAD01MMTub31GlejoiFACYNw26J426wyjvU7by7fDIr2nZXNW4vhTGs7i7F0TnXBO3xN688g1tdUgYwJ5w==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.33.0", - "@types/tedious": "^4.0.14" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation-undici": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.24.0.tgz", - "integrity": "sha512-oKzZ3uvqP17sV0EsoQcJgjEfIp0kiZRbYu/eD8p13Cbahumf8lb/xpYeNr/hfAJ4owzEtIDcGIjprfLcYbIKBQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/semantic-conventions": "^1.24.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.7.0" - } - }, - "node_modules/@opentelemetry/redis-common": { - "version": "0.38.3", - "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.3.tgz", - "integrity": "sha512-VCghU1JYs/4gP6Gqf/xro9MEsZ7LrMv2uONVsaESKL38ZOB9BqnI98FfS23wjMnHlpuE+TTaWSoAVNpTwYXzjw==", - "license": "Apache-2.0", - "engines": { - "node": "^18.19.0 || >=20.6.0" - } - }, - "node_modules/@opentelemetry/resources": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.1.tgz", - "integrity": "sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.7.1", - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/sdk-trace-base": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.7.1.tgz", - "integrity": "sha512-NAYIlsF8MPUsKqJMiDQJTMPOmlbawC1Iz/omMLygZ1C9am8fTKYjTaI+OZM+WTY3t3Glo0wnOg/6/pac6RGPPw==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.7.1", - "@opentelemetry/resources": "2.7.1", - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.40.0.tgz", - "integrity": "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==", - "license": "Apache-2.0", - "engines": { - "node": ">=14" - } - }, - "node_modules/@opentelemetry/sql-common": { - "version": "0.41.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz", - "integrity": "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "^2.0.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.1.0" - } - }, - "node_modules/@oxc-project/types": { - "version": "0.126.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.126.0.tgz", - "integrity": "sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, - "node_modules/@pagefind/darwin-arm64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.5.2.tgz", - "integrity": "sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@pagefind/darwin-x64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.5.2.tgz", - "integrity": "sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@pagefind/freebsd-x64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.5.2.tgz", - "integrity": "sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@pagefind/linux-arm64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.5.2.tgz", - "integrity": "sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@pagefind/linux-x64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.5.2.tgz", - "integrity": "sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@pagefind/windows-arm64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/windows-arm64/-/windows-arm64-1.5.2.tgz", - "integrity": "sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@pagefind/windows-x64": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.5.2.tgz", - "integrity": "sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@posthog/core": { - "version": "1.23.1", - "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.23.1.tgz", - "integrity": "sha512-GViD5mOv/mcbZcyzz3z9CS0R79JzxVaqEz4sP5Dsea178M/j3ZWe6gaHDZB9yuyGfcmIMQ/8K14yv+7QrK4sQQ==", - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.6" - } - }, - "node_modules/@pothos/core": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/@pothos/core/-/core-4.12.0.tgz", - "integrity": "sha512-PeiODrj3GjQ7Nbs/5p65DEyBWZTSGGjgGO/BgaMEqS1jBNX/2zJTEQJA9zM5uPmCHUCDjE7Qn2U7lOi0ALp/8A==", - "license": "ISC", - "peerDependencies": { - "graphql": "^16.10.0" - } - }, - "node_modules/@prisma/instrumentation": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-7.6.0.tgz", - "integrity": "sha512-ZPW2gRiwpPzEfgeZgaekhqXrbW+Y2RJKHVqUmlhZhKzRNCcvR6DykzylDrynpArKKRQtLxoZy36fK7U0p3pdgQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/instrumentation": "^0.207.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.8" - } - }, - "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/api-logs": { - "version": "0.207.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.207.0.tgz", - "integrity": "sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api": "^1.3.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/instrumentation": { - "version": "0.207.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.207.0.tgz", - "integrity": "sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api-logs": "0.207.0", - "import-in-the-middle": "^2.0.0", - "require-in-the-middle": "^8.0.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@prisma/instrumentation/node_modules/import-in-the-middle": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", - "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", - "license": "Apache-2.0", - "dependencies": { - "acorn": "^8.15.0", - "acorn-import-attributes": "^1.9.5", - "cjs-module-lexer": "^2.2.0", - "module-details-from-path": "^1.0.4" - } - }, - "node_modules/@radix-ui/number": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", - "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", - "license": "MIT" - }, - "node_modules/@radix-ui/primitive": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", - "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", - "license": "MIT" - }, - "node_modules/@radix-ui/react-accordion": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", - "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collapsible": "1.1.12", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.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-alert-dialog": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", - "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dialog": "1.1.15", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "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-alert-dialog/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "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-arrow": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", - "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.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-aspect-ratio": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.8.tgz", - "integrity": "sha512-5nZrJTF7gH+e0nZS7/QxFz6tJV4VimhQb1avEgtsJxvvIp5JilL+c58HICsKzPxghdwaDt48hEfPM1au4zGy+w==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.4" - }, - "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-aspect-ratio/node_modules/@radix-ui/react-primitive": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", - "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.2.4" - }, - "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-checkbox": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", - "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" - }, - "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.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", - "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "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.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "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-collection/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "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-compose-refs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", - "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.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", - "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", - "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.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", - "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.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-dialog/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "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-direction": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", - "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", - "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.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", - "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-escape-keydown": "1.1.1" - }, - "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.16", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", - "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-menu": "2.1.16", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.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-focus-guards": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", - "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", - "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.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", - "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1" - }, - "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-hover-card": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.15.tgz", - "integrity": "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.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.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", - "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "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.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.8.tgz", - "integrity": "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.4" - }, - "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-label/node_modules/@radix-ui/react-primitive": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", - "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.2.4" - }, - "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.16", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", - "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.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-menu/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "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-navigation-menu": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.14.tgz", - "integrity": "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-visually-hidden": "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-navigation-menu/node_modules/@radix-ui/react-visually-hidden": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", - "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.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-popover": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", - "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.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-popover/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "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-popper": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", - "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", - "license": "MIT", - "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-rect": "1.1.1", - "@radix-ui/react-use-size": "1.1.1", - "@radix-ui/rect": "1.1.1" - }, - "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.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", - "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "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.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", - "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "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.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "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-primitive/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "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-progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.8.tgz", - "integrity": "sha512-+gISHcSPUJ7ktBy9RnTqbdKW78bcGke3t6taawyZ71pio1JewwGSJizycs7rLhGTvMJYCQB1DBK4KQsxs7U8dA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-context": "1.1.3", - "@radix-ui/react-primitive": "2.1.4" - }, - "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-progress/node_modules/@radix-ui/react-context": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.3.tgz", - "integrity": "sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw==", - "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-progress/node_modules/@radix-ui/react-primitive": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", - "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.2.4" - }, - "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-radio-group": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", - "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" - }, - "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.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", - "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.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-scroll-area": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", - "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", - "license": "MIT", - "dependencies": { - "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "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-select": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", - "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-focus-guards": "1.1.3", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-visually-hidden": "1.2.3", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.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-select/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "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-select/node_modules/@radix-ui/react-visually-hidden": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", - "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.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-separator": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.8.tgz", - "integrity": "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.4" - }, - "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/node_modules/@radix-ui/react-primitive": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", - "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.2.4" - }, - "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-slider": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz", - "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==", - "license": "MIT", - "dependencies": { - "@radix-ui/number": "1.1.1", - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" - }, - "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.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", - "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "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-switch": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", - "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-use-previous": "1.1.1", - "@radix-ui/react-use-size": "1.1.1" - }, - "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-tabs": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", - "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-use-controllable-state": "1.2.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-toggle": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", - "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.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-toggle-group": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz", - "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-toggle": "1.1.10", - "@radix-ui/react-use-controllable-state": "1.2.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-tooltip": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", - "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.11", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.8", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.5", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "@radix-ui/react-visually-hidden": "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/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "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-tooltip/node_modules/@radix-ui/react-visually-hidden": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", - "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.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-use-callback-ref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", - "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", - "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.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", - "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-effect-event": "0.0.2", - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "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.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", - "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "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.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", - "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.1" - }, - "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.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", - "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", - "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-previous": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", - "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", - "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.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", - "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", - "license": "MIT", - "dependencies": { - "@radix-ui/rect": "1.1.1" - }, - "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.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", - "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "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.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.4.tgz", - "integrity": "sha512-kaeiyGCe844dkb9AVF+rb4yTyb1LiLN/e3es3nLiRyN4dC8AduBYPMnnNlDjX2VDOcvDEiPnRNMJeWCfsX0txg==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.1.4" - }, - "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-visually-hidden/node_modules/@radix-ui/react-primitive": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", - "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.2.4" - }, - "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.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", - "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", - "license": "MIT" - }, - "node_modules/@repeaterjs/repeater": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.6.tgz", - "integrity": "sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==", - "license": "MIT" - }, - "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.16.tgz", - "integrity": "sha512-rhY3k7Bsae9qQfOtph2Pm2jZEA+s8Gmjoz4hhmx70K9iMQ/ddeae+xhRQcM5IuVx5ry1+bGfkvMn7D6MJggVSA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.16.tgz", - "integrity": "sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.16.tgz", - "integrity": "sha512-r/OmdR00HmD4i79Z//xO06uEPOq5hRXdhw7nzkxQxwSavs3PSHa1ijntdpOiZ2mzOQ3fVVu8C1M19FoNM+dMUQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.16.tgz", - "integrity": "sha512-KcRE5w8h0OnjUatG8pldyD14/CQ5Phs1oxfR+3pKDjboHRo9+MkqQaiIZlZRpsxC15paeXme/I127tUa9TXJ6g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.16.tgz", - "integrity": "sha512-bT0guA1bpxEJ/ZhTRniQf7rNF8ybvXOuWbNIeLABaV5NGjx4EtOWBTSRGWFU9ZWVkPOZ+HNFP8RMcBokBiZ0Kg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.16.tgz", - "integrity": "sha512-+tHktCHWV8BDQSjemUqm/Jl/TPk3QObCTIjmdDy/nlupcujZghmKK2962LYrqFpWu+ai01AN/REOH3NEpqvYQg==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.16.tgz", - "integrity": "sha512-3fPzdREH806oRLxpTWW1Gt4tQHs0TitZFOECB2xzCFLPKnSOy90gwA7P29cksYilFO6XVRY1kzga0cL2nRjKPg==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.16.tgz", - "integrity": "sha512-EKwI1tSrLs7YVw+JPJT/G2dJQ1jl9qlTTTEG0V2Ok/RdOenRfBw2PQdLPyjhIu58ocdBfP7vIRN/pvMsPxs/AQ==", - "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.16.tgz", - "integrity": "sha512-Uknladnb3Sxqu6SEcqBldQyJUpk8NleooZEc0MbRBJ4inEhRYWZX0NJu12vNf2mqAq7gsofAxHrGghiUYjhaLQ==", - "cpu": [ - "s390x" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.16.tgz", - "integrity": "sha512-FIb8+uG49sZBtLTn+zt1AJ20TqVcqWeSIyoVt0or7uAWesgKaHbiBh6OpA/k9v0LTt+PTrb1Lao133kP4uVxkg==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.16.tgz", - "integrity": "sha512-RuERhF9/EgWxZEXYWCOaViUWHIboceK4/ivdtQ3R0T44NjLkIIlGIAVAuCddFxsZ7vnRHtNQUrt2vR2n2slB2w==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.16.tgz", - "integrity": "sha512-mXcXnvd9GpazCxeUCCnZ2+YF7nut+ZOEbE4GtaiPtyY6AkhZWbK70y1KK3j+RDhjVq5+U8FySkKRb/+w0EeUwA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.16.tgz", - "integrity": "sha512-3Q2KQxnC8IJOLqXmUMoYwyIPZU9hzRbnHaoV3Euz+VVnjZKcY8ktnNP8T9R4/GGQtb27C/UYKABxesKWb8lsvQ==", - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.9.2", - "@emnapi/runtime": "1.9.2", - "@napi-rs/wasm-runtime": "^1.1.4" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.16.tgz", - "integrity": "sha512-tj7XRemQcOcFwv7qhpUxMTBbI5mWMlE4c1Omhg5+h8GuLXzyj8HviYgR+bB2DMDgRqUE+jiDleqSCRjx4aYk/Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.16.tgz", - "integrity": "sha512-PH5DRZT+F4f2PTXRXR8uJxnBq2po/xFtddyabTJVJs/ZYVHqXPEgNIr35IHTEa6bpa0Q8Awg+ymkTaGnKITw4g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.7", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz", - "integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==", - "license": "MIT" - }, - "node_modules/@rollup/pluginutils": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", - "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", - "cpu": [ - "arm" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", - "cpu": [ - "arm" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", - "cpu": [ - "loong64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", - "cpu": [ - "loong64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", - "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", - "cpu": [ - "ppc64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", - "cpu": [ - "riscv64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", - "cpu": [ - "riscv64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", - "cpu": [ - "s390x" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "peer": true - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "peer": true - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "node_modules/@scalar/helpers": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@scalar/helpers/-/helpers-0.2.7.tgz", - "integrity": "sha512-uFTcdi3XYDDuaJLWiMuM3ijQit1OBw7AkuOuujReY8L9UmUQHY56erYg0+Db3llTsinuIYFh+eS/WX/sYuevYQ==", - "license": "MIT", - "engines": { - "node": ">=20" - } - }, - "node_modules/@scalar/json-magic": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@scalar/json-magic/-/json-magic-0.9.0.tgz", - "integrity": "sha512-aSWd8rd3O73Ak9Ylson2TywvOuTjjOYiXydl9Cn8Ip/r7fi+h0QqAGom5gqo/WewrhySF9v+H/sW/Qmd05T/Kg==", - "license": "MIT", - "dependencies": { - "@scalar/helpers": "0.2.7", - "yaml": "^2.8.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@scalar/openapi-parser": { - "version": "0.23.13", - "resolved": "https://registry.npmjs.org/@scalar/openapi-parser/-/openapi-parser-0.23.13.tgz", - "integrity": "sha512-YsljPOKOgQgZL/kBcEouwz2CUa+2hFfThlUZRWC2DFI2Fnw5Ur8F1IvGgPqCAHr9p2XMH+Z/Pag2jZUfLcxcww==", - "license": "MIT", - "dependencies": { - "@scalar/json-magic": "0.9.0", - "@scalar/openapi-types": "0.5.3", - "@scalar/openapi-upgrader": "0.1.7", - "ajv": "^8.17.1", - "ajv-draft-04": "^1.0.0", - "ajv-formats": "^3.0.1", - "jsonpointer": "^5.0.1", - "leven": "^4.0.0", - "yaml": "^2.8.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@scalar/openapi-types": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@scalar/openapi-types/-/openapi-types-0.5.3.tgz", - "integrity": "sha512-m4n/Su3K01d15dmdWO1LlqecdSPKuNjuokrJLdiQ485kW/hRHbXW1QP6tJL75myhw/XhX5YhYAR+jrwnGjXiMw==", - "license": "MIT", - "dependencies": { - "zod": "^4.1.11" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@scalar/openapi-upgrader": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@scalar/openapi-upgrader/-/openapi-upgrader-0.1.7.tgz", - "integrity": "sha512-065froUtqvaHjyeJtyitf8tb+k7oh7nU0OinAHYbj1Bqgwb1s2+uKMqHYHEES5CNpp+2xtL4lxup6Aq29yW+sQ==", - "license": "MIT", - "dependencies": { - "@scalar/openapi-types": "0.5.3" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@sentry/core": { - "version": "10.49.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.49.0.tgz", - "integrity": "sha512-UaFeum3LUM1mB0d67jvKnqId1yWQjyqmaDV6kWngG03x+jqXb08tJdGpSoxjXZe13jFBbiBL/wKDDYIK7rCK4g==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@sentry/node": { - "version": "10.49.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.49.0.tgz", - "integrity": "sha512-xr+HXABCiO5mgAJRQxsXRdNOLO0+Ee6CvXAAIqovL2A1GlhxNWc5ooPWeIrrLDJ/KGyT8zI91O5scpVXdXs0uQ==", - "license": "MIT", - "dependencies": { - "@fastify/otel": "0.18.0", - "@opentelemetry/api": "^1.9.1", - "@opentelemetry/core": "^2.6.1", - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/instrumentation-amqplib": "0.61.0", - "@opentelemetry/instrumentation-connect": "0.57.0", - "@opentelemetry/instrumentation-dataloader": "0.31.0", - "@opentelemetry/instrumentation-fs": "0.33.0", - "@opentelemetry/instrumentation-generic-pool": "0.57.0", - "@opentelemetry/instrumentation-graphql": "0.62.0", - "@opentelemetry/instrumentation-hapi": "0.60.0", - "@opentelemetry/instrumentation-http": "0.214.0", - "@opentelemetry/instrumentation-ioredis": "0.62.0", - "@opentelemetry/instrumentation-kafkajs": "0.23.0", - "@opentelemetry/instrumentation-knex": "0.58.0", - "@opentelemetry/instrumentation-koa": "0.62.0", - "@opentelemetry/instrumentation-lru-memoizer": "0.58.0", - "@opentelemetry/instrumentation-mongodb": "0.67.0", - "@opentelemetry/instrumentation-mongoose": "0.60.0", - "@opentelemetry/instrumentation-mysql": "0.60.0", - "@opentelemetry/instrumentation-mysql2": "0.60.0", - "@opentelemetry/instrumentation-pg": "0.66.0", - "@opentelemetry/instrumentation-redis": "0.62.0", - "@opentelemetry/instrumentation-tedious": "0.33.0", - "@opentelemetry/instrumentation-undici": "0.24.0", - "@opentelemetry/sdk-trace-base": "^2.6.1", - "@opentelemetry/semantic-conventions": "^1.40.0", - "@prisma/instrumentation": "7.6.0", - "@sentry/core": "10.49.0", - "@sentry/node-core": "10.49.0", - "@sentry/opentelemetry": "10.49.0", - "import-in-the-middle": "^3.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@sentry/node-core": { - "version": "10.49.0", - "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.49.0.tgz", - "integrity": "sha512-7WO0KuCDPSq3G54TVUSI1CKFJwB67LasG+n/gDMBqbrarzs/Yh/s34OOMU5gfVQpncxQAmQsy4nEboQms8iNqA==", - "license": "MIT", - "dependencies": { - "@sentry/core": "10.49.0", - "@sentry/opentelemetry": "10.49.0", - "import-in-the-middle": "^3.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0", - "@opentelemetry/core": "^1.30.1 || ^2.1.0", - "@opentelemetry/exporter-trace-otlp-http": ">=0.57.0 <1", - "@opentelemetry/instrumentation": ">=0.57.1 <1", - "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", - "@opentelemetry/semantic-conventions": "^1.39.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "@opentelemetry/core": { - "optional": true - }, - "@opentelemetry/exporter-trace-otlp-http": { - "optional": true - }, - "@opentelemetry/instrumentation": { - "optional": true - }, - "@opentelemetry/sdk-trace-base": { - "optional": true - }, - "@opentelemetry/semantic-conventions": { - "optional": true - } - } - }, - "node_modules/@sentry/opentelemetry": { - "version": "10.49.0", - "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.49.0.tgz", - "integrity": "sha512-XNLm4dXmtegXQf+EEE2Cs84Ymlo/f5wMx+lg2S2XS4qLbXaPN/HttjhwKftd8D+8iUNfmH+xNMCSshx4s1B/1w==", - "license": "MIT", - "dependencies": { - "@sentry/core": "10.49.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0", - "@opentelemetry/core": "^1.30.1 || ^2.1.0", - "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0", - "@opentelemetry/semantic-conventions": "^1.39.0" - } - }, - "node_modules/@shikijs/core": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.0.2.tgz", - "integrity": "sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw==", - "license": "MIT", - "dependencies": { - "@shikijs/primitive": "4.0.2", - "@shikijs/types": "4.0.2", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4", - "hast-util-to-html": "^9.0.5" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@shikijs/engine-javascript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.0.2.tgz", - "integrity": "sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "4.0.2", - "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^4.3.4" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.0.2.tgz", - "integrity": "sha512-UpCB9Y2sUKlS9z8juFSKz7ZtysmeXCgnRF0dlhXBkmQnek7lAToPte8DkxmEYGNTMii72zU/lyXiCB6StuZeJg==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "4.0.2", - "@shikijs/vscode-textmate": "^10.0.2" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@shikijs/langs": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.0.2.tgz", - "integrity": "sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "4.0.2" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@shikijs/primitive": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.0.2.tgz", - "integrity": "sha512-M6UMPrSa3fN5ayeJwFVl9qWofl273wtK1VG8ySDZ1mQBfhCpdd8nEx7nPZ/tk7k+TYcpqBZzj/AnwxT9lO+HJw==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "4.0.2", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@shikijs/rehype": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/rehype/-/rehype-4.0.2.tgz", - "integrity": "sha512-cmPlKLD8JeojasNFoY64162ScpEdEdQUMuVodPCrv1nx1z3bjmGwoKWDruQWa/ejSznImlaeB0Ty6Q3zPaVQAA==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "4.0.2", - "@types/hast": "^3.0.4", - "hast-util-to-string": "^3.0.1", - "shiki": "4.0.2", - "unified": "^11.0.5", - "unist-util-visit": "^5.1.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@shikijs/themes": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.0.2.tgz", - "integrity": "sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "4.0.2" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@shikijs/transformers": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-4.0.2.tgz", - "integrity": "sha512-1+L0gf9v+SdDXs08vjaLb3mBFa8U7u37cwcBQIv/HCocLwX69Tt6LpUCjtB+UUTvQxI7BnjZKhN/wMjhHBcJGg==", - "license": "MIT", - "dependencies": { - "@shikijs/core": "4.0.2", - "@shikijs/types": "4.0.2" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@shikijs/types": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.0.2.tgz", - "integrity": "sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg==", - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", - "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", - "license": "MIT" - }, - "node_modules/@tailwindcss/node": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz", - "integrity": "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==", - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "^5.19.0", - "jiti": "^2.6.1", - "lightningcss": "1.32.0", - "magic-string": "^0.30.21", - "source-map-js": "^1.2.1", - "tailwindcss": "4.2.2" - } - }, - "node_modules/@tailwindcss/node/node_modules/tailwindcss": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz", - "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==", - "license": "MIT" - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.2.tgz", - "integrity": "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==", - "license": "MIT", - "engines": { - "node": ">= 20" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.2.2", - "@tailwindcss/oxide-darwin-arm64": "4.2.2", - "@tailwindcss/oxide-darwin-x64": "4.2.2", - "@tailwindcss/oxide-freebsd-x64": "4.2.2", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2", - "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2", - "@tailwindcss/oxide-linux-arm64-musl": "4.2.2", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", - "@tailwindcss/oxide-linux-x64-musl": "4.2.2", - "@tailwindcss/oxide-wasm32-wasi": "4.2.2", - "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2", - "@tailwindcss/oxide-win32-x64-msvc": "4.2.2" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz", - "integrity": "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz", - "integrity": "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz", - "integrity": "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz", - "integrity": "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz", - "integrity": "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz", - "integrity": "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz", - "integrity": "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz", - "integrity": "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz", - "integrity": "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz", - "integrity": "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==", - "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.8.1", - "@emnapi/runtime": "^1.8.1", - "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.1.1", - "@tybys/wasm-util": "^0.10.1", - "tslib": "^2.8.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz", - "integrity": "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz", - "integrity": "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 20" - } - }, - "node_modules/@tailwindcss/typography": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.19.tgz", - "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "6.0.10" - }, - "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" - } - }, - "node_modules/@tailwindcss/vite": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.2.tgz", - "integrity": "sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==", - "license": "MIT", - "dependencies": { - "@tailwindcss/node": "4.2.2", - "@tailwindcss/oxide": "4.2.2", - "tailwindcss": "4.2.2" - }, - "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7 || ^8" - } - }, - "node_modules/@tailwindcss/vite/node_modules/tailwindcss": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz", - "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==", - "license": "MIT" - }, - "node_modules/@tanem/react-nprogress": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@tanem/react-nprogress/-/react-nprogress-6.0.3.tgz", - "integrity": "sha512-OT3KZiJv/zGI/lEwX3gD9nzNnyUQuSdSL0BK3OJIUC3Prx3JD18u13TZRvzasEXxHPGzm6AtBEr6gYxPeVWjWw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.28.6", - "hoist-non-react-statics": "^3.3.2" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/@tanstack/query-core": { - "version": "5.97.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.97.0.tgz", - "integrity": "sha512-QdpLP5VzVMgo4VtaPppRA2W04UFjIqX+bxke/ZJhE5cfd5UPkRzqIAJQt9uXkQJjqE8LBOMbKv7f8HCsZltXlg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@tanstack/react-query": { - "version": "5.97.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.97.0.tgz", - "integrity": "sha512-y4So4eGcQoK2WVMAcDNZE9ofB/p5v1OlKvtc1F3uqHwrtifobT7q+ZnXk2mRkc8E84HKYSlAE9z6HXl2V0+ySQ==", - "license": "MIT", - "dependencies": { - "@tanstack/query-core": "5.97.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": "^18 || ^19" - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", - "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", - "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/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==", - "license": "MIT" - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdx": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", - "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, - "node_modules/@types/mysql": { - "version": "2.15.27", - "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", - "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/node": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", - "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.18.0" - } - }, - "node_modules/@types/pg": { - "version": "8.15.6", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.6.tgz", - "integrity": "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "pg-protocol": "*", - "pg-types": "^2.2.0" - } - }, - "node_modules/@types/pg-pool": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.7.tgz", - "integrity": "sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==", - "license": "MIT", - "dependencies": { - "@types/pg": "*" - } - }, - "node_modules/@types/react": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", - "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", - "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==", - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" - } - }, - "node_modules/@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/tedious": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", - "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.0.tgz", - "integrity": "sha512-RLkVSiNuUP1C2ROIWfqX+YcUfLaSnxGE/8M+Y57lopVwg9VTYYfhuz15Yf1IzCKgZj6/rIbYTmJCUSqr76r0Wg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.58.0", - "@typescript-eslint/type-utils": "8.58.0", - "@typescript-eslint/utils": "8.58.0", - "@typescript-eslint/visitor-keys": "8.58.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.58.0", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.0.tgz", - "integrity": "sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.58.0", - "@typescript-eslint/types": "8.58.0", - "@typescript-eslint/typescript-estree": "8.58.0", - "@typescript-eslint/visitor-keys": "8.58.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.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.0.tgz", - "integrity": "sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.58.0", - "@typescript-eslint/types": "^8.58.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.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.0.tgz", - "integrity": "sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.58.0", - "@typescript-eslint/visitor-keys": "8.58.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.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.0.tgz", - "integrity": "sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A==", - "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.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.0.tgz", - "integrity": "sha512-aGsCQImkDIqMyx1u4PrVlbi/krmDsQUs4zAcCV6M7yPcPev+RqVlndsJy9kJ8TLihW9TZ0kbDAzctpLn5o+lOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.58.0", - "@typescript-eslint/typescript-estree": "8.58.0", - "@typescript-eslint/utils": "8.58.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.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.0.tgz", - "integrity": "sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==", - "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.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.0.tgz", - "integrity": "sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.58.0", - "@typescript-eslint/tsconfig-utils": "8.58.0", - "@typescript-eslint/types": "8.58.0", - "@typescript-eslint/visitor-keys": "8.58.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/utils": { - "version": "8.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.0.tgz", - "integrity": "sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.58.0", - "@typescript-eslint/types": "8.58.0", - "@typescript-eslint/typescript-estree": "8.58.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.58.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.0.tgz", - "integrity": "sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.58.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/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "license": "ISC" - }, - "node_modules/@vitejs/plugin-react": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz", - "integrity": "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==", - "license": "MIT", - "dependencies": { - "@rolldown/pluginutils": "1.0.0-rc.7" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", - "babel-plugin-react-compiler": "^1.0.0", - "vite": "^8.0.0" - }, - "peerDependenciesMeta": { - "@rolldown/plugin-babel": { - "optional": true - }, - "babel-plugin-react-compiler": { - "optional": true - } - } - }, - "node_modules/@whatwg-node/disposablestack": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@whatwg-node/disposablestack/-/disposablestack-0.0.6.tgz", - "integrity": "sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==", - "license": "MIT", - "dependencies": { - "@whatwg-node/promise-helpers": "^1.0.0", - "tslib": "^2.6.3" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@whatwg-node/events": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.2.tgz", - "integrity": "sha512-ApcWxkrs1WmEMS2CaLLFUEem/49erT3sxIVjpzU5f6zmVcnijtDSrhoK2zVobOIikZJdH63jdAXOrvjf6eOUNQ==", - "license": "MIT", - "dependencies": { - "tslib": "^2.6.3" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@whatwg-node/fetch": { - "version": "0.10.13", - "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.10.13.tgz", - "integrity": "sha512-b4PhJ+zYj4357zwk4TTuF2nEe0vVtOrwdsrNo5hL+u1ojXNhh1FgJ6pg1jzDlwlT4oBdzfSwaBwMCtFCsIWg8Q==", - "license": "MIT", - "dependencies": { - "@whatwg-node/node-fetch": "^0.8.3", - "urlpattern-polyfill": "^10.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@whatwg-node/node-fetch": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.8.5.tgz", - "integrity": "sha512-4xzCl/zphPqlp9tASLVeUhB5+WJHbuWGYpfoC2q1qh5dw0AqZBW7L27V5roxYWijPxj4sspRAAoOH3d2ztaHUQ==", - "license": "MIT", - "dependencies": { - "@fastify/busboy": "^3.1.1", - "@whatwg-node/disposablestack": "^0.0.6", - "@whatwg-node/promise-helpers": "^1.3.2", - "tslib": "^2.6.3" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@whatwg-node/promise-helpers": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@whatwg-node/promise-helpers/-/promise-helpers-1.3.2.tgz", - "integrity": "sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==", - "license": "MIT", - "dependencies": { - "tslib": "^2.6.3" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@whatwg-node/server": { - "version": "0.10.18", - "resolved": "https://registry.npmjs.org/@whatwg-node/server/-/server-0.10.18.tgz", - "integrity": "sha512-kMwLlxUbduttIgaPdSkmEarFpP+mSY8FEm+QWMBRJwxOHWkri+cxd8KZHO9EMrB9vgUuz+5WEaCawaL5wGVoXg==", - "license": "MIT", - "dependencies": { - "@envelop/instrumentation": "^1.0.0", - "@whatwg-node/disposablestack": "^0.0.6", - "@whatwg-node/fetch": "^0.10.13", - "@whatwg-node/promise-helpers": "^1.3.2", - "tslib": "^2.6.3" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@x0k/json-schema-merge": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@x0k/json-schema-merge/-/json-schema-merge-1.0.2.tgz", - "integrity": "sha512-1734qiJHNX3+cJGDMMw2yz7R+7kpbAtl5NdPs1c/0gO5kYT6s4dMbLXiIfpZNsOYhGZI3aH7FWrj4Zxz7epXNg==", - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.15" - } - }, - "node_modules/@zudoku/httpsnippet": { - "version": "10.0.9", - "resolved": "https://registry.npmjs.org/@zudoku/httpsnippet/-/httpsnippet-10.0.9.tgz", - "integrity": "sha512-qmxuSxmTEEt6bc5j1cChljbztIphkuYMj3bbmT2W54ePGwCk6Iea7vPutHVw7NnCIW6cRI//w+u7xGOfOhwPCw==", - "license": "MIT", - "dependencies": { - "qs": "^6.11.2", - "stringify-object": "^3.3.0", - "url": "^0.11.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@zudoku/react-helmet-async": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@zudoku/react-helmet-async/-/react-helmet-async-2.0.5.tgz", - "integrity": "sha512-wDakXPJEiQb4JmacSqPyAiJPdOBFqp6e3VUbm1BtTEkXo6FrC2nN+GmIniQ2OimBEC042rSZ9JdQBX+wou/MKw==", - "license": "Apache-2.0", - "dependencies": { - "invariant": "^2.2.4", - "react-fast-compare": "^3.2.2", - "shallowequal": "^1.1.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/@zuplo/mcp": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@zuplo/mcp/-/mcp-0.0.32.tgz", - "integrity": "sha512-rpLTpwL+g1sXtylu2gZwCTXdNIV2L0LPOcCdwogpP5hdyp/JMLSAVtd7H5fs5Wt2cq3jTm6nn7ZZvsBAECdl3A==", - "license": "MIT", - "dependencies": { - "eventsource-parser": "^3.0.6", - "zod": "^3.25.0" - } - }, - "node_modules/@zuplo/mcp/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, - "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==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "license": "MIT", - "peerDependencies": { - "ajv": "^8.5.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "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/astring": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", - "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", - "license": "MIT", - "bin": { - "astring": "bin/astring" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/base-x": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.1.tgz", - "integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/bs58": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", - "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", - "license": "MIT", - "dependencies": { - "base-x": "^5.0.0" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "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/chalk/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/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/cjs-module-lexer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", - "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", - "license": "MIT" - }, - "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/cliui": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", - "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", - "license": "ISC", - "dependencies": { - "string-width": "^7.2.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=20" - } - }, - "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/cmdk": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz", - "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "^1.1.1", - "@radix-ui/react-dialog": "^1.1.6", - "@radix-ui/react-id": "^1.1.0", - "@radix-ui/react-primitive": "^2.0.2" - }, - "peerDependencies": { - "react": "^18 || ^19 || ^19.0.0-rc", - "react-dom": "^18 || ^19 || ^19.0.0-rc" - } - }, - "node_modules/collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/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/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-inspect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cross-inspect/-/cross-inspect-1.0.1.tgz", - "integrity": "sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==", - "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", - "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/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/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dotenv": { - "version": "17.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz", - "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/embla-carousel": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz", - "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==", - "license": "MIT" - }, - "node_modules/embla-carousel-react": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.6.0.tgz", - "integrity": "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==", - "license": "MIT", - "dependencies": { - "embla-carousel": "8.6.0", - "embla-carousel-reactive-utils": "8.6.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" - } - }, - "node_modules/embla-carousel-reactive-utils": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz", - "integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==", - "license": "MIT", - "peerDependencies": { - "embla-carousel": "8.6.0" - } - }, - "node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "license": "MIT" - }, - "node_modules/enhanced-resolve": { - "version": "5.20.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", - "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esast-util-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", - "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/esast-util-from-js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", - "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "acorn": "^8.0.0", - "esast-util-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/esbuild": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", - "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.0", - "@esbuild/android-arm": "0.28.0", - "@esbuild/android-arm64": "0.28.0", - "@esbuild/android-x64": "0.28.0", - "@esbuild/darwin-arm64": "0.28.0", - "@esbuild/darwin-x64": "0.28.0", - "@esbuild/freebsd-arm64": "0.28.0", - "@esbuild/freebsd-x64": "0.28.0", - "@esbuild/linux-arm": "0.28.0", - "@esbuild/linux-arm64": "0.28.0", - "@esbuild/linux-ia32": "0.28.0", - "@esbuild/linux-loong64": "0.28.0", - "@esbuild/linux-mips64el": "0.28.0", - "@esbuild/linux-ppc64": "0.28.0", - "@esbuild/linux-riscv64": "0.28.0", - "@esbuild/linux-s390x": "0.28.0", - "@esbuild/linux-x64": "0.28.0", - "@esbuild/netbsd-arm64": "0.28.0", - "@esbuild/netbsd-x64": "0.28.0", - "@esbuild/openbsd-arm64": "0.28.0", - "@esbuild/openbsd-x64": "0.28.0", - "@esbuild/openharmony-arm64": "0.28.0", - "@esbuild/sunos-x64": "0.28.0", - "@esbuild/win32-arm64": "0.28.0", - "@esbuild/win32-ia32": "0.28.0", - "@esbuild/win32-x64": "0.28.0" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/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-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": "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/node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", - "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/eslint/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/eslint/node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/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/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/eslint/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/eslint/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/eslint/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/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/espree/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/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "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/estree-util-attach-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-build-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-walker": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-scope": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", - "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-to-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-value-to-estree": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.5.0.tgz", - "integrity": "sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/remcohaszing" - } - }, - "node_modules/estree-util-visit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.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/eventsource-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", - "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "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==", - "license": "MIT" - }, - "node_modules/fast-equals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-6.0.0.tgz", - "integrity": "sha512-PFhhIGgdM79r5Uztdj9Zb6Tt1zKafqVfdMGwVca1z5z6fbX7DmsySSuJd8HiP6I1j505DCS83cLxo5rmSNeVEA==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "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/fast-printf": { - "version": "1.6.10", - "resolved": "https://registry.npmjs.org/fast-printf/-/fast-printf-1.6.10.tgz", - "integrity": "sha512-GwTgG9O4FVIdShhbVF3JxOgSBY2+ePGsu2V/UONgoCPzF9VY6ZdBMKsHKCYQHZwNk3qNouUolRDsgVxcVA5G1w==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=10.0" - } - }, - "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "license": "MIT", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/forwarded-parse": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", - "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", - "license": "MIT" - }, - "node_modules/framer-motion": { - "version": "12.38.0", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz", - "integrity": "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==", - "license": "MIT", - "dependencies": { - "motion-dom": "^12.38.0", - "motion-utils": "^12.36.0", - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-east-asian-width": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", - "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "license": "ISC" - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", - "license": "ISC" - }, - "node_modules/glob": { - "version": "13.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", - "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "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/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/graphql": { - "version": "16.13.2", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.2.tgz", - "integrity": "sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==", - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" - } - }, - "node_modules/graphql-type-json": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz", - "integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==", - "license": "MIT", - "peerDependencies": { - "graphql": ">=0.8.0" - } - }, - "node_modules/graphql-yoga": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/graphql-yoga/-/graphql-yoga-5.18.0.tgz", - "integrity": "sha512-xFt1DVXS1BZ3AvjnawAGc5OYieSe56WuQuyk3iEpBwJ3QDZJWQGLmU9z/L5NUZ+pUcyprsz/bOwkYIV96fXt/g==", - "license": "MIT", - "dependencies": { - "@envelop/core": "^5.3.0", - "@envelop/instrumentation": "^1.0.0", - "@graphql-tools/executor": "^1.5.0", - "@graphql-tools/schema": "^10.0.11", - "@graphql-tools/utils": "^10.11.0", - "@graphql-yoga/logger": "^2.0.1", - "@graphql-yoga/subscription": "^5.0.5", - "@whatwg-node/fetch": "^0.10.6", - "@whatwg-node/promise-helpers": "^1.3.2", - "@whatwg-node/server": "^0.10.14", - "lru-cache": "^10.0.0", - "tslib": "^2.8.1" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "graphql": "^15.2.0 || ^16.0.0" - } - }, - "node_modules/graphql-yoga/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, - "node_modules/gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "license": "MIT", - "dependencies": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/gray-matter/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", - "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^9.0.0", - "property-information": "^7.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-heading-rank": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", - "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-properties-to-mdx-jsx-attributes": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/hast-util-properties-to-mdx-jsx-attributes/-/hast-util-properties-to-mdx-jsx-attributes-1.1.1.tgz", - "integrity": "sha512-MMrAoGgvhYULEqMB/r6AlcVz1D3Cyml/9cMB2NIqZsIsEJ+XEXPMqH0gjba8dVs9AnQUYvPReAS+OIYx4ip+Ug==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "estree-util-value-to-estree": "^3.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "property-information": "^7.0.0", - "style-to-js": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/remcohaszing" - } - }, - "node_modules/hast-util-raw": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", - "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", - "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-attach-comments": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-js": "^1.0.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-html": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", - "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^3.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", - "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-js": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", - "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-string": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", - "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", - "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "license": "BSD-3-Clause", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, - "node_modules/hono": { - "version": "4.12.14", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.14.tgz", - "integrity": "sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==", - "license": "MIT", - "engines": { - "node": ">=16.9.0" - } - }, - "node_modules/html-url-attributes": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", - "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/http-terminator": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/http-terminator/-/http-terminator-3.2.0.tgz", - "integrity": "sha512-JLjck1EzPaWjsmIf8bziM3p9fgR1Y3JoUKAkyYEbZmFrIvJM6I8vVJfBGWlEtV9IWOvzNnaTtjuwZeBY2kwB4g==", - "license": "BSD-3-Clause", - "dependencies": { - "delay": "^5.0.0", - "p-wait-for": "^3.2.0", - "roarr": "^7.0.4", - "type-fest": "^2.3.3" - }, - "engines": { - "node": ">=14" - } - }, - "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/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/import-in-the-middle": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.0.1.tgz", - "integrity": "sha512-pYkiyXVL2Mf3pozdlDGV6NAObxQx13Ae8knZk1UJRJ6uRW/ZRmTGHlQYtrsSl7ubuE5F8CD1z+s1n4RHNuTtuA==", - "license": "Apache-2.0", - "dependencies": { - "acorn": "^8.15.0", - "acorn-import-attributes": "^1.9.5", - "cjs-module-lexer": "^2.2.0", - "module-details-from-path": "^1.0.4" - }, - "engines": { - "node": ">=18" - } - }, - "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/inline-style-parser": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", - "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", - "license": "MIT" - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "license": "MIT", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "license": "MIT", - "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==", - "license": "ISC" - }, - "node_modules/javascript-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", - "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", - "license": "MIT" - }, - "node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "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==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "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-to-typescript-lite": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/json-schema-to-typescript-lite/-/json-schema-to-typescript-lite-15.0.0.tgz", - "integrity": "sha512-5mMORSQm9oTLyjM4mWnyNBi2T042Fhg1/0gCIB6X8U/LVpM2A+Nmj2yEyArqVouDmFThDxpEXcnTgSrjkGJRFA==", - "license": "MIT", - "dependencies": { - "@apidevtools/json-schema-ref-parser": "^14.1.1", - "@types/json-schema": "^7.0.15" - } - }, - "node_modules/json-schema-to-typescript-lite/node_modules/@apidevtools/json-schema-ref-parser": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-14.2.1.tgz", - "integrity": "sha512-HmdFw9CDYqM6B25pqGBpNeLCKvGPlIx1EbLrVL0zPvj50CJQUHyBNBw45Muk0kEIkogo1VZvOKHajdMuAzSxRg==", - "license": "MIT", - "dependencies": { - "js-yaml": "^4.1.0" - }, - "engines": { - "node": ">= 20" - }, - "funding": { - "url": "https://github.com/sponsors/philsturgeon" - }, - "peerDependencies": { - "@types/json-schema": "^7.0.15" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "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/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/leven": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-4.1.0.tgz", - "integrity": "sha512-KZ9W9nWDT7rF7Dazg8xyLHGLrmpgq2nVNFUckhqdW3szVP6YhCpp/RAnpmVExA9JvrMynjwSLVrEj3AepHR6ew==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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" - ], - "libc": [ - "glibc" - ], - "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" - ], - "libc": [ - "musl" - ], - "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" - ], - "libc": [ - "glibc" - ], - "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" - ], - "libc": [ - "musl" - ], - "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/loglevel": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", - "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - }, - "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/loglevel" - } - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lucide-react": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.8.0.tgz", - "integrity": "sha512-WuvlsjngSk7TnTBJ1hsCy3ql9V9VOdcPkd3PKcSmM34vJD8KG6molxz7m7zbYFgICwsanQWmJ13JlYs4Zp7Arw==", - "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/markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdown-table": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", - "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mdast-util-directive": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", - "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-frontmatter": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "escape-string-regexp": "^5.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", - "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", - "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", - "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", - "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", - "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-frontmatter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", - "license": "MIT", - "dependencies": { - "fault": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-expression": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", - "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", - "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-md": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", - "license": "MIT", - "dependencies": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^3.0.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs-esm": "^3.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", - "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-events-to-acorn": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", - "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minipass": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", - "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/module-details-from-path": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", - "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", - "license": "MIT" - }, - "node_modules/motion": { - "version": "12.35.1", - "resolved": "https://registry.npmjs.org/motion/-/motion-12.35.1.tgz", - "integrity": "sha512-yEt/49kWC0VU/IEduDfeZw82eDemlPwa1cyo/gcEEUCN4WgpSJpUcxz6BUwakGabvJiTzLQ58J73515I5tfykQ==", - "license": "MIT", - "dependencies": { - "framer-motion": "^12.35.1", - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/motion-dom": { - "version": "12.38.0", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.38.0.tgz", - "integrity": "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==", - "license": "MIT", - "dependencies": { - "motion-utils": "^12.36.0" - } - }, - "node_modules/motion-utils": { - "version": "12.36.0", - "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.36.0.tgz", - "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==", - "license": "MIT" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nanoevents": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/nanoevents/-/nanoevents-9.1.0.tgz", - "integrity": "sha512-Jd0fILWG44a9luj8v5kED4WI+zfkkgwKyRQKItTtlPfEsh7Lznfi1kr8/iZ+XAIss4Qq5GqRB0qtWbaz9ceO/A==", - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "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/next-themes": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", - "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" - } - }, - "node_modules/oauth4webapi": { - "version": "3.8.5", - "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.5.tgz", - "integrity": "sha512-A8jmyUckVhRJj5lspguklcl90Ydqk61H3dcU0oLhH3Yv13KpAliKTt5hknpGGPZSSfOwGyraNEFmofDYH+1kSg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/panva" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/oniguruma-parser": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz", - "integrity": "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==", - "license": "MIT" - }, - "node_modules/oniguruma-to-es": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.6.tgz", - "integrity": "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==", - "license": "MIT", - "dependencies": { - "oniguruma-parser": "^0.12.2", - "regex": "^6.1.0", - "regex-recursion": "^6.0.2" - } - }, - "node_modules/openapi-types": { - "version": "12.1.3", - "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", - "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", - "license": "MIT" - }, - "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-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "license": "MIT", - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-wait-for": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-wait-for/-/p-wait-for-3.2.0.tgz", - "integrity": "sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA==", - "license": "MIT", - "dependencies": { - "p-timeout": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pagefind": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.5.2.tgz", - "integrity": "sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==", - "license": "MIT", - "bin": { - "pagefind": "lib/runner/bin.cjs" - }, - "optionalDependencies": { - "@pagefind/darwin-arm64": "1.5.2", - "@pagefind/darwin-x64": "1.5.2", - "@pagefind/freebsd-x64": "1.5.2", - "@pagefind/linux-arm64": "1.5.2", - "@pagefind/linux-x64": "1.5.2", - "@pagefind/windows-arm64": "1.5.2", - "@pagefind/windows-x64": "1.5.2" - } - }, - "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/parse-entities": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", - "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", - "license": "MIT" - }, - "node_modules/parse-srcset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", - "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==", - "license": "MIT" - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-scurry": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", - "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", - "license": "ISC", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/pg-protocol": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", - "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", - "license": "MIT" - }, - "node_modules/pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "license": "MIT", - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "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/piscina": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.1.4.tgz", - "integrity": "sha512-7uU4ZnKeQq22t9AsmHGD2w4OYQGonwFnTypDypaWi7Qr2EvQIFVtG8J5D/3bE7W123Wdc9+v4CZDu5hJXVCtBg==", - "license": "MIT", - "engines": { - "node": ">=20.x" - }, - "optionalDependencies": { - "@napi-rs/nice": "^1.0.4" - } - }, - "node_modules/postcss": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", - "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/postgres-bytea": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", - "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "license": "MIT", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/posthog-node": { - "version": "5.26.0", - "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-5.26.0.tgz", - "integrity": "sha512-DK1XF/RiunhvT57cFyPxW9OaliZzl5aREHFwY/AISL3MVOaDUb4wIccMn0G3ws3Ounen8iGH7xvzZQ0x2vEOEQ==", - "license": "MIT", - "dependencies": { - "@posthog/core": "1.23.1" - }, - "engines": { - "node": "^20.20.0 || >=22.22.0" - } - }, - "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/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "license": "MIT" - }, - "node_modules/qs": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", - "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/react": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", - "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", - "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", - "license": "MIT", - "dependencies": { - "scheduler": "^0.27.0" - }, - "peerDependencies": { - "react": "^19.2.4" - } - }, - "node_modules/react-error-boundary": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.1.1.tgz", - "integrity": "sha512-BrYwPOdXi5mqkk5lw+Uvt0ThHx32rCt3BkukS4X23A2AIWDPSGX6iaWTc0y9TU/mHDA/6qOSGel+B2ERkOvD1w==", - "license": "MIT", - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0" - } - }, - "node_modules/react-fast-compare": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", - "license": "MIT" - }, - "node_modules/react-hook-form": { - "version": "7.71.2", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.2.tgz", - "integrity": "sha512-1CHvcDYzuRUNOflt4MOq3ZM46AronNJtQ1S7tnX6YN4y72qhgiUItpacZUAQ0TyWYci3yz1X+rXaSxiuEm86PA==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/react-hook-form" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17 || ^18 || ^19" - } - }, - "node_modules/react-is": { - "version": "19.2.5", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.5.tgz", - "integrity": "sha512-Dn0t8IQhCmeIT3wu+Apm1/YVsJXsGWi6k4sPdnBIdqMVtHtv0IGi6dcpNpNkNac0zB2uUAqNX3MHzN8c+z2rwQ==", - "license": "MIT" - }, - "node_modules/react-markdown": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", - "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "html-url-attributes": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "unified": "^11.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@types/react": ">=18", - "react": ">=18" - } - }, - "node_modules/react-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-router": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.1.tgz", - "integrity": "sha512-5BCvFskyAAVumqhEKh/iPhLOIkfxcEUz8WqFIARCkMg8hZZzDYX9CtwxXA0e+qT8zAxmMC0x3Ckb9iMONwc5jg==", - "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-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/recma-build-jsx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", - "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/recma-jsx": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", - "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", - "license": "MIT", - "dependencies": { - "acorn-jsx": "^5.0.0", - "estree-util-to-js": "^2.0.0", - "recma-parse": "^1.0.0", - "recma-stringify": "^1.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/recma-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", - "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "esast-util-from-js": "^2.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/recma-stringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", - "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-util-to-js": "^2.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", - "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-recursion": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", - "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-utilities": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", - "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", - "license": "MIT" - }, - "node_modules/rehype-mdx-import-media": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/rehype-mdx-import-media/-/rehype-mdx-import-media-1.2.0.tgz", - "integrity": "sha512-rf+2qnPv3LTqLtCr8GjhHUja2TEbmwWtD1o4jigrmGWbVDggOMxyNeqJhGpC4E3vtH+sY+a+u9WPSEaskEWPFA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-properties-to-mdx-jsx-attributes": "^1.0.0", - "parse-srcset": "^1.0.0", - "unified": "^11.0.0", - "unist-util-visit": "^5.0.0" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-recma": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", - "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "hast-util-to-estree": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-slug": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", - "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "github-slugger": "^2.0.0", - "hast-util-heading-rank": "^3.0.0", - "hast-util-to-string": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-comment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-k8YPo5MGvl8l4gGxOH6Zk4Fa2AhDACN5eqKnKZcHDORZQS15hlnezlBHj2lqyDiqzApNmYOMTibkEJbMSKU25w==", - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.1.0", - "micromark-util-symbol": "^1.0.1" - } - }, - "node_modules/remark-comment/node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/remark-comment/node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "node_modules/remark-comment/node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/remark-comment/node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/remark-directive": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", - "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-directive": "^3.0.0", - "micromark-extension-directive": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-directive-rehype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/remark-directive-rehype/-/remark-directive-rehype-1.0.0.tgz", - "integrity": "sha512-10XpgKG/v5pqSpp/lLXEqqJ+EeHY1mhmcgSgno1Zw+PygBvkMguY9X39dj5sMkaMt0GbUmlhWidbBqLzFLZmXg==", - "license": "Unlicense", - "dependencies": { - "hastscript": "^9.0.1", - "unist-util-map": "^4.0.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/remark-frontmatter": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-frontmatter": "^2.0.0", - "micromark-extension-frontmatter": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", - "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", - "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", - "license": "MIT", - "dependencies": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx-frontmatter": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/remark-mdx-frontmatter/-/remark-mdx-frontmatter-5.2.0.tgz", - "integrity": "sha512-U/hjUYTkQqNjjMRYyilJgLXSPF65qbLPdoESOkXyrwz2tVyhAnm4GUKhfXqOOS9W34M3545xEMq+aMpHgVjEeQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "estree-util-value-to-estree": "^3.0.0", - "toml": "^3.0.0", - "unified": "^11.0.0", - "unist-util-mdx-define": "^1.0.0", - "yaml": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/remcohaszing" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", - "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-in-the-middle": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-8.0.1.tgz", - "integrity": "sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.5", - "module-details-from-path": "^1.0.3" - }, - "engines": { - "node": ">=9.3.0 || >=8.10.0 <9.0.0" - } - }, - "node_modules/reselect": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", - "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", - "license": "MIT" - }, - "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/roarr": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-7.21.4.tgz", - "integrity": "sha512-qvfUKCrpPzhWmQ4NxRYnuwhkI5lwmObhBU06BCK/lpj6PID9nL4Hk6XDwek2foKI+TMaV+Yw//XZshGF2Lox/Q==", - "license": "BSD-3-Clause", - "dependencies": { - "fast-printf": "^1.6.9", - "safe-stable-stringify": "^2.4.3", - "semver-compare": "^1.0.0" - }, - "engines": { - "node": ">=18.0" - } - }, - "node_modules/rolldown": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.16.tgz", - "integrity": "sha512-rzi5WqKzEZw3SooTt7cgm4eqIoujPIyGcJNGFL7iPEuajQw7vxMHUkXylu4/vhCkJGXsgRmxqMKXUpT6FEgl0g==", - "license": "MIT", - "dependencies": { - "@oxc-project/types": "=0.126.0", - "@rolldown/pluginutils": "1.0.0-rc.16" - }, - "bin": { - "rolldown": "bin/cli.mjs" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0-rc.16", - "@rolldown/binding-darwin-arm64": "1.0.0-rc.16", - "@rolldown/binding-darwin-x64": "1.0.0-rc.16", - "@rolldown/binding-freebsd-x64": "1.0.0-rc.16", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.16", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.16", - "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.16", - "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.16", - "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.16", - "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.16", - "@rolldown/binding-linux-x64-musl": "1.0.0-rc.16", - "@rolldown/binding-openharmony-arm64": "1.0.0-rc.16", - "@rolldown/binding-wasm32-wasi": "1.0.0-rc.16", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.16", - "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.16" - } - }, - "node_modules/rolldown/node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.16", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.16.tgz", - "integrity": "sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA==", - "license": "MIT" - }, - "node_modules/rollup": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.59.0", - "@rollup/rollup-android-arm64": "4.59.0", - "@rollup/rollup-darwin-arm64": "4.59.0", - "@rollup/rollup-darwin-x64": "4.59.0", - "@rollup/rollup-freebsd-arm64": "4.59.0", - "@rollup/rollup-freebsd-x64": "4.59.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", - "@rollup/rollup-linux-arm-musleabihf": "4.59.0", - "@rollup/rollup-linux-arm64-gnu": "4.59.0", - "@rollup/rollup-linux-arm64-musl": "4.59.0", - "@rollup/rollup-linux-loong64-gnu": "4.59.0", - "@rollup/rollup-linux-loong64-musl": "4.59.0", - "@rollup/rollup-linux-ppc64-gnu": "4.59.0", - "@rollup/rollup-linux-ppc64-musl": "4.59.0", - "@rollup/rollup-linux-riscv64-gnu": "4.59.0", - "@rollup/rollup-linux-riscv64-musl": "4.59.0", - "@rollup/rollup-linux-s390x-gnu": "4.59.0", - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@rollup/rollup-linux-x64-musl": "4.59.0", - "@rollup/rollup-openbsd-x64": "4.59.0", - "@rollup/rollup-openharmony-arm64": "4.59.0", - "@rollup/rollup-win32-arm64-msvc": "4.59.0", - "@rollup/rollup-win32-ia32-msvc": "4.59.0", - "@rollup/rollup-win32-x64-gnu": "4.59.0", - "@rollup/rollup-win32-x64-msvc": "4.59.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/safe-stable-stringify": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", - "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/sax": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", - "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=11.0.0" - } - }, - "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/section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "license": "MIT" - }, - "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/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", - "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==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shiki": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.0.2.tgz", - "integrity": "sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ==", - "license": "MIT", - "dependencies": { - "@shikijs/core": "4.0.2", - "@shikijs/engine-javascript": "4.0.2", - "@shikijs/engine-oniguruma": "4.0.2", - "@shikijs/langs": "4.0.2", - "@shikijs/themes": "4.0.2", - "@shikijs/types": "4.0.2", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/sitemap": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-9.0.1.tgz", - "integrity": "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==", - "license": "MIT", - "dependencies": { - "@types/node": "^24.9.2", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.4.1" - }, - "bin": { - "sitemap": "dist/esm/cli.js" - }, - "engines": { - "node": ">=20.19.5", - "npm": ">=10.8.2" - } - }, - "node_modules/sitemap/node_modules/@types/node": { - "version": "24.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz", - "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/sitemap/node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "license": "MIT" - }, - "node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, - "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/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" - }, - "node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "license": "BSD-2-Clause", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "license": "MIT", - "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/style-to-js": { - "version": "1.1.21", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", - "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", - "license": "MIT", - "dependencies": { - "style-to-object": "1.0.14" - } - }, - "node_modules/style-to-object": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", - "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.2.7" - } - }, - "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.5.0", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.5.0.tgz", - "integrity": "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/dcastil" - } - }, - "node_modules/tailwindcss": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", - "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", - "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.16", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", - "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", - "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/toml": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", - "license": "MIT" - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/ts-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==", - "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/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", - "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-map/-/unist-util-map-4.0.0.tgz", - "integrity": "sha512-HJs1tpkSmRJUzj6fskQrS5oYhBYlmtcvy4SepdDEEsL04FjBrgF0Mgggvxc1/qGBGgW7hRh9+UBK1aqTEnBpIA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-mdx-define": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-mdx-define/-/unist-util-mdx-define-1.1.2.tgz", - "integrity": "sha512-9ncH7i7TN5Xn7/tzX5bE3rXgz1X/u877gYVAUB3mLeTKYJmQHmqKTDBi6BTGXV7AeolBCI9ErcVsOt2qryoD0g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-scope": "^1.0.0", - "estree-walker": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/remcohaszing" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", - "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "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/uri-js/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/url": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", - "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", - "license": "MIT", - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.12.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/urlpattern-polyfill": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz", - "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==", - "license": "MIT" - }, - "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/use-sync-external-store": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", - "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/vaul": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz", - "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-dialog": "^1.1.1" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", - "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vite": { - "version": "8.0.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.9.tgz", - "integrity": "sha512-t7g7GVRpMXjNpa67HaVWI/8BWtdVIQPCL2WoozXXA7LBGEFK4AkkKkHx2hAQf5x1GZSlcmEDPkVLSGahxnEEZw==", - "license": "MIT", - "dependencies": { - "lightningcss": "^1.32.0", - "picomatch": "^4.0.4", - "postcss": "^8.5.10", - "rolldown": "1.0.0-rc.16", - "tinyglobby": "^0.2.16" - }, - "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", - "@vitejs/devtools": "^0.1.0", - "esbuild": "^0.27.0 || ^0.28.0", - "jiti": ">=1.21.0", - "less": "^4.0.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 - }, - "@vitejs/devtools": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "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/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/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/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yaml": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", - "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, - "node_modules/yargs": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", - "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", - "license": "MIT", - "dependencies": { - "cliui": "^9.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "string-width": "^7.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^22.0.0" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=23" - } - }, - "node_modules/yargs-parser": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", - "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", - "license": "ISC", - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=23" - } - }, - "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" - } - }, - "node_modules/zod": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", - "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zudoku": { - "version": "0.77.0", - "resolved": "https://registry.npmjs.org/zudoku/-/zudoku-0.77.0.tgz", - "integrity": "sha512-3zFmWFCYejA8GND904r902zrU11f4A1xsYnKIXOLXnllHwGZCU8rYjyW5cViUFs6bMEN2aN2kOJ13HKNxwfo8Q==", - "dependencies": { - "@apidevtools/json-schema-ref-parser": "15.3.5", - "@base-ui/react": "^1.4.0", - "@envelop/core": "5.5.1", - "@graphql-typed-document-node/core": "3.2.0", - "@hono/node-server": "1.19.13", - "@lekoarts/rehype-meta-as-attributes": "3.0.3", - "@mdx-js/react": "3.1.1", - "@mdx-js/rollup": "3.1.1", - "@pothos/core": "4.12.0", - "@radix-ui/react-accordion": "1.2.12", - "@radix-ui/react-alert-dialog": "1.1.15", - "@radix-ui/react-aspect-ratio": "1.1.8", - "@radix-ui/react-checkbox": "1.3.3", - "@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-hover-card": "1.1.15", - "@radix-ui/react-label": "2.1.8", - "@radix-ui/react-navigation-menu": "1.2.14", - "@radix-ui/react-popover": "1.1.15", - "@radix-ui/react-progress": "1.1.8", - "@radix-ui/react-radio-group": "1.3.8", - "@radix-ui/react-scroll-area": "1.2.10", - "@radix-ui/react-select": "2.2.6", - "@radix-ui/react-separator": "^1.1.8", - "@radix-ui/react-slider": "1.3.6", - "@radix-ui/react-slot": "1.2.4", - "@radix-ui/react-switch": "1.2.6", - "@radix-ui/react-tabs": "1.1.13", - "@radix-ui/react-toggle": "1.1.10", - "@radix-ui/react-toggle-group": "1.1.11", - "@radix-ui/react-tooltip": "1.2.8", - "@radix-ui/react-visually-hidden": "1.2.4", - "@scalar/openapi-parser": "0.23.13", - "@sentry/node": "10.49.0", - "@shikijs/langs": "4.0.2", - "@shikijs/rehype": "4.0.2", - "@shikijs/themes": "4.0.2", - "@shikijs/transformers": "4.0.2", - "@tailwindcss/typography": "0.5.19", - "@tailwindcss/vite": "4.2.2", - "@tanem/react-nprogress": "6.0.3", - "@tanstack/react-query": "5.97.0", - "@types/react": "19.2.14", - "@types/react-dom": "19.2.3", - "@vitejs/plugin-react": "6.0.1", - "@x0k/json-schema-merge": "1.0.2", - "@zudoku/httpsnippet": "10.0.9", - "@zudoku/react-helmet-async": "2.0.5", - "@zuplo/mcp": "0.0.32", - "bs58": "6.0.0", - "class-variance-authority": "0.7.1", - "clsx": "2.1.1", - "cmdk": "1.1.1", - "dotenv": "17.3.1", - "embla-carousel-react": "8.6.0", - "esbuild": "^0.28.0", - "estree-util-is-identifier-name": "3.0.0", - "estree-util-value-to-estree": "3.5.0", - "fast-equals": "6.0.0", - "glob": "13.0.6", - "glob-parent": "6.0.2", - "graphql": "16.13.2", - "graphql-type-json": "0.3.2", - "graphql-yoga": "5.18.0", - "gray-matter": "4.0.3", - "hast-util-heading-rank": "3.0.0", - "hast-util-to-jsx-runtime": "2.3.6", - "hast-util-to-string": "3.0.1", - "hono": "4.12.14", - "http-terminator": "3.2.0", - "javascript-stringify": "2.1.0", - "json-schema-to-typescript-lite": "15.0.0", - "loglevel": "1.9.2", - "lucide-react": "1.8.0", - "mdast-util-from-markdown": "2.0.2", - "mdast-util-mdx": "3.0.0", - "mdast-util-mdx-jsx": "3.2.0", - "micromark-extension-mdxjs": "3.0.0", - "motion": "12.35.1", - "nanoevents": "9.1.0", - "next-themes": "0.4.6", - "oauth4webapi": "3.8.5", - "openapi-types": "12.1.3", - "pagefind": "1.5.2", - "picocolors": "1.1.1", - "piscina": "5.1.4", - "posthog-node": "5.26.0", - "react-error-boundary": "6.1.1", - "react-hook-form": "7.71.2", - "react-is": "19.2.5", - "react-markdown": "10.1.0", - "react-router": "7.14.1", - "rehype-mdx-import-media": "1.2.0", - "rehype-raw": "7.0.0", - "rehype-slug": "6.0.0", - "remark-comment": "1.0.0", - "remark-directive": "3.0.1", - "remark-directive-rehype": "1.0.0", - "remark-frontmatter": "5.0.0", - "remark-gfm": "4.0.1", - "remark-mdx-frontmatter": "5.2.0", - "semver": "7.7.4", - "shiki": "4.0.2", - "sitemap": "9.0.1", - "strip-ansi": "7.2.0", - "tailwind-merge": "3.5.0", - "tailwindcss": "4.2.1", - "tw-animate-css": "1.4.0", - "unified": "11.0.5", - "unist-util-visit": "5.1.0", - "vaul": "1.1.2", - "vfile": "6.0.3", - "vite": "8.0.9", - "yaml": "2.8.3", - "yargs": "18.0.0", - "zod": "4.3.6", - "zustand": "5.0.12" - }, - "bin": { - "zudoku": "cli.js" - }, - "peerDependencies": { - "@azure/msal-browser": "^4.13.0", - "@sentry/react": "^10.0.0", - "@supabase/supabase-js": "^2.49.4", - "firebase": "^12.6.0", - "mermaid": "^11.0.0", - "react": ">=19.2.0", - "react-dom": ">=19.2.0" - }, - "peerDependenciesMeta": { - "@azure/msal-browser": { - "optional": true - }, - "@sentry/react": { - "optional": true - }, - "@supabase/supabase-js": { - "optional": true - }, - "firebase": { - "optional": true - }, - "mermaid": { - "optional": true - } - } - }, - "node_modules/zustand": { - "version": "5.0.12", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.12.tgz", - "integrity": "sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==", - "license": "MIT", - "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@types/react": ">=18.0.0", - "immer": ">=9.0.6", - "react": ">=18.0.0", - "use-sync-external-store": ">=1.2.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - }, - "use-sync-external-store": { - "optional": true - } - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..cf306af4 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,8010 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@shikijs/vscode-textmate': + specifier: ^10.0.2 + version: 10.0.2 + hast-util-to-html: + specifier: ^9.0.5 + version: 9.0.5 + oniguruma-parser: + specifier: ^0.12.1 + version: 0.12.2 + react: + specifier: '>=19.0.0' + version: 19.2.5 + react-dom: + specifier: '>=19.0.0' + version: 19.2.5(react@19.2.5) + regex-utilities: + specifier: ^2.3.0 + version: 2.3.0 + zudoku: + specifier: ^0.77.0 + version: 0.77.0(@types/json-schema@7.0.15)(@types/node@25.6.0)(jiti@2.7.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(rollup@4.60.3)(use-sync-external-store@1.6.0(react@19.2.5)) + devDependencies: + '@typescript-eslint/eslint-plugin': + specifier: ^8.0.0 + version: 8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': + specifier: ^8.0.0 + version: 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + eslint: + specifier: ^9.14.0 + version: 9.39.4(jiti@2.7.0) + +packages: + + '@apidevtools/json-schema-ref-parser@14.2.1': + resolution: {integrity: sha512-HmdFw9CDYqM6B25pqGBpNeLCKvGPlIx1EbLrVL0zPvj50CJQUHyBNBw45Muk0kEIkogo1VZvOKHajdMuAzSxRg==} + engines: {node: '>= 20'} + peerDependencies: + '@types/json-schema': ^7.0.15 + + '@apidevtools/json-schema-ref-parser@15.3.5': + resolution: {integrity: sha512-orNOYXw3hYXxxisXMldjzjBzqqTLBPbwOtHg7ovBPvfBHDue1qM9YJENZ3W2BQuS+7z4ThogMbEzEsov57Itkg==} + engines: {node: '>=20'} + peerDependencies: + '@types/json-schema': ^7.0.15 + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@base-ui/react@1.4.1': + resolution: {integrity: sha512-Ab5/LIhcmL8BQcsBUYiOfkSDRdLpvgUBzMK30cu684JPcLclYlztharvCZyNNgzJtbAiREzI9q0pI5erHCMgCw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@date-fns/tz': ^1.2.0 + '@types/react': ^17 || ^18 || ^19 + date-fns: ^4.0.0 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + '@date-fns/tz': + optional: true + '@types/react': + optional: true + date-fns: + optional: true + + '@base-ui/utils@0.2.8': + resolution: {integrity: sha512-jvOi+c+ftGlGotNcKnzPVg2IhCaDTB6/6R3JeqdjdXktuAJi3wKH9T7+svuaKh1mmfVU11UWzUZVH74JDfi/wQ==} + peerDependencies: + '@types/react': ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + '@types/react': + optional: true + + '@emnapi/core@1.9.2': + resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + + '@emnapi/runtime@1.9.2': + resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@envelop/core@5.5.1': + resolution: {integrity: sha512-3DQg8sFskDo386TkL5j12jyRAdip/8yzK3x7YGbZBgobZ4aKXrvDU0GppU0SnmrpQnNaiTUsxBs9LKkwQ/eyvw==} + engines: {node: '>=18.0.0'} + + '@envelop/instrumentation@1.0.0': + resolution: {integrity: sha512-cxgkB66RQB95H3X27jlnxCRNTmPuSTgmBAq6/4n2Dtv4hsk4yz8FadA1ggmd0uZzvKqWD6CR+WFgTjhDqg7eyw==} + engines: {node: '>=18.0.0'} + + '@envelop/types@5.2.1': + resolution: {integrity: sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg==} + engines: {node: '>=18.0.0'} + + '@esbuild/aix-ppc64@0.28.0': + resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.0': + resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.0': + resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.0': + resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.0': + resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.0': + resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.0': + resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.0': + resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.0': + resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.0': + resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.0': + resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.0': + resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.0': + resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.0': + resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.0': + resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.0': + resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.0': + resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.0': + resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.0': + resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.0': + resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.0': + resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.0': + resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.0': + resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.0': + resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.0': + resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.0': + resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@fastify/busboy@3.2.0': + resolution: {integrity: sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==} + + '@fastify/otel@0.18.0': + resolution: {integrity: sha512-3TASCATfw+ctICSb4ymrv7iCm0qJ0N9CarB+CZ7zIJ7KqNbwI5JjyDL1/sxoC0ccTO1Zyd1iQ+oqncPg5FJXaA==} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + + '@floating-ui/react-dom@2.1.8': + resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + + '@graphql-tools/executor@1.5.3': + resolution: {integrity: sha512-mgBFC0bsrZPZLu9EnydpMnAuQ8Iiq0CEbUcsmvXsm2/iYektGHDN/+bmb7hicA6dWZtdPfklYJmr21WD0GnOfA==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/merge@9.1.9': + resolution: {integrity: sha512-iHUWNjRHeQRYdgIMIuChThOwoKzA9vrzYeslgfBo5eUYEyHGZCoDPjAavssoYXLwstYt1dZj2J22jSzc2DrN0Q==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/schema@10.0.33': + resolution: {integrity: sha512-O6P3RIftO0jafnSsFAqpjurUuUxJ43s/AdPVLQsBkI6y4Ic/tKm4C1Qm1KKQsCDTOxXPJClh/v3g7k7yLKCFBQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/utils@10.11.0': + resolution: {integrity: sha512-iBFR9GXIs0gCD+yc3hoNswViL1O5josI33dUqiNStFI/MHLCEPduasceAcazRH77YONKNiviHBV8f7OgcT4o2Q==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-tools/utils@11.1.0': + resolution: {integrity: sha512-PtFVG4r8Z2LEBSaPYQMusBiB3o6kjLVJyjCLbnWem/SpSuM21v6LTmgpkXfYU1qpBV2UGsFyuEnSJInl8fR1Ag==} + engines: {node: '>=16.0.0'} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-typed-document-node/core@3.2.0': + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + + '@graphql-yoga/logger@2.0.1': + resolution: {integrity: sha512-Nv0BoDGLMg9QBKy9cIswQ3/6aKaKjlTh87x3GiBg2Z4RrjyrM48DvOOK0pJh1C1At+b0mUIM67cwZcFTDLN4sA==} + engines: {node: '>=18.0.0'} + + '@graphql-yoga/subscription@5.0.5': + resolution: {integrity: sha512-oCMWOqFs6QV96/NZRt/ZhTQvzjkGB4YohBOpKM4jH/lDT4qb7Lex/aGCxpi/JD9njw3zBBtMqxbaC22+tFHVvw==} + engines: {node: '>=18.0.0'} + + '@graphql-yoga/typed-event-target@3.0.2': + resolution: {integrity: sha512-ZpJxMqB+Qfe3rp6uszCQoag4nSw42icURnBRfFYSOmTgEeOe4rD0vYlbA8spvCu2TlCesNTlEN9BLWtQqLxabA==} + engines: {node: '>=18.0.0'} + + '@hono/node-server@1.19.13': + resolution: {integrity: sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@lekoarts/rehype-meta-as-attributes@3.0.3': + resolution: {integrity: sha512-DyG740U2y8ZWU5ZsAGzKfdVKOENg9UZsCBUJ3DVaWT7ZMHhDG5U0CjLj40CsEsJJ1gauaQPlrU9QUg5uSa4RFg==} + engines: {node: '>=18.0.0'} + + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + + '@mdx-js/rollup@3.1.1': + resolution: {integrity: sha512-v8satFmBB+DqDzYohnm1u2JOvxx6Hl3pUvqzJvfs2Zk/ngZ1aRUhsWpXvwPkNeGN9c2NCm/38H29ZqXQUjf8dw==} + peerDependencies: + rollup: '>=2' + + '@napi-rs/nice-android-arm-eabi@1.1.1': + resolution: {integrity: sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + + '@napi-rs/nice-android-arm64@1.1.1': + resolution: {integrity: sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@napi-rs/nice-darwin-arm64@1.1.1': + resolution: {integrity: sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@napi-rs/nice-darwin-x64@1.1.1': + resolution: {integrity: sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@napi-rs/nice-freebsd-x64@1.1.1': + resolution: {integrity: sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@napi-rs/nice-linux-arm-gnueabihf@1.1.1': + resolution: {integrity: sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@napi-rs/nice-linux-arm64-gnu@1.1.1': + resolution: {integrity: sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@napi-rs/nice-linux-arm64-musl@1.1.1': + resolution: {integrity: sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@napi-rs/nice-linux-ppc64-gnu@1.1.1': + resolution: {integrity: sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==} + engines: {node: '>= 10'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@napi-rs/nice-linux-riscv64-gnu@1.1.1': + resolution: {integrity: sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@napi-rs/nice-linux-s390x-gnu@1.1.1': + resolution: {integrity: sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==} + engines: {node: '>= 10'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@napi-rs/nice-linux-x64-gnu@1.1.1': + resolution: {integrity: sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@napi-rs/nice-linux-x64-musl@1.1.1': + resolution: {integrity: sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@napi-rs/nice-openharmony-arm64@1.1.1': + resolution: {integrity: sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [openharmony] + + '@napi-rs/nice-win32-arm64-msvc@1.1.1': + resolution: {integrity: sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@napi-rs/nice-win32-ia32-msvc@1.1.1': + resolution: {integrity: sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@napi-rs/nice-win32-x64-msvc@1.1.1': + resolution: {integrity: sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@napi-rs/nice@1.1.1': + resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} + engines: {node: '>= 10'} + + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + + '@opentelemetry/api-logs@0.207.0': + resolution: {integrity: sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/api-logs@0.212.0': + resolution: {integrity: sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/api-logs@0.214.0': + resolution: {integrity: sha512-40lSJeqYO8Uz2Yj7u94/SJWE/wONa7rmMKjI1ZcIjgf3MHNHv1OZUCrCETGuaRF62d5pQD1wKIW+L4lmSMTzZA==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/api@1.9.1': + resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/core@2.6.1': + resolution: {integrity: sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/core@2.7.1': + resolution: {integrity: sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/instrumentation-amqplib@0.61.0': + resolution: {integrity: sha512-mCKoyTGfRNisge4br0NpOFSy2Z1NnEW8hbCJdUDdJFHrPqVzc4IIBPA/vX0U+LUcQqrQvJX+HMIU0dbDRe0i0Q==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-connect@0.57.0': + resolution: {integrity: sha512-FMEBChnI4FLN5TE9DHwfH7QpNir1JzXno1uz/TAucVdLCyrG0jTrKIcNHt/i30A0M2AunNBCkcd8Ei26dIPKdg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-dataloader@0.31.0': + resolution: {integrity: sha512-f654tZFQXS5YeLDNb9KySrwtg7SnqZN119FauD7acBoTzuLduaiGTNz88ixcVSOOMGZ+EjJu/RFtx5klObC95g==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-fs@0.33.0': + resolution: {integrity: sha512-sCZWXGalQ01wr3tAhSR9ucqFJ0phidpAle6/17HVjD6gN8FLmZMK/8sKxdXYHy3PbnlV1P4zeiSVFNKpbFMNLA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-generic-pool@0.57.0': + resolution: {integrity: sha512-orhmlaK+ZIW9hKU+nHTbXrCSXZcH83AescTqmpamHRobRmYSQwRbD0a1odc0yAzuzOtxYiHiXAnpnIpaSSY7Ow==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-graphql@0.62.0': + resolution: {integrity: sha512-3YNuLVPUxafXkH1jBAbGsKNsP3XVzcFDhCDCE3OqBwCwShlqQbLMRMFh1T/d5jaVZiGVmSsfof+ICKD2iOV8xg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-hapi@0.60.0': + resolution: {integrity: sha512-aNljZKYrEa7obLAxd1bCEDxF7kzCLGXTuTJZ8lMR9rIVEjmuKBXN1gfqpm/OB//Zc2zP4iIve1jBp7sr3mQV6w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-http@0.214.0': + resolution: {integrity: sha512-FlkDhZDRjDJDcO2LcSCtjRpkal1NJ8y0fBqBhTvfAR3JSYY2jAIj1kSS5IjmEBt4c3aWv+u/lqLuoCDrrKCSKg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-ioredis@0.62.0': + resolution: {integrity: sha512-ZYt//zcPve8qklaZX+5Z4MkU7UpEkFRrxsf2cnaKYBitqDnsCN69CPAuuMOX6NYdW2rG9sFy7V/QWtBlP5XiNQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-kafkajs@0.23.0': + resolution: {integrity: sha512-4K+nVo+zI+aDz0Z85SObwbdixIbzS9moIuKJaYsdlzcHYnKOPtB7ya8r8Ezivy/GVIBHiKJVq4tv+BEkgOMLaQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-knex@0.58.0': + resolution: {integrity: sha512-Hc/o8fSsaWxZ8r1Yw4rNDLwTpUopTf4X32y4W6UhlHmW8Wizz8wfhgOKIelSeqFVTKBBPIDUOsQWuIMxBmu8Bw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-koa@0.62.0': + resolution: {integrity: sha512-uVip0VuGUQXZ+vFxkKxAUNq8qNl+VFlyHDh/U6IQ8COOEDfbEchdaHnpFrMYF3psZRUuoSIgb7xOeXj00RdwDA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + + '@opentelemetry/instrumentation-lru-memoizer@0.58.0': + resolution: {integrity: sha512-6grM3TdMyHzlGY1cUA+mwoPueB1F3dYKgKtZIH6jOFXqfHAByyLTc+6PFjGM9tKh52CFBJaDwodNlL/Td39z7Q==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mongodb@0.67.0': + resolution: {integrity: sha512-1WJp5N1lYfHq2IhECOTewFs5Tf2NfUOwQRqs/rZdXKTezArMlucxgzAaqcgp3A3YREXopXTpXHsxZTGHjNhMdQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mongoose@0.60.0': + resolution: {integrity: sha512-8BahAZpKsOoc+lrZGb7Ofn4g3z8qtp5IxDfvAVpKXsEheQN7ONMH5djT5ihy6yf8yyeQJGS0gXFfpEAEeEHqQg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mysql2@0.60.0': + resolution: {integrity: sha512-m/5d3bxQALllCzezYDk/6vajh0tj5OijMMvOZGr+qN1NMXm1dzMNwyJ0gNZW7Fo3YFRyj/jJMxIw+W7d525dlw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mysql@0.60.0': + resolution: {integrity: sha512-08pO8GFPEIz2zquKDGteBZDNmwketdgH8hTe9rVYgW9kCJXq1Psj3wPQGx+VaX4ZJKCfPeoLMYup9+cxHvZyVQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-pg@0.66.0': + resolution: {integrity: sha512-KxfLGXBb7k2ueaPJfq2GXBDXBly8P+SpR/4Mj410hhNgmQF3sCqwXvUBQxZQkDAmsdBAoenM+yV1LhtsMRamcA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-redis@0.62.0': + resolution: {integrity: sha512-y3pPpot7WzR/8JtHcYlTYsyY8g+pbFhAqbwAuG5bLPnR6v6pt1rQc0DpH0OlGP/9CZbWBP+Zhwp9yFoygf/ZXQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-tedious@0.33.0': + resolution: {integrity: sha512-Q6WQwAD01MMTub31GlejoiFACYNw26J426wyjvU7by7fDIr2nZXNW4vhTGs7i7F0TnXBO3xN688g1tdUgYwJ5w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-undici@0.24.0': + resolution: {integrity: sha512-oKzZ3uvqP17sV0EsoQcJgjEfIp0kiZRbYu/eD8p13Cbahumf8lb/xpYeNr/hfAJ4owzEtIDcGIjprfLcYbIKBQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.7.0 + + '@opentelemetry/instrumentation@0.207.0': + resolution: {integrity: sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation@0.212.0': + resolution: {integrity: sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation@0.214.0': + resolution: {integrity: sha512-MHqEX5Dk59cqVah5LiARMACku7jXSVk9iVDWOea4x3cr7VfdByeDCURK6o1lntT1JS/Tsovw01UJrBhN3/uC5w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/redis-common@0.38.3': + resolution: {integrity: sha512-VCghU1JYs/4gP6Gqf/xro9MEsZ7LrMv2uONVsaESKL38ZOB9BqnI98FfS23wjMnHlpuE+TTaWSoAVNpTwYXzjw==} + engines: {node: ^18.19.0 || >=20.6.0} + + '@opentelemetry/resources@2.7.1': + resolution: {integrity: sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-trace-base@2.7.1': + resolution: {integrity: sha512-NAYIlsF8MPUsKqJMiDQJTMPOmlbawC1Iz/omMLygZ1C9am8fTKYjTaI+OZM+WTY3t3Glo0wnOg/6/pac6RGPPw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/semantic-conventions@1.40.0': + resolution: {integrity: sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==} + engines: {node: '>=14'} + + '@opentelemetry/sql-common@0.41.2': + resolution: {integrity: sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.1.0 + + '@oxc-project/types@0.126.0': + resolution: {integrity: sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==} + + '@pagefind/darwin-arm64@1.5.2': + resolution: {integrity: sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==} + cpu: [arm64] + os: [darwin] + + '@pagefind/darwin-x64@1.5.2': + resolution: {integrity: sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==} + cpu: [x64] + os: [darwin] + + '@pagefind/freebsd-x64@1.5.2': + resolution: {integrity: sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==} + cpu: [x64] + os: [freebsd] + + '@pagefind/linux-arm64@1.5.2': + resolution: {integrity: sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==} + cpu: [arm64] + os: [linux] + + '@pagefind/linux-x64@1.5.2': + resolution: {integrity: sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==} + cpu: [x64] + os: [linux] + + '@pagefind/windows-arm64@1.5.2': + resolution: {integrity: sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==} + cpu: [arm64] + os: [win32] + + '@pagefind/windows-x64@1.5.2': + resolution: {integrity: sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==} + cpu: [x64] + os: [win32] + + '@posthog/core@1.23.1': + resolution: {integrity: sha512-GViD5mOv/mcbZcyzz3z9CS0R79JzxVaqEz4sP5Dsea178M/j3ZWe6gaHDZB9yuyGfcmIMQ/8K14yv+7QrK4sQQ==} + + '@pothos/core@4.12.0': + resolution: {integrity: sha512-PeiODrj3GjQ7Nbs/5p65DEyBWZTSGGjgGO/BgaMEqS1jBNX/2zJTEQJA9zM5uPmCHUCDjE7Qn2U7lOi0ALp/8A==} + peerDependencies: + graphql: ^16.10.0 + + '@prisma/instrumentation@7.6.0': + resolution: {integrity: sha512-ZPW2gRiwpPzEfgeZgaekhqXrbW+Y2RJKHVqUmlhZhKzRNCcvR6DykzylDrynpArKKRQtLxoZy36fK7U0p3pdgQ==} + peerDependencies: + '@opentelemetry/api': ^1.8 + + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + + '@radix-ui/react-accordion@1.2.12': + resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==} + 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 + + '@radix-ui/react-alert-dialog@1.1.15': + resolution: {integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==} + 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 + + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + 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 + + '@radix-ui/react-aspect-ratio@1.1.8': + resolution: {integrity: sha512-5nZrJTF7gH+e0nZS7/QxFz6tJV4VimhQb1avEgtsJxvvIp5JilL+c58HICsKzPxghdwaDt48hEfPM1au4zGy+w==} + 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 + + '@radix-ui/react-checkbox@1.3.3': + resolution: {integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==} + 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 + + '@radix-ui/react-collapsible@1.1.12': + resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} + 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 + + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + 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 + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.3': + resolution: {integrity: sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + 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 + + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + 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 + + '@radix-ui/react-dropdown-menu@2.1.16': + resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} + 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 + + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + 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 + + '@radix-ui/react-hover-card@1.1.15': + resolution: {integrity: sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==} + 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 + + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-label@2.1.8': + resolution: {integrity: sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==} + 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 + + '@radix-ui/react-menu@2.1.16': + resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} + 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 + + '@radix-ui/react-navigation-menu@1.2.14': + resolution: {integrity: sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==} + 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 + + '@radix-ui/react-popover@1.1.15': + resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} + 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 + + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + 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 + + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + 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 + + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + 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 + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + 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 + + '@radix-ui/react-primitive@2.1.4': + resolution: {integrity: sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==} + 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 + + '@radix-ui/react-progress@1.1.8': + resolution: {integrity: sha512-+gISHcSPUJ7ktBy9RnTqbdKW78bcGke3t6taawyZ71pio1JewwGSJizycs7rLhGTvMJYCQB1DBK4KQsxs7U8dA==} + 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 + + '@radix-ui/react-radio-group@1.3.8': + resolution: {integrity: sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==} + 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 + + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} + 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 + + '@radix-ui/react-scroll-area@1.2.10': + resolution: {integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==} + 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 + + '@radix-ui/react-select@2.2.6': + resolution: {integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==} + 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 + + '@radix-ui/react-separator@1.1.8': + resolution: {integrity: sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==} + 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 + + '@radix-ui/react-slider@1.3.6': + resolution: {integrity: sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==} + 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 + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-switch@1.2.6': + resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} + 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 + + '@radix-ui/react-tabs@1.1.13': + resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} + 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 + + '@radix-ui/react-toggle-group@1.1.11': + resolution: {integrity: sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==} + 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 + + '@radix-ui/react-toggle@1.1.10': + resolution: {integrity: sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==} + 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 + + '@radix-ui/react-tooltip@1.2.8': + resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} + 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 + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.2.3': + resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + 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 + + '@radix-ui/react-visually-hidden@1.2.4': + resolution: {integrity: sha512-kaeiyGCe844dkb9AVF+rb4yTyb1LiLN/e3es3nLiRyN4dC8AduBYPMnnNlDjX2VDOcvDEiPnRNMJeWCfsX0txg==} + 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 + + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + + '@repeaterjs/repeater@3.0.6': + resolution: {integrity: sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==} + + '@rolldown/binding-android-arm64@1.0.0-rc.16': + resolution: {integrity: sha512-rhY3k7Bsae9qQfOtph2Pm2jZEA+s8Gmjoz4hhmx70K9iMQ/ddeae+xhRQcM5IuVx5ry1+bGfkvMn7D6MJggVSA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-rc.16': + resolution: {integrity: sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-rc.16': + resolution: {integrity: sha512-r/OmdR00HmD4i79Z//xO06uEPOq5hRXdhw7nzkxQxwSavs3PSHa1ijntdpOiZ2mzOQ3fVVu8C1M19FoNM+dMUQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-rc.16': + resolution: {integrity: sha512-KcRE5w8h0OnjUatG8pldyD14/CQ5Phs1oxfR+3pKDjboHRo9+MkqQaiIZlZRpsxC15paeXme/I127tUa9TXJ6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.16': + resolution: {integrity: sha512-bT0guA1bpxEJ/ZhTRniQf7rNF8ybvXOuWbNIeLABaV5NGjx4EtOWBTSRGWFU9ZWVkPOZ+HNFP8RMcBokBiZ0Kg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.16': + resolution: {integrity: sha512-+tHktCHWV8BDQSjemUqm/Jl/TPk3QObCTIjmdDy/nlupcujZghmKK2962LYrqFpWu+ai01AN/REOH3NEpqvYQg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.16': + resolution: {integrity: sha512-3fPzdREH806oRLxpTWW1Gt4tQHs0TitZFOECB2xzCFLPKnSOy90gwA7P29cksYilFO6XVRY1kzga0cL2nRjKPg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.16': + resolution: {integrity: sha512-EKwI1tSrLs7YVw+JPJT/G2dJQ1jl9qlTTTEG0V2Ok/RdOenRfBw2PQdLPyjhIu58ocdBfP7vIRN/pvMsPxs/AQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.16': + resolution: {integrity: sha512-Uknladnb3Sxqu6SEcqBldQyJUpk8NleooZEc0MbRBJ4inEhRYWZX0NJu12vNf2mqAq7gsofAxHrGghiUYjhaLQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.16': + resolution: {integrity: sha512-FIb8+uG49sZBtLTn+zt1AJ20TqVcqWeSIyoVt0or7uAWesgKaHbiBh6OpA/k9v0LTt+PTrb1Lao133kP4uVxkg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.16': + resolution: {integrity: sha512-RuERhF9/EgWxZEXYWCOaViUWHIboceK4/ivdtQ3R0T44NjLkIIlGIAVAuCddFxsZ7vnRHtNQUrt2vR2n2slB2w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.16': + resolution: {integrity: sha512-mXcXnvd9GpazCxeUCCnZ2+YF7nut+ZOEbE4GtaiPtyY6AkhZWbK70y1KK3j+RDhjVq5+U8FySkKRb/+w0EeUwA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.16': + resolution: {integrity: sha512-3Q2KQxnC8IJOLqXmUMoYwyIPZU9hzRbnHaoV3Euz+VVnjZKcY8ktnNP8T9R4/GGQtb27C/UYKABxesKWb8lsvQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.16': + resolution: {integrity: sha512-tj7XRemQcOcFwv7qhpUxMTBbI5mWMlE4c1Omhg5+h8GuLXzyj8HviYgR+bB2DMDgRqUE+jiDleqSCRjx4aYk/Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.16': + resolution: {integrity: sha512-PH5DRZT+F4f2PTXRXR8uJxnBq2po/xFtddyabTJVJs/ZYVHqXPEgNIr35IHTEa6bpa0Q8Awg+ymkTaGnKITw4g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-rc.16': + resolution: {integrity: sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA==} + + '@rolldown/pluginutils@1.0.0-rc.7': + resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.60.3': + resolution: {integrity: sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.60.3': + resolution: {integrity: sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.60.3': + resolution: {integrity: sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.60.3': + resolution: {integrity: sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.60.3': + resolution: {integrity: sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.60.3': + resolution: {integrity: sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.60.3': + resolution: {integrity: sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.60.3': + resolution: {integrity: sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.60.3': + resolution: {integrity: sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.60.3': + resolution: {integrity: sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.60.3': + resolution: {integrity: sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.60.3': + resolution: {integrity: sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.60.3': + resolution: {integrity: sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.60.3': + resolution: {integrity: sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.60.3': + resolution: {integrity: sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.60.3': + resolution: {integrity: sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.60.3': + resolution: {integrity: sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.60.3': + resolution: {integrity: sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.60.3': + resolution: {integrity: sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.60.3': + resolution: {integrity: sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.3': + resolution: {integrity: sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.3': + resolution: {integrity: sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.3': + resolution: {integrity: sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.60.3': + resolution: {integrity: sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.3': + resolution: {integrity: sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==} + cpu: [x64] + os: [win32] + + '@scalar/helpers@0.2.7': + resolution: {integrity: sha512-uFTcdi3XYDDuaJLWiMuM3ijQit1OBw7AkuOuujReY8L9UmUQHY56erYg0+Db3llTsinuIYFh+eS/WX/sYuevYQ==} + engines: {node: '>=20'} + + '@scalar/json-magic@0.9.0': + resolution: {integrity: sha512-aSWd8rd3O73Ak9Ylson2TywvOuTjjOYiXydl9Cn8Ip/r7fi+h0QqAGom5gqo/WewrhySF9v+H/sW/Qmd05T/Kg==} + engines: {node: '>=20'} + + '@scalar/openapi-parser@0.23.13': + resolution: {integrity: sha512-YsljPOKOgQgZL/kBcEouwz2CUa+2hFfThlUZRWC2DFI2Fnw5Ur8F1IvGgPqCAHr9p2XMH+Z/Pag2jZUfLcxcww==} + engines: {node: '>=20'} + + '@scalar/openapi-types@0.5.3': + resolution: {integrity: sha512-m4n/Su3K01d15dmdWO1LlqecdSPKuNjuokrJLdiQ485kW/hRHbXW1QP6tJL75myhw/XhX5YhYAR+jrwnGjXiMw==} + engines: {node: '>=20'} + + '@scalar/openapi-upgrader@0.1.7': + resolution: {integrity: sha512-065froUtqvaHjyeJtyitf8tb+k7oh7nU0OinAHYbj1Bqgwb1s2+uKMqHYHEES5CNpp+2xtL4lxup6Aq29yW+sQ==} + engines: {node: '>=20'} + + '@sentry/core@10.49.0': + resolution: {integrity: sha512-UaFeum3LUM1mB0d67jvKnqId1yWQjyqmaDV6kWngG03x+jqXb08tJdGpSoxjXZe13jFBbiBL/wKDDYIK7rCK4g==} + engines: {node: '>=18'} + + '@sentry/node-core@10.49.0': + resolution: {integrity: sha512-7WO0KuCDPSq3G54TVUSI1CKFJwB67LasG+n/gDMBqbrarzs/Yh/s34OOMU5gfVQpncxQAmQsy4nEboQms8iNqA==} + engines: {node: '>=18'} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + '@opentelemetry/core': ^1.30.1 || ^2.1.0 + '@opentelemetry/exporter-trace-otlp-http': '>=0.57.0 <1' + '@opentelemetry/instrumentation': '>=0.57.1 <1' + '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 + '@opentelemetry/semantic-conventions': ^1.39.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@opentelemetry/core': + optional: true + '@opentelemetry/exporter-trace-otlp-http': + optional: true + '@opentelemetry/instrumentation': + optional: true + '@opentelemetry/sdk-trace-base': + optional: true + '@opentelemetry/semantic-conventions': + optional: true + + '@sentry/node@10.49.0': + resolution: {integrity: sha512-xr+HXABCiO5mgAJRQxsXRdNOLO0+Ee6CvXAAIqovL2A1GlhxNWc5ooPWeIrrLDJ/KGyT8zI91O5scpVXdXs0uQ==} + engines: {node: '>=18'} + + '@sentry/opentelemetry@10.49.0': + resolution: {integrity: sha512-XNLm4dXmtegXQf+EEE2Cs84Ymlo/f5wMx+lg2S2XS4qLbXaPN/HttjhwKftd8D+8iUNfmH+xNMCSshx4s1B/1w==} + engines: {node: '>=18'} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + '@opentelemetry/core': ^1.30.1 || ^2.1.0 + '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 + '@opentelemetry/semantic-conventions': ^1.39.0 + + '@shikijs/core@4.0.2': + resolution: {integrity: sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw==} + engines: {node: '>=20'} + + '@shikijs/engine-javascript@4.0.2': + resolution: {integrity: sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag==} + engines: {node: '>=20'} + + '@shikijs/engine-oniguruma@4.0.2': + resolution: {integrity: sha512-UpCB9Y2sUKlS9z8juFSKz7ZtysmeXCgnRF0dlhXBkmQnek7lAToPte8DkxmEYGNTMii72zU/lyXiCB6StuZeJg==} + engines: {node: '>=20'} + + '@shikijs/langs@4.0.2': + resolution: {integrity: sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg==} + engines: {node: '>=20'} + + '@shikijs/primitive@4.0.2': + resolution: {integrity: sha512-M6UMPrSa3fN5ayeJwFVl9qWofl273wtK1VG8ySDZ1mQBfhCpdd8nEx7nPZ/tk7k+TYcpqBZzj/AnwxT9lO+HJw==} + engines: {node: '>=20'} + + '@shikijs/rehype@4.0.2': + resolution: {integrity: sha512-cmPlKLD8JeojasNFoY64162ScpEdEdQUMuVodPCrv1nx1z3bjmGwoKWDruQWa/ejSznImlaeB0Ty6Q3zPaVQAA==} + engines: {node: '>=20'} + + '@shikijs/themes@4.0.2': + resolution: {integrity: sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA==} + engines: {node: '>=20'} + + '@shikijs/transformers@4.0.2': + resolution: {integrity: sha512-1+L0gf9v+SdDXs08vjaLb3mBFa8U7u37cwcBQIv/HCocLwX69Tt6LpUCjtB+UUTvQxI7BnjZKhN/wMjhHBcJGg==} + engines: {node: '>=20'} + + '@shikijs/types@4.0.2': + resolution: {integrity: sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg==} + engines: {node: '>=20'} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@tailwindcss/node@4.2.2': + resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==} + + '@tailwindcss/oxide-android-arm64@4.2.2': + resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.2.2': + resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.2.2': + resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==} + engines: {node: '>= 20'} + + '@tailwindcss/typography@0.5.19': + resolution: {integrity: sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' + + '@tailwindcss/vite@4.2.2': + resolution: {integrity: sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 || ^8 + + '@tanem/react-nprogress@6.0.3': + resolution: {integrity: sha512-OT3KZiJv/zGI/lEwX3gD9nzNnyUQuSdSL0BK3OJIUC3Prx3JD18u13TZRvzasEXxHPGzm6AtBEr6gYxPeVWjWw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/query-core@5.97.0': + resolution: {integrity: sha512-QdpLP5VzVMgo4VtaPppRA2W04UFjIqX+bxke/ZJhE5cfd5UPkRzqIAJQt9uXkQJjqE8LBOMbKv7f8HCsZltXlg==} + + '@tanstack/react-query@5.97.0': + resolution: {integrity: sha512-y4So4eGcQoK2WVMAcDNZE9ofB/p5v1OlKvtc1F3uqHwrtifobT7q+ZnXk2mRkc8E84HKYSlAE9z6HXl2V0+ySQ==} + peerDependencies: + react: ^18 || ^19 + + '@tybys/wasm-util@0.10.2': + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/mysql@2.15.27': + resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==} + + '@types/node@24.12.2': + resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} + + '@types/node@25.6.0': + resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} + + '@types/pg-pool@2.0.7': + resolution: {integrity: sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==} + + '@types/pg@8.15.6': + resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@types/sax@1.2.7': + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + + '@types/tedious@4.0.14': + resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@typescript-eslint/eslint-plugin@8.59.2': + resolution: {integrity: sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.59.2 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.59.2': + resolution: {integrity: sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.59.2': + resolution: {integrity: sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.59.2': + resolution: {integrity: sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.59.2': + resolution: {integrity: sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.59.2': + resolution: {integrity: sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.59.2': + resolution: {integrity: sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.59.2': + resolution: {integrity: sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.59.2': + resolution: {integrity: sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.59.2': + resolution: {integrity: sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@ungap/structured-clone@1.3.1': + resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} + + '@vitejs/plugin-react@6.0.1': + resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true + + '@whatwg-node/disposablestack@0.0.6': + resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/events@0.1.2': + resolution: {integrity: sha512-ApcWxkrs1WmEMS2CaLLFUEem/49erT3sxIVjpzU5f6zmVcnijtDSrhoK2zVobOIikZJdH63jdAXOrvjf6eOUNQ==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/fetch@0.10.13': + resolution: {integrity: sha512-b4PhJ+zYj4357zwk4TTuF2nEe0vVtOrwdsrNo5hL+u1ojXNhh1FgJ6pg1jzDlwlT4oBdzfSwaBwMCtFCsIWg8Q==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/node-fetch@0.8.5': + resolution: {integrity: sha512-4xzCl/zphPqlp9tASLVeUhB5+WJHbuWGYpfoC2q1qh5dw0AqZBW7L27V5roxYWijPxj4sspRAAoOH3d2ztaHUQ==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/promise-helpers@1.3.2': + resolution: {integrity: sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==} + engines: {node: '>=16.0.0'} + + '@whatwg-node/server@0.10.18': + resolution: {integrity: sha512-kMwLlxUbduttIgaPdSkmEarFpP+mSY8FEm+QWMBRJwxOHWkri+cxd8KZHO9EMrB9vgUuz+5WEaCawaL5wGVoXg==} + engines: {node: '>=18.0.0'} + + '@x0k/json-schema-merge@1.0.2': + resolution: {integrity: sha512-1734qiJHNX3+cJGDMMw2yz7R+7kpbAtl5NdPs1c/0gO5kYT6s4dMbLXiIfpZNsOYhGZI3aH7FWrj4Zxz7epXNg==} + + '@zudoku/httpsnippet@10.0.9': + resolution: {integrity: sha512-qmxuSxmTEEt6bc5j1cChljbztIphkuYMj3bbmT2W54ePGwCk6Iea7vPutHVw7NnCIW6cRI//w+u7xGOfOhwPCw==} + engines: {node: '>=18'} + + '@zudoku/react-helmet-async@2.0.5': + resolution: {integrity: sha512-wDakXPJEiQb4JmacSqPyAiJPdOBFqp6e3VUbm1BtTEkXo6FrC2nN+GmIniQ2OimBEC042rSZ9JdQBX+wou/MKw==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + + '@zuplo/mcp@0.0.32': + resolution: {integrity: sha512-rpLTpwL+g1sXtylu2gZwCTXdNIV2L0LPOcCdwogpP5hdyp/JMLSAVtd7H5fs5Wt2cq3jTm6nn7ZZvsBAECdl3A==} + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv-draft-04@1.0.0: + resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + base-x@5.0.1: + resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} + + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + cjs-module-lexer@2.2.0: + resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} + + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + cmdk@1.1.1: + resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + react-dom: ^18 || ^19 || ^19.0.0-rc + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + cross-inspect@1.0.1: + resolution: {integrity: sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==} + engines: {node: '>=16.0.0'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + dotenv@17.3.1: + resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + embla-carousel-react@8.6.0: + resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==} + peerDependencies: + react: ^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + + embla-carousel-reactive-utils@8.6.0: + resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel@8.6.0: + resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + enhanced-resolve@5.21.0: + resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==} + engines: {node: '>=10.13.0'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + esbuild@0.28.0: + resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-value-to-estree@3.5.0: + resolution: {integrity: sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eventsource-parser@3.0.8: + resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==} + engines: {node: '>=18.0.0'} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-equals@6.0.0: + resolution: {integrity: sha512-PFhhIGgdM79r5Uztdj9Zb6Tt1zKafqVfdMGwVca1z5z6fbX7DmsySSuJd8HiP6I1j505DCS83cLxo5rmSNeVEA==} + engines: {node: '>=6.0.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-printf@1.6.10: + resolution: {integrity: sha512-GwTgG9O4FVIdShhbVF3JxOgSBY2+ePGsu2V/UONgoCPzF9VY6ZdBMKsHKCYQHZwNk3qNouUolRDsgVxcVA5G1w==} + engines: {node: '>=10.0'} + + fast-uri@3.1.2: + resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} + + fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + + forwarded-parse@2.1.2: + resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==} + + framer-motion@12.38.0: + resolution: {integrity: sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + get-own-enumerable-property-symbols@3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphql-type-json@0.3.2: + resolution: {integrity: sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==} + peerDependencies: + graphql: '>=0.8.0' + + graphql-yoga@5.18.0: + resolution: {integrity: sha512-xFt1DVXS1BZ3AvjnawAGc5OYieSe56WuQuyk3iEpBwJ3QDZJWQGLmU9z/L5NUZ+pUcyprsz/bOwkYIV96fXt/g==} + engines: {node: '>=18.0.0'} + peerDependencies: + graphql: ^15.2.0 || ^16.0.0 + + graphql@16.13.2: + resolution: {integrity: sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + engines: {node: '>= 0.4'} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-heading-rank@3.0.0: + resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-properties-to-mdx-jsx-attributes@1.1.1: + resolution: {integrity: sha512-MMrAoGgvhYULEqMB/r6AlcVz1D3Cyml/9cMB2NIqZsIsEJ+XEXPMqH0gjba8dVs9AnQUYvPReAS+OIYx4ip+Ug==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + hono@4.12.14: + resolution: {integrity: sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==} + engines: {node: '>=16.9.0'} + + html-url-attributes@3.0.1: + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + http-terminator@3.2.0: + resolution: {integrity: sha512-JLjck1EzPaWjsmIf8bziM3p9fgR1Y3JoUKAkyYEbZmFrIvJM6I8vVJfBGWlEtV9IWOvzNnaTtjuwZeBY2kwB4g==} + engines: {node: '>=14'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-in-the-middle@2.0.6: + resolution: {integrity: sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==} + + import-in-the-middle@3.0.1: + resolution: {integrity: sha512-pYkiyXVL2Mf3pozdlDGV6NAObxQx13Ae8knZk1UJRJ6uRW/ZRmTGHlQYtrsSl7ubuE5F8CD1z+s1n4RHNuTtuA==} + engines: {node: '>=18'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-regexp@1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + javascript-stringify@2.1.0: + resolution: {integrity: sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==} + + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-to-typescript-lite@15.0.0: + resolution: {integrity: sha512-5mMORSQm9oTLyjM4mWnyNBi2T042Fhg1/0gCIB6X8U/LVpM2A+Nmj2yEyArqVouDmFThDxpEXcnTgSrjkGJRFA==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + leven@4.1.0: + resolution: {integrity: sha512-KZ9W9nWDT7rF7Dazg8xyLHGLrmpgq2nVNFUckhqdW3szVP6YhCpp/RAnpmVExA9JvrMynjwSLVrEj3AepHR6ew==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + loglevel@1.9.2: + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} + engines: {node: '>= 0.6.0'} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@11.3.6: + resolution: {integrity: sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==} + engines: {node: 20 || >=22} + + lucide-react@1.8.0: + resolution: {integrity: sha512-WuvlsjngSk7TnTBJ1hsCy3ql9V9VOdcPkd3PKcSmM34vJD8KG6molxz7m7zbYFgICwsanQWmJ13JlYs4Zp7Arw==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + + micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@1.1.0: + resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@1.2.0: + resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@1.1.0: + resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@1.1.0: + resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + module-details-from-path@1.0.4: + resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} + + motion-dom@12.38.0: + resolution: {integrity: sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==} + + motion-utils@12.36.0: + resolution: {integrity: sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==} + + motion@12.35.1: + resolution: {integrity: sha512-yEt/49kWC0VU/IEduDfeZw82eDemlPwa1cyo/gcEEUCN4WgpSJpUcxz6BUwakGabvJiTzLQ58J73515I5tfykQ==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoevents@9.1.0: + resolution: {integrity: sha512-Jd0fILWG44a9luj8v5kED4WI+zfkkgwKyRQKItTtlPfEsh7Lznfi1kr8/iZ+XAIss4Qq5GqRB0qtWbaz9ceO/A==} + engines: {node: ^18.0.0 || >=20.0.0} + + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + + oauth4webapi@3.8.5: + resolution: {integrity: sha512-A8jmyUckVhRJj5lspguklcl90Ydqk61H3dcU0oLhH3Yv13KpAliKTt5hknpGGPZSSfOwGyraNEFmofDYH+1kSg==} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + oniguruma-parser@0.12.2: + resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} + + oniguruma-to-es@4.3.6: + resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} + + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-timeout@3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + + p-wait-for@3.2.0: + resolution: {integrity: sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA==} + engines: {node: '>=8'} + + pagefind@1.5.2: + resolution: {integrity: sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==} + hasBin: true + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-srcset@1.0.2: + resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-protocol@1.13.0: + resolution: {integrity: sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + piscina@5.1.4: + resolution: {integrity: sha512-7uU4ZnKeQq22t9AsmHGD2w4OYQGonwFnTypDypaWi7Qr2EvQIFVtG8J5D/3bE7W123Wdc9+v4CZDu5hJXVCtBg==} + engines: {node: '>=20.x'} + + postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + + postcss@8.5.14: + resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} + engines: {node: ^10 || ^12 || >=14} + + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-bytea@1.0.1: + resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + + posthog-node@5.26.0: + resolution: {integrity: sha512-DK1XF/RiunhvT57cFyPxW9OaliZzl5aREHFwY/AISL3MVOaDUb4wIccMn0G3ws3Ounen8iGH7xvzZQ0x2vEOEQ==} + engines: {node: ^20.20.0 || >=22.22.0} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} + engines: {node: '>=0.6'} + + react-dom@19.2.5: + resolution: {integrity: sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==} + peerDependencies: + react: ^19.2.5 + + react-error-boundary@6.1.1: + resolution: {integrity: sha512-BrYwPOdXi5mqkk5lw+Uvt0ThHx32rCt3BkukS4X23A2AIWDPSGX6iaWTc0y9TU/mHDA/6qOSGel+B2ERkOvD1w==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + + react-hook-form@7.71.2: + resolution: {integrity: sha512-1CHvcDYzuRUNOflt4MOq3ZM46AronNJtQ1S7tnX6YN4y72qhgiUItpacZUAQ0TyWYci3yz1X+rXaSxiuEm86PA==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@19.2.5: + resolution: {integrity: sha512-Dn0t8IQhCmeIT3wu+Apm1/YVsJXsGWi6k4sPdnBIdqMVtHtv0IGi6dcpNpNkNac0zB2uUAqNX3MHzN8c+z2rwQ==} + + react-markdown@10.1.0: + resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==} + peerDependencies: + '@types/react': '>=18' + react: '>=18' + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + 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 + + react-router@7.14.1: + resolution: {integrity: sha512-5BCvFskyAAVumqhEKh/iPhLOIkfxcEUz8WqFIARCkMg8hZZzDYX9CtwxXA0e+qT8zAxmMC0x3Ckb9iMONwc5jg==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + 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 + + react@19.2.5: + resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==} + engines: {node: '>=0.10.0'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + rehype-mdx-import-media@1.2.0: + resolution: {integrity: sha512-rf+2qnPv3LTqLtCr8GjhHUja2TEbmwWtD1o4jigrmGWbVDggOMxyNeqJhGpC4E3vtH+sY+a+u9WPSEaskEWPFA==} + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + rehype-slug@6.0.0: + resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==} + + remark-comment@1.0.0: + resolution: {integrity: sha512-k8YPo5MGvl8l4gGxOH6Zk4Fa2AhDACN5eqKnKZcHDORZQS15hlnezlBHj2lqyDiqzApNmYOMTibkEJbMSKU25w==} + + remark-directive-rehype@1.0.0: + resolution: {integrity: sha512-10XpgKG/v5pqSpp/lLXEqqJ+EeHY1mhmcgSgno1Zw+PygBvkMguY9X39dj5sMkaMt0GbUmlhWidbBqLzFLZmXg==} + engines: {node: '>=20.0.0'} + + remark-directive@3.0.1: + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} + + remark-frontmatter@5.0.0: + resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx-frontmatter@5.2.0: + resolution: {integrity: sha512-U/hjUYTkQqNjjMRYyilJgLXSPF65qbLPdoESOkXyrwz2tVyhAnm4GUKhfXqOOS9W34M3545xEMq+aMpHgVjEeQ==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-in-the-middle@8.0.1: + resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==} + engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'} + + reselect@5.1.1: + resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + roarr@7.21.4: + resolution: {integrity: sha512-qvfUKCrpPzhWmQ4NxRYnuwhkI5lwmObhBU06BCK/lpj6PID9nL4Hk6XDwek2foKI+TMaV+Yw//XZshGF2Lox/Q==} + engines: {node: '>=18.0'} + + rolldown@1.0.0-rc.16: + resolution: {integrity: sha512-rzi5WqKzEZw3SooTt7cgm4eqIoujPIyGcJNGFL7iPEuajQw7vxMHUkXylu4/vhCkJGXsgRmxqMKXUpT6FEgl0g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rollup@4.60.3: + resolution: {integrity: sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + semver-compare@1.0.0: + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + + shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shiki@4.0.2: + resolution: {integrity: sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ==} + engines: {node: '>=20'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + sitemap@9.0.1: + resolution: {integrity: sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==} + engines: {node: '>=20.19.5', npm: '>=10.8.2'} + hasBin: true + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + stringify-object@3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + tailwind-merge@3.5.0: + resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} + + tailwindcss@4.2.1: + resolution: {integrity: sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==} + + tailwindcss@4.2.2: + resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} + + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + + toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tw-animate-css@1.4.0: + resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + undici-types@7.19.2: + resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-map@4.0.0: + resolution: {integrity: sha512-HJs1tpkSmRJUzj6fskQrS5oYhBYlmtcvy4SepdDEEsL04FjBrgF0Mgggvxc1/qGBGgW7hRh9+UBK1aqTEnBpIA==} + + unist-util-mdx-define@1.1.2: + resolution: {integrity: sha512-9ncH7i7TN5Xn7/tzX5bE3rXgz1X/u877gYVAUB3mLeTKYJmQHmqKTDBi6BTGXV7AeolBCI9ErcVsOt2qryoD0g==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url@0.11.4: + resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} + engines: {node: '>= 0.4'} + + urlpattern-polyfill@10.1.0: + resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + 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 + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + 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 + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vaul@1.1.2: + resolution: {integrity: sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@8.0.9: + resolution: {integrity: sha512-t7g7GVRpMXjNpa67HaVWI/8BWtdVIQPCL2WoozXXA7LBGEFK4AkkKkHx2hAQf5x1GZSlcmEDPkVLSGahxnEEZw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.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 + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaml@2.8.3: + resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@18.0.0: + resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zudoku@0.77.0: + resolution: {integrity: sha512-3zFmWFCYejA8GND904r902zrU11f4A1xsYnKIXOLXnllHwGZCU8rYjyW5cViUFs6bMEN2aN2kOJ13HKNxwfo8Q==} + hasBin: true + peerDependencies: + '@azure/msal-browser': ^4.13.0 + '@sentry/react': ^10.0.0 + '@supabase/supabase-js': ^2.49.4 + firebase: ^12.6.0 + mermaid: ^11.0.0 + react: '>=19.2.0' + react-dom: '>=19.2.0' + peerDependenciesMeta: + '@azure/msal-browser': + optional: true + '@sentry/react': + optional: true + '@supabase/supabase-js': + optional: true + firebase: + optional: true + mermaid: + optional: true + + zustand@5.0.12: + resolution: {integrity: sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@apidevtools/json-schema-ref-parser@14.2.1(@types/json-schema@7.0.15)': + dependencies: + '@types/json-schema': 7.0.15 + js-yaml: 4.1.1 + + '@apidevtools/json-schema-ref-parser@15.3.5(@types/json-schema@7.0.15)': + dependencies: + '@types/json-schema': 7.0.15 + js-yaml: 4.1.1 + + '@babel/runtime@7.29.2': {} + + '@base-ui/react@1.4.1(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@babel/runtime': 7.29.2 + '@base-ui/utils': 0.2.8(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@floating-ui/utils': 0.2.11 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + use-sync-external-store: 1.6.0(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + + '@base-ui/utils@0.2.8(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@babel/runtime': 7.29.2 + '@floating-ui/utils': 0.2.11 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + reselect: 5.1.1 + use-sync-external-store: 1.6.0(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + + '@emnapi/core@1.9.2': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.9.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@envelop/core@5.5.1': + dependencies: + '@envelop/instrumentation': 1.0.0 + '@envelop/types': 5.2.1 + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@envelop/instrumentation@1.0.0': + dependencies: + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@envelop/types@5.2.1': + dependencies: + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@esbuild/aix-ppc64@0.28.0': + optional: true + + '@esbuild/android-arm64@0.28.0': + optional: true + + '@esbuild/android-arm@0.28.0': + optional: true + + '@esbuild/android-x64@0.28.0': + optional: true + + '@esbuild/darwin-arm64@0.28.0': + optional: true + + '@esbuild/darwin-x64@0.28.0': + optional: true + + '@esbuild/freebsd-arm64@0.28.0': + optional: true + + '@esbuild/freebsd-x64@0.28.0': + optional: true + + '@esbuild/linux-arm64@0.28.0': + optional: true + + '@esbuild/linux-arm@0.28.0': + optional: true + + '@esbuild/linux-ia32@0.28.0': + optional: true + + '@esbuild/linux-loong64@0.28.0': + optional: true + + '@esbuild/linux-mips64el@0.28.0': + optional: true + + '@esbuild/linux-ppc64@0.28.0': + optional: true + + '@esbuild/linux-riscv64@0.28.0': + optional: true + + '@esbuild/linux-s390x@0.28.0': + optional: true + + '@esbuild/linux-x64@0.28.0': + optional: true + + '@esbuild/netbsd-arm64@0.28.0': + optional: true + + '@esbuild/netbsd-x64@0.28.0': + optional: true + + '@esbuild/openbsd-arm64@0.28.0': + optional: true + + '@esbuild/openbsd-x64@0.28.0': + optional: true + + '@esbuild/openharmony-arm64@0.28.0': + optional: true + + '@esbuild/sunos-x64@0.28.0': + optional: true + + '@esbuild/win32-arm64@0.28.0': + optional: true + + '@esbuild/win32-ia32@0.28.0': + optional: true + + '@esbuild/win32-x64@0.28.0': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.7.0))': + dependencies: + eslint: 9.39.4(jiti@2.7.0) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.15.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@fastify/busboy@3.2.0': {} + + '@fastify/otel@0.18.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + minimatch: 10.2.5 + transitivePeerDependencies: + - supports-color + + '@floating-ui/core@1.7.5': + dependencies: + '@floating-ui/utils': 0.2.11 + + '@floating-ui/dom@1.7.6': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 + + '@floating-ui/react-dom@2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@floating-ui/dom': 1.7.6 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + + '@floating-ui/utils@0.2.11': {} + + '@graphql-tools/executor@1.5.3(graphql@16.13.2)': + dependencies: + '@graphql-tools/utils': 11.1.0(graphql@16.13.2) + '@graphql-typed-document-node/core': 3.2.0(graphql@16.13.2) + '@repeaterjs/repeater': 3.0.6 + '@whatwg-node/disposablestack': 0.0.6 + '@whatwg-node/promise-helpers': 1.3.2 + graphql: 16.13.2 + tslib: 2.8.1 + + '@graphql-tools/merge@9.1.9(graphql@16.13.2)': + dependencies: + '@graphql-tools/utils': 11.1.0(graphql@16.13.2) + graphql: 16.13.2 + tslib: 2.8.1 + + '@graphql-tools/schema@10.0.33(graphql@16.13.2)': + dependencies: + '@graphql-tools/merge': 9.1.9(graphql@16.13.2) + '@graphql-tools/utils': 11.1.0(graphql@16.13.2) + graphql: 16.13.2 + tslib: 2.8.1 + + '@graphql-tools/utils@10.11.0(graphql@16.13.2)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.13.2) + '@whatwg-node/promise-helpers': 1.3.2 + cross-inspect: 1.0.1 + graphql: 16.13.2 + tslib: 2.8.1 + + '@graphql-tools/utils@11.1.0(graphql@16.13.2)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.13.2) + '@whatwg-node/promise-helpers': 1.3.2 + cross-inspect: 1.0.1 + graphql: 16.13.2 + tslib: 2.8.1 + + '@graphql-typed-document-node/core@3.2.0(graphql@16.13.2)': + dependencies: + graphql: 16.13.2 + + '@graphql-yoga/logger@2.0.1': + dependencies: + tslib: 2.8.1 + + '@graphql-yoga/subscription@5.0.5': + dependencies: + '@graphql-yoga/typed-event-target': 3.0.2 + '@repeaterjs/repeater': 3.0.6 + '@whatwg-node/events': 0.1.2 + tslib: 2.8.1 + + '@graphql-yoga/typed-event-target@3.0.2': + dependencies: + '@repeaterjs/repeater': 3.0.6 + tslib: 2.8.1 + + '@hono/node-server@1.19.13(hono@4.12.14)': + dependencies: + hono: 4.12.14 + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@lekoarts/rehype-meta-as-attributes@3.0.3': + dependencies: + unist-util-visit: 5.1.0 + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.16.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.16.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 19.2.14 + react: 19.2.5 + + '@mdx-js/rollup@3.1.1(rollup@4.60.3)': + dependencies: + '@mdx-js/mdx': 3.1.1 + '@rollup/pluginutils': 5.3.0(rollup@4.60.3) + rollup: 4.60.3 + source-map: 0.7.6 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@napi-rs/nice-android-arm-eabi@1.1.1': + optional: true + + '@napi-rs/nice-android-arm64@1.1.1': + optional: true + + '@napi-rs/nice-darwin-arm64@1.1.1': + optional: true + + '@napi-rs/nice-darwin-x64@1.1.1': + optional: true + + '@napi-rs/nice-freebsd-x64@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm-gnueabihf@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-arm64-musl@1.1.1': + optional: true + + '@napi-rs/nice-linux-ppc64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-riscv64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-s390x-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-x64-gnu@1.1.1': + optional: true + + '@napi-rs/nice-linux-x64-musl@1.1.1': + optional: true + + '@napi-rs/nice-openharmony-arm64@1.1.1': + optional: true + + '@napi-rs/nice-win32-arm64-msvc@1.1.1': + optional: true + + '@napi-rs/nice-win32-ia32-msvc@1.1.1': + optional: true + + '@napi-rs/nice-win32-x64-msvc@1.1.1': + optional: true + + '@napi-rs/nice@1.1.1': + optionalDependencies: + '@napi-rs/nice-android-arm-eabi': 1.1.1 + '@napi-rs/nice-android-arm64': 1.1.1 + '@napi-rs/nice-darwin-arm64': 1.1.1 + '@napi-rs/nice-darwin-x64': 1.1.1 + '@napi-rs/nice-freebsd-x64': 1.1.1 + '@napi-rs/nice-linux-arm-gnueabihf': 1.1.1 + '@napi-rs/nice-linux-arm64-gnu': 1.1.1 + '@napi-rs/nice-linux-arm64-musl': 1.1.1 + '@napi-rs/nice-linux-ppc64-gnu': 1.1.1 + '@napi-rs/nice-linux-riscv64-gnu': 1.1.1 + '@napi-rs/nice-linux-s390x-gnu': 1.1.1 + '@napi-rs/nice-linux-x64-gnu': 1.1.1 + '@napi-rs/nice-linux-x64-musl': 1.1.1 + '@napi-rs/nice-openharmony-arm64': 1.1.1 + '@napi-rs/nice-win32-arm64-msvc': 1.1.1 + '@napi-rs/nice-win32-ia32-msvc': 1.1.1 + '@napi-rs/nice-win32-x64-msvc': 1.1.1 + optional: true + + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@tybys/wasm-util': 0.10.2 + optional: true + + '@opentelemetry/api-logs@0.207.0': + dependencies: + '@opentelemetry/api': 1.9.1 + + '@opentelemetry/api-logs@0.212.0': + dependencies: + '@opentelemetry/api': 1.9.1 + + '@opentelemetry/api-logs@0.214.0': + dependencies: + '@opentelemetry/api': 1.9.1 + + '@opentelemetry/api@1.9.1': {} + + '@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/instrumentation-amqplib@0.61.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-connect@0.57.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/connect': 3.4.38 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-dataloader@0.31.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-fs@0.33.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-generic-pool@0.57.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-graphql@0.62.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-hapi@0.60.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-http@0.214.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + forwarded-parse: 2.1.2 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-ioredis@0.62.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/redis-common': 0.38.3 + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-kafkajs@0.23.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-knex@0.58.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-koa@0.62.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-lru-memoizer@0.58.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mongodb@0.67.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mongoose@0.60.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mysql2@0.60.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mysql@0.60.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/mysql': 2.15.27 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-pg@0.66.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) + '@types/pg': 8.15.6 + '@types/pg-pool': 2.0.7 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-redis@0.62.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/redis-common': 0.38.3 + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-tedious@0.33.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/tedious': 4.0.14 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-undici@0.24.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation@0.207.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/api-logs': 0.207.0 + import-in-the-middle: 2.0.6 + require-in-the-middle: 8.0.1 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation@0.212.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/api-logs': 0.212.0 + import-in-the-middle: 2.0.6 + require-in-the-middle: 8.0.1 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/api-logs': 0.214.0 + import-in-the-middle: 3.0.1 + require-in-the-middle: 8.0.1 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/redis-common@0.38.3': {} + + '@opentelemetry/resources@2.7.1(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/semantic-conventions@1.40.0': {} + + '@opentelemetry/sql-common@0.41.2(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + + '@oxc-project/types@0.126.0': {} + + '@pagefind/darwin-arm64@1.5.2': + optional: true + + '@pagefind/darwin-x64@1.5.2': + optional: true + + '@pagefind/freebsd-x64@1.5.2': + optional: true + + '@pagefind/linux-arm64@1.5.2': + optional: true + + '@pagefind/linux-x64@1.5.2': + optional: true + + '@pagefind/windows-arm64@1.5.2': + optional: true + + '@pagefind/windows-x64@1.5.2': + optional: true + + '@posthog/core@1.23.1': + dependencies: + cross-spawn: 7.0.6 + + '@pothos/core@4.12.0(graphql@16.13.2)': + dependencies: + graphql: 16.13.2 + + '@prisma/instrumentation@7.6.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.207.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + + '@radix-ui/number@1.1.1': {} + + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-aspect-ratio@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-context@1.1.2(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-context@1.1.3(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + aria-hidden: 1.2.6 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-direction@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + aria-hidden: 1.2.6 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + aria-hidden: 1.2.6 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/rect': 1.1.1 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-slot': 1.2.4(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-progress@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-context': 1.1.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-select@2.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + aria-hidden: 1.2.6 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-separator@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-slider@1.3.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-slot@1.2.4(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-switch@1.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/rect': 1.1.1 + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-size@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-visually-hidden@1.2.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/rect@1.1.1': {} + + '@repeaterjs/repeater@3.0.6': {} + + '@rolldown/binding-android-arm64@1.0.0-rc.16': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.16': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.16': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.16': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.16': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.16': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.16': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.16': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.16': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.16': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.16': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.16': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.16': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.16': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.16': + optional: true + + '@rolldown/pluginutils@1.0.0-rc.16': {} + + '@rolldown/pluginutils@1.0.0-rc.7': {} + + '@rollup/pluginutils@5.3.0(rollup@4.60.3)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.4 + optionalDependencies: + rollup: 4.60.3 + + '@rollup/rollup-android-arm-eabi@4.60.3': + optional: true + + '@rollup/rollup-android-arm64@4.60.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.3': + optional: true + + '@rollup/rollup-darwin-x64@4.60.3': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.3': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.3': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.3': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.3': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.3': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.3': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.3': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.3': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.3': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.3': + optional: true + + '@scalar/helpers@0.2.7': {} + + '@scalar/json-magic@0.9.0': + dependencies: + '@scalar/helpers': 0.2.7 + yaml: 2.8.3 + + '@scalar/openapi-parser@0.23.13': + dependencies: + '@scalar/json-magic': 0.9.0 + '@scalar/openapi-types': 0.5.3 + '@scalar/openapi-upgrader': 0.1.7 + ajv: 8.20.0 + ajv-draft-04: 1.0.0(ajv@8.20.0) + ajv-formats: 3.0.1(ajv@8.20.0) + jsonpointer: 5.0.1 + leven: 4.1.0 + yaml: 2.8.3 + + '@scalar/openapi-types@0.5.3': + dependencies: + zod: 4.3.6 + + '@scalar/openapi-upgrader@0.1.7': + dependencies: + '@scalar/openapi-types': 0.5.3 + + '@sentry/core@10.49.0': {} + + '@sentry/node-core@10.49.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.40.0)': + dependencies: + '@sentry/core': 10.49.0 + '@sentry/opentelemetry': 10.49.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.40.0) + import-in-the-middle: 3.0.1 + optionalDependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@sentry/node@10.49.0': + dependencies: + '@fastify/otel': 0.18.0(@opentelemetry/api@1.9.1) + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-amqplib': 0.61.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-connect': 0.57.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-dataloader': 0.31.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-fs': 0.33.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-generic-pool': 0.57.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-graphql': 0.62.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-hapi': 0.60.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-http': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-ioredis': 0.62.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-kafkajs': 0.23.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-knex': 0.58.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-koa': 0.62.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-lru-memoizer': 0.58.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-mongodb': 0.67.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-mongoose': 0.60.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-mysql': 0.60.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-mysql2': 0.60.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-pg': 0.66.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-redis': 0.62.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-tedious': 0.33.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-undici': 0.24.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@prisma/instrumentation': 7.6.0(@opentelemetry/api@1.9.1) + '@sentry/core': 10.49.0 + '@sentry/node-core': 10.49.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.40.0) + '@sentry/opentelemetry': 10.49.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.40.0) + import-in-the-middle: 3.0.1 + transitivePeerDependencies: + - '@opentelemetry/exporter-trace-otlp-http' + - supports-color + + '@sentry/opentelemetry@10.49.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.40.0)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@sentry/core': 10.49.0 + + '@shikijs/core@4.0.2': + dependencies: + '@shikijs/primitive': 4.0.2 + '@shikijs/types': 4.0.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.6 + + '@shikijs/engine-oniguruma@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + + '@shikijs/primitive@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/rehype@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + '@types/hast': 3.0.4 + hast-util-to-string: 3.0.1 + shiki: 4.0.2 + unified: 11.0.5 + unist-util-visit: 5.1.0 + + '@shikijs/themes@4.0.2': + dependencies: + '@shikijs/types': 4.0.2 + + '@shikijs/transformers@4.0.2': + dependencies: + '@shikijs/core': 4.0.2 + '@shikijs/types': 4.0.2 + + '@shikijs/types@4.0.2': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@tailwindcss/node@4.2.2': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.21.0 + jiti: 2.7.0 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.2.2 + + '@tailwindcss/oxide-android-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + optional: true + + '@tailwindcss/oxide@4.2.2': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-x64': 4.2.2 + '@tailwindcss/oxide-freebsd-x64': 4.2.2 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.2 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-x64-musl': 4.2.2 + '@tailwindcss/oxide-wasm32-wasi': 4.2.2 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 + + '@tailwindcss/typography@0.5.19(tailwindcss@4.2.1)': + dependencies: + postcss-selector-parser: 6.0.10 + tailwindcss: 4.2.1 + + '@tailwindcss/vite@4.2.2(vite@8.0.9(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.8.3))': + dependencies: + '@tailwindcss/node': 4.2.2 + '@tailwindcss/oxide': 4.2.2 + tailwindcss: 4.2.2 + vite: 8.0.9(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.8.3) + + '@tanem/react-nprogress@6.0.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@babel/runtime': 7.29.2 + hoist-non-react-statics: 3.3.2 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + + '@tanstack/query-core@5.97.0': {} + + '@tanstack/react-query@5.97.0(react@19.2.5)': + dependencies: + '@tanstack/query-core': 5.97.0 + react: 19.2.5 + + '@tybys/wasm-util@0.10.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/connect@3.4.38': + dependencies: + '@types/node': 25.6.0 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/ms@2.1.0': {} + + '@types/mysql@2.15.27': + dependencies: + '@types/node': 25.6.0 + + '@types/node@24.12.2': + dependencies: + undici-types: 7.16.0 + + '@types/node@25.6.0': + dependencies: + undici-types: 7.19.2 + + '@types/pg-pool@2.0.7': + dependencies: + '@types/pg': 8.15.6 + + '@types/pg@8.15.6': + dependencies: + '@types/node': 25.6.0 + pg-protocol: 1.13.0 + pg-types: 2.2.0 + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + '@types/sax@1.2.7': + dependencies: + '@types/node': 24.12.2 + + '@types/tedious@4.0.14': + dependencies: + '@types/node': 25.6.0 + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.59.2 + '@typescript-eslint/type-utils': 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.59.2 + eslint: 9.39.4(jiti@2.7.0) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.59.2 + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/typescript-estree': 8.59.2(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.59.2 + debug: 4.4.3 + eslint: 9.39.4(jiti@2.7.0) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.59.2(typescript@6.0.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@6.0.3) + '@typescript-eslint/types': 8.59.2 + debug: 4.4.3 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.59.2': + dependencies: + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/visitor-keys': 8.59.2 + + '@typescript-eslint/tsconfig-utils@8.59.2(typescript@6.0.3)': + dependencies: + typescript: 6.0.3 + + '@typescript-eslint/type-utils@8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': + dependencies: + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/typescript-estree': 8.59.2(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + debug: 4.4.3 + eslint: 9.39.4(jiti@2.7.0) + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.59.2': {} + + '@typescript-eslint/typescript-estree@8.59.2(typescript@6.0.3)': + dependencies: + '@typescript-eslint/project-service': 8.59.2(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@6.0.3) + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/visitor-keys': 8.59.2 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.7.4 + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.59.2(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.59.2 + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/typescript-estree': 8.59.2(typescript@6.0.3) + eslint: 9.39.4(jiti@2.7.0) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.59.2': + dependencies: + '@typescript-eslint/types': 8.59.2 + eslint-visitor-keys: 5.0.1 + + '@ungap/structured-clone@1.3.1': {} + + '@vitejs/plugin-react@6.0.1(vite@8.0.9(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.8.3))': + dependencies: + '@rolldown/pluginutils': 1.0.0-rc.7 + vite: 8.0.9(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.8.3) + + '@whatwg-node/disposablestack@0.0.6': + dependencies: + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@whatwg-node/events@0.1.2': + dependencies: + tslib: 2.8.1 + + '@whatwg-node/fetch@0.10.13': + dependencies: + '@whatwg-node/node-fetch': 0.8.5 + urlpattern-polyfill: 10.1.0 + + '@whatwg-node/node-fetch@0.8.5': + dependencies: + '@fastify/busboy': 3.2.0 + '@whatwg-node/disposablestack': 0.0.6 + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@whatwg-node/promise-helpers@1.3.2': + dependencies: + tslib: 2.8.1 + + '@whatwg-node/server@0.10.18': + dependencies: + '@envelop/instrumentation': 1.0.0 + '@whatwg-node/disposablestack': 0.0.6 + '@whatwg-node/fetch': 0.10.13 + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@x0k/json-schema-merge@1.0.2': + dependencies: + '@types/json-schema': 7.0.15 + + '@zudoku/httpsnippet@10.0.9': + dependencies: + qs: 6.15.1 + stringify-object: 3.3.0 + url: 0.11.4 + + '@zudoku/react-helmet-async@2.0.5(react@19.2.5)': + dependencies: + invariant: 2.2.4 + react: 19.2.5 + react-fast-compare: 3.2.2 + shallowequal: 1.1.0 + + '@zuplo/mcp@0.0.32': + dependencies: + eventsource-parser: 3.0.8 + zod: 3.25.76 + + acorn-import-attributes@1.9.5(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + ajv-draft-04@1.0.0(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv-formats@3.0.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.2 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + astring@1.9.0: {} + + bail@2.0.2: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + base-x@5.0.1: {} + + brace-expansion@1.1.14: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + + bs58@6.0.0: + dependencies: + base-x: 5.0.1 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + ccount@2.0.1: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + cjs-module-lexer@2.2.0: {} + + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + + clsx@2.1.1: {} + + cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + + collapse-white-space@2.1.0: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + comma-separated-tokens@2.0.3: {} + + concat-map@0.0.1: {} + + cookie@1.1.1: {} + + cross-inspect@1.0.1: + dependencies: + tslib: 2.8.1 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cssesc@3.0.0: {} + + csstype@3.2.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + deep-is@0.1.4: {} + + delay@5.0.0: {} + + dequal@2.0.3: {} + + detect-libc@2.1.2: {} + + detect-node-es@1.1.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dotenv@17.3.1: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + embla-carousel-react@8.6.0(react@19.2.5): + dependencies: + embla-carousel: 8.6.0 + embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) + react: 19.2.5 + + embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel@8.6.0: {} + + emoji-regex@10.6.0: {} + + enhanced-resolve@5.21.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + + entities@6.0.1: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.16.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + esbuild@0.28.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.0 + '@esbuild/android-arm': 0.28.0 + '@esbuild/android-arm64': 0.28.0 + '@esbuild/android-x64': 0.28.0 + '@esbuild/darwin-arm64': 0.28.0 + '@esbuild/darwin-x64': 0.28.0 + '@esbuild/freebsd-arm64': 0.28.0 + '@esbuild/freebsd-x64': 0.28.0 + '@esbuild/linux-arm': 0.28.0 + '@esbuild/linux-arm64': 0.28.0 + '@esbuild/linux-ia32': 0.28.0 + '@esbuild/linux-loong64': 0.28.0 + '@esbuild/linux-mips64el': 0.28.0 + '@esbuild/linux-ppc64': 0.28.0 + '@esbuild/linux-riscv64': 0.28.0 + '@esbuild/linux-s390x': 0.28.0 + '@esbuild/linux-x64': 0.28.0 + '@esbuild/netbsd-arm64': 0.28.0 + '@esbuild/netbsd-x64': 0.28.0 + '@esbuild/openbsd-arm64': 0.28.0 + '@esbuild/openbsd-x64': 0.28.0 + '@esbuild/openharmony-arm64': 0.28.0 + '@esbuild/sunos-x64': 0.28.0 + '@esbuild/win32-arm64': 0.28.0 + '@esbuild/win32-ia32': 0.28.0 + '@esbuild/win32-x64': 0.28.0 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4(jiti@2.7.0): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) + '@eslint-community/regexpp': 4.12.2 + '@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.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + 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.4 + optionalDependencies: + jiti: 2.7.0 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + + esprima@4.0.1: {} + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-value-to-estree@3.5.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + eventsource-parser@3.0.8: {} + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-equals@6.0.0: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-printf@1.6.10: {} + + fast-uri@3.1.2: {} + + fault@2.0.1: + dependencies: + format: 0.2.2 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + + format@0.2.2: {} + + forwarded-parse@2.1.2: {} + + framer-motion@12.38.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + dependencies: + motion-dom: 12.38.0 + motion-utils: 12.36.0 + tslib: 2.8.1 + optionalDependencies: + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.5.0: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + math-intrinsics: 1.1.0 + + get-nonce@1.0.1: {} + + get-own-enumerable-property-symbols@3.0.2: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + github-slugger@2.0.0: {} + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@13.0.6: + dependencies: + minimatch: 10.2.5 + minipass: 7.1.3 + path-scurry: 2.0.2 + + globals@14.0.0: {} + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphql-type-json@0.3.2(graphql@16.13.2): + dependencies: + graphql: 16.13.2 + + graphql-yoga@5.18.0(graphql@16.13.2): + dependencies: + '@envelop/core': 5.5.1 + '@envelop/instrumentation': 1.0.0 + '@graphql-tools/executor': 1.5.3(graphql@16.13.2) + '@graphql-tools/schema': 10.0.33(graphql@16.13.2) + '@graphql-tools/utils': 10.11.0(graphql@16.13.2) + '@graphql-yoga/logger': 2.0.1 + '@graphql-yoga/subscription': 5.0.5 + '@whatwg-node/fetch': 0.10.13 + '@whatwg-node/promise-helpers': 1.3.2 + '@whatwg-node/server': 0.10.18 + graphql: 16.13.2 + lru-cache: 10.4.3 + tslib: 2.8.1 + + graphql@16.13.2: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.2 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + hasown@2.0.3: + dependencies: + function-bind: 1.1.2 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.1.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-heading-rank@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-properties-to-mdx-jsx-attributes@1.1.1: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + estree-util-value-to-estree: 3.5.0 + mdast-util-mdx-jsx: 3.2.0 + property-information: 7.1.0 + style-to-js: 1.1.21 + transitivePeerDependencies: + - supports-color + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.1 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.1 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + hono@4.12.14: {} + + html-url-attributes@3.0.1: {} + + html-void-elements@3.0.0: {} + + http-terminator@3.2.0: + dependencies: + delay: 5.0.0 + p-wait-for: 3.2.0 + roarr: 7.21.4 + type-fest: 2.19.0 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-in-the-middle@2.0.6: + dependencies: + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) + cjs-module-lexer: 2.2.0 + module-details-from-path: 1.0.4 + + import-in-the-middle@3.0.1: + dependencies: + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) + cjs-module-lexer: 2.2.0 + module-details-from-path: 1.0.4 + + imurmurhash@0.1.4: {} + + inline-style-parser@0.2.7: {} + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-decimal@2.0.1: {} + + is-extendable@0.1.1: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-obj@1.0.1: {} + + is-plain-obj@4.1.0: {} + + is-regexp@1.0.0: {} + + isexe@2.0.0: {} + + javascript-stringify@2.1.0: {} + + jiti@2.7.0: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-to-typescript-lite@15.0.0: + dependencies: + '@apidevtools/json-schema-ref-parser': 14.2.1(@types/json-schema@7.0.15) + '@types/json-schema': 7.0.15 + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + jsonpointer@5.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kind-of@6.0.3: {} + + leven@4.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + 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 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + loglevel@1.9.2: {} + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@10.4.3: {} + + lru-cache@11.3.6: {} + + lucide-react@1.8.0(react@19.2.5): + dependencies: + react: 19.2.5 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + markdown-extensions@2.0.0: {} + + markdown-table@3.0.4: {} + + math-intrinsics@1.1.0: {} + + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.2 + transitivePeerDependencies: + - supports-color + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-frontmatter@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + escape-string-regexp: 5.0.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-extension-frontmatter: 2.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.1 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-frontmatter@2.0.0: + dependencies: + fault: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-factory-space@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-types: 1.1.0 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@1.2.0: + dependencies: + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@1.1.0: {} + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@1.1.0: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.5 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.14 + + minipass@7.1.3: {} + + module-details-from-path@1.0.4: {} + + motion-dom@12.38.0: + dependencies: + motion-utils: 12.36.0 + + motion-utils@12.36.0: {} + + motion@12.35.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + dependencies: + framer-motion: 12.38.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + tslib: 2.8.1 + optionalDependencies: + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + + ms@2.1.3: {} + + nanoevents@9.1.0: {} + + nanoid@3.3.12: {} + + natural-compare@1.4.0: {} + + next-themes@0.4.6(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + dependencies: + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + + oauth4webapi@3.8.5: {} + + object-inspect@1.13.4: {} + + oniguruma-parser@0.12.2: {} + + oniguruma-to-es@4.3.6: + dependencies: + oniguruma-parser: 0.12.2 + regex: 6.1.0 + regex-recursion: 6.0.2 + + openapi-types@12.1.3: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-finally@1.0.0: {} + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-timeout@3.2.0: + dependencies: + p-finally: 1.0.0 + + p-wait-for@3.2.0: + dependencies: + p-timeout: 3.2.0 + + pagefind@1.5.2: + optionalDependencies: + '@pagefind/darwin-arm64': 1.5.2 + '@pagefind/darwin-x64': 1.5.2 + '@pagefind/freebsd-x64': 1.5.2 + '@pagefind/linux-arm64': 1.5.2 + '@pagefind/linux-x64': 1.5.2 + '@pagefind/windows-arm64': 1.5.2 + '@pagefind/windows-x64': 1.5.2 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-srcset@1.0.2: {} + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-scurry@2.0.2: + dependencies: + lru-cache: 11.3.6 + minipass: 7.1.3 + + pg-int8@1.0.1: {} + + pg-protocol@1.13.0: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.1 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + picocolors@1.1.1: {} + + picomatch@4.0.4: {} + + piscina@5.1.4: + optionalDependencies: + '@napi-rs/nice': 1.1.1 + + postcss-selector-parser@6.0.10: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.14: + dependencies: + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postgres-array@2.0.0: {} + + postgres-bytea@1.0.1: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + + posthog-node@5.26.0: + dependencies: + '@posthog/core': 1.23.1 + + prelude-ls@1.2.1: {} + + property-information@7.1.0: {} + + punycode@1.4.1: {} + + punycode@2.3.1: {} + + qs@6.15.1: + dependencies: + side-channel: 1.1.0 + + react-dom@19.2.5(react@19.2.5): + dependencies: + react: 19.2.5 + scheduler: 0.27.0 + + react-error-boundary@6.1.1(react@19.2.5): + dependencies: + react: 19.2.5 + + react-fast-compare@3.2.2: {} + + react-hook-form@7.71.2(react@19.2.5): + dependencies: + react: 19.2.5 + + react-is@16.13.1: {} + + react-is@19.2.5: {} + + react-markdown@10.1.0(@types/react@19.2.14)(react@19.2.5): + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/react': 19.2.14 + devlop: 1.1.0 + hast-util-to-jsx-runtime: 2.3.6 + html-url-attributes: 3.0.1 + mdast-util-to-hast: 13.2.1 + react: 19.2.5 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + unified: 11.0.5 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + react-remove-scroll-bar@2.3.8(@types/react@19.2.14)(react@19.2.5): + dependencies: + react: 19.2.5 + react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.5) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + react-remove-scroll@2.7.2(@types/react@19.2.14)(react@19.2.5): + dependencies: + react: 19.2.5 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.14)(react@19.2.5) + react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.5) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.2.14)(react@19.2.5) + use-sidecar: 1.1.3(@types/react@19.2.14)(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + + react-router@7.14.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + dependencies: + cookie: 1.1.1 + react: 19.2.5 + set-cookie-parser: 2.7.2 + optionalDependencies: + react-dom: 19.2.5(react@19.2.5) + + react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.5): + dependencies: + get-nonce: 1.0.1 + react: 19.2.5 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + react@19.2.5: {} + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + + rehype-mdx-import-media@1.2.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-properties-to-mdx-jsx-attributes: 1.1.1 + parse-srcset: 1.0.2 + unified: 11.0.5 + unist-util-visit: 5.1.0 + transitivePeerDependencies: + - supports-color + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + rehype-slug@6.0.0: + dependencies: + '@types/hast': 3.0.4 + github-slugger: 2.0.0 + hast-util-heading-rank: 3.0.0 + hast-util-to-string: 3.0.1 + unist-util-visit: 5.1.0 + + remark-comment@1.0.0: + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + + remark-directive-rehype@1.0.0: + dependencies: + hastscript: 9.0.1 + unist-util-map: 4.0.0 + + remark-directive@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-frontmatter@5.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-frontmatter: 2.0.1 + micromark-extension-frontmatter: 2.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx-frontmatter@5.2.0: + dependencies: + '@types/mdast': 4.0.4 + estree-util-value-to-estree: 3.5.0 + toml: 3.0.0 + unified: 11.0.5 + unist-util-mdx-define: 1.1.2 + yaml: 2.8.3 + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + require-from-string@2.0.2: {} + + require-in-the-middle@8.0.1: + dependencies: + debug: 4.4.3 + module-details-from-path: 1.0.4 + transitivePeerDependencies: + - supports-color + + reselect@5.1.1: {} + + resolve-from@4.0.0: {} + + roarr@7.21.4: + dependencies: + fast-printf: 1.6.10 + safe-stable-stringify: 2.5.0 + semver-compare: 1.0.0 + + rolldown@1.0.0-rc.16: + dependencies: + '@oxc-project/types': 0.126.0 + '@rolldown/pluginutils': 1.0.0-rc.16 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.16 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.16 + '@rolldown/binding-darwin-x64': 1.0.0-rc.16 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.16 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.16 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.16 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.16 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.16 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.16 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.16 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.16 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.16 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.16 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.16 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.16 + + rollup@4.60.3: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.60.3 + '@rollup/rollup-android-arm64': 4.60.3 + '@rollup/rollup-darwin-arm64': 4.60.3 + '@rollup/rollup-darwin-x64': 4.60.3 + '@rollup/rollup-freebsd-arm64': 4.60.3 + '@rollup/rollup-freebsd-x64': 4.60.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.3 + '@rollup/rollup-linux-arm-musleabihf': 4.60.3 + '@rollup/rollup-linux-arm64-gnu': 4.60.3 + '@rollup/rollup-linux-arm64-musl': 4.60.3 + '@rollup/rollup-linux-loong64-gnu': 4.60.3 + '@rollup/rollup-linux-loong64-musl': 4.60.3 + '@rollup/rollup-linux-ppc64-gnu': 4.60.3 + '@rollup/rollup-linux-ppc64-musl': 4.60.3 + '@rollup/rollup-linux-riscv64-gnu': 4.60.3 + '@rollup/rollup-linux-riscv64-musl': 4.60.3 + '@rollup/rollup-linux-s390x-gnu': 4.60.3 + '@rollup/rollup-linux-x64-gnu': 4.60.3 + '@rollup/rollup-linux-x64-musl': 4.60.3 + '@rollup/rollup-openbsd-x64': 4.60.3 + '@rollup/rollup-openharmony-arm64': 4.60.3 + '@rollup/rollup-win32-arm64-msvc': 4.60.3 + '@rollup/rollup-win32-ia32-msvc': 4.60.3 + '@rollup/rollup-win32-x64-gnu': 4.60.3 + '@rollup/rollup-win32-x64-msvc': 4.60.3 + fsevents: 2.3.3 + + safe-stable-stringify@2.5.0: {} + + sax@1.6.0: {} + + scheduler@0.27.0: {} + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + semver-compare@1.0.0: {} + + semver@7.7.4: {} + + set-cookie-parser@2.7.2: {} + + shallowequal@1.1.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shiki@4.0.2: + dependencies: + '@shikijs/core': 4.0.2 + '@shikijs/engine-javascript': 4.0.2 + '@shikijs/engine-oniguruma': 4.0.2 + '@shikijs/langs': 4.0.2 + '@shikijs/themes': 4.0.2 + '@shikijs/types': 4.0.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + sitemap@9.0.1: + dependencies: + '@types/node': 24.12.2 + '@types/sax': 1.2.7 + arg: 5.0.2 + sax: 1.6.0 + + source-map-js@1.2.1: {} + + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + + sprintf-js@1.0.3: {} + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + stringify-object@3.3.0: + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-bom-string@1.0.0: {} + + strip-json-comments@3.1.1: {} + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + tailwind-merge@3.5.0: {} + + tailwindcss@4.2.1: {} + + tailwindcss@4.2.2: {} + + tapable@2.3.3: {} + + tinyglobby@0.2.16: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + toml@3.0.0: {} + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-api-utils@2.5.0(typescript@6.0.3): + dependencies: + typescript: 6.0.3 + + tslib@2.8.1: {} + + tw-animate-css@1.4.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@2.19.0: {} + + typescript@6.0.3: {} + + undici-types@7.16.0: {} + + undici-types@7.19.2: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-map@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-mdx-define@1.1.2: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + vfile: 6.0.3 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + url@0.11.4: + dependencies: + punycode: 1.4.1 + qs: 6.15.1 + + urlpattern-polyfill@10.1.0: {} + + use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.5): + dependencies: + react: 19.2.5 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.5): + dependencies: + detect-node-es: 1.1.0 + react: 19.2.5 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + use-sync-external-store@1.6.0(react@19.2.5): + dependencies: + react: 19.2.5 + + util-deprecate@1.0.2: {} + + vaul@1.1.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + dependencies: + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite@8.0.9(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.8.3): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.14 + rolldown: 1.0.0-rc.16 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 25.6.0 + esbuild: 0.28.0 + fsevents: 2.3.3 + jiti: 2.7.0 + yaml: 2.8.3 + + web-namespaces@2.0.1: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + + xtend@4.0.2: {} + + y18n@5.0.8: {} + + yaml@2.8.3: {} + + yargs-parser@22.0.0: {} + + yargs@18.0.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 7.2.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + + yocto-queue@0.1.0: {} + + zod@3.25.76: {} + + zod@4.3.6: {} + + zudoku@0.77.0(@types/json-schema@7.0.15)(@types/node@25.6.0)(jiti@2.7.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(rollup@4.60.3)(use-sync-external-store@1.6.0(react@19.2.5)): + dependencies: + '@apidevtools/json-schema-ref-parser': 15.3.5(@types/json-schema@7.0.15) + '@base-ui/react': 1.4.1(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@envelop/core': 5.5.1 + '@graphql-typed-document-node/core': 3.2.0(graphql@16.13.2) + '@hono/node-server': 1.19.13(hono@4.12.14) + '@lekoarts/rehype-meta-as-attributes': 3.0.3 + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.5) + '@mdx-js/rollup': 3.1.1(rollup@4.60.3) + '@pothos/core': 4.12.0(graphql@16.13.2) + '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-alert-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-aspect-ratio': 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-label': 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-progress': 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-radio-group': 1.3.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-select': 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-separator': 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slider': 1.3.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.4(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-switch': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-tooltip': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-visually-hidden': 1.2.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@scalar/openapi-parser': 0.23.13 + '@sentry/node': 10.49.0 + '@shikijs/langs': 4.0.2 + '@shikijs/rehype': 4.0.2 + '@shikijs/themes': 4.0.2 + '@shikijs/transformers': 4.0.2 + '@tailwindcss/typography': 0.5.19(tailwindcss@4.2.1) + '@tailwindcss/vite': 4.2.2(vite@8.0.9(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.8.3)) + '@tanem/react-nprogress': 6.0.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@tanstack/react-query': 5.97.0(react@19.2.5) + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': 6.0.1(vite@8.0.9(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.8.3)) + '@x0k/json-schema-merge': 1.0.2 + '@zudoku/httpsnippet': 10.0.9 + '@zudoku/react-helmet-async': 2.0.5(react@19.2.5) + '@zuplo/mcp': 0.0.32 + bs58: 6.0.0 + class-variance-authority: 0.7.1 + clsx: 2.1.1 + cmdk: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + dotenv: 17.3.1 + embla-carousel-react: 8.6.0(react@19.2.5) + esbuild: 0.28.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-value-to-estree: 3.5.0 + fast-equals: 6.0.0 + glob: 13.0.6 + glob-parent: 6.0.2 + graphql: 16.13.2 + graphql-type-json: 0.3.2(graphql@16.13.2) + graphql-yoga: 5.18.0(graphql@16.13.2) + gray-matter: 4.0.3 + hast-util-heading-rank: 3.0.0 + hast-util-to-jsx-runtime: 2.3.6 + hast-util-to-string: 3.0.1 + hono: 4.12.14 + http-terminator: 3.2.0 + javascript-stringify: 2.1.0 + json-schema-to-typescript-lite: 15.0.0 + loglevel: 1.9.2 + lucide-react: 1.8.0(react@19.2.5) + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx: 3.0.0 + mdast-util-mdx-jsx: 3.2.0 + micromark-extension-mdxjs: 3.0.0 + motion: 12.35.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + nanoevents: 9.1.0 + next-themes: 0.4.6(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + oauth4webapi: 3.8.5 + openapi-types: 12.1.3 + pagefind: 1.5.2 + picocolors: 1.1.1 + piscina: 5.1.4 + posthog-node: 5.26.0 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-error-boundary: 6.1.1(react@19.2.5) + react-hook-form: 7.71.2(react@19.2.5) + react-is: 19.2.5 + react-markdown: 10.1.0(@types/react@19.2.14)(react@19.2.5) + react-router: 7.14.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + rehype-mdx-import-media: 1.2.0 + rehype-raw: 7.0.0 + rehype-slug: 6.0.0 + remark-comment: 1.0.0 + remark-directive: 3.0.1 + remark-directive-rehype: 1.0.0 + remark-frontmatter: 5.0.0 + remark-gfm: 4.0.1 + remark-mdx-frontmatter: 5.2.0 + semver: 7.7.4 + shiki: 4.0.2 + sitemap: 9.0.1 + strip-ansi: 7.2.0 + tailwind-merge: 3.5.0 + tailwindcss: 4.2.1 + tw-animate-css: 1.4.0 + unified: 11.0.5 + unist-util-visit: 5.1.0 + vaul: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + vfile: 6.0.3 + vite: 8.0.9(@types/node@25.6.0)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.8.3) + yaml: 2.8.3 + yargs: 18.0.0 + zod: 4.3.6 + zustand: 5.0.12(@types/react@19.2.14)(react@19.2.5)(use-sync-external-store@1.6.0(react@19.2.5)) + transitivePeerDependencies: + - '@date-fns/tz' + - '@emotion/is-prop-valid' + - '@opentelemetry/exporter-trace-otlp-http' + - '@rolldown/plugin-babel' + - '@types/json-schema' + - '@types/node' + - '@vitejs/devtools' + - babel-plugin-react-compiler + - date-fns + - immer + - jiti + - less + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - use-sync-external-store + + zustand@5.0.12(@types/react@19.2.14)(react@19.2.5)(use-sync-external-store@1.6.0(react@19.2.5)): + optionalDependencies: + '@types/react': 19.2.14 + react: 19.2.5 + use-sync-external-store: 1.6.0(react@19.2.5) + + zwitch@2.0.4: {} From 1af606bc53d8b70a3db112c2d50ad75beae0356d Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 21 Apr 2026 14:15:45 +0300 Subject: [PATCH 108/131] chore(guides): Manual update to guides Signed-off-by: Alex-Andrei Cioc --- .github/workflows/sync.yaml | 2 + .gitignore | 1 + .../config/vocabularies/Unikraft/accept.txt | 1 + Makefile | 10 + pages/guides/caddy2.7-go1.21.mdx | 74 ++++-- pages/guides/debian-ssh.mdx | 75 ++++-- pages/guides/dragonflydb.mdx | 78 ++++-- pages/guides/duckdb-go1.21.mdx | 86 +++++-- pages/guides/github-webhook-node.mdx | 78 ++++-- pages/guides/grafana.mdx | 74 ++++-- pages/guides/haproxy.mdx | 74 ++++-- pages/guides/httpserver-boost1.74-g++13.2.mdx | 164 ------------- pages/guides/httpserver-boost1.74-gpp13.2.mdx | 204 ++++++++++++++++ pages/guides/httpserver-bun.mdx | 79 ++++-- pages/guides/httpserver-c-debug.mdx | 74 ++++-- pages/guides/httpserver-dotnet10.0.mdx | 81 +++++-- pages/guides/httpserver-elixir1.16.mdx | 75 ++++-- pages/guides/httpserver-erlang26.2.mdx | 85 +++++-- .../httpserver-expressjs4.18-node21.mdx | 91 +++++-- pages/guides/httpserver-gcc13.2.mdx | 86 +++++-- pages/guides/httpserver-go1.21.mdx | 86 +++++-- ...ver-g++13.2.mdx => httpserver-gpp13.2.mdx} | 96 +++++--- .../httpserver-java17-spring-petclinic.mdx | 171 +++++++++++++ ... => httpserver-java17-springboot3.5.x.mdx} | 101 +++++--- pages/guides/httpserver-java21.mdx | 79 ++++-- pages/guides/httpserver-lua5.1.mdx | 76 ++++-- .../guides/httpserver-nginx-vite-vanilla.mdx | 81 +++++-- .../httpserver-node-express-puppeteer.mdx | 87 +++++-- .../httpserver-node-vite-ssr-vanilla.mdx | 191 +++++++++++++++ pages/guides/httpserver-node-vite-vanilla.mdx | 195 +++++++++++++++ pages/guides/httpserver-node21-nextjs.mdx | 88 +++++-- pages/guides/httpserver-node21-remix.mdx | 74 ++++-- .../guides/httpserver-node21-solid-start.mdx | 74 ++++-- pages/guides/httpserver-node21-sveltekit.mdx | 82 +++++-- pages/guides/httpserver-node25.mdx | 79 ++++-- pages/guides/httpserver-perl5.42.mdx | 78 ++++-- pages/guides/httpserver-php8.2.mdx | 76 ++++-- ...httpserver-prisma-expressjs4.19-node18.mdx | 89 +++++-- .../httpserver-python3.12-FastAPI-0.121.3.mdx | 226 ------------------ .../httpserver-python3.12-django5.0.mdx | 90 +++++-- .../httpserver-python3.12-fastapi-0.121.3.mdx | 203 ++++++++++++++++ .../httpserver-python3.12-flask3.0-sqlite.mdx | 86 +++++-- .../guides/httpserver-python3.12-flask3.0.mdx | 84 +++++-- pages/guides/httpserver-python3.12.mdx | 91 +++++-- pages/guides/httpserver-ruby3.2.mdx | 76 ++++-- .../guides/httpserver-rust-trunkrs-leptos.mdx | 178 ++++++++++++++ pages/guides/httpserver-rust1.75-tokio.mdx | 76 ++++-- .../guides/httpserver-rust1.81-rocket0.5.mdx | 82 +++++-- .../guides/httpserver-rust1.87-actix-web4.mdx | 77 ++++-- pages/guides/httpserver-rust1.91.mdx | 75 ++++-- pages/guides/hugo0.122.mdx | 76 ++++-- pages/guides/imaginary.mdx | 78 ++++-- pages/guides/mariadb.mdx | 82 +++++-- pages/guides/mcp-server-arxiv.mdx | 81 +++++-- pages/guides/mcp-server-simple.mdx | 74 ++++-- pages/guides/memcached1.6.mdx | 76 ++++-- pages/guides/minio.mdx | 74 ++++-- pages/guides/mongodb.mdx | 137 +++++++---- pages/guides/nginx.mdx | 74 ++++-- pages/guides/node-playwright-chromium.mdx | 180 ++++++++++++++ pages/guides/node-playwright-firefox.mdx | 180 ++++++++++++++ pages/guides/node-playwright-webkit.mdx | 180 ++++++++++++++ pages/guides/node18-agario.mdx | 174 ++++++++++++++ pages/guides/node18-wingsio.mdx | 173 ++++++++++++++ pages/guides/node21-websocket.mdx | 188 +++++++++++++++ pages/guides/node24-karaoke.mdx | 79 ++++-- pages/guides/novnc-browser.mdx | 73 ++++-- pages/guides/opentelemetry-collector.mdx | 67 ++++-- pages/guides/overview.mdx | 49 +++- pages/guides/postgres.mdx | 79 ++++-- pages/guides/python-playwright-chromium.mdx | 181 ++++++++++++++ pages/guides/redis7.2.mdx | 213 +++++++++++++++++ pages/guides/ruby3.2-rails.mdx | 84 +++++-- pages/guides/skipper0.18.mdx | 76 ++++-- pages/guides/spin-wagi-http.mdx | 86 +++++-- pages/guides/traefik.mdx | 77 ++++-- pages/guides/visual-studio-code-server.mdx | 88 +++++-- pages/guides/vsftpd.mdx | 86 +++++-- pages/guides/wazero-import-go.mdx | 77 ++++-- pages/guides/wordpress-all-in-one.mdx | 101 ++++++-- scripts/transform_readme.py | 130 ++++++++-- zudoku.config.tsx | 32 ++- 82 files changed, 6395 insertions(+), 1649 deletions(-) delete mode 100644 pages/guides/httpserver-boost1.74-g++13.2.mdx create mode 100644 pages/guides/httpserver-boost1.74-gpp13.2.mdx rename pages/guides/{httpserver-g++13.2.mdx => httpserver-gpp13.2.mdx} (50%) create mode 100644 pages/guides/httpserver-java17-spring-petclinic.mdx rename pages/guides/{httpserver-java17-springboot3.2.x.mdx => httpserver-java17-springboot3.5.x.mdx} (50%) create mode 100644 pages/guides/httpserver-node-vite-ssr-vanilla.mdx create mode 100644 pages/guides/httpserver-node-vite-vanilla.mdx delete mode 100644 pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx create mode 100644 pages/guides/httpserver-python3.12-fastapi-0.121.3.mdx create mode 100644 pages/guides/httpserver-rust-trunkrs-leptos.mdx create mode 100644 pages/guides/node-playwright-chromium.mdx create mode 100644 pages/guides/node-playwright-firefox.mdx create mode 100644 pages/guides/node-playwright-webkit.mdx create mode 100644 pages/guides/node18-agario.mdx create mode 100644 pages/guides/node18-wingsio.mdx create mode 100644 pages/guides/node21-websocket.mdx create mode 100644 pages/guides/python-playwright-chromium.mdx create mode 100644 pages/guides/redis7.2.mdx diff --git a/.github/workflows/sync.yaml b/.github/workflows/sync.yaml index 6dd05134..889d0212 100644 --- a/.github/workflows/sync.yaml +++ b/.github/workflows/sync.yaml @@ -56,6 +56,8 @@ jobs: commit-message: "chore: Update guides from examples repository" title: "chore: Update guides from examples repository" body: | + IMPORTANT: Please make sure to review the deployment of this PR and also update `zudoku.config.ts` and `pages/guides/overview.mdx` if necessary. + Automated sync of example READMEs from [`unikraft/examples@${{ inputs.examples_branch }}`](https://github.com/unikraft/examples/tree/${{ inputs.examples_branch }}). This PR updates the guides in `pages/guides/` with the latest content from the examples repository. diff --git a/.gitignore b/.gitignore index 4dc3d799..df398fbd 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ dist/ # generated files apis/platform.yaml build.log +.examples/ diff --git a/.vale/styles/config/vocabularies/Unikraft/accept.txt b/.vale/styles/config/vocabularies/Unikraft/accept.txt index 19a13328..2a4ed8df 100644 --- a/.vale/styles/config/vocabularies/Unikraft/accept.txt +++ b/.vale/styles/config/vocabularies/Unikraft/accept.txt @@ -236,6 +236,7 @@ FTP (?i)SSD(s)? (?i)ssh (?i)ssl +(?i)SSR (?i)stderr (?i)stdin (?i)stdout diff --git a/Makefile b/Makefile index 5d28e6d8..2e6286c5 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,7 @@ sync: rm -rf "$$EXAMPLES_LOCAL"; \ git clone --depth 1 --branch $(EXAMPLES_BRANCH) https://github.com/$(EXAMPLES_REPO) "$$EXAMPLES_LOCAL"; \ fi; \ + updated_guides=""; \ for example in $$(find "$$EXAMPLES_LOCAL" -mindepth 1 -maxdepth 1 -type d -not -name '.*'); do \ name=$$(basename "$$example"); \ readme="$$example/README.md"; \ @@ -54,10 +55,19 @@ sync: guide="$(GUIDES_DIR)/$$name.mdx" ;\ echo " πŸ“„ $$name -> $$(basename $$guide)" ;\ $(WORKDIR)/scripts/transform_readme.py "$$readme" "$$guide" "$$name" ;\ + updated_guides="$$updated_guides $$name.mdx" ;\ else \ echo "⏭ Skipping $$name (metro line not present)" ;\ fi ;\ fi; \ + done; \ + for guide in $$(find "$(GUIDES_DIR)" -maxdepth 1 -name '*.mdx' -type f); do \ + gname=$$(basename "$$guide"); \ + if [ "$$gname" = "overview.mdx" ]; then continue; fi; \ + if ! echo "$$updated_guides" | grep -qw "$$gname"; then \ + echo " πŸ—‘ Removing stale guide: $$gname"; \ + rm -f "$$guide"; \ + fi; \ done .PHONY: sync-list diff --git a/pages/guides/caddy2.7-go1.21.mdx b/pages/guides/caddy2.7-go1.21.mdx index 919a71b5..23b502de 100644 --- a/pages/guides/caddy2.7-go1.21.mdx +++ b/pages/guides/caddy2.7-go1.21.mdx @@ -5,13 +5,16 @@ title: "Caddy" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example uses [`Caddy`](https://caddyserver.com/), one of the most popular web servers. Caddy can be used with Unikraft / Unikraft Cloud to serve static web content. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/caddy2.7-go1.21/` directory: @@ -44,33 +47,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /caddy27-go121:latest -unikraft run --metro=fra -p 443:2015/http+tls -m 256M --image=/caddy27-go121:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:2015/http+tls -m 256M --image /caddy27-go121:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:2015/http+tls -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:2015/http+tls -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: caddy27-go121-vhf4m +uuid: db624eff-4739-4500-873c-f7c58e4eefd7 +state: starting +image: /caddy27-go121 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: 085cfc91-34d2-0e4d-5f19-fe67832f16a8 + name: frosty-sky-vz8kwsmb + domains: + - fqdn: frosty-sky-vz8kwsmb.fra.unikraft.app +networks: +- uuid: a72ea1ab-9686-c5b5-a8c2-fd58922f30f3 + private-ip: 10.0.6.2 + mac: 12:b0:a9:b2:fd:13 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: caddy27-go121-vhf4m - β”œ────────── uuid: db624eff-4739-4500-873c-f7c58e4eefd7 - β”œ───────── state: running - β”œ─────────── url: https://frosty-sky-vz8kwsmb.fra.unikraft.app - β”œ───────── image: caddy27-go121@sha256:25df97e3c43147c683f31dd062d0fa75122358b596de5804ca246c4e8613dd56 - β”œ───── boot time: 20.18ms - β”œ──────── memory: 256 MiB - β”œ─────── service: frosty-sky-vz8kwsmb - β”œ── private fqdn: caddy27-go121-vhf4m.internal - β”œ──── private ip: 172.16.6.2 - β””────────── args: /usr/bin/caddy run --config /etc/caddy/Caddyfile + β”œ───────── name: caddy27-go121-vhf4m + β”œ───────── uuid: db624eff-4739-4500-873c-f7c58e4eefd7 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://frosty-sky-vz8kwsmb.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//caddy27-go121@sha256:25df97e3c43147c683f31dd062d0fa75122358b596de5804ca246c4e8613dd56 + β”œ─────── memory: 256 MiB + β”œ────── service: frosty-sky-vz8kwsmb + β”œ─ private fqdn: caddy27-go121-vhf4m.internal + β””─── private ip: 10.0.6.2 ``` + + In this case, the instance name is `caddy27-go121-vhf4m` and the address is `https://frosty-sky-vz8kwsmb.fra.unikraft.app`. They're different for each run. @@ -98,11 +126,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -caddy27-go121-vhf4m frosty-sky-vz8kwsmb.fra.unikraft.app running 1 minute ago caddy27-go121@sha256:25df97e3c... 256 MiB 1 /usr/bin/caddy run --config /e... 20180us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra caddy27-go121-vhf4m running /caddy27-go121 256MiB 1 frosty-sky-vz8kwsmb.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +caddy27-go121-vhf4m frosty-sky-vz8kwsmb.fra.unikraft.app running 1 minute ago oci://unikraft.io//caddy27-go121@sha256:... 256 MiB 1 20.18 ms ``` + + When done, you can remove the instance: @@ -164,3 +201,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/debian-ssh.mdx b/pages/guides/debian-ssh.mdx index 65a774be..9480a46d 100644 --- a/pages/guides/debian-ssh.mdx +++ b/pages/guides/debian-ssh.mdx @@ -5,11 +5,14 @@ title: "Debian SSH server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a Debian app with SSH enabled. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/debian-ssh` directory: @@ -42,32 +45,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /debian-ssh:latest -unikraft run --metro=fra -p 2222:2222/tls -m 1G -e PUBKEY="...." --image=/debian-ssh:latest +unikraft run --scale-to-zero policy=off --metro fra -p 2222:2222/tls -m 1G -e PUBKEY="...." --image /debian-ssh:latest ``` ```bash title="kraft" -kraft cloud deploy -p 2222:2222/tls -M 1G -e PUBKEY="...." . +kraft cloud deploy --scale-to-zero off -p 2222:2222/tls -M 1Gi -e PUBKEY="...." . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: debian-ssh-2uwg5 +uuid: b3d158c5-fb52-4685-a76b-2497973308dc +state: starting +image: /debian-ssh +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: 5771bead-c045-52fa-1f89-5bc4f1cf3c38 + name: nameless-cherry-sw2e9ul2 + domains: + - fqdn: nameless-cherry-sw2e9ul2.fra.unikraft.app +networks: +- uuid: 9d76ad3f-2149-f0af-d77f-76daba253d33 + private-ip: 10.0.0.109 + mac: 12:b0:1d:bd:54:f6 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ─────── name: debian-ssh-2uwg5 - β”œ─────── uuid: b3d158c5-fb52-4685-a76b-2497973308dc - β”œ────── metro: https://api.fra.unikraft.cloud/v1 - β”œ────── state: starting - β”œ───── domain: nameless-cherry-sw2e9ul2.fra.unikraft.app - β”œ────── image: debian-ssh@sha256:2442b4d5e078e7bc9ccd887fac65623511551592315d341a219f34a2c6628949 - β”œ───── memory: 1024 MiB - β”œ──── service: nameless-cherry-sw2e9ul2 - β”œ─ private ip: 10.0.0.109 - β””─────── args: /usr/bin/wrapper.sh + β”œ───────── name: debian-ssh-2uwg5 + β”œ───────── uuid: b3d158c5-fb52-4685-a76b-2497973308dc + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://nameless-cherry-sw2e9ul2.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//debian-ssh@sha256:2442b4d5e078e7bc9ccd887fac65623511551592315d341a219f34a2c6628949 + β”œ─────── memory: 1024 MiB + β”œ────── service: nameless-cherry-sw2e9ul2 + β”œ─ private fqdn: debian-ssh-2uwg5.internal + β””─── private ip: 10.0.0.109 ``` + + In this case, the instance name is `debian-ssh-2uwg5` and the address is `nameless-cherry-sw2e9ul2.fra.unikraft.app`. They're different for each run. @@ -101,11 +130,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -debian-ssh-2uwg5 nameless-cherry-sw2e9ul2.fra.unikraft.app running since 5mins debian-ssh@sha256:2442... 1.0 GiB 1 /usr/bin/wrapper.sh 217.26 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra debian-ssh-2uwg5 running /debian-ssh 1.0GiB 1 nameless-cherry-sw2e9ul2.fra.unikraft… 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +debian-ssh-2uwg5 nameless-cherry-sw2e9ul2.fra.unikraft.app running since 5mins oci://unikraft.io//debian-ssh@sha256:... 1.0 GiB 1 217.26 ms ``` + + When done, you can remove the instance: @@ -136,4 +174,5 @@ kraft cloud --help -Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). \ No newline at end of file +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/dragonflydb.mdx b/pages/guides/dragonflydb.mdx index 5b26e998..173a8044 100644 --- a/pages/guides/dragonflydb.mdx +++ b/pages/guides/dragonflydb.mdx @@ -5,12 +5,15 @@ title: "DragonflyDB" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" -This guides shows you how to deploy [Dragonfly](https://www.dragonflydb.io/), a simple, performant, and cost-efficient in-memory data store. +{/* vale off */} +This guide shows you how to deploy [Dragonfly](https://www.dragonflydb.io/), a simple, performant, and cost-efficient in-memory data store. -To run it example, follow these steps: +To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/dragonflydb/` directory: @@ -43,33 +46,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /dragonflydb:latest -unikraft run --metro=fra -p 443:6379/http+tls -m 512M --image=/dragonflydb:latest +unikraft run --scale-to-zero policy=off --metro fra -p 443:6379/http+tls -m 512M --image /dragonflydb:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:6379/http+tls -M 512M . +kraft cloud deploy --scale-to-zero off -p 443:6379/http+tls -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: dragonflydb-10zgk +uuid: 6282ef0c-2161-494c-a3f3-2d16055096c2 +state: starting +image: /dragonflydb +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 18326b44-a571-6195-b9e6-9368832ff2b3 + name: dry-moon-x6bgl6c0 + domains: + - fqdn: dry-moon-x6bgl6c0.fra.unikraft.app +networks: +- uuid: 87aa7a40-2a83-f315-b656-e07a8637af64 + private-ip: 10.0.6.5 + mac: 12:b0:8f:c2:51:55 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: dragonflydb-10zgk - β”œ────────── uuid: 6282ef0c-2161-494c-a3f3-2d16055096c2 - β”œ───────── state: running - β”œ─────────── url: https://dry-moon-x6bgl6c0.fra.unikraft.app - β”œ───────── image: dragonflydb@sha256:21e6d3ff1f86292e14266bcf5c6e73d3b7a86a0ec4102c66a0961373af743f19 - β”œ───── boot time: 28.74 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: dry-moon-x6bgl6c0 - β”œ── private fqdn: dragonflydb-10zgk.internal - β”œ──── private ip: 172.16.6.5 - β””────────── args: /usr/bin/dragonfly --maxmemory 256MiB + β”œ───────── name: dragonflydb-10zgk + β”œ───────── uuid: 6282ef0c-2161-494c-a3f3-2d16055096c2 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://dry-moon-x6bgl6c0.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//dragonflydb@sha256:21e6d3ff1f86292e14266bcf5c6e73d3b7a86a0ec4102c66a0961373af743f19 + β”œ─────── memory: 512 MiB + β”œ────── service: dry-moon-x6bgl6c0 + β”œ─ private fqdn: dragonflydb-10zgk.internal + β””─── private ip: 10.0.6.5 ``` + + In this case, the instance name is `dragonflydb-10zgk` and the address is `https://dry-moon-x6bgl6c0.fra.unikraft.app`. They're different for each run. @@ -120,11 +148,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -dragonflydb-10zgk dry-moon-x6bgl6c0.fra.unikraft.app running 1 minute ago dragonflydb@sha256:21e6d3... 512 MiB 1 /usr/bin/dragonfly --maxmemor... 28740us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra dragonflydb-10zgk running /dragonflydb 512MiB 1 dry-moon-x6bgl6c0.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +dragonflydb-10zgk dry-moon-x6bgl6c0.fra.unikraft.app running 1 minute ago oci://unikraft.io//dragonflydb@sha256:... 512 MiB 1 28.74 ms ``` + + When done, you can remove the instance: @@ -163,3 +200,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/duckdb-go1.21.mdx b/pages/guides/duckdb-go1.21.mdx index d045e6ba..79310058 100644 --- a/pages/guides/duckdb-go1.21.mdx +++ b/pages/guides/duckdb-go1.21.mdx @@ -5,12 +5,15 @@ title: "DuckDB with Go" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows you how to use [DuckDB](https://duckdb.org), an in-process SQL OLAP database management system, in your Go project. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/duckdb-go1.21/` directory: @@ -42,35 +45,60 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /duckdb-go1.21:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/duckdb-go1.21:latest +unikraft build . --output /duckdb-go121:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 256M --image /duckdb-go121:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: duckdb-go121-qfd8x +uuid: 90960d27-458b-4dd7-a037-2a9a3a47f095 +state: starting +image: /duckdb-go121 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: 0e3c61f1-5ad3-7d75-ceaf-079ea83394f6 + name: autumn-gorilla-hg4h6sup + domains: + - fqdn: autumn-gorilla-hg4h6sup.fra.unikraft.app +networks: +- uuid: 0f66c51a-dcad-94fc-d0a8-b0570e3d1b97 + private-ip: 10.0.6.2 + mac: 12:b0:31:d1:4b:90 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: duckdb-go1.21-qfd8x - β”œ────────── uuid: 90960d27-458b-4dd7-a037-2a9a3a47f095 - β”œ───────── state: running - β”œ─────────── url: https://autumn-gorilla-hg4h6sup.fra.unikraft.app - β”œ───────── image: duckdb-go1.21@sha256:6999293f8694ac00beb6a1d639fab8f96f78c2e6ecb8ccb2311539908895a699 - β”œ───── boot time: 32.12 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: autumn-gorilla-hg4h6sup - β”œ── private fqdn: duckdb-go1.21-qfd8x.internal - β”œ──── private ip: 172.16.6.2 - β””────────── args: /server -``` - -In this case, the instance name is `duckdb-go1.21-qfd8x` and the address is `https://autumn-gorilla-hg4h6sup.fra.unikraft.app`. + β”œ───────── name: duckdb-go121-qfd8x + β”œ───────── uuid: 90960d27-458b-4dd7-a037-2a9a3a47f095 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://autumn-gorilla-hg4h6sup.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//duckdb-go121@sha256:6999293f8694ac00beb6a1d639fab8f96f78c2e6ecb8ccb2311539908895a699 + β”œ─────── memory: 256 MiB + β”œ────── service: autumn-gorilla-hg4h6sup + β”œ─ private fqdn: duckdb-go121-qfd8x.internal + β””─── private ip: 10.0.6.2 +``` + + + +In this case, the instance name is `duckdb-go121-qfd8x` and the address is `https://autumn-gorilla-hg4h6sup.fra.unikraft.app`. They're different for each run. Use `curl` to query the Unikraft Cloud instance of DuckDB. @@ -97,21 +125,30 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -duckdb-go1.21-qfd8x autumn-gorilla-hg4h6sup.fra.unikraft.app running 1 minute ago duckdb-go1.21@sha256:6999293f869... 256 MiB 1 /server 32118us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra duckdb-go121-qfd8x running /duckdb-go121 256MiB 1 autumn-gorilla-hg4h6sup.fra.unikraft.app 2 minutes ago ``` +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +duckdb-go121-qfd8x autumn-gorilla-hg4h6sup.fra.unikraft.app running 1 minute ago oci://unikraft.io//duckdb-go121@sha256:... 256 MiB 1 32.12 ms +``` + + + When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete duckdb-go1.21-qfd8x +unikraft instances delete duckdb-go121-qfd8x ``` ```bash title="kraft" -kraft cloud instance remove duckdb-go1.21-qfd8x +kraft cloud instance remove duckdb-go121-qfd8x ``` @@ -153,3 +190,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/github-webhook-node.mdx b/pages/guides/github-webhook-node.mdx index fd3259b5..f388d074 100644 --- a/pages/guides/github-webhook-node.mdx +++ b/pages/guides/github-webhook-node.mdx @@ -5,15 +5,19 @@ title: "GitHub Webhook receiver" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example shows how to build a simple GitHub Webhook receiver using Node.js with [Express](https://expressjs.com/) and run it on Unikraft Cloud. A webhook, also called a reverse API, is a way for a server to send real-time data to other applications when a specific event occurs. In this case, the webhook receiver listens for GitHub events, such as push events or pull request events, and logs them to the console. -To run this it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +To run this example, follow these steps: + +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). -1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/github-webhook-node/` directory: +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/github-webhook-node/` directory: ```bash git clone https://github.com/unikraft-cloud/examples @@ -44,11 +48,11 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /github-webhook-node:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 1G -e GITHUB_WEBHOOK_SECRET=your_secret_here --image=/github-webhook-node:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:3000/tls+http -m 1G -e GITHUB_WEBHOOK_SECRET=your_secret_here --image /github-webhook-node:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 1G -e GITHUB_WEBHOOK_SECRET=your_secret_here . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 1Gi -e GITHUB_WEBHOOK_SECRET=your_secret_here . ``` @@ -57,21 +61,47 @@ kraft cloud deploy -p 443:3000/tls+http -M 1G -e GITHUB_WEBHOOK_SECRET=your_secr Set it to a string with high entropy. The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: github-webhook-node-bzq7u +uuid: 8a8634f1-fc78-4cc0-aa36-8f082d8a59f5 +state: starting +image: /github-webhook-node +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: 67c7cca2-ca82-1467-e2f1-1b455edb638c + name: dry-cloud-uuw0qlb6 + domains: + - fqdn: dry-cloud-uuw0qlb6.fra.unikraft.app +networks: +- uuid: 6153b689-b713-97c3-f8bb-bd08cc47f6bc + private-ip: 10.0.1.205 + mac: 12:b0:d0:97:b0:d2 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ─────── name: github-webhook-node-bzq7u - β”œ─────── uuid: 8a8634f1-fc78-4cc0-aa36-8f082d8a59f5 - β”œ────── metro: https://api.fra.unikraft.cloud/v1 - β”œ────── state: starting - β”œ───── domain: https://dry-cloud-uuw0qlb6.fra.unikraft.app - β”œ────── image: github-webhook-node@sha256:10974aac67ce6355148e21d91f918960bf0af29ad840fffeeb2fd01f8c905f66 - β”œ───── memory: 1024 MiB - β”œ──── service: dry-cloud-uuw0qlb6 - β”œ─ private ip: 10.0.1.205 - β””─────── args: node /app/server.js + β”œ───────── name: github-webhook-node-bzq7u + β”œ───────── uuid: 8a8634f1-fc78-4cc0-aa36-8f082d8a59f5 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://dry-cloud-uuw0qlb6.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//github-webhook-node@sha256:10974aac67ce6355148e21d91f918960bf0af29ad840fffeeb2fd01f8c905f66 + β”œ─────── memory: 1024 MiB + β”œ────── service: dry-cloud-uuw0qlb6 + β”œ─ private fqdn: github-webhook-node-bzq7u.internal + β””─── private ip: 10.0.1.205 ``` + + In this case, the instance name is `github-webhook-node-bzq7u` and the address is `https://dry-cloud-uuw0qlb6.fra.unikraft.app`. They're different for each run. @@ -131,11 +161,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -github-webhook-node-bzq7u dry-cloud-uuw0qlb6.fra.unikraft.app standby standby github-webhook-node@sha256:10974aac67ce6355148e... 1.0 GiB 1 node /app/server.js 197.47 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra github-webhook-node-bzq7u standby /github-webhook-node 1.0GiB 1 dry-cloud-uuw0qlb6.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +github-webhook-node-bzq7u dry-cloud-uuw0qlb6.fra.unikraft.app standby standby oci://unikraft.io//github-webhook-node@sha256:... 1.0 GiB 1 197.47 ms ``` + + When done, you can remove the instance: @@ -215,3 +254,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/grafana.mdx b/pages/guides/grafana.mdx index 329a7bfb..0561a116 100644 --- a/pages/guides/grafana.mdx +++ b/pages/guides/grafana.mdx @@ -5,12 +5,15 @@ title: "Grafana" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows you how to use [Grafana](https://grafana.com), the open source analytics & monitoring solution for every database. To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/grafana/` directory: @@ -43,33 +46,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /grafana:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 2G --image=/grafana:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 443:3000/tls+http -m 2G --image /grafana:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 2G . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 2Gi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: grafana-sikrv +uuid: 1d8f0b36-39ff-45a2-8baa-664640c60885 +state: starting +image: /grafana +resources: + memory: 2048MiB + vcpus: 1 +service: + uuid: baedae7b-0836-4b53-d1f5-a6bbcd373155 + name: dawn-water-4jlnvgpy + domains: + - fqdn: dawn-water-4jlnvgpy.fra.unikraft.app +networks: +- uuid: de0faba6-9c16-f108-a32a-f6bc4133a9cd + private-ip: 10.0.6.6 + mac: 12:b0:fb:95:5b:66 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: grafana-sikrv - β”œ────────── uuid: 1d8f0b36-39ff-45a2-8baa-664640c60885 - β”œ───────── state: running - β”œ─────────── url: https://icy-sea-i6m5fwyk.fra.unikraft.app - β”œ───────── image: grafana@sha256:484d6f98cdc321443188b8f2900035182dffdb45069f3cd087dcb6851ddff3bc - β”œ───── boot time: 502.65 ms - β”œ──────── memory: 2048 MiB - β”œ─────── service: dawn-water-4jlnvgpy - β”œ── private fqdn: grafana-mgby4.internal - β”œ──── private ip: 172.16.6.6 - β””────────── args: /usr/share/grafana/bin/grafana server -homepath /usr/share/grafana/ + β”œ───────── name: grafana-sikrv + β”œ───────── uuid: 1d8f0b36-39ff-45a2-8baa-664640c60885 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://icy-sea-i6m5fwyk.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//grafana@sha256:484d6f98cdc321443188b8f2900035182dffdb45069f3cd087dcb6851ddff3bc + β”œ─────── memory: 2048 MiB + β”œ────── service: dawn-water-4jlnvgpy + β”œ─ private fqdn: grafana-mgby4.internal + β””─── private ip: 10.0.6.6 ``` + + In this case, the instance name is `grafana-sikrv` and the address is `https://icy-sea-i6m5fwyk.fra.unikraft.app`. They're different for each run. @@ -90,11 +118,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -grafana-sikrv icy-sea-i6m5fwyk.fra.unikraft.app running 11 minutes ago grafana@sha256:484d6f98c... 2048 MiB 1 /usr/share/grafana/bin/grafana server... 502651us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra grafana-sikrv running /grafana 2048MiB 1 icy-sea-i6m5fwyk.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +grafana-sikrv icy-sea-i6m5fwyk.fra.unikraft.app running 11 minutes ago oci://unikraft.io//grafana@sha256:... 2048 MiB 1 502.65 ms ``` + + When done, you can remove the instance: @@ -142,3 +179,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/haproxy.mdx b/pages/guides/haproxy.mdx index aeb5c6b0..fdbab85e 100644 --- a/pages/guides/haproxy.mdx +++ b/pages/guides/haproxy.mdx @@ -5,13 +5,16 @@ title: "HAProxy" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows you how to use [HAProxy](https://www.haproxy.org). HAProxy is a free and open source software that provides a high availability load balancer and reverse proxy for TCP and HTTP-based apps that spreads requests across many servers. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/haproxy/` directory: @@ -44,33 +47,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /haproxy:latest -unikraft run --metro=fra -p 443:8404/tls+http -m 256M --image=/haproxy:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8404/tls+http -m 256M --image /haproxy:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8404/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8404/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: haproxy-rfx6z +uuid: 09bd081e-e082-4f73-8ba8-531123a39e2e +state: starting +image: /haproxy +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: c349833c-dacc-7763-306e-553f512c4d0e + name: cool-paper-svzzr3qq + domains: + - fqdn: cool-paper-svzzr3qq.fra.unikraft.app +networks: +- uuid: 494814aa-38cc-c4ed-dcad-5b7173b3033b + private-ip: 10.0.6.5 + mac: 12:b0:a4:a5:0d:24 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: haproxy-rfx6z - β”œ────────── uuid: 09bd081e-e082-4f73-8ba8-531123a39e2e - β”œ───────── state: running - β”œ─────────── url: https://cool-paper-svzzr3qq.fra.unikraft.app - β”œ───────── image: haproxy@sha256:32296847231c151506820ec4914c1d7416e5b7200caf07c1e40eaa3ea5033d21 - β”œ───── boot time: 26.60 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: cool-paper-svzzr3qq - β”œ── private fqdn: haproxy-rfx6z.internal - β”œ──── private ip: 172.16.6.5 - β””────────── args: /usr/bin/haproxy -f /etc/haproxy/haproxy.conf + β”œ───────── name: haproxy-rfx6z + β”œ───────── uuid: 09bd081e-e082-4f73-8ba8-531123a39e2e + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://cool-paper-svzzr3qq.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//haproxy@sha256:32296847231c151506820ec4914c1d7416e5b7200caf07c1e40eaa3ea5033d21 + β”œ─────── memory: 256 MiB + β”œ────── service: cool-paper-svzzr3qq + β”œ─ private fqdn: haproxy-rfx6z.internal + β””─── private ip: 10.0.6.5 ``` + + In this case, the instance name is `haproxy-rfx6z` and the address is `https://cool-paper-svzzr3qq.fra.unikraft.app`. They're different for each run. @@ -90,11 +118,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -haproxy-rfx6z cool-paper-svzzr3qq.fra.unikraft.app running 1 minute ago haproxy@sha256:32296847231c1515... 256 MiB 1 /usr/bin/haproxy -f /etc/hapro... 26596us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra haproxy-rfx6z running /haproxy 256MiB 1 cool-paper-svzzr3qq.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +haproxy-rfx6z cool-paper-svzzr3qq.fra.unikraft.app running 1 minute ago oci://unikraft.io//haproxy@sha256:... 256 MiB 1 26.60 ms ``` + + When done, you can remove the instance: @@ -133,3 +170,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-boost1.74-g++13.2.mdx b/pages/guides/httpserver-boost1.74-g++13.2.mdx deleted file mode 100644 index 6752aac5..00000000 --- a/pages/guides/httpserver-boost1.74-g++13.2.mdx +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: "C++ Boost HTTP Server" ---- - - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a C++-based HTTP web server using the [Boost](https://www.boost.org/) libraries. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -2. Clone the [example repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-boost1.74-g++13.2/` directory: - -```bash -git clone https://github.com/unikraft-cloud/examples -cd examples/httpserver-boost1.74-g++13.2/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output /httpserver-boost1.74-g++13.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-boost1.74-g++13.2:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────────── name: httpserver-boost1.74-g++13.2-rae7s - β”œ────────── uuid: 5a9886fa-f8a3-4860-afcf-d5eb13fdc38d - β”œ───────── state: running - β”œ─────────── url: https://red-snow-3bn7bzc8.fra.unikraft.app - β”œ───────── image: httpserver-boost1.74-g++13.2@sha256:61cf86b89fed46351af53689e27189315e466576475f61c7240bf17644613489 - β”œ───── boot time: 15.00 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: red-snow-3bn7bzc8 - β”œ── private fqdn: httpserver-boost1.74-g++13.2-rae7s.internal - β”œ──── private ip: 172.16.6.4 - β””────────── args: /http_server -``` - -In this case, the instance name is `httpserver-boost1.74-g++13.2-rae7s` and the address is `https://red-snow-3bn7bzc8.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the C++ Boost HTTP web server: - -```bash -curl https://red-snow-3bn7bzc8.fra.unikraft.app -``` - -```text -Hello, World! -``` - -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - - -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-boost1.74-g++13.2-rae7s red-snow-3bn7bzc8.fra.unikraft.app running 1 minute ago httpserver-boost1.74-g++13.2@sha256:61cf86... 256 MiB 1 /http_server 15000us -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances delete httpserver-boost1.74-g++13.2-rae7s -``` - -```bash title="kraft" -kraft cloud instance remove httpserver-boost1.74-g++13.2-rae7s -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `http_server.cpp`: the C++ HTTP server implementation -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - -Lines in the `Kraftfile` have the following roles: - -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. - -* `runtime: base`: The Unikraft runtime kernel to use is its base one. - -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. - -* `cmd: ["/http_server"]`: Use `/http_server` as the starting command of the instance. - -Lines in the `Dockerfile` have the following roles: - -* `COPY ./http_server.cpp /src/http_server.cpp`: Copy the server implementation file (`http_server.cpp`) in the Docker filesystem (in `/src/http_server.cpp`). - -The following options are available for customizing the app: - -* If you only update the implementation in the `http_server.cpp` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-boost1.74-gpp13.2.mdx b/pages/guides/httpserver-boost1.74-gpp13.2.mdx new file mode 100644 index 00000000..704f23a6 --- /dev/null +++ b/pages/guides/httpserver-boost1.74-gpp13.2.mdx @@ -0,0 +1,204 @@ +--- +title: "C++ Boost HTTP Server" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +This guide explains how to create and deploy a C++-based HTTP web server using the [Boost](https://www.boost.org/) libraries. +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [example repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-boost1.74-gpp13.2/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/httpserver-boost1.74-gpp13.2/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /httpserver-boost174-gpp132:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-boost174-gpp132:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: httpserver-boost174-gpp132-rae7s +uuid: 5a9886fa-f8a3-4860-afcf-d5eb13fdc38d +state: starting +image: /httpserver-boost174-gpp132 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: 52cfb573-c035-9f0c-5db7-63615d26f182 + name: red-snow-3bn7bzc8 + domains: + - fqdn: red-snow-3bn7bzc8.fra.unikraft.app +networks: +- uuid: 44a3d2c5-9ee5-fffc-b72f-d6109072bb8c + private-ip: 10.0.6.4 + mac: 12:b0:97:bc:2c:03 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: httpserver-boost174-gpp132-rae7s + β”œ───────── uuid: 5a9886fa-f8a3-4860-afcf-d5eb13fdc38d + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://red-snow-3bn7bzc8.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-boost174-gpp132@sha256:61cf86b89fed46351af53689e27189315e466576475f61c7240bf17644613489 + β”œ─────── memory: 256 MiB + β”œ────── service: red-snow-3bn7bzc8 + β”œ─ private fqdn: httpserver-boost174-gpp132-rae7s.internal + β””─── private ip: 10.0.6.4 +``` + + + +In this case, the instance name is `httpserver-boost174-gpp132-rae7s` and the address is `https://red-snow-3bn7bzc8.fra.unikraft.app`. +They're different for each run. + +Use `curl` to query the Unikraft Cloud instance of the C++ Boost HTTP web server: + +```bash +curl https://red-snow-3bn7bzc8.fra.unikraft.app +``` + +```text +Hello, World! +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-boost174-gpp132-rae7s running /httpserver-boost174-gpp132 256MiB 1 red-snow-3bn7bzc8.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-boost174-gpp132-rae7s red-snow-3bn7bzc8.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-boost174-gpp132@sha256:... 256 MiB 1 15.00 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete httpserver-boost174-gpp132-rae7s +``` + +```bash title="kraft" +kraft cloud instance remove httpserver-boost174-gpp132-rae7s +``` + + + +## Customize your app + +To customize the app, update the files in the repository, listed below: + +* `http_server.cpp`: the C++ HTTP server implementation +* `Kraftfile`: the Unikraft Cloud specification +* `Dockerfile`: the Docker-specified app filesystem + +Lines in the `Kraftfile` have the following roles: + +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. + +* `runtime: base`: The Unikraft runtime kernel to use is its base one. + +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + +* `cmd: ["/http_server"]`: Use `/http_server` as the starting command of the instance. + +Lines in the `Dockerfile` have the following roles: + +* `COPY ./http_server.cpp /src/http_server.cpp`: Copy the server implementation file (`http_server.cpp`) in the Docker filesystem (in `/src/http_server.cpp`). + +The following options are available for customizing the app: + +* If you only update the implementation in the `http_server.cpp` source file, you don't need to make any other changes. + +* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. + +* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-bun.mdx b/pages/guides/httpserver-bun.mdx index 9ddc478b..1df3d5bc 100644 --- a/pages/guides/httpserver-bun.mdx +++ b/pages/guides/httpserver-bun.mdx @@ -5,11 +5,14 @@ title: "Bun HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a Bun app. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-bun` directory: @@ -42,32 +45,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-bun:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 512M --image=/httpserver-bun:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:3000/tls+http -m 512M --image /httpserver-bun:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-bun-700mp +uuid: e467a880-075c-41e0-97ac-88e3e938523e +state: starting +image: /httpserver-bun +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 00cddace-e5e1-be6e-3423-86cccb5a1031 + name: quiet-pond-ao44imcg + domains: + - fqdn: quiet-pond-ao44imcg.fra.unikraft.app +networks: +- uuid: 3e41aab5-96c3-23e8-4afc-e2109f3f60de + private-ip: 10.0.3.3 + mac: 12:b0:6e:91:eb:5a +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-bun-700mp - β”œ────────── uuid: e467a880-075c-41e0-97ac-88e3e938523e - β”œ───────── state: starting - β”œ──────── domain: https://quiet-pond-ao44imcg.fra.unikraft.app - β”œ───────── image: httpserver-bun@sha256:dfcbee1efe0d8a1d43ab2dab70cf1cc5066bb1353aa1c528c745533d2cc33276 - β”œ──────── memory: 512 MiB - β”œ─────── service: quiet-pond-ao44imcg - β”œ── private fqdn: httpserver-bun-700mp.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/bun run /usr/src/server.ts + β”œ───────── name: httpserver-bun-700mp + β”œ───────── uuid: e467a880-075c-41e0-97ac-88e3e938523e + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://quiet-pond-ao44imcg.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-bun@sha256:dfcbee1efe0d8a1d43ab2dab70cf1cc5066bb1353aa1c528c745533d2cc33276 + β”œ─────── memory: 512 MiB + β”œ────── service: quiet-pond-ao44imcg + β”œ─ private fqdn: httpserver-bun-700mp.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `httpserver-bun-700mp` and the address is `https://quiet-pond-ao44imcg.fra.unikraft.app`. They're different for each run. @@ -95,11 +124,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-bun-700mp quiet-pond-ao44imcg.fra.unikraft.app running since 3mins httpserver-bun@sha256:dfcbee1ef... 512 MiB 1 /usr/bin/bun run /usr/src/server.ts 289.03 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-bun-700mp running /httpserver-bun 512MiB 1 quiet-pond-ao44imcg.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-bun-700mp quiet-pond-ao44imcg.fra.unikraft.app running since 3mins oci://unikraft.io//httpserver-bun@sha256:... 512 MiB 1 289.03 ms ``` + + When done, you can remove the instance: @@ -124,11 +162,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. * `runtime: base-compat:latest`: The kernel to use. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/bun", "run", "/usr/src/server.ts"]`: Use `/usr/bin/bun run /usr/src/server.ts` as the starting command of the instance. @@ -167,3 +207,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-c-debug.mdx b/pages/guides/httpserver-c-debug.mdx index 8895fb2e..96eea05b 100644 --- a/pages/guides/httpserver-c-debug.mdx +++ b/pages/guides/httpserver-c-debug.mdx @@ -5,11 +5,14 @@ title: "SSH and HTTP Server with C and Debugging Tools" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a C app with debugging enabled. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-c-debug` directory: @@ -42,33 +45,58 @@ For extensive debug information with `strace`, add the `USE_STRACE=1` environmen ```bash title="unikraft" unikraft build . --output /httpserver-c-debug:latest -unikraft run --metro=fra -p 443:8080/tls+http -p 2222:2222/tls -e PUBKEY=.... -e USE_STRACE=1 -m 256M --image=/httpserver-c-debug:latest +unikraft run --scale-to-zero policy=off --metro fra -p 443:8080/tls+http -p 2222:2222/tls -e PUBKEY=.... -e USE_STRACE=1 -m 256M --image /httpserver-c-debug:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -p 2222:2222/tls -M 256M -e PUBKEY="...." -e USE_STRACE=1 . +kraft cloud deploy --scale-to-zero off -p 443:8080/tls+http -p 2222:2222/tls -M 256Mi -e PUBKEY="...." -e USE_STRACE=1 . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-c-debug-5pvem +uuid: 08629a94-e2b1-466e-abb9-15ce46411b66 +state: starting +image: /httpserver-c-debug +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: 2e016406-0c59-4d74-6deb-fdcb206fdb1e + name: patient-snow-zdzhdy8r + domains: + - fqdn: patient-snow-zdzhdy8r.fra.unikraft.app +networks: +- uuid: 80a11393-8eca-ec11-3028-fb8908b21894 + private-ip: 10.0.0.109 + mac: 12:b0:45:b3:18:b2 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────── name: httpserver-c-debug-5pvem - β”œ────── uuid: 08629a94-e2b1-466e-abb9-15ce46411b66 - β”œ───── metro: https://api.fra.unikraft.cloud/v1 - β”œ───── state: running - β”œ──── domain: https://patient-snow-zdzhdy8r.fra.unikraft.app - β”œ───── image: httpserver-c-debug@sha256:b24b95e236c8eff69615dd4f5d257beed5ee4047fd98d1b6fb200f89c63fa54c - β”œ─ boot time: 66.56 ms - β”œ──── memory: 256 MiB - β”œ─── service: patient-snow-zdzhdy8r - β”œ private ip: 10.0.0.109 - β””────── args: /usr/bin/wrapper.sh + β”œ───────── name: httpserver-c-debug-5pvem + β”œ───────── uuid: 08629a94-e2b1-466e-abb9-15ce46411b66 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://patient-snow-zdzhdy8r.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-c-debug@sha256:b24b95e236c8eff69615dd4f5d257beed5ee4047fd98d1b6fb200f89c63fa54c + β”œ─────── memory: 256 MiB + β”œ────── service: patient-snow-zdzhdy8r + β”œ─ private fqdn: httpserver-c-debug-5pvem.internal + β””─── private ip: 10.0.0.109 ``` + + In this case, the instance name is `httpserver-c-debug-5pvem` and the address is `patient-snow-zdzhdy8r.fra.unikraft.app`. They're different for each run. @@ -112,11 +140,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-c-debug-5pvem patient-snow-zdzhdy8r.fra.unikraft.app running since 4mins httpserver-c-debug@sha256:b2... 256 MiB 1 /usr/bin/wrapper.sh 66.56 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-c-debug-5pvem running /httpserver-c-debug 256MiB 1 patient-snow-zdzhdy8r.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-c-debug-5pvem patient-snow-zdzhdy8r.fra.unikraft.app running since 4mins oci://unikraft.io//httpserver-c-debug@sha256:... 256 MiB 1 66.56 ms ``` + + When done, you can remove the instance: @@ -148,3 +185,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-dotnet10.0.mdx b/pages/guides/httpserver-dotnet10.0.mdx index 77a0713b..1d43e8d8 100644 --- a/pages/guides/httpserver-dotnet10.0.mdx +++ b/pages/guides/httpserver-dotnet10.0.mdx @@ -5,11 +5,14 @@ title: ".NET HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a simple .NET-based HTTP web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-dotnet10.0/` directory: @@ -41,33 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-dotnet10.0:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-dotnet10.0:latest +unikraft build . --output /httpserver-dotnet100:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 512M --image /httpserver-dotnet100:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-dotnet100-dsmkh +uuid: 25459494-cb43-4009-9d05-f0996de5b7e4 +state: starting +image: /httpserver-dotnet100 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 35a84131-01b7-b3cd-03a4-7acdd2c4f5f9 + name: cold-fog-hl98aw6q + domains: + - fqdn: cold-fog-hl98aw6q.fra.unikraft.app +networks: +- uuid: d4ddf6b4-91e5-8692-03a2-1e42552f6dbe + private-ip: 10.0.3.1 + mac: 12:b0:c0:f1:05:bd +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-dotnet100-dsmkh - β”œ────────── uuid: 25459494-cb43-4009-9d05-f0996de5b7e4 - β”œ───────── state: starting - β”œ─────────── url: https://cold-fog-hl98aw6q.fra.unikraft.app - β”œ───────── image: httpserver-dotnet100@sha256:4fad7453995ae96b636696e9929ee0e7376bfbbd63ab9698c1f1e02602aa2575 - β”œ──────── memory: 512 MiB - β”œ─────── service: cold-fog-hl98aw6q - β”œ── private fqdn: httpserver-dotnet100-dsmkh.internal - β”œ──── private ip: 172.16.3.1 - β””────────── args: /usr/bin/app/src + β”œ───────── name: httpserver-dotnet100-dsmkh + β”œ───────── uuid: 25459494-cb43-4009-9d05-f0996de5b7e4 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://cold-fog-hl98aw6q.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-dotnet100@sha256:4fad7453995ae96b636696e9929ee0e7376bfbbd63ab9698c1f1e02602aa2575 + β”œ─────── memory: 512 MiB + β”œ────── service: cold-fog-hl98aw6q + β”œ─ private fqdn: httpserver-dotnet100-dsmkh.internal + β””─── private ip: 10.0.3.1 ``` + + In this case, the instance name is `httpserver-dotnet100-dsmkh` and the address is `https://cold-fog-hl98aw6q.fra.unikraft.app`. They're different for each run. @@ -95,11 +124,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-dotnet100-dsmkh cold-fog-hl98aw6q.fra.unikraft.app running 2 minutes ago httpserver-dotnet100@sha256:4fad74e... 512 MiB 1 /usr/bin/app/src 328.69 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-dotnet100-dsmkh running /httpserver-dotnet100 512MiB 1 cold-fog-hl98aw6q.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-dotnet100-dsmkh cold-fog-hl98aw6q.fra.unikraft.app running 2 minutes ago oci://unikraft.io//httpserver-dotnet100@sha256:... 512 MiB 1 328.69 ms ``` + + When done, you can remove the instance: @@ -124,11 +162,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. * `runtime: base-compat:latest`: The runtime kernel to use is the base compatibility kernel. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd:`: Use as the starting command of the instance. @@ -173,3 +213,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-elixir1.16.mdx b/pages/guides/httpserver-elixir1.16.mdx index e8417b7d..59cec4c4 100644 --- a/pages/guides/httpserver-elixir1.16.mdx +++ b/pages/guides/httpserver-elixir1.16.mdx @@ -5,11 +5,14 @@ title: "Elixir HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a simple Elixir-based HTTP web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-elixir1.16/` directory: @@ -41,33 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-elixir1.16:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 1G --image=/httpserver-elixir1.16:latest +unikraft build . --output /httpserver-elixir116:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=3000,stateful=true --metro fra -p 443:3000/tls+http -m 1G --image /httpserver-elixir116:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 1G . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 3s -p 443:3000/tls+http -M 1Gi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-elixir116-qo9k3 +uuid: e5fbf089-b000-4b2d-a827-44a1f5d28f24 +state: starting +image: /httpserver-elixir116 +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: ddbc554c-3ce1-01ea-27d9-61690cb85717 + name: small-water-tl8lr8am + domains: + - fqdn: small-water-tl8lr8am.fra.unikraft.app +networks: +- uuid: 4e9f6ce2-9f8d-04ed-35e8-073582ac66bc + private-ip: 10.0.3.4 + mac: 12:b0:a2:d1:d5:d4 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-elixir116-qo9k3 - β”œ────────── uuid: e5fbf089-b000-4b2d-a827-44a1f5d28f24 - β”œ───────── state: running - β”œ──────── domain: https://small-water-tl8lr8am.fra.unikraft.app - β”œ───────── image: httpserver-elixir116@sha256:67f5df003758a1180932e931727f8cb7006bbbf6fdd84058e27fe05e4829bba0 - β”œ──────── memory: 1024 MiB - β”œ─────── service: small-water-tl8lr8am - β”œ── private fqdn: httpserver-elixir116-qo9k3.internal - β”œ──── private ip: 172.16.3.4 - β””────────── args: /usr/bin/wrapper.sh /usr/local/bin/mix run --no-halt + β”œ───────── name: httpserver-elixir116-qo9k3 + β”œ───────── uuid: e5fbf089-b000-4b2d-a827-44a1f5d28f24 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://small-water-tl8lr8am.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-elixir116@sha256:67f5df003758a1180932e931727f8cb7006bbbf6fdd84058e27fe05e4829bba0 + β”œ─────── memory: 1024 MiB + β”œ────── service: small-water-tl8lr8am + β”œ─ private fqdn: httpserver-elixir116-qo9k3.internal + β””─── private ip: 10.0.3.4 ``` + + In this case, the instance name is `httpserver-elixir116-qo9k3` and the address is `https://small-water-tl8lr8am.fra.unikraft.app`. They're different for each run. @@ -95,11 +124,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-elixir116-qo9k3 small-water-tl8lr8am.fra.unikraft.app running since 9mins httpserver-elixir116@sha256:6... 1.0 GiB 1 /usr/bin/wrapper.sh /usr/local/bin/mix r... 437.43 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-elixir116-qo9k3 running /httpserver-elixir116 1.0GiB 1 small-water-tl8lr8am.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-elixir116-qo9k3 small-water-tl8lr8am.fra.unikraft.app running since 9mins oci://unikraft.io//httpserver-elixir116@sha256:... 1.0 GiB 1 437.43 ms ``` + + When done, you can remove the instance: @@ -157,3 +195,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-erlang26.2.mdx b/pages/guides/httpserver-erlang26.2.mdx index b0b3944b..4f7cc5b8 100644 --- a/pages/guides/httpserver-erlang26.2.mdx +++ b/pages/guides/httpserver-erlang26.2.mdx @@ -5,11 +5,14 @@ title: "Erlang HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a simple Erlang-based HTTP web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-erlang26.2/` directory: @@ -41,34 +44,60 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-erlang26.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-erlang26.2:latest +unikraft build . --output /httpserver-erlang262:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 512M --image /httpserver-erlang262:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-erlang262-sw2bp +uuid: 1c4a8a51-fb61-45fc-87b8-26d192a7c2bc +state: starting +image: /httpserver-erlang262 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: c7a6b443-c424-8a96-ce90-e833841b6eca + name: patient-field-ck629j2u + domains: + - fqdn: patient-field-ck629j2u.fra.unikraft.app +networks: +- uuid: 6d767165-9196-e27d-bb12-5eb5a9188654 + private-ip: 10.0.3.3 + mac: 12:b0:05:ce:23:30 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-erlang26.2-sw2bp - β”œ────────── uuid: 1c4a8a51-fb61-45fc-87b8-26d192a7c2bc - β”œ───────── state: starting - β”œ──────── domain: https://patient-field-ck629j2u.fra.unikraft.app - β”œ───────── image: httpserver-erlang26.2@sha256:d99feefa7973ba43f726356497f54c34a16421aa25a27fa547d2c1add418204e - β”œ──────── memory: 512 MiB - β”œ─────── service: patient-field-ck629j2u - β”œ── private fqdn: httpserver-erlang26.2-sw2bp.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/wrapper.sh /usr/bin/erl -noshell -s http_server -``` - -In this case, the instance name is `httpserver-erlang26.2-sw2bp` and the address is `https://patient-field-ck629j2u.fra.unikraft.app`. + β”œ───────── name: httpserver-erlang262-sw2bp + β”œ───────── uuid: 1c4a8a51-fb61-45fc-87b8-26d192a7c2bc + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://patient-field-ck629j2u.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-erlang262@sha256:d99feefa7973ba43f726356497f54c34a16421aa25a27fa547d2c1add418204e + β”œ─────── memory: 512 MiB + β”œ────── service: patient-field-ck629j2u + β”œ─ private fqdn: httpserver-erlang262-sw2bp.internal + β””─── private ip: 10.0.3.3 +``` + + + +In this case, the instance name is `httpserver-erlang262-sw2bp` and the address is `https://patient-field-ck629j2u.fra.unikraft.app`. They're different for each run. Use `curl` to query the Unikraft Cloud instance of the Erlang-based HTTP web server: @@ -95,21 +124,30 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-erlang26.2-sw2bp patient-field-ck629j2u.fra.unikraft.app running since 35secs httpserver-erlang26.2@sha256:4372... 512 MiB 1 /usr/bin/wrapper.sh /usr/bin/erl ... 404.04 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-erlang262-sw2bp running /httpserver-erlang262 512MiB 1 patient-field-ck629j2u.fra.unikraft.app 2 minutes ago ``` +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-erlang262-sw2bp patient-field-ck629j2u.fra.unikraft.app running since 35secs oci://unikraft.io//httpserver-erlang262@sha256:... 512 MiB 1 404.04 ms +``` + + + When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-erlang26.2-sw2bp +unikraft instances delete httpserver-erlang262-sw2bp ``` ```bash title="kraft" -kraft cloud instance remove httpserver-erlang26.2-sw2bp +kraft cloud instance remove httpserver-erlang262-sw2bp ``` @@ -147,3 +185,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-expressjs4.18-node21.mdx b/pages/guides/httpserver-expressjs4.18-node21.mdx index 6e06d070..ee9c93e0 100644 --- a/pages/guides/httpserver-expressjs4.18-node21.mdx +++ b/pages/guides/httpserver-expressjs4.18-node21.mdx @@ -5,12 +5,15 @@ title: "Express HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} [Express](https://expressjs.com/) is a fast, unopinionated, minimalist web framework for Node.js. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-expressjs4.18-node21` directory: @@ -42,34 +45,60 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-expressjs4.18-node21:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 512M --image=/httpserver-expressjs4.18-node21:latest +unikraft build . --output /httpserver-expressjs418-node21:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:3000/tls+http -m 512M --image /httpserver-expressjs418-node21:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-expressjs418-node21-lb3p2 +uuid: a1b2c3d4-e5f6-7890-abcd-ef1234567890 +state: starting +image: /httpserver-expressjs418-node21 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: aa081882-8173-7ea1-4136-aeee1d7d2316 + name: calm-ocean-r9x4mk7v + domains: + - fqdn: calm-ocean-r9x4mk7v.fra.unikraft.app +networks: +- uuid: 98ee012f-7acb-82f2-ddcb-7866393890a6 + private-ip: 10.0.3.4 + mac: 12:b0:97:42:f6:d9 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-expressjs4.18-node21-lb3p2 - β”œ────────── uuid: a1b2c3d4-e5f6-7890-abcd-ef1234567890 - β”œ───────── state: starting - β”œ──────── domain: https://calm-ocean-r9x4mk7v.fra.unikraft.app - β”œ───────── image: httpserver-expressjs4.18-node21@sha256:2e7d3f1a9c4b8e05d6f2a3b7c1e4d8f0a2b5c9e3d7f1a4b8 - β”œ──────── memory: 512 MiB - β”œ─────── service: calm-ocean-r9x4mk7v - β”œ── private fqdn: httpserver-expressjs4.18-node21-lb3p2.internal - β”œ──── private ip: 172.16.3.4 - β””────────── args: /usr/bin/node /usr/src/server.js -``` - -In this case, the instance name is `httpserver-expressjs4.18-node21-lb3p2` and the address is `https://calm-ocean-r9x4mk7v.fra.unikraft.app`. + β”œ───────── name: httpserver-expressjs418-node21-lb3p2 + β”œ───────── uuid: a1b2c3d4-e5f6-7890-abcd-ef1234567890 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://calm-ocean-r9x4mk7v.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-expressjs418-node21@sha256:2e7d3f1a9c4b8e05d6f2a3b7c1e4d8f0a2b5c9e3d7f1a4b8 + β”œ─────── memory: 512 MiB + β”œ────── service: calm-ocean-r9x4mk7v + β”œ─ private fqdn: httpserver-expressjs418-node21-lb3p2.internal + β””─── private ip: 10.0.3.4 +``` + + + +In this case, the instance name is `httpserver-expressjs418-node21-lb3p2` and the address is `https://calm-ocean-r9x4mk7v.fra.unikraft.app`. They're different for each run. Use `curl` to query the Unikraft Cloud instance of the Express.js-based HTTP web server: @@ -96,21 +125,30 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-expressjs4.18-node21-lb3p2 calm-ocean-r9x4mk7v.fra... running since 3mins httpserver-expressjs4.18-node21@sha256:2... 512 MiB 1 /usr/bin/node /usr/src/server.js 312.45 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-expressjs418-node21-lb3p2 running /httpserver-expressjs418-node21 512MiB 1 calm-ocean-r9x4mk7v.fra... 2 minutes ago ``` +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-expressjs418-node21-lb3p2 calm-ocean-r9x4mk7v.fra... running since 3mins oci://unikraft.io//httpserver-expressjs418-node21@sha256:... 512 MiB 1 312.45 ms +``` + + + When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-expressjs4.18-node21-lb3p2 +unikraft instances delete httpserver-expressjs418-node21-lb3p2 ``` ```bash title="kraft" -kraft cloud instance remove httpserver-expressjs4.18-node21-lb3p2 +kraft cloud instance remove httpserver-expressjs418-node21-lb3p2 ``` @@ -125,11 +163,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. * `runtime: base-compat:latest`: The kernel to use. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/node", "/usr/src/server.js"]`: Use `/usr/bin/node /usr/src/server.js` as the starting command of the instance. @@ -173,3 +213,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-gcc13.2.mdx b/pages/guides/httpserver-gcc13.2.mdx index d4dde2d2..f327773f 100644 --- a/pages/guides/httpserver-gcc13.2.mdx +++ b/pages/guides/httpserver-gcc13.2.mdx @@ -5,11 +5,14 @@ title: "C HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a C app. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-gcc13.2` directory: @@ -41,35 +44,60 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-gcc13.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-gcc13.2:latest +unikraft build . --output /httpserver-gcc132:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-gcc132:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-gcc132-is2s9 +uuid: bec814ce-6ed5-4858-b247-e7f0b17750f5 +state: starting +image: /httpserver-gcc132 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: c36a4df6-b78d-677e-ea24-3e7a519a4130 + name: still-resonance-bja3lste + domains: + - fqdn: still-resonance-bja3lste.fra.unikraft.app +networks: +- uuid: 0f17e562-b57a-d40b-eecc-74e9058ecaaf + private-ip: 10.0.0.49 + mac: 12:b0:10:70:49:2f +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────── name: httpserver-gcc13.2-is2s9 - β”œ────── uuid: bec814ce-6ed5-4858-b247-e7f0b17750f5 - β”œ───── metro: https://api.fra.unikraft.cloud/v1 - β”œ───── state: running - β”œ──── domain: https://still-resonance-bja3lste.fra.unikraft.app - β”œ───── image: httpserver-gcc13.2@sha256:375677bf052f14c18ca79c86d2f47a68f3ea5f8636bcd8830753a254f0e06c1b - β”œ─ boot time: 13.29 ms - β”œ──── memory: 256 MiB - β”œ─── service: still-resonance-bja3lste - β”œ private ip: 10.0.0.49 - β””────── args: /http_server -``` - -In this case, the instance name is `httpserver-gcc13.2-is2s9` and the address is `https://still-resonance-bja3lste.fra.unikraft.app`. + β”œ───────── name: httpserver-gcc132-is2s9 + β”œ───────── uuid: bec814ce-6ed5-4858-b247-e7f0b17750f5 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://still-resonance-bja3lste.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-gcc132@sha256:375677bf052f14c18ca79c86d2f47a68f3ea5f8636bcd8830753a254f0e06c1b + β”œ─────── memory: 256 MiB + β”œ────── service: still-resonance-bja3lste + β”œ─ private fqdn: httpserver-gcc132-is2s9.internal + β””─── private ip: 10.0.0.49 +``` + + + +In this case, the instance name is `httpserver-gcc132-is2s9` and the address is `https://still-resonance-bja3lste.fra.unikraft.app`. They're different for each run. Use `curl` to query the Unikraft Cloud instance: @@ -96,21 +124,30 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-gcc13.2-is2s9 still-resonance-bja3lste.fra.unikraft.app standby standby httpserver-gcc13.2@sha256:375677bf052f14c18cc8... 256 MiB 1 /http_server 12.91 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-gcc132-is2s9 standby /httpserver-gcc132 256MiB 1 still-resonance-bja3lste.fra.unikraft… 2 minutes ago ``` +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-gcc132-is2s9 still-resonance-bja3lste.fra.unikraft.app standby standby oci://unikraft.io//httpserver-gcc132@sha256:... 256 MiB 1 12.91 ms +``` + + + When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-gcc13.2-is2s9 +unikraft instances delete httpserver-gcc132-is2s9 ``` ```bash title="kraft" -kraft cloud instance remove httpserver-gcc13.2-is2s9 +kraft cloud instance remove httpserver-gcc132-is2s9 ``` @@ -132,3 +169,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-go1.21.mdx b/pages/guides/httpserver-go1.21.mdx index 8789313b..6d5218db 100644 --- a/pages/guides/httpserver-go1.21.mdx +++ b/pages/guides/httpserver-go1.21.mdx @@ -5,11 +5,14 @@ title: "Go HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a simple Go-based HTTP web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-go1.21/` directory: @@ -41,35 +44,60 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-go1.21:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-go1.21:latest +unikraft build . --output /httpserver-go121:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-go121:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-go121-9a2wv +uuid: 8bb34040-9434-4a28-bd1e-c24ee532e2da +state: starting +image: /httpserver-go121 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: cc4ed399-32da-eb56-3671-b477108d1040 + name: red-dew-jtk6yxk1 + domains: + - fqdn: red-dew-jtk6yxk1.fra.unikraft.app +networks: +- uuid: 51f79dc1-e989-908d-894b-bdf0a87e7901 + private-ip: 10.0.3.3 + mac: 12:b0:57:91:bb:a5 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-go1.21-9a2wv - β”œ────────── uuid: 8bb34040-9434-4a28-bd1e-c24ee532e2da - β”œ───────── state: running - β”œ─────────── url: https://red-dew-jtk6yxk1.fra.unikraft.app - β”œ───────── image: httpserver-go1.21@sha256:b16d61bb7898e764d8c11ab5a0b995e8c25a25b5ff89e161fc994ebf25a75680 - β”œ───── boot time: 11.05 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: red-dew-jtk6yxk1 - β”œ── private fqdn: httpserver-go1.21-9a2wv.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /server -``` - -In this case, the instance name is `httpserver-go1.21-9a2wv` and the address is `https://red-dew-jtk6yxk1.fra.unikraft.app`. + β”œ───────── name: httpserver-go121-9a2wv + β”œ───────── uuid: 8bb34040-9434-4a28-bd1e-c24ee532e2da + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://red-dew-jtk6yxk1.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-go121@sha256:b16d61bb7898e764d8c11ab5a0b995e8c25a25b5ff89e161fc994ebf25a75680 + β”œ─────── memory: 256 MiB + β”œ────── service: red-dew-jtk6yxk1 + β”œ─ private fqdn: httpserver-go121-9a2wv.internal + β””─── private ip: 10.0.3.3 +``` + + + +In this case, the instance name is `httpserver-go121-9a2wv` and the address is `https://red-dew-jtk6yxk1.fra.unikraft.app`. They're different for each run. Use `curl` to query the Unikraft Cloud instance of the Go-based HTTP web server: @@ -96,21 +124,30 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-go1.21-9a2wv red-dew-jtk6yxk1.fra.unikraft.app running 1 minute ago httpserver-go1.21@sha256:b16d61bb7898e764d... 256 MiB 1 /server 9324us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-go121-9a2wv running /httpserver-go121 256MiB 1 red-dew-jtk6yxk1.fra.unikraft.app 2 minutes ago ``` +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-go121-9a2wv red-dew-jtk6yxk1.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-go121@sha256:... 256 MiB 1 9.32 ms +``` + + + When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-go1.21-9a2wv +unikraft instances delete httpserver-go121-9a2wv ``` ```bash title="kraft" -kraft cloud instance remove httpserver-go1.21-9a2wv +kraft cloud instance remove httpserver-go121-9a2wv ``` @@ -152,3 +189,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-g++13.2.mdx b/pages/guides/httpserver-gpp13.2.mdx similarity index 50% rename from pages/guides/httpserver-g++13.2.mdx rename to pages/guides/httpserver-gpp13.2.mdx index 0958d3d3..faad64ca 100644 --- a/pages/guides/httpserver-g++13.2.mdx +++ b/pages/guides/httpserver-gpp13.2.mdx @@ -5,17 +5,20 @@ title: "C++ HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a simple C++-based HTTP web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). -2. Clone the [example repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-g++13.2/` directory: +2. Clone the [example repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-gpp13.2/` directory: ```bash git clone https://github.com/unikraft-cloud/examples -cd examples/httpserver-g++13.2/ +cd examples/httpserver-gpp13.2/ ``` Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. @@ -41,35 +44,60 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-g++13.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-g++13.2:latest +unikraft build . --output /httpserver-gpp132:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-gpp132:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-gpp132-jzbuo +uuid: b8e015fd-d006-49d5-849e-3fd497c9159a +state: starting +image: /httpserver-gpp132 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: fd89859a-cf60-fa1f-1d43-0989a7c18b10 + name: throbbing-wave-grxjih4t + domains: + - fqdn: throbbing-wave-grxjih4t.fra.unikraft.app +networks: +- uuid: 636ebc7e-bf82-d71d-5432-5445084a4308 + private-ip: 10.0.6.5 + mac: 12:b0:0f:20:02:9d +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-g++13.2-jzbuo - β”œ────────── uuid: b8e015fd-d006-49d5-849e-3fd497c9159a - β”œ───────── state: running - β”œ─────────── url: https://throbbing-wave-grxjih4t.fra.unikraft.app - β”œ───────── image: httpserver-g++13.2@sha256:a58873987104b52c13b79168a2e2f1a81876ba6efacd6dbc98e996afe5c09699 - β”œ───── boot time: 15.61 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: throbbing-wave-grxjih4t - β”œ── private fqdn: httpserver-g++13.2-jzbuo.internal - β”œ──── private ip: 172.16.6.5 - β””────────── args: /http_server -``` - -In this case, the instance name is `httpserver-g++13.2-jzbuo` and the address is `https://throbbing-wave-grxjih4t.fra.unikraft.app`. + β”œ───────── name: httpserver-gpp132-jzbuo + β”œ───────── uuid: b8e015fd-d006-49d5-849e-3fd497c9159a + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://throbbing-wave-grxjih4t.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-gpp132@sha256:a58873987104b52c13b79168a2e2f1a81876ba6efacd6dbc98e996afe5c09699 + β”œ─────── memory: 256 MiB + β”œ────── service: throbbing-wave-grxjih4t + β”œ─ private fqdn: httpserver-gpp132-jzbuo.internal + β””─── private ip: 10.0.6.5 +``` + + + +In this case, the instance name is `httpserver-gpp132-jzbuo` and the address is `https://throbbing-wave-grxjih4t.fra.unikraft.app`. They're different for each run. Use `curl` to query the Unikraft Cloud instance of the C++ HTTP web server: @@ -96,21 +124,30 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-g++13.2-jzbuo throbbing-wave-grxjih4t.fra.unikraft.app running 1 minute ago httpserver-g++13.2@sha256:a58873987104b52c13b79168a2e2f1a81... 256 MiB 1 /http_server 15614us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-gpp132-jzbuo running /httpserver-gpp132 256MiB 1 throbbing-wave-grxjih4t.fra.unikraft.app 2 minutes ago ``` +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-gpp132-jzbuo throbbing-wave-grxjih4t.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-gpp132@sha256:... 256 MiB 1 15.61 ms +``` + + + When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-g++13.2-jzbuo +unikraft instances delete httpserver-gpp132-jzbuo ``` ```bash title="kraft" -kraft cloud instance remove httpserver-g++13.2-jzbuo +kraft cloud instance remove httpserver-gpp132-jzbuo ``` @@ -125,11 +162,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. * `runtime: base`: The Unikraft runtime kernel to use is its base one. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/http_server"]`: Use `/http_server` as the starting command of the instance. @@ -164,3 +203,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-java17-spring-petclinic.mdx b/pages/guides/httpserver-java17-spring-petclinic.mdx new file mode 100644 index 00000000..ab120fc7 --- /dev/null +++ b/pages/guides/httpserver-java17-spring-petclinic.mdx @@ -0,0 +1,171 @@ +--- +title: "Spring PetClinic" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +[Spring PetClinic](https://github.com/spring-projects/spring-petclinic) is an example project that uses Spring boot to model a simple pet clinic. + +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-java17-spring-petclinic/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/httpserver-java17-spring-petclinic/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /httpserver-java17-spring-petclinic:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 1G --image /httpserver-java17-spring-petclinic:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s --metro fra -p 443:8080/tls+http -M 1Gi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: httpserver-java17-spring-petclinic-r4s3x +uuid: 5a3b7e2c-1f4d-4a8e-b6c9-2d3f8a1e7b4c +state: starting +image: /httpserver-java17-spring-petclinic +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: f4c2b1a0-3e5d-8b7a-9c6d-1e2f3a4b5c6d + name: bitter-dust-a7b2c3d4 + domains: + - fqdn: bitter-dust-a7b2c3d4.fra.unikraft.app +networks: +- uuid: 7d6e5f4a-3b2c-1d0e-9f8a-7b6c5d4e3f2a + private-ip: 10.0.4.2 + mac: 12:b0:4a:1c:8f:73 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: httpserver-java17-spring-petclinic-r4s3x + β”œ───────── uuid: 5a3b7e2c-1f4d-4a8e-b6c9-2d3f8a1e7b4c + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://bitter-dust-a7b2c3d4.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-java17-spring-petclinic@sha256:3e9d1f8a7b2c4e5f6a3b8c2d1e4f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f + β”œ─────── memory: 1024 MiB + β”œ────── service: bitter-dust-a7b2c3d4 + β”œ─ private fqdn: httpserver-java17-spring-petclinic-r4s3x.internal + β””─── private ip: 10.0.4.2 +``` + + + +In this case, the instance name is `httpserver-java17-spring-petclinic-r4s3x` and the address is `https://bitter-dust-a7b2c3d4.fra.unikraft.app`. +They're different for each run. + +After deploying, point your browser to the provided URL. + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-java17-spring-petclinic-r4s3x running /httpserver-java17-spring-petclinic 1024MiB 1 bitter-dust-a7b2c3d4.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-java17-spring-petclinic-r4s3x bitter-dust-a7b2c3d4.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-java17-spring-petclinic@sha256:... 1.0 GiB 1 521.43 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + + +## Learn more + +- [Spring Boot Reference](https://docs.spring.io/spring-boot/docs/current/reference/html/) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) +- [Building `Dockerfile` Images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-java17-springboot3.2.x.mdx b/pages/guides/httpserver-java17-springboot3.5.x.mdx similarity index 50% rename from pages/guides/httpserver-java17-springboot3.2.x.mdx rename to pages/guides/httpserver-java17-springboot3.5.x.mdx index 683438ac..54f384ff 100644 --- a/pages/guides/httpserver-java17-springboot3.2.x.mdx +++ b/pages/guides/httpserver-java17-springboot3.5.x.mdx @@ -5,17 +5,20 @@ title: "Spring Boot HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a Spring Boot web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). -2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-java17-springboot3.2.x/` directory: +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-java17-springboot3.5.x/` directory: ```bash git clone https://github.com/unikraft-cloud/examples -cd examples/httpserver-java17-springboot3.2.x/ +cd examples/httpserver-java17-springboot3.5.x/ ``` Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. @@ -41,35 +44,60 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-java17-springboot3.2.x:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 1G --image=/httpserver-java17-springboot3.2.x:latest +unikraft build . --output /httpserver-java17-springboot35x:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 1G --image /httpserver-java17-springboot35x:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 1G . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 1Gi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-java17-springboot35x-qseeo +uuid: b081166d-a2a0-43af-982d-1aa17f06b5c4 +state: starting +image: /httpserver-java17-springboot35x +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: 04f5b3ce-0aae-a50a-9d58-e6fa618b2cdc + name: long-dust-si7xsngk + domains: + - fqdn: long-dust-si7xsngk.fra.unikraft.app +networks: +- uuid: 4bde3abf-faf8-3a14-ceb9-bc05e646dfac + private-ip: 10.0.6.2 + mac: 12:b0:eb:ad:60:a2 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-java17-springboot32x-qseeo - β”œ────────── uuid: b081166d-a2a0-43af-982d-1aa17f06b5c4 - β”œ───────── state: running - β”œ─────────── url: https://long-dust-si7xsngk.fra.unikraft.app - β”œ───────── image: httpserver-java17-springboot32x@sha256:cc2f2ad18ce8e36b8e8f4debee096fef7b0bb8b47762575a2ba5a9de8199c64a - β”œ───── boot time: 153.97 ms - β”œ──────── memory: 1024 MiB - β”œ─────── service: long-dust-si7xsngk - β”œ── private fqdn: httpserver-java17-springboot32x-qseeo.internal - β”œ──── private ip: 172.16.6.2 - β””────────── args: /usr/lib/jvm/java-17-openjdk-amd64/bin/java -jar /usr/src/demo-0.0.1-SNAPSHOT.jar -``` - -In this case, the instance name is `httpserver-java17-springboot32x-qseeo` and the address is `https://long-dust-si7xsngk.fra.unikraft.app`. + β”œ───────── name: httpserver-java17-springboot35x-qseeo + β”œ───────── uuid: b081166d-a2a0-43af-982d-1aa17f06b5c4 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://long-dust-si7xsngk.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-java17-springboot35x@sha256:cc2f2ad18ce8e36b8e8f4debee096fef7b0bb8b47762575a2ba5a9de8199c64a + β”œ─────── memory: 1024 MiB + β”œ────── service: long-dust-si7xsngk + β”œ─ private fqdn: httpserver-java17-springboot35x-qseeo.internal + β””─── private ip: 10.0.6.2 +``` + + + +In this case, the instance name is `httpserver-java17-springboot35x-qseeo` and the address is `https://long-dust-si7xsngk.fra.unikraft.app`. They're different for each run. Use `curl` to query the Spring Boot server's `hello` endpoint: @@ -87,11 +115,11 @@ When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-java17-springboot32x-qseeo +unikraft instances delete httpserver-java17-springboot35x-qseeo ``` ```bash title="kraft" -kraft cloud instance remove httpserver-java17-springboot32x-qseeo +kraft cloud instance remove httpserver-java17-springboot35x-qseeo ``` @@ -106,11 +134,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. -* `runtime: java:17`: The Unikraft runtime kernel to use is Java. +* `runtime: base-compat:latest`: The runtime kernel to use is the base compatibility kernel. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/lib/jvm/java-17-openjdk-amd64/bin/java", "-jar", "/usr/src/demo-0.0.1-SNAPSHOT.jar"]`: Use as the starting command of the instance. @@ -142,16 +172,30 @@ kraft cloud instance list + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-java17-springboot35x-qseeo running /httpserver-java17-springboot35x 1024MiB 1 long-dust-si7xsngk.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-java17-springboot35x-qseeo long-dust-si7xsngk.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-java17-springboot35x@sha256:... 1.0 GiB 1 421.30 ms +``` + + + When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-java17-springboot32x-qseeo +unikraft instances delete httpserver-java17-springboot35x-qseeo ``` ```bash title="kraft" -kraft cloud instance remove httpserver-java17-springboot32x-qseeo +kraft cloud instance remove httpserver-java17-springboot35x-qseeo ``` @@ -174,3 +218,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-java21.mdx b/pages/guides/httpserver-java21.mdx index a88b7cd3..63cc4738 100644 --- a/pages/guides/httpserver-java21.mdx +++ b/pages/guides/httpserver-java21.mdx @@ -5,12 +5,15 @@ title: "Java HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This is a simple HTTP server written in the [Java](https://www.java.com/en/) programming language. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-java21` directory: @@ -43,32 +46,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-java21:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 1G --image=/httpserver-java21:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 1G --image /httpserver-java21:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 1G . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 1Gi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-java21-5xw9m +uuid: b2c3d4e5-f6a7-8901-bcde-f12345678901 +state: starting +image: /httpserver-java21 +resources: + memory: 1GiB + vcpus: 1 +service: + uuid: 9d96e042-1601-352b-10c7-4a8c7ececbcb + name: gentle-wind-b2x9pkqm + domains: + - fqdn: gentle-wind-b2x9pkqm.fra.unikraft.app +networks: +- uuid: 25185154-a4d5-0da1-e28f-3b3e42190b56 + private-ip: 10.0.3.5 + mac: 12:b0:29:0f:68:f3 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-java21-5xw9m - β”œ────────── uuid: b2c3d4e5-f6a7-8901-bcde-f12345678901 - β”œ───────── state: starting - β”œ──────── domain: https://gentle-wind-b2x9pkqm.fra.unikraft.app - β”œ───────── image: httpserver-java21@sha256:4f8a2c6e1d9b3f7a5c0e2b4d8f6a1c3e7b9d2f4a6c8e0b2d4f6a8c0e2b4d6f - β”œ──────── memory: 1 GiB - β”œ─────── service: gentle-wind-b2x9pkqm - β”œ── private fqdn: httpserver-java21-5xw9m.internal - β”œ──── private ip: 172.16.3.5 - β””────────── args: /usr/lib/jvm/java-21-openjdk-amd64/bin/java -classpath /usr/src/ SimpleHttpServer + β”œ───────── name: httpserver-java21-5xw9m + β”œ───────── uuid: b2c3d4e5-f6a7-8901-bcde-f12345678901 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://gentle-wind-b2x9pkqm.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-java21@sha256:4f8a2c6e1d9b3f7a5c0e2b4d8f6a1c3e7b9d2f4a6c8e0b2d4f6a8c0e2b4d6f + β”œ─────── memory: 1 GiB + β”œ────── service: gentle-wind-b2x9pkqm + β”œ─ private fqdn: httpserver-java21-5xw9m.internal + β””─── private ip: 10.0.3.5 ``` + + In this case, the instance name is `httpserver-java21-5xw9m` and the address is `https://gentle-wind-b2x9pkqm.fra.unikraft.app`. They're different for each run. @@ -96,11 +125,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-java21-5xw9m gentle-wind-b2x9pkqm.fra.unik... running since 3mins httpserver-java21@sha256:4f8a2c6e... 1 GiB 1 /usr/lib/jvm/java-21-openjdk-amd64/bin/java -cla... 421.30 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-java21-5xw9m running /httpserver-java21 1GiB 1 gentle-wind-b2x9pkqm.fra.unik... 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-java21-5xw9m gentle-wind-b2x9pkqm.fra.unik... running since 3mins oci://unikraft.io//httpserver-java21@sha256:... 1 GiB 1 421.30 ms ``` + + When done, you can remove the instance: @@ -125,11 +163,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. * `runtime: base-compat:latest`: The kernel to use. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/lib/jvm/java-21-openjdk-amd64/bin/java", "-classpath", "/usr/src/", "SimpleHttpServer"]`: Use the Java runtime to run `SimpleHttpServer` as the starting command of the instance. @@ -177,3 +217,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-lua5.1.mdx b/pages/guides/httpserver-lua5.1.mdx index 3ebb4bd8..97938d8e 100644 --- a/pages/guides/httpserver-lua5.1.mdx +++ b/pages/guides/httpserver-lua5.1.mdx @@ -5,11 +5,14 @@ title: "Lua HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a simple Lua-based HTTP web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-lua5.1/` directory: @@ -41,34 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-lua5.1:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-lua5.1:latest +unikraft build . --output /httpserver-lua51:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-lua51:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-lua51-ma2i9 +uuid: e7389eee-9808-4152-b2ec-1f3c0541fd05 +state: starting +image: /httpserver-lua51 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: 51a41f63-7e88-c443-b9bf-83cd7c04d975 + name: young-night-5fpf0jj8 + domains: + - fqdn: young-night-5fpf0jj8.fra.unikraft.app +networks: +- uuid: afcc149e-cd07-a4b6-905a-6d498e251e14 + private-ip: 10.0.3.3 + mac: 12:b0:fe:e4:63:48 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-lua51-ma2i9 - β”œ────────── uuid: e7389eee-9808-4152-b2ec-1f3c0541fd05 - β”œ───────── state: running - β”œ─────────── url: https://young-night-5fpf0jj8.fra.unikraft.app - β”œ───────── image: httpserver-lua51@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472 - β”œ───── boot time: 15.09 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: young-night-5fpf0jj8 - β”œ── private fqdn: httpserver-lua51-ma2i9.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/lua /http_server.lua + β”œ───────── name: httpserver-lua51-ma2i9 + β”œ───────── uuid: e7389eee-9808-4152-b2ec-1f3c0541fd05 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://young-night-5fpf0jj8.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-lua51@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472 + β”œ─────── memory: 256 MiB + β”œ────── service: young-night-5fpf0jj8 + β”œ─ private fqdn: httpserver-lua51-ma2i9.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `httpserver-lua51-ma2i9` and the address is `https://young-night-5fpf0jj8.fra.unikraft.app`. They're different for each run. @@ -96,11 +124,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-lua51-ma2i9 young-night-5fpf0jj8.fra.unikraft.app running 1 minute ago httpserver-lua51@sha256:278cb8b14f9f... 256 MiB 1 /usr/bin/lua /http_server.lua 15094us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-lua51-ma2i9 running /httpserver-lua51 256MiB 1 young-night-5fpf0jj8.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-lua51-ma2i9 young-night-5fpf0jj8.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-lua51@sha256:... 256 MiB 1 15.09 ms ``` + + When done, you can remove the instance: @@ -148,3 +185,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-nginx-vite-vanilla.mdx b/pages/guides/httpserver-nginx-vite-vanilla.mdx index 2bcc4a15..2cf4df03 100644 --- a/pages/guides/httpserver-nginx-vite-vanilla.mdx +++ b/pages/guides/httpserver-nginx-vite-vanilla.mdx @@ -5,14 +5,17 @@ title: "Vite HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example demonstrates how to run a [Vite](https://vite.dev) project targeting production on Unikraft Cloud. The deployment doesn't perform any server-side rendering and instead serves the resulting artifacts statically (via `npm run build`) using [`nginx`](https://github.com/unikraft-cloud/examples/nginx). To use Vite in server-side rendering (SSR) mode or via the `dev` subcommand on a NodeJS runtime, please see the [`httpserver-node-vite-vanilla`](https://github.com/unikraft-cloud/examples/httpserver-node-vite-vanilla) sibling project. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-nginx-vite-vanilla` directory: @@ -45,32 +48,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-nginx-vite-vanilla:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-nginx-vite-vanilla:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-nginx-vite-vanilla:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-nginx-vite-vanilla-2rk6p +uuid: d4e5f6a7-b8c9-0123-defa-234567890123 +state: starting +image: /httpserver-nginx-vite-vanilla +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: ed42569f-a592-20e1-f506-7cb1bc1c84d6 + name: swift-lake-m4n8vqzp + domains: + - fqdn: swift-lake-m4n8vqzp.fra.unikraft.app +networks: +- uuid: d05bbdcf-8a0f-b8fe-0d9f-976c4c973701 + private-ip: 10.0.3.7 + mac: 12:b0:1a:5c:59:a9 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-nginx-vite-vanilla-2rk6p - β”œ────────── uuid: d4e5f6a7-b8c9-0123-defa-234567890123 - β”œ───────── state: starting - β”œ──────── domain: https://swift-lake-m4n8vqzp.fra.unikraft.app - β”œ───────── image: httpserver-nginx-vite-vanilla@sha256:9c5f2d8b4e7a1c3f6d9b2e5a8c1f4d7a0b3e6c9f2d5a8b1e4c7f0d3a6b9c2 - β”œ──────── memory: 256 MiB - β”œ─────── service: swift-lake-m4n8vqzp - β”œ── private fqdn: httpserver-nginx-vite-vanilla-2rk6p.internal - β”œ──── private ip: 172.16.3.7 - β””────────── args: /usr/bin/nginx -c /etc/nginx/nginx.conf + β”œ───────── name: httpserver-nginx-vite-vanilla-2rk6p + β”œ───────── uuid: d4e5f6a7-b8c9-0123-defa-234567890123 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://swift-lake-m4n8vqzp.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-nginx-vite-vanilla@sha256:9c5f2d8b4e7a1c3f6d9b2e5a8c1f4d7a0b3e6c9f2d5a8b1e4c7f0d3a6b9c2 + β”œ─────── memory: 256 MiB + β”œ────── service: swift-lake-m4n8vqzp + β”œ─ private fqdn: httpserver-nginx-vite-vanilla-2rk6p.internal + β””─── private ip: 10.0.3.7 ``` + + In this case, the instance name is `httpserver-nginx-vite-vanilla-2rk6p` and the address is `https://swift-lake-m4n8vqzp.fra.unikraft.app`. They're different for each run. @@ -108,11 +137,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-nginx-vite-vanilla-2rk6p swift-lake-m4n8vqzp.fra.unikraft.app running since 3mins httpserver-nginx-vite-vanilla@sha256:9c5... 256 MiB 1 /usr/bin/nginx -c /etc/nginx/nginx.conf 198.62 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-nginx-vite-vanilla-2rk6p running /httpserver-nginx-vite-vanilla 256MiB 1 swift-lake-m4n8vqzp.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-nginx-vite-vanilla-2rk6p swift-lake-m4n8vqzp.fra.unikraft.app running since 3mins oci://unikraft.io//httpserver-nginx-vite-vanilla@sha256:... 256 MiB 1 198.62 ms ``` + + When done, you can remove the instance: @@ -137,11 +175,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. -* `runtime: nginx:latest`: The nginx kernel to use. +* `runtime: base-compat:latest`: The runtime kernel to use is the base compatibility kernel. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/nginx", "-c", "/etc/nginx/nginx.conf"]`: Use nginx to serve the built static files as the starting command of the instance. @@ -186,3 +226,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-node-express-puppeteer.mdx b/pages/guides/httpserver-node-express-puppeteer.mdx index af18cbc4..c0854864 100644 --- a/pages/guides/httpserver-node-express-puppeteer.mdx +++ b/pages/guides/httpserver-node-express-puppeteer.mdx @@ -5,12 +5,15 @@ title: "Puppeteer HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows you how to use [Puppeteer](https://pptr.dev/), a Node.js library which provides a high-level API to control browsers, including the option to run them headless (no UI). To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node-express-puppeteer/` directory: @@ -50,32 +53,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node-express-puppeteer:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 4G --image=/httpserver-node-express-puppeteer:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 443:3000/tls+http -m 4G --image /httpserver-node-express-puppeteer:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 4G . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 4Gi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-node-express-puppeteer-7afg3 +uuid: 7bb479d7-5b3e-444f-b07c-eae4da6f57cc +state: starting +image: /httpserver-node-express-puppeteer +resources: + memory: 4096MiB + vcpus: 1 +service: + uuid: 996b9cc1-5a51-e707-d443-5c98ea86ded8 + name: little-snow-7qwu6vv5 + domains: + - fqdn: little-snow-7qwu6vv5.fra.unikraft.app +networks: +- uuid: 034fa25e-9154-7842-ccdd-289256cc7a17 + private-ip: 10.0.3.1 + mac: 12:b0:8f:3c:f5:16 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-node-express-puppeteer-7afg3 - β”œ────────── uuid: 7bb479d7-5b3e-444f-b07c-eae4da6f57cc - β”œ───────── state: starting - β”œ──────── domain: https://nameless-fog-0tvh1uov.fra.unikraft.app - β”œ───────── image: httpserver-node-express-puppeteer@sha256:78d0b180161c876f17d05116b93011ddcd44c76758d6fa0359f05938e67cea65 - β”œ──────── memory: 4096 MiB - β”œ─────── service: little-snow-7qwu6vv5 - β”œ── private fqdn: httpserver-node-express-puppeteer-7afg3.internal - β”œ──── private ip: 172.16.3.1 - β””────────── args: /usr/bin/wrapper.sh /usr/bin/node /app/bin/www + β”œ───────── name: httpserver-node-express-puppeteer-7afg3 + β”œ───────── uuid: 7bb479d7-5b3e-444f-b07c-eae4da6f57cc + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://nameless-fog-0tvh1uov.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-node-express-puppeteer@sha256:78d0b180161c876f17d05116b93011ddcd44c76758d6fa0359f05938e67cea65 + β”œ─────── memory: 4096 MiB + β”œ────── service: little-snow-7qwu6vv5 + β”œ─ private fqdn: httpserver-node-express-puppeteer-7afg3.internal + β””─── private ip: 10.0.3.1 ``` + + In this case, the instance name is `httpserver-node-express-puppeteer-7afg3`. They're different for each run. @@ -87,15 +116,32 @@ You can use the landing page to generate the PDF version of a remote page. You can list information about the instance by running: -```bash -kraft cloud instance list httpserver-node-express-puppeteer-7afg3 + + +```bash title="unikraft" +unikraft instances list ``` -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-node-express-puppeteer-7afg3 nameless-fog-0tvh1uov.fra.unikraft.app running since 6mins httpserver-node-express-puppeteer@s... 4.0 GiB 1 /usr/bin/wrapper.sh /usr/bin/n... 15.27 ms +```bash title="kraft" +kraft cloud instance list ``` + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-node-express-puppeteer-7afg3 running /httpserver-node-express-puppeteer 4096MiB 1 nameless-fog-0tvh1uov.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-node-express-puppeteer-7afg3 nameless-fog-0tvh1uov.fra.unikraft.app running since 6mins oci://unikraft.io//httpserver-node-express-puppeteer@s... 4.0 GiB 1 15.27 ms +``` + + + When done, you can remove the instance: @@ -124,4 +170,5 @@ Use the `--help` option for detailed information on using Unikraft Cloud: kraft cloud --help ``` -Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +Or visit the [CLI Reference](/cli/overview) or the [legacy CLI Reference](/cli/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-node-vite-ssr-vanilla.mdx b/pages/guides/httpserver-node-vite-ssr-vanilla.mdx new file mode 100644 index 00000000..2004b357 --- /dev/null +++ b/pages/guides/httpserver-node-vite-ssr-vanilla.mdx @@ -0,0 +1,191 @@ +--- +title: "Vite (vanilla) SSR" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +This example demonstrates how to run [Vite](https://vite.dev) with [server-side +rendering (SSR)](https://vite.dev/guide/ssr.html). + + +## Initialization + +The project was instantiated via: + +``` +npm create vite-extra@latest node-vite-ssr-vanilla -- --template ssr-vanilla +``` + +The accompanying `Dockerfile` and `Kraftfile` are +necessary for deploying to Unikraft Cloud. + + +## Deployment + +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node-vite-ssr-vanilla/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/httpserver-node-vite-ssr-vanilla/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, run: + + + +```bash title="unikraft" +unikraft build . --output /httpserver-node-vite-ssr-vanilla:latest +unikraft run --scale-to-zero policy=on,cooldown-time=2000,stateful=true --metro fra -p 443:8080/tls+http -m 1G -e PWD=/app -e NODE_ENV=production --image /httpserver-node-vite-ssr-vanilla:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 2s -p 443:8080/tls+http -M 1Gi -e PWD=/app -e NODE_ENV=production . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: httpserver-node-vite-ssr-vanilla-k8x2m +uuid: 1a2b3c4d-5e6f-7a8b-9c0d-a1b2c3d4e5f6 +state: starting +image: /httpserver-node-vite-ssr-vanilla +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: 2b3c4d5e-6f7a-8b9c-0d1e-b2c3d4e5f6a7 + name: warm-sky-qp3mn4rs + domains: + - fqdn: warm-sky-qp3mn4rs.fra.unikraft.app +networks: +- uuid: 3c4d5e6f-7a8b-9c0d-1e2f-c3d4e5f6a7b8 + private-ip: 10.0.3.4 + mac: 12:b0:5b:2d:9a:84 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: httpserver-node-vite-ssr-vanilla-k8x2m + β”œ───────── uuid: 1a2b3c4d-5e6f-7a8b-9c0d-a1b2c3d4e5f6 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://warm-sky-qp3mn4rs.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-node-vite-ssr-vanilla@sha256:4f8a2c6e1b3d5f7a9c0e2b4d6f8a0c2e4b6d8f0a2c4e6b8d0f2a4c6e8b0d2f4a + β”œ─────── memory: 1024 MiB + β”œ────── service: warm-sky-qp3mn4rs + β”œ─ private fqdn: httpserver-node-vite-ssr-vanilla-k8x2m.internal + β””─── private ip: 10.0.3.4 +``` + + + +In this case, the instance name is `httpserver-node-vite-ssr-vanilla-k8x2m` and the address is `https://warm-sky-qp3mn4rs.fra.unikraft.app`. +They're different for each run. + +After deploying, you can query the service using the provided URL. + + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-node-vite-ssr-vanilla-k8x2m running /httpserver-node-vite-ssr-vanilla 1024MiB 1 warm-sky-qp3mn4rs.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-node-vite-ssr-vanilla-k8x2m warm-sky-qp3mn4rs.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-node-vite-ssr-vanilla@sha256:... 1.0 GiB 1 89.34 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + + +## Learn more + +- [NGINX's Documentation](https://nginx.org/en/docs) +- [Vite's Documentation](https://vite.dev/guide/) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs) +- [Building `Dockerfile` images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) +- [Vite (vanilla) node "dev" server on Unikraft Cloud](../httpserver-node-vite-vanilla) +- [Vite (vanilla) static build on Unikraft Cloud](../httpserver-nginx-vite-vanilla) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-node-vite-vanilla.mdx b/pages/guides/httpserver-node-vite-vanilla.mdx new file mode 100644 index 00000000..befdd254 --- /dev/null +++ b/pages/guides/httpserver-node-vite-vanilla.mdx @@ -0,0 +1,195 @@ +--- +title: "Vite (vanilla)" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +This example demonstrates how to run a [Vite](https://vite.dev) project which +executes via the `vite` program on top of the `node` runtime. + +> [!NOTE] +> This is **not** the most efficient way to run a Vite project! See +> [`httpserver-nginx-vite-vanilla`](../httpserver-nginx-vite-vanilla/) for more details. + + +## Initialization + +The project was instantiated via: + +``` +npm create vite@latest my-vue-app -- --template vanilla +``` + +The accompanying `Dockerfile` and `Kraftfile` are +necessary for deploying to Unikraft Cloud. + + +## Deployment + +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node-vite-vanilla/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/httpserver-node-vite-vanilla/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, run: + + + +```bash title="unikraft" +unikraft build . --output /httpserver-node-vite-vanilla:latest +unikraft run --scale-to-zero policy=on,cooldown-time=2000,stateful=true --metro fra -p 443:8080/tls+http -m 4G -e PWD=/app --image /httpserver-node-vite-vanilla:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 2s -p 443:8080/tls+http -M 4Gi -e PWD=/app . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: httpserver-node-vite-vanilla-w9f3p +uuid: 4d5e6f7a-8b9c-0d1e-2f3a-d4e5f6a7b8c9 +state: starting +image: /httpserver-node-vite-vanilla +resources: + memory: 4096MiB + vcpus: 1 +service: + uuid: 5e6f7a8b-9c0d-1e2f-3a4b-e5f6a7b8c9d0 + name: bold-rain-mv5tx8wy + domains: + - fqdn: bold-rain-mv5tx8wy.fra.unikraft.app +networks: +- uuid: 6f7a8b9c-0d1e-2f3a-4b5c-f6a7b8c9d0e1 + private-ip: 10.0.5.2 + mac: 12:b0:6c:3e:ab:95 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: httpserver-node-vite-vanilla-w9f3p + β”œ───────── uuid: 4d5e6f7a-8b9c-0d1e-2f3a-d4e5f6a7b8c9 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://bold-rain-mv5tx8wy.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-node-vite-vanilla@sha256:5a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b + β”œ─────── memory: 4096 MiB + β”œ────── service: bold-rain-mv5tx8wy + β”œ─ private fqdn: httpserver-node-vite-vanilla-w9f3p.internal + β””─── private ip: 10.0.5.2 +``` + + + +In this case, the instance name is `httpserver-node-vite-vanilla-w9f3p` and the address is `https://bold-rain-mv5tx8wy.fra.unikraft.app`. +They're different for each run. + +After deploying, you can query the service using the provided URL. + + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-node-vite-vanilla-w9f3p running /httpserver-node-vite-vanilla 4096MiB 1 bold-rain-mv5tx8wy.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-node-vite-vanilla-w9f3p bold-rain-mv5tx8wy.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-node-vite-vanilla@sha256:... 4 GiB 1 91.27 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + + +## Learn more + +- [NGINX's Documentation](https://nginx.org/en/docs) +- [Vite's Documentation](https://vite.dev/guide/) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs) +- [Building `Dockerfile` images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) +- [Vite (vanilla) static build on Unikraft Cloud](../httpserver-nginx-vite-vanilla) +- [Vite (vanilla) SSR mode on Unikraft Cloud](../httpserver-node-vite-ssr-vanilla) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-node21-nextjs.mdx b/pages/guides/httpserver-node21-nextjs.mdx index 6dcfefa0..b613040b 100644 --- a/pages/guides/httpserver-node21-nextjs.mdx +++ b/pages/guides/httpserver-node21-nextjs.mdx @@ -5,11 +5,14 @@ title: "Next.js HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a Next.js app. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node21-nextjs` directory: @@ -42,33 +45,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node21-nextjs:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 768M --image=/httpserver-node21-nextjs:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:3000/tls+http -m 768M --image /httpserver-node21-nextjs:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 768M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 768Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-node21-nextjs-bfrq0 +uuid: 2adf9664-c4ae-4e0e-99de-c9781282b370 +state: starting +image: /httpserver-node21-nextjs +resources: + memory: 768MiB + vcpus: 1 +service: + uuid: 43e93d04-615b-0d81-07af-8506c25b1802 + name: small-frog-ri8c1vtw + domains: + - fqdn: small-frog-ri8c1vtw.fra.unikraft.app +networks: +- uuid: e6e3adf9-8512-b678-4dae-6bbf2f4aad17 + private-ip: 10.0.28.2 + mac: 12:b0:2a:aa:d4:82 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-node21-nextjs-bfrq0 - β”œ────────── uuid: 2adf9664-c4ae-4e0e-99de-c9781282b370 - β”œ───────── state: running - β”œ─────────── url: https://small-frog-ri8c1vtw.fra.unikraft.app - β”œ───────── image: httpserver-node21-nextjs@sha256:ea5b2f145eea9762431ebdea933dd1dfb8427fe23306d2bd7966dd502d6c88f6 - β”œ───── boot time: 83.60 ms - β”œ──────── memory: 768 MiB - β”œ─────── service: small-frog-ri8c1vtw - β”œ── private fqdn: httpserver-node21-nextjs-bfrq0.internal - β”œ──── private ip: 172.16.28.2 - β””────────── args: /usr/bin/node /usr/src/server.js + β”œ───────── name: httpserver-node21-nextjs-bfrq0 + β”œ───────── uuid: 2adf9664-c4ae-4e0e-99de-c9781282b370 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://small-frog-ri8c1vtw.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-node21-nextjs@sha256:ea5b2f145eea9762431ebdea933dd1dfb8427fe23306d2bd7966dd502d6c88f6 + β”œ─────── memory: 768 MiB + β”œ────── service: small-frog-ri8c1vtw + β”œ─ private fqdn: httpserver-node21-nextjs-bfrq0.internal + β””─── private ip: 10.0.28.2 ``` + + In this case, the instance name is `httpserver-node21-nextjs-bfrq0` and the address is `https://small-frog-ri8c1vtw.fra.unikraft.app`. They're different for each run. @@ -98,11 +126,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-node21-nextjs-bfrq0 small-frog-ri8c1vtw.fra.unikraft.app running 1 minute ago httpserver-node21-nextjs@sha256... 768 MiB 1 /usr/bin/node /usr/src/server.js 83600us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-node21-nextjs-bfrq0 running /httpserver-node21-nextjs@sha256 768MiB 1 small-frog-ri8c1vtw.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-node21-nextjs-bfrq0 small-frog-ri8c1vtw.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-node21-nextjs@sha256... 768 MiB 1 83.60 ms ``` + + When done, you can remove the instance: @@ -126,11 +163,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. -* `runtime: node:21`: The Unikraft runtime kernel to use is Node 21. +* `runtime: base-compat:latest`: The runtime kernel to use is the base compatibility kernel. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: [["/usr/bin/node", "/usr/src/server.js"]]`: Use `/usr/bin/node /usr/src/server.js` as the starting command of the instance. @@ -168,12 +207,12 @@ Run the command below to deploy the app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-expressjs4.18-node21:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 256M --image=/httpserver-expressjs4.18-node21:latest +unikraft build . --output /httpserver-expressjs418-node21:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:3000/tls+http -m 256M --image /httpserver-expressjs418-node21:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 256Mi . ``` @@ -239,3 +278,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-node21-remix.mdx b/pages/guides/httpserver-node21-remix.mdx index e0a144c3..923d4426 100644 --- a/pages/guides/httpserver-node21-remix.mdx +++ b/pages/guides/httpserver-node21-remix.mdx @@ -5,12 +5,15 @@ title: "Remix HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows how to deploy a [Remix](https://remix.run/) app. To do so, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node21-remix/` directory: @@ -43,33 +46,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node21-remix:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 768M --image=/httpserver-node21-remix:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:3000/tls+http -m 768M --image /httpserver-node21-remix:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 768M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 768Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-node21-remix-jvj6b +uuid: 4e6ccb1f-0533-4dc1-be67-eca8dfc1f8c6 +state: starting +image: /httpserver-node21-remix +resources: + memory: 768MiB + vcpus: 1 +service: + uuid: 46865b94-fd59-7d38-485d-c110a41b0949 + name: long-star-1tms9h1z + domains: + - fqdn: long-star-1tms9h1z.fra.unikraft.app +networks: +- uuid: 270bdb2f-42a2-f26d-4a8c-43de55608490 + private-ip: 10.0.6.8 + mac: 12:b0:00:61:6e:70 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-node21-remix-jvj6b - β”œ────────── uuid: 4e6ccb1f-0533-4dc1-be67-eca8dfc1f8c6 - β”œ───────── state: running - β”œ─────────── url: https://long-star-1tms9h1z.fra.unikraft.app - β”œ───────── image: httpserver-node21-remix@sha256:300eefce3de136ad9c782f010b69da01100ae5f0ca17f038f92321d735d6675f - β”œ───── boot time: 153.47 ms - β”œ──────── memory: 768 MiB - β”œ─────── service: long-star-1tms9h1z - β”œ── private fqdn: httpserver-node21-remix-jvj6b.internal - β”œ──── private ip: 172.16.6.8 - β””────────── args: /usr/bin/node /usr/src/server.js + β”œ───────── name: httpserver-node21-remix-jvj6b + β”œ───────── uuid: 4e6ccb1f-0533-4dc1-be67-eca8dfc1f8c6 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://long-star-1tms9h1z.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-node21-remix@sha256:300eefce3de136ad9c782f010b69da01100ae5f0ca17f038f92321d735d6675f + β”œ─────── memory: 768 MiB + β”œ────── service: long-star-1tms9h1z + β”œ─ private fqdn: httpserver-node21-remix-jvj6b.internal + β””─── private ip: 10.0.6.8 ``` + + In this case, the instance name is `httpserver-node21-remix-jvj6b` and the address is `https://long-star-1tms9h1z.fra.unikraft.app`. They're different for each run. You can now point your browser at the address to see your deployed instance. @@ -88,11 +116,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-node21-remix-jvj6b long-star-1tms9h1z.fra.unikraft.app running 1 minutes ago httpserver-node21-remix@sha256... 768 MiB 1 /usr/bin/node /usr/src/server... 67.65 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-node21-remix-jvj6b running /httpserver-node21-remix 768MiB 1 long-star-1tms9h1z.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-node21-remix-jvj6b long-star-1tms9h1z.fra.unikraft.app running 1 minutes ago oci://unikraft.io//httpserver-node21-remix@sha256... 768 MiB 1 67.65 ms ``` + + When done, you can remove the instance: @@ -132,3 +169,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-node21-solid-start.mdx b/pages/guides/httpserver-node21-solid-start.mdx index 519daa9e..b74b0f7f 100644 --- a/pages/guides/httpserver-node21-solid-start.mdx +++ b/pages/guides/httpserver-node21-solid-start.mdx @@ -5,11 +5,14 @@ title: "SolidJS HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows how to deploy a [Solid Start](https://start.solidjs.com) app. To do so, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node21-solid-start/` directory: @@ -42,33 +45,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node21-solid-start:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 512M --image=/httpserver-node21-solid-start:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:3000/tls+http -m 512M --image /httpserver-node21-solid-start:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-node21-solid-start-lvoa2 +uuid: 4e6ccb1f-0533-4dc1-be67-eca8dfc1f8c6 +state: starting +image: /httpserver-node21-solid-start +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 46865b94-fd59-7d38-485d-c110a41b0949 + name: long-star-1tms9h1z + domains: + - fqdn: long-star-1tms9h1z.fra.unikraft.app +networks: +- uuid: 1b8eccba-a635-e4db-3a3f-162fbe1f692f + private-ip: 10.0.6.8 + mac: 12:b0:8e:29:47:83 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-node21-solid-start-lvoa2 - β”œ────────── uuid: 4e6ccb1f-0533-4dc1-be67-eca8dfc1f8c6 - β”œ───────── state: running - β”œ─────────── url: https://long-star-1tms9h1z.fra.unikraft.app - β”œ───────── image: httpserver-node21-solid-start@sha256:eb2e79b2fc5c28bb43923a1fc4931db94ebc3f939a6fbe00d06189c0ae2e02fd - β”œ───── boot time: 67.65 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: long-star-1tms9h1z - β”œ── private fqdn: httpserver-node21-solid-start-lvoa2.internal - β”œ──── private ip: 172.16.6.8 - β””────────── args: /usr/bin/node /usr/src/server/index.mjs + β”œ───────── name: httpserver-node21-solid-start-lvoa2 + β”œ───────── uuid: 4e6ccb1f-0533-4dc1-be67-eca8dfc1f8c6 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://long-star-1tms9h1z.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-node21-solid-start@sha256:eb2e79b2fc5c28bb43923a1fc4931db94ebc3f939a6fbe00d06189c0ae2e02fd + β”œ─────── memory: 512 MiB + β”œ────── service: long-star-1tms9h1z + β”œ─ private fqdn: httpserver-node21-solid-start-lvoa2.internal + β””─── private ip: 10.0.6.8 ``` + + In this case, the instance name is `httpserver-node21-solid-start-lvoa2` and the address is `https://long-star-1tms9h1z.fra.unikraft.app`. They're different for each run. You can now point your browser at the address to see your deployed instance. @@ -87,11 +115,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-node21-solid-start-lvoa2 long-star-1tms9h1z.fra.unikraft.app running 1 minutes ago httpserver-node21-solid-start@sha256... 512 MiB 1 /usr/bin/node /usr/src/server... 67.65 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-node21-solid-start-lvoa2 running /httpserver-node21-solid-start 512MiB 1 long-star-1tms9h1z.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-node21-solid-start-lvoa2 long-star-1tms9h1z.fra.unikraft.app running 1 minutes ago oci://unikraft.io//httpserver-node21-solid-start@sha256... 512 MiB 1 67.65 ms ``` + + When done, you can remove the instance: @@ -131,3 +168,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-node21-sveltekit.mdx b/pages/guides/httpserver-node21-sveltekit.mdx index 22698185..e4d59843 100644 --- a/pages/guides/httpserver-node21-sveltekit.mdx +++ b/pages/guides/httpserver-node21-sveltekit.mdx @@ -5,13 +5,16 @@ title: "SvelteKit HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a [SvelteKit](https://kit.svelte.dev/) app. [SvelteKit](https://kit.svelte.dev/) builds on Svelte, a UI framework that uses a compiler to let you write breathtakingly concise components that do minimal work in the browser. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node21-sveltekit/` directory: @@ -44,33 +47,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node21-sveltekit:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 256M --image=/httpserver-node21-sveltekit:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:3000/tls+http -m 512M --image /httpserver-node21-sveltekit:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-node21-sveltekit-zmt39 +uuid: cd5071b0-5605-4771-b75d-4789393e60de +state: starting +image: /httpserver-node21-sveltekit +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 2cd097b5-795c-7184-2968-1508c630fb2b + name: dark-fog-z18n0ej1 + domains: + - fqdn: dark-fog-z18n0ej1.fra.unikraft.app +networks: +- uuid: e715723d-4659-2006-bd7b-68a5a3c33cce + private-ip: 10.0.3.3 + mac: 12:b0:a0:31:90:5a +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-node21-sveltekit-zmt39 - β”œ────────── uuid: cd5071b0-5605-4771-b75d-4789393e60de - β”œ───────── state: running - β”œ─────────── url: https://dark-fog-z18n0ej1.fra.unikraft.app - β”œ───────── image: httpserver-node21-sveltekit@sha256:4cea210aef3513bd68490640b511ebcff2b867e9222028b9938faccffc21cb83 - β”œ───── boot time: 72.86ms - β”œ──────── memory: 256 MiB - β”œ─────── service: dark-fog-z18n0ej1 - β”œ── private fqdn: httpserver-node21-sveltekit-zmt39.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/node /app/build/index.js + β”œ───────── name: httpserver-node21-sveltekit-zmt39 + β”œ───────── uuid: cd5071b0-5605-4771-b75d-4789393e60de + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://dark-fog-z18n0ej1.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-node21-sveltekit@sha256:4cea210aef3513bd68490640b511ebcff2b867e9222028b9938faccffc21cb83 + β”œ─────── memory: 512 MiB + β”œ────── service: dark-fog-z18n0ej1 + β”œ─ private fqdn: httpserver-node21-sveltekit-zmt39.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `httpserver-node21-sveltekit-zmt39` and the address is `https://dark-fog-z18n0ej1.fra.unikraft.app`. They're different for each run. @@ -105,11 +133,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-node21-sveltekit-zmt39 dark-fog-z18n0ej1.fra.unikraft.app running 5 minutes ago httpserver-node21-sveltekit@sha256:4cea210ae... 256 MiB 1 /usr/bin/node /app/build/index.js 72.86 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-node21-sveltekit-zmt39 running /httpserver-node21-sveltekit 512MiB 1 dark-fog-z18n0ej1.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-node21-sveltekit-zmt39 dark-fog-z18n0ej1.fra.unikraft.app running 5 minutes ago oci://unikraft.io//httpserver-node21-sveltekit@sha256:... 512 MiB 1 72.86 ms ``` + + When done, you can remove the instance: @@ -170,11 +207,13 @@ You can test the app locally by pointing your browser to `http://localhost:5173/ Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. -* `runtime: node:21`: The Unikraft runtime kernel to use is Node 21. +* `runtime: base-compat:latest`: The runtime kernel to use is the base compatibility kernel. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: [["/usr/bin/node", "/app/build/index.js"]]`: Use `/usr/bin/node /app/build/index.js` as the starting command of the instance. @@ -234,3 +273,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-node25.mdx b/pages/guides/httpserver-node25.mdx index 6f87953b..472c5c02 100644 --- a/pages/guides/httpserver-node25.mdx +++ b/pages/guides/httpserver-node25.mdx @@ -5,12 +5,15 @@ title: "Node HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} [Node.js](https://nodejs.org) is a free, open source, cross-platform JavaScript runtime environment. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node25` directory: @@ -43,32 +46,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /httpserver-node25:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-node25:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 512M --image /httpserver-node25:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-node25-v8mp4 +uuid: c3d4e5f6-a7b8-9012-cdef-123456789012 +state: starting +image: /httpserver-node25 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 8c6367b6-d913-4b24-fbc4-922cf124c8f8 + name: bright-star-k3m7pqnx + domains: + - fqdn: bright-star-k3m7pqnx.fra.unikraft.app +networks: +- uuid: 229c5467-216f-79dd-e2f9-3307b196fad3 + private-ip: 10.0.3.6 + mac: 12:b0:25:ce:7f:75 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-node25-v8mp4 - β”œ────────── uuid: c3d4e5f6-a7b8-9012-cdef-123456789012 - β”œ───────── state: starting - β”œ──────── domain: https://bright-star-k3m7pqnx.fra.unikraft.app - β”œ───────── image: httpserver-node25@sha256:7b3e1f9d5a2c8e4b0f6d3a7c5e2b9f4d1a8c6e3b0f7d4a1c8e5b2f9d6a3c0 - β”œ──────── memory: 512 MiB - β”œ─────── service: bright-star-k3m7pqnx - β”œ── private fqdn: httpserver-node25-v8mp4.internal - β”œ──── private ip: 172.16.3.6 - β””────────── args: /usr/bin/node /usr/src/server.js + β”œ───────── name: httpserver-node25-v8mp4 + β”œ───────── uuid: c3d4e5f6-a7b8-9012-cdef-123456789012 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://bright-star-k3m7pqnx.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-node25@sha256:7b3e1f9d5a2c8e4b0f6d3a7c5e2b9f4d1a8c6e3b0f7d4a1c8e5b2f9d6a3c0 + β”œ─────── memory: 512 MiB + β”œ────── service: bright-star-k3m7pqnx + β”œ─ private fqdn: httpserver-node25-v8mp4.internal + β””─── private ip: 10.0.3.6 ``` + + In this case, the instance name is `httpserver-node25-v8mp4` and the address is `https://bright-star-k3m7pqnx.fra.unikraft.app`. They're different for each run. @@ -96,11 +125,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-node25-v8mp4 bright-star-k3m7pqnx.fra.unikraft.app running since 3mins httpserver-node25@sha256:7b3e1f9d... 512 MiB 1 /usr/bin/node /usr/src/server.js 276.18 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-node25-v8mp4 running /httpserver-node25 512MiB 1 bright-star-k3m7pqnx.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-node25-v8mp4 bright-star-k3m7pqnx.fra.unikraft.app running since 3mins oci://unikraft.io//httpserver-node25@sha256:... 512 MiB 1 276.18 ms ``` + + When done, you can remove the instance: @@ -125,11 +163,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. * `runtime: base-compat:latest`: The kernel to use. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/node", "/usr/src/server.js"]`: Use `/usr/bin/node /usr/src/server.js` as the starting command of the instance. @@ -173,3 +213,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-perl5.42.mdx b/pages/guides/httpserver-perl5.42.mdx index dfbd7a72..21b99cc5 100644 --- a/pages/guides/httpserver-perl5.42.mdx +++ b/pages/guides/httpserver-perl5.42.mdx @@ -5,11 +5,14 @@ title: "Perl HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a simple Perl-based HTTP web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-perl5.42/` directory: @@ -41,34 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-perl5.42:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-perl5.42:latest +unikraft build . --output /httpserver-perl542:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 512M --image /httpserver-perl542:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-perl542-xue8j +uuid: 59d08bbc-cbb7-4c6b-a2cb-847828845db9 +state: starting +image: /httpserver-perl542 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: b62c0c0a-2de6-9068-1e93-223fa8f1edbf + name: fragrant-water-wau08gaw + domains: + - fqdn: fragrant-water-wau08gaw.fra.unikraft.app +networks: +- uuid: 22bdfc9c-2f69-eb7e-5b5e-929aba51a2c0 + private-ip: 10.0.1.161 + mac: 12:b0:d4:aa:c1:98 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────── name: httpserver-perl542-xue8j - β”œ────── uuid: 59d08bbc-cbb7-4c6b-a2cb-847828845db9 - β”œ───── metro: fra - β”œ───── state: running - β”œ──── domain: https://fragrant-water-wau08gaw.fra.unikraft.app - β”œ───── image: httpserver-perl542@sha256:af86e8f03c0d4cfd596ccfd9a9d18ea75ac68c996c9cde31f64db24dc11100fe - β”œ─ boot time: 109.36 ms - β”œ──── memory: 512 MiB - β”œ─── service: fragrant-water-wau08gaw - β”œ private ip: 10.0.1.161 - β””────── args: /usr/bin/perl /usr/src/server.pl + β”œ───────── name: httpserver-perl542-xue8j + β”œ───────── uuid: 59d08bbc-cbb7-4c6b-a2cb-847828845db9 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://fragrant-water-wau08gaw.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-perl542@sha256:af86e8f03c0d4cfd596ccfd9a9d18ea75ac68c996c9cde31f64db24dc11100fe + β”œ─────── memory: 512 MiB + β”œ────── service: fragrant-water-wau08gaw + β”œ─ private fqdn: httpserver-perl542-xue8j.internal + β””─── private ip: 10.0.1.161 ``` + + In this case, the instance name is `httpserver-perl542-xue8j` and the address is `https://fragrant-water-wau08gaw.fra.unikraft.app`. They're different for each run. @@ -96,11 +124,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-perl542-xue8j fragrant-water-wau08gaw.fra.unikraft.app standby standby httpserver-perl542@sha256:af86e8f03c0d4cfd5... 512 MiB 1 /usr/bin/perl /usr/src/server.pl 109.46 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-perl542-xue8j standby /httpserver-perl542 512MiB 1 fragrant-water-wau08gaw.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-perl542-xue8j fragrant-water-wau08gaw.fra.unikraft.app standby standby oci://unikraft.io//httpserver-perl542@sha256:... 512 MiB 1 109.46 ms ``` + + When you list your instances, you might notice they show as standby. This is normal behavior and means the instance is using Unikraft Cloud's scale-to-zero feature that saves resources when there is no traffic. To check your instance is working, open two terminals and use these commands to watch the status: @@ -108,7 +145,7 @@ To check your instance is working, open two terminals and use these commands to ```bash title="unikraft" -unikraft cloud instance list --watch +unikraft instance list --watch # In another terminal, make requests curl https://fragrant-water-wau08gaw.fra.unikraft.app ``` @@ -170,3 +207,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-php8.2.mdx b/pages/guides/httpserver-php8.2.mdx index cda7258c..d980e7ca 100644 --- a/pages/guides/httpserver-php8.2.mdx +++ b/pages/guides/httpserver-php8.2.mdx @@ -5,11 +5,14 @@ title: "PHP HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a simple PHP-based HTTP web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-php8.2/` directory: @@ -41,34 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-php8.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-php8.2:latest +unikraft build . --output /httpserver-php82:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 512M --image /httpserver-php82:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-php82-g00si +uuid: 033b2f4b-72ff-414d-b0de-63571477c657 +state: starting +image: /httpserver-php82 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: a6f268b1-05c3-31c1-7d9b-76cb952fd713 + name: aged-fire-rh0oi0tj + domains: + - fqdn: aged-fire-rh0oi0tj.fra.unikraft.app +networks: +- uuid: f18bc9d1-a75d-dbd0-6566-599c2a1a95a6 + private-ip: 10.0.3.3 + mac: 12:b0:af:34:d3:e8 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-php82-g00si - β”œ────────── uuid: 033b2f4b-72ff-414d-b0de-63571477c657 - β”œ───────── state: running - β”œ─────────── url: https://aged-fire-rh0oi0tj.fra.unikraft.app - β”œ───────── image: httpserver-php82@sha256:dccaac053982673765b8f00497a9736c31458ab23ad59a550b09aa8dedfabb34 - β”œ───── boot time: 32.80 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: aged-fire-rh0oi0tj - β”œ── private fqdn: httpserver-php82-g00si.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/local/bin/php /usr/src/server.php + β”œ───────── name: httpserver-php82-g00si + β”œ───────── uuid: 033b2f4b-72ff-414d-b0de-63571477c657 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://aged-fire-rh0oi0tj.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-php82@sha256:dccaac053982673765b8f00497a9736c31458ab23ad59a550b09aa8dedfabb34 + β”œ─────── memory: 512 MiB + β”œ────── service: aged-fire-rh0oi0tj + β”œ─ private fqdn: httpserver-php82-g00si.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `httpserver-php82-g00si` and the address is `https://aged-fire-rh0oi0tj.fra.unikraft.app`. They're different for each run. @@ -96,11 +124,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-php82-g00si aged-fire-rh0oi0tj.fra.unikraft.app running 50 seconds ago httpserver-php82@sha256:dccaac05398... 512 MiB 1 /usr/local/bin/php /usr/src/server.php 32801us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-php82-g00si running /httpserver-php82 512MiB 1 aged-fire-rh0oi0tj.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-php82-g00si aged-fire-rh0oi0tj.fra.unikraft.app running 50 seconds ago oci://unikraft.io//httpserver-php82@sha256:... 512 MiB 1 32.80 ms ``` + + When done, you can remove the instance: @@ -150,3 +187,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx b/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx index 6fa0bcce..45116320 100644 --- a/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx +++ b/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx @@ -5,18 +5,22 @@ title: "Prisma HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This app comes from [Prisma's REST API Example](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-express) and shows how to create a **REST API** using [Express](https://expressjs.com/) and [Prisma Client](https://www.prisma.io/docs/concepts/components/prisma-client) and deploy it onto Unikraft Cloud. It uses a SQLite database file with some initial [migration data](./prisma/migrations/20240208151224_init/). -To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +To run this example, follow these steps: + +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). -2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node18-prisma-rest-express/` directory: +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-prisma-expressjs4.19-node18/` directory: ```bash git clone https://github.com/unikraft-cloud/examples -cd examples/httpserver-node18-prisma-rest-express/ +cd examples/httpserver-prisma-expressjs4.19-node18/ ``` Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. @@ -42,35 +46,60 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-prisma-expressjs4.19-node18:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 512M --image=/httpserver-prisma-expressjs4.19-node18:latest +unikraft build . --output /httpserver-prisma-expressjs419-node18:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:3000/tls+http -m 512M --image /httpserver-prisma-expressjs419-node18:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-prisma-expressjs419-node18-hdof1 +uuid: 066f55cb-bcbd-45e5-9f6b-b3866c3a3a4c +state: starting +image: /httpserver-prisma-expressjs419-node18 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: b7da8a3b-ca4d-979a-3ae9-9634bca98008 + name: funky-sun-4bf8v7g9 + domains: + - fqdn: funky-sun-4bf8v7g9.fra.unikraft.app +networks: +- uuid: 63d977e8-548c-f0af-cc97-39856660f612 + private-ip: 10.0.28.2 + mac: 12:b0:43:fb:5c:30 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-node18-prisma-hdof1 - β”œ────────── uuid: 066f55cb-bcbd-45e5-9f6b-b3866c3a3a4c - β”œ───────── state: running - β”œ─────────── url: https://funky-sun-4bf8v7g9.fra.unikraft.app - β”œ───────── image: httpserver-node18-prisma@sha256:770d4af1d490daea11171c680eaf99e2a6017a262ba9fbf1ba8d708f5fc32bfe - β”œ───── boot time: 37.94 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: funky-sun-4bf8v7g9 - β”œ── private fqdn: httpserver-node18-prisma-hdof1.internal - β”œ──── private ip: 172.16.28.2 - β””────────── args: /usr/bin/node /usr/src/server.js + β”œ───────── name: httpserver-prisma-expressjs419-node18-hdof1 + β”œ───────── uuid: 066f55cb-bcbd-45e5-9f6b-b3866c3a3a4c + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://funky-sun-4bf8v7g9.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-prisma-expressjs419-node18@sha256:770d4af1d490daea11171c680eaf99e2a6017a262ba9fbf1ba8d708f5fc32bfe + β”œ─────── memory: 512 MiB + β”œ────── service: funky-sun-4bf8v7g9 + β”œ─ private fqdn: httpserver-prisma-expressjs419-node18-hdof1.internal + β””─── private ip: 10.0.28.2 ``` -In this case, the instance name is `httpserver-node18-prisma-hdof1` and the address is `https://funky-sun-4bf8v7g9.fra.unikraft.app`. + + +In this case, the instance name is `httpserver-prisma-expressjs419-node18-hdof1` and the address is `https://funky-sun-4bf8v7g9.fra.unikraft.app`. They're different for each run. Use `curl` to test the REST API, such as the `/users` endpoint: @@ -99,21 +128,30 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-node18-prisma-hdof1 funky-sun-4bf8v7g9.fra.unikraft.app running 1 minute ago httpserver-node18-prisma@sha25... 512 MiB 1 /usr/bin/node /usr/src/server.js 37935us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-prisma-expressjs419-node18-hdof1 running /httpserver-prisma-expressjs419-node18 512MiB 1 funky-sun-4bf8v7g9.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-prisma-expressjs419-node18-hdof1 funky-sun-4bf8v7g9.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-prisma-expressjs419-node18@sha256:... 512 MiB 1 37.94 ms ``` + + When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-node18-prisma-hdof1 +unikraft instances delete httpserver-prisma-expressjs419-node18-hdof1 ``` ```bash title="kraft" -kraft cloud instance remove httpserver-node18-prisma-hdof1 +kraft cloud instance remove httpserver-prisma-expressjs419-node18-hdof1 ``` @@ -370,3 +408,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx b/pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx deleted file mode 100644 index 59557e9c..00000000 --- a/pages/guides/httpserver-python3.12-FastAPI-0.121.3.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: "FastAPI HTTP Server" ---- - - -import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" - -This guide explains how to create and deploy a Python FastAPI web app. -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). - Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). - -1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-python3.12-FastAPI-0.121.3/` directory: - -```bash -git clone https://github.com/unikraft-cloud/examples -cd examples/httpserver-python3.12-FastAPI-0.121.3/ -``` - -Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. -This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): - - - -```bash title="unikraft" -unikraft login -``` - -```bash title="kraft" -# Set Unikraft Cloud access token -export UKC_TOKEN=token -# Set metro to Frankfurt, DE -export UKC_METRO=fra -``` - - - -When done, invoke the following command to deploy this app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output /httpserver-python3.12-FastAPI-0.121.3:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-python3.12-FastAPI-0.121.3:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . -``` - - - -The output shows the instance address and other details: - -```ansi -[●] Deployed successfully! - β”‚ - β”œ────── name: httpserver-python312-fastapi-01213-0n84f - β”œ────── uuid: 5d7fc331-3c23-4953-b025-d152a872ea29 - β”œ───── metro: fra - β”œ───── state: running - β”œ──── domain: https://dry-water-0oexx89g.fra.unikraft.app - β”œ───── image: httpserver-python312-fastapi-01213@sha256:fb2a00dcf1cfc3ac821cbda05f82f38d66e63121344b9bc60c6a6e2f11917b98 - β”œ─ boot time: 170.42 ms - β”œ──── memory: 512 MiB - β”œ─── service: dry-water-0oexx89g - β”œ private ip: 10.0.1.69 - β””────── args: /usr/bin/python3 -m uvicorn src.server:app --host 0.0.0.0 --port 8080 -``` - -In this case, the instance name is `httpserver-python312-fastapi-01213-0n84f` and the address is `https://dry-water-0oexx89g.fra.unikraft.app`. -They're different for each run. - -Use `curl` to query the Unikraft Cloud instance of the Python FastAPI web app server: - -```bash -curl https://dry-water-0oexx89g.fra.unikraft.app -``` - -```text -{"Hello":"World"} -``` -You can list information about the instance by running: - - - -```bash title="unikraft" -unikraft instances list -``` - -```bash title="kraft" -kraft cloud instance list -``` - - - -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-python312-fastapi-01213-0n84f dry-water-0oexx89g.fra.unikraft.app standby standby httpserver-python312-fastapi-01213@sha25... 512 MiB 1 /usr/bin/python3 -m uvicorn src.server:app --hos... 169.45 ms -``` - -When done, you can remove the instance: - - - -```bash title="unikraft" -unikraft instances remove httpserver-python312-fastapi-01213-0n84f -``` - -```bash title="kraft" -kraft cloud instance remove httpserver-python312-fastapi-01213-0n84f -``` - - - -## Customize your app - -To customize the app, update the files in the repository, listed below: - -* `server.py`: the entry point for the app -* `Kraftfile`: the Unikraft Cloud specification -* `Dockerfile`: the Docker-specified app filesystem - -Lines in the `Kraftfile` have the following roles: - -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. - -* `runtime: base-compat:latest`: The Unikraft runtime kernel to use is the latest that provides a minimal Linux-compatible environment. - -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. - -* `cmd: ["/usr/bin/python3", "-m", "uvicorn", "src.server:app", "--host", "0.0.0.0", "--port", "8080"]`: Use this as the starting command of the instance. - -Lines in the `Dockerfile` have the following roles: - -* `FROM scratch`: Build the filesystem from the [`scratch` container image](https://hub.docker.com/_/scratch/), to [create a base image](https://docs.docker.com/build/building/base-images/). - -The following options are available for customizing the app: - -* If you only update the implementation in the `server.py` source file, you don't need to make any other changes. - -* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. - -* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). - This includes the use of Python frameworks and the use of `pip`, as shown in the next section. - -## Using `pip` - -[`pip`](https://pip.pypa.io/en/stable/) is a package manager for Python. -It's used to install dependencies for Python apps. -`pip` uses the `requirements.txt` file to list required dependencies (with versions). - -The [`httpserver-python3.12-FastAPI-0.121.3`](https://github.com/unikraft-cloud/examples/tree/main/httpserver-python3.12-FastAPI-0.121.3) guide details the use of `pip` to deploy an app using the [`FastAPI`](https://fastapi.tiangolo.com/) framework on Unikraft Cloud. - -Run the command below to deploy the app on Unikraft Cloud: - - - -```bash title="unikraft" -unikraft build . --output /httpserver-python3.12-FastAPI-0.121.3:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-python3.12-FastAPI-0.121.3:latest -``` - -```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . -``` - - - -Differences from the FastAPI app are also the steps required to create an `pip`-based app: - -1. Add the `requirements.txt` file used by `pip`. - -2. Add framework-specific source files. - In this case, this means the `server.py` file. - -3. Update the `Dockerfile` to: - - 3.1. `COPY` the local files. - - 3.2. `RUN` the `pip3 install` command to install dependencies. - - 3.3. `COPY` of the resulting and required files (`/usr/local/lib/python3.12` and `server.py`) in the app filesystem, using the [`scratch` container](https://hub.docker.com/_/scratch/). - -The following lists the files: - -The `requirements.txt` file lists the `fastapi` and `uvicorn` dependencies. - -The `Kraftfile` is the same one used for `httpserver-python3.12`, except changed lines that have the following roles: -* `cmd: ["/usr/bin/python3", "-m", "uvicorn", "src.server:app", "--host", "0.0.0.0", "--port", "8080"]`: Use `/usr/bin/python3 -m uvicorn src.server:app --host 0.0.0.0 --port 8080` as the starting command of the instance. - -For `Dockerfile` newly added lines have the following roles: - -* `FROM python:3.12-bookworm AS build`: Use the base image of the `python:3.12-bookworm` container. - This provides the `pip3` binary and other Python-related components. - Name the current image `build`. - -* `WORKDIR /app`: Use `/app` as working directory. - All other commands in the `Dockerfile` run inside this directory. - -* `COPY requirements.txt /app`: Copy the package configuration file to the Docker filesystem. - -* `RUN pip3 install ...`: Install `pip` components listed in `requirements.txt`. - -* `COPY --from=build ...`: Copy generated Python files in the new `build` image in the `scratch`-based image. - -Similar actions apply to other `pip3`-based apps. - -## Learn more - -Use the `--help` option for detailed information on using Unikraft Cloud: - - - -```bash title="unikraft" -unikraft --help -``` - -```bash title="kraft" -kraft cloud --help -``` - - - -Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). diff --git a/pages/guides/httpserver-python3.12-django5.0.mdx b/pages/guides/httpserver-python3.12-django5.0.mdx index ea0c7cd8..20a87000 100644 --- a/pages/guides/httpserver-python3.12-django5.0.mdx +++ b/pages/guides/httpserver-python3.12-django5.0.mdx @@ -5,11 +5,14 @@ title: "Django HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a Python Django web app. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-python3.12-django5.0/` directory: @@ -41,34 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-python3.12-django5.0:latest -unikraft run --metro=fra -p 443:80/tls+http -m 1G --image=/httpserver-python3.12-django5.0:latest +unikraft build . --output /httpserver-python312-django50:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:80/tls+http -m 1G --image /httpserver-python312-django50:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:80/tls+http -M 1G . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:80/tls+http -M 1Gi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-python312-django50-vt56c +uuid: d8469447-fdf6-4caf-9fea-494218ca6f72 +state: starting +image: /httpserver-python312-django50 +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: 109aa11f-da45-8d57-d5e4-6eb509ee3e73 + name: dawn-sound-n5wrkxi2 + domains: + - fqdn: dawn-sound-n5wrkxi2.fra.unikraft.app +networks: +- uuid: 95f37ba4-2586-54a2-bf3e-5764c91c4fc1 + private-ip: 10.0.6.5 + mac: 12:b0:9c:af:65:e7 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-python312-django50-vt56c - β”œ────────── uuid: d8469447-fdf6-4caf-9fea-494218ca6f72 - β”œ───────── state: running - β”œ─────────── url: https://dawn-sound-n5wrkxi2.fra.unikraft.app - β”œ───────── image: httpserver-python312-django50@sha256:221666d414299aff54dbf10020b3d540270ee0c5907c1c6a728ca254ce8b0e50 - β”œ───── boot time: 80.32 ms - β”œ──────── memory: 1024 MiB - β”œ─────── service: dawn-sound-n5wrkxi2 - β”œ── private fqdn: httpserver-python312-django50-vt56c.internal - β”œ──── private ip: 172.16.6.5 - β””────────── args: /usr/bin/python3 /app/main.py + β”œ───────── name: httpserver-python312-django50-vt56c + β”œ───────── uuid: d8469447-fdf6-4caf-9fea-494218ca6f72 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://dawn-sound-n5wrkxi2.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-python312-django50@sha256:221666d414299aff54dbf10020b3d540270ee0c5907c1c6a728ca254ce8b0e50 + β”œ─────── memory: 1024 MiB + β”œ────── service: dawn-sound-n5wrkxi2 + β”œ─ private fqdn: httpserver-python312-django50-vt56c.internal + β””─── private ip: 10.0.6.5 ``` + + In this case, the instance name is `httpserver-python312-django50-vt56c` and the address is `https://dawn-sound-n5wrkxi2.fra.unikraft.app`. They're different for each run. @@ -118,11 +146,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-python312-django50-vt56c dawn-sound-n5wrkxi2.fra.unikraft.app running 1 minute ago httpserver-python312-django50@sha256:221... 1024 MiB 1 /usr/bin/python3 /app/main.py 80321us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-python312-django50-vt56c running /httpserver-python312-django50 1024MiB 1 dawn-sound-n5wrkxi2.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-python312-django50-vt56c dawn-sound-n5wrkxi2.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-python312-django50@sha256:... 1024 MiB 1 80.32 ms ``` + + When done, you can remove the instance: @@ -147,11 +184,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. -* `runtime: python:3.12`: The Unikraft runtime kernel to use is Python 3.12. +* `runtime: base-compat:latest`: The runtime kernel to use is the base compatibility kernel. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/python3", "/app/main.py"]`: Use this as the starting command of the instance. @@ -181,12 +220,12 @@ Run the command below to deploy the app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-python3.12-django5.0:latest -unikraft run --metro=fra -p 443:80/tls+http -m 1G --image=/httpserver-python3.12-django5.0:latest +unikraft build . --output /httpserver-python312-flask30:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:80/tls+http -m 1G --image /httpserver-python312-flask30:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:80/tls+http -M 1G . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:80/tls+http -M 1Gi . ``` @@ -246,3 +285,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-python3.12-fastapi-0.121.3.mdx b/pages/guides/httpserver-python3.12-fastapi-0.121.3.mdx new file mode 100644 index 00000000..e9bb4262 --- /dev/null +++ b/pages/guides/httpserver-python3.12-fastapi-0.121.3.mdx @@ -0,0 +1,203 @@ +--- +title: "FastAPI HTTP Server" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +This guide explains how to create and deploy a Python FastAPI web app. +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-python3.12-fastapi-0.121.3/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/httpserver-python3.12-fastapi-0.121.3/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /httpserver-python312-fastapi-01213:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 512M --image /httpserver-python312-fastapi-01213:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: httpserver-python312-fastapi-01213-0n84f +uuid: 5d7fc331-3c23-4953-b025-d152a872ea29 +state: starting +image: /httpserver-python312-fastapi-01213 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: ced3df54-64cc-9217-3441-e0b4995319f0 + name: dry-water-0oexx89g + domains: + - fqdn: dry-water-0oexx89g.fra.unikraft.app +networks: +- uuid: 66d1766f-0a03-8b62-eb1a-0adb09b07b1d + private-ip: 10.0.1.69 + mac: 12:b0:a1:15:7c:4a +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: httpserver-python312-fastapi-01213-0n84f + β”œ───────── uuid: 5d7fc331-3c23-4953-b025-d152a872ea29 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://dry-water-0oexx89g.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-python312-fastapi-01213@sha256:fb2a00dcf1cfc3ac821cbda05f82f38d66e63121344b9bc60c6a6e2f11917b98 + β”œ─────── memory: 512 MiB + β”œ────── service: dry-water-0oexx89g + β”œ─ private fqdn: httpserver-python312-fastapi-01213-0n84f.internal + β””─── private ip: 10.0.1.69 +``` + + + +In this case, the instance name is `httpserver-python312-fastapi-01213-0n84f` and the address is `https://dry-water-0oexx89g.fra.unikraft.app`. +They're different for each run. + +Use `curl` to query the Unikraft Cloud instance of the Python FastAPI web app server: + +```bash +curl https://dry-water-0oexx89g.fra.unikraft.app +``` + +```text +{"Hello":"World"} +``` +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-python312-fastapi-01213-0n84f standby /httpserver-python312-fastapi-01213 512MiB 1 dry-water-0oexx89g.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-python312-fastapi-01213-0n84f dry-water-0oexx89g.fra.unikraft.app standby standby oci://unikraft.io//httpserver-python312-fastapi-01213@sha25... 512 MiB 1 169.45 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances remove httpserver-python312-fastapi-01213-0n84f +``` + +```bash title="kraft" +kraft cloud instance remove httpserver-python312-fastapi-01213-0n84f +``` + + + +## Customize your app + +To customize the app, update the files in the repository, listed below: + +* `server.py`: the entry point for the app +* `Kraftfile`: the Unikraft Cloud specification +* `Dockerfile`: the Docker-specified app filesystem + +Lines in the `Kraftfile` have the following roles: + +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. + +* `runtime: base-compat:latest`: The Unikraft runtime kernel to use is the latest that provides a minimal Linux-compatible environment. + +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + +* `cmd: ["/usr/bin/python3", "-m", "uvicorn", "src.server:app", "--host", "0.0.0.0", "--port", "8080"]`: Use this as the starting command of the instance. + +Lines in the `Dockerfile` have the following roles: + +* `FROM scratch`: Build the filesystem from the [`scratch` container image](https://hub.docker.com/_/scratch/), to [create a base image](https://docs.docker.com/build/building/base-images/). + +The following options are available for customizing the app: + +* If you only update the implementation in the `server.py` source file, you don't need to make any other changes. + +* If you create any new source files, copy them into the app filesystem by using the `COPY` command in the `Dockerfile`. + +* More extensive changes may require extending the `Dockerfile` ([see `Dockerfile` syntax reference](https://docs.docker.com/engine/reference/builder/)). + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx b/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx index 1a8353e2..0474ac94 100644 --- a/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx +++ b/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx @@ -5,11 +5,14 @@ title: "Flask and SQLite HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a Python Flask app using SQLite. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-python3.12-flask3.0-sqlite/` directory: @@ -41,32 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-python3.12-flask3.0-sqlite:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 768M --image=/httpserver-python3.12-flask3.0-sqlite:latest +unikraft build . --output /httpserver-python312-flask30-sqlite:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 768M --image /httpserver-python312-flask30-sqlite:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 768M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 768Mi . ``` -```ansi +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: httpserver-python312-flask30-sqlite-qodkd +uuid: e00e7aca-962d-409c-87c2-c245ca08b54b +state: starting +image: /httpserver-python312-flask30-sqlite +resources: + memory: 768MiB + vcpus: 1 +service: + uuid: 1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d + name: lingering-orangutan-840mmdvd + domains: + - fqdn: lingering-orangutan-840mmdvd.fra.unikraft.app +networks: +- uuid: 2b3c4d5e-6f7a-8b9c-0d1e-2f3a4b5c6d7e + private-ip: 10.0.3.3 + mac: 12:b0:8a:4f:2c:91 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-python312-flask30-sqlite-qodkd - β”œ────────── uuid: e00e7aca-962d-409c-87c2-c245ca08b54b - β”œ───────── state: running - β”œ─────────── url: https://lingering-orangutan-840mmdvd.fra.unikraft.app - β”œ───────── image: httpserver-python312-flask30-sqlite@sha256:bdb0bf35a9675b9b3836cbb626606da0606334d91768c7ba31195c3062d6f517 - β”œ───── boot time: 166.25 ms - β”œ──────── memory: 768 MiB - β”œ─────── service: lingering-orangutan-840mmdvd - β”œ── private fqdn: httpserver-python312-flask30-sqlite-qodkd.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/python3 /app/server.py + β”œ───────── name: httpserver-python312-flask30-sqlite-qodkd + β”œ───────── uuid: e00e7aca-962d-409c-87c2-c245ca08b54b + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://lingering-orangutan-840mmdvd.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-python312-flask30-sqlite@sha256:bdb0bf35a9675b9b3836cbb626606da0606334d91768c7ba31195c3062d6f517 + β”œ─────── memory: 768 MiB + β”œ────── service: lingering-orangutan-840mmdvd + β”œ─ private fqdn: httpserver-python312-flask30-sqlite-qodkd.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `httpserver-python312-flask30-sqlite-qodkd` and the address is `https://lingering-orangutan-840mmdvd.fra.unikraft.app`. They're different for each run. @@ -111,11 +141,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-python312-flask30-sqlite-qodkd lingering-orangutan-840mmdvd.fra.... running 1 minute ago httpserver-python312-flask30-sqlite@sha256... 768 MiB 1 /usr/bin/python3 /app/server.py 166250us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-python312-flask30-sqlite-qodkd running /httpserver-python312-flask30-sqlite 768MiB 1 lingering-orangutan-840mmdvd.fra.... 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-python312-flask30-sqlite-qodkd lingering-orangutan-840mmdvd.fra.... running 1 minute ago oci://unikraft.io//httpserver-python312-flask30-sqlite@sha256... 768 MiB 1 166.25 ms ``` + + When done, you can remove the instance: @@ -143,11 +182,13 @@ The app uses the following files: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. -* `runtime: python:3.12`: The Unikraft runtime kernel to use is Python 3.12. +* `runtime: base-compat:latest`: The runtime kernel to use is the base compatibility kernel. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/python3", "/app/server.py"]`: Use `/usr/bin/python3 /app/server.py` as the starting command of the instance. @@ -205,3 +246,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-python3.12-flask3.0.mdx b/pages/guides/httpserver-python3.12-flask3.0.mdx index 8150163d..f1afc127 100644 --- a/pages/guides/httpserver-python3.12-flask3.0.mdx +++ b/pages/guides/httpserver-python3.12-flask3.0.mdx @@ -5,11 +5,14 @@ title: "Flask HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a [Flask](https://flask.palletsprojects.com/en/3.0.x/) web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-python3.12-flask3.0/` directory: @@ -41,34 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-python3.12-flask3.0:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-python3.12-flask3.0:latest +unikraft build . --output /httpserver-python312-flask30:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 512M --image /httpserver-python312-flask30:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-python312-flask30-bxwxm +uuid: 3ff1ebad-2639-4214-bab4-ed35c4c32fa4 +state: starting +image: /httpserver-python312-flask30 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 2021ca1e-5e47-a35c-bde2-7190f3815c07 + name: damp-sunset-azd6dtyt + domains: + - fqdn: damp-sunset-azd6dtyt.fra.unikraft.app +networks: +- uuid: 4dc3b272-4fa2-ddb4-7ce0-5e66e8112a61 + private-ip: 10.0.6.5 + mac: 12:b0:66:99:b3:3f +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-python312-flask30-bxwxm - β”œ────────── uuid: 3ff1ebad-2639-4214-bab4-ed35c4c32fa4 - β”œ───────── state: running - β”œ─────────── url: https://damp-sunset-azd6dtyt.fra.unikraft.app - β”œ───────── image: httpserver-python312-flask30@sha256:d6c8e4c5a4f44e1d642d8eaeaa1d820b2841194dd6c5d4a872ae0a895c767da9 - β”œ───── boot time: 222.27 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: damp-sunset-azd6dtyt - β”œ── private fqdn: httpserver-python312-flask30-bxwxm.internal - β”œ──── private ip: 172.16.6.5 - β””────────── args: /usr/bin/python3 /app/server.py + β”œ───────── name: httpserver-python312-flask30-bxwxm + β”œ───────── uuid: 3ff1ebad-2639-4214-bab4-ed35c4c32fa4 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://damp-sunset-azd6dtyt.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-python312-flask30@sha256:d6c8e4c5a4f44e1d642d8eaeaa1d820b2841194dd6c5d4a872ae0a895c767da9 + β”œ─────── memory: 512 MiB + β”œ────── service: damp-sunset-azd6dtyt + β”œ─ private fqdn: httpserver-python312-flask30-bxwxm.internal + β””─── private ip: 10.0.6.5 ``` + + In this case, the instance name is `httpserver-python312-flask30-bxwxm` and the address is `https://damp-sunset-azd6dtyt.fra.unikraft.app`. They're different for each run. @@ -96,11 +124,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-python312-flask30-bxwxm damp-sunset-azd6dtyt.fra.unikraft.app running 1 minute ago httpserver-python312-flask30@sha256:d6c8... 512 MiB 1 /usr/bin/python3 /app/server.py 222273us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-python312-flask30-bxwxm running /httpserver-python312-flask30 512MiB 1 damp-sunset-azd6dtyt.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-python312-flask30-bxwxm damp-sunset-azd6dtyt.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-python312-flask30@sha256:... 512 MiB 1 222.27 ms ``` + + When done, you can remove the instance: @@ -125,11 +162,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. -* `runtime: python:3.12`: The Unikraft runtime kernel to use is Python 3.12. +* `runtime: base-compat:latest`: The runtime kernel to use is the base compatibility kernel. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/python3", "/src/server.py"]`: Use `/usr/bin/python3 /src/server.py` as the starting command of the instance. @@ -209,3 +248,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-python3.12.mdx b/pages/guides/httpserver-python3.12.mdx index d81d98c6..16789a64 100644 --- a/pages/guides/httpserver-python3.12.mdx +++ b/pages/guides/httpserver-python3.12.mdx @@ -5,11 +5,14 @@ title: "Python HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a simple Python-based HTTP web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-python3.12/` directory: @@ -41,34 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-python3.12:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-python3.12:latest +unikraft build . --output /httpserver-python312:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 512M --image /httpserver-python312:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-python312-ma2i9 +uuid: e7389eee-9808-4152-b2ec-1f3c0541fd05 +state: starting +image: /httpserver-python312 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 51a41f63-7e88-c443-b9bf-83cd7c04d975 + name: young-night-5fpf0jj8 + domains: + - fqdn: young-night-5fpf0jj8.fra.unikraft.app +networks: +- uuid: 53da3490-c6f5-3718-25f1-219a65163c73 + private-ip: 10.0.3.3 + mac: 12:b0:18:0c:cb:aa +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-python312-ma2i9 - β”œ────────── uuid: e7389eee-9808-4152-b2ec-1f3c0541fd05 - β”œ───────── state: running - β”œ─────────── url: https://young-night-5fpf0jj8.fra.unikraft.app - β”œ───────── image: httpserver-python312@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472 - β”œ───── boot time: 15.09 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: young-night-5fpf0jj8 - β”œ── private fqdn: httpserver-python312-ma2i9.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/python /src/server.py + β”œ───────── name: httpserver-python312-ma2i9 + β”œ───────── uuid: e7389eee-9808-4152-b2ec-1f3c0541fd05 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://young-night-5fpf0jj8.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-python312@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472 + β”œ─────── memory: 512 MiB + β”œ────── service: young-night-5fpf0jj8 + β”œ─ private fqdn: httpserver-python312-ma2i9.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `httpserver-python312-ma2i9` and the address is `https://young-night-5fpf0jj8.fra.unikraft.app`. They're different for each run. @@ -96,11 +124,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-python312-ma2i9 young-night-5fpf0jj8.fra.unikraft.app running 1 minute ago httpserver-python312@sha256:278cb8b14f27... 512 MiB 1 /usr/bin/python /src/server.py 15094us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-python312-ma2i9 running /httpserver-python312 512MiB 1 young-night-5fpf0jj8.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-python312-ma2i9 young-night-5fpf0jj8.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-python312@sha256:... 512 MiB 1 15.09 ms ``` + + When done, you can remove the instance: @@ -125,11 +162,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. -* `runtime: python:3.12`: The Unikraft runtime kernel to use is Python 3.12. +* `runtime: base-compat:latest`: The runtime kernel to use is the base compatibility kernel. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/python3", "/src/server.py"]`: Use `/usr/bin/python3 /src/server.py` as the starting command of the instance. @@ -161,12 +200,12 @@ Run the command below to deploy the app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-python3.12:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/httpserver-python3.12:latest +unikraft build . --output /httpserver-python312-flask30:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 512M --image /httpserver-python312-flask30:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . ``` @@ -208,6 +247,7 @@ For `Dockerfile` newly added lines have the following roles: * `COPY --from=base ...`: Copy generated Python files in the new `base` image in the `scratch`-based image. Similar actions apply to other `pip3`-based apps. + See also the [`httpserver-python3.12-django5.0`](https://github.com/unikraft-cloud/examples/tree/main/httpserver-python3.12-django5.0) example. ## Learn more @@ -227,3 +267,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-ruby3.2.mdx b/pages/guides/httpserver-ruby3.2.mdx index d31e122f..368533ab 100644 --- a/pages/guides/httpserver-ruby3.2.mdx +++ b/pages/guides/httpserver-ruby3.2.mdx @@ -5,11 +5,14 @@ title: "Ruby HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a simple Ruby-based HTTP web server. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-ruby3.2/` directory: @@ -41,34 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-ruby3.2:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-ruby3.2:latest +unikraft build . --output /httpserver-ruby32:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-ruby32:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-ruby32-s6l8n +uuid: b1ebbbc0-5efa-476c-adb6-99866773245c +state: starting +image: /httpserver-ruby32 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: bcc07c7c-9289-11f4-6e3d-8f7fdde45256 + name: silent-resonance-1jtz5c66 + domains: + - fqdn: silent-resonance-1jtz5c66.fra.unikraft.app +networks: +- uuid: 50203783-cf51-81d1-aa2d-615f939043af + private-ip: 10.0.3.3 + mac: 12:b0:0a:4f:7a:84 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-ruby32-s6l8n - β”œ────────── uuid: b1ebbbc0-5efa-476c-adb6-99866773245c - β”œ───────── state: running - β”œ─────────── url: https://silent-resonance-1jtz5c66.fra.unikraft.app - β”œ───────── image: httpserver-ruby32@sha256:4cf3b341898e6ebff18ff2b68353ef872dded650c9d16a6f005a8fbe8a7cbb3d - β”œ───── boot time: 71.19 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: silent-resonance-1jtz5c66 - β”œ── private fqdn: httpserver-ruby32-s6l8n.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/ruby /src/server.rb + β”œ───────── name: httpserver-ruby32-s6l8n + β”œ───────── uuid: b1ebbbc0-5efa-476c-adb6-99866773245c + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://silent-resonance-1jtz5c66.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-ruby32@sha256:4cf3b341898e6ebff18ff2b68353ef872dded650c9d16a6f005a8fbe8a7cbb3d + β”œ─────── memory: 256 MiB + β”œ────── service: silent-resonance-1jtz5c66 + β”œ─ private fqdn: httpserver-ruby32-s6l8n.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `httpserver-ruby32-s6l8n` and the address is `https://silent-resonance-1jtz5c66.fra.unikraft.app`. They're different for each run. @@ -96,11 +124,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-ruby32-s6l8n silent-resonance-1jtz5c66.fra.unikraft.app running 12 minutes ago httpserver-ruby32@sha256:4cf3b341898e6ff2b68353ef... 256 MiB 1 /usr/bin/ruby /src/server.rb 71191us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-ruby32-s6l8n running /httpserver-ruby32 256MiB 1 silent-resonance-1jtz5c66.fra.unikraf… 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-ruby32-s6l8n silent-resonance-1jtz5c66.fra.unikraft.app running 12 minutes ago oci://unikraft.io//httpserver-ruby32@sha256:... 256 MiB 1 71.19 ms ``` + + When done, you can remove the instance: @@ -148,3 +185,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-rust-trunkrs-leptos.mdx b/pages/guides/httpserver-rust-trunkrs-leptos.mdx new file mode 100644 index 00000000..ecca6103 --- /dev/null +++ b/pages/guides/httpserver-rust-trunkrs-leptos.mdx @@ -0,0 +1,178 @@ +--- +title: "Rust (Leptos + Trunk) HTTP Server" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +This guide shows how to deploy a Rust HTTP server using Trunk and Leptos on Unikraft Cloud. +To run it, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust-trunkrs-leptos/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/httpserver-rust-trunkrs-leptos/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /httpserver-rust-trunkrs-leptos:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-rust-trunkrs-leptos:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s --metro fra -p 443:8080/tls+http -M 256Mi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: httpserver-rust-trunkrs-leptos-n2j7k +uuid: 7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e +state: starting +image: /httpserver-rust-trunkrs-leptos +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: 8c9d0e1f-2a3b-4c5d-6e7f-8a9b0c1d2e3f + name: cool-wind-by4hq7nm + domains: + - fqdn: cool-wind-by4hq7nm.fra.unikraft.app +networks: +- uuid: 9d0e1f2a-3b4c-5d6e-7f8a-9b0c1d2e3f4a + private-ip: 10.0.2.3 + mac: 12:b0:7d:4f:bc:a6 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: httpserver-rust-trunkrs-leptos-n2j7k + β”œ───────── uuid: 7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://cool-wind-by4hq7nm.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-rust-trunkrs-leptos@sha256:6b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c + β”œ─────── memory: 256 MiB + β”œ────── service: cool-wind-by4hq7nm + β”œ─ private fqdn: httpserver-rust-trunkrs-leptos-n2j7k.internal + β””─── private ip: 10.0.2.3 +``` + + + +In this case, the instance name is `httpserver-rust-trunkrs-leptos-n2j7k` and the address is `https://cool-wind-by4hq7nm.fra.unikraft.app`. +They're different for each run. + +The command will deploy files in the current directory. + +After deploying, you can query the service using the provided URL. + +To run locally: + +```bash +trunk serve +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-rust-trunkrs-leptos-n2j7k running /httpserver-rust-trunkrs-leptos 256MiB 1 cool-wind-by4hq7nm.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-rust-trunkrs-leptos-n2j7k cool-wind-by4hq7nm.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-rust-trunkrs-leptos@sha256:... 256 MiB 1 8.42 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + + +## Learn more + +- [leptos](https://leptos.dev) +- [trunkrs](https://trunkrs.dev) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-rust1.75-tokio.mdx b/pages/guides/httpserver-rust1.75-tokio.mdx index adbb6b70..f19a3bb4 100644 --- a/pages/guides/httpserver-rust1.75-tokio.mdx +++ b/pages/guides/httpserver-rust1.75-tokio.mdx @@ -5,11 +5,14 @@ title: "Rust (Tokio) HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example uses [`Tokio`](https://tokio.rs/), a popular Rust asynchronous runtime. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust1.75-tokio/` directory: @@ -41,34 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-rust1.75-tokio:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-rust1.75-tokio:latest +unikraft build . --output /httpserver-rust175-tokio:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-rust175-tokio:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-rust175-tokio-6gxsp +uuid: d5719f64-0653-42d7-b2de-aa6dee0ce467 +state: starting +image: /httpserver-rust175-tokio +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: b59ce5aa-7dac-5241-386c-be48db955f3f + name: empty-dawn-3coedrce + domains: + - fqdn: empty-dawn-3coedrce.fra.unikraft.app +networks: +- uuid: 9136307f-2ee6-2a0b-99af-c5a0fc1727f5 + private-ip: 10.0.6.3 + mac: 12:b0:38:a0:73:f3 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-rust175-tokio-6gxsp - β”œ────────── uuid: d5719f64-0653-42d7-b2de-aa6dee0ce467 - β”œ───────── state: running - β”œ─────────── url: https://empty-dawn-3coedrce.fra.unikraft.app - β”œ───────── image: httpserver-rust175-tokio@sha256:0ce75912711aa2329232a2ca6c3ccb7a244b6d546fafc081f815c2fde8224856 - β”œ───── boot time: 21.41 ms - β”œ──────── memory: 256 Mi - β”œ─────── service: empty-dawn-3coedrce - β”œ── private fqdn: httpserver-rust175-tokio-6gxsp.internal - β”œ──── private ip: 172.16.6.3 - β””────────── args: /server + β”œ───────── name: httpserver-rust175-tokio-6gxsp + β”œ───────── uuid: d5719f64-0653-42d7-b2de-aa6dee0ce467 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://empty-dawn-3coedrce.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-rust175-tokio@sha256:0ce75912711aa2329232a2ca6c3ccb7a244b6d546fafc081f815c2fde8224856 + β”œ─────── memory: 256 MiB + β”œ────── service: empty-dawn-3coedrce + β”œ─ private fqdn: httpserver-rust175-tokio-6gxsp.internal + β””─── private ip: 10.0.6.3 ``` + + In this case, the instance name is `httpserver-rust175-tokio-6gxsp` and the address is `https://empty-dawn-3coedrce.fra.unikraft.app`. They're different for each run. @@ -96,11 +124,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-rust175-tokio-6gxsp empty-dawn-3coedrce.fra.unikraft.app running 1 minute ago httpserver-rust175-tokio@sha256:0ce75912... 256 MiB 1 /server 21412us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-rust175-tokio-6gxsp running /httpserver-rust175-tokio 256MiB 1 empty-dawn-3coedrce.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-rust175-tokio-6gxsp empty-dawn-3coedrce.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-rust175-tokio@sha256:... 256 MiB 1 21.41 ms ``` + + When done, you can remove the instance: @@ -152,3 +189,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-rust1.81-rocket0.5.mdx b/pages/guides/httpserver-rust1.81-rocket0.5.mdx index b8279190..5830b178 100644 --- a/pages/guides/httpserver-rust1.81-rocket0.5.mdx +++ b/pages/guides/httpserver-rust1.81-rocket0.5.mdx @@ -5,11 +5,14 @@ title: "Rust (Rocket) HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example uses [`Rocket`](https://rocket.rs/), a popular Rust web framework. -To run this example, follow these steps: +To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust1.81-rocket0.5/` directory: @@ -41,34 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-rust1.81-rocket0.5:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-rust1.81-rocket0.5:latest +unikraft build . --output /httpserver-rust181-rocket05:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-rust181-rocket05:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-rust181-rocket05-tuwq3 +uuid: b6fe13e4-93b7-402b-bdec-1bc4d81bc275 +state: starting +image: /httpserver-rust181-rocket05 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: 57da8f4a-5c68-3d4c-3b8f-987ee2ba0fb3 + name: empty-bobo-n3htmpye + domains: + - fqdn: empty-bobo-n3htmpye.fra.unikraft.app +networks: +- uuid: fb33101e-f3b6-0859-38b9-71fb057cab4a + private-ip: 10.0.6.6 + mac: 12:b0:07:e5:d1:fe +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-rust181-rocket05-tuwq3 - β”œ────────── uuid: b6fe13e4-93b7-402b-bdec-1bc4d81bc275 - β”œ───────── state: running - β”œ─────────── url: https://empty-bobo-n3htmpye.fra.unikraft.app - β”œ───────── image: httpserver-rust181-rocket05@sha256:23a7a6e155758e6e8f75e9570f0aec5fb744f08c1bad2454d7386367c5ea45d6 - β”œ───── boot time: 17.41 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: empty-bobo-n3htmpye - β”œ── private fqdn: httpserver-rust181-rocket05-tuwq3.internal - β”œ──── private ip: 172.16.6.6 - β””────────── args: /server + β”œ───────── name: httpserver-rust181-rocket05-tuwq3 + β”œ───────── uuid: b6fe13e4-93b7-402b-bdec-1bc4d81bc275 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://empty-bobo-n3htmpye.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-rust181-rocket05@sha256:23a7a6e155758e6e8f75e9570f0aec5fb744f08c1bad2454d7386367c5ea45d6 + β”œ─────── memory: 256 MiB + β”œ────── service: empty-bobo-n3htmpye + β”œ─ private fqdn: httpserver-rust181-rocket05-tuwq3.internal + β””─── private ip: 10.0.6.6 ``` + + In this case, the instance name is `httpserver-rust181-rocket05-tuwq3` and the address is `https://empty-bobo-n3htmpye.fra.unikraft.app`. They're different for each run. @@ -96,21 +124,30 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-rust181-rocket05-tuwq3 empty-bobo-n3htmpye.fra.unikraft.app running 1 minute ago httpserver-rust181-rocket05@sha256:23a7a6... 256 MiB 1 /server 17412us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-rust181-rocket05-tuwq3 running /httpserver-rust181-rocket05 256MiB 1 empty-bobo-n3htmpye.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-rust181-rocket05-tuwq3 empty-bobo-n3htmpye.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-rust181-rocket05@sha256:... 256 MiB 1 17.41 ms ``` + + When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-rust181-rocket05-tuwq3 +unikraft instances delete httpserver-rust181-rocket05-tuwq3 ``` ```bash title="kraft" -kraft cloud instance remove httpserver-rust181-rocket05-tuwq3 +kraft cloud instance remove httpserver-rust181-rocket05-tuwq3 ``` @@ -152,3 +189,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-rust1.87-actix-web4.mdx b/pages/guides/httpserver-rust1.87-actix-web4.mdx index 82dcd107..8610afcf 100644 --- a/pages/guides/httpserver-rust1.87-actix-web4.mdx +++ b/pages/guides/httpserver-rust1.87-actix-web4.mdx @@ -5,11 +5,14 @@ title: "Rust (Actix Web) HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example uses [`actix-web`](https://actix.rs), a popular Rust web framework. -To run this example, follow these steps: +To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust1.87-actix-web4/` directory: @@ -41,34 +44,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-rust1.87-actix-web4:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/httpserver-rust1.87-actix-web4:latest +unikraft build . --output /httpserver-rust187-actix-web4:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-rust187-actix-web4:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-rust187-actix-web4-3pj27 +uuid: 3e729de6-a1fb-5818-63d4-51a905fa6a5d +state: starting +image: /httpserver-rust187-actix-web4 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: bf564711-3ec0-be8c-64ca-e27c5034d3fe + name: autumn-silence-wupu2nus + domains: + - fqdn: autumn-silence-wupu2nus.fra.unikraft.app +networks: +- uuid: 53417e5b-ae43-6307-d433-9a22c0d249a9 + private-ip: 10.0.3.3 + mac: 12:b0:58:9f:9e:51 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: httpserver-rust187-actix-web4-3pj27 - β”œ────────── uuid:33e9b4ba-58d7-4b3a-b9dd-4c406c0e7b07 - β”œ───────── state: running - β”œ─────────── url: https://autumn-silence-wupu2nus.fra.unikraft.app - β”œ───────── image: httpserver-rust187-actix-web4@sha256:11723705230f0f4545d2be7e4867dc67b396870769e91f05e2fa6d9da94f9b59 - β”œ───── boot time: 11.67 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: autumn-silence-wupu2nus - β”œ── private fqdn: httpserver-rust187-actix-web4-3pj27.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /server + β”œ───────── name: httpserver-rust187-actix-web4-3pj27 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://autumn-silence-wupu2nus.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-rust187-actix-web4@sha256:11723705230f0f4545d2be7e4867dc67b396870769e91f05e2fa6d9da94f9b59 + β”œ─────── memory: 256 MiB + β”œ────── service: autumn-silence-wupu2nus + β”œ─ private fqdn: httpserver-rust187-actix-web4-3pj27.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `httpserver-rust187-actix-web4-3pj27` and the address is `https://autumn-silence-wupu2nus.fra.unikraft.app`. They're different for each run. @@ -98,11 +125,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-rust187-actix-web4-3pj27 autumn-silence-wupu2nus.fra.unikraft.app running 10 minutes ago httpserver-rust187-actix-web4@sha256:117237052305d2be7... 256 MiB 1 /server 11672us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-rust187-actix-web4-3pj27 running /httpserver-rust187-actix-web4 256MiB 1 autumn-silence-wupu2nus.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-rust187-actix-web4-3pj27 autumn-silence-wupu2nus.fra.unikraft.app running 10 minutes ago oci://unikraft.io//httpserver-rust187-actix-web4@sha256:... 256 MiB 1 11.67 ms ``` + + When done, you can remove the instance: @@ -154,3 +190,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-rust1.91.mdx b/pages/guides/httpserver-rust1.91.mdx index 5804978b..d9ff3ed5 100644 --- a/pages/guides/httpserver-rust1.91.mdx +++ b/pages/guides/httpserver-rust1.91.mdx @@ -5,11 +5,14 @@ title: "Rust HTTP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a Rust app. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust1.91` directory: @@ -41,33 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-rust1.91:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 384M --image=/httpserver-rust1.91:latest +unikraft build . --output /httpserver-rust191:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 384M --image /httpserver-rust191:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 384M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 384Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: httpserver-rust191-pinzf +uuid: 8acb3d35-38ba-4929-81de-950340662c14 +state: starting +image: /httpserver-rust191 +resources: + memory: 384MiB + vcpus: 1 +service: + uuid: 3bf42986-3032-1ff2-fe4d-2041db03b628 + name: snowy-feather-k4pfgl8t + domains: + - fqdn: snowy-feather-k4pfgl8t.fra.unikraft.app +networks: +- uuid: d64344f4-e159-c7c3-7f1b-ba10bcc60f67 + private-ip: 10.0.2.53 + mac: 12:b0:1d:12:0e:46 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────── name: httpserver-rust191-pinzf - β”œ────── uuid: 8acb3d35-38ba-4929-81de-950340662c14 - β”œ───── metro: fra - β”œ───── state: starting - β”œ──── domain: https://snowy-feather-k4pfgl8t.fra.unikraft.app - β”œ───── image: httpserver-rust191@sha256:7725556f4db01037438c08d5f934eabe89f33c172b4ae6c7424b3286351619e9 - β”œ──── memory: 384 MiB - β”œ─── service: snowy-feather-k4pfgl8t - β”œ private ip: 10.0.2.53 - β””────── args: /server + β”œ───────── name: httpserver-rust191-pinzf + β”œ───────── uuid: 8acb3d35-38ba-4929-81de-950340662c14 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://snowy-feather-k4pfgl8t.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-rust191@sha256:7725556f4db01037438c08d5f934eabe89f33c172b4ae6c7424b3286351619e9 + β”œ─────── memory: 384 MiB + β”œ────── service: snowy-feather-k4pfgl8t + β”œ─ private fqdn: httpserver-rust191-pinzf.internal + β””─── private ip: 10.0.2.53 ``` + + In this case, the instance name is `httpserver-rust191-pinzf` and the address is `snowy-feather-k4pfgl8t.fra.unikraft.app`. They're different for each run. @@ -95,11 +124,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-rust191-pinzf snowy-feather-k4pfgl8t.fra.unikraft.app standby standby httpserver-rust191@sha256:7725556f4db01037438c08d5f934eabe89f33c172b4ae6... 384 MiB 1 /server 11672us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-rust191-pinzf standby /httpserver-rust191 384MiB 1 snowy-feather-k4pfgl8t.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-rust191-pinzf snowy-feather-k4pfgl8t.fra.unikraft.app standby standby oci://unikraft.io//httpserver-rust191@sha256:... 384 MiB 1 11.67 ms ``` + + When done, you can remove the instance: @@ -131,3 +169,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/hugo0.122.mdx b/pages/guides/hugo0.122.mdx index 5a8563b1..d93606f7 100644 --- a/pages/guides/hugo0.122.mdx +++ b/pages/guides/hugo0.122.mdx @@ -5,12 +5,15 @@ title: "Hugo" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows you how to use [Hugo](https://gohugo.io/commands/hugo_server/), a high performance webserver, with the [ananke](https://github.com/budparr/gohugo-theme-ananke.git) theme. To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/hugo0.122/` directory: @@ -42,34 +45,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /hugo0.122:latest -unikraft run --metro=fra -p 443:1313/tls+http -m 512M --image=/hugo0.122:latest +unikraft build . --output /hugo0122:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:1313/tls+http -m 512M --image /hugo0122:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:1313/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:1313/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: hugo0122-zpabu +uuid: dfc6e06c-76cc-4aa1-a053-c4eded0d2456 +state: starting +image: /hugo0122 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: f5492054-269e-2bcb-1d6c-18b2129c423a + name: morning-rain-jikpfy3t + domains: + - fqdn: morning-rain-jikpfy3t.fra.unikraft.app +networks: +- uuid: 4dd794e8-ee05-6d97-fdc8-b86f92dc1b44 + private-ip: 10.0.6.4 + mac: 12:b0:fe:77:90:47 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: hugo0122-zpabu - β”œ────────── uuid: dfc6e06c-76cc-4aa1-a053-c4eded0d2456 - β”œ───────── state: running - β”œ─────────── url: https://morning-rain-jikpfy3t.fra.unikraft.app - β”œ───────── image: hugo0122@sha256:68d20fdb707076b1cd0f2848b17cc75670d8a92b740edb9417aeb8463fef7f19 - β”œ───── boot time: 77.17 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: morning-rain-jikpfy3t - β”œ── private fqdn: hugo0122-zpabu.internal - β”œ──── private ip: 172.16.6.4 - β””────────── args: /usr/bin/hugo server --bind=0.0.0.0 --source /site + β”œ───────── name: hugo0122-zpabu + β”œ───────── uuid: dfc6e06c-76cc-4aa1-a053-c4eded0d2456 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://morning-rain-jikpfy3t.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//hugo0122@sha256:68d20fdb707076b1cd0f2848b17cc75670d8a92b740edb9417aeb8463fef7f19 + β”œ─────── memory: 512 MiB + β”œ────── service: morning-rain-jikpfy3t + β”œ─ private fqdn: hugo0122-zpabu.internal + β””─── private ip: 10.0.6.4 ``` + + In this case, the instance name is `hugo0122-zpabu` and the address is `https://morning-rain-jikpfy3t.fra.unikraft.app`. They're different for each run. @@ -102,11 +130,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -hugo0122-zpabu morning-rain-jikpfy3t.fra.unikraft.app running 1 minute ago hugo0122@sha256:68d20fdb707076b1cd0f2848b17cc75670d8a... 512 MiB 1 /usr/bin/hugo server --bind=... 77166us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra hugo0122-zpabu running /hugo0122 512MiB 1 morning-rain-jikpfy3t.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +hugo0122-zpabu morning-rain-jikpfy3t.fra.unikraft.app running 1 minute ago oci://unikraft.io//hugo0122@sha256:... 512 MiB 1 77.17 ms ``` + + When done, you can remove the instance: @@ -152,3 +189,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/imaginary.mdx b/pages/guides/imaginary.mdx index 6f230f6f..e38dc34e 100644 --- a/pages/guides/imaginary.mdx +++ b/pages/guides/imaginary.mdx @@ -5,12 +5,15 @@ title: "Imaginary" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example uses [`imaginary`](https://github.com/h2non/imaginary), an HTTP microservice for high-level image processing. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/imaginary/` directory: @@ -43,33 +46,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /imaginary:latest -unikraft run --metro=fra -p 443:8088/tls+http -m 256M --image=/imaginary:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 512M --image /imaginary:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8088/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: imaginary-mwb4y +uuid: 8cf18bf7-2bf6-4f23-be07-f9c234c7962d +state: starting +image: /imaginary +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: b9b7fa60-5f4f-13e5-41e9-eeea476f4398 + name: divine-wind-1ycjvhqs + domains: + - fqdn: divine-wind-1ycjvhqs.fra.unikraft.app +networks: +- uuid: 91467bd9-8d52-a378-4426-7014ca09e5d5 + private-ip: 10.0.3.3 + mac: 12:b0:e2:ed:95:49 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: imaginary-mwb4y - β”œ────────── uuid: 8cf18bf7-2bf6-4f23-be07-f9c234c7962d - β”œ───────── state: running - β”œ─────────── url: https://divine-wind-1ycjvhqs.fra.unikraft.app - β”œ───────── image: imaginary@sha256:673834bc531038bb621266f7fd635a04e559050cbe82876df811fd4b975ea4fe - β”œ───── boot time: 32.26 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: divine-wind-1ycjvhqs - β”œ── private fqdn: imaginary-mwb4y.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/imaginary -p 8080 + β”œ───────── name: imaginary-mwb4y + β”œ───────── uuid: 8cf18bf7-2bf6-4f23-be07-f9c234c7962d + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://divine-wind-1ycjvhqs.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//imaginary@sha256:673834bc531038bb621266f7fd635a04e559050cbe82876df811fd4b975ea4fe + β”œ─────── memory: 512 MiB + β”œ────── service: divine-wind-1ycjvhqs + β”œ─ private fqdn: imaginary-mwb4y.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `imaginary-mwb4y` and the address is `https://divine-wind-1ycjvhqs.fra.unikraft.app`. They're different for each run. @@ -115,11 +143,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -imaginary-mwb4y divine-wind-1ycjvhqs.fra.unikraft.app running 54 seconds ago imaginary@sha256:673834bc531038bb621266f7... 256 MiB 1 /usr/bin/imaginary -p 8080 32262us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra imaginary-mwb4y running /imaginary 512MiB 1 divine-wind-1ycjvhqs.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +imaginary-mwb4y divine-wind-1ycjvhqs.fra.unikraft.app running 54 seconds ago oci://unikraft.io//imaginary@sha256:... 512 MiB 1 32.26 ms ``` + + When done, you can remove the instance: @@ -138,9 +175,9 @@ The Imaginary Unikraft Cloud service works as is: you deploy it and then you que You can customize the command line options used to start the service, by updating the `cmd` line in the `Kraftfile`: ```yaml -spec: v0.6 +spec: v0.7 -runtime: imaginary:1.2 +runtime: base-compat:latest cmd: ["/usr/bin/imaginary", "-p", "8080"] ``` @@ -164,3 +201,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/mariadb.mdx b/pages/guides/mariadb.mdx index a208e25f..4d34f883 100644 --- a/pages/guides/mariadb.mdx +++ b/pages/guides/mariadb.mdx @@ -5,11 +5,14 @@ title: "MariaDB" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows you how to use [MariaDB](https://mariadb.org), one of the most popular open source relational databases. To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/mariadb/` directory: @@ -42,33 +45,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /mariadb:latest -unikraft run --metro=fra -p 3306:3306/tls -m 1G -e MARIADB_ROOT_PASSWORD="unikraft" --image=/mariadb:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 3306:3306/tls -m 1G -e MARIADB_ROOT_PASSWORD="unikraft" --image /mariadb:latest ``` ```bash title="kraft" -kraft cloud deploy -p 3306:3306/tls -M 1G --env MARIADB_ROOT_PASSWORD="unikraft" . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 3306:3306/tls -M 1Gi --env MARIADB_ROOT_PASSWORD="unikraft" . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: mariadb-w2g2z +uuid: ba696c22-adff-4fba-88b9-d1b790ca2357 +state: starting +image: /mariadb +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: ca8ae7e9-3767-85f6-3d70-b77bcf894a7c + name: twilight-sun-82lt4ddk + domains: + - fqdn: twilight-sun-82lt4ddk.fra.unikraft.app +networks: +- uuid: 935ba4ef-39c2-07e7-d2ae-8cd3c9aae07c + private-ip: 10.0.6.3 + mac: 12:b0:ee:29:71:e4 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: mariadb-w2g2z - β”œ────────── uuid: ba696c22-adff-4fba-88b9-d1b790ca2357 - β”œ───────── state: running - β”œ────────── fqdn: twilight-sun-82lt4ddk.fra.unikraft.app - β”œ───────── image: mariadb@sha256:6e31d28b351eb12a070e3074f0a500532d0a494332947e9d8dbfa093d2d551fd - β”œ───── boot time: 159.06 ms - β”œ──────── memory: 1024 MiB - β”œ─────── service: twilight-sun-82lt4ddk - β”œ── private fqdn: mariadb-w2g2z.internal - β”œ──── private ip: 172.16.6.3 - β””────────── args: /usr/sbin/mariadbd --user=root --log-bin + β”œ───────── name: mariadb-w2g2z + β”œ───────── uuid: ba696c22-adff-4fba-88b9-d1b790ca2357 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://twilight-sun-82lt4ddk.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//mariadb@sha256:6e31d28b351eb12a070e3074f0a500532d0a494332947e9d8dbfa093d2d551fd + β”œ─────── memory: 1024 MiB + β”œ────── service: twilight-sun-82lt4ddk + β”œ─ private fqdn: mariadb-w2g2z.internal + β””─── private ip: 10.0.6.3 ``` + + In this case, the instance name is `mariadb-w2g2z` which is different for each run. To test the deployment, first forward the port with the `kraft cloud tunnel` command. @@ -119,15 +147,20 @@ kraft cloud instance list -```bash -kraft cloud instance list + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra mariadb-w2g2z running /mariadb 1024MiB 1 twilight-sun-82lt4ddk.fra.unikraft.app 2 minutes ago ``` -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -mariadb-w2g2z twilight-sun-82lt4ddk.fra.unikraft.app running 1 minute ago mariadb@s... 1.0 GiB 1 /usr/sbin/mariadbd --user=ro... 159065us +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +mariadb-w2g2z twilight-sun-82lt4ddk.fra.unikraft.app running 1 minute ago oci://unikraft.io//mariadb@sha256... 1.0 GiB 1 159.06 ms ``` + + When done, you can remove the instance: @@ -153,11 +186,11 @@ For that you would first create a volume: ```bash title="unikraft" -unikraft volume create --set name=mariadb-store --set size=512M +unikraft volume create --set metro=fra --set name=mariadb-store --set size=512M ``` ```bash title="kraft" -kraft cloud volume create --name mariadb-store --size 512 +kraft cloud volume create --name mariadb-store --size 512Mi ``` @@ -168,11 +201,11 @@ Then start the MariaDB instance and mount that volume: ```bash title="unikraft" unikraft build . --output /mariadb:latest -unikraft run --metro=fra -p 3306:3306/tls -m 1G -e MARIADB_ROOT_PASSWORD="unikraft" --volume mariadb-store:/var/lib --image=/mariadb:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 3306:3306/tls -m 1G -e MARIADB_ROOT_PASSWORD="unikraft" --volume mariadb-store:/var/lib --image /mariadb:latest ``` ```bash title="kraft" -kraft cloud deploy -M 1G -p 3306:3306/tls --env MARIADB_ROOT_PASSWORD="unikraft" --volume mariadb-store:/var/lib . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -M 1Gi -p 3306:3306/tls --env MARIADB_ROOT_PASSWORD="unikraft" --volume mariadb-store:/var/lib . ``` @@ -201,3 +234,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/mcp-server-arxiv.mdx b/pages/guides/mcp-server-arxiv.mdx index 36dfa504..6ca422af 100644 --- a/pages/guides/mcp-server-arxiv.mdx +++ b/pages/guides/mcp-server-arxiv.mdx @@ -5,6 +5,7 @@ title: "ArXiv MCP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example demonstrates how to deploy the [ArXiv MCP server](https://github.com/blazickjp/arxiv-mcp-server) on Unikraft Cloud. The ArXiv MCP Server is a third-party library that provides stdio-based MCP tools for accessing arXiv research papers. @@ -21,8 +22,10 @@ The server gives AI agents and assistants the ability to: To run this MCP server on Unikraft Cloud: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/mcp-server-arxiv/` directory: @@ -55,32 +58,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /mcp-server-arxiv:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 2G --image=/mcp-server-arxiv:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 2G --image /mcp-server-arxiv:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 2G . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 2Gi . ``` The output shows your instance details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: mcp-server-arxiv-l7l24 +uuid: 1a721bb8-4472-4149-9870-789b1df5f80a +state: starting +image: /mcp-server-arxiv +resources: + memory: 2048MiB + vcpus: 1 +service: + uuid: 94b10356-3df8-b2fa-cd17-60ca8193c86c + name: billowing-breeze-nuusy7l2 + domains: + - fqdn: billowing-breeze-nuusy7l2.fra.unikraft.app +networks: +- uuid: e6754486-5398-bb06-420e-de23ed73da3f + private-ip: 10.0.1.149 + mac: 12:b0:26:13:a0:89 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ─────── name: mcp-server-arxiv-l7l24 - β”œ─────── uuid: 1a721bb8-4472-4149-9870-789b1df5f80a - β”œ────── metro: https://api.fra.unikraft.cloud/v1 - β”œ────── state: starting - β”œ───── domain: https://billowing-breeze-nuusy7l2.fra.unikraft.app - β”œ────── image: mcp-server-arxiv@sha256:ea1e677ccc03628a3e7d57a4cd41118e3d2a631bcb2c34203bb9b175e7977f00 - β”œ───── memory: 2048 MiB - β”œ──── service: billowing-breeze-nuusy7l2 - β”œ─ private ip: 10.0.1.149 - β””─────── args: /usr/local/bin/python /src/server.py + β”œ───────── name: mcp-server-arxiv-l7l24 + β”œ───────── uuid: 1a721bb8-4472-4149-9870-789b1df5f80a + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://billowing-breeze-nuusy7l2.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//mcp-server-arxiv@sha256:ea1e677ccc03628a3e7d57a4cd41118e3d2a631bcb2c34203bb9b175e7977f00 + β”œ─────── memory: 2048 MiB + β”œ────── service: billowing-breeze-nuusy7l2 + β”œ─ private fqdn: mcp-server-arxiv-l7l24.internal + β””─── private ip: 10.0.1.149 ``` + + In this case, the instance name is `mcp-server-arxiv-l7l24` and the service `billowing-breeze-nuusy7l2`. They're different for each run. @@ -115,11 +144,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -mcp-server-arxiv-l7l24 billowing-breeze-nuusy7l2.fra.unikraft.app standby standby mcp-server-arxiv@sha256:ea1e677ccc03628a3e7d57a4cd41118e3d2a63... 2.0 GiB 1 /usr/bin/python3 /src/server.py 213.07 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra mcp-server-arxiv-l7l24 standby /mcp-server-arxiv 2.0GiB 1 billowing-breeze-nuusy7l2.fra.unikraf… 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +mcp-server-arxiv-l7l24 billowing-breeze-nuusy7l2.fra.unikraft.app standby standby oci://unikraft.io//mcp-server-arxiv@sha256:... 2.0 GiB 1 213.07 ms ``` + + When done, you can delete the instance with: ```bash @@ -134,11 +172,11 @@ For that you would first create a volume: ```bash title="unikraft" -unikraft volume create --set metro=fra --set name=mcp-server-arxiv-data --set size=500 +unikraft volume create --set metro=fra --set name=mcp-server-arxiv-data --set size=500M ``` ```bash title="kraft" -kraft cloud volume create --name mcp-server-arxiv-data --size 500 +kraft cloud volume create --name mcp-server-arxiv-data --size 500Mi ``` @@ -149,11 +187,11 @@ Then start the MCP server instance and mount that volume (while specifying the s ```bash title="unikraft" unikraft build . --output /mcp-server-arxiv:latest -unikraft run --metro=fra -v mcp-server-arxiv-data:/volume -p 443:8080/tls+http -m 2G --image=/mcp-server-arxiv:latest -- "/usr/local/bin/python /src/server.py --storage-path /volume" +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -v mcp-server-arxiv-data:/volume -p 443:8080/tls+http -m 2G --image /mcp-server-arxiv:latest -- "/usr/local/bin/python /src/server.py --storage-path /volume" ``` ```bash title="kraft" -kraft cloud deploy -v mcp-server-arxiv-data:/volume -p 443:8080/tls+http -M 2G . --entrypoint "/usr/local/bin/python /src/server.py --storage-path /volume" +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -v mcp-server-arxiv-data:/volume -p 443:8080/tls+http -M 2Gi . --entrypoint "/usr/local/bin/python /src/server.py --storage-path /volume" ``` @@ -190,3 +228,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/mcp-server-simple.mdx b/pages/guides/mcp-server-simple.mdx index 3b67e84a..db8ad678 100644 --- a/pages/guides/mcp-server-simple.mdx +++ b/pages/guides/mcp-server-simple.mdx @@ -5,6 +5,7 @@ title: "Simple MCP Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example demonstrates how to build a minimal custom MCP (Model Context Protocol) server from scratch using [FastMCP 2.0](https://github.com/jlowin/fastmcp). This is a great starting point for building your own custom MCP servers with business-specific tools and logic. @@ -13,8 +14,10 @@ This is a great starting point for building your own custom MCP servers with bus To run this MCP server on Unikraft Cloud: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/mcp-server-simple/` directory: @@ -47,33 +50,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /mcp-server-simple:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/mcp-server-simple:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 512M --image /mcp-server-simple:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . ``` The output shows your instance details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: mcp-server-simple-bbdcb +uuid: e87d3591-3497-4f30-bd76-1dc886059647 +state: starting +image: /mcp-server-simple +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 3cfc78af-748d-c6ba-5bfb-427b3bd7e9aa + name: cool-paper-b6mht7jv + domains: + - fqdn: cool-paper-b6mht7jv.fra.unikraft.app +networks: +- uuid: 6a712117-5b67-d89a-7e2e-4a57e1732724 + private-ip: 10.0.0.193 + mac: 12:b0:39:2b:a3:15 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────── name: mcp-server-simple-bbdcb - β”œ────── uuid: e87d3591-3497-4f30-bd76-1dc886059647 - β”œ───── metro: https://api.fra.unikraft.cloud/v1 - β”œ───── state: running - β”œ──── domain: https://cool-paper-b6mht7jv.fra.unikraft.app - β”œ───── image: mcp-server-simple@sha256:cbbfb441ee313a6c7c0de571e9002f0f6031312e203ffb6be3b8f4950df3bc20 - β”œ─ boot time: 145.96 ms - β”œ──── memory: 512 MiB - β”œ─── service: cool-paper-b6mht7jv - β”œ private ip: 10.0.0.193 - β””────── args: /usr/bin/python3 /src/server.py + β”œ───────── name: mcp-server-simple-bbdcb + β”œ───────── uuid: e87d3591-3497-4f30-bd76-1dc886059647 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://cool-paper-b6mht7jv.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//mcp-server-simple@sha256:cbbfb441ee313a6c7c0de571e9002f0f6031312e203ffb6be3b8f4950df3bc20 + β”œ─────── memory: 512 MiB + β”œ────── service: cool-paper-b6mht7jv + β”œ─ private fqdn: mcp-server-simple-bbdcb.internal + β””─── private ip: 10.0.0.193 ``` + + In this case, the instance name is `mcp-server-simple-bbdcb` and the service `cool-paper-b6mht7jv`. They're different for each run. @@ -117,11 +145,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -mcp-server-simple-bbdcb cool-paper-b6mht7jv.fra.unikraft.app standby standby mcp-server-simple@sha256:cbbfb441ee313a6c7c0de5... 512 MiB 1 /usr/bin/python3 /src/server.py 9.15 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra mcp-server-simple-bbdcb standby /mcp-server-simple 512MiB 1 cool-paper-b6mht7jv.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +mcp-server-simple-bbdcb cool-paper-b6mht7jv.fra.unikraft.app standby standby oci://unikraft.io//mcp-server-simple@sha256:... 512 MiB 1 9.15 ms ``` + + When done, you can delete the instance with: ```bash @@ -220,3 +257,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/memcached1.6.mdx b/pages/guides/memcached1.6.mdx index 7bd17bb6..81f8b31c 100644 --- a/pages/guides/memcached1.6.mdx +++ b/pages/guides/memcached1.6.mdx @@ -5,13 +5,16 @@ title: "Memcached" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows you how to use [Memcached](https://memcached.org). Memcached is an in-memory key-value store for small chunks of arbitrary data (strings, objects) from results of database calls, API calls, or page rendering. To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/memcached1.6/` directory: @@ -43,34 +46,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /memcached1.6:latest -unikraft run --metro=fra -p 11211:11211/tls -m 256M --image=/memcached1.6:latest +unikraft build . --output /memcached16:latest +unikraft run --scale-to-zero policy=off --metro fra -p 11211:11211/tls -m 256M --image /memcached16:latest ``` ```bash title="kraft" -kraft cloud deploy -p 11211:11211/tls -M 256M . +kraft cloud deploy --scale-to-zero off -p 11211:11211/tls -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: memcached16-arkv7 +uuid: da436eca-bc64-46d7-a04c-72832652b10e +state: starting +image: /memcached16 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: ce58c122-62e5-b82d-955d-63053dbc13ec + name: weathered-smoke-hehsdinv + domains: + - fqdn: weathered-smoke-hehsdinv.fra.unikraft.app +networks: +- uuid: 1e9e37f9-1ba5-7c92-350e-f399db32d93d + private-ip: 10.0.6.5 + mac: 12:b0:e3:15:81:6b +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: memcached16-arkv7 - β”œ────────── uuid: da436eca-bc64-46d7-a04c-72832652b10e - β”œ───────── state: running - β”œ────────── fqdn: weathered-smoke-hehsdinv.fra.unikraft.app - β”œ───────── image: memcached16@sha256:f53cdbce4dc185e8acc8ecb93a0ab0ba99085ca0837a0ad2062aae9e31382e58 - β”œ───── boot time: 19.27 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: weathered-smoke-hehsdinv - β”œ── private fqdn: memcached16-arkv7.internal - β”œ──── private ip: 172.16.6.5 - β””────────── args: /usr/bin/memcached -u root + β”œ───────── name: memcached16-arkv7 + β”œ───────── uuid: da436eca-bc64-46d7-a04c-72832652b10e + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://weathered-smoke-hehsdinv.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//memcached16@sha256:f53cdbce4dc185e8acc8ecb93a0ab0ba99085ca0837a0ad2062aae9e31382e58 + β”œ─────── memory: 256 MiB + β”œ────── service: weathered-smoke-hehsdinv + β”œ─ private fqdn: memcached16-arkv7.internal + β””─── private ip: 10.0.6.5 ``` + + In this case, the instance name is `memcached16-arkv7` which is different for each run. To test the deployment, first forward the port with the `kraft cloud tunnel` command: @@ -119,11 +147,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -memcached16-arkv7 weathered-smoke-hehsdinv.fra.unikraft.app running 11 minutes ago memcached16@sha256:f53cdbce4... 256 MiB 1 /usr/bin/memcached -u root 19266us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra memcached16-arkv7 running /memcached16 256MiB 1 weathered-smoke-hehsdinv.fra.unikraft… 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +memcached16-arkv7 weathered-smoke-hehsdinv.fra.unikraft.app running 11 minutes ago oci://unikraft.io//memcached16@sha256:... 256 MiB 1 19.27 ms ``` + + When done, you can remove the instance: @@ -162,3 +199,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/minio.mdx b/pages/guides/minio.mdx index d1838f01..9166db1a 100644 --- a/pages/guides/minio.mdx +++ b/pages/guides/minio.mdx @@ -5,13 +5,16 @@ title: "Minio" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows you how to use [MinIO](https://min.io), a High Performance Object Storage which is Open Source, Amazon S3 compatible, Kubernetes Native and works for cloud native workloads like AI. To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/minio/` directory: @@ -44,33 +47,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /minio:latest -unikraft run --metro=fra -p 443:9001/tls+http -p 9000:9000/tls -m 512M --image=/minio:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:9001/tls+http -p 9000:9000/tls -m 512M --image /minio:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:9001/tls+http -p 9000:9000/tls -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:9001/tls+http -p 9000:9000/tls -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: minio-w2my8 +uuid: 31e691ad-05a0-48b6-ad49-7f79da8e1754 +state: starting +image: /minio +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 8fdad5ff-9276-5f35-f94e-3d9d9b244a15 + name: icy-bird-tregaga9 + domains: + - fqdn: icy-bird-tregaga9.fra.unikraft.app +networks: +- uuid: f3a7d1f6-b1ca-68d0-6b45-7e9179ad0966 + private-ip: 10.0.6.4 + mac: 12:b0:44:5e:b0:54 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: minio-w2my8 - β”œ────────── uuid: 31e691ad-05a0-48b6-ad49-7f79da8e1754 - β”œ───────── state: running - β”œ─────────── url: https://icy-bird-tregaga9.fra.unikraft.app - β”œ───────── image: minio@sha256:ba4657c607495326b0e29b512fb33a4179cd1b2a15fbfdd3ccc6e66209a701dd - β”œ───── boot time: 73.65 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: icy-bird-tregaga9 - β”œ── private fqdn: minio-w2my8.internal - β”œ──── private ip: 172.16.6.4 - β””────────── args: /usr/bin/minio server --address 0.0.0.0:9000 --console-address 0.0.0.0:9001 /data + β”œ───────── name: minio-w2my8 + β”œ───────── uuid: 31e691ad-05a0-48b6-ad49-7f79da8e1754 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://icy-bird-tregaga9.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//minio@sha256:ba4657c607495326b0e29b512fb33a4179cd1b2a15fbfdd3ccc6e66209a701dd + β”œ─────── memory: 512 MiB + β”œ────── service: icy-bird-tregaga9 + β”œ─ private fqdn: minio-w2my8.internal + β””─── private ip: 10.0.6.4 ``` + + In this case, the instance name is `minio-w2my8` and the address is `https://icy-bird-tregaga9.fra.unikraft.app`. They're different for each run. @@ -91,11 +119,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -minio-w2my8 icy-bird-tregaga9.fra.unikraft.app running 1 minute ago minio@sha256:ba4657c607495326b0e29b51... 512 MiB 1 /usr/bin/minio server --addres... 73651us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra minio-w2my8 running /minio 512MiB 1 icy-bird-tregaga9.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +minio-w2my8 icy-bird-tregaga9.fra.unikraft.app running 1 minute ago oci://unikraft.io//minio@sha256:... 512 MiB 1 73.65 ms ``` + + When done, you can remove the instance: @@ -134,3 +171,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/mongodb.mdx b/pages/guides/mongodb.mdx index 48c6f1c6..844dbd29 100644 --- a/pages/guides/mongodb.mdx +++ b/pages/guides/mongodb.mdx @@ -5,12 +5,15 @@ title: "MongoDB" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows you how to use [MongoDB](https://www.mongodb.com), a source-available, cross-platform, document-oriented database program. To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/mongodb/` directory: @@ -43,57 +46,73 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /mongodb:latest -unikraft run --metro=fra -p 27017:27017/tls -m 1G --image=/mongodb:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 27017:27017/tls -m 1G --image /mongodb:latest ``` ```bash title="kraft" -kraft cloud deploy -p 27017:27017/tls -M 1G . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 27017:27017/tls -M 1Gi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: mongodb-6tiuu +uuid: 99779597-0bdb-4160-b902-a160c3ab4b2a +state: starting +image: /mongodb +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: 91309c0c-fd6f-271d-cab6-2694b0991fbe + name: bold-brook-khkwv7of + domains: + - fqdn: bold-brook-khkwv7of.fra.unikraft.app +networks: +- uuid: 24cc79e5-bb3f-cdcd-fd5d-e4605015a228 + private-ip: 10.0.6.4 + mac: 12:b0:d7:7b:83:97 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: mongodb-6tiuu - β”œ────────── uuid: 99779597-0bdb-4160-b902-a160c3ab4b2a - β”œ───────── state: running - β”œ────────── fqdn: bold-brook-khkwv7of.fra.unikraft.app - β”œ───────── image: mongodb@sha256:e6ff5153f106e2d5e2a10881818cd1b90fe3ff1294ad80879b2239ffc52aff0e - β”œ───── boot time: 82.41 ms - β”œ──────── memory: 1024 MiB - β”œ─────── service: bold-brook-khkwv7of - β”œ── private fqdn: mongodb-6tiuu.internal - β”œ──── private ip: 172.16.6.4 - β””────────── args: /usr/bin/mongod --bind_ip_all --nounixsocket + β”œ───────── name: mongodb-6tiuu + β”œ───────── uuid: 99779597-0bdb-4160-b902-a160c3ab4b2a + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://bold-brook-khkwv7of.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//mongodb@sha256:e6ff5153f106e2d5e2a10881818cd1b90fe3ff1294ad80879b2239ffc52aff0e + β”œ─────── memory: 1024 MiB + β”œ────── service: bold-brook-khkwv7of + β”œ─ private fqdn: mongodb-6tiuu.internal + β””─── private ip: 10.0.6.4 ``` -In this case, the instance name is `mongodb-6tiuu` which is different for each run. - -To test the deployment, first forward the port with the `kraft cloud tunnel` command: - -```bash -kraft cloud tunnel 27017:mongodb-6tiuu:27017 -``` + -The `kraft cloud tunnel` command is only supported by the legacy CLI. +In this case, the instance name is `mongodb-6tiuu` and the the address is +`bold-brook-khkwv7of.fra.unikraft.app` which is different for each run. -Then, on a separate console, you can use the `mongosh` client to connect to the server: +You can use the mongosh client to connect to the server: ```console -mongosh mongodb://localhost +mongosh "mongodb://bold-brook-khkwv7of.fra.unikraft.app:27017/?tls=true" ``` You should see output like: ```console -Current Mongosh Log ID: 65d75b96310f70e63565e0f1 -Connecting to: mongodb://localhost/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.1.5 -(node:79750) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead. -(Use `node --trace-deprecation ...` to show where the warning was created) -Using MongoDB: 6.0.13 -Using Mongosh: 2.1.5 +Current Mongosh Log ID: 69d7a077dc5d28998344ba88 +Connecting to: mongodb://bold-brook-khkwv7of.fra.unikraft.app:27017/?tls=true&directConnection=true&appName=mongosh+2.8.2 +Using MongoDB: 6.0.13 +Using Mongosh: 2.8.2 For mongosh info see: https://docs.mongodb.com/mongodb-shell/ @@ -103,14 +122,6 @@ You can opt-out by running the disableTelemetry() command. test> ``` -To disconnect, kill the `tunnel` command with `Ctrl+c`. - -> **Note:** -> This guide uses `kraft cloud tunnel` only when a service doesn't support TLS and isn't HTTP-based (TLS/SNI determines the correct instance to send traffic to). -> Also note that the `tunnel` command isn't needed when connecting via an -> instance's private IP/FQDN. -> For example when a MongoDB instance serves as a database server to another instance that acts as a frontend and which **does** support TLS. - You can list information about the instance by running: @@ -125,11 +136,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -mongodb-6tiuu bold-brook-khkwv7of.fra.unikraft.app running 20 minutes ago mongodb@sha256:e6ff5153f106e2... 1.0 GiB 1 /usr/bin/mongod --bind_ip_all... 82410us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra mongodb-6tiuu running /mongodb 1.0GiB 1 bold-brook-khkwv7of.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +mongodb-6tiuu bold-brook-khkwv7of.fra.unikraft.app running 20 minutes ago oci://unikraft.io//mongodb@sha256:... 1.0 GiB 1 82.41 ms ``` + + When done, you can remove the instance: @@ -144,6 +164,38 @@ kraft cloud instance remove mongodb-6tiuu +## Using volumes + +You can use [volumes](/platform/volumes) for data persistence for your MongoDB instance. +For that you would first create a volume: + + + +```bash title="unikraft" +unikraft volume create --set metro=fra --set name=mongodb-store --set size=512M +``` + +```bash title="kraft" +kraft cloud volume create --name mongodb-store --size 512Mi +``` + + + +Then start the MongoDB instance and mount that volume: + + + +```bash title="unikraft" +unikraft build . --output /mongodb:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 27017:27017/tls -m 1G --volume mongodb-store:/data/db --image /mongodb:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -M 1Gi -p 27017:27017/tls --volume mongodb-store:/data/db . +``` + + + ## Customize your app To customize the app, update the files in the repository, listed below: @@ -168,3 +220,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/nginx.mdx b/pages/guides/nginx.mdx index 49947914..cc48c3f9 100644 --- a/pages/guides/nginx.mdx +++ b/pages/guides/nginx.mdx @@ -5,13 +5,16 @@ title: "Nginx" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example uses [`Nginx`](https://nginx.org), one of the most popular web servers. Nginx can be used with Unikraft / Unikraft Cloud to serve static web content. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/nginx/` directory: @@ -44,33 +47,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /nginx:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 256M --image=/nginx:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /nginx:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: nginx-67zbu +uuid: 8a8bc1b9-0af6-420e-a426-190dc2da9eaa +state: starting +image: /nginx +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: a942b9b5-ad17-3ffe-dcd2-ef4331f9087a + name: nameless-fog-0tvh1uov + domains: + - fqdn: nameless-fog-0tvh1uov.fra.unikraft.app +networks: +- uuid: 62d9bbf0-aec8-61f6-7bdb-86edf63dd068 + private-ip: 10.0.3.3 + mac: 12:b0:c6:23:ed:15 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: nginx-67zbu - β”œ────────── uuid: 8a8bc1b9-0af6-420e-a426-190dc2da9eaa - β”œ───────── state: running - β”œ─────────── url: https://nameless-fog-0tvh1uov.fra.unikraft.app - β”œ───────── image: nginx@sha256:f51ecc121c9ca34abb88a2bc6a69765501304f7893f7e85af15fbec3dc86e2bd - β”œ───── boot time: 11.13ms - β”œ──────── memory: 256 MiB - β”œ─────── service: nameless-fog-0tvh1uov - β”œ── private fqdn: nginx-67zbu.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/nginx -c /etc/nginx/nginx.conf + β”œ───────── name: nginx-67zbu + β”œ───────── uuid: 8a8bc1b9-0af6-420e-a426-190dc2da9eaa + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://nameless-fog-0tvh1uov.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//nginx@sha256:f51ecc121c9ca34abb88a2bc6a69765501304f7893f7e85af15fbec3dc86e2bd + β”œ─────── memory: 256 MiB + β”œ────── service: nameless-fog-0tvh1uov + β”œ─ private fqdn: nginx-67zbu.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `nginx-67zbu` and the address is `https://nameless-fog-0tvh1uov.fra.unikraft.app`. They're different for each run. @@ -102,11 +130,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -nginx-67zbu nameless-fog-0tvh1uov.fra.unikraft.app running 5 minutes ago nginx@sha256:f51ecc121c9ca34abb... 256 MiB 1 /usr/bin/nginx -c /etc/nginx/nginx.conf 11129us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra nginx-67zbu running /nginx 256MiB 1 nameless-fog-0tvh1uov.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +nginx-67zbu nameless-fog-0tvh1uov.fra.unikraft.app running 5 minutes ago oci://unikraft.io//nginx@sha256:... 256 MiB 1 11.13 ms ``` + + When done, you can remove the instance: @@ -168,3 +205,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/node-playwright-chromium.mdx b/pages/guides/node-playwright-chromium.mdx new file mode 100644 index 00000000..d6c25b85 --- /dev/null +++ b/pages/guides/node-playwright-chromium.mdx @@ -0,0 +1,180 @@ +--- +title: "Playwright (Chromium) with Node.js" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +[Playwright](https://playwright.dev/) is a framework for web testing and Automation. + +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node-playwright-chromium/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/node-playwright-chromium/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /node-playwright-chromium:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 4G --image /node-playwright-chromium:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 4Gi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: node-playwright-chromium-v5f8p +uuid: a1b2c3d4-e5f6-7a8b-9c0d-a1b2c3d4e5f6 +state: starting +image: /node-playwright-chromium +resources: + memory: 4096MiB + vcpus: 1 +service: + uuid: b2c3d4e5-f6a7-8b9c-0d1e-b2c3d4e5f6a7 + name: gentle-moon-cx2jh5wd + domains: + - fqdn: gentle-moon-cx2jh5wd.fra.unikraft.app +networks: +- uuid: c3d4e5f6-a7b8-9c0d-1e2f-c3d4e5f6a7b8 + private-ip: 10.0.4.3 + mac: 12:b0:8e:5a:cd:b7 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: node-playwright-chromium-v5f8p + β”œ───────── uuid: a1b2c3d4-e5f6-7a8b-9c0d-a1b2c3d4e5f6 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://gentle-moon-cx2jh5wd.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//node-playwright-chromium@sha256:7c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d + β”œ─────── memory: 4096 MiB + β”œ────── service: gentle-moon-cx2jh5wd + β”œ─ private fqdn: node-playwright-chromium-v5f8p.internal + β””─── private ip: 10.0.4.3 +``` + + + +In this case, the instance name is `node-playwright-chromium-v5f8p` and the address is `https://gentle-moon-cx2jh5wd.fra.unikraft.app`. +They're different for each run. + +The command will deploy the files in the current directory. +It results in the creation of a remote web-based service for creating PNG screenshots of remote pages. + +Use the `?page=` to point the service to the remote page to screenshot. +Query the service using commands such as: + +```console +curl "https://..unikraft.app/?page=https://google.com" -o ss-google.png +curl "https://..unikraft.app/?page=https://bing.com" -o ss-bing.png +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra node-playwright-chromium-v5f8p running /node-playwright-chromium 4096MiB 1 gentle-moon-cx2jh5wd.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +node-playwright-chromium-v5f8p gentle-moon-cx2jh5wd.fra.unikraft.app running 1 minute ago oci://unikraft.io//node-playwright-chromium@sha256:... 4 GiB 1 300.21 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + + +## Learn more + +- [Playwright's Documentation](https://playwright.dev/docs/intro) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) +- [Building `Dockerfile` Images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/node-playwright-firefox.mdx b/pages/guides/node-playwright-firefox.mdx new file mode 100644 index 00000000..4a7b986e --- /dev/null +++ b/pages/guides/node-playwright-firefox.mdx @@ -0,0 +1,180 @@ +--- +title: "Playwright (Firefox) with Node.js" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +[Playwright](https://playwright.dev/) is a framework for web testing and Automation. + +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node-playwright-firefox/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/node-playwright-firefox/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /node-playwright-firefox:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 4G --image /node-playwright-firefox:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 4Gi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: node-playwright-firefox-q3m9k +uuid: d4e5f6a7-b8c9-0d1e-2f3a-d4e5f6a7b8c9 +state: starting +image: /node-playwright-firefox +resources: + memory: 4096MiB + vcpus: 1 +service: + uuid: e5f6a7b8-c9d0-1e2f-3a4b-e5f6a7b8c9d0 + name: bright-lake-dh6xp2sq + domains: + - fqdn: bright-lake-dh6xp2sq.fra.unikraft.app +networks: +- uuid: f6a7b8c9-d0e1-2f3a-4b5c-f6a7b8c9d0e1 + private-ip: 10.0.5.3 + mac: 12:b0:9f:6b:de:c8 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: node-playwright-firefox-q3m9k + β”œ───────── uuid: d4e5f6a7-b8c9-0d1e-2f3a-d4e5f6a7b8c9 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://bright-lake-dh6xp2sq.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//node-playwright-firefox@sha256:8d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e + β”œ─────── memory: 4096 MiB + β”œ────── service: bright-lake-dh6xp2sq + β”œ─ private fqdn: node-playwright-firefox-q3m9k.internal + β””─── private ip: 10.0.5.3 +``` + + + +In this case, the instance name is `node-playwright-firefox-q3m9k` and the address is `https://bright-lake-dh6xp2sq.fra.unikraft.app`. +They're different for each run. + +The command will deploy the files in the current directory. +It results in the creation of a remote web-based service for creating PNG screenshots of remote pages. + +Use the `?page=` to point the service to the remote page to screenshot. +Query the service using commands such as: + +```console +curl "https://..unikraft.app/?page=https://google.com" -o ss-google.png +curl "https://..unikraft.app/?page=https://bing.com" -o ss-bing.png +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra node-playwright-firefox-q3m9k running /node-playwright-firefox 4096MiB 1 bright-lake-dh6xp2sq.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +node-playwright-firefox-q3m9k bright-lake-dh6xp2sq.fra.unikraft.app running 1 minute ago oci://unikraft.io//node-playwright-firefox@sha256:... 4 GiB 1 350.87 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + + +## Learn more + +- [Playwright's Documentation](https://playwright.dev/docs/intro) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) +- [Building `Dockerfile` Images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/node-playwright-webkit.mdx b/pages/guides/node-playwright-webkit.mdx new file mode 100644 index 00000000..7357ecf7 --- /dev/null +++ b/pages/guides/node-playwright-webkit.mdx @@ -0,0 +1,180 @@ +--- +title: "Playwright (WebKit) with Node.js" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +[Playwright](https://playwright.dev/) is a framework for web testing and Automation. + +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node-playwright-webkit/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/node-playwright-webkit/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /node-playwright-webkit:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 4G --image /node-playwright-webkit:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 4Gi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: node-playwright-webkit-t7r2j +uuid: a2b3c4d5-e6f7-8a9b-0c1d-a2b3c4d5e6f7 +state: starting +image: /node-playwright-webkit +resources: + memory: 4096MiB + vcpus: 1 +service: + uuid: b3c4d5e6-f7a8-9b0c-1d2e-b3c4d5e6f7a8 + name: silent-fog-er8np3fb + domains: + - fqdn: silent-fog-er8np3fb.fra.unikraft.app +networks: +- uuid: c4d5e6f7-a8b9-0c1d-2e3f-c4d5e6f7a8b9 + private-ip: 10.0.6.4 + mac: 12:b0:a0:7c:ef:d9 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: node-playwright-webkit-t7r2j + β”œ───────── uuid: a2b3c4d5-e6f7-8a9b-0c1d-a2b3c4d5e6f7 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://silent-fog-er8np3fb.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//node-playwright-webkit@sha256:9e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f + β”œ─────── memory: 4096 MiB + β”œ────── service: silent-fog-er8np3fb + β”œ─ private fqdn: node-playwright-webkit-t7r2j.internal + β””─── private ip: 10.0.6.4 +``` + + + +In this case, the instance name is `node-playwright-webkit-t7r2j` and the address is `https://silent-fog-er8np3fb.fra.unikraft.app`. +They're different for each run. + +The command will deploy the files in the current directory. +It results in the creation of a remote web-based service for creating PNG screenshots of remote pages. + +Use the `?page=` to point the service to the remote page to screenshot. +Query the service using commands such as: + +```console +curl "https://..unikraft.app/?page=https://google.com" -o ss-google.png +curl "https://..unikraft.app/?page=https://bing.com" -o ss-bing.png +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra node-playwright-webkit-t7r2j running /node-playwright-webkit 4096MiB 1 silent-fog-er8np3fb.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +node-playwright-webkit-t7r2j silent-fog-er8np3fb.fra.unikraft.app running 1 minute ago oci://unikraft.io//node-playwright-webkit@sha256:... 4 GiB 1 2.94 s +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + + +## Learn more + +- [Playwright's Documentation](https://playwright.dev/docs/intro) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) +- [Building `Dockerfile` Images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/node18-agario.mdx b/pages/guides/node18-agario.mdx new file mode 100644 index 00000000..3b300bd4 --- /dev/null +++ b/pages/guides/node18-agario.mdx @@ -0,0 +1,174 @@ +--- +title: "Agar.io (Node)" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +[Agar.io](https://agar.io/) is a popular multiplayer game where players control a cell and aim to grow by consuming smaller cells while avoiding being consumed by larger ones. +This guide deploys an implementation of the game using Node.js on Unikraft Cloud. + +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node18-agario/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/node18-agario/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /node18-agario:latest +unikraft run --scale-to-zero policy=on,cooldown-time=2000,stateful=true --metro fra -p 443:3000/tls+http -m 1G --image /node18-agario:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 2s --metro fra -p 443:3000/tls+http -M 1Gi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: node18-agario-5k2xp +uuid: b3c4d5e6-f7a8-9b0c-1d2e-b3c4d5e6f7a8 +state: starting +image: /node18-agario +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: c4d5e6f7-a8b9-0c1d-2e3f-c4d5e6f7a8b9 + name: dark-meadow-fj9tm6bq + domains: + - fqdn: dark-meadow-fj9tm6bq.fra.unikraft.app +networks: +- uuid: d5e6f7a8-b9c0-1d2e-3f4a-d5e6f7a8b9c0 + private-ip: 10.0.3.5 + mac: 12:b0:b1:8d:f0:ea +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: node18-agario-5k2xp + β”œ───────── uuid: b3c4d5e6-f7a8-9b0c-1d2e-b3c4d5e6f7a8 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://dark-meadow-fj9tm6bq.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//node18-agario@sha256:0f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a + β”œ─────── memory: 1024 MiB + β”œ────── service: dark-meadow-fj9tm6bq + β”œ─ private fqdn: node18-agario-5k2xp.internal + β””─── private ip: 10.0.3.5 +``` + + + +In this case, the instance name is `node18-agario-5k2xp` and the address is `https://dark-meadow-fj9tm6bq.fra.unikraft.app`. +They're different for each run. + +The command will deploy an `agar.io` alternative called `https://github.com/owenashurst/agar.io-clone`. + +After deploying, you can query the service using the provided URL. + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra node18-agario-5k2xp running /node18-agario 1024MiB 1 dark-meadow-fj9tm6bq.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +node18-agario-5k2xp dark-meadow-fj9tm6bq.fra.unikraft.app running 1 minute ago oci://unikraft.io//node18-agario@sha256:... 1.0 GiB 1 78.95 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + + +## Learn more + +- [Node.js's Documentation](https://nodejs.org/docs/latest/api/) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) +- [Building `Dockerfile` Images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/node18-wingsio.mdx b/pages/guides/node18-wingsio.mdx new file mode 100644 index 00000000..6d071d55 --- /dev/null +++ b/pages/guides/node18-wingsio.mdx @@ -0,0 +1,173 @@ +--- +title: "Wings.io (Node)" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +[Wings.io](https://wings.io/) is a multiplayer .io game where players control a plane and try to shoot down other players while avoiding being shot themselves. +This guide deploys an implementation of the game using Node.js on Unikraft Cloud. + +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node18-wingsio/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/node18-wingsio/ +``` +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /node18-wingsio:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1500,stateful=true --metro fra -p 443:3000/tls+http -m 1G --image /node18-wingsio:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1500ms --metro fra -p 443:3000/tls+http -M 1Gi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: node18-wingsio-h4n8m +uuid: c4d5e6f7-a8b9-0c1d-2e3f-c4d5e6f7a8b9 +state: starting +image: /node18-wingsio +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: d5e6f7a8-b9c0-1d2e-3f4a-d5e6f7a8b9c0 + name: swift-cloud-gk7us4cz + domains: + - fqdn: swift-cloud-gk7us4cz.fra.unikraft.app +networks: +- uuid: e6f7a8b9-c0d1-2e3f-4a5b-e6f7a8b9c0d1 + private-ip: 10.0.4.4 + mac: 12:b0:c2:9e:01:fb +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: node18-wingsio-h4n8m + β”œ───────── uuid: c4d5e6f7-a8b9-0c1d-2e3f-c4d5e6f7a8b9 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://swift-cloud-gk7us4cz.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//node18-wingsio@sha256:1a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b + β”œ─────── memory: 1024 MiB + β”œ────── service: swift-cloud-gk7us4cz + β”œ─ private fqdn: node18-wingsio-h4n8m.internal + β””─── private ip: 10.0.4.4 +``` + + + +In this case, the instance name is `node18-wingsio-h4n8m` and the address is `https://swift-cloud-gk7us4cz.fra.unikraft.app`. +They're different for each run. + +The command will deploy an `wings.io` alternative called `https://github.com/Blendlight/wings.io-clone-io`. + +After deploying, you can query the service using the provided URL. + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra node18-wingsio-h4n8m running /node18-wingsio 1024MiB 1 swift-cloud-gk7us4cz.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +node18-wingsio-h4n8m swift-cloud-gk7us4cz.fra.unikraft.app running 1 minute ago oci://unikraft.io//node18-wingsio@sha256:... 1.0 GiB 1 82.16 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + + +## Learn more + +- [Node.js's Documentation](https://nodejs.org/docs/latest/api/) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) +- [Building `Dockerfile` Images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/node21-websocket.mdx b/pages/guides/node21-websocket.mdx new file mode 100644 index 00000000..0c5badfc --- /dev/null +++ b/pages/guides/node21-websocket.mdx @@ -0,0 +1,188 @@ +--- +title: "Node WebSocket Server" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +[WebSocket](https://en.wikipedia.org/wiki/WebSocket) is a bidirectional communication protocol over TCP, compatible with HTTP. +This example builds an echo-reply WebSocket server in [Node](https://nodejs.org/en). + +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node21-websocket/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/node21-websocket/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /node21-websocket:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 1G --image /node21-websocket:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s --metro fra -p 443:8080/tls+http -M 1Gi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: node21-websocket-j2x9r +uuid: d5e6f7a8-b9c0-1d2e-3f4a-d5e6f7a8b9c0 +state: starting +image: /node21-websocket +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: e6f7a8b9-c0d1-2e3f-4a5b-e6f7a8b9c0d1 + name: lively-breeze-hp3wx6yt + domains: + - fqdn: lively-breeze-hp3wx6yt.fra.unikraft.app +networks: +- uuid: f7a8b9c0-d1e2-3f4a-5b6c-f7a8b9c0d1e2 + private-ip: 10.0.5.4 + mac: 12:b0:d3:af:12:0c +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: node21-websocket-j2x9r + β”œ───────── uuid: d5e6f7a8-b9c0-1d2e-3f4a-d5e6f7a8b9c0 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://lively-breeze-hp3wx6yt.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//node21-websocket@sha256:2b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c + β”œ─────── memory: 1024 MiB + β”œ────── service: lively-breeze-hp3wx6yt + β”œ─ private fqdn: node21-websocket-j2x9r.internal + β””─── private ip: 10.0.5.4 +``` + + + +In this case, the instance name is `node21-websocket-j2x9r` and the address is `https://lively-breeze-hp3wx6yt.fra.unikraft.app`. +They're different for each run. + +The command will build the files in the current directory. + +After deploying, you can query the service with a WebSocket client, such as [`wscat`](https://github.com/websockets/wscat). +Install `wscat` with `npm`: + +```console +npm install -g wscat +``` + +Then query the WebSocket server deployed on Unikraft Cloud, using its URL: + +```console +wscat --connect wss://..unikraft.app +``` + +Then enter messages, that will be replied by the server. + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra node21-websocket-j2x9r running /node21-websocket 1024MiB 1 lively-breeze-hp3wx6yt.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +node21-websocket-j2x9r lively-breeze-hp3wx6yt.fra.unikraft.app running 1 minute ago oci://unikraft.io//node21-websocket@sha256:... 1.0 GiB 1 45.83 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + + +## Learn more + +- [WebSocket documentation](https://nextjs.org/docs) +- [ws: A Node.js WebSocket library](https://github.com/websockets/ws) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) +- [Building `Dockerfile` Images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/node24-karaoke.mdx b/pages/guides/node24-karaoke.mdx index c5c66c2d..663e1064 100644 --- a/pages/guides/node24-karaoke.mdx +++ b/pages/guides/node24-karaoke.mdx @@ -5,12 +5,15 @@ title: "Node AllKaraoke" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} [Allkaraoke](https://github.com/Asvarox/allkaraoke) offers an ultrastar deluxe-like online platform for karaoke. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node24-karaoke` directory: @@ -43,32 +46,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /node24-karaoke:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 2G --image=/node24-karaoke:latest +unikraft run --scale-to-zero policy=on,cooldown-time=2000,stateful=true --metro fra -p 443:8080/tls+http -m 2G --image /node24-karaoke:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 2G . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 2s -p 443:8080/tls+http -M 2Gi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: node24-karaoke-9lw5q +uuid: e5f6a7b8-c9d0-1234-efab-345678901234 +state: starting +image: /node24-karaoke +resources: + memory: 2GiB + vcpus: 1 +service: + uuid: ef4112f8-10fc-fe6e-f48c-43a6623ec878 + name: wild-song-p5q2nrwx + domains: + - fqdn: wild-song-p5q2nrwx.fra.unikraft.app +networks: +- uuid: cf5f3cbb-abf5-632e-3dd6-2de91885c6d9 + private-ip: 10.0.3.8 + mac: 12:b0:30:64:22:f9 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: node24-karaoke-9lw5q - β”œ────────── uuid: e5f6a7b8-c9d0-1234-efab-345678901234 - β”œ───────── state: starting - β”œ──────── domain: https://wild-song-p5q2nrwx.fra.unikraft.app - β”œ───────── image: node24-karaoke@sha256:1a3c5e7b9d2f4a6c8e0b2d4f6a8c0e2b4d6f8a0b2c4e6f8a0b2d4f6a8c0e2b - β”œ──────── memory: 2 GiB - β”œ─────── service: wild-song-p5q2nrwx - β”œ── private fqdn: node24-karaoke-9lw5q.internal - β”œ──── private ip: 172.16.3.8 - β””────────── args: /entrypoint.sh + β”œ───────── name: node24-karaoke-9lw5q + β”œ───────── uuid: e5f6a7b8-c9d0-1234-efab-345678901234 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://wild-song-p5q2nrwx.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//node24-karaoke@sha256:1a3c5e7b9d2f4a6c8e0b2d4f6a8c0e2b4d6f8a0b2c4e6f8a0b2d4f6a8c0e2b + β”œ─────── memory: 2 GiB + β”œ────── service: wild-song-p5q2nrwx + β”œ─ private fqdn: node24-karaoke-9lw5q.internal + β””─── private ip: 10.0.3.8 ``` + + In this case, the instance name is `node24-karaoke-9lw5q` and the address is `https://wild-song-p5q2nrwx.fra.unikraft.app`. They're different for each run. @@ -106,11 +135,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -node24-karaoke-9lw5q wild-song-p5q2nrwx.fra.unikraft.app running since 3mins node24-karaoke@sha256:1a3c5e7b9d2f4a... 2 GiB 1 /entrypoint.sh 1.24 s + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra node24-karaoke-9lw5q running /node24-karaoke 2GiB 1 wild-song-p5q2nrwx.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +node24-karaoke-9lw5q wild-song-p5q2nrwx.fra.unikraft.app running since 3mins oci://unikraft.io//node24-karaoke@sha256:... 2 GiB 1 1.24 s ``` + + When done, you can remove the instance: @@ -135,11 +173,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. * `runtime: base-compat:latest`: The kernel to use. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/entrypoint.sh"]`: Use `/entrypoint.sh` as the starting command of the instance. @@ -185,3 +225,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/novnc-browser.mdx b/pages/guides/novnc-browser.mdx index eb4eb038..5e9dfc3b 100644 --- a/pages/guides/novnc-browser.mdx +++ b/pages/guides/novnc-browser.mdx @@ -5,6 +5,7 @@ title: "noVNC" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a [noVNC](https://novnc.com/info.html) app, allowing you to access remote desktops through a web interface inside a modern browser. @@ -12,8 +13,10 @@ a web interface inside a modern browser. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/novnc-browser` directory: @@ -46,7 +49,7 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /novnc-browser:latest -unikraft run --scale-to-zero policy=on,cooldown-time=4000,stateful=true --metro=fra -p 443:6080/tls+http -m 4G --image=/novnc-browser:latest +unikraft run --scale-to-zero policy=on,cooldown-time=4000,stateful=true --metro fra -p 443:6080/tls+http -m 4G --image /novnc-browser:latest ``` ```bash title="kraft" @@ -55,7 +58,7 @@ kraft cloud deploy \ --scale-to-zero-stateful \ --scale-to-zero-cooldown 4s \ -p 443:6080/tls+http \ - -M 4G \ + -M 4Gi \ -n vnc-browser \ . ``` @@ -64,21 +67,47 @@ kraft cloud deploy \ The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: vnc-browser +uuid: 90a59b05-0ae1-4ca6-8383-79c5115355ee +state: starting +image: /novnc-browser +resources: + memory: 4096MiB + vcpus: 1 +service: + uuid: aaf03f7c-65e6-5624-d5f4-84e87450beee + name: weathered-fog-y5jjmwfd + domains: + - fqdn: weathered-fog-y5jjmwfd.fra.unikraft.app +networks: +- uuid: 61708609-d291-572d-4a4c-399413238199 + private-ip: 10.0.0.49 + mac: 12:b0:1e:47:6c:59 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ─────── name: vnc-browser - β”œ─────── uuid: 90a59b05-0ae1-4ca6-8383-79c5115355ee - β”œ────── metro: https://api.fra.unikraft.cloud/v1 - β”œ────── state: starting - β”œ───── domain: https://weathered-fog-y5jjmwfd.fra.unikraft.app - β”œ────── image: novnc-browser@sha256:fdb4887e84362ebbaf54c713e0d85f547e8ee173fe63a6ab39e94b7e612a9892 - β”œ───── memory: 4096 MiB - β”œ──── service: weathered-fog-y5jjmwfd - β”œ─ private ip: 10.0.0.49 - β””─────── args: /wrapper.sh + β”œ───────── name: vnc-browser + β”œ───────── uuid: 90a59b05-0ae1-4ca6-8383-79c5115355ee + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://weathered-fog-y5jjmwfd.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//novnc-browser@sha256:fdb4887e84362ebbaf54c713e0d85f547e8ee173fe63a6ab39e94b7e612a9892 + β”œ─────── memory: 4096 MiB + β”œ────── service: weathered-fog-y5jjmwfd + β”œ─ private fqdn: vnc-browser.internal + β””─── private ip: 10.0.0.49 ``` + + In this case, the instance name is `vnc-browser` and the address is `https://weathered-fog-y5jjmwfd.fra.unikraft.app`. The name was preset, but the address is different for each run. Enter the provided address into your browser of choice to access the remote desktop interface. @@ -107,11 +136,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -vnc-browser weathered-fog-y5jjmwfd.fra.unikraft.app standby standby novnc-browser@sha256:fdb4887e84362ebbaf5... 4.0 GiB 1 /wrapper.sh 7.17 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra vnc-browser standby /novnc-browser 4.0GiB 1 weathered-fog-y5jjmwfd.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +vnc-browser weathered-fog-y5jjmwfd.fra.unikraft.app standby standby oci://unikraft.io//novnc-browser@sha256:... 4.0 GiB 1 7.17 ms ``` + + When done, you can remove the instance: @@ -143,3 +181,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/opentelemetry-collector.mdx b/pages/guides/opentelemetry-collector.mdx index b7b45d2d..180e1688 100644 --- a/pages/guides/opentelemetry-collector.mdx +++ b/pages/guides/opentelemetry-collector.mdx @@ -5,14 +5,17 @@ title: "OpenTelemetry Collector" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example uses [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/), a vendor-agnostic implementation of how to receive, process and export telemetry data. OpenTelemetry Collector works with Unikraft / Unikraft Cloud to process telemetry data. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/opentelemetry-collector/` directory: @@ -45,35 +48,57 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /opentelemetry-collector:latest -unikraft run --metro=fra -p 443:4318/tls+http -m 1536M --image=/opentelemetry-collector:latest +unikraft run --metro fra -m 1536M --image /opentelemetry-collector:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:4318/tls+http -M 1536M . +kraft cloud deploy -M 1536Mi . ``` -The output shows the instance address and other details: +The output shows the instance details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: opentelemetry-collector-bvtnh +uuid: 40e8b154-b3b6-4312-ae69-2cdb794b15e4 +state: starting +image: /opentelemetry-collector +resources: + memory: 1536MiB + vcpus: 1 +networks: +- uuid: e74ba590-cbec-404b-d076-16aca1b52404 + private-ip: 10.0.3.3 + mac: 12:b0:aa:f7:b9:26 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: opentelemetry-collector-bvtnh - β”œ────────── uuid: 40e8b154-b3b6-4312-ae69-2cdb794b15e4 - β”œ───────── state: starting - β”œ───────── image: opentelemetry-collector@sha256:64f73ea5fe208f54e5212f57979f24bebcf36276495462c52b380d15dd539ced - β”œ──────── memory: 1536 MiB - β”œ── private fqdn: opentelemetry-collector-bvtnh.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/otelcontribcol --config /etc/otel/config.yaml + β”œ───────── name: opentelemetry-collector-bvtnh + β”œ───────── uuid: 40e8b154-b3b6-4312-ae69-2cdb794b15e4 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ──────── image: oci://unikraft.io//opentelemetry-collector@sha256:64f73ea5fe208f54e5212f57979f24bebcf36276495462c52b380d15dd539ced + β”œ─────── memory: 1536 MiB + β”œ─ private fqdn: opentelemetry-collector-bvtnh.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `opentelemetry-collector-bvtnh`. They're different for each run. Note that the instance doesn't export a service. The default configuration can receive telemetry data from other instances by specifying the private IP or internal DNS as destination. +Use port 4317 for gRPC and port 4318 for HTTP. The only configured exporter is the debug exporter. Feel free to change and redeploy! @@ -91,11 +116,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -opentelemetry-collector-bvtnh running since 11mins opentelemetry... 1536 MiB 1 /usr/bin/otelcontribcol --config... 177.62 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra opentelemetry-collector-bvtnh running /opentelemetry 1536MiB 1 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +opentelemetry-collector-bvtnh running since 11mins oci://unikraft.io//opentelemetry... 1536 MiB 1 177.62 ms ``` + + When done, you can remove the instance: @@ -134,3 +168,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/overview.mdx b/pages/guides/overview.mdx index 57c5550b..795c6a5c 100644 --- a/pages/guides/overview.mdx +++ b/pages/guides/overview.mdx @@ -5,6 +5,11 @@ title: "Guides Overview" This page lists all available guides for deploying applications and services on Unikraft Cloud, grouped by category. These guides mimic the [examples](https://github.com/unikraft-cloud/examples) repository, and are constantly updated with new content. +:::note +Unikraft Cloud can run any workloadβ€”define it in a Dockerfile and it will run it. +These guides are here to make that journey as fast as possible for you. +::: + {/* vale off */} ## HTTP Servers @@ -14,8 +19,8 @@ Deploy HTTP servers written in your language of choice on Unikraft Cloud. ### C / C++ - [C HTTP Server](/guides/httpserver-gcc13.2) -- [C++ HTTP Server](/guides/httpserver-g++13.2) -- [C++ Boost HTTP Server](/guides/httpserver-boost1.74-g++13.2) +- [C++ HTTP Server](/guides/httpserver-gpp13.2) +- [C++ Boost HTTP Server](/guides/httpserver-boost1.74-gpp13.2) - [SSH and HTTP Server with C and Debugging Tools](/guides/httpserver-c-debug) ### .NET @@ -34,7 +39,8 @@ Deploy HTTP servers written in your language of choice on Unikraft Cloud. ### Java - [Java HTTP Server](/guides/httpserver-java21) -- [Spring Boot HTTP Server](/guides/httpserver-java17-springboot3.2.x) +- [Spring Boot HTTP Server](/guides/httpserver-java17-springboot3.5.x) +- [Spring Petclinic](/guides/httpserver-java17-spring-petclinic) ### JavaScript / TypeScript @@ -47,7 +53,9 @@ Deploy HTTP servers written in your language of choice on Unikraft Cloud. - [Remix HTTP Server](/guides/httpserver-node21-remix) - [SolidJS HTTP Server](/guides/httpserver-node21-solid-start) - [SvelteKit HTTP Server](/guides/httpserver-node21-sveltekit) -- [Vite HTTP Server](/guides/httpserver-nginx-vite-vanilla) +- [Vite HTTP Server (Nginx)](/guides/httpserver-nginx-vite-vanilla) +- [Vite HTTP Server (Node)](/guides/httpserver-node-vite-vanilla) +- [Vite SSR HTTP Server (Node)](/guides/httpserver-node-vite-ssr-vanilla) ### Lua @@ -65,7 +73,7 @@ Deploy HTTP servers written in your language of choice on Unikraft Cloud. - [Python HTTP Server](/guides/httpserver-python3.12) - [Django HTTP Server](/guides/httpserver-python3.12-django5.0) -- [FastAPI HTTP Server](/guides/httpserver-python3.12-FastAPI-0.121.3) +- [FastAPI HTTP Server](/guides/httpserver-python3.12-fastapi-0.121.3) - [Flask HTTP Server](/guides/httpserver-python3.12-flask3.0) - [Flask and SQLite HTTP Server](/guides/httpserver-python3.12-flask3.0-sqlite) @@ -76,17 +84,18 @@ Deploy HTTP servers written in your language of choice on Unikraft Cloud. ### Rust - [Rust HTTP Server](/guides/httpserver-rust1.91) -- [Rust (Tokio) HTTP Server](/guides/httpserver-rust1.75-tokio) -- [Rust (Rocket) HTTP Server](/guides/httpserver-rust1.81-rocket0.5) - [Rust (Actix Web) HTTP Server](/guides/httpserver-rust1.87-actix-web4) +- [Rust (Leptos + Trunk) HTTP Server](/guides/httpserver-rust-trunkrs-leptos) +- [Rust (Rocket) HTTP Server](/guides/httpserver-rust1.81-rocket0.5) +- [Rust (Tokio) HTTP Server](/guides/httpserver-rust1.75-tokio) ## Web Servers & Reverse Proxies Serve static content or route traffic with popular web server and proxy tools. +- [Nginx](/guides/nginx) - [Caddy](/guides/caddy2.7-go1.21) - [HAProxy](/guides/haproxy) -- [Nginx](/guides/nginx) - [Skipper](/guides/skipper0.18) - [Traefik](/guides/traefik) @@ -100,6 +109,7 @@ Run databases and caching layers on Unikraft Cloud. - [Memcached](/guides/memcached1.6) - [MongoDB](/guides/mongodb) - [PostgreSQL](/guides/postgres) +- [Redis](/guides/redis7.2) ## Storage & Media @@ -112,7 +122,7 @@ Host object storage and image processing services. Run WebAssembly workloads on Unikraft Cloud. -- [Spin (WAGI)](/guides/spin-wagi-http) +- [Spin](/guides/spin-wagi-http) - [Wazero](/guides/wazero-import-go) ## AI & MCP Servers @@ -146,11 +156,28 @@ Deploy complete web applications and content management systems. - [Ruby on Rails](/guides/ruby3.2-rails) - [Hugo](/guides/hugo0.122) +## Browser Automation + +Run browser automation and end-to-end testing workloads on Unikraft Cloud. + +- [Playwright Chromium (Node)](/guides/node-playwright-chromium) +- [Playwright Firefox (Node)](/guides/node-playwright-firefox) +- [Playwright WebKit (Node)](/guides/node-playwright-webkit) +- [Playwright Chromium (Python)](/guides/python-playwright-chromium) + +## Real-time & Gaming + +Multiplayer and WebSocket-based applications. + +- [Node WebSocket Server](/guides/node21-websocket) +- [Agar.io Clone](/guides/node18-agario) +- [Wings.io Clone](/guides/node18-wingsio) +- [Node AllKaraoke](/guides/node24-karaoke) + ## Integration & Automation -Examples for webhooks, background jobs, and creative applications. +Examples for webhooks, background jobs, and automation. - [GitHub Webhook Receiver](/guides/github-webhook-node) -- [Node AllKaraoke](/guides/node24-karaoke) {/* vale on */} diff --git a/pages/guides/postgres.mdx b/pages/guides/postgres.mdx index d7fecda1..242ba86d 100644 --- a/pages/guides/postgres.mdx +++ b/pages/guides/postgres.mdx @@ -5,12 +5,15 @@ title: "PostgreSQL" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows you how to use [PostgreSQL](https://www.postgresql.org/), a powerful, open source object-relational database system. To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/postgres/` directory: @@ -43,32 +46,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /postgres:latest -unikraft run --metro=fra -p 5432:5432/tls -m 1G -e POSTGRES_PASSWORD=unikraft --image=/postgres:latest +unikraft run --metro fra --scale-to-zero policy=idle,cooldown-time=1000,stateful=true -p 5432:5432/tls -m 1G -e POSTGRES_PASSWORD=unikraft --image /postgres:latest ``` ```bash title="kraft" -kraft cloud deploy -p 5432:5432/tls -M 1G -e POSTGRES_PASSWORD=unikraft . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 5432:5432/tls -M 1Gi -e POSTGRES_PASSWORD=unikraft . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: postgres-saan9 +uuid: 3a1371f2-68c6-4187-84f8-c080f2b028ca +state: starting +image: /postgres +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: 8e9d810b-b1da-a30b-fd42-5c30c1900cb5 + name: young-thunder-fbafrsxj + domains: + - fqdn: young-thunder-fbafrsxj.fra.unikraft.app +networks: +- uuid: f1fab4c9-7951-75e3-ea1c-d87e47b4c9e2 + private-ip: 10.0.3.1 + mac: 12:b0:31:34:b1:96 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: postgres-saan9 - β”œ────────── uuid: 3a1371f2-68c6-4187-84f8-c080f2b028ca - β”œ───────── state: starting - β”œ────────── fqdn: young-thunder-fbafrsxj.fra.unikraft.app - β”œ───────── image: postgres@sha256:2476c0373d663d7604def7c35ffcb4ed4de8ab231309b4f20104b84f31570766 - β”œ──────── memory: 1024 MiB - β”œ─────── service: young-thunder-fbafrsxj - β”œ── private fqdn: postgres-saan9.internal - β”œ──── private ip: 172.16.3.1 - β””────────── args: wrapper.sh docker-entrypoint.sh postgres -c shared_preload_libraries='pg_ukc_scaletozero' + β”œ───────── name: postgres-saan9 + β”œ───────── uuid: 3a1371f2-68c6-4187-84f8-c080f2b028ca + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://young-thunder-fbafrsxj.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//postgres@sha256:2476c0373d663d7604def7c35ffcb4ed4de8ab231309b4f20104b84f31570766 + β”œ─────── memory: 1024 MiB + β”œ────── service: young-thunder-fbafrsxj + β”œ─ private fqdn: postgres-saan9.internal + β””─── private ip: 10.0.3.1 ``` + + In this case, the instance name is `postgres-saan9` and the service `young-thunder-fbafrsxj`. They're different for each run. @@ -121,11 +150,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -postgres-saan9 young-thunder-fbafrsxj.fra.unikraft.app running 6 minutes ago postgres@sha256:2476c0373d663d7604d... 1.0 GiB 1 wrapper.sh docker-entrypoint.sh postgres 603.42 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra postgres-saan9 running /postgres 1.0GiB 1 young-thunder-fbafrsxj.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +postgres-saan9 young-thunder-fbafrsxj.fra.unikraft.app running 6 minutes ago oci://unikraft.io//postgres@sha256:... 1.0 GiB 1 603.42 ms ``` + + When done, you can remove the instance: @@ -152,7 +190,7 @@ unikraft volume create --set metro=fra --set name=postgres --set size=200M ``` ```bash title="kraft" -kraft cloud volume create --name postgres --size 200 +kraft cloud volume create --name postgres --size 200Mi ``` @@ -163,11 +201,11 @@ Then start the PostgreSQL instance and mount that volume: ```bash title="unikraft" unikraft build . --output /postgres:latest -unikraft run --metro=fra -p 5432:5432/tls -m 1G -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres --volume postgres:/volume --image=/postgres:latest +unikraft run --metro fra --scale-to-zero policy=idle,cooldown-time=1000,stateful=true -p 5432:5432/tls -m 1G -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres --volume postgres:/volume --image /postgres:latest ``` ```bash title="kraft" -kraft cloud deploy -p 5432:5432/tls -M 1G -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 5432:5432/tls -M 1Gi -e POSTGRES_PASSWORD=unikraft -e PGDATA=/volume/postgres -v postgres:/volume . ``` @@ -205,3 +243,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/python-playwright-chromium.mdx b/pages/guides/python-playwright-chromium.mdx new file mode 100644 index 00000000..55921982 --- /dev/null +++ b/pages/guides/python-playwright-chromium.mdx @@ -0,0 +1,181 @@ +--- +title: "Playwright (Chromium) with Python FastAPI" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +[Playwright](https://playwright.dev/) is a framework for web testing and Automation. + +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/python-playwright-chromium/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/python-playwright-chromium/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /python-playwright-chromium:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 443:8080/tls+http -m 4G --image /python-playwright-chromium:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 4Gi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: python-playwright-chromium-m6k3p +uuid: e6f7a8b9-c0d1-2e3f-4a5b-e6f7a8b9c0d1 +state: starting +image: /python-playwright-chromium +resources: + memory: 4096MiB + vcpus: 1 +service: + uuid: f7a8b9c0-d1e2-3f4a-5b6c-f7a8b9c0d1e2 + name: young-night-kq8bv2mx + domains: + - fqdn: young-night-kq8bv2mx.fra.unikraft.app +networks: +- uuid: a8b9c0d1-e2f3-4a5b-6c7d-a8b9c0d1e2f3 + private-ip: 10.0.6.5 + mac: 12:b0:e4:b0:23:1d +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: python-playwright-chromium-m6k3p + β”œ───────── uuid: e6f7a8b9-c0d1-2e3f-4a5b-e6f7a8b9c0d1 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://young-night-kq8bv2mx.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//python-playwright-chromium@sha256:3c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d + β”œ─────── memory: 4096 MiB + β”œ────── service: young-night-kq8bv2mx + β”œ─ private fqdn: python-playwright-chromium-m6k3p.internal + β””─── private ip: 10.0.6.5 +``` + + + +In this case, the instance name is `python-playwright-chromium-m6k3p` and the address is `https://young-night-kq8bv2mx.fra.unikraft.app`. +They're different for each run. + +The command will deploy the files in the current directory. +It results in the creation of a remote web-based service for creating PNG screenshots of remote pages. + +Use the `?page=` to point the service to the remote page to screenshot. +Query the service using commands such as: + +```console +curl "https://..unikraft.app/?page=https://google.com" -o ss-google.png +curl "https://..unikraft.app/?page=https://github.com" -o ss-github.png +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra python-playwright-chromium-m6k3p running /python-playwright-chromium 4096MiB 1 young-night-kq8bv2mx.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +python-playwright-chromium-m6k3p young-night-kq8bv2mx.fra.unikraft.app running 1 minute ago oci://unikraft.io//python-playwright-chromium@sha256:... 4 GiB 1 3.47 s +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete +``` + +```bash title="kraft" +kraft cloud instance remove +``` + + + + +## Learn more + +- [Playwright's Documentation](https://playwright.dev/docs/intro) +- [FastAPI's Tutorial](https://fastapi.tiangolo.com/tutorial/) +- [Unikraft Cloud's Documentation](https://unikraft.cloud/docs/) +- [Building `Dockerfile` Images with `Buildkit`](https://unikraft.org/guides/building-dockerfile-images-with-buildkit) + + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/redis7.2.mdx b/pages/guides/redis7.2.mdx new file mode 100644 index 00000000..5b4bcab1 --- /dev/null +++ b/pages/guides/redis7.2.mdx @@ -0,0 +1,213 @@ +--- +title: "Redis" +--- + + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +This guide shows you how to use [Redis](https://redis.io), an open source in-memory storage, used as a distributed, in-memory key–value database, cache and message broker, with optional durability. + +To run it, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/redis7.2/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/redis7.2/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /redis72:latest +unikraft run --scale-to-zero policy=off --metro fra -p 6379:6379/tls -m 512M --image /redis72:latest +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero off -p 6379:6379/tls -M 512Mi . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: redis72-alb4r +uuid: d3c3141b-97b2-4e1d-87ae-39e4f14ab49e +state: starting +image: /redis72 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 7a4f2b3c-1d8e-4a92-b3f5-e6c1d2a3b4e5 + name: rough-wind-8vxrd1ms + domains: + - fqdn: rough-wind-8vxrd1ms.fra.unikraft.app +networks: +- uuid: 9b5e1f8d-3c2a-7b46-d1e9-f2a3b4c5d6e7 + private-ip: 10.0.3.2 + mac: 12:b0:4e:20:b3:e7 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: redis72-alb4r + β”œ───────── uuid: d3c3141b-97b2-4e1d-87ae-39e4f14ab49e + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://rough-wind-8vxrd1ms.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//redis72@sha256:9665c51faf7deb538cf7907b012b55700cad08cd391f5ba099d95d018c8da7d + β”œ─────── memory: 512 MiB + β”œ────── service: rough-wind-8vxrd1ms + β”œ─ private fqdn: redis72-alb4r.internal + β””─── private ip: 10.0.3.2 +``` + + + +In this case, the instance name is `redis72-alb4r` which is different for every run. + +To test the deployment, first forward the port using `socat`: + +```bash +socat TCP-LISTEN:6379,fork OPENSSL:rough-wind-8vxrd1ms.fra.unikraft.app:6379,verify=0 +``` + +Then, from another console, you can now use the `redis-benchmark` client to connect to Redis, for example: + +```console +redis-benchmark -t ping,set,get -n 10000 +``` + +You should see output like: + +```ansi +====== PING_INLINE ====== + 10000 requests completed in 32.03 seconds + 50 parallel clients + 3 bytes payload + keep alive: 1 + host configuration "save": + host configuration "appendonly": no + multi-thread: no + +0.01% <= 138 milliseconds +0.05% <= 139 milliseconds +2.34% <= 140 milliseconds +4.49% <= 141 milliseconds +8.57% <= 142 milliseconds +16.06% <= 143 milliseconds +21.83% <= 144 milliseconds +26.25% <= 145 milliseconds +34.54% <= 146 milliseconds +... +``` + +To disconnect, kill the `socat` command with ctrl-C. + +> **Note:** +> This guide uses `socat` for port forwarding only when a service doesn't support TLS and isn't HTTP-based (TLS/SNI determines the correct instance to send traffic to). +> Also note that port forwarding isn't needed when connecting via an instance's private IP/FQDN. +> For example, when a Redis instance serves as a cache server to +> another instance that acts as a frontend and which **does** support TLS. + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra redis72-alb4r running /redis72 512MiB 1 rough-wind-8vxrd1ms.fra.unikraft.app 1 minute ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +redis72-alb4r rough-wind-8vxrd1ms.fra.unikraft.app running 1 minute ago oci://unikraft.io//redis72@sha256:... 512 MiB 1 26.13 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete redis72-alb4r +``` + +```bash title="kraft" +kraft cloud instance remove redis72-alb4r +``` + + + +## Customize your app + +To customize the app, update the files in the repository, listed below: + +* `Kraftfile`: the Unikraft Cloud specification, including command-line arguments +* `Dockerfile`: In case you need to add files to your instance's rootfs + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/ruby3.2-rails.mdx b/pages/guides/ruby3.2-rails.mdx index fc358714..4756b6b3 100644 --- a/pages/guides/ruby3.2-rails.mdx +++ b/pages/guides/ruby3.2-rails.mdx @@ -5,11 +5,14 @@ title: "Ruby on Rails" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a [Ruby on Rails](https://rubyonrails.org/) app. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/ruby3.2-rails/` directory: @@ -41,34 +44,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /ruby3.2-rails:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 1G -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle --image=/ruby3.2-rails:latest +unikraft build . --output /ruby32-rails:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -p 443:3000/tls+http -m 1G -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle --image /ruby32-rails:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 1G -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle . +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 1Gi -e GEM_HOME=/usr/local/bundle -e BUNDLE_APP_CONFIG=/usr/local/bundle . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: ruby32-rails-apa93 +uuid: 2f85b9db-94f8-45d2-8e38-ed9b56cb8695 +state: starting +image: /ruby32-rails +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: 42265dab-df44-6d66-0075-fc07455178c8 + name: aged-waterfall-qraz0s7d + domains: + - fqdn: aged-waterfall-qraz0s7d.fra.unikraft.app +networks: +- uuid: 7ae3414b-1d87-c831-d26a-506a4cf9ac71 + private-ip: 10.0.3.3 + mac: 12:b0:39:3e:b5:36 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: ruby32-rails-apa93 - β”œ────────── uuid: 2f85b9db-94f8-45d2-8e38-ed9b56cb8695 - β”œ───────── state: running - β”œ─────────── url: https://aged-waterfall-qraz0s7d.fra.unikraft.app - β”œ───────── image: ruby32-rails@sha256:fdd46011408fdee05644665ad59b24115737e3fdb352169ec2f3f16a45d4f31d - β”œ───── boot time: 577.34 ms - β”œ──────── memory: 1024 MiB - β”œ─────── service: aged-waterfall-qraz0s7d - β”œ── private fqdn: ruby32-rails-apa93.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/ruby /app/bin/rails server -b 0.0.0.0 + β”œ───────── name: ruby32-rails-apa93 + β”œ───────── uuid: 2f85b9db-94f8-45d2-8e38-ed9b56cb8695 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://aged-waterfall-qraz0s7d.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//ruby32-rails@sha256:fdd46011408fdee05644665ad59b24115737e3fdb352169ec2f3f16a45d4f31d + β”œ─────── memory: 1024 MiB + β”œ────── service: aged-waterfall-qraz0s7d + β”œ─ private fqdn: ruby32-rails-apa93.internal + β””─── private ip: 10.0.3.3 ``` + + In this case, the instance name is `ruby32-rails-apa93` and the address is `https://aged-waterfall-qraz0s7d.fra.unikraft.app`. They're different for each run. @@ -102,11 +130,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -ruby32-rails-apa93 aged-waterfall-qraz0s7d.fra.unikraft.app running 2 minutes ago ruby32-rails@sha256:fdd46011408fdee... 1.0 GiB 1 /usr/bin/ruby /app/bin/rails server -b 0.0.0.0 577.34 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra ruby32-rails-apa93 running /ruby32-rails 1.0GiB 1 aged-waterfall-qraz0s7d.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +ruby32-rails-apa93 aged-waterfall-qraz0s7d.fra.unikraft.app running 2 minutes ago oci://unikraft.io//ruby32-rails@sha256:... 1.0 GiB 1 577.34 ms ``` + + When done, you can remove the instance: @@ -154,11 +191,13 @@ Update these files, and other files, with required contents for your own app. Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. -* `runtime: ruby:3.2`: The Unikraft runtime kernel to use is Ruby 3.2. +* `runtime: base-compat:latest`: The runtime kernel to use is the base compatibility kernel. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/ruby", "/app/bin/rails", "server", "-b", "0.0.0.0"]`: Use `/usr/bin/ruby /app/bin/rails server -b 0.0.0.0` as the starting command of the instance. @@ -198,3 +237,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/skipper0.18.mdx b/pages/guides/skipper0.18.mdx index e978647b..e6316d71 100644 --- a/pages/guides/skipper0.18.mdx +++ b/pages/guides/skipper0.18.mdx @@ -5,12 +5,15 @@ title: "Skipper" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example uses [`Skipper`](https://opensource.zalando.com/skipper/), an HTTP router and reverse proxy for service composition To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/skipper0.18/` directory: @@ -42,34 +45,59 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /skipper0.18:latest -unikraft run --metro=fra -p 443:9090/tls+http -m 256M --image=/skipper0.18:latest +unikraft build . --output /skipper018:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:9090/tls+http -m 256M --image /skipper018:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:9090/tls+http -M 256M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:9090/tls+http -M 256Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: skipper018-mx4ai +uuid: 34e3d740-c2b0-4644-b7e1-647350f688dc +state: starting +image: /skipper018 +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: b32c9035-d669-79fa-9955-9ad52cd1fcb4 + name: aged-sea-o7d3c42s + domains: + - fqdn: aged-sea-o7d3c42s.fra.unikraft.app +networks: +- uuid: 70cfb329-9ab3-fc8c-aff9-a3bbbbeb70f3 + private-ip: 10.0.6.4 + mac: 12:b0:32:1b:02:7b +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: skipper018-mx4ai - β”œ────────── uuid: 34e3d740-c2b0-4644-b7e1-647350f688dc - β”œ───────── state: running - β”œ─────────── url: https://aged-sea-o7d3c42s.fra.unikraft.app - β”œ───────── image: skipper018@sha256:5483eaf3612cca2116ceaab9be42557686324f1d30337ae15d0495eef63d0386 - β”œ───── boot time: 43.71 ms - β”œ──────── memory: 256 MiB - β”œ─────── service: aged-sea-o7d3c42s - β”œ── private fqdn: skipper018-mx4ai.internal - β”œ──── private ip: 172.16.6.4 - β””────────── args: /usr/bin/skipper -address :9090 -routes-file /etc/skipper/example.eskip + β”œ───────── name: skipper018-mx4ai + β”œ───────── uuid: 34e3d740-c2b0-4644-b7e1-647350f688dc + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://aged-sea-o7d3c42s.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//skipper018@sha256:5483eaf3612cca2116ceaab9be42557686324f1d30337ae15d0495eef63d0386 + β”œ─────── memory: 256 MiB + β”œ────── service: aged-sea-o7d3c42s + β”œ─ private fqdn: skipper018-mx4ai.internal + β””─── private ip: 10.0.6.4 ``` + + In this case, the instance name is `skipper018-mx4ai` and the address is `https://aged-sea-o7d3c42s.fra.unikraft.app`. They're different for each run. @@ -97,11 +125,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -skipper018-mx4ai aged-sea-o7d3c42s.fra.unikraft.app running 1 minute ago skipper018@sha256:5483eaf... 256 MiB 1 /usr/bin/skipper -address :9090 -routes-f... 43709us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra skipper018-mx4ai running /skipper018 256MiB 1 aged-sea-o7d3c42s.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +skipper018-mx4ai aged-sea-o7d3c42s.fra.unikraft.app running 1 minute ago oci://unikraft.io//skipper018@sha256:... 256 MiB 1 43.71 ms ``` + + When done, you can remove the instance: @@ -137,3 +174,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/spin-wagi-http.mdx b/pages/guides/spin-wagi-http.mdx index 76a321af..9e9fac31 100644 --- a/pages/guides/spin-wagi-http.mdx +++ b/pages/guides/spin-wagi-http.mdx @@ -5,14 +5,17 @@ title: "Spin" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a simple Spin HTTP app. This guide comes from [Spin's `spin-wagi-http` example](https://github.com/fermyon/spin/tree/v2.1.0/examples/spin-wagi-http). It shows how to run a Spin app serving routes from two programs written in different languages (Rust and C++). -Both the Spin executor and the Wagi executor on Unikraft Cloud. -To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +To run this example, follow these steps: + +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/spin-wagi-http/` directory: @@ -45,33 +48,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /spin-wagi-http:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 4G --image=/spin-wagi-http:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:3000/tls+http -m 4G --image /spin-wagi-http:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 4G . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:3000/tls+http -M 4Gi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: spin-wagi-http-is72r +uuid: 045c1bda-0f2e-4f8b-98c7-a208bfa7d143 +state: starting +image: /spin-wagi-http +resources: + memory: 4096MiB + vcpus: 1 +service: + uuid: 9b5b88fd-16ce-3db6-a828-ee885647d820 + name: damp-bobo-wg43p36e + domains: + - fqdn: damp-bobo-wg43p36e.fra.unikraft.app +networks: +- uuid: db3851f6-ace1-8601-b6fa-925b7fdf8390 + private-ip: 10.0.28.16 + mac: 12:b0:fc:f5:09:d5 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: spin-wagi-http-is72r - β”œ────────── uuid: 045c1bda-0f2e-4f8b-98c7-a208bfa7d143 - β”œ───────── state: running - β”œ─────────── url: https://damp-bobo-wg43p36e.fra.unikraft.app - β”œ───────── image: spin-wagi-http@sha256:57a5151996d83332af6da521e1cd92271a8c3ac7ae26bc44a7c0dbbc0a30e577 - β”œ───── boot time: 300.06 ms - β”œ──────── memory: 4096 MiB - β”œ─────── service: damp-bobo-wg43p36e - β”œ── private fqdn: spin-wagi-http-is72r.internal - β”œ──── private ip: 172.16.28.16 - β””────────── args: /usr/bin/spin up --from /app/spin.toml --listen 0.0.0.0:3000 + β”œ───────── name: spin-wagi-http-is72r + β”œ───────── uuid: 045c1bda-0f2e-4f8b-98c7-a208bfa7d143 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://damp-bobo-wg43p36e.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//spin-wagi-http@sha256:57a5151996d83332af6da521e1cd92271a8c3ac7ae26bc44a7c0dbbc0a30e577 + β”œ─────── memory: 4096 MiB + β”œ────── service: damp-bobo-wg43p36e + β”œ─ private fqdn: spin-wagi-http-is72r.internal + β””─── private ip: 10.0.28.16 ``` + + In this case, the instance name is `spin-wagi-http-is72r` and the address is `https://damp-bobo-wg43p36e.fra.unikraft.app`. They're different for each run. @@ -105,11 +133,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -spin-wagi-http-is72r damp-bobo-wg43p36e.fra.unikraft.app running 1 minute ago spin-wagi-http@sha2... 4.0 GiB 1 /usr/bin/spin up --from /app/spin.tom... 300064us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra spin-wagi-http-is72r running /spin-wagi-http 4.0GiB 1 damp-bobo-wg43p36e.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +spin-wagi-http-is72r damp-bobo-wg43p36e.fra.unikraft.app running 1 minute ago oci://unikraft.io//spin-wagi-http@sha2... 4.0 GiB 1 300.06 ms ``` + + When done, you can remove the instance: @@ -136,11 +173,13 @@ To customize the app, update the files in the repository, listed below: Lines in the `Kraftfile` have the following roles: -* `spec: v0.6`: The current `Kraftfile` specification version is `0.6`. +* `spec: v0.7`: The current `Kraftfile` specification version is `0.7`. -* `runtime: spin:latest`: The Unikraft runtime kernel to use is Spin. +* `runtime: base-compat:latest`: The runtime kernel to use is the base compatibility kernel. -* `rootfs: ./Dockerfile`: Build the app root filesystem using the `Dockerfile`. +* `rootfs`: Build the app root filesystem. + `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. + `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/spin", "up", "--from", "/app/spin.toml", "--listen", "0.0.0.0:3000"]`: Use `spin` as the command to start the app, with the given parameters. @@ -169,3 +208,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/traefik.mdx b/pages/guides/traefik.mdx index 13423026..6f83914b 100644 --- a/pages/guides/traefik.mdx +++ b/pages/guides/traefik.mdx @@ -5,12 +5,14 @@ title: "Traefik" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example uses the [`Traefik`](https://traefik.io/traefik/) cloud native app proxy. +To run it, follow these steps: -To run this example, follow these steps: - -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/traefik/` directory: @@ -43,33 +45,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /traefik:latest -unikraft run --metro=fra -p 443:80/tls+http -p 8080:8080/tls -m 1G --image=/traefik:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000,stateful=true --metro fra -p 443:80/tls+http -p 8080:8080/tls -m 1G --image /traefik:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:80/tls+http -p 8080:8080/tls -M 1G . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 1s -p 443:80/tls+http -p 8080:8080/tls -M 1Gi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: traefik-wqe7e +uuid: 69d25b0b-1813-4a3f-88e6-64abbc78b359 +state: starting +image: /traefik +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: ec7570da-5700-01b5-aaa1-0734498c11eb + name: holy-cherry-rye39b1x + domains: + - fqdn: holy-cherry-rye39b1x.fra.unikraft.app +networks: +- uuid: b59f4362-dc72-7efe-477b-1efe227e1b08 + private-ip: 10.0.28.16 + mac: 12:b0:31:58:d7:d0 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: traefik-wqe7e - β”œ────────── uuid: 69d25b0b-1813-4a3f-88e6-64abbc78b359 - β”œ───────── state: running - β”œ─────────── url: https://holy-cherry-rye39b1x.fra.unikraft.app - β”œ───────── image: traefik@sha256:f6dd913a81f6a057ceb9db7844222d7287b2a83f668cca88c73c2e85554cb526 - β”œ───── boot time: 53.66 ms - β”œ──────── memory: 1024 MiB - β”œ─────── service: holy-cherry-rye39b1x - β”œ── private fqdn: traefik-wqe7e.internal - β”œ──── private ip: 172.16.28.16 - β””────────── args: /usr/bin/traefik -configFile /etc/traefik/default.toml + β”œ───────── name: traefik-wqe7e + β”œ───────── uuid: 69d25b0b-1813-4a3f-88e6-64abbc78b359 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://holy-cherry-rye39b1x.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//traefik@sha256:f6dd913a81f6a057ceb9db7844222d7287b2a83f668cca88c73c2e85554cb526 + β”œ─────── memory: 1024 MiB + β”œ────── service: holy-cherry-rye39b1x + β”œ─ private fqdn: traefik-wqe7e.internal + β””─── private ip: 10.0.28.16 ``` + + In this case, the instance name is `traefik-wqe7e` and the address is `https://holy-cherry-rye39b1x.fra.unikraft.app`. They're different for each run. @@ -103,11 +130,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -traefik-wqe7e holy-cherry-rye39b1x.fra.unikraft.app running 8 minutes ago traefik@sha256:f6dd913a8... 1024 MiB 1 /usr/bin/traefik -configFile /etc/traefik/... 53661us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra traefik-wqe7e running /traefik 1024MiB 1 holy-cherry-rye39b1x.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +traefik-wqe7e holy-cherry-rye39b1x.fra.unikraft.app running 8 minutes ago oci://unikraft.io//traefik@sha256:... 1024 MiB 1 53.66 ms ``` + + When done, you can remove the instance: @@ -143,3 +179,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/visual-studio-code-server.mdx b/pages/guides/visual-studio-code-server.mdx index fc02979e..a018636b 100644 --- a/pages/guides/visual-studio-code-server.mdx +++ b/pages/guides/visual-studio-code-server.mdx @@ -5,15 +5,18 @@ title: "Visual Studio Code Server" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} [Visual Studio Code](https://code.visualstudio.com/) is a source-code editor developed by Microsoft. It includes support for debugging, syntax highlighting, intelligent code completion, snippets, code refactoring, and embedded Git. It features a [Code server](https://code.visualstudio.com/docs/remote/vscode-server), which allows you to run Visual Studio Code remotely and access it through a web browser or your local Visual Studio Code client. This guide explains how to create and deploy a Visual Studio Code server app. -To run this example, follow these steps: +To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/visual-studio-code-server` directory: @@ -48,34 +51,60 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: unikraft volume create --set metro=fra --set name=code-workspace --set size=1G unikraft build . --output /visual-studio-code-server:latest -unikraft run --metro=fra -p 443:8443/tls+http -m 2G --volume code-workspace:/workspace --scale-to-zero policy=on,cooldown-time=4000,stateful=true -e PGUID=0 -e PGID=0 -e PASSWORD=unikraft -e SUDO_PASSWORD=unikraft -e DEFAULT_WORKSPACE="/workspace" --image=/visual-studio-code-server:latest +unikraft run --metro fra -p 443:8443/tls+http -m 2G --volume code-workspace:/workspace --scale-to-zero policy=on,cooldown-time=4000,stateful=true -e PGUID=0 -e PGID=0 -e PASSWORD=unikraft -e SUDO_PASSWORD=unikraft -e DEFAULT_WORKSPACE="/workspace" --image /visual-studio-code-server:latest ``` ```bash title="kraft" -kraft cloud volume create --name code-workspace --size 1G +kraft cloud volume create --name code-workspace --size 1Gi -kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 4s --name code-server -p 443:8443/tls+http -M 2G -v code-workspace:/workspace -e PGUID=0 -e PGID=0 -e PASSWORD=unikraft -e SUDO_PASSWORD=unikraft -e DEFAULT_WORKSPACE="/workspace" . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 4s --name code-server -p 443:8443/tls+http -M 2Gi -v code-workspace:/workspace -e PGUID=0 -e PGID=0 -e PASSWORD=unikraft -e SUDO_PASSWORD=unikraft -e DEFAULT_WORKSPACE="/workspace" . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: code-server +uuid: c1a619a0-e222-4042-94b8-ba4b39353417 +state: starting +image: /visual-studio-code-server +resources: + memory: 2048MiB + vcpus: 1 +service: + uuid: 4a0866e4-3bec-3666-c4aa-61672de542e2 + name: blue-shape-chmxf1g4 + domains: + - fqdn: blue-shape-chmxf1g4.fra.unikraft.app +networks: +- uuid: dcec209f-31a6-b355-a88e-f5ac3edfa20e + private-ip: 10.0.0.49 + mac: 12:b0:ec:d2:df:1c +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ─────── name: code-server - β”œ─────── uuid: c1a619a0-e222-4042-94b8-ba4b39353417 - β”œ────── metro: https://api.fra.unikraft.cloud/v1 - β”œ────── state: starting - β”œ───── domain: https://blue-shape-chmxf1g4.fra.unikraft.app - β”œ────── image: visual-studio-code-server@sha256:633ec8a8dcb342b093c6f055f84fc056ee1abe40ff56e98bd612c4b9d4ddffcb - β”œ───── memory: 2048 MiB - β”œ──── service: blue-shape-chmxf1g4 - β”œ─ private ip: 10.0.0.49 - β””─────── args: /app/code-server/bin/code-server --host 0.0.0.0 --port 8443 --auth password + β”œ───────── name: code-server + β”œ───────── uuid: c1a619a0-e222-4042-94b8-ba4b39353417 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://blue-shape-chmxf1g4.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//visual-studio-code-server@sha256:633ec8a8dcb342b093c6f055f84fc056ee1abe40ff56e98bd612c4b9d4ddffcb + β”œ─────── memory: 2048 MiB + β”œ────── service: blue-shape-chmxf1g4 + β”œ─ private fqdn: code-server.internal + β””─── private ip: 10.0.0.49 ``` + + This will create a volume for data persistence, and mount it at `/workspace` inside the VM. In this case, the instance name is `code-server` and the address is `https://blue-shape-chmxf1g4.fra.unikraft.app`. @@ -96,11 +125,20 @@ kraft cloud volume list -```ansi + + +```ansi title="unikraft" +METRO NAME STATE SIZE CREATED +fra code-workspace mounted 1.0GiB 13 minutes ago +``` + +```ansi title="kraft" NAME CREATED AT SIZE ATTACHED TO MOUNTED BY STATE PERSISTENT code-workspace 13 minutes ago 1.0 GiB code-server code-server mounted true ``` + + You can list information about the instance by running: @@ -115,11 +153,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -code-server blue-shape-chmxf1g4.fra.unikraft.app standby standby visual-studio-code-server@sha256:633ec8a8dcb342b0... 2.0 GiB 1 /app/code-server/bin/code-server... 8.45 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra code-server standby /visual-studio-code-server 2.0GiB 1 blue-shape-chmxf1g4.fra.unikraft.app 2 minutes ago ``` +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +code-server blue-shape-chmxf1g4.fra.unikraft.app standby standby oci://unikraft.io//visual-studio-code-server@sha256:... 2.0 GiB 1 8.45 ms +``` + + + When done, you can remove the instance: @@ -166,3 +213,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/vsftpd.mdx b/pages/guides/vsftpd.mdx index 79ba453c..5b165aae 100644 --- a/pages/guides/vsftpd.mdx +++ b/pages/guides/vsftpd.mdx @@ -5,11 +5,14 @@ title: "vsftpd" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide explains how to create and deploy a [vsftpd](https://security.appspot.com/vsftpd.html) app, to secure access to the files of your VM. To run this example, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/vsftpd` directory: @@ -44,34 +47,60 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: unikraft volume create --set metro=fra --set name=vsftpd-workspace --set size=1G unikraft build . --output /vsftpd:latest -unikraft run --metro=fra --scale-to-zero policy=on,cooldown-time=40000,stateful=true -p 20:20/tls -p 21:21/tls -p 222:22/tls -p 990:990/tls -p 10100:10100/tls -m 1G --volume vsftpd-workspace:/root --image=/vsftpd:latest +unikraft run --metro fra --scale-to-zero policy=on,cooldown-time=40000,stateful=true -p 20:20/tls -p 21:21/tls -p 222:22/tls -p 990:990/tls -p 10100:10100/tls -m 1G --volume vsftpd-workspace:/root --image /vsftpd:latest ``` ```bash title="kraft" -kraft cloud volume create --name vsftpd-workspace --size 1G +kraft cloud volume create --name vsftpd-workspace --size 1Gi -kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 3s --name vsftpd -p 20:20/tls -p 21:21/tls -p 222:22/tls -p 990:990/tls -p 10100:10100/tls -M 1G -v vsftpd-workspace:/root . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 3s --name vsftpd -p 20:20/tls -p 21:21/tls -p 222:22/tls -p 990:990/tls -p 10100:10100/tls -M 1Gi -v vsftpd-workspace:/root . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: vsftpd +uuid: 186a46a0-7c89-4bfd-83a8-649bcc60a96e +state: starting +image: /vsftpd +resources: + memory: 1024MiB + vcpus: 1 +service: + uuid: 4814b43a-c1d3-48f0-ef3e-9dba8bcaba25 + name: broken-orangutan-jypu2z53 + domains: + - fqdn: broken-orangutan-jypu2z53.fra.unikraft.app +networks: +- uuid: 6adc6c29-5c9b-e472-70ff-fc3f3816d5a2 + private-ip: 10.0.0.109 + mac: 12:b0:17:ff:e4:c7 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ─────── name: vsftpd - β”œ─────── uuid: 186a46a0-7c89-4bfd-83a8-649bcc60a96e - β”œ────── metro: https://api.fra.unikraft.cloud/v1 - β”œ────── state: starting - β”œ───── domain: broken-orangutan-jypu2z53.fra.unikraft.app - β”œ────── image: vsftpd@sha256:31aad1619c31f499b11f1bef8fead6e6df76f235a57add011e5e414a3f51ee64 - β”œ───── memory: 1024 MiB - β”œ──── service: broken-orangutan-jypu2z53 - β”œ─ private ip: 10.0.0.109 - β””─────── args: /wrapper.sh + β”œ───────── name: vsftpd + β”œ───────── uuid: 186a46a0-7c89-4bfd-83a8-649bcc60a96e + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://broken-orangutan-jypu2z53.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//vsftpd@sha256:31aad1619c31f499b11f1bef8fead6e6df76f235a57add011e5e414a3f51ee64 + β”œ─────── memory: 1024 MiB + β”œ────── service: broken-orangutan-jypu2z53 + β”œ─ private fqdn: vsftpd.internal + β””─── private ip: 10.0.0.109 ``` + + This will create a volume for data persistence, and mount it at `/root` inside the VM. In this case, the instance name is `vsftpd` and the address is `https://broken-orangutan-jypu2z53.fra.unikraft.app`. @@ -101,11 +130,20 @@ kraft cloud volume list -```ansi + + +```ansi title="unikraft" +METRO NAME STATE SIZE CREATED +fra vsftpd-workspace mounted 1.0GiB 9 minutes ago +``` + +```ansi title="kraft" NAME CREATED AT SIZE ATTACHED TO MOUNTED BY STATE PERSISTENT vsftpd-workspace 9 minutes ago 1.0 GiB vsftpd vsftpd mounted true ``` + + You can list information about the instance by running: @@ -120,11 +158,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -vsftpd broken-orangutan-jypu2z53.fra.unikraft.app standby standby vsftpd@sha256:3c448f1e1596a2f017871aa9a7... 1.0 GiB 1 /wrapper.sh 7.19 ms + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra vsftpd standby /vsftpd 1.0GiB 1 broken-orangutan-jypu2z53.fra.unikraf… 2 minutes ago ``` +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +vsftpd broken-orangutan-jypu2z53.fra.unikraft.app standby standby oci://unikraft.io//vsftpd@sha256:... 1.0 GiB 1 7.19 ms +``` + + + When done, you can remove the instance: @@ -171,3 +218,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/wazero-import-go.mdx b/pages/guides/wazero-import-go.mdx index 9b75b187..3553abcc 100644 --- a/pages/guides/wazero-import-go.mdx +++ b/pages/guides/wazero-import-go.mdx @@ -5,12 +5,16 @@ title: "Wazero" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This example comes from [Wazero's "import go" example](https://github.com/tetratelabs/wazero/tree/main/examples/import-go) and shows how to define, import and call a wasm blob from Go and run it on Unikraft Cloud. -To run this it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +To run this example, follow these steps: + +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/wazero-import-go/` directory: @@ -43,33 +47,58 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /wazero-import-go:latest -unikraft run --metro=fra -p 443:8080/tls+http -m 512M --image=/wazero-import-go:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 512M --image /wazero-import-go:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:8080/tls+http -M 512M . +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8080/tls+http -M 512Mi . ``` The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: wazero-import-go-r4dx8 +uuid: a763e1c3-bb38-475f-95b6-1e78d8ca74fc +state: starting +image: /wazero-import-go +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: f38a171d-e283-24ca-1158-c7907948071e + name: cool-morning-camrrhsa + domains: + - fqdn: cool-morning-camrrhsa.fra.unikraft.app +networks: +- uuid: bc4bb64c-8185-3b83-8693-b1464ab4723e + private-ip: 10.0.6.7 + mac: 12:b0:05:55:02:fe +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: wazero-import-go-r4dx8 - β”œ────────── uuid: a763e1c3-bb38-475f-95b6-1e78d8ca74fc - β”œ───────── state: running - β”œ─────────── url: https://cool-morning-camrrhsa.fra.unikraft.app - β”œ───────── image: wazero-import-go@sha256:865700d358ffb2751888798ec8f302d23310b1fcf84f4d3f17f79fc25ff71153 - β”œ───── boot time: 20.04 m - β”œ──────── memory: 512 MiB - β”œ─────── service: cool-morning-camrrhsa - β”œ── private fqdn: wazero-import-go-r4dx8.internal - β”œ──── private ip: 172.16.6.7 - β””────────── args: /age-calculator 2000 + β”œ───────── name: wazero-import-go-r4dx8 + β”œ───────── uuid: a763e1c3-bb38-475f-95b6-1e78d8ca74fc + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://cool-morning-camrrhsa.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//wazero-import-go@sha256:865700d358ffb2751888798ec8f302d23310b1fcf84f4d3f17f79fc25ff71153 + β”œ─────── memory: 512 MiB + β”œ────── service: cool-morning-camrrhsa + β”œ─ private fqdn: wazero-import-go-r4dx8.internal + β””─── private ip: 10.0.6.7 ``` + + In this case, the instance name is `wazero-import-go-r4dx8` and the address is `https://cool-morning-camrrhsa.fra.unikraft.app`. They're different for each run. @@ -98,11 +127,20 @@ kraft cloud instance list -```ansi -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -wazero-import-go-r4dx8 cool-morning-camrrhsa.fra.unikraft.app running 1 minutes ag wazero-import-go@s... 512 MiB 1 /age-calculator 2000 20040us + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra wazero-import-go-r4dx8 running /wazero-import-go 512MiB 1 cool-morning-camrrhsa.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +wazero-import-go-r4dx8 cool-morning-camrrhsa.fra.unikraft.app running 1 minutes ago oci://unikraft.io//wazero-import-go@s... 512 MiB 1 20.04 ms ``` + + When done, you can remove the instance: @@ -159,3 +197,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/pages/guides/wordpress-all-in-one.mdx b/pages/guides/wordpress-all-in-one.mdx index 0d73571f..ffde535e 100644 --- a/pages/guides/wordpress-all-in-one.mdx +++ b/pages/guides/wordpress-all-in-one.mdx @@ -5,12 +5,15 @@ title: "Wordpress" import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" +{/* vale off */} This guide shows you how to use [Wordpress](https://wordpress.com/), a web content management system. To run it, follow these steps: -1. Install the CLI and a container runtime engine, for example [Docker](https://docs.docker.com/engine/install/). +1. Install the CLI. Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/wordpress-all-in-one/` directory: @@ -43,39 +46,106 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" unikraft build . --output /wordpress-all-in-one:latest -unikraft run --metro=fra -p 443:3000/tls+http -m 4G --image=/wordpress-all-in-one:latest +unikraft run --scale-to-zero policy=on,cooldown-time=3000,stateful=true --metro fra -p 443:3000/tls+http -m 4G --image /wordpress-all-in-one:latest ``` ```bash title="kraft" -kraft cloud deploy -p 443:3000/tls+http -M 4G . +kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-cooldown 3s -p 443:3000/tls+http -M 4Gi . ``` - The output shows the instance address and other details: -```ansi + + +```ansi title="unikraft" +metro: fra +name: wordpress-fx5rb +uuid: bfb9d151-1604-452a-b2e0-f737486744df +state: starting +image: /wordpress +resources: + memory: 4096MiB + vcpus: 1 +service: + uuid: 398fe5bb-e172-465e-8f74-56ffcfb24a3d + name: cool-silence-h5c1es4z + domains: + - fqdn: cool-silence-h5c1es4z.fra.unikraft.app +networks: +- uuid: 26c200e0-43eb-dd46-e4be-e9505ff677d1 + private-ip: 10.0.3.1 + mac: 12:b0:4e:20:b3:e7 +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: wordpress-fx5rb - β”œ────────── uuid: bfb9d151-1604-452a-b2e0-f737486744df - β”œ───────── state: starting - β”œ──────── domain: https://cool-silence-h5c1es4z.fra.unikraft.app - β”œ───────── image: wordpress@sha256:3e116e6c74dd04e19d4062a14f8173974ba625179ace3c10a2c96546638c4cd8 - β”œ──────── memory: 4096 MiB - β”œ─────── service: cool-silence-h5c1es4z - β”œ── private fqdn: wordpress-fx5rb.internal - β”œ──── private ip: 172.16.3.1 - β””────────── args: /usr/local/bin/wrapper.sh + β”œ───────── name: wordpress-fx5rb + β”œ───────── uuid: bfb9d151-1604-452a-b2e0-f737486744df + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://cool-silence-h5c1es4z.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//wordpress@sha256:3e116e6c74dd04e19d4062a14f8173974ba625179ace3c10a2c96546638c4cd8 + β”œ─────── memory: 4096 MiB + β”œ────── service: cool-silence-h5c1es4z + β”œ─ private fqdn: wordpress-fx5rb.internal + β””─── private ip: 10.0.3.1 ``` + + In this case, the instance name is `wordpress-fx5rb`. They're different for each run. Use a browser to access the install page of Wordpress. Fill out the form and complete the Wordpress install. +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra wordpress-fx5rb running /wordpress-all-in-one 4096MiB 1 cool-silence-h5c1es4z.fra.unikraft.app 1 minute ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +wordpress-fx5rb cool-silence-h5c1es4z.fra.unikraft.app running 1 minute ago oci://unikraft.io//wordpress-all-in-one@sha256:... 4096 MiB 1 245.32 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete wordpress-fx5rb +``` + +```bash title="kraft" +kraft cloud instance remove wordpress-fx5rb +``` + + + ## Learn more Use the `--help` option for detailed information on using Unikraft Cloud: @@ -93,3 +163,4 @@ kraft cloud --help Or visit the [CLI Reference](/cli/unikraft) or the [legacy CLI Reference](/cli/kraft/overview). +{/* vale on */} diff --git a/scripts/transform_readme.py b/scripts/transform_readme.py index 9841b8dd..aaa68aa1 100755 --- a/scripts/transform_readme.py +++ b/scripts/transform_readme.py @@ -128,8 +128,11 @@ def convert_code_tabs(text: str) -> str: if not matches: return text - groups = [] + groups: list[list] = [] + # Separator that caused the split *before* groups[i]; None for the first group. + group_separators: list[str | None] = [] current_group = [matches[0]] + current_sep: str | None = None for i in range(1, len(matches)): prev = current_group[-1] @@ -144,28 +147,69 @@ def convert_code_tabs(text: str) -> str: # "or" between an ansi (output) block and a bash (command) block marks # the boundary between two CLI alternatives (e.g. listing cmd+output for # unikraft followed by cmd+output for kraft). Break the group here so - # each CLI's command+output pair ends up in its own . + # the two groups can later be interleaved into per-position . if between == "or" and prev_info.startswith("ansi") and curr_info.startswith("bash"): groups.append(current_group) + group_separators.append(current_sep) + current_sep = between current_group = [curr] elif between in ["", "or"]: current_group.append(curr) else: groups.append(current_group) + group_separators.append(current_sep) + current_sep = between current_group = [curr] groups.append(current_group) + group_separators.append(current_sep) + + # Build a list of (start, end, replacement) spans to apply to the text. + # When two consecutive equal-length groups were split by "or" (cmd+output + # pattern), zip them positionally so that: + # [bash:A, ansi:A] "or" [bash:B, ansi:B] + # becomes: + # (bash:A, bash:B) + # (ansi:A, ansi:B) + replacements: list[tuple[int, int, str]] = [] + i = 0 + while i < len(groups): + if ( + i + 1 < len(groups) + and group_separators[i + 1] == "or" + and len(groups[i]) == len(groups[i + 1]) + and len(groups[i]) > 1 + ): + grp_a = groups[i] + grp_b = groups[i + 1] + parts = [] + for j in range(len(grp_a)): + blocks = sorted( + [grp_a[j].group(1), grp_b[j].group(1)], + key=lambda b: (0 if 'title="unikraft"' in b else 1), + ) + parts.append( + '\n\n' + "\n\n".join(blocks) + "\n\n" + ) + replacement = "\n\n".join(parts) + # Replace the entire span covering both groups (including the "or" between them) + start = grp_a[0].start() + end = grp_b[-1].end() + replacements.append((start, end, replacement)) + i += 2 + else: + group = groups[i] + if len(group) > 1: + blocks = sorted( + [m.group(1) for m in group], + key=lambda b: (0 if 'title="unikraft"' in b else 1), + ) + tabs_str = '\n\n' + "\n\n".join(blocks) + "\n\n" + replacements.append((group[0].start(), group[-1].end(), tabs_str)) + i += 1 out = text - for group in reversed(groups): - if len(group) > 1: - blocks = [m.group(1) for m in group] - - # Reconstruct the matched area with and syncKey - tabs_str = '\n\n' + "\n\n".join(blocks) + "\n\n" - - start = group[0].start() - end = group[-1].end() - out = out[:start] + tabs_str + out[end:] + for start, end, replacement in reversed(replacements): + out = out[:start] + replacement + out[end:] return out @@ -235,9 +279,11 @@ def repl(m): if f'{ANSI_DARK_GRAY}β”‚{ANSI_RESET}' in body or f'{ANSI_DARK_GRAY}β”œ{ANSI_RESET}' in body: return m.group(0) - # Ensure the fence is marked as 'ansi' for proper rendering + # Ensure the fence is marked as 'ansi' for proper rendering, + # preserving other attributes like title="..." if 'ansi' not in lang.lower(): - fence_start = "```ansi\n" + rest_attrs = re.sub(r'^\S*', '', lang).strip() + fence_start = (f'```ansi {rest_attrs}\n' if rest_attrs else '```ansi\n') # Process line by line to add colors lines = body.split('\n') @@ -359,6 +405,60 @@ def repl(m): return FENCE_PATTERN.sub(repl, text) +def color_yaml_deploy_block(text: str) -> str: + """Color state values in YAML-style unikraft deploy output blocks.""" + def repl(m): + body = m.group(3) + + # Only target blocks that look like unikraft YAML deploy output: + # must have 'state:' and 'name:' but NOT the kraft box-drawing style. + if 'deployed successfully!' in body.lower(): + return m.group(0) + if not re.search(r'^state:\s+\S', body, re.M): + return m.group(0) + if not re.search(r'^name:\s+\S', body, re.M): + return m.group(0) + # Skip if already colorized + if ANSI_GREEN in body or ANSI_LIGHT_BLUE in body: + return m.group(0) + + lines = body.split('\n') + colored_lines = [] + for line in lines: + state_m = re.match(r'^(state:)(\s+)(\S+)(.*)$', line, re.I) + if state_m: + key = state_m.group(1) + spaces = state_m.group(2) + val = state_m.group(3) + rest = state_m.group(4) + color = STATE_COLORS.get(val.lower(), ANSI_GREEN) + colored_lines.append(f'{key}{spaces}{color}{val}{ANSI_RESET}{rest}') + else: + colored_lines.append(line) + new_body = '\n'.join(colored_lines) + return m.group(1) + new_body + m.group(4) + + return FENCE_PATTERN.sub(repl, text) + + +def wrap_vale_off(text: str) -> str: + """Wrap the content body in {/* vale off */} / {/* vale on */} comments.""" + # Determine where the preamble (front matter + tabs import) ends + insert_at = 0 + m_fm = FRONT_MATTER_PATTERN.match(text) + if m_fm: + insert_at = m_fm.end() + # Skip past the Tabs import line if present + if text[insert_at:].startswith("import {"): + end_of_import = text.find("\n\n", insert_at) + if end_of_import != -1: + insert_at = end_of_import + 2 + + before = text[:insert_at] + body = text[insert_at:].rstrip("\n") + return before + "{/* vale off */}\n" + body + "\n{/* vale on */}\n" + + def main(argv: list[str] | None = None) -> int: """Main entry point for the README to MDX transformation script.""" p = argparse.ArgumentParser( @@ -386,7 +486,9 @@ def main(argv: list[str] | None = None) -> int: content = rewrite_urls(content) content = convert_code_tabs(content) content = color_deployed_block(content) + content = color_yaml_deploy_block(content) content = color_state_in_table_blocks(content) + content = wrap_vale_off(content) out.write_text(content, encoding="utf-8") return 0 diff --git a/zudoku.config.tsx b/zudoku.config.tsx index 639a39db..4c63ecf4 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -134,23 +134,24 @@ const config: ZudokuConfig = { //TODO: Please keep this list sorted by titles, not filenames !! "/guides/overview", // Guides Overview "/guides/httpserver-dotnet10.0", // .NET HTTP Server + "/guides/node18-agario", // Agar.io (Node) "/guides/mcp-server-arxiv", // ArXiv MCP Server "/guides/httpserver-bun", // Bun HTTP Server "/guides/httpserver-gcc13.2", // C HTTP Server - "/guides/httpserver-boost1.74-g++13.2", // C++ Boost HTTP Server - "/guides/httpserver-g++13.2", // C++ HTTP Server + "/guides/httpserver-boost1.74-gpp13.2", // C++ Boost HTTP Server + "/guides/httpserver-gpp13.2", // C++ HTTP Server "/guides/caddy2.7-go1.21", // Caddy - "/guides/debian-ssh", // Debian SSH server + "/guides/debian-ssh", // Debian SSH Server "/guides/httpserver-python3.12-django5.0", // Django HTTP Server "/guides/dragonflydb", // DragonflyDB "/guides/duckdb-go1.21", // DuckDB with Go "/guides/httpserver-elixir1.16", // Elixir HTTP Server "/guides/httpserver-erlang26.2", // Erlang HTTP Server "/guides/httpserver-expressjs4.18-node21", // Express HTTP Server - "/guides/httpserver-python3.12-FastAPI-0.121.3", // FastAPI HTTP Server + "/guides/httpserver-python3.12-fastapi-0.121.3", // FastAPI HTTP Server "/guides/httpserver-python3.12-flask3.0-sqlite", // Flask and SQLite HTTP Server "/guides/httpserver-python3.12-flask3.0", // Flask HTTP Server - "/guides/github-webhook-node", // GitHub Webhook receiver + "/guides/github-webhook-node", // GitHub Webhook Receiver "/guides/httpserver-go1.21", // Go HTTP Server "/guides/grafana", // Grafana "/guides/haproxy", // HAProxy @@ -160,40 +161,51 @@ const config: ZudokuConfig = { "/guides/httpserver-lua5.1", // Lua HTTP Server "/guides/mariadb", // MariaDB "/guides/memcached1.6", // Memcached - "/guides/minio", // Minio + "/guides/minio", // MinIO "/guides/mongodb", // MongoDB "/guides/httpserver-node21-nextjs", // Next.js HTTP Server "/guides/nginx", // Nginx "/guides/node24-karaoke", // Node AllKaraoke "/guides/httpserver-node25", // Node HTTP Server + "/guides/node21-websocket", // Node WebSocket Server "/guides/novnc-browser", // noVNC "/guides/opentelemetry-collector", // OpenTelemetry Collector "/guides/httpserver-perl5.42", // Perl HTTP Server "/guides/httpserver-php8.2", // PHP HTTP Server + "/guides/node-playwright-chromium", // Playwright Chromium (Node) + "/guides/python-playwright-chromium", // Playwright Chromium (Python) + "/guides/node-playwright-firefox", // Playwright Firefox (Node) + "/guides/node-playwright-webkit", // Playwright WebKit (Node) "/guides/postgres", // PostgreSQL "/guides/httpserver-prisma-expressjs4.19-node18", // Prisma HTTP Server "/guides/httpserver-node-express-puppeteer", // Puppeteer HTTP Server "/guides/httpserver-python3.12", // Python HTTP Server + "/guides/redis7.2", // Redis "/guides/httpserver-node21-remix", // Remix HTTP Server "/guides/httpserver-ruby3.2", // Ruby HTTP Server "/guides/ruby3.2-rails", // Ruby on Rails "/guides/httpserver-rust1.87-actix-web4", // Rust (Actix Web) HTTP Server + "/guides/httpserver-rust-trunkrs-leptos", // Rust (Leptos + Trunk) HTTP Server "/guides/httpserver-rust1.81-rocket0.5", // Rust (Rocket) HTTP Server "/guides/httpserver-rust1.75-tokio", // Rust (Tokio) HTTP Server "/guides/httpserver-rust1.91", // Rust HTTP Server "/guides/mcp-server-simple", // Simple MCP Server "/guides/skipper0.18", // Skipper "/guides/httpserver-node21-solid-start", // SolidJS HTTP Server - "/guides/spin-wagi-http", // Spin - "/guides/httpserver-java17-springboot3.2.x", // Spring Boot HTTP Server + "/guides/spin-wagi-http", // Spin (WAGI) + "/guides/httpserver-java17-springboot3.5.x", // Spring Boot HTTP Server + "/guides/httpserver-java17-spring-petclinic", // Spring Petclinic "/guides/httpserver-c-debug", // SSH and HTTP Server with C and Debugging Tools "/guides/httpserver-node21-sveltekit", // SvelteKit HTTP Server "/guides/traefik", // Traefik "/guides/visual-studio-code-server", // Visual Studio Code Server - "/guides/httpserver-nginx-vite-vanilla", // Vite HTTP Server + "/guides/httpserver-nginx-vite-vanilla", // Vite HTTP Server (Nginx) + "/guides/httpserver-node-vite-vanilla", // Vite HTTP Server (Node) + "/guides/httpserver-node-vite-ssr-vanilla", // Vite SSR HTTP Server (Node) "/guides/vsftpd", // vsftpd "/guides/wazero-import-go", // Wazero - "/guides/wordpress-all-in-one", // Wordpress + "/guides/node18-wingsio", // Wings.io (Node) + "/guides/wordpress-all-in-one", // WordPress ] }, { From 5543652bdeec466688aa95abe0f11604bc01bf6b Mon Sep 17 00:00:00 2001 From: Dragos Gheorghioiu Date: Thu, 7 May 2026 17:03:37 +0300 Subject: [PATCH 109/131] fix: Added pnpm-workspace for esbuild build script Signed-off-by: Dragos Gheorghioiu --- Dockerfile | 2 +- pnpm-workspace.yaml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 pnpm-workspace.yaml diff --git a/Dockerfile b/Dockerfile index 16d752de..0af48275 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,7 +40,7 @@ RUN set -xe; \ corepack enable; \ corepack prepare pnpm@latest --activate -COPY package.json pnpm-lock.yaml ./ +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ pnpm install --prefer-frozen-lockfile; \ diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000..49c0ad74 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +allowBuilds: + esbuild: false From 0a3af912ba25234165a101cdbbf1ad4961af46c6 Mon Sep 17 00:00:00 2001 From: Dragos Gheorghioiu Date: Wed, 6 May 2026 11:09:17 +0300 Subject: [PATCH 110/131] fix: Updated the images page to include unikraft and new agent image endpoint Signed-off-by: Dragos Gheorghioiu --- pages/platform/images.mdx | 347 +++++++++++++++++++++++++------------- 1 file changed, 230 insertions(+), 117 deletions(-) diff --git a/pages/platform/images.mdx b/pages/platform/images.mdx index b8b5270d..b1092969 100644 --- a/pages/platform/images.mdx +++ b/pages/platform/images.mdx @@ -6,16 +6,30 @@ navigation_icon: package Unikraft Cloud uses a **registry** to store images used to instantiate apps. At a high level, you use the CLI to build and push an image to the registry, and then ask the controller to start an app from it. -1. **build**: `kraft` builds the app locally according to a `Dockerfile`. -1. **pkg**: `kraft` packages the app locally into an OCI image. -1. **push**: `kraft` pushes the OCI image to the Unikraft Cloud registry. -1. **create**: The controller instantiates your app from the image according to a `Kraftfile`. +This process utilizes two types of registries: central and local. +Built images default to the central registry (`index.unikraft.io`). +The platform pulls from this registry automatically upon starting an instance for the first time. + +You can choose to push an image directly to a node's local registry instead. +This bypasses the central registry entirely. +Skipping this extra network round trip speeds up deployments. +It also reduces bandwidth consumption. +Read more about this in the [Registries documentation](/cli/registries). + +:::caution[DISCLAIMER] +The local registry isn't currently available for the public Unikraft Cloud offering. +As such, the CLI can't entirely leverage this feature. +::: -The simplest way to run this workflow is to use a single deploy or run command, which combines all steps into one flow. -Internally, the command calls other subcommands. -The service in the diagram is the mechanism to connect apps to the Internet. -Read more in the [services guide](/platform/services). +1. **build**: You execute `unikraft build` with the +`--output` flag. This single command reads your Dockerfile or Kraftfile, compiles +the app locally, packages the resulting files into an OCI image, and +uploads that image directly to the Unikraft Cloud registry. +1. **run**: You execute unikraft run and provide the uploaded image +name. The Unikraft Cloud controller pulls the image from the registry, +allocates the necessary system resources, and starts your app as a +running instance. ## `Dockerfiles`, `Kraftfiles` and runtimes @@ -25,38 +39,69 @@ Use the Python running example: ```bash title="" git clone https://github.com/unikraft-cloud/examples -cd examples/http-python3.12 +cd examples/httpserver-python3.12 ``` The directory contains the following `Kraftfile`: ```yaml title="Kraftfile" -spec: v0.6 +spec: v0.7 -runtime: python:3.12 +runtime: base-compat:latest -rootfs: ./Dockerfile +rootfs: + source: ./Dockerfile + format: erofs cmd: ["/usr/bin/python3", "/src/server.py"] ``` -The file is simple: it defines the start `cmd`, instructs `kraft` to build the root filesystem with a `Dockerfile`, and specifies the `python3.12` **runtime**. -On Unikraft Cloud, a runtime is a base image that contains the (minimal) code needed for the app (in this case the Python interpreter) to run. -Unikraft Cloud then overlays your app code on top of it during the packaging step. +The file is simple. +It defines the start command, instructs the unikraft CLI to build the root filesystem, and specifies the base-compat:latest runtime. +On Unikraft Cloud, a runtime provides a base image containing the minimal code your app needs to execute. +The unikraft CLI combines your app files with this base image during the build step. +It uses the Dockerfile as the source to generate the directory structure. +When packaging these files into a root filesystem, Unikraft offers two main options: cpio and erofs. +The file specifies the erofs format to create a read-only disk image. +The erofs format decompresses data block-by-block only when the system accesses it. +This selective approach saves RAM and improves boot times. +In contrast, the cpio format must remove its entire contents into memory on startup. +Check out this [tutorial](/tutorials/rootfs-formats) comparing rootfs types to understand why Unikraft favors erofs. The `Dockerfile` itself for the app looks as follows: ```dockerfile title="Dockerfile" +FROM python:3.12 AS build + +RUN set -xe; \ + /usr/sbin/ldconfig /usr/local/lib + FROM scratch -# Python HTTP server +# copy the dependencies from the base image +COPY --from=build /usr/local/lib /usr/local/lib +COPY --from=build /usr/local/bin/python3 /usr/bin/python3 +COPY --from=build /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 +COPY --from=build /lib/x86_64-linux-gnu/libm.so.6 /lib/x86_64-linux-gnu/libm.so.6 +COPY --from=build /usr/lib/x86_64-linux-gnu/libz.so.1 /usr/lib/x86_64-linux-gnu/libz.so.1 +COPY --from=build /usr/lib/x86_64-linux-gnu/libcrypto.so.3 /usr/lib/x86_64-linux-gnu/libcrypto.so.3 +COPY --from=build /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 +COPY --from=build /etc/ld.so.cache /etc/ld.so.cache + +# copy the python image COPY ./server.py /src/server.py ``` -If you're familiar with `Dockerfiles` there is nothing unusual here, other than that by default Unikraft Cloud uses `FROM scratch` to keep images lean. +If you're familiar with `Dockerfiles` there is nothing unusual here, other than that Unikraft Cloud prefers usage of `FROM scratch` to keep images lean. +This multi-stage build creates a minimal container. +First, the process loads a standard Python 3.12 image to configure system dependencies. +Next, it starts a empty filesystem called scratch. +The builder extracts the compiled Python binary and essential shared system libraries from the first stage. +It moves these exact files into the empty environment. +Finally, the builder copies your app script into the container. To add your app's code to the build, change the `COPY` commands as needed. -All [guides](/guides/bun) on Unikraft Cloud, and the [examples](https://github.com/unikraft-cloud/examples) they rely on underneath come with `Kraftfile`s and `Dockerfile`s for you to get started. +All [guides](/guides/overview) on Unikraft Cloud, and the [examples](https://github.com/unikraft-cloud/examples) they rely on underneath come with `Kraftfile`s and `Dockerfile`s for you to get started. :::tip You can also try a standard base image (for example, `FROM python:alpine`). @@ -66,7 +111,7 @@ This choice may increase image size, memory use, and boot time. ## Example workflows -This guide uses a Python [app](/guides/python) as an example to show three workflows: +This guide uses a Python [app](/guides/httpserver-python3.12) as an example to show three workflows: 1. How to create an image and launch an instance from it. 2. How to create an image and launch many instances from it. @@ -75,45 +120,67 @@ This guide uses a Python [app](/guides/python) as an example to show three workf ### Create an image and an instance from it -Start with the simplest workflow: create an image from a Python app (following the Python app [guide](/guides/python)) and start an instance from it: +Start with the simplest workflow: create an image from a Python app and start an instance from it: ```bash title="unikraft" -git clone https://github.com/unikraft-cloud/examples -cd examples/http-python3.12 -unikraft build . --output /http-python312:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB --image=/http-python312:latest +unikraft build . --output /httpserver-python312:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512M --image /httpserver-python312:latest ``` ```bash title="kraft" -git clone https://github.com/unikraft-cloud/examples -cd examples/http-python3.12 -kraft cloud deploy -p 443:8080 -M 512 . +kraft cloud deploy -p 443:8080 -M 512Mi . ``` The output should look like: -```ansi title="" + + +```ansi title="unikraft" +metro: fra +name: httpserver-python312-ma2i9 +uuid: e7389eee-9808-4152-b2ec-1f3c0541fd05 +state: running +image: /httpserver-python312 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: 51a41f63-7e88-c443-b9bf-83cd7c04d975 + name: young-night-5fpf0jj8 + domains: + - fqdn: young-night-5fpf0jj8.fra.unikraft.app +networks: +- uuid: 53da3490-c6f5-3718-25f1-219a65163c73 + private-ip: 10.0.3.3 + mac: 12:b0:18:0c:cb:aa +timestamps: + created: just now +``` + +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: http-python312-ma2i9 - β”œ────────── uuid: e7389eee-9808-4152-b2ec-1f3c0541fd05 - β”œ───────── state: running - β”œ─────────── url: https://young-night-5fpf0jj8.fra.unikraft.app - β”œ───────── image: /http-python312@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472 - β”œ───── boot time: 15.09 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: young-night-5fpf0jj8 - β”œ── private fqdn: http-python312-ma2i9.internal - β”œ──── private ip: 172.16.3.3 - β””────────── args: /usr/bin/python /src/server.py + β”œ───────── name: httpserver-python312-ma2i9 + β”œ───────── uuid: e7389eee-9808-4152-b2ec-1f3c0541fd05 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://young-night-5fpf0jj8.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-python312@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472 + β”œ─────── memory: 512 MiB + β”œ────── service: young-night-5fpf0jj8 + β”œ─ private fqdn: httpserver-python312-ma2i9.internal + β””─── private ip: 10.0.3.3 ``` -This command builds an image named `http-python312@sha256:278cb8b1...` using the `Kraftfile` and `Dockerfile`. -It then packages it, pushes it to the registry, and starts an instance named `http-python312-ma2i9` from it. + + + +This command builds an image named `httpserver-python312@sha256:278cb8b1...` using the `Kraftfile` and `Dockerfile`. +It then packages it, pushes it to the registry, and starts an instance named `httpserver-python312-ma2i9` from it. The controller fetches the image from the registry to start the instance. You can see your images by running the following command: @@ -132,26 +199,38 @@ kraft cloud image ls You should see output like: -```text title="" -IMAGE TAG SIZE -/http-python312 latest 77 MB + +```text title="unikraft" +REF DIGEST +/httpserver-python312 sha256:efcf60c1ab4677464f50f5fc7c0011efef7ea66d371586a22d1960bbeb53e2ee ``` -And you can remove an image from the registry via the legacy CLI: +```bash title="kraft" +NAME VERSION SIZE +/http-python latest 120 MB +``` + + +And you can remove an image from the central registry with the following command: +```bash title="unikraft" +unikraft img rm httpserver-python312 +``` ```bash title="kraft" -kraft cloud img rm http-python312 +kraft cloud img rm httpserver-python312 ``` +:::note +It's impossible to remove images from the local registry using the CLI yet. +::: :::note There may be a delay of a few minutes between removing an image from the registry and the image list reflecting the change. ::: - ### Create an image and many instances from it For the next workflow, start many instances: @@ -159,35 +238,93 @@ For the next workflow, start many instances: ```bash title="unikraft" -git clone https://github.com/unikraft-cloud/examples -cd examples/http-python3.12 -unikraft build . --output /http-python312:latest -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB --replicas 2 --image=/http-python312:latest +unikraft build . --output /httpserver-python312:latest +unikraft run --metro=fra -p 443:8080/http+tls -m 512M --replicas 2 --image /httpserver-python312:latest ``` ```bash title="kraft" -git clone https://github.com/unikraft-cloud/examples -cd examples/http-python3.12 -kraft cloud deploy -p 443:8080 -M 512 -R 2 . +kraft cloud deploy -p 443:8080 -M 512Mi --replicas 2 . ``` -```ansi title="" + +```ansi title="unikraft" +metro: fra +name: httpserver-python312-lscmn +uuid: 1121225d-a678-45a2-a8ce-335a9a6a2683 +state: running +image: dragosgheorghioiu/httpserver-python312 +resources: + memory: 512MiB + vcpus: 1 +service: + name: restless-orangutan-1lklj6z5 + uuid: 16f4b86d-df8f-452c-b189-41ec34250e58 + domains: + - fqdn: restless-orangutan-1lklj6z5.fra.unikraft.app +networks: +- uuid: da9445a3-c7b7-4327-8499-3bd7001cd829 + private-ip: 10.0.6.37 + mac: 12:b0:0a:00:06:25 +timestamps: + created: just now + +metro: fra +name: httpserver-python312-xfgvc +uuid: d021379d-9e03-4d0b-92a6-6fdf038e076a +state: running +image: dragosgheorghioiu/httpserver-python312 +resources: + memory: 512MiB + vcpus: 1 +service: + name: icy-violet-hce1qwm5 + uuid: 4cd63083-d538-44df-92b9-74bd6eb54ec0 + domains: + - fqdn: icy-violet-hce1qwm5.fra.unikraft.app +networks: +- uuid: 51c147cc-8f8d-4347-b628-d2e0f4f9b3be + private-ip: 10.0.0.121 + mac: 12:b0:0a:00:00:79 +timestamps: + created: just now + +metro: fra +name: httpserver-python312-7lha2 +uuid: 0706c648-0c56-4c74-8dda-5a1aeff7d8b8 +state: running +image: dragosgheorghioiu/httpserver-python312 +resources: + memory: 512MiB + vcpus: 1 +service: + name: hidden-silence-l3g520dw + uuid: 38703973-ccbd-47ae-b4c0-f9f59c1751e7 + domains: + - fqdn: hidden-silence-l3g520dw.fra.unikraft.app +networks: +- uuid: 6c20f9b2-dc39-41d1-a4bd-250a52a75b19 + private-ip: 10.0.9.185 + mac: 12:b0:0a:00:09:b9 +timestamps: + created: just now +``` +```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ────────── name: http-python312-8mxq5 - β”œ────────── uuid: 37f5b23c-0996-45fa-8d7f-e6b2942eb6fb - β”œ───────── state: running - β”œ─────────── url: https://small-darkness-4t9y8n5s.fra.unikraft.app - β”œ───────── image: http-python312@sha256:5b922dfa1632af38c476b98fdd9f4314fb9c5e587d3d31255e6479108c057e88 - β”œ───── boot time: 153.65 ms - β”œ──────── memory: 512 MiB - β”œ─────── service: small-darkness-4t9y8n5s - β”œ── private fqdn: http-python312-8mxq5.internal - β”œ──── private ip: 172.16.6.7 - β””────────── args: /usr/bin/python3 /src/server.py + β”œ───────── name: httpserver-python312-lscmn + β”œ───────── uuid: 1121225d-a678-45a2-a8ce-335a9a6a2683 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: running + β”œ─────── domain: https://restless-orangutan-1lklj6z5.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//httpserver-python312@sha256:5b922dfa1632af38c476b98fdd9f4314fb9c5e587d3d31255e6479108c057e88 + β”œ─────── memory: 512 MiB + β”œ────── service: restless-orangutan-1lklj6z5 + β”œ─ private fqdn: httpserver-python312-8mxq5.internal + β””─── private ip: 10.0.6.37 ``` + Check that it worked by listing all instances with: @@ -203,13 +340,23 @@ kraft cloud instance list -```text title="" -NAME FQDN STATE CREATED AT IMAGE MEMORY ARGS BOOT TIME -http-python312-w4bcp sparkling-surf-qphxdk0j.fra.unikraft.app running 45 seconds ago http-python312@sha256... 512 MiB /usr/bin/python3 /src/server.py 153794us -http-python312-juvv4 old-brook-v3bf7h7z.fra.unikraft.app running 45 seconds ago http-python312@sha256... 512 MiB /usr/bin/python3 /src/server.py 154744us -http-python312-8mxq5 small-darkness-4t9y8n5s.fra.unikraft.app running 45 seconds ago http-python312@sha256... 512 MiB /usr/bin/python3 /src/server.py 153646us + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra httpserver-python312-7lha2 running /httpserver-python312 512MiB 1 hidden-silence-l3g520dw.fra.unikraft.app just now +fra httpserver-python312-xfgvc running /httpserver-python312 512MiB 1 icy-violet-hce1qwm5.fra.unikraft.app just now +fra httpserver-python312-lscmn running /httpserver-python312 512MiB 1 restless-orangutan-1lklj6z5.fra.unikraft.app just now +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +httpserver-python312-7lha2 hidden-silence-l3g520dw.fra.unikraft.app running since 7mins dragosgheorghioiu/httpserver-python312@sh... 512 MiB 1 82.28 ms +httpserver-python312-xfgvc icy-violet-hce1qwm5.fra.unikraft.app running since 7mins dragosgheorghioiu/httpserver-python312@sh... 512 MiB 1 81.27 ms +httpserver-python312-lscmn restless-orangutan-1lklj6z5.fra.unikraft.app running since 7mins dragosgheorghioiu/httpserver-python312@sh... 512 MiB 1 84.28 ms ``` + + Three instances run: the original plus two replicas. ### Create instances from an existing image @@ -219,17 +366,24 @@ In this final workflow, take the existing image and start new instances from it: ```bash title="unikraft" -unikraft run --metro=fra -p 443:8080/http+tls -m 512MiB --image=/http-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca +unikraft run --metro=fra -p 443:8080/http+tls -m 512M --image /httpserver-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca ``` ```bash title="kraft" kraft cloud instance create \ --start \ --port 443:8080 \ - -M 512 \ - /http-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca + -M 512Mi \ + /httpserver-python312@sha256:1b815914eb568a06ca4bbfdfb7d6cf484a9e9a0947ba8e0e0f1664d972a25bca ``` +:::note +Pinning the digest is optional. +Providing the exact hash guarantees you deploy the exact same immutable image every time. +This prevents unexpected behavior if a developer overwrites a standard tag like latest. +If you omit the digest, the CLI automatically pulls the newest version of your image. +::: + You now have a new instance created from the existing image. @@ -240,15 +394,14 @@ You now have a new instance created from the existing image. ### List images ``` -GET /images +GET /image-store ``` -Returns all images accessible for your account and known by the platform. +Returns all images accessible for your account and known by the platform from both the local and central registries. Each image object includes: | Field | Type | Description | |-------|------|-------------| -| `uuid` | string | Image UUID. | | `created_at` | timestamp | Creation time. | | `owner` | string | Owner of the image (omitted if not root account). | | `url` | string | Full image address (includes digest). | @@ -259,46 +412,6 @@ Each image object includes: | `env` | map of strings | Default environmental variables (omitted if none). | | `users` | array of strings | Users with access to the image (omitted if not root account). | -### Look up by UUID - -``` -GET /images?uuid=[,…] -``` - -Returns one or more images by UUID. - -### Look up by digest - -``` -GET /images -``` - -Pass a `digest` string in the request body to return the image matching that digest: - -```json title="GET /images" -{ - "digest": "user/image@sha256:278cb8b14f9faf9c2702dddd8bfb6124912d82c11b4a2c6590b6e32fc4049472" -} -``` - -The response includes `url`, `tags`, `initrd_or_rom`, `size_in_bytes`, args` and `env`. - -### Look up by tag - -``` -GET /images -``` - -Pass a `tag` string in the request body to return the image matching that tag: - -```json title="GET /images" -{ - "tag": "user/image:tag" -} -``` - -The response includes `url`, `tags`, `initrd_or_rom`, `size_in_bytes`, args` and `env`. - ## Learn more * The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). From 181a0f086711d2024bd982975905148f61b0e008 Mon Sep 17 00:00:00 2001 From: Dragos Gheorghioiu Date: Thu, 7 May 2026 17:27:10 +0300 Subject: [PATCH 111/131] fix: Removed redundant sentence and grammar Co-authored-by: Alex-Andrei Cioc Signed-off-by: Dragos Gheorghioiu --- pages/platform/images.mdx | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/pages/platform/images.mdx b/pages/platform/images.mdx index b1092969..4d2cdc8d 100644 --- a/pages/platform/images.mdx +++ b/pages/platform/images.mdx @@ -18,7 +18,6 @@ Read more about this in the [Registries documentation](/cli/registries). :::caution[DISCLAIMER] The local registry isn't currently available for the public Unikraft Cloud offering. -As such, the CLI can't entirely leverage this feature. ::: 1. **build**: You execute `unikraft build` with the @@ -67,6 +66,7 @@ The erofs format decompresses data block-by-block only when the system accesses This selective approach saves RAM and improves boot times. In contrast, the cpio format must remove its entire contents into memory on startup. Check out this [tutorial](/tutorials/rootfs-formats) comparing rootfs types to understand why Unikraft favors erofs. +For a more in depth explanation of the Kraftfile you can check the [reference](/kraftfile/v0.7) The `Dockerfile` itself for the app looks as follows: @@ -95,7 +95,7 @@ COPY ./server.py /src/server.py If you're familiar with `Dockerfiles` there is nothing unusual here, other than that Unikraft Cloud prefers usage of `FROM scratch` to keep images lean. This multi-stage build creates a minimal container. First, the process loads a standard Python 3.12 image to configure system dependencies. -Next, it starts a empty filesystem called scratch. +Next, it starts an empty filesystem called scratch. The builder extracts the compiled Python binary and essential shared system libraries from the first stage. It moves these exact files into the empty environment. Finally, the builder copies your app script into the container. @@ -224,9 +224,6 @@ kraft cloud img rm httpserver-python312 -:::note -It's impossible to remove images from the local registry using the CLI yet. -::: :::note There may be a delay of a few minutes between removing an image from the registry and the image list reflecting the change. ::: @@ -391,13 +388,15 @@ You now have a new instance created from the existing image. ## REST API reference -### List images +### List images from local registry + +Base address: `https://api..unikraft.cloud/v1` ``` GET /image-store ``` -Returns all images accessible for your account and known by the platform from both the local and central registries. +Returns all images accessible for your account and known by the platform from the local registry. Each image object includes: | Field | Type | Description | @@ -412,6 +411,21 @@ Each image object includes: | `env` | map of strings | Default environmental variables (omitted if none). | | `users` | array of strings | Users with access to the image (omitted if not root account). | + +### List images from central registry + +Base address `https://controlplane.unikraft.cloud/v1` + +``` +GET /images +``` + +Returns all images accessible for your account and known by the platform from the central registry. + +| Field | Type | Description | +|-------|------|-------------| +| `name` | string | Image reference (`{owner}/{registry}/{image}`). Excludes digest and tag. | + ## Learn more * The [CLI reference](/docs/cli/unikraft) and the [legacy CLI reference](/docs/cli/kraft/overview). From d271829ff02b32a2d0ffc77a137e2c12664064d0 Mon Sep 17 00:00:00 2001 From: Cezar Craciunoiu Date: Fri, 8 May 2026 14:36:35 +0300 Subject: [PATCH 112/131] fix(actions): Roll on all instances Signed-off-by: Cezar Craciunoiu --- .github/actions/setup-www/action.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/setup-www/action.yaml b/.github/actions/setup-www/action.yaml index f0122aa9..7afcc293 100644 --- a/.github/actions/setup-www/action.yaml +++ b/.github/actions/setup-www/action.yaml @@ -94,6 +94,7 @@ runs: run: | kraft cloud deploy \ --rollout remove \ + --rollout-qualifier all \ --build-arg API_URL="https://${{ steps.service.outputs.domain }}" \ --build-arg PUBLIC_API_URL="https://${{ steps.service.outputs.domain }}" \ --build-arg VITE_PUBLIC_SITE_URL="https://${{ steps.service.outputs.domain }}" \ From b61afee1b337ea9a9ce3214caece2bf62d2d9955 Mon Sep 17 00:00:00 2001 From: Tobias Landsberg Date: Fri, 8 May 2026 19:01:10 +0200 Subject: [PATCH 113/131] feat(use-cases): Add checkpointing and branching to databases Signed-off-by: Tobias Landsberg --- pages/use-cases/serverless-databases.mdx | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/pages/use-cases/serverless-databases.mdx b/pages/use-cases/serverless-databases.mdx index 3fff680f..74c0be50 100644 --- a/pages/use-cases/serverless-databases.mdx +++ b/pages/use-cases/serverless-databases.mdx @@ -34,6 +34,15 @@ Databases can integrate with API gateways, event triggers, and headless services Unlike traditional serverless platforms where databases often suffer from high overhead, microVM-based instances deliver **bare-metal-like throughput and predictable latency**. These instances optimise both Online Transaction Processing (OLTP) and Online Analytical Processing (OLAP) workloads. +### πŸ“Έ Checkpoints for point-in-time recovery + +**Checkpointing** saves the complete state of a running microVM at any time, **without interrupting execution**. +Checkpoints are incremental, fast, and keep a history, so you can restore the database to any previous checkpoint to recover from a failed migration or an erroneous write. + +### πŸ”€ Instance branching for instant clones + +Unikraft Cloud lets you **branch** a running instance, creating an identical, **independent copy in milliseconds** while leaving the original untouched. +Test your migrations or destructive changes on a byte-for-byte copy of production before applying them, so you can proceed with confidence. ## Getting started @@ -204,6 +213,43 @@ kraft cloud deploy -p 5432:5432/tls -M 1Gi -e POSTGRES_PASSWORD=unikraft -e PGDA +### Using checkpoints + +:::note +Checkpointing is coming soon. +Full documentation will follow once the interface is available. +::: + +### Using instance branching + +:::note +Instance branching is a preview feature and isn't yet available on stable. +The interface described here reflects the current implementation and may change before general availability. +::: + +You can branch a running PostgreSQL instance to create an independent copy with the exact same state. +The source instance keeps running unaffected. + +To create a branch, pass `--branch` with the source instance name to `unikraft run`: + + +```console title="unikraft" +unikraft run --metro=fra -p 5432:5432/tls --branch +``` + + +The branch boots immediately from the same state as the source. +Connect to it like any other instance. +Whatever you do, the source instance remains unaffected. + +When you're done, remove the branch: + + +```console title="unikraft" +unikraft instances delete +``` + + ### Customize your deployment Your deployment is a standard PostgreSQL installation. From f1e731ac8bdb488e7895eda5acbcd43325bb76c0 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Fri, 8 May 2026 19:02:15 +0300 Subject: [PATCH 114/131] feat(use-cases): Add serverless functions Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/serverless-functions.mdx | 436 +++++++++++++++++++++++ zudoku.config.tsx | 1 + 2 files changed, 437 insertions(+) create mode 100644 pages/use-cases/serverless-functions.mdx diff --git a/pages/use-cases/serverless-functions.mdx b/pages/use-cases/serverless-functions.mdx new file mode 100644 index 00000000..0c5272ed --- /dev/null +++ b/pages/use-cases/serverless-functions.mdx @@ -0,0 +1,436 @@ +--- +title: Serverless Functions +navigation_icon: function-square +--- + +Serverless functions let you deploy small pieces of business logic without managing servers or runtimes. +They're ideal for event-driven pipelines, API backends, and dynamic code executionβ€”but traditional function-as-a-service platforms often suffer from cold-start penalties and opaque sandboxing. + +With **Unikraft Cloud**, you can run serverless functions inside microVMs: instant availability, VM-level isolation, and true scale-to-zero economics. +The ROM (Read-Only Memory) model goes one step furtherβ€”package your function code independently of the runtime image, and swap it in at instance creation time. + +## Why run serverless functions on Unikraft Cloud + +### ⚑ Millisecond cold starts with instance templates + +Unikraft Cloud's [instance templates](/platform/instances#instance-templates) pre-initialize a runtime once, then stamp out new instances from that snapshot. +Combined with stateful scale-to-zero, instances resume from a warm snapshot rather than booting from scratch: + +* Single-digit-millisecond wake-ups, even under burst traffic. +* No re-execution of startup logic between requests. + +### πŸ”’ Strong isolation per function + +Every function instance runs in its own microVM. +No shared kernel, no noisy-neighbour risk, and no container escape surface. +Sensitive business logic stays protected even when other tenants share the same platform. + +### πŸ’Έ Pay only for execution + +Functions are inherently bursty. +Scale-to-zero means an idle function costs nothing. +The ROM model makes this even leaner: you package the base runtime image once, and only the lightweight function ROM changes per deployment. + +### πŸ”„ Decouple runtime from function code + +ROMs separate the runtime image (Node.js, Python, etc.) from the function payload: + +* Update function code by pushing a new ROMβ€”no runtime rebuild required. +* Run many specialised functions from a single base image. +* Instant rollback by pointing an instance at a previous ROM version. + +## Getting started + +This guide uses the [`node-code-execution`](https://github.com/unikraft-cloud/examples/tree/main/node-code-execution) example. +It deploys a Node.js runtime as the base image, then attaches JavaScript or TypeScript function ROMs to instances of that runtime. + +### Prerequisites + +1. Install the CLI: + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builderβ€”the easiest way is via [Docker](https://docs.docker.com/engine/install/). + +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node-code-execution` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/node-code-execution/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +### Step 1: Package and push the base runtime image + +The base image contains a Node.js server (`server.ts`) that loads a function from the attached ROM and executes it on each HTTP request. +Right before starting the server, it writes `1` to `/uk/libukp/template_instance`, which triggers Unikraft Cloud to convert the running instance into a [template](/platform/instances#instance-templates). + + + +```bash title="unikraft" +unikraft build . --output /node-code-exec:latest +``` + +```bash title="kraft" +kraft pkg \ + --name index.unikraft.io//node-code-exec:latest \ + --plat kraftcloud \ + --arch x86_64 \ + --rootfs-type erofs \ + --push \ + . +``` + + + +### Step 2: Create a template from the base image + +Boot a short-lived instance from the base image without any ROM attached. +The instance self-converts into a template and exits: + + + +```bash title="unikraft" +unikraft run --metro fra \ + --name node-exec \ + -m 512M \ + --image /node-code-exec:latest +``` + +```bash title="kraft" +kraft cloud instance create \ + --start \ + --name node-exec \ + -M 512Mi \ + /node-code-exec:latest +``` + + + +The output shows the instance details: + + + +```ansi title="unikraft" +metro: fra +name: node-exec +uuid: 96608ed2-45e0-4c8f-8269-5d8cd3e4b41a +state: starting +image: /node-code-exec +resources: + memory: 512MiB + vcpus: 1 +networks: +- uuid: 6f7a8b9c-0d1e-2f3a-4b5c-f6a7b8c9d0e1 + private-ip: 10.0.5.4 + mac: 12:b0:6c:3e:ab:95 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: node-exec + β”œ───────── uuid: 96608ed2-45e0-4c8f-8269-5d8cd3e4b41a + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ──────── image: oci://unikraft.io//node-code-exec@sha256:71487fd6196987cf65fb89eb84405cb796677aba177dabacf391f09618313328 + β”œ─────── memory: 512 MiB + β”œ─ private fqdn: node-exec.internal + β””─── private ip: 10.0.5.4 +``` + + + +This instance is short-lived, since right before the server starts, it triggers a conversion into a template. +To confirm the template is ready: + + + +```bash title="unikraft" +unikraft instances templates list +``` + +```bash title="kraft" +kraft cloud instance template list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS CREATED +fra node-exec template acioc/node-code-exec 512MiB 1 just now +``` + +```ansi title="kraft" +NAME IMAGE ARGS CREATED AT +node-exec oci://unikraft.io/acioc/node-code-exec@sha256:71487fd6196987cf65fb89eb84405cb796677aba177dabacf391f09618313328 20 seconds ago +``` + + + + +### Step 3: Package and push the function ROMs + +ROMs package only the function source filesβ€”no runtime needed. +Package both example functions: + + + +```bash title="unikraft" +unikraft build rom1/ --output /node-rom1:latest +unikraft build rom2/ --output /node-rom2:latest +``` + +```bash title="kraft" +kraft pkg \ + --rom ./fs \ + --rom-type erofs \ + --plat kraftcloud \ + --arch x86_64 \ + --name index.unikraft.io//node-rom1:latest \ + --push \ + rom1/ +kraft pkg \ + --rom ./fs \ + --rom-type erofs \ + --plat kraftcloud \ + --arch x86_64 \ + --name index.unikraft.io//node-rom2:latest \ + --push \ + rom2/ +``` + + + +### Step 4: Create instances from the template with ROMs attached + +Stamp out instances from the template, each with a different ROM. +New instances skip the cold-start initialization phase because they restore from the template snapshot. + +Create the first instance with the JavaScript ROM attached: + + + +```bash title="unikraft" +unikraft run --metro fra \ + --name node-exec-rom1 \ + -p 443:8080/tls+http \ + --scale-to-zero policy=on,cooldown-time=1000,stateful=true \ + --rom /node-rom1:latest:/rom:js_function \ + --template node-exec +``` + +```bash title="kraft" +# kraft does not support creating instances with attached ROMs, but you can use the API directly +curl -X POST "$UKC_METRO/instances" \ + -H "Accept: application/json" \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "node-exec-rom1", + "template": { + "name": "node-exec" + }, + "autostart": true, + "service_group": { + "services": [ + { + "port": 443, + "destination_port": 8080, + "handlers": ["tls", "http"] + } + ] + }, + "scale_to_zero": { + "policy": "on", + "stateful": true, + "cooldown_time_ms": 1000 + }, + "roms": [ + { + "name": "js_function", + "image": "index.unikraft.io//node-rom1:latest", + "at": "/rom" + } + ] +}' +``` + + + +Test the first instance: + +```bash +curl https:// +``` + +```text +Bye, World! +``` + +Create the second instance with the TypeScript ROM attached: + + + +```bash title="unikraft" +unikraft run --metro fra \ + --name node-exec-rom2 \ + -p 443:8080/tls+http \ + --scale-to-zero policy=on,cooldown-time=1000,stateful=true \ + --rom /node-rom2:latest:/rom:ts_function \ + --template node-exec +``` + +```bash title="kraft" +# kraft does not support creating instances with attached ROMs, but you can use the API directly +curl -X POST "$UKC_METRO/instances" \ + -H "Accept: application/json" \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "node-exec-rom2", + "template": { + "name": "node-exec" + }, + "autostart": true, + "service_group": { + "services": [ + { + "port": 443, + "destination_port": 8080, + "handlers": ["tls", "http"] + } + ] + }, + "scale_to_zero": { + "policy": "on", + "stateful": true, + "cooldown_time_ms": 1000 + }, + "roms": [ + { + "name": "ts_function", + "image": "index.unikraft.io//node-rom2:latest", + "at": "/rom" + } + ] +}' +``` + + + +Test the second instance: + +```bash +curl https:// +``` + +```text +Auf Wiedersehen! +``` + +Both instances run the same base Node.js runtime but execute different function codeβ€”without any rebuild of the runtime image. + +You can list information about the instances by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra node-exec-rom2 standby /node-code-exec 512MiB 1 nameless-wood-gw7pbnls.fra.unikraft.app 2 minutes ago +fra node-exec-rom1 standby /node-code-exec 512MiB 1 sparkling-dawn-syowlbtj.fra.unikraft.app 3 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +node-exec-rom2 nameless-wood-gw7pbnls.fra.unikraft.app standby standby oci://unikraft.io//node-code-exec@sha256:71487f... 512 MiB 1 6.98 ms +node-exec-rom1 sparkling-dawn-syowlbtj.fra.unikraft.app standby standby oci://unikraft.io//node-code-exec@sha256:71487f... 512 MiB 1 7.86 ms +``` + + + + +## How it works + +The ROM deployment model has three layers: + +1. **Base runtime image**: A generic Node.js server that loads and executes code from a well-known path (`/rom/rom.js` or `/rom/rom.ts`). + Push it once; it changes infrequently. + +1. **Function ROM**: A read-only filesystem image containing only the function source file. + Lightweight, fast to build and push. + Attached to an instance at creation time and mounted at `/rom`. + +1. **Instance template**: A pre-initialized snapshot of the runtime, created automatically when the base image boots without a ROM. + New instances boot from this snapshot, skipping initialization and reducing cold-start latency to milliseconds. + +## Cleanup + + + +```bash title="unikraft" +unikraft instances delete node-exec-rom1 node-exec-rom2 +unikraft instances template delete node-exec +``` + +```bash title="kraft" +kraft cloud instance remove node-exec-rom1 node-exec-rom2 +kraft cloud instance template remove node-exec +``` + + + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the [legacy CLI reference](/docs/cli/kraft/overview). + +For more on the ROM and template features: + +* [Instance templates](/platform/instances#instance-templates) +* [ROMs](/platform/instances#roms) +* [`node-code-execution` example](https://github.com/unikraft-cloud/examples/tree/main/node-code-execution) diff --git a/zudoku.config.tsx b/zudoku.config.tsx index 647dac81..fafa7d37 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -89,6 +89,7 @@ const config: ZudokuConfig = { "/use-cases/headless-browsers", "/use-cases/mcp-servers", "/use-cases/api-gateways", + "/use-cases/serverless-functions", "/use-cases/serverless-databases", "/use-cases/webhooks", "/use-cases/remote-ides", From 7f46a121120e0610e905474a2a2c80aef47430fe Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Fri, 8 May 2026 20:45:37 +0300 Subject: [PATCH 115/131] feat(use-cases): Add build and test environments Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/build-test-environments.mdx | 457 ++++++++++++++++++++ zudoku.config.tsx | 1 + 2 files changed, 458 insertions(+) create mode 100644 pages/use-cases/build-test-environments.mdx diff --git a/pages/use-cases/build-test-environments.mdx b/pages/use-cases/build-test-environments.mdx new file mode 100644 index 00000000..e15f9bd0 --- /dev/null +++ b/pages/use-cases/build-test-environments.mdx @@ -0,0 +1,457 @@ +--- +title: Build and Test Environments +navigation_icon: tool-case +--- + +Build and test workloads often need dynamic code execution in a controlled runtime. +You want to swap test logic, keep startup latency low, and avoid rebuilding full images for every test change. + +With **Unikraft Cloud**, you can run a reusable Go runtime image and inject test logic via ROMs. +At startup, the instance compiles ROM code into a Go plugin and executes it, giving you fast iteration with strong isolation. + +## Why run build and test environments on Unikraft Cloud + +### Fast test iteration + +Build and test logic changes frequently. +With ROM-based deployment, you package and push a small ROM instead of rebuilding the full runtime image: + +* Keep the runtime stable. +* Update only test payloads. +* Roll forward and back by switching ROM image tags. + +### Runtime compilation in isolated microVMs + +Each environment runs in its own microVM. +The runtime compiles ROM code inside the instance (`go build -buildmode=plugin`) and loads it as a plugin. +This isolates compilation and execution while keeping the runtime reusable. + +### Template-based cold start optimization + +The base image can create an [instance template](/platform/instances#instance-templates). +New environments launch from that template, reducing startup time for bursty CI-style workloads. + +### Scale-to-zero economics + +Test environments are often idle between runs. +With scale-to-zero enabled, idle instances consume no active resources while still waking when needed. + +## Getting started + +This guide uses the [`build-environments`](https://github.com/unikraft-cloud/examples/tree/main/build-environments) example. +The base image contains a Go server (`server.go`) that: + +1. Writes to `/uk/libukp/template_instance` to create a template. +2. Reads ROM source from `/rom/rom.go`. +3. Compiles it to `/run/rom.so` using `go build -buildmode=plugin`. +4. Loads the `Handler()` function from the plugin and serves its output over HTTP. + +### Prerequisites + +1. Install the CLI: + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way is via [Docker](https://docs.docker.com/engine/install/). + +1. Clone the examples repository and enter the example directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/build-environments/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +export UKC_METRO=fra +``` + + + +### Step 1: Package and push the base runtime image + +Package and push the base Go runtime image (see `server.go` for the runtime implementation): + + + +```bash title="unikraft" +unikraft build . --output /go-build-env:latest +``` + +```bash title="kraft" +kraft pkg \ + --name index.unikraft.io//go-build-env:latest \ + --plat kraftcloud \ + --arch x86_64 \ + --rootfs-type erofs \ + --push \ + . +``` + + + +The server in `server.go` loads `/rom/rom.go`, compiles it to `/run/rom.so` using `go build -buildmode=plugin`, and invokes `Handler()` from the plugin. + +### Step 2: Create a template from the base image + +Create a short-lived instance from the base image (without ROM attached). +The server writes to `/uk/libukp/template_instance` and turns the instance into a [template](/platform/instances#instance-templates) before serving requests: + + + +```bash title="unikraft" +unikraft run --metro fra \ + --name go-build-env \ + -m 512M \ + --image /go-build-env:latest +``` + +```bash title="kraft" +kraft cloud instance create \ + --start \ + --name go-build-env \ + -M 512Mi \ + /go-build-env:latest +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: go-build-env +uuid: 650dbbe7-3949-4c93-88e7-6619a9216e0c +state: starting +image: /go-build-env +resources: + memory: 512MiB + vcpus: 1 +networks: +- uuid: 6f7a8b9c-0d1e-2f3a-4b5c-f6a7b8c9d0e1 + private-ip: 10.0.5.4 + mac: 12:b0:6c:3e:ab:95 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: go-build-env + β”œ───────── uuid: 650dbbe7-3949-4c93-88e7-6619a9216e0c + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ──────── image: oci://unikraft.io//go-build-env@sha256:1f57e9bb8702d031743acf43164b24cf182158c398f1eda8c5583208ccc9c300 + β”œ─────── memory: 512 MiB + β”œ─ private fqdn: go-build-env.internal + β””─── private ip: 10.0.5.4 +``` + + + +This instance is short-lived, since right before the server starts, it triggers a conversion into a template. +To check that the template is ready, run: + + + +```bash title="unikraft" +unikraft instances templates list +``` + +```bash title="kraft" +kraft cloud instance template list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS CREATED +fra go-build-env template acioc/go-build-env 512MiB 1 just now +``` + +```ansi title="kraft" +NAME IMAGE ARGS CREATED AT +go-build-env oci://unikraft.io/acioc/go-build-env@sha256:1cbd6474386c9df546820cd0522030a1bd8702c59490548f10ae10fb8b0a6e14 20 seconds ago +``` + + + +### Step 3: Package ROM payloads + +Each ROM contains a Go function implementation. + + + +```bash title="unikraft" +unikraft build rom1/ --output /go-rom1:latest +unikraft build rom2/ --output /go-rom2:latest +``` + +```bash title="kraft" +kraft pkg \ + --rom ./fs \ + --rom-type erofs \ + --plat kraftcloud \ + --arch x86_64 \ + --name index.unikraft.io//go-rom1:latest \ + --push \ + rom1/ +kraft pkg \ + --rom ./fs \ + --rom-type erofs \ + --plat kraftcloud \ + --arch x86_64 \ + --name index.unikraft.io//go-rom2:latest \ + --push \ + rom2/ +``` + + + +### Step 4: Launch test environments from template + +Create an instance with the first ROM: + + + +```bash title="unikraft" +unikraft run --metro fra \ + --name go-build-env-rom1 \ + -p 443:8080/tls+http \ + --scale-to-zero policy=on,cooldown-time=1000,stateful=true \ + --rom /go-rom1:latest:/rom:go_function \ + --template go-build-env +``` + +```bash title="kraft" +# kraft does not support creating instances with attached ROMs, but you can use the API directly +curl -X POST "$UKC_METRO/instances" \ + -H "Accept: application/json" \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "go-build-env-rom1", + "template": { + "name": "go-build-env" + }, + "autostart": true, + "service_group": { + "services": [ + { + "port": 443, + "destination_port": 8080, + "handlers": ["tls", "http"] + } + ] + }, + "scale_to_zero": { + "policy": "on", + "stateful": true, + "cooldown_time_ms": 1000 + }, + "roms": [ + { + "name": "go_function", + "image": "index.unikraft.io//go-rom1:latest", + "at": "/rom" + } + ] +}' +``` + + + +The instance will compile the ROM into a plugin on first start, which may take a few seconds. +To check the progress, you can view the instance logs: + + + +```bash title="unikraft" +unikraft instances logs go-build-env-rom1 -f +``` + +```bash title="kraft" +kraft cloud instance logs go-build-env-rom1 -f +``` + + + +Grab the fqdn from the output and test the instance. +You should see the output from the first ROM function: + +```bash +curl https:// +``` + +```text +Bye, World! +``` + +Create another instance with the second ROM: + + + +```bash title="unikraft" +unikraft run --metro fra \ + --name go-build-env-rom2 \ + -p 443:8080/tls+http \ + --scale-to-zero policy=on,cooldown-time=1000,stateful=true \ + --rom /go-rom2:latest:/rom:go_function \ + --template go-build-env +``` + +```bash title="kraft" +# kraft does not support creating instances with attached ROMs, but you can use the API directly +curl -X POST "$UKC_METRO/instances" \ + -H "Accept: application/json" \ + -H "Authorization: Bearer $UKC_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "go-build-env-rom2", + "template": { + "name": "go-build-env" + }, + "autostart": true, + "service_group": { + "services": [ + { + "port": 443, + "destination_port": 8080, + "handlers": ["tls", "http"] + } + ] + }, + "scale_to_zero": { + "policy": "on", + "stateful": true, + "cooldown_time_ms": 1000 + }, + "roms": [ + { + "name": "go_function", + "image": "index.unikraft.io//go-rom2:latest", + "at": "/rom" + } + ] +}' +``` + + + +The instance will compile the ROM into a plugin on first start, which may take a few seconds. +To check the progress, you can view the instance logs: + + + +```bash title="unikraft" +unikraft instances logs go-build-env-rom2 -f +``` + +```bash title="kraft" +kraft cloud instance logs go-build-env-rom2 -f +``` + + + +Grab the fqdn from the output and test the instance. +You should see the output from the second ROM function: + +```bash +curl https:// +``` + +```text +Auf Wiedersehen! +``` + +Both instances run the same base Go runtime, but execute different ROM payloads, demonstrating fast iteration with reusable layers. + +You can list information about the instances by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra go-build-rom2 standby acioc/go-build-env 512MiB 1 nameless-wood-gw7pbnls.fra0-sandbox.unikraft.app 2 minutes ago +fra go-build-rom1 standby acioc/go-build-env 512MiB 1 sparkling-dawn-syowlbtj.fra0-sandbox.unikraft.app 3 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +go-build-rom2 nameless-wood-gw7pbnls.fra0-sandbox.unikraft.app standby standby oci://unikraft.io/acioc/go-build-env@sha256:1cbd64... 512 MiB 1 6.98 ms +go-build-rom1 sparkling-dawn-syowlbtj.fra0-sandbox.unikraft.app standby standby oci://unikraft.io/acioc/go-build-env@sha256:1cbd64... 512 MiB 1 7.86 ms +``` + + + +## Why this pattern works + +This build/test environment uses three reusable layers: + +1. **Base runtime image**: +A Go server plus toolchain. +Build once, reuse many times. + +1. **ROM payload**: +A source-only image (`rom.go`). +Update per test case. + +1. **Template snapshot**: +A pre-initialized runtime used to speed up new instance startup. + +## Cleanup + + + +```bash title="unikraft" +unikraft instances delete go-build-env-rom1 go-build-env-rom2 +unikraft instances template delete go-build-env +``` + +```bash title="kraft" +kraft cloud instance remove go-build-env-rom1 go-build-env-rom2 +kraft cloud instance template remove go-build-env +``` + + + +## Learn more + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the [legacy CLI reference](/docs/cli/kraft/overview). diff --git a/zudoku.config.tsx b/zudoku.config.tsx index fafa7d37..dc55426c 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -91,6 +91,7 @@ const config: ZudokuConfig = { "/use-cases/api-gateways", "/use-cases/serverless-functions", "/use-cases/serverless-databases", + "/use-cases/build-test-environments", "/use-cases/webhooks", "/use-cases/remote-ides", ], From 0b0fccf24b01c9e4f809cc3c7b70bd49f6fda984 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Sat, 9 May 2026 16:29:47 +0300 Subject: [PATCH 116/131] fix(use-cases): Update ROM commands Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/build-test-environments.mdx | 4 ++-- pages/use-cases/serverless-functions.mdx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pages/use-cases/build-test-environments.mdx b/pages/use-cases/build-test-environments.mdx index e15f9bd0..ee7383f8 100644 --- a/pages/use-cases/build-test-environments.mdx +++ b/pages/use-cases/build-test-environments.mdx @@ -232,7 +232,7 @@ unikraft run --metro fra \ --name go-build-env-rom1 \ -p 443:8080/tls+http \ --scale-to-zero policy=on,cooldown-time=1000,stateful=true \ - --rom /go-rom1:latest:/rom:go_function \ + --rom image=/go-rom1:latest,at=/rom \ --template go-build-env ``` @@ -309,7 +309,7 @@ unikraft run --metro fra \ --name go-build-env-rom2 \ -p 443:8080/tls+http \ --scale-to-zero policy=on,cooldown-time=1000,stateful=true \ - --rom /go-rom2:latest:/rom:go_function \ + --rom image=/go-rom2:latest,at=/rom \ --template go-build-env ``` diff --git a/pages/use-cases/serverless-functions.mdx b/pages/use-cases/serverless-functions.mdx index 0c5272ed..c9220181 100644 --- a/pages/use-cases/serverless-functions.mdx +++ b/pages/use-cases/serverless-functions.mdx @@ -235,7 +235,7 @@ unikraft run --metro fra \ --name node-exec-rom1 \ -p 443:8080/tls+http \ --scale-to-zero policy=on,cooldown-time=1000,stateful=true \ - --rom /node-rom1:latest:/rom:js_function \ + --rom image=/node-rom1:latest,at=/rom \ --template node-exec ``` @@ -296,7 +296,7 @@ unikraft run --metro fra \ --name node-exec-rom2 \ -p 443:8080/tls+http \ --scale-to-zero policy=on,cooldown-time=1000,stateful=true \ - --rom /node-rom2:latest:/rom:ts_function \ + --rom image=/node-rom2:latest,at=/rom \ --template node-exec ``` From 1f5d0b54fd0c0761b821d8cceba690b4f98effc2 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Sat, 9 May 2026 16:44:46 +0300 Subject: [PATCH 117/131] fix(use-cases): Remove acioc user mention Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/build-test-environments.mdx | 20 ++++++++++---------- pages/use-cases/serverless-functions.mdx | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pages/use-cases/build-test-environments.mdx b/pages/use-cases/build-test-environments.mdx index e15f9bd0..368f3223 100644 --- a/pages/use-cases/build-test-environments.mdx +++ b/pages/use-cases/build-test-environments.mdx @@ -178,13 +178,13 @@ kraft cloud instance template list ```ansi title="unikraft" -METRO NAME STATE IMAGE ARGS MEMORY VCPUS CREATED -fra go-build-env template acioc/go-build-env 512MiB 1 just now +METRO NAME STATE IMAGE ARGS MEMORY VCPUS CREATED +fra go-build-env template /go-build-env 512MiB 1 just now ``` ```ansi title="kraft" -NAME IMAGE ARGS CREATED AT -go-build-env oci://unikraft.io/acioc/go-build-env@sha256:1cbd6474386c9df546820cd0522030a1bd8702c59490548f10ae10fb8b0a6e14 20 seconds ago +NAME IMAGE ARGS CREATED AT +go-build-env oci://unikraft.io//go-build-env@sha256:1cbd6474386c9df546820cd0522030a1bd8702c59490548f10ae10fb8b0a6e14 20 seconds ago ``` @@ -396,15 +396,15 @@ kraft cloud instance list ```ansi title="unikraft" -METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED -fra go-build-rom2 standby acioc/go-build-env 512MiB 1 nameless-wood-gw7pbnls.fra0-sandbox.unikraft.app 2 minutes ago -fra go-build-rom1 standby acioc/go-build-env 512MiB 1 sparkling-dawn-syowlbtj.fra0-sandbox.unikraft.app 3 minutes ago +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra go-build-rom2 standby /go-build-env 512MiB 1 nameless-wood-gw7pbnls.fra0-sandbox.unikraft.app 2 minutes ago +fra go-build-rom1 standby /go-build-env 512MiB 1 sparkling-dawn-syowlbtj.fra0-sandbox.unikraft.app 3 minutes ago ``` ```ansi title="kraft" -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -go-build-rom2 nameless-wood-gw7pbnls.fra0-sandbox.unikraft.app standby standby oci://unikraft.io/acioc/go-build-env@sha256:1cbd64... 512 MiB 1 6.98 ms -go-build-rom1 sparkling-dawn-syowlbtj.fra0-sandbox.unikraft.app standby standby oci://unikraft.io/acioc/go-build-env@sha256:1cbd64... 512 MiB 1 7.86 ms +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +go-build-rom2 nameless-wood-gw7pbnls.fra0-sandbox.unikraft.app standby standby oci://unikraft.io//go-build-env@sha256:1cbd64... 512 MiB 1 6.98 ms +go-build-rom1 sparkling-dawn-syowlbtj.fra0-sandbox.unikraft.app standby standby oci://unikraft.io//go-build-env@sha256:1cbd64... 512 MiB 1 7.86 ms ``` diff --git a/pages/use-cases/serverless-functions.mdx b/pages/use-cases/serverless-functions.mdx index 0c5272ed..338713c3 100644 --- a/pages/use-cases/serverless-functions.mdx +++ b/pages/use-cases/serverless-functions.mdx @@ -176,13 +176,13 @@ kraft cloud instance template list ```ansi title="unikraft" -METRO NAME STATE IMAGE ARGS MEMORY VCPUS CREATED -fra node-exec template acioc/node-code-exec 512MiB 1 just now +METRO NAME STATE IMAGE ARGS MEMORY VCPUS CREATED +fra node-exec template /node-code-exec 512MiB 1 just now ``` ```ansi title="kraft" -NAME IMAGE ARGS CREATED AT -node-exec oci://unikraft.io/acioc/node-code-exec@sha256:71487fd6196987cf65fb89eb84405cb796677aba177dabacf391f09618313328 20 seconds ago +NAME IMAGE ARGS CREATED AT +node-exec oci://unikraft.io//node-code-exec@sha256:71487fd6196987cf65fb89eb84405cb796677aba177dabacf391f09618313328 20 seconds ago ``` From 587d49c178e8063d380c31a78e5411980099887a Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Sat, 9 May 2026 19:28:25 +0300 Subject: [PATCH 118/131] fix(use-cases): Refactor instance listing for new use cases Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/build-test-environments.mdx | 48 ++++++++------------- pages/use-cases/serverless-functions.mdx | 37 ++++++---------- 2 files changed, 33 insertions(+), 52 deletions(-) diff --git a/pages/use-cases/build-test-environments.mdx b/pages/use-cases/build-test-environments.mdx index 368f3223..5e974258 100644 --- a/pages/use-cases/build-test-environments.mdx +++ b/pages/use-cases/build-test-environments.mdx @@ -289,17 +289,6 @@ kraft cloud instance logs go-build-env-rom1 -f -Grab the fqdn from the output and test the instance. -You should see the output from the first ROM function: - -```bash -curl https:// -``` - -```text -Bye, World! -``` - Create another instance with the second ROM: @@ -366,20 +355,9 @@ kraft cloud instance logs go-build-env-rom2 -f -Grab the fqdn from the output and test the instance. -You should see the output from the second ROM function: - -```bash -curl https:// -``` - -```text -Auf Wiedersehen! -``` - Both instances run the same base Go runtime, but execute different ROM payloads, demonstrating fast iteration with reusable layers. -You can list information about the instances by running: +List the instances and note their FQDN values: @@ -396,19 +374,31 @@ kraft cloud instance list ```ansi title="unikraft" -METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED -fra go-build-rom2 standby /go-build-env 512MiB 1 nameless-wood-gw7pbnls.fra0-sandbox.unikraft.app 2 minutes ago -fra go-build-rom1 standby /go-build-env 512MiB 1 sparkling-dawn-syowlbtj.fra0-sandbox.unikraft.app 3 minutes ago +[1mMETRO[0m [1mNAME[0m [1mSTATE[0m [1mIMAGE[0m [1mARGS[0m [1mMEMORY[0m [1mVCPUS[0m [1mFQDN[0m [1mCREATED[0m +fra go-build-env-rom2 [94mstandby[0m /go-build-env 512MiB 1 nameless-wood-gw7pbnls.fra.unikraft.app 2 minutes ago +fra go-build-env-rom1 [94mstandby[0m /go-build-env 512MiB 1 sparkling-dawn-syowlbtj.fra.unikraft.app 3 minutes ago ``` ```ansi title="kraft" -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -go-build-rom2 nameless-wood-gw7pbnls.fra0-sandbox.unikraft.app standby standby oci://unikraft.io//go-build-env@sha256:1cbd64... 512 MiB 1 6.98 ms -go-build-rom1 sparkling-dawn-syowlbtj.fra0-sandbox.unikraft.app standby standby oci://unikraft.io//go-build-env@sha256:1cbd64... 512 MiB 1 7.86 ms +[1mNAME[0m [1mFQDN[0m [1mSTATE[0m [1mSTATUS[0m [1mIMAGE[0m [1mMEMORY[0m [1mVCPUS[0m [1mARGS[0m [1mBOOT TIME[0m +go-build-env-rom2 nameless-wood-gw7pbnls.fra.unikraft.app [94mstandby[0m standby oci://unikraft.io//go-build-env@sha256:1cbd64... 512 MiB 1 6.98 ms +go-build-env-rom1 sparkling-dawn-syowlbtj.fra.unikraft.app [94mstandby[0m standby oci://unikraft.io//go-build-env@sha256:1cbd64... 512 MiB 1 7.86 ms ``` +Test both instances using the FQDNs from the listing: + +```bash +curl https://sparkling-dawn-syowlbtj.fra.unikraft.app +curl https://nameless-wood-gw7pbnls.fra.unikraft.app +``` + +```text +Bye, World! +Auf Wiedersehen! +``` + ## Why this pattern works This build/test environment uses three reusable layers: diff --git a/pages/use-cases/serverless-functions.mdx b/pages/use-cases/serverless-functions.mdx index 338713c3..b620f570 100644 --- a/pages/use-cases/serverless-functions.mdx +++ b/pages/use-cases/serverless-functions.mdx @@ -277,16 +277,6 @@ curl -X POST "$UKC_METRO/instances" \ -Test the first instance: - -```bash -curl https:// -``` - -```text -Bye, World! -``` - Create the second instance with the TypeScript ROM attached: @@ -338,19 +328,9 @@ curl -X POST "$UKC_METRO/instances" \ -Test the second instance: - -```bash -curl https:// -``` - -```text -Auf Wiedersehen! -``` - Both instances run the same base Node.js runtime but execute different function codeβ€”without any rebuild of the runtime image. -You can list information about the instances by running: +List the instances and note their FQDN values: @@ -367,19 +347,30 @@ kraft cloud instance list ```ansi title="unikraft" -METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +[1mMETRO[0m [1mNAME[0m [1mSTATE[0m [1mIMAGE[0m [1mARGS[0m [1mMEMORY[0m [1mVCPUS[0m [1mFQDN[0m [1mCREATED[0m fra node-exec-rom2 standby /node-code-exec 512MiB 1 nameless-wood-gw7pbnls.fra.unikraft.app 2 minutes ago fra node-exec-rom1 standby /node-code-exec 512MiB 1 sparkling-dawn-syowlbtj.fra.unikraft.app 3 minutes ago ``` ```ansi title="kraft" -NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +[1mNAME[0m [1mFQDN[0m [1mSTATE[0m [1mSTATUS[0m [1mIMAGE[0m [1mMEMORY[0m [1mVCPUS[0m [1mARGS[0m [1mBOOT TIME[0m node-exec-rom2 nameless-wood-gw7pbnls.fra.unikraft.app standby standby oci://unikraft.io//node-code-exec@sha256:71487f... 512 MiB 1 6.98 ms node-exec-rom1 sparkling-dawn-syowlbtj.fra.unikraft.app standby standby oci://unikraft.io//node-code-exec@sha256:71487f... 512 MiB 1 7.86 ms ``` +Test both instances using the FQDNs from the listing: + +```bash +curl https://sparkling-dawn-syowlbtj.fra.unikraft.app +curl https://nameless-wood-gw7pbnls.fra.unikraft.app +``` + +```text +Bye, World! +Auf Wiedersehen! +``` ## How it works From 995162b21fc364c93d60f82e06e8b35f2c8cdd42 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Sat, 9 May 2026 20:10:23 +0300 Subject: [PATCH 119/131] feat(use-cases): Add game servers Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/minecraft.mdx | 288 ++++++++++++++++++++++++++++++++++ zudoku.config.tsx | 1 + 2 files changed, 289 insertions(+) create mode 100644 pages/use-cases/minecraft.mdx diff --git a/pages/use-cases/minecraft.mdx b/pages/use-cases/minecraft.mdx new file mode 100644 index 00000000..733d6884 --- /dev/null +++ b/pages/use-cases/minecraft.mdx @@ -0,0 +1,288 @@ +--- +title: Game Servers +navigation_icon: gamepad-2 +--- + +Running multiplayer game servers often means keeping long-lived VMs online, pre-warming for peak hours, and paying for idle time between sessions. +On Unikraft Cloud, you can run game servers in microVMs with [stateful scale-to-zero](/features/scale-to-zero#stateful-scale-to-zero), so instances pause when idle and resume when players reconnect. + +Minecraft is a strong example of this pattern. +JVM startup and world initialization are expensive, but template snapshots and stateful resume keep player experience smooth without running infrastructure every day. + +## Why use Unikraft Cloud for game servers + +### Fast restarts from template snapshots + +Game servers often have expensive startup paths: loading assets, initializing runtime state, and binding network services. +Unikraft Cloud's [instance templates](/platform/instances#instance-templates) snapshot the server after initialization, so later starts resume from a warm state instead of repeating full initialization. +For Minecraft specifically, this avoids repeated JVM warm-up and world initialization work. + +### Stateful scale-to-zero + +When all players disconnect, the instance enters standby and consumes no active resources. +On the next connection it wakes from the same in-memory snapshot, preserving server state without a full restart. +For Minecraft, this means your world and server process resume from snapshot instead of cold booting. + +### Isolation per server + +Each server runs in its own microVM: no shared kernel with other tenants, no container escape surface, and no noisy-neighbour risk. + +### Quick iteration with ROM + +Server settings can ship as auxiliary ROMs at instance creation time. +You can run distinct game-server variants by swapping ROM configuration rather than rebuilding the base image. + +## Getting started + +This guide uses the [`minecraft`](https://github.com/unikraft-cloud/examples/tree/main/minecraft) example. +The base image is built from [itzg/minecraft-server](https://hub.docker.com/r/itzg/minecraft-server) (Java 25) and includes: + +- A `wrapper.sh` entrypoint that starts SSH, loads ROM configuration, and disables scale-to-zero during initialization. +- Patched startup scripts that snapshot the instance into a template before full server warm-up. + +### Prerequisites + +1. Install the [unikraft CLI](/docs/cli/unikraft). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/minecraft/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/minecraft/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + +```bash title="unikraft" +unikraft login +``` + +3. Review and adjust the base server settings in [`base/.env`](https://github.com/unikraft-cloud/examples/tree/main/minecraft/base/.env). + You can check out [this documentation](https://docker-minecraft-server.readthedocs.io/en/latest/) for available configuration options. + Make sure to also set your `PUBKEY` for SSH access, and optionally set `TEMPLATE_WITH_WORLD` if you want the template to include the world (see below). + Optionally, create per-config overrides in `/.env`. + All `.env` files are packaged as [auxiliary ROMs](/features/roms) and mounted at `/rom/`. + +### Step 1: Package and push the base image + +First, package and push the base Minecraft server image: + +```bash title="unikraft" +unikraft build . --output /minecraft:latest +``` + +The image contains the files from the Docker image [itzg/minecraft-server](https://hub.docker.com/r/itzg/minecraft-server) and includes a few tweaks: + +- The entrypoint uses a custom `wrapper.sh` script that: + - Starts an SSH server + - Loads the environment configuration from the attached ROMs + - Disables scale-to-zero before executing the original entrypoint +- The server configuration scripts from the original image have patches to trigger the template snapshot before the full warm-up of the server, which allows faster instance creation from the template. + Scale-to-zero is then re-enabled after server initialization. + +### Step 2: Create a template from the base image + +Boot a short-lived instance from the base image. +The startup script snapshots it into a template before world generation, then the instance exits. + +Pass your server settings as a ROM: + +```bash title="unikraft" +unikraft run --metro fra \ + --name minecraft-tpl \ + -m 4096M \ + --vcpus 4 \ + --image /minecraft:latest \ + --rom dir=base,at=/rom/base +``` + +The output shows the instance details: + +```ansi title="unikraft" +metro: fra +name: minecraft-tpl +uuid: d9d7be54-5495-45d0-b5af-48be7f30d1d8 +state: starting +image: /minecraft +resources: + memory: 4GiB + vcpus: 4 +roms: +- name: rom + image: c99125f6-6b8c-4f94-b94c-e2d9551b253b + at: /rom +networks: +- uuid: 123b0ed0-9f2f-417c-9307-34424d80e4cb + private-ip: 10.0.0.29 + mac: 12:b0:0a:00:00:1d +timestamps: + created: just now +``` + +If you also have per-config overrides (for example in `bingo/.env`), create the instance with more ROMs: + +```bash title="unikraft" +unikraft run --metro fra \ + --name minecraft-tpl \ + -m 4096M \ + --vcpus 4 \ + --image /minecraft:latest \ + --rom dir=base,at=/rom/base \ + --rom dir=bingo,at=/rom/bingo +``` + +The instance runs until initialization completes, then the platform snapshots it as a template and immediately deletes it. +You can configure the exact moment of snapshotting in [`patches/start-finalExec`](https://github.com/unikraft-cloud/examples/tree/main/minecraft/patches/start-finalExec) or with the following environment variable: + +- If `TEMPLATE_WITH_WORLD=true`, then the snapshot will trigger **after** world generation +- Otherwise, the snapshot will trigger after extracting the jar files and writing configuration files, **before** world generation + +Follow the template instance logs until they stop: + +```bash title="unikraft" +unikraft instances logs minecraft-tpl -f +``` + +Confirm the template is ready: + +```bash title="unikraft" +unikraft instances templates list +``` + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS CREATED +fra minecraft-tpl template /minecraft 4GiB 4 5 seconds ago +``` + +### Step 3: Launch a server from the template + +```bash title="unikraft" +unikraft run --metro fra \ + --name minecraft \ + -p 2222:2222/tls \ + -p 25565:25565/tls \ + --scale-to-zero policy=on,cooldown-time=5000,stateful=true \ + --template minecraft-tpl +``` + +The output includes the service address: + +```ansi title="unikraft" +metro: fra +name: minecraft +uuid: 56787b5d-14fb-4908-88d0-e9609d1ac1e0 +state: running +image: /minecraft +resources: + memory: 4GiB + vcpus: 4 +service: hidden-water-ewr8l9sp +roms: +- name: rom + image: c99125f6-6b8c-4f94-b94c-e2d9551b253b + at: /rom +networks: +- uuid: b6c7d615-7e74-49d6-a8b6-14c39323233b + private-ip: 10.0.0.29 + mac: 12:b0:0a:00:00:1d +timestamps: + created: just now +scale-to-zero: policy=on,stateful=true,cooldown-time=5s +``` + +The instance address is `https://hidden-water-ewr8l9sp.fra.unikraft.app`. +Follow the logs until the server is ready: + +```bash title="unikraft" +unikraft instances logs minecraft -f +``` + +```text +[12:59:45] [Server thread/INFO]: Preparing spawn area: 100% +[12:59:45] [Server thread/INFO]: Time elapsed: 3641 ms +[12:59:45] [Server thread/INFO]: Done (3.850s)! For help, type "help" +[12:59:45] [Server thread/INFO]: Starting remote control listener +[12:59:45] [Server thread/INFO]: Thread RCON Listener started +[12:59:45] [Server thread/INFO]: RCON running on 0.0.0.0:25575 +[12:59:45] [Server thread/INFO]: Saving chunks for level 'ServerLevel[world]'/minecraft:overworld +[12:59:45] [Server thread/INFO]: Saving chunks for level 'ServerLevel[world]'/minecraft:the_end +[12:59:45] [Server thread/INFO]: Saving chunks for level 'ServerLevel[world]'/minecraft:the_nether +[12:59:45] [Server thread/INFO]: ThreadedAnvilChunkStorage (world): All chunks are saved +[12:59:45] [Server thread/INFO]: ThreadedAnvilChunkStorage (DIM1): All chunks are saved +[12:59:45] [Server thread/INFO]: ThreadedAnvilChunkStorage (DIM-1): All chunks are saved +[12:59:45] [Server thread/INFO]: ThreadedAnvilChunkStorage: All dimensions are saved +``` + +## Connect to the server + +:::caution[**DISCLAIMER**] +At the moment, Unikraft Cloud exposes services over TLS. +Minecraft and SSH clients speak plain TCP, so use `socat` to end TLS locally. +::: + +### Minecraft + +```bash +socat TCP-LISTEN:25565,reuseaddr,fork OPENSSL:hidden-water-ewr8l9sp.fra.unikraft.app:25565,verify=0 +``` + +Connect your Minecraft client to `localhost:25565`. + +### SSH + +```bash +socat TCP-LISTEN:2222,reuseaddr,fork OPENSSL:hidden-water-ewr8l9sp.fra.unikraft.app:2222,verify=0 +``` + +Connect to `localhost:2222` with username `root` and the SSH key set in `.env`. + +## Administration + +### Remote console + +SSH into the instance, then: + +```bash +rcon-cli --host 127.0.0.1 +``` + +Example commands: + +```text +say Hello from Unikraft Cloud! +/op +``` + +### Whitelist in offline mode + +Offline mode generates UUIDs that differ from online UUIDs. +Compute the correct UUID per username and add it to `/data/whitelist.json`: + +```python +import hashlib, uuid; h = hashlib.md5(b'OfflinePlayer:').digest(); u = uuid.UUID(bytes=h); print(u) +``` + +## Cleanup + +```bash title="unikraft" +unikraft instances delete minecraft +unikraft instances template delete minecraft-tpl +``` + +## Learn more + +```bash title="unikraft" +unikraft --help +``` + +Or visit the [CLI Reference](/docs/cli/unikraft). + +For more information on the features used in this use case and how to use them, check out the following documentation: + +* [Instance templates](/platform/instances#instance-templates) +* [Scale-to-zero](/features/scale-to-zero) +* [ROMs](/features/roms) +* [`minecraft` example](https://github.com/unikraft-cloud/examples/tree/main/minecraft) +* [itzg/minecraft-server documentation](https://docker-minecraft-server.readthedocs.io/en/latest/) diff --git a/zudoku.config.tsx b/zudoku.config.tsx index dc55426c..95cad84a 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -94,6 +94,7 @@ const config: ZudokuConfig = { "/use-cases/build-test-environments", "/use-cases/webhooks", "/use-cases/remote-ides", + "/use-cases/minecraft", ], }, { From ee356097dd97ec9871749b620c2489f670b887e3 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Fri, 24 Apr 2026 13:13:13 +0300 Subject: [PATCH 120/131] chore: Make guides sync automated Signed-off-by: Alex-Andrei Cioc --- .github/workflows/sync.yaml | 17 +++++++++++++---- scripts/transform_readme.py | 3 ++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/sync.yaml b/.github/workflows/sync.yaml index 889d0212..4012d8d2 100644 --- a/.github/workflows/sync.yaml +++ b/.github/workflows/sync.yaml @@ -1,6 +1,8 @@ name: sync on: + schedule: + - cron: '17 3 */2 * *' workflow_dispatch: inputs: examples_branch: @@ -21,6 +23,7 @@ concurrency: permissions: contents: read + pull-requests: read jobs: sync: @@ -48,6 +51,12 @@ jobs: BRANCH="sync/examples-$(date +'%Y%m%d%H%M%S')" echo "name=${BRANCH}" >>"${GITHUB_OUTPUT}" + - name: Generate timestamp + id: timestamp + run: | + TIMESTAMP=$(date -u +"%Y-%m-%d %H:%M:%S UTC") + echo "value=${TIMESTAMP}" >>"${GITHUB_OUTPUT}" + - name: Create pull request uses: peter-evans/create-pull-request@v6 with: @@ -56,14 +65,14 @@ jobs: commit-message: "chore: Update guides from examples repository" title: "chore: Update guides from examples repository" body: | - IMPORTANT: Please make sure to review the deployment of this PR and also update `zudoku.config.ts` and `pages/guides/overview.mdx` if necessary. + IMPORTANT: Please make sure to review the deployment of this PR and also update `zudoku.config.tsx` and `pages/guides/overview.mdx` if necessary. - Automated sync of example READMEs from [`unikraft/examples@${{ inputs.examples_branch }}`](https://github.com/unikraft/examples/tree/${{ inputs.examples_branch }}). + Automated sync of example READMEs from [`unikraft-cloud/examples@${{ inputs.examples_branch || 'main' }}`](https://github.com/unikraft-cloud/examples/tree/${{ inputs.examples_branch || 'main' }}). This PR updates the guides in `pages/guides/` with the latest content from the examples repository. - **Branch:** `${{ inputs.examples_branch }}` - **Timestamp:** $(date -u +"%Y-%m-%d %H:%M:%S UTC") + **Branch:** `${{ inputs.examples_branch || 'main' }}` + **Timestamp:** ${{ steps.timestamp.outputs.value }} branch: ${{ steps.id.outputs.name }} committer: Unikraft Bot author: Unikraft Bot diff --git a/scripts/transform_readme.py b/scripts/transform_readme.py index aaa68aa1..bb36dd63 100755 --- a/scripts/transform_readme.py +++ b/scripts/transform_readme.py @@ -36,6 +36,7 @@ # Import statement for Tabs component TABS_IMPORT = 'import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs"\n\n' +GENERATED_FILE_COMMENT = "{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */}\n\n" # Regex patterns FENCE_PATTERN = re.compile(r"(^```([^\n]*)\n)(.*?)(\n```)$", flags=re.M | re.S) @@ -54,7 +55,7 @@ def extract_title(text: str, example_name: str | None) -> str: def ensure_front_matter(text: str, title: str) -> str: """Ensure YAML front-matter with title at the top, replacing existing if present.""" - fm = f"---\ntitle: \"{title}\"\n---\n\n" + fm = f"---\ntitle: \"{title}\"\n---\n\n{GENERATED_FILE_COMMENT}" m = FRONT_MATTER_PATTERN.match(text) if m: return fm + text[m.end():] From 57ea1f998d3754dc45b8f173fd8bfb4f368a7d43 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 12 May 2026 12:14:10 +0300 Subject: [PATCH 121/131] fix(scripts): Better conversion of quotes to admonitions for mdx Signed-off-by: Alex-Andrei Cioc --- scripts/transform_readme.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/transform_readme.py b/scripts/transform_readme.py index aaa68aa1..a3aa3847 100755 --- a/scripts/transform_readme.py +++ b/scripts/transform_readme.py @@ -40,7 +40,7 @@ # Regex patterns FENCE_PATTERN = re.compile(r"(^```([^\n]*)\n)(.*?)(\n```)$", flags=re.M | re.S) FRONT_MATTER_PATTERN = re.compile(r"^---\n.*?\n---\n\s*", flags=re.S) -ADMONITION_PATTERN = re.compile(r"^>\s*\*\*([^*]+)\*\*:\s*$") +ADMONITION_PATTERN = re.compile(r"^>\s*\*\*([^*]+?):?\*\*:?\s*$") def extract_title(text: str, example_name: str | None) -> str: @@ -95,7 +95,7 @@ def convert_admonitions(text: str) -> str: while i < len(lines): m = ADMONITION_PATTERN.match(lines[i]) if m: - label = m.group(1).strip() + label = m.group(1).strip().rstrip(":") key = label.lower().replace(" ", "-") i += 1 block = [] From b18d180657e34448153a0585d445e7efddd7f3f1 Mon Sep 17 00:00:00 2001 From: Dragos Gheorghioiu Date: Tue, 12 May 2026 15:16:47 +0300 Subject: [PATCH 122/131] feat: remove the cli labels when converting to mdx Signed-off-by: Dragos Gheorghioiu --- scripts/transform_readme.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/transform_readme.py b/scripts/transform_readme.py index f58811ae..4a633c1e 100755 --- a/scripts/transform_readme.py +++ b/scripts/transform_readme.py @@ -121,6 +121,14 @@ def rewrite_urls(text: str) -> str: return text +def remove_cli_section_labels(text: str) -> str: + """Remove bold CLI section labels from examples READMEs.""" + pattern = re.compile( + r"(?m)^\*\*(Using the unikraft CLI \(Recommended\)|Using the legacy kraft CLI)\*\*\s*$\n?" + ) + return pattern.sub("", text) + + def convert_code_tabs(text: str) -> str: """Group adjacent code blocks containing title="..." inside a wrapper.""" block_pattern = re.compile(r"(```([^\n]*?title=\"([^\"]+)\"[^\n]*)\n.*?\n```)", flags=re.S) @@ -485,6 +493,7 @@ def main(argv: list[str] | None = None) -> int: content = insert_tabs_import(content, title) content = convert_admonitions(content) content = rewrite_urls(content) + content = remove_cli_section_labels(content) content = convert_code_tabs(content) content = color_deployed_block(content) content = color_yaml_deploy_block(content) From 90a7ef716fedb6d7ddf5b4f5cf05e83ba1d2e896 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 12 May 2026 19:21:46 +0300 Subject: [PATCH 123/131] feat(scripts): Add script to update zudoku guides list Signed-off-by: Alex-Andrei Cioc --- Makefile | 5 +- scripts/update_zudoku_guides.py | 106 ++++++++++++++++++++++++++++++++ zudoku.config.tsx | 26 ++++---- 3 files changed, 123 insertions(+), 14 deletions(-) create mode 100755 scripts/update_zudoku_guides.py diff --git a/Makefile b/Makefile index 2e6286c5..2c16a4c2 100644 --- a/Makefile +++ b/Makefile @@ -68,6 +68,9 @@ sync: echo " πŸ—‘ Removing stale guide: $$gname"; \ rm -f "$$guide"; \ fi; \ - done + done; \ + $(WORKDIR)/scripts/update_zudoku_guides.py "$(GUIDES_DIR)" "$(WORKDIR)/zudoku.config.tsx" .PHONY: sync-list +sync-list: + $(WORKDIR)/scripts/update_zudoku_guides.py "$(GUIDES_DIR)" "$(WORKDIR)/zudoku.config.tsx" diff --git a/scripts/update_zudoku_guides.py b/scripts/update_zudoku_guides.py new file mode 100755 index 00000000..d4fdad02 --- /dev/null +++ b/scripts/update_zudoku_guides.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +""" +Rewrite the guides list in zudoku.config.tsx based on the MDX files in pages/guides/. + +For each MDX file (except overview.mdx) the title is read from the YAML front-matter. +Entries are sorted alphabetically by title. The overview entry is always first. + +Usage: update_zudoku_guides.py GUIDES_DIR ZUDOKU_CONFIG +""" +from __future__ import annotations + +import re +import sys +from pathlib import Path + + +FRONT_MATTER_TITLE = re.compile(r'^title:\s*["\']?(.+?)["\']?\s*$', re.MULTILINE) + +# Matches the entire items array inside the "Guides" navigation category. +# Captures the indentation of the first item so we can reproduce it. +GUIDES_ITEMS_PATTERN = re.compile( + r'(label:\s*"Guides"[^[]*items:\s*\[)' # up to and including "items: [" + r'(.*?)' # the current list content (group 2) + r'(\s*\])', # closing "]" with optional whitespace + re.DOTALL, +) + + +def extract_title(mdx_path: Path) -> str: + text = mdx_path.read_text(encoding="utf-8") + m = FRONT_MATTER_TITLE.search(text) + if m: + return m.group(1).strip() + # Fall back to the stem if no front-matter title is found + return mdx_path.stem + + +def build_items_block(guides_dir: Path, indent: str) -> str: + entries: list[tuple[str, str]] = [] # (title, slug) + + for mdx in guides_dir.glob("*.mdx"): + if mdx.stem == "overview": + continue + title = extract_title(mdx) + entries.append((title, mdx.stem)) + + entries.sort(key=lambda t: t[0].casefold()) + + lines: list[str] = [] + lines.append(f'{indent}//TODO: Please keep this list sorted by titles, not filenames !!') + lines.append(f'{indent}"/guides/overview", // Guides Overview') + for title, slug in entries: + lines.append(f'{indent}"/guides/{slug}", // {title}') + + return "\n".join(lines) + "\n" + + +def update_config(guides_dir: Path, config_path: Path) -> None: + content = config_path.read_text(encoding="utf-8") + + match = GUIDES_ITEMS_PATTERN.search(content) + if not match: + print("❌ Could not locate the Guides items list in zudoku.config.tsx", file=sys.stderr) + sys.exit(1) + + # Detect indentation from the first non-empty line inside the current block + current_block = match.group(2) + indent_match = re.search(r'\n(\s+)"/', current_block) + indent = indent_match.group(1) if indent_match else " " + + new_block = build_items_block(guides_dir, indent) + + new_content = ( + content[: match.start(2)] + + "\n" + + new_block + + " ]" # closing "]" with fixed indentation, replacing the captured \s*\] + + content[match.end(3):] + ) + + config_path.write_text(new_content, encoding="utf-8") + print(f" βœ… Updated guides list in {config_path.name} " + f"({len(new_block.splitlines()) - 2} guide entries)") + + +def main() -> None: + if len(sys.argv) != 3: + print(f"Usage: {sys.argv[0]} GUIDES_DIR ZUDOKU_CONFIG", file=sys.stderr) + sys.exit(1) + + guides_dir = Path(sys.argv[1]) + config_path = Path(sys.argv[2]) + + if not guides_dir.is_dir(): + print(f"❌ Guides directory not found: {guides_dir}", file=sys.stderr) + sys.exit(1) + + if not config_path.is_file(): + print(f"❌ Config file not found: {config_path}", file=sys.stderr) + sys.exit(1) + + update_config(guides_dir, config_path) + + +if __name__ == "__main__": + main() diff --git a/zudoku.config.tsx b/zudoku.config.tsx index 95cad84a..b176a74f 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -144,7 +144,7 @@ const config: ZudokuConfig = { "/guides/httpserver-boost1.74-gpp13.2", // C++ Boost HTTP Server "/guides/httpserver-gpp13.2", // C++ HTTP Server "/guides/caddy2.7-go1.21", // Caddy - "/guides/debian-ssh", // Debian SSH Server + "/guides/debian-ssh", // Debian SSH server "/guides/httpserver-python3.12-django5.0", // Django HTTP Server "/guides/dragonflydb", // DragonflyDB "/guides/duckdb-go1.21", // DuckDB with Go @@ -154,7 +154,7 @@ const config: ZudokuConfig = { "/guides/httpserver-python3.12-fastapi-0.121.3", // FastAPI HTTP Server "/guides/httpserver-python3.12-flask3.0-sqlite", // Flask and SQLite HTTP Server "/guides/httpserver-python3.12-flask3.0", // Flask HTTP Server - "/guides/github-webhook-node", // GitHub Webhook Receiver + "/guides/github-webhook-node", // GitHub Webhook receiver "/guides/httpserver-go1.21", // Go HTTP Server "/guides/grafana", // Grafana "/guides/haproxy", // HAProxy @@ -164,7 +164,7 @@ const config: ZudokuConfig = { "/guides/httpserver-lua5.1", // Lua HTTP Server "/guides/mariadb", // MariaDB "/guides/memcached1.6", // Memcached - "/guides/minio", // MinIO + "/guides/minio", // Minio "/guides/mongodb", // MongoDB "/guides/httpserver-node21-nextjs", // Next.js HTTP Server "/guides/nginx", // Nginx @@ -175,10 +175,10 @@ const config: ZudokuConfig = { "/guides/opentelemetry-collector", // OpenTelemetry Collector "/guides/httpserver-perl5.42", // Perl HTTP Server "/guides/httpserver-php8.2", // PHP HTTP Server - "/guides/node-playwright-chromium", // Playwright Chromium (Node) - "/guides/python-playwright-chromium", // Playwright Chromium (Python) - "/guides/node-playwright-firefox", // Playwright Firefox (Node) - "/guides/node-playwright-webkit", // Playwright WebKit (Node) + "/guides/node-playwright-chromium", // Playwright (Chromium) with Node.js + "/guides/python-playwright-chromium", // Playwright (Chromium) with Python FastAPI + "/guides/node-playwright-firefox", // Playwright (Firefox) with Node.js + "/guides/node-playwright-webkit", // Playwright (WebKit) with Node.js "/guides/postgres", // PostgreSQL "/guides/httpserver-prisma-expressjs4.19-node18", // Prisma HTTP Server "/guides/httpserver-node-express-puppeteer", // Puppeteer HTTP Server @@ -195,20 +195,20 @@ const config: ZudokuConfig = { "/guides/mcp-server-simple", // Simple MCP Server "/guides/skipper0.18", // Skipper "/guides/httpserver-node21-solid-start", // SolidJS HTTP Server - "/guides/spin-wagi-http", // Spin (WAGI) + "/guides/spin-wagi-http", // Spin "/guides/httpserver-java17-springboot3.5.x", // Spring Boot HTTP Server - "/guides/httpserver-java17-spring-petclinic", // Spring Petclinic + "/guides/httpserver-java17-spring-petclinic", // Spring PetClinic "/guides/httpserver-c-debug", // SSH and HTTP Server with C and Debugging Tools "/guides/httpserver-node21-sveltekit", // SvelteKit HTTP Server "/guides/traefik", // Traefik "/guides/visual-studio-code-server", // Visual Studio Code Server - "/guides/httpserver-nginx-vite-vanilla", // Vite HTTP Server (Nginx) - "/guides/httpserver-node-vite-vanilla", // Vite HTTP Server (Node) - "/guides/httpserver-node-vite-ssr-vanilla", // Vite SSR HTTP Server (Node) + "/guides/httpserver-node-vite-vanilla", // Vite (vanilla) + "/guides/httpserver-node-vite-ssr-vanilla", // Vite (vanilla) SSR + "/guides/httpserver-nginx-vite-vanilla", // Vite HTTP Server "/guides/vsftpd", // vsftpd "/guides/wazero-import-go", // Wazero "/guides/node18-wingsio", // Wings.io (Node) - "/guides/wordpress-all-in-one", // WordPress + "/guides/wordpress-all-in-one", // Wordpress ] }, { From 96f620690b6246ea9d6dc44209cd6cb1241e7629 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Tue, 12 May 2026 19:27:19 +0300 Subject: [PATCH 124/131] fix(build): Add .dockerignore Signed-off-by: Alex-Andrei Cioc --- .dockerignore | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..df398fbd --- /dev/null +++ b/.dockerignore @@ -0,0 +1,45 @@ +# Vale packages +.vale/styles/* +!.vale/styles/Unikraft/* +!.vale/styles/config/vocabularies/Unikraft/accept.txt + +# Node/Zudoku +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# zudoku +/dist/ +/.zudoku/ + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# env files (can opt-in for commiting if needed) +.env* + +# typescript +*.tsbuildinfo + +# build outputs +dist/ + +# generated files +apis/platform.yaml +build.log +.examples/ From 3e85d37de325f7a86db56859d993ac1d4f6232b2 Mon Sep 17 00:00:00 2001 From: Daniel Vallance Date: Wed, 13 May 2026 11:11:15 +0100 Subject: [PATCH 125/131] fix(sync): Use prod-staging branch of docs repo This will fix the scheduled sync workflows Closes: FIELD-443 Signed-off-by: Daniel Vallance --- .github/workflows/sync.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/sync.yaml b/.github/workflows/sync.yaml index 4012d8d2..a3cbfbd2 100644 --- a/.github/workflows/sync.yaml +++ b/.github/workflows/sync.yaml @@ -11,10 +11,10 @@ on: The branch of the examples repository to sync from. Default: main docs_branch: - default: main + default: prod-staging description: | The base branch in docs repository to create PR against. - Default: main + Default: prod-staging # Automatically cancel in-progress actions on the same branch concurrency: @@ -31,7 +31,7 @@ jobs: steps: - uses: actions/checkout@v4 with: - ref: ${{ inputs.docs_branch || 'main' }} + ref: ${{ inputs.docs_branch || 'prod-staging' }} - name: Sync example READMEs shell: bash @@ -61,7 +61,7 @@ jobs: uses: peter-evans/create-pull-request@v6 with: token: ${{ secrets.GH_PAT }} - base: ${{ inputs.docs_branch || 'main' }} + base: ${{ inputs.docs_branch || 'prod-staging' }} commit-message: "chore: Update guides from examples repository" title: "chore: Update guides from examples repository" body: | From 8b9796c11b08ec5aada921ce3095296a10c8b1c7 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Wed, 13 May 2026 14:46:35 +0300 Subject: [PATCH 126/131] fix(sync): Stage zudoku config file Signed-off-by: Alex-Andrei Cioc --- .github/workflows/sync.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sync.yaml b/.github/workflows/sync.yaml index a3cbfbd2..81e99651 100644 --- a/.github/workflows/sync.yaml +++ b/.github/workflows/sync.yaml @@ -65,7 +65,7 @@ jobs: commit-message: "chore: Update guides from examples repository" title: "chore: Update guides from examples repository" body: | - IMPORTANT: Please make sure to review the deployment of this PR and also update `zudoku.config.tsx` and `pages/guides/overview.mdx` if necessary. + IMPORTANT: Please make sure to review the deployment of this PR and also update `pages/guides/overview.mdx` if necessary. Automated sync of example READMEs from [`unikraft-cloud/examples@${{ inputs.examples_branch || 'main' }}`](https://github.com/unikraft-cloud/examples/tree/${{ inputs.examples_branch || 'main' }}). @@ -76,7 +76,9 @@ jobs: branch: ${{ steps.id.outputs.name }} committer: Unikraft Bot author: Unikraft Bot - add-paths: pages/guides + add-paths: | + pages/guides + zudoku.config.tsx signoff: true labels: | automated From c40544c1e529557108a70124a7ad205a9ef3c5b0 Mon Sep 17 00:00:00 2001 From: Unikraft Bot Date: Wed, 13 May 2026 11:52:22 +0000 Subject: [PATCH 127/131] chore: Update guides from examples repository Signed-off-by: Unikraft Bot --- pages/guides/caddy2.7-go1.21.mdx | 9 +- pages/guides/debian-ssh.mdx | 9 +- pages/guides/dragonflydb.mdx | 9 +- pages/guides/duckdb-go1.21.mdx | 9 +- pages/guides/github-webhook-node.mdx | 10 +- pages/guides/grafana.mdx | 9 +- pages/guides/haproxy.mdx | 9 +- pages/guides/httpserver-boost1.74-gpp13.2.mdx | 11 +- pages/guides/httpserver-bun.mdx | 11 +- pages/guides/httpserver-c-debug.mdx | 9 +- pages/guides/httpserver-dotnet10.0.mdx | 11 +- pages/guides/httpserver-elixir1.16.mdx | 9 +- pages/guides/httpserver-erlang26.2.mdx | 9 +- .../httpserver-expressjs4.18-node21.mdx | 11 +- pages/guides/httpserver-flask-redis.mdx | 244 ++++++++++++++++++ pages/guides/httpserver-gcc13.2.mdx | 9 +- pages/guides/httpserver-go1.21.mdx | 9 +- pages/guides/httpserver-gpp13.2.mdx | 11 +- .../httpserver-java17-spring-petclinic.mdx | 9 +- .../httpserver-java17-springboot3.5.x.mdx | 11 +- pages/guides/httpserver-java21.mdx | 11 +- pages/guides/httpserver-lua5.1.mdx | 9 +- .../guides/httpserver-nginx-vite-vanilla.mdx | 11 +- .../httpserver-node-express-puppeteer.mdx | 16 +- .../httpserver-node-vite-ssr-vanilla.mdx | 9 +- pages/guides/httpserver-node-vite-vanilla.mdx | 9 +- pages/guides/httpserver-node21-nextjs.mdx | 11 +- .../guides/httpserver-node21-solid-start.mdx | 9 +- ...mdx => httpserver-node22-react-router.mdx} | 41 +-- ...it.mdx => httpserver-node22-sveltekit.mdx} | 39 +-- pages/guides/httpserver-node25.mdx | 11 +- pages/guides/httpserver-perl5.42.mdx | 9 +- pages/guides/httpserver-php8.2.mdx | 9 +- ...httpserver-prisma-expressjs4.19-node18.mdx | 9 +- .../httpserver-python3.12-django5.0.mdx | 18 +- .../httpserver-python3.12-fastapi-0.121.3.mdx | 11 +- .../httpserver-python3.12-flask3.0-sqlite.mdx | 11 +- .../guides/httpserver-python3.12-flask3.0.mdx | 11 +- pages/guides/httpserver-python3.12.mdx | 11 +- pages/guides/httpserver-ruby3.2.mdx | 9 +- .../guides/httpserver-rust-trunkrs-leptos.mdx | 9 +- pages/guides/httpserver-rust1.75-tokio.mdx | 9 +- ...mdx => httpserver-rust1.88-actix-web4.mdx} | 37 +-- ....mdx => httpserver-rust1.88-rocket0.5.mdx} | 37 +-- pages/guides/httpserver-rust1.91.mdx | 9 +- pages/guides/hugo0.122.mdx | 9 +- pages/guides/imaginary.mdx | 9 +- pages/guides/mariadb.mdx | 32 ++- pages/guides/mcp-server-arxiv.mdx | 9 +- pages/guides/mcp-server-simple.mdx | 9 +- pages/guides/memcached1.6.mdx | 30 ++- pages/guides/minio.mdx | 9 +- pages/guides/mongodb.mdx | 9 +- pages/guides/nginx.mdx | 9 +- pages/guides/node-playwright-chromium.mdx | 9 +- pages/guides/node-playwright-firefox.mdx | 9 +- pages/guides/node-playwright-webkit.mdx | 9 +- pages/guides/node18-agario.mdx | 9 +- pages/guides/node18-wingsio.mdx | 9 +- pages/guides/node21-websocket.mdx | 9 +- pages/guides/node24-karaoke.mdx | 11 +- pages/guides/novnc-browser.mdx | 9 +- pages/guides/opentelemetry-collector.mdx | 9 +- pages/guides/postgres.mdx | 42 +-- pages/guides/python-playwright-chromium.mdx | 9 +- pages/guides/redis7.2.mdx | 20 +- pages/guides/ruby3.2-rails.mdx | 11 +- pages/guides/skipper0.18.mdx | 9 +- pages/guides/spin-wagi-http.mdx | 11 +- pages/guides/traefik.mdx | 16 +- pages/guides/visual-studio-code-server.mdx | 9 +- pages/guides/vsftpd.mdx | 9 +- pages/guides/wazero-import-go.mdx | 9 +- pages/guides/wordpress-all-in-one.mdx | 10 +- zudoku.config.tsx | 9 +- 75 files changed, 972 insertions(+), 203 deletions(-) create mode 100644 pages/guides/httpserver-flask-redis.mdx rename pages/guides/{httpserver-node21-remix.mdx => httpserver-node22-react-router.mdx} (75%) rename pages/guides/{httpserver-node21-sveltekit.mdx => httpserver-node22-sveltekit.mdx} (88%) rename pages/guides/{httpserver-rust1.87-actix-web4.mdx => httpserver-rust1.88-actix-web4.mdx} (84%) rename pages/guides/{httpserver-rust1.81-rocket0.5.mdx => httpserver-rust1.88-rocket0.5.mdx} (84%) diff --git a/pages/guides/caddy2.7-go1.21.mdx b/pages/guides/caddy2.7-go1.21.mdx index 23b502de..d7b581e3 100644 --- a/pages/guides/caddy2.7-go1.21.mdx +++ b/pages/guides/caddy2.7-go1.21.mdx @@ -2,10 +2,12 @@ title: "Caddy" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example uses [`Caddy`](https://caddyserver.com/), one of the most popular web servers. Caddy can be used with Unikraft / Unikraft Cloud to serve static web content. @@ -16,6 +18,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/caddy2.7-go1.21/` directory: ```bash diff --git a/pages/guides/debian-ssh.mdx b/pages/guides/debian-ssh.mdx index 9480a46d..85ac063b 100644 --- a/pages/guides/debian-ssh.mdx +++ b/pages/guides/debian-ssh.mdx @@ -2,10 +2,12 @@ title: "Debian SSH server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a Debian app with SSH enabled. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/debian-ssh` directory: ```bash diff --git a/pages/guides/dragonflydb.mdx b/pages/guides/dragonflydb.mdx index 173a8044..477c0dad 100644 --- a/pages/guides/dragonflydb.mdx +++ b/pages/guides/dragonflydb.mdx @@ -2,10 +2,12 @@ title: "DragonflyDB" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to deploy [Dragonfly](https://www.dragonflydb.io/), a simple, performant, and cost-efficient in-memory data store. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/dragonflydb/` directory: ```bash diff --git a/pages/guides/duckdb-go1.21.mdx b/pages/guides/duckdb-go1.21.mdx index 79310058..3f63f2fc 100644 --- a/pages/guides/duckdb-go1.21.mdx +++ b/pages/guides/duckdb-go1.21.mdx @@ -2,10 +2,12 @@ title: "DuckDB with Go" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [DuckDB](https://duckdb.org), an in-process SQL OLAP database management system, in your Go project. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/duckdb-go1.21/` directory: ```bash diff --git a/pages/guides/github-webhook-node.mdx b/pages/guides/github-webhook-node.mdx index f388d074..96fb44b0 100644 --- a/pages/guides/github-webhook-node.mdx +++ b/pages/guides/github-webhook-node.mdx @@ -2,10 +2,12 @@ title: "GitHub Webhook receiver" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example shows how to build a simple GitHub Webhook receiver using Node.js with [Express](https://expressjs.com/) and run it on Unikraft Cloud. A webhook, also called a reverse API, is a way for a server to send real-time data to other applications when a specific event occurs. In this case, the webhook receiver listens for GitHub events, such as push events or pull request events, and logs them to the console. @@ -17,6 +19,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/github-webhook-node/` directory: ```bash @@ -59,6 +66,7 @@ kraft cloud deploy --scale-to-zero on --scale-to-zero-stateful --scale-to-zero-c `GITHUB_WEBHOOK_SECRET` is the secret used to verify incoming webhook requests from GitHub. Set it to a string with high entropy. + The output shows the instance address and other details: diff --git a/pages/guides/grafana.mdx b/pages/guides/grafana.mdx index 0561a116..214cd24f 100644 --- a/pages/guides/grafana.mdx +++ b/pages/guides/grafana.mdx @@ -2,10 +2,12 @@ title: "Grafana" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [Grafana](https://grafana.com), the open source analytics & monitoring solution for every database. To run it, follow these steps: @@ -15,6 +17,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/grafana/` directory: ```bash diff --git a/pages/guides/haproxy.mdx b/pages/guides/haproxy.mdx index fdbab85e..a3e29882 100644 --- a/pages/guides/haproxy.mdx +++ b/pages/guides/haproxy.mdx @@ -2,10 +2,12 @@ title: "HAProxy" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [HAProxy](https://www.haproxy.org). HAProxy is a free and open source software that provides a high availability load balancer and reverse proxy for TCP and HTTP-based apps that spreads requests across many servers. @@ -16,6 +18,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/haproxy/` directory: ```bash diff --git a/pages/guides/httpserver-boost1.74-gpp13.2.mdx b/pages/guides/httpserver-boost1.74-gpp13.2.mdx index 704f23a6..94d0e99f 100644 --- a/pages/guides/httpserver-boost1.74-gpp13.2.mdx +++ b/pages/guides/httpserver-boost1.74-gpp13.2.mdx @@ -2,10 +2,12 @@ title: "C++ Boost HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a C++-based HTTP web server using the [Boost](https://www.boost.org/) libraries. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [example repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-boost1.74-gpp13.2/` directory: ```bash @@ -168,7 +175,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/http_server"]`: Use `/http_server` as the starting command of the instance. diff --git a/pages/guides/httpserver-bun.mdx b/pages/guides/httpserver-bun.mdx index 1df3d5bc..df612cdb 100644 --- a/pages/guides/httpserver-bun.mdx +++ b/pages/guides/httpserver-bun.mdx @@ -2,10 +2,12 @@ title: "Bun HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a Bun app. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-bun` directory: ```bash @@ -168,7 +175,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/bun", "run", "/usr/src/server.ts"]`: Use `/usr/bin/bun run /usr/src/server.ts` as the starting command of the instance. diff --git a/pages/guides/httpserver-c-debug.mdx b/pages/guides/httpserver-c-debug.mdx index 96eea05b..5ad70af1 100644 --- a/pages/guides/httpserver-c-debug.mdx +++ b/pages/guides/httpserver-c-debug.mdx @@ -2,10 +2,12 @@ title: "SSH and HTTP Server with C and Debugging Tools" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a C app with debugging enabled. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-c-debug` directory: ```bash diff --git a/pages/guides/httpserver-dotnet10.0.mdx b/pages/guides/httpserver-dotnet10.0.mdx index 1d43e8d8..05ec8e53 100644 --- a/pages/guides/httpserver-dotnet10.0.mdx +++ b/pages/guides/httpserver-dotnet10.0.mdx @@ -2,10 +2,12 @@ title: ".NET HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a simple .NET-based HTTP web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-dotnet10.0/` directory: ```bash @@ -168,7 +175,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd:`: Use as the starting command of the instance. diff --git a/pages/guides/httpserver-elixir1.16.mdx b/pages/guides/httpserver-elixir1.16.mdx index 59cec4c4..28e33b02 100644 --- a/pages/guides/httpserver-elixir1.16.mdx +++ b/pages/guides/httpserver-elixir1.16.mdx @@ -2,10 +2,12 @@ title: "Elixir HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a simple Elixir-based HTTP web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-elixir1.16/` directory: ```bash diff --git a/pages/guides/httpserver-erlang26.2.mdx b/pages/guides/httpserver-erlang26.2.mdx index 4f7cc5b8..97e4c629 100644 --- a/pages/guides/httpserver-erlang26.2.mdx +++ b/pages/guides/httpserver-erlang26.2.mdx @@ -2,10 +2,12 @@ title: "Erlang HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a simple Erlang-based HTTP web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-erlang26.2/` directory: ```bash diff --git a/pages/guides/httpserver-expressjs4.18-node21.mdx b/pages/guides/httpserver-expressjs4.18-node21.mdx index ee9c93e0..dba30296 100644 --- a/pages/guides/httpserver-expressjs4.18-node21.mdx +++ b/pages/guides/httpserver-expressjs4.18-node21.mdx @@ -2,10 +2,12 @@ title: "Express HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [Express](https://expressjs.com/) is a fast, unopinionated, minimalist web framework for Node.js. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-expressjs4.18-node21` directory: ```bash @@ -169,7 +176,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/node", "/usr/src/server.js"]`: Use `/usr/bin/node /usr/src/server.js` as the starting command of the instance. diff --git a/pages/guides/httpserver-flask-redis.mdx b/pages/guides/httpserver-flask-redis.mdx new file mode 100644 index 00000000..d368ead9 --- /dev/null +++ b/pages/guides/httpserver-flask-redis.mdx @@ -0,0 +1,244 @@ +--- +title: "Flask + Redis HTTP Server" +--- + +import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" + +{/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + +This guide explains how to create and deploy a [Flask](https://flask.palletsprojects.com/en/3.0.x/) app with a [Redis](https://redis.io/) database on Unikraft Cloud. +The example consists of two services: a Flask web server that increments a page view counter stored in Redis. + +To run this example, follow these steps: + +1. Install the CLI. + Use the [unikraft CLI](/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-flask-redis` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/httpserver-flask-redis/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +### Deploy Redis + +First, deploy the Redis instance. +Redis is an internal service (not publicly accessible), reached via the `redis.internal` domain: + + + +```bash title="unikraft" +unikraft build redis/ --output /redis:latest +unikraft run --scale-to-zero policy=idle,cooldown-time=1000,stateful=true --metro fra -m 256M --image /redis:latest --domain redis.internal +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero idle --scale-to-zero-stateful --scale-to-zero-cooldown 1s -M 256Mi --domain redis.internal redis/ +``` + + + +The output shows the Redis instance details: + + + +```ansi title="unikraft" +metro: fra +name: redis-09p2q +uuid: 0355f93a-7b60-4ade-9359-b01671e812b3 +state: starting +image: /redis +resources: + memory: 256MiB + vcpus: 1 +service: + uuid: 19c050b2-b5c9-4e8e-9d25-a9053ff09270 + name: damp-brook-xmmmwzwo + domains: + - fqdn: redis.internal +networks: +- uuid: 97df34f7-63bc-4f02-a1b4-5ba07278de00 + private-ip: 10.0.0.41 + mac: 12:b0:0a:00:00:29 +timestamps: + created: just now +scale-to-zero: policy=idle,stateful=true,cooldown-time=1s +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: redis-o9abw + β”œ───────── uuid: 9dd4c7b5-7cc4-4b99-ac70-b10af54ef075 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: redis.internal + β”œ──────── image: oci://unikraft.io//redis@sha256:3e35bc6c8048269741a0c0b4b165a10112736c48dbf869c76bb263a237502462 + β”œ─────── memory: 256 MiB + β”œ────── service: sparkling-fire-rnd4o9kb + β”œ─ private fqdn: redis-o9abw.internal + β””─── private ip: 10.0.0.41 +``` + + + +### Deploy Flask + +Next, deploy the Flask web server. +It connects to Redis using the `REDIS_HOST` and `REDIS_PORT` environment variables: + + + +```bash title="unikraft" +unikraft build flask/ --output /flask:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8000/tls+http -m 512M --image /flask:latest --env REDIS_HOST=redis.internal --env REDIS_PORT=6379 +``` + +```bash title="kraft" +kraft cloud deploy --scale-to-zero on --scale-to-zero-cooldown 1s -p 443:8000/tls+http -M 512Mi flask/ --env REDIS_HOST=redis.internal --env REDIS_PORT=6379 +``` + + + +The output shows the Flask instance details: + + + +```ansi title="unikraft" +metro: fra +name: flask-q62qa +uuid: d081ec92-629b-45b3-8caf-059e0a87dffd +state: starting +image: /flask +runtime: + env: + REDIS_HOST: redis.internal + REDIS_PORT: 6379 +resources: + memory: 512MiB + vcpus: 1 +service: + uuid: ac1cd90e-a1fe-478c-8f58-8598fa80c494 + name: hidden-silence-htyml3s2 + domains: + - fqdn: hidden-silence-htyml3s2.fra.unikraft.app +networks: +- uuid: d2f3d024-3082-4e98-be22-f36df84263a1 + private-ip: 10.0.0.53 + mac: 12:b0:0a:00:00:35 +timestamps: + created: just now +scale-to-zero: policy=on,cooldown-time=1s +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: flask-a06h2 + β”œ───────── uuid: 431f67ed-1f18-4dc1-86db-68dac4edff51 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ─────── domain: https://withered-cherry-xfcrfp93.fra.unikraft.app + β”œ──────── image: oci://unikraft.io//flask@sha256:3d29ca3a8a3d434f41acf7c8093435836dcbacca9190c51ec39dbb4ddf1ee45a + β”œ─────── memory: 512 MiB + β”œ────── service: withered-cherry-xfcrfp93 + β”œ─ private fqdn: flask-a06h2.internal + β””─── private ip: 10.0.0.53 +``` + + + +In this case, the Flask instance address is `https://withered-cherry-xfcrfp93.fra.unikraft.app`. +It's different for each run. + +### Test the deployment + +Use `curl` to query the Flask instance. +Each request increments the Redis counter: + +```bash +curl https://withered-cherry-xfcrfp93.fra.unikraft.app +``` + +```text +This webpage has been viewed 1 time(s) +``` + +```bash +curl https://withered-cherry-xfcrfp93.fra.unikraft.app +``` + +```text +This webpage has been viewed 2 time(s) +``` + +You can list information about the instances by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + +### Clean up + +When done, remove the instances: + + + +```bash title="unikraft" +unikraft instances delete flask-q62qa +unikraft instances delete redis-09p2q +``` + +```bash title="kraft" +kraft cloud instance remove flask-a06h2 +kraft cloud instance remove redis-o9abw +``` + + + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + +```bash +kraft cloud --help +``` + +Or visit the [CLI Reference](/cli/overview). +{/* vale on */} diff --git a/pages/guides/httpserver-gcc13.2.mdx b/pages/guides/httpserver-gcc13.2.mdx index f327773f..84165d9b 100644 --- a/pages/guides/httpserver-gcc13.2.mdx +++ b/pages/guides/httpserver-gcc13.2.mdx @@ -2,10 +2,12 @@ title: "C HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a C app. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-gcc13.2` directory: ```bash diff --git a/pages/guides/httpserver-go1.21.mdx b/pages/guides/httpserver-go1.21.mdx index 6d5218db..ce313102 100644 --- a/pages/guides/httpserver-go1.21.mdx +++ b/pages/guides/httpserver-go1.21.mdx @@ -2,10 +2,12 @@ title: "Go HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a simple Go-based HTTP web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-go1.21/` directory: ```bash diff --git a/pages/guides/httpserver-gpp13.2.mdx b/pages/guides/httpserver-gpp13.2.mdx index faad64ca..7ba2ad82 100644 --- a/pages/guides/httpserver-gpp13.2.mdx +++ b/pages/guides/httpserver-gpp13.2.mdx @@ -2,10 +2,12 @@ title: "C++ HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a simple C++-based HTTP web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [example repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-gpp13.2/` directory: ```bash @@ -168,7 +175,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/http_server"]`: Use `/http_server` as the starting command of the instance. diff --git a/pages/guides/httpserver-java17-spring-petclinic.mdx b/pages/guides/httpserver-java17-spring-petclinic.mdx index ab120fc7..66e6ebf2 100644 --- a/pages/guides/httpserver-java17-spring-petclinic.mdx +++ b/pages/guides/httpserver-java17-spring-petclinic.mdx @@ -2,10 +2,12 @@ title: "Spring PetClinic" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [Spring PetClinic](https://github.com/spring-projects/spring-petclinic) is an example project that uses Spring boot to model a simple pet clinic. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-java17-spring-petclinic/` directory: ```bash diff --git a/pages/guides/httpserver-java17-springboot3.5.x.mdx b/pages/guides/httpserver-java17-springboot3.5.x.mdx index 54f384ff..3e46117b 100644 --- a/pages/guides/httpserver-java17-springboot3.5.x.mdx +++ b/pages/guides/httpserver-java17-springboot3.5.x.mdx @@ -2,10 +2,12 @@ title: "Spring Boot HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a Spring Boot web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-java17-springboot3.5.x/` directory: ```bash @@ -140,7 +147,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/lib/jvm/java-17-openjdk-amd64/bin/java", "-jar", "/usr/src/demo-0.0.1-SNAPSHOT.jar"]`: Use as the starting command of the instance. diff --git a/pages/guides/httpserver-java21.mdx b/pages/guides/httpserver-java21.mdx index 63cc4738..1c6acd65 100644 --- a/pages/guides/httpserver-java21.mdx +++ b/pages/guides/httpserver-java21.mdx @@ -2,10 +2,12 @@ title: "Java HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This is a simple HTTP server written in the [Java](https://www.java.com/en/) programming language. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-java21` directory: ```bash @@ -169,7 +176,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/lib/jvm/java-21-openjdk-amd64/bin/java", "-classpath", "/usr/src/", "SimpleHttpServer"]`: Use the Java runtime to run `SimpleHttpServer` as the starting command of the instance. diff --git a/pages/guides/httpserver-lua5.1.mdx b/pages/guides/httpserver-lua5.1.mdx index 97938d8e..410c8a36 100644 --- a/pages/guides/httpserver-lua5.1.mdx +++ b/pages/guides/httpserver-lua5.1.mdx @@ -2,10 +2,12 @@ title: "Lua HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a simple Lua-based HTTP web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-lua5.1/` directory: ```bash diff --git a/pages/guides/httpserver-nginx-vite-vanilla.mdx b/pages/guides/httpserver-nginx-vite-vanilla.mdx index 2cf4df03..42defaa8 100644 --- a/pages/guides/httpserver-nginx-vite-vanilla.mdx +++ b/pages/guides/httpserver-nginx-vite-vanilla.mdx @@ -2,10 +2,12 @@ title: "Vite HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example demonstrates how to run a [Vite](https://vite.dev) project targeting production on Unikraft Cloud. The deployment doesn't perform any server-side rendering and instead serves the resulting artifacts statically (via `npm run build`) using [`nginx`](https://github.com/unikraft-cloud/examples/nginx). To use Vite in server-side rendering (SSR) mode or via the `dev` subcommand on a NodeJS runtime, please see the [`httpserver-node-vite-vanilla`](https://github.com/unikraft-cloud/examples/httpserver-node-vite-vanilla) sibling project. @@ -17,6 +19,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-nginx-vite-vanilla` directory: ```bash @@ -181,7 +188,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/nginx", "-c", "/etc/nginx/nginx.conf"]`: Use nginx to serve the built static files as the starting command of the instance. diff --git a/pages/guides/httpserver-node-express-puppeteer.mdx b/pages/guides/httpserver-node-express-puppeteer.mdx index c0854864..8a42ea0e 100644 --- a/pages/guides/httpserver-node-express-puppeteer.mdx +++ b/pages/guides/httpserver-node-express-puppeteer.mdx @@ -2,10 +2,12 @@ title: "Puppeteer HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [Puppeteer](https://pptr.dev/), a Node.js library which provides a high-level API to control browsers, including the option to run them headless (no UI). To run it, follow these steps: @@ -15,6 +17,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node-express-puppeteer/` directory: ```bash @@ -43,9 +50,10 @@ export UKC_METRO=fra The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. -> **Note:** -> A Puppeteer instance on Unikraft Cloud requires 4GB to run. -> Request an increase in the instance memory quota when you need more memory. +:::note +A Puppeteer instance on Unikraft Cloud requires 4GB to run. +Request an increase in the instance memory quota when you need more memory. +::: When done, invoke the following command to deploy this app on Unikraft Cloud: diff --git a/pages/guides/httpserver-node-vite-ssr-vanilla.mdx b/pages/guides/httpserver-node-vite-ssr-vanilla.mdx index 2004b357..448fb6d1 100644 --- a/pages/guides/httpserver-node-vite-ssr-vanilla.mdx +++ b/pages/guides/httpserver-node-vite-ssr-vanilla.mdx @@ -2,10 +2,12 @@ title: "Vite (vanilla) SSR" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example demonstrates how to run [Vite](https://vite.dev) with [server-side rendering (SSR)](https://vite.dev/guide/ssr.html). @@ -31,6 +33,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node-vite-ssr-vanilla/` directory: ```bash diff --git a/pages/guides/httpserver-node-vite-vanilla.mdx b/pages/guides/httpserver-node-vite-vanilla.mdx index befdd254..6f616116 100644 --- a/pages/guides/httpserver-node-vite-vanilla.mdx +++ b/pages/guides/httpserver-node-vite-vanilla.mdx @@ -2,10 +2,12 @@ title: "Vite (vanilla)" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example demonstrates how to run a [Vite](https://vite.dev) project which executes via the `vite` program on top of the `node` runtime. @@ -35,6 +37,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node-vite-vanilla/` directory: ```bash diff --git a/pages/guides/httpserver-node21-nextjs.mdx b/pages/guides/httpserver-node21-nextjs.mdx index b613040b..603e1583 100644 --- a/pages/guides/httpserver-node21-nextjs.mdx +++ b/pages/guides/httpserver-node21-nextjs.mdx @@ -2,10 +2,12 @@ title: "Next.js HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a Next.js app. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node21-nextjs` directory: ```bash @@ -169,7 +176,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: [["/usr/bin/node", "/usr/src/server.js"]]`: Use `/usr/bin/node /usr/src/server.js` as the starting command of the instance. diff --git a/pages/guides/httpserver-node21-solid-start.mdx b/pages/guides/httpserver-node21-solid-start.mdx index b74b0f7f..6874ccf4 100644 --- a/pages/guides/httpserver-node21-solid-start.mdx +++ b/pages/guides/httpserver-node21-solid-start.mdx @@ -2,10 +2,12 @@ title: "SolidJS HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows how to deploy a [Solid Start](https://start.solidjs.com) app. To do so, follow these steps: @@ -14,6 +16,11 @@ To do so, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node21-solid-start/` directory: ```bash diff --git a/pages/guides/httpserver-node21-remix.mdx b/pages/guides/httpserver-node22-react-router.mdx similarity index 75% rename from pages/guides/httpserver-node21-remix.mdx rename to pages/guides/httpserver-node22-react-router.mdx index 923d4426..ac8a13d0 100644 --- a/pages/guides/httpserver-node21-remix.mdx +++ b/pages/guides/httpserver-node22-react-router.mdx @@ -1,12 +1,14 @@ --- -title: "Remix HTTP Server" +title: "React Router HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} -This guide shows how to deploy a [Remix](https://remix.run/) app. +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + +This guide shows how to deploy a [React Router](https://reactrouter.com/) app (formerly Remix). To do so, follow these steps: @@ -15,11 +17,16 @@ To do so, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). -2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node21-remix/` directory: +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node22-react-router/` directory: ```bash git clone https://github.com/unikraft-cloud/examples -cd examples/httpserver-node21-remix/ +cd examples/httpserver-node22-react-router/ ``` Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. @@ -45,8 +52,8 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-node21-remix:latest -unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:3000/tls+http -m 768M --image /httpserver-node21-remix:latest +unikraft build . --output /httpserver-node22-react-router:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:3000/tls+http -m 768M --image /httpserver-node22-react-router:latest ``` ```bash title="kraft" @@ -61,10 +68,10 @@ The output shows the instance address and other details: ```ansi title="unikraft" metro: fra -name: httpserver-node21-remix-jvj6b +name: httpserver-node22-react-router-jvj6b uuid: 4e6ccb1f-0533-4dc1-be67-eca8dfc1f8c6 state: starting -image: /httpserver-node21-remix +image: /httpserver-node22-react-router resources: memory: 768MiB vcpus: 1 @@ -84,21 +91,21 @@ timestamps: ```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ───────── name: httpserver-node21-remix-jvj6b + β”œ───────── name: httpserver-node22-react-router-jvj6b β”œ───────── uuid: 4e6ccb1f-0533-4dc1-be67-eca8dfc1f8c6 β”œ──────── metro: https://api.fra.unikraft.cloud/v1 β”œ──────── state: starting β”œ─────── domain: https://long-star-1tms9h1z.fra.unikraft.app - β”œ──────── image: oci://unikraft.io//httpserver-node21-remix@sha256:300eefce3de136ad9c782f010b69da01100ae5f0ca17f038f92321d735d6675f + β”œ──────── image: oci://unikraft.io//httpserver-node22-react-router@sha256:300eefce3de136ad9c782f010b69da01100ae5f0ca17f038f92321d735d6675f β”œ─────── memory: 768 MiB β”œ────── service: long-star-1tms9h1z - β”œ─ private fqdn: httpserver-node21-remix-jvj6b.internal + β”œ─ private fqdn: httpserver-node22-react-router-jvj6b.internal β””─── private ip: 10.0.6.8 ``` -In this case, the instance name is `httpserver-node21-remix-jvj6b` and the address is `https://long-star-1tms9h1z.fra.unikraft.app`. +In this case, the instance name is `httpserver-node22-react-router-jvj6b` and the address is `https://long-star-1tms9h1z.fra.unikraft.app`. They're different for each run. You can now point your browser at the address to see your deployed instance. @@ -120,12 +127,12 @@ kraft cloud instance list ```ansi title="unikraft" METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED -fra httpserver-node21-remix-jvj6b running /httpserver-node21-remix 768MiB 1 long-star-1tms9h1z.fra.unikraft.app 2 minutes ago +fra httpserver-node22-react-router-jvj6b running /httpserver-node22-react-router 768MiB 1 long-star-1tms9h1z.fra.unikraft.app 2 minutes ago ``` ```ansi title="kraft" NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-node21-remix-jvj6b long-star-1tms9h1z.fra.unikraft.app running 1 minutes ago oci://unikraft.io//httpserver-node21-remix@sha256... 768 MiB 1 67.65 ms +httpserver-node22-react-router-jvj6b long-star-1tms9h1z.fra.unikraft.app running 1 minutes ago oci://unikraft.io//httpserver-node22-react-router@sha256... 768 MiB 1 67.65 ms ``` @@ -135,11 +142,11 @@ When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-node21-remix-jvj6b +unikraft instances delete httpserver-node22-react-router-jvj6b ``` ```bash title="kraft" -kraft cloud instance remove httpserver-node21-remix-jvj6b +kraft cloud instance remove httpserver-node22-react-router-jvj6b ``` diff --git a/pages/guides/httpserver-node21-sveltekit.mdx b/pages/guides/httpserver-node22-sveltekit.mdx similarity index 88% rename from pages/guides/httpserver-node21-sveltekit.mdx rename to pages/guides/httpserver-node22-sveltekit.mdx index e4d59843..55115c49 100644 --- a/pages/guides/httpserver-node21-sveltekit.mdx +++ b/pages/guides/httpserver-node22-sveltekit.mdx @@ -2,10 +2,12 @@ title: "SvelteKit HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a [SvelteKit](https://kit.svelte.dev/) app. [SvelteKit](https://kit.svelte.dev/) builds on Svelte, a UI framework that uses a compiler to let you write breathtakingly concise components that do minimal work in the browser. @@ -16,11 +18,16 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). -2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node21-sveltekit/` directory: +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node22-sveltekit/` directory: ```bash git clone https://github.com/unikraft-cloud/examples -cd examples/httpserver-node21-sveltekit/ +cd examples/httpserver-node22-sveltekit/ ``` Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. @@ -46,8 +53,8 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-node21-sveltekit:latest -unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:3000/tls+http -m 512M --image /httpserver-node21-sveltekit:latest +unikraft build . --output /httpserver-node22-sveltekit:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:3000/tls+http -m 512M --image /httpserver-node22-sveltekit:latest ``` ```bash title="kraft" @@ -62,10 +69,10 @@ The output shows the instance address and other details: ```ansi title="unikraft" metro: fra -name: httpserver-node21-sveltekit-zmt39 +name: httpserver-node22-sveltekit-zmt39 uuid: cd5071b0-5605-4771-b75d-4789393e60de state: starting -image: /httpserver-node21-sveltekit +image: /httpserver-node22-sveltekit resources: memory: 512MiB vcpus: 1 @@ -85,21 +92,21 @@ timestamps: ```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ───────── name: httpserver-node21-sveltekit-zmt39 + β”œ───────── name: httpserver-node22-sveltekit-zmt39 β”œ───────── uuid: cd5071b0-5605-4771-b75d-4789393e60de β”œ──────── metro: https://api.fra.unikraft.cloud/v1 β”œ──────── state: starting β”œ─────── domain: https://dark-fog-z18n0ej1.fra.unikraft.app - β”œ──────── image: oci://unikraft.io//httpserver-node21-sveltekit@sha256:4cea210aef3513bd68490640b511ebcff2b867e9222028b9938faccffc21cb83 + β”œ──────── image: oci://unikraft.io//httpserver-node22-sveltekit@sha256:4cea210aef3513bd68490640b511ebcff2b867e9222028b9938faccffc21cb83 β”œ─────── memory: 512 MiB β”œ────── service: dark-fog-z18n0ej1 - β”œ─ private fqdn: httpserver-node21-sveltekit-zmt39.internal + β”œ─ private fqdn: httpserver-node22-sveltekit-zmt39.internal β””─── private ip: 10.0.3.3 ``` -In this case, the instance name is `httpserver-node21-sveltekit-zmt39` and the address is `https://dark-fog-z18n0ej1.fra.unikraft.app`. +In this case, the instance name is `httpserver-node22-sveltekit-zmt39` and the address is `https://dark-fog-z18n0ej1.fra.unikraft.app`. They're different for each run. Use `curl` to query the Unikraft Cloud instance: @@ -137,12 +144,12 @@ kraft cloud instance list ```ansi title="unikraft" METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED -fra httpserver-node21-sveltekit-zmt39 running /httpserver-node21-sveltekit 512MiB 1 dark-fog-z18n0ej1.fra.unikraft.app 2 minutes ago +fra httpserver-node22-sveltekit-zmt39 running /httpserver-node22-sveltekit 512MiB 1 dark-fog-z18n0ej1.fra.unikraft.app 2 minutes ago ``` ```ansi title="kraft" NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-node21-sveltekit-zmt39 dark-fog-z18n0ej1.fra.unikraft.app running 5 minutes ago oci://unikraft.io//httpserver-node21-sveltekit@sha256:... 512 MiB 1 72.86 ms +httpserver-node22-sveltekit-zmt39 dark-fog-z18n0ej1.fra.unikraft.app running 5 minutes ago oci://unikraft.io//httpserver-node22-sveltekit@sha256:... 512 MiB 1 72.86 ms ``` @@ -152,11 +159,11 @@ When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-node21-sveltekit-zmt39 +unikraft instances delete httpserver-node22-sveltekit-zmt39 ``` ```bash title="kraft" -kraft cloud instance remove httpserver-node21-sveltekit-zmt39 +kraft cloud instance remove httpserver-node22-sveltekit-zmt39 ``` @@ -213,7 +220,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: [["/usr/bin/node", "/app/build/index.js"]]`: Use `/usr/bin/node /app/build/index.js` as the starting command of the instance. diff --git a/pages/guides/httpserver-node25.mdx b/pages/guides/httpserver-node25.mdx index 472c5c02..8b2199f9 100644 --- a/pages/guides/httpserver-node25.mdx +++ b/pages/guides/httpserver-node25.mdx @@ -2,10 +2,12 @@ title: "Node HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [Node.js](https://nodejs.org) is a free, open source, cross-platform JavaScript runtime environment. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-node25` directory: ```bash @@ -169,7 +176,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/node", "/usr/src/server.js"]`: Use `/usr/bin/node /usr/src/server.js` as the starting command of the instance. diff --git a/pages/guides/httpserver-perl5.42.mdx b/pages/guides/httpserver-perl5.42.mdx index 21b99cc5..3b3dc92c 100644 --- a/pages/guides/httpserver-perl5.42.mdx +++ b/pages/guides/httpserver-perl5.42.mdx @@ -2,10 +2,12 @@ title: "Perl HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a simple Perl-based HTTP web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-perl5.42/` directory: ```bash diff --git a/pages/guides/httpserver-php8.2.mdx b/pages/guides/httpserver-php8.2.mdx index d980e7ca..1bf3637e 100644 --- a/pages/guides/httpserver-php8.2.mdx +++ b/pages/guides/httpserver-php8.2.mdx @@ -2,10 +2,12 @@ title: "PHP HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a simple PHP-based HTTP web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-php8.2/` directory: ```bash diff --git a/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx b/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx index 45116320..4aa13f7d 100644 --- a/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx +++ b/pages/guides/httpserver-prisma-expressjs4.19-node18.mdx @@ -2,10 +2,12 @@ title: "Prisma HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This app comes from [Prisma's REST API Example](https://github.com/prisma/prisma-examples/tree/latest/javascript/rest-express) and shows how to create a **REST API** using [Express](https://expressjs.com/) and [Prisma Client](https://www.prisma.io/docs/concepts/components/prisma-client) and deploy it onto Unikraft Cloud. It uses a SQLite database file with some initial [migration data](./prisma/migrations/20240208151224_init/). @@ -16,6 +18,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-prisma-expressjs4.19-node18/` directory: ```bash diff --git a/pages/guides/httpserver-python3.12-django5.0.mdx b/pages/guides/httpserver-python3.12-django5.0.mdx index 20a87000..82e34ead 100644 --- a/pages/guides/httpserver-python3.12-django5.0.mdx +++ b/pages/guides/httpserver-python3.12-django5.0.mdx @@ -2,10 +2,12 @@ title: "Django HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a Python Django web app. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-python3.12-django5.0/` directory: ```bash @@ -128,9 +135,10 @@ curl https://dawn-sound-n5wrkxi2.fra.unikraft.app Or point a browser at the address and/or its `/admin` area. You can set the username and password in the `Dockerfile` (more on this file later) to `unikraft/unikraft`. -> **Caution:** -> The example sets ALLOWED_HOSTS to * and runs in debug mode. -> For a production site, ensure you read the recommended deployment guides of the official Django project. +:::caution +The example sets ALLOWED_HOSTS to * and runs in debug mode. +For a production site, ensure you read the recommended deployment guides of the official Django project. +::: You can list information about the instance by running: @@ -190,7 +198,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/python3", "/app/main.py"]`: Use this as the starting command of the instance. diff --git a/pages/guides/httpserver-python3.12-fastapi-0.121.3.mdx b/pages/guides/httpserver-python3.12-fastapi-0.121.3.mdx index e9bb4262..d8747346 100644 --- a/pages/guides/httpserver-python3.12-fastapi-0.121.3.mdx +++ b/pages/guides/httpserver-python3.12-fastapi-0.121.3.mdx @@ -2,10 +2,12 @@ title: "FastAPI HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a Python FastAPI web app. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-python3.12-fastapi-0.121.3/` directory: ```bash @@ -167,7 +174,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/python3", "-m", "uvicorn", "src.server:app", "--host", "0.0.0.0", "--port", "8080"]`: Use this as the starting command of the instance. diff --git a/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx b/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx index 0474ac94..d464105e 100644 --- a/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx +++ b/pages/guides/httpserver-python3.12-flask3.0-sqlite.mdx @@ -2,10 +2,12 @@ title: "Flask and SQLite HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a Python Flask app using SQLite. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-python3.12-flask3.0-sqlite/` directory: ```bash @@ -188,7 +195,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/python3", "/app/server.py"]`: Use `/usr/bin/python3 /app/server.py` as the starting command of the instance. diff --git a/pages/guides/httpserver-python3.12-flask3.0.mdx b/pages/guides/httpserver-python3.12-flask3.0.mdx index f1afc127..e2c677e7 100644 --- a/pages/guides/httpserver-python3.12-flask3.0.mdx +++ b/pages/guides/httpserver-python3.12-flask3.0.mdx @@ -2,10 +2,12 @@ title: "Flask HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a [Flask](https://flask.palletsprojects.com/en/3.0.x/) web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-python3.12-flask3.0/` directory: ```bash @@ -168,7 +175,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/python3", "/src/server.py"]`: Use `/usr/bin/python3 /src/server.py` as the starting command of the instance. diff --git a/pages/guides/httpserver-python3.12.mdx b/pages/guides/httpserver-python3.12.mdx index 16789a64..a8b0d853 100644 --- a/pages/guides/httpserver-python3.12.mdx +++ b/pages/guides/httpserver-python3.12.mdx @@ -2,10 +2,12 @@ title: "Python HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a simple Python-based HTTP web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-python3.12/` directory: ```bash @@ -168,7 +175,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/python3", "/src/server.py"]`: Use `/usr/bin/python3 /src/server.py` as the starting command of the instance. diff --git a/pages/guides/httpserver-ruby3.2.mdx b/pages/guides/httpserver-ruby3.2.mdx index 368533ab..5c2e1068 100644 --- a/pages/guides/httpserver-ruby3.2.mdx +++ b/pages/guides/httpserver-ruby3.2.mdx @@ -2,10 +2,12 @@ title: "Ruby HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a simple Ruby-based HTTP web server. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-ruby3.2/` directory: ```bash diff --git a/pages/guides/httpserver-rust-trunkrs-leptos.mdx b/pages/guides/httpserver-rust-trunkrs-leptos.mdx index ecca6103..08860dcd 100644 --- a/pages/guides/httpserver-rust-trunkrs-leptos.mdx +++ b/pages/guides/httpserver-rust-trunkrs-leptos.mdx @@ -2,10 +2,12 @@ title: "Rust (Leptos + Trunk) HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows how to deploy a Rust HTTP server using Trunk and Leptos on Unikraft Cloud. To run it, follow these steps: @@ -14,6 +16,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust-trunkrs-leptos/` directory: ```bash diff --git a/pages/guides/httpserver-rust1.75-tokio.mdx b/pages/guides/httpserver-rust1.75-tokio.mdx index f19a3bb4..bfddcc6f 100644 --- a/pages/guides/httpserver-rust1.75-tokio.mdx +++ b/pages/guides/httpserver-rust1.75-tokio.mdx @@ -2,10 +2,12 @@ title: "Rust (Tokio) HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example uses [`Tokio`](https://tokio.rs/), a popular Rust asynchronous runtime. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust1.75-tokio/` directory: ```bash diff --git a/pages/guides/httpserver-rust1.87-actix-web4.mdx b/pages/guides/httpserver-rust1.88-actix-web4.mdx similarity index 84% rename from pages/guides/httpserver-rust1.87-actix-web4.mdx rename to pages/guides/httpserver-rust1.88-actix-web4.mdx index 8610afcf..62082bc7 100644 --- a/pages/guides/httpserver-rust1.87-actix-web4.mdx +++ b/pages/guides/httpserver-rust1.88-actix-web4.mdx @@ -2,10 +2,12 @@ title: "Rust (Actix Web) HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example uses [`actix-web`](https://actix.rs), a popular Rust web framework. To run it, follow these steps: @@ -14,11 +16,16 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). -1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust1.87-actix-web4/` directory: +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust1.88-actix-web4/` directory: ```bash git clone https://github.com/unikraft-cloud/examples -cd examples/httpserver-rust1.87-actix-web4/ +cd examples/httpserver-rust1.88-actix-web4/ ``` Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. @@ -44,8 +51,8 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-rust187-actix-web4:latest -unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-rust187-actix-web4:latest +unikraft build . --output /httpserver-rust188-actix-web4:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-rust188-actix-web4:latest ``` ```bash title="kraft" @@ -60,10 +67,10 @@ The output shows the instance address and other details: ```ansi title="unikraft" metro: fra -name: httpserver-rust187-actix-web4-3pj27 +name: httpserver-rust188-actix-web4-3pj27 uuid: 3e729de6-a1fb-5818-63d4-51a905fa6a5d state: starting -image: /httpserver-rust187-actix-web4 +image: /httpserver-rust188-actix-web4 resources: memory: 256MiB vcpus: 1 @@ -83,20 +90,20 @@ timestamps: ```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ───────── name: httpserver-rust187-actix-web4-3pj27 + β”œ───────── name: httpserver-rust188-actix-web4-3pj27 β”œ──────── metro: https://api.fra.unikraft.cloud/v1 β”œ──────── state: starting β”œ─────── domain: https://autumn-silence-wupu2nus.fra.unikraft.app - β”œ──────── image: oci://unikraft.io//httpserver-rust187-actix-web4@sha256:11723705230f0f4545d2be7e4867dc67b396870769e91f05e2fa6d9da94f9b59 + β”œ──────── image: oci://unikraft.io//httpserver-rust188-actix-web4@sha256:11723705230f0f4545d2be7e4867dc67b396870769e91f05e2fa6d9da94f9b59 β”œ─────── memory: 256 MiB β”œ────── service: autumn-silence-wupu2nus - β”œ─ private fqdn: httpserver-rust187-actix-web4-3pj27.internal + β”œ─ private fqdn: httpserver-rust188-actix-web4-3pj27.internal β””─── private ip: 10.0.3.3 ``` -In this case, the instance name is `httpserver-rust187-actix-web4-3pj27` and the address is `https://autumn-silence-wupu2nus.fra.unikraft.app`. +In this case, the instance name is `httpserver-rust188-actix-web4-3pj27` and the address is `https://autumn-silence-wupu2nus.fra.unikraft.app`. They're different for each run. Use `curl` to query the Unikraft Cloud instance of the Rust-based HTTP web server: @@ -129,12 +136,12 @@ kraft cloud instance list ```ansi title="unikraft" METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED -fra httpserver-rust187-actix-web4-3pj27 running /httpserver-rust187-actix-web4 256MiB 1 autumn-silence-wupu2nus.fra.unikraft.app 2 minutes ago +fra httpserver-rust188-actix-web4-3pj27 running /httpserver-rust188-actix-web4 256MiB 1 autumn-silence-wupu2nus.fra.unikraft.app 2 minutes ago ``` ```ansi title="kraft" NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-rust187-actix-web4-3pj27 autumn-silence-wupu2nus.fra.unikraft.app running 10 minutes ago oci://unikraft.io//httpserver-rust187-actix-web4@sha256:... 256 MiB 1 11.67 ms +httpserver-rust188-actix-web4-3pj27 autumn-silence-wupu2nus.fra.unikraft.app running 10 minutes ago oci://unikraft.io//httpserver-rust188-actix-web4@sha256:... 256 MiB 1 11.67 ms ``` @@ -144,11 +151,11 @@ When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-rust187-actix-web4-3pj27 +unikraft instances delete httpserver-rust188-actix-web4-3pj27 ``` ```bash title="kraft" -kraft cloud instance remove httpserver-rust187-actix-web4-3pj27 +kraft cloud instance remove httpserver-rust188-actix-web4-3pj27 ``` diff --git a/pages/guides/httpserver-rust1.81-rocket0.5.mdx b/pages/guides/httpserver-rust1.88-rocket0.5.mdx similarity index 84% rename from pages/guides/httpserver-rust1.81-rocket0.5.mdx rename to pages/guides/httpserver-rust1.88-rocket0.5.mdx index 5830b178..90f6b97d 100644 --- a/pages/guides/httpserver-rust1.81-rocket0.5.mdx +++ b/pages/guides/httpserver-rust1.88-rocket0.5.mdx @@ -2,10 +2,12 @@ title: "Rust (Rocket) HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example uses [`Rocket`](https://rocket.rs/), a popular Rust web framework. To run it, follow these steps: @@ -14,11 +16,16 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). -2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust1.81-rocket0.5/` directory: +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + +2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust1.88-rocket0.5/` directory: ```bash git clone https://github.com/unikraft-cloud/examples -cd examples/httpserver-rust1.81-rocket0.5 +cd examples/httpserver-rust1.88-rocket0.5 ``` Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. @@ -44,8 +51,8 @@ When done, invoke the following command to deploy this app on Unikraft Cloud: ```bash title="unikraft" -unikraft build . --output /httpserver-rust181-rocket05:latest -unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-rust181-rocket05:latest +unikraft build . --output /httpserver-rust188-rocket05:latest +unikraft run --scale-to-zero policy=on,cooldown-time=1000 --metro fra -p 443:8080/tls+http -m 256M --image /httpserver-rust188-rocket05:latest ``` ```bash title="kraft" @@ -60,10 +67,10 @@ The output shows the instance address and other details: ```ansi title="unikraft" metro: fra -name: httpserver-rust181-rocket05-tuwq3 +name: httpserver-rust188-rocket05-tuwq3 uuid: b6fe13e4-93b7-402b-bdec-1bc4d81bc275 state: starting -image: /httpserver-rust181-rocket05 +image: /httpserver-rust188-rocket05 resources: memory: 256MiB vcpus: 1 @@ -83,21 +90,21 @@ timestamps: ```ansi title="kraft" [●] Deployed successfully! β”‚ - β”œ───────── name: httpserver-rust181-rocket05-tuwq3 + β”œ───────── name: httpserver-rust188-rocket05-tuwq3 β”œ───────── uuid: b6fe13e4-93b7-402b-bdec-1bc4d81bc275 β”œ──────── metro: https://api.fra.unikraft.cloud/v1 β”œ──────── state: starting β”œ─────── domain: https://empty-bobo-n3htmpye.fra.unikraft.app - β”œ──────── image: oci://unikraft.io//httpserver-rust181-rocket05@sha256:23a7a6e155758e6e8f75e9570f0aec5fb744f08c1bad2454d7386367c5ea45d6 + β”œ──────── image: oci://unikraft.io//httpserver-rust188-rocket05@sha256:23a7a6e155758e6e8f75e9570f0aec5fb744f08c1bad2454d7386367c5ea45d6 β”œ─────── memory: 256 MiB β”œ────── service: empty-bobo-n3htmpye - β”œ─ private fqdn: httpserver-rust181-rocket05-tuwq3.internal + β”œ─ private fqdn: httpserver-rust188-rocket05-tuwq3.internal β””─── private ip: 10.0.6.6 ``` -In this case, the instance name is `httpserver-rust181-rocket05-tuwq3` and the address is `https://empty-bobo-n3htmpye.fra.unikraft.app`. +In this case, the instance name is `httpserver-rust188-rocket05-tuwq3` and the address is `https://empty-bobo-n3htmpye.fra.unikraft.app`. They're different for each run. Use `curl` to query any of the Rocket server's paths, for example: @@ -128,12 +135,12 @@ kraft cloud instance list ```ansi title="unikraft" METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED -fra httpserver-rust181-rocket05-tuwq3 running /httpserver-rust181-rocket05 256MiB 1 empty-bobo-n3htmpye.fra.unikraft.app 2 minutes ago +fra httpserver-rust188-rocket05-tuwq3 running /httpserver-rust188-rocket05 256MiB 1 empty-bobo-n3htmpye.fra.unikraft.app 2 minutes ago ``` ```ansi title="kraft" NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME -httpserver-rust181-rocket05-tuwq3 empty-bobo-n3htmpye.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-rust181-rocket05@sha256:... 256 MiB 1 17.41 ms +httpserver-rust188-rocket05-tuwq3 empty-bobo-n3htmpye.fra.unikraft.app running 1 minute ago oci://unikraft.io//httpserver-rust188-rocket05@sha256:... 256 MiB 1 17.41 ms ``` @@ -143,11 +150,11 @@ When done, you can remove the instance: ```bash title="unikraft" -unikraft instances delete httpserver-rust181-rocket05-tuwq3 +unikraft instances delete httpserver-rust188-rocket05-tuwq3 ``` ```bash title="kraft" -kraft cloud instance remove httpserver-rust181-rocket05-tuwq3 +kraft cloud instance remove httpserver-rust188-rocket05-tuwq3 ``` diff --git a/pages/guides/httpserver-rust1.91.mdx b/pages/guides/httpserver-rust1.91.mdx index d9ff3ed5..c810dd9b 100644 --- a/pages/guides/httpserver-rust1.91.mdx +++ b/pages/guides/httpserver-rust1.91.mdx @@ -2,10 +2,12 @@ title: "Rust HTTP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a Rust app. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/httpserver-rust1.91` directory: ```bash diff --git a/pages/guides/hugo0.122.mdx b/pages/guides/hugo0.122.mdx index d93606f7..be61c6d3 100644 --- a/pages/guides/hugo0.122.mdx +++ b/pages/guides/hugo0.122.mdx @@ -2,10 +2,12 @@ title: "Hugo" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [Hugo](https://gohugo.io/commands/hugo_server/), a high performance webserver, with the [ananke](https://github.com/budparr/gohugo-theme-ananke.git) theme. To run it, follow these steps: @@ -15,6 +17,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/hugo0.122/` directory: ```bash diff --git a/pages/guides/imaginary.mdx b/pages/guides/imaginary.mdx index e38dc34e..f742d9a6 100644 --- a/pages/guides/imaginary.mdx +++ b/pages/guides/imaginary.mdx @@ -2,10 +2,12 @@ title: "Imaginary" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example uses [`imaginary`](https://github.com/h2non/imaginary), an HTTP microservice for high-level image processing. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/imaginary/` directory: ```bash diff --git a/pages/guides/mariadb.mdx b/pages/guides/mariadb.mdx index 4d34f883..85e9e63b 100644 --- a/pages/guides/mariadb.mdx +++ b/pages/guides/mariadb.mdx @@ -2,10 +2,12 @@ title: "MariaDB" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [MariaDB](https://mariadb.org), one of the most popular open source relational databases. To run it, follow these steps: @@ -14,6 +16,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/mariadb/` directory: ```bash @@ -99,14 +106,12 @@ timestamps: In this case, the instance name is `mariadb-w2g2z` which is different for each run. -To test the deployment, first forward the port with the `kraft cloud tunnel` command. +To test the deployment, first forward the port with the `socat` command. ```bash -kraft cloud tunnel 3306:mariadb-w2g2z:3306 +socat TCP-LISTEN:3306,reuseaddr,fork OPENSSL:twilight-sun-82lt4ddk.fra.unikraft.app:3306,verify=0 ``` -The `kraft cloud tunnel` command is only supported by the legacy CLI. - You can now, on a separate console, use the `mysql` command line tool to test that the set up works: ```bash @@ -126,12 +131,14 @@ count(*) 6 ``` -To disconnect, kill the `tunnel` command using `Ctrl+c`. +To disconnect, kill the `socat` command using `Ctrl+c`. -> **Note:** -> This guide uses `kraft cloud tunnel` only when a service doesn't support TLS and isn't HTTP-based (TLS/SNI determines the correct instance to send traffic to). -> Also note that the `tunnel` command isn't needed when connecting via an instance's private IP/FQDN. -> For example when the MariaDB instance serves as a database server to another instance that acts as a frontend and which **does** support TLS. +:::note +This guide uses `socat` for port forwarding only when a service doesn't support TLS and isn't HTTP-based (TLS/SNI determines the correct instance to send traffic to). +Also note that port forwarding isn't needed when connecting via an instance's private IP/FQDN. +For example, when a MariaDB instance serves as a database server to +another instance that acts as a frontend and which **does** support TLS. +::: You can list information about the instance by running: @@ -175,8 +182,9 @@ kraft cloud instance remove mariadb-w2g2z -> **Tip:** -> This example uses the [`idle` scale-to-zero policy](/api/platform/v1/instances#scaletozero_policy) by default (see the `labels` section in the `Kraftfile`). +:::tip +This example uses the [`idle` scale-to-zero policy](/api/platform/v1/instances#scaletozero_policy) by default (see the `labels` section in the `Kraftfile`). +::: ## Using volumes diff --git a/pages/guides/mcp-server-arxiv.mdx b/pages/guides/mcp-server-arxiv.mdx index 6ca422af..7885a279 100644 --- a/pages/guides/mcp-server-arxiv.mdx +++ b/pages/guides/mcp-server-arxiv.mdx @@ -2,10 +2,12 @@ title: "ArXiv MCP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example demonstrates how to deploy the [ArXiv MCP server](https://github.com/blazickjp/arxiv-mcp-server) on Unikraft Cloud. The ArXiv MCP Server is a third-party library that provides stdio-based MCP tools for accessing arXiv research papers. @@ -27,6 +29,11 @@ To run this MCP server on Unikraft Cloud: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/mcp-server-arxiv/` directory: ```bash diff --git a/pages/guides/mcp-server-simple.mdx b/pages/guides/mcp-server-simple.mdx index db8ad678..c52d7d34 100644 --- a/pages/guides/mcp-server-simple.mdx +++ b/pages/guides/mcp-server-simple.mdx @@ -2,10 +2,12 @@ title: "Simple MCP Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example demonstrates how to build a minimal custom MCP (Model Context Protocol) server from scratch using [FastMCP 2.0](https://github.com/jlowin/fastmcp). This is a great starting point for building your own custom MCP servers with business-specific tools and logic. @@ -19,6 +21,11 @@ To run this MCP server on Unikraft Cloud: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/mcp-server-simple/` directory: ```bash diff --git a/pages/guides/memcached1.6.mdx b/pages/guides/memcached1.6.mdx index 81f8b31c..9df47911 100644 --- a/pages/guides/memcached1.6.mdx +++ b/pages/guides/memcached1.6.mdx @@ -2,10 +2,12 @@ title: "Memcached" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [Memcached](https://memcached.org). Memcached is an in-memory key-value store for small chunks of arbitrary data (strings, objects) from results of database calls, API calls, or page rendering. @@ -16,6 +18,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/memcached1.6/` directory: ```bash @@ -101,21 +108,22 @@ timestamps: In this case, the instance name is `memcached16-arkv7` which is different for each run. -To test the deployment, first forward the port with the `kraft cloud tunnel` command: +To test the deployment, first forward the port with the `socat` command: ```bash -kraft cloud tunnel 11211:memcached16-arkv7:11211 +socat TCP-LISTEN:11211,reuseaddr,fork OPENSSL:weathered-smoke-hehsdinv.fra.unikraft.app:11211,verify=0 ``` -The `kraft cloud tunnel` command is only supported by the legacy CLI. - Now, on a separate console, run the following commands to test that it works (you should see output when incrementing): ```console telnet 127.0.0.1 11211 + set test 0 0 1 0 + incr test 1 + incr test 1 ``` @@ -126,12 +134,14 @@ Ctrl + ] Ctrl + C ``` -To disconnect, kill the `tunnel` command with ctrl-C. +To disconnect, kill the `socat` command with ctrl-C. -> **Note:** -> This guide uses `kraft cloud tunnel` only when a service doesn't support TLS and isn't HTTP-based (TLS/SNI determines the correct instance to send traffic to). -> Also note that the `tunnel` command isn't needed when connecting via an instance's private IP/FQDN. -> For example when a Memcached instance serves as a cache server to another instance that acts as a frontend and which **does** support TLS. +:::note +This guide uses `socat` for port forwarding only when a service doesn't support TLS and isn't HTTP-based (TLS/SNI determines the correct instance to send traffic to). +Also note that port forwarding isn't needed when connecting via an instance's private IP/FQDN. +For example, when a Memcached instance serves as a cache server to +another instance that acts as a frontend and which **does** support TLS. +::: You can list information about the instance by running: diff --git a/pages/guides/minio.mdx b/pages/guides/minio.mdx index 9166db1a..7b6b998d 100644 --- a/pages/guides/minio.mdx +++ b/pages/guides/minio.mdx @@ -2,10 +2,12 @@ title: "Minio" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [MinIO](https://min.io), a High Performance Object Storage which is Open Source, Amazon S3 compatible, Kubernetes Native and works for cloud native workloads like AI. @@ -16,6 +18,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/minio/` directory: ```bash diff --git a/pages/guides/mongodb.mdx b/pages/guides/mongodb.mdx index 844dbd29..7e3bc5bf 100644 --- a/pages/guides/mongodb.mdx +++ b/pages/guides/mongodb.mdx @@ -2,10 +2,12 @@ title: "MongoDB" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [MongoDB](https://www.mongodb.com), a source-available, cross-platform, document-oriented database program. To run it, follow these steps: @@ -15,6 +17,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/mongodb/` directory: ```bash diff --git a/pages/guides/nginx.mdx b/pages/guides/nginx.mdx index cc48c3f9..b6dafe1e 100644 --- a/pages/guides/nginx.mdx +++ b/pages/guides/nginx.mdx @@ -2,10 +2,12 @@ title: "Nginx" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example uses [`Nginx`](https://nginx.org), one of the most popular web servers. Nginx can be used with Unikraft / Unikraft Cloud to serve static web content. @@ -16,6 +18,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/nginx/` directory: ```bash diff --git a/pages/guides/node-playwright-chromium.mdx b/pages/guides/node-playwright-chromium.mdx index d6c25b85..e18ec561 100644 --- a/pages/guides/node-playwright-chromium.mdx +++ b/pages/guides/node-playwright-chromium.mdx @@ -2,10 +2,12 @@ title: "Playwright (Chromium) with Node.js" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [Playwright](https://playwright.dev/) is a framework for web testing and Automation. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node-playwright-chromium/` directory: ```bash diff --git a/pages/guides/node-playwright-firefox.mdx b/pages/guides/node-playwright-firefox.mdx index 4a7b986e..9d1ffd0a 100644 --- a/pages/guides/node-playwright-firefox.mdx +++ b/pages/guides/node-playwright-firefox.mdx @@ -2,10 +2,12 @@ title: "Playwright (Firefox) with Node.js" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [Playwright](https://playwright.dev/) is a framework for web testing and Automation. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node-playwright-firefox/` directory: ```bash diff --git a/pages/guides/node-playwright-webkit.mdx b/pages/guides/node-playwright-webkit.mdx index 7357ecf7..0cc74003 100644 --- a/pages/guides/node-playwright-webkit.mdx +++ b/pages/guides/node-playwright-webkit.mdx @@ -2,10 +2,12 @@ title: "Playwright (WebKit) with Node.js" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [Playwright](https://playwright.dev/) is a framework for web testing and Automation. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node-playwright-webkit/` directory: ```bash diff --git a/pages/guides/node18-agario.mdx b/pages/guides/node18-agario.mdx index 3b300bd4..fddd7b64 100644 --- a/pages/guides/node18-agario.mdx +++ b/pages/guides/node18-agario.mdx @@ -2,10 +2,12 @@ title: "Agar.io (Node)" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [Agar.io](https://agar.io/) is a popular multiplayer game where players control a cell and aim to grow by consuming smaller cells while avoiding being consumed by larger ones. This guide deploys an implementation of the game using Node.js on Unikraft Cloud. @@ -16,6 +18,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node18-agario/` directory: ```bash diff --git a/pages/guides/node18-wingsio.mdx b/pages/guides/node18-wingsio.mdx index 6d071d55..1ec38e98 100644 --- a/pages/guides/node18-wingsio.mdx +++ b/pages/guides/node18-wingsio.mdx @@ -2,10 +2,12 @@ title: "Wings.io (Node)" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [Wings.io](https://wings.io/) is a multiplayer .io game where players control a plane and try to shoot down other players while avoiding being shot themselves. This guide deploys an implementation of the game using Node.js on Unikraft Cloud. @@ -16,6 +18,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node18-wingsio/` directory: ```bash diff --git a/pages/guides/node21-websocket.mdx b/pages/guides/node21-websocket.mdx index 0c5badfc..cac2444a 100644 --- a/pages/guides/node21-websocket.mdx +++ b/pages/guides/node21-websocket.mdx @@ -2,10 +2,12 @@ title: "Node WebSocket Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [WebSocket](https://en.wikipedia.org/wiki/WebSocket) is a bidirectional communication protocol over TCP, compatible with HTTP. This example builds an echo-reply WebSocket server in [Node](https://nodejs.org/en). @@ -16,6 +18,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node21-websocket/` directory: ```bash diff --git a/pages/guides/node24-karaoke.mdx b/pages/guides/node24-karaoke.mdx index 663e1064..d79b6108 100644 --- a/pages/guides/node24-karaoke.mdx +++ b/pages/guides/node24-karaoke.mdx @@ -2,10 +2,12 @@ title: "Node AllKaraoke" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [Allkaraoke](https://github.com/Asvarox/allkaraoke) offers an ultrastar deluxe-like online platform for karaoke. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/node24-karaoke` directory: ```bash @@ -179,7 +186,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/entrypoint.sh"]`: Use `/entrypoint.sh` as the starting command of the instance. diff --git a/pages/guides/novnc-browser.mdx b/pages/guides/novnc-browser.mdx index 5e9dfc3b..77dc3d6d 100644 --- a/pages/guides/novnc-browser.mdx +++ b/pages/guides/novnc-browser.mdx @@ -2,10 +2,12 @@ title: "noVNC" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a [noVNC](https://novnc.com/info.html) app, allowing you to access remote desktops through a web interface inside a modern browser. @@ -18,6 +20,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/novnc-browser` directory: ```bash diff --git a/pages/guides/opentelemetry-collector.mdx b/pages/guides/opentelemetry-collector.mdx index 180e1688..6a4a8c57 100644 --- a/pages/guides/opentelemetry-collector.mdx +++ b/pages/guides/opentelemetry-collector.mdx @@ -2,10 +2,12 @@ title: "OpenTelemetry Collector" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example uses [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/), a vendor-agnostic implementation of how to receive, process and export telemetry data. OpenTelemetry Collector works with Unikraft / Unikraft Cloud to process telemetry data. @@ -17,6 +19,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/opentelemetry-collector/` directory: ```bash diff --git a/pages/guides/postgres.mdx b/pages/guides/postgres.mdx index 242ba86d..677b2753 100644 --- a/pages/guides/postgres.mdx +++ b/pages/guides/postgres.mdx @@ -2,10 +2,12 @@ title: "PostgreSQL" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [PostgreSQL](https://www.postgresql.org/), a powerful, open source object-relational database system. To run it, follow these steps: @@ -15,6 +17,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/postgres/` directory: ```bash @@ -122,19 +129,21 @@ postgres=# Use SQL and `psql` commands for your work. -> **Tip:** -> This example uses the [`idle` scale-to-zero policy](/api/platform/v1/instances#scaletozero_policy) by default (see the `labels` section in the `Kraftfile`). -> It means that the instance will scale-to-zero even in the presence of `psql` connections. -> To ensure that the instance isn't put into standby even for long running queries -> (during which the connections are also idle). -> The PostgreSQL example makes use of scale-to-zero app support. -> To this end, the example loads the [`pg_ukc_scaletozero`](https://github.com/unikraft-cloud/pg_ukc_scaletozero) module into PostgreSQL, which suspends scale-to-zero during query processing. -> You can see this in action by running `SELECT pg_sleep(10);` and verifying that the instance keeps on running. - -> **Note:** -> If you'd like to use a port other than `5432/tls` you'll need to use the `kraft cloud tunnel` command to connect to PostgreSQL. -> See [the tunneling guide](/cli/tunnel) for more information. -> Additionally, you need to explicitly disable scale-to-zero by either changing the label in the `Kraftfile` or use `--scale-to-zero off` in the deploy command. +:::tip +This example uses the [`idle` scale-to-zero policy](/api/platform/v1/instances#scaletozero_policy) by default (see the `labels` section in the `Kraftfile`). +It means that the instance will scale-to-zero even in the presence of `psql` connections. +To ensure that the instance isn't put into standby even for long running queries +(during which the connections are also idle). +The PostgreSQL example makes use of scale-to-zero app support. +To this end, the example loads the [`pg_ukc_scaletozero`](https://github.com/unikraft-cloud/pg_ukc_scaletozero) module into PostgreSQL, which suspends scale-to-zero during query processing. +You can see this in action by running `SELECT pg_sleep(10);` and verifying that the instance keeps on running. +::: + +:::note +If you'd like to use a port other than `5432/tls` you'll need to use the `socat` command to connect to PostgreSQL. +See the [MariaDB](https://github.com/unikraft-cloud/examples/tree/main/mariadb) example for a guide on how to use it. +Additionally, you need to explicitly disable scale-to-zero by either changing the label in the `Kraftfile` or use `--scale-to-zero off` in the deploy command. +::: You can list information about the instance by running: @@ -223,8 +232,9 @@ You could also a different location to mount your volume or set extra configurat You can use the PostgreSQL instance in conjunction with a frontend service, [see the guide here](/platform/services). But in that case make sure to disable scale-to-zero if you plan to use the DB internally. -> **Note:** -> Support for scale-to-zero for internal instances is coming soon. +:::note +Support for scale-to-zero for internal instances is coming soon. +::: ## Learn more diff --git a/pages/guides/python-playwright-chromium.mdx b/pages/guides/python-playwright-chromium.mdx index 55921982..939632f8 100644 --- a/pages/guides/python-playwright-chromium.mdx +++ b/pages/guides/python-playwright-chromium.mdx @@ -2,10 +2,12 @@ title: "Playwright (Chromium) with Python FastAPI" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [Playwright](https://playwright.dev/) is a framework for web testing and Automation. To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/python-playwright-chromium/` directory: ```bash diff --git a/pages/guides/redis7.2.mdx b/pages/guides/redis7.2.mdx index 5b4bcab1..a218fe94 100644 --- a/pages/guides/redis7.2.mdx +++ b/pages/guides/redis7.2.mdx @@ -2,10 +2,12 @@ title: "Redis" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [Redis](https://redis.io), an open source in-memory storage, used as a distributed, in-memory key–value database, cache and message broker, with optional durability. To run it, follow these steps: @@ -15,6 +17,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/redis7.2/` directory: ```bash @@ -138,11 +145,12 @@ You should see output like: To disconnect, kill the `socat` command with ctrl-C. -> **Note:** -> This guide uses `socat` for port forwarding only when a service doesn't support TLS and isn't HTTP-based (TLS/SNI determines the correct instance to send traffic to). -> Also note that port forwarding isn't needed when connecting via an instance's private IP/FQDN. -> For example, when a Redis instance serves as a cache server to -> another instance that acts as a frontend and which **does** support TLS. +:::note +This guide uses `socat` for port forwarding only when a service doesn't support TLS and isn't HTTP-based (TLS/SNI determines the correct instance to send traffic to). +Also note that port forwarding isn't needed when connecting via an instance's private IP/FQDN. +For example, when a Redis instance serves as a cache server to +another instance that acts as a frontend and which **does** support TLS. +::: You can list information about the instance by running: diff --git a/pages/guides/ruby3.2-rails.mdx b/pages/guides/ruby3.2-rails.mdx index 4756b6b3..32554df6 100644 --- a/pages/guides/ruby3.2-rails.mdx +++ b/pages/guides/ruby3.2-rails.mdx @@ -2,10 +2,12 @@ title: "Ruby on Rails" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a [Ruby on Rails](https://rubyonrails.org/) app. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/ruby3.2-rails/` directory: ```bash @@ -197,7 +204,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/ruby", "/app/bin/rails", "server", "-b", "0.0.0.0"]`: Use `/usr/bin/ruby /app/bin/rails server -b 0.0.0.0` as the starting command of the instance. diff --git a/pages/guides/skipper0.18.mdx b/pages/guides/skipper0.18.mdx index e6316d71..2f62b833 100644 --- a/pages/guides/skipper0.18.mdx +++ b/pages/guides/skipper0.18.mdx @@ -2,10 +2,12 @@ title: "Skipper" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example uses [`Skipper`](https://opensource.zalando.com/skipper/), an HTTP router and reverse proxy for service composition To run this example, follow these steps: @@ -15,6 +17,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/skipper0.18/` directory: ```bash diff --git a/pages/guides/spin-wagi-http.mdx b/pages/guides/spin-wagi-http.mdx index 9e9fac31..14b24851 100644 --- a/pages/guides/spin-wagi-http.mdx +++ b/pages/guides/spin-wagi-http.mdx @@ -2,10 +2,12 @@ title: "Spin" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a simple Spin HTTP app. This guide comes from [Spin's `spin-wagi-http` example](https://github.com/fermyon/spin/tree/v2.1.0/examples/spin-wagi-http). It shows how to run a Spin app serving routes from two programs written in different languages (Rust and C++). @@ -17,6 +19,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/spin-wagi-http/` directory: ```bash @@ -179,7 +186,7 @@ Lines in the `Kraftfile` have the following roles: * `rootfs`: Build the app root filesystem. `source: ./Dockerfile` means the filesystem is built using the `Dockerfile`. - `type: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). + `format: erofs` means the filesystem type is [EROFS](https://erofs.docs.kernel.org/). * `cmd: ["/usr/bin/spin", "up", "--from", "/app/spin.toml", "--listen", "0.0.0.0:3000"]`: Use `spin` as the command to start the app, with the given parameters. diff --git a/pages/guides/traefik.mdx b/pages/guides/traefik.mdx index 6f83914b..f117b26e 100644 --- a/pages/guides/traefik.mdx +++ b/pages/guides/traefik.mdx @@ -2,10 +2,12 @@ title: "Traefik" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example uses the [`Traefik`](https://traefik.io/traefik/) cloud native app proxy. To run it, follow these steps: @@ -14,6 +16,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/traefik/` directory: ```bash @@ -112,9 +119,10 @@ curl https://holy-cherry-rye39b1x.fra.unikraft.app:8080/dashboard Or better yet, point a browser at the dashboard. -> **Danger:** -> This set up exposes the dashboard on port 8080 without authentication. -> Please change default.toml as needed. +:::danger +This set up exposes the dashboard on port 8080 without authentication. +Please change default.toml as needed. +::: You can list information about the instance by running: diff --git a/pages/guides/visual-studio-code-server.mdx b/pages/guides/visual-studio-code-server.mdx index a018636b..518bd44e 100644 --- a/pages/guides/visual-studio-code-server.mdx +++ b/pages/guides/visual-studio-code-server.mdx @@ -2,10 +2,12 @@ title: "Visual Studio Code Server" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + [Visual Studio Code](https://code.visualstudio.com/) is a source-code editor developed by Microsoft. It includes support for debugging, syntax highlighting, intelligent code completion, snippets, code refactoring, and embedded Git. It features a [Code server](https://code.visualstudio.com/docs/remote/vscode-server), which allows you to run Visual Studio Code remotely and access it through a web browser or your local Visual Studio Code client. @@ -18,6 +20,11 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/visual-studio-code-server` directory: ```bash diff --git a/pages/guides/vsftpd.mdx b/pages/guides/vsftpd.mdx index 5b165aae..a0b42e1e 100644 --- a/pages/guides/vsftpd.mdx +++ b/pages/guides/vsftpd.mdx @@ -2,10 +2,12 @@ title: "vsftpd" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide explains how to create and deploy a [vsftpd](https://security.appspot.com/vsftpd.html) app, to secure access to the files of your VM. To run this example, follow these steps: @@ -14,6 +16,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/vsftpd` directory: ```bash diff --git a/pages/guides/wazero-import-go.mdx b/pages/guides/wazero-import-go.mdx index 3553abcc..f46c6ac9 100644 --- a/pages/guides/wazero-import-go.mdx +++ b/pages/guides/wazero-import-go.mdx @@ -2,10 +2,12 @@ title: "Wazero" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This example comes from [Wazero's "import go" example](https://github.com/tetratelabs/wazero/tree/main/examples/import-go) and shows how to define, import and call a wasm blob from Go and run it on Unikraft Cloud. @@ -16,6 +18,11 @@ To run this example, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/wazero-import-go/` directory: ```bash diff --git a/pages/guides/wordpress-all-in-one.mdx b/pages/guides/wordpress-all-in-one.mdx index ffde535e..bbea8ef4 100644 --- a/pages/guides/wordpress-all-in-one.mdx +++ b/pages/guides/wordpress-all-in-one.mdx @@ -2,10 +2,12 @@ title: "Wordpress" --- - import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs" {/* vale off */} +{/* THIS FILE WAS AUTOGENERATED FROM THE PUBLIC EXAMPLE REPOSITORY. DO NOT EDIT THIS FILE DIRECTLY. */} + + This guide shows you how to use [Wordpress](https://wordpress.com/), a web content management system. To run it, follow these steps: @@ -15,6 +17,12 @@ To run it, follow these steps: You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). Alternatively, you can also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). +:::note +The unikraft CLI is the current standard, while kraft is the legacy version. +Choose one of the CLIs below and only run the commands associated with it for the rest of this guide. +::: + + 2. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/wordpress-all-in-one/` directory: ```bash diff --git a/zudoku.config.tsx b/zudoku.config.tsx index b176a74f..704b026a 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -152,6 +152,7 @@ const config: ZudokuConfig = { "/guides/httpserver-erlang26.2", // Erlang HTTP Server "/guides/httpserver-expressjs4.18-node21", // Express HTTP Server "/guides/httpserver-python3.12-fastapi-0.121.3", // FastAPI HTTP Server + "/guides/httpserver-flask-redis", // Flask + Redis HTTP Server "/guides/httpserver-python3.12-flask3.0-sqlite", // Flask and SQLite HTTP Server "/guides/httpserver-python3.12-flask3.0", // Flask HTTP Server "/guides/github-webhook-node", // GitHub Webhook receiver @@ -183,13 +184,13 @@ const config: ZudokuConfig = { "/guides/httpserver-prisma-expressjs4.19-node18", // Prisma HTTP Server "/guides/httpserver-node-express-puppeteer", // Puppeteer HTTP Server "/guides/httpserver-python3.12", // Python HTTP Server + "/guides/httpserver-node22-react-router", // React Router HTTP Server "/guides/redis7.2", // Redis - "/guides/httpserver-node21-remix", // Remix HTTP Server "/guides/httpserver-ruby3.2", // Ruby HTTP Server "/guides/ruby3.2-rails", // Ruby on Rails - "/guides/httpserver-rust1.87-actix-web4", // Rust (Actix Web) HTTP Server + "/guides/httpserver-rust1.88-actix-web4", // Rust (Actix Web) HTTP Server "/guides/httpserver-rust-trunkrs-leptos", // Rust (Leptos + Trunk) HTTP Server - "/guides/httpserver-rust1.81-rocket0.5", // Rust (Rocket) HTTP Server + "/guides/httpserver-rust1.88-rocket0.5", // Rust (Rocket) HTTP Server "/guides/httpserver-rust1.75-tokio", // Rust (Tokio) HTTP Server "/guides/httpserver-rust1.91", // Rust HTTP Server "/guides/mcp-server-simple", // Simple MCP Server @@ -199,7 +200,7 @@ const config: ZudokuConfig = { "/guides/httpserver-java17-springboot3.5.x", // Spring Boot HTTP Server "/guides/httpserver-java17-spring-petclinic", // Spring PetClinic "/guides/httpserver-c-debug", // SSH and HTTP Server with C and Debugging Tools - "/guides/httpserver-node21-sveltekit", // SvelteKit HTTP Server + "/guides/httpserver-node22-sveltekit", // SvelteKit HTTP Server "/guides/traefik", // Traefik "/guides/visual-studio-code-server", // Visual Studio Code Server "/guides/httpserver-node-vite-vanilla", // Vite (vanilla) From 4b98ae1e0fa4d0efe571f4e78dd04f244ad16669 Mon Sep 17 00:00:00 2001 From: Adina-Maria Vaman Date: Fri, 8 May 2026 19:33:07 +0300 Subject: [PATCH 128/131] feat(use-cases): Add remote desktops use-case with noVNC example Signed-off-by: Adina-Maria Vaman --- pages/use-cases/remote-desktops.mdx | 224 ++++++++++++++++++++++++++++ zudoku.config.tsx | 1 + 2 files changed, 225 insertions(+) create mode 100644 pages/use-cases/remote-desktops.mdx diff --git a/pages/use-cases/remote-desktops.mdx b/pages/use-cases/remote-desktops.mdx new file mode 100644 index 00000000..c2633190 --- /dev/null +++ b/pages/use-cases/remote-desktops.mdx @@ -0,0 +1,224 @@ +--- +title: Remote Desktops +navigation_icon: screen-share +--- + +Full remote desktop environments power browser-based access to Linux GUIs, agentic computer-use workloads, secure browsing sessions, and disposable workstations. +They're memory-hungry, security-sensitive, and often run in short, interactive burstsβ€”making them a strong fit for microVM-based, scale-to-zero infrastructure. + + +## Why run remote desktops on Unikraft Cloud + +### ⚑ Instant session startups + +MicroVMs on Unikraft Cloud boot in milliseconds, so a full desktop is ready the moment a user opens the link: + +* No waiting for heavy VMs or container images to warm up. +* Sessions resume from standby in milliseconds when traffic returns. + +### πŸ”’ Strong session isolation + +Remote desktops run untrusted browsers, untrusted documents, and arbitrary user input. +With Unikraft Cloud: + +* Each desktop runs in its own VM, isolated by design. +* A minimal, single-purpose image reduces attack surface. + +### πŸ’Έ Cost-efficient scale-to-zero + +Interactive sessions are burstyβ€”active for minutes, idle for hours: + +* Desktops scale-to-zero between sessions, removing idle costs. +* Pay only for the seconds users actively spend in the session. + +### πŸ€– Built for automation + +Computer-use workloads drive a real desktop the same way a human does: + +* Expose a noVNC endpoint over HTTPS for browser or programmatic access. +* Spin up a fresh, disposable environment per task or per session. + + +## Getting started + +Remote desktops on **Unikraft Cloud** run faster, safer, and cheaper. +From disposable browsers to a Linux GUI in a tab, you get instant scale-out and zero idle costsβ€”without sacrificing isolation. + +This guide shows you how to use [noVNC](https://novnc.com/info.html), an open source Virtual Network Computing (VNC) client that runs in the browser, paired with a minimal Linux desktop and Firefox. + +To run it, follow these steps: + +1. Install the CLI and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/novnc-browser/` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/novnc-browser/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + +:::note + +A noVNC desktop instance on Unikraft Cloud requires 4GB to run. +Request an increase in the instance memory quota when you need more memory. + +::: + +When done, invoke the following command to deploy this app on Unikraft Cloud: + + + +```bash title="unikraft" +unikraft build . --output /novnc-browser:latest +unikraft run --scale-to-zero policy=on,cooldown-time=4000,stateful=true --metro fra -p 443:6080/tls+http -m 4G --name vnc-browser --image /novnc-browser:latest +``` + +```bash title="kraft" +kraft cloud deploy \ + --scale-to-zero on \ + --scale-to-zero-stateful \ + --scale-to-zero-cooldown 4s \ + -p 443:6080/tls+http \ + -M 4Gi \ + -n vnc-browser \ + . +``` + + + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: vnc-browser +uuid: 90a59b05-0ae1-4ca6-8383-79c5115355ee +state: starting +image: /novnc-browser +resources: + memory: 4096MiB + vcpus: 1 +service: + uuid: aaf03f7c-65e6-5624-d5f4-84e87450beee + name: weathered-fog-y5jjmwfd + domains: + - fqdn: weathered-fog-y5jjmwfd.fra.unikraft.app +networks: +- uuid: 61708609-d291-572d-4a4c-399413238199 + private-ip: 10.0.0.49 + mac: 12:b0:1e:47:6c:59 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ────────── name: vnc-browser + β”œ────────── uuid: 90a59b05-0ae1-4ca6-8383-79c5115355ee + β”œ───────── state: starting + β”œ──────── domain: https://weathered-fog-y5jjmwfd.fra.unikraft.app + β”œ───────── image: oci://unikraft.io//novnc-browser@sha256:fdb4887e84362ebbaf54c713e0d85f547e8ee173fe63a6ab39e94b7e612a9892 + β”œ──────── memory: 4096 MiB + β”œ─────── service: weathered-fog-y5jjmwfd + β”œ── private fqdn: vnc-browser.internal + β””──── private ip: 10.0.0.49 +``` + + + +In this case, the instance name is `vnc-browser`. +The address is different for each run. + +Open the provided address in a browser to reach the noVNC landing page. +From there, click **Connect** to open the remote desktop, which ships with Firefox and a minimal Linux GUI. + +At any time, you can list information about the instance: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra vnc-browser standby /novnc-browser 4.0GiB 1 weathered-fog-y5jjmwfd.fra.unikraft.app 2 minutes ago +``` + +```ansi title="kraft" +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +vnc-browser weathered-fog-y5jjmwfd.fra.unikraft.app standby standby oci://unikraft.io//novnc-browser@sha256:... 4.0 GiB 1 7.17 ms +``` + + + +When done, you can remove the instance: + + + +```bash title="unikraft" +unikraft instances delete vnc-browser +``` + +```bash title="kraft" +kraft cloud instance remove vnc-browser +``` + + + +### Customize your deployment + +The current deployment ships with Firefox, a tiling panel, and a small set of X11 utilities on top of Ubuntu. +Customizing the deployment means editing the `Dockerfile` to add the apps your users need, such as a different browser, an editor, or developer tools. +You can also adjust the screen geometry through the `WIDTH`, `HEIGHT`, and `DISPLAY_NUM` environment variables in `wrapper.sh`. + +[Anthropic's Computer Use Demo](https://github.com/anthropics/claude-quickstarts/tree/main/computer-use-demo) inspired this example, which works well as a sandbox for computer-use automation that needs to drive a real desktop. + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the [legacy CLI reference](/docs/cli/kraft/overview). diff --git a/zudoku.config.tsx b/zudoku.config.tsx index 704b026a..1181c336 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -95,6 +95,7 @@ const config: ZudokuConfig = { "/use-cases/webhooks", "/use-cases/remote-ides", "/use-cases/minecraft", + "/use-cases/remote-desktops", ], }, { From 3df311356f09787a35b1fb43a332cc9a35b5b61b Mon Sep 17 00:00:00 2001 From: procub3r Date: Sat, 9 May 2026 03:07:06 +0530 Subject: [PATCH 129/131] feat(use-cases): Add sandbox use case Signed-off-by: Sriprad Potukuchi --- pages/use-cases/sandboxes.mdx | 316 ++++++++++++++++++++++++++++++++++ zudoku.config.tsx | 1 + 2 files changed, 317 insertions(+) create mode 100644 pages/use-cases/sandboxes.mdx diff --git a/pages/use-cases/sandboxes.mdx b/pages/use-cases/sandboxes.mdx new file mode 100644 index 00000000..8680a239 --- /dev/null +++ b/pages/use-cases/sandboxes.mdx @@ -0,0 +1,316 @@ +--- +title: Sandboxes +navigation_icon: box +--- + +Sandboxes give you on-demand, isolated execution environments for any workload. +Spin up a microVM in milliseconds to run short-lived tasks such as executing code, processing data, or responding to an event. +Then let it vanish automatically. + +Or keep a sandbox running in the background for as long as a job requires. +Either way, every sandbox runs in its own dedicated microVM: hardware-isolated, minimal, and ready for the job. + +With **Unikraft Cloud**, you get the instant startup speed of containers together with the strong isolation guarantees of hardware virtualizationβ€”not one or the other. + +## Why run sandboxes on Unikraft Cloud + +### ⚑ Instant startup, every time + +Sandboxes need to be ready the moment a task arrives. +Unikraft Cloud instances boot in milliseconds: + +* Ephemeral sandboxes spin up and complete tasks before cold starts are even noticeable. +* Long-running sandboxes resume instantly from stateful scale-to-zero snapshots. +* No pre-warming pools or reserved capacity needed. + +### πŸ”’ True hardware isolation + +{/* vale off */} + +Running arbitrary or untrusted workloads such as user-submitted code, AI agent tool calls, third-party plugins, test payloads, etc. demands more than container-level isolation. + +{/* vale on */} + +Every sandbox on Unikraft Cloud runs in its own microVM: + +* No shared kernel between tenants. Each sandbox has its own. +* Hardware-enforced boundaries reduce the risk of container escape. +* A minimal OS footprint reduces the attack surface for every run. + +### πŸ’Έ Pay only for execution + +Sandboxes are inherently bursty. +Some complete in milliseconds while others run for hours. +Unikraft Cloud's pricing model fits: + +* You pay only for the actual execution time of ephemeral sandboxes. +* Long-running sandboxes scale-to-zero when idle and resume instantly when needed. +* No idle infrastructure, no wasted capacity between runs. + +## Getting started + +{/* vale off */} + +A great example of sandboxes in action is [OpenClaw](https://openclaw.ai/), an autonomous AI agent framework that runs in an isolated microVM on Unikraft Cloud. + +{/* vale on */} + +This guide explains how to create and deploy your own OpenClaw gateway on Unikraft Cloud. +To run this example, follow these steps: + +1. Install the CLI and a container runtime engine (for example, [Docker](https://docs.docker.com/engine/install/)). + Use the [unikraft CLI](/docs/cli/unikraft) or the legacy [kraft CLI](https://unikraft.org/docs/cli/install). + You need a [BuildKit](https://github.com/moby/buildkit) builder. The easiest way to get one is via [Docker](https://docs.docker.com/engine/install/). + You could also directly set up and use BuildKit, see the [quick start](https://github.com/moby/buildkit#quick-start). + +1. Clone the [`examples` repository](https://github.com/unikraft-cloud/examples) and `cd` into the `examples/openclaw` directory: + +```bash +git clone https://github.com/unikraft-cloud/examples +cd examples/openclaw/ +``` + +Make sure to log into Unikraft Cloud and pick a [metro](/platform/metros) close to you. +This guide uses `fra` (Frankfurt, πŸ‡©πŸ‡ͺ): + + + +```bash title="unikraft" +unikraft login +``` + +```bash title="kraft" +# Set Unikraft Cloud access token +export UKC_TOKEN=token +# Set metro to Frankfurt, DE +export UKC_METRO=fra +``` + + + +The `UKC_TOKEN` and `UKC_METRO` environment variables are only supported by the legacy CLI. + +When done, you may create the OpenClaw Unikraft Cloud image and deploy an instance from it like so: + + + +```bash title="unikraft" +unikraft build . --output /openclaw:latest +unikraft run --scale-to-zero policy=on,cooldown-time=10000 --metro fra -p 18789:18789/tls -p 2222:2222/tls -m 4G -e PUBKEY="...." --image /openclaw:latest +``` + +```bash title="kraft" +kraft cloud deploy \ + --scale-to-zero on \ + --scale-to-zero-cooldown 10s \ + -p 18789:18789/tls \ + -p 2222:2222/tls \ + -M 4Gi \ + -e PUBKEY="..." \ + . +``` + + + +Make sure to replace `` with your username / org-name and to set your SSH public key as the `PUBKEY` environment variable above. + +The output shows the instance address and other details: + + + +```ansi title="unikraft" +metro: fra +name: openclaw-8tosm +uuid: e2a6183a-721b-4145-bfaf-37a5f859bbc1 +state: starting +image: demo/openclaw +runtime: + env: + PUBKEY: * +resources: + memory: 4GiB + vcpus: 1 +service: + uuid: 7ab20338-b04d-4869-947b-9433e21677b1 + name: divine-flower-bxsaapup + domains: + - fqdn: divine-flower-bxsaapup.fra0-demo.unikraft.app +networks: +- uuid: 2b0b120b-6ce5-4b19-ac4c-04ee8f11526e + private-ip: 10.0.12.97 + mac: 12:b0:0a:00:0c:61 +timestamps: + created: just now +``` + +```ansi title="kraft" +[●] Deployed successfully! + β”‚ + β”œ───────── name: openclaw-8tosm + β”œ───────── uuid: e2a6183a-721b-4145-bfaf-37a5f859bbc1 + β”œ──────── metro: https://api.fra.unikraft.cloud/v1 + β”œ──────── state: starting + β”œ──────── image: demo/openclaw@sha256:7a3d9f2b5e8c1a4d7f0e3b6c9a2d5f8b1e4a7d0c3f6b9e2a5d8c1f4b7e0a3d6c9 + β”œ─────── memory: 4096 MiB + β”œ─ private fqdn: openclaw-8tosm.internal + β””─── private ip: 10.0.12.97 +``` + + + +In this case, the instance name is `openclaw-8tosm` and the address is `divine-flower-bxsaapup.fra0-demo.unikraft.app`. +These will be different for each run. + +You can now SSH into this instance and run the OpenClaw onboarding process. + +To SSH, you need to set up a tunnel that handles the TLS connection to the Unikraft Cloud instance. +This way, you have a non-TLS port that your SSH client can connect to: + +```bash +socat TCP-LISTEN:2222,reuseaddr,fork OPENSSL:divine-flower-bxsaapup.fra0-demo.unikraft.app:2222,verify=0 +``` + +Then connect to the instance via SSH using: + +```bash +ssh -l root localhost -p 2222 +``` + +You can list information about the instance by running: + + + +```bash title="unikraft" +unikraft instances list +``` + +```bash title="kraft" +kraft cloud instance list +``` + + + + + +```ansi title="unikraft" +METRO NAME STATE IMAGE ARGS MEMORY VCPUS CREATED +fra openclaw-8tosm starting demo/openclaw 4096MiB 1 just now +``` + +```ansi title="kraft" +NAME IMAGE ARGS CREATED AT +openclaw-8tosm demo/openclaw 20 seconds ago +``` + + + +When done, you can remove the instance using: + + + +```bash title="unikraft" +unikraft instances delete openclaw-8tosm +``` + +```bash title="kraft" +kraft cloud instance remove openclaw-8tosm +``` + + + +{/* vale off */} + +## OpenClaw Setup + +{/* vale on */} + +Once you have SSH'd into your instance, you may run: + +```bash +openclaw onboard +``` + +This will set up your OpenClaw gateway on the instance. +You will have to provide your LLM's API key here. + +Once done, make note of your `gateway.auth.token` (henceforth referenced as ``) from `~/.openclaw/openclaw.json` + +```bash +cat ~/.openclaw/openclaw.json +``` + +Set `gateway.controlUi.allowedOrigins` in `~/.openclaw/openclaw.json`: + +```json +... + "gateway": { + ... + "controlUi": { + "allowedOrigins": [ + "https://proud-smoke-cjf0wro8.fra0-demo.unikraft.app:18789" + ] + }, + ... + }, +... +``` + +Replace the address above with the address of your instance (noted earlier). + +Run the gateway: + +```bash +openclaw gateway run --bind lan +``` + +You may now access the web dashboard at the following address: + +```ansi +https://
:18789?token= +``` + +Where `
` is your above noted address and `` is your above noted token. + +For security reasons, you will have to manually approve your web "device" to start using the web dashboard. +Create a new SSH connection to your OpenClaw instance: + +```bash +ssh -l root localhost -p 2222 +``` + +First, find your device ID: + +```bash +openclaw devices list +``` + +Look under the `Request` column. +Device IDs look like `cabd915e-137a-4bc4-b640-d0e507684d65` + +Finally, approve your device with: + +```bash +openclaw devices approve +``` + +Once you approve your device, refresh your OpenClaw web dashboard. + +You now have full access to your own OpenClaw deployment on Unikraft Cloud! + +## Learn more + +Use the `--help` option for detailed information on using Unikraft Cloud: + + + +```bash title="unikraft" +unikraft --help +``` + +```bash title="kraft" +kraft cloud --help +``` + + + +Or visit the [CLI Reference](/docs/cli/unikraft) or the [legacy CLI reference](/docs/cli/overview). diff --git a/zudoku.config.tsx b/zudoku.config.tsx index 1181c336..ebe78814 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -86,6 +86,7 @@ const config: ZudokuConfig = { icon: "lightbulb", collapsed: false, items: [ + "/use-cases/sandboxes", "/use-cases/headless-browsers", "/use-cases/mcp-servers", "/use-cases/api-gateways", From 02e0eeff0a7e97af3c5132ca07e7c058d4b8493b Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Thu, 14 May 2026 13:34:04 +0300 Subject: [PATCH 130/131] fix(use-cases): Fix instance listing ANSI coloring Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/build-test-environments.mdx | 16 ++++++++++------ pages/use-cases/serverless-functions.mdx | 8 ++++++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/pages/use-cases/build-test-environments.mdx b/pages/use-cases/build-test-environments.mdx index 8969ecfe..8c6357be 100644 --- a/pages/use-cases/build-test-environments.mdx +++ b/pages/use-cases/build-test-environments.mdx @@ -175,6 +175,8 @@ kraft cloud instance template list +
+ ```ansi title="unikraft" @@ -371,18 +373,20 @@ kraft cloud instance list +
+ ```ansi title="unikraft" -[1mMETRO[0m [1mNAME[0m [1mSTATE[0m [1mIMAGE[0m [1mARGS[0m [1mMEMORY[0m [1mVCPUS[0m [1mFQDN[0m [1mCREATED[0m -fra go-build-env-rom2 [94mstandby[0m /go-build-env 512MiB 1 nameless-wood-gw7pbnls.fra.unikraft.app 2 minutes ago -fra go-build-env-rom1 [94mstandby[0m /go-build-env 512MiB 1 sparkling-dawn-syowlbtj.fra.unikraft.app 3 minutes ago +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED +fra go-build-env-rom2 standby /go-build-env 512MiB 1 nameless-wood-gw7pbnls.fra.unikraft.app 2 minutes ago +fra go-build-env-rom1 standby /go-build-env 512MiB 1 sparkling-dawn-syowlbtj.fra.unikraft.app 3 minutes ago ``` ```ansi title="kraft" -[1mNAME[0m [1mFQDN[0m [1mSTATE[0m [1mSTATUS[0m [1mIMAGE[0m [1mMEMORY[0m [1mVCPUS[0m [1mARGS[0m [1mBOOT TIME[0m -go-build-env-rom2 nameless-wood-gw7pbnls.fra.unikraft.app [94mstandby[0m standby oci://unikraft.io//go-build-env@sha256:1cbd64... 512 MiB 1 6.98 ms -go-build-env-rom1 sparkling-dawn-syowlbtj.fra.unikraft.app [94mstandby[0m standby oci://unikraft.io//go-build-env@sha256:1cbd64... 512 MiB 1 7.86 ms +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME +go-build-env-rom2 nameless-wood-gw7pbnls.fra.unikraft.app standby standby oci://unikraft.io//go-build-env@sha256:1cbd64... 512 MiB 1 6.98 ms +go-build-env-rom1 sparkling-dawn-syowlbtj.fra.unikraft.app standby standby oci://unikraft.io//go-build-env@sha256:1cbd64... 512 MiB 1 7.86 ms ``` diff --git a/pages/use-cases/serverless-functions.mdx b/pages/use-cases/serverless-functions.mdx index fd137d7b..65fa470d 100644 --- a/pages/use-cases/serverless-functions.mdx +++ b/pages/use-cases/serverless-functions.mdx @@ -173,6 +173,8 @@ kraft cloud instance template list +
+ ```ansi title="unikraft" @@ -344,16 +346,18 @@ kraft cloud instance list +
+ ```ansi title="unikraft" -[1mMETRO[0m [1mNAME[0m [1mSTATE[0m [1mIMAGE[0m [1mARGS[0m [1mMEMORY[0m [1mVCPUS[0m [1mFQDN[0m [1mCREATED[0m +METRO NAME STATE IMAGE ARGS MEMORY VCPUS FQDN CREATED fra node-exec-rom2 standby /node-code-exec 512MiB 1 nameless-wood-gw7pbnls.fra.unikraft.app 2 minutes ago fra node-exec-rom1 standby /node-code-exec 512MiB 1 sparkling-dawn-syowlbtj.fra.unikraft.app 3 minutes ago ``` ```ansi title="kraft" -[1mNAME[0m [1mFQDN[0m [1mSTATE[0m [1mSTATUS[0m [1mIMAGE[0m [1mMEMORY[0m [1mVCPUS[0m [1mARGS[0m [1mBOOT TIME[0m +NAME FQDN STATE STATUS IMAGE MEMORY VCPUS ARGS BOOT TIME node-exec-rom2 nameless-wood-gw7pbnls.fra.unikraft.app standby standby oci://unikraft.io//node-code-exec@sha256:71487f... 512 MiB 1 6.98 ms node-exec-rom1 sparkling-dawn-syowlbtj.fra.unikraft.app standby standby oci://unikraft.io//node-code-exec@sha256:71487f... 512 MiB 1 7.86 ms ``` From 8670cffe5a5023a9e7a221081d1be9cb20c38ef7 Mon Sep 17 00:00:00 2001 From: Alex-Andrei Cioc Date: Fri, 15 May 2026 11:55:22 +0300 Subject: [PATCH 131/131] chore(use-cases): Rename minecraft to game-servers Signed-off-by: Alex-Andrei Cioc --- pages/use-cases/{minecraft.mdx => game-servers.mdx} | 0 zudoku.config.tsx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename pages/use-cases/{minecraft.mdx => game-servers.mdx} (100%) diff --git a/pages/use-cases/minecraft.mdx b/pages/use-cases/game-servers.mdx similarity index 100% rename from pages/use-cases/minecraft.mdx rename to pages/use-cases/game-servers.mdx diff --git a/zudoku.config.tsx b/zudoku.config.tsx index ebe78814..465dd2a6 100644 --- a/zudoku.config.tsx +++ b/zudoku.config.tsx @@ -95,7 +95,7 @@ const config: ZudokuConfig = { "/use-cases/build-test-environments", "/use-cases/webhooks", "/use-cases/remote-ides", - "/use-cases/minecraft", + "/use-cases/game-servers", "/use-cases/remote-desktops", ], },