From 63b8e5db0151b59cc1c07b4d29bb54772cfc0d77 Mon Sep 17 00:00:00 2001
From: lyukai <760492172@qq.com>
Date: Mon, 14 Jun 2021 23:29:46 +0800
Subject: [PATCH 1/7] =?UTF-8?q?=E6=96=B0=E5=BB=BA=2017307130133?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
assignment-3/submission/17307130133/.keep | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 assignment-3/submission/17307130133/.keep
diff --git a/assignment-3/submission/17307130133/.keep b/assignment-3/submission/17307130133/.keep
new file mode 100644
index 0000000..e69de29
--
Gitee
From 102a045d1be289b08fdd006491de02f2b91a4d25 Mon Sep 17 00:00:00 2001
From: lyukai <760492172@qq.com>
Date: Mon, 14 Jun 2021 23:30:37 +0800
Subject: [PATCH 2/7] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=92=8CREADME?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
assignment-3/submission/17307130133/README.md | 151 ++++++++
assignment-3/submission/17307130133/source.py | 350 ++++++++++++++++++
.../submission/17307130133/tester_demo.py | 117 ++++++
3 files changed, 618 insertions(+)
create mode 100644 assignment-3/submission/17307130133/README.md
create mode 100644 assignment-3/submission/17307130133/source.py
create mode 100644 assignment-3/submission/17307130133/tester_demo.py
diff --git a/assignment-3/submission/17307130133/README.md b/assignment-3/submission/17307130133/README.md
new file mode 100644
index 0000000..f113f2d
--- /dev/null
+++ b/assignment-3/submission/17307130133/README.md
@@ -0,0 +1,151 @@
+# 作业三 聚类算法
+
+实现了K-Means++和GMM模型,基于轮廓系数实现了自动选择聚簇数量的方法。
+
+## K-Means和GMM模型的实现
+
+### K-Means模型
+
+K-Means算法的基本思想是:通过迭代寻找k个聚类的中心,使得用这k个聚类的均值代表相应各类样本时误差最小。误差指的是每个样本点到相应聚类中心距离之和。
+
+其算法流程如下
+
+```python
+init_center()
+while cluster_changed:
+ for each in train_data:
+ for center in centers:
+ cal disance between center and each point
+ assign each point to nearest cluster
+ for each in clusters:
+ cal mean in the cluster
+ change the cluster center to this mean val
+```
+
+#### K-Means++
+
+由于基础的K-Means算法随机选取k个聚类中心点,可能会选取到距离十分靠近的数据点,不仅导致算法收敛很慢,还会容易陷入局部最小值,聚类效果不稳定。
+
+采用K-Means++方法初始聚类中心点以解决这个问题,其算法流程如下
+
+```python
+randomly choose the first center
+for i in range(1, n_clusters):
+ for each in train_data:
+ cal distance to chosen centers
+ let D(each) be the min distance
+ choose the one point with the largest D
+```
+
+### GMM
+
+GMM模型是由多个高斯分布组成的模型,其总体密度函数为多个高斯密度函数的加权组合。从高斯混合模型中生成一个样本x的过程可以分为两步,先根据多项分布随机选择一个高斯分布,再从选中的高斯分布中选取一个样本x。
+
+给定N个由高斯混合模型生成的训练样本,希望能学习其中的参数$\pi_k,\mu_k,\sigma_k.$
+
+根据EM算法,参数估计可以分为两步进行迭代:
+
+(1)E步 固定参数$\mu,\sigma$,计算后验分布
+$$
+\gamma_{nk} \triangleq p(z^{(n)}=k|x^{(n)})\\\\
+=\frac{\pi_k N(x^{(n)};\mu_k,\sigma_k)}{\sum_{k=1}^{K}\pi_kN(x^{(n)};\mu_k,\sigma_k)}
+$$
+(2)M步 令$q(z=k)=\gamma_{nk}$,训练集D的证据下界为
+$$
+ELBO(\gamma,D;\pi,\mu,\sigma)=\sum_{n=1}^N\sum_{k=1}^K\gamma_{nk}(\frac{-(x-\mu_k)^2}{2\sigma_k^2}-log\sigma_k+log\pi_k)+C
+$$
+将参数估计问题转化为优化问题,约束条件为
+$$
+\sum_{k=1}^K\pi_k=1
+$$
+利用拉格朗日乘数法求解,通过求偏导使其为0的办法,可得
+$$
+\pi_k=\frac{N_k}{N},
+\mu_k=\frac{1}{N_k}\sum_{n=1}^N\gamma_{nk}x^{(n)},
+\sigma_k^2=\frac{1}{N_k}\sum_{n=1}^N\gamma_{nk}(x^{(n)}-\mu_k)^2.
+\\\\N_k=\sum_{n=1}^{N}\gamma_{nk}
+$$
+GMM模型初始化较为重要,这里使用最大迭代次数为20的K-Means++进行初始化。
+
+## 实验
+
+### 对比K-Means和K-Means++
+
+下图是进行聚类的数据
+
+
+
+下图是使用K-Means初始化,聚类该数据的结果:
+
+
+
+
+
+下图是使用K-Means++初始化之后,聚类该数据的结果,该结果非常稳定。
+
+
+
+可以看出,使用K-Means++初始化的实验结果与目的相符,可以逃离局部最小值,稳定聚类结果。
+
+与此同时,进行10次实验后,使用K-Means++初始化需要的平均轮次为4,使用K-Mean初始化需要的平均轮次为7。所以,使用K-Means++初始化可以降低聚类轮次。
+
+### 对比K-Means++和GMM
+
+使用同样的数据对比K-Means++和GMM。下图是GMM进行聚类的效果
+
+
+
+可以看出,在该数据集上的表现,GMM表现与K-Means++类似。
+
+接下来生成三簇距离较近但是数量较大的的数据集来进一步比较这两种聚类算法。数据集如下:
+
+
+
+K-Means++聚类结果如下:
+
+
+
+GMM聚类结果如下:
+
+
+
+可以看出,此种情况时K-Means++略优于GMM,但是差别依然不大。
+
+虽然GMM聚类效果与K-Means++相差不大,但是运行时间要比K-Means++长不少,因为需要使用K-Means++模型进行参数的初始化。
+
+## 自动选择聚簇数量
+
+轮廓系数(Silhouette Coefficient)是评价聚类好坏的指标,结合了内聚度和分离度两个因素。其计算方法如下:
+
+```python
+for point in dataset:
+ a(point) = avg distance from point to all points in its cluster
+ b(point) = min(avg distance from point to other clusters)
+ silhouette_coefficient(point) = (b(point) - a(point)) / max{a(point), b(point)}
+```
+
+显然,轮廓系数取值范围为[-1, 1],取值越接近1则说明聚类性能越好,取值越接近-1则说明聚类性能越差。进一步地,将数据集内所有点的轮廓系数求平均就是该聚类结果总的轮廓系数。可以利用该指标来自动选择聚簇数量。具体来说,分别求属于[2, 20]的聚簇数量的总轮廓系数,然后选择对应总轮廓系数最大的聚簇数量即可。
+
+### 实验
+
+使用如下数据集进行自动选择聚类数量的实验:
+
+
+
+最终K-Means选择的聚簇数量为3,聚类效果如下:
+
+
+
+GMM选择的聚簇数量不稳定,有时是2,有时是3,聚类效果如下:
+
+
+
+## 使用方法
+
+```python
+python source.py --kmeans # 生成数据,使用K-Means模型进行聚类并观察效果
+python source.py --gm # 生成数据,使用GMM进行聚类并观察效果
+python source.py --auto_kmeans # 生成数据,自动选择聚簇数量并使用K-Means模型进行聚类并观察效果
+python source.py --auto_gm # 生成数据,自动选择聚簇数量并使用GMM进行聚类并观察效果
+```
+
diff --git a/assignment-3/submission/17307130133/source.py b/assignment-3/submission/17307130133/source.py
new file mode 100644
index 0000000..9d2324d
--- /dev/null
+++ b/assignment-3/submission/17307130133/source.py
@@ -0,0 +1,350 @@
+import math
+import sys
+import numpy as np
+import matplotlib.pyplot as plt
+
+
+def ecul_distance(x, y):
+ """
+ :param x: vector
+ :param y: vector
+ :return: eculidean distance between x and y
+ """
+ return np.sqrt(np.nansum((x - y) ** 2))
+
+
+def draw(n_clusters, label, points):
+ """
+ visualize the clustering result of data
+ :param n_clusters: number of clusters
+ :param label: label of data
+ :param points: data
+ :return: None
+ """
+ for i in range(n_clusters):
+ cluster_i = np.where(label == i)
+ plt.scatter(points[cluster_i][:, 0], points[cluster_i][:, 1])
+ plt.show()
+
+
+class KMeans:
+
+ def __init__(self, n_clusters, max_iterations=100):
+ self.k = n_clusters
+ self.cluster_centers = []
+ self.max_iterations = max_iterations
+
+ def get_nearest_center(self, x):
+ """
+ get nearest center index to x
+ :param x: point index in train_data
+ :return: center index
+ """
+ center = -1
+ min_dis = 1e9
+ for i in range(len(self.cluster_centers)):
+ dis = ecul_distance(self.cluster_centers[i], x)
+ if dis < min_dis:
+ min_dis = dis
+ center = i
+ return center
+
+ def init_center(self):
+ """
+ init centers in KMeans++
+ :return: None
+ """
+ n = len(self.train_data)
+ # choose the first center randomly
+ self.cluster_centers.append(self.train_data[np.random.choice(n)])
+ # choose the rest k-1 centers
+ for i in range(1, self.k):
+ # find the point with the largest distance to the nearest center
+ dis_point_center = []
+ # for each sample
+ for j in range(n):
+ nearest_center = self.get_nearest_center(j)
+ dis = ecul_distance(self.train_data[j], self.cluster_centers[nearest_center])
+ dis_point_center.append(dis)
+ # add this point to centers
+ self.cluster_centers.append(self.train_data[np.nanargmax(dis_point_center)])
+
+ def fit(self, train_data):
+ self.train_data = train_data
+ self.init_center()
+ # stores which cluster this sample belongs to
+ cluster_assment = np.zeros(self.train_data.shape[0])
+
+ center_changed = True
+ iteration = 0
+ while center_changed and iteration < self.max_iterations:
+ center_changed = False
+ # for each sample
+ for i in range(len(self.train_data)):
+ # find neatest center
+ min_idx = self.get_nearest_center(self.train_data[i])
+
+ # update cluster
+ if cluster_assment[i] != min_idx:
+ center_changed = True
+ cluster_assment[i] = min_idx
+
+ # update center
+ for j in range(self.k):
+ # find all points in cluster j
+ points_in_cluster = []
+ not_none = False
+ for k in range(train_data.shape[0]):
+ if cluster_assment[k] == j:
+ points_in_cluster.append(True)
+ not_none = True
+ else:
+ points_in_cluster.append(False)
+ # update center
+ if not_none:
+ self.cluster_centers[j] = np.nanmean(train_data[points_in_cluster], axis=0)
+
+ iteration = iteration + 1
+
+ print("iterations for k-means: %d" % iteration)
+
+ def predict(self, test_data, show=False):
+ """
+ predict (and visualize result) with k-means
+ :param test_data: test_data
+ :param show: True to visualize result and False not to
+ :return:
+ """
+ ret = []
+ for i in range(len(test_data)):
+ ret.append(self.get_nearest_center(test_data[i]))
+ if show:
+ draw(self.k, np.array(ret), test_data)
+ return np.array(ret)
+
+
+class GaussianMixture:
+
+ def __init__(self, n_clusters, max_iterations=50):
+ self.n_clusters = n_clusters
+ self.pi = np.random.randint(0, 100, size=n_clusters)
+ self.pi = self.pi / np.nansum(self.pi)
+ self.sigma = {}
+ self.mu = {}
+ self.gamma = None
+ self.dim = 0
+ self.max_iterations = max_iterations
+
+ def init_param(self):
+ """
+ init parameters by k-means++
+ :return: None
+ """
+ k_means_model = KMeans(self.n_clusters, max_iterations=20)
+ k_means_model.fit(self.train_data)
+ if len(self.train_data.shape) == 1:
+ self.dim = 1
+ else:
+ self.dim = self.train_data.shape[1]
+ for i in range(self.n_clusters):
+ self.mu[i] = k_means_model.cluster_centers[i]
+ self.sigma[i] = np.ones(self.dim)
+ self.sigma[i] = np.diag(self.sigma[i])
+ self.gamma = np.empty([self.train_data.shape[0], self.n_clusters])
+
+ def point_probability(self, point):
+ """
+ calculate posterior distribution used in E step
+ :param point: a point in dataset
+ :return: the probability distribution of point belong to different clusters
+ """
+ ret = []
+ for i in range(self.n_clusters):
+ pt = point
+ pt = point.reshape(-1, 1)
+ mu = self.mu[i]
+ mu = mu.reshape(-1, 1)
+ sigma = self.sigma[i]
+ sigma = np.matrix(sigma)
+ D = self.dim
+ coef = 1 / ((2 * math.pi) ** (D / 2) * (np.linalg.det(sigma)) ** 0.5)
+ pw = -0.5 * np.matmul(np.matmul((pt - mu).T, sigma.I), (pt - mu))
+ result = float(coef * np.exp(pw) + np.exp(-200))
+ ret.append(result * self.pi[i])
+ return ret
+
+ def fit(self, train_data):
+ self.train_data = train_data
+ self.init_param()
+
+ # train with EM, described clearly in report
+ iteration = 0
+ for iteration in range(self.max_iterations):
+ # E step
+ for i in range(train_data.shape[0]):
+ temp = np.array(self.point_probability(train_data[i]))
+ self.gamma[i, :] = temp
+ self.gamma = self.gamma / self.gamma.sum(axis=1).reshape(-1, 1)
+
+ # M step
+ # update pi
+ self.pi = np.nansum(self.gamma, axis=0) / train_data.shape[0]
+ for label in range(self.n_clusters):
+ mu = np.zeros(self.dim)
+ sigma = np.zeros([self.dim, self.dim])
+ for i in range(train_data.shape[0]):
+ mu += self.gamma[i, label] * train_data[i]
+ point = train_data[i].reshape(-1, 1)
+ label_mu = self.mu[label].reshape(-1, 1)
+ rest = point - label_mu
+ sigma += self.gamma[i, label] * np.matmul(rest, rest.T)
+ # update mu
+ self.mu[label] = mu / np.nansum(self.gamma, axis=0)[label]
+ # update sigma
+ self.sigma[label] = sigma / np.nansum(self.gamma, axis=0)[label]
+ print("iterations for GMM: %d" % iteration)
+
+ def predict(self, test_data, show=False):
+ ret = []
+ for i in test_data:
+ prob_dist = self.point_probability(i)
+ label = prob_dist.index(max(prob_dist))
+ ret.append(label)
+ if show:
+ draw(self.n_clusters, np.array(ret), test_data)
+ return np.array(ret)
+
+
+class ClusteringAlgorithm:
+
+ def __init__(self, model="kmeans"):
+ if model == "kmeans":
+ self.ModelClass = KMeans
+ elif model == "gm":
+ self.ModelClass = GaussianMixture
+
+ def get_dis_mtx(self):
+ """
+ get the distance matrix for every two points to reduce double calculation
+ :return: distance matrix
+ """
+ n = self.train_data.shape[0]
+ distance = np.zeros((n, n))
+ for i in range(n):
+ distance[i] = (np.nansum((self.train_data[i] - self.train_data) ** 2, axis=1)) ** 0.5
+ self.distance = distance
+
+ def get_avg_dis(self, cluster_idx, point):
+ """
+ get the avg distance between point and points in cluster_idx
+ :param cluster_idx:
+ :param point:
+ :return:
+ """
+ if cluster_idx[0].shape[0] < 2:
+ return 0
+ cluster_idx = np.delete(cluster_idx, np.where(cluster_idx == point))
+ avg_dis = np.nanmean(self.distance[point, cluster_idx])
+ return avg_dis
+
+ def get_silhouette_coefficient(self, label, n_clusters):
+ """
+ calculate the silhouette coefficient for the clustering
+ :param label: label of train data
+ :param n_clusters: number of clusters
+ :return: silhouette coefficient for this clustering
+ """
+ n = self.train_data.shape[0]
+ cluster_idx = []
+ for k in range(n_clusters):
+ cluster_idx.append(np.where(label == k))
+ S = []
+ epsilon = 1e-9 # in case of division by zero
+ # cal silhouette coefficient for each point
+ for i in range(n):
+ ai = self.get_avg_dis(cluster_idx[label[i]], i)
+ bi = np.inf
+ for k in range(n_clusters):
+ if k == label[i]:
+ continue
+ bi = min(bi, self.get_avg_dis(cluster_idx[k], i))
+ S.append((bi - ai) / (max(bi, ai) + epsilon))
+ return np.nanmean(np.array(S))
+
+ def fit(self, train_data):
+ """
+ find the best number of clusters between 2 and 20 by silhouette coefficient
+ :param train_data: train_data
+ :return: None
+ """
+ self.train_data = train_data
+ self.get_dis_mtx()
+ max_sc = -1
+ for n_clusters in range(2, 10):
+ model = self.ModelClass(n_clusters)
+ model.fit(train_data)
+ label = model.predict(train_data)
+ sc = self.get_silhouette_coefficient(label, n_clusters)
+ if sc > max_sc:
+ self.model = model
+ max_sc = sc
+ print("num of clusters: %2d, silhouette_coefficient: %.6f" % (n_clusters, sc))
+
+ def predict(self, test_data, show=False):
+ return self.model.predict(test_data, show)
+
+
+def shuffle(*datas):
+ data = np.concatenate(datas)
+ label = np.concatenate([
+ np.ones((d.shape[0],), dtype=int) * i
+ for (i, d) in enumerate(datas)
+ ])
+ N = data.shape[0]
+ idx = np.arange(N)
+ np.random.shuffle(idx)
+ data = data[idx]
+ label = label[idx]
+ return data, label
+
+
+def data_1():
+ mean = (1, 2)
+ cov = np.array([[73, 0], [0, 22]])
+ x = np.random.multivariate_normal(mean, cov, (800,))
+
+ mean = (16, -5)
+ cov = np.array([[21.2, 0], [0, 32.1]])
+ y = np.random.multivariate_normal(mean, cov, (800,))
+
+ mean = (10, 22)
+ cov = np.array([[10, 5], [5, 10]])
+ z = np.random.multivariate_normal(mean, cov, (1000,))
+
+
+ # plt.scatter(x[:, 0], x[:, 1])
+ # plt.scatter(y[:, 0], y[:, 1])
+ # plt.scatter(z[:, 0], z[:, 1])
+ # plt.show()
+ data, _ = shuffle(x, y, z)
+ return (data, data), 3
+
+
+if __name__ == "__main__":
+ (data, _), n_clusters = data_1()
+ if len(sys.argv) > 1 and sys.argv[1] == "--kmeans":
+ model = KMeans(n_clusters)
+ model.fit(data)
+ model.predict(data, show=True)
+ elif len(sys.argv) > 1 and sys.argv[1] == "--gm":
+ model = GaussianMixture(n_clusters)
+ model.fit(data)
+ model.predict(data, show=True)
+ elif len(sys.argv) > 1 and sys.argv[1] == "--auto_kmeans":
+ model = ClusteringAlgorithm(model="kmeans")
+ model.fit(data)
+ model.predict(data, show=True)
+ elif len(sys.argv) > 1 and sys.argv[1] == "--auto_gm":
+ model = ClusteringAlgorithm(model="gm")
+ model.fit(data)
+ model.predict(data, show=True)
diff --git a/assignment-3/submission/17307130133/tester_demo.py b/assignment-3/submission/17307130133/tester_demo.py
new file mode 100644
index 0000000..19ec0e8
--- /dev/null
+++ b/assignment-3/submission/17307130133/tester_demo.py
@@ -0,0 +1,117 @@
+import numpy as np
+import sys
+
+from source import KMeans, GaussianMixture
+
+
+def shuffle(*datas):
+ data = np.concatenate(datas)
+ label = np.concatenate([
+ np.ones((d.shape[0],), dtype=int)*i
+ for (i, d) in enumerate(datas)
+ ])
+ N = data.shape[0]
+ idx = np.arange(N)
+ np.random.shuffle(idx)
+ data = data[idx]
+ label = label[idx]
+ return data, label
+
+
+def data_1():
+ mean = (1, 2)
+ cov = np.array([[73, 0], [0, 22]])
+ x = np.random.multivariate_normal(mean, cov, (800,))
+
+ mean = (16, -5)
+ cov = np.array([[21.2, 0], [0, 32.1]])
+ y = np.random.multivariate_normal(mean, cov, (200,))
+
+ mean = (10, 22)
+ cov = np.array([[10, 5], [5, 10]])
+ z = np.random.multivariate_normal(mean, cov, (1000,))
+
+ data, _ = shuffle(x, y, z)
+ return (data, data), 3
+
+
+def data_2():
+ train_data = np.array([
+ [23, 12, 173, 2134],
+ [99, -12, -126, -31],
+ [55, -145, -123, -342],
+ ])
+ return (train_data, train_data), 2
+
+
+def data_3():
+ train_data = np.array([
+ [23],
+ [-2999],
+ [-2955],
+ ])
+ return (train_data, train_data), 2
+
+
+def test_with_n_clusters(data_fuction, algorithm_class):
+ (train_data, test_data), n_clusters = data_fuction()
+ model = algorithm_class(n_clusters)
+ model.fit(train_data)
+ res = model.predict(test_data)
+ assert len(
+ res.shape) == 1 and res.shape[0] == test_data.shape[0], "shape of result is wrong"
+ return res
+
+
+def testcase_1_1():
+ test_with_n_clusters(data_1, KMeans)
+ return True
+
+
+def testcase_1_2():
+ res = test_with_n_clusters(data_2, KMeans)
+ return res[0] != res[1] and res[1] == res[2]
+
+
+def testcase_2_1():
+ test_with_n_clusters(data_1, GaussianMixture)
+ return True
+
+
+def testcase_2_2():
+ res = test_with_n_clusters(data_3, GaussianMixture)
+ return res[0] != res[1] and res[1] == res[2]
+
+
+def test_all(err_report=False):
+ testcases = [
+ ["KMeans-1", testcase_1_1, 4],
+ ["KMeans-2", testcase_1_2, 4],
+ # ["KMeans-3", testcase_1_3, 4],
+ # ["KMeans-4", testcase_1_4, 4],
+ # ["KMeans-5", testcase_1_5, 4],
+ ["GMM-1", testcase_2_1, 4],
+ ["GMM-2", testcase_2_2, 4],
+ # ["GMM-3", testcase_2_3, 4],
+ # ["GMM-4", testcase_2_4, 4],
+ # ["GMM-5", testcase_2_5, 4],
+ ]
+ sum_score = sum([case[2] for case in testcases])
+ score = 0
+ for case in testcases:
+ try:
+ res = case[2] if case[1]() else 0
+ except Exception as e:
+ if err_report:
+ print("Error [{}] occurs in {}".format(str(e), case[0]))
+ res = 0
+ score += res
+ print("+ {:14} {}/{}".format(case[0], res, case[2]))
+ print("{:16} {}/{}".format("FINAL SCORE", score, sum_score))
+
+
+if __name__ == "__main__":
+ if len(sys.argv) > 1 and sys.argv[1] == "--report":
+ test_all(True)
+ else:
+ test_all()
--
Gitee
From 0858c5f6b624728ee5d100c62d3c78756a3b6a86 Mon Sep 17 00:00:00 2001
From: lyukai <760492172@qq.com>
Date: Mon, 14 Jun 2021 23:30:44 +0800
Subject: [PATCH 3/7] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20img?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
assignment-3/submission/17307130133/img/.keep | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 assignment-3/submission/17307130133/img/.keep
diff --git a/assignment-3/submission/17307130133/img/.keep b/assignment-3/submission/17307130133/img/.keep
new file mode 100644
index 0000000..e69de29
--
Gitee
From 461ba40585bb25870d905957117ce6fe6c90610a Mon Sep 17 00:00:00 2001
From: lyukai <760492172@qq.com>
Date: Mon, 14 Jun 2021 23:31:14 +0800
Subject: [PATCH 4/7] =?UTF-8?q?README=E4=B8=AD=E7=94=A8=E5=88=B0=E7=9A=84?=
=?UTF-8?q?=E5=9B=BE=E7=89=87?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../submission/17307130133/img/auto_gm.png | Bin 0 -> 361506 bytes
.../submission/17307130133/img/auto_gm2.png | Bin 0 -> 347040 bytes
.../submission/17307130133/img/expr1.png | Bin 0 -> 121865 bytes
.../submission/17307130133/img/expr2.png | Bin 0 -> 385424 bytes
.../submission/17307130133/img/gm1.png | Bin 0 -> 284494 bytes
.../submission/17307130133/img/gm2.png | Bin 0 -> 388935 bytes
.../submission/17307130133/img/kmeans .png | Bin 0 -> 123457 bytes
.../submission/17307130133/img/kmeans 2.png | Bin 0 -> 371386 bytes
.../submission/17307130133/img/kmeans 3.png | Bin 0 -> 380134 bytes
.../submission/17307130133/img/kmeans1.png | Bin 0 -> 124724 bytes
.../submission/17307130133/img/kmeans2.png | Bin 0 -> 120344 bytes
.../submission/17307130133/img/kmeans3.png | Bin 0 -> 123189 bytes
.../submission/17307130133/img/kmeans4.png | Bin 0 -> 123707 bytes
13 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 assignment-3/submission/17307130133/img/auto_gm.png
create mode 100644 assignment-3/submission/17307130133/img/auto_gm2.png
create mode 100644 assignment-3/submission/17307130133/img/expr1.png
create mode 100644 assignment-3/submission/17307130133/img/expr2.png
create mode 100644 assignment-3/submission/17307130133/img/gm1.png
create mode 100644 assignment-3/submission/17307130133/img/gm2.png
create mode 100644 assignment-3/submission/17307130133/img/kmeans .png
create mode 100644 assignment-3/submission/17307130133/img/kmeans 2.png
create mode 100644 assignment-3/submission/17307130133/img/kmeans 3.png
create mode 100644 assignment-3/submission/17307130133/img/kmeans1.png
create mode 100644 assignment-3/submission/17307130133/img/kmeans2.png
create mode 100644 assignment-3/submission/17307130133/img/kmeans3.png
create mode 100644 assignment-3/submission/17307130133/img/kmeans4.png
diff --git a/assignment-3/submission/17307130133/img/auto_gm.png b/assignment-3/submission/17307130133/img/auto_gm.png
new file mode 100644
index 0000000000000000000000000000000000000000..92760d2f0e72f2502b52111580269f58b6cebd3b
GIT binary patch
literal 361506
zcmeFZ2V7H4x9|&s^eT$+e6r@IwB29|)7AX>X=pB(R
zy@XCkzC@q*d7ks#d(QcN_rB-5<-Fk+GBbP6%-)mPGi$B?T8YutR3;^&Bf`SMB2`sU
z(80pOmBYfq5hcJwmvql5Yhz)NI6276Ypcr3vuJy|**ZAeU}34myfeht)9sj-;Iz21l-M2JUVbP?+iq|K3a-RJ
z{#GteZ0;fZ-49!>p5K9kbLWQx0AQ0qg8-KOiO0P+40^;bOg*v%c_iP9vEF;9x`|6b
zL+JgImc=80pYWluFp&)HCW>dzRmSDMA>*xDq!`j%F^U&-fF;8&n>muOA+z1T9;qPbjO+1UltcXSw?ezLs3GC
zE&1lBEW`ZD_mot&%P}w%87Lj
zLP_>>f)iP++y#N|O2Ym`9z4;wV*7Q$?kWCLCO7=A(GCNey)2j8{Jku6<55AO(O10{
zEL8c=SLB(}(&f`TwVx9_3Zqe~?jSwDnj=pNgRxARdbrKm-A^jNh$xKkZD(uuk;7j+
z(R)&P)N~*ElFS~Ut{->g=Je7;K7+}hZ;;5q?C&!MwyGq~VVR1WR
z@MMAiY|Z79a=;39ZRIkY^6
zyNk@SY>IH3VIpE2huxRK=_}83`YNFIq59`~dOB;S%X6y;
zRk0L~``xP7c;-$Sk2%EMpuP{K2n9zDx?_6$oq*y%0M+>JJTfg-{K`Ot8V
z=moI<>sOgkL!M%+7ai_NPre7QI!|EBP+__IGHLM)7<$$($-Y3{NOv!!#iFvncD9uM
z{FUnLB?|>nR~QWlOXus&r#7sn>pFZm{djO$!uvQ6zZzFyJ7dqbxmJ)f;2wV<%*3+$
zdflDY6yI-ga|4%GmfRozf)baNRWKrvhNU3-*3ygmJKt5XZp13EdZ-Y+iL}1+Tp_Vv
ziJHZxo6{PninK^6R4I{#1LUP5;YlA5?ak^2O1dAZ^W@nWO^uTB$M5%v6BMY1dhFT7
z8Mzg1=k^T|RTIs}P2_M45&!h5#tDfzd5)zErFl=g79C*a%!Q}+ji2v<@a>1+dMi0g
zshuMB&N(Mu`dBf$-_eAo)w7wlQTpE*>?mCJI>w_G%tp2+?l>7aRo2uSd)08(
zB-+o9ZH^Z>HQ7V$*ByDszkdwTylfy-g&K3{MU{Wiwrd(x&4PNzyUN;)1{_^KVmul>
z(tMWtIe|x6M6FKU5A2%Znv|WG-DLL0?4?=$_a`l6cwH5??lfZYtMTFS^zlh-@yZoS
z1WH`APb8Llqfal`j>C_xU*un09+z(c1uf_z=&b2W1wV<@yG7H_&?kyyTGmhRS6iN{
z%)bt03t&@IW?~3{5(rg^#0sR_RL}p+eNtW-<56GP>ECjoy6j37sR~j}>7h%uVt-cP
zJ&L9KdV_9sxq$b5pgOfclu?`Hx9vv){BeBA87=}&0$U<=kF*4Ng%{jH7s8$|y1cfm
z?8^O?3mqBr%v^QuqwA9}uzu+FFlSu6#GvGKLU^KQBCd3+3_SaD*4>%N#nE|pdc+yW
zrEu0@+UyJ4Ou($otV>msbJ9%E6!Ff(9bT~yWZ7hQqBO{MJ`#KkR*F&9PiWjw@v#%;hnSUaGDt~x2p`_&@tY+jm
zoqmA3-zD25eAdYi-|yw6?WqZqcajHFoTRa&bWmWxV<{)8re>~|k!In*`J;*B#ACC~
zkcp@tRNDfu!k+c;@UhyBGLr_Sal48C3j)Hj%P=tiiEsnTg0
zS&wAj2RyZXs_|5-Uiqwae~my+!Md|II)lNAEJ=4@gLX^EcW_Gg^;q{=H|gu7-0hEf
zPZE}gJglH)On$sGoW=~#m~ozqJ}R-=h0b(pCSCbRdIWEu^&V&~n=aWxYr0043%mAW
zfTXm9K2XOtPIZjtMagGqHK=Pyk
z6KGHm`BM3!A0gs;2`-EuAz)x52|I$BW=-ECxtT)Tr06`1H@sCEUCM2=_rdpkEU7VJNK$-zx*|Q~<2d}-=PqSKm1Cs=G8g(PP+56}Yy%%$kxpM}{
zaD-*3OsGxhLVO-=6j3#C=k?omGcZ$rxRK@4MXfLUM$JatUj}Sp;461Br@`8W?zy7|
zZaCK(cjlzgO|$ACX`9d!#6oOVoZ&504NHLRvfT13MPgq&FEtPvhQjzRpXZ-9=R5a7%W})=YG1jPlvI7@T+p1$hFonV<}sE50#JG_qwaRo
zgRrK~CUIZrjnv=_+!u=h#O#0IH3JhN
zQ(|%!TM7Aea=XM_n5lr7r%Zm+cH(%9cuRs#hi)b*UTS3I=cNCcVWGL7P@0fF)3`(<
zf@XE9-3kXvoOCLzmfoago$WuzU$eT~LB{MF%Y2@m|^ZV%I*H>1#bM%*mULE+&5Le1^=S95)hnLiTx1pP?>Cq{Cb1nVSLCq3X!9QeYRyNMS6@
z7fcUP2yGAnN${~OK5htC#wHOKWW#wO()2@&^*WY#bKMhm&b_eku={)E;RFbd(q>+=
zSPrb33SEZf=>aT;7Xyt1O!JoIqU{{G*kc1O^+gIPi)+Qzimyaiiqu1c@v3+kIvmdzx_X4`^VY1avyO1k;V~4AH$N>l~+|of9hI!+Ss^y
z*}Hi&&3>0h7ZAFu7`$I{yExebrMi#w(r
zEJ=THbkfDf+mglK#o5(M++XU>uQSBaX-qNi9hP6Gcsohmd8(n!BJbvD!y?SX$HR9=
znuvvkMbgvSR$NCx>5uB@oYWnAZ*O;TUS2;xKOR2;9yd=r-bZ3$V!V9(y!`y!=rg#z
z0$jZ<{kdJe*nT(ik9HJnysSJO+`S##Tv;&fT0VF4@s_%C2h-7?uiw{ch?4tNHY=
znveLz`2Jq?Z-@Tps`_3wp7L%k=svxr|N6fEsQmYXe^iv@#oYSehT``)|0+cfv^0?<
z@1I|qG?9J3@NM+>$l#!$rHB4R&oaylI}`oy{_jt8`dSI=p@vZy7M2W_s)DSZKlXM@
zP=&3LK1aQqt&Y~%gPcQK>icd%xeq$YUb)`Nf5GHkP$O%C?Ne}FZdQ98oc&su&ZKQ}
zYPgnhxJ$4VJ80YCvGWrKd07P}y6{i)hw0j~pRUFBXBfR8-^>cwD}^GXFpH!Z9hyeO*)4J!AVFbV=guUg?Q+e13+#PlM~StJtHFA_{#^b{LDU;ogZRV80G
zq}hbqh9B*30b*UYLq1V90*WC$kq2LjG9FZN$^R#G#vdy5>9(MU_BZEXfzIff!3$f>X4pd8aHbvHvCQWC`4otsK>a1vXZdPPGX
zT1b|IF&-)DIX^kh%B?E#9635(IABF!i+79MP~6hFh<{A&hs6uowX*oGKv@Q@0!#8N7x_hHDK1EDa8N`OKO}*KTFldmRp>-nNj{eZJ8Hpo(N$8^4}gRZql>(!qp)-LMvWVlP22yU>*GXvZ6Rh
z0KDC}O9tWP0^Y^dH)lH+HN;RW=*xmFf`Qvqtm1`d4_{>%F~uzwt}Fdbv2%H(L@lM3QS~1D3GJFgv_3CyFu%Kzb++
zTVw+d5nj_UfL;W`hl4J!$`Q2X&0kn^n4r=no{oF(@G1S=4PygZu$Smv`+iF|LXEHy
z0RfbJ;1uW>rrLcFrSrow8P06C7?#3U5XLXeJcpT#J?E)-j|U;bxAv=F!}ml3c%HUr
z(!H&0`%#-`cV)yW>S6@6I^cRLr*YlJnXjIE!w8r{q-ip-@KlmGMO#;vmY&3w-+Abv
z+*yZ!t0f)RXH}sfUJ;#;wivUX7Wv!aJM)!4ZBBY=&xRz_X0l&VIGVZJ1`lB6bHKsJ
zsmm~!Q@j`Q;A1;`TqbHOEgbf+c?CW6kQ|acPXBk4%#z}V7kw~F0|u;st9O&&0F*pj
z!3?zXlLuZYnkP&b*zc+`IO^BQOo%!UdOzW-_PZ>|`eZoq
za!QWtJ-sFQ&6zLlaXW>9HjL4amyg35C{JW^q#ia~2M@>(d|tVKx42RD&-2vQ%;BK(
z)aM{N!dE(@^3U7m2!cKgW#2NZLJE=_0d+`p*mATT16BU2Facg;-O`Gcb-a7?u?Bg}
zbuYH$lJSdG8+`{9LPCb3&K5RS;0WM012o}2&7VCC4*40sF<
zb+;KM`bPV(e+w3cxbQk0rvV3d!Dm0uCuT^l6wUW%OitXTW-je+gPoSU!D|Bx-`tR{Z4{#LDu`hV>wTn|1UEeGJZfO9?Y&lh?to
zOswe``293FhR}1H);62gv(z0~Q{L5`R+0^#F;c&D#(sz`sj~3Z2UjF-IIQgfSs1;B
zemLa~>*UQB^i^Jl;{lAgBI(6=YYnGdR7TP{j5n@_m4%6d~#vVI*jh}zPrWZ
z<>5b+bjK|saHsRce?)H2>HC=Bwi&39O@_l)jy1}FFPzeBjpzrA%T0huuak(!-(=(%Vi}()A9(mxP&qu|
z9xr-NL_FbMIs1|WTGq0|>%aLV&fvJFCgA$}34)Ux^OJ)&7@0_qSPV6#-F>cX7bzMf
z6RxKT5ymu6if$ewo{*2r4FZI3k}V^?$O7o(_bS?cOy&SgV6+u-T`5O>%}0q^St{*u
zp3#YoBU{-4K?}2)*bnpEWFPT|t^u}^@DxvTdFXh=kltpn^Qd07b)cr4WPtZfJ8eO&
z$^P1J;UwqLn{{wA(uX&;A0sX1j+SM5td5BRfET*^zgl~J3JgF6Ey9>rs91C2)gMum
zIOV=noea5HX4j{?g)5*yF;_qny%K|G+XX}PB}r(@b{}&%UcY{=CArNd_GO|}v4!oG
z4f^lkx=JD>6F4UsLpYKqN#d$Y;=g$_Jf<;Rke|Rdnx$Uj5k(Ibse0!tLC*h%d6~JR
zvFLp68TML|TGm*hXIN#tvei`(B`xEKr{m1dmv@mNrwfMCM{VRi)Zg7ZNLQyStvvBR
zTt;fOflP$Wd>W-dfY#k1bBp7o3VP4cuS5V|J5Hn=X;zuU$b&k{1QmqnyVTJU)N?4wSOcO{=&AMe)}EPg*JywN-g^WN2^Em~mvUIp
z3J8K#rbz&wexxqUg`E-h0o&n+kR%mlh9AkZy-jatsDM37CkiFK|MGAp!|k)nR)X+u
z-LoVe!8hvsj#nT9YEuNyqa!J&_dbe8Ey~5;tfgAl>=F+PZ
z3htYSh(06GH+>@YPh6wep2&FseDCr*3h4=72&vM<5tWhkd<`FdX4Z($D$X-xeY&t!;Kf?&k652PaCd
zqg#A>mp`&=i`trYgH1Z{95c*dXK!hWBhyn^r7~-ap1?Pr>24>CwsNu(?J#V$l254y
zPTmY+tK0ISDGqVhnyq+p8wP&vw!+>*CSOCo>p-6{-}F~Q?@LjiNsM0}D^g3@vm2Nj
zN0N?3wj?s4YuX`tGKa~+VCcq{1ykQqC=&CzjLx-QJ~-)eFn{E(m8zoq(KXypqf*2c
zp~^jutC-XCtr5n$eYeFaw&nHgu{g=NbbX=A)Tg+0tx6HkWV5K88T`}ggs$CZt!0)t
zH5%o1!H?Cmfld7O*C%cp9eqf98sb1JtWAF+9{A~`E$e{8OG$!2+8lFprUr61sefD@
zv8?oH72vZraRu_0I~5Q*a!Rq3nJ0MEewIM;sbA(siY7Q)*ndph=+E(RrWaap1$F^^
zHuV}do{03AcP*T@lD}1!KBNp=^%8me2pLOMAuW~1@P;%9r&BqPX(64zS9tpF`nz)Q
zDkYo8CvZBKwD(UFAX>s!oIbG<-mi81QL4XUe;OQ
z_koJIyn{~LC}B}A6#PurW(d;3kNkr4LPR~_S%+kz;E2?9R5NmvB%R2imKI$;4+`^6{&y!6DolXj}QZu4(VUi2zhYT)O;chsI~B(6AKjZW~Qy35HvO(
zi=?Z2TUJ))dDuxfT{l{Ip408&1G*}rm{4poO#0VYVQ>AoGu=4*Z0g5wewIe
zg&8NR00}><+lw{XAnv|^U6h+sR$IEUKp}bUt88T11*A9K>JjUxOq3_Gqe;$qn7{WN
zfXS}zEehMvcf-M$^E8<>=Kt#shq7lt2Q&Jc=Hl2xK=)kDyR~4
z?8X+ZlM}F*i6vXb&BGn_9un__#hoepVY7Md`i{w1q^a7y*~a6SCtX5VRRRQhS(D8l
zLeS5lQ<1evo%GQ6dOR6lyqCrB^xM^LPv||l-#Kqh;Lp%cVs-z%xUds$NBPhBZ(Qat
zWP+CIu%>BoiwB*|hFTR}x@+{R%1oH;-Ar*4kiOU^xu(A^#B0BhE4*UNIXzKEUM=z&8Vw+g?l1gsQ<0G96J^%LTRk_JjXT?r4WT5OEtEl%ryBM3?F61s{8vQ2G17SHK
zbsw6N_&e~VqoR
zBfL->nc{g+TC%5CmmRYwxvYD3T-j|qBn>Fv;Z?6F64^jzceoHPbDlq5oq#n`0Ck*u
zTd3p4t!sbp26JPn$5D&VZ?NHxFpvqF%MWsEONP(VdLmZO`VJ<^(N@84THq#Wk!Ik!N;4
zWxLs1*dj`-x5lVjxbzn&J&TsMcH@VY;ua2KCo532U;#ecpz5*Apx5Vs{bh6Vb^mJR
zIKcj`^#j;4@GA^xgvxyBQJs_`zSh!x0A2<_Q7>DOlZ%pxC&Nqlq2I*N0>SzjPQWufUTjDs$A7WQ-Wz4A6{-BN$cX+`Nf41lszp?IhF54Zs
z<37)}{eyK5I4!@;{D3Gche_-4W1p(MeFjvcfI(>kDl=9RX+UATUHsU%3eyq7@97{)
z45f=V=UqNT>xpzae_g%L2?ZviIy_Liann40o{071z5HgR`RP@iG{MH8xwxfCLf?_g
zOvJJdk93NeEInU}OZoIkpzX1`
zda3|&0zHY3I|*kZ5~^x^iW#8c6tkK*QRp4izsI#Uq$bPdE66Hs;DYe0K#A4!8%a}H
zqaU#2#<}nzNUmp9x~?!1y6&q&>uLPtllvS#b#vb&GbUbWGcJ61*$=RJ2xnf;G+-=y
zOPB7?!M+$bFGfn&eSy(im4$|s6gpkzumfysG}M=K#56yZF2sk5qWZV;%
z(BkjWk*hfdn_YuG`*fEpm45iscdw)()99mn4P
z$%rwPX!o)kdMXf`C#0$SJzGKq=?OKYEKNLBKk7{8@iT6Ndw9*g>Ja7Y{y{#sng|0d
zc!dFlB2z|>s>TKe=n2PLI=kW|GcSP+aPUFVj9f#`&rc-SUy%1z#gJ(8Rt9IHDhJ+&NYwJ?#i5M)pHzSDB
zpnxRc1cW5fQgZdo&F{kJV*hz}>fd=MBr+Id?OIgTr7@v-oO*iUhaNS0L@avy!oGBZ
zasfEsQ_FOM=9iAU02>)ke${x9oyiL~WwX}{YrgLEPW#Df&Qwt%tH|}=IQUR~
zY5kS(m-}?VSvk7-ucz3_+7`5v{}!QC=Y8WMT%n?&Txl5~6Zyp7?bIWcmOKI0f^Apuj`xDJ5ws
zntPec!2V&@_bALp1UpZ1WI-H9DJu>FGjI0E4Wg_PRuEcZw0MaLj7*A+_O}xJmp&IT
z0EG_^FSaPmfuDbA3TK6h;vj#$@t2%F(IyC3*|C5)y4sWnkTzQcLA8q%6!e?OadQy
z0uT=<-$qCxKSi^UFP$g($&}1bHbY%+PiH~_TL378{wC?#nH%tU(&&{}@+q?pD}VlG
zGv}y%pZXx=4e>z2O0lg%rHR^-{X2M)+T(D152VrMmB_u95GEzX-0Luu%vkHOytJkqzB
zKxfV$4s7cS9*3qC5n@93t-{+}RACoi^xS8vkX=hg6%pw~y;BzMCL>>vT(>f7OCgp1
z#WtAfc@#^5+|M>y(bk)P=Zprg$$IAQxrUy5L$5T0{DcB&&4#U{9CgA=`|TcBz;+Ek*0*$@$JHh&?Ta
zw0?V1UW)U?q1lX2q@C%0wcV>!eA)#v++(i`Jygjfx@%ieccd>`Dbfy_ItEmOKv0z2
zA(`eHM9mNVRvCowE49nC{hS8FfwPS*Po}uhB=uYw{sZ;)#tr@Xf6!6^RC-w{#8}9f
zv5M@~NUYswAU%<2hpyRsT%e|ATv5K0;vf8e`glK`F)8qs84?Yr?M^R2g
z(SuJHrQ>;-2Xg!(_C3=>AN#@ULxl=lD`RR+qMT4J_@`J6C>nSG;>zw$WR=4!{`!@|
zw6n{s&YpApW5EIkTL*^$^!Dcj?qP7uzt#Jr_dvM^?RtR`r&rEXdE~d5Tr(fwt7RCV
zVJ)VRCoxM{JMxiW6Y}Zl)#*yfBOi&CMV#gHg1y@LLjuAk0T(lqqF%}ODNAnwwwP(V
z;Q;p>uY&XH#$JvKp@y*N!fh#-S&ssDF&dPU>HsTW4
zR(~$LJ}{g|kgj(36pr9G&QYmWr?O~z?1wFBoy};X@p>+-8Cj@4wdg+WLD3NVPekf5
zXn~?mD}v?D-CFBA@2b=pq+0SfBC%LFJS=s3`8|$~QVQs=y-=u#vFFXk^9e
z4q?J5!aIztwaeYOYG!A{jF!QX^sY6v_(3P{M=9$A>fRf^a7esPuV!{)hqk}}T=!a~
zVx>PCrwOHK-yAkC?p~c7X=X_OcC-3HZGV
zQ<(OMXYH0nI$L|!o76c}Ch!xrC$c8z#l|f*MJS=5O3jHAoQQ8=*uts@?Muc0L^EKd
z^Zk{x(KKuU#j#xd5EmD8lR{z7^ed85Gl3W9>j(~H-rS`L@55Py5X~St;OGbN+UwDD
z5z6YosqxkHa^!*M(Xe^x>O(VK6Uzi{osW=XyY)d=pE$Xf^!
z?`l8=Ajmh)U>EBo7IX4zXQ#B?=e#gr)bWM#7Q-^rh#@c=EgY5u5pLisi-yZdl+lCr
z-NNT3K8BDR^0!UAlVpS&8>Vui*u2ks*aI}HG!DBT1=1WMzz>y~4?1yxsMpI$0xtsa
zb-sl8Btnjp04oOf4#}ninAzAi$n&1a^2y_3h_p(!y~Q1#
zzvVyEK}uIwVyFaf9>jn&GW>ZJgCS3*bkHE0?7tz1{@()PyZsg}25c@z>w0QVC=d6K
zMF2-2WtNc$gCi}Zy)lY_O-m}ek6cxl>7d?oo*1e7Q$T_Lo6L{Fn|zfEpswp}B$T*y
z5Af~;uTZUn3Qf84mQ;{vz1;ihY??oG&IDk~+C`vBEUBI0S
z;$QSNhr%hcy;G$rb2G|KU{5K^$U2ad@?O|?P9fPTXiittUHJ68T#)$P$MF%zNQbss
ztu9pinpVGyIqoppQpSWTMfGTJKm+qv(AvAs`s+;8eOk4Tb_TjaZlB6Bf#lohWq@(-
z!D;hB(@&M9#V9b#&nE;4q|$Yp)31^wxINFNp90=#W;$h`7JF_N@ZRu)j5rPp1-GSO
z^!Y&m4c%>)*{3%YN_cx3V-dV0hEIt8Xb^-p9PdweAEcr$a3Mbf
zxO<+p$GeU^^jkFxhid}p*iz>t^7iE^44i}cL9gOHy{;vgWnY}FzjXp%%8&28s@WCK
zmEK&U3Aobe>Arw?AH(jwKQ6QiMKAO7;UJ#jw`aoF$I`w=Fx>!J^b282nH;HFxgGj%
z>$Eg^8JA>pU*uJa1k45M+||kxMkAo=ZDb6^s*`z{vaE*wjk1;=D>fSKyQ8cg(UFVL)?Mr>J^bGtk+;+|XbNu^YE)-BU+
z{nf#vO2UwzwkN
z4z*&Q&{owff;L7S<5pFJ)qDrZgF)$EKCveCmKXBsY#Q}-;|1fitNHF|UB+a7I^R99
zyRt!ERUSc|M4C>&u`vlPm@}amfS%{-im%~G@g($Ic!(FQ&DM5w!JrvIN5^muwEH;>
zpip_k@#}4p#Z^bg*6x_}J)U*c6(6z|5E9g|?z5oBJ8v&Jq*uz@vBJg~d%i-`r#J9W
zx~loUZNdV#=MFLI3!;=K$iHXV%}zuky6g+`RQ_rmv95H#4ZT;4qIa^dr3S6v1T5rp
z@n65h9zE?4f3$TweBWba!f-o(Kqae1i0>wCsxXo^P`TUoN}+qBZ1fP`Aa1d__6jY+
zf_4CVHdBfto~ZLMp(Kbk%T478U?Px?_Gqu7A7#3n)9HomI|mavzR}%rW1?q}`}5U>`F&*(RM3Vp
zH*UbNrW6I-*+$P}?byu>Z5{&_4FZ3gZR%-1&`-=`oeIch684Y&=PbUiZem12P7|sX
z(V1-wllFu;loH4BmR2Sg(N@R93MIkUfeNql`vGVBS&S|q?zwDzGaRmsPZ^ImIFkeGK(QshK6Iw_!28sri`kR5<|F&_YOpp
z0Im!B`|`R`%?`%%;wx!h>Ik)9RNcwt9@^GeCeuDxHBP_DM&;&7%AK_)qTS@tShMw2
z<{+|<8R)d-EEe!ww<|69&Wh-F$|WX_X?A*1!AoA~)Q*8fU<1lf4sGULPg>L&C+Cq$Fh7PxUvA0kZrTFoi
z?Om@8-ln69h)`OkRy=txJTN$5)8Z?BJRL(&`|LDDI`FjnhtEN>cnX7URRN)hDv7ix`4
z$Z@vn9k}rFjw0<4#x`j{&g-gSW^Sgr2N*U9^(wphYyuoF&h)C;G!_n4>^bLM#{|M`
zdLnv`;GhA(y7WP|=K?)M7l12AF1{ig9ZVF#ua(S%vH|B00=E|mP>DY$pKmsIi|kKc
zEgQc3C?cgVGBGhz@5^e?@ei*6v<4zXe!Rj(#E(a)l*}E~4My|(oj>?J_`oFl1&few
zXc^O&nB6n8wexyhrlDx0LK@rq`3`P#B-%*zfWRkV-PGLqah0V-eb3j!C^^QE-=ITAFro5eOSBI
zPB6}gVZ}tZaYHCrm(}<|4gG-pjwHA-r@R@L<)?eD_-Nv7eZ?x3qRYQ>mhAl0kp#`1
z{~+O*a+MwFR%APSIzw%iWN7vcfC?H)Lzy>Zbxvmw3U`_=C*06G%cihY^^{qP^Wt)X
zi>hn2h>XzBQ+GdHZ6&;HR@6R~aE8bP>7lf`GJGzWroFCm~9U-*fH=o04
z(wy+ySF>{{K@x9f^hlTRF&zEZxe^2!moRtfq`=WZeasoXuZL^#OLV{e%=?_EEdX``z
z*@j0XjsXgJR@-9VeTi|8QL`agT_iEWKyN4+KkmPQ+h}=gGA?wCL`{z%?-X0aTz+3R
z*3Ml*e!_fW;riIZ$uxON6YxsnaljAh2IbW)H$z2Z*P{ooNgJo0H;Eq$6)Pv2>3%+M
z1V2z_KF>2w`E2vMqB(aai}5X?n*@2$zgk;R9AEf@isyJil}lS($A%vn$IoHC_O;Jl
zA}`lSZA~_-Q~GFCP1AsVM{4R%EbeEyHD(~zTC_*dpm*S7*Jb}Pf2TG_XdBqIP7*)O
z#GP`C$B!ZpL^$w6os&{heC5+n{U~ez%KFL+uWMM^*m+C@gds|aD4d|HklkgV>F!k-
z@QLr>yga$&&uh)0Qc4h#j?-H{mM;hwX{2z^H<@{%OjqBY2USd>=&-ZcEQlw$sNVi2
za+06U?a(XdFNoeySH7G{l3ZvlTs<%OVTkrUuKwNfDTPt}nhtIc03AHuSvj;!E5j19}l!K?FVh3^_z7)4CTnJ={S+Le}y7THFE@rwht^_BC(-Q$K?D
z!(U$*fdav@r}QF{wWjcG!?zzrq+^1kmXT~*sNT=0hgWA9uPf$=dP4mh3{G5*R6H}L
z)e7dI&*Ao->EVg3beMFiy{GXj6T877*!tn5afm@jgsMfIAvmnE(bS1|>12#;{A-)KU
z$g&m`8<15tC(Y$mnN<7drOVpUqAOZo_X~8$%t)mR0OhwAX^I{vvJ0%{evi&+jU1CHQ
ziufhLgIog5IYUfKrTLC~+J|3~zS;Q-`jI#yAc>bO-R=8-m*D6969_(bDD+7PQZ7U<
ziNMOomuxkp)O_xF8KLC+Go-|06SS@IQlXnEpa>&x^p@{Met5>q?oY0~27vQ=
znN2K&rvp!EY~yy(s{=Z`WO%tMV>&CJ}EAO%#)E
zmZ@{BL&7%&Ey)d!sGDF7okXWv0z5ogM0i{uBN*7aj*D_6;V#^;DayzYxltSxlW;pg
z^c3Z}4p`Q$dF3fT{Dk(J?bVYvo(RUSa}mt4nu$8w#2J-h4-wE)#>h*Ity_DUC@&=J
z+`Ir4*Z{N{_~mYl&)Tsu0uxN%t6)0IN{xJAG}mSc&{GkpD3N%!13yDB<|lJ#?O&$<
zlqG24s%aI~AAP|Xp;xl=IgON|{)#!#aQ@pIa1bl;p|u8?p2{*~^95{qVZiX1qU0-f
zWdAZRt&BL!7vux(3qda$txE(##MzD8YY
z=is_H%-L8I7&uJ0e
zJ?JRo%i}XE2LM|=USgVED}mP4+(BAD=Kb^Nj$@Tlz*
zkMZT+7ki4T*C7|xMSDYAOp}T11!}h-Ej6{MbJO|zCd?yOsci1FXm5-MIB7tHY>OrV
zm-EVSxN5r?vWtN+?A(yde*)$2`~_JgXuX0V_-MIb5|!X(osGKBu?Va66#rJEtFLlK
zRSG5ce)JHA4vsbgh7^@qBGCRcXfNNhLNjB8>9EgMer{Q5{#d2?03Em7;Y0Sr59wsm
zhuY8g$4){1!kMe=YNz
zv#7lCp2nvAG+6{&k85{Kc7P(A#Nx&DAT$=t=#cSu(_!)joUA!eV@ln`@iMRR{G3!|KkFl;1-}!?MWv~6J
zu|`?~r#IVMiAk-zlSsSZ0hzT09&_jTTw!%vw6`?C8V+!jKtH{}OT8D=IFCQ}V0@PQ
z&iAyRp{(37Uev%r)N!XDAq-aeazB|!%je_O%?LVpr8
zccTkTn3G1HOc3+@1Fux!p$0_4^1C!-d_Rh4H%PxPa
zp~kF`iw+@s1-nvr=C0JFwIK;Pe=!X}ep7%cgig0^N@2FFqXtzQ9`s@k7=JE_L<(5S
zPgl#)nx1&tEUh5I1L;Nuzf@OaoPBCw)?_s!L^kfLXCGJgPcOYN(eS-rKQBUG^FN)b
z`1O+jnZVmnP5S#CG`(=GY~TePv(|8!ClvYICugRCsrl74zEf7YzwQ8^N$*@r7?4hK
z)5^04Xt@n@$R%#cQ%<{lm*R@@MwK5egD)Y10@{mqS5`;7cZ&?jW5UHzHdnk1#?psI
zC?iz2Og8E@A%_<-d72IL#113)z;`~0c0M}pePFwrW0|rJ7M@g3ehY`mf`JnuC>QgD
z*S$r@!^J94y^?$b8GaRxV3!hflyljFg?sG36Vv>9N<63_6J#EnCP`23ie5LxJuXA|RB;Az&>qZ;9&R;pt8@Ji>x&A?gRd6#@{>pW$n!bPgmkR);^MB|N
z@UIU47~ubGNZ+I56826KDHJM`9=eN~oxxcm4rpELa>zLG(LX_RTZD<)iS4T(6caOj
zDS%89ID$7E#(+pK97zBKi+&MfE-lwiz)2*DHlemWKx6DTm%M3%=g`O4qr{wwTex(2#+R6w>oxm|%9VR)ijd^U3I&tCVgQN@
zSQJDXR~MI;p+mN-l`6h)UZVZN>=ya~B07sZE`pH%a#Ogc#*o^22Lt{#usc0m8ZM@w{U&-CAohSzW-mF
zFD|=6W@OK}E0_od&qZ6%pNypQyqHL3F`h1zW#^VF-6XFKxdGhjN82jUrn01KYG8ul
zfypvEu4scOOVn0Q1J>)yB&t9rV6OrOtTo;@Yvh@j&K;l?cH7)mP3Aangh=j66V|k%
zar*i~KX76pcv_iR@(-4(}s$~c|y4|$oSaUbpKn%5paH?76w0ZATto88I#FK0k{37Zz3N1Lz
zx3J|=o0O=?4Nf?GQnget=C+J}mc{bzdsz(jV!)1Pm)pXVCG&)w+lAj%_6UsV=AV(x
zllcwpWXa-OI-&xsc_>~kdw!g9iA@7O+A52Q4?0SclrB%C1J_nDB!?7?C_?AK3nB^kp6Y8mb>yjt(c)C9GmvcXwoA1i#
zDsp|Foz$(;>gOvL3qPd8!0(MeId#C4v4e=iHkuk|-|V3((zsCgALP9UP*Y#qFRFq9
zQWXK|pduXv1f)iqsE9$T)Tn?+M?gA>2!eewjc5Tq$Q>YxL=P;LlwFq@Jf`WNZKE^C&a&w<{{T|=q~#z
zU$L`VtxkybUOE>qJ=y#_?agby>34$pKdyfMGFvD$za&RCEcW*wl((KXem
za>d2=`fpw~yRA~=K
zc=(J}2=-#)iD=5CeK;c{qJ3H}&V1afKsf(}8z}e&v091c3am%Z){O4`F)JwF4#-+?~l{gS!(1OKQZr8lIF9D(b
zLnm}^tVpO=xK9xsY^KsFYsAm_&iA&6?tpUdzcgosJOF&@vBOr^-zZC2gT9q+*5$0*
zE%|H9pNihbF}N-lw5)N_IJUU4zKx#kkQ=|b>2=}#bLT}Q$bEL3fJS7_t4c$VC8vEH
zHz3ekm(xA;K$dOVZ0D~~j&
zgN-$SMOA|Lw0}fq9Fjg-qqe_Hfr_06-a)xnSbe1v=9x6&A?R35M#aZTPh9fLgwfg8
z<&^QvG@zzl$?G_LDo<(bJ4bBRn|x&*i`B^%eNZ|NYG9{EZ>F#Xy96&^KFsXwJ<1GA
z-H&t$%D9*$)-umzTL`NwlLxvJmkS)5g^{Jsd6L2hWAf_?7#|)<#s>Z};R&Bymq$W85
z8tr9oRjhYTJjBB(jnMqOzy?@QPKhlkx8Of0He57_*S#PkAZh!Pf$N1S!_W
zZ+y*LoyKJ?9z0x~wVmbSLoMRUfs|0^c*L@xqal800yDjhA|cVWQh4$NR|@yq<)pB-
z(z(S8dy)Z@f-NN>tB@n(ECp$!(-%qxQP?HJcnK7~uP#+KDT-Uj%8BqJs4)a{7>XcH
zLJkn!>NIBr{pTH?wvb^hP2}!)>NCp4`>vArSsX}DN-tj&o3GG8(yLhC&;A7pYoZet
z1N6J`RD%<%orfH4AC-)n9@mncLV9m5!|0~Nzar`#_C;3DPRck9cnbaX;oGl^+=IqJ
z8Vr3#-x@-$x8lh8h`v!Dey2_miNE>FWtyT)%yG3hy1XSBuVXQM;QO+Z9hTw4@nEyU
z03zod;Wp4^*2ze5taVGm(Vr_PHdv(PXCR`!vc8~fChs8wp!EQyTy{nf&P(|?5Z8|L
z|B!rHzjwGxquOSFi7Poj{#bkZ!aR4KM%8%II7kd=q7MGewk)@;jASAvLjjEt#j7m-
zStls!pG+d{8UAYFcWk~GEXp0X`8OMAmhLJNzQoHO2P4X737?a&o%#Z@YBMtg_L`zz
zUN|Kdi-R9H^$rp@y*D1SN^S!`=z6)-qv4SyFD}nf8<9uRcoYJCcstWcb1xNNwH?YG
z%CjVgJ(z)5Q3v9I4E#Y|vtb~xCE5!Ca6rZ*-;?5<6~=!V058vgo+wNj^iu_N!VapT
zALq{*%PFKDzy^g|(QZ;a?NRb>Lf(4p$nyaM2Az}YM?baB3b#J1!m<$+%1&1NTQ;u%
z?_*~xc-mV&zDS8=e!2ZGkp6GVYywuoE_B=B^PPYE1s?rNt8eg+(O~&F1KSn(v4Wr`
zOvS$s_18EsVSf^=;c=eZB~jpN$gw?k%Nk}H#}{4fEa;@%)j@VxhQ}#@>TDq!cgftjQp-Xer?q598)m5YrYU-RpwA6=B^Rh9P%TS7eUl)~CQiarxA^w*0vw
z&YzPek>9--PY`l%dJB$-?7-<87Z?={>u$BHtcf7Q1=bw9PcCvRBNT
zeEBa+!U4=-J~;FBI#bT=;*EbZ8HPm9mF0l!!|lK9!&QD^Lew2wmscz5E=5n||FB>3
zGy2deYORUkc|U&+Zwzwc%=TTyN6a=^nM=+}_VdgfcFc{0e>B+^XKmWv$CBMWMQMPy
zv5_28UAWB(#+Pr2X`XSmAc^2#$h*kI{D(7ZoWEKwj)(PzU7T*%=|A_EmmznMwOjsq
z*JZ5=H2^Ylzm<1>*NR$vw8*viOO3B{M?l~EG6Tq$Xydja7eOei*m&wn
ze6OMMoT(aI{;D>5E`qwPao!K3pKNTC-S^vHU4WP
zP(}Uwcg^PBlZcxi+rpMzyX#N?L&Es02_QWp&yki9W`m(erM~lj;;D7zEzbgr-7~%=
zK{(MFeUqrNx3wFqcX}#CH5+aAAmj>Wnm_M!@uRrATd2m3kmY+*D*m2RH~ieE0*)@P
zp6uOM^7yt*epG)bT`s1Ec+m*oUp}?qIdsPR#@r3!#@SktI|rA$%03|vDO28rPSLv|
z%(@$)35Y4qI_+MetiDHkiVlNk+ZDcN34^L;D&1!)_%z*Y;aQA~;}v|e`653qZurU4
znK$k1=M9Snme~-OA|TxODOO+uKZ)3z^i%#}GQ*|5%h(%5#p__5p~0%nUi-FV5(i;N
z(BSE`WC%40A`ZPoMFK?RFdr@;xLxq6pYPhY-G3g6{t;eBr6$(cqfafD9kgGRO4#Ux
zY&ySFvg+JvLNsCl?SsFGkxq~b(hnqr{e6))_5*DdR(z%)wS;M0v`qf;y3$G80xbLA9{%05rb?m4fRdH(?>r5oAG{bU3A{2W
zb<5+XlJGhLGJ)bNP^Uh(ArLF>3jE7XVzo8;wyiESLcmYGGP5WiN6`rq!mANDxTO3;$cxxvBoH{VeHbd(%(Nec7*jGQxoEVI
zv9hv|1AE9-pWj`YaQ(mw&GEXRj1Y-~rz^j{M<ugpSgOMKIWgA=<_|wYjP{5!T;F1T%THSg^a^p_Q&hr7cqi)+_$#s*UGqNDBv8j})
z0wWHvx_4{Bc(nGY=GU0)Q@g(dQHndR<{Z^ALZ}h?Kq}v=04?0YT5%29bA8;WmL)IabqL}B1-P&?#SvW)U$&6cz
zGnm~tdHl%q&E6rC)FaHUJd&H
z*JsP%KjnF|6jzKEL@T)b;m)LW?(W-dD)!_{vD%c6ek=TZlbYL3E3Tr|T#2dPAlK_2
za_5N4F}&r>WwhvbL3PSaf8V{*$}z78yMeAYkgpXIvM*CM%|)X${t**o8^AD+lQvj;
z8vc@;X#E|dTZC-&hnKF?@rNqD0YA(BuYImL3r-z=$hjxH3#ZzYa-98>h-Qe`1awN{`LpGPHWHR+NPBZyDPI8_-ID257I!^FY(s1
zFX~sxgBci`Y?2wQL%MI>?yv#>ldEOuTey4K>5{oB9pups1HLE2C?$P-lIJ)&Tf@Yo
zg(yDe5e~n5XsRN!O)osIs`Tj7)8{oZRmIts4D3k(|5$oBgxtL#*p~YKjca7qPQOd`
zhxW^Uxa-e;EGQXt9@cwB!|op#)BMA@Nk{a$Od$AtN>w}8V*0U(7vg=FfgZ0)?>ZCjb+h3Uy&qNoR*`{LM~>*KU)D@cC%TJY5norco4S_n~6Wp5QpkQQWU
z71go{IN0Ju&NkQ{uPc!qd8q_C)Uy=GmrEH^vg
z7T22hw)*TxOT>U{JatLVR0BNYz^
z5_dyojyIsyql&+#rzJ#J__IPBCZ7X_tlBFUb&m3*1FH+Q_J-Z0m%_FCZkyc9z%=i?
zQOnjkYMv*@2!&6z?gfZR5X)@*1$cK3qZNfLOAa9(c#{0&TJ{bRDD}lYl)4-HkrakF
z=-*qUfAqMs1V&lIC#E$;d|l~Lh?bi|5Z@q&d{3pIr=IWicz
zv|A6R$<)_VlAy1~%n2tJwkAg{JTwEX4L%WaJULW;vP!&ZgLMr1@M$#t{#4LI6RWY%
z_dY3hBw&{7_$$A+)8>iEmh#YZl=f}J;fE&bP(hvj*C`%jbLY+y{mIJU70?DH?Qi9R
z=ev`Fpy`b3ci|n@e3hF7NBAPhrne8L;#u!PhL7^^^=CRlX{Q&4G)L#otcULe7vsM`4xLm4+cL8DCLKy>2!JucQo;Ti*_V^#kUb
z4MEoxkjE8oDKn97c4q<>2Pr<;^6SB$AM;5A5q}zch`2}n5Zp@PC)_*`bgYzDCLK*8+FX0z^8zgF5=gxc+WfiIg~p?l
z{d+>|FxJ?oa(m_bcc;3K7q5)9V%J|87L)uVzAjRO|CGqlThtYH9@1DWr!|x|IKK#=
z`8IJspusf>d9d2$ZZB~>a#s;#E|okrxIF>u>(NmJut(M2ZEh}+pu+$vC~};X;nna$
zK`Ey@rjgpc>(nOQCHOW>WPF4J0;qfWPqmN+jaP6UeQjm3`enhoQ{Rspf?Qu|71dY8
zI1#UO-KszIr<$n%X`ZFr<7%foa_^M7?+(4<*~2(JpZo#RDg8sb(Fb>Vl|R)ZRIlkT
zt*acryrul+D%}=T+Y9=(K1BKtNWTw=qJU)
z#~M3o<*9DUnYr2%;>j7u)Ry%|R0(;k1YWF8K3?w=y`Lq4+_yxEG-HC+*L!2^2!^i^
zBtw*K%Ub<03!7ZTI7{>8C27z&Ehvg!x;)=cHl&qN<#wIrwf3WtXYmvqv^rBgPf?wW2y2U$Mou^b0n%i^^6M}_$
z(9O1hX?rU7QEj`aQ0qT5ygeileVo)P_pXQ!ab5AxxBNlD`%FadmY&zCL2}zSm&rPT
zD!~=M1Y!ZHea-*B3bK
z_ue1CeBZfqagIyGKHkOJ{Ex>Y9!M9mj~_QL-L~u9lKRM?1}t0hlqxR!aZwm~(L}i1
zko#yrkDej&>;2COor|1vlre!_@QvQwT25a%RWxH~j_q;N5S~7;$maT|y2y2onf6_P
zyzH4;PWf2=-k!kgNsh%UzH<&F&0rpQ)ML}D>dSLsuZa_$6!Xfx;_YQF7%2uTA{$!S
z|9(55ORZ0#Wr3UG;gZqvcye-t`Y)zoAs`*Z=6zX%o}umAdYy@5<6qC7QR9%+AEhA~
z6M>hR;NH>h3p=0QLE9G3PlBn#(LHQBLLNv*^kY>3EIDltB9l7PG*l*afv9341zG~}
zI)a;rs!+EY8#9Zbx7;!ti#GV0Kk;&NGa-?VK@d>Kd=ITRgv+mO;FHiGmfoc{8z-ZQ)F!_q)IOD6bs>5#w=4r#h1#*OIv-%tiic=
z>l&YnR+QT|&LSk5g`dm42qfbs1^=as>+hQq6p44$gWkLGZY@s{GQzAt8-KQHGNbQ?
zQq6cH72}^GOR19On1liZXxjD>OVH?bLtg*c=laAZeMHM|1QDN>CP;ZN$WNMBEo{mp
zllv5!W}kO;^%*K_+^zU}@MilBZRKu*`%Z1$!~uwCs9Tp;0B^!k#``5K8u7xe|9+qeL{aYsL=R(R#Q;Q9+WRy
z%QSWR)kPVqB5+jHTbXgg|KW;>5W!XDkUG(~VkUNYSKao3>((Q2O~7i<0+{jM7>3=u
zA~LO74sjKDZ-4)sqdwygZtjUI8RP2$7C+k~G{^MT`+?kk0HnKNwca4s3SPIr?yP2%
zHhy4k{-ikj+ERzyg(|C#{u1Y16Z-TTt8&jH#bak%svft*0lk4d-&@4t5WcSzvKZNw;=00q
zN?(9@Wd@?6XR~w!LExf#Ls16EyGIu~mQ06gD?&osW$dlUvAhD-W$**mVcBo$VQ+45
z)$WwE*TIiw%>cK71TI~+G+zPfUYGSv=-hn}2QRN#Zy^I4&5VBwR9*cJ0P`WU_cFsI
zBm^&9Fg>Xqo_G0v3HzYY%SVr+)R#*A==7p|Z+8*e-{t+GH~gZIE8Tz3*Y}7;+;m97
zDC3pVlCUGkH=fbA#yQ_!fv7=BphC>gE#bZ8^?9}ReXvSZAXuadhXjjM&4NX$f%-A-pL~qei8c(D>K~RYUuV~kQulT-rAp)J5i;^!cfSq*
zslC7ikXmi=jOx7Wxtm5`L$22Sm04hN|NOCI@UkD(87G+TyWjajasY)BAP1=Iw+enj
zwr1wK-n(mh+%@_NQ!~0Rh{52K=-u9P4xt?n=JC~zy9}6FC|tb61!<>BL>=oL5I-54
z6C-V8(Jyiz%>u^@TUAlncYk$2MZ7|r>S;JCx6{?AvRA0&q^x~*!lmJANyjSJFZT{d
z8BJI9imTEQotfXW<|mz?!*3ANe?*;lRE>8aXRktPh3RCm=yHlUbxhQTo83@Sjg9u{
zbEsudkL)Cr^0sl`d*S|Z)3${sq#9UNR8FCk=XG%GmK!GA@b%k>Q|3#lgH`LttDK~5
z`6B~%3A{2pox|FfydMvLm^7Unq1oc(v5E1cK(_aC6l%q%cZ2G
zex3_`ddP_V0;X{XOUqKX1E~JVtmG)xK)grQ~4;mY;cMYIEalE3L
zUVt2uS#t{?594JA&%KEqO+`opE9A*#MCR)AypI%eOl6^BEwN|-vd_a@|HrqJ=)Zqd
z)YofEsNSd!(0*BNzse|bP^S}D|MXhm!dRLAJVAi
zLV}Akse3RnR~T7Ag|mKj`EP3X70#}h?L!=}u2Tqi+
zDrm^&`m#oDlf7kIzfLDR4U8DTv*7|92#?Di%e)AW1a}_(moDcY!
zViFMrO?*KdHu_WUxHW^A%8K$I?#4+apTv(nV8m%qM9iQFA1J@?|Y
z+s{J0)XoGRw)m(zsa@=JZ@=!XF^&p`wBG6;)-kBg+zwcxmiHBrx38nR-!z<3`ePi(
z8Q@ARdj5WocU`qZpsQCfi=frU!}54DnW1?-lVqDl(w
zd~P%^-#R9CG;UtaY^`x$K{RKEutHLHPMqw?7|++u)|wgv2v!GopeB1iU%8vd-sL?O
zy)7NNaD(Z+#j0Lj(H7j*60vl$mKXk+!t@(i^tI>GyVf3nN9BE5cH-Ht$RRVJx)#=(
zKN5%7if>lNn13QX8C}zFl@$DjCIyk4_E0;?xU@npa$_}i
zn5_Be5p^>>Qn7aW@9ke2D-{%~gFB+V6%wkr_gSFg(*pjX?r~Jy1XR
zLqwHN_9hqb4%ET2yw5y&yYGw|?@k^)bl0Py`ygN9pyK`{5TmRaZzn<0a167PP`g1h
zgbPLWA`h{X-|@M&?-2MpV1kvz6}nbw6GGnq#ir;nw`{!^A5eSbsRaD;+7KP*Y@&Vy
zh2lS;_EIb(0n35s*F9gn+;>;)N!Pr9*ok3Hg%C#}GKcVudAxW~d>3w&frWa$zlA~q
z*PohqvZ(>X(sjvPbNIX}C$xYMzXW~RF91Q#he&LP;MDpw4(Cl;c3#V-ifaC00P)KD
z`q`lMQtS+hGQ*+qa5gUc&HcgLClwhr7>fdWgl~E_y~@pP#@5bp`$k=A>FJ$B=RMfs
z@B+;KPo^X5d&@l(7W1qBwwA{tTEYE@FpP&*6~&^IfFYvu(FMI8;Yh8Ldva~5N{Xh2xs%
z^S>CBvnO7Gh(7ZfVkp0v?AYCUig&}-#+_^7(~
zikQ|(zv43=wA7xmhbvb6c$#v@=+&tWQ|4>oe*IU^xIPLSkVwj*J^kwoc#h2vhD;Mb
zPGy)~)nYhXVWRkhX<9Dh;@AJqS!qSYe%v2Fq42EB?McNM&R<{U8SWar%ql+lbSQ4B
z{SmWNg{9;9~W;Fdd{MFI_r(BS^{p2b`7<(N?`*5ekTTSL>(>Ld4at*S+g=^^^J8a1X
z$uc75{mlX2m1&{U0L&rTC0!t(K`BP6hhOLKG3`g
zgP0W6{(bI(zWhxNd6o_9hK~|zbZ2~j$eNzzraO?fHB8B(p*ibBlPugt#9fPG9q#cq
zj*}9+1C1b*thf|!@Le1_i82y*;QLkQt7zuO!X%c-Z1nma4JozkQ}1BdN&X$i6z$Hi
zPy-7SN8FE>Kc`NZb>FD)T>U?PS2kM`-SO-?e|ZW_XOATHsUS&|Zt0t8y!KXT^uGV2
z0IDjGoj>U{QS@(hS8t1BZK8XI{4$cAUz1{v9z8o4;;l&><
zg(Y9Ad>-ATBWo8XJb#2488@9$xt8Ol^go^@|KnY`<-wTZIF8N#&E?0v83Qa2J6@+t
zg)tjXcr!ouDY+(dn%?(b;LJyAJbykK*UK)L&04l|Scf=4~=6iY+t
z99;7e-xmS(D?>vCKN`#~rk!DPTXc6lfCyS@2Hnnix8mu+(OGyRB2L`1lyZJm2?&t5
zeb?xzkjWK8n_jEh@n-AS&%c~9*7)i{oW#fD3t}OHXWhxGzVDq_Z|6L|%kUNa-uXnU
z()^iaWVLATbhPZKs5Q~~>@l$|e`;eQ$GXw{b0$`gzL$R0^hT+R42M=0-)po%N#(4NZa*9wkl^}5
zCd)RH530O=JAeKm9(TVeFs*$Mc~;X9dDgB7db+Q&%b05z&d48n9c2WwY7
z-K)!GAN|{~i^EKpb56&Kba#mmQ1=*xkDUAELtAh!Dfg}lv=$P|;X@unE0mFMC?bwt
zXe&pWDtAg6@ZTaAQQkGt#WrJ>k*NUKu(pp*xd@O?jrt%*px@T&>ju?glr`!$jvFjS
ziVTo?QJ*Y6R>z^tg0vrD2PdCtgt+$uE2`$%`(9~5wvsJNj-RfmMJAZWP3j)u{m}yu
zyZb;_-6%=%NTKN=ZN>WI`df}%w8^LL^>eL1C7=!!2^Y>b7d^QSJUi#S+1^%|ncGn?
zXW+OwhLA3TZ^L@z2HOyB5aq|Q8JF%TbRC#@?ROLy%;Oe*`q@)Z@Q>5*#A&$SYtE5_
z5$$RFzTRet&bAZrGvAWUG#YuXWmhFJDJBZlil?LNBs%OSgy0L_Mj?+L)7IpC=@w}Q
z9zb^(r^#LP@36>0(Ne%sGhvK-5P8Aiyf4*gvk6S7MJM=Pl)1qk@037yo*nWz{G^xO
z)5NLMPVxaaPo0Nr@t=JuDWB9Yb0ews>TaJEi=gTi(QBcXmU56sGEqQ)(GBCH(=V7#
zly%>eZ~T4l4D0QiKV?7b{Pzz+b3S2*an0z2&HHo*zt(gnfrOV4Fr%nbzu)#>sb(B>
z*m+5Nh5SnO!U+q9tLe60SHtP92>sz2%RTY^l0whMD+O+Kp_2@#9G25RIMVMt<;v{&
zeUjlecnM;uUiqVSjrdb*{Z+4rR0DO8ZBWg{?O)$++xC~RsL-GOk2j1T%#
zY6co9G4Z7BUNEK~T#Ra>(F?x*fl$e7bz4ox9TxiAZtW`7GV#(;pFCp}(rlu8a7KMW
za0U`eh;>Boc}gKr}^JEg1-vtL3_Poj$ne}94`EJgPmma
z3cbnt`8dB89#x}DMET$m_j5pBS8AWI75$$(ejCwj8X+1%%dhk2?mt7l7zj+5fZHtB
zP>XKYkUbZXW#{)tzC%J++#cYVZe5wdwZdu8`=Abk=EO$l@{PLF9
zgNDRST(~p!#r*`$Xnyt}(<$cIll)$Ts+Yfu)gILyEtXp}{TN$DUQ0gT_}J@|{J(Z`
zSu6(wLh8oaRhD$OKHpC5NDUKw`CfC~R;n0p!_$s?2mg0HEVca$WA#;_NKl$EZ!e?gV!jmr*E@BFL
zvx<+f@~6K2KUK8^4>#=#Ywlfj?EG42;pINsTPc
zbkf6MCno6vjUz6w#|861E0A{$KR02sCI=7h-xuV~Hc!m|DMP5O9;6q$yGhoe+*uWo
ziw@Jek>&Bs*ObTAu05R-@%HAs&Xj%>xDxi~)K+CKjNEHdZ*so<|og0Wm(a
z_uG@D6R~o&rd-nan}0sP4Jo~&V)UqWyO9s>%;G^6zYxM5eon-OL&NAlHSZP~)f`Q_ohy5rE%u+9iTb(E
zh!)j)-z9?bbj_Cdf4{R*?!56GEBN|}HCE8p5gC9!9Olvx$f4;n6Wdqvzu|st;qG$o
zPkXPjuEQd4=xhMAy#C8ZFxK;S-~juaLEtpAw1C$aP5YmhchZLzbQ>}Z`Aw*PPgdMfPYyr}o>Vuz~
zMrXTC0J?b+c#f0zOL^^I>NRsn+i>t-G<)y=Qo&{J;^HG$3q3{)J-S=}_3DX5Ms6iU
zWSoC~OBN{Bk&Sq#R;z!!@L1(n`p4%#V^^o>c|UUwB(6PbT@7zER-#j5XJmtXa=Pf2
zV|Cr2INY%ts9ZcAzo@A%sG<#x;9CM&-Mr=Qc2va+_V7+ZNJvH4nw%5ErV-hQl!1ti
z#W^sgcij*-yjh@SmR0z$EEbiD!27G;eOsyk)b66~eci_5R_)W@^_*XBohpwEujALqh)emd5;uyMEX*aTcB{j~r#Y?v)B_
zO*`N_Y6P=CB3PCu-T*CJfOgOqS*KS|Px{Q24gl($3x*-g6A#Ba34GSSZYs`Oz6~8(
zKymz&)w7~+rHPy%W}h2u|9U&*meAvd{fc|H)uMZfoA2#>mY7@!wBkMyd_AqHi5fqw
zrp+?VF07vx-;486e7tdOv~{!Tz(>-A{f^5fj-hcMr7I+&-v?wV0nY`CWIPs80|@Wd
z>18kp^g=X>5eZmm;ui@V@xfm&MSm{iWh-&AY?=S8j=tqh5uQxnh>r#R2{W=SQtghC
zu8gLqQ*BrFix9@Cn7vkPIJKgED%l8_d{1Mn~y^v}Z+2$?hTQ3&^#EkGDm};$lTq
z?tiM{`FY~t$qey$GUdX)J~jiGT14%9_Y`vlwT_fqj8;Bxfih7DY6F{@Y*^h*yXmoX
zT5a}GpNKT@5_;?W(|&}hvThP%55bSJu95m`bOEyccOhE`Id}e6&Qb`!dCEF-CQsSkC
zKa5!xdCOUaM?ZaOV-oB3E`-bE!2m=*=T@^f=ltDctqax`%$Clxlf_o#b0V>KVuP?x
zYR=HO|4(fEmNs-`zoZV8v!f$4!tU!Y_lH+S)1T+Dfg|@1;CngS9pjca7tGa>;8EBO!eq7&YyyCt0Re-2iP8RJFmp0zXdn5DF
zEBHG{$k6X-D}$k@^-)=sl&T|bMJ1rR1AMQcr5in|l~q($n1m!MSkgb4eEDewP=8oM
zrwE)`gjiOfsauOKZllI#iA=(k1CTegPZqC7xtTJ582Ns9sr^J@1J8c1Ud>MZn~X-6
z?z@ZgF>Ex+YsHiQ^KArh$?GUg>*M9k9VaQ!u+w^#nJt}8lfQUi{TYk-t0$Km$bJM=
zNM;MqC`gVo8>3F6$5u)z0Be%mTWg?>Tx9c`@mLA4Rm6eww3Z0Hd<|rqqqd&o<0g&Y
z4!;VM=IcIu@=Wd~*Xe+k%AQDBfxyM}`<7DI?5RN8bFo9=jxFL>D`|m-Us^XbP2my|)TA~XepXY}
zBVF^03^7BMx8Ca5Q()7RDx&f<211E*21*6R*G1z@?!&k55tT21g@0P|rPP@oT9f7WC-^RJ$-{sF3bm0$
zv=O|jx@A*i+3vtwrNNZZ=H=I@U~ZTY9@Tyz^x!#`A}cE>8^y|>9Q^>y_rCOxu;JfK
z6Ib(#_P29IAqUkp2RA;DJt@#Msa$IfN_ir&d>^q6qypF1f|a>9$^Ml%)VMuTMiRBB
z+W7rbz;rX8$FG3hFqoo*!PzX5`f;B?bBet-)Gop7Y;qN$%0KyaICN6nYI&nI+InN%
zX~m~nwB??xiiYJ`4L$iegmh?_17yl2{jH@qK@U^)jXa6%M^de=cvTE=5iJPu-snq=
zd{s@t?jtm3&8ivaea+feJHTi$EeG_2Dx93vLf+K0yiXlmcQ;)8iT4zv2E*XNmN#~;
zuWq&48Y(O3zaEf#fKB-j>sY5YS_TohAS@tI$1)nOs}}>Lv{1pD-+#MEuD;QE>o(2V
zp7TaOi~ED;3*LEg(6N~II~S!s^PlIwK!5hJ*|LUbS{s0uv!YkI%_zLIz49PP|IKb%
zAF2+2wiZRKlXBfHGEER#AyVc4zB#0UfU@zJ=2V2bz>Tv_wsCvNVCOx-*LfhmjgRNN
zWG>iHo_YM6)j+e)J4*W5PDh<4_s=^XjA!u|=sS>!*^loj0#hxw0K-1&B-uP&{rJo<
zV+5y)IqLXYbANKnO4au(G5jSks;|nP1Ze?%&eHKB}BK#^XY&4)}Xv4DVshTD*oJahMlW@_tVGjH>#4frhW3-
zdq|b?*81Yd!Lu&>V%ra$Ub6nH&%`j~$s1ubq$2}YUZUkAn=whB>fle8$+Bfi2#GNGT(#Usk0B}er|RN
ztM1?W@YE=BmSmkP!{O7~
zF(B);|8${;)%Des!UZp(55}BjfyPt&hCov$F$PwMY*qig%uMl7v}5(?vJ_#F?M4aY
zb7Dt6e*^iTM!HuDW{cW$fT@U^JqAu!ym@pd7=0J1n8RtcUWe6b?}aRkczvK2QF#do
zzgvr(w^o?a+opdEM7+=UzIE1_cbX`B>l$s}6WWm&e(tX&uBT6M4-~+Zm(LfU5Rs(m
zy2W4dp2^6M$-R7Q8F_4^R>_+W25Tg!z4nkj*W!tr`OG1;W-LlZm4tq+$^kO?z{p2-
z^5xCi%7PZr;bUV%0@r6(?zxc@FG^{xneTj<2{mJ{GaG_L3lUek+wd5ibRrG(Ed=gDgNWZ&8@
zI(5_^Sg*P&d#Tj_H9jr4_s*=ZOV9|jq@1g7W{3>74ZB_ruMM#;Iewjy4f8{cLL`ec
zkIjRoR&if6%hHwj*nn@ZIS!tfm@3HvR)Rnw(xssDIxr(e9es`eJc+1Cwk55K7Ya(c
z9%6#QE*t|u4>~ULg~WvF_jvSqD-q1)I;}aj4=yD(*BB*JvsJ`C0!jcZj0h8j-5qB9
zXYC(_?2O1|@6_klYu$3=dWPewi@#=i4@&QScP+eO+|N;VSec;6QpOY}GXebbzyNup
zNh|pGSnuCCEti+PiIbg#=6%K5slkC<@OIPB5!`I)%(qMD1Y!gbJpJ$*(nlUYoE6!c
zjE#Io%0^gGeQ1yKo6C0}z|xhdb?ry6;2qh%FBl-V3Vt7ASi-MspD6p*IrJ4vqCXzW
zrC~bun$gZCM=ltQfG9u{5`IRTzh??S-x|TEdY23kAl`Q_)
z6-3Pfg>}zgf2We2aK=1Zy-;UDlJ^4BE3st%uOs6j0>7@sXvM0d#^g}1DMi~CM{z!Z
z!VyKCUWD2(wF=6JQ*M3lnb-S8zE52tg{SErErcuuK1-f`;fwFO>rirw#daUOF4Z^G_PaT@(x#{G-`5iT;lHt&37@7WKL+_vT3
z8cl|%WiN42!Qt1O=4|FN;+uKx<%$e&adKZm+G`$->}3S00||+ef}Q#(3`8Cyya!?(
z0ZB}0{b%u>^e?=H(YPzFS1hFg=0y6Ul=KwlvuCs~^s1R}z9Y%H-g5=arh&Z{VB$3!
z)5RW{IY+aEQ@p>cD?c+{A4@dTI_vfl-I*sdWMp7|y5|?xzH4Q#p6qim$Z|~{EVB9%
zpZj*e(v*?suET$SH}Q&-n!GU$H+7^fISPK9IdYR)JH=f4|A`%7LXCF!=ZT>NpAU3|
zTW3lHZInH$K4`UjXzotBK9|1OaGb__;zGp}U0t2Vo&|wpk1a(<3ZQmLHSnZ3S7M`y
zw9L4VM%oV)-+S`82WgHU5zP!3yIq{!QiqDAW`g<%VM-kwFqG7mbTI6|!0}Hdl%v{Q
zOhyW6HV`~$f9Lsw)8Z9R8b0uY9rogXFfjj9JuL4B&T(Qi8zkZP#fFn9A9MxZ4XQ4N
zH@Gy=@ZZ0AdBm5dSaKB+7+BAj2bKc#t!)Y^;QOKdMzBaht%|ZD?r!5=qWn#M@O1Ke
zQ+B&<0rwfxC+9-1sjj~x6@T1BA_QcdO`oM#57r!*R4fHeiglIUiYnYvdc<#ZM|_wr
zzk2X{d9gFqUaDajJnzGk|1{McnY^^7;=UG74WnD$T_^p!nY_M)S<^v^i9&Wdbx?-vNg-%3Gz
z|IRtTuG3$v;ELTMcr>HRzJV|y;_e<|ybEzxrJj^pmtq@___i##sS+Qhe8sbjPW4Q<&TPA1F0#hvR{YQ
z2SnL5GUHIwlkIxE0Yh;6oai^*79>9c(xM=B^`8>GR%Xs_K1*RajA5KWD#D%I^YWsA
z@S=McAzDcY#dD
z)uqctv=E(&D^5a84vm;}V2z4D3iMSg+^P9m-sw2R#}9)VzAzQi
zBpB^sC3y+$bRrU{pULJ@y@Xwi%|y!)(90q0A8$8i8P!wJd6%RTZ42F1<2mBz#ZTFY
zo6OW4HqP69ifYNdcPMp7#V+6m$zM>SXge33=M-P()4
zKRAHWCA+)>ej1{|geZBn4??}(97z9wIt-)*la&F^Ll7`XM}Y5;gVzZ`E`RQQGQ5A+
zuc+{2&GsL)iEHOeItKlDgv@nXZE${$F(e#Dj9)Y4_D^4eShLi)U1o8tUgJ$^S~jh^
z=cHhYqoLa-jy@+`OZo+y
zZ~fQJaqAh>vZabs`#nB}-3=GfGofb&NKM^Sss&0_0|a75)L7B!@s_FDQztX8UOpjc5Lnh57?uRLtdg9T){f%l20^=2@gTf+>;qw-`Wl
zK?Fn5zF)<8CR+7A1&+$YgXii`XzYsfiDx=IO8E&ZRqoPD3_;LyyG)49t~YL95oW}P
zSRtgR*wiUq=8#yQ>uC;FqpsW}wXA$;EQ++2-AkZ}!R?aUS3d&Z{UfPVd2Vnl_r^M%
zhK+d|p}^QZ@|?FNwX}A3qI%dHqH`Fvd;RH)^{*E$ZBA6vpkD1^C-0T$Ud?=UBcWD*
z@xi{0@TDEn`t~CM7<5?t^2qrr(Ba9hrRqcte-zzS0T+u!CK;ztjOXl;ihSx;Vm`z1
zVAw2{wXRgGQL;v1YKx-(?!?>6Zl}W%XbE`m4{^>%oFLlLB+3Rc`+7e2cnZ%iBODel
z58v%mTU>2X@`iOE};*DPO#QXcv
z_K?2H@cylb?KoLf+jdU*=383izH&5Yt}8j(>4#i#z}58p!KTaNNwhr_tHupO!KT&1
zZx^5zLxN8p&9%^ch0<=VH455XwAi-^2q1SaO?)q(T5K%0W-AS6jOoC}YciJFSVOqZ
zJhfMxB+1gxk2RC#7;tILm`QHd(DA45$MNQ@<0z1(aY&F{m0bIQe>;pYjsl6_75%Tz
z_BPJAdJGBTVw8<J>%2O+({}NEkmv1(B4DbY%2-u*J
zc;F>|#HqJ>gsY6Fdp6IB+$gI7Q=yCzo8ZAF7S?Sge^GUWpNP%xBZRK1=t
zOUsT2m7{Nj#9}w2%E;Z{{!K~2s>XAy6%J;x%XxG4tX(eB0d~S3Kr@4hJ;4^CINQ#t-cN9xjb1eP!fs(Rj}e9#Lny^taLjO@*O$K*=EsvA6#7#e|9P
zT?9kGzB|xim&iSDyiiI}z06wjaAy9HK77!<38Vpm<3
zGt*@VAq=&8Tr2F1f~%7fH6CFba~7m6p>AGyYr-8BFHVwN@pT{Kp{{b=s0l`Ql2
z09dzuX_8Nto9PWuT3`oNAQ2V*uIkLt$mAd0!Fg|5_N+Grq3^S)f!wsmes6muu4(UZrKMVQX_@Nfds4RZDzE9$V{E9$UeZdtexvP;De@7-?+{Ff{-37dsp{iRC
z=zUsn(q0Gm(OW1{m*Hu6b%yEp4RUp?TI&l=w%c&OOtWL>i57e!xGFWpD96EWvAGWs
z{}h;#KmV$&Omlo>0kYGg0Xp&c?{Xl;L^zJ3=mgW_TQ)#&oUm|T6v%d{c|1+ShbyNx
zUI#`eO-4=?5|aTQHrIMO0d}5|h3Q7*7^p3{(c!>Z0&6zFkHZjF7xiP{{Z)o-cI+M-
zPbN0KXURJ*W6!wz{0r|+AiDNWH|}H2>jmmv{=iq%!G6;DL
zyYVaH#o}h;i#&%JNM!+0;oJ!nv|Xz&RV*2WvnO2?_9ZtQXN_*){kI@A{F`!FmFlzL
zBfr0~(IA3-h*i9~6?dRxK8b#w(hk{?pq)o}G^7Q($K60BoG?FkwGtnY0xHki6C5*B
zdNa#}fvMbubQ}2c_CYd`;a`nN;fcq1L9N5MgEJeXxS_W)wE3{6UjpSp_cf6ltEEa}
z#S$_DO*eO^kYG(JWNHMWs+$0LZ|&QpLT{z_rO++cN}RK}jf(9juC>Nb)6`=O$PhFF
z5|1S;CCoEdQ&*Z{B>AaVWKIpKT>hnUROIN9(SNMKLsK6vq01H
zq$8kh@|aZn`y;wQS4#DcCRSyzH)Ze{A>BiTNR6yPrGH_jlH*vUK)wzC6Ao+OmiY8v9K{v&L^6__)+6SIx
z#>6kooU2cw0y|-Ld|uWEPq=1U-37U`W#j7G=piw$#FFA+oug6_zM^uj2u*UAC&QEc
ztfCQYK^i_MTygcqYppf}H(I~&^06!*+;H{PfDmHSw_A`VF}PzS2a!$1a2r%Zw3hUp35Wqi6^A&LI6;njE%4Vb08Q$_@Ngz2W1)bTJg+NP(Y{70
zj!q+72>JZ{lsV$!Qk`bYKV5R|J$Z-h5lq_VSLIAtyuS6XX`Jt+%<9Snl~Myr!tfTs
zQAHiNB|ljz^z`IYehSiA&vQ?+=7nO1ZmUIeH>_ktE~%*kqfEp;q`#6gI{5qQ`0fxS
zINJznH}Yps0{G;*6Qg2;TB?fi=`!@NzkPout*2HY$oih}-=ThGl4EGuLe~{}P;u!6
zl(X4cb_T!d{@;Y{{^x?t@o`h~Tj8;yCN?wvKJ7qol8}Kqf9cW_u
zn-*0s&VPyt|8IC{wUy(q*TV2<1FK522L#5W&7T(U^e2!T>XNbVU7)#h>16ya
zxpLbNaE)l(s`zc`_9|G$cz5MOSSfrH9mi;C6m^_8h(53>5bdRLB(!{T*Ba^Z7IYCv
z+_D#q`GI4LmCGFTxR8fc&KGw1V#jTt;ez?F4tDXwTHbtS$tD%$saP#FtsoG#MWN36
zJLp1
zUD=4IZnwBD;U8T0W<)-O(W2#rUP*0(2iW}5f2LnxN&otBtsU}6D>gA}uy+m>TPwbx
z?hoTj1zu!x%iTI>-*UG)9hU|LWZC5~&-&5{lTPMSzu>->-TojyIYMUYOnMdHOAd=O
z7uquEpv>aYXLC*TLGI_o5Bxp_!tNiz`tA%T3Vz?dCfEA@ju))0^V#j_I9$To%#BiJ
z8Rfe!5|${1CoOdXCK|!(HXETW?8d5x=y7OqomJG#IUD#k3Wnm&pf^CL)o9rFfF@qJ
z;M9)TMr&j>Y9z@cl6{q$(aGNtJ{&Ut;FrcT$(}?(Q7{w6n`P7@EU_E=e&O53cXc>x
z8vfuXb)?XTXa?*6I3LBcW4cER97VHrd@GGk2Q{SDsft{NRN6c|qvYQd$^F)>B#1QC&+3Jc%
z@Z5*qwBF4meG%+O@@4-k|G3!rqog9T8{4h@Xg}OD>Yp1N^f0E
zz_?E9m1wbi{~V<>)dZsM(jgrhp$d<#I(-jY@0_4o6Pq_RCx^zUfS{c5=)I!!P}=
z0RL$@kv`Sr3-A0o@Mv3;^~5&sWw7Ju`!_B&&_?7ptr-aD7fru>
z_IF(CzeZ98!cC@~FGuNx19pk&G0()JPrTA~1k0bO=0>}{8HH-y4R;R|!T3K3Q2n>8
z@4p_Ce}d_T3?ZKSYts6%`EsnG7^KqWCr#8~87HndpUQkU&(t~>J7nGx$32x&XixV%
zyhwKQHo>~?Y7c(q6y(BTpw8X+u~XJ^2YDtSX`*T5|mIVsPp6CkA@csaf)=Q<{x
ztb)d6T2=v{p{u=g(N|XqLZm4Tw9NRXW;)M@@)0XNV25ip{-jZe6jkFw`x~tMKXC*9
zi=1&9-^I0qevNrdOVPCt;qw`rd@|}+Z;jf=qBkwX`OhOBnY>YH;8=yiXPt#*aOuUI
zqQ!}FLM!A)njEVau=nfAg$c&zV{9F69LQ=!O%X8pRm!{#=m1oF;g$$%{W0lK30F17
zgMSxHa=UsFVr;yf9xM*YR%fy~Eywrs{XAsZxRsy4<^4{t9yw=`w4DFUWG>aw>$%$!
z&u|!r!f!JSz*V-G@oCA7!b(NkB^AAQQYG#2h^kmv$qK5QjgjFefg+ih0`OEUAMMz`
z|89u7y3ix=SNMLMORu~t{rU~*H$VZiIXjC3JVvstIpitXKrVcuKK9&emwBBLJ=#pk#q$zmx3uSP7J6n`vU|-R
z1o^-`AK_i4V-sj@=O1-@WBEg@heI)j@{Y5wP>1y_Ic8mFObYw$s8Aj8{QU&TfW+|(M%Wy)DEVn6&;F6s8
zRDJeJhufK8~mPmb{&IXuTW%b3^PCGhJ@IO*KcLcdeRQBWIfBm&9nAF%+
z>zfG2m!~q}e`81;2Ov1I1FfGpK#-L9aWTW;9m~lEp6>4kPl4&_fxZhr6TMtmN3UGe
zQR{R-3dU6#EK>oiRH&t>mig&rNZ1#j+{G=6{U66pKrx?($Oa=
zFMq*S=T<9(+p*243Lb8b$*wQw8vDwBG@Jk>)SFAk-#HBX?KE%vK)o0bR69jJ?1XKt
zMhT`Ejg%ht#hp${&pTGse;_UYU@Y)29lKvE0L)ln>&OylX~{033>UhYM+Sn)l_V#B
zV(iyay`G`{%Xc&wOLdB@&GWlY)5*UCRF%Jd`Qf^38<=&vd5bp^Cm%fuuJ`Z~o>}LG
ztd}^HR?~0T6%D@LBoaE?rZ3%a)Nw4lLVanIY!(jUal~cNyu|`-v!8{hW_HaA(VoWj($z{
zzMyepqItRc^e*Z&U7y1Hn`jFUEL
zWOK*AS!8~stSSD;0Swn0AiEwO9}k0(w3?%t?&WhDC>yPpi{1@8^eUON-cgxJ)oFAq
zxzS16nQK8V=lt6a;|S?DWL!fpgPie77BgfkN7Z5PIa71P-45OHLJcqX8H545P;9Mw
zr0%N4t6vNiyn6Zw4i6zU%Jt;~af=J!cWd$#7n0Q%2{%Xk989{zNe2ut-0n*=#WAdusjQah;0IwcL6;R$64trc-(9LJn5J1huiO{1_h1Xm#+Z0y+&K
zlp&k7FqTYb#J@fb_}CHVnxarDd=}YxLNA+pl+AQg~{`CB|%IW9?wu
z!GCevt&tZ@m>w8E;AnU>8cZNy?ceLOnkyak^bXr=QZTT1vM>f5J6*k1x&SNFt6$qd
zTxeZdO^j}q=VP3HT(#bsxpqjK6TrOzsh2;pSpEav?7H;1M4~}1VM5R-tZ$ib!y2z8
zF&7=zpg#7ni%`Ykg;&!;7rsf;QTL3m?YeTG-4xUVk%f(thP>aIF`
zc{tu#M^CqAin$DIk#A~`KkFtZE9P+6m$&tdj^NooSvW%0)o%Bn0zbeou198i%Z(jN
zQS({t>+udp{#U|X`@^$Y*v`ve-+IRu)*mBNQesj%Lh<{*nfwjAoN3)s(>cTNvS~F^
z(Jyxq3H|Xvp!d`MjW5Cd2Ragf0We`FwRivU`)vl?hC46bbu3Fe#@xy0j#E1Iv2JJ@
zl+zxmCw{(Nb=+9@cAUN@_4soMgNnsb;AFk2Wr&H}6IFlL@{?^Yn^VR>Y;m}xHftMt
zzD98jdCT^OO{eGLC}P)5D+0p&VUzmUQFMKIJOY}{E_OhWj_qOKl;yUusN
zV4Jww$NrS4-<8ZU%kYciS-w78QZ=s<&48JUo@SxG&`t6hF%a*0NhPEv+x?H6-yddj
zCoHgZr4P)AploPK5wp||9``6I{_(IiwBSO1o>Fc6blQ*F
zTKI@4$#Ln&F`U+WIyy;V0H7c})Y1&Ug()$*2~jTbg9Q>xBd2gz?`Y!ngAnB-AxUa9
zE97JHFvAE)Fk`ffVv@0;m}&20PE7C;eI&gYji$z+IbzIh@`*3~uR)V#J?+B+GU@UK
zGNJm3Law6;a=kuNXjRU4%vYGNp9qs^94SA!arxS&+wsEi>vQVm|t(p~;gkK7n@Q
zi#X~yXu=UBF^>0?U`DP}(xhXV~W5>%}BCE5KLI1!^
zj;*#buC;n2o^G7dE@^AieuE7|5YYsFOo0NAIz@a3lOHq*F+|XHo(!?>Us`hNo{pZX
zEmHivH2mz?a(Dbm*p^%{6Pjr=#YWGqZykspZq3&LwDmj(iR}nqGnnT=)Ufh!sh!3c
zlVylTtx!$ul0chj8iW-2&<0r;(B^p}bnTLMS3Ad_VuGYIde?1O=Vt*=_O2A*
z>Mi1*x_>v6FM~l_Nwrr1+m(LtZDZBibx2G1_ayq!F3^F1OOFX^|BJz88%x^kDPZdmSrwAUuPSp
ztSGEmAg)J@>oI6?A{p_@VhF=LjtOiY(KxphZPI@IE7E9SC7H20f%fy8gi)+Dk`Bu6!+*R#hcpiHXXih+D~)ryuVgf*>?>`uw$e}d2TQC1vBb{}
zZsp*j-`cxd;k69i3?_U&>Zn4cm;V7fO1%O#>nR=`&IWai(~ZsDltAI>o=szkvi{n?
z!xFjfwU5nU9JHO=0F%Go4%`Nguea>rF+WGUA@^|c+lM~_Wjqo;YD&g_nt{!ZSQ|#W
zfL=NDk66t~(Z%?P{y{$0@rWYd{$+4Ju4>D-J@0O|f%dbJs$HfGDExVB(nWK2;?z?T
z*QjPg7oq`N(jUZrWfmfSA=0jR%vc0-ZpK?H9FyO3CQXGnI|a3U;2pS(=j>tlUV1FA
zvPk0<8-BswgYVjyD~8~ts+>jOd)#M#BNQW5WX3t)jG0!}
zo->XH?tWj2W^8f!XAk{7#
zGwc4txwJS#mRq*?A5w;GLcNo^6OsPNROY1S5g?q`cTe+qv$0Cc=5^tZ&Ayz0`^R@x
zSeYLvIO#3KKDbvNbNZHnrbR2DmF8>Sg-fJm1xs5~u?%Vrdk!B!6-^2qCLMUXj)NI;
zf>q)`@6h==!eM~{xTL193-Jh2`zo;5bQ6?#q@~!F_lXX@Hpg;Z4IDS7|BvGqUkO@Y
z!>U1-0cbs=_X;~7-7@dP=lymc^Ni8A1_xJnnPzIAlsRDh3E
zVCYR;)ywH!(IrfBtm*kt=Aw4RJUe>-@K_bY$Z)J;V5>yE=obi@wKmq*b{so+Pk1Ee
zla1?`b8|jfOHcDei~(ZNA$2Ib{xAAJNRVf^b^E?lKA|-qI}8Ndio0M8bWYgcou)r3
z#@`ZJpHEgPG72tV7jLT(w0_2P&9X%y&>u76WMCkmy6G~dyc%KC7&w&)YhgqyE9R>e
zK7M99a-RD*%Sst0C$k=4yT2R_kI6)nbvU<{k)i3G2FgH#tRMsGCPAJ_zlV`QSMPNP
zpXBTFKi~f0eL?`iu5zBC?3W>xylkeNwAWAnoy#0DBQ8YhcA&QLdgg#v`0~u+>^p=@
zvjx7MgpC%J7WpFegXHoK3Ohg|_p@5eEEV@CMppeiLL?0uU1P_AOs=OQ7_QEUgMz|Y
zE*3{l%T^gw*dpm}ahPww2&Yp+m^^h1jTnpmL;(?z7oEZNE|o+wy<2aV1L1QunXjsh
z49CyxM=nRe0+1@YRMhkA3Q}fmIT9;*gTaSQZ_FHdXY_Mu{}JYYL-TKMV3g5lG?l@T83OeS2VqT~#6K+)w6DhBT`z!h&(X_p*Q%o|g
za5A>UuR+`qi5A2HMez?#-%sAY2^%mx@g?Po=E~dfj76_$eWW^#9B-*@{S^HhQu=5H
z*GZSMvF_twI}lM60D3qhoX%O)9dk3ysqM%}ueClETOYy1k>J}v1GgT0=HVftGF&0>
zfuCRMz5jzxsx6;H?nE+c5J-MV71Ei9KwCBmq5L7Wxu;c=ftVGHoamkJ>z^(_^VdKo
zzc$|$ml30MG#PrdYJ#!nl|D!))isexVqlH5hA$ttMgc;fI>OM|T;B~r5oVJ~7l5Ky
zdYQdP?&W-L;H~1%kZ+ubF`Rs
z!Wv&@l>3MGnVl1Wpv>R`AFJ6khMQ0;=Sjxs3-bc!z
zh{O%qNPch5Kvq>l!uI@|Ib#J)3_Wfr|mCIN9GO5gR(HcGg(+X8H^M>CdiDfr-NV`p1!_w*#2a%rXZ43Ey=(H+~o!K55P+{{MuWu%|DpB&@
z%yN7}JClM}aUhCVO1x1rPv>WHAd%zYhLq0x9?`OAuKnX&cI1rwMERf47Qom}9fFbq
zN_-_eIDTS3QNaffi$}>5rPLX9l~Iql{n`Di0wbV$msa@UoSvfmB#6h{gvWj#OEc{G
zY2ESe*-O3iBl1HUL6i}yh*Qy`|+>MfJ2t9W_1677V{P808|e$%_3-G-@781x1p)K9$-9Epp-
zL`<>~um$V&94GHvsm#FFS~khKCUE+!lH;`Ig)FIz+!XmD)w?DZaDQUj7j5u)V
zou-HiltySC>bN;NVfG3qT1~x)a@F|3qsFAYk`u@7JRYLlhQ_UzuBB?o%V6=vgYTPr
zJZAvZ%Z3BQfoO#{{=yz^IT_;vd%1Ft<@4Z&GAs8_L7Zj)R8jEcjCL_z?;y8bi+L|8
zN#1nHFaQ!RHE@UF6I%4s!DXMUba*Zd8#Q!z*LiGsTbeP7OF%5jbA7B)boS9>pNE|T
zJq2RL<2b!LSUTOD^)%%%Xo!&R9a|*790!sE;6{Fq0oOHXSEF52fV@c~62y4BrTD8X
z`A0PN5oGT*=G>7Lsy8dPzsz4~yf}F=9@gHSYxh@Sa59fI9X`tAK{>)nJwnTZb;OXTM7$}t6*G!oqr74U-8=g;^?spLQCML;Z*e}%nC
zc|7y-)9sEHVe#|Ivd{CFM>aB&PlbGmdr#}wcVzH`0HD|=MnY8PL$1#H(ThJxb)q4gG*iDs
zU_sZ6%0bJ%Gq_kjQeU@!cme9ohsmW_)8TJWkO!-SPWtBm;a>F-UatD9l#=#Bk9`LK
zp$U4m1rMb3@>|7HaVyfutUU0@dDWV^9mm1}j7VIPZ46>U>q}vx(t$y%?I{XWG|Pl+
zFMmsQO(Na%pK@(Ju+xZkcbD#R>rMUI@LD}cQiFQm^Sk+w9~0xoT(|fAQoNEf|0;HV
z;Pyr6KkXag0%>zrYL!~dqwjY^x-~_CniCUI;HWQHP~!VmIMbWp)E^jBni7JKHNc>?
za>TN$z$5up%$}Z>4uKr}u&6n$O!Or}Vw-H!`~RReO18Z$`hG{)JMVgm+%4cH|94Eo
zNT>jiaquh4=rsUS{Sjb&bQshK5`wV;KtK6&RPGIEt$l==wae0}7rLFIv5V<20@{ct9r=KIpP0ulS~H*3U<
zYTVd`+)FWqY^KDVNtOY1zf9H~AHbk|cRo>9sfL^Vr02~k_gAjJy<1M++xR`lAyyo!
zqCDHDh6G}EYT;L>T)0!!4|PhYuXa^gi~=OB_ef8qA|A|
zVx=MqBF8B;6=HM|_r<#Uy6Dy6UO4>8FOL%<-Ta!1TJFi1`Vg^_nc-n5_7AUOWar`g
z>0r5d?|*J0-+P-#Ci@ABLnPIqI^fu(Fts{@Ys&$IbT5zF+>+;482#}_%H1WY!mxS7
zh_tO^Nx)9p!Wr$5GKuiu*$r0I+qb$N+P6|O?^X(UNHw2J{0h~q!|==^m<_Z0QlG@c
z+wi5T>*o3cNzKU?uQ-wOGcwt{IUULCGR(1okG1DBo_nKUVmUZ(ItxGiA$^gg>CvqI8OK*ARGC6b$a;N&QzpEQS)@}2Wi1$2*Nv1R;z5OE
zZD&FkQ8UU3v)r93vmr=N|6P_m&{m_Bo4veTxDc;P2}V`zuqx(@mZc1t>ZL;MeYXBK
z1JDN#=O#)>FpjqXrC>yz>Mr*uSjt)#J|`|a*`rK0^9XVa
z=9jlS)F;Js#!n1c9Do2hG{Jffx(ibOE7bIEu6=~KlKTVE=%_eb{{heVcVyiEti))@
zAQ<;=VeF({RY*M!A!Zp9QjbSh2>6y*^S0y<(S@Gpt=r6hLn|r=T06{AOkhm`W3Wn4
zkn3F%ee`LArlEzA{i9liHM)SDu8+6+lXtO1J~!D7AvYO2;&@H+OJ5o+HiFGh+H5Q+
zZzU)VT8OvsDyYO2vM8Dlmde`eNlZt1Hp)Q9D$F^114e-U@ID_ex5n$#`hV=hN%!)V
zPK%n#(h-FN#U~cYSadvJT7`Q!UEwFHC|WAZ0$Hlwv6%zpL7ZDyUAhrzgdMTbFs7dc
zG6+jv|EC*e@B+H(%iXQy$gGUVDPf-!n|xgPHq>S+;8fyNNM4?Oa?n^t5L+w|FINV#Q$J2;+$hynj>NcmWdmrQf)eUyQ1#fEw
z`0|Ae7fWO2g$CSk-_=*kN;>W%ZG}u}*3Dr@@Am%%d?N)+{Y^$q8O}BS4f(dBais&X
z60|z?vtGFMMH70Ak^7q;DX@FV;Y4)+lr52-fovuN<)w)0nccHUL&l?z
zLFM*gI_-5I1wQ-4b+}4Q?%h?#nZ3rd3Xtv}>v{k!*DPiv*QxB*3SlOdBv&*z;UX9S
zvu6dW5u%4jbr)T&x}>xhXMFyiB=D?tq78#IU;zQ)16&$xFRo3Lo!7++3tG5Sc>f#`
zRD<%~)UPPnFM;JXbq*A4vYEbD9IK?+()0aKAg1@G+Z0KD(^4Z8VaIZ%@&0pMT#L=oO#Sbig{eg7gpED>wK1HN;;1Zc@oDgY?yMeV(;u)mW?LlO5u3Nbum)Wj
zmDj4_Xdf$&f<}h<^=g=;32*BI*XW)QZ)u7s8iSx*qk&eoG^mZGYGMMI`gY}na?|8*
zPw%C%PHA_*XhvU>4BK15c8OYg&|Xo&SN6l_1<|f4g%4X@)_tE1?wh&sSlM0vk)8~7sQCBsV5g*jTL7_ixkdfd(Uhdk}r+mP+@EQDs
z^0nkH$g-h5$p1@qfg$&suTp}qkEh6K)SAX>P-9-{^^Ruj>;|VkN@KSKae~!6@}x0z
z{PK<-<{jBCZA$u$CXQiUOhb?(R{i!x^Tgo_3=xQr0N6D5EH()2*>(ZP*61+YKHxTq
zp6teU&h17}5j<*7c!f#NmP3TFK55)E%M?}|SpVqHd9dFTCjd|mLirIK
zND^E>KFYEC!LMINDTPZ+l||Uh5~}nzvA-G~REYdyfOC7@62wLte#ZuBaYS
zLcRlY652oAWPR?s
z-h0$RTqspV5^?Vu;%?YV(E>LDA8@(n`-vx{pnh+;vDrLBSl4;P92SJ^zW~jv>
z?82$3Kambco8(clc1pAZua%O?L(96LY{O6vKp4_f<^Gq(*y|4tH(Vn;YTUMxZGjs~
zc;rXs-cbe92|Riqri^mnq1qfOO`F#PSBw`4PYoEVTpGk4w%hURNjQOJS&m-bZ!lQf
z#rJ(kU8jv^LrRu2t)RD-FWm1Ux+|!z&{M*UmfW0}J+BZeqHK>8UgAK4(+P(oWbfTJ
zSIV|IynrL|qChp#g#h6se7#MOSQCnjzYmkpjY7aw25xiC8#Cd>Ri3HFk^OCb-Ld|%XH=*gM4~&T3?*Cvqc4UE@rT@a{frmSP9u*z`>wG7Z0j>Wb
ze^*#<4nkM*BcoF}dYaAJ$+|hO(xhhirSO#M^o^+G1{SYrVtM`G-vaaJnB10J27SFRHPA}zjd0g1PZM(R>
zGGLP8R{Z$Qbzwu$$kQ?bBWw`UcwUQ!#g0ChN>+KSzf=au72Pi3*$|bQR=b|?`{k?D
zn50_x_IgGMIdc<}UHS{U54a%=?yUi*!%*x-2Va*|uf0ZR_O%HIBp-`OeD8(+mZ2Oo
zx>YLV^!cmHYQbHOb44+v@*zScwdw4bTRNt%m$mgr)c4T%1LSspdO~zA5EjF*6twlmmuqM;;>ae(eeAEjNjq=z_4tM2SY6H?hug!{Vn
zaAtX9)5XrRW?#$3mx`ByoO3^f_$wuGLRa6fFQycP6+*v}^70-bb_R6{nFG}HX-Cnq
zHDi9luP=?v8Y^m-@e4?4&9#-m@lY-3v#-;?s)#$PH~<;|9ZjUFLxJd1Wb1NnkLe}P
z1Bs&iVQSW4i)=H>*0A_Rh&Y<$fo@!J7g=h0DdGJBOvlKOVJ+Z
zyZBBB73l|wS1&5Ue1DWsm1hD+W!c4x&y=#m4j@v!wHY;%rTo8A01y0wALKo
zscF56(bHa2EuxcD*c|(T{aRi8>&mmKgP9`yQ