# Almacenar datos de configuración usando Docker Configs


## Acerca de las configuraciones (configs)

Las configuraciones (configs) de servicios de Docker Swarm te permiten almacenar información no confidencial, como archivos de configuración, fuera de la imagen del servicio o de los contenedores en ejecución. Esto te permite mantener tus imágenes lo más genéricas posible, sin necesidad de montar archivos de configuración en los contenedores ni de usar variables de entorno.

Las configuraciones funcionan de manera similar a los [secretos](/engine/swarm/configs/secrets/), con la diferencia de que no se cifran en reposo y se montan directamente en el sistema de archivos del contenedor sin utilizar discos RAM. Las configuraciones se pueden añadir o eliminar de un servicio en cualquier momento, y los servicios pueden compartir una configuración. Incluso puedes usar configuraciones junto con variables de entorno o etiquetas para obtener la máxima flexibilidad. Los valores de configuración pueden ser cadenas genéricas o contenido binario (de hasta 500 KB de tamaño).

> [!NOTE]
> 
> Las configuraciones de Docker solo están disponibles para servicios de swarm, no para contenedores independientes. Para usar esta característica, considera adaptar tu contenedor para que se ejecute como un servicio con una escala de 1.

Las configuraciones son compatibles tanto con servicios de Linux como de Windows.

### Soporte en Windows

Docker incluye soporte para configuraciones en contenedores de Windows, pero existen diferencias en las implementaciones que se detallan en los ejemplos a continuación. Ten en cuenta las siguientes diferencias importantes:

- Los archivos de configuración con destinos personalizados no se montan directamente en contenedores de Windows, ya que Windows no admite montajes de archivos individuales que no sean directorios. En su lugar, todas las configuraciones de un contenedor se montan en `C:\ProgramData\Docker\internal\configs` (un detalle de implementación en el que las aplicaciones no deberían confiar) dentro del contenedor. Se utilizan enlaces simbólicos para apuntar desde allí al destino deseado de la configuración dentro del contenedor. El destino predeterminado es `C:\ProgramData\Docker\configs`.

- Al crear un servicio que utiliza contenedores de Windows, no se admiten las opciones para especificar UID, GID y modo para las configuraciones. Las configuraciones solo son accesibles por administradores y usuarios con acceso `system` dentro del contenedor.

- En Windows, crea o actualiza un servicio utilizando `--credential-spec` con el formato `config://<config-name>`. Esto pasa el archivo de credenciales de gMSA directamente a los nodos antes de que comience el contenedor. No se escriben credenciales de gMSA en el disco de los nodos trabajadores. Para obtener más información, consulta [Desplegar servicios en un swarm](/engine/swarm/configs/services/#gmsa-para-swarm).

## Cómo gestiona Docker las configuraciones

Cuando añades una configuración al swarm, Docker la envía al administrador del swarm a través de una conexión TLS mutua. La configuración se almacena en el registro de Raft, que está cifrado. Todo el registro de Raft se replica en los demás administradores, lo que garantiza para las configuraciones la misma alta disponibilidad que para el resto de los datos de gestión del swarm.

Cuando concedes a un servicio recién creado o en ejecución acceso a una configuración, la configuración se monta como un archivo en el contenedor. La ubicación del punto de montaje dentro del contenedor predeterminada es `/<config-name>` en contenedores de Linux. En contenedores de Windows, todas las configuraciones se montan en `C:\ProgramData\Docker\configs` y se crean enlaces simbólicos a la ubicación deseada, que por defecto es `C:\<config-name>`.

Puedes establecer la propiedad (`uid` y `gid`) de la configuración, utilizando el ID numérico o el nombre del usuario o grupo. También puedes especificar los permisos del archivo (`mode`). Estos ajustes se ignoran en los contenedores de Windows.

- Si no se establece, la configuración pertenece al usuario que ejecuta el comando del contenedor (a menudo `root`) y al grupo predeterminado de ese usuario (también a menudo `root`).
- Si no se establece, la configuración tiene permisos de lectura global (modo `0444`), a menos que se establezca una `umask` dentro del contenedor, en cuyo caso el modo se verá afectado por ese valor de `umask`.

Puedes actualizar un servicio para concederle acceso a configuraciones adicionales o revocar su acceso a una configuración determinada en cualquier momento.

Un nodo solo tiene acceso a las configuraciones si es un administrador de swarm o si está ejecutando tareas de servicio a las que se les ha concedido acceso a la configuración. Cuando una tarea de contenedor deja de ejecutarse, las configuraciones compartidas con ella se desmontan del sistema de archivos en memoria de ese contenedor y se eliminan de la memoria del nodo.

Si un nodo pierde la conectividad con el swarm mientras está ejecutando un contenedor de tareas con acceso a una configuración, el contenedor de tareas seguirá teniendo acceso a sus configuraciones, pero no podrá recibir actualizaciones hasta que el nodo se vuelva a conectar al swarm.

Puedes añadir o inspeccionar una configuración individual en cualquier momento, o listar todas las configuraciones. No puedes eliminar una configuración que un servicio en ejecución esté utilizando. Consulta [Rotar una configuración](/engine/swarm/configs/configs/#ejemplo-rotar-una-configuración) para conocer una forma de eliminar una configuración sin interrumpir los servicios en ejecución.

Para actualizar o revertir configuraciones con mayor comodidad, considera añadir un número de versión o una fecha al nombre de la configuración. Esto se ve facilitado por la posibilidad de controlar el punto de montaje de la configuración dentro de un contenedor determinado.

Para actualizar una pila (stack), realiza los cambios en tu archivo Compose y luego vuelve a ejecutar `docker stack deploy -c <new-compose-file> <stack-name>`. Si utilizas una nueva configuración en ese archivo, tus servicios comenzarán a usarla. Ten en cuenta que las configuraciones son inmutables, por lo que no puedes cambiar el archivo de un servicio existente. En su lugar, debes crear una nueva configuración para usar un archivo diferente.

Puedes ejecutar `docker stack rm` para detener la aplicación y retirar la pila. Esto elimina cualquier configuración que haya sido creada por `docker stack deploy` con el mismo nombre de pila. Esto elimina _todas_ las configuraciones, incluidas las que no están referenciadas por servicios y las que quedan después de un comando `docker service update --config-rm`.

## Más información sobre los comandos `docker config`

Utiliza estos enlaces para leer sobre comandos específicos o continúa con el [ejemplo sobre el uso de configuraciones con un servicio](#ejemplo-avanzado-usar-configuraciones-con-un-servicio-nginx).

- [`docker config create`](/reference/cli/docker/config/create/)
- [`docker config inspect`](/reference/cli/docker/config/inspect/)
- [`docker config ls`](/reference/cli/docker/config/ls/)
- [`docker config rm`](/reference/cli/docker/config/rm/)

## Ejemplos

Esta sección incluye ejemplos progresivos que ilustran cómo utilizar las configuraciones de Docker.

> [!NOTE]
> 
> Estos ejemplos utilizan un swarm de un solo motor y servicios no escalados para mayor simplicidad. Los ejemplos utilizan contenedores de Linux, pero los contenedores de Windows también admiten configuraciones.

### Definir y usar configuraciones en archivos compose

El comando `docker stack` admite la definición de configuraciones en un archivo Compose. Sin embargo, la clave `configs` no es compatible con `docker compose`. Consulta la [referencia del archivo Compose](/reference/compose-file/configs/) para más detalles.

### Ejemplo simple: Primeros pasos con las configuraciones

Este ejemplo simple muestra cómo funcionan las configuraciones en solo unos pocos comandos. Para un ejemplo del mundo real, continúa en [Ejemplo avanzado: Usar configuraciones con un servicio Nginx](#ejemplo-avanzado-usar-configuraciones-con-un-servicio-nginx).

1.  Añade una configuración a Docker. El comando `docker config create` lee la entrada estándar porque el último argumento, que representa el archivo del cual leer la configuración, está establecido en `-`.

    ```console
    $ echo "This is a config" | docker config create my-config -
    ```

2.  Crea un servicio `redis` y concédele acceso a la configuración. Por defecto, el contenedor puede acceder a la configuración en `/my-config`, pero puedes personalizar el nombre del archivo en el contenedor utilizando la opción `target` .

    ```console
    $ docker service create --name redis --config my-config redis:alpine
    ```

3.  Verifica que la tarea se esté ejecutando sin problemas utilizando `docker service ps`. Si todo está funcionando, la salida se verá similar a esto:

    ```console
    $ docker service ps redis

    ID            NAME     IMAGE         NODE              DESIRED STATE  CURRENT STATE          ERROR  PORTS
    bkna6bpn8r1a  redis.1  redis:alpine  ip-172-31-46-109  Running        Running 8 seconds ago
    ```

4.  Obtén el ID del contenedor de la tarea del servicio `redis` utilizando `docker ps`, de modo que puedas usar `docker container exec` para conectarte al contenedor y leer el contenido del archivo de datos de configuración. Este archivo, por defecto, es legible por todos y tiene el mismo nombre que la configuración. El primer comando a continuación ilustra cómo encontrar el ID del contenedor, y el segundo y tercer comando utilizan la autocompletación de la terminal para hacerlo automáticamente.

    ```console
    $ docker ps --filter name=redis -q

    5cb1c2348a59

    $ docker container exec $(docker ps --filter name=redis -q) ls -l /my-config

    -r--r--r--    1 root     root            12 Jun  5 20:49 my-config

    $ docker container exec $(docker ps --filter name=redis -q) cat /my-config

    This is a config
    ```

5.  Intenta eliminar la configuración. La eliminación fallará porque el servicio `redis` está en ejecución y tiene acceso a la configuración.

    ```console

    $ docker config ls

    ID                          NAME                CREATED             UPDATED
    fzwcfuqjkvo5foqu7ts7ls578   hello               31 minutes ago      31 minutes ago


    $ docker config rm my-config

    Error response from daemon: rpc error: code = 3 desc = config 'my-config' is
    in use by the following service: redis
    ```

6.  Quita el acceso a la configuración del servicio `redis` en ejecución actualizando el servicio.

    ```console
    $ docker service update --config-rm my-config redis
    ```

7.  Repite los pasos 3 y 4 de nuevo, verificando que el servicio ya no tenga acceso a la configuración. El ID del contenedor es diferente porque el comando `service update` vuelve a desplegar el servicio.

    ```console
    $ docker container exec -it $(docker ps --filter name=redis -q) cat /my-config

    cat: can't open '/my-config': No such file or directory
    ```

8.  Detén y elimina el servicio, y elimina la configuración de Docker.

    ```console
    $ docker service rm redis

    $ docker config rm my-config
    ```

### Ejemplo simple: Usar configuraciones en un servicio de Windows

Este es un ejemplo muy simple que muestra cómo usar configuraciones con un servicio de Microsoft IIS que se ejecuta en Docker para Windows con contenedores de Windows en Microsoft Windows 10. Es un ejemplo sencillo que almacena la página web en una configuración.

Este ejemplo asume que tienes PowerShell instalado.

1.  Guarda el siguiente contenido en un nuevo archivo `index.html`.

    ```html
    <html lang="en">
      <head><title>Hello Docker</title></head>
      <body>
        <p>Hello Docker! You have deployed a HTML page.</p>
      </body>
    </html>
    ```

2.  Si aún no lo has hecho, inicializa o únete al swarm.

    ```powershell
    docker swarm init
    ```

3.  Guarda el archivo `index.html` como una configuración de swarm llamada `homepage`.

    ```powershell
    docker config create homepage index.html
    ```

4.  Crea un servicio IIS y concédele acceso a la configuración `homepage`.

    ```powershell
    docker service create
        --name my-iis
        --publish published=8000,target=8000
        --config src=homepage,target="\inetpub\wwwroot\index.html"
        microsoft/iis:nanoserver
    ```

5.  Accede al servicio IIS en `http://localhost:8000/`. Debería servir el contenido HTML del primer paso.

6.  Elimina el servicio y la configuración.

    ```powershell
    docker service rm my-iis

    docker config rm homepage
    ```

### Ejemplo: Usar una configuración con plantilla

Para crear una configuración en la que el contenido se generará utilizando un motor de plantillas, utiliza el parámetro `--template-driver` y especifica el nombre del motor como su argumento. La plantilla se renderizará cuando se cree el contenedor.

1.  Guarda el siguiente contenido en un nuevo archivo `index.html.tmpl`.

    ```html
    <html lang="en">
      <head><title>Hello Docker</title></head>
      <body>
        <p>Hello {{ env "HELLO" }}! I'm service {{ .Service.Name }}.</p>
      </body>
    </html>
    ```

2.  Guarda el archivo `index.html.tmpl` como una configuración de swarm llamada `homepage`. Proporciona el parámetro `--template-driver` y especifica `golang` como motor de plantillas.

    ```console
    $ docker config create --template-driver golang homepage index.html.tmpl
    ```

3.  Crea un servicio que ejecute Nginx y que tenga acceso a la variable de entorno HELLO y a la configuración.

    ```console
    $ docker service create \
         --name hello-template \
         --env HELLO="Docker" \
         --config source=homepage,target=/usr/share/nginx/html/index.html \
         --publish published=3000,target=80 \
         nginx:alpine
    ```

4.  Verifica que the servicio esté operativo: que puedas acceder al servidor Nginx y que se esté sirviendo la salida correcta.

    ```console
    $ curl http://0.0.0.0:3000

    <html lang="en">
      <head><title>Hello Docker</title></head>
      <body>
        <p>Hello Docker! I'm service hello-template.</p>
      </body>
    </html>
    ```

### Ejemplo avanzado: Usar configuraciones con un servicio Nginx

Este ejemplo está dividido en dos partes. La [primera parte](#generar-el-certificado-del-sitio) trata sobre la generación del certificado del sitio y no involucra directamente las configuraciones de Docker, pero prepara la [segunda parte](#configurar-el-contenedor-nginx), donde se almacena y utiliza el certificado del sitio como una serie de secretos y la configuración de Nginx como una configuración de Docker. El ejemplo muestra cómo establecer opciones en la configuración, como la ubicación de destino dentro del contenedor y los permisos del archivo (`mode`).

#### Generar el certificado del sitio

Genera una CA raíz y un certificado y clave TLS para tu sitio. Para sitios de producción, es recomendable usar un servicio como `Let’s Encrypt` para generar el certificado y la clave TLS, pero este ejemplo utiliza herramientas de línea de comandos. Este paso es un poco complicado, pero es solo un paso de configuración para que tengas algo que almacenar como secreto de Docker. Si deseas omitir estos subpasos, puedes [usar Let's Encrypt](https://letsencrypt.org/getting-started/) para generar la clave y el certificado del sitio, nombrar los archivos `site.key` y `site.crt`, y saltar a [Configurar el contenedor Nginx](#configurar-el-contenedor-nginx).

1.  Genera una clave raíz.

    ```console
    $ openssl genrsa -out "root-ca.key" 4096
    ```

2.  Genera un CSR utilizando la clave raíz.

    ```console
    $ openssl req \
              -new -key "root-ca.key" \
              -out "root-ca.csr" -sha256 \
              -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA'
    ```

3.  Configura la CA raíz. Edita un nuevo archivo llamado `root-ca.cnf` y pega el siguiente contenido en él. Esto restringe la CA raíz para que solo firme certificados de hoja y no CAs intermedias.

    ```ini
    [root_ca]
    basicConstraints = critical,CA:TRUE,pathlen:1
    keyUsage = critical, nonRepudiation, cRLSign, keyCertSign
    subjectKeyIdentifier=hash
    ```

4.  Firma el certificado.

    ```console
    $ openssl x509 -req -days 3650 -in "root-ca.csr" \
                   -signkey "root-ca.key" -sha256 -out "root-ca.crt" \
                   -extfile "root-ca.cnf" -extensions \
                   root_ca
    ```

5.  Genera la clave del sitio.

    ```console
    $ openssl genrsa -out "site.key" 4096
    ```

6.  Genera el certificado del sitio y fírmalo con la clave del sitio.

    ```console
    $ openssl req -new -key "site.key" -out "site.csr" -sha256 \
              -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost'
    ```

7.  Configura el certificado del sitio. Edita un nuevo archivo llamado `site.cnf` y pega el siguiente contenido en él. Esto limita el certificado del sitio para que solo se pueda utilizar para autenticar un servidor y no para firmar otros certificados.

    ```ini
    [server]
    authorityKeyIdentifier=keyid,issuer
    basicConstraints = critical,CA:FALSE
    extendedKeyUsage=serverAuth
    keyUsage = critical, digitalSignature, keyEncipherment
    subjectAltName = DNS:localhost, IP:127.0.0.1
    subjectKeyIdentifier=hash
    ```

8.  Firma el certificado del sitio.

    ```console
    $ openssl x509 -req -days 750 -in "site.csr" -sha256 \
        -CA "root-ca.crt" -CAkey "root-ca.key" -CAcreateserial \
        -out "site.crt" -extfile "site.cnf" -extensions server
    ```

9.  El servicio Nginx no necesita los archivos `site.csr` y `site.cnf`, pero los necesitarás si deseas generar un nuevo certificado para el sitio. Protege el archivo `root-ca.key`.

#### Configurar el contenedor Nginx

1.  Produce una configuración de Nginx muy básica que sirva archivos estáticos a través de HTTPS. El certificado y la clave TLS se almacenan como secretos de Docker para que se puedan rotar sin complicaciones.

    En el directorio actual, crea un nuevo archivo llamado `site.conf` con el siguiente contenido:

    ```nginx
    server {
        listen                443 ssl;
        server_name           localhost;
        ssl_certificate       /run/secrets/site.crt;
        ssl_certificate_key   /run/secrets/site.key;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }
    }
    ```

2.  Crea dos secretos que representen la clave y el certificado. Puedes almacenar cualquier archivo como secreto siempre que sea inferior a 500 KB. Esto te permite desacoplar la clave y el certificado de los servicios que los utilizan. En estos ejemplos, el nombre del secreto y el del archivo son iguales.

    ```console
    $ docker secret create site.key site.key

    $ docker secret create site.crt site.crt
    ```

3.  Guarda el archivo `site.conf` en una configuración de Docker. El primer parámetro es el nombre de la configuración y el segundo parámetro es el archivo del cual leerla.

    ```console
    $ docker config create site.conf site.conf
    ```

    Lista las configuraciones:

    ```console
    $ docker config ls

    ID                          NAME                CREATED             UPDATED
    4ory233120ccg7biwvy11gl5z   site.conf           4 seconds ago       4 seconds ago
    ```

4.  Crea un servicio que ejecute Nginx y que tenga acceso a los dos secretos y a la configuración. Establece el modo en `0440` para que el archivo solo sea legible por su propietario y el grupo de ese propietario, no por todo el mundo.

    ```console
    $ docker service create \
         --name nginx \
         --secret site.key \
         --secret site.crt \
         --config source=site.conf,target=/etc/nginx/conf.d/site.conf,mode=0440 \
         --publish published=3000,target=443 \
         nginx:latest \
         sh -c "exec nginx -g 'daemon off;'"
    ```

    Dentro de los contenedores en ejecución, ahora existen los siguientes tres archivos:

    - `/run/secrets/site.key`
    - `/run/secrets/site.crt`
    - `/etc/nginx/conf.d/site.conf`

5.  Verifica que el servicio Nginx se esté ejecutando.

    ```console
    $ docker service ls

    ID            NAME   MODE        REPLICAS  IMAGE
    zeskcec62q24  nginx  replicated  1/1       nginx:latest

    $ docker service ps nginx

    NAME                  IMAGE         NODE  DESIRED STATE  CURRENT STATE          ERROR  PORTS
    nginx.1.9ls3yo9ugcls  nginx:latest  moby  Running        Running 3 minutes ago
    ```

6.  Verifica que el servicio esté operativo: que puedas acceder al servidor Nginx y que se esté utilizando el certificado TLS correcto.

    ```console
    $ curl --cacert root-ca.crt https://0.0.0.0:3000

    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>

    <p>For online documentation and support, refer to
    <a href="https://nginx.org">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="https://www.nginx.com">www.nginx.com</a>.</p>

    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    ```

    ```console
    $ openssl s_client -connect 0.0.0.0:3000 -CAfile root-ca.crt

    CONNECTED(00000003)
    depth=1 /C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA
    verify return:1
    depth=0 /C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost
    verify return:1
    ---
    Certificate chain
     0 s:/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost
       i:/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
    …
    -----END CERTIFICATE-----
    subject=/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost
    issuer=/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 1663 bytes and written 712 bytes
    ---
    New, TLSv1/SSLv3, Cipher is AES256-SHA
    Server public key is 4096 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    SSL-Session:
        Protocol  : TLSv1
        Cipher    : AES256-SHA
        Session-ID: A1A8BF35549C5715648A12FD7B7E3D861539316B03440187D9DA6C2E48822853
        Session-ID-ctx:
        Master-Key: F39D1B12274BA16D3A906F390A61438221E381952E9E1E05D3DD784F0135FB81353DA38C6D5C021CB926E844DFC49FC4
        Key-Arg   : None
        Start Time: 1481685096
        Timeout   : 300 (sec)
        Verify return code: 0 (ok)
    ```

7.  A menos que vayas a continuar con el siguiente ejemplo, limpia el entorno después de ejecutar este ejemplo eliminando el servicio `nginx` y los secretos y configuraciones almacenados.

    ```console
    $ docker service rm nginx

    $ docker secret rm site.crt site.key

    $ docker config rm site.conf
    ```

Ahora has configurado un servicio Nginx con su configuración desacoplada de su imagen. Podrías ejecutar múltiples sitios con exactamente la misma imagen pero con configuraciones separadas, sin necesidad de construir una imagen personalizada en absoluto.

### Ejemplo: Rotar una configuración

Para rotar una configuración, primero guardas una nueva configuración con un nombre diferente al de la que está en uso. Luego vuelves a desplegar el servicio, eliminando la configuración anterior y añadiendo la nueva en el mismo punto de montaje dentro del contenedor. Este ejemplo se basa en el anterior al rotar el archivo de configuración `site.conf`.

1.  Edita el archivo `site.conf` localmente. Añade `index.php` a la línea `index` y guarda el archivo.

    ```nginx
    server {
        listen                443 ssl;
        server_name           localhost;
        ssl_certificate       /run/secrets/site.crt;
        ssl_certificate_key   /run/secrets/site.key;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm index.php;
        }
    }
    ```

2.  Crea una nueva configuración de Docker utilizando el nuevo `site.conf`, llamada `site-v2.conf`.

    ```bash
    $ docker config create site-v2.conf site.conf
    ```

3.  Actualiza el servicio `nginx` para usar la nueva configuración en lugar de la anterior.

    ```console
    $ docker service update \
      --config-rm site.conf \
      --config-add source=site-v2.conf,target=/etc/nginx/conf.d/site.conf,mode=0440 \
      nginx
    ```

4.  Verifica que el servicio `nginx` se haya vuelto a desplegar por completo utilizando `docker service ps nginx`. Una vez hecho esto, puedes eliminar la antigua configuración `site.conf`.

    ```console
    $ docker config rm site.conf
    ```

5.  Para limpiar, puedes eliminar el servicio `nginx`, así como los secretos y las configuraciones.

    ```console
    $ docker service rm nginx

    $ docker secret rm site.crt site.key

    $ docker config rm site-v2.conf
    ```

Ahora has actualizado la configuración de tu servicio `nginx` sin necesidad de volver a construir su imagen.

