diff --git a/core/lib/Drupal/Core/Entity/RevisionableSchemaConverter.php b/core/lib/Drupal/Core/Entity/RevisionableSchemaConverter.php deleted file mode 100644 index 1be83fc..0000000 --- a/core/lib/Drupal/Core/Entity/RevisionableSchemaConverter.php +++ /dev/null @@ -1,322 +0,0 @@ -lastInstalledSchemaRepository = $last_installed_schema_repository; - $this->entityTypeManager = $entity_type_manager; - $this->entityDefinitionUpdateManager = $entity_definition_update_manager; - $this->entityFieldManager = $entity_field_manager; - $this->database = $database; - } - - /** - * {@inheritdoc} - */ - public function convertSchema($entity_type_id, $options = []) { - $default_options = [ - 'revision' => 'revision_id', - 'revision_table' => $entity_type_id . '_revision', - 'revision_data_table' => $entity_type_id . '_field_revision', - 'revision_created' => 'revision_created', - 'revision_user' => 'revision_user', - 'revision_log_message' => 'revision_log_message', - 'langcode' => 'langcode', - ]; - $options = array_merge($default_options, $options); - $this->updateEntityType($entity_type_id, $options); - $this->createTables($entity_type_id); - $this->installRevisionableFields($entity_type_id, $options); - } - - /** - * {@inheritdoc} - */ - public function copyData(EntityTypeInterface $entity_type, array &$sandbox) { - // If 'progress' is not set, then this will be the first run of the batch. - $base_table = $entity_type->getBaseTable(); - if (!isset($sandbox['progress'])) { - $sandbox['progress'] = 0; - $sandbox['current_id'] = 0; - $sandbox['max'] = $this->database->select($base_table) - ->countQuery() - ->execute() - ->fetchField(); - } - - $id = $entity_type->getKey('id'); - - // Get the next 5 entity IDs to migrate. - $entity_ids = $this->database->select($base_table) - ->fields($base_table, [$id]) - ->condition($id, $sandbox['current_id'], '>') - ->range(0, 5) - ->execute() - ->fetchAllKeyed(0, 0); - - foreach ($entity_ids as $entity_id) { - $this->copySingleEntity($entity_type, $entity_id); - $sandbox['progress']++; - $sandbox['current_id'] = $entity_id; - } - $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); - } - - protected function getTableData($table_name, array $conditions) { - $query = $this->database->select($table_name, 't') - ->fields('t'); - - foreach ($conditions as $field => $value) { - $query->condition($field, $value); - } - - return $query->execute()->fetchAll(\PDO::FETCH_ASSOC); - } - - protected function copySingleEntity(EntityTypeInterface $entity_type, $entity_id) { - /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */ - $table_mapping = $this->entityTypeManager->getStorage($entity_type->id()) - ->getTableMapping(); - - $id_key = $entity_type->getKey('id'); - $revision_key = $entity_type->getKey('revision'); - - // Copy data to the revision base table. - $base_table = $entity_type->getBaseTable(); - $revision_table = $entity_type->getRevisionTable(); - $revision_column_names = $table_mapping->getAllColumns($revision_table); - - $base_table_data = $this->getTableData($base_table, [$id_key => $entity_id]); - $this->database->upsert($base_table) - ->key($id_key) - ->fields((array) reset($base_table_data) + [$revision_key => $entity_id]) - ->execute(); - $this->database->upsert($revision_table) - ->key($id_key) - ->fields(array_intersect_key((array) reset($base_table_data) + [$revision_key => $entity_id], array_flip($revision_column_names))) - ->execute(); - - // Copy data to the revision data table. - if ($data_table = $entity_type->getDataTable()) { - $data_table_column_names = $table_mapping->getAllColumns($data_table); - $revision_data_table = $entity_type->getRevisionDataTable(); - $revision_data_column_names = $table_mapping->getAllColumns($revision_data_table); - $data_table_data = $this->getTableData($data_table, [$id_key => $entity_id]); - - // Note: These values could be by language. - foreach ($data_table_data as $values) { - $primary_keys_data = [$id_key => $entity_id]; - $primary_keys_revision_data = [$revision_key => $entity_id]; - if ($entity_type->hasKey('langcode')) { - $langcode_key = $entity_type->getKey('langcode'); - $primary_keys_data[$langcode_key] = $values[$langcode_key]; - $primary_keys_revision_data[$langcode_key] = $values[$langcode_key]; - } - - $data = (array) $values + [$revision_key => $entity_id]; - $this->database->merge($data_table) - ->keys($primary_keys_data) - ->insertFields(array_intersect_key($data, array_flip($data_table_column_names))) - ->updateFields(array_intersect_key($data, array_flip($data_table_column_names))) - ->execute(); - - $this->database->merge($revision_data_table) - ->keys($primary_keys_revision_data) - ->insertFields(array_intersect_key($data, array_flip($revision_data_column_names))) - ->updateFields(array_intersect_key($data, array_flip($revision_data_column_names))) - ->execute(); - } - } - - // Copy data to the dedicated tables. - $dedicated_fields = array_filter($this->entityFieldManager->getFieldStorageDefinitions($entity_type->id()), function (FieldStorageDefinitionInterface $field_storage) use ($table_mapping) { - return $table_mapping->requiresDedicatedTableStorage($field_storage); - }); - - foreach ($dedicated_fields as $dedicated_field => $field_storage) { - $dedicated_table_name = $table_mapping->getFieldTableName($dedicated_field); - $dedicated_column_names = $table_mapping->getAllColumns($dedicated_table_name); - $dedicated_revision_table = $table_mapping->getDedicatedRevisionTableName($field_storage); - $dedicated_revision_column_names = $table_mapping->getAllColumns($dedicated_revision_table); - $dedicated_table_data = $this->getTableData($dedicated_table_name, ['entity_id' => $entity_id]); - - // Note: These values could be by language and delta. - foreach ($dedicated_table_data as $values) { - - $primary_keys_data = [ - 'entity_id' => $entity_id, - 'delta' => $values['delta'], - ]; - $primary_keys_revision_data = [ - $revision_key => $entity_id, - 'delta' => $values['delta'], - ]; - if ($entity_type->hasKey('langcode')) { - $primary_keys_data['langcode'] = $values['langcode']; - $primary_keys_revision_data['langcode'] = $values['langcode']; - } - - $data = (array) $values + ['revision_id' => $entity_id]; - $this->database->merge($dedicated_table_name) - ->keys($primary_keys_data) - ->insertFields(array_intersect_key($data, array_flip($dedicated_column_names))) - ->updateFields(array_intersect_key($data, array_flip($dedicated_column_names))) - ->execute(); - - $this->database->merge($dedicated_revision_table) - ->keys($primary_keys_revision_data) - ->insertFields(array_intersect_key($data, array_flip($dedicated_revision_column_names))) - ->updateFields(array_intersect_key($data, array_flip($dedicated_revision_column_names))) - ->execute(); - } - } - } - - /** - * Updates installed entity type definition. - * - * @param string $entity_type_id - * ID of the entity type to update. - * @param array $options - * Options to update the entity type with. - */ - protected function updateEntityType($entity_type_id, $options) { - $last_entity_type = $this->lastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id); - $keys = $last_entity_type->getKeys(); - $keys['revision'] = $options['revision']; - $last_entity_type->set('entity_keys', $keys); - $last_entity_type->set('revision_table', $options['revision_table']); - $last_entity_type->set('revision_data_table', $options['revision_data_table']); - $this->lastInstalledSchemaRepository->setLastInstalledDefinition($last_entity_type); - } - - /** - * Creates missing tables. - * - * @param string $entity_type_id - * ID of the entity type to update. - */ - protected function createTables($entity_type_id) { - $storage = $this->entityTypeManager->getStorage($entity_type_id); - $entity_type = $this->entityDefinitionUpdateManager->getEntityType($entity_type_id); - if (method_exists($storage, 'entityTypeResolveMissingSchema')) { - $storage->entityTypeResolveMissingSchema($entity_type); - } - } - - /** - * Installs new fields. - * - * @param string $entity_type_id - * ID of the entity type to update. - * @param array $options - * Options to update the entity type with. - */ - protected function installRevisionableFields($entity_type_id, $options) { - $revision_id = BaseFieldDefinition::create('integer') - ->setLabel(new TranslatableMarkup('Revision ID')) - ->setReadOnly(TRUE) - // @todo Fix the entity key to be unassigned as well. - ->setSetting('unsigned', TRUE); - $this->entityDefinitionUpdateManager - ->installFieldStorageDefinition($options['revision'], $entity_type_id, $entity_type_id, $revision_id); - - $revision_created = BaseFieldDefinition::create('created') - ->setLabel(t('Revision create time')) - ->setDescription(t('The time that the current revision was created.')) - ->setRevisionable(TRUE); - $this->entityDefinitionUpdateManager - ->installFieldStorageDefinition($options['revision_created'], $entity_type_id, $entity_type_id, $revision_created); - - $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); - $this->entityDefinitionUpdateManager - ->installFieldStorageDefinition($options['revision_user'], $entity_type_id, $entity_type_id, $revision_user); - - $revision_log_message = BaseFieldDefinition::create('string_long') - ->setLabel(t('Revision log message')) - ->setDescription(t('Briefly describe the changes you have made.')) - ->setRevisionable(TRUE) - ->setDefaultValue('') - ->setDisplayOptions('form', [ - 'type' => 'string_textarea', - 'weight' => 25, - 'settings' => [ - 'rows' => 4, - ], - ]); - $this->entityDefinitionUpdateManager - ->installFieldStorageDefinition($options['revision_log_message'], $entity_type_id, $entity_type_id, $revision_log_message); - - /** @var \Drupal\Core\Field\FieldDefinitionInterface[] $field_definitions */ - $field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($entity_type_id); - foreach ($field_definitions as $field_definition) { - $this->entityDefinitionUpdateManager->updateFieldStorageDefinition($field_definition); - } - - $schema = $this->database->schema(); - $schema->dropPrimaryKey($options['revision_data_table']); - $schema->addPrimaryKey($options['revision_data_table'], [$options['revision'], $options['langcode']]); - } - -} diff --git a/core/lib/Drupal/Core/Entity/RevisionableSchemaConverterInterface.php b/core/lib/Drupal/Core/Entity/RevisionableSchemaConverterInterface.php deleted file mode 100644 index 7239af4..0000000 --- a/core/lib/Drupal/Core/Entity/RevisionableSchemaConverterInterface.php +++ /dev/null @@ -1,29 +0,0 @@ -entityTypeId = $entity_type_id; + $this->entityTypeManager = $entity_type_manager; + $this->entityDefinitionUpdateManager = $entity_definition_update_manager; + $this->lastInstalledSchemaRepository = $last_installed_schema_repository; + $this->database = $database; + } + + /** + * Converts the schema of an entity type with existing data to revisionable. + * + * @param array $sandbox + * The sandbox array from a hook_update_N() implementation. + * @param array $schema + * The database schema array that we are updating to. This is usually + * generated by + * \Drupal\Core\Entity\Sql\RevisionableSchemaConverter::getFullEntitySchema(). + * @param string $revision_table + * The name of the revision table for the updated entity type. + * @param string $revision_data_table + * (optional) The name of the revision data table for the updated entity + * type. Defaults to NULL. + * @param string[] $fields_to_update + * (optional) An array of field names that should be converted to be + * revisionable. Note that the 'langcode' field, if present, is updated + * automatically. Defaults to an empty array. + */ + public function convertSchema(array &$sandbox, array $schema, $revision_key, $revision_table, $revision_data_table = NULL, array $fields_to_update = []) { + // If 'progress' is not set, then this will be the first run of the batch, + // so we need to initialize the updated entity type and field storage + // definitions and create the temporary tables. + if (!isset($sandbox['progress'])) { + $entity_type = $this->lastInstalledSchemaRepository->getLastInstalledDefinition($this->entityTypeId); + $storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($this->entityTypeId); + + $sandbox['entity_type'] = $this->updateEntityTypeDefinition($entity_type, $revision_key, $revision_table, $revision_data_table); + $sandbox['storage_definitions'] = $this->updateFieldStorageDefinitions($entity_type, $storage_definitions, $fields_to_update); + + // @todo Instead of switching the wrapped entity type, we should be able + // to instantiate a new table mapping for each entity type definition. + // See https://www.drupal.org/node/2274017. + $storage = $this->entityTypeManager->getStorage($entity_type->id()); + $storage->setEntityType($entity_type); + + /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */ + $sandbox['table_mapping'] = $storage->getTableMapping($sandbox['storage_definitions']); + + // Create the new tables using temporary table names. + $this->createTables($schema); + } + + // Copy over the existing data to the new temporary tables. + $this->copyData($sandbox); + + // If the data copying has finished successfully, we can drop the existing + // tables and call the appropriate update mechanisms. + if ($sandbox['#finished'] === 1) { + // Replace the original tables with the temporary ones. + $this->replaceTables($sandbox, $schema); + + // Update the entity type definition. + $this->lastInstalledSchemaRepository->setLastInstalledDefinition($sandbox['entity_type']); + $this->entityDefinitionUpdateManager->updateEntityType($sandbox['entity_type']); + + // Update the field storage definitions. + static::getStorageSchemaHandler($sandbox['entity_type'])->updateFieldSchemaData($sandbox['storage_definitions']); + foreach ($sandbox['storage_definitions'] as $field_name => $storage_definition) { + if ($field_name === $sandbox['entity_type']->getKey('revision')) { + $this->entityDefinitionUpdateManager->installFieldStorageDefinition($storage_definition->getName(), $sandbox['entity_type']->id(), $sandbox['entity_type']->getProvider(), $storage_definition); + } + else { + $this->entityDefinitionUpdateManager->updateFieldStorageDefinition($storage_definition); + } + } + } + } + + /** + * Copies existing data to new tables. + * + * @param array $sandbox + * The sandbox array from a hook_update_N() implementation. + */ + protected function copyData(array &$sandbox) { + $entity_type = $sandbox['entity_type']; + $storage_definitions = $sandbox['storage_definitions']; + /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */ + $table_mapping = $sandbox['table_mapping']; + + // If 'progress' is not set, then this will be the first run of the batch. + $base_table = $entity_type->getBaseTable(); + if (!isset($sandbox['progress'])) { + $sandbox['progress'] = 0; + $sandbox['current_id'] = 0; + $sandbox['max'] = $this->database->select($base_table) + ->countQuery() + ->execute() + ->fetchField(); + } + + $id = $entity_type->getKey('id'); + + // Get the next 50 entity IDs to migrate. + $entity_ids = $this->database->select($base_table) + ->fields($base_table, [$id]) + ->condition($id, $sandbox['current_id'], '>') + ->range(0, 50) + ->execute() + ->fetchAllKeyed(0, 0); + + foreach ($entity_ids as $entity_id) { + $this->copySingleEntity($entity_type, $storage_definitions, $table_mapping, $entity_id); + $sandbox['progress']++; + $sandbox['current_id'] = $entity_id; + } + $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); + } + + /** + * Gets field data for an entity table. + * + * @param string $table_name + * The entity table name. + * @param array $conditions + * An array of database conditions. + * + * @return array + * An array of field data for the specified entity table. + */ + protected function getTableData($table_name, array $conditions) { + $query = $this->database->select($table_name, 't') + ->fields('t'); + + foreach ($conditions as $field => $value) { + $query->condition($field, $value); + } + + return $query->execute()->fetchAll(\PDO::FETCH_ASSOC); + } + + /** + * Copies field data for an entity. + * + * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type + * The entity type definition. + * @param \Drupal\Core\Field\FieldStorageDefinitionInterface[] $storage_definitions + * An array of field storage definitions. + * @param \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping + * The table mapping. + * @param int|string $entity_id + * The entity ID. + */ + protected function copySingleEntity(ContentEntityTypeInterface $entity_type, array $storage_definitions, DefaultTableMapping $table_mapping, $entity_id) { + $id_key = $entity_type->getKey('id'); + $revision_key = $entity_type->getKey('revision'); + + // Copy data to the revision base table. + $base_table = $entity_type->getBaseTable(); + $revision_table = $entity_type->getRevisionTable(); + $revision_column_names = $table_mapping->getAllColumns($revision_table); + + $base_table_data = $this->getTableData($base_table, [$id_key => $entity_id]); + $this->database->insert($this->getTempTableName($base_table)) + ->fields((array) reset($base_table_data) + [$revision_key => $entity_id]) + ->execute(); + $this->database->insert($this->getTempTableName($revision_table)) + ->fields(array_intersect_key((array) reset($base_table_data) + [$revision_key => $entity_id], array_flip($revision_column_names))) + ->execute(); + + // Copy data to the revision data table. + if ($entity_type->isTranslatable()) { + $data_table = $entity_type->getDataTable(); + $revision_data_table = $entity_type->getRevisionDataTable(); + $data_table_column_names = $table_mapping->getAllColumns($data_table); + $revision_data_column_names = $table_mapping->getAllColumns($revision_data_table); + $data_table_data = $this->getTableData($data_table, [$id_key => $entity_id]); + + // Note: These values could be by language. + foreach ($data_table_data as $values) { + $primary_keys_data = [$id_key => $entity_id]; + $primary_keys_revision_data = [$revision_key => $entity_id]; + if ($entity_type->hasKey('langcode')) { + $langcode_key = $entity_type->getKey('langcode'); + $primary_keys_data[$langcode_key] = $values[$langcode_key]; + $primary_keys_revision_data[$langcode_key] = $values[$langcode_key]; + } + + $data = (array) $values + [$revision_key => $entity_id]; + $this->database->insert($this->getTempTableName($data_table)) + ->fields(array_intersect_key($data, array_flip($data_table_column_names))) + ->execute(); + + $this->database->insert($this->getTempTableName($revision_data_table)) + ->fields(array_intersect_key($data, array_flip($revision_data_column_names))) + ->execute(); + } + } + + // Copy data to the dedicated tables. + $dedicated_fields = array_filter($storage_definitions, function (FieldStorageDefinitionInterface $field_storage) use ($table_mapping) { + return $table_mapping->requiresDedicatedTableStorage($field_storage); + }); + + // For copying the data of dedicated field tables we can simply use the + // "INSERT INTO ... SELECT * ..." syntax. + foreach ($dedicated_fields as $dedicated_field => $field_storage) { + $dedicated_table_name = $table_mapping->getFieldTableName($dedicated_field); + $dedicated_revision_table = $table_mapping->getDedicatedRevisionTableName($field_storage); + + $query = $this->database->select($dedicated_table_name, 'dt') + ->fields('dt') + ->condition('entity_id', $entity_id); + + $this->database->insert($this->getTempTableName($dedicated_table_name)) + ->from($query) + ->execute(); + $this->database->insert($this->getTempTableName($dedicated_revision_table)) + ->from($query) + ->execute(); + } + } + + /** + * Updates the installed entity type definition. + * + * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type + * A content entity type definition. + * @param string $revision_key + * The value of the entity type revision key. + * @param string $revision_table + * The name of the revision table. + * @param string $revision_data_table + * (optional) The name of the revision data table. + * + * @return \Drupal\Core\Entity\ContentEntityTypeInterface + * The udpated entity type definition. + */ + protected function updateEntityTypeDefinition(ContentEntityTypeInterface $entity_type, $revision_key, $revision_table, $revision_data_table = NULL) { + $keys = $entity_type->getKeys(); + $keys['revision'] = $revision_key; + $entity_type->set('entity_keys', $keys); + $entity_type->set('revision_table', $revision_table); + if ($revision_data_table) { + $entity_type->set('revision_data_table', $revision_data_table); + } + + return $entity_type; + } + + /** + * Updates field definitions to be revisionable. + * + * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type + * A content entity type definition. + * @param \Drupal\Core\Field\FieldStorageDefinitionInterface[] $storage_definitions + * An array of field storage definitions. + * @param array $fields_to_update + * (optional) An array of field names for which to enable revision support. + * Defaults to an empty array. + * + * @return \Drupal\Core\Field\FieldStorageDefinitionInterface[] + * An array of updated field storage definitions. + */ + protected function updateFieldStorageDefinitions(ContentEntityTypeInterface $entity_type, array $storage_definitions, array $fields_to_update = []) { + // Update the 'langcode' field manually, as it is configure in the base + // content entity field definitions. + if ($entity_type->hasKey('langcode')) { + $fields_to_update = array_merge([$entity_type->getKey('langcode')], $fields_to_update); + } + + foreach ($fields_to_update as $field_name) { + // Configurable fields are always revisionable, so we only need to care + // about base fields. + if ($storage_definitions[$field_name]->isBaseField()) { + $storage_definitions[$field_name]->setRevisionable(TRUE); + } + } + + // Add the revision ID field. + $storage_definitions[$entity_type->getKey('revision')] = BaseFieldDefinition::create('integer') + ->setName($entity_type->getKey('revision')) + ->setTargetEntityTypeId($entity_type->id()) + ->setTargetBundle(NULL) + ->setLabel(new TranslatableMarkup('Revision ID')) + ->setReadOnly(TRUE) + ->setSetting('unsigned', TRUE); + + return $storage_definitions; + } + + /** + * Creates the entity tables with the new schema. + * + * @param array $schema + * The Schema API array. + */ + protected function createTables(array $schema) { + foreach ($schema as $table_name => $table_schema) { + if ($this->database->schema()->tableExists($this->getTempTableName($table_name))) { + $this->database->schema()->dropTable($this->getTempTableName($table_name)); + } + + $this->database->schema()->createTable($this->getTempTableName($table_name), $table_schema); + } + } + + /** + * Replaces the existing entity tables with the new ones. + * + * @param array $sandbox + * The sandbox array from a hook_update_N() implementation. + * @param array $schema + * The Schema API array. + */ + protected function replaceTables(array $sandbox, array $schema) { + /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */ + $table_mapping = $sandbox['table_mapping']; + + // Delete all the existing entity tables. + $table_names = array_unique(array_merge($table_mapping->getTableNames(), $table_mapping->getDedicatedTableNames())); + foreach ($table_names as $table_name) { + $this->database->schema()->dropTable($table_name); + } + + + // Rename the temporary tables to their actual table names. + foreach ($schema as $table_name => $table_schema) { + $this->database->schema()->renameTable($this->getTempTableName($table_name), $table_name); + } + } + + /** + * Generates a temporary table name. + * + * The method accounts for a maximum table name length of 64 characters. + * + * @param string $table_name + * The initial table name. + * + * @return string + * The final table name. + */ + protected function getTempTableName($table_name) { + $prefix = 'rev_tmp_'; + $tmp_table_name = $prefix . $table_name; + + // Limit the string to 48 characters, keeping a 16 characters margin for db + // prefixes. + if (strlen($table_name) > 48) { + $short_table_name = substr($table_name, 0, 30); + $table_hash = substr(hash('sha256', $table_name), 0, 10); + + $tmp_table_name = $prefix . $short_table_name . $table_hash; + } + return $tmp_table_name; + } + + /** + * Returns the full schema definition for an entity type. + * + * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type + * A content entity type definition. + * @param \Drupal\Core\Field\FieldStorageDefinitionInterface[] $storage_definitions + * An array of field storage definitions. + * + * @return array + * A Schema API array describing the entity schema, including dedicated + * field tables. + */ + public static function getFullEntitySchema(ContentEntityTypeInterface $entity_type, array $storage_definitions) { + $schema_handler = static::getStorageSchemaHandler($entity_type); + return $schema_handler->getFullEntitySchema($entity_type, $storage_definitions); + } + + /** + * Gets the entity type's storage schema object. + * + * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type + * A content entity type definition. + * + * @return \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema + * The schema handler object. + */ + protected static function getStorageSchemaHandler(ContentEntityTypeInterface $entity_type) { + $entity_manager = \Drupal::entityManager(); + $storage = $entity_manager->getStorage($entity_type->id()); + $database = \Drupal::database(); + + $class = $entity_type->getHandlerClass('storage_schema') ?: 'Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema'; + return new $class($entity_manager, $entity_type, $storage, $database); + } + + /** + * Returns the representation of a variable with short style array syntax. + * + * @param mixed $var + * The variable to export. + * @param string $indent + * (optional) And optional string to use for indentation. Defaults to an + * empty string. + * + * @return mixed + * The variable representation when the return parameter is used and + * evaluates to TRUE. + */ + public static function varExportShortArraySyntax($var, $indent = '') { + switch (gettype($var)) { + case "string": + return "'" . addcslashes($var, "\\\$\"\r\n\t\v\f") . "'"; + case "array": + $indexed = array_keys($var) === range(0, count($var) - 1); + $r = []; + foreach ($var as $key => $value) { + $r[] = "$indent " + . ($indexed ? '' : self::varExportShortArraySyntax($key) . ' => ') + . self::varExportShortArraySyntax($value, "$indent "); + } + return "[\n" . implode(",\n", $r) . (!empty($r) ? ',': '') . "\n" . $indent . ']'; + case "boolean": + return $var ? "TRUE" : "FALSE"; + default: + return var_export($var, TRUE); + } + } + +} diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php index 9ba0038..0854220 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php @@ -1337,15 +1337,6 @@ protected function deleteRevisionFromDedicatedTables(ContentEntityInterface $ent /** * {@inheritdoc} */ - public function entityTypeResolveMissingSchema(EntityTypeInterface $entity_type) { - $this->wrapSchemaException(function () use ($entity_type) { - $this->getStorageSchema()->entityTypeResolveMissingSchema($entity_type); - }); - } - - /** - * {@inheritdoc} - */ public function requiresEntityStorageSchemaChanges(EntityTypeInterface $entity_type, EntityTypeInterface $original) { return $this->getStorageSchema()->requiresEntityStorageSchemaChanges($entity_type, $original); } diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php index 4fcbfba..6a9e4e1 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php @@ -121,6 +121,52 @@ protected function installedStorageSchema() { } /** + * Returns the full schema definition for an entity type. + * + * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type + * A content entity type definition. + * @param \Drupal\Core\Field\FieldStorageDefinitionInterface[] $storage_definitions + * An array of field storage definitions. + * + * @return array + * A Schema API array describing the entity schema, including dedicated + * field tables. + */ + public function getFullEntitySchema(ContentEntityTypeInterface $entity_type, array $storage_definitions) { + $schema = $this->getEntitySchema($entity_type, TRUE); + + $table_mapping = $this->storage->getTableMapping($storage_definitions); + foreach ($storage_definitions as $storage_definition) { + if ($table_mapping->requiresDedicatedTableStorage($storage_definition)) { + $schema += $this->getDedicatedTableSchema($storage_definition, $entity_type); + } + } + + return $schema; + } + + /** + * Updates the field schema data for the given field storage definitions. + * + * @param \Drupal\Core\Field\FieldStorageDefinitionInterface[] $storage_definitions + * An array of field storage definitions. + */ + public function updateFieldSchemaData(array $storage_definitions) { + $table_mapping = $this->storage->getTableMapping($storage_definitions); + foreach ($storage_definitions as $field_storage_definition) { + if ($table_mapping->requiresDedicatedTableStorage($field_storage_definition)) { + $schema = $this->getDedicatedTableSchema($field_storage_definition); + $this->saveFieldSchemaData($field_storage_definition, $schema); + } + elseif ($table_mapping->allowsSharedTableStorage($field_storage_definition)) { + // The shared tables are already fully created, but we need to save the + // per-field schema definitions for later use. + $this->createSharedTableSchema($field_storage_definition, TRUE); + } + } + } + + /** * {@inheritdoc} */ public function requiresEntityStorageSchemaChanges(EntityTypeInterface $entity_type, EntityTypeInterface $original) { @@ -227,39 +273,6 @@ protected function getSchemaFromStorageDefinition(FieldStorageDefinitionInterfac /** * {@inheritdoc} */ - public function entityTypeResolveMissingSchema(EntityTypeInterface $entity_type) { - $this->checkEntityType($entity_type); - $schema_handler = $this->database->schema(); - - // Create entity tables. - $schema = $this->getEntitySchema($entity_type, TRUE); - foreach ($schema as $table_name => $table_schema) { - if (!$schema_handler->tableExists($table_name)) { - $schema_handler->createTable($table_name, $table_schema); - } - } - - // Create dedicated field tables. - $field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type->id()); - $table_mapping = $this->storage->getTableMapping($field_storage_definitions); - foreach ($field_storage_definitions as $field_storage_definition) { - if ($table_mapping->requiresDedicatedTableStorage($field_storage_definition)) { - $this->createDedicatedTableSchema($field_storage_definition); - } - elseif ($table_mapping->allowsSharedTableStorage($field_storage_definition)) { - // The shared tables are already fully created, but we need to save the - // per-field schema definitions for later use. - $this->createSharedTableSchema($field_storage_definition, TRUE); - } - } - - // Save data about entity indexes and keys. - $this->saveEntitySchemaData($entity_type, $schema); - } - - /** - * {@inheritdoc} - */ public function requiresEntityDataMigration(EntityTypeInterface $entity_type, EntityTypeInterface $original) { // If the original storage has existing entities, or it is impossible to // determine if that is the case, require entity data to be migrated. diff --git a/core/modules/shortcut/shortcut.install b/core/modules/shortcut/shortcut.install index dbed0f5..8df408f 100644 --- a/core/modules/shortcut/shortcut.install +++ b/core/modules/shortcut/shortcut.install @@ -67,40 +67,3 @@ function shortcut_uninstall() { \Drupal::configFactory()->getEditable('seven.settings')->clear('third_party_settings.shortcut')->save(TRUE); } } - -/** - * Convert Shortcut entity schema. - */ -function shortcut_update_8001() { - $schema_converter = new \Drupal\Core\Entity\RevisionableSchemaConverter( - \Drupal::service('entity.last_installed_schema.repository'), - \Drupal::service('entity_type.manager'), - \Drupal::service('entity.definition_update_manager'), - \Drupal::service('entity_field.manager'), - \Drupal::service('database') - ); - $schema_converter->convertSchema('shortcut', [ - 'revision' => 'revision_id', - 'revision_table' => 'shortcut_revision', - 'revision_data_table' => 'shortcut_field_revision', - 'revision_created' => 'revision_created', - 'revision_user' => 'revision_user', - 'revision_log_message' => 'revision_log_message', - 'langcode' => 'langcode', - ]); -} - -/** - * Copy Shortcut entity data to new schema. - */ -function shortcut_update_8002(&$sandbox) { - $entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('shortcut'); - $schema_converter = new \Drupal\Core\Entity\RevisionableSchemaConverter( - \Drupal::service('entity.last_installed_schema.repository'), - \Drupal::service('entity_type.manager'), - \Drupal::service('entity.definition_update_manager'), - \Drupal::service('entity_field.manager'), - \Drupal::service('database') - ); - $schema_converter->copyData($entity_type, $sandbox); -} diff --git a/core/modules/shortcut/src/Entity/Shortcut.php b/core/modules/shortcut/src/Entity/Shortcut.php index 9f60fe0..6ddaf05 100644 --- a/core/modules/shortcut/src/Entity/Shortcut.php +++ b/core/modules/shortcut/src/Entity/Shortcut.php @@ -3,9 +3,9 @@ namespace Drupal\shortcut\Entity; use Drupal\Core\Cache\Cache; +use Drupal\Core\Entity\ContentEntityBase; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\Entity\RevisionableContentEntityBase; use Drupal\Core\Field\BaseFieldDefinition; use Drupal\link\LinkItemInterface; use Drupal\shortcut\ShortcutInterface; @@ -30,12 +30,9 @@ * }, * base_table = "shortcut", * data_table = "shortcut_field_data", - * revision_table = "shortcut_revision", - * revision_data_table = "shortcut_field_revision", * translatable = TRUE, * entity_keys = { * "id" = "id", - * "revision" = "revision_id", * "uuid" = "uuid", * "bundle" = "shortcut_set", * "label" = "title", @@ -50,7 +47,7 @@ * bundle_entity_type = "shortcut_set" * ) */ -class Shortcut extends RevisionableContentEntityBase implements ShortcutInterface { +class Shortcut extends ContentEntityBase implements ShortcutInterface { /** * {@inheritdoc} @@ -125,7 +122,6 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDescription(t('The name of the shortcut.')) ->setRequired(TRUE) ->setTranslatable(TRUE) - ->setRevisionable(TRUE) ->setSetting('max_length', 255) ->setDisplayOptions('form', array( 'type' => 'string_textfield', @@ -143,7 +139,6 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setLabel(t('Path')) ->setDescription(t('The location this shortcut points to.')) ->setRequired(TRUE) - ->setRevisionable(TRUE) ->setSettings(array( 'link_type' => LinkItemInterface::LINK_INTERNAL, 'title' => DRUPAL_DISABLED, diff --git a/core/modules/shortcut/tests/src/Kernel/ShortcutSevenIntegrationTest.php b/core/modules/shortcut/tests/src/Kernel/ShortcutSevenIntegrationTest.php index c8517ce..0d58c31 100644 --- a/core/modules/shortcut/tests/src/Kernel/ShortcutSevenIntegrationTest.php +++ b/core/modules/shortcut/tests/src/Kernel/ShortcutSevenIntegrationTest.php @@ -21,7 +21,6 @@ public function testInstallUninstall() { \Drupal::service('theme_installer')->install(['seven']); $this->assertNull($this->config('seven.settings')->get('third_party_settings.shortcut'), 'There are no shortcut settings in seven.settings.'); - \Drupal::service('module_installer')->install(['user']); \Drupal::service('module_installer')->install(['shortcut']); $this->assertTrue($this->config('seven.settings')->get('third_party_settings.shortcut.module_link'), 'The shortcut module_link setting is in seven.settings.'); diff --git a/core/modules/system/tests/fixtures/update/drupal-8.2.0-filled.standard.entity_test_to_rev_conversion.php.gz b/core/modules/system/tests/fixtures/update/drupal-8.2.0-filled.standard.entity_test_to_rev_conversion.php.gz new file mode 100644 index 0000000..c7a96c1 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/drupal-8.2.0-filled.standard.entity_test_to_rev_conversion.php.gz @@ -0,0 +1,900 @@ +~Xdrupal-8.2.0-filled.standard.entity_test_to_rev_conversion.php]iS븶~~EUOW@(wZnpLwq;?&%hgh 3ulcXhLqQq,Hgo:1۷ Ƕ1 +L33qrRo?f[/a",w  <8[&03kr\L=~\ ./7˶de/w|}XhIu2?tЫAfY,l׃FTX3[dacGmEr% NoJZt3g74`O4m<Cx}o[5:.ث8Ҩ$ƪf<`1d}j=5}ҧֳlx5QS{![5rJ= u{"˭gM3Աv4k!k5Z ΢.ڍQL-ո;שePN\zhV}ȡul+`Ic :[8;$D,iOf0n?c\SuAMi) MpM9bɨ)Ӣ|ic #QkUF8϶:=М(3&DāQ:w|tӹw3%[D !b*ЗynȚb6xjz8ntB&3{eT4Uި}?E/yE/2ƽs[Ꚗ4$s!{%@c#S70J7P8]"@+=S9i%0BA B>Ck/aF)܎}OtTIwI 5 ?(%J.N FQ&X`X& lKÖ¥N9}x39w4 KڛL:$8'j^ c Jw).=DNmQxɿ`'(Myf? +?ˎF!cv"cmcK\O#'(w63O8D:Φ5Ns?LeE/M߄Kb1#_NfZ;[Ŵ}c)'FՒba{IR'CvE͘cq鯎S5Gp'O#┰G9i0?䈐~>Ǫ'G#ۊ:Uk@qD#?!g4Oճ½vOgg?yՒ,@pG?ߍ;{< l +ÍN<^89KTZ^:9Y@<*(`UU o2D9#_#l:~j',rT;.i#TmaH[CE'TTpJ}<LX ϔFg4Bf{CUdowA]^/k9p/<܆2G +.rΈ~prXtb6덀’c]kufX '4P !r2VlX|d +T%Uɸ)4l'Gļ33ΌOq@v-8/1qG}'h +wl99(iGHgN[3C*A4sA0BkU+ŗ^D~[d[qmKIheNz]o^)ԏYj1¬Ŭ.;c3gbd'H#5s@X11Yz_'r/%Od\wZ)]Bgm'pa N[Q5M#Q8M;!?n3S"~iH C'eHWs F8(! Z^g S'fz;~$ ȟ46n~(| cz'U(z#nU*8BC%q4$ QWY,l? T僋 O+e{| Uc+rWcib3FvO.S,}|'lq.]E ^D400": ̨O+\љOz7Ւy Z<ҕF]w?{/ >C>$5  M!ĪEi[ܰ]3+$nfSɏmKxb`;=>eVQTjC"#Ssv3|nZx/qYW X<>UA~]ݛ8+ >/Zv}A]okH4c ]A(!Xt!Ayd̩@:8 o{Ah7X߮[oJd.XWo 7`nJWE-?Zsr؞p;hz#3 щ#0ҧt#tG4RiF д {:LO}>&l1g&&׻#h{x B`( O['֯HPC,OweMm,M(2/Sj_<`}/`l"ZAF ,$0>U-ݒZj![VugɬYKh]ݞu>NFӟo;w}~tqn +^F_-.(>*>{@iC +V SXLR?Sg3eA*(cv__dϴ- CZ[ݎ8)FKm筶)PԦ#4e 4@*b~"j ƨ p`l{k/U,ozO;Sf29םlӺhsZ4wVh i뫛fgO!`7L!=  +reKo1^ϫusjM-^omvΗfȮ@>^zÇ0^y}=ڍ~QA:0rPa,0o=|5|S y`DY5 5"e$ (H6́vI*tf)<"<尓,/#`f +i Jġ !@VPb$3]u|n:50Ec^sC/׆'{4pCx@Z@8vE<.-VubvRA47i:vyZWƕkXM׈wYq/WC *eNZW_8$T.ė: aHp* ţB LP0+%8(.VkSM-L^.ey ?`B7<6 +[4v@sRvB8h vD +ɨ[Ys^BѨ:U%y[4DwWLQ5Z5\Vze=שK}dI>1b-iOʥw2-$iD3S^qWf6H7r=PgTeQS5副2$p1Mkz4%4G5gC '6-E'FKJ@\Acbf[ ?i#b?z0؜iIo6bR}?iRJx-LKiSP!M=PG?",77-H5^ðϰ.ͩBp08$ +."87 +Q*oY5.ɞމl-Wz 8`F0L6 % V C 5 eyPE(޲[ TDgIɁa!rajkuƫ1`/ψmW%B0@р!(?j:ɬl229Txۖ<d|' /PQ +W77UxQt/n ϭ8p~(ABS6*šK7A {T|'$L߶f'jG +$hFC^{O2 zk (Gibp*A_ 4 2| *(ˊJoi T.ۧ.HX:i$F"T8"xsǓPćO#OmCyFB/=/@O>JɄFe$+DCE57a-X}l5auPZJM-`Fk0,R0g9 UwA#,˄km8/H +%JFc,b, ӊ +LQsRd|"qPڣX2(|tпF&V6mL#FB0T Mt@B (FVCc _"!Yk,RTrB/uxch/i'ԇEOyͬcһP{gb6곍.Mt1&&Ƣ8J8sBMB\LzXgMc<@.-ڴt"D;eZ $#j90`@._G`r3FԹ}Ȅz}8%ς +Ӝ7^GSfF)m +  R .t5Y:YlǴr2bpH9@@ +ZWT)qkhg|S3 ?bɸqfXB$tv,:(wP4CX6^O0.m̳Y($Z 1Gmrs,8놥ۺmbJ|1!Ӫ{N(&JŊ\mFejO]iqPhr^CPXH01 h5p -h͛srz2Lnx!9K^f0.Ew[BָvkgeevQy2L! +Z@T CWJN6{fKr"?;Zt[wWsU;O*-"4kwR!ErO1 +ǧ:F1!Ctw-"GA>;zQ?C'=;z+VdߺT6qkq5DY0~۝MK#TǦR$"Y^e0y.83!De298y|$9i>"-T="ަ"촫0δH@WfbIf7k9_t{^:&OmP>BYAj\E\"~n{1=I*=5lR#OCge(_EAR%SiXbFRӵYeE,t׫]^.1Ў\5+ ^el4^V"VS@Z Q [o E0Hl7=7:V MpiaH'x<I^ʑΚ%FۺN*5ӉbD? eri!0@я+ +V:x8N0sfb |Y 9&tT)(s E6u@2n8ږ+9bn4HSӣk9*-D\vkݬ'qo^יtZiˁ3@)^ٲJGT}a 5he,׿VKVZ_f^<"+][ ըTmib1yeU0L Eρ8YZrz{s9㏸m_MۀG®]-6;셜neş~Z\r9)(bX$&ra 1I^NM?~wsv _Zސϗ^w¼{늩(kp<"}ՏeusX.[Wy1OmJAD c0aѺ q &YdDKqrj.ퟞ+:ݯT:pj}e03U-b0 T(c) ID2[NIg~8&=VJuxw/>*M 3 @',@'Zʼn +V .U}2_>S~:U]"zHEKQEQOܔ |Tg XD0B۠]"˵o͇!vAãݽCކߍ:w_vbH#$GTH`:b +K򴊀J}iF8 ֒co㘵) +:7'__wߚwػTunW8o B8ʶVzHH*j8$mm{Uh_H xy^?69\V"{D2d+4ʳ 0,*9;[W>T4yDm'4~V;R\u =v2%g8!r, +Gqo+ڝ;CY_/ <0{Ϛ||Aa-c\NASm sr- M"~vsWCɧotfseL2U]n\%>n7 M}=ky|?ig} ߿#\EC~bVyW/#4A5y]QAƢs+٤~W9|A8 wx4rp=*gc;pĺcwTP%EZ(Sa뵑VT熦a`&D77?#&`emW~gœ\%Dʖo.ȍnVSK篗 )D:^0QF?O||ة*'. +, hF<9Ǘg_a|uu2=yH*Xb\v٦ +ԙai 3׸#X{(f ojDeko\Җ-xn$ M@164ٌi_޵ݢ{3ײNM_ulWê< C@lms, tQKnmvO7 V6>6 KnpahT$=jcS0'dx~˚>m= +nF~1_gioPWޖNu1yVu~2n}Ѧ8 +h,0؎!iڐS`6Tv~P1>V%A#-͘#m~ h3ę[:dDEgl&/u +',]KtvaGgs(򥰇= g7=78LUWՙ,˽Ns䬎gO'U f&vUٸ[wEݯi.׮E~h_D[,;ʵ@+~m;PqX^$Xd=;䞇a@@LȦ،GԲ= E\܏kXtKT֓:Mۼ6 :hp7ޅ|3jEOVO/XigKPs](}ub?u[E+) 57ɗbE3lj +Z$k]PΰF@-冨Zc c$v/m[k[U:Bo}Zv +ᐸuJFB280Uy]:\q^q̭C6`7~OZ͇;Z_$|VSH~wSp'pր9,Vu`ch%ul.2)0\0rϫnj".c$`$#&abU{AÖ+,Ӱ`Xv6 !oĄ DP[7܌lflI'čLo6v~^7(p|4/%}{=7 4t?b_brך#צY:%exmEJ8lP(%݈YL|fM( $AR[_V6QM"1V;VJ +g:l ǟ3棻$)O_lx9 A V> YhcR>8wHvnJط5M\]#<턌+Q]u4 ܨ#^1W?T%,eMJ26#AâXx!ciLYznr{ zs'WaZ㎴ړ9Z6* +5XDtxV-П8bi6<ޜTNt*KG^AkFZ)'qE#iλq^gx|ݼHlT3;T"cp "DUl€C, /Tƹ͑+YM`gyU}iঀMHH~J_!n1=V0һ,N^T4aȕ>včw\o۬ٓ}H0|5TM:\LC_ignDbnOwRu˕$L&8 tQrP%6;ۙR`4o\)a5NpjֽczoΫMz +\v>Ȫ< R^,Xwd`LKRc /LvS,;_avL]s9q]Sg-b7#Éc]^^99 +jGF\6͗MR |+z- 7=\f:z^{d] 4i lLmL0Vy¼.PAཋ{TJ#~Y^[ ~N~wV_~y +XqVѽQc[Hv!T R{!@l vƥv:i˞wg]7 Fs/}hpG2pW(`u]IWXX_gb6vZ`Ur[)gWz,"kXTMeI>{iFq4*WC`:n:_'d>J4 B]C 4#{pX~]vΞr +kU/Q8vZ;H*+e}Jy@3ף=`@ d`4\tȨMwrE{At:TMnU)u{Fޮ꧓8j AaֶD|j3KJck&`@<`E6ܫ!{Oog_^ U/@qrl&^z D "+S뛛#PmSbR`a@bҨK) jzة\Ըw{kn,7sV؛s Hq5r bz\Y#RcHmUܫ!9a +t5b>=\avK*{ 7m4WdYγˡx! rSv~^UntJ-L n`=H5 [i/_/|{:J( GMc xʺtf%q~eщ?ʍ [8Xrqu. &,] $D;ޫh黉41O]eܫӑm.tVQW/F-]]];{!Kݿ7opC66K;cmq 0'ۺ<<NFwOeWni/wo+SJVc^I5ד4[}XCsjY.!Ͳ4P4`B&]k˧:6.O&/:gaVG9 +ߢj"VJǩKAJS'B4rcpCf܈؇ϏZf zufsc"p/ӻ݀jA䎲3%gYm(ioxpq? +2 <\A&cafH|en_"FtiP#93D,iG$oGp)sFAzrmkW_ G.h]p|uMj>MokRC2l%,tQ3$n3j ;pY*u|[&;v"4ժy{C$ѮX]񖨘 (gvC]dU\~j<邁)q>]|hc=|wuqJ)~'J'}|=)=ݙ5zEM턙C}t7q&] +~͑.eh$! IȪHsc +`cCX{f#@yw k&mnY3ufQ[`OU_'-Ri01f) [+ͺx ,7Z)Uqt_{b_F܍r>͔T\\@a 箊1NUJF{;nbƶPja/CRy~PhCU'Q."!}' = S5 Gb)"L6Q)?joRr EGGp PCPGyoEy U3{'!3%gԤ|f>3F ?5ז2II!<<' RFV`Z`\ˆdT +d@nWƾzLDhI0Rst)|()d½qKel,!m YJkm" ĥ9oq [0:6XdW:?==˷Ae ~)t~ԄM<ceWy'7Ni)C]q[m 0tQ:?6 L*Qa[*xIljц8| OրS:ovJgNO I:wluqFtM@³%l$?L"yfy6gAj5cD6k\z+'w?wd̼ .BƟ AD +\nx6&2EH邘sa jk3Zt$ԧ~ՠztֻ+Vukd\of\ +/ ZM'| tYtOl}e[_׏=gTn'0mC/B禀5NV,%5(8mb[͓srݬޏoMxY Jf&Afz6L *  _j pKRq>YY'NӋݬyQg4"%)|V}s]rwsH@ zd« -?~R1IK|)y-'? bnX-"$a? WMh!A F̍ðx79)Oτs;c;!I5Ipv 47kN7fUh9f5d:Mi脫ڶ lB ؂"F=˻U0JZ͗N_yyrJN꺅=XĬ[o@j  [#?0Т%hԁaĔXaS1Xnqɕ]*3z^ؾܨ*:Ѓ4Qw1 98 4NN\I/_2/P_ԻAt0Q3Ƨ¶<5Eʜ*Mcd~p^̳m<{!(Z&?`Xnqx'5ÔFR_r)f-m3:gxwtS|kU.Y٦닯>,/c7)A{Q[ZQTm mcRBȐDSüGÍd`^|[5c| +˻BhY6^PL[d+/1yWmbdi$Ck9vTwTiV"1v A?Dz!t#5!Sk34N5bhP ]gm9iC@5@=,Y7Wh<@^߷zE~xQMOƩ(+A鐧^Ѵ- Vbh@M[Ѡs۰M:[OJ_r-3j`xi[Q$CДN9\ńH]Q$6$&^J4[D7u\lꪟXF]9sh3ĀfU-a9BgrM-*)7p_#:h.Dc M<{فWvл:ui{V;$"0t!(Ngh!F\s>'U\_%* 29W8[ mI92*D[й@Y\#Ѓ!<6V;Z[N.FoRb<[2[B2о7CYͰV [&?ISS[.k6 <&C;C*%+kRs;*ɸr⛵۷NZ_UŸvWw pM/Jj +gw1bVJ׺; ǢۢsxA>| ̙T'xb&LW >kG7N +M"wіpН_tVQ^~Z:*Ⱦ -_~.?z~7 +{ɁGtn+U}:T=Pn"N)GN&f K:]f0?b.;bbkg_nsfDK5/ͼh_8sa@@d]z,i`HҖtoy}WZ7M[ҹqM9Ô +(C$np_)b;Ost1hg;[u5~CQ/2~|S,3L͵#WKsTzCu+tKܥgy!H,٢B)DDl tȦhϋCy쎮2oέgkW>oT;|Nsռk5[Z͛OTY=/ԯpZIrgu{RxFVjKOvr p}s[/Zgiffzt,L5+w74*'N}+!vg+קּ)(]%Thik؝Ě]ݔ=K]w0*Eb{H'7hab2Bۘ% +4Ч^ꨜԧvNh}D2_D\F=DR{vao4vI^Oڠ~\npOhzZ7EP>&OUR y:4 L #ѐ [_VjFuXoLڀzw迎ױTd(xN&K~'wim ʭ0 +ܦөfk|f.&gYI-0Ҋ?I^L,%ʱڮ ^̐ף3))- 怘,mhE};:;v즯ãZzdU:àRkJ4 %~~Jt2fuGt]RXEisr<{6%`#))OiݻGJcY(mi9v.Sjjʐie;L`L{vƎ})H+kN\%/>,ɶNt2$Y0RJ &;$Kk}AZZw:Ljgpo&=xZ?<h(ȩA +uϤM1\5BpK`bM 'BNu ֧BNa̲ߤO 0RHeIT'D 6=3$Z_[<3e , +zr2YA +S]9Vhjxi.ڥOUԢviy\€D3R5M +NӦ<>P$'Emi`\Z&@L݂Pûq$JH[ +N+_d] Q~NcU-`LT:;:9瘦dl}`! չ𗳞{+3,YJLD߉:ةey3) Bʢ`2eˑٟw>|߯dM5-Ah>PL{wfFEv/&n.Jt{߃5+{#u i+ [@4֕8E &Gp@07Z YUU՘K rQ{#,Mk&F76&Uz48ss.D /p(E +Di0wߍcoM҅`6wM Rg?\EȪcc0G#<@!0"3(Mj@7, n-r Dv A>0"  CpA!l}r@do.8lN5Sô]CYKPE#cFkp,!hxg+v-rʮp3 3#Zٝe[w9,LiLK=DepKp,0D+oKSK6EIʇWYO`MQ_AvłH$ 9H! 8@ K,s0 a4/zЌ:f':B^%u]\ +S6]L*,s_T$jU?Ns 󸟯a7!'0hH\(9TbƸ Gb6쾑lj2?g$X&F96dV;_g UB~fI=f{BJ6\pq +k+[1\|0B:ă9 Gm6 K|I%Jɽ"[-ff0feDr"q":?+6`D\P}ϽDzwE8#^E󯃖p꿼XVδ-É3Ȑ\w8jz,?*׍U~9==<>nN &,,ڙ .H[o7gE<`9?NOZy<r1Gq[<3v!@H+1mG|V$ e:d-hICk tudlzPpr.e]@VxVbO (OSQ{fX@Wm٤E?hzMn,sY1}2o3 ^ +Q8@eK}Y9E1!'qeQTgQㄱZK0}2 ao4k->ZbAe}pGf?ҨNLD ?h s0Mn¶P^TNo=wnbLo' 8Vl=mf.LlUTc+Ѫx:[eY(owHQd&]oEU$})&{̍'ty׬ݬy}f68x|Re{:f2*NM<5/+W5g'KXMWj,tIQ%}-ˤG/'kTr~n*H.Jp1y\Atix<}:)Qo\Wdu]V~k&H +KOڞ `pEe)R 1 aePT>.i[<'Po[k~>brUH5O5 J.Dou78 THs,"unAW }$y?S@^ß`º 3ȷYWqZNZVnqwŷwsTT#Tx fc*R Py +M]R T!B0T ATPTMLjHI$iXF`8M գ^n7f,өuҾ5+i↋jj eVJ>aꖦbD᪚VpӶZ|U]Se>z +u1}0 +7F->U UQ/ E&aUM઺ +j(>KM &T#Oy} l2WG"QtLr/GV ϗg-^V FWjyߕѶ+MȡO%,\;}9ף6h=Màފ+YB(f,7IB(XOGyrPlYVx}ʜ7X`+1Laλ`m堾ģ W<҃Olƪn٤5!; p$,Er˜O?l3/; +in>VQk Jؖ j-[nǠP^u6Qk;)dOnm ש׷wKm28յy<(.*倵mH"Fmy*&AAYd?^p3$s )s]`rhDe`D$p-,V~Ot(l ҹ~vߞ_ +c}Y^RȌ˒ũavR9$]*utֳer䕅$r|>˒a"Je#:'bʱm݃HןКm q?ɋT>* +Ƹ7<4!yR a|k̃e Ӂ8WA%l$ݑt D#03HLK1ӕe`X@)U 'J6r{99%~|ɜY|}Sy\=>u W$ ?*A2L8?ÈU[sطk(n'Bm/E+ +"4ƷC\a`C] 0)py1y'qB=?Fl)B2~z>g{S)""AeDО!!\VBFѰ}*Mn'[ jf ؞)$J4+'z8tbYoa9MV Y&m;fgԩnm|q  뵐!TП UH|ɉPp?х/,)őgfHL }5z|CxӍݥv^B4sx ̓緡4F1+5k>0ꈜܵvʱ쮁I0֍Q gx 7f0ԔsP}J @YJy-k;2)8ܑ[NiSq1G vN^dQJ-ZRY)S{:egۈZx;%)r1[y[ʽTPLE-]kjd׍Xz](L^Ur'QIQ4//6"yl7;Q+s3P..ӹr_a@8G`Tn[ZyN'Gݳdt~i4,xĠs%ȶ +AF[Bb2<C(1.U䩿bsom{>쮠(7mjxj_c&*aG]95]xγeڭ C.~cçte[[ sL%-OZ߆-%𖥱A1Bu98lHvErV7$C9Nహ$)(Jя/Kնڃ'+sܓum/ST8I 'ŶfI}#ysg1k"!ahZ`L`e^AbAj_~!,׍` kzpKE?Sa>VVPRu y+Zׂguw!LeE/$W dG*Ϋ+@ɼWU{{aqiHG`a2ZU55_ A؝Ndp0d0D`>={PQr:r<͹8ٌH"p oDӤ,C55SƚTe«&C_sm> +l(Ŗy=Vn0w;I,G$A~+$ r"2YH MZƳ9Cd O&.s1+}O<'OVaN٪IE[Rs%s[mMvөjuE,4% +BDƨ ,cyKL] K"M5&w8,5\=,c>gbf?#Ӷ5%K&lq5HN5bm!tT40ua) DTB*;{W&y585{i6rY{+NO+ so>N~@I=rgaGbf,8_%JFA/1?,q" %u 7i8DapWjaԓ8i}s{4.}ѫ_#__mzz٫ٷ_ :q^vyD әR JpFKWQ4vT0VkU?%;ȐJ?W."fJ߮mt +i3?3!) Q5Cե+I;,=kDwOrj{F;z:Xu痵j?zuTs&nE_]NΒӥGr;=|a,!L֪ Qrg(=TK/UڥI/R$io/gItΰ#f URr|lQFVոblbŽ@2dêS-lV2a?(=)]Y#kkm.;ϱ-L<ɸPWx^1KzQ}:0%uhj$6K/B.TV@YN!4Κ8Z4Յ(D/ʮAؽh`|"ez^<҉uȊmż3 0es9VVmGPmG<;,` kP 5KLq<2\w| +& on^VjCV2 v &_ ֜cޅw6"$Ϥ7.>/~Gaq\ +^O"I:dnɒ|BhR J8ɚ>[lʏPfV{Z}Ծarl\UQKG4޼w4p(r4b0gth9~/z\/yMȄL\uTNy=Kj!Χ۬b2Ot2CC6;}gcyYVIƗ9IQ߷aϧ;.6U;U>7367&4;kDw[(8hdSv.%-8vQ>qIq"a\02<,B#DQ`&k: ӔBXd5Mx@ KO=B_yK'H57Lxo! @!aȸDm{fZÁ7w + #N@wK=aň7fW܎L\+CxI3R6]eڛ+.'i] 2n5\ RAnj q6QSG2,<]x +ԏ=7oƒjL% DAEK`, JJE {:綎 08YQ0Z$I?c,O5] 6ygјOW6/3ї0ҞgruzeKc%oe -p"ydG!CQܙI>S*[TKӇ[>ӜUy~}[yC''lGos2Z'+v鰁ǯ}<~@s%uC>zduϮެWsLu"Veiljnu}躲];Qs.+a$p46I%~YXI3 g̱R>ӬYءz*)LE5Uͳ}a²*0"άT$LFjvhzRh: +9*!vjQZֿK@+,MpaR.B'"Y7v)] -NMnƽ^2E&GW]|/:<$=Xm7 yhUr=b` &zB-OU+  +,.|:\> 4߆i|hc0BɃ%҃`q#_ゐ-ܔ̾7/pQ Y>n~& H='i\׿u <K嶕nz=99DD7R$%9KonFπnM, !#pgd+0F~aٯӕxs|i\zmUY ³dƇxO *͸֙lkY=[ʋYbY?:I`^yҌz_֤n2Xmэo, W|Y_:KpI_m0Sm='|j"Y>:P/v.ӆ'2ݰu]PC.JԫC_'aX0^PNy ;7Eie9y!?si}j5XI*2ظ:Kݳ18?eyJm2.P&O/7;'%^a=OEI!x۵D8Yz:Zq! +ڵYz GdmӬ.PE\?O}^w F8xi ŋ/,a*YjR:UV7gb(X.$4z{}''QZ?8QB;0{8m +[jhMZx[- Wf`fHuޘNxz:&ݽc9C܁Cr=`&tNi_|'$}yTx|TY(=kd.?ca Z|'gÅ1%$7>宁u [%MUu̿-P_@|OaƜSk-k:KNi; +"i&:[d{WV% PRIR{gy& +!+0Yפzl_X>\43|w¤U2Zb=%pPޯvncyyWms_>R8e҃.%l)1X5n, +6~e,{JKm_TLj?8!%6 _[)9>6h,&h;yUV WB#]U0H&9#׎ͮ2wp¨ .00&ЕmU)`fc,xXGJ= :qN[)aʎ<&3olV &կR,oRz&NF!=W+ꔪi'j tBKIN';aT2odT8e^c +3 + +Qұ/T~S9>d h=6-k_R%\:1]5=w '뙗N6@r62nWPР؝['w7?ow]W?6_t|f}sUbnk=զ(=`Pl}/".pXn/?}_뿱_[rOmyiPbnY;5ɡ'v}8iݯR!v}[sCo#ca3G8#ܿ_O|etb@_/ǟo?kTN2ЌF^UǩV9!N40 6;(r,zŽ Yk~s*-[ٕF`<ߠ=JD V«C@=qZ6PF6  Y\7$wy5a?;?~uws?^?=G(T͔ڙ f2zͅM& :_|VwñOp;^ +97L'/{w${rM*(#DR}vUDʁNWzQ&{EPpkRj$.]7_uÂ7'MM(Zg=ޓn#P8W-{lR[ `I^ݲͮ(0P0l2u[U|!f^x 4+mՊ(җ}ooo?_\B"w7?WݼE;X(,kՁ9rUV+~ެW[?/ikrV!D=֭~goKN7n,\llӘ}* D( 99Sl߉9Z_|p/"?n78% qcq_'W.?>?; }cNK%f=ǯ}Yģ6~/?&?H쐷/~xeFJұ?}CO)|AC?|Q8P-?|n<6*ʮM6n~/}9(n{u)??{7g0|ӗ ޳7UOQ0IHbIZ(QjcAp5|f:4٦@}'7f4dU>>2?XmUMk^DwO_/}fMuwll/&zSQ>t#?.,yJgM +cB[TÊE{&|*ڋYۢkj Ӽ|K*ck y$dK@mec:]ue ,UwM4$*{%݈&,%>*{yDU;k]UB"Aoc +=K|-yiE̒2nPɍ)-^eH6?NU\=m;e(h6^JS/vsڄ0_z d7_4o1&K{ɵy{gؼdrHi0 #Ig>WVYa²n:9ݒ\/#[f hcKGv d\]]G4wGPL +E}t%Zz(|ןj6+xvuի`PJn+d~vef#dC†[5WNG*UwK*e3BLΎ_س4 pfYMDF)(Au;Ӟ[?.Jr|W +籫enֹFM N+uCYX 8 *5Ct?joym.T`[QcBT$`i}HUⴁ\=dnEiީWY]jw'*=y|:EeW#^cQsȕ|"K491m칷,o Қ_ZPSB)?N9G:jk2 VI&3;D!tfj^|?"P]r[6/`F:jC3𮭅˫.6P W]ƉDrQ_vuc֩-0u鋯~z8*SY"}^P(ꁺmQh3z 5g&Z*]J~5J9B'E6W&"@}}U3۟U3Zڊ;`*hh1=mB!+-]fsHֵbY.8rKֱ)U3zSl0}-ZV,9eYp0NV{*,̥s~X7QLjbkP.6~`kFɸWluvUiR9i>+ux;Կ&Qe-mx]~U&FL{y +'UqNOɠS^,e&bx<نodF ͬ+j( @?>v㆝51yմrԴg ld$sxghhy5/ 4j $%[H$ي#U'0-V#6Oj|9>)==:Eĥ6\f 3YZ̵Mm9]Zl$Uǭ7s{v替 yXOg/|>:j 8xf쳍氱3r۴&YXi Ϻp>~Wp+fGևmK9T|TB⣙GcѼ0m]}_∀_{= K{rڨ3y~_oZ石(FV29;$?+_1eǣӿ8 +ojCMĴry=/oYΔG±; ie6fL 4lsT1J!`fڇjNZ,UFGysQG*%)ح+"Ys:cդRib$G^$v@d%O *' {Vi ˁ_޾ո̝ yM}fg/IpW`͕دoWoo`J>+d +a&نG~E8V;'ˎul7V27/UgI4xFɮQl@lYևe_|[[$t9qՠJa.SRK2V;4߰U~xfjn.ipy_|t Y´'{N8}c)-j\g}pDf/Vey + +2߀̐B/l+~uwS+@' )Y+S7 刞,)V!fMaNF@guW6VeVa8I8ǚqYA*ufi}oa YכF +ҦJn.aXbKE#]veWYvx9N*O*mvMKO|Ne0m~(N\ͧq.J/{ϲ,{{.:]Y*cc;yeQQxI*/uoB%ܚ 6vN@/ 95u ?$t"I[|W2\TLabogSZVnGf@`d7, , < ,,=pZ!'͗9E˒i '#2ZSM0h"S@ + DyBn:6481ͪJg0``<D+f+C3"L$dNC OUz,I]Z_cT5|vf|;ɭc5ۮ)x"SaxǤZ2lՖw>jQz+&!֛$ժXR7ꂞmwoMڻ w@\>%}3њF%9ʐ= ϫ88N $ , L'*lg;C^Pw mT8MmFe9A^旬>_"e nXmKGܝ 0+P𩚬_;ŌM!62Ѝ Рk،"{9b6/?뛟o/◯n_ y#.ƕ/艎D'"r/iM*8* ?L0n)Ssi$j4_;i4+H'Svt\s^jMc5x!Kggu]\:ZzJZz˪"]5ZK4*㦽Xl͊ѶzhۖnVrҰ%>d[PiT[HCe Pn(RCT3+7s Sqe_tnX}W9)v N^\j} Oe"%Vyewɳ(󨷦#sJիO&;cCH`^[$pjnNsHw5dZ[_~?ߪz]JyQ͸>bKә:NƝې˧V}4ZӢN?m}ӳ6b*llyϻj8n&ZR$*oZۥQPDv FrM6*TEh/?,e&S".8b̋A02/8p?a`Z47R"0\/—NzsOY?|;GP<+\CZJ-iG&pM),vfxeޢfRg&Y^Z#uo6kឳAy2hO 7ϫܫ>gp曱9|\֍= v=O'9jM#\HޜȨpRen9,gL#_enp +7'Gp'oHmM4yan=, M%Քޱ'ujK=uNPVR&e#i +êXH V{;T#B?:YK0*\%as<2f(U>~U??ӏ?w=njeūF_R(?$wR{Zy${I3E43x<3ش+OOmGȫྷu- J.7>UUJRrI572ᛧwwy'}DK]u%줚*KE +-&%*Zj Qj Hj [^VQS DŽ7H0u-sGRWpk0\" ?qKU(kح*=JfFږ̨ZΒ;*si/laSBM1;" (Ho~Ra[丐. s]"}BB "&D (grgQ\e·#^78rbZGUfmP$%E@WV\3.mjXu^Zi&3 fhq)3%x>EQܢ ;Uvo/dY?}vo~x̥gxV_Yxkv`8)a'ůߛ![X26ce# UFT{ +q0<0)Ď0d;/G5*IP'nPպ0wG|thTy8:.U-k +]!_˓r2?$oퟀ6X㰰aVK+8_]:_jZwK~~(R[Hf'x^h塮ޮ<$ǹ?W%}w_f׼Mt@56FU[1 (]=][oYE#'?B}X-j֢ҹ@޺\z_ye* _xA$f>ƛ +'!-`+ȮZ+o$$=.h킶 m+*V#p=Y"!!G޸Im7{^\͊wɊ)^} _]5a]x RJuV)|g9u2,v`U֘+)_+A􏃌ܴ\leuV6(ìV%wX I?~O/3WqUI]W4:U%KM֧&ɀk.j1Iҟ*)\ ,x S Iy~aڣV ̚ =:ڲND=_yF 屦܌_r+VenrfVUa;)Y%+'֯ ߆'̺yZ\^"Z腷eLb62v PtYR%ټ IAfVqWέ2QV)I 7_w ~B"k] XdhQWK,Z+m]ވkV*/(Y3V(6YJ 1BϪ-f J +neS*$a]ˡ,vRYVi/5CZWϔl@>wTwWdm_ ~ݘ|^;.^k:k)i|-*d~'ed?~UD8/ീ׃VQPt`X_yUU T-P@Z8%ѵWE :-贠CA'ݱQ; TCYЬ*Y⛎φa"9Kaxǫ#C76<c ]aQLmŶ"յ >WPz߯)֑M8e.:Qr6)zsʃRʛY5nH)3v}K{04S՝Ub/"x0R%<6g/PV%>GqtnC߯YLfW̼=)#T[o5כxS/ +nFU@RAAWCPl? AIS.AQtwo{~dĊ B}#2;EEge_efzLV$VN,p(h;<2?ĮֻN}"~~A sW18Wg~ۿ?h~/fwQNL2֕/j{g1ֽ{&^z,:7*3 鐽nfxo@n㲛PW]~5]I;o +.rpeg

θv=ݍ}Oۃ(ԛ>|>@;$Zafrw%lqq-Fhe|(x&2O?ְr̋ᛧww*={[]'Q& kS2;3|!~Cr#;l$#5 +dY}hMj&p3W]8Q•&3PB Qׇ^_LfG]7ٗf5O^+Fq#oe%VE"mź3 jbv~^'%+f_#dн?ye'y87ϫ~n~ `[KzSK2VFzn1]{Е{+oŴ_<L689ʣeu>`r$9btN!O2=,u||ro3AêQ4"ZTE +]1Z}@ w[v.[pd&{W>lHvw>Y(s1%ęxxAy=<蘱O^ o++d_O.nK9*|;+eB:+.ﰻm,9dVnY+%[f1XyFJ7|>jXV:%R"I" /x-c䑲FH +,;VK;5Wt[[iA7|,@>I=9zQDI1/Wkk+$9Oe.Nkߜ`-E8Ez3T?cP%oI{0)xJ@RnvCIײѡV& khjaeұE/2.@yR#B;aՏkY:.wCQlȽoMn}O@ >X=}.~l񻢓;yxA8,]riՁ# pN|/ɲĺvLY߮3|pbW{[{{p|{Sfr=K2ePgide .:O{i3%Dt:VyI#`w X5껼YUd8hX+kr h,=5K +*&764h?+C1nQ=ֹhd؟ oȰ'ZkՐT2 P*U/[}iX1,y KÒP1 r3BպV+e(W.0OcILFbO')yQXFYӠˍzK,ݯnEʙ,Kq AL/&+w1iQ +c$u5]_-Qο}PKmk ۯ˵*%=oAB&EkDվVq84JIyӡ}zBry-~saCއ_rبBpBiGnօ1tLb}?j;_Z,X 1[w&9~K.Ogg/^<޼#a=r$ =e W X\Z|UЂfwWʿ +ryuvD= +| ^B -jn)`6UZ~~ ؤa~״I*H篟fxZ>Z$ C%8n88e.kݼ0kH^f ߤ7CdG.S^և9rl5kr)n ̱Uѻl\\ڣhU/8 *ДzV}ͪu X(|\3wq.ܼ|sl'"ok~o,ȫ->e\ķ&jPk}8hUį֡Ԗ~Z=*wd\u8KsuIY13uh*Zwe5%ar:PsEO " ozN[)64يkRVK︤]ev)V]Yݦ*KXBPBjpvKFi + &,'g:و<?}?_5x 66Fob7[wRk`uۊSM~[6ӻ +VW u fz{{vYa>>"k>d1OtM(AIXd;=y,G>m#rK_`vW XJ!ɡRL<֌zz*ilu _Ikjv[8 +_4a Wˢ[#>v)m\KRp +9%Gqy5_!]:sG + fT(U*],%V3*l[s<^x㇂դ,s K\a2YYl f:mjjuR6:Rb-"eE[[Mwb5)\gV\W h_W*h_gE N:Y\?Nh_"/iv2nE?O}uxwx_p_¿ _ji_?փ7^uשVƗ +c. o_5mg oSuXLT׾Dqn<(ZyO%[}6JXM溱˴B9J ˞.83w+;OHn΃ijA9 >^p9.Uk#x#ln +'%Ij?ŕ ilA UtetZꮋjץ*|뾮h&vdjuU!IZ[0/;u:|u~werYƓU)wچWsw1u/WjZgY/]C:ۄ% E+암c~gLZ֫J'RdgR^7$#ㅠPtW8]g%jyL4:7V|ji8*O@;尿r 3+z6jP*^Nnjf[r+\ĺפ3m.$.pZyuu] Ү5x]u_W-r_Dy/)D1NTҒz 4 xN+`KKmMŃ ( հz;jy?:Fxѧ1V''n%0ĬdE7Z* OK>A&p6.Z5h̷Q2􀥬 Éݤs+Juqs]94P/ +m%hd몟v+_ +MV4`73UgEZҲpUXO%4/dNnH/pc'wV~*kR:TΊ;]U, -Sua+-늹^x]\3pxs[u.P?$'ZZ6;[ZTN)|bTɬFR5.$O<|Zؼa9w#K }vS|Hx#gE.2AMd$-if#o7̟66m7Py./1n!WWEK)C\r+mNJs27'cNCnV݁Yy'!ܥNrA>UZ6;'Pn5*g񹶯.'rϦc' gq`*0W "9oJ095yټb6b<_|1]AȾN^ۻG0{҂ݲ$UJݖ?6Q.T}^'=(pPG=߳W7>x+~rLsiM7i$=.۞lygMOuX>dsJ1MozV6䣪yb/x$zpЕ59u*y) |~O-j챀zy}.ɃOrc*hX5@ +^YqI2DSs>f/$cJ{U*guY[ZfQK΅*>bGT{>/X Wʊ+LsX]w,į1mSLoߧ^9W_}vURW*~Q'TIMJlw+؟7yP~&ՖEo~Oٙh o}x "-~f=q] xY_F sb~=fOYhDgg :NA7n]UYlO:}ϝRg옮1I2i.7G>`oͨDOg%@NÙ_{eB rٛuRdoq,6dhHUF^]匲5:?ϥ4$F&?[!"edtYPoaz҅/(:*UeK*,sO#S)zuYXvx'GW]-o[4TqmF,gp+XjGi rr7Ym;彗x> ֿØn9plɒeNA= &eQE}T"JFe{4iͼ8VV"2#I2j=NS3&/rDZJI=ƥ[-&|#k:.:,}Cu0aַsh~=D,giyXWgxfsAl6rGYr$0  5$YdAH"ApQY%ڙ`6y@J17]m@) S )C#W1u  Vt-H1" }aEQ\ruX %() X-1?5x +-dcjв٤w)ƿi`_^kߑ4: ;[&;n3 B%e[vEm_#NFS`GLȊ&5lÙ~} SjRK?ܝ:rL2#tL;k۽a:5'h]<岣K>A,,I>>CɂX#UY/fe& l-% lM[Uu"~Q>1IhZjE6oIW]U/^VGՊ.΢Qt2“oQ|¸(>(>I)>K1ۉ]}M5q0,7x!|hKr(,QC/,:ŧS|RihbHMVi EmPr%XtIu:IS\zSBbCx-bCo6 k9GUYN:A]OLp|ĺw1k՚/<Z) =z||UPU#ďJ6]l}0@x5򓮪#Yq= 7tj! Dbûx-bûo6<<E[8)5|&g-iNzwŢ-UD{HNsAƌBR{{n`BSS'u\~8f@IyNb5#]}dOOY~2-3BGx1(-nRAdIAS,lL9?[/ѩ&}BI/&:mE]bUUϥ* }1=> eF+[s rC@quH<[y]'K#N 6m$y(<}R6ZNDimlm֒tFi]3`s)2"(ҹ(4M,yX~&v^U;1vI7}m|]W?3gcNJW]ZնTZΕ˹rqf,%>Mg1_ +S%De-Zɒ[iG4wz*c?$g'|u bxS.uOj 8It+m$?2ۯ0xD3bbنHla@ܘ1.Y1f0c1ql L<+F _42!(`Ř! v`Y0#QD(17|]m4}jCGv{6- D3De|<;-.jGv(6]߶ 300pmfml?pC9pĀ#60#lm0EfQ|54dg>،e[ ,B5 F02 ;2۲l Cv0F}ˏ"5}q-P )lmg(jXf:. -0A40cLB%`-= 6(>>A5 PnAϰ,>5M<ô8!>KÁTxd]8~GZˠdAH}w(jXw=aM@ +-d3 fG=y7PxԵnbС9=!2X8ֆaLaX=<`]eyPj 7?Qx` l^J"P{`3'0÷"sjhh]%NΚp]8.Mdėzh0@h1C  \ca{&>J :Ϗ-Ţ|/8IkF]is91= +'Ρ#l@84Cn2sl~6(smi2= &|8af`Pؘ ¶d]D!|dk:Pi) Dm8=N04 Ȧ8?/Ce&GfqLfat."#jz& n/B +p7=8Ab d<##Ql4G 6k0+2a?"Cg=Pκ- 贶o96+XR01i6(gn4i/D? صq,۷ʦ}. EpFjX!s” Sӊ,|7tZؔˋ}`Ff$3A)zCT{A(2pXOu"!5m S= ,; "WPhPv Yp>lpidob45\q 2td@rc0k@pd|[CuZ=a&`1Ā#{h kvSM˳d hl;=$l_Fw'y1, 8y @-1MGsXCmzF`2@Z[Y }s"s@m͈1n=srLgm۹'lZ8#8;%:>e@\P@q8CM=!8#rkA]1>;9Ч1M8yv亾Kۂ +G: 훀!YG+]:"!o;y l't.pd{nC`dt 1&~:(BPsǁ aĀf`DZ8{6 jԌC@ZFA @u^.: }¾(d1NEAׁ&K:a9Zfh~^0B)9y!Ff3#2=wlD )0cL8zGje{@dG 웑 R/4' S4~^,A9{*bЂϭ؃-7xp/\s0I¾cJhR~gN Զ3Ј&lFlÞ;z x溑?L#QLl;,8pQ31E8tX4Tנv`vp&Bp\3Pި酱"O8QCOu= b?2LƭT +|8Jc&x }N` +Xy&HlEL~2pم4 ۋ WX3#m.54^^8Ab\#1@`cیhD/,%4Q^.XBH@Pˊ1`j^0ps %x\`628 [laӂcPQ!bfF7ϼB2ioԆ#c{. SIIy<-y@ycP .b7v!&TPc6%e{g8lˈ-g&Pt 6! 㡖=B@Z뛆C3R6h1# .,q?kfN&Vఀa3]#ߝYpLy6u݆jAޅ{68 QSX3ۉ '`ȧm}.ywÎboF#qK-<8 #9\Wd^ `dعA?֙o27!`p"y5žXˁUkD6V®ٟ;ٯ X`r*] +RpR Zr ݆;?١-ƿM0puR3/jZ +2ں5Vd,W}rhP^[2nu^I_O95d[ BW*-^Mb/fInzZa#Hީ.X-ʨbiK-J0Z\(![B*b;2`"ٟ~ Z F %dAtKPESFYB$/!RP+!hq #n TG)YB$/!RP+!hq #n qTG)YB$/!RP+!hq #n qT;Q,!)ZaPBDPUieT%D?"E 2J0O@qܣ2x%D?"E 2J0薐jJ.4p= R0hCWw]{}u9z(i\ǎDݎLufpIbI>(%EEH] $E%e@hڢ:vv8CLzH"r" w."GŒ2 ~ QK4xn7lH=K$D.)"0GN )rP,)E7jnlH=K$D.)"pGTu힗pIbIE?(%%4QNpE9z(\G?(%En^ete;@RXR&$vI&_Ȅמ +?{$=K4Go|–G/"GŒ2~ QK'li[}N )rP,)E|–G/"GŒ2~ QK'li[}N )rP,)E|wDnlH=K$>D.)"Gov8CLH" [|nlH=K$>D-)XZ7U^ *CqI|]RD>aGue;@RXR&$vI=pIbIG?(%EX(]Gz>z'9z(I|]RD>;QF^ $E%e@hOkc>z'9z(I|]RD>aGue;@RXR&$vI;n{WG>z'9z(I|]RD>aGue;@RXR&$vI=pIbIG?(%|QonPHC퍓E|Dv8CLH"  >zG/"GŒ2~ QK'L4nlH=K$>D.)Ku0%XRfa'L4nlH=K$>D.)"0'}N )rP,)E|Dv8CLH"  >zG/"GŒ2~ QK'L4nlH=K$>D-)'?SRl>zK$=J@z\()]RD>a[pIbIG?(%E5m>z'9z(I|]RD>a[pIbIG?(%E5m>z'9z(I|]RD>a[pIbIG?(%E5m>z'9z(I|]RD>a[pIbIG?(%E5m>z'9z(I|]RD>a[pIbIG?(%cJG/ۡ~IZIH %e QK'h;}N )rP,)E|ŽG/"GŒ2~ QK'h;}N )rP,)E|ŽG/"GŒ2~ QK'h;}N )rP,)E|ŽG/"GŒ2~ QK'h;}N )rP,)E|ŽG/"GŒ2~ QK'h;}N )rP,)E"p`LIque;/)P+)q $vI] >zW^ $E%e@hOwue;@RXR&$vI] >zW^ $E%e@hOwue;@RXR&$vI] >zW^ $E%e@hOwue;@RXR&$vI] >zW^ $E%e@hOwue;@RXR&$vI] >zW^ $E%e@* ƔG/ۡ~IZIH %e QK'L5nlH=K$>D.)"0ࣧ}N )rP,)E|Tv8CLH" S >zG/"GŒ2~ QK'L5nlH=K$>D.)"0ࣧ}N )rP,)E|Tv8CLH" S >zG/"GŒ2~ QK'L5nlH=K$>D-)'?SR<>zK$=J@z\()]RD>aOpIbIG?(%E4=>z'9z(I|]RD>aOpIbIG?(%E4=>z'9z(I|]RD>aOpIbIG?(%E4=>z'9z(I|]RD>aOpIbIG?(%E4=>z'9z(I|]RD>aOpIbIG?(%"pdLYN4 tE&je(M./1"pd\q +je?0%FD҂.W%ҢEJRD" +rUP\ !'tJ-J0Z\(![BD}cY.ʠЉ $dPЄN Z F %dAtK(ho T2q +)!RP+!hq #n K]*B%.AA:%Dj%d-.a-! 1+PeP2(8BHB Ņ2 %Dx2(4 SBhVBB F",\0 +@BC)ZaPBD{t*}cS.ʠP $dPN Z FKR q2?\4k(G~aع0$E]^]%e#ci#nv'9z(I\]RD^ێte;@RXR&q$vI9z;vpIbI>(%EEH] $E%e@hi#nx'9z(I\]RD`te;@RXR&q$vI9<햗pIbI5?(%EFH{^ $E%e@K4->z'[I|]RD>G/"GŒ2~ QK0ZG&T%XRI>zK4->z'9z(I|]RD>aKpIbIG?(%E4->z'9z(I|]RD>aKpIbIG?(%E4->z'9z(I|]RD>aKpIbIG?(%E4->z'9z(I|[R'5nlTNکE|Q%E^ $E%e@hOkc>z'9z(I|]RuTpIbIG?(%E|X^ $E%e@hOkc>z'9z(I|]RD>aGue;@RXR&$vI=pIbIG?(%E|X^ $E%e@hOkc>z'9z(I|[R'L4nl%EooG?(%E*)}N )rP,)E|Dv8CLH"  >zG/"GŒ2~ QKRs7kb~>zIz(i>z"  >zG/"GŒ2~ QK'L4nlH=K$>D.)"0'}N )rP,)E|Dv8CLH"  >zG/"GŒ2~ QtK- |nl%Ej%e =.D.)"p`TIpIbIG?(%E5m>z'9z(I|]RD>a[pIbIG?(%E5m>z'9z(I|]RD>a[pIbIG?(%E5m>z'9z(I|]RD>a[pIbIG?(%E5m>z'9z(I|]RD>a[pIbIG?(% >zG^C"I2J@hO80v8CLH" ;|nlH=K$>D.)"Gv8CLH" ;|nlH=K$>D.)"Gv8CLH" ;|nlH=K$>D.)"Gv8CLH" ;|nlH=K$>D.)"Gv8CLHݒ|®G/ۡ~IZIH %e QK'?URte;@RXR&$vI] >zW^ $E%e@hOwue;@RXR&$vI] >zW^ $E%e@hOwue;@RXR&$vI] >zW^ $E%e@hOwue;@RXR&$vI] >zW^ $E%e@hOwue;@RXR&$nI"0ࣧ}IzPRE|Q%E^ $E%e@hOjS>z'9z(I|]RD>aGOue;@RXR&$vI=pIbIG?(%E|T^ $E%e@hOjS>z'9z(I|]RD>aGOue;@RXR&$vI=pIbIG?(%E|T^ $E%e@O4=>zK$=J@z\()]RD>G/"GŒ2~ QK'i{}N )rP,)E|žG/"GŒ2~ QK'i{}N )rP,)E|žG/"GŒ2~ QK'i{}N )rP,)E|žG/"GŒ2~ QK'i{}N )rP,)E|žG/"GŒ2~ QtK +2ENɘhK4MP\(0C _bDɸ]/#I3~(ajޱ~?,GX@p#6[|gW%5DdŏuN̗}o}xW!\J^W&y~z^<ٰMB-?XÒOOD#Yo}?>8ݛlߔoWl7(38j: +c`7_d0Z$vXo_ZdvuE~}_fO$ddI6D@ #WL͊~u`gcz7X.2ȡ7Ӎ5]U6r[=wk^S{26o7Vd4-Zk[œ  Cj-1Gmϑ9Bs_ !5pACj-1G@qKĞ#sH:C7Tg8sdPB7s992Zck9Y2#sH:ڣ 7axsdPBQdvj1ˡ988tRP""l/E4J.B hd)Tr9|-Hd.D#N,ˡEk?E"!قfiB\,2_+*vT4KCr(dRȀFYS%C!עDfD4MҨ* +YdvU$2&-hUP"Z"sb`8YZW%Ca(|Ȝhl]fi]\,2_% ;uUP"Z"s5u՚uUr9|Ȝhl]fi]\,2_%2'Z#[WYZW%C!׺j̉UkUP"Z"s5u՚uUr9|Ȝhl]fi]\,2_%2'Z#[WYZW%C!׺EhJ.\ZWȜGYZW%C!׺EDY"*OcYYWD%*\L.IAs]}-t3?pAzu2Zck9D ܬ9Bs_ !255\ކf!꘣Zf^2GoNZ u-G,H_cm\Rk9n5\fe!꘣ZhN,H_mPRk9v`A.HoSNZ u-[KEFdv0Ph YDhR:OSr(dZKDFYL%C!fDB4l* +YdS$2mhSP""lAE4J.BLhd;*!Ur9|mHd@D#[S,ͩˡEkQE"3"٦fiT\,2_*ȖU4KӪr(dZW-9ٺjҺ* +Ck]DD՜Efi]\,2_% ;uUP"Z"s5u՚uUr9|Ȝhl]fi]\,2_%2'Z#[WYZW%C!׺j̉UkUP"Z"s5u՚uUr9|Ȝhl]fi]\,2_%2'Z#[WYZW%C!׺ED3~ uJ5Dȇ|vU.u!i#N'>wٜcj{$~œnoomFߤS$>ذM RTV!\eDV˭{|p=ޑyW_ ^]`eO(@5 p_Qd5= "mv{=XV$KH&Gqoc갻߇ x'R61A{J?o,{J&߿zN0op`?ݓwժ){.),&%`bǶ1r0[: +1a,"ۦ"bܾ?ጰ#)1 H{5|P*V6Nku3+Q vGu7Ist4VYo4 +\EBï{#E6 +֯q)D]!yMEx$}buoϰt@mv]]gZuul>>Ozқ2զ$UlN(y,l''8K-Ɲin8|vq8' ^ĸ>'q}n0+g;Q@aw)q0N})q}8N݂q ##`QvN #j1Ls )S#`0|Xp,agqr$Kp4`r>;8{ƿKb\Ÿ>l`\0Qvz sbܙSg猃qIqׇk;ƹN"qZ;܂qq0N$q}8N݂q ޣ#`Uv& j1Ls )S`0Np,a獀qrIp4`r>;8oJb\Ÿ>l`\36FUfJ%lCQSl-H4fX>l' ܇k2()#s)H@s'εzfkA''vc$P 8F +RC$Q Y[N=HBF1R)zނvcR䍪, RKq3[Kr)'vNzނvM#"oT%)ȥRkoA;ւv#R9Nȥ{ 5p$FIBUXr)3[ ڍu$FPbɥ€cRXs),enɥl-h7R.n\^]ȥRX +r),Ź[N=HBF1r)zނvM#RKa)ȥRkoA;ւv#R9Nȥ{ 5p\ +K}. RKq3[ ڍK!8i#-hd1r),\ +Kq.ŹSl-h7R.n\^]ȥRX +r),Ź[N=HBF1r)zނvM#RKa)ȥRkoA;ւv#R9Nȥ{ 5K7\ +8\{ کgS#R9Nz, 8F.EިJSKRkoA;ւv#R9Nȥ{ 5p\ +>+ȥs)εzfkAr)'vcR 8F.VKRm(B%B;HBF1r)zނvM#ϥ +r)\s-hZn\ +!IxoA&KR`Xq.ŹSl-h7R.n\^]ȥs)\ +8\{ کg)Bqh7F.E/[ЮɀcR`XA.VKq3[ ڍK!8i#-hd1r)\ + +Υ8ނvꙭFʥr4ڍKыk2X}.VKRkoA;ւv#R9Nȥ{ 5K7\ +8\{ کgS##R9Nz, 8F.EިJSKARkoA;ւv#R9Nȥ{ 5p\ +>(ȥ s)εzfkAr)'vcR 8F.QKARm(B%B;HBF1r)zނvM#ϥ +r)\s-hZn\ +!IxoA&KARDq.ŹSl-h7R.n\^]ȥ s)\ +8\{ کg)Bqh7F.E/[ЮɀcRDA.QKq3[ ڍK!8i#-hd1r)\ + (Υ8ނvꙭFʥr4ڍKыk2D}.QKARkoA;ւv#R9Nȥ{ 5#"oT! +r)lŹ[N==R.dѮɢ]/[ЮɀcR䍪=\s-hZn\ +!IxoA&KaϥR؊s)εzfkAr)'vcR 8F.>VKQ\ +ւv#R9Nȥ{ 5p\ +[}. VKq3[ ڍK!8i#-hd1r)l\ +[q.ŹSl-h7R.n\^]ȥR +r)lŹ[N=HBF1r)zނvM#VKa+ȥRkoA;ւv#R9Nȥ{ 5p\ +[}. VKq3[ ڍK!8i#-hd1r)l\ +[q.ŹSl-h7R.n\^]1r)F QKq3)9#R9Nz, 8F.EިJSK(Υ8ނvꙭFʥr4ڍKыk2\ +GA.8\{ کg)Bqh7F.E/[ЮɀcR8s)enɥl-h7R.n\^]ȥpR8 +r)Ź[N=HBF1r)zނvM#QK(ȥpRkoA;ւv#R9Nȥ{ 5p\ +G}. QKq3[ ڍK!8i#-hd1r)\ +Gq.ŹSl-h7R.n\^]ȥpR8 +r)Ź[N=HBF1r)zނvM#QK(ȥpRkoA;ւv#R9Nȥ{ 50h7\\s-hN)Bqh׋dѮ-hd1r)FU\ +Wq.ŹSl-h7R.n\^]ȥpR +r)\Ź[N=HBF1r)zނvM#UK*ȥ(PvK.vfkAr)'vcR 8F.>UK*Υ8ނvꙭFʥr4ڍKыk2\ +WA.8\{ کg)Bqh7F.E/[ЮɀcRs)\\s-hZn\ +!IxoA&KϥpRs)εzfkAr)'vcR 8F.>UK*Υ8ނvꙭFʥr4ڍKыk2\ +WA.8\{ کg)Bqh7F.E/[Юt\QGRPŹ[N=)Bqh׋dѮ-hd1r)FU\ +8\{ کg)Bqh7F.E/[ЮɀcRPTA.UKq3[ ڍK!8i#-hd1r)\ + lC-ڙFʥr4ڍKыk2T}.UKARkoA;ւv#R9Nȥ{ 5p\ +>*ȥs)εzfkAr)'vcR 8F.UKARPŹ[N=HBF1r)zނvM#ϥ +r)\s-hZn\ +!IxoA&KARPTq.ŹSl-h7R.n\^]ȥs)\ +8\{ کg)Bqh7F.E/[Юy +ySK)Υ8ނvr)'vNzނvM#"oT%)ȥRkoA;ւv#R9Nȥ{ 5p\ +O}. SKq3[ ڍK!8i#-hd1r)<\ EhRhg)Bqh7F.E/[ЮɀcRxs)<\s-hZn\ +!IxoA&KϥRxs)εzfkAr)'vcR 8F.>SK)Υ8ނvꙭFʥr4ڍKыk2\ +OA.8\{ کg)Bqh7F.E/[ЮɀcRxs)<\s-hZn\ +!IxoA&KϥRxs)εzfkAr)'vcR 1)Vry9UQxg\ o;ż#dQ^?\p H(ZUʀ ++*½%B?ǵHbǽ1+1৊{ ׿?[όv7S^65NgW%kA?]ok!yM~z^<9ɾom6ߤSv&K3 ۾:ޤYzOgfz-hgU-OynT)QgWG)VA:Ϧkd cL"Ук!9n^m Rx]|{hsQ4V+.U)ܓ!T/)'VGiI?o8l1Z1 H͚]M f/J?m :6xZr[=z>ض#3I- +F +--]EVCeU5Cs3b4nk=$߼:i)3;iA u$ ֯zӳb@l˪LٔN{:ĽwkGfj=[n~&?2ieՆ*m5-dK1'o!UlyIE*,lUocj +1Mo2Ekg?5_fvU[māh%Zrx"~,ו#7qDKqv 6ۻĔk}c[q`уfuJFHs+lv# +}On:z cG+:J@DlmD nnxqj+y;0ͶӁ=AQl ~<#! %{FO6qb:ݳ@~p{Ø}aYO1vALmۆmD~lƁ5+l5gEl ;{ +¾g[Ab߰HèQhs +Mopi",PSÂU7s\2};Ήح< +tCӍ ۞C4)}suz;>_@cE {^cukNq~g&a>@ fRNk&D8h2"e2l2#a bv`aP)auJ &k!i L-sh`x8|9J~% |s"Abن"׏(E "vkRX \b6s#Nj09 y8"84`ݜYBEcx}sh+ +!Aw'/4 `p sf+1Mt4-xA#bԁX&8:$Ҭ[#;`A5b/mNiҖ۠M0 +BX6k .$6iF`"CO* , ~ $"l ʋpX2Y:hÄFWqf;(M ӄS63|@`#A,Ce3iV`DSE6QL]u3!53J<\&pt$1G:Z"86 Lyf!vǬ2)+_otNQ,r因.p^!iypLHv[^Ώ980h;NNt͎UPn7{,|L=Sx$t&'-Gn1.I,낿QSQXZg&42yl=lIBNhy3`^FxF!"ԌLԮ< -R~V0Y֕A4(Fȣ03boӹ]ܜl4uk.h!6(H&!5bиAkҗsW.Dbf&E}:Q&#R8fs3̑e(ev;n|M5DLdS둤[Sף DGnc{w1LQ kv]l;4BP b;1ω:9/r'~wL@dP"wÀ<840ӧ68X +(P>' Ʊ +]A]?6! +|;vwފLmG/T?3(Fd($Qfyx'30 +"#%u} tPs@E=؉#5umNp u~bN Zǡaς-!S7 0ŁCh5%6xF@vznt"ӵ]6`o z3@= ssoB 60(xڬ 4C' %VG983+2 vp{>D ~ %klS/3'y" N m"fؽuHɨ ĵeֈL @дH3.m¦C{`av΋b2]5cS|Pt ~3>p{'0Z ,†gᚡ5Nz{#uCDihĎgtx!jPX1}IIN2;bm1  +h ڵ j/z0gt4@Yahu#Xb&wؓ)uZL]!wyiswk׹3rEڣ_6 gf`86-8a۟>Ga{VH#J]rLVn4n"÷}C!lN^ؠ{D-Wf ;޸DAsc>S2F?h ,?rB#@=1=ZaBct&6Gݤ "dB@5G@nucۘD +i58 oMYXr +8 0Z; {h\3{o() `p."<.!܈2y݇> Pl$sslgK,C=s*`K?6 ̐;"119i5㺎YBtŘYu`NDqwE d4!Ȏ G҇C 4\솨}-nwz'QA=4((ŠvLμ ر 7̃)2K|J}5 ؁C: ۝Q7 Z~l4g1v1!G!miȃULbǰIZս(d!#4a셆[c[ֻDvRKqͼ9 eOj͏'&K=rewuoZ^VO0x6w_[_90^dwoٞr[ߺe^/+n,ӂ[T p$ynW&@aRl]$^x?y+mBV4Ёx6jT$1؛zU:?MCY'Y%VkD{'ҒjmLQF[ft[.}E ZqҶ9M.!~UW@1 ԰CJ13N+۹sv0mӑ0c߈|؋)CQNlpuECE 0mxqsq\]Ȧf<Gr q&g Nrp;zhkccx!wܻq`-xĢi 859x5at (706_Fgu"p`M0IO`p&Shvo]] +v\_)A"1]P2.C=s!؃vyٞncX٨3mzoFmABA<}܏Ao(N:ss13L\Vȣ^A34̸pkMQ dEft09pk9tOʄ;qa1J4NWPuL3ATD8faV/z[:ڸ{궈:tĦ +|b X/a PciԱ]|+m~`$Q)l'z +ÀO?͌ j`^leG۳FEϗcUUpZ+D9kSYL+QwJqJ/}Uby<B bo}7;;}HVg<~+'AU,mF*8@ @5y+ +`<4"ظqoXxO3H)@B >GG>6wON)9oz1W'1fȏ@>S}{wQHœHl1d`lRߣtOWqA9ořP+di^IIPZq:JNN D_k=l$y! RKj[\߱a,LW&`?6 0fZ+fN0:f m؈]ټ. +36ԌX"E Oy!sC+`-[ƔG\Ņuq0H eV82$ @T!Cej6lTѹ 6hE=ˁ{bFmA䘄uɬ $et:-lO8(.iԱX2}@@-Xp L3(7G@`6nا^u-JAABKf@1 +O9e +,Z>㪜o3öPx{ƑKnGJuO 2MC̯Dٰ.̐ŞͮҀb8&jg2KNtcv{8g<7#VXQ>wXȄ>Dni*Z6v. +<˰# d3aCȌ݅rjgPwȫsVEmPx6b1+>c)f `~6lԤ2~˫>6@u#Řu$*Qi`p-ߊ̀¦dr2QDAOEչh2DY!mK Ṱ/;7"A|$SmM5bN#ր( EN0@}< y|A$`3rΙ)N12E~^^`J̌!PnS8옗PuĄntFfuO0O8ȉ(/ n%lC"~XZ6337ڿ17_Fad`:fQD&L;a˭#F@vHe94۝FR1M&qdxN`4l }?6w6⽥螽ZyijެN"qy$/F6hct!rQb:J+N GpB5\y.EcDȉLu5wӉcqhH*2XaJC 3x;[\uF3Kǁu ^+CǶ/p4`S؅s1D< XNĵ 3D@80/Bе:&G1K*fs`dwĠt2[PB1rB.;6LIֵM ! q"Pb\ 8m.mwW0ESJ1 }N"|fX/e8S1u_܆ ɤrJ#;-z H`|6!An7hiT* +ӏ,khx2Y Z/Z;p NAvdyp ) +xG^ʉx_w覘܂$S|^鏗 fňFU/mS oFc{4y|$7Q C ^tGV[*E7$%#ۺBqG@~װɘ^=D.3kjDlMFFLI h9~S0  #:B3n;\smQna0Ʋ}'qMl`\S5J] Ќ;Mbd\F@cwָtvUWy--s|cE4cF粀 S'Ys2"%XN"8DŽX8e~`,"7ub9NMm?etJ0읒}L)GGx`20l:L맙O:`0Ƚ, +l xsiZC%pbr)BM3Wr͢:˭mŮi80` + ,'U;GmX#&`&54q@ GS' +mNaX)22 |b C޷as- + +H}90)v{%1g°)A]HxSL DA; +ڞmDS+&Q[p&Apŀpp4"/t wʴI^1?Wb?Q`X&C>v`u”a#ص(*gFb"_ +v;8-gmPmG28MVPex}0=݃pG07>_F# 7OIK& +AbӰcӵvwmYg#+ }S?61x8p2r%{KE$Rzhc6 0+x!W;4|c?2g*!+#A?f`x ؚ-Vs* K7Y>N08fGYa{fZ_m2&ش,dvxx:g7gvz4qᙀiЃ:ݺفӱ H`f>ALcyg*.h); y<ؚABvY\xCxx-WrqbGqw O619b`^<Ǡ^'B謵>}C)#}yA6·x #&hNMQ@]3L,r"Nwʼn~1Dc3& BϠ^'qMؿa7薿s`A :MMgzO.-pҲ|cx/dw'Q )BM{p=y!^s{E:oy+}P L0ߝLӸ8)/ +158~!8{~hfLŽ#s>DÂ.B_ǯ^`/;)'>'}<{5ف3¯ڶ]4.F=;jÿ́7_kY lfec5N+/[TZy1ځCIՉ€xኈ,UqaLQw])N01`%!<l82Bb p; hĚE,$ svb`] 8.:izKɪeFp')8IlzҚP1p79cdb.a3„AKÉUH;t&] qz3&I_88k݅ޤ0^4mq 'y Vxa(e;qk?`H[oVot{B.Կn@BMb0XYQQV'mW.-+6ٚG +aa#3)p[x&tci!7>E"A1LSO:0t럘yF~W633p€u%r:O0elN Sdx$ 038tػR:Ǚ n肂lF" +F!;. yh&ꦸۃ'tbUC +z&2a +(S-;좎'ǁ`76"IG/5@/{ ZB&a3Ơ=Btc3cdaLL9jIܯ7G6<(f6Phư jKѪ7+8}1I}d2ۈPr= +p}&}2x1ҢoFe`+wQ~Բ]O6i2"u%,fr +`ڡ,nLiwYf3 ~NDHN0nMǝώN_O:`@NZkY&-h3Dq쒀3Zn^o؏aÝ0W."̉<on`R +9!ĝ^HϩiJ+}O4|ӱ d&Cw⳺fHw*gc6 =:ш;A=&crx ³Wv}Wov܅-0m44w>I9Wj;@KuEpn]>@ۦӝMjcE:p6 ul< ܁n'”ݱݝp>l4=_k4tL#0cLJ0VnYoGwܔK()"-LԽ} L}d3pHsBۈ953̨ȷ=?2bbY~m u[2xk"td0xF )Ltuhg5ʠbf!1͐gS8Sƃۉ[Q'31(Z(RStcybȖu018քpެɮ~x}gI3Y|>:LIM %XTe˦:5h%{4Ï;\8żP&,I:KzWBOʃ#Ɲ][B)Y͸3'SL"O?uYKϿw], +>rmEk^j:kr*\>h\9|q'Y-`>Z![awvVC>|+%M(0r#`ע(hg1۳m8l+gwRVm4]:j 4klYe3ZoGފS"f2/wiyQWǏ|LhFZ{ ] +"(f{}6_,oٻ>8X2ë'(],LyB B[wWolEɁDPfWGȹN+K`LK[Vok-cy^PNt1˔ _:J͆ÉEciUƂ;9=-[La_ͳe_ +KXI=^e&i;feښW6SkǃKY){}joy0TVLy.#d{ h"٤T{S}JDLxt_7ț.ƫ&xEK1֍W+-:\k֫l|3nKwunfdܘ)k(keR"*:R|'Wj6tşo@򽍻:5^D!dЃOnU}\C82g*"3<ڦf5_\8BwT*)v]~}q{f"SGW#%gx0 -҉,:e:QjHE-QSB jRCi񤫗[]ҋE'Nĉ*o/Ң!אKM $=s |xazETd})Zҭ`^e*M +eW7\(wThSzn*Nk*IqfSn+:R4''L' L52Ef:-C0~oU>w<*ԟ"O2 h6P$^{ERՇQn F96l%x%>1.w'}]`0 _ݞmdK϶${ P`ѢRms9{XRLYT6-g5=ZITJCS3 +TiQ ]o zV7M~^oyMEUF)MeBn^cu՚ҍ嶘}5~l,ru]j\SY:ثvG/'[d0RQL ̵(W\ζ$z隄 +,uTn%rޱ +#G0e$ԠB! \*7Lwm"F.?YСߞ;Z$q:iF>TM`'UTj =mJƀTSYUS5;͐FQpexf;Z(Ewi5L<#z QʒUPugWu5<;#j4& ʃ YZC/O*پ}XK,jBxd]nm/,q>7cQvMG?2v4ڌP:v'?ް>'P󓈎aEmmr~GvgKQrV1|ox_pFaWǛelBp޿O%̜t*"F"D90Pd\r~k!'Ji q`\$:%駇%V Yl(Xeڋr!p1}9v@b 85+`Sv(ڜN=Ti@d"aFvhʰJN^T.9TM=MOeknQĶENfmhM+n80n,㵬 HR~ݺPN lBrz +Q2mrΆ[*^)PQy<Jѡ q#5YmOX\8+;9wa,`ëYMR%Rm_%j?ׇ¼ڼNDR=(0W "7ފTl^Ye֘G(Tjv"OT[y?\m0Yo5m)ŀ  +pV=7Um@:D*0ҩő![hb{ JiyԖ-ZQfATo2c+8Oavgg| =_M ƝBgy*E+?YJ v L&%VU,&z#Յ߸\ׅ*k+ %14'j텶vq<ʰ` A&,h*Et€Fyu1C_ S^Fy[z4qz9' +9uݠDeUKoJ du2ߍHixNB!o(\m)\H2f7(BIuJGQ&(ʢcҜC-G&]:Ydh03β+|}x% +='{*#d!qȠCi&e-Ά?ҁ՝ʞy;W+9<+Dxn2ۍ^_Ww9Yyݟܟg շ?~eXM>a-Qنpų +˳sQ<~{Ⱦ>%6d"ׄ@=yvmO[|{cĨՁܿY gv#w\6\W`0\ * [( ̇n)iK+|FrCE&/'RU>߻#\Ѿu8qeʘY@@[u=q&Sh]pB&%WVtΈEɄ.ju%oBr^XZ ̬5|w*MB]>YƓVdM>ؒtZAH-Db(&Y+?p uFQn];l֭׃~:1$W{,L.T?={ D%b8ԀKpXNdgMp$$ܚT)S S$NŽї^N>SA*fy+2șDiFES /Bԉb(]"MtZT0_ rhAhQ6xnQ] 27sԹx<>WAj*ÓcUg\\|U.O_^ 8f(ZB "JvᒬiT~L )8v,~N$}[Sg/:uzj;2Gypq1T.:v*iy/1'Ҏ+b+ +紵D/c{bޙ/g{CRcRXUѿˇi\omڽcofʎζ\g4R lbV]]-E+bl?L˺M9&LʜO,\߭SM6nMnAH`duh msɡ]fsf +?s J^㬫I?DJYIK C$]TuǪeN֬l6"MdENP1zޟ6q$ >ϯVk]dޙ i[j҈R` B qgyiqz{xxQ9o۷e~0' %?@IF +*>ftq SIqW\<^OPb 0b.cG9Q6U qd&3K)(k>X ΑUÏ@{Znzr*0Qv ~Ϗ%il?D1͒= q٬Vȏƣg*-:[4IJ6x4aN sHIP ej$nKN[GW ;UҦpBٗqxHp~~ǠL쩓F fap7*z$BrNQBP۽P#X1EeNA9s }YX/@ŕ$IX82JԞ ϝzD6w95eq֊fa738IU$,A/$G=MmAr + 8z%c= +G3AЫ9Hi _K/LՏ`(B}P7,@l(yqxk". EJ.LD60J#crh^Ph(Vem8J *2@Db C)k>oRc"TF-&r +wٗvpVl\r\$~Ğ.nzN?P N`⏏Yzހ G%$Z5,QiR{*@7wh7xW! +n##S9%p+OK>s/zo;JčSA'vQb(\;@c JhGhCfQ:.Y709o3/)Dh$2D7^'9qlPq <#'^Ns2XKVXtة8V]<#'mҐr/ pdz)%_hM[bAgA߷(=®ֺxmHaM#k$w \ H}U69ZMirɳ}- *BsK<4|UĚ,O8Aظh.8N=QŅ''꠯S;ƣ˗ø6)/p:K%|$b͋x K0”DKT ]S,ۆF\AsL6}9.yɥ{Oš&%+z%Ѻ`58kT 2``s;o +[˸xWGML9eD;6YoKn{K#x +{.7sSW4PMP7vMOBLt}A6~"!(}WASrlS}vAyQUBߡ̞8@Y MLy"&'ʸ[J%gK&9ǧ}k#7O{.js8QMAȞ|pͬ&͍Iæ +, +'LqG.ՆE +jO0"ϼwn=qєU.w2 쪲M;?X50 2@tˬ|x.:2[ 3€$*kMZ`|UUz2,h`L!Z +K+&Ys% z"-|)a_=(7&.iy;t]_[L)(sSX{jDZg<+nK:7?:8 51A`g!AW`53(Yf\0W[1`74[p&cÛ-P##7̲2?lN~pΉnΌӮ>uFM-Nk`F@;8x,orKnEɧMJVSxW4pNoM8"pp;uaȼ-QG}WeY|w|~(`EzyC6@^y _r~* _%|?߀Aj1Y^džnsC[S̱ +o9uߦ%hqpZ,5yYe_MSj'<:"6u@6 v3I. +C>9 ,Y4# 3?Tg@OE3]uFBds#F~Q؛}0 +-KYo wnsmR\GꖮUvGPBK@ |r`ce=6zC2G0J~8z ~(Cڌ5J W\|Lr@΀7s쓛 䄓P=UسߕrjfHWiSN%D?<-HZT0_~T!>mMs* +#EmӢ3lwqW 3*Y;X7&Tg?V;v;DhߧaO~K qю U8E蟉(Q3F9𿠅swmۙ?]s>Dߙ;s˚7fzĸ~-]_Cs7OT ⶗%~7 +m7~dX?׭u}Iމd;M%M}5Yow@3eml2n6+uF}{j8'ޠJ%ь3Tyw}f^gwr}(}Ƀ:y;˄x~w/ * 6bݝZgf$h hW~/21zWm.{=5*d~_E{X\ܞ{$@ӝ^}2'h/D"YHVGw!unbT&-&:&٤;ؤ$Wg>Vt㟆e0wog>^aޞ65xIÅeVgћX&Ew6WcޞʝeӵLweL,*Pݾ,5ރ*}p3z1$?gBso} br'#$9I5PXˊ̫8+VdYo[Xu=?޺nnM܈l_nRfSA9tn6˅s2:3m\&KM!zvEVa:jSEzĽd +F8:!7:9\ '-;;=9a^F$(GaTIʽ2є7HYGH2G +ۋ%~=5륉TR#2XoJDžG$` օ~q슁8P$cc;qv\<aQ/5\Myi!휴vN/bZ9lݘ+Su.kq۹b_.W?U yb9g[τ9!C٬DBFPDqMkƆ}(d=Ε.&?hśpw" q6!ZSY<P>0Lى|}qdgufq[3BqF(#0BB&ex6)=|S +LEXu%0@8fT{.nssݸ-mA[n d."43B^ˤ.uq2Wb/Ӓɟ +]9Zȱc+i]c&F2qGhRgĦ`v/u+Or%ȌQ`La@s ;xyjv)P߇9XqTl +Y8+XSg|2^FDiAc$¢8Ï+7pX~(jl?Z3x&.D3p&bFtC}n-'U߈I[ѭr-.GՂtNR987{ cg5AQjl U?lB.lj6H +NWob5Z9[zQTzDR:1EytgRu&Uuwvg[lml3/%:#A'gm5ZڸBk!/Y[Uف"iPP柛ջvh&#ufZ fL˙iusgdqrZc SDH+U#Xob2G9_D\x[[:u,N}U<^jd{,!hIN8r!8DkB-A:A6uQlwliGNyTԎ2>;e))Gsn/wg70sv={'{/6w^ _8GS~>1z/yQ aQs8!ҶYe#,BrWw`SbWŘDUS*,dHnV8sWptŏj w!\2`!SpJr>jC +fՠǹ60_&8Ch{nX-~WKʇJ^ RzQ4c|ހMAqY Z*$ Q_{/;b3,mx"ꌻ.m&ጻFi՘%:ۮ Gr] ܙv=UӮm/Li3iWcn,xe!GRGe+mS&\ƕ L׎)LXI%Rܥ}n(jGKs5DXJ,=cX^BB7÷{ -D-ZGh"p&6j` ?t0 hHǁ8eD55(]?p51E3ЌUljj+M9Q&$;"'̤*,V Tօ$b7?Lr$H@H3%3= +XuMr<ҩμ )K,.y$H3T;( _?>aBl3Ʋ;za­3|f +L@7tq@PoN엀B"Ds  ;CZ"^7$Fbi9'^CVC~_ +BSm΢yLA9ZTL"8SggLGh\MywvS!ԹO&еrg=^6׷Lp&еMk3/Uj 3v&=Dg}AgugL[3~&е, 3v&2Р{@5>9hITg7]'.ɣkB;Kק~9j hRH߇VWfCc{8-m4*f}^":~l{mA@zj\5ɝHƣ;cW6Xj-`:@X>n?(d{j+aK%b;>U}q8I_sJ_/Z\<_ mO?08Ly%=8H)G>| B} nw3 3/{ ,c/ P;)u(ܙ>UX?-8XgLcǕς6p:bB0V7'>ܲ¯gY=륣EEh}nD,+8H *{dWQҐ3pf:3 +،BWn=w&F|lg413xFJ8[ g+1[\.p@hg$5^6ra%Ոqxn:.|YY3˺`Bݙe53jDZc\Yc]5V]~Zf pqk6Zc"ژ v[g7d˜㰑mk7Wuo4xZp<jMs[bNFV) 8Ǧr6\ۆzw\Θs:rV]Ӷڵyx3"V=pv^% g켜WqjDg |pg,嗳r_#jއ{|֙֙ ѹKJxVQc #p!;(^ 6!취.̪ +>XTօ 1sA! 䌴);mQv#I/」U׮$ëxD\t*5􁳘;~C@ZD&8)]tpJy *=Ai5yjxE!9L5pFT=XMDZܓ@3HuXtM+}3͗n,TwHijsb}BhnJA5bC/wm`ZdEn8+~50ʑ#.i#}:3X7$d)֞)dS6zCK% Lݒu;6+~sצUki7IPk0{K1R$&|LJ9׫0z$L}Y{=S1A,R^ĪSZJ?})N BY/(@h-Tp6 DEZBib;uנ'gL} Ҍuξwun;35y_#c}Y9oݝ9c}bpf㥅?-8^g(z2Bg{A[gpgly3}3uX >{w})xK~>=RQ.ގr8 v'?@[za^e'vɊvt{I j&f6"m[6 cV>Nx_/ܧK a}JQ1l8t+6F솘FW Ϡh/G,kNKs (y>TR`ۯ'b3߬欹 +z c ߡC!<~3>|鏂zx͙M8bR5Y/JȉPD\C /BJoru-&Mj΁1J~Q>94Eoj9_:"[$ya@Fe _=㫀|Y|w|uv%/ 8FzyCG^A +%WpuH>o V|,=t%-7hp'6%y@AffҸf+Ǫn.TB`L5]TyQLqTΑ9R HCE;R<4T|L&{6Mky6M^WݦbpJę4~Z5pJ4~KU3j眕].ZF䨕u|Zƍ汅p "3,AbvaEy`_\+'`s`W vAqu ^5hpz^Fa9|9/5$(J:V:lv;Ж?\V+0ͪGvrce:~}О\OtqVSQy]R.WGt.OGڈcx!sL9cIa>t>]rGڈu[[ḗ[u~uVY[^AνOGL0ھ&?sd5FɎZ>rYm45^~]j3r~ceKaP_߽7˂oqt}os/~U烿Ȳ4__7Q71EXi.|ଷ{W/|\q4'~fSp{\5pQ8`n&(G&DϪi;~ugU"'z'&7^EFT7?~s{^@~0cP-DD#fqB5暎ʸ#^] p!41x45!*߼*5.##wHwucqw$jqEp\DDhA.У," tm:odE+q\3FhwpF@\" q`d"lqE#@ ^".DhG.@Pc\E x5-%;3XclN/; cQ"CC=Udl11{8N6X,eʩ0=i?Y>\wb}^RO}-؉Oc-O bKn=DH7W39K]$Dri""Yt-&*M/+$H ?J". VWA#E#'ץU)E\Y*Et]NNl%ܸy1KE<ť{ď6& +9x4G *P]mPH\R59/ޒyY$GPZr8IIb߹k]_O:yOwzW& ƪrHߝ{ku~c%NICv:i9++3ip.%;q8RR:R5XОaZܖ}r ̒Y3KYrS:uc[#iL଑IpΘ>$|vigltӜ(Mxi"<ߦx\l9uΛpdy:o֑ st.cplEΑs9#mt9^V9{qlKΩs:eA9u:FNآstεz\;stl9x:OyaV^u< m~_$IXIDleA{CFkC,&0$)L>7DGD|?cS(Hą zh0e$Rv=1%=hO# "[$*ILRŦ8"Dտrr^΋yˋ> 8_Y 2dBEyI3sO269{fߓ.s6l6|aٰ0x¹0 3Sf$hr iRYm +Ӛ +^gSN}bmzq^rd]GNu@t!P#}R %}MqwB%%*w%rTr +KiGpnsW6'{tZVns^skhӜs\b5*_܈9ƗikvzJ7^\zqkIΓnZ=XjKP1Rڛ ˘ "B9鱭0!9u[B@qX?5 +q[A6oerYF.}*Jd=ukҟ !—  sѸ/֣v`Av Ǯ=.i ߺt:;8s꬧2O pzdg,4qӏrO"SM錩/8cjgLݐSWbG!3!u\uQ!m!"^q~RgB7g&3(yW@k7<`Z]2_^Y-&URoWU*GơHJ2RqiijWLXAQ,L ,ɽ&iK.Kה `vvϷ+S,Gsܻ8O=Ϲz9W'TJUO'@&)57*rr Y.0 Ѕ$>KH?Y¤ui..q͸-9=p>]i‘.;z5ҨMTe(vIEM91l( 7%xZkp})lm% 46Ps q9K4FS.nU-D1' p~ +Sd_Bc +f_ɴRJ0VYDM$Ԩ+txE[ªdo8ٿqZ ˱Ը- x{Ɩ,>A%o]i6Ȱ`/) ܾ 2&g.nXK ,oNq|uXbgIF}Lx)i$9+1lnFtAG #RλSK?}ydN:6_~|a0 .Pz(^ΚSŨ&V>uƪuIG֤e)]>NKv=PrUf+ZvJ "WF:xbkyYx^Ļfޖp!x&<)y䂝$trf+P}]a/ @ꨘk$"^Ee1p_#$}&vrQ>ID>C0CF%.E$pJ'WG$#/w:Uv1N"?X +b%C+6ll\>y9YS\I#N = D `/}@0?mA@zj\QC#L=GuAS_MfCd|-Nar'PRgԷ-E/IXl,7-' &;Q1(Ay.+N(ʍe%qB9YwsmoqKfBjF3yjhMI\1(wEoE1y_39z%퓳zqufvW^NqBQr\)buج%-Q /ˏv;ΆmS~zI}0IOTV%.GӸR.lsq@w,pA!Ë#Ӽ{e4pnLjx[9ެhbnzi(B}׬F=}b~ZapoYQEct}?;*kiM7 +cy8Mbl4'<9yg25 a<:ehQOQ׫yU;3wFΈ~F ՙҏnJ?$8Sz)0&mvlg8?^n{W|ttm™Ϗ(b>?d,g>7oۚL9cj,߆5{%&Cz+:yg1_b~}k^3wɗ/V"Us?A__]51Bh.0_T{PkF&6$S~ 4enw֬ EрVekt5oP9\ y%ǽ=! Ϡ"34|UĚ<5C>L =ጕzɞwfMbF/ 3i=_n jl䪬 @,U纆jsb qImPaT,[L[HQ1~\֋vNXC1/D]tbf+7]e&\#\p.:1.6Sg8VsvnbőUV0x귖 l#4+es*uf㥟\ΌҙQ>N3F qP%$Vq eDx z#x5Oj jK$pYnx?OtX߃#xkFWny/6/cE&Mwh~E#A44>hoa7M-K ދS4 >*$ + @dPU9ofQժn) ڜn7>?+vo`vsUq? 3/)LbicQ(t%2D7^'9qlPq 3)cF[@ 3/c LSD͘ K Ƭtј1Bg +sD +xg'DgCΞ/KXk8|&RTBrF vaj8挱YI &3a3o98'Da WhhMd'L2~X=#h3"8=$CzȌ99Gmmf 1/~9BUCM += 3M6Tޥ P8\8mbűUEqhܢmƝTgGLtI#9EÝlPr?g_09wSN͍,-dѿ6"{ʖbNbJĤz--~4i,6)A2j/KԗrȂ3o+TO %/cp5M{l+ۂ{dT\W¯ /Z"u^*K Tj8UvT +Ov~7 @B8z=(!\]Ho)&3&eP~ɟ$߭&N>jɟ~׿uTͤX])UQV4;Yל +&e%5'; +e(@&3p#>lRWr ,P99a\rf}N"pAD@NP +5 dػ$C0mV;J lƒ~w#Jq~wL[<2i W%ݗLLdaשt-%u +ㆭwckC6tYnĻe쳻$CvC&R\jߔj] pѯ\S:b)L 2?9k4j@# wHZ~43Tyv/sHM #op {hxbd?@Y0Qx¾<uw,3bZ${ jP4@d;y:9GtAҝR[!=N=ҥ .K490KM" T`|[Mc`:l7eoZnӗey.WnC94읜n7r1~[N.{D˝4 Fs`[W?QpZd8삄"i$?pQY֬6|)nJGAO5O`ǢAT >h%jlo)zQJP{d #^"CGxlvtUHUr\l ZqSj>Ҧd5eˋ=4=jD4KMx + z/ Wq@s=|}]˖g7O, ڙq۞A[,G߼%j\AKc8BfCz_@+ɦJ<' z0"# `z=u~+&/&'gB_&xg ~ ;)W=7h U>=='=='wR4aa%]2Ⱦ8|<=vpdgͼ`=WÐg0| ''aXJ.Km(ɇ^w_GTE #+`#Zb5,bmKdX/ <-4|u `~؜ڕG4ͱV(j`xURw }HJ[v]_Jm&C8>fzVmG|O52tӷ鄰#t]RXb\F>:7t$fjjx=kj$% ($qcN|;ȍu ~w=8kzPH93!v8>3!5P ~p֮sᄀWxK 4@[ݟ>MpmlLOd[/Mqdq..i$WV;#+Sqrm&C.G5:lKlxN"ݮJqu uُx*'Qr8cgWb_E$r'S{Tx0=& @Ft] Pr`wT]?Lכ=s8* ƨ9__DT݂klAt-/0[\e]5jMddc}͈uTc YS=.k*k?=,-4M* 2FgKcg~5!ǛS!u9: +Mw}t-E)lУUx$5鏻r 1s9_k4oIN6h3.44;FԺJ}h@]({ܯ 9'3wO7BWr;tf6ʛ_H&xžq]g<}{;O;U|RX1keQPo4=AA5aS&ER'}1W69qv :Srr )74vu82ѫϺ9bS9]0rz8U8x)H.[$:f,S|nʒ07/4= +ېW5xisIԅ'+KN|ǒ(KvkOn$0دrD+j 74_=t,nV7¿zw_/,I._ߛ~n[d˿{}釿9h!1ua(yŠe 3ucѬd@0h`|XYR*obs]1(ݺ E&fYX0/&Kvz˧_?7XO݇7w_K5e)81cwfFM”wdE8`aUc>K%Qurbc"^ESoS pDEr}"Ou +db"o18c s o|?{qpWGDȲ..cSaM &.Cx!$9Ɲ2tC+{s0|;*>(/J1:E/yR_ZQe{|#++aq9!V[++\1 [=V1 |Se2yY35zǭb4JW^'5~6<ۓEˬs&;lڔy@jm5Xa[ҥ(*f,!qR +Tu!hNgC:8-1bW(1dqAHc@8lyz8/P/8I_2mpiQr|4RooʍK&=2) >ڛWjo^MӸzY+qievMIV~Ei2GII=mح^T&_'z])+3ry%2rfr%7 񗌶oǔfZ{YwB/9lͰDW =r&B$'a1B֑ɏ!9'q, 1b }%(ZD TOmHIT<'Zlz"bs|D=yʑ6oQjBWMl[}":sէ,s}- +A۾}G"86dל@7U"I$U:haٴ]KdOIʱ$LE$ɷDƌ2&6_:Br!3UZ"wU]4]](N +X$OL,D<ÒbuGfE و"%0Ϡ饛2w%P`Ȝ4Η /`;@"&4Z ae8=.)_c6WH(~Љgj?*A É})3CxJ^T{]'Zrun#U |w>`Z +3QK8$ZR>*Z /(-ÚW;MwZ ԆB4<6i/@p,:?^"r>x D:T&yRAnj]]$e/@qim ,.60y<3P ?`~8{})‘o ."ar؃)hSn8e4g`,QAKsjAbI\N?)ORV M.&aBf,0'@K-%UEHW0x}~8"딄W=s!6zA\R|M8n[L-:)|(ڧ떼~N0Oct,cq F GMg9A/,^6 $$ZS3Gܼ<}|Jҷ`gHHM,f۟Gm9tɀLztl67w'fA9y\R`Nэo{Ptktx8l=ןD>+/^ b7A_4'5v6PjnNH wƹ~Ld46mMUVBYfAw7T4snm.(ZK : 쐠SsFǷ!`6?!rӐ7%Nb3y ӾG.Hj*(ѐ0ֹw`F?-|.ihPRb.iXFT%'a!AT\b0gY2.݅ j/ysh,$oEs*SpN.8$VkolqM]Hʼn:/-աfE^) KZx(^Q@m% q+.Xs( b:UYߎn#[*ֆF(O㷟[;}8WH+Ľ,0(p"꽈p#0exv[iZ/&aʇ.`ۼij̩Jxt߲ZU__YU5eQ{dRHݙ#}UgXa$՞Ɯ,-, +TVǣ7t\/ Cx.-riEe,wȝr~Ncn5?t#i$܄LbT%1 IGi$nÿAM;. 71*!0 +ؑ(W<O*DND'x vwŊ$#wE['$7P\[!$4?8qg|{QYjW)9%;qpvOz #)8d< +bBSQr=D9 W:+CC: +/19'n7[Lhmg<~pí9Qr 璬F, Umm\>RC QYN 9X\븩wTLt[n6 df)C7mg4-XI6 ! BL^8Mju7{X)&jµ4gjV!ka ƮvsTnf]4+AT@|$Tw4 7PŔy.tCPl[~v˱5?n$!G<* +Emtyo^=t se p8J0~oM>VNYPVDDIsf͎MɚdbA`m:"*uT(yGÜ6|ryw݃xpz#2l^xGy$?_$l (paUJW2DQك.UHy-+d|@Sj +:7VZVzFYW*"{h?͎zI +@f*aժ 䑱`_|XEJwh Fwoh6ۢU%m,C{Quô-rXDm@07@L2[N#vouRF h R4$qR3חY>HhǜHX9/pT +G U҆8hrN%XVY_liB``'uk8沤,M 6qw +#!;Q#e3>Lیwi悵??"G÷dq*F q!f|  043)l[ '82zS3'IS+QUs#KM>T)&FX&ps |.D׉8Z a15=c[=<'vh87S B$ԒڋáXjfFm9KXfb[F4ƯbE)gH&ê76Tt/_+N\_Ƙ= Ɲf |1Lq(Ul 9LSI~yg259bzv'n5 |WT~njf-l bkayYTൈ6&Y}K+E{P؉ѢU ~%~fvF>zbH]Rȴ:>LcUD>2ޜxs*fnkidRIQM^ˈ aԆȀ!D!0f&*87LV5_  k3ݴv)iәwnt " ɭ1.(?_8&hI:>E ^Z Oxl- [$ɟnms7i|@:OT xKj{[P}߂.H+Vd8T5Pȡ lolf(Z?A񑐳2 P0\&:HB\ho^ ĸn{ ~(Νa%.NEjX[_E/!$T#A굒LG)k$ ,-?=x6$\_Ro,עRݧٓ1iè'5+E_A(]m0/~G̲ن4Y[=w?Lbu^QzB7mɯ<5l VJTrډ-} B57ȑs_#^_pYv =+~w=֨cXAur;ס)+8kn#gS;+wј%!X' ,!`љrAcv[t]mya1AN2$}cQ]SrOl^3aHKX +1 +QE$6&{&X"f v\Yn6^m$v(o=xy2<*iMr E΅4yAڅ-Oi) o)"x]!%;k̿!b^$66 Jd- 4\j +ynU,Ⱥ~j:-NIZ4 0f0-JbY+B$չZoOɉǢ=h;m +IoH(bՉ(jfD'g5>%5v%0/B ~(@[Rџ؜n=q& +ioݸձţ &AP"f?Y] oHnb<(YL@DDץD +a9&  7=rJRA'7䷛|f폿ܤors?o>M3ONjD*pt SNM. #lY|w|hq,90 |dG=\q~?~N# g%T)2L8&rve$JIgx# =8ϚP4 -9z̤[fũ/Hɻ`(2Œxts+LEC3!2?˕rH E`. E`}sR݀ O hᆶdB"G[r K!K)24gXJT)JXUO|Y9Fm'չYMrS\)%Mލv$z} O<.ګ3'T <~0c5쭍dixa:,*SLX37/-BL6cG-[1>YLV4IK⽢g^fQ^3KicetĊ*1WX ASz䖆xTzg7O:P孝fCFATg+ǖΤnSTL3K쫉QT7+ye뜋gjM;I"o, <6(ӶP_\դ|0U No "n[VCՃ~X*hr}I30:-2\P'JhcaT]%2y5>l"JiIeb7ڬe̓Ys6k#YTCDD {xo?;7{ J;S +43z2DmQ1iQv:Ep7걔 VaP΋+ꊃabAl a<xe։f 74J/ZÞd L-hHb\ 2q^ranw=@yU1@te8ag\iLojΡq0\gc#R8sgp1sh$$E@3 Wrf]<2s;JRR[ vTއU[@*kLvX/ta9Z.[1eƦ젧`TUВ?n|,Zي3b )V)yުXr%(s(xen9I[>;6\7gSV-XXl\^ x. Z謂o][ x$|&? <|։] +Ԇ{& t*sAtb FU&0]0jf2F|RٌeE\P,wTCt7uʬq"6h2TrDcj .UQ-Ճ`&OB'6{˨H KH5WҦ鶌4 +):xM4Ғ=VIꅤ%j mаXǷ#mɅv \6)5\BՉzal|$O#yY Ϻ\6VkuyyNG%Zɖ7mS|ͷeW*X4HZd`3XS> +j1=NVR-*[,QMlkj/U R;/űfL8$ͱFTJ``W/$Uͪj +*fuU CPU 9Ԏ8|q"CZoZqx7ZʽvZC qSOiku[ط@j!֥Y"iLc-Hb&Ui S0XDp5*٣[M0ZocZSV6O"tFYr\)2n:H~(T0B;#Kc,i)_v+R\ɪ +4w诂%F-rE+zGuru uU|VVËPZP~]Uq 0륶FƫlFb[fp?su2iv.惻tU%^X\^z  +U^]\ajt&H]4Ζ5^H35 G!ZIJ cZCp'd)IG~䅫KzbUMihwr[;|Ql;EDG%5j*Y& DUWMuMΕ r&5 YDW-`0p$ irH4Q4.UUtqL).Hı2n' h; S>xB hmAwb dM4v=КhE?jT]0(k)$.$ K^ڋvqPIk3JS f$Ă8J^0\"o%>W]rŖz7x2v8Ⱦ $醥V]e ]ehN%Z6ѲOOɓN=ʯ ɕ*PKKf}.B+WbltxW/U/LW qZG_*hm}5F#_ Kf$SXw~IwL4`SY*:P TaUU'l5V@K,M*#XeP 0:MdYE`Acz]J"5ARތ_$A UDi+w{oWHFS +gJpm6 QmTnrU*mTD_E׾]6W;/x Qpj%%]n`h#!; I`PuGkУm(@݅~1(9aMqI\k|v8;>n8KQ|)ٜwFdu4ۑ5ϔLRneMˆ㩂bhn[No{WXɾbC}YƱ\' !,BR>ڡ>ac=->^ko`24fwqhM:I쨶]_;` _ +^Vi֗Զ a 1{7ȴ,wML9J$I-Mڶq/ٿ8gYai?s/eBfHmVnr۬f5ni9 U㗴=쬊(Ga ٫sZʮ5 jؙZ.8 zHWni +ggE~Vaؚٜuy-;fXN|w氿y^fܬ]p?=ۨ/6v}ֲU& -SN>#1/"UTözz87cGZQYʞ6"?h` R:j҉#4yfV>fǠ1Axͪ:೅ZJ󹠔]6jJ +zV5ϥ|ٷٿZ^.Dzv ++RS4Jܓg:LE1VJZtzr{EtAA3?ZVEsԾtCboFU\[1\NKc2| 4Tvxar948So8H)){]t6\9\ȣ<nwXAm߻5_57'Dqm[9,;/+[6"mk˃oakQIzvv[+7;%VmQٷ1=-ꡉ[\h*[BIlp،Řcjrcx,mqr[,ujuTW\[ PKu`йm~TIDZԴ?:l  棻C q8X0|EGLݎCHy1`EQ{/PЁޘǣiT-tfr=2_jym +@tUj@: իDB1ҋ<5rIT}W83?_r%uvZ9E/Dw`MT'iM56Ԭ9Z;_>Ic4hP4F8XZ+P`22:֥{~hn!l%SR" JK=W@Lp/^~RjTH"obP0[wVΪYU:JgU*UeŖlh/}ž1\IT,F(>uu rVK\eBuU:JٺX,i>ͽ ҦAUPu8nFΚ &5]& 5Ջg@IJr([ܝvjQ +Wd.=gJ-}+Z_ڶSe4#6LlDju[)J#L<_[aoϾ2E4[o@]\[u-%&/43+Hv[ۢ(Eӣ4П̶͎0RK3~ +MrГvö~1p[@On=Gg_WQ+8Am@ӂ?ʕXܡv^ &<\̥X&QZfΧ\T!t)jGCɪhJ +iq<ٽA*ypqirZ-*#kY%j"GVZW~iiS-z© 뻠HuScYɤr..Ȯ\^895rO#Gu梴L^Q4)(ݐsHj! n;:!9P$-?Vl9=3ӃvSd543''z{5Ox)@9*[dV#yw0*U(\Y'9կȣ1XRH+ΠV\\KUnZi_ALf~WVET9noY +Mћ`k) 5M]`ՙM&Y=kiZ>g.xYc3i$Y<]inc?*(-@ugb+fb+03uU[s{ީq(PxGn]Jmzq@9zc :lHQ4i,NtW sNsœ$}Eي pGž }}jbp*W%{f:OB?Agl}^K= +SgijWe-aA}c_HU#AuF5ͩϕ_"T+`Sh=FcGcG\ +nM Si2s1ة ɼcg]ț?ӷgj>F)HD?o æ'6ݹ„бY<y._p/s+vfۜ&kER'_S.j4uwUS ڭv'-()ZfbƥwլPXYKPq0ԍ +Wo/dNu܋mF. +9^$^=xNaoncIP&9K.6uu֮2m2g[2Y1"QWKTBV wT'ɪ Eu(8_c؀'0Wf 9E;`zB1/^o&^MC$Ȅ>b_H[8ҦE'z a;h M2V36 Lw0c> +6Nb9.)l;P_x) + Ojm45V6 7n(QtؼVǀvDzwtV;",tюD3a7D{OzbJߓ5y+{I1Mum}ELI K;:p>_ܓgvOw퍻E/6>рbgpޜԆ =5BbRn*)&k#Dj4[:p}auVh+]d׀JAxҰX;A8HSEp@(F2RbdgQ$ID +Gݹ]Cxj4.J4T5oK:PByᛸ볦*7LgJۨF6*QUlۨ]usB-F&yxYaQgZݝծIA99W 'sR ,֡ %^o=̟E n?/@o_|8QҤRQ$d =$]"nqEwKw)Pd m"Ikٸp|eW폯# +bX>`%W2g4Z7?SY30v%eoP= M/mz3IQ>ppgd.k o3^1PmwFq7ٳzieDa3 sS( ~CbPgغ:¡p9#fb4Df(v!]jQsF ?(XGsƶN@$ҩT3"ΰ2<:)xSބVdƋ0 CKШ+%v -Cj<Od*"0/=} 1Y< +t(ZM]hW57 [wQجP=Ð`*Lo>c/ȁǘIcEvU qGIY1wTg%q#p7TVrw'c?nY; qM{HVs2g| +`Qv2{Ҋ>V +c0zbݮnxdHPT9qU=:A Nt$ I'H.Hj7UfHtMyF *HO;]ۀ*y(,kȚ-VuNw:u:S1D_ƨj03ot˽X+Ib,-nv&ʗ&s>C& :ch3CmaIXN]U OQjb:3h`f(!pjgD>.u9^GqfYo!tAE rHww \2.1[T=6-"}EM_Ԇ6 ,->lps~pp?UbIdS1{G|'E, 3՝Y[:rt8Z=yigf8-b֭*j ۴Vrbmlm6ؤ>Ivc(*c?!@"W 7ҋ&5/@".@ĻVF +LpwT̾NT8v3 bva |h*OR:CҺM$4q}]kg<*X#Cb #U&RUzk5y5+fXCVqs*.5d9ǐڎJ?f>1omJP%9?r8*@Ń꼘mͫ|J<6G=#UB + #brOni~*w &B!y;DKFZlᩛ6V؍XazS7)ӡPZRq8931J́,ɳ!k_gm9'{yCn`ynX3"x d(fJfKuq`Mr?fNY >leS* 4ƕDٶRe \x +Gd?.JayO- tPU JFO쪓&2тޙ0q,6 +Mn*[Rvճt7CoB'*m*hlWe&jBЎ{.jZqpP,Z70k(mXJwԔ8S?42iIOMU*&P!LhMjeVi!_.c9ukf5 nyݜ###lWзg[PtlLW#K.]m#fxse*!p6 +@"8эVc=F'*Eٲ:\JŴ"wj!<Ͷ'f[ >=?wgM֜л%4Qr71@] *b]j6x5uS2ZW~[IΧRȚ +#M dXpD # XSS+B>=*HZHsl.X'$ekGH㲎YgsLE_"&mu.AݓIPez] ' (%\o|YyW.S{Ey1Te{4)+n/XҮ9!IǕB._;4*dx7G(Z@¨>9皜e]>l~޼{8hƄZW}(mG5ŇZƄDWe +` ) xP9_܎GXP6'i?5R 87}9nw8lGvC:Aޡ@5p)UZo>w;s=6$aqpzsĆtI8(~s<}UEt"Oa@ +h`lc EK#\皐xz~fTBZ܎ ύw17v}UQ #G|Dx[IϋDV*鑦 A?HC>!FcYyAq~PKhmqdOΟgo^>#{pJ<GrAB*qeb͂c4Ěp? CVhŏcc ڢi#O"n +/1>C"{`ƘA0$!1?g `F&kB8cZF6`CLp :DQ +;DE2!e@)tFt!YȦaFN #5 Xcx].j/Gr6iTc)DUok m4Hě=`¦\,7KFA6b 0B#+9= dS{p~_P @S]2@'&!~ev$*P=(|cy847>"B)<{[0$$9g勼]?W vd+Eb">L4f_C'AAP)DNV,>69 x8Yr}qS PW2}4ՈK "\ U#׊[\ *ʕSZTf\-iG<ҁ8)ERh + ,IE +#+ЂQ$$WPEViYRZ`G¶ +&5BEB ||Ql|{ ~0B~y=S"@vey&6zj+Y'dh[Go&4^60x x P94=ؖ }+фC6GªR-`2jNO HB9T?,%>)|>lk4%R;y.Z|L.vDjsB+r!/ήp!d珉Y[P!rmd R3s [~)aJ&Z(oF"RbTc#:=F򬘄bb{42LiG.`Fa#8TO#G3u^Ǫe0yMO-yϟ @>GfR4Z4$A>B7v#BHIscN:`t&M ~iNp(ҦIQ>EgȿxY Nfe0)`|2$,i[;EI^ +KY"bQIR)Q$,` QYF8S}ӑk2C_D@2ã􅗘7N(!-`nk'DFdosl]_d\GJ^X솆[UMS2ؖ7/^O:r&#TFX."A\hq[ +"2B0~L 2^RYA@KC^0%]fE~U8tQK:fFAe-yb~(oɇnvWv4ŨAUiPTU&WS. +[Jr̼|% .k Acdhs]OU4L2؊⹏ :=U|=iRi2+INͧ^'( T +atDZ,Z _72M] 0&,ah*+@Jcg҈HƗkfJd}_]l9=m)-ͬJel8OCQ:[JKױ3t7p@^/ &Sqx[D}ղ#Ԫ,&uZj]y:ip+Qڙj鑂*5EVD,1.9ftd$pn(nf Q[IESCKN3"4̩q4 ITo(IZGLj՞)IW;:ڪ f*6LHϕ(J7&!T;6+džtq7&,a5Rk4-"^mBHW=F"ᐊuhQ!f&GȅI֪==!jhT9vpm),Ҟ K@:D4'*R"7aU˴kҜĒyE4 vTCբgukq1̊=4B<\U1dҤgc]O/\9l+"e{\SbǴ~ cmB% :Li i WGL/ɢiXXl86o/b/= fZ\%נ9fM[73WAoCu& ۜ$;iؘt>#׋C!g[3J5hMraHz[#J:-΢;:=;f ptjf,:DqӽSw ЕF\!7hg 8=0flEĹ0/¤&{S 0iנCΠP׌_%V+R3aW#=77bYܼAk"F[hl"ht'+XAB/@DN,tc~Tפc>HU1S7TMUQUiu_7XwXvq_9Hx,ԚQB4&^EY bpJhl-qJ|⣛*%+- +D\^C\!T0b@IrMfJdVjE*YTDz0za^+pL,7(ր*W j0ѵFs (SJyK DhV)`0)GЍ`CbkXdXxQ"dmŦ, +,3Q@4'3Mիf8:lc/U +n}zZlzz +q5d:zs=P.I~?W?WE?_^߿,׏o?6u۟ =}Dx88|" "~i-ǔ&@?OI,k ~d/nnKܫmCY9M>D>mX> #AaINbS|;Mq5b>5_,[lݻ зGP:FJQP$T,?H+I/^.q\0Ԛġ_,t4%5jP7'!K"؄"ң`#8S"?nVog ɀS eŢ*BG4ź?k@1W#2]nG~8j9df! ?/XHajF3CտVy7ߐ<# +8¨pĪrې׋5' YBn Ud2ZO餌]Ŷ:2^sjmZB|[ˤdڤ4c +u"Ϩ{MMĶKIouo\+eE_H(NpR":Bܘ K+|Pb% |ڲ|prEhOhQb%=O0 +6ʼ+q>e׾BUaռTlXg +#U¤:0 a>0I*[iU#*rX9o͏s]ZzCS4#y4,wc9i@2p 5k0:W60pکYO\+ӒӅ`i\>5[rCϚMS([qE +w$Zhzo=LJz]#<75P]PP}q8lV$'3tLMTbFuS}i"A ru44[U߶ \hPK.E=4Lߥx_ e׵fz[]QW]U'}sE{G_ݒpjq/RFT׾ԈݸtoPDt_ ;˯]XV,ӼWjk\k6;#u6_s㓨9\*{㘒u*tb $:zl7.iQ52ےFc]~~Z]xzxhu L(?W0mhrltXEQz=g|qqQAݑ4_$C^-ޛz 4qP;NSn^˸܇iE-WMJX(맖C&>ZdA#;ޣeyXDz6 +lPʜˊ|ZD#h"[ W܀42B8c +%Wz}q'V%WR:lwURߨxJ+v$,x3R3 -#7dxm S +m~\1=)zUОha!l]mKQ`:<9ɹ%aL{ ,DߗOi^)eGX}w%wZI]-yljR'# C#[YfPZrWCEKUub|&_Lײ0ș י X4ӋY4tml`D|2;#$=Vv(0!*enJEۮQD'U-o2CZ]u[Ejg@B17J5@od`Yg$X[}Sx=Y-\y%NL|0߂maJS/*7ezG^3I}rnXoP׷L/W|55DUS5*h)uM',5C^x<64R(}4|8an !RWJqF3dS܋!wVxrJn4W:Wguku(V]&R͙Z0~Hq=/_U [qhGVռR0E)掸'Ӽ4Ie}RS}H=\ 39/)p9noR,J eUя쇢b.ֆnФ$[C_Pz!.S]<@C*WaNUkU2~P[MpWъ +e5t;Y) 62u*Ҏw* (b"8NLe"QAF2a,Y+/A]T)/Q(>pԈDʪw,c֤YÄ,=+gzwse?]K+==Q _@;C>=<\Km7gӲ u+6 s-͓V_)gncABe˺TԈrqXHWT!F8ЈxE8<Lpyeš10c֌CJe;yۿ坲E_΋̴4ֲ{Uo`Ю +Rp渁Ԋ:WSxP1ezwT X_,ګ')LߐngŠz⿮dCY"}-)bBfQUej#+{VޡfY"/x}DpY0l\I(o*TW{ +dMOڗʵ)'7?$h껲͓.DͧLX亚W=j^$?t"8:Ι$R^(zQ>*yv@l 1uo\BK9-/ӂi"AJxg]/ecBx=,+W6{+‰vYO&TY~V{wT#]T!(m P' 4OQ?a;$x*/ۓkBV?i,EGM=hzI&JYMB0GMQjyZ0~]v<6͎ ӛTJy-+1{uګWJ+XCjU%q&43Q E?Z0~P RKyx"XrQNdv_ )vzNY-sFّE{B$ˍ #iUVer pϏ0W\9~Vݳ=XNV֝mqKdUtGB5iL] &: ע +(eEB<w4Z;TQ~Vx'|jAJU=%ށҧ\Zeq1~Eb״eV)@E~">T =ᙰlPZjnQ9 P +|P(mpSQ8xdžD0G_Zoa7W{-+͈Q*k^"*xKQkxU`{( +&.G3#y_ZZWJ>,?^Bh*)w g6]6IUJX9&zU9N&T^T b  uw[j;JCeUT$%qyܟbZWJvhM˧3f vj⓵ ]d"hE >YuO +#'14u#4_%YM-?(#_l%q Mᰍ)ye]fi͞ +|G ~LufϾGxɡ˿?@5(nj]4J$߭&n0Yod?3æB~$3ʜ=˞ϽAUGVtYæ8bc{l5x/  AhFO(NHhfy{,^`u|AJ&;2'>`J1+b1O-U|\oAͷhWB{/?ᑙH"eyea5ײ)̽Z^<æ^ c^o٘ϘPw>A)2":Y".W2ݞqBPxY–keOw0y#`iQDpf*v<90|43Y޺Gd~3Î0fʄ099 zQ]k4:_e=vLyL-_Qvx&?1geG +(ijvʹ3al1 +1&0jΒ|}L,Lӛ iAǷ#'ܔ;6f Y},h"䆡$BZʹXl&U?Z +X:=BxB8[M^};A( +=O/nr$ `e8Qc􏸧I2X&]0 elxT|G8mX,lCgZϏH$p "U*ʳ:r_+Th-LBƵD5g[VJqU7{fXtLO'(X(:5%rL|_j8|Eoq~ iC%(gJ8 oxj K-!l߽k⿿ pJ%e!2L5BnB]:u1[pΧhy,Ooɓ|btԞ ;mΔnC$tL)HNv4=ħ]/\.GL ȌGAL2 pc||q3pl>.E|PǿLd/~7z ZLpYm~(7*4LF~'Bp-?^tGz}bVNZB#`[`\> noq\Ɣ/X 73kt/U3O xc*};Fj([*uGBr6K^:+ןq @8Nօg8ުM^IØ+p7_5Ȇ0emɥ쫭 ϖ/ߘ2ֆTxkO,GTn˸ :>>y>eͻ>NU^Oo]ycX9ۆ&Knoʱ70{5Atua$S* @8 +2:إ^.xظH~DX:?u̘HzfLҲI(ír[N+&msw50"6Z{Ͻ/8]~ ߾= U + C56s$7 (,M*)C49"Ba4<MB R] +H*<эD8DDUs9ih9BW BT +Ԫ /ϝN8glgee4гͩj"ʀPD-H7xe#*dwC|iAМf!UT J90S 6YVV9}<=[a* L`!6B 5`(E?ˠ +؎#u +6G\[U`P'U&!@sM.CB(wjsCDE:g9rIQxgU} }` ư[RL%Q}hHWjR¹q6e~n?u-d3VIe;0ei +oj 2Si샟Z^!kN*|C C`Lkԋ,lS`4"$hp. N `hpjRc!Y&vFTzbj LӡUb>|3*.50`w48MA +C_ցEhH(9幞idde,HW(̢#DɠQ*n UthglP#Ԁ ++f*jfQI-ں_ cc˚pcp+D,7P޿a(_+Ȟ,hr[6!u6vbt"0sk=M!W8&uݦ7ylW طޠr - 81s* g ˆC19אEeYTHa+~M WjY|" ٪!9lI1[_؈X&O/g8RۆÈܴT,Z-{N\ =Єs:j?Qe ̬9#IHm1 U -u:&pBMp*c#4@:i2TMF9U3OAT[ +7p+D,jKeΠU `3L߸A_a?Y)nPw6ҟ?W9;_;V[㗚)6UM;UYXn6?5$&uk*iqhVlZ3LT"", &5 `./֪<+c[ݧ7q&kžPk~ `h0vén7suעJ{_uaηJ2Y@:2iVSiuS0(j4x|X4"a8_>=BjԀ'5pHQFo52"tE͆kQm x(.1XV<*I +*hr&z'M RPgw& ߁`Lɗ?| 6fkESh^I_־I$Bk'_ʱVD9%&vR2$'|I)XvUr3+7u9"r8p5{,yഎvag% C4O` #eSc5[r|Яu8I\*elMKѴUԯ3)+_[j{ɇ_/`\R,$uͮKpEHsfEx J+qsxawvƎ=rZfQ:Mm;%U* [Nā}de3l@_\E؁t4 +\KBKVF +)[e:v^Vd臘JZ &/V!is MZ+U(a"XU68r^ò8 S#Tl@jq99Zt,V]]$v9ASgk[5B{hɷ5\un UiI5!J0lZA) SPZ&,Ԭ +[c`5Fͼ˗ xm,Ǹv}⺺wtInuj^]"S-Xʊ % }f1J'5/o~湶Նce3~jCYm蹆ތkh|h$ 7q=Xpn-VkFvkmlr +6}we~S|!!5j{4Zk L̝gssJ69?Ljңr*a/$QɴꕪR^Zrh\n^ڟXK~VZq9u=tiiMd޿ҩ !=FUW$հPWM  +ZĤR҇N]oڮo>1 [IWKN %BvIR~_ axEZ :ne+0bV~ҁzJLvIvh9/]OO86 +.@.ttj侤Xd;n ^}Mh@U +TzP }Ea`R4sX80({Z@uQȄ|ZAQAA$H+\_658eD.wW%3 /{@/aܾP9CwL=?,2n^.aeBke~NrWü:z]J 5pr ۟PDB# { ahm9.Y:Va({ 6,\|3xe2p# Oe.ylعbÓ + :\Pd/؍Q뿻i< _(znu*`wȂFjVa;8a«>Hx{9ЕRݎ}4Wo쒞懝 0{ZwIw3 +1/6GR)>; ;_q_(ߊOsڼx9e#D^>0_2ajqsO^Q::nPEa5^ziB9wĵ5 ۇqlEEu1ucO_'VCР 8M4Hߡh&eZ|S>=Hg̞_s s+eDߺXd1@Hgx +# '{3/"}7d OM)@Zsݻ qOÉcgDO&(kVkA<>&^r +҉oϿ~qXeZB+=yJO^ +6-{^i ywIV-}(oG{FKb +=}ǞP2?~=PhȻSQJp*gTXh3" !11zsɱl?+ءkoe+m iuƓH沏H_ȡ=ʰ~g&}(cYbD\ï!x쉅) !̡a-r ИhCynߍQ;]/ʷ`r  Hu` 6P ͉w@&IpC>|w/Ȕ^6ua21LgP<py._&2W4 mLbĮP HE=0W P & %+znԧ͈@b`tՂ +ҼV;h5/t7Ch47 j)?< 1JByQ8e[G 7_Ÿ&Ӵ(uJ3P#ZyV$v- +^`{qXl ! LB7|n|,>ccccY,W%T I.X= +hImoJL,j.UĬ+m ų,f'Ow/)u.Z Z㓏S{y:KdJy]:';Ikz t)!=wDo@\r<'pNEGs5r1<.ꚍ?VžpD(N?it~1|'Gp 抎ߴ&74MTz9rn;+Iix&?%? dG_H+{I@<_gf +"tjxv8cĄM9NۂBl6oOU梨pFCuroDhxQPO"wwg)xu1ѳbgDoxL.^Ubb$^bx-t>{/ϲEY11I I@tXMaŞS.7e;+Sea~/ 8kQbQUL%i(83wjX$tʂ<[AX{EijUbeiXBܜ @nCѻZ,23^tU\QBn4M׫8a:i Q8┇F d U״)0q-K `{QÕ2tZe^x() 8;8L=Y`^dѴiK .߻..tjg"O0t%i,4źI"v=Hp,h]/hڴ%dNnf:{<4b5 lb^8c Gl~4 fIc:)"Аҧ.!nj Ҋ3M +۬qLUE ㅿ8S/*N؏AP|~p{(] MO5yɣ_IX` %[iyM8 IFVE@(\11 Q]L11K`b?&F50Ѯ̖^z _A/ʪ<1 abXS|3zL~UݮZb&V^/%Q1q: +e{8du^{hZ.qd<EHߌ!_U"dij?PZ/V!3/_)@2rŪoX~xUUb5 BlvtH~: +/O4[d$(\P\i[-V}Ū߃j%&^bbկX?M:Op&"E p< ';O jdWgfҧL>I_< +Q0IfyO7^{98%<[8_6]}֣kb>R#|zi$2>݋vzYk/gb fY'^\DEl4 DDu0kbD䩌Ȭ\Ӫto-q9 -Z[Kvf+;L`c/Z-8^e~&~ 4 +8KFaxCdqC_SZ#-!wnmܕWV rAZW41W2^-Vdc;rtYo YwGU@תU/F`M Uʄ.ZOxڼe-ֹFYיzyal _EQլSУ^kՎV/0Ta膪v%CT3?lYxI\&54 =zG6me~73YנGUU;^ZPڕ]PR#g;[A.RoGyz(lWX?鬥QƬQУ~YӪU/\`M U*.Ze43*t4Xy4[yaGg@$PE!RuQlWUZa;jul0U-(HSP,˧uPjMp$I 2S#f:L^Դ  \MOHp|B4 '5\A@s3ԇ2Mkh?Q%xQNx=S]f8iӊ#uQk.8ZJ/4-8HCb +`:i +aaӃ81M`J)[̗Z5mZQ7E]tBQ@=uDWE/ueA`~G Q4B8 MES-ԧjVh7i'N;hH6o3&rME'U.z(u⯖(6`4~Ŭ7բAmiEK+M)vәvBQʴVjL8EieX}ەU?C@.0]ѢXejX- ,X +k/q>R/ViDӨXQx:G&3i l|2# v'jVlcu +YtAQI) 6 0qbE o%()8/p=/HM(z<:x4(-J>%n-ƾ*cp@ ouNY-UEf!w̑q2'ԡ>ڢ edmҀvAYk.([4z4-(/0gc6Vg4]/U eA0m"ijV|:D6J)-TDfVP*p +0ՌP4͖82M#X$\Nj5D(X|:t\"#8`NhC6TmTDJG*S08 -IY,4^.bkp_ʊe=_@sgnm. vkZul ]E$_dYdKyx!.udY&Ӟ\:3.)-ڐͽRfWF푯@o +ˆMP_tlyRZ!N ];uAdS{Dt6zͪe%9<~e0`ʺXǫ*ͧQZ=SzSI7Ȧ"tlRZ!W ]uAdU{D +4NqM֮LWI"o"_#Di!a;0|fU7v,l +Ɨ._[`h[abD5Y#6aHUפi:fHu->覅 2_i-"mq}8No <&l?7v7zS4W߿wıת8.{,g?:CI0"kϹ=ZKn>V%.6LVv%;0ut>I=ap>wx\ |*ڲs*v韡Ŧ;hfYijUi^k/hʀ-SYq +5d9AmdRF`:a›|zKMCQ窅r9S<3̡>'c{p=P2Kz-Ay8ܺ/o|4JtGҝǾz6YYUȏBxMnh `hW1흶y'5vg:ž噍8uA)cVd~ #EĴUUHxo22@> fTEÜ7aNd_@brM /"A6|}E]]cibZrZ0+5[_"Dm/9f@mrH) U=FԿ))oJAwA{A{ [)JU26MBԿe 47Q;,EҤ)W9ʰzri{<Ӷ".mDhFo?#7]: ^.<畦JIk&UUjVZ1Z#ĺ\ZqOGTqyQ߸oR7Uͫ#@ *'ot=PRjYQirK)+?qoJpd',FyڷIZ%a%۟7i/7~?>=x $#}<ث#HK4HV Bz@_ZSjwGۮ_*׿j?-h5Olt7:OWO?͏iǬc8.`_Ňa8;^ŷ}8SlbE3tNfW:TW! $@ tHSYVYk@BAя;@ٞJH,UȈ .e +oh&w1)DŽ/ nYW% rsa07U ="i3q~p7YyB6jVm|mgy;{@li$DܿȮBBr»=h[hb[ ݤ3;i{>\W_ (`urqvTǜl@*x׺yxqZg?ZI=EؾqѢt^|ᎌ1;==fF p _i^l}w=>u)g"RHݯoWa]FXAx j ,EˇᴝawaOOwOهGyGtVw*!Y>S?p?yNB۷zAwt;N+\dNhII?󬪆Eѡ}eASH~tv{ĺi~D]T4;}8<7h<ç3.Ku<ݼ{ً "jKvxW0snIȢ N|(i9e +V3-':U)'Q8c~r8gu_MQ4D\ 7)Gz1w }uG\ֳ]^>K̄/|#$K!LI/'LB vc +%ݭRG[?6y2Uɑ >99>9Wߣ/'> }x<^M~I[С{ܯ?a +~{:W,wJGb%{.bE:ngIw)ҟYc j>C9Z-iRxGIi=Ϲ*b!T\M*yW< +Y}\S{ +B%*(RO%M}iEj۫ HM_0ѩ9GL"6~_!G40a_8+3bǢX KKڢo\BS#86 ?;͒pCѻ6dp"~$ f'OhJH?rq_(Ᏻ..{wE~VguB8_NA`M8Gܑž J^uD\Ąg%vՙz)i{w|shZʺjT[GODU:teƳQg pgv +դG+7piЊf`Q 7䄗@33)>S)vVwc!1^Ql:tҢR toe\ȞYaq )HhCmU:َ2m^‹LPt'1fz:O*[&pyw 5$3su< +dT˹f{L-x"3;ߢ=eĎļOq[G~u[궳κn5b‹qS!Xy?ӊ1T_< Dx)Hc;&1ZO"'؃2q3L,hMw#i ;\$98My_;u-$ie?*῟v-Y]@:*&~.EKX&EU=py!Hr& OzDDC@(:(λ1χLD(9pD1>?|jw6 sXޣ#{z=O3Ƌq~Pn?Ll޻|m"l xpɸSl.zAۧ3B *āL`8C8.xWKQmhZue.MJPgwc6[JB%~ L~_HLlV&f$IȈ`_ayp] b3fm}w&]ߠ-{gmFI =1r5 3L~ٻáQ(U,â FL}Xh^tؕ@3vBJrcS8{/`&5<#/1xi{脇С}vp*˽F/N5Rbϴ_ʄmCclb0ɂX+1R.|;_YXCi4 +L')(⮠H)IF'ot)Y8$dF/?}?[wӈ%Ny'p?CS>·wDLp ~ xbEMc%x\L`y_>= eGn)H]r8 +/ޱ;g .h·pN0L8_>[}$S8 }|LJ7Teyxѧ2J&AͺdL pypip~_?:@#2Zّm-5}8vonwWҧû$_ѳ1Je y?iΐFK~a'Z@SYbW$ވ(g{IU?n 8ȗ҃U#_Jug/:- 1ÜVqx^b#oBsYk I~E`?h6z&C8cYa2KX, aCPlv[nJ$EIYII$" I B<*)ZJ2VOWuߤD$CNBA_dF<1yJ +mb8p{nGr1udI 4 +AbZm5<8Ҍ#V|AʪU9$̼>[m*c3 5Y ݡ숭U_Wj1yd^l;yMZ9~eagK)C,1cφ$,)IN~#ƥffm9QS&F[8FiBU#,=XԌE-=)seRGc8Ĝγ#c&?F?vӽʠi?N\_l]BuF{l;?Ufjѧ ;;^ÌalXt4w224n0{Kzq{ޏ濞 t򢈭r QĐIiLe}4/c9}@yuڞLmecOAĠ0^q}+ތ|#Nx.nwISYihtHذlK_iUk)8M0d4Z2g%wIÓBHH=1 $USXtʮ V #ɚhM`$Ogջ#B"*7Oy=}7BFzGBp$lGW՝h +g-*Rܤ /.Фu{g>W2[EI;UhӞ6&oC]3~r% p aBom_? ),=1zp_'iEߥ DmףwY/c,ʐ)%?(Ü2:Vuvf`.at0mzM%Vd$pNOQr$%YQOlޡcOa=lE{˦c#a{OϙWƏ;n?N^zF򩿋 +/( %K;wy0:=ch0 O_t\Ek@{"U-Ij_@qVn[X~z}/AX*&; 0t DgkQZc2EmsyJnS]y1;=2yip)m+>Pc@됯/_|8QSp#͓n߿]:6E~}]k1VÙ 5^\9RylwW]AJN+zqE)rzN'Tϖ+S?ӡ%/}VLDol?˹9vne?z "V +3-jZ:dFrp)lEGȟ 3s͓>e'=ww=>(,TPj)2|uܝkD 4@d+kD{ƻ6)c qqbPErvs@OG?jL`ɎLmssIC0d\"ZWEcVG3Siz(_l-S??p#sos#GZ.-?QnȀ98#ԑ'F,KOXPnL ]{w[zCH)梙 n,{.qpJ*H/ B4pLHP}|z{Rv.ÇVL+dLY<-Btn y&-\{!' (COHQIu*Ymӷ?ݿ;<|pxx@7.='ݾx(?_/qE <R {EЇI^/^=XvqO2xbu=8l{7ſ|!kznTv&%ooΝ|[]O\::~yz^O+Sſ^Gi[q' Hۇ뇻j}hbRHKpq[jzf'di5$3 69nzMT_D,E'Ѐ~Qwo\tܾ^?ߛ?Gٻ|u@o"r4 >Kdf''/w@NY`; P(o9JA7&LXKt$ %ȗO 1v $F\K2W!}n J+%$B ;L W>G^D2LBသ륤K$]ļß|HaU.m`  m+AĊ?v@D٠mpt>>ݝr=s|||LZ~ #@/9mU$U>hɵҶ&_1!O_/l_~]s w"LjS~W/h##u@2~w:9'۲;7Vrų^Uɻ|N7a/)"%p3, CSϦXa)KO!,ROLW@R@Z/pA>.^Q,ſHW;/*1<.ܒT>/"_n|AxGx</ɄJ_ bʥJ!?*]U|Qݭ;o5KMZ[} brWb^;y۩f:=D@l +鑄/Kd 9!, `+ \dB IA(3qC`Na 9QZXN(%* ri窏uWaB$7&miL1em)Yf*Ya .0`ےMc W!=bq"ĉ .ZZ@$K&Q OM`?OU`=6> 9SNJ(u~ b~|`OL"1pXK](BqS9Z$ 8 +(QyljG:K$%Bm=}8~ZVD$m-rhH|-Da2z7h0=]T:_Z4;@0P~.)2R%bMAcKEr+W@ +Æ~qԹ' #D +g)#Ag5}Go6u m]Dq4M7q !3܊撆Y*gtЮ%;^C7Bsѡݐ)z<~:ww=~mKhyuG"課 d T u&* +ۑS*"ҼŰ&:pqr]T{mO̅"˓;#П6'Lj{s7-`'Wp⍃(o!1g%kBxY ~H7O*1k1PxfKRFS2XT]`p_A8!8_/76K˷LsAnXfNPbfAA.OQ/(=gtQx %X +:c%:'WY/U=t9ŏHfTB0QaA;jW ;G'ƘZ=nxXwTJr]1VizL@>Kɍ/ MG0(qJ3 ʃ(c8dU(52AkMlrPk#SOM})8A_Os/7앀ozٽR= po6s@W$z>>cX;˕[e'؉.&bDiE<ᢛ'ܝn|UOo8yɪh(jMQ̿o-]f}9S&Eڬ¦V'd^`CDd4dpq-Meӝ}n$}oY˾y>?i2ԥd aΊ4 +r\Ag;zi]mxmky s|*H39@htGHCP36C( \J͂j;*URtm }"M-7)Η'􏲳"H+C@Pk Ȕѻi}KS SE`tջ̨>G\ue*kydTd,נ&RH|B ˏh( pZb\}d8>lܔ40FP€Jͬη~U;9c[XV7sNhvñ/v[G/7.Sc?/I%>^=&q*$'SAR%;qfK?cY~% t^&?ix>4Ql5'(h慎 ":Be745 %ͥ8?,9uiKF8"Rj +*io+=`_B|)N&XGE6 B + 3FBy2pL/Ca9|V@y4y6? sD$%9#c}N%ATر # tH~aeAp" >#j.b!K\q,K)eYSy9?Eʩ{oʱƲg"a}~'"!&.4A7)qq [Ts0 qp ƽmvr_}lzi^5/}W-+$9,ؓ]aJUG+||g ( #א.iEDNe (- [)Bdb=ɯ~FW6^ m ^ْ*L_z&IsZ~]\ ;OJ 8nFbGRiJlUY7 \j| Zz:OJrd"~DNeɸh|%b07L@@V"vv+xū{Clv[FMy̵B6q_D6W[k*-yqpB6Rޒu[N6b̷e.~sxS%Ͷx[Z(Vq94%ofӷ}9x><9Se}љm-o;巴,-ͯgݖ.緵<-#o+No. m=v#䖑пJ[Jm-o9ˊ[쿭-#oY+5pKC@LfUݶ0p}mr J$OBܾ$r[ +TaFV"tスFM +5nEqKp㖲(En;0rKm$4Prb- &MĊt`CE5ܶ%{_8-ُ +`!ް*͋;UY 7SaĽWo0SHDjߡe +3{t--5x~h+]Ϗ]\0QŅ.^ +-\&ɕ7Vrfw!l&&P1$ee=E9Oy۟8 +=q|ew&4l}Dm#(<¼*} ?G+aOv^;&B*/@`xT^ʲz8(_5JQ su'l/j?wƝ ɿ\<=`65mzG4|{oG[lי zڛ]>( H -h 28`.]rb,*5{p\ut!@ s5BP[;@]uE_O +lk [^nOH2Noݬq^e~4XlUjN'q49N*-dn# ސ/Z&屜 ?mVB~k>T|/]B)B*]4c.i>Wf3P'&U-1Jly\i!rd1ˌJz9wl%'%=[g&wcyk|ֵ!6u~>11 } +zm`v-{`atQ +L8ȿ1̯:|L^8CzNt.%Cmyt&f +^\{\wxzYI w$aր:%)6D Dy$h Nz-Y%ƛBNnMW0S\]KǵOǠ4tpS1$('<7"w♑X V3 =5 MJP߄$8譝3MU!Ї^"O@)05j<N,NjWr !pm>fQS$\7ߣfQS@f@M'q&pŒpycD= _W^@٪,H_?bgZS}ٯ,S0S2Y>6 5:S bGJY & &U=QKmK8lYSe T-ґюq[oT W3][$+jDKҖ ߊ%f27[&= jfڨY6؝E9dX:/ +I2 @mjR*lfd% | +:b`vR 3԰P9&F|Ԕj-$ZٴL1%AUĐQlW,{4-FF}zܬkSCHU!4vN-I +u$sE{ݐ\5cOMƢ0[kAvQGWNɔZ)GSjsRhJmE\:ypj +0GOh (ZLǺ(ڝFY¢3P'q#C/8"`ޑ7g1zN"Y@Ot9@6pg5` \EVXxu~8<{ ~\.5P7H,(YzX'gqQ}`["iT$Ԛfĺet-S͘KS͸>Ӹk24EEc^·k6OFR N586j0dӇoT0M֊.Ebӟ廟g UW=2PwpWϧ;#ٴRŸQX06Q +r"',bmwoڿYDž.oXβjE^T&UF 9N= -05&YDsW7z?OY1]v+/76C׏' R@(~կʯ9 CE7|O$^0֧1_c؂I?&W/[NWbJlѨLªLJ|^ !6o+[q! и !i;˪X300ԞE9Xu WZKE4fp[GR̊g#Ԥ ĔKH-iV"Z%VL+b*Ĝf%Z^"f%3+X0dA> W=X0oðc؆A\C\X {oOƛebhU+X+?m=ІȜ6`0~@*r2"@…űgMIiQIE((<9e|3t&Ne}[\PsZoCģֳ>R/ZSQ'}hɸ'@׀ +9U!*S@Srr.ܻc.)R#[aE/7̰vWmz3=\뻌51W2]C3WE--/tm{sa[}?Y j5`o0T,bT͔8D-X7 g窾bQKا"0{սgZ\ISQp_SV҃-+86.ٜiWөhG劦)zPbTR I(dOó-jl/"ƣ !ӱb<u{4~ɞ焲VӤ9\TQl~B0ͦ(92A]J0ov_)㢇&`36/zaQ| P'3'frT}JiR +}mqA3` !ۻXVxuә_<13EKM ٠G2g4;;%Ga@[ tԗ\CBx*ɜf4gB޿]y' M;!U?nk\M㸕F—ׯN:)_M1MhӸ_S@<ԕI21үM "JHEF9u.Gh0M1$3A G* |ǂ"{,9tI rnP!s<2t@j>ґXDW`[ S !0-ɐ"Y L%)r*EQмi2"%(}Fe/]@*.TsK\A]j0PG(mZ藰C>#Fq*%(f|#Tdh.܁x@2X` `@Nꕂ5{_wi&Ϲve/$ᚊV>Opmu*erPq.O?^2æ9+fŤ ".ZAI: RF; LL\eP/kW⻘4;K4Q}4ؖB]i(!,dm2-a>b@>#?"OċV:s%h3ZG@L MF#p:GppZ>'>pic `S 2FX5ɥs{^^[,wj]8s.K.T5t +qLa.]P1Ǒ<ǢyjS}00&P]5S11c7KZ&϶ߏ<[I4$}u֛^Az e^J*`IE ix 1~M$$ +asg\QS,*kb(tM0a-EhK)H5w;NԝK&od!Eu,<# k-N(S;T0}AY>,Op,W^R SHZBaکiul6'󪵜:bP[| !/E;RU@J7l0 h0~X)T0k([#ocSMr  k_%n/Y +6m۞8ť6r^+B)K,x&u`cОyMXp<Z9nj[cy tzSߩLmZ}b!ԗ"0p;9D,r,&p̺؛wjWRNaV?2KF>c{*恵xW)Esm_kK}XjS+߈bnjTȄ#DK欛nnCc!RƂҫnuşɢZ0!3(44=*j3Tύ6|@Gs'$UvO˂VQ  0f0x):"z.BVBe?6JĒ ft Sܲ3~m- l X1 _tERo![K.e+EOm1d֑<ϖP2׭1S6L`3ðgU@k%sLEtM1)E5UqO*W9~n~ s + i< ).FSҼޘM9TOJ- @3Pd:b_s堋ɸ/t-4HY%˺b25XӉhm1VbM_(I =Pl)}4*f}cfV݅N*⥲Y \Щs3Iufͺc7\Q2v60U %h._sIK?fsI`M6q yy~bA455n.l?'qD u %KaYEAy +VS1 E4Do'qα.]:tYEU p>NF%N3}WǢ #:Cu?J7S7rlf"ׂUR `#FzΎ)u53zp1qzV1 MaS\y:oeʮ)@^&ĥ6R@ޫӶ5\6O|t.M˞z;4Wf"f<,@$\CHDx,KjnoR.C[n>5bsgrP=dP}<}4~hY +<H+k=ie@@t]J7В=G1~D럻j1u}r=UWmy* 㒚;FO=U]fusxu`<3Ii?~?"nYjj)몕؅Ud$]Uޣ ٛ꼀kߟBBc@,ݕ + +O PSJ:IuC Uݼ1K->*Acm[\Tpy'_XǬ<x{Fw B pK4@Y(ޯrs" H; TÃrj~oԯ[Tu&>t`Y'/x@ߙ1R@?*@d ~uȿ +us+b#Ui7jBKw]khd/#.Z| +<A#-kSޕK4Fhk%+Zr/;Xon dlM].s vًt8B-?9%QB4xzFsw9\Rs/UO]ׂk]G^ӗ`ŗIiS SEԟ +m3[nժS6KiTѬiU}ЀǹZ9u:iL`g:DN\ۥ%X <\4P$-H'-˗.mpcV4^Uw&ۀg:,&nbд |wJȃLd[7 Hg·Z/k@| 9;BXʡX~^}ؓSܼJf\|?jC\!xx@^V!v+x4' gDؚ,>Hg@` Xtcd A jQiށJ:HXRr3) +)O)xyp *{}{EuW0wOӗG,[1Ǽ IEf!{߄:|9}ʧK2HPܒ @Pwj/$A +%@1L0u$IW$ji(wYjKWEӡt,w10 Fo:# + 4/&^{)&EU9BY%X(ZHlcQ('ӏG)S]x5%D,hZH9c=!0 2q{xooh:p%Yd`Әm8rܧWwrh&X> + +Q5><HaTf B WmOJ$A;.`‘P{L( 6sz/e~OrSG~)vTt=l|r8ZQI )觿?ikAiD' "aiBނq麃ͭD\P.])MEQa7 :"pRQpS废m LSc`  +}R'g PG!ߡ?Ouv`/iKr+pMT \KXpqu7[5!VY]JĴpJ;H_SsLȯeWwJ ]#ߴxM 2`Ʋ^qg`&zk1XFƊeI5sEgG8b k𣇊 +tю0B; +Vhcƨ|h])NUd5'|9(0k-5Fz /ߠR_MEͼm\T|zVɵEFrYԲȵIDsYVO[jY?'X5ΰ]$ItHءC$T +qKG%hFYTLF@ O{<=F jm#cWcx/0:P_pjm5QEsBA+UzD0ZAm:<%[^6 19b}EozF$|p.δz0#s،4:4U (z"(YR=O| 5jpn|ΉD#Mb|~4MV0OJX^f#Ÿ&D#m7}Oe=}q%eޕt=v~qPpfx9%nOCuI 1LLgY+[1>I푮v!'ZklJ$τOZ]HOqJ2=&%@ U=6V4,/%IQ\`z69ee*xڈei ,AP p|" f5w)T";2b?p>Q놹K?ˬsL## EhgtVo) ÿe07Nk2T\ +GTCVK~+r+!f,1JQΪcv4vd4Ƥ6 6Irt_Rr:n1~8.) u}B+hwXwdZ*4p*MjBSzR])IRsJuHd!PYYzyRdwm @Io(4'Z[ wPmЁF/saMٹj.˅_,v8ζ/LϘG$P[hCl+2&城 ̄E&@'Q:uE־H[:I;IXDQ >MlEqpگI +]ioOexs16n|V9-lAdvyN 2Q: +^/M-+S+ec,i@$4{+bZu a^_?҈tjPQy:q[ ߈SQdNx&ToU7'bN"SI?rԱi'kE'Jj1 krc~,&l6tvW,!4$L{^?b6BHQHNzi蛶VkXIYuurXSQwHxuW@*%mLzfńZ6Ku6'q,$;wjs螨]ykWer}&wLb`,p{q E{/; j9ȹ(ւal &TNeϋӯ:-/ЯgL|?=#bW8v^>?zeV˃8hx#Vdb +wl,6hSr&druWTg b3<*\ ?! 2ѹ~ 񒤧l;GjWW9[%XPW]_-( 99~Q# +Wij&dq7߯1 +q)ÔȤD͋ +"AC[ Xbc8{Ḍ%`מŻlN@hC|!_X[z+x,3 6-t:1du<|7 )<|Ia%+yk~ʐH[ϽuszlQi!#ˏ$_Ϛ[RV\찤clb"^.`7f̾IYvv&*S`1fiZjye^t5};2Uʣ[ X[,ɘ,Zۨ짼12Ff A!ngΡHKkR?%.4c 53w )<_RBI +kԓ[0o|{?=1xu\vGGo⥐d$ +)O!T jf|`S^ ljɋo{4nj҆.ϰECLrN&I: ktDCb]l7Ûu5CwCJdw@RFsDw{L +Z5 kA YM\@\v|`ѝnyŎ/3fc :'ڡA,r/PDuy֨, 6=``|q~DXV|$_)"c(?/U5KRa& QGOBLk}lsٌ +aa5=V˙c9u̩yUzen5D_7}ďi֍6Bp 6C/\~.T'h1i6l4qzb2Q̗wPP"ureoye3Ff,뗠 +bi. ZO@R8Pc + )#,22)rVQN-#J^ҔKW!45+yWP]E n;:LKK9q1Sĩ4&Wf\5OEjr;ϫ(E +aT5{&LO4PͲt˖9U.xY6ܩ"/ ˦U,UtUk!K ("`}m3W,l1@J`T.g)p?f:RRb%v<gL1B`*7TY)TE߶ +U=Gm^(^%U gh@+ Z@`X)E0|9FTr|<+v=ZWI?Q :7(K\J+YpBOˌHy#*&zӌK 5vy/LSkHq1dXS3㈡Z^̾&tʒЭ+oAB5 +)`EP4Ha=p5|\3bĻ ܀M[說]1Zl]yϕe Xb@" }.[m0GI6,5q{G`v;2nbR`7!IWpV !pW2BomD m;oʹ^tcUV#gs"E\?@PP̯ɾ%ҹ6l YKdp*ְ<\xWEZ-z=ԉSM8jqfO5<K TAKBf㗛=__co "t<uR.\ E2M$!f_ K%AҺ<4S7%bz=JC: E^`&#Dœ^yzu4H`R*'x;_"WEB>8 +uau{!XR&eI KBg~1YXc^C $`=-"eH!ʚ٣_fLmC|CP +i 78<<'BVZxC",DX!5ϡFb8Fٟ +F-'I`H8֚[0ډ6 ezԠI-fb?h}-JyX`6ԛ-GRiTsmH*~UsL/6 .{\PvB1G%fE|[]or[?Ry5:tڎ-hk>rcd%\nh ւ9fb<%ԆOm7h>%n[4҅E!!# $-&ARez@g3tI).:iOP*s1x.+ZVX2ԯWJKU28[b(Ŝ_,JABqK &+\?hy/YӞ8Tt;p J#l2#hT4 ,`W#"{)E8ˠ5ɶX`.ArD]h<E<5&9\1@Bqϖ1qYep  x:8XiM8hې=Ru*J4./Win߬v+67l0#K4Y8-"hߡV٣Ѣ6x(%͔zr +W^rQDpS|սgr%}+rü"Iu'4{ UĴ*#]a"3pzIݡ+ru"tgٹwR48>Sl*͡ﴧ )I/ylMP)Cs՟`ȅ #1hñmN`A]6uj@| CbЉH~I־>XM|X3ڝ9`lD,3bhaqV6Z5xͶ!C;pq""HauҌYchC ;Plhk@9B[ZµrCz.@*޷ƀM |@NwUy][NrLps]Ӧk tig;_עSPܷ.Ă_6csyTBgV(qW-biȲӵX4n΍嘾B2m\z* CϽjg)fge +4/CUg EYey D`(_h,U3°$JKca]je`w7|ood9o`3vePt~k܀.4йC{81 \eI& Q$s>^`BhPWR%l ; 5D9gKII ^\%}KKCd*Q<HVx, |"KWLghgvV_.ƞXpW2O'{2%:yfؾyەs yМNJzfМhTmvVmJ(MMe-qǧvk '%S^ki;_rl\E9v.a̦<fOoW^^Ro@k(>.KiTh.7zD2st-אXv?v$Hp /SOB:PU"TQ0ČJ(&s vr0L(kj4Dh՜hgi_yc .XP"TL25R]=H![Cp)>\ ({ hN258B'V{I8H>$Gp\{P(ؘ~lvW(5aU.Ijr\?k|V'r*ny}|={Cr-Sy#6Hdtn3gy2JRVoBM__}s.c8:1r1j' R6Xß_՗տ-WX?g.fK#ץ\kbws=n+|m^[#B + Å}F*Ft^FpҖeq *z(*TP 0̳gKЈ%uv(p9|)oc֘|R^PK1uTYfHLȝOo(6ōGr)$t +9P+܁ -L^ƀVēU^+auhU^  +N=rw Ύ|uߔ K6\wkC5݅Bb\dS7晠2,`px=ƹ Л nqeR &ZWryUK-iCHOFZ,GZct +\2M@>k@ޥK,?džlHʙr*1&!V_c7X}E%ۈ0GO5\ԏu%+hCH-y?;m?Ыimm0i[+^~;.u-޽YUS6vRDQ(g h_&#;b? !C[ z<|,\֎/9c=`&`)XiȒ +7@A ;!wK}uA$@ z)Ve f_ۏ(Y6OᇌZH\CNZBjQoaf +ϡ Cg׆'LD? `Q)B*p)vNUu!V'GU\6f1raPl€w|2^7@lQ(* x H$Vsrt^՞deU:u \̌҃> @3{o Mf׍w.1Ikp? VF9 |j$cU!X@}&z)\%=X4THNrlFrDzM?hR$@O%@,>=e#I"n / $Zl;=ן^~`hA=I®]~]vF$dol؞,20 7z-H|yG J fŸG`2;UOlY,۲lU; Vĝep9Fbx"'j M(cj2VQ"r2L%)"JpLSfdHUE r#QEY +W2-+H7&:H%SEV*D/kU,"يZOܾ8.DJl.bG[ 1 vO<&pQG靣, +l׼KV葽DD }!uWew/ +q0Z0:aP M؀UרWߋO'eK牗˗+hE +- -)Vvhtʢ7 .kрpxF X640ѲWX6lhӆdeZ  hwلt.W_)k"+O+SLMa{MOՀ 3oz>m+WYC#nsWR mTb'ʲ%u=$'?,P@`/w衧n=q TN<'pF)g&+ !>m_*Ժ 4;lGTXz +X>u(`=젎G O3 y: :a#TSF=n0V[Mր!uYW^sߜf#U' Ezu|d)ZUSf K4hʗ]K0\)|xN +֍PN?ջlMrfΫK;)jm*.=ܮwە VcwICK'WzPq#4TTK]:@' 9?~_{f P3To&PLB]⤞fkuZ3^9Xv$ s*s@ʀA"Wtr`[apР V=Z 8e$uIM>]շڃ Շ +]sCgiVnvpaȵ :8I-۬Ʃǡx",%̪0ՎT]u|Z,eK> k%[CxUh6\gT)iNswyPecw,wg)LvøgH ,ag5oJη .<(LF<'5lFg Z㳞zn[jyO%\N: zurv^Z˙*VX& ?jDRĒtsO3K--^:Hu#{M<l*;#R +`~ /O5-6/ +!?]nky aE"!Q\J җ闈Hb%tRˈ2KJK8aSbQ $@JzG%VU]29jdHaE\?+!$>$"N5g!N 7ˆSqAPQDsCv$]B\')W!Ʉ-.ErW@&J& \79<1Ġ `ZOI$ &;:d4"z.UsHJR1]:MM%Z;DR#)߂`>C +SP|x#^7"jz_N7DeD|f#K`Hp5h3(pOsZ q`o6jVI8gX=nөj{) G:UZݪ7@l:Z;KRK 8\Faîv]59N_4o35"8ڊVCܲ[wfC +t3%A/c |D~P;;|",0 pb8+ɴv6zEmРQc)Ua*M`bL~p\5G.?d2vC0/s[|J-:M9FQSQPQ` +XO;pRO%ւ]c&⧪ LY FYk{ jD"6 B +@BN=7*aDNC.6*"9DKE3M~·7LWL0]50]"?< .&n: CYLA?Qk ZnE.Ne R&z?F'ݞ_( u.t'n>ӓQ%}Y?Dgs8K(haR,j;oTLә" +Lp&C̔f,OX$f7((~JS-uҐs@*GBC2V)]^͘I?D38%[7vJeh9Afm +| /؅ h/^c1oߛp-nfp +L00q.q2A8?&k67d/׹%pyu.y]8 @%rK|8 Mn7uajq3aQ[cFQFv0kӠun%9لhn@V " lc0MJIMdֈ f#CYpz$M)*fZ3/~`%N2-EA`Ŋ-&rutlLHXp"M@0b!fQW`WZTΨ*`C+"եO( 5Uc!e܉; ]={  +xWLFʻpUgO %eb2&^hOZSj˝CmH"v@{DLӳv"yּgYcXgm³&` zֺtfnh%XZa^E$r[=-Z񹕥C5ÓblGǤī.=:ۍa)ug_1# 6{rk.`FhӆEȚ V X w962" $Cq4x~Yaоh` l|gm }` fĦ(-0/Cl`',MLR=,ʆ`dvޣ=sAzKÂr0O{wFNj;Q:gdv1EE+2gG@9lͱ{P3Lި. ]#+/~ͩĂ&d"l!äֱ1Y>΍JTS+Jb<S`rIz^-+Р`f 4h4XHJ|{,(`id olvF jVcZV;ՅeK ]KKCpi.Dce< NI2ԫ8IfG,K|1 ?dtId<f{`F7hޡK.9pgb?"E2Xeq4-!b|S"*G4fN0|VkRdl菢P@QIQ,EY=P0A!;Q؅Ja0 }F;!YƆڭ2 x(2 |G5 |AS +F0B|(`D$ld?f:mܸ"&fwŲ/̎E'OI,ZNKڔZ,GGtc 'gLA dC=p\A܅v! p2bEH̄aH`#z>sLCB<Հmj҉KcBA1Ӥ1EޗĞ,~hLC()":vx$X  οWcWVܭ#-`.4<ϣk/9/SDcD!Z@Eڍ2p+=b؅V%}w4|(pƇEqIYSDt*$?21{S3&`7'7/|[r O 3 +Θ&ʇh`KsfFV/YHadcp26+}'.qd)@BΝp>l$|6 VH`?fC15c,FO74כd+{*NfaYd4/v4r/^tOD;q8C!MrQ!A]חb ԕQbEsWoT/L̑ +>LyûU~RV yfp -ِ؆ +< Dql~ḭSMzhԕШPNӨg{HF$Ii1)RΦBʆ +6)9ZI4|Ilv X \$%rx!Kϑ=JWDc7FLЅJT,=Xd*dj0Ɉ]Te{G;hnx[}گ>b͟yKoVxܗ}\;_vY4qi;&n"Xx,O9-b'fYDŊg'ǁ];;~:.jVOچ؀e [J#3'y)gaŊ# "뉱M/7.P@-to>(oOH䜼|2",8q"Hgr!OЇSAa.Z`Tǝ/# Fbq/N4=2?D3ec24`>f{B\}Ys=<7Hlb::' +ܑQl>g;2kو~jߏ* +3N3NÝ/uI'`R$Ek[2jϛAPx]~à%qH&0H\XBS୲z@3f3`ۧ9X8zn!@_S}~\hs DDW|!Э0G*2 \4N"lVz+=ײ FsA]UӕjeE^Uڳb~çGTy  lqvY\e<ÐUQև蚳V&"LJ;TIIzQVȫf߽_?7de}_%hn~qkPjLUSyEdsQeֵ7%RAd4SjB- F4'Rќf|hc^_mv' rU:U7=mP_nرT`ؗ݁x 0rZ-N7Jm}c-6^PP S[`.LI!Ps^عv4gZf¡+f:,':VX9SXԌZayJ;+Y֙jY=kY;B~,Zk = Sv6T]8i!-|o7/ +j` +p+=/ܱW!f.±ⴑPS}w؜w:ojN7ίɝvPŭm@1fpO<jywY4Shұ:ch0*(TYT`,xnvm i$VtTv];ӂbPZ#"q7-]'臿Yˆ^U++ EX1Ԫh4SVg&9.L(vS ;Z5Ҥ nVSM+d[lcjpJT|G|NKv鼋ӵ sy33 P:@5d TjWjJ)Z'LOe2uSq\/Eh \tA+7o_B*!F22vV$(vra(7/=WF#rcR>{WeT:o  ,ʍf.R,;5m`OZ>!8$ Xq)Yz8UCu8g$\%eC>{՗۱h&Z?| :Euvb |k-ke-VD].V +kLjL*TI5S [W3EF\'+͗##U uag5P! C~C+MQdn<0E7\VepM hO;-_RjvY i +gܔ8g `2 ǨeRxu~8Oǻm~SPLM bǩ-`BlgRnI+ߖ~ a8@9 'ecؖ+l.#gH"bDΚ57 |ЭfJ D.Hc +jOyB~#p\^Q}鼹: 女ОXIpju*\t{l7y i(CO~Ukr[9"~bښWѻHѨ7eq yހZHem'DF%3FFrͥ2;,\Gv 8hYS0eȥ)&nl^+ 6RU0G9F,P'HOgW%끒 n;)[$pX :_G ,<5ܒ.1J)Ww dJTFYJ<%g0vciGR~M:+_jʜ\!'V{`@[FY|%r]. 4e;9ml(/̆$.Vlf\(P_ L Ǚ0<o7KiO5hN/\z:N)D%h2_J^ᢍ_fzKA-"k%BVJ@cCR 3Fh)owG|+^$*v:s2'x:P5w7g2]6s֢6Y-DA2ŠJ10?L46Q&^OTM© +HB:oIc d].W’Z HJ j]4G5M(צyĹ6\WeTs,HΈ$mܚ?ڄ}P9D.Erg(q (_8y7݊ā +iID՗~P/;xIL bUNεw6 [L[g$N¢2Y;A aSA s ߝNd¥Ρim3<ӫcMO_n>=nbGy%FyɃQed?4;k(O%S NV!S ,Q$zr rA- +q#<$R$}ǪL湪w Oa#VFuѪ0iE X׵~+Շ^:b`1%4J75^(|Sc_n:-6ni+1+Y// pId؟?\#"loUƝE ^9__Ŀ*.[;3Rʚg"+k{x5/ep hfٕb[}jZPB/.FlV~aw:P =g8>v̱MDdnfh"Gfw07ؘT .<]Go&9v@;Ch5v^2He.UjKlQ3؟H4~1ιX%̪gIS?auQ󚫵z -E +rnNzP@BH%eӀrXKGKcx 3wlEx)n/I=a,Grհ3iFGL#!{4e`4ۛꖰ+2Q-D)n̂!ϲLǪG^jX\ }jcd.>45yN}AAj^)jn{n==Mm7*Zd<·?jxSgY4C] +g_g'M|s"LbSLg s_$ܰhAk=5O2b=Aݗ- ~ gEPr@dPs=u±zO -{X̂K9z5q5M;zE~C: R8.,xw¯a,'0g`\Nyct_yёcGGh +[9Y`vyW0O|1;bry@Z9PuBPr颖 Q19HA݃b}&%fxhm-SE+ ETZt}z !9'8;R 9X37F.P:(`)&kYF_7`p8ίz/'$ƾ!1r|ԷߠQ<-ϣ:kf礹@z穷 7ϕnF"'w&p0^E˅z;_ $;=8r+ߐ31-MBd]N9ۦEz537 ;]o6^дۭvx:!y}|ܓ⥙u8A^,,!XcWP:JoW/Zʓ~,gB?:ߔ7>g'=hz|̭zzwܮAAR7@9J/^Q}鼦:B4n ܭ/߫xéQ 嚨CШJzjE,m_?kԻ6Ehՠ^n4{!haX euq}pB/k)L\#h#Z8ͥD2{bLF?2Y|~$%e +v^iڛ#S')(%|t(G l>nHLjmA_\ڽ"M\Mc_>KЬH"JC\z-ԙ]uMQ7eΒ"*91ɋyї42BK)ZzbB~xo`w@ Xtan,i'K(YBٰ4];e (k`@7؏c_>AO|gslnPN\NpYϿ갠1 mwX%_ !6tH%u.Q CT,3$͸[(vE]3,-{HGZT Bhn͝PhnL@A^< +4,c:|֬bBRL@ހ!)&$ń +?GkfH/ +ngP/zn1ABz-(FwAT|jDNur|T+|/#^l&?OeXQ`hc%VŠ6r#łl5eMAoyuڞ & +z)*' n7;ʩS!pG|7y[;Ph6":n)lw3:2<^o|8-] #N\ܙM>ݝۛq>o/7tc!<} Tf8[ P踓V?zSB[^3倍s e^ +q"hx |T88oJPw)hRL+-X-GM;2{ͧQődpKxP…ۦߣr\1.."KA؞`]B9T)MV sKNʹ#zc4#Ivh$R1́wgNvk]1#^}aN+mHn>Ud `Q c39`㿔QTݭ}?!<^CZ*W^0̏ ^jU'tNN-%_,@~7C5,J|A;QW"(oQ)kx2!_6 'RO^ِK +1Wv*Etg*püwo ͂,hp^ jk$hK="+}: &b~@DkZk4&o>ƨt3f=-ZpȌynʃ@5ߋ<,rZ0byz!i8Ȟ;0ՠe"P0iKS Hj;0 h/΀uN\#8c'*5R a }Dlgb_7w Z4R$[Aߙ]I-h pzdQ8VeadA Q"Dܘ%c\SY9&)+ &8i IbHsD5&%5eH/YV>#Ɛ)9l,φxӐG#r{Dq!9tp]0PXkPaYV%a[; a©a* } Ă$j G8`{w~zڭ?NeƙfT+9`T>{$-sI|9gUGeN. +2օ\j#ȍwƤ.߳EkzW)lOF3b>7Zq&W;tҔh72@%AZq)w"Z[uV=Jn-@[]ܬKPZYԴTCq!7jOSb$"bWG+Iy:x" _>AIwU7 CtxٓCn0%Km 6/*yb^}a"UBP\ _ ,-sJȞ̅Ȟ T3BzMnG˫t1'18FzEp;mx~0ާ02si}??/T%^q4%tW_^v@gH=m}7d@7@ aWt ?foހSGksUy:\`KJDwCtPFR$a?n :Ň'g`S07p?oxV'&u5x͍⮆TO'e.13o3+Ԩbf;W,ws_p:'W\m{~U|" k.c[2@-/@IS&/׾:_PMOfUz^M7JLt.!KDVYəƺ G_5Ȣ漺$ +JEg|"pH[o-)]|)="=#;s[mR]V~/m3V%P~_ϴ ]m3Ŝz6.7?jA,XbEm'`Sx SÄ,&0 ahPX +)҂NŷPq^]ɶT@ᦺGtM/}y^o^@S :HO:wͪ~fŊVrXP#%ݎQvVkz a2|.G^ou[GO pRS զj!X7: +&VUm$Jvmw־fl)4Ph\RQz߆k5H/OV5nr4^&XKM Ī{3/[Ns(t9vڣTU`[&%YNjrl?$r[s0 bL%)*l - +;ɫ_JEXwvy]ǞߘInjx\AF#TH)Fd9s CyX:pnL_P^]X[nr: vt =3H$9`H<7F+O>VC"~]' ߷_`ñF: +:>s\RcWrr + ۟< ; +U{u +{r9R3Յp ֞ݺ8fQܣK=kK5w}mKNhW循q5s@t$_rwd3[/D$.^PkH\ %E)d) +GWQ'6 -5noXcjDLLXs+^-tWjH@"L 19e) (*I8T~ؚf}!ou3ox_` ++,mv*KML6(Y>BjRJ'S]#r,fmJ'>rr>.0P5}Rڪsj67 +0+ԋ czL9% _)ͽ猥(pP1 5|H)~]0ĹCm+T1amB -ZK^O3ИrZ&X34i85QYJp[z[QFcM?4[QBl% UgD :(:F5 XuZyثI}av?j08[u2Ahm:`O"E/!CǮn7:]73OĴ#(t +WبuFٌcD .#ڙ:h1 = L~C5}x NMrj莫Sv钾4-v:ZG%;o[]zhiz=]>A;:3。o3>%zԐ/kߑ]4߽AmU<\i;7=+|.\ aapnf 0mw g Dqz.<#71=-xc L'?~~*@VoI)\]=MH~z}Mi9 +qdoBč[тY窄d>,Z<[ =v{Asx- A6*TL(<0@/ @Sܲ Y6Vݖ%{^x"gy8KSd/' A'!9g;YH ;A^T5[쁅0#+G'.=ˡlԽ ZX@9fBq"KN\N乢6= |H<p#0_1)o#hok82 * x8+tNOl\Oacy?l3rlE+`&+/}30 Yv+h}i6z`DLjЂŐtdRIiLtЊtRo@~5lO%qx(+>6h-L @~R/;N %u?2L j8qrH $;"|RuWz`a]$,Os_-!$"7.03Ka'wU3-j /FYiт\pKRXbiΠ@S]p=-U6BxL3+ö~x3yG`^lQ/T,\%dY3'Y숟l +<9~x#U\ +5FȠSu/y4_sL-< k@֠Z4=;\X׭ܛ^[G+sPQ^G _ՙk.Wz쀮])t-֥QxP#Py玻F9B{p@BZ + +ثu fdD{EY|%{Q3! ; !\RF~n˫DޯWB(R^u=<7XP R[;K6x%~uOh~fIcl(;)MpliA5)PUJesEyc1(VN.\ pWZ>#9pt/ɂ5Fs0*3 7E-$h]niҭu~ ڶ_rQg\dF-4釛zAPa.^l X,'eQ dR8Ѭ[fU`9Re[(̊9@8'R gl(UӛZoaf/#YHYhHRDwyxVxkߠnV=o~̶H[W<1in3ur򬜹сkLj eBsOB<# H7 +F' d $Ql*03毪!;J&j CJ1aS + mB)yw$ Nٙ\ %i+)!i{.xڛ>9b}qT=7eķ+@dsE ,?q &ݧ9yhY +S>W޷lB)#E{'{M5MaCO NNFU/6pG 9APL0>thv̱T0v~oK]mi Մwzhm*zqkU,1L:j_"/^^\[ЏħT"-o>vbq&)cmf7c3HALٹ+ΌE@hI2u ;Q]#}tS?;y|)[> {}PSH Ih~Q!܈A_4G M 5io./*MoRuoR=jMO+qMV&E*s|ԕL2396Mz?IM*ju-UnyL6fr@9SJ 4Vyh@_"'!p)ak}Z_.QY7Aā8=R_m߽ޑHE+o7 Ӟ*D~"oߔkvxIeM?q6/n._ɈNQM( W;2(= GI0uc6E0?!^P4sjA$k'\cy1l8ٳRIZ~d>j\P>!nyQnSKo&='-%i h `x-ͅ40CZu׼谎vDQyby 3h-1\fsvטa^ρj5YDnR*?d*ƾZ9W҂P-!!^YMY U!P[8@pR4%88ܣ]FuƧ}%W m6|^Lf< T&P@etL w ʘ@eFejaI03d1BHLӤ(v/u)RPP +YKE*Ca1Pkbcq +9>~z/QA>!rOڝntU7-U.Q^¾c$w%8E1&RcDY?%lb5]AΚS^H)#)A$/Щ)[U^u5!p'm#yՈBH8E? >xܝ xL퍪Y7b 7h1 C@㎌Y%GKp2T?J 2b|a4; &:S XZ>eω(T "O#dK-`v47M{S—7(,l$g[ܹ\;R'yӲTps)J Z/zC/F"6@דy$9({ӿgè{-];PcP3SYY"O<Bcc`l 4"H9wcc5`f]}|^7N3ĉHjfd68F6~z9rAIYlv; zڽBT||;?7|gr3q~3S^R8boG P,$oh%~=B\/fx6ƘQ2^X,vo[15 MX6d\&`xi $G@[mc/R(9ۤHUҫ+ɂJe#EuXKldmd +d^h['<4 hW M޻pO%fTD|_D~q.v@5Z(ގ޹. pu@>wy"P>' 4 0o mXnTx_'=/o64W#9*x)jZ-짻䑑~{<5 &?;jhm:tMN6CLuYTcRO99Ƥ6TlJ# o*Y 3 ^%@ZD!ii۔Ҷn߿]F#~}Sj`RY+ ܪPׯ0܅M*&9\+]NU/U#U%:G`u@b`xRE5Q_տ7-'b>ŝ.ެXvJͦ&uu22AH~{B:}wo^pɤ:XW"~6ej]%I_UCڤwuۛ`OFZZGiGZ;(jIG dΈX*2c]Y^mj>\ [&O&=Fv{ h'xA =S9⏍nY*rmB@)QggD}Fsgt=U)ܮN[(LYt3|Ǡ$ ׬66qsJ<7Ҧ>d].bY1d#ۏ;2 1∞Se!8/!^2:vԲZ7\]R:66]T/)>SmzV%bQJg1#:+O`>:uQD~͇WmPRv8_[ADOZRjWu&G, +XpD\czh;o .XB5 _7!Bսi]?dz#+}t-ѵQ_F?Y YwZ`~=})|gڬ•s1dilKqi_\'nQ/4t1B(ї%l+kJ1{plr~9jy +b 1cVYo'QHc1QXȈBOj 2OܢT: +oY\C|.x?6=۹L{Z^kRox\A%ȳDQ \ps,ur +={$frrInzMwfpJb Fmӆgq~ +,t-HI\PA *yGs7yMՆWu鄿,Mt$}y@mj&/ 5NS zOr_΄U?2P~@r_ vyccisMϧnlmtvd(ԹuEFa6o$`YW%T6 Ug0N +u:R)%KF&#h-ytTCcARWl=zfpߩ[CKs t%+e-d-ȥrZo?_#MO׏vn +t"*6Hz^%p1HqW=^Ui|ʫn>WWʪOR #=IS +ӝMڂ|hYrHjmT-ܤM\un* ܤm [ٲayeURm6)K[To%N>調ペ<}%k'^!)* Q֋'X$?WkA5KUj#ҔC!$ x 1Nr HYY7_\ēr49/cyi]>_Eq_~/LF6e X fMZ~j7?]⯓cg3NP D al%wy\i!'`Ra3^I ȯڹw~L_"2G~g\2ްG$cj(Y^&A,jᓆ-}b~-!X!bCbp㵄qHTjQXƆ +m6>/ؐ †,i#!Kw2\_`=Ncx^?q˜ϛoޟ*U>P4Sq>xAQ`34G1(| 7nIO  jwqn%R3l&(%BH$Z9X7S^d|W[oA\i:*Mkyv{_3C{0rX=NhQbA$-K |&j{KdOwɩViS!gt[BDce Z̈Xn+I ,…E\z)VK&ІL430L&Ռ Plt}Dc=D XH,c0$`r0[LV{?Ȑƌo3}$~i&%lNnx^`^`")] R_wnG&DvGåX=·{JgZ ?k"in5AODHKRnY6_t}]7gJW~QcEl|0@eAqD$V? .@ W5]\{j-Պ:ĪIzb=T>W.<{wxz"0D`'So"0L;o9\6NB/_Ȅ7 +P7}xp+7U ܜ_Ml56>;\(/V^Ω$gԺ&WwV?+wg$ | (8O@VDy : ,mLzr-NUF$zχw ,@igG +hXQ'V\?&{WNwyinhU*PK`pGPHt)`h}hIra،&>p2pv++r~OAK*) 2?mwT4zE ^mDfJP]u^.\u=M?x6`Kof "﷛03%*M]ca0qJj(gDtch= aar..%[3(FCz/U*ܽ3'S,cjf_?R6r:iaLiDu-|ق"@Y )14WFyYFmj$@N%!{py-ٝ$4vRh*oћ/4\L9qhޤ^A6>7gG>|\\*Kvg3)iYӟi:峢84"~AQ ;l1sž: \LO %ƶ ";}?;RI ^ "A~88? l!ѳwxӸQRZ$8n&4\2uVYxj',^if 6-[YSqT=+{]{84uEn/:}8V>x²o.H7Bn:k3)9Ch/ꥬ|}lSwh嶤嶐+Y-w#JM.A=?Nwz63V?/iĞGxL AdO.☦=^@{lGoB.B,yyO䝐t8bNn>9(u;(v_Az>gQW0\C`m' +j'Rj~µmO1; T\:T3RJ?,yE+ +Wċ*'](`K}X|^l9N!ĭgqtLku//t;җ}lRՇ=bH.=s '*c<>-Vk9e ]ݭ_ɐݐoJ,6>nݶnLř_?mEz{z=*rB[]Vl)عIxl{jmjI7GRXK\XKz(jI7+4%t,K0LG7x5 |7~'WdDclo HM 9 HZL la9 +@}F9)Qr)$GàoXT>>t^V$'׹Ge,rLY^㾝=>h,E-=^'N3*T eKihb[Zt}sAVٕC!o%*z·G츪Lc鼺V=9}Vhr]Ry+Igg2CQZqyn1:J@B:.[At +5"/ы4-Yyi E?fw/rXj-Go}€Εc//YQ֛^|tC߫[S6L#CsF|Kih#7 :4SCsKWՀ ǾnfYm< 4w47/-3%iaksxܷ3-77@Qfȥ`#~*_=~x|xډKDmɜ>mP.=;3|-9Uk[=+:Ǎ5GgOPuρB,~ۼ n.2:|CP^vZA+]ԜL0.9`\?o!\]>qL<_n>^We>xRy| k1_`ڝ,`l,ߑ)C͓ϲ /"Œ n_'už&%H `S( +;U)D*{nҫP;LSwa ~c ^|˰^ :/^M`!$I}2lW~GnDZI7#຀8 HG92M W>:m@[PDPߔ@KKbnZQ+FYPuIU6fn~_եj^H~F&am>ƒlgoV.H:te&*?|ɬ)$|)\WP5ϐЊ'kZ3|Ewtp;xr՝R׋OAW +(G~S z4%rѬy|Ao}y{rm}כd6%)7՝^xy?rLXԣ1>񀿘 m>I_٫'7Fq/ž +au>N{$>P,} |) Uw(aX`H"CGM3 E;jŽ1z +csf Oǥ1^|KjBNزb#&%jNݹЇL-Z'jQRamH.lRURQD?wzaΝrjߣ}[CLCXtOcLQ8O^ !|VfGQ| {J"w[򙠙v4RIoA#|tvt:ng1P:c%\ylB7mhYoF ZoG BMo'!@4qsw&cBw3d؀k[ @% ~p%/h ӽ?v',ywuJ|`nXPӪg[::2K=8(ѭOB>aeT[ h{\t*omة9I 9[D֜$oIO)d4ﳧ ӃL:`І{{]Uvy~}rU@8<>*FߋBDĒ~qiH?A-SSor: $G&;u8_uAt~:*sx@xF4t-. N"ѩBM~ +C(VVo=n}ܮj;LU,b^U\ @n#--̖̭Ew] $XbWgy4S1_Ӓ vH5igMX-R[`DjN<^ӝˋh탴hϽfMQ@L~ ZZ+R.U]ܡ?6-rʚY:i 6BR('Fū#+ret,zO?<$~a;_XrptFr `Aêv\FWפ\zO"O=7SMrAc6OLc+iVt `C/[#a'O%ۖK-D)]z'LA;ovls3}Kcm qHe'|_v0(`sL,?ގ +e|]`ҺXi~u,G &[+:ܯwÆ/l) e3C&v~?!} @se>@ [@gcDɎ DEѲ~O'k=B/A!-CpZam^[k&#!r#'ܰsfksKb/X,ڔjGn~/2b2XױZ>T_Xv% d]E=I'Oz Byb kG*ƕTA ޢ;dYUbT +:hҹLJBr{P֧Yu\{!BfPL>hZ'~o駺ɻfڬ~UIjN͚w19< [6 s2!nwف ݩIѳOVxB-M0۷ rbj߽p^'7[>CLL ٞT Ao91 ׵̤gLM<2*!$XCbPBЖ5iv uX +qc +E`?51#IY̴?cPloWiz9_%.eATr{|ޫ ꂛ'ycՏ ~,E˪; [c/W_{:<%HP秷oci jiU+Gg@plTkF:!<,jeI*rZTO~zܬWwecDz$N4UKtuic-}Q+J/?w2\ev>ʛ+ujûo8nUk$;KЎyC%ɫ^^0.9@CJY]DN5}{RqU57+կ2y}xNc_MYf4@y!/l!)&LCQ`> PxsF9W6S5Z떶'_F&s\(i't^m}τ/L= ~у?^2+=M(o"u^z?"nj{g!iБ/AQȲ֬y%tn٪fQL_%&)L I& i#}z/ŽdwR#|9];+0$iA~+0*r^u'pq.rLb=<75B\öZ <%zXA/H[Nlf"RyG1NA([嘿|r@ӡ ѝhf +S6jF^G-k˽Vsع3%<O~-{&DjzV&rVz=Å'6l'I̝$\G3S$vOI~h"b Ѕ*è*?A;VY8п~luEXR7q3+jC,E}&?\^N6a}?Ij|g_nKoKo>KYTqA38U x/؈Z/` ho{<+gʴtNsc9dT|3Uc^r%Hiki P 4ѐvϗ"Bxޞ[ +MMB,  K))&pQqT 5~| <^Ԓ^g- %˷YN= 1t`*YԲT0e.?>R|nfVfBW#\\*z]J> xcu֝A-hҟCܾQi9hOkhMaH ~ \w0)IU.D1h<ûM=R)DJxPPC??v +E ={\N+4)&oB~%~z O _]ڏ8VQ{$vJ[ 'gP+R &Ôjho[W^rcqb؟̘hfƐfTS|dw [z⿨/śH$t㿃 - ` +0PAfѼBPG;УH*"}!wLp(=ҚO㓴p`Hq%U|ڞgOY;Г:BҰW4pLkXVetQځ^^mŽQ"9ڽЇfkRDҪ2~ߒN,G(-SDemD%a9]Dg6u[$տ9]gYd֣/,SVAf}]meRˌhJӅ7r"pzC eej$M1h?,@Z Xq`I@014Da@X'|GXvI\3Li` +LoK=XO15(8׏ pҸPpߡJT-luZYrRo8eɤ| (e4&,K!,(H#p WnT>eFeJͳ-EmYZ\ _N30Q~T(]*{ˏob֫꼐U$ʧtސU-5n! ."h L)7L?O8u4咨>·l{{\?Umj5ӴٝOe9Z_T$|Eƨ/:}8V_~n 2+c4AS'z'ч:',G*45 I0D<41. xy4~ T 6>}G0ĕws&Gu<VP"aSdd3.r +=^kj X!ݻ^R׷bS'`V->jx鼈f K!ފ״x$#v2v+8kUbKt]s:=ie`.dϋ ؇"+@2Vo*2A8H,BթjP,EB E_:: +׈ RR#GO!'$ɶ\c!f& ")n{CE8~^Bd0&iZHO>_%|%xj_9 " @ *Mi)-%Gԓ1҈$(~keE.'Eα㷠zڽWixXD)%e%~U B5Е6ԡϿyCc<2LQ \mӹ|%%(?D, }y^-7T>+\‘LÉ1Caў,;$zx7+yNð&k:DrK- ŞSK>šJ˷,`3ϭuWFQ#גegduO[ %\&b@!P (AQ+'@:"r@R ͷ4?g p|> ™n\Z]kD)X$)DƢ0QqLECȞ +f)pC545鶴ᇕӹ GygD"φgzm nٖ7N? AxЫ&N#qp:ɌצI*"TrDoO} .Rvz0^h^';v/= Rw}1Уjp =V/a M|t?Ԏr8.V 2e6mOzǤ1t"3>o2lr55 H'A-//wS+'lb+3i, ׈7ԋާnh1>RP^L^afv-|0V|zKߟٟCmf_U8^tnA@_Z}>Q7W]Àg 4T.`xA`1g0Á3 '#Cp-~?駟3!dIz_\ay0JWzY㣇WK uX?}=N€}=zI QG*:n>o+)em2V%&S53z@HC2 .vU)il-c'lڐ H (_.o1ЈÝ_}\eeUqZrBk:3-lv/޴!,2!\j`eQyr5(mO!._i1J/KFt ; 1"tEITn`_a+"ڥJih~.3Bt0vYH@]e#0:g$+PS?UpXPԠu|ӆzB6pҪFmp΀;))XokEl s#BwH. 94SZl$.kьÎMXO80s;ά!!$CdjZ\n0uaJxTEn'DsPҽ:E(%]ٜЋtԵx=cwbXc;t>i1$r j%Q%eZz ƾvtr;^;< 0&elQ|o㴣SӭT{R.? {1?V~ ыC==ܚ@ Ep%%Ꙇ}'Ox$= +zCK+Qʡ/!><&RW~TapRѮPtKl +ҭN*qr[;5}رjreuxAP(/^p:K =u`^/ W*ĈΘ1Ӂˈt\QȬ(TP@JT?^~3PH/.xxQ%f]sk0Rk:s GRPwwo4wΚӨ8"[vۦN' xwȋ/EHiq'w+eN17nl$H9܅0t1Rx,- %albqI[,Dީ:y"巪|epeK]$.Y.2k(p:_, "JC~1f+_4f$_)-T,74| {xq3{[㥌2^7/*%NJi*G3XqlawVZSMNx='Hk`Çڧ&?Rm5HT +moN=tU*5;v}{2 qm-lcrY`쬗v֘珗[k.|g6낈K탣N.BP/+CC/JLIz{$Sv(rZC&o|s;3dxc@@nž_ +u|<9hЕ2c/鳂Y­gurzeJX%؞!7x>mP|@= +POx.痖Tr)y)ݦRMP\rT02cWW߂TrfvΔm>B4u?os]Tt}\ _a5G3Ħ ~0}4"89pE+.qQEG.v ˙Wʅ:dώnI} #h9̲$Ŧ ;3<:o ԝF-pNt&K ;_$ۈ &HLtҮ{/9ܫܕjd}/m;K}Xm! ˜BEIr/vHƒkr b. \ No newline at end of file diff --git a/core/modules/system/tests/fixtures/update/drupal-8.entity-test-to-rev-conversion-enabled.php b/core/modules/system/tests/fixtures/update/drupal-8.entity-test-to-rev-conversion-enabled.php new file mode 100644 index 0000000..2186d34 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/drupal-8.entity-test-to-rev-conversion-enabled.php @@ -0,0 +1,37 @@ +update('key_value') + ->fields([ + 'value' => 'i:8000;', + ]) + ->condition('collection', 'system.schema') + ->condition('name', 'entity_test_revisionable_schema_converter') + ->execute(); + +// Update core.extension. +$extensions = $connection->select('config') + ->fields('config', ['data']) + ->condition('collection', '') + ->condition('name', 'core.extension') + ->execute() + ->fetchField(); +$extensions = unserialize($extensions); +$extensions['module']['entity_test_revisionable_schema_converter'] = 8000; +$connection->update('config') + ->fields([ + 'data' => serialize($extensions), + ]) + ->condition('collection', '') + ->condition('name', 'core.extension') + ->execute(); diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ShapeItem.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ShapeItem.php index 0d2ebb9..acaf919 100644 --- a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ShapeItem.php +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/ShapeItem.php @@ -59,11 +59,11 @@ public static function schema(FieldStorageDefinitionInterface $field_definition) 'columns' => array( 'shape' => array( 'type' => 'varchar', - 'length' => 32, + 'length' => 64, ), 'color' => array( 'type' => 'varchar', - 'length' => 32, + 'length' => 64, ), ), ) + $foreign_keys; diff --git a/core/modules/system/tests/modules/entity_test_revisionable_schema_converter/entity_test_revisionable_schema_converter.info.yml b/core/modules/system/tests/modules/entity_test_revisionable_schema_converter/entity_test_revisionable_schema_converter.info.yml new file mode 100644 index 0000000..1e9cdd7 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_revisionable_schema_converter/entity_test_revisionable_schema_converter.info.yml @@ -0,0 +1,8 @@ +name: 'Entity Revisionable Schema Converter Test' +type: module +description: 'Provides an entity type for testing the revisionable schema converter.' +package: Testing +version: VERSION +core: 8.x +dependencies: + - entity_test diff --git a/core/modules/system/tests/modules/entity_test_revisionable_schema_converter/entity_test_revisionable_schema_converter.install b/core/modules/system/tests/modules/entity_test_revisionable_schema_converter/entity_test_revisionable_schema_converter.install new file mode 100644 index 0000000..15ca20a --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_revisionable_schema_converter/entity_test_revisionable_schema_converter.install @@ -0,0 +1,698 @@ + [ + 'description' => 'The base table for entity_test_to_rev_conversion entities.', + 'primary key' => ['id',], + 'indexes' => [], + 'foreign keys' => [ + 'entity_test_to_rev_conversion__revision' => [ + 'table' => 'entity_test_to_rev_conversion_revision', + 'columns' => ['revision_id' => 'revision_id',], + ], + ], + 'unique keys' => [ + 'entity_test_to_rev_conversion__revision_id' => ['revision_id',], + 'entity_test_to_rev_conversion_field__uuid__value' => ['uuid',], + ], + 'fields' => [ + 'id' => [ + 'type' => 'serial', + 'unsigned' => TRUE, + 'size' => 'normal', + 'not null' => TRUE, + ], + 'revision_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'normal', + 'not null' => FALSE, + ], + 'type' => [ + 'type' => 'varchar', + 'length' => 255, + 'binary' => FALSE, + 'not null' => TRUE, + ], + 'uuid' => [ + 'type' => 'varchar_ascii', + 'length' => 128, + 'binary' => FALSE, + 'not null' => TRUE, + ], + 'langcode' => [ + 'type' => 'varchar_ascii', + 'length' => 12, + 'not null' => TRUE, + ], + ], + ], + 'entity_test_to_rev_conversion_revision' => [ + 'description' => 'The revision table for entity_test_to_rev_conversion entities.', + 'primary key' => ['revision_id',], + 'indexes' => ['entity_test_to_rev_conversion__id' => ['id',],], + 'foreign keys' => [ + 'entity_test_to_rev_conversion__revisioned' => [ + 'table' => 'entity_test_to_rev_conversion', + 'columns' => ['id' => 'id',], + ], + ], + 'fields' => [ + 'id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'normal', + 'not null' => TRUE, + ], + 'revision_id' => [ + 'type' => 'serial', + 'unsigned' => TRUE, + 'size' => 'normal', + 'not null' => TRUE, + ], + 'langcode' => [ + 'type' => 'varchar_ascii', + 'length' => 12, + 'not null' => TRUE, + ], + ], + 'unique keys' => [], + ], + 'entity_test_to_rev_conversion_field_data' => [ + 'description' => 'The data table for entity_test_to_rev_conversion entities.', + 'primary key' => ['id', 'langcode',], + 'indexes' => [ + 'entity_test_to_rev_conversion__id__default_langcode__langcode' => [ + 'id', + 'default_langcode', + 'langcode', + ], + 'entity_test_to_rev_conversion__revision_id' => ['revision_id',], + 'entity_test_to_rev_conversion__f655316315' => ['user_id',], + 'entity_test_to_rev_conversion__34eed4023e' => ['content_translation_uid',], + ], + 'foreign keys' => [ + 'entity_test_to_rev_conversion' => [ + 'table' => 'entity_test_to_rev_conversion', + 'columns' => ['id' => 'id',], + ], + 'entity_test_to_rev_conversion_field__test_multiple_properties__shape' => [ + 'table' => 'shape', + 'columns' => ['test_multiple_properties__shape' => 'id',], + ], + ], + 'fields' => [ + 'id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'normal', + 'not null' => TRUE, + ], + 'revision_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'normal', + 'not null' => TRUE, + ], + 'type' => [ + 'type' => 'varchar', + 'length' => 255, + 'binary' => FALSE, + 'not null' => TRUE, + ], + 'langcode' => [ + 'type' => 'varchar_ascii', + 'length' => 12, + 'not null' => TRUE, + ], + 'name' => [ + 'type' => 'varchar', + 'length' => 32, + 'binary' => FALSE, + 'not null' => FALSE, + ], + 'created' => ['type' => 'int', 'not null' => FALSE,], + 'user_id' => [ + 'description' => 'The ID of the target entity.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + ], + 'test_single_property' => [ + 'type' => 'varchar', + 'length' => 255, + 'binary' => FALSE, + 'not null' => FALSE, + ], + 'test_multiple_properties__shape' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + 'test_multiple_properties__color' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + 'default_langcode' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + ], + 'content_translation_source' => [ + 'type' => 'varchar_ascii', + 'length' => 12, + 'not null' => FALSE, + ], + 'content_translation_outdated' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => FALSE, + ], + 'content_translation_uid' => [ + 'description' => 'The ID of the target entity.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + ], + 'content_translation_status' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => FALSE, + ], + 'content_translation_changed' => [ + 'type' => 'int', + 'not null' => FALSE, + ], + ], + 'unique keys' => [], + ], + 'entity_test_to_rev_conversion_field_revision' => [ + 'description' => 'The revision data table for entity_test_to_rev_conversion entities.', + 'primary key' => ['revision_id', 'langcode',], + 'indexes' => [ + 'entity_test_to_rev_conversion__id__default_langcode__langcode' => [ + 'id', + 'default_langcode', + 'langcode', + ], + 'entity_test_to_rev_conversion__34eed4023e' => ['content_translation_uid',], + ], + 'foreign keys' => [ + 'entity_test_to_rev_conversion' => [ + 'table' => 'entity_test_to_rev_conversion', + 'columns' => ['id' => 'id',], + ], + 'entity_test_to_rev_conversion__revision' => [ + 'table' => 'entity_test_to_rev_conversion_revision', + 'columns' => ['revision_id' => 'revision_id',], + ], + 'entity_test_to_rev_conversion_field__test_multiple_properties__shape' => [ + 'table' => 'shape', + 'columns' => ['test_multiple_properties__shape' => 'id',], + ], + ], + 'fields' => [ + 'id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'normal', + 'not null' => TRUE, + ], + 'revision_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'normal', + 'not null' => TRUE, + ], + 'langcode' => [ + 'type' => 'varchar_ascii', + 'length' => 12, + 'not null' => TRUE, + ], + 'test_single_property' => [ + 'type' => 'varchar', + 'length' => 255, + 'binary' => FALSE, + 'not null' => FALSE, + ], + 'test_multiple_properties__shape' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + 'test_multiple_properties__color' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + 'default_langcode' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + ], + 'content_translation_source' => [ + 'type' => 'varchar_ascii', + 'length' => 12, + 'not null' => FALSE, + ], + 'content_translation_outdated' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => FALSE, + ], + 'content_translation_uid' => [ + 'description' => 'The ID of the target entity.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + ], + 'content_translation_status' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => FALSE, + ], + 'content_translation_changed' => [ + 'type' => 'int', + 'not null' => FALSE, + ], + ], + 'unique keys' => [], + ], + 'entity_test_to_rev_conversion__a37a3596ca' => [ + 'description' => 'Data storage for entity_test_to_rev_conversion field test_single_property_multiple_values.', + 'fields' => [ + 'bundle' => [ + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance', + ], + 'deleted' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'A boolean indicating whether this data item has been deleted', + ], + 'entity_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity id this data is attached to', + ], + 'revision_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity revision id this data is attached to', + ], + 'langcode' => [ + 'type' => 'varchar_ascii', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The language code for this data item.', + ], + 'delta' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The sequence number for this data item, used for multi-value fields', + ], + 'test_single_property_multiple_values_value' => [ + 'type' => 'varchar', + 'length' => 255, + 'binary' => FALSE, + 'not null' => TRUE, + ], + ], + 'primary key' => ['entity_id', 'deleted', 'delta', 'langcode',], + 'indexes' => [ + 'bundle' => ['bundle',], + 'revision_id' => ['revision_id',], + ], + ], + 'entity_test_to_rev_conversion_r__a37a3596ca' => [ + 'description' => 'Revision archive storage for entity_test_to_rev_conversion field test_single_property_multiple_values.', + 'fields' => [ + 'bundle' => [ + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance', + ], + 'deleted' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'A boolean indicating whether this data item has been deleted', + ], + 'entity_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity id this data is attached to', + ], + 'revision_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity revision id this data is attached to', + ], + 'langcode' => [ + 'type' => 'varchar_ascii', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The language code for this data item.', + ], + 'delta' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The sequence number for this data item, used for multi-value fields', + ], + 'test_single_property_multiple_values_value' => [ + 'type' => 'varchar', + 'length' => 255, + 'binary' => FALSE, + 'not null' => TRUE, + ], + ], + 'primary key' => [ + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'langcode', + ], + 'indexes' => [ + 'bundle' => ['bundle',], + 'revision_id' => ['revision_id',], + ], + ], + 'entity_test_to_rev_conversion__26859c2758' => [ + 'description' => 'Data storage for entity_test_to_rev_conversion field test_multiple_properties_multiple_values.', + 'fields' => [ + 'bundle' => [ + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance', + ], + 'deleted' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'A boolean indicating whether this data item has been deleted', + ], + 'entity_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity id this data is attached to', + ], + 'revision_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity revision id this data is attached to', + ], + 'langcode' => [ + 'type' => 'varchar_ascii', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The language code for this data item.', + ], + 'delta' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The sequence number for this data item, used for multi-value fields', + ], + 'test_multiple_properties_multiple_values_shape' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + 'test_multiple_properties_multiple_values_color' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + ], + 'primary key' => ['entity_id', 'deleted', 'delta', 'langcode',], + 'indexes' => [ + 'bundle' => ['bundle',], + 'revision_id' => ['revision_id',], + ], + 'foreign keys' => [ + 'test_multiple_properties_multiple_values_shape' => [ + 'table' => 'shape', + 'columns' => ['test_multiple_properties_multiple_values_shape' => 'id',], + ], + ], + ], + 'entity_test_to_rev_conversion_r__26859c2758' => [ + 'description' => 'Revision archive storage for entity_test_to_rev_conversion field test_multiple_properties_multiple_values.', + 'fields' => [ + 'bundle' => [ + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance', + ], + 'deleted' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'A boolean indicating whether this data item has been deleted', + ], + 'entity_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity id this data is attached to', + ], + 'revision_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity revision id this data is attached to', + ], + 'langcode' => [ + 'type' => 'varchar_ascii', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The language code for this data item.', + ], + 'delta' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The sequence number for this data item, used for multi-value fields', + ], + 'test_multiple_properties_multiple_values_shape' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + 'test_multiple_properties_multiple_values_color' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + ], + 'primary key' => [ + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'langcode', + ], + 'indexes' => [ + 'bundle' => ['bundle',], + 'revision_id' => ['revision_id',], + ], + 'foreign keys' => [ + 'test_multiple_properties_multiple_values_shape' => [ + 'table' => 'shape', + 'columns' => ['test_multiple_properties_multiple_values_shape' => 'id',], + ], + ], + ], + 'entity_test_to_rev_conversion__e37161fa29' => [ + 'description' => 'Data storage for entity_test_to_rev_conversion field field_test_configurable_field.', + 'fields' => [ + 'bundle' => [ + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance', + ], + 'deleted' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'A boolean indicating whether this data item has been deleted', + ], + 'entity_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity id this data is attached to', + ], + 'revision_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity revision id this data is attached to', + ], + 'langcode' => [ + 'type' => 'varchar_ascii', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The language code for this data item.', + ], + 'delta' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The sequence number for this data item, used for multi-value fields', + ], + 'field_test_configurable_field_shape' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + 'field_test_configurable_field_color' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + ], + 'primary key' => ['entity_id', 'deleted', 'delta', 'langcode',], + 'indexes' => [ + 'bundle' => ['bundle',], + 'revision_id' => ['revision_id',], + ], + 'foreign keys' => [ + 'field_test_configurable_field_shape' => [ + 'table' => 'shape', + 'columns' => ['field_test_configurable_field_shape' => 'id',], + ], + ], + ], + 'entity_test_to_rev_conversion_r__e37161fa29' => [ + 'description' => 'Revision archive storage for entity_test_to_rev_conversion field field_test_configurable_field.', + 'fields' => [ + 'bundle' => [ + 'type' => 'varchar_ascii', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance', + ], + 'deleted' => [ + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'A boolean indicating whether this data item has been deleted', + ], + 'entity_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity id this data is attached to', + ], + 'revision_id' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The entity revision id this data is attached to', + ], + 'langcode' => [ + 'type' => 'varchar_ascii', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The language code for this data item.', + ], + 'delta' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The sequence number for this data item, used for multi-value fields', + ], + 'field_test_configurable_field_shape' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + 'field_test_configurable_field_color' => [ + 'type' => 'varchar', + 'length' => 64, + 'not null' => FALSE, + ], + ], + 'primary key' => [ + 'entity_id', + 'revision_id', + 'deleted', + 'delta', + 'langcode', + ], + 'indexes' => [ + 'bundle' => ['bundle',], + 'revision_id' => ['revision_id',], + ], + 'foreign keys' => [ + 'field_test_configurable_field_shape' => [ + 'table' => 'shape', + 'columns' => ['field_test_configurable_field_shape' => 'id',], + ], + ], + ], + ]; + + $revisionableSchemaConverter = new \Drupal\Core\Entity\Sql\RevisionableSchemaConverter( + 'entity_test_to_rev_conversion', + \Drupal::entityTypeManager(), + \Drupal::entityDefinitionUpdateManager(), + \Drupal::service('entity.last_installed_schema.repository'), + \Drupal::database() + ); + + $revisionableSchemaConverter->convertSchema( + $sandbox, + $schema, + 'revision_id', + 'entity_test_to_rev_conversion_revision', + 'entity_test_to_rev_conversion_field_revision', + ['test_single_property', 'test_multiple_properties', 'test_single_property_multiple_values', 'test_multiple_properties_multiple_values'] + ); +} diff --git a/core/modules/system/tests/modules/entity_test_revisionable_schema_converter/entity_test_revisionable_schema_converter.module b/core/modules/system/tests/modules/entity_test_revisionable_schema_converter/entity_test_revisionable_schema_converter.module new file mode 100644 index 0000000..b02d933 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test_revisionable_schema_converter/entity_test_revisionable_schema_converter.module @@ -0,0 +1,6 @@ +setLabel(t('Field with a single property')) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE); + + $fields['test_multiple_properties'] = BaseFieldDefinition::create('shape') + ->setLabel(t('Field with a multiple property')) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE); + + $fields['test_single_property_multiple_values'] = BaseFieldDefinition::create('string') + ->setLabel(t('Field with a single property and multiple values')) + ->setCardinality(2) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE); + + $fields['test_multiple_properties_multiple_values'] = BaseFieldDefinition::create('shape') + ->setLabel(t('Field with a multiple properties and multiple values')) + ->setCardinality(2) + ->setTranslatable(TRUE) + ->setRevisionable(TRUE); + + return $fields; + } + +} diff --git a/core/tests/Drupal/Tests/Core/Entity/RevisionableSchemaConverterTest.php b/core/tests/Drupal/Tests/Core/Entity/RevisionableSchemaConverterTest.php index b244252..75a417d 100644 --- a/core/tests/Drupal/Tests/Core/Entity/RevisionableSchemaConverterTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/RevisionableSchemaConverterTest.php @@ -2,14 +2,10 @@ namespace Drupal\Tests\Core\Entity; -use Drupal\Core\Entity\ContentEntityInterface; use Drupal\system\Tests\Update\UpdatePathTestBase; /** - * Testing RevisionableSchemaConverter correctly updates Shortcut entity to be - * revisionable. - * - * @package Drupal\system\Tests\Update + * Tests updating an entity type with existing data to be revisionable. * * @group entity */ @@ -18,8 +14,16 @@ class RevisionableSchemaConverterTest extends UpdatePathTestBase { /** * {@inheritdoc} */ + protected static $modules = ['entity_test_revisionable_schema_converter']; + + /** + * {@inheritdoc} + */ protected function setDatabaseDumpFiles() { - $this->databaseDumpFiles = [__DIR__ . '/../../../../../modules/system/tests/fixtures/update/drupal-8.filled.standard.php.gz']; + $this->databaseDumpFiles = [ + __DIR__ . '/../../../../../modules/system/tests/fixtures/update/drupal-8.2.0-filled.standard.entity_test_to_rev_conversion.php.gz', + __DIR__ . '/../../../../../modules/system/tests/fixtures/update/drupal-8.entity-test-to-rev-conversion-enabled.php', + ]; } /** @@ -28,24 +32,47 @@ protected function setDatabaseDumpFiles() { public function testMakeRevisionable() { $this->runUpdates(); - $entity_type_manager = $this->container->get('entity_type.manager'); - $shortcut = $entity_type_manager->getStorage('shortcut')->getEntityType(); + /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_test_to_rev_conversion */ + $entity_test_to_rev_conversion = $this->container->get('entity.last_installed_schema.repository')->getLastInstalledDefinition('entity_test_to_rev_conversion'); + $this->assertTrue($entity_test_to_rev_conversion->isRevisionable()); + + /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */ + $storage = $this->container->get('entity_type.manager')->getStorage('entity_test_to_rev_conversion'); + $this->assertEqual(count($storage->loadMultiple()), 101, 'All test entities were found.'); + + // Check that each field value was copied correctly to the revision tables. + for ($i = 1; $i <= 101; $i++) { + $revision = $storage->loadRevision($i); + + $this->assertEqual($i . ' - test single property', $revision->test_single_property->value); + + $this->assertEqual($i . ' - test multiple properties - shape', $revision->test_multiple_properties->shape); + $this->assertEqual($i . ' - test multiple properties - color', $revision->test_multiple_properties->color); + + $this->assertEqual($i . ' - test single property multiple values 0', $revision->test_single_property_multiple_values->value); + $this->assertEqual($i . ' - test single property multiple values 1', $revision->test_single_property_multiple_values[1]->value); + + $this->assertEqual($i . ' - test multiple properties multiple values - shape 0', $revision->test_multiple_properties_multiple_values[0]->shape); + $this->assertEqual($i . ' - test multiple properties multiple values - color 0', $revision->test_multiple_properties_multiple_values[0]->color); + $this->assertEqual($i . ' - test multiple properties multiple values - shape 1', $revision->test_multiple_properties_multiple_values[1]->shape); + $this->assertEqual($i . ' - test multiple properties multiple values - color 1', $revision->test_multiple_properties_multiple_values[1]->color); + + // Do the same checks for translated field values. + $translation = $revision->getTranslation('ro'); - /** @var ContentEntityInterface $last_installed_shortcut */ - $last_installed_shortcut = $this->container->get('entity.last_installed_schema.repository')->getLastInstalledDefinition($shortcut->id()); - $this->assertTrue($last_installed_shortcut->isRevisionable()); + $this->assertEqual($i . ' - test single property - ro', $translation->test_single_property->value); - $shortcut_storage = $entity_type_manager->getStorage($shortcut->id()); - $shortcut_entities = $shortcut_storage->loadMultiple(); - $this->assertEqual(count($shortcut_entities), 4, "Four Shortcut entities found"); + $this->assertEqual($i . ' - test multiple properties - shape - ro', $translation->test_multiple_properties->shape); + $this->assertEqual($i . ' - test multiple properties - color - ro', $translation->test_multiple_properties->color); - /** @var \Drupal\shortcut\ShortcutInterface $revision_one */ - $revision_one = $shortcut_storage->loadRevision(1); - $this->assertEqual(1, $revision_one->getRevisionId(), "Revision 1 is revision 1"); + $this->assertEqual($i . ' - test single property multiple values 0 - ro', $translation->test_single_property_multiple_values[0]->value); + $this->assertEqual($i . ' - test single property multiple values 1 - ro', $translation->test_single_property_multiple_values[1]->value); - $revision_one->setNewRevision(TRUE); - $revision_one->save(); - $this->assertEqual(5, $revision_one->getRevisionId(), "New shortcut revision created"); + $this->assertEqual($i . ' - test multiple properties multiple values - shape 0 - ro', $translation->test_multiple_properties_multiple_values[0]->shape); + $this->assertEqual($i . ' - test multiple properties multiple values - color 0 - ro', $translation->test_multiple_properties_multiple_values[0]->color); + $this->assertEqual($i . ' - test multiple properties multiple values - shape 1 - ro', $translation->test_multiple_properties_multiple_values[1]->shape); + $this->assertEqual($i . ' - test multiple properties multiple values - color 1 - ro', $translation->test_multiple_properties_multiple_values[1]->color); + } } }