zC$R<4uR>dIM?Ue8yWsk^9clgy+zDD^7zfY<5)Xwsf7>jL{%qrPYlY=CLUP!!5 zUrCL*qdSw&1z87Wz@kW-x7(>U%3GDHv$!kQxz3P0^RR+>S|eXg*}WLi8tc|a)~S3;da+Hen9Yj#ob zw?7?=!*!2xPK_6G%Zd%bL=uc_V}Ho{Z$hj&=I^g1wR6u0))DK=vcB%~zzw`spL_$p zlL1pSLfuz-u4o-7M9&Wd5vZGPZrqv!CTgPKPKL 0x3d5+f!S5UTy-+6!SA^sqPdBdSi%bVF##L;Q7F%qbxe9y~O_Y1Zg (e~<7_$k5W2r_dg}5Q>@n+*F z3~?J9y`=OT?#}GaHg%zYh|LZWPJKrhOSKq(4$*3$|8fe-gDp@~$95b4EF9XMIQ#j+ zI` *a)y6`r^{u7cB zEXl+s%yW-Z=-i2I6pLjUw2km4gYTZ#3G@|LMWVqSG7)jx?E#lXS{$jk$aysb_jJeP zPkXGEOO`^sD&yJPieHF4maZ~@Sa+X+W-Fhd9uvU7Gm}^8>!H}O3;QP?X)y6=icP>g zeZt-Jz&*xtC-y7)Xgw%1&Uht^q*vi&^mK+3OPeP_RU Z;;_1tUp- zCd%mCb2w?%6x4q9^;naZpAAtE7D=y%1_Zu@%2LO@8i~xh;9s3rQgY9y*n}XngI=zD zaz%6y_VVer7Kbuzmfc0IJjC??A)#9vP#i~L1n5PORNak4o8&94ruhl + zFL`gOz#|wFSo(WuDu(Hb0^Y@lhz*QgVh`^if&+cmx3k|o27XmAH(5F*L*6TuID*tY z5F&Yc^>~SRjymCLcNJ9dY(fXsl!W~IGTfmDlK|5N*;+?hE-Z|cBk$%zc=X3EIodiD z2Lbx9WMbx>GC)bifpj#rVpD!pM~lk{O|s>@re@;tu4(rd{{Vz%V3 )y7Kg&VIEVxGnL=9}3owQ_g`}G%A-<3Unf(`ZSHI cRNLz~~8S$gq7hTt3sL*fu@!%4(Bb3BMv}S-{y9u^A9A%!P;l8Yo-^pl~s0 zrT+Y|iEGdf1d|x^M0Q*`O!POYJLx4}mB*1wF-q Xp=ZUFW&)d zft*7z@WZ^#56FR 3AU<6hvP-d zS89WLP6c5J(fmp&@NNc#6!tqvD?PjJ+ZSR+2KT*Hh{*qHn^+4WR4gGGA}~Lt_(Ei) ztTH#6DGRTZlhpU($#PD2*>OEH{9rbq( oJc;Nm$(0}kDZ z#>H?cfVz5=1EZ>tH+0kB7*MWN0sSQut|?EKtMi06{tlP!m&Ll$me&8R{ByYW?uT#c z?Hk{Ej_UPqMF)HNVQ7LHXv401H@F7PiqD2Voo#7tDwyQwwF+bLe4vTl!1BXB^C w8AkCk&u{*u=$`uI zK+|6?|5ck}PjKs96 Lpz1Bv~Ak8}ySnfgM3cU1^J*f<*D|epOZr@ctnVnK^RzZu&{m?+w<) zJlID#*Wk(eR+=wl^}Q**rC#5nT9_;>gt+tVJ04*?Ma1F?HfT{ueTt3J^J2ka`GxEU zG=?Yh%H~bI14TaRM(uxl_vCuR*mWAb)BZ^Lq^;fGkO7T+Hx26=@vUIaYHc8FDL->3 zwwuh6CLTU#)dLA4Bn@t8l2f_fTHyXd1g5fzpxqKpBzZ`Ai8u86_Oy>Q?6DPEjRg6( z+z@Yg866f*_zi_&18wdaEslOza?0R!mCJ&OWmP!$6o!jta_Q`VrK$JKPjWbj?#isT zRQmE)7P($^qlcv4Y3w|_+Ycg0=ZHO1N%eCw+2mHUFDO_C{e~LGMKv_78HvB=D{+uS zlKKXsqLS+CRY^mSBgrd>0n>aCHX*4IGUt$;>0D2p$c<`pMbC?w8?R*%sDy3Bded0c z5B$pReA3!uA4rWCQ{c-t@w2%(eoKxPr`*(Q+XmZj&6>o__*&P?FrJ<%yAz3$3C_Lf z^GUm{ID6!G>Ob`4*I(U7*QMc4W@orBFsv*V_*|u=nNzagJqEokAn|!hE-c3*?*d0o z`DIb!*sX`e$FIY&OJwdDS0{;j;B$#8N*pi`lKcq0y_z;22AK17b-tUX+3h?sA(Q_L zAm!Ef@T>HVrpbIMZYE=jKwbXWwqkoc>xZsCNavR5wYAoq8{N3^`s~+8q2J!1?w|SO z%w_Zaliy{T%aaNG8s*sjangrKMR %z$|i%W#!+Fv?i3r&Pg%An0jz@{bV2~=Eti>5qV z Tol!K4{eNM3%QrH;gowNM{GJZ#usXZv{FN6V%|Pnc6kM4z<=oJ{Nf@iJyJ zHc~`{rQUhU<@?A-6I#@rhP ew%e{^Z@FP$F>;9Jj5lsw5 l-8x zj@DLCa*2CZOAETw{4&8C*(YY!#j0bRST26&C;f)u;+vH)qtexV{khwl64+*Ri3k zTkY@9#;n08dfU32Vt>wK=mQHck>Hgr@%y2~ZGEkHbS8=D0rkAP_PoJr>F>`m+zwby z(C7iRXbfV2$r#~$DD(5CW-WQIg`U1Tc){VjK3*xw3;Oa0M0q6q=Q^L1di|R}v#vj@ z0TWQk_sSL3AAq7Lv0^HeT!0uG;JO~iN`_Ss__ZaRfwfwHH$_Pi!gFQL1t=eiSi828 zHkpRq@4Dkk^c>F;RNpi{xJp)N!J$ddPmxd-Oeo~%>3Ml^XOZ;oc*G>-t4ROEoUG7< zr^B>htTvE(^JWs$azD@M#RK?)IIivI;MbQ9eD*4aJ7p`KG3Z&y>a@e|Gv93b=^6w(~hsQ$ZEH?vD5!6pudEsE3YKq{(jf*@@ zq3gVe4=H2y$pg|mFVVZ^UDGCKFm1Sd-foppk5d`1flDa~ih#^e>B~n%Kux6MO77rV zMIFu9&qQqJpGwT#lpPWDnzmDX9#dcKKyAAZ^>l|UWcc~I8msNr2!}x;y#HIpZbQ+n zt7@lT68L?2mPj(_B;X1ZelYH>t@CqxYxkvk%Muh(RfqvB8y}I)T@8A>&fA$#9c7g= z0C>fT8>l3#qza8Z+f~DlTQgU5K~o2~t~gc$H?90kv^EalhdCod#jWAtC!|ILRUmj? zJq9U;A=GGrI$QLW%(?zLShKOs-1N{dapvnks7KyP?PQ%k+_oLx7#cY #YNNZk0eRD8 z& B;a$pPL-5deSVVZ2|^BYVJw!8K2#CP2wm(CGRK_2R5d9! z;KCxxDq__6xlfVjFk(EvN!*E~tsE@^ae8scY;|qCau@rfY^K@Tf!H>ux02xEyrI_B zWQ5I8uf(P`E$;BCKqR?Ue=F4&SOz;Tr7b$w5V`}#LG%ncZ|DV{_0Zt%ApB7i^O7&= zslJ77sEGbHcuP@*M7csu0MF)JU|`0}I!6w)oJ^9+$76yVHuo%SrwG@UM5(NH#7-F* z5VD|kaX+tdkt3bk>cHG|u#WMqKp%4rFpPDHW<4dDRdG9m(rvL*ak88<6?BX*JB?Kl z%AJ_};67dMnYML3u5pe$gVGDG@ZqK>;yfdz4BX{HzRuWT>Q8c)L^{o&ufN59OB1bA zTM1#`1C({AHolCAOsLD^f3xSLeDOR _gH(wXG@Ne(*cY>l?qn~n-TyY_YeU1$VOkcSav zG9SOoM>LIx%~qHp%F #I`sl z4+_@5a?tSSc+P=C@2T4h+;O;AdYT4iMxs|IL2Pw2b+z!DDsvu}5Gpz_eC-JF$7E?G z_O7LrCfg+y_E&dorW#-VS|r!I0@Nc87!XIuE+Ins5@e|)*q5luwSBXf6mOoou-h%i z|0>G+cc)?kTNd_v^@VZ_Ep=Fb;;vqn4H%9C&05S@XIiZn^akICq3`Rh{M7YwkfJyl zB`g*ymRLS22zf~S^58zT8L^PSu~NggPysOZaSP>F@_@UB7r;E=owD3~#;$IhyuxBC zNUEz}1U2=3k^<(D2U{ZZbSB#$#2KSGKV%c5IA9qN5F4Nf@&rB{Ez#+>J@f8ci6lmi zta T+a=>x(xh4tm`JuX}JwF|GYstyd8+{{bB tYSX!^J4Ef6hYMi zb!6Uu;1QJcoO8T3sHT=zD^IdWkDhlY;>PX=O<$z6+18{6h;xoifDL70ok3DAbMIV@ zitpFz%Gh`K6;qp1%}Gv3NBo?liI67|m07wsC$_77HOTElzxdffVi_D#-rG TlLa}_Dh}H{g6yu{ewn>yc!~W9A3vqdzKnf?h%g5)QFd4X zEQRut@G&NWl>P?LnWC}Su&L0C15k`y6KI32D8OXTn?eJC0?CtbzPTcrpH6bmGTjw5 zu_|zPVq-RN$50#_O?=aXEP}K@D?W_RKG)&BBc{;4<1xnb(R|rJJeY)C+U>8 4B9;_w7U6 z8~WWYiaCy8BTK)6=A} Uyv&2A(}{} z4Zv8=A;iF4;XDJ7ue6?Gc5Kc Fo;8hV ^<{WY!Sqm*T6dU?qj@Xi&Uyg%Iy%lzLp;rsrf-6ci{Lb$vYy>m z=FhodcS!{fBEw5M@#X8ty{F`wf8m7*t4d@pS8DIPrSM2Y$Ut9DBS|& @no_m%4Ob&uG zWItuZuz$>_MYUfHvOkiBpJ&L6nhT%D=AN7Hw&o?ukijJeFOedC0#(VN+q((5Yo96& z4?THE+D(z;jWq|!!N`*u ;LTF^Xpgov!& z{;C7$Ch@1Tq-((>$%SHzFF(OFt{#_((Xn)L3SwWKj+i}mpsMkLx2wW &+qqVU9Z=3o#z>k^El_VO77aQgefv? z&`ml$47KUqjJKh@?fYeea5u4P`yzzpOcLdI_>G^y5_h)`!Inj2EkI0a4W9-^RqR`V zMz1oaL3rM-a(V<%@ULCFv3W6sr;umKK=u50$4VneVk_p7UvQ*s;{Cy|l}*3hwrt{6 zno0sMUe1|H=s47L5o~LaJSF#j%IuWEE7uoL!C1RwLE}IbMJ|?#J`CwEjm^FuS(3tA zaUQGFG++imZu_fIk@wxR0nW p*#&kwkxS@ZOweeNb$YGoRiKxIRTOX=arZaTQ)T2KLbNu% }?9iVO z&g8o&L9kkVmxnsL->63*7-$7WVLOtkZ>QTM }F`dUtLh TkxC>;Z-lBvUpVypp HOVSvbTSwd(iWeBLnzr%)Vo)s@f5PhwrJk{yKpL6n3*dkunkUVdJ zCT>A_9-fOwC}#q>-}6{Z5SHrwU&wYhEmZhUxPS|MTHhaM{&2NIuQI;rQ-Zxc;+-|N zRHswU9ORp#WW}u^-9VYCO93n{0*!4wdUyQRs4Kv$L^)RJm8KP!2%nqNL|3kk|8eXM zv%GjCYu~ONF_SPJ`^sPLRto+dn{Kju>w>ZbntpKyXk8EGaf3CFr|_OR;Zj1TnxK=mun>0yJ%5$LIx=<8gjd2mwr$WPDN)1Z0At zF3U1*BeGUpADnk@>z^;aQPRdyYp-8knU%g|08#I%pFHCmY8M3AqsgE@9NSkNW(@nt zkKPXw2_J!j?I=Kzby=1yeAruE;Sy-1&p#d)W}cuO*L@D8?J{PdsRs_r*@|#GNy=(t zML7)JUD3Bp$qOP=-KBWNlN+!<>g_gR{1pzs`WA5whh^`+YjDu|hg}+{@q=`#$GvdS z@}qWQ_0r?foa8V_{MGZ@KGUlo>(p;~Z=K=-EF1R~{7sH#>51oU8p5f88&Ux2{xV~G z#qAE&EzQjDxNJ?=K%7wvbiycu%}bpED3K{QgvS&BS0L@g?>AEaUj0R`s2Im*_{gKZ zsSIn{z>0~;U&MKFJ>nf(x8K{bui}^2(N9YSak=k?3MVi8gE;O%3GLZ6etiGs2hvy% zehhuj{FBnpuI|rp?BAM8#JewV{oT7O_HRRNjTa6e&8@;W!^O933(NvgsB@>Vw#X$` z@W&=X4`SpqW25swPR6QClL3%zyUyVq*y_Gv;HtnTxP_pymN <;PJ^H+h%jb{%TT*2ay1k|409hU(H|B$y`>)R>*TH}+pq@gTLK)4MC z3Kl@y4 {auQCDjxul`P7#Zd6-tDu2}BXTY}Pe63Hu^dL&e4t_Zb2$tFwi)DbsJ z0n?&ZjPzmuQ{b=NCOU+h*6@5*z>uXTn8)k8PT0Lsq0FEyCz 9`cWwjSaR({k>8-)2)R{`q-v3&BT;-UZ~Y5p{-byI uu zK25 O8dr1bsx9nfbEX*%fqOtw<`cyJe-j; z!&RvDstllt$m5f0Pru}@OERQiY5iR*PuYE!)n3_DW_$MGv?)k1T1+r)%_j&IYT&La zB`D!#Pgn-32^=u23h(XZ3YUrzlJl!|l$`Lek`v|{*VexrN&cH=thIWILxK~d0P0O0 zb)3x{4|BpMd2wa!TGf9RZ+ZU!P3eD*n#PK@3IOk%1gcf$BY7t1v$+62oDy6)Fb(-5 zf$4wY+wLUdW;F4{_S8d8q7Cn|*NR(CzA3#~O8eCDi34+cm&Jvz7CkSyeISziLWdv# z=94}_mk$)?2wmdt*bhM9B50$sJkCh1EYb5;6%GnA6x_A#du3tRb)PnD-tn`mkorBP zk9eKtv#Zw=0HvX5;n8m7D&%J2AM=-IiaxhNBhWR}o@|Ut7qmi$_3YG<5h&0WmbkL} z%4PvgC7l;QS&`XU8NY1q`^|xH>)4a}vI&TeNTMRh6ismB#MizbEw5txlr+`wFA`00 z<-plf?E*Z!`?6GMTdK6L^aJ2RR*#2f8tK-4=r6x|%Xi|c{JwBV@+*&$`7>&8*`oqY zo`S0lJ{8 z7^GCx`v;aHaaQG@&cx|r2H17&d^jBdZh)lNh8r38T#8or7?Cq6D$KdYyFt1b;8SP_ zmFriS->Fu+wo;(u^6LvgPYIPt1J&meWz8)HkUj}^{q4#@Bt>YE{juz@#3B#(gEUdo zQxi<93n51w#6FAUaqZ!=bWUdHJTwhpF77A;$Xgh&`J|wWyE(4ac!%J`GL)0u{Rv3! z=jCN}Fd&wO2LF?#a>Dt;QUvE_ySCd!Wy(J`R6xzY-QlcrCK=TiYqIAc=lv UA<}ZzC@iIxSSS&9$3fsiq*5p2^ bS3x+Jyu`$Eb*-VWgT1b zX?7LDFO*xPE$9ZIfJ!MW^nktelVirQ<$rdaJ&rXq%adzLd;pKX1}lD`vv%?9fp4l5 zd9{OqI}ic$@5(ie{)=fuD=$;9R&9{#|6o3`J?MJp=$?PvIQRq{#r;PKVA@8z{s;qF zSaX^}AYea!L_>aJJF_*EjGksiUOwuN;>$V>=ySaH9FN>NMb12~+6-0svNmqC>8gwi z^G7nc0#=4Gf!q&af&FVAaEg?<%_yb#Ab~(J4`f|vc{wp402o;-m_+mo2$9VsJsW4t z>aAD<7=huL0Nm(`9YAN{nZU5-FvI>280^tH0#K9q(YEAQmxn!DT{;0u>xX+>^lP9{ zs?P|bB*8u|a|1;Lfs4ewEbjNQ9w*tPq5N4)_p%aSr5Elg6opsaDlhL@wS!c{Zm431 zko&n4Asm9AznyG0W?4vx2YVz&Oi*$PvekiFR^e2gNgMrrx*E>o=6d!0d7j^4hCH%A z=7&xE7NP@reshf!Vcn)R5{|{>fwlEKon;$|XK<5`^6r2JiSr(QcnS0dq@C8*F3R%R zv5_y7(f~WH3uC-YYkI8&*?{QV-fR~!EnQAXetmh^y!GmoNfMw8?I)Z$?KopV ut1= emuK6xJ|^KV#KoZXotq4g?ASyqeCY6=_0R3e z@Z_BJao*hpfymR?ojtIXeEA67en_D#PL0oRgryhP9k6K6>P83i&FM^$4nV&OM=X{U zUv0Lj#YaOBo=LrbI%=%HXT@RFLP5SP^ma$!`*&dwwI_c1uQqG@{z4z>)$Tley>7M? zHULj%i+`bnXv+? e?Cl zr|gc&0%_>JZsaH4_EP*d>$hE#lz3Md@k0^z7-zswcBK!l0 *>Abm43}X8$gS3a zu<4-B?FWz%)DsdY5ytyfai&3MGG3Pzs3Mfw)FQ-JdvJj2wB)0Q-Kr?zUK9J&FzgfF z+QUK{9LOn)j-|{vy1jttb9d2hO|`+6e3dI5!zF~ASYmYdG-TVZ5Zm6~W-Lflg1S9_ z)U7O=4 <9Vk*flSy**dn#yFIbP?+a1v-T zC~S~mWbh;Z1ZcCO6HY2m_beCqqcj>R9!8sU@?Qj-Njhkwefy_u(&5R*;ug@(zv$a+ zQQ`Rli2jX^mJJi herZ>`|}?O4oDl1+LAR3>ffd3mE&_? z*6{V+!c9_;s+zxSCrW+@ _RElyAIHDsiLeoc|Kg2 zB8_Sx4)tc-AX{C;Cy8r(q|@rARony^le`n4(!9nxuU+GbXeYTsX(hDVckxdHvw>I9 z2r^(6Cif%;o66OD=jLYWi2}I6_bcAp_>3XAH 07BBXFPFk_&K%GX=?L zZ~F4w+&>(AXH#^4VDmWrjiO#tPRPYhyc6@u(JRBbh-|54a|%2G8;BJ6dQCcMO ^q8ZZ^!Lu{-aNJ5RiEVavK1#2D&8O9-9pA?ch;NSm zGmstm7C*B$IJ2w1)zz$3;x50DFHHh9Kz1Ve?4&8k(wT_@lt|)0-(8%*nS5J>QZz`W zhAuidw}6gB+r-H2+rE^#s;x6g-G-;sZuQ}HQHN9qPl8sHhSQJpI|0~#s(HN8@I_$r zyiVpE1izz5tia$8vUA EF>O0K857>BagY^DPvpPZMTv{AhE{_lu+g~) zojcP4O 4o;q*?w?va%L55vdPE}FUfNak6}^625jEozah2RLo5pfHi41gJNDYhi&>CsGRYD| zGAhc3dTjWS1T;S~5nE|o*b?`@X*lm4A6}^CvaRP%p^(BM?WayGMvD!xs?l99rG}dg zkvjCf?)hv#-c5TV{swVVt{#tKp4#2`!~?+>ePMlL@i1BVYjz+aimW=Av|b!rUP=zh z5ln>|Kv_ReL!8b^;6u^xL*}}x39P vfS7sNbj+d^pq};DD6E%awzlpi`@+NmL zv|~c~gW!XnxOHWqM0!f`F4)yZ*1Ukc ;7@B@ zY0vM?T3m<`FeR=R?~2DCWNzCwk~b^D*)BQTghuvHRwUh| zF7C|YB@@`Ld#L=X^Mn*--)p7$XuNUuMuQQ=D*f(1{T67%a *pn_glVwmO%&B*zy!&2F4{>ZoNZ&Y_D3!zT!vlNml0b z!k%2sDWaG>w8rd(YfX;LqV-bAb;rs}q;w0JfSMiVRxze8p6cZbAEEJ5Ge?#A&{Mk2 zs&^F-9+cc|LN{h*xZ3DB+MB5lagAO-O~0mRU_UY+UgS}h#z{Tb&;CsUEiK>g=Mlp3 ztQAOMJ>(%K1Qu#3 *E>>{C6AK&q) z=eQoadn@>N@#H5NZ-ydNM0#FkG!yo2J1J09LwhOPJW7-0w=gCDGffw8&uk8+)ufn1 z>N-pDq0u{AR^G_AE$yl7Bj~YXs4N{;z$y6vvF58zOP_U_?k@|-*H$52&W+9%H7haT z^8E2*)GI|7<@6M3HWMZI*%sjXhO!9mR^xRQEu `k|6Fq6bU7Y(oIT;NT`p&ts2 z8obsEeU1+}JWM`Iyg?3er|@mUO(LuAaj5fbLJ!`SD88O($DTf;z0_7n$O88@5UGO} zAh}1uEzulzQa?_rG?WlV>o9X|-?s`;JJnm3e_qqA&kzz650^10Bb{lVP_AdYw9hLy z DW8Oy#!XTbv(YZTH{JYXf;0UmONwgk7vS2b+k7n%9n|} Uv zC XTSpVo243kKE`sT kaBGn&J+n<|YsGY9EYshp+qbM`S zOu*o7U!|bcaP^{#bt9;KO$=*oY(+RyrLnb&$N^HvXmK>DNVA@ud=Bky1n)pOY}X4V zv$t{7o`J@OHx?A1LN3h%&5l7 Pzm&7r;?L!bpa zHhjvF1Xjra^@@dmS#fpW;9$l*J5a{tQFj&b>LX{}cLtZ6kq+w$(`-xUZwW6WpUvLL z*%qY{B?UIA+OhPOwKUzatcbAR=Le{{9l&4(7H|rkbSZW%q>|!-Jxgqx>JF4$ n@S66TeI3m7}O?sVFT{Fs!I=@_$6iRNOr&A>S{l02?E;h(@&Sad _@7`QQ5lHbn^_dFwg(z0$5|C<8P4Xo^Av0pY`oc zW_ugd1W*`Q!IS*9^9dwp 8 z#`6qU w-(We0{WT>RX&%{bW1T5rf}*yG zyt|^_$9W)bY!kBa_H+clJ4S?!5G1fZ2CxxBTB1`f8uGOCBWQ5UG^aiv8{`s0s?RDO z>C8O4wfTuj6MUss=hm;qh^1?70C8ZsNMI~C6tn~N-X8bnDp_?b4gDBK`*c&|!BZnh zT*nYiE?Ih2pQmtqEouEV+?!$7#q$7TDD?-VL7Ssg0J%_QJjzI)r>d|0XJ<@MjbO r{Z70(V%d(jWzTeGj|dTCX+bbYI#9nNjf&KCF~{%8 zu9`h%gaeh`TD$i)&Yka*#=>4X|9ha-1)bMp_)F-xXfOGc;g?x^Z;%rX0?T3dolLO( zNs4xa$@T+1xLKj4!;+fpTP+plG8;fFF-tc+=kcJl;>2`M7ydT75DQJHxl?WJ8cro zQ35)-PHfZN7avQ@-6m50CHaeCiG8n+n`f?TX)c{h9e+}dHls^Ki7>45^n;4yk*Ux# z#AkW8TKms_9U$@h(hTrl(rq<1!onf^Ed^7Pl^&RSt~K+`CMI)fy)ql`hbkGt=mNQ> zsQx2dX{@=W9_z%e227bcVliCVeK{G~mSi#A$zNcL^rcGNGkARk9UQHJQ5MHK5ql`x z)d!~1CViygFMCcPGU(H<5MSAfYjWsB{s<%cs7nExq(Ob)6A@w(S@dUDVRGOpLd zcymhzqyM-pB@hzZs;9UXx8&kDrQBsB2Txt}vSH6m2-())9bqeN4(p;9XCFhsHX!9t zU+EGkfz^A|ne37Ax*Ouy%C`n}Ok1J^CfR5|J!d^6um^Nh8)4xUqN(rSi7OpqNp<_C zB7zYKEKPp%CeYNQb}Yru_f=8a^p}4-@3{ggU&dyCh=)I`ab>x` )S7ig9~#&& z-_7>X+eu~@(=E2qtupL2y^oA^?mymSlAy==_HkNVUy(+_4z9iJBVvH8I^CRw_()mT z%Y*GO=+8}Pl8@9hK`?CaBuy8kI^Jm`!k`@LgaC*CHZOHfv&(>1fj+RUdplPQ)DO#& zl~l;rH^u@&D9^`c+aFx`%q66zPZnt w+;HX~!1cXqd#e%!j%MG5)b zdztPAQ~*^X+ME7(&C3QU3@I5wnpQKic)7n(2&te_MG@%@Gz9%`6sg(@B7x@Htm(A$ ztihdHEBdL}R_~>bx;fEsR}xeQ-!x6-Ieb6G?}7v=pSKAx!h64qG>!SA 6&-yE541F`q^n?#`Gg+Dk8^+ zi_71)-!DaZGnW^#Uq*JU`3&@EHArA8>9+{QZBZYT!Xc~Qn`tO-U>^usR=_^!R=U1` zm8TlCK;42{lJSA;-)_@3aT^V#n?!i((v0#<)SY O;S{+IXx&9fS+fKj1A436s zIRIAck2=LYo%8o<@`VfKCR($lbDj*#)u}hv2Pl?1&1?2EX||X$yp*9oM-^Q4ay~K+ z>U*-@S3GMac0(h4kUSH-mRRzN*G`Dtc#7L7a3THiWzi1nbj2 BiMKUw6U+h z`PcTvMEt=|;$2_TtHzIEL=hE~vF}|4lp7=Wr c H2 zd5Q6A%?9Z+;> Jr-<)ty-K+i=0Iv#cW^dhC@{EK^O zi2mbg(!>6&ng2=w0`9EfGwI!Nd(g%A*O8*h>?eUYdr~x~l!b++kYTO(rJ|PPi+iYG z%XR}>d}E7Hl$PX&L1#Ze-OlrR?Q8Sbh 2FR)>)KOp3|i^JB` zbfeXmc~`zfjNaE$Jkgz@n+2(+keVN&HCYm2{76ewEX`{`! UWT{d&)`7 ze9UVDvG>LBF@F~A?4Lz(Z(8LU}fBOqTDMVFNE-AIxH$w^{C;?P$H{7 zV|Y?6K;f~ao1FzfFeg!aXo2T71hA#d&h*CW9?F$`8I;4^f}7)1)m@sA9AU^_?`S{l z=u6_BT|+E#!jhakpxo#VyRB(4Y5+`#V_%~qd0V8Wa0ta|U{@11+Y8VG6i`UTQkHBg zKud9}v*#6>`~c+r9GyYqC5tWs&rb}SM5@DGD|4m~$YtA)Z!3jod!z iCaJNr< z+D{O+CyFZn7jf;-!)vyF+#105xy?qjg3IbtXuk!|0dPzfJ9agABHa>o;+%#rGnN77U)3XL z0-(B bXiLnsseQm>(?g2Th#G0LS{- zz;m6X${t1{Cb! zp*;zW(qe!D-fcoFfQWN}GdEm89!Ju6aibO-eD>|O)|5}aYwF@mxD-r;>3BdWKYf{1 za`!Ae@rPJQN>BiE`f)nBS|$cGkgk(?dsQs(w((_imQ?S9NuQ5ECgbtk$Sml$HTuPd zu;J7C_;aXODi~~_r-g+s`KN6C^@zCrQik-AaImXWqqGjWL!_7R7|=GlPNopu-syJ{ zhUk*)SoJxP7BdGrO8x}7o-VkL={ZW|8`mq@H|pYYjVGfA)-C51KHGq(QDd8)xLato zxU6fZK8j}5t9 $8}qyX&PtcAI=?vu zXV*5UOh0%q;Y{BO-Q%SBtgRxm%OZjenoj-z&3vA6z-o*_zs)IZn8=3fv03~3*B4%f z;5@puX6KJuzz4L0XbZd!OOV>HulG8ysz8k*ngZS0wHOj%$v`jht^@C6*=7Zeo{O?v zJA?=(hFr@jcx3`Az8y4t8L )pc&LFYdj +=Xh~S6KEt)2l=?VrYrJXIGsJYU^j13I1TC)M)cnz)Xs6 zn*mwY8_#42=tZ*UG~c@Cn(9>N4kClWOBJ03Zl&Ju6^% *jm>_4DnTGF139W3pmt!Q<0M10@PDpud?#C z`xa !1 9RP?(0x=+5lq=6xeJZDATov M?QkMiKDb5W;fBU3}R zUzY!{z9 TX*GDC78~MDGEMlZXJu7^P>?eeH`B=fZv$d*SeMJnmw|V>OI7S%L=q#1lk7^I!EN zDNuWsc1BbS+hY!zB%-@0;8g;vpe$|DXJFiCZH6wnWwZBZp68F>SKgzmZcN OEjTdk>v|dNH!C*Rn_fG;-V?D`@xEG4i_Xj93^<(% zUYrLJVdZRRG7>yZwcXB77wtCb7YXnF&|R%@%t>F`h G8Ep}a7vDI@=@XR>b)v^^w5-8FCs6<^vVM6}JsClJDAz0Lp86%0 zaL-mk*#*v<%RgwZ(Klr$1WaY}qM|ye^7CGYE1||#IUuEBv29nD2EazL<*Gs_NEo^R z;N}QA{aOU!EH~)0v#6X0)I=^rA{y8o;14i?QWQ5GA7~7y(OvXb^dledG#IGc(G`m# zY9N97nr>rQry00HhMQx<)k~%m)_sn`cO#e8ZV~7++{k1^w*KDX&uaNH!LrFci6{xo z&U(m)zc%|o7JRx2!H+5Z+w$?*URGV(vv))nX4h%KtmB|9uJ*b59iE^&t%7b*z|?p5 z6reL0?Q1?|#QJi0F_wh##W!ZSw*$QuZ*vwbA(m{p>}drTUt+j)Q9K8!aec#~y8G8h zr+)l)eGhul?(BGhy}*8un%#hewZ)ult0lY!=(H}nWWs{t`jKfFPgJHZ96jhuiDh^p zk#W&~dU{IP8#A5$idYh;Ln=$0@lZE(UW^EteD)6SnAdRa9xyY7YMFJ2yLK&UOj;Te ztr$zj2avY_f`vwcV`G7Av$NMt@e9_;`n&U;kdtVBAZW25OAm?-!sTHO8<{qbxK3PQ zj=eJee~VY6J 6r36L}8FM!#AMaD}{X*ko) zt^!Bsxrric9q1B$zRL3xt(e?aOi8-bSaE<8$RqyACjUxdz8y}|a{mEWVE@;F3p8aP zsQ`wWVbap8w)8;~ag}e|ihA9QF0OIi&pO}mcfg9m77&SGNIQ?4auZG|yJ#_LHE3>G z!^gE*ca)^Y7X#>8EZnyrsocts$eMkasT94ZHRI^|e5UA*Ps2Evpc_ML5#UI48A9~X zFN-($@eZh)Dum~x8LK4qj~zZ{bgFyEwY%|d_1}^UiA{de5P*>N-`=m02*HgeaIFnE z-_ga;`tZY7S&ScpjJ~z8{;Ppm=g_fRS{r_I|2cmnbjl$DD}egfp_w=>6tqe{+06>x zDSEkWT_nc+HXPzYO?da~#PTRqBGq>}-!1v1k29RZS(!xfflv)V;2qCRRF$IZqt&Pe z9VR<@%$en*m&+Tjned8{Ahq|Gj@YXetU~7hHQrAC0-{eRR{vbvpUly==O)V5c{c}{ zb+7)7<3iC3I+tg|6bj-u#K4Mtx*K1o7m{zMG~EDZp}hJg=@ 9yU6p@uH!JD&&SV48*gtP3)#sflz*tDFlXd7ze59+)UH%`4n~bZ zE7FhER(7X>ByAc%H&%Us`v!dJ)ZF#7Ck;Q^H!tS@Yj{lP$wSR#J|!RD1v8rL|2U>< zxP$N)>Wwr2_edGOGavGy8yI4K6FH0%NqJ9`A<_!8{@@=QuGzw|9a7T B+6EAhsJJl>6ZInyVW<==i|YoPopb%zmK#5^j+F1g zFrar0T?rVvhv@^Fpy_yR+M;e-60i}I@* zqB*Z|D#r1hifi>qUnIW-g t-K9l z(ag2BamTsh{LlRf-IOtk%^YOrc)J1pTwlZ;6CN W`GN2Y3ZQ#7@axW^?Ax@RgE`*BCEZ(-r)gp5BOZ^$o>a=(91*0r5Yntpnh9z zEM3(*SUjE2fn2)uzc9*5>lc%lUeyW5WNicwdjWle{SbW{l`{s_e bWcQQr9`TXaAhOkNK>!?kY|>+& UB5PA8NIl}QCg C`(6)37! zjdz&!JkwKvdPK&J0hmo}bI9leDfrKD_@?z3>w{M`Y9HnAd}n*xaq7-!Pv|Nu1G;|5 zI}ykfpU1Ud=AZ8Jn6~yL7bH0$#C;k15PcYkUA94fRZh=DAKEOiBCP9@k-BXXY44t1 zKR(Lbo?IQ*-~oqvqCIj!aON=2M6OQ(0CO4Zv%SyF3DM^i-E9`hogY4nZ5V*2TZeW4 z_V*F70d+jko3l SctxttHz%_>A6*!v)_vkbUmarFcj-^*x;@RZH+fk{|1max{MXiX zD+{+Q0W8v``L}h&(izC?B1H2{2E(!0=d#Uy w$A3<@JJs &Of#%yR$imxcL*s1F*EY=Le?q{hFbG?A3;}J%K{oM@IM({j z_=IL;m8uf*0eew0@Mcezk#|?JKSc!Ni6~+wR6!c(6eooUr8}!WYn&d_d;_Q_FGZ znt+c=Xma46%!Kmor6n)C%p$qgBIpsic)o8Bve-zFyHX$Wp5moq^+;-V9@3tpINFni z7@(DmrEvwa7}SsV;a0F;m(7D!Ykjw_>`f^N%;gMUdRj2AXF=$XLFCpvi{Wi}__L1@ zcYI^S>@-mOZCNJ#$c|`<$N{PrO&>aD!nC7Uc>0dpF0WKQ=l^d1Py6(^{gzYwtNf&2 z9NgkA-@XZ(sW=^F9;}neWVGtI)qbQmI8dkEg}s6T_aBqImStAqg%QFvH|M=i>G?i8 z|C0 _s}#)lz#%`j7}?AvO!=a&<
Nc%Y#o&^i!*Z*zf zTQ+WYVE?;$>4D;JK93rU=R*V{|9Q4^m>KuhWqvz%XP@&IfB+IErLq`5)KIz};-Vpb ziO~*iTI+1{VZ3yxB+up<)_?DEK-v7hQ?B_rMxo+9csTCeHwTT(r&5pzFAyCTbFzTy zz@va^(nMCXY0Sp%JLMGn1$BjIZ%HMz>g?BKO$&}@JO8%mvnlAP?l?F1wU97icsbAwmGzd3pSVmV z;LSZ<1=XmIH86BM{uOe7S|^c|H>`JNRO$Pzt_Zc&e94z3H2hoFy$20{%y4W0cjfy@ zuZvH)WOFR3*FUbhGji8MZVFnWOE))-QlVGEHP|`1n0*^hO;bnzv znu1{B?Xqo>t|FjO{n#gvkJDN5LE&?e;slWS1QkB*t{->mCTp&&m25}7Wfd hTb16e>`uC6$*cAkx|R^x@X2Npf~&P?2Q +`e?j`?hGcivX=i*DJ% zgJr-ll869IK6)$#q}l_KbZW_h&7l;L#`io69!H@B)q6RWq`SAM(y6A#FhVedaWX|b z+SRH;@f&)&J$)8@n}+l0o1#?+#~F;>;@kGz%B2#DU9%u(SNrs<+CpF2{ClQwvU# z-uKARh2P~e!PXtZe^O0#fpScyIyiZ=8U3Iec6?>G%~`lPfS9HLdMNd~^CO~?J)?6s ze|+0J=kH_e$YW#h{Xoq`>a|o;Ls+H}gjHCy_s74~O9rK#P>FhOS<5J?ZgVYovIzkN z7LtrfMgXW(ys7uYr|bJpzfYDHw*P+Tdt-vt50aa1^GyguK*sXaNr$`Kzl3drAdDDG zp2k?Cj~y5Kpt3<}wvAnjPJPNRL2v^!PAl>rL~SpxYY728*c^2A(jK(^hL+d()T_C0 zBiI7(@@J4itzW32N>|GZ(eL*KLkbn*f$OFX(z>EF;E-~hu(Mk5RZA__2hX>cybUPo z(B_hRIiJ{4!8-`47 yEa^sAqcy6OCZP;87u{-M$M|t~XQ#uvK1%f$RCo<^_C-E&<33 zwY=obaDx&-7gQ_WwZ1CUYo7P@tmh&t;omIT0CtrVxW(P@HXP6>cjUo_*?p~fHU=#6 zSH?1_Z7n3|X4>*XT3lyj-iPR}qHC%V)<4?%nLVfR(NdwDaO(6%C-v822t+1gBIblM z(P&8-Tt5uxL9_GbdKRSi=7UU}_Ee9-z#|7Y&38(Z2D%#dWTfLm^h<@pWS||tV{d0X z+c^Du4t%PJzU|cGbIp|#k7bVaTt-&1>lDukO+n5ZcwZQLa_XJf`C`trt$y*%wFuuF zZ)@CFA$3}1VOMoGl+uT1-JMf|h)~{)X#j@RYWjUdERD(n-^)t6I;C-IbmnGrg!Q?v zp|`KUUd4Pqo_}AVFbxb(%Q<7OMlDkO93%i4Jap&t&(GlVR4XS $ok1*bH`b Om+xg$eqc~ljyXUpG zZcspmza4)T@*J(YUBB<=Q_c3`gOMgrV(;*Me%$n+;BJ0~LLtYxe2S1Myu8_I5rLUb zw~&0#sk*<%+#VdcjnW56;i3%qE(|SovFzYp^ZgeUu1Pl9Z|a1yZ{H6!OU23oX;X ~cE)aJcU&(*)U_}2h?Z=R$8~?ujx-y@9ox5LM^TMSi+(x*y4X!|#(*O+_x!HB zQb%Y{g?F`@M4PXw@7olisKzA7Rc=K|#gqs;KIWRxc(lGaE0Nk3$Q$=7P$Ld+N0E@X zC$ +9#f z5ycA5O?qD4xBgc;W}R1T5<=lJxsH<*a}khKNiDwkLh9UPi5Q~QYDiTd)~8VT4?;0F zXpl_^o~S(ZD366w`u;+(;M~8{t~BeP!tH5I-Fr1YS3Dy+lY-81Gfo>S(a1a3-Ws2q zd?$wZ{!4PMRak-}MN?X(_wN%=b&A@TXsafcXGEylJjhe9aFYVZliXbXr=Hp3RC;sR z<6IH?++>*;;@p$W%^BXC90X?fqqyF+Y;U>yf4-h6(LVCu!>%v$%q`sX!NdG*0UJil z(*||CFAl0WT~=DZETZxA>vnvqX%V=!wz(6GT~66e=d!L?etz=J>YC*2s3EKwxLR)d zVNR=C;+_X`ejBMe1r)7cmP9UopWv2`G2=L5nqMfL6`C=MmG++)=l+!|UKeRu{vjRX z#4-M{9$VrQu@gtbuYFRpnkqkze*F7OhXL#o_|5c;7S&2a;ZN?Tw I7(`O0nwZ{bSZXAUpmmLM;Vv=Fl+|$bFde+pc+L%WH^-lHzS#XrggeyS>tp zIX^>~H%H^~mJ!=UpwBEfC8w{;rzve57k#qjt`B?3Sp`=t>z`zqGeOoiN#=38PonV; zGgXvODpmvr^79O(qF0tW3ie6Y|M$~*6O?``b`LBm5W g za_X*hOr0$5H*`(B#ijrCYEb{{g#UgD^(_t|@lKn&%~9v@<39%T$ F9@JMN|{y#0OlNmqEs=VNvqsNPhp zHs}6xElzL9*%D%o (hM>3!k&Q$Cn=u@qk%A1mY@s zpLDHF!M5K0NIv@)HEB@n&H}GK>;o8GDCu#{Gwzt-efA3s@QmWQxqL&|-jiVTINndM z-Mhc2{ML*IpO>_}lYhmc@B|p-%>@sgnQ-;iH}OIJO;hK8k0#9Uip7CJPA7Wa>*{Ke z_^p{L8R7C*bV4DF`!#1B3l*+@Jt5kss*{TjAjIjmlqTsIK8~h<^=AK>$>X=Z;8~J5 zsDuzlcw4xg 58cYz=3!QkLot G8!!symWsIvX7w=s zw!yw^H@DkTo+-u}b0zEPhOljp=Z(^~pNp`JFKYcT&`$W2VR+J_N!Zo`oOtNjCD~fV zmv&2zzBBcy%1w25xuw7=4!q#9I)1o1weE7G_=XBqQ#xjda}WJa-6NT1-8_3+CgjKG z9*Wk+a|0LwpaR%~iD4bPU(J3P?4l>jz~PS+D)c$$;5coiCsmzB3}YQd-^~jJgYtrP z*``a@e)%JMc}2g!8*@4>nXm{J> &9PsC`KPU z7u%QDDxz$1X9kR-D-YD$i+)B6e)sI?+S8GUU#}L*q@n*48wpu0%uhjxKRe67L$6J1 zUv|YfM+U1oD?eaKO}b{0GWTf8rL9OIwD=$Rp-7>Eb3y-|IAVCkWzJCj(6PX`U{i(Z~E? |KD=%A?(!b8UK1ADLm|PzY~~U%n(O {&sY&Y)fsFwV$Z_r(ceO6Lc2ZK{m8YH* zAfx^F!*lQh?qS}ccc+?891oWY4ZM2 cc!%H#1Nwfy%Q2X1fBQQ@cMC9Z~@)CQR>5NmLD(Te+RFl4mW@$J{ZVfF0E zKh*sHUVc7~gW(=ZDLM7Nue{TS$KpT1No{iAT{b3 bWzV0UN#Zwf~nlM9;d1uXWT z1v^g?lvsIMe*E7aecXcQkb?lj)a4)kyQ>AQ5)onJE6VowpYwUn(!0vx0>9k1)Oa^A zG*+^TG*p)V-aGTa{F;O7+<_vKnYa#k?&z}@{wBLUNsWnx G8!$04v4{x= zFv!L2*ibKV=f0o {krbF}Ap zY7DZiLm+^m?wZOI<$G%sfwnm;a7b9mr0{?{u1A>z$W7pC%;ah)nE%Lj7YooZ4jYvV z+ZZ^$w8u5
().getSharedPreferences("source_$id", 0x0000) } // ============================== Popular =============================== + override fun popularAnimeRequest(page: Int) = + GET("$API_URL/advancedSearch?sort=7&page=$page&origin=,,,,,,", headers) - override fun popularAnimeParse(response: Response): AnimesPage = searchAnimeParse(response) - - override fun popularAnimeRequest(page: Int): Request = - GET("$baseUrl/api/anime/advanced-similar-search?page=${page - 1}&size=36&sort=views,desc&sort=id") + override fun popularAnimeParse(response: Response): AnimesPage { + val parsed = response.parseAs () + val animes = parsed.data.map(PopularAnimeDto::toSAnime) + return AnimesPage(animes, parsed.pagination.hasNextPage) + } // =============================== Latest =============================== + override fun latestUpdatesRequest(page: Int) = GET("$API_URL/latest-episodes?page=$page&type=All") - override fun latestUpdatesRequest(page: Int): Request = throw UnsupportedOperationException() - - override fun latestUpdatesParse(response: Response): AnimesPage = throw UnsupportedOperationException() + override fun latestUpdatesParse(response: Response): AnimesPage { + val items = response.parseAs >() + val animes = items.mapNotNull { it.serie.firstOrNull()?.toSAnime() } + return AnimesPage(animes, items.size == 20) + } // =============================== Search =============================== + override fun getFilterList() = AniPlayFilters.FILTER_LIST override suspend fun getSearchAnime(page: Int, query: String, filters: AnimeFilterList): AnimesPage { - val params = AniPlayFilters.getSearchParameters(filters) - return client.newCall(searchAnimeRequest(page, query, params)) - .awaitSuccess() - .use(::searchAnimeParse) - } - - override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request = throw UnsupportedOperationException() - - private fun searchAnimeRequest(page: Int, query: String, filters: AniPlayFilters.FilterSearchParams): Request { - if ((filters.year.isNotEmpty() && filters.season.isEmpty()) || - (filters.year.isEmpty() && filters.season.isNotEmpty()) - ) { - error("Per gli anime stagionali, seleziona sia l'anno che la stagione") - } - - val url = if (filters.year.isNotEmpty()) { - "$baseUrl/api/seasonal-view".toHttpUrlOrNull()!!.newBuilder() - .addPathSegment("${filters.season}-${filters.year}") - .addQueryParameter("page", (page - 1).toString()) - .addQueryParameter("size", "36") - .addQueryParameter("sort", filters.order) - .addQueryParameter("sort", "id") + return if (query.startsWith(PREFIX_SEARCH)) { // URL intent handler + val id = query.removePrefix(PREFIX_SEARCH) + client.newCall(GET("$baseUrl/series/$id")) + .awaitSuccess() + .use(::searchAnimeByIdParse) } else { - "$baseUrl/api/anime/advanced-similar-search".toHttpUrlOrNull()!!.newBuilder() - .addQueryParameter("page", (page - 1).toString()) - .addQueryParameter("size", "36") - .addQueryParameter("sort", filters.order) - .addQueryParameter("sort", "id") - .addIfNotBlank("query", query) - .addIfNotBlank("genreIds", filters.genre) - .addIfNotBlank("typeIds", filters.type) - .addIfNotBlank("statusIds", filters.status) - .addIfNotBlank("originIds", filters.origin) - .addIfNotBlank("studioIds", filters.studio) - .addIfNotBlank("startYear", filters.start) - .addIfNotBlank("endYear", filters.end) + super.getSearchAnime(page, query, filters) } - - return GET(url.build().toString()) } - override fun searchAnimeParse(response: Response): AnimesPage { - val parsed = json.decodeFromString
>(response.body.string()) - - val animeList = parsed.map { ani -> - SAnime.create().apply { - title = ani.title - if (ani.verticalImages.isNotEmpty()) { - thumbnail_url = ani.verticalImages.first().imageFull - } - url = ani.id.toString() - description = ani.storyline - } - } - - return AnimesPage(animeList, animeList.size == 36) + private fun searchAnimeByIdParse(response: Response): AnimesPage { + val details = animeDetailsParse(response) + .apply { setUrlWithoutDomain(response.request.url.toString()) } + return AnimesPage(listOf(details), false) } - // ============================== Filters =============================== + override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request { + val params = AniPlayFilters.getSearchParameters(filters) + val url = "$API_URL/advancedSearch".toHttpUrl().newBuilder() + .addQueryParameter("page", page.toString()) + .addQueryParameter("origin", ",,,,,,") + .addQueryParameter("sort", params.order) + .addIfNotBlank("_q", query) + .addIfNotBlank("genres", params.genres) + .addIfNotBlank("country", params.countries) + .addIfNotBlank("types", params.types) + .addIfNotBlank("studios", params.studios) + .addIfNotBlank("status", params.status) + .addIfNotBlank("subbed", params.languages) + .build() + + return GET(url, headers) + } - override fun getFilterList(): AnimeFilterList = AniPlayFilters.FILTER_LIST + override fun searchAnimeParse(response: Response) = popularAnimeParse(response) // =========================== Anime Details ============================ - override fun getAnimeUrl(anime: SAnime) = "$baseUrl/anime/${anime.url}" - - override fun animeDetailsRequest(anime: SAnime) = GET("$baseUrl/api/anime/${anime.url}") - - override fun animeDetailsParse(response: Response): SAnime { - val detailsJson = json.decodeFromString
(response.body.string()) - - return SAnime.create().apply { - title = detailsJson.title - author = detailsJson.studio - status = parseStatus(detailsJson.status) - description = buildString { - append(detailsJson.storyline) - append("\n\nTipologia: ${detailsJson.type}") - append("\nOrigine: ${detailsJson.origin}") - if (detailsJson.startDate != null) append("\nData di inizio: ${detailsJson.startDate}") - append("\nStato: ${detailsJson.status}") + override fun animeDetailsParse(response: Response) = SAnime.create().apply { + val script = response.getPageScript() + val jsonString = script.substringAfter("{serie:").substringBefore(",tags") + "}" + val parsed = jsonString.fixJsonString().parseAs () + + title = parsed.title + genre = parsed.genres.joinToString { it.name } + artist = parsed.studios.joinToString { it.name } + thumbnail_url = parsed.thumbnailUrl + status = when (parsed.status) { + "Completato" -> SAnime.COMPLETED + "In corso" -> SAnime.ONGOING + "Sospeso" -> SAnime.ON_HIATUS + else -> SAnime.UNKNOWN + } + + description = buildString { + parsed.description?.also { + append(it, "\n\n") + } + + listOf( + "Titolo Alternativo" to parsed.alternative, + "Origine" to parsed.origin, + "Giorno di lancio" to parsed.release_day, + ).forEach { (title, value) -> + if (value != null) append(title, ": ", value, "\n") } } } // ============================== Episodes ============================== - - override fun episodeListRequest(anime: SAnime): Request = GET("$baseUrl/api/anime/${anime.url}") - override fun episodeListParse(response: Response): List { - val animeJson = json.decodeFromString (response.body.string()) - val episodeList = mutableListOf () - - if (animeJson.seasons.isNotEmpty()) { - for (season in animeJson.seasons) { - val episodesResponse = client.newCall( - GET("$baseUrl/api/anime/${animeJson.id}/season/${season.id}"), - ).execute() - val episodesJson = json.decodeFromString >(episodesResponse.body.string()) - - episodeList.addAll( - episodesJson.map { ep -> - SEpisode.create().apply { - name = "Episode ${ep.episodeNumber.toIntOrNull() ?: (ep.episodeNumber.toFloatOrNull() ?: 1)} ${ep.title ?: ""}" - episode_number = ep.episodeNumber.toFloatOrNull() ?: 0F - if (ep.airingDate != null) date_upload = SimpleDateFormat("yyyy-MM-dd", Locale.ITALY).parse(ep.airingDate)!!.time - url = ep.id.toString() - } - }, - ) + val script = response.getPageScript() + val jsonString = script.substringAfter(",episodes:").substringBefore("]},") + "]" + val parsed = jsonString.fixJsonString().parseAs
>() + + return parsed.map { + SEpisode.create().apply { + episode_number = it.number?.toFloatOrNull() ?: 1F + url = "/watch/${it.id}" + name = it.title ?: "Episodio ${it.number}" + date_upload = it.release_date.toDate() } - } else if (animeJson.episodes.isNotEmpty()) { - episodeList.addAll( - animeJson.episodes.map { ep -> - SEpisode.create().apply { - name = "Episode ${ep.episodeNumber.toIntOrNull() ?: (ep.episodeNumber.toFloatOrNull() ?: 1)} ${ep.title ?: ""}" - episode_number = ep.episodeNumber.toFloatOrNull() ?: 0F - if (ep.airingDate != null) date_upload = SimpleDateFormat("yyyy-MM-dd", Locale.ITALY).parse(ep.airingDate)!!.time - url = ep.id.toString() - } - }, - ) - } - - return episodeList.sortedBy { it.episode_number }.reversed() + }.reversed() } // ============================ Video Links ============================= - - override fun videoListRequest(episode: SEpisode): Request = GET("$baseUrl/api/episode/${episode.url}") + private val playlistUtils by lazy { PlaylistUtils(client, headers) } override fun videoListParse(response: Response): List