From 67d6da5cb50f6f95e7bd4adfee3cd92de331cc08 Mon Sep 17 00:00:00 2001 From: Craig Osterhout <103533812+craig-osterhout@users.noreply.github.com> Date: Tue, 7 May 2024 11:48:19 -0700 Subject: [PATCH] add database use-case guide (#19737) * add database use-case guide --------- Signed-off-by: Craig Osterhout --- content/guides/use-case/_index.md | 40 +- content/guides/use-case/databases.md | 678 ++++++++++++++++++ .../guides/use-case/images/databases-1.webp | Bin 0 -> 14276 bytes .../guides/use-case/images/databases-2.webp | Bin 0 -> 14164 bytes .../guides/use-case/images/databases-3.webp | Bin 0 -> 14940 bytes data/toc.yaml | 36 +- 6 files changed, 717 insertions(+), 37 deletions(-) create mode 100644 content/guides/use-case/databases.md create mode 100644 content/guides/use-case/images/databases-1.webp create mode 100644 content/guides/use-case/images/databases-2.webp create mode 100644 content/guides/use-case/images/databases-3.webp diff --git a/content/guides/use-case/_index.md b/content/guides/use-case/_index.md index 3577cb317b..e8f55f27fa 100644 --- a/content/guides/use-case/_index.md +++ b/content/guides/use-case/_index.md @@ -13,8 +13,10 @@ grid_genai: description: Explore a video transcription app that lets you ask questions about videos. icon: play_circle link: /guides/use-case/genai-video-bot/ - -grid_nlp: +- title: Face detection with TensorFlow.js + description: Explore a face detection app built with TensorFlow.js and Docker. + icon: face + link: /guides/use-case/tensorflowjs/ - title: Language translation description: Build and run an app to translate languages. link: /guides/use-case/nlp/language-translation/ @@ -41,23 +43,6 @@ Explore this collection of use-case guides designed to help you leverage Docker for a variety of advanced applications. From generative AI to security, discover how Docker can streamline your projects and workflows. -## Generative AI - -{{< grid items="grid_genai" >}} - -## Natural language processing - -{{< grid items="grid_nlp" >}} - -## TensorFlow - -{{< card - title="Face detection with TensorFlow.js" - icon=face - link=/guides/use-case/tensorflowjs/ - description="Explore a face detection app built with TensorFlow.js and Docker." ->}} - ## Data science {{< card @@ -67,6 +52,20 @@ how Docker can streamline your projects and workflows. description="Set up a JupyterLab environment to conduct and share data science research, making your projects more reproducible and scalable." >}} +## Databases & storage + +{{< card + title="Use containerized databases" + icon=storage + link=/guides/use-case/databases/ + description="Learn how to run and manage containerized databases." +>}} + +## Machine learning & AI + +{{< grid items="grid_genai" >}} + + ## Security {{< card @@ -74,4 +73,5 @@ how Docker can streamline your projects and workflows. icon=verified_user link=/scout/guides/vex/ description="Learn how to suppress non-applicable or fixed vulnerabilities found in your images." ->}} \ No newline at end of file +>}} + diff --git a/content/guides/use-case/databases.md b/content/guides/use-case/databases.md new file mode 100644 index 0000000000..8217a8d866 --- /dev/null +++ b/content/guides/use-case/databases.md @@ -0,0 +1,678 @@ +--- +description: Learn how to run, connect to, and persist data in a local containerized database. +keywords: database, mysql +title: Use containerized databases +--- + +Using a local containerized database offers flexibility and ease of setup, +letting you mirror production environments closely without the overhead of +traditional database installations. Docker simplifies this process, enabling you +to deploy, manage, and scale databases in isolated containers with just a few +commands. + +In this guide, you'll learn how to: + +- Run a local containerized database +- Access the shell of a containerized database +- Connect to a containerized database from your host +- Connect to a containerized database from another container +- Persist database data in a volume +- Build a customized database image +- Use Docker Compose to run a database + +This guide uses the MySQL image for examples, but the concepts can be applied to other database images. + +## Prerequisites + +To follow along with this guide, you must have Docker installed. To install Docker, see [Get Docker](../../get-docker.md). + +## Run a local containerized database + +Most popular database systems, including MySQL, PostgreSQL, and MongoDB, have a +Docker Official Image available on Docker Hub. These images are a curated set +images that follow best practices, ensuring that you have access to the latest +features and security updates. To get started, visit +[Docker Hub](https://hub.docker.com) and search for the database you're +interested in. Each image's page provides detailed instructions on how to run +the container, customize your setup, and configure the database according to +your needs. For more information about the MySQL image used in this guide, see the Docker Hub [MySQL image](https://hub.docker.com/_/mysql) page. + +To run a database container, you can use either the Docker Desktop GUI or +CLI. + +{{< tabs group="ui" >}} +{{< tab name="CLI" >}} + +To run a container using the CLI, run the following command in a terminal: + +```console +$ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -d mysql:latest +``` + +In this command: + +- `--name my-mysql` assigns the name my-mysql to your container for easier + reference. +- `-e MYSQL_ROOT_PASSWORD=my-secret-pw` sets the root password for MySQL to + my-secret-pw. Replace my-secret-pw with a secure password of your choice. +- `-e MYSQL_DATABASE=mydb` optionally creates a database named mydb. You can + change mydb to your desired database name. +- `-d` runs the container in detached mode, meaning it runs in the background. +- `mysql:latest` specifies that you want to use the latest version of the MySQL + image. + + To verify that you container is running, run `docker ps` in a terminal + +{{< /tab >}} +{{< tab name="GUI" >}} + +To run a container using the GUI: + +1. In the Docker Dashboard, select the global search at the top of the window. +2. Specify `mysql` in the search box, and select the `Images` tab if not already + selected. +3. Hover over the `msyql` image and select `Run`. + The **Run a new container** model appears. +4. Expand **Optional settings**. +5. In the optional settings, specify the following: + - **Container name**: `my-mysql` + - **Environment variables**: + - `MYSQL_ROOT_PASSWORD`:`my-secret-pw` + - `MYSQL_DATABASE`:`mydb` + + ![The optional settings screen with the options specified.](images/databases-1.webp) + +6. Select `Run`. +7. Open the **Container** view in the Docker Dashboard to verify that your + container is running. + +{{< /tab >}} +{{< /tabs >}} + +## Access the shell of a containerized database + +When you have a database running inside a Docker container, you may need to +access its shell to manage the database, execute commands, or perform +administrative tasks. Docker provides a straightforward way to do this using the +`docker exec` command. Additionally, if you prefer a graphical interface, you +can use Docker Desktop's GUI. + +If you don't yet have a database container running, see +[Run a local containerized database](#run-a-local-containerized-database). + +{{< tabs group="ui" >}} +{{< tab name="CLI" >}} + +To access the terminal of a MySQL container using the CLI, you can use the +following `docker exec` command. + +```console +$ docker exec -it my-mysql bash +``` + +In this command: + +- `docker exec` tells Docker you want to execute a command in a running + container. +- `-it` ensures that the terminal you're accessing is interactive, so you can + type commands into it. +- `my-mysql` is the name of your MySQL container. If you named your container + differently when you ran it, use that name instead. +- `bash` is the command you want to run inside the container. It opens up a bash + shell that lets you interact with the container's file system and installed + applications. + +After executing this command, you will be given access to the bash shell inside +your MySQL container, from which you can manage your MySQL server directly. You +can run `exit` to return to your terminal. + +{{< /tab >}} +{{< tab name="GUI" >}} + +1. Open the Docker Dashboard and select the **Containers** view. +2. In the **Actions** column for your container, select **Show container + actions** and then select **Open in terminal**. + +In this terminal you can access to the shell inside your MySQL container, from +which you can manage your MySQL server directly. + +{{< /tab >}} +{{< /tabs >}} + +Once you've accessed the container's terminal, you can run any tools available +in that container. The following example shows using `mysql` in the container to +list the databases. + +```console +# mysql -u root -p +Enter password: my-secret-pw + +mysql> SHOW DATABASES; + ++--------------------+ +| Database | ++--------------------+ +| information_schema | +| mydb | +| mysql | +| performance_schema | +| sys | ++--------------------+ +5 rows in set (0.00 sec) +``` + +## Connect to a containerized database from your host + +Connecting to a containerized database from your host machine involves mapping a +port inside the container to a port on your host machine. This process ensures +that the database inside the container is accessible via the host machine's +network. For MySQL, the default port is 3306. By exposing this port, you can use +various database management tools or applications on your host machine to +interact with your MySQL database. + +Before you begin, you must remove any containers you previously ran for this +guide. To stop and remove a container, either: + +- In a terminal, run `docker remove --force my-mysql` to remove the container + named `my-mysql`. +- Or, in the Docker Dashboard, select the **Delete** icon next to your + container in the **Containers** view. + + +Next, you can use either the Docker Desktop GUI or CLI to run the container with +the port mapped. + +{{< tabs group="ui" >}} +{{< tab name="CLI" >}} + +Run the following command in a terminal. + +```console +$ docker run -p 3306:3306 --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -d mysql:latest +``` + +In this command, `-p 3307:3306` maps port 3307 on the host to port 3306 in the container. + +To verify the port is mapped, run the following command. + +```console +$ docker ps +``` + +You should see output like the following. + +```console +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +6eb776cfd73c mysql:latest "docker-entrypoint.s…" 17 minutes ago Up 17 minutes 33060/tcp, 0.0.0.0:3307->3306/tcp my-mysql +``` + +{{< /tab >}} +{{< tab name="GUI" >}} + +To run a container using the GUI: + +1. In the Docker Dashboard, select the global search at the top of the window. +2. Specify `mysql` in the search box, and select the `Images` tab if not already + selected. +3. Hover over the `msyql` image and select `Run`. + The **Run a new container** model appears. +4. Expand **Optional settings**. +5. In the optional settings, specify the following: + + - **Container name**: `my-mysql` + - **Host port** for the **3306/tcp** port: `3307` + - **Environment variables**: + - `MYSQL_ROOT_PASSWORD`:`my-secret-pw` + - `MYSQL_DATABASE`:`mydb` + + ![The optional settings screen with the options specified.](images/databases-2.webp) + +6. Select `Run`. +7. In the **Containers** view, verify that the port is mapped under the + **Port(s)** column. You should see **3307:3306** for the **my-mysql** + container. + +{{< /tab >}} +{{< /tabs >}} + +At this point, any application running on your host can access the MySQL service in the container at `localhost:3307`. + +## Connect to a containerized database from another container + +Connecting to a containerized database from another container is a common +scenario in microservices architecture and during development processes. +Docker's networking capabilities make it easy to establish this connection +without having to expose the database to the host network. This is achieved by +placing both the database container and the container that needs to access it on +the same Docker network. + +Before you begin, you must remove any containers you previously ran for this +guide. To stop and remove a container, either: + +- In a terminal, run `docker remove --force my-mysql` to remove the container + named `my-mysql`. +- Or, in the Docker Dashboard, select the **Delete** icon next to your + container in the **Containers** view. + +To create a network and run containers on it: + +1. Run the following command to create a Docker network named my-network. + + ```console + $ docker network create my-network + ``` + +2. Run your database container and specify the network using the `--network` + option. This runs the container on the my-network network. + + ```console + $ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb --network my-network -d mysql:latest + ``` + +3. Run your other containers and specify the network using the `--network` + option. For this example, you'll run a phpMyAdmin container that can connect + to your database. + + 1. Run a phpMyAdmin container. Use the `--network` option to specify the + network, the `-p` option to let you access the container from your host + machine, and the `-e` option to specify a required environment variable + for this image. + + ```console + $ docker run --name my-phpmyadmin -d --network my-network -p 8080:80 -e PMA_HOST=my-mysql phpmyadmin + ``` + +4. Verify that the containers can communicate. For this example, you'll access + phpMyAdmin and verify that it connects to the database. + + 1. Open [http://localhost:8080](http://localhost:8080) to access your phpMyAdmin container. + 2. Log in using `root` as the username and `my-secret-pw` as the password. + You should connect to the MySQL server and see your database listed. + +At this point, any application running on your `my-network` container network +can access the MySQL service in the container at `my-mysql:3306`. + +## Persist database data in a volume + +Persisting database data in a Docker volume is necessary for ensuring that your +data survives container restarts and removals. A Docker volume lets you store +database files outside the container's writable layer, making it possible to +upgrade the container, switch bases, and share data without losing it. Here’s +how you can attach a volume to your database container using either the Docker +CLI or the Docker Desktop GUI. + +Before you begin, you must remove any containers you previously ran for this +guide. To stop and remove a container, either: + +- In a terminal, run `docker remove --force my-mysql` to remove the container + named `my-mysql`. +- Or, in the Docker Dashboard, select the **Delete** icon next to your + container in the **Containers** view. + +Next, you can use either the Docker Desktop GUI or CLI to run the container with a volume. + +{{< tabs group="ui" >}} +{{< tab name="CLI" >}} + +To run your database container with a volume attached, include the `-v` option +with your `docker run` command, specifying a volume name and the path where the +database stores its data inside the container. If the volume doesn't exist, +Docker automatically creates it for you. + +To run a database container with a volume attached, and then verify that the +data persists: + +1. Run the container and attach the volume. + + ```console + $ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -v my-db-volume:/var/lib/mysql -d mysql:latest + ``` + + This command mounts the volume named `my-db-volume` to the `/var/lib/mysql` directory in the container. + +2. Create some data in the database. Use the `docker exec` command to run + `mysql` inside the container and create a table. + + ```console + $ docker exec my-mysql mysql -u root -pmy-secret-pw -e "CREATE TABLE IF NOT EXISTS mydb.mytable (column_name VARCHAR(255)); INSERT INTO mydb.mytable (column_name) VALUES ('value');" + ``` + + This command uses the `mysql` tool in the container to create a table named + `mytable` with a column named `column_name`, and finally inserts a value of + `value`. + +3. Stop and remove the container. Without a volume, the table you created would + be lost when removing the container. + + ```console + $ docker remove --force my-mysql + ``` + +4. Start a new container with the volume attached. This time, you don't need to + specify any environment variables as the configuration is saved in the + volume. + + ```console + $ docker run --name my-mysql -v my-db-volume:/var/lib/mysql -d mysql:latest + ``` +5. Verify that the table you created still exists. Use the `docker exec` command + again to run `mysql` inside the container. + + ```console + $ docker exec my-mysql mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.mytable;" + ``` + + This command uses the `mysql` tool in the container to select all the + records from the `mytable` table. + + You should see output like the following. + ```console + column_name + value + ``` + +{{< /tab >}} +{{< tab name="GUI" >}} + +To run a database container with a volume attached, and then verify that the +data persists: + +1. Run a container with a volume attached. + 1. In the Docker Dashboard, select the global search at the top of the window. + 2. Specify `mysql` in the search box, and select the **Images** tab if not + already selected. + 3. Hover over the **mysql** image and select **Run**. + The **Run a new container** model appears. + 4. Expand **Optional settings**. + 5. In the optional settings, specify the following: + + - **Container name**: `my-mysql` + - **Environment variables**: + - `MYSQL_ROOT_PASSWORD`:`my-secret-pw` + - `MYSQL_DATABASE`:`mydb` + - **Volumes**: + - `my-db-volume`:`/var/lib/mysql` + + ![The optional settings screen with the options specified.](images/databases-3.webp) + + Here, the name of the volume is `my-db-volume` and it is mounted in the + container at `/var/lib/mysql`. + + 6. Select `Run`. +2. Create some data in the database. + 1. In the **Containers** view, next to your container select the **Show + container actions** icon, and then select **Open in terminal**. + 2. Run the following command in the container's terminal to add a table. + + ```console + # mysql -u root -pmy-secret-pw -e "CREATE TABLE IF NOT EXISTS mydb.mytable (column_name VARCHAR(255)); INSERT INTO mydb.mytable (column_name) VALUES ('value');" + ``` + + This command uses the `mysql` tool in the container to create a table + named `mytable` with a column named `column_name`, and finally inserts a + value of value`. + + +3. In the **Containers** view, select the **Delete** icon next to your + container, and then select **Delete forever**. Without a volume, the table + you created would be lost when deleting the container. +4. Run a container with a volume attached. + 1. In the Docker Dashboard, select the global search at the top of the window. + 2. Specify `mysql` in the search box, and select the **Images** tab if not + already selected. + 3. Hover over the **mysql** image and select **Run**. + The **Run a new container** model appears. + 4. Expand **Optional settings**. + 5. In the optional settings, specify the following: + + - **Container name**: `my-mysql` + - **Environment variables**: + - `MYSQL_ROOT_PASSWORD`:`my-secret-pw` + - `MYSQL_DATABASE`:`mydb` + - **Volumes**: + - `my-db-volume`:`/var/lib/mysql` + + ![The optional settings screen with the options specified.](images/databases-3.webp) + + 6. Select `Run`. +5. Verify that the table you created still exists. + 1. In the **Containers** view, next to your container select the **Show + container actions** icon, and then select **Open in terminal**. + 2. Run the following command in the container's terminal to verify that table + you created still exists. + + ```console + # mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.mytable;" + ``` + + This command uses the `mysql` tool in the container to select all the + records from the `mytable` table. + + + You should see output like the following. + + ```console + column_name + value + ``` + +{{< /tab >}} +{{< /tabs >}} + +At this point, any MySQL container that mounts the `my-db-volume` will be able +to access and save persisted data. + +## Build a customized database image + +Customizing your database image lets you include additional configuration, +scripts, or tools alongside the base database server. This is particularly +useful for creating a Docker image that matches your specific development or +production environment needs. The following example outlines how to build and +run a custom MySQL image that includes a table initialization script. + +Before you begin, you must remove any containers you previously ran for this +guide. To stop and remove a container, either: + +- In a terminal, run `docker remove --force my-mysql` to remove the container + named `my-mysql`. +- Or, in the Docker Dashboard, select the **Delete** icon next to your + container in the **Containers** view. + +To build and run your custom image: + +1. Create a Dockerfile. + 1. Create a file named `Dockerfile` in your project directory. For this + example, you can create the `Dockerfile` in an empty directory of your + choice. This file will define how to build your custom MySQL image. + 2. Add the following content to the `Dockerfile`. + + ```dockerfile + # syntax=docker/dockerfile:1 + + # Use the base image mysql:latest + FROM mysql:latest + + # Set environment variables + ENV MYSQL_DATABASE mydb + + # Copy custom scripts or configuration files from your host to the container + COPY ./scripts/ /docker-entrypoint-initdb.d/ + ``` + + In this Dockerfile, you've set the environment variable for the MySQL + database name. You can also use the `COPY` instruction to add custom + configuration files or scripts into the container. In this + example, files from your host's `./scripts/` directory are copied into the + container's `/docker-entrypoint-initdb.d/` directory. In this directory, + `.sh`, `.sql`, and `.sql.gz` scripts are executed when the container is + started for the first time. For more details about Dockerifles, see the + [Dockerfile reference](/reference/dockerfile/). + + 3. Create a script file to initialize a table in the database. In the + directory where your `Dockerfile` is located, create a subdirectory named + `scripts`, and then create a file named `create_table.sql` with the + following content. + + ```text + CREATE TABLE IF NOT EXISTS mydb.myothertable ( + column_name VARCHAR(255) + ); + + INSERT INTO mydb.myothertable (column_name) VALUES ('other_value'); + ``` + + You should now have the following directory structure. + + ```text + ├── your-project-directory/ + │ ├── scripts/ + │ │ └── create_table.sql + │ └── Dockerfile + ``` + +2. Build your image. + 1. In a terminal, change directory to the directory where your `Dockerfile` + is located. + 2. Run the following command to build the image. + + ```console + $ docker build -t my-custom-mysql . + ``` + In this command, `-t my-custom-mysql` tags (names) your new image as + `my-custom-mysql`. The period (.) at the end of the command specifies the + current directory as the context for the build, where Docker looks for the + Dockerfile and any other files needed for the build. + +3. Run your image as you did in [Run a local containerized + database](#run-a-local-containerized-database). This time, specify your + image's name instead of `mysql:latest`. Also, you no longer need to specify + the `MYSQL_DATABASE` environment variable as it's now defined by your + Dockerfile. + + ```console + $ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d my-custom-mysql + ``` + +4. Verify that your container is running with the following command. + + ```console + $ docker ps + ``` + + You should see output like the following. + + ```console + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + f74dcfdb0e59 my-custom-mysql "docker-entrypoint.s…" 2 hours ago Up 51 minutes 3306/tcp, 33060/tcp my-mysql + ``` + +5. Verify that your initialization script was ran. Run the following command in + a terminal to show the contents of the `myothertable` table. + + ```console + $ docker exec my-mysql mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.myothertable;" + ``` + + You should see output like the following. + ```console + column_name + other_value + ``` + +Any container ran using your `my-custom-mysql` image will have the table +initialized when first started. + +## Use Docker Compose to run a database + +Docker Compose is a tool for defining and running multi-container Docker +applications. With a single command, you can configure all your application's +services (like databases, web apps, etc.) and manage them. In this example, +you'll create a Compose file and use it to run a MySQL database container and a phpMyAdmin container. + +To run your containers with Docker Compose: + +1. Create a Docker Compose file. + 1. Create a file named `compose.yaml` in your project directory. This file + will define the services, networks, and volumes. + 2. Add the following content to the `compose.yaml` file. + + ```yaml + services: + db: + image: mysql:latest + environment: + MYSQL_ROOT_PASSWORD: my-secret-pw + MYSQL_DATABASE: mydb + ports: + - 3307:3306 + volumes: + - my-db-volume:/var/lib/mysql + + phpmyadmin: + image: phpmyadmin/phpmyadmin:latest + environment: + PMA_HOST: db + PMA_PORT: 3306 + MYSQL_ROOT_PASSWORD: my-secret-pw + ports: + - 8080:80 + depends_on: + - db + + volumes: + my-db-volume: + ``` + + For the database service: + + - `db` is the name of the service. + - `image: mysql:latest` specifies that the service uses the latest MySQL + image from Docker Hub. + - `environment` lists the environment variables used by MySQL to + initialize the database, such as the root password and the database + name. + - `ports` maps port 3307 on the host to port 3306 in the container, + allowing you to connect to the database from your host machine. + - `volumes` mounts `my-db-volume` to `/var/lib/mysql` inside the container + to persist database data. + + In addition to the database service, there is a phpMyAdmin service. By + default Compose sets up a single network for your app. Each container for + a service joins the default network and is both reachable by other + containers on that network, and discoverable by the service's name. + Therefore, in the `PMA_HOST` environment variable, you can specify the + service name, `db`, in order to connect to the database service. For more details about Compose, see the [Compose file reference](/compose/compose-file/). + +2. Run Docker Compose. + 1. Open a terminal and change directory to the directory where your + `compose.yaml` file is located. + 2. Run Docker Compose using the following command. + ```console + $ docker compose up + ``` + + You can now access phpMyAdmin at + [http://localhost:8080](http://localhost:8080) and connect to your + database using `root` as the username and `my-secret-pw` as the password. + + 3. To stop the containers, press `ctrl`+`c` in the terminal. + +Now, with Docker Compose you can start your database and app, mount volumes, +configure networking, and more, all with a single command. + +## Summary + +This guide introduced you to the essentials of using containerized databases, +specifically focusing on MySQL, to enhance flexibility, ease of setup, and +consistency across your development environments. The use-cases covered in +this guide not only streamline your development workflows but also prepare you +for more advanced database management and deployment scenarios, ensuring your +data-driven applications remain robust and scalable. + +Related information: + +- [Docker Hub database images](https://hub.docker.com/search?q=database&type=image) +- [Dockerfile reference](/reference/dockerfile/) +- [Compose file reference](/compose/compose-file/) +- [CLI reference](/reference/cli/docker/) +- [Database samples](../../samples/_index.md#databases) \ No newline at end of file diff --git a/content/guides/use-case/images/databases-1.webp b/content/guides/use-case/images/databases-1.webp new file mode 100644 index 0000000000000000000000000000000000000000..504af50aec78b120d57c8765b2230ec8efc66caa GIT binary patch literal 14276 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 C&Hx1f literal 0 HcmV?d00001 diff --git a/content/guides/use-case/images/databases-2.webp b/content/guides/use-case/images/databases-2.webp new file mode 100644 index 0000000000000000000000000000000000000000..ec3e3bfa6ee92fa34053ce907a86d0545c808b2e GIT binary patch literal 14164 zcmX|nV~{4m&h<04ZQIzfZF|SIZQHhObH}!A?AZ2vd*6HO>tCs^>Qqwa{ebRHnFZs*=rRCctl==bwa+QaL2+Q)7MfAWv)kJ&fQz4|4@8~daD z%Xg7qFkvYTT6J_c1v-1ck9XwtBK zUXeO;*U|d_azAV=N=#URccag-k$(v}ZIN(%;$WF)XZR}w6rUG65i2E)$c%EWkanq3 zZ~|myzOxtLCn$Q0^mtI4*7H3B*7+^Vp$uB^eWTGq`d#^i@Zvc<@>MP$agoEeTPVA- zHH)c}ALi+|L=4Ss#;bTGFvclq2rlHyP0dLqa&tEf)(uHbI}ge^4p;n?^?oS{Hr zgSrWH%`zYyv!59Ex&NPJt)FGyTE^hDKtlf;;Xf$8j$Wq!IA%SXGw}7!2SPi>4q+n7#Wi9^J%()_7r!DKOaTgQrn5{|`{O8F0w|A7f%`Kf{0 zDx!7t2NaONBfg-Kzn+fdnj`#S3n47|k2OHU@Lhohpz|CB0aT{Jc&g~ZUHC?p{>K`+ zAg9|SsCT8<>Ho_thg9>K%RtVoeaI)(Pzd-Dg8Cz~gEOPQ0XjLfJH=vnoZ?Bn+^=he zUXs7ETLileYLdI4MjEf8Jmc!928AaXHDQ$6(e`u=Ny2<>-8`^y5B?`Yy-=u9>Q;^YK?&mjMQNwd!PbnR{P{t{G4tf89Yx~H@HT#4d!}s z7V@d>WBmWuM%I{`Gm@PCc?si>A{;|Y|9euUs>L0X`F1YOlr-3Y!$lWp!6ENptXj9} z|A_f7U`=+Sf4oZfQ*FfRKIaBog#RDG@75K^C6Q3}!t1GMbJ9#tm*xbUD(}ED?oO_0 z12O(nBZ))*#axldOGWk^$i1NWKVB2uZAUKDhBUG{^CyybH8R^4)L}zSSGaua+SOFe zC_2-Wn|yk_gxY=JeDx+z&Wa^^g#tV{A@B$rDkbEQKqlfzPp4A0@VGHO(82VH8Yva$ zfagBE+>OgG;)p#0(q*AYnuZnhXk&;II%7uNJckDwYO?Io>lFc#6ve_tYn~4zE1Co| zP8DtWt5yFKjsFvh1`vF#UO81vvQ~uA3!M$H`a!4V#Ys?*t{t2rj|=D7fg>d{pH*hf zjRkODWKKQ;EWNPmzqde}f~*4iR;Ez@CB8Trsfb`JOz`^dlM66(Ic31J?p{^^z8sFIfU zHY>Do3>AF!@!`BXiN8M;0+lMFl_6c4QcYXezxtjtyTZ}p8Q`U;ZW#lR4u2>MgQGs} z#pj`(aW2~tX^JwAfg!3+)u1*7BoW0>ok3yeYsXY!Nt%KKdBubi787@sxyJVpe`TcI z+=R7QYSF5m>NJ5fSH~N7)xr;AAHDiI1z0YB)5(ZglRpO?x@gr``ClptQ3#y2mvw39y|odwE^raS~m>P`mDdkfu< z%$odAueZ}sm$!tB>1Gzj3GMJ`8rm{kkN4K+slAK1zfMf!U(Y6sb`OoPk#CfsB=2#3 zhmR7IF~eI&o3{JE-Nic}ZJrTr8C(doO#<}JPdNN7m% z1_+@sZgB$$5kFp>JPPx9OpTBODs{&)X#6<#zN)Ukl;;@rE7Zx*w(Ng<;6IK>^cU0P zNahRyM--MADG?)8I@9?;NJE8rLXTnLLRQr;9AyJ-tp8W2{%N0|zaLTlB`QWhBnLX@ z2i>ey*&lA(<*L>8bz?b2Y&6q136CD&K>%{-B%oB4eL{E!GLulzDy6P_9^|5dmDuK5 z0PsCVLsDC4P9^{C!A)w z1GGVrIjdZM(ikE-(&boT=w==~P}>^b+v?{xU!H~pK}zAu9q@E>A0R!L@z8*1P?`Yz z=E9r$n!LsL6x;5gs6gOV?o@^jT5WT+0Vc#}e1~`@a|qKuj#|ZCk>p7dof$X%mfvLU z&$A#LKeE@8F?(Uu=j6SvE#T?KkL5+U$MpHGf~1H<0PaaR)!d(?BYbT@Kttv0nyE+o z)Eh6_%2|IBQx@6p;NAbQK%pB(W(fy`c4xP#yu%04D&!CRKDseV*w|4R+AbThl7|w+ ztIm&%wJqN5a-z4^#|ii>`4u6DE~t!m<0Iy8hGjnk`~A=1-XEWr9JCH z4UOoV8e2W|Q`uHWXf{nDF zMPfm`-8EWdFz-b!bP4qADsisN>9Uj?B;FAAP=Bh%A53HH)AZ&Ow%-T*Dk1SVsXaIL z#Q=DB^F=)3kc~||SY%+lEF`UaaM%wz$6(~fbkHr#20f^j;0TXve$v^Nn3ZR%$2Ht` z%}&WYWBliLEn8-!0QB0=c+7QVV2_>2MK+te@xDPEPpUuD=}eXBTZ`YPFjTvIzvpYA zq~0T$N2qUy)1)EGXZ91HLY!g4L}pBWIc5X{b9Q*yhAPf!`twJN=4I&%qVFSpc%B&3 ze~|-e?lt_{(v?^KP%M>kmR;)-6I#xtpfsx0(f4dAZPY=@sf9w20cC|Gvc5^v*rpn( zOILR}(+3eq<{VsbBOO4?a@k}vAa381wDHV)|8h>!HT&qGH026e6z>K28)nP}{tZ4L zGVZLE)2I{0#II~&g!j<#Nmu9=I>5u|U}hkgn3!=UD|wdlg2L;ZC~pD~A{KA$nPJw; zs}_bRMqdsA&V(;xsRFtjTMdJTOa7)NAQfSdPg*lIzh@n`&C^_~rG`lEEnMBU$v!9A zIpr*qp@fE{bkLi;WsoABj>8s2d{JW9WqX^>{Ou?&Y<=b|^qkwbqMzM)ol@lH+_jp1 z=jdijqFM&S=D)+(i4$Vi*StQEL_Og5vH8*zhTzY!D)l{4%dcxARK<4K}n)QS!WPlEuFA?P69^GT~gVwVcd84 zG+%3qtEf;rz8pvl;%XElqG#9my9{P17t;U@T}5e9G`bX2Rw8=Tg0^T)c-iP+PQoK{ zNaamRQG|>Nzg$VI!siJ1x1f^f%pXzJGC81eu^5%B2Y3k#ijp5W(NNn(Gq9H6KEQo) zkR2Tea3XUkbM5Bl3h1kWqaipCUV(Ght!}Sz8k!n-zuF^-*m~`K&}r45dh_1M+p=i0 z(0s1(L<_qQ#`UKq6(U?I>^l-c`@zcPWFLRjz_B{Z`O@-6%qZz}M?zRxOS+7$W^sg*6&%fR$99c}%Kchu+1SzEuNX3~ zwN5^C<~PwqTCu<`&nfUG@|PR!+rdJ0pIGkfb*Ue8X?&ySX|nwzIh2ELXB8Pw$_>-e zQ_!&euo-U8;f>>Ga?{jc(0T0;p>(i`o(o=K;{(1ou${qKkOZ@5*=U%`zzu@7{fhsm z3leV9`)U2oY&1hly&!q;o+~oC=ACvWdB@xV^sAbmkVE2+8c;Ob+*_=x9i?t{m>3x zhmDs)$$8&Xqb&cd6xWrr;);%`I;_hI>>vua9P*KgP<%9K8F|u+b%Z}c2p~y79tijxv9C*x4k^4WH_CL~f0zGAvC{U5vQK9A zGT78WnCsQLzLvqsgp>;7RP-*YFAlBX&UxJ~V})J`gKS#j5TeZJRHm$fm>oi~|4K8o z08=STF$%v*BbaICenZu!>gsxuKua}(JicOIuAh4F(1e>~HnjBg6!7c${qmsa8)6on z#O@3ngrIPUOeeTP5MgQz4)07-F#-Ty^pZ5C@N^#dHXZnun3}_duvoKDF?N|{*)*>E zK5^Rctp#;UEQaM`rEZ0gBeAs=yxS3{ErX}f1|#T8YimwVrej0CfjCXy^R5Zee(?hU z16d_UF2IW~`My(YY_`g|;v%6_mDw~ea70Jw?_@=+FWv5v=dvWH18k%(F$V#l0@;$F zW8olr;mP7&Oj#1pYulVzYW-N5{ELqXyu%(Iepo~)(MD>hi~;&= z`yqQNE4qnss>h;cCbX8qQ5)`hM_17UMM8mPy9e}(K!{#{g#-qdT-6(3w=+DD`LY1~ zv?z_@hIBM`=_yyL5lY;DU?EjDGA(bTZ+h&lCI@>CsHbGZ)VN~uF|TJOKk-{=XQO10 z=%;k{i@Y|>EFzKZwV`p=0uC8q)Tx8kiE{hR_irg`Oz%t<7m`L*Rhcu34Jjg9Z#ebs z4mobHLPo>izKRoomUvelp*9qw^-nLAF2=43@m}}x zcrG7(pE}%9RC+Kqc@f21Qgqz z7XodstG_l>&@5$KYY6i(;;S;N-&PdjxpHil2ubiRh+v&39Moo0;yf-CmQuF&joV~b z{H*H?az^op7v1y2DXRovt$77K={%Yv&uIHYCt!SXc7WWX5z&$_G~!NugC)gj9dT&e zCv&v7!7=kbHG~4_B#6U}bAy|-@?ooy#!rQ4;cXYp>eiWUR6dzx=E7ONZ!cgLY^;Po z9EtK9^|{D0MN*Lt>u)%S9|QyHCgz`$!$s?F8v2e$idR=9+JEsCj;Q z^>CV~U0GQ81pPQI4ZfHh!dgK36qn!(`zYN^Ozh?@2UAwD_bQ4Zg!ni33Fhv=q1(SV zVcWX4AfLSE%zVb8FJ$Tgs)V4)>fTFbNX@`YmxMYE-BNXM(G$Yl8Or`6;08UAuf#rG zSj8|+eDw;o3@6>3yVqm1P&R%A#-%tXn^>fj?L&vbsSL2RYtXE{ZSobwZ63Y!|6LUx{ zlhkErs-M{ltCLc5G8c~5jb0PZ*3ppx!JL00@bamwo2gU&&|~8K4ycVimT^r&>gwJm zz);p1aA3MoI7<*$p^Y9t59KHrQd)A&#y4gI&T^pd0wq*ZObl(BPkh}*TAvVAE8PLx zWR5JQ#J9n%-&x+B*J8|YQf}6kHJxis{7|O^5MYqGrjS!C#Dhc#lANcoM@bA9)_wbx z#Ta^|J>EnU9jl_Chs0Et>^?vUpnq*O-|_NGmUAe?bGV%9a0i*3)I%hf8N7s5v!Ft0 zb*S69Xi=)OZ&+<2E(kNhNKu5klPv_l^rtxyo1>=)U_j=n7Yzp&7=yP|X34if|Lzn{ z!k!LEgx3WB39no_N=VE=@8|T3=XRpxDhw{>v;L6U09Q)ZR3z7G&K+idl?rx#(?ocf zf3%MNVgueMCk8L@=-=pA!_b6m51Dy2MXdD;s<_K|sp!RT;%&?Z-~asdWoC_{G2!k3 zlR{nt2BBb02sGzLwsZz=bA~0m;!&$Vg#t7OAGZlNVm!@iCumotdN3B(8BHq-0ea6FubXp zh+ClleZ){=;Tb@qYEbX=ODNK3SsGLFEoh&T(~h8lEUiuD-7j;B1PO-}>IY>6C!cCi z&A>?Ed;cC!5X*AlCXVc{xu5G;81#kC3-RM7ylZVB4y?CFUTi zaMHHvSyjLzhH?++vkT=u+Y(psbdd%NYA5LXRTY_sG z0rJ8!m1=TP!Tb76oZed(0Nr()W9RZIFEBOxlX`_a{3DHN?*1^V_iCwfNbVGW6MemJ z1beUe4#o}f?vS75Fdl_$3aRY>sWdW4mDG<^c&7Iq%OJ*_+5@a9Y}8zEDhh`^FfF;%42VFeZnG z$r*cQO;a?ThskFqE(@oT$7{;bP!*b3zc?A#!NA2S zG5J`t%le7~VuP#9^pu#@(cFTtV3PDR#==}M^LNsK5pWJ?I51$nhM;@89u;YLlk>p0 z-(bNQDV}@g4qNGc20X%O6707`BF)Uw!oE8XQM56!&$TK-#!GUaO4LzmI)kTR~}`E6`926@8XvpTiRMo=sO!(9jU-Y;;KXkS*PgdE=I z0(=xvm@_9sV37kS-`}tGhLlUyxSl?ug>FjA51xdRY(faM6c9b7vv?++J3hb`7wMb! zJvcxi!)&cL%qi($@6a3)aJ~Y@z-m4A3QIk)_%<#9_mzLWpfLc#3)Bq0P%n+Q!I};V z6NM%~!O6s33n35z6O@kJC=*`f{RJ09tC(ymKLI6u0`}+3mqY`r?!x*)%44jvMwpxu z1Sl(+TGh|LlrmhDfGf^_pqP%%hCgK|)xg~m>d6cUW|4?^2qhSl`l`3F8jjv{5M{0S zPysB`xrRfFa4jE>?F4P74&SWL#yCVS{UeH-7Ib#y*crRFyS;x)D@ub{VL(hRNy)I6 z_FL`f7K*)YBI4X3oCF5=0>4JjcO+ei(WA`4=8&d?8!7i~p1IVg(sALCcRlJGRK24` zbkJXk1ays z+RaPK@#-|8PC~Cec>__N6h*Y%5lQ{9O$k}?5mjFyn}hp(LMX2#3W(n1oYZZ`F^3CF z9#e;Q+K+g3Hr--9xAOd;=y(?wmrLEu6~j-PD=H%vNog1op%QlcouDmHPo_Qh*^QPw zK%Udh1cRF{zUyA1MM{hMsKP7LzQO9WTFC>o;QzRgY-LaC+Ot$9Qfz*3buQH0CnLx2 zgl<>rJwb7VsS^$cbVw8k@ddP+v3s#$l`+FfvfD<6pGO-_1Y0_LXN0n`|HttV2o100 zdwe0~N|z8C2f^pt{BW=oIc(e;0n^`dm?YXD7?HaxI-978UtGwp9u`N84G$ZITBCEX zE~wVoM?!9SYdQNCxFXKriTti^P)^-Gwe4lyw2JN_?i^K;&IRXzv9yIy&??vLk$tE2 z;dSN}A(!#w4wEKZv>|XXCejiJa@3eiOn46wF0OnPL@6h`%n`LscSE%|Zs2D05x-9O zn9H5amX5X8ViPGao1mD`8wj3yG)}B|kV^j-JWu!@AqH4%>{%q^fc?^((W&rA{*GKt z_*{kKLwJyLFA=X%avhUZ2|4u8V)B0eYdHs?q4e*fTAyRlKq#WUrxebY8x)n2r4$?) z_O>nozG7_e@wEuCGV2|P35W-V0E^{{@WX1Qs5Q`B!`| zHCr672PSfx5zECZFGWBRH z5Y8jI*mYzeCS|8&Y9NNj7-@Io&q+yY4~9g?(QlAeZ^CZyl|cG_P|X88HopNoNPMLr zVh;0BxJK+_N_5wovPER?!lXX&WQ2JtkoyQTT#gh~9U3EP&jet?cA9e}9wS12nKGff zul9U}EoqdSH&@myzYCnD@}Y-N=oonwnw46&AZJ!gy@ak)jA*9BY5Y>Y*H+?D# z(9BR{MDFSTXRZTu4~0kaVDZ=9LX<*8W5SctJ*&6vw+!H=!e^<67 za;swOsA~{^Cp4(*y_><0XDhxN5V-$>C_1|$yn5?zPj5BXiI)$hs3aup<0#juS_NNY z`ciet*3tNHuKWa2-Nvmm(Dc?j#tQu~D%?jI zBl>(4VXL4=vdD5_;LcKpxkWVhIRwJJo)Jk4?&9bwZ7s?pL3d;GzmHj!Eoh0Gl zr2!lDp$a5(Gz}|W39VjMQi>}e;OmAM)`-{mS>Nk+K8;?F3f58DVg|NvKbBRqdLQ}? zsrS06b-ou#w3_FmbvrL=ycM5=Lbo?Hf4#YoyoTPjp=zh(&WDUjw6!j27*Su_@Rc%20OhWSyYN5VewdNNtI3{x1>aft|M zXOms932HajFSj=1X>i-n6yhZrmA@4sqSeL=G%)p5*~byMB8pE8{c^@LoZ<-Bw+vX! zBT%5>1RUSm?8P_W5--j61!xfC{7Y`4?v$O*%jxXvp82 z--|Y7;@j8CKh6!0^(H3|PnmRcochVh8Hvd2Z@Q!Q_4qUyeQXY3S2yST!*g_O%&)uB z_Y`Wr8gG?%L8%Gj_uYAml3B^h-4B+d{1;4dJ6&V9P3n&IUFciH z1cWbFz1}llVSkmYi>Re=)ymX>GhG#Vp>PkYm9Zqc39vM))n1D&YRum*Yi4r>r$6e7 zMgIMc(Q}d))M?TH0NQviwEAY6GXgxBHNq1S|L$rZMF9PTobgAyD)>=ywi(|-H!a!1 z9+7_@TxXNb>~AR)Vyy*`)b35xKJ_!OHfEgv;^-skvVt;-B9f*oV(pi|WVQ|!UmtNa z9q$^a$navT9F*u!ddY_JWybZr(`ffM%QTO*1IdlHn(|d9Z`qpKi2|hc$Q>0n$EfWg zc9(QT&~Yb6yDQ{}V<2g#V@Vu^rx(vt24sc_nQ1b`MVS4@RNvv(0XVpSQ?E7Ua zP~M8+URC7!06fh9igcanmu#b`tzAm0vcNq&3_dGNOlo!Id}(-2iO%Kq?MxH_g}mW^ z<#V$SN>~l-*#QKR$yX4YcljCbi3IE_SP-n~6xB2^B0>2=M*fq7qBS}#RLCnl{gcj= zWDH&~xsi;a)i>VP1i2m1-0?8P^o0o{0OVZ8h;_t{TDXDF)>q3Th?&Y>@=bE!@u$B>Ouak{sLhT4rhTwe7%IW0FRiI)XMrpG%-Z+QO~*mQGgjQm3UJ zu!oYgGC>$}JxEO5HJf)uM9+BRjHuIPw>tb%ZvHflne>~NkuUQkFIAnhX+LS%ozJXd zZNfXGLRA}%nZ?msB>Vij7bz{4kX~$ehmi4K=6ytI&4$fTGrUWSmNsj0f!7X$B?UQ; z8QVn6uiSo1q4Bs@T8TZH;z_*sn;V7%r|FUZcIr4<8-sNy+YHIj=1TY=9K@0_D*u{0 z_ixtVKI|0lDN{7~gkucI_ly3+#gB+xM4QiZW!~FuJYv$`9-bZXf$s$=s$lg8F4q_?tenmfmwL!G6;5Gq4{eVNlx$9WVJzCJ z!4bA)4lC0}b5(8Rz+(jx%OWU&3x=W7u0DD-0=KaDv4#(54xRc$BBCB3;*>Vn(!Y34 zls&Aj=pKf-&lGTnizQYziMIXIo*tsd@+mUHL!eHX@`v-Cwh88so0XOS5`>tCnaJ1c zb7PYjjZK>?gY(AK>oS{;<&`Z=SE1xrLnxeA{jC)k6dv2wo;;@}?(p7j7PrIo~l%Q&?^?Q(9n#S!Qv*Dlq|@R_WfaA|F+dQquVRWpVh+ zLy}}OIHh>P^p9@={oIU$*mWVA2YWseKjt+sQL7OvvK_YDI zM|6^~C&8vKbq0WJYpbYhM__Y;jCXtSFj!Tepg^Y`iwL0U66rqsxY1~VTvzGm25Zt; z?Sb70ro%il50OH}+|r}_83OlWHOe%=r}XIc%urghsM#IAzb22F9hLHhG+rS1fYMJa}m}>j?=V;v7lGnPz(HOXXawFP|psigtoJ#nva21br){yMfS^FBr zMea=TLd?fRe7VD$w}t*5fp6fJVlwz9SfnXP=(LEscJ|MM{kfqt(d4I5NvCn(d$0G` zG`Pwx2+2HA^;b_oa7MYD<0j-#gpZ9N28|n2)FDVf0X}3va&Croz}r07#z0BGZ6vBA zC4YHFM|aXAn&o?(GJ6H=^utrPIrriB=ZjJ~i;49iaMd z$EzlfLB@T`_GnUUYE}rXO-~$y$*zsA;@!6WtDnm*kDQ@x-~QpY_iNUUVAer#^zdsY z8o1h6Z=hqK@L0HdZ7Bl}tvD(Z4=*;CYeCR*^~VN(m~=_VD~k|eCV0-N=iO-O5L5;% zZIGbMA+-6hAi{Ht~w7Lk`ON{Y5_cZ#u-|~T%VB-6fY$FHzD)-VDa|0 zGvuT0X5B3t@j_g)jbSht$e16O!EwE|6riTsDXvYOn*iI&Nh2~O!mGIl{n97zD%yDX zC+j~w{E+JWEnbsjRDjZlZgUuK{EE`}sYxcCr%IcWT>`AH>xkUVy8_QkYOc;)1N878 zaXjZ&A>m@TY_Un8MW`h+;1A(@3Cshf2+^UWk1e$e)%vSuU2H2R=6j=Stb&RJ1^4>q zDsUw^aX}fWaR-=#L{0HHgrgGJC zbVgflvq0wWIVD7DH;G^UH0L#R=tl-|66USN`UcWzO;SNO1{$NP?)rpv-8+U}?EB+M< ze`QTxx95%DpkWj5nLSp&DXgur{thVNrfNy+JPxJeirwBC2N=H3S!}jdcn3{SoX5@_ z9b%BdVljAZnbU*+L3QVM@tP+nJ(Xw`#OwcE9#=fVgF~;&a2|RdRQqu$X`V>b<`qb_ zp&BIP6qb#gO@WJTACE*FiKc_Z0jOPtetP52=Peo2>(9xDQ`JcY_DU@ZGDUi|4yImm z?iVX959q{Z$cdzC`b%1E@>Y?bMof;MH>&|_l(<6<<$959755v+yF%j4&LC`&4W27B7b&3BtL7q%fX5?D z%B4X#ondZzF+`#p6isu*B2$LC=h5k)G zO>Ek3K)u16O}4vBOt?bB2K9#kk*+?6(tiF4X?e#_5VP_2xdumWvz=_7USI|@yVvsa zktMCecJ1PCCIrr;x=u8ogICV%Zdfut|0izGIrQ8bR4kPAcxjPrNA**XK1kS_l6^wy zZVyCif-;9_8%!(&p~!UkNRY<(loCbNLcVIJ7_DUrP=$V#>BBuGu4dfC+n|d=e2^w~ zwXE!_3MZhP!ZZJsAcu(ojc)T-^arE{l@(VHn9q_4b)MS`g+cya@ZZL211*oi=qkQ((Ygb)ODpyy3Pbg|{s@J2v4C;HlRKlVQWu z8!rRGG~=4tk7L0fH8^1;_(S@kOJ_E~7VDdXP)hk~%TRd!njL+@z2&3fD*DivyLa@2 z9duAkbVl+>@3XHD(`sPfjVl2^fPEO$7rfcUsUcPfoj+r7R${|~9S3Qa%M+NgA{y6S zVPm*hKHKqCan#GAJu43=aXfpo^JfW2`6Occjd&xYTvfqvC=#`AKfvx(hau`)@qwXL zfgO}nJ$mB_k;|g^4F+YJu|f4=MmEFsMA-0Ln7;${T3s9Zqby1hCE?W8 zz52B(Kf|y#)qG8=Bu4E%Ed!+FozvDakH$eUdQsS4x@yP&>&JF=;Z?)? z%v%vqtaA|q(;zER+!1Pi(Ac>~MC#A+^nCRG9HhKgwhFZ3wv2lbTdSP`z z@h4lf89b*PAo}kWz#y@FqM06xx*S-jMRr)4ZucJ#cAC=kj#88D>3FKfT2+kL3Wz&F z9uN|s4jS#PfUZa-#wr8c&u4rWD@d0z1m{Asab*4~m=$mu zGfBtMuco?iN6a!|I+)CYE3(gl7x?9t`BNgXKu?Y`dm_sS&{S}HK!L#7{N#+o&2<^w6x=*Xvil?#XlSnhUD})6eb=hhq-T$x2b|g{b$l(5hm(ckc&gp z7BYm*!m%=(S~UkXSB7*-+aq$4rnN?J$G`-n3ntQ~Y0G zKELJ+uAGwx zkE!0u>N(sGbK!^IXIEga&_9uG$5HkefcewGuN8mtESxOQ*Iy}t8JyF2Tl7CMV%F~n z53~VFajOc5-t+dXj9E@KuK;9jovng$a=nPvq-J0qiRD{)MJxcO{Jow<)(#yf=iz(a zZ8eUh7>uL?bo^iT9#3{9aeNA9Km0?KeDlW6 z`X#}b8@9N(UL-ch7ah;8KJ@N!+Povhry2?@AAx+2$&$4)=wrglldisM0IyV?B0TI{ zi$z%X0EcJgv7G6aX_ppPRs>kW7p?gWUiBpZOq0urIu!N%`L}&vupf09A4eb&hx)Qv z6HE{7dCh>kl7T$Tptp_6is-^N3V2QkZPXc7IIvqccEL1sh~F@0(fo7-+x08v4a4^B zt{H~$Fwl?VHikR?O-v7QI*W=QD>3#l+f{6hKxll6U~e%n93SQ_FNRcBeQgE)&#uo? zX`onQ9_jk(jC}!lH}D^3cOjmrv(ImoFKm48 ztrxQqOk9g4I5{{%_TUGf{9L&wG)$H!B3>6wcI23&GG1a2p9SA2KwzS$KSg%QFV=Iy z=g))W)AYYFXk81TlUzRUqH8P!I}%2-%r|^f?l1ZGa63k-MrECFi}Y?M%dAAC5C>Q3 zUUMgA-zI+Olh5C>oIpmYjkGIu-Z-TV`#j7B1K@CgE8*9+qf;gyj;a$9-aF{%7#JMNd9ActIL}QvQ7QFqe$)P@rlV&DNA)pGnkUvk#Z!6z{^1*Vg!eXjPa3_hoB*T?jMA=Zl z1X<{D#e$i>wJKnOy<=DCQ^9a^ZH;imBZ$?sFs$O;M?@?`8SQTe;C94z_bw$?;S1(@!k(BZ zjN6i*eEr))eKfK1P`o|aCNrH6A62-vUlWqI2y~-kg}c}+B4ek3`)sRfNEq484|SM$ z)K<%T!il+|;yro$3BM0GSX6c(uy|gwJMN|!Wr=|vqe`a$bXcAx1c&fh zz;0ar$_7T2?Oqp%X}B}BFcM+npEH0TO^6vK6-W(I z<)8iw_}PWMS+LervTzMFDy~~kI)dI!7RgxoLZUc?KJ#?*doOvpn|cbAvOB`utN=lP z;%D&scM%rl@?;OxqfFj}csGvH*rTMfXZ;aE^fuBd`ieKf+4(8PRoH$3$dy@sy_`~? zf%CQhlEh$CX5?fzjJC?(ju#^#S8x81#EIw$AY-_MI7(-Gno8dnG_a3b&l zX%>RL&9mSHrxCNad0ZsDH@)>t#=Up&6Mpp_oC@woJh7)DcC{Ae4=5rGZkx}H@gBLc zzoDD(kTMLdbX1}Xd-h!M{b~rOT9) zbMHdCA%41dmIyvZ&sxI5MyKLL+GX9=#=FFLWv7gMFcrs$Gy;eqK zDocrrt8xPX8e+nV>WZ9%lK-v~h=Fo}sPTc@f%y|f^JGeki;9XHp%Lqmp{(paZLk<+ z)Njh(ojFKUI$s|lMk$Njta9e=@yq+TZaE$WPLaMpo;9{kMdQB=j1{g09=@V})O^`~ zT=|iIM&6cxEx$p0q#y0}GsJ#-e`SBTU+2H%OZnr!rQi8)^f~r8GUcBW4Eygrk-Sl? z8_fAT|B!s3T)n*cgMY*Li(G)cnk3ij>(RrhuJ8vp3u zDInc9>c9WP^j-d3V{>$e{k|=>`#(1u5-Sx*l$KUb>860ykeRkc7jE*?wKFbZl>%fWCO{j427=d75N;KHn8+i4;_@#qs$*y4V4H7>?DI6AKU(XrDC(|5J6(y=4&s^9E6~s zMO@au>C5dx^~?>ghjSkyam1pXkQSanJJF`=Kys(%G6@@wBs%IVo4%%z9>{Ea4E!>w zoKi|9{Xd&y(UQO+^|ZfV)dzIoV`n^_X{yF737wko2XBIGk>zdae}~rnPZ2udkt2-! z4Nzj?aS0Ez+r9=j$Pe&VH(q*fy?6e16H$fCxfh=^n;^`Lm9QvG$gDT96`_B|yEyP4 zDS&^Wuyu`A-5j#-M`FOVx{kuud7w9`uSr!{fFyDC3P%yV_6Ip#jY33bqPkMS9A%2p z&e={E&Gc>>)xguG`8OU;l%sUYV4OrBd`ZV-G8GhYU_l5o+?f zm`>sU12r4O_UY`ROgT%W^^8E@{Io_IZu%LzFqT>`f_8C=z(~FJ75OSS5(*%{EM1U<><{c?zBytER7a+!bSYb-A>}=Hx z$T`3DRm>phQQ2E-w&QElIUsPUB~;c}>Fc3vRl1im8U9mJpZ_6H0cZwPu9RL`a1m1D zwbK!OBXNf@k$b0CLfOqz?tg*|NY%52A;h5|0~0P568aC?tzIxn_yjpLSZ2N*{Z=kNhC^_-kQJcKgoqZcx9h|%&orq zzf5|n$UTcfC}w#NhKgj+OkX@-Ed2k`0XFicgqdMB0Cp5*`#Qwj1##&{DHDg9IV$9~ zfooeV7tS{+I35gJsmF!MV>FlJ!IbX66g zDu>fBXSmJ(xpyPiPxM|XYll}W z#uQl$aqj+Ple==-go%d$WW>0GMc9daf|v9|`1!|uh)Ul$IW12Fe`wV4jN!BQ_ z^7HPiaMAb>!KZa7@eimUc>hfi4i3wwJabgt(7Vf{bc2;A5=ur-XdC2Xyn(yT|1Mb# z_?uzS%hPF~Ke7s#5b@qJvfi0UuS`eQ4BH-qZ0Nv1{WyVC7Mm0HSyI9HNarFjhaEe|ychXA@V!&1__Ctd- z<~7IK1qi?I;g*0DkdEhJ*%{%6<5D9 z0D$kDlY|S2Y_=WWyTFz6jSy4QA&5m`Dd_%B8EHCsu4c#@gAsOZw+ldeTdw-X;HUUx z&L}xuHqjMoKv8u5i!9#_Op1!%TIkmo(0L*bob+xtsR}p2f@Y7g)U@zw`ZpBE+m>V* z!hlzbG4={%@twbcPz;G7}Wg>~4u>qL_nepfw`|LuMMT*~@Wo_ZDmdib+y zx*bG!z&-+g-`JQ8!S|AC@ULowW3A|}yM4`~0`TU4gzcXN6b+vHBVfe@&U#aO@4FQa z2R~;%n%$s0u_3RC@4}LY<4GUk+I(~%A?MU+(EXR8Pwr@J1(egMO;s;1NJm@*0KWO7 zfuGUlHv)irpuA$LAals1VZ?#zkXtC}GU|EtGx0ML)s_FY?Y)&2O5*%%KrWoY@LNu? z8{@C;OSpE;Fq<+?{DNt~zq|J%@KQ`&Loe0^op0K~Mj=-cq2CWtPh!|xArAdv6)k-_ z!7Wc1U*%j7W?oC5-6f3p{U)z1iJ8KY(RzPbqcR!kKZ6bGlHWaYem+kJ^#$rAGEzsv zlHSW!_0~~K$GA=HYWAs6e3rt~wU%s>$#N7Q(zqTZnRP_|?CA;b*7>;L-NG8Arl{rWv6};HTXp`XCm$1_$+UW`xQO{e(iBa4Z z4!@r7*y)x73`g;a9y1WBS50cjLA7e_@{ti;m)tSMp76R5*N1lb+V{y5{K97pspAG9 z)slkLLcAIbq6#J!V8-p1tS5!*B7#V8GERLum$CdQTXH|j z=`nN+V!85Nov$mvnEQ2DhlM_vG_d`k0G-ch_N&wj#WIq8}Jn4`A>}Z`N~({xn?lL`;JJSuV#&ipbNf9bsAj zaA2i@%O-?oE~{I9b zOxtj2g(SoVpM&t9+^2qcmbU3ZW7&X#8K?rjJ=^TGM!R<3o&}*@++=lBI-W4=SlLa6P>Wp?K`+*_U5*-`RXi{yELjgsN794*GN?jwAc{>lp+>w zJ6(c)!&EYJ|Ix`Tb@;=to`IB{*~W)C$mG;ZqPP|*BgGiLG;Xdg9zNbkc;idhNf?$u zp^yX$#81mfYeqq~U@8+Y6@YSsHR4CiUY+A)1KSywEKyNH>a;U!EBo2g;H$t%1n?UWTY$_sBX_)#740RL)$N?^rMDl7ub@?Xj`e|l^2=dPs6R3+}p-83u^Ame97;>fUr%Fp<_#L%4f;Frpo>%OIt3upXfED zo16W#rDIIRm(z4CtVC^IA*CRxQ>E40DN|C2?>RAUPaxmKD8}hW%EV!oVYsYMx^l3^>Yh)_i058E4_3!T{ z_fs7!syy*sJ5m-sJ4mJ>idhpo(6HKJW>(CHwEU1&+6CS>ij(~|=$s+%8`f+YQ3zS! zg1F&^5qcgclLD75<3=N%Iy0mS@kCW`N8QoC^24j&_wq4tfgjZLThl=(T0Op`UJ}q~ zDUj#HB~UlSpudq#fvh?a52i{xJZHG_j-Jxvw{Gauv+haY^h;t1)1)%T2EB9kv#GM{ zJZnodj@icypVckNRm{OO$<8y@GIqHG4AlsgDlBm$EMm5gwWJP)ub#m=YI*6jSx#!w zg0e-HJq{Cleix#=VhxhhpO2l45yAT#BE7SC?gMz8_KXf%<$nx}DNiI?hW4nF+5Pvr zk4@VtZ+Z0s&2U<&)IX{wJ1m&5rQa;_l)bimVLI9+ z%`#|6#HyD7mG=R~;KXyn6J_U*XJ{rc|B;ANMChBb8*@fvBM>@*1!o|02Etc3#axdU z1Tv=zr4Qw)7UO{ApFGjhOj{J0K_OWRpP8+68+3+v5gc6mkeh|0cYdQ=ccd$mXIa}^ zHGuD$B&E8q0K0LyrV2OKQ8uK@C6Im4BV0`vZ4hVRxY)ZQCK$z(ktx8eKRF7*$$3&c zu`5&`VIn|8dIMc3;&!M9%Pk+aOGoOf{L-*J3uL=1(nZ-pR*#s8JM1)u8Sz`81#huX zKBKi!z1}EFf7{B#o#YdRWn!dTf0QrX_C4FD^dhgl;XxPzp|*bgWc_l(NHaQpyEqqX z?;oV&;s(Zi@}Xgwqr?4Z>8949tpEsQ`d4N~$*Pc6{PBh7-qm(_yIvbk1xvxRNM-+O zD}^#(8VB=#J&`+l3V*B~{lf5;g=c^&^5+4|X(Sqw4Z2yL7Js_`9`-|k9o?_iQjCXf z?uV6#QS4~=1*-6*NI5{V-G?qXys7+a8tMM)lK;+%QpP$3KXDFHVG~nHob1o=&Mw(p z3KLN)2LscK+11{r;!}>HP5Ds4iYT8;vtv7@MLiL;JAI<{fJWt3PQs()OZK1!i-#4? z4%(2+ht0O55bhR1+uifJbNveTuWH8v*#XT)k?SJJ(27@AMuLE)%tprmd@A)%_~cp- z`~rysB(GZ+9MJ|-d3b050PKgxC{zTJ$MK4%^JO0sDgoMHpyAGt&QJ%oW+E7B%_2kX zRZt*ElmH^V0d21r*$w8kM3>la;#Qake-pE$_4&1w!~>iPz4p+{H1JAHfe|)cQ7%P0#7G!jV>!F4(T@r!Ymi?*^DR#9YiT9F za0q&cN8aT#BmHzO@#SDS%yG$ItfV%NyLpM0il=p_46WTQo2iV0Lt&|I@BNILOlBj! zSJBFjWg)hVtL)$|jr{*^4F3|6nmv^?+Z_>0AK2gYI{emAtS{|w0d>&Y| zj2CZ?(QIn7lZTAhu#I+bCeM0SFjkKi&nl%;w-*qgn*BE0&BPR4Z^Ry$aRD{l94xxm zKgq^12^+e=9W-4KhCD83NYqVEPm662Fik`2;&suY>M-{A7-xj9a?2MIPR%M!|H9Yp z-9m`G0|rL3y)PgK>jBH(fCXdGa!#@=d!ETm7C3NgNw_o^m7(Rv>rl-<>)}}|e0-#* zk`YIn9^)G8t@I%mW2LXG1`8r=UY-H}eIZ&|lk$B*&8d`=p?=~S;(i>frMuuYUsaN! zY`(%lzWei=oCLFlnxp(D#TOYVCsvMLy6LM{cs7QI5#SZrp*!$HZSS=$^;G^VT>2?O zg;#TSbUq5AoFgqOvSnMv1%_GEn80g62&z%f6`)wTjFNO?!+2 zPV-5^j9roFnbte{CB!vR_7j6N_tUT5__kWy{kHxp-o@{~`&|be51#5#8?P7&6qpdW z{eHRV2@5EMO)Jl{*$u;0zJn7&D3DJHNPCCa;xHoB!jS^kl2NJ(g(Uakyjc@Pi%ZY?eGkP@4N zwm(btF$Y=EI$77#FNp#l!(M-)jyzWjQ_*w4>}HeX%3zxMi;zzJ8^oZa`LY-@op;%a z?n;_1nfqTqure^mVy0Gi9_9x-t_Us?T_Z`CLik9NEj?ZUtjR5%G?QU1fv}AfDq{mg zU(j|D^9gA(o(zt`D;$6gBKne_srC1u~%Kg0o!Np=&vv5`r2;Y`@NQDuG$NNo(0xd&F1iLCwyTnS)U*RFS{q z0tVjg9(SB7jXcIK!p!tFKdSKpJ=dZjCX=+CmG`yPcRmD_xmV68FQ|?d%@=r6sEP}V zroRw*_M&`RCzGX+)|1)ZCpGT@9&B+SEWGKPm{Y;3$@y@9H6h4D5Dm--FDG3gH{lB- zoTKD0oDt`9?*QNtb2g|uJvU>j7WDa%u6x_CWHqG`UaI4d;E8vd3ZR|_GO1}sOV{yz zvFz>Fob0yv75=R7Au+7i;vzmw@i}1pR~!tXWa*XqL0i%OoqiK1MO;B>E;Cggd3UAn zeW@nVNJUf>wvGcg8Bf$V8 z7JWA1Uo*gvK$2ILZXf_ezTx6=z1kB&L*nz96@c=u6+Qp$C}wbYncZ&hyublMto0~T zsL|wPBL9P8(DNOxL=Ye$u{omm$y{tf%Nl;fbzd@(9qaL_|2+uRpo9A^c<@qPKX_Lh zd+B0*-=t2g|8SCF98O$VPBD;#+b7Uzbm0ij&*Sv?>KD~>=I);sN1(>YZcjCvoA&4h z2Z~zkZQ8lfzSZGNA|C0Fhw`z}eXD0(uNC^+~p$!zWfun1>G+;>$ zFHu#@O1j_d2imoBgm4uZ9O!Lr&owx&Fz3;p1U>|rZoo-@NG!*7{gcn?V^>en>fks) zKoeOLoQ|-xdhx0(MTOdn+_AJ)jN%l2Lc3?W@>%Obzqv9YZ=P6`H79M=SDI#}oR2XT z)rW?}RJTz#zpNTEDP*ovf8TsK+G~aZi}VX{B7@>g59n+np{J)Tq$Z{_!%+r)clzCpsN6_lhjmymO6XFx@oztV}R61=15l zMz2aIXY3}77iC5mQ$oU@jpuu0zQsW->I%B#er{d}^U5Vc!&j&YKqr`+k{fw*C%V&( zn7ey-Gw0Av$jEin1&x&jG8$9)=KT023+{K2BjIoE>s#7SpH~+sA3-OsDjevtbN2%_B`ulu1Wu=PwkK1<3YKXR7KfT2HhEJ}|Zsmq2 zhUlDkC&)NZ1(6FWh6VTx_E}loqUpP{ky%dFY11Vy5ztEE`!Vg8Q~h@Kq&!n5#*G;E zWMU9qW%?QI%n<8W)HUZ(0bRW-4ss^N01HtVw{Wl(sq>EMgkgb)kPL68^fWdoI2J4@ z&4l1#!C#4*=6?KijG5Br$t zVY|ul0as{+kukL`Edy~!+23=-Gl_9-sH;85K8HLU=!rIN?{s876HOI22?`#r&q*!b z+@?PI1Jp7;Lw#sBQy|$}!qyof*_o7_%*V>B40jy?D}IQmca8=I#;5m5tNbdF9)&oW zJ!?N5gc9ZW6c&c-s|M)lW3-!});oP4`B(RGOg)e=Agz}uz*rZ<>i0oTY|QG+V0Xy<(*G!8lx(=p+!jxjo3Z7tjsmo;YFR-ZP;=ZDk z12K&#Au~C~mrwk1;q5R1QV7LW>>!~^2UETVp>?Tvz+J`~k;dWiiEuA;+^*@EipFBu z9-mJZNmg9($F0}5@lUFv;)sDXbeRO2tcx`jGlH22Wce=YZ{z?-d zh{EC^@RXzGO38Fzf?5*=gg4#dO!FVM+NB`+_MXhC96Qzv$ow+yA}siaqkSO_KvF&? zA9i{xVs#cHt`!vtmJ5cEVh81E$Uv*in#oqy#})fE2)h|i5U|_#_5mVWCe+9mFXKY} zzsAB%Vl-_v%;5#$wyjYDmPC~Al9iB>p_VS2cg8WgWl_%uGjWc(U{DK`g!QXGvsaVj z%51s9PY6X90M(_34|~Pc=|3D zPh+c()>f(6xog2GtemKfeAspUgUjeyFeHtu6r~B)ILLYZrAA&P@3G(70(?r^5Xpr2 z4baA^!87PVV?t7acV1M{ShJlBnEe1n$jA30{q+I)^ciitETHqu{+H;VGIFm-qUKicaJtA?|yX2&i%(x90o@zSD|La%*^TZxpUkqXm9O%R@+% z^z5D`u!JtW#QDIBLb9hPURn$PO<{nvVYRGsaBV~y!bXiety1WBA0AD(#HS7$ zvgdZtZP~iOp+fym#J%?t3&zXeI*-rk*-?dg3cwrX*utPxrw#stYhxJ~wS!l1g-FzR zt@yFM(6ftP$1yN6c4(x_$CYge7Ct5(bAl>saVP>Tt{vx$UW5)~@fyt~^eq7rb&Gk^ zlnd(6VqZE3tV}1HG#Qfkgc{pDjMz1QF~RjEkC_(KS%%DIzh%C|JE+9QYtsw7$P-FW zP$L0R!>v}o5h63wX)XUq&#*(V_tv&bKURg(%u>_;6)Q?igUj7(Q-fPJ7zZI)+nO1u z`Gd9DHt{!nJP(4h27QO4eL3GO?8`7*#SFQi7Su0k#+?DOA#{;XRv@{=IgmMeIswpv zAywl@YOfe#6UkOMbI|NHn{2cc=UxD^P|wW;K29r-<)5JfueZ7Sfe!;r9Uhw}*7KIl zl2G02RovJ(YY(6T+@zi~3S7>zWo8YFC`Wg_s}q4xJ1P&|A>p=R{T3C?9qq4_v**9?e#P$H8}>S8Gt0Q&;`o z8feUOe=Vxjv*@Kalz<&vM+b%eVwxm1pQWUgzYq_eB1Ba8S#mM;@HZO;@ZW-zhxkR54iiJV1Y!RfEOwn-Cs)(%VjIF(E z?;`TXF)HpJu<+%t4`AqUK5RT)5k4eJg7BE{JJ8q^KD_dOS+w@Lz1CN5c=Kvz(~FDy zEKY1Jp4B>vv4UQ6cQmYoFJg>*Rm`FW8P_Y(@lE)k?A_7KW}cBahu#6+hxGz?_Q(ek zBBUqiE;AnFPQpdw&&XI~wAdsE_paG>RROxy=e4XlO8bUkz*A;0eDIfM$^musSBDUI zf`n}zBk$+y9PP{oU(7`y3IydSgCtV3lLeMxhrXHp?c>})Y}I$kEq|(^qI7@UU;s~M z#8I-}?=_>n9W-3{?N+ZQ1ofNtiiK@(yM1?t8$@mZ4%kdTP3j6;h4!00bhRwRD4Egx zhHmfkHbMKVZrqaCI2KJ8%{{nwa@>BWSKh%tXmu3AsBsGW&K+lY<8#$Tj!(uFTt)pj zhYWcK`+|ggqz>EVhS?f>3{5FAgLi*d2}brLK4>5^oD`k$-N0a>U3xX4eNfH;S*;a65rU`mvlUE{zphEk)30m1@zx*nUFjO$an% zH|XZ)LK%%b&Sy?UaMKOSG;AZ((B%WD;o zIbmfbNE2vmwz8@{S(vW`xLF749P^FWFZK=l1Fy#3$8$M+K*kXBkwb|79r$j0Z;tyt zK}RQ`I1!idTBMi((+uMhzWMzf9~_f}Nm-yOY_IjnzMeNM;iYuWU|86A4WyTMi0@1i9}5O{AAl48_On z-(R%9onGGqFL}C`exO7&1_K)(Zhv^+?|5A5O%CWv4-xVvWecEu$7wLloc=P}ygpXZ z&~hB?MDwYP5vg}qLVIxE_%|UI25v+*Uo#0sM@h6QK%_2!ZOi*X`Qa<^b~W8mHV#}g zzS$Vr4jCT;#_mnz%(4XB7=>3&u!$0DJ0Kcd1ntNm&msSu^lA=##NUX}p2y9Byk1Rm zc`%6dY=F@FmoKLp`4_o9T(4h66j&PE3lt8Q6n^#7rDZd4CBQ2L;4+#ILezglSfwp+ zppeFoDBCqW@0bOwTtYl;;VJ#et;KsD;rx2CWY;8Bmu>>#Mek<)E1NZly%@-dJ_0OE zP(?1bRAK_bzvH0xZac#FO`Arb(uuS;n9U(HG^)nzN*{umCUDGOF3ZrHs1-9v7oYV!0iEmu33kl_;8{U%_M5moXyyvA-GM1J4TSkk;=7%Uf?S<CB%}lwK!I+(-b^k@V|VO&hc04c&H@7c^173LYVe$sF+KJZ0QI#N zBD*Vqae5L2cs6>WQI@iJH&ySK0l4%rAC9p;S^wEzPqO+)FV*1|q@}{-kw@?%H!e9+ z1ctSHpr0lD^^^@Xn_vpasvBi@6eb{4Y=FaTGCNC<*@;?<0;HIG03-jt43sDntd-Ud zYh46R3q7W>%Q2H86N609hDW=k6DXyctD}D`_u`zzv#84Bcaf0Y>$7#?pLXL~pT^;q z(;`&3tPRNM)*xuo!GM1+Yu{;4pf5bVfA}%nub&Y`mB+0uQfH*3pQmtN&)^M5M40k{ zF2+NqPZhMUL*52tux!&V~=cuHM;0vL*;r@T}6j@c4z!DKO=rS+~D?)Q_5C0={` z;9Nee2iD4hHB&4lR6IE_g1NBVdiubkGBAp%zm+K4!SElfgI&Jj zQG69sVeXcv(db8g7<@4${flWv&*qQ!Ginpp7xhedDbZ-(&dD=>k#h~LCi>VCR`u9I zLqx_Nc~FFGhOzaAFC>rB`$>FbYw6S{(yLw6)*7U;nIEbpp-YR0O*>`f8g7}5dU6cy zzICp~;gQQwg$D`mY;`$FLj=W5!oJ2RYifmSI*eKpM%#Hy8i5E2R~gnvlX)!=ZCy*| zB9rcID?o={Z0*Kn8)2{ubL<~=mC3%)vN~N6YcbiaRt`sUPg8L58`=i2Q?Ps8le}7hCb;x| zwgg>Og!TXvd%I;WsIDo>^seSsgQwqiHrbAfp3X+#k9nv(*&N4L#&GI5WxNX+h!$77 zt-G0zI+ZJYOkq&5C}|(h-Q<^tvvW);>Zn8u8A-mf<%|4lPq6mV8L|BP`$s8TjcT72 z3oqGZ0=Ek%8{uW-OyMu?o{g8r)2jr7?0Z@t0(-u!n8+=jYM#B?4}H`%eCoD8NW&#M+W`kfjGmpy2H5c zO?CFn-LLMkTHro*40hS!>QPj?4|`lR_(Ivr%jpm<>%VQBrlRWF?bbKV2fIfw#xbL! z#}}oNE=;kEWw{vuq_bvr;dSg7-_R67!r{CtIN1}_G0Ul0$dP3@u~EluJtJ5WL(6f% zi`AhWp&Y~!TiN1UB(J&v45C|{4=s8tZRIu)IC50SFT<(3vTT1mL_bb7Bh{+m-9>U{ zUF=N|+F~D?JV%dafe9s^!mfLZsgxH#{aKD|5o5$y5%tytw0wf##tXO!3`HJY689}< zyP66X_k|JgcCJg20LH38)_pzF-y#{~Ez5WkALGuA1Zz@D*2=7-=kZHDJ2EX9Cib$; zLH5fGtZqWtB|{%K)niT$Z+eTTj}z%OYrUkYdP=Ddtxnq=+K^Yj^II=sPi;dc&8q#N zid02qe$Y!{Gw0qJjd=xb^maHuqbhbFy zn`1MB*g-pSTYN>RS29cHj?ecT^_eg&pvA)jh?i5P0!Xm|AA7uXRXO)P8z_hn34*WqFql}D%(9KyyxirM*=bF&6_;2$CC=eWNTxsf*lZDv$Fyu9EOCfL83*kXV zkZW$B0u^Yl_6n4@Y4UAYsarhk)kZ6o75RB_QfXh8PlDa@%b-mwKI(xb&T7BpM2OR` z&7gGT2jO%5UbRhVMMf;2X*It60JXaAyr6!Aahu%Fcl7P;9%p5$ZoSi==fSkrEYQ?> zL^l(S^Pzh$<_vX*m%jRQ+5nd(n%A6_;10M+{+}7@ZA0!* zcab*VGV>X>k;jM_Nm5KOzH52Zw5pR2T+D?y1oEI2SudH#P6!r|)2k%bxQf2wRoYYl%QDpR&zQgiSJDA?Kf7zsv?GdIFpxc+#8r^}hip+D52lWyQ)z-CiTqx zpBuWrh$Q_{Ejd59{#@;bkO|&5d9W4y^jN~x>8}#KJQ@5u~)z}_=2z1!H%}IEun%0C~7vD@fFtH zJNb99gr^n5AR{+IZ|_l+zjSo+t3MKXmm9{N;W16)(u;Y zMQDD_3dn>u@~fE5kcD2_nMJMrj2{0-O=8SiX^k#?nEE z^@kY2_~KMUB%FkQ{3_Kf3V5n|9$2nGRikzu0`MF|3!x65MYRGvvhL5h$ zLGMn2)^a|XN?S^gX;Fq1L4H!X`pjz7m`d zHJS@MjE(qKS3_)lcE7n*Uy2--l&EWD+NFegY}Acyu5*1qNLh^$aWZ(fg)u2=6%ZgD zXN4dsE~~K{E82u>amiuw%g6>{A*zMD#KJ8qR+~(;SlYLK+IU zaZj~SEjQnS6|a@X|M++6>P?hGSRX>qR@M6wKOPQ?=X0Qw-8Apgcti#YGba$5>||qg zpUQj4r#bPv8NdX14&Q#kWK2K;nRajSFQ)Wr^{^XEH8#2v%jI`D$8V-dW?v zZJw^oSOL=Hxk&vmI!@~J8+79D2X77AX@A{%OL%RGp5LMZ({;El(b~~UHfpfHn=ir> zJ*!|48PLnC?e-{>DQ2Y6JqySX^|s)nDuj35h zy>50ElM0#MWGosAe%(@tJV}kEKnam#V~AGR>U}{o_E=kOQ=l=o!&JgYT@ytn(oN^8 zaKdfS$3IS8(v=x1%pt-F8ICh@*ai;3rF!F^pvswH+ygP|4lJBPK}zDo@zF4cte=xU z>~Y2%xvnqYPuH^kWF0F`oeTB=Syj@87$cxfpIju0ZHd23V<|Y^7-O`(ms@=ecqH`7 z&yZ|C+z8%#AWeuV=tJ)SDw%2|jo6#q%p@JnobGy}5Ku)Va38;+rvpeYlY&>XS|U6q zRJ?Nk{q<|PAZ$=$QUbXfMh}7XpXLu(smpiPQ^U4-*CoYZ8gCYp-SGT-`^>u4vW`vw zkhwKYtpeND6a%j(9j>p|5?eaMtP=S($?|G=VS$d8#*^s)0L$>codf`&cr$&e?qeQN z>XmgOR$7X$sGo(8lGA!0fUFMjl2#aWUHe`*x=~dHo^orbe}bL*dm2T^E}d5Ln*Z8S zJ~(ZGcpiAWv$-Y%Zr$XT%-l=KSW&X(=2XXW8@t)^tsP+0gpC=uT@OY-l$q4pqX{qh z8v}mIm)%XQg?+~muuL3R^T*1l`Q#$EOhyx1*q#gEd{)>iQHu1+EssqcN{Q7^-w30( zdjztZv%%tmV<@fMOn=4ld+D(JO>t5b?@p&@oP)iO{G@U`1A1d{aR2)EsoqgyMmWON z>5zNAuBBFU*23$`?NbEFP|IDizT|Ybwdo^Q;ssd)6@5UuzV62xnzo23x{}ztlzgjM z_OaMh!RPL|?0^lK&Ly9VnsH&v-?h7z_Q-u7(pr#--s;vR(Lw&~hvk-r`rhs8@3d1tWNvR|8jP1_yVt<)04nzFo% z;eDvmbf692(9M%zc7$)zh9nMzE2*HW)gDO7b?6`k_DDT8R|Cg~he5-m1X~-My^K6h zLq{ct{ITl_o(iuW`$q5&cQs5(W30WgJ@0r zvAkvr&75<`?Dn(7=D^ouvET#$afaG|yDw?*wwT#hDpQfn};k(w` z+Qq`FGMj8O2L`8hQdi2euC|_A(RSu>om8q6PQH~|2l*2zlIQ=u2mOT&XReY3chBk7 zlKUk)$~z^Q*_@}=En)+FI|hH*k(GG?tsqF3>ZdCh>a=(IKG~a3RL2prj71PtK`|Hs ztUlIQkWOsG_#&0i59r)nT8l}_sAL4W@&3UW+;Hm&sRgWowAbl;wa|ybwsEjJ0Y{|e zGZ0)o>pa`!|NbFz&vK#%8VpjPA-eF-_bYH-W9PG1tt~WpJ$Z)F7-Xt2$||l@F%`i> zs$|BR_l`wPe#8(GLB@ggs5dg);rYu>g~08TXhN{_U=-fb?wuXpk@)8{N(4B=SRscW J_un+*{{b&cC`bSR literal 0 HcmV?d00001 diff --git a/data/toc.yaml b/data/toc.yaml index e0fa4a51e8..af421cd1ac 100644 --- a/data/toc.yaml +++ b/data/toc.yaml @@ -191,7 +191,7 @@ Guides: section: - path: /guides/use-case/ title: Overview - - sectiontitle: Generative AI + - sectiontitle: Machine learning & AI section: - sectiontitle: PDF analysis and chat section: @@ -203,26 +203,28 @@ Guides: title: Develop your app - path: /guides/use-case/genai-video-bot/ title: Video transcription and chat - - sectiontitle: Natural language processing - section: - - path: /guides/use-case/nlp/ - title: Overview - - path: /guides/use-case/nlp/language-translation/ - title: Language translation - - path: /guides/use-case/nlp/named-entity-recognition/ - title: Named entity recognition - - path: /guides/use-case/nlp/sentiment-analysis/ - title: Sentiment analysis - - path: /guides/use-case/nlp/text-classification/ - title: Text classification - - path: /guides/use-case/nlp/text-summarization/ - title: Text summarization - - path: /guides/use-case/tensorflowjs/ - title: Face detection with TensorFlow.js + - path: /guides/use-case/tensorflowjs/ + title: Face detection with TensorFlow.js + - sectiontitle: Natural language processing + section: + - path: /guides/use-case/nlp/ + title: Overview + - path: /guides/use-case/nlp/language-translation/ + title: Language translation + - path: /guides/use-case/nlp/named-entity-recognition/ + title: Named entity recognition + - path: /guides/use-case/nlp/sentiment-analysis/ + title: Sentiment analysis + - path: /guides/use-case/nlp/text-classification/ + title: Text classification + - path: /guides/use-case/nlp/text-summarization/ + title: Text summarization - path: /guides/use-case/jupyter/ title: Data science with JupyterLab - path: /scout/guides/vex/ title: Suppress CVEs with VEX + - path: /guides/use-case/databases/ + title: Use containerized databases - sectiontitle: Develop with Docker