From 8237a2fd88c4d17fa40f48b194ea350f6a8cf3ef Mon Sep 17 00:00:00 2001 From: liujian Date: Thu, 26 Jun 2025 17:48:18 +0800 Subject: [PATCH] feat: install image_registry (#2640) Signed-off-by: joyceliu --- builtin/core/defaults/config/v1.23.yaml | 2 +- builtin/core/defaults/config/v1.24.yaml | 2 +- builtin/core/defaults/config/v1.25.yaml | 2 +- builtin/core/defaults/config/v1.26.yaml | 2 +- builtin/core/defaults/config/v1.27.yaml | 2 +- builtin/core/defaults/config/v1.28.yaml | 2 +- builtin/core/defaults/config/v1.29.yaml | 2 +- builtin/core/defaults/config/v1.30.yaml | 2 +- builtin/core/defaults/config/v1.31.yaml | 2 +- builtin/core/defaults/config/v1.32.yaml | 2 +- builtin/core/defaults/config/v1.33.yaml | 2 +- builtin/core/playbooks/init_registry.yaml | 6 +- .../core/roles/init/init-cert/tasks/main.yaml | 11 +- .../install/image-registry/defaults/main.yaml | 2 +- .../files/keepalived/healthcheck.sh | 9 + .../image-registry/tasks/install_docker.yaml | 2 +- .../image-registry/tasks/install_harbor.yaml | 70 +- .../tasks/install_keepalived.yaml | 58 +- .../tasks/install_registry.yaml | 12 +- .../image-registry/tasks/load_images.yaml | 2 +- .../install/image-registry/tasks/main.yaml | 4 +- .../templates/harbor-replications.sh | 20 + .../image-registry/templates/harbor.service | 2 +- .../harbor_keepalived.docker-compose | 26 - .../image-registry/templates/keepalived.conf | 30 + .../templates/keepalived.config | 31 - .../templates/keepalived.healthcheck | 17 - .../image-registry/templates/registry.config | 10 +- .../templates/registry.docker-compose | 16 +- .../image-registry/templates/registry.service | 2 +- .../tasks/high-availability/kube_vip.yaml | 57 +- .../templates/kubevip/kubevip.ARP | 2 +- .../templates/kubevip/kubevip.BGP | 2 +- .../env_check/tasks/image_registry.yaml | 18 + .../image_registry/tasks/keepalived.yaml | 5 + docs/images/ha-harbor.excalidraw | 784 ++++++++++++++++++ docs/images/ha-harbor.png | Bin 0 -> 86158 bytes docs/images/ha-registry.excalidraw | 551 ++++++++++++ docs/images/ha-registry.png | Bin 0 -> 81161 bytes docs/zh/core/architecture.md | 16 +- docs/zh/core/image_registry.md | 245 ++++++ .../harborCreateRegistriesAndReplications.sh | 64 -- 42 files changed, 1874 insertions(+), 222 deletions(-) create mode 100644 builtin/core/roles/install/image-registry/files/keepalived/healthcheck.sh create mode 100644 builtin/core/roles/install/image-registry/templates/harbor-replications.sh delete mode 100644 builtin/core/roles/install/image-registry/templates/harbor_keepalived.docker-compose create mode 100644 builtin/core/roles/install/image-registry/templates/keepalived.conf delete mode 100644 builtin/core/roles/install/image-registry/templates/keepalived.config delete mode 100644 builtin/core/roles/install/image-registry/templates/keepalived.healthcheck create mode 100644 builtin/core/roles/precheck/env_check/tasks/image_registry.yaml create mode 100644 docs/images/ha-harbor.excalidraw create mode 100644 docs/images/ha-harbor.png create mode 100644 docs/images/ha-registry.excalidraw create mode 100644 docs/images/ha-registry.png create mode 100644 docs/zh/core/image_registry.md delete mode 100644 scripts/harborCreateRegistriesAndReplications.sh diff --git a/builtin/core/defaults/config/v1.23.yaml b/builtin/core/defaults/config/v1.23.yaml index 18b24611..441980a4 100644 --- a/builtin/core/defaults/config/v1.23.yaml +++ b/builtin/core/defaults/config/v1.23.yaml @@ -14,7 +14,7 @@ spec: etcd_version: v3.5.4 # ========== image registry ========== # keepalived image tag. Used for load balancing when there are multiple image registry nodes. - # keepalived_version: stable + # keepalived_version: 2.0.20 # ========== image registry: harbor ========== # harbor image tag # harbor_version: v2.6.3 diff --git a/builtin/core/defaults/config/v1.24.yaml b/builtin/core/defaults/config/v1.24.yaml index ddfab449..c80e7fa1 100644 --- a/builtin/core/defaults/config/v1.24.yaml +++ b/builtin/core/defaults/config/v1.24.yaml @@ -14,7 +14,7 @@ spec: etcd_version: v3.5.6 # ========== image registry ========== # keepalived image tag. Used for load balancing when there are multiple image registry nodes. - # keepalived_version: stable + # keepalived_version: v2.0.20 # ========== image registry: harbor ========== # harbor image tag # harbor_version: v2.7.1 diff --git a/builtin/core/defaults/config/v1.25.yaml b/builtin/core/defaults/config/v1.25.yaml index 77501b75..69ebc085 100644 --- a/builtin/core/defaults/config/v1.25.yaml +++ b/builtin/core/defaults/config/v1.25.yaml @@ -14,7 +14,7 @@ spec: etcd_version: v3.5.7 # ========== image registry ========== # keepalived image tag. Used for load balancing when there are multiple image registry nodes. - # keepalived_version: stable + # keepalived_version: 2.0.20 # ========== image registry: harbor ========== # harbor image tag # harbor_version: v2.8.1 diff --git a/builtin/core/defaults/config/v1.26.yaml b/builtin/core/defaults/config/v1.26.yaml index 5a3e227a..8ef52a3a 100644 --- a/builtin/core/defaults/config/v1.26.yaml +++ b/builtin/core/defaults/config/v1.26.yaml @@ -14,7 +14,7 @@ spec: etcd_version: v3.5.8 # ========== image registry ========== # keepalived image tag. Used for load balancing when there are multiple image registry nodes. - # keepalived_version: stable + # keepalived_version: 2.0.20 # ========== image registry: harbor ========== # harbor image tag # harbor_version: v2.9.1 diff --git a/builtin/core/defaults/config/v1.27.yaml b/builtin/core/defaults/config/v1.27.yaml index 321f6f66..be1a385f 100644 --- a/builtin/core/defaults/config/v1.27.yaml +++ b/builtin/core/defaults/config/v1.27.yaml @@ -14,7 +14,7 @@ spec: etcd_version: v3.5.9 # ========== image registry ========== # keepalived image tag. Used for load balancing when there are multiple image registry nodes. - # keepalived_version: stable + # keepalived_version: 2.0.20 # ========== image registry: harbor ========== # harbor image tag # harbor_version: v2.10.1 diff --git a/builtin/core/defaults/config/v1.28.yaml b/builtin/core/defaults/config/v1.28.yaml index cb9abbbc..aadf3439 100644 --- a/builtin/core/defaults/config/v1.28.yaml +++ b/builtin/core/defaults/config/v1.28.yaml @@ -14,7 +14,7 @@ spec: etcd_version: v3.5.9 # ========== image registry ========== # keepalived image tag. Used for load balancing when there are multiple image registry nodes. - # keepalived_version: stable + # keepalived_version: 2.0.20 # ========== image registry: harbor ========== # harbor image tag # harbor_version: v2.10.1 diff --git a/builtin/core/defaults/config/v1.29.yaml b/builtin/core/defaults/config/v1.29.yaml index be8eea3f..bc625415 100644 --- a/builtin/core/defaults/config/v1.29.yaml +++ b/builtin/core/defaults/config/v1.29.yaml @@ -14,7 +14,7 @@ spec: etcd_version: v3.5.10 # ========== image registry ========== # keepalived image tag. Used for load balancing when there are multiple image registry nodes. - # keepalived_version: stable + # keepalived_version: 2.0.20 # ========== image registry: harbor ========== # harbor image tag # harbor_version: v2.10.1 diff --git a/builtin/core/defaults/config/v1.30.yaml b/builtin/core/defaults/config/v1.30.yaml index 453f6345..ea32d24c 100644 --- a/builtin/core/defaults/config/v1.30.yaml +++ b/builtin/core/defaults/config/v1.30.yaml @@ -14,7 +14,7 @@ spec: etcd_version: v3.5.10 # ========== image registry ========== # keepalived image tag. Used for load balancing when there are multiple image registry nodes. - # keepalived_version: stable + # keepalived_version: 2.0.20 # ========== image registry: harbor ========== # harbor image tag # harbor_version: v2.10.1 diff --git a/builtin/core/defaults/config/v1.31.yaml b/builtin/core/defaults/config/v1.31.yaml index 1ed5a61e..fd54e6f3 100644 --- a/builtin/core/defaults/config/v1.31.yaml +++ b/builtin/core/defaults/config/v1.31.yaml @@ -14,7 +14,7 @@ spec: etcd_version: v3.5.11 # ========== image registry ========== # keepalived image tag. Used for load balancing when there are multiple image registry nodes. - # keepalived_version: stable + # keepalived_version: 2.0.20 # ========== image registry: harbor ========== # harbor image tag # harbor_version: v2.10.1 diff --git a/builtin/core/defaults/config/v1.32.yaml b/builtin/core/defaults/config/v1.32.yaml index 3f931275..66161f66 100644 --- a/builtin/core/defaults/config/v1.32.yaml +++ b/builtin/core/defaults/config/v1.32.yaml @@ -14,7 +14,7 @@ spec: etcd_version: v3.5.11 # ========== image registry ========== # keepalived image tag. Used for load balancing when there are multiple image registry nodes. - # keepalived_version: stable + # keepalived_version: 2.0.20 # ========== image registry: harbor ========== # harbor image tag # harbor_version: v2.10.1 diff --git a/builtin/core/defaults/config/v1.33.yaml b/builtin/core/defaults/config/v1.33.yaml index 400c1a16..221babc9 100644 --- a/builtin/core/defaults/config/v1.33.yaml +++ b/builtin/core/defaults/config/v1.33.yaml @@ -14,7 +14,7 @@ spec: etcd_version: v3.5.11 # ========== image registry ========== # keepalived image tag. Used for load balancing when there are multiple image registry nodes. - # keepalived_version: stable + # keepalived_version: 2.0.20 # ========== image registry: harbor ========== # harbor image tag # harbor_version: v2.10.1 diff --git a/builtin/core/playbooks/init_registry.yaml b/builtin/core/playbooks/init_registry.yaml index 63fa56ca..f28b1390 100644 --- a/builtin/core/playbooks/init_registry.yaml +++ b/builtin/core/playbooks/init_registry.yaml @@ -2,10 +2,10 @@ - import_playbook: hook/pre_install.yaml - hosts: - - localhost + - localhost roles: - - init/init-artifact - - init/init-cert + - init/init-artifact + - init/init-cert - hosts: - image_registry diff --git a/builtin/core/roles/init/init-cert/tasks/main.yaml b/builtin/core/roles/init/init-cert/tasks/main.yaml index ffae1a55..5456e1bf 100644 --- a/builtin/core/roles/init/init-cert/tasks/main.yaml +++ b/builtin/core/roles/init/init-cert/tasks/main.yaml @@ -21,10 +21,10 @@ {{- range .groups.etcd | default list -}} {{- $internalIPv4 := index $.hostvars . "internal_ipv4" | default "" -}} {{- $internalIPv6 := index $.hostvars . "internal_ipv6" | default "" -}} - {{- if ne $internalIPv4 "" -}} + {{- if $internalIPv4 | empty | not -}} {{- $ips = append $ips $internalIPv4 -}} {{- end -}} - {{- if ne $internalIPv6 "" -}} + {{- if $internalIPv6 | empty | not -}} {{- $ips = append $ips $internalIPv6 -}} {{- end -}} {{- end -}} @@ -46,13 +46,16 @@ cn: image_registry sans: >- {{- $ips := list -}} + {{- if .image_registry.ha_vip | empty | not -}} + {{- $ips = append $ips .image_registry.ha_vip -}} + {{- end -}} {{- range .groups.image_registry | default list -}} {{- $internalIPv4 := index $.hostvars . "internal_ipv4" | default "" -}} {{- $internalIPv6 := index $.hostvars . "internal_ipv6" | default "" -}} - {{- if ne $internalIPv4 "" -}} + {{- if $internalIPv4 | empty | not -}} {{- $ips = append $ips $internalIPv4 -}} {{- end -}} - {{- if ne $internalIPv6 "" -}} + {{- if $internalIPv6 | empty | not -}} {{- $ips = append $ips $internalIPv6 -}} {{- end -}} {{- end -}} diff --git a/builtin/core/roles/install/image-registry/defaults/main.yaml b/builtin/core/roles/install/image-registry/defaults/main.yaml index 3f26e774..2bbdb1c4 100644 --- a/builtin/core/roles/install/image-registry/defaults/main.yaml +++ b/builtin/core/roles/install/image-registry/defaults/main.yaml @@ -30,7 +30,7 @@ image_registry: nfs_dir: /share/registry storage: filesystem: - rootdir: /var/lib/registry + rootdir: /opt/registry/data # nfs_mount: /repository/registry # if set. will mount rootdirectory to nfs server in nfs_mount. # azure: # accountname: accountname diff --git a/builtin/core/roles/install/image-registry/files/keepalived/healthcheck.sh b/builtin/core/roles/install/image-registry/files/keepalived/healthcheck.sh new file mode 100644 index 00000000..43bd99d6 --- /dev/null +++ b/builtin/core/roles/install/image-registry/files/keepalived/healthcheck.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +nc -zv -w 2 localhost 443 > /dev/null 2>&1 + +if [ $? -eq 0 ]; then + exit 0 +else + exit 1 +fi diff --git a/builtin/core/roles/install/image-registry/tasks/install_docker.yaml b/builtin/core/roles/install/image-registry/tasks/install_docker.yaml index 174fcb95..f54f5582 100644 --- a/builtin/core/roles/install/image-registry/tasks/install_docker.yaml +++ b/builtin/core/roles/install/image-registry/tasks/install_docker.yaml @@ -5,7 +5,7 @@ register: docker_install_version - name: Install docker - when: .docker_install_version.stderr | empty | not) (.docker_install_version.stdout | hasPrefix (printf "Docker version %s," .docker_version) | not) + when: or (.docker_install_version.stderr | empty | not) (.docker_install_version.stdout | hasPrefix (printf "Docker version %s," .docker_version) | not) block: - name: Sync docker binary to remote copy: diff --git a/builtin/core/roles/install/image-registry/tasks/install_harbor.yaml b/builtin/core/roles/install/image-registry/tasks/install_harbor.yaml index 562b2ab0..2b3a7f25 100644 --- a/builtin/core/roles/install/image-registry/tasks/install_harbor.yaml +++ b/builtin/core/roles/install/image-registry/tasks/install_harbor.yaml @@ -2,7 +2,7 @@ - name: Sync harbor package to remote copy: src: >- - {{ .binary_dir }}/image-registry/harbor/{{ .harbor_version }}/{{ .binary_type.stdout }}/harbor-offline-installer-{{ .harbor_version }}.tgz + {{ .binary_dir }}/image-registry/harbor/{{ .harbor_version }}/{{ .binary_type }}/harbor-offline-installer-{{ .harbor_version }}.tgz dest: >- /opt/harbor/{{ .harbor_version }}/harbor-offline-installer-{{ .harbor_version }}.tgz @@ -30,15 +30,6 @@ dest: >- /opt/harbor/{{ .harbor_version }}/harbor/harbor.yml -- name: Generate keepalived docker compose - template: - src: harbor_keepalived.docker-compose - dest: >- - /opt/harbor/{{ .harbor_version }}/harbor/docker-compose-keepalived.yml - when: - - .image_registry.ha_vip | empty | not - - .image_registry_service.stderr | empty | not - - name: Install harbor command: | cd /opt/harbor/{{ .harbor_version }}/harbor && /bin/bash install.sh @@ -50,3 +41,62 @@ - name: Start harbor service command: systemctl daemon-reload && systemctl start harbor.service && systemctl enable harbor.service + +- name: HA harbor sync images + when: + - .image_registry.ha_vip | empty | not + - .groups.image_registry | len | lt 1 + block: + - name: add keepalived service to docker-compose + command: | + KEEPALIVED_SERVICE='# keepalived is generated by kubekey. + keepalived: + image: osixia/keepalived:{{ .keepalived_version }} + container_name: keepalived + command: + - --copy-service + network_mode: "host" + restart: always + dns_search: . + cap_drop: + - ALL + cap_add: + - NET_ADMIN + - NET_BROADCAST + - NET_RAW + - CHOWN + - DAC_OVERRIDE + depends_on: + - proxy + volumes: + - type: bind + source: /opt/keepalived/{{ .keepalived_version }}/keepalived.conf + target: /container/service/keepalived/assets/keepalived.conf + - type: bind + source: /opt/keepalived/{{ .keepalived_version }}/healthcheck.sh + target: /etc/keepalived/healthcheck.sh' + TARGET_FILE="/opt/harbor/{{ .harbor_version }}/harbor/docker-compose.yml" + TMP_FILE="/opt/harbor/{{ .harbor_version }}/harbor/docker-compose.yml.tmp" + awk -v service="$KEEPALIVED_SERVICE" ' + /^services:/ { + print + print service + next + } + { print } + ' "$TARGET_FILE" > "$TMP_FILE" && mv "$TMP_FILE" "$TARGET_FILE" + systemctl restart harbor.service + - name: wait harbor service ready + command: | + if ! timeout 300 bash -c 'while ! nc -zv localhost 443; do sleep 2; done'; then + echo "ERROR: Harbor did not start within 5 minutes!" + exit 1 + fi + - name: sync harbor-replications scripts to remote + template: + src: harbor-replications.sh + dest: /opt/harbor/scripts/harbor-replications.sh + mode: 0755 + - name: execute harbor-replications.sh + command: bash /opt/harbor/scripts/harbor-replications.sh + \ No newline at end of file diff --git a/builtin/core/roles/install/image-registry/tasks/install_keepalived.yaml b/builtin/core/roles/install/image-registry/tasks/install_keepalived.yaml index 74b10aa0..27220825 100644 --- a/builtin/core/roles/install/image-registry/tasks/install_keepalived.yaml +++ b/builtin/core/roles/install/image-registry/tasks/install_keepalived.yaml @@ -1,23 +1,65 @@ --- +- name: Get interface from ha_vip + block: + - name: Get all interface with cidr + command: | + ip -o addr show | awk ' + BEGIN { + printf "[\n"; + first = 1; + } + /inet / && !/ lo|docker|br-|veth/ { + if (!first) { + printf ",\n"; + } + first = 0; + printf " {\n"; + printf " \"interface\": \"%s\",\n", $2; + printf " \"cidr\": \"%s\"\n", $4; + printf " }"; + } + END { + printf "\n]\n"; + } + ' + register: interface + register_type: json + - name: filter interface by ha_vip + set_fact: + ha_vip_interface: >- + {{- $interface := "" }} + {{- range .interface.stdout | default list -}} + {{- if .cidr | ipInCIDR | has $.image_registry.ha_vip -}} + {{- $interface = .interface -}} + {{- end -}} + {{- end -}} + {{ $interface }} + - name: Check if network is exist + assert: + that: .kube_vip_interface | empty + fail_msg: "cannot find network interface to match ha_vip" + - name: Sync keepalived image to remote copy: src: >- - {{ .binary_dir }}/image-registry/keepalived/{{ .keepalived_version }}/{{ .binary_type.stdout }}/keepalived-{{ .keepalived_version }}-linux-{{ .binary_type.stdout }}.tgz + {{ .binary_dir }}/image-registry/keepalived/{{ .keepalived_version }}/{{ .binary_type }}/keepalived-{{ .keepalived_version }}-linux-{{ .binary_type }}.tgz dest: >- - /opt/keepalived/{{ .keepalived_version }}/keepalived-{{ .keepalived_version }}-linux-{{ .binary_type.stdout }}.tgz + /opt/keepalived/{{ .keepalived_version }}/keepalived-{{ .keepalived_version }}-linux-{{ .binary_type }}.tgz - name: Load keeplived image command: | - docker load -i /opt/keepalived/{{ .keepalived_version }}/keepalived-{{ .keepalived_version }}-linux-{{ .binary_type.stdout }}.tgz + docker load -i /opt/keepalived/{{ .keepalived_version }}/keepalived-{{ .keepalived_version }}-linux-{{ .binary_type }}.tgz - name: Sync keeplived config to remote template: - src: keeplived.config + src: keepalived.conf dest: >- - /opt/keeplived/{{ .keepalived_version }}/keepalived.conf + /opt/keepalived/{{ .keepalived_version }}/keepalived.conf + mode: 0664 - name: Sync healthcheck shell to remote - template: - src: keepalived.healthcheck + copy: + src: keepalived/healthcheck.sh dest: >- - /opt/keeplived/{{ .keepalived_version }}/healthcheck.sh + /opt/keepalived/{{ .keepalived_version }}/healthcheck.sh + mode: 0755 diff --git a/builtin/core/roles/install/image-registry/tasks/install_registry.yaml b/builtin/core/roles/install/image-registry/tasks/install_registry.yaml index 08f4986c..a42b23f3 100644 --- a/builtin/core/roles/install/image-registry/tasks/install_registry.yaml +++ b/builtin/core/roles/install/image-registry/tasks/install_registry.yaml @@ -23,9 +23,8 @@ mount -t nfs {{ $internalIPv6 }}:{{ .image_registry.registry.storage.filesystem.nfs_mount }} {{ .image_registry.registry.storage.filesystem.rootdir }} {{- end }} when: - - and .image_registry.registry.storage.filesystem.nfs_mount (ne .image_registry.registry.storage.filesystem.nfs_mount "") + - .image_registry.registry.storage.filesystem.nfs_mount | empty | not - .groups.nfs | default list | len | eq 1 - - .image_registry_service.stderr | empty | not - name: Load registry image command: | @@ -58,9 +57,16 @@ /opt/registry/{{ .registry_version }}/config.yml - name: Register registry service - copy: + template: src: registry.service dest: /etc/systemd/system/registry.service - name: Start registry service command: systemctl daemon-reload && systemctl start registry.service && systemctl enable registry.service + +- name: wait registry service ready + command: | + if ! timeout 300 bash -c 'while ! nc -zv localhost 443; do sleep 2; done'; then + echo "ERROR: Harbor did not start within 5 minutes!" + exit 1 + fi diff --git a/builtin/core/roles/install/image-registry/tasks/load_images.yaml b/builtin/core/roles/install/image-registry/tasks/load_images.yaml index a07cf4ce..8e1ffac8 100644 --- a/builtin/core/roles/install/image-registry/tasks/load_images.yaml +++ b/builtin/core/roles/install/image-registry/tasks/load_images.yaml @@ -36,7 +36,7 @@ done when: .image_registry.type | eq "harbor" -- name: Sync images package to harbor +- name: Sync images package to image_registry tags: ["only_image"] image: push: diff --git a/builtin/core/roles/install/image-registry/tasks/main.yaml b/builtin/core/roles/install/image-registry/tasks/main.yaml index b794737a..3eb426fb 100644 --- a/builtin/core/roles/install/image-registry/tasks/main.yaml +++ b/builtin/core/roles/install/image-registry/tasks/main.yaml @@ -4,7 +4,9 @@ - include_tasks: install_docker_compose.yaml - include_tasks: install_keepalived.yaml - when: .image_registry.ha_vip | empty | not + when: + - .image_registry.ha_vip | empty | not + - .groups.image_registry | len | lt 1 - name: Install harbor when: .image_registry.type | eq "harbor" diff --git a/builtin/core/roles/install/image-registry/templates/harbor-replications.sh b/builtin/core/roles/install/image-registry/templates/harbor-replications.sh new file mode 100644 index 00000000..5afa78d2 --- /dev/null +++ b/builtin/core/roles/install/image-registry/templates/harbor-replications.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +function createRegistries() { +{{- range .groups.image_registry | default list }} + {{- if ne . $.inventory_hostname }} + curl -k -u '{{ printf "%s:%s" $.image_registry.auth.username $.image_registry.auth.password }}' -X POST -H "Content-Type: application/json" "https://{{ $.inventory_hostname }}/api/v2.0/registries" -d "{\"name\": \"{{ . }}\", \"type\": \"harbor\", \"url\":\"https://{{ . }}:7443\", \"credential\": {\"access_key\": \"{{ $.image_registry.auth.username }}\", \"access_secret\": \"{{ $.image_registry.auth.password }}\"}, \"insecure\": true}" + {{- end }} +{{- end }} +} + +function createReplication() { +{{- range $index, $host := .groups.image_registry | default list }} + {{- if ne $host $.inventory_hostname }} + curl -k -u '{{ printf "%s:%s" $.image_registry.auth.username $.image_registry.auth.password }}' -X POST -H "Content-Type: application/json" "https://{{ $.inventory_hostname }}/api/v2.0/replication/policies" -d "{\"name\": \"{{ printf "%s_%s" $.inventory_hostname $host }}\", \"enabled\": true, \"deletion\":true, \"override\":true, \"replicate_deletion\":true, \"dest_registry\":{ \"id\": {{ $index }}, \"name\": \"{{ $host }}\"}, \"trigger\": {\"type\": \"event_based\"}, \"dest_namespace_replace_count\":1 }" + {{- end }} +{{- end }} +} + +createRegistries +createReplication diff --git a/builtin/core/roles/install/image-registry/templates/harbor.service b/builtin/core/roles/install/image-registry/templates/harbor.service index 9219b1e6..60df0119 100644 --- a/builtin/core/roles/install/image-registry/templates/harbor.service +++ b/builtin/core/roles/install/image-registry/templates/harbor.service @@ -5,7 +5,7 @@ Requires=docker.service [Service] Type=simple -ExecStart=/usr/local/bin/docker-compose -p harbor -f /opt/harbor/{{ .harbor_version }}/harbor/docker-compose.yml up{{ if and .image_registry.ha_vip (ne .image_registry.ha_vip "") }} && /usr/local/bin/docker-compose -p harbor -f /opt/harbor/{{ .harbor_version }}/harbor/docker-compose-keepalived.yml up{{ end }} +ExecStart=/usr/local/bin/docker-compose -p harbor -f /opt/harbor/{{ .harbor_version }}/harbor/docker-compose.yml up ExecStop=/usr/local/bin/docker-compose -p harbor down Restart=on-failure [Install] diff --git a/builtin/core/roles/install/image-registry/templates/harbor_keepalived.docker-compose b/builtin/core/roles/install/image-registry/templates/harbor_keepalived.docker-compose deleted file mode 100644 index 49e86c23..00000000 --- a/builtin/core/roles/install/image-registry/templates/harbor_keepalived.docker-compose +++ /dev/null @@ -1,26 +0,0 @@ ---- -version: '2.3' -services: - keepalived: - image: osixia/keepalived: {{ .keepalived_version }} - container_name: keepalived - restart: always - dns_search: . - cap_drop: - - ALL - cap_add: - - CHOWN - - DAC_OVERRIDE - - SETGID - - SETUID - depends_on: - - proxy - volumes: - - type: bind - source: /opt/keeplived/{{ .keepalived_version }}/keepalived.conf - target: /container/service/keepalived/assets/keepalived.conf - - type: bind - source: /opt/keeplived/{{ .keepalived_version }}/healthcheck.sh - target: /etc/keepalived/healthcheck.sh - networks: - - harbor diff --git a/builtin/core/roles/install/image-registry/templates/keepalived.conf b/builtin/core/roles/install/image-registry/templates/keepalived.conf new file mode 100644 index 00000000..e160c620 --- /dev/null +++ b/builtin/core/roles/install/image-registry/templates/keepalived.conf @@ -0,0 +1,30 @@ +vrrp_script healthcheck { + script "/etc/keepalived/healthcheck.sh" + interval 10 + fall 2 + rise 2 + timeout 5 + init_fail +} + global_defs { + script_user root + router_id harbor-ha + enable_script_security +} + vrrp_instance VI_1 { + state {{ if .groups.image_registry | first | eq .inventory_hostname }}MASTER{{ else }}BACKUP{{ end }} + interface {{ .ha_vip_interface }} + virtual_router_id 31 + priority 50 + advert_int 1 + authentication { + auth_type PASS + auth_pass k8s-test + } + virtual_ipaddress { + {{ .image_registry.ha_vip }} + } + track_script { + healthcheck + } + } diff --git a/builtin/core/roles/install/image-registry/templates/keepalived.config b/builtin/core/roles/install/image-registry/templates/keepalived.config deleted file mode 100644 index 36c11c2f..00000000 --- a/builtin/core/roles/install/image-registry/templates/keepalived.config +++ /dev/null @@ -1,31 +0,0 @@ -vrrp_script healthcheck { - script "/etc/keepalived/healthcheck.sh" - interval 10 - fall 2 - rise 2 - timeout 5 - init_fail - } - global_defs { - script_user root - router_id harbor-ha - enable_script_security - lvs_sync_daemon ens3 VI_1 - } - vrrp_instance VI_1 { - state BACKUP - interface ens3 - virtual_router_id 31 - priority 50 - advert_int 1 - authentication { - auth_type PASS - auth_pass k8s-test - } - virtual_ipaddress { - {{ .image_registry.ha_vip }} - } - track_script { - healthcheck - } - } diff --git a/builtin/core/roles/install/image-registry/templates/keepalived.healthcheck b/builtin/core/roles/install/image-registry/templates/keepalived.healthcheck deleted file mode 100644 index c517da8e..00000000 --- a/builtin/core/roles/install/image-registry/templates/keepalived.healthcheck +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -{{- if .image_registry.type | eq "registry" }} -# registry service -service=registry:5000 -{{- else }} -# harbor service -service=harbor:80 -{{- end }} - -nc -zv -w 2 $service > /dev/null 2>&1 - -if [ $? -eq 0 ]; then - exit 0 -else - exit 1 -fi diff --git a/builtin/core/roles/install/image-registry/templates/registry.config b/builtin/core/roles/install/image-registry/templates/registry.config index 64bdf289..a964621a 100644 --- a/builtin/core/roles/install/image-registry/templates/registry.config +++ b/builtin/core/roles/install/image-registry/templates/registry.config @@ -22,9 +22,9 @@ log: # to: # - errors@example.com storage: -{{- if .image_registry.registry.storage.filesystem.rootdirectory | empty | not }} +{{- if .image_registry.registry.storage.filesystem.rootdir | empty | not }} filesystem: - rootdirectory: {{ .image_registry.registry.storage.filesystem.rootdirectory }} + rootdirectory: {{ .image_registry.registry.storage.filesystem.rootdir }} maxthreads: 100 {{- end }} {{- if .image_registry.registry.storage.azure }} @@ -71,13 +71,13 @@ storage: usedualstack: false loglevel: debug {{- end }} - inmemory: # This driver takes no parameters +# inmemory: # This driver takes no parameters delete: enabled: false redirect: disable: false cache: - blobdescriptor: redis + blobdescriptor: inmemory blobdescriptorsize: 10000 maintenance: uploadpurging: @@ -124,7 +124,7 @@ storage: # options: # baseurl: https://example.com/ http: - addr: localhost:5000 + addr: 0.0.0.0:5000 # prefix: /my/nested/registry/ # host: https://myregistryaddress.org:5000 secret: asecretforlocaldevelopment diff --git a/builtin/core/roles/install/image-registry/templates/registry.docker-compose b/builtin/core/roles/install/image-registry/templates/registry.docker-compose index 1d76d926..b6746e77 100644 --- a/builtin/core/roles/install/image-registry/templates/registry.docker-compose +++ b/builtin/core/roles/install/image-registry/templates/registry.docker-compose @@ -20,7 +20,7 @@ services: - type: bind source: /opt/registry/{{ .registry_version }}/config.yml target: /etc/docker/registry/config.yml - port: + ports: - 443:5000 networks: - registry @@ -28,26 +28,28 @@ services: keepalived: image: osixia/keepalived:{{ .keepalived_version }} container_name: keepalived + command: + - --copy-service + network_mode: "host" restart: always dns_search: . cap_drop: - ALL cap_add: + - NET_ADMIN + - NET_BROADCAST + - NET_RAW - CHOWN - DAC_OVERRIDE - - SETGID - - SETUID depends_on: - registry volumes: - type: bind - source: /opt/keeplived/{{ .keepalived_version }}/keepalived.conf + source: /opt/keepalived/{{ .keepalived_version }}/keepalived.conf target: /container/service/keepalived/assets/keepalived.conf - type: bind - source: /opt/keeplived/{{ .keepalived_version }}/healthcheck.sh + source: /opt/keepalived/{{ .keepalived_version }}/healthcheck.sh target: /etc/keepalived/healthcheck.sh - networks: - - registry {{- end }} networks: registry: diff --git a/builtin/core/roles/install/image-registry/templates/registry.service b/builtin/core/roles/install/image-registry/templates/registry.service index f6e7f56c..27061352 100644 --- a/builtin/core/roles/install/image-registry/templates/registry.service +++ b/builtin/core/roles/install/image-registry/templates/registry.service @@ -1,5 +1,5 @@ [Unit] -Description=harbor +Description=registry After=docker.service systemd-networkd.service systemd-resolved.service Requires=docker.service diff --git a/builtin/core/roles/kubernetes/pre-kubernetes/tasks/high-availability/kube_vip.yaml b/builtin/core/roles/kubernetes/pre-kubernetes/tasks/high-availability/kube_vip.yaml index 72c0d5fa..19a3ddbf 100644 --- a/builtin/core/roles/kubernetes/pre-kubernetes/tasks/high-availability/kube_vip.yaml +++ b/builtin/core/roles/kubernetes/pre-kubernetes/tasks/high-availability/kube_vip.yaml @@ -1,22 +1,43 @@ --- -- name: Get network interface for kube_vip - command: | - {{- if .kubernetes.control_plane_endpoint.kube_vip.address | ipFamily | eq "IPv4" }} - ip route | grep '{{ .internal_ipv4 }}' | grep 'proto kernel scope link src' | awk '{print $3}' - {{- else if .kubernetes.control_plane_endpoint.host | ipFamily | eq "IPv6" }} - ip route | grep '{{ .internal_ipv6 }}' | grep 'proto kernel scope link src' | awk '{print $3}' - {{- else }} - echo "kubernetes.control_plane_endpoint.kube_vip.address" should be ipv4 or ipv6 - exit 1 - {{- end }} - register: interface - -- name: Check if network is exist - assert: - that: - - .interface.stderr | empty - - .interface.stdout | empty | not - fail_msg: "cannot find network interface to match kube_vip" +- name: Get interface from kube_vip + block: + - name: Get all interface with cidr + command: | + ip -o addr show | awk ' + BEGIN { + printf "[\n"; + first = 1; + } + /inet / && !/ lo|docker|br-|veth/ { + if (!first) { + printf ",\n"; + } + first = 0; + printf " {\n"; + printf " \"interface\": \"%s\",\n", $2; + printf " \"cidr\": \"%s\"\n", $4; + printf " }"; + } + END { + printf "\n]\n"; + } + ' + register: interface + register_type: json + - name: filter interface by ha_vip + set_fact: + kube_vip_interface: >- + {{- $interface := "" }} + {{- range .interface.stdout | default list -}} + {{- if .cidr | ipInCIDR | has $.kubernetes.control_plane_endpoint.kube_vip.address -}} + {{- $interface = .interface -}} + {{- end -}} + {{- end -}} + {{ $interface }} + - name: Check if network is exist + assert: + that: .kube_vip_interface | empty + fail_msg: "cannot find network interface to match kube_vip" - name: Generate kube_vip manifest template: diff --git a/builtin/core/roles/kubernetes/pre-kubernetes/templates/kubevip/kubevip.ARP b/builtin/core/roles/kubernetes/pre-kubernetes/templates/kubevip/kubevip.ARP index 05979968..5b7fb6ef 100644 --- a/builtin/core/roles/kubernetes/pre-kubernetes/templates/kubevip/kubevip.ARP +++ b/builtin/core/roles/kubernetes/pre-kubernetes/templates/kubevip/kubevip.ARP @@ -14,7 +14,7 @@ spec: - name: port value: "6443" - name: vip_interface - value: {{ .interface.stdout }} + value: {{ .kube_vip_interface }} - name: vip_cidr value: "32" - name: cp_enable diff --git a/builtin/core/roles/kubernetes/pre-kubernetes/templates/kubevip/kubevip.BGP b/builtin/core/roles/kubernetes/pre-kubernetes/templates/kubevip/kubevip.BGP index afece06d..b4be82ba 100644 --- a/builtin/core/roles/kubernetes/pre-kubernetes/templates/kubevip/kubevip.BGP +++ b/builtin/core/roles/kubernetes/pre-kubernetes/templates/kubevip/kubevip.BGP @@ -14,7 +14,7 @@ spec: - name: port value: "6443" - name: vip_interface - value: {{ .interface.stdout }} + value: {{ .kube_vip_interface }} - name: vip_cidr value: "32" - name: cp_enable diff --git a/builtin/core/roles/precheck/env_check/tasks/image_registry.yaml b/builtin/core/roles/precheck/env_check/tasks/image_registry.yaml new file mode 100644 index 00000000..0958e943 --- /dev/null +++ b/builtin/core/roles/precheck/env_check/tasks/image_registry.yaml @@ -0,0 +1,18 @@ +# image_registry is installed by docker_compose +- name: docker_version and dockercompose_version should not be empty + when: .groups.image_registry | empty | not + assert: + that: + - .docker_version | empty | not + - .dockercompose_version | empty | not + msg: >- + "docker_version" and "dockercompose_version" should not be empty + +- name: keepalived_version should not be empty when image_registry is high availability + when: + - .image_registry.ha_vip | empty | not + - .groups.image_registry | len | lt 1 + assert: + that: .keepalived_version | empty | not + msg: >- + "keepalived_version" should not be empty when image_registry is high availability \ No newline at end of file diff --git a/builtin/core/roles/uninstall/image_registry/tasks/keepalived.yaml b/builtin/core/roles/uninstall/image_registry/tasks/keepalived.yaml index 367d4ca2..dcbfa7f3 100644 --- a/builtin/core/roles/uninstall/image_registry/tasks/keepalived.yaml +++ b/builtin/core/roles/uninstall/image_registry/tasks/keepalived.yaml @@ -1,3 +1,8 @@ +- name: Delete arp by kube-vip + command: | + ip neigh show | grep {{ .image_registry.ha_vip }} | awk '{print $1 " dev " $3}' | xargs -r -L1 ip neigh delete + ip -o addr show | grep {{ .image_registry.ha_vip }} | awk '{system("ip addr del "$4" dev "$2)}' + - name: Delete residue keepalived files command: | rm -rf /opt/keepalived/ \ No newline at end of file diff --git a/docs/images/ha-harbor.excalidraw b/docs/images/ha-harbor.excalidraw new file mode 100644 index 00000000..0320872a --- /dev/null +++ b/docs/images/ha-harbor.excalidraw @@ -0,0 +1,784 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "o93_Uv5XcZbMQM0H30Zkq", + "type": "rectangle", + "x": 868, + "y": 241, + "width": 244, + "height": 59.99999999999999, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7F", + "roundness": { + "type": 3 + }, + "seed": 865016729, + "version": 290, + "versionNonce": 326982455, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "Q-e9pr0XedDsE8hLhtxpo" + }, + { + "id": "_oQQMRTunRyo9Zq43ZnJU", + "type": "arrow" + }, + { + "id": "3wbQCkbDLOFDINm5zzTS-", + "type": "arrow" + }, + { + "id": "LWBWVZxRHzET8YEmPb-f3", + "type": "arrow" + }, + { + "id": "DQu2mOOAST7Qj33GexWWU", + "type": "arrow" + } + ], + "updated": 1750302611172, + "link": null, + "locked": false + }, + { + "id": "Q-e9pr0XedDsE8hLhtxpo", + "type": "text", + "x": 926.0099983215332, + "y": 258.5, + "width": 127.9800033569336, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7G", + "roundness": null, + "seed": 1864202359, + "version": 274, + "versionNonce": 2119579319, + "isDeleted": false, + "boundElements": null, + "updated": 1750302514626, + "link": null, + "locked": false, + "text": "harbor service", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "o93_Uv5XcZbMQM0H30Zkq", + "originalText": "harbor service", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "KcVtlaVjZmNTnyoeRJBfq", + "type": "rectangle", + "x": 486, + "y": 245.5, + "width": 244.00000000000003, + "height": 60.000000000000014, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7H", + "roundness": { + "type": 3 + }, + "seed": 1227906551, + "version": 335, + "versionNonce": 1110807543, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "o1sccqOk7_faggHLFNheO" + }, + { + "id": "L8_xG3dqum2_YKMebNu2u", + "type": "arrow" + }, + { + "id": "3wbQCkbDLOFDINm5zzTS-", + "type": "arrow" + }, + { + "id": "LWBWVZxRHzET8YEmPb-f3", + "type": "arrow" + }, + { + "id": "cO9D1owMBo5ciGKj9M8W7", + "type": "arrow" + } + ], + "updated": 1750302607030, + "link": null, + "locked": false + }, + { + "id": "o1sccqOk7_faggHLFNheO", + "type": "text", + "x": 544.0099983215332, + "y": 263, + "width": 127.9800033569336, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7I", + "roundness": null, + "seed": 1568638743, + "version": 318, + "versionNonce": 1300714231, + "isDeleted": false, + "boundElements": [], + "updated": 1750302560040, + "link": null, + "locked": false, + "text": "harbor service", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "KcVtlaVjZmNTnyoeRJBfq", + "originalText": "harbor service", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "53tMOC8ghJAglooQgD-kW", + "type": "rectangle", + "x": 484, + "y": 126, + "width": 624, + "height": 78, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#a5d8ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7J", + "roundness": { + "type": 3 + }, + "seed": 981932439, + "version": 81, + "versionNonce": 428276025, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "neXgNEUOhJo1yjimmCiTH" + }, + { + "id": "L8_xG3dqum2_YKMebNu2u", + "type": "arrow" + }, + { + "id": "_oQQMRTunRyo9Zq43ZnJU", + "type": "arrow" + } + ], + "updated": 1750302564064, + "link": null, + "locked": false + }, + { + "id": "neXgNEUOhJo1yjimmCiTH", + "type": "text", + "x": 731.4399948120117, + "y": 152.5, + "width": 129.12001037597656, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7K", + "roundness": null, + "seed": 1816398713, + "version": 50, + "versionNonce": 212167193, + "isDeleted": false, + "boundElements": null, + "updated": 1750302564064, + "link": null, + "locked": false, + "text": "Load Blanacer", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "53tMOC8ghJAglooQgD-kW", + "originalText": "Load Blanacer", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "edP1PJ_ABStEloX-Syel7", + "type": "rectangle", + "x": 488, + "y": 337, + "width": 244.00000000000003, + "height": 60.000000000000014, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7N", + "roundness": { + "type": 3 + }, + "seed": 271586231, + "version": 393, + "versionNonce": 1107051063, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "WaP95sXUDIWaHJ8dD3VlR" + }, + { + "id": "cO9D1owMBo5ciGKj9M8W7", + "type": "arrow" + } + ], + "updated": 1750302607030, + "link": null, + "locked": false + }, + { + "id": "WaP95sXUDIWaHJ8dD3VlR", + "type": "text", + "x": 541.75, + "y": 354.5, + "width": 136.5, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7O", + "roundness": null, + "seed": 511870167, + "version": 388, + "versionNonce": 1016794583, + "isDeleted": false, + "boundElements": [], + "updated": 1750302602385, + "link": null, + "locked": false, + "text": "storage service", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "edP1PJ_ABStEloX-Syel7", + "originalText": "storage service", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "QnD-8-ujPJygThWv4oRRT", + "type": "rectangle", + "x": 872, + "y": 336, + "width": 244.00000000000003, + "height": 60.000000000000014, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7P", + "roundness": { + "type": 3 + }, + "seed": 303174871, + "version": 384, + "versionNonce": 384514423, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "zvSBobCjWHUzU-fOWcJLi" + }, + { + "id": "DQu2mOOAST7Qj33GexWWU", + "type": "arrow" + } + ], + "updated": 1750302611172, + "link": null, + "locked": false + }, + { + "id": "zvSBobCjWHUzU-fOWcJLi", + "type": "text", + "x": 925.75, + "y": 353.5, + "width": 136.5, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7Q", + "roundness": null, + "seed": 1388798455, + "version": 379, + "versionNonce": 1293090647, + "isDeleted": false, + "boundElements": [], + "updated": 1750302598218, + "link": null, + "locked": false, + "text": "storage service", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "QnD-8-ujPJygThWv4oRRT", + "originalText": "storage service", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "L8_xG3dqum2_YKMebNu2u", + "type": "arrow", + "x": 789.8272747713355, + "y": 204.9990705847769, + "width": 130.79362370312788, + "height": 39.02567346207175, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7R", + "roundness": { + "type": 2 + }, + "seed": 383988983, + "version": 166, + "versionNonce": 2021834489, + "isDeleted": false, + "boundElements": null, + "updated": 1750302564064, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -130.79362370312788, + 39.02567346207175 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "53tMOC8ghJAglooQgD-kW", + "focus": -0.2888910803214833, + "gap": 7 + }, + "endBinding": { + "elementId": "KcVtlaVjZmNTnyoeRJBfq", + "focus": -0.2441231343283578, + "gap": 5.5 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "_oQQMRTunRyo9Zq43ZnJU", + "type": "arrow", + "x": 862.5126006477127, + "y": 204.99907058477686, + "width": 142.14928077039178, + "height": 33.100855462394435, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7S", + "roundness": { + "type": 2 + }, + "seed": 72016441, + "version": 108, + "versionNonce": 732067801, + "isDeleted": false, + "boundElements": null, + "updated": 1750302564064, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 142.14928077039178, + 33.100855462394435 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "53tMOC8ghJAglooQgD-kW", + "focus": 0.2194976788477558, + "gap": 7 + }, + "endBinding": { + "elementId": "o93_Uv5XcZbMQM0H30Zkq", + "focus": 0.6222604211431018, + "gap": 10 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "3wbQCkbDLOFDINm5zzTS-", + "type": "arrow", + "x": 739.5702440443347, + "y": 258.96307786317976, + "width": 118.85951191133074, + "height": 0.014658463536704858, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7T", + "roundness": { + "type": 2 + }, + "seed": 1405197335, + "version": 135, + "versionNonce": 1501321783, + "isDeleted": false, + "boundElements": null, + "updated": 1750302560193, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 118.85951191133074, + 0.014658463536704858 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "KcVtlaVjZmNTnyoeRJBfq", + "focus": -0.5514950166112959, + "gap": 10 + }, + "endBinding": { + "elementId": "o93_Uv5XcZbMQM0H30Zkq", + "focus": 0.3999999999999996, + "gap": 10 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "LWBWVZxRHzET8YEmPb-f3", + "type": "arrow", + "x": 858.4297559556653, + "y": 279.2973724995128, + "width": 120.65385031474193, + "height": 1.916023220647503, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7U", + "roundness": { + "type": 2 + }, + "seed": 67343543, + "version": 140, + "versionNonce": 1144521719, + "isDeleted": false, + "boundElements": null, + "updated": 1750302574470, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -120.65385031474193, + 1.916023220647503 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "o93_Uv5XcZbMQM0H30Zkq", + "focus": -0.156993339676499, + "gap": 10 + }, + "endBinding": { + "elementId": "KcVtlaVjZmNTnyoeRJBfq", + "focus": 0.24342244771700097, + "gap": 7.7759056409233835 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "dBCR-0VHhAZrQsuybKfxf", + "type": "text", + "x": 746, + "y": 290, + "width": 110.52000427246094, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7V", + "roundness": null, + "seed": 1033720663, + "version": 68, + "versionNonce": 931739607, + "isDeleted": false, + "boundElements": null, + "updated": 1750302594968, + "link": null, + "locked": false, + "text": "sync images", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "sync images", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "cO9D1owMBo5ciGKj9M8W7", + "type": "arrow", + "x": 610, + "y": 313, + "width": 0, + "height": 15, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7W", + "roundness": { + "type": 2 + }, + "seed": 1108486455, + "version": 11, + "versionNonce": 745405719, + "isDeleted": false, + "boundElements": null, + "updated": 1750302607030, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 15 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "KcVtlaVjZmNTnyoeRJBfq", + "focus": -0.016393442622950786, + "gap": 7.5 + }, + "endBinding": { + "elementId": "edP1PJ_ABStEloX-Syel7", + "focus": 0, + "gap": 9 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "DQu2mOOAST7Qj33GexWWU", + "type": "arrow", + "x": 1004, + "y": 311, + "width": 0, + "height": 17, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7X", + "roundness": { + "type": 2 + }, + "seed": 572285047, + "version": 11, + "versionNonce": 1740299351, + "isDeleted": false, + "boundElements": null, + "updated": 1750302611172, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 17 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "o93_Uv5XcZbMQM0H30Zkq", + "focus": -0.11475409836065573, + "gap": 10 + }, + "endBinding": { + "elementId": "QnD-8-ujPJygThWv4oRRT", + "focus": 0.08196721311475404, + "gap": 8 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff", + "lockedMultiSelections": {} + }, + "files": {} +} \ No newline at end of file diff --git a/docs/images/ha-harbor.png b/docs/images/ha-harbor.png new file mode 100644 index 0000000000000000000000000000000000000000..740d530ec2df66a011a6038d0316dd8f5a3e50fd GIT binary patch literal 86158 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

9$|fBH9Hi`Td~(hku+Jj&&BSO?3pyv8v|7 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 literal 0 HcmV?d00001 diff --git a/docs/images/ha-registry.excalidraw b/docs/images/ha-registry.excalidraw new file mode 100644 index 00000000..4a015256 --- /dev/null +++ b/docs/images/ha-registry.excalidraw @@ -0,0 +1,551 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "o93_Uv5XcZbMQM0H30Zkq", + "type": "rectangle", + "x": 868, + "y": 241, + "width": 244, + "height": 59.99999999999999, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7F", + "roundness": { + "type": 3 + }, + "seed": 865016729, + "version": 292, + "versionNonce": 497225262, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "Q-e9pr0XedDsE8hLhtxpo" + }, + { + "id": "_oQQMRTunRyo9Zq43ZnJU", + "type": "arrow" + }, + { + "id": "DQu2mOOAST7Qj33GexWWU", + "type": "arrow" + } + ], + "updated": 1750924036450, + "link": null, + "locked": false + }, + { + "id": "Q-e9pr0XedDsE8hLhtxpo", + "type": "text", + "x": 921.1600036621094, + "y": 258.5, + "width": 137.67999267578125, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7G", + "roundness": null, + "seed": 1864202359, + "version": 282, + "versionNonce": 697610606, + "isDeleted": false, + "boundElements": null, + "updated": 1750924050371, + "link": null, + "locked": false, + "text": "registry service", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "o93_Uv5XcZbMQM0H30Zkq", + "originalText": "registry service", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "KcVtlaVjZmNTnyoeRJBfq", + "type": "rectangle", + "x": 486, + "y": 245.5, + "width": 244.00000000000003, + "height": 60.000000000000014, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7H", + "roundness": { + "type": 3 + }, + "seed": 1227906551, + "version": 337, + "versionNonce": 1529332210, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "o1sccqOk7_faggHLFNheO" + }, + { + "id": "L8_xG3dqum2_YKMebNu2u", + "type": "arrow" + }, + { + "id": "cO9D1owMBo5ciGKj9M8W7", + "type": "arrow" + } + ], + "updated": 1750924036450, + "link": null, + "locked": false + }, + { + "id": "o1sccqOk7_faggHLFNheO", + "type": "text", + "x": 539.1600036621094, + "y": 263, + "width": 137.67999267578125, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7I", + "roundness": null, + "seed": 1568638743, + "version": 328, + "versionNonce": 511754546, + "isDeleted": false, + "boundElements": [], + "updated": 1750924033996, + "link": null, + "locked": false, + "text": "registry service", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "KcVtlaVjZmNTnyoeRJBfq", + "originalText": "registry service", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "53tMOC8ghJAglooQgD-kW", + "type": "rectangle", + "x": 484, + "y": 126, + "width": 624, + "height": 78, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#a5d8ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7J", + "roundness": { + "type": 3 + }, + "seed": 981932439, + "version": 81, + "versionNonce": 428276025, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "neXgNEUOhJo1yjimmCiTH" + }, + { + "id": "L8_xG3dqum2_YKMebNu2u", + "type": "arrow" + }, + { + "id": "_oQQMRTunRyo9Zq43ZnJU", + "type": "arrow" + } + ], + "updated": 1750302564064, + "link": null, + "locked": false + }, + { + "id": "neXgNEUOhJo1yjimmCiTH", + "type": "text", + "x": 731.4399948120117, + "y": 152.5, + "width": 129.12001037597656, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7K", + "roundness": null, + "seed": 1816398713, + "version": 50, + "versionNonce": 212167193, + "isDeleted": false, + "boundElements": null, + "updated": 1750302564064, + "link": null, + "locked": false, + "text": "Load Blanacer", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "53tMOC8ghJAglooQgD-kW", + "originalText": "Load Blanacer", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "edP1PJ_ABStEloX-Syel7", + "type": "rectangle", + "x": 488, + "y": 383, + "width": 628, + "height": 60.000000000000014, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7N", + "roundness": { + "type": 3 + }, + "seed": 271586231, + "version": 458, + "versionNonce": 1441604658, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "WaP95sXUDIWaHJ8dD3VlR" + }, + { + "id": "cO9D1owMBo5ciGKj9M8W7", + "type": "arrow" + }, + { + "id": "DQu2mOOAST7Qj33GexWWU", + "type": "arrow" + } + ], + "updated": 1750924054994, + "link": null, + "locked": false + }, + { + "id": "WaP95sXUDIWaHJ8dD3VlR", + "type": "text", + "x": 733.75, + "y": 400.5, + "width": 136.5, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7O", + "roundness": null, + "seed": 511870167, + "version": 452, + "versionNonce": 81645042, + "isDeleted": false, + "boundElements": [], + "updated": 1750924054994, + "link": null, + "locked": false, + "text": "storage service", + "fontSize": 20, + "fontFamily": 6, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "edP1PJ_ABStEloX-Syel7", + "originalText": "storage service", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "L8_xG3dqum2_YKMebNu2u", + "type": "arrow", + "x": 789.8336419760351, + "y": 204.99907058477686, + "width": 130.72171598152477, + "height": 39.02567346207178, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7R", + "roundness": { + "type": 2 + }, + "seed": 383988983, + "version": 167, + "versionNonce": 798245042, + "isDeleted": false, + "boundElements": null, + "updated": 1750924028531, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -130.72171598152477, + 39.02567346207178 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "53tMOC8ghJAglooQgD-kW", + "focus": -0.2888910803214833, + "gap": 7 + }, + "endBinding": { + "elementId": "KcVtlaVjZmNTnyoeRJBfq", + "focus": -0.2441231343283578, + "gap": 5.5 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "_oQQMRTunRyo9Zq43ZnJU", + "type": "arrow", + "x": 862.5126006477127, + "y": 204.99907058477686, + "width": 142.14928077039178, + "height": 33.100855462394435, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7S", + "roundness": { + "type": 2 + }, + "seed": 72016441, + "version": 108, + "versionNonce": 732067801, + "isDeleted": false, + "boundElements": null, + "updated": 1750302564064, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 142.14928077039178, + 33.100855462394435 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "53tMOC8ghJAglooQgD-kW", + "focus": 0.2194976788477558, + "gap": 7 + }, + "endBinding": { + "elementId": "o93_Uv5XcZbMQM0H30Zkq", + "focus": 0.6222604211431018, + "gap": 10 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "cO9D1owMBo5ciGKj9M8W7", + "type": "arrow", + "x": 655.6624775795378, + "y": 307.58611094053396, + "width": 103.19328237376556, + "height": 74.33503752082942, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7W", + "roundness": { + "type": 2 + }, + "seed": 1108486455, + "version": 120, + "versionNonce": 1804812210, + "isDeleted": false, + "boundElements": null, + "updated": 1750924054995, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 103.19328237376556, + 74.33503752082942 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "KcVtlaVjZmNTnyoeRJBfq", + "focus": -0.016393442622950786, + "gap": 7.5 + }, + "endBinding": { + "elementId": "edP1PJ_ABStEloX-Syel7", + "focus": 0, + "gap": 9 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "DQu2mOOAST7Qj33GexWWU", + "type": "arrow", + "x": 966.2341709724777, + "y": 303.90007395282873, + "width": 99.30046503552558, + "height": 78.16233299063248, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "#b2f2bb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b7X", + "roundness": { + "type": 2 + }, + "seed": 572285047, + "version": 91, + "versionNonce": 1177844082, + "isDeleted": false, + "boundElements": null, + "updated": 1750924054995, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -99.30046503552558, + 78.16233299063248 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "o93_Uv5XcZbMQM0H30Zkq", + "focus": -0.11475409836065573, + "gap": 10 + }, + "endBinding": { + "elementId": "edP1PJ_ABStEloX-Syel7", + "focus": 0.07278735375547067, + "gap": 8 + }, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff", + "lockedMultiSelections": {} + }, + "files": {} +} \ No newline at end of file diff --git a/docs/images/ha-registry.png b/docs/images/ha-registry.png new file mode 100644 index 0000000000000000000000000000000000000000..5eae82625a015ca4e69aca38c414c0a26c77a32b GIT binary patch literal 81161 zcmaHTbzIZy`!^+u3IEP>=?dlJ1gFx{3OAaUG*NR@R=*)=oGlXN;IjYHC9tK453C#|4rReo(9}*Ce(C#sv zI#z<H@hp%Enx=HeNwE6BJK^Rzh(Ym&!)&g5Sir3zB zdda<8S2opRpb~GJg;*#S=nK$=EM*527ztNBk#%HCR$Gz;3xp3uX>#b$qjzS;J;4$1 z+ufJ!y?l%75eqZpXwmQ$w0QFvYnAeMkf~eO0{5reEW97ZK*qa81VNmx6T=8(1{_-?X&J7VD$s&yEubCJMb`|qni;a)JI@#z}xHjD|@cF{(XbDHu^?UKuJcbIx z1u8XrWk$JEyp=?RRp%a&uk38E3|n?5a^@_FxGgGZXlRhHh#*c=)lM2h^1GhvQ#!sl zG|wR(m-4jjRoCk)tjYuertNRh_w619J>OZI+}!Np>!EjUx?w+7s_5mA`0zA^$$oq$ zT4a${WN$vfa&4jtUS-~K8|3LB!Cgok$?X3lSbXC%Wsddfw#Y8N_3a(=`J6Yr@k6=t z<9SYDXnR#sT91{jX51_nrfExcnNWl9KTG;cLxP`N9n2pdf8rLEI{8-Vuv^>ImA7>_ zrR6{t-MEw)J2z~6$-E-oVGPn-yFO(!<-WpJCWedEWrQg9P#EXQLi^!GwimV@sPfSJ zZRP279FzopUKOjzt3_j(566vW^Vkz(l4^RUm-L(Up;G~+oQK1ZXoS8s>Mu`9X!OE9 zyf(4{@#FCE7_)OrtyDqYO1K*%m-cLjcUA(HE4f_dZ3G$i$$)~5aFt2vz>dB-pljhE ztCc!B3)-1XPva~azk)-N(D%&t!a7;zk_C?r4DRr9eL0{PqYu%4v7)vqP_?7Hr=NS| znc*&Yl?!=OzYLm5rFOwHJZUR2X1s2gL0D@9Q9dfgldf)p0htTP)_n=u_k^m_IciRi zYCXWS-`NS{yrSOUg`H1r-(Fd8EF4PF-_SQ@Xz`Z7>5DHAZAuJ8;grD7j@$cvDSIL$ z_=I+{k5(@~v;0m~TVTsICimdbJCl!gQF% zKv7F`ow^4;25$K(wp@m-!zOEzx{^2e#`H^h+{&@4Q4tZ7X!fmIGO{F>mi1UW*fq#nN5wQm4hKjhOXHu*3oh^8H^+i~0V7rF zF*Z9j5S10uEoSRE=`B%G-2mf2OofZHAXAd7RWQ->3m(mm=|>{w8;f676C1QLer- z8!R>sKOZfi_d()3~(KAG) zxTV!*UEy=ie0uxK!{QBhj%kYXV&tFg5~U^}F{3d_3b`=O@7vY>2V{lOJD9rdBC|2pU+A@X^x`V(vBS6u5%u(hZ8*(je+l& z?`>$RK3)369_}G4wqPMbQzeeeV&~eJBs)V?+!6nsj&QF$EWQ2UAw}tYfXmvHRIQ|g?Kl`E;Nf=k;-m48l&yoX>_ATC9TtwZ#vh5?YIWt^ z&QC1Ahi5wI$#96>>GN=|vqEu-KNwUE|UsPHLs0owc@My(JM(5gsb$e8q@-j)ViR7P{&0f1H+-;LQim&QT<-9%Pg~mLl`s#ZlT04Q z)LOB7mQ_-m`Io2pU*OQ0+?q@-Tm9pWqCnv4qg1g4Moun7)>v-8D2lrgkA~*Ugpk@M z4Jtrf|syXQT;}&-@iSNq=v+Kx3u`4`KVtaAA+gQbxka zVmwmfHgSx|JzL4s2RcF$3^o$(nWte+x^#4?-i?Osua?{s>eOE#Y*$QR?_x`Na`oI) zvAOWxWI_V*mcnUnQaZcfyn{)@<5{20fz1Ud9|z+nJf_8zHAP9!Hb?_mci(B|{$vaC zxVk5I0H)jzLD%QCTKu2T_aydHA3g(1+fF;cRJ0^GrjMPau$*o3ffs4ywl+OcDXk`$ zi)T}sZ`$flh@uzX=avKE4e8t#20$w}Pi-yMnP^(bF*XI$tOz?=10e@R-BsI?a=YPS0YDy*7Jc0g?PBz zy&EW{JZ$qD8WZoQUw8Rh=CWLWyrv}j(?ScKJ3!TAy4GT5e~^1@t}VdJ-t&npU9FZ3 z*%$~sa{HPcBZ+r?@g`W{<}a7=pAdY6Js2~y>GIWuuknXC=PcFRB&~1*a(>umH`nIg zQWlk*D6uqpcCL+O8?CK3iGOj~>%-iI6VWg;X!L_}3x7#=D3ELZx0Y;0xsdMxW9VW!{ zMS^@A`3a{fL6Ec~HLd8rGADQG9P8W7No|9sFDV&&|i^{8S0JPbB5LtFkl&^Ikq{-TmTf9Guwm zF*>8>s@VvRkDZD9x^U7Jb3Rq&MW)k2IYN@FB-e$V7ZfL(&C}QFJQGYB`w}uJh3PKw zmm4*x7O12z($Bmr%;4}?9ozcD(h(4u1lwbdD}+Bn{N{$lEPWi$@vCNvPYQdhd_}wo z<~~(wSiVx)j8;MU9N`xNQ#{0EyImbp-P^7CRZ|7N2=DeEzIsf9dh_3a{vR_7r@X(I zo`OG*Zt#rfon25WAA1>jmR9QczzrGnDv|-E#CmGjN=OoaA;V|A4Awh-6ac-3*hy~42zSNLZx|8XP15oc7716zJjr3r3bFg5gG zx47GS-+5LXslU%C+5N|%X>$*jdia^X^U69bVd#7Z&J({lX21)M|$%B2~SGcUeK(N}?$DR5?&nK%bVRyD^{a^A$k^DPX``>aXm}YBb$-q8U zsL^7SO3GhGo}uMX%~+;?SU7w15r01JROKZgdPmY8Gtfpb_mYhA!3}lV(?vap%>T#7 zvqQJ7-s!em@uO#(r-z#l<5SB#8h&!|Sa^@HwIRfI%K@Z1UaJALG@ zSq6_g6aE@0PP+|Q4T}4#^Tl+8YNxi$GH_;}F~Gk+nxB=hoyVwtmvo{Lss87UGRfAc zN&d#AqY)KJLi;8nqPPeuPI}rLgQqwupN__7Fy19>&p5PMrag5p?*vDcBrkHy$`M7{ zkC*pN62kACIwd=Z^v0_A-+Q-HP7tt9ZwbCW)^ixm9S z7IHDVr?y%2g~-w}zuK=uH%r>&3~hrG_7ZL^^`I(g z@3ZC~oT(n4CW!Qkl%;%iE=-Yo#2dX`Yq4ml>K)CCTl(OFG@O< zMv7yKGuEujJ?#!2Hgv9aRVbnQB^Dw}0(p!nm~`Klqi10{1ugh$?kq7Cio_(H3Ek$9 z>k7G6WqFEk#^8>vH{hVbE1G~nhGJ`5U$!7_*GOiVVVmXU_A|#Ga=!dWi~*_01b?h* zc#`%}e}%w&@M3$d`>o#}i?H!;OrEu9$5*6Dmc11NdVc<*7B$9Exc{~UYyjQ1Pu*Ni zDDXQ8iepUn!=CK+oV`7Y0OI~w|J{SOxM`cg5AP#s{i-tVqvc)I+u9YUISs}2Bm)*U zypiM9c^E}zInsa3l(bE-1oQ=Q(4W114*%)u^HJ!@ne2U5DtpjVrS~ zb>DNOEBJxg@Dx?%Oq6Vo1Wv<=S~>k%ewvni3S8Ou8)kC}6P@hQLvw#6oF;v|V)LeD z4knZIU&g*Dv31s1j7z8G_H8{o(z$3xF(P~?JKsMcOYAVw!LgSUNIX9uFV1L(oHMhX zEePT0gH6`hhdE4E$^i<`XPJ**w{V-Sw`~?bdZRQC!J8&oDX#k6cKM%~h}9zU^IGx= zdcM>@!)&Gsk{_h|t#~Xsts+v8Vc&}H-#G14&`1u!SwC6HU7TsYH&(N7ZR~s9m@BHK zD|LK!HSc-wKRc!_NV2m&3EpBX8@alYN7zm*BIP9dk9y97rNI#FeC052Eb{^Op6zsg zinagntiQ<)W?@u_>6+7TWeUE|5{n~jH->tS2E_#P{uAEUDM<@^h+wR7-lSzp_U>UW z|AP>N)7UBlO@Hu(Ut;J4(*-1@eS9n4`c{m%)Bq{4P5s+LbVf?2goHf?#L@dYm%$QZ z@Jm7$`TurV^?V|FIz8dg)vH)Dy=iThv58bXjHn1*c(;0FW>MYIepr835|(fUNy^UCG)O@jh&%Ob=;%vkX;T ztvTdny^7nMML_dFF#%)jQjEjJC83%=b}(438v?%P8jF>H+fQiZAo+gV<=Av0d;$rr zn=Pq%K2fCK4vE@OZ9raEpV~{48^3V5y7Syw_)z75Z&wVU?wJm^4WGVXK~vPB#^mK9 zoAoIqu;R88d5vORD|JU^bq+h)d+@0l3v`EbS2Rz$zvYGV=kun69xlADqUm~Cn2G7R z^mwAtqsCw88{OV^pqdd>uwsj9D7$z0LPY{Bj1kk*6Z+D4`msei)x0aSBXq|TskgjvY+*B%4#NE{{aelQh_ z*i-_IdqUR{dwq+4|J~H>Pe@Bd_1+i``xu3X^m67LI!xE40H)0j$cUU3!I1ZX2fTnq zD2NQyv}!sorefHEMHc}954>ueKxAizD=KCy_T?Lk%@B-R9J}$I?*v=e#r@MK zH+H|99;^6Xl>Dpe_0rMScvb=~%TN08SlLb<$L#VY)9W)M6(YKqH^o|f?ptPC_vMIe z&O5{CY4vNTO$4^IhAMLVn;z{mh{9F-Q@7?*j=rrZ3EC&y4C}6o+iExqti!fT29#Yi z@VQ7XL5}DY(x|k~;TC8&jeae@RHjLGSSp@Pu%L5t9LdYtzZ(r+5VMA~>=17^Cp$|V z$)A{2#g>Y?tbNcSTtc`DKOo6sZR}ODEwy!g%ZEqqi!R@*>^^c6MTXy+`RSEn9}?~Nv}LoV5Je{W zo;Ba3i&-myg+IIg+86r~sZIMt z*}-f!(Q6*eah&*eZN|QG0V5^CXX!G;>0rEkv4iXqa#gi>%>Iy2+u9`H$4p3OK!)#L zR3^Sic+v$~V-GD9d((2Dzy$Sq0{@x=tt4G+m)bU>{OndZJwCZyQD62E*7C$H&3_Zg z5l>39E;+H(H^weDF#8+~LSTfgS?qa}8K427$>#QbAfE^i;>rkbCe=PxkH)gWAif$&61^Kb%UF@@jtO6}BE zF*O7$Dw*$xc!eBDk##bVaDu;vQVca3+l(k^`XCGYSUTM2*^yTZ3W1r+ov zyD?K?8*=Cp(e*hd6&X@(Ip>cMKQa+wyh^2xH~IPG9DAc9mPoINE_ZACKz_JKihF$f|U!U$ic1ah5y^ zv`TG3oRwg<=!1wauJz<=AwR;$_L)YWFPBcLnfS~YKmuFOpIaU1zCKYCgUf{JEe0M1 zgY5gmGF>wxVauY!(d?zBu)*FZ{>PK}GOriZ=>q%B64*NHK5oN=*!fE!uYAz5o7fKB zO^GlDPB5M#PIb%!k3L*;=>M&uAw*}pyG>iZqfL0fAgiyM%`--#W76$^dPBR4Aktv> zy&}8~;A!`cOikiKo}}m5@LP2jIV&LBVp5K0kGX2%!p2U(il+Tm=lSYsW-sBVhlT`PRFE^fpJAs5%?ZQ2X4oqSi4 zFgpubl{lak*~#FtSbZ7T^*uGKGj?v^hd*@*O#mD70lq?&v3U^F<9s+DlX;ii6_r9t z!hARxs>?6F^XAAa3!+C+1;gF@U@-I!B!(&UD#Z48M@;?oJ0UC9Wbv*@00f%!_`0}C zu7x1&gd4`sFeW>B7{Q=P|E9sz9i3pj zjN81#bin-ai-mOFPXne-d}foqRo{@K z4{B>&8y&Crf8i_+MYixQDs;4?Y_RYeDldJEZ0VYYMj#gdybhbGihBnQ7q)@-f)mHE zux98&iDHFMccy*claYm^_Y{bzspikVZQZi(BhtkWO(=X*%tNU-eN)-zf8kaiWzuT_OzG|m#3 zYok$mxBc$g4}To~++W6)=?7A?_|AS;1CO%3|4{=ah9G6Qp16=V`rb${t=3^K6#=oIrsj}Z zm6bgl#W|v<}z7_hVO!*0D&0OQjHQMx(|Ok5E0a0K)>X(deTU|h z>KyY{4Gul+m;S%P+)j<)7oWbK>D*&ByJ&JfGnbhX@!(h1<8ZFj^cz?wzsGRea|Jw> zYuGqzUPuK5)+yDQuozXZ?on$eZbM!+d%dnqV=-kG1?%t?)lcCVUF9d5)u1iX0m0kD zrfLuAAVXf5l>&wphQcTNl&L=&j4ac*6!3fW1L35fAWY)oV0QTJ1TtLq*}Ans+0`+r zTeo@=#wu;y)PnBZkzV6;Kv?9op!9fm?v~UzA_SczQmJNaF3*B&)OX(-mAi1THP?r{ zG0e^($mNZ(+Ign=Sm0+2-RTqj2|z2@-y|}9Ws4L!?o&MblStB8FTK&dX`GHVaD-wN z8|Oz6%wX_>WPEeT^W#~G&GI^8OyOLX0HLfGxNc#Fz}AGgcy$D8opg!c3NB%@mP+x;vbyC98KE5cD>;dJYCq!0ss8b-W@boZ*_Zdk zKcb9k&m-8Weg*g}UL@yHBz)4U2cbS5JNG|?C9TI{iMh}Iio{2pg5mH9-iG=Y=*4t& z6*A3ZS@K0d5&UbfloLcjNFPI|?6C}8-3EJ#zPZz@k$UvXN436t_3C#3QT8N?+|R)F z(CF?zpY*J7KTCPN(>;(fiHZ^fEWvcGqHrY=>; zZ@CtO&&~6+vOdBA*t4dlw)ts0+#su)RhT_c&m@7`QDUG-8Bl4RITbPcu_F9LEI+;< zoPzc!Kn#PNMqE?T6&O6kMs}oJQ48fa0$LW6@+e&4594K1tLO52>v`+VuSlVhOTEzP zu(f{y6m-XBwg@9sx~vbqd#81oJkj=WGQkvg*KMs)uUi=A z^@gJlRAV*7fGfj5Y`L6+sss+P_e@mC!fS*mF(D9->=%f0g6m8pVaf%Tkd|;lIna0^ zS~_$0Frl9|tzl)EvjAh}Fq5&+`@e)udUdRXrYKg4u>Gr}4H0x*ZG=r;=ByxXh_=E{ zen_?_nfvl2(lG4_O#gxK*S8z9TvUH0qLG;C*nCGl%p(8w!AYoJVPP5Tz;5)CjhE4E<8U7X^AtQZn%#*pN@% zo;Y%CLlf14Bm9XSwVq?}oI1l49*?!3-#f-vt<@zbkuqwPrkZJ)2971%`;?YCQQ)Sg zW>{0tC|<*QZ>xsvcr&re8OYGtjt{U4x&$@};KXh5wU;&GK7bds%}#T27ugkTFyRS@ zUgIFGsrBO#bH{F1mzHX?H~;WbO9LhFctH=9vuZ|>ZE9Pv9<7$Ftlb4mAg%3gy|G+6 z!#C?|V$z7AsdlLMVqd>v{bcQZjny{?pKs`_o8+5zPsyeGvqUvAj}W7q%L6bTuBCw= zwI6@y-}5QbhauNVDQ=}$@h4XponNzC{R}C$RGW?OHQV-e3Hy5orTZwox2m8PXb$Jl zRqvi1w!Rq^fP4rT%kUCMK7xdCtTILm2L(@SDj z06WUiQsvtQxfcfD*hBa!k&}X>yOH6s5vB# zD@)&sAvjZ3zrP;l6A13kVRHjNd%BO(?*86KYSFqa5*M)kG=7h$CaRxC`CEcQCEP_e z8-)+DwAN?n(eXKKTjDiPz#gX!8yLQi{v_(LK#x2I+XQhf-(P@dbyrsuq_w6kqPVMs zk2lWxU{?I{eWq14s{`uRkkF3zQy+X#=ToYv4J!io#?+2)os=na1ew=!bBpkH)j3y(AX=9icgF+o5q`=RQiW}EY_2hm`<^&LMM5eV6?j0`W)@tA_6mAN-gy zzNI^0acd~&lzVTi-uPLgjmO}d4P}TvEylB@bUEQ2spChgW4xJ5so_OPwPQRAbM+1B zY{SY7D?j+r@2KDs;i0ATV4RX5Z4c6dX=M03e0BWN?3wu8XJ=e2e&wklM2=8zVa@O< zS#aHgN$r@Do-&-$qqpxB2* zicEy|ON<9waUPcPNH|RlK`N#@gbMiM#6yZ-4gwaga@ThWIb)nb_dV(hC7SOX>`1>*V- z$05o3HDfNTspgKaSD0Gfbp*Bzw^#_bsfl(NzBtHV(6X8xexGGD7`JjXH84nk{(zKx z)_iFLl)67vv)KH4pQ7jULt!|b&+NU$Erp$U&%-0Bttlhfj_of-e4VA2j+Q3ZI-Rtn zN^}{a;V`83vC)OJZzY+AR$4>n1@Z37%Qb7O8NXP-*`()}+1+I1dHc+`D+5>=MXv9* z(>r(KU^odREtc;}i%(pN3f}CWIxcH=Pmxk7u4_eLQB>Cq(7xy#!CM~Tt|Jdq?p7EJ zA-Q$Rt((t5Jvz|ro!_0*0@n;I9bdl_>~g2`5S3p!0#$dNXR!NG+3PzH)gNzRb=7&$ZAU-7IkD7;jcp9dUshB|c2u`M#Z|`Q{LBwBA87wP&Y`Nk!LLJz z3m-&vA8iFIOgO`da9mz0!ib-Qg6~KUC23__EV?5niL5u=5D0R|-G`+Jl#{zS9Jv zoC$t!nsj3BxboB^t(@gza-WB@^8p+R-S2hLGA4PyaMk~P@8p#_*O^sen_K%PYoA%2t@wp( z;WwW)mar9N)QZ`e~mF5`Po zFKDsEOV3%A`C~V4w@&1Q21c+$74UzqzYTtnwKr{U@;M8%tiu&Zl0+8?8^}1l5dRn1 zT_^M<{>9OY?b!sZ7_-Rj<_B!Q?Dl^r=uf0VWW~Rz6I2CM%3w0gW(hP|WT#UO9$m44 zS4UMC0@%-aQ1gY<%h${-NX-=sB}!y(gfg>>OmXQS1-n&&e3Pd08)k{ z0&}2RxCXGuO<%IX11L3r*EoKcB>o;XP^7Qb5i>12xWs?njTV&k2U^vm%lC_(nh){e z;`Gv++*e1sB!t}hNaUFRG%sqKF?KVm=ksF%Mpf|irn}CwPp;pyn_tl}SP2-A5dN1S z|5GhK$8y;?+W@r#>u#)8hQJBs7!AhDjY0pPlIZ2TA$Nc>F#_Vz6M3!dUk&|66o77m z)Utgf`QpZgJTbEfVVlz{vC=GpM19lly~+;_Y}iV25Z z)+TE>vhJS#6$`~|Al@*rYuxO!0yY#g+suWeH2kla{N9dW>0s*h1H$%CpCVuG5M|M@ z-(hWDo*0snt??d>=ReHmKD~>ZSBkvUiB0=6CH(wtN8@7S2+Y+xQu_C~Z>8QnRV*)` zTN?RpdP3(Y`%{CgLa}w z^NwgNHV_x>2)p~IZOUk^S3!ZOPDDwmB>IF4bC!Z(8FjqbX!>W8fC~}5F7J+x&0uRw zO>Kob)lCcT)(N15YU-5&`l1S#ymoqTz;bP(_#TcGLB7*n;Ae-0XoT@&hP_IhZiZEYp^)gNx9nE0=qi8bwa@ari4X}r&#r+`LtI%O%jp$66P0P{*&xK{`z4q`ht#R zdZ-|^*@$ZN^?Tjp<9k|2T>hUZJ}YDZ9kg4|<@4(+f76LnNFmZ zZ87@5^kX)83MjPr){R`kcHp?h9z?>q8(MAN!~Q2;C5w8M^v3v6RAR_?7pjIt@Kri; zekRX}r<(f9&aR7}^=gLw3}t^JSpQudfZAi?v-%Wy&ZypD1t2hy1m3N@Dlvqxj~3rl zFuib+H~e|9JcIAzI)jPNiibwu|9)-&&l2NN*2fZF8jjm~Aa8>f<0f>aq*kSS_hY22LHF31B{9Rc9X0kq7(yhP3``veeT_u8&fsVmFC5 zE37lg7Y(MXDk@B3vaZ35#7p`Uh(U2 zhf|z9xU?f__S4nI zI2#~n>XvWoYq{+1ZF;(CYOrw>| zO8H-7@e2Y^yUmZqS}%OWWbq0X1jM_Z6Q1?X-NqoLEK{F!a^E*&)ESKfi+ObeY-&D$ zL|XnMu1)QrAhL0D3Et#bc)myTG($uX{DejyFd0p_5s6LgNH~?J$4HUJ=7^S>jy^BV zd2N71f3^vrz0wIgWt8ey<$T&0f3Ih%dL73~cerk!pIzC_ZlpWGcmC8kBepz07lH*uus_s|P85$J&2kL~W!R%O#YRZCAe<-s1| zBhG`jz_$}m>Z3=Pl|j;jXz8gMT-8Yt`-D?&fi0Zxg0(f+l+>0m{Mgw}y~?6dA1b}%eXK_V~`i#+Cq zM)@imcTqOeQ%=v)*%93lS$#<*#!$d;X1h++7NFh@yw2)tUYuCZzeVF0&3W0rr`$a4 zuCVWdZI8HI7BwGAyu-p9{}e6m*lyQR+%bKr^7&LPZ+A&Yx0n!miETY*ymQ*i@(u2W ziPTZ;W|i%kLPuy5;*yt%c;C%QM>`#;EEi9vL*Zxi95y511L|{mouY)Ygw{+srBdB= zxUh33-N2o?wWTx){m}1qbqWXVD{)%m7LEA4I?d6jdv?Oh{w-^hbq^_An+@B2>a`@t z$lOqQA~dREhTRP1FRFSrt33(T8rDA=eR+~w`^M1P8MM?t{aUL(#bMm*HoJI7l9N== zO_7y;*;2Lez;@=hP1@odii87iiF-)c*?0ar64{NPBU`D9E3Hp(64v^fr#&ZIN_j>R zA0PV-!gG0C<@-5hT^Crw^<8x?;hl<-FW%&Z&$xShUKD<7 z{O50UtC-=X%(Q)%K#O6VsO}>|ct+WyL*W3%9s#l{W^+oo#2(rDO557f=l%leQpW`A zsF87#(nx5zXJ$VWpc*NyVdi1^^#q^dm4qGX>3f`2^lH8?FwS+(r4eCATis%zvZmdd zXJ1BJ!Bzru>m6`&^Edf^5;J>N{2SIC?Ur`C`_Fvoosmo}vvw=<>-j0pQo>`=KANSJ z3j-JYU+E0wrN^aJv$M$}d$#I|$F`(~?Wwp52k!K>_jIhLO4SAJ34e(6$w{uP?#uH1 z5-d$ZcsNaoe0b$+(Tl%*p|mR5{oro>Yj>$DN3!#da)TAb?yu$Qpv4;yg;LHa)-lpj&Naf+dGdk>K(L^8s#*mJjnYTTl9`>IFykWUiKRp=J+{ zA7?@rR;sFZ1m~=|q;|N)nwy$*Cbx&TWrPPk+EI_aqV$9(?^&vdphN>qXQK;j@jHUg za8;h`5KlTxb0K*dMx4upwf7m6HjX7>H?j+Wytfd7$61+Oo}%)1bvr zh>9oWyN;6OVMJ)P=gN3>vxT|b5wzH-p?t=FtIu^*N6#{^dDZTwHBqEc>&Sbpg&}$7 zB;e4_wCeYNDoJmdpMk#$GyN-x9&rhN!wczLQ_B&P8{cMK0v=w@5OJFa9At`~DM&}i zdDel$?H8~1zy2Uw?tHDy(1U(4jQEM?+Xm8Fx#$~3!y@!%?p`~<$>)S{N{()MX3$Ng z6kZSO=f4rKfAtOkO#SC;ZHMKerH;Hs7812AfTPzU(*xb^rE(;+2;wI-R#Cla_mmd< z(mCGH@Fg$wq$p`<#9gDI=|F}o^7h?3HK5R89jr2!Uzu%&Zm&=4k&<7(3B*b%gv6xU zeQhNhocDNJ-*(%b9G^Gupa2-LF^S2^kKbXR_4{I16+=kL^8h#vUitJP<;xMAaAQk% zcegkW-Q-@*Wn`Ka7cK-}u~*^E%>uFGv$}TRj$8;=^z&C`395S*mY)jjrD`-foQCiA zGyiv%=L!8DUggPoPJlNVK>Oi5-Zp)%4##;ycP7EiiPY>;ItI}7h<+JIZEX(a0CfW| zL(y?hW`t!3d}hzrcnDMt9Mf-bTT$ptHbKTx$>WJb7BCW;1hsvxM8516NLmf|Y`+RlrYpAk%rC^b=dZUG{%!-U7dqF-# ztyjrkPIiwfNv$+%b+*4|Al#8-mV;|a)oc8DA+!Qv32&@NO<8+^vuh(Zhs(4yL_n&8 zHEX^rnQgUK3QF;NXjH`1Iju1#E@eijLop!KIFU&Y$odD=*-^5D3QMfQm};@O7b8!D zxW`93_{OKh>q99eGLB8hk zHUuBe#J=7SJUXbIuDY;_PD2OfnxNL$ezTN2 zje!eK8u62Zg1>usM>Jfh=Jg`NZLv38JR&zna;jHzB0j2FtK>j_GCG6ETtX-e8sDp_B+MLI#Hl@voS#H2e zLBvxEkaHTN3xl|KWopzecHC5~rx+W$_w*7XZkW-<0a(!q_FKRCi*(mmTHnejr~M|- zOtDtl4zsJNKL_B$IMND28o!k-;5v!F>SWkRiZ#FX@U?7{FnAbvOqeeZzEcfSCywRP zEp;J^-bd}*<-=RFef-ClnBBHR;LGl%Ca zu@yx76!M7qFD9C0^o*erK+3U3!Z2NDZ=Gyu?>B{hapuA&Ar8pPDMptOwy}Rm)*?Xj zsWo}Of$L6ULLB}Y(tk^Zlb1L8Zn1f^NPFu0`(~{{3XbYz!Ty)^n|3PS#xGP=0&a z)d|{Q0BLyrCVZ3s1njOf_IFq{c?f zsr5~y%dH3J|6ZUGS77{g2lPSTey*3g(V1jkPOwaOA zu8LVz;PH`0S~gHNve1zBDyR>M@-_M3@^rbd&SvNn*?qeo8p7Ui<2jFp)mvii_I^9A zb`sM{bq~EFe=n6ZuvGVcJk0I+)z?=leVBiv!T!PSTue^{6<1TL?JU@9)~8?j3xHtd z8@zdTjwSX25uge`NEmY0xXYjl(}E26?G$L3eARL0mwiY<8k>nh(m2Op#LrQhB^?@XwYZKo{NY@Fz%{Kcz zyyOBXI{R`Fz39rt4&dUQG*6G@Il%WmY$&X`jtz8P3(DmkUHpmJurQw(uC~HX+MkB2 zh>eIjVE0|q?)NtW0SCJZtdiIfEfr~v6sZ~+rJE0K-%vL{b9c~&FL(^qmo6N}q*P(j ztPI$c(0xf=$2JNxr>R;_cfb8vIkAbN;0}QL6Z(&k&A$M2<;m`~W#V7)56O84Bn;83 z*#rP6tj*>s^vwsGJu2!N!gfzXlBKP#UMWf<+FI-r{3t^%Y8R_+&GAYCNMV*p80dwa zxB(~NMigD5S3xnIv0R{uri+HS-TTFByC)MwV6L*8xXk*qr#b~Q;3T$HNbn9>Z((A}6;K zaeTe+{p0JPqxw%AFt`}Fj!K`ZTl}|Q(>&jsDkz`n{hiDQP#n!&PX2Zn(wtSAF*g0#g{!n9v|TrfILqC!&egOf02%m zq*z~CI9&1K{Z)I0PfQ^E&OMn=0f+mkLFUh&SJ~1mxvHhfmNnV z{E29@uma*I_(|axDTPHnE(rZ$AFjmL#nUkJ7aoVHDEh$HBKwBgby!6>HGjYu;=Zx) z_o;gAy4F&In%?$1o?o8>LC-trNk}`SVh-H=WOZ`LW$g;NkX^c%7y2S1v;QsN`~c?$ z?98%I(J!P=A5gBRU;c4*wiil)L+DKYKV*DX-xtEm=Xkxhhva)k^-LX;C2M5f7`+0R zY)Z-ARw8mfm}d#>D!muw$wkNBYjs=%oPBBm0=U)T71K@-A+dN*G0-&wg#7le zRg41!GU8>Y{4W?zoycve|6a{C4^q{{xd^WE*bBTLq__FLoOlyy6>9yKfM&9bQy71bq^c@%iaI{ei^<-TZwX}^pl%P&&V_ktgoHkg0dzGLcYjrN)OT6TxsC@UZ!r-9 zE^dp^_`6Ik4czCp3HrH91VpxE%kkofY)g2aqHU5IxBJEynx49G6RsW8Aj+-Azt{8f z5Kd?+y?vQm9#mmI(H0Ps+pJZ`TQX*rTW_SROI<92cyDN}bn=ZQFL zvj5W2%knc0dCmR(rr7c5`z*oQpekc1L{Fv+-6;&4|04L_N)hEna=hiQ>^#7>33ZSgE zt}P{@lz@Pwpi&aj4T?y2H1IDsPC6heyK{aaIm+bgfF za{o!9dgbB{zO)-)}f^g3reMfdI7w?BAg?rVvpY|tHP-{7bJvm>3=&C6{; zYpMRkUqMxXN_Ga^>dn3!2oG-mJg8FwW^PgtF68vF5RcFlBtxl4(;6J+=Yr_~Guq1X zIU$l`&_W~vq20rm_hEp)4->4#hL^_q54hy_gC%i0j)==(H|$S9>3N8AJ{0Euf^F6k zj!DGZ^1glcP?_H$%f6{Y#*pVTXuvxu{@9w}scU4EV^I4c@@L=0A8iI*F96hW#4C6cq&_Kd$LKg?R@F6GqT8yN!3_;a{KSto zT?lqP)B7!h5BJ)9&^S9y3Ddb0cDM*nOm43)WYyIPRr{gllCuX~%Rk;RoCi3^sj>`x z=uUynCHoEhAgI6`kvLs$Wsz6#S+5FXg+nHawEmGiD&^z+_yG@a%KZB!m&bT}jiSj=x((_YdsQ)6@oR{jdd*q!SP(YCz>e zjy>}VYefqiFO7`=+xX`>{LQq*h6BV>%`!e=VA!7xuE>rmTS$pR?zjWnb{#41Yvpi7 z4TtA$TE#@BqfA^1b#~Rz+)ODjnKxJM+<(LAAZ$-8J=@zhzPpQoQULn~Pe7bEjp0pp zT8~Q;8~qEpJ1d((%7&*W7bpPHWdr~rXAt>ioIv>pd-9JX@LoZf;@GXyu6Hdwf{yb6Ko&QzKls40{!N!`EbGZ1$PkCET%zM= zn6>S6wC-o#2%tIiDFiH&*&7*RvEOaJwQr9X?9Ak-df>-~`8U4P2VuOd)(a!`!oWOr9WG3#R#e#!Y4U@&Rg>< zAV)<-IRb2$?|gTAlS;AxO815%c&O|ET8X4Vj z4)+!AA9H#3n!)4NRca7A86;I`B;_sK(OvB6S7RQF`Fajpu3DIoe$(=Wl}Rvk+?JojI`MmS{L@}1|TUvnAq;0Wh>X&7a&s_YaakYjZP_J zHLPNo_;Mr3r7*$rCo&FhCj6hRcA`$XOU`8?$dZUR=m#u6m|1p?yZwe(Xs&=0l3J%x z2Nw#wGwRIy=%|V0=dv6;=ZijR@y&nN z5w3KE;oj7cO<4iM4r;W{09c?aFdSMO^?d@SoCXH{{3GXI@Sx4d3^tHc>;Rz5pkKo^ zHij2_4oxQBfuNEdIQsBU9Kgulg)KAaJM6W7O-+p=A*-y6=WMwB%YRdH?3rG9to)9O zPxzSKrsQx3v5RSU$AaC2hV_sjZpLc?Xzdd`7pC1dit_$AJBBE~;StaApn$=|JGazx z@-S{PPPvp!l1pMrRLboM&=yFJDzuQ!ZVypD;%#%CEMNq*?yr+i^Sr&Q;Hi@tsBKZT zBLbs8kKl>y;_MViKqO9{bpZplNM@QmJe)wjNYG(p9V)Ig6fg~zT8IZKJkU5KM&B@6 z?=hI@v=YLWsh+t)7jH6Aimx{4kX-81Z5xJk&!Vc307@iP_rcc>3wfh3Rw0JRYNR;qiQe@PLRz>#I7EUcwz+1LSC>FdWhq{fYBF| zl9o1_Yp+^>*yH-3*%7 z2lMMl4HNAYyBYPM&7UA$5U~$;FMDBFPLl&r6Od44o0wlo_mC+zq%zjF?Fc0jxk`GS zo|3{3a1|j%b~fMfU-In9fBOgmTDU+iN+tBtyknbv7NqUmLP4Ymn+*YpxWLBl^@6H- z(W!PY_sucPR`fX|Ccozc@&&kibxDOkt~!6loxtN_KkSV4N<93zz~>izMY+L6jhEfX z)ROV6w8Oe}4*PrX*g~O%_&KQ5fBQ=LZ;?0GElwdHP}#Tl#>T83KV$A>>UqrHD7{Nu^sH^;aSgnG;57^2$v3WK1RiK5+*)&S$)6;K?|KPc5`BTWe($dJlYPHiJ5}#=Jk6D45#z>i! zIEdXNd+oqsT3lQVcqEl__hiZ)h6nH$0NqwL;d6cn^(UYww86J3#{VRV-uuEq--GuJcFcGCTOsg?XB09a$V2M7~K`%L=pfvEXEAk4d+Y1CY- z#|!!dzZC+kX%!4hixEKQVW#AwF}iH6 zPi4{r3P!5o1^kW@cx>a3Hu~yC*fPCZ(BUG|qerF-x}TCV2Ec%%kkS0c$W9{p;8CQ% zt_+yfW8_WI$M;DNl`;eU?6u?gp~W=wr|DiFuEc!8PY-5o2I90>XU^VkXx$#hTKBO` z!0ShV-oT3Y02R<)q~JqcE5-+H5DnLFxGVsy9yW#sHz*(wIiiU#0j(KKVngm(%b*{O zjDx@=y>j#6Vc#0r40Y(Q=#BTawgS=6YOcrwUn zE4*!E0&DGng6>JgcMeczx(y6^7aEh(-nOR*cr1eXhg>7h9#Yab@3<1GO-wf zJfWQ1l!lpUbW8W{_}-Bl=Xy5ePiv}b5P>B11{ErEB`Adfj@}X#wUJ;GI%_*3F`Ofp z6}8q0wEP;xt8ZG#6zNbcr+)bx%oCJzznWQiWw!EFj4lFrHgY5P$zb3&*kJ_SvUEz% zxD`juLGViOOr!G}CvoTa6Fk5hyJB0?=Z)is$}9+J;1eVkC=c~^t64NC&^28jc5{EO z1%%KCtZ+O9J*W`sMW(O^HPWEq@kiMCNb>EAjbsn^;cHtaXa*G?hwu7#t8Lyzw-JVn zPrxY`4ohd}KWB81Mp@y-N2#ialRkfjSyZ)8ytiII2U7b0fa=^W49o{(NTM)C=SX7cx}7`K|V(;OH?}!r02Na3Tiz3 zo7Vwq4CVoS<8mlOW}b!-x?c(bLD?ioVzfT}*F`+=vV;Yc#l}9b(kE1g zZSc|A>fta5T9I#b+dHi~hz#d9CTnaq4#f)rFKq_{*z*rap2OY8Uu5o^;}L@{(b8#; zn;oq+fVqTYcE!N?k^n5}1ZJbJ^nBvpMAD-+z#+HFXZ){smmdKZXyH+>~@=D8(kE$cZySb^h87fai(*&yBm z1W3D)Ye@4lp9!bw_R_>bF?$CL;O-2dNZRa`Hw7(C|Fq0N-xni0p*c-3i2H5F#nFaR zVM}<0-B@s8(h^Xg?^J-G8@QVv10MipQKi(eqT@5Z7ZnqO+qwJg&li<^dz|Iv^!?NR zWj>7HO>Xb7;Y~pWkDS$NXM{+y$bTjjjXnAU&^dc#*rK||hw_x@kB;;!r?WJ`ZWV&v zf?N)BLU)S^mb3MD`G}<0bh5|w3JG*@@cCgZt(t-R%$OZQ+GoyvZhDbipN=T6n2rnT8Pj?$oCi}ir$Gk<}Gx%GwMI;lZx__F&z4UuW+0RCHv#P?M$ymo{=OD7Gi?Wsm+^X>_Uc1+|J&IXG9iCD7q`%CQg? z?{Q#5RdGud{%$8(d4Oh)9Tk{dG)Q;lGa3^^Ig@-?GYDD+_O@uwmte3gnZvA=KcI+0 z^PtQFfB_fk2cGY&X4Di3mfmI8Dh`iV?-d1TL^pDjNL&6vbil7iI!cUX8K2!s-gL$&nGZwzSQjS?l;<@eE*l`i!)zL(h* z2thbCC2a~y{W24%@J$3}s3@78ROic!20~()1`cM`oD}US_{JaE6b+0nX5WO(*E#Ii zYf-Fkxs|q}F`G1AaURSkW=)*B2~NDd@beoNUN);9*t0#Wh*`>>g9S%v=92l+g&ufu z;|`t?zT(=KhQjp{Tq+V>|gXZnij@6#zU(el3MI=9eoMk78E6`gLP(f7L*tHL_E`4c0Ka^4Z#M`wW#$h3;8jpPlXB;pfNCoRNtlsF7fYgJ7S^OJlyp#3^x2<0X+wzH~)lm51O&8@ADrO2B6Xcv3d_ zKM6e6eDdx|BS#rm{0!^NUPGP8ZF+nh$B4(-*I6Ei^@Or0D(v7P6p^;C%1j#?MQ57F z1q1PChoR$yZ_Kq}MVGQeLX7$mFMoA(Ty5ixP!E(`T6$0ygkU{+Vrv~;6{wOKo#(2f zlNLpA^jb-udY4{OOf0>^WMUW)i!XPLCA4yTMeqDjmpO%}i) z=t49JdLP5{KY;)F%5t$8#u#9*g;UczOW@Ysdwi%Cd81?_?kGVVM1o%Y+3=G_zh-M} zwz87l(?C@7o#r;!KI%_A|K%tuEdF~JZ&*??+sPV^#;yK2+g5adu-tZ!a9mX>#i9H$ z&DmJru0%)xyEtq;$0PPuUw;EqFmV&3+GUjI7}RrRhsXk~*-R#!-Ywye7V!Nv~uJ7sPA`St-k3Yk~DMPnQY19~&V=j`8Q zDXn|aJ_4Wsl?OkmIxI;1r-HmlvSczZkvZ-sMCjwdLmhCtTdNJwcD?*0+r6^OhHG*k!U zNg5^Wg2n^8Dg;{aB4ZIEVPP;Hcr79o@8*K!NWyqQ&q+0|x|mx5C?o{$ykyA_!M1+5iwja7o}dKwk(i9Qd0P-R+S7P=W%%*JVtkrsi^EL&0u zpGw%(@##z5edVY6*8SgWt>?k?IFFuhcz1JCwXRGzhh3(sO`pv8zl^XAWM+zl__?)D zqDV8ekDoM~-fzMS*jROItwv_;W3iR&!O0{j?3Z}YM-w+ zP46xhQCcsc(4YFbP|+R4d=?$qx9h9^i-R}LvI%sKkz%~@B7?l)(4-vFBc#y${-vIc zh(a?3`(xYp&b)8Y+K1`e%BwtX&O1&sSJOF{`9I{0_JX1Y}P9p2=_R@YcI(+{GwuiTTi`GUR4;ZFi&8jmzD;R8pqX4wV6SlSI@jCp7<0U zYczmP#k6)|ZKZ}E^rMQ-kb}a*nJjL-b~2dr7wa8O9$y*`Ly@QI#~?YAN39581+~EapFMdUMxu=NC-jgNcuOj=}cwF z_0++xRgb>y+$O;zUif^BzYf8al;O$;pZR2L|Fz4d$&6?&p4NP6uh~cM88{toj0aG+ z(1{G0Uh}APrEJK`%EI!PMaz$p7wtg7p_a~)Ow6`eXpH*$b@^02jd#Aq2QeV=*wPg; z`G(VG{jq+4uJtu*0!PWl9>9WfKu4%JI5@VC+Wz=E3@>mv;8KC^cIC)JZZ75o&d$sF z{)ynBF!WwMdz(Tb(;EErsP65*R=YKo2A8#P^H6&-t=SMRj1gC+j^fJC1~padta!}k zVnna(_tNcX#)otHlxn+PFPAtvVC=Y(pSD7G8Tv%IJ>JF+*OA1}E0t+yIu8X~S{ zF77WIJ7Ya~+OiwMsH>^QH_DiIsj9+Yv|I0!Q?#9}T%qKoo8Mia^OC7@i5pR&5d3Fd zUthvaVL;UUB^bK5?H}g+X(yXkzJ|4E_;x$b+T%^t$^iuF_HwAZpnW9fi2Hi&rYpou zo<}#o09Q1wvXIpbBBj>8}1R zvd-t4e?lh%yuI0^2)+7URL-`CmUEzao%=VDy-Lz`oM4lY@sWH4zM;~WJ)hcU`2s>T z$o~G-1Eg@<1WUmB2UFhq6xU&bf|n=1I7aoxyvwJ{@~zC8*|S>#+qWH=uQ=fUIBD>2 z3zqWr+`G%=uDiHrKQc1n^voaW$hJ6wQx%uzby8dY`|c?k@oDH?yFuOu{{%aESkNuY zHD@!xBhCC71?>blSyOU`k3Zp`fxJgf)1H9Kh^GfCW7l)23f^D9e0tdU#AcMt##l`4 z4g{Ik>bf}NX5zldG8AexCCw-PrjxjE51b)nAij@)50F+}U?HCjk2i;GL567UszMtE zyzE6#GZ^8U4azW?BC(WmUz3tY z6sc4}Wd&Kf*xR|_nRLTAYK~-3t^CzbY-*(pSpCGFw0!Z~grkfy4*Ios>tZfDC9^ZH z)GEe)P34j#zOF*8>NAVo6|vDso+Z~+`}jA&mAoaT;|+ZhgyK>q=$8d~5$cy^Dru9j z8UVsZ;(HmP@rm}v^55lsZdSY^lT*=evTXR;OA{c3oNf^8L~d8_&^eWMXGQtM@n$~^n&SN+zqJ_r@+-xc3UG$OyBOQ%q^r?r>{zK4=KS5>cBRu z4yEg3G>a<=o2|_k9;=LYv*gR=lMLc~RU`RO-_*Uq;?4dfd2?X-tdy&{D!awkLtn?h zv$2Dyp89Ybr+T(ftkB$Ltm=?la-E2?D3=lSc1C=c?TyS3ef7PIPOB$atK7?2e!(*? zD~>TeR_v$aXYJ~2UL$1dPB=e`L7WrSXpCchttn)(QH0`b1bTN`G zj|UI!daIgu&dbp+`P#Nwb5SI%Q<9d+i1b%n58%njF-+?4(lfR7+GIgdA8uHjI_W(T zqJ3&R5#5i^W&~Ipm?*d~IiAdvL<4#CuXvMpPuTMm)Yp;r%jP+glt($}>xa8J=NT1* z+R`B0SyMg*;x30AkS@jJHhqry+D2zhj;aX8ej68+fsxoE@srk)B6oA5=f@%RUz3=v z-i={SEW{e9n9s}g(O}{4X?3k?kk>6eob{uKaT5u^?v8rhb+fc3FgDaai|9h2MPunCpk?i2 zPNHH)>U*dU<}9HRi9UMznxSHk17cl!xLh3CGK%gOkSP3k6s=I<;1Y>L9x`ID}|z&>)FQbKE*WUa{ap+>$Ojy{lgY? zI;|_9>O+4A<0%ZQ)vtL-!B1U2Zi%sH+H|5U9^0bqk6yV*Eu?o^J5wPU8@WKIr~AMa6h0Rk)`Ol6~k~fcsP? z%&(CbrsVB4^_M<=_ivEAgP(lc`y-1tb*$;!A*P)xSkq;fck z7JlI%tbp&&ZFwOQ7bozL_#0TH{Plg{ArY8(=baLxN8>#=_Ke`OINhC{ztuuvq02+^ zgLYQX=1tUP!$cRUw)}V1F368vtbB7?KbgL^6l`$>=it6Q?SWNM^ZiJ-_=1MHQMuk9KPob{8tl2M!U;jSW@5gBp(qf zF*JfM%yKZqdxZ0rX;&rk@%>xf?_VeKV|=azW9D3=sUh&$hQ;4)UmyE|)ucXAuIir- zxGnUg%OH@Gv^t-vl#v~L?l8~nw#%(9;SGlQ z`^$cz{OYcRs2Cj?1+aXkuAo6lQ83&KiVX+B;OrS83aKRKF?yNG7h`5B3orctFh{7G za=^k7v+!L3G&WZQL+flW-*OK0=KJS-=>{^pnjC)-w12}JP_$y$|jpDaejCh5HTK-IUjw#dz8_t;In&VTolT_8n$?QryDJt-z}Adacy@7BQ!EP{_0 z#*A%O7;FDs!@bF>zyfz{W$*c*fh$uxfzPASXmd}%IZp5XUG8;+T_|M)RfCpGtJ*R( zgYe#GZ7i+q9PBT8HeY0^J{<^fDBl6-!I=`*9B zzR0iQjTWEn<@{C(1B zf47Bnk<_bwm)^GctiI0veM_~=nfXX|#rGfI{wqPL6nVd4`6da05q^*f`THIikG+7k z$LEfDdk_7B|Ho!5Bl#ye_J z*K~N;K?$@NA+#BMVp80M)9t$a|KCoMn3c!=08);cZt~RS%^v8Lz^A1R%Qn1V=lgXW_Ta`;L_4QWMLO4{^vd~ zEVsX1u$QY1T!m8Nfg~Q`FTcV+NeyV2crIO$G__-*sHn)Uk%|gD&2tKEyIJZRdFSU@ z-fKR8d@8>!azaV5zo~xvV1No|n)YkC%wQ}V!Q_9Xgo(jG9I;;5pUg+{HtZ7$pq2+6`*3O4#{==`a#q;nMYM=q_l zn|-0$<3)<3OjOm)o{0HgOdcw!`^z%08UK;ZOF)q9jM+7sfNaD?M21kk|J5h{V`TaK zIMeU%OLW@A|LPM43?&{M<~xqRI#&%a$&V@ZfQ)2p#LV?C-X(fnU(v*IH2%io2T1SV zrF{GS!t61i+aE9wq07Vw=Xb8Xc+@+^G}(fOL3j^ZpfSY z&SHi`GivwO7i8GDt+-65)z#I%2E-eknRD3Lg1dnF z%};0Al0RaD!T6#A8;8G6e>XKX^@dAJ9N-gDdt@M-Qs)57I-2I*KY^D&Wf7A--rRkD zU;?EbboD;1&-2BBh7WM@^HNySwbuI#6_8_H5E5mA_@qs$ouggu81V7a=hy!lqYpeI zEq1WE8KtEj;>y8F2hso6mT+VQUG~Yrhal#7dye%W=PkT>D)Ic^)mnaOt|>Ec2{Mm+ zZw*$lJxb*-ovQX%6u@$ja2o>|OS0?xaKVQ!=E1Eod7C(5z82ohjev}RYk3Q88 zJ05Cc`jI^{b+<%0r+!p#IMu}S7%-a~RK68f)|vEmGw*A2d)(I3L;|aKT<^tKdKLEe zuM8i+dsArZ`(UE9FJ7d+0)nH1$(zGaiBqY;35WH!`m*>Ujm9j~%?VwY4V&PYyI0TNrjqW#~#)j?_y>1{3SkU}kDz zm~R@ge8F4P#NL3%G>cj_CkW2@R|3bMVi7;BB{U`AJ#<^wg&nG8J9@(?&La%VF~yPj zT`&;)O;-X2yY>6&?pHxrkwX77`xdNXPBK&k-QU;JSU@FXJ;!3BA^Dp`J>7};vZUc+ zDH~>Po1-OiQ6TvmT`2t>fR48>yQ4Y_7Nr9nM9gn&${;*9@|?7{<}el8W7DZagJ$k8 zFbZ6l_)32!_)u8#Zg8t4G8A9N6S)?(O!#`gaa7E{PfP-7UVLw^d0aMRNQrlJ^0IC9 zEvYg5@^UX?sx`=8PM(_DlQG{ zrK!A(--Sm$iu6KFS2hwi+kC3=*Bb#Jz`r;|F5w zk{D2e6%8_?@t2Pknk#>y{n$+xs6&?pOogh(UcaYiZ=po0yXQsh2^YMJ4V^+Gb{mE7 z>B}p~*5j6sY*y+eA6_2h2pAr}U$YJ$C zy>9z9*Y{;rWHQm23cD-00nJ_mQ-{=*KEYl?7p`ye&Z*f=yd)v7Bu?&2xt9kPzC`$b zPauoWx*f9#h+skZ+#Fv`w=rTce*4_=v{&WQWSmj;Zbp?lUOjaBWM8;~UYv@urY z4KTHf^X0bl(E{vX;FDKyQAgms@Lqzbxk|r`R3haWR?277=ke+8v_Tf%>gwDj+o>u> zw&mAAyI9us2arfQqFv3Tut*gv+TZTU`?VLsWz_OR%jn|xrEE#|Dq-wvr9flmLcuxz z(-=3CoHKO9&6_pxd92J`&q3%CFiV{#iQSzOyUU@lPuID3u z=Ar%I;P6jF@1jx4SoUc)MA!GHBin(<&z(CS<$eh^W#YKFeesMf3yBC8x;+PEFf^1b zY}za6=TfXvk^P+E((i^JcNv%^Hy5pO%xlpWH>Id2^Q)ni1;QB|ScYA=@cw6nFBE^} zHJ=$qb1LL)6!+xJjS(HmXV0`LgoLoOBAs(dKw?7am{07(djp@+KGTzshx6LR{C3mw z_;TyUs1f;fa!pjyjU9Je8<)=aQ8u(Eq!?cw?Dg^cN)yw0<%=I-8bP!l$G)2O;$M2D zeNvBpqjOtLAscJ)wOcTWmL}^qp+ue%UTj#6ydA4)mHBhxj{PQfa6bI?!Px%RMwr2~ zyvxHZKX71CjIC2Di=cMcE*(*3NXN-Th`W9R!|l2gK8OFnPEQ!}1f?FG#94@%_KJ^P zni{tTg+|5w&OJh;r4xluk?vE;iA59XZ)BiX55QB$+x_`FJsAL&w_(Y=Z- z+Zibe4Z`}NpJeli*~tn@R#pPthk2L zv%}}RZ}7J$TNctQ!or$ADR!Or|2)(uhHB@Ssy@EQ;p}gl{5YkslE=`@AW{D#dnHEzgbm5+BreDh-giHo@e58|@1ej64J(jugj zbKymP{hEgM6bm%!!aplF+H@grvzyXHm{h5Y1I0`TC%s);(0NEw~d@kbLSG5CEOnUEORdvwW$CLrN_xSYhK3ZPnM!_ByM`!(h}*m|kn1I)XL{+5OHu zwJ`gJC3gF;#ei(hkgy}?N}Nlw*tPXz4~kOb!|CQb$)BilS~rq=31gKTD;FAVZ`@c3 zq*Vxmcj&Ip>g;Oh27H=aa&^nhEywyXw>B}fUy^INmjNLDHm+Av)k&({vYGVuVV`{MJELvxY{Y0vtaHk@KUR*^bbtjfBIdL$ z(0Y2mk>RwKClqq#HF=>WBf5BZqonfs^z#`d7 z;Q9EuFu&CE6CH_4>azol4`#Ww9T@e z-kLf8jufKIdB4|=qc~i#X@$wMKQBt0v96(E?^mHC^n>-d;mUa1VPH%(!ZzvW$`OSE zch6A(mi^aO6cseceHbaj(i>bCJFd-dVg@%-xE(hLUgS~gi7f|WXv zf77o5v}BtIOVT#}dE_VYV_2k5$nSUNNBd#6yhZrkx<(53MyamRh7b9l0W`!83mRCN z6qu~*neJ`wM-y)B7bM^@n#ZA-q;sFkHY8lyFt69+kq6yh5UBo`%_wd0>?%$UUdrlj4b zq1jzmKmA$uX|LVVts@;o-Z0EEIQ?f@(fS&PP-D_`b0wp|34i|dOxFO=#y$lC#8x1i zN3U+uh(2>7Q-~~;-Yl(I*oJ%zsY>4n9OS22B(rbeYw4zMgN4$Z{L`#-eR2mRKUUsW26iS*u#Ul|S1JM-TUeU4hUt5E4- zb`doj$tuuSVgG5oEL_D}eAB7LcN53R#8{y-G2&GiWdF_;zDoXLc7Ms$_+!_q;52pP zvA4+OToA5?dkHt}ULJ(SD~jzl;$&&>a}}Su2RE91CnKly;`4>?{-l% z%(o?*JetBsgV^UU&gLFz4Fh=c<1;Q>W|V65aoolv+s z6t1`tw`IYF*QAxZ1uR<41B)KwS941KSabfz<7)zalWo8NdyRQgf9qF*W{`Jfe4Q0< zjoZdoTCUjUEF+5NEG7?nD!E$^@E2bx%`Ha+pm?3XFVloWY0p+idE8yNlU%dTcbE-J zLvBvufqoF5$VAaUs8tq&Tu0S3bgD4pnquyJ__S7jGK%5z9D&1=CVVwsw}7oa629i& z5f4v$pF-5g_mZQDY$$GDpi=KYJrz91t!6DoEC3A!6oi@O&)u8dRzhPxjeJFAoV)Xa z88va#GP8?wU+IrE8rk0g3A7l){gg*sY;0pgDC0BN+j6X*=l|G%_hXTV1EVUN@ht#&jA*Q^!UFGoveZ0F5_LoR5>;oxAMp5?+V(eLAJMmOR-p^m&XLu|z(MgL%-opWyj zlBe+)Yn%$cSv$WA zACYi~Z*jIoFZ3y9Bu78%ygbRu7?wh~ zW7`Tpch@%5=5or%(6N{xz%3e~dN#&>&E25jXt+L5Kd?SnjQinzeuA9a3}$SRs+a1i zu>>Se%}-FPZ-fdD0D&OtuT~(|ZyhcfKo&Pf-Jb4!2VXr^TS8Vh2^#IR_iC|{ta{E< zq2Zgb?!h!|IiJTq-t8^Y!8oD49>$r9DU40f7W`a`2Cv}NfR^W2DBX%qL>Lh)zD`d) ztEpCnLSy1+jT1&UKUs1E>DPB>uOEE{RHS%w=b~J<&wi_d zu0L!piASeuF|Ufd$c5m?ZtJ&o4eL6;L_D)aqHpb%rVE&fo#!7Ea1L<~l|J)s%y@xJ zKpD&!dkLLlijlx&7t?X8m{t(^Dz3EAfqk&b0h|b>S6p=7_8Uv0Jv)&?1rg$pN}>n@ zl{amA%<`rzMS=^xXAL*2htEQcRTUml21RL^l`ts~BvcRlTp~bLQ#3H)alxN@=wiW$ zd&_pRoKhlNQ?M4L^d0AvvXuT;OyK!H^%V03o-f`z0rs17fAwjzmOjv^!5()d;K&oQEA?5 z7E0N7cZr&QM@#sF%I~2 zv&LIfdw-QIl(xdwj~&iJnhlawaE9X^z)`^ zc_(WTQ^>UO`Bih-ENm(3*y4mc>OLxP+wfA&#)cKqp>*fOK1D`~W)By}EhO@~%DmJm z@ovb1reJsJ-`omlm5G=c4`xOb^L>5CLN7ct6&inViXCYk5f-6oZ^-Aw9Esb-y2KhV z7gX;P=wM|v+3=C#=2eu+ZM})x6$JOynvTN9FL7bY6HVD(@`t+;a{>hJYC=JcNfaca zq0gfHty360ek(f6%VfgZESCI3mk>#B(-SKV;@Q741XUJ@D=1J&j;_^&#vP@(@-KN4 z!?x_6BX`-gPD?*cyixE`KKLe zQbZij_j(GJC9VdntLVbojs|&~>snZ5S<({SpjqBou6-R}?;+m)O=Nf!I2bX6bicW* zpUr6u`9q%s5*?ly69xMAqjt|zB^dF43i~r5WS@S9HC5O|K3<&p{^*?{YqaZMQ#BQp35a zqGYL~3Z*}AYip#HK5w)CEeFSGmz;AOVny1xRJ`UQP^T7yDqe=#ZV5}1hf9FnVy8A9 zTgm9OSCjgXrS?Yv!{S_!qaiiP)JE0Vw&p)<%(E$RG+#Sk`3-j+uXz#73aH!sdI)0z zauiy$I=U@>u1_J^5mI~EhG%eGr--gek00VEFE1KC-R+s{qW2I$mvZhsOVAk`sP)S; zn$fDEKPlLrq*{qowo@IAB-vBCDpjsCkqGHRVKp1%y)s&p%&0@%6G`TIGc>_NgU1!P zZ$PuLYR+EO(B5O*H=@1nPjjHjcOw%s~fnlCehG$N*(MQbB07K-HP zjC<%Iqv8`qm9J-y-+m-iAy5q@@^V5@oYlDcjXJ7u{n3FD-bTaGH3^+-Z0KPn?pLM7 zogCC_L`He^U%3s5P!%0judrf(rYO)6rkm020UvzJ?P-GZ;hMo^pbotg(QX%yy07Ew zWY;5-o1r~nyU4unkCrzv2IuLg@te`oV;&BJnnMc)C8&Jne8=KS75CxCz=4I-RQfqa z6rn=&rxq4)%o_NO=Bct#>*XvzPr5D^Sya;V9xR>NF7TA^CQ4R;j*OzQ_Rp$10=~`> zJx5EN5X-iL!4LKI<9iG|wP#2Yj*GO38X_t}t^+n)t8D{aSG|RHswFpzUTkjN4#Zh@ z$(7Id8Oy(u@YS*H4!=`6-pN{i|Mh&2P_z?WT|fnWdtD+W+wX{~%ATP%Q=8l5_jx?q zlc@G5UM9q~n(WS0YYw8<9|TQ;ylK#$a^YU|NoX#8&Ewp>{e9TaX}0Jd-HQLxuuY?; zdre`SaXm5ogWq@kHc~&4m&cVl!CcfnkoHq!C~@OoiTE_1y19>z#aC{2V-i%v;i0nm zB2>zk0J01M{JMok%OR>Ct&8_eJ@dp8dfAELv*v~RsD!X>h(Mj~`q z_puDRN)v-{j_-U`Hx!5P0RaZ1QwqMk8;ix_Hr`v>5?S4Na<|-Cb7m^vaV9%m|FX zJLtRLEh`=Ol_hU%Nz0zp>5j2RM_EmYI&(R_)@zeqi=wV|9-03JnZQpjOhd(=Z?WCt zzd_^Vy+}i?#~KLLW`lxNuJLX+hMCZZl{2Vkz8a=Z^=K1z%bmEBPd7o1bZGbT1Sjyl zy&@~^#YapD=WVPxhg#*0Tn)J42u$H}%ar(UpH5#BO;L^)9F0FvsX`WWUO(R|o=%lH zMrPj6JYzOV7$RPh7TiIosV=@Vxb`tNZFRbBRZDdiT%hlO<2u{PEkV>vZzu-z+RiSY zu^yo*#L-00PQ4}9om7Rz>PI|JTTb&Sxs&EKIJg(`USXn(eb8$*`SQ!dKfmOBzs#VX#?J~Qe9i6q-~0-lNW_YJ1}Kj2G2(GB~fcvVwMtKU1L zF~3QbM3nsBGv#_bCynXJmPpD$x#M}S*f4(EbobjCG4CI73_q;P9jGh%972#<3bf7M zCy7v$g!^~p9*5D&{!Rd&)qzzMDJxyEw~UKUpahLklg}n6>hm)D7URpcm8sIUYkK$8 zZB!H4jkj}~@0NPM@*p0a6HdBc|15IPP}!G^bUN`#-pGGP`>`xZi!QI&wOy9eeleR} za9G40QHLT*$akgT((IY&{#b63hSf%V?Z^O0-zbNfyc=8fq^_9s8hOC(Iux#UJqt0b zd%R6&y02EIZzBkS?=zB-AWHW-xk|^SKC&i#qk+Rd*|L)%8GT}G^bt7RigtEQ8Qt_ zXvzJ#t6IfXwgUGHD?guisoAKAl^eJJ$JTp*W8J?0lXbQ~nKd(%Tz zzi6X>=(1~5NZ=)!rdw~= zSEGKdwhkLAkUgvt^_^*OS~8B$sC1^^@%8l$5!d9XkktHy&ygnacu>mCT0`nNH|;L3 zRn(IoSp1p40=Y78$2=ewHxbQyztv90EPN2X=Jm1c36ao{3BR=`V!UhzgWva`_`Tem=XL~&I+#WabknRFtgc@<7405YaAsd~ zTlp6w1^jc<1SvQf{7o3tw!c%IiSr{fwvGckBzb^bz=ZkINl* z&su@ITyuh9&@vq*{3tDYCt^3#FA%TekF)&ZjrRXI%Nxo5bLFOL*&dr_;dqi2>PCaM z8MmMn;!33EyVO!eQ?!r#iPx((pQEfImZxsxWw#HDQ=7q95#Fwdn)o6D(+WA%m^GI`)-wpFfBkhq4tW4=Y_S@>{dS*P`Vai98)hT}xdSN5moB zQkJ}x(1h=pmG)e>sLf@*u+==K)1{Y)nZU3_*k7q(t8POh$xQZsth??Cd$CoW{e3>x zZ@buqe!uu{PWf!V>+ZJ;36Prd*-5`NsA;S~lkHhKt@^5OiDS8BK}f>cv6g93?D;2g z{KStLt|@&{#%VE8zaGSkS!(*Zq&nxvI7N~8IeVswo;FGP@R;o0ES50CJV(*iI*Is> zGF}yHZ`4CE7Nfd8v+<+(f(bJVM)dA}_1#)#1@Ka*WH%J=?ePO%EW}usKFe zOpNvWIeEGf_6CVx)f*kZPElLO{@AowZ?9qDdQ<)f7kt95rZ?b?`MK?|7W&XwNnGU4 zV zlUoaZo1#EyHxb&GHK^LYtiCj^`5#X#6+bE|rKT~R$Lq8gUA3ja)k32xMPngj{ZkM< zylJ~&VCk7Kun{%j-1EsEp!M6Rh21L|Cc1JD3fErn*F4^cTsr?$sM|?CS3d;9uGE(8 zGw}rn*BygW@2<)F$3HlZeNs%+`mv3}AKZCCYj!-fQuHD}mS@R{xX3IMJh8m%9136 z{Mw!$1C2KP-uN0Oc6&=-PuNi=ZY;Pxql^)F*_~sahUMy8@H=I!bSiD%274*%tU(+T z$vY?cgY~eb|G#4^c)_ZZ>0GX9{%47f9;`9$@Xu`KpQ2xqMo4vDAnA&}fRpq?W#W9T znk@Gde%j^Bbg1gSG8qUjjVk`H;W+vlOpQ`TK2)$q8 z$;fkyXYR`xKi%gfkavJXK{OcA^oru8=+C8FgIiTp%sU3Xu71XYzpAKQ$H(Par=2YB zE>XO3{Bi!L4=sVMCfVF(T?LVu*>J(iU1kPP`Q6#Vrr6=Wh4_8BV7qH`?h3A6mStX+ z=BYCkX3;igjKZe9(~Co1Q{APs)>^w&U;*`rd@y>OPW%;wRF z%f031(Q)=WM63uTn~SEs+hsm-J-npPX~DRM_1f&IIqTc`?pmG48eR;InjE7d=Chdm z`i1y?*ok{pd|e_d;tobwo4H>EpRo0sq89{(0YRcrEc zx42sT_ST4!4juhMeEZAVTLr(_7JcVsQ47nzDMEI$m={mFj2y?)8?x0Ro8Re@aqYx! znV%-OId{3^1|IDQmM}k}%-GN8+0-OFz5QV$`MekRM5br7a4;7CS21>>-d-7Mp>H>C zBp5Gu4sqV^pdnK+iwP`NUL`zPO){3|)tk+PCVs)+Mf~Z%=CQ^+)DuY^DYROp%6@K-wb023hxCsH|qQA!k7V7ax zz79fC*}7xedmt3204r}d>s7n2Io((rOa+EY+!%M_nCG5!<8M8Q#NR(Fxw7?{vQOT) zMbrFBWXaVNa#+W6q;n-@JI3NXIi6G8adXM(%71mbY@$!}LvI0T{#2JVcl(rHinT*y zdtqW;qt?l;Un6Ipyx`hnZJE0!$Q0mu|Bnx4PiXi5@u3*ib0l;B`cP%LroBlo(!Kpd zaw1k_Z@EGNlA|oQIclGhCsC(9=E6NF&`QGvF=@bVZN^!wTW70sX1d6bp2(K4A4)m5 zPAIj#P$lQ_;bP*`KNOj= zV%A_woJjedUwI18(cGM4XfJs1{B^C)3B9(9-O{z}zc9Dvf-|B8YNPn@Ze;?mTOO;6sh7~Y-K9l}|y zcFdc{vGA^VU|Hz0s(s51?h!h7>l7~{TGW1{Bh!Lb!HPVGrRt^(LDFeTd-Z%13$&|YD&u#6ndSMw zWW&p!uJ28|7IU%n-g4H&9F5m8_ITn*4g&hZmY~}L)+y=T(!-P49=MWf3_7beL%!>dVpCj#VlO!)4Ow3zNjm5g_ox5+wYtSf$DY}rblUtJOB zNWvG>i@;}H?>@s>`=h3>0TO0cV{^Am+Vo}ZqDQ<~oG2bKNZ7tej#F>0&=qGI5@yP* zs+c$-BwF%v<5J#~T<((_zcsV_l+8(3qQ~Tg(qqb^EBBXQn}$<;OhH1H5{OpqN8TwQPZ}L`7D-d?+#k}Mey59as zsis@}VO`4Sfj9EKN~xMrn*~JBDVR7+tP`Tqf|u@p(T~O7=w|uXb;4n8FC+*tcju8f z!;la+;|EM8a@)0!Vk}O1$$eTEZzc$F1vkbuDCm;sAZWiN%}4gbDX3C&p85FcqFCjm zaX_Gs+l_IK9%3gwee?1tUFliX-g7F!?Zq+slV4MR@K^4WXbpTZH|g=fcLU$P*Dsn! zjX9gH;ib3g)>c=V@cliT3$1;ZPbv>%fhEX!+GS)~B`pu>2k@^yPg`3JH!R@?o_?eG z-MDFg&Z*;?<-}rOhRZ^oI^7pM2i8EFbR`q_tJWyo?}WlA1d?@&mT%_&Om}UO`9)ja zB(dvUth;V$>~+1l=8|j8kYYD!*>b6gx6Fx4lenSWJim&ctWy8Ny`Ubj78-QS!}Bin z8zbHJv*Yoe4@_;uyqwvKnln<1RsHdoKNo;2Hd2aUD`E;w*8 zonuzWkYI6CVHQ;^lGSC{3+O;_oQe5}$d7n5ms2#EVmg03S2e6ov;vM(tP0egKJcUvHIR?kvA_Fqn&o@>?8xL z{()uhcSHzSmT9c0XfYyi;#%mmQO(-xjZgoKyv11uKkzGSe}cxbQW+#dWq<+PRf~C@&I8|;$U-b z1fsUoc*!bdXVRV|?bWtogh0K9zReOq?e{JcBNkekbW$(p1S$L6?sUHvxHZAfUcp+y zW6T|FcR62&K9%wPqcpYO`@gj5N>jrWn(*$ zG^=R#9jf&Vt6U7YwGDpoYn=Asu1b4)YQpvO+Mq($Gby=?`#aYth>w@P=&`ntl9VG| zsw{i{HRBep?NfYxfp(kt@(G#yp=@q`w0j$62T3qQzu}4)I%T$eIS6Y0nAud*NlG#& zZ^WG<|5FEpxq*|mWkXl8;buO0{Jx}Q+gMyJPu{aEqn1Sy7HJlez2h?Ob5;r_vVxn( z9ok3VopR<36@G%Pq`N$S*KBx%WFN)<9fxj_m2L2P4OJ29!iRAgt#6Gp-$!=0Ynlpw z^=b}$vlyc}J$Zx=m(_YY>D<2KzZr~qd@)b-C*I@zJ4h*X&8CrwFs2)q>SjA8S~=ah zM;%Gb7#!fSe$+;Qf!fEt{IX!G#x3w$1W&TgeTk=OGsDVW(b%3C3t}2&M))@hzL4jZ zymb+|-3U1^aegK9w$CL2JOuthk~(!%F-9AeaRsPg-59?^Scbv8`T3Td-0QG&0E(dj z^OeX)yrkQyfwg~cxPAs_Lm`PGCv!jf;q4}m*`}UrScO-xur`g>BJ_m92E&ybG;a=- zZRX0dYtfi;+a^!@Ki&?wyt1T}cY$~BbIo_9-*OaDxO-Dl`T_5+dciR;{-;NpH*SvE7IMy`;sY=`VN{z7xGpxlCT@)?d#{K^mXru66uv#u6#Ngqkhq zQoGdn(IY22J9hf~-dUO>W4dJ{ZL!_W$oF-{J;^fI?EK*RZye=0;c+j?kUU#2X=C+| zw)&5I3q)Nb`NpC3k?<0xo7UL9@KX(#vd`N@tiT6B-AjBd82j={Vgz)uqFY_68L+xl z&A)i+@t@=1;CPoy@26glV@+H%!&*|x{5i5Dw!8Fq9_dGi^lLCdppanxuJWLrl!%kR zgRO$d$vWj0eu@ILfhv-~)MN?AMo}ly4V$0Pg8?C5I)aYFEj%)D+MlFuFi|Km7-9Ws zDI?_a&`o-4$6j+CThGzav0J2>5X%p%`-w`?C%)>YSGTLCs^foHKN@<-2ic0HEaP?C zy7;%uNeXXje~&aZMrI9tkCY)IFrPnIe8?AM>z>+?A-2}X$>et~(}3_wD3;IJd?6am z^oz5}q_r1NzQ;Xqa8v|ml+9H*JSkg9{+8Lvp{kzW<<#S`o+PAWV7O3`H$fqP&A`xb zhW>(-a!=ta>W~E(fyOGi`>`!st5jR^%h_^i^WjZ;wbkpaIClcwg)=P2>SpY?#LZux zBZor8GC~+xRLv$|A#l`lk=RVwoqMU_ODD_(D}1YCU4Q(Yg(zKJd1**6F1ptX+P#M9 zF_|+gP2IBYygKtl`j{TLJtVTwPqU4G9NRid=H_3^U!D}-6Ivwy@X!(W}Np40>o;^+L3>ue=@_$)7K2Jk!CA1iXYmB z>5S*vQ)g)ExIP!K+;EVCuf6`L~^fnvm54GNj4LH%z`WKEuUB8V50PNtl)D z6($zvpZ&L^be?e2sgAOiN8k3V>1y!rc2f=cYxG@dv+d`b*^b`dU4#(JNA1cvc{w>x zqgPDG8BJseij4d~=B?2iJ@>y?gF55}OX^SZC&Ec-NgzX&CYPc1TwWATz~NGONZ^n# zKOD4Zhv6deyAc;oi2<2SJG~wpbI2-_RTG9yZdLS z6Y#F4=ms`VOZp26z9ai{KcqV|YjM$sw)I=kZ3_6W%qZaM%e`A{J~Q;+*K0h(W3h<^ zWd?e@-s;j6n)25u2d%0t-~8$C$H4h|TjzkwdCAU;Qw-DN`^`k)=SqH&uKu<1@_(9$ zRZ;2({ieJka&l)1a^IBSz#iG3+qp`1@?Wz$Ki0bG;9R4~Icz}YvV<_s;FWRQr}2IL z*Ei9xk1WFQRS%>=fuK2CUsAGw_*NH*pA*-drSASDv}qm6Cba~rNQa6=Lhb_+B|hZ= zgD+xI&D4YM*+)J6j{4Ir&T~%(3gyE0@=dxL<>sF^!}Aab&u7P}kZk|$$-73}o!8pC zm{UN18M!xMq)6`Lj_T>i)z?&Kv7h*zKin1g%p=t4^F3j!l5l>$^K%S~9#-2ckWVPD z$2Ac8aO{r~8Yc93X1rq~NXD#mKSCTD4Kc88(KUaRXOIthq22Hf$^nns%F%s|-7-3J zyNcm)z*n6BgnTBd#p^Og~ts({ed5DnerUEzGvD$>P4?WaO0?{6upkI3{R)4 z@3v9HSm7Io&DI{WIEyWxQWZZ%N7u(+0~!oL)7Q8E?u-r^7~XE>4Ae>wQv|DM%muXIoKIwLFi; z?*#AKx=8l^^dY_~FP3rRs$o)2{d40tXFe!?I*U)v{xiF$tI1hfe82L6u_Vu*vjKBg ze*6A>F!Q@%DqL&4tfa!1ECq(VK5sD@mAWW@jq6E&x1}vazOq7Z|Ct>?J$%uF*h^-T zFGDRqnl%u;!FO&A4>~O*{rq`Ho-8FW?rl?iq|twto{-N&&Vp{T^*32t-NAWr;Pts~ zvslZVA^T3Og*ORVFCe81Kc1j`ko_GC<4^ZG2Id4bsRqt-%;HTPztaR_{2~BDcqfoj zu-9@RCgMq=4CP+=f96wolw+Oo`6(ar{hXc*1;_36K65F57=n6zx-UQD?tFOp zb!=L;M5!3AWE&_Ik7aLbivEw}@!ZxKG_<-;kw4YndHGN?&|JEv`x9q*BF?oZu&j+t z#`WUe4WpAs2j)e92ock*Tw)X1Bs2ZVuoK$v`(6%+UEq$UC|YFH-RHm90Hmx4Q%iEL zzM+0wHdVxb&kxUS_p?5@XWH#o9*D2447(n7s55N|RWfxj2Y@anG&uNIe$oDE{P%-D z-Wf92F8q{*vny+aD=`+JQX;!loxsle*7CgSlaKnT-f!?*9F`JrZtZ=~;x;6zyBE)= zrRbl<+9h(u9?Lep=Vp=H&`p!GX>V^ZE1xJS7pHW1j!ddaoZ(l!{;j65U}1l6N1f@M z+nzlaiJ$Zj@qsFDnN z)|@YX*3C`P}c6~!RB)H4#MtzbTduX^9p<+&0@hZq{c`q&rqePM4~Loa)AIu+ z>u6U(U-@MOgnqK5ln*n0lqwt_!aCPbRpAi&xYSZHaEyjR`OcMzJ8CY!71ivW{YREJ zd3+*ZYS<=E_{pfWl-4Dh3@P8jrKM2n?e%KWf@-Un&97MIv&KKhvhR1Ug;y}hdZyOR z{oKUW2<%&Se$>kmA8nV|ZI=byVllXxzgyltB`Nb&UAht)@S8#ZF5P?O2r@5dCK0x;%S4@+2$7qrIm6|HNI6tdFWU~63f|< z@60I*Zx~#iD>qJ5sssr9g^u=E@lfmkh1(`D-2!UOjb=m1K04J9SY~*p6QW)6r$Obw zMj{21XHo#F^YP#n9)V^LPbqip=YHfIFJWlZd8?B)FbHUS)p)x7BQXW9Fy*^JRIlWyx|ab7)l5 z)auhosw1_BN8%ymvfcdSwD5hH0_s;|!#gdi_W3IejyU64Yck@H(DX)Mp3Fp4;>ZeO z;5@&nQ#Eb2y4=vD#zbZgO$({&#ayAj51)z>1B`Tnc8x}-`2w#z(;gZbZkSfw6d%xX z@@R2LbWqBgHep{(>e;4r6$`32HG95&NMETArrj&-Dm{4TCil*k>_h6&a8ghXo|ntl ziw%keUl^3`ywmrE2C%kBwuF=bI#&9J7B$%f&k@~1h>wEt0GxL78je6rHwmOaEs?0o zBOvDyNmG9Br_yJ&2VMje$bdWrc(TaogtD5isXC8no4T}|SYQ(90B6F__jd|6O1wUN ztMI?C|8J^JByQ&IXV@XGZwjam?o_Q)-B2bx!_~XL+ms=Du8zD5Xt1 z=t-jTSW|dEY&lqZtSFi7<|*WQWy|Vd<*r#7bIi@SQL&J|fOgT$Y&@8G@xV^-b z^n!lBSj`t><|xI2y!gD>HYEqT(>KO*P5REQXoN@H4|{Q@j-cW++;>nVc^ZrOlSx(9 zy-&7cQA}Nxy?jh&q*e)Pyux;mS7JMB(^~H(BlDC$1x|<9RaiyqDH`}GM)?%PwoMaX z$(V-0o>;cwp?xP(!tP%%Y1_5)(|()PBO;wcev^yzdspO4*p&yKFg{aUF;yYhZQ=|u zamQG#a@Hq2G5Q?aIkiF+12^zV3M5uqU)T6v*?Z&| z&#^hNbCCS2#Qe<}i;9&rFQkDD{o_%Mlj-tczqGD)0jOQrvKyPByAQHd zW&3Z7<_qfC5M#0A$T?-9qJ(P$I5>+$;;zpw2@ig$w%0E(?~qWJ3HQBO zvSx2DLv=pN{ujOePh6R3y+&_?tBVF!da5!?OP$w20a^UKxjr)WqG&DI8CNE*--n&5 z_OvTU(n)sa!OE;=<)7vg0#-|kWVkYF74h7r*=&lH*AJ@pB%&njfiY4_f6&oVi+yg2 zo11OhcSJ~VuU2Ke;)39k$!G7~U&gc(o>bI?SRUY5B(M2)wnjTJPc5)GE;R2)3-3>d zSnuTi7{1<1MO}RaFJQ(SFy|!#C0PQ{db4Yr&;GIjYV=ZpGsu~dZN|ML`mI`aD{>Vm zJ}!s(?^8#7l8YBBbr9|_mFv?ct-gJ^+$TA9Hn#sX6~(V&Zx>4`HRbWJgr;><+upKtk?Kzr2x|*I&>pv{(|6NIpH}@@YEdBbfR)rP*)d+| zk)~4S*0e*P(IZPCcDCs_Y4FUVJ>#O+Gr1Ek6I7- zB~|rGrL$vn#9m|mnf~&KV8C!4a{>4G)?zTWxr0CzZh-^qO10(864A4-STb52P5w9Z z-zL~A%Di`o!)DB6nEZ01&vg~i9wo2jYLJ{h@ zH8r&@9UPs(dmpnNl?jMFxuETGJw1;tA+~C*GlD%n;ao_Y+yngrT?8z_L*1e)$7_SJ zD1$OIbeB^(t7zD2&+wkL^(598bcvojVO8?;vdmt8@oTH7ecGLSOw%C=Jl3(u42yN> z!4{0MYn%5kGHOcJe8XCyT;}4nzFOaH_~GWW<3i+U`2i8aK&=zo&wS1|0+N()imuP< z5#Vea9(h?LcTf+Mud%no(B3wG?m-FFTi=c*_aX|L4|9<5I!q8ee_i*^q<_odtU&~& z8=+=nJp%8@#0&J8$AFQHgJy#T7`%KavN%7Vdp@|SZ*DP*ar_@{=Rt)rD<{L0-nO~? zA!+^EP~3E)$H>~Ff1ZoF2MXp`whS#z@Yzf^`?8fvz{uW{pWHan)4_M|Q74o5;r)gI zU&b&Uw$H9DY$Rw9dpA7tO4Z035yfY!tk+#I&dqkt5IJw%3K;%!iE1<;hL2H5uK zN8BCL1>g5--6h2GczE8YrYH5o+GGns2xP?+}y!8`-o3++6a;gUYP4*4&qI?O{vW? zbwfSOVc~cngIVy>>Xjlz;X7B~m%0|;ZQS`u(?DTCXwloq3F98GbYv(eY@SQYu1NLI zHSVeJ6RykES8`AsO07@*oN6dOYZWvamonXUrEC0itEuiYs`ahv*FOHnpPbWT#;<4= zaxM{6K%h|;$ZRG(PqHS$xO!P|@3yip{oBzy!!O9R5@B{=-+~bgN@Vi~XV{z<4>{q9 ziNxN<*zbt;!M9<&aU%?T!rNY_sgj}TOjb#;zb8t zgBEZye?8@*ZhQkFS5AZabLV-U>XfRVpr1`B2M2*sP*9UeOx2;5%@byfFoo6ZdgA;O zZAYw4IyS0T`&$zUEDXVskyq?kU>Ig@_}C%fcz7u&0|w`hz14|B4oEo`!9^Ysv%b6= z-*lXu^r`~FibAAb{6jK`S8+=RNL=I!A`v%>D&dNblP`~|&Z`q(Ha%{MiNr<#=`dnG zy+u(lgzighCz-bMrMY?FD5%dqoGAFuyxx!IeD&n(uj9)p8lx1x^2zr-EU&ZI8{va- zamRt_8}6+1;SlqYg^)Z%vG{Cfjnqi`jt_h>Cf0P@TU%}9Ux=*zHwYQ73!{aAuy`_9 zoN}oTvro-=twZ@$pg4NQB?gW?T+*8#y)?R!<#6;QfPSsHL6%qR;jfh@VHqGAIWad- zq^x}6U)l>^Y7ytEN@jWX!>#49sb{B!sBI@b(W(pLxiCH<{)8p6aD?($-B}3J%@h## zt(aH^`v+{ybOi#x>{)rMsz-nRx` zOd>*;%B$W|x$Roi)~){rhj0qG9_tyHzjGd0W<=3(;r2VueC9MC6yPlY{*HSmoU(Z3 z>+z5q=|00C@yoKHxONiR37lvQD&NMsbzR@HER#`&@s|RK{yh(jexS{CSTSHyN;}t) zuE}3a(2TwW9uW+NJK0iEDF?U2Bfu0o+fYOfy!I1z4~j#A?Ko-v3jM!d+(WPub*x{r zZlj%%6Sx<7EfKzmR{~~iFbiM1_vw8JiKkELC;wW#zpDZ>pxiyPu4%iZQNT$NA>5pN z7dZJbC4RXmT>VMGi%LK8ks}p;xb%NN32`y)g9DyZ_96r7L{1S7>oo(f>6(d^1#H*# zYm)c>o`iq*N<0JiO4L$KJBh@JiHv%(>GoivGcpW2s*u|~lZvsGrlH6&G{h5}~O zcRzpryjA3S_2M6?NPJ4HL(E;?{&5cfSS5Fu z`M5qmAQ>pQey$;oUztEH`_bKPplAC46sPl2C|WdjxI~L_!SBVar(VIompObTSy|lr z1mOh4I?A&y^T{L#NhP>$8{gDq?}V%v2I~4v47|$7ucsnm()r(e9{wV78B1t$_*mgs zxVjN=nkGMC=ioS+PYJ;o+8`ZmW$3>9uZ$i3-p_E&an;D-RPRtVoV-P4ti!2;?)X@l z&svUq9}NutyHW5A|W!B@4)Kwr*l7$rLB&dO3i zi+XrD90hN)b8|g84Bhk}{xF5W`=pzaZ7~Tm z1L4rDXWfxOR!Wu{XYq$4kjy3FzYCz?Zv{d*b?VL+qJNiyC}Y?mjw4h*85)tZu@BP^zeNzr+RBqFHvB>3)^6HCGm$ zctrof)3|bA7n}t0z+@o#-Jx&-WMmEOnA=Cgh23E!FD#a8@+5lt#_|nJ<|bc2j>)Ai zJ7*T2py!~XFNEP?M5t0=Nw>BzGz3cruxk}ObdiE{{=Uy(Yq9VIk@LOBf`Ng&F3f^H zJ+Jf&G|lpr);1YoGsRQra_qy`F41^EXq7f!T*- zEJEbu<)!w*!7+^MK6(J}5ktr@Qr3 z$-Rh1H`kE+wraK^rd%-%t`jQkE4{@VcRTgmb_R=aiRryrdGYLkHc|qaG7pwo<}1y6 zutmTn1|O)yXrODsA`|39bISA50Ex1AcL5{9IL41v8^LDI8b%2Qznj1f zjQIHRYePV?*vW8$dX#U?r65w`(3X^Yvju!dS8T!P!w>DfO z^8-aL3&092xdpn`WkuqU@EqZIL-Th@umBtO$2C{>^9YUOLlg{3=Cq3<*qE(=amf;I zZoN3uN%iEAQu*k;(Tr@S%da`+`$^#{)oUmS6-B^^dP$&v6lzjw9Z}Mh9@(Ljlzc1y^Dt-w>H6)j6&=@3Jt-`#;Yc^aTZRy?714 zgue+`AA50|b_adgOFpCwZ#hZgU5a<(e-;ql2#4+3(_s+@nAZN|ELczdZUOc~flI*P zIA=BFBo>HBTqtRzpi>^eF?#)~s`8^59oY`vaS-E}Vtgym;wldzvao2je*^ zc&wllgwpb3e#|$37pNLWWLh*3lgC*v3~I6#PSTL`SsPi}hH3%gM!%Da2M}#46sBR`?Wpb zRYV3oE}yj@3sZh?w=kFuc6~@|5Qs0AK^Qo!T9m!+Am85rD#iM}g-f)EELoP6gH99F zL)acQfZLB;sH{f*6+)hkTuPOz1@VE<$xoC#x{PdfI_YG`rwD=V$#)NTGMY>v_#1LRik;4s{BWD#O)O9d zC#dyYui{x&jY+3A7@;21q;A@g8fGr^3N48r>4I!qdE`ta{J>9!Z{*`mW=~=sJN{^M zwgRGFl7Jf$)V(CiV5bkCpH|E-=+_S~FN!Mgp;=D@#dx>#;r--ffFgCeB*hQh668$_ zuWk?64dL?#fOu*jKTUZR!8`x7h<8~zJWdi!GAYHMXiCtAKsFQbNvt$5K*=pUi4C?2 zO1mOBC2G4!KRBFwg1T>ZdBZgrRQ zo2WJ=nq54U4D`UV`SoLnBCR%iHQz~~J6;r@P5(_+Sd ziwq`kK)>i+w#3uX87f(Cfg*>_MSF_+Xt58~TaXVT*-M)G&?WKjf&cz?SpsYvuID({ z|M`F4Bb3()&dTJ(|8q@3v0=#MhC+@(yissNW2_zI!w^?OHZ z=I9jSjM{ntw5|cf$H1(VcFil>W=5$eOV11OG7DUcR;iE|q&|Ti`7QF`|d zb~YAdYAo2VphcvZIn%6}|(>|Gcl#`^G}Yz~+Y&T4WEz%==Of&1GC6*YAb7HnO} zuvFqn^ozYB>;7UKGLa0-wH$^Hr>KPbL&Q;s`%-Xs7zi{%FFg5rb9euMm4!try8N-F5+?;s&?iWdp-8^rmh)P0~<;g>3 z`P@Y)jFlGD<;)|fBazG0`PMI_u^otBoVO@Q?Sw)ws18VkUBo|>skEv3cBCr)(Q_Cc zX*ghRd?;V#E`>abyn0xEbKUW6aPYSC^^S51Yi+L;Cqm1+24GLf8ng{H9#=0 z#i?94{{p*5if~Gmusy{j{g|Y+J0-%YOHvr~I^mE&tydTG>_@rCuvL59g|OX@5V)I21t;@KeSubpuy!=GGBr4jMqQmF;HxUF4Mm*N$G$X`PeXsb=1( zRp?L}ZQ&T$;y0onlyH%#S-*v?Wc9U7K;-F$F0Y9{wDic6gHSpsf&y|_i!>niVQRo24gHPlCpCc1gdG^Z3cz2vZ8piy zDK+s=aUj1fX9GxFSuSeoMn9A88RQ_5Tvd@pf;RFle+cW3p6KIcSlh5csY(b_q3`fN zA0nQJ`P6y(1ikeC`($wHnShA*ev(~C*8in!se^PpP`IU3`G;bTmUZMK6Zay&?R^AW zAru;LD8&kG=N{LMA!ZP4(kNnScNd5R{|os&NJv$R?X&vrhFq5W%*&!^cfqpiH^mFK zf;US-as3AZ&j}?&F~cQNeizk7qLtulH65^F*hvUK)uam>fg#l}C`fh81?EXXw)Qq1dw{PR^>|*zmV!mQ8{i)eu~~ z0wJJ{(Gc{u0H%Yb;EK2-6U|v;CkwfC5=|}_;Ai>+`rJjb@nE+)?OwW~E!F$ja^8tp z+7~Cu)+xG9P&w-~8pHy%*&jq#pgz2}F%$uQSRDkdTu!`g(uHkHTDkux~ zGX7OG4>ffX7D(6?G)PZXth3Xoi(rcYlBsIujN;!hGH6sJGEZW^+9E#o#)}fK&tX7x z8v@OzcO*Y#lGYq8-(9R$>GR^RS6@6iGBXT-WmerWkFh(i|4xd~VtRJsbU0K6j^h#^ ze+44@{;j*v`PU?BhSr$n44)>K8Q$-r(^&zvv$ZdNZ@j&0FmV^2QUif8+?q35?2DuE! z{Ka46(oYW;$}iDdMSFnMblCC0S$`^_1P-md6_;KJy_B5g?kPM(x=B3{vcDhNcvCCq zoYtnpn11MAJUp$DDAVQdCytccWkUO5j}xP7UD~I2>MNjjvo1_oi*frIGn!>wWEl_Q z=r#FPi2Dn;+kN--*087`eOUEgGO5asocNDJ z5=;64AVtbCi2jFx8Lx#((c!=PRe=!BFx~=<9(q$H$UQ8_YHRA)%3^;l7k-paNv^ji z$3a&4F$xM4!qjpfzj(P8=(c-%HOdd-VR%UvhssDK6?gGerGk?<`RPATg!U?`J+V(- z)SK?gNa%N3C<)*^3}C#L)B(;fxh!4LkLvkPEN%P-k0b~mfvcEd^oJ_iJEa^Pt4p-v z0h}@IV>ZA?7EZ#d!4sdK$b#q}WINFx)CQn>@L^c7UryKJ!=E&7Qo9NDPJjAUbS{i6N zP}mV4%Q6weZ5|%;r0^~vLONwFha`9dwjN8W^P&*_A!J)+0 zJ?!OB2YMF>EysipwgSy}AbSuZ9mluz&sD;N9d$l(fg~P!fC`oT@e&_^+l6zJucsgu zT+1!2^$L`NH-e$0;{_NC+hr5XY~kwmH)QzXY;r*|){wHBK%g;m#IAr@l7P9bE$>U76c&{h@Z@*OlXy4{? zf`oGo@bEPlc5k1hK0FkdShwJ4-6n}WI%v@-2-k4CsUShW9|Vh_fw;N3RKPpzX3sK! z)KkB_BKQ5~1`;0R=;XUMYFSeu9J@%x$oyzz#@clv$bx3X@>qP&_eY`z2oE2lVru9g zn}kC>4B@!R)nP;(f^>zF+An@PF@^+%71A|&>=53s5YXav01@V5s7!t%l_uDDB#R1e z0PP>ae#KkEo=`8~OIyAnxgG33$d|%C zl=0)oKYY`;)2lsOZ@+o|R^&uHUdp{rw1zGQ6S5PWqwJ_Mmr@@qQo41&GS$vF%p5bFVm zp;R%3)0hTh^$jhf4Y8zIa$D(C@~N-~}4nlt2^V5Dgv zcDnjrJY*5Vz14AcgN(?j`V8?wZU?Bk$abb0s{CV9Pb0C5)5SHXjs!v2L*2ZjqrW^6 z(3NXXw#A5;RbJqeGsJ;G;z8e02;VQ_0opDMvXt#_ ze_D{RQT+wqO9I!cbSs#C+5nf7Nr7dr9?1bb!w9cV+qXPn=lMpTL-iBG2Dx27GimUj(vh`oF%v2#`L@rq%CE`EEa-L8}V%gD7_f-%MK0d#DCj zdK_+hWF)Dth`0v_9{KM$n|O%sjeXD!;a=08U6Bak00_cana9=GuQYHwwSxNcXg^~= zl@#%)I_OgT&7~oX)3~^Y%YL~8y!!WUzLV64`|y!56DD}Ikoy*@=k7Jr`Ge7V4N0>e zNs!?diREF>9MW};zQCEYd_cy#L4-a=xD++KcN5s7hje=H=Mi4-` z^W0Bn?=k?cvrH*RWE;R%HUu%MFr)?76s+_jP}q1ptp$gog5lAB2`qE}l2D7};hB+B z5;=zFDw$+c4l3ThHXz31QVaGZko-$EvlTEt?&x~RZ)%4-A@e`EeHY_wSfL29#|~@5wa6VJ^+I+|7cG- zu#s>vq8xbZ!7xdJYDI8f#3qf^o&64qcQzA~PpeEaO6a+VoO32y zjW)6j8qV9D0pU6H>YjmtwIWPVKhk@tDAGy>#oZ5o^R5b!+Fb9PdP@;*bTDQxtLA z?27V%jwKi$pS(q21yw`ruDkXh!C-CavnfF5C!o4GmzYV;9Md3pb?H-_{YYAPcF@>8HNc9XXu>5&Wqu~gtzX&)HNkIKu z+-cN#jdL6Zeuj3FU%qf!O%`JM3F(;u(4_Q%eED|c)7AzWnx3%UHflJ+L9&>d=Sv{K zz7pTLQLF{765YMfr>mlNzFi9rWl8O7vI!lV5SNk!b`OfRuYbHRKOKLd=@cc4vJK zjaWk&<>|x6KRg4YhR7KggiZRc@%%|`xg)wpl>1SOer;hrFQwQ1wT!wqHa$6c3qsah zBM>gU4E2u$4fbiWZ#)4$$t6q2Otnc^b}L>AbtxtceAwuPAo=7)U$Blf zpdH4t>sWnr9j5;z@nqe}{hUdTmahELHJ5E`Bq}NT%-)gHtXHA;i?N<7U>Apg>?{o< z>Ia4#(nv0AZ6>`)+WK82D9lKGFb{N)7LQBW1<<1_G}96SY@j%!k>v;b8^R8ozr1d5 zhUmZTzI1L7* zY71NJC294c`oX}|2CP*%-Xt&)50=^HnJa!@$_*87N_?^(LZClhpcS!o=Y5 zu77`U2Dby%QL`a@Kca8cB(Q}qMfsTo<;Gx$F z*fsfN*V;mq+xi&}oWW`b%($=*Im821fCKe~R%9ctn#eXSH2Z5?|42bRBYmei_JB(9;BTvcGrEu z)~?=nIxIymUlH6M)StEMOr&@fbYJ3$r=*TDqEpLnx@+#CY2X?lcsLRwQNbYDh^Af! zGi_(|>Lj4k-HLT-2IKD${V#xD$pMH^h@uoQuG(ihq7p!4x082ZJdhPx7AXe;_z{gy zX0W$j+|M8OK;90LcR}9In;T=kY8HJJ^0oWDiC%Ad16svAaT+6es@(1(_1qUb1VQyH z%1M*7SRzeX1eVk&J6)0(R7hyOi8=va?_}TcI2azk^MVI(U~q9yR!(W8j$Tns`Qxhq zhMD$z-604VoOx5T{O2{!2Mjc@?whOOuP>~04Y94UT1Dx(zCUlid+ zc*HvPN(|}hpmy2zG2}0N9!%YbC)q!i|AXIMIDH#S$C1xsh|BKQh1f^a*Onv}zeE?Q zlh@Cifqe*;Y5MCW$ikJ=6e#d^+#3~z_ry;KT^ZwLc2K(rbw%8hb#3`Xw^&&=G6# z+y~nuN!e}M--8Y0?tr+;b^a5XJvc}j-bPt&mkBHQZ0z*03T$9A1)ahhBgbGt2nY4X zu@D6?8x7)XK{fENNOnXN`k?yw=pb&>8V_jOuC=QaI_43m4X|N?T zMg(Yep@PYt_2n2tMWBOxk!O>q01VU53+ZRI+MgFdZTj|Qp2ejGbw{_NAz^S`vDS=E zel#-^${lus5CYDJeeyy*AO}1Eb74LC1V~=H)it39ltkiC&S8Sl$GY(e>6}-$x?(4} zKO4gU>7Yqhuy^ChyUUSv;^@ea<@!Q@fr?-sp@{(ZpLP|Q$N#;jFfx82FERe2RC6-z zH%LGUlmtu^&N~jzF&Mo*2Hdi^L%*A{p$so^ z2@$ogs@?ZE9w<!xob2j-(?|g)%W$Dh(#!#73E0fp?mxl^qHL#XtId;g@B8T2xORz{o@l5leE|o2 z4{ox3U=X?*K`awh@l-XZsAh#{$z)rw#;&H&cyYLOs1q~P&t>Kv1kuP;C`GC-zBOx= z6>;56Hy_Nc(_YWYsc>2y$YQ1_Uy$=B<8I>_fenZ|MLAHI#G!H#6mCL0Wd}p>9KZGZ zENK?=KUt}y{UNT*JGuMUo6Sm(q?CEJNi*fqWv_p>yp!u(afL58aE^aop@qG90p)s<2(0^r)moGsjgQEf|!u?S|?^91Zp^%|*^YRR?maAyLKp zR!k!fl`Vq@6UbBt4|KoIm~6l__dvO-P%JHZGi=20RYuy*^k3oMNg?4uO@$we9QMA~ zd-wvuIBC_;#?qXskeg=dMqA7N%t6XKGe|EY$9jt+liZ}rcqngwI$J+wc-16jFU-F% z2BMP*ERHc<1}Ys7R^dg96}_13B*x4wOp6v~(@bQjkQtWrjP!JM0vOP9EPQ3jo1ZtC zrWEWTK4t;~w%e}oIq(dGcfq|3RU6sHP3e=6e(NI^lFB?o9GYXgjjKb8QbsO8;RWN0 zXzROyx3FF4YK<|q2$6Ix$N<600KuxNs}b_&BC1#4VZ5KE8k zHvcxboq{=yCGjrS-p3 ziGThCHeLYq1JB)@^WBH zu3+WH1L9Jd-0FUS1#Ano70qhy;Pn%P<8Rf&D6;f($mgA1wYJR)V!BI@Z2Y>J3A2(= zbsTkS?U(GEUFCCD+Y1(>Vij_Tjqh4pWx~d}I3ErYS3$m1)v{x|c+xP9GTeBouFy)cZ}#<*2=}3S;JZ`#kR8S6FwoqFna2w&6F`OGTzJ&Q~HC z#|+$3vSPJ(yZZ555O4!Y7bj34tFWfn*8Gb z^@>)r9vfL#xjA{{@C25(5~O=?P?7rHv;G+TM4d~0c_}_*5A(A;qfiTmg?4pDh0i8N zp0al!uF5+lF$gU#9=rhgSEL3WL+}dI(PtFqy@BN6!q~ixet z=bP)y)W{QT$QDc|DswbA&C5}tGX_QEuK0z9HBR$_)`_&YTXt{FN4pr&nU=RRtFsER z1nO<8nYk^h-)=K1e25MR`@)#8u{nH^EPqa8=aNd75w-=+*NZI|*RzgHKk>xI5w|^D zh0

Gx73VG)n1$Ea+dJHLU_8vSo6iMrJ|QaC+$zi}}`@9gbCUW7L>61Fy5)20wpyk zVvAH(`2JYtH{ZB%*k#3ZlW&WLuiRwTi16tpRo*8zKDn;6iW=pHW~P&J<(XczG}e7& zWoB^UNS&6O|0YA4$3=zn^rT@|!te+1`>z;Whs2Nq?!?wjFR5#9aM!FEm^1QsK*O5ogQlw=Ky# z0)Z6szArl6i$;g9!f`I%ZnEnyDao9hUADmVn5mH-loqvb^1s}_$)Fc1*GaHNYcFyj z^gU*{;imqX7AH0q1_jp1Y8mI5?&uwt8GqlgiF)7SomCyD4!I&HVH z8UR7039tq30fysyvb6dcmXsGIJj%x-xDA_*Qzc5XR>}5B5fd)PK6+I=j#sW7H9QEU zs{EAvNon?njFwBRY);Ky{wO_$|5-<+Pt_+4;lYw;I!Wfg1fPwe6fMR_(tj)^In;a}x5m-Aad?!nyZvDE~R24$MSlw!z z)yX%h$3^AZS7mAB%EIFd+SW?r)kWYSsZZMk`ULwAMgGQ%w6NDoULU{v5Ck|sjo2)I z%0J>-M#!WiILS}gMviS{-E;Z9(XQ#0Y}2x|DfC?;F zm<~&B{$QX?pDR^k5EAM%M}}Kk@v88K#>3;Ed9(>S9s6&4IXqc@H*{&c9c~fhGt>*O zSkHpbo9US^V16-?n=*Mhwz;ZSZ;`ExtxQB$fgp*g-PIwK7h7^0JyEuex=MuFXxmqP z-8@6owt<*hvC5_L%x}2%ecxrW=@zyC?@Hi{4LGlt|Nhd{GP<~)YX$IEJ_it+BeQj$ zZY5=e7GgC3-f}D8=du7jLA$*m@6{DrM7CwD$)n3Bz*5~{n=Gd@6wO5g%S(e6u#8H zpw%BzTc&ZhtJEP1ZncqJcYwP}xEPUHje&cb4y9`}9|~Y{CaS!aT^8TDzO1lfZ+FIv zd8dHA9R0yFM$az6?IM#p?*_uE^Xi`ZhdQGzj!>vv!N+%PPw?tO^u`armLAMzFIH|B zU*8qvlcOCDTPx6}lcK{hM|t+@yJ;JYf!M5-o`5VOi9KSgF2@TgRLBV` z?G8hdq<@R`$bRj%<&F-$;n&di+&gF4??1uq$*bfywX@^A%}Z?1mbT8+)-ejV`;@`L z5jLO}c_SjASWg*;1W?7TvI!v7?knTY8Ywy@UTqegO>}M%=Y5L;^XUcL#)lU>B zHR}@~e5~gEnqPf2^(t-YeCFS5_umDJv)`uRnYpq;r?ykm5IJAIKNA7@3vEa-TIP^C z?^iCreNvR5mX?zX8ID_J+KNK%O#i`q{QGi8*u>)_O4+3anI1;$TR__1#4a+_cIOKF zHA+GC6FtK4cwFaZP;ZCDM6}djB(qag`#*a7E%Cg4V_47R$MBa|vefgQZ05aNC=WL$jU*@cvwlzK7z4qp#{eJ7~ap)Q?o zee&-&SGrPIor+M&c-~(!b_6?+;C27d81(Dh)CpWY4lh}<_3WD~^R4Fj_j_OW6-Ap3 zdn1bV>fYqKbQ{oc)s}+#d?cSuqSf&x%J-B)_IH1u;YlK%;cBr|#d(0C;nVI*N1cGx z0I=(x5-XO97%Io|R4bfQrtSZWBc6LE()!Bu`bO`C59hx0vT`l_fQQcx2LhmKOz+mj z|GJ@vC#NRwwuL@a1fD{&NNJJ(bLlq0EpLRF_N;AcgVu zzN(Z}e{Iv9C{e9rK9KOviXRlZ{{I&NVnyXihOe;36&h~zRNwD=Q0}=Yz{U_9wJ^>) zW>v~grjI?V>HpC~@8d=5)W47c>D#;2(qMueYM^ zI1gepn|t*#l(P+c<8B7g(lFPS!ZEIj0Udnf9v8_KAD_~V{M*Gob~7Tj<6-WkA2@EOErWa-kki0tm3q#qA@s^iFZ~=V1RetIKv9QFxxs;C69VwIK^>}?6gSx z$MWXshqF%Hw91$ZXfh{v8Eb+tBYr%C9%sWI_9dQTdw+Jt4>3JpVzXu}X$!`qUZ-d2 z)z^~$x+{p@b@c>bu>_q6|b_~EYSGhGQ{afQaWP8zc-Iv_x`tjBm(3iz*te?>3@IT5BqkD^Lal2B7Vv%+BAJcq$lXQYwXI#_Xm6XY{N0X z{R`~Of}ghA&|B!W#@~Ut^#&Cxqpb*63q3OiAIfOCA_0 zomC9}tEW8GaazKD;gW!|IhC1Rg6m0hY!1cKZ=F)j{v58N+m}OGlp5^3?n``h?n#ty zDmyoYhway0tr2=kc=_*U-6isL4_1^VW}3-35yC5K7UF?h_!TGp`^V3D4qmvNa+|OQ z^${SU{)op~h&xx=Q&Hu0C&Jr58w2L6L4;^R;giXo%K8&c(_T2Zcw0okIsNc)p;NZw zpECg4^Nk6P0SK()f=x^`0=jSiDvbK_)_u>8xj6F64O{ZlYSc;hzq-Ze{wuc);~LI< zw8qP*li(LKJmdbT=w^BDw=(;5II=6*vmzwg-O`;`l0G9H*=WvIshG16ZyB^8@$Lb==g}v9aep1v; z%D8ERy5qZkn^~KEQbGCp>BF(DsReP$%&{fqeI^eLRtY)6F!H#07N|}S^9}(Z$OhtL zZ$-t^MXQ=$D$@S)3@Zbm&+}2I0waLwYGT29CV|W{2|=W^2Yxf4my&doi{Cq?!$^oi zAtu&J0U|rcj3WMVvL}QW?S>mpp1y86bO%nW5#w{r5y3OEveD=vxjg0iNjMeRX~O1N zNp0OjvIw{h`G&RNVKR%qeyBC}3~)qGnhx|s_8-zPe7_pu2efmb>u)hYs@`l;I##f} zdw%xd?wVoK&m;p9F{7FP+l*NKPCaIoLhH}0L4N8QyqG13u9l?J>0|MK z&5zR#yDt62bIMk`*lIkEMW{88w&$JiLod)UrL%@b<6NWSqapWir{64c-}=~~=F$vd zUpr1d89?T`c}mw-gzly=MTFVDXqD*>?iNZ?;Eh8W6e?wFy4X#T@{Vp7Y5C__a&0IG z?ASL)upO=%_3I-+g6@W9mEmkzu-j-+Wu&i{C3fN^U)yTFMQ=Df#F7sJQN|b5g(`eS z!B!$A*{D~k5nrG2PZk$VfStggb6_;ztoPa@+xhopAEZgYb0|p(ipXhD$YsUjAW95p zj5c7bIuH3h90qjy305BI4XSMzA`fpG%1Iw#@4+^{(^3k#_st{eP!)CoYgI~*ACSdU zj55#-QD~P*@ zqkrFQbdtO0xUza6W$)|b&<0}eu;{p@W$6-DRm^^c`@w)X%6L;h?S_59j#w**-CnTH z+XNLZ**;Dse-*7>9cB(!h+ABA*mA!b?S93gpqTo`SkvNd zh@NSR_o0|kG*N$k0*mB5R@DN}4uCW1zO6~V&hF}IViISs!l~YKn`?$uo~u*M!mNo zwIlab@qFD|t|_XR73qG^AuiQLqf+aT$hl`p z3is)=aExN2$Jp+5%1!TSdB3~KRcrTiYk4N6hJZMhVnLXd{moksSYcY^;Z)jl!%2_E z=sH!WGHWEXSU}Dawn9aU>*#1Xa&J|TU771yC@P_@i}iSsRneZ58P(+53B~7^F&4WBly8XZW)f0nX*+!?S0yQ(INNy?}-q4=cIjot*7dz-i3~=>oG8GbCK= zeV%7x9SZ-UYT6lb%AnviE?Hc~g30(qBI^fM_0lhC7d=)47~=5{24jlU^UYt%08aJ=Y=SfJ!EdLr!Bu0PwxeBhVmH#AzIA0RmHmfjZ4MQ@%b)(~uTkO#I3m%Z)d z4Sd!`z7AuG&qAqK2?6o$B3~yG$E2V%rh!}|2?ZSS3){xxbrJw?3Q&l* zfPMH_rjzh0xweX3Y}veUs>h+%RbJuq`x;FxLH(V<2V-lLpa@~JAm5cNcfxf#&V#yM{OmC;6zJnOzrtaQjpo_U8B(Q=Tr!Dm4ql*s6032N+)%d9Q!cU zkupYRZt<#3!Q54bQ-8qlHX~HfX)X7LaSv^3ya=!6=HB~(1i5&&>OBs-=FBjoD)@fi z#o2sYv?jzM##9$ck~Rhf7>;3cfUm)R<9KxI_hW0Ege8a3IY^bD0+FKDy!1fIG{wHQ zC2MRyIKFC}L*Hl)nd46!`!cQ3n-)FYs0a__K^Al7=H0 zXHItS$Rk8dZm)=-JWxgiJrFdSJplXLz9HsD7vyPqz#E*Z5Zn>N`(+B!uh)LPT;-sy z(I5!2|IBf=jgWYb`;ppiC-qXOHP0NEw#3ntXGnx>L!%)z$N3{MDQV=X#?}f1qwGJ1 zxPDMJbqU6Dr?m=m^4sGr5>UCL8BU-d+tp*r;BUoqkI+36MiiYvoUF#oNw_ui<#*Hw zVArP8>5u43YWh06B_)Z;1gq9QjM)x7N;@FxHOxhd?DKX*@fL3`+3}aGU$`nKEyHcciqmYt5JfXTGl$)*J>{kaxRVM5l`m-8GH6si44zcdEmhOe3i?!+*4ToHow zDlxwCb#@QW8m6&jj)V~vDv~`dyhu`#HN?DM^`&mX+NZ;4)FL`a{oCMm>4(J{hN{T`^-|yZu?3)izR|$L!_`+%L~2{z`qyjWc>3ID_swF6(r`2(RUx`+LG`@ znNB6PAD+hjDrhHV=ebicC0PE62CL!GNnY~)k(#6wWY5aVkGXBTw}_!C%wGj{ED^0d z2(j}(KR4KUL%VQ&^98SRSu)aan?{4n!t+sYPY}uMli?bVzS`V6iOi@Dp58ge#ib{s zKY2$I>K^a3)j0SLxPJ67X=5#i03s^K-hq^?6jiQZTEU%@{?@F99h{GkyI; zbw}r;C6RbO9{!#=zN4xB3Z1(8O)ZmWy1XuBQ!^f}JQT8_X0BFeIhLpRl{+J7e0HJ- zp<7T3G~dmedLtFQxj*Q-tw#t>L%vtU4BA=mlk(lXW2rgGS?%{`zq&BpVR5QTlNy}( z@FKVBhG;h`2(ZX3`g9Vg9~HuCpf@A|yCbrtD3dRLo3!=CvQI~GUu@R053Xse$^$dS z^%%6@6DPga=S|XG+oPR{m1CdF(&e%_`89P>Ef2rTLucz+uoZ!CQIfR_@v}aC+UsXy+VQ_$P@s3ag11*7+p`+XP9g?NpUX{?2xQ zh;Dw7awjMg+pkT}z6Pd!%4$Bue&L^zzbzKu$~#llY&+d`!_Brhb`@1TT<}x2y`hM+ zD&CSNt+T#>3QdH_gLn%eVT*92jsz<h z%I(1TB|TmoD%T={;ISLs2weQVhD^V%edl38&)M+w)+nw|j&M z$*|4K(;h!s>aJz&72zit9(B%`;_tbFX+sgj7LlWOUM6ZUV`k1W{+n#pyI-6FLchJk zP&MDOSUnlNRRS9xeNw|VXQ%_n(^Uiz-u529a@H4msl4C#xk|-)@*WSD%|_^&olE(& z_O!-`LaS+Slr_}ZVtQ7WM>|DI2AzaLrh2!9Ym_D*##32;5w+3OS2N1cNeH3V_L*r-nY-PI zvg(SLshK1azIh5|Pe^e~I z@sLSMP*|>+gGj{Z1om^3aI)Iw=)WXA98k>LP<=1BntppK*@BbC&6Q@Zd5KKsnDLAT z9)vf~);ube9aSg&x*M}?d@9+@4c^aFl^clCCi3X4s7`S09C573rrTl)tYbo0_+)QCRi!RiiimmDDy)Xy>9^rRmsez71;sS&?$X zQm+vOr-!#u`WtkzJo8XmS1*ZmpAiPExYC4+BW9ligvAb=0edj(|_PrF*gxCdPdhDugS1v0?2_?8<$R@`^ zjg~xwZI-yq*{ovOqKZXT+cBf%R}VCcbRDGbnhi%G)+_Rog(5#mi^!F|Wajtnh8u&D z{>la&=BDfb3K0pjeDdylOdlVHuyaEp4L*PMm3PLXOb32;oWgI*1Mv8iu9Q+ePR1u> z4BmS2VCWi_;l_FPKHsb=JlUYKZ+5zuFw9ZZ94UK2u?Au zgI>ifrr5mn@&i~@V99$cy z?bM8Rsxe;SvvlFDSc>^j{CJpyxueJ6CFLPPB1-iZY~R;60If2 z5O4A}J~9qg*7=_?h8dlm?yCvB)19!NyrJFak~@O$>~#_wis#&WXf<|gwNqK)Q~mOy z6QUwLetdMHYG@1dGj3)csX$|bIGQ{>IsvEFP|gb9gaVYHENzG8gG7y|(X2T|AU$1BvjSPj@K-UU;xK;DJwX0|wE2lL<^@;G?9?{v@ z`pwUBfE_=AO2h$|cuT`8_5eex!kbCYPrm+CpJyT`q&K1hzBj4f3}q%pLLV;nAZs}Z zBbujqYr^|C)FkcYmggM2EIEwItCl`%l-f7E>So(w)hk3`Ngi0m`Gzt)@Yz0&To58F zG-V(rX&v<7iVHKLAWPTgvCGqTMb9W#9Wg3{V{h!d7qZ(0{N>#TT6R`FsI^or^FR7_ ze5!D18W%$b#r-%a2o2HyVBbcpi&Us~v3oPmNir%0aHaOnVgaFWw4_Cp^cDSvWH^;Z zBR{qC;nSVQ>EN-550+n_*E=7jcM$1T>7{h1<%rcaN{BEA(pQrky$BhZAX{XnKh2-6 z^Lje71cBtr28ge1$ocTkg8uC*gby?aZEooV3z+^oZsWqwUy!^hb&cwwQ@A4`7b_RL zvys+Zuy&?jNASMkH|EAHiP0|cnk64g>-El(72c3+kHWOFgKU^;_{wA!=PwR^E(RpV z6D<+p(XcT;Qj(cArD%=`0andQtH62?lz%YtvPX!Yxv z<|KGT>`=m6FDX;n*lV1BA@xb1*M2GrV0kRxvpss0ct#|4F6KnwH?TIC5oce!-3>ht z-{15}K>I1Yip7bdh);UJ~Jdjh4P90@s!5zAEM?#yCws@`VnmKQku)Tk zSr$LU^Ve}l{{DQxV>W3fN8&?xo>lgqOCX7Su^q9En=f__(9~3d3x0!8$K* zY4oT~i6t|7?``xb+OoBZyzro^xW()oMtEu?ofAeaWbdEJX)crDs- zd0rd~qz*=a4ze_2(XFXELrM6zOi~a#*0M&Kb-^LBZO=A!p2K96lz*h*ZuwGyS6*MS z&2Vbmmyd4Z5o0|vrZF~O-7!PX`oz<><9N2l@mAy&KSnUV#ATgRjAQB*+0zX_uIziB zBbtCM*_9Jjw)PJ9JC}NJw^9kpg};b~;4 z*l2x%Ium578R^8>hWc(U( zcF0j9?ys@u{E3z+9;dYp^Hm_rseDQ{@>dJ-EVM}P=aZfdlyDr>xg4#5B+EjsGU*sW zO4VQ5hy?UKNXsc#sqTC)U>LM!d>)3okeG3WLT&+(ZfMHPXNuPt+oFJ&63FzU4YHKd$Tp6fQ2__kio5Zl_+*u?Pusmqluoe@FP39 z2s(7zLzuT=~dNt%%6##r2g@tz-6@O^r`OiumQG)(^GMJ?NFB zW(Wi`H|rBEWjszz0@{3h*{mee^QZb#B#WkgN4NtU_fADbnB#8kJye-V+R|9QoC4W# z?`tQ3RJ%iIv>d)w8TE5(SDg9ticaECRxM#|M4-0?2*`P!x^B+DRQ$Lgc&}5>ekbc$ z_aOX|P04reGvH7`^t=ndmqN{?Lnx2Y%z|2>59<{c)kT$z?ukC*O#T+M^2*n(ua9~X ztGXt>cJQ>$1IZbG5=)#9?s*5IL`=HDg`mVoppkNyYiKL;gAv;oC#&0W7fmOx3Pn@?oPq0P7b1o{#LRiSAV1%#=IB!cQ9V zV4}oCJ6rdD>}&tbz3IQ3Rwnyp**~HQM~F2TtPt;oAvXP$UpAf6)zF8Y7TOCIJfJy1^L{g6mk5Cn;S6UWfMG9lm^B>RGaW&cH{No*yzwWROgg~>n`YzbMytwQn~U=h83 zwL$FS(dO0n|AXGrL<#sm&jC5*H~@p9mdHH4`dPAd`gY<5gJw@ff?j2~G`#_?{=3V! z1-o5U5393V|HmtFwr8LOqL`vxBwntPp&W;GXT+^GL=vbP|LxO1AQP_@nOA`6flZmx z6C-w3;6>PriY0e)J+qWM>xQ!mu;=a-^CMVNTKD;jlbl%W_plm(R@wzO7q(2KNCqUF z|I(zpfXgG#REgC9>Jtq!l7KE_2~=afDES(z^*A%7M=1! zV0G9PLMiv;3AP_Nfo*+xc#_IvL;klN@Sj}?yd|k~jgDj$#XuKsCD%s*zLI`v2g|Od zZYgume=sHfSsYHhxtZoLD<&zxSTL?o{T9Hvn1SJd)v>+n?0&uZ_N4Fs;6&P7SAXah znHILcg?8(CB`+=gIu9Is_ws<(ZYkj9#;K>zpDpwp!~p?`_@_gc!QQ_dElu+1XlQEH zfya3+CYs0eh zCF7Nk9v5c~Ey>RO;of`pdtTjE=hx3$Qm+|(UIhk3TwxXs_!;R+N(X>!fWrtGEi-o= zv5Oz_wf@Tu_K)Wa-fCRGRI(!j98wCpzLuDRhg+Un0R~w@#p+O@SX7~ifIWi#O4{Lr z@hXAlQy269w?14FXUnx{CyLydd8$|stdV4aTa4g>h75QVN&rm}Ilq z{FesBi9KuCa`EstwYDb;-?06L8o`+>_1*nC4a^M>#YDmtoU~~{q3%bJll3Z=%fjmS znS*24)T!z9*=YEu3o5av;>azS{o`ia*_BV!=+Tq`KMn)Pqy))6Cj0lK$elQ07ytvd zgh`Npg#$=a4pbMK>Z&dpw!e9iASk3Eh~Y)$+ZObhYD#?!XIN~S`paJX|KCX*nDCz8 zTZxsaCIlWEA;4g)m6wh3!-*F!CB8(jBp6zTz;)!)1DNCp<4J~pOLtGZ+TA3ET9NJY zZ5Eo?16`J7H-28-V^7;?JefT=t1Xo=;mMUwuV+*U zzgx*LR>LY>&36<|)jOiNUPeNruq15CrRZoSTYQ~8ir07uCc$UiN>cpZ?ZW8pJ!8p; z_oWp%>Qq_Fi=aUYion^wAv?R5rq2m{G zE^pk*Yb8WgHw!5fsZNB5l}Q9Rr4%GT zF8L_c=Jz1waj@3YfQDa68ZrvE;~a~GZ5rRwXy63QrF?$&1~2GtJArT#J^C||Fm8#? z@Lqa@?A>KHr6ccM`EP9=mkI*!Y+2F9TVCfZ%uaU-K$g-*GAeGpNuO<<$2?SsyFj+; zAFNhiKO@ats$4nF_)hMVnsgl_#D1DX^PcE8KQ`|lBYH&8-K3J0hQc!Uy^Xt7>rpha+<_YB-1P56mC$oR~U>Eh!wYhYD=@ij?mhJ0SAD01F}%I0LKXp%Gb!p&7gE8ofe{ zHQ01Dt*^O+P4*u7L#o%3mVe6Y!Z&(yM*PvdL_a>fbnMR>u7>&?%=QLUPh^r ztLI%fJTB-Qk8&!R#fX@G``(%Ia&m6Nq;jUFHGzk8uAnrK_*KZK27}@+ktQgir0nsE zKw|Sc%R_y$qO|VaH`%6S2k9%!Y8}w2Xxqxpi{!%jh3IKD`K{*9=J!O}h-W_zG{xJ? zuQZJZlG8kmP4Fh6D*Uclh=F=$JU_xwkClj_%Narrnp<{Vu2yRQTJlN+$;bECe8{?l z-DA!yl>D7^InPAnBO^-EB`+_s(eI#9zX8U5(D9?ZLBEOxMZ7}K&pB4}ET<<>+oR+~ zQa(8@Yj4Ecyee}Y{X8Wn&(r|Y-b-lb;xFW5<@Sf#tRi0Bmo)Qp4%JMW$L=*Zf8qX7 z(A3kA>Z%;`qXF|Y?rjrgi^Lqik?RZd_0D9a?RdN$8WR(^Fs_itYOtk=_Ko=DJ2$bN z9(iu09W9RSeuo??9vwBekH(k@Edv(&$jOP=Q>iy{v+yM!op35gJfhytdtr z3?7c}g51=No@?;i}FF1R-*v-h}9Rr>`FYLJq@e9L63~=*!!*h@nRIDKxmRgB@nE^=Pdkk}4`Ze}J)ErK$|i*O=0iFzf+OWVpSX_m zH!6~q0w?)Lwczxn5n!k}3LJi)3kFomu64%_j|_F@*j;vd{Kb8&iOIglVHLJh-mYkF z6HR&iad;QezH%iR89?^3M@7~@g>TtAqdY;@W|fEo;324 zb@jhjaXsq`U%fNA=)}Bwcpg6Y;^0y!(#U9Ui*lwiBTu7-<;|6SeV9EeVwpV3&CB(w z=$@I>BXkzRj0K zgcyGN=XnA_>tVS&PrZ~B;Xl9OI34cV>;Rv~j1M=!uoZ=3uLrE4P^e#{oTM8*?#Sk$ z^`iD7;n+F-@m)a?NT#kO(xI76c#F+(ER;?7rzsV!R>sfny@nf?em|ws^OvUaTNARr z=N!wlt7|=P*3Fku0Drdp+ouq-G#mV*{O#q=X2=nD^N%L$84B?v?O?B))1-wo)46D0 ze_cB&rw5#6SHMY<)^6KN8pUGQvg^`mSamDsr!5Lk9DwOJhU9dWzCpr^oUKoG_s^lP zEtrQ~bV8K$hYn$rLxte)cF$nSor*rD9fTad&Q!UvOdHo`6xX6Vty{CIn!b*?j=N>& z#zEG>kJ*D_#0#xPLEUA3)&{mR(13Fnyk$kn^izELwDPsIB1p)`4YS)TiU(6mN1#Z# zNAc0ocI&0!$UqVY9VioOVuiK}w65D-zV0P7~LZH|k>dW8nS z-)v4HUU<19P6*u*FS44gUG{3U?cP7*nn>o0;&bKVz+J({Z0=O9aC03ydjA49MYC+~ zt?q(H!D(vE)#_RimCAkt%47!(5nNda8AUQ)o$QoP1^bSyMW~`!#on}Xeoc#_et+1j z7h-k>h~k;gb8fOafBhoW2UvTq86NaZUceNi45TY%qZLjSu>wwCT~LhziFKc!?*o1K z2r$My@#Gu@&fp{9fXI2vkEnxO?cJW8+X5EvULp6g_nCDQes>6mpw^Ez1pfwvGVtmRLL*B%BF8 zMZor~YgiL_h7On7BmoQM=wXn;-HjJ^GVrnqq+z^_je~80FO4qQP%cnDKo(lAfAHQySGJ}W^re%Sl>kI?C$ zwHC|zlH8h%=R)>X(Q7KexT{NrMN60s#plprf7lSzlp;yBeiRXlxW-aM0p|v`Zy&t&6Z> i)Bs?Xqe37y{$~!=PUBc}k2#A02s~Z=T-G@yGywprK313j literal 0 HcmV?d00001 diff --git a/docs/zh/core/architecture.md b/docs/zh/core/architecture.md index 083e1a1f..6a68f597 100644 --- a/docs/zh/core/architecture.md +++ b/docs/zh/core/architecture.md @@ -47,6 +47,8 @@ precheck 集群安装前,对集群节点进行检查是否满足集群安装 - **containerd 版本检查**: 当使用 containerd 作为容器管理器时,验证 containerd 版本是否满足最低版本要求 **nfs_precheck**: NFS 存储检查,包括: - **NFS 服务器数量检查**: 验证集群中只能有一个 NFS 服务器节点,确保 NFS 服务部署的唯一性 +**image_registry_precheck**: 镜像仓库检查,包括: +- **镜像仓库必要软件检查**: 需检查 `docker_version` 和 `dockercompose_version` 均已配置且不为空。镜像仓库通过 docker_compose 进行安装,缺少必要软件会导致安装失败。 ## init @@ -61,11 +63,11 @@ init 阶段负责准备和构建集群安装所需的所有资源,包括: install 阶段是 KubeKey 的核心安装阶段,负责在集群节点上实际部署和配置 Kubernetes 集群,包括: -**install nfs**: 为 `nfs` 组中的节点安装nfs服务。 -**install image_registry**: 为 `image_registry` 组中的节点安装镜像仓库。目前支持两种类型的镜像仓库:harbor,registry。 -**install etcd**: 为 `etcd` 组中的节点安装etcd。 -**install cri**: 为 `k8s_cluster` 组中的节点安装cri。目前支持两种CRI:docker,containerd。 -**kubernetes_install**: 为 `k8s_cluster` 组中的节点安装kubernetes。 +**install nfs**: 为 `nfs` 组中的节点安装nfs服务。 +**install image_registry**: 为 `image_registry` 组中的节点安装镜像仓库。目前支持两种类型的镜像仓库:harbor,registry。 +**install etcd**: 为 `etcd` 组中的节点安装etcd。 +**install cri**: 为 `k8s_cluster` 组中的节点安装cri。目前支持两种CRI:docker,containerd。 +**kubernetes_install**: 为 `k8s_cluster` 组中的节点安装kubernetes。 **install helm**: 为已安装好的kubernetes集群安装额外的helm 应用。包含:CNI(calico,cilium,flannel,hybridnet,kubeovn,multus) @@ -78,6 +80,6 @@ post_hook 阶段在集群安装完成后执行,负责集群的最终配置和 2. 设置脚本文件权限为 0755 3. 遍历每个远程节点上 `/etc/kubekey/scripts/` 目录下所有 `post_install_*.sh` 文件,并执行该脚本文件 - > work_dir: 工作目录,默认当前命令执行目录。 - > inventory_hostname: Inventory.yaml 文件中定义的host对应的名称。 + > **work_dir**: 工作目录,默认当前命令执行目录。 + > **inventory_hostname**: Inventory.yaml 文件中定义的host对应的名称。 diff --git a/docs/zh/core/image_registry.md b/docs/zh/core/image_registry.md new file mode 100644 index 00000000..93aabcfc --- /dev/null +++ b/docs/zh/core/image_registry.md @@ -0,0 +1,245 @@ +# image_registry + +image_registry允许用户安装镜像仓库。支持harbor和registry两种镜像仓库 + +## requirement + +- 一台或多台运行兼容 deb/rpm 的 Linux 操作系统的计算机;例如:Ubuntu 或 CentOS。 +- 每台机器 8 GB 以上的内存,内存不足时应用会受限制。 +- 用作控制平面节点的计算机上至少有 4 个 CPU。 +- 集群中所有计算机之间具有完全的网络连接。你可以使用公共网络或专用网络 +- 使用本地存储时。计算机需要100G高速存储的磁盘空间。 + +## 安装harbor + +### 构建Inventory +```yaml +apiVersion: kubekey.kubesphere.io/v1 +kind: Inventory +metadata: + name: default +spec: + hosts: # your can set all nodes here. or set nodes on special groups. +# node1: +# connector: +# type: ssh +# host: node1 +# port: 22 +# user: root +# password: 123456 + groups: + # all kubernetes nodes. + k8s_cluster: + groups: + - kube_control_plane + - kube_worker + # control_plane nodes + kube_control_plane: + hosts: + - localhost + # worker nodes + kube_worker: + hosts: + - localhost + # etcd nodes when etcd_deployment_type is external + etcd: + hosts: + - localhost + image_registry: + hosts: + - localhost + # nfs nodes for registry storage. and kubernetes nfs storage +# nfs: +# hosts: +# - localhost + +``` +需设置 `image_registry` 组 + +### 安装 +harbor是默认安装的镜像仓库 +1. 安装前检查 + ```shell + kk precheck image_registry -i inventory.yaml --set harbor_version=v2.10.1,docker_version=24.0.7,dockercompose_version=v2.20.3 + ``` +2. 安装 +- 单独安装 +`image_registry` 可以脱离集群单独进行安装。 + ```shell + kk init registry -i inventory.yaml --set harbor_version=v2.10.1,docker_version=24.0.7,dockercompose_version=v2.20.3 + ``` + +- 在创建集群时,自动安装 +在创建集群时,会检测 `image_registry` 节点是否安装了harbor, 没有安装时会自动根据配置安装harbor。 + ```shell + kk create cluster -i inventory.yaml --set harbor_version=v2.10.1,docker_version=24.0.7, dockercompose_version=v2.20.3 + ``` + +### harbor高可用 + +harbor高可用有两种实现方式。 + +1. 每个harbor共享同一个存储服务。 +官方做法,适用于在kubernetes集群中安装。需要独立部署PostgreSQL 和 Redis 服务 +参考:https://goharbor.io/docs/edge/install-config/harbor-ha-helm/ + +2. 每个harbor有单独的存储服务。 +kubekey的做法,适用于在服务器上安装。 +![ha-harbor](../../images/ha-harbor.png) +- load balancer: 通过docker compose部署keepalived服务实现。 +- harbor service: 通过docker compose部署harbor实现。 +- sync images: 通过harbor的复制管理功能实现。 + +安装示例: +```shell +./kk init registry -i inventory.yaml --set image_registry.ha_vip=xx.xx.xx.xx --set harbor_version=v2.10.1,docker_version=24.0.7,dockercompose_version=v2.20.3 --set keepalived_version=2.0.20,artifact.artifact_url.keepalived.amd64=keepalived-2.0.20-linux-amd64.tgz +``` +1. 在inventory中的image_registry 组中设置多个节点 + +2. 设置变量`image_registry.ha_vip` ha_vip 是负载均衡的入口 + +3. 设置变量 `keepalived_version` 和 `artifact.artifact_url.keepalived.amd64` keepalived 是用于负载均衡的镜像。目前kubekey并未提供下载地址,可通过手动打包的方式来实现。 + ```shell + # download keepalived images + docker pull osixia/keepalived:{{ .keepalived_version }} + # package image + docker save -o keepalived-{{ .keepalived_version }}-linux-{{ .binary_type }}.tgz osixia/ keepalived:{{ .keepalived_version }} + # move image to workdir + mv keepalived-{{ .keepalived_version }}-linux-{{ .binary_type }}.tgz {{ .binary_dir }}/ image-registry/keepalived/{{ .keepalived_version }}/{{ .binary_type }}/ + ``` + `binary_type`: 是机器的架构(目前支持amd64和arm64,可通过 `gather_fact` 自动获取) + `binary_dir`: 软件包存放地址,通常为: `{{ .work_dir}}/kubekey` + +4. 设置变量 `harbor_version`, `docker_version` 和 `dockercompose_version`。harbor通过docker-compose进行安装。 + + +## 安装registry + +### 构建Inventory +```yaml +apiVersion: kubekey.kubesphere.io/v1 +kind: Inventory +metadata: + name: default +spec: + hosts: # your can set all nodes here. or set nodes on special groups. +# node1: +# connector: +# type: ssh +# host: node1 +# port: 22 +# user: root +# password: 123456 + groups: + # all kubernetes nodes. + k8s_cluster: + groups: + - kube_control_plane + - kube_worker + # control_plane nodes + kube_control_plane: + hosts: + - localhost + # worker nodes + kube_worker: + hosts: + - localhost + # etcd nodes when etcd_deployment_type is external + etcd: + hosts: + - localhost + image_registry: + hosts: + - localhost + # nfs nodes for registry storage. and kubernetes nfs storage +# nfs: +# hosts: +# - localhost + +``` +### 构建 registry 镜像包 +kubekey暂未提供registry的离线镜像包地址,需通过手动打包的方式来实现。 + ```shell + # download registry images + docker pull registry:{{ .registry_version }} + # package image + docker save -o registry-{{ .registry_version }}-linux-{{ .binary_type }}.tgz registry:{{ .registry_version }} + # move image to workdir + mv registry-{{ .registry_version }}-linux-{{ .binary_type }}.tgz {{ .binary_dir }}/ image-registry/registry/{{ .registry_version }}/{{ .binary_type }}/ + ``` + `binary_type`: 是机器的架构(目前支持amd64和arm64,可通过 `gather_fact` 自动获取) + `binary_dir`: 软件包存放地址,通常为: `{{ .work_dir}}/kubekey` + +### 安装 +安装registry需要设置`image_registry.type`值为`registry` +1. 安装前检查 + ```shell + kk precheck image_registry -i inventory.yaml --set image_registry.type=registry --set registry_version=2.8.3,docker_version=24.0.7,dockercompose_version=v2.20.3 + ``` +2. 安装 +- 单独安装 +`image_registry` 可以脱离集群单独进行安装。 + ```shell + kk init registry -i inventory.yaml --set image_registry.type=registry --set registry_version=2.8.3,docker_version=24.0.7,dockercompose_version=v2.20.3 --set artifact.artifact_url.registry.amd64=registry-2.8.3-linux.amd64.tgz + ``` + +- 在创建集群时,自动安装 +在创建集群时,会检测 `image_registry` 节点是否安装了harbor, 没有安装时会自动根据配置安装harbor。 + ```shell + kk create cluster -i inventory.yaml --set image_registry.type=registry --set registry_version=2.8.3,docker_version=24.0.7,dockercompose_version=v2.20.3 --set artifact.artifact_url.registry.amd64=registry-2.8.3-linux.amd64.tgz + ``` + +### registry高可用 + +![ha-registry](../../images/ha-registry.png) +- load balancer: 通过docker compose部署keepalived服务实现。 +- registry service: 通过docker compose部署registry实现。 +- storage service: registry 高可用可通过共享存储的方式来实现。registry 支持多种存储后端,常见的有: + - **filesystem**: 本地存储。默认情况下,registry 使用本地磁盘存储镜像数据。如果需要实现高可用,可以将本地存储目 录挂载到 NFS 等共享存储上。配置示例: + ```yaml + image_registry: + registry: + storage: + filesystem: + rootdir: /opt/registry/data + nfs_mount: /repository/registry # 可选,将 rootdir 挂载到 NFS 服务器 + ``` + 需要在 `nfs` 节点配置和挂载好共享目录,保证所有 registry 实例的数据一致性。 + + - **azure**: 使用 Azure Blob Storage 作为后端存储。适用于部署在 Azure 云环境下的场景。配置示例: + ```yaml + image_registry: + registry: + storage: + azure: + accountname: + accountkey: + container: + ``` + + - **gcs**: 使用 Google Cloud Storage 作为后端存储。适用于部署在 GCP 云环境下的场景。配置示例: + ```yaml + image_registry: + registry: + storage: + gcs: + bucket: + keyfile: /path/to/keyfile.json + ``` + + - **s3**: 使用 Amazon S3 或兼容 S3 协议的对象存储作为后端存储。适用于 AWS 或支持 S3 协议的私有云。配置示例: + ```yaml + image_registry: + registry: + storage: + s3: + accesskey: + secretkey: + region: + bucket: + ``` + +> **注意:** +> 1. 使用共享存储(如 NFS、S3、GCS、Azure Blob)时,建议至少部署 2 个及以上 registry 实例,并通过负载均衡(如 keepalived+nginx)实现高可用访问。 +> 2. 配置共享存储时,需保证各 registry 节点对存储的读写权限和网络连通性。 + \ No newline at end of file diff --git a/scripts/harborCreateRegistriesAndReplications.sh b/scripts/harborCreateRegistriesAndReplications.sh deleted file mode 100644 index 86375c48..00000000 --- a/scripts/harborCreateRegistriesAndReplications.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - - -function createRegistries() { - - # create registry - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master1_Address}/api/v2.0/registries" -d "{\"name\": \"master1_2_master2\", \"type\": \"harbor\", \"url\":\"https://${master2_Address}:7443\", \"credential\": {\"access_key\": \"${Harbor_User}\", \"access_secret\": \"${Harbor_Passwd}\"}, \"insecure\": true}" - # create registry - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master1_Address}/api/v2.0/registries" -d "{\"name\": \"master1_2_master3\", \"type\": \"harbor\", \"url\":\"https://${master3_Address}:7443\", \"credential\": {\"access_key\": \"${Harbor_User}\", \"access_secret\": \"${Harbor_Passwd}\"}, \"insecure\": true}" - - # create registry - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master2_Address}/api/v2.0/registries" -d "{\"name\": \"master2_2_master1\", \"type\": \"harbor\", \"url\":\"https://${master1_Address}:7443\", \"credential\": {\"access_key\": \"${Harbor_User}\", \"access_secret\": \"${Harbor_Passwd}\"}, \"insecure\": true}" - # create registry - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master2_Address}/api/v2.0/registries" -d "{\"name\": \"master2_2_master3\", \"type\": \"harbor\", \"url\":\"https://${master3_Address}:7443\", \"credential\": {\"access_key\": \"${Harbor_User}\", \"access_secret\": \"${Harbor_Passwd}\"}, \"insecure\": true}" - - # create registry - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master3_Address}/api/v2.0/registries" -d "{\"name\": \"master3_2_master1\", \"type\": \"harbor\", \"url\":\"https://${master1_Address}:7443\", \"credential\": {\"access_key\": \"${Harbor_User}\", \"access_secret\": \"${Harbor_Passwd}\"}, \"insecure\": true}" - # create registry - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master3_Address}/api/v2.0/registries" -d "{\"name\": \"master3_2_master2\", \"type\": \"harbor\", \"url\":\"https://${master2_Address}:7443\", \"credential\": {\"access_key\": \"${Harbor_User}\", \"access_secret\": \"${Harbor_Passwd}\"}, \"insecure\": true}" - -} - -function listRegistries() { - curl -k -u $Harbor_UserPwd -X GET -H "Content-Type: application/json" "https://${Harbor_master1_Address}/api/v2.0/registries" - curl -k -u $Harbor_UserPwd -X GET -H "Content-Type: application/json" "https://${Harbor_master2_Address}/api/v2.0/registries" - curl -k -u $Harbor_UserPwd -X GET -H "Content-Type: application/json" "https://${Harbor_master3_Address}/api/v2.0/registries" - -} - -function createReplication() { - - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master1_Address}/api/v2.0/replication/policies" -d "{\"name\": \"master1_2_master2\", \"enabled\": true, \"deletion\":true, \"override\":true, \"replicate_deletion\":true, \"dest_registry\":{ \"id\": 1, \"name\": \"master1_2_master2\"}, \"trigger\": {\"type\": \"event_based\"}, \"dest_namespace_replace_count\":1 }" - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master1_Address}/api/v2.0/replication/policies" -d "{\"name\": \"master1_2_master3\", \"enabled\": true, \"deletion\":true, \"override\":true, \"replicate_deletion\":true, \"dest_registry\":{ \"id\": 2, \"name\": \"master1_2_master3\"}, \"trigger\": {\"type\": \"event_based\"}, \"dest_namespace_replace_count\":1 }" - - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master2_Address}/api/v2.0/replication/policies" -d "{\"name\": \"master2_2_master1\", \"enabled\": true, \"deletion\":true, \"override\":true, \"replicate_deletion\":true, \"dest_registry\":{ \"id\": 1, \"name\": \"master2_2_master1\"}, \"trigger\": {\"type\": \"event_based\"}, \"dest_namespace_replace_count\":1 }" - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master2_Address}/api/v2.0/replication/policies" -d "{\"name\": \"master2_2_master3\", \"enabled\": true, \"deletion\":true, \"override\":true, \"replicate_deletion\":true, \"dest_registry\":{ \"id\": 2, \"name\": \"master2_2_master3\"}, \"trigger\": {\"type\": \"event_based\"}, \"dest_namespace_replace_count\":1 }" - - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master3_Address}/api/v2.0/replication/policies" -d "{\"name\": \"master3_2_master1\", \"enabled\": true, \"deletion\":true, \"override\":true, \"replicate_deletion\":true, \"dest_registry\":{ \"id\": 1, \"name\": \"master3_2_master1\"}, \"trigger\": {\"type\": \"event_based\"}, \"dest_namespace_replace_count\":1 }" - curl -k -u $Harbor_UserPwd -X POST -H "Content-Type: application/json" "https://${Harbor_master3_Address}/api/v2.0/replication/policies" -d "{\"name\": \"master3_2_master2\", \"enabled\": true, \"deletion\":true, \"override\":true, \"replicate_deletion\":true, \"dest_registry\":{ \"id\": 2, \"name\": \"master3_2_master2\"}, \"trigger\": {\"type\": \"event_based\"}, \"dest_namespace_replace_count\":1 }" -} - -function listReplications() { - - curl -k -u $Harbor_UserPwd -X GET -H "Content-Type: application/json" "https://${Harbor_master1_Address}/api/v2.0/replication/policies" - curl -k -u $Harbor_UserPwd -X GET -H "Content-Type: application/json" "https://${Harbor_master2_Address}/api/v2.0/replication/policies" - curl -k -u $Harbor_UserPwd -X GET -H "Content-Type: application/json" "https://${Harbor_master3_Address}/api/v2.0/replication/policies" -} - -#### main ###### -Harbor_master1_Address=master1:7443 -master1_Address=192.168.122.61 -Harbor_master2_Address=master2:7443 -master2_Address=192.168.122.62 -Harbor_master3_Address=master3:7443 -master3_Address=192.168.122.63 -Harbor_User=admin #登录Harbor的用户 -Harbor_Passwd="Harbor12345" #登录Harbor的用户密码 -Harbor_UserPwd="$Harbor_User:$Harbor_Passwd" - - -createRegistries -listRegistries -createReplication -listReplications