alerts by host bar chart pdf (#25)
taylor_socfortress committed
Jul 14, 2023 at 13:20 UTC
ecb61935a32057d704c4be7cd0ec17c6bb372aaa
5 files changed
+91
-30
backend/alerts_by_host.png
Binary files /dev/null and b/backend/alerts_by_host.png differ
backend/app/services/smtp/create_report.py
+56
-7
@@ -1,19 +1,68 @@
1
+import matplotlib
2
from loguru import logger
3
from reportlab.lib.pagesizes import letter
4
from reportlab.pdfgen import canvas
5
6
+matplotlib.use(
7
+ "Agg",
8
+) # set the backend to Agg which is a non-interactive backend suitable for
9
+# scripts and web servers. This should resolve the main thread is not in main
10
+# loop issue as it bypasses the need for tkinter.
11
+import matplotlib.pyplot as plt
12
+
13
from app.services.WazuhIndexer.alerts import AlertsService
14
15
8
-def create_pdf():
9
- service = AlertsService()
10
- alerts = service.collect_alerts()
11
- alerts_by_host_percentage = service.get_alerts_by_host_percentage(alerts["alerts_summary"])
12
- logger.info(alerts_by_host_percentage)
13
- alerts_by_host_per_index = service.get_alerts_by_host_percentage_by_index_name(alerts["alerts_summary"])
14
- logger.info(alerts_by_host_per_index)
16
+def create_bar_chart(alerts_by_host: dict) -> None:
17
+ """
18
+ Creates a horizontal bar chart with hostnames on the y-axis and the number of alerts on the x-axis.
19
+
20
+ Args:
21
+ alerts_by_host (dict): A dictionary containing hostnames and the corresponding number of alerts.
22
+
23
+ Returns:
24
+ None
25
+ """
26
+ hostnames = [alert["hostname"] for alert in alerts_by_host["alerts_by_host"]]
27
+ num_alerts = [alert["number_of_alerts"] for alert in alerts_by_host["alerts_by_host"]]
28
+
29
+ plt.figure(figsize=(10, 6)) # Set the figure size
30
+ plt.barh(hostnames, num_alerts, color="blue") # Create a horizontal bar chart
31
+ plt.xlabel("Number of Alerts") # Label x-axis
32
+ plt.ylabel("Hostnames") # Label y-axis
33
+ plt.title("Number of Alerts by Host") # Title of the chart
34
+ plt.tight_layout()
35
+ plt.savefig("alerts_by_host.png") # Save the figure as a .png file
36
+
37
+
38
+def create_pdf() -> None:
39
+ """
40
+ Creates a PDF file with a title and an image of the bar chart.
41
+
42
+ Returns:
43
+ None
44
+ """
45
c = canvas.Canvas("report.pdf", pagesize=letter)
46
width, height = letter
47
c.setFont("Helvetica", 24)
48
c.drawString(30, height - 50, "Test")
49
+ c.drawImage("alerts_by_host.png", 50, height / 2, width=400, height=300) # Draw the image in the canvas
50
c.save()
51
+
52
+
53
+def create_alerts_by_host_pdf() -> None:
54
+ """
55
+ Creates a PDF report of alerts per host.
56
+
57
+ This function fetches the alerts per host from the AlertsService, generates a bar chart image using the fetched data,
58
+ and finally creates a PDF file with the generated image.
59
+
60
+ Returns:
61
+ None
62
+ """
63
+ service = AlertsService()
64
+ alerts_by_host = service.collect_alerts_by_host()
65
+ logger.info(alerts_by_host)
66
+
67
+ create_bar_chart(alerts_by_host)
68
+ create_pdf()
backend/app/services/smtp/send_report.py
+2
-2
@@ -4,7 +4,7 @@ from email.mime.base import MIMEBase
4
from email.mime.multipart import MIMEMultipart
5
from email.mime.text import MIMEText
6
7
-from app.services.smtp.create_report import create_pdf
7
+from app.services.smtp.create_report import create_alerts_by_host_pdf
8
from app.services.smtp.universal import EmailTemplate
9
from app.services.smtp.universal import UniversalEmailCredentials
10
@@ -30,7 +30,7 @@ def attach_pdf(msg: MIMEMultipart, filename: str) -> MIMEMultipart:
30
31
def send_email_with_pdf():
32
# Generate the PDF report
33
- create_pdf()
33
+ create_alerts_by_host_pdf()
34
35
# Get email credentials
36
try:
backend/report.pdf
+32
-21
@@ -12,57 +12,68 @@ endobj
12
endobj
13
3 0 obj
14
<<
15
-/Contents 7 0 R /MediaBox [ 0 0 612 792 ] /Parent 6 0 R /Resources <<
16
-/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
15
+/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /FlateDecode ] /Height 600 /Length 23690 /Subtype /Image
16
+ /Type /XObject /Width 1000
17
+>>
18
+stream
19
+Gb"-V#BU[Arl4J&85BMJ,d]f\67>H)P6`R*OWng3\=cn+iR1*q#-Up)@_!*DdM.6?.Rcckp]Kdr5t+&78k23u":.Pb)Ho\bs6jJ.F4O':2e;Ygh!aDga"oe54#8sD2:&A1)lj\Rzzzzzzzzzzzzzzzz!!"!V`JPBGMe2ncq&5=Qq!mBos81^B\Dn&ZP4@SQ(Lmh9HM!#NMCRlN\ljlHM/q[T:7]gUzE2FL/Ak;mlp%A:^pYTiN2f%"2SpTmFcq[l?[m0i`dm68cs7suj55X]Qh7IkI[bBE@BBA3qd3^4ggF^#0hO]srZtRj]i]Xb]H[C<.mK3\(a=cNfh;ZH+XB?c<.qeDg[fZU1i6I;</d;e*BKQ5IhqQ>@0E96PceNKIC"&sTq>"$h:uR[@?Em^Vlb,G80MjZ*]]\-@]j8&hgQAVoicY;%!8O!igD_t_i9T]UjN%pSrb^0>04):nN+[E\Gf7YChf-!#9q-=keEOpg?`[G=WnjCYp\*Ctgrl$;>NtMT!!'NC7W8=tb:gQA]ESf`ABqY9E^kPB2/Ss6F/1i8dmf,JZY.T?cTDj\*#o_0p?J]^8io1XkYV0Mm7Wcu?+t^^0k84jcS^%GgpqJrN#3^r!WiH&p:%fYb-p&3^OCUseu`M!rr2mpSq$Rt(NY_D]3W$l4oP$%+X&"Ld8Agp91qqDgpqK>BW,b+JHm7khuE[gqiYe2G&l$[e"tpEak<n,K<2Lnbo5?5G.g$d-YNAPnTWl=[p/s!.p&l\^OBh@S2$AQRZB]4psQ!3n%\mO=[CWG3sMIq?at%u+X'-Pp@7YZ%hF0^d76-6hH]!D)(/kembM0[FHJA,`uTB:nA5Q7Y$<]Iar.6]YFaQKC=K30W`?)$[s!tK]s(FMpu$c8jQ4Q/q4YmQS3;5-H(;;kn,NFg`F+q_?[r$^=0GqZIX^E`m`"DWd\!@,:S'[O$E?3.2f;mFRPg^ercsq'i.DQ_S5lUj)=&6T]l)Z;dOf%<iPUGoY,,,:mm;robEkkAD:GN3fWeq_ilZ$,:s--3m\D%Mkg2UR5&&H@r3,G]n`+XY+GKNS='h"pe?<6:e'iBs_M-RRo(gsOT?.jP[VYbBT#+7J47Bfq'GP't<OHSl"q2>V]@=!mpZ^-sY'p0?mJGf@rcd#!@=`u\Z*CRcY$EiLb*pk]=-poW032,81EcR[!oKeF'B9q\Y$EQYFm[m_?Ko6(orjE@rqP;nhj)BQcThHB^gf/qJt,22kJIfpm+/;.4RCq<]<V"'O$8_^4*U*LfAF)XUWiQ+dn^A,Rf'[2eZ*cWcaIZC@b]Xq32P3=)iA0;C%YE&:4<0@pNuZ&/_:RiJ,As,1+J4nru/)JGlN6r!!'gZRCun[XOL"?CKZSGg\^[0B0=D`cE:E_ZA43joNl%Qfs>>irVauf6B'bB&J9$A_?FGpQX>1jF/88-o55e0NfJ#5]!Y3K9;OXMX]e_>[dELY%2SKF"qMb+l`=F+g3B!IOWdr=o?KF=EcTCa^YsSrdYc:ri(&eI)&=!RQ'Go5[I*@e,MAa[%^TU.d\XBnA5.=t1MsUns#ui+A]ifPh)j3R-_Ytcp?!@*XH5HjP@aUG\T;d?,aT&(;YeGWmL&:(o&I.m_X-YYT2N4S.dY/)mZRYO!4[/`DjT^<rpua[p5U1WC+WJ)hmd[$\b(_+T!5j(\j:rQ9q!mnVN'Fr@`/OnWDrMI'e;mXQYGJshH@0sftR48Vb\CA?XKQP)S7f_]e<3A)E$O6ib[e:*^/6N/a+/IFt(54Nd3.24ONkrp!:<W>-V&pP:'/[*ck.SO;t^6JukC?%f-%9>ull?M6[#P6",_9Y\_uJF3a40]4I#89]P)1:H]F1)/3@QaH]`PT>Qp9[l!Rrrp97&5I^%I7A!J'+`[d'a+0$'%KHKJlYLp[m9B"tkj?EO+#fNYMj$d6g\#-1Fm@I2VN'FrIJS'?'r9C3XBAIKk09AsfR(BQ*TP0-m-]Y<,:26[BuI6#nRC84IDao*AB5>He]GqTqlZ,pC\oHnD/XpjZ,[26@.X>9=n@bG*jOHgrn]92?-\q;Ve9g^XLq7&M%k,X`_"gtJ%n#,g9k_e`93_=c?T-O\)3WU2o_?eG45.Z\s`HMMa!tXU*:d*jC.`HeHZL"@/G3PH92*,^oas1m@n7>T#P"&[RKWB_1QpE4Zb_eIrDfEG?sL4PZ$6Vfl"%XhEGSt*2>.cOH4Cnps"2Oat<>\gt^]-Pq2%di;ir[)&X=SCG^Bbldi2]Pq/4$J@BCMAuoBf0%Fhm"b*)&SGYsB-?\P!61uThM^;#^'R5<,H[AdoQ>LP!hIH$/\$&JLldi1)KaKT5Yh+6f^"o.O`BJA+cBTOuqj$uP7ZB1ce(Xm'!,e?5Dbj)%p%%ZG84]s:Ep(c@\,?&_MPd5Hh0Numlol<I'9lFn:+bh"Dl1#,^T$7aGM]n+qdbX1I.PTAkM%[SH>.hge[Dpt(bhU^WD_mAC@`s[[g*'?(%FGK-Vg1fLkp<F_$:?QHGfVj`/?:_(`F<=k0+^rO\?S",O<VIp)BT$;eBX=]N@0;`qS5H))I$(%KHKJMsPc%p%hn\2/CdM/TP9.@3%FQ1`sI(dS%(+g[fnIFi&e<f"<Y8XB)H,FEFnccF2]machGG/jJA`PfB&s=S(AV^?_r6DZ4^V]mKL>j#=_Rd3M64VG/$$24D4,jiWj3=!H5.2o*[&&mA[]042G@LCP?KLY:A6kK]X)>p2*a2C9cJ^`tDsF/e:`r7:2+'^3uAMu9ocmuoT`9Q)T\PlC3n+1BK911Z3=Vl0(VSMFc64E9]<X[O30!!!"VQG9otgUF@cWDYM#[`An"5$[5@S!=KWo[?UnJ,fJVhV4%YJK-n']^\.HeZ2cdFQnt!K$9(1N0GniRl4"?fsGJBG4!uu[_)Hr0.e_RVT`hZ]dC@)d%GrFLPP]%L"7Gpqph`K6UF,2GiFSXMr]K/bKK4iM%eHfhZN]0F3hrd++*?/g"hE*I[H4Y:oR>=o5@8:f\>/hD(B75m+ARak0-uCI_Ctnj3F'4j2T3AIe(T.AV7:q^k9#m*lpp:-5k\CfsPTs]@H2rW?_"Mf</Dt\[('sD_LsOhKRk*noBnVP!8m?@l[2r^:nVq`ZjGmTZGPW5Q+Pf.Gk46!!#h(q0T_2YE@Q3p</dU950a<<k<Bel'!JjT"OaQ/er9BL_8akQ1ObEQVO$ASo21>eu`.<Fm;r7CftJ&;L2oPbEjk8Cj-%<r^`,-E4H+-Mi4q=,=+cjpAb$)s-':OI.Bl.7E55i`qNKqs*L_C[cNB9?B1O%C",M*%Q1tja')#P:J"-?lOd:WP4s0e1,C_A$lMsXIXQLQS3<:-4F(sUYKf*6aiVZq)J/lod*R=G#Nl%."Rj%uSuhYZgM[n:*J;et>q5?.:7XFG?An@FW`H6j]TDaJc^RSbHL%\hL^6dP:MuO#!!!#iRkS9&LPLZ@2%]fg!!(W5S"!WkDVaI"S*N6Lz"h8gIiYPsLdC4%$MoG8;='t2U)uos=!!P&o9b.O:)*)`5mUH7tzzz!-!'@3B;j*+$Oo:gj&l"!'$)T0WALChi@u!-DSN]!!!!nUl=R+K=F(cKq:#,FC0"h!!'MFj6]boA%MO[D@\L7AAF_Eq(((t!!$s>C)E0h?iU0,[%N.>#m1A3!'gp,(mH^^!!!#+TS>`=!sS`*5RV<DPV?JF!!'C!L-Z+J"onWg$YgNC0OOk\!48DR5m[Vt!!#7lC)E0h?iU0,[%N.>#m1A3!'gp,(mH^^!!!#+TS>`=!sS`*5RV<DPV?JF!!'C!L-Z+J"onWg$YgNC0OOk\!48DR5m[Vt!!#7lC)E0h?iU0,[%N.>#m1A3!'gp,(mH^^!!!#+TS>`=!sS`*5RV<DPSaKlL5a)\2$3gY!(Wfn6OCFH!!#7lH97A<gAq9S[%Olq$,%>Z!'gp<4-\+H!<<,,TXR8p]c@(Q5RVm"PgJ.c!!'C![mLJ8*<6()$[On!d+\R$!48E.6OCFH!!#7lH97A<gAq9S[%Olq$,%>Z!'gp<4-\+H!<<,,TXR8p]c@(Q5RVm"PgJ.c!!'C![mLJ8*<6()$[On!d+\R$!48E.6OCFH!!#7lH97A<gAq9S[%Olq$,%>Z!'gp<4-\+H!<<,,TXR8p]c@(Q5RVm"PgJ.c!!'C![mLJ8*<6()$[On!d+\R$!48E.6OCFH!!#7lH97A<gAq9S[%Olq$,%>Z!'gp<4-\+H!<<,,TXR8p]c@(Q5RVm"PgJ.c!!'C![mLJ8*<6()$[On!d+\R$!48E.6OCFH!!#7lQgO0=VG%:'$HgN61*1%<A9`BF2/Cde>[bU/'lrB7WMr`l;<,]X2eL4>bZqVpS[hoj6A"U2Ce^K`\Sg67V=QN[fPnrq-0?E)lk</W&Jc-/Mn4#pEr>]PgF%IAbr8@d2O22Op\0`*M4$).L@*F]o^oS/gWH8[nF2cOIbB)T7un^>qWXoQUSBt74QNGWT9>S/=MK<5@p6<QZ/P$7CT]!;`:@Q\`\%#!pYL8ZZ[Vc8VoKm/>[E>)lE7beHLf0*=05Y;/37b.JDClU:L/P8m/R+d>.ABe:J"-_XcZM].p&n?kN@'Naq\F3W)9<6,9s=9?/;rub;rP$c0Z4mgV<aalYjQ:G44;$HhQeD3HCq)\+agUr?h+h?G%]b[U[@<47[LWclk;*2CBlmGh**AI,O8R3F]p_?+Y:IgUD+FQnd$E?[Cr_@qg+0G+C[:*e!\.X]r9W0hY`:22t%&P$`ImKit`o2/(@0kh[@#*.7*6gIh`r+as7]4_DU!D`_V.o]^C%OHu2E/=JD0P!"-cfk6X)?[hM&_<p!d:REip^AI=S%nTOeO$EVW55j3CCIS8.kj8?M!*ZmKD\j-=<ZF8KZnX^ckg9,"ptE,kY?8'HQm:_*7un_BI(`gsZ&as,'QR\Y&\[!qBP?VM++GgTbEa`DAo=3(F6Ch?p&3j)+(Y5pTgM`Hs7NRFffi9%]UZn4ldoA4XtSkHB%`b2AVu`Abfic8p#UFUmd4T.PUZ)-o04ro\]T0XO[kApo^m5cg)"+Dd;GN1gg"@+kj<DI;=lb`dG"[%!46_,hVPYUf2f"W):PjqZ1I/)n)(n[W)9>NiT87LI=6NVcCAUnf@sk?WdDF*oo++9Dl1!VB4oPY1Ip0uY$JZ@H1/Y;.TPd!eZ6\fR?32%X^uh6\8cQ#NZL>uqfJh!5s[e+UOMU<f?=FOp@$lllYkI^`HM2!p3,+pA7T64b*C_jDf>P,JARmk8$3Z@]Y%k&So$SHNn/S^5!PgO=/f(D4?WPX#9Wm/X02k8:!UQMlOG"#9Q(.9!,t,'md2*EoMK"(?rg=ZKaS]mNh/@Ynr#080^aKp^3mI2G'\JG[@lA/CR-SYqU85)[GIjkn(=m4Fs0#Z9URZu>P.LYi8A!gih];7/mc1ME8X"7=204_A<C+V'_l:M>UDT,fOH\a[r5XF>!p@HjLM^Cc<G5:gXiT64)<EKX]r9;>e..G]683?;O,KSH@'uD?>'#@^NfM/G=+_bc!-%cB]\L@dKL!oR*V$6/osdY3]2*If_+R^DqqjBfW\d**ZbJcG<*<`GL4gn!<<+ib*@>N^4#n>fVHP[UV?Wn]4K9M,=d-0IAN:Ep=a;+h0#'h>5mA2'5tPR`gq>1R@0IWp@b,.rn2+iT7?jNZ+d:^HeGc?e*u>6_ns9LpY2fq\&uecV8l3)n(+VqIJ;PF*SBYAhJVZ5[;4<m<I=Dh=3W,dm+HI;Fjdkgeur5_VHd]"&+,B8,9oRI-'n^fh&FhVHhW::H78f@hJWW!!79#VHb64]\T1SGd`X;Yr;?04)fr#\YJ,D[EiGCRqXcN)'\M0:UR!Q??Dc!(IeiPGZghA3E$>7q>-qsO]W#e3@XRn9=db@G);ieMgj(*1&%8N1q3PlJP.FH/:?Tons7)/"'_Xq!Ea^0hg9tjf3G7^2Z2*jP.H6rm%mTur6A5c#D;W/-m/R+d>.Afqn(ta)bEa_i@UeKERqKt0eZ5%dGTS"Lo.KG4Hb2/=Knb;8andsl\^ZBVIb=FgWu\`EnF5p<8P-0ns.lRK%4^h]s1[=P;GWfB@4[j.F_Yl7Y^*:^iT>K6G'8&RRPi>#Q58<2jl#UBs*i]_`mG8;4P4gh&\VI&L$lYKhSQ^>TXP"'!,1?N]m]bLl2L\]?=$t#2mget261i`d^C5-/ZcE#2jsI:q%_K8LCYK@C=OfuYrd-qOD-0,hgb[>\_hPqeto7@IeMH-GMI1nD,HYe9/@YMEocZE]4H]$A&ma3*lqBa>&E$&D<]KFiSibXpHXV<H)+_imFkPebhI/SHi"b#]Wl;+ZF%!Gc'pZliue;_j#:$iU:8<A0H_KGb*4>uo0<$."64_NJ,8CWH)7f@\I+G)BADB.F6:\"^A)/]Str/-H!U!XMth9ol0SHN!1LEBD`?MmY#VNg3To>:K/0?:c'mdb_KrhU;CX15f%YQEl6Ycnq"RClDUG24=k^j!@Dg6S0CS;q*??.Pc.r6V7)N)5IFY,bPJFt!.Fh>5mCKG?iF@p3-C5Z[@:@UIc+gl$c1_I+AFIP9f3WgKI&hYai5(P<O`FEA!,^K![CsVXLu(=<l;ZHs\T?s)0DaX_+67\-l9d1RA=H@WnUt.D(lP3!f</C`$@d#6E*QZ'r;#plgpeq^3rf82(,"Iuh8FB\4nna3O6\ueRmM#u!!(AthQGIa$PujG=qr)"DYq0T>T(3q!!#7lHFmL9#7m-KhQL9No1R\@*5*?m!'gp<4-\+H!<<,,TXR8p]c@(Q5RVm"PgJ.c!!'C![mLJ8*<6()$[On!d+\R$!48E.6OCFH!!#7lH97A<gAq9S[%Olq$,%>Z!'gp<4-\+H!<<,,TXR8p]c@(Q5RVm"PgJ.c!!'C![mLJ8*<6()$[On!d+\R$!48E.6OCFH!!#7lH97A<gAq9S[%Olq$,%>Z!'gp<4-\+H!<<,,TXR8p]c@(Q5RVm"PgJ.c!!'C![mLJ8*<6()$[On!d+\R$!48E.6OCFH!!#7lH97A<gAq9S[%Olq$,%>Z!'gp<4-\+H!<<,,TXR8p]c@(Q5RVm"PgJ.c!!'C![mLJ8*<6()$[On!d+\R$!48E.6OCFH!!#7lH97?F?iU0,[%N.>#m1A3!'gp,(mH^^!!!#+TS>`=!sS`*5RV<DPV?JF!!'C!L-Z+J"onWg$YgNC0OOk\!48DR5m[Vt!!#7lC)E0h?iU0,[%N.>#m1A3!'gp,(mH^^!!!#+TS>`=!sS`*5RV<DPV?JF!!'C!L-Z+J"onWg$YgNC0OOk\!48DR5m[Vt!!#7lC)E0h?iU0,[%N.>#m1A3!'gp,(mH^^!!!#+TS>ah0jnP5==dKN;?6at\06/[PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<HdS]cSQ`REAIf<4n`.[U4r0JMDl:&H!!"V7m7!,cipH+rET4p37upufFQqq[\73Da3NHf=Sorhnjk$7tNt*0k'`7-OM2Cokf>$9ZoQGOB!!(AthHkl+4*SihftW$Od^-)^]2j#lccjTaM5.CIDng]&!!$t*J)T6JJ,]@,FmAbtq;$&2*A(I%\9ROQ:/9(RDnHYo&`Md1,9?Hhn%LSZ5(*.p5Q:26d*U-iJ:ROc^OQ4YoeU4(Yh1pSi..meH1L%.m^gTrgUfq7)P;KTWVLX=5o0FdDh!tK97OBuU-+YTRPejr+!7,:OANB%g#gPK>OsHSg9bQ-(`6AX>e+b.\t(m)Wj'CLk.Q<f)]L:H02n`Aj2R&h*^"-1@\n5%mSqc(R>27mlI)Me4@NRXqtBE:QVcVkls?bU/F9IdgZe)*!'lIWC2Z=_oVe+Cf=5h\Uoa":Z")4X8JrB`nh<$_Gg;g>.4H]5LCTUG]m&pO=]lM3)fO0#am.EWp[-]oDr/.7CY)n,I/1f)J!?/'ET>&Ka,X_DB.mN":nAl#g9YG<fWepZPq)IU:Ho`/PLZIX:S0g6/M0\3nGiIEs2c6`9qHUtgc9.VD\!0^)DYho8tNA%c\@41Nu0T\p[6jA[VT[2ZK8t75?uiLB4YXG_1)4AQW$g]PEV2CcCC;oSo4:KA[NnXHr;R"NoeC,be/,d>4(%OHhHYMgQ?,kmFns[c'gE&^ob_:IHdSpm^_L%j6?-=YS0ZJVmca.!%n2M]m]M7c18I4hNtBEWDZVlP5-di2Klld!S4moT9_*8qXj%$FrT,GFfY=5]4g!0ESnKYc)"^WFD9L<XYDE.%3@Xa>a57P)<pP_hKuI%n?'1VC=T>Lq=*n4_a_s*n?D#iAEM%".uSkuG5'++p=X(Ve8o\PNJGs7rVc\]/R)9.er$t5k3CKtkH?ZOQ/58S#64a!p/gYKg"G%1>-sALhRR^jC"&rM3HN2bV7(ePR^V`=p[c]qhm@+Hr#;p,m@g5I1M=uiQVNo%Tk`,X`jDi@q<+B>M[Jh<IJWRj+3IH+H[?"OOS+qk=d&fhNV.Ylm-3j%gTFgDg$-nZ7qGGAHFioWj'os0\%hk3bG@grZJC4iLWAJtP7-07[E.3BG7tJ"S_ahV!1`M]g=o&6DXK0mr%`$:W4I-;L51P&gU=5ghYs^.rTi$]qk?N;bXD^/p4S)%o3n+HD)uh)[-u>">M8BRg\b%;Q7Z=tIf&M%N>_s("g)"</h8HqI%p.\$LE(cs8MuWio9<J@GJ5RIqr*ADl:&H!!(XE([g[fm-O(pLkr<Ga6(-4-9aV"-DZV+#6u(*5+0G5J)$F"lg8K=XH>Mmr:,P&a0)n4*'(<:c'm(oDs":kju7,/E6t7Dq:CsCCY,_[q/G&pBl]ne_k4$@2*!I8lI78/ALmMae(Xm'J0ocrhS+I;H7>T'rq^DVHMWt8Id,nQZXh1@n`.Y_5G(#]DG!ODY[PGnc_Y5cB%EnXUIgXr^\mXq>$BX3"Uina?#.^:gSL=];^P;3/C-(8QYLnbM`"j[s8D]L4ZkjfEo?$#P8P5UepP10aH7_+iSg=hGM]iL@qocDd\TT`p?X4s]thPB^OQ:QiPXc=%N[aBCtZ,"A]l"$]@`5n7Rfki907:]e?s)D/mZ%&*?EtKH1RYXr`QZPLFW9#nDV9=D/K"5fn"^*nri,!=0Gp^m)7?,l0SHN5`<BlDbj,'DV_n3FCSZb?g6Vb-Vfno3B9+'^]&OI7"j'.]C1<8')VF<s'8fV5X7S.9[&5#)m&j]]=#`KJ[Fh3ilsF>XAGUB[!2+g+DlJ;ORh;6A&j[m&:]30>.&)S*]uD@2n-T?5(<G)'2L_fZ!p/$nPN.\UIL6+(R"eEb;DW0Q7[`@K$<\74Eg)DZd1fS()A6$PJchC\$,_&$eq+lFZBPE4F@Yb]c@(Q\=gTODhitlgZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-\+Hl0SHN5RVm"PgJ1Lm/R,O$[On!d+dgP!!#7lH97A<gZe)*!'gp<4-VF,!!!#+TS>`=!sS`*5RV<DPV?JF!!'C!L-Z+J"onWg$YgNC0OOk\!48DR5m[Vt!!#7lC)E0h?iU0,[%N.>#m1A3!'gp,(mH^^!!!#+TS>`=!sS`*5RV<DPV?JF!!'C!L-Z+J"onWg$YgNC0OOk\!48DR5m[Vt!!#7lC)E0h?iU0,[%N.>#m1A3!'gp,(mH^^!!!#+TS>`=!sS`*5RV<DPV?JF!!'C!L-^YN?t@>\/69@_!!'fSkj;25D[-7Bd":*a-1l?\!!"U@hqM^LM\[m::/5ud*`7OQm/R+d=u`FhGNmOeil$[/EV]1ekic\uDf79^Y6>:L3-;';"F<-0!.Yj1l0[TUQf#5gRnV%t4hH%5lBa,/RQPk9K*Dc)\l1Qi]c@(Q5RZcIG!A4+6\c/n7/--*LCG1L'C"cGJUr@^h'j=ph@9McTS7H5HZXB%]Qs*$?G%*r*km$tEga7NgU=D!b;saCE!1JK!!%NbcKX_[-;F(%nd5[0WE690:/6hnq;?l9RQ#0Qd%/#ckj8?M!*VALqdb0Sp"+m*(M72g(_?Z@^]49'b:en4.7tSn*<6()$YOo!A7fFc8kM]V<gFEm"UCa1!rr=7iLJbRl-cD7]m>sdPEqL]Es<*o3-t41L[Gk:5]6l-!78SC^&<X$?F^%7qcBt-*>fW,o_-7^(\9eO[j-2\!!%NbcKX_YOcet\XcnU7THL#=n(Y=TFQq3`h'j=ph@9McTS7H5]>)+q;:j(L^2;W5i8A!umM([HD[-7Bd)%fV]h+D7++3R/26XLXhnS';GCOu*eu]t(;`Fil*<6()$g70UeZ2bEA+/<i^Rq-*6:+#^Q7W1@"#k)NjNsI7&a8T^!!$1^m<]sS;cESckn>!T>J#(GB:aB\a,V1#hBO"kh@9McTS52:^E%e)oQC37!%j_ogJ=>!Z#f*Rm5CK=;j8hZ3rf82(=)13Rl5,pkFR#_4ZtrEa?taN'TPFs#64bN_E#<C?G1Y*4*FlDIf4g"#7fI,kYC(BoQC37!%j_igOk*0p?gVtcs=FIkj8?M!*V@[[s.&_@DRO!%c%;YKAI(<!2,$eHMa[?VqSRrqtfW^97-]]L-p.l8"d<n!!$]kSDO8<f3ajn;o[kDpg!+OLu&UA!2,$eH@&Uj<.')kn`.Y1\ed=,]c@(Q5RXK</i>LDeY0U*F3rYB!!'BF:2bXUfk3PGkTblN!mX)M#64bN_E#=.huE\"=BJ[d*^.N%)=tQOL[Gk:5]6l-!78SC^&?6.<39?STf[rQd+\R$!46]?DoZ2h]c@(Q5RVm"PgJ.c!!'BF>&QWQq!b(NPD0Mcp7`!dmh@(.h@9McTS7H5qi<u@(_@6TVbS6c0<YQh)MEcsPUTPniJ/LukY@[VmFnt>St9fR[^D[:E8eY=*dAee3&i<7kjH(O:.Ro0k0KDL6XI1V(?FO0>-uA@2TWG/?G1ZG*^)Dug17@s@`8[WFS>'(j5H+F8*#%UC!u(t\T>b76WdIC@uid]A&f)6]mTV6LJ^oG^:q=$EH)pUCbTIm5(.b8^k"@XeF<)$X&>e:TL"3@;`B*GoQC37!%j_igLF`'7u\Euc2/^Z['[3!N/[JtgJ=D'fqCKMK&41f9.cJH,q[i<,?H;MhVR_7pKgHab+:bCUlu<+0Yge41VI)F3HjcAJHH.C/R.rC^]1uHWD^'7bqbU=p@d"ce>cNL55t?;QS2]((Wl++\XPNrIcQV]Uk`SpAf=I84*RigO3dI_ds(35e[KI(\S+$Die5P5\T;D]:7],uqJ4d<o&\&iUSDC]2gia>FoVLB/Y)`_Q_ZJ;p=jL@Z#/7(W2M,"maTYFl9emEo^euPH7C?mad=M7^3T>4"g3>2^"o2:4T"KOV+[.=F68G3VRLL$^:cje$=18ec-"0a<jR-'?E1LtPgt_JEH-!gnaXV@:/4Q\8sMl,*hE?#^AROpWV>O5$U\h;!!(B_3PE+Rq=;YLaYH`*G3uKIqT>8YgB.N[*P,0>qrEr:@U`eWigXl#WE--)DJlUN9-k&Y&)Xp=BE%R^dG)-Jh't5Dc'r@Z?I$=ap05*$OWJE,c=#D]c^d-FQ!PO"hS!,7AnGY@.TOW7ZZ7YE^4#nVL\K1d+,,E&h=+FngAq9SZuAcYn'IcGZt\!"ih_uJWa<C8^]49$qsM)"7>hokh5R/,DVTKRKF'DrQ'EYT=3@jC?bCWgD;2L>8u&,TSpKZNl1S2^?8^<#hCeC%s/bG@Ic\]eRJH9_molo]EuuKrmbPM0*Jq&Bgn6?jq2lmljPeh#CX&-"$lKZo(MC42;l<AZ7RiCX3O6G%.PKcYFb^JLVRHX-!'$TlH@&h!RW7):eCs)WH`h8B\t(m)3dC.e6[.fl.4H]P?=(X2iZ^QM^0A'ak0hc/e;lfiW-@^e+X&$%lIELgl&mp-\!J^QHJb>0h:jSi^+;(tHga,`olAoc9:)<ETV$`5flf5_d?Z@gjJZ\9S6;UVNMB"))N/L1\'%QSk-SjOk1[4Y"hrX-`'fMHH92*,J5c":mDU=;=3b$LlT@<nrVc]dIill5rVNGJ:S0i,>-.U32K.G'1[!)VDnTK&c^[#EVb`r#^q`sN<gg#Ah;9hJ^IaV9`q0`/PIYYk6DI#0>-qs_jiWk*?7bQS!rr=7kKMd8*E$'J\d^%Re.K!lZHALe5BcDGSMmKJX#=P3'Y?5DF)utdK-sEaBJ!8'n(tai4P_FHAiZ2pp?U=+Wr'r(.ui*GHMaO3QU4&,(G8s+4H,2V)`Vf00qFMl'+kgbIP+WLmL:*nCt>\UnUC[Z#5>S/!!$]kSDLtmc^on5HH=QiLPLZ_e"JjG*,4"g5!F/YXq)O61aXOr0em[hO<IMtp[@"SA]pC24a[&&qkp6c=B3'?o&.?:hgb[>nNDu?B?rK%g6QfZma",tHpBrIEDsPVD`80'DV_nDB349ASa5V-4*0Q.jQ'i#r#m4,a,_=Ok5FKcGi/U*/N#EYfQGm#fgWZ!H92*,J/6Gpm>W&DDVDJ^OsNc0DV_nKL-p1M3:5G-Zhms"@`*p0E[E/-Qlpgh8sLl(m)t_Khkj,;eZ2aj/):'[?1RUYX&c?+NugGBDr,<5BiiTVPK1_a96L:!Vk<PSp-XTFH$OZQ?UQ+c:7N.=)(C=T(DjQ0rHd3-g,X-15gcd+h@9McTS7H5]@9L6CC,!mUUL=*!,1>]hB!=DA%q>hgD[aG!!#7lkOeK0bEk/&e7cgY'n?/Oa*AU6h'j=ph@9McTS7H5]18I-bi_m[)8.$j!'gqTo_+Q(E9L'U#kW9?!!"U@e(`@#duEfA1s*Yip\W_$)8.$j!'gqToQF#+cP%[$fZs<QO$C-Mk&s.2#64bN_J/bRT0.DIG0[pV#6P#/*4f'.!kfTS!'go^p\#EpG^=["pY9gC?MD;E00Ja>"-"6YG0j"C3:q@o!!"Sjh:nF^naQ%0QJVPN<ioQuldp(DhRsEQ.3+-"%KHL%Klc[Gl.NBjhq%eY5]6l-!78SC^"mReM\[nu]mI6;p4s>LD[-7Bd)%fV]h=\E'.6P>M9D5=7n6'rH[C*bGqE.&^nEiD,LG0G!!'BF:2_dm^APEVgLOdem+Kpi=2/kAdcAN6)`26dd%/#ckj8?M!*V@[\,6!s*BJ:5-G"Ei5&Ak*CYiE-$4I>bkYC(BoQC37!%j_igS:O=kKTK?n`%OWnF5P_Qckn9gU<A!>LoK0Kd4t!!<<,,E)(>D1hi,>QWH^K8H&DXF)l;3c3GG=d(FXFL[Gk:5]6l-!78Ssh^A$]YJ2\p\1f-P_g(sks8DDQ?[d"e:/U$7m/R+d=uc>)+ER-6B4#T\H92*,J/1oGmB^ELW`,gUDk=O_l[J]pViKUY*.crV!!&[GF*d`9Z"!k;!eq1*qGj+16\`\"ET>&!FJj'\H92*,J/6Gpm<@E4kH%gmD!0$43E'NNFJj'\H92*,J/6GpmCp<KqtBE`S[3P/?CC')S\c!&m/R+d=u`FhhfI+,8P)L^F5D6/XZCUi3-;';"F<-0!.Yj1l0Sio/1=Mu<9r,;hom;Y?=$qG(G9gn:>lKNFoVLB/Y)N_17L1=HKLW.m`Qgg>IJ?foH)rsoQC37!%f2HgWp\X5s'e\d+\R$!46]eDtibjn1:)^Fpc9`[fZU1B]813^@JiM.ouHBqp1isH_h/Vm1bRJD[-7Bd)'Mk[u6oPTX;'_-gV,!6Z320!76>S%OLaj!!!!Nkj;25D[-7Bd)*o<IK0<F:=p-uLY`L@!2,%@H[A7%?=$s?>.(Z,j.Ms[EL_<J#64`(PG;nqcQYA_Vf3W%3rf82(=Y#d@DDjC!,+Y-K+\@s!!%Nbe1`:Z^]4?7BL*)[&dAaE!.Yj70IUAF!!!"45n/GZ"q1J3J/6Wg-t0mk!!$[u%>,8t$ig9X(=Y#d@DDjC!,+Y-K+\@s!!%Nbe1`:Z^]4?7BL*)[&dAaE!.Yj70IUAF!!!"45n/GZ"q1J3J/6Wg-t0mk!!$[u%>,8t$ig9X(=Y#d@DDjC!,+Y-K+_\0aH3Z/XFq-OL`6QFL#*:coQEP,+`8>d(OA0-d+\jMKXc:-?0LZP6>n6)&E;gQFJ602$,)l@6AV*9d"U<d-1l@I#U+(,5Sn`.PgJ.k+b[@N!+"gU:dT(JKFm/*!Hb$E6OCGs&422B#LJ1]%OLaj63n`P*^CNf4-\+H#pFu3GlV.6m8-,f-\N&jjoKRt[mLJ8SIe,DRg7;oh@:k(G!ZHXDB;%ZH97A<gBf$V\9S'[kj;25D^U2LioU8`TsmAq]q#^$LmnXrL#*:coQEP,+`8>d(OA0-d+\jMKXc:-?0LZP6>n6)&E;gQFJ602$,)l@6AV*9d"U<d-1l@I#U+(,5Sn`.PgJ.k+b[@N!+"gU:dT(JKFm/*!Hb$E6OCGs&422B#LJ1]%OLaj63n`P*^CNf4-\+H#pFu3GlV.6m8-,f-\N&jjoKRt[mLJ8SIe,DRg7;oh@:k(G!ZHXDB;%ZH97A<gBf$V\9S'[kj;25D^U2LioU8`TsmAq]q#^$LmnXrL#26L<ifCH5ErKecg!]U!mo[.+b[@N!+"gU/uX$.?(S?8d@t+=1b'tir:oe@>`IT8#U..2"6`'if-N4/Z`lmjG!ZHX`+9&76>q(FB$Hd`a2]PQ,a9lb[X%K,EosiKh.eL(Q7`]EZ!6hmp=63F5P3;iIXZa2.p!cKB[F_V(\;QJ>.<TSR5SY0?G-'iHggY#orVE*lKbXgSs>Qe1NRVY',)%[<2nm;j&<3l7G4>R?ks\M]EEOB+bUCc&"j<Dh3k&[#6b8?))<H`ccu+UeC<!`^qfL#a7%irGKlR6d_gG*m$W@H-Vp=uVp(M_j4LVH1+dQrrqYa8i8C"ZB;VN%IK09?GM[VC<-O`pJ,Xh`^LYHLo^qbb)`CBZ2GIeT5(-Te$Jp1%c!u%c2Lb>aeaqB55(&aS:'`#]SHJ(BDg*Pmm8CTVklV/#ge;YTh7ImGIf7JBXBrToe'mp2Pq2YhDKh^HM\[o$If"!RiFed2<j?+&R2A#/ClK>jY$JYOp[fZtP=\GA[+M._'1)tEdf?u+gRUo^H_3KMN9Qhum4g=M5!D/]f*)9[aJ.bVjJ8RsF(T`E\i!i5%grd:oCFciO_ItWd\TTl%NVQIV+TjlQ/tOP/mN)F4C]tK\+>&1+bUD9#1/(\mS)'`'+tq:BdqeWk-o0[@QZJbFNNFpCXoFBB[EE#J!QLjH2@/Io:aRFm<ZAYolo;AfC"JU3B=D/o&\&%J,Qck[R,ZTN>aZ0hL"F,WItgLaNXk7L#25k[_5thZ^gi0^\u`.q#0sE(YIKSG4""X7>mYg\@8sAJcuP+LQ*63ma\@>d8)LbZ/<3>ZV3kZ7unNDk(\5V[hD(6EUs1Ad+b,5[^V0L%3%3>dNgh5H0*26EH,t%p@dn.\,6("a2c5=h7@athS"g`0:(i(2_N)Hq<+A7G3mkL1M>e-d\TUM]Y%R#rUo&sqb;5gB?m#K??o!%c^6HIj,ZF]\T;Ce>2$$\^+(*%j,ZE8I`n$/gUD,$qsV:l3d%HYQU#I:KFm/*!Hb$E4-NrgQTEs$;'Tf#%2q&Om/;+4ET9M;eNlJeJUrCFlIAO"8h+f??[r#sp$1)(X..uK.Fl+Oj2SD'i8A"R/hk"#B$m>A%m9?3b`T$LKu8s9rb/CGDV[A,\?E(hhZHFU+bUOA5Sn`.PgJ.k+b[@N!+"gU:dT(JKFm/*!Hb$E6OCGs&422B#LJ1]%OLaj63n`P*^CNf4-\+H#pFu3GlV.6m8-,f-\N&jjoKRt[mLJ8SIe,DRg7;oh@:k(G!ZHXDB;%ZH97A<gBf$V\9S'[kj;25D^U2LioU8`TsmAq]q#^$LmnXrL#*:coQEP,+`8>d(OA0-d+\jMKXc:-?0LZP6>n6)&E;gQFJ602$,)l@6AV*9d"U<d-1l@I#U+(,5Sn`.PgJ.k+b[@N!+"gU:dT(JKFm/*!Hb$E6OCGs&422B#LJ1]%OLaj63n`P*^CNf4-\+H#pFu3GlV.6m8-,f-\N&jjoKRt[mLJ8SIe,DRg7;oh@:k(G!ZHXDB;%ZH97A<gBf$V\9S'[kj;25D^U2LioU8`TsmAq]q#^$LmnXrL#*:coQEP,+`8>d(OA0-d+\jMKXc:-?0LZP6>n6)&E;gQFJ602$,)l@6AV*9d"U<d-1l@I#U+(,5Sn`.PV?JF!!'C!L-Z+J"onWg$YgNC0OOk\!48DR5m[Vt!!#7lC)E0h?iU0,[%N.>#m1A3!'gp,(mH^^!!!#+TS>`=!sS`*5RV<DPV?JF!!'C!L-Z+J"onWg$YgNC0OOk\!48DR5m[Vt!!#7lC)E0h?iU0,[%N.>#m1A3!'gp,(mH^^!!!#+TS>`=!sS`*5RV<DPV?JF!!'C!L-Z+J"onWg$YgNC0OOk\!48DR6&@=(AB7k(<^I'8KFkVPXr9cJa%`;;'1)sJKNRI*E-_)!63n`f&.?/l/s"ja#U+j4@\L9KjjDfh+bUCn/G++q4F0(4KFgJ+L#*<+7rKc.&4-Z-d+dOMkj=$763n_MH95@Q]q#^$#U.,QDhlN2[hD(6+bWt]m;R@CG!ZHXKFeO)*A3E0:'`"r&7V?B_r];##pFs567hbP\3,(!+bUCnLkX[qQUbsAKFgHUZ-_7ao'#Io&4-XG(4&&I*ke*U63naQ6>qY&UULn'#U+k'kj<>7oQEP,+bUC7]cA_dhG+>"KFhUd\&7=TgBf$V&4.r?G.9Y\4!B7g6AU?P%[T\(-\N$t#dMb2iUZ4"KFgHU+VoAc>TUSL&4-XG`'SBtbG2N[63n`f=Qo-kH1Z8H#U+j4$b[Q5O5<V;+bUD9Tsqr$dG"sNKFgI$oQI`,H93:'&422,h@>lBD^U2L63sjCgYq_em=Z$;#U't04'Wi?SIe*n+iH]ca,NJU7?&BRr`6IHi4oBhM/V4][<PKF[hD(6+bWt]mC8:B-Vn'[FNKoqhr,4^'C48R?h>,tm=Z$;#U-YukG,ND^?Fs;&4-XG]&J,0G1Y6F=gRlc_83s!bEdSLeQ6g5F00r[l:(I@S=H*.hKU7h,/VC@7qR5Eh06kd]AC8CkKYu&g&qTaQ7H%>>ISLJ:7Wm2_!(0=&4-XG(4&'FPMR>p'U4]@OHPdtq<+@T"9_Df2U/8MgW,9m-_5b4S2mm/TgOT]H[G5;]@ZoBhL>1bg$nM#&L0d3hS"9ZQ7X[m[X@l/LPn>MH93:'&422,hN$ot\(@cggN\cb$l_)u*a81.Frqfu5T<VHc/)d+;Pg1b,]eUCZ*=B8%']`A\%hUe>HM):1=nO6pol='ZY,?T_-F["p&&sP3qRS^#U+l2H(9rPm[Br\s7;l_1`n>V]\(EN.m#iIY.)1:at*@*$lUtDkj?BNFlgc2jq\.3*c/KUDVNo-GO@"^hmW@(U*WHufH!Xp@\Ug_]q#^$#U+(+kG,MuVOQr>L#"+tPJ+Y(Rl6fuFkZS&(GB+%3uHgm-\N$t#dK<ZdG%rjo_,oc^>"#pI/*14muo3[rq?9aai)6?>Q<L57ueQlZY%I`XK7mU0^`j,KFgHUZ-_6FSaj8?(LMPE,phZ20>7]#%/fRDs(bX!mBS-"3-alH\[$ot_hJp$\^VioNeE1CGOF73j2R(XWMrOW0(%>uB6JHA&I1dD-\N$t#dMb2ELlaq!<WPun)%K`GA([RaH7^*nNDu;^]&OI7"k)=e\]$*;TaC-NZCJR6N$f\CXoFBGjo,4_ls<=[hD(6+bWt]mC5o;HU:&Nm\;01]q#^$#U.,QDo["mG!ZHXKFh4FXr9cJG;]#963n`f&6Fmp)FeYc9qo*163n`f=Qo-kH1Z8H#U+j4$b[Q5O5<V;+bUD9Tsqr$dG"sNKFgI$oQI`,H93:'&422,h@>lBD^U2L63sjCgYq_em=Z$;#U't04'Wi?SIe*n+iH]cLWcI%'1)sJKNRI*E-_)!63n`f&.?/l/s"ja#U+j4@\L9KjjDfh+bUCn/G++q4F0(4KFgJ+L#*<+7rKc.&4-Z-d+dOMkj=$763n_MH95@Q]q#^$#U.,QDhlN2[hD(6+bWt]m;R@CG!ZHXKFeO)*A3E0:'`"r&7V?B_r];##pFs567hbP\3,(!+bUCnLkX[qQUbsAKFgHUZ-_7ao'#Io&4-XG(4&&I*ke*U63naQ6>qY&UULn'#U+k'kj<>7oQEP,+bUC7]cA_dhG+>"KFhUd\&7=TgBf$V&4.r?G.9Y\4!B7g6AU?P%[T\(-\N$t#dMb2iURg>!!!"&:rArZ!<W<%TER1]8f05^!!$2!_k;Y`!rr=o"Z6]\(bbpi!*W4:TS*=J!!&Yq2%3(o0E;(Q>#<,0KE2/T!2'KQ$q_?j!!!"&:rArZ!<W<%TER1]8f05^!!$2!_k;Y`!rr=o"Z6]\(bbpi!*W4:TS*=J!!&Yq2%3(o0E;(Q>#<,0KE2/T!2'KQ$q_?j!!!"&:rArZ!<W<%TER1]8f05^!!$2!_k;Y`!rr=o"Z6]\(bbpi!*W4:TS*=J!!&Yq2%3+&SNA2$k4%?Ik5bP_i'^JYUkVGYe(k7KHUpe&ZN't*5SIl#])*Uf%qj4[PlYsiclq4HS:;R![57gjUBGR/9,?]s`,SCB*2g/SEB[$#8Y+:NkK_1=EcQ2BpHdRUc?!Jq8`Q&$3)420id@%O:2,RFPa3lGB8PZ5644!(M;shd3)420id@%O:2,RFPa3lGB8PZ5644!(M;shd3)420id@%O:2,RFPa3lGB8PZ56AqmGY9kSCb!1"jaBo1M[)?rV9,?]s`,SCB*2g/SEB[#8V\B+2zzz!!!#/XUdYo0IeQpf@Mr6/oJR]%D!)52R$rHWcmd`<NK<M@^.If[)ec0S"'</CTga::r1K(Y=4?bHhZqc(S*a<\nfp#V+[.-;l36l?G/*L13=MGl[&Hq[prlVJqATk_o"QXk`Csj@P564jiW)S"7E\ZNkiHG:7XEd5CVBmPb+K'[V]5uIt)apb:gW#Q'J3+fNlncacl&AX]mh^_hJVe/6QH+k@Bm7dA'4T^\\<D$-#?XC@NPr-JJI(aI4u%)Y5t]`V02t^H_>61NMdAG>OhkFaj;^=(=G/Ru0_9OklWdQ'#clLdJ/QF6EDppe7;DIFkW-IJ`^I#miV3ie6`PEcof^??tXtKaS^Np%EUdGt7k_[s7H&mG#+ZDr89DeZ/1Y\$;l+Rl9s*f3c:ArT_q6X&lM(o[?TO3d)=i\om<V1M6RYgMbiTD3P"`77KaQ]Qhh+eA$M5.TNK"?bUp:VG0rS)`MYNbg4S[Q=!=H55OKoX]sm7&f)6@@`/P#YJ@PnrUne"If$8FG2BQ<ccD4n]tM,@gfc_+-"5iRNHa6)B>&WabhgWJ/KX0DpY9i9Z0P/U3b?OuHkt%r1M<Lrp?^IR_hJWtp[;ItCftLfWj.B;9uV2Ej@OE?rp[f9nf*(tMA90H.("kiMi3XW2l:Y:E[k(h1j\e-]n^\KZ0gqh\[`G)<;=dhraS&QGOD!)YO@uAF(@<l3Eaoihtm-9]C.jE4H:CAU?.bJTDYTb:=lLGX/pTE;**n<q=BS7]6E_07I/O,ZfYOVH$Xe*Dfe[@1*nn>3&<?hf3u:sd*U.#5Q7%6H0[4@18:P=jYqFjB$H:kc<2_Wl0Zn9m:LB&Mf%+N@1PNn;#^:gDCQ7hmsDHWe`:6r7%o_OVc'?`ftLtom'G$\`ONoT]"Qbip9_1`GplbIk0g,$S%eC/$Sq7o-_H'FKUDA;ZEiPu03l$6a[^]ifXGdkSB7<`GKTRKji_63m+J`-d`BMNET>'\`+uQiB)>5Ns8Mu&k*@T'S:A>W/3>ptIR3l+q!?_BMj&GPjM-e/#7m+,ZaY!VMbSME5X7TRMA<0mXkL0ufC\]W/*HL>e?3(]#&!,ES\r@_)`24^D;$gV5/3S)SWotVA]lDH-!;+[cq5pkAPfL7]@NK.AB9kB\2]J'FF1:[m;(:SObZGf*]9:-l-e\8-_HV0q3ScaN>f6$PlIm]Sik\oLO-SRaiSi+n])`!n3Q*nm+J_AF5!c.)]Lk\kYR]2gUD+%<isUAQS)R,o5EL,N?(*("9o(QDrEH_b'a*R[oQ8d/X%]X3d'^)2].pqS[2L9E[ng$o#pFT[kD$uZr*Sf;LU6'\A7nk2W$VA7Z<G'3-FLc5<loN1M9neh,G$Lc'p*\/N*N'"@EkAdG&RO]tMAWn)$>Z.dHN^_o>(C$X%;6R@3sGmG#!^e*u>6_ns96mFoP$]G623*@b-nS<Q_-+hbR"SNV<X3&p]nO$DcS(7VeB[p8p"%gNO^e?E@K/&.QGJdf;8mFiH,$rL]VI589fqd`<"I!g>'b*D_ihf$g!s%&H3(+i_^ldq2]Gq7t5F?(_FY*3Q1%hG*'n])_3X!Jr:-:Y-m)5Y;!-`VCZhW@2)hj#ZkZLYWlQ5r)4d*pHbn`%O-6\[#]MMmB33,kNFSWf6N&J;kB;K#n@c_ZX>1WFZarqq&Rci.b7[)lFWCtUR-qdW.ASs4Eo/S"Y]A_-/h;HpA5JakE?-,o9c5j$Z?9q==&3&p]ueZ2G/o%V%!%mSjE7h8AWXgi?/_G2%J1:q\p-52p"&s8<=&K2Sarql/*5)\gmVk:Er>jC7`K8m@tq;$.N&ebr?"Ie63a:O&3F6Ci6It_O\S14L;p?U=+0"l,:M%g,V?SPdVaM4itPq<Zh-`Z$Kk8cR6?[_UtNZC2BFQd-,?!I'[Hgc[u)h.VEQg!XH^2(p;o?TX.VG*DC.p&0H\omi>AReU;rr"&d,CfRS-i)lP.$$+?pr9F:X]fSr[Vb9WV;^ClI,gN,q!d7C<inE%i.)5)R?laLhgb[>Q'5?kbkkqPSCQVFl(sa-?[3NcCY#S4o[-1H_ST'>4DEo)(>$Qc)ninsP*2"%mFsRHp?[<[JBpI[gfVM`VII`jacXt1CtLGrR1)sV20%VD)1at85&kR^ldr>lI5n]e'e<>;r@NaF4aL56s)!\bjibiD:l?)@p?^IB53;G$e+2D6TV*F<qYoYBs2j0,Y[bdf`f(eT,3(=]KSG6(YG$ss4%c>.T69Y]_8dUDbhq;bIcF'+i%J?&HM-P<'br%p;Tg^')2^mt[rO5sNbr^tX;9,\:H_^_@RV02&J5U1D1:.tkHigTq;rX\NUdIU<ioQfpW6P5h/j$j/R'R:O)3.0Pp$J7zzzzzzzzz!!!"LX#b4XJAl!N\ok&pG.2hmmKXeX^t72IIf9+%s"*2k,G.,Geo:p!!!!#SMB4p,87`f)HF,\Fd@s&bVkgcijPKmsP>=C5a<Lp#*rP&Z571Y(mFnt>St9fR[^DZ/]\`);QNdEi!-]d'h9XD#,UDHpR5;i&=6o7AR@-"Ko)8=?5AJ]H,$*p`]6?S.6;UM*OX!B?RDnCWE`D[S!!!!YNV)pfmFp*j<GT[;+iYMVhO^+%BR@Y=q!mC>U8#jZG3I9r.4M6$\T29(P^2;K2mT`p?@M_3d*U-qLkt<EV]2ZSj`\q>3K4q7o(D[hkFR$$Y$>[YE9GN;D;)?'$k/A[FR.NFe>ZBdr+=3B`Q-"l_(Js#D"Hf6m>a1S-V&>-Hh$XrOi.(a]C1^S()q;Tq-Rr-7YWbnPa%E1SpF"hgmi<7gK1RbrQmnBalQ4Xb*<2@)KbN/7:X'Ep,ClVZ[;H7V+[.5r]c*.%bTE/Ci!oQ5_,Ad`f1oZ4Es]a7f`Si!#3SSh[:5QPaZpnn6r@iDjU;Mm948o-_Gc1:MJXr[?TX`HhY8Iem%"fhT"-*hC\tV_1Dj4aiSu-oT<c(2mGnL%M''l0k/)hh7L.4g![0;bD.0gf\!^`?n'`K.?Te6m[2%S)]'J6/Css/B^!g:Z7jn1bWg:;Qs:H?o[6Af+Vd0?Mj<=]M2@@ODnc%E>.&+U\[f_-gYSNjROZo$nk*J_CY#StpYL7Dp?ZLp-Eg_K4(c^(e3"[/DNnf4pu@F@]@3ZRb@QU]Fh)OT7Ij&`cCC;oSmDI_+TMKBi-K=.M1uHYp?L2OWm]X53[Z;qGZ_:abpH/R(t70kfi!6p='Mm&p35A=a&jVK<]^/jn%L=$;X[htC1V9fHG6JkB?qW7?>l1I>hCc4W`7+6h=B4NfDu'Y(t3N4"hrH'B\^,fKF&<N_[$VXPIbYU\*`RrHhZs[YFkWTeZ2buH?ro.ElFL!gRi`M$$26bI54^Vje;)A9`P.n!(r.%gK1L\<N9#tjQ,Bkn*RQUmVLUaWEGf]A7Xcun%WeS?>a?7js$e=`]MhD4*UDlp("GQCG&bq`1#<4qt0,OhuTH7J)7=L%j!jcI&"E3hO]mnioT9Eiku/`@=3HM[r1#\C"qJc',0Edj's-.5X9iNP1*mblg=`OpV4r^k.eZ:?C.k!DnC2[jQb[edA$jd"onW':^grS(Xg34g:"K*n\uO@lI@[lIdauEm-\dN(J3(N84YEVb%aiFX[VsW2Jq/ilI9P*T,BSOgMP29Z$ZA0+[b=IV69F^o^qnP5BlOcp!:=b<ioPX"q@k".c[k?k)1u/ppnm+>IM3Cp=kQF2$sZt>.8BTJO]bA!!&t'Xku3`m#X+eFQcQ-[niSX\Ql[ck'c/n]65c4D`;QmZ0'l8;Pcu#j5J(A,AYl3.<G&%<=uq#>0q[QnaZ.hFCDjgp/8VPq6=GMm^,in>.#eXVHElRgZ:<$B[NQirS$r<,=dd8ZSl[S<8bn.)`Er[?eA!O!!!"`f[]HYh7NR[q3eoZ3B>d1_rI<fDsn0=;iedT!5lZ=-=]CO6Y7*dd;NDK9NW>_ZV?W7.-q$E%!F@B``\7PQ=82a@e<#9].XF6??YdKjd,)OLR3)]l1Z5Yn,MK\[9C8X^>@`'r[bNkZe;gs\&DfRX4<BTjC)q"jPFu>rV6.IS'@],a2^]X>2ARh^K3K1Q*7Bp#D9j5\SO)@a*4Lihrj_-p\2kSbJW`D;044AB<%l?I6O8N&rC9)5!M9,lu4pH2?da(4aMZ]fl":.gMKnrYLh$2F#'/"2Oi*-PY.dHlhS`U#69:(Eu)M8Ak0QuS_r;kG44ngYHG%"St8!6cHgNX^Y^[[MbuL,c]?-,j0As1PtL0#jsC.K/siWjl\E+N5Nhb=IfK?DSB5:cZ(K<mr;&UdQcnKsIk?B=F;fLaTRJd(1AZf)W>,;"S@VNF*:NUIEdR$CHLYu-/hUVNOkq0$*q&Iaig@!VeS6*Hm/d7fzzzzzzzzzzzz!!)M<r;s3?*Q.~>endstream
20
+endobj
21
+4 0 obj
22
+<<
23
+/Contents 8 0 R /MediaBox [ 0 0 612 792 ] /Parent 7 0 R /Resources <<
24
+/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject <<
25
+/FormXob.dbca89fbf8b5cf46e71bed6f33b8b15e 3 0 R
26
+>>
27
>> /Rotate 0 /Trans <<
28
29
>>
30
/Type /Page
31
>>
32
endobj
23
-4 0 obj
33
+5 0 obj
34
<<
25
-/PageMode /UseNone /Pages 6 0 R /Type /Catalog
35
+/PageMode /UseNone /Pages 7 0 R /Type /Catalog
36
>>
37
endobj
28
-5 0 obj
38
+6 0 obj
39
<<
30
-/Author (anonymous) /CreationDate (D:20230714131032+06'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20230714131032+06'00') /Producer (ReportLab PDF Library - www.reportlab.com)
40
+/Author (anonymous) /CreationDate (D:20230714141422+06'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20230714141422+06'00') /Producer (ReportLab PDF Library - www.reportlab.com)
41
/Subject (unspecified) /Title (untitled) /Trapped /False
42
>>
43
endobj
34
-6 0 obj
44
+7 0 obj
45
<<
36
-/Count 1 /Kids [ 3 0 R ] /Type /Pages
46
+/Count 1 /Kids [ 4 0 R ] /Type /Pages
47
>>
48
endobj
39
-7 0 obj
49
+8 0 obj
50
<<
41
-/Filter [ /ASCII85Decode /FlateDecode ] /Length 106
51
+/Filter [ /ASCII85Decode /FlateDecode ] /Length 177
52
>>
53
stream
44
-GapQh0E=F,0U\H3T\pNYT^QKk?tc>IP,;W#U1^23ihPEM_?CZ51'*4N=m0!2`!rD0(`OljRfN-C.VOL2(7/\aKOcNbBRpjHDufr5>SXa~>endstream
54
+Gaq3^]aDY2%"rgh`Jn_i`3PZH=\G6`90kqs.^=ao0`?9Hl@_D_d)!ceNaRcY]Ais_"nb,'#>$&@(imMobg%64gk@6U3UIR<U>tgRi#qR]4[Nc%Baq`a>J$_ZnYTFGQ8MSOq7Snr<g/QicmMORRk\n%446*raa4Ih9uJ?I]7KbYn#Rq*~>endstream
55
endobj
56
xref
47
-0 8
57
+0 9
58
0000000000 65535 f
59
0000000073 00000 n
60
0000000104 00000 n
61
0000000211 00000 n
52
-0000000404 00000 n
53
-0000000472 00000 n
54
-0000000768 00000 n
55
-0000000827 00000 n
62
+0000024094 00000 n
63
+0000024350 00000 n
64
+0000024418 00000 n
65
+0000024714 00000 n
66
+0000024773 00000 n
67
trailer
68
<<
69
/ID
59
-[<9b1b145b1b22d3a9e95daf79e858348b><9b1b145b1b22d3a9e95daf79e858348b>]
70
+[<d85f110e28b07ce1655753d76f05c3b8><d85f110e28b07ce1655753d76f05c3b8>]
71
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
72
62
-/Info 5 0 R
63
-/Root 4 0 R
64
-/Size 8
73
+/Info 6 0 R
74
+/Root 5 0 R
75
+/Size 9
76
>>
77
startxref
67
-1023
78
+25040
79
%%EOF
backend/requirements.in
+1
@@ -11,6 +11,7 @@ flask-swagger-ui
11
flask_cors
12
loguru
13
marshmallow-sqlalchemy
14
+matplotlib
15
mitreattack-python
16
openai
17
pika