From 61298d63848c04efe1ea8437928c871c5b1688e0 Mon Sep 17 00:00:00 2001 From: Nikolaz Date: Mon, 28 Sep 2026 08:58:23 +0200 Subject: [PATCH] =?UTF-8?q?Refonte=20export=20PDF,=20colonne=20commentaire?= =?UTF-8?q?=20et=20UX=20r=C3=A9sum=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Export PDF: nouveau nommage AAAAMM/AAAA_Trajets_MATRICULE_PLAQUE.pdf, logo carré embarqué en en-tête, km formatés selon Precision_Distance, restructuration en-têtes (Domicile déplacé, période/année fusionnées au titre) - Correction bug: le nom de fichier suggéré au téléchargement ne remontait pas au frontend (CORS WithExposedHeaders manquant + composants résumé ne lisaient pas Content-Disposition) - Résumé mensuel: colonne Commentaire, sélecteur temporel unifié (auto-chargement), km selon précision - Résumé annuel: bouton Export PDF repositionné, km selon précision - Panneau totaux: renommage "Remboursement indicatif" + infobulles d'aide (icône) au lieu du texte permanent - Ajout de PdfServiceIntegrationTests (3 tests), 65/65 tests backend OK - Mise à jour requirements.md et design.md en conséquence --- .kiro/specs/schotziad-km-tracker/design.md | 97 +++--- .../schotziad-km-tracker/requirements.md | 19 +- .../Assets/logo-carre.png | Bin 0 -> 136254 bytes .../Controllers/ExportsPdfController.cs | 7 +- backend/SchotzIadKmTracker.Api/Program.cs | 7 +- .../SchotzIadKmTracker.Api.csproj | 5 + .../Services/PdfService.cs | 304 +++++++++++------- .../PdfExport/PdfServiceIntegrationTests.cs | 169 ++++++++++ .../src/app/core/services/trajet.service.ts | 38 ++- .../panneau-totaux.component.html | 36 ++- .../panneau-totaux.component.scss | 29 +- .../resume-annuel.component.html | 31 +- .../resume-annuel.component.scss | 8 + .../resume-annuel/resume-annuel.component.ts | 22 +- .../resume-mensuel.component.html | 41 +-- .../resume-mensuel.component.scss | 21 +- .../resume-mensuel.component.ts | 46 ++- 17 files changed, 614 insertions(+), 266 deletions(-) create mode 100644 backend/SchotzIadKmTracker.Api/Assets/logo-carre.png create mode 100644 backend/SchotzIadKmTracker.Tests/PdfExport/PdfServiceIntegrationTests.cs diff --git a/.kiro/specs/schotziad-km-tracker/design.md b/.kiro/specs/schotziad-km-tracker/design.md index 7961fae..f0aba87 100644 --- a/.kiro/specs/schotziad-km-tracker/design.md +++ b/.kiro/specs/schotziad-km-tracker/design.md @@ -20,7 +20,7 @@ | 4 | Vue annuelle | 12 résumés mensuels + total annuel | | 5 | Modification / suppression | Édition avec recalcul conditionnel de distance | | 6 | Persistance et cohérence | Base relationnelle avec invariants d'agrégation et transactions | -| 7 | Export PDF | Fichiers `trajets_MM_AAAA.pdf` et `trajets_AAAA.pdf` | +| 7 | Export PDF | Fichiers `AAAAMM_Trajets_MATRICULE_PLAQUE.pdf` et `AAAA_Trajets_MATRICULE_PLAQUE.pdf` | | 8 | Visualisation carte | Tracés des itinéraires d'une journée sur carte Leaflet + OpenStreetMap | | 9 | Cache adresses | Stockage des coordonnées BAN des adresses saisies, autocomplétion BAN + cache local, politique LRU (1 000 entrées) | | 10 | Profil / adresse domicile | Saisie du domicile, bouton "Utiliser mon domicile" dans le formulaire | @@ -248,14 +248,16 @@ src/ - Si l'utilisateur tape une adresse sans passer par BAN (pas de sélection), les coordonnées sont absentes et un avertissement discret s'affiche **`ResumeMensuelComponent`** -- Sélecteurs mois (1–12) et année (2000–2100) -- Affiche la liste des trajets et le total mensuel (2 décimales) -- Bouton "Export PDF mensuel" +- Réutilise le même `SelecteurTemporelComponent` que `ConsultationJourComponent` (sélection successive année puis mois, surbrillance des périodes ayant des données) au lieu de sélecteurs distincts mois/année ; la sélection d'un mois (événement `moisSelectionne`) déclenche automatiquement le chargement du Résumé_Mensuel, sans bouton "Afficher" sur cet écran +- Affiche la liste des trajets, avec une colonne **Commentaire** entre les colonnes Date et Départ (valorisée avec le commentaire du Trajet, ou « — » si absent), et le total mensuel +- Bouton "Export PDF mensuel" positionné à droite du `SelecteurTemporelComponent` +- La Distance de chaque Trajet et le total mensuel sont formatés selon `formatKm()` (pipe `number` alimenté par le signal `precisionDistance` de `ParametresApplicationService`), reflétant Precision_Distance (0, 1 ou 2 décimales) au lieu d'un affichage fixe à 2 décimales — voir spec `precision-distances-km` **`ResumeAnnuelComponent`** -- Sélecteur année (2000–2100) -- Tableau 12 lignes (mois, total km) + ligne total annuel (2 décimales, max 999 999,99) -- Bouton "Export PDF annuel" +- Sélecteur année (2000–2100) et bouton "Afficher" **inchangés** (pas de remplacement par `SelecteurTemporelComponent` sur cet écran — décision explicite de l'utilisateur, à la différence du Résumé_Mensuel et de la Vue_Consultation) +- Tableau 12 lignes (mois, total km) + ligne total annuel (max 999 999,99) +- Bouton "Export PDF annuel" positionné à droite du formulaire sélecteur/bouton "Afficher" (même agencement visuel que sur le Résumé_Mensuel), sans changement de comportement +- Le total kilométrique de chaque mois et le total annuel sont formatés selon `formatKm()`, reflétant Precision_Distance au lieu d'un affichage fixe à 2 décimales — voir spec `precision-distances-km` **`TrajetListComponent`** - Affiche TOUS les trajets du mois, regroupés par journée : chaque groupe/jour a un **en-tête repliable** (jour de la semaine avant la date, ex. « Lundi 15/09/2026 », puis nombre de trajets) ; par défaut tout est replié sauf le dernier jour du mois ayant des trajets. @@ -326,7 +328,8 @@ src/ - Affiche trois totaux : total du jour ciblé par la navigation, total du mois sélectionné, Total_Annuel_Partiel (cumul de l'année jusqu'au mois sélectionné inclus) - Reçoit en entrée la date sélectionnée et recalcule les totaux à chaque changement - Tous les totaux affichés à 2 décimales, calculés par sommation de distances déjà arrondies selon Precision_Distance (voir spec `precision-distances-km`, Requirement 5) -- Affiche également le Montant_Previsionnel_Mensuel (80%, désormais calculé sur le seul mois affiché) et, en dessous, une nouvelle ligne « Montant prévisionnel annuel » présentant le Montant_Previsionnel_Annuel (100%, sur le Total_Annuel_Partiel) — détail complet du calcul dans la spec `precision-distances-km`, Requirements 7 et 8 +- Affiche le libellé **« Remboursement indicatif »** (renommé, anciennement « Indication de versement (80%) ») présentant le Montant_Previsionnel_Mensuel (80%, calculé sur le seul mois affiché) et, en dessous, une ligne « Montant prévisionnel annuel » présentant le Montant_Previsionnel_Annuel (100%, sur le Total_Annuel_Partiel) — détail complet du calcul dans la spec `precision-distances-km`, Requirements 7 et 8 +- **Infobulles d'aide** : le texte explicatif de chacune de ces deux lignes (« Remboursement indicatif » et « Montant prévisionnel annuel »), auparavant affiché en permanence sous le montant, est retiré du flux visuel et remplacé par un bouton icône (SVG inline `help-circle`, 16×16, `aria-label` dédié) affiché juste après le libellé ; le texte explicatif est porté par l'attribut HTML `title` de ce bouton et s'affiche via l'infobulle native du navigateur au survol ou au focus clavier de l'icône **`ParametresApplicationComponent`** - Nouveau composant du Sous_Menu_Application de la Page_Parametrage, positionné entre « Compte » et « Véhicules » @@ -1537,19 +1540,17 @@ QuestPDF est une bibliothèque .NET open-source (licence MIT pour usage communau ### Structure des documents PDF -#### PDF Mensuel (`trajets_MM_AAAA.pdf`) +#### PDF Mensuel (`AAAAMM_Trajets_MATRICULE_PLAQUE.pdf`) ``` ┌────────────────────────────────────────────────────────────────────────────┐ -│ FEUILLE D'INDEMNITÉ KILOMÉTRIQUE MENSUELLE │ -│ Cécile DOUCET │ -├────────────────────────────────────────────────────────────────────────────┤ -│ Véhicule : GOLF (ES-036-YF) — 6 CV (Coef. : 0,447 / Base : 0) │ -│ Période : JANVIER 2025 Total parcouru sur le mois : 931 Kms │ -│ Coef. : 0,447 Total parcouru sur l'année : 931 Kms │ -│ Base : 0 TOTAL IK du mois : 416,16 € │ -│ Adresse de départ : 29 route des Cascades, 23400 Saint-Pardoux-Morterolles │ -│ Réglé : 500,00 € │ +│ [Logo] Rapport de trajets │ +│ Feuille d'indemnité kilométrique JANVIER 2025 │ +│ Utilisateur : Cécile DOUCET — Matricule : AB12CD34 │ +│ Domicile : 29 route des Cascades, 23400 Saint-Pardoux-Morterolles │ +│ Véhicule : GOLF (ES-036-YF) — 6 CV (Coef. : 0,447 / Base : 0) │ +│ Total parcouru sur le mois : 931 Kms TOTAL IK du mois : 416,16 € │ +│ Total parcouru sur l'année : 931 Kms Réglé : 500,00 € │ ├────────────┬──────────────────────────┬──────────────────────────┬─────────┤ │ Date │ Motifs (commentaire) │ Adresse départ → arrivée │ Kms │ ├────────────┼──────────────────────────┼──────────────────────────┼─────────┤ @@ -1558,20 +1559,25 @@ QuestPDF est une bibliothèque .NET open-source (licence MIT pour usage communau └────────────┴──────────────────────────┴──────────────────────────┴─────────┘ ``` -> Le « TOTAL IK du mois » = kilomètres du mois × coefficient de la tranche annuelle applicable. Le « Réglé » = Montant_Regle saisi pour le mois. Le motif affiché est le commentaire du Trajet. +> Le titre du document intègre désormais le mois et l'année (« Feuille d'indemnité kilométrique JANVIER 2025 ») ; il n'y a plus de ligne « Période » distincte dans l'en-tête. Le libellé « Adresse de départ » devient « Domicile » et est positionné juste après la ligne Utilisateur/Matricule (au lieu d'être après la ligne Véhicule). Le « TOTAL IK du mois » = kilomètres du mois × coefficient de la tranche annuelle applicable. Le « Réglé » = Montant_Regle saisi pour le mois. Le motif affiché est le commentaire du Trajet. Les kilomètres (mois, année, table des trajets) sont formatés selon Precision_Distance. -#### PDF Annuel (`trajets_AAAA.pdf`) +#### PDF Annuel (`AAAA_Trajets_MATRICULE_PLAQUE.pdf`) ``` ┌──────────────────────────────────────────────────────────────────────────────┐ -│ SYNTHÈSE 2025 D'INDEMNITÉ KILOMÉTRIQUE │ -│ Nom : Cécile DOUCET Année : 2025 │ -│ Domicile : 29 route des Cascades, 23400 Saint-Pardoux-Morterolles │ +│ [Logo] Rapport de trajets │ +│ Synthèse 2025 d'indemnité kilométrique │ +│ Utilisateur : Cécile DOUCET — Matricule : AB12CD34 │ +│ Domicile : 29 route des Cascades, 23400 Saint-Pardoux-Morterolles │ +│ Véhicule : GOLF (ES-036-YF) — 6 CV │ +│ Barème applicable : 5001–20000 │ +│ Total kilométrique de l'année : 12 241 km │ ├──────────────────────────────────────────────────────────────────────────────┤ -│ Barème applicable pour l'année (par puissance fiscale) : │ -│ PF │ ≤5000 (coef/base) │ 5001–20000 (coef/base) │ >20000 (coef/base) │ -│ 6 CV │ 0,665 / 0 │ 0,374 / 1457 │ 0,447 / 0 │ -│ Véhicule : GOLF (ES-036-YF) Total Kms : 12 241 Barème applicable : D2 │ +│ Barème applicable pour l'année (6 CV) : │ +│ Tranche (km) │ Coefficient │ Base (€) │ +│ 0 à 5000 │ 0,665 │ 0 │ +│ 5001 à 20000 │ 0,374 │ 1457 │ +│ 20000 et plus │ 0,447 │ 0 │ ├────────────┬───────────────┬───────────────────┬────────────────────────────┤ │ Mois │ Kms parcourus │ Frais payé (réglé)│ Frais réel │ ├────────────┼───────────────┼───────────────────┼────────────────────────────┤ @@ -1586,28 +1592,45 @@ QuestPDF est une bibliothèque .NET open-source (licence MIT pour usage communau └──────────────────────────────────────────────────────────────────────────────┘ ``` -> Le « Frais réel » mensuel = kilomètres du mois × coefficient de la tranche annuelle. Le « Frais payé » = Montant_Regle saisi. La minoration 80% n'apparaît pas dans la synthèse : elle sert uniquement d'indication de versement en cours d'année. +> La ligne « Année : AAAA », auparavant présente dans l'en-tête, est retirée : elle est redondante avec le titre « Synthèse {Année} d'indemnité kilométrique ». Le « Frais réel » mensuel = kilomètres du mois × coefficient de la tranche annuelle. Le « Frais payé » = Montant_Regle saisi. La minoration 80% n'apparaît pas dans la synthèse : elle sert uniquement d'indication de versement en cours d'année. Les kilomètres (total annuel, table des mois, formule réelle) sont formatés selon Precision_Distance. > **Rapports distincts par véhicule** : si la période demandée (mois ou année) contient des Trajets associés à plusieurs Véhicules, le backend génère un fichier PDF distinct par Véhicule. Chaque PDF ne contient que les Trajets et montants du Véhicule concerné. ### En-tête obligatoire (Exigence 7.6) Tous les PDF incluent en en-tête : -1. Titre fixe : **"Rapport de trajets"** -2. Période couverte : `Mois AAAA` pour le mensuel, `AAAA` pour l'annuel -3. Total kilométrique de la période +1. Le **logo carré** de l'Application, en haut à gauche (voir « Logo dans l'en-tête » ci-dessous) +2. Titre fixe : **"Rapport de trajets"**, suivi du titre spécifique intégrant la période (`Feuille d'indemnité kilométrique {Mois} {AAAA}` pour le mensuel, `Synthèse {AAAA} d'indemnité kilométrique` pour l'annuel) +3. Total kilométrique de la période, formaté selon Precision_Distance -### Nommage des fichiers +### Logo dans l'en-tête (Exigences 7.13) -- Mensuel : `trajets_MM_AAAA.pdf` (ex. `trajets_01_2025.pdf`) -- Annuel : `trajets_AAAA.pdf` (ex. `trajets_2025.pdf`) +Le logo carré (`logo-carre.png`, cf. section Charte graphique) est **embarqué comme ressource** dans l'assembly du backend (`Assets/logo-carre.png`, copié depuis les assets du frontend au moment du build) plutôt que lu depuis le système de fichiers, pour rester indépendant du répertoire de travail au runtime. `PdfService` charge ces octets une seule fois via `Assembly.GetManifestResourceStream`, en cache statique, et les insère via `Image().FitWidth()` dans une colonne fixe (45 pt) à gauche de la colonne de texte de l'en-tête, pour les deux rapports (mensuel et annuel). Si la ressource est introuvable (tableau vide), le logo est simplement omis sans faire échouer la génération du PDF. + +### Precision_Distance dans les PDF (Exigence 7.12) + +`PdfService` récupère la valeur courante de Precision_Distance via `IPrecisionDistanceService` avant le rendu, et l'applique à tous les kilomètres affichés (`FormatKm(valeur, precision)`) : totaux d'en-tête (mois, année), table des Trajets, table de synthèse annuelle, et formule réelle. Comme pour l'affichage Frontend, seul le rendu est affecté ; la Distance brute stockée en base n'est jamais modifiée par ce paramètre (voir spec `precision-distances-km`). + +### Restructuration des en-têtes (Exigence 7.9) + +- **Mensuel** : le libellé « Adresse de départ » devient **« Domicile »** et est déplacé juste après la ligne Utilisateur/Matricule (même position que sur le rapport annuel), au lieu d'être positionné après la ligne Véhicule. La ligne « Période : MOIS ANNEE » est retirée : la période est désormais intégrée au titre du document (« Feuille d'indemnité kilométrique {MOIS} {ANNEE} », au lieu du titre fixe « Feuille d'indemnité kilométrique mensuelle »). +- **Annuel** : la ligne « Année : AAAA » est retirée de l'en-tête, l'année figurant déjà dans le titre « Synthèse {Année} d'indemnité kilométrique ». + +### Nommage des fichiers (Exigence 7.4) + +- Mensuel : `AAAAMM_Trajets_MATRICULE_PLAQUE.pdf` (ex. `202501_Trajets_AB12CD34_ES036YF.pdf`) +- Annuel : `AAAA_Trajets_MATRICULE_PLAQUE.pdf` (ex. `2025_Trajets_AB12CD34_ES036YF.pdf`) +- La **plaque** est nettoyée de ses espaces et de ses tirets avant insertion dans le nom de fichier (ex. `ES-036-YF` → `ES036YF`). +- Les segments **Matricule** et **Plaque** (et le séparateur `_` qui les précède) sont **omis** lorsque la donnée correspondante est vide ou absente (Profil sans matricule, ou Véhicule sans plaque) — voir `PdfService.ConstruireNomFichier`. Le header HTTP de réponse inclut : ``` -Content-Disposition: attachment; filename="trajets_01_2025.pdf" +Content-Disposition: attachment; filename="202501_Trajets_AB12CD34_ES036YF.pdf" Content-Type: application/pdf ``` +> **Exposition CORS de `Content-Disposition`** : la politique CORS du backend (`Program.cs`) déclare explicitement `WithExposedHeaders("Content-Disposition")` — sans cet appel, `AllowAnyHeader()` (qui ne couvre que les en-têtes de requête) ne suffit pas à rendre cet en-tête de réponse lisible en cross-origin par le Frontend, qui en a besoin pour proposer le nom de fichier suggéré lors du téléchargement d'un Export_PDF. + ### Timeout PDF (Exigence 7.5) La génération PDF est enveloppée dans un `CancellationToken` avec délai de 15 secondes. En cas de dépassement, le backend retourne `503 Service Unavailable`. @@ -1984,7 +2007,7 @@ catch ### Property 9: Nommage des fichiers PDF exportés -*Pour tout* export PDF généré — qu'il soit mensuel ou annuel — le nom de fichier inclus dans l'en-tête `Content-Disposition` doit correspondre exactement au format `trajets_MM_AAAA.pdf` (mensuel) ou `trajets_AAAA.pdf` (annuel), où MM et AAAA correspondent aux paramètres de la requête. +*Pour tout* export PDF généré — qu'il soit mensuel ou annuel — le nom de fichier inclus dans l'en-tête `Content-Disposition` doit correspondre exactement au format `AAAAMM_Trajets_MATRICULE_PLAQUE.pdf` (mensuel) ou `AAAA_Trajets_MATRICULE_PLAQUE.pdf` (annuel), où AAAA et MM correspondent aux paramètres de la requête, PLAQUE est la plaque du Véhicule nettoyée de ses espaces et de ses tirets, et les segments MATRICULE / PLAQUE (avec leur séparateur `_`) sont omis lorsque la donnée correspondante est vide ou absente. **Validates: Requirements 7.4** @@ -2359,7 +2382,7 @@ public Property EtatProfilConfigureIffNomPrenomEtVehicule() { ... } - `DistanceCalculatorService`: BAN indisponible → saisie manuelle autorisée, distance null stockée - `ResumeService`: total mois vide = 0, résumé annuel avec mois manquants = 0 - `ResumeService` / `TotauxService`: calcul TotalAnnuelPartiel (cumul jusqu'au mois inclus, exclusion des mois postérieurs), années disponibles (données + année courante), mois/jours disponibles -- `PdfService`: génération mensuelle, génération annuelle, nommage des fichiers, timeout +- `PdfService`: génération mensuelle, génération annuelle, nommage des fichiers (avec/sans matricule, avec/sans plaque, nettoyage espaces/tirets de la plaque), formatage des km selon Precision_Distance, présence du logo (et comportement si ressource absente), timeout - `AdresseCacheService`: insertion nouvelle adresse, réutilisation adresse existante, éviction LRU à 1 001 entrées - `ProfilService`: sauvegarde avec géocodage réussi, sauvegarde avec géocodage échoué (warning sans erreur), mise à jour - `ProfilService`: validation matricule <= 8 car. diff --git a/.kiro/specs/schotziad-km-tracker/requirements.md b/.kiro/specs/schotziad-km-tracker/requirements.md index 1f99415..2cdcdbb 100644 --- a/.kiro/specs/schotziad-km-tracker/requirements.md +++ b/.kiro/specs/schotziad-km-tracker/requirements.md @@ -127,12 +127,15 @@ L'application permet de gérer un profil (identité, matricule, adresse de domic #### Acceptance Criteria 1. WHEN l'utilisateur sélectionne un mois (valeur entre 1 et 12 inclus) et une année (valeur entre 2000 et 2100 inclus), THE Frontend SHALL afficher la liste des Trajets enregistrés pour ce mois ainsi que le Résumé_Mensuel correspondant. -2. WHEN le Backend reçoit une requête de Résumé_Mensuel pour un mois (entre 1 et 12 inclus) et une année (entre 2000 et 2100 inclus) donnés, THE Backend SHALL retourner la liste des Trajets de ce mois triés par date croissante puis par Position croissante au sein de chaque journée, avec leur Distance respective et le total kilométrique du mois. -3. WHEN le Backend reçoit une requête de Résumé_Mensuel, THE Backend SHALL calculer le total kilométrique du Résumé_Mensuel en additionnant les Distances, exprimées en kilomètres à deux décimales, de tous les Trajets du mois concerné. +2. WHEN le Backend reçoit une requête de Résumé_Mensuel pour un mois (entre 1 et 12 inclus) et une année (entre 2000 et 2100 inclus) donnés, THE Backend SHALL retourner la liste des Trajets de ce mois triés par date croissante puis par Position croissante au sein de chaque journée, avec leur Distance respective, leur Commentaire et le total kilométrique du mois. +3. WHEN le Backend reçoit une requête de Résumé_Mensuel, THE Backend SHALL calculer le total kilométrique du Résumé_Mensuel en additionnant les Distances, arrondies selon Precision_Distance (voir spec `precision-distances-km`, Requirement 6), de tous les Trajets du mois concerné. 4. IF aucun Trajet n'est enregistré pour le mois sélectionné, THEN THE Backend SHALL retourner un Résumé_Mensuel avec une liste vide et un total kilométrique de zéro. -5. WHEN le Frontend affiche le Résumé_Mensuel, THE Frontend SHALL afficher le total kilométrique mensuel avec une précision de deux décimales. +5. WHEN le Frontend affiche le Résumé_Mensuel, THE Frontend SHALL afficher la Distance de chaque Trajet et le total kilométrique mensuel avec le nombre de décimales défini par Precision_Distance (voir spec `precision-distances-km`, Requirements 1, 3, 4, 5). 6. IF le Backend reçoit une requête de Résumé_Mensuel avec un mois hors de la plage 1–12 ou une année hors de la plage 2000–2100, THEN THE Backend SHALL refuser la requête et retourner un message descriptif. 7. IF le Backend retourne une erreur lors d'une requête de Résumé_Mensuel, THEN THE Frontend SHALL afficher un message d'erreur indiquant que le chargement des données a échoué et ne pas afficher de données kilométriques partielles. +8. THE Frontend SHALL afficher, dans la liste des Trajets du Résumé_Mensuel, une colonne "Commentaire" positionnée entre la colonne "Date" et la colonne "Départ", affichant le Commentaire du Trajet ou « — » lorsqu'il est absent. +9. THE Frontend SHALL utiliser le Sélecteur_Temporel (défini à l'Exigence 12) pour choisir l'année puis le mois du Résumé_Mensuel, au lieu de sélecteurs distincts de mois et d'année et d'un bouton de validation séparé. +10. WHEN l'utilisateur sélectionne un mois via le Sélecteur_Temporel sur l'écran de Résumé_Mensuel, THE Frontend SHALL charger et afficher automatiquement le Résumé_Mensuel correspondant, sans action supplémentaire de l'utilisateur. --- @@ -146,7 +149,7 @@ L'application permet de gérer un profil (identité, matricule, adresse de domic 2. WHEN le Backend reçoit une requête de Résumé_Annuel pour une année donnée, THE Backend SHALL retourner les douze Résumés_Mensuels de cette année, chacun avec son total kilométrique. 3. WHEN le Backend reçoit une requête de Résumé_Annuel pour une année donnée, THE Backend SHALL calculer le total kilométrique annuel en additionnant les totaux kilométriques des douze Résumés_Mensuels de l'année concernée. 4. IF aucun Trajet n'est enregistré pour un mois d'une année, THEN THE Backend SHALL inclure ce mois dans le Résumé_Annuel avec un total kilométrique de zéro. -5. WHEN le Frontend affiche le Résumé_Annuel, THE Frontend SHALL afficher chaque total kilométrique mensuel et le total annuel avec une précision de deux décimales et une valeur maximale affichable de 999 999,99 km. +5. WHEN le Frontend affiche le Résumé_Annuel, THE Frontend SHALL afficher chaque total kilométrique mensuel et le total annuel avec le nombre de décimales défini par Precision_Distance (voir spec `precision-distances-km`, Requirements 1, 3, 4, 5) et une valeur maximale affichable de 999 999,99 km. 6. IF le Backend retourne une erreur lors d'une requête de Résumé_Annuel, THEN THE Frontend SHALL afficher un message d'erreur indiquant que le chargement des données a échoué et ne pas afficher de données kilométriques partielles. 7. THE Backend SHALL calculer le total kilométrique annuel exclusivement en additionnant les totaux kilométriques des douze Résumés_Mensuels de l'année concernée ; aucun kilométrage non rattaché à un mois ne peut être inclus dans le total annuel. @@ -203,14 +206,16 @@ L'application permet de gérer un profil (identité, matricule, adresse de domic 1. WHEN l'utilisateur demande l'export PDF d'un Résumé_Mensuel, THE Backend SHALL générer un fichier PDF contenant la liste de tous les Trajets du mois (date, adresse de départ, adresse d'arrivée, distance en km) ainsi que le total kilométrique mensuel. 2. WHEN l'utilisateur demande l'export PDF d'un Résumé_Annuel, THE Backend SHALL générer un fichier PDF contenant le tableau des douze mois (mois, total kilométrique) ainsi que le total kilométrique annuel. 3. WHEN le Backend génère un Export_PDF avec succès, THE Frontend SHALL déclencher le téléchargement automatique du fichier PDF dans le navigateur de l'utilisateur. IF le mécanisme de téléchargement échoue après une génération réussie, THEN THE Frontend SHALL afficher un message d'erreur indiquant que le téléchargement a échoué. -4. THE Backend SHALL nommer le fichier PDF exporté selon le format suivant : `trajets_MM_AAAA.pdf` pour un export mensuel et `trajets_AAAA.pdf` pour un export annuel. +4. THE Backend SHALL nommer le fichier PDF exporté selon le format suivant : `AAAAMM_Trajets_MATRICULE_PLAQUE.pdf` pour un export mensuel et `AAAA_Trajets_MATRICULE_PLAQUE.pdf` pour un export annuel, où PLAQUE désigne la plaque d'immatriculation du Véhicule nettoyée de ses espaces et de ses tirets ; les segments MATRICULE et PLAQUE, ainsi que le séparateur `_` qui les précède, SHALL être omis lorsque la donnée correspondante (matricule du Profil ou plaque du Véhicule) est vide ou absente. 5. WHEN le Backend génère un Export_PDF, THE Backend SHALL inclure dans le PDF : le titre "Rapport de trajets", la période couverte (mois/année ou année), et le total kilométrique de la période en en-tête du document. 6. WHEN l'utilisateur demande un export PDF (mensuel ou annuel), THE Backend SHALL n'inclure que les Trajets associés au Véhicule sélectionné et SHALL indiquer dans l'en-tête du PDF la plaque d'immatriculation et la Puissance_Fiscale du Véhicule concerné. 7. WHEN le Backend génère un Export_PDF (mensuel ou annuel), THE Backend SHALL inclure dans l'en-tête du document : le nom, le prénom, le matricule de l'utilisateur, ainsi que la plaque d'immatriculation et la Puissance_Fiscale du Véhicule concerné. 8. IF des Trajets de plusieurs Véhicules existent pour la période (mois ou année) demandée, THEN THE Backend SHALL générer un rapport PDF distinct par Véhicule. -9. WHEN le Backend génère un Export_PDF mensuel, THE Backend SHALL faire figurer dans l'en-tête : le Véhicule (plaque, puissance fiscale, coefficient et base de la tranche applicable), la période, l'adresse de départ du Profil, le total kilométrique du mois, le total kilométrique annuel cumulé, le TOTAL IK du mois (kilomètres du mois × coefficient de la tranche annuelle) et le Montant_Regle du mois. +9. WHEN le Backend génère un Export_PDF mensuel, THE Backend SHALL faire figurer dans l'en-tête, à la suite de la ligne Utilisateur/Matricule : le Véhicule (plaque, puissance fiscale, coefficient et base de la tranche applicable), l'Adresse_Domicile du Profil sous le libellé "Domicile", le total kilométrique du mois, le total kilométrique annuel cumulé, le TOTAL IK du mois (kilomètres du mois × coefficient de la tranche annuelle) et le Montant_Regle du mois ; le titre du document SHALL intégrer le mois et l'année de la période couverte (ex. "Feuille d'indemnité kilométrique Janvier 2025") au lieu d'un titre fixe, et l'en-tête SHALL ne pas comporter de ligne distincte "Période". 10. WHEN le Backend génère un Export_PDF mensuel, THE Backend SHALL faire figurer la liste des Trajets du mois avec, pour chaque Trajet : la date, le motif (commentaire), l'adresse de départ, l'adresse d'arrivée et la distance en kilomètres. -11. WHEN le Backend génère un Export_PDF annuel (synthèse), THE Backend SHALL faire figurer : le nom et le prénom de l'utilisateur, l'année, l'adresse de domicile, le Bareme_Kilometrique applicable pour l'année, le Véhicule et sa puissance fiscale, la tranche applicable ; puis pour chacun des douze mois : les kilomètres parcourus, le Montant_Regle (frais payé) et le Frais_Reel_Mensuel (frais réel) ; et enfin les totaux : total kilométrique annuel, total réglé, Montant_Reel, et Regularisation (Montant_Reel − total réglé). +11. WHEN le Backend génère un Export_PDF annuel (synthèse), THE Backend SHALL faire figurer : le nom et le prénom de l'utilisateur, l'adresse de domicile, le Bareme_Kilometrique applicable pour l'année, le Véhicule et sa puissance fiscale, la tranche applicable ; puis pour chacun des douze mois : les kilomètres parcourus, le Montant_Regle (frais payé) et le Frais_Reel_Mensuel (frais réel) ; et enfin les totaux : total kilométrique annuel, total réglé, Montant_Reel, et Regularisation (Montant_Reel − total réglé) ; le titre du document SHALL indiquer l'année couverte (ex. "Synthèse 2025 d'indemnité kilométrique"), et l'en-tête SHALL ne pas comporter de ligne distincte "Année" dès lors que l'année figure déjà dans ce titre. +12. WHEN le Backend génère un Export_PDF (mensuel ou annuel), THE Backend SHALL exprimer tous les kilomètres affichés dans le document (totaux d'en-tête, table des Trajets, table de synthèse annuelle, formule réelle) avec le nombre de décimales défini par Precision_Distance (voir spec `precision-distances-km`, Requirements 1, 3, 4, 5), au lieu d'une précision fixe à deux décimales. +13. WHEN le Backend génère un Export_PDF (mensuel ou annuel), THE Backend SHALL afficher le logo carré de l'Application en haut à gauche de l'en-tête du document. --- diff --git a/backend/SchotzIadKmTracker.Api/Assets/logo-carre.png b/backend/SchotzIadKmTracker.Api/Assets/logo-carre.png new file mode 100644 index 0000000000000000000000000000000000000000..7127725e3640a8ee669e364f2853aa06457378cc GIT binary patch literal 136254 zcma%iWl&s8*DeHtTOhc*I|O%v3~qzFyL$$Ax53>Vf;%BN1a}Ya?tXdCIp6==Q&Usj zQ?>W%)yvn@;fnH-$Ow1{5D*Z^(o*8e5D=d``{DL4Lo<5fR4j>?0Ss);e3?LwQQz0O* z9WvXL_&@%DF_MuKhj{GDRE#a`UA&}4#7P)QWbMuENsJAhoDM%GVos)pE~X|V z?v^eVB$Co{idsDUAGDD`NQ;Z8dMuxGx@QuogYVu2n%lh1k|?6!r$-zXLNr>|0W_V{7XNuE6oi%+;XyzO3v!W z*kUS#Qe37T zXA*`n8s{L*20OHh7!3^#4*2m{7}zXZ_x#~f;2##FHd8;lq%Y_{kwYAf7R9VjM4V5} zmfI1$)J4vn4z&GmYW#r2eT)t$YOsBN#VI#P6bV0!q4VKnq4Mp*ymHr(qw}N|6c2De zi#7W_U4YB^L$2buiPQ(Lx#vssPz|HMY3zGx%z+AZzup-L3k#EIKte*=(*hNmyuHI!VMGVdE#A}QOxJ+Yxj6GuF-F50$SkZMF>lC4-dto{8-@~(a{p8X@{AJ zT1ON_c;R|SA5tVo6jeEFszP^8bnJYlBBJjZU1Wd4DL1Pbvy<(Pe=+ z6qJe(>G9MJ59M($j%hlUPh1IK7%t@{A5UeU>XV2{Tt=pMSXBwPbVP3~@|U3xL$wIK znu0f1dP}nm7sr{mQzNe8@Uj=|^ddrkwmcg=dvN1@`WQV3aBv=D2N|}5uD3r4j~54S z*|B;l@Sg0ly&;mBg@FPHueiikejMn^m}!MB=7ss(yA0H7B@I7-@mu$}kQgd2dU+)B zWWh0D!H^y3$jmr3;`YAngl<5!?7Ofo5?-J+tfJ6Af+h3-9O|ag8A=t^u_YidZ`J^-1T&RcEag?eeEmN*`(! zv3wdZm_sR)%_*r|na5uQJs?QIr)~wCPW8?Ei}(-ls7g87L?}2rsn6J=%V2J^ut>0% zE^D!`T?-)x8=*S5h3Y^nEPaw4NrEWM&XdF{#4w|)CW7@py^2r zFeI;ez4H&vQJ~+u&b$r{Vr}7_4aw(J zc}Q0jCoJ9D=@+65Q}s-4O2n;NEiBaVRF?uG$Vw;2X9_=3$m~vJMR0tXb0VW5%+|i* zE3!JKn`MZftP3e992U7@6w=6Pg-YItzJX#x&)3?_P*x=H;SUfN(I}_>ykWf?pZelk zv;#6i+XY-Pi4LpL>klhW{5``UJ`m1S4k&tazDfTw_bk#0FijhheuP&a$@ZjGlJ(J^ z!f6OU;^C##Qz^lN(+yuykjbjBW|3+szH|a*`0)% zu0jnE>;#2Ck7zbjaPq6_XWjU#jP9yCuCO%Svf2taqarCXI8#cVM08y8aAmMp9Y8rv z>d~=OFa}ErRqs&2sTDw9qZsl2$|SzQy_Z7!x^Qgn9G=u%7AZ0>QUxm^8}Rd4Y)z*| zK*wByRqYOOv*bT&D(@%xPDCnqKFza!SMTVcXI@97e~0@C(c3dSeGu4i5?Y~p(~zaV z+aX#W;}}bUsp~bT|2(Z;jiuI?*YP#A3`m=&R73u=QcLZ+mM+My7DJ;^dx~0}?9`ms z@;R>qxv-bmgQz;nri_=ujw&mBZ6(hbC1i?END`a9A#`IQra`553jaR~`Xo_lSG#Xb zOl+w8p2zRXT=$}2;mn!38CHh5=ACazomHa&h6jeXl#*;MOcpwO>xDO4Jbu$6)h?2K!R{1*?hQxG;9EnN{5i|>4)0LSD%VMkwwbDnwL;IJu%Hz zI-#Pwglxe6Oj^x2c$)%YtLVvmJYWtzAK2VR%xIW!yhU-6RLy8GE52yv-XPeCbAJo-Gchh z>TXYFT6P)OZ>gmD1PaCwi*{@J zL00&Vqr)Mjw+3kevbZ@qYQre&AfWcwnPZtgfMUdR^?+dM6U_aH^f)5x?RDdifTEhe zk92@wLY=q#ew8t)96uvP<4FtcMJF6$y_#y!2L)!e^u3(Nq5QZur`d--ab06Wr7a!o+bPg^CMHnO6kY(?8o zKWu&mXKT8Ez>_FnqUcLxe2a@nqcpu4PN5rShPdd&yl9sKyG{BcwvFbk?qU9)m$*nl ztI$3XZ%$Siikx_3j3f%?RDb}%53{gh(uO8Lt6&;9u_;lhQmWDJBVwY@l6DExr^}Nn zV~Wf1$EM`}RW6bv&xM&5ro@G*YP2hL6;V}yVOp?KtRQVHrSVK2vG#KgizKznccdpJ zdn^jJKx}|-5KcGH3TyafA>UT#z<_JAf@z}U~B z4H7Pb?%J!B2cBtsASJ>?WUVaNblL*5xr;gWx@Hw5y8r^~J=P^#S8Zj3_3*rR1>SVZnlKj%^Hin{(XeS|{ z1XWQ7Ptll(KAdUM03>59#7HYxfA3FN5tI>>8U3Q0uS=w@uMyr46{=9fkKpE?*v5ql zxUeMP(4mmR^oG5+h6q^M~ssUehB!xhelr$Ys zgAyi!Jc8C|6Y}j_sG)W)`5+1TfUx?)sFpG0MVz(M$}a#B-ktlMf3p)GSIJ7jEX&j{ zaRLnJfhil?v2@JZBU6*p(McT?JIa>1@Tc#<3E5@|fFfdVchjKLV+a%DgggV%1GuR# zVxf|ep5Yit3M_2O&~fU3Blt8*wWaRVq5E}R`oA4Ocm)&2ZX)S6pJ?;n!D>7c;H2=T zPm?H4IpKygtpB1{kzPt#m#_W7q;^Io+i^D6LH~|ILF##wusJccH`&RFw1&XtgcOAr zEio0yZRhm*2YSz~+q+l$BxB~}YY;g!RXAJxx~q2m(PxcYg6ZzBTPZzNw5Wc?TkHjZ zT8hhZS4G%HG2=onCDiGGS~is~X`g++C`(@S=R2ctr>Vmmmi zFZ-W%CLMA9@mRl#B`W7@QzU+*@GRI(j4F^R@j5GTl71`iuQjDz%Ds-^sVdYfSI?mH zEGsnntxP9aeRH0fAnQZq_XK2d;lk-eY+Jf(329xyt#*zPy2AB5sn0(qB8j?QP^X|DYyl(8VolTvJYN^=YQFJ;A>S{k_ zYUCuKkSiX7keq7wGS?I&1`37TF$0nqPnkljWGKBDM)!Uv-PL6#t>0mllVD6t_^q50aUp>A{M^DxaUzc_E3SG0fY zd7n;dpI%n?vrZ3^F7L1ana&I!#iY(xO(w_Uf2xG=`|h?s40>eY3YT zacC-JOahhU&#iDm)1|fAJJvp=&ofX1g%o^i{&PLCX(t-W#6`|_9a3d0EYkfcCOKSw z0)jz!k5Nle^gDiN$N$C!zhENfRlWTW_X~K<2mBd2G0KobX|C8xUrgvO#l!y?gFzdD zVc#jV#RYCD+T$-(W(fPNzc?P$5*k#{9!%Pv%@e)(u@$_z@v)zjarxV<8B@;!osp~; zb0A|3PJgd?T7F}@;24r((Or+B9|GoyTdh#!Zs8xYY!8l}u_ct6kD1o)_6)fVDinmC zk4(8qEVBQ{F_uaEkC1Zv2gverF!lOfQC;k4t-pW8!Gg_j z-E*!W+gOP*Gkgczx%{Xs{W+D2P=~S%Mby#n3}i;Pu|D^idSn}4JT{vQ&EG?}rKthS2 zzyhK+L6Dv6ko_217jcK?f3&3Fq?%Eu>Ai{Qd0dh0y`xXT%(BhV4d|0nPLx{_E9z+2 z1zq8ocC>n^hJj`FE-i_9k8CfRoJokD^luzgPIbJ$FY+A=-N5iM**S(OjT^49n_tg1 zN^M*lNCcLZ3<}4G7I#Tj*e1oh@yqRNm53WaTcYGfPqDmZ(VNm>kD5I9)>8j#6Ey56 z+vfFXI$!u=}ownQ%qItgt;V7 zQc8^kuX=)m80vguw}))pQQsjS(ggBHN|6T{1+YG znrbPH8pWdg(VA1+-RMf`(NLdF$$k-Qhz8<;vuIh5XDiz)%$YG=Coh^?8wQKp}0y6gEe}*VH&{NPE^lh&;zI`u_cTvTkMmJjKq)Lxg zoD%JpEV5;|3ufj2Kr6(`fVH z!kbSWX*vX#QsQsr>fr7b-*7<#*Fv>iFA&AI`G8pNGS*qWIH*;flOrwz)dY@BCRx0ZU3vuj18P%}j-+sSYGOPL?l6NN+9>%+TwRFBjYR9eeO{d@9<1sl;~E3ig^+&PFR_*OJFVaTy-RyGd+>*JFhBltaaX14(L4gax50 z2Gic7_qbXA4~nDDvRkM(RG%ndON(jAG}(i_RA8n9XH9iOP+TZZe0bSxhFYC|uyp@- z0_wly8k-%@ZA0syAmg|R_46%vzjxlb-@+wN6pwIJaMYyCF51cB4NpeLEMig-ycY(> z&W)mukT#M_-W%F0H6f-^ znJBedW{tngcO)1u74;zwNnuL2vczILt{pI`Od1+*sPHjHX@AtUKFV5uIrHty*NO~V zBDG8GNXNc=VjJ8^chlT^(g7`3qg9}WyM9iN?gyDa)GXGFHtgr`-h-&^B+@6SgEm@& z_*;_-M!zafKvliob8@{~xEzs5P z4u#7uK7ClmtK=7Y*S(sC3agZD zO@i8YGTL2PlL_fz5TwALApax>YkVI}i27vXlJMGG3;s7*_b_#G4eV6R@jOf6=fw=4 zFP2^cXS+?^(faGT8+6GQIe(&5@Ng+3%`W`h#R^H4U0B@%Yi+)iV^>EvihL)k^h$}U zkNnC^s`RCj4y9p(wCbi|`>QQy93iUs;Q1rxOfRKV5{QAIwI-l%-C~04_@RrT&9mV! zCo~KyI&u3Om%encNfEi{v~}Wae3ApF@!}6ulhvtrN%@8xL~ZVWWj-dXrjB^8jQULm zOBeY|FtG-L(eA!xV>kJ%Ia&0AT*vyiI?6P1F}(JF0L_II^l&EQU)+1Sh~y1}$}>YGwN;K66PyMoHy z6}Ef2ymLo!GUm_g6p}U4a4Aoey*Cfz_n!lr2%?rD34KTIKg3Y7cOLm4G4xwsaw{1? z5FC4f6{MKZgPn>C5RV5rOqd~94d2pdtz&scwtwYO$AbbLG?{O^EpN*cj!_>=+NbN$ zXW7NhQRNtHx|ST(1xt0(tI2cNHzj>ou8^WsiNTWlisWMiO_G}<=_N2 zxHiFtuFog8L|aq3`sF!B-F4D-$9yN;dRuVO>MsGIzKNv@jb4WK6*0KKDe3Y8?%=06 zz)_J5dHj}ClUS3DxOMM*zyZ#6C84o#9pdJ|EVuWr1{kZKMPSUJHg5xpI9?an3R< zsk&Aklok^v)~DnE?La$L+_l{UZ(XjO>KsG+WeRXYnj3)QSE%P!$c*L_4M&JlkiJ)W z?iOvZ7FwmAh?Wx1-S5aAska*Hvh6XS#cPH|qhsc@u~u1>dgq0dQv+Y`32a3Wv&1(A zeP_f$2zgla0eEQ;$EzS}alj6*sxY(-#@-n;8wAlx&OJ7^aaQxisk=fSr!|H<~aDe zrUu>8&c<}P9BiJxweS{}az$Rb=@|s(r;G%kwC@>)luQtrR)iIu#1SqD;6(d%^uuz- zuf=w<7<%7Ym}8z*WH+iL6=Qqy%GU@cj`G)8fU^ z36c1*`RgH<3%sn()f4+>Ybl72^}z)s z!cl*rE1t$tqGZz20bGA#7tPVZ$C$F=DTQ~tTG2Du8Jal>w{PEPUUbiycZJ%B^Av(^ z6S0!!m&le}-UP)9?e|5NR=tftg9(gqh9`RfaUO>|WHt#LO9i1agX5&kDtcO+q-qmyML zN2?stkr7$Jly4HGSH(yD8zE%q!a zr@#5RxW2{(VV2=LX(s5OglJI%`|Z$8)RuE&ud4zjSq(9FK5-mgR!p?$3SQtfE4i|B z-TjDCm(SmS?qHre|5?YS3Tcy{$9+Zycj5T-^AlT2ox`2E>DjwqWDkeK;h%Q?4rMy> z5IVXrpf+5&iVmQ;CaJV;h4*^_+)+l)%jn-X`i-*D)?&`Nx3P>aLoyYa@pR72vMCN^ z7}>1iG7On$4J1}tf91TQrF%4MWyjI3SZO9kH7x{2Os(?1BgKW^EmRhX;7%x(NrJl+ zK~tXJdR&V8pVkg_-z&u2L-v+C%7o)=k_>;A%o6{|mav)iFM0FpdO7hu9=ii=GJHk5 zI8sE+ATbEkd@x_WtlU{y6}q(m3Wm*xQoU|l#b3$2a5E@7ah{2~WaxHb zW|<3h4%=>MpNQD;oG%nj`1qAni)RUQBot=uE6Y=!29<)06U{@U)25rkwT}{GR|uW{ z4-2sFwA?Z{n{d`VfK_V+|8h9G^3foDl>1R6P}$0}aV9v;risxGjJJRg6_vJ@)IIDf@$@}=fTfnX*3t_gH3#oCbv z)F}MA>Diu{1i!fa{pKyjP5Mt?s`d*>ww><@QQM=e<{Nb(Yh?pR_@w90-bg*P?yAZ2 zi-;+SC?c!pwaG6flKacVHcsVpw|5AjvqSxhq1fg)SLXyLf&_+#{QkQtXn%9L&y;G# z7?h=W<$UU2N1N4r!Ki-p&w?ZqYe=`G!t#6x3(1DSpD)%L@d zTiuSRB&yddDq15wxw6M*QXpZX+h(p(79irvmF65pAJ02Z*IHRyRSNtS{EPbP00a!g zIs2`L_3Y{eh*MZsLlg0>sGxOS%kvrSlQ;WSEE&w~S^Q+7sp-UfJ^Nx=%l--~WkHu~ zRLJ#xh*~$Z=YjdR1b8a%}jWaS}L170+j8%m^3R2A4JMe{PJgu zFfmKSWYbdUcXg$PzyP&i+2Keyae<5Jtb@Rm^Zjh=b$tDIn6W90GD->xHSbKZ*&@ol z6Yh#QCPpdXC0nDcD&k#2Oe5>z14-h`c)0hP{>bnh9(z>%;(fi0npN(rRJjSfV}5!# zwlEzP;a^+fHiOfGRP6m9B-w^S*yGCo)Ua$kc8>T#Mwh-L35SX`)QGn8;@M0C(^$i2 zWpHJ%5_6P@9Wv4Fa^EG1B37OoDxR$~7hEGiHi=8cTq_Dk^_}-uLw{5}&G7n|G&yLo z)Q5SQRX$I086x`3cRu(VQ$7wi6Ij9$$9sK^ib$!B_IUV&)xWr9L~Q-xX>>yPA7oOW zAKbOnS2CW?YPayRNe=buto}>|# zLzYF(=S|g8CRAPUDu_W$vpG*78aJ-FXDaMcD<{A^AEQ(a*t$aH!h`2`g(^<5=Q^*G z466SCDSaS?j`?s~#?SIP&tg9sEK=R>KxT8z-LsqyV_OH;@8WSSAu$3lYumrh#m!gl z?=m~X<0=mC65DqAS6c5QbWI-#hp*12aRYoT)#!pse@7RpE+u3VV(Qt^(ren@D>0Iq zd1@t8sC8{rJPhnP=eO1km!`O@MOUiGyv5~8URdmq@(@LCF$VOvk8s)VfJ~p0_gdsOznsJ zx(JCUygJ&UB$m!k&C~CKCGN{vznAF$QODafw1$?L_G)1b$nl-xoSi;BX`~c@c7{~@ zrG{`>fi|&N$8*;^HSdbg4-8VE_u=gwWY%+u{cwP_us*bvrJx!*d0dIxGrEkO<2*Y2 zsI3j9F>qkC{O4ydaU=T8kvmoLA&^NKb77P|jwANPlyaIE|t7OS_FyM}=5xg-BoxUTsB$r!)Wd%NbnMSksr8DUvN zY|7J8L_eU@01)M8`Rk7QuiMhL%B}N>`Zq5l*Uqd1v&F&Hz-CaWr+Prg;-1(95O8Z! zrtIo4X)|fnrP1#9P(CpD%%&Ea8tn%4VvwhqMYQ0}m=I*1k5G*2`J~{m(s19WzG$Ao zewwt<)N?{B5N;6+dJbU&{dTe=k{d z@a_10q+^5B%$4nC*%b~x zuAFx#zA6gBV+ui8$qXPGVsB!Pk=7szDnG*X{A+fWQ2`AuAEAdco`Zhe^0XSEss|XN z2UQDWa6(BfK(N{Ku7V!BXa7#`A=fC6Ss~v@n{;RfQB52Gn5a%ik|KiUNJSdx;K0as zyP1*AM`9CbF@`Uiqf>dq45HyZePLhW-@hNVQ&GJFk(l2$$vW44$TFAy0ke2SDrt|N zxBB9dSvzrl?{omrKH4?Zcf>RI!=$4Sx^nZr`MoEraILon@UF>E;-6x>9LjJV6Z_UR zSEi;Uxr8M~_MNhyCpD}@JJq#ySF6v`!jN(c&MDFL{Zep@6M2SRNvbQPXKmdv_Tpt_ zu+McVE8w6EPQw)#E+C6_MzhW1g>Vg?Qy}H?-4?!niCo~SX>yxubo)(j@4#wx6jnw~ zB}xJ4!b`-P!Ep8>>h_ZyVEaAiZyv5tJ?ohj&U!?E1Ckk^SxY<(m}fzm(cQqs;QFQd z>b@jDjz?uws3)oaLcXl?>YFih`g8LH>z}r(cF+Uh8H%XQSv@^ciEP>Yb29d|8?#hC zFbqQx$`OOG71gdr%oiieR;Xhtq2l=DC!TY-;J4EX{wI8Kf>avj&&swx@8Q(Ev%Q}8 zZu=Qezj~_WOVD;ssplIWo+^_n%iNV;RraW({a8NN871<5S9`cm|581zjv-QofA+?D zb>XUyR~O@Jt9Ol1D7@Xp%~pyNRc4qEXDrJmNEMOL(G=w%tr`@HVkJNNO?ck_AT)*Q z3tBnC`0RT5cBOS))^Qs*(48A9y{c{mc*K!Aboqh3BYqW}p6Ca$pFTJwBmPq_mXkOJ zcta{MKgKcSz!#%@w-6pK*qZrN6-7!5R@P!XSVp-Mv;&^nc)v+VSDLNBf8??v3)PwZ zppC^?H3iX5dfl_S56kH)q~H|S^zBy@U6MzZec4w2R)uPKF^!<*$h`X09m}*x7=aok zbk$_jQFNmVl7(q<9kBXhG*~m7r!_n$HBHdy-ofP1cqpgq#cgIKlhdK~)nj88WxY~u zw8ncsyWpw$IDjfZ!d0gVC7!m8xPOQCL>fA9fl))QZYV}y9awcGLqN@rI<>6r`Dad{ zu9?N^X5%=Sx>s0#*>7tk!c@c*GH}SkWU7dI78Z{7{2%yAN7_fz@t*VbMJHJ&M!Yvs zY|47ZK2lrpvJgQilBNi~`g45lbEk6*&Nsj=z`j<+1zBj4y4Y83{|zU9O0l9OGM#>3 zu8|h;l+GYyk~7R|=UC(@QI9rKbD1ho+FXFXd4|?@3Dx$w6NgL}8IMpEbX|i%xYPL1 zCy7oO$?9;u5QepWm(!@Gv)WOKQrC@)q zYYBd_4&5&S*BKC$1g6x>WF{zhj!w)>N#6~AV31N4UuX*FLQ~}lv$H#ND#)$XN$IiP ze0h7bamGFV-K=zJ)piEIm#gk9WzNktmg`8C#^FSGM8YojrWy?gZB;Fnz(J0B~7t!0Y36Lph;2?>Bdqjesc8@Y8P2$;L59RE(a#daKs`@Dt z;Hy67dGxoIPLkOKtNc$?^=Ul?y>&ARAP-@>N-t#L@2WJM)E_6f(VF!#OA2W3=-WfsmIGXJ4XH|vDrTD zf-*k5W9GwH>C+R1z=59xA(pIws<}OW|7chC}!1l=MO~k7qN|Ih>HL*xsJFTR) zmohRRn&O@7H6*r4#Fd;do1bG`JFDGB&?8S0)pm8~Gy4xb|Gl@%TPU+%%a|w??=n6wP@CoCYXo+<;%N5uJ-U-inv0HGt)+jRnXI3fwbw?)0O= z7^kx~@K?g44dKZaz>3Q##aZ%c9}eDBdXRA{94;Mo#_R28lNq9pqc*KlWTgi%84;s zQtVMzPNZd5Dop#9($&dDWDjRNQ`~nh$QNsF#Q!*v`$lGd(f2A@=O&F#n`;@)++B)o zb12Qe#Q7M-8`uD2u)~exzR1z`_$VP#X;&ZGa(rs~^ujK*J@wA-x2xcX`;izIMgA?$-PW0S2%Fw!uQkz!e=x(RnQgm*}TWV?*UZ)^E z+OBzELbbmq!GdhTaa9ShEaU=Ax4`eUf1P#?wYyi_X2*40TLlWl>*SZ;vAlcY_X%q? zZy>!Vfz0+RVYmm!6D7kq(X31oS9U#4*fz9+`Kr9&+bagf!6m-Jf#9}L*t|z&N1fgB zvIS5%N&_+0ICJ$81&QH<|ib-~&T&~n2WJ?3w(-J!G zg2a5Eh4*aYJR}~F#RY1eAonguWAK~o#^x^Vt87*3-`@IirnS8PJl_#qcOtHTOY-02 z<**~`!?87L0GGxxUF$WPyMS|eG~WiEB_Lp%;s4@UaK3(cd#348$<}jf1238Y%+BxM>5aA75_a9|ivEah&mBPOlbmf9 zIJI@!2T}p=m&1AI^ztV7FA3A`x5paJKXc&4zfFUiWz^~pH4v=d@6-fhd{{z_OW` zNq(^BhWwg&kl%SDW!3(Ku%h~B30P|WS;4DM&*hKgV02mcC{dTL^JuAb{gQ0#E!F_C zfeywLu-wGboVM1W$_^yp1MBs`vy$!53c%O`9=$qC6{{A@VV9FAA;oUM$q8bQNBryZ zh+vo4VvH`KN=Dj>r1`vu{Z`XRES?uPOn!!||9)tJH51d{sKzZ*5H1% z@q7yrH)UK?RcWOp}Ajol)28l7ImOHw16M7H$g!F&F> zj^+Hg8g4>t=jCFdRT`eQ{Bv*G8R@q@+ss9+Kc-<(mVM^GWT578PWF|NHLxs;>(F1) zn!Z&ki-*&)HOw2|$Tmf4uf5>6`##~?cBzh(&mg1$p)DD|=YX!rI{VLv$D{t?!3$@O zL&=gf=Vtp}cttKN*|5MB_76sCofJ&Q^TbZbIX#z?p9gMy?_|7#KJI~QRLv`(HP<^l zEXD_->o;=>kb>Xg)oezTXCb9(O?zEd7)tV&BFgXLjaeqH5q~SGV$_LM_{t@~NlIVB zqnn_3kU0Aaz$p(~$T}#?w9T%1F$8>`886RJ=OtVX zQS$^Jt)<8?{~YZuk4%h|IQYeudW~-~zLsODYm8l!ZMUIBrb*0wP5Pt`+Ia}q2ECo5 ztY&Y*Im$RFLy_aSif=iYGUMV9?n2YUGpIES5>G^9oC?^%>6?@wCZY<99%_us1TX!% zGd~ksxEynEL;5G=tq}$>VmnOOhsuCV*mC5Gv=pz5KF`WL$S*9OB-Zlcv~iyJ%&txG z+=1{btz0W!EgJr;)i|4HGBJ;7)v zvCYbDTZn3>yp`qAk&q2LQK4oi`J) zcvu;CK~(D~_L~aMqhPXaHJfxo(5vxJ>!(A!?CRL+x<$+N@4(4d6h^!J+IMQT5Ee_Z z8(rj=;WKURo`u^(ScT*iBAA7geQ)VKLpzMThRP9-cQ79eh}vsYJ5hcFJVBwl?EIzF zObN3a{XGwiPZe@ zfIODs>Dm#7aCG}t3Ajf}mu1W#PFJ1`Ok$8eSGmTPHC#z);z`pC&5cQiYbScM(2rI? z1%-B27h34@dNYTh2)SJ%(swzJ3LtuVL1bF`VTc!qmtjK1=gp~(uiLWU;dbu|E!E$@ zzCHOw-LF}>moaYpnyjP7a9Bma3vJnMBuNz%7VSQd9)t8(jB~CJq zzKFx|@9|AV= zygSM2<$Lh9dgrrNevY&qFkxst$bx#&)7PaUtE=Jn#q-#BT`V|k-rh`sY%imELX+(= zo6=fCmpDREW~7ixG&*m|C9`p5?}X28)VINYV;>g3@7bp*OWC{i-7D=LBx`H(v^lg( zjDpUb1!=`{0^xEW{{EG)d9$+w>XRO_XgJH?Xr5Xv0{Uw^?$uOMDPHT^Ozy)Xhhq}> zZ3H?L!d7CN_ofOi4kykJP?FQalC?_@NGM*?7k13tA5TkJicVXMehL$lS&e!=ZX?u% zrNKJ1n4d9rdN@oK96~{sg0vh!efS#2Zea}T@*erL=GNYMJeNT4S6zR)4-<0g;K#RT zk9BkbihC>UgJWVIZFEiBTdl>TzXaq^B>I-GTOT@fAV1NnMhMY-(u{m*%1@#bCfq8S z@|^kGv!qY7zEwAuvS=&=eXN^!o@YM?i@IT3;of;&s=HJb4HD*u64hU*elZ|Tn;Sm9UEF~m*6F3%4$x+izc&k_b6qBF zd}~kB;2YL^(rTWYykC6Y@`*98DG;n_&w-q3%4Hm>3eSQwZxyR`d3K9P@+sN16ZZug z0q%-i^7x%fX8rQOuSu;jvZ4)9ftaWUXDu!hq^}cWNAJ-B?`7}igS!;RujWj(*x4?J zK(V9eEbrNBuAJI2w1EbruTTRN04$g-^Hzzq0+S8P1X)g^2wN^#UUkomN2p78DOF9PS<0wk zGv0y2q$@e&a|PP-pR+bx_|ER!8)@(C+hX5Gq4d4iO|d1<8}#jM8@Kb$;+%o4q-0`Z2H1?3R0+9P=HeHp zc%c6Z`B0dLfBoH$W-gJ*U$ z+vGvL@N+PR#ywhF40BMu**}KH7iP@*l-2ApfO)vBNXi5NxtYYE zFd9j`FVCb$HLF5$7!M`$CJd&_cICr&OpINQHxiFgDvcIt=0k4YXYIC$F%mr$e-^6A zc)E1+R<9q|JONFbyVP7yJ~8D&mEDgZ=8U~)s^uit#63M?QFFd<0jpjX33BK`p9odR4}&vcUeSP^4Kzq(O*Ys ze~SW(gDm$?E86u3F8&V-5V&K7?6oz^|Ei1V2DZ6$VQDmy3h0@ZUn&l?9oTl`yBh!s z=^ye;tOG%(clW-$%x+WmIU36oEkDKHr?T4(Q&(5UVO37I+0GMm!`0)Oq>2aClfIb& zjEq;d^XK+l_{cIvp#FCw{GfqE&o(w9dDXR^p@pzbw(YyrPnBj0_&8?B z=9QrP*_h^TJ$?O}@rL%kR{~Ql8Q(nTYRLlyq~S-hQ*df&^44rh^+@Fqxtz3XHI7@B zXN79xb%y3>P*s@K1&mnJ%r#aUe$HtwE%`Gx#*yQ>DG4&7ZnRQLu z0GOm>+qODR$F@6muGqHIv2EM7ZQEAIPOdnae(ra^Ip!y<+O?``pQ!c4;lzWaVAcDsqljO1G)lBwSLY3@PR%LGrcR9NZ+0r#&s1;tcOCH?dcdK;6jx zqZ(8n`qGE~ZjIpkwU~XYZkp$E3w68$nDS}xB5{h>Hjv|WyM%C;mDjrd@Dy(LrJmEx z0`q%117V2##z}7ROM)QmvgJno82g_ZjS}I1V_{yv3Y%AS`&nseWL3qQe$ikVd$00O z?cVcn&=xDREznY3O`gS^#vKNHj8xhb3hj{}9^(%CB^oo#SFbi_HYBGsvonP(t)YB2Ow>w{mraO*DjRXb^nF`TPA_4V0U2NpmjO{RzJ$5~KIi*$}p;(~tw0qFK& zf!P!d2^QUdw(kZ{mu^0B%x%6+`Ywp@uA2N9xCHm??=#w)1To!11N&PDHtqS%j@|CB zWJs5i?Lf@ZvkHn`{e6V-i!jTwhv<15ewPi2Rda1|RXrU`INfvf%c5+qjNO#Al-u7^ zzm^bTW89S>C3wg3b@K}ztpI8Atj{|tp2X=KQle9fE2c2$77|;Goi!6yU&?!Hb zFr<@5Z4wr$5IbmwsWNNx^ppANn~v=)3fR=1b5b(Q#%14V$wk#V3~E~ox5)(RN+L7G zvs-*qhXH6@IX3?+I<0@lwgCR{N5!Y)NOY=7x&j@?;iof){Fnrd`!WCW{uV{{8nhNk z*-hi&s8AAN7Ix7?*ui#kW;tX@u$ox=T1Y4I%eI?beRY%7nV@&2eX*y%i;je)j3%*i z;eyVkNRhCIo?r--dKmJER|;@!MrNblR5WO_VT$}Vj)NP>50^;*-I?oV<}?(SxQgWn z@jKIy(IRHgz4gH#u)Mt!EsZtQ?J>@3Ctqz#`h?chB|j+7j2&of*1?uTkPzv$r+IG zmG2G?r%J9D>>BOg+KqR0_PX+CABvA^bNJ%IVbv{~@2A%E@cj~B=;Xp?d>K#lP#9dv zQKRNv2F(3-!Lh#Am415#vT`n6^Kq+^#S4A#q?a7{!6;WzL=EK*{S|KbrB@I4{%5n( zg8OQ z(~6kNh6Rg1l*dE#r|pRjt(1K^M-ebs`xLGTNO?^qj+gpSW4J)Bk{7Nybt$l!wk=-z z1M5M1&=0vN*)Y=-!3~tQOu@vFi)fnVbCt87J#68Hq3rrr!`X52bguY(e3PvK>6ook zzPM?TICV|rFZ2Qg72-v&VvHtNHc$Y%6D%vm>enIb$6ht%15)Vrq%$> zn(7)lvoK}EoQwMTH&5a zWtR~kgZm~TWiLaxn>ya097*0$EC%`#h^AJ|;6Fan&{Qfc|MLG8o9Wu4@Qsym{OkCO zQA~SsE{DKi03u=^t|W7J5`cpJmhy8)eO=j^ohaqxhD$XkJy?`azrZzJs)(HVl|s|6 zrf^qGV}mI9Dks){=wb?8Do}BgsB>#H?s`)Ao_tbR20fd-EvJ4g=cKl{|0H8DZNujy z!b~9T{&GWtgeGa1+-pjj(rjS!SX6FU|`+r{)+WiUYcO+xO5lWb$wA9t_ zv#NXkoznW>ZO+!>GWxMJX_yycD+*Q}KA{)Ku$pWatW%#TW5{gh;_U27W{iEQ0Tqq5 z(iu{i*cm!Y%8E;H@IQIACWyHu_J5#GPin6l!DY;#KaT5UY*duoLg9eEDeC8|-A^vc*YSQvf0ogJ#N0^iWebh~=3M>t>yd2uYTRIQ&# zIOy)yZ>o|_9x4|uMrAxNz`gxFbGx7<0=AwdqS(X_e+EEs`#$-d<9*2!jo}R_tpyxE ztbX(tkBs855+0~^e5e#UO7uCku5N3|!Qd@?}w zV6xRVON`;pxG`=$lQf!BQl5u+Rv)#~Cfq);=Q0;JnH7J6#7U!vJX0T3s-;hqAK!5g zuga3L&RvG)XOem4;8}6xvJSS%{+jby>6qW4c-HZ)TT1!-zU=ns(pB|&{{E`zer{Jr z6&4185eb`mpr@6NUuP<$UemI&f+DiHs$HoU=+M&Me0xzMx-jyocq+#%kC0^v_CQV# zMIJyWhGF$5H||*E@~XXg7|mJPIRQtu-Gh8iUHzNo<#f&ErD0Y*`{mucJ4usvCdjer1WdW3pdLrm8dLD%7@*mC0p{q)%6sM21~BxJ>mX^J||_fEl1 zT3lm%vd`FPij18wIc$8rs{M%oRD<6CV8aE%lDe4SrdW!H41Fs`J4W< z(fh*R?rHi>(LsIoyUkI(>DEwi1wN-v`W|faR4tLGp63Wim6n&zC?QEy=L!0?ZzO)A zEZbgSi7b#~-N!kt_8d-O_AnhznU4Xj;Jk|)_v|h>KIbuB4LYier^=K{r&6FY(hzex z^ywkBH`k59>-vu=O~qD;7&v#~>0C_R1B{IB099e))yHm#1Gi&1AGyY;L;r@vmpowy zav~nJ)d;@o)^H^UC@mlS*qKQtSu*C(1U9lqdU>m@dy%^#S`N@UMSQZ;Hc`>s2BtGR zWajjHwdFQ?d?)TVl3RDTxZV4DJZjfcaL?~xCSkX?7e9#7HSw1G@Q{AXgI4(TQSX$} zYbb)rh?4H&ycJ7|FTae95aIxGf+>EYp&*^-k~+22&DajrtzsmdU$Im(P*)OiN%dkK z{UMA?9J2CQmQPld-rR+uB?;&giN08*#q&%q+*La_fBh1cFz*_!C5HdV-p-P*yeQUM*6Qe2Wtf{OiG}~!c0V-k(w=$PQmCuV!QBlwbC`bDb zdpn!_^SFO&Uc|i?C>`8xUU0Rq;2m_77bTU0s=VM8cLZEJw~NzVGXGb_eCbHJc56~L zzi&)WVV59GtUQq*E;7(;fsioVY=OqH0xyv(p*z^S%-z%1`IY}x^tjvmX}a)8CNSF- z@0Cm1Mbi=eluC}gc#TdtPXt3sE)@Z&2I`Lob@5s$fe0TG%g^<5oz^@MDu{Ddx>R%* z;?!?5dnfaiu@68QA2;T5AnEuIRT4)mc*);!+-*^?C$8j~%jU7rPF(CPXKOsOE~)o? z=nn6`bm+eJLh8$|oYI!b`nUFCwRmhk2clgPDR^RDNWaTmzx7g~Mthvu24?VwjT+3{ zwViGHGV!)3y4n>O)MdCwN_aQ(MV1ooMjZvCin?dpAM3j5GV3g4M}GzHfFw0PRkHa^t8^9)WV{NnLy@#hIX#?0Gu^()_|(x#pD}Z>RxahdU0E2 zl5Kl^-EJ5I4LD1T;q!!sja}3!f9Nh>)JpdAswUqr|1b_vI0E7-c~q-5m&8U8{8{-f ztAWo&!unw-9!H@*5CHHaZC~TxZJ#G(Ew@|QyXbf#j3c)wt#n8DAwnVs!(8tivw%62>ai(lS7HLQ#u9Q*En(_VM`{v(OT7e zx{Cwxt(0O&&X`qYVi`613(_0lSkfSQ2qCp?o)r3d-~VxKr8+itd)MDiZK4cUw?jqj z@!)fsKfL_jXe=B8@J+COku`_Q(G2`WXS=IN&%3zNdwU$?F?n=Q8JGwl(OP~lZ>cF& zW30$KyfAoHuqd!r!GrG}C(Ik%>f=k5!+5st*fajcuarbz8EW06aj{_Q-V0fg!l_ct z0`ue?SBjzqs`WKltdyZgKXtx-aJ1K4^*sSwK%p&}{i8+P%@@m7e+3{Wv1Z3s_}Dz$ z2LlZ4L)ygJxS6=8`i`Qy7Tr3(%xHV`AaE$r$~^EJm0sR4D2?w`LNP_A=9_%*D6oNT#~ht_Qux$q4_zH2RlcxeUT$=!d3kzzYDgs z(sd-Y>t4vB23^lNS9M#dVgr%Dd^$K=0Gfy3UVR@1s9TMesZ|*sb@~ac*mLeo-L&cL zUGbR-TEV|JbQ~g1vn(xtIo)avy2p3{)X0z!q2<`B0lP{yytmQwYx>j}Us#Auu{~a3 zjr)@U&RFYWp07vc(+P!_h87PL*$o64L+z^jqJpH8ChEoB-5ouNPpGVV` zEfg-wrnR)a>a}_12y)A}%BlZWu(ap#xtC|Gk@NLw$jcPHW03VDTf4AbetlV)to*%! ziLunEjD~HJZvfoDi}7@J$8>14^5F*ftI$msA>ai=Bzdl)-#t#9V>LA~R*+Q*AM}6A zzan5KOTVJ}%lMC-^`MQ7_QZiDr}*!e?xlRMDd+mVO&l4%b0i+?xCvhyj24pM&{=Vd zA+v|2L;hQ{lWg#pt+3(0bFM_XWaTUD!oYhxBAP_IM%R>kp3;z$F+C5SE=3o56}PTs zI}?1`}k--1U`X>i?8lzK41ieEv9XyKdY3W*S{DJgO^+`-~3zO1v`Khq|QUcI(_-?4I$K zFTH{oI?}DTERyD0@n_?2*M_}SYi^uyHo|g((QBnmc2F|6PX1kc8D0i2W9JPCDLfa- z;4h}`P4U(KDfaH@b(-muqdmF?feZhs@TMI`xo$^Lfyn;zG1$w2*^7;=;a^G0U>Km( zV^;f~n906pYaP%2W|A?MF85BO*igFRtzM!kKk=nMC&m{;Y)EB}Ru~umo#Cp!5$SIK zHQr#$j4NtUt{Prd@n!!sQ%4AZI-B@hek_Za=_8!bR8re~6wJlxL;EhqSaxIk0f-Xf zBxvD>s`w=XPW4qq=*s{*!Ei&-ww^)a)f5( z&^C$Pe5hCVwDIowtf?aUWF-_pN^lqgr;)ihe^XhO*fnb?g;FjiY2JKqh(t#_WA>2Y zkkMw7lU&_hl={sYgzt^Hkg%JIb``rjRiCH6wmaVpSCd+58(DYqOZ3OTCM+ZR?)aX*7cbF6qwoP1KvV3S1XV|?>wXSO4;mh7&{;Ug75ZsX zhhpuJP+6T^4ELRK!Vs#jWl&P}YDn?wtESp9+2BwP8>FOueGO?;E}<*tnbT4 z((3VW^0`}#BGE)z1cqM4>Rv;>2)h@3&T^o?d_1;@;4D4|Y@#}lWV9vS{K^}mW;Qfr zvp6h@UJy^j4qz_0^>}~3>2MCb@wv7MW&U-~0M__(F4mlu7b0)Q#5!is!V)#j9O%*S z2^osX;xnNOeA%V~cV2(MB1|UFt_=K5SlW972mJKvDabQ9f%U?+dX3@rdG2Yr2R1GK zG>RZsH@%tH+;~vu2dQ0Wc_k>)>SitDxp}OKTg{2d2sUd%{v&?sj<^1fZ9L*yIynvu z;6TvdwmdoIp4sp5^KAv!E*d>#8N9!HsymD)Uj*`YI8c}yDu;`g&m@X;s*-sy1287D18U z`zITV_jdC@S9-#;^C`{Vui6clDiLS1!qZR_1QP#QClV^PdnPia+(kt4F?#a5oVD`< zB!I8_9@m)Z7s+ijpXR3OaPdoWFc&M=qwKJD61_KS_u2_O&InwaM%waOwq4bH<+@b| z&AVEPXXj=GJXNh0o3OxC`|^A4S^ot}EKXu=O1{QLD?h#j^+6gN$i|K<|DZR=XMhlNID$n|KcfRLZ= z`wRp9d?#$Ij%b-v8|zsClzJ)M9V>*SFr#B@tY?N=fmAtk+E)UBVgBSH(>pP^z8l=@ z^4`yToViAKy+U;m8FU3FXs#pFVZH9^zbqk6o5d<@mvsD9wa&88&rnwxrsWzs7|Y!^ zUW>#aYZ9KA9$nY27H8Y4Ti->QX20U`-zdZAD7~NPIDYn5X)Bm>gM+5c=?_4Mlaj+O zjxq@cfS_T6`3ojfOT8>Fu=6%}AE5yQcm#I3Bkps*eJ4?;Zkh6(p`%2=;`)dU;%rLR zWXpp5$>OljqV5iPa)VqyaJ-%t!prd-&jb1dk?nU1u-qT zi3zhUdy5v2?6)5V)jQTl4>uU|?%ZLa**EWb)hQ&>O8z`}c1dsRnRrV^V?LSelsjKx zO5ZX(P*3rg0RHk2SAYp43!JVmAome?Tb!dcza zYp~}KAN@Ngb!rFmvoJ^;nYnDd2o~&z_`>>N5xj_?tYoGjH@JAa(J;01!Byo=_gd=tZkF ze|jq(Q3s0KYz6EHA=2O5~^hk>H&Q?_jzKxwS&I`XH;_thj z)qe)VnZ-)$!tmw)Dk&UDl_H}4@icLug}iVPIP|uS+;CC0Rh%?9ysbxNm!ILZ*5>NQ zk0{3$UN=zDOphIJoXo#Q{1XfePuL*kBxMmb9i9Xs7`dFiJPi`2P){H5ot=Xb&haQo z;M|M@O$77X0?%=o^`AsRRBH-|1Qs_Qiwy4g(f&AOOxR>$%;g-pFf4xj%CdM7B^1gT zewvjcE&6>qp8kjUA!b2C6HXxrw)_ND=7OZI^?ywC@C zEMgTA8JN6&L{(m(PnMu`gwSQ+|*JgLCJ&+biy122@Q)3jAo0rzIYOJHEDi`ph<>w5` zsamQuO%#VyXGG=q%beQgio0>{)7^oX1&#LB2Ve5xR4KawLgpx$IMIswCVFRj;$2D{ zLMAuPvIn_Bm5Z|j0&($BG2tUb?1S?iXWTvM(}T+Ms)Ndc+78S_sKFdi6~;h2W9UFq zn4O_d&1w7R?1XK7O~Jh`9&R+6oR7cjPqsa3vcLBf@r)bg>sy`QUX@s^fH&=KYZBY0 zUV)>g$$2aaBqe8zyO&(*?aPKTqlIOouBz5-jSgp0Hd4hRD~a}F)nIlG1{N6g-GOEZlC>^di^6S;<*_q}bYG|3xq6CPC!|xo7DA1}Xf=GO2fFKo+ zOy;$HH~T20`TlK0KL`>(v3TC zY9^vtee=QYy`tOKVwP>WuiRC0H}sN=drb4v^`p1VM<9B^-<_bmMAI_|cC!TET(!Ks zqQonBoA!03Vk~p1sLj*DDLHNuYfJiRU3Q{OKES+taz`liW?le-jRwa8P0)*vWp2rU z{l5%*>Yq0iP}@qP)yQlJ&_16N;f+L0Oa;(9+WBAH^zw6$=&{GYQyhLE#^z!fm=;); z$9^h53qzn$dP#dB05Es@Z;wl z&p{yCITgT=(^MDeYMOJu>l_0f=JdWRt7=e_DXz-7GbSKS{(w4Q$RG#l(@s zlI*3jrpkq=3Ty5YaOI5$&Z?>Y^r4i@lon`G1C19OABVNMe@meBK1gQ;+>*OrcI?(G zF`vP;suQnt`_qB{_GwOeT<^{5l{ChR9wuAJ6^!#w9_MDFpLC^2T{<9ms(h)=?4^u3&*&KJ^Ahf5w8GTelh5o21Y`B9fA?Mev(4$%Akx}oq7eUuDbXVe-xOkJkIj6&i$!+^ zWwB(rjKJ)wWuned>W;PbEUjR9pc-uLB))8Uu6XU1E_D;-D70)zLs&YLKw(#stB9$E zuPg{1QU0Q-G^@=2m8@}S@%6y{6IV(a|46k+0p7|~N1@;2mJ-;Z)z3s6J|B()n#~mI zvSOvCoeA}zeAk!7uAzXPZJA~4R)*|4&;~(Tv73w)0uNUn)w;ND#nK;l*q3)O&Y2#$ zzed*%3&=QPunt9ox^MHj%5bwx&w88_NsCp@TF<}SX$rAH+HmmkLw}f~!A!n)c_dWf&uI zh2)Spz>EV4GwswK2`sTH9Q}a^C96UWuT<~`Pb^Uew*SBI#4)=b48Qj^DPcI%uxEDM z6wq9xvo*$^Wx|23jw_;-9yVQjcB&I+^+#-yKsOpXpD@#@Smkx3mTm~E@?fstf?c{9 zKJkJQIwdni!3-6iHWAprd!L_k;(D6d7kthX_1@MPO$5$xgR|eAhj_>7iii@j8Y-Oy zo_`!<(V?m;rPfmC!s%_$es|LV%%c9t{zgz6#a3TRC?2I@xQdvf7=@Wv;{WauY@|5ZRJ@B!Y!bOPW`l}y^;_4NL5gUCSry&(Kv|EQ z{xE0iJ!dhpjVybh=;W}J_uf7_n-C9y^9sce;`Fhkzo?V z*!eKFYh!2#VN_U##`*B2hfOZC=J|w*Y_pSQT+{ncA0smA5jpt22-#D7le>1A-zO~n zGxu#u)OM24_T{?BAwemMH9m#}vjVN>vzN(?jK?5zegV1*eks`k*Dvl}5B0hB?^*s% ztP6&=%D@uoY~i2sp(?+K%#V$T4-JpX%!WO0G#WbSwK`|SLh4QQx9`lN_ z;|iE5_vpKqe$lI;A@o@qE=B;GfgmU`i4IDC^CY%8a&`g7e>FfB#ap(1yrs__00r0O za=KAqLQZGSj^E=O=@uv=w3IvUF#%}$#avA0bmgM@cKGO|2oPgo| z?^I6JsuF++ICS=4OccEQOWDa7re#pI^11(N~+qG z77OXvd*v&b!{y=oP!XE->vUYRxc)qnlf#xrfFy&Mks2-zK#*YXf4t`eFVlVZ>wTZz zbY;Y5zjXrp{dZdhPOV$EJGVOpfR)B0Uv2Vn?BSC0cqIIh6bnvh3c`hxSM8kgG|C6T zE{UGoQ5kN2@)_(xI~KJ<+UnAh9&&7|eP&mQKTeIyv8@XJLuo9b#4>f=E$-+YxM~-5 z6N(7aXufkl8M0uMp>AShTF^@Tn!j*6kwA%zrdev+vXwGv83h@&Uo7`3m1M;TvS0r_ zm?FG?-Fj>JCbJnY8t)1v_e>A*LI%lAhvy%+1McmtH1fqqr4#8C2Ef>Z z4@u$dP#$WWq^O}5Cz=7+U?jouiJJgxBt|8_g`F<<$+GXqUOF&k<=>JS+u6Zc=l5Ly zL>r~Qb7?H98L=INm&r@VijLD9<@Nuhwn2<(GI|mkrw;8&C7Gi6B$3!#Fl^$ozkc8d zt@0z)&^X%_{10z6%)eMq!MYI(?0Gx^YfJiwR@sX7c@4l$@4#c}lS7-(YhD*#;q9Sf zn84&g`n}v%?#Oq(y;Ad71{mi~_RNX(PUKciUCwOBjvk#e1_8dAOO!gQS?!45>UtlF z|Dl_)Qah^lh?w(;l>(EBqSR#OZ08LmleB895R^0_hyMZngB+S9j3rLhsDb=F9e+!u zn?zAbY!L=jL+I3zfbq&Ug*stWuYv_4fW(rNiDX0&K+fCMFSQzISb}q5{3I8tVS$$UpRN?wM#AfO ziA;f5*P+Cup(+c*A}&_ys#P{ksb2b~U72*ItAA2z2~;X9%v#81gn0bx5jR{HZ zUwAkUukEhW5q-Vb!8gd)BLRKpe5bD3zq^j+cI6IwwturAFu{!Rur;zKZkrd4oLihQ zLKchZN}ALtK(GqqsCa8~@k*vK~3w!TY6qJ>Fm zA6g-oc;;5|A+P>r@`+5IM?s^@vw-ic|Du6@|L3$<-lV9eje7o@H$irXQNLU{Ov_aR zE20iYCk3}YYUEsma0PxAG?pY{a8dou!#k7HX)y~u;~&n9yg;(_D?SG83_Bi=OnSte zV%>>D{Ak3Y-QmqSiJzdb*v6jV7aYWpN-_F~#HJ9j^d2+?<&yUW@;r&-IvD}!hUf-~ z4>6(Fanp8mC^&7oqCSWgT88*T*8cys= zQ&8G>*rQ=gSsyk1_qj0F7x=!Egic_JFWK)*O~(p zZs8R<4+IJm#?BWZ_h43cIl#|r!#5J=veRn!X9#v8Cc&b@sOS)?ab`Z5FugE+2>E+^ zATpUV6EZI1rZ4W}6Q7R94eM@ul$!e>zcMMRW9(oSflFCif}*Iyx&3*VYIrsaE{`jA z#GfO~w>NbK_`ZR%QnX0Rbj&JdjbJ%{z#}0zCybOV96JiCC^X5p^ScwPX7k@zz-*0J z=|uY}51MHI2)87U9wljwZk=N|UZf3X}5%qcwY2|+DOUnHWJh1g2FIb?c%fSE}&uk5Wt?A&&INrCgPc**I7JJ4;2}PEsy{lo8A(R*qV;FoO%jTEa z!*r?ldQR6am+lQgP%f8E?fMD-{Zs~D=qQg^yLxlpW^W7^uf3?h!A+}ObI6$YEMe!x zAR6cS-CWc21uoeUMvB!=cWUGXm^i*aw`^Y9)1l7&%Y;B3)>dO*j%!~lfVG8lX9xar zxo6IoQloW{!{bBzlow$kHCk>u;)hJ(-P>~$_F{XLlr9IuYK@a1?`ue52z^R<=Rk%R z%X->nLR6Lhr8iIOw{vGvdi#GhE0I6Ts7BLC!1C8aQw}Y6hI4+UVKPP+hwQ1R zfOzD7XJTOm^OF~3Pi(T&h9}hS!rWplh)0u z)PD(9m@N!nf{OA4efl!F!tf}xu1zf~YZ21|RgYH;FjI0o2;Q?#gViF^*RUX+*m2zpRC zn8e+PRZFXv6MZfu`@}95;3VeFZSUhxmjXt6e(RIhemgUp?UyjdtjL9`B$s`rz%+ig|KC_Wx^~LkiRBl+#v}yb4!|L6i=))Z~XkT2$?q-Uq4>;90w_ggp(bj3`Pq@pv{imbtH*sQ-;v{ z@(FD4RKttF{_rf##gy zd=R5QqKFsy#mfDYueX9w2Wq+!hgpqH@;@6DMoHnRMnDY3oP59Pvb_WxR(cXCUXcIF zz3HQM0m(UR^Gn2w1#rt)kgm3UqT>;^eknsNj!cq+y^Pi$rmoksA~t@1R(^>Ail}L2 z8lPA3ndfP>V|qT1U?^JcX{v9$T zfD#w7GJL#uC90vgrw%!uDUm*p5>Caa3brqvB&OfSVc-L1xBids23dIrhu#ijrn$^_ zZw&zhQ~ps?a?!bv$%L{J>6AsuMbfua_B}1!*?6NSEb5d0{%h-jdtI+a8=j9XoQf7F zGjgD!gyF*ZgP>uQgSlxJK97X{$R!OF?@Ppu&pe+OviKqjf`cJ+7EMVJCmpzSmW){$ zQ+D}K)Y>7i%Sae$0fK=dUzWE2k8vL@{bQ*TkuV8*8dvkMXHvYu!m0;Y=Xtb1AlV!u znCKz1fL`5)tk?B4+?8hN=R=U}*2877k=q7TVNbWfh^v=h3>4#e;?r|rdV;UtLniVS zXjajP>v8Zq&2Q&K2l@>D9AkYbY+p?C;@vrS{BX{)|Gx`w^>82zt%VV{pxQsLE0HnP-rSQAz!+~yt4y(crF8d4H36fJs+cX%eT92F zNP_aW-kyw9w%@Mh-uWm;Z|)OWuE7?5ghOCbwJS4CEtXlxq)ifMbw4Vy+Gg&K50}V1 z(pC8TBfV(r$rey5BvC+tber8(YNb8ZqBvDA-ok`uXf9?kSirsi>tH9Bg`IPhuyb|@ zy}dG0F6WC?2(*sPsMgVQDXakpM&gn;a{Jd!?+qRYfA@`N0GNHLBhkA1Bk$NeI6_dV zT8z`7GTFEBY_HQ)j_++NrQzy3Qj5%=#wT?kH&v;3)H2i;e=H!(c?5Ye^;&?TI(afv zl?76x^L)~=vtS&iE=;3J+4T=rtx%Hy0d=;+Z$t~z>;G%Z$enf99!$!fZtET#-C`$- z{z8xjZ?eB4${hsZY6>>c>LXAeQv}O zxRvs{&xuvteUItYth1h0XV7YZL`}`^z4XSkHqUun27&H-Do%i&UwXc3dQIK!oSZ^_ z85jboB1d$zDW-?0PVkSe3J@MLuz!@9no))bDTw`?_toBdkM2}Q2LCCVDEl^ue$ZJV zT|k-qZ4ZMRymh-~*^-Ouv#96(4C{67eTU_XqD_@^YHxY4%$uRj0F+z843k z)JwND4lX%m`PM)60KN}88+g>EY2K=Vj$qx68f{kL6y`uoU|zdfk=~M-RyDt*&kowR z_T)+h!>Ph;92trEoxCP3-9O#&t;zJ`?JajhvTzAKNf4>oW*r%NYGROlwL$t1qPcc{ zqCZ^`b$&cy0Qyp}q*aFI5Luq}dkQXm_6*k7s?B5`pY&1$%zOVMRGPn9%achgiYYNE zc39XO+1uNXH|+s3I*GQ!aCV7B9G)7m8ipRPT%h?09oA2ua7okxYLcivQOHHuc<&3i z_#O}o2=Jfzi~&7kC=f8Kd@ZO;AMM@N<6cyz*2hzs#3L#TCKlbO>82erVl;-Ke1@qI ziy?3P4hx7PZFde}_#-9}&*^@J9pESU3=f=1Z6f+Xxm%4{K>L&4O9-ScyMddOlXapY z*4MgBucO^FAwXZS4|43X790(H!Q{^$lc=&BH_=sg@=lq2;PI_dnVVMcHqLFleLJTe(%tbf&xdVy!^Xc+vO6Sdn_ik(H!PGC|7)?eYjQ5Ws#I=iE|dxNM)Q${1bb2qKk9O*lyIpc$oG7wjRIjXAP7 z;^J8BpcX^%1G_|FY7I8aExp`%#pKCzq*4MsQ9d1*)a`5E_bU*vZdc;(3fZv4I^vrC zB)cG#fGETwj~sg_`mze(gK>Bd1ul#NGwg}~Ep}&mi)+sA?>Th25#Zak@j)hMEGgL< zS!8;Edk-Y$V=$t0>Ch(2DQb=`Jq2aqkJ2;$M_ao87pH}grhm}psATf^#au;Mv{y>Yqvd3k6!>qYtmjcO{8yscnUu1s^$S+nOT ztujg5twMimXi8V8wadeJyx zMISVXSL$1>h(mk*W04SQF{y*?e_%W1LkG9CfK?8J#eA{3TryLF4o8_Jdk~Wi<%l&o zWTl9f>h%F^9j%*mqzN;WnzP_W#1OH(^k(i9K%ON%6rVTj(N^)s@ZQk_dc0#g09v;h zek1EH1smFGbhE6984@Efacg0uc00a9LjqLfK9_sL$TM6w>jyeUpmZFj#);*rW`8p# zfz9&lPt>+@yS;y5m}v(S^$Zh%yXmR$XsfgkTaU$mE1xB*o4&F+nHwU(#e!T*h*lSq zBqttc(}WmJtQ>9o>M4zFP33=liuT|tL|U)y6mlYm^4a&^ej|4N2u9BX4=}y7(ab1r zqP&}n62ZLKTM;Zx3u{^|Io#1=kNZDf6*sV0*66cQ^QSmRy)r7?mvGX1!&CoX);JH> zL+CGxwk1FMnY37)@$F=seo~CGxfN$b*BoJvV}ed3q$1nsg~-MP+`)umRcLV8uqZzN znA`oL3=%j`{iVaK&hy~ZLVwES#UO4D(2tDV!Jj=rJM#3Y$ zpRC?z@mt86$|1C8!#A>7~;j>4Wk8|&ryC}PS#_vqp#&gqv<3>xh_PGy~9@brcm5-|eWisD5>&&iu;awcY zEwL3O(G=R2=Zm>gG#ktMIRAhf*h$YBm3rDd%A@_w<;bTIPE99yBW;4Hla3>&S@iyG zP>35g!)0)TnE9aMR+mt5sbcc5LJBkB1d6ih(y+1~iI^uU` z_V<{0DjqbyelHplxL`_Jldyh*_^!WeJ}zc?ddl)A47p9# z|H$-z5;Ep=oT|9bB01G+!A`Z2f!kI=ElBb#uzvBT%HM`>Aq&HOCdn(|!vEd`WsVx2 zld874jVz>_GzI#dQL51XT~>ksQ<}FZ)4Di%`l4mNU)UbYm=QRi2G+ICIO) zbCj;ohdM3?s~k5(F_n=b1l)UwNo~zaD1$K2jO3Q|nG638bqnLiJ4vwaDjq(^9Yr2( zZfNkmEbnA&EWK`<%4v9Rb<4&0Tol?wnsa4lK#l_!35e&!XjL7jkaRF)qMmg_o#{P< z!6x((>7v(uxD2=r1jf3I1_~72d^|di%4)1iX#&{AfHn;wki2qCfdTPq5+H%o@H_t_ z!_$)L-*9=<;i2}%x|SWI3N+nPF{PI`5PawCaiQI;n+V{;aJJ~DXNPd=a24k6z_~L_ z;hUiv3pR8?05&Z2)(CW?Y6hJ}_CIL*(?@M_#K=K4W9fU~ed2FUw_Qu+Qu;e?SGXj# z*s2zM>YeOWZ^|DplAAziw`qib&eQ_TOl~i}Cg2NF`2V!8JMO@ga@P;9JtgJQ^y!WNM+R6uGIhEEraOCQOggOE3jqvp!sELY03BO z?6oKV90rxIGLXa1*~&i*Bf#n&e~#t`3_m%oLxBgQ-!5xOGH!w?y$+E|t}Aw}%glC+ z2jDl~lz;}qKPyj~G9*?{b~>V5Kn^2=->YGViNvgZ3G06B@6G+)=RK|q)wR|8?6c%+ z!<*%qNBHQE=kl;la3HlM1}!-RTTqVf0)Mtzt2vtSKMp$4c_HE~^=Z=Spx~>P;&JXg zpyD-vn+YNbiem#&yvj^JH1%|drp|F`L3#b)IFsXjZ{h-)?t2Q#$aztNUpv`t=Jo38 z)ht439~go)I3Tl&!Z*o&Hx2yE+|rkfD$j|mz{L*sOJ7fT3Hoepx?OgQ`O4P49# zahQmtjw4Sk3^fLfH*1-`<=LqE^YrBJ-tL3^MM`j;Y^P1asBt-;Hm)ab@oN~V6PGX7M!SwTT3z!v?x zK8$Dc9aD#7HO0urWS)S>uC9F=IYnGNr7)wVioW4vC!AMWVEI%1_(CXo557Y_&KOXB zXJUV&V3tmypqDb$`dv4U09_4mueFtS1P&|nNWh_JOsh;O|5h3lEXbcsBb{EbKgbO6 zD)t%ncm@iAGYRVlU32(VN9j(89NhajTKIb+R>2x<;+OV1R%Y{k{sBD7U437~UUMa` z(a;L#NmDZ{0@0y`*}^0P_!ItNElg4SCy}cIG8a8&jM{aR7rEPo_D|+!r&Oza{O{!y zvjB_P&O;vHN$aC5KtZ6NAv~s)Ll&5SR#G2Eqb)?~yIE!UUjrN`FlxfqOF!p6cKK%( zwgoQLTBwCug8aY(jPc?e;+EJ-sBH-=w$!LZ2Gd656@#@RMJ$OZXJDv@OB+BOxk*{p z3foch_huwd>D7YSQqZ@fV(LC0A4zW#_U_o?vLNq$1*ssrkdjUb0(um3mgNv@$i1evORq3wPP$0P z-u6fUxt-HZ-|i=BKgg+r5@^ez5~RGr&5{2>tusx1;MnkVMuUEg-VT@-hd13{My#g9 z@R}JcOE<*gw+4!L1|6#)Spo`(-G0- z#iM0q$kc20TEo}WDhsD~y-yQev%wydpxG zBcs{jS#dc3p1}MLwNnMNymPh=t|CAkWmY0L0 zW*+WiUNyR!!`%D9Ny{o3lc4C^iCSF>3<`<{YGWNc6A_ut`L3|0@OnDntskpBf5$g# z!)hBjoNJnIGP{0|QddjLmbch`T;zflv1O-h45m$yhO`B?6=|1{q^w~p0eIz<3SH zvSF-3uobfF7~v>vOl|)kp5DPR&;R!xzT4ilZLGF!x2sm$wr!iMZLHR6uC{Hhw*B<8 z_wW1s39npNl9Q8@gvbP%464<|WE@Od@5RS!229WWyur)R5X}tj(2&&P_9u6>UQ?)F zx9>;?rdsu9a;N*u;h72I`IlN*<8+1*Kgh6$X?A?~KS$z%f?Ja`Yw==rXWQn_D2o^0 zL9$eDnOS->I`8A2Y))rRqHki`Em!o_Zq_)?uOUsB4M)qdRy4XC{c{?Lk>dXO6V;Qt zSk)xKb9_n1jk4>*06YFvyk#ti;-##w1P*(&ArEjjSa7q*E zvNw@p7ItR5k*qiC1$B=6z%W&tA{)4YQO!r;`N-?!<(lEq>*cy3BVQc3XtX{Ih<1;8 zNjmN}Qa_g_=cLyenQD#h=Z}Y*FoCO#Sh|b6lcRp5iX!&J@3^dgL+aQ+9rldgZn{c8 zLh5Gh)^0C7E=!p8EQURkyYA}Kppq6QX#YbYS*WT#?4(BN{0cRgPn0wqN|P`neZKMp zz9bKGA+-8oh2IFIvHdHT+vGKBth*`!Y;2B~b-RhAeU`Zfk6CvYo}C>~aEEO##?J0z97W$1UdmJNo`JLs)<$nlF427Av1uX-4R*pRNS6OI9We{xY(y$weFO z{7m-Vdl`x==JQQ{U#ZFr&Mg5}sy=u^Q$$CxfQK4$-R4Z+wwr`W+wTE z&olW)#~QLw0l)-}pcSpaLJz@}=VENc`!%j4?%6T8^LYXf?n}D;Ij8#||BATDc30Xz zf{K>qDnvvlDh`M?39r zHED4}k=1beof8_U4YD{Bn2$gc#f8fQaMLj3LQbA)?83=aS~316L+W(Ey1lJR!&3fe z7IdaQ^oJ7-5$k!H4BkWap<83v1@AqV7!-`J@ZJmHSE6Q396ml1y{6AN7Dni92o?0QwX~@Pc zeUFzu5BRyuW{au*TRsc9xI7fQaXdj%i5^&lpTxImU*KJ(casx7nN}U(aVH;<@#bN`L}|T*`&hT$fxWQ z_-KSIr?eIkX_Oof1NV}4OI$L15{;#M$g)XA@}#DPeG9I*v<+2)r$zdsbh zOpEF6({)uAMoZS;xGQxd5n8bg=!wejs-EJ4)1OG@gV)3enrO2Nx4rfOV! zIa|Dxv7xV?Zf}0ZcwBXNn-8vXxYE}(Io)dwi+axbK$k6^DBKE+=N$g_c?ic(eIF!L zxVE@!)pc(>?i&?Y6BFq852}R3iwXO zC5rF-b7Tr4Bs#oNP$aGCzBWrgl{Kj4Uw!&ajGme!oZ3{T{7l>3F2^@Pfy&4~x{TX4 z_U(4%{js-G{R#Mb+~JsgH^=8&)#ceDG0at>He@Z|(Iq{u1m9@`&u4%hlY^bC# zAtNw`)yM`WzVruwON^lN$xb%&^r!Usif02~8FnM?psNYH8>`SsAgN@^DV6P7DaS zlO%E0+tVo2X#$jt08}b_Q1idHa4jX1f~gN=ySA!W$v2)X9O4o;Z!Y76AF+BhM3s0e zm0G7Zt(d{;cZTaUBE&UHBho-7-Ur^Nnl%(vHh3oIjYH~)rQ>R9;$lqG*$FyZz_4b) zSmlK9e0(!JPWC%gy&cn z)s|pHCo0JagkECXYx?gssc0f)8F0?0@XFedEDsVD_dPI%a6Y}bHAR&^Z%G@U_F0oR ziZtJr`cbxICyrk9#Be z%{>l9Y$c>=+?LJBM6(-J4r@nh??zOVxM=R;i5r0$3R5iW@zrrg}gT z>rIOu80}Fei`gtj<#_I+I-P-fDHZbCv$|sYS0%Z}G@yqTi5N%|n;^GKA@-To6ypiT zco^LVX*9|;x^X_0+g{U?64WpQ=O5I5gC_P$1zj7rq&o&&Rv zU_g#T%P>+j>u995O?OQn5R4A}25g8w=ne&cIOpxW@;kZJP8x5{wS>4i?NI}t96f!2 zGYo`F0)}MAFhSh50r!2hij||Jn5RT!@v8ac6uMJi%{`l8+xC%l9VbcJodhVgi>)>fY=9HiO zk3oFOPMwO;dhOMU$3tNI$MXUI>gR*hf$z63)jT89%1&0L;Fe4w78;BRYL7 z&2FM@84D~%pKUP~c_u12=Xz4HG2PUsZ^MTc0#!Yby--RsrDN(4bC8)X<6D<U`%ze{d{2jfuHJdo^0|47*L^hWt4*Pr*>3 za}27Lqn5W1nwRq~yC5eq8YWfVXj-T^b*nN@-@jM$#xGW7hJS4}?5$i%9li+P+!>1k5qjw_~&GaR$7l3f&@eyh#IW@@r0vVjq}Ojwc<16f}i8LUH&zy zYGkDyXsL*!CCzv|P?~Mj21kwKq{8C=pLPJ(IAT5=?N=p@;-}D?*x>|2bh1U(M70_1 zKx40qpc2b&fmT$xSzcrT?sj!Ktkp++y6~%anqAah0Otk~#Ufae4JF?SY|l&U!04so z-aeW+yuTLWj}K6tt6QIq!m+8SnpzHLTPxN^c3v>2IX(+{uvy5`yYp*W#TM(zz6UyKNQbAtQ3<2GtQbPbxz}U&{8uI6(oyI5Mh+bb z#!M6_lRmCgbKvUZ8xW>od;jbd_+qdNirrmP#rKD>+ZdL4f`i%;Uq%!imWI~N!e|1Kn{&?^0Mx#<%guIrnJ##efH3`ccQhOiO zv0+&7IwP3yubKN6QSl&VOumaQp0KoHo|=}_IjT`vlw>x{&&vq<-Rp~SJq(h`e2!rt z;C}>x3wHt*U}-aXDuezcB4$F4XbdOQZ*6*7!JmSd&e0>#GUukJ(6zFzhP+c&GMG~a zF37yF2_>V$$vrDr<>*YqZU18#Npq^g#f){DM;e;T%N`)qZZg!eVnFKujx~M=%;0|_ zai0^bP_`%!Gj)40%pXhVDJ?Yp;b0YI12g-;PQdwd9bg{vKD!xS2B_lOZzRRij+bXfdhoooH&EeX-@eBKj>|vxvLUUR- zGFtWIP%3$KiIJ0ytX#0bx1q-E!4d+ti_hvSY8Ab2pE41!EjBDmt$&|%2KZ@IM*0*8JbxT|~9EB1el zC5|pjcJ zIyUVllnq20uov#wZ#YbdPZtY36JcCyR-6 zaJ!$;7W6_h*?wwQr4$9x*J}MPfpdUs#6J7f&?#!52a3~WqHSs$gmmxoWV@72$GG&%?q+l6I8!=^0?~jOB*$`xR;6MRS#y3us6$LS|!tuO(EWdbs z9I86l^jsj9YG7Slnrg_@-K?lCS9_d)&bj15-OoOW&fiihl>vHX-*CZ7KbbobnU$O*!;~(%FglJ?3dVrZ1O59^?8P*^Z-4%AD`ouG}-%1_NUvSaL&=ZfZ| z$3p)C!d0Ix4~evOi0sguBvFUO$%@wc2HQq)9D+`&$!ImQ7@^@&A0h5D05^Qp`Z58_72?~oiff8)GQ3s^kg+-0WZ%ncwTwUMv_(Sff_B;s|iew{b9wt6I+ z-iJin<^gJoovB$#Xo2;xhN>DS0GbL{9V35;xs9wj-#;zshwcExD;T2fBBSd|>TaRU z(_H6WQnnXY`;~2d8)T+w6f|Sep~?_lH$wo1#446em*|lTbPBOjCis}%xFMj>oqIwa z#I$fWjorAujD}q5nG1#)VGpAQLN!1uWHwg>q=<94<@O%2jc)t>w3mTTUKUsP%|+M1 z^%~k^A#8VFjTls&%#fo#y#jId8>>);&5!|BCJYD?=IV>e^L5-upGu$C1op~G0A||y z$%wE>V|7yTkda|6C7(p1CkxDKeqi1Z#{c_b3;YAoKK8+rqBKHC#_Qv_*5AV$BgH83 zyx>%U^(CVowwT=65;`ooUOxb$xwrd<;o;X#U$LK z=)T$ALzfU6py=fC7$UrbFQJ64)JGJ967m}W9EU&fmGz&Ni#hn zAFaCheWM6Ra7V_r>m;VaCG+|r=pO=xA-C;A8rUp)1$Bm4(4G4W_$g1SYlh1$HWyYR zgn`QxYaPT4#v|579s4PpB7vc`6{S8D{AY81qyMXAQ8H{eRV^tr2xAW%rUTW|1K0gH zM^kCA?fOjWh|5hn#LtCGQT&x%_j5!By;*JRlczGqZ!pp4g%{-#x^|ze)TZYbUzc}Z z8mb$DE3bPFyP<2FG{#NWn+rg94D~P+bK2StMM66&| zpFmpgZKrbE&x#N0=c%{ow_yjDoAzp(x_tOTR#Y@TUO_6#0}&r0|6;{W5$H?^#=J;B z`#NCu%Ldbf4vrcyr~bih>59{RU8Vo8sT&ieklzxh7^GU5Jyv-Cx;h>b60SfoKNiQ1{}r#fCIcgxppmh2dZ;L zx4|4L^p{?PLF$Nh9pAkfv;2;8ZXL{!z?e-U@ik{5{JyX$_3{NNiAMc<{-;JG5hN4! zm5>MIJ{xEhAt2@RrMu;;)8*In#wXwbI; z&S#CjTM7LJsjudG)lgR6B`?k?7X;ZTl({B&30RbxWJ+`v;d>P{*u5{?I+|ej>xo$P$<`P?-l{V$IEajs4VIU4Xv>W-@cBMM02J;zC%ds zQ_^gO8%8xgCV)}a2$+c$CDR3ZHlNRE{NHK^WDda$ZX~r+* zVQP?QiXP&YhhKk-)GkK>{7NDt9!ubhu8#me%$k2Is`ejYke?@z;izq-ASCg@G!&m; zrTP6=f(s&4Atl>h@R?fvonF7!Pi5|}+2<0Ue^}?r4NDcn$PWIiY@WX$Wh|2Vvu+mt zuy2n()$nu8qhGEYqi`=k1o4OcD74rn?_cJTi(9$-8_;` z(jE_8s?bl^Cy%6_?c0Bz<)y+DhoPKXfQcpbBwBo2Tj}0JJT1Sp^BBPMbsDEr!8iB^ z-WwUgM~$6*T%7+qPEW;BdT0t*QzU*Jsx`pj*EAn=q<%2pCs{oSyoSOq1=omRGE{#H zD@%qf0oFR9+Qaw|+bybC%^<|1W*fbi=_PIU16bVQHI>Fgw>fJ&q4VfZPOxLR{@R z4qw+YWSt&NWwaS(_`OJUj~JOWl=H(<5&%0&pv)Co+bz(@$x6({-6TVdyRU>10f(~&AoTS(%?*+yM7UR4*6#P!W4^@!CD$j9v1T>3;^ z{_YbRt$z*ky!Ysm& z5v=+vmY$sjUbv71X%LwV(=DPe_b(-NI5?O|HoyVYd~Gf-xw|dU(z3*h<)Co$_GZ=S zLm#!>*SzDTf-|1$*a-;%RS+;CJnWGPF-)Nf|1++N;3`$)YmK=*YmZ}0SRy13*M=uL zD5WoB6p-s8N%lzB<#GP@^_+hNneqvT2l*9AN&t#_z>^q|tgwdU?`Ex_e!~Gv(btz4 z)wJ;8zIgijX*9&+;+Hh1ww|inmrt}Lavt`Xh4~QnoSrH9pr8m*8*DBRpkZp?Pf0Ct{9h}-Yw*z#M-QSyg zG6XgS+Y!cZOh+K2rtteri(@k%lT4kKS!RJxX-zjTE9bu2VJ) zoEi5t1nVKx!b|aX?o;VfVwdRZ=vHLs#mVk}`p?DTmcTeXZ!DqRk36KX~NCoz_o0;`B z=>B^r+Xv>pM4YO$SE`+Hb0=C|Bxba_MM|k+qZ7404zLCPrvgz*+9kyt6yC z_FyF1eX*4sSM9C3$!V$LdOt}GrmlfMH^ASdSeh8H%BL@p)YP(Sp6(BDzxR(z7<%QW z&ZRtTqK(G|X7gr-`Ry3e+kR5BPk?to$XCN55l^ncKO@qllXKaa+e^u?*O_>-)E=iM z)duMAIrXP^BcmAx5lUBA)$#ngo@a8Wse6<1)e+&KY52h+2ml8Bf-JkX(I4;&s2JKH zhtT!Rd~A6uEFb)FgE>kz1og-9y^I9wNm2n%rH6J~q*($xIAqQ0`ljmzIeFYZBwW@o z-v$K;!~?}6<|Nt&&))>Ij1mUB_Qw_lg{Y~d%lo@@D<-qa1WgDb(<_7vOD5 zSth7EKnW)Qw{6+27F-4t27r9pRDv%KbxsRQ^ZA@sk7x6Xu+_t^4;?a-cmIaVT}r49 zmJqn~ZCvA)-nKjMQyK6-H2XiZtsU&k52=&_UN>h-#cJgp%hq@7h3TzlXwvn>z!Kf4LQuZSK5gJ{=P@6#E zukz^Ok(NhzXiH#Bjp0PTaeY8;O1S{ zhc*H*eb)UHKQx^OACHAwKaMsv;^njUk9HsQIg@+7nr|<8?C8_L%n;*52T~YoIUp7S zkv9H_vSTzS=r0%k+P`_s!Et!toLV+x=AJ48pW;M@kQUh;d%&71++`WlCKXU|Y<0c% z4nh(IF1iVl&nHv5Z752{$bAU^)OyK3AizxzJp4Arejef+{g`ahRJ+o_AuQiyTXfiGcUa5Rfc_MSmo8e9Rgyj zDQ=l9SnbJSPkBi0uG<3lC$xv&skGzKOgm^jWeg0f_L!t#Gbny7l0OL%9^@Yv!D_J4 zR-&a4dnf->h%c4tutSi9ejgF&wIML}XRZ~1B6#`?6B!8p8QTTH8MqA1^UrLg#3&9;jc!pfOeaSHfrs3ofqQ4XXpbDZ0e8#j zP|0?lbZ2{rl5Rbuv}dY`p&ls-Yb4@hr;LFL-rr4SPd9&4wYIawqQbHvC?GO#>%R!7 zEG4CBpZ=>dZfg%(wc=}08=wO9XM*u~IA6L2Fe(JO6p*@sSm}M>bW#0>`_seYQi038 zUkWO5FyOqAfKfqI&bX%{*q=fB=}!m>*AsE+r!3dg{vS*P?^#4KVx*C^mBSNgRG*DPjE}*44tmdkjj8n1m(TPifU8%J za(z>WtMB3hu?}Ix%JZKI{1`^kckJ1RpiKos&lOm}DeM0EAhXYiWfJ}9(L}m369UO<e=L`up zq*fXHV=Ro?k5F1;BHaUS0k6ImP*n*PLpwTkdFD8gT9$$m_CMwMJC1mtmm`f(rdyTv z*Voaw)(M@DW#1B}&K|s?LxmY93F%shbw>&XkM~8aGSWoYDS_4P&SR1NMRD0 z$W&Qaj7GQ5bWZcz?qO~8azZZO=S^UGgs*v5o+D%`LHzaQ-!-pxw|LYW-Xtumt#2@g z83@y9h}e`<29)x42(jv;A10a7>5&6yh>V-@{P89T5-1HI&SfO$!l)rsANl|~2^Ae6 zEs6z+fcMqw5B9vO()B;W+7geI#<7({5wwb{S&>jZGX z;%dL3-^0-4aL#_Q8xnr`_dB2*;S9fb`fxDCO1a{*Agk+a)X2pzMK(UJ4fWu=Wlu=6 z{y08cxg(tX5!}-^DCEJi+^^B4C=Eu6^F;9?3*l;G8Rv0p?7T`*x4YD^JLqHXV^(_E zJ(1Y;DR?EXF$9n^D?&O|e{%=~dPodD^#HZhkL6sFt?Qhh9E6KONmDje_7=aCb_$4q zk$*r?iMD$WK=IH7uUrg4;4r9qhLNCHRe>l)@FG-;d}7sa7(}vAiy8sjLCavvV0DnY z#Cd^`m>>rMh1#Ns{vY^CV`4=GP4>Z6aJ`+rTjZ-j5NW7WWi+1BmwK z%k=kjz1{NB%o2b+fWrczsonJ@x34uw4Ge37WZ)(<=yJ;Y$nbh`1zrX=cjMA`W$fsFl62oJQQT4H%J z!+f6f?QBXuv|Do(tG!=O1D0*;~s{FJXH%y zNw#4@$nfI#fO!Km7*GoO4Y(qRAC=Tq-Ntl1+(!VRG2h+Z(r*TsqvNUN1 zXbez@P;~UsZKO8zn0Hpgu0=DCm$9fRDfK&D+2k?0Q~L|xeZVq7a|U~IJ{^zo94{(R z@RAT}I3{*joD~l7DsX=P0QUTdyxnguV|>`U8f4CMz=x6rL=6kjlTRm2*%$ekUDmh@2}aoK{$T8@*=y3vSoi~FqN z1VRadU0uNFFAXZ}&VT#ytMtIBEADe#HlE>Y8C=HG%x?fcO|Hi|1*Y4n_mEiCK#lc= zZV<;K+g_Dvh&Xy9z+e}hC5va;UI8z3LLNXhA2c&871!0PUlr(z37JvDtXLKt=+)E-33)>hUPNz1WI4r*1wDYP!&E+*AVR@=$_XU~b zF;{ORq5kL_7Cy%7-<@ecv~{@lH=T`U|I0;xqv(@PqgW1Z3*ZWOL{2NyW}1%3Teg4c zFW7B@qg^MEh%`ULOw%Qs8os$6BWSbMo|4?`sJ#ql3OL$HEN`_&+~5Mb6tYOVNnngV z!L=|!;VVGgdy8Lsuh2lFj-<1sG?@~U zFCo*q?(iD-Q3}zGfxuQ!B=G6Ug&v+7y>D{(E+LP>-qFwkV>%>y=FMWhZ{fcI7eM>c z|Aopq$iMs`KXjl6HiY&q<~UUIe+dzJ&*p|Hu;OtR(`lI-eV3Hpa~BAIv){p-R+L%qVgm4{%rop#cI32&Mtbq89TAJuv7Vm`H}Et_%O_3YRp)K~-gV za7$M(IeJY-Sq7=tGh9xD2os1mFhLz9h8&8if(Xa+osC)jEI#$J$k?Dm_Ol^ewh4is zi1b*I-XEBbt1Tw@pysj(dUojyg!W?st{e+-oiUrf;O5#0_PRq8$q!q!zSL4Y`FF0_ z&K*xH8O8RAXhVnlivvB2CQDH) z;(C{SRD=fGnCH-q0KrYhzZ!rkf}3037UT0Qy5D`nY6&}(>6f^aZ~}EGosf6$S{@po zdQEE&Q<}}k$s7;x%CtT5@&R_LQ0wW~s$g;wc=&w&Wb0O{olZ!x6*`yb5rVQu5*eIG zLCM0+^yvOmWA!wyszZ(@IF*%WsKjx6M_i!W!nH&Yg^B^8ea<(rLla<~P_I27ZXo(+ zJEd#Eu#1>ls{GsN`FMka8~0B;1=)U41)pVEb#H^Q^;=^M30mvlZ(O^*R?OMXes0~? zG6c~;f_Niss}|veWa#A=NwimKd=okBr=q6AeTW|j{9PPC4lAipbSNC*rFk`Hqq#(p zb)LwN6#AW_f;i2G=+Ivqkf{fb@v%!@XSSEyv2qizi|3&-2FkU)+-9YaeOHuQ!=@Ub zpUs)}0+v7S60lg}a}HUp`Ve+ATG&Fqg~(g{rZ@)1ZkyCmNMi9bt{S(sX5p1J1J)kD z=i6fXQg35n7Yg`#Y0Y%E8r!s{J5RgeKTOOm^J{WB^diVD=wwYZXs&y>_t<%xt~Ra$ z;Wd;Qx|Ti1R8?NT_A&@x*e43|c|B!rb6Mpz+}rqC=jM3g&^hTnw_B>(o?_(3OXtnu z?Q{jfF7oG}@>6?2jQ#=mdVctV3fWv(0N1aBViVkGP$pDt9BTz(2|FUnpjN3Dy8*qW zDGQlwh&4fLunKpY2?`D~3MF#VLiaBH+3CmoVEk9X$%Q$`(;RS&&pV|8*D)nq{ExXz z8j71Y64sd)wd@+`+d9UcOb{puiSs0$kO!WG(OW?9&HZbTdO%Wrqnhs4tReqG3|y#D%^Z9;avn0SyF$T>kk$ty(kOTv?XMEpVnF0P|i*E*o%JDXOh=U3@eK(memF|z*<~NOP zO1;B8Y?BaT2+NRi7mL{bpU$qu|3%M^MB+GnP6Ocf0`?4AM3ZnM!4PZL1I#EGo82D+ zZC`f{5Z8P($_90PcXLMkE1I!vZv-lq#U|k`?@p& zYpd9p6)e>+$Z>CKc}i|QTgB;kEI%fV8&MDnqZPe?Y3Bnd#`?adO;FN)o1?6(ix;!G zaM^uI->Vg`QtTTKf9A&Mp^oFUB&mF{X`bh9J&~WUc;_4U;Q}HbgITYD#lrzZ2%%Z? z@a9*{?<)Vk{$8?DL{%BLO=;{AW1s0tz0EdJ7~}qRdN8}D^)jd>-?)u%F?J%j-1}L&-2}29sc>Ua|Wf}$Oh4+^1&oJ?^Vj@ zUj8T4finoErE})Iq0jO#S7Tk>*Xhj&W~}OS$;!!M!$;BvY=&^M&aUCol-Vn-E4*Wr zH{%O}Vo+wKAPhJGB#>6>yloH~Kak3o1)Iih)3(R7x9rEa1fb@=MLe0IY(g!(UnW8v=+G#2$y2gco`6P%>fB@?xi zf2?>IO`B-7VTgbef@W9<<6_?~QM3xnB)PGpzajjzXBq``UyA&+e0Tzw7%fO5ESaNz zen3j*RQ?RboArV2xR&0n3SMRIH?zu?LK1?)_1`xhhvd&57qcFqh@J0`yxXX4d|G87 z4XJ5g!&&lG3}J%l@HIuw%wqsiYuu*H1Wo|$lzm@b4qPodYR2|KPHk%v`wqzzH)SJUD9w0I`< z4~m_n5z)la9dW~4!A6A2*QO;TSYfPZpT0E^>0S0b5NtNwJoJUv?jBP()u8|}G!Zex z(->Pd3B^JGAlu*4r<^lvuSvT-Zq!#itKIY-I31j!r@Hm;eYrudvt3H={>8iP_Ksd= zHN-k#U_zem-qRptWAk?vuXLgPE~OB)%Nd1{P|5OAq%Dz^o&m% z2!Hoao&5iL0!=Nb?0JtK`YLfx7@5RGeLDq6FY`zPrm6b?whEzp&hazZp98qJ>s444yt}>6c~MGG$l-op)J1ZG8r*sK&{(I!q`d&WooG$3 z(oso9}5h0~0;W3E7?K|d0DiPs42By3N8a-x~vNqfozvz{X9WGg);wm!lbM#W- zwP1N=aqfocsb3F;oO~eW{wmx;X&;=k=~Fj#_lK1my00^X!pQWzoZ9oT=McRVY2P?o zn6A(#PnYoRX&#K#j{b8Hx*F7!vPj(;aiui~C3M_aoF1AEYU*MED-T%Z{*W+q?SvhE z0`Nc3Mp{$}3A69F2gkrKoaBSu*`UD^%UYjZ~c(BD-N%-pi#>ay(oyX+TayK5_3anr&}uy}unEm?4fq zgkswliMYcXAj;hTVD%pijpr8D(1bhpPap}veDsQsa!sYvZNAj2Yj6$8YIv)Tbw8v2 zx-K;;K%Yz7uAp1t8J8(Y_&O?n!31Yc1sXz3Z00NGnu!hp2#UxwN}(kEC20K{UOFCW zAj*W4t-v|nM6S`nQHsq_27W{Jr3BnPQ<@MBND{T}ByHDE!~t0#mzRC}?JF6gHJxW4 zOe9S;(f{mQJET6{^64w%ALd#;Qv#zEV0_y_ueVL9#7N#X$`XXS`tkGv=4~$uV z#4me&)wu`nad25Bg03oq3w{QIBm2{;&>E`O(EDGSJiz@U*!Dn74A4EZ5$%;aC`Eo8 zg@~tGn@k?7$VvFO^yCcWd1`ws%jr16)lyi;qc<|yaF7`pQZrW03!C>q_PPKa^?83+ z5IlC>xE^HOvu!2Mr4q)+(Y?xq@da~?P*8=9c&|R;&V%cDD7oOmH9q-Y2H-Pyh+#9W zB^2d>3e#lViQEZjHD=calq%~-JM%}$ey*YsrI?Z+yRmZdgBYyvq|Imj>WXXPyP7rx z59iI}oz{vAS`=^zX|KA<_-yPrl#dI@a{hoRt=}zK3%&D~m^Lj84KgLYdsKM^rIpg8 zw-3~5^kE1GDRbQnZF(3%%@k;Go^WM_Sd|o`zpILcie-nyp(X5xJD|~ae1R4;v6XN& z_zzY*St6?kmw(tXvq{jXr-_we8Z|7SGEBb+<-JS@BBMs#9)O?w{e?lVvrI53gs#_T zp)d~b& zA{l|9mvOg|<^tQ(U;?Rta%&`mMjoK%Jv->njFhVc@Gq;yZ2T~oZcElvaynqwB}N>{ zQ6D|8!enm zqo&mvpB(~S?BYbBoFWh#X?tm`_V>TQQd17?h1oo2X7V}UuL6tNHbju*LOE535!7C`_dD;dW-}htFZuR-~jZa3}7ovt$J@!J`9XM=IKUQt1can;%jlCrMs|6PmYb4&`f1x;mae?TZ8 ziLKq=!(~wKdN?1&A%^NDnoaB;9mY4Fg%{4nL-W>`zoZs?zTH1~XZ8yHpKTVd70N-S z?RTI3Ev4*XdpAs^lH`gU3V3U+_>YJN8$VMVKw<%0prq>nZD2mlaE)b(jalx{QlUmo7`TfJn**%(IyQCebQ4W@zIMhj-4#Bn-rtj zy;!~zON=L`M1IuUu>GhW#?DE1Ok^TIOoYBA4hRQE7>agjS~F=`TkX;cj{-nkKN&KV z>ENT~I;x>DQ1!lwxORV>o#4{ahf04Ijlp!@!863lLK)zNFt`@q~pB4*M;Tm+X0A~3C zZra~<(ZB)3fU{O|{aqaHJMAh0=8UoQw6)dG0~kVxsguPJ6yj+ZCe84=`jsJ)F}Iyx zWISE-%YhS)4_10-WkYGz38&dqH>U+=k1R}oPjYYLt@1}9%^{exrj3yaO_lKQUpPY$ zt`2u2I`r4}HaTr$nTyelhUde^2!aKv9)O(% zyn`+?fU;QysO1pW5TsT-c|7-4@|Hbi*NJ%T1nVO$f{3)7j}vlrfyz&Z{Q&CA^>^tH zDl=kd47g&hrdp@ozW>&;oJQGfB$f9l0)vaqx$%zXYK0+64)~{ET5uRPOg5mGd%=>o z22oyjr5QO0X>|v8%eCct>any3!MyQa@s){Fq+6x>qplCX!;*OhK7;{Qtf{B;mJ_}X z?b|>3SoeQg0M&r)z8RzaUY)NR^j==wp%(gU?HW8oXVb0ULFJO`h=!HzS*@T|$NIK5 zNjD|L9ZrDL;HN5l2ZFXQ_jV#gE?(0?pepg&I7%|3IP`R1iG(WdT)>EW?$MAG3mmo$ zqZx$A;D~HpS{0`%MeNe|Z{28t7EKrcG5I-+tDk1#_NX5{Q{8@$?jHALHags?@29oZ z2zaW)31AW}=VNHHcwOj3QN6oR^57XYlHKOPIKTRa^hdaG2d%xVKA&P_;c}t*VQB)S zSu|k+?}I?Mnj*{|EX6!h7gmxv|0$K%RaO>m5VbeFNU}OiXf-lEQaaGdd=w6)@@)HB z&CQnpN1(vs#tMDyYJ=ZQdoy;nYYfnT0T~95fTwrC2<#>-&;@wA?-DyFinmY+_y-a6j#-4 zzqZInsIw*SzfBy@M`=n)PPt5r0d8Zo^~iJ(eIY1T3a9-~j~ctBn0?K2$A_6G+$fyD zCT!QdMA_zq;eQIK;$md;3CK-2Py9jYNN46cT3D8ZY-|NFF!&}0gydR85;J^2;YFgo zL;L?|x(3F~ww_zNeWtc;P5soiZQHgnwcDvNHK(>awQbv&8ei|d-+TVS&PjH%vR77K z=@Vuc5VR8z=7zr;oc3J9E?>Q-cjiO!Yc|~3Kg_e!r_QDM>+*GYD2VeuJWD$LNGB_q zgNBx=W`9r&3R`xNQEsu8e&4?*)W)lLV z;|Yr_M*X74Et^3U#(?-bGi*{A_<)`}`tn+tUw!m3Yncf&c?bvEf+2;it0ENnmnjEFpTpE^9kZ^;i z#V?VzbEhICwNUaBZ*mR06o+e6H=eV~5in9PPh@!!y+ZkA3Ip$BTZ1*~SMTgu>om{9 zyHjJ>V__~D7|wM%WW~eMC%*{P?;^_J=dp7k+7|-UD@xA49c>I^AhJi3kVdaK%}FI1 z_?t51kWY}XFVn})c?lF9i6y$q0?o^F#%p;ZI+mO^0%iH32?uzA@?DH;NY7=`P1&pU zb9=l_z1rm)04$ZYfbURRY97rNpY#b+-JS~%&5tqORry$h5TVGN6r%?UR}x@Va8DMw zRspxp2dd^aBmXl=TPeJm(_?~GoKRQ?*Tv-Wbl*2tjs1WOU7|kxDnbD)9k|+C@5y6D zWV&OxfP@PuhTrD90#5|30pe{0EJA^{t!{LKk)hM%FZg$tnXr+N>7vsg3Jy93>bjt} zgUz&Nw!mv=svKfMU7re{)4w1155RPiTny!dP#>upZIAgaI`tA?l=DN7D+4B9@uDhq z8b~@51j_i4(w>O8-|4AniD7dsWlzJ$`Ufr6FdEJUHUVY@5MOjTgZz{7h*hg^3@z!< z_IfTEN-cZ7S2Fq=Ywhmn$=q}}l@URO-C!p8O_fJsZT56)9pbOiqOa=@B&aXbgQ5mnsuC`5TwfZNp$BT)0lKzfN=l?MS=>JZZ~h)%gTE z+sRt;EA~%h*@;j3qsq+ngehqE0-xnp#aKn(S3j+ow?3zZPqSL8fKKq4c;R$(Ni*w- zb!VM6{<-&!Jz2Wj`(6`k%na~e7>GSpM{!2u6w!jr$K&aD#I%_^xzxJ|@5Ym*I-9VLq@=*+-mjVW{ zH$~B@8;QNof(Ht0ZN+e!sm67?u+JhjuYAk*@tH`$e@-5jPXO%OB^u9{fp_JJZL}uK z=fWKb@Z<#>Gtw8b4TlMTt*JECs2ysd{sI0a)G1UvNWI*)pT;Q|jGd#m{wFHLreuYN z425V2Q7hEhsdTX6(Um}-*GgNI%fGo!n!xEq8+X%cI%C@#S7D!1}V+fIULnppG z?-edQ$JK&z$AH1?4M${F&xP=okLV(TLO>1E&ApvK+9ab1=K8;05?=fU^b11`2R(!85L2~V(qJAu)N4WxLhiK*U2GPk5DlPt>sgSl_&pq;6ks2zt?iYG z?5}xiinJ;EVU0Wurf>)%YfX%m%Lt_2+G?oG^wwy33IsO4JAJ9VE`Wnf(&`IBVxZ;= z^HS>m4dyM!68OFBcfR19dF5g4eQ~^W7BvjJSWUBYUv*g3Fk@pfu^sF~So$@`^*EY# zFpv*0SO1@BZqfE*k)-@ekb4~-*CpG>ea@mh*;y>d#QjF?9rL+kD#lMAQJIzfkS7r#mJqs{04oJYm zl_!rA#L+gj+S=8R4penXm%b1-Dq(GMD!nkq#)-l4%&;V$Jq!y6VR{Q&gJ0%u9=G)I z-#NS;HLTblVEz2H8#?A+_GWF^OO#@=Z2Sl$kr9K+2IM zS3!SzHND9%NIUAtHtprBPr5(G)5hCe_OPY6#H2i_>7SPMY4#cG z6`L%dtbM1v?>n*Z^o!ebpk(3LUu%*w2E4=9V4)z%UFNDn#CsZy-Da1z&Oov6=sQN8 zGoGZ~&s?oVL=#X``f7RO-fz6Zv$s((xh5RY^R_V1Tw#O@-~ywedBAXCBE{HJ!j{?B z-lh8`bXuySy!VOKe4GplyLC0^!^tp`5K^VhxFV2@UI9IWr!w8SdRp6m?-*fq zm(Vx-Tt5s}^*^5eP!@*HV*GI7NSCQ8U^GWBuAeT zo1k9~*z`ZYK#{z_ELvH}O`Sg_gj#@U!q4$e_>P}OQcaYC%-`f2gbBhUw zXUXiqx;p5C(Dy}i_0|7wnz|M|cgG{afU6UjgzG-rJa{Bc@ct@h8(2k8bAuB?;(6ja zjis2M8=bShUuTEGLm@Mj>+_(oCo}Ufe%FV+D#@pKx-?jqW+`1M|oN;004* z&hfFh@)Zu74K5dP-aJm)kL0VgZWRh)2Z=L_Zhee&X7>$ee5s|y8ld>knkY5x3;-l(5F~vJ2%( zou=oYgkF6`8MYpp4+1FVRDe)PXJTY+j|+}XGlJ>N3vfW+U#*^~x|D7D57+3rU#~9M zU*fK>o(JOPmq3M9fY0?mbk4LO*7NNgI`ro0iK?jcrt2F1+wCV@y=^z30AL|di3ii7 zn*5I36_+^+aX`RDAWDNieFTwx{T#Fu%M~t^Jyh_XXUH*DiuD#q=!+!=If6eD|D~KQ-6GoaH)0P=jct){}MO_&u>-e zndtWdC-bAC%xXP}U#_5Jj}~;k)2(m94Mz4Qka_BQl~I#9HeFD?Puj z?eG!6IM4crq4RRB_Qk1Ib2)q9RpkQ-AZ#QWhEZ+GgN2rfEyK7}fvwDf+}VqN%i9l8 z?B=={V1Rc*=PKQ1OGnwJ(IH;Z_!T_k2+v8rcp*`Q`q3d8p(u2PD%MC8x)C%uKo&u_ z!GZ=s4wK`s4Xst@R1)#Ewc=^Uy8UK-wKMnDN*i;Gi?)k2SI=EcoX`Ijb)V(P%d83jkTe|Q68lbj z)MoFj>+1((%%;}!{+WInJUim?@R5RFkj|kF?bQu!`ILI0-7~wGF2Jp#w@NfXCA|fL z<)O+pePnS-inr3po_)-KHKvh-brhPq(lkr|C(>9DB^p72GUIVN*k@#HCN@g9|2RaV`twuMZ`o?ZG+r;F}CZR zw*NjWaIJeuU_SmJJ$yJ`JShuI@kC1jNf(H8l_Rd0r4x!$m1;8}m!xbeR852x#8^r( z(#n8wkZco5*X-Dd6cJIF4vU6Eih%V5%R|fYD1qhIZRxZbw7&Ae^~O;f)*Q3HIzCeJ ztJ6u&q`P{cl_U7t$odA(=gqSGg+e?6k>o_8Q#`j}Y`LDmVTD=83bLi?c8zgCSs9rp z_LIkToN1*MS%1lZS@>a|Z@w`-B9Nl4y(KZvdttFccL6Sc1en3&gkgX*4aybCJMRR(y}i40C~o*scYLdpfkh z&-U4~Xc9xW?dJjU%sQ6U+Ck_W7&#*@XzC>7;o&>`N2106#D z7As&5>SN^MpT)oZt7f#U@X{_V?G}gP^CV{VE(#Ko_}ek8XkL4rGqIqS`LS@G1Ovmd zVqjf)`PQg3RMlv8>AyI;Qb@)*dp&Ga?{hN6S8&wKi_UDQK@A|B8al02=7ZE>ihXPP zv_ZTfD$nWrbFJ!@zxpgYcnVGk()c(5TA{$!Fpn^H$(qc`;xp2f4!cIlNHOP0OIw0I z!dTMg7gA4*N$*V1LBLJwmwe^})Z5LJws*}|-I?R_a`{&li_FJ=?--R&8grW4*Yz{q zQUv;}zWbbt29(dHg69*^%#<{yqbz4sL~uwtGROUOG1+E)#fz0gl#(o>yU`?Nq6sMG zP1(;so9S0qalnI){q`+r8-%k}W_t`1(duHU{RoZA^$D;RN}u_Ue@Amd$+m5$=GlQ-_jbUDr^V0ys2vhe+%hFywk!5hXKsPH5ta40h7$Gx1{wKGVy z1jI#JzzE3_cz2gi)?+1*j0enfBHlilv+!uNHyh7mzXw{7TI8pBvJJK(O&U6Viwt#C zDKnSFF3U17c@z8|Q-jGU*{IzFelA@t8iA2ILkmq|`P4JL-IVaK>+R34i`R^$5iaX4 zM)Rukt)0NH2ZR*wq_@gb&%>el(oFq>(|iL_5SO(yDp^EP@8!~h{DJ>9P;`j7?2R~)n@d98SmX`%f>owdpu8++~aRR6a$BE6lZ5l zD-P|^dT}dYEIiT=5Srr#BA2^=syy$VXTZe&NIQ~kN`kej2$A)Ui@1R#EP$_sRgZ>G z@hyJ$PVch8%<+4!s%dI?vL6-4-0}iu8Mopd2t7hQBWHQ`s(VaBP^o}kqZT(Y>l8rD zb71!!D}Rrm zj^O^$p)NsKo7H0^Ce(5}OT>32tg)pM3ZdpH=1(8g3#AT$3&P^X-|pBc0a;Mp8mTV$ zFKSjxh2RMWhoyVEz+sRP;1ZcR(>7V=3}jv{hymB->O1@l2gJJfLx9bI$nuf7um>T) zP#}?5Y?Q-Fcz{qDKSrlG<+L06l1kFXDXT4BVt1(0Y(JQ4GF(IAG!Zq-oUAZUsc3s2 z?Vv?aIJ#@h)5ROTMvL7Q;X$Ev)3A7|o*yvFeA2|z{`Zw+64Py}7+GI!N0@|e&(3uqQJXo6AzGQ5GYI7fA|)`1L-Kno}%~2fn1Nnfwso`OoX*8 zks*5PV1HtFjJqpp4b(|5{Xb&n(ri{9v$B4lTRtBrCg8v8(01!gD)Ta>h_5eKW?6MI zj&ENM*9IaO=t8KM1t* z`|Ivae0FY6zzP29F93ZCyrco^Ail%AhChUmVeD!e3#|`@F43td7_CT zkzp}JI_wDcEUih}SYMMi!^-_={sF4Fz9qw=mk&stsQji(Gfff1%@&=&o?_OPeU*um^~*0q@O?;{)KV)V)Ik=7;4bLAGKdugD$wE;n$ z7!hd$*CJSuGQ>^qW{gM8ethuCC{p^EQe5Reune&{yU;VVs`Q0g?%1of!)Ckw;(h)$ zzi1AlL-SR>3K}QAkOZ$AUC5K@06elcGT5yH5G3bmz=Vbz0ZaPo22E3LH&vbSUqF0} z8f~-s>?-s;+Oh|tWRPdFPlLHU8FZuPL4C!8*V9*l*43VZD*jeEM9pjWH0xP%vmNQw zK!XVZDhLsNZ<4~aBp&H%B-8Y0fi*wgi|>u+o8;gWUbV&yIXh4!x9b=!M~&K7wur)x zRf|UyVg`ezL**2ZCtT!&p8vj zx%qGYtYDx5nfq)o#LUV9rve1^Tk7(VL@m$rv!H>OaP|z>zjiWEB6xmpH!}NY9Ioz# zc5KX$Elj5lsvN5@K*WLpvd_ru*o|Z;3N;zP}qlii%853NWQhP@uYV)15XqeO z%soKfkWP@|zO9VJ$7KL5fL&WL*x$)`)kC;=`AGn*Ok`E})tl5|D;3u3DZiFJ<$*%j zGP+S1r4w_hFa10nA z#305xYaMfO6sO5`7?dG@^6a}1tger)eLRQhqVV|5f;&9NLxU$dPiSw~leRh=#3>tC z@*;>Kh`?eniW+@nqK)Zmb;^6;?%)d9!boLR$>P|HxXWP1k7eq5jf#4q*vBPDVnd0A zwnfo!_@Ij8z#K+(IyBWo-sZF?lW?v5kwjVd@0aXSRDjpk~^dN56`tR?1bw_QgJb!=0e}-}T6_|vt zXb}*M^{ZA16!qKsJ1wNc*GwmQsn`03-Wo*>|C!$N$ZuZ;y!E>w_c$(WO4ZcD1v$*pzC?E%BFsxp@8{~U@ag#%VJ`CxRs6G%ezi&0g`;n4s5TJ+=;UBcBf}JE3Haf* zVWO~oiAqR;JC_6mJWxH5dDi|8*f_Dc4u6jmD>j#xu7hpck%*4!%!Y+1o+JnX4Z zu0z4)TT00cW|!vzBN?`as}ui=eLe%~zD~|Fq@D^{*v)!DwSn8xfGR~tBD&L5aP6&@ zkxa@fi>1Nc#hK4-H8sEcxqff{ha$sHh2evl)A|(nbeSgDpTB;6tYq;wd;%F60#IVIjZM9YxH{DP_ zPtSVq?^XP9i%6R2hgFzBPA4hEl>SpmLu!W6IAzLW9e+`6>x9$~186Q0jUh#y5N!a_ z^#V2h5}@l@sB|UWxw$&*YJ#W91-KPYJF5T5BxgY{3h2N9JLd#J6?-@fluJR^kKdCY zllgzljU8ln9Ah}?Gk7BW>5rT8@e@|kW!lk*M}~6{ z5VT5Cg(7cn)n-gW9C*EaKNHz#Up?lK0soXc$aB-)=-nOmrw{&Lj(E~p?8a!CG z{xU}foOdv_Q0!U*4th6qT)N$3#w4#3ocA!bIH{Pg1J9L;DW`)@M?Spl*2`eQ1uw3M zUVR=3G`S8F7m=-(d2nUzh1_aGzIJPH)Fj_C7nke4@5%!6f1ysS#vG1~TcOL^~93fB@{(6-)Pt2#nG|~kzg4~ z$n@pa0AIv=55M$a4=qdf#^#j3|F{5o1G5#Mk;AZ?I5+Z<{y~~TQbz1v0ML#LHM__r z>Z}O(Of`&=9>oqBGEF$`hAuGS-Vth>3fmB$or%$srK{)9^G?qWT~p7G_s-nLM?T@h zkod2UDePMx8Vm%UK(e4&ykHr6QE3N8S>t=Ys(-~icSF;QmUIG5qZ%kNgh_3I#y8Po z5MqGVrM6(u+Al|srQfH#pV~z1&iuL;<;ycTv?X&&JQ>_N2^P|8%yu*Hmgp) zE!R77q3%^VzlATJA48y*nr>Y+pPi>;&mC6B!A`iCjGd!zhQey$CCrd;$ zSfL>K7|l;}{l&taXRLmz_ty|({dp1YfLTN?oXM|Hgl6oNs3iMO<+3- ziHyO-jOs|8!6-D*T&w0(@D5dB)vF}ZHNv_Lt{L!W;O1(kv` zBrz?*EfJ*H9IPCQt|SFG`p@B~b={v8E(Weom+tJ5FzLA>13&8ZH)h}NDpIS01Jm=6 z(MH3pv~C+nsEUQG1fXP*+$wtxtW&L4B-bewt1i!;yW4q{eYHnJ-ZIuYx%D!n%ylQ3 zqKiAjJt3LpAlh(zEEXY(WzXA!#V)jWETI{F`c*61`#c2!S1Fr|`q%Te)1Pos;(~k| zwafWPb9u<($(!5@`6&yxnfV1AztWA%R(ynQ|Mulv1xUVT>+#TbcrGVatP$`VZ&+vA zbv$&b+B9XmJ2rhBs!^!!Vn=L>}C& za zBT1vvcD&zs+MKl?ownzkcv%Xt=BiSwT8h%7u>WOKwM(Mft%=JPeH^}g*6Y0eH&Xtt z;@QLSTdMIs#odl}Dx49V12DwP5*~6DCz)kX8jRt*wk^9OhMWzLe(&5a`POUR&u=2! zQ~(mXAk~aOK%H+K&|Yo=09YbR+MFrbpAMQ(42; zh-vK?OU4$DBbA!D$bMZ@fT858$sz(%He0>@Uc8`KHc3t;YiC7IgS#Cd@7w;+b=_xJ zp|^2;y&KxC<2Rh7{ZeKsK9^zOFv4Tq`#rv>N|Py!Dv;DH`Y5~J?Zd)j5omAo_@5a> zd~7}H>E2h%C{86(N((9rgHs6BU4g6=@DVr?TE{J|$Cad?jc#gBVdO&LQ3RR7_GcGo zsPAdGguXu-CnyAYaVw0;rDXx-VBxH0CATEbHL0kRWY|gNR5U-Iv)OklggR&}_g}O( z{<0hs@f^tD0~=~A_`We=uf(V-C?8er@o<^tI?8efjrFqvp8KxOJkI3%;w%7ZH>0;3 z8qWM=$P&CfXw`0u17&vhI~5pmjRj(<`&*qlW#5{Ia72nci)g zT)X)JlW^TPVRix>d_J7uGp*7b_r7nKV;r@jN#F0qhl3dEP0omukw*~UlsZAPjZ}-! ziqPj$#~`yn7ibnfAD7O|V)ZNENNF;nt=K}_mHvzu#yPR1Bc&4P!+WeTY~a-%$U@@;mUZ*QIFG@J>^=;LG0QEKJJzjRepY+qSjd4>f2+V@!J;WQO{ zn^d^Zf6Q+J`HdE)<`u&sB(vVD5b-|?QI!L8eJ=&zr z7H8z!;I|yk_T1Rm=CG2>?&TUEf*b=+j}A}?I{@R}v#EY^in{<)pC^aRVg5|HyyPf$ zSlJeZ_PpqHDdA6F3KqxN6Q^5TdkUnQ_XRL+?(XZPBlgaV))d?o5)5YQzmlkPvSmW( zBM1x$Ht-a#F&9eZx+#dduCgP|VQ1#FpMiZeTMPyVAyUbGV=7dfU%Ec{-ppF@ zqF}*N0qFe%F#(Y6u_kfUq<#{?Og@kH`s~qH2=YmK)w`kQ6m^Hh0}nx#0cED-EiP0o znR^SDxk?RKiYny%*yzKVlly!vnnym&yjTJ}zs z9=vxJs%+Q=564E$K&)T4c;_kf7IPYmvT{!RQ-EMDOn7U96zPR-y^S=J5z11P6~3vhafVa+q$mb{5qTnm#ZWc zY6sfhwT}_;v~RS?v4G9 zr?}3!IyXSR76{xlIG)(CS?kXRzA&~&SepDcvxpyoEuczq17+wy)v&|Hn+SGvWGV0_+ z$Vp~1s!&Zw5MxSnFohUV(`dv%uUvC%o(G>Tw&R^IcNxkoGTK1%3s7Hr3-53sg^014 zV>ws{Vh33;w|G-;u+l^D^mfc$Nwl>#?6q9WX1ikOJx&*$HL-PjP1Ugh=b|Nl9eyL} zT`>GwHHAA^4(Dmh|Jeu;)eB|sNP#mNuQJH&hbUOPDk=Gw(XH51n){F{#$AFx4t>mz z$MxpnWbg9K&-CQr=&IB5LC%#AzoXU$%$fkYo$q3pjs!%;GZx;7T$r_gloq)p`RF){ zdtln;h!cGy)Yh40kQ)3nUcDeWr`ChkYx#3Vjbq3qn_!dIW_Tek7np;X>3@Ia&P!V( z3QLkmQ!N)!rl^9cQ}!&CsZZh%s%BM=BatYS*8I=i5Oy`W+e!zQ(|g3Q zl0^)r#InJM2D7$4nZyy-`z6!_!Bud73KWz%i7J@Tw~D>xCsSf;C0Q%iLfx^fOrnuE zejpcJIC66)>x0B(9zV6#F0Fk~b5g$T*AlBYGkVi%b1-)7UYb+d*->DTlEJ}JMB$CR zn@uv&I?8;k1j>?(F|!WcENUiwQUL8gFyBTG|2;lZz;W0$vZu+8AcY3D#{)-x%tQ8fskvdx$AQDglc87iKJaRhHzTnPUX%ma<|dv zHZ0C;lof~oQEJaGDKlm>81w1^3${1Ch78-Hwa@x6r7o8Ua)s6Uo>kNx-GXuujH;NB z_bGpsKh8~fgnS&p;f1-oI*QD@<+|Fd zbcRVjmuB4lM*_!G{TU!o>Pa(%z@DKOXHY!dnVTki|L#KyT_pQAS1fm;Yow}Q4aOu@96UfMriIbF?$^=k~Ufnul>39(Zz$iztgk|(goZ%RXPmh%*Lh?@bp1uJ04}| zwc`l`=T^H%U*#1ng>fF6DDToq4h$O9l6p<&OXy^O^PBUZT4Y+XN9yP(WeF09g9hJ= zv3rEgX#8>Mw|ln@Ud{?x{WC-niwJAdv$F^xOF#w6lR#+1W!Jdj>yL){b&PTVTMS_i z%@ZTkvezrlZHP6Zcp;&_a{aOU&i!FJx}U=~?6z;K-5c#rxfAcq5&{KbB49R)8blYt zSQ{Np=j)Vi+Z^+&SaiP;qXn>A(x1bV%<%e~WW^c@m-IVaOQwOtn3cPw#NiQyDS2|#(o={W_xD^sOV_Eg$LiIAxrt;Q$XFqx zyYC)V4>G6m+~Wpm4|&g?!b>m}xFsJHDdyLA0J&s)V;im$ND=yivP5z=nBzQQgz(Ii zH{Bz~l`WuLHXlVQ+93^E%=j^W(b@QDYS*1UNLCWD zXdXVGarfs9?a%OVN(}-Yl94vHHz;}F(#d zo;Ti2{vYg`D}&?DcZ$b->hG_N`dwCYpzhsmG3uGjuExl+9Bshed;`rFYp5NBjFCdo zuvE^fz=G=V7-BK8GdGGsi#0XrnNrT>yQmjQeq^SP$oMW425?Jd8f4p3!Sh*diUEyztb61`BgH_?S%=KX;Tmow~}MExKG zx_(|gqmTFZqteCUV@;g(i}oh*bMYQ~ca1wZwY4<7ThX&m`uK={1gOl+24ak-hhMr4 zBNdsXh**z^V@2>kAK#rlei1j;B6dT~ZT35i@@cWCx*@$vUNZB;%!WREkW{MUSINndSf=4z=KkbOG0Y ziqhtmI__i5^>AIc!u+f<6yVV^-CfE!kr5WYO-t=^n~GLYm9^d~=R1tVM+v+N7YPZ^ zD<%w_Y&v7fkq^}4@F(zxD@G9$PjmiNUjRcwV!vsf^w!9eE|pBuQs|e6p7DSYt+XA_ zL+Z>zOxY^3<+oSgjI1k3O4Z-jv9#()qY`X)@4xilE#wXZuy5istjt`MU586=NlhKr zgggTMEl4Ao8@04BeyK0bR2@d6v@}7XvAi7M;0Qbf7I-7!Sfxe(*fcx`ZL#g z-KdtK2)BD4zb~*W6fUedwRW#aQJbT~sW-847V-!rhy_%7fT;1^PAnqs6!Gjsc^s}! zF&nK1?H!)qPIUj|NUgr%C_u2RF zay1J0XmFB?q8e3ZJ1&XnnO%@&khQmb2$?8j^^Z@{a0BL-A}K3qw&dPC zfhoBBGP0T|)YoJaFQMSnIp_X-Kf3C>bR}Mao#^Bu%K8r4>hN z;PGZt^#n*xT~OMx!_bndMA2sSTt<V)qLEl z8o?ke7LS(Fi-;d_Q)!Xa@9p4?Eo+&%LS*?Ik7Hu<-qgHHeL>629qAAP9@esNe@+_0ioYFQ6NZwx!<{wD}fo^gSxB86Hom&`JxG>pF|6CO;|V8d?3L zLp?xFVYy$0mlFyM%%N}1{vL>N+Fu*tq0J43a#l}1}UggfS4Y7*>db24U7c+iTFe05O%V2C8j%e z+3Pg#V)B`bVsVOA9s<>nCTv<7IuY|k6|+9r7++88+74BpyMpy&DIXOuI0?Mu<9?R9 zn0J_|B~oA7d<`_SzvJ(E8pE`Rkj)gZ@vD(w1}nMOO}XQp`yraKVO^$gA0+#fMCxXK zAHrM`W=`M}rT-HM{OY(pfeW0qU0c`P|B1`&TFNT~N6}t+i4syenV-N}ks6Y-QkaAZ zfcyGv6w{6QqD43h*5|vW=uCKSUfo-{vKU# z#V=+JY6T8aBo;IRW=5-|eS`B$ih3hfXcc8`qb;pTRKTRaT+%DQB5eGbil%WYLs5sr zMo6UFf2u@ZxBcL%Mz1bRi#|Igy>w*LB-yj>xhgTzyKIM7Hd*?wq6F(oTi{(>dhdXv z-=DmH)4ab!L^q~hk^I|I?oT!Q(~>&dLia|i&}y{6FFZ@fqy#4MGIPlr4=%4|*xpj= zr{r;j)a|+1aWCTKHKo!5y+legTNr zuMapja8i9krZ#2G__iD&V62j2H#ay)ns)bd@+wadzA+}*z)~dM+^7tJ;RjNJ;qMK> zol65-TW3#E*jm^JZd81pvn?6SrID{=^ap8dG#WuwsOdfo!`JveEn+Utm9l|ku2zsa zsFbrTjkDcYi*d?|)qTrnRh;DYp-`rXl)g%@2W9F9ZC{S_4tX~ z0u2bCJX%Kglma^uF$CoaaFYuLm$RQ8Y;8>H&kP?l^V$HXG`t{x>}q+==KoSfrkV#+ zPTxWwj7**ZQ(+y56yBlY_!YTa)UX8P;?5oLom5zt`Z}NSPGP*X$Sg zHk8F~5A`aC<0G6hits6qn57rc=aOC$CCh|fYJ4dTtaX{ZpM}AQ*iHu4l zs*WuPjZzgR-nG>GQpM3|hroz~fqU9|XJ5G3@-)or{xWxc%$vjIGmEvmTn3x<-s9^-sq{|8jIXPX`&tiwu z8o;mB=A+-5T^XPhs$NA8$Uq$eX_Dw;Y?rp>+EWgo+Rb(@`F%C-=zlnp5+1Hz3;ckY z?%>L@^?Hh=`xruvJ_#XGuKUH^DA(*Bs*aXkNlyrFHS-HrSw6(l`^~x*RX?GyKc(L& zxYPB7j{T9))cW>n%l}DLZ+TU|6RJS6t*X4&jJ)72pp+G?$cme?p5jM;byh4Zz24|$B(GzuzB ztPt&4MD%bX^vM+GjwIZUSN^Ph?g!)7A3HAmAxrOXb@XQ({x`+q>bJ82MP^piBW@!_ z$u-)dqmN|I2var?v85zpL{c6@StsMUzwdHGk0xJJ^N{PG0YPC-22iBN=SjgOkLyLRNgFvuOMzN}9MmV%7kYRo)<`n1zDQ z42g4JpIp)X47MUA*GM$kucTvFyFFjy#&nib%-*n=9j*N{t>iKr$aEK>5Azn>LD^xe zfn0&>|C?v+g}?r7uo3fZ>dtz_29lV{+~#PXy1naevNsFKx_I;84sveJDE@0v%e&jb zHTE7qT2Aw}RrjjLKQ-#jkXRi?sIv^A`sl7d-)uTaf|l7~iV$%EaYR7VRK#SMh%m;9 zL7*CH)l>+0T<8qGIa1ocfPynyR*%^>2g_{A4UVe%#O&U71YTP4JO8H zVhvIfsVRA+M`tser~_JQieeL_{VouMEpbGSO; zxONUC{)yLM(_CSsR8~qINRR@8lVHgPTO(!^pNYfTZ`pHToO7M@@2rID9jIdi{^{L) zNX&Q}dpLCF(oQ7O0uUQQzqT`Qjc{Ow5j3b%<7W6Y%aa1=;>j##VZHHVWO8oOdRKP% z0qrqQVXvEVh2A^z7&RHSKJRKxGzK!M+w?zkEvL!$*;}*{R8)znHGgt%sn^x1Kr^yw z9mc?6_s(+CA}?~TH#|kX$Y#y{rKNL?mMS;+v38|_55a)`S7wZO*)voIotv`%d~fDu zxSI*lE=f6D{9NcD%kN11N?vQmfAixSzVf&}0*g+n04j5$VtmVDUqtH8Gq^SApeuhE z#$|${!?^ooe9d@PyubcX_e34@zk?3Xw6Os-nw*M&FP*}o-rtO;MWQBDX$2Ei%u&_N zx;gm>&c=7GHC^6-`vK3*ln$Ez)UN$@%3aUDAMNoYKJJd9)Nh33`F$yT4}MIHg$Cn- zH^k_qWQ`JY$W?6SLHMpJ?Kh^|sSjBFikpB{gJ3Tf%{Dd(=&s!AVb%p0mlgd6HDXR2 z5{lTv8q>YvRIavVz7-WA#sY7j5H_1^l}sKp#Tp0T-2y*e0gU>;z531l|MqD$S%GMd zaQwF9_D&Sl*PueH$TCQ2eXf>QtVNkFa~SQ|Sav^MhVNqqyvFLQ{u{Q}63vloeO#+! z9QQv6yJTPV<Di>7xQ42{iKj4GMg-diRtLZuTFO-!QOQzk znLK1GGNs*fkRq>;a8RfI zBdW#hQsHp;#+&~8E}b87%lX*--D>wAv=J_zVzPlb8KHk@4ScRwmc6>IWM%rhS*n~! zlN=Lmpjw|h|2+G{2#uxiiE7!JZ+!WzUNQTOJB~1nyx7{04L)d!x87~cQ#yC8ryiLM zi^(%NXz#aE+hw`qFQxPm>7avXYA2=rH7pIWiBeN84J+f9lWmff(SyJCENy$L zmGewSWs*YiuN6*vO^3fYqp*8O)TY(IvAN)RuN_KV-&>LW$jmQWSSkH4o?n(ey*>qu zKJNSpymS60HomuN&&xo5=1c-<4r6IGw%Kv-U5cIx){1Fz&5I&o>NjyRs6UrK@SN`VX17V5 z)?;~%%wHoHN$trOYxsW~^@B?5Z}!#y9^~vQZ5THj4V*>4(mEMY;=l-GSs<<%DVMIL z!PY!+#P~h`1J)*FHAI8EWuRl=i01<_XfxTsuuMA9%u8}LId9gix}Mnr4F9!&^{6-f zhki_G1@|OeEl5iB!yt1Q2LzGxi&!;b6d;F>$y@PDgHf^OsyKp(B<%~QB(f3W2}*a1Z@twu_S zR8|7DRwDS2he`;XM0L-+SbrsHyye^{0C{N)wx5*MnrX)CoKEXzi9q*bbv}I2Zf`-P zEDAEyOLlT#x09sYdn+smTF-j?vAatk<+$x2a6EDbet zH05d$ewaYezOJf8s2;W|)uEJ|_VleYZ)9~DJWz;5bMXVMFXP@Kcm8$VA^VtP=p9Ux ziBb6xX?J22#Rk--I0?lxmJT{ zt|RoR|GSi)wvsAEcPLFa{`e;!*$dn7e@l*3dv!P-72q>BGt?t-Y5PrP|H&c5E#nTs za%OuRLY>R@^&7EwZVg*|^*{G>mII@-CJy!Aou0ieSH26x56njw{PZ%ak5?LgS0m>_ zca1Zxw&6;alA81Jv_P~1v65Me;NR2Z+w6=$9#K;{C0h)lpw1qi{gYrTG34TMyJoO@ zDNoMEr^wItcJqJ4eN$s)TNCY$ZQD*dwr$&X(y=-=I<{@QW7{@6wym4m73I>5w5un%%&W$cKvlvt{&5L$fpQwQ+FpgOkJslKAdtS#*E+8kgPol>p}x20 zzwp=RND;|K^n9%-*yYj|)wo{EiQu%zd!#*RWyh-OL*zwedK_M{b85ExGGCPfNCj1E zNpqp{p-8pkv>?tMp=EM9`>=o1WMTQ3YoJt2`@S%oKE&`mtsTN-`?!Dz&h$t{t;8ch zP=_g>BUk2&q*ALp$o153TZ&B>1!r0JNxoh5El?$V@p)Y#<=j*R{O64XWM|^L?anaU z2jA?zv@O-Jg^DEF#koq}f#almWzOwrTC|R9QcD1+1a5%?fBoC~jPBEyPeqQMa}Ixp z*}5v*mv#o&p<0m25sN+epACyFBn;#S^ zV?;!4$?BLs_>+^~2R`;(D5+&OT66Hqq=l~GQ9_(0MCB5;KGYPZPj5|<@!OLxKLpfP z5-8r+eNX+7g;pRqoE8+Rl|*8ta4o4)T`?&2sAQsqB3EQqd>$E@x-8B4?BY%bm?vT+ z?v44bXY{ob81Fw9`RnJ8{D*P-?5>G}!_}M|#7bXC8S(N04e0v9m-A+}097m#TDf5z z7l1z3G-B>*;8Oc;E&^dz))za}v%}u~F7v!Sr0ALZFKvvj`n;=&jGXO(wvjmo%NOcN zpqWO=T*~&tp{iS_G6OJ6M-Ffjmr|&`q8OMn1bfMkZY=r?$wHJS@C2K|1z4sRj?|WA zW3B+}2}ty@y4_kjyI_6Dr=isT+`aj6J$K9Ps7{at9NmEh3r*o5#3Rs(FhhxO<;vDy z2hq5!Ifw>TPW14z!a8= z3iA_@J?$2%T|MHU(9;A@MjH)NldMHXGJ-pnP5dL9(KGAh)}D2v%#YILc}4d5t<&{C z!i$S|J>`4QBimPaXjf!i0byxDdIC*}(~M#XH1Xo2jww)OI+}i|oivdl0!N+Xh)}8C^+nKnI*!79>ei+}i3_m!}-s-x` z)_)+5W3^C_hdZMd9i=BH>_b!>zpa+B(ok2XLozEIH`@%BWRqq{_RH45+FTvX>2~S% z;S$rq?y~Du{rvIY2a^@Nd$n&C@tW)Ccn0>kVJkE~3P3EYFyI6o$0OY{<3C7vQ5jd{ zF<}G^lWfR94SUT)FPM)Jr?~K}adz^ycYJ=>{RP{fk(6vwv{CfqVS#>*f;lnLiKqTC`w&V<6}`a zXIOq5lA)#r6IHC7p7+1dBXx&*+gY$UZ*ujbTE?RHKcn~h&qCi^oHvtp-~K#0XxZ6q zpU`);1o%_>=SHIm7YdocDViC?FaamMmH&+hICw7qW@?R%g&HX&46(xw)bcUvxIcHD zb5*}JM6MmAUr)61ZIAs69C#2P>>+mFvZz988{X6vzQGGa34_7PsmocCTo)el2PRqP zZ}~8@H?9X%`|-uS6GFniMhIH32UV?ndV9#`+)_$38r zce|c3ZCl%e|0`U(pVwM!BI;3tc@$L<)fdIP!E&)kFA!;&W+~kI zO$trsV{#S{TOKN-78Uh7IK`&fNydZ2Twr#sd&qFum=6ZK(PoKeItx{aIeiGY56#L~ zw$NlUI$`3xJH797@3z0bau)C(>f$U_rneei(7=ksg2Jg-op|-+b2HE#91zqUN~s-I z%x#3CA)13^joZ*DC&NU|sPs3BaQu9PHM`=v8IQ#M+PpsRPkG^9{_j)dnCN2QN8gfp z{O#T*&&U?#;!+YFTa%)+l#1U#bzk;Xg^!rBYw#L?e_6pB1tzXH@vy-PS-uE;q_e=aPmX(Y<5tR-|l%|q)D!GITIs>>sbgZ%6=)UzwD{J z$1pGIK_|a6FeQNZphl&YY=@L?Xh&UD0|{qx+_#wG_Ik9=O$ouscFy9b`S*ljxmjwU zzO*_O8AIRA*|u1U6a?5uauW5+IdSor={lV}B`CQX8ce z;1tzf$D=M(3p}Oj<7r`Nhfw!^rZ3eREM=cFdmq&Vc+tG?gzGik{x3!tKj%NK+3V@H zC}n@15Sh(0Tc**I2o8E3SAv#;3C9z~?^M*m|CG&2f1J2E8%J`PJGI!v@AspF9YT{J!W zS1I4*|1#jf{^qlO5bhnRw}rsFz^E9KIsI}O4~a4k#=>}0|}Fz!dn|2TQTMxG@tWOd`_kl{{>~=>u<;J(%(Dge+buCxblW)L`tQdBO(#iYDD1@ zc4abB`Am#7fa`*h_Lc_c&1D(KNdz>d{Z-8X?70S0%`@z|wN3Y_3ik0j#?zCuxt}au zi`Y6u$Z}Y(r?aBGE_H}>xZo{48k5nyP&Lw)eNmBU#>FS!u+X72XGZsE%v}{knzZT$ zNs84%gLoAi6*+;)?(SJx_8i9*aK8Js%3^O4z|ix&Xn)%LubIAkBOd(u1#g~;jxieI zl4JA|nEH$+f(%{q?R%Glw#9Ov7AGU|Qssedy5Xx%;lj0!h85TLl72=~H7V2@!3MCA zD_G4!r?n@N!c>iNTg$@(2-Y?m!AzvfB-livL-ar;V5F4@3VYQL70WsMZZNo)1W#FRWP%UzF3z z8b+8VeX080*J*4)nk;9$63#VTe%rgWwz!v$voyQbf^TcvN6xrZICMJ@un206_B)=C zijz9>gi10Z6WQ>$mRR*1lOfG??HCtmfzE2Z(ge;#4#g}XUYu~5d)hB{&#BbWecj@% zvFDqV(4$Vzy6%d9E&Y0Arj3_Jfw+sbLZ4GkPbacbPe{fO8w|#XnJclVtwPGmY+9v~ zr+J|hN7*NNngjQ5bP_Fq)zi7!%JRS=?M@FYzVfgLXhBTqNyFqEG?f92Tt*tzr_%n< zf<|?pSrhC`+$|K&?6ON=1`cA|%aHvOVJ@@eF-x+X^>H+vGH|~(V`id_E_+$iPuAJu zD3MO>nI$%ry@2a-px=lk9n3iCnb1CxhGNq~0#3w*R3{NE>U9Au(^7XplY)j`c9xG# zaP@PBWhSC&@o1(ZQCb-Du31A1mdyCZ`vcQK1Uv_9z8L=+-EJM8$e$3qlEIXT)5W`k zB7MO|;6f7CGV_P7#=_;~Jl11Z+TlBZXi&exZL)U6g1%dZ^@|tPALUx~I$%(X8NaC? z$M{eMZUHy#gvPEw^X_81KaF3|kgOq(g_XNqRY=sv{g%SNzRLAK*n^oPXXv1^1cZ&S z!{^FEs31MH`+Ffn*KNP0+cNY?wmPDhmSjabc~>j|(gA3Q%EGd-qUMFe^Jc>%@$r?J z27}b_y;9+-*}4bCwZod6wMi&tJX%CF9|!w1`Dzom6XU7iU~M?BgF ze&Rc?lQ;U}G_S@)X^~0_RiX-1$NpVsxB8^bmR=5?GlYM2b0~t(it;l@#Aal|sC#Jifvz zsH|CZyds&OF6tqPWuelzF1wRe{K9?zfl9KVaXjUePs#Mrz3bm?a zMavmP%uO6|e?^vGt2|v`N_3_{8M=}tw`StwRm22?@+U7A742A7x^E%5bA^HGJi=Iw zasb(iOk90>3VjRkJyZeP%SU52LOk?SIl75*N8Tmnt^gKY>4?ep#Si1TIb#&7Tdmg|1&VB`?V5QE{j^PqPa^ujpqi)Tn1oV2K%@nBQqOrq{h{WuTKo5p5*3vC z<)8eCnuy;lk33dHs^!FUIu#OmX&N?F8ME!@!p8Rlo*Bs*p2(N5U*tM}Ya9{&yD*co zT)`eKH9M%xjR*8RcEud|LT989HsfHECf zC+_xr?|&&@6+1NQ?0CmhuIWfhu&RU3C?-%K8LGeWNFu#tZBwVvgI?QUgg#XH%2)j=`O`QZLHYIzC82 zlxc)$e2X{@u5x6q#FN!S1piu$FxFB`5J3*8o5$q7Q}{b{OfWPiA6a{U9uw*V+3;VZ zpdV=#Za09`5S|XcLh_zS*8!t`*C$NCsvtHuI~i%6EEjrqw%3$L+-Xgz8fw!qSE8V==N7MK>Q-L9QL6(?nNm@3y=l|A5UrO+>?BwvawRCy zC~BoyK1)H^_fpTPho%>Tg0m&4?2&EB7ULWo1G z@yWaGFTP3t_dXI5Gf-q_LcywQRm&52H!%V$q*J|k28z2eBDsrg_3kCBlPmTrVy*NO zU4j&@-m=pXTT$~oc-d-H^;TqxHX_eR<4Ahg+xP=*Nw(jJM0Lq(xG18sv~=gkx+g0x z_)J!>^jc%YD76!iG~14fEgSm&|5?|2UP9Gbe}PTkJpf%I3*mZZS@uIsDp4bzqYwLcWSZP^q%fmyg3nsx2JW)PkG}D{ACNhZ z>goUYa0+KccQY|v*~WA%?VBGfIRh5ujh1T!(s?Cpkc{h<^0CUT#68XR7q7F+Rk*?o z!snwTUOY;h1sr(Qr)qvP8K&E*D*mbWU5~PrfI<(1RLhSIa~ShKeQr-2ASXqS&kc!A zm0)m?Z!4ahRZFNa9*+scrZMm2*Ez2t{|^m#z!RznLOtikk2%Z=%NWJ2Gbfu}?2I2A zHM*fs)}e0zMyQd*tP08n>7~^(TYKy#3SMbldeLiG9fd8eI)N=ITm`O7@dxEv)JjC! z!B6Fs9|z@XY<$C7$kr0b8OdOQ;JqUbsafU<8D0G0OWg#2TB_2ng$fdEJ+laY+^K&j z8~?_rFKZTzkcN2j0&5qu48MdRe`b#hFq1p0<4wTFIw3y52r0+gEtg{@6sk&j@Ty+Hbs*Okn@07Cvw^)7w1<779qRdtx z2mDW&^o>l7WXY__cJCRSh5sD-+8r+!reCwsVgSgP%s^gw&mCCKcrTrc_iWY{C(n&$ z?p%8Dhi!lurKD8PEoXqym`4Dx0d&6V6t0c54gJK;6lQLK!D^yT8QlVHQ<|?7NGzZz zBptqSEBFFCI2t;vs**zO`>81qCPtWpV2)i($w{PgE0vIbLumEBZXzS@Nd=*<{jdD_D?(4yJEf>OY<0(BWEA z1NM-16h-UBV;05)*(@xz)E^ANexn+$$c8*)7QsJrGf0talu{?r6i@`PDP}=mQJb+1 zJ9{e7mr4&zaqe^$Ovr$6&iVwFJ$9vh!M~C5|NrypPGon;kH2+)3~N-3n0k_{JY&Lg zEU~au>xW3f1aKue){5+aHnVjf%9DRq{$ot2^St7wzzwDv7$IomY8u|FKvGAzpup-U z*su+xfm6T+?w`99+LRJ<^y+l>eQ>*s?~0zn?0f6US-%}&6+74`mr#G@pYVEDMNfJo z@lK|GQWm38kg5qL^$3tKI4@d9o|ZC}SM-it!uMI@Zwb+92v72aN?wxx+{DXf^{wO2 zvSVm%+r0skuUdI7L8!JxCei4@7F7^XoV&9)7X5Pnzg&Q-_|ieGL26Qg0HXyZ<#B=h z3GB^YO9;6%xPOK>|9PO6YBv4sbh&fgY_XMeKv z{iSbSda<#z{x_+MJUxrX8Wc?uDw#T;YE%fVGC$TkhcKNGyP$4PUpXv4gunFLp8pBs zwlNx;x6i90qZG}R7g=BLr?x!pWPevR!mG##iE7ami-hT@(N$scOHKBvDKt)gM28iY zhe1jN5ZXk*p8e_V_lCCCie%Crx>z)nTQSxdhH96?7jz#tMo?x}52CpAZQ`G-L8)9) zp=Awc#5Nv8l#UtzEtMLJ0h>90$C?ad2@BBpJqyZONU9y5{?DK4hpAfcM*!_hskI^L zHDZW`URxEnLXn^Yz7z*3&C^gcf`wzO6nXB*#NF!X@0|LAr!N=vf*;JsM6-eXRW8=l;<<;SEEOM55Ji&5?Ip->$3L)KjhX z+Hy#AZjXc;uTk95>3Mvo@j3$U#6@a=Y{OSsmqm~jd~{0N;RnrccNfL!N4v#yS!V}8 zV_)Hbgu?{On+|Tnxw#nVpb1(97iiXrxG`w4Cl8Y&&kbBoaI`@%oVx|Q zON8$q_%$5aSnskR(7RWfoNeiAEQJi_r0Hs7C4PlfL2GTu#3zIP{>{jZlyB;yAnh1j zSXA;ZQVMM(t0=}&xRoP7S9*}Pm0I$Pc&MW>ty64adfj+=_9&R0_my@?4?X+W2yr*< zC*P%*vT}t+hJgf=!&ojkFAlMihjAd+QS!YPwNfHRoz;in!!;(~%y&#B=RFtcz$&EK zR0?p`rw$z+2xKBFK1V&8LCqWXl3 z`u(7mTw}Ly_=sqBIpv4G+W<+8&B0=_QQ*A+Su;m=>DtDvj$vD?S?aA3mEFMmAL2l{ zaxVV)^Fryz^V7_Y`y)o}s)OAsS$xm>l+A42_T??*;VsOq#(lDY9i#X-`Jj^TUR}!Q z_Cr+#0wplaMEj_BRnaA6E1(8_rSHsfdRFLzjiMy^t@PUqs_9FCNV%*h5@ zl4KhSMA?);87x7%?@N9YNmmMNiwIjMD66uX4pRV`#S3{|F0v94!AXX6#^(lhVH3FS zAD^1zrR&nyQ9C{)O7=yLKh}P0G9HBrwYk{5x%ov>6k3_SBFu7!uVt*B##OfRi66LQ zFvKXPq$K)f5r-1_kTamR#FJ4B*E}{1BX$!v zz0h_#zh;}WyX>}JuW33~Y>*^>A(8^2DSHu`uF6w~GMj&LKqo6}%?T+^Y#~`VTv8(_ z(2X=5QZV!TmV>hOS_tJ|pZo2;94*}ql+(>WZhQAtL0r(d1;Y?@v+!7d75S9C>q4Rz z$A11c6`g12$zNpW9kisnQW6yiP+^j!2 zlBJC`@sUbkDmjhN-TEk-B;S@UvaMUjy98sy2zGLwOn?ZtEiMmNvUyFHWKHTIq2n$k z!$4(011Kd86OxXc7L6nt^8ueTfJ)c1k637R$#%{rMtt)H7#E~YYGilk;xSYaqE({j zV|@d6&QDr_so}?IzFZWao+)xO;y$BltzN!{w>*beRdtv5taF^UGm62Hh4Q6RzV4&i(XgbhRB2q=r zQ(bIJmWL$Isn1V`sm`a&w=D_gfVf2WYW`_#G1IN~gUqI7Jx@A=kAS=drblk0_rj~= zoQkgnWd0v|)q4CpK*{M%I|OQ#Yp+K!-JN)N_DP`*J!9Ry=j_TXr#S}20Fr|p^$|TV z9Oh*M3z!KW>ZPq2bdUAsLJ2$Ue(VZq?6d8y2)E_Smg~NGc;9cCy{~Dah=xVD1aBq$SOt{suT&C}BDm#!27LPWFsA2ERMz3|~3(OygT8?fEios-U2#z$=VgDw037O&7 z13zbE430-S6mC#Vq%CL&GyM;vC(#1Bx5YZt{Gw^lF6)1W4d<6E^O&>c~K3 zPG6{S=1HuQb{EI&QgHDLD4_-fp!d5moiBZfqrWn)2*^MkFvk`k=v4r0_>a!xRAnD| z{^CodAa2W$bWZ_bT2|}bth?>acL;g!T96RT0L(BfT2iIz2-X0R z`&%H5&$n+U?>5Eldjvvn*AHrMg&G)gFu}&|iI9tmqOTe%GY<8+`a6&C7TM`B|n+c0os45NryrlG5jh=@qY$>S4>=4|L~4Ylr;G`p%S=r%!#l?ywh7}xvaJaXL2%#pi8lEyqHfa;_sUZ*dr{AgMq zT2kTeCkIdIM+WH|GljR4f4@b3^!V#B#5JBb#>u{Cy#p374_~RjsFKO?sRZEXBLtvR zkQy-+_Mi)R_!4f8^CAbO>S)UPcOt)RKzg=wLQF1f_*~^kKdx1+UM+Rm$sJH-F5ECY z8cTpvpZS@d3DW3&q2_pPmE7Y#lq_P#uxv5ZCWL(eYn*CU@_^FgjyE2uAXbgaXcshD(tzFDMwm=^g z8-}EblNiynG?-g3yzQ6^s9b}==<+OA7Dico@l=sEdacZvc3f;#w(24{f6zIyYyBW~ zAij37hqVnwAO=dU>d6=PGYtJwc36wbso<;Z(rA(6{m#Ubf9*W*Yj+i2jK|b$1q(3( zr>!*a1o;smJ-)|JXVN-T70U22Ec%ss$)|K`M*3YsPP@ZLzW7GY`I31@juPn-7&ZWr z*2472W7zf;?TLGd^LE%Iw*8#Tfve8+th_Mtg(ht$$Bm?bm?s5V`ipAN>T|hc#^Elo z$^12aSY`RP)xN$~S5W}LTSV=QE6l9znJffK1f+=Sy1yRImI^mw0cpg|(u@7Z33u-M zr8t3ElGsUjbwi$GcwIbMe?a6GJo4}hJ{ArBnb=lu@45}8xjm0=VK%jh_-i9eJbP-z z)n#R?ebX+Wz2=Q$S~1}SyJ@?rr^^f$pX8`!H)yL-Sp~!|mGd6v$+J}FDk!*;;J_cv zGayd|H-j;OEB@9I*0AMuMT}| z4-}Zs@f=lB1dF&QWMo7n4RpU!04lTqDIsaU2>5{`RB0l3$?EHa2yrGXT!%g~UG`nK zAqXaWanRTxjt2mZU-7JDc#Zt%r=P~aLbYw13RoLe+`ts_i9WG z69&fTR1Afd=&RaoU_!KCvN3eyQG^MLF5m*bux|TaJw1+{pZ-;bDQtK~Zwl#L?3IAaZDSBr%DQ z(md3e7AaVn_eEVk1s68>cXMvRH|O3amz@(37@4wa86UAx+x-u^0q7Gi?M7%{YThDQ z?bATXZFV;zDm2@lTlrO#=)~M<@<@@iJz>D9&;Ut9(6FEe#SuA;U)yBa;(VVEE*E-* z&_(p?Awf62T9b>CbTom!KVH(x#3VGnkcfJO0t!K)pd^5hk+mRYY<}znpon)z4eh$Y zS7&%@Y84HNo_lTtZPBkT|74WvNxJI=^8CH<9Y|J$q{6@hEW!wbS>Fk#duI8TlR4R8 zt+OsLX*ukJ?*{`1=LGPPU?J-^CB4XTPWCfv!eyUq2^Sw1>?0u{1IhfbG+I$((LD9Z z5?p?SlRjME7K1jhBIKd3TwI|GaM9Bu8>|Aa-C!#WMS_4B)Inf#wuDUJql|J+di1$* z3{elp_u^k%tVT~tX_dY-6O#R+n~Gyi%!9m@z?PbjMHz+m0MYQ*o50HAvZJ?(5Wutc zU%qUUIek`tPi=G9X3}W;^~O8ioTD`ZOB4h~6CR#<-6c2Chy0|P65@B?jj}^lpCZry zazXY7iz3P5(FMH;IT?IJSL|wA7TpA*l8{USIfxL_9Kk>YR2F%jA_^!Zszq4W>HIB_ z#yp3uFN}AH5KK-iG&kIdkjs`N-C23#&SrGy#@b0@wo+5*H?WbSUosdbR`19NU$;;Y zzQ<_s&Su~VZ@8czYwlZJkiP@~DfpYoP8leh&P>F5WSPCMg-?j97HMa=EcS=@AVM60 zfw-~VaeG=D(?qDSP{0q>j~0;BB!HGv%2O=I%>YPVH-{?$fq5L&M?kJu zm0|U+yyh38%lR^|pT}t?E!&#D(GW)OGuAA+FcSnQf{x(tG<^Z=G(QA*#5cR-0mU6{1#X%W}kGXhS2& z0zolPpgw$DIR;zkd!Aa+w7?%hMdoyTjmoj^?J*|WkWb9Al&PGeE~Y;D+j7*7{(i9IRC1|*8C#4Vk1l8Xe$YbI&iO9|1TYO* zFCOA~pzww`g%I$71F31ic-lByiOKXDrO}yc{_ZEQogwVO9x2!X;{tKfGR0*=_FmmV z0HCR<3}OrH(O65BO`<8N5HQcj%$uhReO9IA$-IvdHp!pnnb}D$3)vuUd zMj%V~Jd?B7trHT>X*vnQxC%v9B#;Krpyz*WBZjVGG~ zx5B3|AmFtNop;mP+nS%=&dCBZ237NzRMnhBu;owwqJ27?T+yTwu}}3Xc!7w+0oYl&tOmHGe&ggZKhL(GReh=0@r4-xv7-A-5^zs5(jT*6_eQj@{ zLS)4i{t%*Nv;UWZ&ubh}zc7GJ=X*%%8Pv(0zPDyxuTg&@M3 zK2AdEuZsMgJ23#NXB3xn1bZZf3t-iD`fpwMqBl<}ad_p|O7tTvQhgAxg+{n}jl4p{ zr}y&s-IBuJf^rqom)2*MrbLB=jR zDWTUk&K=otE7QnsntjfdJ{X9+9!0KJa6O!}uJyAfWpKlM8Xjw~Q)+0El`o;uUm{6{K?9IT5Sy!;I5j&*!# zA0S920k0F~Q9YR;;brKi!=Y7Kl$-}9Dq+$atwIJ&mF7PRqM>4a&j@qE?? zz5=(Cyq$cMfOP{FM1#Z%)!Z^aX>$C?yJ#K@3?pV3hO59?a4PDVdZVw|^4gy^#gJ7Q zKu!#p35t{xsekgaeCmoo7IilTCMZQjV`%{)bJ@N#CI%r4&7-3Lqxe*|MxYXWw-u1n zF-d+b9qOk;B9jCabiv$)C!^;*QohOTM6Q1n@4>xm!DCR{l;JRXEUU1bv4HD5=eS^t z=fUTJz+X$X(G{y^xZ@@eJsFwtaV0-nHo9TaRd2|w^sTuGKRXYBUi9GVK@8%&Df78_ zkhlZNO>PqpssdvCxH z@peyVMaKFuX<2`J67N=QBm&3=QyL^Mw zPL}(v6e%>z+hPwiw!?OHDw`Q!XA%A~Qcy?;8mAZvym1)>gB-kd;E5z?$kZGc2G;WP ztryMFPMugK2oZ6A&0ApYv4Q>y$RDC-u0+^OKFk{%oV~vngyE6Mbh|Lw(Xf6O9g%hb zYMjsl(cq#zit{bPAA3Esl2^=AL&?2+Y=dUHjM;KAWG`2{3U=_zCQ-U(`snV!c!MLZ z$o}~wvGe9Dpw3kE>=q>hTfPmn$0ywcW2E?s89XeYB7+%r@+R?HC5O@#L}3mYpBySd zPRm(m`7uYy5~k`0UwU5JDu1jEsw` zjG1IIvXTBJX<5PqLI4kBEjY49XZg?#d6yj&ws;R{yB%00Sp3MX&bh_+djjwjTzVQW zU1i$Oh%QpTF1K%QM8M&piOdPuquH<+ky}7!@-&7~?ZJQKr8|tB_mbWAS5~9`Hqiiz zYZn(8G9zM-(f)J!a9JRj5z^a#!Lz>&9qyo1eb?7&rx1&jGL!%dTK6XcmhVrt5 z%123dJ0p1^6hcFdLr#bboW@yNJ_7+rOVaVH!w$uN&~OLE_Xte6S2r5>HℑgtP!M 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 literal 0 HcmV?d00001 diff --git a/backend/SchotzIadKmTracker.Api/Controllers/ExportsPdfController.cs b/backend/SchotzIadKmTracker.Api/Controllers/ExportsPdfController.cs index 63aa19e..e1e3adb 100644 --- a/backend/SchotzIadKmTracker.Api/Controllers/ExportsPdfController.cs +++ b/backend/SchotzIadKmTracker.Api/Controllers/ExportsPdfController.cs @@ -9,7 +9,8 @@ namespace SchotzIadKmTracker.Api.Controllers; /// Endpoints d'Export_PDF : rapport mensuel et synthèse annuelle (Exigences 7.3, 7.4, 7.5). /// Chaque réponse renvoie un unique fichier application/pdf avec l'en-tête /// Content-Disposition: attachment et le nom de fichier suggéré par le service -/// (trajets_MM_AAAA.pdf pour le mensuel, trajets_AAAA.pdf pour l'annuel). +/// (AAAAMM_Trajets_MATRICULE_PLAQUE.pdf pour le mensuel, AAAA_Trajets_MATRICULE_PLAQUE.pdf +/// pour l'annuel — les segments Matricule/Plaque sont omis s'ils sont vides). /// /// Le filtre par véhicule est optionnel : si vehiculeId est omis, le Véhicule_Courant /// est utilisé par défaut. @@ -46,7 +47,7 @@ public class ExportsPdfController : ControllerBase /// Génère et télécharge le rapport PDF mensuel d'un (année, mois) pour le véhicule indiqué /// (Véhicule_Courant si est omis). Retourne les octets du PDF /// avec Content-Type: application/pdf et Content-Disposition: attachment; - /// filename="trajets_MM_AAAA.pdf" (Exigences 7.3, 7.4). + /// filename="AAAAMM_Trajets_MATRICULE_PLAQUE.pdf" (Exigences 7.3, 7.4). /// [HttpGet("mensuel/{annee:int}/{mois:int}")] [Produces(MediaTypeNames.Application.Pdf)] @@ -76,7 +77,7 @@ public class ExportsPdfController : ControllerBase /// Génère et télécharge la synthèse PDF annuelle d'une année pour le véhicule indiqué /// (Véhicule_Courant si est omis). Retourne les octets du PDF /// avec Content-Type: application/pdf et Content-Disposition: attachment; - /// filename="trajets_AAAA.pdf" (Exigences 7.3, 7.4). + /// filename="AAAA_Trajets_MATRICULE_PLAQUE.pdf" (Exigences 7.3, 7.4). /// [HttpGet("annuel/{annee:int}")] [Produces(MediaTypeNames.Application.Pdf)] diff --git a/backend/SchotzIadKmTracker.Api/Program.cs b/backend/SchotzIadKmTracker.Api/Program.cs index ace870c..a4afe6f 100644 --- a/backend/SchotzIadKmTracker.Api/Program.cs +++ b/backend/SchotzIadKmTracker.Api/Program.cs @@ -214,7 +214,12 @@ builder.Services.AddCors(options => { policy.WithOrigins(allowedOrigins) .AllowAnyHeader() - .AllowAnyMethod(); + .AllowAnyMethod() + // Expose Content-Disposition en lecture côté client (JS) : sans cet appel, les + // en-têtes de RÉPONSE ne sont pas lisibles en cross-origin même avec + // AllowAnyHeader() (qui ne couvre que les en-têtes de REQUÊTE). Nécessaire pour + // que le Frontend récupère le nom de fichier suggéré des Export_PDF. + .WithExposedHeaders("Content-Disposition"); }); }); diff --git a/backend/SchotzIadKmTracker.Api/SchotzIadKmTracker.Api.csproj b/backend/SchotzIadKmTracker.Api/SchotzIadKmTracker.Api.csproj index 1f91e6c..0ebf34c 100644 --- a/backend/SchotzIadKmTracker.Api/SchotzIadKmTracker.Api.csproj +++ b/backend/SchotzIadKmTracker.Api/SchotzIadKmTracker.Api.csproj @@ -22,4 +22,9 @@ + + + + + diff --git a/backend/SchotzIadKmTracker.Api/Services/PdfService.cs b/backend/SchotzIadKmTracker.Api/Services/PdfService.cs index 36371bb..7185838 100644 --- a/backend/SchotzIadKmTracker.Api/Services/PdfService.cs +++ b/backend/SchotzIadKmTracker.Api/Services/PdfService.cs @@ -29,8 +29,12 @@ public class PdfService : IPdfService private readonly IBaremeService _baremeService; private readonly IMontantRegleService _montantRegleService; private readonly IRemboursementService _remboursementService; + private readonly IPrecisionDistanceService _precisionDistanceService; private readonly AppDbContext _context; + ///

Logo carré, chargé une seule fois depuis la ressource embarquée (Assets/logo-carre.png). + private static readonly byte[] LogoCarre = ChargerLogoCarre(); + public PdfService( IResumeService resumeService, IProfilService profilService, @@ -38,6 +42,7 @@ public class PdfService : IPdfService IBaremeService baremeService, IMontantRegleService montantRegleService, IRemboursementService remboursementService, + IPrecisionDistanceService precisionDistanceService, AppDbContext context) { _resumeService = resumeService; @@ -46,9 +51,32 @@ public class PdfService : IPdfService _baremeService = baremeService; _montantRegleService = montantRegleService; _remboursementService = remboursementService; + _precisionDistanceService = precisionDistanceService; _context = context; } + /// Charge les octets du logo carré depuis la ressource embarquée de l'assembly. + private static byte[] ChargerLogoCarre() + { + var assembly = typeof(PdfService).Assembly; + var nomRessource = assembly.GetManifestResourceNames() + .FirstOrDefault(n => n.EndsWith("logo-carre.png", StringComparison.OrdinalIgnoreCase)); + if (nomRessource is null) + { + return Array.Empty(); + } + + using var flux = assembly.GetManifestResourceStream(nomRessource); + if (flux is null) + { + return Array.Empty(); + } + + using var memoire = new MemoryStream(); + flux.CopyTo(memoire); + return memoire.ToArray(); + } + /// public async Task GenererRapportMensuelAsync( int annee, int mois, int vehiculeId, CancellationToken cancellationToken = default) @@ -62,9 +90,10 @@ public class PdfService : IPdfService return await ExecuterAvecTimeoutAsync(cancellationToken, async token => { var modele = await AssemblerModeleMensuelAsync(annee, mois, vehiculeId, token); - var octets = RendreMensuel(modele, token); + var precision = await _precisionDistanceService.ObtenirAsync(token); + var octets = RendreMensuel(modele, precision, token); - var nomFichier = $"trajets_{mois:D2}_{annee:D4}.pdf"; + var nomFichier = ConstruireNomFichier($"{annee:D4}{mois:D2}", modele.Profil.Matricule, modele.Vehicule.Plaque); return new PdfResult(octets, nomFichier); }); } @@ -76,9 +105,11 @@ public class PdfService : IPdfService return await ExecuterAvecTimeoutAsync(cancellationToken, async token => { var modele = await AssemblerModeleAnnuelAsync(annee, vehiculeId, token); - var octets = RendreAnnuel(modele, token); + var precision = await _precisionDistanceService.ObtenirAsync(token); + var octets = RendreAnnuel(modele, precision, token); - var nomFichier = $"trajets_{annee:D4}.pdf"; + var nomFichier = ConstruireNomFichier( + $"{annee:D4}", modele.Profil.Matricule, modele.Regularisation.Plaque); return new PdfResult(octets, nomFichier); }); } @@ -274,7 +305,7 @@ public class PdfService : IPdfService /// /// Rend le document mensuel en octets PDF selon la maquette « PDF Mensuel » du design. /// - private static byte[] RendreMensuel(ModeleRapportMensuel modele, CancellationToken cancellationToken) + private static byte[] RendreMensuel(ModeleRapportMensuel modele, int precision, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -286,8 +317,8 @@ public class PdfService : IPdfService page.Margin(30); page.DefaultTextStyle(x => x.FontSize(9).FontColor(Colors.Black)); - page.Header().Element(c => ComposerEntete(c, modele)); - page.Content().PaddingTop(10).Element(c => ComposerTableTrajets(c, modele)); + page.Header().Element(c => ComposerEntete(c, modele, precision)); + page.Content().PaddingTop(10).Element(c => ComposerTableTrajets(c, modele, precision)); page.Footer().AlignCenter().Text(txt => { txt.Span("Page "); @@ -306,86 +337,90 @@ public class PdfService : IPdfService /// Compose l'en-tête obligatoire (Exigences 7.6, 7.8, 7.10) : titre fixe, identité, véhicule, /// période, adresse de départ, totaux mois/année, TOTAL IK et Montant_Regle. /// - private static void ComposerEntete(IContainer container, ModeleRapportMensuel modele) + private static void ComposerEntete(IContainer container, ModeleRapportMensuel modele, int precision) { var periode = $"{NomMois(modele.Mois).ToUpper(FrCulture)} {modele.Annee}"; var identite = FormatIdentite(modele.Profil); var matricule = string.IsNullOrWhiteSpace(modele.Profil.Matricule) ? "—" : modele.Profil.Matricule!; - var adresseDepart = string.IsNullOrWhiteSpace(modele.Profil.AdresseDomicile) + var domicile = string.IsNullOrWhiteSpace(modele.Profil.AdresseDomicile) ? "—" : modele.Profil.AdresseDomicile!; var vehiculeLibelle = $"{modele.Vehicule.Plaque} — {modele.Vehicule.PuissanceFiscale} CV " + $"(Coef. : {FormatDecimal(modele.Coefficient, 3)} / Base : {FormatDecimal(modele.Base, 0)})"; - container.Column(col => + container.Row(ligne => { - col.Spacing(2); - - // Titre fixe imposé par l'Exigence 7.6. - col.Item().Text("Rapport de trajets").FontSize(16).Bold(); - col.Item().Text("Feuille d'indemnité kilométrique mensuelle").FontSize(11).SemiBold(); - - // Identité (nom, prénom, matricule) — Exigence 7.8. - col.Item().PaddingTop(4).Text(txt => + // Logo carré en haut à gauche. + if (LogoCarre.Length > 0) { - txt.Span("Utilisateur : ").SemiBold(); - txt.Span($"{identite} — Matricule : {matricule}"); - }); + ligne.ConstantItem(45).Image(LogoCarre).FitWidth(); + } - // Véhicule (plaque, puissance fiscale, coefficient/base de la tranche annuelle) — Exigences 7.8/7.10. - col.Item().Text(txt => + ligne.RelativeItem().PaddingLeft(LogoCarre.Length > 0 ? 10 : 0).Column(col => { - txt.Span("Véhicule : ").SemiBold(); - txt.Span(vehiculeLibelle); - }); + col.Spacing(2); - // Période et adresse de départ du profil — Exigences 7.6/7.10. - col.Item().Text(txt => - { - txt.Span("Période : ").SemiBold(); - txt.Span(periode); - }); - col.Item().Text(txt => - { - txt.Span("Adresse de départ : ").SemiBold(); - txt.Span(adresseDepart); - }); + // Titre fixe imposé par l'Exigence 7.6, période intégrée (remplace la ligne « Période »). + col.Item().Text("Rapport de trajets").FontSize(16).Bold(); + col.Item().Text($"Feuille d'indemnité kilométrique {periode}").FontSize(11).SemiBold(); - // Totaux : mois, année cumulée, TOTAL IK du mois, Montant_Regle — Exigences 7.6/7.10. - col.Item().PaddingTop(6).Row(row => - { - row.RelativeItem().Column(c => + // Identité (nom, prénom, matricule) — Exigence 7.8. + col.Item().PaddingTop(4).Text(txt => { - c.Item().Text(txt => + txt.Span("Utilisateur : ").SemiBold(); + txt.Span($"{identite} — Matricule : {matricule}"); + }); + + // Domicile, juste après l'identité (même position que sur le rapport annuel). + col.Item().Text(txt => + { + txt.Span("Domicile : ").SemiBold(); + txt.Span(domicile); + }); + + // Véhicule (plaque, puissance fiscale, coefficient/base de la tranche annuelle) — Exigences 7.8/7.10. + col.Item().Text(txt => + { + txt.Span("Véhicule : ").SemiBold(); + txt.Span(vehiculeLibelle); + }); + + // Totaux : mois, année cumulée, TOTAL IK du mois, Montant_Regle — Exigences 7.6/7.10. + col.Item().PaddingTop(6).Row(row => + { + row.RelativeItem().Column(c => { - txt.Span("Total parcouru sur le mois : ").SemiBold(); - txt.Span($"{FormatKm(modele.TotalKmMois)} km"); + c.Item().Text(txt => + { + txt.Span("Total parcouru sur le mois : ").SemiBold(); + txt.Span($"{FormatKm(modele.TotalKmMois, precision)} km"); + }); + c.Item().Text(txt => + { + txt.Span("Total parcouru sur l'année : ").SemiBold(); + txt.Span($"{FormatKm(modele.TotalKmAnnuel, precision)} km"); + }); }); - c.Item().Text(txt => + row.RelativeItem().Column(c => { - txt.Span("Total parcouru sur l'année : ").SemiBold(); - txt.Span($"{FormatKm(modele.TotalKmAnnuel)} km"); + c.Item().Text(txt => + { + txt.Span("TOTAL IK du mois : ").SemiBold(); + txt.Span($"{FormatMontant(modele.TotalIkMois)} €"); + }); + c.Item().Text(txt => + { + txt.Span("Réglé : ").SemiBold(); + txt.Span($"{FormatMontant(modele.MontantRegle)} €"); + }); }); }); - row.RelativeItem().Column(c => - { - c.Item().Text(txt => - { - txt.Span("TOTAL IK du mois : ").SemiBold(); - txt.Span($"{FormatMontant(modele.TotalIkMois)} €"); - }); - c.Item().Text(txt => - { - txt.Span("Réglé : ").SemiBold(); - txt.Span($"{FormatMontant(modele.MontantRegle)} €"); - }); - }); - }); - col.Item().PaddingTop(6).LineHorizontal(1).LineColor(Colors.Grey.Medium); + col.Item().PaddingTop(6).LineHorizontal(1).LineColor(Colors.Grey.Medium); + }); }); } @@ -393,7 +428,7 @@ public class PdfService : IPdfService /// Compose la table des trajets du mois (Exigence 7.11) : date, motif (commentaire), /// adresse de départ → arrivée, kilomètres. /// - private static void ComposerTableTrajets(IContainer container, ModeleRapportMensuel modele) + private static void ComposerTableTrajets(IContainer container, ModeleRapportMensuel modele, int precision) { container.Table(table => { @@ -433,12 +468,12 @@ public class PdfService : IPdfService table.Cell().Element(Cellule).Text(trajet.Date.ToString("dd/MM/yyyy", FrCulture)); table.Cell().Element(Cellule).Text(motif); table.Cell().Element(Cellule).Text(itineraire); - table.Cell().Element(Cellule).AlignRight().Text(FormatKm(km)); + table.Cell().Element(Cellule).AlignRight().Text(FormatKm(km, precision)); } // Ligne de total du mois. table.Cell().ColumnSpan(3).Element(CelluleTotal).AlignRight().Text("Total du mois :").SemiBold(); - table.Cell().Element(CelluleTotal).AlignRight().Text($"{FormatKm(modele.TotalKmMois)}").SemiBold(); + table.Cell().Element(CelluleTotal).AlignRight().Text($"{FormatKm(modele.TotalKmMois, precision)}").SemiBold(); } }); @@ -456,7 +491,7 @@ public class PdfService : IPdfService /// /// Rend le document de synthèse annuelle en octets PDF selon la maquette « PDF Annuel » du design. /// - private static byte[] RendreAnnuel(ModeleRapportAnnuel modele, CancellationToken cancellationToken) + private static byte[] RendreAnnuel(ModeleRapportAnnuel modele, int precision, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -468,13 +503,13 @@ public class PdfService : IPdfService page.Margin(30); page.DefaultTextStyle(x => x.FontSize(9).FontColor(Colors.Black)); - page.Header().Element(c => ComposerEnteteAnnuel(c, modele)); + page.Header().Element(c => ComposerEnteteAnnuel(c, modele, precision)); page.Content().PaddingTop(10).Column(col => { col.Spacing(10); col.Item().Element(c => ComposerTableBaremeAnnuel(c, modele)); - col.Item().Element(c => ComposerTableSyntheseAnnuelle(c, modele)); - col.Item().Element(c => ComposerTotauxAnnuels(c, modele)); + col.Item().Element(c => ComposerTableSyntheseAnnuelle(c, modele, precision)); + col.Item().Element(c => ComposerTotauxAnnuels(c, modele, precision)); }); page.Footer().AlignCenter().Text(txt => { @@ -494,7 +529,7 @@ public class PdfService : IPdfService /// Compose l'en-tête de la synthèse annuelle (Exigences 7.6, 7.7, 7.8, 7.12) : titre fixe, /// identité, année, domicile, véhicule (plaque, puissance fiscale) et tranche annuelle applicable. /// - private static void ComposerEnteteAnnuel(IContainer container, ModeleRapportAnnuel modele) + private static void ComposerEnteteAnnuel(IContainer container, ModeleRapportAnnuel modele, int precision) { var reg = modele.Regularisation; var identite = FormatIdentite(modele.Profil); @@ -505,55 +540,58 @@ public class PdfService : IPdfService ? "—" : modele.Profil.AdresseDomicile!; - container.Column(col => + container.Row(ligne => { - col.Spacing(2); - - // Titre fixe imposé par l'Exigence 7.6. - col.Item().Text("Rapport de trajets").FontSize(16).Bold(); - col.Item().Text($"Synthèse {modele.Annee} d'indemnité kilométrique").FontSize(11).SemiBold(); - - // Identité (nom, prénom, matricule) — Exigence 7.8. - col.Item().PaddingTop(4).Text(txt => + // Logo carré en haut à gauche. + if (LogoCarre.Length > 0) { - txt.Span("Utilisateur : ").SemiBold(); - txt.Span($"{identite} — Matricule : {matricule}"); - }); + ligne.ConstantItem(45).Image(LogoCarre).FitWidth(); + } - // Année (période couverte) — Exigence 7.6. - col.Item().Text(txt => + ligne.RelativeItem().PaddingLeft(LogoCarre.Length > 0 ? 10 : 0).Column(col => { - txt.Span("Année : ").SemiBold(); - txt.Span(modele.Annee.ToString(CultureInfo.InvariantCulture)); - }); + col.Spacing(2); - // Adresse de domicile — Exigence 7.12. - col.Item().Text(txt => - { - txt.Span("Domicile : ").SemiBold(); - txt.Span(domicile); - }); + // Titre fixe imposé par l'Exigence 7.6. + col.Item().Text("Rapport de trajets").FontSize(16).Bold(); + col.Item().Text($"Synthèse {modele.Annee} d'indemnité kilométrique").FontSize(11).SemiBold(); - // Véhicule (plaque, puissance fiscale) et tranche annuelle applicable — Exigences 7.7/7.8/7.12. - col.Item().Text(txt => - { - txt.Span("Véhicule : ").SemiBold(); - txt.Span($"{reg.Plaque} — {reg.PuissanceFiscale} CV"); - }); - col.Item().Text(txt => - { - txt.Span("Barème applicable : ").SemiBold(); - txt.Span(reg.TrancheLibelle); - }); + // Identité (nom, prénom, matricule) — Exigence 7.8. + col.Item().PaddingTop(4).Text(txt => + { + txt.Span("Utilisateur : ").SemiBold(); + txt.Span($"{identite} — Matricule : {matricule}"); + }); - // Total kilométrique de la période (Exigence 7.6). - col.Item().Text(txt => - { - txt.Span("Total kilométrique de l'année : ").SemiBold(); - txt.Span($"{FormatKm(reg.TotalKmAnnuel)} km"); - }); + // Adresse de domicile — Exigence 7.12. (La ligne « Année » a été retirée : la + // période figure déjà dans le titre « Synthèse {Année} d'indemnité kilométrique ».) + col.Item().Text(txt => + { + txt.Span("Domicile : ").SemiBold(); + txt.Span(domicile); + }); - col.Item().PaddingTop(6).LineHorizontal(1).LineColor(Colors.Grey.Medium); + // Véhicule (plaque, puissance fiscale) et tranche annuelle applicable — Exigences 7.7/7.8/7.12. + col.Item().Text(txt => + { + txt.Span("Véhicule : ").SemiBold(); + txt.Span($"{reg.Plaque} — {reg.PuissanceFiscale} CV"); + }); + col.Item().Text(txt => + { + txt.Span("Barème applicable : ").SemiBold(); + txt.Span(reg.TrancheLibelle); + }); + + // Total kilométrique de la période (Exigence 7.6). + col.Item().Text(txt => + { + txt.Span("Total kilométrique de l'année : ").SemiBold(); + txt.Span($"{FormatKm(reg.TotalKmAnnuel, precision)} km"); + }); + + col.Item().PaddingTop(6).LineHorizontal(1).LineColor(Colors.Grey.Medium); + }); }); } @@ -618,7 +656,7 @@ public class PdfService : IPdfService /// Compose la table des douze mois (kilomètres parcourus, frais payé, frais réel) — Exigence 7.12. /// Les données proviennent de . /// - private static void ComposerTableSyntheseAnnuelle(IContainer container, ModeleRapportAnnuel modele) + private static void ComposerTableSyntheseAnnuelle(IContainer container, ModeleRapportAnnuel modele, int precision) { var reg = modele.Regularisation; @@ -643,14 +681,14 @@ public class PdfService : IPdfService foreach (var ligne in reg.Mois) { table.Cell().Element(Cellule).Text(NomMois(ligne.Mois)); - table.Cell().Element(Cellule).AlignRight().Text($"{FormatKm(ligne.KmMois)}"); + table.Cell().Element(Cellule).AlignRight().Text($"{FormatKm(ligne.KmMois, precision)}"); table.Cell().Element(Cellule).AlignRight().Text($"{FormatMontant(ligne.FraisPaye)} €"); table.Cell().Element(Cellule).AlignRight().Text($"{FormatMontant(ligne.FraisReelMensuel)} €"); } // Ligne de total annuel. table.Cell().Element(CelluleTotal).Text("TOTAL").SemiBold(); - table.Cell().Element(CelluleTotal).AlignRight().Text($"{FormatKm(reg.TotalKmAnnuel)}").SemiBold(); + table.Cell().Element(CelluleTotal).AlignRight().Text($"{FormatKm(reg.TotalKmAnnuel, precision)}").SemiBold(); table.Cell().Element(CelluleTotal).AlignRight().Text($"{FormatMontant(reg.TotalPaye)} €").SemiBold(); table.Cell().Element(CelluleTotal).AlignRight().Text($"{FormatMontant(reg.MontantReel)} €").SemiBold(); }); @@ -669,13 +707,13 @@ public class PdfService : IPdfService /// /// Compose le bloc « formule réelle » et la régularisation (réel − payé) — Exigence 7.12. /// - private static void ComposerTotauxAnnuels(IContainer container, ModeleRapportAnnuel modele) + private static void ComposerTotauxAnnuels(IContainer container, ModeleRapportAnnuel modele, int precision) { var reg = modele.Regularisation; // Formule réelle : total_km × coefficient + base = Montant_Reel (tranche annuelle). var formule = - $"{FormatKm(reg.TotalKmAnnuel)} km × {FormatDecimal(reg.CoefficientTranche, 3)} " + + $"{FormatKm(reg.TotalKmAnnuel, precision)} km × {FormatDecimal(reg.CoefficientTranche, 3)} " + $"+ {FormatDecimal(reg.BaseTranche, 0)} = {FormatMontant(reg.MontantReel)} € " + $"(tranche {reg.TrancheLibelle}, {reg.PuissanceFiscale} CV)"; @@ -703,9 +741,37 @@ public class PdfService : IPdfService return identite.Length > 0 ? identite : "—"; } - /// Kilomètres : séparateur de milliers, 2 décimales. - private static string FormatKm(decimal km) => - Math.Round(km, 2, MidpointRounding.AwayFromZero).ToString("N2", FrCulture); + /// + /// Kilomètres : séparateur de milliers, nombre de décimales selon Precision_Distance + /// (0, 1 ou 2 — voir la spec precision-distances-km). + /// + private static string FormatKm(decimal km, int precision) => + Math.Round(km, precision, MidpointRounding.AwayFromZero).ToString("N" + precision, FrCulture); + + /// + /// Construit le nom de fichier d'export au format `AAAAMM_Trajets_MATRICULE_PLAQUE.pdf` + /// (sans le segment mois pour l'export annuel, `periode` valant alors `AAAA`). Les segments + /// Matricule et Plaque sont omis (avec leur séparateur) lorsqu'ils sont vides. + /// + private static string ConstruireNomFichier(string periode, string? matricule, string? plaque) + { + var segments = new List { periode, "Trajets" }; + + if (!string.IsNullOrWhiteSpace(matricule)) + { + segments.Add(NettoyerSegmentNomFichier(matricule)); + } + if (!string.IsNullOrWhiteSpace(plaque)) + { + segments.Add(NettoyerSegmentNomFichier(plaque)); + } + + return string.Join("_", segments) + ".pdf"; + } + + /// Retire les espaces et tirets d'un segment de nom de fichier (ex. plaque « AB-123-CD » → « AB123CD »). + private static string NettoyerSegmentNomFichier(string valeur) => + valeur.Replace(" ", "").Replace("-", "").Trim(); /// Montant : séparateur de milliers, 2 décimales. private static string FormatMontant(decimal montant) => diff --git a/backend/SchotzIadKmTracker.Tests/PdfExport/PdfServiceIntegrationTests.cs b/backend/SchotzIadKmTracker.Tests/PdfExport/PdfServiceIntegrationTests.cs new file mode 100644 index 0000000..f500dc3 --- /dev/null +++ b/backend/SchotzIadKmTracker.Tests/PdfExport/PdfServiceIntegrationTests.cs @@ -0,0 +1,169 @@ +using System.Threading; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging.Abstractions; +using Moq; +using SchotzIadKmTracker.Api.Data; +using SchotzIadKmTracker.Api.Models.DTOs; +using SchotzIadKmTracker.Api.Models.Entities; +using SchotzIadKmTracker.Api.Repositories; +using SchotzIadKmTracker.Api.Services; +using Xunit; + +namespace SchotzIadKmTracker.Tests.PdfExport; + +/// +/// Tests d'intégration de (vérification manuelle demandée après les +/// changements de nommage de fichier, logo, précision des distances et restructuration des +/// en-têtes mensuel/annuel). Branche les services réels sur une base SQLite en mémoire ; +/// seul est mocké (jamais appelé ici, aucune adresse de domicile +/// à géocoder dans les scénarios testés). +/// +public class PdfServiceIntegrationTests : IDisposable +{ + private readonly SqliteConnection _connection; + private readonly AppDbContext _context; + private readonly PdfService _pdfService; + + public PdfServiceIntegrationTests() + { + // Licence QuestPDF (usage communautaire, gratuit) — requise avant toute génération de + // PDF ; configurée normalement au démarrage de l'application (Program.cs), reproduite + // ici car ce test instancie PdfService directement sans démarrer le host. + QuestPDF.Settings.License = QuestPDF.Infrastructure.LicenseType.Community; + + _connection = new SqliteConnection("Data Source=:memory:"); + _connection.Open(); + + var options = new DbContextOptionsBuilder().UseSqlite(_connection).Options; + _context = new AppDbContext(options); + _context.Database.EnsureCreated(); + + var precisionDistanceService = new PrecisionDistanceService(_context); + var baremeService = new BaremeService(_context); + var resumeService = new ResumeService(_context, precisionDistanceService); + var montantRegleService = new MontantRegleService(_context, baremeService, precisionDistanceService); + var remboursementService = new RemboursementService( + _context, baremeService, montantRegleService, precisionDistanceService); + + var vehiculeRepository = new VehiculeRepository(_context); + var vehiculeService = new VehiculeService(vehiculeRepository, _context); + + var adresseCacheRepository = new AdresseCacheRepository(_context); + var adresseCacheService = new AdresseCacheService(adresseCacheRepository, _context); + var banClientMock = new Mock(); + var profilService = new ProfilService( + _context, banClientMock.Object, adresseCacheService, NullLogger.Instance); + + _pdfService = new PdfService( + resumeService, + profilService, + vehiculeService, + baremeService, + montantRegleService, + remboursementService, + precisionDistanceService, + _context); + } + + /// Prépare un profil, un véhicule, un trajet et une tranche de barème de test. + private async Task PreparerScenarioAsync(string matricule, string plaque, int precision) + { + _context.Profil.Add(new Profil + { + Id = 1, + Nom = "Dupont", + Prenom = "Jean", + Matricule = matricule, + AdresseDomicile = null + }); + + var vehicule = new Vehicule + { + Denomination = "Véhicule de test", + Plaque = plaque, + PuissanceFiscale = 5, + DateEffet = new DateOnly(2020, 1, 1) + }; + _context.Vehicules.Add(vehicule); + + _context.TranchesBareme.Add(new TrancheBareme + { + Annee = 2026, + PuissanceFiscale = 5, + KmMin = 0m, + KmMax = null, + Coefficient = 0.350m, + Base = 0m + }); + + await _context.SaveChangesAsync(); + + _context.Trajets.Add(new Trajet + { + Date = new DateOnly(2026, 3, 15), + AdresseDepart = "Départ test", + AdresseArrivee = "Arrivée test", + Distance = 12.3456m, + AllerRetour = false, + Position = 1m, + VehiculeId = vehicule.Id, + PuissanceFiscale = 5 + }); + await _context.SaveChangesAsync(); + + await precisionServiceDefinir(precision); + + return vehicule.Id; + } + + private async Task precisionServiceDefinir(int precision) + { + var service = new PrecisionDistanceService(_context); + await service.DefinirAsync(precision, CancellationToken.None); + } + + [Fact] + public async Task GenererRapportMensuelAsync_produit_un_pdf_et_un_nom_de_fichier_conforme() + { + var vehiculeId = await PreparerScenarioAsync("AB1234", "AB-123-CD", precision: 0); + + var resultat = await _pdfService.GenererRapportMensuelAsync(2026, 3, vehiculeId, CancellationToken.None); + + resultat.Contenu.Should().NotBeEmpty(); + // En-tête PDF standard : les octets générés doivent être un vrai document PDF. + System.Text.Encoding.ASCII.GetString(resultat.Contenu, 0, 4).Should().Be("%PDF"); + resultat.NomFichier.Should().Be("202603_Trajets_AB1234_AB123CD.pdf"); + } + + [Fact] + public async Task GenererRapportAnnuelAsync_produit_un_pdf_et_un_nom_de_fichier_conforme() + { + var vehiculeId = await PreparerScenarioAsync("XY9876", "ZZ-999-ZZ", precision: 2); + + var resultat = await _pdfService.GenererRapportAnnuelAsync(2026, vehiculeId, CancellationToken.None); + + resultat.Contenu.Should().NotBeEmpty(); + System.Text.Encoding.ASCII.GetString(resultat.Contenu, 0, 4).Should().Be("%PDF"); + resultat.NomFichier.Should().Be("2026_Trajets_XY9876_ZZ999ZZ.pdf"); + } + + [Fact] + public async Task GenererRapportMensuelAsync_omet_les_segments_matricule_et_plaque_absents() + { + // Matricule vide (chaîne vide) : le segment doit être omis du nom de fichier. + var vehiculeId = await PreparerScenarioAsync(string.Empty, "CD-456-EF", precision: 1); + + var resultat = await _pdfService.GenererRapportMensuelAsync(2026, 3, vehiculeId, CancellationToken.None); + + resultat.NomFichier.Should().Be("202603_Trajets_CD456EF.pdf"); + } + + public void Dispose() + { + _context.Dispose(); + _connection.Dispose(); + } +} diff --git a/frontend/src/app/core/services/trajet.service.ts b/frontend/src/app/core/services/trajet.service.ts index 5099620..d14210d 100644 --- a/frontend/src/app/core/services/trajet.service.ts +++ b/frontend/src/app/core/services/trajet.service.ts @@ -1,4 +1,4 @@ -import { HttpClient, HttpParams } from '@angular/common/http'; +import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http'; import { Injectable, inject } from '@angular/core'; import { Observable } from 'rxjs'; @@ -77,22 +77,46 @@ export class TrajetService { }); } - /** Export PDF mensuel (GET /api/exports/mensuel/{annee}/{mois}). */ - exportPdfMensuel(annee: number, mois: number, vehiculeId?: number): Observable { + /** + * Export PDF mensuel (GET /api/exports/mensuel/{annee}/{mois}). Réponse complète + * (et non le seul Blob) afin que l'appelant puisse lire le nom de fichier suggéré + * par le backend depuis l'en-tête `Content-Disposition`. + */ + exportPdfMensuel(annee: number, mois: number, vehiculeId?: number): Observable> { return this.http.get(`${this.baseUrl}/exports/mensuel/${annee}/${mois}`, { params: this.vehiculeParams(vehiculeId), - responseType: 'blob' + responseType: 'blob', + observe: 'response' }); } - /** Export PDF annuel (GET /api/exports/annuel/{annee}). */ - exportPdfAnnuel(annee: number, vehiculeId?: number): Observable { + /** + * Export PDF annuel (GET /api/exports/annuel/{annee}). Réponse complète (et non le + * seul Blob) afin que l'appelant puisse lire le nom de fichier suggéré par le backend + * depuis l'en-tête `Content-Disposition`. + */ + exportPdfAnnuel(annee: number, vehiculeId?: number): Observable> { return this.http.get(`${this.baseUrl}/exports/annuel/${annee}`, { params: this.vehiculeParams(vehiculeId), - responseType: 'blob' + responseType: 'blob', + observe: 'response' }); } + /** + * Extrait le nom de fichier suggéré par le backend depuis l'en-tête + * `Content-Disposition: attachment; filename="..."` d'une réponse HTTP. + * Retourne `null` si l'en-tête est absent ou ne contient pas de nom de fichier. + */ + extraireNomFichier(reponse: HttpResponse): string | null { + const entete = reponse.headers.get('Content-Disposition'); + if (!entete) { + return null; + } + const correspondance = /filename\*?=(?:UTF-8'')?"?([^;"]+)"?/i.exec(entete); + return correspondance ? decodeURIComponent(correspondance[1]) : null; + } + /** * Trajets d'une journée avec géométries pour la carte * (GET /api/trajets/journee/{date}). La date est au format ISO (yyyy-MM-dd). diff --git a/frontend/src/app/features/panneau-totaux/panneau-totaux.component.html b/frontend/src/app/features/panneau-totaux/panneau-totaux.component.html index f70b0a3..7e8d7b7 100644 --- a/frontend/src/app/features/panneau-totaux/panneau-totaux.component.html +++ b/frontend/src/app/features/panneau-totaux/panneau-totaux.component.html @@ -24,32 +24,46 @@
- Indication de versement (80%) + Remboursement indicatif + {{ montantPrevisionnel.montantPrevisionnelMensuel | number: '1.2-2' }} €
-

- Simple indication de versement, calculée à 80% du barème sur le mois - affiché. Le montant réellement versé est le montant réglé que vous - saisissez. -

Montant prévisionnel annuel + {{ montantPrevisionnel.montantPrevisionnelAnnuel | number: '1.2-2' }} €
-

- Projection à 100% du barème sur le total annuel partiel, sans - minoration. Cette projection ne se substitue pas au montant réel - calculé en fin d'année. -

} diff --git a/frontend/src/app/features/panneau-totaux/panneau-totaux.component.scss b/frontend/src/app/features/panneau-totaux/panneau-totaux.component.scss index 7215d71..8378466 100644 --- a/frontend/src/app/features/panneau-totaux/panneau-totaux.component.scss +++ b/frontend/src/app/features/panneau-totaux/panneau-totaux.component.scss @@ -13,6 +13,8 @@ margin: 0 0 12px; font-size: 1.05rem; color: #333; + text-align: center; + text-transform: uppercase; } &__erreur { @@ -67,17 +69,32 @@ padding-top: 12px; border-top: 1px solid #e0e0e0; + &-libelle { + display: inline-flex; + align-items: center; + gap: 6px; + } + &-montant { font-variant-numeric: tabular-nums; color: #1565c0; } + } - &-note { - margin: 8px 0 0; - font-size: 0.8rem; - color: #777; - font-style: italic; - line-height: 1.35; + &__aide { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0; + border: none; + background: none; + color: #888; + cursor: help; + line-height: 0; + + &:hover, + &:focus-visible { + color: #1565c0; } } } diff --git a/frontend/src/app/features/resume-annuel/resume-annuel.component.html b/frontend/src/app/features/resume-annuel/resume-annuel.component.html index 43927b5..9727f21 100644 --- a/frontend/src/app/features/resume-annuel/resume-annuel.component.html +++ b/frontend/src/app/features/resume-annuel/resume-annuel.component.html @@ -2,22 +2,25 @@

Résumé annuel

-
- - -
+
+
+ + +
-
+
+ +
- +
@if (chargement()) {

Chargement du résumé…

@@ -45,6 +26,7 @@ Date + Commentaire Départ Arrivée Distance (km) @@ -54,22 +36,23 @@ @for (trajet of resume.trajets; track trajet.id) { {{ trajet.date | date: 'dd/MM/yyyy' }} + {{ trajet.commentaire || '—' }} {{ trajet.adresseDepart }} {{ trajet.adresseArrivee }} - {{ trajet.distance != null ? (trajet.distance | number: '1.2-2') : '—' }} + {{ trajet.distance != null ? (trajet.distance | number: formatKm()) : '—' }} } @empty { - Aucun trajet pour ce mois. + Aucun trajet pour ce mois. } - Total mensuel - {{ resume.totalKm | number: '1.2-2' }} km + Total mensuel + {{ resume.totalKm | number: formatKm() }} km diff --git a/frontend/src/app/features/resume-mensuel/resume-mensuel.component.scss b/frontend/src/app/features/resume-mensuel/resume-mensuel.component.scss index d9585e1..97ef8b9 100644 --- a/frontend/src/app/features/resume-mensuel/resume-mensuel.component.scss +++ b/frontend/src/app/features/resume-mensuel/resume-mensuel.component.scss @@ -12,29 +12,12 @@ h1 { .selecteurs { display: flex; flex-wrap: wrap; - align-items: flex-end; + align-items: flex-start; + justify-content: space-between; gap: 1rem; margin-bottom: 1.5rem; } -.champ { - display: flex; - flex-direction: column; -} - -.champ label { - font-weight: 600; - margin-bottom: 0.25rem; -} - -.champ select, -.champ input { - padding: 0.5rem; - border: 1px solid #bbb; - border-radius: 6px; - font-size: 0.95rem; -} - .actions { display: flex; gap: 0.75rem; diff --git a/frontend/src/app/features/resume-mensuel/resume-mensuel.component.ts b/frontend/src/app/features/resume-mensuel/resume-mensuel.component.ts index c858be9..0881760 100644 --- a/frontend/src/app/features/resume-mensuel/resume-mensuel.component.ts +++ b/frontend/src/app/features/resume-mensuel/resume-mensuel.component.ts @@ -3,8 +3,10 @@ import { Component, OnInit, inject, signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { NotificationService } from '../../core/services/notification.service'; +import { ParametresApplicationService } from '../../core/services/parametres-application.service'; import { TrajetService } from '../../core/services/trajet.service'; import { ResumeMensuel } from '../../core/models'; +import { MoisSelectionne, SelecteurTemporelComponent } from '../navigation-temporelle/selecteur-temporel.component'; /** * Résumé mensuel (Exigences 3.1, 3.5, 3.7, 7.3). @@ -22,25 +24,45 @@ import { ResumeMensuel } from '../../core/models'; @Component({ selector: 'app-resume-mensuel', standalone: true, - imports: [CommonModule, FormsModule], + imports: [CommonModule, FormsModule, SelecteurTemporelComponent], templateUrl: './resume-mensuel.component.html', styleUrl: './resume-mensuel.component.scss' }) export class ResumeMensuelComponent implements OnInit { private readonly trajetService = inject(TrajetService); private readonly notification = inject(NotificationService); + readonly parametresService = inject(ParametresApplicationService); /** Bornes de saisie de l'année (cohérentes avec la validation backend). */ readonly anneeMin = 2000; readonly anneeMax = 2100; - /** Liste des mois pour le sélecteur (1–12). */ - readonly moisDisponibles = Array.from({ length: 12 }, (_, i) => i + 1); - /** Sélection courante, initialisée au mois/année en cours. */ annee: number = new Date().getFullYear(); mois: number = new Date().getMonth() + 1; + /** Date ISO (`yyyy-MM-dd`) transmise au sélecteur temporel (jour arbitraire du mois sélectionné). */ + get dateSelecteur(): string { + const mm = String(this.mois).padStart(2, '0'); + return `${this.annee}-${mm}-01`; + } + + /** Réagit à la sélection d'un mois via le sélecteur temporel (même composant que la page trajets). */ + onMoisSelectionne(selection: MoisSelectionne): void { + this.annee = selection.annee; + this.mois = selection.mois; + this.charger(); + } + + /** + * Chaîne de format `number` (`1.{p}-{p}`) basée sur la précision courante des + * distances, pour un affichage dynamique des distances en km. + */ + formatKm(): string { + const precision = this.parametresService.precisionDistance(); + return `1.${precision}-${precision}`; + } + /** Résumé chargé (null tant qu'aucun chargement réussi ou après une erreur). */ readonly resume = signal(null); @@ -76,7 +98,11 @@ export class ResumeMensuelComponent implements OnInit { }); } - /** Déclenche l'export PDF mensuel et le téléchargement navigateur (Exigence 7.3). */ + /** + * Déclenche l'export PDF mensuel et le téléchargement navigateur (Exigence 7.3). Le nom de + * fichier utilisé est celui suggéré par le backend (en-tête `Content-Disposition`, format + * `AAAAMM_Trajets_MATRICULE_PLAQUE.pdf`) ; à défaut (en-tête absent), un repli local est utilisé. + */ exporterPdf(): void { if (!this.selectionValide() || this.export()) { return; @@ -84,10 +110,10 @@ export class ResumeMensuelComponent implements OnInit { this.export.set(true); this.trajetService.exportPdfMensuel(this.annee, this.mois).subscribe({ - next: (blob) => { + next: (reponse) => { this.export.set(false); - const nom = this.nomFichierParDefaut(); - this.declencherTelechargement(blob, nom); + const nom = this.trajetService.extraireNomFichier(reponse) ?? this.nomFichierParDefaut(); + this.declencherTelechargement(reponse.body!, nom); }, error: () => { this.export.set(false); @@ -96,10 +122,10 @@ export class ResumeMensuelComponent implements OnInit { }); } - /** Nom de fichier de repli au format `trajets_MM_AAAA.pdf`. */ + /** Nom de fichier de repli si le backend n'a pas fourni de `Content-Disposition`. */ private nomFichierParDefaut(): string { const mm = String(this.mois).padStart(2, '0'); - return `trajets_${mm}_${this.annee}.pdf`; + return `${this.annee}${mm}_Trajets.pdf`; } /**