From df1a3ecc0d529c6daeff3c39d8fc8295f0b0bfc8 Mon Sep 17 00:00:00 2001
From: qyx <565485304@qq.com>
Date: Sun, 4 Sep 2022 22:41:47 +0800
Subject: [PATCH 1/8] =?UTF-8?q?[=E6=96=87=E6=A1=A3=E4=BF=AE=E6=94=B9](mast?=
=?UTF-8?q?er):=20=E5=91=A8=E6=9C=AB=E5=AD=A6=E4=B9=A0=20Spring=20Webflux?=
=?UTF-8?q?=20+=20JavBus=20=E6=9B=B4=E6=96=B0=E4=BA=86=E5=91=A8=E6=9C=AB?=
=?UTF-8?q?=E5=AD=A6=E4=B9=A0=E7=9A=84=E6=88=90=E6=9E=9C=202022=E5=B9=B409?=
=?UTF-8?q?=E6=9C=8804=E6=97=A522:41:25?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../css-webflux/reative-spring-css/README.md | 12 ++
.../account-service/pom.xml | 93 +++++++++++++
.../java/com/baiye/AccountApplication.java | 14 ++
.../baiye/conroller/AccountController.java | 52 ++++++++
.../main/java/com/baiye/domain/Account.java | 38 ++++++
.../com/baiye/service/AccountService.java | 50 +++++++
.../com/baiye/service/AccountServiceImpl.java | 34 +++++
.../customer-service/pom.xml | 122 ++++++++++++++++++
.../java/com/baiye/CustomerApplication.java | 12 ++
.../java/com/baiye/domain/CustomerTicket.java | 84 ++++++++++++
.../baiye/service/CustomerTicketService.java | 10 ++
.../service/CustomerTicketServiceImpl.java | 37 ++++++
.../reative-spring-css/message/pom.xml | 19 +++
.../reative-spring-css/order-service/pom.xml | 64 +++++++++
.../main/java/com/baiye/OrderApplication.java | 11 ++
.../com/baiye/controller/OrderHandler.java | 30 +++++
.../com/baiye/controller/OrderRouter.java | 21 +++
.../src/main/java/com/baiye/domain/Order.java | 49 +++++++
.../java/com/baiye/service/OrderService.java | 9 ++
.../com/baiye/service/OrderServiceImpl.java | 13 ++
.../css-webflux/reative-spring-css/pom.xml | 27 ++++
fuli/jav-addr/pom.xml | 28 ++++
.../jav-addr/src/main/java/com.baiye/Jav.java | 39 ++++++
pom.xml | 3 +
spring/spring-webflux/README.md | 113 ++++++++++++++++
.../pic/ReactiveSpringCSS技术组件图.png | Bin 0 -> 332207 bytes
.../pic/ReactiveSpringCSS架构.png | Bin 0 -> 234102 bytes
spring/spring-webflux/pic/响应式宣言.png | Bin 0 -> 39039 bytes
.../spring-webflux-demo/pom.xml | 78 +++++++++++
.../com/baiye/HelloWebFluxApplication.java | 16 +++
.../controller/HelloWebFluxController.java | 14 ++
31 files changed, 1092 insertions(+)
create mode 100644 best-practice/css-webflux/reative-spring-css/README.md
create mode 100644 best-practice/css-webflux/reative-spring-css/account-service/pom.xml
create mode 100644 best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/AccountApplication.java
create mode 100644 best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/conroller/AccountController.java
create mode 100644 best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/domain/Account.java
create mode 100644 best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/service/AccountService.java
create mode 100644 best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/service/AccountServiceImpl.java
create mode 100644 best-practice/css-webflux/reative-spring-css/customer-service/pom.xml
create mode 100644 best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/CustomerApplication.java
create mode 100644 best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/domain/CustomerTicket.java
create mode 100644 best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/service/CustomerTicketService.java
create mode 100644 best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/service/CustomerTicketServiceImpl.java
create mode 100644 best-practice/css-webflux/reative-spring-css/message/pom.xml
create mode 100644 best-practice/css-webflux/reative-spring-css/order-service/pom.xml
create mode 100644 best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/OrderApplication.java
create mode 100644 best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/controller/OrderHandler.java
create mode 100644 best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/controller/OrderRouter.java
create mode 100644 best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/domain/Order.java
create mode 100644 best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/service/OrderService.java
create mode 100644 best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/service/OrderServiceImpl.java
create mode 100644 best-practice/css-webflux/reative-spring-css/pom.xml
create mode 100644 fuli/jav-addr/pom.xml
create mode 100644 fuli/jav-addr/src/main/java/com.baiye/Jav.java
create mode 100644 spring/spring-webflux/README.md
create mode 100644 spring/spring-webflux/pic/ReactiveSpringCSS技术组件图.png
create mode 100644 spring/spring-webflux/pic/ReactiveSpringCSS架构.png
create mode 100644 spring/spring-webflux/pic/响应式宣言.png
create mode 100644 spring/spring-webflux/spring-webflux-demo/pom.xml
create mode 100644 spring/spring-webflux/spring-webflux-demo/src/main/java/com/baiye/HelloWebFluxApplication.java
create mode 100644 spring/spring-webflux/spring-webflux-demo/src/main/java/com/baiye/controller/HelloWebFluxController.java
diff --git a/best-practice/css-webflux/reative-spring-css/README.md b/best-practice/css-webflux/reative-spring-css/README.md
new file mode 100644
index 0000000..47b053c
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/README.md
@@ -0,0 +1,12 @@
+# 基于 响应式的 客户管理系统
+
+
+## 设计
+- 该项目中的Web服务设计
+> generateCustomerTicket{
+> 创建 CustomerTicket 对象
+> 从远程 account-service 中获取 Account 对象
+> 从远程 order-service 中获取 Order 对象
+> 设置 CustomerTicket 对象属性
+> 保存 CustomerTicket 对象并返回
+> }
\ No newline at end of file
diff --git a/best-practice/css-webflux/reative-spring-css/account-service/pom.xml b/best-practice/css-webflux/reative-spring-css/account-service/pom.xml
new file mode 100644
index 0000000..fea2ccd
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/account-service/pom.xml
@@ -0,0 +1,93 @@
+
+
+
+ reative-spring-css
+ org.example
+ 1.0-SNAPSHOT
+
+ 4.0.0
+ account-service
+ 1.0.0-REALSE
+ jar
+
+ Account Service
+
+
+ 8
+ 8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb-reactive
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-stream
+
+
+ org.springframework.cloud
+ spring-cloud-stream-reactive
+ 2.2.1.RELEASE
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-stream-rabbit
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ io.projectreactor
+ reactor-test
+ test
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/AccountApplication.java b/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/AccountApplication.java
new file mode 100644
index 0000000..80d36a3
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/AccountApplication.java
@@ -0,0 +1,14 @@
+package com.baiye;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.stream.annotation.EnableBinding;
+
+@SpringBootApplication
+//@EnableBinding(Source.class)
+public class AccountApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(AccountApplication.class, args);
+ }
+}
diff --git a/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/conroller/AccountController.java b/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/conroller/AccountController.java
new file mode 100644
index 0000000..abedaaf
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/conroller/AccountController.java
@@ -0,0 +1,52 @@
+package com.baiye.conroller;
+
+import com.baiye.domain.Account;
+import com.baiye.service.AccountService;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Mono;
+
+/**
+ * Account 对应的响应式端点暴露
+ */
+@RestController
+@RequestMapping(value = "accounts")
+public class AccountController {
+
+
+ private final AccountService accountService;
+
+ public AccountController(AccountService accountService) {
+ this.accountService = accountService;
+ }
+
+ @GetMapping(value = "/{accountId}")
+ public Mono getAccountById(@PathVariable("accountId") String accountId) {
+//
+// Account account = new Account();
+// account.setId(1L);
+// account.setAccountCode("DemoCode");
+// account.setAccountName("DemoName");
+
+ Mono account = accountService.getAccountById(accountId);
+ return account;
+ }
+
+ @PostMapping(value = "/")
+ public Mono addAccount(@RequestBody Mono account) {
+
+ return accountService.addAccount(account);
+ }
+
+ @PutMapping(value = "/")
+ public Mono updateAccount(@RequestBody Mono account) {
+
+ return accountService.updateAccount(account);
+ }
+
+ @GetMapping(value = "accountname/{accountName}")
+ public Mono getAccountByAccountName(@PathVariable("accountName") String accountName) {
+
+ Mono account = accountService.getAccountByAccountName(accountName);
+ return account;
+ }
+}
diff --git a/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/domain/Account.java b/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/domain/Account.java
new file mode 100644
index 0000000..9dd7939
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/domain/Account.java
@@ -0,0 +1,38 @@
+package com.baiye.domain;
+
+public class Account {
+
+ private String id;
+ private String accountCode;
+ private String accountName;
+
+ public Account() {
+ super();
+ }
+
+ public Account(String id, String accountCode, String accountName) {
+ super();
+ this.id = id;
+ this.accountCode = accountCode;
+ this.accountName = accountName;
+ }
+
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+ public String getAccountCode() {
+ return accountCode;
+ }
+ public void setAccountCode(String accountCode) {
+ this.accountCode = accountCode;
+ }
+ public String getAccountName() {
+ return accountName;
+ }
+ public void setAccountName(String accountName) {
+ this.accountName = accountName;
+ }
+}
diff --git a/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/service/AccountService.java b/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/service/AccountService.java
new file mode 100644
index 0000000..a1a5dae
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/service/AccountService.java
@@ -0,0 +1,50 @@
+package com.baiye.service;
+
+import com.baiye.domain.Account;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+public interface AccountService {
+
+ /**
+ * 通过 Id 获取 Account
+ * @param accountId
+ * @return
+ */
+ Mono getAccountById(String accountId);
+
+
+ /**
+ * Account 增
+ *
+ * @param account
+ * @return
+ */
+ Mono addAccount(Mono account);
+
+
+ /**
+ * Account 改
+ *
+ * @param account
+ * @return
+ */
+ Mono updateAccount(Mono account);
+
+
+ /**
+ * Mono 通过 Name 获取 Account
+ * @param accountName
+ * @return
+ */
+ Mono getAccountByAccountName(String accountName);
+
+
+ /**
+ * Flux 通过 Name 获取 Account
+ *
+ * @param accountName
+ * @return
+ */
+ Flux getAccountsByAccountName(String accountName);
+}
diff --git a/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/service/AccountServiceImpl.java b/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/service/AccountServiceImpl.java
new file mode 100644
index 0000000..2489c82
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/account-service/src/main/java/com/baiye/service/AccountServiceImpl.java
@@ -0,0 +1,34 @@
+package com.baiye.service;
+
+import com.baiye.domain.Account;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@Service
+public class AccountServiceImpl implements AccountService{
+ @Override
+ public Mono getAccountById(String accountId) {
+ return null;
+ }
+
+ @Override
+ public Mono addAccount(Mono account) {
+ return null;
+ }
+
+ @Override
+ public Mono updateAccount(Mono account) {
+ return null;
+ }
+
+ @Override
+ public Mono getAccountByAccountName(String accountName) {
+ return null;
+ }
+
+ @Override
+ public Flux getAccountsByAccountName(String accountName) {
+ return null;
+ }
+}
diff --git a/best-practice/css-webflux/reative-spring-css/customer-service/pom.xml b/best-practice/css-webflux/reative-spring-css/customer-service/pom.xml
new file mode 100644
index 0000000..5328d77
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/customer-service/pom.xml
@@ -0,0 +1,122 @@
+
+
+
+ reative-spring-css
+ org.example
+ 1.0-SNAPSHOT
+
+ 4.0.0
+ customer-service
+ 1.0.0-RELEASE
+ jar
+
+
+ 8
+ 8
+
+
+
+
+ spring-snapshots
+ Spring Snapshots
+ https://repo.spring.io/snapshot
+
+ true
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+ spring-libs-snapshot
+ https://repo.spring.io/libs-snapshot
+
+
+
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb-reactive
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-function-context
+
+
+ org.springframework.cloud
+ spring-cloud-stream-reactive
+ 2.2.1.RELEASE
+
+
+ org.springframework.cloud
+ spring-cloud-starter-stream-rabbit
+
+
+ org.springframework.cloud
+ spring-cloud-stream
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis-reactive
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+
+ org.springframework.data
+ spring-data-redis
+
+
+ redis.clients
+ jedis
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ io.projectreactor
+ reactor-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
\ No newline at end of file
diff --git a/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/CustomerApplication.java b/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/CustomerApplication.java
new file mode 100644
index 0000000..4c89b57
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/CustomerApplication.java
@@ -0,0 +1,12 @@
+package com.baiye;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class CustomerApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(CustomerApplication.class, args);
+ }
+}
diff --git a/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/domain/CustomerTicket.java b/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/domain/CustomerTicket.java
new file mode 100644
index 0000000..518588d
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/domain/CustomerTicket.java
@@ -0,0 +1,84 @@
+package com.baiye.domain;
+
+import org.springframework.util.Assert;
+
+public class CustomerTicket {
+
+ private String id;
+ private String accountId;
+ private String orderNumber;
+ private String description;
+ private Date createTime;
+
+
+ public CustomerTicket() {
+ super();
+ }
+
+ public CustomerTicket(String accountId, String orderNumber) {
+ super();
+
+ Assert.notNull(accountId, "Account Id must not be null");
+ Assert.notNull(orderNumber, "Order Number must not be null");
+
+ this.accountId = accountId;
+ this.orderNumber = orderNumber;
+ }
+
+ public CustomerTicket(String accountId, String orderNumber, String description, Date createTime) {
+
+ this(accountId, orderNumber);
+
+ this.description = description;
+ this.createTime = createTime;
+ }
+
+ public CustomerTicket(String id, String accountId, String orderNumber, String description, Date createTime) {
+
+ this(accountId, orderNumber);
+
+ this.id = id;
+ this.description = description;
+ this.createTime = createTime;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getAccountId() {
+ return accountId;
+ }
+
+ public void setAccountId(String accountId) {
+ this.accountId = accountId;
+ }
+
+ public String getOrderNumber() {
+ return orderNumber;
+ }
+
+ public void setOrderNumber(String orderNumber) {
+ this.orderNumber = orderNumber;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Date getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Date createTime) {
+ this.createTime = createTime;
+ }
+}
diff --git a/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/service/CustomerTicketService.java b/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/service/CustomerTicketService.java
new file mode 100644
index 0000000..679bf71
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/service/CustomerTicketService.java
@@ -0,0 +1,10 @@
+package com.baiye.service;
+
+import com.baiye.domain.CustomerTicket;
+import reactor.core.publisher.Mono;
+
+public interface CustomerTicketService {
+
+
+ Mono generateCustomerTicket(String accountId, String orderNumber);
+}
diff --git a/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/service/CustomerTicketServiceImpl.java b/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/service/CustomerTicketServiceImpl.java
new file mode 100644
index 0000000..2e9047f
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/customer-service/src/main/java/com/baiye/service/CustomerTicketServiceImpl.java
@@ -0,0 +1,37 @@
+package com.baiye.service;
+
+import com.baiye.domain.CustomerTicket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+
+import java.util.UUID;
+
+@Service
+public class CustomerTicketServiceImpl implements CustomerTicketService{
+
+ private static final Logger logger = LoggerFactory.getLogger(CustomerTicketService.class);
+
+ /**
+ * 典型使用案例: 从其他的两个服务拿到相应的对象进行聚合转化保存
+ *
+ * @param accountId
+ * @param orderNumber
+ * @return
+ */
+ @Override
+ public Mono generateCustomerTicket(String accountId, String orderNumber) {
+ logger.debug("Generate customer ticket record with account: {} and order: {}", accountId, orderNumber);
+
+ // 设置 customerTicket - id
+ // fixme 正式环境不要使用 UUID
+ CustomerTicket customerTicket = new CustomerTicket();
+ customerTicket.setId("C_" + UUID.randomUUID().toString());
+
+ // TODO: 2022/9/4 代码暂存
+
+
+ return null;
+ }
+}
diff --git a/best-practice/css-webflux/reative-spring-css/message/pom.xml b/best-practice/css-webflux/reative-spring-css/message/pom.xml
new file mode 100644
index 0000000..28e4da0
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/message/pom.xml
@@ -0,0 +1,19 @@
+
+
+
+ reative-spring-css
+ org.example
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ message
+
+
+ 8
+ 8
+
+
+
\ No newline at end of file
diff --git a/best-practice/css-webflux/reative-spring-css/order-service/pom.xml b/best-practice/css-webflux/reative-spring-css/order-service/pom.xml
new file mode 100644
index 0000000..998ed9d
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/order-service/pom.xml
@@ -0,0 +1,64 @@
+
+
+
+ reative-spring-css
+ org.example
+ 1.0-SNAPSHOT
+
+ 4.0.0
+ order-service
+ 1.0.1-RELEASE
+ jar
+
+ Order Service
+
+
+ 8
+ 8
+
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb-reactive
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ io.projectreactor
+ reactor-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/OrderApplication.java b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/OrderApplication.java
new file mode 100644
index 0000000..7909d70
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/OrderApplication.java
@@ -0,0 +1,11 @@
+package com.baiye;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class OrderApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(OrderApplication.class, args);
+ }
+}
diff --git a/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/controller/OrderHandler.java b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/controller/OrderHandler.java
new file mode 100644
index 0000000..9af52c0
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/controller/OrderHandler.java
@@ -0,0 +1,30 @@
+package com.baiye.controller;
+
+import com.baiye.domain.Order;
+import com.baiye.service.OrderService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.function.server.ServerRequest;
+import org.springframework.web.reactive.function.server.ServerResponse;
+import reactor.core.publisher.Mono;
+
+@Configuration
+public class OrderHandler {
+
+ private final OrderService orderService;
+
+ public OrderHandler(OrderService orderService) {
+ this.orderService = orderService;
+ }
+
+ public Mono getOrderByOrderNumber(ServerRequest request) {
+ // fixme 获取参数中的 orderName 设置 - 这种最好放在 common中定义 constant
+ String orderNumber = request.pathVariable("orderNumber");
+
+ // 返回包装后的 Reactor 调用结果
+ return ServerResponse
+ .ok()
+ .body(this.orderService.getOrderByOrderNumber(orderNumber), Order.class);
+ }
+
+}
diff --git a/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/controller/OrderRouter.java b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/controller/OrderRouter.java
new file mode 100644
index 0000000..c5e733f
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/controller/OrderRouter.java
@@ -0,0 +1,21 @@
+package com.baiye.controller;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.MediaType;
+import org.springframework.web.reactive.function.server.*;
+
+@Configuration
+public class OrderRouter {
+
+ @Bean
+ public RouterFunction routeOrder(OrderHandler orderHandler) {
+ return RouterFunctions
+ .route(RequestPredicates
+ .GET("/orders/{orderNumber}")
+ .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)),
+ // 这里要进行非空判断
+ orderHandler::getOrderByOrderNumber
+ );
+ }
+}
diff --git a/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/domain/Order.java b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/domain/Order.java
new file mode 100644
index 0000000..aa7d735
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/domain/Order.java
@@ -0,0 +1,49 @@
+package com.baiye.domain;
+
+public class Order {
+
+ private String id;
+ private String orderNumber;
+ private String deliveryAddress;
+ private String goods;
+
+ public Order() {
+ super();
+ }
+
+ public Order(String id, String orderNumber, String deliveryAddress, String goods) {
+ super();
+ this.id = id;
+ this.orderNumber = orderNumber;
+ this.deliveryAddress = deliveryAddress;
+ this.goods = goods;
+ }
+
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+ public String getOrderNumber() {
+ return orderNumber;
+ }
+ public void setOrderNumber(String orderNumber) {
+ this.orderNumber = orderNumber;
+ }
+ public String getDeliveryAddress() {
+ return deliveryAddress;
+ }
+ public void setDeliveryAddress(String deliveryAddress) {
+ this.deliveryAddress = deliveryAddress;
+ }
+
+ public String getGoods() {
+ return goods;
+ }
+
+ public void setGoods(String goods) {
+ this.goods = goods;
+ }
+
+}
diff --git a/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/service/OrderService.java b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/service/OrderService.java
new file mode 100644
index 0000000..6f82aa8
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/service/OrderService.java
@@ -0,0 +1,9 @@
+package com.baiye.service;
+
+import com.baiye.domain.Order;
+import reactor.core.publisher.Mono;
+
+public interface OrderService {
+
+ Mono getOrderByOrderNumber(String orderNumber);
+}
diff --git a/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/service/OrderServiceImpl.java b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/service/OrderServiceImpl.java
new file mode 100644
index 0000000..f15e071
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/order-service/src/main/java/com/baiye/service/OrderServiceImpl.java
@@ -0,0 +1,13 @@
+package com.baiye.service;
+
+import com.baiye.domain.Order;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+
+@Service
+public class OrderServiceImpl implements OrderService{
+ @Override
+ public Mono getOrderByOrderNumber(String orderNumber) {
+ return null;
+ }
+}
diff --git a/best-practice/css-webflux/reative-spring-css/pom.xml b/best-practice/css-webflux/reative-spring-css/pom.xml
new file mode 100644
index 0000000..82df350
--- /dev/null
+++ b/best-practice/css-webflux/reative-spring-css/pom.xml
@@ -0,0 +1,27 @@
+
+
+
+ dev-protocol
+ org.example
+ 1.0-SNAPSHOT
+ ../../../pom.xml
+
+ 4.0.0
+ reative-spring-css
+ pom
+
+
+ account-service
+ customer-service
+ order-service
+ message
+
+
+
+ 8
+ 8
+
+
+
\ No newline at end of file
diff --git a/fuli/jav-addr/pom.xml b/fuli/jav-addr/pom.xml
new file mode 100644
index 0000000..97ce4e5
--- /dev/null
+++ b/fuli/jav-addr/pom.xml
@@ -0,0 +1,28 @@
+
+
+
+ dev-protocol
+ org.example
+ 1.0-SNAPSHOT
+ ../../pom.xml
+
+ 4.0.0
+
+ jav-addr
+
+
+ 8
+ 8
+
+
+
+
+ cn.hutool
+ hutool-all
+ 5.7.22
+
+
+
+
\ No newline at end of file
diff --git a/fuli/jav-addr/src/main/java/com.baiye/Jav.java b/fuli/jav-addr/src/main/java/com.baiye/Jav.java
new file mode 100644
index 0000000..27e5b86
--- /dev/null
+++ b/fuli/jav-addr/src/main/java/com.baiye/Jav.java
@@ -0,0 +1,39 @@
+package com.baiye;
+
+import cn.hutool.core.util.StrUtil;
+
+import java.util.List;
+
+/**
+ * 小网站生成器
+ */
+public class Jav {
+
+ public static void main(String[] args) {
+ String pre = "javbus|busjav|busfan|fanbus|buscdn|cdnbus|dmmsee|seedmm|busdmm|dmmbus|javsee|seejav|avsox";
+
+ String end = "jav|bus|dmm|see|cdn|fan";
+
+
+ List split = StrUtil.split(pre, "|");
+
+ List split1 = StrUtil.split(end, "|");
+
+ String dian = ".";
+
+ for (String preIndex : split) {
+
+ String www = "https://www";
+ for (String endIndex : split1) {
+ StringBuilder stringBuilder = new StringBuilder()
+ .append(www)
+ .append(dian)
+ .append(preIndex)
+ .append(dian)
+ .append(endIndex);
+ System.out.println(stringBuilder);
+ }
+ }
+
+ }
+}
diff --git a/pom.xml b/pom.xml
index c9d995f..a1f236f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,6 +45,9 @@
longpolling/demo/demo3/dev-protocol-netty-common
code-language/java/java-demo
bigdata/spark/best-spark
+ fuli/jav-addr
+ spring/spring-webflux/spring-webflux-demo
+ best-practice/css-webflux/reative-spring-css
diff --git a/spring/spring-webflux/README.md b/spring/spring-webflux/README.md
new file mode 100644
index 0000000..b982b02
--- /dev/null
+++ b/spring/spring-webflux/README.md
@@ -0,0 +1,113 @@
+Spring 响应式编程
+
+
+# 0. 目录
+
+
+
+
+# 1. 基本概念
+- 数据流和响应式
+ - 数据流就是说明全链路都是以事件的方式进行驱动的
+ - 响应式编程核心特点: 不采用传统的同步调用方式处理数据, 而是由处于数据库上游的各层组件自动执行事件
+ - 响应式编程: 基于事件的发布订阅机制, 使用推的方式
+ - 优势: 生成事件和消费事件的过程是异步执行的,所以线程的生命周期很短,资源之间的竞争关系较少, 服务器的响应能力也就越高
+- 响应式宣言和响应式系统
+ - 即时响应性(Responsive)、回弹性(Resilient)、弹性(Elastic)以及消息驱动(Message Driven)构成了响应式宣言的主体内容。
+ - ![响应式宣言](pic/响应式宣言.png)
+ - 具备上图中各个特性的系统,就可以称为响应式系统
+
+# 2. 背压机制
+- 流概念
+ - 由生产者生产并由多个消费者消费的元素序列(生产者消费者模型 | 发布者订阅者模型)
+- 流的处理模式
+ - "拉模式": 消费者主动从生产者拉取元素
+ - "推模式": 生产者将元素推送给消费者[ 资源利用率更好]
+- 流量控制
+ - 生产者生产数据的速率小于消费者
+ - 消费者数据没有压力, 也就不需要进行流量控制
+ - 生产者生产数据大于消费者消费数据 - [常见]
+ - 消费者可能因为无法处理过多的数据而发生崩溃
+ - 常见地解决方案是 **在生产者和消费者之间加队列的形式**
+- 纯推模式下的数据流量会有很多不可控的因素, 需要在推模式和拉模式之间考虑一定的平衡性从而优雅的实现流量的控制
+- 背压机制: 下游能够向上游反馈流量请求的机制
+ - 如果消费者消费数据的速度赶不上生产者生产数据的速度时, 他将会持续消耗系统的资源
+- 响应式流的核心接口
+```java
+// Publisher
+
+public interface Publisher{
+ public void subscribe(Subscriber super T> s);
+}
+
+
+// Subscriber
+
+public void onSubscribe(Subscriber s) // 回调方法
+
+public void onNext(T t) {} // 向订阅者发送数据
+
+public void onError(Throwable e) {} // 触发异常时候
+
+public void onCompleted() {} // 数据流发送结束
+
+
+// Subscription 对象是确保生产者和消费者针对数据处理速度达成的一种动态平衡的基础, 也是流量控制中实现背压机制的关键所在
+
+public interface Subscription {
+ void request(long var1);
+
+ void cancel();
+}
+
+```
+- 业界主流的响应式开发库包括: **RxJava, Akka, Vert.x 以及 Project Reactor**
+
+# 3. 响应式编程应用场景
+- 数据流处理是响应式编程的一大应用场景, 流式系统的主要特点是低延迟和高吞吐
+- 网关的使用
+ - 网关的作用就是用来响应前端系统的流量并将其转发到后端服务
+ - Netflix Hystrix SpringCLoud Gateway 以及 SpringWebFlux
+
+
+# 4. 基于 Spring 框架学习响应式编程
+- 响应式编程并不是只针对系统中的某一个部分组件, 而是需要适用于调用链路上的所有组件
+- 只要有一个环节不是响应式的, 那么这个环节就会出现同步阻塞
+- Spring5 提供了 WebFlux + SpringData Reactive
+- WebFlux不仅包含了对创建和访问响应式HTTP端点的支持, 还可以用来实现服务器推送事件以及 WebSocket
+- Spring WebFlux 需要支持异步的运行环境
+ - 比如 Netty,Undertow 以及 Servlet 3.1 版本以上的 Tomcat 和 Jetty
+- 非常适合开发 I/O 密集型服务
+- 不要 WebFlux和 SpringMVC混合使用, 无法保证全栈式的响应式流
+- 案例: CSS: (Customer Service System)客户服务系统
+ - ![ReactiveSpringCSS架构](pic/ReactiveSpringCSS架构.png)
+ - 开发重点
+ - Web层: 构建 RESTFUL 端点, 并通过响应式请求的WebClient客户端组件来消费这些端点
+ - Service层: 核心逻辑在于完成事件处理和消息通信相关的业务场景 account-service 消息的发布者, customer-service 则是消息消费者
+ - Repository层: 引入 MongoDB和Redis两款支持响应式流的 NoSQL 数据库, MongoDB为各个服务存储业务数据, Redis主要用于在 customer-service 中
+ - ![ReactiveSpringCSS技术组件图](pic/ReactiveSpringCSS技术组件图.png)
+
+# 5. 了解 Reactor
+- RxJava诞生的更早, 但是 Reactor 更有前途
+- 使用 弹珠图来说明 响应式编程的策略(Marble Diagram)
+
+# 6. 使用 Flux 和 Mono 构建响应式数据流
+- Flux 创建
+ - 基于各种工厂模式的静态创建方法
+ - just() range() interval() 以及各种以 from- 为前缀的方法组等
+ - 采用编程方式动态创建Flux
+ -
+- 注解方式进行编码
+ - 基于Java注解的方式进行编码, 编程模型和 Spring MVC 一致
+ - 基于函数式编程模型
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring/spring-webflux/pic/ReactiveSpringCSS技术组件图.png b/spring/spring-webflux/pic/ReactiveSpringCSS技术组件图.png
new file mode 100644
index 0000000000000000000000000000000000000000..483a0afc106607e861fbf642731fa934617dd827
GIT binary patch
literal 332207
zcmZ5|WmsEV6K;_rrAUC{QV38Sg1Z$0EmA1O9g2H#3GPrREe^#!1b25@v`BELXprI#
zH|IO&eD}NeSDt6>?CiB?W{te_P9jxR#@!~O5!dQ?kZ7ajhrTIFo;$nU+*`@}`_EbfG_oZsw!=pZ!rm^1KR
zkx@HpOV+}jeX171oU5R4hDR7N%E^B4Fbc82OnS<|kfTNDefZnY(tR+Mw}zK(YkS*k
z^f6e0fiO~*KK|d2v-sUdIWB_#T|$0Aq845E|6dZpuKj=RWFUmN5?V3-ziT%;48Pv~
ze@_^Hlb!hQPCSUCw{^4AJ=K1;&}?3FlLy8?@UdpJ4=hKHLc#wt5Es{P~8RgG0`-8c0D)EAQbU
z*xcOAEh5rGtUN$yFQCw3HMnOZn}+V^I;2U*pSw%u;ih
z{m%Ps0da9yLx1P48I(N&s{B%kC`N`yKhKpYQyFqN1WctGy4=u6Uxe
z*xuMkw(@Y%a9p?YK=Jk4H-4;zSmgCTHCgx1A5XX*gZ%Gj{NeWze7AR5kJnkvMpHk(
zy*eIo^dssx741Mv9x4d@uIc)5&i1CYVEBI7V#Nx^O*pC$$Uv3v1tXEcNy*AG+BSAl
zk%!tly(}IZzf)3ZNX%PU9L`b2!ok6zY$ZOVv@f)C(7Cm1*mK*y5xDG!)~}Sc?Tl?z
z!_G?GL~}3w0<>692<3d-g5#9OsSRe3ukg1m`Z5UqGm;wC^sKW0zfh#$Pf1E0dgu
z2fw?!ZOMU(`}vBscaLZ9_@#L28Y?4+Ua73&KmNf#rtCPTyz1lf3v6$1hfAiUOl-S~
z93wg&5LbsD9ndvZ*Y71-@Pu3}5v;8CbC~0rNBf1S!kag90=3Pa$Mg@Y_zzDy?iV^f
zSNPu}u5JX|16OX_R(g<9KiatTKe{|_>9}pVf_B`nElHTmuyI~`ib3NwEgm&*n+P-g
zze(ct+}i2NBXH-}{94Q1+}u3>WK(D)YTPv2Bx`jZT_TQ(^Ydlj?fP6Et{pD5G#1$p
zPkJ0Kj&F%o1UB6-%xbN_wzg&&92}g!ez?D7=HfCs0Mc2yxz%0t?1dM@VDRnt6$WuP
zH{N`FeA!i1fRT|A&$}xSO?c6kWzeMMSY}RLof|wR6S221gS2vQAMf#n1?Z97a>wi7
zU{49LG9Ze)VT|#|kLX-R?Y*st3yb}n+Rbl)z^-$Zoy
z_iaZI{5pPqZ5@FJ)4l!uDK%}R-Z}zlAFl?WYPwsB0!26Gk1u#~;I#MSw7U}dg@q0Q
zntE-XM(w_H0R}c5Sr2DLvmO2&80rIYv@;UkXT=h<7vI)JP=!#-N3s)->1=M8<^v^}
zyu?}A*y59t3ImNzP1i+SQmw;#P>Ohp#!ts%7aiH;k7^tqWsBP1J+C+-vM-;6DDmCc
zU-;Wgnu#B=bic_o^Y(6b2ZJ$qczNR!6GQj+?S5}ojNp78di`#efpG{oxQgm
za_h9(i9&tvvGa?LO2Sv$e`U+#-RvN9C$Ht`>i%5K{PtMZO!l|S5ja%K`ToZ3JC8SF
zngjRJllI29UE`&Kg8WN)Ck3+0KRGCCH1L@U89}02ajz5E;QIP{0o+-v8O@yeUtcid
znUpqo2Z*(0YUk$W+|=wsKKfehD5LCX&i6CXzTczx
z3Ee$`dN(-a*fJL3JaOOhYc{p
zW@ojZKYvd4IqWfI-F+-P%QmHt)CW8uI}<6Ej1ZA7WP@@=8xw|wr%e=HSLdk&UQbzn5ML56hQj1(M2vzkqaeSp
zU1-6mAl(7t1z_i@NM?hMx~=H?x$zm{S}fegz%qTLaOB3Q_Igg=qG6%I^>_V|>1m^;
z?m3Hzn~vu-2}EEk*d`AgVlWk3qL*`Z$@bEc{AT4^3cME5tT*Pnf5RB5=OSY+yQ&Z`uJU+v2)QSZ>e~
zMk(m9I>gn{d$7=Oe!6;jeFjn0(23l`gcp~TjH}tSZetB9DS%%tz~P~s{EW;%h7H~#
zl(`*6;JTf!(rcdO!a{eAan_fBE|K>vBPkV$99{nbG8;S`tuwIVfcPqOW4L8>uy$1onlG$tS_GE$A}
zgp{Ab_>4rk(rM%79QWz`b@!MANSvEZR8hXtPPLcTT~AK;xFGAxIwmp*P}qstLh76G
z$0Gl%9X+lcx!toD&VwdmoT3Rr>pIEo!Ntaz>i2oxZ7~Q>8j*re>GZXxH;W**?__ea
ztJ1S3H)p$((D>Krv=+Y!Ox88GybakLTJ~^AU5V4IQHkptQoYz|E{At{z2E-Hg_Xam
zVA+nNmCWf_0LsU%as#sx$Wi28HX9j8dK;On+2j+CT;JV^{odTP{$)0QH+=Mi4+!&&
z1K@!O*?4(h2LsaxBDq-@88u!P!XvnNDLBLoLOs<2#$uRwQBtvol;ndX713jOyV9>y
z5%g<%d@;P#ZDOCq7eKeYr`&<$V{rj7+oQI|;H+ca&CP8nBBi2&rQ$liM}8WG$FG5O
z%ENE-eD=CVDrtR=arr`Fqc+cu!}(uRE0WE
zh1zJ2DAUHpAh_OMU2R0VN{{aFa8nrc4_WLP5%N7GcSy!v(-{*B
z+G|h`eyp64)5mU_|8Js5VoLm8LnBe;{uZ`!!*MtEc-Np}zCOehIN;HKN_}@K`BME=&jSGFN>@RlHSMJat)Jj;5
z2B3-PmB3WZ{$fr;7i#{Vv+646o{f#046j9)7{72q(c)np&B|gchFG~UHSQ(jL>@4&
zxsW)|m+ZK3yJwr5Pbj}ACWTUUrNw#~jW5U0C`+vDq@=U&>O!CagnaIiTF9VrAL}S>x-}e7#Qi!l%H=^w$A-AsQ
z{Hml3q)WlDvl~cyB9ERAq>7GV=IzuD^Gg~&Q_9T4?!|J%e(%MB)qBPMNB6jyoO{2#
zxxLJPOWxX=oRyVT?X;2v4tHxrI7&T4@(6u$?D^`2KRx`O|52)~Qe2hG4qn-8n_$bY
zRNX}RWz~ARo<&dmo$`iXM=bY6?Phzemn8GBl6
ze(0_(bnf2yb*7{+1Kh0?~ipEkLv@e+~M33gdv!b62&jzN8mV9B7wbxX~m-2IyC4OiNCPR>z
z->po9lEADfmK}#;mo1@8|x-p{feO0Ub9(9a9Lh@27XT&-9BQ6n2Y>Ury0b!L{
z?97jU<=rArhlow^a?k>oX&;Yi5oT#X1|IR~-EaExI|Hue10!+g#i1dZ$UGN5lQges
zKtIk_fDq-N6hKIfZ~X{G&xYnvglQ`+DG+_8VHxK;k|g;!6FS#(IdXOug8{i)#(p|r
z7z>jT29pDNLF)==je#ikXwB!=JK$ga&6>X8lz#a}aCU$9Sx8TaHM(_KdLLisLW2V=
zh?gksyQS+wD(@PW09p!YJ@ywnVG1A#5R)o3tYpFvz|%?-D>uyvtmMi2F`YdN<|f(w
zu~WIDz@O)*Q~inc>kh+3=>1!HT^j+yZ%dUzCj{HGn2PHr+TT=|v%tO+EWM0bGIoPH
zy#*Os?E#HbLzVdkp^WDgW!8cwBaP7^`-JASgw=PImdPy1(6JYlTLhluY8oQmgOdU1
zj(PPXx3XNU7u936)BP39RAx6}!DY)RCW8KrXV#S0iE^l%-=8yb+_
zzqj%J2669R_UrY=>=xKEYYm>S8g$MK4+
zO-5#>{PahY-DJ>FF~Pt72-$tJKP3ynW2!ano$$XK@Xy{d`Hb-l9nW`no2T6D8C{;y
zFrQdW;fvcpg8rw1%_BcZKY^PF$Ws1F1t+4cBbaKV(9L2v>4{f&BE=-)tf$Y`y#S`5
zy02;`F-|5eN<|+N$SYEt4k+I|a+Th_JBx~YJ>J))g%cKzbLJ=?FV~;fMoEl4r75jD
z>mAa4{iVFE{@E{7Y4ln&3M^x^m#wXqziyQpW*PAS$H!|;=6ouIdf5Qq9kXr2m%pBF)}fA
znY;@b+4`Uo1W$UdCqq$&y=x<(F044R-EHI1wdd4hddccTVCg~W{+rHF)Tl{{gYCm|
zQ4+0G*~XVN8V!j;U)1BsqQtS6%U&c^k)(icpKw7xXA&J>3Y;^ozjtI=(L9xl7-D_x
z>mK^ad{$!+KFA+2W*xxT@MdAl1{`!-bwV_|$Whr${u5r9*Tim9dSI`WC2D-`UJf?3
z-g$viCFH1PXi%tJ`BAqm!P`oP!Dac5YWIg*7;Z$pvrl_t`j^2!UrwAnMe=6`e4Znc
z@5JiFCMYk8W`a4;9LR4gIHH#=ePZE|`MpNRt?zc0ujc1r2fsw;MpbI-)DL`P1TuML
zc2&L?X6Rf!X&*EkPGgkz7?Avy%lxlV5ph(I{Rsy!#Vo(PqYE&RwhGF~y8Hc#;tw}P
z$e#!`O{6y)q%_LFw#ITnR(lUPOG``59PP|Rz5t#oA%V#jaCeCr+CAFMW->rKX2&$-
zTe-Eyhy0uu$)}7$pU$MZ*)Bd0m@|+76^GMweXlL1NaFe+pLb`@67EgW$;SGKb6(Jq
zq7WGkV&gKm@5{?Te<-kl7yg)kp9zC}guLXPh@$rdzBEe@(LmSB*v1j33syL5C&s
z2-~WtW)V$^q*H2&9>D8`y6d+~1Wu-ErIdFerAzmFo_i^g;jXS)t)~$uYMUDoE}61+
z6FR+&Mp9*;dFUBNZsL{O2hE#kDag7c3@9H`benchJ#=?pkUzIv5CKI!qp
zgnueTfp~Jb3|6n{68eW2SyMiu$@}(8!IjCnd@@+C0zL_;U>6}!lnh1g*K4Vsb6*pS
zQlh-7M(XI=$92+Sb(F%_IA8(s!0P;N1A(|F?g;%-Cv$ABePQ7OgF8S?>
zq+Bo=Hn70`ZO3B^hSlTw%42BOkQFyK^zj%6j@9
zCdC8`{ST6g>BhH<6bSln?=?zNL`;>$zwu7iq-5fm+K7adw+mBAuAs}S00>>8SBIN0
zeJ-ds^#+aT=@24zI$8-_K)O@Hee3PSG3!_P-@`c0(aTr{jNeE+vz-8J_EZXCXX3FQ
z8P&mciZk$`Kw6S{6(U1&b?8#f7COG2ds=67XUr&m3&AlS+NVBIe7aFDbmzzcf^VLv
zpwVx$>7E#%H`|F^CXOc>y#;>cv0Kg2jkWZ>7B_%ookCyQW1Sb3AGNyD^z!ua*>E@z
zs3*!19{j-3d)ey}9)xohC#kJ%)s}|f`iXa)S)1!vDS4H-L8zuhY1Z+l7K|bxerjCk
zbP+0{cdDB1IM-l&$y>_*sB;vJLUUo!UO~0vm1Vhj-;Q=;`L>qOld>J?zg53LJhsLa
zkFJ_p4)7b6Ysz|mEgcvSAOebtvQ{k1IsNSD`?}|q40+)r=qB=M8ab>hS!a5aZV_Z_
zP*r(-*>MRmIE~~Ew_siIf4ua!)h4F4et`=kBkw+A>}EpN{ko~v5OjNe6|24kDdd9k
zuFSH*Qgc7SWSNrvQyA8&-_2x}O$rI}7HjiD%<4GO-0T-96gcls^+&8K{IA0Of3YOd
zkC&^W`z+ywZB8CH0z)$L?2)qRTDQkee>#;_ylZA}OS6PdX{*{q3!77K5&4=uq5(6U
zE;Sx2k(F^5wwv?Qu8vALVqOX2*kH2To%!;`PeYljC(RutY3kI*8xOmrXiY%`vMVKT-dJB6_UF*hsxz-J_4^cHfQwh5<`di~}O?*@?1PL#!25MB2
zH>Ais$pHpQy+jc+{4JxbS;36EL1~7vzI*)IJdRyook^X^`$Qlh&S>jsd_b07oRAjp
z`chfnIkEGyz@~d|<(Jk59Dz8La&61#KT!fU4j^wfLc`QuABzvkppJHlL~9vVV5n1G
z9*SnZ(RZ50Dh?!;BM_@KmNqh(=Z8t#Q`bTAE;E)wvUlMcL;`vLU(`G*2Ho@-fe8-X
z)N-4Tt9>yN|McLmG?^z@Bb+=YJ3b4hy^|{12gu$Zdpu|dvzEWQqYvPb$Ne}(ByR^T
z<$I<|6q5>UaSo9P;v~|oGN4Hh&G!;hpPZa*7I=}@X%+j+f<((woCSI95D#UtbXYz5
zs^@U(r@9DF^y=qdgCRyCmP(-vDfAI$=qW6*69YeZz`9j&R2&@DDlZU5p!JyD=$QI-
ztY|8hal~=?QJlgVh-JNCyABYzW^dH=eJ=B4U(Bh(6m|4Yv$sio!-p4Xe1Gj3dV
z$!3{PeMjgMi8|uBUINVP09x<0kdVb93Gai$mYFs&_>J&e8u0Mm!RnU`g3&M0Hd!~{
z3K?uF3|_F^eo0Ud>fQHovRDcNA`~~%D=iIQ%k-Pi@+9(dc7OF#xn^g#9xOpud1W##
zfdN$keJov**8WBouaOOG#j09ASk^!)T}AIBgO<#!$cdsboly~czc3#Cv@;nf)@&9b
z_E|jAvTDGK#^)O+9p^d5`h)`==e@u>Pc#5}LjxV9<3vc<&A}@-r}jS3wLk%Q9yKD{
z0}84$eU0u0t5)G{>+e`DK
zD)o#9zJmgjA+SB2Ivf^
zq=gb}+*@^CG?V(p@2HP6
zH8`KOO#VQ3I_zgAT!dA6djl#af92*3+$4{ltBH+|OVy@wS_YJBJBG)~tSbbB=#${K
zW7%Ul#%yZ76D1Ub4UW|wWEPn;6py_#Hmgl;@Olx{*Mdl}HFoBO9ifyV-K_bFyi7gq
z^l(e1g>MP4g^;J5IV)WJo_*iCD8BPU|8L-6xQU`fM2IZ-)A-XtL+$UJ3_>n-_IO&e
zWea`uXG&^kr7St5d5zEb2%@!a2ZS$yU@ymYx?Uz4jiGlv-Nmrqij{@>!5rr#gcBMa
zJogbJe%boaJ1l2mcFq-4%8HJbC1$FM3gvvb+u2z_U#8hD3FcZd=A&gL7Y?HKj=8}Pw|iR
zJDO+-gMSjV9ez_f3osvm3eZh}0WuxjK82x@l4w{`Py;jD&pFJ9CA!&SwJoCJ)ow43
zW^RcB?)NPvdzxx2)ig9p)VD^zi-zaP$L{e-uoCJz`_OzFH$a!Cg2Vv;PjgW{7AG#;)v$-wN7GaRV9O>CB|9
zV+Fl4KILN*?B4Q2Z)q`O365+)&q-(FUm|eeFi-eI%H+G_-A>a
zFH9iMzAwh~Z}q`ffGkfX(#Qq|nt+j}cfp)Ez{c8Bf}=C~(VwQL;CxN7ygI^XaM!Ff
z8YwY(O;?(p<=&dvbXRHRUB!qu%~4kg>6Q6Qf&4Y-NoDVQT^RbxKFxlbdjt#d)%t{8
zwW^rADW7=ScLS-sM`Zr!b;+Lkcu}Tzt{a&23@nbe{FQ*qHoRy%RK5c>oR-@|*aiGI
zrqh4DeT?;LhC2=eGg^N|kOKQ3SDAjLSDtpM0+R&5cX;O5`~(;qhFB`2(d3;PXY
zcjwipa^e=aZ+4=&+O?mm64R+_X_3Bv|J7}eW?}8@=;6@uyf|p(F4%FsW#yjpaIq;b
z?+e+8>(O!>Tvt6rGp5)S(*v3~t#)f_Z&2ZTu=a~>upa4_@5@!d6!wxRB{TSJP>PutE@x{ttN3JQve
z0}A6Ky=IyjWUIwhOE!0jQNnRpTWxZAyR+*wIAY8^(0SUBM`{3URd>;Cjmj1qb7^Dz
z;{NLlbU1=eMbM#!ramR~M-%%^f#6=B;5+-gGU-?q>;3nWpKtarvrW*TJsc^Q_Q-sCLHyYpv)M2FW(t%j_n;*bSlh}mYHYSBvMci
zM%6o^)BcLznbe4nJql@FZB==#^oOh@f=YP&rxizRzjlCj9j8EGyx!tyaYLVop7Us4
zgd2@~%qidcSI(Za8%Dd`OM)!5uvsT@4rt4p^ENr1^Q9hUVLyK{OVo}-?mxUy-7X($
zejF)qsV|U~gpaTEkjz|tb3TKdREah}uE(uVn!qV)*N^De{7LPa;+*#FfMG@)=)o%5Of)|`zt~g5
zdPH_S-xUo)wnbN_rJ?{TF}z?bwwqVD@Cv8y+S9*;`FoarNB)zv(>
z)AW7COoeRK6-t*I3jP&@c|Wn@{jPdw_ljA-GUBv;kb+KGF{7F#@i3%yOfz|CSsmG1>Vv(mu*pK1kaxlk6
zy_&DY21VI!vdNpafUDoUBBpGkURYHsBq4(I^>%o%nLD8zT{zJr#dYSJ#ZeY(o&(ao
z!m-HEPFNMmPUa7o{tc}xD886<=tOE
z6&^8Sqq-t2FT=
z(z-2y)gN;h&!5%KC;pqn3CI@rBs5{d@m=>QyWTT@d|sinBlEInUTYETc)1!#Q^NI$
zuT25e9Ra-J7ZAv8Zl;K%5uZ3OEi5eLt29kN+xby!xbml1T3)eA^Mj8MrHzfvnSvj>
zWsYiN*z1t6@NhTD*_rauayaTiI_q$ZXY4z@%)NR&U0qFtuG&7S?I-xu)Skp?qusaL
zsTnu|;`yK$t#~8m`5@+wq(d~X@7M6wG_UAu>FGt2av7FI6A(qZrwS>m!>oX
z4khzmw%mOFVc$s?sM(_V539vn4@TB$W9|jX|AL({O;R?p7grI%_t4|@~d8}
z#y&hu`-kt>fU4JvRxh!g^C}h)gQa<1I+&Ce*Kps;E5B
z+AJ02;KJLxZX`jj5TK*2zqAl3gfFkgM_;$UJmBO>xq3F$y<0Am+d>uD#HcXbjBB~&
zCd9+l6Yqz2F-26#7>=+O*4c-2e4;D!mhF`h?>3>r>0Y?pP3R>v;DxH%Z^)GCl791~
zI8MDZ8JGGjcQQ8$0(eHAhmz)2k5x0DsFPm$6g!h-R{Wi-
z0StW%$k3SjNgF#FN~NjAQl@ih{Id~TanF4A>sV)!C-JnCv}bw`S~L*TIhI{JgIvL>
zuxD#nrj?f#^d^}g{rZV>x#e0!<2j4n_>5i4443!9<&l=rW!xAl%sm;Hqfrs2i8&@F
z^XP)KY_RX5JRIXiC&Og?wA2n7E|q>C(7?E+AbO`QLH3B&-p(*_2TKb
zX`NAqiZAZ?auQMEmxmF+MEX2iZ8jv(WQzbw_s`caGF5*OlfOj-YQ#Nj#Hd+s8%xOQ
z?v^?B8mZg{Scr!JFC{YO#Xmn42|8sPuX{
zFYm>=fArU_gJoJ8RVE38m(7>2ZrG#wzCs5qP7Je&
zu*wBOCGGvuL0m_7Np#u>vRRO*Og#s0Han@8?I`$O@TOP$1{%n%!
zw-d0z0~3!jkrScTchl*Rs8+4|qaS9iC3y?pdWZ*v%Z_YWk)k9m$ZOAQyl(x7m_
zBVKd-3+w#&LbS&qWeyzW|9aY5XkSF3)XRXtKolf@&)7lbAsfjbpJn70b3ewGO5YpGNlp&aG3i{h3PY}MLs?QeQ2
z`mz4S?#?-)9;P)=u3oMM$sc(D8^(d_+TYkO6yGT{;VpOb{NAPs7Zj(w-Yxl|=+c>P
z6D&A_=aEKKUilMvCp4meeEh@0#A~^38o!b!BBhRTW6g?~Y8+arr;Yr2Q+u6GS=$}QZKfjocwUXqfJN$5qoNvfL~C)c2IupjveqfQ`rgxZ
zliQ{uL*}54&88#07(Srd?o3*j-gwwgy}3}l(yOoKq7F$GJZi6MGCCO18*E4f#(6o~
z8#>lRI<^KQO@K(gp^gJ;>v_5?f;duMy4BE%R&_0TZW*gZR}_$^AQ3Dl&p>hBzuY%I
zmg`ycKjG!z87SAr*%^QYq;~f9f>w?OkX*;LPfe>%LIk9wm_?H%$(X@iJ4|$K}=EcT*B-E-20syv~r7(+!{G13*IiuCBX|jW3CS3Zf
zz8imt>%yeB^OGQ3Lrb|JHLaftma^syGUqfGM0G70(k`4H51bIIGiaYLk}~k%=U6Hl
zb7|gREzD#Q&8}bR80CF{gn2=x1RU+psV67Z1d<(h;fOyZu?`4js-@}rVHc6wQS|~b
z54X5v>VeaVAuATvuH@vswdIuvbbNIwota_wt4H_ctHmgfepHymtH0~}@d2(H=9rVg
zlNy)#-3i*t5-$fswJxqQ-jRz@34KiJq62Xr|ntXJ=<;?*Yk4
zJ!`K6=+>>@%Ro`~e^PdmHq*SzDo;%~Y>vZ`cgQ}!@H+qMhc4ZLOfobS!uJZQaCH{i*CoNqQ>OMkhkxr`1(@PI92+5<8_Tp
zYkN*{lJZNAdhS}AycWN3*?-@TdSAN@e>jD%ETrok72TMo4CwI2Q7*~}j0)T4-8UiS
zYn*?^KL7Tu)4dG;`xDxp_1%fSJDp-l3b6eQWtQIYsCG7do8fQb=nX^PS;x=FH)38V
z=vozqp#vMzpFZ&r5)vBM>DG~(B*w=F_JreaAQ_of*4AA=enc#5A-TxytoC>?ZQfTm
za{J1y{KzQ4SjjWIKH>fjc(J)8vss|%xhomdG@;KFYgtB!mr=Edmbo9MUdl?G^Bq4Iv2dl+Soyq*u}U4~2mAJt?WnKthf)~f#?^kh
z#8%jmAE|cMhJ}jSiZq4Ay%!mWX!woK<{uhlcQ71{h4Vu>(}M
zT!J;_YzzQv#0_&h8ma|>@y-yd2_MuOeYFb|V<#RYD
zI07WXe$9W`Rb-o~Rjcgz;>6sf`Rt{LZ{OZgGzNp0a48VcWgnupaNfVI*~6?V8MpnVhDG^Q7sr+c$w0-$>H3amLdt*CQ3hKgk)dVQ9Gh59!-v~
zZjTJ#BfD2bD*1FDlA=SSeAzWUt5lQFP+#)uzAd^+^r}?VDQ>_{w6OUl`{i{b@rN0%
z51B>N2kN)mCO?x)0>hm-tZT;74JH}T$>HjUD4EMoZtkSUIM`=s-yCY$>R#uhX-#h9fA+ec%h(nG428q}AeWWz{n2s!+&D$f
zzr-6c?LEX;JL4i^LRfUl4LT0en5xB{gwr%K%g9)>LFToq~A3gzx}Jpct@V46FsoLE1ia*E2kEUU0%Q>U>@mj
zje8QV%1HRk9vw^@E!bUr;4NPJtm;BN6?14LIk5ecaW)m(yNZ{;$G{P4ihU(}H^0rU
zcd6?RQGWT;4&e?Ee5A+_gI64Uaf
z3WrL-rnB)w(+L3qg{B`(eOgu#{CG<~W|t~C4mH|FWFagC|4NNUAB(Pv4G{Iw#^r6?+nIHuxD5y!2z_f3~;=a7j2-IoAF*C)Cvj;c55YrSf@)(
z)!e`up!2hC>w30i<7`>qqRC`rR4hJ8_A!o!C!tP8P<-J_w(1#9n#CC
zogcLlU|fLM)1g*v8!pr!Nay;?Ke;4|8n>>_t}@xXQF+?rUW6Fp5bfRO&}>N}6eA2K
z2+gnn1Y4;N3c(B*$J8!6GcJ!{Nn$G2Rg|8x4gt7*BirOx&j{Te+|c$rR$3zdwkLF7
zD%n85{8P3vB6J>JzjmXo$mm*KAKM-E#L13pb*R^BR~lV}bxOIv9$Y0f6*716tgeho
z`rsM*byJ%@N5zNoiAKyXH`r_|%A7E=s8!^(Wj4PPAXQpIQc_T~SHq4IPx
zY_WTP0T(!=oSg^mwnFA$4V^Mgar)J+U`#dr4`q3Op(uIjI$YOza>#iabV93hld>E|
zA=95Bn(BU}7BnjuK|SD)6CWv)5V2ozRs}kw9aqb>^5?HtAm(3H!gG;3F
z({{S#AbOf2AvclA^*NBP59ntLA?1jTJb`UHj}g-Bm4CUSbjV#VRoqO~wa_
zz^YPpPaQXreO@vRnzH7Q-BA%YY7DrafwtEt?9;Mu1qc^_K62(Ds=d5rBuk)HH~Lf5
z>2o^6IcBPkL?c|-@^sm4UENGT8aBLftl!0(2&eWYpDvcXIbAuACAi
z3a>Uzs~<$T#f#e$Sd0rXhj1;q^}dEi5(;i*zCb%Q+f&3Tb+p4EbClUxqf<)yXx3{K
zA>~0`nLW)Vj_Iw)?Jr4s>U}0GlmC49#vp~mEdCUNRsG8=RZre&?t9IJ{VVKy`>~4*bJkVkD&)?yOY~`^djfJbBP2|eTlWwY{quAxJ`>z>OpIw
zfx(`T?K1SnR0J%nX-`D7%$d}8;IlqFq*5`>7@No@4_wKN?W{@I0s$|x>-AJ8
zH$mnk>PM(ygCH#k7Rq$mMCfc!-gT($$ET1~jM@o)7?W$@xvCL|MJ5T|pEEoQy`2_7
zdw6ORlH5~>vDL{!V5#+z}g-q
zqJ1^U(QAFfvnKnQ|1n-4QeeKeej9RX2?_pA?fNO*@~S`ij%-F~DB;^#S#|#S@gs~_
z3OP%7^MUc#UQY@@6Qfp_&5(xO;`ros3c~M+!K95dI$K)-8JlR#_+GSj>i&lzrYdfM
zfK8qAP!2q^k`6+yxA>-I7xYO?K5$Zza$w~aLd9$_`SbBDCV|Z*ipzaxwXUFOL_xg!
zCf-Yh0RG&`=cIe@Hq0YQ&G1#sOllSDYO)Wbz5ty0FHwhx#I;l3+p`nux1n$OAZd{D
zot{%NA5V;L@K+#pFZ3Ee{H-WnzFD&mX|Y=qY6g@Q2#3?@Uwhc=$jA@>6_vM=YLWlN
zn#iie+ECK;beYL!M_D|ejj8h3mF__GRTN@-oaZ^;1&Z=u9Hyp#Ta7^d*@obs=KCp7
zmaOhl|2vH54NjRuQ@&8|e9q+2uF`U7-vaR0+ggr)YC%1=Pg5Orp|&;1`8*0Kao;O~
zqIcgXjHAXsSd6fOb*ffx>TG9zO-uxp{Cq?G`LBu47G$*`5%XCA%H3$H%)Ht3)ioyZ
z@O5^b>^<=O{p-TS9GjSgtX}O6gO|U;6PvcljvS<{YSkgm$jrbeYJBgM%&{>tahDEQ
z;807$s}T;;{2E+x1MQSeUM8s#Px1H0=VBdQ^@1}F*GoE?GUmGvEaUV
z2RAbU?Ganm2C`iEn8Mf}KF_wwJh~5oI
z_c%>(pTpUW<3?|Zyi+qRFfd-}`o6N*y0t;Ci72VnUHfDKP*GTwiAVkUMbD3%R*Bwr
z{*bwL?6M0__z_l?i-%x!tZQze8+l(G$rqPu{BqvlKN-~XQ-%j!90$Up*$4a(Fl1U2
zG5Wj>4$C!rl7ojd``}yKY(*mp&f@TZ&2SFxE
z2h(yGamwz@xL%5XdEr^*$rlO9VSLK1ZDT?14<=GVdPvw^#IS6je?3dpZcb*K9SFSGUoP
z^tCtLqQoe$d9_nJ@|nTc5pH$B{+=7PCB3xs0s)tp79yV|8~;f=HbF5BL#R3&P%k`o
zPF?yLHhj*Zz-lL@Nqi^(V0
zrC2Z?9v-K&9kr`_zq9l6-FP(MW997g0OSz#coAoyCT%}cEf4)SEJnhr9mSrQmCw6r
zE}fo5YB9de)I`dc1XRW$lQ`^gb*o-W_Dc0yl;heiK&)DEsq8$>kvN3C=DaqhEp7i$
ztZB|=yv?g8u^5eFbK!k~V0K)w?sa3J%$Ocrf;~tgD)D$A#nTfbPot=+*w$=hPee24
zf>7z!AjPCKXY6ybo8SjgH1LW{u=Z|a;Pu4w5MMET8MbhVWMgNF{-HRNoQmZDO``89
zzOK|nZd%+k>#tXJSPHWeP3r52UFOZPChQArbfdgB`z+w!Z?Z&FRRNPAmus>7Df>5Be$>dn`4n+xG#~Kwl&pymjdm`TL)t`X4
z3~ONYog|2rn@lvbBJrI${9GL`P-6QbRda^k58k%dQ2gRe=x1gKm6X~>(0so_3$YdB
zeC*%g=+3z}t~PzyUlfCQjga>t8cJvkW!0klKZbesG(gIKu1~kYZKa<_BL343kb>fG
z)O`>+bs{-Wkp3Td&3{v^guFv
zDXxal34uIO9MR%lW9$9c_l6ypkMdU(LDYFM*+?ySwpg)5cyzUkUm0MM-x74PN=yRQ
zgUxl!X
z*NL0}(tQD%T14#2oZl%Fc51fUE^^Dto`>Vpf^~J%!Zb*tpJHPRe6+OO=)OKJhC+LW
zlDXXGS4#y1Ui}rlkbfi~5d%a>R#i6Y#6YH#1FI(Pv0P_LxL##HfGFjh{;-gw_BU`x
z6pWfazl}3JThlPMk+SD464;gAc^X~&4uy9qr9vE8aBwlPk?o#gQ9b<?=wsPI+Dv~P^{bSzRFA2
zPK7v>Wl?sXOb%h)On|n5N^d7JFAGe;_L7p7|JJ~pDvSXP%5fp
zWSIF3@#S?V2*0J5SJi(nxV2AIR-2)I|3lUO71ZpQEKAWl8wExZg$4Wc>!>5j<&|Q5
z5(KwCVWU#$)Y$D~*Pc>%Uwn|K4-pU0l-|jRpXFd*!~et7S4OoNF5OaGio3hJ
zwYXc0TW}~&af%do4c_9#-GT-w?i3Hjt!Qy~=Z4dB*ZKY@D|w%pXJ*fynf;QQoqN~5
z@1!)@BJN*6ae62AhT?U%u4Em79&R6u+^uv|R5AL-VHV
zIy*Z<@3Lb>W_YzGw9P0MgHjPQd5vsBl$8{z=JJig-D%V$vTU}Tt2uq(e3}ce%^3KJ
zlYr8syEH&tu0q!b==|B(;a&MVA4iGoA%f6yOw)nXkfAy$_$4TRsS%RbpX%WGe9Ck0
z8^OIL94h(Oe^oN(7L|K_VoCFC$cwBYn7HT<*tW7HyRx%f)UIKUz42tOJQvu4?gG@Ac`TjyIjEeN?vEdGIxME@sb=LN@FMT@ro
zZwT$qyTd(3Q$;tZHN$4swN$jWeczd7BAo?%n5$u|z~Rm=ng6kR6_h)pfd^h(W~0kV
zn8UE9UMW6OySNTknMd`;PMuhd6T4c<6Kl2((wbq4rrpc>2b2Tj7+%65q__UQodhUC_
z>G|Hhv(>e1tgo{luYAM$`h{KBL}B;d=7g*CcFU32v;C6
z*vWh|ad(TGL^nRC8_%YrZuQ2~ZTj+Ed_~l_;T7B_>vCPG;mjr+#n5?eqN0AA;yY8e
zYwb_hlk`e}oNlEf!BO!JV1GC-a*|g}hIS}GN!HM`^}DXu9o_{LEoy#6aRrsDYPQSS
zQXPCk7wt3riF6@5e(FV(Z7z9-Lui$84D+U#27`LqC@%55V3$=iZk<6q#VUNph!9eM
zikNZo>Gm0=;TS%gB)X<6L*KSDY#dcdhfFee8dRm25$^3>*zc^RbIHHr7Z(aBLr(I9
z9CU_gmSiMsl|}R##9Pdf&wt14*;kl@uuyZ$reEkqHu#(>4pKil{kDAMsfYCuVW0nQ
zEwWS{EPrAKr=PwTl=VyK++NeB|H^7Vd)=6BOT0IcHH66_b4qsd$~6@HCG8q)pB6Bh8`hT;_?w1Oa1!L*>h7Nm9O
zyu?Y{Ln!tM6r4enXERhkQWER+-9#9@{p}vhY|bZMjKpBxNQbsr^uWEU{uwVC(}VW*
z5(DuGiA&d=!nId5wzTGs8(x^wtoe~Fd|1V-=8?^q?_s7~te`s7?P_QG>eoOfMIIz_
zn`a8Epn7kyfnSsJYf$fvd}&%)fuoz9%?xrx33f_biS0es^(d)=f*A4-UZmMRd)>^R
zHT3vYe-a~zT9JG*k!l(5V6UxGX$PkAv%5KrPKK0nmOfO^fX(2itRTRHm_>cQ9d~LE
zRYEea*k*09VCJh386y7rN=H@xzdLmUf-|$4TiG@tI~HgvtM<}^pOC4qmS!p(YhAyZ
zl>R+p5?G0PoN7PKq>wqMCNK_gcS}WqZb{PhAWEyc+wz5?IY9bFWRbmG_+
zjyhvC8A(5VeNX+anmnZqI&j0UFiO)b1Qd{`-oVA|N%W!^kI}4Q@WwtlE&cm&I#Q^3
zO9Q>}=`3k;1@_baz;L0-oYlUV?8V;vlY?CC=Hle&f+uV(^m2zD*%?tX^aORiBj@dz
z4V8YF;C-ae4Dgrn92}@-EJ;7d
z*x6<%rmu?JNXXylx}Y*VEf95fV)D8ZVtIS0Hh8T%M_@*e>2SZSacwIarCnLlsu>6N
zr;zIIvG?~({YdlmMC_KEiI2l+h^LHp_{weILo!w52=Diq>o?hv&>|4wH{3Iy5>Hn3
zIt|wX#%#U*G3TJo0(Q)dp~i?VXS4(`(R5v*3c>xtg-#llTZ&%_1Zh^0?6YT0p)~2s
z6f*HMzQ3mrFKB&t;}`-EAv9Y4v%^gTQhC?4=O~xignRafgU-_+akolV$_m@;J12By
zLx`*jwP6&=XFyOF_hxSr;YJ8!Bf5}v{)Z7LyBol@0c3U)B3FrTB=i^Kck^nUZvF}d
zS1wKYl#*8kd|WM&tT)+t9qzE2(On_isi$*qO<4*Zv9EmiE1sooWSjXFIf#c(t8YtucNOz8#>bq-1k>
zq29Y4rK0g03>(zkJakZIO@K$#*{={^9$QHkl3GM-S3G>qRVHGzEmgyYhUQ;9RAe@u
z6Q>uzQT$|RQrb8opUb8bQW%!++>&?R_C*aY{;ks87cTAcM$WOpq}AvJ4NlndSiuI4
z!nh&W{ZQ#jYJP)lb%&i@zhXa%hIXXyVjR3{DRDI#en!{nkm0;MZAeaj%pR%x5_-CU3)?%>5i}e0hE6_KNE_x%esU3YDNmJM#jK1;_R
z*51FsofnOt_9&{c&J5${rX;X_vw;)8ks9?L>$`SHbDPIi<<|<27E>wKtg0RI>507o
z>zgb8_cq!gKFM%G{51!6uyMvV5?-5%Srob}m#{Z>_k3v?nMQKjD_k9Hj)M*+NXNIW
z&P`yXo5!P4JF=e3WmJZpz$I?S_d?F%prW12rczfoG|?Av;RRZ9A6-Ufy-
zw?xABc0)vSALKSUmMl%1G?x?lOOmwVzSLuQ6O}f{Mxr6Rq=b2RzB(|38^7lKeh&)k
zWjEUVyw%{MOK{JQt%pJT3;V%iOBg8+FD7H5vS?$zm_p^ODsg+iwQ^;U5Ka
zw3RFPZIT23n)%4|CBF%dnHJ`~A7*kJpWKSEw1bIuj>do*>Etc%YF1tf5Is9fKaqg=Tw~X}c8p%S=Cq
zm^>wj*o44Jv7Wm(l5ITI!gj5=J1stt1FpVgJtm()P=WS576FJ|+;9nhAEZ9{**|F3ZiI&7sEUUD)P@;|(CYkedAY
z`a@?5ZiWxKPP#T62tdr$592qa2$!vpP=uo^kofuY$aYZ=9?Y|ENxYXl39+6`&9$G>
zB~A83rp<%u4!tDoq%B3&K`1hhCb$|CoAM5Ao?N2Yu};$E2^O0@`8Y|t
z$vvaiOU$3eX(gl65(jHuUZ{emwNpbTCJt9~HcvWr*!aWordII&S+^B>!h%|vW!dqt
zm$%U_8#26P+14al#QdemCNcV2h+Sqb?gd@cZb*LV+qh5<)%db+#
zXz?nS5?=n~+7^x*y!q&Is(||}?z6L=GH~tp6mb9a?8p`fdyN4%+eg6PF0ZLobMr^|
zx~kMI^eWpAu`hS%YT$?6u<=Cwao1=%uQj4Ia!%`wn75^hR0UJ%J&wNYrgz0A++hJ0(fPmdx}m5oo#&UyEgM1f)yXbL
zF8))lA^_PCL^~#eU^j{6TUtK2U4nE9X10x`4<>C?nyCxNZ7-qOO0>xm(6n8ywkQ|H
zr{i*^)$}&>=sR1gszZ6Di3~@i+?sQc!g0v$|dBFDz4?jRvakbESbPp?fN%zNL!}||5*-8S{_u$
z&p#YMr6bCrW^TgNzaZly2>v+fb15%bar?YS2H?z{89Y|b4C}kF8HwKCdD^8|>HiF~
zOSvRF*H!G>-g40U19K|P#KqiuA;S7($0BLwyqHk=8UY0q2W@-}CITuc*}?&@ry$IF
zUIdj?u(Pwfy*;DFlTCE5u#uAp*7ox9^1MDIE-op7&VzO==k!C*wQ1H!k`>rU<6NYZ
zl3+*C=ASmbGUr!W0Qb&>>QA?7(*zmTJ`mOoR&^;huJonYk*#hcHdYKi
zQLOq_&I$S-TG;iidU13n_w&~n^ts0^u+M&{us>VHn34?=iLKxaz}iTWAomA2-l~x@C_`sf#)MNt*n}f4+W%x
zq$(^fV1I+)Y>pQ~8Q~9evdrB)DD8ZViH-QV8bhj{-81ik_)$O%+)ZD?_bfTH-;bNQ
zK!pG(57Fj@(YlCXGQ0&u6RtM+ndw>h!DUuq;Kd(BS^lXaE|h7Ix_V%cG@lXkjo0
zodH3@C!_CI#W+l$)8Y1qn`eI;{&+q`as8I}Yq*&7oi*|zX}kRFNP{;JerFVYzs$bO
zO*~S0>bGN=pLTA^Mo7g_K-UwnJTwQ=@kl}kIA#qkRT+8s2aRSnuO8I-oyO!he1(dN
z3RGtnC?8Kj&B(YzgAcLc%Z19aIygAYFD$5A!?&sQRrEZ9CSHAR#z?AS9#iJ!zjO0cyH5;N7DV@0f4@OnE5B}A!
zXL|5_opwSSXA?u%aDW
zgbeKnIzMKdx0t6o13q*a43^LJ-l@6C6!*
z01txVfYa+E12#6cuFbQ)li}C6N159i2)LxpAbSW>{;XoRF?dU(kwm;Zw#k(?Sk)9I
z0wtemwC8hUU8{z?1?j$|6Y1CLvductl}tr-
zbciLTrjBTJO;6*YR6>PE)pc|jX{%LKRjQQ{EM7krKWQYv3Vc>02X#tgMSmh7pQE-r
zFl?M{`C^I=syDs{g137{R;@?a$yVo-$yX=n?TU10JPhkvI6C}B!AAyhP673Pduc*H
z3q7J;jPHLuZN}rSrdTz#j+-pqe7*SAT%|s>qcS4#6LnoZd3Aw7SmMB4MZfKYx57$=Djy6SX)Y`;@1;q|Z
zPN5LdJ$X}*z)O#*O*FExM}Co=v{c1RI}FJmwhg}rYB3L=PvzP2;g)!xi!r7KvR1ccM-9*ASVNDf316C(AiDn^ee337-C5xD@y^x4!s6F13$T)hB$fxi20AB&
zgoH#`7I@}fLD#pz>G}F;>K0NPeAi1PV?49Tc+2~BQU}hdBo4tc-A80XmF9scdIN=f
zk>9Z%pFXv%RRqnnIX`h#x$X1`N9tPr+k9J*~4?CB{p9S6vZ?B#__~<@m
zzUT1Up1di?jn;K(0#m;%7?1(vV_-@JC&d4Dng
z2-@pr`s1tLmne)E1n4*k1iazC#t#Qnl1As@NB5gONqy^|p=H3fUtC&}_VE$^sHjL+
z3M9}k(dwG3Ha7S2A`X(Es$ztmgxQnM{Yf5vdVYC+7t8iY&Hjm!!zTIa_T0^k9iFT2
z(vL&eA5eJo(s@AJain~GH|rmeQvK{VXj0O7k@~=BkdoUJL&e{T(gOZMSCm3Kc}w)c
z%Lt;EnrQKKALFxnE*=3;$8FP>{8q=*7ARvW2)i(wz&2Y%7@uEct=hvhC`m-G`YzFs
zuR^Yjd8*W}HoUB#>N;NPG(6Cp@^tYyg}==)g+d^x(FId11_%6w3v9Nc3$;2M!2#j#
zzsStxAE5JE^k^V!Yiq?%?t=KvHa5tNsTyyf^Xt*>@1aKSx2iw+4IimdImLyykdSc(
zLn4jxEv7+XyjHSeH2Nrx^#mus9=FGM%n?+dWr*iy(+8oz%PQ=$a8O9iGvD&aTZkEqWyTq
zB&h%X6K>@s(+HP-cb#*=4=tmo!nCLyZ=sy{FO+7g>Z$a~i;u9=j{h)3hcp^hZK6E;hhA7`oQ1}**)L03_~^15G2(BF0lYM
zJDse^0ONNzS^1?_92;Ki2zWC>GE3+d0DDP0?e)nS^D--&{+3rqfd+R~7GTEW>Z-h=
zVtu7HK08=ttvtUC*3ZvRKtx1FpwOS!pve_#WEbz$~k*mq$7)o(#xm#x4o0|+t9fz6%-{*@rYv-tCLTP_v6aPOwy
zQ?at5-D|az7$v7hzjs>gT6gXujH>$fU~&}v>iObP|2$vYrU5a;{cU)D6Qnp)*+-O~HXGAO?(|`1mD%oJoWMKC33At$uwE`RGEW
zo!(axhYsHtGDHruO-^wcN0I0BD8r@-5%&%ZnlySFcTy1Wh_zxqxJ%)lZ@q>5WG+vX
zCLnRr$80ZcEaK^oj6O4{(cw?=zueVgC)=U>
z0|tj)P(2;~WC_=Ktza&IdH6q`cG9U5<>d60X~!;!7h_m<-&)ZXi_3kHJRz5?pf6-H
zzn%Yy*y+hYp8dv2yqb1tF`})G+kybIU{_My*xyjbZj~bYonV5IP^jAhRbAy%sV@(L
z&kII|(6!pN1^U1@dK()u5g)1pB2E6J1Hb~oL4MH*aY=XU>
z43NkB4G3dA@ax!*Qg5O7og7Sc-3H{p>vRm{Z^&)~t6VU76iX7#@@;CV+aB9uvv5DH
z!nvu0Cb$Q{4WUA98~@+Lk9owxtCK-D{+R%5Vp>d;tK8W12HEGn49(tC-V&Y
zYGln+N+NS|iPFa~>JX;(XoJfv`~4ROvFsous`9ft4!qdSgDIP_T-{Jmp;H&*Yq0%y
zW>17I+apt(XHa!{*qND`FLGTrM=Tl4r_eMozp~OEsP(quHH*zbpW@wv>J^Iy+Z0!Z
zaNd}G;DC)}a2^gydaS}b)eXno8Duf{%ApLvgSEum=^L^oW5^2)xdBR#A#bEy?UMk^
zA@E35OfXSH0Ji80UOh&23}jId!FH8G$~v2H=j_T{E*{D6-_)9_msa3%Lxs~~IeSXJ*<2)gJMMz}}6AAV;YuO#J0Y#m1W|L|5(pW%W
z_m=}dVVj0PJWHY+Asu?(MZ%ZmM@VCM_nD|5?^-c$Ov_xo=cNZhtBQMLSBgL8?_}!f
z&di?i$)C$kU;dJLB`ZSG2ofp{MFEd4ubF`MUnVeNI{!%*tXn#V>-}
z-r8EbI+)WnFzUVYGOTrf-mruQUlaWoQLsh;q^x*OeXwyg`gXtLa49XY`(*3(;=$eT
zPVDwKyqHdSp%^27vn2lq|mEGzoN^!2=<(uqt_4!lJfS@rSyP4GxO1x(p`$>fQwHrS3aAva=M&H`)Ol|q#Yi7#&mzgjDOnBew
zUl#1&p_C$PVb|~!7v(iJ5@>2_p5FPI9QTkHPpCo$ID?*$g0Fufd@@gRpeKcAsch)|0~?Z)sps`_SL4|Fe7kf
zU?`LYC1Esobi`fcW?=kM*M5B(pM4JK(}W!JfHi0Zw5o@Zqbw}-JY^r9O`_VK8~JNuY8%{^O$J!aMmr-KEMPg*18V(Fj9(6mxrM8ASwX=RGnYcBRaz$PosRqH
zC~4pDSOz*m-HI^xye4uLS!KWF!M`Z_#P;==(i!Z?8US_gc^uAc1InQbBubi0r5Qb2
z`AF1fN*Vg-l4a>3k};sNO&EE{Pfy66*LN`Vs>P?by|5IWS$(&U%!X!2gVbuzzKVwR
z#CL~OHdkNgBLB}5D`<5Bt&l2x)uJvh-B2oi@d;BE!BLP?l$(^BBL3sf4ytmsFXgjh
z5^B}3x3z89HU?Yk0<|vqG?c$@4DQp#4CB4s?rc&QPzEa({0;c~a_{*9WDH|`hEb(4
z^4=(UADjB@UjPs<`AoD&!KEDSV}?Bhgo_#mh6<~9J$$_?>TtjpQ+LZ(S@!vy!d*z{
z8~6@{Ln6)n{Ckd;x>cLZ2bF}iyI41LD?Si_qeU3otN%WvKb9(ZBb|>gAnx&@9)kaN
z{dtOiKBCR@@(hL;-&KJdld1v2kvB7YCa5AUu~dq*XL$ihBczK_)aY}mBrUHduJE@1
zKL8nK@-V=!-H&iDkeQjeE^a0S36o1y6uombK)oJlr}GNKPC!tWqkM+a{Qwe48Oc1%
z_FFlGsm3ioKcD=H-^kN&E|&31)KlXtuQ0n?6^Q4{>A;)yyU3-oP1ttxv8KT5{sn8A9_4MRdNGoq(EFwh@f{cl-&oTXLpJ1
z${eg=+lLHpv^&3u$yuwcxxu|T!&+L#%(p(oYJ8^UyUE_rtR{8OS%#!e>2_k=K;znf
zD-?H9qkE0Q;DaBeKk5MZk}SX)njcCGdZAfXNN*!<4U(X#^O_qcPPe6RE%e~)vr
z(%56SXlU);8L&U!Jhpn7Tr2;Od(kpp*Pg#faF%>&Kin_)Cx9b3OZj})Nc
zPs-bWQYknz)Xv=M%o$$T2`dV6@wvPT7
z(AOm?s4BKb*0cmbO(hp@*|H`pgCCGs2fccfMXjL#ymiS2AK=)Sjo&4rFbMs09(20I
zgI!ZZJ%3*>@T8BV&l}3S?lguo!p42fcH1}K{(B+OvPCzQW3luaWvXTV{w=%#&tDf<
zkoVais!Wf`ZJ;G3alUe~$hCGf_dKz0{MT5x9)D94#S{UI_F{A5zXE<6%hRqc
zwv<2lbr$VtcS;XJ_ZEGZ+@7>XYMV;ulH+y?{Piz5$ZUpiH%Dh`f2+?S>b!mTlWqh52_qPp+Z|PllW2Zlf)791ds^uIe
zUCpm5AS^?^f*@`ylqwm6A`cAOdgDyQz#;ng#sPo2eq~aQEJ?CC+||+?Vi~XCjVM!+
z9f+}2`_$G^rW^wI%u+o?h+v*?!Bl(LnOh0>P!G8$gH6fJj}u~O6#e6j=1TR
zv(aaa;biwNm>uyf#OMWos*%!k^F0}6EyquK)L<_dSPY6eH
zl|`?;qOo^2md6b=C3i|23;e2Xnj{ui@7lsLT|g*?*fn38wtDCfv3Fz>l*m~n`L7am;~%da>8~
zVd`Y9k3*>XNbQ~rb@7kD54w~b`Im{#y&}V5tRzf&MN_v%U0Z}XbHiHh6{n0)x&
zD6SACMQk$p^PwsBLf3UDWSE-D-abH>rN?rcyA^57JuDK=RrK1roPPNF
zMy{i~E(TR!MIu{%GS{&nWzR~%-B1S-;g+
z=ff)+N086i@I6-^)!foSMnz&UF*zrNXIzz2sx|?7s5*-oq6En2h1$X&O2H%3)3u>S
z9uMOT;B-9#;XHtCBVkhjAc6s}EoB_d3J~6~*L36~#=+
zNC%tv
zg-o~#EE$sdpY;rLs^M7w51G`VDJ(4P`SRReX;L(`M_0qb#MA|S;a6=_Qwh{qJ>@o`
z1W}y|P_ptM{7#tCBQQR+g$&zWxo^tB4;`k(
z8D7rFE?E0_B3~8_`DEB@n%{^so8l~Mw8bLcc|
zdxjK(dFV(%wtmRaP!Cf2>=_QLtik#tF^Pb+Y}pNgR0^-y~Wg=e_mf7=peurpa|
z=zlHqA1vnx3J7zb3A%PTvqwr2`nI9
zv)A)P5HNzrV8HqUUh~bB%H$2=AdzN~>e=Dp=RpN@Y=bMX6|tv0HwL|Malt|kV`F}7bJ
z3(xh5JF37;yy+P{KqeOoB`oTV7{TU@y0JLBw?W7=M_OCLen6qb=zcFDp#}Obms5rs
zIn6hoGnh1R%a02lPU_#)Ii%FG(H04_7@;W*pPunKw2GSnYaD1iSuXU5uG1Zm@Bx7K
z`@!!@-h7Z_#kuOg759U~;aQr#2lQ7cU>zZA$mU@Mv7E0;S5$1~62tTJN$24p0Fs^s
zz7CmXd8vEKiM*FPE%!pN3e=DEv)M!sNl;f%bJvEB+nVkz@+lfp
znBPGcfE3n`{uC=W|55^_l4+j-mB-APzL5jgQ~#H3sKzM#1P#}&zDaBi@J*povw^G2
zta|Xpood&*K#h3hMHJ)dlB?vT<{4yfLr7-ek>94MW&GY5VBXh*N|1i_hYwkaMl(V&50
zeC)MlEB%i(cVy~ZjbB*M6Y)HS@%CfU(9lS*;>*wLpumXO90@*1?O-GR^jbaTfLkhd}>rsRWZV|gyyg=yp+*Nb!-H%Ts|*Z9~TG=r~Il#
z+bo878`sw_3TG%Ru$mF%WC`ynttLZrvw==3I~i#=|=067=HpFiL*5;l^JsbfIB
z+{59Mt(yv`YT+RzsA)=}4ox4YVVQ=@)>mLr_S+U+4e=tuJd}>9O#s}8fvf?M{RB1(nCmwPsMw2A5Byu
zY^2MA6%`5>^>GXxKH9iDC|8W@7HYTAgL#A#G;0Hk$8nWF*=R`I(BA(y*5|NY3y0~y(dbjfxA&U9j;~D%gc>Me8wTi5U@+SC2ctaZ#DfAZUt+bGG
zSmPySTm2^{d27_R@iPbW6gA1&j~`R1_P{ftQ{9BfIrfnz)7Be`-jvV%Dr6pW>$y)s
zmkXz^q1!*8Kmpx}RFVvT8LP&nal3m#8}a6s=56txUg0}}>_kRq_tc)56wDlWY4}Ls
z+8#(U5H&tt9CzuYcflBTLW2Ae*9j}l6JZrXd)wF8HH`+pr+ajFsu@Zk$vBxB9hkH$
z%=bi+cedmFHFZ<>a-GaSYAQ;udC<6P$%pcdPnFU-EtTwPv{jv}yLJ!jc(3@K@h!;n
zi730u45iBVTFLWJ&l%`39{0tw@7+n^u3}98dzyhcWhypG76DCby|%YiB6a?nVi*tE
z8_Pf0pCycX7!ws5{Ay$7I~l8-`Y!K#@K!uns$Qs_xsXjdo3}UW^Ex=?!~IYyHZ-{c
z2;}p$8=H@z?@ZG+5XUe-BjcM@0BgZ(O={Tb1*zx-4)Dd&;TB<*!_aSoB4_Yc(q@n=
zI8AYi=Ei7bi36)nMfr&NA-kYk)*?J;m!6ut{zD}t-V&jOy5~ZKyXNfRHy9;7IpZrb
z@160pa^66h3-^iSU-M%lOy%jlyZMx%9=O5_l
z>3QB9XR$SpH@tG=(O2xy!kVT+yp9m+CWz3%vGs;@dbPWs)IHj`^E5{=N82NX&DobOhjem`0$i0rd1R8!g&zi)qeQdp*5#{vH
zbBcTlGm7p~;S4s9UvuCLZl%YxX19X37LPuv=vp8X;mujgeug1ahNY+-7lad#5ogrQ
z&!MmNhv{A?@yw`Sv!jR6h^+63=z4D64QY(;5uS#z{z~5?+-pY3Vj~s;xkMw@maQ3O
zAK2Yz3JW;ouMuP#Xr{Sd(Hh*t*<1nB@~Oq~8i-{&pf2}LVCkRWZ{jZbPJ8HGN5y(%
zVorC>Wx_d)SlZx6LFz0=#E|t7vhrUN&`e#(r3YCB#0_KaK2eW@kAGkHeh!_}Uq4_D
zVTFZG6ar18Dk^gJCM@ywe>xCU&Wo2phIx?KC0Q)-g+_QZ*e(>*i*s2?q`s)Ue@?X;
ze6hr&`Os6ylmvt=2Pq!pcW}UdL>SQ@!MmI_-bEu#{H7N|CmrR?jB}~2Fzgwd6zpiD
zjLT!BuGz+7XEwAL!TlsTS%R6wdZ;ljL>zgQI^dflk`9M1*pp(
zq=oKC94h11ZHM7wZ;FmCEH5_IR|
zEx1!GSjX<0kYl|N!?byc($HjSKq)Tnjneqe>RPGeLP+L&e03}gq4EjZV&R8C7YkHt
z?HFnu0h7uJ&Xa-qujccjsKeHCP=jF_v(adRC(6_Cj;s@nYmtrgz}vGkI}?9*ppzA|
z4$#Id)ZQEizf+gj*YiR(@9yphnS*3yWpT`Y8dm8_zs|DMc2I`{Uc#BZ2dU8VeDu$q
zmpv#u`o+51IXS9G*QvV6Glm>V@+?W)3RKtjSyJ4~k>%9b%Qxd#;K|`wYR)NXe7Vq8
z4Ur6avydHC%AA>MqE0{ZstA8{vEdA}%ad0Qq2-bb`y*u(PddP0`liAmJrU;
zJ1oOTcpU@mxI;i@Y#VH*qS+5k@||v2*yxqhu|;S|kheL5{i&Gh~^|P=I(8)V^qUGMZSt5)FlOEBl
zH-CyST#U0$Ilgu`xn&8jo7l>KI;MSuOXdNNandes0HJIC5TI>|<#1k#aeneu~
z+ulzU5qY_U;fJb_B5~Po>u>nV=pnm`355YL4%>=_TVJJ8=UA5sT{=%;-0q$r+c#3Q
zD~!g2t%UlMO^r1M&1lTBSqiMSvR0D@7F*(>V!iMnYNVlX5xRZ+W!yoQ8ok~C#{i{Ku5}F9HchPLO&{rDYw$S?Z_wx?SgDD_X
z;r4255krLF4QU~wpo$af>!Tt8S}qTcdvq`QX;jcv@5~D_qXT^pfcR{S%n2vLNQbrt
zqZn(qqNlcb9BJhWnS8tqX5WIKdwoy<%q)Q8mvf>TT}u(Y=|EL8{nok_;UP==v>Kya
z-6Rip&6A*GQpdS5x#x3z&(sr)HMwOzCYnk=_j5_LnuL+0VFj8A16rP2tc9@lr
zFmKaxUE^doF6$=EBugE3_N-0eHdTgBz>CMG7DI(Fm#d
z`7z7xeRnTq>ukL1@(70Rh1TyC9VNcyy@?8Mi9ATOz&q$aKqEa!NV-gX-
z4^~RC0{1_@o1ot5rV+c&Hgg+_U#F)GCuk=!zBJYHH1xFZj_CeCDApv*)w-1gv9)B4
z*%(|>;A0;qF^L)$!b##^uCIc+%9HcIj3aP#c=+0Iu5*MopP^cQP?ZTK0<)6f!~eL+
z6D~LS-oHY2afasb3qUACuR6@CbELm^3|Me1l&Rc6)yz+CjU|%+4Do>us5G&6Oe3uk
zmk!pp;~ftXbOo?A{*_r?gE67-bMHeEH2tMB*cM@U5N
zpk(iPe~IVViXiqw$d#%H`}js&+BpD&4~}x#4mnPI&^Q`@e3Bt_C8>vL_5`DQPBW;N
z05^^voT1&V>Wmgt1R!g|H*b2t9>+|fjvhh6!2aR}dZ0ID6mG2BjxL9W~2X*ZXM=uKxJKr1H8ibkY>ZzPCt!?($z
zQ1??2l7W%xTDAjzFNy3YJJ_Hxl-p{TPp)J^vFh+T!t3PaLD5z!bT;@;nf}x^`0Tf;
ziDr&20hNoZc^v~7M)zpTie=JYY>6+!X?CxE_UQGbe@SQgQ$m88r>q^y-ZL8+9j2H&
zLpYMZKja-5+u00Ln8r#TX1)Gch|d<@0|ahe&C7GqxW95R?RhQ)~uv`|Nlcu
ze5dOS_fz-qXo{?&GEfJarjwJ2;GQ@dQ2tS@uX1SRt*hfON0i87NZ}?F!ofY-wI&0r
z-^!5?fuhU}e}Gd9(McVBkixBh7J*@S>&5As*Dsur5nlJ*rXJ6vJ7F)QuP}}EL9@^e
zckrhx_=nL`dz80SUdAldtFA&Yp?u@Kiyxgqsw&bR+Uk2Q6!|5
zk4puD5>u*I_0UI+V%!xi13fpo?1LMCsb!AOF`kEx3bBk{47u4)vRou}2}XstJR^!!
z?Dt>Y-lW(9_?JM?u@x>YV8h*J*Kh40Y%j^|31@eY4>a1f4K)JVI%Lgf8z9y-
z8hTc*Vf8`-n@VOSAXlt^GRoBb+H#pdMuOQIVxEJXQHkIQ8@!LUBm4f1slS4vQutatj6ALk(VzF0=?*31B>sx=2!zW?Hs1{xrhi7@8rN%@
zbr|Fsn-6}>Bkp#L!VOk`_ki8Uir=NP5>}$|R+?j&`m^KOV8H1?S*TUsG}@Qaov|g~
zfPFmjf+WRiPcMv2cj;f{DJF{vzBJF
z58Ev2*`{&-KNVEbcLV0@hbR
zIoP_&prk}yW^$##h=)BIG%DFnM?j`cro(j4U8m(>z}ThGM|~92KqV}(AjZr&ZRd+E
z^*d%Q;}F`*9Ba&}2%pc5Ic%HCp(byEhj9V3U+d*&F((cLS03%3js@2&i)HaAGBOk;
zZFgN7!k2!B`+1g6(%lmZF|cxdF+({br#bNr;a8Z3a;T9+QIgvkK%s0v&_UBI2fcLc
z9X&Q*&ucfzCF*p#ZucjoAz6ibpV*{hnc?Qt-EZw7Z0}Ld_HbEsG|-HlAMZJ12sOfq
zHv?+M7U?Q6!cis88IR&m7*#W2!!lLxa!^(1f&MX7%g6Va8rE7GG-pUq>y%7Lo`FW;>CqeWb5o0LtlPenXHv51
zTWZ;T|COnzsQ}4569I7<@JE#>_&AF~FAHQj(-}&dS5g&}lprAr&R1Axtiml{+`$;5
z;?~5(=ajwdb7kb>c0$2C;v3h5Oy=iQD1q4(*(tWvfrTlwW!B$s^)hh5-
zT8f7Ko*|(ul1j7Ak?$^R;CSGiv4c*(&2H_<1>=58ut}G=dDf!i#Gxxc?Asgq=tX(H
z%k)A*&Q(F(=0W^5LA9UhuyZ#W&%H;;e|ZCXW^OZNrYWc`9K=FZo?{S+T3zdt_ZOLz
z38^Nv4k3x#+SzRYCR6=G{juZf9I6K1-U1*E4Rr&&*^D-{e?n&9KGc-IedHVGA*be6
z#EDv1&wuwgfJIgk(6$T{GaSU83h!BNs%c#sI{A_8GoCY*7f0Z8hDVxQ19U46vWKV?
z21yjBapmo=4}v~(wDEDjU5geNOjB#TUQ_Kd-@qKu!m&;t0xkX-S)R@0c*(R8H(
z%tt`*eZONITR*XgsNGrMk0fK<#eC{%MMOG9@0gUI6~v^4OZUhb3!i{;b8NNfv(!d*
z^~_j%3Nxe4%Q=-os;ujpW*#Z!LCx5)aR*Puw~BcZ@yjl6Jazv{%j|4x_6y9u-5|->
za2HOKdSzcPbhr@=DlF8&H@f{pwSQo)FnczX5u=-mN6S9U(0*yN>E(iyy{v^70AFM;
zQ+pM@o!k^H*KRC@D%>Qf};
zFdKBbDTaqBp`{sL%3~yvXyOKq?qRi10$Lqb
zAz+^5INW#nA7l8=8=p7%qnE8740gA8CKx~tqYyaTb7BYx5gY0I_{TQrzo7O%ZNlLw
z&PQ4p#VamP5J?=Padia>%~n;bFK-Y7<k4rVsAA?(^;cp!m}4I*7ArRJ;oi%YHPWIF$kJ;W`U%`kBgNyUMq{
zD+HOayf%yI)_H&mZGa;(kuoot&yem8NxqlyDf65L+i5YoZbVGA4EyOoeOgZX8kcn^X^)MKqlPS^Qxh$t9nAQ|UQKqp5lrP<-7%SAITZ
z*DHb4{lJ2qgDu3;EcgOR@BH&Ww=d&q$XNZIhwDLyviAm4XM
ztI#c2FqtjT!i4XUsU;}VyJX-X4Tj4$*pr&LGm&Li1Ks-uCG<0X096zEvGKHKEoOGAm
z0k)VJRLwH{likU<&oz&lG{h)6I6N^;Wz^Q5#O+X-
z8akJCDQ_5qCP8TCtEg%A3MES43^0>Xid2soVGJsWg3R>>j7b`jipIhpa$$}a1JADG
zJE;3a&qCYPLxL<7WEKy7{l~^@?(&M~_@+mAVK5}I_6i_8GNXf?pRJ*zJ;_Qe-8n$7
z??odr*DV=4ljS>;?#CN53
zuJWt>W|oHbyYtVUcADJcnqKOg)IE=Hhpzmg?b5JIH%rpPWp|^e8m!BxK$TD;TOEgN
zCZ@w6J!(lT6H#4;eG~s
zGvcwO+r!)Oe$yIUO9cH356uQ#vC>7bd>=KA!};8WqfNs`RU!0A@hG<5=erFZ1ce~X
z-8Tz_k_I(cCnGAzO?20T0Mx8a*eKdX=66a*Ivp)}Bw;~jp@8rOTn1yFU9a>NTX-6M
z>foC$l62%L^iME@YbxI$p5Uf}@1+i2*ENz0B~3VEsV|loD{g!|N9&A`M{>sPhw#AI
zn-BluwyhL)|MiwT1@T7eO@3{qwWsT+_`58Vu<8~PSy5SwpHuNV@?G1T
zDOCwaceS_6f-3ewTJhb1UnJ_=t@2=OiY*fN?&xsiFun(M^_R|z1O%CCWQvUcAEx$MIR}XW
zMip0CqCGskLKVHVP%(3$zcgY&J&vWBW#y89;_vD4w`gc*jmJ;~T2CmXk(IBj)m}UD
z@T-0CXhg_tXTKxNcmX%^4VaYEYmI(Ba$B*AxAZ3SBvYU}7|@HX%^+@kB=6unlm0-y
z0Xb})1HrjjW3-gR^?h-iQAasdB83sF10Z4eq10@2c(Q6Y_HegURbY-Yo1^5TtB{{t
zqsU#{(&(c42SaHN@X)NBH$lg&ZlE8xol+zx#RA+>P82t-uQfBj(PJ@pCA*_uMhAkU
zUQF=e+I};pTl42=#pvP0m|PGJ#-fblgf@B-H)2dxWhL>+2zKKU{8{~2b*)K|IxhIW
z$5H1vA8BZjx)yDuQ{W2bu^uIDSgHB}HW?fFwfe&t#%xpBS3G>%E?QY6QWk3Ws>mv9
zsVJyLfC8?%0D6c6#CL__>|rWQhB;D^8E-I)$_rCKPHg!K#`At$FeylhMJ_o=KW#o+
zV9P>Brp%1H;+1r-NU6e6-xf?mr@Ii-OK@4Rz0G3B2as#{7DVRVPD@}fKU_IUpcq7b
z5``0`qfnFl^A63H#_)hNBamY!uZ)WQag*~;ngci-TN-Y>xt}+v@kigaxpSv~?UC9;
zGu~VynZ&64aIiA9Eq=WSYZ5<9wY(6DNy^84USe=4{bb24u%Xz8I2QstmK1LM#p8cl
zi5_wxwYAjH>M6?bAh-&PnfBvjQk_(6LVtCgu=Kyzx^{B%kGCzbP
zqxTDZ=z_;3pSOWbgO&UoyY!v@p)eT=ReTY~u|=oao@=D1I^c_ENRW&mZvm73l{&>p
zMDI`3Bsj~1yFLD?^J14)B!fRrfC%(?!o7C;Iu3r*Hu+*{n&`r!1)@(m(!_v8;u}2H
zZQaPrux6v|FtO;@F8UT`P}gW4#K`!4vLr6;nT%Lfh-2of7KecHFNpp-l|wcNLnA&|
z*EJ8SxrfsHLz%}f|LSel_ldB3L@t|ReS*X*eBBSGbal1TEMx@7?*XCQw`~~b0!Lhs
ze2(=M93rz{RjfAu6uz5Z$*0f_V&(Yh1