From 46ead16ef8ad020c99ca017c201df2ef9d0eeed1 Mon Sep 17 00:00:00 2001 From: Mohamed jinas Date: Sun, 7 Jan 2024 16:58:18 +0500 Subject: [PATCH] Add adhadhu support --- .idea/baraveli-news.iml | 48 ++++++- .idea/blade.xml | 121 ++++++++++++++++++ .idea/laravel-idea.xml | 19 +++ .idea/php.xml | 58 ++++++++- .idea/phpunit.xml | 3 +- app/Console/Commands/ScrapeAdhadhuCommand.php | 73 +++++++++++ app/Console/Kernel.php | 5 + app/Services/AdhadhuService.php | 29 +++++ app/Services/Feeds/AdhadhuFeed.php | 82 ++++++++++++ app/Services/Scrapers/AdhadhuScraper.php | 65 ++++++++++ public/images/source/adhadhu.jpg | Bin 0 -> 19798 bytes 11 files changed, 497 insertions(+), 6 deletions(-) create mode 100644 .idea/blade.xml create mode 100644 .idea/laravel-idea.xml create mode 100644 app/Console/Commands/ScrapeAdhadhuCommand.php create mode 100644 app/Services/AdhadhuService.php create mode 100644 app/Services/Feeds/AdhadhuFeed.php create mode 100644 app/Services/Scrapers/AdhadhuScraper.php create mode 100644 public/images/source/adhadhu.jpg diff --git a/.idea/baraveli-news.iml b/.idea/baraveli-news.iml index 8d45442..7993b0b 100644 --- a/.idea/baraveli-news.iml +++ b/.idea/baraveli-news.iml @@ -2,11 +2,10 @@ - - - + + @@ -116,6 +115,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.idea/blade.xml b/.idea/blade.xml new file mode 100644 index 0000000..552879b --- /dev/null +++ b/.idea/blade.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/laravel-idea.xml b/.idea/laravel-idea.xml new file mode 100644 index 0000000..29d6b2e --- /dev/null +++ b/.idea/laravel-idea.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml index 8580406..594c763 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -1,5 +1,15 @@ + + + + + + @@ -111,12 +121,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + \ No newline at end of file diff --git a/.idea/phpunit.xml b/.idea/phpunit.xml index 0e6ddb0..4f8104c 100644 --- a/.idea/phpunit.xml +++ b/.idea/phpunit.xml @@ -3,8 +3,7 @@ diff --git a/app/Console/Commands/ScrapeAdhadhuCommand.php b/app/Console/Commands/ScrapeAdhadhuCommand.php new file mode 100644 index 0000000..6d3919d --- /dev/null +++ b/app/Console/Commands/ScrapeAdhadhuCommand.php @@ -0,0 +1,73 @@ +first(); + + $articles = (new AdhadhuService)->scrape(); + + foreach ($articles as $article) { + $articleModel = $source->articles()->updateOrCreate( + ["guid" => $article["guid"]], + [ + "title" => $article["title"], + "url" => $article["url"], + "author" => $article["author"], + "featured_image" => $article["image"], + "body" => $article["content"], + "published_date" => $article["date"], + "meta" => [ + "title" => $article["og_title"] + ] + ] + ); + + collect($article["topics"])->each(function ($topic) use ($articleModel) { + $topicModel = Topic::firstOrCreate(["slug" => $topic["slug"]], ["name" => $topic["name"]]); + + $topicModel->articles()->syncWithoutDetaching($articleModel); + }); + } + + return 0; + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 096723c..b1b87ca 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -101,8 +101,13 @@ class Kernel extends ConsoleKernel $schedule->command('scrape:dhiyares')->everyFiveMinutes() ->runInBackground() ->pingOnSuccess(config('app.url') . "/api/ping/dhiyares"); + + $schedule->command('scrape:adhadhu')->everyFiveMinutes() + ->runInBackground() + ->pingOnSuccess(config('app.url') . "/api/ping/adhadhu"); } + /** * Register the commands for the application. * diff --git a/app/Services/AdhadhuService.php b/app/Services/AdhadhuService.php new file mode 100644 index 0000000..4bb0574 --- /dev/null +++ b/app/Services/AdhadhuService.php @@ -0,0 +1,29 @@ +get(); + + $articleItems = []; + foreach ($articles as $article) { + $scrapedData = (new AdhadhuScraper)->extract($article["link"], $article["date"]); + if ($scrapedData !== null) { + $articleItems[] = $scrapedData; + } + } + + return $articleItems; + } +} diff --git a/app/Services/Feeds/AdhadhuFeed.php b/app/Services/Feeds/AdhadhuFeed.php new file mode 100644 index 0000000..114ae2f --- /dev/null +++ b/app/Services/Feeds/AdhadhuFeed.php @@ -0,0 +1,82 @@ +client = new Client(); + } + + /** + * Return the latest articles from Adhadhu + * + * @return array + */ + public function get(): array + { + $crawler = $this->client->request('GET', "https://adhadhu.com/category/News"); + + $feeds = []; + + // Parse the news articles + $crawler->filter('div.category-news div.row div.list a.item, div.category-news div.row div.list a')->each(function ($node) use (&$feeds) { + // Extract the details of each article + $title = $node->filter('h4')->text(); + $link = $node->attr('href'); + $timeText = $node->filter('p.font-11')->text(); + // Extract the time and convert it to a Carbon instance + $date = $this->extractDate($timeText); + + $feeds[] = [ + "title" => trim($title), + "link" => "https://adhadhu.com" . $link, + "date" => $date + ]; + }); + + + return $feeds; + } + + /** + * Extract and format the date from the text + * + * @param string $timeText + * @return string + */ + protected function extractDate($timeText) + { + // A simple regex to extract numbers and time units (e.g., "minutes", "hours") + if (preg_match('/(\d+)\s*(minute|hour|day|second)s?/', $timeText, $matches)) { + $number = $matches[1]; + $unit = $matches[2]; + + // Use Carbon's sub method to subtract the time + switch ($unit) { + case 'minute': + return Carbon::now()->subMinutes($number)->format('Y-m-d H:i:s'); + case 'hour': + return Carbon::now()->subHours($number)->format('Y-m-d H:i:s'); + case 'day': + return Carbon::now()->subDays($number)->format('Y-m-d H:i:s'); + case 'second': + return Carbon::now()->subSeconds($number)->format('Y-m-d H:i:s'); + default: + // Handle unexpected time unit + return Carbon::now()->format('Y-m-d H:i:s'); + } + } else { + // Default to current time if parsing fails + return Carbon::now()->format('Y-m-d H:i:s'); + } + } + +} + diff --git a/app/Services/Scrapers/AdhadhuScraper.php b/app/Services/Scrapers/AdhadhuScraper.php new file mode 100644 index 0000000..52125d5 --- /dev/null +++ b/app/Services/Scrapers/AdhadhuScraper.php @@ -0,0 +1,65 @@ +client = new Client; + } + + public function extract($url, $date = null) + { + $crawler = $this->client->request('GET', $url); + + // Extract title + $this->title = $crawler->filter('h1.font-52')->first()->text(); + + // Extract image URL + $this->image = $crawler->filter('img.img-fluid.hero-img')->first()->attr('src'); + + // Extract author name + $this->author = $crawler->filter('.MuiAvatar-circle img')->first()->attr('alt'); + + // Extract content + $crawler->filter('.body > p')->each(function ($node) { + $this->content[] = $node->text(); + }); + + // Extract topics (tags) + $crawler->filter('a[href^="/tags/"]')->each(function ($node) { + $href = $node->attr('href'); + $slug = basename($href); // Extracts the last segment of the URL + + $this->topics[] = [ + "name" => trim($node->filter('.tag')->first()->text()), + "slug" => Str::slug($slug) + ]; + }); + + return [ + 'source' => 'Adhadhu', + 'title' => $this->title, + 'og_title' => $crawler->filter('meta[property*="og:title"]')->first()->attr('content'), + 'image' => $this->image, + 'content' => $this->content, + 'url' => $url, + 'date' => $date, + 'guid' => str_replace("https://adhadhu.com/news/","",$url), + 'author' => $this->author, + 'topics' => $this->topics + ]; + } +} diff --git a/public/images/source/adhadhu.jpg b/public/images/source/adhadhu.jpg new file mode 100644 index 0000000000000000000000000000000000000000..98e7321908b1af6fc2509fc64dea4e940b21d3ac GIT binary patch literal 19798 zcmeIZc~qKL*EdXRo21QDOkT|6mbC2C~+1MaYpo|&#<2N{_f|G=f1yhed~SK>SkT*OkCHw z_K$t`*=O&~!RWzTz{j_oZaM)D9RdIjDL#OMDS(kp!D9~(b0cz9XWFNKWcxr4}YMz{wzQG;DaMaKm72+_dYmw z;-jM{4j=vS=pm)|-~Zr)!yg_#{Nd4mi4J}TC?8e&LGd}H3wTfYkdpGDgARa};=SK{ zPw7v-{*#V=c<9J`9~^#PNippHv4UGArT3IRQ2OBb`yZb8ll}LU-v8jR@{v!Do_13K zelfMGs(bH4y{l1A)YL)O?*vAF_iOFTfeSajuRC)M>W+$g_)Ej5<_;b~F;AbB)^oTL zQ^iv?71RAW=l?dTV!k6sl@7h97`>sa7(MhS8Xq23I;!;NYyCN=@&}(BJ`McB?cUX> z@1E2iQPEXQ_Up?5z3A^tr&b^SB2fjI-hiU&>eb5H4|ss%N{WXlD=7o)0ob>O*_{7m z?yvGM1pY$cF9iNV;4cLJe?s6r_$TWNJUFom?nYQRk4z<3_@?1LGabK7rrF73_=I=U z_q-_d%R5U1n+*r(R_m&rONW!RTdyqus5O_CUa(Fukd>akLG*twajIpu%k^CsClN*P zWtgwPnra+-)7IR;G5+<>Lup2Y4P48BPU40NFA06qHfzUf_lsW#vM>pYg*hp3PUPdN zux8UBAtFP;Dp`yLgO3G0@Y>!y@Jg|ze~V4g$|i{oA_g8Y!tGO;qHdyDkBB- z1ugj?1>I%MD(l)w{l%P$x@f7rBe{X_Bn}OB^2ydzb>#d%8uvKv`;i+ z7aSR|Rcd4~GO3TQAKb$J1-}N@)e|V|kUkL|09Znq$DX}|KIEy%r;*O;CCv6;FmkoX zxZe%ZkHvtaN=3)^ob6mv76OBJD{EYc1^cu@u8rpQ&x53lU;?hBY!YjZEhrzyj?6X} zMAq?r;TZ;#j-cHI>{?2R4wfFVor<+eelGbEUk0%aR&5(Q%ljqRElJDx@%g@J0k8R-}Vov!CMqinU zIRKn;9ExN`K*Aq97$xB?K%k(LeUtUjiJ(bD%B!s*o!2#JZc9;HLF{{E4w7A{<1jJ$ zRO-9Kyx#hn;HD}Zn8ELSxCOjY+T-6>y@>Bd`^5NJPFZD@U6_2IEx#r9I{+l+ApOx9 ztn63U%nj}&+iqZ9Y$5w4V~M%N=9wJ$@YG-kW#5c_FN`l>2HAg9P@{9&*n!>fnuf48 z8-jt|JKcaVwbZN_m`le2z-dOMGhpbCd|W?A1A^On==R9%%hx|`y!KkA8mnWIU1W@c zLp%5XztIOBTxB*$xdR0P>73+%Kr7jB>xU-n2vHWRg<1q|rJCA8zFA73cAn+Ib2I&7 z+0+7ppr_>S+H_E#dvB6YJy@H10~4RT3T~s*&KBmx_4~Jv#s%}nUUzrlsSg~IVG+R7t+UFCZ5B>uI;Gd5SM+lbq1eW`oj~%|Vy1_&Uk{gRCFDJr zq(se=g7V7>3NnJ8rJne74TUcYI48opr$!{PtR9q2Nw57T!kb3tSMB%bY>Bn%wKi(( z7I58KF{rf|#JTmrFkAQtd9Z54#ZNvb%50n!Ptw5M5eVK!xBi6IJSm>UB_SQQrW;-_ z900zgM-7f2z~#=UApl6M=CIxBHD`~IO@H%1*C&}q|p z4Gx$elFxysIYQPv%l_P){bXg?HeP31^H%WO8U)JFO3l8ue^$ir5`-nxDy!~4c0k#% zm34HIH@EAK=f?lXkEfHn=NnG8s9n44%?#2XAA41c7J$G}=!|Ls^$DVBZIWufNYclZ z1_oA!m{8*N=h@JS-D#)m$*bI4s-GIPVQpQ5bC8FfV z`Ee>zWabu~5k{aV=W^VgO{${f>VwMcslo3%%M&-3T7_@|q)Pn)h?frKSI_I0ZDT7JBa zE!+Q8ufBh1W-Ey5)jkxfL9iCSko~kjI_a(Mky*hnAZyRWND&*RQT7poD3LVMT0Mj` zE+3o4hbp^6ZQ6TE;rf;k{mIT}1)=AFJYyfH4Jur}UKhm-h%*Da3BeGj3bE2V& z$5FnUUQke6s%zQX%f6VFjRK8sueV--j+klM>N#oqbwHraJQsq@iRs=gXe_)DN-&8^uI(O64s6{Z zN`06i69%e2r2-&WwbPWN?H#CVpUJ~1wo0h-Di-zgr?}^T2fFs{O0COdT6g(*n_XLP zB-9kEcQW5Z(sbdour(OCN(8dXNZvjd(<@bj@|p3u58|<_l`V-UDkiuPra{ul8ZHTVRHgy$?ALwn#+Nzb*#h%O$zP}T_%$Xy#UTwi`*QQsD zuq@1H;*2sPW+3w}9Auk5**~OD2OFBrQ9J>EbH?{|_Na(UGu+>4f3c1En6tF%=|-e^ zKie8kS_)Zdh+~n0;`0jt(wl#W+dthn4s&;Kk+PI~d-oNWWc96%e{MO#d$W=_k26}VQ)%hl{19`$D zEj?4Umy=lB{6avoEc+<4R>d!BVkQPhW&V{&fyv^e|qzU*1*Ar|VJVh4W)UyYz=Vz=bk zWnH=2oS7D!qqx6t2F1 zom6ZtFu%WY3bRUXol9B?H*Bs&oA_C(z{QB@x@s<1ZhbpVD9wLnlwmS16e74Py}nOV zc^aNRlRm^R#$+h?Gxct-39*_mP5g(GCK4(c?ub3Kzlzj8AX zLqnVVh{V>-H$^$Q2Gr5i0vK^p+)tHxe)PcTt0wpRP_yKMH4f5JRwdUyRn#V(AEEUp zl}Yi7BPk$ZPWw6&n1Svq(bo-X%$FHs4Dn9&!r}Zm&);YcJ_JL;pF);~g~T`{>#atA z@TC90LuAmQ8spY)=VXg3Qy0PdY&Z|2OCo&J#HIn{ z>^&nL-!~f(wbckloZm|(VaduQ#T!n1nB&mtvDDsdUUzu}vb4rVCi!MBb$%}H)_Bu> z+4JGBp!qw;CJNoub}LdlvvqGncH&4tGXxiilb1(fJ)h~}8=x?#ox3aJutfTVuhmwg z6Wl(;lOGo5JhYG<_L7%)O{%hodNxzMtj%Rf5eqKQR~^#y_x?MM{)c@9Z&PsknH4MG zu$z3IZDHPqU!+^vEsls!Mb|JZ?)!AsqRAd1I8wc1TuQmGgT&PqwVIL|5mM#SD^k|z zW#4x|cO&*)v$LUzE6m}PV0EKRH7*q$*GSVo02q_$`!$HdhNS6?+G@9G{Ep9R2~g9) zA*qZOoVx(;;?N^FB4X`&kNNVnsPBByhnZ%cKv)!nI#d@*dFLoQ>{LX65E6fd2QSY-$YWDK1<~TU8mCfEwk}eV~@sH`4 z?a#+_b_LV}zz+8M0btW8X2S2zqVrdEYbXoC);Qy*mTuh%@M8f)*BGWA7)k|utE;&O zIyiz@VGzAd8~dG-GY0^rM+bnnPHg45?v|FhU328A9DJE9!gW}j5xC@G3k@3%9^qo| zNPklpW9}>>2;ASn?ojNMMOBvz)du=B6Dnn{#@!WCXCNP+xpXJ{)nf2hRuRQn72y#A zN(7^c3iha7-{Y6Cr0Yr66Pz1Nvp|1b_2w)YYAbVr#Qw1DB`GAvJ~Yq?itJ4`ZXL3u znuU&?EkQ&{<+&igMN?TE#bsf)&(s+gH5<%Uo+Tv6p5#38amnE}#0E3|NNF=-Ys~xC zKN>_$Hw1V3&2rQhC!TB)3i~(GM7Um2zv3tyQ+_r*ee3Fzu-_E!cTVI9a+x@yo)Te; z(Z1Rc(Oy3C0%2~M4KG?!^P-Sp2LLitJ0zcE%Ym58JbIm0az{S6SzgL5NLNrcR7G<- zsQ=SjT3?RRYg}j(bE9-FXj9Zo;(jOE%XRQ8y@Xqr-`2*-!D+_h{Cc>u17FS~P zl&0M}V(wBk=^TH`m)Xm?GZ+u)dZ}IS?@BLi{!3i{$=U_>y92<&5OTj>AZU(XpWx7= zUbt2xo0+~~ODi^&6Js=u3z81EvCfNuAn}@>Da!`BB8BAPM}V3K07S370i}zGT)!R% zTQYS*9stHI%#z{=lWIv?SA)L%y^~Uz4bMPD#hx!yoO|J+h9f=NzH$LRyF1|a2Is|8 zfmJ=VPV^I##SAzAP)we>cR*dB+Vk0Z%okDO`|5F@{TDaevBhDx_&k3!wR-WIw`&eT z=nDU}5@BgxK|^Mm?oi%6xIaNMtViex6)rPR)#%X8Yg{M@kwG)5MCt>{nY97CwoRnAa2J^R zPP#MpbcuDW--so{qU@X{U41;Cta4`}$7KMcuTQTa4X49r>>@O7lO}h&g*@(@u*X@m z*Oo$B@$~DVjzrIN&x(5TE>Ym{=2=D_a-4)qwdy9#1*s|6QC8MHo&EBwFM|aQ6=qo|@y%`QtBpulihn<0t zB?e79Kot$hwcMBS-z)=LVu)o=U~%~XWgAPJ{jbDRo#Z~Z=8 zYz`@6so1vWEMZ5e-6_46|gZqtSyB?N4BMXWvbrdxwz}=?XBn?$RU7~wy;L~>KrgU%!n_Uu zY)SMX)4~5_Ny#ggUBfW=RRbQ|+VjLRk#HZ}suVuuOB2;0O07F_mr8)YRg!yVnE?VK z-s{oqa7Nc=ap}49DRzFYx2D>?TE*5L)U4TH*&IkAmu!RQivjNFfSc%k|D}oD&f-fh ztUW;?s&~BAcfgF#S#L42+eAjVv*tNkWi1kAqn8rp>CD89C3j}JpXcW0%dYNCoa;dC z6OdYx5pj9a0w)7M($+c7l+R~?{YR^eUIZ$AmoZ2}9 z(TJZM^D9f4nwS}mEC4QF5-6p;IP`(&TVw@T}BPjdO|=qq>@AO(5<`kX|rL2 zbp~FgjPayJnc8k>I{rtSWc80Sbe;wyg^RXl2jfma-5*30&%rOVs*sjs=We{hEna%p zyL+S7rzdm^vOpIOXgT*r`Kkz#TrCd(r|a+Thmsn*48<;~1X!NipUnPCWO3?;6Gr>h z)Ar?(KwS(fwwqcw-m#yJFAwH3+@n@XqDA}MCZB9$KK7Qb{R7}fj6MA3d`*Y{r!c4* z4EtMs4R6+#1NKSfnz5uUc@&l`%n7o(EiYncF)yMvP9(1f8(j!Jaso*=QY8rD3g6zNSNC68ExQKkcs#OWYO z((sdE+Qpyzb8Z%TK5P2SBQmL_QLwMbCw7=yaZs8`>dFMY%c;H^p(gcP zYH>7$s(^xzxV96L>8Ztzpic7&k-`j4?pd4Q^HCcbsKvtecm!>uILVVKs;d*D(=rk= z&&JO`>9&Wpo)mBYuzc5gpjT5*T}qYm>_c;q>}K#z zr{0)F33``Waaecy-?15MI~y)wPV1G$jFpme!Z2R1npIi!!fUu9L9=~d8U@d5x{Y}` zAU}ElK&$z^b%t~e*?bv6uZu|XjuA8$kb_vM+_zH;!xAK{11%JJdX#IG>T&8Yk63RC zWRp)VWi!XF_ylC&gWpfJyqfy>+oy;(3Nx&%C1l>*Z1SYv&BB(1bz5Bv$Lt^>tuA5~ z+OcOeO)u=MO!hngbh4`s02`sIw4J)E z@7=8aH!(a+mK+)Bt9g@BoaD_#(C|%W=Mh~z88Wk0?VT?n+qV1_A)&UMPa?q?ZN+6R zn|uC}FAII1-Y@_YdMbN-uZ3B(&LM`a;h2lrV+AwH{RvhF0OkD)XoXm}+<%vJA|Nr$ z!>BAYBBZrrywKMz&SPjcU3yO>^SnfxZRR0xr5QP<`|=%<>wu#Gp`;;!6@^RH>yLYKw44{sFi56Ty3 zlN+E2#A93g_t-Xpp^epCnBtCx1QI?a)@A+HaG9GW@sHXuouZvREzm%J_SDo_T5(N@ zMCMYWCBGGa$AF)Z-5~cKQc{ir0Oa-dN7L|FMjAG`7Q|Yfo76cv3x}r+sCKaJPoB>C zgZ0qXhr|t)i7TF6UH317?Z~Ym>CKL!>xN{kxy>dS@&+Cl#NQ;f?fdIx%yG1>@0U~u zCG5-Gik#CHno`fPD;hj%$2O~Nxm9tzWLp$SSq1nu@z7LROl+x0-dXG?sO4y#tYkLD zWjmH|p+wF(?~=n4rAldVcN91mrx@mM4+;I0I)U)@#=U3vUpH4;XlfW>AqNc zd6bI8ZS?l~CWcN|d4D#W33F}>hNYLl;jnZUN1(DxLTK9B0OSQ!8La9&rRoTjLsFcq zrt@E*^0P#CD8cgH8(Xbu?-D~_dhe5=c8i@>J9`G?)+W9>%%wAKIlHPuVF$lD?$~kI z-~b@rh{G?Zzu&iqD-4`zPtTQKBL(>Hp+91}6cHHl^Z{TDc7wg(DOc=7iPtf= zmj1B%<(wMH`X5+$>(c>w&ol&M-Zg=wAY+iAJtBj$}T9C z0o)%lIXv#-Q))1&8fDK_R?(q4%fg^!$8koSC!v{U1!n}=g%RM_9)o>8+So0v*n*5z zwlK0l);dtmDpm8AoTC40rfaHkzhI${>I%+i!p50X24v7=tMO{>D7yo|dI7IeREI{$(pl2GW6cPia$9@=4GSp3LoZGJP>T2&A-ciFyo(3Ug2cI89Qg-hS(nq zW7#sjWrtqTsWZc=brIU>;k|tVdYuuu$Ns^7Uri~Hv+G-z4@To63p*05p=hAd>fU+6a3}%y1 zsy7gyxs+W!g8X$+BV*Q)XHNN`yFs2?p0JV-F-l5rFjp`{xrU~dv4M65nV z&aL(+jqV?qX9eT&^9%kN>&T)j#~<`)EJk}SxEug_s-!#g9eK03#I0NJo8xNhfW!K! z%3{1EKkWdpNXl0nHf`^9XPEdmBl~cd7-&%xQb3O3fT)lW*Owc{Q;G;djn^}!;+qHyOU|L6*#6v=0u^}7HO6=n_;^; z)#wu&CMuc#A}SR~n2I+rPnfgr1hUG1nNVAkd6dAgwx!7wsUfgKan?5Uf z*Co)hGNZULKU+>#33HJ)j?dNUo{J|f`EJli^lUP5lHu`&-_Sofwn-*bNPSog z-`OzF%QA$*jpKTMoOFqZH6zE5cevbkt#xs54oRD1Dl5wr=>$5D-gY;Kfe8_|_15%& zo8_G^+Fj0;A%dzrY8Sc~)yV;ake5#0-2I7IibaYE@h2R3P2 zRg|JPIzeb61j#|!_m(npk{pBDFeeWHFO@r~8*f6dE=JJayyy!|65CX2^Ie?DxOVij z@!xqG!I7c}6Ma)rbE)^6-xAWqu6d8bPWQ!jV5)Et4!wKu2mD%PR>*^hH2zad^W zyg>{Cf$Tswv!Ck({H(B0wD#hcyv{p60&^m@Yc7XbQA{2_(PSsaMtEPIETb`T5v<6U zx*xOGo*}K9l2nMYz+p#Vq@O@-@m%}>u(#_+0yO7QVnw=L8+*Vm7nNL1aWJ18Ok*-e7Ke~?A zVzf89;prn+E9xzQewDM=Xz-?O#X8OcPZNV5M3#KNp?970TP2&zOrkDY*`_zUK&XR+ z$Kzp7J$)s!ndmwLY-YQSi?C79>h-5dSUciJY=k(0rVAsx&6h@scAUd^jLtOla+O&) zN}!&kARjvl1jqPdZJTEWm?E0}k8CCqvjV$qR9FK5MAMKWS!3<8PjjMt=?S8*&=dx8 zA17U;A-HtC!aV(EMI0cx=P}B?)3ieo5K~sR*B(%4o|4tyY7XyzTrsv8Gf}x=0nXS$ zJ2v(5tx@Jfm|vmjG)jM2#VEyI`aL<;p;Ki~)dh1-{79{iPYwv*zOIxNRc!y!OUpWG zgZQkZLw@<$D)uP08rjWy-0QI4_HnY7*O+<33Sr|0goa7*r=3f}M9laQLSJS+?ewUR zJr?VHChqtE(9TPQFc>M(S9r&xbOPosI5;zw_GWSm)s3cWJle*@1(LkaBz6Xs(_V9S zrTpHt3|85#Est7(LT}C~1YVbkG0b|*i?hFdHH?Hot;~C=11t0QZ69Y^fZ+DUn@OYi zI`#LlC8oQVin%LKxtPdlC;#Qq9T-yU%=rSW8PBM8X2kSy0x4eRIPPPP$WFZ$rM+9? zO$SR{6iMUFmj)u>wgxKgIhQ-`z=sMU4-(g@y6~h@V_?gc(_+ns1d)M_8H}k zzLuNv3ZLwkzJ52^S@{pt7mq@AUW;e6DLaZxrIhLuoPN-`x{)t3;wXko5Av6b7!hjw zM++v!-a(C3-{v8{`g2nc3{ERp&xV!nI4DxSBC8Y8W3_(%><1$2c(0g*=^$QM-kf)4 zt+GA3W?Z%zD%>Go?0H4Y%u3SV@V|X+b5_oip)=JNTchE@0`1$ehH)erZ|;s&UMsCL z&Sbp4X-i9RLy7O47%nemc-t9A*)7nB90Y#T&G)+O&LyF>OmDZ>Jn!{>c63-|MgGhq z?E!nt1(8nAnS{?jHu>()7yOqi)W4YCGUU+P!KN#GVxUf6XClx9Y&dm>w7FY75Ydd! zL60xVkl2Y5VZF0*XP<6o;oWA{0TBDQW}@qb9pa?B@A|VPpUU{wz=27P=3`#vuV1ip z4u8oT6(b;Z=m{HQqs@y$vU}eG_Qc+$a+1im6gN-7e;VWI;^G2R0V_(`JWg@m7_3bF z)~LPn0PvFtT9(ANK+VTnM8@#Z2vFXO*|Ac1kxw&qSYT^*@oGh zi_T3Yp5HZ_5C6zmx4j*);&WZqc||gV$(olsIFdG_XRff-JyB zt875mz5y>Uw|c%vBK05E;vrrU5i9g)@>;JC)%>%D>eSBE_*%2h9h}rg+UGX;!^two zkdnr069$Yn`@4HS{IXUv4qq*1@4CR{X?7Jnzo2~D+DaB_#(dlx8{7yt_~lqFXv1E( zeIeEUTODPKy31azga{iS3lo`jGc5ABQE9#us*)P+)tONP?daVJ6>niw^XIR8+lS{w zK$K#|^6Opu0xP65uVMUdN3)X}t{Uu?RS@aYO+q3P8sxmvXgDd9ghLQ?Lw_1ahjLDPAps(0@`K{tQ; z+}&@cDMlMXe7mc2*~XnzO^BPNl$~p+oo%({!7SSBmHvFBPBoAeSTTL?XJzM(N8eQ| zRgM)f*u-;ZeVh|#V3y|z_(Va#gI*FTuqHBk*ar1tk?X0Jik=iukSKTb%u$QHN3OJR z&BAS2CP7w`X>NZTI=C(?I4hkI_q7Ir(`f;r*#nDB!}|I7wVhk`CYf4u@w=dzu@$+7 z(huvLv=GCyk!tMhT56EKB$4%lzokfPAf$1i!D&Fl@Y1bO>m|Q#nRd83MkRW(@17@z$68Ig?&>tv zMy-X^Q^ZM_7J<6J(xO6f{xI?pdiS?edQl?DIyNGX8A&HqYzVRKOOm|xEe_yqL4?*L$u61yjqZZ*_E;xDgFUn~2g zU~>z4VPCaje-3y3TU_YZ{|(#ci5#X0ymS6Xx@g*W z6SQY;i_>RtJ20m^!Nlkp^-2?9NeZf*&Yw1D*)=Nby5euNWPbtk;2ZVo7|<@cg9Bt8Zg@nw^t3|yP zcX0hw$4AWDmRnQjz+0}qDfAf-=$ZwE3uYu`aPb>WYR;+?r6qf*C^496?D5^ByexcH z5a^`5s>qiNe1d%vIAaEdSyW^`i}YeRNYGr5#q^A_$I-N4r}a#!doyDJjNB#m~%Bk$?{bE1UMEhV1!oyZ~2sf0FlNaF#nmIc`?yFQo?B zfu@u-XBBZ=7xqO2L@V`z@p5bHlR@yW6;X^hk5f6(4}v^3rvqm=rX$!hhWn@7dT1g= zKBNR`0ukVi=z5B%YR#%hlid}MR@if4Nlbq(&Fs8Y1*@uhfSKGZ>eFXi+mGKT+SW zZ)@a3=awvBW4a{P9lcks_btVVd|Kf%j7G}98Dl@HA4uhlVa7Z~&>fsHkJH!Jx0PHO z@X=OnfzQRTmNgXHpBJv=_su8R^04|dNI%Z>Ocdl7k#b+(4I~HDI{+~o(A){EiDtzJ zAg;roMVZ+eSf7G&P|HppCx0c*cr_zuEGjdW-%URdj+ovTa$Q(z9FR(P&qLejE(w29 zTZhxvTNL))Vv}oRVUNaO+)hiaj+11^+m0Gsl%R-24k>-=_xEU?$8_kVgLB@1KQdX2 zt5$?D?{pUO>RI9icG3p_bVDUKNvd^k3;Wj@2)tiGWitP(CNy4~Qo+%q&V zOH?_nh$!rhx;v}+z9!i;E^LrU7fBUXzYdAUxFTU?q@S?R)wQhHu1DiEtHd~nPlG`- zUo3cBB1^BSLOofnP>}mp$tOem6_F=vR(b`(R&aKrMQi6P`V|>A(w$yW>l05PA=uHr zL;lfr8vcrALxp^JxJvBByZ4AZ@OC(`$a3LKIU~&eY{_W;N`8L+N^Z}3UUiDylHEfm zT3u{!GEd}9sP=SX!c5-*IX8)A>RjY~z@l<3i@pKlG zXHua;fjzOkuk_m77aLYy zMRa3nplA`(_ad=O{w`tIYBH|X?8wWqFr3pgC(5k&81(mH)1oE+$y0YYSC_|WzOa?% zAOr16!i>&4*Lr+h6@8(hh_=jp#Xu5OPGql!LjY%4GobT^B1o9cZ-hYV|thUucd^^370Wl#npV-qgx;h6`;+xUzA5v3wbUtN1j0p(n)Hn9to6z1HNzV{%=`~6hXP6Pc8rXapzrasA{a9W$ zn7M6Tp8y4A<<(Y?<%$r`n+u+(1L_EJXQ?kk9iR$znnuVcT*D@_eONU$_Owa+8oc@G27)+|kcW=j!IR8<*@r~0~{%%4?$cShJE1q4-n{m+Z?Kir|BDaU-P zG`2oj)e2tFkM-goK_jd*{mASbBI*oqgW9Sz?)CE0X%L+4$C_Jpz`57hff9eM z+7-Flgu%eRR!8$3OAE96boZRzcG)1GenmZP)z9hGA|67=KJq}n638&oqcnFP=6Mfd zmLjtly}(ch0b3;g<_?PgnLDt6HtpPmvW?Ux{7UZmuY>0nyqb2i^9u8bh-NsYmDtGqFG8ot68uZT_=ZK+Py7En=3gmhAT z0okpC5;0Cy-V1?`c>Xl$tvAv$UA|~#*!2x$kTWqL#D+iF%L&DXUw1w6Mb`9Wdp0aH zZei(gCoA*mPU}yp^YfOvE zY;$dnrrKHUZ$u&4%D1;|M3wFSeCK+6dko=Zwj_N2r$P%m*_}|GS*C}*YRjzNw^~Rxv&VUi>wU4QK~^(WMTP4u zNgy2rj|wZX$G!1cs`m3(^z&q<^2JeM`83)1;8K5cq)x+5Y3Q5ZNQ6$6S)l;(GClQ^ zY}>O1dwLst>H?k5uVs6s4+UtS-|9L5SYl$)HPWgYlJ?a^9gbDB#AGE?gB-xh5IKF< zU_)EVkc7&b60=hZHqU?BO+iZoNl~W?|S@&lyC+( zFu8WujzaSe>fBX?gAtaVQtI)lqVaJ?J?0X~MBcrm$a^#MWngqSpcW=zCAYL-Scmb?; VUr!Ey{_o>|4gAZHyaF7I{V&IhY()S7 literal 0 HcmV?d00001