From bef9cbdde00cf4ca68bd9a183955523f6f5d8ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Mogu=C3=A9rou?= Date: Sun, 14 Apr 2024 17:00:03 +0200 Subject: [PATCH] =?UTF-8?q?base=20de=20donn=C3=A9es=20+=20pdf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- colloscope/migrations/0001_initial.py | 97 +++++++++++++- ...teur_colleur_alter_utilisateur_etudiant.py | 24 ++++ colloscope/models.py | 72 +++++++++-- colloscope/pdfexport.py | 118 ++++++++++-------- test.pdf | Bin 5327 -> 5473 bytes 5 files changed, 244 insertions(+), 67 deletions(-) create mode 100644 colloscope/migrations/0002_alter_utilisateur_colleur_alter_utilisateur_etudiant.py diff --git a/colloscope/migrations/0001_initial.py b/colloscope/migrations/0001_initial.py index 1e6583e..3ac3ff1 100644 --- a/colloscope/migrations/0001_initial.py +++ b/colloscope/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.4 on 2024-04-12 22:38 +# Generated by Django 5.0.4 on 2024-04-14 13:40 import django.db.models.deletion from django.db import migrations, models @@ -12,29 +12,116 @@ class Migration(migrations.Migration): ] operations = [ + migrations.CreateModel( + name='Classe', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('libelle', models.CharField(max_length=20)), + ('annee', models.IntegerField()), + ('jour_zero', models.DateField()), + ], + ), migrations.CreateModel( name='Colleur', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('civilite', models.CharField(max_length=1)), ('nom', models.CharField(max_length=100)), ], ), + migrations.CreateModel( + name='Lycee', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('uai', models.CharField(max_length=10)), + ('libelle', models.CharField(max_length=100)), + ('vacances', models.CharField(max_length=1)), + ], + ), + migrations.CreateModel( + name='Matiere', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('libelle', models.CharField(max_length=100)), + ('code', models.CharField(max_length=20)), + ], + ), + migrations.CreateModel( + name='Groupe', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('libelle', models.CharField(max_length=100)), + ('classe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.classe')), + ], + ), migrations.CreateModel( name='Etudiant', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('prenom', models.CharField(max_length=100)), ('nom', models.CharField(max_length=100)), - ('groupe', models.IntegerField()), + ('classe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.classe')), + ('groupes', models.ManyToManyField(to='colloscope.groupe')), + ], + ), + migrations.AddField( + model_name='classe', + name='lycee', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.lycee'), + ), + migrations.CreateModel( + name='Periode', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('libelle', models.CharField(max_length=100)), + ('debut', models.DateField()), + ('fin', models.DateField()), + ('classe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.classe')), ], ), migrations.CreateModel( - name='Colle', + name='Creneau', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('groupe', models.IntegerField()), - ('date', models.DateTimeField()), + ('jour', models.IntegerField()), + ('heure', models.TimeField()), + ('duree', models.DurationField()), + ('salle', models.CharField(max_length=20)), + ('est_colle', models.BooleanField()), + ('capacite', models.IntegerField()), + ('classe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.classe')), ('colleur', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.colleur')), + ('matiere', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.matiere')), + ('periode', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.periode')), + ], + ), + migrations.CreateModel( + name='Rotation', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('semaine', models.IntegerField()), + ('creneau', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.creneau')), + ('groupes', models.ManyToManyField(to='colloscope.groupe')), + ], + ), + migrations.CreateModel( + name='Amendement', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('est_positif', models.BooleanField()), + ('etudiant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.etudiant')), + ('rotation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.rotation')), + ], + ), + migrations.CreateModel( + name='Utilisateur', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('username', models.CharField(max_length=100)), + ('password', models.CharField(max_length=300)), + ('timestamp', models.DateTimeField(auto_now_add=True)), + ('colleur', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.colleur')), + ('etudiant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='colloscope.etudiant')), ], ), ] diff --git a/colloscope/migrations/0002_alter_utilisateur_colleur_alter_utilisateur_etudiant.py b/colloscope/migrations/0002_alter_utilisateur_colleur_alter_utilisateur_etudiant.py new file mode 100644 index 0000000..9ad315f --- /dev/null +++ b/colloscope/migrations/0002_alter_utilisateur_colleur_alter_utilisateur_etudiant.py @@ -0,0 +1,24 @@ +# Generated by Django 5.0.4 on 2024-04-14 13:51 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('colloscope', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='utilisateur', + name='colleur', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='colloscope.colleur'), + ), + migrations.AlterField( + model_name='utilisateur', + name='etudiant', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='colloscope.etudiant'), + ), + ] diff --git a/colloscope/models.py b/colloscope/models.py index 3c2c89f..4fa259f 100644 --- a/colloscope/models.py +++ b/colloscope/models.py @@ -1,15 +1,69 @@ from django.db import models -class Colleur(models.Model): - nom=models.CharField(max_length=100) +class Lycee(models.Model): + uai = models.CharField(max_length=10) + libelle = models.CharField(max_length=100) + vacances = models.CharField(max_length=1) + +class Classe(models.Model): + lycee = models.ForeignKey(Lycee, on_delete=models.CASCADE) + libelle = models.CharField(max_length=20) + annee = models.IntegerField() + jour_zero = models.DateField() + +class Periode(models.Model): + classe = models.ForeignKey(Classe, on_delete=models.CASCADE) + libelle = models.CharField(max_length=100) + debut = models.DateField() + fin = models.DateField() + +class Matiere(models.Model): + libelle = models.CharField(max_length=100) + code = models.CharField(max_length=20) + +class Groupe(models.Model): + classe = models.ForeignKey(Classe, on_delete=models.CASCADE) + libelle = models.CharField(max_length=100) class Etudiant(models.Model): - prenom=models.CharField(max_length=100) - nom=models.CharField(max_length=100) - groupe=models.IntegerField() + classe = models.ForeignKey(Classe, on_delete=models.CASCADE) + prenom = models.CharField(max_length=100) + nom = models.CharField(max_length=100) + #lv1 = models.ForeignKey(Matiere, on_delete=models.CASCADE) + #lv2 = models.ForeignKey(Matiere, on_delete=models.CASCADE) + groupes = models.ManyToManyField(Groupe) -class Colle(models.Model): - colleur=models.ForeignKey(Colleur, on_delete=models.CASCADE) - groupe=models.IntegerField() - date=models.DateTimeField() +class Colleur(models.Model): + civilite = models.CharField(max_length=1) + nom = models.CharField(max_length=100) + +class Creneau(models.Model): + classe = models.ForeignKey(Classe, on_delete=models.CASCADE) + jour = models.IntegerField() + heure = models.TimeField() + duree = models.DurationField() + salle = models.CharField(max_length=20) + periode = models.ForeignKey(Periode, on_delete=models.CASCADE) + matiere = models.ForeignKey(Matiere, on_delete=models.CASCADE) + colleur = models.ForeignKey(Colleur, on_delete=models.CASCADE) + est_colle = models.BooleanField() + capacite = models.IntegerField() + +class Rotation(models.Model): + creneau = models.ForeignKey(Creneau, on_delete=models.CASCADE) + groupes = models.ManyToManyField(Groupe) + semaine = models.IntegerField() + +class Amendement(models.Model): + est_positif = models.BooleanField() + rotation = models.ForeignKey(Rotation, on_delete=models.CASCADE) + etudiant = models.ForeignKey(Etudiant, on_delete=models.CASCADE) + + +class Utilisateur(models.Model): + username = models.CharField(max_length=100) + password = models.CharField(max_length=300) + timestamp = models.DateTimeField(auto_now_add=True) + etudiant = models.ForeignKey(Etudiant, on_delete=models.DO_NOTHING, null=True) + colleur = models.ForeignKey(Colleur, on_delete=models.DO_NOTHING, null=True) diff --git a/colloscope/pdfexport.py b/colloscope/pdfexport.py index 29e87ec..b286c46 100644 --- a/colloscope/pdfexport.py +++ b/colloscope/pdfexport.py @@ -23,50 +23,51 @@ def jour_of_sem(n, cal): return jour etudiants = [ - ["Aboujaib", "Alexandre", 4, "A", "Angl.", "All."], - ["Ajan", "George", 4, "A", "Angl.", ""], - ["Akrad", "Lina", 1, "SI", "Angl.", ""], - ["Aubert", "Nicolas", 1, "SI", "Angl.", ""], - ["Badr", "Roman", 4, "A", "Angl.", ""], - ["Bazire", "Aurélien", 5, "A", "Angl.", ""], - ["Boit", "Arthur", 1, "SI", "Angl.", ""], - ["Boubker", "Youssef", 1, "SI", "Angl.", ""], - ["Boudjema", "Dylan", 1, "SI", "Angl.", ""], - ["Chiriac", "Mihnea", 1, "SI", "Angl.", ""], - ["Courier", "Marine", 1, "SI", "Angl.", ""], - ["Daguin", "Joseph", 1, "SI", "Angl.", ""], - ["De Weer", "Matthias", 1, "SI", "Angl.", ""], - ["Desbouis", "Katell", 1, "SI", "Angl.", ""], - ["Dupouy", "Jérémie", 1, "SI", "Angl.", ""], - ["Hariri--Gautier-Picard", "Grégoire", 1, "SI", "Angl.", ""], - ["Juricevic", "Matteo", 1, "SI", "Angl.", ""], - ["Knanoua", "Anas", 1, "SI", "Angl.", ""], - ["Lesenne", "Pierrick", 1, "SI", "Angl.", ""], - ["Lin", "Hao", 1, "SI", "Angl.", ""], - ["Masbatin", "Lucas", 1, "SI", "Angl.", ""], - ["Mayuran", "Mithushan", 1, "SI", "Angl.", ""], - ["Messahli", "Yassine", 1, "SI", "Angl.", ""], - ["Moguérou", "Valentin", 10, "B", "Angl.", "All."], - ["Mohellebi", "Mathéo", 10, "B", "Angl.", "All."], - ["Mouisset--Ferrara", "Maël", 10, "B", "Angl.", "All."], - ["Ottavi", "Corentin", 10, "B", "Angl.", "All."], - ["Ponce", "Alexian", 10, "B", "Angl.", "All."], - ["Pujol", "Raphaël", 10, "B", "Angl.", "All."], - ["Pustetto", "Mathis", 10, "B", "Angl.", "All."], - ["Radice", "Roman", 10, "B", "Angl.", "All."], - ["Rat", "Evelyn", 10, "B", "Angl.", "All."], - ["Rousse", "Louis", 10, "B", "Angl.", "All."], - ["Roux", "Gaëtan", 10, "B", "Angl.", "All."], - ["Rouyre--Cros", "Célian", 10, "B", "Angl.", "All."], - ["Sourbé", "François-Gabriel", 10, "B", "Angl.", "All."], - ["Stourbe", "Simon", 10, "B", "Angl.", "All."], - ["Thai", "Dany", 10, "B", "Angl.", "All."], - ["Théodore", "Jonathan", 10, "B", "Angl.", "All."], - ["Vandroux", "Benoît", 10, "B", "Angl.", "All."], - ["Veyssière", "Thibaud", 10, "B", "Angl.", "All."], - ["Vié", "Adrien", 10, "B", "Angl.", "All."], - ["Ye", "Luan", 10, "B", "Angl.", "All."], - ["Zarka", "Amélie", 10, "B", "Angl.", "All."], + ['Aboujaib', 'Alexandre', 4, 'A', '', ''], + ['Ajan', 'George', 4, 'A', '', ''], + ['Akrad', 'Lina', 1, 'SI', '', ''], + ['Aubert', 'Nicolas', 1, 'SI', '', ''], + ['Badr', 'Roman', 4, 'A', '', ''], + ['Bazire', 'Aurélien', 5, 'A', '', ''], + ['Boit', 'Arthur', 5, 'A', '', ''], + ['Boubker', 'Youssef', 5, 'A', '', ''], + ['Boudjema', 'Dylan', 1, 'SI', '', ''], + ['Chiriac', 'Mihnea', 6, 'A', '', ''], + ['Courier', 'Marine', 6, 'A', '', ''], + ['Daguin', 'Joseph', 6, 'A', '', ''], + ['Dauguen', 'Gabriel', 7, 'A', '', ''], + ['De Weer', 'Matthias', 7, 'A', '', ''], + ['Desbouis', 'Katell', 2, 'SI', '', ''], + ['Dupouy', 'Jérémie', 7, 'A', '', ''], + ['Hariri--Gautier-Picard', 'Grégoire', 8, 'A', '', ''], + ['Juricevic', 'Matteo', 8, 'A', '', ''], + ['Knanoua', 'Anas', 8, 'A', '', ''], + ['Lesenne', 'Pierrick', 9, 'A', '', ''], + ['Lin', 'Hao', 2, 'SI', '', ''], + ['Masbatin', 'Lucas', 2, 'SI', '', ''], + ['Mayuran', 'Mithushan', 9, 'A', '', ''], + ['Messahli', 'Yassine', 9, 'A', '', ''], + ['Moguérou', 'Valentin', 10, 'B', '', ''], + ['Mohellebi', 'Mathéo', 10, 'B', '', ''], + ['Mouisset--Ferrara', 'Maël', 10, 'B', '', ''], + ['Ottavi', 'Corentin', 11, 'B', '', ''], + ['Ponce', 'Alexian', 11, 'B', '', ''], + ['Pujol', 'Raphaël', 11, 'B', '', ''], + ['Pustetto', 'Mathis', 12, 'B', '', ''], + ['Radice', 'Roman', 12, 'B', '', ''], + ['Rat', 'Evelyn', 12, 'B', '', ''], + ['Rousse', 'Louis', 3, 'SI', '', ''], + ['Roux', 'Gaëtan', 3, 'SI', '', ''], + ['Rouyre--Cros', 'Célian', 3, 'SI', '', ''], + ['Sourbé', 'François-Gabriel', 13, 'B', '', ''], + ['Stourbe', 'Simon', 13, 'B', '', ''], + ['Thai', 'Dany', 13, 'B', '', ''], + ['Théodore', 'Jonathan', 14, 'B', '', ''], + ['Vandroux', 'Benoît', 14, 'B', '', ''], + ['Veyssière', 'Thibaud', 14, 'B', '', ''], + ['Vié', 'Adrien', 15, 'B', '', ''], + ['Ye', 'Luan', 15, 'B', '', ''], + ['Zarka', 'Amélie', 15, 'B', '', ''], ] creneaux = [ @@ -98,7 +99,7 @@ class PDF(FPDF): def liste_eleves(self, etudiants): with self.table( align="RIGHT", - col_widths=(50, 35, 12, 12, 12, 12), + col_widths=(4, 3, 1, 1, 1, 1), width=80, line_height=3) as table: header = table.row() @@ -120,7 +121,7 @@ class PDF(FPDF): align="LEFT", width=190, line_height=3, - col_widths=(25, 12, 10, 25, 12, *(10,)*len(semaines)), + col_widths=(2, 1, 1, 3, 1, *(1,)*len(semaines)), num_heading_rows=2) as table: header = table.row() @@ -152,7 +153,22 @@ class PDF(FPDF): else: row.cell() - + def table_travaux(self): + with self.table( + align="LEFT", + width=190, + line_height=3, + col_widths=(2, 1, 1, 4, *(1,)*len(semaines)), + first_row_as_headings=False) as table: + + row = table.row() + row.cell("TP Physique") + row.cell("lundi") + row.cell("8:30") + row.cell() + + for _ in range(len(semaines)): + row.cell("9 à 15", align="CENTER") def generate(): pdf = PDF(orientation="landscape", format="a4") @@ -163,18 +179,14 @@ def generate(): pdf.set_author("projet colloscope") pdf.add_page() - pdf.cell(text="Colloscope MP2I Semestre 5/2", center=True, border=1, h=5) - base_y = pdf.t_margin + 10 - pdf.set_y(base_y) - pdf.liste_eleves(etudiants) - pdf.set_y(base_y) - pdf.table_colloscope(creneaux, semaines, rotations) + pdf.y += 3 + pdf.table_travaux() pdf.output("test.pdf") diff --git a/test.pdf b/test.pdf index f3b2b2a638a2de24147f786af6b1b85ffc75ddef..c05d5db9d32eff008d3c4d1074e23e1cd7e9fd8c 100644 GIT binary patch delta 4606 zcmai2X*`r|-;TMBZU$|(2xZGM7-42CgGw5a3YBFTyX<7iST2)xN|{jE5|UkGjD0s* zE4Lc^ng}ySnHlTgQSbA9d7tO^d#^9YbsX3AKacY~{^$AS{H!#sTyDe#oYH~wp-_A` zLxSC%{rGOBC#UxW%c6r#*0zPOo5go`ues{D$~>IQF}@Ave(oLiLfQQAA@p;j;M|=v zY$q?cm5#?I*yP067tplO{vz_*!G=sk&?!w>d_q(R)9RJ=$9Y3Q*FFKYoBnuF&cZal zDM2AV>(SebuW;7X(0<_@fNb%|gQcWGC>CED$hrT_>WD?^*M)b5BXT9@;sbI3-AR;T zz+|I;Q<-Vi+6H^xd7Bs$8NS=NnZC>P`W4U+MAe<~uok|NM9$H%?8bdnu&J$L^CsQr z{kC(Zvh?ztT*Q^+t#jd{qO6(wj)Rya(V^^5No3uDZ2uKGzgEFDpia8%D&cJ>F5D|A zADtoX(|^RIf7Y4MGrrdDb=e(F$Q*d1OeoxMud0>+W>|?1-w=4E+*MfK!h)UB4T+G> zBIt%tQMa7$J1oZrbywsbnz=LG)guR8jhU$!Uh#;EzW4TpXu$FBJYNo8*Du@kVQ>0X zofArkTRVU{DTs=A4#bIkupMlD2j1p|Lb6Nma`BVOnovRoZCw3q4asRwMP&bHzFD_( zo3>Qob_2&FN|dk`9H-x~dd7K= z$lYL!11}TRU5Xt8u=3j>%-ToUxEikH@3s(|L2m1QlmpOV9SXZ7fT}ucGXSCzi?%+O zT0!;Jt_3<}TFk}oR}q`P4vMS$IJm@Igr49R)E#aK)vFFP5pGCmCtE_w9p`9gIA7`8* z>3^;6qffo=K2V&hxCXISq%$dnK&2R^w4boGO>|?fp7$6ptYa}mXL@Es>*?GeemXX= zBHA7R9<|_plji0{yTA0jkk>H@Sl;*huMWr#71M;8_tCEQU}!BD&+TeXKiiw0Z7@)c zX=pO^TR+-jFXr2I`#rU?Ifay7q6Q|*i41pd;{65;O*MvU<%1sjN{`vlH}Ngw_F{ou z-%_btn;S2)$0fwPx?*!|Dq~Yf+;%n)FSKfoF#Cbd$F0gV{6I-OjNG#|ymA3DAR&hB znwsliboAW&NSbJoxgeNOT*^bt1!mnsVNd1XpT9Z)8h)d)#gl%K97y{{9IkVE{DZMN z^(DXOSMYSHdlsYYa|d(13nI3d3u@~bPjsr1Sj|1C8uAryk}%ST`-)G=)@hdtl}Wjz zf;&5YHS7U@l^vsg>v5euB1_+~qsnEih~L58 zAh=|7N9hhl+d_94m7#CWV0`n`n!*MhlVreYHpmJW6t+iu(dINmKuBMxe1@pgf!U$O7c(CnK+ITIkKCbb}|iQ0!^a^>fOL2MhFC zyU#ABbZ6|IUJK&{>Np0LPP9&$iF`>ci#qWW7pJ-)Zj0e}L-%woy2xB`c~)F(N^}pB zEA}sNI5Di=gWOVpNJ7f-ZFAcTGfNK*-f#(l)FL#hYej&mq?9%)WnXIh2?yK6z<8ol zzj)xdcMWq=Z1SR%)Q4+dXfH~uH0F~isnk&k;Q2m5uzfJrHxybf5A`gH$3q{Qkcm>m zb2ht@tyr2!uY7q1Mh(dNoC32Ca4wgR@1Qa_+0kvcX;4VD+p|0v1_KE}M~SpiEBB?6 zPB>tII%_Cy8g2&1>R|PW$&=!F!XvnR~7^jg@OD; z_fFC5VlC|sHkR_P;~itO$lI-bx3lEkxqhY&3JDP?`Id&3bIf1q<5H38J_kB|*oo^k ze|44|7yBNyKLjS&BI9x9wNKD~a0%kCS}EXuEUW)OuIWk^W0bWr>;j8%n_dHh!!;3; zjP{xidog;~X>8deyum|cqzykEtx|D~-HhtHxf+qm<~PfTW~9*ac2_oI!osD>9E{3x zgjm~&Z*}NlJdzcw&_z*+Io zdE6D*V4TTfQr8qwld*BenUaVI4CFhyx07ZkV`=xSzLa+b?yBbcr{f@K%SgSvjAjs;5xrC@zf;A_ z{6*2u3arN)qcjf0$p3`{=>rSMTNua`y0@8Tw{I`hJ*%I1$9+!P+g4)y^>t5W*4I1K zUX$MmEp|B#er|%%Cz@MPVuAEpvG+nQ_b`JeR*h9$2H6iXSlp{bT53HwZ0#Vdv?8yr zE}<(D6sIq4UL_s%=GUIne>LI;vQ~wHAwTo#9^~%daS~r`7;C<`(nB?z*wCL5fH2%- z0#Nn+^N;Im|asOGi0OU8SjT;fh%feGPa~57+1LMTmP~)2dN<|H|~R~s*iRE9WwIADsBLjMRwJT z+Ej_J=uZVSm)93v&S3_*L;D|n4K=tV#7f5vRBq24i^shpK`-q_hrwK%uJH25bFe`b z(V-WVb!Ou3ngHckmH@0@x*ZmMCZ5Gxa(1#$HoBjmbn>n`L9rC&c284nLBCo;+s4 z#VVVTICe>53~jJOo++cm;_(>}L>LA#gzhb;*)>Z^*4)7if`C;cb!=Hr48;dq<|A3D zuDaytdr9#ZE6#Go(O*Lm=~)_&M?Mt4iQ(@>t7z_ZQNNGBx2VvGezdnpM~P#3dPggB z_Yk1Xg9GU;bf|A%z`||?U}F_Qf{vn~TZc~ltQBeIHC4k8viG6-c&Bcz4e~i9l-A}# z$8Y?z%LkbSI8-+ASD9HA8pR<;GQ&3)=ENf-8~g~x5)+LKPOdY2VKKL~RRL~~t4s** z)EqpaS7MT~?DSdy=TKr;ocJu+Z@0}Y>hC7z&CX{EYCQ(F-u=r`@5!hOj@6O7EYjzs zRR5h1;L|Y_Th9V;_^lBOEoob zkwZX!UU?Yf6 zj$xj~ON9;Rzq(!hrcj@jN#B-d1Z%5DM|ZkSB`WEF)Y>=3*v^crK~x$T?p^N0Z#bYv zbMpS%VW*Z+#k)y12Gt8$9n(y$D}_Lbb3zM&Jk9p1LpMBu_|SLZcyA$ccMV{1u3~n0 z-TONK)HVSJ*$y{kw>*LWFwrxgMr3sdr-NseKRKESD;&$?yLs1vV&zcK`m(@!`c6{O zEvb_>56Vur<$qc}o0HE7lue^5e3GEM<;*>1snf=gOLJ!fWe4uAVtgH@#Evyz+%v9$$fV;Zw7kM}J_C zJumtrJ}*Kgm&Yf*>c$?HaaC(?h$Z=g)y#B4c{@F-1+Gvk9_k?rh9QRMHFeXV`Crs8 zE3jQ-&B0PkEohGU(cr8uqfFD6)}*KClEqU6Hqi>n%5K1wqD^yen=Eu5-^;IsD1w== z<^tSUQxi$g4%uam+Gll~d{Q2tB-PO}u7xYv#NXi{Lce&uS6t!`C6tIw8rH~3oG{+}@U9jsV7E@GJ zY&wY(gMhZG&wF(R%z#V(tg_sAfLWem#wv;E;WRX2_E@jxLD02XvG9J+k^|vG$>xcX zKb4aHiHfpZKH$<%J=2^^ptxS8gl9jJtWdoM>oF517F!=L2^MC)vp$|^CcJX;8Z5|6 z_)vadYDWN`?OAt>Mh)-t1A8ZR+ z0Ys0Dq-P%AOtH0d`mFMwuUEa+gI3cD7iP>OiAv#q2@x zt-buxCgNM}IfiKQ2SUBSb(+|d3kAh$u{n+3gn0Om(Y4>*S6i3aa;MF>q3qjhtP;6z znyPWGD8$1;gN3c~t&fMA318V;|8Mxs{w?weWa&2XW@Xm4K{@Lm57Vdf_m0A6=`wxa zLdiA}I_CQRQMs1<- zf|Em^fXsL;zK**Jd{&<;B#t}}xV=6)g?w|A<@8SLrSrc0Xa1K&wvgyk>xSw3H~A`h z4n}hEBek_pA?-AfirU(Q%ZKv~;V`6(#_vbQUxx3`i-r~grt=>f5{CG{nzjZ^n*cwe zhe05br?s_CpFzNpa7_e43vObfh1Ae7F)@anK8-k|gVO(h|G@mu&5m<$$gN;^4?b;} OmL{LPyou#GzJCE=R{=8s delta 4459 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%0D!R`7WmudSf5{6YQf%SVeea! z&(iRZZGK&Nlq}wGe24Nzi=ON3{>(~)E{)~$wHuQx+bf$e*`vvoQWR{GAS;~aJ&iQj zo}MF|o<`3ji`RT7E`7V=ug(cjGb#){eo;JJx3T?K>2Lv+al2=6oL7t5Ge=zkC`i2R zNIN+`7n&)NDlWZ&k>PlHiQS#-9661o0p^6VG@h%N9Sz5gxMoe9UfH&`d~)7bjJvY_ z$pxziAqg_opr{G^6$nqQX&Eq=+cDTC&OGtlzExk5Zpy8p`6XwyDt4nnRr5Rh&IeH~HiML>xiTzy2q>Rb6 zB7(D-L_q5bUOpGX6CiCVmK!y(dJhAUPn227sB5zWTJ=dd;#(7NQ9X7Mh74XCVwAqG z2T=(@ZTAy3(s{MP$EJw^7ti8uEuXONaatJ|+F@o%{+(~TqfGBO5!$-SQKt*f)Y(yb2%fYXVj zeQ(3D^S#%ly`JOo_k;~fK2RKG4Re=ILe_;Mmo7=CmYazSCuR36X-RXIo4F|rcm25s z&%Ip+e8zp^ZWWdRI!bI$p4t99>qYXme;HnL2WOtBLXIvNFOIx*(uSRPElo_d5LlLzdf8!j%uyILMuCT{^@;g)w^!s)qX@RS)8g@ES_#J7L0(=btOjcoH}S5yb0Y)iJ?;wpMHUoD*%Nspn(x{>>XBO4Hn?k*tJ$%x z)N6h6pRfs-k4t*lpWm%K+EMKQD4B{kv!yW*S&M@&d?u5C9CukAVp!SFfOeO{Jk&?q zaRr`bKrXPQGdfYmM8z?f3yl0fm=3?om^A9TnihNNpiSGtaU28daiGn0#)|g-DpaVB z(7q>BIM&wQ+>c7Wg_Dj};7VGY(Sl%)juPZe^bN@fMhjX>~Gi~+9r1l-`?zb(LxEoIZbn- z_3lq!F)7x#n5z?1M)UZ2(QZ3IX5}sh^4ri$GIxP4fAhpSdS$fBfUV0_>DrNUC543U z`=@!4Qa+{P974rZN6)!MJAF-GYV1>f+`uy?|Hu1xEuXXGE`P7L&uDxW@9%XpQ|=^> ziraVf59g{(r|_+LJCb*2CEX{c#t_H%37E2(NgZ$S*MD?=d4 zN}3Q&Wkmx;b?8kfL=|#VU0DsHr}O_lVgEnBQJe#U!U7QPKow0*HK2q9)a(}U-;A@Y A`2YX_