diff --git a/core/lib/Drupal/Core/Entity/ContentEntityType.php b/core/lib/Drupal/Core/Entity/ContentEntityType.php index 6d8d619..6103a56 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityType.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityType.php @@ -8,6 +8,13 @@ class ContentEntityType extends EntityType implements ContentEntityTypeInterface { /** + * An array of entity revision metadata keys. + * + * @var array + */ + protected $revision_metadata_keys = []; + + /** * {@inheritdoc} */ public function __construct($definition) { @@ -41,4 +48,44 @@ protected function checkStorageClass($class) { } } + /** + * {@inheritdoc} + */ + public function getRevisionMetadataKeys($include_backwards_compatibility_field_names = TRUE) { + // Provide backwards compatibility in case the revision metadata keys are + // not defined in the entity annotation. + if (!$this->revision_metadata_keys && $include_backwards_compatibility_field_names) { + $base_fields = \Drupal::service('entity_field.manager')->getBaseFieldDefinitions($this->id()); + if ((isset($base_fields['revision_uid']) && $revision_user = 'revision_uid') || (isset($base_fields['revision_user']) && $revision_user = 'revision_user')) { + @trigger_error('The revision_user revision metadata key is not set.', E_USER_DEPRECATED); + $this->revision_metadata_keys['revision_user'] = $revision_user; + } + if ((isset($base_fields['revision_timestamp']) && $revision_timestamp = 'revision_timestamp') || (isset($base_fields['revision_created'])) && $revision_timestamp = 'revision_created') { + @trigger_error('The revision_created revision metadata key is not set.', E_USER_DEPRECATED); + $this->revision_metadata_keys['revision_created'] = $revision_timestamp; + } + if ((isset($base_fields['revision_log']) && $revision_log = 'revision_log') || (isset($base_fields['revision_log_message']) && $revision_log = 'revision_log_message')) { + @trigger_error('The revision_log_message revision metadata key is not set.', E_USER_DEPRECATED); + $this->revision_metadata_keys['revision_log_message'] = $revision_log; + } + } + return $this->revision_metadata_keys; + } + + /** + * {@inheritdoc} + */ + public function getRevisionMetadataKey($key) { + $keys = $this->getRevisionMetadataKeys(); + return isset($keys[$key]) ? $keys[$key] : FALSE; + } + + /** + * {@inheritdoc} + */ + public function hasRevisionMetadataKey($key) { + $keys = $this->getRevisionMetadataKeys(); + return isset($keys[$key]); + } + } diff --git a/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php b/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php index f9ef160..4c9e890 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php @@ -6,4 +6,50 @@ * Provides an interface for a content entity type and its metadata. */ interface ContentEntityTypeInterface extends EntityTypeInterface { + + /** + * Gets an array of entity revision metadata keys. + * + * @param bool $include_backwards_compatibility_field_names + * (optional and deprecated) Whether to provide the revision keys on a + * best-effort basis by looking at the base fields defined by the entity + * type. Note that this parameter will be removed in Drupal 9.0.0. Defaults + * to TRUE. + * + * @return array + * An array describing how the Field API can extract revision metadata + * information of this entity type: + * - revision_log_message: The name of the property that contains description + * of the changes that were made in the current revision. + * - revision_user: The name of the property that contains the user ID of + * the author of the current revision. + * - revision_created: The name of the property that contains the timestamp + * of the current revision. + */ + public function getRevisionMetadataKeys($include_backwards_compatibility_field_names = TRUE); + + /** + * Gets a specific entity revision metadata key. + * + * @param string $key + * The name of the entity revision metadata key to return. + * + * @return string|bool + * The entity revision metadata key, or FALSE if it does not exist. + * + * @see self::getRevisionMetadataKeys() + */ + public function getRevisionMetadataKey($key); + + /** + * Indicates if a given entity revision metadata key exists. + * + * @param string $key + * The name of the entity revision metadata key to check. + * + * @return bool + * TRUE if a given entity revision metadata key exists, FALSE otherwise. + */ + public function hasRevisionMetadataKey($key); + } diff --git a/core/lib/Drupal/Core/Entity/RevisionLogEntityTrait.php b/core/lib/Drupal/Core/Entity/RevisionLogEntityTrait.php index 7392858..f935a8b 100644 --- a/core/lib/Drupal/Core/Entity/RevisionLogEntityTrait.php +++ b/core/lib/Drupal/Core/Entity/RevisionLogEntityTrait.php @@ -25,18 +25,18 @@ * @see \Drupal\Core\Entity\FieldableEntityInterface::baseFieldDefinitions() */ public static function revisionLogBaseFieldDefinitions(EntityTypeInterface $entity_type) { - $fields['revision_created'] = BaseFieldDefinition::create('created') + $fields[static::getRevisionMetadataKey($entity_type, 'revision_created')] = BaseFieldDefinition::create('created') ->setLabel(t('Revision create time')) ->setDescription(t('The time that the current revision was created.')) ->setRevisionable(TRUE); - $fields['revision_user'] = BaseFieldDefinition::create('entity_reference') + $fields[static::getRevisionMetadataKey($entity_type, 'revision_user')] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('Revision user')) ->setDescription(t('The user ID of the author of the current revision.')) ->setSetting('target_type', 'user') ->setRevisionable(TRUE); - $fields['revision_log_message'] = BaseFieldDefinition::create('string_long') + $fields[static::getRevisionMetadataKey($entity_type, 'revision_log_message')] = BaseFieldDefinition::create('string_long') ->setLabel(t('Revision log message')) ->setDescription(t('Briefly describe the changes you have made.')) ->setRevisionable(TRUE) @@ -56,14 +56,14 @@ public static function revisionLogBaseFieldDefinitions(EntityTypeInterface $enti * Implements \Drupal\Core\Entity\RevisionLogInterface::getRevisionCreationTime(). */ public function getRevisionCreationTime() { - return $this->revision_created->value; + return $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_created')}->value; } /** * Implements \Drupal\Core\Entity\RevisionLogInterface::setRevisionCreationTime(). */ public function setRevisionCreationTime($timestamp) { - $this->revision_created->value = $timestamp; + $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_created')}->value = $timestamp; return $this; } @@ -71,14 +71,14 @@ public function setRevisionCreationTime($timestamp) { * Implements \Drupal\Core\Entity\RevisionLogInterface::getRevisionUser(). */ public function getRevisionUser() { - return $this->revision_user->entity; + return $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_user')}->entity; } /** * Implements \Drupal\Core\Entity\RevisionLogInterface::setRevisionUser(). */ public function setRevisionUser(UserInterface $account) { - $this->revision_user->entity = $account; + $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_user')}->entity = $account; return $this; } @@ -86,14 +86,14 @@ public function setRevisionUser(UserInterface $account) { * Implements \Drupal\Core\Entity\RevisionLogInterface::getRevisionUserId(). */ public function getRevisionUserId() { - return $this->revision_user->target_id; + return $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_user')}->target_id; } /** * Implements \Drupal\Core\Entity\RevisionLogInterface::setRevisionUserId(). */ public function setRevisionUserId($user_id) { - $this->revision_user->target_id = $user_id; + $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_user')}->target_id = $user_id; return $this; } @@ -101,15 +101,41 @@ public function setRevisionUserId($user_id) { * Implements \Drupal\Core\Entity\RevisionLogInterface::getRevisionLogMessage(). */ public function getRevisionLogMessage() { - return $this->revision_log_message->value; + return $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_log_message')}->value; } /** * Implements \Drupal\Core\Entity\RevisionLogInterface::setRevisionLogMessage(). */ public function setRevisionLogMessage($revision_log_message) { - $this->revision_log_message->value = $revision_log_message; + $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_log_message')}->value = $revision_log_message; return $this; } + /** + * Gets the name of a revision metadata field. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type + * A content entity type definition. + * @param string $key + * The revision metadata key to get, must be one of 'revision_created', + * 'revision_user' or 'revision_log_message'. + * + * @return string + * The name of the field for the specified $key. + */ + protected static function getRevisionMetadataKey(EntityTypeInterface $entity_type, $key) { + // We need to prevent ContentEntityType::getRevisionMetadataKey() from + // providing fallback as that requires fetching the entity type's field + // definition leading to an infinite recursion. + /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */ + $revision_metadata_keys = $entity_type->getRevisionMetadataKeys(FALSE) + [ + 'revision_created' => 'revision_created', + 'revision_user' => 'revision_user', + 'revision_log_message' => 'revision_log_message', + ]; + + return $revision_metadata_keys[$key]; + } + } diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php index 8031830..5c03b65 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php @@ -294,17 +294,11 @@ public function getTableMapping(array $storage_definitions = NULL) { // Make sure the key fields come first in the list of fields. $all_fields = array_merge($key_fields, array_diff($all_fields, $key_fields)); - // Nodes have all three of these fields, while custom blocks only have - // log. - // @todo Provide automatic definitions for revision metadata fields in - // https://www.drupal.org/node/2248983. - $revision_metadata_fields = array_intersect(array( - 'revision_timestamp', - 'revision_uid', - 'revision_log', - ), $all_fields); - + // If the entity is revisionable, gather the fields that need to be put + // in the revision table. $revisionable = $this->entityType->isRevisionable(); + $revision_metadata_fields = $revisionable ? array_values($this->entityType->getRevisionMetadataKeys()) : []; + $translatable = $this->entityType->isTranslatable(); if (!$revisionable && !$translatable) { // The base layout stores all the base field values in the base table. diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php index 51ae6f6..7c06ed8 100644 --- a/core/modules/block_content/src/Entity/BlockContent.php +++ b/core/modules/block_content/src/Entity/BlockContent.php @@ -51,6 +51,11 @@ * "langcode" = "langcode", * "uuid" = "uuid" * }, + * revision_metadata_keys = { + * "revision_user" = "revision_user", + * "revision_created" = "revision_created", + * "revision_log_message" = "revision_log" + * }, * bundle_entity_type = "block_content_type", * field_ui_base_route = "entity.block_content_type.edit_form", * render_cache = FALSE, diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php index 68afc83..d66904b 100644 --- a/core/modules/node/src/Entity/Node.php +++ b/core/modules/node/src/Entity/Node.php @@ -60,6 +60,11 @@ * "published" = "status", * "uid" = "uid", * }, + * revision_metadata_keys = { + * "revision_user" = "revision_uid", + * "revision_created" = "revision_timestamp", + * "revision_log_message" = "revision_log" + * }, * bundle_entity_type = "node_type", * field_ui_base_route = "entity.node_type.edit_form", * common_reference_target = TRUE, diff --git a/core/modules/system/src/Tests/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php b/core/modules/system/src/Tests/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php new file mode 100644 index 0000000..457ced8 --- /dev/null +++ b/core/modules/system/src/Tests/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php @@ -0,0 +1,83 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php', + __DIR__ . '/../../../../tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php', + ]; + } + + /** + * Tests that the revision metadata fields are moved correctly. + */ + public function testSystemUpdate3000() { + $this->runUpdates(); + + foreach (['entity_test_revlog', 'entity_test_mul_revlog'] as $entity_type_id) { + /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */ + $storage = \Drupal::entityTypeManager()->getStorage($entity_type_id); + /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */ + $entity_type = $storage->getEntityType(); + $revision_metadata_field_names = $entity_type->getRevisionMetadataKeys(); + + $database_schema = \Drupal::database()->schema(); + + // Test that the revision metadata fields are present only in the + // revision table. + foreach ($revision_metadata_field_names as $revision_metadata_field_name) { + if ($entity_type->isTranslatable()) { + $this->assertFalse($database_schema->fieldExists($entity_type->getDataTable(), $revision_metadata_field_name)); + $this->assertFalse($database_schema->fieldExists($entity_type->getRevisionDataTable(), $revision_metadata_field_name)); + } + else { + $this->assertFalse($database_schema->fieldExists($entity_type->getBaseTable(), $revision_metadata_field_name)); + } + $this->assertTrue($database_schema->fieldExists($entity_type->getRevisionTable(), $revision_metadata_field_name)); + } + + // Test that the revision metadata values have been transferred correctly + // and that the moved fields are accessible. + /** @var \Drupal\Core\Entity\RevisionLogInterface $entity_rev_first */ + $entity_rev_first = $storage->loadRevision(1); + $this->assertEqual($entity_rev_first->getRevisionUserId(), '1'); + $this->assertEqual($entity_rev_first->getRevisionLogMessage(), 'first revision'); + $this->assertEqual($entity_rev_first->getRevisionCreationTime(), '1476268517'); + + /** @var \Drupal\Core\Entity\RevisionLogInterface $entity_rev_second */ + $entity_rev_second = $storage->loadRevision(2); + $this->assertEqual($entity_rev_second->getRevisionUserId(), '1'); + $this->assertEqual($entity_rev_second->getRevisionLogMessage(), 'second revision'); + $this->assertEqual($entity_rev_second->getRevisionCreationTime(), '1476268518'); + + + // Test that the views using revision metadata fields are updated + // properly. + $view = View::load($entity_type_id . '_for_2248983'); + $displays = $view->get('display'); + foreach ($displays as $display => $display_data) { + foreach ($display_data['display_options']['fields'] as $property_data) { + if (in_array($property_data['field'], $revision_metadata_field_names)) { + $this->assertEqual($property_data['table'], $entity_type->getRevisionTable()); + } + } + } + } + } + +} diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 6dc2663..c6b98ae 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -12,6 +12,9 @@ use Drupal\Core\Path\AliasStorage; use Drupal\Core\Url; use Drupal\Core\Database\Database; +use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\DrupalKernel; use Drupal\Core\Site\Settings; use Drupal\Core\StreamWrapper\PrivateStream; @@ -1794,3 +1797,144 @@ function system_update_8203() { ->set('logging', 1) ->save(TRUE); } + +/** + * @addtogroup updates-8.3.0 + * @{ + */ + +/** + * Move revision metadata fields to the revision table. + */ +function system_update_8300(&$sandbox) { + // Due to the fields from RevisionLogEntityTrait not being explicitly + // mentioned in the storage they might have been installed wrongly in the base + // table for revisionable untranslatable entities and in the data and revision + // data tables for revisionable and translatable entities. + $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager(); + $database = \Drupal::database(); + $database_schema = $database->schema(); + + if (!isset($sandbox['progress'])) { + // This must be the first run. Initialize the sandbox. + $sandbox['progress'] = 0; + $sandbox['current'] = 0; + + $definitions = array_filter(\Drupal::entityTypeManager()->getDefinitions(), function (EntityTypeInterface $entity_type) { + return is_subclass_of($entity_type->getClass(), FieldableEntityInterface::class) && ($entity_type instanceof ContentEntityTypeInterface) && $entity_type->isRevisionable(); + }); + $sandbox['entity_type_ids'] = array_keys($definitions); + $sandbox['max'] = count($sandbox['entity_type_ids']); + } + + $current_entity_type_key = $sandbox['current']; + for ($i = $current_entity_type_key; ($i < $current_entity_type_key + 1) && ($i < $sandbox['max']); $i++) { + $entity_type_id = $sandbox['entity_type_ids'][$i]; + /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */ + $entity_type = \Drupal::entityTypeManager()->getDefinition($entity_type_id); + + $base_fields = \Drupal::service('entity_field.manager')->getBaseFieldDefinitions($entity_type_id); + $revision_metadata_fields = $entity_type->getRevisionMetadataKeys(); + $fields_to_update = array_intersect_key($base_fields, array_flip($revision_metadata_fields)); + + if (!empty($fields_to_update)) { + // Initialize the entity table names. + // @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout() + $base_table = $entity_type->getBaseTable() ?: $entity_type_id; + $data_table = $entity_type->getDataTable() ?: $entity_type_id . '_field_data'; + $revision_table = $entity_type->getRevisionTable() ?: $entity_type_id . '_revision'; + $revision_data_table = $entity_type->getRevisionDataTable() ?: $entity_type_id . '_field_revision'; + $revision_field = $entity_type->getKey('revision'); + + // No data needs to be migrated if the entity type is not translatable. + if ($entity_type->isTranslatable()) { + if (!isset($sandbox[$entity_type_id])) { + // This must be the first run for this entity type. Initialize the + // sub-sandbox for it. + + // Calculate the number of revisions to process. + $count = \Drupal::entityQuery($entity_type_id) + ->allRevisions() + ->count() + ->accessCheck(FALSE) + ->execute(); + + $sandbox[$entity_type_id]['current'] = 0; + $sandbox[$entity_type_id]['max'] = $count; + } + // Define the step size. + $steps = 50; + + // Collect the revision IDs to process. + $revisions = \Drupal::entityQuery($entity_type_id) + ->allRevisions() + ->range($sandbox[$entity_type_id]['current'], $sandbox[$entity_type_id]['current'] + $steps) + ->accessCheck(FALSE) + ->execute(); + $revisions = array_keys($revisions); + + foreach ($fields_to_update as $revision_metadata_field_name => $definition) { + // If the revision metadata field is present in the data and the + // revision data table, install its definition again with the updated + // storage code in order for the field to be installed in the + // revision table. Afterwards, copy over the field values and remove + // the field from the data and the revision data tables. + if ($database_schema->fieldExists($data_table, $revision_metadata_field_name) && $database_schema->fieldExists($revision_data_table, $revision_metadata_field_name)) { + // Install the field in the revision table. + if (!isset($sandbox[$entity_type_id]['storage_definition_installed'][$revision_metadata_field_name])) { + $entity_definition_update_manager->installFieldStorageDefinition($revision_metadata_field_name, $entity_type_id, $entity_type->getProvider(), $definition); + $sandbox[$entity_type_id]['storage_definition_installed'][$revision_metadata_field_name] = TRUE; + } + + // Apply the field value from the revision data table to the + // revision table. + foreach ($revisions as $rev_id) { + $field_value = $database->select($revision_data_table, 't') + ->fields('t', [$revision_metadata_field_name]) + ->condition($revision_field, $rev_id) + ->execute() + ->fetchField(); + $database->update($revision_table) + ->condition($revision_field, $rev_id) + ->fields([$revision_metadata_field_name => $field_value]) + ->execute(); + } + } + } + + $sandbox[$entity_type_id]['current'] += count($revisions); + $sandbox[$entity_type_id]['finished'] = $sandbox[$entity_type_id]['current'] == $sandbox[$entity_type_id]['max']; + + if ($sandbox[$entity_type_id]['finished']) { + foreach ($fields_to_update as $revision_metadata_field_name => $definition) { + // Drop the field from the data and revision data tables. + $database_schema->dropField($data_table, $revision_metadata_field_name); + $database_schema->dropField($revision_data_table, $revision_metadata_field_name); + } + $sandbox['current']++; + } + } + else { + foreach ($fields_to_update as $revision_metadata_field_name => $definition) { + if ($database_schema->fieldExists($base_table, $revision_metadata_field_name)) { + // Install the field in the revision table. + $entity_definition_update_manager->installFieldStorageDefinition($revision_metadata_field_name, $entity_type_id, $entity_type->getProvider(), $definition); + // Drop the field from the base table. + $database_schema->dropField($base_table, $revision_metadata_field_name); + } + } + $sandbox['current']++; + } + } + else { + $sandbox['current']++; + } + + } + + $sandbox['#finished'] = $sandbox['current'] == $sandbox['max']; +} + +/** + * @} End of "addtogroup updates-8.3.0". + */ diff --git a/core/modules/system/tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz b/core/modules/system/tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz new file mode 100644 index 0000000..1977264 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz @@ -0,0 +1,517 @@ +RXdrupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php]is⺶޿Jݪ>}(ǃ<=&IIHBn%[28fʭߟ3&takkd?4ofcê|dab/_ld |߿~OK>?SHEI!Z -;-'n'UO9ױ=A᥂R=". N qOVoۦwJ%Kyk8~ȟ߾uqpΌĘ۷he7l+Yɓ~̗yZo?_K`OH5oU֚5Z'r]4[*]75~mWK=e)cçOϗ'>C5[cyF"8RGwt (F0rdoK{d* ȭ!O38:1Uae>]wH&f8Dvn;B $e؛XFCr CumZ-_EfgِڝW|+}0(¤Ob(\jk0IkZ0H[rKƏhVSmYEZ[]~5!!c d]?pcsK2YQQ$:}Nt$?9JrÛ/Ӆ=;qVS`@956E&׉GGug+!}pCDh':-jqp\q@i%OC#kίa)ܞ,(|T_֤| ɖZ,Wu%G@<(4auIXh# +O $ēOBZ$HZr9ӑ/ggu3h{֓[Y0l6QOwjrNvr$,߭xz%r: +9 . 24HSTNkUp%P Gayԣ1Z|Ɣ'#h,fw §H1 + +nhQ֓.;8}H.p>]}=u7 +<(}{fha'NjaX Ŭnbših~Eg[ XIw2fڱ`b^aͅaWM[b *J?Y^wm*nD+ڱ:EzK:K]0uFtH2K!aQсBug$bSY$Y9ht G4%{e/Nid/紮Z~i4%A'&0Flzujm.s맂 >aH Z8 9MdtF[9UfRL  2*C4QS"(" ȲQ9 >-܁q}%LWl:Ȭq#_+yR,4;о\4t<͜sPk9( Pר_<}4!Ga 0@P`eeQ:v&^ţ&]cx +=4[[ XD O68>nVq](KK͎K'aQ7|͝CN'@epu4LLYDE'p$Q..p9X)WJ2 nթ9h^\w88B '46sd)d<_wqG'bP1eH aU q@RgdkSs{Bkʻv}s;7voW*(Os#n挬xՍ2)uʸ_= r 2, aXI$SwˇPރ^B9\_]:/K +}s/>o |e{,bl蠏)]o is4 M{՚640O-4p0ǁtpU\Z: 8r +PMIG<Z-=^?젨GiXh3H~&n>\_wO3mn볦ɛ<,LC/\ +s+i0d? r+>xz7"y}˰~PJB%:WE}AQʖd97;ǢKb QFt1P$VU$rw?ܕNJ(_ٸ"U\;3-ZVNٹ;+͜Fc;9IJG8o'XWuE@fP?Lvwlvٓ wy *mN~ulBI.43F0PlCcF\+P/@A*:nsWQlx]yгS`'[w;:Pa䭗U歇LFp>? }ÍD ! @PV5CEWxPouܻLBмnoߚՀ1Ţ'wo#|pUۈcd |*/I^9$P\@gFgFϧʹ%tY»ΑR2PZzWbW\Z đGgh6?lP. *C +^be(I:WlѻPe^~eFE͎ /SɋK&x]O){<}a{s# @DѿT +FBxT/H0tr_XFxy6lܻ7HF >/FnCAhXm$*F?2ne ȫ,9 $PTGLd= p֪ AuPes[.bػkn~"gJf;f!4y Ơ&&MiaBB>Ra-A4N~"DM怌:,G.ˈD:4jg1o:H;{CpF΋G)k]zJE0`a*Ԩ7%FgT F^2̹i=o"%mML+NuB[:ENk@&,;h/:yM׷#B7xᔯ-ݛX9tB-,2QRe ~"1¹L&ECG.q!MKZyMqf7b.' *?iwOpŏF$ڼ*P)ypX%eB>l[tSWsILV+kN\%uز,˻BB@*J%fLM0tt2FZּ&^FvokDTA6 v#?VSWgIh{BX|~;Xsb~6h_|6SlB\s|u*9vXP^ 퇔?CXr}׏ q2m)@U ,2 T3Lh˸*QK`S~^ /xidʁp⎐+헆/uҕW% V*wGHApG0-΍pOMd9`q[W%'"ښjf  GҦ.*z˭'DAcU-s9_I8_zT(]d3E~IK8θdn #_"3HWE P3 ,r |1}ygZӉ3Rjhd<۷A6pډt8v#vZed oo7Eakl#p Wg6 @ +a:/> BJ~ƵnXJ T+`x +S&,7u E!uMQ T/3޴-f{ҵTwZz/=Mj8IRX.-D?UY +G/N84U #*ր@ %bhNn}nL 4o'Jv͙j̻ g .HRD/1Z?//hhL8TuSm*5Dj TǶBqDKWl=`t +9o9V|5C4;`HH*-^]>a𙚁8)Sc0fBӤ6*KBX+&n T4{^]i_ VSMd2ԍs(vi5&+aB +]Pn 6u;rOS-o{eJߦU{iLs6[;$j"Ux<>>oɗuus Ϝ&" u[vHSB]&36 +"'LNkT{UDŽ[B3輒Y ܙ;kUbvrg &KweۻPy]ն慏_j:іL kbS8 $uoyL,䫉l?B >g9He`C\*r4l.hqTM,n؁Xdʨ2bn9lЮƃڠƇI,Fmϝw[yg1wG1emˍ"Qo}s #]ƅf#e +D3 ^&M^GP?lc?6P݅}[NPw\͘x`J?,/@m_a u5UwG;]Kz}ʱH588~C^.SJT8 wp)<>6.^%]$%b/VM+LW{BRe'qðD(/V`Q]7uCsˋ':ި|ܾގFDOA^辑'Y걒޹euǝѣrM#i-Wa +on_OnqyWM0! Dm`j*RLlAf x +? oك5*nOߚkF FwgE&Ao#-0:iX\gtG(4'X JtKzw@4m:nP/pc> NM>#"V1 ydSQme?e($--+e>c<ݎSg)wۚE +~h󨔧i_T_Q6Ⱥn|qZbj/7#RXr',SO5 zA<-wx+q #J4,eg:A]1Ѭͷf'ńu \[aygq +b9 f0@Ma!GH_nUn)1*s@T^t?;v&=VY ?tX'"7._㪝ohKN w7bHQ\d*' F5 +E4LSqujr,}ȓ˵lI-̧LF탈zd syFhPx]rU#zT ߷ZV䩵lԹUd ր! #ұT]@-}ØɧlYqӟT%H'|]߽j`>szOI*8{gJpX BF5~Grw+#AvtʄVv`ǏG[5 !0*  +'t xho?N:b|׌]v:iK knu5I,r\"|Qr\u! Mv]`@,QYQ'rN,ө;F^0`lVfgo0o7UE a&D iF@7 ׯʴg:-< !7OCPyhT+ 3Ӥ#!aNnSr}1-Yfus3ԑ ȅ;J*7MS b?äYܖtXxJsgв +ܛmLm;#XVcX&;3\E B+6-KMYt2-o3$ %)²X *Iݾ=*껾=yI=.^|fu=>nƱQ,$4Aujw+9d}k0_<[{{Tr"yk'~"6h -P* U?r.>?oLކuetVt1VRܦAeB|@+OES? ^P,>vFRqfS¸r2 Xf}؜/n~Tۓjԍ|j}w~{AX\SLdMNUq ZujZ 5YIx\h78;YDK[}6o憎9%q n-yS,S!&DYplfb#0ħxV>M7iM7+4S(Yw&)u~+gz:^ +sDmhu<\+ˆ + [_!յ1p@ݡlFevp"ucZGkNTblmĆ*@H `Gs*ݐ@ݽgG[H[fVfed# +̹[mkQ6A@KZۖ)ZC٫"dg2c)O=kYz{%r/Kr&^|rOȍtbϹ6t5W - +@vs?taԼ]Vv59PiԘa~%g?=wϱ7p][) +˽3\Đ;R k +4?7%l:Kt}DH+$JYUg!#?)K[sNCfL+')oZÒeCO fN[esBu/WS +h+Kd2˱KGd\i.ɔ + +dBuw\7* %Q +BR,R'h$WL0tnZ/F]ԞкX_vISWGI(ֲbq}LXQxx{nz3GCQn{fI\ica)2|5ZH'B*\4e(qD`Sl>;֟^ /yҾYzn 5ByzYzb߹W1|qv>faS\//A1tS̢|J{ЌCߛ7iخƽlЦ)_K/&&赗Ҷ^uI_:IJi~nF?L%zg^Hu_D,|u 5b-C7|Tch͓z4&dEhUJ*~X{B{SǀFԧ)Tg)3>'ʞr&ǣ7]v!ʶ=x_wPcdQm_7F/E~sbܣl'6"dJoLB[E0gԼx%A1Kӏ^5b2!P%Q:=’>RVlMBdolc&4G 3QB_l;IJے2a x i5!MgTzU^Rd d 1//$FI5'2wh]X]G9%!ɏ99u@:p +y z QG.0?NӤ$OYZU*31 k-uw,OJ*?ʤ h'4{I٤'{ѓLEU؜"bW;.Q}A< бL '@(KY@*Uh"?²<iR2?W;Ӟז$fXKvy# xGy/]e2ڇ)*寣!+Y8ڱ~?g!5ᠸy8g/gHvQ9CXbV12 /@U0m<;D#)$) R}un8cq{߬iv/T&|h$oȫkC;o6p?dɔ-2u cA+"#(1Ή"˨rT-;[[Ըce_oxݤс70\}j'(f+_6ŭ,d{H@ Чso S?yXڹ#̽x`%>l+q4U,}p8' SIh1m?B%4g8Aun2 8~e(CxH E#"BH&`tr,VEgJ%{[/7*6H 奓4g?Opr7J}ԣ*܂2<z + M I"$rvOeI[F"tqaiEv(=)~plj:.;\1K4ڋ+-|_bm>z=U*vpgY޷#А(3 /G*wo hg:t2Jou0! G?,FSOe9v˲{Ѹx7x hKZe~[l ?'>\>-.&S>8Y%GrLYWeEF0d9 DCPFUy^*G:r#oI&ͦ1WfU7#uٿSzŎȺ9yCaû٣1H618j2 jB(!ᰄx$#ke`\;WvJW c2uPc:X\>^k\ +tБ]\-v0#7*+ˣqBϤ~ +A)Bk@$?cs@8M^nj \B@t'T&i ҍ^Ę;1oטERK0ݟOΨ4 V!>5%OPzޯr!['"i2Rnbnaΰ>75BM򡾫#>e#s m# W)#F@%@UsK:j/jCW^z]]Gbmt/du5;6 f/Q{<tBoڐ!8I$l"EfA݁f=f>|nܮ0rĻEkݛF]]Kl+=oR);}gjf5+PI@DK2V@!V6|NI*/juSf&*w#SRZ=݌v{qq#K=г:f3܀26Wih34$̵;gM6LzWNۊ?|ٸ @5X,"U PI(,ȐZ;*P'<.+5_q/;"e@m3[Uu'xܞ+JUy:%3%W<[۬{@s"h1x ,P, |' <Ԛݸ_ƃ=zs|մ $6lygm+ELJJt|a~Zh}d9MdDLZdK4-u}LӪOoB/uNFwɆ$CR{_:jL0.NR#Q .@%3 M1$N¾K]~QZT[ K鍖^AMPZIV{rxE9ωe6<\/@%n=weB-'빥?{9춻(kɐ ]TsϰL,}\KOBB7/Ho[#|L}ɷ|ɷ/h:˚+gT [6 +g[@ ;@iHl#U'sV[c75]:[XFwD/Yݽ;NY^yqS'f%+K=F9؛-L菫h#ߪ ӝ~Kռ:m'jXR1OࢄxwvzeZ6renO +w񺸌8s?h&ڳe}˱&Q f$ HP:G/AexY5)k辏:i[\vBO7@ozÚttM;m"bJe%H”a^?y +Oj^fd[>?eb[a4P9 j^8dᳯwe2pjU<4iD5MfUIk҆Ɠ>3R9mI[IŃ|I +xQ^g?c(@Ú֧FHZZa?* ҄kDinDI7y3h^˞`Kuk(b$b/瘼TMO)ٕ^EQ*J:d!鲡!MGJma͗y3%oƛ@FS%+E +~<4ny>aFH!$hEK;tVĢ(܍>ٝ,91?Ipa-X*kKԁH3ٜ>8:c A*  +@/"AUq# Fjo<].9:lCO:I#49l 9PxtLQE YPf(zo@r"Cvܳg42]J/}e[#6@UǬI3Ae& $ŧ،E6ҫz*K^!\n #= Vݵ+ !9ɱƩ +P$r*#0tDeI.x_ YI.)P-+=N h1c;9z0XvҚn|SAOڼoe|Ѽ`kUz IםbADǒZzaq2_F +i_X8ڍ=ð0%!/\EC4-E@C@" +LGmKU.cV˪;sj6BfjOM<]ݕ)[bo AEFlrgjBᙀOs%ʜY WDjs#}ӌOZ,pt&Dy4ڙ(Ts(Jz硘o7q%^k+M/Zw !DH\U؎mlKHzZ' +ug:6ژZAq{mӋK&ZrbP"q25T&cY^ AB=^ ^^j8ꥁԋKCwKLoYJ.FܼGzP4V65 KԋK\^w?b؜ꥁTUzp -cB0wqYCg{֠Xf=b30T/FT[ۚ|iP$lVz%j۩y1Knrt C(z4t!Δ Ʉ2}5`Em-Lɭ>>Vcc0Py[yT+blc- +ǃ?r)r`--#QEq 7{R<7\{,=DRiRbq8D[WQ/9,:5Z/($\\Ni\ז$ "kM *4q2dx%V5٠B% !Wrܺʥv66z LG̶06S˶ixxSt1T$uG6r %_:wP6t)G6R͐Zaً*ʧ+a9Kg0B!-_%|Dž=l8y~շ] Dv u.jU.KeRvc)ЄQ! 3$i9r@4@$pyAQlٯ7jՑ4.lJJ^R+ZT;۰᮴<ۥ2[ל 11LHAt ( RDy!.9I}\r<_ oBmV%PB"-j oWzmd{gCvgMI5@1u+ A54[*Q]!SUTyYRRh𫆠4C,u4+\> z׺AB^ S~'.cf SS& CUʛ4/N$_ѧbv5Y*5=55/_[> e rk; 5 q=g|TL`"cXցBT,A]֓Upٹ\#YmP5]M]Lvwh zY-bɘ?^zn9>/)F@MjBMR"Cfį GGw\-v +NV LA{|nxgC~ >k*$X:4* +$%mv8m@TJ7! +wC$fxN88\0pѿ9EU&dUB,Ej@S0)O?*\6gJr8OK: \ԗq8ܮ^ߥ.X:|((r@`"<1Y1U DtPᗮeA޵(NIXm*~)Wsl-maѩ>]HC 堈 }ϙxeZ~@tg,}$ + +īAO]Bg_h쵘#1 `x9>[鲋͗8 I&0Kv&N"&83Kљw"$K COPܬ.~ŏh +3CV.@(DG +2tMP=} >e]+ Sͼ2noCoԽrޟfi0ڗ}yu_#aހA$Ht,!~ {F.SUuneVŗQsl]k`Gg}d o?5`"[\L}LjLSy@=S4VJ#%*$.:dqcK%{fof # @1FՓ`1JQRjtӬH|(b Me]hm ܞҘk N`3 V"8=bҗڄyRDkiUՠ7Pub"Y׭(/?n`s_ V;2ҐG3恰&͹lzqc-k +ǝXۜUa*4;n!&+*}غZ6']}aXV͑Ѿ2ՙ6e0RT䯸A0UYPY96luj¥ķH#>^xꜾy( +Z:n +NPZ6G+ /FnvSHoLF,u[l'S O/ӚlΜ@).;yEv0*/K7S8w닓I#WrNz*GDmvG}t%kԍe>:ٟen+) rm=z0GhdO /'ݡҗ/Z)BH5Ǚ )2O;%5EydAܟLoJ|?Y+o$c*X1IQ#ˤvPr&8c KDQѓ"B{GmHQ)g b+] +Z\XhAUo昝֍)$"JPCC`RH!:0!'  +ڧE{WCw|خK{8hxUTv99\S{zj%#/l'QTQq:B^se~u+" %ϩ,̓}'H1 dH@8CEZ׭~gp}/۸䛨݋f6lAė7Nڭg"I_.?ΰ$ ˸f:Np( 8EQE@ eEӤ0/hlp-NczWx VSܬ͒>i6U)ot +jӎ%F$=Q؜8.Kv;ZO1xdPЀI + 4`M% .ƩЀtǜ)6G˛a^!_Z`l;KNIKfn1=W 6+H2'M!Pu"e.s0W-~6Y:Ҳyk^'}hOF[>~I=vs̡fJ1lFI |\j. ?Yn3rJr#.ljD|?1XYI"n9]&1YO8zԠ޻ǿ~ٵ|ӿtl!_dֳ酓g<<%y߾[GDYT:5NGj1-"׾˺B\va%3*'` 2j?Ǘj/rgIG+ +--̋c t c`PjdH6`&:b_*J%Y ƾؘ6:JUYYyO8/d_ J=1U{I~?d~[CNcf復!kTdE 'ӁzcwoOw}bpg_?D9MUH8P䅹ŽVAHfe0] +R{BR^壔Kњym2:nj9={ۍw+M6uk6Z~zv]iSl,1]>;O#oĢK7VŽj]܄?? 1~@GEwL <ڲr%j`SW:?pM;3 ɎLÃU ;w4OۋbF٤)&JJoY?%qo2{WWAz:ݽXtW_}!G\m&m#x1jMޠ$I0' <^}V&);+\"IjW:/ycrP%Ȕ8Mgy]Xp8$IڲMXUVǮ-ɫK;ִvw8Gk~|׻:{eӎz? [32W/ zyaU suD(IjNb`,k!NӖf5oxqNC}XǀP앧4nw Nnivmͪ{i4Ah}JGCXl^׋~p$-n`?O2XdɚcE{6#`պIT@Kn]2u=vw'lh"9KBݢsyًMU+|2ShmΦ[nO_Q:L;۩'Q?I[σ"72.vp 鰾Pud j[hAI)D\k>Ss\7p/n;wSݺmiuC4z4kR,7&r:΁5k2^o]ΚQ䖴~mKΊ]Sv0j]H"L:F' -5 eĺ'Et 4Hh=INJ0mVt 68n&jc/}%| !@sKalBf$%mO0 *-?t!pvU^Y8 Ry5b/j#I`-C <;&N 我=?$ԽGld2`Z2|/2ڄkx ^ڗ^Y j>G}8:]pk3d;\6^:Hy3:khxXToN*?@B Jyk^mSR +豧tv@PD +=fu +dPT*fXڟyg=Ka9U"gQ<$ud1cʼ2D$y1aMپ_}{e7OO~/i퍍û_q\"NȦPf5\Z{r z4ܜf@._ܯ)V +g+f+Q}5]0xt7 4zfH2`Xұ4;$9dCx!A)&BBP~#^Q9ΡQ3I1Oo8O<34\t.xr1@0IPNV*sٸ#7xɈ+0B2!!&TaEvc6qsps.V +$J(w6gע&P`/*x5B鮫]lo$1`| $ϖ p"k(G@:^5U'tT 4,~q17$ e1416RT%U#aVBUNl)џ@7M0 p|q%>V_Ē0Tv284.뱌sgrxn/Ua,$&>_/^ܑ0 l5A}EQl ڞe +`h5%߷ ڟbl\ZnXsA$-7L{a|_7;wc}4u?7;wnM~o7W?zmvЫ:ԯnjNӶ״~ᤵ3l_] {q^xɱqt|H/q*kxATĀjS/)YG[GA^GI<mfjt~kFMot,8лfN{Em~k> ݽ~>q̳oV4vr7{Oq!C%AnlW@ZiMk7cN^fDGE5.PXzfILvDCMeѡu-`>m,ʈhM| ]@J%v7jnSo:mӻnpcW_mUѷ]t~=; +=|MΆiҹ,c +*, *YDyȠdl+ j lTMao!Egae/N>HR vK>r< BU,>@R+PFbyGRvooeCI͢$%E3|&TԴnYg'D+Fo6Nev8:FUdoɧ?t[IJAupSѸtj޾_ڽx4_KQ?C赃e lUr}3kzipY"a2l!Nt9'B̻ (ro.[8d xh**&r=Za‹m*6._ elSۈz)۲%dKMlw"5$h@Z1l<ƴvC C?͈]LUZE/ܓ?y{p} e!F?f_?,"~@Y~E7cW>X,/;#Au'S~Ry!K~kVB{'d*0;8!-E ? 5;Ke ++DvpDػߔ)n:q;טN۵jM7_v7炘ۉ%fg]ҵhU ݪ{]ݷm;4+gױiUx)SƱCeY0lt0!9${3~oQ:6- w{ +vԋ"-l쎲e楙p {a(OF4Wbg֍YM b"钟7*CALCF2EC #" +jX@q` =Yqqp,QBMUN)ϋ*T# ʆhxTp,X˄+%$ȅ:rfJ C_)U1>ψ$K'\ (x!Z\%%5u&tL/ Ȳ's_,De<y(Ƀ6 ݊N֡9jǝ! Bs&F jN6RG  +ylD-:a *-#eľk r@%xSx)UcJ3$|!K1s6=2Y 'V&cT+rx5`FBٙůjE!=]I[&DuH&=_0vK!0PZ>Hj@FM^MK_&$3Ϯ(NnJ^8Y%9lSxA0XJx[J*9ҫR2׾o+zE-W|DFDȔR}ѪVr3FM(s3W\oRk"[*@9Pz- +7/@\&2KW}WŲ,)nY@ 8/T3:OG 6aQ1ƈJ +)Dm3SKkr͢ E~@lNr !MD˜Em*7vQ~`bl4Sy!OlT12nS,D7+kAE$KZ4bNT-B>0\dy/PB)ٖR1|5`Vd̫K)3'tɛۢr.`NNF&Y+n{+Mjg'Ŷ%F!"WM5!T,6D-Ž$)0q?G*ݲ,V RK8rk#aóRKlD-Ga VS55j4[z:zq:z7װ-7ܼ?73I/fQ8pN?MVz.GSh<񫅁-zH6M+dy螾D.}OxM2G7]s_t}Sy|8K-K7y|z !~/}9J>G|0”y ?#`OB#wEyAU^ +Gc %k<v0*Zϋ(H h O pOٕϪn>U(Psٜ܀DY ՂÒr;˳Y7Ĝ)5SbCPUF{8""vԗͮl\ۂK,^VK6yg;5,|hn@&.ˋ3cUb0/L٭`R륅iT[4ߒL_:LCw5wU׷pRcDx95h|jQk(%o[,+k 01[AT2}T+Ti5fgFM ~%Uu5-W!7k8uptu.Et᧯i(9Ѭf\a9؛˩7-խZm +:VJ/<9,< b^m0j2<~'\]T)h֗3Lf +Juy8J>EHSe\vfI_e3=8Ξ{`4:ҸV2Ǒ/-GEPV.7ΌMOUlTMߦ tVsin:MeyFGxDDŽn/07<=dPTF|PNw ++쮴e F%2m `pܦwȀfi^CrxƞMӌO=E6ͨUMP|h*R 4hlhPJcVm=>#TW0 W3~AO#wx\,u\륮6c:F$7b Yh'||x5˖LK-WSm] ".UcUI ^0G˫Y55oɫǗl{ +Owf.-F!{x88HQuoxL=2)?S8v9M)#oG@*ܓM53I}cC*'qSYRaz{j:&EfR^2DHHAP:q1JK7\/bD!|/⻟n~Oo]X} K#%%'3{zGIb{X %&*K~U4..%Mb:%2bZ1--q${u`4Gj~ʕi6&]W`W}ؔΑ 5ԝ\@q&>Pe+꼪p7_.KnQA|T=™}l[YBIFK%*-k4.Z -9a5`UM1S6eupfPynCb*F3ggG3݁f:AQ _ey5wꍔݾFC0B q+.\3|%M7.xW՛zi`&K'}IN#)U ؍ & i"Dd-=ewɽ(כivWٌk Ws]݇NCe߷FU;-^iR 4ͼMӘUO4?a䱩(L4ϛ~@JߠW7@ߋ^BɊ`O??jdvH4]?#(RE-+R7JP+$)ؽÕ?~2~._ӟ7?~z~Dן1˗UhOKF8sHўe{6LF;̄f6l"YDWz!Yr:QrX4<N2 C[&_ɟԜ+޷?cJ%Yay O6\@7b#]U_oTP8(j+Wl3E~j%`ެ+f^=N=YɸOS\/,//}v=_Q-5mܥN疳N'G rnv]5r{#9 aᭌtכZiaRf'{=93a]%t&yLF*?%9ܲƽ꘴l=V!;WO|ldd]j>=yH5N%>ec}Wm @^We֗o=f_{n'i]{C0VXSqXW[Fet/SV- o 3lI.[7BK'KT~z= :vSr*>z|qЍ +d7gt͵)/YFfiF,sGg%ܼ%(gO|F>a8U&\]XkX6ʙX'/Vs6? i,);VZF[:,mfNIeOqmOeEvO6}fpT< Wm}VѦЛ 7]hp_9DэwJg͏ Ƅ|'Ȥw/ŦiNaز&blDP-F&1`nV~ F`Ѱ-c[KsM6a JqQ$zpOpȩ)8X+伻\+%jk-i5ǮqE 8F|[VlinWf囍J\u [1/DG}#SܟH%-`0aVfPP6dC^l7x\Y$6̠sWB<_O% +uz&ibSO;ڷ5:,VZ +Lct^R;Re~K8z3u}iɐm6:qai}ANDn,4=/%y/_._]OYO~x-x=KZ}U~qe$ *f-o?z2{3Dm~\[6C%Z|-m~#(z<{k+W 1>Je8~)YX3SEn;oo ב߼apq`4ܿrwbL>!> ^g#JYIJ$|Z[R#N0adeCۃULg{L}dב̽~eϺV\O6=C!vc'|e;8wC'/C<7\zvw{7}zÛq|" Rg_{vN4},5n^[X2>CzxF=ul7Unl;6؛'#t79SKxݠWJ]m񂽴xIcSdߙiX{7.7~2A'zd_n2OiTL@|8OE/zI^+(!\#xpSf]II\e03Zy9l٣yRJ+.3n 롋QJ:cwӁ7mhh/՝TڹFʪR2~2xd&.:߳^Ȕz>E^跾2ҫJVݥ`[92%dnCj~6*Ѹu:HO2v<>}5ڲ=׾emknW}"5}Q+;ڋS?5W =5t5d7RWJJ3"OLe`u]w}BBFcf.0@ާn@G- B 3 f\tSzR49Ğj{}2qٟ//^wM/_-y w4ё\!3TW=zo=qUef%dlɄ\:-ZˬV谼Ex +ut +u;KUT~g*.˔Ψrt%N2B$el +j$>hq!vmI~m~3 +]}W-jjjfL (l4-WHd 7W7ڀ6,<]|gmǔgQ־-QX᣺)BVdBDYYdwfk|9>5T +DFo?`4-'?|?>˙0ylolvTw0sdCυ1v@ZEs h۴GurW8dk=clt7W'u-9+Ϗ_vX[ϟmv-udQä|xLi'!Rc(]ҼW|b^Zi7OiՋap:׍lHz%osn x2F6G^x-"Oy ^:c{n53>qwF҈zaROW!tU- =odm+Y&&j|01Dqysdrd>ftIH'u}BnLwCuw,^#lda'f')uv퇾܊`mV7;۷}6f3~̊;pjek<с/3Q?tu$od&ӷpIqu]δ#\" cqZ6c\HFNenGa{$I|= RopGrQXp<)X`J3g;/2f?WeOu/?e~=auWjNL̲Ԭ_+{f3d},h6rX"[o!oaNs5}x#e@Cs[eلk ںL _;8ɋ5QAٰ +:[Ʌf]yF;Cjg{=߯eW1o {4!x$`9&ģM鯪`|n =ʩ7}>Ky;By#=ZJ;Utw|\e-Jqw 1uߨx%''vB;#ԎPhv*h<B'/Еf$ Oͬw'N@RNJx>JDًm]k+Yo[E /n(-JF\?]ޮrC+B(HEst=K=ZVgj*-ķ/wǣ{3wgݿ#:-4qؕQeWGiȠ'804ߊ(sF\IܦZ%S5|z_Ӻeu,k #~{CG} }hc K3|Cԡ|jAbTð51q cP1 v=lїN!V~Uadf+VAb^y`%4|2>E{@O{e9 - [ݮJB+9#/(*ǣL-FR U8R~K_IvI,ܴʯ6nq͗d=vϼ#ڝMyϵ`sM18NA]0lJK + vmΧzB!mWU,#/Q_-W7@ЃYY$NN J8iA/S7HMVnoqvF1 r/ۢzի~/>U|s˗_foߍ'l=Li>Z<0hXBb|!2hgW+ZjcIN[ؗ @9tp75}Bl*Sr_oF?\JPToeNke׍8@q`zh!ceA+CQKܫx~BJf%ViiLr\` +7# [ +eq^3=_fb#Ԋ&n;ƉnuE3k,Ds9sGch2}Mךe+_=쩡%}znU=\'NѧqѭKeEztQך=Քsv:c(%-fj[D䔔{Kiarnf{S4KQӎK7y M /wt??Ufn0bWk\T53$44wMlݨod)*-pᖬ1yeD +;iQDNpI8^FpAC;c@Xo^|onOٗx/~o {~,R=3fJ]T7̼mU|xhCV \ Z„ b/&ɇn=YC5ͰZw5\:3<ߞs dO=lZQe+t7[%J?>bu2/|/~DK*GJIKIcCA52}$zxj"לnFHnTLk_ + RPMXnk2iACOY[^ZoEMivy%]csgƫ=.0q½mm݄ˣMUK&(ܣZ+^Sہ 27Tϴ'KO}m*ټƬV3fZ]rVÔI: !s ŋFAQ#)2z% r%H]VFb~·" +Ҝ5!Ak)e|&> T AhG<~,xeȰ+Mg 7><7mᑀܒ%i<Ϡ*k1WIgbĶFl{223|jc+n[u8`ŕ o{Ʃף%D3UHl/i~LFS:B#栗 +X'dWIy`XGSP$}ぞ[gbqx x Z-=K75zZ nFaZcӌ~#aF%k#}|&?Qw1pWLCg +QyPODL Z4b&];jFջ-U eh,[I%-G$0QvMjQmUX 3\z3U$M&*+:78O"[ofN[#DzÃC{&)7g}ălx tH337 Ѯ O匵nwmNNnlscklos&h!ض{Q#knϹDWcpTO\GncUw.Kg똵RF׶-ә܁p:Qg@wp 8^4u.qÏgy>`p,0E\iuqO]_"JO4 F|2al'l +6*W3*tWlIYY,mAiK\'~A9IJYEbh7J=1cʩ`*2J]Go JHB=OʔT'SF~죍Dڬ7W|?>xͫݟy ~3O|ЏW38>L[uo׫m&6mlM?H +vf'&r "_ڦb6͔sTL+4UkOzN4Q}]{~#yn֩j[K}LSqecO0ݮ(S;S%䴬RO] -_#wE4B^,wӚ1)}gf(;;RN1g4&LQHQ;2[^p7*7USU냁lz+#DohP%fN:+11"LrN>)ַ}@:|OTq>LqܧӸ7^-3 |_T"Kw 0ЛU hL5'Yx(m.EuƮ"Z׹>iթGZ]E#֣*>w=z3ejfOjDsҥ1F6hF@ydV0l^LmO4Lqso>@TSGf^iLu +Xd*}c?{g$=fp$OxY>Q)01SN0|QISeq;U7^5|TQy>*{t&_ =pP8N7M(jjͶ;%%m}bڑ}3 5)L"Jp jKZgk r4/Y bS7bMt"_1=52S5SQwcVPjjOMRo]Z^RSKZu^%,zu\tvPAB+/ɨ R)t9k8&w5ר;W1eq3Hi#6FACU!/*CsZ[4OhF3U?3TL곏5YU3kGLXi7DyLXټ8)n֠ +Rp)mW=A>- Vw#-hfO}2_\LXE?=%F{x6&ٿ~wӠFv5NقAщ͘0nf}&Z>7&Bnc7NΩ |>'mdf>Vāt>' +@e39(<ddLc2o0;9/hό&,U8`@d›nչɕnIkdݿc}XNԕ3B˫D=O7Ͱ(NdҾK?[}q rlFtI'ϣ2.&N q,N4IKQ\`X/s`Z}1i`?NI,s4,3,$q`bO'R@=9M)Ezt"QŝKYcAη2!RAq:IT`'PA Fh"zuڞiD>Lx%NG@_qLV)$N(si~fl1\g)ɒ2a_(*adnG$.ʷ.Y+`_ X엱 4 2:l r)8/pLB1r( dyBdkr!<beE^y;AX0$MyN0y&isp~e99.B8.p$( 8$֮Tn'$aDV"(M’2tD(vK/ "&pq J"q BZ0LvTP6 62q=X2+P@g={"yJyZp,/>L}9l+(=So74Yy7 s}u +2`O\ Jsz{ςĉPcrR` P0 nkzY:xac8i#q-[8'A(wn~'tX,9F35eۂ<@ us#1!/ϼ Aa#dwVm#=ԲopkByF ~B_02 [2Kw@vA$B 3vLO٦z1NS1,/(4N}S^0dXBHD)Uyd) v_n޹zAodT/N6UWE뀸RPy%p2D5=))8NLm#&W@u-ӹX'af66G$~A?-080Kmԋpy%*kHʨ@2̙{L\p#" ;QhgAzvmﲭ7O,"R8p\GԻ9츰(HIxصdŽ# (̓(q"4F_(p(yݰt^X%%#`J84+2_##O9Q`KED!zEd~ȂmK_0{fNIøo&<12*AzO#Q8aҌnvj%Ô,^3RW¹]`QIZFŘ6$o0c7&RF#`j!:8gnhE%p1yP"& pH]Kb`qw`oÍ]<> )4qإ,prPZ4bS 6?%ZCv{Jh,0ˈ۩><۠j4O%Y pP;.I;ηA]Mrg](Uc8F4P- +eѵcB@57tʈƥ"4N`@i9e7к@[~\D"?РxDkK(. cN)JS̘:Eq3 ۉμ`, 3Tn0oQumP~405iB I݌' v‚r3dID yv3ͮ9ˁz@Xex~i\Dy-0A?Y IS )C8 uRn4K9J\``#tLB+OW(T9_.A{[p{1~(Vk#Kڼ{;DI? &ar{2#4XCt^؎oYq e$a B5/ 8ap݁)47/ktmOBG`4#ȱFA6M8ti>O?\if۲C6,a4 i$`b0urZ(@45^eoW9v D^$1#zZ5xnWFpzے?tzTTIX,γ=v <%?4MpR/)΁#ףq fafQ9mA4;e% '?AE9Mq'ITz5V|y~{e)LiJ fDN v?\z3v:P:R[peY0$\d/ɻv:L<R'$R(Udð*@iZn2"ʝ\'Ax E-Y#v>))P WS7JP^/v9C4" 8Jtcݓ275O$)0H!KZ$0urJ5JB"'heҥ6@qGa{$I8SDb}>X4pӜJ F eqy7 +I @AHm`K"'B&f= 7>vˢE|okmyFm12~TDpnmv77L6hv@>CS ]ww'!J5kc*3YW_Zo+ ؤtj-vaU>ݝ>SrǑtv&҃sAAIId7|VLgW' ʗtQw0i bB#y͗- +s(`XT {zw//K񚎐ƥ?BK!CYkjfw;BNpۅc>yRa]0ͅ,M.pFNG|vcy w zY 36obUU=SʛbpHpfţY|b-c:b(x ]  2ZBZ^stvRsz2"MY#(^.Ew.0&+AI}/rzX簌xnXװ:M>s,vZG^-fD>y%_B9F)'UwΑqRϮxIu9ʮt1_(~ebU.PUO*- +|)6AYmiiш' Y E-[]zO>j/^k#5`%T z %j)e]Nb!us6Qfx ENscyd\W0(;UfN1oVG\r:>|M(N4 j'n>crsV>@^[IF+ ؕgud4g|gyQ\_EwJ*ӫi[q1<-}P̉ QQt$鐧2g:T&%d|y!/vt2:*]Xq͖*%7tUOn6U8Ev`yD]D?2wWsrS} ߫?]2k^oܗ^ܦ2wdBt5ru#WC\?R> + hqrkPL>E G1 + Ug-.ϗj?;ccOerLoT1kkϙW?Bi~'(VG#6JtYk erBxA1bcrf+/57|i-ɯyAfUd,hSVF +RÝy ISoyYz( .@G Vr:x=܁8aNv,+fYHâH^nO6>/{M6RS($60L8]u-3.Zq ^5 7O'nʞOoF;r^sEM/?l]1|+<1l}Q} Wm8rܑ+ꄵqhlQȎ:csS.d0>8;wjIW W..iFp E/;2_Â'*x"mz4_oɍ2%0 + +ʻ:\J[~+7,nI C8}E(yXO +R,Y}-4!CȢܴ{Hp' % . 1 agm7E8"B5h>nwcCmgD-Wo5u^ƒoC +v^V=L4! K R\*JCn2I|%K~7[Y"CL٤ZZu՗ Jhk XYW(Ɓ~m\&EwQ٠C-@:g"XmI'K90([iM,l_e|P9օZB6Iǻ38\ЗJ{ܖ3ZYlKe"JҘBa\^BkPS"-B⹻N,4?OuXQ%K z97l;3| *ABt٭Z])cu]|bTm950}0ݿ3i0JwN}gF042G=1{t,%)d L5u ?ar,O 14 s{?%-)qrʿ+Br)(\9*Z&{.v} [1N7#(6 A+ +\'m">[G뮇<pq ѱe?^L[^nN;Q&^zp_/Qpi8Oc4L02?H +Ltfs$,; +FTf.6!|ovq6wE?6۠&,Slh8dw.iōqqz +lIk.WLTH"QR0yD+bQZE"ei>7dpE]\$!5ƥ%gұ 8Dm19]R j` ؑ=-f ޟxН- ,9+8m!:]GutF;aPMIRnH̚(ףV,,ҥ0ol4$Wn7<*|Ux:)SQ0hgeE괅SO\C{Fr,232sҊlfƑؗ/i^A8^ƶy1/Ck-Qd+!r"iK*UjW(A.ː*- &F JR"=eJ / +$M~ş,~w)dZ:(M +Hz?`tIVdBi@Nt? lν"d @D&hM @60+-"b0#=dc 1cA"` L|-*:ev@Wvs-;;+z@e^;;Pw@`pnV&JxKi;]dkh#'l|"S4uu_dѱWi76:BK:4EoeAXad:l@AhȵRǺ IY_{Th {Ƿм*iD_U9;yZ !,w08Xz.É>Z95k62(KIU/)/}+a%Шl!U,{bYwO-AīeGAs#.@( PLcB H9  C +DzQѢ2C/_rO/yJnG4hO^l8%ٶK8&Tɲq8hdt6oɠ-] VV:,j s]"oyMrI'MujFuE&K-a6c@)I50T0ae@Ip + + Ǡ `vC4ŢȪ:"<18:eptS<7LN:Ƀࠏ^W86A'[(ϟ Da%s-݋SOȾy0{ (h\ ZтzEfhWBE QP8D O!` B>W"T3v|=(gȮ}j-@Mo8PN7pLُ\#4C~'E&[|I'֕r) wʟNqPMlCEFE Q\|"wt| j.?bT|Nl}ޑ+T϶{4/;6mPTp0:$xS6;Xq0)`g;$b8gXqϒѯ3Z600 lX?q &;#0fL +m[|v;(Lګnä@eTpũSj/NA,΅KL(Z "j`,P)I,n`oģS\5O@? +Bëo;_/6[_m0o&Ez٭Vˮ&\x;7p$zEjUI$H {p)̜e4b$n Aw ]K*܃;.ů7jbr./"My {}"tq#nkj͸4'E^DcF/Q? o4UY0Ij!W'e\!T`醒z5~>?~]ϧ^6_M4|BiJ/ݔ+(^)1hҍj(>Lb2ɂ8 錽mjIͶOCH(. ++.cJq+&m +3kp! 4և* jl fX"d#5ei<)0) +=d#ud%P NOU׿װ\ዼm! rhuȦsАM.rybBqccBjDF4mlG㓁{zJ'Etrb4VQ +iaDU =$A~jGiw,[U( 'rwpzĪFԄ$ +D:@,07$dW! + n#grJ5K>wUƷR %y7Psݑ*v\Ŏb#a iR%QE"?Er +pw@6[  ?AOml'N,Q+D敓~{ǮA1x9E_e V"R*]P9Fet0^`$]_Z\"Xt̼k϶Ƈz@rXcΉLηÏg_@@Pcv|Sh(棽$G ,X~ĨɞC7TV]r _G)J~S !"E2~="CJQ+1jK[!HӡXPK҃gn EQÈmĻ~*c!fWc!Mok24%1rB$*&a"K͜DtJ~}?&RQQCH <2l5`.^~ƥw|GlB^!+/w@XҺhZ}ݞLW~d>:粚-ZQ^5]Ѵ=պYOshMVqڲnf(TRj&j҈!׷(V|WHm).dNewhBznC$'9B61.HrcBa{g*/nح,f]Vd#JEn[\M$;Fez E9&?5E[iy"h\I/'أh{c{@IRt٠·tK2l":[n+J%C bӄ*gVqx BALx-$=4gsm /C.P](K+ۦʟ;9l r^.]IĤ9w +ԃ +9.Y8ptO~ڰ' L\jebԑr;92l[Ix%UU{'*#^pX6 |5$bi+cIP^yX +7Y6?vH-ly\;H'YXs(cq嫮va͉qxMI 7T%a59tWKR%NBU'A?$ Ҝ:Qc~Jtv&E6;a=m +XdV8KR9h[ _uɝqf)@O3[ЧшmIb+ }||dGRղIc% U#o!seqNCm{k4l%%QQ_wlu>-ܨcbXL-.qh괺4Û_))8$8$]7j:&\N U}~BW?~B/GPtͫ{гprsu ]]5J]r=_ ++t .A4}u9u?Tm.?g@I]S +"\}>}, ]}>gSꮮ>EAPZwu\]}ѕ\|ޑT%W7st) 5L,qLlLzد? L^j| k{qTH^3=,Qg +>ӫ8vL^e*2y) ȘQ<+!*4mt &4).ʢߝ%_i&zW6iڵ]ҭAB +BB~!~K(!tIA8I'4D HE*cS**\UҹJ:%$K:2]@Q~VJM'_H%!/;IeeØOJb 17frE=p+t3sN&r!r*G4z4EͬF +T]t~.K`laW1*AaA*0^84/:i!0 byV.c9R@Cr2 C{,9f @DO/v twxD ؗg6PLT-E?=! .V!OoKm I陧@ک4_5>e''hD˼\pdp,O=#`Ʊ rZt(:. j ӱ30+9Ā +&ʱ eOKn%N$i'YXm?Oqݟ;DPOR\,m5YgSwZWKh 䮩2ͬ= g@=E*2'GW\Aտ0&fsn! m>f"j;Mg-VFp&Ru' 7hDi]TN]k~zi(n>uĐ5PM}m?D!ѣ'gb{.Sqv11m8 +xvn7l-hߛ-;]v :E.zVy.dR N5[>>#MJ!B\ & \Mm% if| [ ;$$D:o.'OA}p Ԩ :+[1spQh 7?FH-CUy1InBoftUqe:}B2Bx bHpx 5 .tœѬ +n 6CKwG yR vЈ'7&~`wX[)?ˆfeegf S9JcF',m֟#2J#GEUܤ#ݤR'q>\D6(/w(DVa>46$$I yR#R̪n".f7=,MV+ bJ#FWKP%q~B̟̹Lz%eI 'Y4Vo=8~ձRi^`xI ĴWzx1t A5؍$]b]4|m9亘&ukxxl"ELk5b1K\\s v֌,+ޛs`,u//6Q%t\pQYXR)!IHGV^$yJ+B' I +9]%P,!HQ C!U?.mܱTdc*v&(1,cz֙VNR(;26٩sO!Pq!|I.ARIƪۊ㊥.:L,C6ٌj9n\y@r?7K%O/j/ʢ+tOeKc|b.<ڕHyFE<&C*·`@.V>RJO&)Y +I`?G+ֈ.b_k )|YJW2ǽwrVbKy) +'EnE/mve]bW\%*溪.,ߪ.Եu +]lryk nY?{͸gA3X"xG|=;f lv:^[YDXX)*lW;,u:Vp],h_nJmN]E>t#mXPkck +A֯ BUc֓X rjC cQt(ŢTX)"X| )<ǐ jh 52q158_ ]7 Q8GGi)7EO_ha{1Z(1OSaqKE_ y +4̐b{\fX*THCz yoʤQBDCG\eld-n4-SƵG'* \RH& %h +QE| AiҐս3〕r"h'l@軄CFkZ]ݒme,樼l1x~jjE~ ѬV1]0  -46":Dd[ò$R"u9/(!0~F{dWn ^Fj!+Ȟ!Ca 6D/<>,;ea>OAl]d='ˠ(%`irCӄ M87쇒~ +Zyz>(%prnzv?~noo褛N7;fg =P:y2%pS +z*4?$v>-2Ţ73LLv%5Kʃ^JQkeV@Uꉱ`QQ^A?vW\G햽hџ̢ fyˊoWGlNM7p&݅ \"`[^\VPYkMɊݺW]h'Qw~h`wX!7M&SXX[]P_vSE. J6>h*J\Ws-m +3 lD 46AXn~FeHmcծHרbմlӟM'Аt!/Pӕ su2 g.8]gRx\hJ(vPrG /,D +5k.[PH]͔Q⨼٘)R B/d;TmWQs2+dK ܁/az!q3UT& BH-HMh< ,q%l9vJap`.kxsV=<;6MkywjhHfݢr^c?͘ԜIC.cWY"S]Y乮9G{ zTkPEc}Vy3zX#wkLEcBBh#x.Z9z&_KUFG@0ICpuZ&*e|\gqmяCJZX-Ɯ-k3_(5jǃA~js8  C 譨T&?sI zǗ"rt! :~tF5QEc6`qhB mĦpNJ$ܯfƫ|R~CM~ßцGu 2DƫŚ(Į? WlVL~7L.g+fVEUdm1@ Nsu"@~4m"_!_C Eur`M ߁\U+- &Kwmjg^[=5WM1U Y=SO#&U`p*lDQ&,ֵDVM@CwѾמBŒv?? EQ]P~?s%CU:pTbk|Olcw>, \1ݬ |O}SlTKtДv-F"6 ck +|kFs~1Ŕ2{9Iz 0%zzf,YPS6tңR +gՁ@fAr"vEE1eZ(E3Xk?nM= z%yWf$*SHUt&"LsuN!yxW\<ȯ*4N"ɋh/ݬ"dwӡw/_t]}!~wWTtb("Y]dIhp>17blP^J+㢚YGFh AgDf꫄m`VS!R!kǐng~$؞JLY8cDu/ĉlB/߯RyU4نADGn-V罱@vf#Ut%D>w^j!9Ή<9X%f'^jE}.뽟 -N#=҃G҂౞",p撈DI$a,ˆ:!iEORj"QK*zbw9GRdE" N2BIjdbQjIlߡK yd8#>\lIl %VV+ʼ$u**)]8\‡DWMLFDvw/$_D2/+u3 4vş,.-K8 +q}|*Xk@ǚ!i$*?CXdXn/eڥj&eD"GƤ)[EƌseLV +i'3Jd"t>Z"|FZ"* DOL͛T'Xa/ɖA"|S &"$o(1鏠^de.W٘p8ԅ LqMK(X%&^$T gGR'xx `,VyڞJLR'us"!Ik>լRk4`Z'nsB).hNU\\_nPL,frU PȋwT~W#ԎUgqP_w؂Ү\߁1@^.əmViJ6z?}Ul[^PK3 N/ 99lʬ0ɐ뵹|vԘ~$mAO!")cpHAei"ݸ42d\Bw~UcYK$y..d/WweJq)h kdV I K /Ʒ0x}| ‡۔GJ=qL9Eذs3Kh%O:Gv9~э +<[VtXbyp_}If%ss\W@!!7`3DӐn71o^yBgjQ$-$Љ8$n-s~j(7- 0_o*Tp.7%VˇQCAL\gӸ;:\..P7BxUw`2d`IBr,PA*8i.LDHTPR2\.GŗeF=w䄊?1v[qI9لGRׅலJR1W*[ߎf-gN kGڧgΩ>._]]@jJ A->`djyE|w_K|(b6f،eeV|hʖ=N#cWc':̊; +)z-wL ZD=ً(>cr{KRͷ\2!xvB.],5f̑`H 2AGn_ZWt(22j4cs{PҲ0,3q~K8}$PM|y&fJP|z{ PX<W r[B6G&>Dx$#zC}duI$WG:Viw{Z})|tuI66eg뒬l`Umm\>RB QQ]NU %X\˸wLt]L3F`8_@K}t#R&}݂Jwֹ)]TJ撠~RZ V\0jpLuG*iหeXP P\#@߼KA _+ëQ.^I\Q G8yG DL&SUgEЗmm<$7[U4: 9>iJ#M̅ij YyHVYW:줱+" +LrhقlA `6^-HzR~RĤ')J^ycUFʖFDn]\X15[ҝZHyu:GcUiYel}ثQFU}2r2F%O(#e1C`8Gb)1(|ψDfw!\l +,G6I–p>U94qwjs +ī]4 kbHԠ]jD$$!m*b^1> O`scN"ۯQYf̚_Bku;O=,)ā$h! S¦17_܏wM&BY =zIC shgvImb9bjv,YPDueW 8;@L3җ[Ngz rR F bY'eQ~yyGg~{CY$;"qe^&{9$/HL +Ǫ: h!YK_00R0*49زd@%Pzn8겤.EWі)*V$g/)#ӫq;JH؁( ya]%[ +fōA,n +),ʪWJ/- &(3j +#hWb<RLJ5[\cbnk4B_xOE8}QlIjq@Ti + *}<|j ~rcupe @S(:h̶%5]DYd7KӼd1LHҊ4OЏz)@C.aSr5֭9ZrgG R 5XN5O蓉t Ѐ8jc3p^1a@@'@:~0#dE4 ?apI4ܚ~ | рp3lg4 Hz@5⑞Y1Q1eu4fGȔy<5}"GpL>h Ut2chzn2U85m]FJHIa7Ԃ9v@!u`@Ձ2Aϟ(&Tɦ@}m=mzpC˨TH&7 KY­큗TbȅIU>"9Lۀ,UKOOX'71` ȁda-H2Qa̴XGwwhY _!?QƝmf)|Q*Ui2GnW϶':lރ +|Ipx+H*?6A&R њ^6]X{}vW͋CܤWq_bPYDF@gQqcx j\ , +40=ZVİ׭])+edI5-4av-#hlDHx!( ƀPJg; uc֦"% q:P4:es(WI *X\ZlQ&?6\A0$9hT&0xj! +EyZSXc@[tMh&͹7x6]6e0BԨn[>h`3ZdBЊ B%^%JTs'3Pw (Xi{R-d y#j.~bD¾*d:p{ Z>}gzFPyy +Gz%5̡r FqS +yHp3)#EWA@ +iP +X"abzq?N=]3N[~=6ڡёPT58h9JTxq5@CR"cH84.E46& Q~)'X(W !t@\7zd/(B{Hԓ6bP^D" ;<4:Mݪa6~ ՇbKb ![v 1JaGl= wTRon{&H_VzuZ8O(:`Wk3A>U2Z[Bl"7lIw; [Ш4UX:eסfA61fmuoٞ6Eń6f!vkj_RX[/Pg/0:uRP@؀pOʐJqevo]H𒔺/P.hE%w6ۊ-T/ F]Қ ˚"1p.KPs./\2PJzCTel-CH+뺲+뺲+:XeW-8Zt9@õ,ZP ,r5ОפN%5kZ\ĕwi:dN03qHBuGy40 yΜ#4-Wi{ʆէ7ԾZcTX4-T޺Lbǩ \v[ MMTmP}>\N@\! MUYm vDꓒkAGjdT:rz1_[%kMp *iHrA)3eҰkaڜm|qp "ƍx9ωw bWC(A%lPHJCujU3ةVwq[κc%,=qWhX\ěSޠ9 <\rKE%NxWH'ihYtYCqjg9ri\J3)³lI3[8SluU1T+b5כz6ѻK.:7Ϳ/K$O, 6YY}H.a668LHHJ@Hj"V\MaWAKv#/0Vu!QFFW#긳D;0&8_Zr<%,435ޒ2mzfjv6k>LU4Z +,4{p]e<nn'%yׯvo{8ZWS4|4byUqi Qlu4c,î% qyD]qqLQqql+)W{!,ac{}KɃ^e \) JbOn$tćnbqTuBLw|-dYQT쪠jlwt}0ɮ CgfQUcAPwřvD xK )ihKϰۛ.)JMߔ؎rl-laQ\dpK928h-pQZ ZmӴ?lkg^SnXmvm=hK;geQ4]GnkC%T_K0:lKp!>P'BK[ym(IB/OPU9TW=:%ٽגtO#[`мӳ9gxe9\r#[|[/KZK9aZ`o 8YR)^0'T喘§7TA֟U@ GLGuKs7~3kր.% P^w8ۡoPlr?ϖ⾁ +'fzؚt{Vݥ:'g.Z9z`kn8uN4 +Zcvfa ChWˍ*]iqC{ѼFmN:8)bi?>)oAӱeE1%Ixil&;T26uAZ6vl2ێWf 6T>}"V7*HT)W풦U :(IZ@RjmW~p(]"ѷBXLРr _OCtbx@8Y%<^U5/͚&xܻ,{^DSe32.}8ݠE r֛b,Wj#Mو ^ WCIteCY/O`*PA*/5b'M~ؚlKX$s)-Hfwj%jcGEX O/6*ר[:]Kw~bvWd0w(%~yQʖ0 }veTWFueTWFueTfTqy+Wt9x:Z]xI_Ekȍ<ΙbڵtÐsFӽJ8W *\%N$nU.D#;s M& %n໎x|/jV~ KBghQHC.9^M\ȕ\ȕsSlw\)*XyZ#I(\پ3 +☩.:_uœsE |2,+A@F^nI}:N( FX@ |4 (5Ճ2%J(p; ]F$E@VŽnv4qh"\t9*|JPIB:"S7d7oə;R ] +x:6z#9Ź 6O<-5 c]c*\dXmdvJRlöj]ꓮ}c(Yxhj]$x7AH~9") <o}8WS1{&SAunx*;\bZJgU s.g>=&Δ6g̟F`1rY6"pd#sf(LG:y9#漹ɹ͕Q^ )QmFf8BK;_Hh.֡#Ex*yKٹ*VbQ'kl~fdِuX;L(S,Hrs]{taU~<4q}e7[^nshjjƅGuʔ=҇1UJ?;*`xwd +C㪟j.AMNzGƩ7΅ .F`m;tw0p,|FnPv&.[5qi[[V/Ez}r*&_Rz9De}a_N"SϰĞz_ɤ!5UUk3.%0!\huplt<ζ6͙kR^?lYu +q E΋]!nv.FHTB-g#jAGgVeLV5:*RlȖ=T*YϜɊfwHgJkk>QU(mɻb:л%,QeV1݃]kT64l0,f˶ǺhO6fmR=y.~6y^r>ۗdy0@4#.k3 X3S ++F||PAi)@-Z]<Ĩ1 c<|< Y]m 8@!xji$ XQsB +Ph~t6?Ghlol3Q}@W9y]ue岮]/{6ԁL\%w'.`8JQnK^5w=c|/;x]_otdL.=?aѕv4.#\jsSʹk|H׮z k4R>dC٪ 0q͡Tpx?r:oH4cZ':C+m9e[{V) +h1\Qb2 p_A͆$ oIƚ@mz3#QL +թ^rC깖8d:a$.eBΐݕ"<Lb82db=k62[pC +sis=j-Őf6GEJDNɜN&o-dd")ɻ[ Y*\PLQ)Mf[!Ec{.f-8d-?zB" 5֠ wrQ +M\- oGU%jƂ 4Q`e$<60O;fAAqj 0i\/^hlͨ1 'XR-3I^7Iփ"AV? ɹ)O_ї(!EmVH*ܮST6xe~y}KHGpFx`+LqBu%<[z6;`x[+)"zLz~6~ ͖̀tIfEGD.42rWP + m߀_Kj#EBL5~ Mġt[_SFd zgy=a +KHΣa%6,Ŕ59Jڷ:hlmo "PEE!Do!<`_>&4aab_ &(Z $x π +dHB␐@|BF O;t7)ƊkN|^(P^0#&t.ǰG9qǥEK`2T_젺{n(!0 rqnaLuzlݪ )j2H );xX~ )>e K4-Jy3c e3JD!vJ&[9Ԇ>0 b#:(_B& $+9(G\ -pV^a薺wHv uJ-ݱ|n9CWeK| T!{S|Xs^fW;y&}gw?lf~3wt> +g 0A>b"$cH&[ +45)*ߩ&~(X7xj:"P@<_!_ XZ +Ltlpq+o .]I39Vأ)v^i>"fAd[6PyOGEQyk#Mh)+I4=M"bm֐~OED:į{g:5b2GA؆}Sِ%MD@ +ٚNVUB4[ok'SqߦuDd1#o@kGEV7~@yoXd+aGs& ^⫝KGJ:Oo7]F*]K棉Ƙդ:cNhTbG= +eҥȆ&GCxJJ_jOA}25FS^llG@K .c5-tC:ېX$WڂK|dˋ0Q8 PM̈-e;a]#~ݓKp-dL4 Tr{=CS`{m*rw*v{0Ư#(BH/%XJQUSYYReՖ3"UPޗs.3B_/#|.G_|kͫ^~m~{C<~Ty$DC*8mgm2LhŭfQ?id?Kl˜~(Mz+b*j$l_/2ϷtuӣuѼ ؉8>):V'^OJKpCpUJ>?J>gwI^ix:x%g#4HN>Ś7r6~r!`A%i-U3*FeCBլak6h[ψQV*zke C"n̪D{T +r)4kAot;`7Yi)DM>8_~;AQV*BKcME b2|}\hɾ~KbfP4&Xyɓ_ + p1F0:,hp=ֻЏHdGq(/N1G*R+8˴j>qCjkL:bb0XN>xg{"EX^l$>GESw}00=c w ]-jk4f&1&rbV:W10+Hq:2zq/FEh䵾4օWMx;`_Q. ygLPޭW Yi84$FMj xmt`Tc"Әx\QkgQ) F>.2fu}E:a/_s2zHVa$nΒqj&-1g4K=}I ΝhQ ,QfF2w|pj٠lCҽ3[ 'ŭũ^0wa&FQr-2յhޞTeVYKCʆDU]R&ڣP)2pH:*H.BTK彪!::i*p[U*rxơP)t0֕;g0\2ŔJ6г5Po1.hYAܭykdPweU@wAҿǖ9N +A䱼r4]=,4{}svS3 +@( cY/cւ[6i<#~K_1_5r$`r$#@뽽D{W79w&Cq7In%ޛL}+݈1F[J, ҭTJi1lꓮEE X[?Gw \]h5h1xy>~2a +B54F+)@kxa +%z~6f7ZER&IW8}vɀ4@m&P,U}".cHbJ]aMFڽ}̕M\.0eY6A镣#[v[=S`LxaX n%5"iTT^)H)$DՓJ f^+Fs4(DU+1 &܍#0"LaԲ'\ IN}DjBa"Ƶp +uOVE8ZtRW:10 +lVɻy?!\WKpj/%%"MŽrLߥ"W*͝"˲o"_.Ö%[`p궵lʘfQDg ,^m ;ISpF W VW!'f> gz_B=BC#ÖcmC3åffq. +6ʔY7@.,%b:-0/d%ak0aIV 97,ART:E駱ŧ͖slCw$ljl26f!vs zd/?[&Lfy2- +6F%8:Xp!r-Q?t .lTO: Ykb+'Q߹8/]Ȕ- !Ỳ/z04lUy5u:g "0uBxmL,ODCWuj-)pVV ?GݔRmm}ipG@VƭT(*+ ǐkz"eBҷ!^q5 I$(q TTNNo29lEՖRch/ף iW5ZLGÄ%/1ڨȁ6T"~ދvOؾ8 iLJFbr?V&}?d5WظU'by/XPWee%i`8)Q@\uoL$c]gW[3^"pR0To~φ|c$y[}' ,#3#TUY/'W_X:<[eE68(KJR>ㅁ"Ab2*Ym=H֤VGlW8]OŨjgp.5k V[~c Jq&#><ܜy fi9V,,ͶUpO|eM\VUNTUqp(H +3Oյ(D2w(GtNuGj'H? hBtg0N;UmtWY>|//6E2a_rblgF.T̩ keɃH|~H*ǎsŊ+aerB4mq[nK}:UJ]e-bVYudGdᡀaر th:&B199 IPv1UrB>[7[nK㜆&aVsnRߥ[N|뻷}y-rk 5vyh/7E_xa(&T˳L:޹ T7mȈf΍Bw !/9{^TӞFvX:/1kIr +E!夷Y=rVO>?%z]EihŧdZ0_ꓱW'4ϩO\^AbR2Njgt~*>WГ,b@+U_ )W),k'PO +nBԍsW粿-Qd JZz0) h¯vΪeݪy_ m-M;Rfoz hTQ!tbM&لۺ`NJnK|%'b^Үl3DkŨem;BGJOH6) +^[EP@}ʭ"WE>0'-'.s̶wZN"J<;m]%8?p؀XDG{~k׊H,+Zky;facm~3'.Cj>Q$@DJic,UNZ| u'#icৄB%8qU,9-\155G}4*sDdӟըRnj$V{օ[^Bdxti.:]"b48j}ȉMi1]Jc h-ݱ֗ZJdcUP+W#YG}? Y}p6^,@d=ÓI{7IJ %a$+ /RZOe/Oc}O)q[‚bhZҥ~$DzPI$.R4 "ueKmٗ? ƒ \:>(z5&.\!z!P[N:Y̖3Hq:d:·tRoglA3g_vD_夳M`3E%-wݪ-v/ՀbN@,[>?H"@y8"&*5I3N+M||{gs?} f>m,YyS*{y?_v('R,4./ fNC Wl٥#^ix+|j':^̶JA$ӧOX\ۏg9uTJ_EQe0u~ڈZJ&ߨv2K=-!#7΋ 6tzxOx%O.SKJNoF#P< rA,=UlM!}‚H$.7Y1>dhҴȴ3-sѹD29A#008pxȹpnMByax7HF{!&_n|xfD] WpD8\_Ћ{AIF~A2%$8tC?JTCy0L0Kd3n+DٳOd(&ٽ`b1i1 >VJT;gc( v#:áW| J)CˋO2?ΐ-NƗ:#sglIIw!;աP4^QN섀#֧}:W߼=%Cdn(HLIsYM{fq{j"?P3 hA^u ̑esPw(LYG{-b(E))WNKxTݘ2ҨN[ ,;؍jiF8xkhUf! +KhsMįs'^9?%TM}P5JddhtT4EnOTȋ*_mHJ,w+x{$`ϭpK=%j a@F#ݕd +*`ۗΖwVTUھ<,Lgj|w5,ndEsMlR)sք38Z- Ȧ<|2D+AM885) D#h%eŦr+d" 3!LfiuW-bHiTüj;_+۱ы֒uR2|(%{aEkǁ*ܶ5A؋ߵC~:, G:'"\WYL*t:5n=-'G'id i S3hm%w.MrA4 ";l}ŘnVe "]b,9s2Lv w+\U8𓧒 y,H/s>Fl*۟ xFP[(W0UC֛"<)o!o;-nn޿aEz| Zmj$\r|DqiI^uݞzea1ذ6Ӿ}nы@MĚ9 s)|ԟg|n +TP avwen-wRؔ*6W5Ƙ6vn>Ԝ&`FA"cb95h-g&lve`N`žksy B{Wᇇa8B0\$jȅeK:KO%깊af$fr"i[WtFqd١6K8.vJU"DPRV@`aQjl/{xFY f#SiQ o6"S(-ǶTrg)tO$/Rܙ!:E:B_Gc_/Fy~sx% +5Hz~g^$z'lI#b&^);ڷ<*,EG8'Muњ")IW'zQC7g)җx $%o#{I_ R=J_"ܟ;×r1ixD^HsYJ +$Ǡt%- +E_;k|p$顢Ў +;gt,ZGgSW9{Ї[,&$"uD:[."eWN<~>\9UN0<;H6쓾:%#cCmWLR?S,犩}mW̮UNSzt}DKx%_GʿH#nXx@M$)ZI_TC`ɕ*y-)mP1h#$~',0ɫ7o:k_)\z!K7C8!(\ [y@(?ۭw/_~EK[mɨ#V7 "P ;|_\IlB%k2'%ٿd55kdIҦٻ"((X^z"?^+dH2j-s,2K)K\;= ;&(WK9PS*r=,֒QYEP*}R _.|ǚ\t2ƞ7[ȱ7b씳1dg-IԾɤɒqm2uҺt^x||!??=pC A;Zީ Zm},6˔^uQ eH^fIL=n2xW*ZSB0JoZ[WMJ(|LC$Js6ZD'Uf£[zTx6Q T-dwRq* +/KNm%qxI!ISR^HWpW0f 1.Ue2B4"c`xJmnl%]׍Ǭ]'q0ծ|e0qg-G+GF{*sUc`T&!=.7;j\8?ءT2M{4RYOP`*5^۹ q k9P'@xƼYNA$$4θb`1IZzlwۼmv1- 7ø%WoL{DWeȢmzzlB N+gPN,٤UK'4.ӴYZe{zo<[f˜;ZtG+Oͥ?K7Ǡ/] +sNZeNy >[ oTj)Mpҫef _HUh[AEՆu$WDmwqR[7a:^x-نOЫ!8pֈ8I +lE4q8 +B Ӝjq\-!z=RVWc߈ITQ0JY}޷5qJ0V4ݠJ4&C>`fF̤:Rm[{ +L`vFNB=*s^]x6-#AUn.zÎ) +l☙ښca~7-F^eʚ-,K #YBU/O޾r!#ov4R"5} Mϣ֛?Q!zHHT'VBs6ScsjC08⬤+ag!4iXv/ QAՂy_}&3xP?j)V۹~`1?awLE,\'_CJ̜ RXu.aY/^wqKOSW8Wss7t&Xu,MǪc){]T )^M:Tŷ Ә:' epy$oIv|a14]Gf >{Իws|qPdLrlRXt~Q  -Īz!/UPFE5Q +i*y&}xIKOOR>Yz$M)ȧT]MQ+<a{˃I<⛋ΏR_Ml!8"0C' '$Oa waDaII/Lau?~x݉G~ey$IU9% maca36i׆ + -dƎf\a&Le! 6'}3gˉ=_b?Svq&ݹ߰`lUn{,馍>-oW76aě3J<%]Z̺MM/?AK͎=Mf3Z7f}[CƦ 75*gKF+mp߽߳;lFIhL>|P"|џ?QƋ>U3wQOo@$L9uDSfV[owo#"A2Dh9"{O:|jOgs82q0`oSH}?3=SS򽙲u@zl|~WM%ڄCٷbݸڄ&[FYIInenŮ{^{=A/AY r 2p&OA!A|/M$.IKzt%(>"( ׏%\hRKS +JۧD$[Ac:ӑO,IrD,M4I(8:%ze)˥DI);%zSWHqxI%ow'taoxi~7r1t%ҐCG +iHfLywli)MlҪ^J#Ь ۤ]u:IjMNZ w09;K?%I:io2^6vh +yU.ŹA n&?4 \>yaЋh[5$OQ0w}$v8IaG8<'e4tRxOpܤqK*[ұE!oG]Zեum,֣v\p!Hfq(34F;6/uGxQOG}X$18+EK~j{3ѥ / X|^#axK8˺A4ʦYHbރ$ +2\z?$轙,ӈ^,xA i6޸ 4 +ߟH:ȣnYFLyV2Ӕ&+}jBؖ!7SuVEoҫNPfe!q"pnui]/U$E! +>&ϧW;5y쫩c_F߈$ki~CE vMl<㠛Ž;wț|Y!z_W{sRZ)(>%pqpYuR"({qK`L]o2I BFAp%vRb7NJn-Ĥ׋AQKZbobO`o[&A/N0OI7@8Ac%e^xިZĈē%-V\Ui`ZH'X۷X-V&}7N4I2JY#D yYE;|L L~I揂^㬗i hǦ9=){J9ON +)T^T^)BK?;aG޴ߟtl&F=)W=U^ U* R"bڱj O(vS$Aި7Ҡ?;3E|:\,yDQy#*#B2l/Iɰx=G|"p OIq|:Bۚ|P wrdX|=S^ Sdx))|*B[$OPp<&Amd^^Mtg-{?IW|=S^ Sx))|*#?OY?iQ ob4Qbkp>!Δ<| A7!EgJ"LINa)_@ggJ,ΔsD-&H2 Ө~.Iu'AExIotu}+&#lIJd3$ˡ6In`$ _O$顭K`K8zqw9p\}B%cE$%=5I V6Ip36I/=I0^{)%Oô7dq: +t^mVR#"q>G䯧&oA^kE Ax{1F{,N88W~NY!CX'!uB-Rssk4̧Ԑd]'k},գlRr!q]$7ɱMFaOz~&~2 n4\2 +Ólu"+Vj>qزq7;lFܹgmѐؚCݠu=/KG8 DǓ$lO tqjWJ'S86$4#|eBR-'y17~7 xڟz^煯~ mRujW+J'S8604#|%CR-3=呪$q2i^O~{5Iam)5TOvLЌTMHP-r8$ z( Ҵ;b/˲#,D4$(Ial)5TO\LЌTU MHPݸ|'BS?MċI]?(r1 ;HիHT[z"RmvیTsajqlvMcyꍒ(vQ^ڟL~ʮ!k^OnsWHԞR-eZ}B#S,\c- .Ѡ9F}ku0vSM(ŋ~""ļ$$iϢ8M;GY:MxBq܍oUjqM$Pe評DLhʴjL9$g(n6{\,v{a~MCW|LQhɘrBuƌPDO32h~'nY4CoE${pv=D4Ni0$$XSidV2>!ć A]Zd, n4&0iu,vY!b ~CN-|cx: 2=H &&^]b5Bq=rE};rlgi0A&p0ui$"M.u\y- S65%X#-܃y]DVy۟tt:x,iVd)rh& be],Ey~hp:znuh?qYUFOaLۅJ'%Q>բS>KE ~COQ6`G&ԛfI/\fҘj(|#v'f4X 6*iDF% hȦ$DlaI$J,uv}nzv~ <AO&=] : J5|?%t_HPE~J/vx?;ѨߟDa{ؐ;ȸ +/O1pۣG(iz4鍱iQzaoyl#>Qb9WC|ͬ_Q}+:/B~?/)GCLQ_N8U6qDO#ma/(wKFȎ''fNM9ԩ>!:[u:_=2ͦd2(zSLI LBv_q|eG> !]'䢓qFdϟqv$qwc/Q҉+9&' .Vb_LNS®Įkr +bũ%U#QMF-:&~7q~qaEq(W:E?Fy<*R[KmA fA30n3߰'Ed!MQ/Ix<"VI q +U/6?r,Ԇ-AP' IxMIi9l7 %q[6 +yR&= y6^+7å񸟎Q4'}/xL^}r(m!?>dnwiFzI=`O7_,m:/~xg_//le՟ƫ<"َE/2ޠh}"[dQ]}e'lϡ,O.MW%jmf/ٗjYs}ǿS+ :ݨ:j~Egln;Gۤ}L0Hjh81ߧ[x-χtVpHio10ץ!ByJ~lrgr]t?WıV$ێ75ˑjĤGR+~3;L/@-\1Ըsi[|5*UXٽVɲ2ׄWEQiMf + C6ص\qbrՅ +}ʖGhn@l:b:Ula)^PYZ8CDdoü^m"M}MfA/O_^jm+VtOM9HԴƂ߬BZ@,՚v!dɗ?|zVYVJof%٬y6weaX-"iu7j;tզ]bϻI-ZwWݓ~m!P\:o4tx㋶6l!e T&}3\ܸrmv΢s4RG\.#By [;dn"ؐuNw/?ٖ.6mOlBQ&&X1?DDeBROoHFoL&oѿd DmYh:Y̖TH&t'w+%L3c|A4l#fS |nf%WM6x̖o7r;OaR7L~}sFO8n&;Z@ts_1K#l_(p $Ș77_ɤˍMݷ=)jǗnMf=)e6FF3}LP\+c>c>vǞW56n(> +܋K̵ N-^is &GRQ"]YmF_6 EY Ac0 lZI kA Y!tFK =?n@wxFDV=dl}|0Jluz,*M6Gc,/ TuȠ?+0HW g ~1h`s p|1"A@ dYuPwvNvYg_b]Z:BGY D\^% bfڕC{4e_Z}Я#ltw1.vkp&LHAIl&W^Q@J@J +)Ez wl:~ЇK7BZm·3 ʂ=4vWC^nw-io:gզ!890/o۰6gsPdA٨Z~D`to!۶"1cU +%Xoth4,iXGC/~16@=|72v|`/wj}9/{9 tbjeЀl`|X䣢DD!fHCjCq +-([aON[9.ˁ!pJ140 $.5wJPަ$9f5gˬ_CXO ]aqE.ݾˡ% ^ز||[H")ڃ}MRYxqp肤_DX"e4Nǰ@2B|MvX pOG#vQ܁0^E*zbٸ٬6@ەO|]قz>^ȶJ)FћгN +Sb&LJw-kMb/TJjѢ<[\2禛_bې9Mv'yVRTTTJnɨb P^%ߕ@5l% +mesEۜ_e,MOˇ: nuj>'}\-_ҙ3HEXK}Q#MۀTLS}mf~Zȅ^w(vȐN5m'[ñϳɞ踯S0/SylSB/S)4)zQ0MIE-FMC`U>9ذbsْh`78qp H7<[\34NHgN:AKee;_ݧ/;4sgeׁG_+|Uxc[:vYcKIl8Fw+q\`"x*0~vx 7(z*B<=!!4P'l?.قgwkCm]=eX|u@مujU2 ~gK2?pPENV9R͛;DŽy?YE9^cu#;&d;O]u/u=}pyI1'ثjFQ tn !jKX1V5\r8ԹƼ3Xc:ELظf G8$Y&lEXXE,PA'ΘCMƂ,ֈ)(g^Ƈݔ#^gǹϴBT73n@ dXEdt8}kK؉ (crK;|6-"$ۨ-m?GLxQ'_t. 843:g$Gx @8pq|Κ{{&Y3Ww}V3~,olԨs7+a!upw^gfۙ--Z#x/np"^gk/uR{?~f5^-td{c6K֌S8SY;a3?8 *_E;YF-HT i[| g :ܲ/Lz,VG 5[_M9\Q[mOE4cu{ec5; n~N:3F pyn&o;U'=I8Ku.VjhJxH3$Kv‹/)z7q?lVK|{wzAadC?nw.Мώ9>@ֶ$2/< | ) ˲wTRº6To<р| q~\-W8m(S%*-bGo>.i3ʲ%<0@%\/:`̜@`a+0qۈ^]a7G鐎Mb&G/:G^l6&8.`ҳI:#V;dYX$(I~th?. +Ib$NW 9<(fZ=-=.N]HNAo3#|1%ەr^>}Pዉ#g,jQ] DHc͎jAɟ!/ղd-,"ƣڇF@ 6ymjO6Vt]66_ +l_lLyqdx*<ǁ6!"ۀy>ՈTb:ә϶:k9^LϿ༖鬖t>I!W,9$ǞZc7R8Dr>tg}Rd+5+= |&#TuٮO5lQIB 1zO1/m'Sk1Q/:_9+aehb{CD%Z-==1/@§m6|Ѣ)ʌ+ƁOʺ`H 04;|N7Uo8_.@ٹZz{qma=DcPANt7-F^p8ZM,~9t{"˄!ds$K]͖=~dUnځM~E{v8 XJNde+cDjUm Ǻ6>]yVk':6_X4(j1P;~UUz.2+#2c.Z6MO@D>KW0 7GoQ:/%Vfc_W(m{ASل-hA?b]^_h$=:^4 +9eb(RyPU@R H5%sF'l!NX5yy_K6%pma^K2b_.B}yEerzWkDe4,sseqeO yu(>WWJE +T?:/]Y_݀t\=CϠپԆgETsB{ + "jh5Vf׳MU c涠(Us DLWIv?t]8xQy,uZhli_4b!ldռ-YNj_Sjo QTlÅFYt1k@E L/pBCf[?o _ +cJbd?{uw7oqjX(Wd^׻#Cڃa{w72aOH{׻'n6{xm + a5y_~~O^GQc /쌯@orpg?hzrHOgsEw1-gثoIxT{D:y\&aLmqnj5^x2b 6rt&"°$7'D2\o죝V N,dgVﲥ_)w B.P1= RE  +j.0$pp-xd"^ݍĻ5nӢ=R}>wp {@uY̶[JAeE3F +ٞyCz1 ˧$''lѰbt +%^_//>_wn{ru;=32I"T;'HfOEcjc\&MzNr[8_o-V%Y$p^%6_.r9AmѨ4cSOnv9Oi^0P /%[eqq< y=١-<qD>pܯ$/r^s3}&dKE%P!Ƅ\&WeBz>CYsYߵj5~Lq˜f 5gAF}Ήs\n)EUkdAq$W׍ǹcq a= &emNm [`9Os+p~ + +Z @}|6@n~Hm*'1[ӧ3!\·<@eE_ʉ蘜( +q+Zf2#ϓй}@4Nwj8L*GN8 5'f*+_ .3<&VŤVBSu5\T+jJ,  6@۞zMGRRBa 9ȅ,$@ hGcbߤ)w6J[f|~gli@iʶV +O&qlr\}Tl3NA 0f;D 7wP?F츳e`|G- nz8\mfe:n8# c :wʕofCw74.q,0øEY10h^^M8y&EqWK9 +7x9yd)vn$ +{^3gjbW~[-WoQG dMFn{ԍo30Qw{"%dlľ>Gݪ.#&Uk*sNL|k#%.x_pF|#7h}fR'XݑX{ IsBfzQ 8Tv%n6Vo[wW/wc-ᗞq2k6o0SVs)ez_lԋ%o/ƨ +-bhYf3Rcgh`kY=Zv,rfEeZW( gROix鿫9GYp8Z +ZP`8ebƒA:F.&~[ 1WmRE)!Z:$R'I4av%>S1RŔ ]hoJ>{kuӻgs@4PZ_&&O Pp= 8 Z_0(}=[ceHN$'Q{.a|Gt;>sC|? ݺ&[*.f~hX;6^'-T傤1?e'ԒHCna"i +Uw)q쪋b,&G z#9Gzrx@Oc}LطFFwj* dAAoB.V<N5r<Yj፳?l>ǙG[_%:\@ydgu};(04UNPHDOp'\ + el4DÃVX͊})i^Ս}EP`;PA!O[ :bu+įաr. -aLjqL]? !s}GJd{aaNHc社(0TeUDzEhqcO> ccMywo4M'OpHcm!xqzlS6 "px;|"aRz;Mn ${W9g$S@%jg+S)"wxMB`+0g gEЁU)B4ԈBT 7aZu_>՞g?u dq4~u +4cXыa`]S@}Iɽ +ja]`c1^.UcT۞l,0a?[tqPbLjar+߷kB>ֈkj"A d8 6@Q '4D#44RRF5 aGZ$VqR vRSkY"KȒ}\6da9_.¦OKR 6ðoBЮp*\*J\E =D{9V rlRE +m5ۘC)j[=9ݨ +CjW+\dQ,pMy +֓wp.:GZR2Ox=%K<݁3c`E5w]?U!ùikA}jM*^=kQ(ŗ"\GGЅ̹ s*")(_jn땟]Y͓ؠ2xdNK!Z kgկUꌮ_:$?UDZ 2_Dz fh,KhB:-hrhʥF׋E&i1_m4ZjeI;Fu7bѤ|fkR^+%ܥ:_\FQN ̇mm*)hmYMƾ9ǩ߉39MfP\LEj2Ũ 4,o\s24▗ՙr9DZ_SYmYbDxEUz=B|.wxie24Cիclm~سʱh/5<ۮСw a\$agZkgi!EY۪[buDl1^3SNzz3 cJH.X;9ސۤ2v0F!zHS䇼RY pUx5<+Q-<-LիzƏ7Iҁya64u>QiZf4 r0qmZX5+5 ǝ0[Cl?:Gr iEl⥖ݖ-9փ Rk)@wD]IOY}U9Tr;<65|3-we DTR7QɃǥ0Ó|uK m-gK@}IҾ:)9`p Y|5|O܀7yh0p|H̤x~Zw>G6f;9Ay@P= x4=vJqtܭ͏$JoyTd(0 (H>| cJYБ(0,|@||  aM0= @R 4?PQ  ta@C00Y6!`1m}2+qeǜ),a`(H) 0Bu{,+FcAP\S Xn3Ҕ6o $Ia>A\dG dN2Y@LMpúl€B"]"MÄ`mfQXpڗzBbld5$Q; /W,^X GA43cԭ*( osgPk`\}erOC 8K.5Bh0 +ڎaab%l5–{GYoZp8}qח8)eϸ =joJcQ6a4oqmZpqP7&Suf'a 1XGምp#[t_#wH4cbY[571ܯ?gs6pZGn8rۋSrR`88[u4&I鑰]Є+2 g4o +deXLh3x-+qvo1Lط +Q9ZxHxˀ>$Tߕ~د8,TGy5$z'u-?۝wv$ $))lIPc /Xv#n_C=KGwn@ٜ42W\>NA?wLMs$MlQkgF}1ڛ߇ 2 '79dL#5ܣb]$U޷]YSg+r:>{ jCfq<[fq;\nH8]qjއIZ< :mȪzŭq)l|G HVzp$8wdn &4Zs-.>QsbSQ~bHM_%l%RHZ dBl + HLetd>nNiJcm\;٫,ۈ%Nv4ws"Xӥ [޸'W@6C4IWn {|6ڤGwldR@v=Oi;^}< `0Zԯ 5!j]ܰ:n81bMzG2: <؉#hUO_p@s ؝eMpE`Eļ\V6+Tgd؂ړh<1DlPrhcXMd+2=w\/ͺ})qFYdgsy];VNmD-ajlD-u3vᛱ8IOlhrpr1 Ck@cWUUUxNWtU^UT4ʌC0KTc?ԊR6)rqB߉uuGU^E5d"w}ir=)1q;@pSKF{Ľa5$v֬4}v9d fW J\8vYVs +ȮKDegPpL-4LVrLn0nhfrUkޕPi+bEXǤ1K( ",=\޳kNnN=-.s^󞒇xrQ6%6IŠ՗Em+q1 몶XwQ" @W~/V׷O灍Zهrv۸N7ª^{g3/LyDZljҸR*a=A<{xƍ*kr]JYƎB4+\ϒ~ e gġ< yǍr ϭ4Җ:"e <'[AhdM|Gs[M,s +QWse8gp 'g8FX2KPcd>sxg4?tw6nΕbc銡>:iчhF#ԌΓ6@Oqqp$,`&5vƚmK59;SτKZQu~:FDc!LYb\uROk|{6ь +kcR--Q 18Av< Fk &gozYO/o#_䎭Vz[6"Mªl32DG`K3E~z C383pղ{r3_1Nfr15c6ߜ^D +Ms4f?ߜwhţu](gt/1"Z|~m3<܌6e\q|yڡNK]ռѻ&a:#$4?iv1OY9sNjiq|^=cKk]c#2vU;+Pz;=7e7ŐǷ;uQD>\$ |mAaڝ}OWC513[tpke +jI] +0e\z˾0vinƻ -Jv8Ǵ#w>Gn Ji<NPNʈ^,\M*v\x- !,omEp/"tedi/Z4*goj/ k nb1?<9LJtS%(ŭw\5 ܖVݩww9lJ.W! +y +Ğ85,Pj5m9&JBhEKM;PHd ^M8U]Ec&:6$i U7滼攍 Y=zfu j۾ru89A4ss W~؈] h`/7ۭim(w3FM<9J]:T~i +"O7h=Z_oL ؃:,Kt* 5G:z4%9h3?:x9>fDk],0C0N(xL̆zha }!AwDtf;nFv.3p(ZnT04iu}IQ965S'IU77ZibEYXgg8Y6U4XR܏-pwjeN;*0ۛARC-նPyJAiU>W߼dDlztlz lJ r7&N9*H^xy*<RQXpQ废kVUYSk O ݋L㙚}Z0E|~/ۍ'}OO#v`IW˭5]BzU-#(tvvIb_6!ui`QZ},fZL}@!aX,llܛ `o[jڀ$T w}>?M+:$Pd] 7M\P{:6/ZStq墓f0{Z2"ۗ 5󸑹DgڗEiVK(HՂh [:16– )/H"7["Ve,ҌOnjtvw"슿r9쟔AE +?'Յ rՈ?e;YZ卝QY-H]+ +_!VԻ&dߊ +vlS/BΦ#0FWvO _f,<W +Yj +-GWOcru*˯FAzRT.RXѷJi J6nİOOciDL^^W\:u=mjF,ɬRs5ASbjV +d C{ ,t45 7QS])^ܐrn+d**e-M׍$*mZ*QӘm[N!~4lC/4m&mCcb# zKFnmDplF'j#d M"hd$d$jT$vn"Z`XUz+ŴBu/^0#IO|n@retbS*˟X0 +U@(p5AS?UOcŒ{d Svޡ =Dз8ʰ[6}׉Zt/|<-#SσX%PӒdFRP1y2<ā3\mt}+Y.q[QBpJa^;>Kz򗉪DK /yI*%tJ)ʴC5X|*Q}nupECZK+}LR)jfVKM6N⃝IxGq=Q[B5#DmS^r򒓗LaZ$[2Uz ]b.6I"IC:pi8KwPw&; V.+,DM(SU~#-S!o @BH3q K3⊘&dK4;)?ɁbF0m0e"eS )w0o(:tYk+.D+=Wzt:PLU{;P+@VnIʯ0P,&jVEe5Kn.u-j=bQҲ%Go""d5_Pť,<ߠhW}p+Bh9֏~w:򗒋#} +}zje,8)c4 ?2Dcc-ebqXPt"0#gN +k̆"z(Hda }*WB"^}~ODjcfe炓A#B{ݨva^i,%ŞFؤ&IV Ъt3+|#+ {Xo}OiG jeN; Lo.jY_f:j[1O)_ߒ7JWߔ#VN UP3e &%ߘة 닁ZĠc[h ցZ*.\~Jj ^ cG{qTQKj% ]ߡz vIߓ%He%jQv{.3f ާ %PLzɗ?5gv]~i-b,:-AF]J/x W;_ +R^L & HI%@x, +oo~e) +UYE[{P ͸rWְr_*nž#^lN߰}p>]u،.7$7P7An%V:}یŹL, p1{ 9Y -MVor4!ԪKKa)T{ٛ!`۫WehLI4yIK^t~vYMS{u2WC/d\\MՒI@w:h"Ctb\&:c76M2cgM71J +Ij If Ɛbǻ" axѱ0 +Ľ%%>%+*RwO2qiOn}QT~0v.A_~`/+N2kuYc(,Y|So`{ iL{ az, ,x5罥kX!]i}SmLq\:XRV% f8'}Y^Ҿuܧ9ճ3]^z^rW&*wlĮ뚄(i+u PH'gw@(3a)ogPԘ@\3 9,g$>/i~e8qe.@ojw-Sb^_FqGz`D #~إW7_n |]_~`76k5dTJqmK>jv'MT,8\"U=?(P@S JwW#S&v+c‰_~C +bfĞ A[N'lHUW!Uup +8hn =8S8vv~Qn#.arCtpU{tQX"Ϡ3 zCgP!G fz?݁>OA:q{G?`P̂>[Pz"n})qU]iL^XiJz3!)',~ L (!qj^g<8Ybw +E{h0^bz4o{2 +Axj#MfyŨQv^bԓl191jIz.P$s]P$u) # $p"i'An=t 9wGԤazighz*pjtTJIPpBvtqx8#EťV<_IUw~se~=Ek-^E}U+(< ҹ]rxśZ&&/tMĴ +T7DG0IM\ X&Z [M}<| I TOZ]eې4 PՖ; $g`r 8ZԢ5xo KpW>N,D?u4/oR.H gw_P"I >A bAN>!#:.]ؚ845aعieKpeFqyȔ Fnx w^6M*& RwSoVh`ƺ rm/+}fႈ҇*T5 W&W{E_%|U7 ZXP-P^)MRP|+z(fJ)ѤQs *K% Yΐ8cBi֜ ź4˸$A'ro߯̓'H?Y-@ijMbw ] kajXR)u6ԭY1G&*aXiKX^uӼGe_\|-~)j +J\ Kr͗ +;>=b?揇c5S5eC+f:rEZbܰɸm.f&]^*J EGf۟elM!|7)HO+* + Tϙ|rZh9eh _s.LBVUSK$ 4/^%jgB̖.P#)4G&Ќ 7 \*N՜>Sg2oRݾ;rjep]E4^WV5Џط3^S: Q0jLTjŵNH94a)\q'`JcX0Ntc pX̌j'=JVu֭,`L,ʵ,fX_5rMYCg 7soHZ] Y'~_?珛|߉ɕL۟/Ip{s{NY/N"QQH/1?Ιnpx!9Due Io/g]hth%"m\Nvt5/m+qq)@w%HCcN5 MJQe0(ƫ|φÆi o"721-)p͠R.1XX(di(X(X1y rB嘛ӷ~CӬ:Zi7wmM̃ ˒wAnSvxgWIz| z%IYu' + K_zu׳g]zu +wlu%e3_4kKgP3ŸȀڷp柒pooYo4^uwNqO`f%uE,'9|ЛJ_AM-Ҕ&U+cXv-)0d!@N8&-Aޥ?鱦 A I@dQ9s,]@?`)wpz̍)>(6F[Y#`gۭIIfb5v^K p!"lYys;\׬Kz Ɯ'sɜɜcd҃66%?tGc!x ! gKzY(LrEyrQ!Ϛv,p:#F&&G a "ΦB+؇ +1nқC=( Q^~$Z=ePe['M+F3dt&PbZ`}Eձ@{'}۟C/zkv{AK3~ 1ᴈPrӠHx{4cin1vbWrbf&4Kn\7yJC e/SS:Τtu 2k*ntӑ^ܐqqҁ yvQ͋Cb;񿗡qDäYpk5jpvzy4 ’鱳 e~q!+@MMCѲʉZv܌ re}[yDqG}ktb);&<'reE{#rT&{A0vC0r|s\K1VO}?v] :V+/*;Ӫ0Mk]ӿu'sh8iy_h隕WK9r;ݶ$;=8m/*鷜ròZHyYmS"k $ h dbZjMB bRV*)dpgf;ə|r&Ur6 36^M?}ђɉ|; +be:2zV@Fn䋴LaO^ryP?"ba9B-t` m+Zz[I"[eJ7@Ӷ}@PccV<ֺbpEr*?us0Q#`t_lot6X JUܒ'[_N\Z!7k 6wˠ)üUv%g -Xܞ *5{O#H콦xZum<- 2 :o8<?/7ۭfⱊ~>6 zjkT鋺EVS:/~ Hj+`~-FY1/8n4 F9ac|. #Vfx'W+'+f!:tτ] +v&݉"VZk26#Tnm`fj`>*B u M}Ck.bVvm8Zߨ&1,)U[swy +t]Djq* b8㩚?п~F_e`}.^z]wbY"vwzo>RuPQ6Bǂ< +_{AԙX&OB]G7%j `YgZ B_h 33زg~& Oࣦxl<V99ia!/ ?SHsPh)&qs%8jP:H48j!(_QWk;xJB&=TI>J2Ǻ?5|獗xǣ#aԙeۢirKmɅcX0]&:e.fQ!mEoKSLI" % *:I?gBu{'dd(ɰZPaЦ'8ƪ#QarN>bADk< JI0Ha(.oחݚɑ{F\`gLuw&͖ IEgocZd55~ *VF/VPѶVO͂~ KӨKi&och߅6 PMEٳw #DZl'V'PHzʹJr01wg\6ww-Njq% G8CX@vE8^+ٚx U x'p5^0.ɠ>lZö9rq]*L;mJ'@Fp,eI]DkzpfR&jO /58)LIDIG_Oe ח4*\bVRAmdBL ت=HkuSnnX:!l}t쒂4 yɪ]DSDDdz#tsB{$#||_.gxM~z\.{/FYh+&zHgHrth'$0]8I-Y+Rp.;Zo9?jK؛33ssUi<^wLqHp.]/Bg|I!I1?<9:Ň sN*`f&j AGC~M{N`FE;j44f` oZ!+2YRMjR1+f{qg_洝 I\ +vU֭ߐJPyMY7yӿ +)~nj}2KiP)?r|7]KER#`H#+`9X7A3УfYTW M^.GL8$[8 -Roo54{A(~쌺Jꪀ^{봡DK`n>7f9ܨX<`b q%0LELiB\$XPJ)=nQHm@bihhvx"18L 3u + L0 Ӄc0ߋbٿOhv0UÀHI 77Yn.t0[uO㘱<] >BwA4JOq:o!;_Ձ~B + D8X>fmқͳƙ]EP*}UPx:%ۑ>L?B@?jiflFZ$W1}5*X#},`{R7- 3L^ ]N/5KO2y$B}&k,y'Iʁz clG ȴDM b +`[5Y0}cJ5{\ |xӢE&Hq5G[F\pbD9&NẌRY&|1~KG.WeNz=cy‰I5Y*Lz/e!&jm*rTӞ +tv;g@lY&LzƠ&@7Tr$Ȟ][;j: +jT73-L5uIhLC?@Ci##ET;ڻaGk5EC>!K8C8HQ4lI1z| + kR-֛Wy|,$&zK$(4uGMI{xZ$pHb20AR]NstƓƤ>裸\9 +"pUiQ qU0^Qsߑ8)Q&,V]5'=[{%{Eg|:;x2Ã'ɒt; LΚ"О.'V&"Vz-3JԈUD?^YvНd8qG,ϸ7Vo_k@+'˕^UyPDJR,ϛ ;}ISH+%i+m02fG}?IS5". ~QW`eJ[McmLH7B0Zs~x:Jn3Ĕj2=u3{za kbCV]Ƭ+C=?lcJWBWm>+T1aLY] 8ɪע5-{ +,(8 G0*lXJm&*Drv׏CGhAcM?4YQBt6q[o%o坡Wj22ʨoeTa&]j-wc-:sdzL&ѻ1o )`"GLCǮ ߝîjqԯĴ#*p]M ;7V˷?lպr76ldjchM 澎A+{<ʹGxFȃ=l]ɣ_gz.lA75FcYߒLaS iMxD헢~&#녠㊏¤;!-"%aZ=gϤdknEiOj|<'f ~Bd_a.nqάGVlRr;,g-<[=Lh2E49<:i*s09ǑZt `՞e 2F:Q\".DyB1$n+ ,҉tN߽\R)ѳR¨{KzRh?t GdN LҌQtݷh!bV,60oth1ËciȼO-`x р ,/Ӹ*IrAk-r՜#D@P%"ΛIC nc\i䍧+ 5n,atb[x`$H<`P<04O[cĄ}bl00W/%-ϸF2a`L ˱KnY `=2ep#[}BL!v(L:0 @~w8wy_a4E9nJZCys/7O=BD^Aę""ӌ~:O,i 4_9HI87sIöIFѽ]5 LRN2 uӲAQ{&13B^քxȿ%"#˲d\'?A_dC&/ %`|exBrrj迬C$!AZŅa7[Z(˽R%#-q,^{{wH}ߑJY">6sid"\?~7_h/HMO,g」?Y،.&#Nm( ;zߑEi18@NԌNZ'٤}6e^#9̙lY1Gq_}JRp.MV{>ك.L +b ̺\voxYne#S}{䶷OE[ VA2dn[m吅P3}R+:tpR6#Hw#s.O 7?^pUk9;YnBIP %ߒa]MhEd9q$X&%VbJ2/`+E +D26X !NiK5WR 6J*L|'ޡ]fuKJ +:\VhcYęǃ'G/xQƋ2:LN] LLŝ% : &=\Ș4MhwH#]6HaK#v4C^2$[ Su&[fОi|,7=w6; =IxtOK5amuwٙk#E_* uZ&؍hh>>-TWr1%%=k?2o" I)pJaIS:"NA Fֺ n@d-ᜪoK!%"/]wg4|Z6'-I.1}!;j *1cό|#yRTl$E} \uwjUOqg0yqy{2z:^0ִʙbWM+)GB !vƅs?6ó1pOѤ)Fz~A>۵_R32}V> 򅦡*#$mA&`G07'P{82X^dͷ2)HW^gY=ܒj. yf$lɼ:m&g_p0ݢnȯ|-޻|gt$S>Wl~8?,YdP޹&t_Nam|83kV|E4;R/`aٙ;KPJը(%8e@XR*O~#TsJ50)fc"ӫ0iRUUc!L;sܤIۀpXw*]T(;tizm10ޖ*ULuwSGSf<屟,dhvfSIt;DkX#;3P2YI%[5\L~ GNI.WyeƔӍm: 75xG,hZ[(j$4k՝s%RH@os{T'?4 +F6i^<ȞsbY +3зpޔU /ǟ+}eu\3Sψ&5)x#t="ǙF eNg#\7/ie47qك!8+ ,+3LV.X?|?S2LU>s*LuJ~^0]Fa vMktYbAְM% 14 qC]JD, +p/S ]gR@IRD(UX0M%Dd%Y{<ޕ-DS(+"QqEqY{H}n7WűC]U]dz%N ٕ} fJgBz5A`/ۍ'XO`9gݒ`K{u[c0{>nN{ +w.vyyxwvV YvF˼S7wtHc||<;mf zLb#}Ħ/Oh7^.94( KǏ5T K H ,1BLP)#yDu:nW _c +_#0>|#&NrQ|:,$Z$漐l_>/6K:>o9sk7nxʍΤs7oBejF \dCxŊfۜ +"0CȪ)\{:o-ϋ"~MhRUZ9B% Ϗ~={mQzwxou0י<{  +ȓHFuȬ-T$:9ؠ2fr3J/gZ؀âUxۋ|.M#]Ý!I$'b/? \&bY:e<:Uf /}֦P7.a?m#%֜Gp l$0 +no̪y]dWRl#$Nвʓ׏uzjs[RKjD@ɺ0#k0/si>v7]>#7 Uxq~sc!'l 1iKFΓuՠZ6z=jhM2J.:BzI_]D[o^:kKHsFeT{VљP&dYnrZ)~zĪ, xzTEB=RN_0%0ZpU fh (@A7uP[KLx e@˩Cr!h.i).oG¸ge?p_;ēr8/נUaW)Mcvo2iTGƞԫ9T?+NB'H%/H6>aeriTK7$E }>\a+q=@bTˌD1o$XT[$/9`X;i(Ӗ ې;ؐw6d~ qcF7KƹݘzHe5#<;/ER*aGUX|JBQ-Dehqs!8mI%96`w| 1ܨ8kԀJlef + n[MpB]y;\Fz'.D_,@{Jd4}[KRP|H?(̃(n[qd=2)jQ`$ +e3 ZM!b'(r>f]Z/;PPelsY$EbW<`@llebK(ΫqA22p]h2A2u)Sep]EUcG >)/8滇m_K*fvrVeG|=me/E}V7tEA.fϊ %x0ײJ7,e0aۮi ӛ[t~@y0MCGͨ#הg%̷m QC^oadso 8CB? x@K,L) +t kYA?O2o={`q8gMWI5X*yE8@ixo9[#CNUp ]>/oЉ.G:~-_4zd=tO Ťl]C)e;nnnKK9O9W+MAa=M<9uV5pMI;#WśJu8ik+lrIm7! K +H!"Fzc2Ŕg0_Uyl01&NZi  K-_5 4v& +pWBK0ݫD.x7ED~(A#]LjE'{:'x.&|$]ŖD?M4U!C/3!aHe!=)#>T)"m]/2~ xk1E`^m=͛6WVl8hyx_Ջr`JZ;} |h݄QW?Zd)qw$3/դY/m+)4IBԧ&.}VEI4k@*"*!^׃K1]N=L CzEQ y{OlUvU[*񫲻+{@鎚*#% E%j?杢A t +lt?ȁ[~[WT%57rGS9t_ƋC~?A?XDňW=l.woԔUcaJaрON$miow %-U3Ȗ}\K #- [hp"ga#`o!` !`/b0v+5ƃ#`F@|\6<{{vPAw@8bHWtϔV~y&qT.zT<߹IѨ´|kt-Mďk +ZRI:w/>{4SVd =Fh!z5C@.ŘiMTʹv!c +VP24}n|ʒ/;L3MG0>+L slǗc=uyK/R^LqT7{I=&N ÷O"PD^LYvVߤla6 ^9)"|};tYb,de=eL(zSr"S8ᄎ S^fDJ5?-`!$ 'Wu5S@@k_ aMkїA\V/?ussi>SMiwqd aXC3ٝ?Ub.vi1萏}MpvJb9r&ΟYH͎.+e U>E :U[2և}2ꙗtYD֌kvSOT*3`.'MB siudQsR1uYRK v}yģãԨ]7ue#x| g 5yl5w[_5{!TGgOJfw6L_Jtg +cA⮇aJ(|YaZ[|[j \A[!?pϛ㻜/ϧ|JKZ墔/;|A_neohmLkf+JD"X U8xw25*PE߄ˏUgbO;DEz [=֐_ nnms|Gx׽RX +(UR>.DӇȍ^Nb34wӖuٲ-VXY>w6m=J4" S--jhFFYc_GK5jb+/Rmdb7)Oe +#~X1nMId#0`\,ɬz<84tk!OlZ3?Isw8p;a?HnEL5tr7t0 +pa[K TQDgw,`2Otj?uLPw ̛z)K=eev"mMjё^!];MTSn >6Ͳ*v97g'-tv9g,iCIZ~r1[Z6Mk֛Q!wL6@> .P +4q s w2nrl=x*R~S/:l4)tmj'c'n#.1 z쎎Ε +;=[=yäf34˨ d0Hҩ_YR} ZSڛrV9Q(^\KNJ2_c+~]<{L:`І{gmU6|}hW@2y|"tN?e f&Exosݯ>PиQ^U'90Y޸̳ւDr U5[8IC<к= [Lvz􇇷6J&zh }UV|X(rP\ 9S$1Yf柋m)]]5E١u)у/qeyTJM}z%/<^wJ 2̟5a@yla%5D(<:Hۈih9֔K엘ɥ&Ipʤ[\e,( Gƭ|e,4.B,#~ZrOWlӕeܶ%,< ޗS/68Ex-)kBǒit4U!Vs5nA9ttA ]eY=+ya™, `TR|i2`b4ׯ/sͷy=ҥUNsv;7]#}ލ_ivfO ;G|a;_Xrpe:x1,HdI{Ú.7zե|0|x)ؙjv-'kAylOr3MWh:߮z]l9N +RyXmU?!.pd .Y5kL^;a +ѿ˚:k^_heBlOmOi}_2`sOatuC7-iwG1[.pպXiuoYNLWvA#vbKa(+deL1VSOhyav@b}S_h+L]&9Efho@T-iaF.p.}d. Ba[L^ftjf(%JH 6\)Obd+84I?n luyA[D[ZpM˼^&#]9#'0pvd+?ahQY|&=Nd<>hj,m]d_p~uQe.h]/6ez.ιOx cS"fc[m> W]o3k'~=N.̏ tsԏ˜VH] Ȃ*5(tDE<>ؐheT"E:Cn@~Zl̔/r۠'۝ģw Guѵ0ux9;0* 都3>h+k^c3y@#S pn}w(S8Ʋu-g? `c?DXRqRڇI¹wJ*ɵ~2[7_B#utye)?¿莊YiPMg\(!r1u2c"4+Υ2/e_}M?s~~87M?bDN2s2($~؇pt0,$L ܺ/quQS5f+qP +7Î>}Mz߽{^6Zt-;IWi u~!- +EжPLws쌙);&(@HxERP5V 錸= 80]A;_3;ҚTFg`e?;b R6Ν3 nb$NG(=6P`:ς|>|ýh0/?ߜ䙏[8~uHcL,XVϑ,g/+F?wp#_oD/aځ[ӆW*ƪxߣ3 d 86mZZg 3bK6kI*J 9yV?ٓ/9yG ;:Nuha;ރho_ʎ 'FF·}<oT;ޞ?ny9@aX3Ŏ6cבkRUD?MB2\u沃h[$KߓԎk.ϋ<$*:@G944 f7@`%%rl!Y%cQ`V> x{ rtyTI\YuKۓ>B_…څMg ~G^6{?'"/M= P~с?^2 PR2]  +_ ZV[:{V[5/=? r})ܤ\kNb|-P_0O +Qj"hLa?d |oϤ +p2UwOҚ TPT#hNKW3='KPEX ԫ +$ꦴxbûAƨV (>Ci螶?lv{\ ڧsmΏUx5M5ˆ7]8j3Pk7:s[bJ>(3M|$9Fz 0>KV_\tMNn_!9̝vXoe}ĻWè{6ws.Y~Bɻc.F6BX; k"5`dB#Ο*ǰCV}l-G=}p#T)丏)(N@6x6OuU><bFmRB b K=]NaizOZc!NBpڻSe'|/ +h8^/n\+y*M$ݮH|gSpp;.gj9`JjNvaLONfvs+$ns qc +SBF3 b3N;Ux + +aF^fxS 9&y}0JIᣣH~MRh2j;m"X qg_h:^Λ/4cE38'I/]5 \y:/7:yF7R.Q8o.$kaEMש^Ajk;QD6٩you +öV"M=_NyB4XԊLpjMA L)LWhffff3\b9U.L xaEIΠ*ha!/*MAu 9 M-_AȟtJTW:`IDL+4f먔"G)g"^>׻M>th|+bJ,5f6iX%hf(E5_?'X% t +Sח{,eUf"SK1MY'(=%گ hQLk\ `ÉM1ybfeT̟,EPN{x&VxZހҎёkM9xp01x +ZR#p]zVh&Ѫ]$` d587uS;FNO@7 p@80Dl`5B'&G Ŀta!;06BCP4)5uW1tpA!x{N}VĖ᤭ؿ,ּuS[{fxGaX1Mkafqư?7cSy3w{3q~',#Q ͸< LFt/5};x>zMiUd,*YaO} ܩ}τV {tť$^MdqCOyp99@O(QKʐ11͛&W^QځaWGq/@8U|C8pR4l +MAS6 ,}CuZ"KP*Rcc391|cPr.[:Ai~E'ZHvA4i~iiSˣav|: ("RY󀲲GrYnI弸28 aAٽ^K]i8.q: Xgomi}2[17ZTfSAz$03]6a )%FdG4c%[Rd۰ZfEcA0ۻKdǐ_^ -qM`(T0Bkjb8 pQ\|*%)K5kt MWUgHqژVQp~,yal^2OFQ]LT-l)/Y8d޴%2%e)^ 4liB:فvT.:fNFpe ƶdԹf!89n3b>3e=))ڵ=)P[2և~_6|A4i] ӟ|k ] cBG ]BGl"Ceb?ʼny!@rw9yMJ4w+I^DH&=U>eu2*? t>fqsTpwۖ:ӴݝOE/*5ltzX/dڒn1롩e 9B(SƯu])`<Qؗgl|ISoʨcݵt}8!9~"HxoBt3ֿc  jSc2>`gMBS&aB@/H +7̗TxA- +f\fX?zBu OuDuݢ[#ZF 6F`k-G BB>?iќ4&%qwȍ;:AaV9_ '2OM^ {FdW7uݰatO:APrBm?hh=$kD-҇f?:]mFՕBn Yϳ[+׈*`*'P8Ta1d!"/7^^UɯSq!&ᥔ< d|Da$z6Ϸy<^q/5qF&k'5*FyDZN!e?7MĹVW%?~_gϏBCE2&$ڼ,^g`)@錟gA`0(W\).Q֜m=?oީCp-HwD $LJNÆִ)c~XȨL {ī82 ?^WU$OdќP8K!{TBp 8=ڐ`~L27c_k1αNMf/HQWpTL/kE +q +"-otU}JK]V2%#BW穐dM^}]U'+Dҟ%g_0?KJDWiA( +5 ^TY 7?HI>|'i-AؼLp$ +9FnvKe^^r񒋗\#VL ߍ$L4B,.E r-(!t')!2cKr,RD-Ԕ C&2cXxıչ$%T,idķt4/@x ##jdX %xGV,z3GH.`y۟LM+קcMג`r FvK&_CcK2a SA}3de$`TyS36+,zHwHHĊ&`([pNhqW"\$hE w0VR ;CDe ^āytN BX$MuI*[L$Wр >IIIC)RBL/րP+*@8n:Q7bD%x"D*X_KW^U%]K +MD^Ⱥ!hZ=ZPPz0ESbĥZW@<Fۚ|әPR¼<0 +N^ +N)|=/(q2R1mrR]<:rKE휆Tߛ0兩*5j3ZDžrkGWN.s5|jk;47YWq֭~ZǠ-I[.l'{Ƌ7^)c͈1y/oJ|y΁+}ܔ_w'Qvc~8b|+zWM;ѣDD+z=DrEpћ~Ecx@O"[Q4Ft7'RaBd`L.%N}56Wio|;=9RO%Ht+NP =xM&xƯ䡿U(VTA=W*xϺ{{l*7\#pzf<{`wRieXI=b ,/)Ǥ@0 Q\gz)M?ooZ~ssچ@ANJ4-S%nda^UDm|Eʨt1L gˉy\w]a[Y.`?MmB7=TT/[ ̦:~'ӥSEΐ#SCSNM9|I5v!Hux,7#hX}Ub6VM~7M]r6盿bb˿|u7ǻAf5%uGn+>t*3%<{_g +?._Nwןjyxww}o97Ng]IyA(WLzEqٷ;p}ݻ |ޗ34a{Ru/NgƟfs22EWMX}<4%YmZ'vOw6?V~D&M9kR֝gfá=xhH~/R鱽0I> ѯ'0ǝADFf=H1cق,fqKЀCxOac{^}y~GwfEd!X"{jpEy/MZc6lZr'҂g t*??Fp34-lZ? L$Ȑ?aW_oGϽ&\4_URP~/Y`X:i!:m@mE4`< Mj[;#xk<1qD8LgW{tY12M͌tdGAܘt&H ŦnȿUPϲQcobiH57kG &AZ1WM49KOmz=~6ZfrYh&s VG-,hf.kmgۦ5fJ-e8~'ÑFp>z1\RfX>wnI2di;GV{{c) -޿ >KRۄqMlqkguAdϲk,,RNbmm{>+/?@ρlN'){J#V +}+pǒ.:aYʳg)`&Y :^˦ilLZb~%z af(7ݶhړ=&R1.h@AiwE2W-HZkY 8W7 i{w^u/O +q$VQ.U ĚkH*w լ.r\o&=f$c8Y~<[=]dto96$~4TSЏ׊@lG͡xNCv7|jM *R}p!5`\:Lo-t> '_%JlbX +O_Cj>'BA &V[2}rk bYS+ikGF JuNͬעڣ_8[#v*rҔ_:GfUkPt +Ny ljì3iX]%퇟_߶4/?,/Ϗ-Wj=gs>?]^d]|{}_PC[S0ջm)!$pXUBz \ No newline at end of file diff --git a/core/modules/system/tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php b/core/modules/system/tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php new file mode 100644 index 0000000..0c537f5 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php @@ -0,0 +1,162 @@ +insert('entity_test_revlog') + ->fields([ + 'id', + 'revision_id', + 'type', + 'uuid', + 'langcode', + 'revision_created', + 'revision_user', + 'revision_log_message', + 'name', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'type' => 'entity_test_revlog', + 'uuid' => 'f0b962b1-391b-441b-a664-2468ad520d96', + 'langcode' => 'en', + 'revision_created' => '1476268518', + 'revision_user' => '1', + 'revision_log_message' => 'second revision', + 'name' => 'entity 1', + ]) + ->execute(); + +$connection->insert('entity_test_revlog_revision') + ->fields([ + 'id', + 'revision_id', + 'langcode', + 'revision_created', + 'revision_user', + 'revision_log_message', + 'name', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '1', + 'langcode' => 'en', + 'revision_created' => '1476268517', + 'revision_user' => '1', + 'revision_log_message' => 'first revision', + 'name' => 'entity 1', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'langcode' => 'en', + 'revision_created' => '1476268518', + 'revision_user' => '1', + 'revision_log_message' => 'second revision', + 'name' => 'entity 1', + ]) + ->execute(); + +// Data for entity type "entity_test_mul_revlog" +$connection->insert('entity_test_mul_revlog') + ->fields([ + 'id', + 'revision_id', + 'type', + 'uuid', + 'langcode', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'type' => 'entity_test_mul_revlog', + 'uuid' => '6f04027a-1cbd-46e3-a67e-72636b493d4f', + 'langcode' => 'en', + ]) + ->execute(); + +$connection->insert('entity_test_mul_revlog_field_data') + ->fields([ + 'id', + 'revision_id', + 'type', + 'langcode', + 'revision_created', + 'revision_user', + 'revision_log_message', + 'name', + 'default_langcode', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'type' => 'entity_test_mul_revlog', + 'langcode' => 'en', + 'revision_created' => '1476268518', + 'revision_user' => '1', + 'revision_log_message' => 'second revision', + 'name' => 'entity 1', + 'default_langcode' => '1', + ]) + ->execute(); + +$connection->insert('entity_test_mul_revlog_field_revision') + ->fields([ + 'id', + 'revision_id', + 'langcode', + 'revision_created', + 'revision_user', + 'revision_log_message', + 'name', + 'default_langcode', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '1', + 'langcode' => 'en', + 'revision_created' => '1476268517', + 'revision_user' => '1', + 'revision_log_message' => 'first revision', + 'name' => 'entity 1', + 'default_langcode' => '1', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'langcode' => 'en', + 'revision_created' => '1476268518', + 'revision_user' => '1', + 'revision_log_message' => 'second revision', + 'name' => 'entity 1', + 'default_langcode' => '1', + ]) + ->execute(); + +$connection->insert('entity_test_mul_revlog_revision') + ->fields([ + 'id', + 'revision_id', + 'langcode', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '1', + 'langcode' => 'en', + ]) + ->values([ + 'id' => '1', + 'revision_id' => '2', + 'langcode' => 'en', + ]) + ->execute(); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php b/core/modules/system/tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php new file mode 100644 index 0000000..59b05a5 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php @@ -0,0 +1,35 @@ +insert('config') + ->fields(array( + 'collection', + 'name', + 'data', + )) + ->values(array( + 'collection' => '', + 'name' => 'views.view.' . $views_config['id'], + 'data' => serialize($views_config), + )) + ->execute(); +} diff --git a/core/modules/system/tests/fixtures/update/views.view.entity_test_mul_revlog_for_2248983.yml b/core/modules/system/tests/fixtures/update/views.view.entity_test_mul_revlog_for_2248983.yml new file mode 100644 index 0000000..d9eba9a --- /dev/null +++ b/core/modules/system/tests/fixtures/update/views.view.entity_test_mul_revlog_for_2248983.yml @@ -0,0 +1,435 @@ +uuid: 25b89168-a8e5-4ae1-8fb5-c8efb91f0938 +langcode: en +status: true +dependencies: + module: + - entity_test_revlog +id: entity_test_mul_revlog_for_2248983 +label: entity_test_mul_revlog +module: views +description: '' +tag: '' +base_table: entity_test_mul_revlog_property_data +base_field: id +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: none + options: { } + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: mini + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: ‹‹ + next: ›› + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + name: name + info: + name: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: '-1' + empty_table: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + fields: + name: + table: entity_test_mul_revlog_property_data + field: name + id: name + entity_type: entity_test_mul_revlog + entity_field: name + plugin_id: field + relationship: none + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: { } + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + revision_created: + id: revision_created + table: entity_test_mul_revlog_property_data + field: revision_created + relationship: none + group_type: group + admin_label: '' + label: 'Revision create time' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: timestamp + settings: + date_format: medium + custom_date_format: '' + timezone: '' + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_mul_revlog + entity_field: revision_created + plugin_id: field + revision_id: + id: revision_id + table: entity_test_mul_revlog_property_data + field: revision_id + relationship: none + group_type: group + admin_label: '' + label: 'Revision ID' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_mul_revlog + entity_field: revision_id + plugin_id: field + revision_log_message: + id: revision_log_message + table: entity_test_mul_revlog_property_data + field: revision_log_message + relationship: none + group_type: group + admin_label: '' + label: 'Revision log message' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: basic_string + settings: { } + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_mul_revlog + entity_field: revision_log_message + plugin_id: field + revision_user: + id: revision_user + table: entity_test_mul_revlog_property_data + field: revision_user + relationship: none + group_type: group + admin_label: '' + label: 'Revision user' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: target_id + type: entity_reference_label + settings: + link: true + group_column: target_id + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_mul_revlog + entity_field: revision_user + plugin_id: field + filters: { } + sorts: { } + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + tags: { } diff --git a/core/modules/system/tests/fixtures/update/views.view.entity_test_revlog_for_2248983.yml b/core/modules/system/tests/fixtures/update/views.view.entity_test_revlog_for_2248983.yml new file mode 100644 index 0000000..412972c --- /dev/null +++ b/core/modules/system/tests/fixtures/update/views.view.entity_test_revlog_for_2248983.yml @@ -0,0 +1,436 @@ +uuid: 5a8b00d2-67ce-415b-9e7d-6c013bf7f6b8 +langcode: en +status: true +dependencies: + module: + - entity_test_revlog +id: entity_test_revlog_for_2248983 +label: entity_test_revlog +module: views +description: '' +tag: '' +base_table: entity_test_revlog +base_field: id +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: none + options: { } + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: mini + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + tags: + previous: ‹‹ + next: ›› + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + override: true + sticky: false + caption: '' + summary: '' + description: '' + columns: + name: name + info: + name: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + default: '-1' + empty_table: false + row: + type: fields + options: + inline: { } + separator: '' + hide_empty: false + default_field_elements: true + fields: + name: + id: name + table: entity_test_revlog + field: name + relationship: none + group_type: group + admin_label: '' + label: Name + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_revlog + entity_field: name + plugin_id: field + revision_created: + id: revision_created + table: entity_test_revlog + field: revision_created + relationship: none + group_type: group + admin_label: '' + label: 'Revision create time' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: timestamp + settings: + date_format: medium + custom_date_format: '' + timezone: '' + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_revlog + entity_field: revision_created + plugin_id: field + revision_id: + id: revision_id + table: entity_test_revlog + field: revision_id + relationship: none + group_type: group + admin_label: '' + label: 'Revision ID' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: number_integer + settings: + thousand_separator: '' + prefix_suffix: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_revlog + entity_field: revision_id + plugin_id: field + revision_log_message: + id: revision_log_message + table: entity_test_revlog + field: revision_log_message + relationship: none + group_type: group + admin_label: '' + label: 'Revision log message' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: basic_string + settings: { } + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_revlog + entity_field: revision_log_message + plugin_id: field + revision_user: + id: revision_user + table: entity_test_revlog + field: revision_user + relationship: none + group_type: group + admin_label: '' + label: 'Revision user' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: target_id + type: entity_reference_label + settings: + link: true + group_column: target_id + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: entity_test_revlog + entity_field: revision_user + plugin_id: field + filters: { } + sorts: { } + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url.query_args + tags: { } diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php deleted file mode 100644 index 4f4f4f1..0000000 --- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php +++ /dev/null @@ -1,48 +0,0 @@ -setLabel(t('Name')) + ->setDescription(t('The name of the test entity.')) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE) + ->setSetting('max_length', 32) + ->setDisplayOptions('view', array( + 'label' => 'hidden', + 'type' => 'string', + 'weight' => -5, + )) + ->setDisplayOptions('form', array( + 'type' => 'string_textfield', + 'weight' => -5, + )); + + return $fields; + } + +} diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php index 1e9fac1..f75badb 100644 --- a/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -5,7 +5,9 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Cache\Cache; use Drupal\Core\Config\Entity\ConfigEntityBase; +use Drupal\Core\Entity\ContentEntityTypeInterface; use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\views\Views; use Drupal\views\ViewEntityInterface; @@ -290,10 +292,13 @@ public function calculateDependencies() { public function preSave(EntityStorageInterface $storage) { parent::preSave($storage); + $displays = $this->get('display'); + + $this->fixTableNames($displays); + // Sort the displays. - $display = $this->get('display'); - ksort($display); - $this->set('display', array('default' => $display['default']) + $display); + ksort($displays); + $this->set('display', ['default' => $displays['default']] + $displays); // @todo Check whether isSyncing is needed. if (!$this->isSyncing()) { @@ -302,6 +307,45 @@ public function preSave(EntityStorageInterface $storage) { } /** + * Fixes table names for revision metadata fields of revisionable entities. + * + * Views for revisionable entity types using revision metadata fields might + * be using the wrong table to retrieve the fields after system_update_8300 + * has moved them correctly to the revision table. This method updates the + * views to use the correct tables. + * + * @param array &$displays + * An array containing display handlers of a view. + * + * @deprecated in Drupal 8.3.0, will be removed in Drupal 9.0.0. + */ + private function fixTableNames(array &$displays) { + // Fix wrong table names for entity revision metadata fields. + foreach ($displays as $display => $display_data) { + if (isset($display_data['display_options']['fields'])) { + foreach ($display_data['display_options']['fields'] as $property_name => $property_data) { + if (isset($property_data['entity_type']) && isset($property_data['field']) && isset($property_data['table'])) { + $entity_type = $this->entityTypeManager()->getDefinition($property_data['entity_type']); + // We need to update the table name only for revisionable entity + // types, otherwise the view is already using the correct table. + if (($entity_type instanceof ContentEntityTypeInterface) && is_subclass_of($entity_type->getClass(), FieldableEntityInterface::class) && $entity_type->isRevisionable()) { + $revision_metadata_fields = $entity_type->getRevisionMetadataKeys(); + // @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout() + $revision_table = $entity_type->getRevisionTable() ?: $entity_type->id() . '_revision'; + + // Check if this is a revision metadata field and if it uses the + // wrong table. + if (in_array($property_data['field'], $revision_metadata_fields) && $property_data['table'] != $revision_table) { + $displays[$display]['display_options']['fields'][$property_name]['table'] = $revision_table; + } + } + } + } + } + } + } + + /** * Fills in the cache metadata of this view. * * Cache metadata is set per view and per display, and ends up being stored in diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php index acb84e5..42ab859 100644 --- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php +++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php @@ -9,7 +9,6 @@ use Drupal\Core\Config\Entity\ConfigEntityType; use Drupal\Core\Entity\ContentEntityType; -use Drupal\Core\Entity\EntityType; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\Sql\DefaultTableMapping; use Drupal\Core\Field\BaseFieldDefinition; @@ -1087,7 +1086,7 @@ public function setEntityType(EntityTypeInterface $entity_type) { } -class TestEntityType extends EntityType { +class TestEntityType extends ContentEntityType { /** * Sets a specific entity key. diff --git a/core/modules/views/views.post_update.php b/core/modules/views/views.post_update.php index a4da940..b9e4c68 100644 --- a/core/modules/views/views.post_update.php +++ b/core/modules/views/views.post_update.php @@ -239,3 +239,24 @@ function views_post_update_boolean_filter_values() { /** * @} End of "addtogroup updates-8.2.x". */ + +/** + * @addtogroup updates-8.3.x + * @{ + */ + +/** + * Fix table names for revision metadata fields. + */ +function views_post_update_revision_metadata_fields() { + // The table names are fixed automatically in + // \Drupal\views\Entity\View::preSave(), so we just need to re-save all views. + $views = View::loadMultiple(); + array_walk($views, function(View $view) { + $view->save(); + }); +} + +/** + * @} End of "addtogroup updates-8.3.x". + */ diff --git a/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php b/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php index 1fd873c..b78a588 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php @@ -2,7 +2,7 @@ namespace Drupal\KernelTests\Core\Entity; -use Drupal\entity_test\Entity\EntityTestWithRevisionLog; +use Drupal\entity_test_revlog\Entity\EntityTestWithRevisionLog; use Drupal\KernelTests\KernelTestBase; use Drupal\user\Entity\User; @@ -15,7 +15,7 @@ class RevisionableContentEntityBaseTest extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = ['entity_test', 'system', 'user']; + public static $modules = ['entity_test_revlog', 'system', 'user']; /** * {@inheritdoc} @@ -31,7 +31,7 @@ protected function setUp() { public function testRevisionableContentEntity() { $user = User::create(['name' => 'test name']); $user->save(); - /** @var \Drupal\entity_test\Entity\EntityTestWithRevisionLog $entity */ + /** @var \Drupal\entity_test_revlog\Entity\EntityTestWithRevisionLog $entity */ $entity = EntityTestWithRevisionLog::create([ 'type' => 'entity_test_revlog', ]); diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php index 56b4b00..153691f 100644 --- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php @@ -533,6 +533,9 @@ public function testGetTableMappingRevisionable(array $entity_keys) { array('bundle', $entity_keys['bundle']), array('revision', $entity_keys['revision']), ))); + $this->entityType->expects($this->any()) + ->method('getRevisionMetadataKeys') + ->will($this->returnValue([])); $this->setUpEntityStorage(); @@ -573,13 +576,13 @@ public function testGetTableMappingRevisionableWithFields(array $entity_keys) { // PHPUnit does not allow for multiple data providers. $test_cases = array( array(), - array('revision_timestamp'), - array('revision_uid'), - array('revision_log'), - array('revision_timestamp', 'revision_uid'), - array('revision_timestamp', 'revision_log'), - array('revision_uid', 'revision_log'), - array('revision_timestamp', 'revision_uid', 'revision_log'), + array('revision_created' => 'revision_timestamp'), + array('revision_user' => 'revision_uid'), + array('revision_log_message' => 'revision_log'), + array('revision_created' => 'revision_timestamp', 'revision_user' => 'revision_uid'), + array('revision_created' => 'revision_timestamp', 'revision_log_message' => 'revision_log'), + array('revision_user' => 'revision_uid', 'revision_log_message' => 'revision_log'), + array('revision_created' => 'revision_timestamp', 'revision_user' => 'revision_uid', 'revision_log_message' => 'revision_log'), ); foreach ($test_cases as $revision_metadata_field_names) { $this->setUp(); @@ -590,7 +593,7 @@ public function testGetTableMappingRevisionableWithFields(array $entity_keys) { $revisionable_field_names = array('description', 'owner'); $field_names = array_merge($field_names, $revisionable_field_names); - $this->fieldDefinitions += $this->mockFieldDefinitions(array_merge($revisionable_field_names, $revision_metadata_field_names), array('isRevisionable' => TRUE)); + $this->fieldDefinitions += $this->mockFieldDefinitions(array_merge($revisionable_field_names, array_values($revision_metadata_field_names)), array('isRevisionable' => TRUE)); $this->entityType->expects($this->exactly(2)) ->method('isRevisionable') @@ -604,6 +607,10 @@ public function testGetTableMappingRevisionableWithFields(array $entity_keys) { array('revision', $entity_keys['revision']), ))); + $this->entityType->expects($this->any()) + ->method('getRevisionMetadataKeys') + ->will($this->returnValue($revision_metadata_field_names)); + $this->setUpEntityStorage(); $mapping = $this->entityStorage->getTableMapping(); @@ -615,7 +622,7 @@ public function testGetTableMappingRevisionableWithFields(array $entity_keys) { $expected = array_merge( array($entity_keys['id'], $entity_keys['revision']), $revisionable_field_names, - $revision_metadata_field_names + array_values($revision_metadata_field_names) ); $this->assertEquals($expected, $mapping->getFieldNames('entity_test_revision')); @@ -760,6 +767,11 @@ public function testGetTableMappingRevisionableTranslatable(array $entity_keys) 'uuid' => $entity_keys['uuid'], 'langcode' => 'langcode', ); + $revision_metadata_keys = array( + 'revision_created' => 'revision_timestamp', + 'revision_user' => 'revision_uid', + 'revision_log_message' => 'revision_log' + ); $this->entityType->expects($this->atLeastOnce()) ->method('isRevisionable') @@ -779,6 +791,9 @@ public function testGetTableMappingRevisionableTranslatable(array $entity_keys) array('revision', $entity_keys['revision']), array('langcode', $entity_keys['langcode']), ))); + $this->entityType->expects($this->any()) + ->method('getRevisionMetadataKeys') + ->will($this->returnValue($revision_metadata_keys)); $this->setUpEntityStorage(); @@ -809,6 +824,7 @@ public function testGetTableMappingRevisionableTranslatable(array $entity_keys) $entity_keys['revision'], $entity_keys['langcode'], ))); + $expected = array_merge($expected, array_values($revision_metadata_keys)); $actual = $mapping->getFieldNames('entity_test_revision'); $this->assertEquals($expected, $actual); // The UUID is not stored on the data table. @@ -864,13 +880,13 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent // PHPUnit does not allow for multiple data providers. $test_cases = array( array(), - array('revision_timestamp'), - array('revision_uid'), - array('revision_log'), - array('revision_timestamp', 'revision_uid'), - array('revision_timestamp', 'revision_log'), - array('revision_uid', 'revision_log'), - array('revision_timestamp', 'revision_uid', 'revision_log'), + array('revision_created' => 'revision_timestamp'), + array('revision_user' => 'revision_uid'), + array('revision_log_message' => 'revision_log'), + array('revision_created' => 'revision_timestamp', 'revision_user' => 'revision_uid'), + array('revision_created' => 'revision_timestamp', 'revision_log_message' => 'revision_log'), + array('revision_user' => 'revision_uid', 'revision_log_message' => 'revision_log'), + array('revision_created' => 'revision_timestamp', 'revision_user' => 'revision_uid', 'revision_log_message' => 'revision_log'), ); foreach ($test_cases as $revision_metadata_field_names) { $this->setUp(); @@ -880,7 +896,7 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent $this->fieldDefinitions = $this->mockFieldDefinitions($field_names); $revisionable_field_names = array('description', 'owner'); - $this->fieldDefinitions += $this->mockFieldDefinitions(array_merge($revisionable_field_names, $revision_metadata_field_names), array('isRevisionable' => TRUE)); + $this->fieldDefinitions += $this->mockFieldDefinitions(array_merge($revisionable_field_names, array_values($revision_metadata_field_names)), array('isRevisionable' => TRUE)); $this->entityType->expects($this->atLeastOnce()) ->method('isRevisionable') @@ -900,6 +916,9 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent array('revision', $entity_keys['revision']), array('langcode', $entity_keys['langcode']), ))); + $this->entityType->expects($this->any()) + ->method('getRevisionMetadataKeys') + ->will($this->returnValue($revision_metadata_field_names)); $this->setUpEntityStorage(); @@ -937,7 +956,7 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent $entity_keys['id'], $entity_keys['revision'], $entity_keys['langcode'], - )), $revision_metadata_field_names); + )), array_values($revision_metadata_field_names)); $actual = $mapping->getFieldNames('entity_test_revision'); $this->assertEquals($expected, $actual); // The UUID is not stored on the data table.