diff --git a/README.md b/README.md index 60b87c8..3b0018f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ - [ ] Introduction du rapport - [ ] Toute la première partie d'essaies (*Méthodes de classification essayées* & *Observations initiales*) - [ ] Comparaison de perf entre 10 ans et 50 ans (dans *Recalibrage et optimisations*) -- [ ] Intégrer des morceaux de code dans les parties nécessaires +- [ ] Mettre le code de la méthode clean_text initiale - [ ] Mentionner la réduction des données parce que prétraitément très long *Mathéo GUILBERT* @@ -63,9 +63,23 @@ Avant de construire des représentations et d'entraîner des modèles, j'ai appl La suppression des numéros de pages est une étape délicate car leur mise en forme dépends de l'ouvrage et de l'éditeur le plus souvent. J'ai quand même repéré un écriture récurente : *-- [NUMERO DE PAGE] --*. J'ai supprimé ces cas là. +Voici le code qui permet ce tratement : + +```py +# CODE EN ATTENTE +``` + +Soit dit en passant, cette étape est très longue et pour réduire ce temps de traitement et aller plus vite sur la classification elle même, j'ai travaillé sur un echantillon du jeu de données. + +```py +reduced_ds = ds['train'].shuffle(seed=42).select(range(5000)) # Echantillon réduit +cleaned_ds = reduced_ds.map(clean_text, remove_columns=reduced_ds.column_names) +``` + ## Méthodes de classification essayées + ### Observations initiales @@ -73,6 +87,7 @@ La suppression des numéros de pages est une étape délicate car leur mise en f Après ce premier aperçu, plusieurs choix d'optimisation ont été faits : +* augmentation de la qualité des données par radicalisation du prétraitement des données * élargissement de la granularité temporelle : plutôt que prévoir par décénies, j'ai augmenté en périodes de 50 ans. Ce choix vise à capter des tendances lexicale et stylistiques plutôt que des variations annuelles insignifiantes. * changement de la métrique d'évaluation : j'ai utilisé la différence moyenne entre la date réelle et la date prédite (MAE temporelle en années) — c'est plus pertinent que la précision (*accuracy*). @@ -80,16 +95,96 @@ Après ce premier aperçu, plusieurs choix d'optimisation ont été faits : * recherche de la plage d'années la plus pertinente pour la clarification. Avec cela j'espère pourvoir améliorer les performances et retrouver des périodes qui s'approchent des mouvements littéraires connus. -**TODO :** Remplis ici : résultats comparatifs avant/après agrégation en 50 ans, et évolution de la métrique moyenne (graphique à insérer). +### Pré traitement plus radical + +Malgrés le prétraitement déja appliqué aux données, il reste beaucoup d'impuretés. En plus de cela le prétraitement était de loins l'étape la plus longue du processus de classification car je cherchais des expressions dans les textes pour les enlever. + +Pour optimiser ce temps et l'efficacité de l'entrainement, j'ia simplifié les critères de prétraitement : + +* traitement des dates identiques au précedant +* suppression de tous les sauts de lignes et tabulations +* normalisation des caractères en minuscule +* suppression de tous les caractère non alphabetique (comme précédemment) + +**Résultat :** tous les textes sont réduit à une suite de mots spérés par des espaces. + +```py +def clean_text(example): + """ + Nettoie le texte d'entrée + """ + text = example["complete_text"] + date = example.get("date", None) + + # --- Nettoyage de la date + if "-" in str(date) and date is not None: + parts = str(date).split("-") + if (parts[1].isdigit() and len(parts[1]) == 4) and parts[0] == "????": + date = str(parts[1]) + else: + date = str(parts[0]) + + # --- Nettoyage de texte + text = (text.replace("\\n", " ") + .replace("\\r", " ") + .replace("\\t", " ")) + + text = text.lower() + + text = re.sub(r"[^a-zàâäæçéèêëïîôùûüœ\s]", " ", text) + + text = re.sub(r"\s+", " ", text).strip() + + words = text.split() + filtered_words = [word for word in words if word not in french_stopwords] + text = " ".join(filtered_words) + + return {"text": text, "date": str(date)} +``` ### Impacte de la granularité temporelle Pour grouper les données facilement, j'ai fais une méthode `create_period_label`. ```py +def create_period_label(example, period_length=50): + """ + Crée une étiquette de période basée sur l'année de publication. + """ + try: + year = int(example['date']) + start_year = (year // period_length) * period_length + end_year = start_year + period_length - 1 + return {"period": f"{start_year}-{end_year}"} + except (ValueError, TypeError): + return {"period": None} + +dataset_with_labels = cleaned_ds.map(create_period_label) + +df = pd.DataFrame(dataset_with_labels) + +grouped_texts = df.groupby('period')['text'].apply(list) + +period_counts = grouped_texts.apply(len).sort_index() + +plt.figure(figsize=(10, 6)) +period_counts.plot(kind='bar', color='skyblue', edgecolor='black') + +plt.title('Nombre de textes par période', fontsize=16) +plt.xlabel('Période', fontsize=12) +plt.ylabel('Nombre de textes', fontsize=12) +plt.xticks(rotation=45, ha='right') +plt.grid(axis='y', linestyle='--', alpha=0.7) +plt.tight_layout() + +plt.show() ``` +![Répartition des exemples par période de 50 ans](images/repartition-exemples-par-periode-50-ans.png) + +Ci-dessous le graphique d'évaluation des prédictions nous montres + ### Visualisations des différences entre périodes Pour comprendre quelles caractéristiques distinguent les périodes, j'ai généré des nuages de mots par période. Méthode : calcul de TF‑IDF par groupe temporel, puis génération d'un WordCloud à partir des mots les plus importants (somme des scores TF‑IDF sur la période). diff --git a/images/repartition-exemples-par-periode-50-ans.png b/images/repartition-exemples-par-periode-50-ans.png new file mode 100644 index 0000000..66a7d6c Binary files /dev/null and b/images/repartition-exemples-par-periode-50-ans.png differ diff --git a/work.ipynb b/work.ipynb index 0ed7648..c5c8504 100644 --- a/work.ipynb +++ b/work.ipynb @@ -137,12 +137,15 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "id": "91c483b8-ae5b-4f1d-9f8a-dffc8eea16c9", "metadata": {}, "outputs": [], "source": [ "def clean_text(example):\n", + " \"\"\"\n", + " Nettoie le texte d'entrée\n", + " \"\"\"\n", " text = example[\"complete_text\"]\n", " date = example.get(\"date\", None)\n", "\n", @@ -174,106 +177,67 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "id": "39e38bbf", "metadata": {}, "outputs": [], "source": [ "reduced_ds = ds['train'].shuffle(seed=42).select(range(5000))\n", "\n", - "cleaned_ds = reduced_ds.map(clean_text, remove_columns=reduced_ds.column_names)\n", + "cleaned_ds = reduced_ds.map(clean_text, remove_columns=reduced_ds.column_nameds)\n", "# cleaned_ds = ds['train'].map(clean_text, remove_columns=ds['train'].column_names, num_proc=4)" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 29, "id": "0474c7fd", "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Colonnes du DataFrame:\n", - "Index(['date', 'text', 'period'], dtype='object')\n", - "\\Aperçu des données avec périodes:\n", - " date text period\n", - "0 1888 v congres international sociétés chahitables s... 1850-1899\n", - "1 1716 ordonnance roy reformer quatre compagnies ze r... 1700-1749\n", - "2 1856 souvenir sme année janvier respects double all... 1850-1899\n", - "3 1782 flore bourgogne seconde partie flore bourgogne... 1750-1799\n", - "4 1863 approvisionnement ville lyon lt gt lt gt houil... 1850-1899\n", - "\n", - "Périodes et nombre de textes:\n", - "period\n", - "1550-1599 5\n", - "1600-1649 62\n", - "1650-1699 44\n", - "1700-1749 122\n", - "1750-1799 381\n", - "1800-1849 1066\n", - "1850-1899 2361\n", - "1900-1949 910\n", - "1950-1999 43\n", - "2000-2049 6\n", - "Name: text, dtype: int64\n" - ] + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAJOCAYAAABBfN/cAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjcsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvTLEjVAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAjx5JREFUeJzs3Xd8VGXaxvFrkpAQAkkggVBCrwHphCJKlyoqIE0URJSVRXdFwYIoxe4iFnTFCjbWtjYUwY7AIhYITSnSW4AESCCEtLnfP3gzMiSBJGRmSPh9P599X/OcM2fu55mTh1xzmsPMTAAAAAAAwCP8fF0AAAAAAAAlGcEbAAAAAAAPIngDAAAAAOBBBG8AAAAAADyI4A0AAAAAgAcRvAEAAAAA8CCCNwAAAAAAHkTwBgAAAADAgwjeAAAAAAB4UICvCwAAAIDnzJ49W4mJibrhhhtUt25dX5cDABcljngDAACUUM8++6z+8Y9/aM+ePYRuAPAhgjcAFBO1atWSw+GQw+HQhx9+mOd6PXr0kMPh0Lx587xXXAH98MMPcjgc6tKli69LKRLTpk2Tw+HQtGnTfF0K4PLTTz9p0qRJ6tu3r+bMmVPo7Xj793XevHlyOBy68cYbvfJ+AOANBG8AKIbuv/9+ZWZm+roM+MCNN954wXyxwhcOF67ExEQNGTJEzZs31/vvv6+AAK4uBABfIngDQDFTpkwZbd68Wa+++qqvSwFwgYqLi9OYMWP0xRdfKCQk5Ly21bZtW/3xxx968803i6g6ALj4ELwBoJj55z//KUmaMWOGTpw44eNqAFyIunfvrqlTp6pSpUrnva0yZcqoUaNGqlGjRhFUBgAXJ4I3ABQzffv2VefOnbV//349/fTTBX79u+++q+7du6tChQoKCgpSzZo1ddNNN2nz5s25rp99bfmOHTv05ZdfqkuXLgoLC1P58uV15ZVXat26da5158+frw4dOqhcuXIKDw/XwIEDtXXr1rPWc+LECU2ePFn16tVT6dKlVbVqVY0ZM0Z79+7Nse6OHTvkcDhUq1YtZWVladasWWrZsqXKli0rh8Phtu7mzZv1t7/9TXXr1lXp0qUVFhamTp066e233y7wmElSamqqpk2bpvr16ysoKEhVqlTRqFGjtGvXrnO+9rffftOIESNUo0YNBQUFqUKFCurVq5cWLlyY7/fP7vsbb7whSRo9erTrmv/cTvdOTU3VU089pfbt2ys8PFylS5dWw4YNdffddysxMdFt3Q8//FAOh0MVK1bUnj17crz34sWL5e/vr7CwMG3ZskWS5HA4NH36dEnS9OnT3Wo589rczMxMvfrqq+rSpYtrv6tdu7bGjRun3bt359rfb775Rv3791dUVJRKlSql8uXLq379+rr++uv1448/5nvcTj8dfufOnRo5cqSqVKmi0qVLq0GDBpo2bZpSU1NzvC4jI0Nvv/22RowYoUaNGik0NFTBwcFq2LCh/vGPf2jfvn25vl+XLl3kcDj0ww8/aOnSperfv78qVqwoPz+/fF0ecPr1zYmJiRo/frxrv6lZs6YmTJigI0eO5Pn6ffv26c4771RMTIzKlCmjcuXKKTY2Vs8//3yul6ecfunC+vXrNXToUFWpUkX+/v6ufepc13hv3LhRo0ePVs2aNV37d/fu3fX+++/nWWdmZqaeeeYZNW3aVKVLl1bFihU1aNAgt/kkL0X9uw0AXmEAgGKhZs2aJsmWLl1qP/30k0my0NBQS0hIcFuve/fuJsnmzp3r1u50Om3kyJEmyQICAqxbt242bNgwa9CggUmyMmXK2Jdffpnn+957773mcDisY8eONmTIENfrwsPD7c8//7RJkya5tnvttdda9erVTZJVrVrVDh8+7LbN77//3iRZhw4drH379lamTBnr27evDR482KpUqWKSrHLlyrZ582a3123fvt0kWY0aNeyqq66ywMBA6969uw0fPtyaNWvmWu/999+30qVLmyRr1KiRDRgwwLp162YhISEmyUaPHl2gsU9JSbH27dubJAsJCbErr7zSBg8ebFFRURYREeEa16lTp+Z47TPPPGN+fn4myVq0aGHXXnutXXbZZRYYGGiSbPr06fmq4dChQzZq1CirW7euSbKOHTvaqFGjXP/7+OOPXevu3bvXmjZtapKsQoUK1qNHDxswYIDrs6xVq5bt2LHDbfu33367SbLLLrvMMjIyXO179uyxihUrmiR77733XO2jRo2y5s2bmyRr3ry5Wy2vvPKKa73k5GTr0qWLSbKyZcta586d7dprr7WGDRuaJIuIiLBVq1a51TJv3jxzOBzmcDisXbt2NnToULvqqqusVatW5u/vb//85z/zNWZmZlOnTjVJNnLkSIuIiLCoqCgbPHiwXXnlla79oWPHjpaamur2ut27d5skCwsLs/bt29vgwYOtb9++VrVqVZNkFStWtC1btuR4v86dO5sk+/vf/25+fn7WuHFjGzZsmPXs2dPmz59/znrnzp1rkuyqq66yunXrWnh4uF1zzTU2YMAAK1++vEmyhg0b2sGDB3O8dsmSJa51atWqZVdddZX16tXL1dazZ09LT093e82oUaNMkt1yyy0WFBRktWrVsiFDhlj//v1t5syZZvbX72vnzp1zvOfnn3/u+l1r2LChDRs2zLp162b+/v4myW666aYcr8nKyrJrrrnGJFlgYKD17NnThg4darVq1bLSpUvb3//+d5Nko0aNyvHaov7dBgBvIXgDQDFxevA2Mxs4cKBJsgkTJritl1fwfvHFF02SRUZG2urVq13tTqfTFU7Cw8Nz/EGf/b5BQUH2zTffuNozMzNt8ODBJskuueQSi4iIsLi4ONfylJQUu/TSS02SPfzww27bzP5DXpLVq1fPdu7c6VqWmppqgwYNMknWvn17t9dlB29JFh0dbZs2bcoxTmvXrrWgoCArXbq0/fe//3VbtmPHDlcgfeONN3K8Ni8TJ050/aG/d+9etz5effXVrprODN6LFi0yh8NhkZGRtmTJkhx1RkdHmyT74Ycf8l1LdlA68/PN5nQ6rWPHjibJxowZY8nJya5lGRkZdtddd5kk69q1q9vr0tLSrG3btibJ7rnnHtf6l112mUmy8ePH53iv7P0mty8csl133XUmya688ko7cOCA27Knn37aJFn9+vUtMzPT1V67dm23ff10Bw4cyBHUzya7Rkl29dVX24kTJ1zLdu/e7foC6d5773V7XXJysn366aeWlpbm1p6enm733XefSbK+ffvmeL/s4C3JXnjhhXzXmS07eGfv/4mJia5lR44ccf1ODRs2zO11+/fvt4iICHM4HPbvf//bsrKyXMsSEhKsW7duuX7Rk70/ZY/B6a/Lllfwjo+Pt7CwMNfvuNPpdC375ZdfXIH/5Zdfdnvd888/b5IsKirKfv/9d1d7RkaGjRs3zlXPmcHbE7/bAOAtBG8AKCbODN4bN260gIAACwoKcjt6mVfwzj5S+txzz+XYttPptGbNmpkke+SRR3J930mTJuV43apVq84aMv773//mGvJOD96ffPJJjtcdOHDAypQpY5Js+fLlrvbTg/ebb76ZyyiZDR061CS5jtad6eeffzZJ1rp161yXn+nEiRNWrlw5k5TrGQH79+93HYE7M4C2a9fOJNmHH36Y67bff/99k2SDBg3KVy1m5w7eX375pevo+ulHrrNlZWXZJZdcYpJs3bp1bsu2b99u5cuXN4fDYV988YXdfffdrrE6efJkjm2dK3j//vvv5nA4rGrVqm5fAJyub9++JskWLFjgaitTpoyFhYXlPgAFlF1jcHCw7d+/P8fyBQsWuM4eOfOo99lUrVrV/Pz8cvQrO3h369atUPWeHrxP/4Is29q1a83hcJifn5/t3r3b1X7PPfeYJLvtttty3e6ePXusVKlSVrFiRbeAnL0/NWjQwO3Lj9PlFbwfeuihs/4uzZw50/XFyunq1atnkuzFF1/M8ZrU1FSrXLlyrsG7qH+3AcCbuMYbAIqphg0b6qabblJaWpoeeOCBs667Z88e17XWo0aNyrHc4XBo9OjRkqTvv/8+12307ds3R1v9+vXztTyv62HDw8N11VVX5WivVKmSevfuLenU9aW5GTRoUI42p9OpL7/8UpI0dOjQXF/Xpk0blS1bVqtXr9bJkydzXed0q1at0rFjxxQZGemq6XSVK1dWz549c7QnJCTo559/VnBwsPr375/rtrOvmf3f//53zjry64svvpB0anxye4SUn5+fOnXqlOv71qpVy3Ud8vDhw/Wvf/1LYWFhev/99xUUFFTgWhYuXCgzU58+fVSuXLlc18ltDNq2baukpCSNHDlSv/32m5xOZ4Hf+0w9e/ZU5cqVc7RfeeWVioiIUHJyslatWpVj+Zo1azRr1izdfvvtuummm3TjjTfqxhtvVGZmppxOp/78889c3+/aa689r3qbN2+uFi1a5Ghv2rSpWrZsKafT6Xate/bnntd+X61aNdWvX1+HDh1yXad/umuuuUb+/v4FqjH7dzO3OUWSxowZI0nasmWLaw7Yu3eva8yuv/76HK8pXbq0hgwZkqPdE7/bAOBNPNQRAIqxadOm6e2339Y777yjiRMnqlmzZrmul32jsoiICIWGhua6Tt26dd3WPVNudzQuW7bsWZdnh628/gjOvnFbbmrXri1Jud7sq1KlSipTpkyO9sTERCUnJ0uSqlevnut2z1y/WrVqZ10n+/1r1aqV5zrZtZ5u+/btMjOlpqaeM7QeOnTonLXm17Zt2yRJDzzwwDm/kMntfa+66irdfPPNeuWVVyRJL7/8surUqXNetbz22mt67bXX8l3Lv//9b1155ZV666239NZbb7luENatWzfdcMMNhbq7dm6fUbZatWopMTHRbV9LSUnRDTfcoI8//vis283e33Lb5vk4W721a9fWqlWr3OrNHuvLL7/8nNs+dOiQGjRo4NZWmHqz54q8ag0PD1eFChV0+PBh7dmzR1WrVnXVHBkZ6TZ/nC637XnidxsAvIngDQDFWJUqVfTPf/5Tjz32mO677z7XUS9P8PM7+0lS51peWGaWoy04ODjXdU8/MprXUbjTFeYobn5l11K2bNlcj857+n0vu+wy15cpeWnSpEmOtsTERNeRRUn66aefcj0CWZBaWrRooebNm5913Xbt2rn+OyYmRps2bdJXX32l7777Tv/73/+0dOlSfffdd5oxY4Zee+21XI+Wnq/T97X77rtPH3/8sRo1aqTHH39csbGxioyMVGBgoCTp0ksv1YoVK3LdP6W891FP1Zs91tdee+05n9sdERGRo80b9Z6PC+l3GwAKg+ANAMXcPffco5dfflkLFy7M8zFL2Ud+so8a5XbUO/uImTePEu3YseOcy6Kjo/O9vcjISAUHBys1NVUzZ85UZGTkeVb413jkp9bTZR+Vczgcev311z32xURe73v11Vdr4sSJBXqtmemGG27Qnj17dM011+jHH3/U008/rS5duuR6SUB+a+nYsaOef/75Ar02ICBAffv2dV3CkJycrFmzZmn69On629/+pgEDBpwzYJ5u+/bteS7LbV/LfhTWe++9l+uZJLmdrl2UClpv9erVtWXLFt1zzz1q06aNR2vLVq1aNW3cuNE1d5wpKSlJhw8fdq17+v9PSEjQ8ePHcz3qndvvkyd+twHAm7jGGwCKubCwME2ePFmSdPfdd+e6TnR0tOvoZ27PEjYzV3vXrl09Umdujh49qgULFuRoP3TokBYtWiRJeT47ODf+/v664oorJOmszxAuiNatW6ts2bJKSEjQV199lWP5gQMHcm2vWrWqmjVrpmPHjrn6UhSyj7jm9kxmSerTp48k6YMPPsjzaGxeHn/8cX355ZeKiYnR22+/rTfeeMP1TOmdO3cWupbPPvvsvK+5DQ0N1bRp0xQeHq4TJ07k+dz5vHz11Vc6ePBgjvaFCxcqMTFR5cqVU+vWrV3t2YGxZs2aOV6zePFiJSQkFLAHBbN27Vqt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rvbkkIpKDqmoiKTdKp3+1+WER8pVUUpweUUd2a6AzL8OeCSE19DJwLKqeniLIoJOatKkSUpMTFRqaupF8TnRJ/pEny7cPu3fv1/55bDTvy64gIwbN05ffvmlli1bpujoaEnS/PnzNXr0aLejz5LUtm1bde3aVU888YTGjh2rnTt3ul2vfeLECYWEhGjhwoXq06ePGjRooNGjR+u+++5zrbNw4UL169dPJ06cyBG8czviXb16dSUmJio0NFRSyfnGpiR+C0Wf6BN9ok/0iT7Rp5y1x8XFKTY2Vre987WiGzZ1W/9CPeK9b9M6zRndT8uXL1fr1q1z9CmvvkrF93OiT/SJPl24fTp69KjKly+vpKQkVy7MywV5xPu2227T559/rh9//NEVuiWpcuXKSk9P19GjR92Oeh84cECVK1d2rfPzzz+7bS/7ruenr3PmndAPHDig0NDQHKFbkoKCghQUFJSjPSAgQAEB7kOYvUOcKfsDzm/7mdstTLvD4ci1Pa8aC9pOn+hTXu30iT5J9CmvGgvaTp/ok+SZPv31Po5TQftMDofMUZB2P5kjlzfNo/1UoC5Au5+/nHIoPT1dfn5+cjgcOfp0upLyOZ2rnT7RJ4k+5VVjQdsL06f8uqDuam5muu222/Txxx/ru+++U+3atd2Wt27dWqVKldK3337ratu0aZN27dqlDh06SJI6dOigdevW6eDBg651vv76a4WGhqpx48audU7fRvY62dsAAAAAAKCoXFBHvMePH6/58+fr008/Vbly5VzXZIeFhSk4OFhhYWEaM2aM7rzzTlWoUEGhoaG6/fbb1aFDB7Vv316S1LNnTzVu3Fg33HCDnnzyScXHx2vKlCkaP36866j1rbfequeff1533323brrpJn333Xd6//339cUXX/is7wAAAACAkumCOuL94osvKikpSV26dFGVKlVc/3vvvfdc6zz99NO68sorNWjQIHXq1EmVK1fWRx995Fru7++vzz//XP7+/urQoYOuv/56jRw5UjNmzHCtU7t2bX3xxRf6+uuv1bx5cz311FN69dVXeZQYAAAAAKDIXVBHvPNzn7fSpUvrhRde0AsvvJDnOjVr1tTChQvPup0uXbpo9erVBa4RAAAAAICCuKCOeAMAAAAAUNIQvAEAAAAA8CCCNwAAAAAAHkTwBgAAAADAgwjeAAAAAAB4EMEb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rVq11L17d0VERBRFbQAAAAAAFHuFDt7Tpk3TE088keOxYoGBgbr77rs1Y8aM8y4OAAAAAIDirlCPE3vooYc0Y8YM9ejRQ19++aW2bt2qrVu3auHCherRo4ceeeQRPfTQQ0VdKwAAAAAAxU6hjnjPmTNH/fv316effurWXrt2bfXu3Vv9+/fXiy++qAceeKBIigQAAAAAoLgqVPBOSkpS796981zet29f/fDDD4WtCQAAXOR27dqlhIQEX5dRIJGRkapRo4avywAAXIAKFbw7duyolStXaty4cbkuX7lypTp27HhehQEAgIvTrl271CgmRqknTvi6lAIJLlNGG//4g/ANAMih0Kea9+7dWxMmTND48eNVp04dSdK2bdv0/PPP66efftKiRYuKtFAAAHBxSEhIUOqJExry8IuqVLu+r8vJl4Pbt+j9KeOUkJBA8AYA5JCv4F2uXDk5HA63tszMTD333HN67rnn5Od36h5tTqdTkhQUFKTmzZsrKSmpiMsFAAAXi0q166taTHNflwEAwHnLV/AeNGhQjuANAAAAAADOLV/Be968eR4uAwAAAACAkqlQz/EGAAAAAAD5U6ibq2X78ccftW3bNh05ckRm5rbM4XBowoQJ51UcAAAAAADFXaGOeMfFxalhw4bq2rWrbrrpJt11112aOHFijv8V1I8//qj+/furatWqcjgc+uSTT9yWm5kefPBBValSRcHBwerRo4e2bNnits7hw4c1YsQIhYaGKjw8XGPGjNHx48fd1lm7dq0uv/xylS5dWtWrV9eTTz5Z4FoBAAAAAMiPQgXvm2++WQcPHtScOXMUFxen7du35/jftm3bCrzdlJQUNW/eXC+88EKuy5988kk999xzmjNnjlauXKmQkBD16tVLJ0+edK0zYsQIbdiwQV9//bU+//xz/fjjjxo7dqxreXJysnr27KmaNWvqt99+07/+9S9NmzZNL7/8csEHAgAAAACAcyjUqeYbNmzQjBkzdMsttxRpMX369FGfPn1yXWZmeuaZZzRlyhRdffXVkqQ333xTUVFR+uSTTzRs2DD98ccfWrRokX755Re1adNGkjR79mz17dtXM2fOVNWqVfXOO+8oPT1dr7/+ugIDA9WkSRPFxcVp1qxZbgEdAAAAAICiUKgj3vXr1/f648W2b9+u+Ph49ejRw9UWFhamdu3aacWKFZKkFStWKDw83BW6JalHjx7y8/PTypUrXet06tRJgYGBrnV69eqlTZs26ciRI17qDQAAAADgYlGoI97Tpk3TXXfdpeHDh6tatWpFXVOu4uPjJUlRUVFu7VFRUa5l8fHxqlSpktvygIAAVahQwW2d2rVr59hG9rLy5cvneO+0tDSlpaW5fk5OTpYkZWZmKjMzU5Lk5+cnPz8/OZ1OOZ1O17rZ7VlZWW43oMur3d/fXw6Hw7Xd09slKSsrK1/tAQEBMjO3dofDIX9//xw15tVOn+gTfaJP9Ik++aJPTqdTgYGB8tP/v7855TitFnM4JIdfnu0Oc0pu7X6Sw5F3u9O9RnOcOi7hMGf+2v38JZkCAwPldDqVmZlZLD6nv97Hco6Bn79k5t5Xh+PUGOTZ7vnPye+0cc7uN79P9Ik+0Sdf9im/ChW8Bw4cqJMnT6phw4bq3r27oqOjXR04vZhnn322MJu/4Dz22GOaPn16jvbVq1crJCREklSxYkXVrVtX27dv16FDh1zrREdHKzo6Wps3b1ZSUpKrvU6dOqpUqZLWr1+v1NRUV3ujRo0UHh6u1atXu33ozZo1U2BgoH799Ve3Gtq0aaP09HStXbvW1ebv76/Y2FglJSVp48aNrvbg4GA1b95cCQkJbtfgh4WFKSYmRvv27dOePXtc7fSJPtEn+kSf6JMv+pSUlKRJkyYpolS60iSFnkhUaMpftacEh+tIuaoqfzxeIalHXe3JIRWVHFJREUm7VTo9xdV+pFwVpQSXV9SR7QrI/OuL9ITwGjoZWFZVD2+R47Q/nuIr1FWWX4CqJWxy69PeyIbyd2aq8uGtrjbz89PeyEYq5+fUpEmTlJiYqF9//bVYfE5JSUkKDAxUkMPc+prdp9IZKYo8usvVnhkQpPgKdRVy8qjKH9vvaj8ZGKKE8Jpe+Zwigk66xjk1NZXfJ/pEn+iTT/u0f/9+5ZfDznwOWD4sWbJEV111lY4dO5b3hh2OHN8iFITD4dDHH3+sa665RpK0bds21a1bV6tXr1aLFi1c63Xu3FktWrTQs88+q9dff1133XWX2ynjmZmZKl26tD744AMNGDBAI0eOVHJystsd07///nt169ZNhw8fzvcR7+rVqysxMVGhoaGSSs43NiXxWyj6RJ/oE32iT8WrT3FxcerYsaNunfuFqsS0KBZHvPf+EaeXR/fT8uXL1aJFi2LxOcXFxSk2Nla3vfO1ohs2zdGnC/GI975N6zTn/8e5devWOfqUV1+li/f3iT7RJ/rkuT4dPXpU5cuXV1JSkisX5qVQR7xvv/12hYaG6sMPP1S7du3O+SZFoXbt2qpcubK+/fZbV/BOTk7WypUrNW7cOElShw4ddPToUf3222+uyfi7776T0+lUu3btXOvcf//9ysjIUKlSpSRJX3/9tRo2bJhr6JakoKAgBQUF5WgPCAhQQID7EGbvEGc684yAc7Wfud3CtDscjlzb86qxoO30iT7l1U6f6JNEn/KqsaDtF2Of/Pz8lJ6eLqf+/34yDj9ZbreWyaP9VFArQLtf7n01R0HaHUpPT5efn59b3y7kz+mv93HkPgYOR+59zbPd85+T87Rxzr7fEL9P9Ik+0ae8aixoe2H6lF+Furnan3/+qUmTJumKK64o0tB9/PhxxcXFKS4uTtKpG6rFxcVp165dcjgcuuOOO/Twww/rs88+07p16zRy5EhVrVrVdVQ8JiZGvXv31i233KKff/5Zy5cv12233aZhw4apatWqkqTrrrtOgYGBGjNmjDZs2KD33ntPzz77rO68884i6wcAAAAAANkKdcS7SZMmbufbF5Vff/1VXbt2df2cHYZHjRqlefPm6e6771ZKSorGjh2ro0eP6rLLLtOiRYtUunRp12veeecd3Xbbberevbv8/Pw0aNAgPffcc67lYWFh+uqrrzR+/Hi1bt1akZGRevDBB3mUGAAAAADAIwoVvGfOnKkRI0aoV69eatu2bZEV06VLF7fz9c/kcDg0Y8YMzZgxI891KlSooPnz55/1fZo1a6alS5cWuk4AAAAAAPKrUMH7qaeeUrly5dShQwc1btxYNWrUyPWu5p9++mmRFAkAAAAAQHFVqOC9du1aORwO1ahRQ8ePH9fvv/+eY53sG14AAAAAAHAxK1Tw3rFjRxGXAQAAAABAyVSou5oDAAAAAID8KdQR72xLlizRF198oZ07d0qSatasqX79+qlz585FUhwAAAAAAMVdoYJ3enq6hg8frk8++URmpvDwcEnS0aNH9dRTT2nAgAH6z3/+o1KlShVlrQAAAAAAFDuFOtV8+vTp+vjjj3XXXXdp//79Onz4sA4fPqz4+HhNnDhRH3300Vkf+QUAAAAAwMWiUMF7/vz5GjVqlJ588klFRUW52itVqqQnnnhCI0eO1FtvvVVkRQIAAAAAUFwVKnjv379f7dq1y3N5u3btFB8fX+iiAAAAAAAoKQp1jXd0dLR++OEH3XrrrbkuX7JkiaKjo8+rMAAAAKAk2LVrlxISEnxdRoFERkaqRo0avi4DKDEKFbxHjRqlqVOnKjw8XBMmTFC9evXkcDi0ZcsWPfPMM/rggw80ffr0oq4VAAAAKFZ27dqlRjExSj1xwtelFEhwmTLa+McfhG+giBQqeE+ePFlbt27Vyy+/rFdeeUV+fqfOWHc6nTIzjRo1SpMnTy7SQgEAAIDiJiEhQaknTmjIwy+qUu36vi4nXw5u36L3p4xTQkICwRsoIoUK3v7+/po3b57uvPNOLVy40O053n379lWzZs2KtEgAAACgOKtUu76qxTT3dRkAfKRQwTtbs2bNCNkAAAAAAJxFoe5qDgAAAAAA8iffR7wLemTb4XBozZo1BS4IAAAAAICSJN/Bu0KFCnI4HOdcLz4+Xps2bcrXugAAAAAAlHT5Dt4//PDDWZfHx8friSee0EsvvSR/f3/dcMMN51sbAAAAAADF3nndXE2SDhw4oMcff1wvv/yyMjIydP311+v+++9X3bp1i6I+AAAAAACKtUIH7+wj3KcH7ilTpqhOnTpFWR8AAAAAAMVagYN3fHy8Hn/8cb3yyivKyMjQDTfcoClTpqh27dqeqA8AAAAAgGIt38F7//79rsCdmZmpkSNH6v777ydwAwAAAABwFvkO3nXr1lVaWppatGihyZMnq3bt2jpy5IiOHDmS52tatWpVJEUCAAAAAFBc5Tt4nzx5UpK0evVqDRky5KzrmpkcDoeysrLOrzoAAAAAAIq5fAfvuXPnerIOAAAAAABKpHwH71GjRnmyDgAAAAAASiQ/XxcAAAAAAEBJRvAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPIjgDQAAAACABxG8AQAAAADwIII3AAAAAAAeRPAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPIjgDQAAAACABxG8AQAAAADwIII3AAAAAAAeRPAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPIjgDQAAAACABxG8AQAAAADwIII3AAAAAAAeRPAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPIjgDQAAAACABxG8AQAAAADwIII3AAAAAAAeRPAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPIjgDQAAAACABxG8AQAAAADwIII3AAAAAAAeRPAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPIjgDQAAAACABxG8AQAAAADwIII3AAAAAAAeRPAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPKhYBe9p06bJ4XC4/a9Ro0au5SdPntT48eMVERGhsmXLatCgQTpw4IDbNnbt2qV+/fqpTJkyqlSpkiZNmqTMzExvdwUAAAAAcJEI8HUBBdWkSRN98803rp8DAv7qwoQJE/TFF1/ogw8+UFhYmG677TYNHDhQy5cvlyRlZWWpX79+qly5sv73v/9p//79GjlypEqVKqVHH33U630BAAAAAJR8xS54BwQEqHLlyjnak5KS9Nprr2n+/Pnq1q2bJGnu3LmKiYnRTz/9pPbt2+urr77S77//rm+++UZRUVFq0aKFHnroId1zzz2aNm2aAgMDvd0dAAAAAEAJV+yC95YtW1S1alWVLl1aHTp00GOPPaYaNWrot99+U0ZGhnr06OFat1GjRqpRo4ZWrFih9u3ba8WKFWratKmioqJc6/Tq1Uvjxo3Thg0b1LJly1zfMy0tTWlpaa6fk5OTJUmZmZmu09T9/Pzk5+cnp9Mpp9PpWje7PSsrS2Z2znZ/f385HI4cp7/7+/tLOnXUPj/tAQEBMjO3dofDIX9//xw15tVOn+gTfaJP9Ik++aJPTqdTgYGB8tP/v7855TitFnM4JIdfnu0Oc0pu7X6Sw5F3u9O9RnOcuhLPYc78tfv5SzIFBgbK6XQqMzOzWHxOf72P5RwDP3/JzL2vDsepMciz3fOfk99p45zd7wv990mSSpUqJb/TxrlI9z0PfE5+MrdxvNDmiHO1F8d5jz4V3z7lV7EK3u3atdO8efPUsGFD7d+/X9OnT9fll1+u9evXKz4+XoGBgQoPD3d7TVRUlOLj4yVJ8fHxbqE7e3n2srw89thjmj59eo721atXKyQkRJJUsWJF1a1bV9u3b9ehQ4dc60RHRys6OlqbN29WUlKSq71OnTqqVKmS1q9fr9TUVFd7o0aNFB4ertWrV7t96M2aNVNgYKB+/fVXtxratGmj9PR0rV271tXm7++v2NhYJSUlaePGja724OBgNW/eXAkJCdq2bZurPSwsTDExMdq3b5/27NnjaqdP9Ik+0Sf6RJ980aekpCRNmjRJEaXSlSYp9ESiQlP+qj0lOFxHylVV+ePxCkk96mpPDqmo5JCKikjardLpKa72I+WqKCW4vKKObFdA5l9fpCeE19DJwLKqeniLHKf98RRfoa6y/AJULWGTW5/2RjaUvzNTlQ9vdbWZn5/2RjZSOT+nJk2apMTERP3666/F4nNKSkpSYGCgghzm1tfsPpXOSFHk0V2u9syAIMVXqKuQk0dV/th+V/vJwBAlhNf0yucUEXTSNc6pqanF4vdJkm666SY1DTqp0v8/zkW573nic4oIOqmOHTtK0gU5R2S7kH6f6NPF2af9+/crvxx2+tcFxczRo0dVs2ZNzZo1S8HBwRo9erTbkWlJatu2rbp27aonnnhCY8eO1c6dO7V48WLX8hMnTigkJEQLFy5Unz59cn2f3I54V69eXYmJiQoNDZVUcr6xKYnfQtEn+kSf6BN9Kl59iouLU8eOHXXr3C9UJaZFsTjivfePOL08up+WL1+uFi1aFIvPKS4uTrGxsbrtna8V3bBpjj5diEe8921apzn/P86tW7fO0ae8+ir57vcpLi5O7du317h5C1X1/8f5Qj/ivW/TOr0wsrd+/vlnNW/e/IKbI87VXhznPfpUPPt09OhRlS9fXklJSa5cmJdidcT7TOHh4WrQoIH+/PNPXXHFFUpPT9fRo0fdjnofOHDAdU145cqV9fPPP7ttI/uu57ldN54tKChIQUFBOdoDAgLcbu4m/bVDnCn7A85v+5nbLUy7w+HItT2vGgvaTp/oU17t9Ik+SfQprxoL2n4x9snPz0/p6elyyvH/L/CTOXLZeB7tp0JNAdr9cu+rOQrS7lB6err8/Pzc+nYhf05/vY8j9zFwOHLva57tnv+cnKeNs8PhyNGn011Iv08ZGRly5jLORbLveeBzcsrhCh8X4hxxvu30iT7l1V6YPuVXsXqc2JmOHz+urVu3qkqVKmrdurVKlSqlb7/91rV806ZN2rVrlzp06CBJ6tChg9atW6eDBw+61vn6668VGhqqxo0be71+AAAAAEDJV6yOeE+cOFH9+/dXzZo1tW/fPk2dOlX+/v4aPny4wsLCNGbMGN15552qUKGCQkNDdfvtt6tDhw5q3769JKlnz55q3LixbrjhBj355JOKj4/XlClTNH78+FyPaAMAAAAAcL6KVfDes2ePhg8frsTERFWsWFGXXXaZfvrpJ1WsWFGS9PTTT8vPz0+DBg1SWlqaevXqpX//+9+u1/v7++vzzz/XuHHj1KFDB4WEhGjUqFGaMWOGr7oEAAAAACjhilXwfvfdd8+6vHTp0nrhhRf0wgsv5LlOzZo1tXDhwqIuDQAAAACAXBXra7wBAAAAALjQEbwBAAAAAPAggjcAAAAAAB5E8AYAAAAAwIMI3gAAAAAAeBDBGwAAAAAADyJ4AwAAAADgQQRvAAAAAAA8iOANAAAAAIAHEbwBAAAAAPAggjcAAAAAAB5E8AYAAAAAwIMI3gAAAAAAeBDBGwAAAAAADwrwdQEAABQnu3btUkJCgq/LKJDIyEjVqFHD12UAAHDRIngDAJBPu3btUqOYGKWeOOHrUgokuEwZbfzjD8I3AAA+QvAGACCfEhISlHrihIY8/KIq1a7v63Ly5eD2LXp/yjglJCQQvAEA8BGCNwAABVSpdn1Vi2nu6zIAAEAxwc3VAAAAAADwIII3AAAAAAAeRPAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPIjgDQAAAACABxG8AQAAAADwIII3AAAAAAAeRPAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPIjgDQAAAACABxG8AQAAAADwIII3AAAAAAAeRPAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPIjgDQAAAACABxG8AQAAAADwIII3AAAAAAAeRPAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPIjgDQAAAACABxG8AQAAAADwIII3AAAAAAAeRPAGAAAAAMCDCN4AAAAAAHgQwRsAAAAAAA8ieAMAAAAA4EEEbwAAAAAAPIjgDQAAAACABxG8AQAAAADwIII3AAAAAAAeFODrAgAA52/Xrl1KSEjwdRkFFhkZqRo1avi6DAAAAI8ieANAMbdr1y41iolR6okTvi6lwILLlNHGP/4gfAMAgBKN4A0AxVxCQoJST5zQkIdfVKXa9X1dTr4d3L5F708Zp4SEBII3AAAo0QjeAFBCVKpdX9Vimvu6DAAAAJyBm6sBAAAAAOBBBG8AAAAAADyI4A0AAAAAgAcRvAEAAAAA8CCCNwAAAAAAHkTwBgAAAADAgwjeAAAAAAB4EM/xxkVr165dSkhI8HUZBRIZGakaNWr4ugwAAAAABUDwxkVp165dahQTo9QTJ3xdSoEElymjjX/8QfgGAAAAihGCNy5KCQkJSj1xQkMeflGVatf3dTn5cnD7Fr0/ZZwSEhII3gAAAEAxQvDGRa1S7fqqFtPc12WUaJzSDwAAgIsdwRuAx3BKPwAA8Ba+7MeFjOANwGM4pR8AAHgDX/bjQkfwBuBxnNIPAAA8iS/7caEjeAMAAAAoEfiyHxcqP18X4EsvvPCCatWqpdKlS6tdu3b6+eeffV0SAAAAAKCEuWiD93vvvac777xTU6dO1apVq9S8eXP16tVLBw8e9HVpAAAAAIAS5KI91XzWrFm65ZZbNHr0aEnSnDlz9MUXX+j111/Xvffe69PauCMjAAAAgAsRWaVwLsrgnZ6ert9++0333Xefq83Pz089evTQihUrcqyflpamtLQ0189JSUmSpMOHDyszM9P1ej8/PzmdTjmdTrft+vn5KSsrS2Z2zvZ9+/Yptm1bZf3/drNlZGRIkkqVKpXvdofDoYCAvz5iM1NmZmae7X5+fvL393e1O51OZWVlyd/fX35+f50ckZWVJafTqYCAADkcDkmn7si4fNky1ahRI0ef/P395XA4XGN1env29vLTHhAQIDNza3c4HPL3988x7nm1Z4/7sWPHVKpUKcVvXKuME8dPjYMccuivul3jk0v7qZ/yapccObaRV7vD9X/P9Z4Ju7ZJko4dO6bDhw/n6NP57nue+JySk5NVqlQp7d+4VuknUvI9vkXVXpjP6dDObSpVqpSSk5Nd41yU+54nPqfk5GRJ0t4//tqfz93X/O97nmpP3HVqrI8dO6bk5OQLao4437nDF3NEXu3nmjt8OUdkO/Pz8NbcUZSfU8LOrW5zx4U0R2S3S+6fx9nnDt/PEX+1SdmfU/a8kZyc7Pp77EKaI3L7nI4fP66AgIAz5o2/+pSzr96dI3JrT9y1zVX7kSNHLrg5Irf27Hkje5wvtDkit8/p4M5tcjgcbn9zXEhzRG7te/fu1WWXX67kpCSvZg1JyszMlJnl2X62nBRcpoyWLV2qatWqFem+d/ToUVcfz8Vh+VmrhNm3b5+qVaum//3vf+rQoYOr/e6779aSJUu0cuVKt/WnTZum6dOne7tMAAAAAMAFbvfu3YqOjj7rOhflEe+Cuu+++3TnnXe6fnY6nTp8+LAiIiLcvm25kCUnJ6t69eravXu3QkNDfV1OicZYewfj7B2Ms3cwzt7BOHsH4+w9jLV3MM7eURzH2cx07NgxVa1a9ZzrXpTBOzIyUv7+/jpw4IBb+4EDB1S5cuUc6wcFBSkoKMitLTw83JMlekxoaGix2ZGLO8baOxhn72CcvYNx9g7G2TsYZ+9hrL2DcfaO4jbOYWFh+VrvoryreWBgoFq3bq1vv/3W1eZ0OvXtt9+6nXoOAAAAAMD5uiiPeEvSnXfeqVGjRqlNmzZq27atnnnmGaWkpLjucg4AAAAAQFG4aIP30KFDdejQIT344IOKj49XixYttGjRIkVFRfm6NI8ICgrS1KlTc5wyj6LHWHsH4+wdjLN3MM7ewTh7B+PsPYy1dzDO3lHSx/mivKs5AAAAAADeclFe4w0AAAAAgLcQvAEAAAAA8CCCNwAAAAAAHkTwBgAAAADAgwjeAAAAAAB4EMEbAAAAAAAPIngDuKDxxEMAuDAxP6OkYZ8uepmZmUpLS3NrczqdPqrGt3iOdzG2a9cuLV++XA6HQ9WqVdPll1/u65JKpO3bt2vRokVKTU1V3bp1dfXVV/u6pBLpzz//1AcffKDExEQ1atRIV111lSpVqiTp1D+EDofDxxWWDPv27dO6detUqlQpRUVFqUmTJr4uqURifvYO5mfvYH72HvZp72Cf9o4NGzZoxowZ2rlzpxo1aqTWrVvr9ttvl3QqfPv5XVzHgAnexdS6devUs2dP1atXT6mpqVq/fr3+/ve/6x//+Idq1arl6/JKjPXr16tbt25q1qyZHA6Hvv/+ew0aNEh33HGHOnTo4OvySowNGzaoU6dO6tChg8qWLavPPvtMrVu31p133qkBAwZI4h/CorBu3Tr169dPVatW1ZEjR5ScnKy77rpL//jHPxQYGOjr8koM5mfvYH72DuZn72Gf9g72ae/YuHGjLr30Ul133XVq0qSJfv75Z3333Xfq3Lmz3nzzTUkXYfg2FDsHDhywRo0a2X333WdZWVmWlJRkr7/+ujkcDhs9erT9/vvvvi6xREhMTLSWLVva5MmTXW3fffed+fv7W58+feyrr77yYXUlx9GjR+2yyy6z++67z9W2ZcsWCwwMtBYtWthrr73mw+pKjn379lnt2rXt3nvvtZSUFNuyZYtNnTrVHA6HTZ482Y4cOeLrEksE5mfvYH72DuZn72Gf9g72ae9IT0+3W265xcaPH+9qO3bsmHXq1MkcDof169fP1e50On1Rok9cRF8xlBz79+9XWFiYxo8fLz8/P5UrV05t2rRRjRo19NZbb+nJJ5/0dYklQnJysvz8/DRs2DCZmdLS0tSkSRM1adJEcXFxmj17thITE31dZrGXmZmpEydOqHv37jIzpaSkqG7durr00kvlcDj0zjvvaN26db4us9jbuHGjoqOjNXnyZJUpU0b16tVT586dVa5cOT3++OOaOXOmr0ssEZifvYP52TuYn72Hfdo72Ke9o1SpUtq9e7cCAgIknRr3smXL6oorrtANN9ygTZs26d5775Wki+rMAoJ3MXTs2DH98ssv2rFjh6RTO2xAQIBiY2P12muv6a233tK7777r2yJLgOPHj2v16tXavXu3HA6HgoKClJKSoqioKD377LNauHCh5s+f7+syi72UlBRt3LhR+/btk8PhUEhIiHbv3q2UlBTde++9Wrt2LftzETh27JhWrVrlmjckKTw8XFdccYWefPJJPfnkk/rqq698V2AJwfzsHczP3sH87D3s097BPu15GRkZOnnypMqVK6cDBw5o3759CggI0K5du/TCCy/osssu0zXXXKNly5bp5MmTvi7Xu3x5uB0Fk30qxoEDB2zAgAF2xRVX2JtvvmmLFy+2ChUq2O23325mZiNGjLAJEyb4stRiKy0tzfXfGRkZdvPNN1vt2rVt5syZ9vbbb1v58uXt1ltvNTOzu+++2wYNGmTp6ekX1WkynnDfffdZqVKl7J577rGnn37awsLCbOzYsWZmNnv2bGvfvr0dO3aMcT4Pv//+u3Xu3NluvfVWW7Rokf30009WoUIFmzRpkmVlZVmPHj3smWee8XWZxRbzs+cxP/sG87PnsE/7Bvu0ZyQkJLj9vHz5cgsLC7MOHTrYwIEDrUyZMq5x/uOPPywwMNDWrl3ri1J9JsDXwR/nlpiYqBMnTujo0aNq2rSpKlWqpLFjx+rNN9/U+PHjVbFiRd1888164oknJEknTpxwO6qF/Nm0aZNmz56tUaNGKTY2VgEBAfrb3/6m0NBQPfHEE6pSpYpuu+02zZgxQ5J09OhRHT16VKVKlfJx5cXL3r17tXv3bu3bt089e/ZUcHCw7r//foWGhuq1115TVFSUJk6cqClTpkiSDh06JEkqW7asL8sudjZv3qyVK1dq2LBhKlWqlGJiYnTdddfp/fff15AhQxQSEqJRo0a5Tn1OT0/X2rVrfVx18cP87B3Mz97B/Ow97NPewT7tHZs2bVJMTIz+/ve/6/nnn5ckXXrppfr222/1n//8R+np6Xr22Wd18803y8y0d+9eNWjQQFWqVPFx5d5F8L7ArV27ViNHjpQkHT58WA0aNNATTzyh3r17q3fv3tq+fbucTqfq1q0r6dQfz6VKlVLz5s19WXaxc/LkSd1+++365ptvJEkBAQFq2bKl2rRpozZt2ujee++V0+lUVFSUpFN3u0xPT1eLFi3kdDrlcDguqmtUCmvt2rXq16+fatWqpQ0bNqhatWoaMWKExo0bp3vvvVd/+9vf5O/vr9DQUNdrDhw4oJiYGGVkZCggIIBxzoejR4+qY8eOSkxM1PHjxzV27Fj5+/tr7Nix6t27t1JSUpSenu6aJ1JSUlSuXDnFxsb6uPLihfnZO5ifvYP52XvYp72Dfdp7fv/9d0VEROijjz5SRkaGXnrpJUlS69at1bp1a7d1HQ6HFi1apNDQUNc14BcN3x5wx9ls27bNqlWrZg8++KD9+uuvtmbNGmvUqJHVq1fP5s6daykpKTnWf/DBB61ChQq2ceNGH1VdfN15553Wo0cPq1mzpl1//fX2yy+/uC3Pysoys1N3v5w8ebKFhYVxh+IC2Lt3rzVq1MimTp1qCQkJlpWVZcOGDbNSpUrZjTfeaAcPHjSzv07Z3bRpk919990WGhpq69ev92XpxdKwYcPs2muvNYfDYU899ZSdPHky1/X2799vDz74oFWsWNG2bNni5SqLL+Zn72J+9izmZ+9jn/Ys9mnvWrBggbVq1crmzp1rUVFRrkskzMwOHTrk+u81a9bYLbfcYqGhoRYXF+eLUn2K4H0Be/XVV61Xr16Wnp7umoBfffVV8/f3t9atW9tHH31kZqcmjYSEBBs2bJhFR0fbqlWrfFl2sZM9tjNmzLA5c+bYzz//bDVq1LDRo0fbrl277KGHHnJN0IcPH7bx48dbTEwM41xAX331lbVp08bi4+MtIyPDzMzi4uKsSpUq1rp1axs/frwrrBw9etSmTp1qbdu2tdWrV/uw6uInMzPTsrKy7Morr7T33nvPXn31VXM4HDZ79mwzM3v33XctOTnZzMx2795tN9xwg0VFRbE/FxDzs3cwP3sH87P3sE97B/u0dx08eNAGDhxo8fHx9uKLL1qlSpXsrrvusn/84x/27LPPWmpqqqWlpdl3331nI0eOtDVr1vi6ZJ8geF/AJk2aZE2bNnVr+/DDD23MmDHWtm1ba968uduyzZs32/bt271XYAmzaNEiGzJkiJmZff3111a7dm2rV6+elStXzrZt2+Zab+fOnbZ3715flVlszZs3z6pVq2bHjx93tS1dutS6dOli48ePtwYNGrj9gxcfH+/64wP5l/1H3dNPP20zZ840M7PnnnvOHA6HtWzZ0lq0aGH79u1zrb9ixQrbunWrT2otzpifvYv52bOYn72Pfdqz2Ke969ChQ1avXj375ZdfLC0tzd577z0LCQkxh8NhO3bscK2XkZFhqampPqzUt3ic2AXsyiuv1MGDBzV79mylpaVp/fr1GjlypC699FJ988032r17tz7++GNJktPpVP369VWrVi3fFl1MnDx5UllZWW5twcHBWr9+vSSpR48eqlevnnbs2KEuXbq4Pe6gRo0aqlq1qlfrLa5OH+c+ffooPT1dt99+u3799VctW7ZMffr0Uc+ePV034vjwww8lnbqeLSoqShUrVvRZ7cXJoUOHtH//fkmSn9+pab1UqVL64osvJEm33367YmNjFRcXp27durndzKR9+/aqU6eO94suhg4dOqR9+/ZJYn72JjNjfvaw3r17u647Zn72HDNz/Tf7tGf16dNHaWlp7NNe4HQ6FRkZqWbNmsnMFBgYqI8++kilSpVShQoV9PTTT7vWDQgIUOnSpX1YrW8RvC8g69ev1+TJk+V0OiVJjRs31q233qoHH3xQjRs3Vrt27XTzzTfrpptuUkBAgMqVK6fDhw9L+uuPbZzbhg0bNHr0aK1atUoZGRmu9pYtW6pevXqSpFGjRumPP/7Qc889pz/++EOTJ092/QOJ/Dl9nFNTU1WpUiV98MEH+vrrr3XVVVdpwIABuvXWW3XfffdJkurWravjx49LEjczKYANGzaoS5cu+vHHHyVJmZmZkqRWrVqpQoUKkqQbb7xRe/fu1cSJE/XCCy/okUcecfsDEOeWPc5Lly6VJDVo0ID52QP279+vhQsX6ptvvtG2bdsknZoPWrRowfxchE4f582bNysqKkoffvgh87MHHDt2TEePHtXx48fdxq558+bs00Xo9HHOyspy/c3x1VdfsU8XoR07dujll1/Wv//9b3377beS/vo3rlq1avrf//6nUaNG6ccff9SCBQv09NNP6/nnn9ddd93ly7IvGBfZreQuXGvWrFHbtm31wAMPuHbgyMhI3XnnnRo0aJA2b96siIgIdenSRdKpuxBXr179orsN//lav369Lr/8cg0ePFhRUVFuj+UICAjQvn37VLlyZTkcDn3++edq3bq1atWqpXvvvdcVYnBuZ45zcHCwJKlz587auHGjtmzZooCAAF1yySWSpIyMDDmdTtcRQTPjH8J8WLNmjS677DKdPHlSTz/9tAYOHOjapxs0aKBDhw6pdevW2rt3rxYuXKhWrVopIiJCTz75pMaNG8c+nU+nj/OsWbM0cOBAVa5cWRMnTmR+LkLr1q3TgAEDFBISogMHDqhz5856+umnVbVqVQUGBmr//v3Mz0Ugt3F+5pln1KVLF23atElbtmyRv78/83MRWLduncaMGSOHw6H9+/dr8ODBGj58uNq0aaNSpUrxN0cRyWucu3Tpoo0bN+rPP//kb44isG7dOnXt2lV16tTR8ePHtXHjRv3tb3/T+PHjdckll6h27dqaMGGC6tatq88//1ytWrVSs2bNNG/ePLVt29bX5V8YfHWOO/4SFxdnISEhNnHixHytn5GRYffcc4/VqFHDdu/e7eHqSo6kpCTr3Lmz3Xbbba627du32+bNm23//v1mZvbUU09Z165d7ddffzWzv+52eeYdipG33MZ527Zttnnz5lyvUzt8+LDdc889VqlSJfvzzz+9WWqxFhcXZ8HBwTZ58mRbsmSJ1a9f3xYsWGBmp+aIxMRE69Onj7Vu3dp+++03t9cePnzYFyUXS7mN82effWZmf11Pfzrm58LZtm2bVa5c2e69915LTEy0+fPnW9WqVW3Dhg2udWbNmmVdunRhfj4PuY1zlSpV3Mb5dMzPhbd161aLioqyCRMm2M8//2xPP/20NWnSxBo3bmzffvutmZ3ap/mb4/zkNs6NGze2xo0b29dff51jffbpwjl27JhdfvnlNmHCBDMzS05OtkWLFllERIQNGDDANm7caKmpqTZ69Ogcd+jP3q/BzdV8bufOnVa+fHkbMWKEmZ36o+3hhx+2m266ya655hr77rvv7OjRo671ly1bZjfccINFRkZyh8sCSk5Oto4dO9rGjRstIyPD+vfvb7GxsVahQgXr3LmzLV682MzMFcLN/posmDTy72zj3KVLF1doMTsVau68806rUqUK+3MB/PLLLxYcHGz333+/mZ36siMmJsauu+46t/XWrVvHjdPOQ37G+fS5gfm58GbNmmW9e/d2a+vVq5fNnz/fPv74Y9fjfZifz8+5xvn0L+mYn8/PtGnT7Nprr3VrmzRpkjkcDqtbt64tW7bM0tLSLD4+3rWcfbrgzjXO2V9ymJ16lBX7dOGcPHnSWrZsaa+99pqZ/fXF888//2zVq1e3AQMGWGZmJvvuOXDhmY/FxcWpWrVqCggI0Jo1a9S3b1999dVXOnr0qJKTkzVo0CDNnTvXdaON2NhYNWvWTMuXL1fLli19XH3xcvDgQW3YsEHHjx/XP//5T6WlpWn27Nn697//rfr16+vGG2/UkiVLVLlyZddrsk894hSk/DvXON966636/vvvJUlNmjTRFVdcoRUrVrA/F8Abb7yhMWPG6OGHH5bT6VRoaKgeeughLV682DW2knTJJZdw47TzkJ9xPn1uYH4uvIyMDO3YsUNbt26VJD3yyCP66quvNHv2bE2bNk3du3fXokWLmJ/P09nGefr06erXr58WLlwoifn5fB0+fNh1g9Hs+8k0bdpUV155pS655BI9/fTTSklJUVRUlOs17NMFd7Zxbtq0qV588UUlJiZKOnXvJPbpgjMzpaSk6NixYzp48KCkUzdUy8rKUmxsrD788EN99tlneuaZZ9h3z8XXyR+nnqvbtWtXK1++vPXu3dsOHDjg+ibpnnvusdDQUI5aFYGMjAy76qqrbOLEida3b19bsmSJa9nmzZttwIABdvfdd5vT6eQbu/OQ33HOzMz0YZUlz8aNG61Ro0b2yCOPmJkxvh5y5jhnz9W5nXaO/Pv444+tbdu2dskll9jw4cPN4XDYJ598YmlpabZjxw4bNWqUXXnllZacnMz8fB7yO85HjhzxdanF3kMPPWSVKlWyNWvW2LFjx2z37t1WsWJFe/nll+2DDz6wiIgI27Jli6/LLPYYZ+956qmnLDg42PV3XVZWlqWnp5uZ2aOPPmqNGze2Q4cOMUefBUe8fSj77sNDhw7VLbfcon79+mnq1KmqVKmSa53HH39cDodDixcv9lWZxZ79/92bAwICFBsbqzlz5ujrr792u9Nw/fr1FR4ernXr1snhcPCNXSEUdJz9/f19VWqxduZj8LI1bNhQQ4cO1cyZM7Vnzx7G9zzld5yz92/uXF442U/xuOaaazR58mRNmDBBVapU0ahRo3T11VcrMDBQNWvWVOXKlXXo0CGFhIQwPxdCQcc5NDTUxxUXX9lzx5QpU9SqVStdfvnl6ty5sxo1aqSBAwfqlltu0bXXXqtSpUrpl19+8XG1xRfj7FkJCQnatGmTli9f7mobPHiwrr76at16661atmyZ/Pz8FBBw6j7dkZGRrid6MEfnjb8UvOzQoUPasWOHpFMBJXviGD58uO655x7XqS/Zf8T9+eefqlGjhmJiYnxSb3G1b98+rVy5UtKpU7ZOn6BHjx6tzMxMvfTSS9q1a5frNcHBwapfv36ef3AjJ8bZO06fN3IL1NlfegwbNkzVq1fXu+++K+mvP7aRP4yzd5w+b/j5+bm+hL766qt10003qXLlykpJSXF75N2JEydUq1YtpaWl+aTm4ohx9p7Tx9rf3991yvOXX36pWbNmafz48XrzzTc1Z84cSdLmzZtVoUIFLgUqIMbZO9avX68+ffrommuu0RVXXKGBAwdKkqpXr66///3vaty4sUaMGOG6LEWStmzZotDQUKWnp/uq7OLBl4fbLza///67hYWF2dChQ23Xrl2u9rOdEjplyhRr1qxZrneDRu7++OMPCw8Pt+7du9vy5ctd7dmnw5iZ3X777ValShXr0qWL3XPPPXbTTTdZWFiY6wY+ODfG2TvymjfyMnz4cIuJifFCZSUL4+wdec0bp5+q/8orr1jlypXtlVdesU8//dTuu+8+Cw8Pt3Xr1vmi5GKJcfaevMY6IyMj1/UzMjJsypQp1qhRI7ebBeLsGGfv2Lhxo1WsWNEmT55sP/30ky1dutTKly9v9957r2ud3377zcaNG2cOh8Natmxp7du3t/DwcFu9erXvCi8mCN5eEh8fb5deeql169bNypYta8OHDz/rH3effvqp/fOf/7SwsDB25AI4cOCAde7c2Xr27GkxMTHWv39/twk6LS3N9d9vvPGGjRs3zi699FK74YYbbO3atb4ouVhinL2jIPNG9h/UK1eutNq1a/OHRgEwzt5xrnnj9FB4yy23WI0aNaxOnTp26aWXWlxcnC9KLpYYZ+8pyFibma1atcrGjRtnoaGh3FW7ABhn7zh27JgNGTLExo8f73ad9r333mv9+vXLsf53331nM2fOtH//+988mi2fCN5e8t1339nQoUNt8+bN9vPPP1vp0qXP+sfdI488Ym3btiWkFFBcXJxdd9119uuvv9q6deusUaNGOSbo04/IZv/MjagKhnH2joLOG2anHnmVkJDgxSqLP8bZOwo6b6xZs8a2b99uiYmJvii32GKcvSc/Y316gFm9erU99thj9vvvv/ui3GKLcfaOlJQUGzRokL344otu7W+99ZY1bNjQ0tLS3A6soOAI3l5y8OBBW758uWti+Omnn1x/3O3cudO13unB5PDhw16vs7hLSUmxdevWucZ5zZo1rgl62bJlrvXODIUoGMbZO/I7b3BH7fPDOHtHfueNkydP+qrEEoFx9p78jvXpp0Pz72LBMc6elz22Bw4ccLVl/5v3/vvvW/Pmzd3WP3TokNdqK0kI3j6QPRmsXLnS7chKRkaGPfPMM7ZgwQIfV1gyZI/z2rVr3b4dzczMtOnTp9ubb77p4wpLBsbZO841byxcuNDHFZYMjLN3MG94B+PsPeca63nz5vm4wpKBcfaO079o/uijj6xJkyaunydNmmRDhw7ly7tCcJiddjtLeE1WVpb8/f31yy+/qFOnTq47Bn766adatWqVGjRo4OMKS4bscV6/fr0GDx6shg0byul06ptvvtEvv/yiJk2a+LrEEoFx9g7mDe9gnL2DecM7GGfvYay9g3H2HDPL8TiwBQsW6I477tDWrVt1//33a+bMmVq6dKnatm3royqLMR8H/4tG9inkp1+Dkv1t0vLly83hcFj58uXtt99+80l9JUX2OJ/+TV32f69atco1ztyw7vwwzt7BvOEdjLN3MG94B+PsPYy1dzDO3pE9zklJSXbkyBFX+8cff2wdOnSwBx980AIDA/m38DzwHG8Pyn62a/Y3c3v37tX777+vkydPSjr1XM3U1FR98MEHKleunJYvX65WrVr5suRiKXucMzMz5e/vrz179mjWrFlKSkqSdGqcT548qddff13lypXT0qVL1aJFCx9WXDwxzt7BvOEdjLN3MG94B+PsPYy1dzDOnmNnnOxsZq5x3rFjh2JiYrRixQrX8qysLP3000964YUX9L///Y9/C88DwbsIJScn68CBAzpy5IikU5NCRkaG/P39tXPnTjVt2lTr169X6dKlXa/ZvHmzPv/8c3399deKiYnxVenFyuHDh7V9+3Zt27ZN0qlxdjqdCggI0I4dO9SqVSsdOnRIYWFhrtckJCTou+++01dffcUpSPnEOHsH84Z3MM7ewbzhHYyz9zDW3sE4e8emTZs0depU3XjjjXr11Ve1ceNGORwOBQQEaNeuXWrTpo369u2r3r17u17TqlUrNWvWTN9//71at27tw+pLAF8fci8p1q5da5deeqnVqVPHYmNjbfTo0a67KyYmJlp4eLiNHTvW7VRGs1N3FT169KgvSi6W1qxZY82bN7eaNWta3bp1rVevXq67Dh8/ftzKlStnt9xyS45xNjM7ceKEt8stthhn72De8A7G2TuYN7yDcfYexto7GGfv2LBhg4WFhdmgQYPs0ksvtXbt2ll0dLR9/fXXZmb27LPP2h133JHrZVepqak+qbmkIXgXgR07dljFihXtrrvusv/+97/25JNPWv369a1p06a2ZcsWO3DggL311ls8iuY87d6926pWrWr33nuv/fDDD/bBBx9Y69atrWbNmvbNN99Yenq6ff7554zzeWKcvYN5wzsYZ+9g3vAOxtl7GGvvYJy9IzMz066//nobMWKEq2316tV28803m7+/v3311Veu9eA5BO8i8N///tfatGljSUlJrratW7dau3btrHHjxq5n4rEzn5/vvvvOGjdubPv27XO1ZWZmWp8+faxy5cq2YsUKM+NZu+eLcfYO5g3vYJy9g3nDOxhn72GsvYNx9o709HTr3Lmz3XvvvW7tBw8etFtvvdWCg4NdYw3P4RrvIrB//37t2LFDoaGhkk7dEKJOnTr6+OOPFRAQ4HoUjb+/vy/LLPYSEhK0b98+VahQQZKUnp4uf39/LVy4UE2aNNFNN90kM5OfH7v1+WCcvYN5wzsYZ+9g3vAOxtl7GGvvYJy9o1SpUrrkkku0ZMkS171OJKlixYqaPHmy+vbtq4ceekjJyck+rLLkYy8uJDvtjoD9+/dX6dKl9fjjj0v664YQVapU0YsvvqgDBw7ovffe81WpxV72WPfp00dly5bVXXfdJUkKDAxUenq6JOnNN99UWlqaZs6c6bM6i7Psu4dKp8a5XLlyjLOHZO/P/fv3V1BQEPOGBzA/ew/zs+cxP3sX+7TnsU/7RqdOnZSamqq5c+fq2LFjrvbq1aurf//+iouLc901Hp5B8C6ETZs26c0331RmZqYkqUKFCho0aJAWLVqk//znP5Lk+mbukksukZ+fn7Zu3eqzeour1NRUOZ1O1wQcEhKiu+++W0uXLtW//vUvSacmaKfTqYiICEVHRys+Pt6XJRdLv//+ux555BGlpaXJzBQcHKyJEydq+fLljHMRSktLkyTXvBEeHq7Bgwdr4cKFzBtFiPnZO5ifvYP52XvYp72Dfdo7duzYoVdeeUWvvfaaFi9eLEkaMmSILrvsMr300kt6++23dfjwYdf6sbGxKlOmjFsgR9EjeBfQmjVrFBMTo6SkJAUEBEiSypYtq/HjxyskJESvvPKK5s6d61o/NDRUderUUVBQkKScz85D7tavX6/+/furY8eOat26td566y0lJSVp5MiR6tSpk959913NmDFD0qk/ooOCglShQgWVKlVKEuOcX2vWrFHTpk0VGBiooKAgORwO+fv7a9CgQerYsaPee+89xrkIbNiwQcOHD9cVV1yh/v37a8mSJQoNDdWECRMUGhqql156iXmjCDA/ewfzs3cwP3sP+7R3sE97x7p169SmTRu9/vrreuyxx3Tttddq9OjROnbsmGbPnq3LL79c//73v/XQQw9p69atSkhI0BtvvCE/Pz9FRUX5uvySzXuXkxd/a9assZCQEJs0aZJbe/ZNedatW2eDBw+2Zs2a2fXXX29vvfWW3XrrrRYaGmqbN2/2RcnF0tatW618+fI2fvx4mz17tt1+++0WHh5uN998s/355592+PBhu+eee6xOnTrWo0cPe/zxx+2mm26ysmXL2h9//OHr8ouNc+3PO3bssLvvvptxPk+bN2+20NBQGzt2rE2aNMmuvfZaczgcNmXKFEtJSbHt27fbkCFDrGnTpswb54H52TuYn72D+dl72Ke9g33aO44dO2YdOnSw22+/3czM9u/fb19++aVVqFDBunfv7rqh6PTp0+3yyy83h8NhrVu3tsqVK9uqVat8WfpFgeCdT5s2bbJy5crZ2LFjzezU3RXnzJljkyZNsokTJ9qmTZvM7NRjEV555RVr1aqVxcbGWteuXS0uLs6XpRc7M2fOtE6dOrm1vfPOO9a0aVMbMWKE7dy501JSUuybb76xnj17Wrdu3eyqq66yNWvW+Kji4mfbtm1Wvnx5u+6668zs1P78+OOP280332yDBw+277//3szMkpOTGefzNGXKFOvZs6db23PPPWcVKlSwiRMnWnp6uu3bt89effVV5o1CYn72HuZnz2N+9i72ac9jn/ae1NRUa9Wqlb377rtu7Zs2bbLIyEi78sorXW0HDhywL7/80pYtW2a7d+/2dqkXJYJ3Pr311lvmcDhs1qxZtn37duvcubNdfvnl1q5dO4uNjbXAwED77LPP3F6TmprKA+cLYebMmdaiRQs7duyY2+MjPvjgA6tXr57dd999OV6Tnp7uzRKLvQULFlh0dLT985//tF9//dW6du1qXbt2tX79+lnv3r3N4XDY7Nmzc7yOcS64u+66yxW8MzIyXO1z5syxMmXK2AsvvOC2PvNGwb3xxhvMz17C/Ox5zM/exT7teezT3nP8+HGrVq2aTZ8+3dWWPY7ZZx1MmzbNV+Vd9AjeBfDss89a1apVrUaNGnbVVVfZ7t277eTJk5aammq33nqrhYWF8Y1REXjvvfcsODjYdcpLWlqaa9mLL75ogYGBtn79erfXOJ1Or9ZYEsyfP99at25tVapUsX79+ll8fLxrcn7ooYesdOnSOU7vYpzz5/jx467/fu6556xcuXK2d+9eM3Pfn6dPn24hISG2c+dOr9dYEhw7dsz138zP3vGf//yH+dkL3n77beZnL3n33XfZp72Avzm856mnnrLo6GhbsGCBqy17rB9++GFr166dJSYm8mx0HyB4n8WWLVvs559/dmubPXu2tWvXzn799Ve39t9//90iIiJyHFXBuW3ZssU++ugjO3nypKttwIABVr16dde1KKcvq1evnj333HNer7O4yx7nEydOuNr+85//2FVXXWUrVqxwW/fo0aNWsWJFe+mll7xdZrG3ceNGu/76611h+vjx49alSxdr3769JSQkmJm5jrTu37/fqlevbh999JHP6i2ussd5x44drjbm56KXkpJihw8fdps3rr76aubnIpY9zqd/affOO+8wP3vJVVddxT7tBW+//Tb7dBHbt2+frVy50hYtWuS6Xn779u02ePBgu/zyy23x4sVu68+ZM8diYmIsJSXFF+Ve9LireR7i4uLUunVrxcXFSfrrmYO33XabXnrpJTVu3FjSX3dYzMjIUKVKlVSlShWf1FtcrV27Vpdeeqm+/PJLJSYmusbzoYceUnR0tNq3b689e/a47jp84sQJlStXTuXLl/dl2cXO6eN85MgR1zgPGzZMjz32mFq0aCHpr/05ISFBVapUUb169XxVcrG0Zs0atWzZUu+8846+++47SVKZMmU0adIkORwODR06VIcPH1bp0qUlSUFBQQoJCXHdsRX5c/o4f//996525ueitWHDBg0dOlQdO3bUddddpwULFkiSHnnkEdWoUYP5uYicPs7XX3+9PvvsM0nSddddp8cff5z5uQht2rRJ9913n2644QbNnDlTq1atkiTNmjVLVatWZZ8uImeO82+//SZJGjFihB5++GH26SKydu1adejQQTfccIOGDh2qJk2a6N1331W1atV09913KywsTFOmTNG7774r6dS/hdu2bVOlSpWUlZXl4+ovUj4M/ResuLg4K1OmjN155535fs0999xjbdq0sYMHD3qwspJl586dVqNGjRx3uMy2du1au/zyyy08PNxeeukl+89//mP33nuvRURE2NatW71cbfF1rnHOzf3332/NmjWzffv2ebCykiUuLs6Cg4Pt7rvvtokTJ9rll1/uOr08KyvL3n//fevQoYPVrl3bFi9ebN99951NmTLFKleuzKnmBZDbOO/fv/+spyQyPxfchg0bXHd6njNnjnXs2NGGDx9uZqdO//zll1+sU6dOzM/nKbdxvu666866PzM/F86GDRssPDzcBg8ebLfeeqtVr17dWrRoYS+//LKZnXryAX9znL/cxrlVq1b2/PPP5/ka9umCO3jwoDVq1MgmT55sW7dutb1799rQoUOtQYMGNn36dDt58qTFxcXZrbfeagEBAda8eXNr3769lS9f3lavXu3r8i9aBO8zbN682YKCguz+++83s1PXRHz22Wf28ssv26effup2TaGZ2fLly+0f//iHhYeHc3fcAlqwYIH17dvXzE6N8/3332/XXHON3XTTTTZ//nwzO3W61z/+8Q+LiYmxhg0bWrt27XjcQQHlNc4333yzvfHGG27rLlq0yMaPH8/EXEC//vqrhYaG2uTJk83s1Cn8YWFhtmzZMtc6TqfT4uLibMSIEVaxYkVr0KCBNWnSxH777TdflV3snGucz7xejfm5cE6cOGHXXHON/fOf/3S1ffrppzZgwADbv3+/6zRc5ufzc7ZxPnDggNvf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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ - "import pandas as pd\n", - "from sklearn.feature_extraction.text import TfidfVectorizer\n", - "from wordcloud import WordCloud\n", - "import matplotlib.pyplot as plt\n", - "import math\n", - "\n", "def create_period_label(example, period_length=50):\n", - " \"\"\"Crée une étiquette textuelle (ex: '1880-1899') pour chaque période.\"\"\"\n", - " try:\n", - " # Gérer les dates potentiellement non numériques ou vides\n", - " year_str = str(example['date']).strip()\n", - " if not year_str.isdigit():\n", - " # Retourne une étiquette spéciale ou None si la date n'est pas valide\n", - " # Ou essayez d'extraire l'année si c'est une plage comme \"188?-1890\"\n", - " # Pour simplifier, on ignore les dates non valides ici.\n", - " return {\"period\": None}\n", - " year = int(year_str)\n", - " start_year = (year // period_length) * period_length\n", - " end_year = start_year + period_length - 1\n", - " # Gérer les années avant 0 si nécessaire, bien que peu probable pour ce dataset\n", - " if start_year < 0:\n", - " start_year = 0\n", - " end_year = period_length -1\n", - " return {\"period\": f\"{start_year}-{end_year}\"}\n", - " except (ValueError, TypeError):\n", - " # Gère les erreurs de conversion ou les types inattendus\n", - " return {\"period\": None}\n", + " \"\"\"\n", + " Crée une étiquette de période basée sur l'année de publication.\n", + " \"\"\"\n", + " try:\n", + " year = int(example['date'])\n", + " start_year = (year // period_length) * period_length\n", + " end_year = start_year + period_length - 1\n", "\n", - "# Création des labels de période (ex: 20 ans)\n", - "# Filtrer les exemples sans date valide AVANT le map\n", - "dataset_with_dates = cleaned_ds.filter(lambda x: str(x.get('date', '')).isdigit())\n", - "dataset_with_labels = dataset_with_dates.map(create_period_label)\n", + " return {\"period\": f\"{start_year}-{end_year}\"}\n", + " except (ValueError, TypeError):\n", + " return {\"period\": None}\n", + " \n", + "dataset_with_labels = cleaned_ds.map(create_period_label)\n", "\n", - "# --- Groupement des textes par période ---\n", - "# Convertir en DataFrame pandas pour faciliter le groupement\n", "df = pd.DataFrame(dataset_with_labels)\n", "\n", - "# Vérifier les colonnes après conversion en DataFrame\n", - "print(\"Colonnes du DataFrame:\")\n", - "print(df.columns)\n", - "print(\"\\Aperçu des données avec périodes:\")\n", - "print(df.head())\n", - "\n", - "# Filtrer les lignes où 'period' est None si le filtrage précédent n'a pas tout attrapé\n", - "df = df.dropna(subset=['period'])\n", - "\n", - "# Grouper les textes par période\n", "grouped_texts = df.groupby('period')['text'].apply(list)\n", "\n", - "# Afficher les périodes trouvées et le nombre de textes par période\n", - "print(\"\\nPériodes et nombre de textes:\")\n", - "print(grouped_texts.apply(len))" + "period_counts = grouped_texts.apply(len).sort_index()\n", + "\n", + "plt.figure(figsize=(10, 6))\n", + "period_counts.plot(kind='bar', color='skyblue', edgecolor='black')\n", + "\n", + "plt.title('Nombre de textes par période', fontsize=16)\n", + "plt.xlabel('Période', fontsize=12)\n", + "plt.ylabel('Nombre de textes', fontsize=12)\n", + "plt.xticks(rotation=45, ha='right')\n", + "plt.grid(axis='y', linestyle='--', alpha=0.7)\n", + "plt.tight_layout()\n", + "\n", + "plt.show()" ] }, {