From df3f47c79a3b81c0d1e8bbd9cfcc3899cd5c45a2 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Fri, 17 Mar 2017 13:51:45 -0400 Subject: [PATCH] Add a RepositorySearchScore table and calculation to the RAC worker This will be used in a followup PR to order search results instead of the RAC join. Currently, the join with the RAC table in search results in a lookup of ~600K rows, which causes searching to take ~6s. This PR denormalizes the data we need, as well as allowing us to score based on a wider band (6 months vs the current 1 week). --- data/database.py | 14 ++- ...4525c86_add_repositorysearchscore_table.py | 35 ++++++ data/model/__init__.py | 1 + data/model/repository.py | 3 +- data/model/repositoryactioncount.py | 118 ++++++++++++++++++ data/model/test/test_repositoryactioncount.py | 38 ++++++ initdb.py | 9 +- test/data/test.db | Bin 1654784 -> 1667072 bytes workers/repositoryactioncounter.py | 65 ++++------ workers/test/test_repositoryactioncounter.py | 10 ++ 10 files changed, 243 insertions(+), 50 deletions(-) create mode 100644 data/migrations/versions/f30984525c86_add_repositorysearchscore_table.py create mode 100644 data/model/repositoryactioncount.py create mode 100644 data/model/test/test_repositoryactioncount.py create mode 100644 workers/test/test_repositoryactioncounter.py diff --git a/data/database.py b/data/database.py index 8a7a87004..caf4f560b 100644 --- a/data/database.py +++ b/data/database.py @@ -451,8 +451,8 @@ class User(BaseModel): TagManifest, AccessToken, OAuthAccessToken, BlobUpload, RepositoryNotification, OAuthAuthorizationCode, RepositoryActionCount, TagManifestLabel, Tag, - ManifestLabel, BlobUploading, TeamSync} | beta_classes - + ManifestLabel, BlobUploading, TeamSync, + RepositorySearchScore} | beta_classes delete_instance_filtered(self, User, delete_nullable, skip_transitive_deletes) @@ -584,10 +584,18 @@ class Repository(BaseModel): # These models don't need to use transitive deletes, because the referenced objects # are cleaned up directly skip_transitive_deletes = {RepositoryTag, RepositoryBuild, RepositoryBuildTrigger, BlobUpload, - Image, TagManifest, TagManifestLabel, Label, DerivedStorageForImage} | beta_classes + Image, TagManifest, TagManifestLabel, Label, DerivedStorageForImage, + RepositorySearchScore} | beta_classes + delete_instance_filtered(self, Repository, delete_nullable, skip_transitive_deletes) +class RepositorySearchScore(BaseModel): + repository = ForeignKeyField(Repository, unique=True) + score = BigIntegerField(index=True, default=0) + last_updated = DateTimeField(null=True) + + class Star(BaseModel): user = ForeignKeyField(User) repository = ForeignKeyField(Repository) diff --git a/data/migrations/versions/f30984525c86_add_repositorysearchscore_table.py b/data/migrations/versions/f30984525c86_add_repositorysearchscore_table.py new file mode 100644 index 000000000..48795acff --- /dev/null +++ b/data/migrations/versions/f30984525c86_add_repositorysearchscore_table.py @@ -0,0 +1,35 @@ +"""Add RepositorySearchScore table + +Revision ID: f30984525c86 +Revises: be8d1c402ce0 +Create Date: 2017-04-04 14:30:13.270728 + +""" + +# revision identifiers, used by Alembic. +revision = 'f30984525c86' +down_revision = 'be8d1c402ce0' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import mysql + +def upgrade(tables): + ### commands auto generated by Alembic - please adjust! ### + op.create_table('repositorysearchscore', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('repository_id', sa.Integer(), nullable=False), + sa.Column('score', sa.BigInteger(), nullable=False), + sa.Column('last_updated', sa.DateTime(), nullable=True), + sa.ForeignKeyConstraint(['repository_id'], ['repository.id'], name=op.f('fk_repositorysearchscore_repository_id_repository')), + sa.PrimaryKeyConstraint('id', name=op.f('pk_repositorysearchscore')) + ) + op.create_index('repositorysearchscore_repository_id', 'repositorysearchscore', ['repository_id'], unique=True) + op.create_index('repositorysearchscore_score', 'repositorysearchscore', ['score'], unique=False) + ### end Alembic commands ### + + +def downgrade(tables): + ### commands auto generated by Alembic - please adjust! ### + op.drop_table('repositorysearchscore') + ### end Alembic commands ### diff --git a/data/model/__init__.py b/data/model/__init__.py index 09521f9e4..41a5bbf80 100644 --- a/data/model/__init__.py +++ b/data/model/__init__.py @@ -133,6 +133,7 @@ from data.model import ( oauth, organization, permission, + repositoryactioncount, release, repository, service_keys, diff --git a/data/model/repository.py b/data/model/repository.py index 17404554b..3253e7aa0 100644 --- a/data/model/repository.py +++ b/data/model/repository.py @@ -12,7 +12,7 @@ from data.database import (Repository, Namespace, RepositoryTag, Star, Image, Im Visibility, RepositoryPermission, RepositoryActionCount, Role, RepositoryAuthorizedEmail, TagManifest, DerivedStorageForImage, Label, TagManifestLabel, db_for_update, get_epoch_timestamp, - db_random_func, db_concat_func) + db_random_func, db_concat_func, RepositorySearchScore) from data.text import prefix_search from util.itertoolrecipes import take @@ -42,6 +42,7 @@ def create_repository(namespace, name, creating_user, visibility='private', repo yesterday = datetime.now() - timedelta(days=1) RepositoryActionCount.create(repository=repo, count=0, date=yesterday) + RepositorySearchScore.create(repository=repo, score=0) if creating_user and not creating_user.organization: RepositoryPermission.create(user=creating_user, repository=repo, role=admin) diff --git a/data/model/repositoryactioncount.py b/data/model/repositoryactioncount.py new file mode 100644 index 000000000..66c1f9c4c --- /dev/null +++ b/data/model/repositoryactioncount.py @@ -0,0 +1,118 @@ +import logging + +from collections import namedtuple +from peewee import IntegrityError + +from datetime import date, timedelta, datetime +from data.database import (Repository, LogEntry, RepositoryActionCount, RepositorySearchScore, + db_random_func, fn) + +logger = logging.getLogger(__name__) + +search_bucket = namedtuple('SearchBucket', ['delta', 'days', 'weight']) + +# Defines the various buckets for search scoring. Each bucket is computed using the given time +# delta from today *minus the previous bucket's time period*. Once all the actions over the +# bucket's time period have been collected, they are multiplied by the given modifier. The modifiers +# for this bucket were determined via the integral of (2/((x/183)+1)^2)/183 over the period of days +# in the bucket; this integral over 0..183 has a sum of 1, so we get a good normalize score result. +SEARCH_BUCKETS = [ + search_bucket(timedelta(days=1), 1, 0.010870), + search_bucket(timedelta(days=7), 6, 0.062815), + search_bucket(timedelta(days=31), 24, 0.21604), + search_bucket(timedelta(days=183), 152, 0.71028), +] + +def find_uncounted_repository(): + """ Returns a repository that has not yet had an entry added into the RepositoryActionCount + table for yesterday. + """ + try: + # Get a random repository to count. + today = date.today() + yesterday = today - timedelta(days=1) + has_yesterday_actions = (RepositoryActionCount + .select(RepositoryActionCount.repository) + .where(RepositoryActionCount.date == yesterday)) + + to_count = (Repository + .select() + .where(~(Repository.id << (has_yesterday_actions))) + .order_by(db_random_func()).get()) + return to_count + except Repository.DoesNotExist: + return 0 + + +def count_repository_actions(to_count): + """ Aggregates repository actions from the LogEntry table for the last day and writes them to + the RepositoryActionCount table. Return True if the repository was updated and False + otherwise. + """ + today = date.today() + yesterday = today - timedelta(days=1) + + actions = (LogEntry + .select() + .where(LogEntry.repository == to_count, + LogEntry.datetime >= yesterday, + LogEntry.datetime < today) + .count()) + + try: + RepositoryActionCount.create(repository=to_count, date=yesterday, count=actions) + return True + except IntegrityError: + logger.exception('Exception when writing count for repository') + return False + + +def update_repository_score(repo): + """ Updates the repository score entry for the given table by retrieving information from + the RepositoryActionCount table. Note that count_repository_actions for the repo should + be called first. Returns True if the row was updated and False otherwise. + """ + today = date.today() + + # Retrieve the counts for each bucket and calculate the final score. + final_score = 0.0 + last_end_timedelta = timedelta(days=0) + + for bucket in SEARCH_BUCKETS: + start_date = today - bucket.delta + end_date = today - last_end_timedelta + last_end_timedelta = bucket.delta + + query = (RepositoryActionCount + .select(fn.Sum(RepositoryActionCount.count), fn.Count(RepositoryActionCount.id)) + .where(RepositoryActionCount.date >= start_date, + RepositoryActionCount.date < end_date, + RepositoryActionCount.repository == repo)) + + bucket_tuple = query.tuples()[0] + logger.debug('Got bucket tuple %s for bucket %s for repository %s', bucket_tuple, bucket, + repo.id) + + bucket_sum = bucket_tuple[0] + bucket_count = bucket_tuple[1] + if not bucket_count: + continue + + bucket_score = bucket_sum / (bucket_count * 1.0) + final_score += bucket_score * bucket.weight + + # Update the existing repo search score row or create a new one. + normalized_score = int(final_score * 100.0) + try: + try: + search_score_row = RepositorySearchScore.get(repository=repo) + search_score_row.last_updated = datetime.now() + search_score_row.score = normalized_score + search_score_row.save() + return True + except RepositorySearchScore.DoesNotExist: + RepositorySearchScore.create(repository=repo, score=normalized_score, last_updated=today) + return True + except IntegrityError: + logger.debug('RepositorySearchScore row already existed; skipping') + return False diff --git a/data/model/test/test_repositoryactioncount.py b/data/model/test/test_repositoryactioncount.py new file mode 100644 index 000000000..7d53ca9ff --- /dev/null +++ b/data/model/test/test_repositoryactioncount.py @@ -0,0 +1,38 @@ +from datetime import date, timedelta + +import pytest + +from data.database import RepositoryActionCount, RepositorySearchScore +from data.model.repository import create_repository +from data.model.repositoryactioncount import update_repository_score, SEARCH_BUCKETS +from test.fixtures import database_uri, init_db_path, sqlitedb_file + +@pytest.mark.parametrize('bucket_sums,expected_score', [ + ((0, 0, 0, 0), 0), + + ((1, 6, 24, 152), 100), + ((2, 6, 24, 152), 101), + ((1, 6, 24, 304), 171), + + ((100, 480, 24, 152), 703), + ((1, 6, 24, 15200), 7131), + + ((300, 500, 1000, 0), 1733), + ((5000, 0, 0, 0), 5434), +]) +def test_update_repository_score(bucket_sums, expected_score, database_uri): + # Create a new repository. + repo = create_repository('devtable', 'somenewrepo', None, repo_kind='image') + + # Delete the RAC created in create_repository. + RepositoryActionCount.delete().where(RepositoryActionCount.repository == repo).execute() + + # Add RAC rows for each of the buckets. + for index, bucket in enumerate(SEARCH_BUCKETS): + for day in range(0, bucket.days): + RepositoryActionCount.create(repository=repo, + count=(bucket_sums[index] / bucket.days * 1.0), + date=date.today() - bucket.delta + timedelta(days=day)) + + assert update_repository_score(repo) + assert RepositorySearchScore.get(repository=repo).score == expected_score diff --git a/initdb.py b/initdb.py index a7e278823..855ee11b3 100644 --- a/initdb.py +++ b/initdb.py @@ -854,8 +854,13 @@ def populate_database(minimal=False, with_storage=False): model.user.create_user_prompt(new_user_4, 'confirm_username') - while repositoryactioncounter.count_repository_actions(): - pass + while True: + to_count = model.repositoryactioncount.find_uncounted_repository() + if not to_count: + break + + model.repositoryactioncount.count_repository_actions(to_count) + model.repositoryactioncount.update_repository_score(to_count) def find_models_missing_data(): diff --git a/test/data/test.db b/test/data/test.db index 55e2f8cfa75f575eca5c6f87bf0facc7c394036e..914c1c29e7747fed2c1ba7005a9a17ed1c8c72c9 100644 GIT binary patch delta 75406 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 delta 74467 zcmeEvd3+>Saj<%HjaJf(q>)y8dbRf2-t}&4`|fF9yK|qK`}Q&JndzSUJ~cKTYcZGr z1_$M%KSDyVvB4z10%ipv!RAOp%w@tAuGl2`0wE-r9OMH0RgYF$X|-N&!jJF!$NRIM zXI@oT*L$z3-g{N`-rVz|aL+x$1N*1NfdS+<1~&g8+^?S?5%Kr$aH+2)&!7Oj^2`A! zC(n!n&VR1l3FY6eWTE`xN)XDAt(^Ms*VN2=k+-c*JjJQsHmFpbL4JmO5wQ+@YT!3k zr|&quDm`_(^3XRwT00@p1qu7=ylY}*@W|LeaA-)WTsgL?d+vyG{(V07@ccLLS^eQR zT&vIj{;n(Wl$KA@bP6R%T8mOCPK)v>j6``Yj}a7)3C!xxexFbt|4exNCbOm~6}~<1 zTD|u}nDXTNf5hs~zV2^V|L{Y1E6F$SJ88Z46FTX^znPQYdT8^l5+9vEqP*#@f4?O( zcgu%XPkqz1I{P%H-0x`}yym9bQR$BN&$(8A6KY0Qe!M((z-^H3zIV54b>SnJ^2T38 zUk;|`|M%(*-*Vk@V!v_#x?xN?kRTX7$tOfKDG($|G1>&m@ks(r2^g2sau`Vo*ol1` z*dn3j*#ya=DFPQ!N)UOJPb5-k65|DoB`ASTt|Dh~<=8Xi?@m5q4M?AV!<_5Z6MHtE z*W#>}V^|U81rCS)!Eux)2nHo-iby0An8=XSiTMreBq6dGnIKS+Bn6bBaSY`|Hi=SX zQsi+?O9JDoe{&X7YRm&mUq+zc71g8meH>dJ)}sDKQaD>(Z@%GiHAq;RsJjTcN0FvjQYtj%Vc%prz2~V z*1;HZVBop2PmO3sUmkhe(DLBd)Z?SXpmO{hV}C#V$?;o({{iXQ+x8widUP;|(9p#R zl1QQ~4dOwOJPjhBBvD+z6Dfhj`6S1z?*C-?Y9fi@7?Y$>n%ByRf)-6ALA5cC=P8Ow z@RU}(MY^dpkFI{^lMf#OYeA+M0YgQCgn?zi$njc^KzXnsI6y=u$$$8*pGpk6=%g0Z zLJPV}5TLubRsc;GaL_6u!C_(&Bu{%vW;K<9!RNF*D$*pF6dVJwAK@n--Q^avlWNiYhM}nZx6rRvxEKM*hn_9j9Pr_GIES6$0&`L2WK&wF7 z05QqI*OVYIM2eP)O1GAwRm`7$;c5ZbavV=UTX2w6N>&Q3R-{mdOC|}Zhki&A((*0y z=rNYS8IhBFiBEB|60s-;W(7KcptQJvVL%F#n0XAt*2svLVXCni88JohTImP5`NON#FFfkI93wj+KXy6xbzDYVz31ac zR^R@`dzLQ8OpeG;T$Y8r^-H!PFk%hKlAOOz{#2Kq49p*!kPY0R>Zh`S`}Ge`JpT_W zk}bK*)jO z*w83};VcU4AwqiON`>p<#J_w*u}}K^l?shSU8UH4ah!XOD2_^Ryh?HO;$R?gh4kW8 zit8^9hNq87;UkKJ=WCJbK9o zdZ=Pdy8Wo)hEa^=IPJ!3KJ!0%>ds^RcU?r(fVl>UjcoS&4Y>i@a2aSvCCzb#MsDxU zvFf*1eL`Ux#W=>@ZiQYlZDs$6#G(f_JK}W*hjtO!Ur~w3%0cp94>C1MkqesY`>^ zuMFBPnLWA6|`B10RG5?eH6VF=M76C03C zqMK9ao>xPd-;U7RNn-bQjGYK`uZA$Y9pNI{vWd`JpRUg<%!a;fV!Q&v^aThz25;)s z5Y#e4?|f(O6c5#*p|SG@X(xR0Rp1k^0v|s#)Vt&hc5NfDb0o%I1+Lr%zli!A>TPS` zj$s(tPGCnT55Ee0Xd8TI0|rmM3WDMaU~p`Qyq{O12NYj=1tr=uG;r}*=Frf<`BB}; z)4B?6YTr(T`3nj3E?B>=YtSVqtZUFE5N5Y^%S9Au8@#u3WM}%)zxjrp2-Djr?3C@P zSAnayz`=;^B=G-0c{X&XC$IQ-$mXwJc{X&X*WYsdzgM2kA?Vx4or3zR%JW{uXJ0{i z`ZLh^?bK^C&_y)p)g~BFp)H1Hr+|VA0lc?i+;$>>3SE)_%s-ce!~AneILto-Fay3a z1E4}%2<#Lvn13z_hxum zpg07JgfYcN7j05FKLI_Z_+Jy(Tx^%Kd*A+HSjHjewMhE-A1d}2ere-dV(%a(bnVP;3XU7PSP8}YG z5xRtsE~sA(V_vld|_-i+=+3)S_xMimL>mEDt6z?&nVz;5dMbN zUVdiyp!HA2qs4$5X@UL@( z0O3fjHU$oIg2EwESS}~{t^!BapBbYt5uEfi#1B}ELyuEDOQ7K4hX5!CaVR1ok|{RT zf2g(#e5OO{+XmE6s{ca$MzwUH2oS4t%3SwNC^E&L9 zmW)P8+Gn@1L5JPIIwE$;W^z)T9@mAeoWZli+Wq0MIqK6p4f?H9?^h4Y|(OfPS_*z;xUT&9!TB6+W8iQuf z5^3_Wew)tgWjRyK8nK5NHsW`BU7V3~=?uZ3KVrn4xH;nX6K-RGcKS@D+ifGGP8g2$ zzyR5UXu~F35aTDvndZRCbyKqgL3UteQaPX;Qz~_XV<3bB0z)Sfg2$Fa%oHg0JSV`XlSs)1YbLT(czp2TRHL=zkb zp+m5bs1~O{9R-$1VHlRe7%b7uZS-uiTrTvP)kaLZ0A`680!vm(>kN6_F{{l?d33%I zq-TU9X55dnftbb4y39*lG~zU9Da;wMnnOm+YYv|8+O51|3`rzAsK{ENH^Z6ye7O=h44j)-$JiLa~qSIf#CjuQ%XoD*&G^? z!)b{1Cs9I#xDbUUAp8jpMR^)*kpM|00wol(i5g#9mMTvu_e!e!l_T2}1m3{X6ma>Y z`+!RvPl93s0SqJp)HMY;H8kX*2s}eTD4I@^6ek^flajcQ2BRftQYybmxxYtJw3ern z5NPI8FegFCnM*=gR)p5l7|a_e-Y4a&m;=kKn`+q0+7e>iNP_${}(-(knWe z<>q2TbaY)Y7=%v9m%=#DB1=SzR%}VMl%v&Dwp1ogH!^%FUtdg?iyN{sBhSBm(Z<^46v0tkr44n&Af5wu+_YW^S>XOfDu%CzEYHVMw;pPM5#qE|rrP;fln18(cAq zT2_lQxGcg~kAVp9T^T+$HUNXVp>QI}YAGHD6o=dll!62SG=V`PfEEMW#fo@BND9Dc zO4wl3i`zo!TBn-DbXXysH!d$ay*9T{a~f!4N?Ugk?O>Ekb)A(?sHyia8_05$FjY%s z{GyzmXOzYnu*g#3&B}c_NNbT(7zm!?AixSO8jBvr=a01vi(b#kK)BhoX{~suXRn&l23Le_*$hmm!!|=clGE1~ zLzYsRx@5P}i;$|p5sb|2@eyE_yU;|5G!02#Ftq%7rc{cS%|0yKl90cEkuXb;Vo$6I z^^DBy@pB8azLj!YVnHwCFmV2`1q^>s>vDy4EXnx{W+#XFbtDlBJ6slK$!88*12#Jr zhy`s99jRTi>LUcCXl+aYn@R%g0>4zhZ^>a`_t47lsj-3H7I_3-X|2FR4if=+YZT}S znjkqIO(wwdGdx4GFg)nlT zq}Vc6sYOeu=<$bq6qBnbGv!+Cctfba^ZpBDfL^3w3gKi^xN>r6U2SgKrZ%v!0+WhS zD3%~#O69aPWM08Si%j8!HkqI>R%9y8L?N3z$77;~QI5Q5P2|}`x||K?@Wrfou|-gs zth3!N248F58SWZSOKj|C%p*KO^n2(Z`}`OhNd{^7Fbv$ zlOiZDpTN)rSYlM1XVW*F@_vC#VW-wggN;h6$Mc_K?*VHEbEx$#b?(W(sGed)}rzkij4u zh~$$gl$CR6Ao~b1zaWPQ6(FA{DQblTWGCC+na>F3CI#GnIYc~3>=xjc^;O~97%6<&&DuSwW)wTVXhh}KO=N(=92DY)vY^O zrotiKK(b7ZYjw;y%5~CE%O%SuugO&Ar9XPR^27yf&{{37UHjSFl@n7F>U&hScHZ_&57V8ma}19{vdqfl^z`6=f3$krSJXgl=p41F z!C!XJfY{(UV(P(H7`xtOuSkI!?BM$i9U1&(hY*Ot)*gr%C#MGof9aw8#i_Af3lr*( zsgJ3=s_&_*s&~O2_a;@(G7RH_4F0mJIC758e|LC$7jBq_&k_1%M|S8OomUvtjWO-L z>NaEW9HC!!JQZfSr^hZBN#egh_nfVa{qdn$za>Ok^aSg58)(LE!5YhzvV`2PlyieN z9b)~NfB@ge*$2j6Qcqp@%-Q#j{nr&otwAoZmMjt6AGVoe22bEV zcx3IFXLcPt4W1p6V&$w)NIQj`ZXTRAycQB;A>kfUT6so|Dol`xWg&r(h$OAh;2hW=Mux`}wKy(bI#o z$nUL<-ZTE_DKG53wXoz6VGBdSE*IuZ*dl~1 z&?!v>bfb80ZoTHdo=$litQs*`V`yRbmx9e8!KUP653m`B)Oj`u2MoaZv$lKR#GfLQ z7>8jD!<|^TGM`OJ2lq|vkrW3eX1B@@0UjlsBEd!TczNO|es6TJ|L*&m^1C6y3=TFx zcDq(i#fC!*@Dg|vp5Wwc_#~{fMd|eiCiq^-WlwZ%-3Xztn}rBk$|ov8LsM@E;#pf; z8;Lr2V~(fsa=Ytk`}LS$buAmc#dN}yYIE~CE4Z6&Pp_ME*di?J^7D0Hhr`0! za0eQo_Y%gIC5t!nXsD30HET_qcc~d55>a03w=+R#jl*YQv#wmBWaY~`e`Zn4bW)I0UBNvK{^}HXocScUIlxx}vMnF;Nr}=6S4?2NK&E+O0W8cCUt5r+ zdt>v;E}-D-!LEe&Hp(09T)6|AfP_2hdU$Ld`*m9sWZgp#P6UujiqftOBYkOG8P+KW z7!ERWA)g-I5AI8lIf3Q+J{J_{!0RCZ*JM&FeelqP;mB6|C(~kCEhGDO2i0#J0B`qS zfYjUbassBy=^)=NU6Ay04(7G2><^oQ!VA7{wH*xzm=M=X{fYD}H ziN1Tnunoe>ju?y}q_$@k++n#~lGMsAAGSW@G3#d_xG=Y&cC;i5S z5OR^BaV<-%{e5rZ=T~mslgI`Q^n;ZC>!FEIkH{s8m5i^#;9M>jOBmD9C38c|JF!fx z3fmm7ztLi1jYg{#=o0k=Rn(KMdW>iU!R`y*1h-r?B}LI(F;+1ml+dE6uN#h*8i}Hq z^Rhmp9kclge8`H0EoPsyYC(N2yUQ(h+Lcr>ZRmDVJsZJB3jQt@E~m4poPp2>^ns)+ zZHkq2F_@8AzHSPpt<6Fv8PC?uMv~0biL52<^jVgh?nt{4EYvI2Wq+U+snnLtMoTeX zFQYWRjM|$~Unh{L2C-_#Sh434f(}cj6O1=u<#4;xWN{WFF{W2HbrPOzJi(apjGe-C z=8C(q)b!;lOGG|Z3}tyXld4i#ma18zX>+`T>4gOEwAeX8D3l0y(i3&(Y|F8T+om-~ zSw}t+)uP3U4h++s+w^)vV&rpM^f`|RffCc&9a-ZqJUrp+l`N??%9t>FuEsFva>EpE z_*2ee3u_yxE*f(4e29;mT-~Te8+8_IL?-GMFhUT5%N{gt%BIb>s-s$K1Zh;L@J5e; zsdlvmF{MxHB6!7uz(wu6!XPb7#3M6aoGj7afD$Sl5Q?I7xB#dCxl+k&p89u07(5(C|lQ& z1yso3Ix8*0bZzxmgK2}m673cVU!WLHqp28%WrEsn(phPNhZ)>XR(jdpW|qozOF0y; z#p_%QFE|7%?uhV>V2)!9VJ1pdsiLXasx)hP%1-1W&Lm!C+;9@99q!fYxh%;T0xToC zDiv$B?V|KTB-nLy4X!1-x!xv0^x;IMudKJiiq+^TE(LVjMy3=rSsU&qoerU7%ae2D zD_kiG!Ki#`$r8)aVYEj1YFsAM%o9W|z_oNP-V{w&ES!!+(~ee=OExM7Yp7=-?QF(G z8%kMiDdKT-ISxXLnU1%dU>Y$$BbvNHQz2oYd@;6N_F4r88mU^NonWv|MOi1Av$Rku zil@tsW~-aGB_p1onKSUI_QkaYEF#H5XmEX4C={P2cMQvi9-Z*_y3u5utG2QtXE4>m z?N%jU^JKh*P^^;)#+nJ-ery$7vhw6m4~dt!RVMrffvliTjrdxmYn0 zFPH>F&TR5TioOJ1T=s+t6^k}!PNTJuJDCf|s`^H_SV*~8LpWSF#Y>zRG4^aNx)~`o z?O8pOZ`Xxj-Wgr$SX=feUn_M4Q`hQ960LSIpD7WccCBh^m*WYi)l;|C^#)MyaD_El z%S&x*fU2amY?dn0Vg0f%4$EtM8|`!~Sj3j(97{1$Fp-#G;37KQ;#($~L~OYls#SZo zsJ|FZXXARkqa)CKw_?|sBQ~wQ?MUWGGn@!0u#IKbPjr$V;}XScO-w4~H99>0Je4$4 zQQvYpmauu;Izyo7=KK*@!V`2$|4K$oo{lhZzHev?IgRfamet>#2)wrF{go|xFE+PO z5CULHjDG#?iiv^abI0B&r5>BG^~&i2o2-WQx=c2wvwEGJ+hiyCR=P&j8Hi5l8xgc^ zsMY;}ay{t4h)UgU4T9?$x0~|CpoKQ$g@V0RO?z@W(vD(vE+SSVm0UOMbb_cSVXsRV zGO0p5#*F-soQM4RHRo;!*+(w0oZTC64MpgY1w#8THsn{;k%80Iqr z72)vZqM!>m>dlylNBt#-)0OJhs~HFGaJF+L!ecPz=!_*(?iBEFwPlVjxBVDVTgsR! zWt0^KqrM>2TLrX|50{gbKq1qL`m+8dqFr*(wcb)u2quzkogr(FCi7^;UUN4ZM3-v0 ziB3uD^E9m4rMe-SV9n-Cq;6fZmTA_|via?zIW5MLLEhz0GGSjk?{(qYbTCB-X_Lv~ zeFc*R3o;xIixQVISvNc};qBpK&XQqDycsolEzw+1G#PA|SzE8xV_v7fU}uUY!eAsU zZ8{hZhKYcHwk#f|ZSXD!GFFG##Dt>;jB>dl9@k-wTqhm#7f>cGBXyQ&nqH%w@CAu+dph6ql=6Gf|3lyf$0Q*lAnaf}|Ip zNnkZhQ82m7dmyFy@d5SP*i#e#afoRS>>el&D2@((S^aJ`uKKuYaq^EQo}RFezc}vS zb>rBdkKL;LjP&KOQI}vjZz|g#cn&7lJ1^y;p~eO zZ~NR4o)A-*AP5i`fsh=W2E`$X0D_&c5lxX0@FYZrlRor&lQ$h95&}U$QUn|omNAnM zbJX&3S_@A=oD?=9VuF%1k4-KfNl_GpHe}BXo02z*a^@B6Xi$=cdkz=~QED+k5+0jm zj_@QzVziJ!!_xAhZ#lsVLPi)A5HEq-9JE4`ke+#L(sTrl_LGoqlteKR2cHy;0VbRj zhlo2Pz;ysricY1ZqmNJCa72!MijWJ2f@=kWwwS1eERzIG-&z5qxTHv@w77KNy* zji(@cDalfz$V(@mn4E)yW%%w*lFcMN@Vyw!#59o zZD@IDLGe$DdyszxM0&tAaAwa+ZghTbPI2#aKSo$@@HP2w;HPVmm}(H&wXl*Mo%d@L zD}wa8W%U8+eoiwn+~Cs#|0+FL7@d>$FRNonMrtjqQRH8wYrEV(}yL)H>US1 z2EHfpk5288e*Bf`aq0Enm|lbv&;vL0mGA0-7Y(5mVPyWeMsepRU727WzMZ4`6X_>i zHHW06<9DhLAumaeJJmNJN$I{j)klyYOOM^DHXsSd%p(6~oFclH;q;9Z!9IdQ^JsE7Mmh2EM=E@$X5_?vgturdWx|ICjOr|Je>1mkM8< zo|DvHoxVc)m#jq%_>(i6# zkKXn5>1oAEczsxakNwhLpTnAw{{4efQ_`WYPVYvJz5juksk1LlenWjsggYL10X7+M zT?iN<9s_rpoPtQwJfs9L0$it)QrrpKWbguiM}6dS(9ce(hOmze4gT!p`=y^K*930gRi$ni8)E$}t)SE%Vw)|UJSh-tzOG9l$#^nLKT6&_P-X*=< zP@fojgLdV0lCrAiB-IC}lv4eXsom1E74_(vSXJMQ?7OsPDG*tdOVY`v`Z{Dxy0N9+ zCpDVtYvCCGVpF|Gdb$b1r45& zeHGG?{!RYhu=L)yBYUO$KQJ{aJ@A(Cg|%DS>ISmw=9Tv7{B5jar7pd$2Xq%3>Pe~m z+kpOqyVY~R(Wdx}ONV;u5Ym!bJ@pL=WN=+pujr{Kq;K@p$HrH#UTK0=08);vq{6CQ z($DMaaRs8-d}6PxQ&W<&r#?7*?99|kLn=0)t?q_;RC?H>g4ZH_iI*|dlEpE2m2_We z_Dbnmuc{1}9Y|gksXzwSIs3#nVXD17pi)Wy;Z+exO*-LI9UFPs;DcN`>3e?FtW@@? zu0g8OJAEp2;GmKCk-Dq06Fi_9fK?*|YL7@ji_yH7MTY@bS(C^|ARMPkwju zbCVyN{J`WpC-0rCP2Mr-n!IuHI`AX^aH2PLV0Zvg9#(E_3JGp%f4^q)z%114>(@+f z!P(od8QxN}r(d&cOU*pgj2%9Il!H_69)^6x!&^}1di|$14=cjEX8SegPvLP>ntqLH z%VRVBn!znK)BT#wGbcc2s$Vm{1xMYl8986Gpn{VHh*GzO^u~r5U!)nxf8iD;<%e`z zntmPwe7+pXEKKwrf-Q{pF}94z!p1R7Y>^@e3d0sg`Y2mF>0D?7 zyw8w$Opy!2eT*$bf9^FP;*hKjU9vFL$JjE2=P@9mhbHNT!9E5IAcRc&2LU(ycCwxj zuvVlN6n&H}Bf3EZoPMOd5e8Wzf=7~ z^_$gyqb{odQvE1|QFr;qwtwAzox;Xw5*uo?{WgX3;2vcC%SyEUI)(G_#dQtZex1S=@VfSFzfNHj zyrDYVZc~si23TKeU?4|5S#h>qr?3^it~J}QQ`qwOy2fn3PGJL#Z>Y=2)(a0diErpi zkKBHp!sg@J#dS^D7AV{L__~&C3zVG)Z>Y$&K-pF>b522ExpZLCGBEkL`gff3CqWbR1uKG6BRq7ije@nf8(xUp$$v;wkbMh^!kE&)=(qu%{n#`(#lP{ZwnvPye!SczXQh zLu)S|f*sLW&r}w+U6*mw*V_H@srmvj30svZg@0gB7-|oGMeSGp=Hw42Z`zd_`|;TA z%0E?dqaPn76<<~Ok#`Jy8F|mZpA38o9A&>gb4D|>5;!w6I$yq4apvI4O=l*h>f=)f zq|ZM#bsX6*?+^}3pL+}{{^{|ly^{U$scVo48N-6?TL->X#s=Wcu=&EDn4(}$(|^eM z#MGGd)+eT}f(+O*yQI4xoZ^r@>!5c%IHi)F{>sFZ^zuW1^s@)2)PwnzyW~yP@h$tT ztA|$pXB)d)6oW%&#w7JaQ;hU)k4+ttjz2WDODa7yb*)l4I)B4)#mat3_wdx5^r45Q z=B1B54j4apXzGM=badVXz>_j?UMjs09=hp$urCsx0F1)>rWobO=)40kZdiZ(nfF2c z+JjKQC$%*3@DvLBG-xS!U>=`>ZJWH;I`t52Nc&%5k98gF-=2GT3X}fqA$V%>VJ7R*tRo zsu8JjgJzf1r}(cGwfdb;O^tkHWc1$;DF(*g|J2k*zQyLI z9^AMTvo`yMsoRjP+ag&@AoE;Ht-axk7Xi_52PCuh(=SbZ)a~1n8q?KlfiF$|0jPLkuyp1M>7M7OkItg7 zU0&hNTsb60Tzw$~3y;7 z*9;DyQA=NZVv0r%ZUF;Ha_CI+j7nmEZ|Yj% zecL+%zTL=~1?li9&4NTTnmH+SN^=eH@H(g%f+4uL0lslCa^`?^>My4kkmLP(_kgW{qmyeY%g;>;nrV|`eK)nLf3k066D_uY5b4a0mguKp~P z$lKNb1v{&ssDGsXzWT4!--R93SJYnw&>{fgpLFECGd~!5(*r;KGimCLfthztE{yisng_&dhoql;V5U8E(?=dzUMoF1 zGleMUAGq&e|0T~p3NQKG2WM2skbJ$e^xfZ``SH-B+I=rd&;K59Eey)98`V9XPWNIC=qq9k^%xZEwF-Gq)e! zw)+~ufQ|ZQ^XR+Q5uUkKv-xtT-0bjYY<%Cix zQ@(OorYt>qyJil0FFM~d`dwi26 z*o(+FPEQTW^_pFqH@aW9-XHzi z$+0&NOb>j20Nh}>>UUM{$;T#sJo>fKTSvY!VjTY9&{qflaMtEHGOF|h#<$M|6QKF4!J?b-79^kJbPrYeC9goeXQm>iFXd}mOe;o#-)Gk zPfF5mt>!9(ldjilzKk4|COC~9(XLO`{is^>2FW-YxwZr~2nAVwp^6!U7r7vV=r)1Dw@T#@+tOGGhUwU?EZoU3n>Dg(C z%gizeDOEDF7R0a#bORrMglTMuezR&ydJ)sWLIT%Nd-2hEj#IqR+xQ=^@}%c()`Vb5 zbg{L^N$DN(V&p|yGbR1bDb1+#7pLHQ?~T=^^iSu2B&>XX@;rn?Z)E}74y%u|cW6F& zauBp??K5xJ{MI4)lazc?^C%+%DoZ(uia^$a2Ai4F`}2+l=e5VHsOa_8L}M`9^mxCnLE&p*b+!bq1E&A)|?Q=X97mXCkGQgY$=a7N%)%1>0nqZIwto zzT_t2gsnr;IjyJ*cp9;E+-t+Ujy91BxvKh7$DP$J+wFF)st*}64KAB8no?PF)D(3W zjHYI=CYXxFRMJzjQk{&>1&50Boqctun1O;x<^;A-95m1&P4VP9S0VcPv7Xt0bT98bAU{D7>Rkct)Ub z%PTmSd83uo*$?UKzH^2kn}iQ%&Y>XPaQDty8_{+?Yw*`*z$M*nUU8+ps{ z*$+?O@y_A#74I2tbUuAbab{GSPR$;YZb^a>wr?8GJQ&hlsaYdp+pO9rVX4_6=}c<& z1j0&Bre>EAtL!9zeOn4l)z!kR9?WJ&m_3D<*F(Y23bX&D{Qqa`5L~L@8V=E|{VuL~ z1c6PehtwF5)9WpQdE_?aq%=xt803^Z+qjU6&0a^(zIS$PYVb$uZ>&vE4Sr62Y<3Vu zE*v0*W)K~_a3Ib;JNxSgUb9=T*{xTxTVc{@t0n{00&9w=*mT-0x{5A5NVnUKY?HHv zb7-*XpqoOfi7wSRPu5MC^lVP_`3gQl=d+nS&gFzjOr`A>u9oVQV_ho9Rb7!*Gac4t z*?bh&bz@$_kLvtJPH*$2U3H9s%N<;aPPJ87)|;Jmmm^cdsQ{X)!Lg2Z7jAUJT1GY+ zs;&>J1J)>tub_994_Z4yVqX$R)9S#2nS@f_`n=QQ-p(JVYAfg*aZ# zIXyO4EiU@1oidpVw2OS)3N*7etKaUyB9xwuXtkMo%VVnBsYX?s?iDKCY}V({6{RUH{;TkZMdCIu+C@LE^TG4W*E z0gHK~IotG6c9X6npw)6$8?s<@h3TT+WYkw;;~Zzk^JZNxY{oF!n}%a#OJSd>(@m0{ z5Fv=+cHOCS2f0|g-F5mJ^`#seu9hPfE>6^NeG1KyOQBfK94%^>B8BB7Mb(r3bgQg~ zD{Hjrklw;@v05OX5hHbnP&O1xOPNBaz{D(xQZBvhz^axYnU@dzLkTk zBg;g{W3ROZuIy(F>9v<$eod}_)pD(xdqsO~HMOE{u5C)vA-y}2v5;1*QEM9uOKj0) zDf*2*yTB})+5*}x(nZs9DyUngEm}8fb({SiOU}%-aV}J|+1t((6H8Y8yeR95s3i;e zQnm>)G69gu;;}rVJk$k**sIrF2kPC5EYxeP0&_| zbd*55LHNnYm?NH#2bvLEJy#Swr398wdt7v>3}4G&^A%qUx&F42X zX}`JTY>6$M7;KxI8O)|_+8S^Kxao|BJc0|g*emvcv6PP4y2dCK7rMoC2#XUDXVgMu zoH4HMidtiC(P40=JFp0L@=1%`smJnII>U9NCTGuSi&hia28TuYifGL?QtlkwY1}R6 z@^GzamaTRRPE*{91?Y;E3cxvdGn>o=7;6<>c6m^*Ih*o!mrOdF-RrkfwRoiyr*vgH z=FBiKfkYk7S~V1kR7t$xb9D2qn5ST63|>=nMvIK3S!zJ99i^sf--Q5XBOVv7`b~eqaut---;bn*2 z4_CLf;%?pAONU;Q>tD6KzJy%sECxa#On4=j#B#PyH`dbm93{4#spo5%N;#i&qgj8> z!v^Xw{MiWCPWUomkufC9F;=L@TZX!$5J?jg|fh9_^iVSN4ROSAP{xj-%9tgQ8+!9%~Z{Cv1Onfd_H7cO53b(G+BqbbA}+RUTXW%W-MmM zx&^PX)3kdZxyDN)ibr>mrGSPrgL9_xp136v6b)r_#!;ke zjA*s`Ec&G1|HV6k!q7hpokn?ohDMeuU5l9|mnb$PlPuUNZFc-`Ef z43rIRM@s%=f{fdWOZFtbRCGp4tpMTA>pWb9sg(ry@oE-+d0IzV!OnL(3|`dQO{jyf z)>~#9+&=+7&6w>}`Es6P5)D@C2qlBnrKOOa^fBH_EnPOX13^@&Mh zOFwtdjUD*(fa+b7i{n4o_4=`AmG2p4hCe&h8`L2GJn-p(B6PDus(R+aGw9xa8V4$; zah%J)IQg*|$Qtp^-3Si&=R#-xOuEH8_ioL>J$=M$0dZg*5s`l1J9k>L`Q}al=I`G1 zTv%H60cLi-pF$#&Tse4-=Er548UI`xod5r5{CHv`VMF@Ek3nk5@xYva#=Lv;1@UuF zA%6f*eK{}}1p1%4Cl!{i3(mcJHb2*=e|SsI2>eQM5Lnq8np=iQ!aKg%S?DL9+!dTN zt-TPM+m8&z-M9T@?HA#>E0CeXe=fXpZ6P|RLMG&2m)~UNi%}rajmOLcKX3h#aByqRRePSs0*^lDV z&u@cnNU8eJenQT&c&LO{v>69lp&F*NF{{J;l+}=Qrm6|8PiNvoK-FMu;T4fd z=N(iz=q}jX4Kv2Ji%YSFyIT~PsL^7vqV1a3U_>2lXM)oQndPM#T`19*!e)E?g*AO-8f=@m$tYXjjt-9iLkc8Bx3tO3)phvDC@x zg1Y8X(cxH*>TN=(!qPRk^rn&_vPIfu&o@Lvp7X;xru^DE=2yLrxrAKjx*3jj`KYwt zR`k@Dn?lH2b&GmOg3NXusb)6Os-T%bvEqs3bER}WRL~kQcXFvzu^MVP;V8Otk*>+? zHOEVaE^RgoRncLmOEp6RZ#$Sow^9p*D1WCx$4Yufs#7ODV#Z_!w~5IcHMf)Qo`Z`R z-L*s$?m-h!xaqOz)4DjCwI%EIWQ_?#3obTI80r;wq8(^^lZJZ2mhncoc*&8CgjzvA z$5fJ5M>t74YDT!NLFeL}bSdxhSd0zQn@Lu(2Aikh2JetP$Tf6Do@x3`QPjnjt5$8? z$VBQWt+U$AmU`7<42T9XQC~JY;Q|IWUbEnasM9N2x@0yZ@(sR_s4Et9inJ+_5ALc+p43G*{)iuhLo~yg7r|PP%>PBp8?0KH5 zTj2yyR1iVV#bUTj0xE)GxXJ;M!SPc-0R<7o87Bro1)TA>I-2-B-<6;FC(r#SNuE6C z?B2C&ch#QOTJL&aIWA#U59l-1!|CiWNt8lTQ|>5O0>@2n)hwow;y9TuX2VIcS|`<} z>WdW68XJg>0t#1X)Phul$2<{mafg$>RyEa&O1)M{^kuqLs$1%|6|v9A;PT7%;$CB{ z2(?_@(-~E1J;Q*5Wt5Vnfl(;cy(6>3@tmfm@^zU@s~Ik23P>hlvy|O55>~_Kw~A4z zlQyl48jT`6pKcYnkeye280O<(y}tCoxZdC6`ntD1hqQXM9nNI4UJDy=Oe^OZSQJh1 zR5Us+CjiDJ0FO#Hi8gs8EGk(m%*bNA0Aw^7A|kcXZZw!3h2mV8O!;zMEnJHtx|d6t zmKoOl?S8v6%%rejrx`YMxs(qu{3ol1($H*14tJ7h%qbwOe(d4%ZEA{Wg1Y(?bMTx4LfS}DdiGdY=* z!--BX+l1|^(yJ9&zN!?XK>yes#eA_8@C)~%=`QF(@mgL@HWOvFj&vhZAds!4vtz~= z<08#?m#jlv=lTQVdVi1WU2i?E>jl}THW{uNQgfxa1r%mUcI0gp`(rKu0SupwinZY| z+f6cTyeG6RL-mfv>CjN(Xd_IOyKLX%?XZZ zt4+1K<9=rx=X5)TcS@E$sw#!}cs@}VnG!$9hJh2xVv=I1>Wg8+PLK)HKm-}~29@ft z&JMb)ILe#QyuqdMYA>IT#Z8SP1;c2>2mKOaq)lN+b&^F=iT3+gosO7Q%YzQ15zY*^ zOR`dmhT`2WFV>O%DB2e*?9kILS)`l`(sne(BneRfF+VPx42xD59gKM;JY;w_(lxmO z2}sO=iit+lXX19S9iZd76f3m*jUbLxBB{8fic(rY$4ZNr{VCIyv(77bY;YfW?9{r8 z)(+M%tDaf;*_lgLY+Cl2>DtoeOZ={5ryd16|5oSmJ2!lHI`;0*nv0*h3yj`raw_>p z=b^hd@ayzV|Foo!TIL+~-y0UeKEGoVxpJ>je9V7?QGDd5H~e*aSL`Ty@u<&isJNyt zx94tmF1`nB@#4naE&M%QWRF|m$M;MO>BS9wu*G-oc;B15?cDF*vmxl5dhdoGO~3!S zZ#=oU@xBd*xu!3?DsbiEX`kJ2mTP)YmMV+a-M``Ou4x}OxNq^f&uu8UrVnd9b;aTt z4{q4xTJ!4H&lv3O*7XmCBSzU4L_}UU(+4@WfrKj>CYc zM<;>n9g>QH{R))g5Y+&tt_dMF4zxZdweXj_@R^goB(FX#bV%Q+eb1d(c+cJF%*h{n ziT2%d&d(PsN6bt~Q$Xb~1(IXee3W8@0P?wVyMynP|cnk~OcF5kFvV_LyD1}%wR3tnWu&0>}I}t<#9UPscDG$5t z;61fL*2+T|C{#2lAa0rn7BH4!fxssPie(t+ClW4nVSFz-<9`0g!;kG;^5DX*?8A@F4uM+<9cn%D4aG8xH1%w|V(z(V0np z75kU+?-t&C4xZ+kJvWEORZte75MbVb9^gQC4lHUOkRfArAYdmZ{K?x^@2SlI@tt9j zI6_he=pN`S=#}ZfkOt45#A#Lq-e7v6cRxBaclZCPAGh$+zb)K;|G6_;jz9VxWbwqE z3wM4$v9R-V=#1-ymo8g!M+|i?+6g0T`2*<8Br)sg#OYslj(rwJ^9LVTC72)_X#mk3 z0{m|9x+YIWwJ^{#nlSwXIi5z5>b7NjItDy`9vC?A_;dE3mHwEA~&E2fw-D+?kVJdU?ZX=l<*h=jG*4;qq@mg;noX#_M)% z7&?!93o0D($xUC|^4T|k?xdcA-%i=weMETdqlY`CQxAhT4O)VKpQWS@EPWuJ1u_lz zL>`s_F$#zU!5GCsKhe_RJu=%)-%}e@0fG7+bp1fn6J{xf!kboAAWt%YW(?#gD9pn; zJD-NW9KQC5$2Z##zklJfCllMZow}z1kiGG&=SjD_r26n!@oI?k&{<2DRM7V-gm6)icQY8??B_^ity*7 zry0G4)4!GY$g}YA?7J(qW5$2h9gK!6E}Rri_NJ)krW2e8pM@*7|KwAvy*E9y-uWCn z&F$OpJzvknAX^x+i$Kt0qRKm&1fa-4AQY?X_$2Fy(hTR}??QV=d~5pREw8bcI%oaR z4K1L1TA*=^vRD&X4poq}gSiCEk`w7JRmFjI&_qF5mvwsIgBA{^FWYt4&c8nF+y%qb z`O~E6^z{b?vp;_RPYXMqPB=TCgQw&%DGdc_Ip_umDG(|JY?PV~?--;?EXxBViXPS3 z^&DKg#D5XH^rSP7T)69p35WPTl>EoZuWX;a_58I9FGFjeosySeB}kTnl@^#V zNl*s?wH12u#~J?+uG=#B+^5KA8y7pT3}zGe{Ak065BQz;uiyFCZ+$KX;WxD)MdRV} zs8%Ct6lSHxs7?tbgWlA_NL;1F^dZ+3ecTUzU5(Xa*67YR%JX zjx?lE9}eT)Q6W1lD*ZY$Ff%o(YUJxWq971Z%nfp*XoE0%xYiiO8_i%@o|napn&~3i zIMWS9*(}=+6$yX9Gh_mM)92yyh6e2E!9h8qgtc5$8x~_$GM6!0)jUM%Td-#(*!mbe z&tjuWCJZ}B2100oM5S!d_y!DnfX9Z=z)-`3#0);3rd}!Llz_D@Ph)28YCgW?K;BQQJ^0t=Y&| z@aCwN(~FP^M^`|5L9bA0p%jjrCe8DnTqiOrN@2~cbjF2#RjFp%II0z*o=!D|VbvI) zEws9X#mbo|hl#zuRR*|JyzA{4GFz*}^I{=|m(WfOP=|Cpm{!!0U#g9h6#%Z+`dUzm zjZ=w8FfqZW9vIjAdt9%Z{h#>Me~jx^p*Q45EE6sc{9(|4wX5+?uUg3t!sB?08hMap zl`UjKrEq)1=KOqJi&{2mH#%Lpg;QBye$-DV26ih14AJF5zym=1c&CcXEj8YYbqt;p zs|l$T0PFj(@iDWvdLb-uJnCI&KK8;s+UTa z_#nmAixoVBs)?}>p)|fSij)iytAR3xC!LZ3pqiE=%^1W1J?Vm0j0XGup2g*rVKKyu zVg>6L*<631N0b&CiuV$^Y(`+sTtiAIw$)K;4d0lqc@X=a0=!;BVI%CwHAyHR|yUay}$ zfKT1e_|*TO^*T^0CI(SjK(taBX@_M0sPFfHdVr>3nAD5c3*jyi9RyI3&R2zCB}8SJ zTD#PS1ycv%3=szzfq)mcn!QvyQu3Ai1250{$rNwvzH%~-#<`Z)W>qpvLbzBAq(y%s ztRgwTC<~y6rg!Jt=~kHTD2Dv~56r3oS|XkJG`5bria zF^v;NkxSKE<%E>ZkF-h_JZWK@^);DPwCeA(L=EE=P3Q6vp5gcaUMXR~hh$0qAzvF0 z`pHqOz?E}CMiWUTKB{R976~`(ohG0RQc>JP|Foz0HPn$DAH=hb6oXAjR!t^3H@t*d{y>fI{~ zGx+i^FMG%I+>$$hQ7GqNKXSj_(KgQh=k#mm(swTYY2)lMuIa~*mo8X5>bP0cHFND{ zn;zKhJ!>8}8+0DuG%Kw2Zr_banV??)k+OaB?3L5)o2XALKDK#sL2=6uw(q{+=;Psn zbGOV2>nhv+>Et_Une&4!vkwBC=7Eo&eE;GNZ<{^AHGTi4pZ$LE>sx0JbIsg1`^eVa zmmhNiT<$q>RygGB6aMMp+k@tL{L=tqdG^HF1~hd3`S<_EiJdfi%^{(!|1W^Y(N(vl93fpG>cQ|6T{)?hn4ZZ8o#6`nG@e4_W4%g3LYyNxxURYtCPh+5bAExaFVs zKj|O1pc_8}_kVf&>~06+dzNh3-R0EwSpd?UJbM60v!54|e-)VBy+LlA4>Z-3T}`F5 zSdi!s?MAQYlq|gV^ZNV9gd=QCkQ4_MH+bWG%KQ54GTv*X)FubYo~&B{W7sD8xkJzDlte;Ak zIz=Io^BMkdgptBgizLG!%q21i>|fntC#7dY8M>9rBq9XOiM<#KP!=pLr}UD7%CTU< zUkK@8gf`lVs+>_cGF}4Yi1HK^QgNmt@=XEnR_SHbSEa6GlQUS8k12`@l z8CWp|l?H6wt_(@3hG)lNyj@0%!_J`DXk?kDzmZ6eMSYYnFiDaC>UFFtQ1vRFsP>yx z2?^8VVxurL#sgde7L2Y^w0bB-L4liY|jJmU_(l4BH$PXvXQP5bz4G8pe$m@ z9;622I(cAR@9%N_&bPK_O7WyWk!_~Z)%3XBL9=YCDCpTF+svB@x(bn-I)^pQa#SbM z-a$-8dIi;jbOnMG%LLLc^O^@TbI>-MM8-&q^z(G5*Keen1;5@6&>GS=`$eSM@3e*d zILLV^f43G;`Dz5KB5^G>Cg(MfQN$^w$Cz=8><6-b2&USdLMbmOc&oydq*0I!MWTUh zxDASwfjA$h%BF$VIcpG+$u?OR+1{{HuUL{iPL;8Y=xLI{EFb`wQJ)-(r9@pti_vJO zT~xYwW~@d$rAECj<-8Q#r=z0W8Vvw&87vMHdL3&BAr9kwi6WUO6=TKGC~Fin91eLU z8EJ~?Zo5_Gy$z%nA=|vtgt*P96;H=}pjjE|FyTQwT13rwKBty^i?0-BUzv6_7Jq2W z-o4@gt;K$&wRp?Z$T9O4mm{)C5t20<34!(aJe^Lf6>k@8t&&!okyys^a81FG!Av2G ztWfH9eMoL3jC6lN8JI~5DS4xMD@e52hQ`XxOgJp7SvnqxgmG>-k_y%OIAVFR>KJl3 zd7m%XDS3^kpa+X~Yuqn$^C>hl5(2!pkoUFdUeDvhqL`Qor&4v)JMb6B(xB18Qz5$v zVB*>c4Eq{@%my6G*6Wltky%C65*GD=rYPa{iG}uEa#`9P4i>?2f9l?*Mzwxuhm#>}eyJilzp67PgJmb2FfpGoo zgm?WXkG(g1+Iv3heD@rPJZ-sg7UC(5?N@KQ+IzZl*QHQ&`=n^qi!=AFkF24b_WPj- z|0oolF#FpMd*OxGI}bbu;lO(*MQ<}ty^wyJc)#=NM`t12s&*an{u{sL)FEu?eCei1 zGf#iu;`Jx~?hDRc5QB1}H$&0t@ZD#wf8;Ck4zU15Pux7aYBQ$cn#H0tLRlV&;DDGt z0yO)e=1vA_@?uluU5SGb!6Z^!{WHL4DYFo^w7t zg5E#)G3XbrPo%?j0zyd;Pb45Hj%Yey2T%|b12$nz1>rB}rH?_sR(#{*&#(IR(PucP zZh|k>`8X8)$F7aPcIUSr?py=GCg%^6qBXVmUV4!6**`nzC*X!l7vA;QGS{b4&W)Sl zn(14i!YRkr|0aCZdek}S`%rYztOXq7Xfu2)BXgA^)WXRZlCt^?G$@=2($>V-S6 zUC&+iy(_Bl`4hLn=Tm>mZ+E@(+#OD$2R+W-4n-?=F1vHp&J}Ms&F@03=O#tuuGf!> zZQb;`^MnhEv`<0N+|MiJ<693+}bOu3lYU z`O?e>R@9cCG5y$5Y005ecTVLY2>$j(?bX>MU2ER;)vL|DljZBL!en{mH?yy=8Gq>) zSL`iDe+$!d_3vg+a!ucH_-{Y#y#2M=YYuG%cAM6_6LtP!TDzRfUV{csczyOJAHjv!Z8i3G`i4J1r?39wEasXv zAMK%wkN;`*I@h%S=wH0P*#67x)voE;UlQ+GT>s{*01M4)`R8uf-2?Sa=)oO-n-yJ6 zXU%Q1r+>!hmX0{E3Gcs6xa!D9xexn~|A!MV;_N)iy>VXUy<;VrD)5PXIFuV?W4?4U zl7}STP98%#CYjHV2VAkKcFnN`5f5K$*z%TxUAfZf*3-puBBzP=xI%hE{e(PL24$>6 z5n>U``fwVOYe7jeU&fNPB1KaEM6;vNv0>g*@dE^$ZAa8*c^=UOq*wBF8dzCt_04F$ zGYB@0|prc{B+ol@GZO79_n6RM+;-ZY6n82Udz*`ivGOB z4r#k$55yss4p?yN%@+415!`Hi;3mebA=AMo210nqV?D2vS{#y+1sFdnqEqRO@p=zthrJ7=pSNvLb z*pfStNz-mhBTJ&gd@q3*ls>KlzerS$+c=10up(iy61;z|&qZ?no)1DbN`F|Xg+ifX zBT0~S)5n6}C>Va=7dfTm5_pDWW-USdE&h?H@DzD62F=KmbvsO}|HC==i{2 zjYeC+{2&p5a8q0h6>D|Crw&PuZpZR{0?lcuiieae3zN;zfT$;P6&q%MBR>jz^_0$7 z;bId>MO$bWa`ClZz}Fu`Mt(k091=i=5>pUJIU6BX$!`w8Ip4tJ6(g1G@p4C2(hz{{ zmBNd!ob3MS0bt7h1*Slt^DRbo-)qvz8s6#E8$G5SuyHf%3y>|Xkskx|9Z@LoDHD^0 zsuiZ06l3*stss;4$NLsxC5Qe@#^1z7Eeh?i+qI#^WTLUzi zGwA}|P(mXni=k?~8xxwour@&1(!3|l$g;N<;YU`CB>ka2-2ne>q>BjVK4@J1$ICVI_$FN*l9n%(K=BT*vQjcG-z z;kV>8smoRbi`9j3ERchZCGJy$zI4tXD9qc_dlwdwfEx^(=c%8>cb|CX1MZ;nO3?lD>AS=YUtN4QTLv2C2I6K?*H!@0dT z*_$%{$`|3#$R^znXArUm79L=s*_hOTlu|}cTYXF@&hZ+UP-N7JM+_-`(`eiDbAce zvth+cE55km>J{x3;T1ximA1seA-?Z$H%br;F@nz>M6PKN|Y{~Sq@ORbH zA1}Rk>7`4prKc@Dbjb@#KELG3CCw$FB}chlb3N+%sB7d(x!yMQ=0wNg|Ni6LtGG`D zhTWxS?F)c<&UrKCzIE%rM<$~OZ(S<67IxmhdEwG;EOQ=DyH9kE6Wp0iD!>~x6`@p+ zV+Q>9L=hX%lB8*A1{iH9reRgk4Rz->{d*K7i0kO?^EUl^pz@l9%f5j)3mNw&@dU6^ z2+E)-9V9*hrwmAX3c$qB2@(u9a?&{fhU>)C7bZ1v1MrC!U}HTKJ#fHcsv!DIz^?%0 z1^}!_CrE1QVdqTIom*J?rLE2~$$jFyrK13k2Anpa9uWe7#&8W~B8Cnc+oTFQ(FAtR z$Y7aj3e&>;_`{d30fWlt3aM~k?bFAz> zaq~XldfA1mzJ@GxzkGu8W!WumwMb0|9KDVLJRSxSU~WN`8`Qorc+mitMGboDza~%8 zd1BpRo1Ie>_eq)E0|BK8)r9v6*$6NYFc=anu0cwLMtC%g#R-Bnr>>to*nL6KBF?3X z`vm8#oO^o)$1%XkgU3Xl=#K-|7J&W}+`oZ?1PBAU46HGA^`r|P9Aiii_zyI7g0oi{ zK>HdR=&Ktv=!KYufz#B~;_kk$S$o*#B~$k}-_5zt+dP3cgHkQ6f$%)Qx8U_b$^lF$ zmSSO0(;BT#o$p9__sNNUaFU!kX&;BzPC!lufc7VS)@T^F7U2oDNaGK@AYYU(a$ zKJPwf;gT<$;3Ut4N&4?nQZUaZ=g~9W^1@wT-0U>p;of?}RYR({t64_A6$Bc3$pZ2dnrw?EHo26e}wqx0U zF8k&3dzN3a+*p3firZIQup&QMR@XnXe%F#?m;Z46duLM1HmrZgvhsS*`c+fkTK8iR zS-f=GS!d0>&2`g~*t*kJyt(es>CdlyaoGb)zP9|J6;Dss*M4E`Rcl-GYr`O#dCi*F z*E}};;+mV*jMt>sY+e1g)!$zE!qTHwetzYZuF>>iQ-587t!z&FmtV3nwDPE#*OuS2 zG(7X@%tu|nU;4^&V`lV!uj}yh<5|qm5zN9_ii9Tu$v9IF zoUqh+^K3T)LJjWC(~~#!kvnEL%h5>#6pRGifOV1~0f`O^G&uig8bx5$AW;l6Fveh} zKD+x?ra@^Y0m{iJK=BDnH4w&td>n@G&;+;-Ro$aceR@gXxisV6zVP!$HcwBka?aZ^ z2gCXf=X%Y3;z>(>H@W-1B%e&y^b?$;boYtKikYe1o!%GZ{O&#DUC89l8fC%ULruiA zb_4BU#6V7x0jUg-EQG_F4Y?sxA6<6F)I#fP$ni9_k2_b!sT=O?TUg!HVfAES*paZV z!b3n*0#+G@VklT{bVvchr~cFVyy1S&WMllt!)WewZ(cEV@v_NNaCUxg!)D+%f53E~ zxNP~PWU`%}v})3KRiiDM(I#60N`mVXLRzc=Uj@^2$a(TmG)7TV7dTiEUaFXOXEyK4 zj_v%=a-XmjhS65TWFYehMG@50!Lthg!{!J}J!3*%7HL4=b<=sO3VZtPaEIgf`Q(5& z&lcS`xz1WR`_bcpIe#hPeDbLco0sj_{pD`FbMuK?rlywsWFIoYh{G3VzKA$qF1xpG zDeg;3&~oR6vU`4hU(z#hAo9O@U-Dc)ZPnG@m-L2-b^&M59(v)M4<9>G3^)cH+>-|| z^~S?KBS8sve5oIvasv%<6)3aU;fZ$CslK! zoBn-no7)-J+_!Gthh&^nouljSY+_%M`Hq;p$9?gLOHQlqmYrAY?l+u+Zk^ra;7#{! zoBn+c+3I^*?k&q*!^O7^+?C}AJg585a|&uAZ*7DZNursxb5f3Ec@~ZNvXs=6P_Z8j z^Z=~EcI0-i-xp$`Y7(n4dOM9339T=(1BKHYY=sPUOsx%ik60unck%^KBrmtgf}r9? zC9b36ZXs%bAWK>7kHZw+t+yIdq#%(|mD8FbiNjm-UCS%fB{Nmam9q(?8UVT?w$C-l zetv8OYHfwiw-S7sPgB`pJz0tMYDoqShZ=zbp6_<5y-u;i(h{1egixlL%ZZ(+jpG3^ zRS#!{8lC4w!&Zk~9q%_~yp(3srpM#;=mEK!js^;BW}rmJ<`^Xd>~NGSVXb0N&)asC z$YgrSXgd=NM3UJmRWCvI^dONe*GpNV#rR1{RiiOk2&6%EHsi}eQdYXh^eylQ1Bn74 z^no(~SE|@A~<%q3}BAq4Vbw&aZa5v6<82zdlm>*3L_u2Ty@auhx0))fqUO zLom(qAds3f*_S7#2?pB$iFp{D2J?XNsN2q)*%N_-Bj>+8tvla15AL<>cp<%l*s%(- z_#hZ0oexC^S9V@>*jM8paz1pvdwz!c*!@BNg5`+w?QMrYp#MaKx|A9T{Qzlu4D_qorVIrM$S!I2MK_8sT5Z$O3P-VYTvkYBz2 zsJrgA9qji|^odCk^V9zG$(z4(hV!HMyK~3=`wiAP^8@ge=XTjQ9Cyichd7UY85;V@ z2cRL>bsq>X3FN-!T>1nQl`ev!Q_sF`PJEyLe&>dZpg+g|^r$4c>I*kI*#ChFy^Ep3 zDNF9*glo+!o$Zr%_NR;8t2Udvg-s!P3Qr%5A4tZ7JY>d$m?&hL6S_g`1nzA8AY8nz z%Aa-U$xkMovp)!}Z$0Q;2s1Z2-FayUO%azsg%vkVUA5}2sc$>AOQ6C=?bIJ4S&4D5 zMY#Qr4?%^A$LMX}{q5_{kKQ#4FQK~UCG5+g%6VRi)zC+@k-jUVvJ?pLquE7!W;$}1b;@_}L4&=Od<67#975#tF>1|F9d zVMDq_pf%KzZGVm#n*_m0a;crD^$NgD&Jt$97Ij`$B{>+b$A&~Wm{62JmGCrU)jSy> zgZ_FnLIIKKuu>_j!btAeazhcw2Rc zE$J06j<-Z5B@<#iz{-hs$6Jm!%fTXUhKs;32l22^Nh zh{|vyx(KO?-mV`M$EpL+^&0!)#a=qytq){x6iGz95~XycMx_=Ej3DV?Uh86Ygcs?YFvLnVu{& z&h?*k^XqEzZb$8elXF5q`NvPXzc4-i<1@!Be*QLh(KTKB&_!QZ-1aH=v99UBIqR=j zOz)aBed>4D{Zmr)(uX0$zUvP6PY+D%{W`4^fWmx>U`xA{EeCBh1~hwWp&%Q8$?7Hg zOf;TtV@SBhn~j3Xrn-UtAUy0d=qMFn^Q=GCD@)M^HTHGdT_b9vy5u9(Zh}#gIfkh! zln?I>Wg!yp;{lZLchy8pZjxRcXxW1yE}|N0A)gc!)u_+wXsp@~S;inE#tq;SL4-V= z_a(=8pjEGsN=Z}rB1@W{KtmihGMWyGAdnXpt%f|oA=OCuQ~Iz=`G=q$lII5;p(c6CatCbbP=R^y1JILrIQFE3p)!`bS1730S=3c+8q1 z(c*w(4kQRfH@i--5q!g-(NlZ)EM&pF!^>)w*0vVBMS&5Vbgr`pEBZDIhriWN< zDHvc75UF{{eITi9KS##D@s_(4D6#YtMLjW!QE4w3%l3xp1{U)78wl_!4TIirGglwA zT0P)2ijQ&us?aZLeUd4KTBcA2OghLl@t6YGT(y@MwQwxuD^#L`T(Qw8iok?aE)(oP zH%C!MF6Wq-ILeOHPQRQgja0st*9Y?qmQs@4Vx((@y#xu_?A4q}Np-SVOHL5Q4aPs< z8&am97DA}6MCSv98nTmezMtvX2oN_B(WKvJ8sl&n&&t9uTlEcCywL)+nK~Vgm&zf8 zE|>FoDU{!c~lQ)8bAdemXqFeEQ}5fza7spSq%?L+E^;` zIUy`GB7V7-5<(Csi4S6`w=E_r1vDEDM9pkSP`W|2g$MO;SxDkaOx084!Qv~AyWRhB zWC?`4>5@#$G$JN~76 zBIJE5`%G`|hW2=MZijQ*uiS5}Ip@5s|I7(H=mqzV#g|`jAMTnCFS)3`xcVjcJAtkl zYzwFUvirN!ck6FF;KY6nTk7Fw|If(cjlYInn0>{40>I49``y-6&W$&?ufFHi1L&Cj zonY{$`+p=%N9?~70mL{V$*2&Trz+WUw{CImfb7-s#iHEPx?(Rx6oWp0R!%RLO(B>}drAO^W|4$O_^31mDaK|wS9A?hD^3lY_h zrDFv-r=XnQtaz}t#b~wcn68L}+ z!)N1#aJUi=SjCJEUnTrdKiTo`pE1z*l47Z z^R5AwbM zZxsZ|%I8`oKziX4#`;2)P#g=T^i;<({e>}RqgtiTL9%8rXb5t|9;n@p+^gt$Q5A(%TD6`R4J5k(rId`bddet) z&4^@Ckep`JLT=osSz=#ONgI^6(!(wgT&$lvaAw=jXSRPKEVyS}ODtW|yDYGdq$7Dq z+^Zq7QZA@eD%SRN@n}1h>-F-IRp}cYDNh^zLKBIHdi9**Yu0OorJyOLp8_0in>X}f zBZwI!f;JfpAQgxdw3-Z=Eh?Qxr8yRTh9?*<1!&&yEv3*VnE>KWYCh;!W9?$2oHW^p z3E88Q9039k?p#76=XSqt&jKOg;8THzbdJ`*0 zd_dk@?r~O^qKhM4~WS>vcM~ zUK)+!XrdbhqK?ia(eaoA<9dIu*W2gb@*Gl?(mmXh0V<&$=4I-L#BoZa%F}*ZZtG~z zFoFMSNRz1FFClET(#P`yQ)rbvp=iF1qzADOl^#S$U!z~ z39FT`lB~*73^=eL{L$m9jb6V}(%KT!^C&h;_PhCZuh|1$am3GPF_P9)E7h#^KW9K9Lux4v6r0StTvCh*q*5E0k2j@L6L3;G#%Vj>ME| zF2)hwKo<*oWRd0SsLYSY9Ap5;jJ!oLc^JL5tePm7lUyR2%w=PS9`VM??cpfXtb>hx z@*K9@b>ZT1)LipGsBr(fkWPQ=@vVD0K1S;jS*g@P5y2Zx1%jZzQO(8cc|5Mg1)21h z(m;lN(B^Bofsw8=oK|=qT=~MB%g&`SE|PQ5S#Za1(`-lu?odi zN@HNAx3FTgSZP;?aw}dBR`Bk)tc^zV7%QU%$?LNk;dHu;rnGuN$yJ9+%O5Aycr}#o zNtK3YkZGyCG0hH#8MFozLA6l>Z3x2#VrpHM3wQ}ob0`~9P0SL66a<3*>aZI~_{urO z=7N^28F4lhF2;InBiPS}GlmGPFFMN&b3oq=IgdeEVd=c!>xQ~XnuuFWx&SzkaMZ4< zWilLNI=Yz-3v692dAf~QvRo0;;fx^HS-z<-nO-`gpiw?hR3#!2G?{2h61*T-HTRjB zL*6m_w<8X}@Ji=lVEc9cyklADF8)o8QZq;Q-NokBVU-Cbo2NLEzPU`>lw36#P# z)cNtGi7ijKpQf_!`=WE^H{r{df>3nCWpC8BI1d@ljlsFx=6!(&IY)=!xqYx0GE zGAUa5vj3{JKl}1Z=LinEMnJC3zXLovS8{OOEOz!a#~k$XEzXmZ>tHqhx3EMf5rOMg z=P&=t`k#4z?3^@78GL$DggkrkGds}B7MyiaXlh?Dsm{ewxDLPKQ~l7BA8a|dTm=vM z;20EnZogojlV6NEM_vs@SH~!QOCu@@H*w>mvG^^yAF2V zKlzP4?bbkQ)5dKMHp!hmD?a%m?=6b|aqNjc=ej-=JwGX$j{WwDcuXZ#wK45+GA^m}^ba zoM-mBjZU`ab}XKgo;%dFnkA0D_8;X=Yhljod|#M*b$asj7N5+_ZE#InKJ>N47sNT> z5T856iDmhP?zKm=DTxznUg)I`7`akuukJt(^K}_lgTARh&nax!~fd z`MDX_vZ;s3mwbznGv@}bnNQ#Oo?q|&{F*c2^EGG9ZFQ}=)42TTz0G=m49)I*=iE=$ zTtPn2*jwBzLEm>3<}TcJ08q0(0X4t5fsFWbSna{}ib}lSPX|V{$J1!Nj z`*B|qD>S8smIW?WuU*L}%r@({6&tr|BP7I@z4N06l}}=*k4|s^z$cWTk1XdzDcdik zIa;W)et*D{WmF46uAgTVtuj0@w$i*uApG9?Sn+}>pB&r!YU~KQdv3{ z#P!sG81?6}h$C!}Nw?-388+9maNv+^fqhZ&2U}phv_e9r-VI0bWU(x( ztSLs3ObR?&tW=e?LP9LJJBU308W%f$74-Lf>8LGbcp-x6tt1OPVxdTej|}Q@PGX3n z-BjwMaZ>7mR{Bs1B~qbWy`Iv8c}%q1M0$`O32{?Mi5dwyNOSI^t*Le2SzBHsu0C|t zikVkuj#<9A?8fQB()1F>Wx3WtQ2YgF&0TZfo1R$n&Wm@=eR<6(e?4?=?*aX+7Xb{o*8CZai~OhOKDK&eVaLbzl(v34=UwDKGY66CiS4~uxd&{HHSS-W zdHde>eyu}{`_aX@r`AmD=)J|*y-@t(y>suL_NnWGnsNC@o7$gU_vi-M}0hIq=5J*P;G4Vn77u?7upYBMuzXa!yf~rJutquIa z9z%>q*lbJaL_SoYI-Z>B4Sigd3-)ys+M$WW?w zGua0J^W$^M0jpy_`knu$)e-%>)zK~F!>rIB#@l$oZWRW>K}yk!80$ig)h%GA@sOSN0*s(FISR^Q^ zR^mYb0+hz`Y|NGey$UCro<6YTTUvZRm5O+^rdTVcQXol{=Y@c$S5BCr63vZEl3nG} z3ds5aD6n zjG-^i2U}vQ*v}|_l&qiuiXHpvUUnQrltxTp(};&rD?!vd^u*ISLmc(Sl04uVHkRu3 zyI~Vi)I8Fphlvu&Q3L`0@|aA;yrV|mj`4!xYk-`VWQeMcbpRK~4p<%g zHB|VPLt1O}!d9xPVflDPD(ZaOrn~jA4DQy4+IyQtQqV4#izRjqCa zVxyRh7J$Y%R;t;#xSkm$1KnnO+-xISqNPhP5yrjDNY3>FN_x~YO=8eab_RB^;xj^6 zf|IO-9UITbOQ?{@`}!rm+a^+D*f9!)QrCkU^${@TWXZnHz@2*;yNYVU*k7*ILyh`? zOlVgnSba~zkKY!e&B)1G1uXG457Q!0#r)*dP5$77_M$pI06jEDfO zYMLXBYK5%!vsFxF%0>(kQVpG#cstUzrCehOtMm^KtkVBGL)s_f#hj(KJ-CU-QhwIP z(kX=Q+SOPno1wcV9fwty3mH5a&Bc02y)-VjAg&f@Smk5}hr~HPmK;-!Ogg4_3Au`o z?Sasvv9Y(Ma%m1&f4H9A?v(_{i_ zA5~%O`n&y9PsoP4y%6MZvr27pNElwp-l#Ou{E#o1M% z70Bj6E&>R!B9xj1I*wMim8)VQRviwcTzJHE6E!&+Y;sCGTdg8Kd!XT7zTPPYD`mZ0 z_BS(_-Sjr?v9fr}FXvu9;2QehICq#~0q+C%n2+e|z;~PF2WZpROv+k!OiGv>R6M@A z-LS*HXdW%M1L1K=7I4KEqIw}~m=$9|J(lPcje$@p45e_vFC_hFKc=?h9uQXa=F_#9 z#N>hMNkU86e%B|oVsWP0k7=T}-fu@c^UR=cW>S$z!HWe_0dKpLDAvP;4)9{ZnFh^u zl~ytw8UX|_Jj}9OmuJ%}AP$MecqmyQY9y&KY*nP~I#)#ec!4I8MSE-j^zM}d zi}Ze6q~Dl(%X5d(7IlSSN}ACX$HXX<%pwh`9#)494`d)K5-fq8wCOj{Mzke^{8K)M zo8v^R5J{tqFN;#~nk2?$N`c6X-Si`U4W-P~uwHDXB6%$nYxncMkrvA6p@uJ|V0o(A z?Dse`6)9K+Hu(Rwceb&TTW1~LC9Cw_eYr`fHrc5{vb5WmuyxljGqxwRX*~AW%Z+;t(M@_F%(TY~B1PNe?7XcCh2~_a`ltn@m+K@;f6?H+X%1f$z zK!q=~&|Ed%uiyYCT8|>xutTxCDb!VG?q?Uc_@rQ zDlfoR`uq2{()Vyl|J?t)q~mSW96DVASU7dp%SLi$ARayiM4(bhj3L-F1xSBA3<|jJZq?E+jJ8wdUczdtww#u-txhi z^J=Ou@7mKwtDB6~wuaXyqcj?m%SDR9jW79rb;FDOb`*nq^jz!^Ap|-CMnXnzXhMCc zjEwzqwAh;5E>_7|phuJ>*CvZ}W2w?+?brd)oNQ*!Xjf&eVK{Pn)O@mLSsqG}$_o&| zp-wZXWc3XO<^67iX!GtkhV$eq!Z1Cvc8E%2^{NE{{CBQ=|6T8MC%8+az`Js2a?i5@ zT+pZtCczl)+GXGskQi2+KPce`&#<5S6aD(lZx!YUkOnUwl(2*Im*4*U(G$P&dU1Q- zR5~nO0L<0@4qz)9htT=SU;6F8`Y`*HQ@nIoIzG7e;3v-EtKGb~N|*KpLLa+RAaoiY zQt|2YFyJ%K{@@$>2jBcb@ul-H;14Np{p155pBlyO+R1=V-x=^Ue5B$l7hpjAv+sG6 z|HJP#ikChGr6}S>Xu9~d&(|LL$3K3qc)STS{@O*D@o9iy#XI}XKmLio#(NF-hYRz) z(D^f$py^5WU%!3*jh}57xA#q#j$pj%DX2`vM~|TM$K03R-~Z>oKl6$K{=cv9Tb^1! z{3B04AbzEI`!-aUH6PkPkW)~?iu@ty{HXU6XPYY&(H;q1A_FzDa< zr$w6?fN%w{mr{e=Gk-mCs;gvx%BOG&%XSZFWma@ zqovW=lc#VJIsW9MC82ohvC^MD@bTeq-1^NcCBRDVzs%yRrP3Q0%s=|Z)jNZ)-dAF7 zee*pf2%hi1ojc86hUVgDd*P|qf8orXYuDd{ zkop&&EdBibaNa%JR^Me05|vq$?Q{}zD2px^wU!;UX-o+Uq)#h>oF}vkewKo+P3E#! zbGb0gYEe&8Y|8bklTo+gP8YGFS6Y3aXq0ttQwPmIvYFEs>?z7N0zd$Zp4Ym{(g4@u zT(2ylz6Q;(>Wo_poVhwioRFcK8weiYX%=K7npT80Dui2Mu=l)=gzY%R4ZIg|vD9vdnV&;u5#Rt2&-m2j#7R&Oo6|RALWUrA(;w#p0Or`wNET>qqYbRX9 zf5vAdXp1Ex}bLCb0wg2}ez`omsCcO~YTcy82{`dssqe zk~(K5!LBl+g@qd{OWJ8#)v+VQ{7#CYtO2;jmFA|_9dV%PkGM2$kA#GzSNu2xZ~z`H zTk0$w#gHY2lj4n%e))bf@m?hp@3N$OvnCdZGhBhlRDZRZq1#OofZuRlX?DxAu|PQ@ zHYo3+HA=B#sU>Lb{(7w@I-@Yd4KL58TQgXdr~G<8=mhoh8tP$cUC6^B=IP#MnF@Q}uLIUbb@_7wfxjt*SAdTvX8Uj)h_1*Q!7W zZX(MJ(OIk+XFAlYvsyo8yGgX*4VIo;c0CNGXwk%C$r}PVq6-pwQ>lyVT+rAtQ=iI7 zonXC=*#<;ztI3)cxG^FGWL*^vENl~v+exzN&&Br0@_l8RZy9(?H}1cs@8L=DE=!t+ zgf@_PjmSsw+MvT3wO)Gc zY_{>2vOjcLBk2M*6pAKoF)gyN%g2b zAeffd(t2VzoKLk59q;lC?Yf+khI0U6E=X5X~@|7an zXsT9?Vq<~Gf$wCSop2bC`O3-tF2PotJB!hLW)UtXgYkk}>kEd%ha|FKomEW&xGXyi zd=O-;*g<^|WW7<^q>Jy|C|!2YgJ;g{vAGX@`l06lmV0>MAH99_+R+z|#z#*dJ$&i! zF8#r!pSd)<#GHWC-?;dT7o&^f#j6+o<-%A06QusZ^Z&L7sh@x8ya5pP2M^ym{N2OP z9omQV;nBh00zCcq4_^MAM_%~)yFRk#rJmwgN}YNAgh%_!Q0!m)lu`O*VGm0;UU~D4 z54{3p((4~M8Riu7k~6OsH_XyUuHm#zjUX=N;9yAw*i=A3k4C^8M}Y)Q;lSe?{};sc z{l#CHrJFzMV1Od8i~w{~cI**iyBG-q8w`@j1Q=*l><5bv+$?>n`16~k?;(5C=Ba3= zCzHC)U%7Vu%&-1OC$Oxo-ktjv7Thc0Du3SBCqu_B^-9}+Y z>$*}DEy-wR2_k?x^TrmHQ)RWDJ6zW0K=Td%?x!k;NYj-e{<4hS`E3*a9vqb?7-lh;W3hsGC3@_qikD& zTy|A)7s))U?8Mx~`Dm$4O{^kL*B*%g>dhK2CBHjpII*W97+q&u>2@+h2`-}ijoza= zxM^!4icWh50?tbF-3s4z!-kytRIIu!t0jSSed~b{=qC3B*;tCk7V(&tgSdl~tXp;P z8b~)IZaTo{jS5rIQC*$$8+i3Mg|?Ol8;*@uW}uF!-E>CTZW%traEXCYqLI|= yesterday, - LogEntry.datetime < today) - .count()) - - # Create the row. - try: - RepositoryActionCount.create(repository=to_count, date=yesterday, count=actions) - return 1 - except: - logger.exception('Exception when writing count') - except Repository.DoesNotExist: - logger.debug('No further repositories to count') - - return 0 - - class RepositoryActionCountWorker(Worker): def __init__(self): super(RepositoryActionCountWorker, self).__init__() self.add_operation(self._count_repository_actions, POLL_PERIOD_SECONDS) def _count_repository_actions(self): - """ Counts actions for a random repository for the previous day. """ - count_repository_actions() + """ Counts actions and aggregates search scores for a random repository for the + previous day. """ + to_count = model.repositoryactioncount.find_uncounted_repository() + if to_count is None: + logger.debug('No further repositories to count') + return + + logger.debug('Found repository #%s to count', to_count.id) + was_counted = model.repositoryactioncount.count_repository_actions(to_count) + if not was_counted: + logger.debug('Repository #%s was counted by another worker', to_count.id) + return + + logger.debug('Updating search score for repository #%s', to_count.id) + was_updated = model.repositoryactioncount.update_repository_score(to_count) + if not was_updated: + logger.debug('Repository #%s had its search score updated by another worker', to_count.id) + return + + logger.debug('Repository #%s search score updated', to_count.id) if __name__ == "__main__": worker = RepositoryActionCountWorker() diff --git a/workers/test/test_repositoryactioncounter.py b/workers/test/test_repositoryactioncounter.py new file mode 100644 index 000000000..e2dd36d83 --- /dev/null +++ b/workers/test/test_repositoryactioncounter.py @@ -0,0 +1,10 @@ +from data import model, database +from test.fixtures import app, appconfig, database_uri, init_db_path, sqlitedb_file +from workers.repositoryactioncounter import RepositoryActionCountWorker + +def test_repositoryactioncount(app): + database.RepositoryActionCount.delete().execute() + database.RepositorySearchScore.delete().execute() + + rac = RepositoryActionCountWorker() + rac._count_repository_actions()