From cfe842b4874c884f2fff2a73dac748a947bb8e91 Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Sat, 1 May 2021 12:47:29 +0000 Subject: [PATCH] [DOCUMENTATION] Add database diagram to developer documentation --- .../DEVELOPERS/database/database.pdf | Bin 26327 -> 0 bytes bin/generate_entity_diagrams | 38 +- docs/developer/src/SUMMARY.md | 1 + docs/developer/src/database.md | 3 + docs/developer/src/database/database.dot | 1525 +++++++++++++++++ docs/developer/src/database/database.pdf | Bin 0 -> 20613 bytes 6 files changed, 1551 insertions(+), 16 deletions(-) delete mode 100644 DOCUMENTATION/DEVELOPERS/database/database.pdf create mode 100644 docs/developer/src/database.md create mode 100644 docs/developer/src/database/database.dot create mode 100644 docs/developer/src/database/database.pdf diff --git a/DOCUMENTATION/DEVELOPERS/database/database.pdf b/DOCUMENTATION/DEVELOPERS/database/database.pdf deleted file mode 100644 index f92649aaa09efb393e6eaeeae280cc10cd324a90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26327 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

4@elwg&o! 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 diff --git a/bin/generate_entity_diagrams b/bin/generate_entity_diagrams index aec74527e0..e78e04f9c4 100755 --- a/bin/generate_entity_diagrams +++ b/bin/generate_entity_diagrams @@ -1,4 +1,4 @@ -#!/usr/local/bin/php +#!/usr/bin/env php $table, 'type' => '']]; foreach ($schema['fields'] as $name => $opts) { $fields[] = [ @@ -39,14 +48,11 @@ foreach ($files as $file) { ]; } - if (isset($schema['foreign keys'])) { - foreach ($schema['foreign keys'] as $name => $map) { - // Patern matching like above would be nice - list($foreign_table, - $keys) = $map; - $local_key = array_keys($keys)[0]; - $foreign_key = $keys[$local_key]; - $edges[] = "{$table}:{$local_key} -- {$foreign_table}:{$foreign_key}"; + foreach ($schema['fields'] as $field => $opts) { + if (isset($opts['foreign key'])) { + [$foreign_entity, $foreign_key] = explode('.', $opts['target']); + $foreign_table = Formatting::camelCaseToSnakeCase(preg_replace('/GSActor/', 'gsactor', $foreign_entity)); + $edges[] = "{$table}:{$field} -- {$foreign_table}:{$foreign_key}"; } } @@ -59,12 +65,12 @@ foreach ($files as $file) { F\map($fields, $cell)), ]; - $tables[] = Common::indent("{$table} [shape=none, label=<\n" . Common::indent(H::html($html)) . "\n>]"); + $tables[] = Formatting::indent("{$table} [shape=none, label=<\n" . Formatting::indent(H::html($html)) . "\n>]"); } $replace = [ - '/%tables%/' => Common::indent(implode("\n", $tables)), - '/%edges%/' => Common::indent(implode("\n", $edges)), + '/%tables%/' => Formatting::indent(implode("\n", $tables)), + '/%edges%/' => Formatting::indent(implode("\n", $edges)), // '/_/' => '\textunderscore ', ]; @@ -73,7 +79,7 @@ foreach ($replace as $from => $to) { $out = preg_replace($from, $to, $out); } -$path = dirname(__DIR__) . '/DOCUMENTATION/database'; +$path = dirname(__DIR__) . '/docs/developer/src/database'; $outfile = $path . '/database.dot'; file_put_contents($outfile, $out); diff --git a/docs/developer/src/SUMMARY.md b/docs/developer/src/SUMMARY.md index 07333c23a3..c3145bb6c0 100644 --- a/docs/developer/src/SUMMARY.md +++ b/docs/developer/src/SUMMARY.md @@ -2,6 +2,7 @@ - [High level view](./high_level.md) - [Architecture and Paradigms](./architecture.md) +- [Database](./database.md) - [Plugins](./plugins.md) - [Event Handlers](./plugins/no_docker_shell.md) - [Installation](./plugins/docker_web.md) diff --git a/docs/developer/src/database.md b/docs/developer/src/database.md new file mode 100644 index 0000000000..8e972133a5 --- /dev/null +++ b/docs/developer/src/database.md @@ -0,0 +1,3 @@ +# Database + +Checkout a visual diagram of the database tables at docs/developer/src/database/database.pdf diff --git a/docs/developer/src/database/database.dot b/docs/developer/src/database/database.dot new file mode 100644 index 0000000000..645c1053c6 --- /dev/null +++ b/docs/developer/src/database/database.dot @@ -0,0 +1,1525 @@ + +graph database { + + activity [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ activity +
+ id: serial +
+ gsactor_id: int +
+ verb: varchar(32) +
+ object_type: varchar(32) +
+ object_id: int +
+ is_local: bool +
+ source: varchar(32) +
+ created: datetime +
+ >] + attachment [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ attachment +
+ id: serial +
+ remote_url: text +
+ remote_url_hash: varchar(64) +
+ file_hash: varchar(64) +
+ gsactor_id: int +
+ mimetype: varchar(50) +
+ title: text +
+ filename: varchar(191) +
+ is_local: bool +
+ source: int +
+ scope: int +
+ size: int +
+ modified: timestamp +
+ >] + attachment_thumbnail [shape=none, label=< + + + + + + + + + + + + + + + + +
+ attachment_thumbnail +
+ attachment_id: int +
+ width: int +
+ height: int +
+ modified: timestamp +
+ >] + attachment_to_note [shape=none, label=< + + + + + + + + + + + + + +
+ attachment_to_note +
+ attachment_id: int +
+ note_id: int +
+ modified: timestamp +
+ >] + avatar [shape=none, label=< + + + + + + + + + + + + + + + + +
+ avatar +
+ gsactor_id: int +
+ attachment_id: int +
+ created: datetime +
+ modified: timestamp +
+ >] + confirm_address [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ confirm_address +
+ code: varchar(32) +
+ user_id: int +
+ address: varchar(191) +
+ address_extra: varchar(191) +
+ address_type: varchar(8) +
+ claimed: datetime +
+ sent: datetime +
+ modified: timestamp +
+ >] + conversation [shape=none, label=< + + + + + + + + + + + + + + + + +
+ conversation +
+ id: serial +
+ note_id: int +
+ created: datetime +
+ modified: timestamp +
+ >] + cover [shape=none, label=< + + + + + + + + + + + + + + + + +
+ cover +
+ gsactor_id: int +
+ attachment_id: int +
+ created: datetime +
+ modified: timestamp +
+ >] + follow [shape=none, label=< + + + + + + + + + + + + + + + + +
+ follow +
+ follower: int +
+ followed: int +
+ created: datetime +
+ modified: timestamp +
+ >] + follow_queue [shape=none, label=< + + + + + + + + + + + + + +
+ follow_queue +
+ follower: int +
+ followed: int +
+ created: datetime +
+ >] + gsactor [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ gsactor +
+ id: serial +
+ nickname: varchar(64) +
+ fullname: text +
+ roles: int +
+ homepage: text +
+ bio: text +
+ location: text +
+ lat: numeric +
+ lon: numeric +
+ location_id: int +
+ location_service: int +
+ created: datetime +
+ modified: timestamp +
+ >] + gsactor_block [shape=none, label=< + + + + + + + + + + + + + +
+ gsactor_block +
+ blocker: int +
+ blocked: int +
+ modified: timestamp +
+ >] + gsactor_circle [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + +
+ gsactor_circle +
+ tagger: int +
+ tag: varchar(64) +
+ description: text +
+ private: bool +
+ created: datetime +
+ modified: timestamp +
+ >] + gsactor_tag [shape=none, label=< + + + + + + + + + + + + + + + + +
+ gsactor_tag +
+ tagger: int +
+ tagged: int +
+ tag: varchar(64) +
+ modified: timestamp +
+ >] + gsactor_tag_follow [shape=none, label=< + + + + + + + + + + + + + + + + +
+ gsactor_tag_follow +
+ gsactor_id: int +
+ gsactor_tag: int +
+ created: datetime +
+ modified: timestamp +
+ >] + group [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ group +
+ id: serial +
+ gsactor_id: int +
+ nickname: varchar(64) +
+ fullname: varchar(191) +
+ homepage: varchar(191) +
+ description: text +
+ is_local: bool +
+ location: varchar(191) +
+ original_logo: varchar(191) +
+ homepage_logo: varchar(191) +
+ stream_logo: varchar(191) +
+ mini_logo: varchar(191) +
+ uri: varchar(191) +
+ mainpage: varchar(191) +
+ join_policy: int +
+ force_scope: int +
+ created: datetime +
+ modified: timestamp +
+ >] + group_alias [shape=none, label=< + + + + + + + + + + + + + +
+ group_alias +
+ alias: varchar(64) +
+ group_id: int +
+ modified: timestamp +
+ >] + group_block [shape=none, label=< + + + + + + + + + + + + + + + + +
+ group_block +
+ group_id: int +
+ blocked_gsactor: int +
+ blocker_user: int +
+ modified: timestamp +
+ >] + group_inbox [shape=none, label=< + + + + + + + + + + + + + +
+ group_inbox +
+ group_id: int +
+ activity_id: int +
+ created: datetime +
+ >] + group_join_queue [shape=none, label=< + + + + + + + + + + +
+ group_join_queue +
+ gsactor_id: int +
+ group_id: int +
+ >] + group_member [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + +
+ group_member +
+ group_id: int +
+ gsactor_id: int +
+ is_admin: bool +
+ uri: varchar(191) +
+ created: datetime +
+ modified: timestamp +
+ >] + invitation [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + +
+ invitation +
+ code: varchar(32) +
+ user_id: int +
+ address: varchar(191) +
+ address_type: varchar(8) +
+ registered_user_id: int +
+ created: datetime +
+ >] + local_group [shape=none, label=< + + + + + + + + + + + + + + + + +
+ local_group +
+ group_id: int +
+ nickname: varchar(64) +
+ created: datetime +
+ modified: datetime +
+ >] + local_user [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ local_user +
+ id: int +
+ nickname: varchar(64) +
+ password: varchar(191) +
+ outgoing_email: varchar(191) +
+ incoming_email: varchar(191) +
+ is_email_verified: bool +
+ language: varchar(50) +
+ timezone: varchar(50) +
+ phone_number: phone_number +
+ sms_carrier: int +
+ sms_email: varchar(191) +
+ uri: varchar(191) +
+ auto_follow_back: bool +
+ follow_policy: int +
+ is_stream_private: bool +
+ created: datetime +
+ modified: timestamp +
+ >] + location_service [shape=none, label=< + + + + + + + + + + + + + + + + +
+ location_service +
+ id: int +
+ description: varchar(191) +
+ created: datetime +
+ modified: timestamp +
+ >] + note [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ note +
+ id: serial +
+ gsactor_id: int +
+ content: text +
+ rendered: text +
+ reply_to: int +
+ is_local: bool +
+ source: varchar(32) +
+ conversation: int +
+ repeat_of: int +
+ scope: int +
+ created: datetime +
+ modified: timestamp +
+ >] + activity_location [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + +
+ activity_location +
+ note_id: int +
+ lat: numeric +
+ lon: numeric +
+ location_id: int +
+ location_service: int +
+ modified: timestamp +
+ >] + note_source [shape=none, label=< + + + + + + + + + + + + + + + + +
+ note_source +
+ code: varchar(32) +
+ name: varchar(191) +
+ url: varchar(191) +
+ modified: timestamp +
+ >] + note_tag [shape=none, label=< + + + + + + + + + + + + + +
+ note_tag +
+ tag: varchar(64) +
+ note_id: int +
+ created: datetime +
+ >] + notification [shape=none, label=< + + + + + + + + + + + + + + + + + + + +
+ notification +
+ activity_id: int +
+ gsactor_id: int +
+ reason: varchar(191) +
+ created: datetime +
+ modified: timestamp +
+ >] + profile_color [shape=none, label=< + + + + + + + + + + + + + + + + +
+ profile_color +
+ gsactor_id: int +
+ color: text +
+ created: datetime +
+ modified: timestamp +
+ >] + related_group [shape=none, label=< + + + + + + + + + + + + + +
+ related_group +
+ group_id: int +
+ related_group_id: int +
+ created: datetime +
+ >] + rememberme_token [shape=none, label=< + + + + + + + + + + + + + + + + + + + +
+ rememberme_token +
+ series: char +
+ value: char +
+ lastused: datetime +
+ class: varchar(100) +
+ username: varchar(64) +
+ >] + reserved_nickname [shape=none, label=< + + + + + + + + + + +
+ reserved_nickname +
+ nickname: varchar(64) +
+ created: datetime +
+ >] + sms_carrier [shape=none, label=< + + + + + + + + + + + + + + + + + + + +
+ sms_carrier +
+ id: int +
+ name: varchar(64) +
+ email_pattern: varchar(191) +
+ created: datetime +
+ modified: timestamp +
+ >] + user_location_prefs [shape=none, label=< + + + + + + + + + + + + + + + + +
+ user_location_prefs +
+ user_id: int +
+ share_location: bool +
+ created: datetime +
+ modified: timestamp +
+ >] + user_notification_prefs [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ user_notification_prefs +
+ user_id: int +
+ transport: varchar(191) +
+ target_gsactor_id: int +
+ activity_by_followed: bool +
+ mention: bool +
+ reply: bool +
+ follow: bool +
+ favorite: bool +
+ nudge: bool +
+ dm: bool +
+ post_on_status_change: bool +
+ enable_posting: bool +
+ created: datetime +
+ modified: timestamp +
+ >] + user_url_shortener_prefs [shape=none, label=< + + + + + + + + + + + + + + + + + + + + + + +
+ user_url_shortener_prefs +
+ user_id: int +
+ url_shortening_service: varchar(50) +
+ max_url_length: int +
+ max_notice_length: int +
+ created: datetime +
+ modified: timestamp +
+ >] + + attachment:gsactor_id -- gsactor:id + attachment_thumbnail:attachment_id -- attachment:id + attachment_to_note:attachment_id -- attachment:id + attachment_to_note:note_id -- note:id + avatar:gsactor_id -- gsactor:id + avatar:attachment_id -- attachment:id + confirm_address:user_id -- local_user:id + conversation:note_id -- note:id + cover:gsactor_id -- gsactor:id + cover:attachment_id -- attachment:id + follow:follower -- gsactor:id + follow:followed -- gsactor:id + follow_queue:follower -- gsactor:id + follow_queue:followed -- gsactor:id + gsactor_block:blocker -- gsactor:id + gsactor_block:blocked -- gsactor:id + gsactor_circle:tagger -- gsactor:id + gsactor_tag:tagger -- gsactor:id + gsactor_tag:tagged -- gsactor:id + gsactor_tag_follow:gsactor_id -- gsactor:id + group:gsactor_id -- gsactor:id + group_alias:group_id -- group:id + group_block:group_id -- group:id + group_block:blocked_gsactor -- gsactor:id + group_block:blocker_user -- local_user:id + group_inbox:group_id -- group:id + group_inbox:activity_id -- activity:id + group_join_queue:gsactor_id -- gsactor:id + group_join_queue:group_id -- group:id + group_member:group_id -- group:id + group_member:gsactor_id -- gsactor:id + invitation:user_id -- local_user:id + invitation:registered_user_id -- local_user:id + local_group:group_id -- group:id + local_user:id -- gsactor:id + local_user:sms_carrier -- sms_carrier:id + note:gsactor_id -- gsactor:id + note:reply_to -- note:id + note:source -- note_source:code + note:conversation -- conversation:id + note:repeat_of -- note:id + activity_location:note_id -- note:id + note_tag:note_id -- note:id + notification:activity_id -- activity:id + notification:gsactor_id -- gsactor:id + profile_color:gsactor_id -- gsactor:id + related_group:group_id -- group:id + related_group:related_group_id -- group:id + user_location_prefs:user_id -- local_user:id + user_notification_prefs:user_id -- local_user:id + user_notification_prefs:target_gsactor_id -- gsactor:id + user_url_shortener_prefs:user_id -- local_user:id + +} diff --git a/docs/developer/src/database/database.pdf b/docs/developer/src/database/database.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1c2502883bfe4f4d126c958432c5450623fc48cd GIT binary patch literal 20613 zcmZs>18^omyZ61x#@^VuV>`KH+qP}n=Ek;ddy|cA+qRv&`<(Nhx6W7fO-*&rbF)WF$_tCqGSacakTze|yu+{n7yx#LmN4Ah0D5T?TQg^K0P8=OA`Ackpcl2U zb~bVRms=Y+n+Tg2*%_O_@bbbqIXjvd*uc1F9cD{85py^WUq4d1Cn3n}f2I`@`%SS#>m1TdecUb8&q=O!)gruqL`b)zJoLCF ze9exHZ-yQ3_CWRqeLqci`n^b8@P0ClY}&CrLB4(GhJL@)X0QC-92SV&?71lVWoTEl ziq+W4g*G5Ny15*-*>h~={n_+BOaN)|BnV|9{Z)5Y$s&7AtTRxa4ey0fnBefde}99> z*Mo9BAbaKe;qemNx%tTz0+G7#1(nM3n%S$vX8i*!zzB-f<*y%#>AN6OKOe50w{d(4ePYiW1I+d zvOOwR!iwc`S*%g_rAYubG~*b)%vu* z7VhCT-IV%|Z)>JIT7NrYmXV@h9Czw)VRWCV<~P&8u}D>ABGr0_BY1`Q(Ps$}^7gln zpAfE#UfC4)1|^f1*+Gydq6CjcOnero(=(3^$u&7phIM!+UlYvNl$6ea6EX9Wk>mgb zY6{!sN2&_d@ES{?OsbbpxE&6ks;K6fsldF*3`knTO14&rg`M<-o zBN;j|UNkym+Yv4S(|xI&{R)|;)KryK=`#WQwflmLH?o7BrD2?WjfF18gmiko$q4gH zzG3EQBy_q0VSo7L6S_d;)N8v*f+-W8u;*e+56&(yxPQ)en&PQWR>c&Axjg|v_Q7PW z-Hs}gSsKEad#H@1-?*zjqtLdx;xD(l%EX-!?RW`6LJ1@K`tBBA!Bb6$j?IwJgR~;r zn1Z4%cjw88V!waFlB*@Mj~_@o8)-L=+ZrdsZ}*$Xb+E}`=t8=GV68pe?(SnwN1Z$G zd;VC7kjTrbxgpha7$oYofG4KaaH>3%#fEW+mghPI5+wpb)0NS!3Vg4@dgs-i2-$R> zSs$&7fH($ms%Iekhw-Gl)5eLP0cwpN<#U8Y%oi(F zQRAvoi4N62bTG-2Nlli10=z=Eb8^BrcaG=`bhRvuDR!CD~Q3dM`dz0Q+o-GlIhc=U0 zH~PnOG@`iZS!D-I%PE=1C^thE-iN7xneo=n?_}al<|2E)4_$|x1?~oboF0Aq6?`5* zT){uuFw=56-kY{s;KnA*0OkzFV`~C_zD@G@8>MuQ*U(o}vXX41isoDgCeI9p+lurE zIzgexw%nOGcepv)ySfRX+V-V@K8}83U}p~rW_lQg&&GCR;z{f?lPq`tLkt?>V%>v5 zDTv4F1!m?Rrq|*yV>cYd>P=WJM{;zr+1>@sZHIm#9aPftWOpO2?D(G{O=$2h#nFJ!;E@>XCFJ{f#0TZ% z-v=gTZA$iEudp0F4go_35dtCN+p@jyYJG`NT{@n9Buba}Y+K=j`$x(82$J;=HFD+a zk8<4!K{)HeQ$pBG90M?H0#|$8+lpidk>UBELIX2U6DLHLP*|Qn-r;{pmOL5@y$Z&) z>)0caH95wq*oz-N?cBWX=3Kp^WEM?J@X~>8r1I%^^J^Q(i_bs_rBR_Cygm9mXo;3q zNgiqkchNKBV68yJ(K3y4ieNpff^~#$nLkJH(t*Gh7c6=C!Di6>iFEUN zdB)HMmgg*ThTTO`>-J*J!o_G;|H5rgX9KB8g--k7)bLAPxdHUP1-6cgLS1jas#;21 z^`u)$e1zCKDSzkufY{?K;GhLHZy~@(FN2BYHZTx0E4tpQ+Cx|b6qQkM)^^U>vQ{J* zv`CQR4SL zJphfx5QWh&-`AI$zPj)d}T?@@`#+AwM5I2WV-6RO)n%ZXEgY z85OJ=;VW;=9c!Z$xwv2X4}xI=96sVfvPf8&+DuuK?X}A|3cqGBdLN|r;BTJ`$A{$Tzs{u{X_L`vIk#0% zU3Mb;PlQoW1sDE1(S?7;C_+_5snA8)W4FYlZH>^HcZhVW+bD?W+M2HX&(RzgXr!ET} zF$M55Ii+Lm$F4>4dPEz}Uj*ljPEpPq5zZUM9pe(Z2|qzxB!wkoW*&-vB9D!vc-0Oc zKou%c1!sRwZEK(Xk@v+Y*u;4g)wJG7NdoSGX81-0PnP4~Q-?8}3h%0g%Orp=@gc#Z zQ+$=a+*1CPz(3z*4f~zTg_0^wDY+~;iYlq;Ts(jZ#IIZ6uRw?mqpzy3%GD*Nzr^wI zxF9FdRqf`jwTpwzg1~W9Jzn$i! zHB6&*&)fac*OWtHs)$Eo+7S~(_3Yuy&+7Vg<%VI6-TM_kJ5o9@moHJ7=ANqJW)W68H7CXC|c^l zxot=5Jr9)qTRt=hhaMrZeF1Es20|a1+IbUUC7Yap{Q9Jno-OYP9h+b0aTs+slIHEH z!`lq*Mc_5;ozlt`q6Xjh(0hsA@8-3udIWNvie$Ze5(!E}90`m?ig3kKIuZ}qV;r0Z zLcH?B_+gB%bm~@~q#$trv>4Q^C_qkTW?Fko!p#RA9mH%r9NM_@VNm&R1lkYLpBraSzzO=TuTSZeo= z@vduQ-M6Q`U7gO7aF3MX#3azR4ctw(cq{=Jzwh8`Vy^?@?hohLYPxPt4Khobo_{BA z%BGs@%0wC7U6YmsUklQxx$eVwNUVGvf9XhjiPE!kHKY@2;5aZCw0gHD!l5lWXQCQV z;K%lXbmEh}--laaPE+7!t9!j@l9TmllC`}KN+@;vrKN1VegOndmjJz}>-o~T074I7 z`_rItGO=0MA$U* zJ4KG=7nZ(Q!ug)7}Sx@OK{%|Ebjg(j7%HkeNnJXg()-+WBB5 z`J!a3!m|7((ZMbT`-5~R1PB79d$|wAKS=juiyfs?v2U~zC<#=SWRKhqn7ceMRMTho zTZEX1fQkAjvAsWwZmg%K%IdRBqE%2qdM)9R-%Ns*KOwZDwM{*-Fle6}yiF4%P>D74 zv9Q7?R=g@!DVD}n>)=-cnT}xEsFk0y`xVP?Am*ZYC|KeOr+r8?@aG^l?*~jVbLgT9 z-HXTmPSS|Tc&^($qwKV3GjfMGlXP((o)6H6ga=}3uY}%;IELu-4~wfyK&QB3;0q$w z80r`6NEU;*S}C=8y`N9m{=nUoZDttnGwz*^)wbvISaD~|ou}I$&p%&HcD{Y_W9%a= z&3kpwkg|n3@WaCU)>ZbtjyRopH}z;CBMAaEC)*}j3BM>0K7fRQ_=m9K^8qt5tK{WT zGIz!aB_275GLdJo6>sh&x#(2a&JM2i+)cZN4+v<#Zo!x&8B(D**p6%=8{(iw3E>ZH z)gyUp+q%EEUp{eKym}6cRKsI+KIM=H;+n9;&?l47RJ_Sv#?s+M*{qVhKboUTsQ z(kk2%+X5D}=B**WRNWql;Uf&|!t{t^Z~~cQ!v0Wvi`fgYVyoR_4SJUI=sO*?eJGD*ckwhh(vI@)s;l-F1UX1P z0WI5lV`zW2pqqOF{X1S7K!tdy>G3l5(BVCzr3D64EQK? zaQ2Bxek$85&8$D#%&BB_uKyIV(_DdkMBJ@~2=*0u$wlDl)_~?0u#A!Gaa>rc=Dgd5 zsYs)cj65sLHph-4eqvI`8$(u4y_5S3Z4zUHB*aLub(g0e`Ixyr1vgfzLFmh}@*-^_ znEM@H+7>WUo(0-o9i7!Qm714U23eZvC`pz;n&{%Ci>X9~<&0`f1o@MTU2@px?+|a~ z-iUUAcHT3Ep=f}tox|f*m~cgiF!w153@ibPwoT zD($T$)=c?AFT0}9=nCoRMN>#iHWLoA8EHkCf2#&+n!onepjqj9bg|XlS&E_3{KB7b zihg~W5a7L~C2eszERo(IwUbt*CU!syZOg#vKC$1(0q{)TQeWKB#{@qu%)gNl?2zIMU3`unHgB*aN(26TtMP+dsHR-|TSMaGr{ z!Ov0Qu>`&OpamI?TxjORq{aKb6;CIDBTu_U1e;KW6{Yd&%}+271VJLcg!!IE>YI+l z3=F)vsk2u4PK~ogpbg&^Bed*3UYO@Fh3EEeOs$i2Q6B&56%e(i0IFrW-%qQNjYv@A z8Yp~2iCo}M^^AwKX{%H6OOJo>TGZRrj+ytcb7#LR+D=Z6UR#T#a9uUb)i=;vr8Wh& z!Z$eVZQJH%#EZaWI+*T;_nxsvdl1k}IC>=r{n|R%mQZ|c?UFaHcS|Cv3}q)Ip?ggc zM&~Nv0qccCOm3&e5pTp7iQAF-$Pi;U?^#h7QKONHh85{D+hP?lgi_F$4`4FgUwt!M z4=jXZl-#bGAE3}zsH8*E&{Z@a_-r1{R9F9Lh~ebcRvc zycm>H5T1X!-BVMCaXp;+32Y8U`hl1k*`D?488%)<4zhlfCs0n*(k(Z`Kv~MTlyPLL z4=Dr5r1RC<;=x^rh#Xl$^9wX31Q-Je605F0c5L>}zGoV6IM3tkkePJ@Q=sy^nmZlc*l9TsVrugWQ=4+E4oA} z`iS5k>k52+Nswf|z3|yX&g526`uuz>#gJ98;EWz&9mcmMvg($*VdUtNH=#&A6t|K) zJn*|xkpFp*7=}$ZF+E=-==31aE!EP1Tx#zX*AWtOACHQF$d(|8e=jci2rX)Bwd<`t zIvz80ZyhXUr!H3$E-AKJFt`LO$=b;S-r~K19hOJgCW&_)q~kZEVel$Bz<;Hu#ioH4 zhmQHDF{axv*R&yw`m&0GqvGhy<;9|$cJcL?k%s4YA5jZyv`X(te8_-8IzGb?*RoLi zV>Rg-o_&U)t(@wU7SFAieL`Yp#z=g0Gcm_vY3oHGra{1$^5;q8wq^P=g(DLLm z;H(y|hl72C>&x*RuXi#H*|S{=ma<2jukE1$3}VK?^4_eKrz*)n5n2R7o3LP@A_ZPt z7AOCZ6&bF>VnGNE1GJn5WmZ+OvUBD6xSpVxWydePh1GBboygj-t8)XVJQ;Enwd!HH zml>Uw$dpQNhI`JNcFIM18-8;6U<9UYK~G)G!~?)ZP-=NPgjuJNFhw-kFABnJVQ7tR6~^Tj@U*A&-wIGGb8T;R{MmxlS<9|=d;(RU@rC= zokK-B_iB8Y)Uu!EtuelGi%%6Nn2frXK(cxYUwJPVAXABb0w!aPzLHDnWY}$eU6sOj z%6;7P#_U(K(+ft^*La&mN!#%LQ3*n0QbM30^m0_72_glm#C)^-1Cu{^_}wJGF^Hgn z93lXv5m-kidDucQpC6)J?`@ScxysvB%9uVA35`u|bEXc@5w{z-2Y0(%e3eJ74$avvU1Xq_ZxC?r&R0U#E zC7)!gWoKG`3KRHyg>dPnPp`jq=&TW&E9sVIO`YvzPU13>>_wFYCJY=II~Y%ArpxAZ z;TJM!yr{UQsyJ%6wuEm-IvJ8cz2RJXFj&TcxiBYc|1Cm}!50W|uMCDrm@>fsQ&eOg zuOieL+_Svi>_lM;xl~f3;voPhyo%r8asd7ySxIU0Z{c=gqX;lA*T@zI6x^M~c@|pw z*!E=JM_i^${TFK%W`Cf=&itVHzDdn~HyYdd0FNG%0p>ZUTl51s(~aqn+!Ah4f9@Ba>(IMK3f# zlBxMVihT~neMAFnF3#9o8bIhURMfa795uuIk>3?Xp*I|+x&d3kL#qhZityjeaY<7> znLZKq{okh`G_mzSs1TJ6i>GnfJI;-_#9oKDK*W_P`8ibMmf|SvkT_E+Kq~jlQz}Ve zIme3S>`xMYDzaB}bp~S_ksgf-sj#yN9L7xvLj*m;L}B^h%~)Mem{C>W2Q3;<4bPQg zSaKvv2<&U@GJIb5oVZqYU=(#MVzM)WorNO9`x>m{bW347rUY(`&aLfLVi-P$5l61X ze1hJkENQxCqROzCGQl0}~HHY~(FJdt!PQepUU!vi`2D zSSr1j)f2u`ezv+$Hp@CmlgfO1bJx`gvvfvhlTl_R z8KDp)t=-M-D0Srg@!Z3+m&Mn|I_7W4(bK!<_&w@G3`Z_R42SW#QUZC{?D@CN6hpz&}NvdS@``(^uw zh^_K$Le>ZxLRuiN!}09v@6Nn@_TTw!TYnsdnvxQ;5mjZg7Q87qb5o>`N0nk@#&aFM z*p2fIU5L?|Zbp@}t_4k01x=JT+}5mUp08x~{}3OHKjRCgdet78sMpbx?lhiP!fokH znRZFjtce;b#?A$PVe*6rC_+H6$8PkH;-LzaXOnPSP%vDC) zS5w$GpMX9?NW1kG`J7jw?N>Fcy7oFN{ocn7+eJz;tPEi?Y9tItV9Sl4yEkmU&!}QV zubwqa(0wyl$+v^TK7T2jrE$cV0bv%dDLWV$E12cP2C9cGfDCwqK|hAkRKrKet2@PG>UMDj}BP(5p*9lae0>OI`+p9 z=g-I59Rzd>%5c*hg*AVdO5eNB%QkO1L&a=gzrR>$oxfM9XW=3IW@4e4%Gt+sF1(4e z&0~AIJ-7XvX3Q&@Cdy0nNAKzO%XTbg!Sz}7+n!l}fViKEJ-+7(MZuC*s109r1TXl0<`}`71I#3-&MJ(weeQFoMT>m5>W0^bY#c) z!264cE^KRk6nve=E`Lnx0wu8Y^wAk5-Hezq%g{2JRV&;e{_c8vrjc~1Y?l^m>)tz@ zwqA|B{FE5ojJ#zvo*v0tdPw6C`Mylkl0#@iG!pyNL?PT6Fbmdex1e~p$EfO|&?e-$ z0@=)#0q5fxCn_Xm86$p7Y|+f2SSP_4D+*0SjZGCV)dBI=m_VH$a_z*f|HxQfSdj(^ zGNd5)xA9ZR6tUg0@2B-Xm>HQx*7hG%YlP!dIe#!t;6vR8~}!A?MKAP7|GpN^bgvaeOgsXF68v+FNs5u zcnfNJ9k9rcJ^U`)alTnp8wI4wQR;pDFAv@%VC>I{OxTCiIMJq%>H>B)K7 z2cky{!M&zHBb1>zh_MQvBI>9Z_${#jZu%^0I{%%|xWdD@Koi|=c6@&?!(k_zn5F_* zt`i)kk2s6;4B2@MN3YBhNxMp|T;o%yw!6FG*jgfnj$Z*VXdr4%em-EWi(A!9#Oans zs$R*|VcwDF;WG4Q)u8#Kixk2Ypb_=3aX9L`PvUi^^1K26UQ3hcZ%5RAs`FbJc#;c5GKU_#B=Ns+ zs>!{`o{8Uv*2z_+l!{9BeyYvUf7YCI}vwO0s0ZtUi31@yu+4H*_s#G!@4?_omatAY7t8*;KlkAG~;x)G)V+b3m zqpOg%8kuv@Qeh~nPUTfUxX>!8+;FwRH1=E$1^X69z-fb+F&b!UCl8~wURC(Zj29uo zrNGJgjoCZgza(O1ND2!^Aa=_3mqYkZx;m(oQ9Hs|6n}9lDNsm#x?v*9PzboNC?pt5 z*pvjXNz_W8mPG9s*R&T!w5WN^Pt$Q7quGg_@V3~S8>;37bn$(7pA zwj@gpAW*lZt%QuTP9vh@E;aAjbMD{lnGOWU=H{$7tj@*ku&`Wf<$EONi>!jL(PAR# zgW}uJ?Ef24lrp>&j=xw{)w2b2h&-MiFoJ!R1co-UZNT9nI*FgqUL*gj&Dwis` z%F#AU2t_VdEJMj(y3feUN!lF62Wc`q;&8$^6!N{yd4%_{%+atmIcdL4adpHvc6k^^ z?<%?J^fak~G6o#js~EtVtb;fxd&hvWxsEJQ&OfJvnJac)?^>~Lx(t(a4wT1m{y7!) z$%L=5Gc;16#)^`OcxQJl|MFKI)B8N`bfYrgUqm8CZkJ~VolLU^%>Xs7yb28g>JU@|(>N>^7 zwPb)$hMF|h)BZVcU?^ICm2f&&aoxxz1+<2+Lwvh_q`{CBb%M8q)Kh6H^4#~YWTn#& z=?hQ7zgbh!z@T1V^lm~qHCGRp<@UgO%k$ViO~A*<8kL-Q5j8vk!Wphe^5brtptj;D^TYyVl6sp+}I%ZA1uqgT<#g`=t95~GxAkBnNLsR&MY6)8Pi zZPBtZ8IB_Mg0nh(^-Ew_k9vN9*FT2^@vxq4lQban8g%rSuT- z+@ujHE)Z;#PL~9y9K7*J|*<&ll-$o=a3{fCWO z4MnS+lNIQf+*Pn0O-+AOSLfp?PTbY6033;Z9VR7j;mfWJN46>7{iD#e4`E^}d2<+q#zP9fW zpM{kxXQrsxwYa`AxYHZ))W6mJ-?&pNaN^&yByMd4nCjy_f~@Hg`No&1u}eWqk7*o# z9DN`XTPM>hAjGtK@Y8g=4>7576D;zX?%S5+BdT?|J%^%|t1k8j{esC5+}L9}gbf#2 zG&z3T)AcBDJHwkn31A@UxfcguP!GWaT6QTty0RJ<7E?Jl$PCpgYF2u@J=1V+Z4zo& z`%GLKxvs5EEZ^JiyQ1N+uM;V~#0B&M;!{E$)n6Q)T`z+_^)|OY;8@l#D&L`5wujYv zLcsGPsaUuUN%TZK26<&)WoSVhJ|Y4rZH^(M)G{PZtg{up_Zrdgu6EOxjEK#xjJ zQWTgz%Uz%}KVd;>NvIU>S>A@cEU0uF@=Mmfw{XAVJA+r_x(Q_+45S@s6z`f9;`12v zdz_lGy#~?hu&9;qer&-QB%m2(ZFk8n`H{jrJt+D&8fd-w7Yv`TBke~Z<%e_^c8@N# zLP%J%4fjIP?_dlb_oxJBZ6v$~^{k6DU8g42>`I2ZSPt!#$mj^Kwa8`;jy?B?vytr$ zI{z(Jn7nF~w1V_y$Q)+|dfCtFn!*L>ixCI+*QCFGHCjTIvc5I;@~{BpDj>gT>?RsF zm8=f5yp9FI^2+_t8jSj+>;lyI_zcwes6s~95}y91|GP5abcOR!IG$nw;*>;zZI7L! zLu8*PovnWuCD)ADJSpfwPrBBe=+pKYp_(h}c;OJSXpNIw`!BFg#NAm;$@w2t2jJ%ZkK^A#Z@}=+0MH8w02l%EMh5@V zf2iHR8~>fsi`v;b|F39MS_WDM0PufMy?;Uf&i^aM^#8;F^vWLgCIEVQ12YoU zKru%<7yJKJoBvk%FYo^}N9muoqk*lH{eRSqJpRWm0dRJ7G5H@$=wFnuiK~T?iK3X` zf1Llfv5F>6b}o)aCQg9=be!V`#&A}zj#IV|5vU5KVI=aUHji)BO`#3k(CYj z{~;JRJz>?+mRGMd8;`o_nZ2gF?ewoFZD4JKt%XUcVxF~Fl;H)Gh^PR8qUDkP*wTvE z07k;_lyHd;8!JVTOm)L3!cYz*IaQUB)1ig%sSQ>{pnv;jtiW4r#` z$yWZKz!f<tPt%gBD;rJAs2e{SuzjpiTB;I#AI=9Ti6`)B$sOZbfMh*qP{yX5X$UHUe%-*cAbxSQBUq5U_-6hIOOd8?DtGPI# z7)-f@J5+a2G_;%=QCQ8-iZ8d1ks2HAUsb>u{ct>P!8>09y5cV(#PTV7?5X`pWqdqX z3d2vv!01uF>72gZ;8R_$_H{<&bvkE5voe$6ayrqIovhl_Y6XyFa zA9E)3z9}=%F#VBKEnyBA^tB3I4a4OHZqh$LYI{%HA1;37eBo)5T_ zy_)6v)LS@Bv)7?}C27dP)+CrL`QR~;n zY`}PW#V@6jsF5s|({lqfG-F-TzMpKr3eHa%8VY1t)lezAHw~NZFKNs|RPd*Jt;|CW z?-@j$*o}{{0?&o#LaWdNj@7Y=1(*~Pyl;6jwZfQQmhhSnO(%2oMn)%6uPDgx^@h-W z>J4xE6a<#3B$X0H!LF6YhwB{puCLqy!>Fd}k>iCF z++ne$Bm@Q8vU-V|M0LRx%(FI6rTdhnDqvv@n70Y5*}E)>?yp2Q5wy$j#Mtu7M((0l zpF6ZTxc&j(&)Nf{OZ2^|xZkAgzZ=h{G!IfR_R!iO=Cclx=F?cvwT)o3`V}j*!;h7o z8DA%Sta-U|sgYo%58J?yR3}pG7tMdx4Icr-5Q$3sfDu`X3=3V1!4@}VT>e-n1XzYyo4Oo>7n-q z*G*;kQze_rGk|21K~@EXbX4L|0#Aa4P7;fVlgg}!XNZ)85P827Gk0bcPxHKt!1m&6 z8pqD|W4Fwxt?GU>l*jA&%EG;&U{8G1ko)aOhTGBsI$8Dhv6EW&eUQNS`8Ib;pkp%? zqGm@o1G=>44)f+zqa|W9(jP={EUeU(E}Mrk{OT`tn5WUXVf~whzU}t z36?Jifl zy!u9v|L=hD7uXjVgymZmOoZT|U3qrKtR``7V@+dSV+~YwRBcqvB=xi=+B(`c+9p~D zEk&t3(iLP&32O;XWOih3WX=S45=vb>UA~XD{kHqI^S1Z4#|`>vyA z&<;^VQ0Rih2(ca9ei_?in>)lEFx>mKHJA>E+KGweaKom_CHmDTlK!1p(5+K zE3J?BZmDjuf9mr)%y*jtJDG^K>Am*ENj`rco*zwSeq=vHO$;r*`yvaNL%D(PC_&y8 zwp)S@a-Adf)OA?5xf^Yu>aLUo%{4+lsiqAyjpCm<-x2SS{_b> zJpt|J*Rj{VVfL(n=eXYaP{$X_n*9|+ck=zQ8q~}O#Uj@2{h9GZ>H2v}pVl#QwW;tO zEKT^;AA80|aP2R=6f0&)ki-6Ywwh{$>F>?I1?k0eLdhDBfvS&GJ{5|o79>*E*qkn$ zGsf>YFcmiW%PIu}IVfku^T1Yz?LoA;bt}*xCo7>iCO$sOM3Rh&mbpR6b<}n>@l+{3 zQbm%Ks+vhDt3t}95}&*)V~!qS4={-Clc>=pYI-a9+XS6Esnn)*K9ZS?VyjmFXlkqe zd9M0i4A30KshL_IB|G2U;dYgdFbR2T(i^F!rluLq4IhvWsSN#+!u4?Q}>FvSvR(#$|KJ1N=edxO}%FFk`|x z5y1}emZKEvhi$BENe~fS+u2~ATXQPt6-%h$1lcoEcs7D?GTZg~@Yhi4+sq&wsmzo; zJ=YIs-!HZG1; zU2!?8W-kYuwOa7zOlB*o3El=FTem98@@8(2T$l3+TzN z($&awr~?)&#%=xQcWDk7G>0{Q1LIRl_#M>C^ViHI*9QD1$yxJF?o8X9&C@(*ihv0A z(A2bS9)AZs8a7+!pXyCM?t_W&(O%C$L8_k{+nOp3>hFV-nQL4>5@5Qz&$Ib_K05h6 z_L|pyA-(ozEm`-R>{A44)jqGibf&4lyVh;Kqt-E&Pi>bw745^eGi7seAGk!PEo+sc zXAof{m1wiT>s3_IBY=V$huvScJOs}@rB<)XV`S@MTpB)yCD`Ad`$Kw&*6XhPUOs5u zQK`Gg-X4o{Fx9$VvRqY*h`gQfhMLpbVyEUYoZ8{^@D%44#aDCwNi7J;B`FDLinllV zfk?SYWCbKCkM*Wu;TH=x>S(3oKi1`IF6Rs1Rcj%9$0ij;;m<&(!2M2s&fr4!z0YYZBvgwSE8FtQwr%A12uD{-hkoE+J*wTO_dY zqda-PdDZhno*asZWy@usxm8@q_pJcaE-YSG&~J9qr2Y z)pNPK(95~!IwZ{&Xn3YJi92#cRXI9DxCYa}vBr$5NNSd}Nv5=mo7%nRrT_l)(}&I0 zyq3QDZ|u%>pi8VWjZSe$Gw{-awkmcupk9-X*J42p+B_s94bV9$Y~T4I6Zu0#HS^B- zZ{lvC<~XY)jL@HCv>#Q^IF3_Dr#zb-!l{1c)D(X`>e$=J+##oaLQMUfF=Y31sP?K3 z6BOC5=yBfhqozK{T86EU&`3{Y=8x#U{fHXALw9L6@U(Zk$#mCnZ||A2byUs%3vETS&nT2TVb>4`D~7Dy$?V zduKX6)N>^b6tsFA556VEppJm8ctDN^hlx9ehZq{66X5S`oBNtO_ zyuv0?<=+6bgHAd7;w|HVhc2cQ!!SCY7upLtJ2<;M+?tCey+Zi8Vg2cX)vQXbNT4*$ zVA@R2f!zb22Y&{aQ&Xns`)0lTnw+{E5HCIW7#HH>_7*NgK&#z)86k`&&{l#_BA{7y z4o0onw%=Wb;3(y89S0o4P|bDov=smT6UmALe;Cf68Z4miRyJ-hA$f^V+P`L7&uNfM zuECMRoK7i)KkWntbLN_2q|iy=P&d{;a_Z>mlf;L}?i4c*C*ZB%^{qX+)d9?0{tGfBSr2Xj6L&d1*UDRht&3;6p}| z;AAIQiZ!C5m!ElR^tOs%jr#ScA@I~rKwU;^^i?XU2J6P+^m!VmpH4weLQi(5S_MH` z7_IWvtH!7uI_`=Ky+cb&LnSFosij?YcPP?LR?D^)%eN$1j@R{&6%(<%&Q}*ru*Xw6 zFRzt$e*8MQJW}WHdy!Au4z#{V*MEnRk-Mp?XMC;9`=I@w5l#p~tjly{@+H9({*o3@ zO!O9DRX2lnEk#m84bIavXoMT@QFd;)IcU4NeYe^An2MKj`KTJ0&qV=|pqo8Pe%#$C z%R^}fswx`K z&WFR#?3*arTBLA1Q{8>kIxpj~+jYMjbMa1mdE=X3fyru!e0cnwye1~(Vu^Ne&aPZs z;z(zVaqf;P#^zCJ?35j3*9e226`-#kI!hq}`j`n$WVEqJ@ld0ciq$a^F8HUyYGuO5-;K1%&c(t}DqCy1Prqv$3DwB@KGvzDb^{&E6CB$z6bkCN0`ql5;ff=+ZV z!<4gC;Ma21XPxDlr=dA=}sV z#H-s5E5!7Ei4*&{QH4_lLI9%28knuS(@4aM^%__#tYJ~>k}5f%M#bMAcZPHsE@L<` z<-T-f=ps5#j%Emhf(s=+7o|ug^$2P24-@wTPahOIfFFPf1&&Nkg@T8Yox;_Vf_dSh zCAW5ai4_uGesFPMROwp_um9Yvr9L-hN$@kMx}Lk^Y(wMnBFE?b>0)(Rl846&9q8u( zzTR}X)~Fc`q$k`JJ(bK7BnKV+Ji`NU5JTJpAb8?BY0Cs=!t5pl(|5Zd&>9md9wy>HKIW$A9Z& z=X`2n&pj3bwEW5eCaq&-63O62RVd_W57&M=oh}}F*k-ut}duJpaVG|#AIBqf*fqwZ~aP(+vUQxN(?YOmR7AbXwp|i&`Gnx+d1tzLT zs7WJCnP8wQFrKbX*(O)Zj$YreZ`K&}F*u}AE@qIKjGVSOzuSuqq#unv#4^P;L^T|Z zaY)uU1^Q($3~~=L4RWezP@qPJl)M*%Y6bk^r^FbWFbUOHr=zc@t*2L!#51We?75W~ zR3=|uvAkH6%yw#RSg)UNpIdp!k?A;@I~>(PU;(O_5F#xTYR}@2e%P|WH=3ah1;g(^LL?! z9kpHu39oL9Il^9driXVHfUz#Xv*#Ktz)j_WFlfy<4jjudt4}+oAR_CUEbxnuH(xN_ z!;92uNt1a~!va-QFszb&-Sc9MU*WsTjSF|f52!=$e5gY}x)`FHEhX6xXO|uw+8@+5 zfyp7AQoh0-moS35$#zJMb)jcxl zrQ?*wZw>fOyCr>#!~hB@JO z(3v8bLR%s!4qffXM0FJTYG_cdZb+q+!WpS^t^i+C3{0GiW3pP+tcg+k*(}(sZlY;d z)1s_ZSqy&%u@3RhX%b|VTBmg3xcGxTSb#9%QBIQ4pCax5lyV+GO>A8NR#6dnq7(}R zFw#qq^gw7rAXMofD3%aN2!;fcP!$ys6(w|#2&fbl6_tSX2@(+jg(uZQ5mAsLC{a|5 zl>D1u;pzM{|IDAAJGk`|@np;7zIW%ooOTVN(|G&$7Od$m z_=2^oy1G9X;Ko5O-@@(H+|mkEL6Q?5+K)UHGR%uR^fI;W&yE<#AFD_=Cz&ds5lTlt zoBE+u;6Wqp@K_uIgp(SL-(HnmNz~5n;i~4Ic5rlFY7WDqP~?(yo%7x6_E&D((H0Tf zb!*RL9q^mBn)#*J@P5l{`z@!Y?~-Z$clY)y^~4OA5e|U17Oh| zt=Z0YJ<^~E54lW*@rq&{(7FeO+^Ye?Gbh(6;)PMOxBH)-PMN7n9J$j5kr75*``1|UBm6Cnk&6N)*Rxf_mcjSXY$JUPedmTG{`0x8<3TopP&Ik!-a8YU- z4o~DtHXDRlOnwnm3)_bjE$bx1Ko-m1wd~v@)7AW;nK;q%@|(#5y~tT>T{*M&ht4my z@>5q_IxZvRvxNqhN+W64<5xuSf)|(-fR{#ZRPs$-_jaL_R}GY(eKdFg2XS2Txv5}4 zNE{am2aniZTW!{v*qiXhg8Cv}-)&V_vh2Mt=YxxOPlum;22#1*H2myt3U;?L@D941 zRjzitf}ckuFpwMHj)xPU=Lo_P) zmsJm&ecqJOU&z}#cyQwgGdfXzU9~SHLp1gR~NR^ z+y)P->Q>+P0F9}vZ7?dHX{wRcz7k)|S7kZ2trPY>v?SS(hSn@K?d4#D_!m5npXYG} z31t_??-7hG!X5F{JkMo%)#iDB`zlY4>+(RiOkx=kMcnrnEib(5c>Q3{E$_0%mxD`u znU|1j1+SHit34}+=xa6DOH5jqHZb}GjEZ&OYsVg1nd6^J3n zhEYPBx6Sr$=f^n>2HK2oL6S_YL zNgoy1l{>YX*P#&2rVZ{0!S2lIl0(zbIF;n|p;Ly0Q|%2ES_7Qb1{2QGCSDrwBOdls zREC?jYYI5jR6YmIp6)x)Gz~tblKODg$DqP8;aW}jWuLZ-ZBu=9v9jfKnHK?ChWayJ z(v;bKtJ_P{bWXeF=y*0L>@jRokd7`?xO8#jc&vZmmn{vwE=e7nPyOoAmB(pYsyLLG zgt6$_+A(gLx&Dh~TiKBrhhJQUE?4fXx^%R2M!K^qq4zo>q0`$Y;=(7FvR!29PVS4k zF?+BnR`TzTg)w*7)P&7+!}Twl)l+Ua6d4Z4DRg>x)KFXPXB;^fCex2#wsMXX1y*EH zyL4f>iskO=;fBRe@gX+l1=t4aEr*NG>S0f;$}N&h<8z;CrCwJSoWfsx>YJm_F6E}8 z^s8bJ(ZSwo6K-05S#~}?CplSgzuO5{kQt6yR}O6U>CrTJw1eOiT)a10&U02;@1?bo zkrN?%P1+m%ZQ0h2uL|38i;E9InCWMg{R-1wKhVetU_;cb)H>|b@OMpf&B{2CwuTzL zVmFP+UB!K?7^m@rCsLzjKj!N`tlk{(5tFe;3m#dBP3$46S2#8_*_`5ZT9a%ZveXgn ztKk2*obymeJaIbb?31IH75Gt;!zoR5P}tO@$#M2tLMluwS>zsW`S`rfwNx`~{KH&a zT?!N0PtMp)v?b-mCwY!=)o+_Vd)%|lhEe}K$KO9=vbX`bnzD_!&>Q~Qe`er z0-_e+PN~2b zdta-y74(5GB<~*<-dHH)ODc`*UjT|vO8*nt5b*=wkqu**G4uyTVe%(w02AR6|J&9` z+dLX+{m{QEM-5oi6$z@`G-cj0Hx#b`kmc9pvNQKFNnv}2ub6yu>AI? zH?jh-)faq^?OddN?-e&duV$P#o;lf96~MQOPT6;Lreib2Hs*|yS3AA6!n-#v@{t|i zefI*{V|F_QB{Z2z?=dAagTu*Jv93JVgQ{ho&isvU<62z1#`|7+3;AQ0$O8(<(+ird z%%={WDmMFsdt#?u%vs4ea}pG_BYGHk%lhQ-SxS&G=*q{T$X})2)~{$$%CxhvnphtN z{=D*xhV7cZe%Dd`;m7;l`&MSFk9x1U^FE8#kttwKo``O}@NHT$e4wfQ&(w<(`aSnZ zDEde0VInr>2W2wHwutZ>n;<5UK?!5g86s3gOysx_LIJ$S+R4e!-QB>N!kUADe1aGR z&mabcWavQ;CD49a;|ZY@YBX5)ry*Em2^O2`%~??iWB_`B|8%jQ<8lmP#t5(>9DxD@ za1I7+0uVZLaE=3uK&23^Xk=;-7%KL%ViHAo4`3n|MV%JOB4@DzM+mbIqL71snRv2- zLVdu%%omMHB-sBDM56|vnjkn>#NEv2a75(MpAnj?Av}O3rjEP-(nl0MvDTWv3=%U; z|68;u3?>T~Okn(og)`y141@m)&aZ?3XwT23X-fk(Dx=WIV57|xniY*n`JoW^V>2a? z70d)sCj?A1ruhfL1c0A_GXFp$(BS`80RHOxT?BBR@Ady&qo5*hlnKx-5;&uQRzznL z7#M+>yGA3CK<`a}0?1I5_}T<%4A>z787{UL`5-aIU=$1iMnYlYdnhy#Y>Ywybs~U* z1f$^Sxmg6DT6Aw3MYO*gSoGMNpXfiAf(RyKieu?S2^2+A#G85igvG)|Y}q_w3pO7| zb7Rm0!->G2a=JtUg+T|yHo!0&kYL?l7AuU2H3GOdKucy2!h$J8<_0>0tT(qVaKMgp zEDD`wBVy)sZLn}C90o-}VK6un2{YNEH^04Ktlba%4MzZ037stNv$*%);kRGNTofaS zBn<__kkZhfA21q)0u~$zJg0+0p)erJq7Rt%T?YfY0R-qb9iaV92N=KrGVnJ$C!t%D*Ff3#tYf&S4KV+{Py`rttRf2+>~E}E_XY6BRX@$YTGp)iwqzAOd- zcn~ne;GHKWCP)-3(euKCP6zTWiuv3ZqXUfuq*Xj6=14mNgC&kGkTN7%T1(5;6)*iC DR10C^ literal 0 HcmV?d00001