From dc1eb8fa92e32952c1a00ba0d82b945bf5d2e29a Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Wed, 30 Apr 2025 21:00:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8F=90=E9=AB=98=E6=A0=87=E9=87=8F?= =?UTF-8?q?=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 33 ++++++++++++++++++++++++++++----- data/src/floor.ts | 28 +++++++++++++++++----------- ginka/critic/vision.py | 5 ++++- ginka/dataset.py | 11 +++++------ ginka/generator/loss.py | 19 +++++++++---------- ginka/train_wgan.py | 16 ++++++++++++---- ginka/validate.py | 6 +++--- shared/image.py | 10 +++++----- tiles/10.png | Bin 699 -> 406 bytes tiles/11.png | Bin 0 -> 291 bytes tiles/12.png | Bin 412 -> 341 bytes tiles/13.png | Bin 419 -> 396 bytes tiles/14.png | Bin 0 -> 289 bytes tiles/15.png | Bin 0 -> 344 bytes tiles/16.png | Bin 0 -> 419 bytes tiles/17.png | Bin 0 -> 305 bytes tiles/18.png | Bin 0 -> 358 bytes tiles/19.png | Bin 0 -> 441 bytes tiles/2.png | Bin 368 -> 847 bytes tiles/20.png | Bin 0 -> 442 bytes tiles/21.png | Bin 0 -> 448 bytes tiles/22.png | Bin 0 -> 436 bytes tiles/23.png | Bin 0 -> 448 bytes tiles/24.png | Bin 0 -> 643 bytes tiles/25.png | Bin 0 -> 389 bytes tiles/26.png | Bin 0 -> 353 bytes tiles/27.png | Bin 0 -> 382 bytes tiles/28.png | Bin 0 -> 453 bytes tiles/29.png | Bin 0 -> 699 bytes tiles/3.png | Bin 406 -> 426 bytes tiles/{11_1.png => 30_1.png} | Bin tiles/{11_2.png => 30_2.png} | Bin tiles/{11_3.png => 30_3.png} | Bin tiles/{11_4.png => 30_4.png} | Bin tiles/4.png | Bin 396 -> 420 bytes tiles/5.png | Bin 441 -> 422 bytes tiles/6.png | Bin 426 -> 678 bytes tiles/7.png | Bin 353 -> 368 bytes tiles/8.png | Bin 382 -> 365 bytes tiles/9.png | Bin 453 -> 377 bytes tiles/999.png | Bin 0 -> 414 bytes 41 files changed, 83 insertions(+), 45 deletions(-) create mode 100644 tiles/11.png create mode 100644 tiles/14.png create mode 100644 tiles/15.png create mode 100644 tiles/16.png create mode 100644 tiles/17.png create mode 100644 tiles/18.png create mode 100644 tiles/19.png create mode 100644 tiles/20.png create mode 100644 tiles/21.png create mode 100644 tiles/22.png create mode 100644 tiles/23.png create mode 100644 tiles/24.png create mode 100644 tiles/25.png create mode 100644 tiles/26.png create mode 100644 tiles/27.png create mode 100644 tiles/28.png create mode 100644 tiles/29.png rename tiles/{11_1.png => 30_1.png} (100%) rename tiles/{11_2.png => 30_2.png} (100%) rename tiles/{11_3.png => 30_3.png} (100%) rename tiles/{11_4.png => 30_4.png} (100%) create mode 100644 tiles/999.png diff --git a/README.md b/README.md index e4a4f0c..a7766fb 100644 --- a/README.md +++ b/README.md @@ -29,22 +29,45 @@ GINKA Model 内部集成了 Minamo Model 用做判别器,与 Ginka Model 对 "yellowGem": { "30": 1 }, - "item": [47, 49, 50, 51, 52, 53], + "item": { + "47": 1, + "49": 1, + "50": 0, + "51": 1, + "52": 1, + "53": 2 + }, "potion": { "31": 100, "32": 200, "33": 400, "34": 800 }, - "key": [21, 22, 23], - "door": [81, 82, 83, 85], - "wall": [1, 17] + "key": { + "21": 0, + "22": 1, + "23": 2, + "24": 2, + "25": 2 + }, + "door": { + "81": 0, + "82": 1, + "83": 2, + "84": 2, + "85": 3, + "86": 2 + }, + "wall": [1, 17], + "decoration": [], + "floor": [87, 88], + "arrow": [91, 92, 93, 94] }, "data": {} } ``` -其中,`clip` 属性表示你的每张地图的那一部分会被当成数据集,例如填写 `[0, 0, 13, 13]` 就会让坐标为 `(0, 0)`,长宽为 `(13, 13)` 的矩形内容作为数据集。`special` 不用管。 +其中,`clip` 属性表示你的每张地图的那一部分会被当成数据集,例如填写 `[0, 0, 13, 13]` 就会让坐标为 `(0, 0)`,长宽为 `(13, 13)` 的矩形内容作为数据集。`special` 不用管。注意装饰所使用的贴图是白墙,如果白墙是墙壁的话,需要将白墙设置为墙壁。注意不要忘记保存 2. 使用 [在线工具](https://unanmed.github.io/ginka-process) 处理数据,需要给每个地图添加标签,为每个图块分配种类,有一些图块包含多种等级,需要填写正确。 3. 将 `project` 文件夹打包发给我 diff --git a/data/src/floor.ts b/data/src/floor.ts index e308bfa..572bc97 100644 --- a/data/src/floor.ts +++ b/data/src/floor.ts @@ -28,16 +28,16 @@ function convert( const clipped: number[][] = []; // 1. 裁剪 - for (let nx = x; nx < x + w; nx++) { + for (let ny = y; ny < y + w; ny++) { const row: number[] = []; - for (let ny = y; ny < y + h; ny++) { + for (let nx = y; nx < x + h; nx++) { row.push(map[ny][nx]); } clipped.push(row); } const res: number[][] = Array.from({ length: clipped.length }, () => - Array.from({ length: clipped[0].length }) + Array.from({ length: clipped[0].length }, () => 0) ); // 2. 初步映射 @@ -278,12 +278,18 @@ function range(from: number, to: number) { return Array.from({ length }, (_, i) => i + from); } -export function getGinkaRatio(map: number[][]) { - return [ - getRatio(map, [1, ...range(3, 32)]), - getRatio(map, [26, 27, 28]), - getRatio(map, range(7, 26)), - getRatio(map, [3, 4, 5, 6]), - getCount(map, [29, 30]) - ]; +export function getGinkaRatio(map: number[][]): number[] { + const arr: number[] = Array(16).fill(0); + arr[0] = getRatio(map, [1, ...range(3, 32)]); + arr[1] = getRatio(map, [1]); + arr[2] = getRatio(map, [2]); + arr[3] = getRatio(map, [3, 4, 5, 6]); + arr[4] = getRatio(map, [26, 27, 28]); + arr[5] = getRatio(map, range(7, 26)); + arr[6] = getRatio(map, range(10, 19)); + arr[7] = getRatio(map, range(19, 23)); + arr[8] = getRatio(map, [7, 8, 9]); + arr[9] = getCount(map, [23, 24, 25]); + arr[10] = getCount(map, [29, 30]); + return arr; } diff --git a/ginka/critic/vision.py b/ginka/critic/vision.py index 465760c..de317b3 100644 --- a/ginka/critic/vision.py +++ b/ginka/critic/vision.py @@ -13,7 +13,10 @@ class MinamoVisionModel(nn.Module): spectral_norm(nn.Conv2d(in_ch*2, in_ch*4, 3)), #9*9 nn.LeakyReLU(0.2), - spectral_norm(nn.Conv2d(in_ch*4, out_ch, 3)), # 7*7 + spectral_norm(nn.Conv2d(in_ch*4, in_ch*8, 3)), # 7*7 + nn.LeakyReLU(0.2), + + spectral_norm(nn.Conv2d(in_ch*8, out_ch, 3)), # 5*5 nn.LeakyReLU(0.2), ) diff --git a/ginka/dataset.py b/ginka/dataset.py index cbbe4c2..c701c19 100644 --- a/ginka/dataset.py +++ b/ginka/dataset.py @@ -6,13 +6,12 @@ from torch.utils.data import Dataset import torch import torch.nn.functional as F from typing import List -from shared.utils import random_smooth_onehot -STAGE1_MASK = [0, 1, 10, 11] -STAGE1_REMOVE = [2, 3, 4, 5, 6, 7, 8, 9, 12, 13] -STAGE2_MASK = [6, 7, 8, 9] -STAGE2_REMOVE = [2, 3, 4, 5, 12, 13] -STAGE3_MASK = [2, 3, 4, 5, 12, 13] +STAGE1_MASK = [0, 1, 2, 29, 30] +STAGE1_REMOVE = list(range(3, 29)) +STAGE2_MASK = [3, 4, 5, 6, 26, 27, 28] +STAGE2_REMOVE = list(range(7, 26)) +STAGE3_MASK = list(range(7, 26)) STAGE3_REMOVE = [] def load_data(path: str): diff --git a/ginka/generator/loss.py b/ginka/generator/loss.py index 11bd813..211bbf8 100644 --- a/ginka/generator/loss.py +++ b/ginka/generator/loss.py @@ -9,13 +9,13 @@ from shared.constant import VISION_WEIGHT, TOPO_WEIGHT from ..critic.model import MinamoModel CLASS_NUM = 32 -ILLEGAL_MAX_NUM = 13 +ILLEGAL_MAX_NUM = 30 STAGE_ALLOWED = [ [], - [0, 1, 10, 11], - [6, 7, 8, 9], - [2, 3, 4, 5, 12, 13] + [0, 1, 2, 29, 30], + [3, 4, 5, 6, 26, 27, 28], + list(range(7, 26)) ] def get_not_allowed(classes: list[int], include_illegal=False): @@ -30,14 +30,13 @@ def get_not_allowed(classes: list[int], include_illegal=False): return res -def outer_border_constraint_loss(pred: torch.Tensor, allowed_classes=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13]): +def outer_border_constraint_loss(pred: torch.Tensor, allowed_classes=[*list(range(0, 29)), 30]): """ 强制地图最外圈像素必须为指定类别(墙或箭头) 参数: pred: 模型输出的概率分布,形状 [B, C, H, W] - allowed_classes: 允许出现在外圈的类别列表(默认[1,11]) - penalty_scale: 惩罚强度系数 + allowed_classes: 允许出现在外圈的类别列表 返回: loss: 标量损失值 @@ -62,12 +61,12 @@ def outer_border_constraint_loss(pred: torch.Tensor, allowed_classes=[0, 1, 2, 3 return loss_unallowed -def inner_constraint_loss(pred: torch.Tensor, allowed=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13]): +def inner_constraint_loss(pred: torch.Tensor, allowed=list(range(0, 30))): """限定内部允许出现的图块种类 Args: pred (torch.Tensor): 模型输出的概率分布 [B, C, H, W] - unallowed (list, optional): 在地图中部(处最外圈)允许出现的图块种类. Defaults to [11]. + allowed (list, optional): 在地图中部(除最外圈)允许出现的图块种类 """ B, C, H, W = pred.shape @@ -100,7 +99,7 @@ def _create_distance_kernel(size): def entrance_constraint_loss( pred: torch.Tensor, - entrance_classes=[10, 11], # 假设10是楼梯,11是箭头 + entrance_classes=[29, 30], min_distance=9, presence_threshold=0.8, lambda_presence=1.0, diff --git a/ginka/train_wgan.py b/ginka/train_wgan.py index 02ce124..1f7ecc7 100644 --- a/ginka/train_wgan.py +++ b/ginka/train_wgan.py @@ -17,14 +17,22 @@ from shared.image import matrix_to_image_cv # 标签定义: # 0. 蓝海, 1. 红海, 2: 室内, 3. 野外, 4. 左右对称, 5. 上下对称, 6. 伪对称, 7. 咸鱼层, -# 8. 剧情层, 9. 水层, 10. 爽塔, 11. Boss层, 12. 纯Boss层, 13. 多房间, 14. 多走廊, 15. 道具塔 +# 8. 剧情层, 9. 水层, 10. 爽塔, 11. Boss层, 12. 纯Boss层, 13. 多房间, 14. 多走廊, 15. 道具风 +# 16. 区域入口, 17. 区域连接, 18. 有机关门, 19. 道具层, 20. 斜向对称, 21. 左右通道, 22. 上下通道, 23. 多机关门 +# 24. 中心对称, 25. 部分对称, 26. 鱼骨 # 标量值定义: # 0. 整体密度,非空白图块/地图面积,空白图块还包括装饰图块 -# 1. 怪物密度,怪物数量/地图面积 -# 2. 资源密度,资源数量/地图面积 +# 1. 墙体密度,墙壁/地图面积 +# 2. 装饰密度,装饰数量/地图面积 # 3. 门密度,门数量/地图面积 -# 4. 入口数量 +# 4. 怪物密度,怪物数量/地图面积 +# 5. 资源密度,资源数量/地图面积 +# 6. 宝石密度,宝石数量/地图面积 +# 7. 血瓶密度,血瓶数量/地图面积 +# 8. 钥匙密度,钥匙数量/地图面积 +# 9. 道具数量 +# 10. 入口数量 # 图块定义: # 0. 空地, 1. 墙壁, 2. 装饰(用于野外装饰,视为空地), diff --git a/ginka/validate.py b/ginka/validate.py index c82e6d0..2e61bd6 100644 --- a/ginka/validate.py +++ b/ginka/validate.py @@ -6,10 +6,10 @@ import torch import torch.nn.functional as F from torch_geometric.loader import DataLoader from tqdm import tqdm -from minamo.model.model import MinamoModel +from .critic.model import MinamoModel from .dataset import GinkaDataset -from .model.loss import GinkaLoss -from .model.model import GinkaModel +from .generator.loss import GinkaLoss +from .generator.model import GinkaModel from shared.image import matrix_to_image_cv device = torch.device("cuda" if torch.cuda.is_available() else "cpu") diff --git a/shared/image.py b/shared/image.py index 364e6ae..039d1d0 100644 --- a/shared/image.py +++ b/shared/image.py @@ -26,15 +26,15 @@ def matrix_to_image_cv(map_matrix, tile_set, tile_size=32): if '0' in tile_set: canvas[y:y+tile_size, x:x+tile_size] = tile_set['0'][:, :, :3] # 仅填充 RGB - if tile_index == '11': + if tile_index == '30': if row == 0: - tile_index = '11_1' + tile_index = '30_1' elif row == W - 1: - tile_index = '11_3' + tile_index = '30_3' elif col == 0: - tile_index = '11_2' + tile_index = '30_2' elif col == H - 1: - tile_index = '11_4' + tile_index = '30_4' # 叠加其他透明图块 if tile_index in tile_set and tile_index != 0: diff --git a/tiles/10.png b/tiles/10.png index d2eb5330f889f6e52154bd6775324ac93f888048..08409ab09b4e91217dd91817ad4fa93113bbdb0b 100644 GIT binary patch delta 367 zcmV-#0g(Q?1(pMlFnMDBSFzt2Gw0j$X6YHpz~n}0DG>V6dgY- zhu9@0v24WiK#yKo=XV0Q(QO#vN%TZS*US3ZtjNs(?3+zOu02EWvBMNB zO+VhV3P6{m<=E)}sRm$(DKDkm6Z|x#HSgj;lEW9iXez-4z2vVqz#C=&Eii)4SFr#9 N002ovPDHLkV1kFor;-2w delta 663 zcmV;I0%-k~1G@!~Fnlzc zXy`0a!2fXtv>*gXK#K&$NpzPcsjs*$5~1K_1Ky1W#V3oq1HaI1Lt`_aXTF)S3B2n?j%X_{2zv4@Mg2Q1OV>&=KmQZ)oS%CW9(iOMSs~#7LUgxaL)fyO26y6 zzV-#6Y1#)$=}%dfKdY)rD5b6#_WL~yheOzGHVeksmsYE_@&!<@*HZxSST2_n@p#-- zaQmY5dJXM%dvQ1%f&)}4l|&>G@dRKP26Q@|#df>(1#l9NQksfJqYuSmQSl03nkIC+ zU0)d>wOZ|yWq(=slv0Hdawm$S=Mtg^yWP&a1AfJG)(4+{Fc^Son%)6|h-X7!{oCz! zFaST|1qBE!o(R^&YPE9L1vWqs@tgqIg1KDIRR*y3vVUosDOr|(l}aVg6YqRJV+s2G zzN-v`DjtHMe0T&wxb8rh;$cv1JzT-~9#AM0U^bhN# zc)JV26z^O>Y{5$z2wglU019|11JCbx@pxPT067wgcwV*V=5x*g*DwCYVzE;TPN&nC z4umb9bAR?b1)R_4kWQyxI&cf|UK22z&Ay(2TLRz!!U>21Ud+JpczjGG5(!mRPtz)_ zV^2U)6i*IJCKJBhZl44}`1br=fDQTa9V{4V6R|%5^~O$jIke$M&pn3%jndC xhG7IY|61lGN#eS$Z!kDsd-H(TfZiS8AKKmtKM>joJsIEcgHb diff --git a/tiles/11.png b/tiles/11.png new file mode 100644 index 0000000000000000000000000000000000000000..378a738951be173e5da59a72f9534c99a3d784ae GIT binary patch literal 291 zcmV+;0o?wHP)Px#-AP12R9Hvtm(dY}FbF_#mCTY^>5DeEZL#F_Y>G3V$4e>_+ zAp%U(Ck6OG_0g{eiu<5@4eYgIw;JfyhIo+aMMROBUd1JZW)?{10DikU3(9<(j^jEV pdxa>CoZeR%IO89}0o;HaSOE`f$06@3cl-bV002ovPDHLkV1mLrZ<7E3 literal 0 HcmV?d00001 diff --git a/tiles/12.png b/tiles/12.png index 7f6a74b70e2c6823ecc81a85d6dda6edb245146b..c2330ecde5e924ab4963dd2b7f7e9f9838028ae5 100644 GIT binary patch delta 301 zcmV+|0n+}Q1JweMF@Fz9L_t(oN9~r;4TCTYM8hhXC9}|37=f-*X2~k847$p)9GtjS zA|(2Sir}8_Y=43af z{DPlQ;I_cu)3YZS^&eX( z6@kqAuMwcMp-rekz{+l8$RTjueG&0FMaj7RbT$jVBG#y@XdY^d~XrJvvKS;DV ztbMN)f&W|%$R_EiId)4BKLMOoR(tOTxE=Tan=jKLVf|B|00000NkvXXu0mjf(|Clb delta 372 zcmV-)0gL|C0-OVoF@IJ`L_t(oN9~vE4TCTYgkcqC$t>+m?JSvvRazP8q^s-L4j`gR zf`~{;XY2r3XW}l;UQs*1FlVAR&MjUf0zHSe9k8 zXF*&55r@YRhCqu#j}s6t8chI*>jkp_JkNtL0azS@^5*bs5PxmMx4dO+3nB#o@g4x4 z(*>Zt=Y@C&h)0NmfLXQ-#8(8Y@UsA_yH$h$(SWTed;ny;mxWnGK=@k&L{ZoU;2i{~ z1BjTUpp|FXTQ$J*tu%xYfVY6aceD-Jj=6^b;7JyM({vg@v;!cj8`dcRyse^3jINh7 zfGlinMRYelmTfHvK7P50dB<^h5OFaf3ay4@?H12_aU$Id;IWsAp3q~x6o3rYk+4$0 z#doM1>RMocOYQ^kZs?7OA-LgOdMD&O54#oXVjK2f5S@N|?csmH-i5RC{s3=)RM;>; S(=lcM0000dyLc_CZ?EH0t|0E7T|Az{qjR-9^7K#`U zW`t!PBpr}VcwHXo(Tf9#cEchr&zJxhA_fqf6{!{sU^9S*;IiZ6nddCvasb2}j-0a7 z{ln#ehNyBVWeENnYs@ck;LwLp+{g;S3BALsH^3X6{arA>nyOL&00000fhdH1ET|wF@If2L_t(oN9~r|5rQxjL_-O-kQQjc7H9!m(Gs8pXu%d}ffg)5 z=VoS^^`esp$>fLp$be)|_P%IL<<(TyHzz={1KrTQIehbNPTDK!B@wsRi&>v9$AIe; zh-d(ax7M0@T%0(T0L4N?0kF7;0zhD7E$ixBiGc_P(Bcr3Uw;6kKm-B&6XzUY2ywbA_S`ue*uweeun@1Ac6q8zICFUY!GDIQ4I{14L}Rs?XUsO=CN}{9)=`j zumhW=<6@?M`V!Z0F=crOKu(UO^P;!|EMCQdssK_IdKC=;mz-|D+!4_avL~T#GP(!o z{!j#fE!QVS#&j2JM7%M2K9AyG)@N(QvJuY%J$mIie-prsY{LjA(Gw9_?*MPx#+et)0R9Hvtm(dM_FboCFDp`RQ(h-;iMqnpqV1=yG>Iu0@BS`E@#H#8@{6T!a z*s&PMcn!w!$pPHJ?-^Lv?OE%bWqGKQQoW4eA%tq@rj$qnAqL>!5&#W^2!ORCxD)`I zBqo{wxprhG0pNEeCaM6Xc5H~Jwo1Sj#8&_aGEGM@?mNAq&J5iGFwgNr0z>={K#Y;b z@sNP*vA90E)j%GI3$xo1T(x31fNpJwK&BTFXKH#C=Mb7%AejT$yEzN;^EMsF<#AjU nqBL{4S53 literal 0 HcmV?d00001 diff --git a/tiles/15.png b/tiles/15.png new file mode 100644 index 0000000000000000000000000000000000000000..56ecb3f4efa745fa75f1f36940ede8d76c865f3b GIT binary patch literal 344 zcmV-e0jK_nP)Px$5=lfsR9HvtmC*^qFbqVKRWge^Q!+w!>I_-ItF$QLKnU5gRIn+yUkSmzr_)JZ zm%+bvu>LXu{@a1`e19lI$MFgm5w5NpL>a}~=AXXtfY3TEUQ4m+ShSo>bO$lu*9 qkfEe^PtPUHPXM*bTE9(z>A)9EO!Xm5TOJ1h0000Px$T}ebiR9HvtmfI16Fcd^X3AT_HXu%d}0b9`$paf{a7HEMMEJ5dHW|{S(lLyJ< zhy2KZWKZ_KXiVkRRMs~qK(Yhf(7ic)^KDMrE9oT>x7UkVpD)LN>lBD+0EoBNnt5ED zIFRgF|2nNvN5R_j4q(B4#{1fLKUITVnXUI2(A&LRY> z5q|-ZYkr3R`yhe3ze)AXyfGyW2MaCCv zM7%M2K9AyG)@N(QvJuY%J$mIie-prsY{LjA(Gw9_?*MQYH>V?fCoT5~;@NcPSR_aOIonO&Wtlbm6mBsZ zoSqso<%89OdvmLKmRK}tupelWeNvqy%TT0hsOWfs@x(#CPm+d#48hJm9uG(+Q|H*wgW!?7vDfm>;YKl>I9w=x#ZQbxnC3@37$N*Rl4 z_%lj-}@O1TaS?83{1OP+g BY%u@; literal 0 HcmV?d00001 diff --git a/tiles/18.png b/tiles/18.png new file mode 100644 index 0000000000000000000000000000000000000000..b092cb4b79a1aa3dbf6cf15735581fae387f0036 GIT binary patch literal 358 zcmV-s0h#`ZP)Px$AW1|)R9Hvtm$41PKnz7MD=K@1*;pbj8d&UBanJaAAU zLU0H8vm7^)0KDf?l@vk(vmjIeEpXW9akxb7b2!E+u$)Ut8|?1$CI zeanGj0C>S_0q^%uTY#lC4WR^qR#qEB3W4|47ZIIvY)SQ1tYw12RXL2b>F|of@0n+T z^x59@gG6eFweM5^JzNg(>Bu>DHHfbOQkCUCn*nAA-c-i*A?Zetp8x;=07*qoM6N<$ Ef<=vw{Qv*} literal 0 HcmV?d00001 diff --git a/tiles/19.png b/tiles/19.png new file mode 100644 index 0000000000000000000000000000000000000000..b12132365b9d588c47f337fa0e75ccc04ad94298 GIT binary patch literal 441 zcmV;q0Y?6bP)Px$b4f%&R9Hvtm(dl2APhz02wlMy=m^fDBRGR2lvz4LS-}-L0zDCj zahwQ%+dCInE(h&7JFKi!GS-( z-+>=HfLCyMhNf%izsmBPz`g|}?8|LINM1x1K>XBW1sF@D|3GmbrX+wbuDm)NK0N@< zalfZS!UDj}IO0<}DmCWFL4eTdw@$un5D=K-Lev2&IybGMd_16UnlGLA)B~*hlPmyO zc5m8=mSs77_I8g8&C?+0gnzSfk!3eW_7oo zjUwC3o z0T4Vi!U>RO+&zdQuxT(jl?QGOSAzh!5rI}Kho;;!h(RLlaQ=S3?H*mZ1nc!W|Bq9Y zPRd%sDNpKczke;6?X}%*O$SOfjoyP&)9KX8)5=yWm~=cIM?zF$1>cjZJb5i+r7}_% zLJUMG=0;RK@ENE3k8=hNpl1w3sZu4=lay=~XkM0mCQJiT`VD}Z9y#HO71`JvDP$iY z7+duYS#Ua?`iMrJlC9C1p}wDYN;{^OUm|bqtcS8Hh5f&p4kh?Z8{`RiEK@4X$DYz zh=!EtUCsa-hBly@;85pPMRk^7Q&QYu@7wK``-1uM87K)3G6OIw8$2jAVA51=JfQJB z!a&GXnSU8unBXME5|)}=9szV7&=W*DuT)cHGc!bfjjsN`TmsH>I-J0v)-vMvH=K{~ z!gXoC-`h}%i-wEEBJ;f!0JEa1N2=+Ns-<8StRJWnk|xSkY=VHaB&u-AdDu=S6SJ+! z`=ICe0I;FfTG31zaRZL#ehy?dO=|x>UWgArXMg5y$cVj`D=;-M?UL%qH!(W&SYdfG z2=N(Zyp%Bu&v?JtY&v`k0PQS=sv3jj9^|{?0%bg(&m)3_-vwTF{VE+sTQdN40Ri9u z+Mu!!>3|V|EfOEE8BvhL20`oP*#ZC!eN>cPO<^Rv{J-=81BW;{^#t~$_&^D@&%;Ou qO(pGo{tKt1d|DRrU-u-n@$LtUxA=O7zd$(v0000t`}Re21~daEWsA6MOx9xL!1zj z@E3+t9-YJeHjoWlSiH8y`r-cpUXSBVs~lqtm)reoe0l{=1F-LV0Qb`?z#T*RK^)c+ z081R8-0uLbKuLTmK#jN?06+Iy@hJc;;zfYxaZN%51BC`j>wlT^=oc>`3Zomo3EBx4 ze$(n4_h$egPK7xH73UCApO=PR0zkzz_ZTQ1;@KTQ083nQgjL}&TXLTO)VkLIdc;M5 zR`*)Q*SI$Utji{Kg=+=qnQHCE9~tfdS_Pyd>S@0$2YCPg48TYWsyTq=u_Bj#(|i6! z0DjxGSat&dK|+2P;5Ta?jEJk_xHJvvJfNewHhk!J=9^G^55OOc3ajI|$HmAV_g8T% b%yNJaO-mXu%jmJ)00000NkvXXu0mjfE1Qu0 diff --git a/tiles/20.png b/tiles/20.png new file mode 100644 index 0000000000000000000000000000000000000000..dd9a8c510ca36a5271c8b6a88fc9dfcfd2a8f38c GIT binary patch literal 442 zcmV;r0Y(0aP)Px$bV)=(R9HvtmR%KtFbsu*gjuMCP68INfQ4zm0v2YW5{3mVAfY><1UlBAWOU_Ra+yi|4BsE-znA0clYxwmf_$j_XA!AVF)b9jNMHt4L||g#ZXkmU~)N zz=1!&-+>=HfJbn?hSp=~-^%inz&-^e?90UYp)N7 zqX(cl?t4BZECAe$BfgfS)=P~X1PDbRi+uk;KwypwNe8Iu7&F1`RzugB7oEDk1Ro~z ztDpn`wq0YKs8VYF9mg>$N*`#hQd71Lk`71#NZ2RD|5B$R3xE;Fq7Dh}?I{9~^*k}* z5CHCrY2f5N#E=tby@;d$O{3s`cZFI6fa?MZLIC26wYflGw0@04_AuKRev;Y7A07*qoM6N<$g1aWO^Z)<= literal 0 HcmV?d00001 diff --git a/tiles/21.png b/tiles/21.png new file mode 100644 index 0000000000000000000000000000000000000000..d9fe4bf7c3373f968a525da118b4f6bf6ee13902 GIT binary patch literal 448 zcmV;x0YCnUP)Px$dPzhh!1jOsk}Z+J!XsN)AH)DvWsFka*jn4~@;npmDVmJp02<1&^cq(b1pp`!#3%q% z??YH|95Vvo_SOX)jpwZwHZHSVA|ifu0LPT)1WB*Ky&r=5Y2<215yAI{FnZ{3FPFQXV@;;fEH43HfGj0H{tz;*$JaR|g&4v_cMj>p1*r%qms+yveHQ-Iu+(ONJn`vi*?2Y3U4+vyPx$Zb?KzR9Hvtm(dl%APhy*5nQ1w#8q4YS8xPZkeOtKuFw(iM4A>`3Q48*M?Nd? zE-!(^1`Zz0!TO*Ecs{*HTw*&HzMapFYERW<5(jW#txXzdi~#^tL2Lpb^*KZkr?Ddd zZ692qF?c?D5#q9I2w00lF~wn;P1qc2Be+Pc- z0A0cNGc;bq_*K^51o16k;aF}BLh~Yu0P?3ED!@=8;|EIeFckq}ag6G4`t$%iC;VOx zi3or;lZcP$h&bfPmjJ2Lubq6}AP}&`g{%WybSzkS-~+Di`k`Zhdw^wsQU!p@u7x0q z?J0BtUB6VDec`#-U5a^-bwCTi!XGa~ch5E{MF7{{R!^N0T;xIxfTHJ_3HS{F?Mq=G z7q*O&xTqu20+`bsY#)HD07zXRVHz57kppZ!x8tR7(5b5zqd5N4|AKT@ND5HAvRDhY eB%fx@;Q%kFzv>}Ut!6O*0000Px$dPzhblj-&FXL?xw zJCLwtq$*ot!2qNN(FDLt=P(+`9Yi+(U;q+@7zV&WA`n9XzTWBBu0QEbIr#`FwL|7% z7y!hfszGRZ7ytQ{_t)0PLXadm0sdD;CamxkdAPf){*Ia0Jpj8|$@En94=n)sc8*IfYUAtW8g>Imy=Fqb*N`)?gA-pah| qJ_ZpW{=0Gjx+bBwnwE8s1N;FqAv7@R56cGt0000Px%JxN4CR9Hvtmf?+~Fc5_&x->uwZs1PxmEaak2}ud0gir!0;b`D~xCOUB3n^h& z&)H`UU~(jvDElKwks$`pH*cN?HuBhH=GeC*}jrCGhRf>H+pVK);YpqDrNQ_b1`u9T=DFPT{WM|wcI3P^d zrQiU;h_dvDI*W8qc@_b%s)mTp3BVYfQ9}sghd~bEbeAGU04|PzIDB=Hei|GK*bqj| z^j44&01T+>&&B-lk9hBs?D|0VF2?K^J+~Gl15AVK#UOuDLO~#V)A!k+yr1U9{NGw06Y{h%Li0+@p6U4uEwud~JfUDwU} z0U_=JSOVepW3Rxd-yfx3@LvE$kgp!_uMWs(9|AA~@t1mEdkH-SVAL8{UOZHRl`%)R dy#ZdXz$XrTelR}js#^d6002ovPDHLkV1kZB92)=t literal 0 HcmV?d00001 diff --git a/tiles/25.png b/tiles/25.png new file mode 100644 index 0000000000000000000000000000000000000000..aee20bfbf5ab936977ec7020523dcf16bd7fa3d2 GIT binary patch literal 389 zcmV;00eb$4P)Px$KS@MER9HvVmg^0|Fbss#RWeIfV1=&042;mOzzSKRD`XYWAzV3-heMoJ`f$p2V?1&*}mo z2R#5yJ;2>_@zzps*Brju11SKATWiH3gb<>-ive=(#mekO9(xx+i*pFUeNG(Dvn9y6 z2Y?g;;_3jc@t53Z6DYZt0@R$-KFJcK0Hm=~-SJytjT<##Y36efO^6+UZaX;V?;&QsypMf?7zV(_mt`^AwwZNZUo;$IH~_@4 z0DuLELjmS_j%si?0MrTMuo6I&zJgK{YSuq_4&cw!b!)^IP@IOJhljTF;xv?wT#fgt jmr@N8@liZlEVcg=!SWC=xXy}B00000NkvXXu0mjfv-YMr literal 0 HcmV?d00001 diff --git a/tiles/26.png b/tiles/26.png new file mode 100644 index 0000000000000000000000000000000000000000..1329097ec6ef38d770056727124cb1929db8e720 GIT binary patch literal 353 zcmV-n0iOPeP)Px$8%ab#R9HvtmeCD^FbqVKQJ^C*10%2tBd`l2FhfQtj6!vhOs!C2C$x$xg&zdA zx#u$pSX210h4oDZs18&I{?CEg&HL5fF?2(6L+S!9+_vqBVO`hbUJ8f`fW$uuha?1| zg%AN!#0e$^A_~C8_vd@`_Hix?<5~z20Jh`dUDq9MJLe3CxQYWp8pS05b>HmGA>Q}B zhgg=y5Cn~pM{e@;%a134nGnhH=IDDJ=u>7Ljj0_o5=00000NkvXXu0mjfo%)eN literal 0 HcmV?d00001 diff --git a/tiles/27.png b/tiles/27.png new file mode 100644 index 0000000000000000000000000000000000000000..2e564fdbad4432bacf7076cf32e36b25bacc4bd3 GIT binary patch literal 382 zcmV-^0fGLBP)Px$I7vi7R9Hvtmfa15Fbssl2wi~{vI49^XDX|}3ar2i9ii1x9Wp5~PC()%yimzW z@5}ioRPN@dx>?^9fZ{-LAj^SQ*L-5_`|QW0|4dp;;l|a`@iDr2iCIC+01%hLb-jg{ z=btbifLI_*08%^@mZE?_oG=!MLjbEdK~f=9fYA1L*R2QkwxQ`2nX7AMRA5cl4% z0@E}(2?6oFI3ToCL;>XKDc-j23NQ?VBLv0w;*Y*x_QW6#0Z>#@0KyQ80fh0(0ce5M z0i;PwgUJDi#&S#`tp-k|0GrwSVU>q%5bJ_00Bm9*YQtx*|2d5K&gudQAYIVDA>|OV zPQ=S5VU9Qsa|jSRK?g#c<%v@+BohE3@Yb$kDU9Ej-G(yn+Q$gjS%kUP?0{B$XJQ4Q cIB>fIU*dfYFdiP%WdHyG07*qoM6N<$f;4EKTL1t6 literal 0 HcmV?d00001 diff --git a/tiles/28.png b/tiles/28.png new file mode 100644 index 0000000000000000000000000000000000000000..9404de637c5ec192431f79fe950e6ccba90c96bf GIT binary patch literal 453 zcmV;$0XqJPP)Px$e@R3^R9Hvtmc5a}Fc5`B2OdfwyFSh(kkJQ}09`mByApJLkdZlM+`-+vn_1l( zq5UxgPVB_ki}b#I(yqKo3tyXs_0tNlIz!UJ~LIDW5v^dYva-j*p*>mQ7 z|8H^5IgR6(uGd@1T#Exjb3p}YWe))e%e@8Aid!zs1`x}KVfg#0Il%F^0Hl<7jgh&C zxAp+Xu~E4s>wVxl00GoLcKPA(Q8pbiudARH7ja1>41fV*oire>bFU9@=2k-rm7%y` zor0~FEG=5g9`D1A$byK7V|=&|NT%LFBt2g{jNU#AFu^NFu_WLfMCKCkdPhG-YGKWG vp4F*>sFH-00000NkvXXu0mjf%gD!( literal 0 HcmV?d00001 diff --git a/tiles/29.png b/tiles/29.png new file mode 100644 index 0000000000000000000000000000000000000000..d2eb5330f889f6e52154bd6775324ac93f888048 GIT binary patch literal 699 zcmV;s0!00ZP)Px%bxA})R9HvFmphNzKoEduOWdq)g2E`|fy92+_Z9`)-pJ%?Au?f8MA@3X?f&dUr)9xfm z^86o$Ven?NxdZ_2`R4x_Bh_m4D`V_l6h+xf7LUgxaL)fyO26y6zV-#6Y1#)$=}%df zKdY)rD5b6#_WL~yheOzGHVeksmsYE_@&!<@*HZxSST2_n@p#--aQmY5dJXM%dvQ1% zf&)}4l|&>G@dRKP26Q@|#df>(1#l9NQksfJqYuSmQSl03nkIC+U0)d>wOZ|yWm)%> zQiTw5CyJuy5~2sY-OjrMe#LXv2cLd07=US--T{J$XG389+wFER06*dd1qdvj4dAB) zp@?S#91aJtEX#cfP&`7&?_@Ih5htG4mU9Y-^&gE!kk98~JRZAi!!X2i*1yx~06xTO zwQ|=5Hb4;ZoB-H@xm?aw2C(+BX__fnmVcE>CC?M@d_H3d`u)DE41_8kf}nhO1VOm& zK$zlTP;5P1!T26fC=_5eo56CqeA|IA#dEIUUatp=qCh5-!ESiF3&IrdTtIBWOBo1V zJSPAOcqs$V?|AWeTmb+%5{Yji{>EalQwvU~)0Yl}EuM4sI|ZE2=a5dP zUpjCL@m>=!o6WwSfm;IL0Ky4~0$$9(@pybpBoYZ#RZr6@tYc3=Q4~)OOePb)-EN-* zLHPFkU4RYACxuoxP{7kG0Z{-4S|Jjhq!peV zF=!as*&mP#T!3ABJnQvuyUqP`IqYuuo%_B0J9j4AqWc8U_kEV_X_{QQQhhr>2lh}- zfxx(usMVhdsB-FrN}@&oK>#4*IEL3?GLSP8AQG*6K*KQ1%YV>+B4EZL;3?ZajClmG zmcp?8MFO4|OsRyx5=IsQ4n|{JLmPHkd0~7^Ij8ysQRe^`yY9unE)!+&+ln-J?>}QOib5p zkK^ZM1U#2}oqO@+1h|3l={4Qnas_HI)vmojZMuRbw;S+V({S}dw0bGVeSX{V$3378 zrG`L+k!(iMSX?s?C>91^cPKUC)y8sdE}j>>S%CF)KWCO$|7m6{^?ew{fHt1!gt_|j g;}pUzPwW=menAv1=nBhkl zUi2kSNZ8N4W6#A*zLv@Q<_2hXz_0Gb<$LT$(_T$~5^-m&IZTKQxNm`|27tJ=*6iVk z;bv^qkGO`b zIhNM|w(SF=`(nHUBtFN1sQ}g`uMtB_z(-EUFDD}MpnDVQkkJ{S^I-@8d#;}p9X~9H zcw=NfkK!}yyJtnQY{c_Gk6u~lcLKQ4Z5ZK6^h8A0%lg@@$jt!kn@vKlJwx!Z!xSt{ zKi;znK$oNC*y#YN24ILOFQwcQ{4}LC@8Up`!xz42D!~Q4b%7 M07*qoM6N<$f@(9TegFUf diff --git a/tiles/11_1.png b/tiles/30_1.png similarity index 100% rename from tiles/11_1.png rename to tiles/30_1.png diff --git a/tiles/11_2.png b/tiles/30_2.png similarity index 100% rename from tiles/11_2.png rename to tiles/30_2.png diff --git a/tiles/11_3.png b/tiles/30_3.png similarity index 100% rename from tiles/11_3.png rename to tiles/30_3.png diff --git a/tiles/11_4.png b/tiles/30_4.png similarity index 100% rename from tiles/11_4.png rename to tiles/30_4.png diff --git a/tiles/4.png b/tiles/4.png index 792ed88c56a26fe861b8cc51f302981cd5e0e0de..bd23e079c4e265f9635cd95fddbea4922efb75a9 100644 GIT binary patch delta 380 zcmV-?0fYXG1Ed3xF@Ii3L_t(oN9|YJ4Z<)Cq^oojq_Po0jDQduQHf2u3dj|Qj+5QI zfd0S_kl5#o<5#-P^K&{~@A#ejeLU_ulWoy`1L*rc%l0%)u3V|U9iRhyD5pSRTuIdG z&jeICbwVZ4qW>ZQkZ~NtYcLte83_=H);*wM80KZ@zY#Fw5P$HLZ6C%w0$597*#05` z&kLqhLSP9aivS0sv8^ExVf+acd4Szm5(5ZgPFY-I5dp3VobL?GnSm4o0Z!X00-BBt z2xD3YycFg@F7kk$L{G@ZH0pV;i9l5S)PVhuywOYmm1}?4ZZ7BBY@3Pcy6tiNe2jqS za<4OfoB%fvK6SmO+gGkY4W`<)7pP5Fu;g|F{%RVoUWisN#kkLZJN~%`w4u}xh%l1P zC>o1v<^jdR;Oh>hCcN5MuFb{sf;S7Wp6=(&66-(BjHSL0qZrV}6P++ue}0@oxaEo6 aqWb_hwy0*g8M2T70000 delta 356 zcmV-q0h|7$1B?TZF@Hu$L_t(oN9~r~4TCTYgkcqCNk?E77=fM23ar2?txR?FWKzWr zM0qHAq7-r;=fAW~<<(Z!Z*G8W2d3%y;_!{*BWtg$mqfhlx@KM1jRDs=5N-g7i|9Ph zn>dyLc_CZ?EH0t|0E7T|Az{qjR-9^7K#`U zW`t!PBpr}VcwHXo(Tf9#cEchr&zJxhA_fqf6{!{sU^9S*;IiZ6nddCvasb2}j-0a7 z{ln#ehNyBVWeENnYs@ck;LwLp+{g;S3BALsH^3X6{arA>nyOL&0000 zK+8{+P2JQ0GxIUPV`!Vt?{?~+_#gW{4`XX%OKfKj`lgGDJvPoeF4f*9(1ISuUAGM3 z+&j2J<$B0N&A-svLljj~yT>1FQ=vdjOl5k1Uok34jHM&pSKj zQ=lRR8{S7r05M{uI^a9P#Q?k%Yf1^BVUQw#kosu=7A1u!27q!MuaD+_IZUy6eYM@7 zIa8Yf@T?g?+jlny;0uIjkHDdeiTksTAskfQgq&VqP4LrWSY3#!OEIK%zmET&0liRi z075=iZ^KYooKp{|FBHDsqSOXgE6XjoicCx`z_OfUU;k-lGtl>8XbET&Y~kYgCmq#Izm~&6*>Yv z5u;QQ62JKds>yjfj_|Cfgd}7S8#ZSrfcZG%JQ4Qz6B)g%WXkOUPKl^{M2Iw7)zx8KyeI5U;!`>*HRi}cfY9l;PQGjq5SZga)B!3wH?5(3JfLry zFP-<)1FZX#EPnu4c5m8=mSs77_I;M1& diff --git a/tiles/6.png b/tiles/6.png index 83de73ae0de88d5be609a70e8c9dbae8418fc313..efce63b49e53beeda639d1939871a1688da1cecd 100644 GIT binary patch delta 641 zcmV-{0)G9f1EvL#FnJxK*U3TNmMI0Huk#7Vk% zH$ZQX1hSQJCr;vqJ^|f8o7f)z#?B_?&(qWE7ycjpdpbRA=S`LZZ+F;5@91 zQ$Q;KoOgKA0)bqQ0Pvn8eVjr|fn1gx!Ki{rWzOaMC;(p*rZ?Mw0~G*-MvMs{1(B

dcc_Lthg>#G_h(%oRjhTC8M5qBuh51rc4FLd=4eXEKT& z2N<8qmVN`kg;S&eQsgZn!Sg~ogj*EtYfRerW<7=J|oUa3*yhT``;yabFVu}F6{ z4SSch!iiLT-Yo?gh#yE{3YgV;01#q3_eDs8%%+jPq6jeyio9iMgp~^`Y{T5^Rtue4 zssThqgau`rjI4Me5gXQ~ZgJr#{0$XTL4vk_OvT-CdR%lZ>rF!*T9Qs);WSFusJI%( zPRYnV5PFW|5J2{hneLhg2(cD1)zD1~3G(zSD;aSJgT8FV7&HT$akmBr$GOx723EP2 zQ{VgQrwcNK!^}uLErui`8(M&@~$*lJ<@!pQia*^>wG%Clk|Nl5e=+`{4 b*T{YYV;VYUuG60L00000NkvXXu0mjf|34$^ delta 387 zcmV-}0et?Z1*!v(Fn z95HAZ+1VeE3tWI*dpzs)Z@bO?b2;p8_?`Q`{X2Ii+oJmf(D!|o?P;1^xl(;QKnM0v zPJzIb+7K8$$; zu$IEG{Y3(v7fh*yz!F9l0S-oETSFki_!21c0K2gy1`x!Yvbe?~0$dX~-x-)Q11Saq zoVHa2G#wcb#=!4|AVTG7cvoDh=m z7lu7cU_SqZ_^n+6fna z)9M`eX8<5hg*gNj=MYk#mxf&eK*crp7$_d%*&RRtOI&hH7c>n(lz(@7GYMEz_^^fbO$De9R0sagf!WRb)!s35Lvlmv0xsOP?TKMs*W+Fa zhzfwjKM98<1fqoy0aC;XCIuo2z{U6Hd-V2kE(_yY2oV6b}h)mPufkFUWkK^d!ehQG{0LCPZ zL399uciw?pBS0~&{oGZM4S+(th?>oZuYcsjb~~pM{e@;%a134nGnhH=IDDJ=u>7Ljj0_o5=00000 LNkvXXu0mjfhOmpV diff --git a/tiles/8.png b/tiles/8.png index 2e564fdbad4432bacf7076cf32e36b25bacc4bd3..9e5888f7166643649c78790ca450ee472cbf89ff 100644 GIT binary patch delta 325 zcmV-L0lNPF0__5jF@GmXL_t(oN8Ogo5yK!1L~$$bB|W(W*WwmZOK2q-9h4D55nujt9vcu zYuuXv)@75r!nFeQOtp67j|_JJtpd^!^|W7>1HAwL24JKG)f~X`SdmM=={^4<0Ke^8 zEV}`KAioRnn?5xUM#R-|T$+Y-9?;QT8$R?q^G&F|2jCAzh1GG~<6>lw`>VJWW;wtI X_tP3MY#~JB00000NkvXXu0mjfxXqK5 delta 342 zcmV-c0jd7&0{#M!F@HEoL_t(oN9~r~4TCTYgu@73ffcd>tU_lhtH27ZzzQ9q)lnTX zDKSn!;w8LL$w}|a`6pEF=BK(@-xYx3Kye_;fmhdjV(t6v$E5#ET1?@_)zR@Wx_OCN zLCgRUm%??ug_!4`Fdu+eAWQ&KJQS9qfIyru7KlRtt2jYYA%9eW(DrxNtq1nw_*Vy0 z(`@1vC(Hm4_uj7p(=<5=0r9;!Ahc9O0p#f^-nQ)uFbsnu1jYB_kG@~_#2^jw+u*Y+@m5!)LGmIgI$u z>H-NMUC_QEfIU*dfYFdiP%WdHyG07*qoM6N<$g05Ve0RR91 diff --git a/tiles/9.png b/tiles/9.png index 9404de637c5ec192431f79fe950e6ccba90c96bf..d106e37cdf4ce9d948c3fa0d03209b2dd33b14bf 100644 GIT binary patch delta 337 zcmV-X0j~bV1Nj1wF@G~jL_t(oN9~sD4Z|P|gq>B=RWeIDQ!`6eDXX-yDn}Ow3X4!{{eu-QCK#XAGntFIxBv#0L8U1iXudbco4u6_gNx9y3MAH`ptsW=tBT! z#CI7GfZXUqJw7FR6TmubdUM~9DFQ%GL*=FqWmO9#A{_;nr_Z9Q84yuyHkgI411Kp$ zvk~!2tL0*6JWA_-6d=@cbz80mz#HpXz|X9CP$GWFfJ7FXhG-9t=G5B9@60=4=sv(3 jlnM((^-F1P7XAQlGTHedY}oj%00000NkvXXu0mjfq6(Je delta 414 zcmV;P0b&060>uN6F@JwaL_t(oN9~rqk-{(#g+&J*N+7#F&Lxo12b2I^I3T+cbbXMK zIc40z-MpJw-5a6(F$7NR#Mq1UzJ1cJyh#gRn}zk$3a~n`IxyRT^Ev-`rF%N{;d#S< zWa0b$OJ&&Y_9Yep2?2<>C0r8;hzH>Uw8XovD|*v3B|P(8f`1VR6QCAnVa~XQKn(A2 zc@QoD+s^Czc;u&ju-*3MT|G`)3KgKv9^%L2XA!tuz7s=0yp9Wm<$?*o6Y%6h0SLLY zIM2~?p$Wj*bLM^jZ*k5!jpLZE*IUV4ivvP)K?P`K4*>|vy#>&UTQ1B75X*;Q`1`3j z!11>Lq?CA#k$<^}xAp+Xu~E4s>wVxl00GoLcKPA(Q8pbiudARH7ja1>41fV*oire> zbFU9@=2k-rm7%y`or0~FEG=5g9`D1A$byK7V|=&|NT%LFBt2g{jNU#AFu^NFu_WLf zMCKCkdPhG-YGKWGp4Px$SV=@dR9HvtmcbE%Fc3vU37oVdTEGih2`6d9@uDrzkta*QS(xv97aTSrnOw+4 zM=<~Kck`FRWnM*QeYXPyJMg%$#00c(X`_+!F_&}Hev^WIi696F)CV+q9+ye|D&d9Pju?hfj)LDdJHR>-Q z@|~~Y{xt{_K;2BD+-wkJ+i@BgEE<3oDvuNcLpO6p?zc3g*#SJg)VDtWifcHZW4R4r z=)PsqeUaV)63^p6R)A(oK3+*nz(-EUFDD}MAbJz(kkJ{S^C1ZU+pV7z9iJ?Scw=Nf zkK!fkqeZc7#PdLpUb)Wi1aKqTFv64QiHNS3>r1m@Z3bZ9)g{<;Hv0DMvvFkP1gYXATM07*qo IM6N<$f_^NkHvj+t literal 0 HcmV?d00001