From 8966870a05b85ea940a02c4646693ec101ab0575 Mon Sep 17 00:00:00 2001 From: Lupin1998 <1070535169@qq.com> Date: Sat, 15 Oct 2022 04:48:52 +0800 Subject: [PATCH] fix update of issue #25 --- README.md | 3 +- .../imagenet/basic_tta_sz224_4xbs64.py | 64 +++ .../imagenet/deit3_ft_sz224_8xbs128.py | 83 ++++ .../datasets/imagenet/deit3_sz160_8xbs128.py | 64 +++ .../datasets/imagenet/deit3_sz192_8xbs128.py | 64 +++ .../datasets/imagenet/deit3_sz224_8xbs128.py | 64 +++ .../models/deit3/deit3_base_p16_sz192.py | 24 + .../models/deit3/deit3_huge_p16_sz160.py | 24 + .../models/deit3/deit3_large_p16_sz192.py | 24 + .../models/deit3/deit3_small_p16_sz224.py | 24 + ...6_a2_near_lam_cat_switch0_8_8x128_ep300.py | 4 +- ...m_cat_switch0_8_att_ln_8x128_fp16_ep300.py | 4 +- ...2_near_lam_cat_swch0_8_8x128_fp16_ep300.py | 122 +++++ ...am_cat_swch0_8_attn_ln_8x128_fp16_ep300.py | 122 +++++ .../classification/imagenet/deit3/README.md | 38 ++ .../deit3_base_sz192_8xb128_accu2_ep800.py | 43 ++ .../deit3/deit3_base_sz224_ft_4xb128_ep20.py | 53 ++ .../deit3_huge_sz160_8xb64_accu4_ep800.py | 43 ++ .../deit3/deit3_huge_sz224_ft_8xb64_ep20.py | 55 +++ .../deit3_large_sz192_8xb128_accu2_ep800.py | 43 ++ .../deit3/deit3_large_sz224_ft_8xb64_ep20.py | 53 ++ .../deit3/deit3_small_sz224_8xb256_ep800.py | 43 ++ .../resnet/resnet101_4xb64_step_ep100.py | 4 + .../resnet/resnet154_4xb64_step_ep100.py | 4 + .../resnet/resnet18_4xb64_cos_ep100.py | 35 ++ .../resnet/resnet18_4xb64_step_ep100.py | 35 ++ .../resnet/resnet34_4xb64_step_ep100.py | 4 + .../resnet/resnet50_4xb64_cos_ep100.py | 4 + .../resnet/resnet50_4xb64_step_ep100.py | 35 ++ .../resnext101_32x4d_4xb64_step_ep100.py | 11 + .../resnext154_32x4d_4xb64_step_ep100.py | 11 + .../resnext50_32x4d_4xb64_step_ep100.py | 11 + configs/selfsup/cae/RAEDME.md | 2 +- demo/bird.JPEG | Bin 0 -> 74237 bytes demo/cat-dog.png | Bin 0 -> 744894 bytes docs/en/awesome_selfsup/MIM.md | 8 + docs/en/changelog.md | 8 +- docs/en/index.rst | 7 + docs/en/model_zoos/Model_Zoo_sup.md | 2 +- docs/en/tools/analysis.md | 135 +++++ docs/en/tools/visualization.md | 221 +++++++++ openmixup/__init__.py | 57 +++ openmixup/datasets/data_sources/image_list.py | 19 +- openmixup/datasets/multi_view.py | 32 +- openmixup/datasets/pipelines/transforms.py | 16 +- openmixup/models/backbones/__init__.py | 3 +- openmixup/models/backbones/deit3.py | 460 ++++++++++++++++++ openmixup/models/backbones/moganet.py | 10 +- .../models/classifiers/automix_V1plus.py | 65 ++- .../models/classifiers/classification.py | 28 +- .../classifiers/mixup_classification.py | 23 +- openmixup/models/heads/cls_head.py | 28 +- openmixup/models/heads/cls_mixup_head.py | 25 +- openmixup/models/utils/layers/attention.py | 11 +- tools/analysis_tools/gradcam.py | 421 ---------------- tools/visualizations/vis_cam.py | 364 ++++++++++++++ tools/visualizations/vis_lr.py | 333 +++++++++++++ 57 files changed, 3021 insertions(+), 472 deletions(-) create mode 100644 configs/classification/_base_/datasets/imagenet/basic_tta_sz224_4xbs64.py create mode 100644 configs/classification/_base_/datasets/imagenet/deit3_ft_sz224_8xbs128.py create mode 100644 configs/classification/_base_/datasets/imagenet/deit3_sz160_8xbs128.py create mode 100644 configs/classification/_base_/datasets/imagenet/deit3_sz192_8xbs128.py create mode 100644 configs/classification/_base_/datasets/imagenet/deit3_sz224_8xbs128.py create mode 100644 configs/classification/_base_/models/deit3/deit3_base_p16_sz192.py create mode 100644 configs/classification/_base_/models/deit3/deit3_huge_p16_sz160.py create mode 100644 configs/classification/_base_/models/deit3/deit3_large_p16_sz192.py create mode 100644 configs/classification/_base_/models/deit3/deit3_small_p16_sz224.py create mode 100644 configs/classification/imagenet/automix/pvt/pvt_t_l2_a2_near_lam_cat_swch0_8_8x128_fp16_ep300.py create mode 100644 configs/classification/imagenet/automix/pvt/pvt_t_l2_a2_near_lam_cat_swch0_8_attn_ln_8x128_fp16_ep300.py create mode 100644 configs/classification/imagenet/deit3/README.md create mode 100644 configs/classification/imagenet/deit3/deit3_base_sz192_8xb128_accu2_ep800.py create mode 100644 configs/classification/imagenet/deit3/deit3_base_sz224_ft_4xb128_ep20.py create mode 100644 configs/classification/imagenet/deit3/deit3_huge_sz160_8xb64_accu4_ep800.py create mode 100644 configs/classification/imagenet/deit3/deit3_huge_sz224_ft_8xb64_ep20.py create mode 100644 configs/classification/imagenet/deit3/deit3_large_sz192_8xb128_accu2_ep800.py create mode 100644 configs/classification/imagenet/deit3/deit3_large_sz224_ft_8xb64_ep20.py create mode 100644 configs/classification/imagenet/deit3/deit3_small_sz224_8xb256_ep800.py create mode 100644 configs/classification/imagenet/resnet/resnet101_4xb64_step_ep100.py create mode 100644 configs/classification/imagenet/resnet/resnet154_4xb64_step_ep100.py create mode 100644 configs/classification/imagenet/resnet/resnet18_4xb64_cos_ep100.py create mode 100644 configs/classification/imagenet/resnet/resnet18_4xb64_step_ep100.py create mode 100644 configs/classification/imagenet/resnet/resnet34_4xb64_step_ep100.py create mode 100644 configs/classification/imagenet/resnet/resnet50_4xb64_cos_ep100.py create mode 100644 configs/classification/imagenet/resnet/resnet50_4xb64_step_ep100.py create mode 100644 configs/classification/imagenet/resnet/resnext101_32x4d_4xb64_step_ep100.py create mode 100644 configs/classification/imagenet/resnet/resnext154_32x4d_4xb64_step_ep100.py create mode 100644 configs/classification/imagenet/resnet/resnext50_32x4d_4xb64_step_ep100.py create mode 100644 demo/bird.JPEG create mode 100644 demo/cat-dog.png create mode 100644 docs/en/tools/analysis.md create mode 100644 docs/en/tools/visualization.md create mode 100644 openmixup/models/backbones/deit3.py delete mode 100644 tools/analysis_tools/gradcam.py create mode 100644 tools/visualizations/vis_cam.py create mode 100644 tools/visualizations/vis_lr.py diff --git a/README.md b/README.md index ea42022a..84a17835 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ The main branch works with **PyTorch 1.8** (required by some self-supervised met ## What's New -[2022-10-12] Update new features and documents of `OpenMixup` v0.2.6 (issue [#24](https://github.com/Westlake-AI/openmixup/issues/24) and issue [#25](https://github.com/Westlake-AI/openmixup/issues/25)). +[2022-10-15] Update new features and documents of `OpenMixup` v0.2.6 (issue [#24](https://github.com/Westlake-AI/openmixup/issues/24) and issue [#25](https://github.com/Westlake-AI/openmixup/issues/25)). [2022-09-14] `OpenMixup` v0.2.6 is released (issue [#20](https://github.com/Westlake-AI/openmixup/issues/20)). @@ -113,6 +113,7 @@ Please refer to [Model Zoos](docs/en/model_zoos) for various backbones, mixup me - [x] [MViTV2](https://arxiv.org/abs/2112.01526) (CVPR'2022) [[config](https://github.com/Westlake-AI/openmixup/tree/main/configs/classification/imagenet/mvit/)] - [x] [RepMLP](https://arxiv.org/abs/2105.01883) (CVPR'2022) [[config](https://github.com/Westlake-AI/openmixup/tree/main/configs/classification/imagenet/repmlp/)] - [x] [VAN](https://arxiv.org/abs/2202.09741) (ArXiv'2022) [[config](https://github.com/Westlake-AI/openmixup/tree/main/configs/classification/imagenet/van/)] + - [x] [DeiT-3](https://arxiv.org/abs/2204.07118) (ECCV'2022) [[config](https://github.com/Westlake-AI/openmixup/tree/main/configs/classification/imagenet/deit3/)] - [x] [LITv2](https://arxiv.org/abs/2205.13213) (NIPS'2022) [[config](https://github.com/Westlake-AI/openmixup/tree/main/configs/classification/imagenet/lit_v2/)] - [x] [HorNet](https://arxiv.org/abs/2207.14284) (NIPS'2022) [[config](https://github.com/Westlake-AI/openmixup/tree/main/configs/classification/imagenet/hornet/)] - [x] [EdgeNeXt](https://arxiv.org/abs/2206.10589) (ECCVW'2022) [[config](https://github.com/Westlake-AI/openmixup/tree/main/configs/classification/imagenet/edgenext/)] diff --git a/configs/classification/_base_/datasets/imagenet/basic_tta_sz224_4xbs64.py b/configs/classification/_base_/datasets/imagenet/basic_tta_sz224_4xbs64.py new file mode 100644 index 00000000..2b069634 --- /dev/null +++ b/configs/classification/_base_/datasets/imagenet/basic_tta_sz224_4xbs64.py @@ -0,0 +1,64 @@ +# dataset settings +data_source_cfg = dict(type='ImageNet') +# ImageNet dataset +data_train_list = 'data/meta/ImageNet/train_labeled_full.txt' +data_train_root = 'data/ImageNet/train' +data_test_list = 'data/meta/ImageNet/val_labeled.txt' +data_test_root = 'data/ImageNet/val/' + +dataset_type = 'ClassificationDataset' +img_norm_cfg = dict(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) +train_pipeline = [ + dict(type='RandomResizedCrop', size=224, interpolation=3), # bicubic + dict(type='RandomHorizontalFlip'), +] +test_pipeline_1 = [ + dict(type='Resize', size=256, interpolation=3), # 0.85 + dict(type='RandomHorizontalFlip', p=0.5), + dict(type='CenterCrop', size=224), + dict(type='ToTensor'), + dict(type='Normalize', **img_norm_cfg), +] +test_pipeline_2 = [ + dict(type='Resize', size=256, interpolation=3), # 0.85 + dict(type='RandomVerticalFlip', p=0.5), + dict(type='PlaceCrop', size=224, start=[0, 5, 10, 15,]), + dict(type='ToTensor'), + dict(type='Normalize', **img_norm_cfg), +] + +# prefetch +prefetch = True +if not prefetch: + train_pipeline.extend([dict(type='ToTensor'), dict(type='Normalize', **img_norm_cfg)]) + +data = dict( + imgs_per_gpu=64, + workers_per_gpu=8, + train=dict( + type=dataset_type, + data_source=dict( + list_file=data_train_list, root=data_train_root, + **data_source_cfg), + pipeline=train_pipeline, + prefetch=prefetch, + ), + val=dict( + type="MultiViewDataset", # use multi-view for test time augmentations + data_source=dict( + list_file=data_test_list, root=data_test_root, **data_source_cfg), + num_views=[2, 4], + pipelines=[test_pipeline_1, test_pipeline_2], + prefetch=False, + )) + +# validation hook +evaluation = dict( + initial=False, + interval=1, + imgs_per_gpu=128, + workers_per_gpu=4, + eval_param=dict(topk=(1, 5))) + +# checkpoint +checkpoint_config = dict(interval=1, max_keep_ckpts=1) diff --git a/configs/classification/_base_/datasets/imagenet/deit3_ft_sz224_8xbs128.py b/configs/classification/_base_/datasets/imagenet/deit3_ft_sz224_8xbs128.py new file mode 100644 index 00000000..45889f7a --- /dev/null +++ b/configs/classification/_base_/datasets/imagenet/deit3_ft_sz224_8xbs128.py @@ -0,0 +1,83 @@ +# Refers to `_RAND_INCREASING_TRANSFORMS` in pytorch-image-models +rand_increasing_policies = [ + dict(type='AutoContrast'), + dict(type='Equalize'), + dict(type='Invert'), + dict(type='Rotate', magnitude_key='angle', magnitude_range=(0, 30)), + dict(type='Posterize', magnitude_key='bits', magnitude_range=(4, 0)), + dict(type='Solarize', magnitude_key='thr', magnitude_range=(256, 0)), + dict(type='SolarizeAdd', magnitude_key='magnitude', magnitude_range=(0, 110)), + dict(type='ColorTransform', magnitude_key='magnitude', magnitude_range=(0, 0.9)), + dict(type='Contrast', magnitude_key='magnitude', magnitude_range=(0, 0.9)), + dict(type='Brightness', magnitude_key='magnitude', magnitude_range=(0, 0.9)), + dict(type='Sharpness', magnitude_key='magnitude', magnitude_range=(0, 0.9)), + dict(type='Shear', + magnitude_key='magnitude', magnitude_range=(0, 0.3), direction='horizontal'), + dict(type='Shear', + magnitude_key='magnitude', magnitude_range=(0, 0.3), direction='vertical'), + dict(type='Translate', + magnitude_key='magnitude', magnitude_range=(0, 0.45), direction='horizontal'), + dict(type='Translate', + magnitude_key='magnitude', magnitude_range=(0, 0.45), direction='vertical'), +] + +# dataset settings +data_source_cfg = dict(type='ImageNet') +# ImageNet dataset +data_train_list = 'data/meta/ImageNet/train_labeled_full.txt' +data_train_root = 'data/ImageNet/train' +data_test_list = 'data/meta/ImageNet/val_labeled.txt' +data_test_root = 'data/ImageNet/val/' + +dataset_type = 'ClassificationDataset' +img_norm_cfg = dict(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) +train_pipeline = [ + dict(type='RandomResizedCrop', size=224, interpolation=3), # bicubic + dict(type='RandomHorizontalFlip'), + dict(type='RandAugment', + policies=rand_increasing_policies, + num_policies=2, total_level=10, + magnitude_level=9, magnitude_std=0.5, + hparams=dict( + pad_val=[104, 116, 124], interpolation='bicubic')), +] +test_pipeline = [ + dict(type='Resize', size=224, interpolation=3), # crop-ratio = 1.0 + dict(type='CenterCrop', size=224), + dict(type='ToTensor'), + dict(type='Normalize', **img_norm_cfg), +] +# prefetch +prefetch = True +if not prefetch: + train_pipeline.extend([dict(type='ToTensor'), dict(type='Normalize', **img_norm_cfg)]) + +data = dict( + imgs_per_gpu=128, + workers_per_gpu=10, + train=dict( + type=dataset_type, + data_source=dict( + list_file=data_train_list, root=data_train_root, + **data_source_cfg), + pipeline=train_pipeline, + prefetch=prefetch, + ), + val=dict( + type=dataset_type, + data_source=dict( + list_file=data_test_list, root=data_test_root, **data_source_cfg), + pipeline=test_pipeline, + prefetch=False, + )) + +# validation hook +evaluation = dict( + initial=False, + interval=1, + imgs_per_gpu=128, + workers_per_gpu=4, + eval_param=dict(topk=(1, 5))) + +# checkpoint +checkpoint_config = dict(interval=1, max_keep_ckpts=1) diff --git a/configs/classification/_base_/datasets/imagenet/deit3_sz160_8xbs128.py b/configs/classification/_base_/datasets/imagenet/deit3_sz160_8xbs128.py new file mode 100644 index 00000000..f626123b --- /dev/null +++ b/configs/classification/_base_/datasets/imagenet/deit3_sz160_8xbs128.py @@ -0,0 +1,64 @@ +# dataset settings +data_source_cfg = dict(type='ImageNet') +# ImageNet dataset +data_train_list = 'data/meta/ImageNet/train_labeled_full.txt' +data_train_root = 'data/ImageNet/train' +data_test_list = 'data/meta/ImageNet/val_labeled.txt' +data_test_root = 'data/ImageNet/val/' + +dataset_type = 'ClassificationDataset' +img_norm_cfg = dict(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) +train_pipeline = [ + dict(type='RandomResizedCrop', size=160, interpolation=3), # bicubic + dict(type='RandomHorizontalFlip'), + dict(type='RandomAppliedTrans', # 3-Augment in DeiT III + transforms=[ + dict(type='RandomGrayscale', p=1.), + dict(type='Solarization', p=1.), + dict(type='GaussianBlur', sigma_min=0.1, sigma_max=2.0, p=1.), + ], + p=1.0), + dict(type='ColorJitter', + brightness=0.3, contrast=0.3, saturation=0.3), +] +test_pipeline = [ + dict(type='Resize', size=160, interpolation=3), # crop-ratio = 1.0 + dict(type='CenterCrop', size=160), + dict(type='ToTensor'), + dict(type='Normalize', **img_norm_cfg), +] + +# prefetch +prefetch = True +if not prefetch: + train_pipeline.extend([dict(type='ToTensor'), dict(type='Normalize', **img_norm_cfg)]) + +data = dict( + imgs_per_gpu=128, + workers_per_gpu=8, + train=dict( + type=dataset_type, + data_source=dict( + list_file=data_train_list, root=data_train_root, + **data_source_cfg), + pipeline=train_pipeline, + prefetch=prefetch, + ), + val=dict( + type=dataset_type, + data_source=dict( + list_file=data_test_list, root=data_test_root, **data_source_cfg), + pipeline=test_pipeline, + prefetch=False, + )) + +# validation hook +evaluation = dict( + initial=False, + interval=1, + imgs_per_gpu=128, + workers_per_gpu=4, + eval_param=dict(topk=(1, 5))) + +# checkpoint +checkpoint_config = dict(interval=1, max_keep_ckpts=1) diff --git a/configs/classification/_base_/datasets/imagenet/deit3_sz192_8xbs128.py b/configs/classification/_base_/datasets/imagenet/deit3_sz192_8xbs128.py new file mode 100644 index 00000000..f2f7cb03 --- /dev/null +++ b/configs/classification/_base_/datasets/imagenet/deit3_sz192_8xbs128.py @@ -0,0 +1,64 @@ +# dataset settings +data_source_cfg = dict(type='ImageNet') +# ImageNet dataset +data_train_list = 'data/meta/ImageNet/train_labeled_full.txt' +data_train_root = 'data/ImageNet/train' +data_test_list = 'data/meta/ImageNet/val_labeled.txt' +data_test_root = 'data/ImageNet/val/' + +dataset_type = 'ClassificationDataset' +img_norm_cfg = dict(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) +train_pipeline = [ + dict(type='RandomResizedCrop', size=192, interpolation=3), # bicubic + dict(type='RandomHorizontalFlip'), + dict(type='RandomAppliedTrans', # 3-Augment in DeiT III + transforms=[ + dict(type='RandomGrayscale', p=1.), + dict(type='Solarization', p=1.), + dict(type='GaussianBlur', sigma_min=0.1, sigma_max=2.0, p=1.), + ], + p=1.0), + dict(type='ColorJitter', + brightness=0.3, contrast=0.3, saturation=0.3), +] +test_pipeline = [ + dict(type='Resize', size=192, interpolation=3), # crop-ratio = 1.0 + dict(type='CenterCrop', size=192), + dict(type='ToTensor'), + dict(type='Normalize', **img_norm_cfg), +] + +# prefetch +prefetch = True +if not prefetch: + train_pipeline.extend([dict(type='ToTensor'), dict(type='Normalize', **img_norm_cfg)]) + +data = dict( + imgs_per_gpu=128, + workers_per_gpu=8, + train=dict( + type=dataset_type, + data_source=dict( + list_file=data_train_list, root=data_train_root, + **data_source_cfg), + pipeline=train_pipeline, + prefetch=prefetch, + ), + val=dict( + type=dataset_type, + data_source=dict( + list_file=data_test_list, root=data_test_root, **data_source_cfg), + pipeline=test_pipeline, + prefetch=False, + )) + +# validation hook +evaluation = dict( + initial=False, + interval=1, + imgs_per_gpu=128, + workers_per_gpu=4, + eval_param=dict(topk=(1, 5))) + +# checkpoint +checkpoint_config = dict(interval=1, max_keep_ckpts=1) diff --git a/configs/classification/_base_/datasets/imagenet/deit3_sz224_8xbs128.py b/configs/classification/_base_/datasets/imagenet/deit3_sz224_8xbs128.py new file mode 100644 index 00000000..a8fa0d25 --- /dev/null +++ b/configs/classification/_base_/datasets/imagenet/deit3_sz224_8xbs128.py @@ -0,0 +1,64 @@ +# dataset settings +data_source_cfg = dict(type='ImageNet') +# ImageNet dataset +data_train_list = 'data/meta/ImageNet/train_labeled_full.txt' +data_train_root = 'data/ImageNet/train' +data_test_list = 'data/meta/ImageNet/val_labeled.txt' +data_test_root = 'data/ImageNet/val/' + +dataset_type = 'ClassificationDataset' +img_norm_cfg = dict(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) +train_pipeline = [ + dict(type='RandomResizedCrop', size=224, interpolation=3), # bicubic + dict(type='RandomHorizontalFlip'), + dict(type='RandomAppliedTrans', # 3-Augment in DeiT III + transforms=[ + dict(type='RandomGrayscale', p=1.), + dict(type='Solarization', p=1.), + dict(type='GaussianBlur', sigma_min=0.1, sigma_max=2.0, p=1.), + ], + p=1.0), + dict(type='ColorJitter', + brightness=0.3, contrast=0.3, saturation=0.3), +] +test_pipeline = [ + dict(type='Resize', size=224, interpolation=3), # crop-ratio = 1.0 + dict(type='CenterCrop', size=224), + dict(type='ToTensor'), + dict(type='Normalize', **img_norm_cfg), +] + +# prefetch +prefetch = True +if not prefetch: + train_pipeline.extend([dict(type='ToTensor'), dict(type='Normalize', **img_norm_cfg)]) + +data = dict( + imgs_per_gpu=128, + workers_per_gpu=8, + train=dict( + type=dataset_type, + data_source=dict( + list_file=data_train_list, root=data_train_root, + **data_source_cfg), + pipeline=train_pipeline, + prefetch=prefetch, + ), + val=dict( + type=dataset_type, + data_source=dict( + list_file=data_test_list, root=data_test_root, **data_source_cfg), + pipeline=test_pipeline, + prefetch=False, + )) + +# validation hook +evaluation = dict( + initial=False, + interval=1, + imgs_per_gpu=128, + workers_per_gpu=4, + eval_param=dict(topk=(1, 5))) + +# checkpoint +checkpoint_config = dict(interval=1, max_keep_ckpts=1) diff --git a/configs/classification/_base_/models/deit3/deit3_base_p16_sz192.py b/configs/classification/_base_/models/deit3/deit3_base_p16_sz192.py new file mode 100644 index 00000000..4d97709e --- /dev/null +++ b/configs/classification/_base_/models/deit3/deit3_base_p16_sz192.py @@ -0,0 +1,24 @@ +# model settings +model = dict( + type='MixUpClassification', + pretrained=None, + alpha=[0.8, 1.0,], + mix_mode=["mixup", "cutmix",], + mix_args=dict(), + backbone=dict( + type='DeiT3', + arch='base', + img_size=192, + patch_size=16, + drop_path_rate=0.2), + head=dict( + type='VisionTransformerClsHead', + loss=dict(type='CrossEntropyLoss', # mixup BCE loss (one-hot encoding) + use_soft=False, use_sigmoid=True, loss_weight=1.0), + multi_label=True, + in_channels=768, num_classes=1000), + init_cfg=[ + dict(type='TruncNormal', layer='Linear', std=.02), + dict(type='Constant', layer='LayerNorm', val=1., bias=0.), + ], +) diff --git a/configs/classification/_base_/models/deit3/deit3_huge_p16_sz160.py b/configs/classification/_base_/models/deit3/deit3_huge_p16_sz160.py new file mode 100644 index 00000000..3be0655c --- /dev/null +++ b/configs/classification/_base_/models/deit3/deit3_huge_p16_sz160.py @@ -0,0 +1,24 @@ +# model settings +model = dict( + type='MixUpClassification', + pretrained=None, + alpha=[0.8, 1.0,], + mix_mode=["mixup", "cutmix",], + mix_args=dict(), + backbone=dict( + type='DeiT3', + arch='huge', + img_size=160, + patch_size=16, + drop_path_rate=0.6), + head=dict( + type='VisionTransformerClsHead', + loss=dict(type='CrossEntropyLoss', # mixup BCE loss (one-hot encoding) + use_soft=False, use_sigmoid=True, loss_weight=1.0), + multi_label=True, + in_channels=1280, num_classes=1000), + init_cfg=[ + dict(type='TruncNormal', layer='Linear', std=.02), + dict(type='Constant', layer='LayerNorm', val=1., bias=0.), + ], +) diff --git a/configs/classification/_base_/models/deit3/deit3_large_p16_sz192.py b/configs/classification/_base_/models/deit3/deit3_large_p16_sz192.py new file mode 100644 index 00000000..aa16fa68 --- /dev/null +++ b/configs/classification/_base_/models/deit3/deit3_large_p16_sz192.py @@ -0,0 +1,24 @@ +# model settings +model = dict( + type='MixUpClassification', + pretrained=None, + alpha=[0.8, 1.0,], + mix_mode=["mixup", "cutmix",], + mix_args=dict(), + backbone=dict( + type='DeiT3', + arch='large', + img_size=192, + patch_size=16, + drop_path_rate=0.45), + head=dict( + type='VisionTransformerClsHead', + loss=dict(type='CrossEntropyLoss', # mixup BCE loss (one-hot encoding) + use_soft=False, use_sigmoid=True, loss_weight=1.0), + multi_label=True, + in_channels=1024, num_classes=1000), + init_cfg=[ + dict(type='TruncNormal', layer='Linear', std=.02), + dict(type='Constant', layer='LayerNorm', val=1., bias=0.), + ], +) diff --git a/configs/classification/_base_/models/deit3/deit3_small_p16_sz224.py b/configs/classification/_base_/models/deit3/deit3_small_p16_sz224.py new file mode 100644 index 00000000..b0bf4019 --- /dev/null +++ b/configs/classification/_base_/models/deit3/deit3_small_p16_sz224.py @@ -0,0 +1,24 @@ +# model settings +model = dict( + type='MixUpClassification', + pretrained=None, + alpha=[0.8, 1.0,], + mix_mode=["mixup", "cutmix",], + mix_args=dict(), + backbone=dict( + type='DeiT3', + arch='small', + img_size=224, + patch_size=16, + drop_path_rate=0.05), + head=dict( + type='VisionTransformerClsHead', + loss=dict(type='CrossEntropyLoss', # mixup BCE loss (one-hot encoding) + use_soft=False, use_sigmoid=True, loss_weight=1.0), + multi_label=True, + in_channels=384, num_classes=1000), + init_cfg=[ + dict(type='TruncNormal', layer='Linear', std=.02), + dict(type='Constant', layer='LayerNorm', val=1., bias=0.), + ], +) diff --git a/configs/classification/imagenet/automix/deit/deit_s_l6_a2_near_lam_cat_switch0_8_8x128_ep300.py b/configs/classification/imagenet/automix/deit/deit_s_l6_a2_near_lam_cat_switch0_8_8x128_ep300.py index 41fa6c7d..77de3bbd 100644 --- a/configs/classification/imagenet/automix/deit/deit_s_l6_a2_near_lam_cat_switch0_8_8x128_ep300.py +++ b/configs/classification/imagenet/automix/deit/deit_s_l6_a2_near_lam_cat_switch0_8_8x128_ep300.py @@ -9,7 +9,7 @@ pretrained=None, alpha=2.0, momentum=0.999, - mask_layer=2, # dowmsampling to 1/8 + mask_layer=2, # dowmsampling to 1/16 mask_loss=0.1, # using loss mask_adjust=0, # none for large datasets lam_margin=0.08, @@ -92,7 +92,7 @@ # Sets `find_unused_parameters`: randomly switch off mixblock find_unused_parameters = True -# apex +# fp16 use_fp16 = False fp16 = dict(type='mmcv', loss_scale='dynamic') optimizer_config = dict( diff --git a/configs/classification/imagenet/automix/deit/deit_s_l6_a2_near_lam_cat_switch0_8_att_ln_8x128_fp16_ep300.py b/configs/classification/imagenet/automix/deit/deit_s_l6_a2_near_lam_cat_switch0_8_att_ln_8x128_fp16_ep300.py index 84cca4ec..d3a4b718 100644 --- a/configs/classification/imagenet/automix/deit/deit_s_l6_a2_near_lam_cat_switch0_8_att_ln_8x128_fp16_ep300.py +++ b/configs/classification/imagenet/automix/deit/deit_s_l6_a2_near_lam_cat_switch0_8_att_ln_8x128_fp16_ep300.py @@ -9,7 +9,7 @@ pretrained=None, alpha=2.0, momentum=0.999, - mask_layer=2, # dowmsampling to 1/8 + mask_layer=2, # dowmsampling to 1/16 mask_loss=0.1, # using loss mask_adjust=0, # none for large datasets lam_margin=0.08, @@ -92,7 +92,7 @@ # Sets `find_unused_parameters`: randomly switch off mixblock find_unused_parameters = True -# apex +# fp16 use_fp16 = True fp16 = dict(type='mmcv', loss_scale='dynamic') optimizer_config = dict( diff --git a/configs/classification/imagenet/automix/pvt/pvt_t_l2_a2_near_lam_cat_swch0_8_8x128_fp16_ep300.py b/configs/classification/imagenet/automix/pvt/pvt_t_l2_a2_near_lam_cat_swch0_8_8x128_fp16_ep300.py new file mode 100644 index 00000000..a883eb8e --- /dev/null +++ b/configs/classification/imagenet/automix/pvt/pvt_t_l2_a2_near_lam_cat_swch0_8_8x128_fp16_ep300.py @@ -0,0 +1,122 @@ +_base_ = [ + '../../../_base_/datasets/imagenet/swin_sz224_4xbs256.py', + '../../../_base_/default_runtime.py', +] + +# model settings +model = dict( + type='AutoMixup', + pretrained=None, + alpha=2.0, + momentum=0.999, + mask_layer=2, # dowmsampling to 1/16 + mask_loss=0.1, # using loss + mask_adjust=0, # none for large datasets + lam_margin=0.08, + switch_off=0.8, # switch off mixblock (fixed) + mask_up_override=None, + debug=True, + backbone=dict( + type='PyramidVisionTransformer', + arch='tiny', + img_size=224, + in_channels=3, + drop_path_rate=0.1, + out_indices=(2,3,), + ), + mix_block = dict( # SAMix + type='PixelMixBlock', + in_channels=320, reduction=2, use_scale=True, + unsampling_mode=['nearest',], # str or list, train & test MixBlock + lam_concat=True, lam_concat_v=False, # AutoMix.V1: lam cat q,k,v + lam_mul=False, lam_residual=False, lam_mul_k=-1, # SAMix lam: none + value_neck_cfg=None, # SAMix: non-linear value + x_qk_concat=False, x_v_concat=False, # SAMix x concat: none + att_norm_cfg=None, # AutoMix: attention norm for fp16 + mask_loss_mode="L1", mask_loss_margin=0.1, # L1 loss, 0.1 + mask_mode="none_v_", + frozen=False), + head_one=dict( + type='VisionTransformerClsHead', # mixup CE + label smooth + loss=dict(type='LabelSmoothLoss', + label_smooth_val=0.1, num_classes=1000, mode='original', loss_weight=1.0), + in_channels=512, num_classes=1000), + head_mix=dict( + type='VisionTransformerClsHead', # mixup CE + label smooth + loss=dict(type='LabelSmoothLoss', + label_smooth_val=0.1, num_classes=1000, mode='original', loss_weight=1.0), + in_channels=512, num_classes=1000), + head_weights=dict( + decent_weight=[], accent_weight=[], + head_mix_q=1, head_one_q=1, head_mix_k=1, head_one_k=1), + init_cfg=[ + dict(type='TruncNormal', layer='Linear', std=0.02, bias=0.), + dict(type='Constant', layer='LayerNorm', val=1., bias=0.) + ], +) + +# dataset +data = dict(imgs_per_gpu=128, workers_per_gpu=10) +# sampler = "RepeatAugSampler" # the official repo uses repeated_aug + +# interval for accumulate gradient +update_interval = 1 # total: 8 x bs128 x 1 accumulates = bs1024 + +custom_hooks = [ + dict(type='SAVEHook', + save_interval=1251 * 20, # plot every 20 ep + iter_per_epoch=1251, + ), + dict(type='CustomCosineAnnealingHook', # 0.1 to 0 + attr_name="mask_loss", attr_base=0.1, min_attr=0., by_epoch=False, # by iter + update_interval=update_interval, + ), + dict(type='CosineScheduleHook', + end_momentum=0.99999, # 0.999 to 0.99999 + adjust_scope=[0.25, 1.0], + warming_up="constant", + update_interval=update_interval, + interval=1) +] + +# optimizer +optimizer = dict( + type='AdamW', + lr=1e-3, # lr = 5e-4 * (256 * 4) * 1 accumulate / 512 = 1e-3 / bs1024 + weight_decay=0.05, eps=1e-8, betas=(0.9, 0.999), + paramwise_options={ + '(bn|ln|gn)(\d+)?.(weight|bias)': dict(weight_decay=0.), + 'norm': dict(weight_decay=0.), + 'bias': dict(weight_decay=0.), + 'cls_token': dict(weight_decay=0.), + 'pos_embed': dict(weight_decay=0.), + 'mix_block': dict(lr=1e-3), + }) +# Sets `find_unused_parameters`: randomly switch off mixblock +find_unused_parameters = True + +# fp16 +use_fp16 = False +fp16 = dict(type='mmcv', loss_scale='dynamic') +optimizer_config = dict( + grad_clip=dict(max_norm=5.0), update_interval=update_interval) + +# lr scheduler +lr_config = dict( + policy='CosineAnnealing', + by_epoch=False, min_lr=1e-5, # 1e-5 yields better performances than 1e-6 + warmup='linear', + warmup_iters=5, warmup_by_epoch=True, + warmup_ratio=1e-6, +) +# additional scheduler +addtional_scheduler = dict( + policy='CosineAnnealing', + by_epoch=False, min_lr=1e-4, + paramwise_options=['mix_block'], + warmup_iters=5, warmup_by_epoch=True, + warmup_ratio=1e-6, +) + +# runtime settings +runner = dict(type='EpochBasedRunner', max_epochs=300) diff --git a/configs/classification/imagenet/automix/pvt/pvt_t_l2_a2_near_lam_cat_swch0_8_attn_ln_8x128_fp16_ep300.py b/configs/classification/imagenet/automix/pvt/pvt_t_l2_a2_near_lam_cat_swch0_8_attn_ln_8x128_fp16_ep300.py new file mode 100644 index 00000000..3b3e55c4 --- /dev/null +++ b/configs/classification/imagenet/automix/pvt/pvt_t_l2_a2_near_lam_cat_swch0_8_attn_ln_8x128_fp16_ep300.py @@ -0,0 +1,122 @@ +_base_ = [ + '../../../_base_/datasets/imagenet/swin_sz224_4xbs256.py', + '../../../_base_/default_runtime.py', +] + +# model settings +model = dict( + type='AutoMixup', + pretrained=None, + alpha=2.0, + momentum=0.999, + mask_layer=2, # dowmsampling to 1/16 + mask_loss=0.1, # using loss + mask_adjust=0, # none for large datasets + lam_margin=0.08, + switch_off=0.8, # switch off mixblock (fixed) + mask_up_override=None, + debug=True, + backbone=dict( + type='PyramidVisionTransformer', + arch='tiny', + img_size=224, + in_channels=3, + drop_path_rate=0.1, + out_indices=(2,3,), + ), + mix_block = dict( # SAMix + type='PixelMixBlock', + in_channels=320, reduction=2, use_scale=True, + unsampling_mode=['nearest',], # str or list, train & test MixBlock + lam_concat=True, lam_concat_v=False, # AutoMix.V1: lam cat q,k,v + lam_mul=False, lam_residual=False, lam_mul_k=-1, # SAMix lam: none + value_neck_cfg=None, # SAMix: non-linear value + x_qk_concat=False, x_v_concat=False, # SAMix x concat: none + att_norm_cfg=dict(type='LN2d', eps=1e-6), # AutoMix: attention norm for fp16 + mask_loss_mode="L1", mask_loss_margin=0.1, # L1 loss, 0.1 + mask_mode="none_v_", + frozen=False), + head_one=dict( + type='VisionTransformerClsHead', # mixup CE + label smooth + loss=dict(type='LabelSmoothLoss', + label_smooth_val=0.1, num_classes=1000, mode='original', loss_weight=1.0), + in_channels=512, num_classes=1000), + head_mix=dict( + type='VisionTransformerClsHead', # mixup CE + label smooth + loss=dict(type='LabelSmoothLoss', + label_smooth_val=0.1, num_classes=1000, mode='original', loss_weight=1.0), + in_channels=512, num_classes=1000), + head_weights=dict( + decent_weight=[], accent_weight=[], + head_mix_q=1, head_one_q=1, head_mix_k=1, head_one_k=1), + init_cfg=[ + dict(type='TruncNormal', layer='Linear', std=0.02, bias=0.), + dict(type='Constant', layer='LayerNorm', val=1., bias=0.) + ], +) + +# dataset +data = dict(imgs_per_gpu=128, workers_per_gpu=10) +# sampler = "RepeatAugSampler" # the official repo uses repeated_aug + +# interval for accumulate gradient +update_interval = 1 # total: 8 x bs128 x 1 accumulates = bs1024 + +custom_hooks = [ + dict(type='SAVEHook', + save_interval=1251 * 20, # plot every 20 ep + iter_per_epoch=1251, + ), + dict(type='CustomCosineAnnealingHook', # 0.1 to 0 + attr_name="mask_loss", attr_base=0.1, min_attr=0., by_epoch=False, # by iter + update_interval=update_interval, + ), + dict(type='CosineScheduleHook', + end_momentum=0.99999, # 0.999 to 0.99999 + adjust_scope=[0.25, 1.0], + warming_up="constant", + update_interval=update_interval, + interval=1) +] + +# optimizer +optimizer = dict( + type='AdamW', + lr=1e-3, # lr = 5e-4 * (256 * 4) * 1 accumulate / 512 = 1e-3 / bs1024 + weight_decay=0.05, eps=1e-8, betas=(0.9, 0.999), + paramwise_options={ + '(bn|ln|gn)(\d+)?.(weight|bias)': dict(weight_decay=0.), + 'norm': dict(weight_decay=0.), + 'bias': dict(weight_decay=0.), + 'cls_token': dict(weight_decay=0.), + 'pos_embed': dict(weight_decay=0.), + 'mix_block': dict(lr=1e-3), + }) +# Sets `find_unused_parameters`: randomly switch off mixblock +find_unused_parameters = True + +# fp16 +use_fp16 = True +fp16 = dict(type='mmcv', loss_scale='dynamic') +optimizer_config = dict( + grad_clip=dict(max_norm=5.0), update_interval=update_interval) + +# lr scheduler +lr_config = dict( + policy='CosineAnnealing', + by_epoch=False, min_lr=1e-5, # 1e-5 yields better performances than 1e-6 + warmup='linear', + warmup_iters=5, warmup_by_epoch=True, + warmup_ratio=1e-6, +) +# additional scheduler +addtional_scheduler = dict( + policy='CosineAnnealing', + by_epoch=False, min_lr=1e-4, + paramwise_options=['mix_block'], + warmup_iters=5, warmup_by_epoch=True, + warmup_ratio=1e-6, +) + +# runtime settings +runner = dict(type='EpochBasedRunner', max_epochs=300) diff --git a/configs/classification/imagenet/deit3/README.md b/configs/classification/imagenet/deit3/README.md new file mode 100644 index 00000000..6a72d38e --- /dev/null +++ b/configs/classification/imagenet/deit3/README.md @@ -0,0 +1,38 @@ +# DeiT III + +> [DeiT III: Revenge of the ViT](https://arxiv.org/abs/2204.07118) + +## Abstract + +A Vision Transformer (ViT) is a simple neural architecture amenable to serve several computer vision tasks. It has limited built-in architectural priors, in contrast to more recent architectures that incorporate priors either about the input data or of specific tasks. Recent works show that ViTs benefit from self-supervised pre-training, in particular BerT-like pre-training like BeiT. In this paper, we revisit the supervised training of ViTs. Our procedure builds upon and simplifies a recipe introduced for training ResNet-50. It includes a new simple data-augmentation procedure with only 3 augmentations, closer to the practice in self-supervised learning. Our evaluations on Image classification (ImageNet-1k with and without pre-training on ImageNet-21k), transfer learning and semantic segmentation show that our procedure outperforms by a large margin previous fully supervised training recipes for ViT. It also reveals that the performance of our ViT trained with supervision is comparable to that of more recent architectures. Our results could serve as better baselines for recent self-supervised approaches demonstrated on ViT. + +
lQt07u-^ z!PxAXq$1K{7r?va08?ZuBtHv;05}*J7?>D1n3y<(*jU(vr1&^E_@rdS#H7T;WP~`k z<*&mZ=D*hbvsB586_(68GG}X{Zmi?5Ez1rhK_-Wg^hfm{96eEz$kw!2>=iTgaU?uQPI&b zP*HGrkxD`o2pthOs<^5VF}+hD4;o2qPL%`$j8yHDG4BKCpkYaL#yIs~%X=m+e0OrI zgPEk_HB6;HzjfumJEFN_w*Nll%c$G80~zLoywIA&_Ob7W`L!M6t4CVq?k|!G>N+QW z91F;5TX?)oF0AjGTst8Iz+hywklUEh(NOtrL!jd(f*>Psq9;b>35+GViQtpk@GoAN z@v?JJoTNIbiOYjMMzos%(3$u?k0671d)HK2li$^B<-bDszmI_VKOtPt05~YOeG&p< zz@|iuDwenwPH8BYh7oM3z&q&Gybxq0#+uE%EsTURH)WiZ74|D7#7aJ48A=i$A8Y&c zb09{@v1&*$|LdSP)(@CwLfM8s%QdOVCpugYZA!e+V+~f-B{l4?VWLyyaVGm5V;!$I zui3l#-1XrRRRp;UR8Y@`9mpEEWS`oit=T=C3i}vz4J02W%!1@N%?HcuI%;>C?^fjn znlKpAwiqm))#ksNEUp?qi*ziQw6mL)oB26kuUKyX^H-uT{;vp(1E&*_=9o;@XBfOF zLC=;uVwRKfN#tS{M>g9x(@~)dJ;$GG+CLLH1?24rs)E%d3DQwTikBI=K`iRH%9yM) zW3ldeaaq^HTLJ1+EX8%ChP_2f6FrKDujy+miGz}HmT(cvo+lIA&DdT|WhDh~021A` z2O`P*Rd3%p>{iVdn_L4$P4@4zw3RpNpPAIP4BX3qkLNPKO(`Zk-RQac#NJ!PwjOI{ zA}qkbL}k!n#AUupI_rM@mv1ANkN4Vo4<$}qPtv%Zb_6F0^ye&y&v=e^{U#Q=gh$@b zTmx>cr-2_hiP!tO8_e!#9S3kfE1ILiZykL NnkW)+np Mm zVjgP(mlW%VT2)pQP0OQNR3Cab8)^-8lg44^8n11QSkz~d#u7S-Kl|qJAT(fc2-fS7 zt)MtVLb4vsFYIh-g(h1Ch4WUknu`2Sd? SL>-!#kgab0zU^>&%>Fv>DcnVp7T3 qL4IBUp(%LL9*;c0IbC#w=}K z2Ny5?P-=%o_Ci8qqM)zyAz8A@5cWHhw4TfLWB(CpOLYorVdn7&J%{L{cMhr@Ut|S) zsAPXMma;WEnphZo`>K2;?JlPO!Nqd(ZdI_MkLiSLXnafSRBgGwuid?dN^3qxhK7LU zQ%y+|$>MO^@Tb<@;68SjbiZ^VH}v|ZbNSIS&gXfAIt04ET<4d6U!qEk=zn_x^Sn@> zK#e?X5U6+Dvq>#j%0$1j93}Irf%|GY?6|Q>#Qnn?3S)r`@?DQ%_sh)WA53ShZ&Hu7 z$$bShh84dOjkxy}xs_c5h% QkHlcR%X(Fsx7}7DAUb&jGDo@ zH_o27FtD1Mh)%FpH&Gku gD>wy6Q#i$ 95?gi-47YkI^P j5LfBIzPY+ JjF>VxPqF>Tt> zpPZ&mL~Hg1Un(r!?)ZP6yas|b-u7UR`!Ei#@}w-CM8Dk>a8vpvGV^n@Q4@8LPteLu z2@=gfR1up~u*_-s67Sq%<`|mpyINuLVrSq4e|`tEa+qgalu6QA&e5?HT2q5^s1UjE z Cxn>luG0w!=A? zzgj!>tfuP8X0?~yo4HAT?6fau1O79e3+djMMYyfS56j8NHLihkl|F0kqB~stJ6XT6 z=b8fUW-NW@uc&w^_|B0oL%eRX&cv)u=Nib|FEfZF$ihYCNOsGiCy6IneMk3zHKB*m z5&?^oydM9_+4s5KcJ=#cl-RPZjo9Yg``xpRBW0?N47Fs!nU)FvwStGw)!$X^a#oFe z>tWWU@fY5I`{lI*y+8i>cl|*)t)0j3uCvSqUYehq!xopPWlDp4kw+qPKSbWojapnD zl^f7g_$be*Z@V6x^oo`2o% dR>TiEwG-g9jVi!`l`i>Z3t*z16e5@&sSahoAqcM zI(yo2=biYq&Vpsv^meBv>QB-?df`?&`mJP?@y}|)EZ2ZFSswp=R &4tS1BpvssgO`-<@Y$CZ2h)5%{qqm~m&woYM;RT)THhszoiUUh_V1Qc zF`v?=udZF?x7QwdV-Rx0c=+BWr`hQn6=MFqY(Akq>6kt;h1c7`^N7N>t7UQR%;OrE z7?Z*NonBIDSAP6(09yH_eJgL5_AseXuG5|0t D3D$T$-XEHk)w`5>49&J^FI;7fI!{M_tT5R8l0hq-%+ovf zqv7f@x~%o6gQi{~sATx?{GHfSN3TSC(Ijn^+_=&6kh+q3f8CbSneMR)!L!m~ z8y2R*OP% UVJ#xAfy28M%n0Q{9ba}{Y`XE)QFFe~*--b|eleG} zi&foTTfh?IJL;j???W>U%iiKtl1!W0oSkcc?>w1({2J&;mg>iQU-)od=v( YX4SgHFLCNI z#&BsLBNNwH-nrR0&(n2RJ89HicyNtk@W g+oevwHi5wcVz8U4&>}`KP`k~O? zez~#P&d~+`M`QU^OY~;Nqyqjsz6gCZ0aY8b-|gLwwDSGPNf2W3llOF{^_NtX&>h^a zJ&bSf%R|@InHAC!<4HCm 0vZ#xfKzH(4EG@4Nl4}i!shL?ut!cfg=-1YP+eG$NUfMy^AP5v> u*?Wn~_GP~W7VF&cP2*Cn9USa?wCjITUc{VGK= z<7sV!P!q*t{Ym`XV?p1$wKj*g`g?B@hqiL2WeTT8UoRF=>(C7rp3v5o6soVEzd25S z=B=;}5lp%U1Shqx@aZdl)fAd^hl?LM6t_OrnIP+@$<}+OhBCE>Yqx}}|LIUC_9_W^ zuYdN-SHB|T%-m+?xU#uwn{Iq+6e4KdRkfIQTw!vSbM($FLbNAE(klZunFh6=_Bgld zv`*k^44F%P<#cH$+08q_LoIZy5mpNFkzR3%tgyoCq1{hPql`FB()=vi1=i^~LHR7j zDQxhZpiEUYoyX2J-(SVn@XjTDXH{-wSI2VX;@&SGcuP@IUG4Vq_yPJyG2bn*cfL9s zzN+;)8v?XEQ_PG(m@a<76*j(g*TA#W@#02SY2_EbChMNmV%+D`>(hE|-BxED%FZxJAMzC^$duRjDa8D#7p{R#ho@hc z;2d-V^pY>KgTK7FG-aj`vQ;NG@ nOS$Yr~mF Nl1f{?d|Mcoz-L|pigvkq3DB1 NGuaa=NmNX0=e^;nz F|LPJI3KM)8SCK58bDX3_eSeO`C zH_VNb8wWS7kbfA+R<|bqkE&br3UmmHM*$(>o )30GH zUNz(8J9lB~&Ov*Uab%1SnE0hlT!Q0sN09EQkv)Nt-Tk9OB>M*nL#oA*p&@}N6jXF% zb|7d-ObCghp%6lleIdaxG-7%qr$8hW_G$PRItdSh#Io8Rsj+h|#vNYCpt!p*#_E3q zNhhcn&``q4S*HOX{S%aRDo~?v2QU-_@gQ|Ib5wQ>4=mbI1BqjbM6Xqnvh=pmD{Tlf zKc8JF=j+rX!X(0 `oOz^|#wB7KO8|=AP(xjqM>n%N z9CR9ZiW}%#4+C6(9(2gvHAf(XGlgj^(PvyTqz;%@0t5|4Wc{pF<_Out!uSZJ8Z2VD zKarqHypDO0=r0783dmRjgegF7gw3fa*5D$Q7|-L=Y;pvbvR%`7LYrF4qqz8e|HLP# zB+E>uAk~4gK&c{{HoQ?a29`N1%5AjaixND`7*|3rI3E{*BPdSP5>%8Dd2%T&qxAz) zPV%+}aki%s)O`wNi8DQ?DDaLC{;sPKr}X_K`lzIgzWtrLHiPnhajd!&Nwxrw@PTS( zd&fjEFM8wL7!~ I4nOGy*^M9I;6~qQ}u`p$dx9AOyE`V$Uf(@<>zsf zQ-h;NADnA+u_q_pQG*1b6KZ|hNA1CmC1zqaT6m|_26c^cEoyhVvQtx^*hYQ4qRys5 zbHprS8=$gZ|A=hor#dQ1Tl8lIClXY@U$H#OmBr>GZS`~WQsMM|*3hlw`^DBO?67`K zPQ`U4d{rqh;zHJG<~_z-!X(eBeX5#i zo-KOBygMT6Xd~H>0ER6%36abfxsz=Ae1cfYi1=6N4-rHqVS>z!X<%t7R7XpI)!F^g zg$rDT07I1s)r>tbU lUb1-kW4mWkNgBf9t5% z$A-8fK6O#in7+3ilm?}3S08M6cVf=jku(g(FWOU0ur+)trwt+c2qL9)h83D( %4O$qO*$1)e@a1t1R8TUe~tvciG|hTw!4Q5&8J@7LSK4ssWwDL*Q+ z9}A%~(gdY2Sbvq073R*x2!L9}Q-TacgmZ^O;^gF}Rdueuqp2tj7c T;Tna~K9XN;9Qo)nG| z>MfyCf8tAD$KqTwX%M3>X5Gr>sF*8(v4pzwVal(T%wmwD5*3elk10sQ$U}(Kpb447 zTI#&2F87a%0X&SWaU)fKLpTBk(gPZ5QZdnRhVY>P9gihgX2cx*pqTv$agaE}i06-j z=0H?p;cXl8+A&l#aTpPPhjf=7N<1MZ;G@ofjzbcMFMLp|gaNSfcw+HIf5#%l6^>RO zv`$QF180q3ptr87I<5mfs (uaJ4A-pfU1O3Vjoxi6LAP6j|}<3 zwZxgnFlo$JFnA#sBuLy p9aYJSCDy*BoVvP+74PumezB52V37}v`4l(Z+p%5{v zO61df?<_p8ps~eaWK^XWSzEjyK?%pAf)l{gs)@cE^?s3K@H`BoF8T6kn=3;_!_a4< zjY2|PG)r!$1*2DM&MjwFj){pLd6U S!!BTIn)H37jL}FcP;}gsCR98)f;AyX zx$>kqfZg?qh!p01Akl%Bi!W#x$egi-d%!f_9{wn};oCKk)}ufAF>l&Pl}CfwNk@LW zTB*CCG88_$P$u79vXfi@ppO8*>DjvNrJ8Gi07U#uIqGmOKVkg?lwbt92Hu4VDrEpe zY>Pa1!$U|APS{B)i7ggE5$~CcG$ptQT^<30AFrgUFcF!-9Cp;|xk#Xd-3$u>SaGuG zaw(}l;q+%o{2+Pi@6tF=u>jLVl-URZhjyM2Vgmk?oJ2;W&Kc(CP-W4hd+)lQ3%vjU zDGfVcj5QNETNtyUKij~ESW2r(k&tsIEmQbCr7qu(HQj*{k!q $OHT1D-D?wj+Ye z!Xf3|cM0`%<=p^r6yL^oEQDWseTN)2AT;>arZU8pjCx>ytf=`dENX={Lrr^uB@KNt z=ZU4UHtxB-Jyr54kbTOG+}VWlDf!oalC0AZUs=*6US3x-tYBdzQnplTe26k|4fK0t ztX-UtveenUgww>pK6uXf~YY|D}g9`MYE zH3 PLS$V +R(h$6SANIBT0kJ 2=Ty!D1 zQ2t6k(9uqQ%HflkZVZ*oP^Mo3N*E>>0d=62p8^G8y`=o5+yXG>VuT%^4H4NfKEhDM zc~+znUj$dU7#Y}>aQ-eAkPxSIk@|pv*-0C*)79*rUt2}U$H%NtplqFB;^=fwoG8Y; zFcvg1Lurdobq!djP}{XE5ud5x
zxbp-&qs5O&ctpFU+8tOv5CjWni2D4|*%eI{KwfFGZ7HO70@*Zn2v#&Yv9(LK_Hv`n zZwR61%wEmi<_ctTsqwTU0d`m;7?5-StbAM0aU+)$t#!JZJ7@`)3ncRGTr+lxn2yPf z`faW0XRWD{_;-*XJ{S6Y@+VPJ_wtH}a6D+n&0S%qU{zM(R8o2@Y7ACA>b$|8oJ39q zGRK(g;?(0GAqVU_aY}JP2q1D(WiDUTvPhu>1M2V9Q0<^d_L%^P5$9%-C1Izs!kU(r z5Q&thOjWDgB#La2T=Z&a8<7HF_!ZWPhm}-z++Zn<92!HnmauqU>XJ77*v4Ip)~aGj zN71P`5WOeyLOBXt4oaJ+Ql3JZEzWGT2QM63A?9tQJXewTMT;Y@g!xIld!
&3p-GS@q{D<;pZt^0~=W1 zyS#uvs$FCLY#hSIu(0DF0TE&HuoBU%iGVtN{cfNLQ`n)Ws8 67>qCe*b}@p`Pf1g|QrIXJ0-(_cUi}P)RQ!h2D-Vl MZph_fu5@T%++a{owgR-DptV=dCCG{$>WQdJ~=$G$ej I-H+^= >l~btf053W28bonm!7L9*wA^|<-%uzaGK}&-4TVJkPn>G7 z7C1nR=Eb&(Wjv*R{Vd1Xi1jD>LY~S4U~W4{d*(biLS`u>tsAA1ituuiT?!Ai8yMVD zg9KnL$SaQq!yWnYi+a#&cG nI=}hQt}&6rUe`Vg zlOP^4=-VNork8w28^Z+w!Qaq$s81|671=YB4+&6 2TB;kV*?wx4_Lc<>6KANyA&sTDYF|9KRrX4(dhqKLM`WXQs5Gj(;n@f%} zbd)20H1sq Rh9oiZzBY zMELcmU0!ka9ZEJsJmkWqo@WPI((^>_kKy6A8QhR-fLDzjONBs|Sfq;t*V(v_u _Q-?Pe($0-BNfU9Hs9lMh$VMsP`6x&Gu;9_oKC8bdm@UO#EHGqb9~S6Wdg0n_FF> zQu!#U>3v^dQ%?d~Vr)nr&Z`aTl#ml538f9@6SPO8f4DYNhJt~BkO#vb%zy$Q5eaIB zPE}l(sQQ;|D?EuW-%w}(Gi<7@^s()MgjB!SmgJc&)4*)D=N{R2ajm$Bi~QMu4W%F8 zD}j|l+-}9!jKvTl5 UA~ z4E2|fivUSrofE+hW~#w-ke$V>GN8|ndYm;pD Zn-eumIz-1baMB zyPF%dBm=Lz)&4LP|7@_sr)HP$JEBr5t{BBhlE~*J5rea=QHL#Q^n;N^nivJy(=*LV zEqIGAmxO8&;pLT$IVE_v&%|! j${mifr<<)S#9xUrOaO@-9w|3w+FvsSLA|mdc14mfNageh{3GMMM;v?a+bIc!-m9 zj0So%^yLjkf>T{qyi`qNvhX_3EIgJKWhp{0mTKFR15{v2R!U-5N>2$7!u-}+E3ewX zlGK*6E9_CSe*}ska_t8lsJ|K_k~j4uzbG+G3MjgOX5{81E-aPkFg_xljYwhs?o}5E zcjU=Mw? FPjblCx4Xbta4d?zMWc%?HeJGW&jbvmOi)%hsbInDjxBRp zr4&^#G$T}=r%^vnsat1BZq`4gn2ZDyePebdKQZ6~KY_Vyi=sGK6+N)Dd8~~wt`;NF z=K#(#&^T-Can-t1${Mse-|W(lHT|NKxM4;w5fYxsX3kvs$<~V5=;L^0^K0{oZsKsr zCi-F;vHWM74#yw*=JVQ$Y|GAI%4EE`_&frL1G8oPOtS;=rPPujTS*i%xuW8Fk{NSB zh1^09qx(XVP=f(#WEs_1F`~Tg{DlL>XDovCR?|wU{DCi~4x89h1khdnnUc>}`Nw{> znlec|MDg0g8)gH&(`s5?^{b6SEg4-BoSLkBb~I_{^}?uC_Ny<-Q&haBCDc{~ 0!bRf=x7pfw zW=&Kgukf9&YFX^DbVpF&o2d%u6?4ZNfJT#w1l#LzaC&KmzrV1Ax1yX23(;$ZZ@Rj#w zHlP}4@b3_x2{?S3NV$~+6^vN4Ecy;lac~B>cRCm-fwF3hC9A7MC>1v(1=fD9f-XrJ zK1TsI%4r5j7XsE2M8)J$9;3*pAz%)zgwI$b8W-)qSel#0B-%9`zw3C=iyeG#Lk?=U zX#GKW?yk(Jkg51j?VumC7OnxJCYGmV0s0iOv|)Z4C gP}G{O YVzmgnnQv0o7Ahb1qL!Zw)JAE1aZI`wllXGCd>1{fH-b2a)zlW2m@hw MvWgnrSvgo*< z8JTqm&wGRZ83Wo?dxR+mz6Yo3Y! -t66X@6hc!$sH+y~0JoB!+-T zpM8$~zCEv-_Z+R7m>~hbI7cOlFAS{pMSs6o@jHz(kE@}iSo%4Mg$V4#^S%vZwOz-| zE++DeN6$=IHEj4;PUksV?5?y`g`?h?M`dkwau-q!Op~$7Pv*0KRKwqUP^m(iC%bz{ zgHz-zCgYdvzhV)g5~Xx+f%8>T+^~jxpVe~{cHw$T0lU1i!dE-^8<*tu_rwloR(r3~ zU!TN%c$x72vc%qb=V+)A_q1HcV3u=cC!vj}P778zCW08tIIWn=NZpCX{YKKXK&z=V zTb9>id}Q#Ug7>@N6}cYnqr}AKQ*ZLcSxdVPueTDqcsXyWUq@6Yb?_v1QP{zW>sNnj z5#kgC#mP~~9%ch}BI^0{o_r~t=U}=Rv5=D)_B$T~tT2L72oHa%y>_S~-@e-$2t}dJ zeb<*Cn|LQFJ0U1M9woAA%sIc2tlaFw@(_Q@&srI!?NnR0^;wt0q5uOG4I*)kAyk}< zm)+S|NswrSuzL>9R?LAN5qxy>I0v>%QiHbge8!TvQR;mIg(j^$IVHy7Clq@Y%p8DL z4jjN``HAvmB_PF0(wLa~r8Q7&FSlTc7BjT7d8UH8Kj;h1@>`^x2+@dD35zB2OMoF* zG_cTiis>h-X18?Svwa=leXJryJ=o%tkH`$|5$RMJQuvgW$u?4z$Inkm{D>k$m`k7B zG8;F6d8LklGU)pZb8L}EDZH1F9^mnyJW%uu@-qZ5!7Lc3g*8_-+|0)Lh^de;(Q#Mz zDmYKJ+yyi%imkgmJ2wFuS$IBPHuc#i=4~EvW5V(2J60xBzG|$o)Zo@FHRxLL6vvc2 zSY}oBsI<8AoFJiGKPLDSfjN}oBe!Lk9U4D@pR@v5YpJi{MwcYd(;xnuQRX$hr*`$~ z);(%Ied#hA5~|2=s*89Cu!rM9738B5f^u5E{C2a|RN9Pa`pr20QLcTnNc^iVL*bH+ zL%AP)brj<(9aG`-jL|oJ&Q0uMO(Ndm#$k|zhmO^=b~<(PQaQRw451!pqIci>+{eXf zs3}FPk0l2i=onnhKZ<^+{@R$CeaKVoNBuD`zDXwahxpNL!WS+|`n|{eVIG6;1@|fU zbun$pB~cLuJs{P5;sR(-g(9aIDOJMLvi$gJgO1#NzU82wG*(+%6&-VXv>hjE6+-Ic z=~(AQcN$uDbvwA)4Uavq0lZd;dyWciwX9A2d#|W5P4xuhB%aw>sp#LUTZzeQJasu* zJgi5b(G}U{OtM<-%`f|A)8c8iR^L0g?Hjy9)W*5<;H|Iv!TRCY >|a!!~S%>5|xGQB|=RPlTlXFFn7v?X7zfysQ?d*$=jz*u8b z*#mE@!PpavE*7OsFK49*;g6ti&^JxC)Z2PobI ~1gsBb{Ev0Ds z_!X`v(MPV4brLEvm#wxOPkX2BH@?146NxB7G_`WzPWNQqceXdTd)JblGU#qQy}UaI zeYO;($N!^JUp|gnKFkop3T=o9wU?VwuFF4jc#Qip(n}{jH-A|z>Pg-1&WFb%S5`Ei zeT4WNcYf%+(Y5jTas1FbedNVG-ZhB>t^1=F^6f?Zy+g=M6>V@ZONzVXMJuO3^H`y5 znuj!9dl$-hD{K{>u*4+WJ|*4t^0GnukN!M6_supti3(W?l9MO(XbPS`*z>ShK}RQl z_As{(b+aYjQu3p^SrT_Qf?b^>A)0NO06VFZgs4U^WL*{W@?>gvLVe|dNox6iUym5y z@R7mjQo6|t`H(jezb+#8B}}a;FNG(Y1Wg8N^O(e`i_n75Izii_Y};WEc5>8)g(F|K z$Q3ItEJZdzqui%7okNdc@3y~sN<+zcgwqmCjMxvvi5>()B4QzLZMZ3eX R1-r!GkF}0CPQ!kgQd>{!lmTiZ=n qr^O03#P#C-RBT zXD5&!=x7NG@}Px`AD)4Jj1URLu(c5|5heT*t%1l3%o?M8TL`tzQ4vf*6O&I6phLb- z@&W 23w9%nk%Clv|GC76%8TAt*Lm8&(p4Fb1(e6QmqwOrYnpph#MLw;{Yl#NiE z>DhLfkx&F)Ioh07yNQebHqOj;G2kw&H6U_`!dj2H!>}}-9UK-QAxF<*#-1hOZ_DJn z$G0pib~xC+h~VyLr>gCUbxC^1jiZc R&4Mb5dl;dX}zE`zkX!Mw2Y?oQ+J-MT)G<3amVTpR^@!yZ7e8 zejc9#ktpz^y6KJUORS`XWWpL;FSH|RDtjj9{>%*5)(_`*waO^`s6P1M+VvZ-UdXtP zoZwr$>nb99`nH^IYz2R1Wq-VfLd$PIl$9fnQsZv0vkE%t@RM{+{%?0vnfrDcDV~4O zBpPUZ?~AgB5_)98ZA^ye+)wT_mv=?$cCOULRg+wnQRkGHE9RAG16ijGa>qtM(20fg zl{8@oO3zkkCH|0W0e2=nrY+A**xFanGErfB<{=H9Nm3iFYjmFhm-jR%+1`- z%kD3wq7ZC^eiVNBq{aCf*uM9ae=3RM#R!&xQ*O+g7j7`6mn3;1)N&(klil7rXDBoF z_~Mf}I$Dt#qaz!f%H?nP>d&HOKZ$Aos?FM2_4YnFKWeQaAEo;t>{B1M;u+2T%<%X$ z3%l8Dj(-`oQ`@UXuncrMk{6&MPlAa#Ry2|-aoSqo`@YN2hE*PKV4lNM#P`1Y;q->R zvP(@yY) Xe%GK=h?lPbdJ(bnD%hoz`Z>J^>x<3UAtE$md&B~j|1_T zC3=DRKj#nydayq|rY{9UHz z=Zo7e0STvW`eidI!~dv#wcAu+GY-z&qVTRfcn%3<;dvT5oA_DE^Vk?;$s}}BO8pdP z)qm>Jz;KWgN|`hnkqG^?GoYT4#4@YJdg6#*n(3EF#Hnm3U$+2{-Nk*(z{pf*q|#1^ zvZd4A`%>4Ml(=-Ekn(_+*~6(lyT6Ai&(ITh+mvNr8pKQt4F?B2Q!bX;gDdyZPK|La zGo~ggn|zkm8h?%0B({4=`fSlQ$X$K 7FG<7XA7N=z$yR7EyL>QtGKbyy4{<<~Iz z6&(w=s)*Fji2G1BobHiNUSud>Z|uOsHSw(3iu3XkmLyN978KDN2p_>bq7F-&>=0bt z{aHF|;1f9qOJ^$V@rjN~pAO+2)t`Mnfo=JNqRB%ev`z$uDeMspTxb(xc07HklX0O% zs%TSHHP5>xD$_5>K5ZlNWLfEnDAAkujw7T$V8Nv-Dxr1^<2AHpUYk_*oNTJ@7I;4Q zlU7H0pY!ykqEk|P|LU*^HoG8y&A+kjz?sdzQ^0JftDSO`@xD9 D@Oqc0It9CBHpLM7L fA4W~c%==$u z-V@6A9f=KEc~YlieAb87R#EjM^!(Egg8NV9Yu;5mq}yRQVTbbXe0VAe>hf8QO5eDb z`t5XRIEr3Lhn6E!VNYbV`5G{vuM>{1Y PS@(qPll1#YzrKcMge2R3^Zw+5EAM&s zi&?eL>8uk4NeT9j>ALv>j2DR~+>r&Vkfbh^UwspJxl5T09FJt&KJ`n2I`*$bt^q5j zezPaoS`~V9Hjf=DOEnmi((z6sp3TR_nB}uTB4tXxsbzR6u^XhhFn`ftMIbhg&$Awj z2)Cbkj5Tk)Hh**Pi*=o2>6+bQt&{cBa(cc{J+^85GWN?AKEZ+nygW8Q$hb8tBYS!3 z9kuRP3YMN8tHQ+i#fpNosY}++-jW81WS#NDrG8??33{FH@k0&DjHsV&2swWwP0I3p zm29{3Zel*N>7$R(X!u0#s1lux)#qU3hem9SL-^b_`sTgms6xeF?$QrhHBYm`?RN?; zc1m<<;VWbc0u;+pQFH 7m8@w7e>@=x+gj9YZuZi=Whu)^Ek zsUE4N>!dz*s?D(!{YApBQZeVl96sD>v>g7W>GLzRj5I&1g4EwXBY&k$QAzzuiC#l@ zV9p;kD89sb{o+%A6vcXaOnw7IJS>|{#SkHUev*CHmGA<3(3nl^gryGy`yzjE0btd} zF{@sUhm=*)*GafjV)Y~}tYU+~HORGCknwC#Mqw-R<4 L^L0YUv>b-kOJ>oULGS zkb^xfGW*%r34W3nSDGxHt7?h8IW66zgM3Z|8#3$6a#>F5K|eJ4gWiP{#& w>oDZ0d@JKnLRf2x-kOng199vd>9Q}rl9Dj6r)fB;_E|BYEto634K+?; zt?svOtKcM498as_e|67*ODU#iF5DK^T3+nADw|d;TMXxCjq)VhdIQ}HjImN>^P>}* z0N18crIq=6UsLZ=w%hJEy%@IR3wsolH_Nz^)E_yPlP9Q_)E>+uVH#C?&$ E5(QToi+UV_YH|K z71cWhJMV@{HtQ55D?WSE`q)`|ij!QOEd6QxZ(p?cO5`anM*XS5e8%-HJgtqNrW)RN z&iE`WPw^eSTK`bf$YMXVP)Dt9EvjeKNqs<+tP(e*`=IImS$=TY{n>BUMe<6+0|lm6 zx<}Q%4sTzQZO?tXl;^6}ZL+bUI7ymV@cQ)Y(dvsO9pTUQT6a`mEKIMYy4|@H8Jswa z%YNzvh}r$%%Q2`|S&^4Oi%S~ueR*LYQu0BqDC2{Di)!z4tl@$Z7Czsf?++TAXb2sf z7e_AEA`44I_ B(R>M!gH-SAJ2eomcxI z@zIH+^~@Hf`!)mCsYeT4?(x{FC2nSM4i(Qd>+63+D}C&nJAT?XT}U^#_>`@48^;5q z-l>*9X*QBGpM{4{CY)7xod~4pYjUXlsz{^a3o{bu^HCpF%-`zWy@)0~Tb|xssePny zC#zF=(Cw)HRK!jKN1OoHFF+JSA=ko+8?Gw(9sg?p$g-#nxq_lD!b1M@2aP!N0T9t} zN-znyyuJZ}F$!13E%9aWV?iexVntW@dL)=9-KR%_Qx_gUA6FYr!V+KYeU%6}(nCR4 zJ}QK)8M%lZxEx&M%JZpDjqt?9}RLiJ8w+4Y?RX+doDVIHrHgGDj5Bw!&6#Ges z$zb)aU={@fBxIP1e4QAulrO`C?*-0BsVDvkcY@0W=g}-20>>w`y#XWNgG@JOl cr&4X;fP`{oSv=}=NSr&VD?e(xAIT*f{6(ZZMW9Fz@)f2PZB!OP zikS2V?J%<~Dp^8V749D&w@e43&wp_A=1j_GhiobpjLszzF(^!a71M0kuGFW`XX7Xt zkAJN@?_Ydgv*nRrFFc?5xg>EM!QLr!`EjjJOp|-o&FFXSKxwE)y-NL4w~l+g+N_LU zru+!h2TdON6drzy_!6>Al2_*Dd${3mwc&Jl4LE5HYIshka viD@GT6>zxfH5et zS*&mA=>@_y8LjUU()`8C;*ARvX1L)tGulT94!={Y)SdD>eNvpi3%}NQg1kKNcz)DC zU%beltY6ZXk7BBM7iWKbuzzvz@R3AF@kq;0hwwZy=9hSl=G)6j2TBf`Ow_Tom390{ zPjs-Ij|wRCeTO@zDRk88H3-Up9C?};_KcaRQOB>uLGRLecNh8mg|}7 AohMQ$Assf0Wr_M*jdUT!p)2%c@X8LRTax6u??lrA4Ky zNm7)Q{;A>hRZ20f3B5PHz82(p3Yf_x>COrIU+QJtxqOVm-TmGblW#Fr?i^jiu3>qO z-Pi9FpZxoEC?zkYB%)ELPNNVut^7qgQ;neS=*=iO(|KC4v6&wf>z7OLoCd`hTdcI> zDO>hzt55)Q6akQ!8;{n2tR07cfM@|J zBWVZ#?Nf?C50@lr^q*>gPnlmVZKWc6#R}B9u$n+eU^uB~V$X1DQIe2Bq@Bqt^CFZ; zGC}Xh6%s)-k+BDOpciokGJDVf2_^}VKE{BrZOI=>0fxxikSGF`5hRa@s83*1Uj*){ z-YTL|jmZTWh$KezELtG#>L3HEMN2y>w@|56NeAMtFiTYLDnI+E2$Et-bo 8lWmU5T3$rFP zr(;$W%W~k`VgiZZoyYR6h{uvDlVM6yB!x+>f}sbM2T@+1?NOAhWh;pkmlOhIleE<( zv5kwZotQhpgZ@QZ7~68WO6Or^lz=7xi2SPfN0}1jgb+X=6-O0xBYhYyOr|#<$W_2( zCsCe$C ?y_NivUI93;C=aHA%llzrkkc27I zuTp?X{ANhgzl!Z=3#C#@w9{_Z)m zRLb8=KokL`#RY;isG!JGWY@Lq zKk5^jr{2poMWf{J_qDI*(2o+}w!4b(?!7r0>(dr2EbdnIjuh4tiQ5%6(@VQ;1;!8| zK}#u1YXuFjWRd_%7wVF#@}I1j%uAQ;RZP_9XXx*3Y_{ipp1m%1dp%J<9F>|kivY=% zff#M33yND>;!imB)w-BE*?nk&>K25gXjCl(O*?Kmf<)8SxBElc7>x6yH1Q`Cof! z>8B^D?Po |&&2eEYK|;8@ETR%E-qe(BpQWguGz6w{8f6t>c)9a>h_r8Wps zONvlheQDIA2Do^-)YVrBw3L;$ZEdG5y!YjE(RP0iDNfP&J9@A2vF)dZj-gz21EqLa z#x0kJ=Ij~O;Fz_d-43m%8YDKdq4<)v!U$J=D%_B3>Rpw@%6KSKsP8&{7uUn0_*-6Q z&wEvYjvpH?>E06YC+n+T#%Gm{L`MGroq8kA5DkeQ +Ehp-Baezk9ZaWUX=X;pakP8 |z^h@ohU|;O3P}MzkT(4)`0h|#5~QR`hy->bwqdymM&})JQ?j6+@+&f*LJBu6 zD{vJ@e&01&YE~JwYf^zAN6ktxxe3dW*qB0nDFQv?dbwKVWzm!osDMcBJ*!|3B_wGe z03)|*x-m%srpkx_2>wE(29rMWJD++3qxC;LucrM!%$eObHW$YaW6tvKuTyN<> wID5Rwp<`2rnacn!O*8HU1sH0)`H~~wfd*J@=2Zb z!g66FJu^w|eSF*cU)W|G`D4)Rn&a3$Gn#PK<_jDJ^_xH1Nn7d0VgCT#GS{okaWdoU zQY8%AlHni{Q_bOg62BD1RI3QNMZR0}SM*JC_nG0C2+3uZkMmDmU#911#B)`KWjLlq z{iuv*CEH=nBG(VUQ*B=c6wB%Iu1ZuJWtAj)O38Ce$<&Y{dt3vukiknmSt(h!wy$-s zxoY*-(Dochgi@hTD~;yX+?ThW<{h@l)>&U1>J|*v6z*3;I6cSgXKgMOukSXcgr(54 zt!P4nnhI2nE+y5tU@8+wYxo69@`YLo?>_!kc5Q6!ckjK|FCOs9inR2)zqflAOe?8u zV>q@CgyNZh8_JiL7op4*-!s$apy+v*A5WG;1un19N}NWZ6jEhs`A--9H*~1Fly5C> zB=_AnXLRlDzMQU41;y`EEcEDYUr#fZGm`SgC2%l%Y}0AwIPH?z^B;Qp*(9yR1f?of zy~Ar(xJpzMl7((Vi5t8ZfzYc3Mx-p?J3Up~+g!H2+g4Y6(q;Ji^P9}SKIT^GXI*-4 z)K_luZXDZLnCMHlxo-K$eS%Qg)XlQtMY4sqLeL=rMGDlN(fT8^eVeU9j8+;>R j()xoQ}QJik2=gV$SUyq^Zs&QCGa)Y&>$J(^~)U@J0AG7Wug1cpL zi#wY!yHe%2yS%s#J|!ATE&>PsA(&Fo+mAM)-*N<#(86%)ju|RD$$Nj_%KIFO*vfgc zMQHy3KP+~fzl360Cnn&p<_t3(vbA(KZHPMS46U0lEoNDI+1*M7NhlJMQlqK?R_fyM z1q?KmNv4#vZ%Z#Gp1Q5Q*1707JiEs7HFdJpH|W<+X5Dx!)0R4e)r_jkuPV~*Lglbl zu-=3ysf99!KX?)4Iui%D1|yF}*$8)at3#_#*~-c4w05_&^8KZ)-o_JqtFOPr^nyf5 zOl`e;v&ocFfII`({7?c@n+^<61JqUNfTP}kfl7()vCq d|_9?@4ra-i$DR2~QCR)JN%q9ec8 zngT6?wFShEAbU_9lEr}uh#PjR)Oi}^^_zJ!A5E&*!>BIJv+g$UTM&;hFi>JR?N$Jd zB4bfWC%pmEx|`JOjnV9-h-Yr0 zL1-zsxHM?@;NNJY#D{z2zkN}cM0&8LvucAcZ z2Pb5F@_5+$Me|2jEHRvckyyUTnQ1@_KMi5scX@$C!d!Jj@gX~_N>k;hOv{@Z +(RA4Rv5&w(9#lDXKveC*4YFlDh;TR6cDAfRHoJPz7fYER=TX^ zl`R{0vw!J|wzj*>?5?caO4pmgMN)8r-+s3G7khhr*MxMQ$%~8*`xfeUKJB{+%+5R> zz8GTMZ7ej^vSC4M(3oXJI8cQzND{O3db~!8#M6pyEj`t?>29w}-&-eZJGa&0^=L;4 zDO6XNCGvMX+v`41#H=30@tl7cw9VPz-6F>k7dGuC=LuULTPe0$8qyTvo3|@iCzvbN z6*cv4%yDSblA}TiQ+BgmZ+Fk0_uE@Hp|8TRF^hLvwqtC!)E=N #T4t+!m5*m5Yxnz%R{_UZVe3$E<@xQX0^(8tyg^f7iSkqufTg61u$WgV zWR!K5z8BSO`FwdC&LoqhoSurx&3bG@?>O#!vb4KH`C}HsFyFXc-V3)&k1_?-yM9t$ zZEZFe _ZDncIVGp(tO51ZN^jstvHoBhb3w$bQ+E;hGEs*A!#(V zT5b96=4S|!S)}y*{Mha|KTh*jH)m~&W)|^0Ue{7vxWz881Y#~Xc rB=ARYSf8xP+K6u0WLWry4Yz}qa_75712vibhq|<*~G*`g;n8- zZ9Ur8;q~|#^C f-nCr{Ee%Ab$aShzLx=^;#-hk$<%ZWmjC{1$c;H&5Ut68mN-nM>EmYZJwT#f0^ z3h5^l_th;fzu$jl`I|}5TMXHQbwdWmb4&O$t~q$CSA~mm!wxu=peeN^1to_iM?>H( z4#?EGOnUwgO07D%tM7Yh`J#O#s(jtg8^x75MXEbm`tSC?r!9|6LX{*D5dyu5<^imp z$AS7#3zBv0LHVE?Wuj6-lgG^f>RE_8kEgw5M&&Y<*hDp?@Sm+sL#Yw8vnPdAqZ GLQ!c ze`u(d6dF@I4gP3Uo4GWZKf({vg`|eSABq8I41IZ^0Hr_#PztR>x$VEwfDvC1VEj-J zI!V}qV_`r;Z)5t<8djB!;3W2vYvkvk4wWeIMAYf^0nn)-K9Tv=pk*qJAdolq;;&BR zDs6G*+%YmtdzzeGnNdewjgG*Iu}a_?N|tv3@3^FAs4rG+5>g{=yH%0gu2M&Aw6`J% z1PzY;t7Z$CS=btA4Z=#k1#Bp{s2&IjMxaRVR)Pg8Qojh>;($jT$8cPwfMYqUGU5zi z`F{_#a`N`+&%(ng5=?g|@Pv)jq5#~Avq-D5P=l1R$98 79%bTn# zAzP@igjzhEOks$fI*LFkdf{diNeTgC5)ObVQy#GNT;-#Cetv3tTt5g&rG2+N@5$B} z)@tgF!|25AvhD!V4Xf^4Jhj|iSn35pX;!r@(vnmVVqhqcbgT2P>V`ezFw={Rl9r0e zziWQ|wSK4AxFsbVI-^Z!wf3Hj+H}_qOE&qB8^m3;u~cbv1E~-|0e1) lq?ICk$ECC%QBuAa4iQ>)`|8cPU)43yE2ZY|yIOdEmhXQ~ zH1hBC{QG-4XGk)BGt(?170$PrUk+~X6@1%a%5n?9I)iR?`HF_rpp|Tb17Nutl%*8? z0 RaK;?$kg=HL3QXzZJ7Tf6HkTSRlIVPu=FJ-IJK6LlxUh7pP3esfMBTswYm zv3r|PqWgy6DJr#UR6h}Q5>q8gTY$k*b$UL^ahz2=TJD}|X*9gj+5C3C*4JHUh@(z0 zyLOfJ_L`ZQ{59QWJVzJ7UBmGO+gK@Sx={fp;3=mAhe|>96u9ca2ji1pS>e6EsW&)F zN4A@Dchg&ayw2YTsVK@Vy%DM%MCk5n!dbh@7*=A$?ehL0 uKxfN(D6 rVX8{)!k<}7$YGGmnr#jRA!o_f(pzx~)Re8QCuG-WhVkq}sc6mH&t6MQdo<^! zr r&K}4>d`zXHSh(RP3Ujoh{4A@D+PEd1)v0HoKwSC+fb8KRey!>?xL6y-G1= zFocv_ ~6|6B~CQ3haYU08%o?# z&G YPqN8o~+V*LR4kpTJ>6c*48})x9gTMgnioT=P%=~+F9Fu&hpCR z%XRy8CEX=<&aI$_66U0+A>f@-0(6xHpIt_ha#z(_+S~K
yBTTxOI(}q42o@pyBHtBE0)6-**QjDgpd!DQ0{O5${Y#kWB7QGAfrs0JU zOA8`K<7FX05|xdJ2e?okl7)EGSBp5+X*fKr?GZ7y-t}=&R5m6w57L0SG(urq_Mu$Y zF|b06ZYso`ipd}e*a`WmMppw#k5t6`)PXsGG>QU9KB?8X Rlvbb?NYn`+o$4gwlh~kC5vc9I=R#zIktRe(V?wnX?hQ{t zCWV5_cih3C7E|#6m=pr5eKG*p{du4uUI|IwKeYh@`X)Ui^Pno1WCIkt=vx@YtK8EB zD}fdAbG8yh00-$)gL?pgr65c}J3y;I BJrSqSqZeQb8S8))??5y9fN;R2JkTQ#&KL9Mt%7ls=We-HGl;|@k7>>EKQ zB0CMatPpe5IxW;lNgMwFO0qEOVbpw&6@J(s5Vx6MDd2qy${5mZv0K*8BaI=V3cylG zw`M1G`n=GebvC20t!zdiX72iKdXCR<*E`ml)0fonqblW0ad%dBc2=v!?%Q|Dzj_QU z)1)2@sZgki04Hf1*T%b5+N r}bxzpmb!^*5_xyV+U>;AD(7 zzxx+#i}zD*tNVl%3uY5;yPHPTkPE6O_bmB}BqR;tD_K;4pM&EuFBAU&r?Pys%+p%F zmc5d`nqOVEDdA-w6D)mT%h+|cS+R1*8o9=jgKC5}q^ZPy_10QOgEAAT^rKM(XiJLp zn2u)*?7Zt$m7V01dh2$*Y|`IbS?jaVyAz0Ur>?;|bCL@<_7K6lTWu#1Zt;dx_M|xf z0G#6iNz{1#%d6Z8@>^EGBo9YIrCL~Z8M|h;KCa%nrK0GQ*&|M*Q )O@6cf~_Qwbn7x85$ZAN2D8KJ$})8zn{Vd5{IvFY9gZK1$t xv)1W*Smb>tr8TTp1%suc`1% zE2h)7{{Za0oQ>QZr&U_|etk_$#v8W5Gj+w1)r+-gU1jhZE?hTyr6pQjN@r(OC9)vv z&_LXZ_Si_qQM1t=cZk*Q=XA9;@1{As_A?g&j7&3QexmiWPN5|W3eu+x5S?tT3R;49 z)u{JKDz_A+7&zMMT%OPTSmjiwO1+cabNt!gncZ^+V$9ffEoqxBac?rg2}&^wkl0bU zXlV7RwN9r309oVANK_P*gx5cUN?2uRD EuPCSue27&=;S}Yq^K^gYD)w9H)XSL@GGUmm zEt+x;V7al!t(bW?4%rol9b*r2N_049%v){wQ6qH7DkUXD9nF?mEB(B`J|(qazmzm) z%yeI=N28hY*Dl>=XD%|r+i6xRe3ww$P7qaUT_aMhmI_>9N+&{r6EF^NSeJ*Wqkj+P zo}AZ0j7 =Q1P(<2 zbfQ4moxP|Da8Ij$r2r)+L=ZnZ03-lFAW!w7D9XaBFk`&cGEU{GSQg;>j%b?ZWQ{}% zsE}ul#Lx=3cAnqTfJH>ijt{rJ0J6yvU=h#L{N8|FO58_3T8dAZW@NM~Nst0${-^b* z!uykQu~4}H=}l(RCy| PkXnPvu)MPR0(-!yzdUm3#cw z;4Udi;sg)nRy){)q_zkUW6~$;IH^T4q4s>HwYzds(+Tysr4Ry8H&puw2CRy^2gdh^ ztkaA2r^N1b%=g#9>j8{B>n{;0Tr2Sa0oXu++zq%B^S&k88hCm&D>r+${tu|&>Exjb zYoXcj%gbys%I4DnYTrX_A2Q>z!6#OcJCiDvPRR#;YvJ<2M-x8wPs0~;UlWLNb~?4j zHtTrBh1kRJ>($w)w8fpue87N7CP?7QluEe-?mG_=#Bh+ENmQw 08eF( z<{rG4iEel7JFTr|i;Gq;WCWIchT20n9$0lrLe@c2q5vszDl-RQnINe6Y)4@Gip@h* zmHhW|a(uPf>#oPAp;b-^^MCAam5vF4W7rLihAU 3bk(SNg_<8U_n)RE+fM!(1es#^n8}DM7=My`CqBarHjvNv!~)WiqDxx z6U{c*n(gr{I~6Ox@)C_YUex3TZ4K&mXHNeByKAvgi@Q6)ty=Y!@2|DH-7hDvHEZ8e z`kX;%)`qTi8>u;?FIit@J3Ly#{@n}nw4t>tP+KnRZ&=^b ak|vg; ee)tf}>^Aqh{Iuol|Hg{4bzwIRVe z3Wz5`1~8{4^+tv=X{MJWI&{OT7dd`xvtA(6D?(J#+q<}3wbNQt2|;iJG73N;B{LG0 z2~hR8CgV#}=lI_g?2Wq1nZpmgvADtRF{Uv*w`in1(=J`P=UM9qL3D z#iTTluz*xb)2#1QwY$Zsnp*z=PDaME9_nUT#&TG|uJTV(vZ-a;FcN<4duXL8_L9np z^)NyT3J&N7J*%0-aI POahv$#&iWl z05%cD2>@A%+|TJiF0~ybNdEv@0S6*?-Y5kY0q2do&;irt4T+iFgrh4GDT&lzd(gQq zgmkB}WP8Y=TboaRfvE{jqXSW%E9B>JIza+889NXDYEaz8&_ krlGTUUC0ITc%eJWtN+FF%Digu6IuY$2$+1f2_KmY;h`K`!C&nYx93-tI1GMmW}Rx9|q+md+2rC*NqDc7Z_|CbSNmxNjkO@ zuSktV5|~dOuW64ngvCp`l6oci?IVb%;!MW)P9ok6997_XVLFs`sx(N{N|m>$q#cKN zKNYK2hN`PYujb@?*9WQ9mz^4aF+MKtoMlZkrMwwrXlMcG2|@n=?FrxxNY%ejhE;|h z)VU+6hQzk6j?ahP{{Y#{NxK`ITG^CYyqlHVu$IG2q^ji$f=-gJTWcXue+Wz^Rnp?Q zWuvyg i;X49Bag?CQ?stM~!|}cn zskKrn*6HWd&i?>YO0N^Ch@I*?ncpyVHs1owV&e%{-=4g-abcwdx>~%pcod~gCR7r( zReTAMbgXwf@bKI%Vk<)G`E2jD>h9X|e=dxotz3|9Jk4Rmv-U3D6`XJjo3@4 Hnuq_JcU!%~bAkU+1X(CqYM6 ci~~Ds&Xel!YlRx}cLFl`JJdnzswXqXm{*C%LswypvXA`O({# zaK_V!STOD-YE WEOlg7G zwTh$f4&J`D+Hf?KDammPLV`k6l+UIT6C+pQ1cD}av2e4@&SY`QdLkL`3C;LDi&*Yl zRm0ZGKXZbVDR5INXo7UOeJIc*h$&9#J8$8oDZw|n$i_Pv=cE{(1)Q?Qh7*pph~h2W zYEqTw7T;+BNCdXG05Fi0`b>|)6p0|7s;c2fGJ2j%5d`YlGq>F2oX?PPOfwM6nCM%o z4xBRmwo=Q5u&}2R+lkUp;s^?HlcSwr=`bzA;$1|fw<)qt%*t3dRS^1Jz&fpi;a6_7 zv|d{M?U0o{b^%K-CEyh8lE7NRE}ISnm1$a3l>u8cYdFg+{{V~S*X` OggJ21-M4kt7NKrJ zl6=G?p bvEAD(bvZSe*!9m6p@MJN?o+_rckNdZYIB24lR5`FIo#>Wv(>vf^!arh@j zc6&d@Y?EpLjr5PDb&|29TpBaH81Gp%%acG7l6RT`nIR@Wr2z?4iJA9`0EtjLbMgNG zS_6u3M&s2$1xtcR*w729Qc2{0Y8gu8C14Y@cJ`<_qcV+%kPMB#O2ntoxEhQO0qyZs zm~pt1gu;w^cN8)#wGaST2l>zou1|6a{N{j3bJ!|=cc2$hAn_uAq>Uj&9jXp4_eHUp z7)%}De>%%)YGb_UPz1*@`BaSN@-;QIq>bWx5nm`#XJ$^rXlW!#NCd$$YWPLiu2Q(d zQWLO9*zN}+uS(k(O5xgQm`O+{ald0(FkWp~^Ar+O@y}|UBX$nSZDvSFAOY>|TabaS zc3WFrFf@b3Zc~X=o~7xQbdVt_gZ!%K?qR#K;L ){DE`?K@*&2!ChaVUpM;pUZ!X8!jAj;Iy5*$N5xC8$HS!~CBKU(qqx#DrdVPj4I z0PafO?S98!f#KZhN?++m&7V_oVQ+hhU%ZoTX5kJJz6Yj69p*?-k8(G!g?6@ASB~9J zpzwI9Q`d7 JCGCngmPe4k*i9ta I(e8RivMEq$L_ccpwQoR{sD9#N?^n%~>Vuf6b15Ck*APF)lZn zaeN}|TsH5X^U77q*RRx3uW(9WK+u$c1cNcWM{l@ MyIW@l|N3+B;> zT_`Nw0 wRHK9-B~7Tx&7fLUsj>(<+tw6N zp(Q3zV5})y9iGNDHy5GI;?r#yyCA0+uyo^g_D1FKqPG;5{VFpA06_o{0h6#h9f?wX zL$vf~o{lzg)iY>u%tHdrIYn3Yc8*(PmQJ$XA!Trtr(CR|rKgx>MS23sK3P}_I%JO4 z8j_4Iisg@#o=3AVgIJx`TgRNZx4yY+8fEp}wQ5rQ3K?>O6kc~UH z`RVzorH;*YV;Sch2L!^JV* +}3SgVUj_g|6FCk&HY`bn_!%{RGEzz75qZ-DQ~CTi8Aog Nca)S)t`QwAILgp`yH9Y&=~E0wLX*YnzRBHEqun46_uE%C04^_w7dGavia z??<|YhO>|2cw5PqEHM`@6pTg7X2A(V*7&8R^576u+O(g>4O0IAt4`~E{i*cz*w|9E zwLXY^B;%)~el;`31z-}cmGyGm;?^aEk0RF`WgcKsRGp?3Mbql8<_`gW{boAivXB zPj2h#y`_9d4ys_?_k+K)XY}_T+M&J(f$j5ONIZD^O{4)E4|Bx|WbQnK@FVl~p%O|l zzTh5c0I6G$Qm=X$O5}XP2NGytrm{%XM0=VN$ij&R2?m5gC=vngM{a0kI}{D5jrRW4 zT+uZ898z|jlkHK+$tc-@SP9fS{{TwERwN|g0GWVEtN~@D@f%P9TXF}a0oYIrsi`nY z1LlBPO^^XHOho_%AaAkyP!dW`!attou+{f6n!U*e(m*;2zIUuUi}@Oo(oCd6Vs|FK zVHj$5r90ghCeWx%&fe9t7`=!D2oQJQ>p=X+nr~5n6Z7<;hbtYQ54O~(36N`Mj7pre zvD_`~hx|H|1A6FFflQ> JtF@%e<`-1Nr-y0mF-w8h%g_rM?}Kc||tZNI1D zzDN4OLaeZqCrw>OrQf>C=Gp3dD>$jti{_7;4zXc37{(&oDJep%mQbWm<52@l?ejlK z`L7X&;Y$}noTa*76V~wDTBO_`GeGlm7={{~>nl>S@0;W#DC*@SZ=nQlzvmU`Fuj?C ztfsX800!l1x78SL5XJ4VacN|N%dfISs!AX!P6D4)7z#>2h#uf_cjUgyNB0+w%vPtC zDYG8Cja!AM3`?qV@mk6WI)H>A0waMdo%^KiUAb^5!apyOEF`>Iop$Qo#HP)p7p|`m zrKP}usHB2SAD!3RxEprhW9X`W7$eZqnn>;+w(hNR{qo#-t7cfYa^ch #bz%*Do}Amg?F04`|a z_>3yGDD<&u$$7sRVM5aJ`;wBB+pRA+B@SuO*+?)ZP?Ul_pzN) ob)r+PEUg?iqy&W|fK&o>okBnhNfqd6 aHPqZI-0vv3t+o#(`rdnyu^88Qp>~M0s=w}{} zW}KOSm~(bl>l0YsXUgrqj4K D9#$h|)423o}Mtct6&T<1KUh+ua}eOFe> z3?lj4Z!na;!q44ZBuaG>sr4GRd^RegRHbamwa)!*@HOMa-Jg3Mx8-hzSZ~6ARC+zr z%r^nG#8}RmivTWM X1Cf&&n1YPyX8Xm@H3yMm3VQ zWS^&1>~}ntCX%O8RNp550Kwi{Ngz)Zv}%U{O!4zT3CROsC EYPOs& zsY`b|&KYJB6A1!qc9aU|vDzEAfB+xo`qt!QVxs2LK_Ey-_lmj^U}X%!;v?p)F(+c@ zZqa}MG5zacrMs8rSrM=?9qQ<8V0pW62|wVgp&nqzePGE-&UqUX! gUM+5CTS;Em3@V+IE#&`Ygh>gGcCAI D|cXrU2@<&Lx^QCP# ?opz)=yX86a(1m9X9W z@bo-gYR;bK!sI&(EO1}kB{z1f4G@(sN?*28iqg1=3IjsoBrjJW@1a8v1*2OKo+fhJ zV>01amiT?6c%{QvSe2?lV*cTPR$XX=sHr1$q(WXo#KB6V_>y$^x>BOmu3JKFJxkUg z@%@=@j0Ww1pD|A*I-$F?DGCm@f;JKfB?r=VCv?vI96ji(OZ*#myU^(Q52|>QZEbKI z!lLFSYj(Umxa7;hDj*dhB+TiBb|A^z16}S9Da~3&!>p1_Yu`Y6LYGFSe86O76@ sQ0+Vi@6=_X`!96(<0*qYVq(> ziC8x8nQGUofp2i-#j>~p*BQG07Kk2O8%j~TUca8FcL`TCa=p>$H%$7Kjr1ozT#OqP z$1waWAY(S&OUrj{JW}Y%c$r0}FK(V-+ncLrw21(?_#@L?>UfnLwIJ=4-`MvzTyC6X zw0}d^oL9$pUvO)@xowzp{iWTVg|papF=&e>Qq~~6I~84?BBiJ&X4K9pg5p6#acKR* zWThz6y)G?@Z6_<)Ta}%irSpux>AL7s4jn^VD>v)SY4U5;Bi4TeonB|EnL|9-qYk;k z?6B-$U0~>aI$Ty4bkbIk;Oy&H2)(y(ajl|8#8;{8&NbA8>9uUG>;9MZQo4R;2aRE} zN-|v5zN_x6Zs(Gr1Pv 0X@S717&q_2z&Y&?L%a&=CkahjBm{AtSLPngg0fsF)wp zfUlPz^B*7DfRsj=A}9$E4 orPA}6R|VD(xWSLGZ|O{)2IM= z?@*jkVpduTECII45gcx61cgdA-;e1)MQPFu$NEqLErSMj_lg23XdR@9{&WP?fhW?h z(ty;oCIV6E2EJ(Y*z6NZbwLQ8^%+l~E|!e!JtN=gS4CaeqE7DTZ^JCXDN&Gl_^rxt zFn5b9Z7@KMwynxgNTIuzmRU^hJN~t|81rRvm9`yizBegMRfTFz4z|wV!GrNuQ!|@O z7khR$0Vpx_tDvu`686g{Nc5let(ZppmAUjCLqb${AZ^83LA#AMmi)wrM7Br@k8b|} z%4oEAF`C+= IkvGlApWq4Iw(r1}HN9p4hzqRqu@NU=4Q_UTWsGtH9JDv{5pK9W8E+a4DC1!dY zUlDdq^fV8wctfhgGWoc+bQ1IKI^dO~LLXCU{YaBB8jKCA=&5Fk)aPOG(syjutU|#y zEh+mZtxFH6H|t)-Y9T2f@{VBb@4(w;EzMa9*ruJ%*Ojf&WtNt;n}?9&W#+vFURpgw zog;urQvU!U^c<&I)02b0=jF}X6?{2_Si|jCg?;+o `(#cd@vt_$(5^ z%X>Tgyi&k-?pl`m7pM2c5+rZgAqG!z9qV>@RZ zKHjvqq>W0_>W8Oo!~+AkQ0JIZ!b&quGt1*?-8W-2WUJS%vNm7LHtKHD$XX#zp|^ob z86p;y0tcWSFy{I|NLYwa+sE*T_fDlf*~!Dr-6 NWN`y zRN7J|6{#B_nM%@92`U8nTuug1+}v`pjIezE_APAVwjXuHFx3+6zm`D{HOv9HONsTT zSFlKe3654Kj%SgV!ls#vu42l}<{PwQ*k#(7yVND*q?9e@hy%?*{w*P}p~(VB?sqT? zx^|9>a;Z(rb3XJ_sOi4Cw8AkxSZA2OE!_~OEmRf(3M26-5|I0CEoA=Z9i1B$=m( za!UM+*P60c1&%7^IOEKqTBR kb6YXXvJ6%e_TSsxpICOTzClbho9 5fxII6*KbI#9_ct$bZzPAcU45 ^$icjHIV3Rx%INRjbhL&(n}aI&Rs!T6>|0I7o;fS;{TBCrHl;z)o$N{pe< z6$vEwC$#Kp0E8xZ^!tCGN&=xO`cM^6gr<3*H~>gVRLud!0tr^pKm^BmBeejdi3e#X z;)LUVLheBWx%m}CjfuuK7I89nB!WHbIaweD5JA)@x6Lx?a8XDwcc_42vL-=4+JG`x zB!LIsh8&V9<;LEl^E5JP@g(V;$9nm!mYN+zt$PkIkb5AXy6E1bC(cANBss0jX*vlV1kHW8;|r2hbF zkRnF#2rA?2KzNJxu5_x~2))XER>H8>(8e;0n;c1KARoW7&bHUT@i^L2K2*&2HS-?c zaFrD-WhJbZzHKcZt6F;xTiNQl*L3-9=+6jqnPJSn{u_uotBY~!Do`dC7aR`$q;DOj zzdT?ulEl`vFXXrSp31!}u(R2kBbn{na|yk}oGv&TZ9!{!MMW-oWl%@T)QCKOBh7uE zhv28(`1d&N GK_ET$VqUv6P z3WC&0Nm)qTzyUjZ^EE6F5{=Xr-hR@&P957aGs3XTXB#fqq!vPw)}G}jZH#lNaz2%_ z`?RHVehsyl>Gs%iQ;A;Nyi(1e3vFkW6#1T&{E!^q{vZc NKz`JyJGFV~Es|UG#4_In_4YuMX8V<0q zK?7H(REXUnUAC?2JVhmz=7gyvW*p;*VXfho)~p~}Fxx3CD&1jES{A}mg{M*7Nhxdt zKBz!Yl$9FsScp`HQ=5pU;`1X7S+#kQ^S!<}+csk>Vz&htr3rYa@Y_ 0N z0*^4vX{|~eKQtC?*3a%!-`V*a9hUP32aEmX_L3EFl7?|BU=yuHBk= usqPpRq68zK>PqHGdv{eQS|Dr zyfChnMJKV9TQqEXKWCB?joaAf95tZcFKmbG-)uOd)+J=(LS43bQ|bf|v@H6Nw535( zG@nmOyLOW_@};5IvVJ9o*yem+r5T?LeRxgNg`0NXLRJ9hKp4NbK}ilVsbHZJl 0G=$_T8@-1 g)0dM W@dm-b=!NpNQU0pC;!P z>E0EVx~*Y$_9E@8y*AG32iCjGbSo%c+$fL&N|?UMc!4Gqe(Y2`8s;jg)$wgFuZ8=s zA91?rT0Wnjb13+3>xMOu`kmq1s#vwE(~MeT_*N^AzJ&m7aRQez_F%Sr2r{eewQqF> zVB$(UmC5X3u`Z0^QL8l6pSsfb Qnm*M$w%6-rNqK?-kf3BKCvbj* z5Nqs*fqHI5X@Dgl@FIYTZ($Ih^`I465(wLqA4&i!K<~Eo9Ug#(m&^^ntybdDI1v-T zH4t#5&aEVx0tfUQ{U{2OI3^GDpch`9w;Ov<3#;3|wG6dkVvtYZC);Wh?*Zum07tz- z&h{k@h-gpZkItq@r iQMyh)75 zgyHS94j%o|SzfdgEx{vil%)VG-Veoof8iaSrB4{~5ZV5Hy-%Xz@k=U4pPhBXpUXI& zWW!s#KYD3xT#|zXAb>#nk~jC5HS`(JA~oX$G^}d2WW?FJ!cyJ4gs@m`q-u?ZfRLYW z;xRtmtCLp}<@`>?IvHYOOfeXMw?-FaguaGSmlD|;fo&xNWBey@KOwM+rk!bI@f<4N z8QLa8w!E@)4ZX8 !IK&Y_)pDq{1I+Z)tfkW=cD9gi(E*s%HMEL zoXK#dM@VUCNdWD>#v~7MH7b>}#{ABWY&(k3>KC_ yr5JV2!1Rtc1 z(kR46s*i_biBfL%Em?;bZpqs_2T5)3EGa4k5aW7?ByTb&LHG2ZYTV%!q}8O(ZX*$w zLmNGeTjBW18nbfgZIyY-ZH1J$%BN)m*n>On0fXAQwJT+9rfRzRm66$VP1XB2TQ{h= zXg-Cw@PuhV0H~DcR>3DqQc(Z^K#1D2gM{Tg@AFer5ha$)%efx;yw#IgbvDX-TW$q1 zsVi}!l3^f;^An(YNF_;-2~hQWEHr Nd`iz7?d#W=oZWYw(A@56I06>M;J7 XsWrju@RXoeMHhqFXx| z21J9fuR&7|ro2Y1Ws_sl9*pK&EI!>9*XmnWDR3#KTo4^>oytJio+J(7K#)Y&PYHy} z3o^V+^F0ik*Itp@=4NpIpk=H$D^i<$Eu?<&r&~UdBfppt!5*XoAc-8lDTcbw6mM|q z{{Yy{M)5__{2Q;`7Q;G!n{dn@_FdDq_?} no5GS@X=+e}w&V#{;VWqq3Ld=- zKM ;3n@P82<3CXOnj$sbrU1;e}DQAda*sqqqy<)j~%`Ud4 z2@3MAZQDia7SRNf+Mi&lO|$|v@l=zXrET>T>P^#0?;nxv?nlD0j}kpP%sp(w+rw}R zT=9Zh wr9yT92jSlld~*5e<# z)Mt58P=$Z)udr}jLaBv=T$R1re39WejU1Kb9#_BA*b 7TsFJ3PBQg0)kJGBsPBxDkw)*95f;bSH%do zazz^ubdT*rF?~Ul0!cG8Gbp>7RLUj w5$Wicoo;gr0C^1k)+*G>nqo H@ zB}O;QpXcYq-JGRsNXK}qw-|mcV{q~xU4nwxd?d^X2U0|GAgB)ejpn67uB}Mn zq`7XA3^R9{7pK69Be~-%$n%oEh$>sT=TW%bFX6d3%R?&@tZ_C z-L<+>UPzM-D5w94B6tPi4${O?PPEqdgxppE``mS$f%dmoF>s7iG(jEVxv&s5(b- zBk_on5w@)1`%tHI*9fTG%#I$KAj#Zm>pF<{yY#DXWw=i3dVfwQ5JmDcEoR?O^bl zz7%Df$(eGo+d7?>?sIjDF7Q-XSw0Y6TM9%p9@5&BPzdybw542nbr2((-m6McjnQ2> zrq1DIVTfWKKf|5E@dxcOmRXiW`jp^Igu0ay2^)wzEi?ECD;t z9QE2AsoeIK;P zGB$R}HYg1_deZT1AI)g3t7po=b(FO+0mO+wfI`VkY8A|UF(}FlTk5{3=~2f#%5wB( znRP=cxth8Gb# YKUN3C(``+O%EAGw&xKk^)eT$-zz}ArA+z@z|mRAP+ zQ2Bki9eKvmQ(H*YU$c9}?o;rOh 1&%QCH1n^!Di2yUa?nhMhI`e~*#tWuHWGYo4NI zeyL>^>~Z|Kwr{YsuMTy$nHH+Pw#;}_;c1jD4dNE}_GwVtMd%z8K3f5Ys~hE4*H2^5 zAN!M!wH>@wSjndJ>+*jMPguUrC0%81o%IK#S9Z9Cn^|iz-&$BE=kY4f%sxQ}zy29k zMtG8Ay?s-$^HHZd3uwvP)BUoZD~(f5ai3IrGchOBJ4JgFgE-mTrkOg5L`k6+J#-{d zrT_^vEu62fBB8K0RDt#8g>selCZ>cQWBbs{o%RB@cQMb!3nM1hqK>CeB$M$&B1=TT z(to{GD04trZ37}|02)xOhW`MN;()1a7%2en`cM=tav}hr7gJFJAkYv?A|QfK^q?!{ zz<`+ir~-gsY<`??^`Ia@AObe+Kt>h+02F>y2A5i-f(av3aBJp}S{;M5S+%Ii9~H9* zkaOsFd^w2HNUhpX=u lzrCk`<7j_#EHquF}V2ZQo zU72rg2p#IwuIxZ%DKot9v>LWCuo^%KAtV?wckNRHsT+W5QCE6`Dw8lZO HoC*XQmn*?HozP{h*PpV0PH@p)k3EzJ(k;j1jcm4n4>3-zr!rUG3GN>qgp%tx^* z-+KBF3gL63PsGlAYhGHK=hQ0}4s&l4NH(|n3&mlmONcAbM#cneqxI*Co-rjHhgO iJC{od&EKGqQ%#Bg)5PijVDB+S` z1BX_dMf=Hpyei>V?kidXz>-MWumqj=A;Ogd_<>M7f;usv;IGW()RHUF@q24$e`9mz zrM8|@fjqJXgr#zJAB-oMfRcU8u=tlbS&)=81D!D@S?Ug5a9;~dNz^)9gp@6MLbXS- zeRC5bZKO=@pHYU&m5m1+&gRKwq<#9xsk5zwvbB_?kffu^Bg{b)tO-dVOr=x5eXK?o zGQ3E_c4hMa0046P1irPyowjY|wBoca1PK~RAV@ncAiyAvdnqOgbX6A>;WkvSW3TvB z%#Y()uR37&?p+k#+&b&pke3#R6oQZzf&yIB60K!Gd74yJ>h;#H9JFRCVB!~fBQjxc<&42+Y_%cP;rFRh6cVHmpr%&hR+2vi1#m0R){Qw;WIr zgsjdbI|4h7)H4Q_`;#CP$ gIEB(n1kv3r~#H^w0~*>K3aE5cKoOc zl$82R&;nCnk+6ybo>Xn9r{X9LF0o*&gCZina~K_YI~~@_-b!Fe`c~W`$`0XV&;dIc z?OXJfwJNE;hiSKMT0tVVAi0n)3^WWVkJr6j4a_-Myflq5z}uR*pt`i)!*lWTR>NR2 z+d>HgZ4HNHG_4q(u{wS)q1bGy7rsg zI=^>SUuUEC{h9I)h~=Cytdof=C$!=iXt{M`Xt^F*9UgFOr`aWLCOc{PubE-!#to=! z^*wBz-nui(uDiOYSiZ$9ZI^J?9{U*UEg+BHS~w83kO}m`-`j3#+(lHC`69(lGo@xM zIlO872Kg+Y* *v8vesG(jnM+#B1E?6p4ZpvRlb!kY} zgaUOaD@an3d+dKD0C(WS_A52f2UDqqy1I+DGma6D+7!A0I#iJX1R!r4fwCm0@~)LF zH{7Sp*v^G#7O_PB&AM*s*MalfU^o!zNKs3HmpD<9Q~)9t36ZaU{sLNMX01rw+}kIZ zZB|cR7ubK#O1z7L-i0_|0;MKBE=ZCH5J}@;GmNEui(xKCyJA{W$7 9ZRX!k-_0?7>M;K_Ec8}r7V)VHz~Z@GjW+V8K)7;*xng;Y@Ei;(jTzAQvG*Y z5~MiOvmtBHq3R%#5I0l;y75$$(&}wcn~l$*PX^svV>V?RD-T vUE7&% cy=q?dww`Cp&B=;117r E#-tITGgpaaFrUr z&2#G)v+}dt+oL$I6+INb5B!=Tlrh}DpV{diX~FROv}6oQ!KW;+u!wref~&WaguIT= zVc3PXXTrccmWB+T19dvIUv{A_Y`y!vJh!)7$H=l3V=20;pXc~Dn X9O)7#_lFO072_Gj0>PqU64 z)EtkK^WF~X9>VdgF548hQcQw}TS~y5{{V_B>X>@UtvJ+N)z1xHlcwA{I~~ZC6SNNB zO1!EH?5aVXCJCWv!caCON%lRcQ!T<210=`Ej%Y+0kTyO3v;fr5lQ2iYp_J@H$RvRh zKa~qy(O)7&Zb#CFZ`283L=X>ssAO4fdXCAcIH#a08c#5N>6e!vMNJLJ1zS Bhy&{0!oBwDI@t*qZ@#!NfRm_+*QEgG7JTLO#vWa z84@OdC_5Pd{b&v$#UW{N2TIbQpnZ*DOI-o-kM@Ohg+3j;R5fLXTD4)*%;n}@;VaN| zTDtS9T3e7H1YDO|j=|)6*UtE^2~e)m{x4PJpV{f|J#GsVo|>OEzpwjhc!$-jk9U_d z-PO&`9-)(;xOEMMCsKTuN%PqQ-3kR^JIYj{Tnf~rp1U22bz-A*Vs5DARprdGaJ&hI zQo9v5b!?TSk_r}u1f-vU6qE5C>dG>4PA0Wwb+N7%tu=|}3@ *SM-EGODL@Jc zSV3EAQcmJ@sCVG|){Z@0FU?HQe9X6(R=h6q+YZIqN-&$11zOyyH8mj091+Li(s!M3 zeTOc-5;96wI#_&Di?i71{adtqD`t!@5oCau9P&KF&hzOb*o98qd+}QsO0J!u$j&kf zQqFZ;rF`ZkXNtB*-R|0TyHx_ML>(&KTgK%xJZ`AsyBIoIuFeiIHL--crsLQqZMVhk z9a8X{mkfHnC>n|YRB$0fXr1TgySPYrj!jmyvDi9$ire0(;a8U{WmeaLO}vj+lnDcI z{75oFk|$+I+$Mb;9J?Ad6K>_xGGLat-Wc=O46>J-Nqv_Bb?I;`k-q6Yk8oh_4MwFo zYRN&{LmG6q6n_Z0%yut2<@0SQI*kd^vOq~n(68ZALc&OcsR|MfgEPa{GUH=&GA~pH zA(Y*@!|_C7*-7Wxb><5E>zikbsah7=rb0-cN{J9wnL1Jq?55 M$+X-V&Sz&(gIe6?XrL+COyW{6I|?1iCEsFWvGU8x6Bzc0m8A2CB`1UKu?&U z+^IJW%1V#{0U^6AS|e8;%Z7UzcX(la Lw|O; zZWPt?N;*g-CKBef32tR2N(2Hl*J?FXmAagX(v&%m{iVJVUhzfYn>OINUlAA%Z@08f z#ubXPRNAl%THVCIhhiR|P)ip~+PJv>2G#CGXBg5-vsY2y(`WGC(6a|S-j_GGuOsCP zE#uEzXTGRl@7iH~I=0S@TJ>VX%NmiDFEM+|d@~+tDhE!SCpO_&P0<5nur5q#T%Acr zG&kAXp89L=%Vp9psnv^3zklD{{$}fR!yIn|zQJ#tuwGliv%Xrq%hwjEkmehWStWN? z_N5#LTT^(Qk^cai+vHawtXh(5W}5Woy{gR{F_qt*=hIKwlbzYm9uGQd<2OjVP8jXp z5|sq$9$RlIO@KQM4j@;v?A=`WRpi?E-|Bh(FG)tbYo4c|Xh?}LYrJy;X(`yrpbnIX z0KpV1o{vEKcMua4D>>!I8$|)nDExMVKv7MT$N+sP4i@0<0osOdt;N=jj>PZH3n8$w z+7f0Xy$O)ee-s)51twxPkJ5k&o7-s#s5Nu|=$H}!p4Ct&rq6LS1w&*Ju=;z@1PFl= zq48O>2BBCmAsZR_?Oq<74ve0sY_e-kk=y%L+#}4Ya^!X^R6!CTkDAzmD?25+0geFX zermv8nQw4Nj^eLM#<_D#e&^{|!(cp=?Et{|sR4qXAt&4ES?8z>lmbbQPrXVlUqDG| zRHPBLS_r|I)P7`fKu83T1cO*=;O9I*Rb&tV07pMlKzX_Lr+9HsUi>cREO!IKQHga6 zC2P#MQWA-B^3|{n<)TR5R? )eT#AK #$5p3Lpj zn@-HrYs<0JZk@S{-m)-^%-Ws9aZ6MzYQyiE8dljo;L4JJi3&*u39T5y@V_ 53WI7XAb>#FN>#TcA9}7(lw+YN$u(v*p7Ns|M9KG7*EcSv UV;my&yP%B}v%KK?zrL70{)Ma@f|CbiX4pUE&Pi-Pl{( ztt?_?l?MWrONodnDp1)%Bh(3)3Ybx@tf!%*m8Em6Wz4B #))o4wJm-A%}? QSJH^pc;G?w3= zbFqW0 G^JMIxkzD3_Vpi zr_FqxkKFYb%CBY|UoGdHGdWG?Rx-XO&S$$V$YT@CSS|CGSj(*fHcipAYWRU8{{YS= zJyoGyC7MqE0P0?`-=_9Y{{WG(7qaGif%YGD2EqKh;=`cLT_x4z{P?TPITB3aSImcP zlnLz#Qg-7_cDpfFDy3=(-pw`W{{Y#0%^o#P_$K_(?+OC827je`^M=z5lnDUoni!L| zyn+F%h@L(uP}pD}1I1pF pE-r z%UJzavFqs1PeQY;1vk3U{XOT4S=S0 Wl@OG(c-ocaI)S+L z0< ;P0N6t z zC*q#0d=i9uM-ZgAdafjTrW6rfy5Ryj3jnYqWLH;fADlOXlYQD1@3|fo)icJ+E2XJlxZlfNvfH)F;+L0TE=mc zi6MiC+rMsKLb&qoQy|9M6(qszPW`5(PF8vnicMU^If2J*F$O0O7ed1Am0f8hk!<87 zy4=9@z$9=)?db-)5SmfEjS7+RSro?ddT%nGJBQf1n|EGnB~Iz`oFJqH8QCh+#O)~} zwlL61H`La|$C-)p?VcrTi)A&g{9C_dU$%J#Bov_ujWTvmJA!+N_dPmNZ^E}Z?i%?S zXC&f}W0ts;<}ddpo6F?4Ztb$lkn$UpB!kJ;5J@}*Dl270X>&2>V-t&kgmpI&v$Zy% zr)}K}ONt>E2wDOH3P<8W*0Q1BXx<3d&25R7q@m2KhItpuyRyPo^Xp}$%B`DA(dQvX z6$nrXnM#0CQndpGLi#l&8F-4P6!bQ)!mcTbUtu|G0>yFsM-gt>=aFn~3cUXSx|UFa zl8IRf)PkiaT7pzp$dgvpw&W?w%^rwgxdzKTWps>5#aZF1c@KwBojy~^Y$&NSxk}Or zgUoi~x!9;FXwHTnrJiJFEAD|}IY*~hmR-c{F+2Q|i!t{r=fh`BtAB^@gW(0n6&$HL zf!YYrjtN38GTK@l7mCc*SE~H6>_^!3n(>UKk?;ChjozT#;g<*uA#Z95v{$JLOzsL+ zOKL*4l*k~;Y8{)SIu)u?mfQY(zZniUYLw$NbRV|&!|q6LI`mV;R%gFWr%x_Y{{T+2 z({4V5vi4lYt&SIbsZj&WX-;8xjqmDJqJZ3kUCu1!2I{S(lit>G(*FScU%=;Z%8+r% zK37l8OZ@7258;D4;@LY9$oNlD6>W^;mhL}>W>vU#PCbL&vzD_4r5)nt%{f~W9_0=$ zqgE f-m?+IolfSY|`gZ?uOo^upm@LNiuCxWS$i{`&g} zxJsH{{OY!KQSd5`2`5J#8g~9k$J(`D1X;wRo`ZcX{-0CowGEv>&hk6g(2pxASY#$l zMF=@1Cdnlr2?KH3gk<#$l!yWhd(gvt!vH`AeLqS9L0U|14FOL|z0dm40#Hx`leCHe zD@foSNBYnL^7Rk^BmF2!F2I%mP)O&B7XjN~HzI%;f=C;IKm|$EW4CVg89M+ZLH_j# zwe18zonD%NIVkRu4FRmyOu+K66q>p%as-bX z2s>}@QUHp1_KpawH(+zPipV*vBu1_O0HrO=08+LZM|y;#eNZ?AC;$ig{MK?HVBZm) z1j>FSI$Mo&>om5DdzA%UVHkvZ@T>5JCAY+Kk`z$1{{Rvcq3s&j%p7Y&Bj1zg`u)v} zHYL)P`E&F>F?>pND>Zc2sA%c-eZv)j 8v58?pwYr|Ed z;?yUjPviFUJuNzx@hy!j>fQy2;H+8Z)@|G_VTfC|R;fXYyKU0uq23ZozNsGdRxMf% zT?=TneGO{Nm`mAa#`@aC7w}|jHYZ%E7ODY3GI$9h2R@PnY-3)F@il)!%IeEOewkxw zUA8J^PF(`4M_42!r_iLd>uwSJDgk5>xs gO00XS;qPpho_9< zclmkDE$C$y530e0rAk081rnM0C0y+yYRWg2^8!k-Mn9huY|>vBOr+Z(@%Wr;_h~L9 z@C=2(jf` PR4yI`q65%))xKk5Mc# z)s5|ywX_Sn2iyCynpBh{Qwk|cl6@y*1b6aBb6Od0tjiSI)X~PX)?)C5<143F!NoC) zj29fbLw|B{ANWM!idu`UYy{|9?i({J)DWm4a6Ildys))ZRjc}QN1?+(VkzW&{(O&G zzS*pkgmtUzqVZRTxJmn_2HrDf;=n#a+jXZBLbxJ8P*5;W=U(!)NOx+lD74qZ=y?c1 zsW{7;clIADJqznD2cPiEPN-wnZ`<7FECUPAn3|9_7`20c_G33RkT@>c+~N3%{{WuY zD|njHr%6UGoSowyy*7S#ah7jlI#a0R)Y8@K?b)8Tcwfvb!#s6(FzQ9}+g;WnelXkT zm9mp?ZQjE!l76nV()ZZw9^$lPCmcl@lif)t>wJvdsRb%kA>{t&*=iDC9tSaBL_Bn* zbzrG%b|e|0iAAMydMEu23 h%(atH@Z4`UPu52%#EAkYy4My)&06juAEarB`m z#^98lL~1EeKgxtil}Ip2_n|d()y38zDqwvD3q_QjFbN+MQEe?)1h7 `cA-56fLY1x~L6vv}=w4`d5>JHzv-{Xx5;T4Qx{@FN~r9+=J~_ z6}jqM*&C%P3IaRTuv!(DW`F=~#akV~`X_0CD&QR^LF{M(`bVco`Jg17_7k_wN*jVo zi2?v01GP!75FkV#$oZ=PGGIy5AFW}#01GB!C-Uu3l(f(i2}*<$y&!=pPOVc`0)c7Z ze3_s;^7}x16k#4Kx_x t+{f6NBF+K`FgL6|FY!0w9pDQ))kjM1!)cm&C9g z^lu;Lzdij8{1z!i 1LYq& K1Fl+lOc5YJAmXR7;TYG>LJeUN0Ks!xqJU+HIU41oXp5Ndq z$X6FOM%7Is&?L6KML+mLPJpF%&`OX!k_T$#)}+(alF=RYw%N> ak|{57=)gsuERCAf!`Z^Z_IlGdg9&iwV4bdAR+xqG7~BC z)(U-` Pyq%9-xIkyA=clh~}u_?T^WpRe5LBKL)o*iKR9deda zi8T$}dVnekAt_d`bLrpYMAYcXqB3`O D4|O)c;8 zTe!9k<*G_<*}DuWHs9|dvQkjBCKeQjN|LR#7D$?$D@!W6)ARG}W^~=pqhAEQZpS*K zkr#K2*kUWTX@+qeDfKWLa^lHp4z`z&6rkGDuf4KUB&3j%OoDaj%JQ;WetvyPPM?PF zbF=-Soi)JoS3)q3r7)J-#Pa*CyXS`FTQ=&^FD*&znL^5@eFtM)-aUtm>35wzyv~;e z#7Z?BIWuk7o$zlH{{UrQTCiMY!HFXGr8wIcC_a}Hac^L?5~6n2m9&=vyUI^_J#H0M zVmN+Ru2u5?0AruUY4=!{CA0dU4BiZS*@R#g`D({HS}x}<*=Czudl5%5g5y?)2FES* z_7dY)AM&ZNNSfZN;|bmDwDns*dVd2_jYi{dJD)&a8}o8*Zu(!CGYzfH=5NY5!ws;y zb+wS9^H=Dxxp`mum1KvHxp 8 zABy+w^E`f3w+<3E8i*7jCveGaP+=)FFmg8s)HahqQ7DnTiUK5VM&!^HBS?r%022V8 zOn0ClsRTyfPV_Ssn28g~8_>NZwg9jri1sxdKn40#N2nfZGkky-0FC$U%~lAM%=>)M z10X?MfH*V-G?1wzPk5jPu20s0z&5CWAb}O-W3jhA&c$h^MI|!>xvSu`AYKrel7Kzp zDrF6IE=)iikIt@+#s?6sreY094YsixX_>2|D}l5xl!@nhkO?q$`TBh*20IRBDp1@U zR+;VnKU%fEV4;w9B%bw&HOvswbxf=CsQ_z0PSdgZsB*gmK!SJQn#?u@6%uzF_X4B< zl|+rdr7g?@CvMdhuBKF5Jj?OR;3o$06JdzR$fDZKFhUq7=t7+hVFr#-s#K45yu(Jb@Rr*hTLP%?fam$0k#yJc%|^Ggl4 zc7RglvdJEm5D5V9A~&uUMy#f-bA86%!%p+wMRxlQxK*XQn3t9|1u~_i!d4aDK^utr z*0ku~%* Kbxre6r`k8IVa5TQ8+o-G3&?ZoijRY3wZM4*5Pb#x2lx?w+e`(=3 z&AOJ`Bq>@;mh%K^+7d{D3@SL_imG%j%OhK<*Yesi3?;jqvM%l(x3*e?H$=iN?Npsj z>j1za3uoC#Onx9LRO7rwmiI4KxRzkTSpA#kq#!9uZ(@}KsZoUpB0`D?;Ll^dZqtjk zid@^+>^(NRb1?qiyu_^8Y+Jg}au9WSx{{QldxVDESd$@9@mAA{dyyM+1jF0SS-@Gl zZr#Jrpdlzg)#jL7d)B6%N5oh5e6$=vFJr)_hVY`(G!V(P>0tp^t+FDJ_jP(JXJ zGwmmkL6dirw&;zzn=g (f$H+I;q9l8c(T?k-ni z*QvcH$MUV^x8B>hwic^OhRJaap-MV92T|B|)l;iOJr_-o!_>)9Owz81=O6o(@Mq%V zCgPW_+kVf *0F;RUjlPsDj1yO4?zXZM1c*DwdI-YWqAK1A3i%_w zLCtJf57HtaNcX8Ha0$e~5IL%+xCBQ#!0$B>4@i un^K3!`tw%9U^d#*18>Mwz VZ@pIKt;r~(4t1NP83V4pKg^vn>OKQ+jb)rkxOF;0U18DqA8CB0)R-Yd zdZx7))QgPvW%O%G4>V7l&b$4SeNpM{wq(b$9%VV^=F#O{Slf$zE@L)2B~S+!ZEvYR z#*!47+*cB=4y+q%U#jQrT-Qxe)2CXTwA%jw56(w|op(k~%kMX5n67Y~D;T}=8(tXs z4ZCoprWB+%{{SgMiQ{m4il#DzmZDLT)tZR?z9)v_&9d7;{5?fMms=Y;kVzBlNF>K) zOm?blld(&Vg~HroNw{Ybuv(JReQqH;1p~1l5wd|3?Yf7xR_Wz;MAN!1p?4RI3rAL! z+Yq^InT=hCawZ`s{UdHOR@AKRnMV CsfE7P5IIPl2Ey)23tTn*AdgkKZ;@0*2 zMPZc!VM{_rg#va7S71bHC$ZY8O(` GZV86; zQ=(mNWo|0k*B#5at%&k8D0%NblqX{f^@jkN;49!)0*4QDD!9k{uk$+ij9hC_cjaT_ z4>@7jgE`*c6jh?wv2h05&5f7qkO`h;B0n#B^)%wLSo4Zjc4wnsX9rYQZQ`fHo?pgY zwG3TnTq6#Azp^}+@m5r%k6?AIK<=vMV=oBiTU~$tk 5d0cn}iJ}U{_kQJkS_CECqYoH(yKs-eh*B}LH2iy+zSO=$L0zPO6l+5g6C 77m(8E-h@lE<% zu2rD7W){bMbof8Y+R=@8iRpU_Ov+ls1Efd(iLSK{0gamQQj_*GT6{``U7V4I@qe|S zzy=9EcZeJk`VSVCk2^m|O?0VtGl|b?FW_p=j$xy`jCXzZ*!`c@Yg!T1oXL6<5~i?c z0R2f7yARX;DKGuC{{Y#2&3X2h3Z1TWJMXu*z!i(BWjOazZvo*<;KC2)Rz8(u{XOD$ z{wv;y{{ZG}H&RLadVB zd0T(tGUea^{FJ1M*L{TIk