From 165a9ddde723f9eb778abea39392d515b2346617 Mon Sep 17 00:00:00 2001 From: Fredrik Burmester Date: Tue, 6 Aug 2024 14:48:23 +0200 Subject: [PATCH] fix --- app.json | 17 +++-- app/(auth)/(tabs)/_layout.tsx | 10 +++ app/(auth)/(tabs)/index.tsx | 2 - app/(auth)/downloads.tsx | 85 +++++++++++++++++++++++ app/(auth)/items/[id]/page.tsx | 6 +- app/(auth)/player/offline/page.tsx | 4 +- app/_layout.tsx | 13 ++++ bun.lockb | Bin 533017 -> 536136 bytes components/SimilarItems.tsx | 17 +++-- components/downloads/EpisodeCard.tsx | 23 ++++++ components/downloads/MovieCard.tsx | 18 +++++ components/downloads/SeriesCard.tsx | 49 +++++++++++++ ios/Podfile.lock | 17 +++++ ios/Streamyfin.xcodeproj/project.pbxproj | 66 +++++++++--------- ios/Streamyfin/AppDelegate.mm | 1 - package.json | 2 + utils/jellyfin.ts | 65 ++++++++++------- 17 files changed, 318 insertions(+), 77 deletions(-) create mode 100644 app/(auth)/downloads.tsx create mode 100644 components/downloads/EpisodeCard.tsx create mode 100644 components/downloads/MovieCard.tsx create mode 100644 components/downloads/SeriesCard.tsx diff --git a/app.json b/app.json index 438c220f..c8a31d8e 100644 --- a/app.json +++ b/app.json @@ -39,11 +39,7 @@ "expo-router", "expo-font", "react-native-compressor", - [ - "react-native-google-cast", - { - } - ], + ["react-native-google-cast", {}], [ "react-native-video", { @@ -56,6 +52,17 @@ } } ], + [ + "react-native-vlc-media-player", + { + "ios": { + "includeVLCKit": false + }, + "android": { + "legacyJetifier": false + } + } + ], ["expo-build-properties", { "ios": { "deploymentTarget": "14.0" } }] ], "experiments": { diff --git a/app/(auth)/(tabs)/_layout.tsx b/app/(auth)/(tabs)/_layout.tsx index 2b4e4232..10e828e5 100644 --- a/app/(auth)/(tabs)/_layout.tsx +++ b/app/(auth)/(tabs)/_layout.tsx @@ -27,6 +27,16 @@ export default function TabLayout() { color={color} /> ), + headerLeft: () => ( + { + router.push("/(auth)/downloads"); + }} + > + + + ), headerRight: () => ( ); - if (!data || data.length === 0) return No data...; - return ( { + const { data: downloadedFiles } = useQuery({ + queryKey: ["downloaded_files"], + queryFn: async () => + JSON.parse( + (await AsyncStorage.getItem("downloaded_files")) || "[]" + ) as BaseItemDto[], + }); + + const movies = useMemo( + () => downloadedFiles?.filter((f) => f.Type === "Movie"), + [downloadedFiles] + ); + + const groupedBySeries = useMemo(() => { + const episodes = downloadedFiles?.filter((f) => f.Type === "Episode"); + const series: { [key: string]: BaseItemDto[] } = {}; + episodes?.forEach((e) => { + if (!series[e.SeriesName!]) series[e.SeriesName!] = []; + series[e.SeriesName!].push(e); + }); + return Object.values(series); + }, [downloadedFiles]); + + useEffect(() => { + console.log( + downloadedFiles?.map((i) => ({ + name: i.Name, + codec: i.SourceType, + media: i.MediaSources?.[0].Container, + })) + ); + }, [downloadedFiles]); + + useEffect(() => { + // Get all files from FileStorage + // const filename = `${itemId}.mp4`; + // const fileUri = `${FileSystem.documentDirectory}`; + (async () => { + if (!FileSystem.documentDirectory) return; + const f = await FileSystem.readDirectoryAsync( + FileSystem.documentDirectory + ); + console.log("files", FileSystem.documentDirectory, f); + })(); + }, []); + + return ( + + + + + Movies + + {movies?.length} + + + {movies?.map((item: BaseItemDto) => ( + + + + ))} + + + {groupedBySeries?.map((items: BaseItemDto[], index: number) => ( + + ))} + + + + ); +}; + +export default downloads; diff --git a/app/(auth)/items/[id]/page.tsx b/app/(auth)/items/[id]/page.tsx index bb051ab9..61c49f62 100644 --- a/app/(auth)/items/[id]/page.tsx +++ b/app/(auth)/items/[id]/page.tsx @@ -1,3 +1,4 @@ +import { Chromecast } from "@/components/Chromecast"; import { Text } from "@/components/common/Text"; import { DownloadItem } from "@/components/DownloadItem"; import { PlayedStatus } from "@/components/PlayedStatus"; @@ -9,7 +10,6 @@ import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; import { getBackdrop, getLogoImageById, - getPrimaryImage, getUserItemData, } from "@/utils/jellyfin"; import { useQuery } from "@tanstack/react-query"; @@ -24,8 +24,6 @@ import { View, } from "react-native"; import { ParallaxScrollView } from "../../../../components/ParallaxPage"; -import { Chromecast } from "@/components/Chromecast"; -import { useRemoteMediaClient } from "react-native-google-cast"; const page: React.FC = () => { const local = useLocalSearchParams(); @@ -114,7 +112,7 @@ const page: React.FC = () => { {item?.SeriesName} - + {item?.Name} diff --git a/app/(auth)/player/offline/page.tsx b/app/(auth)/player/offline/page.tsx index 6780e9aa..6462972e 100644 --- a/app/(auth)/player/offline/page.tsx +++ b/app/(auth)/player/offline/page.tsx @@ -9,7 +9,9 @@ export default function page() { const { itemId, url } = searchParams as { itemId: string; url: string }; const fileUrl = useMemo(() => { - return FileSystem.documentDirectory + url; + const u = FileSystem.documentDirectory + url; + console.log({ u }); + return u; }, [url]); if (!fileUrl) return null; diff --git a/app/_layout.tsx b/app/_layout.tsx index 3f5c4ab8..670e3d87 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -77,6 +77,19 @@ export default function RootLayout() { ), }} /> + ( + router.back()}> + + + ), + }} + /> UOKtMnRrMUxvY^o5H5_*RK0YVETp#;GMMI>l|IO2ec ziV9*EQ2`Zu3yO-~3Kr}Qu~+Qx@0_)Ej6UAa|NS4w`{Dh-=+3#$bMf(Ot1!+mz_1afTUUE5Z?`YU}H4#G)M|KIX}OkaBjAf zK>Qi-zSSJ33HSzB9emN^Qy~8rZ$uP+03PQ!rxX|DbvTwHcv zD&Rf;y~Miidw!-{H|y{*j#C@$ZLlWzGN{JP%_^AQdS-Uv)0RI7D(~GE7f#QaJe@jn z^0OCZgO4BUIJJmhM-Noa7Se@{^UK{vr$nd%p?G>$e(R~TvZnn)J5}0Vbfs=k$FG)f zYUgpsJ5C+wKv2nhf@(}EsN`)x6}mTKu$kr2y8euWQ|k|_XWFn6RQ6jf4)AYDXjF7L znPiPll%SU87v#;EKihH6vR0aSk|}fxsC1L^vL~{FPP^zMNVG!{QR7$g--L6jmbX-)w_0$OoKYw z46|~l&CDq%C@jp%n@0W4*2a!QM~eec{;?8N2bO@!KLAvP@8TqC*j%emvH003j#Jk; z35O)0mX5R$alep1v?w~MxyfGGHg%4}H6^QXhN`bgYW4e{#;;kPD}7<{+tHxgwwDY#dTq%Dc%jX0JniEu=I4(?B!tCzpT9c?D=`K^0Vhm zQA5|9VbU!J)xGTO)>Cuxm_wFtY;EH63$hC4=V#}y@xMvxQ*=@l<9er^WpZ5uGP1=N zgLT1)ZO!a0gsT{gQ0R!rr23+lzM_Qx|Vdkn6eLxkz+;^)qs((+^H1^w8j>9k&7o?iT z9q>C5)^-$Ve&l>YAiC)wek%+*ScobtXVnv1x^NB9nCn;aZX@n6;oW+tgI>7 zT@bXMv;?(~GyrRWr;~x%R$L!s=_#&F!J1Nc#~kN$aKJ#5?l-Un{7q05x5;#zreGqd zbT6S-2jd-h3|^}U;U)rF^REJBy0bu4cqJ8R57?aUI5Hx?+C?{4vHeW`oL5HrAN(Jh*ytFA13k z#UG9{Jy{7?1>->VtUag(coyI3V)zN5X6yYR&R6_oC*xC(W*JMZ?t=Z5V5&`+Zt)A8 zOTO@BnkgUxs$oxCz9ZZ4>)j4W0efb z>+h;!#yD-J@$MD{#@VWXvdD*^D#**u&z-d(+xdCEal)@a4dHvBoRd8(cOffc`-R50 z)}q%!Ka_8V{P`jq*a03-M0WoCf*ht7i$G}7bHFy}jX?GEmps#>eV|NQ1(Ti(-Ue5L zR)XqC`4UrJ+oh%<*U+Kb=o4(dvn>`S6Ho;o&NG&H0MuBPfvR9U*dFWx$};sqRq)MR zGc+%N;@5!f!0BKIa1sq`4EBP{!hg;-mOB-$2LGHJ`czSI4iTzw4}!e;$rX;n@E6|% zSC6KGIBan@%Nu|yuo)FJ0>8z)%HM->WT8E9`P4O_IyMt*3-$sP-xyT>cSzq@^M4ls zRpeW22x^`De3r?08Hi&S4*=B=7wiu{i*L||;VTI!)mh}1)u`KVEp@5P6`)eh0X<>v z6n3DTyq(t={wt_9P1tDCWrAu$UiM^;EDZ6r{mGKwILfvg2#GUjy(lzpQ56qOLa?Y7Oi9PJ3Dj24Hp8{GTQ4uFaPt;KXym8nXD`T} zQ;@%qeP0DGztKP0z9)G6mlTYT{?-<>ltJ z&R#TRw~3#T-?}hs_AG}Z`dl4HPkh*ge+yF&?o8EK-XfX=Ng4 z*_2s1bFw#7HNL*s;#lxx(#61rU^DO}(6iY139}*v;ECvQ*ZbpfqrYXb3{-tHa&t72 z&Ye%OvTAIueacL#)fN|nGWBwcw?AoGe62q(rEbxK6r%}$mBqNrP0hzR1$kM2K5P0r zBR_Y})SOw_bMta%>omNp+>|#&bG8Z(P3& zWa<|cze_-dYzC_NMSG1W6oAs>Ye@dAto-RzbT0*|-@9#r@lCXZifW@T1m#InL6vvz zOD6p=%R7Qva}vNBL($^vVPp_HsJ_6OeCqb=HExVa!#{Fs+I^8~{_}&9%#@q^O`0{7XpQfA5MYCtM z({0?Xepc;9off`fhG%Ygj7GJoU0I8HtdND0@gFyIvb_Nkc$%MO{@`VL&P^GQ%W zDFthT(Zl8dQw?klA54CEQ%_LC*&5VnO?Qo*XHV(Kz3Z&(TfZW$c(?|#8YmO4r2^%<{cF>JlWaNne``8$J$M4~H-2Z* zF_jl+S4sWeSZ+I5REq@3KbQii<<7-0j)yF@ZjBkSKVXxnfNpAv= zhj;wLRG9sn!RBz8z78l~sBYsokY4%QfojM}pz3i!ReblarrbS0V}E5_L4nF}2viUL z1FFKOKv{@WO_zv&l|H^}Ukg{ymM6NQ{tl=fm!Zpoi$Kk_IiP%EpiLhG)$sO3 z1T?LhfvTu3sEjkJxS?JXu8cp?Vpa4msGjVzJ$S#W8&>cLTs^%SRKr(TTmY(~G2lsH zPf#5U@CnuH;hh?CXRZHw-A46SA*=fB)!lf%&GRomrC!~3m*P+=d~{7WJQ02fs&}th z>FRNd7)HrI=m^@YA4foA7T5ufvG~1ut zlT01e;Hvpo+p>ceuWDf8Uxdqi@df!Y-#xKz_j^$_1Pf1g!{ufsC}YO^9be9Gw&~t& zs1sWhT}`ZVtp#QK=BJqco&YLU&RpZrJm{UAg_ZyLi1?q6g#Y;{cuvmb z?A8T&h4DwibLY>VD>uq$9*)+e;wDW^h4n0Mq^C0Y#kN7`gEHbgi_du~p7AF83>3sp^nA1*`&Uzcc5wl`K6qVMGmlS#H-JwBwPaozGeg$0o2h*@ zC}Y~Yv2M#Ttgbslk?2NTU)ZE~(@D5sY2k!nqN9a0qk($BPb3n&wR25NDC z3zVr|usEl`SzzYsyu|ecx-1lbS7R4kbMKk~#@+6+e2d?`QQe{q15Ig72bpfn$SDXX z*OXZcRG4!c%~Y*CjGvV~&vD|1=XROKEXNNvvuFmWfvpazw$}uE2QD$K+0G0h%^pnA#ab)?)t)TqkGEn-GF=lw@!ZmCeW6dz7fwKM&pqAEA zHh-GU7jJF@ICkK~OGO%vPsf`A;=}g}TzK1ar~x(^1>lmR%o1a zCa6VjG^nvW57bz`ve;N823Jqx7R89IbsIB;a@3)|w*2;%-_&G@>B&d*q7exm0$YK1 zE;R+!xxjy*>B&Vyi%bX30aago{~t(lb@Uuiv({Z^Tqpj%*5P8)-apXQ@m?1i!-P+C zI`WoeKFb4ncU zwt!xs3{rTBS)EehDkpxf{S#dcFI#EST?DFwbM@4e>x?jc2Oc*QkT1qR3K0JUKwWhC z;4z>IdS{j4k&FCl&C`qaV*q)|jBGvcb)2h8P5o_Go8sb6qt~LVm`;BukaSu?|D=k?(#zysB=}@xaYrnp@;*VA#j+RWgqCe(Et@@? zclNXM3O(wpq2(=oqbaD3MLigl$(q1b(4cEg1-~;S>gfTv8c>gTrTf+nRs4;GUDuhO z-VQ4N*6U5fKC$U~Z8Afy({Pb`)(Jtb)8htXfli?u4FcAUw%@({<#W)iAr z58i0j-$(Hw@s&53ife2(L-iwEi^01V7lLZ|$So!wpX*c5nkVXiBB%lXG+q1&Ui_wJ z4;86L*K9RCia+Tr-MYP6%X1o?^;);aFLXM#=)Oqi>@BkvWZt^w@cXw$i@*G}>$I1q zEV*PxvwAI-XZ`2;c7w*IXKg!W>(ja02lY9UnB1lO(22L!c;nFazUMxg14<0OmmX_lwr{X$MdTVPIu4qGX}@p zGQWhs&-mqoW04$eGsNFJIL-aY&lnO*Xj=B6fz`89{7sp_FI zx4U1$-+6vHe{b`>VKMI~#y&k>o7WLLh*eSDk$hNcn47f2W8UXB*6~w@M-!sQ_^XDe zyEFZAqW-`~2dG+Q^v=WMdl)u6>aB)#3#-T+8jZXFOAYq6bGszt=hDMG?m2$O$e6br zO%15(mrYLf%TXFKw(a7nyn!%QU0cr$Fx8V7*7_k#U9aNrTb7#4tdtcKd@6NE`x&ES z-deO&lbL2c3sb>Ke&*Ss)hMV?0K6_i%R{G1s~Bg)1^y-_gLPE|vqUH~(eDw_~>U-V0| zVqPMLBU6u3bb`sgu3t7N>Met5Sg_Z)C=OaODdzs_mrsg$Gr0LsM`*#wsC$>6F*)WP zLX(*i{W7}MqJc?K)!)ac%!8>_rpph*R7=%xfRDhedB;T~XK+YM_xq1d^JWlI%aX$K zZiRJ$G4ju0kL*}N>dF3|?DWXYlSwACxSRZpsWIdIE&@k&@CZF2!D$JMz zFN{=gCNr@Fco~G$8wQCsE`upmg0JD<0n=ni@b^tmO|~Rl1-xd>O%togOx}3dSt=wb z^IXh3E9O0p)C-oKn&p>frbV&|Woadhd`&1jToZ@+<+-s)*V7zlTp05qp$TD3 zPrqbt%v*oDDIfR6(yzgcGw&N2O*r-pzu&xcx36C^FXmm%^pR;9F1-Ftn3_eCae?}+ zjX~Y8bD1z3M+a_!*?d%R$fgWeBdxa=K4oJxO(Y266>VODMYvv+xmE4^tF-nTrXg`g?QJBC81vQYfKD%wM%M-F?$9UmEk? zrY5ae%pIn816BdGpGh_~>JIQrE{M68`sEkIyxqj868wWk9fF+~GK?GPNPV6Cy-U-) zhY9_qS7Sh@`lU% zGm=OFBg1BoAv8J+-A8Cj7(4#l&>rl3>j~LW#+_d9%U8s_2^eT-SeF*LhhTEkur-nI zVLkoQ!nA~Fe}B&<>Fy=Iw=x!ap}*sd_xsbYGX~Jm(A0Sfkuh8yBRgS>LVYxIMBWqe z_p!1!9ppF*!c?kk18jz2_)TV}hAEpOJm-T zXp>1-EnHGY4T+Cc%7xL$I@tKo7~c^Zt`@r)e#T|7goI)Ks>{+ND~37F3MFu}eXleY z`Di%J3vK)B2pbbwHqvnxhn@YE(44TioKdneW8gmFm#mIaX!+_`WY1{FxzO)_SsE)u z#+q29=~$)LNZn3oWEe^sr%{oEO((R(FI}A$sWskl7W#V$tsq2Qo4O=Tko}Zw5upWs z>E=*c;P3smOVY$pA?^)Ad10#aviQi0s*Zd@D0K2j|4ELM8y5QzA(O5RrpgODbA1?+ z^Bgw?2T&>QRNuQI7C8W)9p>wu9p96oh-~v=hIe3KV5KeoSEtwCw1{m{BA3gn ziUM4#{j957cqbK_`9<+8c9}4S4ii5^=mNjAv`f#u~2 zt7R>5oavz<-}cKl#v-w$n*MvQ?BZu!8;d*-GkLo)S?~Z1d@ms?qr7%SGO$9|5Hd|U zt~j1!1)-H;>@myYK2ty_tS#~up}cUI23#1|?kBXuuUXc`y+})T2gAoL+|;4km=2ki$hnZ9WN4^AIA1tffd8remI(T(#2gcXKSM zBwl_Vp^0I;UM6Jv)OVGvTC+4QvXfArzt``QbZOiOTL~=>Gn{c*+)b|`G$YJVrBq#z zV^1f9$*=2@WCF~GUVh2VvHE*gJI*E=Ta{rxo>%HB+bNsoN(Yd28V(N}0F_7ZxB(8N%S zt&7K&5jsbjyWh{aE#{qZrP-%h5XVN{8GiX~F^(4A?XiT~f#2`;ba%dAa(m3%7F2BK zY?fcadeNVRU|&y;24n?q97xVmCXnGlT(hNXt7 zRuNJvj^zuY?xVi9EtbF-^xMWQ;Wefjjs+8=ZjoQUE#^IDwQx&IsJ7AXcTc*Pv(dDG zg@c+l!( z=07RNz!b-Q8V8{*Fg9{6MCAJtmL4*h?~Ln>F~CB*7UgOvH?8^Z0Ts7n%o(3{-%{qh~LNb?)D z=(ECl?-CkU(UJi-nYuaElKn!lpug^Y3H39nF60@@X20LAbg$j!cz1Oy&xLg+3AX15 zc?)b1j6veO`?H_%KrEsC7Jt

5+mh+C5eG3xv9vQn^2k-t0JiLW^HONIm7m{z+=G zB^YjUG$CcHU+tlEZ`f92F>|Ibg&9k;?Yq1E@`qxPCb#J9viG61$P_|d!_dQodMo55 z-fDa+yv>Saz+z#F%L%pj`|s|Oe4Dv<9@J% zo&-}KUxRfQ6^Ns!|(TKy4UB9xMy<=ij=~Jg|+`cXhaw~?@r#8 z4_ms9P#X#i{U-7R?94F5AB4^gQ)Ju~w}oz=m%-FHdiH&4GUOZxW3q_bue&SU9QPat z8x+Rv%S%m$$g9n!`2oy~3-d72bQ^a%s>xmAXFM5mU-CaygJ8z#Ww%n_dnOin7VWH{ zf3n*piO}F+@5MOcedc*XLti&4m&1C|?BsA6*JX4WtSNdZiqO7427K+maa9MBg^wK?_)Gg9mbeWHGaU1h4Jm- zu%5)3PHp)cI|S1z5(zR-VU2yzbojXN-f1Gt}FT`<*5e`)cpuqccr_Sz_4XY^i*dCeY<+W;T( zCc>*Omi^}@u}e6(^K&V{9htyK>%f|)hu zAfYVu(0-Bh$8-|c$?{4*JTs<^J&*zu*3Jx7aV)AM0|BW?HC z8+dOSq2cJq>QL=9dd?iB%>%3~824V*d*6Zeu3#C@o28?gpYlR#5+pQAJv_Q(XaM)x;OPj z^B~?lP`nqW+35uPPIpsT>h_Ri=u5_k=BegtSU-}O2d)QTePQ7;kkELazvms^Q`l!b zlbhaoJVkytR{vL&VJerap8nYDeSg!tExbW5n~_frXXgsoS?Zd5zn}45jPpndf8X-U z--|^$|A+QzD~YTi#Cd3Pns<=UD9Yy1+(I5fylNU-HGG^n7p75V{2B54VBKJB2h7PI zY#dK5iEI5@{1!-t%Y~_vwCF0H4(&H1Y<7ofus+1K57)ChVJef&a9%X>C5#6soTu9z zKo1|I<`GgGFyG*)`?z2JQOx@jP0R5y;qic*nU7;$-s@%yU@IBRc?qTz)x)-a0BZxI z1w2Pgc_Y4AsI9$WX2>(grzS(xoba>|d0SE8LU-(&rnp*K)ZPAm$)_=I6CHW z_riy^Xpa#Z6KW0KkLNg_5D#vNJwS+!_i&om^8@3B=8^3(SZAvA!h6#fU<0(7E@w^&~B`~c_tnaMe_f*8`LHO4&c?t%wU z_yHlFyYOId!snc^XhBNoVOwGH>YCv|eg#X1u{OQL-1x#Q9IS93rY1w=&K!|hwC{&m zf5SuSd>J>J9CI*i04Z@=CfM~b4S+c?yaAIhv6xPZCUpMFul7@VmU_HWuI6)+||Jtv1B%L=UGmgZ(hrTxJ53AysXu`?g_;HT!<;AL3ooKAs6vv&jux4KwZ1 z*uM`mB`alvA1fGRKOAQ2(JHY4##xIUaDPRrOnP?qPyVXk(!INXs(kQBK4L~bTzn!! zVT1gdW7E8w2n{t&;aGLt&t{u8OVpeSrl!>TCBA&=0G1Ey9p+2tOw~T137h#AExZ ztS(7zIQHS$#l1Mlh`2Ft4`LTJAxIg_Q7#fMM58borkyg}zr7n^cHR*8K1`hq-;9W~ ztU}T2YI4{oU=nfmirf$5B*MG2-x4xIU&ebcRpZ7>`7G*P12g90U>f-v#&*Pn>X7V) z1~;`A!_1hU^Dr5<1)q{T3U6wsm%_G#|smT!a!0bTDHR8jfwxz>D`-aap z7uz^9QSXMeGmYRl_dd)x82g=9Sknz}^3Cq^Evy$Q!*wZg_A#N2eoONf6OvWbjHvfK zOx-Xy1NCdUb}dtfr@^!gaNmWq1h6w;=7#ABm==8)Z*>1;Q*z_M+e~L28#k2fJ{~6b zHJimX6>-`u_Q2GB_F5*v2`Q$k$-jV^cIxh+-3jrb*CI9trhI1Tx58vd zPw(I-LzK-d(e>(9_|KxKHvlF_HAY$jQ#NzDc>pHgGUogdCLb{#)45(nDRf~j%ydY; zuob3d#F(>reK))ncLQh9kWGZI=tZiPij$>(EOQ#+htT5A@Yi($sKWxyw3n(w@w&c^hOjWaX+ z%+{t%OvI#|W*JjyacYuCc<;8KkXg)CT=h0?`0EdxiWl${AErieM#Z@cU~&j!iu+(P zVPa60iUXf%9Kys6gQ{NKg0C6g%ROKd2l=9PTUaT&zHf}U^DMuws9;`w?!kZ z+SB}?^h7t!n@Ldq$;QVza%>07f|Ryy%w_SXmKBI*(bD)n4(k?v=<3*x6-yAFGZdzl zQ9HhJxn*XYUb2i;n$bSyY%>Im6Q%dC%y{Dhn2e4$@_DPRFwHx&W`73LRu-~^&e5P+ z2iB+g(YQybw1;5wZBvtzT6tj7VI7I%j*FBRRK&p|55dfvF~1X%L6XeFyH2L9=3&ZA zn7oh2AQ)={tTl{B3iG1g)39MM`a$U@b#}vBL-s6OX*_H&ai$-4!$yXT7Dv8G!xQ}e zyd82z7vmGmmlgOgY(`j~7IDb7{@em7tAgSr2HKwr(-w9m3nuNH(xGzJ>bWKr zCkIMj57R1UmdNK}vYy!r8=PnQ#x{uPQf-JE zesIEd%+=F>Y+wr>$9VgR7)>!8Q!`VOhq~cUAsrjqb_z_EuH$F&jAAoP%NmD&-uc}R z8)%l_Q->K>X9!rA^I+j^srL{em5hacOido{hR=0sg(c^}Wa98ay0;Ui@ihm!Z(%Ye z^Farn5n9yr3E>L}nLJv6AAlL7W)@@AI1BGAdW z=eg+#O-BXQ`g43M8KsRuceCY$)TZ!Qn2l2h}o3*L8wQlK1(9)O`%dP56G;5WjR@ns?g7_@vUr84uI? z%cQ!WkBY-|BIPs-OU^P=%pCZq!zxsw!3rX5U$pj9qyD{BSff1I8!Y zR;PJS5|Ve|)*NhqglRo66Y9Llrc*V;`}K9OUVeW*;PW~mJ>6r4elnWScuKHp7&e_f z#WaPDdqFhe=_x_A;h5m$?4Td$eV=VQfwS?(bBC$H9>s2&8dMtr)|?jf1HF~gOy_7b z>(Og4bsW!S77dwh<_B|%P5wrhPC8~=`vRuEnzguXj`6sVCCttVs*R%T`%uj(YTpRn zjmQaBNj+zV>tvF%N{~4mPY9qg2MZXtiLb)c0GtlvG@ThYs2VU0rb&&Xu}y7;nK`3V zWanA&d|J;I!!$;m3&{60%xsxjrJBw*1`j8VR|xy-y!9ANwVS2&v^j>EsW$_5CUG2{ zvZLM|FuQax^?rw$^F+s7(?&Bv^I@vFYOt>!UEKu@XG&1k)Qu)2%neqJ#~|D0#;2>^ zN&W(6w-QS3IgfgR((!Iujv^yrI$WBAw{PRj>GTztb`BF)HQy}y z%y#Z0w!st^-e@O&l<)fI4(;l-Er@%X_DYC)iRbg!^DS8aaDnMKKi&Y{+LypI6LFLB zXu`|$gFTa&fz1|Zrqz5Y&09#wj47L0WCyILN{Rdu4|!b|#&=;k;l(he52sPWQwxJt zQ?Sx6s2Y7dO{auYmY5}hy9}1L(My6=sF9theS^~J9KxNYYzSoItsy4nz@cgR(jJZF_=s!s7Q|^X+bdSlC!{te8mOW`~Aml(ryAISS} z5LFz$9q2s*GwVUhSoVRH6@JMm^o7ZC*!>au4AbbDRpnintZyb^vyzGr zaXCz$%M4?uc?qUwa?e6s%~h42FnC>IiZl0+n_(JKI)s4^!R&_5iLLpiCN43^%;w{1 zu<-3zZw(>sRpwmx3{0bo7cGh={CsIpZ9aa}<}#z2gVRKq$sxa6Z{v7Gv4kg_Fs%*r zkvTh|)Es1ucYFg=AI*;0Wp%ud>eXV{*~FPO_HLM-1(83tcJ5Je59{xq8!(&GjBa{VPiN6Q(gTdHP;%mOoQoDa@38(ng0b_*u)#2MEMIv=En(P~G6#hQj{p_2*wu6+e7WIGbNbb z&W7n0Fl<%AbJqp^mebpM*JJWv?+P~-F;&Zv?ney2rx*E!P%PNHh>w45a`~)V%{RLw z6VQ#Qc^2{wtfEve^M;BAkQp7o)B|%A-v_H`b3%<9gKC#BSBKna-nYQ2tWHHRvj*(@ zAvFmyDg1Or=bI{ZKH;jHf_^K>+H|wo16ZPCY=U{4gFTWTMV1pGb3pNGZlT>_x3voA z!bViEr(qfzGf)j~uH2O|Fb%hP3ceAhhOw3DrVgfM#~iAvZ;d-Y(3 zuz>I`%wj31t1^1ZL4(G*yw*l#c#Cn!i1pf zYPS(*2*%0lrQEw7Af-tAWZH&nOppnjyLl=89?Q2|yf^#}N(g~)0C!k? z0MsRP1HRi{x4ZK1mc~^XRsO@FYEb_01TUq3%IZQl7`Mi4lqKa^QC{U1_kg;D%Jw`j z#qZ^%ODO$CUeaIUrK>W^{a)c!Jvc};MN0lIFJ143fB%k3{(;s14VC{RUaIb6i=SBh z6x1bDIec^^#4kZz;3@Gy81W5E1$`T;1`~sgYwhU&WaY}J6a~m&I@KnpeqHy}2ZiW9FRF*SrzW)u?z_Umvx9Dio3l%(DKVYIj z)C#F0TtWpqSzZ}6GHK|-t~Oq%V7lePs_@=cKga6-1H;)z!pae9aX*_usDd(WL4&Pc z86^#|x={H?fTx2Of^w0I!CD}Pned8ZQ9K}29A}vDs*EatGevm)8>)fqq~Rr0dUm$Z zLTpoEgIMarOQ`tU3@-`;3g2!M2o=18KkCUgP^R84@gJyy?zehnRQjFh8uQ&Y|05P3 zv-;DZ{LguYfG(jbd=6B>FIfHm237G(ww(WfnmupWa)gS1%kmI|u2;BqX@uh(L{`k( zHd?6QJC+O8toK0`^C77I9kTo|m<<2U@*gbz1oFRggg@%uZ=lNg6I3~F0uRVkP!*Vj zWd0~&4NwVdfhyow%WH%D?;LNjuGLSpTt7{v{Ee;N)auQ_DnY|_ZrvP0PFwycSw~RS zq=M2rTRq+KZlL0OTHf38zLxj1yualGEguXf1)R_ubt2@9=Z|_Z0hF1hfkVLut^N?m z|IWkw(WpHMvaepr=qTH>P+_^!`~%gx=h4-hmn{CrrV}cDzr{B|MZIP5ZHw=MO80@~ zA6fos0xqhG4*<$qXoNkq^|1eLxDf0VAe<;Q@E z*AJNSzf(IA@04)773$dpCtBXnVq>eHVtI4RTUdUY#nx6o)ADwp7LZP$I?~m~$83C$ zI#%cfs-+o<2sQ?8i*S=24wYd>NCrpqN9BwM)$WNFCxQI$Wb;Sqr;1pt11^SZ;EOG; z0F{5G#Z{on)i2NSzf+c|#lr+DPz3}w!v>||s*IAZ;g1@y(c-nBD!N{g78SqA>Ni^b zeD*i*u zE2H#};sZt?yegwQdY0_v)aO8*PG_TuJAjFU2+ zq1r4e&zW#xJF5$ov4iFRhB}XRBVIG2H>fqOzfE5mW!WLc})u`KDW4SRG!JZv~+e6j+>Z^~xxz(8ezY)ste2E3AGA zs7t8wR$49;FR{4F=tYhKYVl=8_!}xism-w3;u@Ro-%t%&N4$Ex-lqHCk?~gorM-qf zYRI)VqfiaF&T^sRH(C7#t5-(F-(+>6@^7}d#p-{<=_HUKr@750yxk`JH%uYjZsL{X zF`NEzn_j5+S3p_fb*l>_!5tgjy20}s-Q;j-dIwF7d)KD<-%#n^Bb}0dWYY^}ucG;xC{I`qkoZpe~{AbRx2pMWw4^d1X|?JalEPY2$@z zSglC#^0n@9D#|%lalyfB?Q)$0RguS8tgUFS%BU0jDd?)Axs9)kl1{U_P)%rKxlm0w z%W|R0i$(M=>6kzTs)8OQP=k8f3_|wV>)2Fx(r z&<=|`L6!3msC185{ZUZmJ`U=tjLKj11QDuWk4;b+mEbw63&o!YRp1L&7xstiUt5vh z5Y&d%Tmx=V4br~~q%5sLmD9$=7li={XW9fEOoUSz6|aAcLzhqmbp|DM|aEbg|tQ2Jw*3svFc7N4-X zP`duTmGGSXGyyfB98>{&K~?;s)nB&yYnJODZczbmSbosryB0sN_%SG7_!3lkUxT`Y zs_(lhcK#CxuYW^T^gZ#yA1wZ8)BhXFnSUo<75-_{{Tr$Q301@OPXSmcn3hH0s;~;E zF|2OmE29cH23^Os6G6>q{R=(1gv#ICa-l5S%5tIdpK%5OC2VaY{tZ<@C*qTWahvTu ztNukGW$R|M3Dw~qmj4?neNP)Nlx;FV>HRF83#y#{mJa}R3Dw@rs&>Q(gqKheLqQcZ z%<4iFG{Wj5tzH=wKicY*QRR$5m%%33{1a`uiB%_?f+r!UfGIXXwoM>Z0aHQUV&q$0 zsPywKuZ&8+0A09H@xk6LJWf{f^KEjWf*0~f$u6?GP!6)v>LnIe+4#z+e3zoD+)||r z#@)V%v+jQ4}vhDRYJ!qyuC4uO_ zB?!Izc3Z$57ViY*MfX~MpT+w@b!aE3t1_ygyR0r0e?Zev86L6`l~D` zssT?~E>thD{G}R&*sf!&o?`Xd;0eUH0#)Q$pj@Q`s7t7FqoDfLCE2GYGRiVf7ug8?Ca^A{GCT_^!SkRRu-C>{M(Hou z^e@@?e?vtb;E&S3Zt)G9z9=53jOxjUHbG@n!#=hJd}8A(qv8*t3lD>`*ta&FP?q`u zR6~9QNmt|?u?d9A_zS3>{{d=f60x%~B!%}%231g1t0!AsD80Jnl~Lu^w7O8`r-0!J z&fJ7?3xS}7bwJI6MwU0R*c8+yRL@QW)v(hoo?+vKDyI#oirRtd2w#Q`ov}BlSuzIH z+f2?_0?IHRRE9~QE}`@(pn5jV;tU)AZ>V&$iC4qsfXYADVxHCWL8V&&hD)~sO1KEr zabY>AOQ<{fbv8Z#)$?mXO|P3QzYSD{w}a}y-Jq`j4V8YI=LAjfbW_4fu$xS3#3L3T z1C{7;TbNLVKW%wsRBy`BmH#f4A{}TCSBx=@T?>{|l<3MB;@> zHhmSFzDf}Rjb{y;pr*xRtX>C{iR*&8gyJWHvee0-3T|ZeQ$SrpHLRKCLZxeN^%j;F zwX_L@O3=#UX`m`S0`u<=3_SPV*E zW_6(ozSwf18nn`Kq0*OFUKzthXqAnqjPlyc(dB#rsERj$D(EVUSAz}VJ8k>}pe~`_ zJ$V7tR{o}qKM1O!?^*l^4ERNr`3hh^-K7=Dx)k=65h=pz1jRRKAn+&&ev`$p~uMDWEQ)W<^V|KG+>px?Z3%W>|h6r~>zf3*WMhLY*vs-cCTDmovOmoEp^kc&ZG!sEfKK&89J;dzOTs{01i$ovj!dr5*QT@{J{j%LI>o3Oe~C{%?tEY`H~DnuU)(@U376?NmKhW6&A z2KD9Df>$mtmGj>}BxYCa|BFwFg*{q9q3YR6Ub_Ab6~8Ks{a-#LcAia8S_$O>|NT>9 zCShRHSH`0s5iLrAY{g4=*aP&iBc!G9_qaPBh{9!R2sg8a~?C6KYj($i?yQLmB`~!98b@W4G zM?WOy{M(1aF)UD&4klO6y7&i-eVqD0_2=?>Z6BO@ zxP8rKXJ5O1bpK7~cX;7H)9Meb+qO<@-o+QZ)%=U17cMHSaz(xKcU6CRPTsS@?)HiG zifWCz>*1H4e(B)}JB~a(y2qiDCT!XFVcSkWF5BI{SDX8ObjA1p#oG^6vN-yj2 zO`o-0aY~Qg%P&Zt@_my&%lB-4@zko7ny241h+j$1jhj|4V@Q(;7Y~;8=W3~;cd-L!!ZzwD(>U3;c%jf!i_1m1wwK@U zyXW3pl6F0Q+7H=j%`SYi#?80==PB>irPohyx?}sK`nNsVG4aVIk9>K~$Iu9TV#X&D$rQ>wXc;Yo9nGIM6Y%X7H+nuYx8W5LTXzaB&BOZ-RXi zQlkhRJ0g4+EbEBysf3Rt{1CJ~8)1Da!n(5&ehS``(6$4i9!pxlc-B zQjm~_GQBHGb{a|~DY!>Uy>yi0yHHHkAgc?-JS*WT30{!W6=6{fVSZPH>cL|YT6RNd zo{ms6n3s-lK*FmMY6VSV2rIiITpUA43HC`y?Sas-8$#`1SvQ1FC43~|_@Hffg!MfU z)^$gy8@wl>Z!d)2JrL^iuiPLUk?@0rlY;I&5w`Y5*xVDLVepNFk>?-`>xIxL*whOl zxer35H$syjvp2#{3HM288o1{mOz(@3eGWqNV4H+`83@PsL1+ewAezLs)T_-lVJ!eM<850 z3?VbvCn0qtLdW3$M zgM=|b_fZI2#~^GTg)lDoM#9Lk2*XArOb9lOMo1oq5E+Az6=aS<*eT&Y36leNEW-5h z2-#y1vV(0B>PHC> zIUAw%OoXzaa3(_P9E5`s{Gin=gij@u&O%rhye?sVE<)GY2tiOX8=>!9gfAp)2s+I{ zI3i)=9E7WbLlU;mL+GE2urb(>i!d?|;dcqw1sQV@lJgPnn2WF}_*ueE3FGD=+!)+4 z4`F%%Ld`sc&B3TVgnIK4c1yT9@bVF!l`uOW;g(>RghdMw8Wtej7UUElv|Na=SHc}Z z{rLz7BrKhea92<+VdWx()(a4}1%(R`QVS6dO4uH>T8Qwegwllw_XV#@Sicyd>mr05 zLCGS7zUL!+Az@e0sSx3agpGv=4+e)MY+ZuTe=)-DV8ddBkxLPNm+(lCaXv!w1qgSX zkMLOVvxJ=z#w|g3BDiG*NYJL2PGFF^j(4Qg@o6GPRkLFNZ7a>;mzQXgsqn#^uHM4V6fq0 zgpn%|ewXl0kg)k6$tMIKTFstVcaDM9|X5tf-rp*Ld}&39|faUBGkJSVYh@& z0qBrLiNq2Vfo!$Hm}gqEcUdnJ4k)V~zrfP|%&B77B;OIW!Yq4i}5 z-vou1A*8NBI4I$}pjBz&2>1J7nc#=ub-|B8+tt8NL5bi<@Sfo3pwk-Qm!ND-;tn>z zjJ1g^+^ik*)+PpSvTjIhkwp3(1y?72o=`t5!{JAQSy^Y~=g#4Wt)1h#Q<4(Sbc4p< zB_>7YoWnO*RMADMXhwc^{$!GU7c9L#F*rWs-0*87#gk{{w3)#-F;r5$(kJ z8W?_uv$*SE(>7C!&AwyY4TNJ2u{tI5Q!V zzKP7ivg;H5;QG508@TDg?z3!?Mtl6`iYj!;LVq*JH%9}H}HNAJzceLJ>c)IJ(-!bZeM3(Ve`MFuX z&r|&HfA~(GN@$;;M$LUQG1o<0MD>eNc*L`=#rhSR8Bt~xHll8~$c(X@BF0VTe^m$sX%>W ztFzTc+I0FVQ5UO?LQ_LT)2$Z&c{nT){wxy^{#2amV9=dSDu8ReepgPSz5y8j{i+FQ zYO%hUUrzxp{XU%1=?i}it(J|Z2C}?3jjR^`{WyIqxv|xz+r0V-sQ6b}bF5ZW8!_3o zdWJ1fpV!q_o^{PaQ}6UWxh_`AwVCxDylz&TYc+kTzaKAM^Q@+?&W+%ua`J3>`oiFN z`^`p2KVGNau`oIldFfhUHT`<`lu+T-@D{dW{lJ~_>N}SDYP_!Vt#&fuPp!7Z zYOJ-+TUJ}D-xZVz8}qu$it!<7f_Asnif!go(6(7^nbn%2?Y7#5R%?dVnU}7Mtk#?` zKSCc~%dK{*{9j+R)OE2HTM#~CwfN8VwM5%uhbjJ(eXY=Lwp#pW`%Xi<#cJ`N@H-vt zR;%e({M3dsc-@W`&c92o*c$O}oA5F;S*8uIZB~o_wBMO%`nszweR5L;p2h1O+vv4c zYm1gFcjqdzT06pPY~IV0s9%}e^ID6jA@yxS&EeiQ;T33VjOK86G|5-mbY~NO$$ENV z(?!wtS#5*WQqlfnwX3bxN&Vk%#f`Q=joU%1>9+;>U;osA^N!W@JA!I7zu@nDVznEs z))nn*tHpm;FdglCt8KRFVraihll}F(g6ds2UapoUuB}$n0J zv>UAUs?9tGO+O0W9DEH;JsHc(wPt zR-8z&~)k7Fx8k`UiVn-D>QXvF0buY`^Ki5 zht_}$T7(a%;aMAT2|Yo&|-w&!BPebj>gr@6O|uIl*yzjH6#OQA@BBqZG6 zS|A}pg1fsziwAdiOK`VB*|dx@WNVGyt``@+=@s>uun?TD+= z&uRO`S`x66NicySjDw&tekE`d8owbt7dCWyxu_;M6nO9}g{x=BwSdDwdgG_(#VcZhM9|In1sT6d z`27Y{BBnKdlX=!ARf*`qPxF`pwE5Iebx2Jw_EY|yrOos&z44sNvtClGqEi)1&2Jhw zWc)H4y3g=asi=QhjNf#glbIT4HGYDhFMcX^^%7Q1Zw7Gb{I6m+ry-olb7B%yzmJUH zES^)COmZ2&+4%Vyzud-e4t{>dFOTt?i(h(^UWoCVhu>qMqCHeEC{@Tw@7lX9MuYmDef?u%lD`@#`lApHaf=$iFL>rRfGoda#%~3Fm5it^Zv0l_r+p^2 z1^-GI&o6oY2l3bnx1{k~#j|FjQnHlsTg|g(Vo6Tpw+6rUK>x}ZzqLG9V%X_lS>v~k z=Zg5LG%cqW)M{tYh0cH6v`IFD zy~eMaq1%F=UUa8Yvbyoxs?tYq!&5O?!+37vS${l4rJwi8-LH7=2c1eay>?go!gf#$ zzahBwOxztj=f-a+ZhhnTHP1Ql8;1L_@!QF>b!(=!|0l+C7th`+IvW_j-S~MoN*fx# zJ^1O>?xS$^YG2Cg^9{IY{2Cj-z4$3d^sfo7a%LacZRAWd{4D)%Kc1fwS%piCAw0nI zH2n0hh4K5A=c_;kPAmL0-?{TDsb8v z&m%mSAY~OK?Tz12o>l)-LDIqa9phP7z$za)8o%Q_KcUbnA37O79oD+qRr%1__?_fg z^PQ*d@4XFK$NF8Me_bI|cAW1ZdK!;>sD4=FXNXGKkdn*jo+_4 z>s_+DaK{)wt%UyGz;4{J#_tNxv+z5h?LQ7rW%X4s+xGOCUFjO2GFLOV*K=73#3i;spSX%Z}M^#D9fiB!dpBmtCf}0jNfgZ z^+ro&oA+CzJ3JpVetIc29JczR2t zKv}uS_&wqIDp0m9Hhxce*5BVy+9mjD)BOYVw>UIxnW5Y2!vlYH(roGfB%#yc&d*B$ z9~t^IVRS4%E$K5A=>0> zpbOln04jn?pfaces)A~uCa48!gF2uts3*yuCCn1rjK>(z0<;9JKx@zrvaAD|ans!>giXy?Hta2e>8o-6di(v>`X304C& zs;Lo8jb`h?2CxZi23x>Zunl|#b^tY`?E(cUP$5tl=+8(U2WmXi-?q{#M!o@i!9K7J zdk&{x+f(olm`iKU0}H`oumq^lO^s~J zfg0A-khT)2@oWuHdzsqD)`Lx8b1eVV3^*L9MNbW7Gr(wSG6tL{qYFTdWh%v0YO6#Z z42FQAKri-61k`v|l6N(jsV%G=s01p5Dxeh5Uv9{Sn;YZ-HFNM!FP{7yd;w07fEvS2 zgYUsv@Dn%(egWsfMQ{mR23Nr~a2@;({*YcT66Wpnn8zpJAMhN!055@BtehYLZ~-?^ zi`54pF;Gj@haf3X3zaWO4b(EFMkh5g1p+lJr3G6_bGD>>nJ`VP$|03Is#mlD`9OY9 z4Cs;}GspsTopG9)eh*ZvtHkz)3qSI%w_F|r$HBK?FW3h*fi0j7XbbkzG&6{&cZ@az zU8#kS{#M*PA6fk}VL-uL@HscwiJ(gbVFjKmfy$r?(50a+BU>O5TY=VK75*FK`OAc! zST$ws06IlDfDLo8<0*m*7Lf_4e17z=vlCaDu&L zzYlx|t`K$=9E5~ljbS6vYMz)12s#X1v;VY1ilC8<+%sJH()o| z1LlJTKrL2kp;`=Q`b%@0fd2BF{wUmc;2=1pqtg1>I5JEKF3>t^+WwqDuoA2X z8-QAl)l!_1=K@3=i8~6YIco|KFbu?i)}RCE2o8|m5pWdfJ%+x(599;UAb%|X3WFj* zO<8KXdI+)F(xb>|EVb2Z_kIIcz*X=U;eP`)Rn?-MiPNOC(wNQod z9t!dTy;61+SPj;IGBiV3pq8o%Krazrmx${U)l8*ksVN|c8m9#w`NHY)#Ae|!E70q- z&x1>#2=5DU)ySkqB{d=~2WmK43DhoB0aOI@DboU=<~TLK=?&>>Bhuf?s)<_*l!0No z2As&V+J*Xp)}T!yA1R%{l`^&)FWo^a5CimU#E(Hipmv`kAOpw*RAsM+t3Mc)7gv9% z;0bsN{sGTGI*=Y@0GUA+kQIDSoFBj$a2EUsFz@8De$(Si5?%#XgEgQ5wQC3(0k!Qk z0nOxj0#}-twmh~29Y9CW8FT?%K{wDH^aQ;?Z=hzNeqaC?2nGXPeZ_$xU@6(D^7Mo; znw~P{l3od28Djh3)fecpxE$C)M@>t+>*c$@fb-xYxCAZ(y(M@j*bm)&a2fmxYSJ#P zNmdO??Ld3b0dxjxQ0f6%fevKf5p)8bRc>_Qp)2SHx`Q5|H|PWUf_|Vs7zhS~I4}eZ z1;fEeFdB>j6Tn0;2}}l4z*O)V5HJJG1hc^$FwcqHSir*~uox@{Uw{>04Ok1-fem0I z*aS9%Enq8{K+Scv`YF&w<}~mbhy$14h+4kX{(l6hB`YZnq1LP9z|DJ-SpFpkYJpOV zQ%ay#CVvnF(t->iGdMw_CxI^b<6vbXnjs<38^OP&FuKywm5p98eh8YwK(8-XgHjrx zMx-F1h9fl;r30~Q98zOY7LXO_jqg`z|1$`vvp`Ro?*zNSH{bv`1jdv2JY2mS^*HoB zDBx(Im#?ZZ=oxRX-fPSD?653yH`t1hPC@hS%qOfK?iK}5JC(pTn z9!%Cd_pgF$;4;_^)GniTn0;Uy&|f&<+=BJfTyuDyt9}%sKd$~lL`hH-WCcPVGsxd( zCJ&|X_z)xo$$;8U9Ju;RBrkxPO|pUPAP3OH+iEu14ZHV%D4uK31nB`k+v#(cLfivt z9?|QmZ-Lw34!92<0KLxoYApY*f$QLRu#m#+#yx;r8;;ZgYe;-5P;*HZpua$Q6wHBU zF<1ds0^Og{{TSVU(d`!9UQv_COi+x%6bGe1X;22}7Hn)6{uKeb(p2k&S{2S}Vn7%5 z`tzE)G*)xS5g_yrz16=X=ni^-p5P;p3*-SIU><4q1Y^Jens*@R0@Tib6VBcScN6(! z_fZ4E5%3k*4hDijKy56uKmwjaB|Nb!b!;U#Um56+5#<7Tz^^dmB$Y`_IUS_0mwSIp zw7TR|AAAfNfW^=)0ZW1Y?&Bi-<^o;n>jL;V7*4qhfH0sR<&FizKsfnCxY>S);-MhW z-vC++mVkPoK4<_Mf<~YzXa-_HbI=mB5=RnO4p&bedr3$VSDM&?JPrb}Um#*g3!@EzC+Mu1U3f9m#U z@HjDD{|SkW#&Zl93o^pLg80=S@%rEbiEan_gS~3#i326TSm-7K-BK?J8sfK{c*k&0 zfuF%Gpc}#Z>!^)*jseji2S`Jl z%}eIPDNtLUb$6;UXaZsj@lSV`(gEF3nnAnf!%Ybu!MaS~7=F58l!uyyfC`{I@VPXXHJ1zuF}E;Xs$KgFt_6|JM^#bCnwI zH-jxe?e)3INNw~#gFRp;_!{g0TY-kFDZMJF0p{a3l5|Faemv{11nG~VHpNv_`bQua z$PIGD@-HXwvd~8ZNJLHF7l4|(_kiy}Iy#?j66mJD6*}Eo{M4d-m5i2wX<#hq1e$`< zAUXI8nw2D61=ef9egj^=4Lnz-g0FEr)<=KvM>9Q$`z`nm902OC&{7V-9SoFPLqKtm z2ZX|jgt%&tRr~7|plMabzdG0hmlpEA2&gSqO|RD|gqmB|fW>+=N*^>6?Y+tkO+eq( z{{c`dq_Xe^_zkEfQ!S2~kk(M2t5OJWE!BLg=2A6}o&YDoDKH$203*RDFci47Mt@Oy z&Cpv?HE*gpvl)faL~jDkNHf&Tek9H%Tg83D6OY!#> zcpiT9!2%GM#^nPkJ-NJKzRVn}nW_c^*Q}-3LY{krUZ50cPY3LZtJ8Hy&;e*BI&`(~ zv<2m%Q7%r$)p?;2P{p<(u1z(3$F(4XGD4Q_2onbLJSb7uX1>^e|=|99M7aODQBHenm^M*_K%(G?J@ z;hLxBSAl1BbwJz$UjGL?>reMS1b>42K>hURef6h))n8rj^CO<0f*$1g9QPUUrlqd; zd6vURn&xwb$2zH)W~>GfJgq__A$<}8FR?CKRAu+Rzg}<^q*`DtxMt|3QKcyjVF5rj z`cyzItfNRvHGS3i(f*VBB;(-`87Ia4kdNhDUHArULX^wn(#1e(Srz5V?^01+UIyiH z<&M=QL1hvtfm;x0lNJEcK)XaF2nCsewv--!)o!89t}UirMZ1HxpjKGJwBRB5c?+*} znwHY&;wlf%D*dzSuDX{X1q0~>;z9n&s^RCP5 zPk2`SQT0fDuY_9$ly1g99hDV9YKSY~mIviPSx_2ics-zsXmwB(sJ|v&1y}8Q)j$nU z3)BSVD1d7GwdH<(6hw`#(Ue46OriR!x-D^=gBYO2X$rhF>bBzDLvrxvIe5-Xav@+4@A-NE6@LE)=Hb^LzXJG$0`18Ic~}1dxH{H# zZkfrmD$et9=V}j~!-Epe0yDsLpk@3FOa-5UDL@sSF(3|%1|vaE5*&d$91H`oU@*|k zm2L{Z>Igi(m zK)L?|?s1@L?gq=jL(=#Qe8uw~uoh^(J3$0VeT};eC^M8^!?bKWaJ931DbEYJGJK@b z)&P}(8f`VtD}mawI)E>DenHp@DO=c8n2#HV6n3TIo2!|HDWm4C>23o%AyS3^IPN;! ztzZk-1XMZLfZGaJtGJP8A2QP_Z{ty?)uTY^Hv`=i90RsUrXsG$behF>pq)uO++*;n ztkSKBE453xvP;Gkab<8EkuQq4a)hhTA#f0ACBFp+fR{hJc-{vzzrElaaTI0os;_Ss zN7<$R`+;_TegBSUjjq*I(}Y(4Fzg963D7IZqAs0nBgR3cP_CfC` zrsjOfOSaZLYEY}T{jxtal}3t4_$a9gyB9*l*85$KD5$1D1(v>FdA59s0bo>6-;IM_8G;J+pxX*Q|2>~Dd zb-;1DoHDYsE5aGq@%I|LoNk_<6 z(^oeiJLrSXghWsU+UTNutxBy{Bv-Q!?DB_O#8!}P&Bw&QXGQnx+Rbjg7XI+6`ypt&NVA@ znuxiYkW_@EzQ1YX^d)MF}bY>P@DVcg=BpD&ZBNn=P5PQG4ARWoX3J`fXWyl;5fWt$4WHIBw<0C)1A(^F zpMK%r*Yw@}l@&ECG@6N3PD0?ABX`HS{HIrPCFFzYlY{WtCmAYHrJslyK+Gv^Z%X=J z87>i1do0P{B_u5&P2DL^*Qk^7j_LIUqI?o3lFpS74p~`TGdsq8d+u8PI+5#d#Zz!6 z1Bp8t$#xu%TKZK0eOqZ?fpz=aJIN!WU?_vvXQtfMLa5m&GXzH~XACQFW_iE(gw7F? zlaN%=zh@kJW^xPqZX_`aqELJw#VWh1aJ#|Fy{@3tdWJ-s`S;~xQ=B>D?&?Hq*;3h+ z$yqqDoU80=9UO*zO9{e@FUdA=Sjw~%A`~Dt+}g`G*udm+48GLcN-YtHtq6tp?p?8C1;`$(Q%*s=>=; za#)?UlFaGW(e+Z_4oJg|By}pe-7kCBk4QIRV6{Uer81VmbwR3Dhwi4dsZNUD$R>3@ zlLR$fk-<;tF3b_Y3w{bWH6S6pyb z#ws<8^BKBx`FG{IA0RL05{(t=FZb%xEeb%P={ox-+dMY2Z!fDf7DZ|4Qj_9Vhkz2t ztsJ*-765}EdW zhM&~0?JDSrqEGumHLm5fbvw=-yht)gOYJFTWhKdw-TvA%Of%`Wf&P-J4oq4mA$7>kj!wX~FYTa7xfZVj$q^fdO@hx$+w+s)?f>seLRSby~{TU*dF?>byk_M7F7rD%$2m%YmcXXH_l~ zux9nqgy>YfrrpXPj-=ihU@AuGMCKCJvm63g9~XFe`L1ibR%S2+@cojU)ST>mopww6 zCnV-Y$xxq6Z!mmydit_U_{NTRTBz(YlJOngTxAz&THQR4%&gB!!>)o!IMCzCW)Hu* zr*CEL-^KS6l8d&dtf%r}Q>)5FKZY-+%LTi$+w_TFPMP1V=Vb@<+N1JQ-|RB}V>)Fh z_0pC}m-%v*-H9`AgTfT!sO%!CsCSG8q=VJxNL(5ETSSQu3!N!H)g(?0Zb-6EhS6k1fkL)zhe-Jp#`Q*DLRZ%64ubw+A}McJ#3Dj%)R^TlF{E-^`l>-zskCX zq_j>B<9PHcdY$5Y=Z%P@G@vEH<9Uw5+XSfL|P`1^g<_Xd?)DZL^LMF-W z#;!Kpmr}QhB}KIa>&QKG6| z`mR8-Ia+zU=Zuh5n<)AmdD+w*TsIB%_*BRSVIQncmnoEp|U zbC6Z z=km*hJPPx1Gl{F-8Wl5XMDsIq0%2@^yHT?ilzA-}v!$U>y`k#HZD-b+RD~id6laqq^1n87`Q!LPbd!Z7?wBsyaXj0h(_!@4 z^0W)KWz0$MG^=>>tZWD5NLxxJl+gBVGA5v3_wj%Am z5ab|g$?!gNr=7@9C!S!wbb|mrV4OO4q~t7@U!n*d8UaOQcPq+Ytca~a-S2YcyFX`M zJ!8eSC|XO(*)Bh~HI61qvesm@8Dhji+@2+I0bM&aVl6=>EaHn&5&~!9qSB}}sYVuM z1VPxn&aKCzo=4Y>FHvKe1Yy)@2pF1icfUUJTc@_oZI)YEZ6qXwklwfZl;~ciWU2V5 zm*u<`B4sg5%MgUt%ztoy>1qe#2}(-JHdM2R88ucu{dkx`WV!m)Ftf6&8PLweYYof`-Nm9YyqFMge+*!>{_sdoM^`gttgrLy8Kjs(6#8}esZ^?%jH-i>w3A;B#7W7 z=sFTWCST6w4w5TvU3s{WCuKWVT~C)%w)UKD|FYUSJna+OX|f*l87o8D5$8*pjpKZ~ zbgy!Zd?QCYBZ+R0P~9N+JCJ})>DFSJM9}&(X~;1--JbFKZ>8DN8)3eovrFw zBHz)O)IVHBcRrsP73`L}{Nm{9ocWT?utKct>_h@R?~5A-zpbjj-WEsX;zH{DyQJuZ zW0-3!E8ye3VW-QC<0%G@t|F8! zUucBdQ|d}cXIIsz;41cv5&3D0{(I&w802)Mz(>VvPF&S%Zx)V;IT%qbv8i%_h_E8E zrZah0l!KjNqs9Gz4Dk2u%zPaiNFy<6yvf%`^t^!v!99@Ka)QS(rtGu4{x3Od?(nH^OJ-IwMV_*lgnrE0%C{$lo-UVr5?n=^_9Xsm9O@)B`%q(~ zSwWwv67w0l(Sg?@*p=n#x4gZO5MkA&QZIP&j=paQO}TBRxwIHpB;^nioi#bW6qdM* zbeN&DrZ-~Dc)jifVRE;|lT}1*L~T7M)6IfDR=e;TX@-rTOII2Lm4 z^|#2y{@!+ZRR`10*O z;*$j*yH`i2>tw4<(>nD!mS$$R{x*LR_K~FsQKctIu1^}JJQ`xpxl}dE2h}Wj9FtBv zsX2wLrb@{;oNdw&$8(Wr8MWv&>QDSVWyjiff?=3$UdoWk&{@JK$Z5tQcmL57f*htx z+QY(Wcbq_{Eo}mw89Pg}A(-gObhgX1!Ih%Ug1p5N*okXzc&CbHiQf*gijn3?Y&53U z`5GoF=qST7%PXJf$Ylt)*AjKoPf`qZxjcu+N6lWlhjksd|KcT`0gW(!AbE$PUS&0^ z@v{?sbL~qtXQNG^Vy-dys8}xhYv+jZ=aa6Ck2+lj5!Dmi#a3uzM}K&ESi(MR2YAyi zA?qM;w3fq4w*)%XSKHp1J*?!gko@s`HY>LP2YxR$|#J1$>e zzjSYTl<0#QOBz>3=;w z>S*Z#LG(%pv^iX*4~Gqze^kwih86ErwXLq_E+{)kyl)L-QJj?fS_qcBBPm3N9(MOm zS9kN4?UfIzx!>ebPKrZN{gPSal%GAJR`q|*kBTSgNmN}BM7PZ{>&byrRpLXo5TZt< z(YIQq?esmMVT^+wCs66c8@}WPnOHSFvUF{<;wGl?6QQ6rlNO=rHkreYg--9 zRj|6s7Gp1ZA~BTuHpS*)r766=BV!R%t@UxbnWr#+u8_ z(#q0_{bcGGS9oGQ3W{|x&Ym>Q%7j9{IcdC_OPJGMn-we~Yj*Q`dJYb>d3(O;)yJ0( zY)C^rm=1K|VyEE=A7n3F0$yY;yKBwqiB_`|P&>A@BVg7@W(Hyd%$hI*xpx$W$K(K0eP}2ERt8A7kvsM;=>aE|aYFca4aH%&HW#El!{y!-MwZz-x|0@auF}f%ptgikD$QPFsQoB*<@Tk@cF7(vj+fOk`D8*`1Y04`Zh`u&F5{a zbUWt?NFTu&%Q<$tezNP1YtDt+IY~#Y@t8hqO63UFBTeP&`L3$Y^z$U?0?OP$vMq3J zvJ=3pvw+qZCyv8b&rY$Bq+_JdLNcFYF>MonJWLi3Q8uT4r|FQG)-y8{!Q~?v~`Aqx`&c3bZVd3#H`e z6nm{SRA-a)`ka{`OWBIgIRk<*@X~5}fxWJ>SH;Fg50#A<6Ky2#7gYPw3cK2c+dmmO^Orca85twKeM-S`L*~c0{av~z{+BE~f{dZV z+U0X{3A!&O34T8l0#{C7!5NEx@A!Cm@qRAlSSi(rYnb3POmmc#@U@iNdqH#dao0i; z&pOKK0B?%rWXfs?8n3jE59Au$H)&i**v@!@nKH!XrW*O#F}Jp*%uYg$m2{pS(t(|- zcaQ8SbSm9TUa-=&(bF=cZA*LJ(XqB`<}&AC97>?>pbeBRY22@WTr?XG@7!F(cDpM%je1aetfGIs)h|pZc(}^NiGu&Jp&Y+TW0+@{?66sB zR`}LV%d1Sxwuxn#G`-G@@YlWUGH9>U126AyGt&a!t)T@v$Zu;HtET(e&25T6SgW-d z4C~5%4hfYi--*;lkw#%YdcTt&J*c7*&(%>sSu{d-r{?idPuE)$GeJiab+o z{?aF`Bnd%JWeZEA2FQkWs8#Fa$P~>NCj;c24DAxgsr&nO-wuC}v#G0^v=| zXMnU{&pdArG;a-#%J%h?`SAu@Y^>S4sA8QQ8Gp3WvdSDkLjOGg?RnpsV55xRz{oIM z+qnUOJY4?V087TmAjK3XqlYfi0H}{CX?H{1HD9chEj49HT{pB zMeT?Md@9N8Eu{a(2BTw|T;4>wY$HC~#N@bN@@|Hvw8VtdIhRR`%{18pS*Ok=c}du- zBFvPUojJk5NhIHHSRPw%q5YrA5Y58Q$y0TQJgvaaVtr% zl?{WH(9xK2jk=b*RcUo`-ApnqSzBsuW$sM7QxfVte;pcsyvXcWZgPl7ju~;Ea3iO~V(bA3wZ5e;Eb<@1Z1n$2`#9=#HerPSO2tJ1wVuVoCLii`!kt zG2UunqTYEhLA7z8dHd|O+ro5zSDLqbXeEo;5p)kd&8_u#BY9Is&-+hI*+&k%#gO%1 z!#}$ap7$S)dLf>jud3kaFDG}p{0gb&?K6D8J*PdWmQ^-Nu%0H-{bxcZ65>k>mRd6S zvyTdIhN}qea6Qj5Pv(-EXEg*VA=q;z(lu+-wbt=XY-JE+=My9ece$$lN7+mpSwkz& z2dYDo`AgZpivrJ<55Hw{zO##c>um?^k}kU0KX=bYf2!3&doATTD=}w~Ke2~h{;YDV z?{)a|~Ud>SVb};W~{#sUbVALIxlWp8-|AWw(^@wzB?hbTD9g)deTrH3sx5~Aqzl%~iW?;!T%EMc>-(x#V}E;PDi zZ@}u2*2q{{1)*nRSzBIDT)4jO^Fhazzzk_ydc9pGyS{JxS~U#fM@3{WQlPRN-b>Q& zIgSYPt;2Yc9?xle2v?Zp>GaY3xH760ph8AO``Cwlqq7=3n!5oDqB%+6;+fQo`m;C#w=XB}7o5%Z$5nm=NbM=NSqm)c% z){ORz%->IA{U*2fyV|^K%ED}>oiQwlbUi?sm;YdI0Ord7vwLHrf0~*e2!++akys+` zA0U6@%-%xhP3KUP_RsjD(1k`49;m z`PrT)9bfM0AIaOC zA6<|pKez&ANh65zwqV_6Ye=5_w7w3np!F%AyC>PoAAA>;S=l=pYC?GjTA(KlUY zKPFvtvDL>>lD?I1kJCN+%Rk3mRfES}v1QMVnk@#@7-!A?+CPwD!B^$T2}`L$@cJdv zLFtp@s?0cnakcAJyLD`uILC6SdXhnAZ-%Sl-txNLSh;^#-2G&S^^Gh>TI0;t45Hq5 z{wTs{!tZ<(2%k3f{weH4?;-1~E+2uojQUa1oq|u+2_{a9L#GVSw|VLGOBsB-I~@z~ zQEUH2=>VPQ8Lzr6K0A@`hhftmZMG6Z?iS?8#C!;%zUpQh!dG43JE^AJ3t|l}70mD6 zFCiq{Ugrl7`NLkBulgzDsc$~*uUeQfzrV{2_olIjvru23W}D!h2Xic&Pm-JVc8#oz z`^ay5!N>8b=f5dQzxVFlTHDDD^mV9A_?`n}HgDOH;d72OQsM_bATR^WiAe7I1C%Rd z``s{3$um8&xbMz9W|)3{G;_9_~X5C;IWL==s&4(8I&b#Qt|B z^bC?R<^#JEIL~&Aladj7j7lXmX;>pXGB`6y=op^y`Kkf6dZ)c$2uLFIuB<&{X~vw; z4oDat;q&E|=Vx3WCh(T`KU9f2QuG|Xz!)+tn~^HjP z&j`{|vrOELbNx3pJIDO&m;nd;Xz^d4FALP-xkCA5}hr zv6lKJPhk>BMN!t>xc2dGzY_JW1gs`|L-Kj5Lgxovn}zKw1wYPLNQ+|W#VA2lFTktb z5corIeb>5A-L>cTaXRe99bdP~5C~YT%~rbiPa|inbGlKRNhkve75;Wii6@@yJ2fZ! zboe{F4xQrFvCZg<==fu$!$st%$hM1!=*4myCpi5>d(N3s=XBqaQQx07EzYD=;Gq<` z1cRo@^WP}t3W>pyuq&j5ZSsaIz!kx{$-m^@HHe1D{Ywy?kUf{-qIcKqCmC`RI?7?w z<<*aDCW_+$hFEe)`N(E*;QRqICoHd{D?HQN-b%+xo%4*kUzO#N`09?_a7l6Z-#OZp zGVWJC37sL0q42yv7n?YvmF)Ye?6OFn-&jFBer$7Vd*2&1e=PT$L%7}&+w5^1l1#TL z)z5PGPfnOCtmYT~|s&Y=w~)T4U;V=I1#mXAvDqpSRRQwrK? zBq7>aPek8xR6Fc%uQjdNdA7_Yq5t5f$$qWeRJvUxl!}CsmzaLTGobdzWMPeD)eJLS zgWwVbX&`7)?NaSOYUV6ys)NnXZWfeJTKkc7g4mhtnT)=MNVl7mpCP1Q1v%|b6%m}~ znb8MoZJS>sdw(?*X+J`yW_>2buG3kpKBpZBzsP5D>j8enW!!bfL3P=6o#M124YfA- zeLueR&Si)7!!47B;b&(__B)L1E6?xYjFgi4HbolZc;*o~fXG>5%YF3ct&FNjGnuL2 z-zbwHh}sW<%C!NDt5=FyeMGlvGf@Q2wpbymMsW4&c}?5#-0pIL z*{^51FnLxM6BP~G?ov+AbIJ1uX5sgDt%&E+OexBcl$PRN(lqVco_booW3NpQ{@YN{wC~|K6L{1M8BAQ$zW!;c1#r#^151k?2+$Mrzqf zd4?x&Sb}Elhvz!=9kE%b1Rc8Y^9`Bnxd@%sx%-QiPtW{1UXOO`w{di8GfXMYLt4vD z-Lz()cj%b1nu?l1W;|a>0P;K`G51(Vws+gVn3yc!af5r~FL9XG8bS0UlY$XHuc8uS z#;Tpagx$9}q(yoMvB}yZwmt^6n4Shr;QjTq#7Yome9r?$YLpoa3uY#X&aiF#T~oyP z-ursl>?u@cK45)s)!?WHR|L z48R4sQBzgU?%(!n61ViTj4;I*=*kkJk}vL9@)Zll?$}KTolLdS26Fx{_<05b)fCre zSQ|JlQx1EUvMRtql)o`DyHiNBzg@@Jna%r%Mx8F~#s*3AM`$RMMIO0^{KrE7%?0rL zwZ-=@fbEs9!~V9FHaz~=HQUiZIy|8$_Q#?8!1jE7GkMvHr`&piBJn>Mg6ckXMMhUX zVGGzjsS5wqw92Q4Ehgz1bDsmL9G0qns{RkZUVJba71$aOu+KlW?0m`^KmNOBV~02= z6HuO6Nb92CsM6T-)QCYf{`!ZVl0km_!Y4d$kYi8ukjZsUk*Zn3jF-mGXz02!1t&N| zfZZW}YLWcQVaJ+pjL$u1fLwa!Y90NK??Y)jZQl1=x(oQrz~@ZOrRB5dY_aim=b`7! z`sUC;zzYU&V+nuZD$6HLeO~ZM(|(!x!j;=|ElBUsKnL$0)3t54jy|3;-JiC|ygQvQ zhbb>AT^Dh@M2O7dIzTll{yDVL$Z;dq4X4!R(+|Ui2GZ`OeymuGIFzrR?4oEso~+6O#a|a%)9e`Lj+?9oaO>oxtHZC*vG^2KFAKJyPkU?1CWb zQU-^m|BPwsn$)=5nieEyx_^iC_K+#mdPR?^IhyF_PJC*w+Jt3DdKdEm5p5>Q3bxrtm~I=EryWiEo#mfKOK$v~g= z^$t=@H5kyFZpwT&1*j{haiaf*&KJ6CS@K_4yyN&{=*-;Z=88X+CNp!UKfOJ}M%|21 zrje6h9x0N@-P)543hn!in^gKRegp^Tje52 zMBjlxlNjOKsAI?B4(kI$+syog5Uo^Ds#G28WJ&S8iAv&$!zDBct+p z-G(orFnyE7Y7%$uECsm5FD(RhE8897-o8Oy=bSxaE%)d-F!CQ+lZ1A$kH7>c<-!j& z1k79U>CFKDQzJ-FkABbxgCgYxSw^?aXxkEA+mSb)9qu5m7WeVf0d2qecp5g}rTC=5 zhu!=tAG!mBFY~T#(ejhM-^@#~z~yut!ABXJOA(`_iyGZ=afLuIisXTQg>_f zfxVna>Q0MPyh-HXcL-VSPGp9V&6vy`p;j?Yf=Rn%?sT5T`Rx|;jL-KX-PWoevM}Oh zwJc2LKJK))0sM6vr-zK=FoEY`0lQbM{$=~EOg-{&cECG5zB+C2Q*yeu+28!2uv`jY ze0vH@wG6oV3rlDkHkYeOOd1-mnM_K7(^IMk;Y^SCqk9Q8SrlJT=wE(W?I6MO0BOWu^P($DJk zeSi9<(66VJ#2d?03~^F5m2OeLRlhYd8*k5d+?1?F*F{TOc0I7YZz^jeMq7i$(s3nl zagDMEg5lSEGk%sRr8Azu=8!XEaY>(=0TT_OuGr3gk>R(m^R0Yp6EdwLcWS17#Y0a^ z=z^i!ozQXMQm@vW95C{eW82hTzaminc;cYb-gP+by{ujQ<#XE6C`jYvcIsDL`X5^1 zmUQuh0|`n*tY@c6UoZ^Os9~xBIj4WeGtzXj^wBXMCh2-sJ6~lzA&H=l|4X z-kxc?q|L22d*=VpbKIq6a40xKue#9Nea2+@|JX~NcAok%)&Dqr?EKz}SJd0V z-#;v7m$kcM(1?#qr*kz?>274qIw|UT$6$Damzv*h4-)eL$>=(B$D^fB`knh^ReVpq zU_zd4o$|$*Y#q4H#@mPgmSn-N`sV-M4zDD@-*P_KUG~+hT`)P|ivazf+15^0rK1el z<#IZP(?f#tvh-KRO!y+i z8qwCYW}P4iNQi=CKH}XbdosgRzE0(&kY_IuRbq|p-u~;xmHyCAYE;ul6qut#$7F!g z{Q{lN)t{`)awFM@-aDYv>uC^`H)IV2(N7^jHIA$PWbdXO37gM?z#QXER@t7imyTJG zC0DgY#jFt3HGDEvmM^m~d!qVef#J&}byjy(C%(LTj33iC#8FTMPE@@1?_jS4bTHe@5+(sDhUyK3+<=u``?+w9iMr;}sU2Bq^dRmf69 zYGh|Rc<0$r>+8NoGAujFe?(1NKe@K2tzY-QOX`_n!-Yq3GCN$g4>B*4<`FezJo_*;I-mBw$9mR^;t!p<~pxn}gVBQCzuM+YU zEMdpG*?z#t#D${gQ%=s86u=07M7o3`IyOL{#-V`J*Q(?kU4g|X;nsnN5l!r-{@~QQ zIf;se-XW^4j?vbqHj$m7aMBiUay!(W&bh3KB+bjZVm+}`KTMpX=CY6;HMNJi<#qq@zWrbr`u`Ux8~lDLYs=C=c^2+Y^-5>MGcbad zFkduGlvWW8D5TRye1kI~m~}n2Z*`wisT^h0zOT}ZWr*k^&WW) zTkWeUFt5ywL50?ZW52ccqm(`P^yLmTz0kWI;aEgx<0}pL_QI zYNu=W|752-ZJXwY>_2j+isvtmd~9oJFD@G;vOiDFFr#_;D>+wB)(uteb1a}cYFP7v zq8hidEiu{hd|qJR?GD$hUdZIeweBWl$ms*Y?gXJ~HZhYPr+}lGHhV#!vtrS}mcksgW^KW!X4D|}RTD=ruCMEE?Bl=)E^e`zIo@6f30a*eFw&GYsZlJVq5+}Vde*v0jV$x*E(tiY=gPjZ6_sK)A$ zJB1K7z6oSKq0Zl1%cY_WH~Sk9=cCq=w&1Hso*HfJ`i}ZI-JU@|7t)EJTV=&;LYTu&ND|Ki2k`@R~&o7m!#LYf>@5&p8%IX5p9M-kl=v7-uo?`B_o|%xV z(dDPn*caPXc zh*u&+=abnxa&IZtZ(SiPU8@B-o=~MY1#JL@=A5{Di{QM;l4OM=BY4iarwln^~jHzq`kbF-$M$Oq;2~4l+Go|{i9woTHky1k{#+M z=q>l~_oU$JT(yloN_4PyvrS*>R=TE?pDk2984#e_4jZ_|$d#qbzc)y|)p44lX-4Nt zxvMxiD3!A`85Qp*jY?DGD*f!yb9`y{ux|rrG3gGby;R;c=qHnvq5~9aHrbnSVc}|# zVHoa|LT`2((oe$5x+BE532NueraJPxGWt%rSep|Qze;v}*5U;zEtXsTvrep}FHhEQ z7`0`1dFC=>Kl@3xm3I$u?v9fp6=2!F>+3yhdMHl1LSgn}WKjh)sIzgh6ThgNaWfGw(styOKMfISubDGjz*=N^TC7 zxrW(hrtyI@zN!0D`lCcPyGY4R$ksdAzMFdggLd(yw>j@g1A)r+{@phmEcMgU0}$wu zWqR0L39rK3l4+P!sRCc~K&S=W-uURelXDhw^w^q#sb7I%5(hhF zUV*}_NNN(IYny?M6RzpoV}KsIFg$EFOpa;lU7+xVA|lO~+53kN90di3$CP{K+?X?V zm;_g)^?s9a)hX8GVN!$F;6+5#!8)?s?g67BJ9Z_aSypcuCc~?`BWk=q^RvV4x*uFq z?5mb_im+Fz-?uWleL_aqm3@*d^Ctfi3y`Gg@X-RAe4UF&O2%pw$KL6Zj@9T){YJ^? zYVOv~m!sq!VbL$Yv(@cqXDd0&);TtsvgulnN(~!r_xJnvvh7+F8LbVbn{~`dQ$|a% z>aVIPU8~d4ttv-4FOHSn)hz*>tOh!@VI5|4Z71njgO1TbzR;kw6QpZhw|x)7M-$|6 z4TMhA1j$nqsb|df(xj$4Rk2bN?5VDOs~$Z=T6Apppw-bCp{sIYveNEP>-kKELi@+Z z)h3P)dGP7}_z?4{gmcyex!21b=(h(-YYSshs@`k9ZWrL^ST;c()^um|gio|h9}C;( z-}LR1{v0;NmXK-W#8TQmC=9{k1bdhrE& zFj3NXhK2TSV(@bawc{4aHL}^k>S@Qt6DFP{Cu-|N0Bbtn`cIN0O>r|%lJs?O`3klp z33 zQI?-aopv1DyOb%>%jdy_s1iDAw7cEb;lECb4|x|~ZL7PtoOW)lJp(7(VjxSWCrw9| ztkfhvjWKe+F8$))U$-!SwYAhCdi|T9t2s?wf=7_54qkuXb=&(->O6x~^}aZIF`s1q zQZK%C&S{gyw?4vj88Nh$i=KSHZQjotTgR8m)X%!P*iX_ma%XU!n`woXpXgc}-Bk|Fn$uBMVY%*zMSZ1FL4}O19GQGO+fD5_={OaqK zj0v708DYPDi*41nsJs)rNmDj9bGP-9Aiwpt@3*RB_C{m7tkYq&bvti8H6EL~t%* zrY7d*0fYX?@LkdqR!plm(1^Y*>0R~cL#hKN_#=PSB|d-jgTnN#qQq6rzD3u;HDX53 zQO#aEEIrBe(6sLtfO3Kl2s2spW(Tpq1$gVS3aV*}AmdxmkF2ie&)Tuz`+6SLwR>KK z(~cRTUl?20vNvk!P8;n%+a4!<$MyU=^{uB9D6i3F-p>WQCIMVaYF%2)Hxl0A7<`@N zbbjp?c;ecG&(8UfoGvyPuco0TPb((&H+zw{2bvk~{Y`8dOrEtusJy9v2F{hZ*0ia2 zPB5L?o?unQfB(FhX|6rf2UJOVcjL|hmiA(63*H&YE0x}w4}(LAsa-7f51B)kteee| zdhah16q_sa+Atp8(01R~;okMFveEkN@~dPt-N#hhTTf?=d9p(Xo}H20X^Y}!iY+U; zv6u>L&A)o>=qzS{$0zAk2)xy^KYsAfKxh4Np1s)p{)a_hjxU_kKB;b*LZ45RW{)>m(=F2n4u^HJX#;5znm5gk>x~yuy*e2-z z`y_8iX3%EVH87s{j4bN>);zX+fvoSy$(t#B+^yR`WzOuKd1Y7N8f!#btgu<&+09~0 z`}{|RmwueR(O*;TUZC2ht^9EUe|D#TsVl1V6I@#y;*&zGVSWC2&AyYMt{8_JLk-dGI)r`;7W|X+Q&{;Z5 zrY>0a;ya7CIlNq>8SC{pUKvO+WDbiEzZSU+eCr55urF&OKT-gKQU)_Uw>(g$`)o*pzx7xbI zVhQa|pW}o?h3>2_wl9`}yxSil2FdE~$gFr)cxRYC{QhuC3X^&MgQwjK71O;<^MfR# zm&mQ2I>T7niJk)Bj+ZoCI%Ns$G<>ghiMVPCN&0EoIw^<$SU&!q_rI6OF*F)a(xvts zlWt0-&Mg*9<-?y`YI)^vgE)H9pup3@xhL+yNm0*9X^w7T@628{As&B zJ31X$!n^9ZlaEbLJ7{5=FE;b83)*7Ou09{~VPy5aysI48THtb}M-vK#^^9rPu}{0s zEz37NmHkfcby;$}ox#5gAnp6Pi?vzW)m9;f7l=CI=$rgS|FO0_?00m{v!Q*jM-As) zhsl6WXUbe^6Y=5OMx4(G*I6`0)0$~=&M0?k?J%3qYxTG0`AbrySAk*~!=+gXKE}?` z-~CXU7D<#OQRh}Y+jVZ;WlORFZgKkd?${!vQ>&KkVnVuhjOo{^`zRUY-Xen%jjkU1 zR!H8Eyxm*HwCEYqIi_d3-mOC3jv1l~OLYFwo^ATSLD!>WyOyoGzv0!pRg0cox`(uD z(WP^b)-h2by}ELQxMi#6?KQF@vDTcTvS zUQhC0C4DWskb<)3Wuh!HCR?HuQgXgKn|z%uQE&oOEy-9aQ6{-J&z;VnCH>JvKj)AW#S$e+ZJ10n^Ar+3eO{uh(sj5y`IaXS6J-qf F{{Zj9Z2|xQ delta 87831 zcmeFaX?zt$`?cG>!-lkqGKhePfQo_$DyT^a$tDakiOe%7Ap{7707)2vgd`}VphAnS zASeooDB=hNMdeWx=ULH5R2;#1)}ZLQR#)v9eR<#WKfm+gd^ogrR;^X@U3XPi_wK#f z^Ip@No@#nso0ey$oS1xSpT{P=dvm+?AB-8j`{fI|?%&(+(s?Ie^x&Ictl9D0;%14C zj-QqfX%bog>GD}kOKy)iPGiR@eF8igtOXti=4WSS6_T_$ImF9A4{VAi{ujJ9m{m|v zSTr@;dAf$A@b@RwcQ^R`-1?bYj(428Xt#ki!5cs|W@={Pgw~U?i$2o!cVe~-dOe9^{IR9C<$!X8hE`-tvnFX!KD zyRG9iBwmfnDQG=Dcgh%NEMu=mdgvIXbX;aZ;WWo7aq_dL7vzj9at@L}Cf{_b>D@1& z8dQO^C`0a)@sn~23yX>}^T$)aliSpBFhuDHQ2ucVsPr8{S*H%D3fJQ#YS;x*^ACk&T}}%W)@9U^{+ND{rR-QBrrF&=6)-h3 zzaV>her`c_-dHtsz&R#ecTnBS&Tc&}C%>RD&GO9FCcdCBvv7JrcEJGu`)b`vKENGn zlKPu-O|H@BISwOR+5@Z)o^igJy=ic@;w897tu0)&WHR*9!&%)rry$3+HZv}6duGdDM;(wMRqTs@gZLgqo~#!;pxm%vp)Gf+MIwS#HEixzLU_-?A1t+U}cU+JP0<5O2< z8cX%>fc-U{&nAH|V)1^QOTO@cE#TSqreRAgzarc4EVxYG!D2m&-`e!+LAiX1#o-n& zv{<`6_GjrT{f3rltX{A!EU0eA_^*k^yT2?j&h{KAi)<`34amDc zvI$ND+rb@B>%qRMrh~vR}WMh^0TwpvN+C1Yy2OM zYvT>S#Vqc9{FXJFc&no(@#TKMn)O?b#~zwX7h9|WYCyjtmF&0*|2_qr?=P=ezrBbW}8)npp1ognI30@D)8Nn#&VOh3-hOtF}?%q*wkDevT}2# z=b-<4t2DC!k)v=z{*+8C7a!fEyG^;xz>^r0(qjnJry|e4|M>bP6`O2($u@obgtoH^ z&5kC%kB#qNpWR}vW;q3!`T3be&Q3V}DZOK}Sr7`d*$}ZPTz$W>V`kQre06*}{3O!7 zM?LD^Zcw#bFE6Qd^Dl|e$d4GV&ah`e5tVs8gULF?T z5cGc7q>JyRj^ApAe<-K{iSMDZa$4u)jho^;N;$`B-i`^|?Kq3KnE}bnE1H~Hm^Gos zcGIA8DpF6^gU5i=re{yjrXeffnr>sujlLM}!Q&OY$Uw^f;+wqqo;1E$8?}RYt{atm z=3I50g8ySZpyi{c;3=Rces+HTl>FA&v+D0OJ)c<6x+rsUuEQ2R+>XAFt_C(Hy&7EG z;+Ds32S8aY<#96<*MKEz@s%x21T7nzo0FG4s)q6Pbc;>FQ%RQqHUp0*q6bpZVk-)8B~&Q}V{;Mbwz*Y4A95ls-a072RiXk$+R2vq~1c zZu(>I!Aqx3&nwDez0E_H|NP(CDfdm&|KX%pe;;|vly?`X<}Cs>h2vZGxL*~c)0)#t zXYDmJCJ)r`735AIuba(TlXKhZHZIT4tlK0d^<6VOQ^RdEs!biwy^?s%o9q5-I=K+8 zh2d1cyl#_{GxnLXGO%P*5uiYG{={4Whk7Gou|%! zXn8uQhQ&wWYdRvQ$o9xejalYU@b@b@pw2IeKOHT)#<>k3u_)Np=J&oo*+Tw~|SV=v_1 zH8(r&Yh%F|L3L;cShs}00WzrNCh1-RRlqbVP`;_( znFf4d%bERy>A+aaXwos2XXvW(2V9n$`4j7vTKob56*zv%R1D)dU4J$etpQcR z^%lozxy;O((Ek^cK978g{~TTy9Qmv9nK$8e;N9VJ{Gp^%LmvIj_`*jtKtAzk1@@Oy zv^-=?wW-2nyaiN)5)T`bP5|q{D?nA)@(+Ut;WGVRP(6Ct#*YG({}LMXE&&d z3x7A|UQ>bnm9Zxg%CH%10Nx0y!o{F0#I7bkdwlk+S#YI~U$w`;)wAviZm8c5s>g%S zHB=qIUhbv=y8kdEM9hsiTB|$UwlEH@4F}0&zOa(AxJ&d z4JXyPphha*@Az^)$);Q1#5EoPs-J89VJDweayhZeH4v2T4>mLXeHT=!oTtFyLDlHQT&nc)ajF_%8hC^4@YZE>8Gce3g5GsNl#_)9=1U- zP)5AaVk?XB{e9_KZs@r2C$|lVSN=;{m=3J-GaH@TqtV&MNI7{qs@kP7%s^@jN%2q&q>y$Dgl109QHxzDc_aU47cuHca2M^c4cCIDRkk@5i$(nwn94 z`U2CC_`~1$R(J~yQ$;-dJ*9q+|J}?Po1GhWIzP#jG9FYebz=-uE-Be??zY0G-`o9+ z#!X6Yu4XQWpORNAP;tv>9 zLAt5XY$@0bY{t&uH1Mkgvt^n-UHcKb2v^TP?P(gyt|fe=`YQZH zQj|VMKrNmK%Eb4A^0Qk(`Q-|WZF`#qW~%l}91GD^aQst^Vz}ns=u3^e6<9ve&uCJ= zWKDFPPMI7&eCurzlr|V-8hFegzirbq zOHLra9H{vavrwJ_D*N|1r0%lb1vTzhgBs__RzG8y8LobC4bS&*rTZ9^HP;L`{b+CV zpJMaH+k2Sp7yV)fO9N!y>qeRa;=^$TTzFI9%g@DX6tM71VJ4d6{WQR_5gF z+??6jts(tD$d!wd9z42q;52sKxzGP?nBgXyf;rH=~CQ z1=WCYS#D?{HY1^BZW(JFx^cE?SZz@0J_lvtw?K{D9#Hi?1|Fjw>~Cb$P+kYB0q266 zVm+v!F_<+aR}Vs+X%kF=J3$o?zwFGd=-N5jo z4644YDN`opWIIkI&n*c}GdW+M1vySPHsz|QEvT_?nr|9(GF;C0DqICLE-<IMx z;7WftsQ4PBS5JSMYVZddtV#D7sQBr5V{@`_h6U6g_F#5=OzjxQZz7ls;gGbPX`Hhz zs6{IRYAk=6VTR(0S;iut!`0KcMKNM)-Ij302^+|THMHo7mS57Hn&lji(urgYV`BLxnNlEteh#7=WL#1dUOjYUufVrJEMNd@VUlw;vZ9WfvdSgN=#{MK-ndH zKyx9VFcz>nP+F}r*J+CWd#SPGCQzPu-aNDTECAJ-gXkKc_&xnzc<9n#c$N9%N+Xop z0@i?P_G?#}f|kQoP<)#@biP?_z5tc(Jy6}5s)wK)^KJUspgb}D!G8Sn{Hf^j!116* z$)(AQjBr`0->G?e$$1z+=AD?W$G492;}TQ3X4S=;NOg)LCPC z8U>Z#U27WF(WYAi*N|&-TcVz=Ku`gzZ!s2F0jl7|7RP4uP>MceO_7H%4VjDbg%j7A z<+mX|B)%Um6KCIMhN=&!$(3U972?(K`)@b#_*}Qb);u5|y52P4-=>Q{kc;1=oK8jR z(a#%9kKzw5KilwNrxq7Cd2oBT-x40&-s_2K?h?PKZ_F+C%lX^huL#2_{bFuCzo=i# z`+*0e?I@>C;P!Nr{R*TdiH_4AshVFlC@Jz(qCdNTx?9UH?;mpq`4#-V+D{n}i?*hp z1N^iBsqS5V`G8pD^JDx&1Jd2*e#*dDbP`7F;1>@{RmB5iZq%>f?}dKKpqM+wFB%l{ z9%1~_D=So zS1l4z+}&en9H-k;W2L@&Y>1W z0yjp>VJex{4NvmkhIN6}@OSk~@*3fmN*RuZJHW3P5%bofnZ8kCSmDCt4EqcU>0qO9v-MJ(i*_e(~T`uQ#EK!m>!{S6m*8K7!KLKYV$r_cft& zh@%^{r-ffW8b@mouRCK{lJ`<2b4Mn5joBNh3Dh$n$r}L+&E>nJlU(1g$c%Z3r{gkq#5|lJeVq}5svbsFl*vbNzw0M>Hf~)sa_lQVQN@4`Hq(d>i~~{ zksXWt(b#W4E~2<)cN0u@aC~=6 zlJ@~jbN2-G(kpAqt0rMeO`+FeJwqlJZ`>^ItSTi7mO)${-^Fs9VQL_j%S}#%sE72I zgr}co8Wei2mt|QsKVy87w;MK?l*Z#5oo z>DhQ$SC~>od=38RW;i!nW>$v-Ftw4{Mcir4joXLTcKiDkxiN16S{G6{q4Vs6 zse|;1^bOC9JAe!`$TC_=8`i+oC)4g9Vd_OVHN19bnI0ynOm~`Jkr(qGM6;$FkQDtE z*4{tdFE!e-h2vyuX^cKZC_7vv8~Q0zV^Q~P#~BsIY$SAf7*oTqm>Tm&wld{23=H2Y znEL4YOpVAJt^6I+(%s|yifJ+La;A}O)`!W75KR+Wj0^08$vwzL-|DrljHATKFq3W9 zlgWvYa6ScY7RwJz=5hnK3#^SXs4>DYn1;ppolS)2!H>@*xPWE?=PVy>XDRJh`@r!1}yf<0O`k*l?~9%lH5F!g}dX?&7f z$FGcLn0ObEx!aC=N~RkbuaMCOJnX* zzoIl2d7-o4zAW9X<`=##sp=BNzor*EKg;r(ervZ&S*bvZff)yLPNtwH=(HEVW^1E z*f93AUNT17kW_CZAv5GmKX-+nvM}bIj(G-#b!mYqg_#b}n&@^|Xa8_fYUKAz{Pv5| z-ClmtqF8iAZ^yaJ-$}o|BXqGU@h-ZwaseNi6rBT`73!xlN8~$EKZDWy95w^SRHU*| zT;(SkhSSvR$LE!XU6z~(nH!ICkM%2-#JnE;jUCt*%t>;u@QbdFc{|XuNOw%Qpfny3 zAE>fQwH_uLGXm~Hzv7x0Wu{yki(WI_apw6um!`5ll*2zCq4XN3 zsUtNy3hf~@HZ0?uQI0dmKYUGU^mRfr{j_USqdhNEU2?sr2+i_$uIo_kaQvT-Opi@8U2vCd4ADNG4H+U7y!*&6g%N{(nEC33i&)fM3A@4veGEbjwiFETZ- z4Am=&57pI#=K5(jbf`8vZowi##wMQ9%T!(3 zj~%KJ$PeAN&OFyjvz)oT1PY_xWhWamz_xcG!Ys1&i5)LJZeoa@8TqlD-s zi_oQh`CT!0t^P)ST;aFhlpcM^mj`L0pL)GULaX}ighq#2!peB;AVL>Qb65N2cgMW% z;OX*4ziecZ+s041C&u2Q=$=^Q?Hl|Z_oOrbD(;DS(}T+EIoHYuVO>He)hg`V7{4fJ zTYk|$ST0P(n?3ZVf3O3v zeu#x(&RiS61hWnE=EF?w+8sRtQ!iPBu1)g3gqcM}DVyA4;<#7ij$|T?tGBhl z1F-av$?o65WKEW>8A)D?TjSd)c5%^>FgB_EQoW^w%yPyBJhJCjf5+Bv*S$3s?TCja z`-ihry;+11|ODqHg3VckNjce>N`7N6qY;U>#yNLEth%{%?skEVMKH&(hGM(hXEP;mP@ zFUc+QQ+CFppQ3g4({`ptTinGt4s{5jJEPp*9pBPM_#P*tubf{}AdG zrl`3kZVQ*KR#%uBN7uL!mT)~!-~zSVv)V~`|WqrnFow_<8~!U(E%_<5wou%6m}-^{R4jcr_r+2hGXzc5z zWiU*=N(={Q6)Y8I;@*U%giO=2(N^=ic;oP{D#tH+HpYXG@@Hd_Pq+Gqo=uN7+Q!`U z(}tyb!w8*6#_;Kg=fgDr*b(&SNdb&0*FV*(x7}22*2!To8I2WTYm&DKX6Ed!?Bqm9 zTcWr#VpJNGSKghldb59dA?9sDlN&M4%%4wS8V#lZ{(bTeb60BmH1Qv7Gfc~gd5G{O zO#Q7B-b9`8NIaiFUmT-0SK7b_~ zhNGRf)8wPKb7QGVl4xkwe;6&aTk5yWS++!^>9el(xW5?fN>6B&S zx<4LwVVNR;sS_sdRhUwmHk|N8ynQ^WiFSjTb!Hu*Oj3pBi$->7TdrN^a6*H_(0zpZ zhoR&D6Z$VtNUA>>PD>sUOeZultVL_|t1$J7I*V94p0cT;CGn8=1|hYPYg|^6d%R!q zX3V>Cw^>2Lc1NFr#lq`e!qdi;Njomd>jcxVd*QRDS(b5+$ue;-tebzB+vcC2_IJFU z?soAj-i~=!JQH_R?vA2&!@_6Z(LduMuiqZi951|8y&9%L|Ds@n^0GDTEO{7Mdiwg;2VGcvWijYeKz(;!<+HSh<6z-c>N}g=eIC zdkOWWMB@%EUW&I)t}+~!T3OplSY_RjcVF^nzn|`%{jzy7Z=Nd7f?YxeHdQmY%DwEj z{~+CK@QSgXd9v9b){`V;xFR_b(j5|dZRC?z{PrKFd(B@pE=dX=$7T8DAI2I!jy6aI zb2QK&d)(pI-hY;N;%jEm6GJ=ngq^3pxwHN9{V}#A75u%`Px&Yo{quDis0&H7=NpWa zzcVYV>ig3-J2vdqbn0M)aO>ddPOwiSS(ZQJaE?O7TnNJ_idCxFx z#iQ9`*m=a64_(+Kei8Hbp~()%hbwxUeeqgcK1!M7r+gXHBKT#@OMc%hp~ge6gQ*r4 z)Ga(decx~YReH4IgYb##SEoEhx3TC$pYTl0Ps5DA z5YmboJ|^`#erjBkRh>0^2F%2{Zzm^0G!w8l7rQ@UswCV{dC8x}2UCyCi(s9JJ2u?n zJ_@@KR?E-mmlXN_Gyl-{>E4B(TlWjfChK#xAHvTCe~5X}17=E+_nD;Vei+YDxWPMU zx3rO`4*ENOOpmtsf?LjD*Q$he{?xvS(FM@%;Vo3lFXOj@cM_W87Y7{@zhZAi3u=eX zl?&52*7RK-KSR{RWBjsLlDzL>T}@NDXkYZT@np6j?CEF2LU#*xEoS<_jAgX&ob-)Z zRdCVK$%znI#$4Lg!sJP;pKNCT{KlXCYkD;Ht!9gs*AhZn|Czqn`(aooSa|h~{Q9jw z`?qvHsx1F4=9PYDmLBsk_M`9o_7&;gO+R22(lgh{T>%?p*xn>>>W`)w4A*b$O<=kR zFx!}wHT|MPd^Yiuxz3tv{o61**7T^}&!*YrX2aDVX4<8pzXPTY8gKisl4ZNK?*`z^|1xbcnoHz0S`_S|FY@5PK46q<#?qq+oc&v(HCHY zgS2BPi$_VO6Iy8J!Y&T;$cvtW*^=2`9q+pF^4Q8<0vj5pBwutrtiQkWZDubaQvzm) zc8IuKBxJfmLY1xb9)n#(Zkz`{`3Yvs%4244Sb|9z2{OjJ$<<(7;K#G3RCDbmoqdYi zBPfr$G4C404wapJ4rU6{7@Qh)Lo-ncY#c0{E};Y60aG*0M-X4ZtUF=Q_Pq6OQgRWF z&W3gH)5<$kBf!(j(H#ML6>qH@qZqePD1#!ORpWqfG%!<_+(| zy%%9^<1F&mF~N>wT^77!O`l1_a4vwU7v|dY0?Z6g*_PzQLa<)|Y%{=aW{~)DZ3ryqPeSY2voPjDa;#eurty%x!-T@4^j-nN|Ktn91i- z!|yQb?Q|@IZym_U<|E@PU>ZIhRlv#*&8Qw_$RJ76-oahX41wiLYof(G#($r*BCT22@o?0FED z1mn~GtCQTOK}ti0YCywycAg4&2VlKP!ajoRYfd(X#NFBJ9fYYcHq2C%*2pvo^UO}J z2H^vNVX2X~8wH0>X5O57iWyfXHuG)*%(P#{u7~~I{sWdVlB_BjjpL5D3->L7S*w4X zoCwiiVG`>98Ybs3_x+ciYUTjd(b1b>S_1H1F5d5*8tiCHlj=9AoXQkE3}yyRbMg_` zU~-uGRlBKi1g?}ceh5rM!QQz%$y*6iD~yF+gc;Y);N_RUng%Ds8IgqxeW{_i8wydO}_GUQ&Jli-u zXmffzm25E%rWP`j>Dd;Tbu!p~m|b{ZOinzb%8ZKUz<4~uc4i$R83XU8(tR+q_n}hv zgPJSHjn3GAHk>1>;`y-kEL2hLhRMPn6%S8_$t#R0ieO=*0yhnV!ZepmT*Grs z6KTeXh471x7T9|ac z$;b4e$0ab?)cD;_SPaI9upXY&){Hr~L%4BYm>O&*{|z>dQtnQQehups96s4i_0DZ) zGI908x!$N`a_i$SFpgIv$T**O=E7I&q6-i^hA&;cK}ddN_6-d#G%cfcd}Xj@W}L3K zjFp;6`5Np3KW%7-#EZ;O7)NXmlf7{^UbM=Enbk_ebT3Sove3;Ve_j;KzJT>9B`NL< zx>lFM)SR#q?nAcqdFtvQ3#DAAcE#m+|b2 zn!BFhiF8L}0Mo=`m<$ISm7EAMyGE`Ao|h4Cy_|0>%&fw4;k7VTM_-t3Kfz>E3fY?E zwe3{7m8D^eU>ZwfpD$sfD_O73m75e&u7=r-2<&rM|H_mpUE>n93e)fEf$Qy1&EBB7nz7&*_Oh{WKnf{Xs~n zc)(8IM)opZX|`k6!89+b1!awBF-$h$Dvpn~xy1CFDUTmcfMpPeH)E5#U>b6!C+usO zo(8bZ*_@o%+e~@}i-|W2rmIc3O-R_-+x1iLO;-|)wRz-!#-%1h__?Py8D{3KE(Ti^ z7w*TuB&1O=OLg-;W~Jql#-(A>KiKUswaujb4W^L|8{qa1in=ihbNiaf7;ZPB_rQAk zJAX{|j_qfR!xDl)V=&W9^`sakX9_p((F3rH!w(5M^{?W92`l=${uLwByq8erh!}|V z^5g-kK_8xsB{bYLjxryE>3Pcup&4rrG=_)AhOwE%yQJ#q3l?pGHkgiJjA3M*r zFgq8SVL!ptDITyfW79Gz&)+#T)hi>Um4h3a-8_iN3}z3(V)e$Drf^%uGx)qQ!6DSh z(_@16Ly5gP%X9*V(+)f<*nt}9F*Z0Pe0Xfoei*6F%Ql^(%{cg6m^#k&c?3p*X)Q3D zwO-@m^G43I5~jZ5AbH7&5VMiTcOv!12Zx3;2BXGnM)1*J=9J<4N5;URSzz_@%@mV5*EW$Hzi`1=V8W{y7-@vVV^AF93DHDj53bkb z$%C0onXWC*!^{$@);F6}bqkaOQ_W`g|C(jtCrMtNTsQnVFLpEBW)6bMB4*NUfSK$3 zK0;a;%$-o9$);wk*pO~!Lc=){xM#RYkxi3>*`qPWu)O$0)knH3VU_KRehKRv6pwaO zqcf(2E5)c(?+HTIKx`45sg)Oa7Q9rL;>_mc3YdJ`?31^^v=}qb+20SFX5zT4VwPnv ztx5^OuB8k(EOfKL?FP#?oyG5YB6$_8ceujrBV^j4JMZ%gjLYIA&m~1>7X&-TGWIW^ z4)BX#N%fi(##6IuMK6bSRw>cj;vw%-LS};?7i>M-n1xEpzX z0n??Yre9W&oH)ZS%0b2qH`$#L%pQ+_-#R1M0eT&0#_gKHngOJiC#v5H&;>l5w?-zTI!VY~3s zP&n5-Pc{3;fVs#!lwL$1Ir2J27;b`(Sbs-qmL={tA;BYJ_WEt5P?76Xe9O zhV#l?X997?)oz68a%pP#0%mR|G#}f~Gjjna;?lMPW~`Ahg&83K47=i;dS&H;N2ZA| zUC2#0AA)rc@5gFh<%XYPnU3{@sUo|*fpvn>T)h81nAWZEBRQ|Zd{Zsuajnd>470Q9 zuY<{Sn4R73uP~Kjb~GsqjPcFfD~9QQl4a~U-jRo?E2jNl!sNvaEZ3Em3r#z@g`hX% zVA>a%cHUs)%-!6dFb#m&z;s#^UpRD4p9@o5crPE_4hugK^$rk{Cx+V`ujyhly!2*P zQl$Ulp#4nTW}#Kh^R;rA$)O&9UztO@gVUFowSYb{N4LYYu{7?{^J>#a#&PRSuMzDf@3ZKMIVCk;T>-SAA2op zQc$c<%L!?GO!{>&t$3!a&tP)cFfQ8qI{YErK@yhEHjXWi@9nhL+HV=- z&EBZ<3bS6BC(u{Jv~aTx#xlRajFamU#1Geoqi=SPi!3wN-UBn*FoXz%O$w zs}{H;Sb6S+Uif!IVR}Ajntk5Nsu>r-%sq?>eG8_Kb4|*+H&pHJy|AIgam}N`>VfG5 zTUl0&k+4g{``1l`LR z^t{P9Efa{AEr7|{!$scP3j2E?eubrkaax4WTlIHbaw5cDDOh^Gg&7}V(TKKP%{&ON zPq~Et?)Jm5zdhqSSY=hwPB(|wRz9*>N~m(l^qz+4DM)Cz$Qf&b*$bF0)7Dfq{9~|6 z4~?F%mad1j4eOO0$zSa%Kjo#K&?@B_NzsyWNXnqc+ z`NosIkx7xJcLqDIaod;htWVGT!b4btlU2xxaxzLz0w*TcFQ@8lc*o_;vp5CRA&hWN z6XB?e)!{QakL8@lsiO*>7G}H(Q3WheEXO}E=)KLY&&84-dgK%?v3ND8qbhpv>qGUQ zsC+A}ek4>sZ{$?En`}Cv_^R+%E=(YdLU5d*=5=oUhHCa2PNiGRsYB=nt+%^PN<`P` z4~J0A+a$tqBvf(taH_b?oH~T!_i`%!KFja7_yDLwsBS!LaeMgVjt~N20p*~Msu&5r z-tN}#q4FOMBMoZ!cX6t|C#^12x~DAew)ixtBgA0xa<@sQvOUMCX!@D%intp_Zf0R_|i<{|TzW-EI2rT0B%xA6rmg8&MS{^|QKA1q=dPfu*2a z;7afWkgZC190?W01|>Y=SfYRmVCxVbM?y7_D`R*FmHt*xmg4dgHi#8GJcNqB%W|QD zn=BV9csGCONQtwBfC{=_>c3D0J!JK&sPtRW0{5vf^ZuO@?{&#lkk40JTS-8r5 zA=DXv6ZoH@Dt?KKD(E#(vuAHukU_=2Yk5_a^k1u2MK?&h!7dgb60PhXf$G=imLCKY z;on>Sqs5;={&#-ikD7A`RKE^`D(5dyA{-E-6rAO7zLG?vcZ91IjHXKP%`jQ{-~Az0oAMB690ut|1`QAG``WT zf4-7E2UTq^S$xfA6Ds~qi+jOHP)s(n@{1Dvv5o!=ROz2vJfKJpp@LuVN7Z}-s#yJQ zm+&W0gIHnt9~S=t`QLF#q;%EzqjX*ZGfKj7{857ALGjv_*R}j4%NtnU$l|G1Z)&-I z=u71^x4ebLR#tCq`FWt0iKK*frYEU3L7Gj_(eh59TH4L(J*5Y0cDZMT`=~)y9tz4J zBNYu^W^uHQ&jMx8v7ip&iQp_y!#vmGRiN@Ou($|Rxl2L*cdpeRgXU5oK?SS?l`*gh zs-mP-{80l|Tf7-m`n8I*sQ6o~zRv1LLPf1lU^!QY4K|@r{0__ifx*|SST+=W7tyNs zZkwzss-s(MG56W{s;K<;+xQ1S^?SQbR~1$M4yy~5?~w%koQ?@-FR|M0C7vQ)j_|xq zFVr4kFR1e02bKQ=8!uG(`z;qL{v*q)qV$igegrHDNA`0PsKA3Zp->sWuw1Bk{qmq1 z`lF5i$?Cs=I;x`5|AwwB?&(-n`OcPgEhPR-IeB-Px)b4kh zJP(7Jz@hYp&2XzQl-~!8qti@|tRMoyER<4RlezncE)Z#Lm z?ntQWed5)>8*IA&0UFm@MFurQKLe^ms0OUDT&Vb4tbVK2tD@p>v$|0EZ@0MK>i;X^ zT5^%QY{E@8;gPU5=^i0oNglW9pRnnLihmW9CEm8WQ02d8c~w*c_Z?>=_JK_HTip7= zqqn$;`co@(yN_)Gp=|q^(oeAZ-x%Ds$E_1Qwa0Cs9};((l0X%m zZWC5TNiD1{R71|OT&RY$v0SL~(k!ovD!(JT8kAwU6;*B@s|(%W@H!@;21NhboT7(-%0ApC6V`#}+W5&9^FZBG&IEP*zd&<=RsmXt z=Gg*;S_T(eE>y#of@PN;GM%Y&$?KNM8(jYQ}YcpIpJyaUt# zZnPPyq8hjbT?Ia1(>(;LoQExL1y#-tQ0aDB{V`DGK2btI#}idh1?+;Wf<0ERii&^M z>O%47Ko$6c)rGy``llhJHv)AbI$h&!Q4K0N6G3@efhy=6n?NYu+QzrFdR0_>JF5#- zPBJJdoj;0?S?ma^!p@d=0Xa$>1r+XSu`j5M{Xk_H2(|&|fimR+P!(MbD&10x%Pd|4 zs>jz^z8uscR50L=^4|<5p43RDDkfgEbrMmGCL3s(S`h^5;QS^P<&XvHBa9zYVIGy_Wyi;`_EqYA5m8Zl3${tH#Wap>A~H2^hvPqXQS%741$LRt1K%Z18+b{7Il*vdv62~|N7 z@hTwIrte_W3*Dgi%XTC?TKPz*YBFrRP`2r&>|l3`JwO?*m*tm$I)rL(AIqzv^!_#Y zWLO0aunB}JXb>oUu+^(#BuLvxyA?f*XmwBjtdIC*Hn~v6jJ7z&#%I}hq0)~9bz3ma z>O$o!u)HcNeIdGVdJQMI{S~*i%VXA!+;S*+sf{bMd4=+U1y)~ZagmL$iYjw4y6V2# zrdw*$9SN208XFG=SKQ@#p+T-ilwnuc$f_uPCAuoR!Nwm6mF^~+ZWSm4ueIs_4``-@ z63Fp3*#hpicn>JgdBE}qEj|RQH(Nm+RZ$JyW_6+XcAI{O)&EBB_?6%hoA6PKJ8eRt z8t|m$Lhkrqv!1jEs_f572A{Xdgv$0RD8sw~D&3nlUMPL9j+JJJ5wxAB7%DE6!{`OWEDqVUaKSQnxV+fjZmw?L92jr2}J&Xe( zXO#X}R5!EW!W{5;aHfqHD*J4U#h~h)XZd_k{aFa=5UTn`pxS?}jb9FGW4J1jYl;e7 zgPdjGJ%xgC7a+#sHnGW zL2p~!YttVI)sc^Ed{tCEpV<7L+W1d3V)b9G zE|h-A@~WtM|FF7H<;(mk*VQmsRJsI@5s}LtPlSY87VFrALJeg@Pz9W9v5}1zDqmwz z6*U9ZkuyQL(gmPgx+kdoy+Eb!4Jv&<&tB#G*@yw4dN$bNFi^*lQ0YbzuYyN`D)@4X znN}YIDqS|HL#TA)L9L+$`X}sk6o9&6zRD(80IKK9Kur$c@>QTJTn(xRw}3kSPpI^_ z+H^wYTMufKYTiRYExK12G~UZ10&^aQ#!(&EZjZpoJ|FqSG z%J&?o`d_np6)XuO-n9|`6I4MT+4NOW6@P4Xq4+1D`umyHg>soMZTweq2_^W(3g3d_ z--9}igev$4oBl_e{%4zBs1f|##{Xea|BAZw1ZJ=-TwOC+SYibal&NZhs^EC5*9LV6 z)v&sj3&rb!N`I2oh2r%sHUL#&BO6~8rI(yagepD_l#{lx8O{e)K|7GfI~}YZ19b>h zQAe;5IKt{e=_4(UvUr(|{}+}x5|rU`P%Ro`6IMkvWUNh>4XVL8Hl0xMlPo_Hs{C9V zFI4(GkY9o4Weyu5RKW$73)P?*mJ3zTOv|gH^jTJ~igMOcbUEF8P!%r(m41;>^KUVM z#^4<`!A4MrP@g_L3hEO3tc`yjR6}33_&TUVsDj_HT&QO~A6qU|Lk?K{8Vu*Z0*d$n z)KL{>fuGUU@?SyuNCL~aDyjx5p9d=4aiAJj3)CT$*PjG71kVMPt}Up1N%~h!CA3FS zfvKPlp(;$XT&Q#%t=`G%RZ*tyX?3A41*0t&Du0&cLN#>!v3CCFAjr$}K{cenCKT3# zF9Ow|B^H;0O1BKuA#4C{09Ei^Ru^grcUoQ*Wr6>kL4*o=(k2k9fM+ZhCIb>2>gbzO;f}KE8&ld#h-;^Lgg2%XE&b@5Q=uiCqi;?b zI~;v;>gbzO|9FE+PauxIId$~Ssc?Cy`UaIAjU9b+>gbzON8g+}`sS3`JDko_Z9S+t z`sS1#?{f?WkG?q-KIA_7=9C=b=$li_2;Gq$>5VBFNczz?r;ffk^^Z5G^dZ^NH>ddM z`{b1!0ebPbGXEoZlW{ zRx-lM_6Xkw`z5qULFk%_@O`j66=AQ0pC$YlWOP7S)E;3&2ZW!4?RBz8n--U%TZOzVWOUBa6ZY6Q(XBTUFZnBN(} z3tpAbpcBG{T@a29%DN!zk?^U6n!)*95oUEpSlJcfgkZmf7F`g!UW`yXSbj0WUI{-- zs2gN-Ls--mVM8~BdcpS+k}pOW)E%LIu&z780SVC_2n~aNJrHi}hVZb2M*MynLig?n z**y^&2lq?(O+vk12u*^_UI-g|AncaVEU0}6!qA=w(=S0dJ=i57u@^$~-U!WuX}uA) zOL$YlSwXW)5hh%MF#l47mcgqM8uUiEun$73psWwV9todHXdRs27h%?=2rK&{oEz+y z(4r4Q*M11+2g~~*?3M7dgmytje}qMS5jONkxG?x$LUKQZK?4wyf^`EB4oHX&L`Vtx z4Me!HKf=QjQUiAoLiYg(*@F<$g8L=>CZXP7gjkR{7-8c;gxwM{g4#n6h7LlQJ_Mn2 zuuDSXV1(vF5xNG`h9Yd2@TP=rL9<~96NVtnABNB)cvV7!p$HcaN9Yxl4M*4`;Zq5{ zgY!oq%o>KUas)!3V84VG!x6fUMCcbRABnJ6!p{;01R0|c7L7pIFbZK%@V$iOkqCn> zLl_dQyA0uggy`i6!-9U7BiuL&;b93Q0(Ue*_sbBnMmj{`d2pca) z*exM5s67T@=xBuLV-T`}T@n&A5t?TqWCzb?A#9h>dMv{DplB?@gfR&FB;*7wvk@9( zAuP*Am=wGtVUL8gaR`%x#p4iWjYarc!jvFoJVJ|Xgf-(4rUeHj?3K`a0zyG>(*%S? z;}8x@m>%@VK}a5tusH`|W>6vFfP_&K5sHGlCL-K80iot3ge!t!lMuS+AncS-9C*11 zze$*!i%=4jOV~IOq48vdvLI(N!q7F1(t*0O?42q^8 zOqh(YPr~A$dLgD`70!q*bE z1S!P`Ev`UVQ;cwba8SZt3BBhcJQ&Vip=Ag! zN_aA8cojn8JcQz_5OxR8O4u%;^?Zb9f};5d6Rt$qC*j$k$^j?hcdT`TXghdMx4oi45=&=ML zc@e_qB?xZ^6%r0e7n>l3!QwSs;t6V8e@=MDYig4$aXrffU!{)7fD|D&rl5M?jPH0r)q%gC?Z+>#8GO=Jv z-i6>>9ktXj!~*lCbj@w&-;q$? z^{(#|{t!f|8}z#~p{~ift?b=|tZHFBn~j*KAGr z#=T@)@wSB1-I^7fjJ}oEx{p&gLOXed+4%+8`TXu+FsdB;zI;EO+}7{rgkM8*dF#o= z9bD;6+m=0&Fy4)f-ns3uRS9j4-OqW9enkF5dE3giB{Xrp?7SH{dE=%yDcdq1PZ*!z z<-Hz$qoH)(wpag?&^Z#F%CAz^R98BO1=Otff$8&)AMp(bwW(Fu!)-S|op78RnfbZu zI>wCK_B{#J+?sp%{Yb{S^i83R_hU4`58eySdfaZB6IKyqmM1g{o_ZzWyy%xFxTZtB z5|qe${QL0xETxYJ{oY6z(d?YYL{s2}Am4qk4$!(Nb8@aTdM96@k}X~~-M#fK%3sef zNgn&RxUF<=!XK_XVO#OL2?^ERsX^I?38`-XZ96|qxWbKg;GuhVk=Kj2wfQDtMkF}#i-f&l$0VQhdNF0$7M{h=T=R{P z($uTBt^GbBQoUi-$f4^^!Yr_kjQYF3XJ89c>CwMOEpXHV|9`eXz~VFK*aM&Hb8yF* zTERcOR93xiu=%TMXP5l>mpK%ppLo-AJAK7iN1W>l*;E3@B{q#7Wt<)=d{G)rX;gk& ztM#$z^hOT9$PgZVt){Q`@y`wDC<%W@PGNmKeI}P39sO;A`f6Sas|~c7^=-Setu_cv z4G}%ZYC~;0J$BKrL+Kc1HGR|VIu*cSey5JF@#!0qwQWMZajBrb7Jib|M%&E#Mr0$a zWumFaY&4w4R?D*KWW7_ZHr8tTDXREaedE7lR~PNq_&2-9*#h;Qzxda{C!nc!`W|5` z+v-WSKz-_RuGMm_re7yuzY-pkt)}l54&qcfdA2-#qjDstj*|GV=A8_=ER_EK1wDN| zcZ}8aBYG<26wZ@u#WQRr`VQ(rjTJ}y$MsGn{I1pXLwmAT6VA<6n{D!zgpPHu6|b-b zHY4E{tIe_6X=smFt=MX(qa}0d(69K(kIvxar|H8(zgwVSb54EdR7a`R&LsSqzQ(De z%!+3bzTP_0Jgc=pTWPf`t=1APuv+|Q1J6dg(Q5IZ4s3Q zQqcYzW&Z2936cNxZxT5BY(o8dp<2y9tl)fVwY663fcA~mZn0V#+7DK{)oSTzzguk` zni>=1{L5;$>qjyrcI1p|S>o7WGiMM^wAvkL^8QYoHLVu^^~26+b*!deKvbi#7pwpEthm{V-O%b=?OrrBusi4Fv|5YMeOBv1xUKEU12%6@vXDW%_geDS_ij{aT_j58(V+3dbIsa3JA=P~i*gR?|ur|2dTB ztTq_!4ZAKpZ?z$4w^;23G+A&c=dD(I$)+17|I<%~pF!lyh-&q4&c6ujc+DmpL3p;E zVy|0GOXvbLtr>4vZ4}||XlH|OT1~5JGc?Wnx2$$K;Z`b7p@!tozg`pRn4(Bi*V^|jUV(Qc)@ z6xsh9E6Uk!x0QTrwL-M@R{PFs)6q6q?R%@uK)cgwKUi%hn!YxwMeRqc%_7`Yz2x`_ zEkWa7#2MJkzuJVe(dKb#Rr?K1R=9$b9~=vhLpI$U*m$&XrL$Tw+9aFq539{Z8-W%B z4_i%jm!#N)e_F8=u_0Ops9B(~E8{%HY7yqE8l%RYfYt@nkD5xmlJhsaa8*ZBN3Y_1 zkwUtGdSzeQe9pI3u*N?TQQ-xgn+WUBub?X7Le3Eia2#i~MTDnYE&l7Mi_yB-yvKuT z%o5I*S>bflvU#s2JkC@cZu!EW@mPvD#fo)o!ewatIko!Lwc0g=HKtnqPPCO=OIX7v zP5VW)>pD)&eI50!ww&-2Xj&y3psBhQoO?>FsEwsE`j@ugd#uf-f-5ozvtah5!ZbYkT>nPFh!K%QUIFGmD8CF|`R>x|(fGFK+ z&QolGXIkxMv|l*2jGu)j^RMB2iBm^Qn{F-PS2(q_pN&Q_CC)97I(A)dV>921c9PZ3 zvzgbSHL%+GR=W-DWUJ{)s0QB7d5YEAS#3SqsaCtdY8%jM=(o0XVbCR0neWg^U>JCj z)$SyGr`3|Iwh=AaF4f6ay9;eUXC`Ng)ix16$m*B{wzt~dgjI)D$yEJ_D&g>7vQZ@x zJ6LTq;rlpsq*?7=!rhs6I?}DSg>W}CmQyE&CSOoK{ls1#*vY25pYUgBQ^C$wD|rC& zIHHzB{Y0-C^C0IFXga#0X*?g|++{UQHKlu)Q$Mq(RkFL)wi4DGrCKF>SZ$l)$)MG* zr`5I-o>_zO*Q%x;|COJWbLtl8G1_O+QGA>16T4D4sMM+wJ&r?bD+ zcB1hkq2V#WYLCG_m5De8>PK|dlgByrlkoGwK{nwNg!frZHP& zE;Pezx+l@DBd^vL{S>j%J;k{KO~**9?N(1e=G207na%t(;dPukwC7XB&v43%wFr&2 z+8)B%V(ZAX+Ovd}P7BT$t35|JokFyZWLfQb!rJPUXdxME#TS%-0<}P7TkS={ztU>0 z596$+c|D$VS|7$+?PbEMSZl!qt7)!(&8Z^?O;&i7^BYdB50kY2SMOf4rxu7@oB4IZ zI;F*bz4;Bod##pd)4d7*kyBH5iq+mCEURitPPN+Gg!gl9;+$r+z4A0=)|||@;yZ-( zJEr%71y*~Pu;#3$TA|hcOITA@+H|YEM_9icsbdD3d~Y9TF`7Jn4jP7Y-sk+kYWoZD zs*dlE7tT4b4-NsMoB+YCga`@2rMN?JcXx_Q0>xbltGH93#agsDEv2}%P#g-SxU{sC zV((||y-xx(>HYoR=iWSgnSEx~*qWI&Yu3!3t(S#v)Ao6t@q8O-b4{@Q^tTpBn`)x%cZX-qTvd{nJ~v^-)W#pVrXY=mp#A_Y|m6sWvQsb8SDJ5jDPY za-Qw?jAuZYcBoJ z(kO?_br?}Gdgszh(33bSCk z=Z~8a=q-a&z*L}CG`(6bJ>jY#p%BHG8jxx{s^J8JOh6SIRa#U@$qMv-x^HmR8uk}> z2L1-mfnJJtm@vKGP_H`t81x4Nz#uRf3;}8&YYXy#d>}t4kRk^);GrN00csr!1>vAO z+^7gD$rGpHpSc!~wLu+F7kmWjfd-(V3_AzND&VFujYi z6u%8z7f1$@gA^bo(911f0X2`^1!@wz2(EyuKyMXY1y+MK;7fpsEXGSsVrl~005*cJ z!6vX7Yyn%rHt-Elv)C?Bgn~qaqCh_*bquH}Os{C!1NMS_U_aOjwgEmvX?}%k7OsA! z%e+=T(8<98l7OT@?N2U{45-~H1xN|h z-jo)k2Wn?h8Bp1Q(2^PX1;{E4F4FN)O8XM2a%uzP=!4h=;}aM1N*7! zw?Jj8%FCp%;UK^D-p*ZMH`oHc0$&5Y4|FAH02+dQ)I!Cl-jrGk^x(ICDh?$enfYa! zoJr-l%kV3@6H(?3VMX{}8B_sPfiB=uf!4^pwxAtQd)Y>y=BrJTIho;(c}==+fXZJd zNCI3y#cp5F4`d?$fn+lX3;{#IJ(9Z*UV(oYAbN%EL+}VZ22a2~vfmHB2YNN`4RDb3 z^vhh|g72J+#?b`o6sl9E&X8(^ItA45^b^o2Tc_wf;3&Tjg1ta53*H0tGU0_ljZ$ia zS^}1WznGZxOLJcX{qmfC9qxN@5c~kX18+a`tyOBA`URrV zWEMe2Pyti~ zYNV3`zmDrl?&>?MQloX%NT^=FwN? zg9TtAC`U7V2-Fr;5$Gl5>w(&#usivAP36I#8V7(t;08f*C8B#71k}E*_UxPBS1_A!wF0ezF|}}OgK{uTS896oyIOwwgLa@j zPzz5tu6%Es(nufEmLDxaBcLyM76EG6DF!lwtU#6Mdbs*2v4Xhz@q=eTEjG`=Kfn!w zKxPmOvVrX2G;z*=AHh%HEKm#1F4A0MVD9{ahcCfe(1_YK22FrkZ<>J?pfzYCnNu15 ztvmDB1#|=5K@ZRq^a6cAU+^(dL(c#(2n+^80cRq-h67bymyz9a@Qi^PM0xV^tP6vl zGAoslHKr1e<$-zs+2T@+NV;3r2I|}QiC*V+)|rTI-qu>jKCiR zfXpBm94FBeK$rCTl{~#gTyGTDckA?{h`RRBb%ow?{sT0JfL@`lCL>>#Rlfx5zy`1hYy%TWd=jo+`??Ey-5ebQ^jcXp z_uR!#zc@Dlw>0PpdVy}BJ?IG90=>hyWlGv#O}DccYsF#B1`=1(O>Um^0uB|Km;K+s z?S8OZ^1f?VJ?5>?B{ZrHsCMDSdbCI|v=D8K{o5U2q}FWkNeE`iJ7 z8n_PhhVCE1PvER>Zl42-D9w7@?{Mo-i@IPfiBAV=5y=K_kjW9CHiac%6<7^)b3`{o zbn`^S2K0-Ni}9NWbTO}M++$!Q<&FX&K)(?&4vYYW$R`v;fFdpyF^hRv0+xb$pgw2> z8iOXFIcNb|f>xjnXbU=nE|M+1k;mxAV}GfU9`$n=k1-$?dz6V>tCtx(tPu`vfzmd*uFh;)%G?svI zARXna)K+&`bz3(Ox)&7g z0AUA#ns-j}TTMOtaG%17rNkW!tzI3i`;Tq#(|fCR-*F9v@W;)jD%%x)=-%P4K<{hT zy+HkJNf~}O0D4nxXYr#6;N8-AxcA4izU@=$%mIB?(`V6-qnUADE9eCEgr>3A8 zhz7cKR0u zQh@Kk4?s6T9JspikqqeGL^j=5R`bhAFdmPyur4FW3X*}9MEV@80!hfcKQ!avP8l0f zxS`-W@%2vg+d$3u%00c!y$|RP^hL)`;O+F(231K#?KkOV9IOP3!5lcEzgGbD(^~DpPwmKWcVaDgd;HaG ztY+elxcW`inB{gvHPf8}YBM|oeg^evf<|Bl(C@Hx19KumLVD;`d^p7FM;W-lPy}MO_P)P-As95AC$djVrpZs~#Hg7^rPgS$G><2Ws$C zJEA6Z!+x$tAw0D_!m}Dd)#!N~oB(Rr90@)Fqrhko3zC38w9U!SQ_#6FlyVCRx1cnd z=p8#F%}_HwOQb8f+N1T8MmnZLKp`-e-(Qj71rk)ds>iH{Q z#&T1Z=ob-QD!8z8^EZ58f)!i0zhR^K`OLXI_XIsa37~p&XWULed8a9>a;QD34X8wT zYg|=xbbm3vwW zEsdt)AyK_LJz?HJ^>0VMo<_2j zG>SL^q;W~3P)r~`)remVHv%Zj!$By}Ceu!o7pM$YPU^{0Z8mKd<)}8LHkWc(tEORE z<~;a$%B^&omePzTJU7p)q0OQ)-9wbi_Edsko|PY2aW!0#ljj^DJ76*}6Y|9MB%Tld z|H?d+bn-(JhFbvl12w~Fsdb3xP|*a7@;mIUXHOJ@YNX0waL7 zbY2o1jyntt1p~nVpqVS(U@!z|SS-i~y>=xnz$g6vQ9lu*%8znz4DM(!4vYnw=w#c~ z@M%03BH}cl@Xsdtf>?ZgN+!MHKa5sVtU>(qv*O$2Makb8CrT2%1e|imG4`!0Xc(6g{d}u@% zn&Kv2S~oIg_7pFONP)o9|CB4+#8KYJ$_t9w${TrN)aP5UA7~}_f<3^)pKUzv0-E1W zumfmOm0#LPw2d`Pr}ksOQ#R$D`tJrh67=^zo;59vuj^N;p4(Kvi}6F*bdW$#QFTaY zqiW%{%7gNTfBTa>dPb4j_q4r_0&O>Csi$oZ^Lz++M%mkSIfB2&)iUVF)bx(owA$vp z=~}^X2WoQp$^8VbW}~H3Mjn&}6%7A^@AtGHA@P(zbM@qS2LIDs3Sjv2BIa`vE_xjw zojtGOD$g{3Ezfy=Yd_YMwYPZstv2e<;GEQ`X!zIHOf>N;K+6W$|fBO7jWM$0kMM6Wjpm z=YfX(hMx`z5B&lBG!3Oc05p#sq_4%bM|zC8m8Qd4hrCu_>#5z$6F~*5r*~-Kl=dD_ zvGJJSPk4R=9)lp_R&8qbtSVpBh?K)7UK8j0;rr}Y|`$d-u4vz}%yY)gPqpl;s z-^(lZ{BKR$r;W<7*y(5y77`W`j*-htT2wIt+&(1Z3q`^8YqHfTF|ITeks*-~Mdg#} zRg4ICVVhw2%40<`<@~3$(=j|WBrH6nuvZniTEz&AYzRR*QW##a&&Xx2WPKqh912xDj6Z)au+~A`#TGxgyA|x^-Jk;xRSr0+vcDoFHd;j=LQ0S7)nvfPU%-ktT zOVo-Z3RZlxyhBSfYG_Cim@Th}>b&KUfNDm#^OZxY<8o_8Of^#UrfIZjdDndY=bv9~ z?B;Y3sc=YyW%A2HNVjYK^Dk^XCCub0HAeT7V?=e=Au3`j_Kshf`ZL}4Gm|AHiJ~yw z#ZjGFO%ykddl__@q5Ed`x;7JrCGSB(;nWJHYOmCSAo2nP+IrLLc0S*7{SI=X+F{C` zCxmDjzFXholifeQDdcn%)__P_LKbM+Ip{&&5WF}v-{Dwp1UVgH@JkCBA*Zwq)#aXM z(Hy!A&}DqGdDCzGk`AB@Q6XkE)rPMrtZNtGyJcC@d1Ow`Mad>cKB{4Kbly)QJ8RH` zlG7Qr8YTU1ObYPL>upv;3+a_h9@T)uzp~F=6V7_e^a$6#tL?4Tj?i8)UwYRxYS?s+ zy>dSOmz1ex%y%@9%e5$bOG&qpI_hR4qan8Ljg?(LZL_|C)6of^V0@-af!ff`lR7($ zz}g$|)!y?arta>Zt7}n{6}Ha~+pV6y+LTpqdM2glk#s+}q&uG4{0}coxwT>I>urQ+ z$0X#mA?s=z0a3cModyc;g`;O49&tL2Ry#^NrPqBsWaV`4eIvbw4kZM3Xb*XA$V=k7 zb^BU*``x}v56af+ve2Z64yAVm%Jd_KUo^~9TW5M`CaunyckRBw!d5D<->Wzw+GcS2jZ67$--RZUJ_VDex#gfE;hyf>wUjl`Bx5lQA9{oNKq6TJLKSnTSe+ce0AR* z9?_9rNu)+yvIw5l+7;+1B_s4lbD4+ZRue;Zk~>x{I5hg~szLFQ7E1a9MkdDI-MU6~ zM=mKH;0nw*0&|D9@9k9+(w#l)>gD7zjkX^d*_>~Z%b1Uh4$h}3q*rU$sisAhK<$@* z(xBFyDY4X}FrB?HO(@yw87CaE@}wTc7%yQCI^ayKQraIgUY=@4)=$MoffUly{P0I7DeBgyaNu3Gc(QAio0+R0|iRZVLt z1lq?|%wBlk2yRu@BnVT2^^&n6StBOZX)Nm-Qi9#Gr>-l|c_@QS>+T8=zecchx`Z`i z3|`A9)f*YH&f7k6ypa*${M| zosk(rh3FR(my8*i=2<(api!!9QmZjJn@%8^Eoe+;FZ^U%V+Oog(?Chu#OTDGKi!)^ z*h7{yfd@ln2aY=flf1S>wu^;YMrv3T82FvOwwGlyq}SSTk3k>~2bxyU6u|E}vjTB?cuTYHO7IWADbp-jO;Kicmj7 z@<^Iylw^?PX-52Z(v)A$JDH__Go!luc_u5riS0h!xbwoHt4@bD4C2*mja-H>=r5$N zcDdqNE4LUtqiQv~KnSr@StUbrW3D5EtZhyegOEqs#;IG(55Dz5gRBtRZJbxGL*OVZ zFO;r~O;@tx$#z4>cFCy;Mw?T0b*U5T@=HpQn@X)skamMqr|f|1tM=U5^Tk_9E|*~~ zNYcvMZew4KxlE1_;9ke*(+TCvo?)B1J#4FTC$2}o(U@kB{y-|UG>SW{^2PO(t2wRF zSpUrZoP&FMHzsbBHKXj76D^6GS58qn554nnF3Hl$2#7qB%W8qLElXEQ`o+9Q@eKH# zzNc-IIs5e-dsAfJPKYgir%TsXq_|rgeGR{)bhGKQ2#=@)%5O7sI`U3ON}Jv}OO{EM zE}FE$LW*h+rRP7S9F7T6;D8Y*!L5y&|1CI>)!~-l2$Y?zjZW@C`K)qYP9E@y^Z5_U zNjo&el-A=V+bhGT7-e8x36=Kc`a9a4==LV*ev?Wy5U(kOXcw4TZ~lRfTjkIA_;Y1) z8|rCFsX)gTZYY9*7xT&E{YHR1ZDZ7Qx5#g$dg4@py}QarX{su#NVT&xZ%f>Mauvs& z@N7f_*)?&GAfY@IqFPbkeA{juAR&(^H&dwLs4QXaNw1Dn!;x0)jFazrxl4Xv6{W_U z-9>JsoV3mw6V%+RvczcAk7Q1Jqa%)^10$-nM0P+lSyQp|VIf)AfmX2kik$4gI1QJ5 zhbekVl2GbX!UK9xlHukmaP_jLg_q3yQ>i@KK=xP6xFz z|5{0RNZrRFpeMwxxf9zr`f8zX;|W^Jl8%(hsvZ;4BTc!Zr08VKbGKxs(2lqx?3e4_ z<&u|145@fyFlUfGouKP1=Q|k%j4jZmk*O}1uVm?LBh% z_S_#uQ~Tw^)1UM&IBUlrcGA?vQck4T79*3pK(s}brp=rsZGyJ;(TP!2Emk$MR+C9w zrC2Jv)+3KLk^;gs_UDKlTTge&;)IFxl4v^S;b;l%$~e3YMOG+Yo*bC}yA1O;nG~iB zPsV(%AvHD~TzM_cv@Y=>xn)>axLOf{Y!D3nG`e@P?sKlk6Lge~5TH+Fn`QXO)vksS zv<70G3Rh?Cfg->iQY{l~szCPBDXB1T3);8-s6aDom&mm9jPkxw5# zPoGm|P7!OqdQ?nKY9V}!Tf?Dpo2da$TmFc8@8MSoJEUybfCZnP%vvu#Zd-2Bq7V}x z$V=iaH@_}2@5XW8c!IB_4g}5%#id(!CM{fQ|fp5mENm&pT-dJF>ker$)rO_LRMl>a=Q;F%rL zr{4X)$G(cHAD?J8Dc*zfS1)OrU-bOSRzS$-5l+|e`!N5AEMV}!t zeUJkGR)|s7%q(p>t7z7|Y3hMNeUZ6!C9*GK%Fc0kUn7hC>{9L=s3=$Z!`w?1XMY26 zdAZk@PSUiJRsHAb+jo6k_}Cn37sk3Utgu%z$@(#!+$8tQT-Yly%FuWQhk7bKO_mVX z@ulog$1bhaAmZw01bH}7nDu!l>D><^n>X=3&dXJ0Qa=j(sH%9QNGFL#Cht+wKsn#f zs1bRsnl+z9%xF7!--5-%oQ^a2s1Ux7i_Q^yuXyX$hr(;7uqzdf9YLD*Ck3tw>~BOw zjVo`>2Yts^e!Xc$PHTZ+u4p}%T=o3yM7rVQs*AT{Ky^zkdWVgENeg>DttnXs!_W*; zU;w3RQOioR|I2P+Z`SslW#`R6=|o6oO0{zT_xGC&SjtkWg|6{wn$fa$0Bzy9J?r?v z@KOgamirKbP;?t+hedK70#?c|aDoojW;cd}iuxR_9o=l0>M6E%^m}ay9cYBR6EDPD zY&OTGuc7nbEZI1ap3_984>Nq_pMmroYt%aJ+Br|wm&fyHjDPA&r$MOvHtB{zbZfI= z1B0?Qw9FxuQ*3xJV(*Ha6w4l%9u^gs;zOuLYpF9BXR@sS%m~B!@K%}L?+npa_wc9j z-=Sh?2XcGnTggd}A*dQ=u>zexm6TrNP^})%GW}YAM&-OE)lee6RqHS*tv(GU%>p!` zK11Vatr~HIjZf>(a%Pm)fja5@@X! z9wm-g>N-v*a9;_H^|Y{=x3VX$2-inJXOCP{==#cEqfBx$WTSK+@iuu}4wL242$*%K zn4}zOmD5U=E)~c{mJ>&svHsP;td3Pst`0N|yAbY^^{q)SZHj9jWqG)xxmh`soG6>O zGG&1gkfdN}T$w3^J;6j+^M!IZ8fvr1w&0mI3c+J~X>AF4tI}oasN5Jt;t&rsSz$&MB45|v^Q4b1?AOe zu)84_J3=?CyQPA4NnWz^vb%<*R5E`SVJ(`C0l@u|1(nxc)>JWhryIWdgB`QI6 zE?QUr|Ii}}X??o?k)zya+sj)$qA=b4W_L+F9wjV!4@=Se+DKP#aiLO4;`>YqDLo!$ z6@oxn66BY!&6R6M$Hy}(VI51W&`Kr~)g5W8qtVHxY@ZpKeMEfJDY6d&R&*DYEP-mCKTrhlH8uM;Xxi*1rYwFBC!4xFSD|s&~pDM@d)M@rd`nvJ?#$ISpLL5tJ6GS_{HSE#1piV))1hh3{fY)>{^O?745ZI*7G~^GV!#3t$+QoUxW0W zQ^&`fPq8({c0t3tt@^5=PHU!y#fnK@X_nc0W35(#3YnT7xDeDao}j*jO(L)1QVl0) z6?Dp@mtF`9*HWp+_1l@tSvgsEr=tx%fuuQ2ny#UKYo$AM&cl6W+8X$Dudghff&n&-Ji?o) zD#cWzK#JoZTXF0eB;1s@D&M8sR3?CWGWjMG+VZK!2RS^XEBaZ=__8kj`we>CG&3br z8N%fFwX9ErHH${xC26KHV?FC{DQENM9M06c`?ge&+FMksr0FyYN1^&pGxEo!o$wT= zrCKH5PBSXRmA8qcpH3~znb}85PdCC+d^gZiYt0$Lv-UvMc>DKT;{UzLKxY$EJMoaX zCl9q4e7WVXe_#9lYkvxl>ZVHyYYuY%34vNp{a$CUuxI_5DP|Kzt7*EG%$rGiadVYU zN$$iY-P`$U%e_bM^w&FDpt*3cn$-LK`AW*nF>-oJZ>~LkrQO_j)E+JU$8u^e)~k0a`#)&1 z7Tab1JWqmw4r|`D73H@Tzf1atvAbUx8V7B#>-YpA$CM|$m< zZ?$OSJr9lfS03aw)52VhjFegsIC4nm&)Hb}Wr5X8HaxsCer&R)6-;xd3Qey{vyjJ`7fOdM!rVrfUZ~0B+?z`l zRXVI{^xV2KVl6|x@|O&ChqV3Dn1{0U=1ZcsmcX?%hHX!GEVnm~ue2{O;WJeywp-Ln z0kvr!3Av|!Zk2rFr{hnCW*L%C=`3Tqm5`mfIM*44gZ8hoinS-^vzOP)Hfael!&-O5 zj;)fq>*z=qY>E|&iWfe)c$G^Vl}!?iy@MnhCTb@e=OJIAktaAMnpUj#@?aeW`*^k0 zX^YPvSL2f3;lTG&icsrVgY|l3!?XwbC9%zB)(VVev|7ZGpiBe0$h8eo^Ju-vDp6+0 zB4zQ$rk@h;ED%()aRHq+>m)?tIlbr7VY{iZbU-Z^QB8>Ju!FUnqc zgx7XLQWMgB^02fwg1=FIV>{8_Y}LnkV2$kDYy<=)&Y??d#&WyGzHxyh;0UUxX(-Foyj=$2P=%EC>oSrXi9br^c#Bf!`VgFDmw4HXzAXT=LUOyS8&P3UWr<0lF z=ynzl?^r;?`Ie3jEKh-^OUG|0&`z1&F@EgX=XeqyT9#_yKKQkzWk;_Mewp=$MG=fJ zdpaYh@xS6V5(i;BLpS*d&0jbt+Z&f{USY8QsD@p4hglF5$zl+ik)AUSp$ zMLBzrZUnmz{dZ$uS}tGgCX%N-&E=~8ylTvD%YlvzdnnItDY%Dp>|E1JYyFj3hU|d> z`D8tgyXQ_zFKX7S;{B@YO6$gx&H%Kdzr5PRv5G6Zr21au&GOxrP|JO3`HBNPuyrlJ)5>@j|{%mst~oP?k(`%ie%kSZQ?W?TBgN*YwxjHd&BqK-@8KM_pPm6 zb9anQ(B^qSrqVSpWsE0SEK4-C{jvim=q7a8De&tve?NV)XeCwxG(GbylfB{2CvsAJ z3lp14$#02fC(rv*dbTrmUXw+iZ@4}LGn^-ysUP{sqHm2IScJ9UD&W!@t^h|Hsgr^o zYm5TDzOxv3Xln0V0V^IqrLKA|fx5nvjl(Xhc@9eTTRp4b{63jfJiv0?PTh0dDZ#mz z24))4<4$_&>IKo=l@C~R+V3@U$|ec&BX3MSN>^73eNXGQfxw%(eVp-LzwmpF(n6re zK`2}wLedkm?`DKCck`_dgxDRUlnf&(S*Rl$zK=gm;W@@&ww|9e(ES4FRwCnpXX1z736IA{c>`2Mi9 zNit9}|3LQENRJyP_OKlx+4?ZHX2>F?`7cuE?IRM>&lTW&end(fVkFc*YOx|$>wej5 z_wKX6W(B-jEm!l;i9MO{MaNPJ*y`;=xHkUszd=JOT^TowSD2z6{0xY*~HA5tGN}5fSq+ zVW54SPQE+B%y;#)TswlGvku?}-9Bx_-4)sNz_}MWBIB$54{X$vJS?gW* zjPe#I_w>$l@qSEIA2PQI8ps|N#O@wHTf^wth?FNwdzYQ2wY0W|2g)C0!MVFUr*Mi( z(^HU-yXsrkM|SN|$&TMt=-dNIPc?x-^E-^2G`z|Rv$oO7dFu#nf*GoC z3GFy*~tll|%Tfe?PME}GrG@LT%xi70#5a#Ut+gme3*d| z!P5E`PEJW*3{xeFynS-hSL*y^26x4A7rAO3Mv6&VH^<-8$DK;5z1KW)R!0^=5ZMg^ zwY45{6&Rf=_C&6Dg3*Ko5wfmO+i!mw*WD{VWQjZ=YS2CibWgZor#wdE$;P>Of-6@g z`&o_`+VvYJyGpqNBNOjIiFdvj`9dq(L`t8dHU}!A9gyQZ->r8ujo#VSY;p5c_C)D> zj;>Qmt`A|T?LEh8u+~j$T;8qIc1Z1srrw|(h_&9eo8tX5Yn^$>>og=+cl_CPSsGPM zNpjjB8DsZuO8K9S{3#3nYBil5L#F-ADba57{AV=P#5dscO6&6!+SVKsI~Eo0RY%rC z=T6W<6t1JvJXpo3y=@tU3vXF5`&w4-K2AqFd~#CqWw_b|eg3?*WqqgeFX&p7U(dhq zm9Ptx!L+OTN~;S-QupxQ*3RVGE4+Qw((6~M%K%lAx4G})F&za}xMLl)T6;eD^!^!x z^?eN6q@R!x@LhXTRD#E_OnXy;XMW6(<9B7@MU?XwcV*i}29}+qZ5NR&m(VCHO3_Q4 zU$gZ#^Q{hlxqrzB3VOh3Qzh@(+0j3p4jbVxd0@)47pEoXWmf$?9$2lo=49iaQXbAQ znF=uqRO)>ry)Pq&k3En{5IT=Pl)aakPtHHII!4JuU4}2Z@c6YE!Ia15r_9LAd9HV? zlnpNsA7V-fKgn^$$Q*Qw_&Ohb_W9Z&b^B+!VpE|o{QgjyU7?ER@>CD_^xC@mijgYG zf7HUGQ3X7)>N#~zrB1)Q*XVI8TM@D?EJH=bSWp*E6DvRJx4Qr4pJ}cCil_6ePqRr^ z2;BupFeQW+#y-87{@H0xTMpL*5hanbNCl!anNk`8293%q_Y$(u$uiT6Q)5b||Dv3k1!_f@m$jROnX!8k zRJlE}k66y*Pvp`~CiBZgOHZ^>&sN;5m%aB*qM<8lZ?hz~^WhVz*??p1iN8EiS(+pD zA`i^A=H%Jlv1KEgufqh%=*9#Y=Jkd=bhh4j_g165K4lu3d6=t{cLXLM!o8{q<@()P zn}!ar@K64BV_1GL0L&s4vqOH{vvG#&qXh$;4r{&03&>KC`NiE10zYz^zh>^Z=$v=f znmMt$2=%fjAnSOrdoXlap(}oHe3|F&+`DzQHdSP=sj^-tD%&*h%Pq8^n&ST(>S|MI z{~JQPqs+l^{_=+${|zbd@((HV1nsYpIBpZKhdBO3iNAD@cmw3rpN5|i&N0oW68slL z6=caBjGbYs?0qWfpHt$*_v#i%`uju=i;FH;7eFO{va5oz-YdD%F})Jdol~ zgk+#n0gHyrnY^l=t{-i^?Ef(@vtWVF-~N)FcPM9N+3^>Z`5&W6iMxorW)kz1cQB}J z;^nZiaVJh-uNLE6|{q~Bdonoi)4La&0mjWkJQee`#CDK$wnCbP6qB`(0Rk|!>h)o z``M_Zr%9CEv{zLr^niZc5&~ZcE_|{t!0-5zVe#$p|HJ_Hqr#q2zE5N$32~s~2#$L> z>8U=^qUN=a?$pVvudZmzN9mnT^sB(29S~^mPnUGzFD=7^^ramw5lwRHg%o~>Ah#Mx z^)HJvPP=Dn*Yek%dhvyve8{UDN7KdDsqKE<>v0#S0Rm6 zK^5FprS~&9P#*%7vr*Lt7YJGO2+M`}Y7H}08_A|!V4xJoagT>iOFv{;t*Wip9qnXi zK@)x^Jt2r(3qb$`y~+&zVsA`wU8ZXpP{t1sl8KOj+`nbJGHq^-_z9BO zvRuFYCob9qG`rOeoqxTQ)JTM&58(g{{mrzOpn2@HB}C$V@=%BZZ{Cq1$WV3w7=uXYzxmg&YnB2A^7 z7To^jPNe*BVrc%Kh@p4t>Pgg=mllJ~6IBhFw$YV{y?So7*oW`X%qc)#L6; z9j$YIss78XsH511hN}c8rvb9)B{H*}oOy|=VXCs&K2uAHR}A4-Ty?1mdY^-XTEwoH z6-*ZPA@vl}^A+6AlEz`GGuvyoTiV4jjO{&-ZE-FkDpEIO-4HM_TOMnYGV8{9msi-W z52uyXuZ`pEH(z{Br)eVW0tZUkH|Q_*pY)9x;R~P?YFLM3x=vW3t5e**q&OUMg4QDpG;LVp4paOmPYPTxZ^A! zOOm*1ILgW+)xv8_ilnXxc9Tlt1l{nps(Zd|+Alvj-e!~Chp6s-UzwED)gkCMHalJY zc#Yh>>W7MbzK>^!Z6HtRwNv|D5A(It2z`aLzu}5|g>=8+%EU{imkn114pruGxw6si zD!5z)(5ia7C}N~cRL=-m>!PGB0S42o06PP;mYK^;VTbQxY!}i<}g)(Y)v1OoYkOtapLKV%*4BsO|qwSRcEWe zXG-inm$F-JaP7~Wdjf|X?HJz%zuF<$dM9u4U~$@g@gZGg7g60GGs3hd)E?e#=cSEb ze+hy8esYXFfxt0aQl)Z@z_dC!6ajZY1mW95s~Q0A8dsUfK@ z3u^Pr+#UAI!poCOxWZM(vCqKa?wpIS@kSq#!(8Lflh$d7VIBeuWMAkIzuayv&C3XR zt+l5HJUADqf<`wR5Hu?!EG;RomuhLv{#P~wuikx{)|Dmbn*t6~QMi?($dzR~Pb{Mr zcAUcno&?^zQ)K=9jdWQ_9($I2vqj2NqzS9n-6~~OoBF7O!J~SMa4*(46XtxUWPeLy)ICw zv95xfs$(6Zah?p9X&GDrF_*(F7OWcdx@W{ zS;RnWgcaxSe};70-{@29x}EV+4Kab2aV=ZD*9s`KHQP1*cK^b3iw&n^8a}=TURXUo z$jIn9h=;1WVJV;7%U{tasnhW_K5Dt&EiE(BUlS~m*~E$GJ6+Zi)txxOGPw?c^ZUZ` zGNY>lLqp%cm!UqcObHKX?luVZnjjl}EJ1mcdDGfz43q$0B6TccwV-=a;n$hB)o`0F zZjQb_Qp4AELiZH1_)*;=(H7zHo4a~_Hs#N&CZRdJw@Dp6h!A%kVYDCp*53X+T1>75 z(lM_Vlf7ARUlfy&Ol%frkZk_M$tlIviI#M^aq37qsCH$88gnV8u26oP;BMwb)I*XB!HzCk*_GP6_ z zQapn)GZm^Ur-GROTFH7%jL_K3u3#yV#g)NB>hZ+dNDs2%G z53J-c4Z5pqWj-~3#_1jAAW$)l>bwsEv^;e@GSkznZ^<+}XSYZ2Bp|a)c^B7H-V?*` zCW($&DNh`W{s+1HR!L0h`mby}QvO}>p3qSE&njfh=Q^kJ&;5MN7+vIYQFzl=vg%PH zbDL5v>*lM%!=$@8s=puUxxN4|x+7Dde?o(B*X??}`#X0iVTw03uvX!WCY5DEeo3MKeHf;pm_`mQ*JGJS&)e}!TkmE1;1b^6v6`N zuiDlSxwWs8PoKZa<|Ti7>wbp}3!yfaDcn;VIUM3DOzqzg6nUbK!(5e2ebPMOa?LlE z8O^jspC`oJjR>vMXUo0{s=DdlZ8x^AfuipG?wF#IiEC^+mW7%WRap# zE??(@CQ>`fP1$0LfB>MuIiPip0fozbb9nBky$?GA2c_ zs6}Sw=#WKN7A`45e;Xh>aDoc*9T(M+lb_x=KUt}ehtTPQ4~@HcGkIKunpmS$vPY9i z&1O<6+7%Glgjjm7Mv6RjRu=4gH#MZ8`2OH=c}CPYWTmIKD=e0Y(JWi1 zHIuz0!8?5Cqg{9G3vGP$*x~;d!hzxMSKO69PIusU)#7l;KGt7Xq&Pyt79sMwxGPi8 zuSg1ASA4f_K)DQ#@@gm6k;)N)x5)gYO$ioruUk0Gy`cSnr_UGh<7OAMj6NNI(9SP` zU`YJ3g$OxOf=*VmoOQbIR_(z_YSf>zl_c1J*H?qhqa;4!U()rFXKd!Jfi4_e%H^-d zV)LRh`MoBV#A5QGq-);)YD22^|CbHv%=;&rTDP&*PFfCsbGJtgOOZxf%Z!%mgU_SC zd(ick*#nTZY=GJ!BhGvuEO%vvZjm?c5 z=g6d9ko5lDgg%b^#M8e~ZKVZq-Bldc21%jt{mFuUFHqV$j$*q^FT>bLCts9dDwrl$ z`Q?89O2c^acMc}d#XaJyP&*k{K5nd%-1@Q%XDS!0!tIGuZkBb0JEygi4K-c9NwJGs z?>{&fwUg@Q;^MjgZf9{}Y@^KkhFvVCJ5^kQr#;nvNlH~f%3Px_s5S0Xqctb1JYDo_e0g?tvPzoF zr=`!3JLT3BV!yfIFB2=!LKf$ppLdqMq~zS*SuRvS3>@feElB}?DMm@RiSD6|47L;0sKc@A_@z0Zqk4-+9())Kpya}1Nv%uC;gEkg3b23|*xWg+m zLYzIUvZUzKHmFdVlsTa&%wcA7@gqb>SK*VD)?|sOQ$$A>hx+J;g?h-*%Cvv{31TCt zIG^~^GNjnEDCFx?qkmIsYt>q*r_`)MPW7Nj55+$j?z=N=$xy~r?{!M>YHx?EUDCDT zk@}@L+DuLL4PrZ|aOcxra#GVs*4q*d8`ciWd3oDkW1zG(olJ!2;^A@l&29aPe5f;y z9TMJKvQ(v&tx|Jj*1E*fS*f>lt4d1-_mRaKeyWe8u8y*Ex+=pZb6|pC;8Q#c%y( z3b{u;?Qiwz6D#_J9t@bvOw7R!^YTsS0E>UqmX5nK{>XRiEvncIr#&(bkW0jM<{Kb? zRW}WRdZN>lr1NQi`Mw5q`S)qW;d&O91{g9>d}_L?+X;lrr!`@L)qi!0)^m2wvfbon zO;@b5`e5l$%N1TL*$_+a-_BP3oA#f^WHA|TZgswY^{ltU2U?v>yW?sn3CL2eY4#EM zHWSC*Y48?DZEW)i9AvWf^F>3Yc5UjocBpizjqrQNXe-BRqhQ%Kqy=KsagB%y9Bv7? ze8pEZ%H8bGnVMHoa~}COA3Ucra}1ZAb!b6rPeC5mab=1MB^@2CYbN*HG57v-($S8s zvr&0M)KHWEdX`F=Ll=A=pF@-3QmQWLnAe9|J9ehwyaub4cdoeny)Nq9e;xF8H{@$C z%Cc%c-=;jDJ#RP7gf^qq-Z?EU`#)l(V4bgaE{NHhp&nXDP>Wd0%swgLv;FnYXE{b> zm9Px%jse(@kCmfj8?*olHMpKD6nlT{N59^L!c@AspE7nf z2cVqWV`WNX2!DW31z5QMm$?Ur4IK-izPCr8^&FM@8449Ey^DP`w^)`hcg1J+xr}JQ zgnB1d=96U53kX#w9aC}dkg*ZndO>JTH)zNsN`QMb#(c-lw~6)NckqnfhiNL{AN}wvhJ(sl9_Ct(xutnn$ZNy-Mk61yNN5z$ep0D}{wiGxT4-tFxbvI|<~fce#3UdG{qIXPHS-CYI1@ljL|acx`Qe1vQvtHBO2AV_F@m zm1!awF}&$SUTr2xi;rRaNUEv5@MPwvZM~MI7!*&@W0KTvj;tL*8rloj9=;TCdv6Ur z0%NCfY?XEPCHlqcM0-`of~K+Fupyg2rZub0com6k@s`>8t5N;NDzqLI5&(piOSfCC!0P4mKPSB=l zmZ+OLKlt*?*vM(*qDuls_@#=nn0^~|2nyZT7*+a5ch!?WRMK)-CZp-otzolZ{ohZe z)y2JLTvOsMm@W^A>s}9q&gMz(6sfV?>y8dAmC5Kt){Q03@25+N_O#}5sox$M6fr|4 zw1;7~1UTCs@zhkWMevp24p>3#be-2{NSO}MS%;N9-tPapD_~y-SI2j`71yopca7rS z*wi;7u^Ha$!jxc-5_iK-tuffMS@$wubs5l*ns8E9M}QsMek0Rv!$i8btm{OL;$MK; zJBXIBM2xfFEa}!8R#g1vLPwD8XkS)=iQzl4o zSB7Z4*;Y48`}?9vO$&C^k*2C19l$e~+su|8O4$cWojzZ-@%pFS8~;zC)HM_=cu!z? zs^a`)wmc@LHrL*6q>w;&P)i9@^z7ME3JUI8G&`MtA_C32k#>GJ%#-mpJ}dQbI*Psk zgIFr+ML$W)z2J5~36L_~85edbr_3Bn>**bE^48>87rcn6b1@nd?a-c%FF2jJ*te&nI8kkPaOc>$a*~*C;p0}SxTL!=D|hzL zhAMV!72|C!G84V_?K#TRH{H*G(t!VuF9KRmp4`cX^lOg>uE9Dex zCnB-?P2QbfoQ{R^x*umd>Pt+2q>#mFcfxBSRhBFjj798k{gKq3j%l~*jD=Er0JXGL zFL&ZPmn9&B5^qXdZL<4i(7%t&n5%W<(}IN(JdiG9RbPHDz!VxT-3MZ5vrFaSxhfYcJR$jrJ?CcGq=! z`b6Sm&#Ibx9vP@6`0c#2r^akwyC%MqT0`vpPGKuY;qMEScl3pzIg2fW$NaA*P6|tH zr1yz4Yp~1y=@7QGe3n?otl|@vUJB3lT+ONaITB=@`Nmrf58G_PA9NCW75Lc~{r*p% zVx@LkoKg+s`VtvFl;++vO+FjSJZx%&{z;1Ps<$bF^+lMXOJ}2}Mb=tsEqzOVpFHnJ z$q%xS_gGKc6QasN=IK>?v|T)NKzs;Wti$M%ajDwBZB1aqFjvx`jmxaab@GJd*gUtX zd9>2Hq{LDX?K1gTTIy2CJe$;c7TPv*Ybtpyi^>`&+pBe-zU{q^mMitmi%L!RHd<)yApJ1mtC!!_uCuZeztt>oaAl3TcEb`=7wZpM-tddyzD&(sY|L}EjFqgsjwsh{L$wV0jZH{;Q=dhdt77eB}UkbwL? z(p9QS4Xm14uu;*GM;!yxzCJV7n(zl5TmN$8z~3S-^IM0rms+Om#+-p?wY&O4Yd$?!KK+tvx6!0fI2N4ds3$95X)+S+MsvLUs$ WzWF)Xg*-BNl*_&KLq~F>;QtSwOzyJ) diff --git a/components/SimilarItems.tsx b/components/SimilarItems.tsx index 1ce1f5d2..102a082f 100644 --- a/components/SimilarItems.tsx +++ b/components/SimilarItems.tsx @@ -13,6 +13,8 @@ import { import ContinueWatchingPoster from "./ContinueWatchingPoster"; import { ItemCardText } from "./ItemCardText"; import { Text } from "./common/Text"; +import MoviePoster from "./MoviePoster"; +import { useMemo } from "react"; type SimilarItemsProps = { itemId: string; @@ -38,6 +40,11 @@ export const SimilarItems: React.FC = ({ itemId }) => { staleTime: Infinity, }); + const movies = useMemo( + () => similarItems?.filter((i) => i.Type === "Movie") || [], + [similarItems] + ); + return ( Similar items @@ -48,22 +55,20 @@ export const SimilarItems: React.FC = ({ itemId }) => { ) : ( - {similarItems?.map((item) => ( + {movies.map((item) => ( router.push(`/items/${item.Id}/page`)} - className="flex flex-col w-48" + className="flex flex-col w-32" > - + ))} )} - {similarItems?.length === 0 && ( - No similar items - )} + {movies.length === 0 && No similar items} ); }; diff --git a/components/downloads/EpisodeCard.tsx b/components/downloads/EpisodeCard.tsx new file mode 100644 index 00000000..69974a04 --- /dev/null +++ b/components/downloads/EpisodeCard.tsx @@ -0,0 +1,23 @@ +import { TouchableOpacity, View } from "react-native"; +import { Text } from "../common/Text"; +import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; +import { router } from "expo-router"; + +export const EpisodeCard: React.FC<{ item: BaseItemDto }> = ({ item }) => { + const open = () => { + router.back(); + router.push( + `/(auth)/player/offline/page?url=${item.Id}.${item.MediaSources?.[0].Container}&itemId=${item.Id}` + ); + }; + + return ( + + {item.Name} + Episode {item.IndexNumber} + + ); +}; diff --git a/components/downloads/MovieCard.tsx b/components/downloads/MovieCard.tsx new file mode 100644 index 00000000..4f47bcc7 --- /dev/null +++ b/components/downloads/MovieCard.tsx @@ -0,0 +1,18 @@ +import { View } from "react-native"; +import { Text } from "../common/Text"; +import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; +import { runtimeTicksToMinutes } from "@/utils/time"; + +export const MovieCard: React.FC<{ item: BaseItemDto }> = ({ item }) => { + return ( + + {item.Name} + + {item.ProductionYear} + + {runtimeTicksToMinutes(item.RunTimeTicks)} + + + + ); +}; diff --git a/components/downloads/SeriesCard.tsx b/components/downloads/SeriesCard.tsx new file mode 100644 index 00000000..b1470fe5 --- /dev/null +++ b/components/downloads/SeriesCard.tsx @@ -0,0 +1,49 @@ +import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; +import { View } from "react-native"; +import { EpisodeCard } from "./EpisodeCard"; +import { Text } from "../common/Text"; +import { useMemo } from "react"; +import { SeasonPicker } from "../series/SeasonPicker"; + +export const SeriesCard: React.FC<{ items: BaseItemDto[] }> = ({ items }) => { + const groupBySeason = useMemo(() => { + const seasons: Record = {}; + + items.forEach((item) => { + if (!seasons[item.SeasonName!]) { + seasons[item.SeasonName!] = []; + } + + seasons[item.SeasonName!].push(item); + }); + + return Object.values(seasons).sort( + (a, b) => a[0].IndexNumber! - b[0].IndexNumber! + ); + }, [items]); + + return ( + + + {items[0].SeriesName} + + {items.length} + + + + TV-Series + {groupBySeason.map((seasonItems, seasonIndex) => ( + + + {seasonItems[0].SeasonName} + + {seasonItems.map((item, index) => ( + + + + ))} + + ))} + + ); +}; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2f8c24f3..d10b5da2 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -329,6 +329,7 @@ PODS: - MMKV (1.3.4): - MMKVCore (~> 1.3.4) - MMKVCore (1.3.9) + - MobileVLCKit (3.5.1) - PromisesObjC (2.4.0) - Protobuf (3.27.3) - RCT-Folly (2024.01.01.00): @@ -1291,6 +1292,8 @@ PODS: - React - react-native-menu (1.1.2): - React + - react-native-netinfo (11.3.1): + - React-Core - react-native-safe-area-context (4.10.5): - React-Core - react-native-video (6.4.3): @@ -1336,6 +1339,10 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga + - react-native-vlc-media-player (1.0.38): + - MobileVLCKit (= 3.5.1) + - React + - TVVLCKit (= 3.5.1) - React-nativeconfig (0.74.3) - React-NativeModulesApple (0.74.3): - glog @@ -1717,8 +1724,10 @@ DEPENDENCIES: - react-native-get-random-values (from `../node_modules/react-native-get-random-values`) - react-native-google-cast (from `../node_modules/react-native-google-cast`) - "react-native-menu (from `../node_modules/@react-native-menu/menu`)" + - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-video (from `../node_modules/react-native-video`) + - react-native-vlc-media-player (from `../node_modules/react-native-vlc-media-player`) - React-nativeconfig (from `../node_modules/react-native/ReactCommon`) - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) @@ -1763,6 +1772,7 @@ SPEC REPOS: - libwebp - MMKV - MMKVCore + - MobileVLCKit - PromisesObjC - Protobuf - SDWebImage @@ -1889,10 +1899,14 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-google-cast" react-native-menu: :path: "../node_modules/@react-native-menu/menu" + react-native-netinfo: + :path: "../node_modules/@react-native-community/netinfo" react-native-safe-area-context: :path: "../node_modules/react-native-safe-area-context" react-native-video: :path: "../node_modules/react-native-video" + react-native-vlc-media-player: + :path: "../node_modules/react-native-vlc-media-player" React-nativeconfig: :path: "../node_modules/react-native/ReactCommon" React-NativeModulesApple: @@ -1996,6 +2010,7 @@ SPEC CHECKSUMS: libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009 MMKV: ed58ad794b3f88c24d604a5b74f3fba17fcbaf74 MMKVCore: af055b00e27d88cd92fad301c5fecd1ff9b26dd9 + MobileVLCKit: 144d5f565512d1147d63b0fa1379231b3fd66535 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 Protobuf: c1cbc880ea7c4e9b157e113515c720a22ee7cf50 RCT-Folly: 02617c592a293bd6d418e0a88ff4ee1f88329b47 @@ -2027,8 +2042,10 @@ SPEC CHECKSUMS: react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06 react-native-google-cast: 77c4a3acca9eab527328f8b65257d952be5f220f react-native-menu: d32728a357dfb360cf01cd5979cf7713c5acbb95 + react-native-netinfo: bdb108d340cdb41875c9ced535977cac6d2ff321 react-native-safe-area-context: a240ad4b683349e48b1d51fed1611138d1bdad97 react-native-video: b3ba8f424c8c3f54dd9289d47bbe60fbc09bc986 + react-native-vlc-media-player: 0f9860bded57cd6764ac55b5c0e97347069cb40a React-nativeconfig: fa5de9d8f4dbd5917358f8ad3ad1e08762f01dcb React-NativeModulesApple: 585d1b78e0597de364d259cb56007052d0bda5e5 React-perflogger: 7bb9ba49435ff66b666e7966ee10082508a203e8 diff --git a/ios/Streamyfin.xcodeproj/project.pbxproj b/ios/Streamyfin.xcodeproj/project.pbxproj index c391f8a7..3ae1193e 100644 --- a/ios/Streamyfin.xcodeproj/project.pbxproj +++ b/ios/Streamyfin.xcodeproj/project.pbxproj @@ -10,10 +10,10 @@ 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; + 303D6C1B994E4AB730BB4D25 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 5677A7148111D7C0235E3185 /* PrivacyInfo.xcprivacy */; }; 3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; }; - 76DE60737AC6B111D4CF6135 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 6AFEBF12046598BC1A9FEC11 /* PrivacyInfo.xcprivacy */; }; + 7B8C1837932545C6A7001A29 /* noop-file.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46971613083A41BAB9656F14 /* noop-file.swift */; }; 96905EF65AED1B983A6B3ABC /* libPods-Streamyfin.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-Streamyfin.a */; }; - 9B470C0ACF444752B7807218 /* noop-file.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3BFAF74683646218FA987CE /* noop-file.swift */; }; B18059E884C0ABDD17F3DC3D /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC715A2D49A985799AEE119 /* ExpoModulesProvider.swift */; }; BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; }; /* End PBXBuildFile section */ @@ -25,14 +25,14 @@ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Streamyfin/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Streamyfin/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Streamyfin/main.m; sourceTree = ""; }; - 2092729FD1D54853BF6A8489 /* Streamyfin-Bridging-Header.h */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.h; name = "Streamyfin-Bridging-Header.h"; path = "Streamyfin/Streamyfin-Bridging-Header.h"; sourceTree = ""; }; + 46971613083A41BAB9656F14 /* noop-file.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = "noop-file.swift"; path = "Streamyfin/noop-file.swift"; sourceTree = ""; }; + 5677A7148111D7C0235E3185 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Streamyfin/PrivacyInfo.xcprivacy; sourceTree = ""; }; 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-Streamyfin.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Streamyfin.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 6AFEBF12046598BC1A9FEC11 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = Streamyfin/PrivacyInfo.xcprivacy; sourceTree = ""; }; 6C2E3173556A471DD304B334 /* Pods-Streamyfin.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Streamyfin.debug.xcconfig"; path = "Target Support Files/Pods-Streamyfin/Pods-Streamyfin.debug.xcconfig"; sourceTree = ""; }; 7A4D352CD337FB3A3BF06240 /* Pods-Streamyfin.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Streamyfin.release.xcconfig"; path = "Target Support Files/Pods-Streamyfin/Pods-Streamyfin.release.xcconfig"; sourceTree = ""; }; AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = Streamyfin/SplashScreen.storyboard; sourceTree = ""; }; - B3BFAF74683646218FA987CE /* noop-file.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = "noop-file.swift"; path = "Streamyfin/noop-file.swift"; sourceTree = ""; }; BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = ""; }; + E9097609D0714599AF91F55B /* Streamyfin-Bridging-Header.h */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.h; name = "Streamyfin-Bridging-Header.h"; path = "Streamyfin/Streamyfin-Bridging-Header.h"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; FAC715A2D49A985799AEE119 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-Streamyfin/ExpoModulesProvider.swift"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -59,9 +59,9 @@ 13B07FB61A68108700A75B9A /* Info.plist */, 13B07FB71A68108700A75B9A /* main.m */, AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */, - B3BFAF74683646218FA987CE /* noop-file.swift */, - 2092729FD1D54853BF6A8489 /* Streamyfin-Bridging-Header.h */, - 6AFEBF12046598BC1A9FEC11 /* PrivacyInfo.xcprivacy */, + 46971613083A41BAB9656F14 /* noop-file.swift */, + E9097609D0714599AF91F55B /* Streamyfin-Bridging-Header.h */, + 5677A7148111D7C0235E3185 /* PrivacyInfo.xcprivacy */, ); name = Streamyfin; sourceTree = ""; @@ -147,13 +147,13 @@ buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Streamyfin" */; buildPhases = ( 08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */, - E4ADA958330463261FFFF98E /* [Expo] Configure project */, + 5AE4F51AB7DD565AD6F401F0 /* [Expo] Configure project */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */, - FE3C21F6FE840DF7275CA666 /* [CP] Embed Pods Frameworks */, + E8388EA82119C85BBE90EA67 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -203,7 +203,7 @@ BB2F792D24A3F905000567C9 /* Expo.plist in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */, - 76DE60737AC6B111D4CF6135 /* PrivacyInfo.xcprivacy in Resources */, + 303D6C1B994E4AB730BB4D25 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -247,6 +247,25 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + 5AE4F51AB7DD565AD6F401F0 /* [Expo] Configure project */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "[Expo] Configure project"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-Streamyfin/expo-configure-project.sh\"\n"; + }; 800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -295,32 +314,14 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Streamyfin/Pods-Streamyfin-resources.sh\"\n"; showEnvVarsInLog = 0; }; - E4ADA958330463261FFFF98E /* [Expo] Configure project */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "[Expo] Configure project"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-Streamyfin/expo-configure-project.sh\"\n"; - }; - FE3C21F6FE840DF7275CA666 /* [CP] Embed Pods Frameworks */ = { + E8388EA82119C85BBE90EA67 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Streamyfin/Pods-Streamyfin-frameworks.sh", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/MobileVLCKit/MobileVLCKit.framework/MobileVLCKit", "${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-https/ffmpegkit.framework/ffmpegkit", "${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-https/libavcodec.framework/libavcodec", "${PODS_XCFRAMEWORKS_BUILD_DIR}/ffmpeg-kit-ios-https/libavdevice.framework/libavdevice", @@ -333,6 +334,7 @@ ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MobileVLCKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ffmpegkit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavcodec.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libavdevice.framework", @@ -358,7 +360,7 @@ 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, 13B07FC11A68108700A75B9A /* main.m in Sources */, B18059E884C0ABDD17F3DC3D /* ExpoModulesProvider.swift in Sources */, - 9B470C0ACF444752B7807218 /* noop-file.swift in Sources */, + 7B8C1837932545C6A7001A29 /* noop-file.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ios/Streamyfin/AppDelegate.mm b/ios/Streamyfin/AppDelegate.mm index 97ea8abc..aef5365a 100644 --- a/ios/Streamyfin/AppDelegate.mm +++ b/ios/Streamyfin/AppDelegate.mm @@ -22,7 +22,6 @@ options.suspendSessionsWhenBackgrounded = true; [GCKCastContext setSharedInstanceWithOptions:options]; [GCKCastContext sharedInstance].useDefaultExpandedMediaControls = true; - #endif // @generated end react-native-google-cast-didFinishLaunchingWithOptions self.moduleName = @"main"; diff --git a/package.json b/package.json index d1dffdb9..6d0e5577 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@jellyfin/sdk": "^0.10.0", "@kesha-antonov/react-native-background-downloader": "^3.2.0", "@react-native-async-storage/async-storage": "1.23.1", + "@react-native-community/netinfo": "11.3.1", "@react-native-menu/menu": "^1.1.2", "@react-navigation/native": "^6.0.2", "@tanstack/react-query": "^5.51.16", @@ -57,6 +58,7 @@ "react-native-url-polyfill": "^2.0.0", "react-native-uuid": "^2.0.2", "react-native-video": "^6.4.3", + "react-native-vlc-media-player": "^1.0.67", "react-native-web": "~0.19.10", "tailwindcss": "3.3.2", "uuid": "^10.0.0", diff --git a/utils/jellyfin.ts b/utils/jellyfin.ts index 4d930dec..2ab20bd8 100644 --- a/utils/jellyfin.ts +++ b/utils/jellyfin.ts @@ -15,7 +15,35 @@ import { useAtom } from "jotai"; import { useCallback, useRef, useState } from "react"; import { runningProcesses } from "./atoms/downloads"; import { iosProfile } from "./device-profiles"; -import { apiAtom } from "@/providers/JellyfinProvider"; +import { FFmpegKit, ReturnCode } from "ffmpeg-kit-react-native"; + +const convertAndReplaceVideo = async (inputUri: string) => { + const tempOutputUri = inputUri.replace(/\.\w+$/, "_temp.mp4"); + + // Strip the file:/// prefix + const inputPath = inputUri.replace("file://", ""); + const tempOutputPath = tempOutputUri.replace("file://", ""); + + const command = `-i ${inputPath} -c:v libx264 -profile:v baseline -level 3.0 -pix_fmt yuv420p -c:a aac -b:a 128k -movflags +faststart ${tempOutputPath}`; + try { + const session = await FFmpegKit.execute(command); + const rc: ReturnCode = await session.getReturnCode(); + if (ReturnCode.isSuccess(rc)) { + console.log("Conversion successful, replacing the original file"); + + await FileSystem.moveAsync({ + from: tempOutputUri, + to: inputUri, + }); + + console.log("Replacement successful"); + } else { + console.log("Conversion failed"); + } + } catch (error) { + console.error("Error during conversion", error); + } +}; export const useDownloadMedia = (api: Api | null, userId?: string | null) => { const [isDownloading, setIsDownloading] = useState(false); @@ -32,41 +60,24 @@ export const useDownloadMedia = (api: Api | null, userId?: string | null) => { return false; } + console.log("MediaSources: ", JSON.stringify(item.MediaSources)); + console.log("MediaStreams: ", JSON.stringify(item.MediaStreams)); + setIsDownloading(true); setError(null); + setProgress({ + item, + progress: 0, + }); const itemId = item.Id; - console.info("Downloading media item", item); - - // const playbackData = await getMediaInfoApi(api!).getPlaybackInfo({ - // itemId, - // userId: userId, - // }); - - // const url = await getStreamUrl({ - // api, - // userId: userId, - // item, - // startTimeTicks: item?.UserData?.PlaybackPositionTicks || 0, - // sessionData: playbackData.data, - // }); - - // if (!url) { - // setError("Could not get stream URL"); - // setIsDownloading(false); - // setProgress(null); - // return false; - // } - try { - const filename = `${itemId}.mp4`; + const filename = `${itemId}`; const fileUri = `${FileSystem.documentDirectory}${filename}`; const url = `${api.basePath}/Items/${itemId}/Download`; - console.info("Starting download of media item from URL", url); - downloadResumableRef.current = FileSystem.createDownloadResumable( url, fileUri, @@ -106,6 +117,8 @@ export const useDownloadMedia = (api: Api | null, userId?: string | null) => { JSON.stringify(updatedFiles) ); + await convertAndReplaceVideo(fileUri); + setIsDownloading(false); setProgress(null); return true;