{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 🧬 Fine-Tuning a Post-trained Model on Functional BigWig Tracks Prediction (reproduce paper results)\n", "\n", "This notebook is designed to enable the reproduction of the fine-tuning results on functional genomics tracks in the paper. In contrast to the simplified fine tuning setup in [02_fine_tuning_pretrained_model_biwig.ipynb](https://huggingface.co/spaces/InstaDeepAI/ntv3/blob/main/notebooks_tutorials/02_fine_tuning_pretrained_model_biwig.ipynb), this more complex setup is designed to mirror the internal JAX pipeline used to run the evaluations in PyTorch and using our HuggingFace models.\n", "As in the benchmark, the notebook finetunes the post-trained Nucleotide Transformer v3 (`NTv3_650M_post`) model to predict BigWig signal tracks directly from DNA sequences. The streamlined approach leverages a post-trained NTv3 backbone as a feature extractor. A new prediction head is added to the model, which outputs single-nucleotide resolution signal values for each of the functional bigwig tracks in the NTv3 benchmark for the selected species. The notebook uses the 34 tracks for the `human` species by default, but the user can change the config to use any species from the benchmark.\n", "\n", "**🦚 Features:**\n", "In addition to the simplifed version, the following features are added:\n", "- Learning rate scheduling\n", "- Use fixed dataset regions for training\n", "- Implement gradient accumulation for large batch sizes\n", "- Use the best model (selected via validation Pearson) for evaluation \n", "- Save the latest and best models for future use\n", "\n", "**🔦 JAX vs PyTorch:**\n", "The values achieved by this pipeline are close (within 0.01 mean Pearson for human) to those reported in the paper. They differ slightly due to using here a PyTorch pipeline to make it easier for users, as opposed to the JAX pipeline used for the results in the paper. For most accurate performance, it is recommended to use 3x seeds and average the results, as shown in the paper.\n", "\n", "**🚆 Training:**\n", "To run this training, you will need a large GPU (either A100 or H100). It takes around 28 hours on an H100 with the default settings. It might be possible to improve the tuning of the number of workers to improve efficiency. Our JAX pipeline is able to complete the training in around 12 hours.\n", "\n", "📝 Note for Google Colab users: This notebook is compatible with Colab! This notebook is designed to be run on a high-performance GPU. The default parameters can be used with a H100 with 80GB of HBM.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 0. 📦 Imports dependencies" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "7def2b35ebeb45bc97960837f8a7041c", "version_major": 2, "version_minor": 0 }, "text/plain": [ "VBox(children=(HTML(value='
1.20.0 in ./.venv/lib/python3.11/site-packages (from torchmetrics) (2.1.3)\n", "Requirement already satisfied: torch>=2.0.0 in ./.venv/lib/python3.11/site-packages (from torchmetrics) (2.5.1+cu121)\n", "Requirement already satisfied: lightning-utilities>=0.8.0 in ./.venv/lib/python3.11/site-packages (from torchmetrics) (0.15.2)\n", "Requirement already satisfied: filelock in ./.venv/lib/python3.11/site-packages (from transformers) (3.17.0)\n", "Requirement already satisfied: huggingface-hub<1.0,>=0.34.0 in ./.venv/lib/python3.11/site-packages (from transformers) (0.36.0)\n", "Requirement already satisfied: pyyaml>=5.1 in ./.venv/lib/python3.11/site-packages (from transformers) (6.0.2)\n", "Requirement already satisfied: regex!=2019.12.17 in ./.venv/lib/python3.11/site-packages (from transformers) (2024.11.6)\n", "Requirement already satisfied: requests in ./.venv/lib/python3.11/site-packages (from transformers) (2.32.3)\n", "Requirement already satisfied: tokenizers<=0.23.0,>=0.22.0 in ./.venv/lib/python3.11/site-packages (from transformers) (0.22.2)\n", "Requirement already satisfied: safetensors>=0.4.3 in ./.venv/lib/python3.11/site-packages (from transformers) (0.7.0)\n", "Requirement already satisfied: tqdm>=4.27 in ./.venv/lib/python3.11/site-packages (from transformers) (4.67.1)\n", "Requirement already satisfied: fsspec>=2023.5.0 in ./.venv/lib/python3.11/site-packages (from huggingface-hub<1.0,>=0.34.0->transformers) (2025.3.0)\n", "Requirement already satisfied: typing-extensions>=3.7.4.3 in ./.venv/lib/python3.11/site-packages (from huggingface-hub<1.0,>=0.34.0->transformers) (4.12.2)\n", "Requirement already satisfied: hf-xet<2.0.0,>=1.1.3 in ./.venv/lib/python3.11/site-packages (from huggingface-hub<1.0,>=0.34.0->transformers) (1.2.0)\n", "Requirement already satisfied: setuptools in ./.venv/lib/python3.11/site-packages (from lightning-utilities>=0.8.0->torchmetrics) (80.9.0)\n", "Requirement already satisfied: networkx in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (3.6.1)\n", "Requirement already satisfied: jinja2 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (3.1.6)\n", "Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.1.105 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.105)\n", "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.1.105 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.105)\n", "Requirement already satisfied: nvidia-cuda-cupti-cu12==12.1.105 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.105)\n", "Requirement already satisfied: nvidia-cudnn-cu12==9.1.0.70 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (9.1.0.70)\n", "Requirement already satisfied: nvidia-cublas-cu12==12.1.3.1 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.3.1)\n", "Requirement already satisfied: nvidia-cufft-cu12==11.0.2.54 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (11.0.2.54)\n", "Requirement already satisfied: nvidia-curand-cu12==10.3.2.106 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (10.3.2.106)\n", "Requirement already satisfied: nvidia-cusolver-cu12==11.4.5.107 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (11.4.5.107)\n", "Requirement already satisfied: nvidia-cusparse-cu12==12.1.0.106 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.0.106)\n", "Requirement already satisfied: nvidia-nccl-cu12==2.21.5 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (2.21.5)\n", "Requirement already satisfied: nvidia-nvtx-cu12==12.1.105 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (12.1.105)\n", "Requirement already satisfied: triton==3.1.0 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (3.1.0)\n", "Requirement already satisfied: sympy==1.13.1 in ./.venv/lib/python3.11/site-packages (from torch>=2.0.0->torchmetrics) (1.13.1)\n", "Requirement already satisfied: nvidia-nvjitlink-cu12 in ./.venv/lib/python3.11/site-packages (from nvidia-cusolver-cu12==11.4.5.107->torch>=2.0.0->torchmetrics) (12.8.93)\n", "Requirement already satisfied: mpmath<1.4,>=1.1.0 in ./.venv/lib/python3.11/site-packages (from sympy==1.13.1->torch>=2.0.0->torchmetrics) (1.3.0)\n", "Requirement already satisfied: MarkupSafe>=2.0 in ./.venv/lib/python3.11/site-packages (from jinja2->torch>=2.0.0->torchmetrics) (3.0.2)\n", "Requirement already satisfied: charset-normalizer<4,>=2 in ./.venv/lib/python3.11/site-packages (from requests->transformers) (3.4.1)\n", "Requirement already satisfied: idna<4,>=2.5 in ./.venv/lib/python3.11/site-packages (from requests->transformers) (3.10)\n", "Requirement already satisfied: urllib3<3,>=1.21.1 in ./.venv/lib/python3.11/site-packages (from requests->transformers) (2.3.0)\n", "Requirement already satisfied: certifi>=2017.4.17 in ./.venv/lib/python3.11/site-packages (from requests->transformers) (2025.1.31)\n" ] } ], "source": [ "# Install dependencies\n", "!pip install pyfaidx pyBigWig torchmetrics transformers" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import bisect\n", "import functools\n", "from typing import List, Dict, Callable, Any, cast\n", "import os\n", "import fnmatch\n", "from pathlib import Path\n", "from huggingface_hub import HfApi, snapshot_download\n", "\n", "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "from torch.utils.data import Dataset, DataLoader\n", "from torch.optim import AdamW\n", "from torch.optim.lr_scheduler import LambdaLR\n", "from transformers import AutoConfig, AutoModel, AutoTokenizer\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import pyBigWig\n", "from pyfaidx import Fasta\n", "from torchmetrics import PearsonCorrCoef\n", "from tqdm import tqdm" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. ⚙️ Configuration\n", "\n", "## Configuration Parameters\n", "\n", "### Model\n", "- **`model_name`**: HuggingFace model name/identifier for the pretrained backbone model\n", "- **`best_model_checkpoint_path`**: Path to use when saving the best model checkpoint\n", "\n", "### Data\n", "- **`hf_repo_id`**: HuggingFace dataset repository ID containing the benchmark data\n", "- **`species`**: Species name (e.g., \"human\", \"tomato\") to select bigwig data from the benchmark dataset\n", "- **`data_cache_dir`**: Directory where downloaded data files (FASTA, bigWig) will be stored\n", "- **`sequence_length`**: Length of input sequences in base pairs (bp)\n", "- **`keep_target_center_fraction`**: Fraction of center sequence to keep for target prediction (crops edges to focus on center)\n", "- **`train_overlap`**: Fraction of sequence that overlaps between unique training samples\n", "\n", "### Training\n", "- **`mini_batch_size`**: Number of samples per mini batch on the device\n", "- **`num_accumulation_gradient`**: Number of gradient accumulation steps\n", "- **`num_steps_training`**: Total number of training steps (each step has an effective batch size of `mini_batch_size * num_accumulation_gradient`)\n", "- **`initial_learning_rate`**: Initial learning rate for optimizer\n", "- **`num_steps_warmup`**: Number of warmup steps (3% of `num_steps_training`)\n", "- **`end_learning_rate`**: Peak learning rate after warmup\n", "- **`weight_decay`**: L2 regularization coefficient for optimizer\n", "- **`log_every_n_steps`**: Log training metrics every N steps\n", "\n", "### Validation\n", "- **`validate_every_n_steps`**: Run validation every N steps\n", "- **`num_validation_samples`**: Number of samples to use for each validation \n", "\n", "### General\n", "- **`seed`**: Random seed for reproducibility\n", "- **`device`**: Device to run training on (\"cuda\" or \"cpu\")\n", "- **`num_workers`**: Number of worker processes for DataLoader (0 = single-threaded)\n", "\n", "NOTE: the default parameters will finetune the model on the human dataset, to finetune on the tomato dataset, set the 'species_name' to 'tomato' in the config. You can also update the config parameters regarding the number of training and warmup tokens based on the species genome size, as done in our benchmark (see paper details), although this is not neccessery to achieve top performance results." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Using device: cuda\n" ] } ], "source": [ "config = {\n", " # Model\n", " \"model_name\": \"InstaDeepAI/NTv3_650M_post\",\n", " \"best_model_checkpoint_path\": \"best_model_checkpoint.pth\",\n", " \n", " # Data\n", " \"hf_repo_id\": \"InstaDeepAI/NTv3_benchmark_dataset\",\n", " \"species_name\": \"human\", # Select the species to train on, i.e. \"tomato\"\n", " \"data_cache_dir\": \"./data\",\n", " \"sequence_length\": 32_768,\n", " \"keep_target_center_fraction\": 0.375,\n", " \"train_overlap\": 0.999,\n", " \n", " # Training\n", " \"mini_batch_size\": 4,\n", " \"num_accumulation_gradient\": 8, # For an effective batch size of 32\n", " \"num_steps_training\": 19932, # Calculated to provide ~20.9B tokens\n", " \"weight_decay\": 0.01,\n", " \"initial_learning_rate\": 1e-5,\n", " \"num_steps_warmup\": 598, # Calculated as 3% of 19932 steps\n", " \"end_learning_rate\": 5e-5, \n", " \"log_every_n_steps\": 50,\n", " \n", " # Validation\n", " \"validate_every_n_steps\": 500, \n", " \"num_validation_samples\": 1000,\n", "\n", " # General\n", " \"seed\": 0,\n", " \"device\": \"cuda\" if torch.cuda.is_available() else \"cpu\",\n", " \"num_workers\": 16,\n", "}\n", "\n", "# Set random seed\n", "torch.manual_seed(config[\"seed\"])\n", "np.random.seed(config[\"seed\"])\n", "\n", "# Set device\n", "device = torch.device(config[\"device\"])\n", "print(f\"Using device: {device}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. 📥 Genome & Tracks Data Download\n", "\n", "Download the reference genome FASTA file and BigWig signal tracks from public repositories. These files contain the genomic sequences and experimental signal data (e.g., ChIP-seq, ATAC-seq) that we'll use for training." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def prepare_genomics_inputs(\n", " species: str,\n", " data_cache_dir: str | Path = \"data\",\n", " hf_repo_id: str = \"InstaDeepAI/NTv3_benchmark_dataset\",\n", ") -> tuple[str, list[str], list[str], pd.DataFrame, pd.DataFrame]:\n", " \"\"\"\n", " Downloads:\n", " 1) FASTA from HF dataset under: /genome.fasta\n", " 2) BigWigs from HF dataset under: /functional_tracks/**\n", " (filtered by bigwig_file_ids if provided)\n", " 3) Splits from HF dataset under: /splits.bed\n", " 4) Metadata from HF dataset under: benchmark_metadata.tsv\n", " \n", " Args:\n", " species: Species name (e.g., \"human\", \"arabidopsis\")\n", " data_cache_dir: Directory where downloaded data files will be stored\n", " hf_repo_id: HuggingFace dataset repository ID\n", " \n", " Returns:\n", " (fasta_path, bigwig_path_list, bigwig_file_ids)\n", " \"\"\"\n", " cache = Path(data_cache_dir).expanduser().resolve()\n", " cache.mkdir(parents=True, exist_ok=True)\n", " \n", " # --- Download metadata + files (FASTA, BigWigs, Splits) ---\n", " metadata_file = \"benchmark_metadata.tsv\"\n", " download_patterns = [metadata_file, f\"{species}/genome.fasta\", f\"{species}/splits.bed\"]\n", " \n", " # Download all BigWig files\n", " download_patterns.append(f\"{species}/functional_tracks/*.bigwig\")\n", " local_dir = Path(\n", " snapshot_download(\n", " repo_id=hf_repo_id,\n", " repo_type=\"dataset\",\n", " allow_patterns=download_patterns,\n", " local_dir=str(cache),\n", " )\n", " )\n", " \n", " # --- Organize outputs ---\n", " # FASTA file\n", " fasta_path_repo = f\"{species}/genome.fasta\"\n", " fasta_path = str(local_dir / fasta_path_repo)\n", " \n", " # BigWig files - use downloaded files directly\n", " bigwig_dir = local_dir / species / \"functional_tracks\"\n", " \n", " # Find all downloaded BigWig files\n", " bigwig_paths = [str(bigwig_file) for bigwig_file in bigwig_dir.glob(\"*.bigwig\")]\n", " bigwig_ids = [bigwig_file.stem for bigwig_file in bigwig_dir.glob(\"*.bigwig\")] \n", "\n", " # Data splits file\n", " splits_path_repo = f\"{species}/splits.bed\"\n", " splits_path = local_dir / splits_path_repo\n", "\n", " splits_df = pd.read_csv(\n", " splits_path, \n", " sep=\"\\t\", \n", " header=None, \n", " names=[\"chr_name\", \"start\", \"end\", \"split\"],\n", " dtype={\"chr_name\": str, \"start\": int, \"end\": int, \"split\": str},\n", " )\n", " \n", " # Metadata file\n", " metadata_path = local_dir / metadata_file\n", " metadata_df = pd.read_csv(metadata_path, sep=\"\\t\")\n", "\n", " # Filter and order metadata \n", " metadata_df = metadata_df[metadata_df[\"species_common_name\"] == species].reset_index(drop=True)\n", " metadata_df = metadata_df.set_index(\"file_id\").loc[bigwig_ids].reset_index()\n", "\n", " return fasta_path, bigwig_paths, bigwig_ids, splits_df, metadata_df" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "93c67d6f058848d5b6e162815ccb4103", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Fetching 37 files: 0%| | 0/37 [00:00 np.ndarray:\n", " \"\"\"Crop the central sequence-length fraction for arrays of size (..., seq_len, num_tracks)\"\"\"\n", " seq_len = x.shape[-2]\n", " target_offset = int(seq_len * (1 - keep_target_center_fraction) // 2)\n", " target_length = seq_len - 2 * target_offset\n", " return x[..., target_offset:target_offset + target_length, :]\n", "\n", "\n", "class LinearHead(nn.Module):\n", " \"\"\"A linear head that predicts one scalar value per track.\"\"\"\n", " def __init__(self, embed_dim: int, num_labels: int):\n", " super().__init__()\n", " self.layer_norm = nn.LayerNorm(embed_dim)\n", " self.head = nn.Linear(embed_dim, num_labels)\n", " \n", " def forward(self, x: torch.Tensor) -> torch.Tensor:\n", " x = self.layer_norm(x)\n", " x = self.head(x)\n", " x = F.softplus(x) # Ensure positive values\n", " return x\n", "\n", "\n", "class HFModelWithHead(nn.Module):\n", " \"\"\"Simple model wrapper: HF backbone + bigwig head.\"\"\"\n", " \n", " def __init__(\n", " self,\n", " model_name: str,\n", " bigwig_track_names: List[str],\n", " species_str: str,\n", " keep_target_center_fraction: float = 0.375,\n", " ):\n", " super().__init__()\n", " \n", " # Load base model config and model\n", " self.config = AutoConfig.from_pretrained(model_name, trust_remote_code=True)\n", " ntv3_base_model = AutoModel.from_pretrained(\n", " model_name, \n", " trust_remote_code=True,\n", " config=self.config,\n", " )\n", "\n", " # Extract the discrete conditioned model (i.e. remove the heads) for finetuning\n", " discrete_conditioned_model = type(ntv3_base_model.core).__bases__[0]\n", " self.core = discrete_conditioned_model(self.config) # follows name covention\n", " # Load pre-trained weights (strict=False because we don't load the heads)\n", " self.load_state_dict(ntv3_base_model.state_dict(), strict=False) \n", "\n", " self.supported_species = self.config.bigwigs_per_species.keys()\n", " if species_str in self.config.species_to_token_id:\n", " species_ids = self.config.species_to_token_id[species_str]\n", " self.species_ids = torch.LongTensor([species_ids])\n", " print(f\"Using species: {species_str} with ids: {self.species_ids}\")\n", " else:\n", " # Mask token id\n", " print(f\"{species_str} not in supported species, using mask token id\")\n", " self.species_ids = torch.LongTensor([2])\n", "\n", " self.keep_target_center_fraction = keep_target_center_fraction\n", "\n", " # Bigwig head (NTv3 outputs at single-nucleotide resolution)\n", " self.bigwig_head = LinearHead(self.config.embed_dim, len(bigwig_track_names))\n", " self.model_name = model_name\n", " \n", " def forward(self, tokens: torch.Tensor, **kwargs) -> Dict[str, torch.Tensor]:\n", " # Prepare the species tokens\n", " species_tokens = torch.repeat_interleave(self.species_ids, tokens.shape[0])\n", " species_tokens = species_tokens.to(tokens.device)\n", "\n", " # Forward through core\n", " outputs = self.core(tokens, [species_tokens], output_hidden_states=True)\n", " embedding = outputs[\"hidden_states\"][-1]\n", " \n", " # Crop to center fraction\n", " if self.keep_target_center_fraction < 1.0:\n", " embedding = crop_center(embedding, self.keep_target_center_fraction)\n", " \n", " # Predict bigwig tracks\n", " bigwig_logits = self.bigwig_head(embedding)\n", " \n", " return {\"bigwig_tracks_logits\": bigwig_logits}" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "67c12374c3aa46d5aa8db543d97febec", "version_major": 2, "version_minor": 0 }, "text/plain": [ "tokenizer_config.json: 0%| | 0.00/1.48k [00:00 list[tuple[str, int, int]]:\n", " \"\"\"\n", " Sample fixed regions for a total length.\n", " \"\"\"\n", " # For each region, sample a window until we have total_length_needed\n", " sampled_regions = []\n", " rng = np.random.RandomState(seed)\n", " accumulated_length = 0\n", "\n", " for _, (chr_name, start, end) in enumerate(regions):\n", " region_length = end - start\n", " remaining_length_needed = total_length_needed - accumulated_length\n", "\n", " if region_length >= remaining_length_needed:\n", " # Sample a random start position for the window\n", " max_start = region_length - remaining_length_needed\n", " if max_start > 0:\n", " window_start_offset = rng.randint(0, max_start + 1)\n", " else:\n", " window_start_offset = 0\n", "\n", " window_start = start + window_start_offset\n", " window_end = start + window_start_offset + remaining_length_needed\n", "\n", " sampled_regions.append((chr_name, window_start, window_end))\n", " accumulated_length += remaining_length_needed\n", " print(\n", " f\"Sampled window from {chr_name}:{start}-{end} -> \"\n", " f\"{chr_name}:{window_start}-{window_end} \"\n", " )\n", " break # Stop after getting enough length\n", " else:\n", " # Add this smaller region and continue accumulating\n", " sampled_regions.append((chr_name, start, end))\n", " accumulated_length += region_length\n", " print(f\"Added region {chr_name}:{start}-{end}, {accumulated_length=}\")\n", "\n", " # Check if we have enough accumulated length\n", " if accumulated_length >= total_length_needed:\n", " print(f\"Sufficient length ({accumulated_length} >= {total_length_needed})\")\n", " break\n", "\n", " print(f\"Sampled {len(sampled_regions)=} with total {accumulated_length=}\")\n", "\n", " return sampled_regions\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# Process-local cache for file handles (one per worker process)\n", "# This allows safe multi-worker DataLoader usage\n", "_fasta_cache = {} # Maps (process_id, file_path) -> Fasta handle\n", "_bigwig_cache = {} # Maps (process_id, file_path) -> pyBigWig handle\n", "\n", "\n", "def _get_fasta_handle(fasta_path: str) -> Fasta:\n", " \"\"\"Get or create a FASTA file handle for the current process.\"\"\"\n", " process_id = os.getpid()\n", " abs_path = str(Path(fasta_path).resolve())\n", " cache_key = (process_id, abs_path)\n", " \n", " if cache_key not in _fasta_cache:\n", " _fasta_cache[cache_key] = Fasta(abs_path, as_raw=True, sequence_always_upper=True)\n", " \n", " return _fasta_cache[cache_key]\n", "\n", "\n", "def _get_bigwig_handle(bigwig_path: str) -> pyBigWig.pyBigWig:\n", " \"\"\"Get or create a BigWig file handle for the current process.\"\"\"\n", " process_id = os.getpid()\n", " abs_path = str(Path(bigwig_path).resolve())\n", " cache_key = (process_id, abs_path)\n", " \n", " if cache_key not in _bigwig_cache:\n", " # Check if file exists before trying to open\n", " if not Path(abs_path).exists():\n", " raise FileNotFoundError(\n", " f\"BigWig file not found: {abs_path}\\n\"\n", " f\"Original path: {bigwig_path}\\n\"\n", " f\"Current working directory: {os.getcwd()}\"\n", " )\n", " \n", " try:\n", " _bigwig_cache[cache_key] = pyBigWig.open(abs_path)\n", " except Exception as e:\n", " raise RuntimeError(\n", " f\"Failed to open BigWig file: {abs_path} with error: {str(e)}\\n\"\n", " f\"File exists: {Path(abs_path).exists()}\\n\"\n", " f\"File size: {Path(abs_path).stat().st_size if Path(abs_path).exists() else 'N/A'} bytes\"\n", " ) from e\n", " \n", " return _bigwig_cache[cache_key]\n", "\n", "\n", "class GenomeBigWigDataset(Dataset):\n", " \"\"\"\n", " A PyTorch dataset to access a reference genome and bigwig tracks. The dataset is \n", " compatible with multi-worker DataLoaders (using process-local file handles and lazy \n", " loading). For each sample, a random genomic region is picked from the specified split,\n", " and a random window of length `sequence_length` within that region is returned.\n", " \"\"\"\n", "\n", " def __init__(\n", " self,\n", " fasta_path: str,\n", " bigwig_path_list: list[str],\n", " chrom_regions: pd.DataFrame,\n", " split: str,\n", " sequence_length: int,\n", " tokenizer: AutoTokenizer,\n", " transform_fn: Callable[[torch.Tensor], torch.Tensor],\n", " overlap: float = 0.0,\n", " keep_target_center_fraction: float = 1.0,\n", " limit_num_samples: int | None = None,\n", " ):\n", " super().__init__()\n", "\n", " # Store paths instead of opening files immediately (for multi-worker compatibility)\n", " self.fasta_path = fasta_path\n", " self.bigwig_path_list = bigwig_path_list\n", " self.sequence_length = sequence_length\n", " self.tokenizer = tokenizer\n", " self.transform_fn = transform_fn\n", " self.keep_target_center_fraction = keep_target_center_fraction\n", " self.chrom_regions = chrom_regions\n", " self.stride = int((1 - overlap) * sequence_length)\n", "\n", " # Filter regions by split\n", " split_regions = self.chrom_regions[self.chrom_regions[\"split\"] == split].copy()\n", " region_list = [\n", " (row.chr_name, row.start, row.end) for _, row in split_regions.iterrows()\n", " ]\n", " if limit_num_samples is not None:\n", " length_required = limit_num_samples * self.sequence_length\n", " region_list = _sample_regions_for_a_total_length(region_list, length_required)\n", " \n", " # Build an index structure for efficient sequence access across genomic regions\n", " self.chromosome_info, self._cumulative_starts, self.num_samples = (\n", " self._process_regions(region_list)\n", " )\n", "\n", " def __len__(self):\n", " return self.num_samples\n", "\n", " def __getitem__(self, idx):\n", " # Select the chromosome for the given index using binary search\n", " chromosome_idx = bisect.bisect_right(self._cumulative_starts, idx) - 1\n", "\n", " # Explicitly cast types from dictionary of chromosome information\n", " chrom: str = cast(str, self.chromosome_info[chromosome_idx][\"chr_name\"])\n", " region_start: int = cast(int, self.chromosome_info[chromosome_idx][\"region_start_offset\"])\n", "\n", " # Calculate the index of the sample *within* the selected chromosome region\n", " index_within_region = idx - self._cumulative_starts[chromosome_idx]\n", "\n", " # Calculate 0-based start and end for the specific sample in genome coordinates\n", " start = region_start + index_within_region * self.stride\n", " end = start + self.sequence_length\n", "\n", " # Sequence - get FASTA handle lazily (cached per worker process)\n", " fasta = _get_fasta_handle(self.fasta_path)\n", " seq = fasta[chrom][start:end] # string slice\n", " # Tokenize with padding and truncation to ensure consistent lengths for batching\n", " tokenized = self.tokenizer(\n", " seq,\n", " padding=\"max_length\",\n", " truncation=True,\n", " max_length=self.sequence_length,\n", " return_tensors=\"pt\",\n", " )\n", " tokens = tokenized[\"input_ids\"][0] # Shape: (max_length,)\n", "\n", " # Signal from bigWig tracks (numpy array) -> torch tensor\n", " # Get BigWig handles lazily (cached per worker process)\n", " bigwig_targets = np.array([\n", " _get_bigwig_handle(bw_path).values(chrom, start, end, numpy=True)\n", " for bw_path in self.bigwig_path_list\n", " ]) # shape (num_tracks, seq_len)\n", " # Transpose to (seq_len, num_tracks)\n", " bigwig_targets = bigwig_targets.T\n", " # pyBigWig returns NaN where no data; turn NaN into 0\n", " bigwig_targets = torch.tensor(bigwig_targets, dtype=torch.float32)\n", " bigwig_targets = torch.nan_to_num(bigwig_targets, nan=0.0)\n", " \n", " # Crop targets to center fraction\n", " if self.keep_target_center_fraction < 1.0:\n", " bigwig_targets = crop_center(bigwig_targets, self.keep_target_center_fraction)\n", "\n", " # Apply scaling to targets\n", " bigwig_targets = self.transform_fn(bigwig_targets)\n", "\n", " sample = {\n", " \"tokens\": tokens,\n", " \"bigwig_targets\": bigwig_targets,\n", " \"chrom\": chrom,\n", " \"start\": start,\n", " \"end\": end,\n", " }\n", " return sample\n", "\n", " def _process_regions(\n", " self, actual_regions_list: list[tuple[str, int, int]]\n", " ) -> tuple[list[dict[str, Any]], list[int], int]:\n", " \"\"\"\n", " Build an index structure for efficient sequence access across genomic regions.\n", "\n", " This method analyzes each genomic region to determine how many sequences of\n", " fixed length can be extracted from it, accounting for stride and overlap\n", " settings. It creates an index that maps global sequence indices to their\n", " genomic locations.\n", "\n", " Args:\n", " actual_regions_list: List of genomic regions as (chromosome, start, end).\n", "\n", " Returns:\n", " region_info: List of dictionaries containing chromosome, start position,\n", " and number of sequences for each valid region.\n", " cumulative_starts: List of cumulative sequence counts for binary search.\n", " total_sequences: Total number of sequences across all regions.\n", " \"\"\"\n", " region_info = []\n", " cumulative_starts = [] # For bisect\n", " total_sequences = 0\n", "\n", " for chr_name, region_s, region_e in actual_regions_list:\n", " region_length: int = region_e - region_s\n", "\n", " num_sequences: int = 0\n", " if region_length >= self.sequence_length:\n", " num_sequences = (\n", " region_length - self.sequence_length\n", " ) // self.stride + 1\n", "\n", " if num_sequences > 0:\n", " region_info.append(\n", " {\n", " \"chr_name\": chr_name,\n", " \"region_start_offset\": region_s,\n", " \"num_samples\": num_sequences,\n", " \"region_length\": region_length,\n", " }\n", " )\n", " cumulative_starts.append(total_sequences)\n", " total_sequences += num_sequences\n", "\n", " return region_info, cumulative_starts, int(total_sequences)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Data preprocessing utilities" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "def create_targets_scaling_fn(\n", " metadata_df: pd.DataFrame\n", ") -> Callable[[torch.Tensor], torch.Tensor]:\n", " \"\"\"\n", " Build a scaling function that uses the track means to normalise and softclip the targets.\n", " \"\"\"\n", " # Open bigwig files and compute track statistics\n", " track_means = metadata_df[\"mean\"].to_numpy()\n", " print(f\"Track means: {track_means}\")\n", " print(f\"Number of tracks: {track_means.shape}\")\n", "\n", " # Create tensor from computed means\n", " track_means_tensor = torch.tensor(track_means, dtype=torch.float32)\n", "\n", " def transform_fn(x: torch.Tensor) -> torch.Tensor:\n", " # Move constants to correct device then normalize\n", " means = track_means_tensor.to(x.device)\n", " scaled = x / means\n", "\n", " # Smooth clipping: if > 10, apply formula\n", " clipped = torch.where(\n", " scaled > 10.0,\n", " 2.0 * torch.sqrt(scaled * 10.0) - 10.0,\n", " scaled,\n", " )\n", " return clipped\n", "\n", " return transform_fn" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Track means: [0.00219467 0.00128605 0.65863696 0.01080696 0.00494403 0.00370035\n", " 0.72501702 0.00227474 0.48636405 0.00211876 0.00530738 0.00877379\n", " 0.00627039 0.00400846 0.44757743 0.66685837 0.00335876 0.00820212\n", " 0.0034627 0.72625355 0.00622468 0.00548278 0.00574464 0.63734638\n", " 0.01177604 0.74402866 0.64354244 0.00343102 0.01549048 0.0463601\n", " 0.0057952 0.00376132 0.00498001 0.01612531]\n", "Number of tracks: (34,)\n", "Added region chr2:52738399-68719540, accumulated_length=15981141\n", "Added region chr2:94594361-95921948, accumulated_length=17308728\n", "Added region chr2:95922032-97200446, accumulated_length=18587142\n", "Added region chr2:97538791-106291501, accumulated_length=27339852\n", "Added region chr2:110035770-110281551, accumulated_length=27585633\n", "Added region chr2:110576673-111363357, accumulated_length=28372317\n", "Added region chr2:111510960-112936893, accumulated_length=29798250\n", "Sampled window from chr2:114061575-121781652 -> chr2:118561590-121531340 \n", "Sampled len(sampled_regions)=8 with total accumulated_length=32768000\n", "\n", "Train samples: 65051340\n", "Val samples: 997\n", "Test samples: 10531\n" ] } ], "source": [ "# Pre-build the FASTA index in the main process to avoid race conditions\n", "# when multiple DataLoader workers try to create it simultaneously\n", "print(f\"Pre-building FASTA index for {fasta_path}...\")\n", "fai_path = Path(fasta_path + \".fai\")\n", "if fai_path.exists():\n", " # Remove potentially corrupted index from a previous failed run\n", " print(f\"Removing existing FASTA index: {fai_path}\")\n", " fai_path.unlink()\n", "_prebuild_fasta = Fasta(fasta_path, as_raw=True, sequence_always_upper=True)\n", "del _prebuild_fasta # Close the handle; workers will reopen with existing index\n", "print(\"FASTA index built successfully.\")\n", "\n", "# Create datasets & dataloaders\n", "create_dataset_fn = functools.partial(\n", " GenomeBigWigDataset,\n", " fasta_path=fasta_path,\n", " bigwig_path_list=bigwig_paths,\n", " chrom_regions=species_splits_df,\n", " sequence_length=config[\"sequence_length\"],\n", " tokenizer=tokenizer,\n", " transform_fn=create_targets_scaling_fn(metadata_df),\n", " keep_target_center_fraction=config[\"keep_target_center_fraction\"],\n", ")\n", "\n", "train_dataset = create_dataset_fn(\n", " split=\"train\",\n", " overlap=config[\"train_overlap\"],\n", ")\n", "\n", "val_dataset = create_dataset_fn(\n", " split=\"val\", limit_num_samples=config[\"num_validation_samples\"]\n", ")\n", "test_dataset = create_dataset_fn(split=\"test\") # Use all test samples\n", "\n", "\n", "# Create dataloaders\n", "train_loader = DataLoader(\n", " train_dataset,\n", " batch_size=config[\"mini_batch_size\"],\n", " shuffle=True,\n", " num_workers=config[\"num_workers\"],\n", ")\n", "\n", "val_loader = DataLoader(\n", " val_dataset,\n", " batch_size=config[\"mini_batch_size\"],\n", " shuffle=False,\n", " num_workers=config[\"num_workers\"],\n", ")\n", "\n", "test_loader = DataLoader(\n", " test_dataset,\n", " batch_size=config[\"mini_batch_size\"],\n", " shuffle=False,\n", " num_workers=config[\"num_workers\"],\n", ")\n", "\n", "print(f\"\\nTrain samples: {len(train_dataset)}\")\n", "print(f\"Val samples: {len(val_dataset)}\")\n", "print(f\"Test samples: {len(test_dataset)}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 5. ⚙️ Optimizer setup\n", "\n", "Configure the AdamW optimizer with learning rate and weight decay hyperparameters. This optimizer will update the model parameters during training to minimize the loss function.\n", "A variable learning rate is used with linear warmup, followed by a polynomial decay." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Training configuration:\n", " Mini batch size: 4\n", " Gradient accumulation steps: 8\n", " Effective batch size: 32\n", " Total training steps: 19932\n", " Log metrics every: 50 steps\n", " Validate every: 500 steps\n", "\n", "Optimiser & learning rate scheduler:\n", " Optimizer base LR (peak): 5e-05\n", " Initial LR: 1e-05\n", " Peak LR: 5e-05\n", " Warmup steps: 598\n", " Alpha polynomial decay: 0.1977\n", " Final LR multiplier: 0.5\n" ] } ], "source": [ "print(f\"Training configuration:\")\n", "print(f\" Mini batch size: {config['mini_batch_size']}\")\n", "print(f\" Gradient accumulation steps: {config['num_accumulation_gradient']}\")\n", "print(f\" Effective batch size: {config['mini_batch_size'] * config['num_accumulation_gradient']}\")\n", "print(f\" Total training steps: {config['num_steps_training']}\")\n", "print(f\" Log metrics every: {config['log_every_n_steps']} steps\")\n", "print(f\" Validate every: {config['validate_every_n_steps']} steps\")\n", "\n", "# Setup optimizer (LR is set to peak LR for scheduler)\n", "optimizer_lr = config[\"end_learning_rate\"]\n", "\n", "# Setup optimizer\n", "optimizer = AdamW(\n", " model.parameters(),\n", " lr=optimizer_lr,\n", " weight_decay=config[\"weight_decay\"],\n", ")\n", "\n", "# Setup learning rate scheduler\n", "final_lr_multiplier = 0.5\n", "num = np.log(1.0 / final_lr_multiplier)\n", "denom = np.log(float(config[\"num_steps_training\"]) / float(config[\"num_steps_warmup\"]))\n", "alpha_polynomial_decay = num / denom\n", "\n", "def _modified_square_decay(current_step: int) -> float:\n", " \"\"\"LR multiplier function matching the pipeline's modified_square_decay.\"\"\"\n", " if current_step < 0:\n", " current_step = 0\n", " if optimizer_lr == 0:\n", " return 0.0\n", " \n", " # Phase 1: Warmup (linear increase from initial LR to peak LR)\n", " if current_step < config[\"num_steps_warmup\"]:\n", " start_multiplier = config[\"initial_learning_rate\"] / optimizer_lr\n", " progress = float(current_step) / float(config[\"num_steps_warmup\"])\n", " return start_multiplier + (1.0 - start_multiplier) * progress\n", " \n", " # Phase 2: Polynomial decay\n", " denominator = float(current_step + 1)\n", " decay_multiplier = (float(config[\"num_steps_warmup\"]) / denominator) ** alpha_polynomial_decay\n", " decay_multiplier = min(decay_multiplier, 1.0)\n", " \n", " return decay_multiplier\n", "\n", "scheduler = LambdaLR(optimizer, lr_lambda=_modified_square_decay)\n", "print(f\"\\nOptimiser & learning rate scheduler:\")\n", "print(f\" Optimizer base LR (peak): {optimizer_lr}\")\n", "print(f\" Initial LR: {config['initial_learning_rate']}\")\n", "print(f\" Peak LR: {config['end_learning_rate']}\")\n", "print(f\" Warmup steps: {config['num_steps_warmup']}\")\n", "print(f\" Alpha polynomial decay: {alpha_polynomial_decay:.4f}\")\n", "print(f\" Final LR multiplier: {final_lr_multiplier}\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 6. 📊 Metrics setup\n", "\n", "Set up evaluation metrics to track model performance during training and validation. We use Pearson correlation coefficients to measure how well the predicted BigWig signals match the ground truth signals." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "class TracksMetrics:\n", " \"\"\"Metrics to handle multi-track pearson correlations and losses\"\"\"\n", " \n", " def __init__(self, track_names: List[str], split: str):\n", " self.track_names = track_names\n", " self.num_tracks = len(track_names)\n", " self.split = split\n", "\n", " # Initialise metrics \n", " self.pearson = PearsonCorrCoef(num_outputs=self.num_tracks).to(device)\n", " self.pearson.set_dtype(torch.float64) # Use float64 for improved numerical stability\n", " self.losses = []\n", "\n", " # Record mean metrics per logging interval\n", " self.step_idxs = []\n", " self.mean_pearsons = []\n", " self.mean_losses = []\n", " \n", " def reset(self):\n", " self.pearson.reset()\n", " self.losses = []\n", " \n", " def update(\n", " self, \n", " predictions: torch.Tensor, \n", " targets: torch.Tensor,\n", " loss: float\n", " ):\n", " \"\"\"\n", " Update the metrics with predictions and targets of shape (..., num_tracks) and a scalar loss.\n", " \"\"\"\n", " # Flatten batch and sequence dimensions\n", " pred_flat = predictions.detach().reshape(-1, self.num_tracks).to(torch.float64) # (N, num_tracks)\n", " target_flat = targets.detach().reshape(-1, self.num_tracks).to(torch.float64) # (N, num_tracks)\n", " \n", " # Update metrics\n", " self.pearson.update(pred_flat, target_flat)\n", " self.losses.append(loss)\n", " \n", " def compute(self) -> Dict[str, float]:\n", " \"\"\"Compute the pearson correlations and loss and return a dictionary of metrics.\"\"\"\n", " # Per-track Pearson correlations\n", " correlations = self.pearson.compute().cpu().numpy()\n", " metrics_dict = {\n", " f\"{track_name}/pearson\": correlations[i] for i, track_name in enumerate(self.track_names)\n", " }\n", " metrics_dict[\"mean/pearson\"] = correlations.mean()\n", " \n", " # Mean loss\n", " metrics_dict[\"loss\"] = np.mean(self.losses)\n", " \n", " return metrics_dict\n", "\n", " def update_mean_metrics(self, step_idx: int):\n", " \"\"\"Update the mean metrics over the logging interval and save to a csv file.\"\"\"\n", " # Update mean metrics with the mean pearson & average loss\n", " metrics_dict = self.compute()\n", " self.step_idxs.append(step_idx)\n", " self.mean_pearsons.append(metrics_dict[\"mean/pearson\"])\n", " self.mean_losses.append(metrics_dict[\"loss\"])\n", "\n", " # Save metrics to a csv for plotting\n", " data = {\n", " \"step\": self.step_idxs,\n", " \"mean_loss\": self.mean_losses,\n", " \"mean_pearson\": self.mean_pearsons,\n", " }\n", " df = pd.DataFrame(data)\n", " df.to_csv(f\"metrics_{self.split}.csv\", index=False)\n", "\n", " return self.mean_pearsons[-1]\n", " \n", " def print_metrics(self, print_per_track: bool = False, current_lr: float | None = None):\n", " \"\"\"Print a summary of the metrics.\"\"\"\n", " lr_str = f\"LR: {current_lr:.2e} | \" if current_lr is not None else \"\"\n", " print(\n", " f\"Step {self.step_idxs[-1]}/{config['num_steps_training']} | \"\n", " f\"{lr_str}\"\n", " f\"Loss: {self.mean_losses[-1]:.4f} | \"\n", " f\"Mean Pearson: {self.mean_pearsons[-1]:.4f}\"\n", " )\n", " metrics_dict = self.compute()\n", " if print_per_track:\n", " for metric_key, metric_value in metrics_dict.items():\n", " print(f\" {metric_key}: {metric_value:.4f}\")\n", " " ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "train_metrics = TracksMetrics(bigwig_ids, \"train\")\n", "val_metrics = TracksMetrics(bigwig_ids, \"val\")\n", "test_metrics = TracksMetrics(bigwig_ids, \"test\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 7. 📉 Loss functions\n", "\n", "Define the Poisson-Multinomial loss function that captures both the scale (total signal) and shape (distribution) of BigWig tracks. This loss is specifically designed for count-based genomic signal data." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "def poisson_loss(ytrue: torch.Tensor, ypred: torch.Tensor, epsilon: float = 1e-7) -> torch.Tensor:\n", " \"\"\"Poisson loss per element: ypred - ytrue * log(ypred).\"\"\"\n", " return ypred - ytrue * torch.log(ypred + epsilon)\n", "\n", "\n", "def safe_for_grad_log_torch(x: torch.Tensor) -> torch.Tensor:\n", " \"\"\"Guarantees that the log is defined for all x > 0 in a differentiable way.\"\"\"\n", " return torch.log(torch.where(x > 0.0, x, torch.ones_like(x)))\n", "\n", "\n", "def poisson_multinomial_loss(\n", " logits: torch.Tensor,\n", " targets: torch.Tensor,\n", " shape_loss_coefficient: float = 5.0,\n", " epsilon: float = 1e-7,\n", ") -> torch.Tensor: \n", " \"\"\"\n", " Regression loss for bigwig tracks (Poisson-Multinomial). The logits and targets are\n", " expected to be of shape (batch, seq_length, num_tracks).\n", " \"\"\"\n", " batch_size, seq_length, num_tracks = logits.shape\n", " \n", " # Scale loss: Poisson loss on total counts per sequence per track\n", " # Sum over sequence dimension (axis=1)\n", " sum_pred = logits.sum(dim=1) # (batch, num_tracks)\n", " sum_true = targets.sum(dim=1) # (batch, num_tracks)\n", " \n", " # Compute poisson loss per (batch, track)\n", " scale_loss = poisson_loss(sum_true, sum_pred, epsilon=epsilon) # (batch, num_tracks)\n", " \n", " # Normalize by sequence length\n", " scale_loss = scale_loss / (seq_length + epsilon)\n", " \n", " # Average over batch and tracks\n", " scale_loss = scale_loss.mean()\n", " \n", " # Shape loss: Multinomial loss\n", " # Add epsilon to all positions\n", " predicted_counts = logits + epsilon\n", " targets_with_epsilon = targets + epsilon\n", " \n", " # Normalize predictions to get probabilities\n", " denom = predicted_counts.sum(dim=1, keepdim=True) + epsilon # (batch, 1, num_tracks)\n", " p_pred = predicted_counts / denom\n", " \n", " # Compute shape loss: -sum(targets * log(p_pred))\n", " pl_pred = safe_for_grad_log_torch(p_pred)\n", " shape_loss = -(targets_with_epsilon * pl_pred)\n", " \n", " # Sum over all dimensions and normalize by total number of positions\n", " shape_denom = batch_size * seq_length * num_tracks + epsilon\n", " shape_loss = shape_loss.sum() / shape_denom\n", " \n", " # Combine losses\n", " loss = shape_loss + scale_loss / shape_loss_coefficient\n", "\n", " return loss\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 8. 🏃 Training loop\n", "\n", "Run the main training loop that iterates through batches, computes gradients, and updates model parameters. The loop includes periodic validation checks and real-time metric visualization to monitor training progress." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "def train_step(\n", " model: nn.Module,\n", " batch: Dict[str, torch.Tensor],\n", " train_metrics: TracksMetrics,\n", " num_accumulation_gradient_steps: int = 1,\n", ") -> None:\n", " \"\"\"\n", " Single training step for one batch (gradient accumulation handled in training loop).\n", " \n", " Args:\n", " model: The model to train\n", " batch: Batch of data\n", " train_metrics: Metrics tracker\n", " num_accumulation_gradient_steps: Number of gradient accumulation steps (for loss scaling)\n", " \"\"\"\n", " tokens = batch[\"tokens\"].to(device)\n", " bigwig_targets = batch[\"bigwig_targets\"].to(device)\n", " \n", " # Forward pass\n", " outputs = model(tokens=tokens)\n", " bigwig_logits = outputs[\"bigwig_tracks_logits\"]\n", " \n", " # Compute loss\n", " loss = poisson_multinomial_loss(\n", " logits=bigwig_logits,\n", " targets=bigwig_targets,\n", " )\n", " scaled_loss = loss / num_accumulation_gradient_steps\n", " \n", " # Backward pass (accumulate gradients)\n", " scaled_loss.backward()\n", " \n", " # Update metrics (use unscaled loss for logging)\n", " train_metrics.update(\n", " predictions=bigwig_logits,\n", " targets=bigwig_targets,\n", " loss=loss.item()\n", " )\n", "\n", "\n", "def validation_step(\n", " model: nn.Module,\n", " batch: Dict[str, torch.Tensor],\n", " metrics: TracksMetrics,\n", ") -> None:\n", " \"\"\"Single validation step.\"\"\"\n", " tokens = batch[\"tokens\"].to(device)\n", " bigwig_targets = batch[\"bigwig_targets\"].to(device)\n", " \n", " with torch.no_grad():\n", " # Forward pass\n", " outputs = model(tokens=tokens)\n", " bigwig_logits = outputs[\"bigwig_tracks_logits\"]\n", " \n", " # Compute loss\n", " loss = poisson_multinomial_loss(\n", " logits=bigwig_logits,\n", " targets=bigwig_targets,\n", " )\n", " \n", " # Update metrics\n", " metrics.update(\n", " predictions=bigwig_logits,\n", " targets=bigwig_targets,\n", " loss=loss.item()\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Run Training Loop" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Starting training for 19932 steps\n", "\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Step 50/19932 | LR: 1.34e-05 | Loss: 4.9725 | Mean Pearson: 0.1257\n", "Step 100/19932 | LR: 1.68e-05 | Loss: 4.7497 | Mean Pearson: 0.3412\n", "Step 150/19932 | LR: 2.01e-05 | Loss: 4.6592 | Mean Pearson: 0.3977\n", "Step 200/19932 | LR: 2.34e-05 | Loss: 4.4238 | Mean Pearson: 0.4344\n", "Step 250/19932 | LR: 2.68e-05 | Loss: 4.7748 | Mean Pearson: 0.4435\n", "Step 300/19932 | LR: 3.01e-05 | Loss: 4.3888 | Mean Pearson: 0.4834\n" ] } ], "source": [ "# Training loop\n", "print(f\"Starting training for {config['num_steps_training']} steps\\n\")\n", "\n", "# Create iterator for training data (will cycle if needed)\n", "train_iter = iter(train_loader)\n", "model.train()\n", "\n", "highest_mean_pearson = 0.0\n", "# Main training loop\n", "for step_idx in range(config[\"num_steps_training\"]):\n", " # Zero gradients once before accumulation\n", " optimizer.zero_grad()\n", " \n", " # Gradient accumulation: process multiple batches before optimizer step\n", " for acc_idx in range(config[\"num_accumulation_gradient\"]):\n", " try:\n", " batch = next(train_iter)\n", " except StopIteration:\n", " # Restart iterator if we run out of data\n", " train_iter = iter(train_loader)\n", " batch = next(train_iter)\n", " \n", " # Process batch (accumulates gradients)\n", " train_step(\n", " model,\n", " batch,\n", " train_metrics,\n", " num_accumulation_gradient_steps=config[\"num_accumulation_gradient\"]\n", " )\n", " \n", " optimizer.step() # Update optimizer once after all accumulation steps\n", " scheduler.step() # Update learning rate scheduler\n", "\n", " # Logging\n", " if (step_idx + 1) % config[\"log_every_n_steps\"] == 0:\n", " train_metrics.update_mean_metrics(step_idx + 1)\n", " train_metrics.print_metrics(current_lr=scheduler.get_last_lr()[0])\n", " train_metrics.reset()\n", " \n", " # Validation\n", " if (step_idx + 1) % config[\"validate_every_n_steps\"] == 0:\n", " print(f\"\\nRunning validation at step {step_idx + 1}...\")\n", " model.eval()\n", " \n", " for val_batch in val_loader:\n", " validation_step(model, val_batch, val_metrics)\n", " \n", " mean_pearson_idx = val_metrics.update_mean_metrics(step_idx + 1)\n", " val_metrics.print_metrics(print_per_track=True)\n", " val_metrics.reset()\n", "\n", " # Back to training mode\n", " print(\"\\n\" + \"-\"*100 + \"\\nTraining metrics:\")\n", " model.train() \n", "\n", " # Save model checkpoint\n", " torch.save(model.state_dict(), f\"model_checkpoint_{step_idx + 1}.pth\")\n", " previous_checkpoint_path = f\"model_checkpoint_{step_idx + 1 - config['validate_every_n_steps']}.pth\"\n", " if os.path.exists(previous_checkpoint_path):\n", " os.remove(previous_checkpoint_path)\n", "\n", " if mean_pearson_idx > highest_mean_pearson:\n", " highest_mean_pearson = mean_pearson_idx\n", " print(f\"New highest mean Pearson: {highest_mean_pearson}\")\n", " torch.save(model.state_dict(), f\"best_model_checkpoint.pth\")\n", "\n", "print(f\"\\nTraining completed after {config['num_steps_training']} steps.\")\n" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "image/png": "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JCQkIDw8HEVFRTbb9u3bB4PBgOTkZMu6du3aYfr06Zg+fTpqamowYsQILFiwwCLaAaB79+6YM2cO5syZg/3796Nfv35Yvnw5/v3vf3vknAiCIAjfZuLEibj//vvx22+/qSY36969O77//nsMGzZMVbRt3boVZ86cgdFoxIgRIyzrhdncPUVCQgKioqJgMpkUhT3PunXr0K1bNxiNRpHlPycnx6FjRkRE4KabbsJNN92EpqYmZGdn4/nnn8czzzzj8N95ZwkPD8eVV16JLVu24NixY3b7TElJwffff4/z58+LrO18KENKSorTY+nevTsAIDEx0e5nIOV///sfGhsb8eWXX4o8DuRc6qXeGkrw51JUVGRj/S8qKnLpXInWBcW0EwQhS0BAAK6++mp88cUXorJspaWlWL16NYYPH25xIztz5oxo38jISFx88cVobGwEwGWObWhoELXp3r07oqKiLG0IgiAIIjIyEm+99RYWLFiA8ePHK7abOnUqTCYTFi1aZLOtpaUF586dA2C1TAotwU1NTXjzzTf1HbgGAgICMGnSJKxfv162JrmwdJrcuH///Xf8+uuvmo8n/dscHByMXr16gWVZNDc3O/R33lVycnLAsixuv/121NTU2GzftWsX/vnPfwIArrvuOphMJrz++uuiNq+88goYhnEqiz/P2LFjER0djRdeeEEUcsCjVr5O7jOpqqrChx9+aNM2IiLCcg+qMWjQICQmJmLVqlWi56FvvvkGhYWFGDdunN0+iLYBWdoJgsAHH3yAb7/91mb9ggULsGnTJgwfPhwzZ85EYGAg3n77bTQ2Norq1vbq1QujRo3CwIED0a5dO/zxxx9Yt24dHn74YQBAcXExrrrqKkydOhW9evVCYGAgPvvsM5SWluLmm2/22HkSBEEQvo+S67iQkSNH4v7778eSJUuQn5+Pq6++GkFBQdi/fz/Wrl2Lf/zjH5g8eTKGDh2KuLg43HnnnXj00UfBMAw+/vhjze7uevPiiy/ihx9+wODBg3HvvfeiV69eqKysRF5eHr7//ntUVlYCAK6//noYjUZMnDgR48aNw+HDh7Fq1Sr06tVLVvTKcfXVV6NDhw4YNmwYkpKSUFhYiNdffx3jxo2zWLAXL16s6e+8qwwdOhRvvPEGZs6ciZ49e+L2229Hjx49cP78eWzduhVffvklFi9eDAAYP348rrjiCjz77LM4cuQIsrKy8N133+GLL77ArFmzLNZyZ4iOjsZbb72F22+/HQMGDMDNN9+MhIQElJSUYMOGDRg2bJjNZAHP1VdfjeDgYIwfPx73338/ampq8O677yIxMRGnTp0StR04cCDeeustLF68GBdffDESExNl4+iDgoKwdOlSTJ8+HSNHjsQtt9xiKfmWmpqKxx9/3OlzJVoZXspaTxCED8CXRFF6HTt2jM3Ly2PHjh3LRkZGsuHh4ewVV1zB/vLLL6J+Fi9ezF566aVsbGwsGxYWxvbs2ZN9/vnn2aamJpZlWbaiooJ96KGH2J49e7IRERFsTEwMO3jwYHbNmjXeOG2CIAjCR7BXepRHWvKN55133mEHDhzIhoWFsVFRUWzfvn3ZuXPnsidPnrS02b59O3vZZZexYWFhbKdOndi5c+eyGzduFJXeYlmu5JtcibQ777yTTUlJsXsuSmOUUlpayj700ENscnIyGxQUxHbo0IG96qqr2HfeecfSxmw2sy+88AKbkpLChoSEsP3792e/+uorm7HwJd/kSqq+/fbb7IgRI9j27duzISEhbPfu3dknn3ySraqqErXT8nde6XOSljCzx65du9hbb72V7dSpExsUFMTGxcWxV111FfvPf/6TNZlMlnbnz59nH3/8cUu7Hj16sMuWLROVm2NZruTbQw89ZHMce/fVDz/8wI4dO5aNiYlhQ0ND2e7du7N33XUX+8cff1jayJV8+/LLL9nMzEw2NDSUTU1NZZcuXcp+8MEHLAD28OHDlnanT59mx40bx0ZFRbEALOXflK7Xp59+yvbv358NCQlh27Vrx06bNo09fvy4qM2dd97JRkRE2JyL3DiJ1gfDsl6aaiQIgiAIgiAIgiAIQhWKaScIgiAIgiAIgiAIH4VEO0EQBEEQBEEQBEH4KCTaCYIgCIIgCIIgCMJHIdFOEARBEARBEARBED4KiXaCIAiCIAiCIAiC8FFItBMEQRAEQRAEQRCEjxLo7QF4GrPZjJMnTyIqKgoMw3h7OARBEAQBlmVx/vx5dOrUCQYDzafrAf29JwiCIHwJV/7WtznRfvLkSSQnJ3t7GARBEARhw7Fjx9ClSxdvD6NVQH/vCYIgCF/Emb/1bU60R0VFAeAuVnR0tEt9mc1mlJeXIyEhwS8tIzR+7+Pv5+Dv4wf8/xxo/N5Hj3Oorq5GcnKy5W8U4Tp6/b3393vU38cP+P850Pi9j7+fg7+PH/D/c/D23/o2J9p5F7no6GhdRHtDQwOio6P99uaj8XsXfz8Hfx8/4P/nQOP3PnqeA7lx64def+/9/R719/ED/n8ONH7v4+/n4O/jB/z/HLz9t97/rhhBEARBEARBEARBtBFItBMEQRAEQRAEQRCEj0KinSAIgiAIgiAIgiB8lDYX004QBOEvsCyLlpYWmEwmxTZmsxnNzc1oaGjw2xgxfx4/oO0cAgICEBgYSDHrBEEQBEE4DIl2giAIH6SpqQmnTp1CXV2dajuWZWE2m3H+/Hm/FIT+Pn5A+zmEh4ejY8eOCA4O9uDoCIIgCILwd0i0EwRB+BhmsxmHDx9GQEAAOnXqhODgYEUxyFvj/dWK6+/jB+yfA8uyaGpqQnl5OQ4fPowePXr4rVcBQRAEQRCeh0Q7QRCEj9HU1ASz2Yzk5GSEh4ertvV30evv4we0nUNYWBiCgoJw9OhRNDU1ITQ01MOjJAiCIAjCX6GpfoIgCB+FrLGtC/o8CYIgCIJwBnqCIAiCIAiCIAiCIAgfhUQ7QRAEQRAEQRAEQfgoJNoJgiAInyU1NRUrV6709jAIgiAIgiC8Bol2FzAagSuvbI/wcAZZWdwyQRBEW4RhGNXXggULnOp3586duO+++1wa26hRozBr1iyX+iAIgiAIwrcxFhqRtSoLYYvDkLUqC8bC1iPOSLQ7idEITJliwL59gWhsZFBQAEyaRMKdIAjfwWgEsrKAsDC4fWLx1KlTltfKlSsRHR0tWvfEE09Y2vLZ1rWQkJBgN4M+QRAEQRBtG2OhEZPWTEJBaQEaTA0oKC3ApDWTWo1wJ9HuJLm5AMOwYFmuvA/LAgwDLFzo5YERBNHqYFmgttax1+rV3ERiQQHQ0ADLxOLq1Y71w7LaxtihQwfLKyYmBgzDWJb37duHqKgofPPNNxg4cCBCQkLw888/4+DBg5gwYQK6dOmCqKgoXHLJJfj+++9F/Urd4xmGwXvvvYeJEyciPDwcPXr0wJdffunS9V2/fj169+6NkJAQpKamYvny5aLtb775Jnr06IHQ0FAkJSVh8uTJlm3r1q1DZmYmoqOjER8fj9GjR6O2ttal8RAEQRAE4Ri523LBgAEL7sGFBQsGDBZu48SZnBXenyzzVKfdSYqLYRHsPCwLFBV5aUAEQbRa6uqAyEilrQyAIMV9edHN/z9tmmPHrqkBIiIc20eJp59+Gi+//DK6deuGuLg4HDt2DNdeey0WLFiAiIgIfPzxxxg/fjyKiorQtWtXxX5yc3Px0ksvYdmyZXjttdcwbdo0HD16FO3atXN4TLt27cLUqVOxYMEC3HTTTfjll18wc+ZMtG/fHnfddRf++OMPPProo/j4448xdOhQVFZW4qeffgLAeRfccsstWLp0KcaPH4/6+nr8/PPPYLXOdBAEQRAEoQvFFcUWwc7DgkXRmSKLFZ4X9bwVHoDNuvVT1yM7I9sbp6AKiXYnSUsDCgpYkXBnGCA93YuDIgiC8GEWLlyIMWPGWJbbtWuHzMxMtLS0IDAwEIsWLcJnn32GL7/8Eg8//LBiP3fddRduueUWAMALL7yAV199FTt27MA111zj8JhWrFiBq666CvPmzQMApKWl4e+//8ayZctw1113oaSkBBEREbj++usRFRWFlJQU9O/fHwAn2ltaWpCdnY3OnTsjMDAQmZmZDo+BIAiCIAjnMBYakbstF42mRpttDBikt0+XtcLzyFnmfVG0k3u8k+TkyFvac3K8NCCCIFot4eGcxVvudf48i7Nnm3H+PCta36cPN5EohGGAvn2V+5J76RlOPmjQINFyTU0NnnjiCfTt2xdxcXGIjIxEYWEhSkpKVPsRCuOIiAhER0ejrKzMqTEVFhZi2LBhonXDhg3D/v37YTKZMGbMGKSkpKBbt264/fbb8cknn6Curg4AkJWVhauuugqZmZm4+eab8e677+Ls2bNOjYMgCIIgCCtaXNeFcexSKzsv0nNG5sha4eVgweLP0j9hyDUgdWWqT7nLk2h3kuxsYO1as2U5IIBL8jRxohcHRRBEq4RhOBd1R165udZcG3wfLMutd6QfqfB3hQiJn/0TTzyBzz//HIsWLcKPP/6I/Px89O3bF01NTar9BAWJwwEYhoHZbFZo7RpRUVHIy8vDf/7zH3Ts2BHz589HVlYWzp07h4CAAGzatAlff/01MjIy8PrrryM9PR2HDx92y1gIgiAIwt1ojfO2186VeHFpUrk9pXswac0kBC8KRurKVKSuTEXY4jBMM04TWdCF9E7sDeNUIyZmTERSZJJD14AFi6NVR30qkR2JdhfIFnhOtG9Pgp0gCN8hOxtYvx7IzARCQ7n/fW1icfv27bjzzjsxYcIE9O3bFx06dMCRI0c8OoaMjAxs377dZlxpaWkICAgAAAQGBmL06NF46aWXsGfPHhw5cgRbtmwBwE0YDBs2DDk5OcjLy0NwcDA+++wzj54DQRAEQeiB1gzs9trJbZ+ybgo2HNqgaRxSd3aeZnMzjlYdxdGqo2gwNaChpUHRgs4LdleZvGYyghcFo//b/TWP3x1QTLtOBAd7ewQEQRBisrPFk4u+Ro8ePfDZZ5/h2muvRVBQEObPn+82i3l5eTny8/NF6zp27Ig5c+bgkksuwaJFi3DTTTfh119/xeuvv44333wTAPDVV1/h0KFDGDFiBOLi4vD111/DbDYjPT0dv//+OzZv3owxY8agXbt22LVrF8rLy5GRkeGWcyAIgiAId2EsNGKakctWay/OWy1Te3ZGtuL2FXkrMP2y6YrHz92Wi+KKYjSaGjW5s6tRVluGHu17AABKa0qd7ocFi2ZzMwrKCjBj0wzExMRgcu/J9nfUGRLtOkGinSAIwjFWrFiBu+++GyNHjkR8fDyeeuopVFdXu+VYq1evxurVq0XrFi1ahOeeew5r1qzB/PnzsWjRInTs2BELFy7EXXfdBQCIjY2F0WjEggUL0NDQgB49euA///kPevfujcLCQvz4449YuXIlqqurkZKSguXLl+Paa691yzkQBEEQhBpC4ZsWn4ackTl2k6oZC42YvXE2jlYdld3OZ2AXopSp/e/yv5G1Kgt7SvfI9lN4phATP52I7w59h4aWBoQGhuKRSx/BZV0uE2V314PyunLL+7T4NNkxOQI/8bDop0VeEe0M28Zq01RXVyMmJgZVVVWIjo52qS+z2YyAAC7CoGdPoLBQjxF6DrPZjLKyMiQmJsJg8L9ICX8fP+DdczAaufjm4mKuGkJOjuNWWfoM3ENDQwMOHz6Miy66CKGhoaptWZa1ZF9n9AxA9xD+Pn5A+zmofa56/m0iOPS6pr74G+EI/j5+wP/Pgcbvffz9HITj/7zocxthDsBGePMCWK6EGS/uC8sL0Wxutnv8lJgUrBi7wnJcMEBDS4NsW2eEd0J4AirqKnQT7ADQOaozymrLEGAIQLOpGSbWpEu/oQGhqH+u3ql9Xfm7RJZ2nSBLO+FPGI3ApEnW5GQFBdzy+vW+7U5NEARBEATRVjEWGjFl3RTZeuNSlFzbpTXLtcAnZdOyjzPCW2gV14sT508AgKZJCa0wYJAe75363v431eSjSJIZE4RPk5vL/c/72fBZxhcu9N6YCIIgCIIgvA2f9Tx4UTDCng9D8KJgTdnP3ZlNnWfRj4sU643LIXRZ5487e+Nsp93Q9bSE+yMsWMwbMc8rxyZLu06QpZ3wJ4qLbdexLFBUZLueIAiCIAiiLcBboXl4Ky1v0Ra6mgvjx5Mik3C06qiNBZxvL7Vu89ufHPokNh7caOkD4JKmpcWnYWz3sZZtae3T8GjWoyg6U+SwcG42N1vqmLsa193WCTQEYmJP75ThIdGuEyTaCX8iLQ3YI/ndZhgg3TsePwRBEARBEF5HqdQYvzx742xZEc7HkstlUwcgm5UdAJb9ssymDwDYU7pHJLD5zOUJ4QlOuZK3dQu5HjBgkBaX5rXjk3u8TpB7POFP5OSIl/nYdul6giAIgiAIX0UPl3MhclnRhRytOoqYJTG4ed3NANTFMO+aPmnNJMWkbfb6kLZxR+w3ARhgQFZSFhgoJ5NlwWLOwDkeHJUYEu06QZZ2wp/IzgZ697YuZ2ZyyekmesfjhyAIgiAIwiF4a3dBaQEaTA0Wl/PUlakOx6PzpMXbt6RWN1VrTm7WYm5RFYKE9+gU1cnyPjIkEvkP5CMkIES2LQMG66asw3UXXeep4dlAot0FhMXySLQT/kZCgvV9fj4JdoIgCIIgfBepVV2aUI3//2jVUTSbm9HQ0mCJ556ybgo2HNqg2p+x0Ggpn6YX7IV//kiQIQgBTIC3h2FBbvKjX1I/p/sTxqaHB4UD4CZtpMdhwCAzKdNrsew8JNpdoKnJ+p7c4wmCIAiCIAhCHldc2Xmr+p7SPWgwNWBP6R4crTrqkGv5Q1seQsjzIQh7PgyBCwNF/QlLpwUZ6KEeAAIMAT51LcICw2zWGQzOSdnUmFSMSBlh03fOyBxLPgLAWnNe78kcZyDR7gKNjdb3ZGkn/A2GvLUIgiAIgvAASq7sWoV77rZcl8fQaGpEi7kFDS0NMLEm0TZh4riMhAyXj+XvMGCQ3j5d1vIspEe7HnZjwfWirqXOZt3Rc0dlWtpnxdgViAqOsiyHBXGiPTsjG+unrkdmUiZCA0ORmZQJ41QjJmZ43x2VRLsLCEU7WdoJgiBcZ9SoUZg1a5a3h0EQBEE4iZxFXZqVXZpd3R7FFTK1anWGL4k2uttotx/LmwQHBCM0MBQpMSlIjUm1WNPlrMtSy7OUsKAw5D+Qj7EXj3VpTN1iu9mMSYuVv7K+UnW7dNypMakWER4VYhXtvHs8wAn3/AfyUf9sPfIfyPcJwQ6QaHeJBuVEkATh87D+GWJFaKWkBMjLs32VlLjlcOPHj8c111wju+2nn34CwzDYI60z6AQfffQRYmNjXe6HIAiCcBx7Lu5KFvXC8kLZMmpFZ4o09a8lQZwesGCx4tcVluWQgBCkxKT4VGy3GlqE7kujX0L9s/U4MusIDs86jKZ5TYrWZaHlWa7vPaV7YCw0on1Ye5fG/eGED23GlJGQYdeCrxQewYBBSkyK5ZyykrJgnGrE4VmHLSI8MjjS0l7O9d7XoDrtLiC0tJvN3hsHQRCEiJISID1dfmYxNBQoKgK6dtX1kPfccw8mTZqE48ePo0uXLqJtH374IQYNGoTMzExdj0kQBEF4DmOhEVPWTbFYYnlB/uTQJ7Hx4EbOGs7AxqIOQDbbOu+CzVviC8sL0Wxutul//dT1yBmZY4k5d5RAQyBazC2a2/PHjwqOQvUz1ZZzd/b4noBPlpb/QD6MhUYs3LYQRWeKkBSRBAaMKP7/lr632OyfnZGN7Ixs2b75bVmrslBQWmAjlBduW4iRKSMdHq+wHznRbK/8nlKf/P+vjH1F1UoudI8XWtp9FbK0uwCJdoIgPALLArW12l/Hjim7AjU0cNu19qXRJeP6669HQkICPvroI9H6mpoarF27Fvfccw/OnDmDW265BZ07d0Z4eDj69u2L//znPy5eHDElJSW48cYbERkZiejoaEydOhWlpaWW7X/++SeuuOIKREVFITo6GgMHDsQff/wBADh69CjGjx+PuLg4REREoHfv3vj66691HR9BEIS/sujHRbKCfNkvyyyW9YaWBs1CiwWLi2IvsljmeWEv50KfnZGNBwc96NS4HRHswuPHhsZa1vEW546RHZ0agztQSpYmdO/mLdeDuwy27OesVVxJRBedKUL7cGufQjGsNG5pP3xMuRB78fRCnhjyhMNx6EJLe2hgqKbjeBMS7S4gfCYmV2PC36BEdH5EXR0QGSn7YqKiEBQXByYqyrp++HD1/oYPV+zP5lVnm/hFjsDAQNxxxx346KOPwAp+ENeuXQuTyYRbbrkFDQ0NGDhwIDZs2IC//voL9913H+644w7s3LnTlatjwWw248Ybb0RlZSW2bduGTZs24dChQ7jpppssbaZNm4YuXbpg586d2LVrF55++mkEXUhK8tBDD6GxsRE//vgjCgoKsHTpUkRGRiodjiAIotWgJbN70ZkiRUHubFmzz4s+V92fjzM3Fhpx38D7nDqGo/BCMSY0RrQ+OyMbr4x9xSNjsMeIriMcEqln6s5Y3g94Z4BDmft5lER0evt00URAckyyaj8hgSF4eczLonVylnalePogQ5DNxMPobqMdjkMXxrSbWd+3vpJodwFVS7uH40kJgiC8zd13342DBw9i27ZtlnUffvghJk2ahJiYGHTu3BlPPPEE+vXrh27duuGRRx7BNddcg3Xr1uly/M2bN6OgoACrV6/GwIEDMXjwYPzrX//Ctm3bLBMDJSUlGD16NHr27IkePXpgypQpyMrKsmwbNmwY+vbti27duuH666/HiBEj1A5JEAThNVwpoSbtx15m9w2HNnhN2LBgMWnNJIz9t2vJzrQgtAILLe08R84dsbwPNHgvyvjQ2UOYP3K+JpFqLDRif+V+y7Kjmft5eBEtt35v+V7LckmVHa3DAtf1uE60Ss7SLs3kzselN81rwrS+00RthQJcK8KJAmk1AV+EYtpdQFG0eyGelCCIVkx4OFBTI7uJZVm0tLQgMDAQDO8+kZ+vbm3/+WegXz/tx9ZIz549MXToUHzwwQcYNWoUDhw4gJ9++gkLF3LZgU0mE1544QWsWbMGJ06cQFNTExobGxEaqo9bWmFhIZKTk5GcbJ3l79WrF2JjY1FYWIhLLrkEs2fPxowZM/Dxxx9j9OjRmDJlCrp37w4AePTRR/Hggw/iu+++w+jRozFp0iSKwycIwifhhTYvMveU7sGkNZMQwAQgKCAIJrMJGQkZFpfp3G25KK4oRlp8GnJG5ojil+UyuwPANOM0gAWSIpJwtNq50lp6UlZb5vZjZCRkYFTKKLz5x5s2ot1YaMTTm5+2LJvMVqEnjaeeO3QuXvrlJbeN88T5E5Z4f6VYdB5puTxp2IFWeBF99xd3o6qxCgBw/8D7wYLFW3+8ZWlX02R9XpG6wjNgkB6fbuOOrpQITinWXrp/dEi05vOwjEXgcir8LH0VsrS7gKJ7fEWFejxpRYVbx0UQRCuDYYCICO2vMDtZUMPCtPflYBzFPffcg/Xr1+P8+fP48MMP0b17d4wcySWoWbZsGf7xj3/gqaeewg8//ID8/HyMHTsWTU1Nzl4Zh1mwYAH27t2LcePGYcuWLejVqxc+++wzAMCMGTNw6NAh3H777SgoKMCgQYPw2muveWxsBEEQWpEKbR4Ta0JDSwOazc0Wi6o9K7pSrHJDSwMaTA0+Idi1YnBR2hRVFOGdvHcAAD+X/Cy6Tvw15+HFrzBLOe+qvnTMUkVLfJAhCKkxqZYSZ8Ixp8SkYO7QuQDEMevC/4XH1lIyT65cnlzmfi1kZ2Tjrn53WZZHpoy0uS7S40hj7+eNmGdjWZeztKshFe324ujt4WjeA29Aot0FKBGdf2E0AllZnF7JyuKWCaJVEh/PefXIERrKbXcTU6dOhcFgwOrVq/Gvf/0Ld999t2U2e/v27bjxxhtx2223ISsrC926dUNxsX61dzMyMnDs2DEcO3bMsu7vv//GuXPn0KtXL8u6tLQ0PP744/juu++QnZ2NDz/80LItOTkZDzzwAIxGI+bMmYN3331Xt/ERBEHohZbM2sLtUiv65DWTLS71SZFJ7huom1ASaZenXK65DzmhaWJNFgF3ruGcaIJD7pqzYFFaWyobTy1NWscf79PJn+LwrMP4JPsTHK06CjOsIuJo1VEM7jLYpgRbkCFIU8k8OeRi0fnM/c4gPK/okGjVe/GNa9+wnEffpL54/+r3MbHnRBvRHRIQ4tAYpPuPWz3OYXd/Yfvfjv/mdHiJpyDR7gJCYzqJdt/GaAQmTQIKCrjPraCAWybhTrRKunblwnB27bJ9uTk8JzIyEjfddBOeeeYZnDp1CnfddZdlW48ePbBp0yb88ssvKCwsxP333y/K7K4Vk8mE/Px80auwsBCjR49G3759MW3aNOTl5WHHjh244447MHLkSAwaNAj19fV4+OGHsXXrVhw9ehTbt2/Hzp07kZGRAQCYNWsWNm7ciMOHDyMvLw8//PCDZRtBEIQcSnHlwvX93+6PDYc26NY34FhmbTmELvVHqzxnSXdlzELON52XXd+/Q3+sn7oeWUlZdmuWa0meJ7RmOyp+U2NTLe8DmACbhHFyFmqh27pwIiAj3rZmuVbhLU3oJs027ygdo6yiPSokSvVenNx7suU8dt+3G9ddxMWyS0U346BXX/EZ8YT/3+V/OxSnLy3hV9tc61Scvych0e4CZGn3H3JzOS9fPoyBZbnlhfa9igjCP+naFRgwwPblgXwa99xzD86ePYuxY8eiU6dOlvXPPfccBgwYgLFjx2LUqFHo0KEDJkyY4HD/NTU16N+/v+g1fvx4MAyDL774AnFxcRgxYgRGjx6Nbt264dNPPwUABAQE4MyZM7jjjjuQlpaGqVOn4tprr0VuLhfvZzKZ8NBDDyEjIwPXXHMN0tLS8Oabb+pyTQjgjTfeQGpqKkJDQzF48GDs2LFDse2oUaPAMIzNa9y4cR4cMUGoo5TAbe6mueL1ZQWYsWkGjIVGWSEuXJe6MhWpK1MRvChY1a1dKSmYrxMfHi8Ss3oQwARY3rcPb28RvE3zmrB+6noAtpMFqTGpME41IiIoQrVvoTXbUfHbLqyd5f3LV79skzBOyXIvZz2fN2Ke08JbmtBNa0k0JQ5WHrS8n/HlDIztPlY2yzug7BHhqGVdyqZDm0TLjoQLAOoTJr4KJaJzAaFod6jk2/vvA/37+2TNLaORE7jFxUBaGpCTA2Rrz1HhsxQX235GLMsZHQmC0JchQ4aIyr7xtGvXDp9//rloHZ9Ij2fr1q2qfd91110i672Url274osvvpDdFhwcrFoXnuLX3cenn36K2bNnY9WqVRg8eDBWrlyJsWPHoqioCImJiTbtjUajKNfBmTNnkJWVhSlTpnhy2AShilwCNwYMXtvxmuz6JzY9gaNVRy3beCEuRGr1lqtZzh870BDoF7G4Qs42nEVDi0LeJydJjU3FwbOckJSWAuMFa+62XBRVFCE9Ph0LRi6wCNbIDZGoba5V7Ftozeb7WrhtIYrOFCG9fTpyRuYoil+haO8Q2cFme1p8GgpKC2wTtclYz7MzsvHemPfw6p5XUXym2O6x5fZ3JOmcEsZCIxb+aBW2ByoPYNkvy/Dk0Cfx3cHvUHSmCFHBUSivKwegXP/cUcu6lNJaWy89R+L0HZkw8RXI0u4CipZ2tXhSAHjzTWDOHJ8zz7dmF/K0NNs5Eobhkvy3VXxwzoggiFbKihUrcO+992L69Ono1asXVq1ahfDwcHzwwQey7du1a4cOHTpYXps2bUJ4eDiJdsKtOFpCTenBv6GlQXZ9SVWJbJZ2rbBg8VfZX5i0ZhL2lO7xqmBPiUlxar+kiCRVkZwSk4KspCyH3OiFlvv24e1ttmdnZGP3fbtxZMYR7L5vt0jo2kuAJrVmS93W1URzXGic5X1ShG3eAEct9+O6jcPu+3Y7VItcb5SS8X138DvLdRnSZYhle7+3+7nF5VyaLwBwLE5f7zh/T0Ci3QUURbtaPOn8+VybV14B7rkHaPGdGdLW7EKekyO2tPPnmeNcOE+rwCHvEIIgCCdpamrCrl27MHr0aMs6g8GA0aNH49dff9XUx/vvv4+bb74ZERHKrqyNjY2orq4WvQDAbDa7/GJZVpd+vPXy9/F74hzW7V0n646+bu86xX0SI229RBgwCA0MlRUEgONCXYq360knhCdg3ZR1OF1z2m47wNYtvV9SP9V678uvXo68+/KwZvIazWMSenY9/f3Tip+Z3D0k5xXGE2QIwrop63Bj+o1O3VNC0Z4QnmCzfUL6BKydvBZ9k/oiNIBL1KZ2PF/4HhdVFMlbqCuKLN+jL4u/tGyTfo+E5yDE0XHc1Psm0f7CzPRa9p93uXy4gb399fgMnIXc453EaARWrLD+EJ06JWnQtat87OiAAUC3bpxg/+gj4ORJYMECIEQS2xEf7/Fa7q3ZhTw7G5g7F3jpQsnMzExOsE/0/CQlQRBEm6KiogImkwlJSWJLU1JSEvbt22d3/x07duCvv/7C+++/r9puyZIllvwEQsrLy9GgVIZVA2azGVVVVWBZFgaD/9k6/H38gGfOYf6W+bIu7Y9/+zjmb5mPQ1WH0C2mG+YMnINx3cZh4a8LUVJVYtMPCxYRgREiF3C+3y6RXXC85rhT45Mr7+ZJ0mPS8eQlT2Jcdy6vRLeYbiisLFRsX15XjgczH8S2E9tQVFlkmWzYU7pHcZ+Hsh7CsHbDUFZWhuHth+O9Me9hwa8LZK/ZtJ7T8Mm+TwAAW45ssaw/cu4IpqybgvfGvIdx3aw5MJTuoRaTsvFsZtZMy3ic4a+Tf1neT/p0EuYOmisaEwAMbz8cGydsFK2TO56vfI+7xXTDvsp9Ni793WK7oaysDPO3zBe1579HOT/kYGjcUNlzYMA4fI37xfazvA9gApDeLh1zBs7R/Hnx99eKvBU4eO4gusd2t7u/Hp/B+fPyCRS1QKLdCXg3ciF5edx6TfHfd94JxMYCU6cC333HvaSEhro9y7OUtDRgj+S3tDW5kF96qfV9fr7XhkEQBEE4wPvvv4++ffviUuGPuAzPPPMMZs+ebVmurq5GcnIyEhISEB0d7fTxzWYzGIZBQkKCX4pefx8/4JlzOFR1SNaCKBSMhZWFmLFpBm5Iu0FkTZRS2VApWu4Q2QGLhyzG3+f/xvLfljs1Pm8K9szETHw74VvR9V945UJMWaccrsKAwfbS7SiYWYDcbbmWOOjSOvmKIUGGILx6w6uiddMTp2P6ZdNhLDRi0U+LUFxRjLT4NMwfMR/nG89bRLsQXiS+uudVTL9sumW94j0kcAToFNUJJ8+ftCyP7zNeNueGFoyFRnxa/Kllef/Z/ZixaQbWTl7rVGy5r3yP+c+dn0Ti/1945UIkJibiUNUhm31YsDh07hASExNlz4FhGIevc1KtdRJ48RWLMXfYXIfPhb+/tKLHZxCqFj5tB//89fYyvBs5JC4/DrmR33gj8OqrytsbGoCKCmeG5zRSV/HW5kLuQ5EIPgHFtPs+am57hP/RVj/P+Ph4BAQE2JT3Ky0tRYcOtsmZhNTW1uK///0v7rnnHrvHCQkJQXR0tOgFcK74rr4YhtGlH2+9/H38rp7D50Wfo/87/RHxQgT6v9Mfnxd9brPdkcRYaoIdsBXYgzoNwpM/Pem0YHcFoXt6kCHIqZJrV3e/2ub6T+49GeunrleMbWfBovhMMQwGA+LCrG7iqbGpsqEDvRJ6KX5+k3tPxp8P/In65+rx5wN/gmEYTP9SWWwJj23vHhK66i++YrGon8jgSKfvuUU/LbIZEwMGi39a7NffY/5zl2ain9RrEgwGA9Lj0+VjxePTbc5BuN3RcYQHh1v2T45J9tj56/EZOAuJdieQcyMHnHAjv+QSXcajF9nZwMiR1uXMTM57oLW4kJu8GwZGEJoJCuJqy9bV1Xl5JISe8J8n//m2FYKDgzFw4EBs3rzZss5sNmPz5s0YMmSIyp7A2rVr0djYiNtuu83dwyRaKUpl2fhSa6krUzFpzSSbjOZ61RMHgP8V/8/G+u5uGDAwTjWKBPPV3a+GOceM+wbc51BfL//6smyd+eyMbByZdQSZSZmqSb2iQ6yeLnOHzXW5ZrhcuS6lY9tDKNojgsU5M8KDwqXNNVNcUWyzztezk2tFLRmfMzXhnckk/8uxXyzv52+d79P11fWC3OOdIC2Ny6wuFe6twY1c6I3f2lzISbQT/kJAQABiY2MtcVXh4eGKf9T4kmmBgYEul1DxBv4+fsD+ObAsi7q6OpSVlSE2NhYBAQEyvbRuZs+ejTvvvBODBg3CpZdeipUrV6K2thbTp3PWsjvuuAOdO3fGkiVLRPu9//77mDBhAtq3t80ITRBaUCrLNnvjbJvyakKCA4LRIbKDahtfhQGDzKRMTMyYiEe+ecSyni+/VVHnmCcnAwYr8lYouhLnjMzBpDWTbFymeaGWdyrP0nblbytF5cEcLV0GyGftF47VkUmA+uZ6y/unvn9KtM0V0e5IObfWhFpZPKUkbI5OkBkLjXhy05OW5cNnD2PSmklYP3W9LmXtfBUS7U6Qk8PFtDMMC5ZlROt1haxsukKinfAneLdhewlV+EymvNuWv+Hv4we0n0NsbKxdd/DWyk033YTy8nLMnz8fp0+fRr9+/fDtt99aktOVlJTYuA0WFRXh559/xndyeV+INoOx0Ijcrbn4u+JvBDKBMLEmZCRkIGdkjqYHdKWybNLya1JazC1YMXaFTR11X0cqWoV1skMCQzgPg32OWSVZsDh47qDidjWhZiw04o2db1ja7i3bi7/K/nJJYMkJYsA6WaF1EsBYaER1U7Vl+eg58QSNK6Ld3kRGa8bRmvCO/u1XmohbuG0hiXZCTHY2sH49F9v+998sWloY9O7tBjfy224D/vc/oG9fXbs1GrmxFxUx6NatPRYuBCZP1vUQPokwpp0vZ0cQvgrDMOjYsSMSExPR3Nys2M5sNuPMmTNo3769S7FS3sLfxw9oO4egoKA2aWEX8vDDD+Phhx+W3bZ161abdenp6W02DwDBwbu287SA+0POu7hrEX5KFk9APbmbiTX5pWCXilaRaA8IQe422woLwv3lrgkDBt1ju6seW0mouUNgKQni9VPXO2Sxl14L6bm7ItrVJjIIiNzZm0xNMBYaNd8PShNxrSH0QA0S7U6SnQ1MmMDi/fercN99cXDKcy8+nssSr1SK5uhRYPBg4PXXgauuAs6cke/DgQzzfOZ7Lskcg337AjFlCoP16zVmvvdjhJZ2Eu2EvxAQEKAq9sxmM4KCghAaGuqXotffxw+0jnMgCF9ESWA6Ivx4gcfDC7yUmBSHXd/1qrWuxoT0CVxiPA0l3rSI1rCgMMv70MBQ2Vhrno5RHS3Z06V9zxk4x6nzcYfA0ksQq10LwDXRDjhucW4rGAuNNpUHHHFvb6uhB/R04SK88FMI01Cna1cue92uXbavvDxg7Figvp6r6d6tGzBwoO0rPR0osa0TqgSf+Z43XrAsA4ZhwWe+b81GDamlnSAIgiAI30VNVLFg8Xf537LbjIVGZK3KQtjiMORuy8XlyZdbtqXGpsI41YgVY1c4PJ7QwFD0Teorm3RNDxgwOHzusCU7d5AhCAaVR/WuMV1FGbzlRKvU0p4Wn6Y43vZhVgtU78Telr7XTVmH6y66zqlzkjueHgJLLRmaK2PjCTIEISigbSUN9RSLflwke08s3KatDJczye5aA2RpdxFetDstArt2VbaUf/018OKLwHPPKc8K8KXhunblxLtcmTiBNV4u8z3LMo5nvvdDhJZ2sxlo456qBEEQBOHTJEUmqVrDm83NNm61vEs9/yC/p3SPaJ/r0663CLzsntkOxXfXt9QjNSZV1KcWi7iU2NBYnGs4Z7Oet0Dz52PPPT82NBZHZh1RbSONaZe6lgsRitQ/H/gTBoabMDCbzXbzqyjhy7HdSmMDuGtFuIeiM0UueV+01dADsrS7CO8J6ZSlXUvn//d/wNtv229bUsJZ3e1Y49PSgK4oQX/kWV4DsAs3Juc5ZLH3R8jSLobCAwiCIAhfxVhotOu+Lmedk8ZQS3ltx2uWeNrEiESHxyWt0c6CxWODH9O8/9yhcxETEiO7TWiBtlfWDIAmkRMWaHWPDwkIsQgevs52RJC1zFmL2fqgxAt2V5EeT80rwNNIx9YnsY+3h9QmSG+vUMvdAe8LPTwt/A2fEe0vvvgiGIbBrFmzVNutXLkS6enpCAsLQ3JyMh5//HE0KMWEewC3inaegQPVt997LzB/vnJsPG+NB/DizBLsQzryMNDy2oVB+O9+Tty3q2m9wl1qaW/r0MQFQRAE4WmErutZq7IU6ytrEa1C6xzf757SPXYt35PXTEbWqizsPr1btD4uNE5hD2UYMPh83+eK2xPCExAaEIpe7Xth3ZR1WDpmqawVV2qBVitrxqNF5Agt7fx7oeC5KO4iy/aiCve4XfqywBKO7c8H/vT2cNoE80bMa5Pu7a7iE6J9586dePvtt5GZmanabvXq1Xj66aeRk5ODwsJCvP/++/j000/xf//3fx4aqS0uu8frQV4e8M9/qrf57Tdg715cm3YQYVAW91GNjtXu9GWMRiArCwgL4/7/U/BbTKKdIAiCIDwL77q+p3QPGkwN2FO6B5PWTMLcTXNt2smV9JLCW+eE/WqBBYuC0gL8fuJ30fqXr34Z66euR0J4guZzYsHKegSkxKTAONWIsifLUPt/tdg8eTMm9uTEakiAVbQnhCfIWqDV4q15tIgcqXu8EGOhEX+V/WVZbjQ1Wt6rTai0VoSlx6hyhfvwZe8LX8bror2mpgbTpk3Du+++i7g49RnOX375BcOGDcOtt96K1NRUXH311bjllluwY8cOD43WFo9Y2u0xf779enMPPQT06QNceaVnxuRl+Cz5BQWco0FBAfDJJ9bt9FtMEARBEJ5l9sbZsuuX/bLMIhB5Aa4lTpwFi3MN5zB5jeN1a+X6jw6JRnZGNsqeLMOTQ590uE8eBgxiQ2MVRYhQPN874F5ZCzSfbEuJoV2GahI5Uvd4IWrl3/iyem1NuPO4s0IA4dveF76K1xPRPfTQQxg3bhxGjx6NxYsXq7YdOnQo/v3vf2PHjh249NJLcejQIXz99de4/fbbFfdpbGxEY6N15rC6uhoAl1TD7KLSNpvNYBj2wnsWZrObvuDt2oEJDQUj4/7OhoaCnT4dqKiA4bPPFLtgu3UDzp0DU1mpeijhObh6fdyN2WwGy7Ky48zNZSxl7QBepLPAhVnrlhazT1jb1c7B3XAzyoxlHM7gzfHrhb+fA43f++hxDv58/gQBcGI7d1suiiuKkRafhpyROTYJ4tRi1KcZpwn/TNuFd6ktqSrRTWAJY81fGvMSLutyGRZuW4i/yv6CiTWp7CnGXlItoXhWSniWnZGtWpauZ3xPTWNRs7Tby87P5wyYkD5B07FaE2RpJ3wNr4r2//73v8jLy8POnTs1tb/11ltRUVGB4cOHg2VZtLS04IEHHlB1j1+yZAlyc21nEsvLy12OhTebzaitbQHQDk1NLSgrk6mjrgehoTD89BMMMoLb3K4dzKGhCKysRLxKF2feegstmZkI/OMPxI8fr9huWPF7CEdP1CECFXl5ysfs0sWZM9EVs9mMqqoqsCxrUxu5qCjJItitWJfLyspRX+/9H2S1c3A3TU1xALg/4M5mhfXm+PWCP4cNG0KwYkUUDh0KRLduLZgzpwbjxjXa78DL+Ptn4O/jB/Q5h/Pnz+s8KoLwHNKM7byVVlh3WcnKztPQ4tgzGcMwAKuvRTTvVB7GdB9jWbaXxT3YEIyOUR1tJg7sJdUSimehqJZSWlOquG194XqMSxtnt661XEw7j1y9ayGu1lMnCEI/vCbajx07hsceewybNm1CaKjyD5aQrVu34oUXXsCbb76JwYMH48CBA3jsscewaNEizJs3T3afZ555BrNnW/9QVFdXIzk5GQkJCYiOjnbpHMxmM6KiqgAAAQGBSEx0PAupZuz1nZYGVsUa3y4tjeujQwfVbsYdXoWD+Axv4kEkDF8CptFWtLChoWALC5VL1XkIztOBQUJCgs2Dcno6UFDASoS7dQq/ffsExMZ6bKiKqJ2DuwkKsl4bZ+9db45fL8xmM775Jgz33hsHhuHumX37AjFjRhzWrjUjW/15yOv4+2fg7+MH9DkHrX8HCcIXkWZsF1ppszOyNWWCdxQzq793ykf5H+Gp4U+J1qm5kAPAirErHC5pJrS0q4l2NVFd1VhlMzEiR1iQsnu8Wvk3QJ966v4KuccTvobXRPuuXbtQVlaGAQMGWNaZTCb8+OOPeP3119HY2IgASSHtefPm4fbbb8eMGTMAAH379kVtbS3uu+8+PPvss7IPSyEhIQgJsXU9MhgMujwgBgTw7sUMDAYv1tBKTQWKimTrtDPx8WB4gZ2YCHNwKAxNMjPaQUEoD+yIDvUlWIgFgIKRkWlo4NzsU1M11YZ3JwzDyH6WOTlcTLu1HUQCnmEM8BV9oHQOnsSVY/vC+F1l+fJIi2AHuHuFYYDFiw2Y7HiopMfx98/A38cPuH4O/nzuBCGX6ZwFiz9L/0TqylS3HdeZGulqHD532Gadmgt5SmyKUzWjtVratYhqfmJECTX3eOHY/y7/G83mZp+sp+4NyD2e8DW8JtqvuuoqFBQUiNZNnz4dPXv2xFNPPWUj2AGgrq7O5sGGb+etL5dPZI/n6drVvlDu2hV71hbh7hs5of3F52fQuXMcd13j4/H4kx0RseYDLMJzSISdTPJ8bXi5MIPQUG4SwUvW+Oxs4L33gAvzO8jIAHr0AL74glsWhY9qmXjQOjnh5UkMwjkOHQq0CadgWe4WJgiCIDiU4taTIpMULel6W9iF6G0NTWufZrsuPk0xK/1DlzwEgBO/9tzUhYhi2gPkY9r5fnlR/WepbTkyLe7rwkR0chMEwrEbC42ykw9tJeeGMOlek6kJxkKjQ58rQbgTr4n2qKgo9OnTR7QuIiIC7du3t6y/44470LlzZyxZsgQAMH78eKxYsQL9+/e3uMfPmzcP48ePlxX5nsAnssc7SGNSV+wGJyAbepUC3RMsJ2IyAO/gfuxBX/yKYcqd3Hgj0L27/drwXhSqwkT5mzcDS5daly2TLFomHgBtkxM+PIkhB+NFxxCfgJ9gMZsxrqMZR44EgAWDCsTjGLqCYbiPkyAIoi3DC/XC8kKRJZaPW39y6JNuFeaepLqx2kao8dZuOcanK+cIUkOrpR2wiuqsVVk2rvJa3NdFlnaVCQLhsdoifF4GHhaspvADgvAUXs8er0ZJSYnIsv7cc8+BYRg899xzOHHiBBISEjB+/Hg8//zzXhujNXu814bgMEKvAOm4+W2NsBNfefw499KKnpZqgdgKrKwE2rXjJh0kfQnD8VkWaGmxLlvOu6JCfeIhLw8wmdTbHD8OJCfb78vLkxiEAMEEiwHAesGmeoQiHUU4xnZFjlavQPLEcB90zQjCowit6bwFXRqvzv/PgMHK31Z6cbSOYc+dvqSqxEaoCa3de8v3osVsfZgIDwp3ahxaY9qFSF3ltbqvq7nHE1akeRkAbeEHBOEpfEq0b926VXU5MDAQOTk5yNH8JO1+/NHSLhTtTrv1v/UWcPAg8PLLym2efBK4/34gMxPo318fSzUgElvxSn0BMB0uQf8LLv6Be4AOJ4H+ACoQD5btCtTWAj//rH6eEzXUjRx2wSNBJneCS5BYcR8qEyxhaECHwAr8Y01XTBxYAuRpmETyZU8MPe8jd/SlNvmm9zWj7xRBqCLNAs9b0NWyizebmx0+TpAhyKH9UmJScPL8SaeOJcSeO700gR4Pb4H+15//wp2f32lZL3Q9dwQtJd+kOBM7D6gnoiOsKOVloOz5hK/gU6LdH/GpmHYnUBp3BeK5h2Klh+XrruMeftVE+5Yt3CskRGz2FiK0QNuzVP/+O3D+vHqbI0c4q/exY8iYkI48XGh7DfAsuFczAmG+biBQkAc023kAiIzkPmQt5ZiUzpFn925u8oJh7AsWR8SKr4oyrf3pbaXW4RwS2pk5wa7lM7B33x4/DkREAHv3avPEcPQ8PSV63dSX4uRbcjL3fdbqvWLvunnrO0UQfoSctdEdOCK+jVONuDH9Rnz424eYsWmGS8dlwKBrTFcb7wEhakItMjhStOy0pd0B93ghzrivq5V8I6zIZepvy9nzCd+DRLuL+LulXck9/hi6Kmajtzy4ym0TctddwI8/AocOqbe76SZO2NfWqrebOlV9OwCMHMkJpLg4+Qz5AILQAuT9zi107AicOqXc37Zt3P8DByq3+fFHIC0N2LEDuOEG5XYzZgBLlnBt3nwTaGxUFiwnT6qLlQMHLJMTzgqRi6uBSlyYoIGTosZVwQjoa6VWaxcSArzyCvDnn8CGDbbbBRjLhgIjOql/Bk8+yR27pES1L4snhj2++w44exa4/nqHzlPV40RryIYWkepI+Ie9/uz1NXQody3q6uTb8Hz6KfejFRsL9Omjft0cuRZ+lJuCIPSksLzQp0pdBRmCLInQxnUbh64xXVFSpfyba2/CgQWL0tpSi8V6T+kem/ZqQk0o2gMNgQgKCHLwjDiccY93FnKP14az4QcE4SlItLuIkmg3GoHcXKC4mNNzOTnwmXrPmt3j7WWjj7djjc/N5YTl6tXAbbcp93PggN0xAwBiYoCoKPux9LW1dicAqmc+jejH7wGqqoBBg7QdX4mICCApCejcWb1dWBgXUvDKK8ptGhqASy8FSkvV+7rqKiA8HEhIcFqIrLrwfz1CgRINoubYMe2CsUsXYP9+9f7efJP74qi1+fprYMAA7phq7U6fBjp0AE6cUG7X2AjMnCm/TUIImoGjdhIrrVmjqS8LgYHixApSnnlGff+GBi6bYqdO6ufZ0AA8/jj3fTl9Wr3P8nLOmp2RId9fcDDw0kvctZCEK9mwYQPQvj0sGfyUJk5efdU6GabEiRPq23leeol7BQcDTU3ybRoagAceAM6dU+/rppu477G9e5JyUxCtFGOh0WX3cz1hwKBXQi/RuuVjlmPKuik24jzIwInnXgm90C2uGz7b95lin+nt0y0Wa2k4gD2hJhTtzrrGA2Lx7G6XdeE4yT1eGWfDDwjCU5BodxE593ijkasRztUGBwoKuOX1631DuItFu22ZK8101WCNBzhBoMabb3IP+QcPAvfdp9xuyxbufzWr988/cw/eW7cC996r2Kxu3BREX3wxJwbVJh7i463v7bWxN4mRlwfs3Am89hr3vxL2BLvlJOrsC8tbbuFyCkRGqsZwY8oUTpSrMXw4N2kSF6cuagYM4ASSyaTenzCdvxIPPmi/DQAMHqytXbduwPjxQGoqJ2wVuKv9l/ho8Qn1499zDzcjd+4c50GhxI8/AkOGAHv2qN+7ffuqT3QA3HdFC0aj/TYAcM016pMJTU3ArFna+po/n3slJalPnNx/v/2+3n8fGDWK84IZPly53dChQGEhZ5VX45tv7B/zwAHtE4gE0QrJ3Zbr0eOlxKSgqrEK5xrOWdbZE8+8sHrm+2dQXMnVTw8PDEfts9aJ+oXbFopEu1qfjgq1iKAIy3tnXeMBz1rahd4AZGlXpy1nzyd8HxLtLmIw2GaPz821CnaA+59hgIULfUO0C7WUVKQ7HJuvpTa8PQYP5oRebKxr/QCcNfvii4HqatVmlvPUOvGgpY2Wvnr2BHr3VhdvH37IWarHjFFu88svnJV982bOiqhEcTH3sseOHfbbAFxsv734/jNntPU1ejT3xdi0SblNt27cDXv2rN3PVBNr11ot9888Iysu6xGKvwOzgEvteE7MnMn1lZenLtojIjhhbI+PPuJ+SC65RLnNjTdyn/uZM8Bn8pYkAJwwTk3lJoBWrlRuxzDq1n+Am/QZOZILgchVeajv0wfYt8/+pNNFF3HXbf165Tb9+nGfvT3r+GuvcXkiPv9c/cd11izu92XBAuU2b7zBeWsUFKi3I4hWSnGFhr8VGtESF//K2Ffw6d5P8eneTwEAHSM7IjggGKW1pariOTsjG6NSR6H9S+0BAB2iOoi2C0Vwr4ReCDIEqQpyR4Sa0NLukmh3MqbdGbYdsXo2XfHPK5A7KpeEKUH4ISTaXYS3tAtFe3GxvBjmQ3i9jXCsHkmgZ88CrdVS7YjV2w6i89Yy8aB1ckKPSYzMTPttQkI0TU5YXPF//VXdnXvBAi6U4Z57lNts28aJmm3b1D0i/v1v4IoruDAGNQs4b2lXE+28yM7LU5/o2LKFE2979nAC0x6CCRaz2YzKykq0a9cOgy4xoALxMAV0BWAnZwOPnve3vTwR8+dbr4eaaL/vPms7NdH+229AWRnnfaDEhx9a+1IT7f/8J5CejkVpH2PeSRUPhXXruP/VRDuPlmvGMEBKino/t9/O/a8mxi+7jDvP1FQS7YTfIizXlhafhpyROZiQPkFTezC22xkwCA8KR22znZwzArKSslBUUYQGk0JeGUMQPp38KViwFsEOAKdrToMFq6ku9g+Hf7C8P1Z1TFRbXSiCu0R3wcbbNmoeuz2Eot0Vse1M9nhnMBYa8fTmpy3Le8v2Uu1xgvBTSLS7iJx7fFoaZ6wRruPDPH0BoWjn3/Mx+H/95YYDarVmO2j1FootgzQJWnw8WgJDEdgib0ltjtUm7r2GViFojxEjOCEyYoS6aFcTbTyRkdzNXVOj3i4jg4u7thdPrScxMZwlNTLSblML/ASL2YyWsjIgMRG7wSWp6MhC+2eg5/1tT7Q7ir1z6NBBmxeAlr7i44GICHxdcSnm6dEXoP3a6jV+gvBjpPHZBaUFmLRmEtZOXovh7W3DTPj2arBgUddsJyGkhJyROViwbQH2lO6R3f7p5E8xMWMislZl2dR/11IX21hoxOS1ky3LzeZmkRB1Z7Z0oWhnGJlZDo0EGAIs791paZdWA9B6jQmC8D1ItLuIXCK6nBwuhl0Iy3LrfQGppd1o5EKahS79ALdeN3d+PS3VMmLL8kEI2vx7XhFezeEe9r/8ggtP+GMXly39h45eTCSlRTxoFSt6ChG9RY2enhN6e2vAOlFVVMSgW7f2WLhQ0t4RwajX/a33eeo5UaDxenTtCsBeaLiCp4PN5Bvf1t619dXvFEF4ECWBtuinRdg4wdbarCWGXc7NXc31fe7QuZiYMREsWNkJAX474HxdbLmydEIh6s7Ea8Ka52ZWn7JB7hTtVHucIFoPJNpdRE60Z2dznp+8cI+PB955B5joIwkopTHtixYxNoId8J0YfGepCO+K3eAexBt7A4VhwO4L27xaos+OYDH+0RW544Hi4q5IS+uqXnlAByFSj1CEuUPUeDpfgAPtxMkiGezbF4gpU2SsJnqEOziCE+fpsuh1RKRquB53PRGP+gdCuQSHav1pmXzTiiPXTcukoF7WfYLwIEoCTRirLnSHbzQ12u1TTpxP7jUZa/9ei06RnXCy5iQAziVeGC+uJcGbs3Wx7QlRd5Y4MzDW3yhXRDsreOByZ0Z3qj1OEK0HEu0uIuceD4hF1s03+45gB2zd44uK5GPbfSUG31kaBc8jLAs0N4uXvYqCYHGq8oCTQuTBB4Hfd3CeByVOihpdrKR65wvQ0M42WSQDhmEt1RS8en84ep6uil6dReq193fF2JVFKN/H9ZfWgwuxv/JK5/rTjJ4TLJ6erCEIHZATaAAABlj460J8feRrHK22U3FEA52iOgGARbCHBoZi/sj5Did4c7Yutj0hKhLtbhTEJrOdCikqCMcudJXXG6o9ThCtBxLtLqJUp12I1wWiBPFYGaSnc/m7pPhKDL6zCA2HUtHuVUu7Cm6tPCARIgeirZ4HTvelh5XUC8gni2QE7z08IG+js0hlk7ti9z6uvzz9ElITRJtGmmRubPex2HhwIwrLCxFgCECzqVnWMt7Q0oC39ryl2zgq6ytt+ncmuZmzdbHtCVGhC7s7Xc9dsbTvPmX965u1ivNScEeMOdUeJ4jWA4l2F2EY25JvUnxNAEgt7fPmsbKuwb4Sg+8sPm1pV8DXKw+0FtLSbCeqhJZ2wjVcyM9EEIQM0iRze0r3iBK9NZubVfbWl61Httqscza5mTN1se0JUU9Z2p0V7cZCI97Je8eyzCcMdFdGd6o9ThCtAxLtLqLkHu/LSGPas7OBq67iSn4LmTDBo8PSHX+0tMuLSf/3evA1pMkiSbATBOHLyCVf8xana2wrg3g6uZmaEHVnTLux0Gh5f/L8SVGpOa1QRneC8AC1JUCjTNhfSDwQ0VV7Gx+CRLuL+Lt7PD+2pCTbdrxrtr/ij5Z2WzHpW5UHWgvZ2cDkyVzJcIOBRc+eLVi4MACTJ3NfaF+9P/wFf/7dIAhfRC75mi/hS8nN3FXyTVoiT1pqTiuU0Z1wC94QoL4qemtLgP+lA2aZhLiGUGD8he+avTY+JtxJtLuIFtHua1ZduTrtcomjzWb/CFM2GoFFizjX8rQ0WLKt+6OlXRq3npnJnY8vJTJsLaSlcf9fey3w3ntnkJiYaNlGop0gCF8iLT5Nse65p5G64vtacjN3lXyzV2pOK5TRndAdLSLVEQGq1Uqt9Zh8f2YzAs9XAoHtOIHhjNVbS7vGCvlxAdx6fn97bUi0ty54Uav2kO9rAkDqHg8A9fW27Xxt3HJs2BCCGTMMstnWpaK9pUW87A/k53t7BK0X/h5oavLuOAiCIOzBJ19zBgNjsBt/nRCegPK6cqf67xLdBf+45h8+k9zMXe7xelnIKaN7G0BPAapF8GoRqVrFsVYxXnNY/ZgN5Tb9GQDEy/UHaDumlrGFdQZqj8mPiyf/Kf8RAgJItLsI7wbq7+7xSpZ2X2f58kibUl18tvXUVHFbf7C0ewt/D4VwBv4eEE7m8Pjad5YgiLaNK5nKtezL1x93Jm7+xdEv+oxgB8SiPdCg32OuXhZyyujug+gtsvUSoIC64L1qC7f/6S3az9PeMe1NAGy5GmgsA5rOqh9r03AgMgUIilHv78hq63ulNmU/AnFZwPkDdsY2BqgrAUwKbXhOf6++3Uch0e4irSF7POC/ov3QoUCbBGJ8tvUOHcTr/CGm3ZMIRXpbFu1kadeftnYvEYQ74Eu8FZYXuj07fFltGQCga0xXlNaWgmVZNJoa7ezF4c6yas7grvHoaSFvdRnd9RS97hqbkqVaT5EdngzUHlEXlsVvAuGd7bfb+zzAQr3NpqEaLgCA7bcAHcYAYZ3U+/v7JaDmkHpf5zV6lpgbgGoNbf98xn6bX2/XdszzF2rMMkEAq/KbmTEXAAMULtXWr49Aot1FfMk93mjk6nxLY7ulSOu0A/7rHt+tWwv27RMLdz7buloiOn+YkHA3ws/XHz5rveHPuVnmd70tXg89IdFOEK4hLfHmbngRGhsaiyOzjqDfqn74s/RPTfv6smhndfwxJwu5AnqKXjfGXSu6ZjeUqwvZA+9wIrvmiHq7jUOA5rOASeaBWohWoXjgHfttmEAgsht3zhW/KLc7X2wVtGrsf8N+mwErgQ6jOUv795crt7v8cyA4Gij7CShQmdiKGwiABc7mKbcJTeQezEx1QEutcrv+K4Au44HGs8B3lyq3S7mJ+59Ee9vCV9zjjUYullsutlsq3IUx7fy45US7PwjbOXNqMGNGnGgdn239pZfE68jSrkxbvB5kaScIwldxZ4k3pX6F8dlqseDS/X1NtAcYAizv9b5+rc5Cbg894qkPf3IhBvqgtrhrPV3QG8rsCO3L5I8lZO/z6tt5Gk5qa5d0JXcuTVXA6Y3K7bpceKg/tk65zZhfgPhLgMo84NuByu36vQjUnwJOfQdUFyq363gtNwmgJt4TLwdie3PHVCMiGWg3gHOPVxPtgy9MTqiNf9Q3XF/2zjNpJBB1MWAo4e4DpfsjJN763l4bH4JEu4v4Ssm33FyrYOePycd2S0W7XEy7v4r2ceMasXatGVOmcB9EYiKwahWXbX3RIms7f7S0B3rw2+kP10Nv1ER7W5zE0BOytBOEa7izxNv6qetx+2e3o7ZZbLESxmcrZV1nwCAjIQN/l/9tWedrol1YS33pz0vRJbpL2xLaemHPSj36R6D+GHDsC/V+9vyftuOV/QQYgoBvL7Uvxu1NFGy/GWg8Y9/Vu+GU/XEljgRC2gPN1eqx0IM/5ERj/UkunluJ/ssEAlRFtPe5cN3URDs/QRUSry5AU27hrps90Zu1mPtfi8Xd3jG9KXojulrj86UIJ3+0tPEhSLS7iK+4xxcX2x6Hj+2WojURnb8IF+GkxH33WcujCc/JZPI/d3B3i3ZpTHtbg9zjCYLwVZwp8abFMn9z75sxMWMium/rLupfGp8dHBBss43//6mhT+HOL+60bPcl0S6tpX6y5qRTtdQ9ji/Wu7YnjNXcj4W0GwQEx3JuzRW/KrfLm6Xej7kB2LMAYFvUrcWA+nGEDP4ACEkAfhyv3GbACm1W3rhMIPIi+wna3IFWkaoFrWJc6zG19qeljSMTBRFd7Z+3ljY+BIl2F1Fyj5cTxu4kLY1ziRcei4/tliKXiM5fLe1ShHXlhTHtUmuqP5xbUJDnjtUWRSq5xxME4asolXgzwAAz5P+AabHMf3fwOxgLjega01Uk2jOTMkXx2UL3+JSYFJyuPW2J4R7dbbRItOtZC91V9Kql7lG8EeutpV3zeTsHYoDYTCCyO3DcqNzs0re1id7wZKDOTqmuwx/aGdMF+swDkq4AWuqAbdcrt4vL0tafI2gVlnqKWUCbANVyTEcmALQK4wv9mc1mVJ6tRLu4djBIwyy0HFPPyQk/hES7i/DZ4wFxBm65WujuwmgEqqrkLe05MmEkcmPz1+zxUvjrbzQCJSXW9d9LPJr8QaSSaHcv/P0tZ2knCILwJtkZ2RjSZQh+PS62GPZo3wOV9ZVO11SvbKjEpDWTcFnnyyzr0tqnIf+BfFE7oRBfdf0qjL14rGW5ySSe6fQlS7tetdTtoqdl3JEa21rG5WpSOCYQiL8MKLdjrR69jYtvrsxTF+1aGfE50FgO/HCNcpuuU7kJAFMzUDBPuV2XCdaJAnvoLbK1CksHXbhVBa9WHBmbngKY789sRktLGdAuUWxlc+SYfmYd1xMS7S4ivOfMZiDgQniJp0S7MAGdkNBQYPVqq6u4EDkvgNbiImwwWK+JkOeeEy//8AMwbJjnxuUM7naPF36+/jhB4yr8+VNMu/5QTDtBuI5cffXiM67HujNgsO/MPstyeFC4TRuhpT0sKEy0LcggnlH2JdGuSy11e4LcEcu4lkRuWv/gaJkosDcBUHcMCAgHqvYqt2NbgPKf7Y8nMMJ6fL1dm5Xo9ZRVjKuJdh49Lct6W6C1ttMieB2hDYtef4dEu4soxQV7yj1emoCOx2CQF+yOjM0fhRzDKF8TIfPmAe+9B5SWqpfH8yZkaXcvlIiOIAhfpviMbYkmPZLTsWBxvtHq+hwWGGbTRhjTLhXlDMPAwBgskwq+JNpVa6nrlZVcq2XcXiK3of/mYq+Pfqp+UvnPcgnOCnIAs8wfLEMocM0OLmb8lEpiM0A9QZqQ9Me4BGw/aXgw0lP02svkLmzvoNVb1VJNVl7CDyDR7iJSSzuPXFk1dyCXgA6Qj1HnEXsBMIoxvf4o2g0G5Wsi5ehR7n+18njehBLRuRc19/i2eD30hCztBOE4xkIjcrflorCcS7LVbFaP3ZEKU60l4vh67GfqzwCwtaQDYvd4OVEvrH/uS6JdsZZ614HarOP2BPnOmep1ogHg6Bqg7jjQXKPe18+TtZ3U6W+5lxLmBuDrTG198TCBnEVdiYvu0D/pl5Z2erugC4+pl6WaILwEiXYX0SLa3SkA5BLQAUBwsHx7wDYRXU2NfDt/FC4Mo3xNlFArj+dNPFnyzR8/a1dRc48nCEJ/3njjDSxbtgynT59GVlYWXnvtNVx6qXIG6nPnzuHZZ5+F0WhEZWUlUlJSsHLlSlx33XUeHLVnmLtpLpb9skxz+5SYFMSGxlqE6djuY/HSLy/ZCPcAJgAm1vpAwm8f0mUIvtr/FQB5US4U7XKiXHgMtZru3kC2lnplnrqA3jUbaK4EzhWod35yg/0BFC4F7CQ3BwAERnKx17GZQP5c5XbdZwCVu4Czu9X7C+vEvSr/UG4z5meg/WXAuT/Vk8IB2q3UeuIOF3SCaCXQVJOLKFkrhaLdneTkyAuumBjlfaTu8evX22+nBaMRyMoCwsK4/4065CVxFINB+ZqooVQez5sEBXnumvqjV4Wr8OdsMjFt8vwJwpN8+umnmD17NnJycpCXl4esrCyMHTsWZWVlsu2bmpowZswYHDlyBOvWrUNRURHeffdddO7c2cMjdz+OCnYAeGXsK8h/IB/1z9Yj/4F8LB2zFOunrkdmUiZCA0ORlZQF41QjWua3YO3ktejVvhdCA0KRmZQJ41Qjeif2tvQlZ2kXusfLbRcSaGgF9p/j64HSH+y7Z6c9CvSyU3c8cRTQbiAQFKve7srNwNCPgZSbOCuyHIZQLhP64PfU+xq9DZh4gsvUrkZAmLW2txYiunIx5O0GoCUq0/LerWJZcEzRiwQ60cZpBb+03kWLpb2khBNcxcX6x09nZ3OiW5p4LUDlN1k4zu3bg/Hii/JzN44IGWFCPJb1nss5wyhfE3v7yZXH8yZ1dZ67pm3R0i68v6Uu8m3xehCEO1mxYgXuvfdeTJ8+HQCwatUqbNiwAR988AGefvppm/YffPABKisr8csvvyDoQoKP1NRUTw7ZIxgLjQ4L9rlD51pKswmRtTBfWD+8/XAkJiZyVlIAf5b+adkuZ2kPCrAmVfEl93enqdqrvv2i6UDSKAAs8Ntdyu26XSh19/cLym0GLNdW4oyf7NAj1jsw0treU0nhCILwKCTaXURY8k1JtG/f7l7hJdePsEa5FOHY/vOfMDAMC5a1DUJ1RLhIk7950uVcOE5+EkWahG/mTODNN+X358ctVx7Pm5SVee6atkWRKjzn5mZGcRvhOHIx7UYj9zvhjslLwrdpamrCrl278Mwzz1jWGQwGjB49Gr/+Kl9W6ssvv8SQIUPw0EMP4YsvvkBCQgJuvfVWPPXUUwhQmJVubGxEo+CPX3V1NQDAbDbD7II7jdlsBsuyLvWhRO7WXM1tQwND8e+J/8bEnhMdGovc+IMN4kRz0v6EyyGGENXjueO6yB1D8TNQSzDXUgOmYD6Y45+p999jpkVoq7mgms1mICQejCEUjIzgZQ2hYIPacQ+EZrP9vvjzCevCveQbau8rrAswrlD5eoR1caydoH93fQc8hb+fg7+PH/D/c9Bj/K7sS6LdRYSWdrUSWp4Ws3J11+XGdvJkgKxgl7ZTw2iUjyH3lMu5cJz85yEde2am7fKePdb3OTnK2fY9ifAaNjZ67pq2RZGqZmknXEMq2tU8cSZM8MoQCQ9SUVEBk8mEpKQk0fqkpCTs27dPdp9Dhw5hy5YtmDZtGr7++mscOHAAM2fORHNzM3IUZliXLFmC3FxbEVxeXo4GtT+KdjCbzaiqqgLLshZLtV78XfG35rZvXPkGhrUbphhSoITc+JsarMk82CbWps/ztdbs8tWV1ag1KCdfc3Q8jmBoOA5DcyVYM4uGmhqcrY4EY2BgDmoHc2gXGBqOI+G34WDMtpYKFgYArCXKXy0/ZuXZSrS0lMHQACQYQuT7M4SgogYwt4TCcNlPMDRX2rQxB7WDuTYUqNXal7Zr51hfoQBkJgBaANQKj6e1nXu/A57C38/B38cP+P856DH+8+fP22+kAIl2FxE+nCpZ2qV4QsxqFe2dOplQUiIv3IXtlKxkcjXReTzlct4iSIDKfx5S0S4VZcJnx/x8twzLKYRJ0cLCuCoAQkHtrmvqp5OeLiEW7ZTu3J2oeeKQaCfkMJvNSExMxDvvvIOAgAAMHDgQJ06cwLJlyxRF+zPPPIPZs2dblqurq5GcnIyEhARER0e7NBaGYZCQkKDrg6ax0IgWs0oG7wsEGYLwn0n/wcSezs0sy40/Psbq/hwfE4/ExETRPqFhVpf4jh06qvYv3Vc3akvAbL3cYtFOEGxiDaFgxxUCgZAVsgDAgPuRZ7tMAHvxg8CPNypax9t1SAMiEgEkgm2/D6yCBTreElet5ZytfZlZM86ePYu4uDgYGIOkLy1oHZd7cNd3wJP4+zn4+/gB/z8HPcYfGup8uBGJdhfREtMuxRNiVk2ECcc2dWo9li2Lkm3HP2CrWcnUaqJ7yuVceD5KlnZ/iVkWivbUVOBviRHGXdfUV6+HO6GYdvchtbTLlWH0xeSPhHuIj49HQEAASktLRetLS0vRoUMH2X06duyIoKAgkSt8RkYGTp8+jaamJgTLlEgJCQlBSIhtJnODweDyAyLDMLr0I2TRT4s0tQswBGBSLweStMggHX9okPXBMTwoXPW87J2z2x6+mysVM74z5gYwO2bI1y0XMuRfYC66nbOyK8SNMyHxYISiNyqVe+kB35fZDJOpDIb2ic5fLz3H5QTu+A54Gn8/B38fP+D/5+Dq+F05b/+8Yj6Eknu8kmj3hfhpoVgZPLgZixbJK3y+He9tKGclU6uJbjR6xuXcGUu7ryIU7R07ijP7Bwfre02Fn1tbFKkU0+450tJshbwvJn8k3ENwcDAGDhyIzZs3W9aZzWZs3rwZQ4YMkd1n2LBhOHDggCj+r7i4GB07dpQV7P5IcUWx3TYMGKS31/+LIkwuJ5cd3swqxI5X5gGVeegfAssLtSWOD0DQl+hVWwKwZqD8V6BwuXofpZuB8p/U28RYs+RTVnKCIPwZsrS7iBb3+N69gb0XEpd27gy8+qp346elddqHD1dvVyzzXMFbyZRqoickeO4cW6ulnc+Ez9O1q77XtK2LduE9QrXa3UtOjm0YjbcnLwnPMnv2bNx5550YNGgQLr30UqxcuRK1tbWWbPJ33HEHOnfujCVLlgAAHnzwQbz++ut47LHH8Mgjj2D//v144YUX8Oijj3rzNHQlLT4NBaUFoprnQvia6jkj9f+iCOuwy2WP339mv+V91qosvDhkJq4tnGWxfOcJde7/0jkrtlbxW1vC7SNnRWcCgJAEoOG0/X4yngIMQcDexdqOSxAE4ceQpd1FtIj2du2s7597zvsJz6R12pUEG78+Lc12G28lU6qJPnSo6+PUSmu1tEvPQW9PIrXEiW0B4Tm3tJCl3Z3wZRiFeMoTh/ANbrrpJrz88suYP38++vXrh/z8fHz77beW5HQlJSU4deqUpX1ycjI2btyInTt3IjMzE48++igee+wx2fJw/oCx0IisVVkIWxyGrFVZMBYaMbb7WJFgZy6kSkuNSUVooLWmulx5N1cJCRSIdoml3VhoxDcHv7EsF5QW4NlvHlB0VYe5wep2rmZB52msUO6LNXGCPTAK6Hit+kmkTAWS6UeEIIi2AVnadcBgYGE2M4oiSCgq3SEGlFzxTSb5eu3C9iyrLNj49VIrmdDFf+JE+ZroPXpoH7+rSM9H+D+PP1rapWOUK6PlCtLJm7aG8JzJ0q4vcveqtFoGCfa2x8MPP4yHH35YdtvWrVtt1g0ZMgS//fabm0flfoyFRkxaM8liOS8oLcCkNbYx6ixYzB06F0vHLHX7mNQs7bnbxBn4WbCqmdctqFnQDaGcNd4QDJz4Ur2f/suBtJlA1d/AqW/U21K9cYIg2ggk2nVAzrorFJJC0e4Oi6ZSTfa6OiBKJsec1D1eSbDx7aQP29ISaXKl6zwpAuWur7+6xws/S09a2n31ergTsrS3bahuPOEpcrflWgQ7AFV3+I0HN3pEtKvFtMvF2o+y9aAXs+txIK6fujV+yxjgvP04fiSNAgJCtQnyiK6KCeYs2wmCIFoBJNp1wGDgRLo/inY1S7uScNFSIs2Tokd4rbWKdl9FzdJOot1x1IQZxbS7D729QvRGrSIGX8qSBD2hF8UVxYpCXQgLFkVnPFNSQegeH2c6z7mwX+CGxC44UHkA5SagayDwUjww1J5oL/+Re6nBC/boDKC60P4gBYLcbDaj8mwl2sW147IvCwV5RFcS5wRBtHpItOsAL6aUsserxSnrgZJor62VX681pt1f4py1WNpb7JfC9Qkopl0/7AkzrdnjScC1PtTqxgPq9w1BOEpafBr2lO6x285dmeLl4N3jkwOBy/fMAP60/vH5NBJAJGBigYALP431ZiBM7W9Q+izgbD5QtlW5Td9FQI/7gLrjwLcDtQ2UF+RmM1payoB2ifr/MSQIgvAD6JdPB+y5xwtFtTssmkpWwmuv5QSHFHEMOGM3pt0ZfN3S7quCVU206229bO2WdnvCTCnvBN8WsAr/ggKgocEq4OS+V4T/oFY33t59QxCOYCw0oqqhSlNbd2WKl4O3tMcHAAZW/iEigAFaWGBtU3v82nMp55IuQ70Z+CawJzDATom2ztcBoYlWt3c5KA6dIAhCFrK064BcmTFfsLTv3y9vIXI0e7wz+FNMu8nkOxP35B6vH2rCDJC6x8vPiKgJOLK6ugdPeDbIlarkK2IUFanfNwShFWECOi0EGYLckileDmEiOjUCL1+HKV0vJM3LuBk3fXIVDlQeEDn7nzEBcTVv4drkS7QdnOLQCYIgHMZHpIp/I+cerxQv60nRrmQhkiaiI0u7e8blDJ50j/dG9nijEcjKAsLCuP/dabFWK1UIiM9ZKXzCnvD3NTx5fdVw1ivEU54NcqUq+YoYaWm24xfeNwShFWkCOnv0Sujl5hFZ2XJ4i7aGkRdZ30d0xZdlx5HXCOwWvEpawMXiO2JBj+gKtBtg+yLBThAEIQuJdh1wxD3ek6IdkBcY0hJprTGm3V7JNyFKJfO8gbeyx3vis/a0q3mOxMtUWKoQULe089fGnwScL7nyOyvaPeWaLq0bHxVlrRsvFfTS+4YgtKI1AR2Pp1zjjYVG3PfVfUgNBFYmOLZvWnyajeeAJRaft6Bfs8v2Nb6IBDlBEIQLkGjXAXvu8UpCTC+rmJpolxMYWrPHuyLk/v1vz1n7nHGPF+JLot2Tddo97R7v6Vjh7Gzghhusy5mZVmEGiO8RpUR0rgo4PS3f9vpatIjx+1hsT3o2CF3uhw4Vl7Bct866LSkJSEkBbr3Vu94LhP8hJ3CVSI1J1d81vraEywpfmYfA83ss79//8Rn8XxywNwUYYS8rvISckTkX6rZz58V7ElgmHMiCThAE4RZItOuAvezxcqJdT6uYUiI6/gH+3Dnxg77WOu2uCLkzZzxn7XPVPd5XRXtrq9PuDVfziy+2vs/Ptwoz/tg8SvcHb5ENCuKWL7pILPzV0PM7rqWv1hCL7S3PBul1E36+p08DJSXe914g/A9e4GphxdgV+h68tgT4Xzrw7UAYvrsE8TvHwvDdJcC3A/G/yGI8Hw+EG4Bf6oFGpQl6maRw2RnZWD91PTKTMhEaGIrMpEwYpxo9FotPEATRViHRrgP2LO1yolJPq6OSpT3+wt9a6QPn4cPWNu6ytAv7d+a8HLFQupqIzpfCAFqzaLcXY+4O1M5LzdIuJDubs7YCwKpV2gQ7oO93XEtfctfRV135lfCWa7r0uyZc9nfvBcJ7ZGdk4+lhT9ttN3foXMdFr8CKLnrVlnDbGysAc4PsrgYGONMC3HYaGHYc6HEUGFgC3FzTQ5NLe3ZGNvIfyEf9s/XIfyCfBDtBEIQHoOzxOmAvpl0ILzD1tDoqifbwcPkHzj//tD2uHHqJWUfPy159bSmtydL+++/W9/v2iScr/D0RXU4O9znyeEKQaRXtSt4qPPw94sh3Qs/vuJa+5s1jMWWKdfLBm7HYzoZy8J4N/H3SpQvwj39onyhxFjXR7u/eC4T3MBYasWrXKtltQYYg9ErohZyROc4J9v+ly4tyQygntk3qP2rZp4CfGhgALI63MDjWwuK5y5dyruwEQRCEz0GWdh2Qs7QrPdzz4lFPN1Al0X7ypPwDZ5WgZKzZrFynXS8h5+h5OWqhdMbSrmWCxdMYjcC771qXGxrEItffE9FlZwPDh1uXpTHm7kDtvITnv3hxFPr3Z2S3AdZ7xJHvhJ6eBVp+L7KzgfHjrctar6+vZJznEU7MLVzofsEO2N4nwt8Ef0lESPgWfLm3cw3nbLYxYNAroZfzVmoVKzrMDcDmK4BNw1S7yBm9jFzcCYIg/AgS7TpgL6ZdCC8w9XQDVRLtHTvKP3BGR1uX3Z093pnzctRC6YylXSj0fUW05+barhN+fv7uHg9wCb14pDHmnqaszPreZGJQUGBdll4PpftKDXvZ63m0iGatvxepqdb3Wq6vuzLO65U0Ue97XgmtlnbKJE9ohS/3JgcLliuR5i5qDgFQ/7G68qIrycWdIAjCjyDRrgOOuMfz4jE7G7j7buv6Pn2ctzoqufZOniz/wNlLUArWXXXaeVJSHD8vRy2UzpR8U8o54E2Ki23XST8/PfGGaNf7HOyhdl5HjkjbKg/OUUu70chNwghFp5zlW6tozs4G1q61LnfuLP+9UquSIIenM/o7SkCAZ46jJtoffdT63pXfaaJtUVheqJiEzlIizVnO/KG+fcA/gFFfO98/QRAE4XOQaNcBe4nohAgfqrsK8rv8/LPzD4JKlvZLLgE+/NC63KMH98DZsaN1nZqlXQ8h50jiLh6tFkoeZyztcvt4G6XJCp7WYGn3lOWUR+2zra/X3o8jMe1CIS5sP3++7XfBEdF8443W9089Jf+9Ek5gacHTGf0d/fx9wdJ+ySXW97/+SoKdsI+x0Ihms/IMmqhEmiPUlwK/3A7svF+9XeJwIKY3F98uh0xWeIIgCMK3IdGuA864xwNAZaX99oB991kl0c6ywBVXWJfXruUeOD1Rp50nONjxfbKzxaW67MXmOhPT7ouWdrlJCeE95e8x7YBvWdrDVOoTuxLTLhXiPHJC3BHRLLxPlSYcHLW0e6LEmqP3sDvveS3HBJR/E3xlgo/wbWZvnK24LTUmVT1+XC4rfMVO4K/nga96Akf+rW0QEV25hHTX7IL56p2ouGQjzFfvVM0KTxAEQfgulD1eB5xxjweAs2et75UsZFoyqSuJdrMZqK0VL0vHqVanXY8H1EAn77AOHYADB7j3+fnqbVtLTHt2NnDDDcCXX3LLwcHAf/9r/Zz9PXs84HlLu9p5de4M7N9vXWYYVtFF3hFLu5wQB+SFeFoa952WhkHIiWYtot1eFnwp0oz+gD4x28KJALPZ6uauZdJGeI19wdLuDY8Uwn8xFhpxtOqo7LYgQxAOzzqsvLNaVnieuAFAnxxg+03K2eN5K3pEV+5lNqOlpQxol+j5H2GCIAhCF+jXWwecyR4PABUV1vdKwlGL+6yaaK+psS7zfQiPpWZp9+YDalCQ9rb+ZmkXek70789gw4YQyzZhIrHkZLF3AcW0O46ayI6Ntb43GFj07Wu/Hy3XSS7MAZAX4tIEc/wx5ESzFtHuqHs8X2KNJyxM/5htRy3nwnMQtndnlns10e6NyS3CPzEWGjHNOE1xe6+EXorbAKhnhQeAjLnA2B1A8g0WK7rNi6zoBEEQrRKytOuAI+7xQvFYXm59r/SwrcV9Vsm6JrW08/2oPaBqWe8IzvbhiGjXYmmXXl9vWdrlPCdmzIhDTIwZkyeL7w/pOXgipp1PoFZczInPnBxxCS5X8bRoF2I2i6+h8PynTq3HJ5+EIiDAdUu7nPWaXy9FWpc8IMAaxqI0BkA/93h+DDx9++oj2KWWdrn1SsiJdi0eR65Aol0es9mMAwcOoKysDGbJRRoxYoSXRuWb8CXe1HAqjl1Iyk2A4YLbCm9FJwiCINoEZGnXAUfc4/kHUqMR+PNP6/oNG+Tba8mk7qilXfxAyrjsHq/2IOvsQ64jsfBassdLRbu3EtHZek4wYBgWixZxN5FQdEm9INwd0+6u8l9CvOkeL/1OCq9tU5O6mnQkpj07G5gwwXa9khgWis7YWOV27hLt7kBJtGv5/IXnybvVuzvLvVqddl9MWukJfvvtN1x88cXIyMjAiBEjMGrUKMvrCmGyFAKAeok3gItlt1tWra3NChEEQRCaIdGuA45mj587lxNDwgfsBx5Qrs8sRC6TuloiOnsx7Xq4x6s9yMr1ocXN1RHR7mr2eE9a2uU9JxhLuTeppV04Nndb2j1R/sub7vFqol1N7GoJe5HSo4f6dul3gEftOyccf12dfBtH3eOluEMz6OEe7+4s92qWdmk4UVvhgQcewKBBg/DXX3+hsrISZ8+etbwqhVlUCQBAcUWxYok3AFgxdoV6B01VwO4ndB4VQRAE0Vog0a4DjrjHl5QAy5bZrlcSR9nZQEyMdVmaSd1oBD75RP5YWmLa9UhEpyZ6pX1otea21ph2ec8J1uI5IQx1YFnx2Nwd0+6J8l++ZGkXbmtuVr64wnvpySe1xVSrfXfkvgNyY5IiHL9wMk6Iq5Z2d4hSV9zj+fbuznJPot2W/fv344UXXkBGRgZiY2MRExMjehFikiKTZNeHBoaqZ4sHgLN/At8OAsq2umdwBEEQhN9Dol0HHHGP5y2qUnhxJGeFFgqd/HyxYJ80SVw6ToiWmHY9Sr6piV7pQ65Wa67eMe2+kj3e1nOCy1g+bx53QaSWdqWkXHogvQ88Uf7Ll0S7Vku7cL9jx7SFDqiJO7nvgJb9hOMQTsYJcTR7vCdw1NIuJ5KlCfvkPI5cQatob0vu8YMHD8YBvoQHoYpaxvjV2avVBfuhj4DvLgNqDgBhnQGDgpsZ1VYnCIJo01AiOh1wJHu8koUMAJKS5JMthYbKt1eqBy0cg72YdpZV3l8P93jpNq3WXKF7vDSBmBR/co/PzgamTOGSjQFc4q/HHjuLiRM5y5W33OPNZveV/xLiu+7xtgPLyuLu14svtq6Tm2ySS4Sm9p1QKglnbz+paOeTBhYVMejWrT0WLvQdS7teiej48WRnA6+9BjzyCLeclgYsWaI9aZ69BItqddrbqqX9kUcewZw5c3D69Gn07dsXQZKZ1MzMTC+NzPfg49ml7vHBhmCrYK8t4bLD85gagcJlwPHPuOWO1wJDPwZaasXteELiKfEcQRBEG4ZEuw444h4fFqYu3OWs0Eox64WF6g+RSnXapSLXk5Z2rXWphc+HjY3cdVPCGfd4uX3soVdm9V6Cqj+7d7MoK7N+wNJEdM5Y2rWOU2rhlWYy5/vSs/yXULTx97encNQ9nr9P9+6V708tdEDunuInn9LSgD17lPtUQjj+EyeEE3wM9u0LxJQpDLp1U97fW7gS0y68jldeaX3/0UfAZZfZ78toBGbPBo4KjKDCzPNyx5EuS7+TbYVJF34I7r77bss6hmHAsiwYhoHJ07UyfZjC8kLZePYmcxOMhUZkdx2kXn89fTYwYBnAGICQ9iTOCYIgCBvIPV4HHElE17mz/PrbbwdKS+Wt0ErJ3OxZ1aSJ6JRKvrkzpl3at1Y3V6Fob1ApWys9vtbSXI66x3siszogdm+WusdrEbiOjFPOLVsq7vUU7IBYtHnimV94DGmSNnvu8XLu60LUQgfk7j9+LHLJJdX2k+4PAKdOyVchOHlSeX9P4kr2eDlLOyD+bqhNfPLw34WjEq9luZAcNdGuNJ7WzuHDh21ehw4dsvxPcBgLjWg2K/8xnrRmErbsW6Nef/2iaZxgJwiCIAgF6K+EDjgS0x4TA/zjH9Zl3g185kzlmGI5cnPtj8td7vHSRFyOuMdnZwPPPWdd7ttX3porfLi3J9q1lHyT4qh7vJ6Z1dXEt5p7vBbBoBQvPXu2bVutsdR6Ijx3VzOda0Ftcsaee7wa9mKq5a4n/9lKJ0aEXsZaLe3NzfJVCJS8crTi7uzxWiaelGLIhaJdKaZfCP9dUBqT0EtCq2hvSzHtKSkpqi+CI3eb+h9jBgze2fWOh0ZDEARBtFZItOuAI+7xzc3A5Zdz7zt1Arpe8IJraVG2QsuhlNBOiJZEdM7UaZdacB2xtAPW8weAHTvkrbnC/RyxtCu5x/Pwn5Wjot0TmdUBdfd4LYJBKV766FFba7s0pt0R+ISJ4eEMrryyvWaPA+FkjKOiXUupQClqol3sHu/YWJKS1EMH5K6n0vnm58uPSYq9+5RhWIcSOMrh7uzxrljahZ+RFtGuljtA6iWhVqe9rVraAeDgwYN45JFHMHr0aIwePRqPPvooDh486O1h+RSF5YWq21mwiknqCIIgCEIrJNp1wNE67fX13PuwMCAw0No+O5srKcXTq5eyMJGzykuRWtrlYtqdzR4vtDQ7KtqFKAkZYZ/2rIdaYtp5eFHjaEZoPTOrO2tp1zpOJaReAVKPC60IXfAbG/l4aoMmEe2spd3Z8ATh9dTT0j59OifYlSYSHBHtwnwNap/Dd98pb+OrEPhiJS69YtodtbSrfRekXhLkHm/Lxo0b0atXL+zYsQOZmZnIzMzE77//jt69e2PTpk3eHp7PEGAIUN3OgEFKDHkmEARBEK5Bol0H5NzjlZJXnT0rL9r5B0NhciU1S57UKi+HNku789njeUuzI+7xgFi4KVk4hfvZt7RbO7Qn2oNlqulosbTLXW9nM6uriXa1mHYtol1tPFKvAGfd421d8Ll4ai2hAs6KdmfDE7S7xyv3ER5uu66+Xn0iQe6zUjqG8P5WuyarVilvS09vwbp1Zpct7efOOe7NIIeSF4cnLe1K34WQENvfVkpEZ8vTTz+Nxx9/HL///jtWrFiBFStW4Pfff8esWbPw1FNPeXt4PoPJrPwHhM8of9/A+zw4IoIgCKI1QqJdB+Tc47dtk29bUWEV7aGhQMCFSXpeUAiFxblzysfkM33zlrW4ONs2e/YAv/9uOya96rTzlmZHLe16i3ZnLO1C5MYvtaAC4mzTcg/+eiAVCI7GtGdnA1262K6X8wpwVrTLhwow+PtvxwSfI6Ld2fAEre7xTU3KYSL9+tmuq69Xn0iQ60vL+fJt5Cz40oRqQj77rBITJ7qeJ+DwYX2SLSrdW9LqAXJoiWnfscP+vaZU2WHMGNvvLcW021JYWIh77rnHZv3dd9+Nv//+2wsj8k0yEjJk1zNgkJmUCeNUI67sORVgFCzyVH+dIAiC0ACJdh2Qc48/c0a+bVOTVYTKWdqFD6xnz6ofNzsbGD2aez95su32f/3LOkEAAAsW2FoB1RLR2XtA5S3Njop2tYzecm30jGnXYmlXsqAKSU11XrA74h7vjGCYN8/2eHJeAc7GtMuHZrBobrYv+BzNJaB2TC3hCcLrp5Y9vqXFMY+T+nr1iQRH3OOlKN1/7dop78NfSz2swnokW1S6t4SfodLnr8U9fs0a5ycX5K6j9FpRnXYgISEB+cKECxfIz89HYmKi5wfko8wfMV+0zIC7yddPXY/8B/K5Ou1hnYDgC8I8awlwzS7ra3wRlXgjCIIg7OIzov3FF18EwzCYNWuWartz587hoYceQseOHRESEoK0tDR8/fXXnhmkAnLu8UoP2IGBYvd43tIuJ9rVLO08/DG1uMXKxaCrWdrtPaDylmZH3eOFD+WetrRrEe1aXLFdKVfmzph2ALj6avEynxtBOsngrKXdNmEiC4DR5L6uZMF0/JjawhMciWl3ZPKqvl59IsER93gpSvefFLEAZmyOoYdV2Nlki1rc45U+fy3u8cJtjk4u8F5JapNW5B4P3HvvvbjvvvuwdOlS/PTTT/jpp5/w4osv4v7778e9997r7eH5DGcbrLPrDBh0jekK41QjJ9Z5Tm0EGku5Guw9HwfaDbC+SLATBEEQGvAJ0b5z5068/fbbyBTWPpKhqakJY8aMwZEjR7Bu3ToUFRXh3XffRWel4uceQs49XhibLiQsTDkRnfB/QH/RLmcFdMXSzotALZZ2obvvQw9Zt2sR7fYS0ckJW6VzkrtO0vPU4ortiiBScxFWyx6vVTBIxdDGjfYz9DsiRrKzgbVrrctdupgQFMRqcl/X4mWhdExheIK97O1yx7AX0+7I5FV9vfpEgiuWdqX7r7JSvC411fpeztKuh2h3Ntmi0r0lFO2uWNrljqd1coGfKJXm9hBC7vHAvHnzMH/+fLz22msYOXIkRo4ciddffx0LFizAc8K6nW0YY6ER9/5PPIFxtOooWEi+wAff4/5PvQMICPHQ6AiCIIjWhNdFe01NDaZNm4Z3330XcXKB2QI++OADVFZW4vPPP8ewYcOQmpqKkSNHIosPOvYScu7x3bopt5WztG/fzolaYQihVLSrCU6tlnapFdCVmHZehI8fr9yGZW3dfUtKrNt9MaZdLuu0vRJRziLtR5qIzhlLu/R8lCY9nM0eDwDXXWd9/+KL1cjI0Oa+7qylHRDHKD/8sLbwBO0l35Qt7UqiPTtbnBwuI0Pd+0Tr+SpZ8JOTxev+8Q/bvvW2CjubbFFJEGsR7Uru6GqeCo5MLsgl5JReK7K0AwzD4PHHH8fx48dRVVWFqqoqHD9+HI899hgYe6VL2gi523It7vAAV96NAYOF2wRuH/WngRP/4953t80RQBAEQRBa8Lpof+ihhzBu3DiM5oOzVfjyyy8xZMgQPPTQQ0hKSkKfPn3wwgsvwKRi6m1sbER1dbXoBQBms1mXFyt4imtpsa43meSf7pqbWdTVcU+EISEsAgO5dsuXAwUFrOjB/rffWJgFT4/BwazN8fnj8P2owbLAvHnisZlMgNksv6/wfOQoKGDR0ADs36987JYWM3Jz2Qslqazj4Glqkr+uLS3WRnV16tdf2NZkYi/sLz/moCDbsTY3i/ucN0+8Lz924Xqz2faz0PoCzKJjs6y1r+ZmVnSMpiZrW/7c7L2E+wBAQ4Nj964QpWPU1lrbBQWxeO45s43LPH/N5O5XQPmzV792HCyrrb3wem7aZEZWFovQUBZZWSzq6oRjAUwm+XuGlVFq9fXcZ3HFFdZ9vvrKjBtvVP7+Nzaqf5945s0zS8Qhdy2nTRPvJ743+M/Kun39evH5rltn/7qmpFgPHBfH7cOfk9Jr3Tq54wi/k9a2XCiFdfzCe1Hu/hXelw0N8tdN6V5Tus5yvxHS75Zwm/AeEp6L3PfJ2d8ELfeFN4mKikJUVJS3h+FzFJYX2ljVWbAoOiNw+zj8L4A1AfFDgNjeHh4hQRAE0VoI9ObB//vf/yIvLw87d+7U1P7QoUPYsmULpk2bhq+//hoHDhzAzJkz0dzcjBwFc9CSJUuQm5trs768vBwN9ky4djCbzaiqqkJLSzsAITh3rhplZVyfNTVRACJs9mlpASoq6gBEAqiHyRQAIATcg7nYerFtmxknT5YD6ACAE0dlZWWiNg0NcQBC0NRUe6FPK2PGNGDTplDL8mOPncewYbVobo4H/9HX1zdceNCPthlrdfV5lJXxmew62Gznxysdt5CqqmoUFcUotiktrURioq0Jsr4+BgBXwLq8XDgOK/z1r6mJBn+tGxqaUFZ2FmfPhgCw9dxgmBYAYnP72bPWzw0Ahg8HDIYkmM3cmDMyWjBnTg2GDWsEfx2am80oKytXPG81amoiAHAPwKdOlaGpqQosy8JgMKCpKREAf12BioqzANoDABobuXOzR3l5IABrNuLTpyvRrp3tNTaZEgBwrh5nz55DWRlv5rd+1tL7jefkSQMALhlVXV0NxoxpxLJlEXjyyRgAQFpaC+bO5a6ZsAvuswq/0HclEhIcTXfe4UI/tSgrq7XTFmhoaA/+8/6//zMA4OLvCwrE3zeWZXDqVDmAjjZ9NDXZ3jPV1S0oKzuD06cDACQAAE6dOoOwMNOF41rvX57y8kqUlfHna/t94hk+vAzvvReCGTO4+zcsjMXrr59DWBgLwJoso7KyCvw9fvbs+Qt9d7Jsv/VWg6V+e0EBiylTDHjvvbMYN07O9YIbT0SE9VzHjGnAsGFVULgFAAAbNnDjlB6nf/8mAMEXzvsMwsO562I2W397Tp8uR0sLa/ke89+BM2es313hb1BlZTjkfqeE30/bsdpe5717G1FWdu6CxxO33WQS/7aeORMM/lrX1TWA/ywrKs4gNtZ2klh6Ds5w/vx5p/bTkwEDBmDz5s2Ii4tD//79VS3qeXl5HhyZ72EsNKLZbOv+wYBBevsLbh8sa3WNJys7QRAE4QJeE+3Hjh3DY489hk2bNiE0NNT+DuAejBITE/HOO+8gICAAAwcOxIkTJ7Bs2TJF0f7MM89g9uzZluXq6mokJycjISEB0dG2D4COwFmOGJw/zz3kPvJIDN58Mwbz5rEIDpZ/2GluBgICOIHZrl0YTp/mt9i2P3vWgGuuSbIsh4QwNll7AwO5/WJjbYtJJyeLY+dGj45AYmKE6EEsJCQUERG2kwsAEBkZhcRE16wrUVHRSE+HjUiybm8HuUTEQUHCMcqPg7/+QUFWcRQYGIzExEQoGYXCw21v+YiIaCQmiu8F4bNqQUEAgBjJXganMygLx9auXSIaGhgkJCTAYDCgpUVccz4qyjrxEBQUrOmYx4+LlyMj5a+x8D6IiYmVbaN0vKoq6/vw8EgkJsZg6lQDnnySW/fjjwGIj5deM+4eth5TflxaiIzk7mUeoxFYtIhBURHnJj1vHnvBnV54z7GwTogwomUAiI5OkD1WQIDtPdPSEojExETB9xeIimpvOR/h/Wvdru18ExMTMX06MGMGt9yjB4O77oqBNN9mWJj1+kZERCM+XjxJxQtpgDtfhmHx6quxmD5d2TMmMNB6rsHBoUhMtI2/FV5rhpE/zsGD1kmOdu2s18VgsF6XuLgEJCZav8f8dyBSMPcYEWH97iv9mZD/fiqzeXMofv45UZSwkWXFv63CPw0Gg/XAcXHtZT9D6Tk4g9a/g+7kxhtvREhIiOU9ucErk7vN1hgAcJb2nJEXnkfKfwLO7wcCI4GuN3lwdARBEERrw2uifdeuXSgrK8OAAQMs60wmE3788Ue8/vrraGxsRAAf8H2Bjh07IigoSLQ+IyMDp0+fRlNTE4JlUoOHhIRYHkKEGAwGpx+uhHz9dSj++ovrp7mZQUEBMGUKg6uukm/Psgzq6rj34eGMnVh0rvY1T2AgI3ro5frj/g8Otj2XmhpxW4YxwGCQxnIyilZwljXA9UtkQE6OuGSaMDO2ySR/DOEYGxuVx8EwjCVzNjdm22skRH4yRf085e4Ts1n9OGoIu2NZAxiGgcFgAMMYJDHt4s/GbGbw+ecMcnO5ZGVpaVy8sbQetdSbu6VF/vzE7uzybZS+I8I4ee6aG8CyBsE6+8c0m52/v4TjNRqBKVOs9xX/HVy/XhoHLf28xMvNzfKDkft+1Ndzn7/wPm1pMeDzz7ns73/9ZduP0r0uRXrNz5/njmUbd21tZzIxNuOXjptlGRQXQ/W+lXofSNtKr7VSHzU1ojOSTdYpvEf474DBYBBdU+HnrBTT7szv+OLFBhvRrnRdhL8vSt8Tbpv1HJxBj79HriKc/F6wYIH3BuIHFFcUy64PMgRZM8cfuGBlT7kZCIqUbU8QBEEQWvDaU8JVV12FgoIC5OfnW16DBg3CtGnTkJ+fbyPYAWDYsGE4cOCAKPavuLgYHTt2lBXsnmD58khAENPGlx/avVt5nwth9aJEdErYy/DNXwo58S/1trQKZfE6RxJwOcqOHZyoXLrUuk5oqVJKziV8cPd0Ijot6BV+aq9uufDcysrk63dL61NLr6lS1m1n67QD4s+E31dL0jxns8dLEY5drUSfI8dQStinlIgOEAvJjRutn4/c+Tt7vvz3WHp/SMvZ2auyoCVZm717QnqtlY4jtJYr9aml5JuwvUzJcADAunXKY1FCWkVDeq5K42xLiei6deuGM2fO2Kw/d+4cuillWm1DpMXbZixlwKBXQi9uoekccOxCmY3uMzw3MIIgCKJV4jXRHhUVhT59+oheERERaN++Pfr06QMAuOOOO/DMM89Y9nnwwQdRWVmJxx57DMXFxdiwYQNeeOEFPCSsIeZhDh0KhNRix7Lq5dp40R4aai35JpexXIqcqHNEtMsJWleyx2vhH//gROWgQdZ106db3zc3i8vBZWVxy46IdkdKvmmp0662v/Q4ziCur219L2dJFK47etR+/Xhpn4CyaJfeB45QL0gxwPejlqld7piuiHYhaiX6lI4h5/Xrqmh/7z11Qevs+fK/F9JrKuyvpUW9JJrWuvZC5O5xuWstd5wePeT7Eb7XUvJNeKytW+XbL1qkPB4lpFU0pOeqNLnUlkT7kSNHZJO8NjY24rg0BqcNYnGBvwADRuwaf2Q1YGoAYvoA7S/1wggJgiCI1oT3/fFUKCkpwalTpyzLycnJ2LhxI3bu3InMzEw8+uijeOyxx/D00097bYzdurUAkuyxDAPEqIRY8mJaaGlXa88j9xCtJtr5h30epVJHSu7x9gSwFnhRKZxAEIrwrVvlrccnTljbvPSSVczL4Q1LuzP78CgJF3uivb7efv14wDlLuyuiXc6Dw92WdiFKJdLS05VdqjMzbWOkXRXtJSXq11GtZJka/OenZmk3mxmb8ffqZX2fmamtrr09S7vctRbCH6eDIP+bUp9aSr4J28sYfQFor88uJCdH/X5Vmlzy4QTvuvHll1/iyy+/BABs3LjRsvzll1/is88+w6JFi3DRRRd5eZTeJzsjG1ddxMXBBRoCkZmUCeNUo9U1/uD73P/dZ6h/aQiCIAhCA17NHi9lq8SUIl0GgCFDhuC3337zzIA0MGdOjSXLMw/LAr17Az//LL+P0D2et7QrPQyK479tt/P7Bcp8ktrc4xnFY6sdV0jfvpzYVuqjqEhZtH/yia31GAB27bK2MZmsYj4lBSgt5cTD1VcDGza0Fz202xPtcpZ2ubbutLRLhSs/cWNPtIeF2Qp3OZdnrXXa9RLtfJZ9T1raheNVypmQkwPcd5/8/vn5YhduQJtHAg8/duE5dOkCHDmiv6Wdx56l/X//E28XjkPJtVwNufNWy08BAL/9xk2GvPeefD/Ctlrc44Xt4+KAigrb9lq8lIRcdRU3eVFaal0nvbbCMbe1Ou0TJkwAwMXo33nnnaJtQUFBSE1NxfLly53q+4033sCyZctw+vRpZGVl4bXXXsOll8pboT/66CNMF7plgctR42rVFz1JiOCSVy4bswyzLptl3VCZB5zNAwzBwEW3eWdwBEEQRKvCpy3t/sC4cY0YMED8JGc0Ap06KewAYM8e7n97op1hAGHooKvu8XKWdrNZ+UFULlZZDrUk/LyoVBLtJ07IH1/OogxwLuINDdw1fPllA/btC7SIRgAoLxePXYovxLQrWRvlRKNQMHTqJH9dpC7Pnohpt+ceryXkQi9Le3Y2cP311uU+faxWZbVjSK+lI5Z2fr3w85k6VV3UuTpJoSbat28PxiOPiH/OCwudPx4g/xlmZwOvv25d7t0bePZZ6zJ/XyjdW466xwvbDxwo337uXPn1SqSk2Pbd3Kwt9r4tiHa+ZnzXrl1RVlYmqiPf2NiIoqIiXC/8wmnk008/xezZs5GTk4O8vDxkZWVh7NiximUlASA6OhqnTp2yvI4ePerKqelObRNXdjIiSFKBhbeyd5kIhLT38KgIgiCI1giJdh3o3Fm8PHGi9YFUTiTyIio/32pllXuA7dIFeOMN67Kj7vF6xbTbE7VqsbS8qBSORSj4OtqWxXYA2zJyfKilI5Z2Z0S7Kw/vSsnn7Fna4+KA9evFy3Iuz1pj2vWztNseV4vrs6PXXWmMRiOwbZt1+amnrNdEzSVdeo84asDLzAR+/NG6PHAg8Oijyu0ddY8XetTW16uL9v/+NwwMo6+iVPoOXXON9f3WrcCwYdZlOdHuSiI64b7JyfbHowUlbxylCQUtYR+tkcOHDyM+Pl63/lasWIF7770X06dPR69evbBq1SqEh4fjgw8+UNyHYRh06NDB8kpKSlJs6w1qmrgyCZHBAredljrgyCfc+4spAR1BEAShDz7lHt9aaGqyPuiFhio/rK9dC0tpOLmHweZmYMsW6/L580BqqtU9PCdHXbRLLYeOWtq1usdLRWH79sDZs1zfM2dyAuq556zbheJowgTg1VfV+1dGrhQX97+rlnZ7ItaVmHZHRLu4BJy4vNsNN8jHKHs6pt1Tlna58RqNYndtALjtNs6LJTtb/Rj8WAwGFmYzo+k6Cdm7V1zarakJUPD0BWAdi9ZrHRRk/ewGDQKuuEK8XXi/nDoVoJibwhEc9b4wmcTXWA9Lu5JIVvoddfS7qDQZKQxVacvu8UJqa2uxbds2lJSUoEnyBXlUbYZKQlNTE3bt2iVKLGswGDB69Gj8+uuvivvV1NQgJSUFZrMZAwYMwAsvvIDevXsrtm9sbESj4A9f9YVYNN5TwFnMZjNYlrXpg7e0hwWGWbcdXQtDcxXYiFSwCaN8YqZHafz+hL+fA43f+/j7Ofj7+AH/Pwc9xu/KviTadYCvu85TWioW7VKLN8/x4/IPiTy1tVwSNiG8dyAf4929O7esXu+dQ6nkm96W9ptu4s7tyy+Bfv24dUqW9v79ObfiNWvsDl8GFlLhzl8Hd1va3eEez4uDkBDrhIs42Zi4H6XcRp7OHi93X2kRZI6Kdrk+5UqQ8ckP7Yl2fp+QEO58lNzj1XI+CI/d1MT1pQQ/Fi0Wd6NR/Lnt22fr7i48tw4dTDh+3HXhrkW0SydehJ+L3KSZo4nolCztSvexs5M/0vNrabF+fm3ZPZ5n9+7duO6661BXV4fa2lq0a9cOFRUVCA8PR2JiokOivaKiAiaTycZSnpSUhH379snuk56ejg8++ACZmZmoqqrCyy+/jKFDh2Lv3r3o0qWL7D5LlixBbm6uzfry8nKXYuHNZjOqqqrAsiwMBquDYlV9FQCgpa7F4ubfruhtBAOoSZyK2nKZJAxeQGn8/oS/nwON3/v4+zn4+/gB/z8HPcZ/XkkUaoBEuw7U1IiXr7zSGuctzVAtJCXFGtMu9wBbW6tcQooXDCdPcsuOiHbb7PHy7V1xj+cFJd+3Ukx7czMXg6wm2hkG6NrVOmEh2CI7FqNR+ZzkrpMzAlzPRHQ8/HVUEu3Sc1IS7XrGtBuNnDAuLrZ6d2Rni0W7yWSbiM4dlna5+1Ct3JtcHDhg/U7yY3FWtPPH4mlq4iz8SvCfpVo4CY9Ud0gnCIT9AcCECQ147TVJZj0n0PIZSidn5ES70r3laCI64b5K1036GfP3rFJWeSX3eKXjtlXR/vjjj2P8+PFYtWoVYmJi8NtvvyEoKAi33XYbHnvsMbcff8iQIRgyZIhleejQocjIyMDbb7+NRQp1/p555hnMnj3bslxdXY3k5GQkJCQgWi35ih3MZjMYhkFCQoLoQa3B3IDkQCAtvAaJgceB2qMwnPsVLBhEdJ+AiPhEp4+pJ0rj9yf8/Rxo/N7H38/B38cP+P856DH+UDVhaAcS7TogLE8GAAcPWh/u1D6b2lrg8GHuvVq8uhIsaxXAvMVeDUdj2pUsUlKkD9MM45holxt7RAR3fQDOWp+XJ3aFjooCQkPZC4nnxOp14ULg/vvlx7p6te06X7S0S9c5ckw9Y9onTbKKRd67Y/1679RplxN/aWncuOQy6iv1HxUl7o//jjqaiI4/ltDSrlbZiR+PFtFeXGx/HMLz69+/GYsWmTFvnvWPSPfu3G+RI2i537RY2rXEtDtqaVfyUBC2538jlCY7hX2qiXaliTU/9ehzivz8fLz99tswGAwICAhAY2MjunXrhpdeegl33nknsoWxOnaIj49HQEAASoUp+wGUlpaig7A+oApBQUHo378/Dhw4oNgmJCQEITLuLgaDweUHRIZhbPqJNVfj1xQgbLc4yz0DFsyWK4HxRUBEV5eOqxdy4/c3/P0caPzex9/Pwd/HD/j/Obg6flfO2z+vmI9x+rR4WfiwqCbaT50CNmzg3is9wGot76rlHnDG0m40AiNHqvcrFSH//S93bsJjKbnHC+NIhWRlWd/z4QfCZ8RrruFL59leoKIi5YdrPru8EE+Ldnsx7VpFu56WdqV7QFqOj3c9t5eITouVVg9Le06OckZ9pf4jIqztAOv1VhLtSkiFoT0x7oh7vFwZM+nnLRWZl18u3h4ba/84UtxtadcyaaN0H2mxtMuFS0hRi2m3N862ZGkPCgqyPFwkJiaipKQEABATE4Njx4451FdwcDAGDhyIzZs3W9aZzWZs3rxZZE1Xw2QyoaCgAB1dy16qK2GmWoQp/e01NwCNvuEeTxAEQfg/JNp1QE18qIl2LVYkew+J/Pbt29XbCdtqrdO+dy9ntVIIObQgDQ84cwb4/XfxMR21tAvHxIt24broaL4+ue0FSk93TFS7klTOGexZ2oVx9+6Madci2pVcz/WwtDt63eXaZ2cD//qXeN3773MJ+tTEsfC8eNHu6HewRw/g3nuty/Ys7Y64xwvLqAHyQlR8vW2/x85MLGmZeJF+hsJx8N9tb1na5cIlpDjqHt9WE9H1798fO3fuBACMHDkS8+fPxyeffIJZs2ahT58+Dvc3e/ZsvPvuu/jnP/+JwsJCPPjgg6itrbXUYr/jjjtEieoWLlyI7777DocOHUJeXh5uu+02HD16FDNm+EZGdpPZhEaThi8zQRAEQegAiXY3s3evtnZKD/K33qpt/08+sd/GbLa1rPPr5Ni61b7VCrBNxCeE3/dCEl8AYsGnJNqFVk++f6Hwj4kB5s2zTUQHiLPqa8HTol3O0m40Anfdxb0XhlsI7wutgkE6iaTF7VvpeklFKO96bi8RnTti2pVio6Ulo/kSYEr9nzghLp1nz9KudC6rVwO9elmXm5rU77v8fM6D5OKLldvw3HCDeDk1FbjzTvE64fm1tMhPsDiKo5Z2Le7xSp+bo3XatVja5TwUpCi5xytNkLVVS/sLL7xgsWo///zziIuLw4MPPojy8nK88847Dvd300034eWXX8b8+fPRr18/5Ofn49tvv7UkpyspKcEp3kULwNmzZ3HvvfciIyMD1113Haqrq/HLL7+gl/BL50XqmlX+8BEEQRCEzlBMuy4om9fUBK0QpQfSbt207a/FW3HHDttJALWY9jNntD2k2nNFNRrFSaGqqqzvm5vlvRH4eHbAeg3PnbOuCwnhrKyhoWY0NBgQGMg9XHfqxFlZX3nF/riFY/QkUkGwYUMIZswwWASyUDx6O3u8kuu5MDeA2WybiM7d2ePVvAT4dkr9NzcDU6ZYl52NaTeZxJ9PU5P6OX38sbZJML5vIcuXA/v3i9cJj20y2d4fzghMaZ9ySK3lzmaP1+Ie72j2+Jwc2xKAUrS4x1NMOzBo0CDL+8TERHz77bcu9/nwww/j4Ycflt22detW0fIrr7yCVxz5IfcwfI12giAIgvAEZGl3kQ0bVGo82UEoupQeSLWK/uRk+20+/9z2QVXN0t6+vbZjq5Gfzz1EC8WA0GLe0iL/8C50ua+v58Z59qx1HX8evGDkXaT5eGWtlmNhX55CamlfvjwSDMPKfg7OJKLTM6ZdaJEODOQmYCZO9E6ddiVLvpJbuJp7vPA+sFra5WdB1M5Fmv3f3r2kVUhL+5GKY8DWPV7atzMCU9inlrrojlraHXWPV3JTVxpPdrZ9aztljyf0oLa51n4jgiAIgtAJsrS7gNEIzJgR5/T+mZlA796c1dJV0X733bZxsFJOn5a3xik93A8fzp2jowitid9+q25dbG62L9oBLlZWKNr5yYamJk5o8aW2+HNROl7HjtYyeTzeFu2HDgUq1td2puSbnjHtwuR/sbGcYAfsJ6Jzh6VdSfApiXYtNdoB++7xahZhRyztjqBFtLvD0i5XglCKFku7lph2LSXfnKnTHh8vn31f2ieJdlv69+8PRmP207y8PDePxrepbapFhQloYIFQuUtmCAVC4j0+LoIgCKJ1QqLdBRYtYi5YSDWmeBfQqxdnhV66lBPtSlYkraJ91Cj7bTp0sBXhR44EKFqmzGbOgq81UXBUFHce6elcoriffgLKytQfdJub5c9dKtrr6mxFu3A/ae1tuYkIgwF44glAUMYXgPcT0XXr1oLCwkDIhVm4M3u80piU4EWt0Qj89pt1/fPPR+K55xgkCkoSu9vSruRCLTyGWv/CiSRfFO3SfqQWbWkbOdHuqqVdSwy5J2PalX4jp03j8hSkpXHu8fZwxdI+fTo36ccfy4GqZ37BhAkTvD0Ev6GmqQbHWoAxZ7vip1s/s20QEu8z5d4IgiAI/4dEuwsUFcEhwS6sPR4dzf0faOcT0CratZR8693bNqZ98+ZQGAzyqvrzz7kEWFoZORL43/+497fdxv2fkMBZ+JWEu5J7vPSBWk60C0WW1NIuJ1gYRv46ORunmpXFWfQcfYCXis85c2oUPTbcFdPuTNKyxkZrHWwh585xmQSPH1ceA49e2eNddY93l6Vdrwkgxy3ttu7xnrK0C/fRwz3e0ZJvfC36ggLu3uSqSijjSkz74cPcufHHWr++dQn3HC2zHgQAq3v8+cA4oN0AL4+GIAiCaO1QTLsLpKcDDGP7ZBwWZi3bJbQ+8kId4LKfA/KZ04XoIdr5iYG//pITeix27VLet7RU2/EB8bnw4xkzxr6lXYt18vPPgXnzrMtFRY6LdoNB35j2ggLObZ9/gNcaSiC14o0b14hbb7WuDAqyfmZCoSLNP+CKpd0ZgdfUZK2DLYeWbPTucI931NJuMIirLWzZwv3/3//Kt1eLpZaKXHe5x9uztLe0aHePNxq5CaewMO5/pftWSwy5L7jHC9syjH3PID3c4/ljLVyofix/59y5c3jvvffwzDPPoLKyEgDnFn9CWOKijbL5EFdzfk/pHmStyoKx0IlYMoIgCILQCIl2F5g3j3ON54U7L2Z69ODiKgHg0Uet7YWiXaulvVZjrhs10d6lC/e/vMWbEWVzlyKsqe7IGPhr0acP8NpryvsoucdLeewxQFANCN98wwl5AAgIYBEUxL13xtK+dq19ASOHsw/wcm7eQutgc7N1vTSmXXhe9izt/LnKiR1n45+11MEWjkHtuHq5xytZ2jdulO8nJAQYN866zN//Qk8OIUrjlIZoeNrSLhWZWhLR8Z4S0gknObRY2qWTCfzvhZx1XVpuUi/3eCEsK863IIej7vFKE1AsK66K0drYs2cP0tLSsHTpUrz88ss4d6F8h9FoFNVTb4sYC4146ZeXAAAsWBSUFmDSmkkk3AmCIAi3QaLdBbKzgffeO4u+fbmY6q4XwteioqwPvJGR1vbOiHY9Le1JSfKWdt7qL0d4uLbjA2JLO38clgUuv1x5H62WdjmB+sor3MqQEOv5O2Npr6x0zmIuRPgAbzRyYQUGA/dKTRX3KWcxLigQD4wXN0ePivfTcq34NvxnJ+f27Wym8bQ05ckCLf3pVfLNnmg3Grn8BUr9iM+fkfwvxlcT0Ykt7YymiRjeU0I64SSHlph2Ryzt0vHobWkHuHPhvW6UUPqNcLRSA8PYd8X3Z2bPno277roL+/fvR6igLud1112HH3/80Ysj8z6523LBCH4vWLBgwGDhtlbuekEQBEF4DRLtLjJuXCN272ZRXw+89Ra3rq7OKpT4EmQAROLYk+7x/DGuv17e0t6vn2BJ8gCvtU688DjC8ZjN6uegFNMuRU6AHDrE/R8crE20K1nahcdw1uWVf4DnLZlHj1oti0ePiicD5MSn0jPwjh3W97W14mtlz9LOi3a93OMBLnbfW5Z2R9zj1dz45ZK2qaHmJu7NRHTS7PFaJmLkPCXUKjvIoWZpV4tplx5Hr5h2Hn4ygp88VYIfh/T499xj/Y7auz/4Y7XmEPCdO3fi/vvvt1nfuXNnnD592gsj8h2KK4rBQnxDs2BRdKYVu14QBEEQXoVEu47wFp76eqto9yVLe79+wAcfiLddfnmj5SH3ttu4MnS8+L7uOqBTJ23Hl45BaGlXc/G35x7Pj11OgPFJ8uQs7XJCRMnSLsRZl1f+AT43V7kNPxkgJ1zPnLF/jHPngDhBvjp7Me2OinY+1lmt3bhxXPItuftWeK97Mnu8nKVdzY3fUdGuNh5H67Q70rd02dHs8XLnL+cp4aql3V4iOqUYcun58PffmjW2+xqN9n8LMzO5du3bq7fjx7Ftm3j94cPc5NrcufY/x759uWPxJRBbIyEhIaiurrZZX1xcjISEBC+MyHdIi7ctucKAQXr7Vux6QRAEQXgVEu06IhTt/ANvVJR1u5xo94SlnY/3ZllOiAtJTjZZHmL79uXK0P3f/3HLF11kf1JBiJJ7vNo52HOP54WgnACZPp1b6Yh7vL0s+3Iur/YEXmys9QFerT40PxkgJz6FYlwN4QQHnzVbCt8nfz/y96IwAdmgQeJ98vKssc5ChAIKAKqrubAQuWd2YZ9arKiuZI+3J9rtufEL97cmk3Qs3bpcTLv36rTbZo+Xu2/lPCWUJjeciWlXs7SrxZBv2BCCKVMMKCgQt9u3T75igRz5+dx3UMvEHAD885/y25cts/0eSPn119Yt2AHghhtuwMKFC9F84UZjGAYlJSV46qmnMEnLB9KKyRkpdrFgwIAFa7OeIAiCIPSCRLuO8JZNYWI3oXu8XPZ4T1razWZ5axz/EMv3wf/Pss6Ldr3c43nR/uCDYmF7xRXA0KHce62inWHUH+iVXF7tCbFrr7U+wCvVvAeskwFy4vOSS9SPIcfOnfLr5Szt0gRke/eK99mwQRzrzLN4sXiZN7zJXV8tMcGeco+358YvHGvHjtz/fOk3rXgypl2v7PHZ2ZynBP9dio9Xz5ov14dwHLNmAUuWWJe//56bGLqQaFw0DjVL+/LlkWAY1uZ427erhzo4Az8OYYlCKT/8oN6HlqR4/s7y5ctRU1ODxMRE1NfXY+TIkbj44osRFRWF559/3tvD8yrZGdnondAbABBkCEJmUiaMU42YmNHKZ3IIgiAIr0GiXUd4y+aFJLsA7LvHe7LkmzT7OCAW8vyDsVAA81Z6R8fgiKVd7QGY91To2RO45hrr+uRkawiCXpZ23r1WakGzZxEWHkstxpXfJic+U1K4/+WTBcojvM+EyFna5RKQCSkrkxdo+/eLl8+fFx9DiDTGWg6paNdafkzap5ql3WTixOnTTyv3xQtegwHIzeVOvEMH5fZK4/Gl7PFaKwJkZwNjx3Lvb70VuOEG5XHITUIIj3PsmO0ESkEB52ouba+WiO7QoUCwrO2NX1mpvWKBVvjx8FU15KioUO9Dr8kZXyYmJgabNm3CV199hVdffRUPP/wwvv76a2zbtg0RwtnoNoqJ5W78jbdtRP4D+STYCYIgCLdCol1H5LIWC59thJnA587lBIo9S7ZWEeCsaGdZxsbSzotGs1kf93h7Me1aLO11dbZCjRftjiSiUxPEeXmcYNea5ZpH2D47G3jnHfH2zp3FkwFy4pMXfw8/DKxbp348nthY+fVylnZ7wicxUX599+7i5cmTuXORu75KJbOECM/9wAHO+r9nj7bs/Y6WfFPzXhCKdv47WlOj3F5pPJ6q064le7wjFQH4+81efL+ci7yal4PcOiVL+4oV1s+6W7cWQZiClXbttFcs4NHqHn/LLcr724uLb+2W9ubmZgQGBuKvv/7CsGHDMHPmTMydOxejR4/29tB8htM1XDK+DpEOzvYRBEEQhBOQaNcRaXm0gACuFBzPxx9b3x85wgkUJRdnR9Eq2uUeqNUs7fY8AYQ44x5vT7TzMbLPPSeuu20y6W9p58epFnsrh7T9lVeKl7/9Vmy9l7O088cICuKEv9ArQ4n+/eXX833ydcePHJEv+yZE6MUgZPhw8fKhQ9x9y9fjFuKopX33bvE2e9n7HXGPl45HaawMY/3eqk0uyeFOS7sz2ePtWdqFXg2bNinvJ0ROtDuaxI9v//nn4vWnT1snaebMqZG1tA8erL1igaPjuewy+e0sa3vfS2ntlvagoCB07doVJr1u6FZGQ0sDzjWcA0CinSAIgvAMJNp1RGppDw4Wu5cLLUC8QJEm+nIW/iFcDrWYdrNZPabdkWc2Z9zjW1rUxdVff3H/m0ziXAFCS/v/t3fm4VFUWRt/q7MSsgJJ2PddCAgo4gZKFJRRJIjIoCgqjgsfKjAioxAWFUREVFxQVFwYUSAiMygOoLiBokAwCASJQFAgYcvGkq3r+6O43VXVtXZXd3Wnz+958qSruurec2vpqveec881mj1ez9PORJv8hVzvGMjrkgtkufBR8hizOtm5EncAjR+vXG+LFsrrWVniDiG5jfLj0L27clnyDNvsutUT7UY87QqJqTWz95v1tGtdV0qe9vPnzQ2ctjsRnTx7vJanXZ7TgB37/fuNj/1nov/OO423A3CXP3eu53ccB8yezWHIkEqsWOF50bRrJ3RiiWe9MJJMUgt5x17Hju4cIw0aCENV5B0Mcuq6px0AnnzySfzrX//CKXGCAgIAUFRRBACIjohGcmyyvcYQBEEQYYGJ4GdCj5gY6bjhmBipaFfycmslQzLDQw+pf6cdHq/taTcj2tXC45m3XAk9T7saTqdbDBsNj9fztKuJdrOedrloly9redrZuRLbGR2tXK+RDO1qxMRIhbeacBOPTRZvq7S9WU97QoK0I4aRnq68r5po98XT7nB4RsgYJZgS0dXWcpqednlOA8b27cY87Uz0K5UhR74NK3//fs9ted4940JWluf3bF8WCeJwCENmlDp8jCKfpz01FejXT8gmf+qUEKGi18a67mkHgEWLFmH//v1o2rQpWrVq5TGOffv27TZZZj8f7foIAFBVW4Wei3siu382srooXMAEQRAEYREk2i2E44RweCZSlTzt4pdBjhO8pX/8YU3dai+aeqJda0y71supvE618HgmhqOjPb3Ovoh2s+Hxep52NqbZDk87E39K89KrZTVXs8vI8TQ67VfLlp5iS9whI8Zs9ng14XXokCAS5SJOLTzeG0+7ODze25xa8jHtlZXWhMf36AHs2eNZl1Z4fE2N9jlVy2lQWmpMtKuJfiUyMgTxe/iwsMzKb9cO2L1buq3SFItKbRB3aul52vWQ/0ZEREg7boy0MRxE+y233GK3CUFJzp4cTN041bWcV5SH4Z8Mx6rbVpFwJwiCIPwGiXaLiYtzi3YlTzt78WX/77pLO+O4UbReNL31tGuFx0dHC2Gk4uzieuHxiYmeWZn1sserYZen3eFQF4kMeei4lqf9hRc4PPVUukuYs+vF3572Nm2EObAZatfP3XcL+QQY7LqNjPQ8TkY87eKhEmp1snHtctFuZXi8PzztJ08CK1Z4V5aYvDzPY/Puu9Jp1AD97PHi5Y4dhYR/chITjYl2oxncW7QQ5ku/6CL3Orbf5MnAPfdIt+d5YNo09YKZbex8R0bqh7+bDY8XD5EwSl0Pj6+pqQHHcbjnnnvQXCvNfhgy85uZrnnZAYAHDw4cZn0zi0Q7QRAE4TdoTLvFiMe1y0X7I48IXqjYWPf0YgMGKJdjds5orRdVb+dp1/K079zpKVDUwuOZUGPjRsXozdOuhreJ6IyMaZe/kIvtU0rM54un/dgxoLKSc3mdd+5028pQm3aPlSOfNu3gQeXtxdx7r3RZTZD16yddTk0V6lPaXtxONSFoZApDtXHtVobHK41pN0ttLXD8uHQdS/7nC0rH9sQJz2Mq9bRrh8dPn65cV7duxsa0G83grnT/sc833ijdluOEOeNZkkal34GCAul3ERG+e9rl2ey96bip6572yMhIPP/886ip6w31gn0n9rkEO4MHj/yTKsk4CIIgCMICSLRbjFi0y8Pje/cWvFDnzgn/hw1Tn1JNnHXeCMx7D3i+XJudp10cHq/mMXU4PG3Xyx6vJNr37gW2bVOuQ16fWFyJPe1i0c46IdTC47Ve+I2ExysJl02bpPOMmxHtACf5/5//eNaj5WmXJxjLywM2bxa+HzFCeT/Aczo0NZEtb8uoUcJ1q7S9eFsjY9rVUAuZtjI8np1jcfZ4szidwNGj3u1rBWYS0ckjndnvS9Om2ueEZXc3msFdKRGk2pRvPC/ttFSKUvjyS6F+M552ozayMsnTrsy1116Lb+SZKAl0bNTRYx0HDp0aaozzIAiCIAgf8Uq0Hz58GH+KMqht3boVjz76KN6UT1AdZuTkuMdxAoI4FwtZJSGjNqWa3NOuN/Xa22+7vfgtW0q/057yzXOedrEAVnO0OByeNqmFxzMPtpJo18suf/PNwv/bbxc6PRjCmHahErFoZ2X64mnXC4+XU14unWdc/p6rFR4v59gxz3q0RLt8rLH4/PbooV6PfE5yNUEmt/3MGfVEdOJt1dpoJPM3zysPGQnG8HilKdEChVy0a3na5d+1aaO+n5j9+4VrGgCWLtW3SUm0//STcC2yOjnO/dtx2WXuudqffVb55pw1y5yn3Wx4vHhMuzisX4twcEDfcMMNeOKJJzB58mR89NFHWLNmjeQvXMnuL/1xYqHy8vUEQRAEYSVejWn/+9//jvvvvx933nknjh07huuuuw4XXXQRli1bhmPHjmG6WixmHYZ5PMUcOOB+IQWURbtRT3u9ep5CS8xNN7nHi8pt8SV7vJZoN+tpNzL3uJyuXYE1azwTcaklomPfqU35ZsWYdjVYtIPcY6jtaZfStKlnPVrh8VpjjdXEPiB0NIhRK0Nu+5kz6iLPyJj2yEhtoduyJfDii9J57ZXK9DY8nnUKiMPjIyOB6GgeVVXmXLi1tcK5sUu4y7PHayWiUwutV7tXxGWwHANa00rK6xGX+dJLnh1L7Pzt3w+MGOHAkiUxrlB4Ofn50kR0avY6ncZC57XC443OBx8OnvaHLkxJsmDBAo/vOI4L2zncs7pkISE6AeVV5YiOiEaXRl2Q3T8bw7oo/GgRBEEQhEV45WnftWsXLr30UgDAJ598gm7dumHz5s1YtmwZlhpxx9RBmMdTzqxZ7s9KYseoaNcLlxe/rMpfXMUC2sg87UbD4+Wedm/GtOvBBKvcFvGYdnEiOratN552I+HxeqKA5z1DpuWiTln0Cidh5EhhyUh4vNOpPdZYS7T74mk38q6uJuz1vKDJycqCXV6mt552FgYtzh4PAHFxBtWaiNpaYdo6u5BnjzfjaWf76nnaWTli4ayFkmhXWhav5zgeCxbEuzzxcjp1kobHq92D8s5HPRuVwuOLirT3ZYSDp93pdKr+hatgB4Blvy5DeZXQ69mhQQdM7z+dBDtBEAThd7wS7dXV1Yi5EL+9YcMG3Hwhhrlz5844aucgTxtR83iKE2opvRwbDY/3VrSLw0m9yR6v9nIaEeHZ4aAUHr9vn3se5rVrtdugBBPtSp52pTHt7DtvxrT//LPwX8vTrjdMgeM85xmXC1+l912WC+HKK4X/RsPj5WONjYh9wFO0qwk3eYfD2bPGxqV7O6ZdKQGdUpneetrZfSUOjweAevXMi3an0/MY610f/kLJY26VaGc5BnwR7VrwPIeCgkg89JDyTtnZ0vB4NVFu5LoUb6fkaT950lgZ4eBpJzzJ2ZODOz69w7W8+/huDP9kOHL25GjsRRAEQRC+45Vov+iii/DGG2/gu+++w/r16zF48GAAwJEjR9CwYUNLDQwV1DyeYgE3e7Y0XB4AvvpKuTxfPO1iO8QvuUbnaRd75r31tLMy/vMft/Az+kIsRku0u8PjeUs87cuXC+fHW087CwHOzJSuN+Jp79xZ+K80T7uWaM/Kkobjt2wpZATX2g8w72ln51YrPF6M2jZ6DjqtObvVvOvyuth2SsKKtUMcHg94J9rFU76xzgC7HJBK2eO1jhGz+5tvhN8uNcQ5BsxEWBgV0EIdPNq1q0H//sKyuEPwmmuEyAsznnY95OHxERHmE9GFg6cdAL755hvcdNNNaN++Pdq3b4+bb74Z3333nd1m2cbsb2eDg/vHWTzdG0EQBEH4E69E+3PPPYfFixdjwIABGDVqFHpcyHi1Zs0aV9h8uKGWXfnQIffnI0fc2ZgB4f8jjyiXJ85CD3jvaRcLVaOednF4vLdj2s1keGb7Ke3DhKfZMe1qol0vvF2c9IphdEx748bCOZWLICNj2lkdSvO060359re/udc9/zzQoIHw2UrRnpIi/DcaHu+tp10pAZ3Svt6Gx7NrzarweFZOo0amd7cUvezx8mPE8jeUl3tGgohp3Vq4pocNMyZU2Xkx62kfMKDSdZ80bgw8+6zwuUUL4b8RTzur25t52s0mIwwHT/uHH36IzMxMxMXFYcKECZgwYQLq1auHgQMH4t///rfd5tlC/sl8mu6NIAiCsAWvEtENGDAAJ06cQFlZGVLY2zyA+++/H3HepmIOcbKyhDmHH3rIPS4yLk7IIC9OwMSSOmVleWb+FmNleLxYhGuNe1XKHm/G067m7dciLk4Yx3zkCNChgzDHuFjkqnnai4uFafMAYOFCTpIxX9zOiAjpy7yeXUpjd42K9okTBXHD7GIYCY8XJ9qS16PlaVcqn5VlZSK6Bg2EucJ98bTrCbkrr1Qfzw6YD49XShDH5lW3IjxeLtr/+st0EZahJNrVwuM5TvhdMsJLLwlJLgHvw+PZPch+6yIjpWVxHI/XXotHs2bCzvIpHMV1W+lp92XKt3DwtD/zzDOYN28eHnvsMde6CRMmYMGCBZg9ezb+/ve/22idPXRq2Am/Fv8qWUfTvREEQRCBwCtP+7lz51BZWekS7IcOHcLChQuRn5+PtLQ0Sw0MJbKygClT3Mvnzyu/SLNxu1qZv61KRKc3pl0scP2RPV6P2lp3HStXegpetUR0e/YApaXC56NHhSnhGHLRLrbJiF0bN0qXN20SpqyqVw84fVp9P1b2+fPS9UbC4+Wi3Wh4vLx8cUeLGdGuJnis9LRrdQABwpR54vnutfb31tPOjjPLX+CraGfl2T0qqLbWMzxeTbRHRxv3hKtFN+htLy6f7ce85k6n9PrmeQ4cx+OddziXfeKORnEZWvO0m01EpzTlm1HCwdP+xx9/4CbWYyPi5ptvxoEDB2ywyH6mXT1NskzTvREEQRCBwivRPnToULz//vsAgJKSEvTt2xcvvPACbrnlFrz++uuWGhhqJCdLP8tfIFlSJ0A787fY0x4VpZ/gyoinXW2edvl+bPtNm4Ddu5Xr+/xz8+HxSuvE3srISM9QcDVP+4USXW0Qly1OyiW3Se+FvrISeOop6bqZMwVBef68toeNHT+559uIp118DMRlAfrh8WLRPnkysHWr8PmXX9RtlSd8MxoebzQRndI2avuxNpeWSue7lwt3K8LjGSwpIscJ9WzfrnKQNdizx33st20zvbvXKM04UVNjPDxe7XpSQryfr4noWGeWctI8DoWFwmctT7vWPO1GQ/OtCI8PB097ixYtsFHegwkh+WwL1gMTZmR1ycJNHYWOjAguAhnpGci5LYeyxxMEQRB+xyvRvn37dlx11VUAgJUrVyI9PR2HDh3C+++/j5dfftlSA0MN0WgB9O3rDokHpEmdAPVx8IDUsx4Vpf8iqhaa7s2Y9u3bhf9yb6yY+fONhccPHOhe16qVZzk1NdLx3OZEu7QdDDOedrk3Wny+xG0x4plUE+1mPO1KY9rNeNoPH3bbysYFK8GEPcNIeDzgm6ddTbTLBZB4GIlamd5mj2cUFwv/z50T5gmvqDA3Rzsg7VRgUR+BQEm0Kw19UevYMJPhXlyGr6JdnNTQ8x7j0ayZ8DkmxjtP+1VXCZEaP/2kbaPSPO1mw+Ofeko7KqQuMGnSJEyYMAEPPvggPvjgA3zwwQd44IEH8Oijj2Ly5Ml2m2cbjeMbAwBmDJiB3AdySbATBEEQAcEr0X727FkkXJig+H//+x+ysrLgcDhw2WWX4ZA481oYIva0d+0qjHPPyBBEeEaGO6kTIITTXwhY8EAs2qOj9b2bn33m/qzmaV+8WCqiAeV52tes0a4LAH7/3Vh4fNOm7nVjxiiXxTxwkZGeZRoV7XJPu/iFXLyNkbH2RueYliMX7cx7ZyYRnVJ4vDy/gbwctURiZpIBGvW019YaGw+tdL2aSU4nHkaitL8ZT7vScUhNFf6XlgqCETAv2u1CyVNeU8N5nEOtY2SULVvcQ0PEQ1DU0Moez+7z+vXl0xTy4HkOw4cLK6OjpUN0AGOe9t27hTpYkj09G8Vj2s162v/8UzsqpC7w4IMPYvny5cjLy8Ojjz6KRx99FLt27cLHH3+Mf/zjH3abZxtllWUAgIToBJstIQiCIMIJr0R7+/btsXr1ahw+fBhffvklrr/+egBAcXExEhMTLTUw1BB72mNiBGGemysIndxcz0Rbw4crl2PW0/700+7PctH+xx/C5+JiTwGp5Gk/ckS7LkAI7dea8o2VJfZ2LlumXJb34fH8hbp4iYfcjKe9dWtlz7rWshryMe3sVpCLaiVBoxUeb8bTLsZMBm81UcfOmXhaOa0IDLltRupQEqHiYSRK+5sR7UrRE9dc495GPEQkFFDytOvNty4+XmY6cxYscA8NKSjQ396Ipz0uTujMZL+VjRsDb799Gj17Cst6iejM2K9lo/g3IjJSOweEGuzamj07tK4howwbNgzff/89Tp48iZMnT+L777/H0KFD7TbLVsqrhB/AhBgS7QRBEETg8Eq0T58+HZMnT0br1q1x6aWXol+/fgAEr/vFF19sqYGhhtjTruYhFaM2vlTuadcTYGKvpFy0y0Ohxcjnac/JMRb+/K9/CS+ramPplUT74cPaZSqFxzOBIk9E16qV2zvWqpVgNxPoWqJd/sL/8MNyr5/3nnZWFxMnTLQb8bSLow2YrQy1a0QrSzpgPLIAUG/jqVPCfxZODgBlZfrlmfG0K02XJh5GorS/mfD48ePd0S7svurQQfgfFcU87cGJkpBUuh6UsseLEUdHmBG94vvB6H2glDtDXmZWFnDLLcLy//0fjxtvrHTdN3qJ6IwmudSyT1w2+93zdpw6zwtJResKp0+fxiuvvIIyhRu9tLRU9btwobzygmgnTztBEAQRQLx6/bn11ltRWFiIX375BV9++aVr/cCBA/Hiiy9aZlwoIva0GwlJVfKaAZ6J6ORTNskReyXlQlor47nc0z5zpr7NgPuFW2zL7NnuMFFmg1i0K41pF6PkaWdCWO5pT0wEOncWPi9axGPYMGlIrZJol3cyAMD117vHfnOcIO7kwzUffVTbboY8PF5NtCtdF2fPCv9Z+41kj9+3TztsmeeNew/NeOXlc7wrYcbTzsbLixEPI1Eq04ynvV8/d7QLu2aYQGvUiHnag1O4K3X8eeNpZ9cXYM2wCS2UEs2JYfeJuJMNcN83Yk/7+vXCNc7uSa3weDP2if8fOiREPHk7hEApKiSUWbRoEb799lvFqLmkpCR89913eOWVV2ywLDhgnvbEmPCOKiQIgiACi9evP40bN8bFF1+MI0eO4M8//wQAXHrppejM3orDlPh492fxi7IaHKecGErL064U7iv2Soq/i4iQdiTIkXva1TxGkZFSmyIiPL3yf/3lHt8p97RHRgoeTy3MiHbxdHTy5G1mPO0OBzBokPC5SRNB3PXuLd2mVy9tuxnsODLxcSHtg6Hs8SxE20x4fGWl4KFnwx/kPPecf0S7kfB4M9njlYSp0nztauHxep528TXFjiu7dhITgRUrnGjY0Lxi69HD9C6mMe5p95zyTYx4nLeRSBqGN6HoRkU7+8/sYecrJsY99WNZmXCNX3jE4ORJ68LjWb07dnhfJotEmDYtODt9vGHVqlV44IEHVL//xz/+gZUrVwbQouDC5Wmn8HiCIAgigHgl2p1OJ2bNmoWkpCS0atUKrVq1QnJyMmbPng2nt+6KOsLq1e7P77xjLEGR0ku41pj2VauAdu3cy5GRUpEjD4+//HL1up1OTuJpV5uGrn176bLD4emVF2f9ZmUwL3NkJHDDDVK75CiFx2uJdrVx4FpTvsm9dA6HWzQycS0Pky0p8bRVCbaffEy7kfB4hpnweIaaQMrMlLY/IUF/jmsjPPaY/jZm5mkXX+uMnBx3AjSWodtbT7v4+LHjwb5zOIRQ7dGjDWTXk8E6ZZSyoVuFGU+7llAWi3Z2fRrBDk97dLR7Sj65HQUF+p52ccepEvLw+NJS79oJeCYXrQsUFBSgAxs/okCHDh1QYCTBQR3FNaadwuMJgiCIAOKVaH/yySexaNEizJ07Fzt27MCOHTvw7LPP4pVXXsG0adOstjFkyMmRJpY7edJYZmGll3Ct8Hh51nn5/nLR3rGjet1yTzubhk4uQh55RPpiq+aVZ1m/5eHxkZHAhg3u7Ro39txXabyqmmivrfXMuK7kaZcPFVDytDPRyESDfKow8XhuLeTZ3M0komMoCXS1IRR6yI9nx47q4sSMaGFeTy189bQPH+5OgMYydO/c6f7eStEuXm8GFkmjJ5h9QenYsPnMxdTUGPe0q802oMSDD7o/a0XsiFGafk6Mp6edk9gVEwMcO6a875kz+h0kF1KsaNon/i/OQ2IWpeSioU5ERASOaGQjPXLkCBy+jlEIYVzZ48nTThAEQQQQr5687733HpYsWYIHH3wQGRkZyMjIwEMPPYS33noLS5cutdjE0GHmTOXM4/L5puXoedp37gR++036vdL0akrLel5A+Zj2rCxPTz4A3HijZ8I2pc4ANr5THh7vdAIPPeTeTumdUEmcWhke762nvajI0y4l5KKdeWK98bSLRY+3oj0iQtr+5s0BtaGoaqLTSDJFJcx42pXqkCdA4zhg40blstSmOtMS7ewcs+s0IsK86hbnIfCXp10pPF5p/nk977beNGhqiIcAiCNltNCzhR0r+bRuVVXCFzExyp16gHBPWT2m/dJLfSuvrnHxxRdjtThkTMann34atglna5w1OF8jhKqQp50gCIIIJF69/pw6dUpx7Hrnzp1xiqWbDkP27VPOPC6fb1qOkmj/9FNpGfK5sdWytit9pyUolOZpz8oCPvlEup2ScJRn92ZCKzvbU7RXVkrtkB8npenYxDbJs8frhcebGdPORGN1tbDfzz9Lt2Hja/Vg9rHwYzXRruWFtFK0yz3tDoc7gaAcNZGVluZd3Vqedvn1riTale6jEyfcy8HgaWf3ZGpqYD3tStTUGE9EZwa1IQl6+5gJj5d3dkVHA2qzil10kX4HidpsCgxmG6u3Y0f9JJnhxPjx4/HCCy9g0aJFqBWd9NraWrzyyit48cUX8fDDD9tooX2w8ewAedoJgiCIwOKVaO/RowcWLVrksX7RokXIyMjw2ahQRWk8uJHMwkqi7IsvtPfR8rTLE9Hpeabk87QDnh4+JVGTlSXN/N2hg3t8pzw8Xu9FXk2YWp2ITsvTDgidFW+9Jd1GLuLVYPbohccb8bSLt7HK0x4R4Z4mT46a4GNJ58x6krWyx0dFSc+DmqddvtywoXL5dofHN2okRKf4w9tuNJGgcH+pG+Ctp10cdWJUtJtNRCefujAmBrjkEuk+9eoJ/1u10v890+ugUJqnfcEC4bO/IiZCieHDh+Pxxx/HhAkT0KBBA1x88cW4+OKL0aBBAzz66KOYOHEibr31VrvNtAU2nj06IhrREQZvToIgCIKwAK/kwLx58zBkyBBs2LDBNUf7li1bcPjwYXz++eeWGhhKZGcLY2+Zx1nsedZCL9GYEkY97Xrh8UqedsBTSEVGKr+Ix8e75/Jevx5o2VL4rJQ9Xku4V1UJobjyY6U1pt2sp11p3nKOk7b16aeV7TNCba3QafHXX8Lyq68K/8142tm14C9Pu5poVzsvbHo3s55krXnaHQ7BNnZclISpkqf96quBFSukZSlta0S0y8PjIyO9D4+PiRE6sBo1Ao4fd5drhffdqKf95EkH3nhD/XtvRbv42jU6j7kViejk92mrVsDevcJ1oyes9dqqNE87GxY0a5YwFMnbOdvrCs888wyGDh2KZcuWYf/+/eB5Hv3798ff//53XBrG4wmYp52meyMIgiACjVee9v79+2Pfvn0YNmwYSkpKUFJSgqysLPz222/44IMPrLYxZGAvfhkZwph0o5mFvRHt/hrTzjDiaQc8506X28Be+lNSpAnulGxiCceU6pXPQ22lp13c1v37Pe0yCrOf2XX0qPD/9Gn3NuLjrYRcyIjXmUXJ0x4To3zs1UQWa8tbb7nD/cUebzW0PO0REdJrXkmYfvih+3NqqnAfiRNae+tpl0eAyL2+ZmDh8cx+cdZycV4HXzCeU4DTTJi4fbt39ftDtMvHtMvD48XztDNYB4mRyCGjnnZxJxIg/H7n5gqzfhDCFK4vvfQS1q5di88//xwLFy4Ma8EOAP/Z9x8AwMmzJ9HjjR7I2WNgehiCIAiCsACvU/o0bdoUzzzzDFatWoVVq1bh6aefxunTp/H2229baV/IwV78zp0znlnYn552vTHt8uzxDKOedvELcoJoiJ/c056Q4NmhIbdLKWu9PJyZ4e2Ub0pj2jnOLdzbtPFso1G+/lp53L44zYOeB5LtLxal3ibeGjRImguBla/kbdfzCo8YAfTvL3zOytKvW2tMu8OhL9p793Z/HjdOuI/Uxlf74mlnx9abaAZWD7NffP1/+aVniLc3iDuU4uOFe0c8JEWK+o1uZOpJJcSi3Ux4vJHs8fIOKnF4vPw+ZdexFZ52eXi8/P4yOiSBMM+rr76K1q1bIzY2Fn379sXWrVsN7bd8+XJwHIdb1JJyBIC1f6zFk18/CQDgwSOvKA/DPxlOwp0gCIIICOE7b0sQ4Y1gMONp1xJ98nnaGUqedj3RLhfIgFRYyzs0lMpTSlAHKIeYezPlm9qxYsLLl/xKJ04ot8nouGDxvmbmTVdj717pdHWsrUqiXa+++vXd51cv0RegnT3eiGg/fNj9mXlg5WXKxZd8vb+zxzOUPO1Wzd0uvg+vuEK4dwKpW/Ly3J+tDo9X87RHR/vX0y4Pj5dHspBo9w8ff/wxJk6ciOzsbGzfvh09evTAoEGDUKwzp+bBgwcxefJkXHXVVQGyVJkXtr0ATtQxxoMHBw6zvtGZHoYgCIIgLIBEexCg5GlftUoY4x0bK/xv3lz6vZanXZ6IzipPuxJqcz4rzdMuRyns24yn3Zsp35Q87YB7ir0BA4BrrvG0ywgNGigfa/FxNSrajXo1tZALJ3YszHrao6OF88fOoRHRruVpj4iQXg/i6Q0Z99zj/symO5SXyY6RXYnoGEqiXZ5PwNeyAc/rPBB89537s79Eu3xMu92edjORT1Z0roULCxYswLhx4zB27Fh07doVb7zxBuLi4vCOxniE2tpajB49GjNnzkTbtm0DaK0nf5T+AR7SC5sHj/yTOtPDEARBEIQFeJniirASpZfErCxpGHLXrtLvxS+aakIU8P+YdjWUPO1yEhKAkhLpPmpCUy4UhenZOEnZ3o5pB6RztbPwY4fD3Ev55ZcDn33mud7pdCfZGzxYfX+xbf4QA1qedi2RVb++8F+tA0UJXz3tf/7p/rxunRDeLS+ztlYox5vweH+IdvFxNSIujSC2i7VDvVweWiHy3iAe2mGkswYwn4iuthZYuzYGX38tLM+eDdx2m2eZgDWdIWpj2hlmPO1OZ2A7UUKVqqoqbNu2DVOnTnWtczgcyMzMxJYtW1T3mzVrFtLS0nDvvffiO3EPkgqVlZWoFPUkl5WVAQCcTiecPvyoOp1OtE1qi72n9kqEOwcOnRp28qnsQOB0OsHzfNDbqUWot4Hst59Qb0Oo2w+EfhussN+XfU2J9iydwawlYgVGGMZIeLz8HBsNj1eb/5yh5mmX22T2xdSIaK9f3y3aOU4Y556dLe2sUBPt4mW5B3LUKKCgQPgsTgLncABffSUt57//Be68UyraL7znoX5995RnRmjXTkigdscdnt+xJHXiBGvyTgomjgH/iHZvPe1y0W5EvIlFN8NMIjo5s2YB8uhYa8Pj3duY7axhIo9NS8bKs0LMiQW6mqc9MpJHTQ2HiAhrIjTEJCcDJ08Kn9WiauSYTURXUAC8+WYKcEEM/fWXewo2OVYMO1DKHi+GPO3Wc+LECdTW1iI9PV2yPj09HXv37lXc5/vvv8fbb7+N3Nxcw/XMmTMHM2fO9Fh//PhxnD9/3pTNYpxOJx7o/AAe2fyIax0HDjx4TOgxQTfE326cTidKS0vB8zwcIdrLFOptIPvtJ9TbEOr2A6HfBivsLzcjLGSYEu1JSUm6348ZM8ZrY8IVpZdE5pllAlZtrLf8s3xZ7SWXCUY1T7sSZqawko9F1wuP79xZGOeuto1cjIgFRGSk4IllQlGcAV78PlhUBEyaJC1nzBhBlIpFO7ufzN5XNTVST7pYlLMke3Pnur/v1g3YtYt3za8tFu2+iC/5lIMMb8e0s7BvM+HxW7cK50TcAWMmEZ2c/HxhTLcYrfB4cbSFMU+7+0A1bw4UFurbxGD2i0W7VZ52MWqe9n79hDD22lr1Cr2dgq5HD3dHl1WiXe5p374d4Dj3faB07TKs9LRbMaa9Lov2oqIiTJ48GRs3bkRxcTF42QmptbqHSER5eTnuvPNOvPXWW2jUqJHh/aZOnYqJEye6lsvKytCiRQukpqYiUTy9iUmcTidGcCOw48wOLN25FA7OgW5p3TD96ukY1tlAtlmbcTqd4DgOqampIfmiDIR+G8h++wn1NoS6/UDot8EK+2OVxoQaxJRof/fdd72uiFBHSbQzz+yqVYLwUQsbB7wb0x4ZyULMlT3tSph56Zd72pXCj8XrxKJe/MKuZpP4ffG//wX+/nd9mwoKPMUAxwleXCVPu1nEc8cDynON//67e3nbNmDgQPe4YfF14IsYaNJECGvu1AkoLQUOHhTWW+VpNxIeDwjHVSza5fO0M4yIpE6dlMPjAeXweLGNZsPjzQh2wH3tiH+HrfK0i1HztBupx6xgj40Fzp8XriWG1aKd/S8thUuwM9T2t8LTbuWYdj/qVtu5++67UVhYiGnTpqFJkybgfDjwjRo1QkREBIqKiiTri4qK0LhxY4/tCwoKcPDgQdx0002udSykMDIyEvn5+WjXrp3HfjExMYhR6AV0OBw+vyByHIcujboAAO7IuAPv3fKeT+UFGo7jLDkOdhLqbSD77SfU2xDq9gOh3wZf7fel3TSmPQhQ8kIzbxMTPlZ72iMiBOFixtOuhdhLrFSWnqddLqxY+LKRscZz5nCGPIlnzigL6fx8oGdPYVnsaTdLba3bC83aL+8gaN/enVhNHiYuPka+iPZZs4B77xU+9+njFu1WjWk3OrY5X5afyZfw+Oxs4PPPpeu0PO1qop0dA3l4fGSk79nj7fK0f/ONxRUB6NUL2LxZeq7NiHat65cNiWHXU2IiUFrKS4S7Pz3trFyrxrTXVb7//nt899136Ml+HH0gOjoavXv3xsaNG13TtjmdTmzcuBHjx4/32L5z587IE09dAOCpp55CeXk5XnrpJbRo0cJnm7yhqla4IaIdNMUAQRAEEVhCs5ujjqHm2WGCEtAe066ViE5tTDvbX21Mu5o9ashFu+e4W3Ub5N/LOx204Dge+/YZ8yTWr+95rDhO8OJa5WkXzzUtF+w8Lw3P5zhpu8WfffHgicWj0rH0VrSbCY8HhOMqxkwiOrHXumtXYZ52o9nj5REPRuZpNyME5dekkmj3h6ediUnPyBrvOxzUYOdcfByt8rSzYSysHd27M0+7sJNWB5wVnSHyYUEUHq9MixYtPELifWHixIl466238N5772HPnj148MEHcebMGYwdOxYAMGbMGFeiutjYWHTr1k3yl5ycjISEBHTr1g3RNs3L5xLtESTaCYIgiMBCoj0IUBPtTFAC2p52b7LHsxdVtXnajZCT4/58+rR02aynXfy9eL2eaI+KEo6REds7dVL2tGdnu4XXuXPee9pratyCtn59YWhDaqqw3LChcHzYmHeHQ7BZzdPui2gXi3KlYRRmx7R762nPzlauQx4eryTaW7Z0f05IEP57Gx6vdG3Jw+ONJINUKg9QDo9n59dXlBLRycuVh5ZbAbtGzHjamX033aR9/bLp29ixb9YMWLLktOs4tm0LiJKMS7CqM0Qs2ik8XpmFCxfiiSeewEEWquMjI0eOxPz58zF9+nT07NkTubm5WLdunSs5XWFhIY4ePWpJXf6CifaYSAPhQQRBEARhISTagwD5eG72nwlKQHtMu5ag1xPtZjztYnJyhDH3jOpqYZkJdyOiXbxOyRsq/6xERASPadN4Vc9c797uz82bA598Iv1+xQrBi8sEw+nT7pf5557TrluO2MMbHS2dtu/UKWDGDGH8vWC38F/cbqvGtIudUFZ62s2Mae/WTTiuYsSeTfH1oSTaxXNtM7GoJtqVwuPFCRDlOR7EbVCb8k1LcKuJdrGnXVy2VTAbA+lpNyPa2TET521Qgl1/7o5DYMiQSrRqJSy/+64wfaISVg070BLt5GkXGDlyJDZt2oR27dohISEBDRo0kPx5w/jx43Ho0CFUVlbip59+Qt++fV3fbdq0CUuXLlXdd+nSpVi9erVX9VpFZa1wE5CnnSAIggg0NKY9CBCLtQ4dhERYnToJgp0JH/nLoZYgMJqIDgAKCyNcL+Zffw1ccokxm2fOVE/qlpXlaZ+ZRHRmwuOjooT6Vq0SplpjXjxG8+ZCwjdm34gR0u/Z8WVe0hMn3Ns+8AAwZYp2/WLE4fFRUUIHxuLFwrLTKSQXvP9+aRv94WkfPx6YP184LkY97Vqi/b//FdpiJjxe6Z1eHB4vrk8pkaZYtLOZmtTC47U87XKvqfqUb+5CLr5YKGPPHuW2ystkIk88U0GPHtaPaRd36IkJFk87O6Z6EdWtWwv/2fXIzqM4j4Xa75tVnnanU31MO035JrBw4UK7TQg6KDyeIAiCsAsS7UGA+CVxxQphvnI5YhHTowfw+OPuZb0kdUovuUzUCC/lwkv/lClCojTmHdaar1ppHLl4DL4v4fFaSfbUysjKEsbGbt2qXodSWWwd85YePy78T0gQEmSZQRweHx3t2bEhnspKydNuVSK6gwfdMw9Y4Wk/eVIo7+abhWUjol3JfrUxxP7wtK9dK3w+d046faIRT3uTJsL+334L9O/vaZtc1MXECJ0ab73lXpeX590Ua1qojb+fO9eJJ56w1q2v5GnX60gyes2yISNiT7u4fC1vuvy79HSguNj8sRYny6Mx7crcdddddpsQdLjC4yMoPJ4gCIIILBQeHwSojedm5OQIwomRlyd4ldUwEh5fUcE+STM2z5qlbQujY0f1pG7ssxiz2eON2CCUy4s+a9fBjovYs8vslIv2xETpGH0jiD3t0dHqHRtiW3wV7UrnVjzzgBVj2lk9P/4ofDYi2pUEnjgcWXxclESSOAT/8GEh9HzdOuU65Lbv2wf83/+5l9n0iTk5xsa0s2Oq1mGkFB7POmgYVgl2ccZ8Zo/8nA8aZE1dYpQ87XoYzQsg73yQe9q1MsTLv3voIWGeerNYFR5fl8e0A8Jc7KtWrcLTTz+Np59+Gp9++qlf52cPdig8niAIgrALEu1BgNKUVGJmzpQuM1GmhjxJndK27AVZXq54mi4twZydLbVDPgbfl+zxWqJd7uVUE/sMpYR98rHHgFu0s/B4npeO2TeCeEx7VJR6x4bYVrH9W7YIXuGcHONiQE0csnOp5GmXT8WmVY74e9ZxxNqoJdKUOgG+/Vb4v3On8Ce3S42aGiFEvrRUul4tPP6nnzwFNOvEUJvyzeFwF6KXUV7J0250BgOzsOnRAPXweDPh3EYxO1MAACQlGdtOHt3ArhWxaFf7fZN3QnKcd+HyYk87hccrs3//fnTp0gVjxoxBTk4OcnJycMcdd+Ciiy5CQUGB3ebZAoXHEwRBEHZBoj0I0BOe+/Z5rhMLBL3M8kovwEreJLGnXM0WBhtHnpEheK4zMgSxycaIWxUeryfaxWOR9cbNs3K1RPsffwj///rLcxs95J521rHBEIfKM1sOH3Z/z/Nur7CRZG9iu+Wwcylvf04O8OabntsXFmrXw3FAo0bCZ3GSNzksrFre6ZCTAzzzjPCZ54GzZ6V2eYOap72kRH3ohpHweDVxzFDytCt10FiNWmeC/J5QO55mjjPb1oxoN9p+PU+71rh1uaddbfiPHqtXAxs3Cp+ffloaVWPG0y6OhKhrTJgwAe3atcPhw4exfft2bN++HYWFhWjTpg0mTJhgt3m2QKKdIAiCsAsS7UGAXni8lsdWCSOeqIYNPdeJPeVqtojJygJyc4Vxw7m50mzhcvv0BLXR8Hj5C7VaeLnS/swmpfBwJn69EesM+Zj2rCwhRwGja1eA5XZidv3yi7QM5hU2KtpTUjzXiaMe5B0g8jBuRl6eeh2svGuuEZbFyfbkJCcL/+VCWq1ewHrRnpSkPnRDbZ52X8PjlSJPrEYtPH7oUOkKtfv2vvuM12V2ej8AKCtT/y4+3v1ZLtqVxrRrJaKT/77p/U4pMXq0296//pLOfPHZZ8bLeeAB88NoQoVvvvkG8+bNk2SKb9iwIebOnYtvvvnGRsvsg6Z8IwiCIOwiaET73LlzwXEcHn30UUPbL1++HBzH4ZZbbvGrXYFALzxeLRSd4Y2nXSmUdeFCqfD25mVYyQbA+/B4Pa+i3vh3s552X5B72gHg1lvdbXM63QkE2Xbi8GeGeBo+JcRj8o8d8/y+ZUt31IO8/Wph3FqCq1kzobzu3aW2K51Tdl3JPe1a4eNqAk1P+KqFx/furRzhkJ2tnj1eHB6vJ7yVwuOVIk+MzsRgFGaPPPJGPtxB7b6NijLeQcK2M9p5pLet+PdGPkTETHi8XNB7Gx6vNnxCPpWlkXLEeUDqEjExMSgvL/dYX1FRgWgz4Qh1CBrTThAEQdhFUIj2n3/+GYsXL0aGUtp0BQ4ePIjJkyfjqquu8rNlgUEvPF4tFF0NI6JdqZ7rr9ffxij+SkTnOabdeHi8EU+7GkY8p/Ix7Qx2PvbudQvesjLhHCpNjaY3R7h8Wjv5vsnJ7s4XuafdmzDuZ56RdgCIPaJy1DztWvWqiS6lKAIxt90mHEN5Xa1aAU88IXzmOOnQDX8logM8I0+aN9e23wjiY8bs+f576TbyKd/Ucg1ERhq/p70Jj9fqaBKLdjVPu5FEdDt2eB4Tb0S72vAJrYgQtXKUckTUBf72t7/h/vvvx08//QSe58HzPH788Uc88MADuJlNJRFmVNcKPxwk2gmCIIhAY7tor6iowOjRo/HWW28hRe8tHUI229GjR2PmzJlo27ZtACz0P2rjucVohaJ742lXerE3EtJuFKvGtMvt1/K0G80eb1a0c5wwDZgeSp52QH3+6tGjhSn25HVpiR89gaKVTNDh8Bxnz9BKqMXaoteBAqh72tXqBdRFUrNm6jYBQEGB4BX99VfpeqdT8LYDwFVXSe8XeRuUxrTrJaKTX2dqTkd5GLdZWIeD3C7xTBJKaHnajd7T3oTHayG+Hr79VprJ34ynfeFC4OhR97IVnna23KmT+YSC8jwgdYmXX34Z7dq1Q79+/RAbG4vY2FhcccUVaN++PV566SW7zbMFmvKNIAiCsAvbRfvDDz+MIUOGIDMz09D2s2bNQlpaGu69915D21dWVqKsrEzyBwBOp9OSP57nfS4jMtKtmDjO+H5ueNl66Xcc56nIxAnc3EjLF4cMS+vTP35SG4T65NuIyxd/L69XbKvYsw4IU74p7ec+nrzks9PpRGystHyn04k9ezyPEdt3xQonJk/WTxP90088HnhA2Ke4WNxeZRVw/jyPLVvc6iEykkf37jxWrvQ81vI2uJGWzXE8OnVy1y1uv8PhxC23OPHaa+ZSXkdEsOMr3U883R4jIYG/YLP0fN9yixP33ee8YAePuDjxvsr2JCZqqychrJnHxo3S7WpreZw9K5QZHc3Lrjl5XbzCev7Cva1sl/wajIpSvgfEx175ftNmxQontm8X2yCU27ChdllqdUVE8Ir3iBLsN6OqSn376Gge8utPDXFHUnk5j+HDga1bhTpqagCe513CXqhb+dhzHI/du8X3tPJ9r4cgzHlXmTwPTJvmRMeOvOS8qewtKWfaNOueBcFEcnIyPvvsM+zbtw8rV67EypUrkZ+fj08//RRJRqcKqGNQIjqCIAjCLgzOrOsfli9fju3bt+Pnn382tP3333+Pt99+G7m5uYbrmDNnDmbK50wDcPz4cZw/f95wOUo4nU6UlpaC53k4vM2mBaCyMg5AIgDg9OkTiIgw+vLWGABQU+NEcfFxUXnu7yorz6GiohqA9CWL56sBSF88Tp06ieJit0uM41IBCO6w4uJiV5nuZXXKymIAuCMnqqrOorhYOj6ypiYZgDBAu7ra/T3PNwK7NIuLixERkS4ag1wL8WXLcTUoLi6Bw+GQlCeuFxBSmldWnkNxcRkcDvd2xcXFWLs2BkuWeEZ5NGtWi5kzy3HFFZXYs8d9jtQQMqILInzrVg7vvluCIUMqERmZrjjFnrAt79rnzTdLcMMNlRe+kx/rxhfaKz8X3AXR4f4/YcJpFBcL5dTUJAEQBvGfOVOB4uKz6N+fA5Cu2RZpu0pRXFyJc+ekx8DhkJ4LAIiMPAcgDlVVtSguPiH5rnlzYf+hQ8/j4MEI7NghXH+nT58EkOpRb2RkFQBtjxbPczh+XCqyzpw5j+PHqwAkweGoRHFxieu7c+fqA0hwLa9cCeTl8cjKcl/3VVXnUVxcipKSSACNFOqU3jtnzpxCcbHnCa6qch97s572yy+vxBVXnIZwmwnn+uzZMyguPoPLLkvCmjXuxAzsvDOEDghPl3pV1Rk4HHFg15sWZ85UAEjU9LQLwtdow9zXObtmP/nECcCBysoqnDpVAp4XwllOnz5+4dh7ZsvkeQ7l5e7zfeZMBWpqoiG/7/V48cUSTJ2aiPPnOTRvXosZM4T7fMKEGNx3X4rHMRUTESF0DAEcZs4swxVXnEVxse/PAqXx48FA+/bt0b59e9TW1iIvLw+nT582FBVXF6msoTHtBEEQhD3YJtoPHz6MRx55BOvXr0dsrP4LV3l5Oe6880689dZbaNTI80VajalTp2LixImu5bKyMrRo0QKpqalITNQWYXoI3jQOqampPol2sdMiLa0RTDQPABAR4UBaWpprWZwQql69ekhI8Dy+sbGesc2pqQ0hKgZRUe6XVnH5Ssty5O90CQlxSEuTZoCLi3OXn5jo/j4mRlqv+NDGxkZIXqhjYiIubONA/fqeL9nx8e5Y+Li4ekhLi0VKirT8l1/mFF7SeTRoEIG77066YJ9mcy8g3f/ll5MxdiyPhg2BoiL9fTp3ToLSYRUf64gI6XLv3jyqq4F9+3h07AhMn+7EsGHuC6pePXf5SUnxSEuLd407N0pqqmCXfL+YGE9h2KgRE6kRHtcICyNPSoqVhNanpipMZQAgJUX/xZjjeKSmShPyRUfHIubCeIfExBiJHfLz6HRy2Ls3Es884x7/EBsbi7S0GMUkfwAQFye9dx54oCGefppHVpZ0O/GxN/vz0KlTtMfxS0ioj7S0+ujVC1izhq3l0a2bNPt/VJRyZcnJcYiM1BfZkZE8kpOFdO+1terbt2gBHDigLm6lSLfheQ5FRcL143BEIz4+2fVdkyapigkaAeF8Jya6EzgmJsYjNtb82IMnnkhydaQsXuzAoEHCPTN2LJCU5MTs2Rx27+ZRU+NZ9qBBwtj6o0eBm24S7ikrngVGnoOB5NFHH0X37t1x7733ora2Fv3798fmzZsRFxeH//73vxgwYIDdJgYc8rQTBEEQdmFbePy2bdtQXFyMXr16ITIyEpGRkfjmm2/w8ssvIzIyErWyQbEFBQU4ePAgbrrpJtf277//PtasWYPIyEgUFBQo1hMTE4PExETJHwA4HA5L/jiO87mMiAj3aYiKMr6fG6kNkZHu7xwOTlI+IyLC82U0IkJul1h0SMsw0yahXZ7HSSwgxN+Xl7vXX3yxQyIKIiI4OBzi/aBYHkO8zuEQ6hB3FjgcDuzbxykIDw779nEqx9sI7v3FnQSeuL2GzZop1yVeZtcbo0ULDjt3cjh3Tvg/fLj6MY6MFNbFxpprS0yM53UFSDt1GMuXC+tqaz3Pd1WVsL8gsqR2KREfry3GhPH/HAYM8BSElZVCmfXqqd8b4u2loeyc6rYAcOqUtL59+ziMGOHA6tXy+0B67ZlBfD+47fK8t2JjOWzbJh8yolxXVJRD8b6XEx2t/Jsh5557uAvHTndTDzgOaN5c2JHnpZ0D0dGevx8MnufQvbv0/jXSESGnspLD+fMsKkZ63m691YGdOzns2KFcbocO7t8gnrf2WRBMrFy5Ej169AAA/Oc//8Eff/yBvXv34rHHHsOTTz5ps3X2UOWkKd8IgiAIe7DtLWHgwIHIy8tDbm6u669Pnz4YPXo0cnNzESHLmNS5c2eP7W+++WZcc801yM3NRYsWLWxqie9oTXFmBL1EdEplKiWkkm8nzlJ+4d3NMN5mj8/JAQoL3evz8gDxKAaHLFu03pRvH3wg3RfwTESnltlcnGDKm/PC9teeHcld8d/+pj/ns9wOtUzhStt7qwnYuZHXpVQ3GzVRUeH5XeWFyH950j81u+rX17arTRvheMkTgX3+uTt7/JEj0u/UErGJO230pnz74w/5vspTf/ly7NmxFV8PL70kLIvtiojwLNvXRHTR0ca2u/Za6awWZhzFPA+MGiV8djqFiAeGUpsY06cLUxoyvE1EJ+bDD5XXa812IE+iVxc5ceIEGjcWhmZ8/vnnuO2229CxY0fcc889yBOHdoQRFB5PEARB2IVtoj0hIQHdunWT/NWvXx8NGzZEt27dAABjxozB1KlTAQihg/Ltk5OTXeWE8ryx8pdwK8tTWlarR7xdTo40S7PZdzQj4lIp87s8/YC8Q0L+Qi9OhqZUxwnRsGq1Kd/UMptnZ3vuawa2v9FLc9cuIRu6XLiLO0zMina9Tg1Av21mssczlMKbxaJdfLzVRNeqVdp2vfqqkBVefu5KS92ZyDdulB5P9WPgOU+7ml1nzniuU5r6S2m6NqNERnrOGX70qLC8e7d7XUQEm2FB+z5g642KdiP2OhzSWS0uukh5O44DHn/cvZycLLTtyiuF5dpaSHI+aGWPHzDAszPEV9Eu7iQUo1auuM66LNrT09Oxe/du1NbWYt26dbjuuusAAGfPnvXoVA8XKDyeIAiCsIvgiseTUVhYiKNi5VhHUfMcG0VvijCjol1sh5541sPbKd/27dMuNyJCfZo3vWPH2if2lDJB/K9/SbcdNkw6rZ5ZYTB0qHt/JdHuPj7STNQcB4hSMACQdpiYnZbPiLdX7LlUgolzM6K9pkY4tvXqCf9zcqSi/dQp97ZDhiiXceKE8nrGd98J//WEk9gDrtT5JM9nwK51teOVkOC5TmnqL1897UpzhnMc8NVX7mV2Toz8hhj1tMfEGLNXbfo8OXFxwjhwxg03CPeG2FstFu1annbWScHgON87Olu3Vl6vZoPYu1+XRfvYsWNx2223oVu3buA4zjXDy08//YTOnTvbbJ090JRvBEEQhF0ElWjftGkTFi5cKFleunSp6vZLly7F6tWr/W6Xv/E1PF4LtfBRvXna9cSzkXrFKL1YK4XHq4Wqi/dR87QbEbA5OcDy5e51eXmC91K+r9xraNbTLt5fLNoTEoQw4owM1mb5eGxPz5+WV9oKT/vLL2uXwew3Eh4vhg1tYMd4715h/f79whzrDLmH2ij//rfwX084sfJzcoAlSzy/b9kSeOWVEtcyK0/tnF8IBHIhjK2XRmbI9zd7X0dFKc8ZzvPSzgx2To2cZ6vD4+VtUmtjvXrSZJtsO/a/ttY9pp15sdWOfWSk9Z72Bx9UXm/E0y5LvVKnmDFjBt5++23cf//9+OGHH1zJHSMiIvAEG38SZpCnnSAIgrCLoBLt4Yo/Pe1C6Kznej1Pu5541sPb8HgWqq42rthTtGvXIYbjPL2XrC4mANXKMnssxEJd/Pm664RQ4txcoEsXaVizkXpYxwNjzRrtcfBGvL164ftGPO2sHfJjy/5zHLB9u7C8aZO0HLNRHIy//pLur3TsxB5wNc91UhIweHClax0T7WrHq00b6f4ZGcI5EEdmyPf3xtOudA9yHJAqmh3PjKddLnjVEJI76m9n1NNer540a79ctDudbvGr1B4x8tB5s2Pala71wYOVt9US7XV9THt1dTUGDhyIjIwMPPbYY2jevLnru7vuugtDhw610Tp74HkelbU0pp0gCIKwBxLtQYAVycK0UBIzep52PfFstk6joj0rS5rcKiMDaNhQuo+aaNcbp+9wqHsvDx/WtlftvCQlKQsBsaAVfy9OwiYcY04ieHle8PyqHe+qKuk459OnlcfBM9Q8sGqdCkqoiXbxMWrSRDhfHTsql8HzwlhzADh+XLs+ozRtKvxnwkme4I7Vyzzgaud+3z4gIsL9hZ6nXdzunj2FDhi5YJfvb/a+5jjle5DnhY4fhlvk6o9pN+NpNzqmXWuZERenPGWiWPgyTzuzXe3Yy+9/sYA2gtKQDrVhHmo2hEN4fFRUFH799Ve7zQgqapzuMRwk2gmCIIhAQ6I9CPBVtPvD064kns3gbfZ4VjdLbpWbKx1DLH9pj4pSDo+PihLsFk8qwHHq3kv5uG6jnvYhQ4AffvBcryaKxcIyKwtYscKJLl1qEBvLuzy2Cxaod5icOaNsvzxzOUPt2oqPd3/WGpsutl9+TMT7PfEEj3PnxPOHe9rI6kxP9y2Kg8E6L9j1X6+e5zb33ecW1GrRI+np0muHeX3V7kVxu5XEKEM+i4Me4mvj/HnlezAnRzkxoVpHlhgzieiMbCffRm0feXg8S+QnDjFnY9qZ7f7ytCttq3b9h3t4/B133IG3337bbjOChmpnteszTflGEARBBBqdgGIiEPhzel61MZ9yzzLgKSyysoQ/te/16hWjJCSMhrbLvcVq3mPx55YthbHTy5YBd9zhtik7WxB7zGvJ/o8bB0yZom6P1gu8ku1GRDsgHN8rrzyJtLQ0iOfyXrVKEOL5+UJ4986dwnpxwi6GUuZyhtrxiY93J4OzwtOuJB4Z7Bi3awfs2CGI6EWLPM+BUaKjhYiD3r2FZebtVBJfl17q/szOvZxDhzj873/uE2PG066UlI5hdlaI2Fh3sj423aL8HgSAF1/0LNfKMe27dwPbtulvZ9TTvnMn0Leve7m8XGqnOBGdWU+7XaK9rofHA0BNTQ3eeecdbNiwAb1790Z92RyMCxYssMkye2Ch8QB52gmCIIjAQ572IMBX0e6Np33rVs91n3/umx3yesWY8bTLkY/XNTLlGytb7pVT816KQ46V7NUSEUpCSC083uhc1vJoA7FdSp52eeZyhhFPuxVj2lnZSseCHePkZGH5iiuk56BrV/W6lY57ly7Cf+blZMJJqW7x8c7KAlq1UqqDx4svug+I3ph2cbvFx1GO2QgacVuZaNcr1x/Z48+eBUT5QFUxOqad56VZ+ysqpNvX1rrnaTc7pt1sIjql68kXT3tdFu27du1Cr169kJCQgH379mHHjh2uv1zxj1KYwDztHDhEcOE55R1BEARhH+RpDwL8KdoB4x7y+fOBu+/2zRa1OvWyx5vxtBsZ064k2tl+St5L+VRgRkW72phao552syQlASdPenqp5ZnLGWoe2Koq9+fbb9eu00j2eC2xtWOHYOf8+cJyTIzgbWfn4MQJaXI1xoMPAps3C57fandkqsu7zUQ7u/6VriF5J0lRkec2PM+hoMC9s1Wi3eyYdqOiXcmDLx7TrpWIzuj4byPRD0Y97YC0LCbajXraExLc3nl5Mj2zU74p2ajWaRXOY9oB4Ouvv7bbhKDCNd1bZAw4K8b3EARBEIQJyNMeBPgzPF7N067E/v3W1ett9nglvBHtSi//WsdZ7m0zGh6v5mn3l2ivX185UkApERqg7O3NyZGe699/167TTHj8//7nuT8T1+J52tVsFHPppUKUgTwCRC7amXAyItqVcxrwaNfOPe6AletreLxZT7u4Y2LtWvXkgnqedl8T0QHGhisY9bTLYQLc6Jj2lBRpnb542mlMO+EtzNNOofEEQRCEHZCnPQj4+Wf35x49BK+p3BOshV54vNGX2g4djNeph5Xh8Vpj2s2Gx6uhNwe5lqfdlzHtZnE4lCMF1FDytM+cKd1GT6AZm/JNEJn33++5/8qVgjffrGhn9Ym3j452H08j4fHyupRzGnCYNKkC996bIilPLrqVOgdkw3wlmPW0Mw80AJSVCXauWuV5rpU87UbGtBud8o3VYaWnXYxctOtljxeXO2QI0Lq11M5AhMeLz3+4jGkHgF9++QWffPIJCgsLUSUOzwGQozXXZB2E5mgnCIIg7IQ87TbDsoUz8vK0p/Ayi5anXT5H+BNPWFMnq1dMoD3tWuHxSuiJdrOedl/HtKthNipDydu7b5+5Mlj79I6R0jzogDvBn7eiXXz84uLc670Jj1fKabBypRM33ug5T7u4LeKyjYbHi/EmmlZtVgB/e9qNJgY04mlXmgFBKTxea572gwfdn/fuBb74Qlqnr+HxavuLt42Lc38Ol/D45cuX4/LLL8eePXvw6aeforq6Gr/99hu++uorJImnAwgTqpwk2gmCIAj7INFuM3Khw7x/alN4KeFNIrrbbwe6d5eOhb35ZuN16hG48HjlsbxmPe164fFmE9H5y9NuVvwpHRO1qc/MlAV4etqV5kEHgMJCoRPKCk+7kmg3moiOIU/yJx9aoORpV5vpwKhoNyMsGWqzAih1RFmRiC4hwd2R8a9/6dtnxNOuNGVkZaUQUfTVV8KyUni82vUpv758zR4fFaUdRcMQX0fhEh7/7LPP4sUXX8R//vMfREdH46WXXsLevXtx2223oaV8jswwoLpWCI+PiaDp3giCIIjAQ6LdZpSEjtYUXmZRE+3dugE7dvC49lq3h9HKsfVmE9F5nz1e+7O/Pe2BTkRnhac9O1t9HngttMa0c5zQGaDGrFnmRTsr36hoV+r48eZ4K83TLi57zx7357lzjUXFeHNvqc0KoOxp9z0R3dVXuzsyrrxS3z4jnnbWOTJ9unR9Xh7w2GPCZ6XweDNh/L6Ex2v97oi3lYv2cAiPLygowJAhQwAA0dHROHPmDDiOw2OPPYY333zTZusCzzd/fgMAOFhyED3e6IGcPeE1PIAgCIKwFxLtNqOcGEt9Ci+zqL3UKk3RZWVC3MCFx1vjafd2THtEhLLtauHx3ohIsSg8dMjc0AmlYyIPEe/WzVhZ8nbKBY9aBntA6ITyl6fdTHi8EZTC48VtXbbM/fmvv4wNZzEjQtl/tVkB9Ma0exseL+48NGKvmTHtSnkUWDvMeNqVbPAlPF5rukM1T3u4hMenpKSg/EICgmbNmmHXrl0AgJKSEpw9e9ZO0wJOzp4czPtlHgCAB4+8ojwM/2Q4CXeCIAgiYJBotxklr6fWFF5KeBMeryTarfS0+zM8/swZ9/Kbb9Z3CSZ/jmk3O+WbVaI9J0cQhYyqKnM5D9QymItDxHfsMFaWXni8+jzoQieUmmjX6hAB9Me0mw2P10MvPF6M0eEsRu6t+HhjswJ4O0+7nqddLECN2CvP6q+1j1IeBfa7JR7TruZpV4sK8aen3Uh4fF0W7VdffTXWr18PABgxYgQeeeQRjBs3DqNGjcLAgQNtti6wzP52Nji4Lx4ePDhwmPWNiXFsBEEQBOEDJNptRikxltYUXmbRF+28ZFur8Ff2+MJCwbvJKCpyYMQIB3JyfAuPt3rKt7vucgtrXxLRKSV3M5PzwEhWcaOeSq3weAZLqijP0zB9OnD+vLDsi6c9NtYeT7tWp5KR4SxG7q2YGO2x9kpleZuITsnDLBagRq6J+++Xdh5p3V9qEUWAcB5ZeLxSZ9ugQdLfx6FDpXX6OqbdyLbhOKZ90aJFuP322wEATz75JCZOnIiioiIMHz4cb7/9ts3WBZb8k/ngIe0d58Ej/6RF49gIgiAIQgcS7UGAXmIsPXzxtCvNtW0F/gqP377doyZwHI9Zs+wJj+c4ZdsPHHB7xH3xtPua88DsXOFa6HnaAWknFGPxYuCmm9zt8EW0iztJ/DWm3YynHTA2nMVfUSxmxrRHRbn3VRKrZsPjKyulUR9a+6hFFAHC8daap71jR+nvo/hYc5xv4fHejGkX11mXPe0NGjRA06ZNAQAOhwNPPPEE1qxZgxdeeAEpKSk2WxdYOjXsJPG0AwAHDp0aWjSOjSAIgiB0INFex7FrTLu8Tr1EdFqiSFxWaann9zzPIT/f2vB4I0m2hLqV2yYOm/ZFtPua88DK4Q96HRsM1gnF5jDPzHSHxgP+E+1Wh8erjWkXf2d0OIs32ePV8GWedvadFaKd2cKiPrT2UYooYrnM9MLjte5Fs552Co83R0FBAZ566imMGjUKxcXFAIAvvvgCv/32m82WBZZpV0+TeNo5cODBI7u/iXFsBEEQBOEDJNrrAL552nmPdVbgr/D45GSlunh06qQfHq/VKSF/+dfytIvtcTrVRRLziPsi2n3NeWBkrLNR9LLHq21fW6st2tXOCytffPyURLtWeHzfvuYS9wH6nvYxY8wPZ1HqbJJjZG50uV3eTvmmdL+ZDY8HpFEfevvII4puvFFYLw6PV7pv5eXK72kKj/cP33zzDbp3746ffvoJOTk5qKioAADs3LkT2WaSrtQBsrpk4R8Z/wAAOOBARnoGcm7LwbAuFo1jIwiCIAgdSLTXcdREO1snfjE142nv0UNbDFmZiO74cffnqirpdxzHg+c5ZGf75mmX26Al2sUiUku0M4+4L2Pafc15YKWnXd5OvSgNJdHucGifa6X95WPLzYTH5+WZS9wnLldNtGdkmB/O8scfxuvXw9sx7f7ytLOoD7PXlzjEnIXHG0msJ//N8sXT7m32+HAIj3/iiSfw9NNPY/369YgWHahrr70WP/74o42W2UPP1J4AgAFtBiD3gVwS7ARBEERAIdFeB5B76MQCZckSYPNmz32UxrRriXa56NETQ/Kybr/dc1sjoj0nRzqO/cIMRC5at67FypVODBumHyKs1ymhJdrFL/DiF/3aWmXRIPaI+zrlmy85D6z0tOsNIVDbvqZGPXO8FmpDKuShyVqi3Wh2dzFmE9EFGmXR7v4ROHRIeT8ziei0hLBa1IdZ0e4+jxxqarzztJud8k0usrU87atXuz9v2CCtMxzC4/Py8jBM4ccmLS0NJ06csMEie3Hywsl2cPTaRBAEQQQeevrUMeRThBUXA88+67mdUvZ4LdTmWVYTQ199JV3+/XdPkW8kPF5er5ylS0+7RKxYWPnT0y4Pjxd/16iRp0fcV9HuC/70tOtFaSh52q0Q7WbC49n3RhP3Acrh8VrizirkUSRqKHXEiI/VunXK+1kRHp+aqh714a2nHQCqq4X/SmPa5deWL552eTi72nnNyQFuu829XFIirT8cRHtycjKOHj3qsX7Hjh1o1qyZDRbZC4l2giAIwk7o6VPHUJsiTI5SIjot1OZZVhNDixd7bisX+UY87Ur1iklIUM6abXZMOyB9gdfytIvLkb+033mnp0fcTtHuzzHtwSLatRLRMduMJu4Tl2elp93I0JOKCmNh/Hrh8WpYER6fnq4e9eGtpx0A/vWvRABAUZGwrNXZJv/OzLAe+f2qdl6VfkfFdYbDmPbbb78dU6ZMwbFjx8BxHJxOJ3744QdMnjwZY8aMsdu8gOMEiXaCIAjCPujpUwcQv2yrTREmx6xoN5vFXClEVy7yjXjaO3bUtis+Xlm0+9PTriXaldohLsubbOa+4M/s8WbGtDPvb1GRfj4EpfLF64x42r1N3CcuV22cuDezLIiTCWphJIxfeco3/f2sEO1sRgA9u4zw3/+6P7Pw+K1bhWtDa6pCb/NwAMZFttLvqLjOcBjT/uyzz6Jz585o0aIFKioq0LVrV1x99dW4/PLL8dRTT9ltXsDhL1wQJNoJgiAIO6CnTx1DTVzLUcoer4XZLOatW3uuk4t8I552efnyttSv77Y/UOHx4nLkIkCvE6SuetqVYMdwwwbgiSfc640mh2P7i7f74gthqAWgnYiuRQvvEveJy7PS086SCeqJTCNh/N562sUe4guJwCWIRaratRIfr12+GebNU14/a5Y5T7vRrPuA5/2qtq/S76i4znAIj4+OjsZbb72FP/74A//973/x4YcfYu/evfjggw8QYeUchiEChccTBEEQdkJPnzqA+MVTTVzLUZoqSguzWcwfeki6rCTyjYj2rCzgqqvcy23aCOPG5e1QKy/Q4fFK7di0yf35yivNT0HmC/4c056b6/48dSqnmmjw7belx8xocriICM8cDSUlwnUICN7QHj3cy3/+6d7uxRe9S9wHGJun3SwsmWDbtu51StejkTB+JS+00dwU7JwUFHh+J84tpnatWCnaWeeLnPx8c2PaxeidJ6MiW+l3VFx/XQ6PdzqdeO6553DFFVfgkksuwauvvoprrrkGt912Gzp06GC3ebZBop0gCIKwE3r61DGUxLVSMjel7PFGyjaaxfz666XLXbt6inxx3Vov223auD9//LG6dywYw+NzcoDp093Lu3aZn4LMF/yZPf71192fDx9WTzR4+LDykA09r3JEhHaOhi+/FLz27ByIO0d8iWgQi3ZWlz+yxyuFzBsJ49fztN95p/q+WteAuNNDbTsrw+PVhr506mTc0y7vlNQT7UY97fLf0ebNpXXW5fD4Z555Bv/6178QHx+PZs2a4aWXXsLDDz9st1m2Q6KdIAiCsBN6+tQB5C+ecnEt9lQz3GLERGypCeRiZPNmT5FvdJ528Ut7gwbAmTPK2+mFx1s15ZtctIuF6muvSZflotObKch8wZ+edmm7OI92sWOYkuJZlpHkcBER+jka1ESX1vzbeoiFHWujP7LHL18uiEJGfLyxqAC9Me29e6vvqyXaz51TrkOMlaJdbVh0drZxT7s8PN4q0Q5If0fF13VdD49///338dprr+HLL7/E6tWr8Z///AfLli2D04LGvvrqq2jdujViY2PRt29fbN26VXXbnJwc9OnTB8nJyahfvz569uyJDz74wGcbvIUS0c2sr7IAAE9ASURBVBEEQRB2Qk+fMEDpZdpsIjpf61R6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V1e7vMY1NTXCSj4aGHbaeKUlOxH19QD1Oq7ZBCT3MFQU74xCrbMWAFzeczXat2+Pfv364e2338aVV16J/fv347vvvsP06dNRU1OD2tpazJ07FytXrsSRI0dQVVWFyspKxMbGutrKhKer7TLY8UxISIDT6cT58+dxxRVX4I033kBpaSkKCgpw33334f7773ftU1NTg6SkJFRXV4PjOHzyySd49dVX8ccff6CiogI1NTVITEx01el0OtGqVSukpKS41l100UW49tprkZGRgeuuuw7XXXcdsrKykJKSgrKyMhw5cgSXXXaZxO5+/frh119/lZzLiy66yPWZdQgcPXoU7du3Vz8HPI/aWv1zUFNTA6fTiZMnTyIqKkryXXl5uep+epBoJwgdZs4EOE46nIjjgFmzSLQTBEHoceLECdTW1iI9PV2yPj09HXv37rWsnqlTp2LixImu5bKyMrRo0QKpqalITEz0qsyXP30ZHDjwuOBdAQ8OHF7+9WWMvWysJXb7G6fTCY7jkJqaGtKCK5TbQPbbj9k2nD9/HuXl5YiMjJSGTEclGa80WjuUPjI6Hog1UV51tYcIVOPee+/FhAkT8Nprr+GDDz5Au3btcO2114LjOMyfPx+LFi3Ciy++iO7du6N+/fp47LHHUFNT42orywyvFi7ucDiQkJCAbdu2weFwoEmTJqhXrx4AoKioCADw5ptvom/fvpL9nE4noqKisGXLFtx1112YMWMGBg0ahKSkJCxfvhwLFixw1elwOFC/fn2JDZGRkVi/fj02b96M//3vf3jttdcwffp0/Pjjj2jYsCEAICIiQrKPuC1sfWxsrOszO6Za7RWjdw4iIyPhcDjQsGFD1zh8hnzZDCTaCUKHffs883/wPJCfb489BEEQhCcxMTGIifEc8+lwOLwWGvtO7nMJdgYPHvtO7gsp8cKmZQolm+WEehvIfvsx0waHw+ESe3qebVViU4Us8SrZ47nYVMELZACe5112GLFn5MiRePTRR/HRRx/hgw8+wIMPPuhq9+bNmzF06FDceeedAAQhvW/fPnTt2lVStlbb2bEUjxNnsOR0Bw4cwB133CFpA/Nub9myBa1atcJTTz3l+r6wsFDSPrX2chyHK6+8EldeeSWys7PRqlUrrF69GhMnTkTTpk2xefNm17AA1t5LL71U0h75Z732MvuNnAPxVHjya82X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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Plot training results\n", "fig, axes = plt.subplots(1, 2, figsize=(12, 5))\n", "\n", "df_train = pd.read_csv(\"metrics_train.csv\")\n", "df_val = pd.read_csv(\"metrics_val.csv\")\n", "\n", "# Plot Loss\n", "axes[0].plot(df_train[\"step\"], df_train[\"mean_loss\"], 'b-o', label='Train Loss', markersize=4, linewidth=1.5)\n", "axes[0].plot(df_val[\"step\"], df_val[\"mean_loss\"], 'r-s', label='Val Loss', markersize=4, linewidth=1.5)\n", "axes[0].set_xlabel('Step')\n", "axes[0].set_ylabel('Loss')\n", "axes[0].set_title('Loss')\n", "axes[0].legend()\n", "axes[0].grid(True, alpha=0.3)\n", "\n", "# Plot Pearson Correlation\n", "axes[1].plot(df_train[\"step\"], df_train[\"mean_pearson\"], 'g-o', label='Train Pearson', markersize=4, linewidth=1.5)\n", "axes[1].plot(df_val[\"step\"], df_val[\"mean_pearson\"], 'orange', marker='s', label='Val Pearson', markersize=4, linewidth=1.5)\n", "axes[1].set_xlabel('Step')\n", "axes[1].set_ylabel('Pearson Correlation')\n", "axes[1].set_title('Mean Pearson Correlation')\n", "axes[1].legend()\n", "axes[1].grid(True, alpha=0.3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 9. 🧪 Test evaluation\n", "\n", "Evaluate the fine-tuned model on the held-out test set to assess final performance. This provides an unbiased estimate of how well the model generalizes to unseen genomic regions." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Calculate number of test steps (based on deepspeed pipeline)\n", "num_test_samples = len(test_dataset)\n", "num_test_steps = num_test_samples // config[\"mini_batch_size\"]\n", "print(f\"Running test evaluation with {num_test_steps} steps ({num_test_samples} samples)\")\n", "\n", "# Load the best model checkpoint\n", "model.load_state_dict(torch.load(config[\"best_model_checkpoint_path\"]))\n", "model.to(device)\n", "print(f\"Loaded model from {config['best_model_checkpoint_path']=!s}\")\n", "\n", "# Set model to eval mode\n", "model.eval()\n", "\n", "# Run test evaluation with progress bar\n", "for test_batch in tqdm(test_loader, desc=\"Test evaluation\", total=num_test_steps): \n", " validation_step( \n", " model, \n", " test_batch, \n", " test_metrics,\n", " )\n", " \n", "# Compute final test metrics\n", "test_metrics_dict = test_metrics.compute()\n", "print(\"\\n\" + \"=\"*50)\n", "print(\"Test Set Results\")\n", "print(\"=\"*50)\n", "print(f\"\\nMetrics:\")\n", "print(f\" Mean Pearson: {test_metrics_dict['mean/pearson']:.4f}\")\n", "for track_name in bigwig_ids: \n", " print(f\" {track_name}/pearson: {test_metrics_dict[f'{track_name}/pearson']:.4f}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test set results obtained for reference (human)\n", "\n", "===== Test Set Results =====\n", "\n", "Metrics:\n", "Mean Pearson: 0.6050\n", "- ENCSR154HRN_M/pearson: 0.5132\n", "- ENCSR154HRN_P/pearson: 0.5095\n", "- ENCSR935RNW_P/pearson: 0.5690\n", "- ENCSR114HGS_M/pearson: 0.3433\n", "- ENCSR487QSB/pearson: 0.7101\n", "- ENCSR046BCI_M/pearson: 0.5188\n", "- ENCSR100LIJ_M/pearson: 0.5632\n", "- ENCSR754DRC/pearson: 0.6046\n", "- ENCSR682BFG/pearson: 0.6839\n", "- ENCSR862QCH_M/pearson: 0.5441\n", "- ENCSR046BCI_P/pearson: 0.4872\n", "- ENCSR249ROI_M/pearson: 0.6077\n", "- ENCSR484LTQ_P/pearson: 0.4738\n", "- ENCSR410DWV/pearson: 0.7949\n", "- ENCSR619DQO_P/pearson: 0.6981\n", "- ENCSR321PWZ_M/pearson: 0.6895\n", "- ENCSR962OTG/pearson: 0.9150\n", "- ENCSR321PWZ_P/pearson: 0.6903\n", "- ENCSR484LTQ_M/pearson: 0.4812\n", "- ENCSR628PLS/pearson: 0.6479\n", "- ENCSR249ROI_P/pearson: 0.5761\n", "- ENCSR799DGV_P/pearson: 0.5704\n", "- ENCSR862QCH_P/pearson: 0.5402\n", "- ENCSR527JGN_M/pearson: 0.5144\n", "- ENCSR619DQO_M/pearson: 0.6975\n", "- ENCSR814RGG/pearson: 0.7958\n", "- ENCSR935RNW_M/pearson: 0.5600\n", "- ENCSR863PSM/pearson: 0.6915\n", "- ENCSR114HGS_P/pearson: 0.3447\n", "- ENCSR325NFE/pearson: 0.8314\n", "- ENCSR701YIC/pearson: 0.5613\n", "- ENCSR527JGN_P/pearson: 0.7226\n", "- ENCSR100LIJ_P/pearson: 0.5643" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test set results obtained for a new species (tomato)\n", "\n", "===== Test Set Results =====\n", "\n", "Metrics:\n", "Mean Pearson: 0.7596\n", "- SRX29291439/pearson: 0.8581\n", "- SRX27799718/pearson: 0.4512\n", "- SRX29291446/pearson: 0.9152\n", "- SRX29291430/pearson: 0.9069\n", "- SRX27799731/pearson: 0.5254\n", "- SRX27799719/pearson: 0.4435\n", "- SRX29291442/pearson: 0.9151\n", "- SRX27799733/pearson: 0.4725\n", "- SRX27799722/pearson: 0.4795\n", "- SRX29291444/pearson: 0.9139\n", "- SRX29291440/pearson: 0.8633\n", "- SRX27799727/pearson: 0.6209\n", "- SRX29291438/pearson: 0.8770\n", "- SRX27799703/pearson: 0.4722\n", "- SRX29291448/pearson: 0.9160\n", "- SRX29291441/pearson: 0.9169\n", "- SRX29291447/pearson: 0.9171\n", "- SRX29291445/pearson: 0.8990\n", "- SRX29291431/pearson: 0.9181\n", "- SRX29291443/pearson: 0.9103\n", "\n", "NOTE: to achieve these results, set the 'species_name' to 'tomato' in the config." ] }, { "cell_type": "markdown", "metadata": {}, "source": [] } ], "metadata": { "kernelspec": { "display_name": ".venv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.14" } }, "nbformat": 4, "nbformat_minor": 2 }