From a0b1237d3309b69accf8260d89a81661a013b721 Mon Sep 17 00:00:00 2001 From: RogueException Date: Sun, 18 Oct 2015 08:44:25 -0300 Subject: [PATCH] Starting reorganization - grouped all API serialization definitions together, moved Audio to Interop and grouped Net classes together. --- .../Properties/AssemblyInfo.cs | 4 +- src/Discord.Net.Net45/Discord.Net.csproj | 169 ++++++----- src/Discord.Net.Net45/lib/libopus.so | Bin 260748 -> 0 bytes src/Discord.Net.Net45/lib/libsodium.dll | Bin 492032 -> 0 bytes src/Discord.Net.Net45/lib/opus.dll | Bin 271872 -> 0 bytes src/Discord.Net/API/Auth.cs | 29 ++ src/Discord.Net/API/Bans.cs | 6 + src/Discord.Net/API/Channels.cs | 100 +++++++ src/Discord.Net/API/Common.cs | 318 --------------------- src/Discord.Net/API/Endpoints.cs | 5 +- src/Discord.Net/API/Invites.cs | 59 ++++ src/Discord.Net/API/Maintenance.cs | 33 +++ src/Discord.Net/API/Members.cs | 88 ++++++ src/Discord.Net/API/Messages.cs | 133 +++++++++ src/Discord.Net/API/Permissions.cs | 21 ++ src/Discord.Net/API/Presence.cs | 33 +++ src/Discord.Net/API/Requests.cs | 178 ------------ src/Discord.Net/API/Responses.cs | 106 ------- src/Discord.Net/API/RestClient.BuiltIn.cs | 67 ----- src/Discord.Net/API/Roles.cs | 87 ++++++ src/Discord.Net/API/Servers.cs | 80 ++++++ src/Discord.Net/API/Users.cs | 47 +++ src/Discord.Net/API/Voice.cs | 153 ++++++++++ src/Discord.Net/API/WebSockets.cs | 112 ++++++++ src/Discord.Net/DiscordClient.API.cs | 21 +- src/Discord.Net/DiscordClient.cs | 22 +- src/Discord.Net/DiscordSimpleClient.cs | 3 +- src/Discord.Net/Helpers/Extensions.cs | 47 +++ src/Discord.Net/{ => Helpers}/Format.cs | 0 src/Discord.Net/{ => Helpers}/Mention.cs | 0 .../Helpers/{ => Shared}/CollectionHelper.cs | 0 src/Discord.Net/{ => Helpers}/Shared/TaskHelper.cs | 0 src/Discord.Net/Helpers/TaskExtensions.cs | 56 ---- src/Discord.Net/{ => Helpers}/TimeoutException.cs | 0 src/Discord.Net/{Audio => Interop}/Opus.cs | 2 +- src/Discord.Net/{Audio => Interop}/OpusDecoder.cs | 2 +- src/Discord.Net/{Audio => Interop}/OpusEncoder.cs | 2 +- src/Discord.Net/{Audio => Interop}/Sodium.cs | 2 +- src/Discord.Net/Models/Channel.cs | 9 +- src/Discord.Net/Models/Invite.cs | 9 +- src/Discord.Net/Models/Member.cs | 13 +- src/Discord.Net/Models/Message.cs | 5 +- src/Discord.Net/Models/Role.cs | 5 +- src/Discord.Net/Models/Server.cs | 9 +- src/Discord.Net/Models/User.cs | 16 +- .../{WebSockets/Data => Net}/DataWebSocket.cs | 5 +- .../Data => Net}/DataWebSockets.Events.cs | 2 +- src/Discord.Net/{ => Net}/DiscordAPIClient.cs | 46 +-- src/Discord.Net/{API => Net}/HttpException.cs | 4 +- src/Discord.Net/{API => Net}/RestClient.Events.cs | 2 +- .../{API => Net}/RestClient.SharpRest.cs | 18 +- src/Discord.Net/{API => Net}/RestClient.cs | 24 +- .../{WebSockets/Voice => Net}/VoiceBuffer.cs | 14 +- .../Voice => Net}/VoiceWebSocket.Events.cs | 2 +- .../{WebSockets/Voice => Net}/VoiceWebSocket.cs | 13 +- .../WebSocket.BuiltIn.cs.old} | 6 +- .../{WebSockets => Net}/WebSocket.Events.cs | 2 +- .../WebSocket.WebSocketSharp.cs | 2 +- src/Discord.Net/{WebSockets => Net}/WebSocket.cs | 2 +- src/Discord.Net/WebSockets/Data/Commands.cs | 64 ----- src/Discord.Net/WebSockets/Data/Events.cs | 115 -------- src/Discord.Net/WebSockets/Voice/Commands.cs | 59 ---- src/Discord.Net/WebSockets/Voice/Events.cs | 38 --- src/Discord.Net/WebSockets/WebSocketMessage.cs | 31 -- src/Discord.Net/packages.config | 4 - 65 files changed, 1258 insertions(+), 1246 deletions(-) delete mode 100644 src/Discord.Net.Net45/lib/libopus.so delete mode 100644 src/Discord.Net.Net45/lib/libsodium.dll delete mode 100644 src/Discord.Net.Net45/lib/opus.dll create mode 100644 src/Discord.Net/API/Auth.cs create mode 100644 src/Discord.Net/API/Bans.cs create mode 100644 src/Discord.Net/API/Channels.cs delete mode 100644 src/Discord.Net/API/Common.cs create mode 100644 src/Discord.Net/API/Invites.cs create mode 100644 src/Discord.Net/API/Maintenance.cs create mode 100644 src/Discord.Net/API/Members.cs create mode 100644 src/Discord.Net/API/Messages.cs create mode 100644 src/Discord.Net/API/Permissions.cs create mode 100644 src/Discord.Net/API/Presence.cs delete mode 100644 src/Discord.Net/API/Requests.cs delete mode 100644 src/Discord.Net/API/Responses.cs delete mode 100644 src/Discord.Net/API/RestClient.BuiltIn.cs create mode 100644 src/Discord.Net/API/Roles.cs create mode 100644 src/Discord.Net/API/Servers.cs create mode 100644 src/Discord.Net/API/Users.cs create mode 100644 src/Discord.Net/API/Voice.cs create mode 100644 src/Discord.Net/API/WebSockets.cs rename src/Discord.Net/{ => Helpers}/Format.cs (100%) rename src/Discord.Net/{ => Helpers}/Mention.cs (100%) rename src/Discord.Net/Helpers/{ => Shared}/CollectionHelper.cs (100%) rename src/Discord.Net/{ => Helpers}/Shared/TaskHelper.cs (100%) delete mode 100644 src/Discord.Net/Helpers/TaskExtensions.cs rename src/Discord.Net/{ => Helpers}/TimeoutException.cs (100%) rename src/Discord.Net/{Audio => Interop}/Opus.cs (99%) rename src/Discord.Net/{Audio => Interop}/OpusDecoder.cs (99%) rename src/Discord.Net/{Audio => Interop}/OpusEncoder.cs (99%) rename src/Discord.Net/{Audio => Interop}/Sodium.cs (97%) rename src/Discord.Net/{WebSockets/Data => Net}/DataWebSocket.cs (98%) rename src/Discord.Net/{WebSockets/Data => Net}/DataWebSockets.Events.cs (94%) rename src/Discord.Net/{ => Net}/DiscordAPIClient.cs (96%) rename src/Discord.Net/{API => Net}/HttpException.cs (68%) rename src/Discord.Net/{API => Net}/RestClient.Events.cs (97%) rename src/Discord.Net/{API => Net}/RestClient.SharpRest.cs (80%) rename src/Discord.Net/{API => Net}/RestClient.cs (90%) rename src/Discord.Net/{WebSockets/Voice => Net}/VoiceBuffer.cs (92%) rename src/Discord.Net/{WebSockets/Voice => Net}/VoiceWebSocket.Events.cs (95%) rename src/Discord.Net/{WebSockets/Voice => Net}/VoiceWebSocket.cs (98%) rename src/Discord.Net/{WebSockets/WebSocket.BuiltIn.cs => Net/WebSocket.BuiltIn.cs.old} (99%) rename src/Discord.Net/{WebSockets => Net}/WebSocket.Events.cs (96%) rename src/Discord.Net/{WebSockets => Net}/WebSocket.WebSocketSharp.cs (98%) rename src/Discord.Net/{WebSockets => Net}/WebSocket.cs (99%) delete mode 100644 src/Discord.Net/WebSockets/Data/Commands.cs delete mode 100644 src/Discord.Net/WebSockets/Data/Events.cs delete mode 100644 src/Discord.Net/WebSockets/Voice/Commands.cs delete mode 100644 src/Discord.Net/WebSockets/Voice/Events.cs delete mode 100644 src/Discord.Net/WebSockets/WebSocketMessage.cs delete mode 100644 src/Discord.Net/packages.config diff --git a/src/Discord.Net.Commands.Net45/Properties/AssemblyInfo.cs b/src/Discord.Net.Commands.Net45/Properties/AssemblyInfo.cs index cb9c99e42..e242053d8 100644 --- a/src/Discord.Net.Commands.Net45/Properties/AssemblyInfo.cs +++ b/src/Discord.Net.Commands.Net45/Properties/AssemblyInfo.cs @@ -13,6 +13,6 @@ using System.Runtime.InteropServices; [assembly: ComVisible(false)] [assembly: Guid("76ea00e6-ea24-41e1-acb2-639c0313fa80")] -[assembly: AssemblyVersion("0.7.3.0")] -[assembly: AssemblyFileVersion("0.7.3.0")] +[assembly: AssemblyVersion("0.8.0.0")] +[assembly: AssemblyFileVersion("0.8.0.0")] diff --git a/src/Discord.Net.Net45/Discord.Net.csproj b/src/Discord.Net.Net45/Discord.Net.csproj index aa9491683..b9c24516b 100644 --- a/src/Discord.Net.Net45/Discord.Net.csproj +++ b/src/Discord.Net.Net45/Discord.Net.csproj @@ -67,49 +67,50 @@ - - - - - - - API\Common.cs + + API\Auth.cs + + + API\Bans.cs + + + API\Channels.cs API\Endpoints.cs - - API\HttpException.cs + + API\Invites.cs - - API\Requests.cs + + API\Maintenance.cs - - API\Responses.cs + + API\Members.cs - - API\RestClient.BuiltIn.cs + + API\Messages.cs - - API\RestClient.cs + + API\Permissions.cs - - API\RestClient.Events.cs + + API\Presence.cs - - API\RestClient.SharpRest.cs + + API\Roles.cs - - Audio\Opus.cs + + API\Servers.cs - - Audio\OpusDecoder.cs + + API\Users.cs - - Audio\OpusEncoder.cs + + API\Voice.cs - - Audio\Sodium.cs + + API\WebSockets.cs Collections\AsyncCollection.cs @@ -132,9 +133,6 @@ Collections\Users.cs - - DiscordAPIClient.cs - DiscordClient.API.cs @@ -174,26 +172,41 @@ Enums\UserStatus.cs - - Format.cs - - - Helpers\CollectionHelper.cs - Helpers\EpochTime.cs Helpers\Extensions.cs + + Helpers\Format.cs + + + Helpers\Mention.cs + Helpers\MessageCleaner.cs - - Helpers\TaskExtensions.cs + + Helpers\Shared\CollectionHelper.cs + + + Helpers\Shared\TaskHelper.cs - - Mention.cs + + Helpers\TimeoutException.cs + + + Interop\Opus.cs + + + Interop\OpusDecoder.cs + + + Interop\OpusEncoder.cs + + + Interop\Sodium.cs Models\Channel.cs @@ -222,59 +235,61 @@ Models\User.cs - - Shared\TaskHelper.cs - - - TimeoutException.cs + + Net\DataWebSocket.cs - - WebSockets\Data\Commands.cs + + Net\DataWebSockets.Events.cs - - WebSockets\Data\DataWebSocket.cs + + Net\DiscordAPIClient.cs - - WebSockets\Data\DataWebSockets.Events.cs + + Net\HttpException.cs - - WebSockets\Data\Events.cs + + Net\RestClient.cs - - WebSockets\Voice\Commands.cs + + Net\RestClient.Events.cs - - WebSockets\Voice\Events.cs + + Net\RestClient.SharpRest.cs - - WebSockets\Voice\VoiceBuffer.cs + + Net\VoiceBuffer.cs - - WebSockets\Voice\VoiceWebSocket.cs + + Net\VoiceWebSocket.cs - - WebSockets\Voice\VoiceWebSocket.Events.cs + + Net\VoiceWebSocket.Events.cs - - WebSockets\WebSocket.BuiltIn.cs + + Net\WebSocket.cs - - WebSockets\WebSocket.cs + + Net\WebSocket.Events.cs - - WebSockets\WebSocket.Events.cs - - - WebSockets\WebSocket.WebSocketSharp.cs - - - WebSockets\WebSocketMessage.cs + + Net\WebSocket.WebSocketSharp.cs + + lib\libopus.so + + + + lib\libsodium.dll + + + lib\opus.dll + + i_?VL?j4{h2-l0|A|B-1dD|j>;M0W z1SIG=@Bjbl;P?Oki=F)H|Nm>lJel{s@aq5nfxi?1005E`004~)1B+h-4~5A1|No1H z{ObSzx*vt>Q31~P>WhW^>i_@2`UJuFA1T5)mGJ8S{|`mZ>7Drh|BGJ)x!{uo0O^4E z|NprE|NsB#kD|LNNP|Nk+->C^uI|BZAe0FAsS00000S24g=Q-kafi(Dii zi*zI;h1-5TIo^Lch4y$g#{?t-0000f^XLYp|NqAXBmn>b0Ex%w_@w{;jaLJM;`|S< z)`P$UgW&uRuh@-*8Y}?-0E5I3TV7wokd3q^00000Q-kani&P{ei(Diih0=8qgZlw= zTQR_c`vP=ygTxqH!!f{v`T=wdf%^Xd004FDiQ4NMgZl`7?}gib-;G26!QcdokRa_- zVvB$z?NefjL?i@>6eQ?H|NsAk`vQKvY1`xh004u;7y;N@!;N+T$3!F~00000$3!F` z0RR91gTxqH=@G%Hs|BbXJ00000 zS5{Mtd?YA~TqGQebR-~)L?jT2d?Xx;d?X}`R3sFOOe7e`L?j>p0001qd?Xl&bR-ms zTqF=%USH{f>i_?cRaaJ1gX}DeL?lFuOe9E)Y$QO7bR^dH;)4Bv66> z{r~^~i(DjBi9{q2i$o+`i9{qA4~ISh004#d$At_500960|NnJxgZTjugbD!w0E77g z4}~rP004_bBoM~}0RR91#snk)#{&TX0071S0LDN80gE&wF~EcQ0uP_SA;ybDBp8Ww zBv6S&ButA$BoK*2BuI+`i9{qsivo*OBov86BtV12EQ#n_USD15#OeS4jdUgegZ=>z zlmsM$`3Mi5z#;@Bh(shGbXvjZ1dBu@5R11U?Nefj6eNiC(ls72t zQ(}k|FoVVcInH(Ni9{q254J=kAA|V?ixeb?1SAiRVgLXCivo>s|B1B>0RRB$QUCw{ zjdUgef&Tvh004DZi+m&yW-<1O3W@N?0{{R30EzyPjdUgehy(_MzyUePb@qvLBoOHu z|NsAsL?jT$0s#O30LBC)0LKFW0002S008O!{{R1wxc~qE|AWLVTV7vX!;N+TxcmSA z|Lg9F_KmzJ00000S5{Ml>>!JDBs7a$BuI@$|2_Ty004Iii$o+iIYcBpeiMb;bOy%* z|NsC0F~EbwAX{Ev!;3^DJOe}|I6eOW004j9i$o+ig}{E+i$o+m!RQ}^z;(-uL?k?k zL?i@@L?k$g1SIIC{Qv)n1SIG!RR92mz=_9nM~g%xM2Yc>R3tFRL?jRZ0001qL?jH0 zL?l3oL?j4{L?k?kL?i@@L?k$g1SE<0=rid5|AoMHB!$~_G>HR=_~~%}|Nmx?h1(B= zWdHyF#{>EQ|Nk+-=~@5(|A{;#G5?7~Bpm3?Q~&^rL?j&R$cgyrKL7v!S5{Ml>@bUT zBt(l`BwUR~|2_Ty004Fvh1+xn#{>WW|Nk+-gTydfUSGqIjdUgei$o+yi8LgML?i_0 zK>Yvzi3B9*XjA|Ig}{l&bY_c0Bv^@bBnXK-B#A^M9E(IGREb0+7>h(CP>Dn&6pKV8 zOo>D!5Q{`4NQp!w42wi0K#4>o1nB1c|Nn)+brOZ!bUuj#gTye2_*-6I!;N+Ti994R z|A|B-Ea(zc004_bBrNONh1(B=X8-^H#{>EQ|Nk+->0AH*|BbXJ00000iTLSF|NsAq z_KmzJ00000R#S^qBovEWBp8cyBpi!GBn*p8BoK*IBn-On2UB9lL?j&Gyi#JvL?jp( z0001qbR-msTqF=%Ug>i1|Nmx?R#S^qBovEWBp8cyBpi!GBn*p8BoK*IBn-Mh2vcIm zL?j$AzEWbxL?jpx0001qbR-msTqF=%Uga0ssJhZ-M{64*&oU zggOHN0F8D4500<^004pi$`1el4}`7)000krUSD0q zf&Zxw000k!U;_XE503=`004piqYnT84}|#u003r?507jE004pip$`B64}>}c000k; z_yYg{i$o+?JsAA||8xn1`2P=#JOcm#iG~~j001$->!N}GxDNmT4}|^!000k;_yPa` zf&aS?000k!_yPa`5032v004piybk~X4}}T@004`I7y$qP$A%~Y000000075^Bmn>b z00000$A%yQ00000004!+4}~!U004_d1cks4j^F?Q0E!T^gW~*+G!w@}Bm}$< z004;`B=h71Scp z|NsAsL?je3(ur&&9EsI~zypayBov9*iSvVGBozGX0*Ua8Oe7RJYY2@r2!0KVR3sdO z!UKci{Eajai%cXKiF_mki3B8xOe6^C(ANL|g}@JmF#Z4kgT(5TsW|BF;49E~gxi%cXK$3!FqzYhQai3B8xOe6^CVAlWtg}@Jm!2JLJi$o+WgU10e z2042K4~|p*|Nn{TIeQ3yz>7>I6pd*EgXR1I#p}6{f&aD-000k!^#1?rUSD0qxc~qE|LJD@|NnvirVjuB4}`-0|Njq;vH$=8f&Zru z004Brf&Zuv000k!sQ&-|>5BgU|BZG4500_`004pi`YHebjdUge4}^;T|Nnvi3o8Hs zbdKp{{{R1r28}$000000iSXzh;s5`Md?X0RL?i?N0001q1SIImP5=Oj@M%8a0RRB# zY~la^$3!Fq00000iF_moi3B9*s7?R?>4p6N|BZG4f&ZWn000k#3;zHAjdUge=^Ot4 z|AGI+4*&oUgb)7z|LO7l|Nnviqz?c94}|{x|NrUW{r~@g|G5tU01t%u{{R2!&;9@Z zf&a@7000k!=>Grz>AwB{|BbXJ00000f&aY^000k!(Ek7bjdUge>7xDr|BZAe0FAsS z00000>HAFp0FaQ7kdTm&kdTm&S5{MtOe7qOTqGog$#g-5+kP^OL?j@KR3sRUJcR%N z004_bBovJ_g#Z8m0ES{0r_T$Dgp92*mObJ1<37FV%Q1W>UYWA*xA7A&xPB5FN;JZD2sF?ER75Ri$o+O zjTCS(z>Tyf00000G4_MN0cMFZ0m?bpb@J;3-PqmOgTxS9USD0qjdUgeS24g=Q-kaf zi(Diii*zI;h1-5TIo^Lch4y$g#{?t-0000f^XNu||NqAXBmn>b0Ex%wIE4TIjaLJM z;`|S<)`P$UgW&uRuh@-*8Vmsd0E5I3TV7wokd3q^00000RaaJ1gX|oOOe8pqTqH1y zR3to$d?Y}PY5$9KBt(Jz{r~^~4~O#r0024H50C2r0050F7lHl%0000FkK6zN0EN;I zj?@4E0EzvRi3>5niBklLdk7D<6b6V?0}O+}0XfKZ@rfKH=(pSd z|AoL0gq#2X0LKI*0ssI2G5_d+ga7}HvkUk0wxgU10mdkB6ci$o+e$3!Fu0ssI2i8LgML?i_0ScCung}`*$gTx$L zUSD0qi)>!JD zBs7a$Bt(ry|2_Ty004Iii$o+iIYcBpejbI}4}_)w0074W|NsC0F~EbwAX{Ev!;Q2i z00000i$o+m14JY^J^ugz0DseqL?k$cz<$e%L?k@H=pTf@b-;^6Bs_^kBm|2@Bshr# zB|Nn^uB)z*}Bl z!;Q2i00000h1+!O#{>EQ|Nk+-=|TVh|LYBqkdTm&kdTm&kdTm&RaaJ1gX}!V1SA3g z004`0Bv6Z7Bvk0Nf&c%<1SA0f0044*&oUglho+0D=1g6aWAZg--zh0E=8C zSh)ZH|Nn*CcnUGVJ6;42oxu0li%cY3g~^FbBpeTf(gBp8F`{DZ~=gXa8@jdUgejRZ0Q>N(F3Ptb$G0Xf-q?~6nv6pKtG9ElNw z#5`MGUtPn2`@9bT01t)10001sY$O;l|BFThgT(`b<@|-fe-r8H0001k#{oHh1P_kg z0001q+Btp*jT|a}42wi06pdH|gX8=G)5k<41iTLb0ErYN=(mFZ|AoMG%ISju004pe z!Vdrdb#{wHBv^?=Bpi!I1cks4j*|cY0E=8C6fysU!vllk{Ob>pjdUgegU10meguAa ziRw9i2#qWnehrI6Bp8iI1B2oGjVua_L?j%?L?i^l4*&p(6eNj6Bnaq9g8%=8z;wmy z7>#xSf&0A=0049tf%~Zs0049lxcmSA|AWLlTV7vX!;N+Ti$o+?iCiQEi4-J>L?j64 z41)jvgTy>rUSD0qjdUgegTy>Bz*}BlUBivG00000i+m(lh5vMQi$o+CG400(00000 zgTMocL?jrCMg)UoBpCdKz<$YzbR|L8jX|No0kfVv-r>rsiw_v*pdl0{{Sn=m9awi@j+7|Nn`FT>t<7i-lzW z|Nn`#O#lD?iOz|gNdN!;$AxVF|Nj60004=@>mp{5i&cb!#sLA-Dc3u-VE_OB4}=2) z004#metwCCZ2$lNjYWisL?j%IMTm(+BovK>fB*mgi9{p}F~B*sT>t<7$3!F;00000 z$3!F$0000050$`)L?j4_d?W;k93<%dYXAR*zz>Lw0ssJug;f9l|A`zVi9{p_i$#Qq zL?i_0jEMjLJB4ij|Njq!aR2}Rh4v4GX#fBJjb-$>{Qv*|TV7vX!?^(f004vW0gFQf zG5>?%0f>!M|NsAsjZpvp|AWB;iH%(U|Nn!fT>t<7{Dr^|j>iE206BXI4~|^{004`X zT>t<7jSLoxm1zI}|A~!Y|NsAm(hrUR0ssJm=mCpO7&-V4mB0_Sz==d87>h*|ja7(= zOe7$QR3sdUG$e^cBovEe7>|A|B-42y+m|NsAqL?j4{ zg=GK#|A|B-1nB00|Nn`>iG_6k|No0chyjIU|Ns9fg=qi(|Aom9j(7n806BXIzW@LK z|9>>;_W%F@i-mOm|NqBCBoG1s004<}BnXK_BovE3)-|LZW2i-mOm|NqBC zBoG1s004<}BnXK_BovEi$w^Dd?W~i#{tJgBoF`q004{r~^}TV7vX!-c?$wM_s2 z|BIbS|NsAZ&O3#4|NsAg4l&8;a{d4Rxc~qE|LeH8{{R2~>#;Gw>)(yG00000S5{Mt zTqGQebR-~)d?X}`L?jT4R3sFOOe7e`L?j>q0001qd?Xx+bR-zZL?jeoDN|yJTqF=% zUSH{9`~UxtS5{MtTqGQebR-~)d?X}`L?jT4R3sFOOe7e`L?j>p0001qd?Xx+bR-zZ zL?jf@C{tpITqF=%USH`U`~Uxt>5D=D0FaQ7kdTm&kdTm&Rac46R#SuQJcY>*j`_g}@KC0uO|R0000o1E~BDg_r;U0Ev7g1c@{x=(mLb|AoMb#Se~x0001s zO9YJ+0S~W}C;rUSD0qhy%w& zBm_Vo004;;B1hA||AWLlxcvYB|65*PUBivECIA2c0FAsS00000 zxGVtx0K<)T0FAsS00000i$o*@$3O%C0002PjdUgegX|o~1SBj0008J=K>z@Sz;p-4 zKm-5)004u;9K&Xi>03bn0F87e0FAsS00000i$o*@i%cX8i&P{C$3!Fq00000>9_v> z|BbXJ00000i$o*@i$Da!kd3q^00000RaaJ1gX}DeL?lFuR3u0_&<~Ay0{{St!NKVt zgvk$uYy$uQi%cXyJ5dA=k6!}-0F8KHDZ-6hc?gYkfe4FCBvgr1BoxO)Bp3hy004!_ z4~4n`004u0BoqM;gwO#10E2ua6ao)~wE_SD4~}>P004_bBvdiUg}`(Zi$o+8G0A3u zd_(^G01uzRgTVodY$Oze{Q(b-IRgLyi$o+q55H3aW;;}P2oHq;0ssJwLj;XHYwHbz zzyfADQ2q~v>;V7(Irw$&53f`t6pcg?0y#t^P>Dn&7!QoQ0ssJuL?l2l|BFl{Ob@mI zjcEdd$ODK054J=k6o^3qi$o+?g}`)Oi$o+)D?}t1i9{qEbWe*+Buu)2fPjF2NdZ8O zNdJk*_v!)4!TJZm`5!6Dh0+g>s{#N3jYJgyjdUgegT(Dn&7={0IFpESa6ocpig}{C#iF70!G5?9iiEJbU55EL^gU11h1SIHX zWdHvG#X0wN=ZkbC9E*G;RE7T!h3^0W0Ei$o+$i%cX; zjc5UjL?l2Dwg7|R{D=XIL?jqHL?loTjUfO3|BFN>D&GP|BFl{Ko7rD z0*wqo54VBH0001HIl^>oWDvDP|BZG4 zxc~qE|LJZ1|NprD|NsB#WB&jDi$o+CjYLoZIYcB-i9{qAeB_HnButA;ButHH0gFT= zKo7P6gW&vw$N`7}>5~5c|BFNko|No0@Buwda{{R1twg3PC z0FAsS00000gX}DeL?l4RL?jph0002TL?jdd0001qL?jT4L?k?kL?jH0L?k$gL?j4{ zL?kqcL?i@@L?keY1SIIe`~Uxg#4N*&wg3PC0FAsS00000gX}DeR3tcyL?kfBL?jph z0002TL?jdd0001qR3s3KR3tQsR3r?GPz1+BBm@8e004;uB#Bfc2}0i<~560RRAtv?O2w004#CeqF}|Bme*a0EyX&@{L3! zB*#P~C;$Ke0O}0TVBJs|NsC0>+oifRaaJ1f$XdR004`eB*Xv! z0E@IFzyJUMh1(B~?EnA(i-aV|0000vge1fO000k!%m4rY50BFT004`GB+LK+0E?U? z!~g&QgXjT;z==d8EPib<|BY-UJnI^ejdUgei$o+mgU0~@#wo))d?YM%PlelldyPaS zK#4>o6pchAJBe&09LGc?7ytkO0LMfm5C8xG0Et8-497$y2mt^90Et{A1c@{x=!0MX z|AoMLuYts@00016USD0qjdUgei-aV|0000hge1fO004&uXk zRaaJ1i%cXGi+m&;i(Diai;*-T004`DI3WN4iPkB`h4ziE$N&HU4@mWa|KI@t0Dc%b z&<}(s0RRAlzyZAg0000z$N&HU4@AW|&<}(U0RRAnz`Dl(000k2!fU`Bjf4R}Apii2 z5Q!6uPy~rn1dC7ziBkxRPz;Gv42w_@iBk}ZP!x$%6pKI@x`~L0h>1fOiTL;G0s6uE z2EqRyDf$DEJRtx8gZcxBkvt&)01u9{0001sfjA)m0E6lTiPypJ0*yom0r%gH6uOC# zJRtx8iGesF002G50001f3oXb1004=BI3WN4gZ>JCV7kZv001$-+3tXJ;(q60CW%N2N0qN=f|No1D zI3WN4>1F@_|BZAe0FAsS00000Rk$oC00383Q|KZn001e(i>xF-CjbD8j3h`W004`; zBv2;+0E>mt8UO%;h0GcN00D#e6AzEx1ONbyPyvJZ1Bp~5c-urIc-TE)^iyKlR3uc{ zTqIBrkE0U+0ENJdSxCo)xEcTe0000#4~5AS007xUBv82E0RRBH@Bjb+$Ay3v008g+ z007xsBwUNMBw!~106F*%PsfQwBnXX!l|Tys0Et8-1dD_uOeX*UiF70wi?k$MCjbD6 z1SE-cBovFZBv>Z^0Eu)Y5R0@VR3`uciF70k|CA(XCjbD8g@6_S00H$8oXeR&wjf5m17ytl?y?_<~0FAsP7$*P#iF70cz5xIL0ErwVjh%!C004jY+y+05DCp=|V1V%W>s%GeFK^iyKq!QRQ<^4ad+>D|~5M+Io~Q(}okBqZ5HBqZL! z*bTh&Q)1bJfcXFa*y-6+Bq-RUK>Yvz*<2(f+3wlG*~#DQ4~J$0007zU*~Hn&-|Y{F zOalM_-oe=gsPt1}-|5}hb_&@Atn^c2+{)g|*}>S#*~8e(+vyL6fC2yj*#)rlQ)1Z4 z*umKawDePA*vr_$-pSeS*~#1KdJ+$W69WJM-Pzg9>k5sw00000-Pzg9+2EmU^iyKk z&DqM>4Y>4EV&1{t$=>qW?%(U(+7CwsX!KKJi9{qU*+e8P-oe-ny!2CI+~L_=Brw@j zBrMrPBq-kL*<2(j-33tfQ)1XeBqZG&BQ)1W+!1PmM+34KC-tpKa#Pm~Q*_^bX0RRBm$%DoL*_(X$|Nq%UBrMsR zJpBLv*<1X9{_p?*01t$g0ssKng!CX7007ws*}>Ss*@W~Y7ytm-M+Diy*x}jA-oe?+ z-sIWt*}~b$-|G*Dg8={l+3wlG*~#DQ4~K36007>>*#)TdQ)1ug-Pm>t*#)fhQ)1l8 z-pSd)*vi?#*vi}K4~L5V|Nq$qu=G=6*vZ(!*#)%pQ)1Z4*u&n*+3wlN+v(ledI}GO zvjG4A+05$#+059>*~!=qxb#zE-oo6;*~#AX+3wi|X!KKJ*#&I$Q)1c5+w9%k*}>b< z-o@F=-|F4j+tJ3#kG|AY835017D002Gb0{{RIj^GXe0NDkg^iyKl zTqIoC1*G&-V%c0IP}v1!^iyKlTqIPBm4Fri0JzWs004_wNGZ_iF8lxgEyn-=0EvY( zApijBtNZ`|*#)rlQ)1Z3*uvQbwDePA*vi<$-pSeS*~#1KdJ+$Wx&QzG-Pzg9>k5sw z00000-Pzg9*v;9=*bTV!Q)1r2+{xL=-t*b+*#&6yQ)1Z#Z1huN*~;7Q-QL;3+tJ>| z+0EbT-PzmI-P_s8-s0KG*bTh&Q)20D{r~@vjdUge+2HAm{{R2k;OTb$|Nmx?+2HBd z{r~^j!P(&1TqHE|FH|Nq_C-P+yQ*#&6yQ)1Z#Z1huN*~;7P*}~h>+0Ne0 z-|XGn+tS_I*~;GG*bTh&Q)21W{Qv*m*xlIO*x3bW^iyKl1#I+FV%hH7>)FBE)7i}4 z&EM?Z+uG9I+TP*V4ZQSIV(H-f|Nq_C-PqmO-Pzd%aP(7R+3w%!-Pzd%bo5hV+R@$F z>Am~^|BJQI8UO%`L?l>+_QyaF00000bs#ao$ApCt82|wJ0u@llgoRic008*{70`pg z0fYDwb>i9XG5^_ABruB{y+rO)Vz>eT007xkBsAGnBuLp*BskerBrG|@*;FJbjkORN z007xsBqR@xX#xNM+3vdF0RRBmz$wDn!HtZ>AQ%7u*#(I7Q(}#j)F2oD0FAUJ00000 z*#U#<2!p{0*+K}}LHyZ54B5-r$l1!+$lk)($lk%($=Jx=!Q8^xgoL00007v@-o)6z z*@T2(1pokpzya9mIoRIG-o$md-PqX$eDqUd*umWU*#&s?Q)1Y{*~*KB#2NqqjRe4r zgh#Xm007xsg#g*h*hC~O*<2(n*}&QQ+vpF9vkL$K*~{5nBuv@K*<2(**~!^lBz)OK zBz)LJBrw@rBrx3^BDfdiK-okjOm-dF1&H)hV%)>o%h^^)+05SK*~-}# z*~{6=+05$#+05AE*~*QE!2SRK*adv_Q)1rZ*~#AW*~!>MBsAGvBsAIX*}&@p*~!@e z*}&QQ+vpF9Xbb=V-Pze(Bz%LwNZCXreBQy?$=E=+Iq-GZ*bUJ1Q)1l(*z{9k-oe?x z+4|YQ+vpF9?+X9`*<2)i*+e9K*!$T9fb>&h*#+SAQ)1c5-|F4j4~ED9007DtlV*@MRcgT@5eTqG#lL?n3F$=F0BIN4kzIN6?X{r~@i{}OajiP(!Ay+rO)VmZSP zkC*-b|Jen2^iyKl?%4%=^iyKl!P&yu$=S=<%-PD>$?5$4|Nq_C+vpF9&I$kk-Pze( zBz)OKBz)fa*vQz(=^y|9|AV|FWG4Us2iXOL^iyKlTqHn#CyRt6WG4UsjY#;o0RR91 z)8L6jBzW6IBzV|8==4)!*}&e(*<2(**+e8tVDwXB$3!F~00000iL4|*CjbE1 z?%BYQjdUgejb8zaG`-;MQ(}uOo#5?LVma;)jX4Pb0J`7-001fSjfC_d7ytl`l++*? z0051Q>>wBb0NL)@0E55?gX##`LI~MF{MkYb*~>Y|*vQ$+*vQ_(*vQ_&*~!?*-of6% zb=BF*i-aUVCjbE3>e|xTgqWNe007v`+v|34*_4=^82|v;%iHVP)7{(I$=D5K^iyKn z>e|xT!rcY%^iyKk%Gt@^>D}0NE!hS5^iyKk%irpDCn@!bY$SNwL?n3FOe8?r%irtW z+S$nuMtmeBiF_m^>k8f4*~#k!-P+m7gZmY9ABo@T6#xJK-Pqa6i-aUVCjbE1l$e|u z007y_*~#mP-PqmO-Pnt)BtRzs0JszY007xUBrt=$&>8>$0^J-W4^KoSB#A^MBVDwXB-pby=*DtlV z*@M6Vnc0=h761T)!2#JsBsjt99oP*J^;2R2(1YLyDbO*}*F0Ey^{jnEnZ z0NGyz*##8!Q)1bKl#BoX0E55;*nm(P007v@*?{mF007v4Fd6^=*bNxu-PnWq1%59vz}ZA3RM`ZB*@T6Z8UO&;%h|%%%HGP}!P%UJlo|j4gTMiU z_z890-PqmO>jK@_jg%ye0001q=-GfY8UO%;!UTiB1lgES8UO&E9bBv{!%1lgPS9smH@L?kTP zgd~Un007v@*umM9B!~b20NF$&DA@%#^;2Tl$==D>1<3SMV%f{tTqJziL?nFJ4LtQz zV&3cA%GpFDFxkM^;@->I%ihA-$=Q@7ga7~l*~!=qK=o5%*<2(j*#(UBQ)1c4+vyL7 ziBrMs<*i0la*~!>UBq-j& z*<2(**+e8r-pk&}-of7a*agV+Q)1mzBna7DBuLprBskq1B2^90D=0)0001W-PuGWC^5j?$=S)? z%h}4=od6yH0N%;o$=RJCApii`1(fttVvV#W00000*@T7U8UO&;goOki004u)0X@h7 z007>>b>`STVDwXBG185NiBu$bf%^0T007%WBzO-_!q`1v^iyJqg)kui0NI5oApii`z}T!L zga7~l*#(&NQ)1ic+R@$F-pby=*_|jM007+u@bpt+-|5}hc2bLlEFk~@jZgu&^Z@_> ziBu$bf%^0T007%WBzO-_!q`1v^iyJqg)AWe0NI5kApii`z}T!Lga7~l*#(^RQ)1c4 z+v(fU-PzvC-oe?OBq0C**#(I7Q)1c4F~HyH-PjM8z&VA;8UO%v3de=a8UO$Q0001s zlq5ta004=F$Ql3ui+m&`i$o+?*+e8Xh0=+57};11#{dBU004A4i@YR6CjbD8v?N3) z0074a0RR91iN}jT1c^oji$@5FMhJ^X42ebzi$@TNMi7ff6p2O@i$@rVMi_y_EGGZ} zTV7vX!`Z;tEnxIhV%c0IEZGH+^iyKl#MtB6?%(MThLQaL|Jlje%h}1<;Mfgh^iyKl z&e_S?%h}24e*FLc-s;%}kn~ex=_UOC|A~cw761TINO09#&PUBio=Fd+Z{h1+!s z$Au^%003rYWEr(Y|JenI^iyKl!09dh z|Nq(U*~;k&_y7Oh*xAb2TqJPWTqI206eQhTBtYoB6aWC(L?m$8L?lezL?l4j$=S;3 zBJ}_NjZguD_ydVlBzW6IBzV|8VDwXB*<2)0*#%_uQ)1a%BvcQMUF`q=*+e8z*<2)C z=|1uQ|AW8*i9{rL+e9RI*gatMQ)1a%BwX1Ar1Vo_*<2)0*#%_uQ)1a%Bvk1T@&Ese zm4Fri0JzWs007xUBv9F0BwQ)b={fBG|J~Tz=?{mh{{R2o+1bF@EnxIhV%bzAEZM=? z$=S-;$>}Wn|Nq_C+vyL7!2bXL-Pzpf*}>`O`v3pk*xAY1TqG#n93<%B6953&L?kHL z$?359|Nq_C*~{5nByibWBuv>{BtYF9BvBtY59*~{q%_5c6f z*xP(0VA;#rTqJbaTqJPWTqI206eQhTBtYni6953)Y$RaWL?m?CL?m$8L?lezL?l4j z%Gt}=&DqJ>%-PB5%=7>M-Pqa8*<2)G*~!^lBy`zaByibWBtYF9B#A^MOz1)r004_b zBuv>vBw*P@By`zCByib8BtY5A+05x%^Z);ljdUgeRaaJ1gX~<3L?m>JbR>9-TqJOd zY$SY%L?kSWgd~6f004#di;N_Y0001qL?lFugd~Ij004e2J zi~s-ti9{qgi-aVU0001qL?k?mgd~^%004rsol;2Hn`iOBcr!TBG-`UNSWOS5Oey`4i$o+qf&JhC006n*0RR9G zPR)Vs-~j*tiF_m!fydwh004Jqc9E(IGFo{GY7>h(CEQv%U2Acg-Ajtc<*0E;kUjQCSxiA*FM*aeXIQ)1m5B3}%T$BrMr% zBrMxpBq-TzBrc0YBq)hQBq-ZNBq-Pol=xF(*+e81-r?Bf3 z0001sv?S;O0050Fy#N3J0NDkE_)}ty42EWqh5y+DjZ*{w007wqi1<@t*~;7M-P#X^?EnA(+3w%!4~Odj007zO z*<2(H*<2(P*}&OcBoNpQjQCSxiA*FI*aeXIQ)1m5B z3}%T$BrMr%BrMxpBq-TzBrc0YBq)hQBq-ZNBq-Pol=xF(*+e7|-r?BCFEB|BbXJ00000-Pzgb+2HBA{{R2k$%)hH2LAv5*~!`9+34Be z*<2(L*~#f0{{R2o+1cppq}|!s=-J@woY~3Q;MwTe;MrUx4B5%)2><{8*~y91>DB)K z|B#T7kdTm&kdTm&kdTm&Q-ka%p{z4hVu=JK=&u0)0E77di9{qA4}^jM0074XBnSWi z0O;Nw005z^GgM-U1SIH*0RRArL?jrYs54Yzi3B9*cmV(ai9{qEjYK3Ii9{p_jYK3E zi9{p>i$o+ai3B9*s2uw2hVuQpeTf>dCCIA2c0FAsS00000 zgX|oOL?j@I1SIG&|NsAmzz>wbgTx#Uw!rt;!;p}WgX|oOL?k4Iz;qRZ_ycqhxB&nF z0E5IF!VCbAjdUgei&P{ii9{p>i$o+KiBu#Ai3B9**a-jtxB&nF0E5IF!VCb7wg3PC z0FAsS00000Q-kangFOs@Q(^*(L?k413daQufKy@u0001k_yTkhgZKe-JA=d+xB&nF z09(Qg0J|t)RAPbqC}31#bmwM}ivxwgbOQg-gTn-Y`zT;kVs-6<#2B~%00016!VCbA zi$o+S$3!Fq0RR91i9{p_i$o+Ki3B9*L!)UrF~Gx+kdTm&kdTm&kdTm&i$o*@ z!;N$%0FAsS00000i$o*@!;p}WkdTm&kdTm&Q-kanp=eQ5V#h=z2pa$Z0F7KEB*#P~ z1OWg50LKI*WdBoQgTO$EL?jI85F7vii$o+KiCiQIi9{p>p=eQ5VuQdyi3B9*{2KrO z=>Ho40P78qkdTm&kdTm&kdTm&Rf*+SR*A+_gX~O+O~8u{957U3iB-gf$q$av0RRAt z6(BHFVlmr`LIgR+at@1n2m?n5ImQoy)BpeggTn!X!VEdfb>WFLB?2yo*)1gX|22zz>8#0RRAtMc{+@ z1P_JL0001k1spI`VgbiQBnTV;004&Tc>@i9{p_i$%nVL?i_0q#6JKjb-#(USD0qjdUgejaAHx9ZXSFV(YJvjdUgegZMyn z$%{qUjeW?A9Y|4BVu^et497$y2tWV;0Et8-1dBz?i3BA7(~CvGgX|EAL?j4{MZ}3T zB#A^M1n5Q@004_c;Dh);beeD+{{R2~6%0{SV#fp|)c;dri9{p>=(qj<|BbXJ00000G27`+ z{{R1>ATU&7i$n+ni9{p_i$@5@1SFvUQ(}okBn0S*{r~@obR-1F1SEj}Q)1|O{r~@o zbR-DJL?i?p0002T1SFvUQ)1|0{r~@vp%^e!VuiqT2g8lF00000Rf*+SR#SuQOveQn zFjQgz0002!SO@?BjRZiA1ce>|004vF@aPr_0074Y957U300000Da4ILBp-v|@S`9w zRARVXB~)T9TqRUugZKvzj+_7h0E74o4~}I4005y}B~)UCzz>Cv0001?U?o&yg}@Jm zfdBvii#=o|RARemB~)UC{||&c0RRBITqRUui$e&5_yG@v7XknPgToAg`&=bdVslE1 z6N`HUi;4gMP-2aT002;8iA}^0wo3?u`4A6;8UX+RgZUs2gqQ&U0E77m4}@0%004!*#j00000gTnzk9UL%JVttmOATU&7jWk=0JhcD-0005_ix7p{|~kZ54QP<{(;T_|NsAl$qz{Wi*>|- z?*IT$Vky^+P0RuQiA}_fRm`~o0001qbVsW>yL{KATU&70r`tT1c^i>2#Y}oi$Dm+1SFvUQ(}okBn0T4 z`v3olL?i^q1SI_bQ)1|i`v3oskdTm&kdTm&kdTm&p$LFeVv7KUz;qvj>MpjdUgeQ-kaniyc6CQ(}Yr|8yjU+jI~A6rDhL zQ(}Yb0gZM5b@9gpBv4>eV(0?-|Nn!;7+b?J+v@^}!;M1$ixh=GcvE79(sl6b#*MTl z00000iwz_&RAPn6bO!UojdUge#|0!XRAK=D008ThkdTm&Rf*+SR#SuQETJ%fQ)0(O z*Z=?k0LMk#00000Jx=C8yL1ot(4#bfQ(}!}^jltEUBit<*og!r{}mWfRAP&D*o%GK zG5&+>1pgHTQB-1y!~YcsQB-1yMb!Tl98pwaiAB(jMc|19B>xpKQB-0xb>K5~?n&x1dUY$i4_DfRAR>kATv~A2?PMZ#|0!aRAK=D005)-FjQirEHhMM zi$w^>1S9|e005)xFjQipFo08HiAC_CG=NiLiAD7P6*N&)VuS1i#{?u?090cC6+}@~ zVuS1i{}ljHRAR?OBm@Zr0Kka^B>xpWQB-1s>xpaQB-1s z>;#F!|JH@Tbqs~ubO?(_1c@9Z|Imwn2!;Q3*T)1Th%;1T{}n7zRAPhd1dV0%TV7vX z!|M%@kdTm&kdTm&kdTm&Rf*+RG4@k~>=2=ZGgM-Qz;z9cW%!BkTV7qmjdUge$3!Fq z3;+NC#{?t+0002!L=*r3g}{l!bV7?o2*(5@h%;1Ti35v842eSo{}udDRAQlkGgM-U z9e^`bVu?ctgX{#y1SE(vRAT=XEKyWqiSUE$1dV0*TV7qmzW@LK|Lc&Awg3PC0FAsS z00000Rf*+OgX|QcgfmoPi(LqXz;z8Vz>8h{$-|Ad00000#{?vZGgM;#75q?CVv7}k zGgM-O>;#3qd(RIoWg|iNcFQ2!+6P@y7%th%;1T{}n7zRAPhd1Tnyi zUHr+zi%1BGN(hMrB;&uCi$VyafHPELiO}oXjkW*) z0051@00000Rf*+;>==th41@RqbVhO&gZKk=3892DRAPm|b!4~!0002V!=Z#TRAPm| zbz-4}GgM-O_yKk1#|4BlRAK-C0074XB#1LqV*eHRP*h@r>;&t|p@cJ3VuiqT6UPOF zGgM*$0002E0RR91$-`!l#{?vZGgM;#6(CVmVuS1i>)Ytb{r~^#m5sC}00000=)3*@ z|Ld2KkdTm&kdTm&13)~1I8a3Z0CWX0z{6&cW`TGZ3jq(5zz?>-!;N+Ti$o*@W`Q_O zT66_5z{6&c>&}g|CIA2c0FAsS00000R#S^qBn*pOBoG5qJP)^W1`oGF6ovMUL;@Ie z8!^(5i%1MP*>?v6NC-L0atwpQ0fWFOIr4JoF~D11!;N+TRaaIq_EUrG9E*G;Fo`@Q z=o=CM0E74lcME2LJpceuVoh3f3xmWQiSS!qUtPnHxBvi9V(3Qy|Nn)+bmyTw08nC$ zkN^NsVh^`~6aY|S54UOtja&j4h3$0?>&Ir0gT?`a!zelKb0)_`BnSuq004=6Bm{{Z zB4%-9EskE@LOJAUBhOOgTx#$_FIYYUSD0qjdUgeQ!(3v>n002;8=%fAr|AoMGC5uEP z495f{002;8EdT&eVu?f~1n9>7|Nn)+bP|g|B=^w4=pTc`2*ZuG00000F~IBcjkW*) z0051@00000S26!qQ-kaXW`R8b08nC0T8msH7<37P#0ZJ_TV7woxBvi9V(2#g|Nn)+ zbm^fy08nC!uz&ziVuki}+KF@|1jhs<002;8=u`dw|AoMG#(~BF08nCy@^uUAx{Y=K zgX;lI00000gTx3i z|B3ipUSGqIkdTm&QBXYq5C8y;Oe73)6@lph5C8y!2>>ks5C8x@01yBGck3y^g9!jw zS;LT!W{_r(xB&nF0KyCakdTm&kdTm&xB&nF0KyCakdTm&kdTm&gX}!rL?l4jz}e-S z-{9TYiNb;607U=*f%*Ue004AA*}&Q5o8REw*!IK%buxka06+i$4}_cm004pd00jU5 z4}_Wk007zO*}&P#+v?rgdw$*6>jK@_gTy@9`om_B*}&Q5o8REw*!IK%byC>{Z~#RASv+Bp~aojdUgeb%fp7>)+kj+3xGv zjdUge-PqX$bO2Oh>&uXkkdTm&gX~P*L?lqz<(uE&B>+VL06hQ!000k!Tmb+8Jpcs& z01t$Y0000z06+i$4}?Ae007+ufB;lt*~#1K-PsR^+yDRo-35pMRAS%h4~G>2007zQ z*vU|X>Bm@t)L?i@&%nW9U1SHukB-#Ag!P)%TY$ODO#0Xf~!P_k$fKy`G!q~~) z;@QO5K*?c4fx&QfA^-pY-BctP$3!FqkN{L- z*<2(n+3ww3BoN(1Brx4vBnZa@Bm)2d0O)QD007xUBrNGq|NsAxkdTm&gX~P*L?lqz z<(uE&B>+VL06hQ!004AoJpcs&0CW`FJS6BP2LJ%wTqHQ%L?k$a#7x88TqH2)6bk?V z*#)EkRAR>fApigX-BctP$3!Fqpa4{2*<2(j+3ww3BoN(1Brx4vBnZa@Bmn>b0O;-t z007xUBq)Q#Ov8<~00000-CQIn=*J2G0Nq3+D8~RH0002pR3sSL?%iA@5ZzoP2**Su z1fT#^V#fp|0RR91=&K3<0Nq3+DCu$k|NoGX-9#h=*}zbP>Bm@t)L?i@&%nW9U z1SHukB-#AgY$ODO#0Xf0z}dib2HDBo80!Mv+1bI_<(uE&-PmR&07Yg!00ndi-s!`T zjdUge-PqmO+3v%M_KmzJ00000Q-kbi-9#jC-9#jK*}>W6o8REw*onc}z}e-S-{9TY ziNb;607U=*f%*VI000k^zz>8G0RRBm=-=uOo5K%8!-T*Og$Dru0D<8EMF0SS`Tzj{ z0Cj2E!P(`T-{9TY_QV1Yh5P^j0NDks090b#TqG#nTqHQ%TqH2)un7PF-9#iP#{eM! z007-wBpBU9Bskq%BoN(1Brx4vBnZbuBm}4cRAR>jBmn>b0O*bh007-YBq)Q#Xj{XO zjdUgef%yOd004B4f%yPH000k!!2tjOf%*Ui000k!lmGw#f%yOh000k#R0041*}>W6 zo8REw*!IK%ja(#H4}{(T007y^-CQIv-4rB^TqIcCTqG!o*yx7-|Nq(U*~#DO-Pqkk zBq-fPBrtjg4}`D)007y^+2xzx;N95v!~ze6GXnqs+2HFK-PqmO>jq|!-PqmO+34#C z-PqmP>jK@_gT!cC!`TI}090b#TqG#z|Nj5~f%yOh000k!FarPp*}>W6o8REw*!IK% zbOzbU+2Gm9+34B8*~{DO-P;d~yaNCL-Pr2_-Pqaa*~;JQ-PsR@7X$zR+2xzx;N95v z!~%5@>1+W20NvQ#*y{$}*y{q_*xByuhmEu*00000*~#5pBrx3+B;8yjD91!32><{8 z|LA4}004>D-5ez7oc;g*F~GV30002l?%(O%*bkb(-9#iX4@A(}z}e-S-{9TY_QV3+ zL?kG56WPGo<(uE&-PrcT0(1q1(sYWD*}>W6o8REw*!IK%4}~%U007y++2xzx;N95v z!~%2{*}&Q5o8REw*!IK%bqIyh4}`M-007zLo8REw*!IK%4~0qs004#34~2>V0077W1r0D<}d1pojKgr5Qc0NKIW<(uE&-PrcT0*zcGSPzAM0RRBm$=zHeFx?a+-CQIn z$3!Fu|NsC0=#K*c0EyV$93<$){Qv(kz`6kd007zU-|5}h51PQ;L?kE=M9|sgo8REw z*!IK%-9#iX4}{7A004#3bS2rq+2xzx;N95v!~%31+2xzx;N95v!~%2?>3IPF0NvQ# z*y{$}*y{q_*x3cR090b>ApZaV*~#5pBrx3+B#m4oSlwJCD2dqUNc{i*+3wlN-|5}h z-9#iP-9#iXdIk@KfdK#j*}&Q5o8REw*!IK%4~6{!007wqzyMTY*~;7M-P#X}+yMXp z*~#k;-Pqa5>j-9$*~#ky*~#5pBq-Uy-CQIv+2PwfB<{8|L9r*004>D-5ez7ko*7t+3wlN-|5}h-9#iP-9#iXdI}GOHvRwq-P!8`-PzgT z=_~#J|JljiTqH2v6eNvYBv{>CBq)j4=u`Xu|Jm-@$=~VS*xf`VDBVOPFnR_LgjD|j z|Jlje<(uE&-PrcT0uO{({r~^j;MhI1090b>-2DIl*}&Q5o8REw*!IK%4~4w_|Nn*3 z4}`S+|Nq_C-PqX$yZ}^U>9hR*|BZG4-PzgYo8REw*!IK%4}^36|Nq(U>6iTf|BbXJ z00000h0+g%`~3g^+2xzx;N95v!~ze5?fn1$+3wlk>2Li1|J_6+SltE4090b%=?{XH z{{R2k1<(LgV%f>x>D|~5f{XtD|Jljed?ZE>w?rgHv`~Uyh$=zHeINe+%FzBKL007wqumDtI#{eM!007-o zBpAm;Bm}4cRASj&Bq-fPBskq%BoN(1Brx4vBnZa@Bmn>b0O)!I007xUBq-^T`~Uyh z<(uE&-PrcT0uO~&{r~^j?&*5_|NoGXkdTm&kdTm&00000008hmkHYmRT#wQ}+3nkG zBm~*O+$8{WQ)1b`+2PzB2y;_n-{64cMRWz-+1dHS-Pqaj!;p}W+iWBR+5g|*sQ?53 z0CfSw+3VQA*~!`U-{7eL1ONba_1)Ro|HF`wW{_r(W{_r(W{_r(gX|pLL?j^Dz}e-S z-{9TY_QV0%z;!U)*xByc$=m7O*?I))E8W=JL?kHL$=Utg+1cfr-{AJd0d*hQ?%B!P z>D}3T6YB!q*@MI!!;N+T*}!$t-P!B$b?@CAB#m|e=xYN20Nn&6#{eP#004u;9K(>1 zkdTm&kdTm&kdTm&00000008hmkHYmRT#wQ}-39P-Q)1g}Bm~*z-{9H6o^l=7;@QC2 z;oKegb5mm9;DF>sbOqhn+4;lW*xB*Jdg0yK-PyyC+iWBR+2xzx;I>5|=79bMbTHY# zgX{>|d?W-9w?rfafXobLi3B9sEF{_d*=!^PgTx5j>DkHI@Y(3z!P))Y*~6&-0ssJX z1l`!#?!%CfW{_r(W{_r(Q-kbC-9#i%i(DjF+2xzx;MwT900000+vyLR!4E{ygwl0< zh1+y~B>+VL06hQ!004A-iQ0qW0X+af000k!+yDRoJpcs&01t!#0RRBm!G+t|;SY$o z0002p*@OE5bR+h|0olM0gl7Q&0NKfj*wOf?0ocfN0^G^b_;vK%*xAYJ0@=yg<(uE& z-PrcT0(2RL(sUKs;Oh~PjdUge-PqmO>jd4{-PqaagTzQ%!`;}~<(uE&_QV1Yg#-Zr z0NDlP090b#TqG#nTqH2)+yMXp-9#iP#{eM!007-wBp8WYBs|+hBs|?*BoN(1Brx4v zBnZbuBm~$1RAR>jBmn>b0O+;>007-YBq)Q#NL$0+`S;uDLI3~%jdUge-PncO4~W(P z004#3bQ0O+o8REw*!IK%bPVaC0001x-Pr2_-Pqag>0kf<|BZG4-PqaXo8RE}!~%2_ ziP*vDAB4bk3x(2j+l{m)00000+2xzx;P%7F56c z|JeoL090b#TqG#z_x}I?-Pqaa>5%^a|BZG4+3wlk>BIj2|BbXJ00000h1+!gs7kdTm&kdTm&|0Rr3RAP{j|0P^e zRAP{j|0RG?RAP{j|0QHmRAP{j|0R@BRAP{j|0R%7RAP{j|0S4FRAP{j|0SqVRAP{j z|0Re~RAP{j|0QfuRAP{j|0PsWRAP{j|0Q%$RAP{j|0RS`RAP{j|0S$ZRAP{j|0SeR zRAP{j|0Q@)RAP{j|0SGJRAP{j|0SSNRAP{j|0Q5iRAP{jW{_r(W{_r(gX}z^q%%}v z-9#iv-9#i%-9#iKBt(f+BovKQBoK)d zB>&Ls2Hn`**xlHJ#5}{0jdUgei$o*@qogxbV(DT4003r?gX}zuL?l3q5RFRzy6^y0 zVuSewcL$3UjSK=*V%01c_862**Su1ONe4Vu?f~ z454UIRAPg`K#2q-=o0_{05QOW#5}{0kdTm&|0P&aRAP{j|0R4;RAP{jRf*+;>=@{U zoc#aC1S9|zP-5tL;s5{1!;p}WkdTm&|NsC0Ab3+^00000|NsC0000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000|NsC0|NsC0P<{91^@s64FCWD0ssI23IG5A1poj5eI1Y{^8__N004ly004kH z0000u004kL(sZ5@00000?>YMZLN4Y%0002K0000#^8~d&004kK004kJ004kIQb`>; z00000b#7~JZ+C7WWpZ+FasX^;VsCJDb09G;F#vOQV`F7=a{y^>c42I3WFTR3XLW65 zZgc=*b!KK|av*eXZyN37a&BR4AZ2oLZ*l-*Z*p>VaCBv4AaitbWnpaq za%FLKWpi{OZf|rTX>D+9Wo>0{bY)}!X>N95Y-wa5b97;JWdLnuZEtdUAYp85Z)0I} zX>V>IW?^Y;Wn=&V00000000000000000000000000000000000T9H#?Vv$o~bCFYG zgppHXlaW(mq>)o%ypdC4%8^rI005mn06<X8000000KiN?007NB z00000000000000000000000000000000000000000RI600RI600RI5~0RRF20R8~| z0ssO30R8~|0{{X4004kL00000000000000000000000000000000000|NoqBRz^EB zEhr@+9~>GP7Zw#16A}>+5DyOy4Gjzo3=9hk3knJf2?+@a2?+=Y2nYxV2L}fS2L=WP z1_lNO1_lNO1_lNO1_cEL1qB5K1qB5K1q1{H1Ox;G1Ox;G1Ox;G1Ox;G1Ox;G1Ox*E z0|NsC0|NsC0|NsC0|NsB004kL004kL004kL004kL004kL004kL004kL0000$0000$ z0000$0000$0000$0000$0000$002Nh002Nh004kM005vs006*10000%0000%00000 z0000000000004kL0000$002Nh004kM005vs006*1007`X0000%004kN006*2000m| z001yT002lr003Y@004MG004$U0059e005ps006K;007iN000I<0s#OS7Xko&e0ObE zDH90<0ssI20000#004kL004l;004kT0000-&CE`}PAAB8JFUMb5xZxVw#Gcz+k&CJX_&CCox&CJZb z0000&006)}00000Gcz+YGc(gaDO``j^(gc|Na1=Eu1D!V004kJ004kO001aL001LH zWf|f-00000m~Ik-z{uIM-}%!002Ng004l%&CE`}NqnwgnD z0000um49Gg>O)SXjeh@ewqIHOZy<{93jhEB4FCWD4*&oF5dZ)H6951J6#xJL7XSbN82|tP8vpOVApigX zBLDyZB>(^bCjbBdDF6TfD*ylhEdT%jF8}}lF#rGnGXMYpH2?qrHvj+tIRF3vI{*Lx zJpcdzKL7v#K>z>%LjV8(MF0Q*M*si-NdN!O#lD@PXGV_Q2+n{Qvd(}RR910 zR{#J2SpWb4TL1t6T>t<8UjP6AVE_OCV*mgEWdHyGX8-^IX#fBKYXATMZ2$lOZvX%Q zaR2}Sa{vGUbpQYWcK`qYc>n+adjJ3ceEkg#Z8mhX4Qoi2wiq zivR!sjQ{`uj{pDwkpKVylK=n!l>h($mjD0&nE(I)n*aa+od5s;p8x;=p#T5?qW}N^ zr2qf`rvLx|sQ>@~s{jB1tpET3uK)l5u>b%7vj6}9wEzGBw*UYDxc~qFy8r+Hy#N3J zzW@LL!2kdN!vFvP#Q*>R#{d8T$p8QV%K!iX%>V!Z&j0`b(EtDd(*OVf)c^nh*8l(j z*#H0l+W-In-2eap-v9sr;Q#;t;{X5vPx#>i_@%?EnA(?*IS*@c;k- z^8f$<^#A|>_W%F@`2YX_`v3p{{Qv*}{{R300RaF20|5X41pxp62LS*82>}2A3jqKC z4FLcE4*>uG5di=I69E7K6#)PM7XbhO836zQ8vy_S9RUCU9{~UWAprmYBLM&aB>?~c zCjkHeDFFZgD**riEdc-kF984mF#!MoGXVeqH30wsHvs?uIRO9wI{^RyJplj!KLG#$ zK>+{&LjeE)MF9W+M*#o;NdW)=O921?O#uJ^PXPb`Q2_t|Qvm<~RRI71R{;P3Spfh5 zTLAz7T>$_9UjYCB4FCWD82|tPDF6TfJpcdzRR910aR2}SkpKVywEzGB-2eap2>}2A zIRO9wZ2^#cF^Q3L=0u>=4B z6$JnQeFXpj=>-4)Sq1F$@3z(F_0pbqxRj9S#5h$qoPjc@F>pEf4?zp%DN8VG;lUB@+Mu?Gpe1 zxfB2Zi4_0 zfgk_?g&_a{jUoU5nIixIsU!dZy(Itu)g}M{@h1QP5h(xwH7WoAT`K?pi7WsBxh((y z?JfWSB`^R0VKD#zp)vpfPEj0iDc{Tt5$u|H19XS91bvgh5(K`SDF+BhPl|BFf z{XYNzX+Z!0*+KvSO+)|y#YF%BK}P@p!AJlAMM?kw%}W3PSxo={=}rIueNX@Z6;c2I zu~Ps5QB?o{^;Q4?omc<>Nm>8^`C9-0tz7^BWnTaQAz=Uj;bH&)rDOmAZDs%fIcNX? z32FcU-D>~8F>Hz4SN6p1$_Vj0e=7h0f7Jj z1%m(p4TS&z8HWG>DTx38J&OPURgC}uagP81k&yrZwUYn<004mhf8CV;0121?06Cff z0BxKA0HvM)0O6nj03o9Q0A-~B0IjD00Qso^070G+M?0QIl{08z650I{_I02R0Z z0DZau0O`B{09n5P0L{Sw07b+A0Kvup071zB0L9Ay08P#S0NKz00BO?z0R7bf0F~GP z05RJD0MXq50CnI103G810LkS50D0&D04?hP0Ojof0HN>z06zc#0D%Ai0OtSz0C@ob z06zi%06_x)0EYws02u}V0RIO706_`>0Ot$<0QnC90Dltz0D%_(00$fZ02v_w0KX;x z00Auk0OvCR0C_tA0KY>30KrTE0Ebop02yHb0Do)%0Ks?w0Oy4O0Qr*u0RN%@00FZA z00+bX02$T*06*yf0D=7g0Ot|`0C_0^06#$i06|&-0Ect|02z=00ROB3071(E0O#rf z0Qn070Dmq50D)2h00(#i02!YG0Kdlq00Hs>0OuV80C`IT0Ka+z0KuyR0EgZK02vbm z0DnmY0KtI-0Oz{|0QvU>0RJ@w00DLd00+1Q02%xR06#(o0D+1I0O!;O0C^z?06%aC z071bA0EZL^02yis0RO=V06`oH0OxoK0QuJm0Dn0O0D+wf00#sM02yry0KeD^00Bn~ z0Oz+10C_770KcIP0Kpm#0Ed z02y)<06z;90D-3z0Ov*(0D0*Z06&iw06{nx0Egrk02!1R0RKiA073m30Oz(E0Qqwp z0Dm+b0D<@%00+Pw02zxO0KZuu00Ar@0OtWA0D0RX0Kd2*0Ku6f0Ed1g02yZ`0Dn^^ z0Kr2i0OvO-0QoN|0RJm000As300%HE02w$f06#=70D)950Ox2h0C|Bi06(5G071Vq z0Egr>02vN80RKBT06}gz0OzDR0QuiK0Dm7m0D)sY00*o-02%o|0KZB>00E&w0O$Kd z0C`(Q0KdOR0Kq6o0Ed=I02v8O0Dpi?0KxoC0Ox&A0Qmz^0RN6s00AFV00*>H02xkK z06*Mpi0tx?&0;#I10zp>E0)YqV0x84^0|}BV z0|9qV0|9w*0|}m&11api1A%Gf13?@P1gQ!*1PME11i`b91VMYf1PPez1gQ`m1;Oi1 z1pzRE1u5jV1ql!B1%bCD27%;V1__;*1}W&&1_8|y2fG;eA3;e8APKb1AgQ30A;B48A^|Ee zBPrYhBndm&B!N-0C6fjK07VV}01q4h01-0)09#i801b`+0C(L0069$o0AuC>0F|=> z03X2v03jU(0ISyq0Nnx!00*-R0LlIi05ks*0OijY056Xn05M)90Q+Dp0Ij|?0GFXa z09iLp00XgG05wBw06!*w06~_N087)X0DU3I04K@j0O=M90n=MA0fp^Z0Z%500a0bW z0hNCU>BMQX4&_; zYlFkBakUxacfTTCejOtK0C7zK0Fj&k0R1Kb0A&mU0O@xF0GXl%05#SK04;D00O8~l z03pL10PVLZ0Ckc$09i;)04e%s044Z|06oXF08u9D0I?G+0o~Gk0fqA30m)KT0=X;W z0u>aD15F521i^7X1wk%T2F;h02bGKo2|0JT3Q1R}3PT?AE}inB-xy8DfPKhFKx)?HKC?CJz+syMXjG;PPOh?SQ(C7V`&_IZ{>s4eE+=w z00F200FP?}0P&s%06!xP0Kq*K0FSmK0P*}e0RK^200H`o01tK10CB%E0Y93!0m0mD z0uRq$196U?1pj+I1_8EH2#=in3h`lB4nL=i62T?K7msB$9`S(`Cja}VF9Do7I}c(a zNpXh2SwD(`ZNXUMgaHl&0FfaH01+$`0733006|Yj0Fgt001@}y00BmG0RfU)0uceY z1Ccen1woIe2tfwU3=y)M5|Iy@8UY%1B>_waG?AWHM-iQ@U_qvlfg@2C0L7j%02jGy z0GamK0Beb$0S(0d0v`cT1tHlT2{UXk57nZi7^i0lCn^1XJbSh0TOD^DiLan7$*qoi z0Ey-q0Xddl0zDSk1hr##3E?Ql5g`LKAazKBIDJ=FV82_h0)f~k2KR(s4e9=^8-I)I zHi5V0Xcq&V!NCmw4moOtA{p+HOM!SRo-^SIQ~&?~KidyUKL7v#000000000000000 z00000000000D!vy0C)fZ02KfL02KfL005d@VqnZuVt@w#00RI30D!VnVnDJ}VgRyJV!*LeVj!whVu%3% z06@!AVxY-WV&KSAVgLXD000000000000000000000001hKc@eGKbii2KiK?#KV$lT zKRWk+KVI{HKhExdKa1&qKa}HtKk3|mKa16WKY7i6KeWVuKRdgBKM%2gKQE?#Kb)F> zKUR)^KU{%-Kd*CtKTc(TKRQ-_KXgWaKlwF(Kg=Y5KkO2JKUn~OKN9VJKN;D6KW)T* zKMt>cKmC|~KRAMZKf!8#KbTT}KfF19KQ17CKkWs6Kls8Kd6*^KVWfuKW9yRKfNe?KVbuWKULj(KbW?A zKPr!VKMZGkKRrHsKfV-uKac8qKd`@gKOvNQKjLS4Kl3_zKU58RKL+1Kk7zzKM@aiKa19O zKUkf1KX+qxKk6uUKd|j}KgqFmKQ?uBKlV3uKMVSFKXbcuKQMfBKS4ZnKd1Y1KViCa zKX7<+Kh-sJKacWqKc22~KLcuVKfWY#KhNHAKQ@?gKlD&>KL`nNKXbrvKQ(u7KTj=i zKfmH{KZuuaKd4J@KOp~ZKk>0{KN@6iKb#eAKX%4#KdN?ZKQ|_AKOWU=KVE}uKlw0h zKkeOXKRt?TKj$@TKkMLXKTC^hKL<5xKONp_KahrLKVL3sKZ@08KN5UsKldSMKRL%| zKiF$$KhzIrKQFUpKj&3uKmPY+KXjR8KS(-dKYQ9_KMs0iKLHtJKU243KL%A}KN<33 zKaGxJKVd3jKbOT}KQCZmKPdWOKZKKDKSC^EKV!sSKjvFsKh5%9KNpE!KgAwiKi9Ke zKTb$pKPlW?KWcAWKMw+2KN^%KVr68KcGfhKSkDAKTu^^Kg9D`Kc0bDKj98o zKa87KKcFX9KOM7HKLb8iKUBz7KMhhKfq&DKe_8uKOS>aKkxZcKP!MzKhyG>KjDo$Kac!7Ke=iL$KO?d^KS3TjKir8pKlk)EKagKHKdH$!KS47# zKU$nMKl21NKMid(Kd96*KgByUKV+gZKZgi1KP_%CKULE(KLI!}KQf#zKj{B1KO$o; zKjOtLKPf0JKlX_%KS}E=KO{^mKZvXKcs>hKX2C=Kg}x{Kfr$&KS$FSKV&8sKNxuyKVr)jKSCW9 zKe=ucKgqunKXDKfKeAvFKa8*uKL7v`KMhY1Ken9@Kl$qpKiN4BKUIefKW@|vKO`Xx zKXz>kKWMoMKlcO*KPFHKKlYjkKV;kKE}rNJ||A}KHSvu zKI>ZXK1|^6J_Tj&J{RfiK89@TK1}cFK5ud8KJD`6KF)LHJ__{XKB;r!KC1HIJ_&K( zKFjXiKJjbZK7r`kK67N*KFr_OK8{+}KEBk{K2%QAK32!kKFB}NKB%|OKJ+flKCh+A zKHnS4K7NtNK9B~-J{Eh$J{9l7K8Iq$K5^B+KG#RTKC`*KJ_;+mKHZzTJ~RxuJ_3BV zK2PhlJ{?-LK5xjfK0!9IK9-}eK64PRKGS@xKDy|tJ}6YFJ|w@VKBg(AKC_dgK2iOm zK73}OJ~PjsK6y8uK2x8ZKD`E;KDlj~K1$S=K6E;kJ}{t^K7<96K5=T1KK#y)J|8oV zKH-*(K0x}4J~~~AKGeU5J`W;>KJSBsK5pfLK9WX(KD17MKAI1FKFH5_K1PpqJ{eAO zK1mF3KGDf*KCFglKI=kdK7#&XK6|-dKG$SkCJ00jUP03!f0015yZ04M-A0096H03QG@00saR03-l201E&b04V@C z00ICJ03ZM_00#gT03`r401N;d04e}E00RIL03iS{00;mV044x601W^f04o4G00aON z03rY}00{sX04D%801f~h04xAI00000000000000U06YL%01p5y080RA00jUe06_p> z02BZ+08jvK015yo07d|002u%`0962U0096W06hR(01yB!089XC00sag073v@02Kf; z08s#M01E&q07n3202%-|09F8W00ICY06qX*01*H$08IdE00#gi07C#_02Tl=08#*O z01N;s07w9402=@~09OEY00RIa06zd-01^N&08RjG00;mk07L*{02cr?08;>Q01W^u z07(F602}~109XKa00aOc06+j<022T)08apI00{sm07U>}02lx^08{{S01f~w07?L8 z0385309gQc000000000000000000000000y0C)hj01p650EYm>03HBZ0G0sK04)G% z0Hpxo00jU+0DS0IC4y015y`0D=I%02u&P0FeOA z04M-t0H6Te05<@00IvY+0096!0C@nl01yC70Ehs@03QHb0G9yM04@M(0Hy%q00sa; z0Db_v02KgH0F40203-ll0Gt5W05bq@0ILA!01E&|0D}O(02%;R0FnUC04V@v0HFZg z05|}20I&e;00IC$0D1tn01*I90Eqy_03ZNd0GI&O051S*0H*-s00#g=0Dl0x02TmJ z0FD6403`rn0G$BY05kw_0IUG$01N;~0E7U*02=^T0FwaE04e}x0HOfi067440I>k= z00RI&0DAzp01^OB0Ez&{03iTf0GR;Q05AY-0H^@u00;m?0Du6z02csL0FMC6044xp z0GV0agIc07e160dxTD z0AvB&0RjMe0P+B80U!XF01yF)0X_h>04@Qh0bBso089bI0TBR+009Ac0WScj03QLD z0ZjnK06hV<0c!x`09ygm0S5qo0QUfI0VM#P02Kj^0Yd=005bur0bu~y08s(S0Tuv` z00sem0W<)t03-pN0a5_U073z}0dN550AK;w0So|y0Q>-S0V)8Z02%?30Z0JA05}1# z0cHT+09FCc0UH3501E+w0XYD%04V{X0apOe07n780d)ZF0A&H)0RsSg0P_HA0U-dH z01*L+0Y3n@051Wj0bKyq08IhK0TKX;00IGe0Wbil03ZRF0ZstM06qb>0c-%|09*mo z0SEwq0QdlK0VV*R02Tp`0Ym`205k!t0b&5!08#N+0R#Yi0Q3NC0U`jJ01^R;0YCt_05Acl0bT&s z08RnM0TTd=00RMg0Wkon03iXH0Z#zO06zh@0c`-~09^sq0SN$s0QmrM0Ve>T02cv| z0Yw1405t)v0b>B$08;_W0T=*~00;qq0X6`x044#R0aO6Y07L=20dfH90Ac~!0S*9$ z0R8}W0W1Kd02~370ZIVE06GD(0cZf=09XOg0UZF901W|!0XqP*04o8b0a*ai07(JC z0e1lJ0A~T;0RRAiKL7v#fMfc9KfiTWyo>37KMHZyym`%kKj+RMy)UMJKRRAky{~hB zKNIqWz4!z5SSeKLiujy}UVoKXbS6y;aYBKd7h$zROvCKfCV| zz9rdwKU^>%zGqE*KlN!XzL>UqKl7V9zP=QDKf=XFzT#(kKh5S;z6r2-KZ5>YzC7)C zKTQm8zJwomKb#MIzUoGIKkkEszIS7GKR)`3zBYArKXq!6zA$`rKTOn@zHxYSKYBNw zz5{ACbKgmDPz7l+BKayJ3zSIwAKl5wczI2&oKdN)$z5y9zKXGyBzKxDzKL=&* zz9{-&KPOJ~zUEtBKaec?zSpx|KL7v#zYhXjKO5u%zo151KX<|fzn+0uKlYjkza6ty zKX+{lzcJfXKiWACzwh}{KL7v`zibatKgz!ozr7nzKNxuyzxWm7KfOLazvId%Ka+SszdAxDKliCZzechnKhe@eza$$WKMM0kzwvw?KZpuRzslDe zKQtLjzs)NdKlmO^zZiKIKfN1IzskQ8KWqzjtj5KOM7H zzxJ94Kc0bDzjwj~KcGfhzZ>KNKMw+2zW@LLKi9KezmP2YKIU6rzb8)gJ}CNNzXxUR zK8=oIzj1NsJ^>kIzp8WMK6II7zw>L{KGY9qzmi(kJ`#LrzsWz)J|5m_zup_lKIb)S zzZLJpK3;=tzqGl%K6b`!zX5!=J|X{Zzd<&!K2I%hzr5(GKJ-v=zqga5J_BlUzj`;G zK5=++zf9DZJ}`WAzjbPnJ~nlAzdrhkK6hhwzwU#CKI%qyznl+zK7=25zfBBpK0NJs zzk>c@J_)dSzs=@UKH_J3zrw{wKE4!tzw?_qKA5(9zx8P?K4(pQzg#dNJ|)?Fzq{`e zKFe8szo@7MK2^_szjL?nJ-j)7zXTK3J^h$|zcXdKJreDHzbdbwJ^3|%zZ3F>J+E_r zzdBx4Jujwzzvs>%J$cQ4zY1~IJd5dnzrS@>JY)KQzW^|eBme+_zrS@>ykq)*zY1~I zyo>37zvs>%y?M=lzdBx4y)UMJzZ3F>y{~hBzbdbwz4Uqzrw{w zzP=QDzs=@UzT#(kzk>c@z6r2-zfBBpzC7)Cznl+zzJwomzwU#CzUoGIzdrhkzIS7G zzjbPnzBYArzf9DZzA$`rzj`;GzHxYSzqga5z5{ACbzmi(kz7l+Bzw>L{zSIwA zzp8WMzI2&ozj1Nsz5y9zzXxURzKxDzzb8)gz9{-&zmP2YzUEtBzW@LLzt^)}zZ>KN zzYhXjzjwj~zo151zxJ94zn+0uzjtj5za6tyzuGwtzcJfXzW@Lczwh}{zskQ8zibat zzZiKIzr7nzzs)NdzxWm7zr8*_zvIO%zmNPozX3Qfzap|Zzh$B_zmQ)yzw-n&zw-n& zzmQ)yzh$B_zap|ZzX3QfzmNPozvIO%zr8*_za>m7zms@CzvId%zxSy^zdAxDztPe} zzechnzY6n4za$$WzlaJ+zwvw?zcd+3zslDezxWKNzt^)} zzW@LLzvf$CzmP2Yz9{-&zb8)gzKxDzzXxURz5y9zzj1NszI2&ozp8WMzSIwAzw>L{ zz7l+Bzmi(kz8>CbzsWz)zUMV-zup_lzFvcDzZLJpzIMiKzqGl%z9Ii^zX5!=zE3T1 zzd<&!zVuLWzr5(Gz5{Ac@zT#(kzs=@UzP=QDzrw{wzL>Uq zzw?_qzGqE*zx8P?z9rdwzg#dNzROvCzq{`ezE#hCzo@7MzPvepzjL?nz5SSezXTK3 zy%OzyzcXdKz4y)UMJzdBx4y?M=lzvs>%y^HC8zY1~Iykq)* zzrS@>yZ``zzW^`|rDOVkzrS@>Jd5dnzY1~IJbBH3zvs>%JujwzzdBx4J+E_rzZ3F> zJ^3|%zbdbwJreDHzcXdKJ^h$|zXTK3J-j)7zjL?nJyp+rzo@7MKFe8szq{`eJ|)?F zzg#dNK4(pQzx8P?KA5(9zw?_qKE4!tzrw{wKH_J3zs=@UJ_)dSzk>c@K0NJszfBBp zK7=25znl+zKI%qyzwU#CK6hhwzdrhkJ~nlAzjbPnJ}`WAzf9DZK5=++zj`;GJ_BlU zzqga5KJ-v=zr5(GK2I%hzd<&!J|X{ZzX5!=K6b`!zqGl%K3;=tzZLJpKIb)Szup_l zJ|5m_zsWz)J`#Lrzmi(kKGY9qzw>L{K6II7zp8WMJ^>kIzj1NsK8=oIzXxURJ}CNN zzb8)gKIU6rzmP2YKG(BdzW@LLKMw+2zZ>KNKcGfhzjwj~Kc0bDzxJ94KOM7Hzjtj5 zKQY@>zuGwtKkxZczW@LcKWqm7Kac!7zvIO% zKO(X@zX3QfKagKHzh$B_Kl21Nzw-n&KV_mazmQ)yKLI!}zap|ZKjXzMzmNPoKP5~n zzr8*_KjX?Mzms@CKRQAtzxSy^KSr`6ztPe}KO`F=zY6n4KkCbKi(V4zUMV-KNau8 zzFvcDKeV~MzIMiKKLLEVz9Ii^KS4IJzE3T1KfLIwzVuLWKev;lz5{AY zz6r2-Kh5S;zT#(kKf=XFzP=QDKl7V9zL>UqKlN!XzGqE*KU^>%z9rdwKfCV|zROvC zKd7h$zE#hCKXbS6y}UVoKLiujz5SSeKQm>!y%OzyKPs=Fz437KfiTWykq)*KLE&6r2qhcKfiTWJY)KQKMHZyJd5dn zKj+RMJ$cQ4KRRAkJujwzKNIqWJ+E_rKPs=FJ^3|%KQm>!JreDHKLiujJ^h$|KXbS6 zJ-j)7Kd7h$K2^_sKfCV|KFe8sKU^>%J|)?FKlN!XK4(pQKl7V9KA5(9Kf=XFKE4!t zKh5S;KH_J3KZ5>YJ_)dSKTQm8K0NJsKb#MIK7=25KkkEsKI%qyKR)`3K6hhwKXq!6 zJ~nlAKTOn@J}`WAKYBNwK5=++Kev;lJ_BlUKfLIwKJ-v=KS4IJK2I%hKLLEVJ|X{Z zKeV~MK6b`!KNau8K3;=tKi(V4KIb)SKgmDPJ|5m_KayJ3J`#LrKl5wcKGY9qKdN)$ zK6II7KXGyBJ^>kIKL=&*K8=oIKPOJ~J}CNNKaec?KIU6rKL7v#Ki9KeKO5u%KMw+2 zKX<|fKcGfhKlYjkKc0bDKX+{lKOM7HKiWACKQY@>KL7v`KkxZcKgz!oKWqKiWACKOM7HKX+{lKc0bDKlYjkKcGfhKX<|fKMw+2KO5u%Ki9KeKL7v# zKjvFsKaec?J}CNNKPOJ~K8=oIKL=&*J^>kIKXGyBK6II7KdN)$KGY9qKl5wcJ`#Lr zKayJ3J|5m_KgmDPKIb)SKi(V4K3;=tKNau8K6b`!KeV~MJ|X{ZKLLEVK2I%hKS4IJ zKJ-v=KfLIwJ_BlUKev;lK5=++KYBNwJ}`WAKTOn@J~nlAKXq!6K6hhwKR)`3KI%qy zKkkEsK7=25Kb#MIK0NJsKTQm8J_)dSKZ5>YKH_J3Kh5S;KE4!tKf=XFKA5(9Kl7V9 zK4(pQKlN!XJ|)?FKU^>%KFe8sKfCV|K2^_sKd7h$KD;@8KXbS6J^h$|KLiujJreDH zKQm>!J^3|%KPs=FJ+E_rKNIqWJujwzKRRAkJ$cQ4Kj+RMJ&WmoKMHZyJY)KQKfiTW zJmBEq;Nalk;Gm$Opt-rZva+a#Jtg4a;Nalk;NbA^@bJ&i&&I~LkU}V+prD|jprD|+ zxw*N)!NIq;tcpM;@bK{P@bK{P&(F`#%*@Qe!L*M;D7m@0xw*NyxxvA~!NI}7x3{c{ zK_}18&(F`#&(F-v%*@Hj$-KOU3GyRVEwC;$Ke000000000000000000000000004N6s2L}fS2L}fS2L}fS z2L}fS2L}fS2L}fS2L}fS2L}fS2L}fS2L~t*7aSiVBqk>*Dl054E-x=JGBY$aHa9mp zIy*c)K0iM}LPJDFMn^{|6d@@vH90*%LPbYOOH58sQdL)3TU=gXVr6G(Yiw?Ca&>ok zdwhO?C>JL)JVQxOQ&(GFVPs}$Yj1OQd3=6>gNKWbk(8F1o1demsjRNCvm+caK~7m? zYjSvggourim6@NVtFW}Wy}-xK)7aeM<>>GA`xPNNPhoI+|~& zBR^JZdyAN*vAf02*52mr`WYWLOIvAmfQpiup{TC3xxUEI*WTsp@b&)?BtcnjfRLZ9 zxx~-e;_CAH3n@xxfS0Vl(c$s`2`f)-ile&EHq)$00000000000000000000000000RR90|NsC0|NsC0|NsC0 z{{R300000004V?|04V@c08#*Z0HgrO0Nwxq0000000000000000000f04V?|04V@_ z0DAy?0Hgq<0Pp|`0UH4)0Vx0}04V?|04V?|04V?|0DAy?0DAy?0Pq0t0Pp|`0SW;z z0X_jp0Z;*Z0DAy?0DAy?0DAy?0DA!N0Pq0t0Pp}Y0WkqF0X_jf0apQE0cHVg0q_9u z0Pq0t0Pq0t0Pq0t05JhE0WkqF0apQ60apQE0bc=f0eAs^0fPYm000000000000000 z0000000000000000000000;mG00;mG01yBW01yBb02Kfj0384#03-ka0000000000 z0000000000000000BRhKI8wVFItXdpI)d$2JBeemI|C{OJTTljJhVP{JRGB*Jkj#S zJpP99Je#W!Jq4{QJ%qwWJyYgnJrRk5J%^u@J7K9nC+KEFp|K90t4KCqX6K2lqUK41@zKA7c}K6%@o zK5*`)KG++tKKo#|J`uaWK1L_VKDVOKK6onGK9sxRJ`7XpKHlx}J_d>VKE4nFKOb5K zKO~yKbeC% zKQj|PKgEneKX>m$KYuz%KPPQVKhB0uKjnr|Kk;l-KaMz8KWXV%KSh6BKl=GzKXX}O zKd+r*Kf%UjKhM->KM}}jKhmIUKW<-bKTrg3KlG1qKjs2*KfPUZKOdoVKfld&KUd^- zKd|L@KbO*YKjW);KXY<=KPM-9Kj+GOKb>BDKQ-fgKb%>8KfS_zKZYNEKi+VDKdZNX zKhN}jKPD-EKZaF*KfZc@KbDz)Kg_a!KNQD*KOEP8KZ4_bKi%wqKeqFKKZ^K&Kgj!k zKi2(!KL`JRKc)YFKj{B|KmGrIKL7xLKL7v#00000000000000000000003H0OGQ68 zF(@J(6cP#m000000001PWLi{CM?pF>Ehiuv6bt|W00000c5Y`~R!~buK|3`sC?6LO z1ONa40DgCHXkS@VPDnyLHZLb284(Nt004%6cyec9TUAa-LOeDvDI*;h5DEd1iGqA_ zYh_n30Nvdv$MVVq8{GN<%$2F)Jh#0iv6fj)i}Db8Kc{T2xI( zK|3`r9s#VSo|un`gMD^zYGhtlQAmfIxsgfIxsifLu;oPh3t~Pjo4BC~_!-8iX2= z5upsQ3b6|qvoMM_hc<*YhB$>cgg1meazN>@i(NnJ`^N^K}|By}QnB99S~5|R_545bRP2fYTq2(bwlvNm%+W^ zTS;3^SyoV7LR~;+J7+v-JasgCEQ%wAA7LgQ(HnS zD3&3N9bzL*Dk^zkLToEz?iKmY&$J^%oKIR1hwWk(hFKL7v#000000000000000000OL5EB&_7#bTK z9UdPbAR!_mBP1jxB@X}q015yA00jU500000Kidzn+a0000000000000000Q&Xn%SSRQCL7leO*e|~>@g@T4NbdD6XzB>Z8Yepg_yPb;3kmoZEcyp1 z2^s?l`4naO1Oxag8UXPjL;@H7H!l7U1OF8eDF6Tf00000000000000000agY2L%8C z0ssIE94QU__YW!=4gvl?DfjjzLHq;y1VRV+5Dq5&ArRG5VgS`sV&K$MVo=pnVnEeX zVj$I1VuOH&jg5_wk&%|0o12@UprD|prmd~Ez_!4^z|FwT;6+_?c7uwIik6m}mYbla zpbvwJikq9Qtq?E(000000P*3|$GfkjnT~{ea%o^#P)I;IGAt$`9T*f43<(7S0LP_} zd~IM|GCF|NsC0|H4xlN8SJb|No*% zB0{47|Nqi{Nh>+6|NsBVeMc}lg8%>jrfx|&K4{Ya|NDDEH$-Hs{{R300000000000 z0000000000000000RR5|?hXS20RaF0{MsV}0s#R3{`$~61Ofp7|Ni#EM+yP~0RQ~# zw^9fK0RaE}>$F-C0s#R3_~5Hy9s~gZ|NiW)UnK_t0000000000000000000000000 z0000001yBG003h`BqSmvA|fIpQ$-{+B6Ma(L`1M=L_{J%RYX)Ibd8vcs)W0^*olPs zsJV-1W@JP}vf8=1s`S{qyQ=iNyW5Iqo4C1&bhn$Bh=kd=xT>VttDB4TskphSq}bou ziq?<3+Nku6h?}aYirm|aq}$5aiKx2vxr=nU+qsHlWQJsBB1A-FM5xQ%+Nh_Rh-gNn z_N$4DiJRKni`24|foxz^Qcq1iJ2^NrF)%GEDJUi+A|D|aQ9W6m>e3q-k;2tqcVR??Fy3yqm88k*+bdRRM+ZrN1OJR1Ar^4A8Avi`` zagU|M-xVS=NMUu6tHj0bCAvHi#b(pQp;Ts}BUu=P!uF~NY8c1VtgPO3&+afDHPF-@FvCZWd9X4Tnilej9 ziAO6t zi~s-s|ARs@LTkeR|E6?IH#L3#{{R3000000000000000000000000000RR5|^b7+6 z0RaF0{NN@70s#R3{`=861Ofp7|NivDMFau?0RQ{wxKsxM0RaF0@VZtG0s#R3{_nC| z9t8ma|M=svWD^1b00000000000000000000000000000000000000000c2)oL_{Pa zV5DoFxwN^9Wore;Y^XCwds000000Wbgn00000AVi0IcXww+Vnk<<+pGd)gRYJP~Ar@77H@Cp?qGCxmWZhnoO zt-a0N?GY3uGdoUMYkP*4q`1xC@CpwgGec2eaDk4Vt-Z|L><|+mBsfo7Y<7s6tGdkG?F$?$I!ak-c!!pyw8Ycm@dgkf zE<8(IYkP^Dskz72;R_QUEICS9X?cg3sk+MA>I@SdE;&b7WO#&>rMAb|=@AzrE;vnG zYI}y5r@74D?G6zwH9t#PYjcE`tGv$L@CgtdC^$!0XLpI3tG&(M?GO_rFgZ+DX?BE` zr@6}7>kbnnEj>(IYX(_XL5s;r@71A?GY9uDmqSGZhecJs=UtN@CXkgGDA~ibAytivcb{d?+p+sLP=I% zZ-9xGqqolC@evs%G(SsRW_N^;ps&Bw=Mx_>K~rRPg_EJKyU5k!@)933L|A8aeu|Z& zvB1yY?+_g?Jxp3^cZHLou))#b@DCLuGCfIFVQzPUjjzVq?MCx19xLNZ4j*QK7#u7e z3ff^v678Jy2JA2s3*(Tb1ns090t(-20{{R30000000000000000000000000019XF z4pzXW5849P2O_po1={+g z3L>^r1!O1?2Lk~B;J~1OU_c-M)vJJ2D*(-!W-|c5fItANRR93ZJOD5NAY=gW03ZNl z0Q23zwE*S-=$;AyfIt9v0PEdTV&vUZV%Ni_eQr_!%a#B@0QvX!_4Mk}%E`#Zu2MTV zH#RO73=0Yg2LJ#7000000000000000000000000009?wx*tXxA;+*Dq?0WRf{4@iG z3y2eB8D0N^eF0Hino07OUt0JL8K0IZ4t z0Dw3F0000006-rA0JtOo0PHLP0K7B+09-@>0H|RA0Dw3F0C7J6rFT$0FC!Zi4haMR zys(>!cVR;-8VUda000000N=^Cr+aMm{()EGHu$8yFQ55Dp9q2nGZL0s#Qh z(9X-p!MCW6Xi79C8x#%-1_S~C00000000000R8&(>D0ECgLrOYRY*KBC?FXV4-E?m z2nPlQ1OoyA0RAyUO;TNB#tRY{A0#dRE<#RMUTDw`6(A}zLjPW9ZE$mT_%%gPSYKuU z00IRG4ipIsoT_8UXaTObh_|)`BYr0Q~5!R~Q2T{qf6# zI1T~;{`TFcULyzr0RH*t!Gb{-1pxs6`|s1DV=WH^0RaE|^WVCIN+Ama0RaE}_2$Z+ zX*n1O0s#R3{rBtEvxHPE69)nT0RR5_@ZZFra782!1_A*9|Ni~;=h3i;T{jyG0|Eg6 z|Ni~_@7=_2LS;6_UFr=X*d@K0RaE_>(#S`RWB0-0RaF0 z^WDOqbw(u&0s#R3{`l(9tAJH776<|X0RR5_@Z7zXYeOUu1_A*9|Ni^)eaWCZAmK@3IqZH00000000000D%C{G63v>6ae+PND2V?)qyGo0Q%yo zR~rNX`{}}hJ`@B1`s~l3V=oZ{0RQmWwu4bA3jqNC{^`k|YdsVK0RaE`>CUQvRx%d{ z0RaE{?%BGOY(^&%1_1#7{PW_-rhr;F9t{Km0RQ~;=h3v1ZcHy33j_fG|NZ#w+rp!O zT|Olf2m=8C|Ni>%;?1#`tH-8QX>xq0Q%?4sDM~C83q9S?%27MY)2>(1OWZ>;m4+c zS~(vL0|5T^>D0HAZAmN_3IYKC`taYzrhr;HArJ-u0RQ{+=hC&3Zc8p137TYX(jdvkm7zOsZ@ zN+}Ki-@%=XYB?to0000003SJPpv}$y|NsC0|NsC0|Ns9*FGFvp&Hw-Z|NsC0|NsC0 z|58d%Uu}Sqpsmf#&EWt4;Q!!#N;^eijkf>)|NsC0|NsC0|E+UXNlaXGk*&?(;Q#;s z|NsA{hH++PW@~nRijkY9w!py6mf*IAWm8X8VR(_P&EWt4|NsC0;J}u6Wn5WZW_E_4 zw!q-v;Q!#@wws1_ZD?j{Z+3%`psj-d00000000000000000000000000000000000 z0DUtW5)TXu3JC}Y1_cBI0s#QVX)P8H3=0Yg2nPlQ1OoyA0M(*&Q#&gl7!nT*2?quR z0|Ef=yL3Ao5DN+k2nPlQ1OoyA0Q%*;hgLHl6AcOo1_cBI0s#Q|>(#lOfM-)eH7X$* z6%h>z0RH*w&ZKrtE*lUE2L%KJ0s#R3{rT_QznphfIVBel3I+rM0RR2__U+%xvzUBh zOE)MT6%PRa{{8pdqH04b91;u(1_T2F00;^U5C8xG0000005Ej`0B{!o03gx-{~*!- z{{R30000000000000000001EVANC*WAJ`wlAE+OQA7URm9||AX9-tm#9wHvx9grPD z9qt^K96B7>8*&>88=M*{8nhWY8N3)g7`7KK7oZjp7Je1z6iyVd6A%+_637uA5p)p7 z4;Bw(4z3OO3_uKo3&;uz3Q7rz2*w8j2R;UP1+oO{10n-j0+IpB0000s|8D-K{oec* z{7(Cb`oj7C_&WG@_qO)-^*Hr>^uY57^HTDh@#^q8@Qm-`?l|s}?eOeS?6T_^>w@a= z>0s&7=t}6s=S1hm=1k_+Sc^2><{9000000000000000 z000000000000092|Nj600RaF30096100001000000096100961000300s#O40RRC1 z|NRI42LJ#8{{jC3{sR63{Qv;~0sjL30{#R30{{U40003100000000000000000000 z00aO6000091P25F0}KZT1^@#92Lk{B3IGBI5(*3e0KEXH{b>SccXa?^|I+&ibTk0n z0I2qKZv6id0_yVRX3+ok0*vsbU9kU&19k5PQ=R|J1A^~nN0tA_1B>t{JDLB017Y&6 zE~Wnk1JCqcBDw!#0-^Vq7SjKz0ipV|3lsH~=2;T+DIW$@AOHXW000000000000000 z000000F-NI#1Q}t00;m90QUdt|Kk7P|LXq(04xAx0H^@-06hVH0j&YY0RR9100000 z000000000000000000000OVH%#RCBH|Lp(q{{jFR03`q!0Pz30|CRr-|1tn10dE4< z0|*7U1poj500000000000000000000000000Omf%#Pk0E02BZk00jWy|JDEe|3Ls+ z00#hL{|Nuo|4{-j1~dxC3}^xk$oBsy06GBD|E&Lb0Js3f{^R`w1q2m9BLDyZ00000 z00000000000000000000000000Efpt$v^;r0EYi005$;t{YU~cBt=CG0Du4z0CN8z z0gL~i{2LH^H~;_u000000000000000000000000004lH5$KmY(hKmY&$0B;h5I&Tt#JDQmpKh4a{JpcfJ zJDQmpJ^%m!H~;{EHwxDyJOBVdKmY&$Kmb4-MgRanKL7xLKDSa*VgXZ9V$)MnVgXZ9 zVm4G#VgXZ9Vz5+FVgXZ9VgXZ9VgXZ9VjxpeV$ICVJpcdzKmY)MH~;{Ez5oCKJOBUy zKL7v#H~;{kK>z@NJ^%oKJI&0@z5oEgKmY&$0Boaq2~U#>KmY)sK+Vj|J^%nfKW`F) zIx{nKKML0)JOBWIHwxDyz5oCKKo_@BI5RUdKc4S@K+Vj|J zKW1izKh4ZcJ^%nfKxSr!K4xa7Kbn~tKbo1DJ^%oKHvj;DKL7xLJ^=pzKF!QbJz@NJ^%m!KL7xLM*skTHvj+tIL*vVy_%Vs zKh4Zcz5oD#JI&0@y#N4!I?c>XKX=S4GOWd?HUI#CM*skTIRF5FL;wH)MgRbSMgRbS zMF0Q*K>z@NNB{tUIIP7dH(zjxFaQ7mz|6diD_?MlFaQ96KXUnhKXUnhzW@LL0001b z!~j4XNB{tUInB&WJ^%oKKL7v#0Boaq2~U#>KmY&$KL7v#0Q{-((oJGeKh4ZcJpcdz z0AFy4FaQ7mzyJUMKmY&$006O4VmGoe50MG{j05Ej`0MG{j0Qf2Z0O$h%0I)Uy0O$h% z00>e50MG{j0AOtZ0MG{j0N^eF0O$h%0GK)e0O$h%08mB%0MG{j0Ps}+0MG{j0Qf2Z z0O$h%0I)Uy0O$h%0BAx00O$h%00>e50MG{j0001hFOCaGUzSO5UXK^M1CIttgLJOBWoK>z^yMF0R$ zK>z@HMgRbaK>&a|MgRbCK>z@NJ^%m!zyJUM#{mBSMgRcFLI41IM*yGLKF!QbJ^%oKH~;_uH~;_u00000000000000000000KODf7KEKl>KGFcLJ+dD& zJ+aocJgq!8JWBGnJCRN}I{*Lx0000000000000000000000000000000000000000 z00000000000000000000000000000000961000000000000000009610096100031 z0000000IC200961000630000000IC200IC2000330{{R300RI300IC2000C50s{a5 z00aO400IC2000C50s{pA00aO400RI3000C50s{pG00jU500RI3000I70s{mE2LJ#7 zH~;_uK>z>%KmY&$KmLL%Wk(hFKL7v#0000000000#{mBSMgRZ+M*si-0000000000 z00000000000096100IC200aO400sa600;m8015yA01N;C01f~E01yBG02BZK02lxO z02}}S03ZMW04M+e05AXm05|{u07L))08jt`0AK(B0C)fZ0H6Q>0LTCU0000000000 z00IC200aO400sa600;m8015yA01N;C01f~E01yBG02BZK02lxO02}}S03ZMW04M+e z05AXm05|{u07L))08jt`0AK(B0C)fZ00000000000000000000000000OndWICoAn zIn&w6Ig*hxI?P~TJT(Uh zJrK+hJTJ>d6` zJ&NU)J$w0`J+U*TJt323KkDmEKY2b+ zKaY)2KP%Z$KOG@cKXYYNKMkf;KkMRFKl~e5KQB>PKXZawKgq9KKMvVkKSTaqKUg1M zKTAAdKm1f-KWb@WKZSW?KRktGKcI|dKYov9Kh}+BKe~r#KlXfSKb&o9KZ;pvKhZ#J zKTjiVKLi18Kk?aaKl80`KOB8wKeWtpKk$chKM+22KNIhCKl++=KeIu0 zKR@GkKaGEPKdlycKYplqKLIs)KQz2~KNvoGKb^XIKf*D4KX;>hKf4cnKc9AdKLXf% zKlC$wKV^!2KSbMoKeHx&KaXsFKkKZ1KcnYy)-b=J^Jm7KF}q!J_)6tKKQ9B zK3ee&z0Is;zLzK7Bo>KGKT{ zKGKT{zI{EXzI{EXzS4^dzS4^dK7Bo>J_)6tK3ee&J^Jm7zLzz0Is;KF}q! zKKQ9BKKQ9BzR)GKzRj#J(oGHKKkv8K3ee&y$PkCz8iyz>%02Wr~p05MaJfv`aKaaxoJPm9WIsgCw0GgSZ znVFfnKPYQ%P5=O)K>z^oK>z@dK>z>{LCwreKL7xLJTBtqmCKCB!{KHVj8J~XdKbyv8 zKX0IDKlfN_KY;RUKi_U`KMT-qKgt(yKj24kKjC3=KTT(IKbBc^KMXo`KmQ4KKZ?qB zKf8Q)Kfob)KVrIgKb=Q;KTFDaKO{qXKk~AAKRX(GKgfA|KOoY3Kgc6|KR0iDKk~GE zKVJ2GKj1KZKkR3HKew8FKeWkxKL+)EKM@^%KNv!OKTc$RKhuMLKmDM7Kkd7IKf~01 zKeOw8Kkop4KZg{5KaD1TKSMWvKdMH5KjTz?KM!JmKQC^7KV*4-KfZ&1KR=CsKNyyO zKRBL$KfKWxl@KU>g$KL*r)KX2E6KZDwT zKW5#3KNaAAKZ4?aKh5NSKj!9tKh5ZWKa%QyKSu0-KgjKWKPc~iKX~weKc?}2Kg05W zKfm*TKf3gPKa}-?lKmGWBKa}}@KMDGOKY#jvKlJ*4KUw>K zKdt+JKLPxIKUDmGKbZV~Kim9&KOX&mKT!RDKZ5;#KehdTKj-~_KMDSSKRf<^KVANR zKYspyKac)@Kd}CPKhpkxKjZ#?KlJ{8KNbIfKPLZwKR5q>KS%$6KUn{NKUn{NKWYDe zKYIUvKYIUvKa2l=Kb!x5Kb!x5Kb!x5Kdk?MKdk?MKfV8dKfV8dKfV8dKhFPuKhFPu zKhFPuKhFPuKhFPuKi>a;Ki>a;Ki>a;Ki>a;Ki>a;Ki>a;Kkxs4Kkxs4Kkxs4Kkxs4 zKkxs4Kkxs4Kkxs4Kkxs4Kkxs4Kkxs4Kkxs4Kkxs4Kkxs4KL7xLKL7xLKL7xLKL7xL zKL7xLKL7xLKL7xLKL7xLKL7xLKL7xLKL7xLKL7v#K>z>%!2kfrK>z>%KML0)Jpcdz z0000000RI30Ic{^V!-%QVi^Dc01p5F00IC2000000000001m#uy{sRbzLkO+zm}Co zzEpBPzLEnPzXq5-y#k=>y|ydVy}5E8ziPgsz8nWGzH9T3y;`0ZJ|V5qJ_=?GKYcvB zJ`^GSzK^LxKL~g0zY6m%K6R5!K~PhRzijNHzqJ*D!5nMBL84-^!2jnkzAsNFzMjry zzW-Oky_-Chz03HAzARzQy~`m}y+EcFzV0LUy`cR#zT2k*KIvcLKGn+nz8%XeKIf=Y zJ^@ckzV`#xK1X-JKdt#izd)oQ!7IYeKESd*K*@GJZk&bJ)e$4K!`?@KRGCYzeif?zl&5yzG`zaz0%f!I-z7@KAzGMK7iNvKHUt@K70=Y zKl<`=zBh|^J}+*wKDP}szldWdK@z1YKvU2gz%>Vkz<3zFEO9zoY5A zK0q?{KK=DNKBITiz6g+EKPPLGz#$*JKj8DLKB3m=zx7-3!3eCeK>V@)I%*aDy(RUO zy(wmcz5MA~y(5O*y%hPsy({gGy-Ta%yr=9$zItxqy{sIPK544Yz6Z;_JtJk4zRBlV zzx=|>z0_ZCzHfn~zYT1WKby%%K)WZ8y+T{=zj4VaKzQ!yz#6C=K!=Kwx;B`By?-GZ zy^3-fzU5>RKKIHzK5@$YJ$2lgJw`$BJ;*4(Jx9TfJrK zz6jsoJiFcuJ&2}9yS;y=5Guz7?yczH8GsKC2&q zy|$JnuM%JE|L=yyCH6KBBVWz3ig_z@-suKO6`hz=i{vKe$$V zy)Y8?zq-JkKCH_AJ}QuDKW0l-K9d+0z+YYrKqnN>z>rSaKdGTPzi`?@JWb9TJ#Fh^ zJ#B)yJo7`4yrKF^^%J~DJHztCQ7KGhv? zy+KNBKGsEK!131zKyZKhhjczjuTqKta_! zKNDuIzugHkzeidez&@_szk~XGK+OU2KV{(fK1*3O!GM!+O8HB}zJ49}JzgwmzxfnA zKr_VAKj;5pKLXWXKP}IjKQ7{5zoxdNK3(}pKcG=^KZZ9Gzdp-dz#@raKdnB!J&=PQ z!E{~7J__<9KB_AN!0@MpK++bBJvuxTzIzaozC|p;K6FNuzo#AJyqcLE!4O@Vz%!?9 zK#SmaKpLZAKmY&$0000003cdZVohmoXLl`kHZ&k|b#8QNZDk;4VQFl2a%DOS06}DA za%FRKASG}hXkl|8Zf_uIZDD6+EpugKbZKvH03aY%X>xRRVQf)#Wpa5SW?^Y;Wn>^` zZ*m|dWFTUBbY*iOVRRs2WMpz>b8{diZ~y=R03aY%X>xRRVQf%xZ**m2bRcG7X>4U= zAa`kWXdq*6WMv>QcqMoM03aY$ZfkCDcWxkXb7gg8Zy<7IY;R*>bZKvHAaHVTbZ=vC zY#?@Ja&u{KZXhLOE(!nu03aY$ZfkCDcWxkXb7gg8Zy<7IY;R*>bZKvHAYy5BAaiMY zWgsPFE(!nu03b6|Vn8rdVsmkFbN~PV0002M{{R5Me*gf0e`R=Z0001hfA2Z^{z5K> zKv6I))euRCz-(`40001h{{R5Me*gf0e`9ZR0002Me{gSi0002Me*gf${{R4hKL7xL ze*gf0{{R30KL7v#0002M|NsBrK>z>%&j0`b0AF8lZ+B?`0002M{{R5Me*gf0e*gf0 z|5a{lZf|#PAZ2oLZ*l+t0AFokbZBLAawsV}ASH7kX>K4Tb0{TeEFdLkDIg#ya%FUO zVQf7mXDJE*06}tRb!}yCbRcAJZDDC{AZ2oLZ*m|gL{CjYNlqyML2_qxZDnqBAaiMM zXLW30a%psVAShEwM@}gK08e&ha%OCAcOY_MZf9j6WpZ+Fav&&ARz*@qOix!S090sY zAaZ4Mb!>DXX>%ZSZ*L%TZDDL|AarjaVr3w5WpHw3b7gLHWn>^IRZc`jQbtTqS1AAh z090>uVQe65Z*y}XZ)PBKX=iR}W@%$#ZewL2C{#>OQ&TAb08n9abZKF1AZ%}Qb0BYK zAaiMFZfRy|V_|M%WgsX}Oixo&DF6Tf04xDiVoL#3VrT(WVu%4$V!#1ZV&nl-Vn;(m zIv^-VPE{!&G%h$UF(5K9F*7hVGch12MrCAga$z7%X>LbXAT%yGE-@`LE@opgFev~4 z07pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opg zFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21K zE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yG zE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbX zAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7% zX>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAg za$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5 zMrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kR zF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTA zF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$U zG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!& zG%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-V zPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZ zIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~4 z07pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opg zFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21K zE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yG zE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbX zAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7% zX>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAg za$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5 zMrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kR zF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTA zF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$U zG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!& zG%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-V zPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZ zIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~4 z07pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opg zFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21K zE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yG zE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbX zAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7% zX>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAg za$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5 zMrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kR zF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTA zF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$U zG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!& zG%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-V zPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZ zIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~4 z07pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opg zFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21K zE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yG zE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbX zAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7% zX>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAg za$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5 zMrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kR zF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTA zF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$U zG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!& zG%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-V zPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZ zIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~4 z07pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opg zFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21K zE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yG zE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbX zAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7% zX>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAg za$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5 zMrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kR zF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTA zF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$U zG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!& zG%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-V zPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZ zIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~4 z07pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opg zFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21K zE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yG zE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbX zAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7% zX>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAg za$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5 zMrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kR zF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTA zF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$U zG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!& zG%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-V zPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZ zIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~4 z07pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opg zFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21K zE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yG zE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbX zAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7% zX>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAg za$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5 zMrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kR zF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTA zF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$U zG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!& zG%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-V zPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZ zIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~4 z07pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opg zFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21K zE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yG zE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbX zAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7% zX>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAg za$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5 zMrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kR zF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTA zF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$U zG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!& zG%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-V zPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZ zIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~4 z07pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opg zFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21K zE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yG zE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbX zAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7% zX>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAg za$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5 zMrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kR zF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTA zF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$U zG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!& zG%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-V zPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZ zIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~4 z07pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opg zFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21K zE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yG zE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbX zAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7% zX>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAg za$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5 zMrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kR zF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTA zF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$U zG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!& zG%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZIv^-V zPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~407pYZ zIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opgFev~4 z07pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21KE@opg zFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yGE;21K zE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbXAT%yG zE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7%X>LbX zAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MrCAga$z7% zX>LbXAT%yGE;21KE@opgFev~407pYZIv^-VPE{!&G%h$UG9WTAF*7kRF*YD5MgagO z|Jh|^Z*pNEO=)gNS0FSlI4&|RF)n6fGB7Cs002irLpmTRM^05KAT%yGE-@f7FflVQ zH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs002irLpmTRM^05KAT%yGE-@f7 zFflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs002irLpmTRM^05KAT%yG zE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs002irLpmTRM^05K zAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs002irLpmTR zM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs002ir zLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs z002irLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOh zGB7Cs002irLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_Q zGcIOhGB7Cs002irLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSl zI4&_QGcIOhGB7Cs002irLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gN zS0FSlI4&_QGcIOhGB7Cs002irLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNE zO=)gNS0FSlI4&_QGcIOhGB7Cs002irLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&u zZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs002irLpmTRM^05KAT%yGE;1l8FflVRFfleD zC`M&uZ*pNEO=)gNS0FSlI4&|RF)n6fGB7Cs002irLpmTRM^05KAT%yGE-@f7FflVQ zH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs002irLpmTRM^05KAT%yGE-@f7 zFflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs002irLpmTRM^05KAT%yG zE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs002irLpmTRM^05K zAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs002irLpmTR zM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs002ir zLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOhGB7Cs z002irLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_QGcIOh zGB7Cs002irLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSlI4&_Q zGcIOhGB7Cs002irLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gNS0FSl zI4&_QGcIOhGB7Cs002irLpmTRM^05KAT%yGE-@f7FflVQH8U|FC`M&uZ*pNEO=)gN zS0FSlI4&_QGcIOhGB7Cs002irLpmTRM^05KAT%yGE;1l8FflVRFfleDC`M&uZ*pNE zO=)gNS0FSlI4&|RF)n6fGB7Cs0000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z0000000000000000000000000000000000000000007Vv&r$#Y0025d1ONd5001=r z001=r001aJ1OWU%1OU)M1OULd0syeM0s!!@0syeE0sxS*0s!#20sxS%0syeC0sz4K z0szqb0suh90sx@>0sx=}0{~FN0swHs0sz28006Kv0|4+d0|3A)0|3A*0{}2I0{|c@ z0|0<30{|c+0|4M60{{>q0{~zn0|3A%0{|c%0{}1|0|1aa0|2l*0{{Rb0|0;?0|0Oz z0|2110ss)X0st_%0swHi0s!!`0sufd0{}3f0ss&@0|0QB0swF|0{}oZ0{~z(0|1aU z0{|d30{}2J0|4+j0|1~o0|1~!002lr1OQY*1OR421OR$M1OSUd1OT8y1OU831OU=P z1OVhh1OV_t1ONg<1OOI81OO*P1OPlk1OQS)1OQ}11OR+P1OSvn1OT!_1OU=Q1OV?t z1OO031OPHb1OQM(1ORA61OSFa1OTQ)1OUTC1OVhj1ONs_1OOyO1OPxq1OQ$|1OSIc z1OT!{1OVAZ1OW3z1ON|41OO>U1OP-v1OR461ORqM1OSLe1OS>w1OTl@1OUTE1OVJd z1OWC%1OOIC1OPEd1OP}!1OQ$~1OR$R1ONa40RRF30{{d71po#B2LK2F2>=QJ3jhoN z4FC=R4*(DV5dabZ695zd6#y0h7XTOl82}mp8vq;t9RMBx9{?Z#Apjx(BLE}-B>*M> zCjck_DF7+}D*!A2EdVY6F90wAF#s|EGXOLIY-wU|aCLJnFfL?lYyfX?b#q^2Wn*t- zWdLt*b#q^2Wn*t-WnX4&Z((!*Z*X;UUu0!tZ)9b1Ut@A*VRU5xZ*X;UUu0!tZ)9b1 zUt@G^0B>-0b6;d-V{c?-a$jU+b98cVc>r&4b#q^2Wn*t-WpZCbO3K~b#q^3Zewp` zWdLt*b#q^3Zewp`WnX4&Z((!*Z*X;UUuAA%Z)9b1Ut@A*VRU5xZ*X;UUuAA%Z)9b1 zUt@G^0B>-0b6;g{V{c?-a$jU+b98cVc>r&4b#q^3Zewp`WpZCbO3K~b#q^5WprP5WpZ<-b#q^Bb!>ELb98cL zVQpVzWn*t-WdLt*b#q^Bb!>ELb98cLVQpVzWn*t-WnX4&Z((!*Z*X;UUu|`4bZK*R za%Ev{Uu0!tZ)9b1Ut@A*VRU5xZ*X;UUu|`4bZK*Ra%Ev{Uu0!tZ)9b1Ut@G^0B>-0 zb6;(BY;r&4b#q^Bb!>ELb98cLVQpVzWn*t- zWpZCbO3K~b#q^Bb!>EL zb98cLVQpV!Zewp`WdLt*b#q^Bb!>ELb98cLVQpV!Zewp`WnX4&Z((!*Z*X;UUu|`4 zbZK*Ra%Ev{UuAA%Z)9b1Ut@A*VRU5xZ*X;UUu|`4bZK*Ra%Ev{UuAA%Z)9b1Ut@G^ z0B>-0b6;(BY;V{c?-a$jU+b98cVc>r&4b#q^Bb!>ELb98cLVQpV! zZewp`WpZCbO3K~b#q^B zb!>ELb98cLVQpVELb98cLVQpV0B>-0b6;(BY;WprO>WprO+VQyr1X=HS00B>-0b6;>_ zV{2t}UuR`>Uv6SwV`yP+Ze?t90B>-0b6;>_V{2t}UuR`>Uv6SwW^!R|Wpe;;aCLKE zaA9L>WprO>WprO|VqbG%ZE$R5a{zB}b#q^EVPk7$bYEv>bYF8}ZE$R5b6;>}a$jb0 zVQpmqZ*X;UUvOb#Yh`p_aA9NsZ*X;UUvOb#Yh`p_aA9(DWdLt*b#q^EVPk7$bYFFD zaA9NsZ*X;UUvOh>UvqC}bYEj^X>b5-0b6;|0 zaA9L>WprtJWpZC*a%Ew3WdLt*b#q^GWpH6*Yh`q4dS!B7WMy-7a&LJ6Z*X;UUvgz| zVPk7$bZL5Ja$jdbO3K~b#q^GWpH6*Yh`q4dS!B7Z*_D4Z*X;UUvgz| zVPk7$bZL5Ja$j$CbYF5|Zf9ixZ*X;UUvqSFWpZ+FasU7T00000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z000000000000000000000000000000000000000000000000000000000000002Bt z1ONa400000007if1OWI@1OS*&1ONa400000002N$1OQY~1ONa4000000000000000 z00000006X61OUuY1OVhw1OWI^1ON_F1OOyb1OPNr1OP}<1OQr61ORkW1OS9m1OT8? z1OUEL1OU`h1OV((1ONt81OOyc1OO~k1OPx&1OQG`1ORGN1OR+f1ONa4004|r1OS>- z1OTp61OU8K1OUcU1OU=g1OVDo1OVbw1OV()1OWC^1ONb31ON(D1OO6L1OOaV1OOyd z1OP5n1OPZx1OP%*1OQA_1OQf41OQ-E1ORAM1ORYU1ONa4006X61OUuY1OVhw1OWI^ z1ON_F1OOyb1OPNr1OP}<1OQr61ORkW1OS9m1OT8?1OUEL1OU`h1OV((1ONt81OOyc z1OO~k1OPx&1OQG`1ORGN1OR+f1ONa4004|r1OS>-1OTp61OU8K1OUcU1OU=g1OVDo z1OVbw1OV()1OWC^1ONb31ON(D1OO6L1OOaV1OOyd1OP5n1OPZx1OP%*1OQA_1OQf4 z1OQ-E1ORAM1ORYU1ONa4007hgL}hGcbY(+wX>@60VQf=nV{~b6ZUFB9MQ(Iuazk=y zbZKK@Y*S@pbZKvH006`RM`d(Fb#iiLZgfy`Z)0V1a{$EwM`d(Fb#iiLZgfy`Z)0V1 zb4g?X$pJ@YbVGG=a%FCGRA_Q#VPr{U00095M`d(OVRLjva&m8S000#NM`d(PZ)A0B zWk_LeWNc+Y002b-M`d(Sa&KcnWMpz>b8`RydjdygbW?eAbY*Q+X>Daeb4F=wWmIWx zWdN4~M`d(WX=7_cZ*^{T008R(Np5L$X<=+>dSyd$X>@60VQf=nV{~b6ZUFKENp5sy za%^v7Yh`3ZZ*6d4a%Dw$V`yP+XJr5Y^a4q4bY*gEZ)0m^WJP#mXkl(=WdJ4vOl4tq zWkYglbZKK@Y*S@pbZKvH005H%QFUc zVQyq>Wn@KoV`Xr3X>V>uX>4?5asYG$Q*32rZ~%e?RAq8)X>MV3Wl(Z&V`X!5004;u zRBUrcWpq|yY;|P-mIPI9Xkl(-Y-MCccw=R7bZKvHMrmwxWpV%jwggsba&&cJY*2D< zbY)|7006lJR%vo{bzy8#b!BpS001`tUteTwY;SI5cxiM1YXDzgb7gdOb7gXEVRUF^ za&iCwjsRa_ZF6T|Wq4_H007VcUuAM~Zf^hpFacj_ZfSIMWpZr*Gyz{}Z(;xdl>uLD zZ)0l!G6G+3Ze@6BbO7)IUv+M5Z)0l!P6K0MY;131003wMW^i(8ZggeWn};W zdIM&6a%psB005-}Y;R{VFaV|lZDDL|Z({%et^;jlZDVkG006H8ZDnn3Z+2w>u>);o zZF6OG007+sb98cSWo`ff-~)4Xa&BX7Z~#CAVPbD`bO1&KVRT_`G5}r#c4lyLX>N38 z0000`1ONa~1ONa~1ONa~1ONa~1ONa~1ONa~1ONa~1ONa~1ONa~1ONa~1ONa~1ONa~ z1ONa~1ONa~1ONa~1ONa~1ONa~1ONa~1ONa~1ONa~1ONa~1OQ7#QcguoGcqn@Y-|7k z000zF1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ z1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1OOCJ1ORPwc4KmME@W(M z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z0000000000000000000000000000000000000000000000000GP+|Z800000001Cb zQ)19rQ(^!B0000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000001RRAL-(RALY?RALxlRAK-C000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000G003wJ0012@A}~=fVlZbgZ7`BBpfK7n<1iC3BQY^CJ~31=crlnU zt1;Oz<1y_q05S$LJ2F8sR5DvKVKRs^k20Dv!!pV;12cIvu{6Ro$TZwENyTO96Mb*T0E;f@H`$pK0Q=Dsy#41Qa)Hd zUOwJG0001h004LZ000CqJur(fvM|Ch$S~M2Krx>&;4&vOGc(aMLNrJ;PBdaPhBTBk zq%^@a6*cEI2R1)8mNvpR?lv4ZNjFhAU^q}Z_B#4IOFYm#^*qEq(>>um@;x6uH9kE) zNj_LUWV&M8abyt0001>000;O z005gYqcN2;r!(p|J~$IU00026001Ze006r%7&WamO*eWs%sSyZEjw2`yF1f68a!7# z<2>y=OFaO<000aC008 zU^3-0^D;LxSTiOxKr~7@sX7xoayz{{#yinF>pSy1!aO8BEIk@N0002+001Na007fB z-Zz{$$~gEq@j22vkv!Kt-8}Ls5&o=uu$2aRYUN~(yl|BFv0RSif003q)r5H|!kU^opq8#%N&LppRi z$U0v;Wjg>M0RRvH006x-lr@<*0000m0RS`r008PZNja7|(K-A%Dmwl;96Mw?mpczU zF+7JntUSp)`8+W_Q$2b;s67Ne0Y3mh0RS8T002!eQZSJ)dohbK!7;`$-ZAYl5H$c$ z0RRjD007N70001B0RTV%002WZZ8erP#xpLJkhCHJ@|2!r=#Xadg0001R0RT7v006f!zA@Y}@-g`_6*3|+Z8CH+k}{|= zu`0RRjD003(|hdcnV z0RVsi008tgpEuxjeo+9z7;K0002+0RSif005XVzcFevZ!?-R5H#X69W?0000W0suGw002BUM>kzJZa0WGnK!C8!8e0CjXJ72u{uLOeLk2z z#6HYEGe2oRl0UIO(LeD&0000m0stHU001N~E;UFsU^Z$tcs7nUJ~|OS0000$0st@o z003(;!ZV0BygAu9S30jc;5zO)KRbOpgF6pB9zHETJ3di9aXybep*{dm0swFT0018_ zGB83gUod4baWJzoZZ>o_zBa@*7B@jRM>knFUpJyRt~a_j;WzX*{Wo7YoH*Dx-Z%+4 zDLG0xUO8$xd^xB&D?4&LXgzX0oju1r&pq-z1wIWv89q2ZUp}QiB0o1jJwH!B0001B z0sve9006Qu&oCu1#4*${5;7Pv9x_5QS2ABRYchv2jWU5V*fZoa>@ylQAT=B}A~z^E zGB<)Zu{T6GemIIamN=j|s5rkk#W>42=r}VuKRIVPEIP$J0001R0su4s008wcY%$6) z0ss&I z008eaV>Wg>d^-TJ0strg007r8L^x77d^o#09y7^C_PF&+&%I=89q2Z0002c z0st%k0062qur${;>NX%ZCO5)6@;fCxFg;8?Zas)S<~^l9*+1ex^gjUL0ss^M0056L zlrSqYygI}>0002+0st@o001vBLNRqQoinR5lQ!2jC^uF&z&Y7DGCDmvNIFwG>pM$4 zlRN}HJv{&b0{{>J0031ur8wp|`8WU&0{|ER004k6mN6nSHZn*u#XieE0000W0{|QV z002)gS}J007@JA2dxr+dlw60|4Lv006@<#xc+_ z^)df35;7t(Try}ff-;OUw=%&p)H38U{xU){k~5eyq%#&YA~ZZSMl@_Rd^CbIpftZU z$u!e60yPXZIyFi)P&INj!!^$}<~8g!3N{-yAvQfWP&QmPsW$F5OgC0Hzc-j3NoECr!vDb*fJ+Gcr$`Csx!1RzBBbR zXg0Jq;5O^Jr|FgQIp^*9?jEIDU6e>s^sCOR`ZQaV^VZ93ID@H!1U zKs!-8k~_CM!8`RkMLbG`$v^Ht0001B0{{R4 z000m$CNMfMQ7~gLZ!m^1mN2C-zcA7;;xPI!7BMO@J268sOfg$AeldeFt}(PRzA?u! z%rV4+p zZ!?rLnlrgGzcb7;_A>@F4>TGyB{VBEH8ejoQ#4sL9W^mEKQ%=)Of{)Bxi!r-(lz!q z12z#h7&az0IW|W&O*T|ElQy9?uQtUt)Hdig?KUenK{rn~RX1ceb2p+lfH<)@(m3=u zG&x2&e>sym!8rgrD>^+oojOE2TRUw#n>(&Mz&kEHKs=Q^dp)u}cRm1c0{~0{|cZ006)_)H&EW+&Snu>^bl`^f~xB06GLZ2s!|;0{|ER008VU@G&ehFfwd1 za5AhiurdJ90{}n(001O2C^IZGcr$!6fHTN6%rww6)HK*M+%#x4Y&CE-bTxQ2d^LbI zs5q=RusF0hxH!Bxz&PAJ;5`7~0|00M008JX>^Sf^^f>r9{5SwP1UU#f3^@=vs5-1V zusXClxH`N#z&gY_$U4kA&^pvQ*gD)g;5y_w=sN5=@H+H5_&WSL06PRb2s;cr5IYn* z7&{z0AUh;GC_5}WFgr9mI6DCF0{{>J005*os5oFh000001OONS003MtU@#0a5Hb`p z7&06(ATj`81ON~K000ay7%&_#0001R1ON~K000Cq2rvvV5HJ7$000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 z00000000000000000000000000000000000000000000000000000000000000000 J00000005sre0u-@ diff --git a/src/Discord.Net/API/Auth.cs b/src/Discord.Net/API/Auth.cs new file mode 100644 index 000000000..ce62d8eb2 --- /dev/null +++ b/src/Discord.Net/API/Auth.cs @@ -0,0 +1,29 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; + +namespace Discord.API +{ + //Gateway + public class GatewayResponse + { + [JsonProperty("url")] + public string Url; + } + + //Login + public sealed class LoginRequest + { + [JsonProperty("email")] + public string Email; + [JsonProperty("password")] + public string Password; + } + public sealed class LoginResponse + { + [JsonProperty("token")] + public string Token; + } +} diff --git a/src/Discord.Net/API/Bans.cs b/src/Discord.Net/API/Bans.cs new file mode 100644 index 000000000..54dfa1518 --- /dev/null +++ b/src/Discord.Net/API/Bans.cs @@ -0,0 +1,6 @@ +namespace Discord.API +{ + //Events + internal sealed class BanAddEvent : MemberReference { } + internal sealed class BanRemoveEvent : MemberReference { } +} diff --git a/src/Discord.Net/API/Channels.cs b/src/Discord.Net/API/Channels.cs new file mode 100644 index 000000000..030bda73d --- /dev/null +++ b/src/Discord.Net/API/Channels.cs @@ -0,0 +1,100 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; +using System.Collections; +using System.Collections.Generic; + +namespace Discord.API +{ + //Common + public class ChannelReference + { + [JsonProperty("id")] + public string Id; + [JsonProperty("guild_id")] + public string GuildId; + [JsonProperty("name")] + public string Name; + [JsonProperty("type")] + public string Type; + } + public class ChannelInfo : ChannelReference + { + public sealed class PermissionOverwrite + { + [JsonProperty("type")] + public string Type; + [JsonProperty("id")] + public string Id; + [JsonProperty("deny")] + public uint Deny; + [JsonProperty("allow")] + public uint Allow; + } + + [JsonProperty("last_message_id")] + public string LastMessageId; + [JsonProperty("is_private")] + public bool IsPrivate; + [JsonProperty("position")] + public int? Position; + [JsonProperty(PropertyName = "topic")] + public string Topic; + [JsonProperty("permission_overwrites")] + public PermissionOverwrite[] PermissionOverwrites; + [JsonProperty("recipient")] + public UserReference Recipient; + } + + //Create + public class CreateChannelRequest + { + [JsonProperty("name")] + public string Name; + [JsonProperty("type")] + public string Type; + } + public class CreatePMChannelRequest + { + [JsonProperty("recipient_id")] + public string RecipientId; + } + public class CreateChannelResponse : ChannelInfo { } + + //Edit + public class EditChannelRequest + { + [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] + public string Name; + [JsonProperty("topic", NullValueHandling = NullValueHandling.Ignore)] + public string Topic; + } + public class EditChannelResponse : ChannelInfo { } + + //Destroy + public class DestroyChannelResponse : ChannelInfo { } + + //Reorder + public class ReorderChannelsRequest : IEnumerable + { + public sealed class Channel + { + [JsonProperty("id")] + public string Id; + [JsonProperty("position")] + public uint Position; + } + private IEnumerable _channels; + public ReorderChannelsRequest(IEnumerable channels) { _channels = channels; } + + public IEnumerator GetEnumerator() => _channels.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => _channels.GetEnumerator(); + } + + //Events + internal sealed class ChannelCreateEvent : ChannelInfo { } + internal sealed class ChannelDeleteEvent : ChannelInfo { } + internal sealed class ChannelUpdateEvent : ChannelInfo { } +} diff --git a/src/Discord.Net/API/Common.cs b/src/Discord.Net/API/Common.cs deleted file mode 100644 index 9885b3cd5..000000000 --- a/src/Discord.Net/API/Common.cs +++ /dev/null @@ -1,318 +0,0 @@ -//Ignore unused/unassigned variable warnings -#pragma warning disable CS0649 -#pragma warning disable CS0169 - -using Newtonsoft.Json; -using System; - -namespace Discord.API -{ - //User - public class UserReference - { - [JsonProperty("username")] - public string Username; - [JsonProperty("id")] - public string Id; - [JsonProperty("discriminator")] - public string Discriminator; - [JsonProperty("avatar")] - public string Avatar; - } - public class SelfUserInfo : UserReference - { - [JsonProperty("email")] - public string Email; - [JsonProperty("verified")] - public bool IsVerified; - } - - //Members - public class MemberReference - { - [JsonProperty("user_id")] - public string UserId; - [JsonProperty("guild_id")] - public string GuildId; - - [JsonProperty("user")] - private UserReference _user; - public UserReference User - { - get { return _user; } - set - { - _user = value; - UserId = User.Id; - } - } - } - public class MemberInfo : MemberReference - { - [JsonProperty("joined_at")] - public DateTime? JoinedAt; - [JsonProperty("roles")] - public string[] Roles; - } - public class ExtendedMemberInfo : MemberInfo - { - [JsonProperty("mute")] - public bool? IsServerMuted; - [JsonProperty("deaf")] - public bool? IsServerDeafened; - } - public class PresenceMemberInfo : MemberReference - { - [JsonProperty("game_id")] - public string GameId; - [JsonProperty("status")] - public string Status; - } - public class VoiceMemberInfo : MemberReference - { - [JsonProperty("channel_id")] - public string ChannelId; - [JsonProperty("session_id")] - public string SessionId; - [JsonProperty("token")] - public string Token; - - [JsonProperty("self_mute")] - public bool? IsSelfMuted; - [JsonProperty("self_deaf")] - public bool? IsSelfDeafened; - [JsonProperty("mute")] - public bool? IsServerMuted; - [JsonProperty("deaf")] - public bool? IsServerDeafened; - [JsonProperty("suppress")] - public bool? IsServerSuppressed; - } - - //Channels - public class ChannelReference - { - [JsonProperty("id")] - public string Id; - [JsonProperty("guild_id")] - public string GuildId; - [JsonProperty("name")] - public string Name; - [JsonProperty("type")] - public string Type; - } - public class ChannelInfo : ChannelReference - { - public sealed class PermissionOverwrite - { - [JsonProperty("type")] - public string Type; - [JsonProperty("id")] - public string Id; - [JsonProperty("deny")] - public uint Deny; - [JsonProperty("allow")] - public uint Allow; - } - - [JsonProperty("last_message_id")] - public string LastMessageId; - [JsonProperty("is_private")] - public bool IsPrivate; - [JsonProperty("position")] - public int? Position; - [JsonProperty(PropertyName = "topic")] - public string Topic; - [JsonProperty("permission_overwrites")] - public PermissionOverwrite[] PermissionOverwrites; - [JsonProperty("recipient")] - public UserReference Recipient; - } - - //Guilds (Servers) - public class GuildReference - { - [JsonProperty("id")] - public string Id; - [JsonProperty("name")] - public string Name; - } - public class GuildInfo : GuildReference - { - [JsonProperty("afk_channel_id")] - public string AFKChannelId; - [JsonProperty("afk_timeout")] - public int AFKTimeout; - [JsonProperty("embed_channel_id")] - public string EmbedChannelId; - [JsonProperty("embed_enabled")] - public bool EmbedEnabled; - [JsonProperty("icon")] - public string Icon; - [JsonProperty("joined_at")] - public DateTime? JoinedAt; - [JsonProperty("owner_id")] - public string OwnerId; - [JsonProperty("region")] - public string Region; - [JsonProperty("roles")] - public RoleInfo[] Roles; - } - public class ExtendedGuildInfo : GuildInfo - { - [JsonProperty("channels")] - public ChannelInfo[] Channels; - [JsonProperty("members")] - public ExtendedMemberInfo[] Members; - [JsonProperty("presences")] - public PresenceMemberInfo[] Presences; - [JsonProperty("voice_states")] - public VoiceMemberInfo[] VoiceStates; - [JsonProperty("unavailable")] - public bool Unavailable; - } - - //Messages - public class MessageReference - { - [JsonProperty("id")] - public string Id; - [JsonProperty("channel_id")] - public string ChannelId; - [JsonProperty("message_id")] - public string MessageId { get { return Id; } set { Id = value; } } - } - public class Message : MessageReference - { - public sealed class Attachment - { - [JsonProperty("id")] - public string Id; - [JsonProperty("url")] - public string Url; - [JsonProperty("proxy_url")] - public string ProxyUrl; - [JsonProperty("size")] - public int Size; - [JsonProperty("filename")] - public string Filename; - [JsonProperty("width")] - public int Width; - [JsonProperty("height")] - public int Height; - } - public sealed class Embed - { - public sealed class Reference - { - [JsonProperty("url")] - public string Url; - [JsonProperty("name")] - public string Name; - } - public sealed class ThumbnailInfo - { - [JsonProperty("url")] - public string Url; - [JsonProperty("proxy_url")] - public string ProxyUrl; - [JsonProperty("width")] - public int Width; - [JsonProperty("height")] - public int Height; - } - - [JsonProperty("url")] - public string Url; - [JsonProperty("type")] - public string Type; - [JsonProperty("title")] - public string Title; - [JsonProperty("description")] - public string Description; - [JsonProperty("author")] - public Reference Author; - [JsonProperty("provider")] - public Reference Provider; - [JsonProperty("thumbnail")] - public ThumbnailInfo Thumbnail; - } - - [JsonProperty("tts")] - public bool? IsTextToSpeech; - [JsonProperty("mention_everyone")] - public bool? IsMentioningEveryone; - [JsonProperty("timestamp")] - public DateTime? Timestamp; - [JsonProperty("edited_timestamp")] - public DateTime? EditedTimestamp; - [JsonProperty("mentions")] - public UserReference[] Mentions; - [JsonProperty("embeds")] - public Embed[] Embeds; //TODO: Parse this - [JsonProperty("attachments")] - public Attachment[] Attachments; - [JsonProperty("content")] - public string Content; - [JsonProperty("author")] - public UserReference Author; - [JsonProperty("nonce")] - public string Nonce; - } - - //Roles - public class RoleReference - { - [JsonProperty("guild_id")] - public string GuildId; - [JsonProperty("role_id")] - public string RoleId; - } - public class RoleInfo - { - [JsonProperty("permissions")] - public uint? Permissions; - [JsonProperty("name")] - public string Name; - [JsonProperty("position")] - public int? Position; - [JsonProperty("hoist")] - public bool? Hoist; - [JsonProperty("color")] - public uint? Color; - [JsonProperty("id")] - public string Id; - [JsonProperty("managed")] - public bool? Managed; - } - - //Invites - public class Invite - { - [JsonProperty("inviter")] - public UserReference Inviter; - [JsonProperty("guild")] - public GuildReference Guild; - [JsonProperty("channel")] - public ChannelReference Channel; - [JsonProperty("code")] - public string Code; - [JsonProperty("xkcdpass")] - public string XkcdPass; - } - public class ExtendedInvite : Invite - { - [JsonProperty("max_age")] - public int ?MaxAge; - [JsonProperty("max_uses")] - public int? MaxUses; - [JsonProperty("revoked")] - public bool? IsRevoked; - [JsonProperty("temporary")] - public bool? IsTemporary; - [JsonProperty("uses")] - public int? Uses; - [JsonProperty("created_at")] - public DateTime? CreatedAt; - } -} diff --git a/src/Discord.Net/API/Endpoints.cs b/src/Discord.Net/API/Endpoints.cs index 706607eca..67c256a88 100644 --- a/src/Discord.Net/API/Endpoints.cs +++ b/src/Discord.Net/API/Endpoints.cs @@ -1,9 +1,10 @@ namespace Discord.API { - internal static class Endpoints + public static class Endpoints { public const string BaseStatusApi = "https://status.discordapp.com/api/v2/"; public const string BaseApi = "https://discordapp.com/api/"; + public const string Gateway = "gateway"; public const string Auth = "auth"; @@ -39,7 +40,7 @@ public const string Voice = "voice"; public const string VoiceRegions = "voice/regions"; - public const string VoiceIce = "voice/ice"; + //public const string VoiceIce = "voice/ice"; public const string StatusActiveMaintenance = "scheduled-maintenances/active.json"; public const string StatusUpcomingMaintenance = "scheduled-maintenances/upcoming.json"; diff --git a/src/Discord.Net/API/Invites.cs b/src/Discord.Net/API/Invites.cs new file mode 100644 index 000000000..62d2049b3 --- /dev/null +++ b/src/Discord.Net/API/Invites.cs @@ -0,0 +1,59 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; +using System; + +namespace Discord.API +{ + //Common + public class InviteReference + { + [JsonProperty("inviter")] + public UserReference Inviter; + [JsonProperty("guild")] + public GuildReference Guild; + [JsonProperty("channel")] + public ChannelReference Channel; + [JsonProperty("code")] + public string Code; + [JsonProperty("xkcdpass")] + public string XkcdPass; + } + public class InviteInfo : InviteReference + { + [JsonProperty("max_age")] + public int? MaxAge; + [JsonProperty("max_uses")] + public int? MaxUses; + [JsonProperty("revoked")] + public bool? IsRevoked; + [JsonProperty("temporary")] + public bool? IsTemporary; + [JsonProperty("uses")] + public int? Uses; + [JsonProperty("created_at")] + public DateTime? CreatedAt; + } + + //Create + public class CreateInviteRequest + { + [JsonProperty("max_age")] + public int MaxAge; + [JsonProperty("max_uses")] + public int MaxUses; + [JsonProperty("temporary")] + public bool IsTemporary; + [JsonProperty("xkcdpass")] + public bool WithXkcdPass; + } + public class CreateInviteResponse : InviteInfo { } + + //Get + public class GetInviteResponse : InviteReference { } + + //Accept + public class AcceptInviteResponse : InviteReference { } +} diff --git a/src/Discord.Net/API/Maintenance.cs b/src/Discord.Net/API/Maintenance.cs new file mode 100644 index 000000000..337b89453 --- /dev/null +++ b/src/Discord.Net/API/Maintenance.cs @@ -0,0 +1,33 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; +using System; + +namespace Discord.API +{ + public class GetIncidentsResponse + { + [JsonProperty("page")] + public PageData Page; + [JsonProperty("scheduled_maintenances")] + public MaintenanceData[] ScheduledMaintenances; + + public sealed class PageData + { + [JsonProperty("id")] + public string Id; + [JsonProperty("name")] + public string Name; + [JsonProperty("url")] + public string Url; + [JsonProperty("updated-at")] + public DateTime? UpdatedAt; + } + + public sealed class MaintenanceData + { + } + } +} diff --git a/src/Discord.Net/API/Members.cs b/src/Discord.Net/API/Members.cs new file mode 100644 index 000000000..9858e51ab --- /dev/null +++ b/src/Discord.Net/API/Members.cs @@ -0,0 +1,88 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; +using System; +using System.Collections.Generic; + +namespace Discord.API +{ + //Common + public class MemberReference + { + [JsonProperty("user_id")] + public string UserId; + [JsonProperty("guild_id")] + public string GuildId; + + [JsonProperty("user")] + private UserReference _user; + public UserReference User + { + get { return _user; } + set + { + _user = value; + UserId = User.Id; + } + } + } + public class MemberInfo : MemberReference + { + [JsonProperty("joined_at")] + public DateTime? JoinedAt; + [JsonProperty("roles")] + public string[] Roles; + } + public class ExtendedMemberInfo : MemberInfo + { + [JsonProperty("mute")] + public bool? IsServerMuted; + [JsonProperty("deaf")] + public bool? IsServerDeafened; + } + public class PresenceInfo : MemberReference + { + [JsonProperty("game_id")] + public string GameId; + [JsonProperty("status")] + public string Status; + } + public class VoiceMemberInfo : MemberReference + { + [JsonProperty("channel_id")] + public string ChannelId; + [JsonProperty("session_id")] + public string SessionId; + [JsonProperty("token")] + public string Token; + + [JsonProperty("self_mute")] + public bool? IsSelfMuted; + [JsonProperty("self_deaf")] + public bool? IsSelfDeafened; + [JsonProperty("mute")] + public bool? IsServerMuted; + [JsonProperty("deaf")] + public bool? IsServerDeafened; + [JsonProperty("suppress")] + public bool? IsServerSuppressed; + } + + public class EditMemberRequest + { + [JsonProperty(PropertyName = "mute", NullValueHandling = NullValueHandling.Ignore)] + public bool? Mute; + [JsonProperty(PropertyName = "deaf", NullValueHandling = NullValueHandling.Ignore)] + public bool? Deaf; + [JsonProperty(PropertyName = "roles", NullValueHandling = NullValueHandling.Ignore)] + public IEnumerable Roles; + } + + //Events + internal sealed class MemberAddEvent : MemberInfo { } + internal sealed class MemberUpdateEvent : MemberInfo { } + internal sealed class MemberRemoveEvent : MemberInfo { } + internal sealed class MemberVoiceStateUpdateEvent : VoiceMemberInfo { } +} diff --git a/src/Discord.Net/API/Messages.cs b/src/Discord.Net/API/Messages.cs new file mode 100644 index 000000000..8fc031dd1 --- /dev/null +++ b/src/Discord.Net/API/Messages.cs @@ -0,0 +1,133 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; +using System; +using System.Collections.Generic; + +namespace Discord.API +{ + //Common + public class MessageReference + { + [JsonProperty("id")] + public string Id; + [JsonProperty("channel_id")] + public string ChannelId; + [JsonProperty("message_id")] + public string MessageId { get { return Id; } set { Id = value; } } + } + public class MessageInfo : MessageReference + { + public sealed class Attachment + { + [JsonProperty("id")] + public string Id; + [JsonProperty("url")] + public string Url; + [JsonProperty("proxy_url")] + public string ProxyUrl; + [JsonProperty("size")] + public int Size; + [JsonProperty("filename")] + public string Filename; + [JsonProperty("width")] + public int Width; + [JsonProperty("height")] + public int Height; + } + + public sealed class Embed + { + public sealed class Reference + { + [JsonProperty("url")] + public string Url; + [JsonProperty("name")] + public string Name; + } + + public sealed class ThumbnailInfo + { + [JsonProperty("url")] + public string Url; + [JsonProperty("proxy_url")] + public string ProxyUrl; + [JsonProperty("width")] + public int Width; + [JsonProperty("height")] + public int Height; + } + + [JsonProperty("url")] + public string Url; + [JsonProperty("type")] + public string Type; + [JsonProperty("title")] + public string Title; + [JsonProperty("description")] + public string Description; + [JsonProperty("author")] + public Reference Author; + [JsonProperty("provider")] + public Reference Provider; + [JsonProperty("thumbnail")] + public ThumbnailInfo Thumbnail; + } + + [JsonProperty("tts")] + public bool? IsTextToSpeech; + [JsonProperty("mention_everyone")] + public bool? IsMentioningEveryone; + [JsonProperty("timestamp")] + public DateTime? Timestamp; + [JsonProperty("edited_timestamp")] + public DateTime? EditedTimestamp; + [JsonProperty("mentions")] + public UserReference[] Mentions; + [JsonProperty("embeds")] + public Embed[] Embeds; //TODO: Parse this + [JsonProperty("attachments")] + public Attachment[] Attachments; + [JsonProperty("content")] + public string Content; + [JsonProperty("author")] + public UserReference Author; + [JsonProperty("nonce")] + public string Nonce; + } + + //Create + internal sealed class SendMessageRequest + { + [JsonProperty("content")] + public string Content; + [JsonProperty("mentions")] + public IEnumerable Mentions; + [JsonProperty("nonce", NullValueHandling = NullValueHandling.Ignore)] + public string Nonce; + [JsonProperty("tts", NullValueHandling = NullValueHandling.Ignore)] + public bool IsTTS; + } + public sealed class SendMessageResponse : MessageInfo { } + + //Edit + internal sealed class EditMessageRequest + { + [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)] + public string Content; + [JsonProperty("mentions", NullValueHandling = NullValueHandling.Ignore)] + public IEnumerable Mentions; + } + public sealed class EditMessageResponse : MessageInfo { } + + //Get + public sealed class GetMessagesResponse : List { } + + //Events + internal sealed class MessageCreateEvent : MessageInfo { } + internal sealed class MessageUpdateEvent : MessageInfo { } + internal sealed class MessageDeleteEvent : MessageReference { } + internal sealed class MessageAckEvent : MessageReference { } +} diff --git a/src/Discord.Net/API/Permissions.cs b/src/Discord.Net/API/Permissions.cs new file mode 100644 index 000000000..df8a82353 --- /dev/null +++ b/src/Discord.Net/API/Permissions.cs @@ -0,0 +1,21 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; + +namespace Discord.API +{ + //Create/Edit + internal sealed class SetChannelPermissionsRequest + { + [JsonProperty("id")] + public string Id; + [JsonProperty("type")] + public string Type; + [JsonProperty("allow")] + public uint Allow; + [JsonProperty("deny")] + public uint Deny; + } +} diff --git a/src/Discord.Net/API/Presence.cs b/src/Discord.Net/API/Presence.cs new file mode 100644 index 000000000..07a1d8f56 --- /dev/null +++ b/src/Discord.Net/API/Presence.cs @@ -0,0 +1,33 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; + +namespace Discord.API +{ + //Commands + internal sealed class UpdateStatusCommand : WebSocketMessage + { + public UpdateStatusCommand() : base(3) { } + public class Data + { + [JsonProperty("idle_since")] + public ulong? IdleSince; + [JsonProperty("game_id")] + public int? GameId; + } + } + + //Events + internal sealed class TypingStartEvent + { + [JsonProperty("user_id")] + public string UserId; + [JsonProperty("channel_id")] + public string ChannelId; + [JsonProperty("timestamp")] + public int Timestamp; + } + internal sealed class PresenceUpdateEvent : PresenceInfo { } +} diff --git a/src/Discord.Net/API/Requests.cs b/src/Discord.Net/API/Requests.cs deleted file mode 100644 index b60ee0fd8..000000000 --- a/src/Discord.Net/API/Requests.cs +++ /dev/null @@ -1,178 +0,0 @@ -//Ignore unused/unassigned variable warnings -#pragma warning disable CS0649 -#pragma warning disable CS0169 - -using Newtonsoft.Json; -using System.Collections.Generic; -using System.Collections; - -namespace Discord.API -{ - //Auth - internal sealed class RegisterRequest - { - [JsonProperty("fingerprint")] - public string Fingerprint; - [JsonProperty("username")] - public string Username; - } - internal sealed class LoginRequest - { - [JsonProperty("email")] - public string Email; - [JsonProperty("password")] - public string Password; - } - - //Channels - internal sealed class CreateChannelRequest - { - [JsonProperty("name")] - public string Name; - [JsonProperty("type")] - public string Type; - } - internal sealed class CreatePMChannelRequest - { - [JsonProperty("recipient_id")] - public string RecipientId; - } - internal sealed class EditChannelRequest - { - [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] - public string Name; - [JsonProperty("topic", NullValueHandling = NullValueHandling.Ignore)] - public string Topic; - } - internal sealed class ReorderChannelsRequest : IEnumerable - { - public sealed class Channel - { - [JsonProperty("id")] - public string Id; - [JsonProperty("position")] - public uint Position; - } - private IEnumerable _channels; - public ReorderChannelsRequest(IEnumerable channels) { _channels = channels; } - - public IEnumerator GetEnumerator() =>_channels.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => _channels.GetEnumerator(); - } - - //Invites - internal sealed class CreateInviteRequest - { - [JsonProperty("max_age")] - public int MaxAge; - [JsonProperty("max_uses")] - public int MaxUses; - [JsonProperty("temporary")] - public bool IsTemporary; - [JsonProperty("xkcdpass")] - public bool WithXkcdPass; - } - - //Members - internal sealed class EditMemberRequest - { - [JsonProperty(PropertyName = "mute", NullValueHandling = NullValueHandling.Ignore)] - public bool? Mute; - [JsonProperty(PropertyName = "deaf", NullValueHandling = NullValueHandling.Ignore)] - public bool? Deaf; - [JsonProperty(PropertyName = "roles", NullValueHandling = NullValueHandling.Ignore)] - public IEnumerable Roles; - } - - //Messages - internal sealed class SendMessageRequest - { - [JsonProperty("content")] - public string Content; - [JsonProperty("mentions")] - public IEnumerable Mentions; - [JsonProperty("nonce", NullValueHandling = NullValueHandling.Ignore)] - public string Nonce; - [JsonProperty("tts", NullValueHandling = NullValueHandling.Ignore)] - public bool IsTTS; - } - internal sealed class EditMessageRequest - { - [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)] - public string Content; - [JsonProperty("mentions", NullValueHandling = NullValueHandling.Ignore)] - public IEnumerable Mentions; - } - - //Permissions - internal sealed class SetChannelPermissionsRequest //Both creates and modifies - { - [JsonProperty("id")] - public string Id; - [JsonProperty("type")] - public string Type; - [JsonProperty("allow")] - public uint Allow; - [JsonProperty("deny")] - public uint Deny; - } - - //Profile - internal sealed class EditProfileRequest - { - [JsonProperty(PropertyName = "password")] - public string CurrentPassword; - [JsonProperty(PropertyName = "email", NullValueHandling = NullValueHandling.Ignore)] - public string Email; - [JsonProperty(PropertyName = "new_password")] - public string Password; - [JsonProperty(PropertyName = "username", NullValueHandling = NullValueHandling.Ignore)] - public string Username; - [JsonProperty(PropertyName = "avatar", NullValueHandling = NullValueHandling.Ignore)] - public string Avatar; - } - - //Roles - internal sealed class EditRoleRequest - { - [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] - public string Name; - [JsonProperty("permissions", NullValueHandling = NullValueHandling.Ignore)] - public uint? Permissions; - [JsonProperty("hoist", NullValueHandling = NullValueHandling.Ignore)] - public bool? Hoist; - [JsonProperty("color", NullValueHandling = NullValueHandling.Ignore)] - public uint? Color; - } - internal sealed class ReorderRolesRequest : IEnumerable - { - public sealed class Role - { - [JsonProperty("id")] - public string Id; - [JsonProperty("position")] - public uint Position; - } - private IEnumerable _roles; - public ReorderRolesRequest(IEnumerable roles) { _roles = roles; } - - public IEnumerator GetEnumerator() => _roles.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => _roles.GetEnumerator(); - } - - //Servers - internal sealed class CreateServerRequest - { - [JsonProperty("name")] - public string Name; - [JsonProperty("region")] - public string Region; - } - internal sealed class EditServerRequest - { - [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] - public string Name; - [JsonProperty("region", NullValueHandling = NullValueHandling.Ignore)] - public string Region; - } -} diff --git a/src/Discord.Net/API/Responses.cs b/src/Discord.Net/API/Responses.cs deleted file mode 100644 index c26dc701f..000000000 --- a/src/Discord.Net/API/Responses.cs +++ /dev/null @@ -1,106 +0,0 @@ -//Ignore unused/unassigned variable warnings -#pragma warning disable CS0649 -#pragma warning disable CS0169 - -using Newtonsoft.Json; -using System; -using System.Collections.Generic; - -namespace Discord.API -{ - //Auth - public sealed class GatewayResponse - { - [JsonProperty("url")] - public string Url; - } - public sealed class LoginResponse - { - [JsonProperty("token")] - public string Token; - } - - //Channels - public sealed class CreateChannelResponse : ChannelInfo { } - public sealed class DestroyChannelResponse : ChannelInfo { } - public sealed class EditChannelResponse : ChannelInfo { } - - //Invites - public sealed class CreateInviteResponse : ExtendedInvite { } - public sealed class GetInviteResponse : Invite { } - public sealed class AcceptInviteResponse : Invite { } - - //Messages - public sealed class SendMessageResponse : Message { } - public sealed class EditMessageResponse : Message { } - public sealed class GetMessagesResponse : List { } - - //Profile - public sealed class EditProfileResponse : SelfUserInfo { } - - //Roles - public sealed class CreateRoleResponse : RoleInfo { } - public sealed class EditRoleResponse : RoleInfo { } - - //Servers - public sealed class CreateServerResponse : GuildInfo { } - public sealed class DeleteServerResponse : GuildInfo { } - public sealed class EditServerResponse : GuildInfo { } - - //Voice - public sealed class GetRegionsResponse : List - { - public sealed class RegionData - { - [JsonProperty("sample_hostname")] - public string Hostname; - [JsonProperty("sample_port")] - public int Port; - [JsonProperty("id")] - public string Id; - [JsonProperty("name")] - public string Name; - } - } - public sealed class GetIceResponse - { - [JsonProperty("ttl")] - public string TTL; - [JsonProperty("servers")] - public ServerData[] Servers; - - public sealed class ServerData - { - [JsonProperty("url")] - public string URL; - [JsonProperty("username")] - public string Username; - [JsonProperty("credential")] - public string Credential; - } - } - - public sealed class GetIncidentsResponse - { - [JsonProperty("page")] - public PageData Page; - [JsonProperty("scheduled_maintenances")] - public MaintenanceData[] ScheduledMaintenances; - - public sealed class PageData - { - [JsonProperty("id")] - public string Id; - [JsonProperty("name")] - public string Name; - [JsonProperty("url")] - public string Url; - [JsonProperty("updated-at")] - public DateTime? UpdatedAt; - } - - public sealed class MaintenanceData - { - } - } -} diff --git a/src/Discord.Net/API/RestClient.BuiltIn.cs b/src/Discord.Net/API/RestClient.BuiltIn.cs deleted file mode 100644 index ec5b6bb61..000000000 --- a/src/Discord.Net/API/RestClient.BuiltIn.cs +++ /dev/null @@ -1,67 +0,0 @@ -/* -using Discord.API; -using System; -using System.Globalization; -using System.IO; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace Discord.API -{ - internal class BuiltInRestEngine : IRestEngine - { - private readonly HttpClient _client; - - public BuiltInRestEngine(string userAgent, int timeout) - { - _client = new HttpClient(new HttpClientHandler - { - AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip, - UseCookies = false, - PreAuthenticate = false //We do auth ourselves - }); - _client.DefaultRequestHeaders.Add("accept", "*\/*"); - _client.DefaultRequestHeaders.Add("accept-encoding", "gzip,deflate"); - _client.DefaultRequestHeaders.Add("user-agent", userAgent); - _client.Timeout = TimeSpan.FromMilliseconds(timeout); - } - - public void SetToken(string token) - { - _client.DefaultRequestHeaders.Remove("authorization"); - if (token != null) - _client.DefaultRequestHeaders.Add("authorization", token); - } - - public async Task Send(HttpMethod method, string path, string json, CancellationToken cancelToken) - { - using (var request = new HttpRequestMessage(method, Endpoints.BaseApi + path)) - { - if (json != null) - request.Content = new StringContent(json, Encoding.UTF8, "application/json"); - return await Send(request, cancelToken); - } - } - public async Task SendFile(HttpMethod method, string path, string filePath, CancellationToken cancelToken) - { - using (var request = new HttpRequestMessage(method, Endpoints.BaseApi + path)) - { - var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)); - content.Add(new StreamContent(File.OpenRead(filePath)), "file", Path.GetFileName(filePath)); - request.Content = content; - return await Send(request, cancelToken); - } - } - private async Task Send(HttpRequestMessage request, CancellationToken cancelToken) - { - var response = await _client.SendAsync(request, cancelToken).ConfigureAwait(false); - if (!response.IsSuccessStatusCode) - throw new HttpException(response.StatusCode); - return await response.Content.ReadAsStringAsync().ConfigureAwait(false); - } - } -} -*/ \ No newline at end of file diff --git a/src/Discord.Net/API/Roles.cs b/src/Discord.Net/API/Roles.cs new file mode 100644 index 000000000..ba1517513 --- /dev/null +++ b/src/Discord.Net/API/Roles.cs @@ -0,0 +1,87 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; +using System.Collections; +using System.Collections.Generic; + +namespace Discord.API +{ + //Common + public class RoleReference + { + [JsonProperty("guild_id")] + public string GuildId; + [JsonProperty("role_id")] + public string RoleId; + } + public class RoleInfo + { + [JsonProperty("permissions")] + public uint? Permissions; + [JsonProperty("name")] + public string Name; + [JsonProperty("position")] + public int? Position; + [JsonProperty("hoist")] + public bool? Hoist; + [JsonProperty("color")] + public uint? Color; + [JsonProperty("id")] + public string Id; + [JsonProperty("managed")] + public bool? Managed; + } + + //Create + public sealed class CreateRoleResponse : RoleInfo { } + + //Edit + public sealed class EditRoleRequest + { + [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] + public string Name; + [JsonProperty("permissions", NullValueHandling = NullValueHandling.Ignore)] + public uint? Permissions; + [JsonProperty("hoist", NullValueHandling = NullValueHandling.Ignore)] + public bool? Hoist; + [JsonProperty("color", NullValueHandling = NullValueHandling.Ignore)] + public uint? Color; + } + public sealed class EditRoleResponse : RoleInfo { } + + //Reorder + public sealed class ReorderRolesRequest : IEnumerable + { + public sealed class Role + { + [JsonProperty("id")] + public string Id; + [JsonProperty("position")] + public uint Position; + } + private IEnumerable _roles; + public ReorderRolesRequest(IEnumerable roles) { _roles = roles; } + + public IEnumerator GetEnumerator() => _roles.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => _roles.GetEnumerator(); + } + + //Events + internal sealed class RoleCreateEvent + { + [JsonProperty("guild_id")] + public string GuildId; + [JsonProperty("role")] + public RoleInfo Data; + } + internal sealed class RoleUpdateEvent + { + [JsonProperty("guild_id")] + public string GuildId; + [JsonProperty("role")] + public RoleInfo Data; + } + internal sealed class RoleDeleteEvent : RoleReference { } +} diff --git a/src/Discord.Net/API/Servers.cs b/src/Discord.Net/API/Servers.cs new file mode 100644 index 000000000..b86a94ffa --- /dev/null +++ b/src/Discord.Net/API/Servers.cs @@ -0,0 +1,80 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; +using System; + +namespace Discord.API +{ + //Common + public class GuildReference + { + [JsonProperty("id")] + public string Id; + [JsonProperty("name")] + public string Name; + } + public class GuildInfo : GuildReference + { + [JsonProperty("afk_channel_id")] + public string AFKChannelId; + [JsonProperty("afk_timeout")] + public int AFKTimeout; + [JsonProperty("embed_channel_id")] + public string EmbedChannelId; + [JsonProperty("embed_enabled")] + public bool EmbedEnabled; + [JsonProperty("icon")] + public string Icon; + [JsonProperty("joined_at")] + public DateTime? JoinedAt; + [JsonProperty("owner_id")] + public string OwnerId; + [JsonProperty("region")] + public string Region; + [JsonProperty("roles")] + public RoleInfo[] Roles; + } + public class ExtendedGuildInfo : GuildInfo + { + [JsonProperty("channels")] + public ChannelInfo[] Channels; + [JsonProperty("members")] + public ExtendedMemberInfo[] Members; + [JsonProperty("presences")] + public PresenceInfo[] Presences; + [JsonProperty("voice_states")] + public VoiceMemberInfo[] VoiceStates; + [JsonProperty("unavailable")] + public bool Unavailable; + } + + //Create + internal sealed class CreateServerRequest + { + [JsonProperty("name")] + public string Name; + [JsonProperty("region")] + public string Region; + } + public sealed class CreateServerResponse : GuildInfo { } + + //Edit + internal sealed class EditServerRequest + { + [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] + public string Name; + [JsonProperty("region", NullValueHandling = NullValueHandling.Ignore)] + public string Region; + } + public sealed class EditServerResponse : GuildInfo { } + + //Delete + public sealed class DeleteServerResponse : GuildInfo { } + + //Events + internal sealed class GuildCreateEvent : ExtendedGuildInfo { } + internal sealed class GuildUpdateEvent : GuildInfo { } + internal sealed class GuildDeleteEvent : ExtendedGuildInfo { } +} diff --git a/src/Discord.Net/API/Users.cs b/src/Discord.Net/API/Users.cs new file mode 100644 index 000000000..52bb8d6a2 --- /dev/null +++ b/src/Discord.Net/API/Users.cs @@ -0,0 +1,47 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; + +namespace Discord.API +{ + //Common + public class UserReference + { + [JsonProperty("username")] + public string Username; + [JsonProperty("id")] + public string Id; + [JsonProperty("discriminator")] + public string Discriminator; + [JsonProperty("avatar")] + public string Avatar; + } + public class UserInfo : UserReference + { + [JsonProperty("email")] + public string Email; + [JsonProperty("verified")] + public bool? IsVerified; + } + + //Edit + internal sealed class EditUserRequest + { + [JsonProperty(PropertyName = "password")] + public string CurrentPassword; + [JsonProperty(PropertyName = "email", NullValueHandling = NullValueHandling.Ignore)] + public string Email; + [JsonProperty(PropertyName = "new_password")] + public string Password; + [JsonProperty(PropertyName = "username", NullValueHandling = NullValueHandling.Ignore)] + public string Username; + [JsonProperty(PropertyName = "avatar", NullValueHandling = NullValueHandling.Ignore)] + public string Avatar; + } + public sealed class EditUserResponse : UserInfo { } + + //Events + internal sealed class UserUpdateEvent : UserInfo { } +} diff --git a/src/Discord.Net/API/Voice.cs b/src/Discord.Net/API/Voice.cs new file mode 100644 index 000000000..2bf30fe53 --- /dev/null +++ b/src/Discord.Net/API/Voice.cs @@ -0,0 +1,153 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace Discord.API +{ + public class GetRegionsResponse : List + { + public sealed class RegionData + { + [JsonProperty("sample_hostname")] + public string Hostname; + [JsonProperty("sample_port")] + public int Port; + [JsonProperty("id")] + public string Id; + [JsonProperty("name")] + public string Name; + } + } + + public class GetIceResponse + { + [JsonProperty("ttl")] + public string TTL; + [JsonProperty("servers")] + public ServerData[] Servers; + + public sealed class ServerData + { + [JsonProperty("url")] + public string URL; + [JsonProperty("username")] + public string Username; + [JsonProperty("credential")] + public string Credential; + } + } + + //Commands + internal sealed class JoinVoiceCommand : WebSocketMessage + { + public JoinVoiceCommand() : base(4) { } + public class Data + { + [JsonProperty("guild_id")] + public string ServerId; + [JsonProperty("channel_id")] + public string ChannelId; + [JsonProperty("self_mute")] + public string SelfMute; + [JsonProperty("self_deaf")] + public string SelfDeaf; + } + } + + //Events + internal sealed class VoiceServerUpdateEvent + { + [JsonProperty("guild_id")] + public string GuildId; + [JsonProperty("endpoint")] + public string Endpoint; + [JsonProperty("token")] + public string Token; + } + + //Commands (Voice) + internal sealed class VoiceLoginCommand : WebSocketMessage + { + public VoiceLoginCommand() : base(0) { } + public class Data + { + [JsonProperty("server_id")] + public string ServerId; + [JsonProperty("user_id")] + public string UserId; + [JsonProperty("session_id")] + public string SessionId; + [JsonProperty("token")] + public string Token; + } + } + internal sealed class VoiceLogin2Command : WebSocketMessage + { + public VoiceLogin2Command() : base(1) { } + public class Data + { + public class SocketInfo + { + [JsonProperty("address")] + public string Address; + [JsonProperty("port")] + public int Port; + [JsonProperty("mode")] + public string Mode = "xsalsa20_poly1305"; + } + [JsonProperty("protocol")] + public string Protocol = "udp"; + [JsonProperty("data")] + public SocketInfo SocketData = new SocketInfo(); + } + } + internal sealed class VoiceKeepAliveCommand : WebSocketMessage + { + public VoiceKeepAliveCommand() : base(3, null) { } + } + internal sealed class IsTalkingCommand : WebSocketMessage + { + public IsTalkingCommand() : base(5) { } + public class Data + { + [JsonProperty("delay")] + public int Delay; + [JsonProperty("speaking")] + public bool IsSpeaking; + } + } + + //Events (Voice) + public class VoiceReadyEvent + { + [JsonProperty("ssrc")] + public uint SSRC; + [JsonProperty("port")] + public ushort Port; + [JsonProperty("modes")] + public string[] Modes; + [JsonProperty("heartbeat_interval")] + public int HeartbeatInterval; + } + + public class JoinServerEvent + { + [JsonProperty("secret_key")] + public byte[] SecretKey; + [JsonProperty("mode")] + public string Mode; + } + + public class IsTalkingEvent + { + [JsonProperty("user_id")] + public string UserId; + [JsonProperty("ssrc")] + public uint SSRC; + [JsonProperty("speaking")] + public bool IsSpeaking; + } +} diff --git a/src/Discord.Net/API/WebSockets.cs b/src/Discord.Net/API/WebSockets.cs new file mode 100644 index 000000000..246bd2c6a --- /dev/null +++ b/src/Discord.Net/API/WebSockets.cs @@ -0,0 +1,112 @@ +//Ignore unused/unassigned variable warnings +#pragma warning disable CS0649 +#pragma warning disable CS0169 + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.Collections.Generic; + +namespace Discord.API +{ + //Common + public class WebSocketMessage + { + [JsonProperty("op")] + public int Operation; + [JsonProperty("d")] + public object Payload; + [JsonProperty("t", NullValueHandling = NullValueHandling.Ignore)] + public string Type; + [JsonProperty("s", NullValueHandling = NullValueHandling.Ignore)] + public int? Sequence; + } + internal abstract class WebSocketMessage : WebSocketMessage + where T : new() + { + public WebSocketMessage() { Payload = new T(); } + public WebSocketMessage(int op) { Operation = op; Payload = new T(); } + public WebSocketMessage(int op, T payload) { Operation = op; Payload = payload; } + + [JsonIgnore] + public new T Payload + { + get + { + if (base.Payload is JToken) + base.Payload = (base.Payload as JToken).ToObject(); + return (T)base.Payload; + } + set { base.Payload = value; } + } + } + + //Commands + internal sealed class KeepAliveCommand : WebSocketMessage + { + public KeepAliveCommand() : base(1, EpochTime.GetMilliseconds()) { } + } + internal sealed class LoginCommand : WebSocketMessage + { + public LoginCommand() : base(2) { } + public class Data + { + [JsonProperty("token")] + public string Token; + [JsonProperty("v")] + public int Version = 3; + [JsonProperty("properties")] + public Dictionary Properties = new Dictionary(); + } + } + internal sealed class ResumeCommand : WebSocketMessage + { + public ResumeCommand() : base(6) { } + public class Data + { + [JsonProperty("session_id")] + public string SessionId; + [JsonProperty("seq")] + public int Sequence; + } + } + + //Events + internal sealed class ReadyEvent + { + public sealed class ReadStateInfo + { + [JsonProperty("id")] + public string ChannelId; + [JsonProperty("mention_count")] + public int MentionCount; + [JsonProperty("last_message_id")] + public string LastMessageId; + } + + [JsonProperty("v")] + public int Version; + [JsonProperty("user")] + public UserInfo User; + [JsonProperty("session_id")] + public string SessionId; + [JsonProperty("read_state")] + public ReadStateInfo[] ReadState; + [JsonProperty("guilds")] + public ExtendedGuildInfo[] Guilds; + [JsonProperty("private_channels")] + public ChannelInfo[] PrivateChannels; + [JsonProperty("heartbeat_interval")] + public int HeartbeatInterval; + } + internal sealed class ResumedEvent + { + [JsonProperty("heartbeat_interval")] + public int HeartbeatInterval; + } + + internal sealed class RedirectEvent + { + [JsonProperty("url")] + public string Url; + } +} diff --git a/src/Discord.Net/DiscordClient.API.cs b/src/Discord.Net/DiscordClient.API.cs index b90f23d52..d8642f9ba 100644 --- a/src/Discord.Net/DiscordClient.API.cs +++ b/src/Discord.Net/DiscordClient.API.cs @@ -1,4 +1,5 @@ using Discord.API; +using Discord.Net; using System; using System.Collections.Generic; using System.Linq; @@ -312,7 +313,7 @@ namespace Discord { var msg = _messages.GetOrAdd("nonce_" + nonce, channel.Id, CurrentUserId); var currentMember = _members[msg.UserId, channel.ServerId]; - msg.Update(new API.Message + msg.Update(new MessageInfo { Content = blockText, Timestamp = DateTime.UtcNow, @@ -611,26 +612,20 @@ namespace Discord } //Profile - public Task EditProfile(string currentPassword = "", + public Task EditProfile(string currentPassword = "", string username = null, string email = null, string password = null, AvatarImageType avatarType = AvatarImageType.Png, byte[] avatar = null) { if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword)); - return _api.EditProfile(currentPassword: currentPassword, username: username ?? _currentUser?.Name, email: email ?? _currentUser?.Email, password: password, + return _api.EditUser(currentPassword: currentPassword, username: username ?? _currentUser?.Name, email: email ?? _currentUser?.Email, password: password, avatarType: avatarType, avatar: avatar); } public Task SetStatus(string status) { - switch (status) - { - case UserStatus.Online: - case UserStatus.Away: - _status = status; - break; - default: - throw new ArgumentException($"Invalid status, must be {UserStatus.Online} or {UserStatus.Away}"); - } + if (status != UserStatus.Online && status != UserStatus.Idle) + throw new ArgumentException($"Invalid status, must be {UserStatus.Online} or {UserStatus.Idle}"); + _status = status; return SendStatus(); } public Task SetGame(int? gameId) @@ -640,7 +635,7 @@ namespace Discord } private Task SendStatus() { - _dataSocket.SendStatus(_status == UserStatus.Away ? EpochTime.GetMilliseconds() - (10 * 60 * 1000) : (ulong?)null, _gameId); + _dataSocket.SendStatus(_status == UserStatus.Idle ? EpochTime.GetMilliseconds() - (10 * 60 * 1000) : (ulong?)null, _gameId); return TaskHelper.CompletedTask; } diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index be80cddb1..f32fdd487 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -1,7 +1,6 @@ using Discord.API; using Discord.Collections; -using Discord.WebSockets; -using Discord.WebSockets.Data; +using Discord.Net; using Newtonsoft.Json; using System; using System.Collections.Concurrent; @@ -9,7 +8,6 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; -using VoiceWebSocket = Discord.WebSockets.Voice.VoiceWebSocket; namespace Discord { @@ -474,7 +472,7 @@ namespace Discord //Members case "GUILD_MEMBER_ADD": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_serializer); var user = _users.GetOrAdd(data.User.Id); user.Update(data.User); var member = _members.GetOrAdd(data.User.Id, data.GuildId); @@ -486,7 +484,7 @@ namespace Discord break; case "GUILD_MEMBER_UPDATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_serializer); var member = _members[data.User.Id, data.GuildId]; if (member != null) { @@ -497,7 +495,7 @@ namespace Discord break; case "GUILD_MEMBER_REMOVE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_serializer); var member = _members.TryRemove(data.UserId, data.GuildId); if (member != null) RaiseUserRemoved(member); @@ -507,7 +505,7 @@ namespace Discord //Roles case "GUILD_ROLE_CREATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_serializer); var role = _roles.GetOrAdd(data.Data.Id, data.GuildId, false); role.Update(data.Data); var server = _servers[data.GuildId]; @@ -518,7 +516,7 @@ namespace Discord break; case "GUILD_ROLE_UPDATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_serializer); var role = _roles[data.Data.Id]; if (role != null) role.Update(data.Data); @@ -527,7 +525,7 @@ namespace Discord break; case "GUILD_ROLE_DELETE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_serializer); var server = _servers[data.GuildId]; if (server != null) server.RemoveRole(data.RoleId); @@ -540,7 +538,7 @@ namespace Discord //Bans case "GUILD_BAN_ADD": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_serializer); var server = _servers[data.GuildId]; if (server != null) { @@ -551,7 +549,7 @@ namespace Discord break; case "GUILD_BAN_REMOVE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_serializer); var server = _servers[data.GuildId]; if (server != null && server.RemoveBan(data.User?.Id)) RaiseBanRemoved(data.User?.Id, server); @@ -682,7 +680,7 @@ namespace Discord //Voice case "VOICE_STATE_UPDATE": { - var data = e.Payload.ToObject(_serializer); + var data = e.Payload.ToObject(_serializer); var member = _members[data.UserId, data.GuildId]; if (member != null) { diff --git a/src/Discord.Net/DiscordSimpleClient.cs b/src/Discord.Net/DiscordSimpleClient.cs index d9bb88e7f..9dde13ef0 100644 --- a/src/Discord.Net/DiscordSimpleClient.cs +++ b/src/Discord.Net/DiscordSimpleClient.cs @@ -1,11 +1,10 @@ -using Discord.WebSockets.Data; +using Discord.Net; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; -using VoiceWebSocket = Discord.WebSockets.Voice.VoiceWebSocket; namespace Discord { diff --git a/src/Discord.Net/Helpers/Extensions.cs b/src/Discord.Net/Helpers/Extensions.cs index 20e6a6d41..45aad0c5b 100644 --- a/src/Discord.Net/Helpers/Extensions.cs +++ b/src/Discord.Net/Helpers/Extensions.cs @@ -6,6 +6,53 @@ namespace Discord { internal static class Extensions { + public static async Task Timeout(this Task self, int milliseconds) + { + Task timeoutTask = Task.Delay(milliseconds); + Task finishedTask = await Task.WhenAny(self, timeoutTask).ConfigureAwait(false); + if (finishedTask == timeoutTask) + throw new TimeoutException(); + else + await self.ConfigureAwait(false); + } + public static async Task Timeout(this Task self, int milliseconds) + { + Task timeoutTask = Task.Delay(milliseconds); + Task finishedTask = await Task.WhenAny(self, timeoutTask).ConfigureAwait(false); + if (finishedTask == timeoutTask) + throw new TimeoutException(); + else + return await self.ConfigureAwait(false); + } + public static async Task Timeout(this Task self, int milliseconds, CancellationTokenSource timeoutToken) + { + try + { + timeoutToken.CancelAfter(milliseconds); + await self.ConfigureAwait(false); + } + catch (OperationCanceledException) + { + if (timeoutToken.IsCancellationRequested) + throw new TimeoutException(); + throw; + } + } + public static async Task Timeout(this Task self, int milliseconds, CancellationTokenSource timeoutToken) + { + try + { + timeoutToken.CancelAfter(milliseconds); + return await self.ConfigureAwait(false); + } + catch (OperationCanceledException) + { + if (timeoutToken.IsCancellationRequested) + throw new TimeoutException(); + throw; + } + } + public static async Task Wait(this CancellationTokenSource tokenSource) { var token = tokenSource.Token; diff --git a/src/Discord.Net/Format.cs b/src/Discord.Net/Helpers/Format.cs similarity index 100% rename from src/Discord.Net/Format.cs rename to src/Discord.Net/Helpers/Format.cs diff --git a/src/Discord.Net/Mention.cs b/src/Discord.Net/Helpers/Mention.cs similarity index 100% rename from src/Discord.Net/Mention.cs rename to src/Discord.Net/Helpers/Mention.cs diff --git a/src/Discord.Net/Helpers/CollectionHelper.cs b/src/Discord.Net/Helpers/Shared/CollectionHelper.cs similarity index 100% rename from src/Discord.Net/Helpers/CollectionHelper.cs rename to src/Discord.Net/Helpers/Shared/CollectionHelper.cs diff --git a/src/Discord.Net/Shared/TaskHelper.cs b/src/Discord.Net/Helpers/Shared/TaskHelper.cs similarity index 100% rename from src/Discord.Net/Shared/TaskHelper.cs rename to src/Discord.Net/Helpers/Shared/TaskHelper.cs diff --git a/src/Discord.Net/Helpers/TaskExtensions.cs b/src/Discord.Net/Helpers/TaskExtensions.cs deleted file mode 100644 index fa555dc0a..000000000 --- a/src/Discord.Net/Helpers/TaskExtensions.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Discord -{ - public static class TaskExtensions - { - public static async Task Timeout(this Task self, int milliseconds) - { - Task timeoutTask = Task.Delay(milliseconds); - Task finishedTask = await Task.WhenAny(self, timeoutTask); - if (finishedTask == timeoutTask) - throw new TimeoutException(); - else - await self; - } - public static async Task Timeout(this Task self, int milliseconds) - { - Task timeoutTask = Task.Delay(milliseconds); - Task finishedTask = await Task.WhenAny(self, timeoutTask).ConfigureAwait(false); - if (finishedTask == timeoutTask) - throw new TimeoutException(); - else - return await self.ConfigureAwait(false); - } - public static async Task Timeout(this Task self, int milliseconds, CancellationTokenSource timeoutToken) - { - try - { - timeoutToken.CancelAfter(milliseconds); - await self.ConfigureAwait(false); - } - catch (OperationCanceledException) - { - if (timeoutToken.IsCancellationRequested) - throw new TimeoutException(); - throw; - } - } - public static async Task Timeout(this Task self, int milliseconds, CancellationTokenSource timeoutToken) - { - try - { - timeoutToken.CancelAfter(milliseconds); - return await self.ConfigureAwait(false); - } - catch (OperationCanceledException) - { - if (timeoutToken.IsCancellationRequested) - throw new TimeoutException(); - throw; - } - } - } -} diff --git a/src/Discord.Net/TimeoutException.cs b/src/Discord.Net/Helpers/TimeoutException.cs similarity index 100% rename from src/Discord.Net/TimeoutException.cs rename to src/Discord.Net/Helpers/TimeoutException.cs diff --git a/src/Discord.Net/Audio/Opus.cs b/src/Discord.Net/Interop/Opus.cs similarity index 99% rename from src/Discord.Net/Audio/Opus.cs rename to src/Discord.Net/Interop/Opus.cs index 20f65be06..78c7b39d9 100644 --- a/src/Discord.Net/Audio/Opus.cs +++ b/src/Discord.Net/Interop/Opus.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -namespace Discord.Audio +namespace Discord.Interop { internal unsafe static class Opus { diff --git a/src/Discord.Net/Audio/OpusDecoder.cs b/src/Discord.Net/Interop/OpusDecoder.cs similarity index 99% rename from src/Discord.Net/Audio/OpusDecoder.cs rename to src/Discord.Net/Interop/OpusDecoder.cs index e6c9cd400..0341a8acf 100644 --- a/src/Discord.Net/Audio/OpusDecoder.cs +++ b/src/Discord.Net/Interop/OpusDecoder.cs @@ -1,6 +1,6 @@ using System; -namespace Discord.Audio +namespace Discord.Interop { /// Opus codec wrapper. internal class OpusDecoder : IDisposable diff --git a/src/Discord.Net/Audio/OpusEncoder.cs b/src/Discord.Net/Interop/OpusEncoder.cs similarity index 99% rename from src/Discord.Net/Audio/OpusEncoder.cs rename to src/Discord.Net/Interop/OpusEncoder.cs index c5e033a2b..d6209927f 100644 --- a/src/Discord.Net/Audio/OpusEncoder.cs +++ b/src/Discord.Net/Interop/OpusEncoder.cs @@ -1,6 +1,6 @@ using System; -namespace Discord.Audio +namespace Discord.Interop { /// Opus codec wrapper. internal class OpusEncoder : IDisposable diff --git a/src/Discord.Net/Audio/Sodium.cs b/src/Discord.Net/Interop/Sodium.cs similarity index 97% rename from src/Discord.Net/Audio/Sodium.cs rename to src/Discord.Net/Interop/Sodium.cs index ec7dde612..8d5d7e3cd 100644 --- a/src/Discord.Net/Audio/Sodium.cs +++ b/src/Discord.Net/Interop/Sodium.cs @@ -1,6 +1,6 @@ using System.Runtime.InteropServices; -namespace Discord.Audio +namespace Discord.Interop { internal unsafe static class Sodium { diff --git a/src/Discord.Net/Models/Channel.cs b/src/Discord.Net/Models/Channel.cs index 106335e8a..b7df1a2df 100644 --- a/src/Discord.Net/Models/Channel.cs +++ b/src/Discord.Net/Models/Channel.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using Discord.API; +using Newtonsoft.Json; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -99,16 +100,16 @@ namespace Discord _areMembersStale = true; } - internal void Update(API.ChannelReference model) + internal void Update(ChannelReference model) { if (model.Name != null) Name = model.Name; if (model.Type != null) Type = model.Type; } - internal void Update(API.ChannelInfo model) + internal void Update(ChannelInfo model) { - Update(model as API.ChannelReference); + Update(model as ChannelReference); if (model.Position != null) Position = model.Position.Value; diff --git a/src/Discord.Net/Models/Invite.cs b/src/Discord.Net/Models/Invite.cs index 1c523fc16..bdf1e6518 100644 --- a/src/Discord.Net/Models/Invite.cs +++ b/src/Discord.Net/Models/Invite.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using Discord.API; +using Newtonsoft.Json; namespace Discord { @@ -53,7 +54,7 @@ namespace Discord public override string ToString() => XkcdPass ?? Id; - internal void Update(API.Invite model) + internal void Update(InviteReference model) { if (model.Channel != null) ChannelId = model.Channel.Id; @@ -61,9 +62,9 @@ namespace Discord InviterId = model.Inviter.Id; } - internal void Update(API.ExtendedInvite model) + internal void Update(InviteInfo model) { - Update(model as API.Invite); + Update(model as InviteReference); if (model.IsRevoked != null) IsRevoked = model.IsRevoked.Value; if (model.IsTemporary != null) diff --git a/src/Discord.Net/Models/Member.cs b/src/Discord.Net/Models/Member.cs index c784fbb47..4360465de 100644 --- a/src/Discord.Net/Models/Member.cs +++ b/src/Discord.Net/Models/Member.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using Discord.API; +using Newtonsoft.Json; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -77,7 +78,7 @@ namespace Discord public override string ToString() => UserId; - internal void Update(API.UserReference model) + internal void Update(UserReference model) { if (model.Avatar != null) AvatarId = model.Avatar; @@ -86,7 +87,7 @@ namespace Discord if (model.Username != null) Name = model.Username; } - internal void Update(API.MemberInfo model) + internal void Update(MemberInfo model) { if (model.User != null) Update(model.User); @@ -102,7 +103,7 @@ namespace Discord UpdatePermissions(); } - internal void Update(API.ExtendedMemberInfo model) + internal void Update(ExtendedMemberInfo model) { Update(model as API.MemberInfo); if (model.IsServerDeafened != null) @@ -110,7 +111,7 @@ namespace Discord if (model.IsServerMuted != null) IsServerMuted = model.IsServerMuted.Value; } - internal void Update(API.PresenceMemberInfo model) + internal void Update(PresenceInfo model) { //Allows null if (Status != model.Status) @@ -121,7 +122,7 @@ namespace Discord } GameId = model.GameId; } - internal void Update(API.VoiceMemberInfo model) + internal void Update(VoiceMemberInfo model) { if (model.IsServerDeafened != null) IsServerDeafened = model.IsServerDeafened.Value; diff --git a/src/Discord.Net/Models/Message.cs b/src/Discord.Net/Models/Message.cs index b0cab1347..3d00a1265 100644 --- a/src/Discord.Net/Models/Message.cs +++ b/src/Discord.Net/Models/Message.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using Discord.API; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -175,7 +176,7 @@ namespace Discord MentionIds = _initialMentions; } - internal void Update(API.Message model) + internal void Update(MessageInfo model) { if (model.Attachments != null) { diff --git a/src/Discord.Net/Models/Role.cs b/src/Discord.Net/Models/Role.cs index 50c889e06..678bb31e1 100644 --- a/src/Discord.Net/Models/Role.cs +++ b/src/Discord.Net/Models/Role.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using Discord.API; +using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; @@ -52,7 +53,7 @@ namespace Discord Position = int.MinValue; } - internal void Update(API.RoleInfo model) + internal void Update(RoleInfo model) { if (model.Name != null) Name = model.Name; diff --git a/src/Discord.Net/Models/Server.cs b/src/Discord.Net/Models/Server.cs index 3d6554d42..c3f59fd45 100644 --- a/src/Discord.Net/Models/Server.cs +++ b/src/Discord.Net/Models/Server.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using Discord.API; +using Newtonsoft.Json; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -103,7 +104,7 @@ namespace Discord _roles = new ConcurrentDictionary(); } - internal void Update(API.GuildInfo model) + internal void Update(GuildInfo model) { AFKChannelId = model.AFKChannelId; AFKTimeout = model.AFKTimeout; @@ -124,9 +125,9 @@ namespace Discord isEveryone = false; } } - internal void Update(API.ExtendedGuildInfo model) + internal void Update(ExtendedGuildInfo model) { - Update(model as API.GuildInfo); + Update(model as GuildInfo); var channels = _client.Channels; foreach (var subModel in model.Channels) diff --git a/src/Discord.Net/Models/User.cs b/src/Discord.Net/Models/User.cs index d225c9b6d..a0104bcb3 100644 --- a/src/Discord.Net/Models/User.cs +++ b/src/Discord.Net/Models/User.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using Discord.API; +using Newtonsoft.Json; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -77,7 +78,7 @@ namespace Discord _servers = new ConcurrentDictionary(); } - internal void Update(API.UserReference model) + internal void Update(UserReference model) { if (model.Avatar != null) AvatarId = model.Avatar; @@ -86,11 +87,14 @@ namespace Discord if (model.Username != null) Name = model.Username; } - internal void Update(API.SelfUserInfo model) + internal void Update(UserInfo model) { - Update(model as API.UserReference); - Email = model.Email; - IsVerified = model.IsVerified; + Update(model as UserReference); + + if (model.Email != null) + Email = model.Email; + if (model.IsVerified != null) + IsVerified = model.IsVerified; } internal void UpdateActivity(DateTime? activity = null) { diff --git a/src/Discord.Net/WebSockets/Data/DataWebSocket.cs b/src/Discord.Net/Net/DataWebSocket.cs similarity index 98% rename from src/Discord.Net/WebSockets/Data/DataWebSocket.cs rename to src/Discord.Net/Net/DataWebSocket.cs index 53e917f9f..d95423348 100644 --- a/src/Discord.Net/WebSockets/Data/DataWebSocket.cs +++ b/src/Discord.Net/Net/DataWebSocket.cs @@ -1,9 +1,10 @@ -using Newtonsoft.Json; +using Discord.API; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Threading.Tasks; -namespace Discord.WebSockets.Data +namespace Discord.Net { internal partial class DataWebSocket : WebSocket { diff --git a/src/Discord.Net/WebSockets/Data/DataWebSockets.Events.cs b/src/Discord.Net/Net/DataWebSockets.Events.cs similarity index 94% rename from src/Discord.Net/WebSockets/Data/DataWebSockets.Events.cs rename to src/Discord.Net/Net/DataWebSockets.Events.cs index 410829069..6f5177fe1 100644 --- a/src/Discord.Net/WebSockets/Data/DataWebSockets.Events.cs +++ b/src/Discord.Net/Net/DataWebSockets.Events.cs @@ -1,7 +1,7 @@ using Newtonsoft.Json.Linq; using System; -namespace Discord.WebSockets.Data +namespace Discord.Net { internal sealed class WebSocketEventEventArgs : EventArgs { diff --git a/src/Discord.Net/DiscordAPIClient.cs b/src/Discord.Net/Net/DiscordAPIClient.cs similarity index 96% rename from src/Discord.Net/DiscordAPIClient.cs rename to src/Discord.Net/Net/DiscordAPIClient.cs index 44c5b6dc4..bb5f0fb06 100644 --- a/src/Discord.Net/DiscordAPIClient.cs +++ b/src/Discord.Net/Net/DiscordAPIClient.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -namespace Discord +namespace Discord.Net { /// A lightweight wrapper around the Discord API. public class DiscordAPIClient @@ -225,26 +225,6 @@ namespace Discord return _rest.Delete(Endpoints.ChannelPermission(channelId, userOrRoleId), null); } - //Profile - public Task EditProfile(string currentPassword = "", - string username = null, string email = null, string password = null, - AvatarImageType avatarType = AvatarImageType.Png, byte[] avatar = null) - { - if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword)); - - string avatarBase64 = null; - if (avatarType == AvatarImageType.None) - avatarBase64 = ""; - else if (avatar != null) - { - string base64 = Convert.ToBase64String(avatar); - string type = avatarType == AvatarImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64"; - avatarBase64 = $"data:{type},{base64}"; - } - var request = new EditProfileRequest { CurrentPassword = currentPassword, Username = username, Email = email, Password = password, Avatar = avatarBase64 }; - return _rest.Patch(Endpoints.UserMe, request); - } - //Roles public Task CreateRole(string serverId) { @@ -302,10 +282,30 @@ namespace Discord return _rest.Patch(Endpoints.Server(serverId), request); } + //User + public Task EditUser(string currentPassword = "", + string username = null, string email = null, string password = null, + AvatarImageType avatarType = AvatarImageType.Png, byte[] avatar = null) + { + if (currentPassword == null) throw new ArgumentNullException(nameof(currentPassword)); + + string avatarBase64 = null; + if (avatarType == AvatarImageType.None) + avatarBase64 = ""; + else if (avatar != null) + { + string base64 = Convert.ToBase64String(avatar); + string type = avatarType == AvatarImageType.Jpeg ? "image/jpeg;base64" : "image/png;base64"; + avatarBase64 = $"data:{type},{base64}"; + } + var request = new EditUserRequest { CurrentPassword = currentPassword, Username = username, Email = email, Password = password, Avatar = avatarBase64 }; + return _rest.Patch(Endpoints.UserMe, request); + } + //Voice public Task GetVoiceRegions() => _rest.Get(Endpoints.VoiceRegions); - public Task GetVoiceIce() - => _rest.Get(Endpoints.VoiceIce); + /*public Task GetVoiceIce() + => _rest.Get(Endpoints.VoiceIce);*/ } } diff --git a/src/Discord.Net/API/HttpException.cs b/src/Discord.Net/Net/HttpException.cs similarity index 68% rename from src/Discord.Net/API/HttpException.cs rename to src/Discord.Net/Net/HttpException.cs index e0dba7d06..84ae66530 100644 --- a/src/Discord.Net/API/HttpException.cs +++ b/src/Discord.Net/Net/HttpException.cs @@ -1,14 +1,14 @@ using System; using System.Net; -namespace Discord.API +namespace Discord.Net { public class HttpException : Exception { public HttpStatusCode StatusCode { get; } public HttpException(HttpStatusCode statusCode) - : base($"The server responded with error {statusCode}") + : base($"The server responded with error {(int)statusCode} ({statusCode})") { StatusCode = statusCode; } diff --git a/src/Discord.Net/API/RestClient.Events.cs b/src/Discord.Net/Net/RestClient.Events.cs similarity index 97% rename from src/Discord.Net/API/RestClient.Events.cs rename to src/Discord.Net/Net/RestClient.Events.cs index d5d257d49..85c4d02a1 100644 --- a/src/Discord.Net/API/RestClient.Events.cs +++ b/src/Discord.Net/Net/RestClient.Events.cs @@ -1,7 +1,7 @@ using System; using System.Net.Http; -namespace Discord.API +namespace Discord.Net { internal partial class RestClient { diff --git a/src/Discord.Net/API/RestClient.SharpRest.cs b/src/Discord.Net/Net/RestClient.SharpRest.cs similarity index 80% rename from src/Discord.Net/API/RestClient.SharpRest.cs rename to src/Discord.Net/Net/RestClient.SharpRest.cs index a7391fe14..31e4f4925 100644 --- a/src/Discord.Net/API/RestClient.SharpRest.cs +++ b/src/Discord.Net/Net/RestClient.SharpRest.cs @@ -1,17 +1,17 @@ -using RestSharp; +using Discord.API; +using RestSharp; using System; -using System.IO; using System.Net.Http; using System.Threading; using System.Threading.Tasks; -namespace Discord.API +namespace Discord.Net { - internal class RestSharpRestEngine : IRestEngine + internal partial class RestClient { - private readonly RestSharp.RestClient _client; + private RestSharp.RestClient _client; - public RestSharpRestEngine(string userAgent, int timeout) + partial void Initialize(string userAgent, int timeout) { _client = new RestSharp.RestClient(Endpoints.BaseApi) { @@ -24,20 +24,20 @@ namespace Discord.API _client.ReadWriteTimeout = timeout; } - public void SetToken(string token) + internal void SetToken(string token) { _client.RemoveDefaultParameter("authorization"); if (token != null) _client.AddDefaultHeader("authorization", token); } - public Task Send(HttpMethod method, string path, string json, CancellationToken cancelToken) + private Task SendInternal(HttpMethod method, string path, string json, CancellationToken cancelToken) { var request = new RestRequest(path, GetMethod(method)); request.AddParameter("application/json", json, ParameterType.RequestBody); return Send(request, cancelToken); } - public Task SendFile(HttpMethod method, string path, string filePath, CancellationToken cancelToken) + private Task SendFileInternal(HttpMethod method, string path, string filePath, CancellationToken cancelToken) { var request = new RestRequest(path, Method.POST); request.AddFile("file", filePath); diff --git a/src/Discord.Net/API/RestClient.cs b/src/Discord.Net/Net/RestClient.cs similarity index 90% rename from src/Discord.Net/API/RestClient.cs rename to src/Discord.Net/Net/RestClient.cs index 707bd785b..be1d9e4a6 100644 --- a/src/Discord.Net/API/RestClient.cs +++ b/src/Discord.Net/Net/RestClient.cs @@ -1,32 +1,25 @@ -using Newtonsoft.Json; +using Discord.API; +using Newtonsoft.Json; using System; using System.Diagnostics; using System.Net.Http; using System.Threading; using System.Threading.Tasks; -namespace Discord.API +namespace Discord.Net { - internal interface IRestEngine - { - void SetToken(string token); - Task Send(HttpMethod method, string path, string json, CancellationToken cancelToken); - Task SendFile(HttpMethod method, string path, string filePath, CancellationToken cancelToken); - } - internal partial class RestClient { - private readonly IRestEngine _engine; private readonly LogMessageSeverity _logLevel; private CancellationToken _cancelToken; public RestClient(LogMessageSeverity logLevel, string userAgent, int timeout) { _logLevel = logLevel; - - _engine = new RestSharpRestEngine(userAgent, timeout); } + partial void Initialize(string userAgent, int timeout); + //DELETE private static readonly HttpMethod _delete = HttpMethod.Delete; internal Task Delete(string path, object data) where ResponseT : class => Send(_delete, path, data); @@ -37,12 +30,14 @@ namespace Discord.API internal Task Delete(string path) => Send(_delete, path); + //GET private static readonly HttpMethod _get = HttpMethod.Get; internal Task Get(string path) where ResponseT : class => Send(_get, path); internal Task Get(string path) => Send(_get, path); + //PATCH private static readonly HttpMethod _patch = new HttpMethod("PATCH"); internal Task Patch(string path, object data) where ResponseT : class => Send(_patch, path, data); @@ -97,7 +92,7 @@ namespace Discord.API if (_logLevel >= LogMessageSeverity.Verbose) stopwatch = Stopwatch.StartNew(); - string responseJson = await _engine.Send(method, path, requestJson, _cancelToken).ConfigureAwait(false); + string responseJson = await SendInternal(method, path, requestJson, _cancelToken).ConfigureAwait(false); #if TEST_RESPONSES if (!hasResponse && !string.IsNullOrEmpty(responseJson)) @@ -136,7 +131,7 @@ namespace Discord.API if (_logLevel >= LogMessageSeverity.Verbose) stopwatch = Stopwatch.StartNew(); - string responseJson = await _engine.SendFile(method, path, filePath, _cancelToken).ConfigureAwait(false); + string responseJson = await SendFileInternal(method, path, filePath, _cancelToken).ConfigureAwait(false); #if TEST_RESPONSES if (!hasResponse && !string.IsNullOrEmpty(responseJson)) @@ -173,7 +168,6 @@ namespace Discord.API #endif } - internal void SetToken(string token) => _engine.SetToken(token); internal void SetCancelToken(CancellationToken token) => _cancelToken = token; } } diff --git a/src/Discord.Net/WebSockets/Voice/VoiceBuffer.cs b/src/Discord.Net/Net/VoiceBuffer.cs similarity index 92% rename from src/Discord.Net/WebSockets/Voice/VoiceBuffer.cs rename to src/Discord.Net/Net/VoiceBuffer.cs index 8f3dc9f53..29bcb8e77 100644 --- a/src/Discord.Net/WebSockets/Voice/VoiceBuffer.cs +++ b/src/Discord.Net/Net/VoiceBuffer.cs @@ -1,7 +1,7 @@ using System; using System.Threading; -namespace Discord.WebSockets.Voice +namespace Discord.Net { internal class VoiceBuffer : IDiscordVoiceBuffer { @@ -46,7 +46,11 @@ namespace Discord.WebSockets.Voice if (_readCursor == nextPosition) { _notOverflowEvent.Reset(); - _notOverflowEvent.Wait(cancelToken); + try + { + _notOverflowEvent.Wait(cancelToken); + } + catch (OperationCanceledException) { return; } } if (i == wholeFrames) @@ -100,7 +104,11 @@ namespace Discord.WebSockets.Voice _isClearing = true; for (int i = 0; i < _frameCount; i++) Buffer.BlockCopy(_blankFrame, 0, _buffer, i * _frameCount, i++); - _underflowEvent.Wait(cancelToken); + try + { + _underflowEvent.Wait(cancelToken); + } + catch (OperationCanceledException) { } _writeCursor = 0; _readCursor = 0; _isClearing = false; diff --git a/src/Discord.Net/WebSockets/Voice/VoiceWebSocket.Events.cs b/src/Discord.Net/Net/VoiceWebSocket.Events.cs similarity index 95% rename from src/Discord.Net/WebSockets/Voice/VoiceWebSocket.Events.cs rename to src/Discord.Net/Net/VoiceWebSocket.Events.cs index e2e676986..82f525158 100644 --- a/src/Discord.Net/WebSockets/Voice/VoiceWebSocket.Events.cs +++ b/src/Discord.Net/Net/VoiceWebSocket.Events.cs @@ -1,6 +1,6 @@ using System; -namespace Discord.WebSockets.Voice +namespace Discord.Net { internal sealed class IsTalkingEventArgs : EventArgs { diff --git a/src/Discord.Net/WebSockets/Voice/VoiceWebSocket.cs b/src/Discord.Net/Net/VoiceWebSocket.cs similarity index 98% rename from src/Discord.Net/WebSockets/Voice/VoiceWebSocket.cs rename to src/Discord.Net/Net/VoiceWebSocket.cs index 76a42d6b4..59f48da47 100644 --- a/src/Discord.Net/WebSockets/Voice/VoiceWebSocket.cs +++ b/src/Discord.Net/Net/VoiceWebSocket.cs @@ -1,5 +1,6 @@ #define USE_THREAD -using Discord.Audio; +using Discord.API; +using Discord.Interop; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; @@ -13,7 +14,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -namespace Discord.WebSockets.Voice +namespace Discord.Net { internal partial class VoiceWebSocket : WebSocket { @@ -109,8 +110,8 @@ namespace Discord.WebSockets.Voice #if !DNX451 && !__MonoCS__ _udp.AllowNatTraversal(true); #endif - - LoginCommand msg = new LoginCommand(); + + VoiceLoginCommand msg = new VoiceLoginCommand(); msg.Payload.ServerId = _serverId; msg.Payload.SessionId = _sessionId; msg.Payload.Token = _token; @@ -238,7 +239,7 @@ namespace Discord.WebSockets.Voice int port = packet[68] | packet[69] << 8; string ip = Encoding.ASCII.GetString(packet, 4, 70 - 6).TrimEnd('\0'); - var login2 = new Login2Command(); + var login2 = new VoiceLogin2Command(); login2.Payload.Protocol = "udp"; login2.Payload.SocketData.Address = ip; login2.Payload.SocketData.Mode = _encryptionMode; @@ -458,7 +459,7 @@ namespace Discord.WebSockets.Voice { if (_state != (int)WebSocketState.Connected) { - var payload = (msg.Payload as JToken).ToObject(); + var payload = (msg.Payload as JToken).ToObject(); _heartbeatInterval = payload.HeartbeatInterval; _ssrc = payload.SSRC; _endpoint = new IPEndPoint((await Dns.GetHostAddressesAsync(Host.Replace("wss://", "")).ConfigureAwait(false)).FirstOrDefault(), payload.Port); diff --git a/src/Discord.Net/WebSockets/WebSocket.BuiltIn.cs b/src/Discord.Net/Net/WebSocket.BuiltIn.cs.old similarity index 99% rename from src/Discord.Net/WebSockets/WebSocket.BuiltIn.cs rename to src/Discord.Net/Net/WebSocket.BuiltIn.cs.old index e413c2432..af375e743 100644 --- a/src/Discord.Net/WebSockets/WebSocket.BuiltIn.cs +++ b/src/Discord.Net/Net/WebSocket.BuiltIn.cs.old @@ -1,5 +1,4 @@ -/* -using Discord.Helpers; +using Discord.Helpers; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -149,5 +148,4 @@ namespace Discord.WebSockets _sendQueue.Enqueue(message); } } -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/src/Discord.Net/WebSockets/WebSocket.Events.cs b/src/Discord.Net/Net/WebSocket.Events.cs similarity index 96% rename from src/Discord.Net/WebSockets/WebSocket.Events.cs rename to src/Discord.Net/Net/WebSocket.Events.cs index 9824fbff8..1c2383198 100644 --- a/src/Discord.Net/WebSockets/WebSocket.Events.cs +++ b/src/Discord.Net/Net/WebSocket.Events.cs @@ -1,6 +1,6 @@ using System; -namespace Discord.WebSockets +namespace Discord.Net { internal abstract partial class WebSocket { diff --git a/src/Discord.Net/WebSockets/WebSocket.WebSocketSharp.cs b/src/Discord.Net/Net/WebSocket.WebSocketSharp.cs similarity index 98% rename from src/Discord.Net/WebSockets/WebSocket.WebSocketSharp.cs rename to src/Discord.Net/Net/WebSocket.WebSocketSharp.cs index c55196259..f245dd24e 100644 --- a/src/Discord.Net/WebSockets/WebSocket.WebSocketSharp.cs +++ b/src/Discord.Net/Net/WebSocket.WebSocketSharp.cs @@ -5,7 +5,7 @@ using System.Threading; using System.Threading.Tasks; using WSSharpNWebSocket = WebSocketSharp.WebSocket; -namespace Discord.WebSockets +namespace Discord.Net { internal class WSSharpWebSocketEngine : IWebSocketEngine { diff --git a/src/Discord.Net/WebSockets/WebSocket.cs b/src/Discord.Net/Net/WebSocket.cs similarity index 99% rename from src/Discord.Net/WebSockets/WebSocket.cs rename to src/Discord.Net/Net/WebSocket.cs index 6f9165f8c..cf93518c3 100644 --- a/src/Discord.Net/WebSockets/WebSocket.cs +++ b/src/Discord.Net/Net/WebSocket.cs @@ -6,7 +6,7 @@ using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; -namespace Discord.WebSockets +namespace Discord.Net { public enum WebSocketState : byte { diff --git a/src/Discord.Net/WebSockets/Data/Commands.cs b/src/Discord.Net/WebSockets/Data/Commands.cs deleted file mode 100644 index 90b4e59d3..000000000 --- a/src/Discord.Net/WebSockets/Data/Commands.cs +++ /dev/null @@ -1,64 +0,0 @@ -//Ignore unused/unassigned variable warnings -#pragma warning disable CS0649 -#pragma warning disable CS0169 - -using Newtonsoft.Json; -using System.Collections.Generic; - -namespace Discord.WebSockets.Data -{ - internal sealed class KeepAliveCommand : WebSocketMessage - { - public KeepAliveCommand() : base(1, EpochTime.GetMilliseconds()) { } - } - internal sealed class LoginCommand : WebSocketMessage - { - public LoginCommand() : base(2) { } - public class Data - { - [JsonProperty("token")] - public string Token; - [JsonProperty("v")] - public int Version = 3; - [JsonProperty("properties")] - public Dictionary Properties = new Dictionary(); - } - } - internal sealed class UpdateStatusCommand : WebSocketMessage - { - public UpdateStatusCommand() : base(3) { } - public class Data - { - [JsonProperty("idle_since")] - public ulong? IdleSince; - [JsonProperty("game_id")] - public int? GameId; - } - } - internal sealed class JoinVoiceCommand : WebSocketMessage - { - public JoinVoiceCommand() : base(4) { } - public class Data - { - [JsonProperty("guild_id")] - public string ServerId; - [JsonProperty("channel_id")] - public string ChannelId; - [JsonProperty("self_mute")] - public string SelfMute; - [JsonProperty("self_deaf")] - public string SelfDeaf; - } - } - internal sealed class ResumeCommand : WebSocketMessage - { - public ResumeCommand() : base(6) { } - public class Data - { - [JsonProperty("session_id")] - public string SessionId; - [JsonProperty("seq")] - public int Sequence; - } - } -} diff --git a/src/Discord.Net/WebSockets/Data/Events.cs b/src/Discord.Net/WebSockets/Data/Events.cs deleted file mode 100644 index 2ed5c4b4b..000000000 --- a/src/Discord.Net/WebSockets/Data/Events.cs +++ /dev/null @@ -1,115 +0,0 @@ -//Ignore unused/unassigned variable warnings -#pragma warning disable CS0649 -#pragma warning disable CS0169 - -using Discord.API; -using Newtonsoft.Json; - -namespace Discord.WebSockets.Data -{ - internal sealed class ReadyEvent - { - public sealed class ReadStateInfo - { - [JsonProperty("id")] - public string ChannelId; - [JsonProperty("mention_count")] - public int MentionCount; - [JsonProperty("last_message_id")] - public string LastMessageId; - } - - [JsonProperty("v")] - public int Version; - [JsonProperty("user")] - public SelfUserInfo User; - [JsonProperty("session_id")] - public string SessionId; - [JsonProperty("read_state")] - public ReadStateInfo[] ReadState; - [JsonProperty("guilds")] - public ExtendedGuildInfo[] Guilds; - [JsonProperty("private_channels")] - public ChannelInfo[] PrivateChannels; - [JsonProperty("heartbeat_interval")] - public int HeartbeatInterval; - } - internal sealed class ResumedEvent - { - [JsonProperty("heartbeat_interval")] - public int HeartbeatInterval; - } - - internal sealed class RedirectEvent - { - [JsonProperty("url")] - public string Url; - } - - //Servers - internal sealed class GuildCreateEvent : ExtendedGuildInfo { } - internal sealed class GuildUpdateEvent : GuildInfo { } - internal sealed class GuildDeleteEvent : ExtendedGuildInfo { } - - //Channels - internal sealed class ChannelCreateEvent : ChannelInfo { } - internal sealed class ChannelDeleteEvent : ChannelInfo { } - internal sealed class ChannelUpdateEvent : ChannelInfo { } - - //Memberships - internal sealed class GuildMemberAddEvent : MemberInfo { } - internal sealed class GuildMemberUpdateEvent : MemberInfo { } - internal sealed class GuildMemberRemoveEvent : MemberInfo { } - - //Roles - internal sealed class GuildRoleCreateEvent - { - [JsonProperty("guild_id")] - public string GuildId; - [JsonProperty("role")] - public RoleInfo Data; - } - internal sealed class GuildRoleUpdateEvent - { - [JsonProperty("guild_id")] - public string GuildId; - [JsonProperty("role")] - public RoleInfo Data; - } - internal sealed class GuildRoleDeleteEvent : RoleReference { } - - //Bans - internal sealed class GuildBanAddEvent : MemberReference { } - internal sealed class GuildBanRemoveEvent : MemberReference { } - - //User - internal sealed class UserUpdateEvent : SelfUserInfo { } - internal sealed class PresenceUpdateEvent : PresenceMemberInfo { } - internal sealed class VoiceStateUpdateEvent : VoiceMemberInfo { } - - //Chat - internal sealed class MessageCreateEvent : API.Message { } - internal sealed class MessageUpdateEvent : API.Message { } - internal sealed class MessageDeleteEvent : MessageReference { } - internal sealed class MessageAckEvent : MessageReference { } - internal sealed class TypingStartEvent - { - [JsonProperty("user_id")] - public string UserId; - [JsonProperty("channel_id")] - public string ChannelId; - [JsonProperty("timestamp")] - public int Timestamp; - } - - //Voice - internal sealed class VoiceServerUpdateEvent - { - [JsonProperty("guild_id")] - public string GuildId; - [JsonProperty("endpoint")] - public string Endpoint; - [JsonProperty("token")] - public string Token; - } -} diff --git a/src/Discord.Net/WebSockets/Voice/Commands.cs b/src/Discord.Net/WebSockets/Voice/Commands.cs deleted file mode 100644 index 740f235bc..000000000 --- a/src/Discord.Net/WebSockets/Voice/Commands.cs +++ /dev/null @@ -1,59 +0,0 @@ -//Ignore unused/unassigned variable warnings -#pragma warning disable CS0649 -#pragma warning disable CS0169 - -using Newtonsoft.Json; - -namespace Discord.WebSockets.Voice -{ - internal sealed class LoginCommand : WebSocketMessage - { - public LoginCommand() : base(0) { } - public class Data - { - [JsonProperty("server_id")] - public string ServerId; - [JsonProperty("user_id")] - public string UserId; - [JsonProperty("session_id")] - public string SessionId; - [JsonProperty("token")] - public string Token; - } - } - internal sealed class Login2Command : WebSocketMessage - { - public Login2Command() : base(1) { } - public class Data - { - public class SocketInfo - { - [JsonProperty("address")] - public string Address; - [JsonProperty("port")] - public int Port; - [JsonProperty("mode")] - public string Mode = "xsalsa20_poly1305"; - } - [JsonProperty("protocol")] - public string Protocol = "udp"; - [JsonProperty("data")] - public SocketInfo SocketData = new SocketInfo(); - } - } - internal sealed class KeepAliveCommand : WebSocketMessage - { - public KeepAliveCommand() : base(3, null) { } - } - internal sealed class IsTalkingCommand : WebSocketMessage - { - public IsTalkingCommand() : base(5) { } - public class Data - { - [JsonProperty("delay")] - public int Delay; - [JsonProperty("speaking")] - public bool IsSpeaking; - } - } -} diff --git a/src/Discord.Net/WebSockets/Voice/Events.cs b/src/Discord.Net/WebSockets/Voice/Events.cs deleted file mode 100644 index a2bd730df..000000000 --- a/src/Discord.Net/WebSockets/Voice/Events.cs +++ /dev/null @@ -1,38 +0,0 @@ -//Ignore unused/unassigned variable warnings -#pragma warning disable CS0649 -#pragma warning disable CS0169 - -using Newtonsoft.Json; - -namespace Discord.WebSockets.Voice -{ - internal sealed class ReadyEvent - { - [JsonProperty("ssrc")] - public uint SSRC; - [JsonProperty("port")] - public ushort Port; - [JsonProperty("modes")] - public string[] Modes; - [JsonProperty("heartbeat_interval")] - public int HeartbeatInterval; - } - - internal sealed class JoinServerEvent - { - [JsonProperty("secret_key")] - public byte[] SecretKey; - [JsonProperty("mode")] - public string Mode; - } - - internal sealed class IsTalkingEvent - { - [JsonProperty("user_id")] - public string UserId; - [JsonProperty("ssrc")] - public uint SSRC; - [JsonProperty("speaking")] - public bool IsSpeaking; - } -} diff --git a/src/Discord.Net/WebSockets/WebSocketMessage.cs b/src/Discord.Net/WebSockets/WebSocketMessage.cs deleted file mode 100644 index c63bd4787..000000000 --- a/src/Discord.Net/WebSockets/WebSocketMessage.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace Discord.WebSockets -{ - public class WebSocketMessage - { - [JsonProperty("op")] - public int Operation; - [JsonProperty("d")] - public object Payload; - [JsonProperty("t", NullValueHandling = NullValueHandling.Ignore)] - public string Type; - [JsonProperty("s", NullValueHandling = NullValueHandling.Ignore)] - public int? Sequence; - } - internal abstract class WebSocketMessage : WebSocketMessage - where T : new() - { - public WebSocketMessage() { Payload = new T(); } - public WebSocketMessage(int op) { Operation = op; Payload = new T(); } - public WebSocketMessage(int op, T payload) { Operation = op; Payload = payload; } - - [JsonIgnore] - public new T Payload - { - get { if (base.Payload is JToken) { base.Payload = (base.Payload as JToken).ToObject(); } return (T)base.Payload; } - set { base.Payload = value; } - } - } -} diff --git a/src/Discord.Net/packages.config b/src/Discord.Net/packages.config deleted file mode 100644 index 505e58836..000000000 --- a/src/Discord.Net/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file