diff --git a/core/modules/datetime/datetime.install b/core/modules/datetime/datetime.install new file mode 100644 index 0000000000..f58c3ad395 --- /dev/null +++ b/core/modules/datetime/datetime.install @@ -0,0 +1,146 @@ +get('entity_type.manager'); + /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */ + $entity_field_manager = \Drupal::getContainer()->get('entity_field.manager'); + /** @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository */ + $entity_last_installed_schema_repository = \Drupal::getContainer()->get('entity.last_installed_schema.repository'); + + $entity_type_manager->useCaches(FALSE); + $entity_field_manager->useCaches(FALSE); + + // Build up the list of entity/fields that need to be updated. At this point, + // we know what needs to be updated because there is a schema mismatch. + $change_list = []; + foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) { + if ($entity_type_manager->getStorage($entity_type_id) instanceof \Drupal\Core\Entity\Schema\DynamicallyFieldableEntityStorageSchemaInterface) { + $field_changes = []; + + $storage_definitions = $entity_field_manager->getFieldStorageDefinitions($entity_type_id); + $original_storage_definitions = $entity_last_installed_schema_repository->getLastInstalledFieldStorageDefinitions($entity_type_id); + + foreach (array_intersect_key($storage_definitions, $original_storage_definitions) as $field_name => $storage_definition) { + if ($storage_definition->getType() === 'datetime') { + if ($entity_type_manager->getStorage($entity_type_id)->requiresFieldStorageSchemaChanges($storage_definition, $original_storage_definitions[$field_name])) { + $field_changes[$field_name] = $storage_definition->getSetting('datetime_type'); + } + } + } + + if ($field_changes) { + $change_list[$entity_type_id] = [ + 'entity_type' => $entity_type->id(), + 'field_storage_definitions' => $field_changes, + 'base_table' => $entity_type->getBaseTable(), + 'revision_table' => $entity_type->getRevisionTable(), + ]; + } + } + } + + // Loop through the change list an update the schema in storage, the fields + // in SQL, and the field values. + + $field_spec = [ + 'description' => 'The date value.', + 'type' => 'varchar', + 'length' => 25, + ]; + + $keys_new = [ + 'value' => ['value'], + ]; + + $database_schema = \Drupal::database()->schema(); + $schema = \Drupal::keyValue('entity.storage_schema.sql')->getAll(); + + foreach ($change_list as $entity_type_id => $changes) { + foreach ($changes['field_storage_definitions'] as $field_name => $datetime_type) { + $value_field_name = $field_name . '_value'; + $key = "{$entity_type_id}.field_schema_data.{$field_name}"; + + $base_table = $changes['base_table'] . '__' . $field_name; + $database_schema->dropIndex($base_table, 'value'); + $database_schema->changeField($base_table, $value_field_name, $value_field_name, $field_spec, $keys_new); + + $schema[$key][$base_table]['fields'][$field_name . '_value']['length'] = 25; + + if ($datetime_type !== DateTimeItem::DATETIME_TYPE_DATE) { + $sandbox['table_column'][] = [$base_table, $value_field_name]; + } + + if ($changes['revision_table']) { + $revision_table = $changes['revision_table'] . '__' . $field_name; + $database_schema->dropIndex($revision_table, 'value'); + $database_schema->changeField($revision_table, $value_field_name, $value_field_name, $field_spec, $keys_new); + + $schema[$key][$revision_table]['fields'][$field_name . '_value']['length'] = 25; + + if ($datetime_type !== DateTimeItem::DATETIME_TYPE_DATE) { + $sandbox['table_column'][] = [$revision_table, $value_field_name]; + } + } + } + } + \Drupal::keyValue('entity.storage_schema.sql')->setMultiple($schema); + + // Loop though the field storage definitions and update the schema. + $definitions = \Drupal::keyValue('entity.definitions.installed')->getAll(); + $definitions_copy = $definitions; + foreach ($definitions as $item_name => $item_value) { + $suffix = '.field_storage_definitions'; + if (substr($item_name, -strlen($suffix)) == $suffix) { + foreach ($item_value as $field_name => $field_definition) { + if ($field_definition instanceof FieldStorageConfig && $field_definition->getType() === 'datetime') { + $reflection = new \ReflectionObject($field_definition); + $database_schema_property = $reflection->getProperty('schema'); + $database_schema_property->setAccessible(TRUE); + $database_schema = $field_definition->getSchema(); + $database_schema['columns']['value']['length'] = 25; + $database_schema_property->setValue($field_definition, $database_schema); + $database_schema_property->setAccessible(FALSE); + $definitions_copy[$item_name][$field_name] = $field_definition; + } + } + } + } + \Drupal::keyValue('entity.definitions.installed')->setMultiple($definitions_copy); + + $sandbox['max'] = count($sandbox['table_column']); + $sandbox['#finished'] = $sandbox['max'] === 0 ? 1 : 0; + } + else { + $n = $sandbox['progress'] - 1; + $table = $sandbox['table_column'][$n][0]; + $column = $sandbox['table_column'][$n][1]; + + \Drupal::database() + ->update($table) + ->expression($column, "CONCAT({$column}, :offset)", [ + ':offset' => '+00:00', + ]) + ->execute(); + + $sandbox['#finished'] = $sandbox['progress'] / $sandbox['max']; + } + + $sandbox['progress']++; +} diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module index 245d0c4e63..a925706176 100644 --- a/core/modules/datetime/datetime.module +++ b/core/modules/datetime/datetime.module @@ -27,7 +27,7 @@ * * @see https://www.drupal.org/node/2912980 */ -const DATETIME_DATETIME_STORAGE_FORMAT = 'Y-m-d\TH:i:s'; +const DATETIME_DATETIME_STORAGE_FORMAT = 'Y-m-d\TH:i:s+00:00'; /** * Defines the format that dates should be stored in. diff --git a/core/modules/datetime/src/DateTimeComputed.php b/core/modules/datetime/src/DateTimeComputed.php index 16f664be52..5ea36529e3 100644 --- a/core/modules/datetime/src/DateTimeComputed.php +++ b/core/modules/datetime/src/DateTimeComputed.php @@ -2,11 +2,11 @@ namespace Drupal\datetime; -use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedData; +use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem; use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface; /** @@ -48,6 +48,7 @@ public function getValue() { $datetime_type = $item->getFieldDefinition()->getSetting('datetime_type'); $storage_format = $datetime_type === DateTimeItem::DATETIME_TYPE_DATE ? DateTimeItemInterface::DATE_STORAGE_FORMAT : DateTimeItemInterface::DATETIME_STORAGE_FORMAT; + try { $date = DrupalDateTime::createFromFormat($storage_format, $value, DateTimeItemInterface::STORAGE_TIMEZONE); if ($date instanceof DrupalDateTime && !$date->hasErrors()) { diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php index a6680f6b4d..b4d1bd5eb0 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php @@ -227,7 +227,7 @@ protected function buildDate(DrupalDateTime $date) { */ protected function buildDateWithIsoAttribute(DrupalDateTime $date) { // Create the ISO date in Universal Time. - $iso_date = $date->format("Y-m-d\TH:i:s") . 'Z'; + $iso_date = $date->format("Y-m-d\TH:i:sP", ['timezone' => DateTimeItemInterface::STORAGE_TIMEZONE]); $this->setTimeZone($date); diff --git a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php index 3264069008..6528192d28 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php +++ b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php @@ -69,7 +69,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition) 'value' => [ 'description' => 'The date value.', 'type' => 'varchar', - 'length' => 20, + 'length' => 25, ], ], 'indexes' => [ diff --git a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItemInterface.php b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItemInterface.php index a9231c66a2..ae0343e84b 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItemInterface.php +++ b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItemInterface.php @@ -15,7 +15,7 @@ /** * Defines the format that date and time should be stored in. */ - const DATETIME_STORAGE_FORMAT = 'Y-m-d\TH:i:s'; + const DATETIME_STORAGE_FORMAT = 'Y-m-d\TH:i:s\+00:00'; /** * Defines the format that dates should be stored in. diff --git a/core/modules/datetime/tests/fixtures/update/2716891.php.gz b/core/modules/datetime/tests/fixtures/update/2716891.php.gz new file mode 100644 index 0000000000..681e4d4f5c --- /dev/null +++ b/core/modules/datetime/tests/fixtures/update/2716891.php.gz @@ -0,0 +1,548 @@ +BzZr긶7z +j֩vf~}6@H$B̯\-`[Zqؑ|pMfNWuf⛤ihhh?Qo?ݭ֡{hZ#6lF>T2?'Qp܌v73#Cwy3 BfLȅ>3"PNFHߩq,;Y\s䓏Ly\_?/ͱmcgW&GkI_CC\+րj9@=].L7D_/%|_Pp7&~=c;~ƞXVpܼY̷;367Wo.nNULҠz TdYԮL@O3Cdb!—Y&w|Vq4#mgAuMךmC.2Hm'< 5T+OQК5)ֿ]VL[Gst`=pObރB ol)7#WyP:Eu!Nlݺ*`+:2Ċڸu:N=]C " ~^/5 7f4q {E7cǻBM |l,~FDCrbLpiչԂݓf)b\B۳ fx-#)yh%X}^+Ȭ_dr3 +ک젡HwO^R08"b~!38jM 6d.[?&!>ΖeZNeiIwϯD_G>JknO/O6$yŗ'=)sB:!v͕0vPiǪg|_ਞ%h>2 7htiiOEZ8 hnH~cwU;EmV0e]x#aL@G(ŁldqtPw>/b/b_|hdET_DET_DkաaD_Q_QQQwM}M4ez3EA _DET_DETBT MM.RK_X_X*c_,R_,R*K =//U98ꋣ8ꋣ~UrnWK}K,ErhꋦhWC('RT,1Ӟb Ѓ(Nks8W"+3 A|DݕZ21վTqy?n|: y0`s] +JZV+E08_/`PJGqpӞ +K2DbT}_}YO{;j8p {uEcpT:žgvӜ}j"+# ۺq0|wd<9.לiMi<ӫ5M.T o\g46~r~9u~S=gx|;/!Z~  es#J؜;j3GMnˣӨKJh\ܣSnU0#816Hiښwn`VwP,#Ӆ Ϊo5pMjZ+xE\2_;nnk_mqpBDz]π>xmn&c9/!__+l*7 ,~-pxm%U'3$jѱCė~0?C }|ASE|o4y|u+l҃^~c|3sEcmʹ¼N{\؍۩sM{}rdߣ́ml$͒s?MR[VKYTReTAD‰yl DHTH#b +OҊi %IGM :Bko 3w|G[!> 3ySG/QG7=-Ǘؑ,*ApCtŷ?\^ut.~dn'ԑjȚt# K(@R*D$66O"+[w&Võ>/ # .¿i7XIj&B U2(I2V!kT5p.QHQV!&ROQjau =K]-4!΢\m_{){Ƙ҆BKz2?zجZ"(( q\>LQ&ٲqOnNqï@;QJFs'C5esP~m%P.?<7v6-pps$3дη6 +!nL4 sG,K!20$æB2%C'_uv `0(_oSq8GhXV敁2'nT;Hb;4~Usw^ޤbp纓сɒ(3TTF2hdծ1ՠ/%3CʻoM%x5WY>I }z ~@T(CY$tooz)_R98J,CP6D3HӚ*6n]4[zr|6_VXo%q]4&YG%C-Q&9ak%%KfCl$ P } Q QVyYC 1,ѐ7WLrTmY-߽z J3Ԡ=Fm)5&dvr։rwW2SLԠmRGܧrµ`qG^yQcD PPl̳Chxks 67Z\.za*>7AchQң`|*1p~ U&Ae-0Ai-t)2*mIiu1TH>Zo:+̭TkW鳥Xq;#vk76+]0p_b5wYG4\6G Q$TA^40P H4BF6IצS٪2͹ˏ;&iw|tߖJOqTؤQ;Agd8A. I (Nl"8bno `eo]u.u{ҾAc-b;;q8FAz)Mb,`1=io%˩/T0IW~ I*C-h^8UK9G@%0#sFǰtΠ:묢ۺ3rqVT(0|yهgS>5*^qQ36iYj@Ԋ)Q$7.+ιݤ.oIUElˢ +4'tQC6Y*BQO6sHiio&Lɛuo%k@Jǫw+wsY6ٷ}|cY!]c, h(ɬAiHf w-Hwl%ԱZ)mr0:k;7GŷYmݬI``\GC]guQENeB +iM2kb5\mY[ŷJH<5Gݦc+uZ-)IT0N,uZ|(SU^ceu +p44ڠ3,Oc<0޺˝MeOrTra0%V' IqB) +p|çP؊xƨK@j0b< T1)c,;+\"WIy" ( ͈T 4֫;{{v6LHlp7Lo-D?!B1!R˄RB75r +g3 sühEY܎TY -GJ@ԤCO뷛ړ7]Mh>1vǽ7w}~bRg@36w.qm)D,j ~."GRMH(14sh`ӻHaW{R?[wci]S2 +x%aU2DCBH|~i]T룁4y՗'F܃=wq*FF՞®.jGp]{,yG|F/ {:I'YDJ ix2{x85=zTP1z,7ΟY|34@JtR[C2TF?U h9iiJch؄dYFW9@lӕk/7U*36N;/z\q͖2{Ќy/SŰ{r?m"=S\cJ5D9]PP1oPY`JRgTS W_a5I1;EƔ1Ablu캓`ifH26 !BeUxH 1LJY -~V*۹\of,u+-3X# Di W݅KU FרQۮY:-o.1c@#lD% +*s:5eb,Ik=9#ϴV={fq)ܾNkvRTFkrv5 TeбGٖ&>汧MпA%O {MsAcf`aA+*3)dF_lr1@3rJ|#\C=NJEЍLWWF%?'">BLpҚDD.lOjaQ J! ԙ-a3u(ٹ,;#=9aZdi<ȲHÆ1R}A-:bulmk1G8|6>Yq@y}xnmBmt>XX[FN|<%;$s;ua%<[:I'dL*٤B£QO[JI﹎F |jYXGMȁ]XfcYn"B)YGћ2` +)B_)kF\GJ~5^lbAnD/C@u)M{A=uNS:cC>ݠBLvN`?ـ s1eߡ7fH=N<^TZu>`" <'rP\ӕ4U4:hǚp"Fc[a@d^ŗnXl\QtUi\sSq~TauUkgR?{m=>WYvmXQ=ÖNjHS5_ْuU.VUrcdN-ekY6w}ۗVPHZL/So` +~"ɗ-x%[lY +g R$ +8$@tɜи\"![V6aL͟Kkttc)nnRo`Ua<(q-dP{sިKۛİص>zP3Smj @ψ4<~ǂ~? {KM"ޫqͱw|`/FkZ:ȹ8춺lo{L<y!I^Au#&2-BYY5Tx[{%^{ mm;cqӝ>_Z/샇fu6RXX\X}N:b$26.ҳL/D d:#u/]%dE_!NqFM+C/wo^K/mQV%_/&ěQlNL'صuyqM ב4(JJC2BiUJ/#mDfɸICZwE{ۏifwTlp/ 6m~q2*/)q-IJi'S&Or}vH7;u\[W}4\B5 ۹#WXSM" j^u Xiݺwe޲{V5bc9WݹONmI⩡e5zȫO޴n)A%Wו{ǔe*q*kb3GFb!%r +l%})($Eoۂ,.6Z" <GMd 1dZ ]/xlċq~JǜŖF1yƓvp%"S"+Mv )y"` )2_:oerW Lk;? ͏9DK2ɞru^3l9{]gdffkEZ}[[-w .';sn +keܞpVw{P74|ݝ{1||=WQU@ Y tY1A3X]4  Kdcf!Du?=Dh^w >{Jr;3rJd㫷/Dp) &.K ;xyzHU'*"fPB0H8ߵMF2*4(ȩ@ 8M#l.2'<#@CPW}[}Ü\0ar3/#m``Ej7Yˤxۿ:_x h;cbNْ I=/NW"CʌH13{;3yM ;-#ݪLOBM3IP`}QbT{?m+mF*E[&Z1|T`>kmA5!lJ%eU!+BkvIxU-)VoFѳu8 x"ưaÖ>L"F vq0m:iY!EQA j$ 4 }]Nb _m0LĔEswmʿyrӱK<`z` OTUAdR"AUiݩSwr2Oyž5~cjP-nsܗU,z>NOzZlAJR$ @ +DxN7xM>Kq7UJo0=ߪFK7ג`Muv5mKSzp?KuIQZ?:M ed1<9$^R.В$]w=R̳YzԆ7J͵kn沋ϡĶx-bm"89*4@l_~lYD +Vߔql[,$H55uҲN[͈Ҳ,"&f|)p[O?}&5JgzE=z!t&w'%'8VKmq*b~<1~lH4%U&k]a/ٷ0jZZ;¤|g&9lPŲz^BPt,;"$eC).[`SQ CaKl^t0 +EJba.Eaƨ7%O{\VuZZz+]ajʕTdX->&y~'h%8D'y\j-0m3j2i>RF"Vq&8r!gȟt\"eNiz[6) Ьؖ4(zv,ܵlxC̔YrO8EXX\]o[&/qZ5_7Tt[?aGI rDځzItij@h pH: O9Te56 !NtZ`n!eF ӻ2W=a•O己nYkRktj}D5Fʥ&yylLB.ĿAFF,}QNهa\@>J.q5j[RRO|owS9l:1P'O&NȢp|Q!G,kV6C |K K +qWpIuSQuD}l#?'Z7ƐTvm%EG}%7`5ГV߅gI0X.(f㖢A ``x}~Fy$^ = ,hzR(Ծ޽83dFdL4$ؖAvЙ,?eD˳C"ǁ AZ(Z)Nee5 +=ׁJe4JjwoXm5⬈xq]*7ҫmpZSR," {9_ne"UX\,& Y|2Te6ndw3]G]?=Wv8g\9dCFMNI: +X Y]@*V~m- o:t5fh%עa@K皷  -*G:@=q[z$сAfh42d $@Bkv6[׾JKBzq.=`V-ߧxR'6;8fPTh.8ƴݍZʤ#eA8^̊vK弍SY4`< ߾}T-C#PezwΠ9$E?2!9eC3475'ǵ=-o)z4/$TW*ϻKw^!J(ﵔgq_- xLsy%#JxHbi>u:%l'o(s,Hj4`(2`9aUdP"tT4q9Mg$UMB[{Gmr>qђ aGULѹ!pXO?(BȆ*"d@VI +Ph+#}t"]Q2kNSS~).u\yExe,Rs, ePS~A,%5Xr2㕡>>] +?P2DGС8`e{I43!]xY7 c1}Uz7j8{zk϶5wI9+xUJw-$n=XB|\ކNeۙ+j('5Q5#6"rX(C*/dT\5{ ?WH/= Zzժ4\OmZSύM:@VoW#"tQMbX82#Z.pɳSFEܶmU0v(hăw% +K##˒԰=NJĔyh(S)%cD@GDP@(MdY&&;Z( KhZ[^kQEK͹+7FE.5^}WۊLw-Ӥ9^x\1mWLj ['۽{ٮ\98"ejf({ǭR%W-6(Wq4#EQɮ_[fAy%șC8@+Chk< G}KڶW۲n=pIw½?y([-ԔebyFVupLV^lתhVo 6GR'VQylb|b)t|-z-n6wŹԗA*q)3[1 ,gI 3=(ҡO4?9^I||Z>c{;} ʾ!\xsf%:ձU4ŝbNhU-@(\`TZ`$֗E"׈xd1)q[\[݉/Q͐/!L #j, q tp֖Cs4flhT=[ݝY +Y+[tB 3d4cT]7(@aHM1Z jЀ i{Al"-t5PbjMeEV`tP E& )F*FˠO7@z}ygXby˻׸Ag9?Y"尉72j5⛙r1$+#'r2P+@TAdEwAw/9ڂ\x颐g{o8S*CV:L+}+y(G.Ƹp_Pg>iLG[ͻPL#TUg~FS͟9OY|Hl$/RJkAr,=M^zhg~˪x*xo~_L3Do?Kj]IXL6~FʷS!0nM(*O xDct N%[T +<uyՒIOnHxKΙʨM*+u|өpѺ!xޗv1g{k$ kAOs Un_ĵ8q\g0n~^~>$0՟} [:hC4+e$9_ cpHH?1:vwllPI0I\9k8%}TO6]'~/X!*$Q 11rL/z i25% Ī -D|}_1)kT[s}]PN#b9 $4}j +L y.fU +͝9G}y>$ek,G@U)p:#$Xa_7e϶ŵ7}/xk(Дl>lQkIsgm<$e}Q OECvE呅U,sh.%2\NR%؉ L[~- P ` rshp2Tf/+;>PBQPa!zLP/.?@=, n4@P>L< trh9-7}?%eʝG=cқ‚t#@uY3)$kۻgA_([3_$uX1A|*UJ n©'He^U$8L%٬(I@YqwM*unPOCư®Zӊ9'm\^g)qٔ!9C& YH~z\RJX=Y2)ijd=y:*So'ЀL;q&|Gs{ Gdx`YGDJx@^u^D3X @Ȩ@fu^5s .cOG[6|<JV1Up'B@&= +j4f8͏2~$ί0<#H|h*#4PJN30ͱY8%;C5DasHg16h IE1p B,b[r^qԛVʠ:VE]nh f<46 Ʀkٌ9%2Wڏ͒>*%D U*s32 [|Cղ[ZՅp? z!Ceܧ{[d{MS\D w `q( 5@i83cYI588 +2]}Qk0}Z*";UmD/pNN2p*ex_cb`U2xj C,y04u9*T\NLr}0׸+.^G8okp6PuasTᓽ!M@`} HF3tRdQ@ENEK@ 3K4%0]U깐k{Nw܈sZLZ M]dH14Ef[=O,;ſgboSA0:tҀ "2/. &'ORN}]|zY*v:%)+ + GLd7]؏58XS/r Uh@27h\{t@(" ަ߼8CתHwJq\:mX)2㹈^% +Ҕ2`ˍmLj݁:wj]T7*,}-ivKoRDKDDC'/ǎ%~BN?4$UY@d,AH,ixQYW'[l$/d޺SguM-/joڷ9ʙqqH=96ױbP~6itRb2%2ML<.apn(d%Ҏ쏿^ED,{.&Hb䬮gdf'I{!6Va PUډ0%Ïon4B(£w*/q@fg +O] + !+@Cx11b0W*fq><,kɽ|Y^kIW;G: ={Ѡ!+`GpyXݓ*ۣnV {m͌r_>=x֍%ď$rs,X'&fHA68MZd$*ީr]XJ(ύM2q}h4[ ,3{ȺCA}辢v:վַAy4G87]WtH%Y-ż6qOe55G͔t%2xj,xtSgf}Xٿ͉ʔ_mݗd)x.ISgBl9Edo do{ ]}dYɴXod9մwN݂-eZtKX.eU}Z ̎rJ2;Y\?c,nʎߖQñS?~<`WJ?1сN <4ߣl\xk}U@{9'(|\8/]wwk`տ"}n=1˭=gBMiݤ02ZJ2,5y]<><Ҽ{ܯ=O\w.Ѭh*DLh()6a,)yW1(hso &s:j05()e׀1АH ;O5I݅U|,Ne^ޚ =T۽ss(KBȦy3]UoQ2H"Lk`k$>=–fϙXzFE5;h3$*>}~,;|4ܢ(n9UzVC~qҖrNո."KdOGf/iPG,8KžZ$_^~D^6Wn<-n ; kӊ +V* |+Ȱ\M .Z^tn +8gO9ů_{xx+bp`Qz>YNW Kߚ8m#gI@rm6 3m&mG{ӏׯ˟_[ae]olp_YrT! f{eB{ J=d/z&VnUwJJEDPE@p5I#%yiap:$0/ } $|wMHPcl,I$G +@p/|t| )LOɟYg6<39t8?A>~0&Jx Ý <8|Z uF&䯇}Z9={͓!H; z2=EIG0RzIxHv;cû{$V{cx>?F8S8)8NB !(qzdW2"6ZpylK;^z~ yq-,Ke^c8ˍ8}CTB(SIN1֥ļ~}|a>dgG֞ x؃aaݮml@bG"fJe&Ǿ`Sc"|lXC~' i!d¡#)c\7|1a,d6HKvH`+zFn/ZHW{OϏSg0=uPc Pt>C1UFgϟދz,OG?gXhwh>kdHKOervctg4Hf; 9$ku&J)W™ $42˝@E>vMɜf<>:%Q%4M1vpv\cL+v?oN|9X{a2Hf'z~zn b•&L=|"j1j/g?ų -._{?yXo߂_ٓ`ˇ~h _(~m3+s7|H }#JfdFIr}WtuK?>L_>ƫWr +=fW V ߢW#خu4,=^{Kw92hH!GO &34Nb$E:'*< +5V7U8v:e2mzt xh~}&08y}:f>Yv2{% _ ,#pm qddE^W~{CrJ1Ύg9Iu +ao2эGtd!UFBm1g`!nWc[dvq6Y)^t/0#D|0ekcߣ3rի-& ! )kmC +Gz|g/bRŧ{23R\N:E-`C=Ҹpgw{Vfxv{)~H+M֊g2!n>$DO ढ़.IZ6[s6Ύ !(LslsBll,بN0k@BD ԥx"!$ۿf\<7$=hbcl+ROO8${`b8 'c4{aKgN=4sl$.SNbq7!_˵p=Iq a6/7mkp Uą&v?jaOEO+lddD=![(2^ *_l,!Imxq/gAh-ùNo&6"a59qmNC)Lj#9(! ɦai}Pc+3VpWBlÃ?fqB? M$DnJ q5<@/8)RCMdm? +5'/JTb<+y7l9 yQeBKv4< zN:&]3Z{yeK7.9<D[!I yGPvߺx}7x_ $2`6cg$n.{x_HFM\r3+]7O:a`jpu rr_l-u +˘ +&48/vU[N;8q6H`c'y >yu^12EsMh*dCB W01p{[p• ^2}N^eRWVy|=FM$G'N=F+bVլ^6yr My{A}k,TߔF* 7hC")_f)ņc(e!AN}"^ZeB,Qp~^(؇I[6O=Q\'uo5\0b|yj&J])eUT~23NN_=w^hȾ~g{ŋcٵL_$-N&d6*`Z{ H #J-~τ.1/Qs+|c2gk>_N؟^O3vyȞbYHTg)rf.w&aI#u{#"eIK*hGHOδ@G}# `X!75 Y`LDF䄵#AWRHptLM}_<$6zcH#ۓz5 )!g/|:@[ H!f@qzgMt&f..S7`TplV2^|auK3_,jOYCS)7 ptA>C 2vJtK]'U2Hx rEG8H`3-8k+vwGr O{>/(dXmE4?\f5KH] Z +\hl,Vg}@ Q +뉇KIJÄ^XT4d**9"d>SDZ(Ji,;ul]Ea2JK><ē\6zw/"Ɠ> Xh-MK'"n9ј9WclH`عkDr*!.B\IagH9Lo=޷>&p[P\L (|Ġ&w)NR|B߯}Btsl )lAteX+]O`]~醪/Y%*+Sd̤wJW=A;8m:}n?š,$ƛ%l5rI߻qWA}`Ljkd +Bl+JW?za-zXU;ȼ`y+:K˛dm +R}۟:/wϝiy4}1}:8sՍ}zQD #^fV;n*9r?}۫7㏧<=go7o_m)4HJ#%?NmfYy'FYF #,x2Mm#6Ѻm{;1)Y +8󠛦#}}j?}˞:=HLg/G}?9Φ/Nd\ΛOCepf+٫-p,_4O4#S9nI)a`Xtvs(H@ E-F0P8F[lGOSCW tXʆ܍}ۊ}#k0@<"ЃvFMe/̗{__?,_||<}So~}ߟ: EhvDf&ZD3U8ryQ lI>j)G`d027wsctc5Qm*b8p-I`@}S`+C@v>TŝK}C|K Tp`?1-"f#XR)+!eI\<"Ɍ +6GV&͠a.h{W~{5pω??vߎ?ǻɳ%%^;-a?O1,b*4k,ےAz-E6\JFr񰾊4*d*1)pC 6 ˅&3o#Kzi^E}bF13pS\_t.N*F /֧ S|p3Dg8ԥ*co?92^>7Oޱ%FO`p~{|_O?͗*|v?0z,8a_/ʣ{:{JBxO?JӞ>~[<П{/Oכw)>+ FSް'1!BġEɏ_?5/٧߇C>~:xZf]i(Cz͂Üpw8}10bPxW !Ybz$'Ez5B!oI%YpG.M+e ɞ(1uq|@秔k,,ubN@%*ɧbЃq:PGSZ}|J J=N _KSL} ,p"x7x8R\$%RM:)?qo_D~#G=|i^0m:Ų̎[~h(_(4A׎J /M$IDl O`Vu#. 5Bl3`V{RHYf 2q@㌝GI)(8<6 7)SX=&=k_fKI3rHx%1̋dfMM.pKub>,TtHgq KţzKEV[d"taJv.i*- +m{O`Z=HI*قNRx$:jЋ& *L' Q)Q4'Ey{CN7 +}} #-q2tl6]+j-[!JY0J kSŹOca"tf&Oh_5??Fʹ\\&jyeW\P6MY$P^D3:M)@l ͌mςlrQM/YKb *?`lMu"0R3ǥ"&hur'U⚔_ K/4Ne8` +&kt32hHhVE}(xpυbr}6&k% $*.d/-PB`[^؍( +gϞ[xn ֔r)eWb% %%I%;,e;fr~z gu^砄*#VeY&e|0 N?ߡϥ ]fǏ5y$`:+5?U#nez$BbEHS;USn*~3%CT g>v$tG ;i5U1;BgY)+uAe?pnʛΞΞq\ɌF8:TF8rx%(C<&(1|Ujݜ&IXkA;+栟 Z2.[6Ae=P:q\ ¬$_})8K?lUm%fo^:mj]6'FEJztG1݀V V&$ W2i %6t-!P xQA16#2Bb8|۠ ,ThItAOz^X${[3+ |82h^ +IL#N}s.m.X\/[_FM=poxjz + h{"!4Y-kBEcmȒֹ,uxd$ڛהI,%pe\?%[ uSl̠ffl&}r~W1 W, L\$0C֚b +i~ŋ 7 7H`JCjE&T!XLO)&&𥹽=Ift$t6`xAc +tIܤo(!}Q9/d奴Nr@ME|$\̽$6V1W +/5 .(~Y ls\qg*U=8Ԡ|Xx8ȏg4zj]eERydS2dhjDSH"s};mso'oPa'T劮;G1>F^YS1V?gwoJå;\&Z{ti+/PP Њ-.>c[v +Lw|g)0Fmߘ& v(tu7(wL9UTG-/7H/B#;b#f3GLtNxqJ1P޴t7ӝ?~l:=inh$:PCW;c; $3x@ &*pOY~d~uo^3;Wvܾept5^.BB=YUÖ?"r5X*7f` *?`!B#Ui\g~-){ tM~[lx:HH +-y@nJdHoHd~h-{IUmju1A7/ixKaPmJ\=ЁnQjPEe_3bHeB$H񓃽{PV,/`6_b~O*Rū`y+Zlדneޫ!’saD0k}0<nq{;3r༰?;ܬ;V4jǓ>$&\<ƙy%U_*u;/}.wלk' +_QVYzFB"-scQ >XzDWfw]#6ƨ2Hak! :%}$ob~ß@/W+9&ٜN *rlhd'Kx' Y!.]9"'3I0{`:MN91lo¤pZd:Y=;8ŘOUv+u[øΚcP;|{m PX8DwMwԢiO}BS` K.:9$h |9;~9;a wDjXA=,A4T؅9_f]ޥ]L%sdn -wHn~;LUܻp.oG !w +Lw|gL!oZh8??HCe\P1Ɛ4j#A|f{k_h^)^+pch2z9E#뿲^Z:+SI`],~,tbs#hk9 `lFA ?V$x؜\k5?F&xt1>?kKзى=5 _^+{){G%AUn?@?c=ƪ* S離aŮMN҃w#uHE5|k>-t0X/`",a9e͚uH}Е^L9i!&+\*sA1y)4[>,\;au|g <LJ?zokx1+ z5?@4S3@o{h&g,0X+_g20Ar"T@EA%FTVl40"dAg3ƥiL bE;.\lm3A~#t C:LZ&0㤀2fn5Afp$ο(pU"2I)x b8ʼnLdd J]!.7Et6`+AKw['UKrNNn5[UޞRU ?'l39nGp5x%?,%˫VPzS^\QjIyͺ*.`lWKNHQʫ^_duF*Yt-[Ȳ IOwq]ķYn6#Y[ajZ05י*+cMWݐw4Ն`UkJ,hQX*9Fլ"@'?-8 +Gm| ߗ_+G5XS+IyA<ҍlcc +:NtNY;-4L%p'$9ƹo`sƦ*]Uiϓ\HTd% no֮*4ڲױˆZefCm:X"O3k+G _)o3JB;L3=4U2ם` +&BDĮCx &+ +'$@Қ$8NV 1v2gDgmvŲ+$'Wʤzv`ziւo9EE_y쎾r*0ǁOQaY Ok~<9' JK\P: 2YD=x1&ٓ|0<H}aZW*F<֧9Mb~W*\]68^8^TR2D|Ϸ"1HWy攚A}UO8\ؘ_\; :9}Bt6C1 7|#h@߱a,t<}+s/gO^#=UfH_'{>Xc?a-:]WHɿJR[[ֵ9~:u]5E~\ZیmzBj%[ZWP NjϿ R;"!H/ʿAԃ{Stx5q'}CqKlooQ9j)Z҅(i40mek#j0UB6c:7.qcSrjrFnp0" Û[0\SYfj5]++2PIX6(7Q6 W"\-cw?wt>Pڼ:0CrϞUk3G֦cK*[.{]&%j!ȅ$F`4R+ucRRb"9xujw[R2*Eڄ(5߲ `X&'7 +>G#^'~ gBi)nq+P 3\.\lyKqK^8z@ϿZOa2 03;22310zja~9L#3ww-aww5=yv޾; B0r#ه3ovkz] 1 +XdTcW4i3}TzJdY0vXح"̀L~{mph8`NQjppb_ +|2CRTWTTBӗ{=tC1S(Rwg{6#)ֿ~?%QC{ϸ'w,W$)z=twR^ i@@9^BzPWѠgNԹfYW>E>1論Vdeo/P෯@##۔oadqo!>[ϻY2[}Uw2{yI&<ʷ(+|l~^ 1_rpvn슐zoa} Weh%U(}5(»0[fX0ûȰn(0bKJ=*$6^UlOw^p[  4QzUF 7 {J6H?^5& 7z^ W#6:qA%b66U t :V(1uV2k./GGMNf̱\ceժEsMἲ|+3v:GC;qI|B_8Ȗ-Vj"hmMvU fU Rqێvܶ㶷 +uH'GNS""A + h։JGJ9S8gDHZ wIP]ƃ&/]ꯪ@@ 嶡s!Go[%ɭ3a{}Bm]cF/TFU5EJG1fx5\#eMufhXhYoqjAFvyd+rZt6: I G b;`8֧̺x| :+vh]y*ޓ΢ڳ܉$^Tf&7?=& X-Z<(r+@P.PW]4]I4V +.r:jˋHC81==)3=jQǽ~ɽ1үqx><8;;Ig)LfGIp< ?M|CL4?}@wz??aB[ )vZ\L^FؒM w&7TuQaXq*2$eټUU͘*SRRBe4]@2l6^E/p('8L&#Û!>U7四!ٝN,|+L,3׵&t4$ u蓍hCA_WOT _* _|3}bۥlg*;Oj^]ךRjI|ՓS4 T}vٚSOSNJF Bǭd&.TXybaOjtAF r]%Bl{s!ÍJڗ._ڍ@߾^j@rϞt06-M6+̾.M+\;/x9DUυ.w9j Aڦ- +eg!*Y^3݇Yo8<2%Ϗ/ "#N@Ă# DGTBsaϿ 3x6H9)b؋ !E[rzO֫7;!NPDGl +-ύ=}m-\*C wbO# nDҡ[<@!r]7+ Υ $uC0^ %e3? .%"x ^,Cǁ/^*k]uO|E5m|QaڮKF=x9-sQoC/ lyF8R8a֭dgmPs*/4Q`o.l#~EO<9qpA5L)r mOF^M[2j3NL jwv>zΪ{q'kI*s*+ZI8}ٛMtQKûޅ|w!&] SYa¡C@UK@-ĸ׫V%J_aZa|+kK|vXb +|HE*]FT0UD«(>LEοA;fVXkKTdltvbsl rƅw{e{F( MOD*js^Cv#svΙ9s9|iUWNnpTO5+mn^i@kwk}RU͒}ɒ,xQ2kj\ֵae5F2#ee:E]D D_LK; $O_&Z?8W?$ u7ymRP[ +֎v5hk/"hm@hox<fnh&W 5q +nUa-޶pg]R,$Q,e\y=S8AdˈIJа1\ӊXg[TtU#x|_g_{5=z1;_ǧ/{~r Θu)nmE~xz&.\8N{?-أ- b+w6+Vpfh%*mr'oϧ"kL~dVV%+tJߔ'%;y,} ~CK*xWv g š +WI5ji'XSC@ꮺڔUv+Gᒞ/4P~`"$#~c&Ӓ}W.$ڡΊ'ko[=qE: UvWY}]*nϒv7, mm* })j+iւW56p^%I){&+U3m`GMͫCUժCͨV)='ir\^@X:&v'Fj!*vUւm#4Lquc|_ 3 5RJ[}<-λ̹= R0?N:"CP!Q},%H>bOEa;Hu?+XLB̅]I6Kt~y?bb5$2L+jLtmo 2}p4+bu8\Ē‡0|#R8zHr+%_A/_ޒvcX/)cqRh +ƯOvÆb + +܁\+Wڒ/5w|a/*j~P<-2 FՍ>b(.WpW%Y[ڷxgkXc(eQYvMDrWDӜr7ډW f42A r8>M +>CH4cDMԢXIՄ[kҵy`:WI_BY,.bVY*c~[>jQiy͖]wWCnnsSm#J6T^IO.e^΅> VCQ,Vbpv(>UUax~]l}EG h! DڨLf>*vtg`ٞ ,8onzF$IQ8Ͷ2a'G|ATq%mo GoG_'}0G{o/8'|k>em4:>o&n}n %Ný}Dn=49mAVT< a}+phXvT\7S,-ue9: U`_ATo@yAq]?o./{G"՜ZuT `AHc+*/KG)"!Haƒ=9jChZæ|tq糫"=7A,-f] 꼅5d!P-G\/X!m] m.۪02 +a2AxcVg,%EPRs\_ ޥ׺USlĨ[Ichir$&QT2D%UO+vQc?2.gcHeH^E_Cb$0҈dL[A?ZXTǢ:uWXHq^3զk+E16-`< }}ݡ;uWw_-TRHbdNkPbm8Pēvٜ"+QWװ +!iY2d1-e oe|L@cUf5 +D˭@]'NVAir)d"d.^*2hf.Axv@09P4 id_%ϒI +*B{A;T{*u/6C݂UìR)fDCKRF :wCH/i.YEG> KHBdY5AOy {%!Y9$;G\ύ}zFjgF604F-+\쐮arH ҝzVC nP[9dP%ΦƙC2[0< +囈Lu0+nNav?>/vw_n!CZ9CG)^tP4 +~ N7^3tOK1OR F^ӈOnV(nA +KPTyH)SwS7wlK=[)b)} +g^gcOhrMɁ$<.Hym˺Z8r/wzB5Z$+Lˊ JHC+_g意laGk3(~&,O\PnEi_}>]OK3L=P4K$T{hՇMW/LTٓ%\tn En$.9+ gn`$Y&Nu #tyt<g~b /xqx~⸇tYEGKJ^oW6'G9/mʣ n3E^)KEpxETgvfgb>`fgP:tvwlqyڦj}6c+gs&3HF \ACB"R-{z C+Nc$/z&;b3WǢM+Ĵ!S--<^1^fһlWYj+m0oMn~킖6h*^Ū#^"͢E' 6,▜:HN"A5}@,f3jQ'5eSzҸ.۹Kx}JaȚGWol}),QyG8^Iej"hs{U]V_j.,e,9m4\b ,|^`PprtI +xL?˿oԧ1[?h#?Q/{6ti E_qU\$Sua xȝdC'}ÓN}V:.Y h S坿~>Yr f6; +۠/[vmMe#DDTݗkcLsɘ[DyxgkT;ՆFvj\UFGI|%ַzR;Pm2RI-:FMD%.;ZX>, ~P;gc&cfUz1@g9\]Y +42뺍(`~ӊ_?]KFKTjt}xs8+g(vI*Gg?〼M.4asggo0cShn#vؤPSeU8qDm gmĶEP(aNin\}v?Ho 9F*dvц\]iHY[Q;f)OW27~ǺJ8#l^) ETDr*_ˋYA[pEMM7Zl %bsÚC"n e?$^m:H ",8;kFt4^6m/ zݡ~(\pߦG[kŎ$Il A>Br[uስC"{I/=agi@3@xkci b׆Ёa8P=/E<@cJ 6##ψalKOR\; 4x @4E 5Ms5⋱aQ`hHb'0,?c +c7Yڭ1)$^y6nJ'pR70J  ,F0}qT՝BFo{GA +4 +@\!#Fe)pSfd38J, MS2'1c"i%~8np6 +hNƈ\"N[%)dv(LJtklBʒp6bM Kle @G6)I0Lr#.m# +ka& 6mr41'B{KbN0 P̴i?!Vqc,7M$!TNȶb6buqa0NpZ K+1B7r3#<'LBbK3'<׀СĶ, f7b͑dQ KQhG+ 'n "qrc{7K +|M$qqE7W֮2lB=udwHlUh$iIA2ʎ KnXp`6OK^飿M΃I_'9>#x4pʑmOHyaaI]3HSq 8;>U)وgl1fQTX xAg# l.0ϑup'aa"c F"F^xL0PbgUfAl}B*Э{Sh"5O h6}HP +֙0V5WɃn#߀qtش6m6FN# 豅 vG +-xF]""l DY`vXV%A-; L۰\Ԉ0r235K6&n\!"I|!E;rԇ 8Kv>^dٙ[ɪ1B ZF;0INldߋ=M$Hy@8Vhgeƍe&Faĉid@ha=3+wFjumx!#4( ;E:\`Fsƍ$>8L# #tP9qb&4A!fmk#zI]Q`53fa{]-˄^ MC[5깡%feR&H;"tea"m#6adXa 4j-7$5M7ѴC+2tBۉ7rDM)&2nEF LhYj%Ai\i} D'Eö! LY+Zd-\H Ѷu<{8eǍF) ]`,$@ FaXޏӧQ !='3Fe^l[,gi` c+0`1 'H̐HJ&{mDO`FBT'HLSy/5Ahlt q'~.iJgjd3͵c2=x2tzdaۯ5sMBHK8c!H SVcL!.vpS;%kS46;Eݐ0$&BnN]g?RLdH߬q4D4CGZ Ԋ"]c/kd7A 9JrR $"&0"?BC@i>O,{ߧFM\&&z|@d#盙[iq!`26BCZʲlNٙi"  uI."2䧾iف,y!d`8\-:R!s @bHy4Zz +AEBTdA׈R/FRc# +l$n,06:'fxoxC:%4͒bP͒I ;p" ؔYQdFI8{#H"F1 ?a8(Cá̇Űml-'ާnEo}ࣿvYƖŎi5F`mL6zncDđHq7$@6[jg[ Mlۊc1:Ybt]lHvgn0kv~#Ma{ji{Q=lZumcD_=; $qTA: Nl$aEiyʎT}v]OQVde8D vIM4Kl1 i`]L7|xm8iDn`{94HXV6Gf $fe!Q;B{2ͱn02o`|a](.Ng$!]7?Pidl#Ҧ-lGgNws!Mc,#nbd qBF+2@~ +f)[62l"IhRv%8RV ǁH\('A&O kcx53I" F2vwFcLQP11LH$r[0D@>ȂFiHj7y,YdZQB3NЭad(d#s +#Y81H@CjYp~8Fk,g1}+ w\:8ziHӳ-#r`$ apiE6/,\8Fu1s. ^ S$E8njc$󢨙,q|l|->ЊEtFG=ÇHKLriV1dCb7cǵ $fQj0RϯY#%&=:KH y8Npmf?Տ&<`&Z UIhDNTnNmr4XXl7( Bltc)RDMQDtͺd<];:{:D{-_i(5.T`s]h:>B14@`[F +";0mfFWP Յh=<QItRk#:،$Fzq"ŬDpkgy.O g- r2j CAJe&E۶B\ +=$5SYE^ǠhF[!tp w}@iI4ymCM"$˼0t0DH3!$,l6g@t6x^le0.,2=ÂYmqDQ Kq&q؀T*u fzD-a9c& kB$4KB3͒44,@vVq 躑!%aaF^QfD0E|1bA 45.-d2ng0 ='>NpOh =4X!:gLdʃQ:jmfXb8qZ&W8ħ#n Z"hp6+R~bE| vYL'6]3hnZƧ+8Q6aii)|sI +G04jSgAF@uS:ǵ4aVvX3m#?Q_{TR%{ZӶ`$* ءzH`^i@d"ד޼K0x7۟-fAwf̀̆Mv.# Rh΂^w }f}PCڠY6 +tNإgd9 =Kb +8>yS C=ӿŔK$/"\]{So̳ 3 +wFV;$:]qn@$Jw%$9Gç&b.Uv±#Xzt퇕p47! Jk, Pן۽˼T@?Ƴb+x6[M Kp,͝(pf3/;[ Ϊ68,"Qch4 @mӷ.Rz q+mq?- fȢg9ӑXE1[\]&/̟A4ۂ2G4;5 2 UEi,TGޟwgtް  π˶3~9i98YC.3p>Gcmo05TX7zQ] p{ 0E¤W|p24q>jxAA' C7Cw2XځJ4SȽbR<S]GtiAzU7knsѳ|F1xAVZ¬y3-uEެ&3H43#Ԇtugo/F,RdDd":`g<Iá᨟bG 3 {j泑OZx Gd%kDHU?l޳mۛjN4]dw><@A_o_VC%ϼ=dY/gw A߱,Gzw7tm,YET230H{޵Dc,ݙ=AoFN!Q˵ZnYA8[)ě ̈jX<,ڐWFӛ=*:3rA@*k1`12oqbM~/6zGual2ߝ5.xQa3&S;<"O} w@#rt8sٻ14z^z# dA>sf-&)m՛λXHy낈 Yْ@;U9j0,"I-2Y7` |Q? z ߃\1iOzߟf?8CZ\o֟Z`h&ܩ?׷3"e޿rED>3 +<"wmǢqͧݩo3m4;.x$ž&`FOmµru-hs{AnrgCB( OxM+Wogzݾ Q,xÁFF=/vtG%o3 [MThBR +kqJy)?LjEyt|#(F, ׯvgZ,[F qĻx6{1CM5 d<~ݘ-UfĐLtİȾ`\?N_ޢؖ%^ +&dleo'g_ʆ'kyj=zOޚǻŪnPP嗻__Ch!=movhMd#o_Hz.$?-7 9İp{2`#?|2"<ْ'4XdHr:X#RvyYf#zBՇcD W#䛫`wy{w~#{~N3 Yx (b!B}cɻl]1h#Ҧ=г!ZLI`&> N%z &^kd%wX=|[sSCS(U.Asw0 +bP ]l'd.;zs{ + Ss 8Ljm7 m|; ~\{6G|cǿ~b5&JfPh_9ab9RRz|~#wsߡG?PǖO?{ݯMoD> K 4%?x؅eÆ~!6#4cd/_-0ŠT*K}; :0|3*q'tӋ&!Z%"YًkYΎ :n0`rC Ͱ)F8MB?oΊCvVJ7ZEMaz()۫6MXQ"Ĕxc$RؐI ƛ0xyvM#KHi'.M0O0: 2 6 +~~OR$"vuMuY;!ŷPRI]\S +16c +ߩg\1n)#xaX;bo _K |,%|\bLy@ QA$0HA]\X3nW sZN}YNM%-Dk:P$T4yb d(.C\1 VegDi*ycǍ8,7?죇]sBFS>_nEWozK0?W=-q yn-LX1[pAj$p'&If{$xr\fj"{6eՓdҼ}vQ.IinQshVG+QjUO fJlbZZLsA7%>OV&!ÔJRűI +|+[y{|N5b-t)3C +gh9ZGJcB +@Tr+4Z3&pH^ 7"=/-Z0Lэ\Z:Iz@`nD'֠B=) wh,QbS;*Z/K +Vli !؅ta&˪UY/!3nk@.\,088o.%|2%{aw0U2B.,1Q&h o0K1]uݰÝmvdXxƆo,V$rt/+ٌl!iơ5rjqXGT\D^C%7\C[sWMf@V{6Y;+4$dIC-#d~8w{~0 xT:4fjxFrIZLga}E@ʀ/Z?/f^,yR ՟w7?TCЙVڵ`/C 7V S,2dor7Y/^CޡpMxL,t~b rFӐHLY l@LCD#1)J64K +i̇%JKIB%ڒbkiL[֯f~^1ܛTe@IC1'F~oԵA?]g_ 3s34ZDEXaJ擭#3svBMX~q0R"CGtI^u3<|L]~ߑff,jf C<`579g5x=ϗ&kN"E2T~}#gw<». +IFs1$b_#[Dl dRe֕BbIԖ.͕WT ʒ'$ԯMz3NFL =2Ɛ!Tvs$1AUEQ,ex^Z4DW,H>oIAr*8#ƒYD0۴6?ElWMu` t'P^V~zN nǗ#)WPGTy4piH+7}Z ;.iŃ);[/c]S5 +ΟLI#J zц:XxnsΒ- aM5b &K@jmIa +QGCU&[(BE Y|U'vZ"$R6O(ZGF8VVQSS&~Z%lpT*KA n$Pќ 6&_ꖷO eDDeVd2uAEUYܫ%^@=9-'/tToAǼj(֘$^d GjXz1;&1 wQ6!_c +/F K,J$ IYw`i礀#} F%g^T,P{"o1ܖ;ōd13cn4g;[,҄i,l("1;c K12e3[\.y$vXc20XE#S311HFc&c,Hs8)0XA R4qJC@54ՁgX +5rHmЃܹMρPO%7Π pin7Zc76 (_΂=Xcܰgc?;Š<FcEu@hUr0"»2j+yeǙeQPe }5S?_r=׸8R(RMaYwo~-e<8-B C>픐gk]-.o D ^j^:eQFu sGi$ViJ#Vr ^! +J -4u].vBYNXS+a,囙ͣs@3< OnZ 􍑃Ou96Ih _ҰxAyd>sǸFgd 6N܋B ?( uJl6` E+v)49+&&b(&Ćj*ojq7Fi;h" T,E"+"YsWõ oJb_{U)d%vR?s&yh<#50!{b;9h@">M< -XBVڢih1hF >8o @z Vx +e[lòl 7rσY`߸ Y/HG{p h@0i0q;/ѝpNpOpۜkU 嚏~ݿ0^ұMX>y &- +*oL{-yk+m¤@@SFbQntq \؃n0np7w596f 5F%̭HEy277n9͋_vn_w/M>ϭË{+ĒQTjɸqe<Ϲ&f"wǨ^ƩhіF4D5Mkʩvv/ׇ* +i46ټ7LJ-IzͫP}G)K0NF$-WKk𫊺yڀErNt!Ark'1FɆ"j xnWk2 uPqwÍ8Ϝ540X6q;ϗϻ7Lm܈nv.N3A>Wb0L~[m:nQ{l +C |:ɟhB{ks(2QjLK- |DBE +:4Ξl1<d+#wD<)\|"1.6k+hǏEѴh/(ϙ;ݲ,""h3t}f7 /;kgs7SLWI^ٓ)陋u yUUnUT%h[j~WgEWmӞUNl\f3Z5uD;N4D1۴{36"|Jט*2g#cix._tCB]2>lTB55Fn &`Bgn`%`ۦ O*hC߁M/DqA~K2RL4BftW]4 "t:RaKU&T;e\qZvR'C=!v>7"~NuHaKxnT[y/Z]ߘFc X\2Bq*-BLh? 2j>7Kw)'D>G(ý8[@0k>}Kjo2y ˳ 햭HU.f1?<^䧚0u{k܅4#M@XdZ:A,̎,Op9rua1Zqvqr>^>;6;A!0Oe,I+>=l~)"<Ј0!h鮭8{YPENr^D@|] ;%3ؒTAfAV1/c+&3l_01@6}^f T-`|fEtL;Ahri.O$%ERbdh%*]3֔eS-:ɓ6@oU +VXU%jU?BQ|i싇:F6\t^I{Ɣowߚ.ضg`}P~R5.cI0 $St[Z*h=4JXgsr4BItV}֩CWh`jA<3>7pVj1 + [kf#&ckie< @1M&s%~h%YF-^AKv?8znz,R?hY,9wa7e<aciri;[ [Y$dX$5htx..Br֠Ziҏ[J @s5Z.ED 64h>m#Io_Xp`4<fe9t@Flx,*`sp4&d  @v59L&> foL6N +7HrrxےTIQ9] -k9]αcNʹ]m[Y߳9 %Cx )(:y'JX" n @% oI8 }P 20 cxzjdLͷxHG>gt]WBx +m4<Cs5x;|/ +x4כhg C5^ao, 23CwDĊP6bѥ̰8͈E-*ǓNR霠F#eGUA)e*%j\w22nV[. +5;#ᡬ{r`7 +dﱒX~{߫On^"6=os؂ݕ܃&AeHuo"n~\MơhAD> ynmAhW2{vpE]?_F -qo4'iti?|@E?A%t^ZS\IH]a0G6dY<҃F*1\KfتիȤ^ Nj~ܘ0~ʐ>Ŏ^͌q~rCJJ)ݳs* B (Tsǖτ~+78I}!GqUjHU`[gFM/"l&ų"SA2AυS!IU,T- o= 5Z8%>̋_DP0i02a!lPJ^Ư +=z漘C֯n( +ch# 'a";_xe)1c'asH <1@.j5nwROY% +Yx@¸HU\&p"ڻ@9ש|DDV 'D +g)0 +RA Q3 ͂, Zd4i%,'{+n~?;%^kwvsv^Wz{\|LN"{vFrgetzU&}S+a';vQ$i0spXͯѴv'Y_iiNBWkA ;d a_u@uȃwOΧ`y| W*Eٲ$핑(_b21'b房o`@nEi#MhhV>|\RX.@W:un2kۋ@iuПN*)AM9Xs!\P@@, Jb2|&|٘sMe5ؖ'T;%|%ޑ_@xQ.nJ9]n9U$-}咵} <;G SQp?OUco͗HIw߈d"ä;?`X/ Jm20n7jtk"Q6ZdۭKA7mFi<{U( yK>?iopn":9f{'n ''_xE쓯 d8TwEі6jgVpveO!iЫEM9FbH.`"P/Qny"{zVA}lj厑ezd[-P&ډp2å!Ki=\p2^lɱ&P!3$> b=kz`?]1%2Tk\ljc\H/tv=A5qW/ ibv[@`ș+mg| 0@ 3יTsuC+>NDC\N32x/T.H{2*io!> "zIiW𭭸([;[qj_ +HRvvV$q6:Γ=SṈ=/#`,cg(O O|*=#$E"uZ⧐k02{Li 5RdqF!܈էF( dEzmȦ~YTA(rCɒ +KPNMѠizfq>72wz89f-$Q"{Ǵ%ø-*+M/$`A?\}`<+?ulӄy%G,jT.LNX[IrkoQ *`rیifU+c֬~5cfjbV SIGY o{z&#aG ֠|O3E6zUU}0zq{3eMg9~+u "f] D;?6;W. +h&ڌ eLܔwɌ"'6D~vr+:)2\X?^Oz2̚`. /i^G/CtV~$XKjxډ/OBԟx)ˍZ~Wz~ŐYk`M@[GF;RTiSC!`2)&fM7S|1<,1G KAMb wG @Jٳse#DTMm8879ۈ2cp qo [8~pWplC*#X X_Br#DOU$<6] . +`8G^OaJ&E;8#0bf{%o@k!!tUE9y+B-͜ +1 +)< \? <3V\ƉwԘTN>ItX|f~P6DP^5~,=ws,Ac8mix7vp2?am[oXHw gj"Ps: {M~ȇ8b0G iBzO}]]]w>[t}wwQ0~`!$h7lHf2#]iFJcʺɃ=Ƀ ~?&o_ڼ~ ~}w߽X/x#CX@faCfˍ%xk .BY*z ;jɿ$x"._7.A`QФ'2!iBb,DԤ%bгRxl{|͏]Q5 _/ +Ӳho$%tQ$͛3+ (ى3rbS8+\u͢]Jt TܽAe*?HN8= +GôG`1{~w-nonuGu}_/~W +_~j7|}^M/?Тb**:b[BaEHxK*,7U6_p-z82ƪNb#[|mbSG%j >sNY,ܮ;FituݑcR}^͋_^c0_{ow^}zqK/ +%'g42vq +ӧP̀$6ϛfE@*tA̓D惙kφn`;~u3棑=~_\ +D}d &k{7!|yuP "QI'$#mqІˆKL@9Lb:Hӻ -+’ʉ'?Fbwbau=g ubr띌wkK7""zd}XMyBi6*`%BѩɎJfȲNxz!{~zz~7߇7_SozXyϒ@eo%ToOo]`3t߻?~;7_\rtum&(Z4fBcjceϞϫj-z!U*]sk Z$nbHܝnÿZG'ۇK~/D1 +FI2lAnxOXoTV!lLI g,&5P&(#|(h:|m0ug>s[r`rY [f4V\O`v ۯ2/*s>xn^ީqAIIgXFu+| >rU(V?9Rbڱ|7_LVvKwV; k_OFt_MVsc㉑T~f.EgxZU()!gT6\$s3^O}4{|R +xP WzR޾R_/p")!aCmmi=A:KRP}c*0R$w#B1cӖ6C\t5CO( ;unE uU+WMJԭ3 ?@q%.܇J5—,Zxbk,ZDɐ_/RDbFܺT%iר)HӕpWBմEA~ /Yi5~80駍 +݁T2$e߼hMu=pMHKS/W*d]^flCE1VAϪruv+UbrA\@j_A_p I# WOX(phj} +PGqR6 >&l1 K +ؚpffV~)cC˼L..d^&uJrAp6h!y>Qr"z":W% 0e+ l %]n~_i;*Z3a\ϯe)duq@f 9q;-Yp+!F!&Nhci~krc:z[txͪlUa>B<gXe GҎ)qsWqs1914o)ELq9 +ہ B +zݳ"sF2T- Y[>Ȃ6:OD+7*ЬAZK,:,|:ݼzY2F5,*rkC,B^\dKFbG¦hxJ4# +,Edzċ\=|7W);dAgr< rĔ&%<J^+JN 'F_ +C-"T$Hf'7΃& 0ҐOA XޔjL`Ij 5Ķ(V8{.4Գ&#K^k9l%7 ˰H4{R7S)LIEة48L@:"|6L JVÅLα pd4|,g( 7R&C0*T)chDȃˠnE +\z-gs]PRfT7u%y*QB1FUoF =/vF<9361LF)$ՙw45E"$at22L)$Tx.֤9ESu +T=S.̔z\ 8~#q9/Xsb>D΋"Tнp +gxȐҽBdJz,Btz DJk@gpa\^i)҇-ڈ\j>p9J5Sϭ+}åE~.ыFhZL  `z lqo3!Eb:F1ErދI=LhSEPveiT|4wҝU>FRhNe=H#s %ɠdc˔CCH<Ѿer?}k;ĻNVHN4`[!=RXKG]F˝>BfOa( 2q~t2Zrs:P mՆOvvVϻґG#,ыև]Ro#?#'UG?S';b,^FrG.E1yAོPV,[/ .\#+4]bJ[*yڠ 7ʘ|ߺ7 =\sG{>i= + +|_&! \xt=& uy?~ky +p#]ݪft>=¨GL>tэ:7 fSS8QOL{=m;{qJ(W'BO 88L(dQ(>.3Ev &(ɢf,)zz*;M"e*#1O0* @a@,+2d6VbVe +`v+7FH(n@c;i;ɐJa.XrwMg/Qig"΃!DbԱi-#Ze,DY?Fm戫0%d5g6ڪUAK +z WX&MDai.^'ly(܃S쨨@rҔP?-N)iU`WdmUMa4&QO p2FOq= +PQJwiHJh{!XD$%JP(dc +SF\d"AQcwCdI/YH*Oo;縊Y;I}|IE }ew>T;$~Ke[ehi5N *hO߯&53ɒTwGwl&͖Rovd@$/kTT\Rt+ޠ ' +3=~1#W(=cu#2kAh.įsaR99ce¹(s,2=NmcvK0#13#߶au7cpL-7njj7Xop'zJXcT뱞18ܐ3e1g5Xs1#s4DI+JVct_hٌL3ߨg!ds ISGb)Qs{ ==VY.sΫcc EH&rDBEb5L#Nɐ _897#SF #f#scdL X-rѥb8G5kaMe4 +H}D',sBC(ceUeX1RcQ]ezDY4,(OC:LVFZ!މ8e/9q)2'ڌtѦ)8AT0Ax&yJmZ.C݌yLX*t=8$YPW2~+N ||9/bW0s +ʜ $utY~@2yNxN`sfhMŒ(kZLSbuc;l^=m4{?̏\E63lKI@KgQsyQb| NOHoTTfJ@ EGA!l،,Q_i{Bf4זliß4co.v޼\ѸhK2m=RxcM?mqȊ9ptC[[+Pͮnԟڤ &P/͆5&&I_!46.|m2[nS,[>`^eQr B{#F@?&6PRa@;yu4WRb_*yMf-3Ēc~rc?e5[Iyj*Ztݻ|KPU"E򘘜 +9.$ +*njW{m@+APyy!֬r[B;NjL %TjdDۺvyf}Ɓ:eۚZ Cf($4 h~Gwq`>O5tpvʀUTlvr3- jW5l.dw*vQV?d-xJgx0/P#"Bi.X p7\y(`ބC'APp6 Q64&'u'\$P.+%#3m'#A +[-XVFbğ`ɥtpz(KՓ`^naI$I=LdVIeO[PmH3O0mŃ&7XyƀW,V1odzsLZp~C+á'MT!^/=Ȕu{.ÙꌘQ'/vs'cJz/O24XD5QI(\q1X1 +~RR1/KF -wif#?f"<S7IX=DJUNRbKO2dD"~(c90oÞkzߝaםzݑ=4{B6Mb0n>;! 86;lxȱ vsJy +BO<*nAaү~MLoVͼ1^϶Z9>~_ƉuƝ)%xheBUjp|q.8u\Rz' +(G Z +Kdt o$k*m3UDj%<r34o2ә "6H}L}3gt <7 {Ly ;yº\W7V[Ϧ^*> +zLŇ |o6tgkG)h q@^RU:U%Nu;b.U V +:Ð+3P*so:3zm>uIYG2OC՗4vu,=[`Z U7{~[}:(ՊEltMthIΰMmN&TN0E@nFmˬfbvxÓq~&X2쀫a1Q@8a5%+/ٜo%1Rt@ST5i.I{FbӬ谂3zE<4V/^nZo5.ʞl,RS//^1 -t̋' BdG+ +^p7]]u: R8ќ؉^ωv!=IBu: U!{2*rjjF?x +&.|x:Mu6O5ePAd1gY dʯwվ^l**c1@fG4.A=Tjo&1) \1q8E)UkU *kִЬ4]2`|Z^B_O3-C|f1@H}Bvw„W}ܔ6?fM6iUj|@1Xb25׉ a5sS#gn &i4*Tֻ͊T)[:n3:nD4IvT,Z :,ΧX3B@ks煹*i.8L悭`-+h/-_( Ȉ|C;EȈl܎-ޚkrNLG[+#6ʥsC4Ks4mf6Vɐ N,Lt k + yuu@)Âb%u`m;9~9v+3 M!y ǓwA,6L*2jVLj_x WECTY[R":MX Ҭ!.':D΂CfCt̡#N2st=)*[Pi<2ۄ%Z&=/{FnmM\k=ajaSn]5K`G֌WYt﹍{J".ik^_>Y$cBӡQ$Ecj`b&>JZ9%$5UP)k<;e!h=U9˃K W@ȥ%ONel K>""p`Xт70#CY(#U 7B*q^\16:nS8LU,2Ie +32doBmꟌʔ P #+a:oT%*42ףJ#pùjI|b[}2u P1{.c +]x:-Ym8y|yΉ e;"[&>X|AL|.QOF1g6Jj }dܵ.O^r0 rshCj-$u-5Y;'GSђnd:I^} Pa5 +e•Uɐ:_3q./S,պEqgp^*/1Ŏ(%Mܶj XmA8틈WOУC6WN:T lƺUd_G_(ݮVg]!^*+nOtX!1ZӀ$6aX yC( N+Os!wfjj:A&=\w$On<^uy2밨K)Z:SB6Arx?[n 3hNpZ2 Uʹ* Fds^L.K6w^cΖh_ yqvl|%>#kKSrޡSa$*&!89a~!=ES=ES=E"wk;\(6))V:!v]V|mPP5ep*3W挖2Wr嵿~&}з y{y5*\DKL~x۳=Kڳ=KYO?b.!'ͱ5S=y5g[{g[{Up4l{ r>)~鸜t(''gI{gI{<ҳIesId.'oT &%ѷr!3kGhUlF5ޘ1G 28V00f0spHvkuu؍"ug26p?cM=[8r7Vy`2;hc[9~[݁CʨnV 8z>_t+RJRM^S}!9T٢y5Q="ɨ]8$'.c1F4˴ j?jGbS;K盫Z +U]gM$#R*$mf#޾ +}Bl"ΌN= %'|ր / .y.؅ly6 /*=LC9]nwk0tMD[~\}8_`߫Ke 5d tRd!ښqu[u"C+;M] ^7cx6⼐$c?Q'"yª,D{{io]qެ7/}[a"G(Kv`rnj +JݢΫ)Jsl蛕'y#үaTeL};RW[ * +dIЮk~}xYUӲr---_( Ȉ!?ZPtMٸ[vu|79&Euzi# +_I0+J\mIx]`ԫTMc [IX)W}EF?fZ~TA1 K٪X.wt,b_yx:9ˇBvtRQ=?hGB /wS^g 2IiRۖ +dł*+mZl\H0޽؀x-u/]9$3\H}zIWp< +?\VwP[UЌ}l˞unYпu>ߠl3}P2K]v`>p]5996ՁƬj*5ģu,-g rLP_M +ګ*mb/wKJؒmR<ƪydO) THE v869T,-5W3t]b(>~$u ,}2bN[)ns^8-p^-^QD㛘wvo%Eb)l<,q~Yy=/_/0{+'ͬ 9fpy*Wj +>;ԉofJ|\o_߭~0|o?է`m<=fH&mTr1ś{iu&o7~rؒM45F@g&E#KD r!= vwXY M|vya8e(0XtGї*"pUK[Fl4.ja?44 {d + `S`/g%f;sAD 4ga@?  u,ZC*v&c2 &ݜYLJ]QB5Q%N+ +p܁q``r^2*J ΑV\,d]|DUҵ7|Rrv h`w`y,7( p>L/aB;2e؀y|V!7{L brmSEy4rr4zG""]HdѢCxoRf`rŽГPM ZXVDWSO3/FX2 6\p"w}dw)D ˴*LeN>> +D&:#E6#I φ5H+ |ؑʸAf|Onua;KPe}ƨ E棱%}{8j&aaTvataHQjwÖV=>Cɷ%\{:?4R&%;DUq,&qqROL#.aECiQW,\dGD<JQ9`'ߔ`E6S(x,!UQ +VYyO.UI.d$U rNo(*Jh0cVߵO P?#?lx]/~+[am}r,6PiH:JGr#BFK]N #xP>Lm A\Ɔ ~LT\JP!D!vE޼#SμwD2:ieg-gfx"e~<*QUy/"#"##ׂp +7yUW*\Y6tb wc|V,.ߔr|F_l\-i]_&%;UaeJC(`Er Tx1ᘬD(q(UKMkf-%ZVbp%ݛ1RcChvu)A#PX鄘CI]~!B r_c ~yb+ņ X)q? +X@D0,'BFh@/(>9X_H6_lO"_R8bd< ,( U߰:]92ؓ}9~8CC9PS fe H%w\N+lZdb4o̢ru8Wl^hb:!wC4*ۂi3k\3`l]n+#;8/Nk/Lobj17a_Z- V3%uVr2 + 粪9@R^YeGjL,X"J ~`6!@]vX{Rrz;2YxrהLYDeQWs)9/9X26_;5j.HV%?^v*`JpPN]y|hq>B Mؗ"2o!#__̕וm_])I,ogܧ\x1$L~DF"!Lo|Q|X_]T&r:DCEkw$JI#[z\AgY'sʨf_ezAT^ŋî|!=Yx^ϧK.0OT_{3y'EmY?fIKi\NBrp)E- +1|x=v*xVQ&+z$R \tM|Ԇ&wtU._Su&upɴaeJɍdJ|2lՌZۢGAOt!gsʣ?Mō5S9e a#.5bΨUܑ +=)>؇B,QlU\tsU:NJ<_VH`#B$/rCa\Qcrh@hQ,&jOB\-]!x2Uh|z{AJyNz9zElt7ώR9`'j|2Q_TY뫫_|N/۫t>G_7y}uXQ }#7mR**%uʝ\ +C(:VTuA+bjWrY +et9_2{-:U+o6 +w3F4*3mnZZծq#se+)>eG E6[3ȭl_l=b++~@Kf>^]}_px&/aPͧI6]!rfMzXilk}Zb ѨO|<0mg\bbWFr.bE\lꡎzJg2w]{ߑY:etǤ}N|goL z\;$6t)0/?ŧJc` r^g_J:)Ҍ*i/ +$P+ffGm[*qɤ򶉡jCIO V*0DWUBIk,^۵Ukm<Љ˩G%FH9tU +sG2 JFVVLQʠ" *380?hIYNp>#vZD5!ŷ˭V*>vPHӚe8]bUyo/B!#,dpb{Mʖxs!`|73,*.M*{ݣ%a Uٌ~sn Lr +Aj4I[\f^ Cyf]24_%Wd2`uE%]nrK]Ud7+Z,/˒]fbV}Nӿǎ׳%HLAr^KKӚd9wRm<7D . ¢f*l"z[MWoSaf&EDŌ%/[}vE!2EfI.j/{aI겢 jibϽ8JBƮkVfyyfrA> V:De')>=ޣ]dh6zW;>{R8ɔӲ~LeݏXW..y%W#4Z,z߄j\R†8˵$C.pB^ U}$Q7zAM!Zi ݔFZr)CRIᐟ˱R%dWBlk(8FAʼnAo]U6P)U/c?;3>a`G :qڄ@)j%HPN"p/d#n-Ʃeå/N3&udAmON*y =$.\S*.WN A:RvIn&DgєzhfQw5BG !HPCs)l?~"+4 {$ԭqBŢݨ>> Kb.WF:Z mgCu <#y#QK.Pɻ5R5xX@CP.C}yMVB[a3dֻfr,+=g6(=F1uO*Kn "]F%/`;S _B7ņyL/JjW89\zԚiI{=u!GU-.i)uhqe$t7;**I(&Tw.=`{jAQTW>p[;لuA,C*¢9~.h04N٘ ZVj pURUE**o'[4)g?PU +jjdkDDzXx͠U>$F >֌z!mRTMXRdMO b"$cj7Q$f”m ZAmR꒕]ԽP!₆D:T>jRT*ێ̯ZDԓ愪5lf~0n0vazA)lI++Nʮah05)pUPOZPOk ̚)TfwW\{sG¡VNs x <ƒk yϒ=UӦE7,+Uov֜Wp{RܛjQmE,B6`M ˉSߵ(0%mfVR)u)0܈Trb.ԡ}l9Y{6 e/ +tOSp%L z7\OXS-WMF+dҸDh,/m ue&<Ɨ,Ъ1dgQ&fX! غo4!.]y1$\ҍytz{K$ l~0f}G|( "63^3idOLY4w.łb܂̺hVbP^SyBxsnvcw|sM;fY.4yc>%?11V<@GN`]>IX'M>|<6e\>DVITe~ϷiJ$/+zI[Rbg+CҶSIS*vⴂ*¤BUj +޹PHiMBt66h͢F)Ze5eR@{.e- h--"*MxgM\EE:[ĝI'Ec"LY1ii5axl8z)JS`!{ڦ%mӺ![NVےl 9d_(bwŴyx 7Xg/$֋_M"Eڄ 7LUgԒweR)S0S= FNls4}Gzj0P$HCBadYUBZCܿ$ɣIr-W[%JAu3RZju0ƻijMS۟~Tk#%my./G\El P_a^ffA}C}ۄra--춑ɜZ˓q. }b(ZRvUQEZ6nccq&)*.j+9G첬mHW]̊f}[lnrL/KN6 ;Tb"kSϭB JkP\BM~3֊gi K*G5o9"viU_a_Zʹ//ٗkѕbZio#^po|kE +1D*hʎ[b,J^3਒^2˗|<*w÷z, +x"FkҌ +zR|Cב:*϶06:FP2`u[Z~EFh:۪-Vs׾VlWaZ&;K$,5WZ-T_!mC:F-k?~|6^kG:qۗLZWW*lUjֽ^e fx4 Q{/h`Z#MaZmZ-ьK=|fZSl̍VכR"@e"x֋zy%ZwF2޷Pi*cЊUPkIWJD=>"~E2A*uMIXp՗ +1~w_VYUvl%r\XZĥZV$:rμC'TH``z' b +&[kۣ+kjH m-J36^gIXzZV哞T:Nn[رh6jb(ս)yuuk}V)7*[+ŕ'e֋zUbZhjK\tWn]v +%khmq mOpoIo/>BLvX[Y ЫG5 ޤE[gAvvI0m!(I u@=UKk{V]zQNg>v۪5u}t6@%QZK읰>~w+j▜\\Tz]}>I٠TdkcT.rVzJ](QWȱEŒv*U VE^54̋M3UF>%yʌ[P%i$v~J#'}r [.vZfZUeւ Y:+;zʰ|Zv١,3#ݙ:J=ŁÖxvaj/bᑖy2-'P/[=1a<DX:p 0\p8jpհ1vUc<Îyyضz7hW3plȊ2[Dˤ=^!c">݁YG8p{Qрcw8hcML~>Pds%3ŋ%$5l5=cPND>?韩05\|%󋯒%Y?{܏yica/鴌ry)^^D?k e獖hK)T؊dc+2 /GpSVMWO .Qf[DfT֤|FZCJ 驾$ +QEq*Gd܍(-J=ϋ7xLfU W!qp4О-R4Jm_ʣV|LۣKynϻKyv]1k֘YI5b$e#CBp-dIWGlFm֎CEW,7iOOeyuϥ2Oa'ŋ7 dF=*>x~Sy9RTe0)UwWcߋ"F\&IK +U{ݵyT"py5'-I"4M:KYi*XU6A@#ryxaCwbu}u{y |y{%tU]yf:\7dqb4dB(/ B6]i(UW7nܣ[K + ʂc^K* v*)vJ˨@v![< +ߋr8`ɽ&JMŕ~s,JzQ-;ZԽՒ/s% 3()z?Mg7WiA,t{Ra?em£z/ MT .).W#$Jx46lnGY&㣱L?J(:eEe.x _j 1B^|?䪲]3˛"0Kp\:nnPnD6TJ>)N } kjcޭ2ĞEv5=8D!N@˜7س݁AM`BJWW-ޏI沥\(.5Q5Y+SLfͫxvs&>Ǵ,TF\^`c(v7\9Gq-8_n%a*<ߒ7%iQZ2堔Իv" (Q=~ŋID-ᆔ%D+nn6-n':V?Z$j+IzM ;M MVQd\%TY>,<c^TE)$UR<)5uMl2Mo+tfW%4R=+eͧdwc+(nnW %JbT^I>|_I#,OF2:SPv DcXe2I&%UdiP 3'_|eaJ:cʌ$_W=u0A+?^>  PB' PB|f!# 's`zZٝOVy7w t=-<RFc/J\ C7s\fX;J/`741 G0DO%[@,&T.Na0CA x(oc:DHmLl=nbVx-VbvBXȂuFJCIP,sc&.{UtMR ,̤KROكI[q|\:R@A@i0"7sAz^Bl%{i! 8&kI=h҉Jlu G/HHю])&ؕbC;!$H39iaԉ]9N >+`*ѡ#'ݠE9ν(gh{QAf/&9 ]! (n + tF>ŮO|݋—M/\$4k[W_!^@@^0:8-Z0ďa)a@ 'J"S*@ʼn͊|z7I'7&K/=+=#5C;usm/lBJ4 q*&ngJk#]s͡`׊`׈`v`wxv;MFYx8 |!.;62ߎ`R!c :`c Gpl;N' WXݵvp(2M Bu]*S<[(p1-߂-xN ߂;[ \*L@#IexأOdiMȇ;T ` GoN'Z[R%IJ ?C2߂{` 6[:|< oqB!:~C8 R0I + qm^ȣ4>_a ` ͥGpsûN7'Q+M!I8> A!]&ML +d׃ðps۸N7lus?>J%iFNĀx@[-.0x0x !0I$BP0eQz$u|y.&H' H_ ``0`4C0 >]߲c@d8tH2xwK"P $鞖5 r0x8h0Auq?v +nD&L8K61OK2]7sФm\}ه@4:O@v^09-)p{V.g؇(Y h, Cz03Ʌ\Ʌ<\ӓ p`210n<5= t8ɦ@? >{zr!'2zr<:|O.4'b:+g}(Ɛ +۱@ +dɅ\ɅD<\ۓ+.bA,v; Gn%(Փ xTSƃAӓ Y=ѓ Չ#xr=P'W!l^PDT'`B7+]guBV.dtBpu".\hx.B"GkNcq 3?IB@DZ! +``pOO.dBFO.4'W'ɅBݞ\~Z ^"}/B$/Q[ !3C➞\Ʌ\hON Ʌ=|ƊԍbzOh*GgL>A}]Յ ].\> ޅ upς`7(K=K0Q +<~ ƅ up! ȅ'OͅaSP?.a\əxO8ff4@Q>$W/0vNl}@. tBV.4 DrV$nyHHqBPgE*0gNH7?H'5jr W=ƅx\3¥a\;e!qⰨI@' +8$g?P 3 Wf!LK7z1LSn-)Oۋnt-AM%q@qBd$=Dzr5@P#Onz Wwҍetsa K7R@تc7#i g8 38,n|818%4pbd6 +I>!@^"7=ش$ڻ'F~|7B&Ad?"B9WGx\Ί&ڶΪ/2K坬~ cEа}CbIn|OB8 9g:C:4:;|'t8:vBg߈` AP̏`d>H3Vw; #?({zC94z;|s89>um[0$EH\8!B(!`ۣuy}zC94z;|s89> "g8KSB$(,T+$^ +m@vC7>Vsh>xw"pxs} l *I '.v(r!.w5fz>Cq9zC9G>{ns<ڌA +Yv!1|0fNj5Q;?zC94z;|s89><#3DH xrd0 k:oU\<}pN }ϙDYR T~ P8D!FNJ{zC94z;|s89> 滋 >mnD8W.% }pN}ϩrȋ3`ϋb7Ô  jtvDu ^pZX p ڞX?5Vqk0=Sc$Ł ; dAKi: X s}a Ap?z9fqt} 1/&X,F)IyBmUrastj@ `5C0,t6^軾e vuv"qid¨lp}{ +{`=P  +{Tv`;d':e (NbM0vRĆu^WA=P`=P0h' +{[0\Cw8da$@7 8 }@=P`=P0h' +{;f.I`kA KB$vxly[ +[`N a+  +B] B~f.(AdN$YmR6)Ϗ=P`v"{`=Pн"ʄ oKa䥈J 1YL@;+F . - +{ +D@{{ a$qRM0 /J@86@腾.> +{ +D@{{C!JHNȋ݀]1U(ln(&!|,-*Z׾eشoYM޷~}|Z-vڷlu}KYl7mP8r|AHO88 ؽVf|}6G[53ԷO=;Ss<cd2R^@u<RxK\߶!]J@q3alScq[؝ +:^`4 0# P IfM>=zF38]`r~=6)!I[d#޴A +(p\*q=.N@pXøVܣ3CZzT5/mQCE!z}n>,DO%!|uz؃^0}8Ɩa-FݒHRDd-ĺ3tnS +"O|H.]ri"@; =ogm =GyGW6F} ib[d(!AEw $ 8ص]%T!o!7JC؆ق;-B8c<$%gT?^/ @nAfN]`u=&v!= G+4!lQDAn("L]wL# t"E~. ضZ) mg@ț?zNEhJCئY ;mBnyP=aF!v"Vf?昐[B^J+s-~Aꇰ;0,T URsdA3q[/(ԏH3B1eub9IqbE>gAω ܍Q +v4bZTOdc[H3Hi"v"NLRU("G\2vB'udqg,C 2r'9Y-|v}k4ww,jFG.PJ(KB( I"|O!um95oTpM7r;l5D^ȷ{!S>ŧ a(KSk27PI@CxK!/% 940u,ěZζ8 +6CbD/Fnb?|Y,t}Vf@gKl]%y}v'0CamqX0w*7r. G/0b!-(B 6e𷫪Dc> .]rBd?a;$A&~e9#+~KH3Z0eZN`l/0=sU]إ(NϏ }Iغz0C fPUhIJUbɚs]hgwv1;7p(Nb7 ? a H:P"v%Ԑl%~p4~Љ}C -w)|2HMb)(KaľU|x+08HJQ.P~Pqwr~āC +y3E0=H$1rC7KTNM3{8bȚ: <-lZ Z`-0@!%s@I% v2 " *3P.vE?D0x,ʢOd> jܑi_%K&'S2pLi5_FLxI_i}FUjEy4yB}a1L&_~¦V$5V팤VnECM굾*亍RJjcR#MctVS)jlmx2{UXi6Y΢ɎT:7jRCzOۻx\9~h]}"3fNUJh3Y{[́-TW2cNAEEȘ ;m,* J9o75Ư,Pc/ʗO^jZ/ #( u +t͑_M9f9Ѿ5v rNUЇwDtXAĒ+Jk lv޷[}A*K&>uk* >XiCp0՚L yExbhlJ +ZsY6Ɉ^Nwъ +A$<% I0G~0ݢfi69f,4flVxh1niq ,2mcF6]ez_*E򻢸S6[v*+*_T~:{hXZBB:+Di ,yB]`1l\Ѥ+WL T(r]ha#4Gau ]v| "X +:*Y& AR$I?)EQ*c.J]S2.jHʄ>("˿ʿ˿+Hʘ/vF4U4)^!5JҊyk ytM^AlV2և?];3Xqr$7|vfVMͦhvxvKHx?x\?59x^ÒE͔=Ľ5‘61&g_TWϫ|[<_UkڶԆ^tRVaԭfBQo:D}V)~Nѭ?zGcco4As2ػ iW/Ͽ~RyHT4t2F薌8_s O` '$po^(}~Z}qKY,Gd]P,;GOIGȔ(Zo`tbAhKfrDzM&T9 +Y~KH ' ؒ83p`:O7J Ŝ;}.r19A FrGƏV͌ҢI8:)Yl 'NF04@CVP-xU`-~kP8)0R ;<NJ6i(\9"̾Ncу]=':?^h6 vž#~& w,=?% YHo);{PRitK|6_Tl[_YF'X|2|EFnW͌)F.zGVhBt$MTOJi@Gg0#a0J +|El`͡^YpJ]Ij1 +pt[V㌐tjU +? K/_dP +j#&@l3ɒt5Z6?/rDjo&(^]Y(*L&$)VPEaN{9n<>woo)CE|9 tX6-UxGSZERJa8r>)Hl},l#s$|n`Is`*R/՜ Y@ %ʓ+nX+j 7d"ea]|R\eIū3GcR;w*m)D{SH_90Wj2&0K|F>Ih; (YH;↝9bf1 /d"b GzTp̄I(>89aT +E-m" }Z~;Ĵ<TMmxk9Bρ@܂Y;YChkݲmO&{T>+Op4$qK$J0d]=نѱ ,wgB^sl'N5'a7m,`6'/FdQRRYQoً<(sYXأ~2XiEtlhJ=4 p=zΘ䃟) X؄-d|`uFxYBJ11 0X 'q4ێK8KWkv57?9nQwQBؘƧ<"d}Td1_;=FssdJs~$:lW1m~R֊AxB$FQw3]˖!vIs,kfIl2g7jZ{S4l X&TE1SFl͛Wȗ7W7nuSX㳳72D_G5JK~s;g;_LN׎jvLndfA(p)hJ + g7y˓\[90kA__A2 W>K&%ĵ/8u*}}/ TO:y q#DirXb`f7}tsjNSCy> cVled]ln够nOR9,,\|P{$1I)ֿ(Qj$fH۳>'-:<9fgGMnGcb5&PVRṽQt.a?;Hch;u"D'\<'oj+w"NItus!oXFٴQW] (h r5g٘/N5:۾?R/9<%b: > VK?[։Xt%Qq ֤nƪ-/ݞsɍNQ-9W9pzg拲tZ,xdWާ|N8aj*~>eᒖ̧ TM_-ltp[Չ,|. qxJdlNl2"H}ְgMA{kL/|+LYdaEGi},6z]*DwLF=YƁgC3L*i<ɱnq h8l%k>a)2+N23+&ն(` /6+z'L nhx/ٙ OCtހi<^tוtbBNvesxh S1E=mQLȌ_x})3 xyyG&B:͙3 ]yaqA>}f`@%`ڑ舌OC΃x"aЋgpV{сCA4# :f% ]j)d^)XXH8[pm'#O!#uTtܕm/xZjNy U|姫xغdW7F|Ji9#rɚNlɧig<D=i&=g{EYY0 ]P#٬]'1fpҎviI׼Mcυm?;~b6ҎSْYAToEdΆ{Ό&jma#苟'F(LFbRG/9zb@Kчl><$Z`էs%7+'H\frCl  *xbnS)dcȔyd2l`4WևZ:"+\ɒh6yb2ZU ~NGoOm!Y o䉊[iܬ>{]1,s`)$I~r+dqM(TNRl98Χޞ0v5 :Nz)h T).BNFGHHL(xVB2~ڼk2)J$ڋL;FboGj~6Ao~*n9VLys*&䒵Wh@Q[G$ńn=Wttx +M-c'Zchy?R+Kte,}CXB <مx[MW;3zWO-Zl返<'c6QBTa'uLczBkI͌ *Hj(՗CRB$(68s ~P=d8.!&хA\dI6>m<}&of,\PKDdJز+3[*eĝ0 9+:ncq!%c#%#o-&lG,o4jTLkeP\:H^KJl"@^N~؆_Aam wg ~.gM[ZZ] PjmΓzYNkDڠg_.zEU(_оddj_^-Y̞{\QxG<߭VħiaZ ui^8hS}   +ɓcQ'*mG}:jBEhR ;M8e0: e |k7izZ֯#k:d]8|ֽS_SV_5@ɘkO*9KE^{Ew\CC7t R<)Sm] v|N7 #Xoi}Znہ+#SXm? 9d!|_x + {RvM&q}0{Ndz+:v_{Lo2w0b X#EGƌCAjZ,׷y?D5r-!*,uyve;ϟɺ׬~+!` Q1pm[Vov8ƦR|VQ?qgo8t'قbk$tE7J kX%FYɃvI0U!E Ck|R7)W#uLe]ܵź\R@_mTkMPu2d<=殈&E2,x,^MVЅ~QH8!}ĸ>DU(5 Hk3y}exU͓]`Fc{#ZoU~u_)p_zz}wfR$m%=&AB A* 1oU |J(EMNPV2:ϊ'P9B.UDXയx5`okN{a׆9֡W<UjQ|''~cTA>zIx8K%)q?K'^XMT5SĦ#DlS覧EiB7=E$9SXcujNS|i{)㔈N7Ss-~?-O:_{~ߐM/'_ij ;rPq+do)]ȇEwƣ`mA7PsatIJ:eA"C;Iwt&0V־m]!Șcjhe5U::1 +BxL=h0 Pa;K?TFAj;.!06l81/rI%*W/-m%RTؚ l?yl>y9.3$ٵg=ϾX]Cp5I?3ճ/"iFtlI~%zU 6)dBZhB[O&hbbfMh2/D| zd}7O;tR7Ͼȯ?~ Y#fiVl[ :]d{R9l?6ʕI +5=~;=E;zpVӨD9:4ޙ4V$ Aڴl>}|'܉*g&h&O&vr6m"Mj6|.eAxW h֥Q V,Θ(du(&6@3ۗv4(ȩ֔S%CTegEu_w_?߮^z(V|QxrEW_h*FW!KGIR;o1S.E8xrqHtsu`Iw_xhV$Ys!Ze,D^9ަ]ļs׷T,6b,\W ۊ<{˂"P& ˂웤[4\F@@p2_۷Rs롸thg*:6Zٴ-WItߏSo͜\ْj2 ~ņ_QNWeL6% #:ƴ+Oi0O f^r# dk\Jv v +ƮdSdĹxs)^ڭxYm)|IX>;DJ.RNxYy}(`P@fJg4ɩ\ɬi?OīωWCt(^Z45]z钷i'њΗh3$ʋ,J{Ms,62knTߋECӎE}]ʪ8AA\xϏm Qd~|GD=a81RBf|빕ثZeL8}O+NB5Ɩ%GzNIJ}Ir*0/K%Eoz .T pLai[u`Y-Lתx&?[<.`qgEqeTi'pnx'>楨ԫ1VĘuIV[Mꭖ\O' qսhy7UMEI\ֻ_zgHY*h<|n~x!/ يEt=ڊRwjP0^-pJ^5]chXx] pٻ܉#s[G.ějG^.4U%B%Oc,} c#o\̍9.J,7/{텏J Z@ACpx`nh ՞8!p*7шZc4"Hg .hﵞjw}偎KyG@ՅӽNy[yS)܎ ̗0pv-ܤ]O.i) +^4< +|7@Zre+ bWAWŧ6GT:__V2xW*:,+;\#L&ÒYHNS_n\Ź?7si +Z,R0IZV( +:Uy#ɣ\Zۿl0R#6r ^5+! ٰÆNZ}7mwApw9kBdj%0\WƦOz>dF/6>t_@ul#׳6&U[~aBDYFL5yp\/U$N65q 8QC,A~IS}F./jotYsxC?~8aq &! ޮ~4B{܃`e㿪_ۮ_v9%VV,ydV?ã Nvဋf=Fzv֚ڠĿqx{Ҧ۽o^K +YJ?l7 +qfYU獺f{5C˅G~f{^UE^*ǨEMKbSZפK }ouMy$< Kh +Nrb6 +俩FnnK}`8ӟyAR_}@)E'[8Zx L;#k }-:iG^^%ϯ^ ݇z/D]K7ZgAs4qwݚ0:%"}]]:)[\a.1]~i L 1O?Fճn_R~M4>pC, >nQ KMTW_䶘țȻVO':=@ ZOap5KP7 v -7oicmr~@HS:KaW¿HE6a .od`7~AqCsh s 7 <5" )iQ3lQ%:!ĬU?]p\taSpm''t +j;APeGUh2 +/[U(R8;'FUR6ʅL4 BM-N"A<:3h?O;ZmF.`OjdVK5\5v_/ ~|w"\a[*էF?NBk=7$( ޑ\ 2bqm6POIbmVf%[LI{vU6 5J̵[$ڻMlRo@rJ N]t<j>UTkXxp;rܓ{ɚ:`x`ziBt`rB@IԳjv$c7wM/ڦ(htN4, lQ:Tw*{޶tҭ Пdi6Q|Ѽkh v߿]ӸQ$ݏd\^+!:ݳ1 s5ef^eP⭱(9]j,9ִK'ޡ $϶e4X8/8`s68u>iZ5 \[I &=@X0`aWLвXuq4H%cijн¶lP<ك]x!n(otߤ3`ox貪#? }Me=䆠~E](T +n#)y;oC? 1 uPfOF s^=ر PD\GP4xGCzZ rCPuEpXgk< +܂{Nǽ)SI4m]-bd!W'Xgz˜瀠L꜓H="]D6v{36m8k*CLQݓ͂vu[5\>IvWAڂ.{Z;2L +[Y1IOceт$Yɽ0ɓHv"zoq` FaTJQ5顚acNqhHk(  W`rV>ビQdCw\X.N"t|> +&cN[g#!g$ȋg-&7&=Ugf$]҈fcSM_7>ֺ9BRr͠Hi~OH)tF*Bhv TC\aF@\IJEP}Rxrc_>v/N|*v`mj*ʢYR?,$b$%Al0 VwK bޞk+WӐ$Q4zoIva}dr߼KڵQ0Yمݚ׉an-,gϩ[0ejI3|wV3(5[>hjnPe9DMehv2JĄ]?'?nB/I,~9Рk +Zc"4(ZUXEz+B勳gX(8eǶq+i\|a>6/hpZ0o˨cTarR<_S<|QK-Maz4HH܊g Kcc 2&:QLiE鎙Bu ?3E>&I}o=&P&Hj1dNȄvHhs,n m>IhSz۸>zBh6/-= h 8\Nue=#_GkX/ ch8!`EjKUT'Ln-.p3[ plo +uEP'}Zrf f@ߦ.ztG8|r?%<~E.qe +J|[2tqMȅPr|^N}Edh&ŧHNf\BQ!bc}d2H@FOMİ߽-:r}aȞ\,Ѭ*92z-Ҏdk"p ŵmc3K(6Ł+oC t'6i/KmaE +׀_D/zrrCWCbxezP]Wa޿qʌ{OkW *x\fzuDGD˙AՖD<%{חQCtӥ{_ĵ׫E吽a}[ۉZ6'[knt5p#5۾kQ -O'G[T$je2iQjt:m9fK8͹#z5=;mЯMlZn[=?ַN٬ni>~:=|Ę_m=nHgp#Ц׮ cvN'Vo1Kx cʖܢ4[j1%=TE]\%݆Lj@Zuk/*`&\;:5lq ܪ3-]q QNK`jJ.CG2|(d ھj'p8<=XֈZX&fn`9kDNӲ^6Ns8iv.8M5|Gq%Q{T>$Dhb"ڽA49v*klwzzj|i<ΨU3%>4Ay{y656"u#tU16D(쮞Ġ +RG Ѹ s'N{jܬ7lz]t]N&BŐy#YI,HCN Q}0n̰LP\xzdc17|ZK}U{bpKi| ł١E ١@@ +Nax~7'+떐2FA^iAt0\ii vR;sWH-@W>]!mW4 7`3xw®+dYwys4T>fBs=o!;jŏAN?#E}":_n?v}"2t\J2IO[KA'1rf~Dtn_H~@Kځ=9..r\,{95IsZTetҲs;XAt)sH$m URR@mFϷ$|@%1GwM|f\ri+u[cG)̯%Yʱ{D.FaKR/$S(ި!TJ Kׇ+~i"^7HeQH#E3ւD Z G O/2ж-:ժ)\&ή"iMjt[bx mWq! M(h&nGnVKk.a`iM׻b=^?*HWui?eVTCrfs,a~SCS_ZGZvk+ҦUkfwXѧy#gεMMb7 +4[gr[5.E]K8Qעٗ| +,9{DA ++"qX64yׁj#ӍLץ.Z$~CP=Pt/x^PաV%hp87*+;!Y( 䶍pۛ;kɜo:ϱ;ehًj[M(=rEfrgg(jiw'DSD ׷\@  + i#HԈm!FPV`FP2-6`SS,@ZlPWXn#i '=mЃmmA`u;n#AЭBmF vmmE_I~f76 s%Bl+ 3Wꭍ o'r؂ I]T?vm +n#ȭIW~@6z"|Ch#@KѷOsn#8U964SA +ݥ};1ڐ<4OGvf`Qx?hA=m[:6r^+BTS͠!R9uӫh7Dו_(0q%^z]Y,͜R}YkEڭz?axE\'# `1EčJ\xjZfQȣvtY&b/@(3[&oݟ}*JZ ;d}wpIiHi4Q]J KCpMwP[l3dgsFX2 D5&ҷX3eύob`v_0c &Y:lbOgBE(WtNcĂ^J.,~ %0XJpP r^9`oMGI2GNw| + s({v儴ǺK2~õ`<KE1 "3X9gxꤍxvo` Kf {F""w/`^9c(r}iEߙEC_d@;*E!4i"Z*(M{;|s߆Z!2CaEtdsdEi( 1@UNpz,r.3teZG{tZ-`;7ߗ10:~`ǯLH@v}GCPt#F!:tya`LQĊ%\v@8; L.1 +&`@0Y<QghI2<< +!> w #:H ׿G"dTd-ׄ T QrKW~rQı.т`0Vo&܌/T$n +Ngz}MgXҗR 4lFyKu`M.p3] +DP?yt78?\pA!L0 7'5s1pƓĂ P(Ny径Fb,EGųHbWpbK`TI/# kpԤ=|* Q Z~}g? ^?,%uYvFQo +23NoypGPɪni>~:=|p+ݿW#>|tHPXFu3% +Z}E k7baQJ~A8k"T[$ZUgoUḲ=ڨL] XokG6&X)2gŔb9*ˬih) 4YLe@w 0aeUX+we' <( tI(5Ht. )]IB(嚰, +\Mxr L\c|! %%dzb!^<2`\Fĕ%bll!<``u/MExϞ=3I$_}> +ՉCTM8c(L9|vQdvQdgq +5 %FjlDr%HlK?}dcͮygKE1NFeƫcZ]duGw~{$ñkb2{Ʀ"> +6xwrZ-T?.Q@&VWtΥ"e 9-9G {usF꬀cp\9oq61fBƦJ@eZ\jF$B7 Ӌ^veGfJiNcWŰā88׫`-&x_CF@~M}'v#%Yk` 3>;{I߸]A?]|Q {XN3Pnx IƆ?lzw+dfi`J iqNoFV8G^v3! F#V4 ބo{/R' +|9(9sZ.|C''' +ti5y`t=%w&wZX 6´,A/v&Q<02ʚ'z5H,Yk5BA,1([8l!ܓ(QK޶gjr?P=X xѧa;@͖epH0C>v*MYԲt4&I_!In Wm`D}Cm. Do9OuN04WC y6˪M~߬w/OSW~Lt@JQ5`U&bqv "؅!F2/8y A]*i&{r7%s +{¤zk$椖%ph`9@nsr7pz18Pp/h}jv+ XJA*,2T7\#Vb pI!sk D0#O&2D eS)N6U{s)J>8]eSqi~tDL#_$tSTN=7a"N\,rE!#Fiƅib(E+*\9 Pu8;G+h +-:ftP_2Hx0X2v5"v/ax")F#o3ϛ74fotF³.|d,,UxB  6ϛaˎ v=RaS @F{ 1;vfknE"Z9fv 5uiž0/ J5(S1Z(@B=a0(6LЗuico +GSJ|S7mbRM{2*U)X"SEY#tK=[ 6zlgPI?JkTyFg䝡Ψ3pjjZg +LjMI&bgr'Nƻ<__8Q9 wzP*#}Ck׊dNYKo$;#RT,>E\YBN+k="t\Õh@'9;01lzGNٹѼxLU+,|^SGx880 ֠$)|O0$nQ$\{'J Ϲ=F:(쑉U s*8G0E{(09Lس\}Nx5V,c}Om;hvkdjTR@iuC9D/EbQBKB{qDzMKeկ;_ښ WP?ī`#ۡ=#Ts?x7\YJyp 3uYSmuAӉF k4si>ޡ=d6V~)l)FTf+~znd + }žf=}h: 6t _Ѳ;l(hu #ْL)66%b  1(ѫ+t&^ұjfYꁛt "/tfz[i)`Rd,ƓQP?) +s " GJ-.T-.H,*H0LGNEWщgoo83F6c`9o?pГ+@9박9^#9 4ۙ| dsmߵYV3>dn4o.S0ٵeEnAdե"*T}eV=䑈p!rOZb>&>:hV X)fԫFMX5jUݘ's h6'wޭ)n􃈀ގ/A1]i,_0YZyUW6EⲂ!EoM% sh ca]Rf|6VA&9{ j;'_.ٞ٩-X?KHu/A9 t!$$!,DPI*gTr?=贕!uv^QmՖk52-T[HKjG^^FqJ8A~yRH5a]?/?YFzQB_ OUZk>أ:-T'G֠nO۳uC.^ف9ƐҚzTW HmURNH^nf&+qrKW@5|N=·.'nz`h GʶaV7¸bM4498iTu(dHKIHf ]j* M>q-XχrqcZ;W1z1V [B/ԛ/ޱd`w= Uɳ$;ow?M> +>zkRo@L5.ڥsGnX}^6YY`<-b}l+8h [RKlN3٨8&+P&o|z/i tqW-zzlnni>~8uh  F|VX-@Ƈgq@Um6E2 ;n q<+w[[%7f}M᱘YQ6C%I@BZ/C&@) rU `1q L z~%'(Sg7J7qdXTNf[iӇf/ |_'Rgq.+&ջޒ1]XcknCo˹xnm6 yU DZ1=(Vl}|g|{~LA qO!~%V>v °:?'¿3P!, Ndqک,1din0%9K/j).z +370\QWɾ h=KEչek/g6-F$Zf1&֦Qޒ5YMg|qJ +L6e1V`?,Zt!ɔ̀-Q7L>rhB  +#5TbHd\̏s#-VjE=w@ux+߾'pzQYyA2I3A7a`o*#yǜ%]%$>+.gW[b+'cu`+KSH.!:!b$ LTSka-*XXp9?6wpgwnVt)59x}LAe v`"hHɗ4bѹI;9J`lGW\ 0scq!| +I\0X@ t Xn'-4L@ ؎q{`RX7]9*yįf9_ahx}E9ęCPz¹Ms 9]: tD/.em>.Ui؅%MIGjwBg䅈p\F1 +X\4aǹ k#9d3%:RF#02kATȁeAAUxёC5mvOBRo +4TWChWDhLIh BɊ0&l"1ռj8nx^a_ew :ږhbVjGI9=ޟ|@6`g~enN.zT%}P%_ 0ܧx FQ̣ \?L0P3,`a^gV"{'TQv-M4in9k2Tơz܎nr@̤w|љ"ՋZ$lM/Nab"IƢ`]U(p[H_8I2 *3Ӓܻ^ΛID|l|E*,0ǑG $ i^>Յ~5zja3uMS +7]_#OhE ?~gҪR8[̈́T*9W,]&=x d-d,/gYwD{FA0F(ГA "Sp^)<2O/6WF0738!l67z99UKge`v3_D{:Mf}{^eVuR#mɸ^FTiK`ughS:H@S%:6i]8ɼߘ94QSEm68`~4wsC$o+R(* 9mYQ,..0Ո,no%q9(ggR(x"V>̂n e܄JFu(l;{NV|ˊ'c2qestq8] ':[[[_l%jpd2ЧIUm"k#A1+YQH撽nj^`t)Q1TgƉ_ +&s\c%^]C(ȹ5Q]i@.%1'=0'PW.3 ìZf:|0RQ* pד@UNI 0kix@ʘP'0.Rd$Fb0FFJ$ 5HR=4uZ"m^f$g92+oO|zn& +]klx۽݁j#1K ]jE*| -Z /G I-^A-޼=nwڕ _~^\hp㼒b[Cu/(4L[gٴyB)aN$bN2y%) `p3ڊDv܊lJhOjV`Jk;Ҭ%kZ(дK[d  +7<꜐C!B +m%|!N,3f^?<]yC tʐ;(BU/(&L~4;?sQۏg+d/񴀛NA99PiAst;C +;Y?cJօ^ǁpgyB+ܙ$"o]!I1z9iaH+hދt|Gw2{Uv8]R#0DSъzQFWQݩ͙GE>7=<=wwͤX++(yExR-_A#<[]JWi p!tlw*XYGNyDTx<1ҔZrq'7y`=魂"qVhv.J"x V\SKb NJ%khHyoߒ'W?(oQ~[sú@زm;D02܇Η"&ZMKKoE\IlIj$)ˎfe8)Haj36 {֍Cd \_Og3 vTTмs}.vӍh;v7ѩ "}mf8f36XDY[2w tT>x6Y;u9:8+S(l_} G ԧs4Ŏ#/xSacVůNY,-dPΊ00i03{^_zC«K|~>< T1?iN4 Gm# 6ouUQ5N4Ҧ xB1Q#'oCxㆀS| +[#ĩX WLv\q-:_sy3 o,OI\i;7xЯ9b>/w,N)%1Gy& V*&L\0l04͇-Han1 ;Yp;(.^zaӧnK +cn]y/yO8~'\VƐ69u0"pprkaS]]@}~}uzcW 4l㛋X +mI.1\La_t00s{[Ά];F㫍Gj-҄c+gN+MtNZ1ҩ|Q:Ap \ȝ{)X^U5C؃sj^$[NivsqS7jΌKո<8NqsPz,5J^]7 +G)%|ŗL__~ /o#+}arc+̥ZaGZ5>н3 BaRGLJ(F_ za>a~p3.,, +(UO[?8I/GTSAy{ RB$WXaYh}H( +o+6O +$)'݄=o~LpF<Ca{e{dq!M̻',)euwfF]dh7Brv2Ú:&*B5-(aCu. +HӣX4;nql Â,^dhf #m$ڞ w~ߦ_dR4ۢI:q8?Y7Q\7Ѱ-ERA; m#˝3@+`T DNPa8p:ɠ +fI_ێ4ai\I|VnмYNyY G }(ЛtT<& T=)y v:Un--K{Gf`̺5+*K O}Bm%=dF亐>XZ$K-vxs=(4gYGn +G T&z?-r_?ѿy¿xL[oTV=Z~?ډ0"?x#L{^_ <3/zx&!I@ͮW͎x3PɋC>լ?4r S3$6kzhlZfF%wooϷ贜I-ReNvA^2A ++ +x-MsJU,I9簒>HK'14fƠ}2߃i;ҙI/1$#Xi<ίS| f⮬;#Ir8c-7 T-^v."Mc5zvS52OѮXmgW|m3j/ۓ0k銌U翣/ddQ8TBŊ@BN=ҾnmH䊮G=o7tobt:nm|+2l[N v2O>w Ap4'?U`e]: w]CǢUՁ&ǭ0+SPl?PAXVZ7:7:"BW46@h1FˤI%TցUX LIl7=8TK2xZ`>[}wO͌?WsO,&QĄB,G>xQB${+UkjC$ +FTQ(͕PZ;{e>Hg.(tǨA3AxBE(8ݽc34U"ԔPXop8kQ(x}\gtIݲӔG'~UAj[kHVWpoT6F7i?z^#lȑi|Y%ml,7qJJ@_eO3Y:ZC0!j``QTx\PNM`P&Gbr.KBaX2RH!m +)(dNj$s-J PJX[ Jxu+Oӌn&zY&N\MpEbvIJr6y#lz&EM8tp61ME7N( B3n;r3qTf3+FFJJaeli/?GTsoٸ)s ^'fQbR%A[+&k`z0ox- wCCGUЫ[` qGnA8̘j]^ʓqz  Sj9 0{:(~ol~:?̚\j:lC%rLtpfK#9JRL HuTθ݆a X,zs Y}29pv_LԂ_SYB'7xvOO}ޢ7#eHd-EH#vZ@`M^JngCh2h&1Pn߿]I-u +ZL'RqxS2C.Y<_;tܨ4=6V\aȜ:4C弄q~#b5XUB]o^P ʫSq /@xjނ|pdl]t$4. :jv`0 A,<ڸHfFxpE/N%t$yo(+$O)ɬb79A#b)k i5mr0(ª;(EX}Q="} 3Vڙ COU& b {J.+Z;ra<$U]d$˾G}lKb`l?K"fw_x𺁱ӥ d'UMLy ={yQIv|Qh):0gXQmjVz</!˰R6e$L;# A%1 ]a0!R)ˣv)0[%ri*E;0bCRA.@N>5>ǽA\@Iɣ.U7UdGim"`KT ̢9SkABnv;tMC0ɐ`uZY5 pp kCOA֠5yҿ\2]@467M[qšdn|Osl5KU C(s?{x9J +@`{w-9S-Ze$ [#k[K‡xu%oD:0an-:4mxib[;͡n RC#=M~a>L~٤uþ/dgTC`x5גrz"aw{{мle5 +fE Bq7y3M*;.b]/\cW']GZ5Ah6*/a0|m s`[Lm+{C‹dO jB`~&tSOCMj7cmJI z Ҵ68/c Ԍ>H!/|0{~jW[atB_b kWܺ:0>H;W0v~2ЗkvEA9F&ޓ A(b =]Pvߣ'َOC(odBBZ.be, 6BrW,W`p`rKTJŀ$0A LvL3Jl8jݣXiXU^, SDLZhQ1qCE[2:If`@!&vR; fS#F Ffky25KGxд4EZZ!MhoAsp7e$ФGpPYB|p87yޡx|N_? x8^x\kaW|EbIH!L.~noH\ijxĺ;rłH9yGEaĩf]5|P3?| L vF&HJ((dC->+Q$]C +t6VTZ47;8kQ^}b.jd + O FuB*g +Hlx{ \)n PdF_OVLgsu Qٶg4<`Z-`kW]тxh`ƉR5 skd3rdDJՅz@}@.WZYf%E7 yx07[>r9`4[WE(Yaxݹ9`q[1􉋘8<'JMxX?xvyX^ +BZmJN죐||FNW#B,bjd#F*uU2lv#d\#dd #ddBF +2x{\ |B﷓y0bbF 3aF)f|ČONQL>9lb~^a=11>`vTS)b3 +l5acTZ&`EaDa&wl? UŸ;f5=p50)K?_'G4 +~u"_n[ߝI?\2YE1Uݘ`ՍgJdI Y}ލ34K7oO7?%G\.#Î}z1Ͳ$ls"SCzmp9If{ʒ穛0vDitId*\ZyIA2i҆Y# y:`ݲZhE hrd8U,']3V=cR ̜FО>D[.b:@'01-ahRgp$?lT8,~_Lnvr#kaZ%&`㮎i%qJcS f3Bg7P,vKlyKĆ6őKsz,vzؒ2!xC Usj>x 'd~xd=L,jdqX^Mihej`k+LØ6 0^Ё]oQ@RRsp'):σJgI0?//BbsN?f*KUWI՜xg J .z9,x<ޣק˕"oU*lfh}_UE5"9pBpB3!b+!b)bz`H1Oۜf+WڠS6wY.y\|kK"G]?pL62vun6_68_qx8UJ.?;!3{09csW;o'Gn'Gj>Ł8A=^ v-WҲCب=k)t#;င+c9PnE|#w3ݝ{-0dM_.avElԬRf}w ^8v7aBXwy+1x$j6 +m +L]ϻzږ S#NP>vyr0Lc!dw\KFغ- P *p@fTvQ22d$l• C;o@T!mad#>=JH|q@5Fs셪|!mY{1aYM鸿ƧY'HGWlJ +M"žGc黯vliQb#BŭE?qizsLX?xjkw[~^i=zK3P*{ح+Zq:vAj07jdq_GE+]&pSV{1зP +U{Ig`rJɗܳac p{<>G2P/ajBq< Ut~d :  4=']z=~@9Is2׎Uwp`A0?76wx76?:^Lz\v``-@*4o:̛澼 v%qswvB8rkv#@9BnsM +~#NM\4?b{`RudMvv|xg{B{-5ewZc(X$ʫ Lf LDŽa~'o놇uJfrdhF:p+_}@s?ܞ#/—pg+B}8iӃHE"y~Ozok=K]bwx5&Qz/WvŃ$-QWi=+d0vY.:fM,{QݻOo1 |U&߻]5I0A A:ѲRUM$#zuS}8ʼnMpi`EU]إS|} jIx?0OL`=T1<# `grt:On'tf(B-&7dW-Ncg!nOhyZ=5CDdF+J+3 vr# < +ZF4<I,4Kt.k|z=гTIQuK1܌YG{: :D9tGde8ꔀvl!O/pȺ\pRwbvLk餶OF`-."ٔ0i//ٞƮ$3H&3Nzp@5?.=1DU!I~zxws9a-A _/'nWShr_O^ôjZ[5B卒5ns +ʔb7CEl-qTnЖZlds0VǷ+0׷ vݯBQ23 \ S36,-iwG!pT_l#ʈ]?* f_°]c\ 1DnGv(!BvD(R]uhYr% B¶G4(Q1#6!?MGeE,/U!]~: ʗ?zY"_Ki]Ŧ A8?6KiK @E:Vԟ.//_NJu^(u&[^룝׾6B Fli+.NS<Jqu-{|\~P਽BHÀ#u +Gċf&SJ&{"(ip.E~vS*ixx2 +r]^r įi']yt*;Sܔp7E?"FZ<{ÆV:8J]Z"ۚvqx[O{~9;ongM%0Quf)[~300୘BYNΉWRw7ߴT5yX>PX\ -tڜF[%fhm_h=ra2SJeFoi.+3>d[tvV:;QKhlFגodw+l +psre+:V459s"S8.y3pnw_$H<}~9{Dfy{|{ZcM6Ić{h|eɹ_ +$sH*8lRWOl+vPU K>ޜޞۭbL _>OJZ-Ѫi%B]NK103OF,at>s\WH{"7OoGs"ž=Q*'/7TK8:` \,G +x> e1X}u :ݔzzܬof%k-vraޅ3Ȣɏ% JѨw߿UBL· ɽ>h8ޝZl8rҴ%bǫ6r9ޭakVjɽz9$~Su4.nڮNJcnJv}p[6Bp-ih>z4@t9GaS04U8H^%xו)|1Smx +/IkC{U۹wgdWW2`YԸwWUˇP "o_D(+YՎ%ZEpi%FILh He"^dn]S"5.>SA^ZCcT_uSAq9Owp;*e(j-io) lMG8|)p#Uh4pI\^;;] *a{Z"88R8d_ -53׀dh>,HBO.hMʨ9 +ecA'evItyR˃q <Θ-hHUKg`P a %~qpFlmp֍c186~y;(ve賩hFGqk//<nݹ={lꕪU mz¦>97^ /%;?/QKf,Z sJH -8$pCIp&[0@OreaK3=O>f:mG8u+̲y,X6*PYC `^^ O7~s9\x D61j•1aH +C +B c@lѭW׵i=I$\4\) +Lkl\BK3$To>%|+@TnUN0_4.Rб&L:̀b%J;=(Fx n\4O 168ܳ< bT)pNCOͻu}=ZQL]% )_:&5"|!zC7X2r-! z9E9A_8Dߞ9W0z y7H`Yj.snBĄDMc)jҧe`H|N|vMRS;"#鼄!qlS*La2:`eJ y}G j 2+<=0- wFQAr0kÕSF(z#gq=M#`aX %P5+-¦emT!I+vqJbTFk{@46 b#~\0wPFbQlEz'}Oɥwy{Qk<8i(_~'0'3~`͡lj[4֍mO't :3mtv{6ݜAHbMh'03Lȴ|!} +䣲ec=F1$|W'W5(Y}dp1HKRŊn7)Yǎy$߼n7rk%e˒dGkuqbOimz9C9( /m@-ahx1bR߷n53 ÂIF8o0i |)&H#:E+-T6 NekC)/) MRfd"9I z:h>X^c[!bj /)3i1KU0_h +7a:,TcjDz\5B"Pe|*[ğ>}yy?7C;py%X0{qgp?DQќ=b]&QE;o'l%G㊆*8-R8hH?IO~ +?߾*B 4}Ӭ]ڛΕzmrF+Cw1U\*owMmF%kxvfzBd|f0HVw?R{%`vd^̕kê YgXU-~a'eR;ʎ))Ƚ.eDj;4īxh3>-lBT̑D` *4 n \% z3 +e S™߃.R-, MJĭM焹͍b3*z9=9,eſJnDЌZUJ&}DC w}J{H +1yrY8Zb^SޤȷC;%ݼ߼+֑ +G qxmΫz=Ve/KDN6u~v;eE.o==& ^ g /c+/ =BbI3,q8I,+(о)bw=Dѓc><:a;1<ܸۊ)7O2cѼ %_u}mD6r207p_ˀgmmX75\%m[.Rs*.#虷}EpgbN ٞwN=1ꎌ$[jQ;>q|XR.C"@4W{hcB0GW+ +ev1-}mtsX.q J{UUstETb]El;ˎ%C>_[3\jU‚6J>QSg* ..Apo#Ύ8*wy@z +w3Uch 14Dt>+ ͕KHw&@ ;UAtMX@4~0o aiwGWR5V6׾8FhS4!@_cwػnʽyK+^,x#-F`ɱ ;7n_PY V5y ۽!NP[ G"vE bDfvj,Cqd9TF.g.(q̎q.<$՝/0wɼG'R5o[UvKܕ iN!P0z&ksMvGs-cΝi& '{O>r(#F^I i:fB7V/B`È'B#--pD]ZBWaI/Bi ^4gK)E +l .RudۅO"Ť<._ыxW~@+^L|eJZ,o\)U*aWQ}Ř3#Ui.FMB-0}/ewxWL*'o4yC0y #yJ~p$Rυ8о b{[ {FM;饖&T7fsUTy;hxt%[ًWeooa,UzqaI+ԷR}usqc2v7n w +k >( 3W[s)aD2r=VNŴli|i*B)~z%w $n}xn⦝O>* "YDZҧpW =*8'xO`K%} 11Y.5gw6􀐸{8Z7rx2dA 1!rR$N R;awPGM1D<007zz =SE+ݦJ@@abaI՛0bvT끩uMAY>t&?=oIBI2!\pjXY4^mDMhJ OA2,1) +*ČQ%[ĠrtÊȹҁf4q ?A4fYAP^H{0ҁ$4w`DB-d}a +nMA fio͊Q굑EMq;scIRه@f> +9V!_OBJ+ : h9g(V3Rr_SD !r:ǩWk#mZ'q]/wJrFrdxUjɐ&-Cf:cqww̅9]Lw2-ò͐ I$Şml0閭MLWr>oۻjmbRZeaAomv/2`O +AW^Y?7^F/l@=}:Y:R"Z=?x섄W—$r9 !9Km^SV~R1'Ө@KY,]fZth%6TVI'ʠGT,מwsA6N;L@/nmxqu_^g Z32BOƺxKԀ&FtyzRJ%8K ̎R3$$ + ࣃ ?S:ӻƄ(@)F$NzC.AOnw\4JX'G#dTM8^SWl  #u,ܜ/i%rƴwg]*CɡZDcV)Rֈ"x\b4/dЍכAZ#?p +\dS!.Y=K (h)P]*ʮ\Lܧt=}ya՟nWn.ܺ*U@_=AǬ(/w[`d,驲)CO} \ No newline at end of file diff --git a/core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php b/core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php index 5acd6fcae1..a36838266e 100644 --- a/core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php +++ b/core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php @@ -116,7 +116,7 @@ public function testDateField() { // Verify that a date is displayed. Since this is a date-only // field, it is expected to display the time as 00:00:00. $expected = format_date($date->getTimestamp(), $new_value, '', DateTimeItemInterface::STORAGE_TIMEZONE); - $expected_iso = format_date($date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', DateTimeItemInterface::STORAGE_TIMEZONE); + $expected_iso = format_date($date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $output = $this->renderTestEntity($id); $expected_markup = ''; $this->assertContains($expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute in %timezone.', [ @@ -282,7 +282,7 @@ public function testDatetimeField() { case 'format_type': // Verify that a date is displayed. $expected = format_date($date->getTimestamp(), $new_value); - $expected_iso = format_date($date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', 'UTC'); + $expected_iso = format_date($date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $output = $this->renderTestEntity($id); $expected_markup = ''; $this->assertContains($expected_markup, $output, SafeMarkup::format('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => $new_value, '%expected' => $expected, '%expected_iso' => $expected_iso])); diff --git a/core/modules/datetime/tests/src/Functional/EntityResource/EntityTest/EntityTestDatetimeTest.php b/core/modules/datetime/tests/src/Functional/EntityResource/EntityTest/EntityTestDatetimeTest.php index ffce48c340..1b02e08ac7 100644 --- a/core/modules/datetime/tests/src/Functional/EntityResource/EntityTest/EntityTestDatetimeTest.php +++ b/core/modules/datetime/tests/src/Functional/EntityResource/EntityTest/EntityTestDatetimeTest.php @@ -5,6 +5,7 @@ use Drupal\Core\Url; use Drupal\entity_test\Entity\EntityTest; use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem; +use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\Tests\rest\Functional\AnonResourceTestTrait; @@ -25,7 +26,7 @@ class EntityTestDatetimeTest extends EntityTestResourceTestBase { * * @var string */ - protected static $dateString = '2017-03-01T20:02:00'; + protected static $dateString = '2017-03-01T20:02:00+00:00'; /** * Datetime test field name. @@ -136,17 +137,17 @@ protected function assertNormalizationEdgeCases($method, Url $url, array $reques $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format); $response = $this->request($method, $url, $request_options); - $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value '{$value}' is invalid for the format 'Y-m-d\\TH:i:s'\n"; + $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value '{$value}' is invalid for the format '" . DateTimeItemInterface::DATETIME_STORAGE_FORMAT . "'\n"; $this->assertResourceErrorResponse(422, $message, $response); // DX: 422 when date format is incorrect. $normalization = $this->getNormalizedPostEntity(); - $value = '2017-13-55T20:02:00'; + $value = '2017-13-55T20:02:00+00:00'; $normalization[static::$fieldName][0]['value'] = $value; $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format); $response = $this->request($method, $url, $request_options); - $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value '{$value}' did not parse properly for the format 'Y-m-d\\TH:i:s'\n{$fieldName}.0.value: This value should be of the correct primitive type.\n"; + $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value '{$value}' did not parse properly for the format '" . DateTimeItemInterface::DATETIME_STORAGE_FORMAT . "'\n{$fieldName}.0.value: This value should be of the correct primitive type.\n"; $this->assertResourceErrorResponse(422, $message, $response); } } diff --git a/core/modules/datetime/tests/src/Functional/Update/DateTimeUpdate8601Test.php b/core/modules/datetime/tests/src/Functional/Update/DateTimeUpdate8601Test.php new file mode 100644 index 0000000000..f46e8732e7 --- /dev/null +++ b/core/modules/datetime/tests/src/Functional/Update/DateTimeUpdate8601Test.php @@ -0,0 +1,105 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../../datetime/tests/fixtures/update/2716891.php.gz', + ]; + } + + /** + * Test that date-only fields do not get modified, but the schema does. + */ + public function testDateonly() { + $schema = \Drupal::keyValue('entity.storage_schema.sql')->getAll(); + $length = $schema['node.field_schema_data.field_dateonly']['node__field_dateonly']['fields']['field_dateonly_value']['length']; + $this->assertEquals(20, $length); + + $value = \Drupal::database()->query('SELECT field_dateonly_value FROM {node__field_dateonly} WHERE entity_id=:nid AND revision_id=:vid', [ + ':nid' => 1, + ':vid' => 1, + ])->fetchField(); + $this->assertEquals('2018-02-14', $value); + + $value = \Drupal::database()->query('SELECT field_dateonly_value FROM {node_revision__field_dateonly} WHERE entity_id=:nid AND revision_id=:vid', [ + ':nid' => 1, + ':vid' => 1, + ])->fetchField(); + $this->assertEquals('2018-02-14', $value); + + $this->runUpdates(); + + $schema = \Drupal::keyValue('entity.storage_schema.sql')->getAll(); + $length = $schema['node.field_schema_data.field_dateonly']['node__field_dateonly']['fields']['field_dateonly_value']['length']; + $this->assertEquals(25, $length); + + $value = \Drupal::database()->query('SELECT field_dateonly_value FROM {node__field_dateonly} WHERE entity_id=:nid AND revision_id=:vid', [ + ':nid' => 1, + ':vid' => 1, + ])->fetchField(); + $this->assertEquals('2018-02-14', $value); + + $value = \Drupal::database()->query('SELECT field_dateonly_value FROM {node_revision__field_dateonly} WHERE entity_id=:nid AND revision_id=:vid', [ + ':nid' => 1, + ':vid' => 1, + ])->fetchField(); + $this->assertEquals('2018-02-14', $value); + } + + /** + * Test that datetime fields and schema get modified. + */ + public function testDatetime() { + $schema = \Drupal::keyValue('entity.storage_schema.sql')->getAll(); + $length = $schema['node.field_schema_data.field_datetime']['node__field_datetime']['fields']['field_datetime_value']['length']; + $this->assertEquals(20, $length); + + $value = \Drupal::database()->query('SELECT field_datetime_value FROM {node__field_datetime} WHERE entity_id=:nid AND revision_id=:vid', [ + ':nid' => 1, + ':vid' => 1, + ])->fetchField(); + $this->assertEquals('2018-02-01T06:02:03', $value); + + $value = \Drupal::database()->query('SELECT field_datetime_value FROM {node_revision__field_datetime} WHERE entity_id=:nid AND revision_id=:vid', [ + ':nid' => 1, + ':vid' => 1, + ])->fetchField(); + $this->assertEquals('2018-02-01T06:02:03', $value); + + $this->runUpdates(); + + $schema = \Drupal::keyValue('entity.storage_schema.sql')->getAll(); + $length = $schema['node.field_schema_data.field_datetime']['node__field_datetime']['fields']['field_datetime_value']['length']; + $this->assertEquals(25, $length); + + $value = \Drupal::database()->query('SELECT field_datetime_value FROM {node__field_datetime} WHERE entity_id=:nid AND revision_id=:vid', [ + ':nid' => 1, + ':vid' => 1, + ])->fetchField(); + $this->assertEquals('2018-02-01T06:02:03+00:00', $value); + + $value = \Drupal::database()->query('SELECT field_datetime_value FROM {node_revision__field_datetime} WHERE entity_id=:nid AND revision_id=:vid', [ + ':nid' => 1, + ':vid' => 1, + ])->fetchField(); + $this->assertEquals('2018-02-01T06:02:03+00:00', $value); + } + +} diff --git a/core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php b/core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php index 75f892a254..dc145b12b7 100644 --- a/core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php +++ b/core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php @@ -69,7 +69,7 @@ public function testDateTime() { // Verify entity creation. $entity = EntityTest::create(); - $value = '2014-01-01T20:00:00'; + $value = '2014-01-01T20:00:00+00:00'; $entity->field_datetime = $value; $entity->name->value = $this->randomMachineName(); $this->entityValidateAndSave($entity); @@ -84,7 +84,7 @@ public function testDateTime() { $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName()); // Verify changing the date value. - $new_value = '2016-11-04T00:21:00'; + $new_value = '2016-11-04T00:21:00+00:00'; $entity->field_datetime->value = $new_value; $this->assertEqual($entity->field_datetime->value, $new_value); $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName()); @@ -164,7 +164,7 @@ public function testSetValue() { // Test DateTimeItem::setValue() using string. $entity = EntityTest::create(); - $value = '2014-01-01T20:00:00'; + $value = '2014-01-01T20:00:00+00:00'; $entity->get('field_datetime')->set(0, $value); $this->entityValidateAndSave($entity); // Load the entity and ensure the field was saved correctly. @@ -175,7 +175,7 @@ public function testSetValue() { // Test DateTimeItem::setValue() using property array. $entity = EntityTest::create(); - $value = '2014-01-01T20:00:00'; + $value = '2014-01-01T20:00:00+00:00'; $entity->set('field_datetime', $value); $this->entityValidateAndSave($entity); // Load the entity and ensure the field was saved correctly. @@ -220,7 +220,7 @@ public function testSetValueProperty() { $this->fieldStorage->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATETIME); $this->fieldStorage->save(); $entity = EntityTest::create(); - $value = '2014-01-01T20:00:00'; + $value = '2014-01-01T20:00:00+00:00'; $entity->set('field_datetime', $value); $this->entityValidateAndSave($entity); @@ -269,10 +269,10 @@ public function datetimeValidationProvider() { return [ // Valid ISO 8601 dates, but unsupported by DateTimeItem. ['2014-01-01T20:00:00Z'], - ['2014-01-01T20:00:00+04:00'], ['2014-01-01T20:00:00+0400'], ['2014-01-01T20:00:00+04'], ['2014-01-01T20:00:00.123'], + ['2014-01-01T20:00:00'], ['2014-01-01T200000'], ['2014-01-01T2000'], ['2014-01-01T20'], diff --git a/core/modules/datetime/tests/src/Kernel/Views/FilterDateTimeTest.php b/core/modules/datetime/tests/src/Kernel/Views/FilterDateTimeTest.php index 7cb0fa040a..17cf74be37 100644 --- a/core/modules/datetime/tests/src/Kernel/Views/FilterDateTimeTest.php +++ b/core/modules/datetime/tests/src/Kernel/Views/FilterDateTimeTest.php @@ -46,9 +46,9 @@ protected function setUp($import_test_views = TRUE) { // Add some basic test nodes. $dates = [ - '2000-10-10T00:01:30', - '2001-10-10T12:12:12', - '2002-10-10T14:14:14', + '2000-10-10T00:01:30+00:00', + '2001-10-10T12:12:12+00:00', + '2002-10-10T14:14:14+00:00', // The date storage timezone is used (this mimics the steps taken in the // widget: \Drupal\datetime\Plugin\Field\FieldWidget::messageFormValues(). \Drupal::service('date.formatter')->format(static::$date, 'custom', DateTimeItemInterface::DATETIME_STORAGE_FORMAT, DateTimeItemInterface::STORAGE_TIMEZONE), @@ -187,7 +187,7 @@ protected function _testExact() { $view->filter[$field]->value['max'] = ''; // Use the date from node 3. Use the site timezone (mimics a value entered // through the UI). - $view->filter[$field]->value['value'] = \Drupal::service('date.formatter')->format(static::$date, 'custom', DateTimeItemInterface::DATETIME_STORAGE_FORMAT, static::$timezone); + $view->filter[$field]->value['value'] = \Drupal::service('date.formatter')->format(static::$date, 'custom', 'Y-m-d\TH:i:s', static::$timezone); $view->setDisplay('default'); $this->executeView($view); $expected_result = [ diff --git a/core/modules/datetime_range/datetime_range.install b/core/modules/datetime_range/datetime_range.install new file mode 100644 index 0000000000..1a623716fb --- /dev/null +++ b/core/modules/datetime_range/datetime_range.install @@ -0,0 +1,108 @@ +useCaches(FALSE); + $change_list = []; + + foreach ($entity_manager->getDefinitions() as $entity_type_id => $entity_type) { + if ($entity_manager->getStorage($entity_type_id) instanceof \Drupal\Core\Entity\Schema\DynamicallyFieldableEntityStorageSchemaInterface) { + $field_changes = []; + + $storage_definitions = $entity_manager->getFieldStorageDefinitions($entity_type_id); + $original_storage_definitions = $entity_manager->getLastInstalledFieldStorageDefinitions($entity_type_id); + + // Detect updated field storage definitions. + foreach (array_intersect_key($storage_definitions, $original_storage_definitions) as $field_name => $storage_definition) { + if ($storage_definition->getType() === 'daterange') { + if ($entity_manager->getStorage($entity_type_id)->requiresFieldStorageSchemaChanges($storage_definition, $original_storage_definitions[$field_name])) { + $field_changes[$field_name] = TRUE; + } + } + } + + if ($field_changes) { + $change_list[$entity_type_id] = [ + 'field_storage_definitions' => $field_changes, + 'base_table' => $entity_type->getBaseTable(), + 'revision_table' => $entity_type->getRevisionTable(), + ]; + } + } + } + + $field_spec = [ + 'description' => 'The start date value.', + 'type' => 'varchar', + 'length' => 25, + ]; + + $end_field_spec = [ + 'description' => 'The end date value.', + 'type' => 'varchar', + 'length' => 25, + ]; + + $keys_new = [ + 'value' => ['value'], + ]; + + $end_keys_new = [ + 'end_value' => ['end_value'], + ]; + + $schema = \Drupal::database()->schema(); + + foreach ($change_list as $entity_type_id => $changes) { + foreach (array_keys($changes['field_storage_definitions']) as $field_name) { + $value_field_name = $field_name . '_value'; + $end_value_field_name = $field_name . 'end_value'; + + $base_table = $changes['base_table'] . '__' . $field_name; + $schema->dropIndex($base_table, 'value'); + $schema->changeField($base_table, $value_field_name, $value_field_name, $field_spec, $keys_new); + $schema->dropIndex($base_table, 'end_value'); + $schema->changeField($base_table, $end_value_field_name, $end_value_field_name, $end_field_spec, $end_keys_new); + + \Drupal::database() + ->update($base_table) + ->expression($value_field_name, "CONCAT({$value_field_name}, :offset)", [ + ':offset' => '+00:00', + ]) + ->expression($end_value_field_name, "CONCAT({$end_value_field_name}, :offset)", [ + ':offset' => '+00:00', + ]) + ->execute(); + + if ($changes['revision_table']) { + $revision_table = $changes['revision_table'] . '__' . $field_name; + $schema->dropIndex($revision_table, 'value'); + $schema->changeField($revision_table, $value_field_name, $value_field_name, $field_spec, $keys_new); + $schema->dropIndex($revision_table, 'end_value'); + $schema->changeField($revision_table, $end_value_field_name, $end_value_field_name, $end_field_spec, $end_keys_new); + + $results = \Drupal::database()->query('SELECT * FROM ' . $revision_table)->fetchAll(); + foreach ($results as &$result) { + \Drupal::database() + ->update($revision_table) + ->expression($value_field_name, "CONCAT({$value_field_name}, :offset)", [ + ':offset' => '+00:00', + ]) + ->expression($end_value_field_name, "CONCAT({$end_value_field_name}, :offset)", [ + ':offset' => '+00:00', + ]) + ->execute(); + } + } + } + } +} diff --git a/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php b/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php index bd83b980e7..44ec455f7f 100644 --- a/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php +++ b/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php @@ -130,10 +130,10 @@ public function testDateRangeField() { ->save(); $start_expected = $this->dateFormatter->format($start_date->getTimestamp(), 'long', '', DateTimeItemInterface::STORAGE_TIMEZONE); - $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', DateTimeItemInterface::STORAGE_TIMEZONE); + $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $start_expected_markup = ''; $end_expected = $this->dateFormatter->format($end_date->getTimestamp(), 'long', '', DateTimeItemInterface::STORAGE_TIMEZONE); - $end_expected_iso = $this->dateFormatter->format($end_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', DateTimeItemInterface::STORAGE_TIMEZONE); + $end_expected_iso = $this->dateFormatter->format($end_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $end_expected_markup = ''; $output = $this->renderTestEntity($id); $this->assertContains($start_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute in %timezone.', [ @@ -228,7 +228,7 @@ public function testDateRangeField() { ->save(); $start_expected = $this->dateFormatter->format($start_date->getTimestamp(), 'long', '', DateTimeItemInterface::STORAGE_TIMEZONE); - $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', DateTimeItemInterface::STORAGE_TIMEZONE); + $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $start_expected_markup = ''; $output = $this->renderTestEntity($id); $this->assertContains($start_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute in %timezone.', [ @@ -332,10 +332,10 @@ public function testDatetimeRangeField() { ->save(); $start_expected = $this->dateFormatter->format($start_date->getTimestamp(), 'long'); - $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', 'UTC'); + $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $start_expected_markup = ''; $end_expected = $this->dateFormatter->format($end_date->getTimestamp(), 'long'); - $end_expected_iso = $this->dateFormatter->format($end_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', 'UTC'); + $end_expected_iso = $this->dateFormatter->format($end_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $end_expected_markup = ''; $output = $this->renderTestEntity($id); $this->assertContains($start_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $start_expected, '%expected_iso' => $start_expected_iso])); @@ -413,7 +413,7 @@ public function testDatetimeRangeField() { ->save(); $start_expected = $this->dateFormatter->format($start_date->getTimestamp(), 'long'); - $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', 'UTC'); + $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $start_expected_markup = ''; $output = $this->renderTestEntity($id); $this->assertContains($start_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $start_expected, '%expected_iso' => $start_expected_iso])); @@ -500,10 +500,10 @@ public function testAlldayRangeField() { ->save(); $start_expected = $this->dateFormatter->format($start_date->getTimestamp(), 'long'); - $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', 'UTC'); + $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $start_expected_markup = ''; $end_expected = $this->dateFormatter->format($end_date->getTimestamp(), 'long'); - $end_expected_iso = $this->dateFormatter->format($end_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', 'UTC'); + $end_expected_iso = $this->dateFormatter->format($end_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $end_expected_markup = ''; $output = $this->renderTestEntity($id); $this->assertContains($start_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $start_expected, '%expected_iso' => $start_expected_iso])); @@ -580,10 +580,10 @@ public function testAlldayRangeField() { ->save(); $start_expected = $this->dateFormatter->format($start_date->getTimestamp(), 'long'); - $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', 'UTC'); + $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $start_expected_markup = ''; $end_expected = $this->dateFormatter->format($end_date->getTimestamp(), 'long'); - $end_expected_iso = $this->dateFormatter->format($end_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s\Z', 'UTC'); + $end_expected_iso = $this->dateFormatter->format($end_date->getTimestamp(), 'custom', 'Y-m-d\TH:i:s+00:00', DateTimeItemInterface::STORAGE_TIMEZONE); $end_expected_markup = ''; $output = $this->renderTestEntity($id); $this->assertContains($start_expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $start_expected, '%expected_iso' => $start_expected_iso])); diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/FieldBlockTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/FieldBlockTest.php index 4f086d6a96..d4e4efc573 100644 --- a/core/modules/layout_builder/tests/src/FunctionalJavascript/FieldBlockTest.php +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/FieldBlockTest.php @@ -41,7 +41,7 @@ protected function setUp() { 'administer blocks', 'access administration pages', ]); - $user->field_date = '1978-11-19T05:00:00'; + $user->field_date = '1978-11-19T05:00:00+00:00'; $user->save(); $this->drupalLogin($user); } diff --git a/core/modules/rdf/tests/src/Kernel/Field/DateTimeFieldRdfaTest.php b/core/modules/rdf/tests/src/Kernel/Field/DateTimeFieldRdfaTest.php index fc78691b96..eb5f934150 100644 --- a/core/modules/rdf/tests/src/Kernel/Field/DateTimeFieldRdfaTest.php +++ b/core/modules/rdf/tests/src/Kernel/Field/DateTimeFieldRdfaTest.php @@ -21,7 +21,7 @@ class DateTimeFieldRdfaTest extends FieldRdfaTestBase { * * @var string */ - protected $testValue = '2014-01-28T06:01:01'; + protected $testValue = '2014-01-28T06:01:01+00:00'; /** * {@inheritdoc} @@ -48,7 +48,7 @@ protected function setUp() { * Tests the default formatter. */ public function testDefaultFormatter() { - $this->assertFormatterRdfa(['type' => 'datetime_default'], 'http://schema.org/dateCreated', ['value' => $this->testValue . 'Z', 'type' => 'literal', 'datatype' => 'http://www.w3.org/2001/XMLSchema#dateTime']); + $this->assertFormatterRdfa(['type' => 'datetime_default'], 'http://schema.org/dateCreated', ['value' => $this->testValue, 'type' => 'literal', 'datatype' => 'http://www.w3.org/2001/XMLSchema#dateTime']); } }