From dc5f9e6f3b0796113588c484e9c95c55cfdbbecd Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Mon, 9 Oct 2023 19:29:45 -0700 Subject: [PATCH 01/38] test keytar library --- lib/authentication/secureStorage.js | 50 +++++++++++++++++++ package.json | 3 +- .../unit/authentication/secureStorage_test.js | 44 ++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 lib/authentication/secureStorage.js create mode 100644 test/unit/authentication/secureStorage_test.js diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js new file mode 100644 index 000000000..40de3d243 --- /dev/null +++ b/lib/authentication/secureStorage.js @@ -0,0 +1,50 @@ + +const path = require('path'); +const GlobalConfig = require('../global_config'); +const Logger = require('../logger'); +const keytar = require('keytar'); +function createCredentialCacheDir() { + const cacheDirectory = GlobalConfig.mkdirCacheDir(process.env.SF_TEMPORARY_CREDENTIAL_CACHE_DIR); + const credCache = path.join(cacheDirectory, 'temporary_credential.json'); + Logger.getInstance().info('Cache directory: ', credCache); + return credCache; +} + +/** + * + * @param {String} host + * @param {String} user + * @param {String} cred_type + * @returns + */ +function buildTemporaryCredentialName(host, user, cred_type) { + return `{${host.toUpperCase()}}:{${user.toUpperCase()}}:{SF_NODE_JS_DRIVER}:{${cred_type}}`; +} + +async function writeCredential(host, user, credType, token){ + if (!token || token == '') { + Logger.getInstance().debug('Token is not provided'); + } else { + const result = await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); + + if (!result){ + Logger.getInstance().error('Failed to save the credential. Please check whether OS is supporting Local Secure Storage or not.'); + } + } +} + +async function readCredential(host, user, credType) { + return await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType)); +} + +async function deleteCredential(host, user, credType) { + await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType)); +} + +module.exports = { + createCredentialCacheDir, + buildTemporaryCredentialName, + wrtieCredential, + readCredential, + deleteCredential +}; \ No newline at end of file diff --git a/package.json b/package.json index ca97385cc..ef17d747f 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "glob": "^7.1.6", "https-proxy-agent": "^5.0.1", "jsonwebtoken": "^9.0.0", + "keytar": "^7.9.0", "mime-types": "^2.1.29", "mkdirp": "^1.0.3", "moment": "^2.29.4", @@ -77,4 +78,4 @@ "url": "https://www.snowflake.com/" }, "license": "Apache-2.0" -} +} \ No newline at end of file diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js new file mode 100644 index 000000000..70328007b --- /dev/null +++ b/test/unit/authentication/secureStorage_test.js @@ -0,0 +1,44 @@ +const assert = require('assert'); +const keytar = require('keytar'); +const SecureStorage = require('../../../lib/authentication/secureStorage'); +const { randomUUID } = require('crypto'); + +describe('Secure Storage Test', function () { + const host = 'mock_test'; + const user = 'mock_user'; + const credType = 'MOCK_CREDTYPE'; + const randomPassword = randomUUID(); + const userNameForStorage = SecureStorage.buildTemporaryCredentialName(host, user, credType); + + async function findCredentialFromStorage (userName, password){ + const credentialList = await keytar.findCredentials(host); + const result = credentialList.some((element) => { + return element.account === userName && element.password === password; + }); + return result; + } + + it('test build user name', function (){ + assert.strictEqual(userNameForStorage, + '{MOCK_TEST}:{MOCK_USER}:{SF_NODE_JS_DRIVER}:{MOCK_CREDTYPE}' + ); + }); + + it('test - write the mock credential in Local Storage', async function () { + await SecureStorage.writeCredential(host, user, credType, randomPassword); + const result = await findCredentialFromStorage(userNameForStorage, randomPassword); + assert.strictEqual(result, true); + }); + + it('test - read the mock credential in Local Stoage', async function () { + const savedPassword = await SecureStorage.readCredential(host, user, credType); + assert.strictEqual(savedPassword, randomPassword); + }); + + it('test - delet the mock credential in Local Storage', async function () { + await SecureStorage.deleteCredential(host, user, credType); + const result = await findCredentialFromStorage(userNameForStorage, randomPassword); + assert.strictEqual(result, false); + }); +}); + From 5e3cb1180d1862f8f5663dd21c6f82c2ea759b88 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Mon, 9 Oct 2023 23:10:32 -0700 Subject: [PATCH 02/38] secure storage test --- lib/agent/ocsp_response_cache.js | 2 +- lib/authentication/authentication.js | 9 +++++++++ lib/connection/connection.js | 7 ++++++- lib/connection/connection_config.js | 18 ++++++++++++++++++ lib/constants/error_messages.js | 2 ++ lib/errors.js | 2 ++ lib/global_config.js | 4 ++-- lib/parameters.js | 8 ++++++++ test/unit/connection/connection_config_test.js | 11 +++++++++++ 9 files changed, 59 insertions(+), 4 deletions(-) diff --git a/lib/agent/ocsp_response_cache.js b/lib/agent/ocsp_response_cache.js index 112a8e3fc..e19ecb877 100644 --- a/lib/agent/ocsp_response_cache.js +++ b/lib/agent/ocsp_response_cache.js @@ -30,7 +30,7 @@ var maxAgeSec = GlobalConfig.getOcspResponseCacheMaxAge(); Errors.assertInternal(Util.number.isPositiveInteger(sizeLimit)); Errors.assertInternal(Util.number.isPositiveInteger(maxAgeSec)); -const cacheDir = GlobalConfig.mkdirCacheDir(); +const cacheDir = GlobalConfig.mkdirCacheDir(process.env.SF_OCSP_RESPONSE_CACHE_DIR); const cacheFileName = path.join(cacheDir, "ocsp_response_cache.json"); // create a cache to store the responses, dynamically changes in size var cache; diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index 6972398d3..1898998a0 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -14,6 +14,8 @@ var authenticationTypes = EXTERNAL_BROWSER_AUTHENTICATOR: 'EXTERNALBROWSER', KEY_PAIR_AUTHENTICATOR: 'SNOWFLAKE_JWT', OAUTH_AUTHENTICATOR: 'OAUTH', + ID_TOKEN_AUTHENTICATOR: 'ID_TOKEN', + MFA_TOEKN_AUTHENTICATOR: 'MFA_TOEKN', }; exports.authenticationTypes = authenticationTypes; @@ -89,6 +91,13 @@ exports.getAuthenticator = function getAuthenticator(connectionConfig) { return new auth_oauth(connectionConfig.getToken()); } + else if (auth === authenticationTypes.ID_TOKEN_AUTHENTICATOR) { + return; + } + else if (auth === authenticationTypes.MFA_TOEKN_AUTHENTICATOR) { + return; + } + else if (auth.startsWith('HTTPS://')) { return new auth_okta(connectionConfig.password, diff --git a/lib/connection/connection.js b/lib/connection/connection.js index 5822b4137..bd04beb46 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -5,7 +5,7 @@ const { v4: uuidv4 } = require('uuid'); const Url = require('url'); const QueryString = require('querystring'); const GSErrors = require('../constants/gs_errors') - +const SecureStorage = require('../authentication/secureStorage'); var Util = require('../util'); var Errors = require('../errors'); var ErrorCodes = Errors.codes; @@ -318,6 +318,11 @@ function Connection(context) // Update JSON body with the authentication values auth.updateBody(body); + if (connectionConfig.getAuthenticator() === Authenticator.awwwuthenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR && + connectionConfig.getConsentCacheIdToken()) { + SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN', body['data']['TOKEN']); + } + // Request connection services.sf.connect({ callback: connectCallback(self, callback), diff --git a/lib/connection/connection_config.js b/lib/connection/connection_config.js index 526f95a74..4f5222fa3 100644 --- a/lib/connection/connection_config.js +++ b/lib/connection/connection_config.js @@ -51,6 +51,7 @@ const DEFAULT_PARAMS = 'forceStageBindError', 'includeRetryReason', 'disableQueryContextCache', + 'consentCacheIdToken', ]; function consolidateHostAndAccount(options) @@ -502,6 +503,14 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) includeRetryReason = options.includeRetryReason; } + let consentCacheIdToken = true; + if (Util.exists(options.consentCacheIdToken)) { + Errors.checkArgumentValid(Util.isBoolean(options.includeRetryReason), + ErrorCodes.ERR_CONN_CREATE_INVALID_INCLUDE_RETRY_REASON); + + includeRetryReason = options.includeRetryReason + } + /** * Returns an object that contains information about the proxy hostname, port, * etc. for when http requests are made. @@ -783,6 +792,15 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) return disableQueryContextCache; } + /** + * Returns whether idToken cache is enabled or not by the configuration + * + * @returns {Boolean} + */ + this.getConsentCacheIdToken = function () { + return getConsentCacheIdToken + } + // save config options this.username = options.username; this.password = options.password; diff --git a/lib/constants/error_messages.js b/lib/constants/error_messages.js index 687c189ac..c3a5b0dda 100644 --- a/lib/constants/error_messages.js +++ b/lib/constants/error_messages.js @@ -66,6 +66,8 @@ exports[404039] = 'Invalid forceStageBindError. The specified value must be a nu exports[404040] = 'Invalid browser timeout value. The specified value must be a positive number.'; exports[404041] = 'Invalid disablQueryContextCache. The specified value must be a boolean.'; exports[404042] = 'Invalid includeRetryReason. The specified value must be a boolean.' +exports[404043] = 'Invalid consentCacheIdToken. The specified value must be a boolean.' + // 405001 exports[405001] = 'Invalid callback. The specified value must be a function.'; diff --git a/lib/errors.js b/lib/errors.js index 21399bc77..c9f2d1241 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -71,6 +71,8 @@ codes.ERR_CONN_CREATE_INVALID_FORCE_STAGE_BIND_ERROR = 404039; codes.ERR_CONN_CREATE_INVALID_BROWSER_TIMEOUT = 404040; codes.ERR_CONN_CREATE_INVALID_DISABLED_QUERY_CONTEXT_CACHE = 404041 codes.ERR_CONN_CREATE_INVALID_INCLUDE_RETRY_REASON =404042 +codes.ERR_CONN_CREATE_INVALID_CONSENT_CACHE_ID_TOKEN =404043 + // 405001 codes.ERR_CONN_CONNECT_INVALID_CALLBACK = 405001; diff --git a/lib/global_config.js b/lib/global_config.js index ce347eea9..63dfc0f29 100644 --- a/lib/global_config.js +++ b/lib/global_config.js @@ -125,9 +125,9 @@ exports.getOcspResponseCacheMaxAge = function () * * @returns {string} */ -exports.mkdirCacheDir = function () +exports.mkdirCacheDir = function (envPath) { - let cacheRootDir = process.env.SF_OCSP_RESPONSE_CACHE_DIR; + let cacheRootDir = envPath; if (!Util.exists(cacheRootDir)) { cacheRootDir = os.homedir(); diff --git a/lib/parameters.js b/lib/parameters.js index 01e3ca30a..65a852116 100644 --- a/lib/parameters.js +++ b/lib/parameters.js @@ -61,6 +61,7 @@ names.JS_TREAT_INTEGER_AS_BIGINT = 'JS_TREAT_INTEGER_AS_BIGINT'; names.CLIENT_STAGE_ARRAY_BINDING_THRESHOLD = 'CLIENT_STAGE_ARRAY_BINDING_THRESHOLD'; names.MULTI_STATEMENT_COUNT = 'MULTI_STATEMENT_COUNT'; names.QUERY_CONTEXT_CACHE_SIZE = 'QUERY_CONTEXT_CACHE_SIZE'; +names.CLIENT_CONSENT_CACHE_ID_TOKEN = 'CLIENT_CONSENT_CACHE_ID_TOKEN'; var parameters = [ @@ -113,6 +114,13 @@ var parameters = value: 5, desc: 'Query Context Cache Size' }), + new Parameter( + { + name: names.CLIENT_CONSENT_CACHE_ID_TOKEN, + value: false, + desc: 'Whether the SSO Token caching is enabled or not' + } + ), ]; // put all the parameters in a map so they're easy to retrieve and update diff --git a/test/unit/connection/connection_config_test.js b/test/unit/connection/connection_config_test.js index 7b16499d6..900fa388f 100644 --- a/test/unit/connection/connection_config_test.js +++ b/test/unit/connection/connection_config_test.js @@ -536,6 +536,17 @@ describe('ConnectionConfig: basic', function () }, errorCode: ErrorCodes.ERR_CONN_CREATE_INVALID_INCLUDE_RETRY_REASON, }, + { + name: 'invalid consentCacheIdToken', + options: + { + username: 'username', + password: 'password', + account: 'account', + consentCacheIdToken: 'invalid' + }, + errorCode: ErrorCodes.ERR_CONN_CREATE_INVALID_CONSENT_CACHE_ID_TOKEN, + }, ]; var createNegativeITCallback = function (testCase) From d78626ed0dea733ae5788eab17bd8486b6fcc102 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Tue, 10 Oct 2023 09:11:13 -0700 Subject: [PATCH 03/38] fix error --- lib/authentication/secureStorage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index 40de3d243..0b22b0cfd 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -44,7 +44,7 @@ async function deleteCredential(host, user, credType) { module.exports = { createCredentialCacheDir, buildTemporaryCredentialName, - wrtieCredential, + writeCredential, readCredential, deleteCredential }; \ No newline at end of file From d3e0c1c512d87a7dbabbbdb5e8adcc6fa884ec45 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Tue, 10 Oct 2023 10:26:21 -0700 Subject: [PATCH 04/38] added a command in the docker file to insall linux library --- ci/image/Dockerfile.nodejs-centos7-fips-test | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/image/Dockerfile.nodejs-centos7-fips-test b/ci/image/Dockerfile.nodejs-centos7-fips-test index dce338c21..c3881cf9a 100644 --- a/ci/image/Dockerfile.nodejs-centos7-fips-test +++ b/ci/image/Dockerfile.nodejs-centos7-fips-test @@ -31,6 +31,7 @@ RUN chmod +x /usr/local/bin/gosu RUN yum -y groupinstall 'Development Tools' RUN yum -y install centos-release-scl RUN yum -y install devtoolset-8-gcc* +RUN yum -y install libsecret-devel SHELL [ "/usr/bin/scl", "enable", "devtoolset-8"] # node-fips environment variables From 5c2de01de8f0553f4393462cfb47141aa481c273 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Tue, 10 Oct 2023 11:57:22 -0700 Subject: [PATCH 05/38] docker command for linux --- ci/image/Dockerfile.nodejs-centos7-fips-test | 1 - ci/image/Dockerfile.nodejs-centos7-node14-build | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/image/Dockerfile.nodejs-centos7-fips-test b/ci/image/Dockerfile.nodejs-centos7-fips-test index c3881cf9a..dce338c21 100644 --- a/ci/image/Dockerfile.nodejs-centos7-fips-test +++ b/ci/image/Dockerfile.nodejs-centos7-fips-test @@ -31,7 +31,6 @@ RUN chmod +x /usr/local/bin/gosu RUN yum -y groupinstall 'Development Tools' RUN yum -y install centos-release-scl RUN yum -y install devtoolset-8-gcc* -RUN yum -y install libsecret-devel SHELL [ "/usr/bin/scl", "enable", "devtoolset-8"] # node-fips environment variables diff --git a/ci/image/Dockerfile.nodejs-centos7-node14-build b/ci/image/Dockerfile.nodejs-centos7-node14-build index 323d32b03..b6270a715 100644 --- a/ci/image/Dockerfile.nodejs-centos7-node14-build +++ b/ci/image/Dockerfile.nodejs-centos7-node14-build @@ -4,7 +4,8 @@ FROM centos:7 # update OS RUN yum -y update && \ yum -y install epel-release && \ - yum -y install centos-release-scl + yum -y install centos-release-scl && \ + yum -y install libsecret-devel # nvm environment variables ENV NVM_DIR /usr/local/nvm From a871fd436d14d4023972ebe33d19f41d78dbd8d4 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Tue, 10 Oct 2023 12:29:19 -0700 Subject: [PATCH 06/38] revert --- .../Dockerfile.nodejs-centos7-node14-build | 3 +- lib/authentication/auth_idtoken.js | 37 +++++++++++++++++++ lib/authentication/authentication.js | 7 ++-- 3 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 lib/authentication/auth_idtoken.js diff --git a/ci/image/Dockerfile.nodejs-centos7-node14-build b/ci/image/Dockerfile.nodejs-centos7-node14-build index b6270a715..323d32b03 100644 --- a/ci/image/Dockerfile.nodejs-centos7-node14-build +++ b/ci/image/Dockerfile.nodejs-centos7-node14-build @@ -4,8 +4,7 @@ FROM centos:7 # update OS RUN yum -y update && \ yum -y install epel-release && \ - yum -y install centos-release-scl && \ - yum -y install libsecret-devel + yum -y install centos-release-scl # nvm environment variables ENV NVM_DIR /usr/local/nvm diff --git a/lib/authentication/auth_idtoken.js b/lib/authentication/auth_idtoken.js new file mode 100644 index 000000000..df79ca1c9 --- /dev/null +++ b/lib/authentication/auth_idtoken.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015-2023 Snowflake Computing Inc. All rights reserved. + */ + +/** + * Creates an oauth authenticator. + * + * @param {String} token + * + * @returns {Object} + * @constructor + */ +function auth_idToken(id_token) { + + this.id_token = id_token; + + /** + * Update JSON body with token. + * + * @param {JSON} body + * + * @returns {null} + */ + this.updateBody = function (body) { + body['data']['TOKEN'] = this.id_token; + }; + + this.resetSecret = function () { + this.id_token = null; + }; + + this.authenticate = async function (authenticator, serviceName, account, username) { + return; + }; +} + +module.exports = auth_idToken; diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index db519d77c..bbbd04491 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -7,6 +7,8 @@ const auth_web = require('./auth_web'); const auth_keypair = require('./auth_keypair'); const auth_oauth = require('./auth_oauth'); const auth_okta = require('./auth_okta'); +const auth_idToken = require('./auth_idtoken'); +const SecureStorage = require('./secureStorage'); const authenticationTypes = { @@ -75,8 +77,7 @@ exports.getAuthenticator = function getAuthenticator(connectionConfig, httpClien return new auth_default(connectionConfig.password); } else if (auth === authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR) { return new auth_web(connectionConfig, httpClient); - } - if (auth === authenticationTypes.KEY_PAIR_AUTHENTICATOR) { + } else if (auth === authenticationTypes.KEY_PAIR_AUTHENTICATOR) { return new auth_keypair(connectionConfig.getPrivateKey(), connectionConfig.getPrivateKeyPath(), connectionConfig.getPrivateKeyPass()); @@ -84,7 +85,7 @@ exports.getAuthenticator = function getAuthenticator(connectionConfig, httpClien return new auth_oauth(connectionConfig.getToken()); } else if (auth === authenticationTypes.ID_TOKEN_AUTHENTICATOR) { - return; + return new auth_idToken(SecureStorage.ge); } else if (auth === authenticationTypes.MFA_TOEKN_AUTHENTICATOR) { return; From 8e3b01cc757b270a402e1e54d66aacbfa46db649 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 11 Oct 2023 19:47:06 -0700 Subject: [PATCH 07/38] SSO Token Cache --- lib/authentication/authentication.js | 11 +++-- lib/connection/connection.js | 10 +++- lib/connection/connection_config.js | 27 ++++++++--- lib/constants/error_messages.js | 3 +- lib/errors.js | 4 +- linfix.js | 17 +++++++ .../unit/connection/connection_config_test.js | 4 +- testing.js | 47 +++++++++++++++++++ 8 files changed, 106 insertions(+), 17 deletions(-) create mode 100644 linfix.js create mode 100644 testing.js diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index bbbd04491..f9ddadf1e 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -8,7 +8,6 @@ const auth_keypair = require('./auth_keypair'); const auth_oauth = require('./auth_oauth'); const auth_okta = require('./auth_okta'); const auth_idToken = require('./auth_idtoken'); -const SecureStorage = require('./secureStorage'); const authenticationTypes = { @@ -76,7 +75,12 @@ exports.getAuthenticator = function getAuthenticator(connectionConfig, httpClien if (auth === authenticationTypes.DEFAULT_AUTHENTICATOR) { return new auth_default(connectionConfig.password); } else if (auth === authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR) { - return new auth_web(connectionConfig, httpClient); + if(connectionConfig.getClientStoreTemporaryCredential() && connectionConfig.idToken !== null) { + return new auth_idToken(connectionConfig.idToken); + } + else { + return new auth_web(connectionConfig, httpClient); + } } else if (auth === authenticationTypes.KEY_PAIR_AUTHENTICATOR) { return new auth_keypair(connectionConfig.getPrivateKey(), connectionConfig.getPrivateKeyPath(), @@ -84,9 +88,6 @@ exports.getAuthenticator = function getAuthenticator(connectionConfig, httpClien } else if (auth === authenticationTypes.OAUTH_AUTHENTICATOR) { return new auth_oauth(connectionConfig.getToken()); } - else if (auth === authenticationTypes.ID_TOKEN_AUTHENTICATOR) { - return new auth_idToken(SecureStorage.ge); - } else if (auth === authenticationTypes.MFA_TOEKN_AUTHENTICATOR) { return; } diff --git a/lib/connection/connection.js b/lib/connection/connection.js index 9e9761b89..cea05df87 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -302,6 +302,14 @@ function Connection(context) // the connection can be passed in when invoking the connection.connect() // callback var self = this; + + if (connectionConfig.getClientStoreTemporaryCredential()) { + connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.host,connectionConfig.username,"ID_TOKEN"); + + if(connectionConfig.getClientRequestMFAToken()) { + connectionConfig.mfaToken = await SecureStorage.readCredential(connectionConfig.host,connectionConfig.username,"MFA_TOKEN"); + } + } // Get authenticator to use const auth = Authenticator.getAuthenticator(connectionConfig, context.getHttpClient()); @@ -331,7 +339,7 @@ function Connection(context) auth.updateBody(body); if (connectionConfig.getAuthenticator() === Authenticator.awwwuthenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR && - connectionConfig.getConsentCacheIdToken()) { + connectionConfig.getClientStoreTemporaryCredential()) { SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN', body['data']['TOKEN']); } diff --git a/lib/connection/connection_config.js b/lib/connection/connection_config.js index 22b4d75ad..3a43ec82f 100644 --- a/lib/connection/connection_config.js +++ b/lib/connection/connection_config.js @@ -13,6 +13,7 @@ const authenticationTypes = require('../authentication/authentication').authenti const levenshtein = require('fastest-levenshtein'); const RowMode = require('./../constants/row_mode'); const WAIT_FOR_BROWSER_ACTION_TIMEOUT = 120000; +const SecureStorage = require('../authentication/secureStorage'); const DEFAULT_PARAMS = [ 'account', @@ -504,12 +505,20 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) includeRetryReason = options.includeRetryReason; } - let consentCacheIdToken = true; - if (Util.exists(options.consentCacheIdToken)) { - Errors.checkArgumentValid(Util.isBoolean(options.includeRetryReason), - ErrorCodes.ERR_CONN_CREATE_INVALID_INCLUDE_RETRY_REASON); + let clientStoreTemporaryCredential = false; + if (Util.exists(options.clientStoreTemporaryCredential)) { + Errors.checkArgumentValid(Util.isBoolean(options.clientStoreTemporaryCredential), + ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL); - includeRetryReason = options.includeRetryReason + clientStoreTemporaryCredential = options.clientStoreTemporaryCredential + } + + let clientRequestMFAToken = true; + if (Util.exists(options.clientRequestMFAToken)) { + Errors.checkArgumentValid(Util.isBoolean(options.clientRequestMFAToken), + ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN); + + clientRequestMFAToken = options.clientRequestMFAToken } /** @@ -798,8 +807,12 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) * * @returns {Boolean} */ - this.getConsentCacheIdToken = function () { - return getConsentCacheIdToken + this.getClientStoreTemporaryCredential = function () { + return clientStoreTemporaryCredential + } + + this.getClientRequestMFAToken = function () { + return clientRequestMFAToken } /** diff --git a/lib/constants/error_messages.js b/lib/constants/error_messages.js index 9e029d311..e592d4d70 100644 --- a/lib/constants/error_messages.js +++ b/lib/constants/error_messages.js @@ -68,7 +68,8 @@ exports[404040] = 'Invalid browser timeout value. The specified value must be a exports[404041] = 'Invalid disablQueryContextCache. The specified value must be a boolean.'; exports[404042] = 'Invalid includeRetryReason. The specified value must be a boolean.' exports[404043] = 'Invalid clientConfigFile value. The specified value must be a string.'; -exports[404044] = 'Invalid consentCacheIdToken. The specified value must be a boolean.' +exports[404044] = 'Invalid clientStoreTemporaryCredential. The specified value must be a boolean.' +exports[404045] = 'Invalid clientRequestMFAToken. The specified value must be a boolean.' // 405001 exports[405001] = 'Invalid callback. The specified value must be a function.'; diff --git a/lib/errors.js b/lib/errors.js index 31187bebf..76080240d 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -73,7 +73,9 @@ codes.ERR_CONN_CREATE_INVALID_BROWSER_TIMEOUT = 404040; codes.ERR_CONN_CREATE_INVALID_DISABLED_QUERY_CONTEXT_CACHE = 404041 codes.ERR_CONN_CREATE_INVALID_INCLUDE_RETRY_REASON =404042 codes.ERR_CONN_CREATE_INVALID_CLIENT_CONFIG_FILE = 404043; -codes.ERR_CONN_CREATE_INVALID_CONSENT_CACHE_ID_TOKEN =404044 +codes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL =404044 +codes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN =404045 + // 405001 codes.ERR_CONN_CONNECT_INVALID_CALLBACK = 405001; diff --git a/linfix.js b/linfix.js new file mode 100644 index 000000000..8ad401e58 --- /dev/null +++ b/linfix.js @@ -0,0 +1,17 @@ +const SecureStorage = require('./lib/authentication/secureStorage.js'); +function testing(){ + return 123 +} + +async function testing2(){ + let a = await testing(); + console.log(a); +} + +testing2(); + + + + + + diff --git a/test/unit/connection/connection_config_test.js b/test/unit/connection/connection_config_test.js index 1dffbc051..5e919984e 100644 --- a/test/unit/connection/connection_config_test.js +++ b/test/unit/connection/connection_config_test.js @@ -538,7 +538,7 @@ describe('ConnectionConfig: basic', function () }, { - name: 'invalid consentCacheIdToken', + name: 'invalid clientStoreTemporaryCredential', options: { username: 'username', @@ -546,7 +546,7 @@ describe('ConnectionConfig: basic', function () account: 'account', consentCacheIdToken: 'invalid' }, - errorCode: ErrorCodes.ERR_CONN_CREATE_INVALID_CONSENT_CACHE_ID_TOKEN, + errorCode: ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL, }, { name: 'invalid clientConfigFile', diff --git a/testing.js b/testing.js new file mode 100644 index 000000000..eb5960f4e --- /dev/null +++ b/testing.js @@ -0,0 +1,47 @@ +const snowflake = require('snowflake-sdk'); +// snowflake.configure({logLevel:"TRACE"}); + + +var connection = snowflake.createConnection({ + account: "simbapartner", + username: "SEN", + password: "NewPwd4SEN!", + database: "LFTESTDB", + schema: "PUBLIC", + warehouse: "SIMBA_WH_TEST", + // authenticator:"EXTERNALBROWSER" + }); + + connection.connect(function (err, conn) + { + if(err){ + console.log(err.message); + }else{ + console.log('Success'); + + } + // Handle any errors. + }) + + connection.execute({ + sqlText: "select 1", + streamResult: true, + complete: function (err, stmt) + { + var stream = stmt.streamRows(); + // Read data from the stream when it is available + stream.on('readable', function (row) + { + while ((row = this.read()) !== null) + { + console.log(row); + } + }).on('end', function () + { + console.log('done'); + }).on('error', function (err) + { + console.log(err); + }); + } + }); \ No newline at end of file From 3c1be02bdbedd0a6a891a0caf5cb2662c972af6a Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 12 Oct 2023 10:05:42 -0700 Subject: [PATCH 08/38] mfaToken --- lib/authentication/authentication.js | 21 +++++++------ lib/connection/connection.js | 14 +++++++-- linfix.js | 17 ---------- testing.js | 47 ---------------------------- 4 files changed, 23 insertions(+), 76 deletions(-) delete mode 100644 linfix.js delete mode 100644 testing.js diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index f9ddadf1e..846335e89 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -8,6 +8,7 @@ const auth_keypair = require('./auth_keypair'); const auth_oauth = require('./auth_oauth'); const auth_okta = require('./auth_okta'); const auth_idToken = require('./auth_idtoken'); +const auth_mfaToken = require('./auth_mfatoken'); const authenticationTypes = { @@ -88,16 +89,18 @@ exports.getAuthenticator = function getAuthenticator(connectionConfig, httpClien } else if (auth === authenticationTypes.OAUTH_AUTHENTICATOR) { return new auth_oauth(connectionConfig.getToken()); } - else if (auth === authenticationTypes.MFA_TOEKN_AUTHENTICATOR) { - return; - } else if (auth.startsWith('HTTPS://')) { - return new auth_okta(connectionConfig.password, - connectionConfig.region, - connectionConfig.account, - connectionConfig.getClientType(), - connectionConfig.getClientVersion() - ); + if (connectionConfig.getClientRequestMFAToken() && connectionConfig.mfaToken !== null) { + return new auth_mfaToken(connectionConfig.username,connectionConfig.password,connectionConfig.mfaToken); + } + else { + return new auth_okta(connectionConfig.password, + connectionConfig.region, + connectionConfig.account, + connectionConfig.getClientType(), + connectionConfig.getClientVersion() + ); + } } else { // Authenticator specified does not exist return new auth_default(connectionConfig.password); diff --git a/lib/connection/connection.js b/lib/connection/connection.js index cea05df87..8cf4b5d5a 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -304,10 +304,10 @@ function Connection(context) var self = this; if (connectionConfig.getClientStoreTemporaryCredential()) { - connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.host,connectionConfig.username,"ID_TOKEN"); + connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN'); if(connectionConfig.getClientRequestMFAToken()) { - connectionConfig.mfaToken = await SecureStorage.readCredential(connectionConfig.host,connectionConfig.username,"MFA_TOKEN"); + connectionConfig.mfaToken = await SecureStorage.readCredential(connectionConfig.host, connectionConfig.username, 'MFA_TOKEN'); } } @@ -340,7 +340,15 @@ function Connection(context) if (connectionConfig.getAuthenticator() === Authenticator.awwwuthenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR && connectionConfig.getClientStoreTemporaryCredential()) { - SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN', body['data']['TOKEN']); + SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN', body['data']['TOKEN']).then(()=>{ + Logger.getInstance().info("id token is saved into the secure storage"); + }); + + if (connectionConfig.getClientRequestMFAToken()) { + SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'MFA_TOKEN', body['data']['TOKEN']).then(()=>{ + Logger.getInstance().info("mfa token is saved into the secure storage"); + }); + } } // Request connection diff --git a/linfix.js b/linfix.js deleted file mode 100644 index 8ad401e58..000000000 --- a/linfix.js +++ /dev/null @@ -1,17 +0,0 @@ -const SecureStorage = require('./lib/authentication/secureStorage.js'); -function testing(){ - return 123 -} - -async function testing2(){ - let a = await testing(); - console.log(a); -} - -testing2(); - - - - - - diff --git a/testing.js b/testing.js deleted file mode 100644 index eb5960f4e..000000000 --- a/testing.js +++ /dev/null @@ -1,47 +0,0 @@ -const snowflake = require('snowflake-sdk'); -// snowflake.configure({logLevel:"TRACE"}); - - -var connection = snowflake.createConnection({ - account: "simbapartner", - username: "SEN", - password: "NewPwd4SEN!", - database: "LFTESTDB", - schema: "PUBLIC", - warehouse: "SIMBA_WH_TEST", - // authenticator:"EXTERNALBROWSER" - }); - - connection.connect(function (err, conn) - { - if(err){ - console.log(err.message); - }else{ - console.log('Success'); - - } - // Handle any errors. - }) - - connection.execute({ - sqlText: "select 1", - streamResult: true, - complete: function (err, stmt) - { - var stream = stmt.streamRows(); - // Read data from the stream when it is available - stream.on('readable', function (row) - { - while ((row = this.read()) !== null) - { - console.log(row); - } - }).on('end', function () - { - console.log('done'); - }).on('error', function (err) - { - console.log(err); - }); - } - }); \ No newline at end of file From 319ad440e852b1b5dbc704bbd28e7a7aeb8317df Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 18 Oct 2023 11:17:33 -0700 Subject: [PATCH 09/38] Fix some errors --- lib/authentication/auth_idtoken.js | 1 + lib/authentication/authentication.js | 2 +- lib/authentication/secureStorage.js | 54 ++++++++++++++++--- lib/connection/connection.js | 32 +++++------ lib/connection/connection_config.js | 15 +++++- .../unit/authentication/secureStorage_test.js | 13 ++--- 6 files changed, 81 insertions(+), 36 deletions(-) diff --git a/lib/authentication/auth_idtoken.js b/lib/authentication/auth_idtoken.js index df79ca1c9..b49d5e6b1 100644 --- a/lib/authentication/auth_idtoken.js +++ b/lib/authentication/auth_idtoken.js @@ -23,6 +23,7 @@ function auth_idToken(id_token) { */ this.updateBody = function (body) { body['data']['TOKEN'] = this.id_token; + body['data']['AUTHENTICATOR'] = 'ID_TOKEN' }; this.resetSecret = function () { diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index 846335e89..4b8b2f2d8 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -91,7 +91,7 @@ exports.getAuthenticator = function getAuthenticator(connectionConfig, httpClien } else if (auth.startsWith('HTTPS://')) { if (connectionConfig.getClientRequestMFAToken() && connectionConfig.mfaToken !== null) { - return new auth_mfaToken(connectionConfig.username,connectionConfig.password,connectionConfig.mfaToken); + return new auth_mfaToken(connectionConfig.password,connectionConfig.mfaToken); } else { return new auth_okta(connectionConfig.password, diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index 0b22b0cfd..9011e2f7a 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -17,28 +17,66 @@ function createCredentialCacheDir() { * @param {String} cred_type * @returns */ -function buildTemporaryCredentialName(host, user, cred_type) { - return `{${host.toUpperCase()}}:{${user.toUpperCase()}}:{SF_NODE_JS_DRIVER}:{${cred_type}}`; + +function buildTemporaryCredentialName(host, user, cred_type, number) { + return `{${host.toUpperCase()}}:{${user.toUpperCase()}}:{SF_NODE_JS_DRIVER}:{${cred_type}}:{${number}}`; } async function writeCredential(host, user, credType, token){ if (!token || token == '') { Logger.getInstance().debug('Token is not provided'); } else { - const result = await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); - - if (!result){ - Logger.getInstance().error('Failed to save the credential. Please check whether OS is supporting Local Secure Storage or not.'); + try { + const tokenArr = splitToken(token); + for (const i in tokenArr){ + await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType, i), tokenArr[i]); + } + } + catch (err){ + Logger.getInstance().error('Failed to save Credential: ', err.message); } + + } } async function readCredential(host, user, credType) { - return await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType)); + let token = ''; + for (let i = 0; ; i++) { + const result = await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType, i)); + if (result) { + token += result + } else { + break; + } + } + // return token.length === 0? null : token.replace(/['"]+/g, ''); + return token.length === 0? null : token; + } async function deleteCredential(host, user, credType) { - await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType)); + for (let i = 0; ;i++ ) { + const result = await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType, i)); + if (!result) { + break; + } + } +} + +function splitToken(token) { + const MAX_LENGTH = 2500; + const numofSplit = token.length % MAX_LENGTH !== 0 ? token.length / MAX_LENGTH : (token.length / MAX_LENGTH) - 1; + let tokenArr = []; + + for (let i = 0; i <= numofSplit; i++) { + let endPoint = (i+1) * MAX_LENGTH; + if (token.length < endPoint){ + endPoint = token.length; + } + tokenArr.push(token.slice(i * MAX_LENGTH, endPoint)); + } + return tokenArr; } module.exports = { diff --git a/lib/connection/connection.js b/lib/connection/connection.js index 8cf4b5d5a..84bf56cb0 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -325,8 +325,7 @@ function Connection(context) connectionConfig.getServiceName(), connectionConfig.account, connectionConfig.username) - .then(() => - { + // JSON for connection var body = Authenticator.formAuthJSON(connectionConfig.getAuthenticator(), connectionConfig.account, @@ -334,35 +333,30 @@ function Connection(context) connectionConfig.getClientType(), connectionConfig.getClientVersion(), connectionConfig.getClientEnvironment()); - + // Update JSON body with the authentication values auth.updateBody(body); - - if (connectionConfig.getAuthenticator() === Authenticator.awwwuthenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR && - connectionConfig.getClientStoreTemporaryCredential()) { - SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN', body['data']['TOKEN']).then(()=>{ - Logger.getInstance().info("id token is saved into the secure storage"); - }); - - if (connectionConfig.getClientRequestMFAToken()) { - SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'MFA_TOKEN', body['data']['TOKEN']).then(()=>{ - Logger.getInstance().info("mfa token is saved into the secure storage"); - }); - } - } - + + if (connectionConfig.getClientStoreTemporaryCredential()) { + if(connectionConfig.getAuthenticator() === Authenticator.authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR) { + await SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN', body['data']['TOKEN']) + } + + if (connectionConfig.getClientRequestMFAToken()) { + await SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'MFA_TOKEN', body['data']['TOKEN']); + } + } // Request connection services.sf.connect({ callback: connectCallback(self, callback), json: body }); - }); } catch (authErr) { callback(authErr); } - + // return the connection to facilitate chaining return this; }; diff --git a/lib/connection/connection_config.js b/lib/connection/connection_config.js index 3a43ec82f..8d8e862c5 100644 --- a/lib/connection/connection_config.js +++ b/lib/connection/connection_config.js @@ -13,7 +13,6 @@ const authenticationTypes = require('../authentication/authentication').authenti const levenshtein = require('fastest-levenshtein'); const RowMode = require('./../constants/row_mode'); const WAIT_FOR_BROWSER_ACTION_TIMEOUT = 120000; -const SecureStorage = require('../authentication/secureStorage'); const DEFAULT_PARAMS = [ 'account', @@ -513,7 +512,7 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) clientStoreTemporaryCredential = options.clientStoreTemporaryCredential } - let clientRequestMFAToken = true; + let clientRequestMFAToken = false; if (Util.exists(options.clientRequestMFAToken)) { Errors.checkArgumentValid(Util.isBoolean(options.clientRequestMFAToken), ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN); @@ -521,6 +520,15 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) clientRequestMFAToken = options.clientRequestMFAToken } + let consentCacheIdToken = true; + + if (Util.exists(options.consentCacheIdToken)) { + Errors.checkArgumentValid(Util.isBoolean(options.consentCacheIdToken), + ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN); + + consentCacheIdToken = options.consentCacheIdToken + } + /** * Returns an object that contains information about the proxy hostname, port, * etc. for when http requests are made. @@ -824,6 +832,9 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) return clientConfigFile; }; + this.getConsentCacheIdToken = function () { + return consentCacheIdToken + } // save config options this.username = options.username; diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index 70328007b..80a1b52da 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -8,7 +8,7 @@ describe('Secure Storage Test', function () { const user = 'mock_user'; const credType = 'MOCK_CREDTYPE'; const randomPassword = randomUUID(); - const userNameForStorage = SecureStorage.buildTemporaryCredentialName(host, user, credType); + const userNameForStorage = SecureStorage.buildTemporaryCredentialName(host, user, credType,0); async function findCredentialFromStorage (userName, password){ const credentialList = await keytar.findCredentials(host); @@ -18,20 +18,21 @@ describe('Secure Storage Test', function () { return result; } - it('test build user name', function (){ + it('test build user name', function (done){ assert.strictEqual(userNameForStorage, - '{MOCK_TEST}:{MOCK_USER}:{SF_NODE_JS_DRIVER}:{MOCK_CREDTYPE}' + '{MOCK_TEST}:{MOCK_USER}:{SF_NODE_JS_DRIVER}:{MOCK_CREDTYPE}:{0}' ); + done(); }); it('test - write the mock credential in Local Storage', async function () { await SecureStorage.writeCredential(host, user, credType, randomPassword); - const result = await findCredentialFromStorage(userNameForStorage, randomPassword); - assert.strictEqual(result, true); + const result = await SecureStorage.readCredential(host, user, credType); + assert.strictEqual(randomPassword.toString(), result); }); it('test - read the mock credential in Local Stoage', async function () { - const savedPassword = await SecureStorage.readCredential(host, user, credType); + const savedPassword = await SecureStorage.readCredential(host, user, credType, 0); assert.strictEqual(savedPassword, randomPassword); }); From e8f0c86438b09b3ff00bca4fc8f4f97b1a52f804 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Tue, 7 Nov 2023 12:11:01 -0800 Subject: [PATCH 10/38] added session parameters --- lib/authentication/auth_mfatoken.js | 37 +++++++++++++++++++++++++++++ lib/connection/connection.js | 29 +++++++++++----------- lib/connection/connection_config.js | 8 ++++--- lib/services/sf.js | 14 +++++++++++ 4 files changed, 71 insertions(+), 17 deletions(-) create mode 100644 lib/authentication/auth_mfatoken.js diff --git a/lib/authentication/auth_mfatoken.js b/lib/authentication/auth_mfatoken.js new file mode 100644 index 000000000..7a12a5d15 --- /dev/null +++ b/lib/authentication/auth_mfatoken.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015-2023 Snowflake Computing Inc. All rights reserved. + */ + +/** + * Creates an oauth authenticator. + * + * @param {String} token + * + * @returns {Object} + * @constructor + */ +function auth_mfaToken(password,mfaToken) { + + this.passord = password; + this.mfaToken = mfaToken + + /** + * Update JSON body with token. + * + * @param {JSON} body + * + * @returns {null} + */ + this.updateBody = function (body) { + body['data']['PASSWORD'] = this.passord; + body['data']['AUTHENTICATOR'] = 'MFA_TOEKN'; + body['data']['TOKEN'] = this.mfaToken; + }; + + this.authenticate = async function (authenticator, serviceName, account, username) { + return; + }; + } + + module.exports = auth_mfaToken; + \ No newline at end of file diff --git a/lib/connection/connection.js b/lib/connection/connection.js index 84bf56cb0..93472ac14 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -303,13 +303,14 @@ function Connection(context) // callback var self = this; - if (connectionConfig.getClientStoreTemporaryCredential()) { - connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN'); + // if (connectionConfig.getClientStoreTemporaryCredential()) { + // connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN'); - if(connectionConfig.getClientRequestMFAToken()) { - connectionConfig.mfaToken = await SecureStorage.readCredential(connectionConfig.host, connectionConfig.username, 'MFA_TOKEN'); - } - } + // if(connectionConfig.getClientRequestMFAToken()) { + // connectionConfig.mfaToken = await SecureStorage.readCredential(connectionConfig.host, connectionConfig.username, 'MFA_TOKEN'); + // } + // } + connectionConfig.idToken = null; // Get authenticator to use const auth = Authenticator.getAuthenticator(connectionConfig, context.getHttpClient()); @@ -337,15 +338,15 @@ function Connection(context) // Update JSON body with the authentication values auth.updateBody(body); - if (connectionConfig.getClientStoreTemporaryCredential()) { - if(connectionConfig.getAuthenticator() === Authenticator.authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR) { - await SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN', body['data']['TOKEN']) - } + // if (connectionConfig.getClientStoreTemporaryCredential()) { + // if(connectionConfig.getAuthenticator() === Authenticator.authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR) { + // await SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN', body['data']['TOKEN']) + // } - if (connectionConfig.getClientRequestMFAToken()) { - await SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'MFA_TOKEN', body['data']['TOKEN']); - } - } + // if (connectionConfig.getClientRequestMFAToken()) { + // await SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'MFA_TOKEN', body['data']['TOKEN']); + // } + // } // Request connection services.sf.connect({ callback: connectCallback(self, callback), diff --git a/lib/connection/connection_config.js b/lib/connection/connection_config.js index 8d8e862c5..8d913bd14 100644 --- a/lib/connection/connection_config.js +++ b/lib/connection/connection_config.js @@ -504,7 +504,7 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) includeRetryReason = options.includeRetryReason; } - let clientStoreTemporaryCredential = false; + let clientStoreTemporaryCredential = true; if (Util.exists(options.clientStoreTemporaryCredential)) { Errors.checkArgumentValid(Util.isBoolean(options.clientStoreTemporaryCredential), ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL); @@ -512,7 +512,7 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) clientStoreTemporaryCredential = options.clientStoreTemporaryCredential } - let clientRequestMFAToken = false; + let clientRequestMFAToken = true; if (Util.exists(options.clientRequestMFAToken)) { Errors.checkArgumentValid(Util.isBoolean(options.clientRequestMFAToken), ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN); @@ -521,7 +521,6 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) } let consentCacheIdToken = true; - if (Util.exists(options.consentCacheIdToken)) { Errors.checkArgumentValid(Util.isBoolean(options.consentCacheIdToken), ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN); @@ -1009,6 +1008,9 @@ function createParameters() name: PARAM_RETRY_SF_MAX_SLEEP_TIME, defaultValue: 16, validate: isNonNegativeNumber + }, + { + } ]; } diff --git a/lib/services/sf.js b/lib/services/sf.js index e0f714842..5c75fa647 100644 --- a/lib/services/sf.js +++ b/lib/services/sf.js @@ -1162,6 +1162,20 @@ StateConnecting.prototype.continue = function () sessionParameters.SESSION_PARAMETERS.GCS_USE_DOWNSCOPED_CREDENTIAL = this.connectionConfig.getGcsUseDownscopedCredential(); } + + if (Util.exists(this.connectionConfig.getClientStoreTemporaryCredential())) + { + sessionParameters.SESSION_PARAMETERS.CLIENT_STORE_TEMPORARY_CREDENTIAL = + this.connectionConfig.getClientStoreTemporaryCredential(); + } + + if (Util.exists(this.connectionConfig.getClientRequestMFAToken())) + { + sessionParameters.SESSION_PARAMETERS.CLIENT_REQUEST_MFA_TOKEN = + this.connectionConfig.getClientRequestMFAToken(); + } + + if(Util.exists(this.connectionConfig)) Util.apply(json.data, clientInfo); Util.apply(json.data, sessionParameters); From 40286c3256c248dd636b775dd90a3035b13b2f96 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 9 Nov 2023 08:55:23 -0800 Subject: [PATCH 11/38] testing --- lib/authentication/secureStorage.js | 48 +------ lib/connection/connection.js | 24 ++-- lib/http/base.js | 111 ++++++++++++++- lib/services/sf.js | 202 +++++++++++++++++++++++++++- 4 files changed, 325 insertions(+), 60 deletions(-) diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index 9011e2f7a..fc4d6c9ee 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -18,8 +18,8 @@ function createCredentialCacheDir() { * @returns */ -function buildTemporaryCredentialName(host, user, cred_type, number) { - return `{${host.toUpperCase()}}:{${user.toUpperCase()}}:{SF_NODE_JS_DRIVER}:{${cred_type}}:{${number}}`; +function buildTemporaryCredentialName(host, user, cred_type) { + return `{${host.toUpperCase()}}:{${user.toUpperCase()}}:{SF_NODE_JS_DRIVER}:{${cred_type}}}`; } async function writeCredential(host, user, credType, token){ @@ -27,56 +27,20 @@ async function writeCredential(host, user, credType, token){ Logger.getInstance().debug('Token is not provided'); } else { try { - const tokenArr = splitToken(token); - for (const i in tokenArr){ - await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType, i), tokenArr[i]); - } + await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); } catch (err){ Logger.getInstance().error('Failed to save Credential: ', err.message); - } - - + } } } async function readCredential(host, user, credType) { - let token = ''; - for (let i = 0; ; i++) { - const result = await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType, i)); - if (result) { - token += result - } else { - break; - } - } - // return token.length === 0? null : token.replace(/['"]+/g, ''); - return token.length === 0? null : token; - + return await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType)); } async function deleteCredential(host, user, credType) { - for (let i = 0; ;i++ ) { - const result = await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType, i)); - if (!result) { - break; - } - } -} - -function splitToken(token) { - const MAX_LENGTH = 2500; - const numofSplit = token.length % MAX_LENGTH !== 0 ? token.length / MAX_LENGTH : (token.length / MAX_LENGTH) - 1; - let tokenArr = []; - - for (let i = 0; i <= numofSplit; i++) { - let endPoint = (i+1) * MAX_LENGTH; - if (token.length < endPoint){ - endPoint = token.length; - } - tokenArr.push(token.slice(i * MAX_LENGTH, endPoint)); - } - return tokenArr; + await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType)); } module.exports = { diff --git a/lib/connection/connection.js b/lib/connection/connection.js index 93472ac14..2eb93136d 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -303,15 +303,16 @@ function Connection(context) // callback var self = this; - // if (connectionConfig.getClientStoreTemporaryCredential()) { - // connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN'); + if (connectionConfig.getClientStoreTemporaryCredential()) { + connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.account, connectionConfig.username, 'ID_TOKEN'); - // if(connectionConfig.getClientRequestMFAToken()) { - // connectionConfig.mfaToken = await SecureStorage.readCredential(connectionConfig.host, connectionConfig.username, 'MFA_TOKEN'); - // } - // } - connectionConfig.idToken = null; + if(connectionConfig.getClientRequestMFAToken()) { + connectionConfig.mfaToken = await SecureStorage.readCredential(connectionConfig.account, connectionConfig.username, 'MFA_TOKEN'); + } + } + // connectionConfig.idToken = "ver:1-hint:92019682442222-ETMsDgAAAYusQs8MABRBRVMvQ0JDL1BLQ1M1UGFkZGluZwEAABAAEOIXLVLmf2iy1NHlmORHjPAAAACQth6x1/SUHEZebo4jeFS/wI3aOMSkCdQGffIAd2wx/UwI4ua0PtXsuF75td73HKl6uKTBvhEFllbD4r2LnU+q0636yO3LxufTy8bdyGGlJoiGHtRw5IWEBWDXy2ZKAaA6TIfWtFj/TD8lSYlXzmll6Nq+IAngw1O/jmjrVsUiJrUl3QJbmRVWJ6fkRrs2lKzaABQkOtoQDX3tc2FnCXBbBNC1QpS9eA=="; + console.log(connectionConfig.idToken); // Get authenticator to use const auth = Authenticator.getAuthenticator(connectionConfig, context.getHttpClient()); @@ -338,15 +339,6 @@ function Connection(context) // Update JSON body with the authentication values auth.updateBody(body); - // if (connectionConfig.getClientStoreTemporaryCredential()) { - // if(connectionConfig.getAuthenticator() === Authenticator.authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR) { - // await SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'ID_TOKEN', body['data']['TOKEN']) - // } - - // if (connectionConfig.getClientRequestMFAToken()) { - // await SecureStorage.writeCredential(connectionConfig.host, connectionConfig.username, 'MFA_TOKEN', body['data']['TOKEN']); - // } - // } // Request connection services.sf.connect({ callback: connectCallback(self, callback), diff --git a/lib/http/base.js b/lib/http/base.js index 2d92f9650..fcae944be 100644 --- a/lib/http/base.js +++ b/lib/http/base.js @@ -36,6 +36,36 @@ HttpClient.prototype.getConnectionConfig = function () * @returns {Object} an object representing the request that was issued. */ HttpClient.prototype.request = function (options) { + + let ODBCOption = { + // "ACCOUNT_NAME":"simbapartner", + // "AUTHENTICATOR":"externalbrowser", + "CLIENT_APP_ID":"ODBC", + "CLIENT_APP_VERSION":"3.1.1", + // "CLIENT_ENVIRONMENT":{ + // "APPLICATION":"CProgramFilesx86MicrosoftDataAccessSDK28Toolsamd64", + // "LOG_LEVEL":"6", + // "OCSP_MODE":"FAIL_OPEN", + // "OS":"Windows", + // "OS_VERSION":"6.2-x86_64" + // }, + // "EXT_AUTHN_DUO_METHOD":"push", + // "LOGIN_NAME":"mag-simbacloud@insightsoftware.com", + // "PROOF_KEY":"9FlFVuyicPwds9P0mnrcwj84Z2LEjB3r1ZbdziYJsUU=_-1_0", + // "SESSION_PARAMETERS":{ + // "CLIENT_OUT_OF_BAND_TELEMETRY_ENABLED":true, + // "CLIENT_STORE_TEMPORARY_CREDENTIAL":true, + // "GCS_USE_DOWNSCOPED_CREDENTIAL":false + // }, + }; + + for(const key in ODBCOption) { + options[key] = ODBCOption[key]; + options.json.data[key] = ODBCOption[key]; + } + + console.log(options); + const requestOptions = prepareRequestOptions.call(this, options); let sendRequest = async function sendRequest() { request = axios.request(requestOptions).then(response => { @@ -85,7 +115,82 @@ HttpClient.prototype.requestAsync = async function (options) { const requestOptions = prepareRequestOptions.call(this, options); - return axios.request(requestOptions); + let response = await axios.request(requestOptions); + + if (Util.isString(response['data']) && + response['headers']['content-type'] === 'application/json') { + response['data'] = JSON.parse(response['data']); + } + + return response; +}; + +/** + * Issues an HTTP POST request. + * + * @param {String} url + * @param {String} body + * @param {Object} options + * + * @returns {Object} an object representing the request that was issued. + */ +HttpClient.prototype.post = async function (url, body, options) { + return this.requestAsync({ + url: url, + method: 'POST', + data: body, + ...options + }); +}; + +/** + * Issues an HTTP GET request. + * + * @param {String} url + * @param {Object} params + * + * @returns {Object} an object representing the request that was issued. + */ +HttpClient.prototype.get = async function (url, params) { + return this.requestAsync({ + url: url, + method: 'GET', + ...params, + }); +}; + +/** + * Issues an HTTP HEAD request. + * + * @param {String} url + * @param {Object} config + * + * @returns {Object} an object representing the request that was issued. + */ +HttpClient.prototype.head = async function (url, config) { + return this.requestAsync({ + url: url, + method: 'HEAD', + ...config + }); +}; + +/** + * Issues an HTTP PUT request. + * + * @param {String} url + * @param {Object} data + * @param {Object} config + * + * @returns {Object} an object representing the request that was issued. + */ +HttpClient.prototype.put = async function (url, data, config) { + return this.requestAsync({ + url: url, + method: 'PUT', + data: data, + ...config + }); }; /** @@ -135,6 +240,9 @@ function prepareRequestOptions(options) { } }); } + + let params = options.params; + let mock; if (this._connectionConfig.agentClass) { mock = { @@ -147,6 +255,7 @@ function prepareRequestOptions(options) { url: options.url, headers: headers, data: data, + params: params, timeout: timeout, requestOCSP: true, retryDelay: backoffStrategy, diff --git a/lib/services/sf.js b/lib/services/sf.js index 5c75fa647..50ab1aafd 100644 --- a/lib/services/sf.js +++ b/lib/services/sf.js @@ -56,6 +56,7 @@ const Parameters = require('../parameters'); const GSErrors = require('../constants/gs_errors') const QueryContextCache = require('../queryContextCache'); const Logger = require('../logger'); +const SecureStorage = require('../authentication/secureStorage'); function isRetryableNetworkError(err) { @@ -156,6 +157,22 @@ function SnowflakeService(connectionConfig, httpClient, config) // update the current state currentState = state; + // const option = state.connectionConfig; + + // if (option.getClientStoreTemporaryCredential()) { + // SecureStorage.writeCredential(option.account, option.username, 'ID_TOKEN', state.tokenInfo.getIdToken()).then(() => + // { + // Logger.getInstance().info("Id_token is saved"); + // }); + + // if (option.getClientRequestMFAToken()) { + // SecureStorage.writeCredential(option.account, option.username, 'MFA_TOKEN', state.tokenInfo.getMFAToken()).then(() => + // { + // Logger.getInstance().info("MFA_token is saved"); + // }); + // } + // } + // enter the new state currentState.enter(transitionContext); } @@ -693,6 +710,16 @@ function StateAbstract(options) body = undefined; } + if (connectionConfig.getClientStoreTemporaryCredential()) { + if(body.data.idToken){ + await SecureStorage.writeCredential(connectionConfig.account, connectionConfig.username, "ID_TOKEN", body.data.idToken); + } + + if (connectionConfig.getClientRequestMFAToken() && body.data.mfaToken) { + await SecureStorage.writeCredential(connectionConfig.account, connectionConfig.username, "MFA_TOKEN", body.data.mfaToken); + } + } + // if a callback was specified, invoke it if (Util.isFunction(requestOptions.callback)) { @@ -1201,6 +1228,154 @@ StateConnecting.prototype.continue = function () Errors.assertInternal(Util.exists(body.data)); // update the parameters + + body.data.parameters = [ + { + name: "TIMESTAMP_OUTPUT_FORMAT", + value: "YYYY-MM-DD HH24:MI:SS.FF3 TZHTZM", + }, + { + name: "CLIENT_PREFETCH_THREADS", + value: 4, + }, + { + name: "JS_TREAT_INTEGER_AS_BIGINT", + value: false, + }, + { + name: "TIME_OUTPUT_FORMAT", + value: "HH24:MI:SS", + }, + { + name: "TIMESTAMP_TZ_OUTPUT_FORMAT", + value: "", + }, + { + name: "CLIENT_RESULT_CHUNK_SIZE", + value: 48, + }, + { + name: "CLIENT_SESSION_KEEP_ALIVE", + value: false, + }, + { + name: "CLIENT_METADATA_USE_SESSION_DATABASE", + value: false, + }, + { + name: "QUERY_CONTEXT_CACHE_SIZE", + value: 5, + }, + { + name: "CLIENT_OUT_OF_BAND_TELEMETRY_ENABLED", + value: false, + }, + { + name: "ENABLE_STAGE_S3_PRIVATELINK_FOR_US_EAST_1", + value: true, + }, + { + name: "TIMESTAMP_NTZ_OUTPUT_FORMAT", + value: "YYYY-MM-DD HH24:MI:SS.FF3", + }, + { + name: "CLIENT_RESULT_PREFETCH_THREADS", + value: 1, + }, + { + name: "CLIENT_METADATA_REQUEST_USE_CONNECTION_CTX", + value: false, + }, + { + name: "CLIENT_HONOR_CLIENT_TZ_FOR_TIMESTAMP_NTZ", + value: true, + }, + { + name: "CLIENT_MEMORY_LIMIT", + value: 1536, + }, + { + name: "CLIENT_TIMESTAMP_TYPE_MAPPING", + value: "TIMESTAMP_NTZ", + }, + { + name: "TIMEZONE", + value: "America/Los_Angeles", + }, + { + name: "CLIENT_RESULT_PREFETCH_SLOTS", + value: 2, + }, + { + name: "CLIENT_TELEMETRY_ENABLED", + value: true, + }, + { + name: "CLIENT_USE_V1_QUERY_API", + value: true, + }, + { + name: "CLIENT_DISABLE_INCIDENTS", + value: true, + }, + { + name: "CLIENT_RESULT_COLUMN_CASE_INSENSITIVE", + value: false, + }, + { + name: "CSV_TIMESTAMP_FORMAT", + value: "", + }, + { + name: "BINARY_OUTPUT_FORMAT", + value: "HEX", + }, + { + name: "CLIENT_ENABLE_LOG_INFO_STATEMENT_PARAMETERS", + value: false, + }, + { + name: "CLIENT_TELEMETRY_SESSIONLESS_ENABLED", + value: true, + }, + { + name: "JS_DRIVER_DISABLE_OCSP_FOR_NON_SF_ENDPOINTS", + value: false, + }, + { + name: "CLIENT_CONSENT_CACHE_ID_TOKEN", + value: false, + }, + { + name: "CLIENT_FORCE_PROTECT_ID_TOKEN", + value: true, + }, + { + name: "DATE_OUTPUT_FORMAT", + value: "YYYY-MM-DD", + }, + { + name: "CLIENT_STAGE_ARRAY_BINDING_THRESHOLD", + value: 65280, + }, + { + name: "CLIENT_SESSION_KEEP_ALIVE_HEARTBEAT_FREQUENCY", + value: 3600, + }, + { + name: "CLIENT_SESSION_CLONE", + value: false, + }, + { + name: "AUTOCOMMIT", + value: true, + }, + { + name: "TIMESTAMP_LTZ_OUTPUT_FORMAT", + value: "", + }, +] + Parameters.update(body.data.parameters); // update all token-related information @@ -1620,13 +1795,19 @@ function TokenInfo(config) { var masterToken; var sessionToken; + let idToken; + let mfaToken; var masterTokenExpirationTime; var sessionTokenExpirationTime; + let idTokenExpirationTime; + let mfaTokenExpirationTime if (Util.isObject(config)) { masterToken = config.masterToken; sessionToken = config.sessionToken; + idToken = config.idToken; + mfaToken = config.mfaToken; masterTokenExpirationTime = config.masterTokenExpirationTime; sessionTokenExpirationTime = config.sessionTokenExpirationTime; } @@ -1653,6 +1834,10 @@ function TokenInfo(config) masterTokenExpirationTime = undefined; sessionToken = undefined; sessionTokenExpirationTime = undefined; + idToken = undefined; + idTokenExpirationTime = undefined; + mfaToken = undefined; + mfaTokenExpirationTime = undefined; }; /** @@ -1664,6 +1849,8 @@ function TokenInfo(config) { masterToken = data.masterToken; sessionToken = data.token || data.sessionToken; + idToken = data.idToken; + mfaToken = data.mfaToken; var currentTime = new Date().getTime(); @@ -1674,6 +1861,9 @@ function TokenInfo(config) sessionTokenExpirationTime = currentTime + 1000 * (data.validityInSeconds || data.validityInSecondsST); + + idTokenExpirationTime = currentTime + 1000 * (data.idTokenValidityInSeconds); + mfaTokenExpirationTime = currentTime + 1000 * (data.mfaTokenValidityInSeconds); }; /** @@ -1716,6 +1906,14 @@ function TokenInfo(config) return sessionTokenExpirationTime; }; + this.getIdToken = function () { + return idToken; + } + + this.getMFAToken = function () { + return mfaToken; + } + /** * Returns a configuration object that can be passed to the TokenInfo * constructor to get an equivalent TokenInfo object. @@ -1728,7 +1926,9 @@ function TokenInfo(config) masterToken: masterToken, masterTokenExpirationTime: masterTokenExpirationTime, sessionToken: sessionToken, - sessionTokenExpirationTime: sessionTokenExpirationTime + sessionTokenExpirationTime: sessionTokenExpirationTime, + idToken, + mfaToken, }; }; } \ No newline at end of file From c082ca3d4df703120075d986335e4e34637d525b Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Tue, 14 Nov 2023 11:35:43 -0800 Subject: [PATCH 12/38] Applied idToken Cache --- lib/authentication/auth_default.js | 4 + lib/authentication/auth_idtoken.js | 21 +- lib/authentication/auth_keypair.js | 4 + lib/authentication/auth_mfatoken.js | 4 + lib/authentication/auth_oauth.js | 4 + lib/authentication/auth_okta.js | 4 + lib/authentication/auth_web.js | 5 + lib/authentication/authentication.js | 2 +- lib/authentication/secureStorage.js | 2 +- lib/connection/connection.js | 10 +- lib/connection/connection_config.js | 8 - lib/connection/statement.js | 4 + lib/http/base.js | 28 +-- lib/services/sf.js | 203 +++--------------- .../unit/authentication/secureStorage_test.js | 4 +- .../unit/connection/connection_config_test.js | 14 +- test/unit/mock/mock_http_client.js | 36 +++- test/unit/snowflake_test.js | 5 +- 18 files changed, 135 insertions(+), 227 deletions(-) diff --git a/lib/authentication/auth_default.js b/lib/authentication/auth_default.js index 24e587810..0db919fd6 100644 --- a/lib/authentication/auth_default.js +++ b/lib/authentication/auth_default.js @@ -30,6 +30,10 @@ function auth_default(password) { return; }; + + this.reauthenticate = async function (body) { + return; + } } module.exports = auth_default; diff --git a/lib/authentication/auth_idtoken.js b/lib/authentication/auth_idtoken.js index b49d5e6b1..53ebe7f82 100644 --- a/lib/authentication/auth_idtoken.js +++ b/lib/authentication/auth_idtoken.js @@ -2,6 +2,8 @@ * Copyright (c) 2015-2023 Snowflake Computing Inc. All rights reserved. */ +const auth_web = require("./auth_web"); + /** * Creates an oauth authenticator. * @@ -10,9 +12,9 @@ * @returns {Object} * @constructor */ -function auth_idToken(id_token) { +function auth_idToken(connectionConfig, httpClient) { - this.id_token = id_token; + this.idToken = connectionConfig.idToken; /** * Update JSON body with token. @@ -22,17 +24,28 @@ function auth_idToken(id_token) { * @returns {null} */ this.updateBody = function (body) { - body['data']['TOKEN'] = this.id_token; + body['data']['TOKEN'] = this.idToken; body['data']['AUTHENTICATOR'] = 'ID_TOKEN' }; this.resetSecret = function () { - this.id_token = null; + this.idToken = null; }; this.authenticate = async function (authenticator, serviceName, account, username) { return; }; + + this.reauthenticate = async function (body) { + const auth = new auth_web(connectionConfig,httpClient); + await auth.authenticate(connectionConfig.getAuthenticator(), + connectionConfig.getServiceName(), + connectionConfig.account, + connectionConfig.username) + auth.updateBody(body); + } + + } module.exports = auth_idToken; diff --git a/lib/authentication/auth_keypair.js b/lib/authentication/auth_keypair.js index 811e7c09a..850906aa9 100644 --- a/lib/authentication/auth_keypair.js +++ b/lib/authentication/auth_keypair.js @@ -192,6 +192,10 @@ function auth_keypair(privateKey, privateKeyPath, privateKeyPass, cryptomod, jwt throw jwtErr; } } + + this.reauthenticate = async function (body) { + return; + } } module.exports = auth_keypair; diff --git a/lib/authentication/auth_mfatoken.js b/lib/authentication/auth_mfatoken.js index 7a12a5d15..14ba90a0b 100644 --- a/lib/authentication/auth_mfatoken.js +++ b/lib/authentication/auth_mfatoken.js @@ -31,6 +31,10 @@ function auth_mfaToken(password,mfaToken) { this.authenticate = async function (authenticator, serviceName, account, username) { return; }; + + this.reauthenticate = async function (body) { + return; + } } module.exports = auth_mfaToken; diff --git a/lib/authentication/auth_oauth.js b/lib/authentication/auth_oauth.js index 4a221ab4f..8907281b0 100644 --- a/lib/authentication/auth_oauth.js +++ b/lib/authentication/auth_oauth.js @@ -30,6 +30,10 @@ function auth_oauth(token) { return; }; + + this.reauthenticate = async function (body) { + return; + } } module.exports = auth_oauth; diff --git a/lib/authentication/auth_okta.js b/lib/authentication/auth_okta.js index f3f8bd886..f556efeae 100644 --- a/lib/authentication/auth_okta.js +++ b/lib/authentication/auth_okta.js @@ -88,6 +88,10 @@ function auth_okta(password, region, account, clientType, clientVersion, httpcli step5(responseHtml); }; + this.reauthenticate = async function (body) { + return; + } + /** * Obtain the SSO URL and token URL. * diff --git a/lib/authentication/auth_web.js b/lib/authentication/auth_web.js index a95b3a703..f85657c76 100644 --- a/lib/authentication/auth_web.js +++ b/lib/authentication/auth_web.js @@ -48,6 +48,7 @@ function auth_web(connectionConfig, httpClient, webbrowser) { */ this.updateBody = function (body) { + body['data']['AUTHENTICATOR'] = 'EXTERNALBROWSER' body['data']['TOKEN'] = token; body['data']['PROOF_KEY'] = proofKey; }; @@ -99,6 +100,10 @@ function auth_web(connectionConfig, httpClient, webbrowser) { processGet(tokenData); }; + this.reauthenticate = async function (body) { + return; + } + /** * Create server to retrieve SAML token. * diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index 4b8b2f2d8..aff778cdb 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -77,7 +77,7 @@ exports.getAuthenticator = function getAuthenticator(connectionConfig, httpClien return new auth_default(connectionConfig.password); } else if (auth === authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR) { if(connectionConfig.getClientStoreTemporaryCredential() && connectionConfig.idToken !== null) { - return new auth_idToken(connectionConfig.idToken); + return new auth_idToken(connectionConfig, httpClient); } else { return new auth_web(connectionConfig, httpClient); diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index fc4d6c9ee..5b44cd35a 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -27,7 +27,7 @@ async function writeCredential(host, user, credType, token){ Logger.getInstance().debug('Token is not provided'); } else { try { - await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); + await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); } catch (err){ Logger.getInstance().error('Failed to save Credential: ', err.message); diff --git a/lib/connection/connection.js b/lib/connection/connection.js index 2eb93136d..c6124dc8c 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -302,19 +302,19 @@ function Connection(context) // the connection can be passed in when invoking the connection.connect() // callback var self = this; + const authType = Authenticator.authenticationTypes; if (connectionConfig.getClientStoreTemporaryCredential()) { - connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.account, connectionConfig.username, 'ID_TOKEN'); - + connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.account, connectionConfig.username, authType.ID_TOKEN_AUTHENTICATOR); + if(connectionConfig.getClientRequestMFAToken()) { - connectionConfig.mfaToken = await SecureStorage.readCredential(connectionConfig.account, connectionConfig.username, 'MFA_TOKEN'); + connectionConfig.mfaToken = await SecureStorage.readCredential(connectionConfig.account, connectionConfig.username, authType.MFA_TOEKN_AUTHENTICATOR); } } - // connectionConfig.idToken = "ver:1-hint:92019682442222-ETMsDgAAAYusQs8MABRBRVMvQ0JDL1BLQ1M1UGFkZGluZwEAABAAEOIXLVLmf2iy1NHlmORHjPAAAACQth6x1/SUHEZebo4jeFS/wI3aOMSkCdQGffIAd2wx/UwI4ua0PtXsuF75td73HKl6uKTBvhEFllbD4r2LnU+q0636yO3LxufTy8bdyGGlJoiGHtRw5IWEBWDXy2ZKAaA6TIfWtFj/TD8lSYlXzmll6Nq+IAngw1O/jmjrVsUiJrUl3QJbmRVWJ6fkRrs2lKzaABQkOtoQDX3tc2FnCXBbBNC1QpS9eA=="; - console.log(connectionConfig.idToken); // Get authenticator to use const auth = Authenticator.getAuthenticator(connectionConfig, context.getHttpClient()); + connectionConfig.auth = auth; try { diff --git a/lib/connection/connection_config.js b/lib/connection/connection_config.js index 8d913bd14..e9298d352 100644 --- a/lib/connection/connection_config.js +++ b/lib/connection/connection_config.js @@ -520,14 +520,6 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) clientRequestMFAToken = options.clientRequestMFAToken } - let consentCacheIdToken = true; - if (Util.exists(options.consentCacheIdToken)) { - Errors.checkArgumentValid(Util.isBoolean(options.consentCacheIdToken), - ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN); - - consentCacheIdToken = options.consentCacheIdToken - } - /** * Returns an object that contains information about the proxy hostname, port, * etc. for when http requests are made. diff --git a/lib/connection/statement.js b/lib/connection/statement.js index 130d6bc30..37779cd82 100644 --- a/lib/connection/statement.js +++ b/lib/connection/statement.js @@ -1330,6 +1330,9 @@ function sendRequestPreExec(statementContext, onResultAvailable) json.queryContextDTO = statementContext.services.sf.getQueryContextDTO(); } + console.log(headers); + console.log(json); + // use the snowflake service to issue the request sendSfRequest(statementContext, { @@ -1549,6 +1552,7 @@ function sendRequestPostExec(statementContext, onResultAvailable) */ function sendSfRequest(statementContext, options, appendQueryParamOnRetry) { + console.log(options); var sf = statementContext.services.sf; var connectionConfig = statementContext.connectionConfig; diff --git a/lib/http/base.js b/lib/http/base.js index fcae944be..cff0f9a85 100644 --- a/lib/http/base.js +++ b/lib/http/base.js @@ -37,34 +37,16 @@ HttpClient.prototype.getConnectionConfig = function () */ HttpClient.prototype.request = function (options) { + //Currently, this is the testing purpose to get a id_token from the server. let ODBCOption = { - // "ACCOUNT_NAME":"simbapartner", - // "AUTHENTICATOR":"externalbrowser", "CLIENT_APP_ID":"ODBC", "CLIENT_APP_VERSION":"3.1.1", - // "CLIENT_ENVIRONMENT":{ - // "APPLICATION":"CProgramFilesx86MicrosoftDataAccessSDK28Toolsamd64", - // "LOG_LEVEL":"6", - // "OCSP_MODE":"FAIL_OPEN", - // "OS":"Windows", - // "OS_VERSION":"6.2-x86_64" - // }, - // "EXT_AUTHN_DUO_METHOD":"push", - // "LOGIN_NAME":"mag-simbacloud@insightsoftware.com", - // "PROOF_KEY":"9FlFVuyicPwds9P0mnrcwj84Z2LEjB3r1ZbdziYJsUU=_-1_0", - // "SESSION_PARAMETERS":{ - // "CLIENT_OUT_OF_BAND_TELEMETRY_ENABLED":true, - // "CLIENT_STORE_TEMPORARY_CREDENTIAL":true, - // "GCS_USE_DOWNSCOPED_CREDENTIAL":false - // }, }; - for(const key in ODBCOption) { - options[key] = ODBCOption[key]; - options.json.data[key] = ODBCOption[key]; - } - - console.log(options); + // for(const key in ODBCOption) { + // options[key] = ODBCOption[key]; + // options.json.data[key] = ODBCOption[key]; + // } const requestOptions = prepareRequestOptions.call(this, options); let sendRequest = async function sendRequest() { diff --git a/lib/services/sf.js b/lib/services/sf.js index 50ab1aafd..fdd3fdc55 100644 --- a/lib/services/sf.js +++ b/lib/services/sf.js @@ -57,6 +57,7 @@ const GSErrors = require('../constants/gs_errors') const QueryContextCache = require('../queryContextCache'); const Logger = require('../logger'); const SecureStorage = require('../authentication/secureStorage'); +const {authenticationTypes} = require('../authentication/authentication'); function isRetryableNetworkError(err) { @@ -157,22 +158,6 @@ function SnowflakeService(connectionConfig, httpClient, config) // update the current state currentState = state; - // const option = state.connectionConfig; - - // if (option.getClientStoreTemporaryCredential()) { - // SecureStorage.writeCredential(option.account, option.username, 'ID_TOKEN', state.tokenInfo.getIdToken()).then(() => - // { - // Logger.getInstance().info("Id_token is saved"); - // }); - - // if (option.getClientRequestMFAToken()) { - // SecureStorage.writeCredential(option.account, option.username, 'MFA_TOKEN', state.tokenInfo.getMFAToken()).then(() => - // { - // Logger.getInstance().info("MFA_token is saved"); - // }); - // } - // } - // enter the new state currentState.enter(transitionContext); } @@ -611,6 +596,7 @@ function StateAbstract(options) */ function sendHttpRequest(requestOptions, httpClient) { + console.log(requestOptions); const realRequestOptions = { method: requestOptions.method, @@ -698,6 +684,15 @@ function StateAbstract(options) if (body && !body.success) { var data = body.data; + + if(body.code === '390195' & data.authnMethod === 'TOKEN') { + Logger.getInstance().trace("ID Token being used has expired. Reauthenticating"); + await SecureStorage.deleteCredential(connectionConfig.account, connectionConfig.username, authenticationTypes.ID_TOKEN_AUTHENTICATOR); + await connectionConfig.auth.reauthenticate(requestOptions.json); + httpClient.request(realRequestOptions); + return; + } + err = Errors.createOperationFailedError( body.code, data, body.message, data && data.sqlState ? data.sqlState : undefined); @@ -710,16 +705,6 @@ function StateAbstract(options) body = undefined; } - if (connectionConfig.getClientStoreTemporaryCredential()) { - if(body.data.idToken){ - await SecureStorage.writeCredential(connectionConfig.account, connectionConfig.username, "ID_TOKEN", body.data.idToken); - } - - if (connectionConfig.getClientRequestMFAToken() && body.data.mfaToken) { - await SecureStorage.writeCredential(connectionConfig.account, connectionConfig.username, "MFA_TOKEN", body.data.mfaToken); - } - } - // if a callback was specified, invoke it if (Util.isFunction(requestOptions.callback)) { @@ -1228,159 +1213,28 @@ StateConnecting.prototype.continue = function () Errors.assertInternal(Util.exists(body.data)); // update the parameters - - body.data.parameters = [ - { - name: "TIMESTAMP_OUTPUT_FORMAT", - value: "YYYY-MM-DD HH24:MI:SS.FF3 TZHTZM", - }, - { - name: "CLIENT_PREFETCH_THREADS", - value: 4, - }, - { - name: "JS_TREAT_INTEGER_AS_BIGINT", - value: false, - }, - { - name: "TIME_OUTPUT_FORMAT", - value: "HH24:MI:SS", - }, - { - name: "TIMESTAMP_TZ_OUTPUT_FORMAT", - value: "", - }, - { - name: "CLIENT_RESULT_CHUNK_SIZE", - value: 48, - }, - { - name: "CLIENT_SESSION_KEEP_ALIVE", - value: false, - }, - { - name: "CLIENT_METADATA_USE_SESSION_DATABASE", - value: false, - }, - { - name: "QUERY_CONTEXT_CACHE_SIZE", - value: 5, - }, - { - name: "CLIENT_OUT_OF_BAND_TELEMETRY_ENABLED", - value: false, - }, - { - name: "ENABLE_STAGE_S3_PRIVATELINK_FOR_US_EAST_1", - value: true, - }, - { - name: "TIMESTAMP_NTZ_OUTPUT_FORMAT", - value: "YYYY-MM-DD HH24:MI:SS.FF3", - }, - { - name: "CLIENT_RESULT_PREFETCH_THREADS", - value: 1, - }, - { - name: "CLIENT_METADATA_REQUEST_USE_CONNECTION_CTX", - value: false, - }, - { - name: "CLIENT_HONOR_CLIENT_TZ_FOR_TIMESTAMP_NTZ", - value: true, - }, - { - name: "CLIENT_MEMORY_LIMIT", - value: 1536, - }, - { - name: "CLIENT_TIMESTAMP_TYPE_MAPPING", - value: "TIMESTAMP_NTZ", - }, - { - name: "TIMEZONE", - value: "America/Los_Angeles", - }, - { - name: "CLIENT_RESULT_PREFETCH_SLOTS", - value: 2, - }, - { - name: "CLIENT_TELEMETRY_ENABLED", - value: true, - }, - { - name: "CLIENT_USE_V1_QUERY_API", - value: true, - }, - { - name: "CLIENT_DISABLE_INCIDENTS", - value: true, - }, - { - name: "CLIENT_RESULT_COLUMN_CASE_INSENSITIVE", - value: false, - }, - { - name: "CSV_TIMESTAMP_FORMAT", - value: "", - }, - { - name: "BINARY_OUTPUT_FORMAT", - value: "HEX", - }, - { - name: "CLIENT_ENABLE_LOG_INFO_STATEMENT_PARAMETERS", - value: false, - }, - { - name: "CLIENT_TELEMETRY_SESSIONLESS_ENABLED", - value: true, - }, - { - name: "JS_DRIVER_DISABLE_OCSP_FOR_NON_SF_ENDPOINTS", - value: false, - }, - { - name: "CLIENT_CONSENT_CACHE_ID_TOKEN", - value: false, - }, - { - name: "CLIENT_FORCE_PROTECT_ID_TOKEN", - value: true, - }, - { - name: "DATE_OUTPUT_FORMAT", - value: "YYYY-MM-DD", - }, - { - name: "CLIENT_STAGE_ARRAY_BINDING_THRESHOLD", - value: 65280, - }, - { - name: "CLIENT_SESSION_KEEP_ALIVE_HEARTBEAT_FREQUENCY", - value: 3600, - }, - { - name: "CLIENT_SESSION_CLONE", - value: false, - }, - { - name: "AUTOCOMMIT", - value: true, - }, - { - name: "TIMESTAMP_LTZ_OUTPUT_FORMAT", - value: "", - }, -] - Parameters.update(body.data.parameters); // update all token-related information parent.tokenInfo.update(body.data); + if (connectionConfig.getClientStoreTemporaryCredential()) { + if(body.data.idToken){ + SecureStorage.writeCredential(connectionConfig.account, connectionConfig.username, + authenticationTypes.ID_TOKEN_AUTHENTICATOR, body.data.idToken).then(() => + { + Logger.getInstance().info("Id_token is saved"); + }); + } + if(body.data.mfaToken){ + SecureStorage.writeCredential(connectionConfig.account, connectionConfig.username, + authenticationTypes.MFA_TOEKN_AUTHENTICATOR, body.data.mfaToken).then(() => + { + Logger.getInstance().info("MFA_token is saved"); + }); + } + } + // we're now connected parent.snowflakeService.transitionToConnected(); @@ -1441,6 +1295,7 @@ StateConnecting.prototype.continue = function () }); request.send(); }; + sendRequest(); }; diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index 80a1b52da..d3a14696a 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -20,7 +20,7 @@ describe('Secure Storage Test', function () { it('test build user name', function (done){ assert.strictEqual(userNameForStorage, - '{MOCK_TEST}:{MOCK_USER}:{SF_NODE_JS_DRIVER}:{MOCK_CREDTYPE}:{0}' + '{MOCK_TEST}:{MOCK_USER}:{SF_NODE_JS_DRIVER}:{MOCK_CREDTYPE}' ); done(); }); @@ -36,7 +36,7 @@ describe('Secure Storage Test', function () { assert.strictEqual(savedPassword, randomPassword); }); - it('test - delet the mock credential in Local Storage', async function () { + it('test - delete the mock credential in Local Storage', async function () { await SecureStorage.deleteCredential(host, user, credType); const result = await findCredentialFromStorage(userNameForStorage, randomPassword); assert.strictEqual(result, false); diff --git a/test/unit/connection/connection_config_test.js b/test/unit/connection/connection_config_test.js index 5e919984e..6a9c67949 100644 --- a/test/unit/connection/connection_config_test.js +++ b/test/unit/connection/connection_config_test.js @@ -544,7 +544,19 @@ describe('ConnectionConfig: basic', function () username: 'username', password: 'password', account: 'account', - consentCacheIdToken: 'invalid' + clientStoreTemporaryCredential: 'invalid' + }, + errorCode: ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL, + }, + { + + name: 'invalid clientRequestMFAToken', + options: + { + username: 'username', + password: 'password', + account: 'account', + clientRequestMFAToken: 'invalid' }, errorCode: ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL, }, diff --git a/test/unit/mock/mock_http_client.js b/test/unit/mock/mock_http_client.js index 05d3c346b..c9e9e8b5b 100644 --- a/test/unit/mock/mock_http_client.js +++ b/test/unit/mock/mock_http_client.js @@ -187,7 +187,10 @@ function buildRequestOutputMappings(clientInfo) CLIENT_APP_ID: 'JavaScript', CLIENT_APP_VERSION: clientInfo.version, CLIENT_ENVIRONMENT: clientInfo.environment, - SESSION_PARAMETERS: {} + SESSION_PARAMETERS: { + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, + CLIENT_REQUEST_MFA_TOKEN:true, + } } } }, @@ -1171,7 +1174,10 @@ function buildRequestOutputMappings(clientInfo) CLIENT_APP_ID: 'JavaScript', CLIENT_APP_VERSION: clientInfo.version, CLIENT_ENVIRONMENT: clientInfo.environment, - SESSION_PARAMETERS: {} + SESSION_PARAMETERS: { + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, + CLIENT_REQUEST_MFA_TOKEN:true, + } } } }, @@ -1388,7 +1394,9 @@ function buildRequestOutputMappings(clientInfo) CLIENT_ENVIRONMENT: clientInfo.environment, SESSION_PARAMETERS: { CLIENT_SESSION_KEEP_ALIVE: true, - CLIENT_SESSION_KEEP_ALIVE_HEARTBEAT_FREQUENCY: 1800 + CLIENT_SESSION_KEEP_ALIVE_HEARTBEAT_FREQUENCY: 1800, + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, + CLIENT_REQUEST_MFA_TOKEN:true, } } } @@ -1493,6 +1501,8 @@ function buildRequestOutputMappings(clientInfo) CLIENT_ENVIRONMENT: clientInfo.environment, SESSION_PARAMETERS: { JS_TREAT_INTEGER_AS_BIGINT: true, + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, + CLIENT_REQUEST_MFA_TOKEN:true, } } } @@ -1596,7 +1606,10 @@ function buildRequestOutputMappings(clientInfo) CLIENT_APP_ID: 'JavaScript', CLIENT_APP_VERSION: clientInfo.version, CLIENT_ENVIRONMENT: clientInfo.environment, - SESSION_PARAMETERS: {} + SESSION_PARAMETERS: { + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, + CLIENT_REQUEST_MFA_TOKEN:true, + } } } }, @@ -1683,7 +1696,10 @@ function buildRequestOutputMappings(clientInfo) CLIENT_APP_ID: 'JavaScript', CLIENT_APP_VERSION: clientInfo.version, CLIENT_ENVIRONMENT: clientInfo.environment, - SESSION_PARAMETERS: {} + SESSION_PARAMETERS: { + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, + CLIENT_REQUEST_MFA_TOKEN:true, + } } } }, @@ -1719,7 +1735,10 @@ function buildRequestOutputMappings(clientInfo) CLIENT_APP_ID: 'JavaScript', CLIENT_APP_VERSION: clientInfo.version, CLIENT_ENVIRONMENT: clientInfo.environment, - SESSION_PARAMETERS: {} + SESSION_PARAMETERS: { + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, + CLIENT_REQUEST_MFA_TOKEN:true, + } } } }, @@ -1755,7 +1774,10 @@ function buildRequestOutputMappings(clientInfo) CLIENT_APP_ID: 'JavaScript', CLIENT_APP_VERSION: clientInfo.version, CLIENT_ENVIRONMENT: clientInfo.environment, - SESSION_PARAMETERS: {} + SESSION_PARAMETERS: { + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, + CLIENT_REQUEST_MFA_TOKEN:true, + } } } }, diff --git a/test/unit/snowflake_test.js b/test/unit/snowflake_test.js index f95e7d071..55f3dc0d0 100644 --- a/test/unit/snowflake_test.js +++ b/test/unit/snowflake_test.js @@ -7,7 +7,7 @@ var ErrorCodes = require('./../../lib/errors').codes; var MockTestUtil = require('./mock/mock_test_util'); var assert = require('assert'); var async = require('async'); - +const { configureLogger } = require('../configureLogger'); // get a mock snowflake instance var snowflake = MockTestUtil.snowflake; @@ -25,6 +25,9 @@ const connectionOptionsTreatIntegerAsBigInt = mockConnectionOptions.treatIntAsBi describe('snowflake.createConnection() synchronous errors', function () { + + configureLogger('TRACE'); + var testCases = [ { From 38324b7e15bd8d73f8755489636932a14274eb88 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 15 Nov 2023 09:27:19 -0800 Subject: [PATCH 13/38] fixed bugs, and remove unnecessary parts --- lib/authentication/authentication.js | 9 ++--- lib/authentication/secureStorage.js | 25 +++++++++++-- lib/connection/connection_config.js | 22 ++---------- lib/connection/statement.js | 1 - lib/errors.js | 1 - lib/http/base.js | 11 ------ lib/parameters.js | 8 ----- lib/services/sf.js | 36 +------------------ .../unit/authentication/secureStorage_test.js | 2 +- .../unit/connection/connection_config_test.js | 2 +- test/unit/mock/mock_http_client.js | 18 ++++------ 11 files changed, 35 insertions(+), 100 deletions(-) diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index 4d4a7ca3b..8efcdfb2b 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -89,12 +89,7 @@ exports.getAuthenticator = function getAuthenticator(connectionConfig, httpClien connectionConfig.getPrivateKeyPass()); } else if (auth === authenticationTypes.OAUTH_AUTHENTICATOR) { return new auth_oauth(connectionConfig.getToken()); - } - else if (auth.startsWith('HTTPS://')) { - if (connectionConfig.getClientRequestMFAToken() && connectionConfig.mfaToken !== null) { - return new auth_mfaToken(connectionConfig.password,connectionConfig.mfaToken); - } - else if (this.isOktaAuth(auth)) { + } else if (this.isOktaAuth(auth)) { return new auth_okta(connectionConfig.password, connectionConfig.region, connectionConfig.account, @@ -106,7 +101,7 @@ exports.getAuthenticator = function getAuthenticator(connectionConfig, httpClien // Authenticator specified does not exist return new auth_default(connectionConfig.password); } -}; +} /** * Returns the boolean describing if the provided authenticator is okta or not. diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index 5b44cd35a..9595da0df 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -3,6 +3,9 @@ const path = require('path'); const GlobalConfig = require('../global_config'); const Logger = require('../logger'); const keytar = require('keytar'); +const os = require('os'); +const fs = require('fs/promises'); + function createCredentialCacheDir() { const cacheDirectory = GlobalConfig.mkdirCacheDir(process.env.SF_TEMPORARY_CREDENTIAL_CACHE_DIR); const credCache = path.join(cacheDirectory, 'temporary_credential.json'); @@ -27,7 +30,13 @@ async function writeCredential(host, user, credType, token){ Logger.getInstance().debug('Token is not provided'); } else { try { - await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); + if (os.platform() === 'win32') { + const dir = createCredentialCacheDir(); + await fs.writeFile(dir, token, 'utf8'); + } + else { + await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); + } } catch (err){ Logger.getInstance().error('Failed to save Credential: ', err.message); @@ -36,11 +45,21 @@ async function writeCredential(host, user, credType, token){ } async function readCredential(host, user, credType) { - return await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType)); + if (os.platform() === 'win32') { + const dir = createCredentialCacheDir(); + return await fs.readFile(dir, 'utf8'); + } else { + return await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType)); + } } async function deleteCredential(host, user, credType) { - await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType)); + if (os.platform() === 'win32') { + const dir = createCredentialCacheDir(); + return await fs.unlink(dir); + } else { + await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType)); + } } module.exports = { diff --git a/lib/connection/connection_config.js b/lib/connection/connection_config.js index 126d99bec..74244bc87 100644 --- a/lib/connection/connection_config.js +++ b/lib/connection/connection_config.js @@ -51,8 +51,8 @@ const DEFAULT_PARAMS = 'forceStageBindError', 'includeRetryReason', 'disableQueryContextCache', - 'consentCacheIdToken', 'retryTimeout', + 'clientStoreTemporaryCredential', ]; const Logger = require('../logger'); @@ -529,14 +529,6 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) clientStoreTemporaryCredential = options.clientStoreTemporaryCredential } - let clientRequestMFAToken = true; - if (Util.exists(options.clientRequestMFAToken)) { - Errors.checkArgumentValid(Util.isBoolean(options.clientRequestMFAToken), - ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN); - - clientRequestMFAToken = options.clientRequestMFAToken - } - /** * Returns an object that contains information about the proxy hostname, port, * etc. for when http requests are made. @@ -819,7 +811,7 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) } /** - * Returns whether idToken cache is enabled or not by the configuration + * Returns whether the auth token saves on the local machine or not. * * @returns {Boolean} */ @@ -827,10 +819,6 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) return clientStoreTemporaryCredential } - this.getClientRequestMFAToken = function () { - return clientRequestMFAToken - } - /** * Returns the client config file * @@ -839,9 +827,6 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) this.getClientConfigFile = function () { return clientConfigFile; }; - - this.getConsentCacheIdToken = function () { - return consentCacheIdToken /** * Returns the max login timeout @@ -1026,9 +1011,6 @@ function createParameters() defaultValue: 16, validate: isNonNegativeNumber }, - { - - } ]; } diff --git a/lib/connection/statement.js b/lib/connection/statement.js index 20341f632..0e531aeee 100644 --- a/lib/connection/statement.js +++ b/lib/connection/statement.js @@ -1575,7 +1575,6 @@ function sendRequestPostExec(statementContext, onResultAvailable) */ function sendSfRequest(statementContext, options, appendQueryParamOnRetry) { - console.log(options); var sf = statementContext.services.sf; var connectionConfig = statementContext.connectionConfig; diff --git a/lib/errors.js b/lib/errors.js index 9b84a04fc..de01a515c 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -77,7 +77,6 @@ codes.ERR_CONN_CREATE_INVALID_RETRY_TIMEOUT = 404044; codes.ERR_CONN_CREATE_INVALID_ACCOUNT_REGEX = 404045; codes.ERR_CONN_CREATE_INVALID_REGION_REGEX = 404046; codes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL =404047 -codes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN =404048 // 405001 codes.ERR_CONN_CONNECT_INVALID_CALLBACK = 405001; diff --git a/lib/http/base.js b/lib/http/base.js index cff0f9a85..31af5903c 100644 --- a/lib/http/base.js +++ b/lib/http/base.js @@ -37,17 +37,6 @@ HttpClient.prototype.getConnectionConfig = function () */ HttpClient.prototype.request = function (options) { - //Currently, this is the testing purpose to get a id_token from the server. - let ODBCOption = { - "CLIENT_APP_ID":"ODBC", - "CLIENT_APP_VERSION":"3.1.1", - }; - - // for(const key in ODBCOption) { - // options[key] = ODBCOption[key]; - // options.json.data[key] = ODBCOption[key]; - // } - const requestOptions = prepareRequestOptions.call(this, options); let sendRequest = async function sendRequest() { request = axios.request(requestOptions).then(response => { diff --git a/lib/parameters.js b/lib/parameters.js index 65a852116..01e3ca30a 100644 --- a/lib/parameters.js +++ b/lib/parameters.js @@ -61,7 +61,6 @@ names.JS_TREAT_INTEGER_AS_BIGINT = 'JS_TREAT_INTEGER_AS_BIGINT'; names.CLIENT_STAGE_ARRAY_BINDING_THRESHOLD = 'CLIENT_STAGE_ARRAY_BINDING_THRESHOLD'; names.MULTI_STATEMENT_COUNT = 'MULTI_STATEMENT_COUNT'; names.QUERY_CONTEXT_CACHE_SIZE = 'QUERY_CONTEXT_CACHE_SIZE'; -names.CLIENT_CONSENT_CACHE_ID_TOKEN = 'CLIENT_CONSENT_CACHE_ID_TOKEN'; var parameters = [ @@ -114,13 +113,6 @@ var parameters = value: 5, desc: 'Query Context Cache Size' }), - new Parameter( - { - name: names.CLIENT_CONSENT_CACHE_ID_TOKEN, - value: false, - desc: 'Whether the SSO Token caching is enabled or not' - } - ), ]; // put all the parameters in a map so they're easy to retrieve and update diff --git a/lib/services/sf.js b/lib/services/sf.js index 8512f2b60..e309b885e 100644 --- a/lib/services/sf.js +++ b/lib/services/sf.js @@ -605,7 +605,6 @@ function StateAbstract(options) */ function sendHttpRequest(requestOptions, httpClient) { - console.log(requestOptions); const realRequestOptions = { method: requestOptions.method, @@ -694,7 +693,7 @@ function StateAbstract(options) { var data = body.data; - if(body.code === '390195' & data.authnMethod === 'TOKEN') { + if(body.code === '390195' && data.authnMethod === 'TOKEN') { Logger.getInstance().trace("ID Token being used has expired. Reauthenticating"); await SecureStorage.deleteCredential(connectionConfig.account, connectionConfig.username, authenticationTypes.ID_TOKEN_AUTHENTICATOR); await connectionConfig.auth.reauthenticate(requestOptions.json); @@ -1196,14 +1195,6 @@ StateConnecting.prototype.continue = function () sessionParameters.SESSION_PARAMETERS.CLIENT_STORE_TEMPORARY_CREDENTIAL = this.connectionConfig.getClientStoreTemporaryCredential(); } - - if (Util.exists(this.connectionConfig.getClientRequestMFAToken())) - { - sessionParameters.SESSION_PARAMETERS.CLIENT_REQUEST_MFA_TOKEN = - this.connectionConfig.getClientRequestMFAToken(); - } - - if(Util.exists(this.connectionConfig)) Util.apply(json.data, clientInfo); Util.apply(json.data, sessionParameters); @@ -1678,19 +1669,13 @@ function TokenInfo(config) { var masterToken; var sessionToken; - let idToken; - let mfaToken; var masterTokenExpirationTime; var sessionTokenExpirationTime; - let idTokenExpirationTime; - let mfaTokenExpirationTime if (Util.isObject(config)) { masterToken = config.masterToken; sessionToken = config.sessionToken; - idToken = config.idToken; - mfaToken = config.mfaToken; masterTokenExpirationTime = config.masterTokenExpirationTime; sessionTokenExpirationTime = config.sessionTokenExpirationTime; } @@ -1717,10 +1702,6 @@ function TokenInfo(config) masterTokenExpirationTime = undefined; sessionToken = undefined; sessionTokenExpirationTime = undefined; - idToken = undefined; - idTokenExpirationTime = undefined; - mfaToken = undefined; - mfaTokenExpirationTime = undefined; }; /** @@ -1732,8 +1713,6 @@ function TokenInfo(config) { masterToken = data.masterToken; sessionToken = data.token || data.sessionToken; - idToken = data.idToken; - mfaToken = data.mfaToken; var currentTime = new Date().getTime(); @@ -1744,9 +1723,6 @@ function TokenInfo(config) sessionTokenExpirationTime = currentTime + 1000 * (data.validityInSeconds || data.validityInSecondsST); - - idTokenExpirationTime = currentTime + 1000 * (data.idTokenValidityInSeconds); - mfaTokenExpirationTime = currentTime + 1000 * (data.mfaTokenValidityInSeconds); }; /** @@ -1789,14 +1765,6 @@ function TokenInfo(config) return sessionTokenExpirationTime; }; - this.getIdToken = function () { - return idToken; - } - - this.getMFAToken = function () { - return mfaToken; - } - /** * Returns a configuration object that can be passed to the TokenInfo * constructor to get an equivalent TokenInfo object. @@ -1810,8 +1778,6 @@ function TokenInfo(config) masterTokenExpirationTime: masterTokenExpirationTime, sessionToken: sessionToken, sessionTokenExpirationTime: sessionTokenExpirationTime, - idToken, - mfaToken, }; }; } \ No newline at end of file diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index d3a14696a..aa6b50fcf 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -20,7 +20,7 @@ describe('Secure Storage Test', function () { it('test build user name', function (done){ assert.strictEqual(userNameForStorage, - '{MOCK_TEST}:{MOCK_USER}:{SF_NODE_JS_DRIVER}:{MOCK_CREDTYPE}' + '{MOCK_TEST}:{MOCK_USER}:{SF_NODE_JS_DRIVER}:{MOCK_CREDTYPE}}' ); done(); }); diff --git a/test/unit/connection/connection_config_test.js b/test/unit/connection/connection_config_test.js index 1a73dbe6c..047a8e67a 100644 --- a/test/unit/connection/connection_config_test.js +++ b/test/unit/connection/connection_config_test.js @@ -693,7 +693,7 @@ describe('ConnectionConfig: basic', function () account: 'account', clientRequestMFAToken: 'invalid' }, - errorCode: ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL, + errorCode: ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN, }, { name: 'invalid clientConfigFile', diff --git a/test/unit/mock/mock_http_client.js b/test/unit/mock/mock_http_client.js index 2bd9c5e5e..82d03476b 100644 --- a/test/unit/mock/mock_http_client.js +++ b/test/unit/mock/mock_http_client.js @@ -221,7 +221,6 @@ function buildRequestOutputMappings(clientInfo) CLIENT_ENVIRONMENT: clientInfo.environment, SESSION_PARAMETERS: { CLIENT_STORE_TEMPORARY_CREDENTIAL:true, - CLIENT_REQUEST_MFA_TOKEN:true, } } } @@ -1241,7 +1240,6 @@ function buildRequestOutputMappings(clientInfo) CLIENT_ENVIRONMENT: clientInfo.environment, SESSION_PARAMETERS: { CLIENT_STORE_TEMPORARY_CREDENTIAL:true, - CLIENT_REQUEST_MFA_TOKEN:true, } } } @@ -1463,7 +1461,7 @@ function buildRequestOutputMappings(clientInfo) CLIENT_SESSION_KEEP_ALIVE: true, CLIENT_SESSION_KEEP_ALIVE_HEARTBEAT_FREQUENCY: 1800, CLIENT_STORE_TEMPORARY_CREDENTIAL:true, - CLIENT_REQUEST_MFA_TOKEN:true, + } } } @@ -1570,8 +1568,7 @@ function buildRequestOutputMappings(clientInfo) CLIENT_ENVIRONMENT: clientInfo.environment, SESSION_PARAMETERS: { JS_TREAT_INTEGER_AS_BIGINT: true, - CLIENT_STORE_TEMPORARY_CREDENTIAL:true, - CLIENT_REQUEST_MFA_TOKEN:true, + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, } } } @@ -1678,8 +1675,7 @@ function buildRequestOutputMappings(clientInfo) CLIENT_APP_VERSION: clientInfo.version, CLIENT_ENVIRONMENT: clientInfo.environment, SESSION_PARAMETERS: { - CLIENT_STORE_TEMPORARY_CREDENTIAL:true, - CLIENT_REQUEST_MFA_TOKEN:true, + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, } } } @@ -1770,8 +1766,7 @@ function buildRequestOutputMappings(clientInfo) CLIENT_APP_VERSION: clientInfo.version, CLIENT_ENVIRONMENT: clientInfo.environment, SESSION_PARAMETERS: { - CLIENT_STORE_TEMPORARY_CREDENTIAL:true, - CLIENT_REQUEST_MFA_TOKEN:true, + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, } } } @@ -1813,7 +1808,7 @@ function buildRequestOutputMappings(clientInfo) CLIENT_ENVIRONMENT: clientInfo.environment, SESSION_PARAMETERS: { CLIENT_STORE_TEMPORARY_CREDENTIAL:true, - CLIENT_REQUEST_MFA_TOKEN:true, + } } } @@ -1853,8 +1848,7 @@ function buildRequestOutputMappings(clientInfo) CLIENT_APP_VERSION: clientInfo.version, CLIENT_ENVIRONMENT: clientInfo.environment, SESSION_PARAMETERS: { - CLIENT_STORE_TEMPORARY_CREDENTIAL:true, - CLIENT_REQUEST_MFA_TOKEN:true, + CLIENT_STORE_TEMPORARY_CREDENTIAL:true, } } } From 6e4e6f76ec4e66f434b64e00c7f387e5bd66e957 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 15 Nov 2023 10:19:51 -0800 Subject: [PATCH 14/38] added id_token authentication test --- lib/connection/connection.js | 4 ---- test/unit/authentication/authentication_test.js | 15 ++++++++++++++- test/unit/connection/connection_config_test.js | 13 ------------- test/unit/mock/mock_test_util.js | 12 +++++++++++- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/lib/connection/connection.js b/lib/connection/connection.js index c058e1d44..172aca06f 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -307,10 +307,6 @@ function Connection(context) if (connectionConfig.getClientStoreTemporaryCredential()) { connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.account, connectionConfig.username, authType.ID_TOKEN_AUTHENTICATOR); - - if(connectionConfig.getClientRequestMFAToken()) { - connectionConfig.mfaToken = await SecureStorage.readCredential(connectionConfig.account, connectionConfig.username, authType.MFA_TOEKN_AUTHENTICATOR); - } } // Get authenticator to use diff --git a/test/unit/authentication/authentication_test.js b/test/unit/authentication/authentication_test.js index bd98bb9f9..0e150f5a2 100644 --- a/test/unit/authentication/authentication_test.js +++ b/test/unit/authentication/authentication_test.js @@ -12,8 +12,8 @@ var auth_web = require('./../../../lib/authentication/auth_web'); var auth_keypair = require('./../../../lib/authentication/auth_keypair'); var auth_oauth = require('./../../../lib/authentication/auth_oauth'); var auth_okta = require('./../../../lib/authentication/auth_okta'); +const auth_idtoken = require('./../../../lib/authentication/auth_idtoken'); var authenticationTypes = require('./../../../lib/authentication/authentication').authenticationTypes; - var MockTestUtil = require('./../mock/mock_test_util'); // get connection options to connect to this mock snowflake instance @@ -25,6 +25,7 @@ var connectionOptionsKeyPair = mockConnectionOptions.authKeyPair; var connectionOptionsKeyPairPath = mockConnectionOptions.authKeyPairPath; var connectionOptionsOauth = mockConnectionOptions.authOauth; var connectionOptionsOkta = mockConnectionOptions.authOkta; +const connectionOptionsidToken = mockConnectionOptions.authIdToken; describe('default authentication', function () { @@ -184,8 +185,20 @@ describe('external browser authentication', function () assert.strictEqual( body['data']['AUTHENTICATOR'], authenticationTypes.EXTERNAL_BROWSER_AUTHENTICATOR, 'Authenticator should be EXTERNALBROWSER'); }); + + it('external browser - id token', async function () { + const auth = new auth_idtoken(connectionOptionsidToken, httpclient); + await auth.authenticate(credentials.authenticator, '', credentials.account, credentials.username, credentials.host); + + let body = { data: {} }; + auth.updateBody(body); + + assert.strictEqual(body['data']['TOKEN'], connectionConfig.idToken); + assert.strictEqual(body['data']['AUTHENTICATOR'], authenticationTypes.ID_TOKEN_AUTHENTICATOR); + }) }); + describe('key-pair authentication', function () { var cryptomod; diff --git a/test/unit/connection/connection_config_test.js b/test/unit/connection/connection_config_test.js index 047a8e67a..cb04b907e 100644 --- a/test/unit/connection/connection_config_test.js +++ b/test/unit/connection/connection_config_test.js @@ -672,7 +672,6 @@ describe('ConnectionConfig: basic', function () errorCode: ErrorCodes.ERR_CONN_CREATE_INVALID_INCLUDE_RETRY_REASON, }, { - name: 'invalid clientStoreTemporaryCredential', options: { @@ -683,18 +682,6 @@ describe('ConnectionConfig: basic', function () }, errorCode: ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL, }, - { - - name: 'invalid clientRequestMFAToken', - options: - { - username: 'username', - password: 'password', - account: 'account', - clientRequestMFAToken: 'invalid' - }, - errorCode: ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_REQUEST_MFA_TOKEN, - }, { name: 'invalid clientConfigFile', options: { diff --git a/test/unit/mock/mock_test_util.js b/test/unit/mock/mock_test_util.js index 0a7ddcb3a..df219ffac 100644 --- a/test/unit/mock/mock_test_util.js +++ b/test/unit/mock/mock_test_util.js @@ -96,6 +96,15 @@ var connectionOptionsExternalBrowser = authenticator: 'EXTERNALBROWSER' }; +const connectionOptionsidToken = +{ + accessUrl: 'http://fakeaccount.snowflakecomputing.com', + username: 'fakeusername', + account: 'fakeaccount', + idToken: 'fakeIdToken', + authenticator: 'EXTERNALBROWSER' +}; + var connectionOptionsKeyPair = { accessUrl: 'http://fakeaccount.snowflakecomputing.com', @@ -150,5 +159,6 @@ exports.connectionOptions = authKeyPair: connectionOptionsKeyPair, authKeyPairPath: connectionOptionsKeyPairPath, authOauth: connectionOptionsOauth, - authOkta: connectionOptionsOkta + authOkta: connectionOptionsOkta, + authIdToken: connectionOptionsidToken, }; From 25cc0be267eda5143faa6e99835bc783e578607d Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 15 Nov 2023 10:48:31 -0800 Subject: [PATCH 15/38] Removed mfa token implements from this feature --- lib/authentication/auth_mfatoken.js | 41 ------------------- lib/authentication/authentication.js | 2 - lib/constants/error_messages.js | 1 - .../authentication/authentication_test.js | 2 +- 4 files changed, 1 insertion(+), 45 deletions(-) delete mode 100644 lib/authentication/auth_mfatoken.js diff --git a/lib/authentication/auth_mfatoken.js b/lib/authentication/auth_mfatoken.js deleted file mode 100644 index 14ba90a0b..000000000 --- a/lib/authentication/auth_mfatoken.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2015-2023 Snowflake Computing Inc. All rights reserved. - */ - -/** - * Creates an oauth authenticator. - * - * @param {String} token - * - * @returns {Object} - * @constructor - */ -function auth_mfaToken(password,mfaToken) { - - this.passord = password; - this.mfaToken = mfaToken - - /** - * Update JSON body with token. - * - * @param {JSON} body - * - * @returns {null} - */ - this.updateBody = function (body) { - body['data']['PASSWORD'] = this.passord; - body['data']['AUTHENTICATOR'] = 'MFA_TOEKN'; - body['data']['TOKEN'] = this.mfaToken; - }; - - this.authenticate = async function (authenticator, serviceName, account, username) { - return; - }; - - this.reauthenticate = async function (body) { - return; - } - } - - module.exports = auth_mfaToken; - \ No newline at end of file diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index 8efcdfb2b..8f099785b 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -8,7 +8,6 @@ const auth_keypair = require('./auth_keypair'); const auth_oauth = require('./auth_oauth'); const auth_okta = require('./auth_okta'); const auth_idToken = require('./auth_idtoken'); -const auth_mfaToken = require('./auth_mfatoken'); const authenticationTypes = { @@ -17,7 +16,6 @@ const authenticationTypes = KEY_PAIR_AUTHENTICATOR: 'SNOWFLAKE_JWT', OAUTH_AUTHENTICATOR: 'OAUTH', ID_TOKEN_AUTHENTICATOR: 'ID_TOKEN', - MFA_TOEKN_AUTHENTICATOR: 'MFA_TOEKN', }; exports.authenticationTypes = authenticationTypes; diff --git a/lib/constants/error_messages.js b/lib/constants/error_messages.js index 03c4b6c87..a2073052b 100644 --- a/lib/constants/error_messages.js +++ b/lib/constants/error_messages.js @@ -72,7 +72,6 @@ exports[404044] = 'Invalid retryTimeout value. The specified value must be a num exports[404045] = 'Invalid account. The specified value must be a valid subdomain string.'; exports[404046] = 'Invalid region. The specified value must be a valid subdomain string.'; exports[404047] = 'Invalid clientStoreTemporaryCredential. The specified value must be a boolean.' -exports[404048] = 'Invalid clientRequestMFAToken. The specified value must be a boolean.' // 405001 exports[405001] = 'Invalid callback. The specified value must be a function.'; diff --git a/test/unit/authentication/authentication_test.js b/test/unit/authentication/authentication_test.js index 0e150f5a2..59943a349 100644 --- a/test/unit/authentication/authentication_test.js +++ b/test/unit/authentication/authentication_test.js @@ -193,7 +193,7 @@ describe('external browser authentication', function () let body = { data: {} }; auth.updateBody(body); - assert.strictEqual(body['data']['TOKEN'], connectionConfig.idToken); + assert.strictEqual(body['data']['TOKEN'], connectionOptionsidToken.idToken); assert.strictEqual(body['data']['AUTHENTICATOR'], authenticationTypes.ID_TOKEN_AUTHENTICATOR); }) }); From 771afa08f3671619104d744c8135e15cb8611e6b Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 15 Nov 2023 11:10:19 -0800 Subject: [PATCH 16/38] fixed error --- lib/authentication/auth_mfatoken.js | 41 +++++++++++++++++++++++++++++ lib/authentication/secureStorage.js | 6 ++--- lib/services/sf.js | 7 ----- 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 lib/authentication/auth_mfatoken.js diff --git a/lib/authentication/auth_mfatoken.js b/lib/authentication/auth_mfatoken.js new file mode 100644 index 000000000..14ba90a0b --- /dev/null +++ b/lib/authentication/auth_mfatoken.js @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015-2023 Snowflake Computing Inc. All rights reserved. + */ + +/** + * Creates an oauth authenticator. + * + * @param {String} token + * + * @returns {Object} + * @constructor + */ +function auth_mfaToken(password,mfaToken) { + + this.passord = password; + this.mfaToken = mfaToken + + /** + * Update JSON body with token. + * + * @param {JSON} body + * + * @returns {null} + */ + this.updateBody = function (body) { + body['data']['PASSWORD'] = this.passord; + body['data']['AUTHENTICATOR'] = 'MFA_TOEKN'; + body['data']['TOKEN'] = this.mfaToken; + }; + + this.authenticate = async function (authenticator, serviceName, account, username) { + return; + }; + + this.reauthenticate = async function (body) { + return; + } + } + + module.exports = auth_mfaToken; + \ No newline at end of file diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index 9595da0df..3fffd608c 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -30,7 +30,7 @@ async function writeCredential(host, user, credType, token){ Logger.getInstance().debug('Token is not provided'); } else { try { - if (os.platform() === 'win32') { + if (os.platform() === 'linux') { const dir = createCredentialCacheDir(); await fs.writeFile(dir, token, 'utf8'); } @@ -45,7 +45,7 @@ async function writeCredential(host, user, credType, token){ } async function readCredential(host, user, credType) { - if (os.platform() === 'win32') { + if (os.platform() === 'linux') { const dir = createCredentialCacheDir(); return await fs.readFile(dir, 'utf8'); } else { @@ -54,7 +54,7 @@ async function readCredential(host, user, credType) { } async function deleteCredential(host, user, credType) { - if (os.platform() === 'win32') { + if (os.platform() === 'linux') { const dir = createCredentialCacheDir(); return await fs.unlink(dir); } else { diff --git a/lib/services/sf.js b/lib/services/sf.js index e309b885e..b0dc3fc86 100644 --- a/lib/services/sf.js +++ b/lib/services/sf.js @@ -1235,13 +1235,6 @@ StateConnecting.prototype.continue = function () Logger.getInstance().info("Id_token is saved"); }); } - if(body.data.mfaToken){ - SecureStorage.writeCredential(connectionConfig.account, connectionConfig.username, - authenticationTypes.MFA_TOEKN_AUTHENTICATOR, body.data.mfaToken).then(() => - { - Logger.getInstance().info("MFA_token is saved"); - }); - } } // we're now connected From 9619abc736ac219e727535720737ba253b6736e4 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 15 Nov 2023 11:40:53 -0800 Subject: [PATCH 17/38] fixed lint --- lib/authentication/auth_idtoken.js | 2 - lib/authentication/auth_mfatoken.js | 41 ------------------- lib/authentication/authentication.js | 2 +- lib/authentication/secureStorage.js | 10 ++++- lib/connection/connection.js | 5 ++- lib/http/base.js | 1 - lib/services/sf.js | 1 - .../unit/authentication/secureStorage_test.js | 9 ++++ 8 files changed, 22 insertions(+), 49 deletions(-) delete mode 100644 lib/authentication/auth_mfatoken.js diff --git a/lib/authentication/auth_idtoken.js b/lib/authentication/auth_idtoken.js index 53ebe7f82..8935a7bd6 100644 --- a/lib/authentication/auth_idtoken.js +++ b/lib/authentication/auth_idtoken.js @@ -44,8 +44,6 @@ function auth_idToken(connectionConfig, httpClient) { connectionConfig.username) auth.updateBody(body); } - - } module.exports = auth_idToken; diff --git a/lib/authentication/auth_mfatoken.js b/lib/authentication/auth_mfatoken.js deleted file mode 100644 index 14ba90a0b..000000000 --- a/lib/authentication/auth_mfatoken.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2015-2023 Snowflake Computing Inc. All rights reserved. - */ - -/** - * Creates an oauth authenticator. - * - * @param {String} token - * - * @returns {Object} - * @constructor - */ -function auth_mfaToken(password,mfaToken) { - - this.passord = password; - this.mfaToken = mfaToken - - /** - * Update JSON body with token. - * - * @param {JSON} body - * - * @returns {null} - */ - this.updateBody = function (body) { - body['data']['PASSWORD'] = this.passord; - body['data']['AUTHENTICATOR'] = 'MFA_TOEKN'; - body['data']['TOKEN'] = this.mfaToken; - }; - - this.authenticate = async function (authenticator, serviceName, account, username) { - return; - }; - - this.reauthenticate = async function (body) { - return; - } - } - - module.exports = auth_mfaToken; - \ No newline at end of file diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index 8f099785b..a825e60be 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Snowflake Computing Inc. All rights reserved. + * Copyright (c) 2015-2023 Snowflake Computing Inc. All rights reserved. */ const auth_default = require('./auth_default'); diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index 3fffd608c..17b5b83b9 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -1,3 +1,6 @@ +/* + * Copyright (c) 2015-2023 Snowflake Computing Inc. All rights reserved. + */ const path = require('path'); const GlobalConfig = require('../global_config'); @@ -26,7 +29,8 @@ function buildTemporaryCredentialName(host, user, cred_type) { } async function writeCredential(host, user, credType, token){ - if (!token || token == '') { + Logger.getInstance().trace("The os is ", os.platform()); + if (!token || token === '') { Logger.getInstance().debug('Token is not provided'); } else { try { @@ -45,6 +49,8 @@ async function writeCredential(host, user, credType, token){ } async function readCredential(host, user, credType) { + Logger.getInstance().trace("The os is ", os.platform()); + if (os.platform() === 'linux') { const dir = createCredentialCacheDir(); return await fs.readFile(dir, 'utf8'); @@ -54,6 +60,8 @@ async function readCredential(host, user, credType) { } async function deleteCredential(host, user, credType) { + Logger.getInstance().trace("The os is ", os.platform()); + if (os.platform() === 'linux') { const dir = createCredentialCacheDir(); return await fs.unlink(dir); diff --git a/lib/connection/connection.js b/lib/connection/connection.js index 172aca06f..40fd93612 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -306,7 +306,8 @@ function Connection(context) const authType = Authenticator.authenticationTypes; if (connectionConfig.getClientStoreTemporaryCredential()) { - connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.account, connectionConfig.username, authType.ID_TOKEN_AUTHENTICATOR); + connectionConfig.idToken = await SecureStorage.readCredential(connectionConfig.account, + connectionConfig.username, authType.ID_TOKEN_AUTHENTICATOR); } // Get authenticator to use @@ -318,7 +319,7 @@ function Connection(context) await auth.authenticate(connectionConfig.getAuthenticator(), connectionConfig.getServiceName(), connectionConfig.account, - connectionConfig.username) + connectionConfig.username); // JSON for connection var body = Authenticator.formAuthJSON(connectionConfig.getAuthenticator(), diff --git a/lib/http/base.js b/lib/http/base.js index 31af5903c..2871c1777 100644 --- a/lib/http/base.js +++ b/lib/http/base.js @@ -36,7 +36,6 @@ HttpClient.prototype.getConnectionConfig = function () * @returns {Object} an object representing the request that was issued. */ HttpClient.prototype.request = function (options) { - const requestOptions = prepareRequestOptions.call(this, options); let sendRequest = async function sendRequest() { request = axios.request(requestOptions).then(response => { diff --git a/lib/services/sf.js b/lib/services/sf.js index b0dc3fc86..637c6a5b4 100644 --- a/lib/services/sf.js +++ b/lib/services/sf.js @@ -1305,7 +1305,6 @@ StateConnecting.prototype.continue = function () }); request.send(); }; - sendRequest(); }; diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index aa6b50fcf..64656c797 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -2,8 +2,17 @@ const assert = require('assert'); const keytar = require('keytar'); const SecureStorage = require('../../../lib/authentication/secureStorage'); const { randomUUID } = require('crypto'); +const configureLogger = require('../../configureLogger'); describe('Secure Storage Test', function () { + + before(()=>{ + configureLogger('TRACE'); + }); + + after(()=> { + configureLogger('WARN'); + }); const host = 'mock_test'; const user = 'mock_user'; const credType = 'MOCK_CREDTYPE'; From 377bd161c438be2599058296bcace11244615198 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 15 Nov 2023 12:17:04 -0800 Subject: [PATCH 18/38] added logging option --- test/unit/authentication/secureStorage_test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index 64656c797..73ae7f8e6 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -2,15 +2,15 @@ const assert = require('assert'); const keytar = require('keytar'); const SecureStorage = require('../../../lib/authentication/secureStorage'); const { randomUUID } = require('crypto'); -const configureLogger = require('../../configureLogger'); +const {configureLogger} = require('../../configureLogger'); describe('Secure Storage Test', function () { - before(()=>{ + before(function(){ configureLogger('TRACE'); }); - after(()=> { + after(function() { configureLogger('WARN'); }); const host = 'mock_test'; From 4800ca64a533cad6e1a17076a94f8fac5356192c Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 15 Nov 2023 12:39:49 -0800 Subject: [PATCH 19/38] added libscret-devel' --- ci/image/Dockerfile.nodejs-centos7-fips-test | 2 ++ ci/image/Dockerfile.nodejs-centos7-node14-build | 1 + ci/image/Dockerfile.nodejs-centos7-node14-test | 1 + 3 files changed, 4 insertions(+) diff --git a/ci/image/Dockerfile.nodejs-centos7-fips-test b/ci/image/Dockerfile.nodejs-centos7-fips-test index dce338c21..42351c698 100644 --- a/ci/image/Dockerfile.nodejs-centos7-fips-test +++ b/ci/image/Dockerfile.nodejs-centos7-fips-test @@ -23,6 +23,8 @@ RUN yum -y install zstd # jq RUN yum -y install jq +RUN yum -y install libsecret-devel + # gosu RUN curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64" RUN chmod +x /usr/local/bin/gosu diff --git a/ci/image/Dockerfile.nodejs-centos7-node14-build b/ci/image/Dockerfile.nodejs-centos7-node14-build index 323d32b03..29dbc4d66 100644 --- a/ci/image/Dockerfile.nodejs-centos7-node14-build +++ b/ci/image/Dockerfile.nodejs-centos7-node14-build @@ -47,6 +47,7 @@ RUN yum -y groupinstall "Development Tools" && \ ln -s /opt/git/bin/git /usr/local/bin/git && \ yum -y install zstd && \ yum -y install jq && \ + yum -y install libsecret-devel && \ curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64" && \ chmod +x /usr/local/bin/gosu diff --git a/ci/image/Dockerfile.nodejs-centos7-node14-test b/ci/image/Dockerfile.nodejs-centos7-node14-test index 323d32b03..29dbc4d66 100644 --- a/ci/image/Dockerfile.nodejs-centos7-node14-test +++ b/ci/image/Dockerfile.nodejs-centos7-node14-test @@ -47,6 +47,7 @@ RUN yum -y groupinstall "Development Tools" && \ ln -s /opt/git/bin/git /usr/local/bin/git && \ yum -y install zstd && \ yum -y install jq && \ + yum -y install libsecret-devel && \ curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64" && \ chmod +x /usr/local/bin/gosu From 13db3ca6585fba04720eccc008ba0add0cb195b2 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 15 Nov 2023 13:23:20 -0800 Subject: [PATCH 20/38] testing --- test/unit/authentication/secureStorage_test.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index 73ae7f8e6..c0ef81040 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -3,9 +3,10 @@ const keytar = require('keytar'); const SecureStorage = require('../../../lib/authentication/secureStorage'); const { randomUUID } = require('crypto'); const {configureLogger} = require('../../configureLogger'); +const os = require('os'); +if (os.platform() !== 'linux') { describe('Secure Storage Test', function () { - before(function(){ configureLogger('TRACE'); }); @@ -51,4 +52,4 @@ describe('Secure Storage Test', function () { assert.strictEqual(result, false); }); }); - +} From 54c50284d2f49a618012685682747b454f564520 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 15 Nov 2023 17:19:34 -0800 Subject: [PATCH 21/38] removed downloading libsecret --- ci/image/Dockerfile.nodejs-centos7-fips-test | 2 -- ci/image/Dockerfile.nodejs-centos7-node14-build | 1 - ci/image/Dockerfile.nodejs-centos7-node14-test | 1 - 3 files changed, 4 deletions(-) diff --git a/ci/image/Dockerfile.nodejs-centos7-fips-test b/ci/image/Dockerfile.nodejs-centos7-fips-test index 42351c698..dce338c21 100644 --- a/ci/image/Dockerfile.nodejs-centos7-fips-test +++ b/ci/image/Dockerfile.nodejs-centos7-fips-test @@ -23,8 +23,6 @@ RUN yum -y install zstd # jq RUN yum -y install jq -RUN yum -y install libsecret-devel - # gosu RUN curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64" RUN chmod +x /usr/local/bin/gosu diff --git a/ci/image/Dockerfile.nodejs-centos7-node14-build b/ci/image/Dockerfile.nodejs-centos7-node14-build index 29dbc4d66..323d32b03 100644 --- a/ci/image/Dockerfile.nodejs-centos7-node14-build +++ b/ci/image/Dockerfile.nodejs-centos7-node14-build @@ -47,7 +47,6 @@ RUN yum -y groupinstall "Development Tools" && \ ln -s /opt/git/bin/git /usr/local/bin/git && \ yum -y install zstd && \ yum -y install jq && \ - yum -y install libsecret-devel && \ curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64" && \ chmod +x /usr/local/bin/gosu diff --git a/ci/image/Dockerfile.nodejs-centos7-node14-test b/ci/image/Dockerfile.nodejs-centos7-node14-test index 29dbc4d66..323d32b03 100644 --- a/ci/image/Dockerfile.nodejs-centos7-node14-test +++ b/ci/image/Dockerfile.nodejs-centos7-node14-test @@ -47,7 +47,6 @@ RUN yum -y groupinstall "Development Tools" && \ ln -s /opt/git/bin/git /usr/local/bin/git && \ yum -y install zstd && \ yum -y install jq && \ - yum -y install libsecret-devel && \ curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64" && \ chmod +x /usr/local/bin/gosu From 0b805f585fa422e22ed682f2fd8ca48c86168814 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 15 Nov 2023 17:28:28 -0800 Subject: [PATCH 22/38] libsecret client testing --- ci/image/Dockerfile.nodejs-centos7-fips-test | 2 ++ ci/image/Dockerfile.nodejs-centos7-node14-build | 3 ++- ci/image/Dockerfile.nodejs-centos7-node14-test | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ci/image/Dockerfile.nodejs-centos7-fips-test b/ci/image/Dockerfile.nodejs-centos7-fips-test index dce338c21..a6e08c598 100644 --- a/ci/image/Dockerfile.nodejs-centos7-fips-test +++ b/ci/image/Dockerfile.nodejs-centos7-fips-test @@ -6,6 +6,7 @@ RUN yum -y install epel-release RUN yum -y install centos-release-scl RUN yum -y install git RUN yum -y install which +RUN yum -y install libsecret-devel # python RUN yum -y install python36 @@ -23,6 +24,7 @@ RUN yum -y install zstd # jq RUN yum -y install jq + # gosu RUN curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64" RUN chmod +x /usr/local/bin/gosu diff --git a/ci/image/Dockerfile.nodejs-centos7-node14-build b/ci/image/Dockerfile.nodejs-centos7-node14-build index 323d32b03..20fbc4ecd 100644 --- a/ci/image/Dockerfile.nodejs-centos7-node14-build +++ b/ci/image/Dockerfile.nodejs-centos7-node14-build @@ -4,7 +4,8 @@ FROM centos:7 # update OS RUN yum -y update && \ yum -y install epel-release && \ - yum -y install centos-release-scl + yum -y install centos-release-scl\ + yum -y install libsecret-devel # nvm environment variables ENV NVM_DIR /usr/local/nvm diff --git a/ci/image/Dockerfile.nodejs-centos7-node14-test b/ci/image/Dockerfile.nodejs-centos7-node14-test index 323d32b03..9cd31cd7a 100644 --- a/ci/image/Dockerfile.nodejs-centos7-node14-test +++ b/ci/image/Dockerfile.nodejs-centos7-node14-test @@ -4,7 +4,8 @@ FROM centos:7 # update OS RUN yum -y update && \ yum -y install epel-release && \ - yum -y install centos-release-scl + yum -y install centos-release-scl \ + yum -y install libsecret-devel # nvm environment variables ENV NVM_DIR /usr/local/nvm From 9f4f42c4f10a705209f4834eef18fc2cf0e7dece Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 15 Nov 2023 23:33:40 -0800 Subject: [PATCH 23/38] removed unnecessary codes --- test/unit/authentication/secureStorage_test.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index c0ef81040..53a9b8760 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -5,15 +5,8 @@ const { randomUUID } = require('crypto'); const {configureLogger} = require('../../configureLogger'); const os = require('os'); -if (os.platform() !== 'linux') { describe('Secure Storage Test', function () { - before(function(){ - configureLogger('TRACE'); - }); - after(function() { - configureLogger('WARN'); - }); const host = 'mock_test'; const user = 'mock_user'; const credType = 'MOCK_CREDTYPE'; @@ -52,4 +45,3 @@ describe('Secure Storage Test', function () { assert.strictEqual(result, false); }); }); -} From 5a81ba936f39adaec1145d7dabb7ad8b6bff48d6 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 16 Nov 2023 10:57:51 -0800 Subject: [PATCH 24/38] added semicolons, and made lint fixes --- lib/authentication/auth_idtoken.js | 14 +++++++------- lib/authentication/secureStorage.js | 18 ++++++++---------- lib/connection/connection_config.js | 4 ++-- lib/constants/error_messages.js | 2 +- lib/errors.js | 2 +- test/unit/authentication/secureStorage_test.js | 6 ++---- 6 files changed, 21 insertions(+), 25 deletions(-) diff --git a/lib/authentication/auth_idtoken.js b/lib/authentication/auth_idtoken.js index 8935a7bd6..69674dd0a 100644 --- a/lib/authentication/auth_idtoken.js +++ b/lib/authentication/auth_idtoken.js @@ -2,7 +2,7 @@ * Copyright (c) 2015-2023 Snowflake Computing Inc. All rights reserved. */ -const auth_web = require("./auth_web"); +const auth_web = require('./auth_web'); /** * Creates an oauth authenticator. @@ -25,7 +25,7 @@ function auth_idToken(connectionConfig, httpClient) { */ this.updateBody = function (body) { body['data']['TOKEN'] = this.idToken; - body['data']['AUTHENTICATOR'] = 'ID_TOKEN' + body['data']['AUTHENTICATOR'] = 'ID_TOKEN'; }; this.resetSecret = function () { @@ -37,13 +37,13 @@ function auth_idToken(connectionConfig, httpClient) { }; this.reauthenticate = async function (body) { - const auth = new auth_web(connectionConfig,httpClient); + const auth = new auth_web(connectionConfig, httpClient); await auth.authenticate(connectionConfig.getAuthenticator(), - connectionConfig.getServiceName(), - connectionConfig.account, - connectionConfig.username) + connectionConfig.getServiceName(), + connectionConfig.account, + connectionConfig.username); auth.updateBody(body); - } + }; } module.exports = auth_idToken; diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index 17b5b83b9..85117a1df 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -20,16 +20,16 @@ function createCredentialCacheDir() { * * @param {String} host * @param {String} user - * @param {String} cred_type + * @param {String} credType * @returns */ -function buildTemporaryCredentialName(host, user, cred_type) { - return `{${host.toUpperCase()}}:{${user.toUpperCase()}}:{SF_NODE_JS_DRIVER}:{${cred_type}}}`; +function buildTemporaryCredentialName(host, user, credType) { + return `{${host.toUpperCase()}}:{${user.toUpperCase()}}:{SF_NODE_JS_DRIVER}:{${credType}}}`; } async function writeCredential(host, user, credType, token){ - Logger.getInstance().trace("The os is ", os.platform()); + Logger.getInstance().trace('The os is ', os.platform()); if (!token || token === '') { Logger.getInstance().debug('Token is not provided'); } else { @@ -37,19 +37,17 @@ async function writeCredential(host, user, credType, token){ if (os.platform() === 'linux') { const dir = createCredentialCacheDir(); await fs.writeFile(dir, token, 'utf8'); - } - else { + } else { await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); } - } - catch (err){ + } catch (err){ Logger.getInstance().error('Failed to save Credential: ', err.message); } } } async function readCredential(host, user, credType) { - Logger.getInstance().trace("The os is ", os.platform()); + Logger.getInstance().trace('The os is ', os.platform()); if (os.platform() === 'linux') { const dir = createCredentialCacheDir(); @@ -60,7 +58,7 @@ async function readCredential(host, user, credType) { } async function deleteCredential(host, user, credType) { - Logger.getInstance().trace("The os is ", os.platform()); + Logger.getInstance().trace('The os is ', os.platform()); if (os.platform() === 'linux') { const dir = createCredentialCacheDir(); diff --git a/lib/connection/connection_config.js b/lib/connection/connection_config.js index 74244bc87..3a1e4889d 100644 --- a/lib/connection/connection_config.js +++ b/lib/connection/connection_config.js @@ -526,7 +526,7 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) Errors.checkArgumentValid(Util.isBoolean(options.clientStoreTemporaryCredential), ErrorCodes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL); - clientStoreTemporaryCredential = options.clientStoreTemporaryCredential + clientStoreTemporaryCredential = options.clientStoreTemporaryCredential; } /** @@ -816,7 +816,7 @@ function ConnectionConfig(options, validateCredentials, qaMode, clientInfo) * @returns {Boolean} */ this.getClientStoreTemporaryCredential = function () { - return clientStoreTemporaryCredential + return clientStoreTemporaryCredential; } /** diff --git a/lib/constants/error_messages.js b/lib/constants/error_messages.js index a2073052b..7a8002d3b 100644 --- a/lib/constants/error_messages.js +++ b/lib/constants/error_messages.js @@ -71,7 +71,7 @@ exports[404043] = 'Invalid clientConfigFile value. The specified value must be a exports[404044] = 'Invalid retryTimeout value. The specified value must be a number.'; exports[404045] = 'Invalid account. The specified value must be a valid subdomain string.'; exports[404046] = 'Invalid region. The specified value must be a valid subdomain string.'; -exports[404047] = 'Invalid clientStoreTemporaryCredential. The specified value must be a boolean.' +exports[404047] = 'Invalid clientStoreTemporaryCredential. The specified value must be a boolean.'; // 405001 exports[405001] = 'Invalid callback. The specified value must be a function.'; diff --git a/lib/errors.js b/lib/errors.js index de01a515c..ca7e6059a 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -76,7 +76,7 @@ codes.ERR_CONN_CREATE_INVALID_CLIENT_CONFIG_FILE = 404043; codes.ERR_CONN_CREATE_INVALID_RETRY_TIMEOUT = 404044; codes.ERR_CONN_CREATE_INVALID_ACCOUNT_REGEX = 404045; codes.ERR_CONN_CREATE_INVALID_REGION_REGEX = 404046; -codes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL =404047 +codes.ERR_CONN_CREATE_INVALID_CLIENT_STORE_TEMPORARY_CREDENTIAL = 404047; // 405001 codes.ERR_CONN_CONNECT_INVALID_CALLBACK = 405001; diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index 53a9b8760..f48b4c950 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -2,8 +2,6 @@ const assert = require('assert'); const keytar = require('keytar'); const SecureStorage = require('../../../lib/authentication/secureStorage'); const { randomUUID } = require('crypto'); -const {configureLogger} = require('../../configureLogger'); -const os = require('os'); describe('Secure Storage Test', function () { @@ -11,9 +9,9 @@ describe('Secure Storage Test', function () { const user = 'mock_user'; const credType = 'MOCK_CREDTYPE'; const randomPassword = randomUUID(); - const userNameForStorage = SecureStorage.buildTemporaryCredentialName(host, user, credType,0); + const userNameForStorage = SecureStorage.buildTemporaryCredentialName(host, user, credType, 0); - async function findCredentialFromStorage (userName, password){ + async function findCredentialFromStorage(userName, password){ const credentialList = await keytar.findCredentials(host); const result = credentialList.some((element) => { return element.account === userName && element.password === password; From d693f02534449beba19cd2174e694759e50f8121 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 16 Nov 2023 17:24:57 -0800 Subject: [PATCH 25/38] added optional dependencies --- ci/image/Dockerfile.nodejs-centos7-fips-test | 1 - ci/image/Dockerfile.nodejs-centos7-node14-build | 3 +-- ci/image/Dockerfile.nodejs-centos7-node14-test | 3 +-- lib/authentication/authentication.js | 3 +-- lib/connection/connection.js | 1 + package.json | 10 ++++++++-- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ci/image/Dockerfile.nodejs-centos7-fips-test b/ci/image/Dockerfile.nodejs-centos7-fips-test index a6e08c598..c823f3dd1 100644 --- a/ci/image/Dockerfile.nodejs-centos7-fips-test +++ b/ci/image/Dockerfile.nodejs-centos7-fips-test @@ -6,7 +6,6 @@ RUN yum -y install epel-release RUN yum -y install centos-release-scl RUN yum -y install git RUN yum -y install which -RUN yum -y install libsecret-devel # python RUN yum -y install python36 diff --git a/ci/image/Dockerfile.nodejs-centos7-node14-build b/ci/image/Dockerfile.nodejs-centos7-node14-build index 20fbc4ecd..323d32b03 100644 --- a/ci/image/Dockerfile.nodejs-centos7-node14-build +++ b/ci/image/Dockerfile.nodejs-centos7-node14-build @@ -4,8 +4,7 @@ FROM centos:7 # update OS RUN yum -y update && \ yum -y install epel-release && \ - yum -y install centos-release-scl\ - yum -y install libsecret-devel + yum -y install centos-release-scl # nvm environment variables ENV NVM_DIR /usr/local/nvm diff --git a/ci/image/Dockerfile.nodejs-centos7-node14-test b/ci/image/Dockerfile.nodejs-centos7-node14-test index 9cd31cd7a..e8f01a8c1 100644 --- a/ci/image/Dockerfile.nodejs-centos7-node14-test +++ b/ci/image/Dockerfile.nodejs-centos7-node14-test @@ -4,8 +4,7 @@ FROM centos:7 # update OS RUN yum -y update && \ yum -y install epel-release && \ - yum -y install centos-release-scl \ - yum -y install libsecret-devel + yum -y install centos-release-scl # nvm environment variables ENV NVM_DIR /usr/local/nvm diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index a825e60be..f3b32f740 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -93,8 +93,7 @@ exports.getAuthenticator = function getAuthenticator(connectionConfig, httpClien connectionConfig.account, connectionConfig.getClientType(), connectionConfig.getClientVersion(), - httpClient - ); + httpClient); } else { // Authenticator specified does not exist return new auth_default(connectionConfig.password); diff --git a/lib/connection/connection.js b/lib/connection/connection.js index 40fd93612..a639e7247 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -313,6 +313,7 @@ function Connection(context) // Get authenticator to use const auth = Authenticator.getAuthenticator(connectionConfig, context.getHttpClient()); connectionConfig.auth = auth; + context.auth = auth; try { diff --git a/package.json b/package.json index e5071dd8f..fa3c2d970 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "glob": "^7.1.6", "https-proxy-agent": "^5.0.1", "jsonwebtoken": "^9.0.0", - "keytar": "^7.9.0", "mime-types": "^2.1.29", "mkdirp": "^1.0.3", "moment": "^2.29.4", @@ -35,7 +34,14 @@ "simple-lru-cache": "^0.0.2", "tmp": "^0.2.1", "uuid": "^8.3.2", - "winston": "^3.1.0" + "winston": "^3.1.0", + "keytar": { + "version": "^7.9.0", + "os": [ + "win32", + "darwin" + ] + } }, "devDependencies": { "@aws-sdk/types": "^3.387.0", From 5b269a74c6732df23c876c5a8c4d9f5a749eb446 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 16 Nov 2023 17:31:26 -0800 Subject: [PATCH 26/38] dependencies --- package.json | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index fa3c2d970..20c8289f3 100644 --- a/package.json +++ b/package.json @@ -35,13 +35,6 @@ "tmp": "^0.2.1", "uuid": "^8.3.2", "winston": "^3.1.0", - "keytar": { - "version": "^7.9.0", - "os": [ - "win32", - "darwin" - ] - } }, "devDependencies": { "@aws-sdk/types": "^3.387.0", @@ -55,6 +48,15 @@ "peerDependencies": { "asn1.js": "^5.4.1" }, + "optionalDependencies": { + "keytar": { + "version": "^7.9.0", + "os": [ + "win32", + "darwin" + ] + } + }, "overrides": { "@azure/storage-blob": { "node-fetch": "^3.2.10" From 43b25ae999987624af691d57a051915e80f42687 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 16 Nov 2023 17:31:46 -0800 Subject: [PATCH 27/38] dependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 20c8289f3..3dfa95176 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "simple-lru-cache": "^0.0.2", "tmp": "^0.2.1", "uuid": "^8.3.2", - "winston": "^3.1.0", + "winston": "^3.1.0" }, "devDependencies": { "@aws-sdk/types": "^3.387.0", From fdf53dc82a2d8fbcf3f11f6489048ff68cc45af3 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 16 Nov 2023 23:12:26 -0800 Subject: [PATCH 28/38] add dependencies --- package.json | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 3dfa95176..9e3a2cd54 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,12 @@ "fast-xml-parser": "^4.2.5", "fastest-levenshtein": "^1.0.16", "generic-pool": "^3.8.2", + "keytar": { + "version": "^7.9.0", + "os": [ + "!linux" + ] + }, "glob": "^7.1.6", "https-proxy-agent": "^5.0.1", "jsonwebtoken": "^9.0.0", @@ -48,15 +54,7 @@ "peerDependencies": { "asn1.js": "^5.4.1" }, - "optionalDependencies": { - "keytar": { - "version": "^7.9.0", - "os": [ - "win32", - "darwin" - ] - } - }, + "optionalDependencies": {}, "overrides": { "@azure/storage-blob": { "node-fetch": "^3.2.10" From 2b4707ae4d51b9442d0bc9354b5ccf3e26072582 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 16 Nov 2023 23:16:11 -0800 Subject: [PATCH 29/38] revert back --- package.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/package.json b/package.json index 9e3a2cd54..e5071dd8f 100644 --- a/package.json +++ b/package.json @@ -22,15 +22,10 @@ "fast-xml-parser": "^4.2.5", "fastest-levenshtein": "^1.0.16", "generic-pool": "^3.8.2", - "keytar": { - "version": "^7.9.0", - "os": [ - "!linux" - ] - }, "glob": "^7.1.6", "https-proxy-agent": "^5.0.1", "jsonwebtoken": "^9.0.0", + "keytar": "^7.9.0", "mime-types": "^2.1.29", "mkdirp": "^1.0.3", "moment": "^2.29.4", @@ -54,7 +49,6 @@ "peerDependencies": { "asn1.js": "^5.4.1" }, - "optionalDependencies": {}, "overrides": { "@azure/storage-blob": { "node-fetch": "^3.2.10" From c101a4bfd70440e33d80cf58f7eafcd72a17a384 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Mon, 20 Nov 2023 23:15:00 -0800 Subject: [PATCH 30/38] added manual test for idtoken and refactored --- lib/connection/connection.js | 2 -- lib/services/sf.js | 5 ++-- test/integration/testManualConnection.js | 33 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/lib/connection/connection.js b/lib/connection/connection.js index a639e7247..8f7128dc4 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -312,8 +312,6 @@ function Connection(context) // Get authenticator to use const auth = Authenticator.getAuthenticator(connectionConfig, context.getHttpClient()); - connectionConfig.auth = auth; - context.auth = auth; try { diff --git a/lib/services/sf.js b/lib/services/sf.js index d1e1e6525..148769db2 100644 --- a/lib/services/sf.js +++ b/lib/services/sf.js @@ -57,7 +57,7 @@ const GSErrors = require('../constants/gs_errors') const QueryContextCache = require('../queryContextCache'); const Logger = require('../logger'); const SecureStorage = require('../authentication/secureStorage'); -const {authenticationTypes} = require('../authentication/authentication'); +const {authenticationTypes, getAuthenticator} = require('../authentication/authentication'); function isRetryableNetworkError(err) { @@ -696,11 +696,12 @@ function StateAbstract(options) if (body && !body.success) { var data = body.data; + const auth = getAuthenticator(connectionConfig, httpClient); if(body.code === '390195' && data.authnMethod === 'TOKEN') { Logger.getInstance().trace("ID Token being used has expired. Reauthenticating"); await SecureStorage.deleteCredential(connectionConfig.account, connectionConfig.username, authenticationTypes.ID_TOKEN_AUTHENTICATOR); - await connectionConfig.auth.reauthenticate(requestOptions.json); + await auth.reauthenticate(requestOptions.json); httpClient.request(realRequestOptions); return; } diff --git a/test/integration/testManualConnection.js b/test/integration/testManualConnection.js index d763f5e7a..8678979aa 100644 --- a/test/integration/testManualConnection.js +++ b/test/integration/testManualConnection.js @@ -4,6 +4,7 @@ const assert = require("assert"); const connOption = require("./connectionOptions"); const testUtil = require("./testUtil"); const Logger = require('../../lib/logger'); +const SecureStorage = require('../../lib/authentication/secureStorage'); if (process.env.RUN_MANUAL_TESTS_ONLY == "true") { describe.only("Run manual tests", function () { @@ -70,6 +71,38 @@ if (process.env.RUN_MANUAL_TESTS_ONLY == "true") { } }); }); + + it("Connection - ID Token authenticator", async function (done) { + + //Testing to obtain the id token. + await SecureStorage.deleteCredential(connectionOption.host, connectionOption.username, "ID_TOKEN"); + + const connectionOption = connOption.externalBrowser + const connection = snowflake.createConnection( + connectionOption + ); + await connection.connectAsync(function (err) { + assert.ok(!err); + const idToken = SecureStorage.readCredential(connectionOption.host, connectionOption.username, "ID_TOKEN"); + assert.ok( idToken !== null); + }); + await testUtil.destroyConnectionAsync(connection); + + //Testing with the id token. + const idTokenConnection = snowflake.createConnection(connectionOption); + idTokenConnection.connectAsync(function (err) { + assert.ok(!err); + }); + await testUtil.destroyConnectionAsync(idTokenConnection); + + //Testing with the id token. + await SecureStorage.writeCredential(connectionOption.host, connectionOption.username, "ID_TOKEN", "WRONG Token"); + const wrongTokneConnection = testUtil.connectAsync(connOption); + await wrongTokneConnection.connectAsync(function (err) { + assert.ok(!err); + done(); + }); + }) }); describe("Connection test - oauth", function () { From 7b698820d44c0fd4fa774b6df02de69194d2b920 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Tue, 21 Nov 2023 10:04:03 -0800 Subject: [PATCH 31/38] removed unnecessary codes --- ci/image/Dockerfile.nodejs-centos7-fips-test | 1 - test/integration/testManualConnection.js | 2 +- test/unit/snowflake_test.js | 5 +---- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/ci/image/Dockerfile.nodejs-centos7-fips-test b/ci/image/Dockerfile.nodejs-centos7-fips-test index c823f3dd1..dce338c21 100644 --- a/ci/image/Dockerfile.nodejs-centos7-fips-test +++ b/ci/image/Dockerfile.nodejs-centos7-fips-test @@ -23,7 +23,6 @@ RUN yum -y install zstd # jq RUN yum -y install jq - # gosu RUN curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64" RUN chmod +x /usr/local/bin/gosu diff --git a/test/integration/testManualConnection.js b/test/integration/testManualConnection.js index 8678979aa..e9705d985 100644 --- a/test/integration/testManualConnection.js +++ b/test/integration/testManualConnection.js @@ -95,7 +95,7 @@ if (process.env.RUN_MANUAL_TESTS_ONLY == "true") { }); await testUtil.destroyConnectionAsync(idTokenConnection); - //Testing with the id token. + //Testing reauthentication. await SecureStorage.writeCredential(connectionOption.host, connectionOption.username, "ID_TOKEN", "WRONG Token"); const wrongTokneConnection = testUtil.connectAsync(connOption); await wrongTokneConnection.connectAsync(function (err) { diff --git a/test/unit/snowflake_test.js b/test/unit/snowflake_test.js index 98d7f243e..f83cd6eed 100644 --- a/test/unit/snowflake_test.js +++ b/test/unit/snowflake_test.js @@ -8,7 +8,7 @@ var MockTestUtil = require('./mock/mock_test_util'); const QueryStatus = require('./../../lib/constants/query_status').code; var assert = require('assert'); var async = require('async'); -const { configureLogger } = require('../configureLogger'); + // get a mock snowflake instance var snowflake = MockTestUtil.snowflake; @@ -26,9 +26,6 @@ const connectionOptionsTreatIntegerAsBigInt = mockConnectionOptions.treatIntAsBi describe('snowflake.createConnection() synchronous errors', function () { - - configureLogger('TRACE'); - var testCases = [ { From a2c209747602908d7a1ce85a28b2df4e95f4d1ad Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Tue, 21 Nov 2023 20:22:53 -0800 Subject: [PATCH 32/38] brought keytar library into the local storage --- .../SecureStorage/keytar/LICENSE.md | 20 ++ .../SecureStorage/keytar/README.md | 94 ++++++ .../SecureStorage/keytar/binding.gyp | 48 +++ .../keytar/build/Release/keytar.node | Bin 0 -> 707584 bytes .../SecureStorage/keytar/keytar.d.ts | 51 +++ .../SecureStorage/keytar/lib/keytar.js | 43 +++ .../SecureStorage/keytar/package.json | 66 ++++ .../SecureStorage/keytar/src/async.cc | 242 ++++++++++++++ .../SecureStorage/keytar/src/async.h | 103 ++++++ .../SecureStorage/keytar/src/credentials.h | 13 + .../SecureStorage/keytar/src/keytar.h | 41 +++ .../SecureStorage/keytar/src/keytar_mac.cc | 296 ++++++++++++++++++ .../SecureStorage/keytar/src/keytar_posix.cc | 184 +++++++++++ .../SecureStorage/keytar/src/keytar_win.cc | 272 ++++++++++++++++ .../SecureStorage/keytar/src/main.cc | 139 ++++++++ lib/authentication/secureStorage.js | 2 +- package.json | 1 - .../unit/authentication/secureStorage_test.js | 2 +- 18 files changed, 1614 insertions(+), 3 deletions(-) create mode 100644 lib/authentication/SecureStorage/keytar/LICENSE.md create mode 100644 lib/authentication/SecureStorage/keytar/README.md create mode 100644 lib/authentication/SecureStorage/keytar/binding.gyp create mode 100644 lib/authentication/SecureStorage/keytar/build/Release/keytar.node create mode 100644 lib/authentication/SecureStorage/keytar/keytar.d.ts create mode 100644 lib/authentication/SecureStorage/keytar/lib/keytar.js create mode 100644 lib/authentication/SecureStorage/keytar/package.json create mode 100644 lib/authentication/SecureStorage/keytar/src/async.cc create mode 100644 lib/authentication/SecureStorage/keytar/src/async.h create mode 100644 lib/authentication/SecureStorage/keytar/src/credentials.h create mode 100644 lib/authentication/SecureStorage/keytar/src/keytar.h create mode 100644 lib/authentication/SecureStorage/keytar/src/keytar_mac.cc create mode 100644 lib/authentication/SecureStorage/keytar/src/keytar_posix.cc create mode 100644 lib/authentication/SecureStorage/keytar/src/keytar_win.cc create mode 100644 lib/authentication/SecureStorage/keytar/src/main.cc diff --git a/lib/authentication/SecureStorage/keytar/LICENSE.md b/lib/authentication/SecureStorage/keytar/LICENSE.md new file mode 100644 index 000000000..493db50ed --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2013 GitHub Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/authentication/SecureStorage/keytar/README.md b/lib/authentication/SecureStorage/keytar/README.md new file mode 100644 index 000000000..91141b726 --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/README.md @@ -0,0 +1,94 @@ +# keytar - Node module to manage system keychain + +[![Travis Build Status](https://travis-ci.org/atom/node-keytar.svg?branch=master)](https://travis-ci.org/atom/node-keytar) +[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/atom/node-keytar?svg=true)](https://ci.appveyor.com/project/Atom/node-keytar) +[![Dependency Status](https://david-dm.org/atom/node-keytar.svg)](https://david-dm.org/atom/node-keytar) + +A native Node module to get, add, replace, and delete passwords in system's keychain. On macOS the passwords are managed by the Keychain, on Linux they are managed by the Secret Service API/libsecret, and on Windows they are managed by Credential Vault. + +## Installing + +```sh +npm install keytar +``` + +### On Linux + +Currently this library uses `libsecret` so you may need to install it before running `npm install`. + +Depending on your distribution, you will need to run the following command: + +* Debian/Ubuntu: `sudo apt-get install libsecret-1-dev` +* Red Hat-based: `sudo yum install libsecret-devel` +* Arch Linux: `sudo pacman -S libsecret` + +## Building + + * Clone the repository + * Run `npm install` + * Run `npm test` to run the tests + +## Supported versions + +Each release of `keytar` includes prebuilt binaries for the versions of Node and Electron that are actively supported by these projects. Please refer to the release documentation for [Node](https://github.com/nodejs/Release) and [Electron](https://electronjs.org/docs/tutorial/support) to see what is supported currently. + +## Bindings from other languages + +- [Rust](https://crates.io/crates/keytar) + +## Docs + +```javascript +const keytar = require('keytar') +``` + +Every function in keytar is asynchronous and returns a promise. The promise will be rejected with any error that occurs or will be resolved with the function's "yields" value. + +### getPassword(service, account) + +Get the stored password for the `service` and `account`. + +`service` - The string service name. + +`account` - The string account name. + +Yields the string password or `null` if an entry for the given service and account was not found. + +### setPassword(service, account, password) + +Save the `password` for the `service` and `account` to the keychain. Adds a new entry if necessary, or updates an existing entry if one exists. + +`service` - The string service name. + +`account` - The string account name. + +`password` - The string password. + +Yields nothing. + +### deletePassword(service, account) + +Delete the stored password for the `service` and `account`. + +`service` - The string service name. + +`account` - The string account name. + +Yields `true` if a password was deleted, or `false` if an entry with the given service and account was not found. + +### findCredentials(service) + +Find all accounts and password for the `service` in the keychain. + +`service` - The string service name. + +Yields an array of `{ account: 'foo', password: 'bar' }`. + +### findPassword(service) + +Find a password for the `service` in the keychain. This is ideal for scenarios where an `account` is not required. + +`service` - The string service name. + +Yields the string password, or `null` if an entry for the given service was not found. + diff --git a/lib/authentication/SecureStorage/keytar/binding.gyp b/lib/authentication/SecureStorage/keytar/binding.gyp new file mode 100644 index 000000000..77fbf4485 --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/binding.gyp @@ -0,0 +1,48 @@ +{ + 'targets': [ + { + 'target_name': 'keytar', + 'defines': [ + "NAPI_VERSION=<(napi_build_version)", + ], + 'cflags!': ['-fno-exceptions'], + 'cflags_cc!': ['-fno-exceptions'], + 'xcode_settings': {'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', + 'CLANG_CXX_LIBRARY': 'libc++', + 'MACOSX_DEPLOYMENT_TARGET': '10.7', + }, + 'msvs_settings': { + 'VCCLCompilerTool': {'ExceptionHandling': 1}, + }, + 'include_dirs': ["(e1pmqn-3 zWyQbMs?%-9lYd4L{(az>NvF$OYG+>E<{U>$Z_i{pTDo;WpTUN}K?8da>ek=TquYQ1 z1A`3RKQ{~t9$@G*z|gRHD?|T*JwLCKCr?gijkL#T>w{6nr!KPn&+a!ZYBi$Mu;WHB3CGMvWHF0gL4G8*Vcj!%5PWG33gew}dXzUZ?ZREV6Ut!^2TTL%;?Z2Pm7! zN_pyhb4lhRKeNsssIrjl@n%}fsgP4(2cFKUt4o@OT)MgxQeaNqq~^@f{@iluj5%~V zkB}TX4_jV3&*-lJ7Y)^bCvxfnNiPX~O$Wb9(C5Q~kY8g8`phP?@5E2_XVB^Vs|@Pd zEvOqJ;UFFboUiemj%TVrBh;yiMAK!e0f1Xhovsj`CGkx4XVmGUs{~5KC4K;)ueuI+ ze*6ZWu}U9_r_T>K`l2g{=j3$odJ<8mdjK)8ue#iLE`9?qx{8}yk6yiXx)y>*K&F`2 zy@6-!+OnZ%Yfqi74B?KNY}dbuS7p%PK|O#XWCqy@#n_x4-sk-W0`UU%39{6&KRe&R ztB>4&v+EKrv_#VM3xd$2I$c7UD~Q!@ zn^l*P^@N=+q0}AVeQ^oF+Hy#q$PX%wzXO#K0Vw-x3*eo$x7Q_nHwnpl^8i>o5d_q- z!0X|GVskqqZ)zg&0_;Gb<3t2ATOzr11fatXqS(R%Khk5+52PEQJuA&>4fB?YY4JbL6yH% z1C{$(5ObQ3yq|JHDD{@0-j6l_Fl-{I#F6};1yFXzUgRAi(N=vB>(U=V4p^>)Xm)Tp zh1aYgNZsuP0+HE)SD+%2U7jNO7~>|P^k*LmvTrX(17!@AtI#Zz=u;Fe^~er-F;+C~_l?MF(Fg=O4Fd9avk_ZH zo__lo0H>pnXLdl@GV>99TNr@->yX!X1Ijijg5;TPh`HoJv3b!T+G`||7o34IdmQq5 zS4Q$;7?LxVBQPvNFqA5~^&61)d;+2`*$nsdAT@0O04uK|R=hf(4%Fv;Q;=sz0aX42 zfH7_W96E#^1%CrTRx0bZ28b29h{``*54@09NcLU`K$TuV-dhjJVbf6Jvv{EFd5kKj z65!0rLz|+GCL00O_XA$QD$=8deVqX077Y<(eSo~U(m*ah7RaJ~tqq7RoQV>Xn*ya= zSHwaZ0;RDFf_enZ`4%W1!3ZvOMliP+@Jf$DES??AUJ7_+!VvR{0CIFiG^pKb1PgQ! zPeltF6wXfHUJsNq2N2{d4ZKNDf#S-hExC(e1ADoi(kf*~{i9`gbs5PeCXmlE5hyjO z5$zkI*y-UQ8afBboWFr`H`*8fT>vzva&^Ciy#7=HH%w{?ee(jk_%HxDJWy}$3LqL9 zi)51t2#z)fO7X`){?QIW^@=E)Zz)Pd=K|jCdWb#YsPI_@yq9B8Z;wYnnU;vaYZ##O z4FG)h6G;7b8+kuBMjdxnBJW`-1YHgRrTwP}gbfR=0F=2Fpj_CG5|>wi-a-og;${T3 z$>QyaDE12htG)o<(lN-({T-lV*n+LJC0p3YNmRX&34qoc59qf}2qsMj%8#1>xUnAu zF3_4~Wm`U*jbcsW5G1Ta@+PG)_#A>V9g+Om3Mx+I-x!+faV7*6OMy!9?#SzX04=?x z0=dL}5b&Ra;QKrf&(~i8Z}(&XekcOG<{VKS7NXu6H1*d45xaT;EiFSq&G{bC&0Zjy zg&ZHy5P*+VQ10XcXoCxYHkpao8EVc6j<E1_&@>irTI z#QHu!-U8ySO#+I)8-l^ayV4G^J}*J4bq639_!hP0U4~@BU;z5D`&|=}_tkX7f{!8g z=m?5gIafTm0m`12065(Yv00Z9EG`0+wVVwK9!JodgMIE!^zzFBC^o(|i1siduR4== zX|6}z12oHzKyLXbl4k-?`DKdnk`+Pbg$QcHr%qUs4YA(K5zOt3AkRurab656F}Dzu z{~kd(+JnkN5i3v$!GtwPK3|RC{4x-@_Y+!rC=`GV1rdvGiHbfuh6Zh9tMmaNI*c>y z)lLWswSe$EKL=noS>hUvyq1lCGWsV3OU{76y?FpMVsb});O(cWTFCx(VZAxpBRQYy zz5F4{zL*Q-8B>vTu8Cv=w&m*r2#Tx&a%3wI*hc8Zb4YHv1;8+81g**<$VuB-qA&t` zPIrYLBUX=&L&9h1Ol1Z1Rv$*}Y)2q}ItzeniHJ@76;)OuptH^b@6-YW8>lL+s{+uGQ~nStT*4%K9EE6AsIUb z$Uk2OUQ{K-mghszh?CqaD)pl}K#3#Kl7Aq`HxtS6-YDCgF3IHTsCRS>DvJIEdG4`* zezFy1J2ybmnd9GCy7bZvza-R%L`ORpfv56NBBh!-X#e`OFD2~zDi zOHSr=x1kSE{D&afm`ps@1(c^wLO-%zL9%x(B)ijW-aUn2*vAM;)kd+J2T)?i9N_gU z4FXmbL|d};i>@OUR2Z?t&Csg0?SX8Wfjp0;D0}W6itVH!o2m!2(|EKw%QyrZR|DmG z8w4(8K(9_H@bVT%i8+n znhE4RI8S$V2VmMM;I*J)7QY9S@Bc*b35jmtc=KSDjX6FRxPsK(mB_ovnK(2a4a&>8 z`#>X<2&Vx(cLspir=WbFdSCfGDw@|FC>v?6uXjOg$pX-GAnT6(z&3L#pZ+7rTUmJ_ zx^Ek@An8wEC9y7&ZK)t6{%X=4Sx%CI>*fGuejz!3o;pQdyB#rYV9AY~T95 zh)uZ$3$g2o z2yXTV;L>dnt$r7H!QBAWu?0V}EnANw*iEZf+={$ekAc#}7eSF0DCWmW>6f2D<-t0{ z?z3r8V*zz1(NE~3+f7I8<0>F<$qfx!wGSxm*~p&sa#vSJUeUsch0Q=-KxPEJmjF3) zH3Un!I@wQqU)BqF`TMYrSxDZYahr7m!OTCAw`B{0x)ucUUIK6KHK5pWe7MB}rNJ?f zDvu>>!ol6B$eEteQ?|4VhvaTf%$3&yp?DInTpEbzX32Fm*vAo&xmz%njnjxGR7 zd{+dw+XJQhHIN!j^KfS(f>~_=DA^Twndn{jivfWtCy~s&6oEG#v`MoO45kS>wI0FP z6(|u!YgTJFS}=~?Ur7(DI2rqJAnJIq3RLn<1R!t{0Ka5LP?DXgM%|6t1-#EVOi@Z+#L4IO9lCfVRdHp_$eazjITssi!#i_S8 zUF;*rfb#Syg8Cl;uLWl{m*Plf=OVZR)yIw^yT)Of$T_sj4*<-ljyxAy%z^EY9M=ud zBJ8<;F_f*k8_9KCM@^+(ITr)ort%1?(_I){1b9vt0q9EQ|9vw6C0NlTdby3iMl6=yeg$y+#lSXGIPlp~M~vWo&z()LjOYING7SWa63ZX!Cx$?8U|-xI%eM? z66!~L5Li_RfZ_2#_M^i$@G6qaDgc_$0(o^?B51c6bu=0VKUp$QwC6fM^N5X z55?9^2jI*kBqx1^VBUBj?_|@?d<*DidSqgaeXBHz&7q-q$<3+ebSrMq+J2h}F_nt> zBlFsl5%;JfH|-d#T>rLlAt&y^)LOfLt*Vct#qx zOPs-$4F&Q_Ga7VcD3aUQ(%5j&JCg$_qh5lF1D7(HeUX=M3P^sRkRA zm3t4x1^}-+#aJUVicJbfat!xr@^jLh(Fx?8w;=gT9h6yT0O<7) zfHSj@=Q0D(U;aRHC+Dq*>Bv(#&01OSGB3nFCc*H)Zs)Tn3<&K1&9g0?c8H~Wh^+E&A zR$KKbTY{5_QWnUew}JfIPXGjS?^@WB9?y~dZ3LiG>4*7ooOk4qoJ(hRP9$RXKclv% z^FgKhE9C8FBUg~IL+NE?T0&}BW5x8WX=H)D{zYL8fT^7KM&^lcJlxtf+R|6maC zE(B!18X(_*Gfv*(i0M}Yu%aE3*;#BRP5qW&Bs~rxHl{0rLH3}$h)Q#lojy)`nwR{` zaSF+XoHcq}M>3Xko@GChr|Sdo-3r8RT}I41KVs*J5=YOY%md{8YzO4c3W8i^ke7`f z{M|-qLF>i{8gl~wy*^4zy@q7&GYGmqM$ncf=*zZ1p3UKR?g@ep+?nYA5~Q-S;fbSx zQl8xCTmiv$?gpGY2~j*@-@KY4FF=nH?bxc=f{2ylFwO0OvN4?QMwAAMo-Orjj$jr| zeU(1Ivus5PT@xg~nTDYI1O&S|J*{BRt@OE?Wd_QH4gh@2ZI;zs8P;!!vR;&jx)~J> z=AKL$`aTD_8=x~F*_ZQC-c=}@gUV$p0D4#F0A(Ys<131+IK^|16aA?#L3xoYpqps~ zw{dw`pR-H8oPZ|%j#$in&15 zR!^5lAogkI?nkW8&j>09A!zUof=b+>w$%EvJ$H2=$@q}}kw(AsvJ=`gO{0HzHpCM*mguL#|JNYL{jN*XU)(<6K zP?fK94`p^X;?Z$^LD3fRM^JYsg2dHm%d*M{I^RK3H;#3j2Hs)|2=u2FWp8WIo{1V=cEe&#Oqr zP|;Vl1}D#OgJca`)x0JE_j(kcN#2W}dFNuRJGt$ZkL&Z!vy9QYk& zThpQciC)VKp=(?f&F8wO4)Zb}McL9c(mkmMw+Sso^0m3Se4b15hcs1lYarHsBJtXw zgYMi2_>(5GL>3?$SzB{TYt;b+J4oOe1-grP`DY{6Ud-Lx?M_^Y2K~-Os~7hfTzIl_ zbvcsd*Q3f`*8;`BbFhg&06LdS_&J;QLrnxjIVlb5i@b6i0fuZq{)MEznv7&Q))rj= zu{b-_@ku4bKDvft+bP-@ZY7@0kDx#IzLJ^&u<08BN;)E_#^KUwID+FPk?cSN^_;Wc zqqQJk)ef<*j-c!-j@9kAkSx^{u~poa4D$kVJcnNo+TF#R(E2|@BOlQz$`XQNO}OHl z(-uk7FMzt|K`iec#EQ_1Y<&^P-yKJ+<{%*Na6&Mh4*fi??nFoI(~VHyk;-Z`d@E>R6M9Q-$sM5H z#{l?xB$6BI02;jxK`C0UCri<)(Q5%6PcOsuApoa1pXca?pfYF9F|UvpTNGtqk)7K& zp{3t*&m$*&i|3p$j(mpL!v4Uk!WQgh!#8t8m7?+8ikln>wdpbLZ;ZTLxqxzNCt^OQ z04+Ec$c4Fg*ujLn8C0ZUNuW29p2ysiD7KWHUY`%pKRyEV7Ox6?N`t2)B6*vw%1?hI zg52#ymuX}_)RDOaO0=JgAezi6MXrsj3_!WuC=tbzkeD8*qt`6*-U$G44))D7K<9F= z)T=%6!uun*lmkK0Z;^L_$3HhoU>@%uG@+M~Z#t5WJgw?G5Y1RekK%q^1b$NixK{;v z_2}IM)3QFJN);_X@$;$pCy#JU4FSxzjuRGaPt&dH^^3AXaBM z@>bDV^yV1sMAeInM{)sgpNyt>)(-{IdjpW{!YRv=6R~T15OZCFpb+hS#orKklm=kn zImEV-Ic;J@~T5uO-gR21QOZoQh zh7!lP>9m%eo=x37$F6o*gII|l0nHtZWPy`N4!DD$^GBf4@CW3Toq%Majwm+g3$$;4 z0P5(N2YI)C2TCSNFlZhKl;tt+0yaGCE|P8sQFaV9F>_0l=raY$Xf89{FM~??{s3&) zj991V2&{Ddb`C`_oUQt}31WTO`X^TbEkPZ>EcPR=fV(vhA$fqq#rOs2wTnYgpKLn7 zwiKKQz-Khqlh>f$$MHzI@mOLL+xI6mEE6{>F4ORQmkqHeLl6sNr?)Rdkc<9Ccg{k4 zISIF>#@5-3SQl=n{rUo}I-MQCIr@{o#UMzq0I;GV0(V-5*u04Kp%2%OTl_z+14^^= zXhxr>Xn}7KQ09?9(G@`Xl#3dF&e#<=rB?C=z{0JFByPuyyoqG_&rxC#ciNoDoU2ro zLyH0Zc_)&WIluMoj@UXX>st15R1PHPaWiurZYL(ZItK#ttsp<^36M{5@)}MO+m=(?=X4iF(IsBk7${wcvg1?IW9wawNFF1vRxUy1kGPLH<~NjG_6uSsxz)4i++?aVrU7Pq3lJ#jP%k@U` z#1@n&K$pE9m${F*+Y?Ans{zO0DLW*uTR`eWMZ_9B2A~PI@1{OLTTHu=_pl!D7H>fE z@k#)O4Fk$yZgn=JM=`Yr1b|SEo-*8eX~7Y7nw{>=Iv!B3 zMn6Jq{xnd2NVeag+SZ5ym1rt!9MAm6^+b?^qoNa6EUQ-_C`5*}r++_*OO#o!Q1;X= zB=ga+cA1K@%{ivKa}GVz6VN+Z5xdRP(%4^-Y|ptOoIDuAMfC(yX~8@vuA{yu<@!{R zifqP9ZZ12}#V*7BoP$FVTM`JsQ`(%bh_ZVc%Gy(#o~}S=_Hi*)q7s5py?{LCA!0+W z0Wh5QJ@?HGkP991|c}~2T-oNqpS-T7YBJl zIqd}U90&>nU$=NJpo{VY`pgAXKHCVusxT1P(F1_Z+ykAWM;)iU5nQJtIb{Lh zDRsBmEkG}9MV@H~@*2}X*awOt;GVl@u}aDXS(cT_+N)IxA<8>;L-A3+ia z(?YI#Yt8_2?K23RmjKzF%_u|HxkLm|3OWFAk1l)tqX<4-g%U?D0x*Sws`&tT`N*qb z{ZXtcZ+5L(3@Ww#fb7gpf7TPR>Lm4Q3xa12fP9$#?vqjo&TzoyrmmUEy2bQQ`_w>{ zANwL%wg*sdwMT3YHx<?!jb$_9s{!vDuCjhpffqIwfFqd@{80jUUvQco zy9p?l*CV!iCFr%)0lI-+>6-0`jbUNpuo>iqH8-q zFE&Qr!JmQRu?>K4Xub|{Sl=D`vAu=1Uq<`oiqTk zp~VnPpl(##3M$(tBH5Hq!ta%lx0c1S-au?&K>(@@MzNE3k>^CCTA?#yy-opn(Pf|* zh_{U!lI8Csh=>C;fcGf+a##0keUR_Q4UJ)(qrTyMxqvOuw?*v429(&;8nJA&Yx;^n z)^Url*w+X;aPe6C1OS0taP++cp-iI$gQ;c>IkU%cz}~t6K%W4Vc!|sV3CGFARou@1 zmIF4DBdRb5&J${EpDKv8<_Tp}s!HApK(1C8^{SZwjhg`~ZF%ak;XH!MT|r2F5z8=8lboEMIcMGzT^;CLSZ%5y_J6FY6lg6kKyG);Gb3+A1cHc}s8@Fx^a^wD^*1u7|2@<@ogQ*i?xBpMG3wI+#X?x`J?d!( zuFGcJM9f6S&Z8gJVK1N+$=F96e!D2&Pl#O3A9YOP$zHqtsB&i(1Vy;rmYa5?FSmg< z@@#B4yZ_Ri{qP2~-Xa7M^vs9#MQnK-P^v#ca%>=yYuX@KT>;1whJgIinE>>oL$GT! z@}`L~%{ebCH>U~@K}DH2uzkNFd4y{wcaD#?nE?o+Z9h*oJtglio&a9(pMZAa@ps%n zAjeKao}LCJoQtXNzC%zx3-VUBLY3#|BKb{61S75k`7zh*^Ctm1aT5p}8i$x2Yn#tS z!)luA>fBGXd<}pL*DmheKsi6#;!O*jl^0aL`4#k@FgC-Ayyy;yjrjv*_i&YJ;jC7i zGt>9HUi}5vs~5OV(X9cg!L@`#TB5;0*yn&Sv8%It?u!APru&SdG zD^IQanfrw6r=#96JQMEK1%T^25i1@FyfNI0ZNg)n8uLNwG+jw6JJVzsDxX0ycH-o} z?RSuB!t;vuO@UmQqP@zl?xCsQuo5Lg&Vcf5&Z`4{Lu_Ryl!%N5-a?wMX#;_07mK_g z`d77REsBzpJ6ZthM3$W6a;_IG+*EhaJHHmtbH4-mcW%iCbG9;28MaZh%Lb#^2Hpor zNy%c-e-i~ID%qhe*j>12%1rBHuAc>KycC# zfJyW=@AU$`UiJu1mPPP!X#oDnjMypO>YQ;JqynZQwyiYsF0%W(gF){RR|$1^ZeKl+ zb#OQNGWXZ2(i~2s5=Qhx5Xo61hW^zPj?n&GjoH({x2k|4Ien@5~pgy_Lf+wv}_W=El{g_LaL~g#Joj7{+$kU3+lo6Y)CdI{}$%~%Gf-JZEufYHTCMx$%uVUU5lOq=x4W) zSBR3S#<4JpU1%=G^c(?43yboReau@OlZ>CxcHC{LlZq%|^8AuNk88BlM0hm~n24#*Bu}M#X$lF+W! z>^_VUF>_5poHA4WO*Iw}qg5EoK6nHxGQiutfr zzhQ_F{RonFQIKs=A{vqnt(|?-blrnm_;+2ersmmYwK_O9barvbmtC-6lCx+QxR80Z zR3E&hOZ8#Lco$*({UMH03-gi=o{MFSE!arA%zbRpC)i%{=*}5s2dm(I= zd9(8gJblb3z0J`|gcu4J$u98axsMqNa6+)`t6;&hu4JN%V5j>j0?tBrFp6B6&vB)m z-lC~O$}oDd5?R{t>C!Pq4wk7LTNeG3#j@jW>c&_xdIVqG)Ikz_E*bm{!SC~DYz12( z`)ap+qt^R|&VfE=1xDsVL-w%+VmYk(>p`NEPU|yKlLM*A^<>*w9xXQ)VB-zyY3jE{ zUt4RPL4ADSom;2LL+Y+wd0UIdJ4c}o#ryzmQp~lf!Y)+kiZCNWpgl>ijruJk;qY8T^q%aXR<06NoN#0OvF!%>C}4L(X%+vMMB4j(E*WI z2wi6~A2*p}6>}>vE0wYQ!D{oUcV_E5s|E+XJx2sSw*-FMEm^PW#CT^nk#j)_9qy+K z&V`A}>T5{AYsNquZm(EcD1i7o4$2CJQ8bg{=_drxb&wPQUgOn?(IdtKhX|z81VBs+ z6c9~;7(&z|qqjDEjoj>KGOC!C&w@UAO6j4LATCKet2HMT8X0Pkz zFh>YxsEMDy!$qvRVVbMYPFsD^eLa$v@A{5MR`(0wxBj2KpYM;%2 z*-~SxcAjlP6jSM!jtXW2@i#^>L;0V3yT&SY_Bo7mBJ(2pQOJFql!zc_#T0?*$;VQ+ zkT?8^&_fPNou7t&qL`1e+{pw^uXWU+6%|X?ik!#moKPI4WFjtY3!!Ly2Qff~=pIBE~rS zSQ^18>*}PKk13(A90#ExrC`|A=9sq?OPfr#IS>do`J z!Zw^!omecQmY5FFRmF^so6P7hSZeU>(zRoZ8a$tD%@3dChB6tv@8a3Tvoq|zI%6&+TYUq==OFan;`_%1Y2U>V6N`i-a@K73r(UZ*Ykz6d@d;f}XlGA@S)2Z|n__mb>VNJh!P5n}HF5zj zVzM-~Z)h=MO2iDgN<+cde?S35=~Wo4`i&w#7)h82X(Q=s{DjHQWSQ^GCVQJZ!f782 z58xLVTZ_JVMc8gjo&Y@5KupnCX27kNlSpGRNcC&x$hp&~2J9A7YvE*TTux$qEig0- z-2g~OK>2`+pj^)tlnasahyJ5H9BKQU+R;jKa(SUdfI}CsssX^$NeLa{iWO{z-JeEo z+SeR9!mu|=Gt1lXZ<=|k96E+3w7!P5>XuaUT z@0{S4>HKGB z5HUBmx9Uft3dZQaEN3;A#t<9F0SqIiQoHt($Tj%?CQF`Ph||G=(LZa|8@^!cg3*+! z+S*8T1j>F3(<+snU4^ncd7JyDQg{wGcn>-N)qq8yZqXl|DcuW^H({sHaBU6MNMfuO z7+h5Kmf(}5K~Ge5mKYHl4UtzLNFPLiZy}<|H;6`wMiTO~mkxus`M$UL8K!p=Bl*V-j-&8wCHEe$o95Ojuaw3r^ae&u`6LNq%Hv~BfaUF3q_?4z#79> zO6bwYHO0D`J zkssUxjH+0MirxUaVpmT@;YiyBl@*yTuaoav&GNRNM?*2+*}!o( zc0aiQFQp3&?^#l_>6Fudp`z4v2qUxDI2-DY_2Z4+wQ&N12Yu9hf{0!6dD z2Z2S)+fUhYr4%}J(+FJS;*Gz|X| z!ltbzo6iAE<886aBN*=K0yH<^xZ!D3;yeY5edvASySrEld4mS_2#$Nf!?fyWe=gKw zd?;XwWx8_+pIjnkmw+%iRW^|8TdstN!LoF7go%Ojp-$Lk1|AHI!k@-c)i*Pcnd4{G zmlOnpJKJbrVs_H#SoQfN(8*-!L?H=JjA+ zqL$Z7<~3*DIp+QAf2r*WOoX-443V&7BUC^ncZc7F&7WyAa^%*d39P)^PV6NDj& zm@pgMLMn<6%jETZm64xJgMdCVSwa_Qn2SYFk_%YKtMd ze6r0J_mEpFDNe9KVuT3{%@o%Y7TuzcE+Ht_hG5lvr2H@bY5E3#Shxb3{e|WeF?>c{qNPu0`ZW$rwdt2wjoTLD@8BN1!3i{H zcu~#*VnS#pqA<^UZJq|;*NYI2Oq}n?lM5RV)UY3mWdOF&Ff(AQ4O^6zvH8kfO55_( zWcC!B4BoEs@aN?wLuu}XE`sI2bnb|5aawm0(|H!`lq#Z_#TiR~u1O=7*}`V*QOo!nH#+(2l9;(8wVi2hM( zXj#R4o8-`QN$8X*$OC%UKmVN|z{$lfBLz3mmazg`1ie z>VjpFsWX;E5hGD$D}Nz-s8LhpZNl$NCSSlxA4ReHY9Ll$#_*9CmaRPK1Q#@Vj5G%4 z1TDDHft^Gh(9~AKv=ZndfKFC@D+$C<>cj=JSeurNcvmr{>2vCYraui;?+A`Q^$oyA;~{PZ8LgoC<&pCZ^HTD_#qDi zQ;~K`hxE{@Bs+s-&4)oQghcR%DCx*C87Qqnf+I$(Y9Ia|aK$#Bu=}ssE7}XUw>8p- zjZC8ZZ(Dy@><$(LN8=i#EJL{Q0LuZfJB5ri=!9gkIvU;qVuyVby^_Yw3*K95DgAX^ z>~GsnwAz6Z7T|VJ4;LVgrN4w+>6?}FZI@*lgGl2Q$$$n*D+)@`g& z-$7d4F`m^9@SoCY*I#9&w3mJR&-Jw~oBHAP^;c|ozXJ#SVH#Awuz$pXw46!SS9>x8 zs#Q2-xT7vO2c`q7zLcNPEc+DAN?RDIWPTpjr{ZTkN+gf}^-R2N{PQSGjDIe!<3gj6 zB}Qo|332?d;Dh5I*2PR!dnrzYX2)xz0Y{d9h zSHatQgNq+7Bh7do+BWTYu2n#cXJ0&2zx21+|5hIyKo6G2UT{iSnl~DrtPg!zmu-Ae zhBk>s{3Ct1Oh5cz(}%Al^(b}-e;-O8Dv<2kXPdLLJuvu zozGsEyuJTEUc+LvfmUNHmc$TV6q5Y=0CH?fvRz5`@8qan#le;FNgVlcf)&HdtRxD> zr1rD6j`?6RPT`-F$Fe}1JbXp{$JJFc-&-C}9c^P4QqgAd4nZXM4`*?~z0#r~e`6KZ zMHnX<_k@K2_wHcvDfU}aywqV|{RiAj;TQBR&fx>;TO+pe!|U6<>FoU9acm$4+iUu^ zQxr<0Z;eL(2OLW^SP@ObzuS4z@b8~nbsooXU}a;QKe$!5S%Ved{43IFL9%}g1EH9ES`f( zI*rg@!G^0%gr8mtH)RyFk1wxxJi?@h!$oq_vn!98I(FuYd`os{i6zfjJk*)6Heyp7 z-1J$m4j6|L7X42{xu=bEBs{f9alhP0r?!y5trDnH2Lp(*;y$In>Mo(P1(ZkPttA*o z;!G8k;Ni*O8WPM~hyvjud{|WNmyA%52>&DhjDMl8M<%?BzE<&mCw;xAyr;e{KtU?o z>-u_D))y_`nYk54>TbK${>FXXi#Za2E z!J58alLvHAN$Be$3Ct#eIyDBs6nzbqP&J4}si8|GSku>@5_~Wj945iZ`r1GutVl-a zNreBAf83Mj-Qt}v1lZ>=q&gZA?d5#$$o=y`7~SmSH6?Dy1ECAthQ=ju2EM$U?Z=G{ zV>q)cQzJ<)bZ;Onol)IA&}t2RmdPOuzfTFCl2f=p?kDe$3kn93aTAxlZDb5@ye~s( z7}Pn##5okUw?W&0Yo|fQNzx$SBoXge;QA{}uR2g*!U%eZ-GRE?$bpSCq`JSH?mHy? z)&1DIPRt$pEVILm=y0(!L|f`7$k<**F}{tAK^+Y;tkIt~Hv|(sFLs0r*6a_&?X8zz zqAThXhW{P)NF&c$kFaB%BF`0+!28H^EyyIxbN$da z>cvH@*IeJy&r6RKF5+C=fv+YK938`_mQVFw&hdgx&D3S`7`#m zljV6W_zih>8bEorW%z$Vp0mDsM|qkoV+9LRn_akq>PhrSi1qvTFuM+=8e%n_{H~(3 zy(I>}t85<*BIf(ZRvDjKwkO_KwwXXCS+-fBX|LJd5ZJItbp*rzj%-;=8vDC#)PE@7 zo3MvMzUw}ed_Uz>^iE^9fWSMn5t|`*C4TKbrFltgu2PA0Q@+$n9sybMUccY53AGJKp+W6LWP3_ z*5Mpq75T#3H@vwzRpjavcU!|n1;X3M4LypGc%?;qp$qG3 zQB{Af35P{_zT7KUr&vbI)hT-FDVtM5u1>`pyKOOn!rLdeQr4zLo@Yll@_d4a`U3N? z@b$qipD6VdtP*_vT7AG)rXS(*4K$3tev-OH0*gvul6nq6o3HPy&XUlV0W69|x4K<| zg|F|c4wK-YlfiQ&m}`B3-cBO?kc=>l2>)aLcpoLRc(pyEzT=y(x2Ls76^13-qX2QX zMprp>xKZa2CN2kt?!^V1+B%2vhagUq#je&qhr%V zz0axDG7?$5j9=$jkT-N1m%`;GC5Kc8tWJEPi}x&2-?tjYP2FnPvY^r_c(>WX(S+qj zzUGdJctxJ8krT*+m8YjJ7 zuYXUX*k2oaCq#@6yA?x{*&hf|DG~YbmM2(x!DPX!Ddu>qzFuvP=wMuA!VaSLPH-hQ zc%xA)nW|2M+msZd>&uJR~N5f?3zlWAxCV!oVFP z3{-Cov=E@guN1Qv2CV+Khfu1pXl?DMIC!0a57Nk^Zsy>pCW{Z=>W5|fN~?V_3YvWq zLlZIwIfo`>3Mv(vkR_;S=<`fLdXw2J4)|lVw_aPLL}G#0G8=1T2C@^pJY})#`5-$k zZI5(n7(Nm!QgNC8OJwm1n#FE8n-T(|mMQtA2|{<$$2l1{`SW)KI(uhB{XWV6cI&*+&b67!#sm zr9O5)W$oFutK0|tls&cN$%cnI8IvwAoL3|tEO{Q>N8Si6?*J0WyTZI)THbY;cZhi{ zwY(a#>{jO0)ABrJ-eTre((*>jyvcZ|g|xh>GH(R)GBfXg(;wc)O&&*faf7r0E?Q7`AhUhp0J56@u^8!i-BxT@r1w3LYJJ4Or`+%ktG3zdrpERYBj2^V9QkhQ z?SFEA2j4sKF~^I~5a1gO2NkQoV;XiV=FISO6n>x~9zgpvKqQ1clgedx{>$XS>4D+6vAgS)Fz*U3FefKU)Ti*Ua?_h6>hl!*I%96SMbW}FL~v!?!ubk z^)CIRH2r(LTA2Lu(&@lt9$Z7^eA^J0R&ZsLGbCmn@p5Mc*^@y`VkSDSo`-L3;+Iy; z->}KJhO`|IoHt0sFSx975vpO;Kd3I)P@3JnMr2H4g?h95^PPp~Cto2FFK*7fCx+|y zc&OWW>`g*w1=os`;WcBFKkO=bVN}1zO`=G&fK@9N?T&hY#5yXlw7dx)@XFEa{F^@T z9r$;JDVu@cMlKs z>4>!aI|eTmoN@1D-zDzEYH zJmxTsf1>qf^9jMfW)d+C{~mlK3a8;;q3-GPZ{}~({^6l+(;jep<6 zK$3r~I+=d~66>hIve`dc(hu~9{e%FVw0!%8#x|bzikX6+e{n){cn%E<|8Y08HgtbL zy5}`~zd=kw!t|K!n%k(^KI_Ae%6MQM$9t2jE$w?eDuljKp!7HAR<3Oo8+3I0?%OmAWKk1&eR8sx8R>ABQ#nzy2 ze*TcYWxjY>TE2}v*dRVVpdR%T)yV1FSG~kxV$mDhOOg4iFKJUg=pXeN=U>U+=gG=l z1b6X$H#e>t@J7jNlX(YMGRYy#EO^`1p8Ruj*g8wf0^j>uR4D~P98)RgSq6Y>!H-KL#q zYum+;6A+LThh2}}nt;5ZwD)boF;Z1=A!K(&$@}S8GAZURaIg-0$agx&CkS!QoXzgJ z&Wz+^?~80g`>py{F0$N6l=E`G>1BSTnD-Dzerlx79u{*LA1-Kc+bKj{Ya&xE?F?c^ zYN1RC_ZB*^RHL_)?SP88aTh~)y&hN*hA5$kXvJD+#r#+d z27)^vmNro+wp|p9VlnK-d94@4nrp>gv3aNs7Dn636UVcDPzI?l@SoKtEjaob0?DFZ zCbWpTA2S!m$HU7UD{jA_HAanW1ju??vFF%kyV%jGCboioqEhX`r2mbtCMc+OpskPi ze7zFqwVfxwv0hOSO`F-NNrk+Xlocga2ar-i_l5*Eww28a;1TtE*<_-eP=Ayt&bIQ`aaf7rD}jq8FuM)7KQ%B+ z0)J~I8g@cmo*Eb+fk$n?uK`52WV4z|;CcxRQTwyx|6hN}^98S>Vj@4yWw@L#lAxlg z<_m~fn50VOqy}CU;O1gsC}v}WRX@O4!uZuUG3k0tr2Yi8P%N`(eZ;qF_??>kikUMF zmXs#*#3({&F4}3uPctK}m2q&vtb~uUiHV%X;I%pEvQ|`%pOjHBUgXO;NOTAzVFhMo z&Ozd{Vq^ES=VG<#a$TsuCmyOd=6Ep&q1$q%S4(sf8a}QC^-RmFgMDHcOZlL^wv31U`1#7!s zI8v)3@*TqXWfR&Bc=d7_Xj@3V(h#N!nWngyOC>=ZFicARB1P7rOcA&R{GMEn>21pkF;HQPCHlR@%71nt1aooDE?TtPK#P9^#b&RO*VrGymP zV@#V+s2oCdptoH3tpr`~NBCv0@1G8`xvx*~^GDpTS11FeCyVoi6-s<;55i<<)e{ zpAfmM|Js}I)aPU29W{C26QW`h8skCxR_;e7g$N4KR}){#Ey&s9jZ?8zZ3Oomno8~& z)WbA8fA=TqPhz{wcJ{XV$IFdYv61VTdLy?>3DJz+O6W)@T~I0N2PA!1wdYi4#wNG9 zDPE}dmss7oO2)*CN!zNgEc3*`6KsH9_`>H#A6UE4i}M$RUfjn+eU9C-6umI2Cpbtg z`Wj7S&y4DQ91FrR!^ajdw?=}5x>lm(7bsfZVPO4T_umTRe1=bl^m8_7AMIK%d3Bj< zayfRQM9xL7#<0C_biWI1I5^r>cY~MvL0rdAmSjvZvQS>cS0Y@+_wTfiYZ${_am$pZ z5YoU$!}002Oy;9F`gI6$8B$CTIYDlJ>J47tyLo^SEfM!yiG`I>{i8~q=R~L)bXT@#aVIgL5kpxs-@j_6fWqB9>)Vy#v^TZ~Qq@ z4}|sLKp_m5SLPLw`ayRYSBTy0co=&PiJ)M77t_&XX^gWVtW(1w6ZIB%J7r;vGLq!3 zqE+7uMDVp?gD%LJx{#u7NnHT5rmeuIC}3+*7%Jle8gFXkO3ba8`Tapyb>T$Irig=M z`8iF|X^iFZK5WT+XJGEo10$ICwhiD5HbXw0r#pZPH_V$TNfL0t*?*6GlBeJA%X?;LwjepPzya z?S#!MTfXfn{B!YrP}no=yD@!W50XscflPVB1ST!O|R z;U2Z)N2~lBqttooF!2Gi%*W){;X)5OD0PnWyIy$_yL=VhEFkbx<}-Gp!C7{xbt zg(>TV-I7pz=&>t4SExod1$))q@ltwjBrF#M{nE$@wPNQ?`^>|qLmZUj5Gflo=mIi z-A`HLekHk{zIO8LHZP50N|xBi3+6Y)_Us0*0e^^H1` zi6Nqx4~bX%60%6G_lCXGzIvsk_X8$k{%)haVmJ1VHhY(3lT**$c*E}g4o4`Nw^_v* zwt4`~E;oWSvcz7oa-(&sO1HXQP8!((C#5I_u zU<$3g{4yu}0$OF z%7neHF=Zn^k_=Cc+>>w9b&e5Ipf@sts~7nuoUd9DV*-YJvQZj(TvWhGX=?fX+wru& zzfsdSSz=?y zV8-je#E~5a2^{M8ndFe0>ViWas5N#NAqG{YZ-@0yGB^jp@Bf#2ec{6G0cw59?{SD_ zhPKA=l$}ofdmQV$L=VV2UMndeXP$<#jVtTPE*R9$)0t@gqRC?Z;dxVt+yj`-{RlY{ z14RyhdI!!^CdKT*N!KkK zl%(5&Y(y8wAz^V*A+$!85pDb^r-CIIU%#QCphW3uv7%%1RT!3`>EelD_b8%{MuLZ_0p zy{7i|raGR6!C2dRx)9&3i8*()m>#%x_DFP<>ts18U|TXUkFYMVv^2cvfq{6Ur~%T4 z6%oH~q{$xAtw61V8K&eRT{eXq(DVXB>JoH9us~hS;cC%4){z6#s2;(A#eXIu_6O@< ztR>ngmNm}M1emltQB*Vh{uP(nWJXvrFR*37&rqUITr6_`h-UJdxIP`P)`Ia1eU{Z> zyn`SBsvMCXp4*+-GmF005!g{qd82d7LGxo4`h8%I*yYpa%|HM#<8WU6fpD=j0g}IZ z0J~FgZJHmYITnY8%n=>toOCwF4s0^ZXlfYuEU}*n&&)M8YrT87jiIY&iC+l+}MFkwjl_0y` z{JAxUiTt)g0*_x)7!J#GT+Ph`mp5MtXtSPta#62hEJp4SmUmc1V1ie;I}#mKl)Q%8 zt=C(!G`AjuCbiC*VL`ae5YS)D4D_?T5JVzk39O~I;w7g=Zyu%Bb_Hjm_Q zXmpNIvtm(pME$b{Lg5?w7}dOLe#yYFqx&! zt3?h$`GFiKkt^Gf6Tl&8o_rN%l>|E2fJeAU5Vb{0$m1GX?L09#qIOQHqgJXqdPwAW ziJYW{31l}SXZ(Fw4y2i1`Z-5pa*=+Z-H3+T?dTt3P7_E@l=- zj$^*{l6GdvO?%BV!Lr$;m52sj+L;BwLIA=uq!rmsxNTEKr+T{H^+fc4_Ti zMWoqce%eKwS{$^grMZ0q-<;H@7MQKWY8!0crf0UIq}g)8D2?0^k3#BRXJFdQRv~&? z25|`oCM!<`5;+fV>k?^>rS~Z(qQk1mRWn&w4rv!=G#e9@%4DT`Rj#7?5sjZ2t0*6T z-a)BSTN)UuL|Oy$T{VtuaWBJB-9#tIqIaq;2DhVnri~o-(drxt`LmjUM60_9QG1EP z!n7E%(3hqqTJ0y1Puh?t6ZwDH-(QcXN}lgBo@(+Cg_9CY;NOj>ANFbE>8H$pGoE4r zOn*ET!+3?VFO9J&yBJSDaMFCw@$>*Al;bHUT9$e|?fb!2#b1o4;cR3oSM5Tke=?rz zc(|F48=#G+^OzzvH{i?Cz)XKU32vl}r)pxV6u$Febssn-T!8l(Pd{@-kTRaGU<%`e z{pNUTRVCGU>VaX0@f2T08&6@_<=`|Lt$ItyIthtZ`x2rS5{1QhN~+2VIaNoi#U=7s z8*)7&|1bMXGoIGGzW(`C8&Ypw|L_0rj>bzzBgN_Im7u8yn{`v>NzgYj&6D+<%GO5--oHqYC zi{<(U;t}hg-Dz2zW4o=2^jW<3RazF8M*6?G{=t$jJsGW+GP;Vb@W>rWbR>oq2d2&N zy}ACm&*f37^^cf^we`YlR}>aTbzUXbOrwhRk3_C)Lr#zvaPOgW#5!g#^P+E=w8 zrj%Vq@ePdxoJZkwsPA(s3pNgUs)J3ogIFA?jf?W!sUEBeymPK>FR&4Hnz`xRkvgn&6gR>F*KlD%dM?BAwJHU4PKTg)%5QxCGa?e3u z0NbFWpHL}+@gv4qqT;1*u?LEcI$ZCBghUA}`)XkcnQFhAq&*x;zW$!yg>m90*>eK(WFGUfIizFq?*F{rMx zMUiD?iwvsitt}G#!}#asI@E%j>nFrI-fo1u#>uc~^xyVkwcK2HOIgt$S3|iq0q62! zbA&-z zi%$slKOT|2Jlf*Tqlu2=85fqgP`vPA|$)Kotw)0$Zu?!Qd#+R(5f}OJ7U1$&>!RbXUwfYD2NzN@q%FHwJxuv8OcO zS;y`BvHLj+x_0Rtlj7$4Q+zYIZ;-OwP8MIZ6ki{VK!^_{L=S|-dx#?O>Q2~IA->V6 z$483zyulqD&1->U_2J|%n?c;VwIx>X_IV5=^8@WS8^=cJI zV1l=$`S$EC=OJ7AS*AZ0Y);6;a#pdcq>dX<1;hI)GK0AZSCyO#09JolUEf^ zsX3!d>BwK4s_-i}>I9C|h|!MVi<3N2;mFXKtnGG2ry`Z^Zf9%tGf5_yy|G@=B%`tS z=a;DDP4@0(_M7Y-nlE8FAnMoXc%(WW;Su#KhI0K8s7~hi!ufx34sM@7bv>3dTpJkF zAPKo3AqI6OA*!b+Oa`mPN}{M(e;Cxp5_ydcxet(`U|fF~)JhUK#RfEKbp)!85)y2y zy}GF5=VGD_tYce=lsbMXFPf^@$k?T>BUS=kZ9o-!9_&Y;x<*3s+3Gk(h&mi~M5=>D z*q`-f{QW=70pZVSzNkkfsJdK5g>XU;_ec06UBOxLeSCOxImDrcRbSx_C%E7eu;m8D zoZ^RmZ-5>qzqlf=Ke?%1JQuO(R~6wvqU!d-uHL({6!$N2$r6_<;ql@sue@~GK*a@2 z{EJJMNopQWB%%8~(z%|3`;`5haUWZJ{{R<@y?F~%_=dQ_7(XbBj~R|Mek#hfCB97u>zG}!6t_2-58xaJUw2d+)!{u~S1=3ciG}EA z%A5VXT&N~sm58kxUWio)$%fAyqBV`292~RbQ;80a&GBWlX2@ym7>?~~yfPgGuPd&x zFp}t!+uvXAdV)@> z6Q29jdFC+wnwa#x9lfn_3V!Jno$^)oKF`KCA#h8bKVyx%%3Myn?lVR7#5_?aen=iA zE;br;@T1NZ603oEIlawKz3ar`&GjVjI!O)_!$@@Rt!&EJKXr~e9e!ICm`a^v4ioxv zni!JW{ZDL*jk`u5)zHEO>t`te7oETXDn$z6p?J*8~4dGD9YiFoP0|OLf%nGZtG@ zqm>xc8JLkbFwvl*xTgjYe{Kw^IEdSJ)Wntk_Zl(N>A5U_>&!PJBbXx}8nw&4x1KFHB4`;&9XCuot|l4g z%TW>alVZ6}I?2gu|na7TkiH(PK?K+(6HxTe~SLb>O zaoWqd{>=e4cCHoTn3@H4Zr;Sy-QF`)ge&b_|CHphb+gIqd}pRcoh(DqBq3OnmzF~l zBH~wHXPAeh4^k=kE2tYWUy6V%b9sv3ZIA!`@rd-6uNB{nN5ENrj4@&(?c{d*5i|K7 z$FVi)t1SF`4n+Z_#`G%bB%Z8N#6NjulqNLD-X}l=z^oV*i4~O+ncz}T;HvjtyVqOa z(3d1-+tbGJspC#FYCo896S_BJP^a;97UgR@XB=xRJx1W*a5RgUeu>M*!FxzCQj@^J zx52?N+k0x34U;68O>H|ky~9YI#kP$dn#{6?BM6yopYh*4Pe?qTfvQZ(!GH=wd(B85 zuF>;4_JO=)B|W369xdBd{x0IRy^T;9^B7-iq2|f_3Qr!d zd2)sm3vXuWji;)$;X+MhUA1q0u>I@r*JI;;#h;b1MCM`}5%6cXVBmQ1*)^WXjr?+N z%QX%y_!kA!lMgudW-GPS1bcJAXbo@E>X`cAUBhHA&o^8dK0S$x>A| zsUHrNhOQH4KcPf!^BSBvZ6m+I{jL{}RbCn^>rbXdPMtlF7G#`)A$~}sr&1!F(p z4eKAd|3CW^{Pv4|<6K*8BT)E8l$@J%FWh$@ZX;0mpoqC4YQD>cEQnbKZz3bw;15pk zt(Rz3OaHjzZvIh`LlCD@yuvN)nRq)Z!X>H%*+AbMA{u28@d*}t6vF#N`9v5FoI*pi zy9J*2XaQmfYvyyr5x&DPPwX2;+1RE78fCXXdk}E(Jga8c(@7egRtfodW$_xcP(`DlNw+H1r`&5Y|l?9cM1QUl>NMv zZSR+|PF*N;#J5^5TuanXbvbCG4FRu&sL+3vc7vne`l+X?%CUSy9U zgT#IA0}a&sDn^19kcdr!KN7y_5&}4(T2+^VuZz?qe%Gqypz&H2mHYoM{{<$V2Xzwc z#|*nomiVGT2;t(wQZh@I#5xpVryyHfHF_?x}a&SG&X_gnWtYGfx9d2BKT zR_H*$@V7~t)2T+`X!59QbXVfnqobxI^1$Aj8#b131U8(q#0-yZ`sun zvE}u4L{crUdvAY|Dpd0kS$1UYEtJn^3F6J5MIfAj5j+DS>3@^VApzwi-BG!lD%J$U zFnu9&v>%;CrTPI2IAQdYgjN1mug0-1+@*14{WNaoL29$sS7Q50m%X<{CPepzkUw>O zk)ZfS+O}3T%Kd-9U*7o{t3bT_1xDEa56ZB`W7wE#i&f!Q`;)3(6_URjscItIpnC~b zB&6z!)Zc-!B~nd9{ZqGD{Sat~K=tv_az&t;ctk!ALtMnf4RY(D_|pvcZ}5m}`Zy*fjUZ)8wa1M&l5_$h!$ zlV-tavQ4rHc|PF!WdOreEzN;mzri^nztgCCg`nyR)-$+21C_OEslI<)e*g3SdYuQU zz~FKrg{J$-p&1NjjR*!KEPu4Sg~7vnK;hji4C*$iDzE`0UTN8GITYnJAS6iqRq?ac zNDQ&c31XY}io{p8TPVux!&fdcCZx71<$1psGzJnli_>KF+Rv3#Mchga;S*QvpU1g zh`SExJRG4uUFQEyW|}y_xB0KfW9hPoC2buo*`!8$q`!Jv{4FhwvJ6O>ojv*e?iUBY ztd`(QlbI4QytQhvXe8&Ykg>E}V>mT|g~cXy97w)aeMd_Se!2g@{u9L-@h*OMH}Nj6 zfgkm4Pv9J_EY6-mQgJ|*rB9U&{-{U;qF1YueV73j;4)~Hay|e9<3}Zn#OxR%MCp*n zk(kkc1nTB*jUNM{D%bWsf{YqZ$>$cz@;IFBoG!D>~{~>Qi{4E}bHDyHRzZts&NDHIfHS#^{+Y zyOaVc?J%KBYoYDCwzkKRul0}K!`vWJiKe+QN%A>V_G7 zWt~uC9ZyrJ6$`)w>B#P+XoiGQ2hwF9K1#1d&tRWC^9^A#meY(N)kXWGmg+mKU-(%j z7`l*aWK(NQBKaiVW7OTHzARdd6fKOX&rw5UbrsI)Hh^oXCydT#tTB8xyPDeihz#Hs zw5H=M--B&`VaGT&l`b_-Q>E>qz_4a{)GVZCioy#oWai3voH7_QM4IPSIRIxhu|{p# zwlmGd!%b?9dWU=M%a2xHCg~78Di@2aq}8D@2@#)q-!I!3J%PGit$*5CB*{Tb39dAQ=>`4AYJz8 zuQO{=O03nvtFjTXYP)|zOIV3!rjgnqd{$}*na}B>sYy?!yeXj4WfxJXH3gnkt7Hsz zDY+*spBwU%n*v69Wnko}uL}OdSv3B?tUOxUcvj7$oPO{>gZlJVYew^t{u-&;M*2%J zSA1c_-Nz66jNeJ6`#F9C_G$dI5)(j}y;}c1`wPkQwElfe|NdD2KE*FSOn+Eg z?C6$=8tLJ`;a13@N0t)kOF|Xcp|CL0(5Y;*g5&TDwd5CBjo*vK&ko6?bi(Rlhw>m! z;liY|U9YoUud`jRvuQQ$xiW1m4Q$k0Xlrs;Ozm-`H_?MJ4cu8R+D0wQZl;M&R)+vWrDThi*wNCL_DMKU$S&^>>SSdx4!t#)m&(`R=KIhW? zIW9}-;U8HkA4^J)PEl4$x1?;;DgSGwydf!_I^`uRy#ENWxk{g z*C{tyDK|^XfjXthO1VK&oH}KSm2#z|e1NhkJ^W%T&O!~ggN_jz2 z-qa~8t&~nld0wYHX{F3wMaok;Wg55C{!7X8OPz8*w>mx?LL27K<;9LftT9#5>aA>e^*{&B)&oPkd(V#=Od6#%Ka66ibD-JmTLO#k^a64*syS{q+kJ1MWzrDbu&zOe7(l!RH+!a z)3!a0Pk;S6H&b9g{rSt^b+J2iyRmHc-!nVLU=D|znIe0&@w--GYx4{12Z#D=B8uOxwGG*fF!#;OtQc=Kpb{^%n3S6oSEFvzgwn-<)a>YMwx1j)a`LcZD z;2H_8nQ{-#w3_Mrp-f+MH9`D-A&R{eA!+rx7-8P835ojVN5ESA+xT*nuA6N_E48CQ zjP<}?-PHQfggfW=hbPBMB`NoPy6^Vn-N!KqWD4vDPu72^iw)-&+wT~_=UObVC)z#T zzE5^qsu7y>W?uSsv{-s&LHeq^^i6r`kL9Iz<)wc&Fa6QH^m%#d_vWQvm6zU}mp&mc zeQI8MOBe(W} zXFE*0H#}qeTjoW5%e;1%GX48oW>McV58kEBwOSn`o-g~@_utIx)Awg!_PzT)Yk$kU ztZ$h&WXts1_*t>PWe)0F=9jW%W^jI;R%7hB?};5nb0^0x#Hs2`IdC{AKPSr1G4gYW z{FKV#v=M@FKNAtR9QR23x(?Kn=c)E}6T_jO?dukrD9>GzKhf=pohQXbXa*}O0H^7-ji?vQlY`OKlGBYM0&auY?t*VshZX&_(hO@$Umaq1(IdqMxW8IBL^+35lULEi{E$oU`Q`M@Ax^Dn6vhC@6W0<%VOhPolNk7?yGJ2L@dkOm^<^?qN zBWueyO-6+uF?U2$V_YgoPK})Zkx^Uv=5~)G?laokeN(ozr_*s~hta;u*M0XN z`*xQhp3gjl4O{iui7u~%RJh#V`O`$c3 zcb&0H`5Bh@gkmfUmW-=ffPt#Vt*-xcXWF|M7c$Z!=%l!I9}R)6!(Mkct3Vzl5>DT- zk>{L@Df(f1Y#5iQ`61EY55PXwg3Ygs!c-3pU$CJS!%tv|GjZyNSeS6ac!pPY{N6PHBUO6Nf1~Al`F%n8__6A8aG&gcX4IFj((ene z)jPM;X*K#s-su%KI)QjRYB3Hboa zxnbgYS^CP#VnWTnkapiNsMw+5W(Abhydfs|l0y|X*wcPLwJhonP+uS|D_2zo7VI$H z?++9m@7z-HTN0sM%irm)r28das1y}z==u|*R=K-rD=aXmAzV*bKqqv?0%9Hg>Q^TXr0KsB} zM+T>wn;&8X@z#_bM?2>h;brnyAe9=;CR69kFh-?&g(Wkb12f(~JwvfeJR`*cfCc*kB6Fj_r;wvLLA zuquuX&g4m#y|V%!r(^C!x-cHd7W+7Qs7#G9HW0Y~+-xb$ChalN*(0SBDkzByAK6ieHxL`q5W+pfUuNBSv^sfKUu1%?~-L# zUES9-k9Yreu6)1ybzi2Q`lSC{5G2Cwl^pr& zog>NCTSk3}Nnm$>_v@Xk?DLweI#OlFyp!Sl2@-IWm!qS^j|XhF3Qi>{e2h~ zUuEG|y((RH=(kaWN+8C8+@#Bf>c_4pid_z&)BcMXVh?HA%Iq7<1i_BEW#W;8U)Q&U zXvB(^30-^kSP1CZMNo^oahwpRGWLbLYdoTGmHR{+=;2;P22koKNlv=IJwToy+T7p6 zn@;z&q)0P5-B)raRJ+rCgMDX(1HZaWDD_qHWv9z2HRsaJ(p4V(APha{bY2%Vune5JF#@dnVOu+8U71XEvc4uU;qtf`i!Tuu| z=*&ryoOJ)pC7oHwuhp5`xRcIsz>eXV;WN0_JK`Sbv_Yy)9z0_pa5CUS{OY^5qoD1S2uI zVkGax)smjovxmuchS2UH4f25bUKfjBye>`-+})ewf!;TweJyCkwr@%+ej}}@#@VV( zn$iG$PM7^z-q4PkTsv?Qv(+kJs$Vokv@I1_%;1YmHu1^N_zO^ zw8+Xt+TEme--7yA!yx7UKF=CZaI+s}@1bXE%d;{aJQeEF=k-kiZOJov3q4eK{u$}0 zOI~zOM7+y1CE6Gq74$9%d4|@dN<2`xa#m+LVF3F~o9j}pRduypvBQIAq{OIwVcMXe z8T1skvx#!rfJmafvggeRytulpzY*-dk>*g5Y(G0@Y2AhF(Wr68zhqFQQP@6jWPO-T zK!cYJf=NuNG0NkGk2*U}=u^@ahUpq!#U!8t-H$W>q*uI0W?x8Dj2<^zkz+%v+qM|q z$4c*mpvC`sg7C`9jz^t6+cKTCuezK8Ryjp#0^)Jc!RiKN5|#rsEI623t`pjNiqx{_ zcBUV7_6BBN87y+%eOXoy-n*^3^4_UeUXnL)Dd+%I`lfy;Qgi>8%HHdzOx>m$#ggY@ zvh>cN<(S-lL#@GOy(a`bsrOTq!`v9Z5-r)x|5oKzFDh{it)M3hq@o8|`O*RD*|+5R9{n8q zDkD}c5oN-0B*sKn`eW~0_XT8No?p&I9_7m8)m&D(PvY09M-1D=GB=%3!}g@s$bdm# zffGy5c6)ZXgG+a&GONa!2mMd~-NfC#9-2;o!uB+2Sy=C9Nbfo2)Q zo|9dz|CI2Ml;CYSmpP`jh^6@rpL0j(no&;SZv`K*ai}q8*MRj%I#XrbeU_OJ$9M+EUP~v-ZBP6sthh&$3{r? z2N7p@OqV&yY?$9yWHVBCZ{Q{C04;rda2sy`@2CvdPi@j~b*3EWN3oky@p;F zPf#W+c@ZipPZkQP@D}e~1g%4;lS(H@rPPM2>uKCF-AX_YPs%7%uZZZ&ew=jx3%@ae z*rOUebT88D6Wfp()#H)-(1OC=!&)Fk$b9Pu_Sqr5Oo>7`uCUTu4=3>@a zGcJ!^_v)SyD`o|5O9W&lW%LijtBZwk$F|$Zh;>AzmZTg?y<(&j@JW`MtMcm)y4#>#16(tk}kp5cDml>y(a@4R0ao20jaW6JD{W*a(CM=Gjqcyx~_6T zRv)L4uJS$*GTXz|uZPSv!FgM*i(PR|aNdVwuedHAGS{11s#gVx1`;0B<$WMH@1v`( zyCRZwRfGqvW{$bc9S~3tEAEnby^$zA;!WB=e9P%+@2PG00mmv&Z5UACh#h%qlUxpQ zKf2>Hben$83|{7B`7EN1;r(&@^r0csJ@qq>BbexNhLY|}xa}z-?Obk%Va>Lfl<{fp zmRtTy+Dh#qQ?!S!Ox@lm-Y%X#Fg&Q8Z;#}YPPe(qqe~AZOIx}1KCyYIHz7y4lQ5lx z--~N%@=MoP?+%@QBRLM6KAqy7>x}ld{KlYl)&@&ibsyDnN=N*B(|sDb6J4H8_gA

;QPSSk<+uJ9Qy+zylwBP;h zgC$nym$nx8VgRhzz{E>+hB>LqFavPO2FjJCzF+JArp@IEUh0=%Lf)-~p17O(eGzRH@LeWcKm-7T zhik-_h2NguY5LxK&4NXMO>RnqVu$)0dQYr-w22LXlSZm{k)tZ{i>%OUN2gQR9hi^=4q|#P2j2@UbdSn8ie(S{LJTFVB4)kEyLe#YP477G zA6kYy^rXizdcndWZCs5J>&(%gy{IC|dQT9e*j}=c7u1kWj&^PB@WciN&4Nf`xhpx^v$eyQ z_gE5XET{u^>{ASlWOqfperrcTY&>18+)dGpVaPoDv*3&GhB^B=488W71?D)HkviK` zyON^Q?cv(h(|US}gS_u4Opf-6A!#^G^;kG@SD&UX51RF#z4&f0c@9|0=DO&JPN7!B z9|WTC2(cv-nJY_K_b`b2_=@NY9u8an@IgUXLIq`zwb+JX@t%=&PuULJOKISAA7m9w z-N(M!Yke7i+&b2%P8Mo-C2-e_stx96>DqcJ2o@AnXzz(W_^qQt=v~#HsIANSm;kKi z8uoswY1u+YScS$11QV;$J+6>x;MM|hA?I^yu2_#4t|}R$Jt4e3CbA~PF$TUa0tD6 z3EFrk@9=pC(l0qDbLop4zKjbN*a=wP)_82yx`0w)I+#@X!p| zgf_;|y+qBz8;U@4=9Vzd04);kFKUkUpyZ1- zUPOeAu8^sM<}0ZSH6@IsT&<&PW96o@!7KznJ)o<`tYRb2U{cuei!mPr!svDW6A#)Iz3PyTc{vhL%Dm(7SG7ra;vmu-n z(wB^O<>zMZ(D|!^=Jueu#T(ioW!mMP;{ljC64ftvHj?LflI%*)lEppb$|HCE=1Pvy z)J}>t2O30sPmZq$*S34-N7x6IUPxLh%IoIP-{*z|}6c@cv( z-7jZ@GIDW3EX6A7Wguk?;Sz8EQ+Y$*@ixpMOf`5X0+P%#o?#t}f3$C`Bex!qa~s)fKVjyfx^V+oH&z({pXkB6XIjy5!(`cB`_nw_eA1igHnW}y^Sh% zCveDfAi%S{uID+xa|6%yUSDf7C6m-ZQj=jeOH@4`o4iAk^2SKclN2f%{elP+gQ%KV zVBxd4{?KR)U&i%8p3mpH#Je~=muqLl937AqQzbWq1FO3SX(5^nKO(_|s*L2srz0kZ zYRf{5AYHPGOPBrS23b|rd1agVFFL_cD|pmDL5H~u48OguFAR5F{BMHc!)xhT9{_5= znBnUMkU0Pv<#lGjA1NH?sVn3Jj>hnnyx-g(V2xxQk--=j4OU8f)dq7f_}a5#bThvT}&s!V_t&MxEwoW$6ArGCFUNa=tn55<*aiF zyu-?1!k(8C5uCNGmhF-LWwY&>0A{lxBMS|oZ55KX$FgO8G(oztHxg`T+jA3iXKayk zf?gj9h$0n{gmQZ4qb5k_OAndR|JPnKax4zKLzL%5(6@Hdr0Ijy=NK@tSWjXxg@XwD zyWW$8CevO)1*0J^cJJi#Xxpvm1_(|%wx}f?=B4`|Am=~gP|0G6K!52kUG_2=+ z_3doIBEcrK&j062cE|rkc2y0!OqPE+y|qp^tn{gQ>Dm6N5mr6&QJz$udq2o}FCXW< z@2+`NH>LY)*42_BkbbA4HEXiGad7hno5jwJ+JcGMt)7OW11xyvB_q}2*27fwbGb3k zABl6fcw!FJ(ymcxG@u|rgCumjN@%-C;eG?h?*xvQNUna-u_muW2>R%F}M$~1+)OnlC<=E7SY zzCn(`_{>xZ>#$YcTZ33@7bQ;pQ5WiX@2zj+DHEBu z-QjmQW(<=XN4aBW=~nk(d{7I#^Cv^;p4oYQ!HOTvx&E4hO_Bk~dv9BTI3!xD#G6O3 zk;oqzu_`j+g}TD_Y=$3`!7k2w`)T%Q<;IIL2l9WmpPvf@{9NAf%;$59`JdqD=Yjw~ z-)JCxK{Ew${nq`~^?PmB^?^-t{d}&L&$!-szxDjxHtYJMOK9#AJW{-U5J@q-;w6errCF- z1+r=O9cc~OH2d!Q=)h(vELtoVp6<7vrN@J&$B1B!#$Ct_{`vlrl3!F(x@`EpIc7BV!0 zG2Yw0$*+akUNGC2kJ*x8#tq&hLJk(g%rx)yXZ!fM(9h515{adl{|P>RE|BOf-(cN* z{kVW+W8roEg$~{(qUm>mqcr8sEf$Wt1V>x5 zFqh^7Bbn;J$a-32J;_Bd%zBawPmfwpa^b1XdXfuI>#Qfa@U+Q#(wA$TLQotXS$fM# zD{8JcM!XOy>|)(HWD8a&AHtDuYr8jg5Y*bB!CoKlTtmD=kZs%RMsV;#SERkWD0aQ~ zSZB}BUgP6EHt6H{R9zG*hasDcdEEj8(wn@;Mp&1HhOkbH4hclkt4ORTk@Z_>2#dMs z5I-qZr1&Mp=k=8giT_$kj3hSA^;Wi9^}1q*N0vG5zo_?-)$mZC_qLC~ zx+xLwb?sBU4Q)16nCa`jT9R|+Z*{-_N61M09#AEU?`opmCm0_cVIx~n?9^y&>6z_V z(Qj|ic9-&$qApgPDppi^WTyaKEo?(!Zu0Z`f+l?r*f<5 zBhMctCwxNwoxJnO{}iOv)_O!Np`Z4%q>B{$Z=Y)HOYNTVsI_vjY#~>MZcUl(xKbVJ!`GpyX;y;$|~JWS(Z&0+nMZjEVuTdHs6RHN<#g8 z7>h~;sD(pD;(5HaI-5t0bi|3SewI_+^Mr`^8|3X_Q4=@K^HFtosUQ7Hk~@Mc&+wq* zX1AEA2Jd(Tw?mGzNrGOK1lfz}KxyR|5_>Ji zn6-P>sdv}u`N^&^jvr9-(9+hKS8|}#$r1Cik#!^fwl(aU5;SKT-uZuI{)h>qO29O- zw%VImfHY_BGz!yZ=u=me6QOSX1$lVz$V1}$JS1-U)aUTFe9O8mamEhfb&1vvMhaI% z%$L*a=C{q7JtsDAwnMwQRpQEd?ReZ~Vu#}(H<>$iFp4T5JlOJzFrQ7A)sbvQKlKH* z4@jhNEd{BM(7i^?u>nrtG0*)J_3E=Bv(6DI52tGB0tl zZ`vOVVR{JD$P&>CNy{V^|=a90AKOD_-O zZND~Xt_s(_5I;@wPzK)k+v62stP#icd?|H?^D$>IIo1ftcl5Kaa78eU6%%*;RjeD$ zb{c!@d2~a=BF~y27J})4URHwrpyB_ztli(RR2AK`AJ!9JXuve<7X9?3dZArOB?{CwY)!pA)Y||~; z{P-_3_kCzlA9|EucCU8bKmmJedtLu|>6Rtz~tHI7$({`C2O7opm`nlk{Wm-n&nIjgto zGf+NUB-Y^ht0;b{qY|oH5DJ{I-gqmTPZ@5@*vw?NWO)F!eK~4wQY)y7-6(b5$4-m6<&4z>^m$+G%J|=O*>5i>hK_6#djCWG z9VD3TJ^H%x-!n0_PHzPRncbgqEY0PiNZp9irf0YNQ%(}x%9!AD)@vz`y&1Q%SE1L& z6-fuX2C9XWst)I;*K6%Vt(tl#YhP2W(O0&z$B_bzc{Q5ipTo%!t~gOD{9h6C3x3Tr z1BMx_l5soPAOHnw&>=?Q1PpAEN_8fF%su{|!?!woV7(cvG&u8-QgP3P_lj%Nc5zHk ztT1*#zC2ts(r;OOF{6KNSr5N454L@+57fTarRJDylQ;}f_%&`auvc-h7CV1(l3)8+ z7g`UM>WX_UGLTnO?w0AP4QknWuhyWbL`Bdv7Ns%K__&ToE4 z_s<$T^b)k)+meDn8Rh}{ejfMpPSFT`W8x+ddOC-CWD$CbbTew6J<@12O2lP}#mZ=N z=#csA=ZuP^F7QPf9d)S-ed8LVJ{L4NTDUPf;&qHmXLuKvlm|zwihCeu7|!E8p!xx6 z)<|tki@Dl`S`bC^{+^H3kAJwwVaR|cdli1W^(WRhyU5?^vhcaZj$L-~XYp4g&t-hv z58pz=ogTh~uLWoGqyKXA>VCm2{pN2x4&`st(qVDum|0+}MThdN5mNtq zl|mtgz&74{4oqS{p<6k01=&HSo!PR@(vv7Su_GO;7G^kDr6H(hsh>nRMD=?0D|{`) z7Q+@T_xE&(8$=FYqkbvw41MMA46rpGJ^NGnv<=Q72&O*%er~*MIX&aUmpJv;kK>RY zm&h7o^-h;9Ih#$brQaph+^((`Zk<@2uHMQM2sc z`_|61y~}i${z$oI=>bv}C{m&}!5kB%PU%5!CdikPx31ARtWF%=oI%s&Ol;p7AB2q| zVy;#jWu2HKG~~DG3(gY=?id&-RQ@ zxegRW42I0$P~0qJK~#n3)S7XPLx)5P*BiC3O=Ho6i)Gg|C5~wa22&BvNOi3lZH6Fx zdgdUy_55AE_PyN1kP7?!W&M(xShUX~BzKcPaib5>YXj;~Z_C5re6%rwS^uQfbEMxl zc@QlNpJ%=xG-8Y|wjF%?ICFM|%?of2?P2W|yBhxn>~owmyxZJtn8qKtaErMzQiwl6 zr%}6M+6c*yo6>G72$~b{7EP}X*LF<%sldl&F7GK6aTQ#KhKLpdbpYVRgKAF_Odo*s zc|hVtESI_t zYK2o=QO^L}C_|=r!g*U}vI+>}s5nHO#cLK4V5AA2&%QggE>?y0Hu zrpC%c?JWbz<}nH>Y0K8a=GY0rtpj|q;|$Y%fMKEj)!BN5;%zyeZzRS~%YVrY z=Wd%_J(sa(B6euRtP|qyZ5fiu;?Y?K_nc0N&e%B4z9R$e{5v?I%MjPVy2dkbLVQl0 z2bBya<_z_C=l@dP*PP~Uc|dN=!4X2Is-Z&rk^{QM8WF6SQy%k18ZRwZn`K_6N($MW z&Jkp9(17@fk($|+-j=)MV`-_$4S9!3G15r23Q7aT)jp`tsXtM0Ppy0tyNdj=$za?N zb%&nsUATO*^Vfo)Ot7)R1p_Kv1aw-pZ6gshWZRP8?94cA*9+E660B)p231);fgS2z zBr^4F`T3^&B;}`tpG9hp{PsbZ|AWVU$3Kt8Kact=L}3^FyNU6(@b7tETlfcJ<>Q|m z&sB4CNxZn`W|ub=(NC^hip?=4HUf@ul;i94xE>=n76vwK9pn1P zQSe1X=sls}og$I$ih`4+v-^pHXGl?56ugj%cSXSx3yA*|6fC}KTduY zsZa0vk3hkUZZt~+<)m^y4j&Td?)6|z`D`ZmM?FQ6#wJke1hwjubQ-k*@jACV<5!~Y zWon;Uss6f5{3*B8Tvm=au!c3D(RdjXctenlf^taoO7Y!++Wg`UAWpz$`?DqapWT)F zEcd~>6kxLWv-VTZQxvPE-~Iw1>^tZB^mmfW?r_j-Vs4zECJ`a6pALVH$dm2xYmk%O zba>e}dv$na{%1eVeU|I+8w+>e;Z9_-FG99#SwZ61<)6fh6LXYfo7(gUG2m}SQwF>j zeK=0L1f*N5?xR9El4BiN=&fP?wxUaNLy;x4oE-CkM~)orAe*~3@Ct_@vqp_&t!Ol! zSyE>{CntM6$_se#f`t{bGaM~aD_is_U!OoFTl)eq;*sdoId1hDab*gz#(iJ(G3I?0 z_sb`V6%AQWZw{3Fg0%Vz!{Ii}QG18Ok9L8>=}dLt;QL45(88kQp9}}<%)Yz>nK$6l zTq$JTbh~~E>DMmJpu$tK>=MKWC|#kQxt3(s~r9JOPG<8WhXmMo>FXqUY6pQg+_4U_lwU+b~Hxr*?a;7?OLPn}l+<^M5^^8QrNQXM;c!vYkVVN9+TwNvi-j<8_y88rvrTAI6i(>fi(1<+Z?j`<*0&tKSdRTwmh7?RP-joPWRcIW=)9fR&gQ zi0{woh@)Y1r8;woIMatWh_`z}v6o+;irZMB4oVVVL958MUE=n*ia| z$LBSvw#*9>%@T?0HhKQ4Iiu7=I-QNMQF9D2CGZ9$^gtae+I0Z4RUN`OvK4qZyD}#m z2@Xhf=`d`Qi4uzGhfO3O#4hKU!$sZKpzl~P|6W=K*d(4B1Hw{yVl%#xlNNv+T!u zX3=o!J>t|OQPz5I{e&_ZP=9Q&I_plE?`QexPW(u7Y(={&c*yB(5yEJ1yDEmCfkiqx zY&OIEQoyc@7@|s~2*A)dmQwW2o0moPkUCCd-+WQHaf)iIoX%&yA~bqC3}Zpc0zsDz zf)|Cr%8o2(t06Qs0OUvVU&R;FLFUUf^fLJ~xYMbLxh0MnCpSMOWia!^XlX%8U`jrY za_bZjq2&)zV5NXq14&_|R35QBBxYd|zLFgSgg{%XW(i}Pw?ZgNj%ss) z|NhVV(EW!i#PJZ)->S)gyZDD0($BQ~-4?+#33B^WkA4lw=b$d)%|h%s75#o_y{7qf zrcwrySYnQWRxWms+J;^+F>BUN@BDdCea@&)d{EGHgxX{$$A+qxxix3aQqOYj49pUp z6Dlq5!U^POA%NdO%02YDo$1)Ikw#AMfDq*z?w$4?PiOufPgw}oZuh33b6GaCg7#Zf z_z6MioFT(|`_DH3I=Ngr{iyhG|Xs1_j){V|oRGcRB&A#)TP zJkxVdQ4>iOZi0nUf^{?*jh<-Xn?MfNp_kM^{6pX!SwTdG)i3A{z1OxJ|BXqJM@d$>zB zJK`<^Ux`9G{p!ZQ3k#XuT!$w-wC}4|Q?0dy#>nipw>R6{TWwxcb;+^p_!yhnYO}X| znVmMf%_qc^@`yw#C0koxxu zfnh%^qxB))!u8Y@x5*9hLp952Rqu&rR&BXie&`=l}oQ;veU2 z*4il>XCr?dnVQPs@b9&O0`qF1TF9Mj<=&10A$Fa5_Xn~XxZ--loP8xj?sLTA5<2Z? zHDW>8pw{r(sF~!8T^5{onl{9q$BkHKL*}(JV|9pUbM@q#coss4%uZZ-kdMKv5R!>4 ztbNLWqc1%|mPzG8kBGQNYjTKmNrx0?%j%CHt3N0*kN38(li4aKHSs~IN5q=2NY8a| zs242C_=Zr%C3%!_+w^-7yx$0!v!7-&|^c`hkZ|p?PgY?!Vio|J6PAF!zk-^=`8HR8L=1_6Xx8`^qX5pM+ZD`Bf-;nZ&!Nf`M*Rkuh@MxKCeE)pbd&O_3NyopBu z0HePMm!Zzd!hl=#;+-xwz{UevHr^Z*KE7Exs5hU($Y0Yi87qvu*>2RM!pMIzlkS?V zc2jkavQS&9PGU)vNiZ+5(vBo8(c_E}n4#`bb)e+nG5%p<_Buj}sSzzCG)`Q{8ZmYV z{ttuI!8)amlpG$PwKcpp5RdeQqDEn$*b9rB1v)ks!*Vm2oaMRhzY5PqdI1toHH!R| zACqQJ(LnNcaPBEv-VV-wv-J)dA^}6-!42tliFE_RZK$n#$b0KlW)Hd+i?z0<@kI-n0cZG-&=B25 zdlwINj95)r*mN7NOYfr_6)S$tqXjKtN6fvo$U~eTF~o7}j2+CaOKx4n0cjaPh}fc- zTL%f|gcA2s1{|WL-3qdyj8QWgVi?{x-{}1rm3Firm>Z^HtJ}{TPf>t-%;T zYdo=I^k~SvGj^yR4!Os|E92pA8O!keUkwO@x4SVxi-ju#G3L6gX`(i;=2oUCn2~y# z0qruDkIhf~7e9$v0Y`kK?a@|MOPKCnsj)GO~FC@N4yJ9k$kn|`9j+m&9f?d(B*a5 z2U!)uK)Sc-)|5Enqcg1*-P^RGiJScnILNEB0Yl?>t#|Wha!9|tw?4&}=9r8oPEgQ- zOZ+-uQaEkuyt#hKIO8%lBUdG6c^t8cY9LfLDz=TW=q3%8kuSso-o*P$z?bI$bp+RC1O%+pjlbE`7tV3vmdJF~1{>=J+eO}wfmWyE|(VphL z*Q`6cF=7(B2rOoW@R2%zb)R}hYlEMxXd^@Q*5Fb>wZoR>c(Re;u@KaY@1d0?+%+n;* z*qWr8d`*(*C4MfSTb3^G{QIm@{oaslaPIPJ=LH(T@L zQi2p!)iimS9z8eN(?eAEdDCNqF8o<*dQh!pHx%_jZhCZ)$C@6N4mn*m{=&@kSZ952 zPmfNfhvepaYkI6B}Gco zv7rk2^{Jb%MD!FSQOWlko1jb6t<+Vdt};TU@{{V4`k1gfvMQPKVGccDC5z zHzm9b8-x36NY;l}_MoIn|30w4Gs;r3j!U`yWksy`k%f1I0hu$(d^#V|L{skfhsr0t zMjx3)?@8KyEYiOHrkqP?my{!Cn#GXtG~{p*_XvXN;CMp_qvah^AQ7}QLXFGC;v$>G zGrddP`}6O$ziVQ-M@m)Wne|ZfyV{VQGmh-kV&~V9lJoBk(&v}E z#`(}lkIp$FS~k^Yvdh^lcx}$}jm8{0kBxGMa1sBgEKy?LSyh_|L-IVP#hBbAOrEC^ieC=?hzg^CjX4PQxW=lpK-TEmd)1cX}4$G zbq{)7pJdnlv3=e4vh{rZ27Q%ts)8BU2pvawN4PpI+8cl9$S1WcOY}%FpzNqML= zYEIP_)qwg0D6)6MZzNl^IAfSI>y6}ZD@5OfJZT7Xt76McKns^V7*TVkwhh!no>gHh z;?QC#1AkuiD}BS>lAq{O>;3GHK?{V&K(#USV(FlSk?J zT&NovT&m-Zh$25)VW{;?4RL|z<4VJ{s_X&r!<;6lgBg4>I5V9p6Rx|kIJpp#LljDn8z+p168 zd+VdvUr^|-RmagHEHd#E=AEWDkbF5YhYchZtS+(}NDeYg9LHJA+_A>XV429p4*^Fo+cuAZ zWqG!}JXZd7!Q;gOJv$ zM;#|B5>rWeMzrS2NwI^$N$H8ks!gJ;HU%ef#?K%mt~Lmw>Kl6TZzCkz-)6HT^Wqgv z>@cxHzX>5gs3Z3p_41Wc4$4&Vzp3iEC5yImsX)+H&EN*%Q#zA0W(gJx5Wr$-3%jZ< z+&K}?Ji(N}o>BNEzo77B8-;Tf3o;w*uvRx9vxn!uvv<_J05xY0b$^HWrPc!7sGx2K zH{fukdV(9;zKMp?cJ)ghZ40?z@Vpg*D8vw% zrjcUxA*n&)1GK~4wID0p0pB4ar8+~c9P%Uq^W-S#V{%g7!S?d(;QZxTCZsr-3u1$< zpnP^TazAOVeJOwlegqmXh^EF7&o59JT(G>Ns*bQ*eD8_Xj`GFXi&h*-1qnz_DDtFH z)iH|IUN;bVeiBE}Vo82qXs{_#yT?9@vtj!OF%cVXk zf}-OW>-`dDJz+a^$n{;nlRXylg#^x`J$tO9ciu00%IN;#hb0qeX=g();dkhR8iGqj z)f6EY23N@W=*mb_&t-E zyjDtAO zOR*=uBT+}hKek1CMeBjzV2Gd84nYjf-Ws&4lwgdZMqQOfhN;>IaE&^I4&op?*Kpu1 zwTi`$Nc>g2r5?AF@s@g!TeE4F`XN`F7pQM@FIaRl`pSUOcnwER)}V;6$qE9g}NYhbc|ujePby;MPk%aF!kT7k%WlRI%JCMZHm^igU5SY1-BCU zk+m14s_Q^6F?aH)mp0Q`FIgz&t)y+lBxtF)U;1KwvPPZC2j&@ z>4ansnlEYfmzskP!W5^d5Vr3Cez~hS8F6LSh|10XqD`Fh;rvy^A@7pm49J$fIjJ)W zh(?kM$~o^d4vI9cG78V~WT%IUF=u*C7SW=?Fnv(4cqv_9NX=2xW&TV>NDk@Qq&2=GhZx;heADV%EPm{%bUU|tkGiFA6Z_#drl+^^ zx0Vz)Z-t<5zT~UsT>fvFNB^?g%+3_Vh5_<vAbz5G8CG+l1P|FsP=fDsYfhS_?&fM! zf=n}X3)IgV_NeJJN4q*C%yR5_(KkUT9tjDL$d6~-uQsf|BXD&;^mz_42LAjtGh^{C z8z=Ri!zV$#@CoeEt~tT`%{zEdznV;)=DLU(u8KA`ltdCM2nFz#`c5vHr5k>ICl2Ho zgE{9Kjhy%FYL-RCBy|IsBIYG5ptnaFT@^;*cJ)UL`uY@Du^2VhxyZao=xkw^dI>Cm zw+{}cpOacBZthb(g~27x^vYVo&@a3}uM0UwDYyWv$P1S1&rX&ObHPgK(Dme@S&BlaTm zN0LJ*_^|z0uXn%3vWfn554EoL7-ZrK80IMu35mloxJk1M3uq&@8%fM`!fpDQ&%2ay zu#vjKW0-saeOaSAAQf<)eJN^f_jkxl`_L9fFf*n%aZju#iDPN5BjQ$s*evqLCi3!V zD&jXMxO6xPm>A_><$Wg)WKTIBp_L1*2>uts)&@t2b_Q+0Q&?X z0oQP6{39bZrrd&CKXBK8;0JwcYG||WmCW!&+j|y5m`-iQ)(=a?lFJ<-r+}@~43u<$ z(|?R4FDkD~j`t(C`11W0MXSm>G;qTE;S;tJMaff5vgwK+F3vcerJ1oP#UR6>h&qJqhPcch=UEh7aV9O2Sy0Iv&85NZ+z>G zyHz4fG_YKe)ynyvx>~%UZrA%tYTyL7CumT_ltZ|Psye|F8L^zBE@z+Q^*M?2SmC$C zBk=%_)~=hu!SyVQr1zDo{Te|QREh*)tQqT>`A*NtUSCm=_?ErDi_`=>GlN80nq4uDEBsc_rIW|obI_REZy_; zr>*NzEDojo^ziwEb5os^T)a=c`V=eld_@?q=t>XMm^rB!yxRg^qxc$Jqage4>}DzVe6QHICLpDXtqjvx#(MPy>iXJ+d#cNlg|oaZj2Yj;|aUTCEszCi!3)Qn_IzoPBVm-&ClHBKB9gP9 zLxnwq?MSDEJuX^-{ZN{ zy1IAW7yX;+9wT)xxwKcm-x&1I?YAt=z?f`IUt-zF8GAw%1otk7oXxoeJX?~G!<)A| zWB%0nra#(W=VM+kOOVJ)PQ zNW2z)7FhUc5t99i^J~p68+UbIbg)7pZrMIemOflYOFzEV?!!?}luH{gX00wLRV`;@ z+ROefRf+Ye=P0Wer`S1$=uZ5&SSYr1LaR)Za_D<}V86ZC%T&uWTVM6O+gsaD?$h@B zFYd4HA3?n{ZJ%T3u-d*^Y~%lew&P*4)D1A9b4!EP6@mj(uslz8cP|0%GI{#+-+J{) z;u{Rsf-Mp{(A>D7prtK#Jz=Sc#TPhbW$ZX&tKzC(z<`Wy9_4YwOSZXpG<&F@Gs#bq z(*)sBN$&zD8z-L^X8g+=0GC;`z|*n{X2$zuQQ(y4V*V_d9L6vf^!S=lm+B#PYQhO; z-cRP%Yh<%>gYNA{>5?2#CHRPlaDXb)t?G}hSv-Wi$dnm4*?cosma1iuxT}cK2c8mH z`=jIq6thES^ckshFshYqo(pZc2(ck*w#gj$5*{~47Zo`oNymaSJ{S{d=y;i{E8ggb`pD?!z0=S#~!Y?MuTO`NKvugB@S$f6@lKX z;XVk`=P}!#AJW5If7VNXPK+jp(2S7CjONBr>$w#t?r-a*#V6)k{K;9pTl^NDW&7S@ z#_Ss|p(-N3+JlrR1|fM!yKkMHp#tc^Ck2Tr7fSj0nUXV^_;3KTCG z?K!Sslye4n%^9P)8DHJ2*Qw0mkw;j24y6_ z2JR$LO96*dQ|AdO_#-q=)zeI&1FY0b4=t2Y^(;6mM+bHySZdZ?Y9y<(91pp2Kgpvt z7T*K3;tR-BXSA5s`bSjI4jXJ z`%x=k`(qQa)@C77bIut>B^tIMp&N=K)laoOPumRqVly~lFXc%KHC|Lf5*Zy4Mpg@H z^p0Hxgix_UUS5Q-;n?NAOvXk?qcmKoonNh&C7WJo_8;lj#yKFzvCuD1R zJx{dQ$axU}N!DF+FBB^Xwguwy#)k>l$uMu3te4QTo{?IJWV+nPmJsDThl-g$I4yWF zn>>^r;6QW6326i+@g(a}0j(1r@q4Yv0@L;z6!p3**JN%M}vnK)UA(&jaXl<*cMywFpGH2;Y_)0=}Zw)b!*9WfqN zd`~KfOjr87_J)68frh^UpABi~do$2i(J54Syq3&q)bN>r{ksz^u(QS}b?qGB2(${B zf=p;=zi@_y4f_V|KJ+pV8Ll9JF!b_LqvmS_iNF1HnsK)G52HP>kYbRobvy~dOuJGu zXqVG&7h+ZE+Rq2{OHO+rpSXVLmVSgie!q#S4NYqfS?Bd+#j;~|Lmb%rS)>l83X++Zu`@&K(gnd}dafYSKE${gf8)Ps$KsLlgF~*ZF zYd=PKJ5QXRO&8+-D>{|_&vu8)v$(ptQmC{~z|=20p6dYW&|MToPWwjlcq;U{DYg&`6{tyvQzQ zVWWwnh~f)^B1)^aRCX0bBykgEb6v5mT3cos?U5tU9{Tc0*mnhA>X@V8G~jnEXN$`as|yn7iakg4dmvY^k|PB90!W; zm+T>fE)uT~;~9EQCJi%j#*I&bAZN~3BBm(It7-+2-C z%_}mCb`>4-aZ&i{I|GBP&E-2?M-bb)+|?Y9KO84gW3YR9tE(3`p=)KX#HM&!`wOtrpF>aO zotk{1%wswZ%b6h<@Wf2Di_EfxS!p-ne={RXuq|PqKQt@K!K}2Lo|%;ad8l5bf$3;+ zFt2>3ERB%52E%0Rd!jj`LxuCz>zd=Dxy9>5bstT|QdYf!9{g#+Oyz)GKV~<3WuooI zU;f$IrCYDts>jFsYzBiXF&<{D93dVva?>BbstHw}U0q~)wJxuIAiG625Oj4qq|3?u z`?d7ow4mx_X@PMzmEdqY1LA?}>C#+#uR-gUYWR8TT2UqH_C8qx;bl*xsaD+<)zZjp zxXh}nQ=N43{K}2N>4_e+VPARL+LuKBdc0%2)wwiJw|J^*#(6EV*NHV&Z$ue9oiunM{+ zxH?14V{sU!GgH+~#m@NaM?YczR;ED?Gs3cnyFrO}VuT(jIWqG-u8=B4m_A*lfvc z;JvzsO`o@Vggod*=c(0RU8LHcFgVI5N=#=3Y*6>xub11eo78!-Yvk+MWJEl3uN0HwP&<>CvNmD(aDn8s*ue-Z>ExI3Wf63m+c@XOwinzXJ%NyV>eR*}uV; zr|Rdaq-MBQ4ilb#A$7MWocGR=5j!r~J(Zo>w@j)_FsLJwgd&Up`IvYr8Ub&g01q@a zU+Gj|r+VpF1}%*hYjGgEdTa`=o}_4Oh&rDF``C5SG39ybl zt!;je1WN46{Ph|{eH#e5$>vfA#EF22Jx$kwIaa;*n7RqBg|xZiRAe8vN8d-re2u<3 zJsS77B#>Y)4c9yFwPaRc+yPTHSN#QcZp#_MR%I$oRpVs`2!XML3cb;hnDznk*fXVA zR)F>^9dYhxqW9TuwAS=(56_(Ei!9zJ2b{JE-#3n&CnViP#3DQP4ULQVc3V4Gw2(x~ zKNo?Wh6;`P>R`HO3;K8?WAXFYLB}G&ME^P|(SyX=aHG~{r?y{KKVS#4sEGyzjzD`IEje}MTYM8N>arhO2f=n9)Yv@^itqff) zsnA{z`vBed2809|{XcZuoOF!VpX~r2h0vamkEr{(Mx4Q_LOz$c-i;1qX@xh%Ns}34v~3gNP{Zt z0~fX!CtU7`H%UAWqsBv2wwqO;P0*Ffo;~AWl`&#D3jk^_XYWK03G{&jfX+K8P|Z-; z&IvaSPllP^N5pN24&_Gq^RoH;&)w5H>~#P8_+JeC7X#ll1}x(djF6h$hMF8lCd;^6 z=dn3Y$-7zSWwgutq0Teg`pqGaBU6+jNq)UOBNpQIu2{je|$R(#4Oe{{1%PG5TyA()CTzs6G#= zske+?^T*qT0aZ*WJG88O`l;bXia-};}VucW~XFM5v$-wb3Mk5^(Oe@r9i-}=A z!#4FBxJrK`c4OMFC+O!#qNtfgAWFV1}nTnCTULU&_UC2l6%HTk!rx=n;)i_^neg8kC7pfbsB7 zBtf5IE9Am85;@O)7D?M5<~t&vo5SR9X(Kx^Uz2)4%y||#>?TICQ?sJwb}iIU32Ziu zXoWJcmBg+TZz9n)gpDh8-N6oZ|LQGWx9C}8s9KC{yKYf##E#@+r(JwMTp(-3h4C&Q zNz0^Fc8hxHt+g|ZjNmuE;^r&IG09)KSI)$_wpuA7pu( zz5Gt*o~>`mRSO1E1P?+Ok@^gom?1qCxGAjWWL?d-#%gSPj)!{QxFFg7UJifEwc8)P zONLYP!cTmnQPFDmTv2g716LSTi@RBOIE-%f1ZlM{`y#r|WXFCvKzHU^Dv{2N)m~-B z74~DG6DO)_G-=TBm5UkOQr@Ufw7TZo>uc&@Iy^Sv&uL#($jnQG)iXApFREaAfNAcN zqJjdmqKGM|E=3Q=bv!7hmM-VntoS9rV*g{_;R%!i3#8~x;rp;8yQejw#gK}>*R5QI<=A;^m0!Aagbh$eENKrViNW1ChC500MmpTm%aI-swtt3YD5*%M9S1JT`qIqw}O|;X+^Di07O|> z3J7m()ZLf}cidmh@PKv|?16 zq>HE=s-$lEuG>_rCbLv~bp!*aWvVB=mWITRZ;w4S23X0W(xYni-Vt_>1cOlYuHiQF zP)#jAPAak^;jurngW)Y0R%|Uw1jGC8*h(s?eywzeHDtS{q-OQ3bW3x~(nbP-NjR$} z^&y&cR@j~AX1T=qGcZp(f@W{wd3;_VZ~Ul$d;I9&>{LM}TA_IX3hAxdEWjv0anBqM zDHkMobHtdo-Db#AWBaAzF&Id!M-6iZj>4BW&@R4nCd;zdzwEmJ-$6>Uj#$2JtTB$& zd$z34|LHI|K1y;N0N-q^-3xO$h?Q7{*Gw12_&R<|MdlNE98WVVCSZl~hvqiAN+O=L z(A;fuBo~LfdnoC(Uh;NzB-teBxatt1t4(C150K@W6R^JLh!C`HTmzb|t3FNs_Zu=Qv;Wm7LAwSX)B7 zN(0{y?UHKvIZ}R1`ROV@1}+T200&N^Ll}W1z`-(nGCIEj>-D}p7*BXM{$Yn6rirhSGme~4>#V?NuF2pOhH?2hvWP=XYoQ>~@X4VJ zY>3n48ep^1O>sPv!{=p16-l4@L;)Y-VqlEqLoaIOP`uQ<6%#p(crCx7)+y$#zakMB z;H!uS7KWmO1;4qe_|+=wRko(jJyP2FknX(QOSdUGKO=`8KTSH(|FBOwEaWT}B44vA zAEKueY!t^hkafS7kQ<`;(&&is&YPXZ3A17vJ;W|p?-RYGD>@0tp{W1hL;os8ysKDA z0N`G;jfQm9O>-K%Typm4GEUA-lJg!pq1I{Utv8V{E50v}(KF17vveXYFhyu9Pks*9 z1U8@iq6jV^5%&+}``_{GO(5hd$&t{jNfNwUa&9K)DdcHvFOa>EJSS@K^58bJ=CE&1 zsC9pE*3)_ojQE9q;3W!?zR)U$(REl^mehl5VKBnbNTi+ZxBl9QI+n$@jvc#1RM zn{Yi3pP3ciMfKu%b-A@Y^iDeN27yUMkx2$U@X$Jq{@qAaTzOjrHxU&k6`UlmY=N}{ z7dn;-V*M%ICyDLLUUlI75jgfWn=CTYIJQ5V)#tfT_+_bR*}(^~A11#qg1lq1LeX;q zrGn|gP&7R-L{h!w1h<*QZ$Qe8fiSK-3x8J^R~#l^4U$(!CLyNFW43n{J|jX7NARdS znk@}1+ka}{1aD;W(<@r(MA`mX!OOj6AN#yz@vQ4E^6sur3!V!GuK1g#U#-#=Nj?)8 z41gvcP0z`R>|p*4*s)$)wF^MAdQc0epg}C#zC9SM{h@I#;%kQHiVJ6Hb7<}!+&k0` z_9C`O(j>X+D*4V?Zq%=PC3ttH@a`#Dv4Qd#?Rk#*1!$RA9HT*8$Ny8;sG~CzM1UIs zC9oaAZ=3+l|0%2gT5IY5-wP+#Mf+|6@%qfue!Fv+o1dy2#FTdHv7kIyr!$%XMLo9+>6(ojB6S?CXejX{jxuw%KFbyWvIhoXuFhfq6x!uwZ9I&(p}oD$TetGUGJ5hT`oV;l6<*vVHnHFHGW7QT(BAIX zO%6=JvNtNUH$8A{Xm6)L|IpsffgYi~++ki$smOUo?5rAAHCODk8j&z!r`8A$kB!%I zTx@iWFqGH{p}jo9l*)>rjdC|*+5Q}#mX|!LgANEN_1JAZEzyQ2?iOG z^E9~y{mhDcz*$)VVY>dX9GnD4`K%YkCY9@t+;s;TvW1?Zo^(s+Wu`#KxPOWbel`p= z8s%%M7)li-);mHY^Y}ks5;M%zS*!X00&hjwDD_R{|5=f#!^dtw^JSK<;dJu4km_Vs zoIyjmi`lGrgyK4JyPXJJi}uZ|?87Kq#>=PK^dm&`AYaso`%G!&y8+x7N>`{kN3k4f zKeAQQ=y~?;0#ly4A7uuM02@V~WN-B=mfaF7myM!a<2Db2-u!5(Ad72SqjFWMb{u;E zO5;A7v(ln+os`bH-Oiet7CnY6%b1wbB>ApJPST6FlQc=GMk= z=yUp7X5&%b7xW8oO^dOdWN80U=B*-$`sY;I1e{%0%j%v{tF^VbQdJn zlNbmX@IvsiR2AsmXqGjDsZ2r8?H8nt(j%!0k*iK)YcC@>PgWFgrP2=kjL5Ggg_jMU z(f->Rs)zHf5TpL~g*ygrUWfj4A{`ORtL#al2v`N??W@3r_y{=S>#X%6y9nMy z8=dq|S;*!IQ3EHEgg51C`d&mbTQRB4osP?VI zT*3LjMzOuqE}NR|c1&L?5c1SVcs3zCFSXz}QdjImYWaM!UCTLkEvsoCi?=@`&__G; z5f8q-Lm!_s@QFSI%Kd4zEG(;dE^GA!2Is#Ko|Uz3itym0qBEJC&W2tFXa)KdmS{fz z1;wqGwy4m~?pn8ea;UX?@WT8zKy2_iyA}IrY07-ON9F6LCy5|7OuiXv7jER;A)CzD zrQ3cS&JJM7hC`0ghY0m;waXYiuJ>?^5k1iU3YrXon`XmxcEVFO9TM(c2f)4Ppm2){ zE*m^GFe!zoc5ie5OS2M0m7slxvd$ZS0MQDdvur>N2K?0c^S=S8$AN%Wi5?Tx_>TLCWaRZZe!D)V; zTGr3;H=TZutOkBtO&Pnuta+!~f=ruIFFX)*NQ17A4V0?K9r%9E0absbm6T3PJZfO3 zO_AN+5+xiSoyRWa^Wo9yan{#;`J4w6T8qY&Q0>pv9w2i$f z6&OH`?Vy(5N&yZchtos{Y0DJc4}T%L#|6arUWBi&zK}y=7k>wG&bK7q{uj*uA`B3_ zYnqrA^J_~Zr*9)d*S6xwG{s+q&pVV{z>b1HLXx@a+%CdqWHU0geRxmNJ2>YejUPY0D;T3@_b&(h_(HpZE()8-v5x zqSzWtUE3lMXBPF z_a?*&_>s13G_#yVCu(PZbyb#TsG@k(HjHi2GeyzGeI6|Fe5%{Q=eA;Gt6IiB(b;8) zd3g4>Hv2SQb!-b^uk0%%T5gI>YJ1!`pEe`^@@v*KWiL3=aqlS56$e!K@r9S$b*zJGlip!83W{&oPW>wK}V- z9?>=v%70niHCPn=q~$yYhN#9I zm~e1Ki4|O4%5J`gS@T|(1zFx_SZ_EkC9(Rg{ocBdO>gM^G;OfzRuaw+FUX2ML}|0&zTkP=z*tsUmQ;JLW`?WdCFo{Hem!sT!F>wjAJChXjL=VwYv5<*;$uZ-1ie) zZq3gM2Uh@b*97T{$E?t&L&aqEh(HuOc4@UHgjLYM!sj%B)jEbMXslM$zhXfLv|}ZE zUZ3Wf-V|f)GbSJUizbcRpW0t=+mLU$EQaG~AT6VfG)|g{BW0kwU@FtB`KSw-Pr1ru zX(qmNw@-NFm07W!eL{`)g#6U3+$5U@%jl)M9zBhF zKfi&&5@!FX%1`iO3C*o_6%CpzQn4VcN!^ShFnWXDhG5TQ-u{>jEbxF4kQ{yOEMTFF zh|&6jpeQ4r{R~i<7zvwM!eCZv&G}z!F#8((x&7WBJJI}vooKd?L$8Dkv9j+Rhl5Pj zr{1c!$_mfo;9k7$FW4)x7n9AQ;lnCk4&p#%tb=V8g|CCuGNYoUiA-u7-{m^Sr;f5` zQMTfZz?jISE&e%;3`e8-j7>H=;P^m6@HRa{d3}VWMblm@1hki312+)YBH4s?ok)ph zwOT%MyrxZYLV(26JIQ%~U_)R6w4lZcxaqZ?irstLmtfs)9F#JT;Pe#noC$|(D{-NM97L9Wh%C9K zmY7f9`PLX_%GlAO!)Z}j!K~oPWed}01y8U~h8h{YE||Z`)EHkBJ=thoUx+4B3?39i*ofC zS=rkPSZp|4NENsS{o1VA+5MV(sE3ABdo3b(%LzdDZzzS`!>srdgp9?*tdQI5b)wQv z1V)M>#5O)HCkx{fq~?yU#;|lN&qJ`Ed8C58Xdw5=Z&s=E{p+@9)E<*=ztfPQ0SJ`)l{+fYjxKC|LO zx~s`QFL1t?e9w^|kNk|2p9|&ZX!+@lEf`m^(;Zi_ZqZsBQGK5VQA3i}K$kpXq;jmK zQB=AbjoU~h49L*iJgq4=Zuy>O5^-ZOiHLXeiq@b});h-inT#0cY}8ltH5hM#L=&bu zZDnmz#fQlrozc|FkS5hrGc_>`ibYC^MJm-TK-yx=V}j8U)+9$v`&PUJ+7G)UtKFE? z%cF3{GAh!rmA!0q7KggGX)~#2={J#qx8z|yYmGOgyk^BUNHwIGEMs*Fb!){iQe}mR zGrdTdtG&2nm=&3%iIUF&Y!XDtt$Vvud3_^iNC*^^?#&=ZjWGz|p?KQ0`Qn2G?$1W_ z(x(QS)YC{b60<7dzVnK9!?KTzVrKVk^H!gdeEG302a65fGB%wIE!n1ck@8r`YN_f8 za$|$N)fXo}s!9Fm=cyl|nXU^s-`ynN<&`bombT>hQgqn_dv>pRmNA$1?#BpVVez+E zS-Lx#r0fTIYu4=QApu0EIUa?P?Azs=aJSfx>(hld#EzB=1hkNo@U)Fxu<{h|I--{d zWWOwmmf@0S#cN}ElnxFpveLZ~kA%~@wg;Z8X+d{=y0&U`wt+H!oAdb~;w5^(F;r*N z@~E9)#2)$GkyLvE`!}E3_6%)T!V-_LHR0bog0`#W*@6drD!A#(AIf!wW-}b=`NTTg zD#q=Xy73yv=RAaF6cMBf=)N4#Bk3W@5iL@F5$*Y#>r#cE?@K5;X6x5#WoMx@tpH*r zX;4343)UtGF6gJ_YR5k`xzfDz^*w8)zd5o;;+lf;545J)GVXUXUiKv-Wx}=Kfrw+- zS)*9L_Ie6V3YzRB@NGU5<`w-bC92X!bMTZ!8E-yB3+D>4bwSVdC zvi0$TSM_uDKt)xKl8kE325xLbDDDk*`%HglUhqb2Z56be{SXYXqLzpvFYV^2ph#5W zYtc;;-))0+C-XO{Sqz*YSU^z8IZ9Z{N&%P&5 z%u#!b3XTgNQxX}y^C=N>ul|_r%==8o_eJrA7Hld!Df$F6jzRd|_>612loif0D}PCb zx%wn;s39Ku=zBJ5{lE+DKQ1@~h=D)y)*m@5E%ea@gpQHCBD`T_@)w~!8D4WrbF4QT zqNV2mg(y6s{Tb#mKWXo{W|a9PP-PZb?}-w#Bz*O2v}y+nNPT!F9z^e^n-!v7D=YNS z=n*v9tdNu9EF_EmEMmyV?2;K`ADx(KijMjS71~rR4MJB{=VG=+BdXC%ao{b zeXm(QGwj>pT`dQm(Vb&ylxr(2V<|A{%uw4fW_zity|np2eB91Lm5PreDCOXzMdPEZ z?rIVr7t*Lq8U^;Ix6mk4WAUfE_u>8eahiGik7x=Z7e0>8AtCPt7E8e$lgrM%x1}X*)Lem`>3{d+7`%vBMlC%z$B-p%<=BcMpbURKDT}r~k zio)|a!clDfOUIQd?W-1m4!{gmOIa7&S1mNyUuxGoO1tvkV|}(Ow^6>?CE!IEuU8vB z-iHUplOtq<0GSXRqn~Ij*xOE*cm?(9VO`*E3e-h=Ie{!nhX#7-r6U2QfZTSK^Xvu?7vN9fD0yi{NtV}UKN>J;aJ*q@A2kMwVA;BiuhZ_%Kj z)&!;D&f`TFWz&r$4pVkfJGe4%T8Mc4dNYR$2=Md2Tbm5T#TPAa`5e4_B%<&d+z zh$Xb~p8sm&zkCh(Pv4~a$eflTW87iyZFRx;AIun4iz5&_bPv8TLr(pBmdmM_U{z_H zBHQ0EI9H!_)A0>M9}M$b#aTEMAws(424Mc8GS%P5-JSRx9Cf%v@k-7^J%kXzWzYg2$`>rr7Ktci_Ma^8dia{AxrH5^akQDMR5tvc&LL+8pj@1 zjIG0HdHZv6{Z@+9ofeyGi$niJ)LY4xT12BWOm6E0hf*V2-(6Z#VwTFg-^HYM<7NQL znGffz+yV_>#HVlbtXwi)zjc1DKXMJ>Mc>+ybko_ANSdH=M+Ue zt!zO|+7dZEOAVH0BOH$x;n;7T*-vP}kS=%fho>NJPU+_#{+2&HE7xz44ApW!9HiDh zkZ*o%?1O)g(uGPQr_sip5(4#?uO|pqj{yT`oH^7PgIU4xD6@RQ?};*tb$FQGFNcj2 zqyXbiUyYuR$>@Mk@j=MdM&ex66RJs7YRQB-c)&}i$%t>;j}=WBD$2lYTOZj2F-(+@ z;q2ACTFW?l|Llnkp}@q*r02$)*X4PMl;{oBK4-38Q_|WFqb_>D&Ujtb;T_@Gn!{sJPdR9 zYW3CqPAYJ;JO_@{zkT#?j{fZm82qGuBvPlj`dsGeu2KFBCa&SThe5%JQe+i1!WDWq zs&lozc6xOwkrFCCK%T1iDccXuxM#VH;K8&Xr?ccDWY9a2FPl{F9x~;pHx*ekRrFDS z(Dm9<>z{PJp#r!^kVUo4>TcNN%JICF6|<4oY_GSe0u+n(3g0Bz>IK;s+HShFs^$HC zybRX*BctDcw6jacxe)_IDc3$1Tlh|Ta^mg}U*l}ZDZ#>mnGNQ$a_|$GhNzXjZZP7< zSc28bEb8J9=W&8GS7eXp?KQhrE%>Jmoe!6k05<4ed5ScicA(Up+o0|f8`230c_t_T zqx;(dJf$7LqaA>RstIIxmmcM}M)%{RqJm?CJxao3Y{h0&9NPRDpFs$pAEPB(!48bd zizrlL-js?!wHLLo9*l%z^DW)mMk4`5 zFy;oQ(y?mw+xMgz;9E0Sm4y2i;cXy#@%gs!z+TNhPK1R7lfE|R&xD^(mZK4;(-sKn zK0UjM{C!DQ?0JZ;5POw4jfbLH0mzS=MK1S7&L{e~kYB`j@h(Uyw5w2RhZ5V!?={d{ zNpzI!`B++{$#AX+!!*r{M?{zCg*-vf)0TJx)j&Qi@QA<OjS2+vHWrX^Fw$<)MTYIHI+T&G$Mvr-)V%+9z6E0*kvYQ~qTyktor50;JpeO{nM8m-SfOp??D`6-Z}eEB&+&)8@AjF_bH zkm{kg{F`-@&xmpRouDtHQEf#-9z9#kU*_twWm@-$4i=qTc=Y3g^spGrkfQJv+JJLB z<@CVZCXI=9mKLO=?xwch^3zX#y2_710R$RtR+JY0=qg&f4 z`XG382B22%>k~_!al%jA2H;0pRx;*L3;k&>E0`EOPW^qC$V|etYt`j%OWK%30g;~u z*eck39%F~8+y2p3Z~_HcO<2K%V;uVcb+lhiv|Xu5oyh6|b=5*$(KiY16^a%gIJ$vT z=#N<;Gf^i-B*rnEN{oNN5?R(d%B);KuILbFvRRDgexB@eW3ta;{rgc{n#hz^BJVY^DwxbV!^Hyqd=jyeu`m7&XGh1NO&@5db*>P z_-!Sqtl^F?p|Y1X0*vMXpd1ka_3)aE*50S|+G%CNo0|P{AThp%2)5#USfh|Z+^Z=h?2iMjsu`I+HnM6` z+W5hNLQJ%ka^E^D!l&%wXy+dNJ*1$ox!$TS(OT0342S;E8ocM-a{)}pLak?;%fyS# ztcdW7wDU(1H@+{T#i{bsBh=c%toRM@9J~CaH1N_aJr5hX073uVtZRofinIggU9e^- zF}f3>L`29okCL$QQ6E9=M&VS^*+Tm+ZFu-^@gI;Y)4S(!xv`_vjRRDtwOi zqrLl%IOjSAucM%>`8kvocdfqKUF)#2h3OXryP@aGfC|o_VsSf|%)7zCi+Fbq2b%47 zqf#0rzH~3!mC0B}FW2;H{NBzIQiv`htE}MspxioYlh`M{AhA6{`S(aiL=o~=q-lwb z;z7{&0`poZ0*N{$NpE4c&9q(?AD%HI@CzB$ns`|1rj3O4cL6YS4I$sleiKcYksaU9k`c|Be*+X zN1Vi$MK6igON7`hvev2#wlP-2HEB6=Wd4Wy;>Cpn1O5GlM+LeFzIhw$UMv?Vur!YN z8zjaX_R<2nNgW{>T6}#;-M}Ig{X0!5vKH@Q2*%p$Zc})s!oBvU35lC(K0ORFxg0Ji zI<0C8UtJRc&Ol%tsytir5ZB190c#Rc7FT4e=A z=CU71X4vRYIZi5uK5`sAyYeiK0Jo0kJ?9|>OlWR3!7EldM>EX|Io`)u$lmJ6_`Z0J zy&xdQMcxIULNL5a#>@E_eWbWuhZ!hqf6I(GgL@;cghk7 zkF167)y6o?Zd|AHw>kOZ@yRGow-+1TfS&-p<+Wp40wXDXmM(2?>FvF|KHeY&#q*$9 z&7pMkI^k`LSEVf})sFCT_YxhHLej~V$EhilisdCJE7ydw?nFuw%0i)*9cL2@WpS?o z6fHzmtv0@;38`Akk8*B+i^FjEPP$hm9c3LoCRZJ{`S)tS(XY*7{^Ji4bY=AI;gE_4 zbDVZqGsscTV>Rc}rS}osI*O;sx;xk#rhBnA_#-P;hyYOjfd}~z7w?kD$a%{otjkH> zs@+9$F`W2(8_Tnuvk5OSx@mnDT`0*kQqFV}um^}ZEa;Ea^! zK?lpV&BmiHR-!DfhbpRNn>|dd_4)({>W)>|tHn)wj0Cijum@P!rWTQ!q2{ny*q_zv zT=lWug7|7_qgIuOhcB(%+g;YwiDu;o)a^%Ei1_&)c_MyB2ct?QTPr3`(uw|NMUdHn z%w|>`rE?Gz21-tAmT0(3J?hg>X<_89JTjvXQ>55>OPYkFAPP(2?8LvJ2EBhFct0ma z)d$WBg+Az zPDY<&Ll7Ofz-;+U2&S!lbh>k*(}SdGabtH^gjk78<&Q*a1+rQX_|hsj|a8{0zIGc zzeCkBJ7Q;m9N8UfZ1>l7M??}(m&)Eaa+iphF}e1QHswNnr|azLIZ_$*tP}c8L0D12 zb7AaF zJQ|)Socj(TH~ZA5iimYjPk13~HKs#z#M49=PX}X>7>X|T&ipP8Q6#zH|Gk8kFNAd_ z;;78FZ^za54BHga2!$Mn0E!pj&0%(rLK)(*I^M-H2t_=VNtoI5kv#(E2u+;BtP#Q@ zuu6ll9Ozo>*=yCM?+6g|w$A3@Ay#2~IyK8UpQ$&Y4saXv#ef#&kmD|WCXcZNQd4{1 z=Gjo5CCY8QUAhm_uKEyOMhq?*tfj_8Q$(W9zA@9<5rF{1I&cAq&&;YxY&Mk3-MYM^r^>e;dS zLs#7WBR)fHn_=L#f_KB5SJgV*HSO7*FE<227zQngaa|z#oUJ8u))mJaO2k>k(=YBm zk?+^R67_|)8SBzr-}Dy6O`F80DmeZrQ3VtYUsE)$ZgCbzf>0s^a=B}KLxio8wWVY@ zah=wjTGc7dyVO-2uPqMkN((mo=hXQ#1RDq5JiBRA@wmnXSvY7dO&23vTM;N`nD}c6 zQu;aGS~(6vd{)9FB{CIPk)FxAK&x=% znuI6ymblxcp&l}%`KA)d{wD8Xqiz{Od5$a*!kgkz5?9e6rSZ-YbKtl0yJ4=6v=D9?H1Iqf$22 zRgRxcUoywf3KE~!n`Zluv4k3F4@<6gghwxj+yyK9PokbDI7Iuu!?zTT+fZblxj{~P zFz{P^LRNJkHb;|)CaF(~g`^VKYHI+AJ%Jp@anVo?*1%%s=zjPuyB}kdr% zi%;0Nh$8rVr%>Q`G6T;)sZIbhFnj_g`EGai{IzWH}R8Ejg-kEaz43gU<^ zsQ8x)iVp|tiE(H~y?8s6T~CTc4y989p};1A2LM{760Tzyu0XxHEXLv&K$B&I%5 z5&0oRSVrJPiUubGo4><#sI^qZK@DC?S$Kuy?Jo(8u3B}@>uFxr6 z0%QGh$JMK}IiQ)Y1*Z!WKfXpTWP)Ed*ukVURI#w?)x`H0n*A|lP zs=;?K7v>9{SjO&s+@)UiHbkm-!gHkCPIoOMf^b_C5mq zg4sVwCQ&5viXzvf>&`l)c$kH!=Xk4LWuh-2lgf*h zJ}djS;8E~{l1Qbbd3i1`)dh%;MOFHBEX!B5PTeU~VNbToxNLXLCkziIy=D=#edFNV zrN&7-67klol+AcaWWo>_n%?^^nGCg}{N{qiT)mo*7`Ae}8i`^vc6@^LJ4?Mcyk?U= z=O_x$3XRu9DeKRZGTB*)3e?0mq$SR>wC*{15V*MDo#E#)TnjEEUV`<1(q4jNbqj1i z!9-2>eL+n*?Q6!S}$uTQ^O-4lsDm1SOqSDwK&Jd zWdhlhMRf25OrS*xH@^Q*MdcA033}yBou;M^ezud|qUUnBPRxzQ<9h{P9QfMZ=HRlN zJnNHC>tu7;4v#%%gd>b7PC_501;)zHu+T^8fj*)A zs8Dmnkrsjd8nmy``Od=_Xd*htdDtyhxpR3a8|w*<5#0#8FCJy`94<|Z7#H6ttGo7^ zsn(kyYqPM(YPBC7d9*);S02j}*u;FrQW{k1Xwis@?sN7F!b5B2g=`>xk6TrA7c5tr z)Dw$C^zZUuJLo*tsw>-fvs9KTT7c+tPSN|sT(OdeP;`tP=Nos(F7_e#VPXjF6KYL2 zE01xC?|Po%A?Kk59cA=d9uGg7Ug5lZoXuMF0_UNVbVdSfhxX&T_nAif7MNHl zIwdewDmh(#Cd&`CXAt>YeDVGyY%XH_9w8IF$x-;|7H#4b=OU0U%4Bm{STn=TsvFZZ z8s%Xns>>9FeS(l;5fOF5b4&0O&XK_+qIH{x3ecJJam{L+0Y{K_< zL_2`XMe5-y@vW?iiwIAwK7QGr&KzSBRy0C9fA#I}V$2!Vu#Yo>lkot6diwHXR=n&G z)RmfywhKMTfX;+bB%09g&`lVS(u6%NG~ud4HQ}Lphh#oa`s+2RCu$Da$)_3GL?`c- z8oC~;hEo$Y{34}>bEv^vy;uk|D*msyJlc+k6J?xx$WIqN&h-flT&TZhVM2PAZ6r#9 zj}acAZ@vF{1RdAXycl8c$7mAfR!lPNp;lAbCbSrvcS9x~2y&bExi}Wpz=?2ybz};= zJ;vJTJ!W&<{p!OoMV@=HTnWM<-Koz&JaXNG_m~|Vg>76YJ3=nzEN#+DfvUnJC#7v8 zORe&;nuI<&J1|<<0ahFdORzr;HF}$ZH8vaC-3TDA*XR%ASYMv+xEblpfK%mwl+hTMh${!M9`9U-2K10 zw{KPUbJm|533=6K_S^UxB$ixuCj65pYkO5zS?df=!-xx2g6$tIukYY-$+tGrD37UPr8Z0Zio;by949z>QQ=vHa1%$Pw3%$N^< zr!^=PUQ6Lvr**z20oSCC*$z)^fPUic^^}pxfG(g`Plk=^)TfyH7eltaboIt5($Iqv z>G`OVQi=3vCSj6Dx2n@&3o*B2=9{j~e6m43d5h34$_txzr@SaYY}!SY;RJN~R>v$A zSevdaaa34h%Q-RTl*E_=6UeOv{P#18YA<~3OY~&|7vHbaPcvOr>4~5`<1ygW;RdYT zvPbbMd1P*r=!HrwV*r_4I_!bnX#e8;m%SK_gW07SoHyD+xcx6ap+J>ugm?Vm<}EL> zrtu!RzX>jiVu}K9NC9M;Q0r)O*?xw}m;bV)D^8|}IG%~ifEdau|4c%zp(rbuT4EN} z+MnN-{JeC@$iR^h4^eJv9>$|LF3wx01tx}COU%mK=a(_Z_l(NYcFkmvOMNW~zQWxsNsGQcu{miV;hMnOX z%?jD<@`+g?M;zqaCGvAks5LwIoYVhi-LUa_HZ^8@%cceH*%U$w-e1^UAGP8 z>s`1PSzCzek?lQtty#3i8`{}9(2t`d>4EP2cH$%z=!$tLkr^8s+Te+e-n~tC;fUId zHPK%(5akP(AjT=PiD z!dc^*P3lvf$|a>pL3~;>lK*m4q!JyhExK8!vMBNbsj}9>U~ihtoRD3)aW*Z}3ujsD zIQxa`D*d8RUi^$Nc5l~1bwq8;wv0x7*_z-QteJ>z0N*QZ>zP|{&n@mpOFFCVP^z0^J}%GRi4rVN3|HY ze8^IRu#Az%GOp%9l&tKT+3h08Snf;7(x70L>I>MusIn^G2u_qua3@Zenu#qomVmj- zZ4-cHoGzcuc?qSMK2REWpT;ZfA*?`7XhRl67PT`4)^RByj+Szf>~4JT7!$4+nUh6~ zwF^C7--Pi1Pp(O#c}1#=yFa+!HX&rJ%WzfM@kq9ED(N`ypL4Y)13%NT>w{*|(ysVM z#cPWSvI2Wz=}Ws-WffbE9JqLWX;-~aT{PGu#s@$8dhT!dZV1HDt6N4q29DZ0a~B0= z1x|}T$b1s4=P5V4oz%PSnzVYuSj)F!?wcs9xfDc8o3UCD<)}fP`y(dwv3lgxL=ovV zw9Q(Ybc)<3MG)IXnR28Qv5c#1u!&RAGj$8azu`O5rE6T|QSoQHG%h4YYoNHSz#Hfu zPR9I-`9!ip!K9;mg^hYC>l`z_^~a8EMI%#B8n0l}tfOvyx*#>`)>j-i)&p+q$638+ zQI9w{oTEd~#!e8M#Ds`fju;K6Z6SvK{a=B-0=U0%Kp4VCgE&rfQ=)y8y;HHHRl+%@d3gyVTL`1*k>P@!d zW!$l6E)(9r66*_@quD;7F|6c!eLTDPfP7x9 zmIBk>xh_{1KV}mcU+>WRVWijjA_o$~v5sYbkhD>}ShLyU#)jFM-R;aKCF+w{FFUhE z>5|RrPugqAhS9xI+?|o@8mwl>}TySm#djt7wKEB{liuq z)a1jJ=CaOmpLrR7zN5WT!nU$qMfFTe^(9QuI@j(JkuuGil%KkV3P{1%OEwHr(O#zRbXLSNi#1N6{bQ&tPJqEhlgb6ZgHmbQfE#u;}^GoiV9 zSo>wD59c&1?v}43 zrDIev77g8eo^c7ol^#0VV4 zBdwtNCDV0{3xssJgY7EadSu%~>xU*r|>_Tu<0wV7BF!8O^BeJ24>zk;`Q zd~Mqf(fZCu>C1hG9qfkS_%!r`_6B@RiIx4#yBHX%8VPM%VtsOmV zAbTlgO2XMc;g6bJ&8~YYnCA{vZ&~5Q;B>J*m%gTQ*b4ite%e%LTu#xdEE};GkcRP_ z6|V^C#T)#Q0rx|FOfZiwRaHkQw0O&oc)gA`yCeFTO`@;Q74P%)-c>yrW^ZU?yh=h? zm}7G|O+d@ywZ4qC!I=3(7xM|%xQ1YFnfrWF@7vLv4~j!|y;%0pDKQ3Xi*QMaWcJaQk%{~y^ zk5TmmdouXN)((1l@7rtut$6Hk+Y|6M9;q}_eYh?$-r~PH77Oepyb=rS3E}{HT*5FE zB3HGrd6j@-4YVVZeotrQ|UV__F3t;=*zDW9E^&Pw?<(4)nh|XVk;OG! z`yCdO_U|-oGXbMaqAUGc8eqHS1T*rTI84mqA~ypND$TmGpKz zde|D_n#2C4lFvH2@@&#;r}&QLT3$9Jt(CRc55*@aC-Ko#`N%pmi_MP%<`i-=)=Kyu z+=KG~n0v6jhULv!%dxcUdWvUKB>V91!*vL3BOWEp^07QRNCC&mHcW*@{%Hqt>l^+s z-d3%0SBGr5US!5;&10v;<-2sbR%{uKejz6(x0fsp)KtTD0bL> z96%`lK%}W+Yr9r2>}BaK#l!E&d|U?Z8*IO7clyG6@!I_LY7E=cJN)4Rd4Fe2t%||o z63q}FCy${ah5T`u=hbo(mobnu*p~M2f1y7-;mtRN945RdfAF^_%lNaC&L#aT(m)i) z>aej&UhtG%L0Q zQ3C$^mBOVxFb8p^~FY*pIHL zVAjPmJKoun=remGo2Z14L`NlB$^?->6%a_jHyAViHodM#a;N?0E%^flyu;sAl5vRS zHnN3aAQJaIk`BAW@&~~%Y+RvV(l>`#!p3595E^dhkI>=W{9R{U$*)WOM$6DbAq#mH z3h|*G3rITb4$2>E175LWhwMqth2+HD(<4G8?lbICXSS8Xk=DrL5f?Ia1Le=lr1>)3 zByjZa{FU`fYlO190=;HAmQi)_uf>5d&^2xhB(FLxmZ_$bH43D*cS@xKz0`CsV@cSs zoi0VXH?UZ~KQp;l+WT8;z$?6s$w|@Ql89qJ?S8Kmj=MKfHlF=ga?$JUsK#CHfM|nl zbzI(7ht*bx|5kimaYjAhua$O(a3xkz`>!x$o^k9QJ*P9*`(V!Da8cVaZ(P!gUzhrw#yBaa*+<@21z+Q9i&{gU9OLmo7 z;ZjbPQ_2~3xgJt(LTb5=b6oFxkSP4tF4=&O+mMKHJK^mr#OpD|)_pBYOS`)65Mi~u zKlC|1Rx79@Hn-Gzyrt|_@!BLhns=28rFz^Qyh!L!l&`_7;_mY<y z)FSRz5CBw9RErQw9|%Z)9d}P?`|e~v=q|psLRae#)pzob+h2{Fdg?(*AQ z?=0`daslqf;#+UCKS7>?>Nm#S+o&F@kF8G(&Nuvf0L~JArXq>8;s^3%nB%yim$(6L zXR)P9tX;)cMSQtnt$5rzvmyq*L^i5?mqh8fI&4dN`)zvWrsM?99|Fq`Jr~gL88*&O7kZZalq2p=v%vWzHe#UTWKGZH$K6*azY7es zX;arMvc8SZ@w&j;SPy9iIMlCg%podWC5qsHkUCdXYV=(!4CovFI~Z=xNlbhQmM91% z91a-Qn3(%R-n+$_`~U1X_eHALbN`C=Zj)SXf;_eI2Ye%1gt8FvERUdS5Df9`h zylvl&b>_aV_ABN-sF{(Ztc&0PYawa-L*Uz3ew9WPa|T|B_GQwsns120cAwd66DD@e z^iZ+KN9M!jIM=uP5N2L8b1D_N&q zAN8ia*h$B(%1Kv&IV8#ehkyS>LxI zUn7vyfGqa2TH*aRuw4~xfPZ*Uz$tKj0@qpNPO{;S6}S%*W2^(*pQga=d{DTW59|Fe zG9iu50upOh#GNU%I4flALcpH}c--mm$ED?2argIt9qSx-KQUcM^blKNjU0#HCt~Wd z_n@+;fh)BdkC2e1GUBc#r59ZFIw8OGT@q4XH{|`edu_zCUk)y@!w#9mtSrk zRl!UXIrM{J+T~hXhl-GrVG5k~tyAZ$!VcZ23h$Eb0BSI8JnHFPCD>MDcu8G}@Xh}Y zyiPW}=$-ApY+rweTDCmduB>^Kr$c*1s`nHj)%$%GO42%YzkI|SwSWOvY@%^@W3YrwbuP5%lA2?-8a$HbvUXTmrIGLIM^13NG5)a!t59^uO z%d41pP%^9aHq0GycYlqFHwY{tCjsPYTRqp+CHL+-#6DdJBDHtYGC`8lCaX2>K8)7n zzbtJjI4_6c51+@0`}S?w&s0in%k6>)@rO$`qpip7Q*HDm*Wt7loSzfqVBoLM6dV%p zTh|nKp8`DTJ32la>X+&gWdh0nls>fKbqZj=60f5=^koen$>yUYUc3DAka!gwYM*{* z!8j=&X0x695Q5|4?$u{7)j+7HV3Ee?BBF8G7+pjUv0}&oKm4-v7h)HH{Bx5HaRHDY!t7_a95!kM|kWCr!ElTJQ9h)Cid$a{1D9 zoW%L`^CWu6V}o-Y{ zSBBOy5O;6k!~FHup16C7fM7uVaradukq>k5W$Ml*I*@5?R4zL0w<3ZJG3Wf`H?}!P zu+?VHA=tsJ@5qNhI6=$HgMK1wi7b0)AYZ`fsaL?zgaI$2jpEt}dqHIQ3Li!H$zp0O zr%>vGDl&q)mDUTU;eBPR0LbJ>NFSQ^lCI5i*J^0ObDMy^&ezC)#s6mh@3Gg*u76;? z^eI^{eOLfE$ifg0^IN_=TW@^Pb3#4FL5l^a#2T>jVG(Qa zDP3EVzdh76v8thX>&8+Tq}f(cF}&iZqH&)Me5nW&=1RrZi)seWSTgco{~zPbqITKf zT#VZ5^)?1|^aDb~q2~)y<)(v`yIz;;@bRWUbZm>z(o=mIpSb({Vwp05%%_+St{0E9 z<2Tmy?c^fVw?9q&3Ob0p2U7?kQfCXvAetPa~l(*9R8(4@$C;Pci_3}y!~h@8wcVh zB?QHs(1gFPXC?%*krZ-%w5uubGlAcZ6L zS(5JJaE}u9MjTEzpGYr`uko5s^x}@e=R$i9_eK1MmiE2hyi6eJ> ziRLXsJN`Q`?C2-%xjZ;{9t}^Zs zoWq(*tTM3&nNMW;^#izXal5zevj@^R<^Ex*g0pGxBn zEdsZ-)k-&?SP#)jbp(}2AP(OAtA`wVCH)i9U$*ZF>UUqU@2M&poFlL?O!+7u{X0FC zM#z}^$2DBXvGl|2_sFi{><893b+^rr+rghK1_NP9xm%CiVSb4D0YP z(4Ys#rB;rV#S)Pr*vJ7J{@2gF`;<>A$j!B6$Fd5$irQyQ zj(=QZ@H3?Plz1eo<}A3nXeIzO?f=(dWT4#`YkQmJhVpIWWza^!U#2U#@O zfumT$kQqxN%wHD$75iQda9ptyYbxc>uo`i3iVdo%kU#xv%H>b5np@;g_nMIW zF=}q+Pk5TpNdDHmGmpB@dJ2mQf*`x>TYt=UWl>J7zjT!X3tpRAd`sOr%il@Ap2ur{ z_{yxP+zpYK0N>$Xc+AKL68r|4A8f+Y^uEG27h7FbGbRS6?q((T_TFK2Q&-<7GwDlJ z5u&3Ov7z3huxrP|{(fP9Zb`)7j{rIZ>&qqVOO{&3n>%0`slo>R6#lpT%Xwb8e)knT z54qvb_yO7brt~mtrmd)f)d`v6lM2abuE^f%fcIJE8Gj6oyU{v_A5Ow86mtr2_Ni!x}WHg zvjc9_rqh1U7)9I-{dLx#4=2kbS=OmpQoP4H_9ec63uBpTow}H z&!+n8eN94X!mwsr+r`J_G}-nY!{@?fCOlPo0TKENvx52lIsWnfjE3^UsXnBS!K=EV zV!gc3+b?){=qZ`eJ+93OJte9!m)_Q055=$Z4FjvbetrVC^Ea2jcr*Bh@pq5zZrJw< z*H7cd{0gTXDZ>5F;==w1g74iCTAYhoPbSN3`Y?6oTK0-31O1yI*lmjGZND#JPr*AA1{0fR(6cZGUO`<5TJ&Fdkp{P#+ zMcD}yb;2TK3i*m>ZHxqhqrklE70pFG2F-L9B)(-tO0oKXp^G#0nN+H zCm7Kua4zw%naq5Mcx5oJ?Wc~vjT>-8W)JsMW0#;{TN^!=_o}n(W+DR?ufmIVRVQ-L zg&}`k{X1blqgOvi7s3OslRsQAW_Sut38D-8j49^-D~ZOM;3Jt7sO6JBhqP)R=@#LqB}Sc)h2@ zMqA-njy6lk(@qZ;e+~6T z>Tv(tX)Vir`M6F>9oMtjCMCx8Qpk*PJz7RFGGNz}?S?e&{{C2*PNVnAN){gQ7x^P& zdU@f$Gp4sC$5bXzVoZa2FYJtIJ)*}~jOk>cv>($Fni0+(#jjA^^>m=anBMaX^4iAq zG>Ux1nEr#cGC8In@SxlRH#w%6^7KDFralX#b&0xhL)3I&KO_BYEpTi==x1jjI;Z$i zBz*-+u({9HPA=OBa?i%9I5gB%T%X23Glnmt`wRCk4z0`bjQX%_;?Y6VQ}LnaiK9K{ zoiDI6j*TgfXNn>}vnq3`?2paWW5{NnPGRezxo-RSycC!DBY_gE_LS|<4Rq$WOYlJf z(q-MLaaRm5n?0j;S7mY!NrhZfHa<7dX?z!smB#C|D40JAD#9KQK?z)9bGM#VE3H~v`?AF< zinS6R6_Nmf@CF|ht%~^Qo+pa7@|OF5e>1!H$|ZM~T!7fi=aaqJ+1c5d-~8tHo*4wt zQ{&8@|{_tDOse0#yQ!-Rb$ek%3M$>{8ts zSeJpXr#2)_Ko8I%hz(!S=j9o?XC;K!>IAeX4}PBo1P5wWuTcbC<-FtxgD#5-q@1qQ26E`f^&M7 zIL<(osh$?d^**HXKpupx*Sg#0&5MFJV_$M5v9SMN=31fSExxZFD=?GAHa2o^;!{_ z0@U=#-Oz)%iB?w3-5EJ1Vd3?VAtKC_uMko58efKkvNr(>5wOoJ*L7}Z%5S`BCFS>i=@-0dzkUV4>WLZQ;dyTaWz3<= zkZdZfX;f!EOvElw3&Z*3x;{t7TKYR5XQ05OIP*G4Y_Qvy4;`@J?nlfFV^-5*y!=Kq=>6$f&2|qU)|{AHf*P4f(?=;af=k)Yy&Fxkr`(Qfexv(tfBE!L z0FKErSZDzG^kLMk3z{>KR!+EYXi-}2!s^td)kNH=MSfLW$uikE=qGYf^%L(H`-`fZnX870s+sCJ zXozo&58j6{CQ9Gj82`M<7%xT~lRae~uEArhJ{B;>&!TR9j2}Zf>=<9d>eR;g3f!pU z{Hhqv(x+sMyFKulP6zGXtll(q)8+Sap_XV6EM`4kq2a2v79#y2MwZeSONA+WkY*c- z^i>C7+`*vJRS`Qr5Nk%!zfnEHO? z_l>bs6mye)!hYidzk1I_T0UES5M+V1+Ya9-+Kp(}l%t5Q&`6=r>=oSJ4=DsggF_?I zsB4X0*BIVDs%v@6b&kLYc~%215=^@>h{& zd^b%rd_Tpu!-Lpod&)FwkUix({GjZAr!p*6zrrv1E1NYJd;3KRM&EtyIf6I^)}CSN zR?IKIrYuIa-lhz|tPE(%F1&}PtilhPa<|r$JECgJ*8JV>3&o1V*U{FT2rY*nVka>+ zND>t|hsk<~RQ{w*CWoOEd;Y_@8@v}fJS5mN$$fD-)|Q8;1hQsV(RvU|U__D&A(R@* z$#l81X-y=nG}YxOCLSi|ZxKVRG&uUWFRD0-&xq94Iv54Dwu%+Suyh`zt*w%9j!s79 zZtFkM@>S%KP~U-+q5-uF0A;)f{J7RV!=n7hkqSlVcFDF4{oPPedpJM z1xx{iIg{D0Uc;(j5WbkAn<#`}lX?SeG7Q2)%=R11wvB0OHR>*N4xHtFfk6B(CTOTL zk?DQ}Aif6)4a6e@R&sEDzK%S3@bYCb+o75at6r-?+T=wtvj+H3;cCP4e9*8hX@TBH^&*Ev5#om0Zr>3Ra>1+9181p^;`HQdn83S{d~fS=b* z`3odR8a3>=UPZxeA~*X0usFbql(mWA0!9sO3ld5dw!$$F>TxZs*Exv(+Y!gOmX??t}hfq2A;kM-`TpgjBIY~*&c|S9BjV47hneDd8B&kydn{_ zQ`b6u`Q^6a!M=srM&fySlJ4suFdND1F0tjhdnD&vL>KIk&xbeTlaJ2&?)tPp0|Gb` z5$hpFL$1|=4?fW#-|}W;QGBc4TO-H*avHcd|JG&%mq+(4E?cEbMcqaqS_9FcZVDsy z$w|KF=ke#~(~(tv&o%o(fZqGeBpT}`c7y=^-%n=_%>Sx@VIujWk;uY?q_yzsRIonj zX?!`*A&vG)SfY-?a5@%HNlIYjG+ec5C{<~1O8OvcvkC9w+yx6PH+YSfPh_DUU~EE& zPjR2QB-th&0E8#1IE+o&%ilA?KufRfC0UGG*yKCS*d>_F!I`r354w!)OnK2Sz1T1P zgkSmvzqH+#4vH5Fjvs0k-aea*YyTWJJ;+WHFrJNfgdR__mC!%e0X|2Z0&xkF$v;6_ zlgS5t?;%rcx@yKkAv`9ze-#z=A(0<-)9U)YUtLaLT@UMZ^#+z|b~$frIaH+}uDn=dl~5+fV7{TWEX;!@7poSKzuD3yu6*rqK;&$`6QfV3-6u(GhQ& z!yuhrM#D%)d52;lG@!jn0pd5eTI(tpzR3-;b5G*zOD79-(py)EJA>``dZc=X?>n)GEW% zD2j)Ukj?+DEFX)nwwv?cM<_BP94)l#E=6rfxgV{d4T_|?V@XmGaQv7g3_VOiB}qt` z4ogMHW}IhomO^~PO4seG3Speoy94SA6CmPa#Y>LloR=)FAni>nv))@~Aul6TZpKrz zZZuj~=Ir{B*?G^*6zs4?%18We8u|Zk&TuD@90i3yBHcxkvu%78 z`pNW&Kn_fI&9s7~;P=Bj`R_a0?|8~*w4td!nFZW|md-K9nugxE*r^Um5hl&Dxr9LD z)6DsY&H3*EV1z>e5n$jP3IcHW2jOQFNroq7$^ksIC;*0Avf<#nqK{|Xj?hu;OCW!P z)s8p?i3gB*<5JH?^gO;{Vc$sADpznc9D=|Hry)QdZ!rYjR0cO#id3{g{&N`}EeAAL zp@q01ZD7xDsA@aZi*BJ63n>Y_E{u+a0_##)0-}MQ%HYACMn6?P=3_4zet;2iF~}%Y5ygVJ&%)5KhPjkC37&wx2sX>Im*&_@_o_Y75HJm6 z=x7qo-@7^g2w`OGO#qeB?Fpo@JPRUJ1Vf`ZFCD&K*CCCe;@8Rc_^0=Z>Y$Zc)p)XG8rj$(y(rW@+{Kdn0+v^BY}v zlK7z4+3nS5*~V9R9=%TZp&ldKZLs$dZKP*UgZld60p(%;Zk!x{-P4dlN!uI_ z*QHhhk%77VE7|x8iB_&3fXF(cYQL=BPrye5>czqtAn_z1gd~(=H#c6Gl}*15na*xQ z>6vW~$_b@XCiyx8WndkT_NecX@BvG*Gvy5S&V%e7>`HFGB@-_Np(6Xn3+xpmBo7|X z=q2!juurr*LEVft_=W8%DfKgPHk?u~9@^P&v#DRLsSAz|Oj(Lded=-e-2)Q_)!BI^ zTY2+19Hj?Ss!%LZzD!%V^}92)gG z(TzeJDBj`%2hV8U{jGSi4vE zP+z4tFGQ2v>tU~MVN)RfZ7h++*SoT?5c>Mr)qT}zejlIT^2a~(eS8nz9N_!7-o+-r zu6c+XL~fbVqfAMoP)4XXuq*>LOxZc$od`q6QAHx6Y!;48hO}m1coTkzC7A4DmZ@6I z#?u_6^U8679YK_kX<_>qESyM1DU=MN{h2x88mcw^^nzWR#}UI6ytYx6j^Feh}v7CFt0&(qk_ypZ-c5=5WBQ8U2(_B;a& za3uYHRMxUJui3gr>vhezK(Fh`*4EWYuj>oM(DQZ;X>DDrM{9lDewJR>QA;cPc)woP zQ7^n+X>DEo^t%3hw%)Eg!_~!YpOR+$#BYH0lQzT+lAuX`!_H!VA=y(7Yi~xQ9@4 zvA<<0S?G%zF*~jd}JyzP`*IAlJ`+ng5uzDE>OB5S^w6X0q z_s6X57joz3$!q&DXk{^i`*zxgFRG1J+6ea>V%PQtZWlXwaJStXGq^u;vf;jQTFl!1 z1-U$($=K%V*?gozrL$%3;JJZ&Bf+w{oNO7?-0qOPhd-J_*y0-!hpq9 zfe79QQx+zp7NaqZ92zn?H2CJH6zWFOV%z?j@j>L#SLSHon~rmA{2-__f#7^V@Hq{F zAo2SFM(lQ8K{-u;n8Sehxdy~M0P!v;Lf1EeV!m33GI%uqz7zEDT?WRtO$7_`a99|D z@iGR+>=0mNyaj{CB8GAhJ)uDnu=CrOSc_(B8~o^P0l{_c%N#tY%gvjZj6 zNr-wxCtPfGEKW2`A!OZLrW`Wiu^CXBoLy$Bo}B#?@c7* zrs}(%!zn*izr!0Ad}}0e@`)z<3$zuIdM!niO+rZ8L3x;XaHB!)M`2#+VB{${p~!s= z%`T%D({O}3)8&M2!42tSFGDaLH zfqpFej?s^i-HBYJtR1i8h>=-JtCr!Xlr}Wy^y8DT^aGK)YCl9Z5{_gA;mC0lLKldB zOe6X+Es%apBl_`gMn8!8c3ZJ}{j= z0BVABJxum{iJIICYH}~A$-REmWU`l&VG>m#Kto&ef% zMIdeI@1-pd6ls{lKn>b*bR@$Z8Vb-B+QPnh+A{5=(-s}|TEw3PH^%~hK85Fu@Q3zm zpjoK%pHqlGKpUbs_k!X?hePlB_!H<)6C7%e{&?g7`g27P{ps(eKe>fLSoHT1&0$dp z`ZMk1)1P2G8q4WWpd54UI317LBFFq1`<-+YImScLAzoS&YdI$6+8{3V7%X6+xzuSd z$DBPT7PzqhUg?e`$2hT7kA@%ZBFB6>FbG4Y4QmcVLeP;@AjdFWlCMip-iKHsi{wBr zCKKMZBxp_H%UvK3aGhFR2T2Fw9G$05D&7r#S~Sy$-M#6xi6lYfkcOlwMY@*k-G{am z@fW}xt|;3gK2)8>Zy}VwwulPgO5v!OU}$ z%I*2o>gywHHB;{pBC2cmkB|3jG!%Qp@<-fqvdykcgT|9!O=a<+2p3zJKw8@_)n^p& zF9W{qEmNl^dJEw_ss~XW5>^57?2vi1?$a+;5r*|FX$6!j`dfhAkg+k{tR5nb(tuhK z14XOX-4n3!x^rMpsgO0+nl3FoL9LvH^&PKKVm58%1>D%K{v{8%&DSxV3qhXRr0%;4 zdG_B>+KBx>>~GL3u#0R)zR{tDT|=V>$CjZ{A{Hi8G?C8Tn*IjcJ_7o5Lvwwa$ojMx z-9uDU*naJ}vT46MH`A~00E3wIi_JsZN*N%dC3IFqIfPFDC2sNPAg?%y;Y%3{B1HOc0qxAvBJWz60 z&^DVU$M8bQ*=t?Cr*M$9_r^rvA5QWemTVuEfw4p{-D6-g$kMmx+M=dFYQnPEeYD}A z-h}+dfJT%60llsjBI0BoVU2Vcw8P%nOEffU z8QW(qkDWGF+%bot)==tgekPyI&@X9LHaEQgx|F@WQL zN5veDUB&3&_yC&Vn*pa3jyqb7k1xZ127Dxez#ku@q{~4VnbbczNM3?Qv@;~b(q%7B zwjP!fp>D<;mKT&n2g?s&%4&aD>U3FH9zd48G`X$$Ez@C(u(qx8@!t`#g|UjIeEj+4 z(T&tqXo7E~Bw=mr32|6iq|I=g2Af!n;aCY9e>75^Yxrpc$JWbq+2{n|7+d*x-o?>D z@_CrA+8HCm(qZr1ZapmDGq(dQpMlRZ8mt_RMzlXHbvg{{5kQEcM|){;ET4s<%e}pJ z3zI`UY^qLlZE3YQaxSzGOoK;*#F41X7C#LXk4NN0H*n7m^&dEgq55RlEMf`6J+Lpt z7>3_o9UTnEq6t3aZwDCac<&&rul6d1UYrlk4~4frdmA=tYpY&2xs(AtmU`Xdi=qSi zCnkTOWAC|Bpx3n-j_05gK;BrwabT4C@iUOPeaL%C;n;dzj|XKDuW`hxE6g3BG}nCba_@4sBnHB^(!DA9FY^jZ!`Ci6)#TaBMy4D1+7zbJFpr z%;+$3Q*nDkGNhfMDL%Fyjw$Fu%;DGo&u=s;T?Gsi?Te9KIx9^IO@G^(-!lC*DV+Xp zZMFV(>mW8x&bH`pqXYG~$Igmwl-`G%+BZtrSSZ#`XVR_P8;-rv3E+Dy;dptJdhnA4 zrwtri9|o}vF?@jI&x7zWO7}((MrNN89Y#uMMEhc7g!tHcI96TL4saZTg`d&T-vl(G zo#Cj?a5#|I{ry zNNz%yQ2RnMLVRpJ98=H*;A3pz*pM9^94iq0*v@d&>8}(>Xnk^VJLR`GT`q;H5o3BX zONegt>aS?;(ew8?wQ-!o4I>Dxt!7>YT4o8KwA z5&2zidyh!W=vZX)qxIvl7@~R1$75`i?t=_8qJ3vb)Z-Bu+*>cdpL=P{>C%Yw=w`vQ zuoJW|)Wh0O+AhDpb4kqMxW7+yaQrEnaGJoe^>o0A2%?zNfzJ%lK{5@EXkSRSyZl}X zUw+KtnA$fwIMzbmZ)Z5RxBMQ8{+^*xadYN(LWX#_4bex>_X{~nEkqw-VN;OxWGuH{ z(*v@e>`aPojLtz5d}D+T8I~Eo6M7`Za@ABb^fz{J90yZJ2yAZ)9PjTD9UR}j;Ix5b z>!kq!od6u41TIAyoKJWcWIYMO$nxXIqq4d>;QwxKj0{PCgYmKTaNKx)JHW9zN-w}* zG@{+%sMB8%4kIGth;rx)ro6IlET4s<$9{g_HruniL1n-Uh{B$YEy;o?vSvM`2Skyt zKM^JVpX)zv9n_w^0mg|K!|}r|(NW~VXo3&_PbnN*FAqO-HiKg{c38r@Ac`D>k#8T2 z4kHi4Bi_D{3`vih&g<60@oID-goMzNUp71(4@T)1SO)pIo#Cj{SNDBGf3x zbYsoo=&-#rn$W(Z)Qmjb6yIAffs~#Zb2#3b8Xf(uhyCI-fn)3G#t(2t$DD55_-%9; zIR}ksUr4q){e7cXJHT;PT67qhheotB98U%PJ=1HCV6o@m{fVyDQ;sfBGoquwO*eAU zVSGu)Gr8h?1Lyhvk99=&$Hu%MESbwaakydf!GC65L?KA{y_%Wmm^EV9v?&>qeL4<@oRcMv(GH`=F@l3cIsxH*i{dK7UhF;9=f6Ad*_gmi zaa{KKagTcdHtioGI*r(B|H4_<@$*?4z2~vuq?TzosYN@UAb+>|c4ykv4oBb8i3*iK zIUFd818QA!krW-*mN|zSL}7VdY5qZlcAB&8NHkWQxLhbbET3?yKLw==z+trL zNHaS}A{6utpx}~^<;$z~TkJ{f%xj@^gQDV)&myrPO}<9`3xsj4-zz>ljsuF5+!q)f z11!$L2KJ6gDBUJ1E_c_e{VO`7E$sFD-Pm06(Dx=~lXJw*iX*&j+ii6_-Ti!R!~Kiy zGkDvm?YM8mQPho|qHQzt&|Oh!5MJHj?1hc=igpT5*5%ih7JX|{z7u{`+htSTCyBPk zv@S;&Op@GBn?0M*0b}Jsxwlx5CugYN9PqX~0qr&(+?a+P{jgP@#a=`wawb{q1vrG^ zXK1px0+)(Xr$nWat(mwQy8mKdz5 zqHVj!eU+q)PQxzG8MF^3cE|35ow0C?w>vlBzRrC%t2IeH^bs|M+QAFs6z~ReDfyqb zfb%4#(7t?ZkN(i-4g1ga(O|+3Zo=>=i|4!V=e<#1sf2U*#?D@3I z`0sQhhy%*Y!}#x-u%JXrL~i}nbM>Ohmq zZN~=91T5C&*12A$`=a*++f$Sfi{29!{T8W}_n=33VP+Q;6LV`_MAq>5ePPi8dVDnC zalPv<{`do7(L{PY9T4!nz0Ng+KgRb(dVC<@ah>ZDdQ6}0#}d!6p_$nYpT3;N#?=Yg zIJhQ{^#I*M;R)FTg++zv8}bWS{=c>SVqwt*Jm1LjNo1t*CSg%J&zD$!jh1f_7JZBJ zFi_7(mjAq#f1|Ky56{1e{!%ckMv16FT4?6F=b z)NFBzYi)=7I>qN_rQ=ul8687|#Ox$n-Cn0id|Jtj8e91NN5?%J@i~%nG#qE~6q2_=DRTg2RLu4gDi zEc#fm5w3BhbRe~YBjtNq!A-8|{4tPnDm~^%sXyNA8pR(2DJ}GvBc=X$i)#R7e!)-? zsCOyuoKj~D3qg8I?j~1HdQSMqP%|BOG!{fPW_*Nwkb#YO?K|AkC=Q&l8F|1&>I}OfPL@HxRdgLeb?|jVBdQ)Mo=EG??Rpj?0av+}WA}tVVEG(>!1#enU5>c+;-ETRK~kQ}-bc;;7KdTo zR{DqiX&wD5NYg(&veALg1NeTFZGTc~EmCefC_nuWN6c)N z;dt&^SkO7oorEbIp6BlSCrUA%yOp?aOnI&Y%rpX?J04sXJa@=D_(@Tp`M5oKuI1lB z7#hTLU;j`;&^xw9iJ)Wc~-Um?( z`1Nb9N3=oD-3jlhKYkg4_1w>PX!tc`y&rz{BRzKo+3&fsTV8081!&sF6Qu2y+YP6s zw##FSPJzDrI#^j)-s>Q(mFc^qK1C|5zPkuQ5a+#56W5L@@9hp@0r>S<7=5=#Es&$D z`r0S>Nl}M3tM5J=1AX`6Abr;m#CwnYOGDI^{)8}cL_N(puof2=*GnR{*$jiQ784rz zGA3q=H1dwOHPlP-*GnQtz0-*k$MGy$oAW+U-ro4C&LZl+##fOOhbyY`fz)y<$ zO?`8Ea4dN7vj9o}MGWG_rZ+W2Jq~AOD-bo#i+^N(xiv7$#Dqp>f!GFMUa-Eh4KtC^ z$h+~$R-j&-7X!Q<*Z&Ix9Plg#{@=F(@vMpe_p5apo=pa;@ZwqA{~MYA7sC{m2QPsG zQ}h4AgBhL&Pv3)5-2Y3OaZGve30T>HS7H6Xz#8)Zg6on0w^<$>6aVkdAPf!S!N+u^ zBm+`oR0w*SbKkiCH%k96urVeyaRjEJKkscq6H|2e$Me9=s8H^7;<|DCiVnZ_fxg59 zzrNlQ2ET56SL3-y{Ov4po*NO*{S+?AusnBd0}3%4^dzX0;d$=9l__nErp^xjzTTuWmRh6eH6CpT&cx))k_R0J^2bAMd^UogO!(8TvK zAzS3R-TtbfT<)qUQ7+DNJFcF4A4D(?O1UXm8KIY$+H z^*Ue|miIbHYvul5aF6i3chRdT#dz=2#I<9}d%Hte0Dgt_|Na5U0sk-ALg4>xR^N?< z&H3UWeK*+ud*K=lQSbaqs}S`x=fH8lT(o||NAmZasTgckcufUUId4A1ibhV@jv)~!Trep3$ZQq+M`(T;%5Pr0E!r-2Ypgn#lZjj zMj(Z2;_I0Gnucc;Z~Ea`+!h^?E&6K=Q&=9n1iVA@|1Lu+EDxSekyqUROPX;^dGLvU zFuV%u{{_~N{}-k>^8Yr=gJWTfu7wQf&w~?!cyQG(H3WScLE2tI7zu)&=G-^#pNq~v zHyGF$6Ph>z(=Y(zf@7~Tbd-Ddk5QuB>7<#&@hdv~+6T{DOz`XLrD5=E;By*D8~juU z$FEZn_xuW&VmQ5b?GhB?{$Hq*;d$=9U!xTF|HeG-*#Tw>yb8y2$CHBs{@-U9&wU1z zC$!!h3!ZCvDF{P@c&iSJ`Vw#ajze^x`e z3o#X=Lb*84?ZEzDh+@F682Eqx9*AE}>?zxHnQqwAe)!dqeH*8M_r4BR7MAxqNNeT( zU)XTN^WH^I=)Cu7;@UCQce_Ja0Dgt_|5h^I``QbP_YQ4V-;IUM`QjjbH`xFC6nHb^ zy|(9Dg{Y^w)*JW#M(zIvLd1kdzKn_K&x4!L$ZH?bP;bqntwO!ii4({1ELuF<2kILW zJTnF9zfJHgQ_=9OCs5lf>&1C-RIyl}R)blF(}S;qu%r2Z5nmae7pFdkQr!Q$0I8Vr z;ze*+N5G2@{SL?h|F0cC@c)7&h1P>(!Hb^-Py#4okRH7Fw;H1M^*01Yj;L{7{A2U~ z0uN$BBeR0^;U+Zlg2y$~yX;3nBb9|WCDTzVb&{=aq)FL~eeA8BR?wc&?rxH@$*fe2 z#B&MzMmtA(q@-PD`$$L=^`au>RW&Y1DXnUhvz?+xbTo=~V_wB4oy>~SSW%ZJ*13|Z z)65>pNEz-OVlLkE)Qa|zlG$!F`fWiSa&uuR-mW;j{s-|3N2ky%#I)mExUAS9WBaklX7!jsZv*3^#PxixuUbgL$lB>=9P=Ky`3aQ zG$K)(hZ7sIX}L&Ssfk95veUg@%H3&p4o;MI9kq{=B)b@Pda^kiZ)+T`aU5tL9Psi# z9Q;=|vefaON!i_mHFIjPOSOO)Sd!|>FmcUFt*Dqa*1TIDL97`BV8u4fSn<%lx-XL) z^|gBwon12$8%>w(5-aL)KwiD**o^v%3m@(-I<{1NYpDGsrJ}A=BDlY3BqnY~y`s_m zLTRo@OuW=Cf{8~+B{+MJ_a{C+aeRxzsXnU%4 zzr<`$IMX*e+mntl&EZSDKk@O28sQp=G&H1y;vGixf+ZCPv zFAlGc3NP{xVDwt)&nnaWSu`t|KZ|A|moVDNpA~Ow`}hgtaQ)wgtCuh9{w#Q`qx5H$ z!PI-B=FgItLyN>3^PzoG^Ik1{C9GHL`PN(IL)duZ{nGu9@$vF`SL1ltDzEYX?MMd~MD{9|PJHX#WZl z-opFKXqx)`W#*IZFN?Rgef^Pf_{QPu@1OSJLv;QnA`^lB7$Oy?-d`5)5BF!r$LHku zXXE&Gy5U=CRju&YBiKhrQr1iMo3It=6l`BHJyWvJ$r8s(wy(0x${v%j<~vbQCFR?E z?39_RNWJP@T@Th7BUc1Eev!{|6FDSJxuKai9&BxP`# zR5&=p+N^q$ElNmO6B__3yQ|j@Gu*|9j1)+p})}Z$|MQJ_Kb| zwQ`c#4kRR?<4+r!Ci(fb2pWVM)$R1W#^>|z0;1*=7iWan{-cD5YV zTP>@bE-lwnEf%1vL6KF(ailbVw}tvLDg*zS7W)$v7KtBP4U5*Lne3yoOx2^Z@iYf% zS~NGR0RIv)EezupPNbq5dIC=oN@)m2O>g@t!Em#qd>7p;pgs?3Tc2Cq?^FH#$j94c ze_{$Sp?NCXF5_<7@lfDMoT@%J6 zWwW}`a@*6lJf9qHIbOW%mq>yuC}K zD7!F`$80D=SESsEQ+!hL{awp0g=O@F^aOkiK6TSQIsu> zqHNzN%I?1^ayZmQQFd_@W$%un>~&F;?GZ)U&+{UO!^$YiI-4(RQHa9!aF{b(uU&K8 z!=!S5dPr1RE#vPq3LQi{E9Pb-kU0*V0TpQk8MQF8&N$8&j!4S;l9H~bvT7~?y-$+t z2us{3+4|vzY;qvTw+HYDYKU#$0?C;?N~7_HbyO#Gc{w|C%sBBzajZB_a=x5B@wmq$ zE&S?tXsD#5RE|hZkn&+tta?0&GGLzBV^JPRvnT~-Wrvyv3!$V8&n(UV%%XG=#??y7 z=q#h-fJNzBrld>CAUw>lP;Z8#Hx`(JoR;h?lYMfw(NsM-+hjpXqT7*ldlQtk$=SEi zWeVL-D;E}2O~-dFc4r0qxiLG-f>y(jG(Q_!{0r5{RjaO~MmXmnt-PlmxZ=2{Olh## zU!V-L@=v2AKHs9$DNIVIss7Ez`YzqI{@6@ z4-No#4#1sfR^|ch4CJwecbYcw2=*g@8#HXqz<$$r4B4}~Gi3kOa2@s;Ocf_&ml(36 zvD?*>5)S*)e2+yb0h%9%sTVp18;c%g3MPI}j_-Ie5Z~t$zRxFohl$*T3-EnD!}s}w z@AC=Y=lk$ovM=WNZX$fYF+0zKaRR=-N%(HDze!kZu`hlaKlZ8wG9FYVQ zxd1xNgg5z2c-QFIp`Hys!iI)*5i{Wykq-^Q05hTehQ>R4ni-40dC+B;J{BPfPYqgq zYUjZNtOYvNdGNAO^WYUw=zw{!|Avz|4-zm7Iqs*shV=KP2l=J{1$2mbe$1BiF$p<8 z`Wa(5KfnqwL1H&G{z?PnWfEI*LQIVW(29Vmal`c|b!rg3`YoENkC_poj-GzRFQ0Ht z&p$^m1Fjg3m#-M24`0YBH5t97DRoMDx&5d9!<2nV2wr|OSWdvCdb&7ZQnec|=UXN? zlY1n0V)8*pyZ0<4OR}WwQdq)vI7u$F9Zs~S+g8eWV32c5^J|wGO!kFzYisn_9n3K8 z;D%`j8K5QmFgRKU_g^=lHl&Oc{|1vBB7_zB8*D4-nkX#x0@SlGHu(c;3&dnOwXlaZ zahcEF12Yet(@MQ$@7yrh&kmF*DUTm!)}us|Bh6vJrqI0{JF%zSpj~no$y4VrICfUn zTE9jTj|$xB{Y#g8ET^+4$p4nMp7k_348?i!A#qThTi|X7`kYHT9BB&9d!XAUZ6f!JU}jC@ilN zh2@)^y=s$oLA$|+xOT(qqbslDni$maxBbnx1C6K^mNzr zcr?eFY;s^zHDw_q8qQIPG}{r$;xJSvVzxUHMaL!+OPUZukEo4>aanOADktb+^mAqT1tPP zepjG(L};4*1wCfZv3YjDZ@BmL=coDmRiknkw`s3mUkH+8ShA=b7MD#gb?g!cZ4xSv z14N~iIEaM!+Q&|DsaRQu;G?C&Q|pj&if@WMg*-~uA`{or{Km=;gsNfmIwh8|M6FPD z9TJuJeICC~afx|_A!AV%(h0>`vpa)j)S87q*3L+)IC2?wHn%3eWQMoZYN3hO+LBs3%ok!)jZBYoh!&_n)xF-u=o-R_^ST1Oaz1 z+n1@bK=pODeVHhyxc_8UHd~4ap00%`AP)M#dXH&Pt@SS6xt&z%d@A1u9g`7v1wk&aTIU?P6ePHwQk)pG zyf-m-kszvExm&0jf_F-ZXih_-vQelSM8CM7fL{<>A4!Ikm^C|HsNpoZbGhy4WpeU> zMmMOkbLf&LPd)Us*3HRs2G!V^K2_M)wH?HZ=<-qgmMUUKK9S{-pg*9-b@{bEs=NmU zbgF#RlytV%&yn6Ykx+WhijDiM!6i6`F5g*gXvO0mytx7N8~rUhY`Jf zkEruo8dctcI#T6&R?|O9bL-_A_lr=d-LHe{x|@<@F?Tme@=GA{oFuzN5J&4}gEm<& zrannZch!8>aSsvOkwVQsaqoCfy%srx-t*B@8osA$Y3vqj^fZq`u?s>wfKCqS4ETyh zN8>oiB!do!gB#8a#=+N-)3I=n=?Zmf*KBSDS>f?`7Lfc8>QI4S$(eHN-ei*WS$dRT zy3{XS=$F3SFMWYuy0>3C-7o#a$G-Z%^-F*5m)@hNo#M{o^x2(+HFY*MZ=F+ozPPV; zHx74ey?58HgY${C+BfA^<)KsMMVp01KLfGE1_6VFMKh6FmBCg-Y!+26}GR_YGi zIR|$xhYY)DI6XO_KN;%xw4T z{wL0nL+JS^?f!;U#ti<(4O-6StM;DBb1v6%&UTKxSg5Hh&#edhN}t`w-Fd}X4A7fq zc1C_~J(kZ{`w2C>oP*aohdpmQ+;>*G?MUBQ$ux3Ez&s@kt+%Py1`VTcK-(#0QT}DN zkIyjMr)HY%GqXrQ0OzwNn)a--{)3eEJAAZ2>9IZ;qt^G-wU(p#bHQP&2 zavOeBH3L3Jd#C(HNg0w>Amz!awmJPTl;QC=WgDfUAsI7LCHs(!*WePBvu|=>?Z>VC zN$!_u-Oxzzsl29v3L*L&yY@~j=veJthUkHg1mA=X*4~kb7U)Ru{T)JCPMh}HYEOhE z5T=VyMuR~!BBT+KwE6LiI$oRqmEG~$oYMi@EcfepaIU@ZB(+(KDV&y_Id&XdcMPe5 zA|eq-WuHji&h4K3{Zdt%dnmb zm2QB5C7$L9`BpNjj-<#<}UX z;W^2N_TUEAa5VBkeAP9Oy_F>wR~+ppUr}*1SI(+9db!-Q;%J^wMH&EJN^^DRiDXv_ zPZ(UssXxPWvRwb+iA2|zNJ#dnIRJ5ieP*70>OiC{%+M|=^RNnfs>N7ve~uOB&FoMg z&N}XKj4lM&Ey9}3rlRfhr%B3CthPuSEYu{MFG{FLNRV%q6dNHHBJ$Fdk-h4^?0T@? zAmhkWmMaxbNt3Z0`xjIM=6kiQ({WExgPh_i$#N$_@TDO)ITEzNHdU7tk}a!}6bHQu zWptWvrF=leXNov=$O2b7uU|co+O%>nBB2``m#S)h@OT_0+3=z#7k9D_4aCQ)*?5ZR zLRTVwBgO4%M08QvAnbSHFkKcY6hff>k!1zY9UjZfG@6jK=Q@8lg`zzLh@9lKXA04t z>5TU9&|uJ?M+8QHK8lY1e1@nkqCYQMoEQChdvb!uM$tG5yCM`vs2q!EP725AW?Rj| zafC_}a)5;tcVltR>u+(+%oFWbiuNmrFxg+CQufzbh|cR2qN9;6*Y7}L7@>NJ2$iT4 zDl7`pqbE$w5h_Qr1!M%IO1(dmIw@3s4+2mzFB_EWx2R26K0F%~rII{ijAW6ojU`Bd zCt~#=UGAkz4qf^%+Op z=V#$f+iHT8!3UVCRrsn{c*R2_MEf;vGXUaRf*ie`6htArm#fDTcoq2}tC&qyD4nWm zHInz9Xz#>HUJ}Z?Zo*?nNnvr8Tu|Ik&MnTB&nv!M?okYaM=nQ3@Q5rTk?hLl34`lG zp2%|b<%vWW^Q7CaWb|%o4w|czyhG@?KKKS}cRuEc);_L}2#`R7u7zxXg-SAq1Q17% z_8saSXCvrMSW{A1rff15HOvR1dP$?mN#mI4NaKLSrqrtmX_W7eo-FP$G_BYH+XCmW z!wbo2U}4m5i~1HKW(n;c2IX??p~(0M*?Sd21w)a*b5IA7Q*i(P5mFctWe=d2v_DL% z<+QF)??TIIw{@nml%tf>{sGl1l$_=O`GK64yD30UYl5Ic

lkb!=i3a4^!M)5u7m z8PNbf66lrHO0p5TC265s5Y)zMf*MuB1+|_unMqLlj;1Chp5+PoHX?DO=;9}+eWMY( zySjmrl@p~~4MD~|L996JC#ih}E4mxI<%E#bAQo{+jlID|wXOaoLyKy&iEibit#~a< zHsab(z6#e|`9fSTm(RczfcLong(RT&Q@Own$ncbjtkQOu2*MnN&u#>HBs8f#NNQa>uEogc7;_X%ukBNAZNXGAv9MgzLQbtqa@hy>-7Kq1mP6c#5 zF9PDB;tf|Jf2{@L(Jsm!BOXum^b!vu)R1T(Y3$U58mN03^|(b+6hakdRVWlQtQp3F zyEC~y*AM!f`#flNl7~DPTme+lOx5r`@EZ@_BYiK3d6@-paz zPv098L{0AI)FgzVBT~`Fab8H;64I)28_FsT?k6G=5;}OH0Gbn^6Shcqo{fs`bUT;R zol3j~&2DRL2+i&;JPXw9M$cHfhKO@mv&2A_p4-&DrpboCtEk>%9n%yIK zmFShLi=SpU=J>G?n%(51AZc^dlD_=&7QES1vwMR`P=IFlN8|))cK4<5D$+w%F@vfI zsoCwp6W3^5n$heE@Q7)4SMo%%>tdcTxX$H?ELSg{NOY0;4%&EA&5oqRkeVGuBL!%7 zn;6ycGkY=3?q?wGOtT}k?(U{)-PqO;swN~*CsdlCBSU{|Ghy}8RY+x|)Qw^S(iU|z zhz=BiTV4C2Q0V>+JP9E&g`{fLC=05V1VxYNDEbm?wCUiaEGEqlpod@n$s#dB?7OWJxM zX1Y$w-N4thag)*Z7TtTVqAE^z3`j9!5!p~!;yIo`NHGjXKMk@P{Q<>^?tFOylm!e7 zRwK9>+_zzK`6GU2qw!zivDx1kL=L_kL(ntPhfKmuR=7Ft4ZwonkRfA#o z@~Kx>1x@r5KK05-Vu3_)Xd`Jq<(s%i8N0$XahwGR89+DYknYz5lX#>1jhOJ_Q&CB% zxf!SyVSess^D~4w<`|owk(y%;0(nUk_#AJEYqNk|P>x=GJ%n;pixPp#(JS;NT{)WB zUt(^rD+0V;tC`npwZGTve7wbUqbrc0IV|RGWRn={QtQmQ8~GfL!1J{Mwn5U5`k@}K zAMM8s(e)!qpVpV@30jRnlX(tZrqRXE^Ysx*(PZ8U*RbnXC`mV$eGmP}ftzyMyg}Uc zCBgNz863quOI`X6|2`=`O%)_^Izc}wvtREv!|!zwZoRd@@%65Ih5EMUJG(Pv1>}nt zl~jMnS1NaW4M2HDK!lo-LFHo6M%f4e!ibD3jL5jch>R9LkJ(iFmjXS?&MnHs`;e)~u5qSCg z=wA57W5=2yApZ1&h(AbYRimb(yv%e;`6}0VmeDdv&|_3GpsIl+=z0gp$~1~rkrAx| z0yD+uHa^+my(gW#grY4z6{97-&n%u1^Znn#&Omg97Lo?>{V$NE^Zk@pk`wHl=ewRm zKI86xLxLE3d2Wl`y*ZWQPk6mmto>Jbk*57$FfTc4KXwpYJealr74EVavv#stoJOqu z%EQgg%w|}7DOh_DKff4RnwoEH8$TZng{MRE^VZL`3gWC0&$R(*e6F2?w}R$cDzfys zw&$e)8C$5y@QT>>(IB#jo?8z*G-1@}#E=Ic8J8LuvwBi0BQWyC25Orm8)Yup!sxxpv`O?2U*Wv;FX0 z7qzUs=pFe=yxULC#x+;Y#PxEyE3SFghlriJXXBdeet;OMdn(D+<-|eV6GO<>7S0j_ zRpwsCf(J6?bQnzxc0{=4*ym-r`)PN9UXgOze3<(#aKHzN*C7V3YG{kHb!yD!;zn@a z4mlTfMjL8QMlM?)W%Dvp+4@=V5#oWL;VrLhJ$gw9*?KKX1j^P+=}S?|*5~0ZCR<;Q zL|bI*Z$IR+?S-g^%hq2JHPE8UqLi)4WJdG(7hgb})@AFLz+*zl*1!22vwD{LswP{L zw%t^=rr-%b**Y7y!Ls!~zU3XDb#qNCAk%+n*_u|+u`t*0vh`9TW+Yqxi6@d>w7iW- zg6l~nm~3t5If!i;JW)Q6>L?K$gfuOOtXwAq=DB2R4Y(0f$d&K;HFf1=bSCa8o5WoK#=&SSl z7ysastw|;}DZ|0o8-?oSxPg3Kt8;d;p4B$Bo;4?5`}lg4rZb(d_dsknm#=??Y0l(p z|A?#EkoQ`WuiwK|f}IPmL~J^{fM)gY=si=>24*^gx=f}s=*wg}gThRvv%`7ThiOK; z=ir*`obj;f_IWYm>)*hZ(joae_Lsu`*ge?3dEQ^j!+(RAY*6a?)>P@Ea@Ixj z&o=NWWcx2#I~THz7Ue|0y%gK~Id#bYU*8JSpzi{i=b%+$Ro`ab6^ANM%3o+}Ri}S4K*vz0l zeQ-^7XW(jZcg8i#os6q*Z%AF1jn|<=g8#+>9zu;cXjK+*ilTbb0l_Dr1AG;P;~xoPmZG>DdjiUm0dR^04R zZLVY9)g6!@Ji?=!fjdoNfrLuh5ku4C16ROd1)Zkd)3L7J;Abp>8@BTpJJpr>){a!6~p1vi@yDFSOE+!iFVL2RZ} zm^tWy$v|IW73(?Jur;{nZ62^n*fJxUgX2-Kl>;U;Y4*vQgDud?aWF5iaT2j*c`3HH ze6%q%t^6Cy4zzXjsF+I!G}Ch6Yy^Zv7(X5qJQ)qC{O~}8!}NC)#4rsGj>~MJ#ah>T z(6+l;G^fYV{v#BgMwT?8kz@~RN+TcL*O7*@C#(z+%{bTBu^h^iLLI}<#!vTlq=CA7 ze}n^NM8S?R=lH(Y{IoHW9SuT_8Ha5#kHr8l!pF!{xvR>1^DHS-{B7|OfK zwm9)FO*(_|mQ>MWgeOk4Nm(BE1$0A>II~hsA&}VW9F{sPeCKyILsM;B@11UUq1{O# zf%-vyLIC7PuqK_1_UJ7;nK1D28sZ*J^rqqe3YOV^7g`n|2TGKBQ_ppg$!wAANW;~p zU23Z(v8wvu#AL@d;7+OY-9Nu?81#6|`+q+3)P6@oHf=aa) zya&|A8s6VRgK8zbUsxO5m{S7pWB&}6bDj@PPpVmVd*~LCqxT{xLa~!xVlQTfp(Q_m zw*$et&!-(4*8Se;K(PMnC#N^8+a!0M4YOw8a)&5n@z%=!Fc+TeZ|1k|n3V`=4LF&zP9{lQzUKil}~}$tqpDe z`gOE@$L`p)ee8-z+EQ+ti&dQr@Grj-$qT@64txG)An^YVcBVc97Ksq*RstXO`?YEC z+Yz?O@10v3BYda%ew+=-N4*j@rdajkFOUbrBL@18-7O0!hHHqm&p|_)P<1zaj}2mW zC*W#<>uE?e#UrdDd-4|WAr;ko>qL1JfV1+Jg``nvx{dVIPXEBidHUd6bItaodmYB2x%O4 zli=FG^E**`B`)}MMn%CiY>Z9YrivLW;5wyKED0c$uEqGpyD9i_aoaYPpW-Wz zo+Y^7;pa$hN6Btv^dU2j8yB#`4Z?z z@p0}5S9;(`cM&T>{oL=py%{{vvm$zaR79nJ#qGX2lT4BNw`#-N*);&Kb5bp&OM! z>|PIP6DbJZukjQ_@89y&6nPGw+#{FcI!&gA$#M>^v*kXxLJa>3UNArB@Fu#SYxos0rrar_26y@o#>XdR$E^-AOyl-tysP~xSfNmM(1@owyBgTydQEapA-- z{?Im@7=~E0I8OYya3Tfr03@JR%b3@I_r!6cgW&|$)MiL_IXhFb&(F>pBi<;E5yy(- zB;_lJpV*u+W%+9<2~z%g$zFN@4go}ui*J%JZmgLjF26~v5sN1;xK*fJg)DKdk3HOdI^I!#{xVY5;{SViTJhcT_~QHIk;V7R{fno|nZ+~ZZpBu4xN*=%>rMH) z-EXUNoeLjma)aDSSmo+uAD)9laIgW=2H3*febux- z;-@Fpjc1?@5B&o-De6B#+bV0Voq)?h|x3OfdyPHzCOJyI&lPt6HJe%2;DjiTu zk2Ws(Sa_-yCu&-g;q^JY!F2WBJaN#wa*8B9wvM4(w z=a{`FrNOLhS4&>QwkE^ba3m2#Zmx4BqGi@m7G+Xe{y}Q?5LDu;5-U7-m2z*h(x*&W zzcP=Sy7o!l)IN$pE$u`N?ItFDFBTn|zt){(6L9pR1uKf_ltkM+DM5H_AyW8=k@nHX z8f@p7&q{@wuGx~aY_ILEy$NN`$=QkG3escAO_ik%1aGXWwMr(XbT77hk#C@ecvoE$ zGzGnB))bSWle?E+cR!=Pj)UJ9O)8oxSs!(aXp*~Fs{=dwNfu?a(bvtOy3Ww+GAp~O zs;;QYc00&>w_@m_;94=My0z_Muqxu?8{Gu|ZPG4oLZ1)dhb- z)P-|G_DHibzQC-^G@6xpl3Dpwq@z4<6(`(!QruGQq#AhTMKs^&>Fowoz3B`Whpux*Rj3ja2p8M?*p^G*!Ly z`8ZXLn)-&Pt!Mq^q|nyCzNpjILw^B3>Q#-Co`9RP--U24X=)`)N&WKPvk4ui8pQSHBQ5DmooiwULT``$!a2^iv2H zaoIFtIvSpSzW@8?=%*37{qg|azM*B^-q?a}e+H%n*X?hxgNiZw+3*{rB9u*)N|cR4 zw>OXlp|85M3O~AR`a%V6Qq*O?_R6LUyi({4qRJ-3s+I=IQ zF&UMq_l>%G-+OPK39w5k9n@e=GBWkPH`M$3L}h0G-0yN{N~GK0j$Oj44nBMn)N>2p zu)?eu)69j&3@eVPo`dapl09`$ej7csA5S({;mZs-P)gg;Oi61nWa*3d4LPU>3zy`y z(xh#sqV4lv;)?OSER#~tbYP2fHL3Z~;LTi#SC2d%NFv8->iY;BEsT~8RiMY7DJg@o zQe!Z!)OgUpO@jL@rmI^F_h1)?P7<{y4+#reB4`cSKu0&OCfywe!a#3-xSVwM(nyu| z1uzRhyzH+l?frCJpR5q1)}tfpKy;!s>3b6?=1bfckYaugl|va)%&D)?&AAmIjXI38 zPUejBY2Fsz+0rPxif@PLs-M!`d2yVuH6?4|>DO7mIVtq(Nf-$^{VIac&*|5PL|h`I zUvDo#*(m7O^&nE9Un3vFk50d=l$WC3?W13G0&P>>dVZX$MM2g2VLbf>ztfGXy$H2D zELFQriJYnpK-rT;)ri{0#kHn%jdH@%w(FlhDYWey@J&wJzIhlFhRJ5zeu-3sv~4o^ zQKF!2bGdAmPCq(rd)tPa6jcRoYJQivY!;1dcI(ehZz}dF}hC%k;-P%Q1)a| zvHO6PaVi!}#Weagjr_(q>~oygZ_J&>3xA;zFH^RWLKxS~A@7>9$9dmgle658D1*tf zXYezqkQRl?y?BmPiCl=QNqFR6{C=qLNCQuemaXMDFCq_*Z;`Wbg$wy5{s>NFI{yU@ z+`ofevQwkfew2C~xuWB3bvB03W#fhaZx)5M-YwsS>wPjseBLh)z;(KO4z4q00arMd z%ZnPUSyrBcnREvFqDA6T>?3>G=INF<0fDo znyFxFfl&1mq?rB*J!PO-`Jo)Y1tQz}Tyrw7m-96z^Ln|9=p5XQiVSq0Emm%oJFUn? z*WCNLt9iYgj@|KYq>~>`W@tl{x7+AmxlI3&-D7C z@eTM{EvO%E=E6ESkd5Z>LwCHOC+q5RHho0Bk(!TGb^Q;lJbs48J<>dw`Au@PFyULjA`mq zV4appd#Nr8-=@Yvg%xV>+_zh#&w1VxjaFUY5Z=c6HZeCReI@>bqB+E*<03xbDVir) ztAL`W!YhPFSKxuJ`>q!%U&O7X%)|J82p9>EJ;OiV9GtT7*rIGy@ALokU4C$yASV5b zT+plCKc(mb-Vpa9^oN}7!H)8+au017tZ61gs_PbE!~c={$8U~v1{fbj&Ka%%|2;XJ z;Y@JuSa62O?<pw z86qO}ttu3TKivAWQ^FqT`S@mj=Vy}*{$I%A1t*vRIlwD+w~-V43Bp9goM1XID_TylVV+-O zPcA1I=Ktw-_q<;ft~0B5OP>- zg6u>M&Dn`wMse7QX8xbf1G>XU;pG8KAfiXDBW$$Z!t6w2CPl{s-hh+{9CUNey!4m~3?6MdwIDUj_4wgGM?Vn@t|HWQVGGZRfCGtt}F!?k3PxQgsV z{3zN6*n{f1p=hgaC^9*=;Y{?k;#vyAr{{iA4CljAH2=ndIMB60?nGy|GF#D!a%93* z6d1`c(WGocyui&NA{ly$1yeEu0vRsW0~sdz1v21cm+D~+IHuJX%CMC}8UETdl!2{S zV4)1$5Trhf;rA!+H)$rIktSsW+GeI$1|0mM$1)fT?(u7u;66u-Ww;Zu46s$Cp+SX| zqQ>aa4C^VHVI{^5#-H~9G0ph14M{Tohz0lNSi6wvXB*f)9$J)nh;?X$~Gl!llUhYftcy%8M2Y*H(DmuR@FX?c6JwPZiHz_(e}seX(}*h%Bd#9B%H~_HptAR zw8e0T-cmamQK+G1Nr%OxuZpHh*2nYriyVh2*x@0s!AG9Kp)u7T7FRP^`LX zcJ+&%*zSv-xV9Xayp-ZmLc;6PknmdUZ?!o%Gft6PB(2Rp3`282pLa@VZgml?_q};EP~Si-sP*1s)H2JQfVWOONj(8l9rfhbSDEff3BxPBQQ>C!9W% zxAFccDDPs}3OWYm%^wd;ZWHDG4tB-3RU!fs+oTBXg>7+){pB>XveWe`Lfd@X9*;aM z+B2$l&rPR8;}5-$8}F9s-g=tu>)oI4>zxWYQGI(9MXJf!P4@N9P=@!fYDCS$QS%=A z@czy3?!9&E|Ficc@KF@m|1&ut9HGMz2qGFFNF<<#G~j+k!2Rff{`^A%?h^y< zyZP@$6BRBgp|8#pv1`t;k1O42Pj|YF_HOub3{=FZs!bF|Q{{Abu@9yfNltf^y)WIx zIZq&8Mnx6de!NQW7*E*%DE${u*ywsOBoJMnS-`K^ zpcQ%^pymGv3O_w>g*`)85u+>ibJtEXu*s&zJh+)A=gCrB9{O>GJaw$|NR&OKV(zJ zQRpo@R47?P`ysf35j9xUD3yBcqa=BGoK)IiA7+-tvBJiwIP1EbdSM~Ho(a>F{bb{1kMeEhuIGH!!adohRR7Yc8Z#bmK7$=zy?xi*t`TVcs~61ht$l) z4DUa0!QXk3yo&fcxY0Ri^fWZOhibQlX>@FTVo2=jjW$KpXpNmu8>RS+@; z+MNvSBa7*!6)XDFuq>v0*ib*H!g=_Fvm)LlrhCqHoC9m%CVN~)1+J4FJ+ToQDI`oQ zVJBWHEAnG!BT2#<*ZFnohd__G$pDWwqR~?%=hm5svoJVfMY+P$9kXlsc$D_5O4+lg zyjWA5?unLjAqMV@qx8}WNif$)7*-``4jqt`lVp?crxI-PEIej>EhLy4h1Y+P^|jF3 zoH8%3^njzMO}U4vgE{6&vB~!sklQLZAqt$T!lGunSogd0qIXIAk68DsHc-7(gY^T{ z50Z45dKmOPfG3s3{z~$@Y9j^{Hfa_6g3-Q;&Q)?OqcG*-HK_&%8naKmWiC)A=bCKt z)k$XI6{A(YHvxr;#p4qeQdF@~@>Wv%#D*ACjN@xjc%=fbiX1WKaxuy(uWh6TC{v>( z!LlFIedWfoD9O9MJW4FDHM3iDc}2-i#}`=sJ!&#GcDqn-j^q5`hWu*|Z-}JKNK!|T zAV#aojpIi<;$bkF&Deih~iyKC+T4WMmx#?>@52qhChBKq)NO}4B~))LQQ^MV*m_O8Uw`0)q(UM z%g8^+NBPiH=MnkKyBP;SeVqr|%rU7`;K`)+uLfb^*h0<=G&S1SEYC_OR**_}`j|kH z-|;blB%jcjK$8EaF@Y_5CzwFm|Ah@x{St-#&(k>pySmx1sv*-1_DBz6gf9U?o$^96 z!q3V4?hK4j56>7igfYT-B=Ap<5o*B*;8i0S!IdMq51#a515(Zd#21V!Ix9B>vt28^ z(V=qxGq~D+8gkzN`Pn+TFM;QyQ;@rRW&pWgJo&WA{ii4QJCwG2K&t#SXgdWWv31&h z=-N&~+wodMm?)oS{vU1o^mTO&9CtsgPSXv7rsH&)5txGgk#(9u5SFbof-FhY#h z5XJ~o#M5Sk|LHXCwPpLlZT!=a`=cN~TPOD?^E(N-Cu$90fODZ&+*x+&0*2J#_>8Qolg7_s8N5bLX)6&0q_$b3FO&)Mj+A4$a`&!t`(+ zoGZ8oCy+ZB>|1aLyg7_JR_ffbl5s~H{+xKYKTb#YDGc`K6moygL(srU_qj8iKWE&T z`Ev@}_UD`rq1rl=+^cy`ItPok^J`eXIg8`P zcbNY9X^a>BAaYx0g*!B_O6OpO#z~y|87o|I>6x)YfQIxF8ZXWw-A7}J?x#Wb=R%6M zPWN|f9+%ER_Xe#sjP56m`5)b59=Exkbl#7wC;i*fk$Tb}pvnKpdeZT+Z86Esnm49% zFvq!|0 z+)s={oGz}edVkmJ)MAVibPD8{3eP2a-QBdh9fN&9qfg8DcRK;HS_&Z|Fd}-2 zAlCtbKtCw$Y)tPIwDW`Zxe7|aPlsQ6T;B2g@(g&eO@2A||3`kgb9CpS9d-^T3;U+k zArQL0)d&F*=)%UrM)leA7_M?nWp;`#Um90tPPrs=QYr;(?o~H4kIAGY3fYt7dzf&8 zNKS{#)h6$yolqd?_Ng+|dd#v6VnQ@AFmowM!hHptYkHNl=oQj4ZG{ z*qz6oc&t03br)fy;lgCr@r=(|*Oh$i+PesyIiz-nKqCw3B^q|N7GkV0BHVMUoor)hz$M*Owm9VyQ|7H2bRL7fBgt(-=a(2h0G(t8opXeZ zC@2(&fF?bt*AE*O+sg+LEX-L<04qCVd_s5Rbrf_YWi#Qy(5&+q)av1dSgc;nV{+T@Kj(5oV#h^eqU z{_A;T?!eaQ!~wAr0VF1m|8ePrpSIK2Yje-0iCd|o~x`1v2r-X8$z1?JzWmq+p}j@UZA`4TMk77#a1y}%fh6Ne28 zaCBJ4fsCEirgUSCX;gn^Iv^??0p6*!3^LiEHo&lhvVRq=Y{W9tWc%eXGD2Ua#>doRz7xt^@i61Erje&cZ0Fm)N!{oKPOpobtTEqg*daJ=2po$ z$@pAl9cjmprVFEy5{$HKFc4r^+dqU+U)M1eZaRjc<;ZqFQq_X~3)O!A? zL13g^1O%p2$7m_71KYkK9A4O%3oyia09ZVg=O&lMd4`9B#T_h@G(Q&riPHcAt7sNB zF2l#zI}Qc48z2F&YYqR2?Ztmq=fr<2eY~SzJNwwDllCzrjsF9l6Ya2$R%m=(-*(b? zFU;!vL}>gD$l-R$xIQorJEM$ig~or=yPbW!=(5h)$B;C>4vJ#iH2!2lJ866*Ot_y2 zjsHeyFaDvt{Fl-A>%H39$0;zqI%6M0(s(0g7TTuqE%EK7ahl-%iO~4#J==?a7+ReX z|MJvSc{}zj##-R6!j>alT~kvrB~lMJ0$18Xzn>D<`uicnTYtYEUYpj+|79EBFVM}8 zJ)zq-Xjtpz?}w_{TKzZb=24jPFHCLy`*Gm**2?dZqQC#E5i8FVp!(N{V|(D@-c7Sl z{IA8kzxcX^eQKJ0H;!ht!hBZ_+augN3nW>%ci*;B-!vZzTejtp4}C4)J>vsi%Xc$j zp@(bBV0g5{y}QRp4!(VI*zP@Sdk=UE)3L=ijC-kZ6ArstBTpM^rb#upGie{6@wAW6 zK-$NL&+Lr~n%g>$!d81oO8h+sq7mtuYqHL-qfK$tw;>~OV4C)Jt^cjM3(SGlwXh_y z0Z611aXx(t(}LH*eTX&AZ>jH$BsnaUl#;=?jk`j-Ikz!asN*(yMmq1$)nlDaUcp>P zR_zsJ{Au%)Yp}h~MdgzN<|&gUxd%15J393Ge(F#UY5sxg$>>iE_2-;`_b>Y1tBqaJ zqsi1GwogbT`2DdMrxM`W zPfwTl->SdravJRpNl%BF2kb1-)2;i0=;>w1qab>k<9n~Z5Zig_>34gB>FFrsl^-vU z_}{7@#hfl)LhnN)-v zuzg4M@)r8${(bZB3$Rv$Nh_MXah~*QI~56LRg$kzcSN&}B~!a0nK1Y!yyEBZ6d69mXf`MNmy zYp6xVEBP)(yVV_Vl_M$-vh4uQAh|>=&NA53uoqEpioe3PLkJ;?nQB$6Mse+7LoxPB z63jbA?{*tf%-Qd(+Q)PmQQl61BC;v%=5nEBo6jpG}uJ<>9)o~pJBB$$B7_{l?(Bdg~66@l5Ru7(Dt36kr z;^}W_`P}diQ@)P@aJm-LTp_NXz&B3UziHnsCnFutZn98ub!zRItK}c5)e}t?Gv2$% zdc@3Pszf`KA+FDeeOLQsCfF0ynNa;}3^a$R-rUrL9e8)71_Vgz-#9By;iCfVnwnUU zMV}4ve>SG&XM2tx7&4X0Ia^nfH*C8~lXEk(`JiMu`fE1S)FiV!vC-@jN4YO$Yc9nE znrmd|Ugy&+X}W|U(@gO%FxqnC#7*7Nc}mV#t1#EAO+V6+&-qHe7rXZwu`O4EPMb~pPHxigq~Wmy9}X3ava}m94gjKkb|iM!ajZaOQ@T(gv;aTU1!4O zUhrglaG3!|W8}DuMehG1TxPb9FN@(%Z;8t&&X;s18t2O=aaZ6Z#(V&Gj4@^0_!tw@ z{o~r=%z>OUabQ~OtZ9PCZx1>bKr}~=&dZRy6QFZXq`cWqd~N_QbTWLthiQxU;PZi` z_TaMsxjO|u^}XBW{KgGN*VIwkSnrFjJ;U_k6{!ZH#N7QmFE6--U2sCZ8XhiM)G5ie zl6(xSIo5+kZLTQXm9e|Y$u@a%ocaK0gl>=*zS+I%+ut{NZaI-NViJCW|tZd`6f z?>ZAM?_*BD$o0VEuuCGxQepl@j?N|+k(~gY z5$X=o1K3Vr#`^?DQ8nixsGK zB2$B*URpcK>Dxi&?1pXS18Vd3@E9oPI0O7Eh;p9i=wo(8F|Wl$oOA|&Ap9AglVr6U z7ipddd=ETA{Tg2Ft9s8{UL&sC4$Tm%d*pT3L)S-_+f#R6^qbp+%{rc`wzKkCZB^c) z-(l;%fK7I^qvIb!r*5_5q#Gwqm*k@$L{ssK6k2&Fl&*tbj#-QZoG&okUL@a79ycsd zUO6g#e7EIuBv;-sNwHwoGcUocOvI57Sm3QpKSusFm!(m?6&=PIIMxq1B8f zb9q?cHysnfaOeHSsC)EK_t$}jW?mBfd9M3EA&;Eq)pPuz^gz*I`0^Y{a2KrZ%UuQJ zBiQe{pImnySHu*(4ptAAFw8(8O-o`v!<4gumv_+K$neq)LvF|7<$BcZ8^q5tUXCE> z=!eA%xrK>egpEcVeLGwzS&IanZG_TdJYl2AbiC`fd~RFpQv&xo&~!PmPl2;l{`ooP zaXS`IT~T=$JTVQL@y~hWa|_ErWf3!wh&cry>e{oxKpOvr=A#b9*V~N|Wp$SEMQ8s7{*!)GE~X&T=hE?A?O3)Y`qsk*t%eihpw9)Yhx-&GOIRfb zv~jxS-hGzJz3eQN`vD~R*?_|xyxe7cHZIEX3+HAYlX;^we=UupHf1dh^){MkQpBVw zN=&VkU2D&getOYQH)j);wHHAgaQ7rHg1(^7tx&ps{(tG~c4*W8ZG8=tjdV}r8(%}LaU#>-w?g62 z7*Z&G5f5NW(t3|9cq66}6N)7do79WbSxSQ7;X51!KYOycv| z^n&KIKmL#zOCLp`60jOCMvb10T=A!f#WUK1=&Zt~6f^Z_2AdZ@Zy#*>qQQ(6FlSEoO1Tpw+}ks!Y9yS(1CsslCL@lK3239v~x!A z8FZ|D@HzNhhr*|Y973#-EcUBZd%l1noXj6}Hii=0{92omIHM^BiooEyq*z0qTq)wn zYiFZz*&wT2X_fa&l}%lohp$9HN`+O9c?{pgwwDU9fA6@B^}K!$lfKayBqF@0_TZwOS=dg zE7P`DZArkP4D`lXfHzy_;pk_UkDlNFDafu}^3IlHdTPEuwPH&F{2VOrIDhINl>B8Z z?E-(=LwZ^tf7&`d?Gzfu>k-!70`*8w|1==|XGq^t&{L~zPr#eZfG=JSNKXz(e>@;P zj!Me!rIkd!AieG{aG)ozd&#YO+IuW*68f{`dOfWgX&?^S2*DN&rd}A&WV2};QqmY zdso2y>VW&(0`39B}Z=7R4FteI>b%DA$6?)VKG;Fl_YNW4zIxXlDH0J*#8 z2BW#8mSEmna{dZ1$04wQ`EGT79RoNfGyv+Lxe97EY!8aXq_&1DXaI@?aCfOipZI|r zrZ_&==G!w3TYkk(If^5MGjM`7j=e2jVT1a0NGN#-%Ue9iS4xg`o+-}UWUt2zs}6nqHfjMYApO}@?)woo{nuSrQpp;oL1Oh=KVC(_oK8GFg6)WNhrqCLy0j{s16(!9pDbq?Y`CL zL*~pCHtu-Am{wXL-2E&YeOJVpGuNbIxhf8p@BJ@CH-e<)UzkMsIP#QiXL%-LViOAy zY&54TAB2js3J=(|R6PWlZkvA$GegrP*-3n010T`e(D_gXp$n2K7_Yy|DvGoB$Ntik zPaOd|@M&wY-kfAl3^A8A`U`J$_EO2=@>m(Ok#n}qLAe)={V1Lf^g&~CA54uCd}k8O z7vr>ZjKy@Ke7ZPSoYV2E3N#))eH+<_COPSI$b0q&LzcfA-p+Vii_a#i7{q-dP>>H?Xhr6d7_LN zBr4NMVL*f?ZB!wz;`@b*?KsMm^@Wyc5)-2*zD+qa#SC3JVV!@Bbp`tgHSfwLo++#= zX6lMfhV(>Ns%_{>u5#{WHn~duEBt9zxvOMM!mo{Wr>oYT%RTY7>;`m4@Oq-nMg;EM zK)qN@o83ZglIN}63Q)LiP>J)b)ECu;O#q^gpkGopHvX71%Dw_E6NT6N`yD9Vsm07Q zm@DrBQmpa-b?a-)PvyuezCGPwpXj`O)JVs8w-p=((hfng}59&3qUTHum!C#C{-5vqKMm^jRTkUP{gO`8jY_v zp=j>(W_3}zA|75AC0AUR)p&V62w4JQQI-^3^Qe!3Us z2{t7UE6*(3@Z1&818j;#!1GPGKOfC36a(Ha%1u8&!Wgs z%iHFBhL)h6EMEPk!7j+NJ;=OGUAY%~2hB__UVWS;e!~(ASYnD?Bdy&*@R&Pmc1XXn zpUT^J*M4|+Yt-SrpuWT4EyHT+KzLvOiwNM|ksxXM*>I-|Fx#IoM(F{v&Ln4up60q6pxfwkrg@`?JK(1n0A z2zXz{63-sI`58+v1`1);6eZbQ^OC1CbAYXODTLM`Su#GcxfWLB$zPev7S>tiW4Nf2 z{2nfJ+X&~aJyu9CcoNK6!(TlX!w_PsY1<$(G31WVk0S4|6z$2u*4KPsJu|FvC6YB z*Sj>;Dz8k>ljmnz<&VjV>R6R3Vg;li6VN4mX6`dXo-S6 ziONd;N;eVEQi?`PQ#dX0If)?ZaNmQX)bF7I!$-GZ>8WPKRMec9ZUQl7AZz5*bQOZL zBB!QgzSxpkdjY9KxGSPa^-8f7QqIFq$nR}}&3;*Ol^%nMCCsQmSBt2} zF3SrL%bSq90<|ox#XmZ|@E--jn$p9_YICh#Z*%26ZFc>(5szvd%mWFID&mF`kg(WL zW3*pPayStJ9J?SYDrK|$p~>q`gN059_?V>ZD#x{@-lA)z?C+LM^}Gjuv!74hgfD4D zthww0&v;+Hi_n=2uP2RO|HYS@q!r9ws-OM7$-51qYF-Q$W#rJ}mDVA-cvVVKl%pqo znD3W|#rEFt6s=i3It`cE6Xe+?Jhd-Nr6E#Q7%d>wW#Be+cI^(L6%vTz4Rhyo zu%Q{TRBSt==Eqr;lAtXzMQqN(3edDAz1mVoqbUB5;lB|SrjNDG3Hb>2;A8C{cLvBu ze3ltJQmRW~KGI+#H!^d*!e_1@W0pA|ZuY#csUM9jkq^IfQND=yn7$FcZkvY zh&^T{%+~6wX-U6G$2^S70kVG2ROYC|zl#53`1dOoLe`}VRBbHSRvXY)a-3umy=9PJ zq$;d=W-I;ZohB0g7mte-U~1T zpbOM=8WrZ8@{FboFZq%YJIbUXf2+RwoGvPRBPC^$E-RlydIYlaGM^;|gRbLcrBybVg;#cJQv%k4VcWUu88Zb) z_e~WPI1k78e9{e-F^+*0ygRI+GRodZ+60L}f5lRE-7*0yA|%?Sp8nQ&j*bbMUO@bD zZ<|YuqoFC<>PnFGNrLd{&8Fq95xFgnXa$=*RFqYV@QND)CDhrx(oY^El zh0!pk^mF?pQ8B?N8M#CGgeTD$rxcr-i2_T4yO!L2yaF(Mb zm(l$KZm~1=*c2<&PZWUxItn2RsgAzt?ORa|l(cB!m2}AqOFTMHnVhsG4j{pHba!Fe z2l3E{Mfs#M>7a98l&SdCXi>17eBmT%cG0GC?IZE;1CPJ)C7>phl4-6?s>7xk-Auyk z)y|4KPqH%UDRJBzdcyBLf--3vCCubGcA}0v96eIr+lKibn=4wG_`(Yx+Al2qTypi; zL~Ri)Z^$aP^UcWYZNFG`z2pPaqrXA>2aDzDR>cIxK6+CEa(iOgcDJRUv(GXPU?Iiv zZ_RS8a#daN3Er-~&dNH^@PKw9;rE_?TDz#_NZ5%vznySZL}$Ob^b*t|%GJV4Zz%n+ z?mD|pxUVv!!jk=!S^iphxS~fbHK6ieQO=!kzC`yp;kge9n30J#l{DBBO_}M~Pk8@} zzIK1~Oq18tP!k8w2_o8Tu3@AJM%!G;85Qn3(FKtRv)H0Ylq<%OgkPimTKq=YyIQi3 zL3fWu-OKXi8nJqEy3zSrlvp!)6uB>6FgmbeXs?&f`a{0eTFKspPIhs17v&04 z=mVZBJ%d=O(c0`O1QQ8(q((kjfy*O`Jay{_I2Gkf(`1EwG;~I)jd< zGHJ?=Girs#sHAw>Fgc&BT3Fb`)to ztfnM|HjypFM$nrI@KXaz^iy0nry~^)V~^p1E&9SkW&sYP!iF_y7@o!#;>oN?#ke=o zax0N7{KAvDke;^Ef-gKtpW+Eu+cAF4FTna+JYQ4DuQO?Z6`pUno?qwH@#}*3_;pdT zz}_z&$*+a9oC^8vQ~0%r7E+SA^{Pp|7x_R`vkS%%Bzpipm;;&J^NUx6ty{>eRpx0FOFn04eL(S57R6Uw-7VO=+#F0u5DTDnbG_Z4h* zl#|cWpVHE=5!M~z=`&e6$swxu1^|(#&qMl>rIfZnSode1wusW^Qrco+-6K4$kkWD~ z%`U7fDX?LX*qXzW3Agz)uf*a_*4(SEikEakiIl{JML6>7F$eqvL zWA1)gH_XxtchaWExLF?UtURoUG=!{@WI^2gA;2YUq>&`b=IV-(q(CgKv`gSr$tAGC z1Or&LSw2P^ySXs1NDoS~{q24o?U5)i1#!Qbv7Kcp9j$e#woL z2I{+vr-AzFms~|@puV9z4b)e^WE`b|`g&2?11ZI*fl(h{f_W|hVV5VtM}HhU`3rWt|~-9Rp9i) z6o#%nzH%Qv>4mQGYDyiN1qwT5leN*u)wKYICC(&Bf)1fP?<3VGA0Zv0n&}Xep+k%a z&>@I{0(FRLrbAR4?bGoEbOw zLR_e+5d68)GmsS;b^M={Kj5AGh9p0pau{ua^KLygiJW(&Jp5R58l6-n`AIfQ^AY;P z5}VsU$6DAwFnTmOT=@{`SD?N2*gr64u+=r((IqV;ub31cy9k>z^aHck$Tlv zT?36=Gk-Fhn?L(hrHY$B7WrFc@aQkPn z&;CII**}wg_74)m+CLbwbo-}TKIXT7VDxBUdh|hb0QOHNnIEt=0!Jgv3|R1)ZT{Yj z0}^Z?>+!E_a-DLu&j{MbjUa#HkU&NdZyXsxNbnm$dzW5D70HzntRQ(m4A1B~n9a-( zvSuHV{L;;D2$_3)Oh~aBm_J$%>L0*>OHvFAxtm!+o|RY*B*G582IDif z!2Hl^5c?)tBEc18`bZ?X zeuAbCTSFa*?bF!8_UQ+MM?=~0`-wL#uq`9EeXMW^NwQ}9OoKA5**+3(gKQtG&-VEU zQ&-_^pBvyQ`5|qe{9@Q0-1gZ@n_l3F+di8+lkHQ(Z68Mm**?%CL)bo5y6pqwCWP%% zsoOqKQbX82+y7_#oVo484g?OeeU`Oi`%DC<2G~9|X1S4UpJ8PCoTrY5!K3kY-aS6s zhY@+iR*x4}4;7m?e;*%exY>gNM|_CV%FOr8cJx=2l)z3no2_AM2eQLO6)FnPFQz|Edu%^-x`^AWRqUT(wg zc@V~qMyAi-rP)2u7@FBVo?k&@fWj~g`UO`QCZ!w2nn}zv3L_;zVYoVu87;cPK#sT& z3Ik6DKii__n6^36^%gh6>xAwij2XZ;&W{@R}zvQQTJ4$2*YbEoL$+Sz_>X+-c2ZYJ0>{$VYH& zORIfdUaj}_!1EFIb-{fR^!3PNA^LidCH`oAl@X%B@%rg+BkXHDtU1D~)M_}-$wxzU zR%MC2vl0s*J>7U7qVdzAO?mk8PSn(X6!avb6hkwdgn}4RcJNhfu=c6&L%$I03=NspQ>oKQ~ zP_W>zFt%Lmx6cLw)VXjILYp88AR(Ak$gAK-0H|+16$w0F`*jHVd4VN%1U$p^uX)Ev zt|7KOiWbJr+pd$&*55?d(~mU?*gB`Y^>B!uzRnUmqNfq_Nnl^?m3m+IJrh}93xJw7 zrM(I#Sqo|Z7E9z^JtLWL8aTbHLht8iPe<0z+ku!i`)LT(PY+yQx-j^m`}y29y`SEv zBJ1Y}jKOV7`2nm?SYsI&h!hpj(KD5L8cuyaS;)3zY5s|f_vItXaw9@p;1reCGD8E`EE5RAbj0lEC0vp9-!{I z9d(~%bz>jWbBl(3AXj-tpk6Hz%TqCD6H_#-+S410yp6Ya!@fcvL0j-dWmITw@hz%v zt3lz%Jm-Y%uK~l&#TS#y@lQsE@uyu8Q1%6IrM2MT-YoHqIXDdeIwySkYPh~#@wjk?)NBP_T6AtKOY8_q9HxKGkrpV2k8aiZcJkwq^>ox7k@R%#y&-x!g(Y@GPfu&i zG5GpA>#@lC`i0ilRuxhE`Vd{6%M#C+V#D^+IbqC}a5TI6(a3t25J~SIf(xt#$*yII zXWYBfpx5!6b$WgHk;r;EvNQszvjHl2i(Wp)63@7ot>Ez1P2q63`PY&4?#XqLaN~X@ zME720i5r-4WNMjem)9*(T1FRzWHr=P(U)&h|SSYk)?v=vBMrhH*tH?|>u%ms(z28A37wpVcJ?jEj&k%u+1N~adlbqy zI{uAU!p81t`YtrQ1WDfIUbckqXT@mOMhB137MxgubjT_<%H7p-f7Rq&PgAQhw$fZn z!K=r-2DyiN9|)4G$Dx(taOLe;!O9abts{3+Uqo!;dX#2vwX|?$74x!i+PRG2c>(*j zQ<>LmWgY|Jx7I>U7KP|@DleD!*~J2O;c7h(5f8_NN+XV4aP-0U_IKQe#Zx$qsf#-1 zHuMR-xV_C9b-3>!7m!OzvMExMOTxZd+a)C*`}az5>P?szfaMdo`8lnd4x2v*6EW?{ zKfj&%*R;$pM`3D1TdaV!3hXv8E!@4HH~30RAh=&E+;`#9^>XyR_p!ZNH}$vw2ednf z8OVB^NZW_z!2xLQ4KzQso})Qd&1EGAVTR)q<$b#h z<>9&#HX2=*(p4{8XB)jWXeJ|n_e+o`C_uJC zc`ZHDcJ5d*NwMeJ0i;_n?}(E^@={$>Q?Xf-iZx6Lk`h1S(rBy+#-{c0Z{C9*AbNaDvx0G%-sxD^*&f3 zJpfjyd3vfJUiG-u;Du$)C_{sn3O}P4jjIDF(1_`%H7`jWPVjQ>$Um+A6Vp))(mB&e zTw|kBm1eBzxTxnA69WVie;|3lwSpO-#DUby?Co|ex~Wx{&=+zZsLxucF7!XlRA>4h z=Bc^4lv05_ z0u&IaP6Ysi@)13S$X9xT!8HA}U>Zn(I(?Z?s|p&!KcO!1@FmfPV9KI5Iz@pMK4GJ~ z2H7O)o{WzPvOW9{Gu2bK_}VQc| zLB(+r9jlUv)0^V2#!Jb$%d1X@9|wv|Oh$!g_Lf=@$7T{_>MZ!KHb2d5Xte&C^vO%74%#5`EWp|?m+A0 z_-j~szD`|(d}!q-i_odRQKxd)hYoaVB=6K1B=|bj1eQSdzazVJa}5DZimr06fcg-k z8?7d>KGK@@1lCb+;{79H4RZY7?*t?pR`v7rwrz;b~4P%K)oPHkC=_RLg^7S@5aC+(Y~4Q zL35xubP~m*)LPc&dssqt{K4PF7!W_I#NKrW`VLL8hjT@O!4azpn0=63Px0^G2Qz>~ zUxkmnb#0Y*fOHl){v4D@Xz8vFBb^gqCvSD2)=1-n&VNTsdG3+wx8+m|QJj6S9RD`b z0qK7bQ=$poXgtDoegU4t@kk3=xoJ4jii?W!(aPPdnwGROAGsK<+>9zi(aNoGjLGri zDVv{G#v?OmWzRyLR?_&_pp`zn2j{RJXteUtamE)I87jH$LU&`@?c+a}L4DteCpC7;(#b~x1e--8Mi?*wf z554_h0eX8GNr4IMLy`h1$O(LnVv zz7Xha17#s!H|x6`zil0=htT<&_-l|_g^3BR+Z?Ma2&<1G6YKQTU_W4WK>$|&fQHNQ zMU=ze-y-Bgf8(gX*xUGB^(OWqVf8Ai@PK+PF|sc2&ij^O_0Ww-yZHky+dt%zPM;w= zO^L^B9wojK6{ty25nQo**MfpEe#PK4#YFYxB2)=9c0+5U@ZRIbITV3{MS~)jL-*0Q zfKyNP0?e~HpqEY>RNJ9!2I^EBnT3dhk*^lbzpfXun!b`9GSd41niRqh8e;8m}rJE`4HBT z;)IZ7MDs(T?~x}Pn2o0X=3LUXb72G-0W7SIry+plqqQRT(KaPE7ihJmRl@Ot{e}A( z)3!T6Kb29~k@qMFrU%<7_|DirWA*-8a6L)TXFn)|4`?9>^wrJK5hNmJIkhIKDs zoR4zMZiqcl9%C>%aDV`BtP)>t#Xx8(`WhEJHF=go%Eh^C2T0+i?REFJjPLFDZi`#bm#vTsmzH zE+7J!0kQW`Qg*$4pp=zi$1d*g&`|Z=Jnx{{-@|i5%{CFQNT7o@&%SLz z6Nk9pD}}X0^LvSL-0Ag%R(u!=W4&Sa7;~T1s{4Q}5Nb4l&$m?il1MYaD?zq@E54n# zTKZmE&A*#l)DioRyzMN1Ys>O&v?qEcojjF9yKN=8kE2XoM(`LVU9Xgs72vQ#QuaRk zFd%o?Y9KTKm-V;#a4BVf=ztxi1p>6H-39uFbbnA_THrnHq?0PSM6fcVv2l|OEeRiy z2g>HMCItE+0>2BqZ>x?_dD~O3UVif{(>K5+71Un&05umKh|5#f&cxyjfVEmoGT>N0 zar1O0i|W)@X0h=Y4kfa9(r4j!K}s^Vz}tzPKG^0}6N|&E2|>E>)Ej`BmOizhJfkDX z(=Bu!j3t?L9s&r-0hCx1woo7PAgCY^se6#S>Sxz$>VG3OAX!Nv0bU_f=ufK|B)dUV-x|U5ueVe+%nUbrsEKB3uLB2wN0l~X6z4=lxvMPxdx*(IeZ_( z8|e7Z|ElybH&cMd)B;@tp$)cN# zM4MH~jZ?pbCDKBI;GB-B+t@i7$=W#?TK@y%3^5wk!yPBdU#Zh!sbqYPE-jQ4XE8co zkdsC*#;xqI6a%Vi9n}iET)WHn+!OI z1}Y_;qCp$*=mY5q7)=qtN6*r{FZ#KMa3_hIcA;4`JLFbtF~5VO5DUy%*^aK*#_1&W z%b9(V;}V;a6IEcz%CwKzl0eN>6zYswnc`I|rV(m|Qa5EbyIwmFFFe~t+3S85DK=$n z4%Sv(R_b*?hix}=zt5OTzVp@)Hfnj%X%1k2Gc_dqC{|AN-8X;Z!vV<8YxDESjm08t>6 z5PqfXT|&vDxM5@reF~c_-Hz~hQRrx@pHhBJ_SD*=iy%YL%#;78HM5kr z`?Wfh35K@Gf3L?K)8(Pl<;iZE#4W-|OY5L$__e_ozX(Wm45v8-g?)~uE#OU~;{E%c zVB6vXXI7456y(H;D93QP9%d#J|J0GJ8xJoi_8%iAdInT#abXYKYR@0lmDiz{vA-rD zL6AwB)qv{3U+)soW?IURo6A;#%M=NUD7J{QDaFjxP^1)kHrbS?X%VayG9&kDE_AX{ zg@mo*Z1SlL9BoxoFfnWVN=Jirt(VZT)CK`ym3QQ&?GQH7sZ0F~X}icPQo+3e_iuplu8tSH4Cmj$V-phmOT@7lYnk6;Y* z#Hv>4tssHxDaRISl~vxODl~p7%F}oRz`fN4SuwXcj!QDA#HN%|viLf>N_|D3&SmPX zt9($Mho)GSHAeRb$iS-vVLgbEgMr;X%cA6g!533W(C@dzBp8xOw$(tkp&fB#iK5N1 zn@GG18!OOp?8wF%hEmZu8>T-zc^tmqpbm`U=&ySotL`o8pL(>n!B7G()Dvi;)(y2U zT0ovD7t(}{rNy`)Hb^M>3vO(3DNXmwwa$ud*mOvlia~b2v&rGWF_aIk!y9EHOP_-D zUCtAB$0(#zC{%EIfumo6^R+vWp6Tdbzz&Zq#)FnN+R?i}bT-l}bJm|}^CkPjJo(?2 zk_JaAoj5;}sV+9!G)&VjZGeTOdTqR~v@H~f#r-{e4&r7&+0Yz{9AWBea7DzBd`2t% z_b5-|s3m-xvqlv<8bqeRNXmmx!di1fm0Zp;@r4 z{dCRZDWGvr^TcvW{NG=z5MVFd`7xUOga?GV;Iu-sd;+7r zaOZbuJy?r0pkuf-D+`UHyhoXyppINhEjR{nI1<#CFi6xGuzRGzO)*W(VM7u>mSrN_ z2${2y3m)&10y4G(;^@l__SkYDi0f;k!i78g`=Hq!JjVY z_M};!dB6^;7y^ixv7MR=8wp{Z69o84$u$Xxz<#LTO0w#Ka{(W->UJZG`Z*L>n)j}k z=(=02W7oZEExW!EV6Ws1meS617-t#xr3hub;?XAMD7lo@nLL)P=U0Vo$1W&PAj*w>nxeE@WbNRpe>d-DN83L$zNC|B2$3ME?* z7{`LK>cJApM9I!FQsNUp@o*4Z>Ts>a6|dRzVO%Tltl|nk9dQy1ZEIA!5u3<(>D)1| zT`@;3Y`}oM%)m+8FuWT!KM(hoT52I(0`71|(u2tenip;dU7J!EOWt5Rz(8|7Z~UUZy0g_hBfKl+iWF2p#hKM0#})Z&feT znuSs_CG+GN$tcz;ACS`Ope{hS=$T+ntJKuEoemF(#0GU1HSFN^;fN&^1c#FIjU?3h zJ67;stFs1bC6sd<{bW%4v$|vdh`Ob0Rk&*<3_jSX(;$>Hv1K^P*S>NMMc+o(IN$@! z%~W3lSm1$5C$+z?ybtfXNAF|r($#11&gPmA2SGJ1sAnn8R9Twpt|0v!JzC4Y4O{e$ z{56VhUTwNMiM`8NM8#9t_($3EQ{4;L0FKdnf!_}O*P_-5`t(^bqA!WYl7qJ-PJn2W z{CQr$m80_}qbbN5^1 z6H3P80cu{RO(^9X*gA`%a)i?Bcydw9T%j}%_Yj!R_9dfaxB3lyPc}x&Ldiw+N>-&b zkF@`!P;x$f<;=_$N)mA=zKS1^;)F~45Ge{a+CuFubr)0j9Q~0(d(dH%J<{GpM*|4Q z-dFVQ0FBM3FPt?=w(Q2+->~9TS=66~`iYvqB>x)oiaC0q0Y1y73dKW)nLRAAO*mHSfxCh#xJ zE3j}(f|ynd#(^0I-gO)S(GO%@li#8SdZ-$t$6^m@4?5v#hREMA55(_7j#`P0)huxHkx3@9Vm>6on7T1f{1JKB8(c2JQtDkO|WdCJdav4h$Lw_3A6BHHTRRhlwm@ z8wzC~U<8%OA3R0A%bQBCkdQB5-4hoxto<0ZD_At6fqVv+p_T$CyZ|}0(|-)eEjtx# zlVwl2(GdejLN|<^h3ZfYu~S?ntS}LtK%w*mnm{&?S*~_Xh9>lm6-Sq#EKx2wSc_}c zHj=w)qx~E>*7S^4S1En0XNGkdE0nIIswVfu z&i20o>8GPVG<;d(qYcCxqB3=zq?9HjIRidh@P_(3E8=tZqUdqji!ENf^;Q-P!SHX2 za-LYT1SVVJwmCqvqR^M(rc(sc6U@sY?-d@X6kW<5v;_5vyiKB9N(rvX=X%Zs2#k(y z)P2|Fex7(d#yYz4$D~{(W(|bV^=O`TOJUKw%Qjs$_!&u#LAUoI?s9aj0S%i=7Nf*~ zt>Z}Ddj-h_>~RdmREM>?8Hq?U1IElzLNgJM9PR_*X|&~4HP1n!~64G^ezj8 zV84>cEffARjG%GO6Gj{u4N}QeXR``z+3D&u-1*uuiIQFR?9?f)mpQ^~Vp0g`oN8SQ zvNPRFAO@I=-0mL=-=WFApXi^kaliA(XnTL>5hG$en=Y~UWR8R?=7fdF4phd;Z;N^O zOg4ICa>oX93aNi*lQPUBlu7cId4!->2G6Y$2uVgI1&-@DKl~5`6ptN>EuEzaC>+); zf9;=9IHWF{!`xCfW#KlQz#%FQqXm|T(;Fi=?L_C`T^#hLB=+dZ$I2>DJiHm&Fl)&g zHObMC2j66)6n!dB89T}9ib=tALN6L(EpQ%UG24zLr+c*hg|xl)Tbw5@u|FlHof1lD z=WljH8`l@vNC-msRjSRJ^8TSp&ZI|%qk)#7IaH#+j-h&lvV^1r?eM& zn%DgZZp3X!HMnU%JH5Q;wDQP3rI)vul?M$+na;`@#maKrtUo8QZyeX@`FpbW_DS^K z1J^QdDXp`>iobL{7j$SmI}p;sTm23%1vBORc{^Hw_t9ecx2E!H4}=UaCkpvIQDZ7# zKMx?Ly@L#uPP@A`8G6oNC19s-v=|m#l}(;P;TeQOn;gYl5^7EsGk0S)7!kJJJlf># z*`Xu=vxC^QGfIaLK|u8h2dvqj!7nlK6lRo+%O_%nSzW+!ahVOin=K}Q6sM?=dQz9k zs!XGFNx6r_HQp%s)74k_o8D*)gL3%U=y4%i)>2rpw$j935{~(}77$7Iwb?C{K95Fi zK`S9wr^Pui==D%(Uw)weGRe6zE?Ouh7phIp$iVKF8^_+RUNWx9yBV8VVmrvMmj437 zd?5}Nvfn6S4$SF|UV>A6s7p#Q`zo4sTK(7Mth+x`il)o&VsgibvF^G!Xx4nBQio$A z6vAVS_N@jEcp`f87X$s!0FW1x`hZEaIdkW<45>-MJGysM(=CXpTU`hE-?%PuY`C0mc?!2O#~R8iD;b2TCU;Pj&L@b zQDkUNrg-2coBS2onrVc*IjSAhg*lc@9Dm1_!$sb6$=ZKK1LF`d-YO~k!zBk12@7jI zog6eKa?nsjVzM}=3X!&-w$hw7+mOoJa16u{*oF(K4bFeX_!>}udJTY*J8(J15MO}G zG*WpH{^E+i4SE9$P$`_DP4a8~pm9wd4yBXLt>IHP7(t~(?`zc+CTc0vGgujz@M$)t zNs2g@#>i?h#wc%h^`?6qqO8QjJ8vb)>UpeIJxIU7eW`C1V_cQ*E3-eprf zsHbXer5Tcc6CKv*Jkd)OCRJ34vboZKNLK)?eRH?F$q@_cfeIV@$7>M{8-uo`$h%!h z>I`V|a=rR{%Av%U<0UfMvD8sYb`2yHhL{-Sg`Wf1w_pwI*HU+Z} z(NGtgHA;g~v$AAgS&s#jwOlVNIfAkU=Z*XY0rR}NbVDe^cNwG4{d_e$(rOWF5RS>f_eEE{&#J88XFm?pW|CFMsIKINC(0es+`~T zTJjbK7+O1U=+Y)H(-eXz-_MBBd;|^mEC%zvz62dqde&lf!24gt(0XY4({Mhx4k+*p zMz)8M%?s}gYe20xaU1e_M zA=UbO6Zd`zQC+K+!(ji@jkvD3%Q-S5N7G{dEi$`mXfos zi(A#5JQSH~5|li+1Tu}n164|{@y_^X@R^d+LdyADuHiCvRYc`qKDSx)Ke+I*eJ(e{iT+?;fyo%T(2%KwJe_IsnC$)6-#?g$_(g^{B{iL>) z)L&1}tr&H1t|YG$U|WE4!_}?hhpxOGEFzYMdwVbNzB2K!bo?7@cEyq$tMF1i7e=M; zOI#j(00{$OlS=aF3Iwj;{#=NQ8Bf%qg5CDq{MO8G)qBq?j|8q}p-p;FJXQ%`}8zlr2rgL{0+! zF$K9a+1(4&Y0kXFG2NE6B*|e3$o{03okfnQ;z$}Pa}umrHgvpxP{r{&=i#2h1KZ)_ ze4w%{7ju5olE~j#0bn4MI{{w(bk7qMHD-pp1J2kQ3du^A--JcdU0pN=rOiLa#q3Q- zn3#PBoS=%?K)J!Q8uL;~Quf!&M04g+*8bcCHC}5FMzG7&zg!riJ;2vH!3}a`P-CbW zG^2)A$Zx_c2&;rz@zEtH ztEn}-ehW~vz$@9U@MvG+xTXbS-_Y{&WfzN5LjW=aV)tu^HJ1Uegv(5VD&64Z+!}`D zj05tU49n_Mq;fO-4)iA8sWSXFK%Y^6j-gLBxXF&!QEUo8@kp&{G{v}YM2Lokz;L#X zVb&;((9-2M3E^OE=CKy2Jsi`En`4?;@iTcmEHJ$YBfRPCW13Tl1#=Xb7D#r>nBqs0 z@3{-&)$q*h*g!uei($!UA&@xT3G(ZJV}RNdmb9qM?hnIjFnC0+a=#1g3o|f{JPwig z-w10ghi$IaH2bZGxJ{P|YAn*oD`8ri%T`ZO9{_UTOF$0Cc+9^XX37Ix8*!KHBY z%c~Dd@`qCPYE>xtC&OM3broR<3kRj_*{b6UcQuj`;evd1>RZ@CioS$#NEzg4&$^%@ zD8iO}7g@nYI9c-Q!&c`WG{>P@<#%l|j@+7_Z%acoVU4x&RJ7Gw4d17Is7;1tixshz zmdx>Sh&9B-2bspv`=#t^$4B%Hk4B>@OPN{EELdd>RO_k>sJH0NDL8A&OR= zFGcx3zq&L5rp+J&)Ps41~kB0ODz0ZU$!03G_r+4y`z-5Gp zDkzH-P+(%T-;K&w9^8OZYf9;Nq~S_bSc}2xw=d&S+G?c1JQ_VZ~YIj4GY0emgXyCEo55}vJE0$y-O zS+n;#{)Jh|0%y}WM>nf7DGI@Ij;jltN07T|^l}_=xt(%vFfM_^dxte`uNm!6mG+rpnlM} zAD~CD7Wm30e~P6N&eeBa_R1|I|C zh&_lyl#JWL;!VJ*Fqedq9jx&^)aYS4zuu6N>G<5uBKYa+1^AjFhH*FhhEM7AQ1=ZD z`o^;of(6haxdQ5vNV1TC;lgFO4Zb=IZ;&onC6ZzVV+V-i28B-xi6Hqh zpXv&bFVlQ=L%z^#Gr0Lmq(Qzsi7xr%i$XN1iI{6`vd5P8r6yrADkvB{Co86iWDKr#-K_&AkTfs%*~X@X@qR5X%531BzOiW0j9iXb*)iLf?4cw7Lp`K$?%|AK-w zAGB}1l^7VGh9eTOUO%HD4~Id@M+oKKH%yshFLWGdyRRYaN{T*$?JNfhZRHv^W?pGGPo6Sm9=WlSQ>Jm&jndyZ+09f z6no#$P&|~mb=yQTn;g?HT{<}orVWFeV|u9{(;uJ9Uq*!Kp{Rmm`aYBi?42g26)3Yh zrX^O=ZqTF$Y zNrzy}L+B7R7N15TW$(8SEsq*?@%YipyGz3BTqQ^#IXjxHVXQXFu5o-|E{_t68^<}$ zla$HW57EJ0xL>KTS=9AS>TEQI! zXjrmUu%dUGb)kL}c`6!qviOc|uZ3awDb;;d<7Q%JL+ z{$b=(^48vO*rFMM6*Cx-P@FS?R~${avvX$2GqNwDlH&br8Pez|DGG`EmBz1}{K6pA6}iYI;i zMUL3asZn+n9fv5Vc=+eBeSuk4X^79X)Z3vX?N$FXkO~C`5f}lYgC4Z_J<_6B02=L3 zVwGc3tk4?bpeB$O2G0t%RZD{!2g62*f9P{W8!40G)IT#T5Z|AR?}I>lFRDP~WLoj+ zdIPU?4N_QL#}369ieWb!bTll)8yqwUy@B|E^oGwbLf*AIh)?vx#>zd->&>TqsE?W`g0Eb(3yqVCgjp2G|QxLH2@Gc(#JlvI4-r`$8q*Ytn%$(qbsCJZ!|?Q-f)p4N!VyknM20G2xc6_!OOHD zWgb&ENW|QLu^sxp`fu!s$>=mso6iPW9ekHr27kB0Y?iO}Q)80@9!k9bE#8C5E+At; z>DdU<{20q)#7$(BsR&^l$ow zF6VuJI_)mpx`Dlau9KPJ#LOXbVR!Q;mK+3aI(xKO|HbnbuSf-4Szc>``T@FFor9ESGj^f!{xwWq zrrS|$Rk9>w3i5=MeO;VAkz7W__<|ctbK@LeNb>n0OdhI&>gKwC?uW02Uhc~aS=QLr z%SsGUmJ+-3Gq0CX6lQi0`tA{9hOv5{ybEqmIQn6Xk(ZWvyZ?hB1+d7}>66-J&92ku z9dPTPcL(!|=EID^bzTz23>06q*K_AtZ$RU6aQ@1e9CBG*Qv_Ch8jn=VP{EgLK2QWls z8c3Bve!i91Ni1$}Q7Xq)C>puDPvrD;W0<^tdg8Q-uy>tYFV;VSn)h}Bx`W9UQkr{7 zLvoVJa#DHV2exfVH4?|HO!8A(FkE;KG~Y3!w-$9(_13zg^t@8NsUs>wr5eA|9z(m- zKCDoj%BxQmHRnRDeH04_p@LvBjWh5y7Qk8IGG3X0ea`sO66TrS=}1$i#wk<2SIgm0 zCA%bAZK7((ZSAu_b0Ma359=Pibf^WE4fe&GemRA5Vf;!spd;0XHHxkhOkN<3+=x)wjhs&>7Nqg1xxV9HAH?VIz3@-Y|V7xEy5O8H~MQ6AgBPQSXJ=*0#?7W4G~$a@#~D2uCsJDX%7K;i}^ z5EL{@P}*pX25QoX?m`03$_9g1tW~kpyk6Q$WfxFUgPTZ}$5pGXwXc_IwXMFk-irip zNf45N+^c|ifoj`lT`%zliB|UepP6Sbxq*W3`@P@$@%xdTXXebznVBp+6aO;Z$zrHfdXY z{W)GKC|G|yY7vRK<+ep`{gtrFv%_PqcTD!xJl2GM`B2 z>gJKYQDzlO8Gdo}o++oFGO*PUvwN?PJ@y!B!)(E18Jhz&mk9UMwlh%~skL?AZF_{% z`vYy;B8K&V+ZK7fK+jz);H7-Tej<4slF`Ez0&X+$0y~IV;YklRv{u|^sLNf|f zKgWOJB}S3MXzt9AXyIkuz9X6W3jfGJI-m5&r#qET(8x>gs^325pu6M)51Yw^<;P*} z(#yyBGu;iBk26A-v&LSI;C^{QWQFV#%f1sBZ2O$088a@`H%qAv=&Q|JB?kaK^2IAlkWL7>2TSTrfKH$Vbd&)wFhj{RfoWUR|6 z8nX@`_l_~^*f=lSU3$ehe^@GsE{>nytHLQ$m0hw4;dPu8%q*}@mxAT|-v6g=RvOj9 z&1T91J?op2zZ%#6{v^)f|INNq#wU0&l#y_C%5Y*qsh?ZF`p0o&HoM)^JE9Fx4xW_h3=(G{0iM;<^Zb0Td2NB$eCJ!$bE$c+wsmR|;s}Y`vv_@8 z#+rJYEUG4gvwAEEX@dEV7b*rkcDPY8HGx<-SKsflzs$b20P~=Lu0HQ2wW%_`@S6{ z@x8V*I$97+69oT+NrknR{k4tYTLXoVkj11Qhq5?wr8AuyQ~`Vy>DaJy!&q=DbI79; zgRHAFB?JA=8f<5~QM-lV;!4VJi1%xk^*eQ9wI6GBe|&0x;>E@cmeBXxX?M$sMygZ{ z|KK`_{O|3Txu18(21TAl9Mbv@;pO^G6vK3=JBA`2n>o)-p%cyA@Rd-3?l7TO$nz&M z*k_nq_IJ3~3QZarD-~ICoz$jDHROsWpDAR>UuUyz4|&vSk09fzXO5XOR zf87!Ks5|`~Bgj-Gk-1PIqX-G&g9Q7azv?k5^w;J1+Vqzq{j0s~{?N|;e zDDn{cfB$!bkxa4X&GF|3v8m=B4Ld96)32we$?t>q?;ZAUP=34D8sCqpHPMaBBwGjc zC`ygs*sHM}N(+9uCvb49^K!z>a*T8R&D?>=3x4@kU|6g3%tZ9rM4MZqBZ6Q4J8-aK z_^r+fcB(luJ0XatsEiPqUv}?Pv&?BYR&j0f*@vmSSc-4QH5?!uY|gh?G=u-O!nt7#16$I|^7!!lwghCAy*}4oO|yaa`ib_cT;w6&s6U zLfH!~V0=fBy=W^CgE{_NvPhU}L*0-QWi?*(h4jY4clMfYVzOYl!w<7>r-_M-P| zF%M+S&OMwu)fzuX*+q4k-poZ^${SzZRBDt}vpSa7`I6do*NrC%4HnD#oaY3g21g8! zfz9PBuKIjQMd3LDeU2>a1<`^E*V0K2*V4A=kn%NivsYDQ&nbvCd&=A9;YG70eMve; zW^b5NGi7TuM`;f$xP8V7qHHMeO)!UM%cfIA$WK^%fN^7@NX_J`poh)hNDr5^1Hs{0 ztkxg`1y&ZvR^76&YDhOm&av?I7NGdXZ z|6P(wA4Ig5sD$0~9OPGkUApXZ#o{%(>Mw)fZIQ(bqVFP$~E3Z=Z5Z5 zGLi0TQ#lH&&p8V@iq}_gAu0XO48*^uudtAahwTWw?-8rs3KXs|PU-pqEad+pma&M#=oDj{;A9EcoIeC{~Jac*jVs}lKMh@ke!(7G^U< zm>te=4L*$F;w%IR8M7z5WQGhdLW^})`W=x~trWWCci|aQ4pao&#OyLfD{eiLLABqs zxoRCp5UriK?qt?%@pYYZmMkTqoIel&jx~qMPfkoIE9AUOB11Wg__6*A%`%H+Jz<~O z^pv9!u{CBbg&VAL))MJZw;7YV-JZCqJ#nMRPT@Salq)WCULF^zh1~ zgA(DCbElIKY}CdxxF9Rd?=;<+;#jZ`xuN$KKYnL$n{@(s(3oYI578L3DQkc(I6v|) zEL`Hq@GEq|mJU5j!o)!7A)Q->(*Rk2Wf3z!vEGrVzP6j4^;r9#1@-&FV^5}EE6h(Z z8Vz6JD8rI=I#aA7<8yY2#h&0E=T*@~F$6s)hnB1Si#YyKPo)he{AV_4*xN(r5*%KPw7biDWyMj z_{)%V(nZ**C~ulySjmy4XVDiT)Xg2?Su(I9W2Gmn;>7%lj8|=#c{@ZnC_Oa5zPmXK zi$Gt|=YhxQL@-?Rk&?5&6Z|OCe^~IN9Dh#vR{`2N`touf~Y0PP%ooCIj+=urfG zMQ_w*nQ=Zwo>*%VCQ_>OA1o$5%<|oE zTmD~xiSj#fTZ|qedO|{)4qMego^=Pi|L4SM0@lB&C^`;2rp%~c zrCQ`vcOLuVTrm4;VfHh@XWO`~| zkscyPB-6U(l|;!amTh*~!LC7p%&_OA71|w?xsfND!k$wiZzMr*1HP#j7|%T^xMxz} z1P?Z(O(p7z85vgNUrmqJw4sIK=l zddYSR?!Tu<-MJ}kwsF5HktTWIjr5h|`FSE<<&gw)qn+oBM4IFgR;cs*AQ7+fNJ1jd z;fb^)Zk}c5%9vy%lGxZlSMf2CMCsml@Of_2MmLf;DAFEJNx_jEkikKbzr@p|zN`d} zcgCZ2U6PQ%@tS0sI$J*UNhPdI9xtv0^7O|PK6(ozSj^xX!TEVfT*e4HKS&9GoDxoj zc_bx175;%lJa`Cu8ex4FLl93B{$x2n?b7aDqKM1ROMn%EdeaDrF$t1S4+bsrkuKwj zWEst$q?U2QzRJ*N7Rp5M3Y_BNK>|B{=gLUvo~_aS!b6fwzA&9{Auum6s!EWCRx5HuSH!GkbCAI5nl8+xLvSw(EM!AGI@W& zBQ~DSVApp8-$MzusOzrRkmw5*bv?ozt$Bwn>Uvs!|FNh`1T+7eTB8!k2>v~bgWGO3 zBtPuB3R3G@Zr9bK>pH$;=Y&&{WK}AZT2Hb~-=$6dv34D! z!;8*2Qnh>D!Qn;uT<2g5GH;-3`6mNuM|anLiPF`&cCH4mu1T~dHGn!$wmqq~QiFsp2gmZd=;S_LtwQck zc}GjrvQnYP^ELOMPi$R&PjYwO!}#aL9TJue^Kf%Eob3?-x~6Ps;GbwN)05PN(q0Ww zDh>%<&828C=CC7KpnZI~V|m9>Sqb;kl%_@OUsk|-3^Q6&R_q_0sMB957iGggt)#sx zsWp%mct>QdQUfo>{NmzjWjgMR>F)}zar^Z(ZmtEeuNUJHpSoB+goQ7bw}SqU-YG`# z_eW$0+sS~bmv?u(*ATu4oZSX3W? zfsnKzpR1I)srS|K@W-R(IO5~(ZaWVJT#TMUFG-P4VS&phLLgosKgS6wR! z-ttyg-HQZ#=7e*= zMOksSQ8wX7Qv5#a4`OY_SRZb^)fq>@P`B{bThGu<_+GBj)mh_Ib%V$kSSYpJny6(h zNzqH)bsxCu@)0zY=MTAd*~QU=(3JDf09cn$9BAK9SnlEd79{Q=95_A!-yVmr6Zi=- zN@Wuk5O&pFiqK2u**deUZYJND%k%C_Rnfn^=37Dv|6I6yzJ_lzs!gZwgbj)7Q*cd&h?gk-+zYJ%zn#S`me4SP2!?a=;XH| zcdG%Zcq&9Qo_cGcd|Bm1WgDZGFQMz0y^fFZ_gJ~U2p)!bd7XTnQc|-oU zvV5Tlr&EJr?!k5P0$1Ig!dVzUpZPg=b|;sPKPi57GCV!qx>Q+YDmEmpv^M{fxqT)V z6TIPb(nVli{F!u{t6p3uq6YAWs~p~R=D$yHp+2 z@2`0-P!|^Tt9URvWM=ie>^pL9_J8$XPo9^0KNgUYHILEm0UBxjj*Ok3UJ}PVFM{^9`Wwz^ikhtijJni(ZcFr#aelJ|jS@Rle z1#6k&8uI|Mj;Bbtz~zMfcfkQJBLH%N@rr8*{2g)l=>i{nM{$`+8q8I9F%wHon>fcP z`pCPHJHd)${6O6vQyk+*nx2QlF&c&Y^1@j5rT$!g#$TG`8>{=_8#9G(oT>Q6^&lV( zvl+)dl;t(|$~fx9wns6JN#qsA@iQ1lE$7+MpGZlHbKKj5bA)?HJiFiUhASOLICC;-@Qs?#oIS>v4Y9nE2Swuv*OpiuE!S-{ir&_8ogENiOJ7!D@RSrUH^9H1 z7MVUkpzQf(nD`wl0MQ+zQxN4+v5o75B(8(>Hj1q+mqbsVGm+J#qHO$}B(}IG`8wD# zSFxB?{+++(kVe)C5nvyE8*G_h`&Q*Cak)u1KOCC(=cGSh-PPc=5T@qEbK^G+P{ zJ4-WPuh|ZvoYCG>p+o)v`E_5*Tu#{E(gpI)JNCDwEYY_yG4M&o!zWV!H(P=`PHl7} zB^0%JH@EppxNhy7K;8E8k#h+wEtYr1-Pm+t6rFQ0c{trZ1PE@I&O_pa|EgAhojEM? z7dFyC~Ul&+d=bs4l1fja5j-sN(HgJYksRR9HTKT+zW=nIHZFx4Y&?p zsg3y}qlTS7BaGF;<@`kcfd{SxQo#LH;11Prf6#Eh7q}OCz+E74BQ;!=hC5B*e%%A^ z*8+E#hO5_bHwxU(dcajZo6d0#$hirC+(dpNMhXzPd5KeJgMdxYV5bP!kttx(Rt2Zz z@$PV4?5R@Qs^H|1k`+_5`C)^`_!GTLpxJ5nSW=K24+JSndoiulfwBx+K;LsfP zggc=xI5|@4QQn}w;09?pkFHns-%k14INlUvNWu!~L=c+{IF! zFmlS1ai+cJNO_m_fV)iKax~o88ty`Y^YnoGg}@!8;V#f{_uUQL$R2R29r#G^*^ZB) zjnwvDE#>iiv%p=V%lkP$5zz>w!kr*+xf*V?hC5o|9_Rt5#`j>-D2t|pJcq_$w!fIFDQ>uuG%bQu@ zPV$=f?7r>n!5l_z_q&YXmoZoUD$*mh{HZdZ**zR=XS06x-Ytooil-6ogqv%;i*L4@(T>n72M2ekLRUoF6GL)9 zfnNQZ^d(ood%nK#gv*=IeV98D%J3&Q&AfR}@i~K8+nmcgSPHTDWF7V5Vya{#V#$&= zSwhRVxa!`c3)PV*hvAX8`S6y%@2YDgUBbrQG z{3}&$G;}~?zdxD#-OnjnIpsy!f!FPk!9^iJQ*xEF%kpN!Rk1R1FJtF5pV^}a7%@FQ z`PSVUAK(D?{7>AX2X{7u3y>bkqF*z(a-dJ4r|GEt$6+cA?wLAvyqbAL#PY6Bl;_7c zpv)qLlIT!$uU9F66;U2gYiH1PvL3}^d$-%;U7-Extdu-`^;_cYYzT&382 zZ0sk`+kEV^_*Aj^*efzuYE@VM`LlReu8ntPkj{(qu@FGqe+;MaG10$-^WM6H&K$*N zlFn3oOh>o=g=nXa)>DP}SYC0W$iNS5KBjSkk9p;>xW4%qn{Kh}Qq0WrBbfxuF1s;t z>R$3fNCJZ5;plh^80hptZGGN>TMu`lLJVw|pTtkjpAQs4H!74JFb$tAt(dlVD0uhE~fDQ4*Y@?ZA;Z$foDI7< ze!%zy1Mi!)`)@vq2{({V5Dlh&*uZP9VBN)bJ9;828FQ_5@pc$g8wFFC08_49pODjx zcMb~*_MA~|D@{~CJ%ZVB*g2gaWk$%* zoI%*i!Gc_d<_LOd^V_AyF}2T%nei+hmj-?FwOHPxSd>SL_4Brm63p^TW<#zJh!Fs<2j#)EXMSKnMW>C^lcyDhhz0f&)+5^O&?*+B)Q_l%;h+_8^9Q^Y|vv|-Ax4Amr-vY18&c&JZXl#XLjh8 z4d%zH!ZJKQwZ@%YUHj}$*VBC8XTX@{jfp?&HMJZ}!yq-#qC^(GTtL-Pjvf*m)v>W zMzL(-qRFqG25)?iWP=gsMF^ni_VAi|?HW-diw>Ffe;;F;!~^vJX3W5_WM*kl_~@S=l2sB z_?LizC{L{S?1$+OrRvu=omhR!{WtPdxZMq5YK#uCKXwH5=oAZae~pU;sWkn!KTw~o zglQtoXteWV{nV~qXu9qEA9fyoK}!k|A4K&s+tyg`{!M5{tGq?>5e}D_P<$RfE1_^+6F*AvWPKkTQ`Y{!pIiOoBOZ9?TVDHr`2-EM z*Zxa3+stksYyZj{HHplU-q^1NGET@TzsY%|hOP^@)nd3B&f86>(blkSCu|-5QF1_t1Kxa3-D`;Dz5FN%aV&r$WHfp#Z=j@7z)Z!@_+8kU11j(b7Jt*{W` z@Ou&p=ba?Th=$P0vynLgWWJa&r}56v>v|#M9+Be9&pf6Fsu$T>C+q_&JurRHuD!-; z++O~DoOqv-P&n^7ei}t9XtlI_F0bd+h~zz;0<}D}OF3$tYL(J$4e6s&>=e6L*%>yTb;^dt zb=!Kc4m+`#w&u3=-$SYV_*kjJR@UZA#o@dorKUHcx?_YNd(X)azIe9SFRR{wY_F$^ z{(8oySGDYvY`6XdUkqRC;C8sdIQ;s4C7<8K4>jG&Pk7oe>q@(_qk*_XL)2-Au!6|5 zsx*Xa>2_D;+e=`@ZXsdzX)Ru`V2p}(G98*RGQ`@9!^M_yYe z{|I67KE;pq!q>75p!PXly#~ESKp#+`ox;BPj3c?ASP}MShiBmH3Nah)JZ=MGc`mY% zYv3-n-Ht#ePqn9W1BIQ2TdoQ3L=YB+FbgvICR_0Cox+!@kV&`m;a_;v?E}2 z*UyRTJ?sy%(_o6nJ#0~j+NOK*tf zwaiy9IbcxbFZ{8qPQRO1fsh6(th-sjX6GB>Ihik|6%fvNi_87KQfx^dd$uc9KJkfk z?i8Fp@ezLNWByql^Ft$89>XbKkVou1y9PM?C+`}NCEoXk#PW78P~-Mp!(0hDJtEzO zQmMIX07pjHHnthzVNIBLp-b2}Zpna#ijAf6fDI33N&g1%Z1te{+Yr>b0iMeZa9rTc zEx-+)_Pf!Ou6qsWULyMLCk_@%c8NvWY)<_qb}ABR78{P{&H+YvRJ&oG%si`jdmL^K z(s>unF>i3K@9omsh?xDas(8C}k+}}bq~S73gK_#qFgh9`=jd&0FUD-#j8x6yxLXI&@96u}j^ z3x6xHoj?9^4lDg964hx0ukB3Z%9PG|FgeT5J0j0gyJbX?+-fiK8ch~j;e}<{>${MU~}oZ#P?o-jCrs+Cw}nARN&M< z_@zS~9n9TQ?Y*gamFRp}G7ovcK01hQ-s>bxN#spP|MB9PEI{c5mLCdvr+g?6LLV}^hU+E>v-0xWIXdpyVE&a-66o8U}eb%6-WNGaDiv3 zLmtPPBVBl8uq)H=3w90gj|g^U`6mUthWIB2yIlUPuqVp8GXFXT(N*`jkWeJkRVV8U zgQ;(uFrcow8zqK8^_RpVw-UB)SrxzV7|2(5JMK}ZGvLPK!}>lL9nK8Pxof@*%1#EQ zjX{~2$-`9AxbkKh6vTkQ!PXFrKkO@Jqn_rz%3}r(_*I^`OEmx=H{ppZzQ_0w61Jrd7TS-IP0*QC}d3 z6IK!5t?pbAX$0UzYJ72?CP!}uSB1@-m(-`~2szIfM;FMg;#pas-;^7TlH--NLLdX9 z12igv`e5CfLUa&k9q?ymCWjTF^nNB|&sUsc*GNeS5pMl!Pk}i70HtQ?6 zqHIpcXFA)7ugbuO=ddQG^Mb^5Zn3AcpHt21ET4I>YQf>t!`aPV2tBXtntulv1;iRS za`?1PZ+Uwl>NQ)UhX-RxCfo@V{t9^@g$W~Xxn*l<_|z>Qb>%e9FaHNfs9P0G(eJEg ziuPr9PT%CHw0+18J=Zu{SD2L>+hI?ujgq{M&uy7uHI{8`*y3$v;dqrK^$Gj~!28T* zmF0!hECF#z%dG#!Su_7Ruwg6SCRzBBINxVY47u0-8 zy+0uSyA5QxX|QdW?U@i)hL9Kn^bbw%FtfSY$|-dCr<=`%87HR)oV%KFSKwN{bI4Vh zvGnLkh?lvwTw;@JLS!>N!!}xgAEBsikoALSaCF%j6Ia!fvtr8C*W~6-`UP<`0<6u3oYZQ?vh0tw2OB&Hv>EdX;$n@U*M!1|+)(EdYKNc-<8tQE9^FVDi1^TIf(q_p_!1(W@v z6sh{?U&eK=?iI#okoD)MSQIz}7-BvCUxe72_S^e=mB+>3REi8E7~1fLEx_|z;Dczx z)dlQZv#bkxOYr;5GovplOfF!A(Bn4D)>mw;Hc^Z+$GR zs0(U+MM6+(be@_>BaBcbuIF*O5hu`x9sYAu2{bte-S`bI2A-3qs#3WE6t3LL=MLUC z*kG7b(L7a+J_&B?=>ts&rqAJR3}B6YrL-NtYu2a99A43VY#N2dWJ zq_Z^vxPzDQHek4NT=0?tI91gS86*Y|O;4pBsPNhE5{9Q#b~1?h%S6x0z=kT{wLU`z zsl6^Y&8#eNRaT;3dfDCYkO?n8x&qdWWis3x-17-3c0Rzfs|lrx$F+RNkgJ?AoHnnB zYZ4RPMjtsCx-qLUp8r*RF>8+G)b4aFk!kpfO_o_K4gS<;_)^IgPe(h4^mwGtXF5Et z90Ro6!_2lJt2;cdCyil&&+1!J7EQ_ruEJdH*}X9Z+B2rz2LH4tc%OF#6)C=_7BtoH z>4L1+EHAn?D=4q;m~+`Dl+?$rpCH5fU)Trv%ysIJNS4f~?d%!1nMP-GGLnTotoMWS7T zV@NM8EL;E$&gz#2lho9A=t)Opr#P~MF~XR9tgFnwf!12$qCRuRFtf!LKU$Rd@pr@z zCfkW(f5#HcDy+) z%x+Vj0z%Gv0J1XJlgP=4^G^A?Qfew2y@ass=_fQXz=t??*v95lLH<-AD>dXSfpiKv z2XK*PgeM%|CL+^>TzBSf@FTbCoJF5*&X_(Gp;L*zu{il@qD$h6%@P)=B^{qrb z&xP406v`|(zBaf~GjdZ``uqW{0}vHrXz9@}&s6J-`bAZLU+*dNEvuQ;$g;ABb53mq z<13nG8X1aTNrE0DYXsY1s|D7M_Snoh{XJ<}_7Lk)VrcNG`a6U6aH=%)B2k&jNyC@< zfsKF{kZg6`C*wQz5W*tG^?CTOFoB-X4GCF~u-<^5*y@rGpeN;e6)g#_0nvxZJGbdo zto<3@5S{|tRa~yOA4iFlE$Fd5xcEYQdtiT`m-trvdv|ja>hCyb)jYj^b?Ud9m2FUA zk9ANTD_dL8!Ea7sR{0;<2Xl<{ z0JN@4{<&Q;PYh1nV4)xyt`RuLj=zTZHsWK>$M_3ldqi3lnBB2x+OQir0oT3(0%eV9 z94cEm_h_;oXq|DdjHvQ}G1>@E8`U~FSI)}~c}Fueq;+zEd_CcajxyvSL;yn>fJh;v z$xrm}CpPUxUbcsLuRnF|{*%sx2nx(e!_d&v*{mN0aw&=>=i$4%VjYWS54!;_9-LhO zEzK6S(wKgT%5+}!oNOOgvx5wFI$bx5PEQ=~?rL)QU05D+UN_i3SDZ9QKMU?WVp)Nt z7d0EZw^bds$v0+$cjJ3i<*Tb)lkkt)J}sPC?JIBcyHqaDGI;j^o$JTmq7BBzFTCZO z0>^v9!>U(CKH9YMgTUaGUu|iIH4Ol+Ao}6T&iN{vd{UXtBdS_a&M3T6ks9QmC+tCx zaxJ4@ZKPzAD_*at?>%4nYOlu2n}XLMIb(sZl(z|9ZN^49-w?dA4cEEtpSrGe)VKo8 zHLfj98nx!!=zHKb$PZpppPh%DgV$`*9h4<$O)9O)*x0$>o3Fi&I`WZo6>1-@|Eqxt z(`E)u4TvYW;|On2lXv%4dr(YNEt`CJr58V? zEZIn@VNzPpZX?nYqiMY8vNx2TNub1VfK`W$)kr-w{`k-cO1Xm4zZ6Q@pyaCig<2&P zS|3GzA|Dy6y=bd?b%D1i!NT{^>)$NdbRNZ-03Mp-^Jz81r0Di&Bb+&d{&Lm*g{YEE zIH`2i{ay&yrp6B=;?k-69D|&z4%_YvXT2;Q8Y4&=_CT7`8nPmr2M3R_4(S+$O zUlTaH3Svg1<}KoMXU7hfE2!HooiJL4_T}b4Aa!i0CgNkdkq(_F=P+}WIh-V5U}o4bE>)0fl0bdjtt`O+vfS0|@Q(mqH(ztE z&+WE%r@pGg+I?f%=q~TZh_`$r{A9IIU$!CL2le&tJQTcv6NK0_3kf)2A#pxxvv`P0 zb5iP5+!xl-f8V60>=XCYh2Q{iht_IbSHfokECmVlWf?di+!LJIXTDB%!^e~S+Gf__ z%)vc)tBh+A!`~99@D}mh*58@U8^w-b)XJ`pnpS@0w|h9jq-8OCmpL%9M?p4|PVLYB z!kT*tnT$=DE(gcgy2ONG`BW1og=j{P1l6m#!nb6R2D$EQ``4zf?!5u6DXD^$)wO@)?#rk0Nr;r&j2C2^^3VcG3PxVM;J8uo3z+%KJ>2Ly;m_ zyZR6qyU)09=gV~d{xKP&X7(^jOumt>Q1aJM_A+IIU3Fd3W3t2eIE8O1rqzz;AC|j~ z5oRPyoD#4G3rEqr7~})Ji`nR^Urr%=-^oZ-w*ODr9eJr{1k=#^$JKe2HF`eK0OE;PKm3W_jN6EY<3l?JU z101j0V{j+Ic(;BSX^?aG9v##)A%B(EeUf)#FaHz-pvdY}(@^UzftNM?_Q-}Cww^fxl&o7bd_H96V!sj0) zit%v>WhiESVmDT@X_cqg5jyW!wEthp+3t$SXi-C&gO=;DXx3xVVwAVI>gy;)427h$ zDy$CF>9x6;m?mQIenW(tFKI48&N1o=? z8mtd-M52tsaj%oM#ydPOa6bW`*-LkLmK6i(G2gEUJ*0Z8`5(^YU<6kV^d?EGzAcbn(U5_odWO{y zeaZ)(MgI`X_-Mwe47N7&9rdw*)3aoS*eu+mI-#QU{BePig8I$qdl`ykd6nVG#h5JQ z8)ieNYMx_Bnx|o4RsBJ(n|>omxt`tNmBoaAE}pAf&B@WRs&YuKSxC;4(FEC*&C96C zSlKWjwjMKeZ}WSZHNlpDU%fs$y@FwFA~U|ho9TM5xyky)5Je9d6JsneJ+@?Mc+&ER z-wtH0a-iL9kA8%$kN=R`FUkS~+_fuz5X}f*&PxQ}iDvBa#41ePL0~aj9a^n3-+oCt z&%I=eRl!-mk?|?*i#kUoNN$dmP5@ z2&V%BH7_{T$k-6h9N}qj7?-u=bDo14A(SoJ!>*q!EHRc1+4A6=iG#O1D7n}pajeiI zW11KJ*A*@Iq+}etu*g{UA2s@)t`5hH!g>y=I5` zXKfW~egRkUDDLSEP2Nxyn%0K-tQ9`nVO@ZIgU@_M&Cm**k;9X<1 z!bz&f^{Zw$%Q)`EV=z;IH}u~%8$}zvMH?}U#3gIRYdlzMWUQC7JhwG$sXoG7H83qY zp#p|-8z{+vpIeGAtuR;eNOLi)2frj@jA^c?rn`XQtH3&6fH|FDn~E+i*R&l0|Sz97)Bc|<(#QlJ#2WvirVK3YblGS@+gJ>yCs`~ryS?{Rg00a zh5D~Q)XV7}vuBcW{<}-&QTQ~6bs4shz!~P-fq|@YIkG%~gsMPI^Jy+O2i z;bEtGT@_obJAWyo>8e+*)YvH#o(b4sR%hl;Nr=-It>)nvzU zEXzMxc-XQd>Z3C}yRGIgoMub2bwtL7v@_FT1{E1i01O5|*nk2+Sg-*yu4vf>KtSur+hTom&t({HN=!!(`;x=&d${iLv)2lNj)l{!%RIFS53XiHAZQl@05 zJw)n`#~}8%G9MuwnUdyfGAUg{nIqOJ$ftty@CwK)Wh$ykBvzq+R&zzBq|86OgBMq1 ztWpz+VN>%HEx|}8k%+m_noZ!(a{2raU0VVpASsK0tk>Y*H}Ktq35(akZX3m zWGFqw3V3F478Pyt&h}~5g$BO|F^cTqF@DKABRjz+9i!c|s<~pKB$Y1=E=t;zRxtc_B ziF%!N6g{#k13BTXXoiuo6?S&ZVrhQ=IXV=pWCnX`Z_ra~y_L%urPrL=V`_Pr4fRb| z|6uo4g;5~0eC2iNTmp-=)}DL{ZvYsx*ZRU!nQk})MEq*oc+VdQ}j=U(!5quXoqt3q=N6hBNMUW-)(M;iDS5-!u7c$1_%1k;oX7#*bB zWRq@NVikEczScmxP3()+S|fDpiLI|dKrS$XU%_@pu|Q~lQ;_hhid2O@UwT|oaTbe8 zBnS#JL1Jye&VMgFrCftwH=&}u^SbOMBAeDV1$H+~-V-lLl_K@A*u2VmBZTj;&f~;3 z`h#u@R6GM{SY8B}UR>OH=Ln?-ECp?L)C^X-gGa-(XW_ zg&efC&2@QJrKc^+77}88IiDk__E_B}{~<&l=Z&>UDhD-KCB)iYOV28tg-^{`@Dm4* z38!b^dwuj}KgP>Ni#LNMD{}>^q}r3SAXFr-@^)T1<(f}LI1?#zV^zkA=|EU@rW%Ud zd%ZyMbKCxAFQnEjN$e`*Oczs$Ba#aqRsp-bv)g6O%V@(TrZpF%3tHCQoq}QZw!=yI zTQtm(-sj_+N@L9Hm9CdMykod7*X1$Sak0SI95u}Ms5g*Z!?g?79Ziu3=|1bX*GbC) zSMjz4fS_iKS?L|~vb__XH&ERp}vq^*_0Nsdua03zZ@vxO>DI%wYu#| zSNcfaY<1t0HnAsd@*K5cNlSFx#56WoV1qZ?2YqFyF1#;#$HX+WD>~{nqOLQewc3)w zox&QJY?$XHd@y$F-u?cFh?xtyZ60p>7OJkoCyI%49$o?26j1xyhv~HN4~MJmt-Yh| zMHHjiqOrfdlJ-?$@OGHUsFF{;;i=};DmQ!Kna4(77MqzJKGJJR7ekuOw!{_e^7wPY zp69qLJJ0DpaaT0My%ZzWd(=v}Yekl;{-5M9OitO97DMfYjES-%a@DVqq~wN^H(&K! zL8Fmb(jGl7MU{bOW3cEmoE!s3G4*H>b;$0ma@9V#^WPjGWTE1~WNK2TuYBv=0W!0q z{~?syW4cvgal>?5<9025jR}@@QF=h9A`PRf7+w9}K z)m*Kn+2{r#My+InpJMqL`7RWJo2c4%3cw>%D_VAKKWzJ$d(?(M81cC3*3sOQt7H!U z*>XwwkYMCc?Rix03(l1bWfS8g0h5z)kWUdZP*Av$^4Vi;a&wJMeBg}}v-yH5bA`1L zzNh9&JTp*|8Kr|r@pk_1dH%t5=;&4P4Bw=-LvTM9rD#nt-y~<5?XwU5>{oI(4g-3T z=8LT0`#nki7i6r(!+<}7hc<0xTSDf_=cQW~RQsld8wH7Jara8UxDm*csg;W&$5mGd zL4`&}MhjhWpFJZuh*eGROpHY=kFgu(4SrGF=|sK*Na;o60tYb)R^A<~^R8#PriN{L zzG-CJuf9$|y|PivI4|`HP2n<8_8_0#D*B~eyoNd;*qQ0NMJ_v*UQ`U`7ahyH=O-Cu zca>6l;QVDVQfey7+va_r_sF<9$dhWkg}zex@wO)X7K6L*3V}{NcGXnY2*o9vWW_JA4yPLW zXJ{F~fm?07FCkq z9Cl>ps>mr6@jppIQaKiLNqc2_?UJUn6Pv_N+4bz}4RX(*tD&-^p|VrxW0=R4nQ5yw@V#>Vv&Ww~afkf!S`VYh7UAKu8i-B{vssJ+K^5YiYY#z-D zS2jua7g*~T(+AfTAg93KD!cY!$GjeSqn91?aur!9S|RM1wcChmaU1c@ep@o@(deh2 zQeUFW~W$eS2YD6c$getb+_35 z$C5r;x_~0|3!sz#GplVO_S1Ik0VYZer`+c*~NK_TbklG`xNA~mj zZ!)rRYSBU8LW{UF zg=(Es)~rc9aqekMtA$mLNm}ysB@fFrJB-11sY_){Zx#TN-CT8JV2Vs~SKXlmDoRfb zz-n0y4&jTH3Ye!M^l>W3&*|7-&%9FePB6{YhW zoUEb!H{Ds$X{#m|I}puUCm$<|Mzov~HMiI0QXZvBk)AMDom8|gBr0D0Cc*C*}+y!i`ApDP&|CifD9-FB;7Irv#v(NVD7VU*?Uz^XWTBa3~O znO9|}uO>aONvH4LCL5129QfrtMof~_5_4VNP_I^wUpW=&M6u|4R^C(#oaB)`m8aEx zta61Ia(5U^keubzL#n zvy{EYDw!j})_uQB5}cH~=jtriv+a?K*-*iRs4*~!26c^FCea)S=_10@7 z1v~fn$H_-KAI9vh1bM@8fVEuG5|?=1#?Mw;l(W>=mP{(!({?g07Vd`iNxomILSlZl z?dz>NyTqgAV}AD%FYR6;7qQz)wtGr1EWPeb7W#FfKgM<2WT)KI(mv8H2a^D;$+1Yx z#n=0MVSnLxkL$&Q)T*$>%Ko{aAM@v+z>Tdc2WH{U=+TP&qDKX%LMhn$v3}rd*E;c9 zT#)2&i=!q)_Y6#TJ&V^2+xy!)wL(e>UngkUMC3m}Y47WCZGGp+_3So%)g{Qb5xtZM zwrF0?k9^6hktir~JH5eIzx4h6NBg7iMbJ+QvxdG8;nY<`j=j_O!n!32Is0JC3D?bT&zfw7*jI~~iSdBc^KsB-|mKgh@%QJLI#&u-i0 zndtDlWvkXYRq;)=f9s_*sQM+NAI?+iR%o->GGP3--3IHAjA2g~ydu|e^-#?}q3A)^ zAP;v6O=q|pFbBv$CA3Ex{LjltXpMAmj+LODZ#&R04L&7%k3QGiuNqQlFnBp_$>C;m zljXTuwS%oox@&1y12B;V}plbQCT~#`f~4=PEwE zV617@*1ObHHSL*t9TGrFCr7-$-uql#@~8g#>D9$4{iJ$myFFL;x;@BbJ?zyfA1#!~ z1L%~;s-z$mLP@h{4UW#jw zt+9;ZC6e&zTnKNr3`UN<^FY_LU=iJ*BHPt`I#KK}lDaq#x z0uR=)`p#}=k;*hG#ReZ*|K4`Dpl^tx7X5(6A1G`(U zMh2*4s-tAPu7+7$xq%%RRa_mt!7$I>V74}QW_i>>fNN=+tm|c?jO%h6s+uY}uXi_G z*W7SHOLQ=Srb=^l!v)Q>0NrY_b{No96RMP}+8fMC*&cI~+TMs80i`2Z$hyg@I;`}9 z9r*1sE8FZl-l(F6yPmDI#;meas@iN_0&0a0@srxfTor$s(m1Uc!A8Wqw&1{(BlM&E z>xg-B4Rg^B$`>6-Mn?=8V^K%?!pu8z2DTyx+;Vl~s30BT-6jlH$08 zyueDshn!iB55#y>6Rw#oM_`R%h6*SxaH7~8EQTMW0^yylwciJ*gkR8|eQhc3|Gp>0UN*HuoLjos_xlf)Hsx5>#e(HQ)(-g%-a!Ae zy*{1($0MgeIIUGGWfd2xTRE)#z!7+ol}uK1SV=ek36Xn%+}ns8c$%O!iq>SGfc*;G zC|B*-J6z3+enfj?7>tVcI>`bAzF1x2CDWE-GU4Ndd?QSifti+Lja7QfHP&0Rqz8Im z370YsCHq~HoxBIJ=qGAy>sh1b!{l+*-O0dt(2I0bIJ~JdCzA+NEQzTT|Bla{_;;K_ z^mpp)xpPh|SQuJrV=B+)wSKa_)~Joo(|%a-HvxnwlA>co|BD`5So zf|Sh^g1@W-)_-0`roAJR#D$HP@QEohLLN?kjq=yU5qE3!`$nits@yhT*Af-k>t5z# z@Y>w8z?%%_71ztO-|ELPz#8jgR9(?ly&&0$>;(n!Iq}qmn$jiw$9P!zFG5dX|7w{; z2o66Kiva55dU!XO3;Kph^;MA??w0q+zVmj2`Ral`aZqx@n>D2MB{!TP!!2@y>CWy= zHY)D}{pI}}3b6AI>nHCe{pD?p=QW(d%6ezl^3K@)@?Ra#k5;gEW;H+mi3FyUJ6Vch zXnPoJEAc~(EzG$I`|m~X-w!<_Y}|J(L?c^$ZMf(&7m1dWbGFd5hf%U(o%uwC8Lcos zl|Sz&RqGO`*xOy5EkrvLOCwL&5rMP*s5VtqM5BP0-Treq_%a| zX5>~mKf*tX<@r%p?1frtTh57knz`0msuF#sWgSftidf=)Z^w052Pfig(S-oF=X?d% z=%5s9z74v=`joII)!`sXUyTJuJo{frh0 zy4s)UTt}138?F~YpeB^>X}Iu)h6`@+G~8E9M8m!ES7_o=9K2V%Zu&1i!k)?(b}r;uLa5FlEL#_8b9G1<^0iu&*#n)Yg|*;)ObRJtHNibPi`27d3bKdYrc$C zi@uQK*z5lmJxj(jweKhELP~$=@Rz!l4t6b_tC6Qfg@BEN}3GS_+he4k=Y4(|}N!Db8CgF$Kh^%oOLXmKZlNvm}@L znuRmgIi_cUCset>^{i(heN(y6W8SoYW}#ufNt(y+Eh3VUNwn@a73lDEs?5EmSbt0@ zkQBF_Le;sqRNEx3pgHpdGX|ELiB))(Z~A(%!IOpj%uo^-G&SAzErDde$dI%u(&G zS2fe}CG}EoL*?~`d21RWSz=Gqf{&woRp3;jQ{~m)pDVoOR>6t+S8Ls_zw_hYH|lRG z$(pCaFg3J&p~b3j)|XjEh#LryHE~k1H++-O24AYsaJ~H{MFLhGnwk}5^X!8+j-@~@ zK3JpG?>Z|_Rj}5|;n#c%W@TkaXhpONp-VSLZC^N=cFvxNP#5~GiVZnlq;Pg8&Y!te ztZHFskw(BdZjwYU5(G+`Lcc)T(GPFR=Ii92>dn{vGSd7`>wL*&PAed0 zxsLJb7<^afJfUMw(lN!v{87h@)iI^S+@oU-(J^jfZr3pm9b*vFpkqEdQ`L1TF?Z^i zH+9S$Vs6$kYjn&4Vs6wijVi`eld(J}pd%mBkqt6=%5yH&k+4$Cn2vXf1PeI_zYEb_>R1eW2}#TWsPpSJ&;epkN{4X-sR|}WFgnw<{+7P zULZDYxm-x`z)Q|WHsoTA*=?GI9@)&+(s0zSi7qonS-lupUrQ?*;~o z>C>>ZY@vbFL;VD$UN&Y0Xg?Vq($0&YH~!d@9O;h|1#)PstZ$vPdN! z^_&{|q7IMwsx=X{GtSybWWtMwIXz#(Fy(?K0b zBkFOpcukc5Cg~paYIRlk=cN?wlcOJjAF`Db^N97l0;rbCRU{ykJ`o?P)x>dva51@;RQyGrA`~keYn1r}510$v2Xm9LynD z)k@E?-pL?`XMA8?tN_%wrgZI`IKYRNTLH-7Zff6S(xyvz-#S78$e5-8*z2fUlF>mBhfmA~%zIa(MvT z#TL&J1IaY23dx*@n?BZ%(Jd^|*DT1;qAjLaB9FOp4aBga(-DH)h+spfAn+N8Uqh!O z0J#yphE74?GpZ$~nwVJB6lQj5UF1K@;ZA$F4u2@7&cs-#bjIw*BC9b*?`74UTJM26=tgV1m)xWFr ztdTsgfUhSss!%-BqVj%0a(dLG%4*%gdf3CAu7^-uat}Pqqh3!;F1+L+nUy&RfG_;> zT#tS~(Oy|eQ{}QW{}=#Wt{tPe?Ub2u_WqgWRuH&&g}qa*T0)HQlv#0zPp!j&fGM*v zT4ya~F_7N@G(t8(d%Tn%Tt|3)%nkL`M&`Fh{@rBW|AmjJ? zAY+79=a*NZ3JY=d+u5Z;Q{Z6ET{;LCbe7DObdbjntq#KdPV$-WKmc()H%C6?3h$8i zFc*68Jr!?xK^hpv11A#ph5jJfh3~zfGKT)zgYW&Hx+Z?WJcfPE07LI0T>h!97zkf#)gC)SDr z4&$A(V6Bzm>q;xbSN_c#e!g&n0EegEPezJC0gn8r(GUy*WTsMuuGCDNN*vN*{V-m2 zwh>n9q35LDIC|XWmHZPFP~RVnT2V1ie_{{-7Z@8|oST`no?a>OQ3UhtX!tHtiD+R2=TvHLga+`v)k(51HBXDGsJb+)jO~7vhM{`RYN$XBklt4)0T{4{J zns}U2*{#b!vL^c4e z`xStENi|P&Z?yp20DuxvhpdVVsd6j$|Gu1>$_Klh$z3+7Z@wvdA~^uC83{%VV%A^q zg79S6rBI&OtQ&Rl zLO0et9TxJiF4tkeZ>wi0T_DNo>77Nrum@Ss66+>2w(M`Fm7Bf;-i}Np+ ze&L~pCNY-ahC`cmENx+l;B$@jxst2!n6ch^)NSu?qepjJFYX|o-CBY4W;RE094&|L zlP}wB0)HqXm-k%NdMzV~2u(AU92}bMA}evtZIgcxCyas7T-_LI{h+!lrmoh8@~zV* zi?UnG{oJw`>c=o$9Q?n>ex)Vwfr#S+II$TTZTA)7coCDs1~K9#D&7hE`J3!J=utU9+a{fNtaKiKHu;BHk5(mn=sD&> z1*^6g40*T;t>|8Q6%(xO{=Z3Uhe+2B5JHZ=%==(_A=*Qt5BA%E_u3tJV!s`@Al`v4 z_53s)7z<=dwWnR(WA=b^37c2S`px)Qz+P#x-^aWoLJGPBg zID5bWi;&1jne~U%gwhQTe`VIMS0;9mXo*TN%r8^Yo|ZK6B@M~#V4#rc#P?IHOi!qf z-fjxqs)}{hObYpD?7`r=`u}0?UErgtuKw>yW4K#6isoGjc{I ziWijD8-38!K5EM&Gk{ezI7!WL9HkXnd$oOfZ*8@$a`TppCIJK@sDP*huV*}7P%8;o znfJT)nVDP&i1zaSpXVtbCUfRo_St*wwbx#2?cZK2K11jhJ;nMNCb&bkv;JPP^`jTe zM=m@DuQd7;AsByz`A(8oCJA=-*?pO>FVSGWZJ`bFyu*AdH;;3;(nu1GfOor9>qhpY z+3yw2-nPr+ykU0rBH7{;$w-{CLy_!UAsJiSNIC_-AymM6d=-Ku>2_}Pk}vJ`$EHn- zUnF!BiGCecyF<9s{$9etZEEIdmVrg2>(KGlW_yjFxZ)$|?|ca`ewYN~GAFY*x}gzb_tTsl!?T~<9# z2lH`pk0UHtq4wvP^YglXyqFV8Wq-=taKy&QHO1rx<8P5G@@h_^*;>Is4bIvL4YEn# z`yw|7OhVi3!dpX~cd8v;#A^LD7YNGdVnt~liJ){1B{gOG>%-0fTl>Cv4tS z#ugfkM&Uj-RhTUVAPbESnz34`levjSutec8yGh!@@>z>Lm@Q-yE|RW^89UQm^Sd)- zE7nMt!YaFxSY;LoOg0IZt+S3{9xzO3Z9;1kTF0(UMnd}+x}yc7wl7od6x#J+Dv>YX z-50*IQ&Ax6q3OaE3hmX&nT3ITkJ8|_D(BlOSzWR&z%hWI{|hxEPP5TaCJ*EmOzn; zB>+5V(3d|Sy0&MYCfaL&MFs2zYG<|+?5Cz;(s|)7Ix4c;jRh8+%tFKD9O9Em%`2&S zq}y$_sVk%9o^ZCx>tmlTb}u5rV{WidP^UoNXA%bzq5mWSG)K+NBR;G36$#QhYF?I} zXtH0?O*SB|j!rG0ApowgrHw2gxvk}s7+F*EcQs{eOPk3zH(2{laiEZQSJDo!B)w-}6Nq!vJP> zk_5BRS!sd;655k!wqNNVdsp$Z?A#kkM3Cw5b)#^bnYHDjG+#fY&U|2Prz>=o`&com z5xeg`u9#Ctvl-P~f5gUxuVx{V7B*+*!}GVJkd(a(3lAj{5E-Js6gihPNA8q&N28i}$wsP9qdx~@S{WOLIxhq|~Zd{YMNvr#^Ix|vLx@(I=q9jFnRsKeXuPEs6 z;8jmIVENTfp_1sFLbX-a;OON1it9&)rgIFblwjagO~vtA{RdQ(XmK?aC*BtBic5Q7 z8@y^aG7X3m|0Aj-ueg%mG>8~?y&4ohfwK@Ibh}}qiV(b(0e&I_+&i@(e7!vWuzEZ^ zIcN?c5NE(#jnWeuClkI*(XlFL?B>=)-u_BWWY4I1Y<3y0CmQV?ps7h`M4Fcq_3$nq zp{%EBtFF&a)t;({&rDa_9=%V)!lTnygKPs5dgDa6yHrRME`u!iFS|M-otUOh1Y(hf z?;})YCrcw#z)eK3u^cnI0vwkGUD5=tA;t?ke1N4jw z(gW1-8SJ*sMg`JW&W9j<2k1x{peP^?XV&VmT<|(tynWgNL)QuD2HBY~8Qgx!648PM&Qfs=2%|>&I=%(bv#j;qckE#Lv z{2krWn?|_6@R&=GR;)){WIur-H5I35bxS#5Takx-A=XZx8hLdKopYU~;Pz011SgG% zxq#c=O`bZ`IW>t>ZzoUvMLirodlliGLD?YKQY61eCUR>b>l2i6vdM(b)UhCIg#egk zo+|H^NmSmqWCAFlH&=o2F0z+lk!|||G*G^jN_b*ib&@B*F6%1?Cu>y%9hhgPSvEt4 zS{oa*2} z^+(20w+~swvMxYJ1fM3N+?k4538|$EebHI@!Puk1h(;7}{G1$o6UVU*iw#y3It=lu zGkK0c%PJ{iAgp)hBQBzCt_=Zyb#BbIIzJ}FT9)-PG1`0;v+~1wkaop}W*w2~T2;x5 ztb2JB(v9H}9#zF>TfdX1@~mG=WVbBqnZG&@Yjqck+=?ljFn1n@3yL>}bFd%YVM{h^ zyql~u*e7dlks0h*Za&Lm%xHB-aL9i8MB&GzDwS&zfkq;1x%KE#YPZ3M)WwKBA|gjb z7MAg`BDSVf6gy(8Iw`MYjw?Sw`qBvs=!+SZ#1~j4x`kX@3%kn;L=`b&kJs{*)ORRA zv>LhTSIL{|xVq|Uxf26vzJQ5g5kS-@$?xl&-=R_I=XsPd*k*lIJst`e4g!DSCu(QI z7=0ysI*=h*Gfosa)Xu#_thu5w$ui<)tXwp~6WEf;K zep=AJj=9yB-~M0v)uWHfhTI~V@YGa7z8@n!;pNlQ2sNwvRI!LG%dfuKZn%P7WG-t7 z>mO$9VMS11aZ%S+XHqoV&7FO<)I{O&qKI!r zh66jI9pyrdU@@^ABeM!4vuYnBQ$2WsJc01zh>n@Qe^+V*suL3JM9me9nwdt{r&Ar zrA4UTx#J<)8XAukeNc9@9$oYR52%LG$nzKiiNfpN`dnSxry;0h`_=ie)=~KT?x61( zvnr}&dc-dA?K5J3h{kBd9+LjI?vZ0NJ!)T}-sbtEMRn~xWViGmvUA^by9it+g8Iiw z4uG#zqxE|5(MDvQ67MT`0io^vvGeCU)?|^nwyy%5D4ak+Qp#njlwnRG$5M!?ArOW* z24(bWkNq{VA-`re`6}iXguKC7=PDDjNH#=Yix#bJ9~)Vn8NE6usu?Eu>|vt95W5T& z#(Qo-c!HEN-fa3!MtH2ka%KJLSP>^9Lx(0<>p-0B5pl9QLzQ4=_p&Yj=rqKk3by5Z z`Mpn5{^Jd&DR*&I-md6zxue&eW@an1GMnm;4CRRR70tG%sm7p3P}QfUs$Zk3UoQxE zDmJpm$j#x2>LzBiWQl{F5|5M>#x|7KAJS#a|3kG^C+GMo=7|I2>R!Uo&hbUhNNR3( z6{p1F=~yYf#A4cTlOUaa*zo^}A4%R$+Fr@2=uv$i#%?YVX5MM7Qr~H&9t>}pcguJl zkgt2}u|(ldUXwly4?a4nh~o>rTgge)nRl~r=@caQ;O;q{ya)C;IjFc>hJT1|>UIBB z+|Qk(QeCx^iqKVqWzM>q|2YHCS>MN1+pBYW%(Z_+XCPF9F+CIWfPfeF8L_JSaRz41 z%U-dS-Gufq$H9;_FK5MWe%H7=^rjtTk7y#A(i&NU@VQB;!I}e}#i#U?-@bpndiPgf zJ1}%HHel#{vH!-2{fBE8f}G9o0)C4vCZ2L=cC>jxjxTn8rZS?Hg_kJIcvU(lG(ikH zyFzZ>HU`7(WNuZrIX0j&;}V6>?NB}G!JHc=4^ZYH_PcVnzXjO8_6Pp0T%(0^$7bR- ztjwtK=7xrm5JPrNO4f{<-s``9(vKGAhiD6jqf?q|Rh<{^kfcmb&9znWTp9TYweCdW zp;T2FaiQrFlq)2WZhb-X9$`mjQ}GA|fCB965z2EsLTW{4hs2r}CljVzK-@x2q24BD zUsL$N4exhV+La?dOQ6UyFw>?T`UN&9KxAw>3?=NjF-d!FXVBaw_FTX$ILQ*6G@W@o zCfrqG!rhkP{p7ZeeFLbY)2K*d7(IUMzSclAn}iZu`_*ROpOw=uW+HSfPG_4Dw)vfB zC1r*mAYV5rWJn2S-F2Lj8iM@rcM|x;xf$%Lp| zmRW#xh(%`>jxB(LV?!@LB-523dwh$v6@||iy|$AL1nPcnzFFNohiFr3g+~3tjauDl zO%qd1!t-`o{w^`suI<$7ALrd>;qKui2#BdN5^H$F;GqniTPa*NXe^fM?OR-i6gN*5 zw@VIhNZxaydgWB>d&f$nI~04Q)YT@g6{82rGJ?*Y=h)DXi0>`>-W{T#Fi~+js_wxwshUdc}xM?{pT^td~DYS(q!hMVXa9 zdD)peWtq*aem(iBk(4OP!M8c9c4Ght=c*C=?oKpOY$`qWU(?BxV$B^#YuK)Fjk@|h znIX6;SFYd+C!eUK2p@Z{MFGc%OcXw>-WaMdtF2(tWH;9<12a*0pL6XX1N2VxUj zrW?{>TI>^ts)_ustu+#gO3IR;Z-v$s%)D(bS<<&|JW2(Vvvcko`cv*A0qH(v$fz~E z&uZUlmRHF3wX_%!@lsjM`YytSy}6cH&(m-xo*yg5H~m3PjW$M%e^^WQ4gWRheQVx{ z+87_dSIv&Ta@Er1;d^mrVDJabwnX7&gC)#?pAk&iJ- zwo@d}Ys+%9Wd-hrJa+@T-YYW%AP|1rDETzt-8=6)K~q(Ohh!G16n|6NxAevANx@!` zjI*d3>2O4_WR13rMfqiU!}SKwa5k#ME^=yM?N2RpR?M-`r+GvWWc{MNM=jz^wYj6( zMDT(WTMZ}<*hQhWoaraoN$sQAHt}0ToA`3xWH&{K8DmeTcE?iA8POjV8&YcYf#OQ_ z{cv%)`hKjql<#2lvEuRa9s6dYT6=JB(7n5iAQ*TwNgS2xAHjaK1xlU{bg`s9gM~5D zdEEI!ID=(t*u;|p=F5h;H{k7>cY-#ifB$U=m`^1Nzn7itzwH4xcP8d;1JG8-bXfNu$U0t%5_sv@(UezKX3nYx;Kx_CGawKTp@JwmYeC!z< zajtk!mT{i71KNYHoEMu|(wm)LU|*=JPL8V1Z6`|*2eUQkeJ@m;ZZDk&Pj(n3n~1#7 zkja)fY|H>}48PG+mQ+1i)?DbLjL9 zr?9dVb-D!hv7W;E&}TsYq89>YqGqw-{b+7U!2OEhePzzLo|h!~;H}%URO7Z8=KFz?y@q%1-2V4D{kvSGY@$d_a`Jo(EcC#r*u;VA?^X{39uy0pN*kXYZ=pC3U}6e7z#q~z*gKBdRZ`f z0QJD=`5FM!*xMCG&(|=@Zr%r@SEw&S*krP&kmP2Y)O_)-eUh96o|iiRsGLt?^Ik{R z_r~UBHe_-pe4m1t4Li5NH$0(`c>+6Y&2U-SQr)r00wtWjU_U1H^<=J~A}ou6F?l~g zVM@{FcOwoClb7Xd7;XzlG^~yu-3O6Z(2GKUQWSd6K1mU%D@C9mqzD8O?+rzu9weUI z*Wdv0Zh|5yDqS*)O)TK>uHqc;w|0z8QK^bEUyw@9W9Tz8m`cBNN^&aoNxrwBxyFce z7m-PQ&b(Hirw9-LW?y&FtveTG+GDh39i;qmYs(rVo!Q#5U_p`g`zBng4IJrz?kHYwGXgVm88*<@99Z+f-v5>HWh46}rPQI4Oz(_5Xzze*Y5cZ(?!d1?mO#zs4C z{R|)b=WJQ8ewXA>vD1!l$>zdW@saHbl(0Mtq`FDFY+E2!l^}JxMw5okn`72}>!r+W zm*H+rbk=Bdwr1Ef~U<6v&+$7$xRi-x}$by01^{pyb^dQhY{SOc?n|a(EgN z|7G&0TYkFZ-%bAX$WKrF&g4&3wJiGB`zrZzt7h);*wf@!mK~6}dMSQ-*XC|Mo^7%TS zFrUvk?EhEXj;}5L$MKHHOV8<*DnILPna&HWcd%cQrp%|B+A2Cz5VdciNY43CMF~dD zx2``@tXbI;&IZEB%{eaYH#{lcJ@bf-mbuH9Gs*)3npF@ain%GWBZJ(@+(3fRauwv3 zGSVS@n}x-uA(JZ)-rno8r)(dL^E5Edm0+9+ys`ijH|y0CWZDsobB-}9JQE9!ji(h%pf6#AL0#s=u;_IYkXF_Cs} zC-7}+9;F#2JB-+^&<01$*tTqid?rRmyVW^Z$WNf!#!wpk+=jT?&YfD_8brL0Ad4)u zNp00WQ)iN7q5p8ol`8&{n*_C8DNt@XC`Ta%6MGGLs@XOfG_Q537P5QZ0e4$JVyZL* z*UfGm9$qDN_tn20y2$j;mXjxN(z{c;XX=4VW-ly@BSc>CJKn-hdK4H$nQM`)&YwxwwXU>x4Q z=>T*P+_=;h=Sh+E1Kd)O{1k^=;8Tyr(F2ho0NzQs0-f_j&W)D~MOG`ugfuLC9D5Uc zaN{@8c>?6xZkGrx(uAw7ztJCiW`MbI57k2R$}sUO1z>z zvyBtw5-pVdxt!ovX*$uO^aSUB>YOjKevL;JX?0yvT1`tzE0uf=z#p@qL>ND4#Dnq; z*3(aAt8pi6x+*(cW4j=;ihIWcdG zoQmIw-&v5Ma{LN|d%$@rNxSsg0`Hur^5?Kr8W&S3n~CAiG#=Mo_;Bkj%#`H&yJ0o; z{`kG>@~+U1M^$yapUgePdZOpX4Z^RpNt!FPFSPF9wr=GjbsB12oi3jBj2V0B5JPncJ(t>Vp_G!D;x@ca)RNiI zfy9>s65$|EM$W1~m%h;IvI-StTbh2eS>&2uG+nK6#jg7q-d3R$aqFCEa{jaV#v*tY-^^@BAAc6$DzvjJ)s&U-^RVYL8A^vT=kX zuur#+pQxxYYM;wa$~3!Rp9@TskZZxlh@TGDKVhyi+%~Q(g7i*z~s~&RFa;Y2bn`dXf!o)yLu4OBC*G zVLf1r%_7rwiq<3?`37sS8)rlLf^#H8T=j9*o=j&ETnMeYHVNChr5r&f^Toe#ktP1< zp=wNt>=Vf_$_gR6k|U!&ixvuC7LnG1Ee&zap{EN@juS@Wn0sk#KMqUlvPC_*Y%bcA zwG7+b9>WY8&bD@Ea17}Glg_ylERT9$p7dR#D4?Yj&ZczhDC8D%{B~IkzYWg~$1Hjb zT|Pzf>a1nlm2FHEj-m#ld_8MF)vqG`e)`O*Lct5m?y(;Zu&l}fWLKTx*S9< zK8{yCzLJ96&{6*SjWHvkYk}1`F6uY>Ofq`}8d+ez?P-WHut@7K*Hdf8Ea;F_Ya{;m zvcwbeaxlR93fZ>xeRwDd1~w!!{L6+Lzg59z>zE?d*h5)94$JcKf(-B8+uC_EAXfJ_ z-SlmTsgf%+2qY(iT5=`1U#s{1*}tCjdud=+H>pvOo?T4|Rz<@(YzCx1!sm;q^wcMA z_tz)p>oT>)Cd|(S9k41%#avdub+bbN&FuzYijsokL!~L=tw}Tr?Vg2p?LP17+cr4e zTd9D|scMt>t-f*o8^(PK@Gok*dBf8*Z=Lm+TDsm+pSW#=cl!b+m(4OYG3>s=&}PVG z37qnejz&z?=-jf6>`$wKQ}%83!Jp|*pI-gQ@CcnpM1j~@e|fh%@ubt4V+QWbk5y+b z**xu(!Q>!7-GE0051=63S7vy(-}cl%zcvCQ0IlSUWZ-gY=AntS=ZKh z=wR1paeLqPN?h4*?d?`{N$qoWu$Guzk{94>T>Lz7lO*m@ub4`G$~tmCW%a{Uz;{Kf z3>gpSbz9${uSF48Ho@ga>^HbGurQtu1&!EzEZYk@=-yR7CFYp*Ut;e@E}*`#3x?Hx zb!a!*cl3<5DLF1zZf@(8Jo4R~g7Y%b1oG#mkH{8c;EwK~tndoM{0IhF@F~wKF(Z0= z$XV!2?qTmswgdiB%#dW3l;hcm{Yh0^h`QVGt|yDMxgk+F^l=fGRK&Yinc~)-zon~? z-abFj%X*3z%WAd!x|6~N66gyp8 z$`Y{)vaRzxlICo?nROu&REjS0?!5JMxH(+qb_FUXZ4YJIW39#c68y=7{VGFjex6-m zW)<;3q_HxZb(lPvXtA4Cf`E2e-$K12&&8sF>b}2o#w?O_XJztA;($mNG!m&LGofLk zlR_WiWwZyv;v@oysO&$R9x zraGTrco9}|HIg;X?{-x-y*7wR`0PEf?W`6j^_}Ob*2;1+YJC(J1WPdXgv0rJ#dsLc zGInV0t|{diu+&I326mG~RGq-Z!;tuppK3^m)nT)uyw_M!arbNG{2yj?y>B$_$yAB* ztaA)^2XA+8BEhtrDzXQ9RDK~= z6@4+XdvCbVn&gygO-jGYKA+Z}>K$q^%IBOwVl+m4KCQ)@CJ7UpEQV!)Bu#AGEEqOg{v^Z5DRM}tp} zbR}PvXuY~6(w!O3s$E-Y=dcSe?5_bQ*akmD+pAs6)>G`r%`pBTi1peehc#k(!V?`0SF~dpcsgMB3hCgE+H2a++AC#b zP{3SfM6x-41+M=L`W(z=`%#n%0iI0eFWDQ|dGGpZpN_BE%Ef{y}kNCU$tX3aP zbyeJ0STSm_J=z!_j#578Re0v|KbeRm=c7+$7 z?cH7)DvgxJI-Glqbx5kA_roYCc>>C%sey-8Q;V=|XzJ0}QO+oIIJxKm8y=~uIXM2a zBT!@cUh`MfHhP2XLGP3^H$?XA#T)Z1Q@K-~eFH;nhPQCRISe&q+#0I=%QNW`#u)B6t#04$68mj`FzQ36nR zf!fjP_k*!XBsi;UUVK@u>paufJ)V*_`$4I>JA=_{?@1Jza7EOAe_28=UqFI;a8lN} zGUb}pB)He}d{O_;X?N7ko~K~Nwac~0f4gP*BK5lM=H^Ai8c1y!T@cY96F)^TcI0uq zUticQP8O~Ho17FwsViXCwMaG2kL7)Ow%q7$5137r<>jGaiDq&kv%nvS?9ICMU6ohq zdAY-!{_Ck`-6naeidFvZv(MF@_{FH7dUIWRf`yi+N}8ko?~!=&9;4(1^5O=)&DuTx zl?f5e4WIxTd_x6{4J;twU4QF)crtGzU0rp8?X1W->mh`oynzbO?G){I^HlRL^)AD` zrmErA-DiU_33y+))ncXSN$}A0iNDQk(<6WLfYMDg`pixu#Hc&~*Opc1`@9{b|!ScEvF)p3gW%Ig#`(wZPChYNGT(*8o120H6 zYx1Jt?z46^c|u1|UgX<-c7s2A(Vzx@PVJ6QCO2@!*>6U%*>->#X;8rQqbTJ_;1hkp zDZ$v>jG#Asj~0g}{`HIJ9QBw%4smA%uXK-mn$~KzS_gnWPt$b<$sP1@08GMxx`%a-oY`Vru6wtnB z5`~Zb$-yrFjgrh4N~SM&Uz`)Y*yF1R->Kd4J|}SxSLTK*R}AI220tiEfT^Nlm46k1 zQ>hA?lPu^j+!tAJXNGpipEycP&Ph!6m=}8tMFQDfPiNqL^Zz{lH-VGYZ@dj;(%xC1Uz=~;o^i3qo+X@Ero0Du?U-IEih-KfnBw*GFgg}_P6e67 z!!RKa!yC7D`Z6Ya>|+)Unk>bpZmy~gcAw>mRb{Xx(MA&e2MObW%8Tr(K1@I@D-oCy zLq}lRz}GsddujpbUz9LBE%p9q9_-iN!+FOtvHNW!ni18J)++jf_xU+~Uu^bJZTT4_ zh_@!b)19axG1T#q$)3!b$lly=0c(NQk#bt+{BZaR?!xlOG`yeA$+f{x-~WKqh01!P zAC)Qh#jLor{)tN+e%F(_|86{?=xM(~PeVbNg{Fs@>MCb;?rE?4| zI@L|uQS>FZ#ax=2+Jk0DP3>w*4|<=T^9@-et`vA{@uES9s!6%w!HFq3t?r@t85-RD zF=BPa=kN~lWZtydarY@5ri36qEN}T3dyYIoZ6EgsMT0|FsVU8v;_H~mnC z>hj+?N&{;4U8>SDTyt?m%XTzr9!o4mEU}b|5B?vsS8yO29{*vAhA#~MEE>L4dN4H9 zB6o;{OwsWaZ8>2QTVen1+;DzmN>1iVM+^@kEE|zL-SQCD&f|LzG^$virF;EdU|Jy#y91p zX*`oFicirxoBageb@+7t$qtRH-8H*2Mh(<^}CE}kksrpJ< z6NN{>>)blhjU0pj*P%z1v@vB-@%Tja-9+JUf1RGV?kX12$Y}T*u2JbSAtIxJks$fw zoYXDs{W+kH{rAo`z(=tS_6&Es7I~aZs7~(p91*4YDrLH?@J6m}bVbhk`gru>R(}T{ zi_cCz-L7!HmY=nf4(DXXN80Uv1VnYC^<4&B?E)*)><$lMmTpYq2Wl7WbcHnYO38uV zXj!y8I-{s|LAN@Iio(fF>Lgh#t|*=@*7>c)^RYE%9{l2*GndKw>d0VpW>M70(H#qf zoF*V9{AOp+e4CW-k;LBcXuVZ0&(I@ZndsuEG(&IGPZT#}{7L>0WT-)sV0zD53T}4} z=@8q3W+Kq^K66LmvJ=zJ0%4uf^Gwg4UE&xEUCOKzeG~Hl2OuFPV%*5ZZYGT4QguhT zuyt~2M%!fdrq;>j8If5N3F*l4n%^V_?(;nV5C$OoW0g# zet>T_cF5 z1)Ww@yhi49%E)>XjGR+w1f(! zC4{xqLls)xCK`gG(1H5C^E@*cM^Dgx+f%RCl2q>|I}3yEj9-)5}{fh!vkr zr8=rjHWvL=iyX;0GyEL8ae&xzm9Ey?D#9WPGKJRwWGe8Gk0dKwWrolQugBiW~?)z>9UqZA60g2I4w>__Ac zJ?ENsbM9w-&kbg8svT2gLUMq(^)u?l2@$~VqM}j%mPBFWFNAz3DTOr{=bSYcY@wF^ z4$_zUQH@j=j-!s)8J)N~i@5np4iU#EvLqEgtlx->PM#S5InEZdnuj-8uVN?1@8!4Z z#9cnCyfQRMuRZ(l&=?t;$%jYNMj5X0ugR1C*Gt+|SgpuY*Yy}1|08y4e)gbNsj&;1 ztf9pjYW@)}AwDYZU8S|GWZlnYeIt%@l2s#C!mcPT_8$2cBwgr6mNrmTALN)(2}E;s zIMcqw)SbdYqrei}>s;H-e1Q|EI}!3El+P*ao2iE)O{Iy#;LoIpq1UGFJ`% zk>YL_D`Iy#6$#<3M)@p~IYX50&u~l)(EL<;2PNC<_#>$`ekiDbBsoqsVGu`0lD9L* zdH{dQ&V{oIp2U+S-XrWA@gSj#^b47z-Uj8A-+rid7g|!%iCBdb@g(oiazxskWAWD` z-ew*vZSL{c=i%A%G;7P4SR$R3_90ev`f=;3*Sh7+eI2d++9tak9%9)z(X=RIQfa6Q zO#9B1LLq%hrF&!IiXtpu0)PELFokN%eK@D~%+s_VH`@PceVrCFtV(OWr^Sqn+jDQ7 zZU6=li14B&d#d4XT9jYAr!=&yPNGPAUk;tVXmVm~lYPorE~Iz3u$C}Od6C3~P`1j; zW3M@Nwe4gO59i6Xom>ms_N!?tD!s4=MGx$0?AK_14rI@!V#SqK0}f%O7|uLR?MuRW zSX>JitGNfwkh#g3PzBl$opEAoWod?GAR^3`_#mXRfDl{D8rew2#HMQ(;3qTgGssAu zt@c#e56afpUk1#t5y9q5xVt}X%_y}C7iF^vA&ZchcIHE+%Er4|ea_E7;QUUorDuDvxo!xjFR!$9n^3^p)Y&!b#GA_g0-Z`rPl!8=p5jO%3V zDOvc>SmW#8%fi1S`*@hy-^c`mm$^}NdNb?oPcj|Pa{WVM5}5TxoPPpt#QmsHh4tg* zMviCt_~XMlU&(}`K%18cjIddjWM%}Ktcm){1h)pv_P{uXWRuag#Sl;}|MFeN5!;M$ z{1z3TtuQWQT!-O)(dgQGM5BLPQ*6>8-Q8{7ZgnTD$t=EnsGZnO%|pIeO(M1scB+kZ z?(N#*KjK}Z$u9DZi*s?l+2WJU>s^FNA}CVVi@N(cDmQy!Vj`e(?T&M4Ls?^6{YVkM z)F4`4z)|#(eEtgXdo0EJWg2cbeRqW_>SA(Ps~;k#-B0=O$-M51-M=1;uL=wvFkfP? zmfu{fuPCBCJ@VQZy(ylB5YS6LVFKUunqKmf_PDPuWeK16h0uAVfzV5u0D5_w=Vbd# z%Cy~7)w^cSAoG&D_(3EkecW^AhD~q##o9+*_3Fa8FeAuyE^=#0RLy(IaEWMHrsL7x7GV-I;3M?z%MH~jDw~l%hvtt{-Gqe zXMZHP`Cm^0#peC#5Pd}GkfMPPE{Y^h*Xm@)!hzVSgzE#aQ-PdLvXk~W918{^%^Jc7 ziksjO7>-SKtSYQcz!$<4b8}N2WM8C{R6_T*gnT};!xyVmjB&0RT%s6by-)b0$_xsh z(Bn<HkupGhv9AJ9d@9hy(slHgGM18*susgw1g(Aa8U9ePP%-Fj z(eCV|KqIzPp0*~x*PV#RInlLEk%B!hkxmc8#uFNlDt_-%`=`qJDXQROI2fvo0bMzG zAc{0P6gllPD6(evKop6`(QY6Z{*d2tgSFu;QC`N_$bdPBh#3TP#G}0HIbL%k$nf>=B*PT(*%brHOVVjkfHr`mr+x zyEu5bejEpMnCj=4XBbsTc4xF+`o%he+F%*gJzk`4R6T7py-75BAgb6h1@)EHgIOqg z-ueSxXrH-Mp3)|fiOCc6mw3MQP$CmEpy z)HyUiRbLV~9Bh42KtdIf$E8wp<{WL-%YiRir{ra_ds&A}jstsyzNj@xGKgmnPTuhl zDu-6Tg-1~Wih7atMW$W9_cGU90~XvioCS$?!!Vu790(QDb>!{AD?B z5-hR_NU>J8N_xlK+O>_)T602IGQ%+n!-q)VEuMT_o{ZMZgL=#}l9-5Q!5uohr#<)r zh$yp8-N2DtCHqWti8=ulz8^ThUhk;uLltg^4q%T)hXr^n2H7^%8%+M|d5O$)s>=DaKoh z$<}=glYN9akz_K@<}{NrlqWSal!L{^YTTCK#G;RiwfZw9s;>-gx;*BobvKfplC&mo zQFu(JwRQDd7@IQaZOmmgxYlw_4X$Q6P=gEU_W79glq9oiktJen5a&Ds?3_aekTzmS>>isaygR1V5v zZy|MgT1X8|&69C)Oerc3ld&QD9JACQ*+)b%A@-6_@=FP)4dIvKKUTsifpC&}3I#rt z7EOCZ`<*R*)fTTK|`Nsih0oHPKB0bJ4DGKR68hRqd{`bkw4Eu4lzZ<5-Bpw zSCsx2e-0(b@7#m|P6__?{4_<8(b#ZTMc zFMia!`iP(MKH}%il=$g+*TIM%RqQ_E=leFvL8lLqUUftuqj5m z=mQvO{`NE@MK>lHiDBCEID+Sr;$k%xOD-v%2!|qgYDDnJ$i-Awf~TZCG`pY3`Ku#x zLNkN~FCIYD9GC^?Di+ite-IHfAR9V7rV!t+$UERh8HkQ7Gkr@!psH(87=kg60TcHO z!k2}`s~i>|kuDnt*lhbm#mx3E@I%0^qOl|=M#agi9Cd+FX}vH}X`LeEWpQh^^%??P ze}tR_xmvx1?@P3`4kD-2RT)a!Dzl___3G68+NXxjDMwN~6W%P9yga2AjOZ(66H4aV zlLn}!Ql^p>RZ6l|LRIbIXj`7d279oc`Lxuk0XT@Scm|zV87*g%%kYJm?QG~A?5hYB z`@)%Sf+S&+8;D#0{cVO;)or-<>Wg*}T}`XoEkf)`S*7t&!fb3nt?q4psUCPiH#h2u zX4L~^rftOB5s%mLb_-uHqG|=nxg4VYejv1g`NSj{dzpShu`L99H6SEqP%~!HX zS3XIl6YE`_L~vQOrg2AR%riW*(RV`Q1Mz8*?GD8nd?GBDwk#0gHUD~@6ZijULZ!>i+bt|IMv<0$cR1zt(SzUh1jTmOdRlDbCsp z$^;WDCiSOe2f|bcm4Pnk75}r!^nKSuaJ!~Ai~R1*fg#|+-zqY?K0vu6@_`!Ab`qk0%bL8y_dH=ccelXp4dO08ncVN~=Ur8f@ z)Y%{3&;^i~3uhO_p!SmefUmY&Mv4mimGwn(;2J;crL-{IX7;1bNGNG2mh+9wo~( zm9idF>i51q50~&IfArXy=JU}d#SPq|1726HjrsTbq($ON8V@U;NTop{qid?o4j2uA zO_nTbbOwhsQd2$hsr#nGcw8!&uAiM1L@gXIF%267T_2#b1zG#?w#^-7sA$c?F#&f| zH3ex8;=&BN8>_u-^Cp^06bTiemEP1IY+4*JWtVnQV8~iPX>*4K=&zFIpu2_p=e~vw zPM}^i*cYH_(0tx!zKq-G8$t6I#q(*Ej~Jao_(0?-Pf9-Mrl+_%c1^KIN@pnJ`7MKU zs9w|CMbdzPxiOF+dR=2so4gTL&=W0D-`yUcciT-k>74={`ucc{6wd;v&@h0nz1n9! zPYuWx_#;(=ASnYQEuLQEf%ly%DmL7MsQQ*}x~pTCdmup24GUEv_pKtIchgOqX{kRp z9sltaVkfQ(G`&_N!bfbkpqniy?_~s$0OeY=1d}pIbW-VRo%qD&8t;fX1*!JR`cCwQ zZ+X1KZu)C<1Z%Iu5^E}M_^u~BNPdMs43MH$^xuU~iJWnkA3=Q|c(acqivRr=3dol7 zCA}uAvc~9z2&=b?kdqhYXiHh%?%A}({Yl(Fdhe^kTa$%ALf<#Nmn8yA!hwu_1ddj# zEnmkRiM%yNjhjks8O9wO6*hHNMSW!+QWUDOqCnGnlpPtZq9z<@53jWqe>Ml<{hc!m`~O=2#1n(!4^gv$-!9rsqS)m+wJ~nWO$b~S5Ia`mk)YU} zRLWYzosIl5RWT*Cx?YUZj|h{k2Dq!hw^fMQ?+sA_1kg{rl3H*E#QDs9c@ zRpP1Z-Bzcay~exKUfnFH3&is3oCa^|-{2Re!GGAN!4E>r(R<5_)Jc;=I??V7}Imz9D` zeC8JPy5Rs{&W+ynV__fX!B}24^Q!5Kd319PAZHH)Quoy|Ty<@c&smAORylC=SroSvJG6GlFH?_VJ*FOEJNyc2K;c)o=vh?i zg-^+VQ#lDl+nMN-DLFNWq}XzbMPdK-|5f2CB1zcZY@%OE2#YLa0$eg&1PQ`X9PLGl zVAjy1r3ZwhJkTQ1@dYboFyJMz56hM0pBRMN#Wm(O|7dPe>J*?bWO4ba{2E zO8#iRk|U}CscN(J(7L!tb#mK3pp)62iXzivLkx)P0jD9jo-EMEye^k&Dfu z<~gg-Wv_R=$~+`nUJE0??k2&rtU%*(>*fnos8)9*kF1c@os@ooP(79<0iQO-63|Vt zXp%;3QoUMQcJC?Ms4csI3;;x@?7txWI^Dr?A%Cq!EQf>C1x!Dbw;Hi;%lflgk&eaW zHd&Q+uSH+F!#ZL;maTe9mUHfWT4YVV+#^#|fcc5F%Y6C(!uzAgGIV9R)8Utwk5XcL zJOfZI1&!grZ;lY#ha5I>aT!;usp=_q7!uee$sbK>@wy;_{7z0-{p9zWu#(@u&>aD; z`JEX{XUckvicu3;PnBlGR86UuBT1OG0@NwKgloEadUfnJPecICFVQI79Fx2q)mf(Y zls`Z)WQXz;v($tG6urTE??~z0TZ@Zm+eF?VQ`P%UdqZ!r*eTm6O+qsz+jl4JV*oUw z7Z2RNza-mNpbG8P$juJ9_t(e`)-|b`FhBo}o4sHRmP(&#-)XwZP4WdXdQ0n8lN!`~ zrrLZf8j~LM$p#Xw?kEoJ0-26~DUbNf_ngb-&a!R95H=_MfM9t?%G@NYa?DN9$9^n* z?%WlBj+2akvjy|0?s0zjXmi&#k@Yj!u)?%a$h1_|2Fi5(dQ;Uq{BxO_rYG}7@FJ})O0muym3*1v%AS|WJSDI1Jx|GR zr@)?h>d#W`b7bkLRHmqxwfav{{+%gG?$`UwQ5!7#2zjq!0UubyVlpV%C-O&Rs!uV` zHN};R7vV`^tW~K8)a|D>N=Bm?_4Jo~ib$CKb3FC3OVE)3^)6=-dpwt>%Oz~S6V;j$ zMtEofumA#T-r=lchi`DkChtp)Ose3FOFu6aAsQ2TBztz zFX@xRm0W#TG|)dJS^bxN#`NMezkk+v*6OZf`cLxwP{r;tqA%uTigFGadyVE>)cfP7 zaL+$LwEw$^gP?%2r^*`9%-7|yseQD+NOOx@57QQ2MJBo?^L-_|1X@X| zvQ2L!)&UIlnV;ew5>=sVGf1{30pdLa3hxlc^4wB?v?vfWl#31}=NhGrJEP)cqOXAF zUig%})v?Qou_#(jk%&P8#CrjnzodPy#SOsq#mFaf<{q>E(smpsrKz|_q9Bz@5wXk3 zYw=BhrQ1Unrs+i!L?tR|PJ&GFbJcnTWcmys(`?}q)q+X+P5SA3BOW% zuf)%aMNCi|QIk3a)ofr-k{2Vy8_K2phf75rOP&p(u<HX(1WbJ?1@-#T(NVzNQ7-tb(has`@g)s&J$kjdBuLp7sG1qIZj zo?>TlIu9ry{(60tAgE#4iGh_!7yfCkz_{k{*g*Z((6BBRz{cku=F@bSSVUWpf_6fZ2<`Kq9PV+BEc6^fT9{DR(WqF{4|_2~KKXOH{28x%+rmU*$-0d<80J!gy5Xm_e(;#!?X~)K_`l=#@`qb4mP!!G zE2~Nl7^UiNexJZ^dFa~YL-)x;m-8ou1t)6pxGfS10#dPE2|uBNmn-PRG;tUZ91EAh zL4@AE0^?wlONG2X!3DQ z(JSwxW6RAJfszZ3d~rT%TXL19Qj0!qK}mFSB&U9xPaco175$R zs-mu5u4?tWxYzG)6Bzj$YFn*8_M>6}ljC4TTsZJ?D@($mY}ZRZGS@2r`F4=7^-FpI z$nn{gbR$MGMZvgpp%hw1KFRIC$6I~w5B=_)dSvgMdDrW)`M}37Wt49Y8RCp6X-vb% zgY`=o*=4I8_;_pyj=+tA9#_M9twN8>xCTAGbcsTbZw_Ud(-+$-(5-P;91^)Ew#22o zH|Q+7e0C9zarq`izNw=460^e!X6(sya>1gd+cRDPf(A&}tdI>v%W5RRh z-m;DTAl#$YB>~HADG0aR*cZYrY>ZAX9jPGPS8(uX5_K#6svz9Qa)2@~Pg}K(K)6rl zgw8%vFzH&|H;_|(5!g!|j!WUvVZh9?)dRrNmo5R8uGO7H0m5;sy0!@*{2F$lJE-ui zC4K0jd%+6!A;?_x+g(oxaQicfk@w6%#E8EqxG$$Ap=Afvias#%WD9Oiw%`c|2>#Qx z2%XlIX~fp%2SjgHM8>mUuFP=RIsGOT@7kdZ@jc&58R8^wKpa(yRfK?d=}HY}@S);p zQyRJC6PP7X@H+$w4ifwhL4qrHvMBL{@l9gErMsf_(!rKSg|NGq@)9w)L4~h$P~naZ z?r=~q`}>DaNQIZmvn<`s18XUTVSMMH^TbC=?|a)wRl$LRPbC=~7&w9k-(E~u$1yXL zAn>ZFb5ePK-5Uf5zB&F|;b!k!+MUz6-TbjUlm=T04m`<~JveZOBOSn{;>Hibzol?; zCty%m(^jOZ{*~XSsV;(A5>)AELAMAFd@jQ=Xm0vEwH0Al9#JAs!N8?*0t1&iB|F#e zMkuOowhJNDsg0>$xyc*!MQs8DKOV`!_2gCY>(2*_DQkOmXEDiAH&roTY)LNw+PP7F z``sHH|M~jxb}FRR4dwpGg2i*RNGA%6>0gYJ!W5FRU~&9IPJk?D;5xnWQc_YR;p9R; zU8{Og76GS$D`x_pl)SeGQ(metjGb zFFzpf$_uR1AMN4YueZUwOCCw{?k|6n=3QBq#rEEMZ+D_3SnPA;0ex0Uf-0t1R8fU= zS0=fj%LR}L)H7|AlgXDeYP^1j12tZwav=89=Nhjv0!~Pd04?IB46}aVQ4l|xi%Fi3 zkLI{*E4ttanxGKnxFa2>W2r)vPZCDH7k1nSQ7-UCwe6)gwe6*Lz-=$RL|w6{(y^hx z`_4g%x`z?aXVOA$efZ`0_v8U@ zmv-k?4$Lc;q$M2t@TM;o5b&8vGZ zXB7lTm~xObL>T){+5=4Hxt{4v*~e&Y_2Ra#*Xe9sRcNpVDp z6DS3SAu7o}A%gzGCa8acN9x~2{+j~-rog``@Wm+5gDp$OK__hBPNI%V;%tfWeW^rk zDYT~iwmY3t`m!G}54PBo$fZE$57NC4#ZMu@kN@&V^aLkkk!9m4l^aO9{>hv?D_fo) z%j{u4u|lGb^+3=Be0C7QW&~$$En*rVNc~(YfUbF*imwtHr6R9{hD>lViQ{x_v=3c@ z3hA=*R>Hu;1@$ zu4S&^c)0y$SF;OcBAlzD?C5`Lw9nuSIH2%hu{&Jj6N$6L4L>)qQYxkYsnZ@Qmpc>T zGZyYiB=TMJP9{l&T-g~kw=QaKdV5guIeE2{8$5>wB6ddjT|M_%z2OjvIc;{tuVZU4 ziQn*C$H%ZPkgDlte<%BS-x!0rKsyK}I6#cS>5#E+jKRAfbYcvG$vZ%h!N?y52r~F} zbbYTX6G9c$i3|yJtmC?K!BFU2U^j zy)ERfi5?0kR1Sb<6&e!dkXW&o zvA&lIaad}YXO=ax$`dfHpu%LrGHlDHdc0Y=K_B8+;I_4VmuH7_bkz`hborDF`5`T_ zwMA2CO7#(dpSOU$11a!~iUKa#5@g-T`XNS|!Ipyv@w;vTeai~j4JdarWh)>2nbF@wf zSw!o|Rn+)P)hCJ2NP}^Gw{%Zf#l&@Y6B!pN^c#6$@_i~x2Hq3a!){R77o7k|SL#!if}>muHwbqS`Av9 zuzjqF-G~sAyuF#x?D8v1LvHiR6Y04dDKx&I3yu4Py5*eh3pu(o9{+vTDMu#xBe@19{fz zKTr}mM~{w)|3S)$juGKcbB~fLxg%OadT@pCOVod2Tr%?T{$Ymcs;L-lXb4K0;(ce% zVS0n6QVL6`^tNoFXk6AIRb_Cos>+b`e6qaT)q4%);9Z7Km%P>@AL3WEbwg3{-eptr8ZvTW=^CAc%b5sV8q~USpDU*9RdT|J z4szn#RfDK#H9z?ns5+Y&K}3<7higrq2lDukL*TMLu9bxDwy*~bvYUN zDo)GVkm+iuMqq?1YocLPh46~XhHyKdPCgc&oht6K{-EeYoht4!(PsTCoZPLVT8t;b z1h6)LB_2sf*TAJwZf##t4$%H-&*T3#*Y%K zXl~A9WsCefcWpT$F>b*-cCnJG+d{()Z|mGalv!rW-_T^_D$<*rQo6ZUdZG`5`Fcqf z;=kXox`C73B5r_y5ET9ib<*jE)X0+r^tTjMn{&qheS9{6Na}Mc$%m(I? z7p)00H%%`1&7g2$+Y~39`;^j*osp>p`REXBg zA~GxAMO;|G`YM3%&d98Sz4Cmf9CgW69{6n|cZP{Yyw-Ynad(0szNq7CtsocxrDtpc z0%M61O-XmK!%n4M#1ND`BnRiu=+j_+9H7k=EWbEyKCFM6)vRLA+qcy(_iA+^CSS7E z(D2||{RHbcsa9Y5yHu+s_ss21t82C8e}AK;-Abpys=f}XIJ>C9$WeYMGQ0&upLx;p zvW#s`EeOu)*ww_su4Lgfy^=)t;+&FOi1%B?h;y5hixTa`f+madQRJfcVVR(;N50LY z*k4m~yj_dX265bcT_++vQ17{814!mr;a3p$lCF&;87h^Whixo`fQ}WkqteF;o00gt zst9Ml3Y436dGEr)D1(S7N5 zyb_)JrQ0H=1x2?NJ#;%vY+0e(F9x6+^NX_1I^a8!P5!g!mSGwN!bVHg?%QNsiVF*f z8MLc8L**2@im2niX_N%^Bwwn?2nEf+NUIQXO4ep-AM!dHpWyh*B~N^NqVQpI$0Es( zRy=^5NEH6SIRh*f`WY46N{dv!BD#M7&r+Z6J&-Jzzy#vRf-fZhuwXv7{4;wbK@b;I zFZqXY^e>TrtTz8$@(-i-bIZR)J*~bJ@08POCI6gO|HI^8;+P2}%f&|N!6CZH*f#ew?BcaYAgrw?Z+C_W;~=-q_43P<7iq~i%unP_HuDnH zwZ*BI^?>rBgwFAq^|fl)uLJXf{}w$Nhe0_HUIS(`Fpemum=n7AdT{2@Xo-sZ8j7#E z(;i$ViPTYXhLazC=fVnkVK~cbs1*nGNLNUVD_7FcpuuK!kx{nJa(`DU2~|y~YC_f6 zwQ1+!7qTe&j@!@rRoN#-ONY?h%v%1FH54DVT6p!{Uw#fzRIt1WDOjSjNrNw-v-t?=S*B@M?~FjNA*7l2GzWBeToO%#SDVRQF4ofpDU;$v}MC7X>e=54`Q-2$?b*sd_z zDjs%O_kuAK8A&ycVf&%l^VRdzkvzo}x`maZ?bOV6M>cT(TI>1S=+HJh^r%b$-c4bz z!^7tDg7aSp#8ka3bRjRI!V`Ml@+4VJ2mt5YID;GQpWvrDUR(91RJ&iK>AJbyS5D4zwpz!gOz7HL6U~gxcrF;bC=-C3wEm_{Y5ki1t*=QozsB8M zqen9x0=yt?U!w?6)z?T_N5MUfe*4c!b#f!asFi&O#BJoVVb6C0|`%lwN zukGv4V(J&p`r@k;2jGFe450O90Ma7B0T9b!0=B!r1xDA$s4n~C1MwiH7-4k}BUGUZ zs6|{D;UXEf|4K$+R3&Ysfp{U^{xl;D7e=7%DNgt@oRFqM=KiSAmml1{3DKHjh%>DU zw1X5O0t^0sV+f_cBH>uK+!!8Z{X9yo#JNlN{N+}um3U7tZxK-Ft7JMZp2=u72wo|; z&^#+7w~ys^djk?L2Fdt!rD~mCXmGz2nWVvkw|piIW*?viVjv3r;`L~JpGkvs4UX(pg9!uH zpbrh+yL10ENY}v4?780>q-Y=l=SA?Ix#E{veRJkRq*iEeKvf7Z(^-v>Q6^u-5&gDof6OR~RXyp~rnJY-BTf);D#*XFri9J3f-PO$ z(r*y*lLYA`2hF;jT@Y2fJe3(C>?dZb28nDzs(MdG3pez7ZiQ?ksA1*%nB8Nb9IJGTRy~~C&-1pe$L_Aveo)7 z-vyZ&AtIXIA+%hSmjNMVfAuBB^)75QRVh)?BqSS14N02pLad@mH&l{qDzDaRTi+{fU#qsSPx?>(Xk|A65&}vB zRf4n{pw+vqR=_p{tnBx5X71hHY!U)$-}n1_zYXlYcmAE3IdkUB%$YN1upDLJg{@=h zLSbR6EPZxqN$(FP#mQP{4E9(XaVLC^#*sjhAA`C8g}T!U+C8nHEmQ2D0&m7IHWeI% za88RD>YdtbcN=IiE|ex)Ohl6A7Auh??C$J^3se~($#}A=I?C#jqnx`!2rMKQPA7l< zbqJkgHw2o`>=>F(7D1LsODLk5(O80o08~DQn$xQH#u>3W!!!`s)p1wLtyp|0gn6h| z$cRb7&)2#MVG*V!I_1vQLxbBoG4~=mSH|QPIR@Rr;vZlI0QIOLWX1V$Wzbu z;DH0<;Z&6E#znnjAy$HD)$gvKuhTfssBwm(0kUzJZ!IBhROuw_OMyTi15-O>h5ly~ z6XW!VB`~6iwj;9<^>}Y^KL+_i7a7Z1g&2@K%|=NxNt|SatYjaTF44JECSZagQ;3%! z9N;(Kj@bYS!c`ePOtndB^Yl-}EpgDp!4KP@_cBi+v~1JupTnmt9jc1|DR9rmCwZXdQv zd*#Y#?lOmgI2fYuCR_0m_MnIwp0 z1QPdei&~g3T>^o0wVzTrms^)(^@jxK{DyquY+{BOgf(=&5wo3q%+Ei zu9!$NR3?pR%R>rB6m4KKOyEzh06=h!G_Z(tv;@1+-hfu#6)64^#ITk0Vx-LyTb2f8 z&k0{+x5G+#StM$Hjs&kQc9F>vN%ikR90@{ui(2e1no!jaanfEfrNi;6*lWHgiN#xzsKAOqh$IDArQw4G5Z-~&nU5_|IV=+1#Gz)aLmUXAdNDx}$ zO;$<9?Wm^T1la7osK%6?Bt19Hz168BQK^}*hKkLd>%A60q-8L8_XcSt7$JeDcMd(W zAXC>fz?^+{qQ0*a9GtM7dozc0o{C41W;2OgwG0u$Z);I$bz!j3jPfOO1z8<~zU z(=);MCWIo$AkPDT1y3wslTSbl;fdA66YIbei!O;LlF@q_OW3&tdDJs(E89VL%8YR> z==@Ez23w`DHwp;@jT-|;BCM+#KFlXRAjSS^Lttye$b61$|2rtkpOgZ7ia7Etw&Y_q zb^fz;1vC>kVnNZ2d3$3j@s*8GT5rV_zm5c9tClp=G3#(*?+F_h=8cW1*@%+SMH@s} zq;zJWeUU84ORz%^k^?Y*(uEmxv-6XwENck(M?oM30Y8;(#2wfm5e_4BL`xju=%IZB z+UaMvkdKLcNe*ZXK2)9VwUe<8MHeh+@w0mC8Lzx;|UAiW_!{tdqS(u-(V zxx9b~WlcA|_*+s*IBeP$116lk*PoPltrjK>9{T{GCnELxNKM1b0ePX4elyZ5D$!-8 zxpVGx_K}PYyVdj8LLt$#+r&yLW`NT2Ze-^P5=;Q}768fBrBnuI5!~HyEBdw{u4BGS z(Bl=KceqcEX`9}F(zhgSRVwjwust8sj)@`>4j+Ll)H{kHZsH3awvhrgQFSBb=U71o zvHazJNwL>%iPp63Z%Vv|z4`nS`zCeJ11mB>T_SLJ0~44d7OB@PofJ#Xx%?NLlTCX} zInaGCo}V#tM)PIB-$ju)${QvAmqwlM8nX`Lg8&~HcyJrF$c5njs zh1sN1#uE6-;Y;2992wuX%f zw>T>bbm9FzD32RXPR9bu+_EIfpY*5cG?jE-;ZIs=&}wk00ybc0ehc0GO*-ZPu1mau zxUU%#1e$yPk|l89Tsb_&1z`1$KQ@IejyWZ=NZ&#vWKQxWUjvHbsK=-V_Vf17(VoW_ z;wX#gIfo840XIP;bkvu2=X^$7#Yo~4kp{B-FHbXku$&6x9?*7<(00H?YEUQTt2R+n z0%zkwdMUN7@2jNOK!^}Ahb2v*UrbXmmIdo&9Ajr2fw3-*5~}WQa9~vTgP$qYJuqT* z!9*`<+*Y}07(I|~80vHqbs}x7Q??c(>UEB{aX(rXZJgv!dh8mt#1@p8s&}W-%v3wx z%x|(5+{MyBg|Y#f0j!ayg*Wn#5ks^#o}Y;2Hb zdm;1W$00w*X~_Niy)%$EDl=?7ZXC8A>mLiR$E!4Tgp%+@>+xR@xecnvv&{30)MFv? zzF0lJ_V2^B$M4sN*8_(;ECfi!X?s}#j>^K zZUdNFzO`kk9`6DW{EV|B)t)3orAk7D(UML4j61qn`^ z)A^#X3UN^Ty>$hwgw$`7`ITMEIDhuy0@i~+!iq`Sod?y7-i5fF$m%&iipkghVQYzT zFO|%1Y3`6#xYKd?#F1D(FV3l3RBvH8n4@~rg6kk0^2gHHI5Y+#a-_&q>;_ml7QnD<~OjV zg~_n!n9__S_2=W9v3s;}zPrpDQ+VjcdphR%7GnWhgdnI|IC_;VT%CTbl|~mrvyTED z(~-n?^-{_9mS$12*^~34(K#j|deKIF`bO>1UJYfYjQ1d^04>r+OO}aAU%u1{uF{sF zFIBe>@sMh9oL=tYytD#iLm3mYL^H zcaC19L-VSwyQF2p5}F>7hSnLuC1Q$d+79#KFp^jP2?X@mbntK!vS?-6zSzy1Ifa_} zrZUUiX-wWC3T88={@M=MStd{DyjXVQXg7z&PJyGvU-rt3T%Js=$D2!ycyhFPHEZ)- z$<*dTBW<9}f9V3lGH-Psb;2O@BT2yUg0QjHSsa?){? z6yGCwW|W~H)=|tQSVJ|N=htmC&z%SHujukeKl%X$+_tgQJ>Pc+a8sIEO=R+}!!5SA zV&MrI!P;Ldzqg{_&x0Kq1k*PSC3ytAcd3+cXb`>V5G9_~IOAO$b#IB8#3<%Lg=Pj% z8$z4>U-oS)@!&Aoo*$AN0BRXnQ{s5SQs4wA@K8Sqnazk4H|Yn63th-E=*jA>h@5?p z2o5QhN-?d#W=FGmf_|fU9I%PQ)8~Or3Rtwq+%Z2c1ej8zP~N2I+hy5G&H<4>Sxjpo z9K`#WmFlxmObz)=o^%%Xcc6HUzD>*HP?CH4!J^!b1Y%L6>uvquP_gx;{W+iB(UO3D zX(;5rYhu>Vt+}TKR~!hrSzmu1Eb1818ZK9;KcDCr4Mx9lyl;v%cW-SPIFvIE9D{Ao zP(M$!V$q@XptoD0Zs+#yrj%^eOZ=(MLS2s$YNtPG(v^%kJp$%br*SwqdA_{})5HLI zHXfpqhmfeD8CM(zylsD;o+NPm7ZjHYBrxE?xjnJ-iR;8ysX+kXS~a{F>eG?)QI(uo|~(2 zj>d8R$?z3RaM=dzO;9iM=nZb zMiJ+Ma%#pk$HS>M^+sENuIs$kImmZDAY}CT^k?58+>~J5aX?;-!CB%G%Zzu?*CCUJ zwHWLUl+pp@?R5BC{*dBy@m1%C<7i4R-w)RBeE?lNqYd12s)-h{PkO1j>Pycp`0Q-Y z)$Y`2o%!4X7|5q9AnH*I){UWT`9H(_|3#dD&F$}KnXt%Ka)e!A+KOukthonkSG~%{ zXkn|q%ys^1$1Qj!I+Lv}Vzd>UUMQP8(HSRfJ;a63O5#mW<-e`582=X$X80IQTPvDP8w**6q z)Ps+|LrDcXuao52N(Qro$rjxmkgq{Vft?zXuhBLn)A==hY10qouGdi8BSp57V^D#% zNHVNsTyQ4K->Kk;{SG>gg4lmT22F_l6W-?Bw3~lGm^}c874!0z1@}F}P|9aq%<>HE zz~U;aQM3Xu+FIrS(-RJ0_&k$iqWfK*K}u5tv=V{uWO=%h-*lEA;oJKJB3Q`2$trxj z7%gll#5)h0w+C+%USDx$ZuZe7lKD(J*~kSW$T4qxK6NwFnOh#gwE-QDY%&jjtx4K_ zwhQ?=C(An@>i17emfa5qwzIpx0`Yyc#}**w#{R>wLhchs6T(y77^ zpJwFOnWydd znOXj%Lu1)^d0+i&tW~0&I694eKU>R_skG_MD~M#vJ)eR{Ym8vq|itXvC&1v{`HID?!FO+ToP-3t=7 zcFP#cMU7)ECN5YIg2zhd?`%m}l$YCGyUfIRE!LK0u5(vAa`8-bPJ#%HwESzY!2CJc znE=(Feb}!->0oJ+O_HrzOvVIT%k9xvHq!*wWnUQ`s=jgDN_I>hi57`ym++AOy6X1a>k?^y(^H;b6iT5QTc zB~BA%b#q1j5kxM8UksLXyce=soFT<2^wcQFX!&XE(fN+aV=z2GY;u^i7BkU+kiz53 z!a9d<_Yh?X^$N&ytMy!#E1g$#DATAgw6(^{;|?h$j>?VZa2YY+8SUoJi!sHtd$0E9KJPuB$LyO1}C(pJbqN^kwJ#C-tc^I+T z*>59Bx`~ot|Vaxye z#^K68W>EQ`!st0-`E!OUf65mvKa-;yOu~*+<8ir5iW?V*gPvaM{pYEFI?|}cSP08l&dbYR$20&zW8_aUQ2@6c zDG%&*v)hNTM7syKHEk!(j=#q-ix*Qo>P1S%#ZYrFk%=`76IZFer(n{|vlctdo!&FI zquR=?OQ#mXyEcO~epb>7`zn!!RQju@aZShWJkt4Y!#j4(w{dyWd}Ovg8{u>h)O8(9 z^#(Vw!{oDgwo6QD4M|1H!-=G!2`B}zHz4(3(Lg8)hy8{Cte{MI9J~Fl1(Tjbm%u%X zc$Nw2xMMB7w@j!#G^b1y9&?uopH7*IeBdjW3HM~4Xrb>LGLPadG(vlXLb^T?-v6Xb zSpE@0b_?ISf%zUy8jW;kgcWH|vGh0Gbk$RorU&y3KuRlz3#U-Ul-Q2}%a)SZkC(Ok z7;cb9&Xpa2l@?1WzWE-<&8#xPmvlFSF{)`lQ#Mq>>i=6~#vZ^*22aH(;Uhk51v~SF|C#7k+K{?N{KVV)wp@-@6E-N_p@@ zc(77vp&v8QE0Vs?-ujaOne>?i@E|ADsrIcoWy1N)NvI^K<{#eEV6tVKoY$ZfiE9zf zEXBTzFxiN4&L^t(%TZ_@4}FG0r&H*4Wr6$c#9Tf7WiVFUd*qPx}(r;0+@F-ex#IS<$)6Qw!>b$4#jF?oaOZ z?EX|gWjn?FRG-;^_paloUz+lq@{xH1K7g=Z=3B#}-3v$e_Ksc0k8R%%0Ey326_NOl zc<(yC_m@E$KK@;WhIji4-a^p!*v%|%LF?{wfp*@6v`H^A{}r)Y=<>nhT!vk@*7(_1)XO`{=#L@jl4D58Zom_tApC?moKW zeV}p5_ZWl~ZSdvq; zXnJ?o9-On=do<~5l;&J|>+bIJnct>>^B_jL=Y`RS^Lo@I@%@dA9;c!h@)igUL*Vl6 z8=yam-NR%51Hj~O4vf7CWcd<;9W(H;i9U!vx8j4bI?#L@rLrNF4;NS)QL+H8hvngs zfG-~dxN}SDNNGLPi*YsdyKF-zt}VfKjB>au)VZOvjD-nXd0=Q5gKT&hzaULTY+Xp(S+Z^w99mffH&v7l>%s(E}zP;VD>sU;Dx5;%ZN_)`c!FQ`EUMa=E z`U_jTx09MOu2zs*(@01{P|PVFfR0en#M{r`$KAeh}~N8nmZZ5fTWL?Z%iqtJ{n@EqUWEu$ULnrKJQ zvDhKnGNqGKnffkE=>)3U_N(rAC0u=%#q;nneA|7$`YuyGRJY_ot7CGDeIYatn!ESP z0779|%X2K5=S%VY{)KLkNt#CE7Kkv^m>zF3qVjmce?#<)DY$OC8+++xDJoG0{E-o5 zz}(w-oDPbgwh+YtwZ^y7d|3Ez%)A2yQR7oQH)Z5#9am=(wVkvAU5<(EOYf^69+DI3ST@nHEBU*7R=BeYh^TOdX-2AlsJ=9 z;?klHsYgG zmjVfyLc&|+9;D;3))A2@i z9arRbI7Z<#a$-$E4>Zd7A#l%03WU^wGs2*u4p^}# z%(g+OXrymo6r5xSQ5ndnLogF(ANa=-1e#%z(hP}c1}#|FHfn;lZAKIbPx=l`&Dclp zLR0`9m3nC_dT9u|M@7(5y#G-j(DNqDKFB(m8PZxE?*WV}r?i?{mMA@el`7B^SVdS* zXayakC%_t?2jo$Nre$5hl+sGKHyA)bxV^!MS0b)`GwCLlz@I@J$rhpze}RVG#XoGOT}=@4e|ky3O`!#+(1j!`nfHSO>Rc!8>` zq}YAONu3+-!Y)cStcydEM)uh^BRbSdmVPT5X9$jBgYX$IZQt#MFbO-ju;NYzUra3z zMTvstJZ`IpPd~2U$eYw>OF5l~gNq4byBo_Lzc&wrgiVtBMmbkQ`#^v;kEL;M-BomA zTWe_=3kO7BIAqf1O(BwN_N4aCcjLbCEz!Pf$aQLdFS)cnJ-PblpAt5FjKZ0=#E?yc z?YLP*lhGl)b?CUMxhLZ-Q%bjQrlolijE-MnYQAq2`0R!G(ZUn2A)0aCpM`JIxkA&t z9>Mhsd+F0@ZRG-l^0n@lMBJqRG9d zF}a3rhHz+2O;?_M$0{9U#{=Jx*J1OSwvKRCv{Rl1Z4Gv6gbbG5OkzPCb7gxvIA8dG zZ%b#8JY2OK{oh{)1KBgw-7@FCGC-cM+Kt`{Jg^l8I@G@NVH}rF*N7^{1>)1vES0PSSL@)q6T%FQw>We&;TyB zES|g*)racbVqMcC2C_g2Au{o=VN_%XupU+Cw1DZ7Vy+-G(v6>7@cp2X_M;)628*U% zqu!j5Eo>#@O)ZP+$tuWX7`cF0=X&T2!2pH{77Sux3&VH4@JhGu8&+v!4wCwyi3fd5 z%r*|z&JbQ{Mf?ks0`c|2D=@>WoXMV`^PvYH^g)-8C8dpmY&wuvO;ik6P)4LD+g~LG z*&@tfEDH#$W9g%s@3q1}21NME8AVL6nb>jw1}@)`ebBpi8R-H;Rd>VQI)m$6 z^ka#xb6V$>QtXor(Hh@0DYg;sro_j{HD3PutpRm{Z_ZXXNy82_q8JK&2kedkzJbnd z;t-Q`#Gmy0kD{RlX%wE>gF52AlcNp@{P)SPW7k6d#~gs|$AHLphZoCEsQ<#it@B2C z&P`-u)G<^3D|)eQiW<> z58Eb}aXMs#x_CbfsSECK!3GcN;!pDa4Tb>I!z=S5ipDFm3PG$g$-`9UcZiD0SibsY zRt9Zjk;ddn81zUnUwypozCmhSVj5Cf)+A z$P>aV^Ih~nUYWZQ#3~arOl3ABDk?MkORbFBUumb@2p1{3AVC;b5th-<(`1&;h+rdc^N=RNRUT)oQ+Tk6IRg(rv6b2 zs6aD=w@VC6A(h^w*q+1C7rP2kFjaK*U%)*x7(}zoEsM2y;{k^pFlYM)&G9IE9XN3pAZ^z7pzReNf29bqR7lRFkD1-&keAK4>z7d_`=1GRIS0~>atAavg6Kd!|a=Y2%!E3p5c z_#YL}eJ|1F(G5tfmXL=o6j3!)(XCWZ2W4@mdpfb>#4(Iy+ib+T`6dx{eO33>G%}<$dM!C)e)MIz!-kwEe!_Bo@ZW}Py zhVIOPxqO;^(er+<8=J4aVtM&KZhoxMWi5WBu-Pulo{zO zi=7ByXSQf^%CtJF<=0_T&^L?nhJ=%{#|>DZ4oaV{&<74gqr3+B575)%8gvCikc`?L zhkYyKD`Zt+ZT9Wb;o9toIlRrbV6Hl%zL0L-5N-AeTDz&>3$&S1e)T>UC~)Hl6KMLv zUA%ih;pV81y2$wQOXwmUNEPTJuM!A!k=Ft4W%{Nr^5kDw7x{%h>EtnDm!&Moz$U&C z!sIK;036U&!UR!{MMTk+f)OKBooRnC4g@pXvGmu-Kb}c!nrSj|#azhs#*?kAD_twG zR&=d|z8y()Tq|`N*OFvEPjwDGkejF+Mzd-EewQ_w6tS9UmY}1FLX&ASe(6t`CIrYA z)1hql6N{LK2wsX(u`s2ramOjUg^zJUQCjd7Fh5Z`EtX_1q%T){GOpA6Ol+C;v6%ZA zKLI96Y;L%KT}A^{Lzt69OX#n|;GVd20(_+oVTU*Il<@1N6P%ww8?mn|HOg5)krt#7 z&f0ap-|Q#=W?GiKB%7gWM(ga+^6v~(VHl=$JF;A2GP64=2|G3mSZcaFS@P{z3?py0 z?l!;=@O}u)icQzhRejgOgI3%$0+X^L#$My+CIp2fXiboVEXWybSG4^YD(c|22d;(0 zB@?7YK@=pi6~NuT?Ok_^!?v?9Y*-o8u%JTNP}hp%sQ@ zabZLh?9324`dXtMvCwn$jz?94cn9r+P9|;K9{Hq&nZfI8Tj*E{HQ6@l5JdDO zpy%kXKL%O0ihOKQ!q%p_gP}ZCFSW5Eb@C!0T4!HdND0DNLU=Kl+q(}fh%aHsnepD8 z{Cj)-RH%F}xq&E-?ayIDgi!=Y13UUCm?gdyMNz2&6^-sexUK7Uf}^XG@`^A^}EI@@K& z-eAg~%<*mJ+*YA+GpLw&)iFKxzJM*Fx3{r1Pepc1ot#=(VOdajYP1@J{i4(;CFDr_ zyNpH!^ARLVBN}z2BY0rSb;>JC(F7n2(VsxF@3GXfN zW@uKLjiJ{U#{-{6ptKK7i~56^P>Y&aL%@NC;`|$R;h2*do=E`K_?~LojROwuwN9UMeZ0vhjV3S{YZW^YjC(inovs0SJ z#&fW#E9`iGOl_Qe4Ga3zH{aOT9_6@_yyI#GKK+YkVHbP`ghe~9rm*jx35Q3Ov)Ty0CW8vU)E} z{`DdQVP-XO8~fLrFhiuxM9ary>EJX&I~&7H5=kiJF_5)Od4;qV6A52N1-H-vho!R7wf^yF=Qzo-)75(d;m(&`9oi<#PP1ewWCj5V5X4MK4GX1JWV90v zm`}b2`3{o8?_10yk#k@?6Ei{N3Y(-nPw4>O4^&CZR#EgUmU}v$P^6ZB4dr1Ut=$*0 z8Kx~&WHphOVBbeAao)$Y757W@aUuP8sa-$ewu%(ozj=K>6_k3S#BqNEEinGI zxM%cElO6o&G-5o&dXQo;5>TX5G+*;xNxrOb0bkzyY<{W7+=E1*v7=UDQynG_Xjbu) zrWl-N)N7I{X-WqgCkEn&1k9dhW$zWDxXSun_*dr{*QG;>$U6|sePH)i!>sCjj-I!=qks=WOn$* zw2?L{r&DZTG6wIEfdKYVX-BnAeg#rOA$^aK&PT%4m)M0BTzvG6OR8gCXdSyk>R5$3 zb_mP&qTh*b)DiFeZSBS_ypAspsw3;aN*(cy)4PM}2tj{7tLbLc7;#W9s%gI5GbvEh zBD6!@CDwGvy)SO6y`L_3@RF%^T%F5IwZEIw@6T;(DTsPB8iH>W#fW8Wz!E!lK}xZ; z0+Ees$^8w+%Hga>VL91-40w%1Web~|7drGEZ6jq|Jxr@iS|m33)L40e1(*kkU1J?5YxYS*z-kfqB@ zuR@tJj?vwVyl>)8M2swlBCi&ibuiiUy6a(`3zM6df|DEU+{EfK z)xmZuZjgMOCOGY2F3VoPq0}GY1S}dF$JO^%w1+r!>j^9kGt$2U%>3-M?}+@ ztK_{5#|xOMn6b42FN1s#a|i};pL_=5Fiew@AnC&}ng+4vGz>PD9|_BklH@;KNPk;; zn{hV-CZ|8Y1&fl2_;?N7bg1@qx75o+8BY;0UHkk;2>wv$}gunJ_9Dh`|0RDi)M|!^;Bm(8wo;!`5Qry!g zdFJXINq(r~#J;>1=9XPxSMi%<17rPUh*QuYG8{Zcie@`euj5w}V*K)^b`F=!%(FG=3#93EIk;tWs z3-LB$Nqr5Du{!Gr!8jRsL+nXZ5{}sW)sEeNP(zqz^HxbZc%^fU?2Vy{xpf)2X?)z@}1eRe$LroVWsO)afkXW14;$X@&YcGj=begLsX?ciWlbM1H`G#TVyYm&fV8{MdBP zmH01aDvFK)%|bbE!&fzDZojA5gDX`3LgBgUU9cjInk$=&nCHA>l1^tI+=&UcyXh-2 zqGZuG!PMv0I}*vU^C^V8#F!{}MJrxUbFXN4MJZkot5U2Oc*Q7QFv&z-I(X?6 zFEl=R>A^1X(}K1~dwOHec4eEO$gH1DiYaQq7@XKr0(1ic;&3KG35XdG5U+JB{?YIU zbb;E0m6 z0iJcM!n3YbcouFi^5D)70-@9TX0Q*#1@4aaUB%t7RZZbhJ`8pEF#MBV4e$H0TjhB_ zw!tt}a{x~*HQ^J1-PDlBt!7i#~$&z@Ri9je7y9gQ&7X7sR zB6>+B;){B3S>vu#3%J^-wB$k+3D~$R17KghqUip>M)3zT@aSnt#XBH&ji@KS7Fe z^=h$ghc(<(dW@xYT)Nm0uPMSrY%0Y`#3N%Ytc~D%EPW>ebqy*0AK@$+VFh{SUO zxw_6pIg)UFD-gRbS>8OJ6k4Yvxi4ORnmMKsEZ3l25hkYu*T>yAc-{kBw4wwK^kF_G zAr%+~$=)wCG~9Fbjs+&zg>6Z^wvtao&7jHg|)7?g=tUQUyxSF)rwS^gqf(wi)@WSP}u`4Gh4WH}{S z<}_LU-t<71e0VY{-;&oQ--0?}T1`UPm!J}W0mgF5_ivYvZe`zAPK7K_>T#V|D1U+t zT}&*o?g$7_2uB09!QX+|bon$%(@tTK&B0~b-3@ymulM^?I#NE3KY$@NtA4>6tPnJg zv_6l~VUV9ed41FN#1@bzhVU%cv7K@~JV^%Y!y&|-at*n#I}O1c(KRFKkr%gteP_8C z!xKoTF(?Z1ly7xZrR$qte&O${QP{_87CGnyP1E-+crNUV_ zEO|TGD+cU2V(#v>*NHIhS?zaBENi;vb?N|3>t^k_oz!`-VDdf)1_@)lrq}WjQr5KM zwhQd6g|%rEY~T{=^O;f};h)Gh3x*?CjNAqRBwxY@8?W>AOkz$#iFRWTosYp98x*$M z!0c-S>8CB(eJ1GwNhb7UkA*HY`~}zn?9|StmdFfTO2Qie`js{u1_RpJO&@#ZE3j)p z=YG6cNN6lMUr&cg7j%|($R)@M&1xJ{NS4HehI3?X)0s+%i&(>vj#Lpe&uNB>SZ~VT zM+Pt3w%{-YhQ)7~#gpSkp(xKmokQ6024eY>VqYh{%WpW;>lNs%66$-i?-d-) zA(L#Yafdr{yw2p`YstxSOvgzYJ=Ft498CSr`O12_e4avHr}u`vzCT(ru%ER!IZy(N z)BzamI0q^(KM|`G!TA+mGnG!Q*;v#A6`JQf>%AGRV@ByYetGfP9bmFGkXo-?aX=;Z z#!_>_tPZFN)Lnr|oC}9@unq7f)z#9t9g3bV_Fx^Tg_tA*r2l0pO|Vvc~X1^?^Xp?#6Ir z$qBC$X${2+dJR>{5UA24Q$nf)S%O=cZ(FkXbo)K5>PFPHd;W?c>h}cm5^*DI3V5Q zhJ!-m_u!3zVLJ&Bu(XFd(6b&a+4Rm-fJxB0F^5UmaPZ;Lw7*9l2mO2d%&BAbj=x~P zNhiQW``8^HW6PY%j|gL#z<{0drxW+&!>Xd&@$pW!nQq2p0+4BGMs?=s+R?iZ5C+7@ zIWnA618gJ%`Vh~Ss)xw|;FW!Yu>(O0l+g57Hh3>+nfL;^n3{$#U4C&!I6^2dFvBrr z?vZ2Cs7#rZr`lXR&UV(c)EE?z`6a_f1q>CSl^JS=YUQEQA{9@*opLGDc8>sqs=(p! za$?fw@ft`0>(t}89Tlguw}DPHZOq5dd`4|UkJGf7w)Hnk`-k+zgQ^VsuF_WTNa-p!uN*mF61 z-pii%v*!csS;(Hn>{-H|cJ^Gwp5^TM5PPm+&nou(I(yc#r;|O`vFF3=`3QTiXV1sk zvw=Nb?74wGpJ2}>_LSJOg*~5Q&wpdjr`huv_I#E-zt5gOWY2$R&mXbpkJgL4zRI3|V9%ZG>0!?{_T0^$?d-XiJ@>Ka z8|-<2J-gZS5PQDGo`>1<2zwr7&p)&0d+d3PJx{RbU)l2m_Vlu+k3BzP&yVp08Q{o8 zOQLk*tRJ@csgE%CBVq1`!rb?VxtE5ybHm&jK{xie=SE?^*<#gU_V0pO{J*PRQ(4oU zjTKj-3qa-wlWCxBxd*~Cx>r|&%>b~L*k^8sU<2ny@bV{}I*vma6F=Dme;Dh_w@oL(uG-rBaN*mZd4wmHYa5??hwnQUCXCIRXWb$}1hR|CW%gaGtndeK@8 z#|58424Z{cEO^l$^A40atRD^GWaFr!g&lk7HXKBznuxjWj#?^fIdWT86orZ`{4Mgq z9xFU?@6~%g?93p{DeZKxL9jHE-YLaC&1``GVJdZj6&fo(mgjOSg>7qjbutN=XTY^;e?d7 zmAXJ`t}sW?~{^ zq$TUESZ2{Tqyg;w98MuixOo3H0`r-j>>JtrXx73QAf0r1I{W!VV6V^SJ*OIo1;w|WAyC)7;lvGba-#% zv|JMV+MkJnr#y@o#L3c;x!+CxJBs7D!z?u>6ZP7(Z6?V`lZ#xaJ=?TU6X|S@68)Y= zxAUwuqcaccA^yFl<|r%k>dVX6XZ7#J9Wc&06trQl^J**RFknL<;MO)1%9Ru4Oh9Za z-ED)ieF*u$82qAP6zPvvm)qd`_D~od+D|Mo%~yu9{g7n0kq}0}wrg`V<$_`Y16Jzx ze-mDb5?+bR2+IPqXl#tX?$KrhpAb!cw-Ej z#4Wl`MmbN3(i{GyykFrOgQm$h%d4?-&jwhg#G#%QMbAV(z8qbS&=v{uMmG4p`WWyc zKMTQwQo)5%K>|dMEwKV>hr4R%NYvc;F!F7gv(JYUVTVW|;-|!pTx~kK9OpwER3^ru z7WEQ_Gb#@kl@hNuEDP+hGpRXl(>)I1ogAG6o^@LcM%lV|&H~MAbt3q$bVq_sdq%oL zZ_{>~rOFASwiAo_UUY?%c*~@#=CYsCNMFS%ElYmYDEcqW0h_mgQtnJG+YutRt#`a4Zy}hwu09NVNJn5f#8Rx7Xzt$q5{bSBy zsj|>@3aXr4jtPs%-IDmnBW&UZkUc)#B4KOHITF!Ju|H|S^%qBpkfuTxV+-9v-F^h@ zh0QO74J2DctVa=xE}P%*V=5{UKShQXfj{Z{EH;s%vjW=$WJE6epg$?@7X*ZPFY_lQ zzy&csAe~u`IY|(J)}K@m1dtJ^wI3R5O06FY)cUIorbYH9vQo8MpBRM+ixYM$a3k$Y zEHL)qlZ4Cly_CllR7j@(<4-!%qg3jsu;GWO#M}obIA+a#aI#~DSaSRPhWR=97K}_+ zOLX7R328pDx-~r@`;!cSE+1w? zZyS?$Kn9g#m1>QULy3?>saxllD~}58oBy}JZQ#+E1mQ{}NJ!W$h|hpr?quA%!6!iZ z3AWsWm;i}7ZKo}_yJjq#0J+r(PzX03TpPxFlsWei7{B_jx6w<$LdM20Wr*ow#(N4= zIRy0xY7Id$rh4S5XS-kwEO_X2IJUAa?>?-x=SDdV%4pNT>1^Egcy!&exneSwHzN78haCeMj9Hv;%(8keO@OAkwA5d+XKI7+8$x{$IKwnXBYnp(~1`OJH*+*@d zDJ9!7y7GiYhwL_KavIiZn!MaYwO5wmw2|giUdsE0pm!>}^$mWMN{R3Nk@ zppR58;;mTd9&|2*DGkh@x<%LVQ#iqA0?JT%6VN6&qJb7SR7srUMOUkyaH9Buf<6*n z!=`_0n`?m_6|IRDT1Wv6Es-Zd*S%M;0-V(0Ii`a^T&ToBOo-3X0wLgmS%QyX-WV|C z%6(t}7ymn)nZh5?4nRp&t5w^%;h;^h?6smC6faJVjNrpvSiT&RJZF1SJpPW9E+h-a z2SQB3>zdqFLXW9FN8|VqGh9f>1?LASEwu_j%`4FuYZGlHd-Jp%iqo-+Xu)^<66o(z zqmUXo=9jdqfR!Fv05c}qum#_O)_^~0^G`8T87Kwur`5vKpXOxGb?o`lX7VBbOU*bE zFM@#x1|k@UU?75l2nHe;h+rUsfd~d77>HmXf`JGIA{dBZAcBDi1|k@UU?75l2nHe; zh+rUsfd~d77>HmXf`JGIA{dBZAcBDi1|k@UU?75l2nHe;h+rUsfd~d77>HmXf`JGI zA{dBZAcBDi1|k@UU?75l2nHe;xMU0j&oBFXhe{L@o_5`{kpquI;V9x4!9WB95e!5y z5WzqM0}%{FFc85&1OpKaL@*G+!2ezhh%Ls726qm*+k@_Oa&HZ~jpTm) zStUN%Vxqf)4Y(x})+@7Q@wK!5O`>uII4pC)vfo7vD60A2^#=u>)SM6aFm0CXZT{6@ z>uq8nJj)xu=VIZaSF4mcwDpiai^~6sJCGl_kzcj<(0>dGkA*jQHc_%I;Zab2hM(`C z)|8J5|Eoj5uMJNej4vwiAN@gC5mb1ihJcqcGCWOq6cyepI|r1P*Z<$cG9O&NE#XlV zcqsoC!q28b;R=3gUJc}Dq=+{M^CvgU|L*X_JbxCh;3q3Q3i4ONS^oM#;VmrO>;0XQ zzv4a;=05y{ zMT3!Ti&1%tFwlp~c(OFscDi&Mx2#Mx!}zY>y{LXZ49E7-Z5u7%AHElee@J--(1Zwc zwpqAW+%W~_TVYCny{H$Sb~n03!LlsNCRvQ~A9(C#qUbu$!yGr0;cajtvEe-3Y)}J0 ztut(rso$E>A-0(MMOXjSb+J~d!#7I)uOFit@@Q1<(peU$^3wlQ{&4%#1M$CdTfj{S z^4=A6*ONQ`4}oyzzC~dSfM=xe>B0ESeMQi1pz!E0_nEB$cr5(5;%4{06Ys_~f-uMm zgM^7Ldlqi$%rnYu--iv)F!rs|(?c%?;4ymm%?`z_(nA&-4_Y>(F!D{WgyT1BxFLbr z_6r$L408YP!xN7%o)jTVZ~K-&`MSt`_PKzYg})FC-$LPsmGA&Qc2F{)Azk*O^xP^Bfu-7@@#!MP=8A3{XiYRTbfz; zv%&B!6yC0c2k~(V-V7f{&>$DXM>VCtJqWLt-0On*vG5tea5sf74+|e145up(ytfQ0 zkBnp}PmXN8l=7VYUZDQ@l-~zI_ZD&=4!T+Sq#(az?yX_rF9hAal>S-Ot;{c;;O+qW zn)8edXWo|;M!tW4NSHx>4&Iv-tOf#jivLzfL8Uns%)3{V#Oz?Eqth918EN+Kaqqfh zsg{xbDossC`)t_El9*9GspUC*+oTPf z$V+-=BYTaJr@eO8FOMTAuA*uU1`IOi%*-yM=;8x`D@N7&5B(mZ(0};Nu!a5!1)2lwbAeeTG0qD@+;#uH7{ZjECBxe+|z}AA)(ldltIrI8+LDFWV#p*|0w-I=A ztv6_#^F-<2DY9bQIm7h`DwQTJHe^zbT>a7Ol0|80x?BpjfH5lmH@M$vHM ze}FdKNKUnq_b@m5Ta%c6Sv3ghl4291b=(YSFiRUat9hoMYBPGc+KBQin6m|HLyV-QnTF+=csGp>X#;q zfp>wh=|-TSp>UrX3T{ZgRYQj7iJ~-y7pzPgqF~^tfe4n7BBYKKK|4}}#H@6cos>vBV1)YN?U}WA_!-}5O8RG4s?h)8wXbd z^Nr_F5*1PBLIgkoObr0?@e>1q@M#rtp-Gdsd+5*tc^d)-POJjp*=2Ve72gPE9}Es6 z`u>Xt&mSVVp2o`QVhN$aBYOHr;r5))&M1xR*g~--VXr8~wAPn)JU36uz|xP%MLA~`Bj1A)P+=mL$tDJW(doYeaZ74G1$HwK1b&VXrYkYVJ6!KHAl zOgVc0ZD3lZ=_n9QcjdR#OoP-F3i+Nu;$ZmpV1;&KViJlAUa%-WTXrNgHmXf`JGIA{dBZAcBDi1|k@UU?75l2nHe; zh+rUsfiH*w$bBMz|2r|T>Cc*a+JBAwMKBP-z{nVgi5oqjzkKz^f&Hgw!a(=P5F;@n z82JA$2JB(|=k}CH{|Tjr4>BY82*pR_JA#1-1}+~1b`$3#Gj8DT?MVaqinH>e%Bpph z276tJz1mS;RjFk0^!S14-cKEvZpXxnhp#LyH5Av>6hCaJw68N%*eh2#R)?0p)=^Vl zxyscSJ^A=HRUA%_sPXP-_g_gJG?&Mx|RETCi8dl9RA)ipTB>t z)a$2LarfE`{!W|C-+_#jkILfe^1@YiM`1;At)tLhQ&Uw_SYBCHrN*<6&%Ake*w=9% z7Qei|%)qbx@a)`W($QY#^IR+bjewcldToHKWJcIKSYl_i;TZz{EC=FFX4 zva;;vn{S$%W6xv>zFJ%nfTkG$uWIGj>?IB!sMMdm$cN=yYA-9Vv=>&_R8`w+9Od@f zAfV84)!57IHTKF9doWnD#$H=nyejC!<5yJG+6z|$WfiDx37`g2h|KeD@|!pBu@ILM zBP6}OwxqbacqKp#0m-5UhJXOTp}Yfm)5lkpaXOsdjw}6RnnGudGcJwZMo;1K!r@(U zE%#rkz)Mo{9f^MXlzCM+Jgb?*n>>%dpHJol?rj9eX5IVYu8oPl&Xz(mr8T<@40o}ynss$9`vTe zOrd}I#Wlri><)X4VMeXJW^H+ieTHF;v({l)X*U!bcuyQAz7q*5k@%tsLg1@Kzi520 zru@(<)`q!D?G-5PfGDhZ=%A&czT{q9V=uK=I?9VHf*sa8Z$+2L`F$Q8_+#U=MBLjGwQW!&7c?A%zL{wgD z!GWr329F=TsZj&g=~VRV?R7zhp`;J@H*6fk(rsPH=`1B|oLn}{IQgQI?z_r35}uBY zgB2B3C8$+ka77t%ns|O&l<_%v9M4y+C8aBKR+dmI#{89l4kg_~xkHz;pqayM945S9 z3BOJ0PvPZ#PU7izE8}Z;c+QhNe8n)~9ZLA!3SS9Nzq*B|pEPUe@~ic)v9Ge%@$ojD z4M&9~RTUK&?Pkt1+_Tz_`AT&Sh6;wAs!9il(2fa5B}UA(#TDhH1|FLT2_0Y!s2T(5 z8vFGs_(AU>@^d^~eaX4423sg0u26z`LhT57QRaj5W5d&>X2>I>nrg9vBQZ z&~Ag_R~KV0af$HL8T^@-1)s`)(dG#$|04|k`pbh~TsmSFAp~AiT)E0l6U1V}BcZ)v zm`n%bivhS8zCtn!kePv{nq{bUmaH}u*Bb6$nOXb*m10d5#z4&Fs%WlTdy$GOEjYM5 zwbcRq*4Pc}0KB}i)>&3oUQ$loca42bRn5a-_~_b|YcZ`fI0mwT@=AmiW3Z?!ci1r! zgI5^V6ql?9XBfFSL-a>*;2L{1CfLByot1V&Rhi+sg&B{ql2ukY4B$T{7@|rID<4L- zoa>-g&WhrikoFiZ>%sLesajKAVXrH9JghWI(1Y?uYZN;i_BGWGWXbx8p?DS89?)Kl zju@UVThOuM6;nwwF)zR>Y^}XwxB>-w7XKJrK44VszZY+xQkovE0oo1gR@>1?7^Trt zLlhA+wFUQ%9Gj`{`Zt=9f^CoK_1D)!*=f*;h{XR6g29A5h{hK)KkLP$7E zqWiWoP9+Z4hc zKk!lAl1 zkFH4wbL+$6PY4T74s%Zqa~l-5+8(pQ!k_!?!182;h0h6d=O}Kq{PV-y#xS>8ach}q&t}D~ z;;%z-rz!FK6?dxQPT$YVr-m0O?hGY-lj2t4Z&BO^CA>#*PgmT!H#od>#cfpFs(hnP zaZgghH!E(HA8%3Isc+=@Fz~$~6 z1MX@^&CPQZmj>m8xCeVi>b^r^p|cW#o>dV0usCX{S~1#oq5uOIfU-CX@Vxa_jb{FQ zjb<9Y7rpbA9{{e!_oMhdh#&nGtu1rV z9>omqgnMO}n~%W$MI>shV9Vd~62mHIaZPC;jKSw3>VO~MgC2k-_&Z6Y zs)Q6N0#=4T5-1Id!3$V~y`Excg@ab*DhLR{s%o7zfjaPfQ7o*CM}(*38ww8VdDb?8 zLIYs1e1TktiWZ2+t2q)>f?HnWZ~}v+<+arnkVr7u;hN%V6)*PHhD#}8Q7~Q*bB4i1 z42gG1MJ&Qj*TWYL+J+aBgbm&SeFjLmID0OFnziK$%5{Zs>0%R#pUXb zp30}^FCfkf`nw1G&tQf;yr#T5$i6g&Ma0$?GiiJ<6e2W(Izq7I1LB!TUqQjYl2j}Q z>!~SO{qPW3@cb7uu^nWMcd}h^gAM#Qq#Q-Xl~t7wuc>nKO#vq4RI<=4{^~pf0hu>X zqan#2ZEs{kY{fSiY2*R^h6`Y!8jYeKkx9bybfZq&cScGEmNP__?pfqU}WtxQx z3m237`s=UP+_B7Nqwh2fvB7e%oWe>Ok}ul;39m&+I5tmLSCtNmQ0c6wz=%)TY1USi z^FbZo!F&T*vN-E!7&PmtUTcAD;??%LM<^iRW-hpkOTUKg*{T}VJ%AoVxWQ_B1*QOM z(**NXhtkqwM==SZSJEa=$XFMajuno|p`v-H^uuSXCfAVs8r&h^R);0kqq?SiEy#rv z5Imu4;lP%ty;Sk3cCM@_F9`%|?su$)YRvyCTr-OZ5`VM80t}T^T%3lml4_@>culotmVwuW;UUkY8Cv zRWb3C(kdXyuF7OWSx3oI(cHgNq>cf>u#Q7V4s?0 zcPzc*&gFM-2cE&!LY_pnN{B&iFvVS@l-FP{sdXy7z*$M#t2_dqWpM}JThet_8`Mh~dL5yb72q$-Sd1WD(0QtKd8us?^n|E(m<}M##i)tzOKCU75$k9(*~Aj<99gx z_mutgZz%dfZF(NBPI;^FFXtVoH$I{QfB43~5RX8J@HKG zldTEzy@ButCR1@izPDA>nn>*>G)7qXZ8df<-;lqs@Z0SU=pZ_Sal*py4h^Sv2@SUf zrqzpUFu}&+^KJ}};AfV)kQ{@bv0yE#tc`r9z)kI}{{0{J-UA@2qw61@T^3jnWd&5g zwstHib}ZZr*s!384NDXh6dSI9ibf+E6H%k0vBiqUf}I#m&=`XqjRj3iFdBm;mc*C^ z8}|P>ch2lyR(O*4`=0lEpYQ!=@b0<4IcLtCIaBWJ%-nUE4W18JFPK0V*x-dW7=8=2 zi2NcOyx0bRY=ie|i>BXagH@*d%Uc&4Zk7$UZNE-7e67;@85?xj+I|OtjE*@dl8Hs) zakYd8k#32Kk6iq@QXwNK)@6FO6Eji-)Qu&eJo4`XUj)Qvz@in~$_qI`QQrSl@%pj< ziC!1O8nS3;|H|Zm61N){-vPdlg~g8>2FH(tMqUoon|#`8m*5)d2KgeCRPI7ZZzQ3= zQx2bROP0s{bZ4ygAT|IN-+=y(J;@+noINY{Yl}QL*@2?iMCYt;d-La1A<4fa+NK_l z52AB+t>`@19=D>;ziy=W62&*9bG5(IbGS!&F8>8R7vCfPVw>kKxs)xjvD;{adsBXS z6n~3o2GOfF@BCI z(!W*fHn21!2L=VVYu}+`r;yHFx^@fg-XpAMc(2}l`u2wn@(OWnIz{~pFb#-yxU$Gk5VaqZxeprM#N{> z#7__8<3_ekd_$V&-?fP!Y~=F#>pWkfe-oWwFWFMg>BiczAuNb>gFg%$w_`n&m>|}h zb>M>ZDfqove-@_V@%T_k*BxSegT`=>um;ZW&ib%W;D@u$kgqy$es73JJ`Vw`jdFvZ z0dV0uk}p`ReBp+B)PSe~Pz*!h52#|(Yr(o ziRymk`VB-Y5j7I6Nz{jE1EPLJn-TRV+LmY_(e^|`h=vi3Bszv@B2l4#D&bi~KO(w< zXgbkMqS-{hCz?w%kEofb{x&bK@*DvFdJ^^_>Q6L;Xavz%qDe$kh^`=-PBe>XE>Sa4 zc8BNdNz{j^KhY4P5kzB&CJ{{`x`Jpr(M+P*M01IniR$lCzCvE`(JZ3bMDvIm?(zJ5h>CXnpFn#}h-0DfvOsV6?$ZzUH+#oUU>)N}vR<%i1-$5} z$qe}l1(^iph71S!ICTu9jTZu-!y*d0Cd3o!5*5cf#tdblQSmIu6c2PV>jE}(nJ|V0 zO&Gy?#h6$R*m&(eZX#{MxqAG`&&p0b$n5UYJ`CD*MC}Ux8VF(Rv6dm1Yvc;fi2n~#(5R7;;8G<4g z64H9?*w)sWdoOtU#VH*A5enb9)wnnC72`>!AE0QJd~f(BJwb&#!Z-AhD%^`jF|p=` z(LBFsh~@V1{H&PgmjHPP39gLii{HnK@_7EZDo`{9x5FC8?U(@8S>sT17sy9l-j0yN zP@bjo847$+Hy9BF>lA8?e2de8-^IqCh}GYpf&h%L%>+74chc*w0NhnEM}KX~Bf8ELVR+i$ILZogGCw|@fon_J24 zPXw#R()tY7%gZsYNE~u_d2FRcx!#Tsg6A}bFruMA8$lgL!{=mGi7^KM8ZaYB@IRv^ z1|`+f@FVW<*BWdd3!e$_CqfLg249#x^b!$7@i|l;E?i^5%Z@0nk$A#o4_9fp@Cyun zcX{_@Oq$V$40m?pDl2q+?Q~nUFYCJ{*Q1Wzdtw-&xm<~Q_w&EuHgAQJ>Q7> z6Ad9M@)-sF!xwrj`VGSrWo57(v{N2NL;v$-T@`;?`Mni?l88c#_j!IMqFF?ZfAIKJ zqGqCE9n}8;=cf?OA!_`S$0rjt6Ad%-_za?A9W|S99#Q{%E~mEfU)>j7*L-{Z6-Q0% z<%ux5j|D1LPm5cF#eDusAFk()QR%@|*e3tNz`xQr2I^@Tpj^>_L=Nctl6>}8`cWr7spH^j zq}FF^@n7qi3>KlD;b5=ORI<1KN*`}|@nD_Mg{8E$>aW{ZlHxVqW>FKjs5ni$ii)=j z?GUS>zEH+Qc%CLeJ;Z}e+|p<$^`yVB6>}(FKk6C=Il56yC%)$i`zfK^d=au#z7j~$?*kGqfd()#ftAqqP~RyS7*+EPn;JZUj#fZ121a!QhxqJwHJfWM73N8*f;JqIRU;K;DMSk zF$pA#&tx~D3@B_81;M_~#F&2Y0{gg0Do#;-AlDwwOLQC;5AV*Y^2KMmI$x0M5Qhga zqa%9ZD}){41wc5;Xqh14GukHqZg2pW+YmO+G{MA8uq_YhsKOUmWALj-(`e<)~ z7YL1jT`NT?&YM6FcT4Y)V`IYL6~vJVF+mCFdW_(Ci%*+!p}n>&2R+3RLgesyW{}AgHV#ezO@;J!LMlx z6%TJ$KjHI1LDL8ex{4XK%u;FLf@N;bVc{Y3-bBe&u-8;hhq~WZ4Pcfsx<2dwT&foezwF3XZAo=l8FljzzNnzXBNHTVByWAJ_-we?{Yq zMitX#Ev&DwQo>o07sL-?4Mo?u^g& ze7<+z7hh)XKk(JTuMd5bb@<59W5-XN%szGc+cRg+ozJ;&@w@LY{qSS%<)5xx{rTE2 zdDm~;y!GqtJ9qE>_WS)m9{g#}FL?Oq@sp>8&z`?{`RetX|JNISC2#2ctqs5b@$&zh z8_)lEdH%aMa7*6cRW@+{$IJh3u1{w3^uVWtcz*a4!$W@2zkkCML^H$k_jiv`iYEZl znHuY#R`d7%M0#~u{$6?2Dezuj%=6PtgZlj}91rFJ_dM1B_u>wv{%(o6oUQ!dE3H+^ zz^wQDPNVs^H>rQ2(B#O^{dRzr*ghbaVuLemaIOjmfqWt1?r^>!7_dQa)rV{4K73K`IK_sasp4b$yDENfz@AP#e_>A`VNt$V6-N70RJa@9 z3>8NEb5t11$DFO@!~BgZ+y!um3J(ArtHM~mG!;gB^HjJKU{=biAM3+tg98b7gq3o% zCsu{g-c%LF@?@zn=ATEnJ)FwG^6OoAeuy!>zY1geSQWIFGMdsAU7PlO8N zm+BQN+!1h=3U>f(R$;6UqpMXvw#N_^4h3vdVJy!I6-NJLt1$Z8tisqnJPlU;=r4a2 z#`=#{Vcb(nRpGvXvk3QMeHoVLE@7-s^k1PxzB^OeS6PuC@9%mW3`zc11@yT(cv5+B z=Mi~+ggZg&L;r^m#_ucs0Z=+@56OhPQh!Xd;b+)Lg zgFClRV1L5GpNz_5!Jy;c87kN)i&A#Ua9tmFrTCf#irB^*VO<*cU~u0m!Llp=ww!N? za(pj79yFs4bzYbszB4ff^xJZ{Rk)v2l!GS&Vlg2F#3Ka&$}vBOVO@=~jrWCAxMMK_ z-lO1Ds3@8q_d9Su(WKapdxAwzm%Oc)?=_8pa+*Lh?uiu*w)%0Gif) zJVS&2iiZ*w4MpV>l-)=5xs?%+I$o(UJiihJI>Zid(Y8=j4o3_u5$-qQ{vuM`%e4ku z`MFUDq!dpjQc_c&-3*s84~ zKyh+$(AIc-f=w&Jb26A8?gNj23wP&n$A2iqML|!%GYv(@Q{l-3NQpHe%8tDieZ}`8 z$HzZBi%>MYEr2y7NIyfzIST`i)}{(cqi4ST(}=T z7UZy`y!B%`JmWS2yu{m^$P1}$dcGfyJs$mR4R6bhf$;$Q=on?6_^;%#w)klPUjNn- z^E_2!|eZp^;E4NuK{kFe&tKws|TGCc8 z%2{<<&-1-4hvUcui>kNz*y^zdj06Ak7NH)CZROE_yss2JCuu7;5wzm0VhTv(jOFe6 z!9I?&6`UpU_d(+nxj2Zm2HSB$JO{*6*mhhm`W(0F!5+=WprYd;?_bvbI!t+TV=NC? z3Y^VhUsu~T0`%eeokZ|jNxD%3wmW>|&NjW6Px;!+sL*G4{siX_*ca64)X!!-Ph?ca zdMuCCyBLq}+2Sm(XuP$a@zezN=A!kCqX(YQ;Lq8=dd{o)I49)ZAg2Mb^6}|~PrIUH zjhbIv`nTr`wV}Kv&lm6%2-YvQDfB6pegxd(=%o%t<-{o#9QTU`oZ}2Z#nHO zX9`i0^L;H6J#6?cF5WJVh88*(y|2zr=VCDEE9=!cXb4=b$-n1l3Ev`YNBBNr9pOU4 z_JsAdczQf%fWbi6kwfN5SY&P_>_mJY!gvk^gCF5i95R2xE`$RKj~E-Y#@whaxr)kuFoMe5^g})hp;bUKf;X&`x6%D5dsOfBz_2C(R0EG zw<3N7Veva6k%VR9#}W=CY$6;)IEgT>xnW2q+@3?0LKxR1Fr*U3H4zLe2;-UthBU&s zrivk*a90jl2I206GYR(~oJBZ{a5iCFGsBQWSezfqC5&rw8151l^SeUA(>a^z>hSu7 z_dS)MC#)sxN!X6C4`Cf)aX#9fus`t~1fQ@Y;RwQd!m)&%2#fcNN)b*Xz6;?L!lenX zAY6uUI$>ABnS>35vk8|aEY5wq5fFOCgEJdwFuuO zT$^wq;W~u%b$R*g680oqkFXEn`h@)nHy|8B*q3lD;YNg$2sa^|Lbw^>6@;4;PAA-g za3>`7QA>_a$^us`7-!Xbp)5so0-o^TT3 z4un$(cO<-ma3{j)ggXa|w4Ne3x){!i9u;5Z2e{i;RwPpgkuShCY(fg4B-^QGYGFBOfRvsbiz8CkoeI18~o*Tc-|7b|HM1uz_$PVRyp%2HYPWggptDC+tJmo3KA&FB+?U35$S94^eaSq!s#MC;Y^X9aJESA z!_()A^n~w<^n?qAd;>18_v7VtBJ4@nnXnIGjUSiy7xIKdggoI0A>WM4#|nAENkX1* zijeo`@+$s=UdeH8=llVQO9L<|X*@^HIwl^nwu%6B-~iTeo{Vqwn%1MXsA zhyl$Q#?ty8uE}8-P3iD$KMZ1b7=Jem!)THpP5N*>7Q+P6n@IWNdNc-HKx+yR9l@VCr5DQ7kiWBc)i6Axnj0NWAbaAZQj z_T&rPZX5!h060WB^M+B_zL4LG_}I=6_a=<(%NI_Bi1cw#BE&t2kL}GDRw4x-+Z~oy z_5JcT9gmveIa!a zB}h{IW5u}tq2^=1Q)BFZzR+4l`S@G69WC{T{SnI}>>sO?H`G#IzF%o=AJ}ivKH*R7 zzxckpXz$pM5sUtT{TZ>yANw`dPf7m3{;qCMLzVJd?Za_EZ7+@oYK-GTQOx^`C?Ad! zYW`TIJy`YQ_@UM@HZcyIW7aP z*7SV5u=3*+eb)BC#|J$1$U}nSzh2Noi*N6|zgx#Qb^mCmjKyO}lhB9tXB{7S`wO=C zU)`RHOE3J%PlaNC#QN=EX`lRgkEhyr;Qqtk7vq8ZFUT^!asTl%i73JS*Ur*E)#WeF z9^Rj<t3k8qx!0Y2*=Z8I9v}m4RZ%g~)`C0oP&#%43A8P%@*EgOYuq{sy z=z%u=%n^zCf=H~vnZC_f*uil!H%4?cge{(>#_E&M6Q zYo1>hi#{%orz(a0XdV8l9uHiepP|PXErLgj&DeufrfIOb=@tr$E+;Vi-n3Fi<# zPdJb8CBkOH7YVa=+`g@Z4TSd-HWEHY*pKj4!hwWEzYHUMhWL?$zaeZQoK4t={8g85 zGVxatP9r>;u-NCUMmUT3!w8Fga1G%c;){7?9^q-kHxvGnu-G@(5;nBw{t^8~Py47k z;v0!C=0$#lXN&YCZ%;Uo_+s4lB)-^(4m>K211> z@IJzMgbx!o6aJns>&WxpNZ3GlCt)MuUkLjV{+Mte;XJ}&gufyjN%$OL6XENGlL=oT zoJ#l_;WWaR31<*KLAbCMx4#DAEaJxy_N&eL;v7K^@y8I~K>XT-^N1fy*q`(}6E+jS z8{sfY-;glt#Pdra97yR)5jGHi31K7QO@#dj?-J<=i|2Y6;V+0EN%$aPv2QQVDVT_# zLi`nEZ%e|-#25SaA!M%$@l%N}zL!K$`bNZ0BYq;`bV~0@ID`1R31<-&-!sBUzBKW3 zh~I;-k@E8)oJago0#o{`gw4c{A{;^dGK5(OuOC{rW|72qCBA|9O9>kZ_aq!k@&>|w z#23%$5VF^o_<_XdPit6bA%0`xhY>%Ca0c;P6OJVQOu{D0zbxTgl9vUa&)wO7U4+Z`w=z}e+^+HVZIs&=f((6Abud>K7^CV-)@A%h`)?* zB;nqKO@x;dPNwwk0uz5e;Z(A>g}}srk8ld5_aK}`{Juh-_~i&^5WgScEW#@Y=Mesg za30}xgw2H039lgi#*@dpw%6TdoP6Y--7ClfwIIF;~G!fAvv2xkz^B%DR~Tf#YnPZG|g{Jjb1 z5q}V2u@82Wu$lNr2phU`|9(x_kML%~VT3;+oJILnBy1x7O2Wy6-yxht_0g1YD)FZf zzDxW-!fC{xD=_i>31<*LnQ%JsTM^D8{tUv|WN#(HIm91KIFE3g;FEl1!e-(RA)G?_ zH7CrvasN#vEY2w!2^)w%lyENTuR_>J{7Aydq`w(qKjNtGBMB!H z9!EHpupQwv!Z!$K5KbkWMR+~o9Kw4D=MmmU*i5)1VHV2$V-olu`i}?x7khy3Ti`FT z^1#<|qF}v6jfcYShZ;xIE}>XQ!neBA{E@U9D)^&l7gFHSwA(1~7}zgTrym0=(rS!r zd1`Du{m<!)w)<$Tx z>-eZwjjiv&@O5SURP*uuucBDY|HQt@SlX@S`>6QV3=e$W5#MW6N*58Wf`C03m;}Mqn<2V*tkvjcYc(+ZB@tqkp7Q6Uj9o3}r zCzi+hTlrkS$ez6mybd@D@waUU^8g>jz{weZ0Aaq;a^fpK3=oZi5F9o**@ zrxwIMk2ozMu(kd0eFtlM<`_SPe%yD$_jc8IESwkMf$tky?c@8J*8a)&{jI;d&-ZQB zeAJKqmj}MjBTk3lxdAM{IE8{3`zyZ9#sl9+7pFqRIRbH7g`Zd9?|lh*^shL@!q2hz z!p@DDukd|md}EadzE3>b(*O8Atkr(8Pby*%<9k-Ze|%qgv}Jtf`|{#+3Z7HJeS2|g z1Q;?7Qv?4deI3D6B4}2e3&FB5i%11ob(*F3qIezlM&sE@C!2)A` z*7n2qRmEu^Jokh7tL0I@bv)qv-d20~ISp|-h@TJQ?-ld>_`a+-HN@aK$ahM`h#|1( z@dAq;$zG&W3oKodF$ez#g$*pFRuLj9L+?qiU)qq#cChl zSHtm@kKk6!dz`=`J;$*Y`#8q8s(Iiz!7`q3oM?I8@^dxT{7d@(C$sg=OsqNBlWv9F zD%D%7+!%)W4n8@Wc!9tDk=QY3b%S-vx^2|s{oB9UIOu48-C_KDbM(Gf&Fqg|oIQN; zvvO_5wCDN^ms4YwGzcF0qozakl@)5&>49rNf!d{xhv)RIS!v7j<0HmqCtMx7^Y?fS zCOCX9y3U4Sr#(0RS?k>kXH9?pGPN!3;j?X(>R)GE9< zzHgT!M}KmJcRLq0OxL&Dvu&z(wFQCa<~}TS?%1q4rGB4!bV;q9o!u}~@1K9_z3$96 zQT?xO-#+N1OMCmrBg!AV5Wf4%7j@?^j9gL=^Jmpu=6+RSsXQdlqy86w2ZuFo|*sxE=pW0mhUY7+v4fPeq#dY?M z^FnV2HmM!BQx_Ir<=LeROX_}gcHr=34clzEGVOWHj$YR$t=eGB==JQI6WePo=^A=d z$7c8*eeo!#dU%+R>z5A;-21tE1Ye!@POBe2@#rb;aqXwjbGwjW4d+qnN&XS$=D-{+VwntYH6K5 z+i(0(=XUz)&7TE8Iu_U^=l&yeN{#8q$2v!h(|yzK=sUiJA^NfpD)mo$?qhy*R^HUm zD{cG_2WPh*IZYGy%&?}f_v8s17czEz&;GU(Qf7W!UOqdz_1-zxX0O$E><}93viZuZ zMIYDv#r=M)U!C@QKY0)|XMZdWH{(u74o&A=S-IvUU z@2hJ(fARQ_)5gl1DusS|_L^zUPXR&YzwCZGXZ#BHTR*0@4(xG5-u`Udq|n;8cROP% zGc@kA-RWY4%jR!uNA;ckex*@|AI+XH@oxJD=R2hZt+m&mk{k}C-OWCKr%%@N>wDU3 z{>*sKSTmtk{Dm3MGH>m&FXtFIw9S+r?`%BRH0VZ;v147U6*TSpYhU-nwU+<*yU(oO zmwh*>P3J1Re5-ac`tMwJ;oS4NSI%DR{$W;ZpY`vI+%u=GTg~wurWxQDv@6x=QX#J2 zuA%q0&8hz9&o4H7aqG|P6$-u{-ZVL7Z%e5`<~NJ3?eNk^Kl;A=s5i~ajOshWWB--F z({1V{#ja{H`ttGJj}MNFt_|h6^=L@)i`^Ic{E=?#vZ}D(^6k#AcWK_;+@QXU9doo+@VsZI z)+{QOuzTto`wx8EWsICq-?zc6ewz({R?T67Q%?RmH1qDLlw8BFE6!#g?=#2H=ZpS1 z-yeDr(RgO2omYo$cCAi@dhKAxtKP`!HhF#WsWumUKf700eeB?sbNt`U^_qMxe&UIw zb^Cvv+}&=;EoJCnZ2i6O2aOpw?bfP0m)ksBKW^xxp3UZ+xZA(}wTNqN&quuJSiRiT ze(C)u+^OAb#H0$tzP$bW5a(AnN4C1#w0W9+`t1FUpR{wWTJ1`^0lCW_SKPkAOODln z1EXJ0JJd*bs%yp{kFWpKef`3OD^9moKj<-{^ty6ef7rM0NttE-35$+&{{77I`a_n= z{;p3xUu5)XnRMZo;0uSZRhP>3`(^jsA-_JJH1G7CPX~rKvJ2>OC)gSEGQ-c0!ks$2 zb3J(Pu7=G%|8(4^XXUslK6{@|I@~oU`{Iba!t`Au+ML??dEe|YrPi!j$_|GN448YU z%cB;T!$a?08GpQ5rDskvI&>M8yY0uR-LC6bZ(22hrL?`p*T@4Ge{aaw9g2_kbUEB& z_KWRF9(8y3eA#OG@3qSL)$dlSjNSS+ZD0Ewc$qROqTSlejkf|4judp9x?*VJLf2|u zS9X2zX~R7pVcX_!Z}nSnvt`S-{_>0F^>+_1CTl0BwFJ{Ot5%2Q@4R}l!Oj5xmZ2vS zaz>2(%^`hN&%y$`V;ioAr?swO_;G8(2kj4Bb~|t9Ioq_V_0{mZ;d_4V{-T0oqs^g* zuK&2*xyK(vKYI86{&Up=hkwuBFSq{ogqvpy>Nc7+1ATL=!ldXIkG~rqFfr|3Badmr zyFF^!FhBF*g3_+;BbRhbNO!Fr8R)KQ>zp$FOf}z4E&n|A)7-s{zX}fO_Uwl-_Vcnc zHTE~A{;@p#Sk%#>+j4)JeeJiVnNhLkC10;R<38%r;rYHwgE6?@Z87D<+PdW*Im?|N zp5MG_(x){JZJar9!Y44)f zrWTh6ef7a|kKk9{XF3-C?0@^>Y{!umE@-`9=kJqtZQp-%+yi~3L;N8cxa~;bjLVY> z8wC7#ef)|>cP=>%>ly#ESNiUb1M2;7?y9!l>z_NGn_ttt&d!T9zV!M^cdY&yhc8e6 z{#mE1U7gmP)?Pinpy%zz$$gJ5NRMdLEVznpp2x4>ymo*2#@==Euo16XTpB(x?E3zp z4&b+_j1k_>nu}T2?Q_~BxLuJOuKV=HnmtiBt`4hrP*;1&s!OJ*WwmY|**~F_N3{l( zt45A;&)m@F;+%wO`H{c;c=|;BUq(8#oSj+o4~LJ3{~p)bYuuIjA5WN>IJm{ixZ{n# zOl@&I*e83z|ezVPRr+?*%XWok%?M{n5Ap4H^Vf&nd3JUD^kI(m*EPDfraI=w40FC7+_rDaNjLpJ{WhS-+KV$9 ztbMvM@#M3k%kNYg<$r6)j@9!XIzGRja%som0n)iMyFW0=Ro8qs*7vT9=d=prmW&*H zy}^R$kXGxLmd$f*7SXoC-X%{$>U`a=_SA+y&6|*xn%u_yiz~jVA?L@wr@K}2lQ1RE ze?IK&$Y8OiKjCNTTbGnsvvRA%qGjybsQVh)Bw%%SXg=2$k5Il2`vM|XRT-rZB9FXyY# zmv5(WD&Jq@RKcWi@=VbeTY#@QvI0{|_1A++#fa;qT#8ga2>O8BR(f!gWtv%W2Jw zV3RtuRo2w35=PL*f5XVAXvTFI{2!^}n50ey|6eiw@qqc*hEVvXK1|6Qe`#kpd|Nca znMqtP!taRqTU+f|efTrN$;hH5=mt{!_s@#{50vU0%;K1YIuh>9Z;D2krx(SAHhjH> z{f2-4v0#nmj^Dgdf@{%OvkkVYV`YA=UGCj)uN1K}Nrjs)9q-d}Yr5L0Veaj}v&h$y zhF+8Zv{Umj??4*^Eb=@)&x&mepa?`-`3knm_ff(n8-9)julxkVDGTQE$1PYp&GjTY>)$bWz00N6Ljg4gxTcdXHQs0Ewf zyp!E5xvd4G9@HuHp}TM@Vbcr*`~NeFC$sUac^^1IU9Y-1S#v~ zxD08|(VfeYnm2}jg4Foz@k*qoqsvz#O>^*Hi!|f-59<`HIgp0bczyPIq*>ZN8x%UC z+NVfU%l@IzWKHHq#CiTRHz76b@46Xj;QJn1kY=s8s?eP0pQbB#+o-KbbGG_zLke~% zl&w6l9dYXX_jVvPTngHWG;O?Y7gAI73590tn!OuwmQPKk{h4deQfTVMn+o-7(C#zj z2R7TF(8%A}9>j+5Aqvfl{aT@6eic8*_`LKah5CJWNug=Go9xB-9BH9KjWd2%sNbYc zO8bng_NhVxlV5YXr2iKvZ+>U5LNk6Y^Ce>DF;bzCnxhK!+gvGAiMN}mP(RP}3Jttn zXFtZLj!jl*+OAxMf`1NReA45LRiVjo8x@*iJfqOmFCHos>hUP1GcE|`G-sqjlb@t2G*XkP z&^+@sh58-0KcUq*!3s@{ zn5EFbQri@2+IXJhnvWHlGuQhB<`TO?Mxn_*b2+WQTcLU7zUTZqg$gyTuY6MR zM{ux01J4XsXj;HLh59Yutx&_|?-UwlSEx{9`AXTCF12i+LbDzZQ)u3i*$QQow<{Fd zpF-2p3KVK`E3Z5cGRC%2X!4#x3T4-)D>Urc28Ehl99L+@ox2J(e_iS{=9m0lLxo1x z?WxeTLkS8sNy`*!PR~@R@%2v%^^;z4Io}y6G;FStZy|7=Q<|daFnl`ggp<#KYa+Lfh zR#d2;uD(JIb6P7j(7ua8^OE{2)O<5mp{9;W3QbO%tx!Y3GKKoJ*{o3WyZaOxw)dDq zBX51j`7SpVnpM9*p@w#v3z&akxPjCDRTb(N(NLkRM}R_e0=g+Qt>!?5n(Rg?H0-A& zg$8b&tDH#p6Umk_XK=j zx?$6iuAc?;yZGMS(o4?;j2t_(P5X!61@x0zZ2E1$qkvN1TyGoO?pQ$CO(!DH&UqHF zu3=T*yY;`9Ce3{sEZ9J*w8b(eM?T)+0GcIBmdzdhZ% zWq4)j&zDdA^Y%OmNHLpE^uG5n;Pcb1ot)xz(w2AX+*xR%2tpH^^My$bZR8EzFz<4agPep${q=?wtQ7v zdVf~lzJ-ro1uQKUdU92x8j`!qRat z`$yNBcfO*O{Kve?=|ieYw=UOx7TTqzw8W))u5pE%CT*W2g06nis(R<0-ZMxWoPQ3rUgvi|Y9Lka zzr39Jx4Ke`cN@oT-sUCsafo;78{bgsy<^JDrj=?-;TxjP*B@S2@~d;KY<4?Osl~Sg zN_`b=ls0PW%yMbwEd4Nf;l4f#yrq?E2CuH>doN(rtLde050fR2VLdOGS=CT-X+G2| zwMJcO#^5CXlyOa@-J7>}8#S39%)`g06kYkpkD6ylQsR;is%KAZE#3U^ zTKI`F0n+Y>5A)7!Y$UC9&bqi^RvYQUz#|12n~c&YPX<t}lD`nRe3 zYNSZglVw#NmUV9-t#sWmXm-_x(x&~bI>#?l36~=y#g*7uQ!+a7R-s79^P7VUH$!=mwo-EpMLb2+0eyL z%KN4Lk{tK^fX)4XD>KYcODg+g6W64MwWafg2Jg$#9|0en?fPDqm>N>Goynb(2HH!} zai4wf+o+o4^0?LIoyS^AFO$a)omIg{it2p*ie>^`=H~o<=%w> z+rIp^(ik5}`q;U8=TgIbq(Kcf94=StO+ZJdN_RT+ZZ3T=)}hevb{nbHn9Js0KB*kD&Nb-n_$^HjgOPiRAlWV zi|R|i)c>OPFH`DCr{ZR2_n7D@nPXjl4d_u-y18`ngwv5v13L9g{_efuF9XK?GRo^o z)0Wcc_oau1FB?hjhUf!vDXk>$k9Oz8_IeR8zV7^rBR^^mc8skav*dNaawa>x7tvJm zT<4~}?-x$`uvyh2a@!4%q`|Lx&w_5 zp;F|HmLG123z5tlT=I9vbd(bBhwOe;wvlx5!p09P9_l8=OiX`0Fr$`Kxr?{+k#j-P zx>bSBL(T?Crm))CeOq*pBCGo}&wa0@ba8*6-@ytsrGh^vzx(HcKh{@%!D$CsMvS#M;w z=bCMm*1wUBg)^!a&Uhp5yOOrUFzk&yKDf);nD&63YqWn->y50hI@NsG@r|rq(4p|; zz1MQqea+{NXI{&{YYt3F-t}4@@uhit<3+FKTVcyLc_+S>6Mxm5YTfU(oZx+R@}kzS zCr&T&WyIzCmvbO7#XWx~F_%sdtdoEvYYFN79{xjJ( zc65bxKR%PS>u+_xaO9c%lcCRVHFrIe`Fi#<`Ayb>(v3cNCdX&G6y7pDlXp$JS?a4n z&*Z#&KfKHcc_!a(uxk2=X3ylhH*z|^Fg}wnrE1)Ilzt{Z_gua3@Uuc$ZkazN{C1)I zou}V?&3A=z>o@Sl?9gLM)MWzP?z z;9sHa;gEEM^(d5oKD1}b^0tL?+QylhF7<$~ghJWDGcsA@P$&mZ*SxZS^i;0gV?fVZ zH=fFm?570{$$2VI)ihlE`Jt!s(ffJ&>N}sx^ICl|dfTd}a`wig8QtbSl}n#kSyn&! zsr=d2X1A`6cq)&bpgD57?^C&Bg?AD!ba*Pye;st(-0Z1*@LI>|J~f}pPE%KpO>%!K zn`V?6l&5_vSBNYqA6f83KH0L}=%?48$WhrdYHz;qM6NLAaQQKZpU45;pE`H`?1`Kj z-|Ir#^-tuioRrp`76CtYM)}woPh{^AnilKEKarnR?>Xvz)D!vBE^R*O5&lGuu2!ml zcJLGVTGrgmzD=LVfkQQup4WIHFWJ>N_H&OXvP1cZ$Qkxe6#KCYi~>ao1&d8ZQx4?LE$253gx?|3Y4J5wV+YRzN$kBAw57Z*I1 zBkdzJeUl%{tw)Eo{bT%N`9}EE1Ivd!mihk0WBK*WuWr}s^jQAg^-+jZtH*Lz`}DqV z>OGdr72f#GvGQa2__4CrtGfaY)4;#S@~Un>4_)~1k=)9@(U!blAIaSsTs_n-_mLd8 zyVmT?(~soq3pf8Pef>xt_)U1)54#`9T{IJSPT%lI9+9)>W~-%-jDAdp(k0Tpk)z*zu7Z`e3_Xoz{=!*;Oyq z8t(f@?%98E?R~~avWF5NeN34PGaW(RJww*KcqlvW-W0s>!9!WQ_13`#Hy+9-CTv@D z`O-uA&h~dVE7?o+qM<;bre${uY#b8qw6L%DkP6#tr=9?HX}dp4-_$wPU8e)xCQ z=L6q=hP(fahw_6Cr!EYf@K6qMy!LSZ$cJ)ay>&y*z4K5$oK*isrSOMxNB6uPlRG|? z_Z;ju@K)=G^7G20{utEgq5O@ZewUjy9?D<*elKE@=R-O5f}h5#^g}sPd#qlz=Aj(h zX#Ll-o)pMkFT7sg{r3WSd2-jRT6qO>T9~iK`4Z3uGeTdSDv-;z9I)Wop#nLuzGkOx zZ-H!o_~GJ8TMOj1Znx?Ntu2r@=`sh#e_SBDXQa4gq!h@Z=hpi_pH?6@uQMYvETKTI zqxoU#=dlHH{^Dd)^}z-5o=J<|ThpsRUR<*?{40=F6)$e3aa4Nxpoge(L)fbMs|4&lzPsXXMMXeyHd*cT&DQIU#tC zLtMVBY4S2`essQEy3T|lRR-qEr!Kwvbbrr$xy@PUGDAZ0<(i$E%`YS8%Vo2h!@qoa zN7f&6<~7KdoBF+TC!$8aTsvfom!CKAm5?td8#ISrI081mHke0poXr_A#Bpm`r|$ui5?YiixU z{iRvncfVnLqupkCiy_u|#%8k|`Tp+BSJs&2-cFiU@=~*WBWA+q+dnePvkbxdYO?_U zmRWb*yJq>s(@xH{6U_1px5=ybjWWwGx8`3A9cq?8oDiS(pubtxHT&`D@}6e-cy#$Q zojaRlgDwdEfn2AVU!L$c%ie>l?px$%mhaV_^fKDVEbDdJ8G%N#+;U3K7BxLVUI}J7 z8UAB-o!*S=eh>uZ=%3I3Ob?71H)1$i2DGss+yUkHDs%b%u-uO5Q58$M^`MBWQ~7(d z;vh&KVLXY8Vd@ml7w=&w6RyhH>=wzp6TVNl8sSHTmE&6w_mXgF;_Iey{o>?+3t_R- z?Lk`?H@F8qe5MvDpE9b`{&W|vhPF8|H;c|on35)l*LkN2jKa8;W zor(y;p2UwNEPhuYmazC80TW?32LaSQJf8TI{n(Jnjp2%8L!cuJMJ9wH zaWP4WQNt5sP z9y-7;xHV->;7n0_xa%g^ENIyH2_xfUdWHAvHg4GH4oSntOh_0xF~-6Vj~Npal~6L@ zB4~5tU+no98=?OPFxJmGxp>v3lz1cK^exrJCwfclzdOP}_W2PFBwE#{>U(;2#hCfJ^0#Zo)ar9K~|j}?F$515n|!~@7RZV6lWjiTU=1v z=MQPKL2g9}vg-6`U!F=%|Iy#G5A!I_KFqhcptjEhzK?}`{NehmfO#aVx6p)7?UmtBIaIz9T!FyE@vAMQ)CNu3V!D9&G)Z*f6wUoNCw0r|wL z@+~e6#-V)~D!JUhX&>fMoPC&YaY1cgGQ4%`zrcy<;rgq9>B3ZUk*a%4i@HQm*CXmL zE~xF$2RXAWkV`E=R-GRGl&h9o2=>F+R9xFqr^7so^AqMAY_qO2x;|;oLFuNvg-6`j}c@=@Q3^2 z>_MF(54Am*PjNxWBG1?k`aj6UmLRK6kM?A!^2f}-`?=`y9yg7^hc+z7>wO)sBmRX#OesAA;P}HEfanUipqhlr~M#UGo zA39;=nCL;Y1U!ffG&DsICA09ieeuF@l9PWv|M9>-9{9%t|9IfvuTzl)8 zYcogY+N2b2jaqfO>6u$^XXe(-iMcf?V|Fo>ibQ@jdo8oSrDuUx7+VF`RLlqC;d(m` zW&p*=dR5XfXN^0vGim)&YQXmpQ~<%NjuR`_yD}@+tP(4yDbLE}@mwQ)8LP0$iEZFw zK1R5&4VShIo33ZtQ2Y@L@^n2!m#w1&vejx zgYrp%`-PZ~^R*UGI^A_GTMJn+uWF9WT~m)a=GmKck#>ICFrM}+kPYS&8J}Zt|E-et zk{@t&mvrnSC2a}$J_T8kFI(-z9O2^mhUp$tzM{UpYUsf~zRbyNwE%5z18Kr3|Mqa- zRndX@C+ps^XQ@j5C8V9CN}CM#vx`Y9^4GXIfY02SgIQOTq zZP~9FTLC&SRAV}52XLCASRQ!xzaVdEzZLYXLT@)#p;=j0VUK%WS(70W^YW_h$PCSD zG6U49Q=X&A0bW7ydS@lQZi99Zv?lVSo5hbUKx(Fvua6A39pMt)_B|~eb?~a|#41ELhBo5|ZKe^c zplQGiP&%xG1P~VeW-8pzhs&W%>SR4@n1LTT@WJ$#?ATNXiFI*cUP>SKhOxs7`ayZi z*zpyl+o0IMe2&5Ww{U5lKZj#IVfv}eq+Q7pwY>h}7kd1P*5g|~r@HW}Y|lz*+!*w< zNRcL)=fS*`c2NP^g`1^a6y?JAACc$xaa?O?dLACh%v?bwE5 z{V)@R$Pe@2cCjT*;D6l@ry();;X5F|!sVc}2k^rb^aFe_@_^By5T;QEWQ+tfcK5cLnY zgW>w?`UfFV|8Tq5lICC4e=%i00STe(=Yd>@OO!nl%bsj0d-oE{?!3uTc6Yd~23N^t zZ%~R=iEhZMH1lOuG_{$V*^pNz3+9hue2kBP#MSxSi1|bTNP^2jnb`5sM57(Gr46(} z=tmx#wAxC#ty+gfZKxef(*`q1+tJ}Ja6}&~I&SO%RphU);Pwby)V^%nilgP3s?4Kd z{%u&wSS`5DKq3s);IfUg9dj&gMR_)qw>%qgjF&cxXOK@Pxa|&?Rv9zH90sw;c3S+g ztK#Ov8kht*HL=gbIk{qoy90B7x^RsFg$kcRhXp40F~T{w!1Uc%>+q$*t@UT47Qz*y5f9qPir z9ej3#YY-xus&jOdGDXJj?&(9K**Ep7DV&UuwQ7rh;}PDU zd@|tvI$UL(KZUlF*BT$rGwfO`U=#vP5ulSYWr|0GAf}dvs9{fBwghv#i#D|qhuGjB~ZCi;52 ztuSbjZQbC099+(dZCQ$KLEM}y#kRv*$;i#|oU2&VfvoAQ(^qj0*0+F}538%itp6(C zuT=RSgZn#wk*^_Hal_xww-(ezVpFJ(CQu&@E#+;x4aP|-Z(FzzgUdlFZyK))t(1XT zm3dDoU}rmB6^GWk7Datog6@SX-7DaJ$J@Fi|5~>bb8l7=zB79;7qfGoXh+x&EN#0M z%2WZF@^8tcDV7%B{xyyo<_P1A##O^yhl)Pf6#Af_Weya+-H9bA{_&55+mUe1fD7ln zuUo<6L7DfChZyQ2GqhpQM{3zK{WF;K>f*E~KtIlV!yUpjRa{sV7=x-rJF_aio#1(+ zXH}Ybn?3W&XQ7#I^=IY#c8#~btKY%wsLsrAUx-*4sAt$Y6tL=ABa}s1XYgRwZ~6RL zR$~XWZ_ErHt_|S6DO@~lp2J<9l<_|8QRLY$z>>~q7~GChCA-0DV~&s~&cQWh8H~_j zSU*V^2|@XunP^~<1D;sdetk% zDmAOaDrqV)gBezca-6e7d&2QOa3_4*RxAVObOsOu7ys^N(^Yb)q(7jGfm|7`uXse4W*)s=U@ljRdBhu(^?+5N3ck%?@Yx9W+u_o>-~bn? z%hT?K?;twnQox^~=(|`h%c@n=v1*UXF#Bj%7FkWhcEFVZX)!2%g~1!+p23wZ;(=FO zoNf9N^Q@_3H7QSH4GkLuSIu2T^TfD=aJ3cjkY{mmw&`*Gu5HcL56LwsTx zrib$QRnf3LaIFx!aorHgk8#i8$`J98XK``1={2sfRtbI175bcOIA5z&=1|c87>og} z;BwhbNc?!cH<-xfQ$cVYl+cJ#V##zeesbQW+ z=vk#+Gqzc?5pzh}@k-G%6Vl_n;_uLZwPu9rk^fhA{3r8;AC&e7Z4cU;Xn$|{t|TAB zK##L(OC5PRGcQ;(@PhA(UcDWe7p%2;H7S<|tw;&@SP=D7wj8YWf^4~HM_3nkVC9;W z&8zLkaCBs8@PdtND-9bm6WR=fc(|XY!b&83kgl+@ihX)~j+syg&S_qNymxC2dzW;W z0XG4>gm4?U@2KJ#C)-Q>p{otHX8OhTuDS@a3LB=3Z{I%A@IpLf!*fDm~8LHUp>IN96rqrH)z{7TvA+m$Qd9bpZAfG8r$W@Q-Tk*Vf;**wzN6 zpFq7evuCbuw5Oz$9&`h>lwFZ?1-UZJbur16gLa+>Hbv`TAIJ`D(=yR3lyq2sO1cu- zMsd9I&a6B<$Nvv|?*rH8y#N0{-~ZpWw!PQdR@SUdvyh!k$T>rsHX%FNGC5++ibl4y z_Xr&_nGiA|giHvrObFTHgg7CSqcb6dkR#4a2*3O5dS6$2@4c%w=NzBU`F%gz?e^IH z(d+%XUf1*W=Xza#-q-uO#QBGM+KIF3+#qW0HqDv^Jd$PkIl@2_jD9!T(D>V6 zU|VbBVaMYVEnY2s4CBPZI2kQr8+>sF@x530=CC+pOx~4dkxl63%iS8aWnDIopKYnW zvwo4lWey|%$ta9v6wQ{gXzOSHnZ~hFe6V)Bv^}n!)2*CM*~W|0nrX@Nm8ccV@vu!e z9due4|=xvRc2^6zdwBYz-`KHFXH?(!<1+8+k=eb7jY@UZ^D z`Q`fp=D7eIyzlU3gv97?l1OATK zoAbW~+WDWcK5cumu}_<`W8n?!m>MimNe_OBg?XS1t2mJn4ajJiV`%qsDslM&Y zWIv$C7~ye?XR~%@-R5la?aS0QZ>6k59=6Dz&~aC|HLAZiqZRz^|8H=eYCiBALlFmz zkcga7>?8IT?gHovZgV#|^BkG>IFUKLL`SXTss@XEh7P7)iVr+#5$97DIaaUdn|>?O z*0X^9sES=Nuszjyu#8jJ00!5j>Y|QSUR=*Uz0M+|Xir7;_qFf{{#O4+K5CJ%$oSm& z+xT3|r2jWmef9L6w!gt`XQ*+Z%_k$-XRz;J4vd@`u+JE3%xcGi>>sk&KctOhKM^7k zYxVua#9*12HC`sBjgyJ-VKVWXu)fePeIGQ;F{EXf&w{kiSO@1a5yTm>U|b*H-nALy z<*n5g2`;v1^KTN|A1SJ>QqlOgt8x}yLErFR54FTg@L{BA{5@EX$^35YuP(XLB3qGK zCb-16?x11vuOQFINag%d&mS?JI$Ea5$i5L>L2a%kGjt!H&HjM8J>k4i2G>ys|nHl1nTc(YWY4Q8WG`^qTVJ6T%WqTfGSzmn9P1hY` zteg5MtN*#vH6}}tx~E_-?Hq$_zGE!*6=TA=-`2agglA2XaPFxIC(oF!?fa0wudvGc zJgZ!#Z>QR_JIp!k%Q@c;i)ZdxppUyyhlHNttNRG%0BxDwnMaN7#w@Q%TEsZ!hkW1l zg#_Pf#4K&t<3VGcLos0P37m`mrLs-x;w#s8-lery2-k^d(~t%3Jne54pW5e-vdbur z^GD4L_N52JH%9H>n#XhPaUA=(FxlHTA87ZQ9NeT``-qtZk4Dzu%r=X3+1FUV)IKog zwTJ^p$YgJXOy*vk$y~Ra%y$*qtio7T+eDGx)|Sa3GP!vidBey%mb{@dd9yaBk&`ht zb%ady&X=iKC&<+J6uw(a7HzxGKIL=38N&iy{2;`v5DPgCn)+zhVE|8FDR zpW1m|u#C*tm!GWK=Md@~Put9pv3g|3 z>mIQm_3<)iXEA5TkClm=eJ!lw&Qz7+Uj$!xhk8S)*BA-iJVLwHnyG!lIwI9I&RFIo z?qdqL#;LLl?u)e8LuBMyzq-$)?t$s5FSuqM%6uQ1AJ7+C-cd4ggI03^k#cbLv7tg{S6x9Kai^J*v3K` z$D!Zo=fZ(`jK3$S?|{a!-Y~ucVtX*QH{)}~1^W0msK$F>YFh zUxylJ#^0)}Iez2P_&Z?!8q6P@de}mhfQq<%oT9IQx(AnSRHElR{(?+xR3tpTy^r_lvfd zIObh@waGD=@A|E8>>K&NByS{l7H=}iZyC*bwf{9#EiS)pN88R#&MS?21TbQ> zZ*KXJhXz&ref#<2)N-r#yY9g;V6>sJy#9B@-gb^#LS)R^;8ayci(ZEM%~vGnc-O79 zsv#ypDnE0VQO7&Db9o#3fjZ8``??s1s=R)^yxQx1@r?1Szfsm{e0C<< zV%A>j+>`jmF7W@Bnz21p`VjRTY=@zi8!CNQ+pw`dgX(%|H`hzOTrbViub1{|O}Kq~ zH1ZmKF$BkqWDeKcF>{NrZ;gJ@zx&?)y8~6mYQH&v@7}cU-~-23;NSYXBO>^|gZqZm zc?JEPr~0l;U#E(GYpp(>hRNULmp}7iJ-=Unt8#W4|3lP$@OVm_dpR#=4vkH-c07ZP^)%aHirAC zN9cXf7tjZ4`GN+kg823WtT&DI#!R-=6b+uf{R1N+`sc7jzqF1PF^eRaIev_G2E#Yg__ zPM)34^*!9<$z11QF7Ye~$y4R{uFnlI&kQrK_}2f5g)!rICCfKv67`3n?oOV;@olu# zaL1LZ515k%w^3smgWB)JI9H74{BnWui!JhN{o;4cL;IWi@c8aoYlFbQwYib+kC@ZK zn9~NYH|gt-IFRcRUamuAaUFtl=E-ZfpT((T%0yKt|FpUp=RN8iMJt!@#L_sQi|2gK zIF}2EFJf+e-=5agMJZ|Hf$E{rRDBt1QNtr%Qw0qLjoNKg^ z!GEWnf6cyWS8aKK`hIgP=K`Ue3yhJ-?QOYZy|wKv;CR|>8{FMAZLDyf&v%reYqh(x zGqpYo=nLQeZ6y0Q_OFbq9rmqyTSm+rAycv{WlH?*GKGE^{AO1_$JnVajB#xA#h!87 zrLJ12alXs8+B5cibJo8*_Ox+6V*7PZ)4%=ZOyfG9acxrN_i`Vd@g1p($A7NV?sXW& zy$&N~{DQ$P!fzWJX8zS;@%wzJImFn04F1~rIdDBjIa+$)xv9y#t=D(re?ij znHvAHWvZpwVq8g7Y(CWE9^5Br=XxW#M#6O)&LJjoo-k>F z-}M@!T@3!({@C3)UMrXVZ5r1B^xrLMbFy~a!Z8ci4?HvV;}$Ki$@K!W`VKYM8||R& z3wJTcYx~=Oq5q}^v!CYoKHNJsm3ybAQirKC_wLf_WwfWk|3mu$?HEoS%S{Pp--$TK zof7YsDKjVaP3(%;VU8Odr^C(t+ISe|m~D5*pf-N~7mhQA>U(``?9TE2?&KM4cVo=` zr{)UxJ;?$^ffztunge_8LZ zZO>ns-|QOrB`;Z}1WmYV_pX`W_9EW{qI#2S=4R#3r0iK}+ivFngtGh4Tf3QmK6%s8 zjk}rOO5PBZZ<60K)c(P=o&C;Bwa@+j*2dc~$DscO*A0ig-n*;#cXvPkUwRBZc->g- z-_r6Q$Lu@2J!$%Vh5_Ggnzf5De;72&^Y5f-_fzrPFzykIz-jVmI?&M%mY+bd&t1_g@VouJ#>g&ciQ97wLa%W5>4+-|ui{(idZ_GG;??s%01VAVnOg zek*Z;>F*U%wUsj_Cpcun8DsN8GsmQQ;?&wm8)`lt?)&aI?!}HjkNdFC-041ORsSfP zUiL1wwTS&j$b|S4xLoLLZZu-grrhNy!KCcLHX3Ry43%z-fq#{OiSofjw?P@O5?iT{`yM~em=A|4 z`#%*!G|z;#EbzZqO8fn|HZK_a0HaTJ`kvL5&Tr^W=DxQy?RN_*KezSnJddbj0i&(8 zy6pTLa?@iOV>}u(V$jQqn5LcuFoy5PJu*Ij`}gB24&ygw+A&Bz>knwF2yGv*{W~h- z{=qvYIHebDGTZKXrq#5ph5R;f0ly8LFWiftH~4!QRUY3>?r?v$KG*x&YAbE^Pui+) zu&wf3zP9qsRXhtPf5hP2dD94|#Pe*MyUgMU+^)2`j9}fqGE}KM%~64EXtbr%CeC<{ z*R-QtV|)3P+rm&~t78HBM!(;u&3A`TaH(}Bl`E8N5PYk$6ZK$!oLs=%*=8bg@wS2(X z4jk*I+tvpDfyg=&Z_?`*r z`+b+1GZNLnz`kyZ3Jw$K1Z>kqrIYox!nh#I4UGrpGjgIps9;p4mL1FCX}u zl-Evm%E#zuvtbfYk2oWqov3dIW^pb$i+v!fHi>hL zicj5(zQK2Yu+cB!IZkOpFPJUk_gfAl|BPi$`2+gQB>&(xFx)mc)O_IAU#d?Bw`c8{ zPY(UM3HJqaooDb_MaKA3WvcU@U0tWv;u_*P54*MfbFVJPE|IjO|NXjJyu-~c+Bh(o zuT?z!K0Cs@!*eJ4wDSI)>tbfhs%QLi|8+R+7oN|r#Ca;q_VomeTeGpOwcQZ+%NzY* zww%%5CZ9!2R`<4z5zpG~zxDE;(|zZt?33czhWyS^@4Lq-Pom(`fVpG=*HBE>GdPw^ zKJ%@EV_S~H)H5cHc_*^QDQ}|~eH~qR`vcqmR&A&LX=SVR8f~DBeKjs^1uF%gH&3LGn#dblF9jl*JXXjk@~f= z!G1By(T*>NdFGdK?rgS?3U@NTU5sxyGb~f9Gfo+7R65?sB%-n~dk9X$`2xozWLV&v{K+8|-Rc3y9hG{-3?sfAbC? zo~1IX&G-HvH7@E@f&2>`TfXN*?9cvXKh8<_9eh4Slzwg0_dM+>JP+9So(EM{msS#G zY3;H7oK7X1K4T;>&M4lEl)vLIw^X@tM!Cby$AM){=XfP;f9kv+b&mG^PCC=KEf~+I zF|TtBb)HV0qX+9eWd8lsyHEC$328C(?R2h#@?43$fOQz-&ZJGu+G%hM7~^L$@2Ig{ zEzT}`o3%+VTmL=Glo;M&x%CQ(@~+|c>sN{=twh}MS4rJ>%pv_wskQswLpz1`3rw?c zZasl(EWBexJ&A*;d1mf7u75W3%nr`e9L&#o+njPGvOBhy6PRXtP7}}<+A~}E9qkCt zZ+%Z;U_7XI+pP1|CsD1Of4=_kyS}Bh*%*!wJTiK-Z^?)QN1n99_Ox*4?J3V+`=}_CC8z&%;GY(DT8jF*{6=zjlYLEPn$i_ zCAXt(X62e3OIX6Vp8kB`Q?7giY)mBI*);PkOOEv-`E7{tJWHc(2ljW#A9$Aj_-jp$ zX$HSv*#7)kRjT?e+%(>^6~Xf}cX%#bD(A&V^V^COcma@a_44Lqm+$!i!}LeQfk84c zt;{+x{yOVK%hgunmxO9wP2~6C>fdhVIf(C!(r&g+jxV=Pwp?f3ewEL+4QJ|Q`L^Nh z_lfw9aeVg`8SV1k?_81*=aQL$?V^rxj6O8BtzGR4hZ=9%wzA`OK;J#(1OC@nwci)3 zwrJC@0S>O;h(qfqljmgK5+t|8CyB>$r0*H@O}0$6KUe>J&vc(BMT=dsAk!sD!Q1E0 zz%+}xp2fYo7MFU4>`^ks!*iFsM>3BmO5Y-v?02$D%8ljK^KP{kQG;gl zhZ;xfy0`i+g>$tD%o7t93_krz+wWRJ91`-O(HnZ*w6e_Z$1r)OQ#a4T@`iGZ$+N!L zSMppeZ6x~6n|3TCB05B(vpf>TzD_-Z*OR~f`IhQ=5izIup7pMx`1a4f`6Xg|px=R%D=der8?WA{uwuXfyK z?1R*G3pFPGoBmeqsp1-DU!iRWyPIdY;}v6F!{sry87&XjFu31GzmBo}S)4{5Z67e2 z-}H^*H+}rJkLw+i^8J3(r`2hQYd}UB+BgdMZbnPfpOw8qKfatk;-rX$VLZ)y=Y77~ zPZSybt;IdWb4v7e`tB<^Zu@;DR^P&=*E7uKj@?bu_JJnHlzKlz3~`)dTtlsV*d_0v z69f0hTm#wFvLWkTay&ZMWZ7ZA^BpSY5Z*VTwj1?a`8jZyW4R?yxMT&oDsbH#NBEA- z)HQRC(c*)|cy6q546^rgE;$K3V6v=sPt69u@4WTB%HX~_OkKa?d|`oKo=p8&RqC0+ zYF=I7{{|K6F(n&0~m0>^{#x85&7 z#x~2C^(ks&#J7B^MIDQ&=T(}tL&U!9n{#-62>RzQ@zSJ~!uiQ=kNGN;rh_G@Zf&f=tJ#uhq#^};&ZKzJ73r5y-$az z@AXF<%*fH>8@#tcm2IUjhuOEPYj6?Nb6orsu17^ma9&WRJFuQS6MRwu-}$TOg7e&C z^=xpne1qG`)KN0Ez$O!OIA-U0s62yZr>B}~c~|RWS&{cp`JROx%G&vRqMKt!&Jo$J zCUSfpDv+vk-F8AQ6XRP_2ce2Aix@+)V6T|eC**M*4J2mQPP_+}! z+7ISg`-9Js(4I39s^008r?rnZhpYE!`~CJmU>h6U$7t8Nd5$pO_fF;+z4|kP)w?pZ zehc!OH;lReg#Fx7gv#g>#U1)&xcaI(@ZIci<2SJWTG{+(8O3wq=V+_i^WUBp*wX@g zT3}BL>}i4jXItP0kFRR!QNC-U{uNbU%N3DcgW6EPNggAA;*q}P)p3eSQ#xiB6<(cGrdFIaf=I!T8Yv5Trf&VzfmMGGbO+MRrurGI?$!F@)wufg~Bp|b8)sj^v z@wM_2+rWPvCi!Bb19OR-sTz!bMXWRMpNgky7xB0gcW(dF4hSqsqp z-U%k_`F#JK*Rxzd#!IEVz<;Vfd8FqJ(Kjl8j>&pf9U54Y$iDmf(i%+GqxyfSb-czq zlhnVyA(nGToA-T{Nn95tYDMkv-*kQKr&3PfKdt_x4;7or-x08$DAF!CT79zPKQHgv zRsR}>SWgG(Lu~_UIrr?H$IZ7U<8yy~d`5Bae&9dV&IzQOZ7Yc; zo;~O2q`C8sNj~3I89b_f|j}Z!qrpsad6-JK6CfIK3;ZL*MM?~mlSENA^&stY`G`O_wi2u zU-q*vDN*O+yP1Esp8pB*zrL<}-CpwXx}J5X4qg5wcWX%+AkVzBD^v3Ez@t%N-THeVIkRLiA;KF2Zd2?1H7) zdER9!mM5mn3cb5`T0w7ml0F`S*y;?UhXvs%QUXs6=yA5YPuHldgNv=Kg*kAzJOU=D^__I zuQ+pY{*vWqWe3J&n*aRl{4;Y`TwuP2q5EI;$C;~^FI8Q*cqu&-xUwPog^P9B1w*XN zEIzH@^YfQnxOjQ?1&e*H5xAlogWn1W7;$5{eaP{WvU$ShcIQNW_JuUEC zwm{y69BXm~C#ot)ir{`1ixl1;B$+UcpC%>Zt6(laQL>Y#3I<=oZ(Z&Sk~p~JQkKQn z!P%FI%py-6{2X~%R#sCc$|aBDA(vA=UU4?6#48?y8u3-|HPnVz9CrmjkHRZXL2k-a zoQ`7gWw33HNXG3!5_P4>0Lr*6ND@m#p1n#Wi#4Fy3w&L61+M9Vk!JT+ma|_?$5_1ksDx#!;Oodko-R24PRdbz z2fI-(G0R;dKcFhgOst}Qs6fR46Yi!jsAC>HdmZgS40X_5jVIAOc*RE4jn|0p$Co`z>>K%Ro4ORiq)m(y+OP;-*u;1KDo*&+bF>M4EzgU5 zkFuys;$K7#Z^l!{B6#5ojA8211iwZ#w7I+}Vta|$C^Hq7v=B38cEPo+YzvfG^eW${ zyv{QMD6Ho-49lZP@B-xS$~A}Ob>oig4MNv7_pF#d1EthNO>p@TM5b%Ea? zH!&z)^>>kIykak!g;yN0h5L5!dGJ~k&a!pzGvvmrAL@pqID8a52&Lf@;q9mpujuWh zeejB9s1~nSiJI{8F6E#c*2Q;KQiP%(VqLIXi8&$eJ(0)XC%y++R~Pj~IW?qzAaWb> zkiQ9D^bvK&_rd+TDTh3H@ZgUbOO%rbi$15#AE2$i5IOH3%wwv|uec`mHRa&*z9G+d zjBS;tpFaJ8aYB08kIYvC%psJM3Lirr%5Q^5bB}Q`KFVp4TTv@{n&6ixmU#H_s~nC( z)(2@^fseu~K8F(U!fz&yL1}o!F~Jte!7ENeC3wYsPz}BgzK0s|iqZVGs12_ehqmGs z4@Kd1Y`?s#`%>;_E+?Kgcq;Eeug4d`!^T)-RxM@1tZ^0zdzk#=EwT=INmty4O7V&@ z6D(4VSFA^kc*WV_#DG^k2KC?-Pe23sHu&>i76t+BIng3zlPuCq44%C$G6kimnBfLg z@ko%yAMkZ}#akxRws^&A)QwkcMg921DB59)MG92>uol(f6~9LgP_ zJ_A;uSn|}suTV5z4rDzj7oP%eL|OQ1_!X+c+h;HaQ7OI{HlY-J8=UYvV#bHZS>#VB zi*@C~M^G)k30e;#KRygDLR;}U@Ie&DvW@U()K0o*rbQN@c+#`reaMS%fIpx*e8|BT znUB)&nf$K22zgny1lFKNd>wof72-SLFQ^#rKExsipi+E1JQGwE^g1k{F4gX>WXz6Bn0m_<79Met74k8gyZq5-@;fp}5l2I>wkIh_8&H^b!L z)0g;Mc*h^;FMQZ6i=2r1@rAGfg*-<5M_A-I6o$`$g(w}oVFilASHaIv z59JTQE03YA@U<{0nX!k@g=MGkJEK&5 z7JLGw)^BAv>^h=q)|Cz!`zH>$yV(k!wBdGQ7CWt4~yUu2PUP}t+NC%h4b;49$MCsSX_ zY)rSvCn$#Wewc9zZHO;`526Zu1H9}{v>m<+PR^j+@pL5J@o{oC(S+Edwsbyg$>ciK=-)A%TvTO#NcqTF9 zGhrU;z!$-9b7>cR-E!Iq_2JuKW**xbz8n66qMu|upT``CV)1G417yeB^BLPH5+4tb z^0F=9J*$`>P@zhPe?+DDR`@9@#`nPy=hN5tB)A-<;hSK`1+*_ds(|ePRpQfN4ywoJ z!PTe{Ujpw&)%Y6NfNJqg@W2b{#|GLBR-;6GGyErNCr`pf%rj^J-vGy6%)E+^g-4=J zd=gxQy73usIqJoG;U%aUUj(NWvcJG*!Anpj>netKp;~+={0`OQ<?Bcfp_{>Vl7ki%~1S z1pWgx;@y|ApF-XEl+|pr#q>oZ>w>SYp)UB;D;ZNIdd&Gy`#=iIt%EULppYCKVQGUu@Z2MKrY4|QU z;U4ll!~6gf?qj=9>F`hYvn@ZxIC+5ag1qF3e2{gaQhc}a4>3=YCj~A;h4>|C~jBL@D^<=PmLqD#puSs5f$Nq3;v;*eE2k2j>?*e8OjUH zOLz}ljS601e*wEt1?he8j2CHV(i`F4FR|_86X0zq4POt(x6qFGIJg!i;cMZjmzi7e zG4N&7Lz!FQRj;UZ(>`$SU)gUe4;Qzx%@SuRd=j+XTo);178n+LOpoTo1BB71bh-a z7bW5g;N2)0Ukl$tsrW7!)XuhvkAsh(JbW9x{4K^3z79tIjWK{vfPY0r_&#{*+w={- z0Jb4%qMQzkC#VRia@eV$G?+B~x%d>Es@bPf&NULPwOJSbJDjw<>%R5od=Uq2F z_?WR)nT-aBAsJ2|XO(X9SHUMy9KI3uj<-qzK4F4Yj*75KExrjB?L|2(TL=F(k!KfB zuc%0?oHWHMNu*a#waT+7M71HDvX52j@Ud_SYQvYpuT(nu-O*OL9i>oC6P!QIDmC;) zDf|a2BTvP?R=GOPDuu-FKG-Thp)B&x;@JqNpf>Vk!i!J`z6j1d%qm`D?t-<4TP2M2 zsNY-V+do*PpY+^WR=FH?kzN899BGvbd^7Av8RT&vWtC@+wn`=I?Mb38^Q_W{&x6}g z2R{55mPJi!y>LvjRiYUuHSjIeKz+O50mqUbUktO4qpk2AF!6Zabx2(@U=2#4%tkn4 zzE#ReZ-u9wNL}#u1y(uiWXi-Br(5NVQ>@a7Px_NpR-+bTXoB-kw@Nti$1k?ZnoQb? zb#=l=mryVA_rTN6V7;Ul!Y@%9>kV0Im8Dt4Po4(&I*KJvJ50^CN<2OfUT_xeiSLK+ zo^6#hmMzG&N)@Uhy%v6hn(%SwT4m01>V?l(L7Srl)xU6K9`(nEoM)Bgs1RQQx1e%- zAKaF2l^A@&N~@fWs+h+r;OnRc-{-Z;$Ez6UFS1`gpLaA~z`F1)@WBGBY$Z=O?7NV< zkRE@LRjxz5q*uewP#t~%&bgSj#izmBP!qlu{)AfaVTD#%g*xz6unXl;W*^+^&sHhG zN5Ofh2%idXK_&R2ODGfdcjnFSW`Qs0`l-`;ZqeMOHZrCE?3q56V*Mms#aV zmTxXR`eB$-AH%fe&F$14O(fH&tt1Lrx zHR0RfQRVa(z8-#q z3h+rcF`jQG4>3gEVwJTOj1#=)R>taW^eaB`cB_0?Nq@aUnRi%aJ*p$U0ltYmq<6ya z&@6oSo%9Q8AdmYltL%fqNsoocpd@@MJQLNBCl9`gs_@dE#oUa{L2~4SYF# z3&p8&;C>I%NB9)D|3lOTp9S}>rOok;aO}gh6=lZ2OOc!Oa`*^pBfTEJhJ^G^_#G<6 zM?b>;5S5W94X#EN_%iqys=_zI&ruD&c0Kz|RL-&;aBLm(A?eX@G0MW{!N*W8z7y{M zDDw$E5nhMV@b&OxRDuuRV3mcaq?LNXyHEqZ4*m@#;k)4I$7pAKWIb~@ipM9xt&h{E z_@XC>_es`;-wH=JFb436@N(2g%*`<5Ddqxv6ucOvyvn-Zo5+pthFg&bFHc+L2o#P_ zgXJg+-vMVn!#s>nhHFp^z72Mxe%9Ly2au31jaE4X^^l$f(@-Bi53WT;l%O1$LoXc=xMpA1Ddm44;3E z_2KQW^K7Ix`V5~8zk7rBe21~LnSDw-@!?D0!oSg{ZL|Ztt%LD{_xzpte+y%kWnP;z!k=G9KXjAJB$9)b~S<2|vPtF)5d05|sFNte%P^UrA?(oJ@X1^0i*M-*@|VGzx8cd(0lU7V z9Y~MvXFvZv>n6PozV!p+nDp=;tukonF-2y#}uTnf@X@^%s^Cn}mGEScR1q zJbAj{Csv!3;$v(!nPInySCtRna@ZvDL(1oULX%uJ$?Bqfc$V8HB_B{eTpwhUHrhOg z=Y5^a^N?c6-w%HZp&as;jI_!1qij+^{_xQ@ne4Gi7x~NJO=E0QLwW~%H`FG5YD|u` z$@DOrgpr;DSB$es66v1tHW@d8m?=LUo)&JCG|I1n_ea>Ifc!o1tG#T}MEzm7lfx!ce|!PFG|DE$)HiC1O{PsHe)8wQbN9iMrw%?DZIfDjKm28y zP0Gn%wJ+x{y4i55P}PA`j(cEutRjHpx?MehSaII+gNOf5CH4vq`;* z2ZmMIIGTHu0QglLQq{4)H9r$$*OIY~snKO;kM4y@Ga7@xV*Z zBaey)e!7x8DjuG9RDM3~rsBDPcrK)T6%Rc3V){tM14A#dNrQ?9URK07QSrbJR+C4? zb2;%`VPg&;o;AdCrA=B@JSD_)wM}NJc%b`Qn?$R4;HB4-N5um_y@5O`p0&hNPFtyX zZX%vrC|||%s!hUQvq=o;v*2bFg71gtzHXDP%%!E!%0qBF@oDccHc|g;#1BVw+9aL% zEesxpnwY~A;Zl^w{G1D~M{UfF74R8U#C+ZiKSk;9a!d}#zDsq}gJ3eGC zBL3Kqs8cs}q3$*CqmLOglo|htO;SJQGuo;J{@g>m5l_iyHmUxc?T$JYeZ#zk+>{x% zmAu<*;-M}bFywoiL{XPYc*l>7RhEq!u*sC4S%$haSnM*_YL{xt$${UZLY57;+2vl; zOC4L_Np`zL(-#HM;jl|7WyZkAQ7v(Hz%!k8sVB}-xR=W=A@oHed<`YgCR^cZw_Um^ zrv@GxMES&!0Y67ow3UZvf34%$Vj09!GRiIwhuS5Mcp7*4F*a?2{8CU8Wc~X9M;teYfh)FSXUQ(W--s-V_jR}>zUMrb-9<=}do zWqcN%WlP{@R7;-ZY`ffuVp*@}OuL+lLfG!AVN4F~#(GPk=WN=9WxcTf9O7jBXXM(Y z>s-6cV!cVr>7NyhE6R+`vrFB1c4=n4Vfl91xRN%Zjxk==yUH%{tZUZ!cKPH2yQEUb z)B?Nwa3SqXIawFkWmF+`A%+4t^%BMq{aXq*t)@)kX}#Po<4TC1cw(+1=4*+Wcyg|z z?6r(P%89v=XNBHE{KR9guuI$R#6UdFm3CQsH*HNkE$b-be&Q#do*KJ6@vvReiKq7w z+W#@?$Xt|JPs|N=i6oxBrx;Tk?b1X%)teYcs9d#Ylb!2cv=8gbeaE>}{jZES z$}EOIp#kEFY-PKC4Nv>@L+=}S))lsy{Oz;}?b8Q;|2E~*KCLi$3+={s)B|U}OPrL` z45PcKC-F4G`5)1S#IqHqeL_2`_JJv%Q4aBR!}EI?SHu(fC23zVhcH)r`|NVa*UTHl zlLJ?LLz@#%9X#)!^b_$^!|bh$XX2@VcYRCy&?a5*?rpRW{nZX{{*Jn+{(>9(nKy`M z0B-!AZG(9F;D#R!KXu$$&?= z9a2v`1u!ckphj@u69)64lXrC~T zL+(QZYP*J6V~CS@N?~HCL&}IJ54y)Xq(+S&*n-lCrw>+#IV6vG+F|ZEhj@r*D_l07 zcN|kr3H%AwP);Q8`@R7+QcfM57VeN7%1MGxp%TjJfG0!{gR0kF#E%BZlL@ayt@wU; zW~4*fD8Cub+}j~txL9MK}9UeA=_F=uL@Rr{>M9AL*e|He^lfMXd%%nZZ zA9pbE#`Au8^7p~R4sl2dV;~t`k6Nf#75o$xFjo8FQHK(bDj$wGj6Af%EchMjAb(5( z@3=>Klpl7uLtaOjW`r^2h#xu{4X=h$k7w9zhJ`&w(jN5)=6=;LM}QLz{1% z&3flh4sDeN*P#~LD)(rIJb+3`Z-D)1E9vee%ACs>Am##CIgjmy@_S%NGUJRq>F}Uq z8GnrD960+pmSMdG@WkWsw0Q|^OkvCubI1vd=lKrlWE_^k=0CDN#$i~hLnfX`IrM1; zT)Kc|7>CvHp@qauo1~;U-u+Pt4|>)@Ho9MX+1hxeZCkXn2%oO>?yrJPQ+6_w!aw=hp4555;xRxrl!EpYX%v=6=xo^cy>#Fr`F zPJH-67+c9Q_;l#LgFeQ`!%t8%KJHFpLs7kqtGgVs5Ji8loXp3Ev8DxQDjJH^UpMi4)%f zdr%R+4}N^FLmKeW_c504r!Vk1&{0D^d@SrjLTsJ~_#Aog;SW0GVAM~ZS@0fIf^USK zs0-f%_j`zaiOK^<*E%E~p9DWa$#~Dhl!;RDA&)rZ6_kq~fQPK7-Bf;fCW^(^z)w)f z*UV#Z=A-1t7r}p^jy}rSK-p*(>FMw?REaNz8 z_*(dK1LGF&d5UsSBgU4Z3RDhmOS{xjm*8MpZv{m^(Mx!$`AK%qOZx53}0yG*aP4Ff!^cjhB}4*U+K;3Ky<F|8y#uvdV)I**c*n-;dZE(c9v=u%Qo{YNiIdC27!`H#jQ3pQiJ?3iU zq0CHp6N=H7dEh%J0q^c|$UZ0$p9t?n$@pd{AF%DF1&sc9M zd;~S)8(=G{BEQ|{l)s`*@(;kj*qxF|o_=_n!zq2_X@}=KdFM2~4t{{b$=?U3xSY~O zdJ(+U%{vRfr9Fe3vJeeWP9Cg6Tk*Bc9`c;OV@V z8lMV#Q4>BahIJl5yWx{!dC&LnoD%XK{SxPt?1P+=hp&Ry&vZ%&z7>9rV(|lT%E3-a z!Nu9G?b1LQ#14@w`_aCE&eq zdJ5}OdEh3Lj_-tro#2!ld@5{01u7jLHJ`r5r^79%7C!)c{zzZrqf?!78EVE?K+B25 ziI0T0pdNe!Ja_?dQm-_4Ckn^c!7ou1egK}dkaouB!UmL%Z-s}au`T1%;A)hIFM}IV zk;()2T|~_ILg+r3v4M|;r=dpLDiXa;e4}310F^^9;i|rIu3^1NyM-Foe-m{Exga+`L za1AQLm%#>9f^UYsr~qGowo}eH$0-^3N*I<)o8Z&oJ*W)d0LPunc7%^y?v(q`EPM;R zbp?Hg?|?_<(Wm%acqK~xi8A4nC>`Gf-#?FS6Q7vxl-p4zz8?OFV)248VwK%Dq;_{m!8 zi=TBP`vO!={*ZF&gevjL@bsJLJA5s?p@Me9XWYu1bUW?LvITHyCEEzT3Z8HW<42{# zBkm-Ad>$Nq7yA!Q{`w-(0p9OD3F%r!0 z*671p=0JP_EP9yo@!m&>Z9RRV((Bk4Bc9{LZ>Wg>QTh?z1ZQlZt?()EQPhCn3P(Ri zy)3~J4i83Q_%yfz#o`O#jVKad3IB@h_zvi*r`_>ka2^_<%rtm8YQa}S$1}7qzP`~Z zucHj|cf(&$7T*1=Q$jZ~hVf}|&0iRYs>~Ot2P(x^!b@7%58>NicFI?%7w>t+DRa;O zJ`KKsI`MsQ#%s(o_>k9`W6@T89873q{>K->@Hc29d?I`qg;{AgxO_A9!k58o-=rPz zt+1_~cEE?dMcx0#c7#uYiElGT@zEW$1FFCm!f{)OS$TLn%EDK}W8Y!?+vq!ZbSLA1 z^aAL4ml#w!JiUwUiuCXgoMQcuJ|cY)%&Uc@Ezsz zj%vkOC;{*PzH9X^?5ZCbV=Sw<5%uAl2b^;EPqYvDJK#${bL@e)|H5{Pit%l*!se1Z ze1+X5u@0A1;4|T+ZkIITlY?CH9;(6HgL#J%>cL0B6{rti480><(vNS2ts%Sz$jNvc z>5_*=@!nK?6a`BE``VMxYj3C~R09Q{XCO6}JAD0{+ zO&)wEv`lkJF+LW~*q3VH|!NmP|KP|ovChyO?Jyjlf6YpG3#&^NK8T1*x z`FAc^#XE;{$zKn*qDs8|AeSsf)%XfHZzgSu_rh%lyEs>%J>y++!(5j{g;3_Pyi@o% z-h0cF?_%L;$U}NAEJESREYO~cd-Avfz>;L*P;g2rPzqt@QUxEZhTxi zpP%NED$0rC9mdO0De3<2E>`a~ZbO-*EB=TI@EJ>J*OkOUyTul`O? z<%~g8MxLl*mwb$>@!?nSPFmD}PgvuUzoQm7X7ruou@qKX0 zZER!YkAo+oc6F;j^e1-vawlE#7`RV-{88V_}98J_nYdG<+FsLXG%V*o*4% zTVZr1eTR>OsVEDd4lhQ%_+oeq>c&^XO{fyz0^dR9_%3L>gMPt>z{#i?9}SN|h4@ss z6nXKnce*4W6;tws8;puLoQ*=|Pvc@kww6%ETAKeIBBZ@G0?2f^UP~7Gl6x!GxC?-}p?}k4o`TuduzKetactL^787 z8G8OoJL99F7kThStu8rWGvgee__j-eJ7{No(iUQPhwTgB3CF$5oPdvd&n4f#Paom) zx?D2m1DB-WXTkeX5xyBd^SUOu9(r~;n~|B2f0k==}Q)Pv9Z*d?w{s0%(0wxb5T zeCm=1Q3CIS?Sm6~hyfo3PeoDqT(}Vlz8&_V7<@l`;xp=t?}3Xyr(f`ea2=||&-#LX zM5Xvn=}iJ0+a zP=02;_(YhA!p1Y7z!J1o<$-l5g!BeD{}<*)(!H=8_2MgG0#7~f#Am`!Q6%}@7PqWJ z@%S#-hf?uLR=2!@((#Elw;aTyfW7!Uc)r6e75IMmrQ0nn`1&BXyo0vlyW!U%ZVBOi z?e!zw@*e6Xy$6mT<(4LVH2fM3D9^huXQOEHC&OkGi|>Xu-UXb44}p_VCO#S_k8w*6 zz8sc~rA)ks_l`b}YVlq0=5fS{Z-%FjcS|w87{>CR^E`ZiBz2$UmQvnB-3rg*oxAb) zGWa%1!uP-;-j$hyuYt3p+>(aRf!k04K5~j%)}wNKI}D!cmK3}fhVJ8*N_;20Iod6D zd^0?Bnp>jqX>i{dw^ZX3dEex3`-Ork5}d?&Nyf zrNo9}Z|9mAycm@}#Pt){fHG^i#!}>#1Cjed&Z*&_Q4_unzKXK&QJ1;p2vqg}>F`w) zj$gc*v4oO01j)s)9M$3#YfwG@G58tk!*7G5E+_uSxYh*kMHNp3$;&XOn04W=htsZb z^Q@*IIS#Hsxli*99QY~n;zz9^9+dG+kj5r_7QPo+uXIcQQ$ZT1;f4GM!(&l9UNIMS z;;({tA@4@6!@#GJyCq0A!M9KXehb`+a$e@yGH`kc+Z}!;OhI+6L9zhmqAq+sycV@{ zkKc{(5mb$@hp(eB{9CXOdGXuen5!78_z7?(>gL|y1h@dD@LgLv%txL00=O0x;w#_= zREuwbn^8R9C3V1WP&vLIhF;CM#fQV0C<~tePeD!iCGaAY!S`;8H=->3UGOQC$aU;Z zumd%4?fpI2k8*wplAqy(YuHBcli*<}oa<&sz(uHw>w6jS&!`4}1-uhw;H%*#)I|Ol z;D=}{{xfJVWj^6LRWO{2YPhx&1LvS9u8kzaC8!R67A!&yoLjAdccCc!z3>y%%{kgO z=;58w9?pZt!vj$vekME~m2-Tq-u<3~qS?Qzcexj%OuTxx`aP%Z(tM`k) zi~8{DebhgpR`xIIebbSsAFtj8Js;&TZ>#qNUxCt@yVUz>>rgNA!=8V8T3}BL>}i2L zEwHBr_O!sB7TD7Qds^VPZh@A+`;I%G(D|UwN}Yex`CG@4rLSkc&RII+bROB|i}ND= z?x|Qxt}{z#zRn_@SL>|M`Jm25ov-NZ(z#7%@VmbCjn_F<=M0^5 zbS}`DrE|H?i*&BhS)ubmoy|Jm)7h`n{+@5Wp*o{`_@t#hr;8l4+; zw(0EB`464W_x1MG8Le}s&N(_4={!ScfzGRS-lp>rolon0MQ4}Jf9M?08KRHdNS!lu zrt18yx2ylQ@)O?j^@obffIE%GWk~<||)2?3u58?XYLQ z8fwP)_tMX?9+T}&S+dfrz0^uQDj;PAuN<0}pPem_TIQ|DKX-}ugzS|omzWEy!Myb+X*5`MJw^{ZsxD?bDmJl%(w3Z1rcQ z_Lml<%uZS~JM~zj%=hgJytzj&$@8wt&pvv^axbsHl227y%8C`|tje3GzgB7Pa&P{H z{76H6vS?Ypch!>Ila^nwY3#^UqzjoLU%3a+B@YmHHnm^5RTh!v+ZQZZwlaIL_4uKb%H?a|xdn0wF;F93ICf5UR_dyiIa+UM z(MX~HXY+FT(3gIKYI(nLdWdE2@};~QDRsp%t#uCPZ^}HH!L*F=yD(dOdlrw7vZZ7% zIX`=+^e~HWECqhx^=qGi&t@;rT9~(Nxz-=D(UF$Ba<+PDnn;uKG|i$VxvR3}IrSI8 z`u^Ia{?Z2O;}(UKWoP6sVdyogwp4>)c2*W$zf$B)w!9@-`sZ^CXxkji+=69;Bk8ih z*4Oe}vOQJxfO=yTOHNa%`bhMR3f>6v|Fw6uA&y;T_|$GSZE+1nG-|ci+BOll-E1p1 z*4b{lv%93QZNu)i8$_LCXEK}EOmdr#X;#z*iV{H~f=H~j+?(Wnf91z2`5_W5NI;QT zD&(ILqy$k3Vr_&9KIh&unaQ+uTSaVb2Htsc-gEDJ?s?ApzUQ8N+;cUChxab|3+`(# zexA7M6#RZQS16^)*WA~qve^2VT60_YuB&?xfkaj3$@k$a=v#JUmC}#AfbUYGwfk1% zgtTe951o8~zWxQ(uEweB;1gT=y08U@Mi28y1;5*;IZuw$b5G{Cv&BN5?)rANT+HS# zme8BaE_1I|6{cRXr{a-RF`K$Tud;L1srmTG^fiooBcjmKe0(HYa)~%Z+dqLg^^zXi zz3FObXw=L#&k%HiPZiVN#o?HrUVVD?ffPS47pN6Cg{HlrAwSsR%hQq|wfb-=T|ANA zOd*?|UcLVWA)kl;R<^v5^$w&xf0kNfse+Cke%eGeXUiL2O2yaVX_*epIczG1Cy}6I zNPDG1F1=bV=Deedc!HFB7A2G(2g~cO2b@I~!2Un(>oaN3H!{@5o)$DPgfOIS9ItF* zFGKk1UGH?WHr0{qsBPBfLzOaL!JuPLo;_Nm47757=Spd#$O6Y`JJbRTVW`NH2Wb9x z&61k?ni<9w2M>7G-8?nt`&V=(po0cO=gBvS>&J|oJH4x%oA`^%f}0gxul&7-e{lVV+@~ z;nNI%#PF94f6wq`hJn9%_U~kPnjz2dI}CM(J%-OSoH0De`h6S2dl{Z#m}B^LhEFrR z%y7VP#&AEsZjg44-HC0>c@@>sY^UWOxU|D8n-h zHyCa+tTTLy;ZGR8S;lq$b=;lIr}*sJ#dLWshgGk)TdunqDniz;^d@dpv6lMG zt~Ou6vi0z8`9cBrS*bj}VCm`B-CL2hg1hfC_On~irre!&AJ1aPVQ;Hl@_~i=l6$|4 zt14&nN63d>t*%nujF5v1HSV6uz${K6bHB8QV zwV70DjV~7Xbg_Jitn8jK*Ht`S30Cr0Z*1%y9oap4UrlNE9IWB#{XHQ!dpeKl9V6K^ z?k``0VT=;p`*^++GWNyuj%O?vclOmLx9!-WZw{>O>W_JP+S|F(>o*}6y*l(Vzviv> z*GlUs5%Le#HeC=cR&DM%CtX@k@pP%NcnEoU@7b?$P{_06*6y5-ohLnQIa4e=j`e_7 z%9hsVJ1wu_S~qY9PY!u?v|m_Ht*yfci_DvM-moC=^NwL$Vd%E7A}5b|S}ZsVx$X2C zn1`Fd$#Xk;x?%aQnta^TZ>GwroEIvDT(e*~Rl1a4Uwgbze3X!nc{LmEn>1^CYi?XP zr*vuSLILmp+_0eC+3^~CCwh9?zx4|&Hs7;wEEc2bVm<{MDNn!UzR!eVzKFLp=sPtT zPybjY4KLq&Df<(`vb_qo7i{h zBKAiD-UNIK@&ts3OriT0@L|X)$PndqU>M?qbWz^UV$UT=3UU^55^@CcVaTmAPI`gza;~2O9l`d=r^Rc*nPw&6yaCVUwZ)i zhog@F==F5V$K~G@7+5)0-O6#>_>>@9$R79jX-JjnsJen>Bxk~oF zb^4+3(coq(S4s!D!*e?;hhMvumBS0yv~qafIh?+7c!xI>t}r&s>LmkjI|c;&t`D8| zi_uQJlk7AULFuY9lUP10Y(=c76}J*r(i&JpYh+EVsWr2R?X&%Mz~*e6*u`)A00|)} zWCUKQ3N@iFGz3-X3O%7O41}RD62`(zAfiw7ivf`nLt-Z$U6p%tvSc*t7 zDJ~_XjKoV-sV+67rW7_KX2MLG8MA8E%!Hk>dAn*0cGvFPLwjsbZQ}SH&IvnFC+;L2 z-l;haM{v4M-x)e%XX>D1eINNTfCzqp6T(7Nh@+=Gdf5;J^s$frjfE+C=SR=NVif&K zqE9ukfgW|yo1r)sry^bCl=VQbu)wn*FG=Gx(Qv>k6J z+dO*TXbbIbyWbwR$L(pGbo?C-OhnyL;yX34A#}Q(KG+z83j!uM@DK$HNpMgD19*T8 z`3^3902?D%nY3rHpry;N!0k1JIn*g^Nuv-Pcbuion z$EwTn06dSt^aNbbz_t&32f%m;oJYWV47?}6d5i ziQxkunO88LVfAciAWV<$%n|Avr8Zz;Fy4C%|$>=H;qP2!6+l!@B=-?-Hc0 z)R%_RSei-%*UaI1J%8Zg5e-?8yK-M1%42yd69o?=A`RRF4&ZIn*L<#@MO+`txc=4b zP~RH3@k^tZ#x9Lq8n-lRo02N^q=7V&Celpufuj)kiGiC8c&W=xS(SV8Kpx2xc_#am zfD%$7N=!*88KtV!m8PO9J!PPbl!-D^d}=@qsS!1%Ce(~tRqJX~Rn?w4P)F)SovA)8 zpoO%E7Sj^&>nc3Esi|5|8)zeKqRlj)9?(O2M33nSJ)>9ky57`Py{8ZKkv_r5`;34Q zG9pIINMQV{h=!&c2?IpI#F()dh`|37ZVsxOO;a^{=D-}86LV(ztbi3lj*TJ1W~{1J zx0;q}^^j{v$h0%dha4NSBX-PAAa_;my4|!@yJrvVkv*|zw$BMTAt&O*oP?8cs!rW$ zI;zui2F?i4hFIh9+&}n{4{;VkjKvUN8D!|X&_sUjAvceN2{N+}Sve#|kdqULzN%P9 z+^NXK1960CL#&1I>_?1i{7sYD-k4wd6;25&Q6;V<6<(<+4LZjuePyVOm8pV9$*7zf zR-FHljw{&6_pkOu^_PUk;Hgrv@?oCWlNJHRG78 zc+6A{Q!u+`-yE7_bBdYRZ*iE5qnL@47H`$8h9y{CtB)CZjQN;gF6Qj89kt_j5;I)Q zZd_rG!vlZ`zJf%0|F$OwFlR>KWnNY%VLV5}^)s5$yYMLjU&_FbRQS+L^zyWuiCtDk z;AH}4yxi$`qbQ6xiXxKYh@~VVDGHAlFh~0_H}ja2M|3WZ;+Y|CI}!M?0Ppo-zO5m{ z50TS3, Brendan Forster , Hari Juturu +// Adapted from DefinitelyTyped: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/keytar/index.d.ts + +/** + * Get the stored password for the service and account. + * + * @param service The string service name. + * @param account The string account name. + * + * @returns A promise for the password string. + */ +export declare function getPassword(service: string, account: string): Promise; + +/** + * Add the password for the service and account to the keychain. + * + * @param service The string service name. + * @param account The string account name. + * @param password The string password. + * + * @returns A promise for the set password completion. + */ +export declare function setPassword(service: string, account: string, password: string): Promise; + +/** + * Delete the stored password for the service and account. + * + * @param service The string service name. + * @param account The string account name. + * + * @returns A promise for the deletion status. True on success. + */ +export declare function deletePassword(service: string, account: string): Promise; + +/** + * Find a password for the service in the keychain. + * + * @param service The string service name. + * + * @returns A promise for the password string. + */ +export declare function findPassword(service: string): Promise; + +/** + * Find all accounts and passwords for `service` in the keychain. + * + * @param service The string service name. + * + * @returns A promise for the array of found credentials. + */ +export declare function findCredentials(service: string): Promise>; diff --git a/lib/authentication/SecureStorage/keytar/lib/keytar.js b/lib/authentication/SecureStorage/keytar/lib/keytar.js new file mode 100644 index 000000000..027456c56 --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/lib/keytar.js @@ -0,0 +1,43 @@ +var keytar = require('../build/Release/keytar.node') + +function checkRequired(val, name) { + if (!val || val.length <= 0) { + throw new Error(name + ' is required.'); + } +} + +module.exports = { + getPassword: function (service, account) { + checkRequired(service, 'Service') + checkRequired(account, 'Account') + + return keytar.getPassword(service, account) + }, + + setPassword: function (service, account, password) { + checkRequired(service, 'Service') + checkRequired(account, 'Account') + checkRequired(password, 'Password') + + return keytar.setPassword(service, account, password) + }, + + deletePassword: function (service, account) { + checkRequired(service, 'Service') + checkRequired(account, 'Account') + + return keytar.deletePassword(service, account) + }, + + findPassword: function (service) { + checkRequired(service, 'Service') + + return keytar.findPassword(service) + }, + + findCredentials: function (service) { + checkRequired(service, 'Service') + + return keytar.findCredentials(service) + } +} diff --git a/lib/authentication/SecureStorage/keytar/package.json b/lib/authentication/SecureStorage/keytar/package.json new file mode 100644 index 000000000..12cbafcc4 --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/package.json @@ -0,0 +1,66 @@ +{ + "main": "./lib/keytar.js", + "typings": "keytar.d.ts", + "name": "keytar", + "description": "Bindings to native Mac/Linux/Windows password APIs", + "version": "7.9.0", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/atom/node-keytar.git" + }, + "bugs": { + "url": "https://github.com/atom/node-keytar/issues" + }, + "homepage": "http://atom.github.io/node-keytar", + "keywords": [ + "keychain", + "password", + "passwords", + "credential", + "credentials", + "vault", + "credential vault" + ], + "files": [ + "lib", + "src", + "binding.gyp", + "keytar.d.ts" + ], + "types": "./keytar.d.ts", + "scripts": { + "install": "prebuild-install || npm run build", + "build": "node-gyp rebuild", + "lint": "npm run cpplint", + "cpplint": "node-cpplint --filters legal-copyright,build-include,build-namespaces src/*.cc", + "test": "npm run lint && npm rebuild && mocha --require babel-core/register spec/", + "prebuild-napi-x64": "prebuild -t 3 -r napi -a x64 --strip", + "prebuild-napi-ia32": "prebuild -t 3 -r napi -a ia32 --strip", + "prebuild-napi-arm64": "prebuild -t 3 -r napi -a arm64 --strip", + "prebuild-napi-armv7l": "prebuild -t 3 -r napi -a armv7l --strip", + "upload": "node ./script/upload.js" + }, + "devDependencies": { + "babel-core": "^6.26.3", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "chai": "^4.2.0", + "mocha": "^9.2.0", + "node-cpplint": "~0.4.0", + "node-gyp": "^8.4.1", + "prebuild": "^11.0.2" + }, + "dependencies": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + }, + "binary": { + "napi_versions": [ + 3 + ] + }, + "config": { + "runtime": "napi", + "target": 3 + } +} diff --git a/lib/authentication/SecureStorage/keytar/src/async.cc b/lib/authentication/SecureStorage/keytar/src/async.cc new file mode 100644 index 000000000..aef449add --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/src/async.cc @@ -0,0 +1,242 @@ +#include +#include + +#include "napi.h" +#include "keytar.h" +#include "async.h" + +using keytar::KEYTAR_OP_RESULT; + +SetPasswordWorker::SetPasswordWorker( + const std::string& service, + const std::string& account, + const std::string& password, + const Napi::Env &env +) : AsyncWorker(env), + service(service), + account(account), + password(password), + deferred(Napi::Promise::Deferred::New(env)) {} + +SetPasswordWorker::~SetPasswordWorker() {} + +Napi::Promise SetPasswordWorker::Promise() { + return deferred.Promise(); +} + +void SetPasswordWorker::Execute() { + std::string error; + KEYTAR_OP_RESULT result = keytar::SetPassword(service, + account, + password, + &error); + if (result == keytar::FAIL_ERROR) { + SetError(error.c_str()); + } +} + +void SetPasswordWorker::OnOK() { + Napi::HandleScope scope(Env()); + deferred.Resolve(Env().Undefined()); +} + +void SetPasswordWorker::OnError(Napi::Error const &error) { + Napi::HandleScope scope(Env()); + deferred.Reject(error.Value()); +} + + +GetPasswordWorker::GetPasswordWorker( + const std::string& service, + const std::string& account, + const Napi::Env &env +) : AsyncWorker(env), + service(service), + account(account), + deferred(Napi::Promise::Deferred::New(env)) {} + +GetPasswordWorker::~GetPasswordWorker() {} + +Napi::Promise GetPasswordWorker::Promise() { + return deferred.Promise(); +} + +void GetPasswordWorker::Execute() { + std::string error; + KEYTAR_OP_RESULT result = keytar::GetPassword(service, + account, + &password, + &error); + if (result == keytar::FAIL_ERROR) { + SetError(error.c_str()); + } else if (result == keytar::FAIL_NONFATAL) { + success = false; + } else { + success = true; + } +} + +void GetPasswordWorker::OnOK() { + Napi::HandleScope scope(Env()); + Napi::Value val = Env().Null(); + if (success) { + val = Napi::String::New(Env(), password.data(), + password.length()); + } + deferred.Resolve(val); +} + +void GetPasswordWorker::OnError(Napi::Error const &error) { + Napi::HandleScope scope(Env()); + deferred.Reject(error.Value()); +} + +DeletePasswordWorker::DeletePasswordWorker( + const std::string& service, + const std::string& account, + const Napi::Env &env +) : AsyncWorker(env), + service(service), + account(account), + deferred(Napi::Promise::Deferred::New(env)) {} + +DeletePasswordWorker::~DeletePasswordWorker() {} + +Napi::Promise DeletePasswordWorker::Promise() { + return deferred.Promise(); +} + +void DeletePasswordWorker::Execute() { + std::string error; + KEYTAR_OP_RESULT result = keytar::DeletePassword(service, account, &error); + if (result == keytar::FAIL_ERROR) { + SetError(error.c_str()); + } else if (result == keytar::FAIL_NONFATAL) { + success = false; + } else { + success = true; + } +} + +void DeletePasswordWorker::OnOK() { + Napi::HandleScope scope(Env()); + deferred.Resolve(Napi::Boolean::New(Env(), success)); +} + +void DeletePasswordWorker::OnError(Napi::Error const &error) { + Napi::HandleScope scope(Env()); + deferred.Reject(error.Value()); +} + +FindPasswordWorker::FindPasswordWorker( + const std::string& service, + const Napi::Env &env +) : AsyncWorker(env), + service(service), + deferred(Napi::Promise::Deferred::New(env)) {} + +FindPasswordWorker::~FindPasswordWorker() {} + +Napi::Promise FindPasswordWorker::Promise() { + return deferred.Promise(); +} + +void FindPasswordWorker::Execute() { + std::string error; + KEYTAR_OP_RESULT result = keytar::FindPassword(service, + &password, + &error); + if (result == keytar::FAIL_ERROR) { + SetError(error.c_str()); + } else if (result == keytar::FAIL_NONFATAL) { + success = false; + } else { + success = true; + } +} + +void FindPasswordWorker::OnOK() { + Napi::HandleScope scope(Env()); + Napi::Value val = Env().Null(); + if (success) { + val = Napi::String::New(Env(), password.data(), + password.length()); + } + deferred.Resolve(val); +} + +void FindPasswordWorker::OnError(Napi::Error const &error) { + Napi::HandleScope scope(Env()); + deferred.Reject(error.Value()); +} + +FindCredentialsWorker::FindCredentialsWorker( + const std::string& service, + const Napi::Env &env +) : AsyncWorker(env), + service(service), + deferred(Napi::Promise::Deferred::New(env)) {} + +FindCredentialsWorker::~FindCredentialsWorker() {} + +Napi::Promise FindCredentialsWorker::Promise() { + return deferred.Promise(); +} + +void FindCredentialsWorker::Execute() { + std::string error; + KEYTAR_OP_RESULT result = keytar::FindCredentials(service, + &credentials, + &error); + if (result == keytar::FAIL_ERROR) { + SetError(error.c_str()); + } else if (result == keytar::FAIL_NONFATAL) { + success = false; + } else { + success = true; + } +} + +void FindCredentialsWorker::OnOK() { + Napi::HandleScope scope(Env()); + Napi::Env env = Env(); + + if (success) { + Napi::Array val = Napi::Array::New(env, credentials.size()); + unsigned int idx = 0; + std::vector::iterator it; + for (it = credentials.begin(); it != credentials.end(); it++) { + keytar::Credentials cred = *it; + Napi::Object obj = Napi::Object::New(env); + + Napi::String account = Napi::String::New(env, + cred.first.data(), + cred.first.length()); + + Napi::String password = Napi::String::New(env, + cred.second.data(), + cred.second.length()); + +#ifndef _WIN32 +#pragma GCC diagnostic ignored "-Wunused-result" +#endif + obj.Set("account", account); +#ifndef _WIN32 +#pragma GCC diagnostic ignored "-Wunused-result" +#endif + obj.Set("password", password); + + (val).Set(idx, obj); + ++idx; + } + + deferred.Resolve(val); + } else { + deferred.Resolve(Napi::Array::New(env, 0)); + } +} + +void FindCredentialsWorker::OnError(Napi::Error const &error) { + Napi::HandleScope scope(Env()); + deferred.Reject(error.Value()); +} diff --git a/lib/authentication/SecureStorage/keytar/src/async.h b/lib/authentication/SecureStorage/keytar/src/async.h new file mode 100644 index 000000000..e29928cec --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/src/async.h @@ -0,0 +1,103 @@ +#ifndef SRC_ASYNC_H_ +#define SRC_ASYNC_H_ + +#include +#include "napi.h" + +#include "credentials.h" + +class SetPasswordWorker : public Napi::AsyncWorker { + public: + SetPasswordWorker(const std::string& service, const std::string& account, const std::string& password, + const Napi::Env &env); + + ~SetPasswordWorker(); + + void Execute(); + void OnOK(); + void OnError(Napi::Error const &error); + Napi::Promise Promise(); + + private: + const std::string service; + const std::string account; + const std::string password; + Napi::Promise::Deferred deferred; +}; + +class GetPasswordWorker : public Napi::AsyncWorker { + public: + GetPasswordWorker(const std::string& service, const std::string& account, + const Napi::Env &env); + + ~GetPasswordWorker(); + + void Execute(); + void OnOK(); + void OnError(Napi::Error const &error); + Napi::Promise Promise(); + + private: + const std::string service; + const std::string account; + std::string password; + bool success; + const Napi::Promise::Deferred deferred; +}; + +class DeletePasswordWorker : public Napi::AsyncWorker { + public: + DeletePasswordWorker(const std::string& service, const std::string& account, + const Napi::Env &env); + + ~DeletePasswordWorker(); + + void Execute(); + void OnOK(); + void OnError(Napi::Error const &error); + Napi::Promise Promise(); + + private: + const std::string service; + const std::string account; + bool success; + Napi::Promise::Deferred deferred; +}; + +class FindPasswordWorker : public Napi::AsyncWorker { + public: + FindPasswordWorker(const std::string& service, const Napi::Env &env); + + ~FindPasswordWorker(); + + void Execute(); + void OnOK(); + void OnError(Napi::Error const &error); + Napi::Promise Promise(); + + private: + const std::string service; + std::string password; + bool success; + const Napi::Promise::Deferred deferred; +}; + +class FindCredentialsWorker : public Napi::AsyncWorker { + public: + FindCredentialsWorker(const std::string& service, const Napi::Env &env); + + ~FindCredentialsWorker(); + + void Execute(); + void OnOK(); + void OnError(Napi::Error const &error); + Napi::Promise Promise(); + + private: + const std::string service; + std::vector credentials; + bool success; + const Napi::Promise::Deferred deferred; +}; + +#endif // SRC_ASYNC_H_ diff --git a/lib/authentication/SecureStorage/keytar/src/credentials.h b/lib/authentication/SecureStorage/keytar/src/credentials.h new file mode 100644 index 000000000..99e071b16 --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/src/credentials.h @@ -0,0 +1,13 @@ +#ifndef SRC_CREDENTIALS_H_ +#define SRC_CREDENTIALS_H_ + +#include +#include + +namespace keytar { + +typedef std::pair Credentials; + +} + +#endif // SRC_CREDENTIALS_H_ diff --git a/lib/authentication/SecureStorage/keytar/src/keytar.h b/lib/authentication/SecureStorage/keytar/src/keytar.h new file mode 100644 index 000000000..1a6d3ada0 --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/src/keytar.h @@ -0,0 +1,41 @@ +#ifndef SRC_KEYTAR_H_ +#define SRC_KEYTAR_H_ + +#include +#include + +#include "credentials.h" + +namespace keytar { + +enum KEYTAR_OP_RESULT { + SUCCESS, + FAIL_ERROR, + FAIL_NONFATAL +}; + +KEYTAR_OP_RESULT SetPassword(const std::string& service, + const std::string& account, + const std::string& password, + std::string* error); + +KEYTAR_OP_RESULT GetPassword(const std::string& service, + const std::string& account, + std::string* password, + std::string* error); + +KEYTAR_OP_RESULT DeletePassword(const std::string& service, + const std::string& account, + std::string* error); + +KEYTAR_OP_RESULT FindPassword(const std::string& service, + std::string* password, + std::string* error); + +KEYTAR_OP_RESULT FindCredentials(const std::string& service, + std::vector*, + std::string* error); + +} // namespace keytar + +#endif // SRC_KEYTAR_H_ diff --git a/lib/authentication/SecureStorage/keytar/src/keytar_mac.cc b/lib/authentication/SecureStorage/keytar/src/keytar_mac.cc new file mode 100644 index 000000000..93741bd62 --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/src/keytar_mac.cc @@ -0,0 +1,296 @@ +#include +#include "keytar.h" +#include "credentials.h" + + +namespace keytar { + +/** + * Converts a CFString to a std::string + * + * This either uses CFStringGetCStringPtr or (if that fails) + * CFStringGetCString, trying to be as efficient as possible. + */ +const std::string CFStringToStdString(CFStringRef cfstring) { + const char* cstr = CFStringGetCStringPtr(cfstring, kCFStringEncodingUTF8); + + if (cstr != NULL) { + return std::string(cstr); + } + + CFIndex length = CFStringGetLength(cfstring); + // Worst case: 2 bytes per character + NUL + CFIndex cstrPtrLen = length * 2 + 1; + char* cstrPtr = static_cast(malloc(cstrPtrLen)); + + Boolean result = CFStringGetCString(cfstring, + cstrPtr, + cstrPtrLen, + kCFStringEncodingUTF8); + + std::string stdstring; + if (result) { + stdstring = std::string(cstrPtr); + } + + free(cstrPtr); + + return stdstring; +} + +const std::string errorStatusToString(OSStatus status) { + std::string errorStr; + CFStringRef errorMessageString = SecCopyErrorMessageString(status, NULL); + + const char* errorCStringPtr = CFStringGetCStringPtr(errorMessageString, + kCFStringEncodingUTF8); + if (errorCStringPtr) { + errorStr = std::string(errorCStringPtr); + } else { + errorStr = std::string("An unknown error occurred."); + } + + CFRelease(errorMessageString); + return errorStr; +} + +KEYTAR_OP_RESULT AddPassword(const std::string& service, + const std::string& account, + const std::string& password, + std::string* error) { + OSStatus status = SecKeychainAddGenericPassword(NULL, + service.length(), + service.data(), + account.length(), + account.data(), + password.length(), + password.data(), + NULL); + + if (status != errSecSuccess) { + *error = errorStatusToString(status); + return FAIL_ERROR; + } + + return SUCCESS; +} + +KEYTAR_OP_RESULT SetPassword(const std::string& service, + const std::string& account, + const std::string& password, + std::string* error) { + SecKeychainItemRef item; + OSStatus result = SecKeychainFindGenericPassword(NULL, + service.length(), + service.data(), + account.length(), + account.data(), + NULL, + NULL, + &item); + + if (result == errSecItemNotFound) { + return AddPassword(service, account, password, error); + } else if (result != errSecSuccess) { + *error = errorStatusToString(result); + return FAIL_ERROR; + } + + result = SecKeychainItemModifyAttributesAndData(item, + NULL, + password.length(), + password.data()); + CFRelease(item); + if (result != errSecSuccess) { + *error = errorStatusToString(result); + return FAIL_ERROR; + } + + return SUCCESS; +} + +KEYTAR_OP_RESULT GetPassword(const std::string& service, + const std::string& account, + std::string* password, + std::string* error) { + void *data; + UInt32 length; + OSStatus status = SecKeychainFindGenericPassword(NULL, + service.length(), + service.data(), + account.length(), + account.data(), + &length, + &data, + NULL); + + if (status == errSecItemNotFound) { + return FAIL_NONFATAL; + } else if (status != errSecSuccess) { + *error = errorStatusToString(status); + return FAIL_ERROR; + } + + *password = std::string(reinterpret_cast(data), length); + SecKeychainItemFreeContent(NULL, data); + return SUCCESS; +} + +KEYTAR_OP_RESULT DeletePassword(const std::string& service, + const std::string& account, + std::string* error) { + SecKeychainItemRef item; + OSStatus status = SecKeychainFindGenericPassword(NULL, + service.length(), + service.data(), + account.length(), + account.data(), + NULL, + NULL, + &item); + if (status == errSecItemNotFound) { + // Item could not be found, so already deleted. + return FAIL_NONFATAL; + } else if (status != errSecSuccess) { + *error = errorStatusToString(status); + return FAIL_ERROR; + } + + status = SecKeychainItemDelete(item); + CFRelease(item); + if (status != errSecSuccess) { + *error = errorStatusToString(status); + return FAIL_ERROR; + } + + return SUCCESS; +} + +KEYTAR_OP_RESULT FindPassword(const std::string& service, + std::string* password, + std::string* error) { + SecKeychainItemRef item; + void *data; + UInt32 length; + + OSStatus status = SecKeychainFindGenericPassword(NULL, + service.length(), + service.data(), + 0, + NULL, + &length, + &data, + &item); + if (status == errSecItemNotFound) { + return FAIL_NONFATAL; + } else if (status != errSecSuccess) { + *error = errorStatusToString(status); + return FAIL_ERROR; + } + + *password = std::string(reinterpret_cast(data), length); + SecKeychainItemFreeContent(NULL, data); + CFRelease(item); + return SUCCESS; +} + +Credentials getCredentialsForItem(CFDictionaryRef item) { + CFStringRef service = (CFStringRef) CFDictionaryGetValue(item, + kSecAttrService); + CFStringRef account = (CFStringRef) CFDictionaryGetValue(item, + kSecAttrAccount); + + CFMutableDictionaryRef query = CFDictionaryCreateMutable( + NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + CFDictionaryAddValue(query, kSecAttrService, service); + CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword); + CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne); + CFDictionaryAddValue(query, kSecReturnAttributes, kCFBooleanTrue); + CFDictionaryAddValue(query, kSecReturnData, kCFBooleanTrue); + CFDictionaryAddValue(query, kSecAttrAccount, account); + + Credentials cred; + CFTypeRef result = NULL; + OSStatus status = SecItemCopyMatching((CFDictionaryRef) query, &result); + + CFRelease(query); + + if (status == errSecSuccess) { + CFDataRef passwordData = (CFDataRef) CFDictionaryGetValue( + (CFDictionaryRef) result, + CFSTR("v_Data")); + CFStringRef password = CFStringCreateFromExternalRepresentation( + NULL, + passwordData, + kCFStringEncodingUTF8); + + cred = Credentials( + CFStringToStdString(account), + CFStringToStdString(password)); + + CFRelease(password); + } + + if (result != NULL) { + CFRelease(result); + } + + return cred; +} + +KEYTAR_OP_RESULT FindCredentials(const std::string& service, + std::vector* credentials, + std::string* error) { + CFStringRef serviceStr = CFStringCreateWithCString( + NULL, + service.c_str(), + kCFStringEncodingUTF8); + + CFMutableDictionaryRef query = CFDictionaryCreateMutable( + NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword); + CFDictionaryAddValue(query, kSecAttrService, serviceStr); + CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitAll); + CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue); + CFDictionaryAddValue(query, kSecReturnAttributes, kCFBooleanTrue); + + CFTypeRef result = NULL; + OSStatus status = SecItemCopyMatching((CFDictionaryRef) query, &result); + + CFRelease(serviceStr); + CFRelease(query); + + if (status == errSecSuccess) { + CFArrayRef resultArray = (CFArrayRef) result; + int resultCount = CFArrayGetCount(resultArray); + + for (int idx = 0; idx < resultCount; idx++) { + CFDictionaryRef item = (CFDictionaryRef) CFArrayGetValueAtIndex( + resultArray, + idx); + + Credentials cred = getCredentialsForItem(item); + credentials->push_back(cred); + } + } else if (status == errSecItemNotFound) { + return FAIL_NONFATAL; + } else { + *error = errorStatusToString(status); + return FAIL_ERROR; + } + + if (result != NULL) { + CFRelease(result); + } + + return SUCCESS; +} + +} // namespace keytar diff --git a/lib/authentication/SecureStorage/keytar/src/keytar_posix.cc b/lib/authentication/SecureStorage/keytar/src/keytar_posix.cc new file mode 100644 index 000000000..3a5ba7ca0 --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/src/keytar_posix.cc @@ -0,0 +1,184 @@ +#include "keytar.h" + +// This is needed to make the builds on Ubuntu 14.04 / libsecret v0.16 work. +// The API we use has already stabilized. +#define SECRET_API_SUBJECT_TO_CHANGE +#include +#include +#include + +namespace keytar { + +namespace { + +static const SecretSchema schema = { + "org.freedesktop.Secret.Generic", SECRET_SCHEMA_NONE, { + { "service", SECRET_SCHEMA_ATTRIBUTE_STRING }, + { "account", SECRET_SCHEMA_ATTRIBUTE_STRING } + } +}; + +} // namespace + +KEYTAR_OP_RESULT SetPassword(const std::string& service, + const std::string& account, + const std::string& password, + std::string* errStr) { + GError* error = NULL; + + secret_password_store_sync( + &schema, // The schema. + SECRET_COLLECTION_DEFAULT, // Default collection. + (service + "/" + account).c_str(), // The label. + password.c_str(), // The password. + NULL, // Cancellable. (unneeded) + &error, // Reference to the error. + "service", service.c_str(), + "account", account.c_str(), + NULL); // End of arguments. + + if (error != NULL) { + *errStr = std::string(error->message); + g_error_free(error); + return FAIL_ERROR; + } + + return SUCCESS; +} + +KEYTAR_OP_RESULT GetPassword(const std::string& service, + const std::string& account, + std::string* password, + std::string* errStr) { + GError* error = NULL; + + gchar* raw_password = secret_password_lookup_sync( + &schema, // The schema. + NULL, // Cancellable. (unneeded) + &error, // Reference to the error. + "service", service.c_str(), + "account", account.c_str(), + NULL); // End of arguments. + + if (error != NULL) { + *errStr = std::string(error->message); + g_error_free(error); + return FAIL_ERROR; + } + + if (raw_password == NULL) + return FAIL_NONFATAL; + + *password = raw_password; + secret_password_free(raw_password); + return SUCCESS; +} + +KEYTAR_OP_RESULT DeletePassword(const std::string& service, + const std::string& account, + std::string* errStr) { + GError* error = NULL; + + gboolean result = secret_password_clear_sync( + &schema, // The schema. + NULL, // Cancellable. (unneeded) + &error, // Reference to the error. + "service", service.c_str(), + "account", account.c_str(), + NULL); // End of arguments. + + if (error != NULL) { + *errStr = std::string(error->message); + g_error_free(error); + return FAIL_ERROR; + } + + if (!result) + return FAIL_NONFATAL; + + return SUCCESS; +} + +KEYTAR_OP_RESULT FindPassword(const std::string& service, + std::string* password, + std::string* errStr) { + GError* error = NULL; + + gchar* raw_password = secret_password_lookup_sync( + &schema, // The schema. + NULL, // Cancellable. (unneeded) + &error, // Reference to the error. + "service", service.c_str(), + NULL); // End of arguments. + + if (error != NULL) { + *errStr = std::string(error->message); + g_error_free(error); + return FAIL_ERROR; + } + + if (raw_password == NULL) + return FAIL_NONFATAL; + + *password = raw_password; + secret_password_free(raw_password); + return SUCCESS; +} + +KEYTAR_OP_RESULT FindCredentials(const std::string& service, + std::vector* credentials, + std::string* errStr) { + GError* error = NULL; + + GHashTable* attributes = g_hash_table_new(NULL, NULL); + g_hash_table_replace(attributes, + (gpointer) "service", + (gpointer) service.c_str()); + + GList* items = secret_service_search_sync( + NULL, + &schema, // The schema. + attributes, + static_cast(SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | + SECRET_SEARCH_LOAD_SECRETS), + NULL, // Cancellable. (unneeded) + &error); // Reference to the error. + + g_hash_table_destroy(attributes); + + if (error != NULL) { + *errStr = std::string(error->message); + g_error_free(error); + return FAIL_ERROR; + } + + GList* current = items; + for (current = items; current != NULL; current = current->next) { + SecretItem* item = reinterpret_cast(current->data); + + GHashTable* itemAttrs = secret_item_get_attributes(item); + char* account = strdup( + reinterpret_cast(g_hash_table_lookup(itemAttrs, "account"))); + + SecretValue* secret = secret_item_get_secret(item); + char* password = strdup(secret_value_get_text(secret)); + + if (account == NULL || password == NULL) { + if (account) + free(account); + + if (password) + free(password); + + continue; + } + + credentials->push_back(Credentials(account, password)); + free(account); + free(password); + } + + return SUCCESS; +} + +} // namespace keytar diff --git a/lib/authentication/SecureStorage/keytar/src/keytar_win.cc b/lib/authentication/SecureStorage/keytar/src/keytar_win.cc new file mode 100644 index 000000000..60a56dab1 --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/src/keytar_win.cc @@ -0,0 +1,272 @@ +#include "keytar.h" + +#define UNICODE + +#include +#include + +#include "credentials.h" + +namespace keytar { + +LPWSTR utf8ToWideChar(std::string utf8) { + int wide_char_length = MultiByteToWideChar(CP_UTF8, + 0, + utf8.c_str(), + -1, + NULL, + 0); + if (wide_char_length == 0) { + return NULL; + } + + LPWSTR result = new WCHAR[wide_char_length]; + if (MultiByteToWideChar(CP_UTF8, + 0, + utf8.c_str(), + -1, + result, + wide_char_length) == 0) { + delete[] result; + return NULL; + } + + return result; +} + +std::string wideCharToAnsi(LPWSTR wide_char) { + if (wide_char == NULL) { + return std::string(); + } + + int ansi_length = WideCharToMultiByte(CP_ACP, + 0, + wide_char, + -1, + NULL, + 0, + NULL, + NULL); + if (ansi_length == 0) { + return std::string(); + } + + char* buffer = new char[ansi_length]; + if (WideCharToMultiByte(CP_ACP, + 0, + wide_char, + -1, + buffer, + ansi_length, + NULL, + NULL) == 0) { + delete[] buffer; + return std::string(); + } + + std::string result = std::string(buffer); + delete[] buffer; + return result; +} + +std::string wideCharToUtf8(LPWSTR wide_char) { + if (wide_char == NULL) { + return std::string(); + } + + int utf8_length = WideCharToMultiByte(CP_UTF8, + 0, + wide_char, + -1, + NULL, + 0, + NULL, + NULL); + if (utf8_length == 0) { + return std::string(); + } + + char* buffer = new char[utf8_length]; + if (WideCharToMultiByte(CP_UTF8, + 0, + wide_char, + -1, + buffer, + utf8_length, + NULL, + NULL) == 0) { + delete[] buffer; + return std::string(); + } + + std::string result = std::string(buffer); + delete[] buffer; + return result; +} + +std::string getErrorMessage(DWORD errorCode) { + LPWSTR errBuffer; + ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, errorCode, 0, (LPWSTR) &errBuffer, 0, NULL); + std::string errMsg = wideCharToAnsi(errBuffer); + LocalFree(errBuffer); + return errMsg; +} + +KEYTAR_OP_RESULT SetPassword(const std::string& service, + const std::string& account, + const std::string& password, + std::string* errStr) { + LPWSTR target_name = utf8ToWideChar(service + '/' + account); + if (target_name == NULL) { + return FAIL_ERROR; + } + + LPWSTR user_name = utf8ToWideChar(account); + if (user_name == NULL) { + return FAIL_ERROR; + } + + CREDENTIAL cred = { 0 }; + cred.Type = CRED_TYPE_GENERIC; + cred.TargetName = target_name; + cred.UserName = user_name; + cred.CredentialBlobSize = password.size(); + cred.CredentialBlob = (LPBYTE)(password.data()); + cred.Persist = CRED_PERSIST_ENTERPRISE; + + bool result = ::CredWrite(&cred, 0); + delete[] target_name; + if (!result) { + *errStr = getErrorMessage(::GetLastError()); + return FAIL_ERROR; + } else { + return SUCCESS; + } +} + +KEYTAR_OP_RESULT GetPassword(const std::string& service, + const std::string& account, + std::string* password, + std::string* errStr) { + LPWSTR target_name = utf8ToWideChar(service + '/' + account); + if (target_name == NULL) { + return FAIL_ERROR; + } + + CREDENTIAL* cred; + bool result = ::CredRead(target_name, CRED_TYPE_GENERIC, 0, &cred); + delete[] target_name; + if (!result) { + DWORD code = ::GetLastError(); + if (code == ERROR_NOT_FOUND) { + return FAIL_NONFATAL; + } else { + *errStr = getErrorMessage(code); + return FAIL_ERROR; + } + } + + *password = std::string(reinterpret_cast(cred->CredentialBlob), + cred->CredentialBlobSize); + ::CredFree(cred); + return SUCCESS; +} + +KEYTAR_OP_RESULT DeletePassword(const std::string& service, + const std::string& account, + std::string* errStr) { + LPWSTR target_name = utf8ToWideChar(service + '/' + account); + if (target_name == NULL) { + return FAIL_ERROR; + } + + bool result = ::CredDelete(target_name, CRED_TYPE_GENERIC, 0); + delete[] target_name; + if (!result) { + DWORD code = ::GetLastError(); + if (code == ERROR_NOT_FOUND) { + return FAIL_NONFATAL; + } else { + *errStr = getErrorMessage(code); + return FAIL_ERROR; + } + } + + return SUCCESS; +} + +KEYTAR_OP_RESULT FindPassword(const std::string& service, + std::string* password, + std::string* errStr) { + LPWSTR filter = utf8ToWideChar(service + "*"); + if (filter == NULL) { + return FAIL_ERROR; + } + + DWORD count; + CREDENTIAL** creds; + bool result = ::CredEnumerate(filter, 0, &count, &creds); + delete[] filter; + if (!result) { + DWORD code = ::GetLastError(); + if (code == ERROR_NOT_FOUND) { + return FAIL_NONFATAL; + } else { + *errStr = getErrorMessage(code); + return FAIL_ERROR; + } + } + + *password = std::string(reinterpret_cast(creds[0]->CredentialBlob), + creds[0]->CredentialBlobSize); + ::CredFree(creds); + return SUCCESS; +} + +KEYTAR_OP_RESULT FindCredentials(const std::string& service, + std::vector* credentials, + std::string* errStr) { + LPWSTR filter = utf8ToWideChar(service + "*"); + if (filter == NULL) { + *errStr = "Error generating credential filter"; + return FAIL_ERROR; + } + + DWORD count; + CREDENTIAL **creds; + + bool result = ::CredEnumerate(filter, 0, &count, &creds); + if (!result) { + DWORD code = ::GetLastError(); + if (code == ERROR_NOT_FOUND) { + return FAIL_NONFATAL; + } else { + *errStr = getErrorMessage(code); + return FAIL_ERROR; + } + } + + for (unsigned int i = 0; i < count; ++i) { + CREDENTIAL* cred = creds[i]; + + if (cred->UserName == NULL || cred->CredentialBlobSize == NULL) { + continue; + } + + std::string login = wideCharToUtf8(cred->UserName); + std::string password( + reinterpret_cast( + cred->CredentialBlob), + cred->CredentialBlobSize); + + credentials->push_back(Credentials(login, password)); + } + + CredFree(creds); + + return SUCCESS; +} + + +} // namespace keytar diff --git a/lib/authentication/SecureStorage/keytar/src/main.cc b/lib/authentication/SecureStorage/keytar/src/main.cc new file mode 100644 index 000000000..7c7dc7456 --- /dev/null +++ b/lib/authentication/SecureStorage/keytar/src/main.cc @@ -0,0 +1,139 @@ +#include "napi.h" +#include "async.h" + +namespace { + +Napi::Value SetPassword(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + + if (!info[0].IsString()) { + Napi::TypeError::New(env, "Parameter 'service' must be a string"). + ThrowAsJavaScriptException(); + return env.Null(); + } + + std::string service = info[0].As(); + + if (!info[1].IsString()) { + Napi::TypeError::New(env, "Parameter 'username' must be a string"). + ThrowAsJavaScriptException(); + return env.Null(); + } + + std::string username = info[1].As(); + + if (!info[2].IsString()) { + Napi::TypeError::New(env, "Parameter 'password' must be a string"). + ThrowAsJavaScriptException(); + return env.Null(); + } + + std::string password = info[2].As(); + + SetPasswordWorker* worker = new SetPasswordWorker( + service, + username, + password, + env); + worker->Queue(); + return worker->Promise(); +} + +Napi::Value GetPassword(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + if (!info[0].IsString()) { + Napi::TypeError::New(env, "Parameter 'service' must be a string"). + ThrowAsJavaScriptException(); + return env.Null(); + } + + std::string service = info[0].As(); + + if (!info[1].IsString()) { + Napi::TypeError::New(env, "Parameter 'username' must be a string"). + ThrowAsJavaScriptException(); + return env.Null(); + } + + std::string username = info[1].As(); + + GetPasswordWorker* worker = new GetPasswordWorker( + service, + username, + env); + worker->Queue(); + return worker->Promise(); +} + +Napi::Value DeletePassword(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + if (!info[0].IsString()) { + Napi::TypeError::New(env, "Parameter 'service' must be a string"). + ThrowAsJavaScriptException(); + return env.Null(); + } + + std::string service = info[0].As(); + + if (!info[1].IsString()) { + Napi::TypeError::New(env, "Parameter 'username' must be a string"). + ThrowAsJavaScriptException(); + return env.Null(); + } + + std::string username = info[1].As(); + + DeletePasswordWorker *worker = new DeletePasswordWorker( + service, + username, + env); + worker->Queue(); + return worker->Promise(); +} + +Napi::Value FindPassword(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + if (!info[0].IsString()) { + Napi::TypeError::New(env, "Parameter 'service' must be a string"). + ThrowAsJavaScriptException(); + return env.Null(); + } + + std::string service = info[0].As(); + + FindPasswordWorker* worker = new FindPasswordWorker( + service, + env); + worker->Queue(); + return worker->Promise(); +} + +Napi::Value FindCredentials(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + if (!info[0].IsString()) { + Napi::TypeError::New(env, "Parameter 'service' must be a string"). + ThrowAsJavaScriptException(); + return env.Null(); + } + + std::string service = info[0].As(); + + FindCredentialsWorker* worker = new FindCredentialsWorker( + service, + env); + worker->Queue(); + return worker->Promise(); +} + +Napi::Object Init(Napi::Env env, Napi::Object exports) { + exports.Set("getPassword", Napi::Function::New(env, GetPassword)); + exports.Set("setPassword", Napi::Function::New(env, SetPassword)); + exports.Set("deletePassword", Napi::Function::New(env, DeletePassword)); + exports.Set("findPassword", Napi::Function::New(env, FindPassword)); + exports.Set("findCredentials", Napi::Function::New(env, FindCredentials)); + return exports; +} + +} // namespace + +NODE_API_MODULE(keytar, Init) diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index 85117a1df..30915d798 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -5,7 +5,7 @@ const path = require('path'); const GlobalConfig = require('../global_config'); const Logger = require('../logger'); -const keytar = require('keytar'); +const keytar = require('./SecureStorage/keytar/lib/keytar.js'); const os = require('os'); const fs = require('fs/promises'); diff --git a/package.json b/package.json index e5071dd8f..14ecf45d4 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ "glob": "^7.1.6", "https-proxy-agent": "^5.0.1", "jsonwebtoken": "^9.0.0", - "keytar": "^7.9.0", "mime-types": "^2.1.29", "mkdirp": "^1.0.3", "moment": "^2.29.4", diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index f48b4c950..2f82a0f60 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -1,5 +1,5 @@ const assert = require('assert'); -const keytar = require('keytar'); +const keytar = require('../../../lib/authentication/SecureStorage/keytar/lib/keytar.js'); const SecureStorage = require('../../../lib/authentication/secureStorage'); const { randomUUID } = require('crypto'); From bdc3743fb8a7e337432d5df6cfa3f794485eeee2 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 22 Nov 2023 00:31:19 -0800 Subject: [PATCH 33/38] testing --- .../SecureStorage/{keytar => }/LICENSE.md | 0 .../SecureStorage/{keytar => }/README.md | 0 .../SecureStorage/{keytar => }/binding.gyp | 0 .../{keytar => }/build/Release/keytar.node | Bin .../SecureStorage/{keytar => }/keytar.d.ts | 0 .../SecureStorage/{keytar => }/lib/keytar.js | 0 .../SecureStorage/{keytar => }/package.json | 3 ++- .../SecureStorage/{keytar => }/src/async.cc | 0 .../SecureStorage/{keytar => }/src/async.h | 0 .../SecureStorage/{keytar => }/src/credentials.h | 0 .../SecureStorage/{keytar => }/src/keytar.h | 0 .../SecureStorage/{keytar => }/src/keytar_mac.cc | 0 .../SecureStorage/{keytar => }/src/keytar_posix.cc | 0 .../SecureStorage/{keytar => }/src/keytar_win.cc | 0 .../SecureStorage/{keytar => }/src/main.cc | 0 15 files changed, 2 insertions(+), 1 deletion(-) rename lib/authentication/SecureStorage/{keytar => }/LICENSE.md (100%) rename lib/authentication/SecureStorage/{keytar => }/README.md (100%) rename lib/authentication/SecureStorage/{keytar => }/binding.gyp (100%) rename lib/authentication/SecureStorage/{keytar => }/build/Release/keytar.node (100%) rename lib/authentication/SecureStorage/{keytar => }/keytar.d.ts (100%) rename lib/authentication/SecureStorage/{keytar => }/lib/keytar.js (100%) rename lib/authentication/SecureStorage/{keytar => }/package.json (98%) rename lib/authentication/SecureStorage/{keytar => }/src/async.cc (100%) rename lib/authentication/SecureStorage/{keytar => }/src/async.h (100%) rename lib/authentication/SecureStorage/{keytar => }/src/credentials.h (100%) rename lib/authentication/SecureStorage/{keytar => }/src/keytar.h (100%) rename lib/authentication/SecureStorage/{keytar => }/src/keytar_mac.cc (100%) rename lib/authentication/SecureStorage/{keytar => }/src/keytar_posix.cc (100%) rename lib/authentication/SecureStorage/{keytar => }/src/keytar_win.cc (100%) rename lib/authentication/SecureStorage/{keytar => }/src/main.cc (100%) diff --git a/lib/authentication/SecureStorage/keytar/LICENSE.md b/lib/authentication/SecureStorage/LICENSE.md similarity index 100% rename from lib/authentication/SecureStorage/keytar/LICENSE.md rename to lib/authentication/SecureStorage/LICENSE.md diff --git a/lib/authentication/SecureStorage/keytar/README.md b/lib/authentication/SecureStorage/README.md similarity index 100% rename from lib/authentication/SecureStorage/keytar/README.md rename to lib/authentication/SecureStorage/README.md diff --git a/lib/authentication/SecureStorage/keytar/binding.gyp b/lib/authentication/SecureStorage/binding.gyp similarity index 100% rename from lib/authentication/SecureStorage/keytar/binding.gyp rename to lib/authentication/SecureStorage/binding.gyp diff --git a/lib/authentication/SecureStorage/keytar/build/Release/keytar.node b/lib/authentication/SecureStorage/build/Release/keytar.node similarity index 100% rename from lib/authentication/SecureStorage/keytar/build/Release/keytar.node rename to lib/authentication/SecureStorage/build/Release/keytar.node diff --git a/lib/authentication/SecureStorage/keytar/keytar.d.ts b/lib/authentication/SecureStorage/keytar.d.ts similarity index 100% rename from lib/authentication/SecureStorage/keytar/keytar.d.ts rename to lib/authentication/SecureStorage/keytar.d.ts diff --git a/lib/authentication/SecureStorage/keytar/lib/keytar.js b/lib/authentication/SecureStorage/lib/keytar.js similarity index 100% rename from lib/authentication/SecureStorage/keytar/lib/keytar.js rename to lib/authentication/SecureStorage/lib/keytar.js diff --git a/lib/authentication/SecureStorage/keytar/package.json b/lib/authentication/SecureStorage/package.json similarity index 98% rename from lib/authentication/SecureStorage/keytar/package.json rename to lib/authentication/SecureStorage/package.json index 12cbafcc4..6254f49db 100644 --- a/lib/authentication/SecureStorage/keytar/package.json +++ b/lib/authentication/SecureStorage/package.json @@ -4,6 +4,7 @@ "name": "keytar", "description": "Bindings to native Mac/Linux/Windows password APIs", "version": "7.9.0", + "gypfile": true, "license": "MIT", "repository": { "type": "git", @@ -63,4 +64,4 @@ "runtime": "napi", "target": 3 } -} +} \ No newline at end of file diff --git a/lib/authentication/SecureStorage/keytar/src/async.cc b/lib/authentication/SecureStorage/src/async.cc similarity index 100% rename from lib/authentication/SecureStorage/keytar/src/async.cc rename to lib/authentication/SecureStorage/src/async.cc diff --git a/lib/authentication/SecureStorage/keytar/src/async.h b/lib/authentication/SecureStorage/src/async.h similarity index 100% rename from lib/authentication/SecureStorage/keytar/src/async.h rename to lib/authentication/SecureStorage/src/async.h diff --git a/lib/authentication/SecureStorage/keytar/src/credentials.h b/lib/authentication/SecureStorage/src/credentials.h similarity index 100% rename from lib/authentication/SecureStorage/keytar/src/credentials.h rename to lib/authentication/SecureStorage/src/credentials.h diff --git a/lib/authentication/SecureStorage/keytar/src/keytar.h b/lib/authentication/SecureStorage/src/keytar.h similarity index 100% rename from lib/authentication/SecureStorage/keytar/src/keytar.h rename to lib/authentication/SecureStorage/src/keytar.h diff --git a/lib/authentication/SecureStorage/keytar/src/keytar_mac.cc b/lib/authentication/SecureStorage/src/keytar_mac.cc similarity index 100% rename from lib/authentication/SecureStorage/keytar/src/keytar_mac.cc rename to lib/authentication/SecureStorage/src/keytar_mac.cc diff --git a/lib/authentication/SecureStorage/keytar/src/keytar_posix.cc b/lib/authentication/SecureStorage/src/keytar_posix.cc similarity index 100% rename from lib/authentication/SecureStorage/keytar/src/keytar_posix.cc rename to lib/authentication/SecureStorage/src/keytar_posix.cc diff --git a/lib/authentication/SecureStorage/keytar/src/keytar_win.cc b/lib/authentication/SecureStorage/src/keytar_win.cc similarity index 100% rename from lib/authentication/SecureStorage/keytar/src/keytar_win.cc rename to lib/authentication/SecureStorage/src/keytar_win.cc diff --git a/lib/authentication/SecureStorage/keytar/src/main.cc b/lib/authentication/SecureStorage/src/main.cc similarity index 100% rename from lib/authentication/SecureStorage/keytar/src/main.cc rename to lib/authentication/SecureStorage/src/main.cc From 36e1c20698e81b6aaf7b5305c69279da913420a4 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Wed, 22 Nov 2023 00:35:36 -0800 Subject: [PATCH 34/38] testing --- .../SecureStorage/{ => keytar}/LICENSE.md | 0 .../SecureStorage/{ => keytar}/README.md | 0 .../SecureStorage/{ => keytar}/binding.gyp | 0 .../{ => keytar}/build/Release/keytar.node | Bin .../SecureStorage/{ => keytar}/keytar.d.ts | 0 .../SecureStorage/{ => keytar}/lib/keytar.js | 0 .../SecureStorage/{ => keytar}/package.json | 0 .../SecureStorage/{ => keytar}/src/async.cc | 0 .../SecureStorage/{ => keytar}/src/async.h | 0 .../SecureStorage/{ => keytar}/src/credentials.h | 0 .../SecureStorage/{ => keytar}/src/keytar.h | 0 .../SecureStorage/{ => keytar}/src/keytar_mac.cc | 0 .../SecureStorage/{ => keytar}/src/keytar_posix.cc | 0 .../SecureStorage/{ => keytar}/src/keytar_win.cc | 0 .../SecureStorage/{ => keytar}/src/main.cc | 0 15 files changed, 0 insertions(+), 0 deletions(-) rename lib/authentication/SecureStorage/{ => keytar}/LICENSE.md (100%) rename lib/authentication/SecureStorage/{ => keytar}/README.md (100%) rename lib/authentication/SecureStorage/{ => keytar}/binding.gyp (100%) rename lib/authentication/SecureStorage/{ => keytar}/build/Release/keytar.node (100%) rename lib/authentication/SecureStorage/{ => keytar}/keytar.d.ts (100%) rename lib/authentication/SecureStorage/{ => keytar}/lib/keytar.js (100%) rename lib/authentication/SecureStorage/{ => keytar}/package.json (100%) rename lib/authentication/SecureStorage/{ => keytar}/src/async.cc (100%) rename lib/authentication/SecureStorage/{ => keytar}/src/async.h (100%) rename lib/authentication/SecureStorage/{ => keytar}/src/credentials.h (100%) rename lib/authentication/SecureStorage/{ => keytar}/src/keytar.h (100%) rename lib/authentication/SecureStorage/{ => keytar}/src/keytar_mac.cc (100%) rename lib/authentication/SecureStorage/{ => keytar}/src/keytar_posix.cc (100%) rename lib/authentication/SecureStorage/{ => keytar}/src/keytar_win.cc (100%) rename lib/authentication/SecureStorage/{ => keytar}/src/main.cc (100%) diff --git a/lib/authentication/SecureStorage/LICENSE.md b/lib/authentication/SecureStorage/keytar/LICENSE.md similarity index 100% rename from lib/authentication/SecureStorage/LICENSE.md rename to lib/authentication/SecureStorage/keytar/LICENSE.md diff --git a/lib/authentication/SecureStorage/README.md b/lib/authentication/SecureStorage/keytar/README.md similarity index 100% rename from lib/authentication/SecureStorage/README.md rename to lib/authentication/SecureStorage/keytar/README.md diff --git a/lib/authentication/SecureStorage/binding.gyp b/lib/authentication/SecureStorage/keytar/binding.gyp similarity index 100% rename from lib/authentication/SecureStorage/binding.gyp rename to lib/authentication/SecureStorage/keytar/binding.gyp diff --git a/lib/authentication/SecureStorage/build/Release/keytar.node b/lib/authentication/SecureStorage/keytar/build/Release/keytar.node similarity index 100% rename from lib/authentication/SecureStorage/build/Release/keytar.node rename to lib/authentication/SecureStorage/keytar/build/Release/keytar.node diff --git a/lib/authentication/SecureStorage/keytar.d.ts b/lib/authentication/SecureStorage/keytar/keytar.d.ts similarity index 100% rename from lib/authentication/SecureStorage/keytar.d.ts rename to lib/authentication/SecureStorage/keytar/keytar.d.ts diff --git a/lib/authentication/SecureStorage/lib/keytar.js b/lib/authentication/SecureStorage/keytar/lib/keytar.js similarity index 100% rename from lib/authentication/SecureStorage/lib/keytar.js rename to lib/authentication/SecureStorage/keytar/lib/keytar.js diff --git a/lib/authentication/SecureStorage/package.json b/lib/authentication/SecureStorage/keytar/package.json similarity index 100% rename from lib/authentication/SecureStorage/package.json rename to lib/authentication/SecureStorage/keytar/package.json diff --git a/lib/authentication/SecureStorage/src/async.cc b/lib/authentication/SecureStorage/keytar/src/async.cc similarity index 100% rename from lib/authentication/SecureStorage/src/async.cc rename to lib/authentication/SecureStorage/keytar/src/async.cc diff --git a/lib/authentication/SecureStorage/src/async.h b/lib/authentication/SecureStorage/keytar/src/async.h similarity index 100% rename from lib/authentication/SecureStorage/src/async.h rename to lib/authentication/SecureStorage/keytar/src/async.h diff --git a/lib/authentication/SecureStorage/src/credentials.h b/lib/authentication/SecureStorage/keytar/src/credentials.h similarity index 100% rename from lib/authentication/SecureStorage/src/credentials.h rename to lib/authentication/SecureStorage/keytar/src/credentials.h diff --git a/lib/authentication/SecureStorage/src/keytar.h b/lib/authentication/SecureStorage/keytar/src/keytar.h similarity index 100% rename from lib/authentication/SecureStorage/src/keytar.h rename to lib/authentication/SecureStorage/keytar/src/keytar.h diff --git a/lib/authentication/SecureStorage/src/keytar_mac.cc b/lib/authentication/SecureStorage/keytar/src/keytar_mac.cc similarity index 100% rename from lib/authentication/SecureStorage/src/keytar_mac.cc rename to lib/authentication/SecureStorage/keytar/src/keytar_mac.cc diff --git a/lib/authentication/SecureStorage/src/keytar_posix.cc b/lib/authentication/SecureStorage/keytar/src/keytar_posix.cc similarity index 100% rename from lib/authentication/SecureStorage/src/keytar_posix.cc rename to lib/authentication/SecureStorage/keytar/src/keytar_posix.cc diff --git a/lib/authentication/SecureStorage/src/keytar_win.cc b/lib/authentication/SecureStorage/keytar/src/keytar_win.cc similarity index 100% rename from lib/authentication/SecureStorage/src/keytar_win.cc rename to lib/authentication/SecureStorage/keytar/src/keytar_win.cc diff --git a/lib/authentication/SecureStorage/src/main.cc b/lib/authentication/SecureStorage/keytar/src/main.cc similarity index 100% rename from lib/authentication/SecureStorage/src/main.cc rename to lib/authentication/SecureStorage/keytar/src/main.cc From bdd9a995dd6997306d1b4cf95f3964595d6dd4b8 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 23 Nov 2023 14:01:54 -0800 Subject: [PATCH 35/38] testing --- .../SecureStorage/keytar/LICENSE.md | 20 -- .../SecureStorage/keytar/README.md | 94 ------ .../SecureStorage/keytar/binding.gyp | 48 --- .../keytar/build/Release/keytar.node | Bin 707584 -> 0 bytes .../SecureStorage/keytar/keytar.d.ts | 51 --- .../SecureStorage/keytar/lib/keytar.js | 43 --- .../SecureStorage/keytar/package.json | 67 ---- .../SecureStorage/keytar/src/async.cc | 242 -------------- .../SecureStorage/keytar/src/async.h | 103 ------ .../SecureStorage/keytar/src/credentials.h | 13 - .../SecureStorage/keytar/src/keytar.h | 41 --- .../SecureStorage/keytar/src/keytar_mac.cc | 296 ------------------ .../SecureStorage/keytar/src/keytar_posix.cc | 184 ----------- .../SecureStorage/keytar/src/keytar_win.cc | 272 ---------------- .../SecureStorage/keytar/src/main.cc | 139 -------- lib/authentication/secureStorage.js | 66 ++-- package.json | 3 + .../unit/authentication/secureStorage_test.js | 28 +- 18 files changed, 62 insertions(+), 1648 deletions(-) delete mode 100644 lib/authentication/SecureStorage/keytar/LICENSE.md delete mode 100644 lib/authentication/SecureStorage/keytar/README.md delete mode 100644 lib/authentication/SecureStorage/keytar/binding.gyp delete mode 100644 lib/authentication/SecureStorage/keytar/build/Release/keytar.node delete mode 100644 lib/authentication/SecureStorage/keytar/keytar.d.ts delete mode 100644 lib/authentication/SecureStorage/keytar/lib/keytar.js delete mode 100644 lib/authentication/SecureStorage/keytar/package.json delete mode 100644 lib/authentication/SecureStorage/keytar/src/async.cc delete mode 100644 lib/authentication/SecureStorage/keytar/src/async.h delete mode 100644 lib/authentication/SecureStorage/keytar/src/credentials.h delete mode 100644 lib/authentication/SecureStorage/keytar/src/keytar.h delete mode 100644 lib/authentication/SecureStorage/keytar/src/keytar_mac.cc delete mode 100644 lib/authentication/SecureStorage/keytar/src/keytar_posix.cc delete mode 100644 lib/authentication/SecureStorage/keytar/src/keytar_win.cc delete mode 100644 lib/authentication/SecureStorage/keytar/src/main.cc diff --git a/lib/authentication/SecureStorage/keytar/LICENSE.md b/lib/authentication/SecureStorage/keytar/LICENSE.md deleted file mode 100644 index 493db50ed..000000000 --- a/lib/authentication/SecureStorage/keytar/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2013 GitHub Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/authentication/SecureStorage/keytar/README.md b/lib/authentication/SecureStorage/keytar/README.md deleted file mode 100644 index 91141b726..000000000 --- a/lib/authentication/SecureStorage/keytar/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# keytar - Node module to manage system keychain - -[![Travis Build Status](https://travis-ci.org/atom/node-keytar.svg?branch=master)](https://travis-ci.org/atom/node-keytar) -[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/atom/node-keytar?svg=true)](https://ci.appveyor.com/project/Atom/node-keytar) -[![Dependency Status](https://david-dm.org/atom/node-keytar.svg)](https://david-dm.org/atom/node-keytar) - -A native Node module to get, add, replace, and delete passwords in system's keychain. On macOS the passwords are managed by the Keychain, on Linux they are managed by the Secret Service API/libsecret, and on Windows they are managed by Credential Vault. - -## Installing - -```sh -npm install keytar -``` - -### On Linux - -Currently this library uses `libsecret` so you may need to install it before running `npm install`. - -Depending on your distribution, you will need to run the following command: - -* Debian/Ubuntu: `sudo apt-get install libsecret-1-dev` -* Red Hat-based: `sudo yum install libsecret-devel` -* Arch Linux: `sudo pacman -S libsecret` - -## Building - - * Clone the repository - * Run `npm install` - * Run `npm test` to run the tests - -## Supported versions - -Each release of `keytar` includes prebuilt binaries for the versions of Node and Electron that are actively supported by these projects. Please refer to the release documentation for [Node](https://github.com/nodejs/Release) and [Electron](https://electronjs.org/docs/tutorial/support) to see what is supported currently. - -## Bindings from other languages - -- [Rust](https://crates.io/crates/keytar) - -## Docs - -```javascript -const keytar = require('keytar') -``` - -Every function in keytar is asynchronous and returns a promise. The promise will be rejected with any error that occurs or will be resolved with the function's "yields" value. - -### getPassword(service, account) - -Get the stored password for the `service` and `account`. - -`service` - The string service name. - -`account` - The string account name. - -Yields the string password or `null` if an entry for the given service and account was not found. - -### setPassword(service, account, password) - -Save the `password` for the `service` and `account` to the keychain. Adds a new entry if necessary, or updates an existing entry if one exists. - -`service` - The string service name. - -`account` - The string account name. - -`password` - The string password. - -Yields nothing. - -### deletePassword(service, account) - -Delete the stored password for the `service` and `account`. - -`service` - The string service name. - -`account` - The string account name. - -Yields `true` if a password was deleted, or `false` if an entry with the given service and account was not found. - -### findCredentials(service) - -Find all accounts and password for the `service` in the keychain. - -`service` - The string service name. - -Yields an array of `{ account: 'foo', password: 'bar' }`. - -### findPassword(service) - -Find a password for the `service` in the keychain. This is ideal for scenarios where an `account` is not required. - -`service` - The string service name. - -Yields the string password, or `null` if an entry for the given service was not found. - diff --git a/lib/authentication/SecureStorage/keytar/binding.gyp b/lib/authentication/SecureStorage/keytar/binding.gyp deleted file mode 100644 index 77fbf4485..000000000 --- a/lib/authentication/SecureStorage/keytar/binding.gyp +++ /dev/null @@ -1,48 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'keytar', - 'defines': [ - "NAPI_VERSION=<(napi_build_version)", - ], - 'cflags!': ['-fno-exceptions'], - 'cflags_cc!': ['-fno-exceptions'], - 'xcode_settings': {'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', - 'CLANG_CXX_LIBRARY': 'libc++', - 'MACOSX_DEPLOYMENT_TARGET': '10.7', - }, - 'msvs_settings': { - 'VCCLCompilerTool': {'ExceptionHandling': 1}, - }, - 'include_dirs': ["(e1pmqn-3 zWyQbMs?%-9lYd4L{(az>NvF$OYG+>E<{U>$Z_i{pTDo;WpTUN}K?8da>ek=TquYQ1 z1A`3RKQ{~t9$@G*z|gRHD?|T*JwLCKCr?gijkL#T>w{6nr!KPn&+a!ZYBi$Mu;WHB3CGMvWHF0gL4G8*Vcj!%5PWG33gew}dXzUZ?ZREV6Ut!^2TTL%;?Z2Pm7! zN_pyhb4lhRKeNsssIrjl@n%}fsgP4(2cFKUt4o@OT)MgxQeaNqq~^@f{@iluj5%~V zkB}TX4_jV3&*-lJ7Y)^bCvxfnNiPX~O$Wb9(C5Q~kY8g8`phP?@5E2_XVB^Vs|@Pd zEvOqJ;UFFboUiemj%TVrBh;yiMAK!e0f1Xhovsj`CGkx4XVmGUs{~5KC4K;)ueuI+ ze*6ZWu}U9_r_T>K`l2g{=j3$odJ<8mdjK)8ue#iLE`9?qx{8}yk6yiXx)y>*K&F`2 zy@6-!+OnZ%Yfqi74B?KNY}dbuS7p%PK|O#XWCqy@#n_x4-sk-W0`UU%39{6&KRe&R ztB>4&v+EKrv_#VM3xd$2I$c7UD~Q!@ zn^l*P^@N=+q0}AVeQ^oF+Hy#q$PX%wzXO#K0Vw-x3*eo$x7Q_nHwnpl^8i>o5d_q- z!0X|GVskqqZ)zg&0_;Gb<3t2ATOzr11fatXqS(R%Khk5+52PEQJuA&>4fB?YY4JbL6yH% z1C{$(5ObQ3yq|JHDD{@0-j6l_Fl-{I#F6};1yFXzUgRAi(N=vB>(U=V4p^>)Xm)Tp zh1aYgNZsuP0+HE)SD+%2U7jNO7~>|P^k*LmvTrX(17!@AtI#Zz=u;Fe^~er-F;+C~_l?MF(Fg=O4Fd9avk_ZH zo__lo0H>pnXLdl@GV>99TNr@->yX!X1Ijijg5;TPh`HoJv3b!T+G`||7o34IdmQq5 zS4Q$;7?LxVBQPvNFqA5~^&61)d;+2`*$nsdAT@0O04uK|R=hf(4%Fv;Q;=sz0aX42 zfH7_W96E#^1%CrTRx0bZ28b29h{``*54@09NcLU`K$TuV-dhjJVbf6Jvv{EFd5kKj z65!0rLz|+GCL00O_XA$QD$=8deVqX077Y<(eSo~U(m*ah7RaJ~tqq7RoQV>Xn*ya= zSHwaZ0;RDFf_enZ`4%W1!3ZvOMliP+@Jf$DES??AUJ7_+!VvR{0CIFiG^pKb1PgQ! zPeltF6wXfHUJsNq2N2{d4ZKNDf#S-hExC(e1ADoi(kf*~{i9`gbs5PeCXmlE5hyjO z5$zkI*y-UQ8afBboWFr`H`*8fT>vzva&^Ciy#7=HH%w{?ee(jk_%HxDJWy}$3LqL9 zi)51t2#z)fO7X`){?QIW^@=E)Zz)Pd=K|jCdWb#YsPI_@yq9B8Z;wYnnU;vaYZ##O z4FG)h6G;7b8+kuBMjdxnBJW`-1YHgRrTwP}gbfR=0F=2Fpj_CG5|>wi-a-og;${T3 z$>QyaDE12htG)o<(lN-({T-lV*n+LJC0p3YNmRX&34qoc59qf}2qsMj%8#1>xUnAu zF3_4~Wm`U*jbcsW5G1Ta@+PG)_#A>V9g+Om3Mx+I-x!+faV7*6OMy!9?#SzX04=?x z0=dL}5b&Ra;QKrf&(~i8Z}(&XekcOG<{VKS7NXu6H1*d45xaT;EiFSq&G{bC&0Zjy zg&ZHy5P*+VQ10XcXoCxYHkpao8EVc6j<E1_&@>irTI z#QHu!-U8ySO#+I)8-l^ayV4G^J}*J4bq639_!hP0U4~@BU;z5D`&|=}_tkX7f{!8g z=m?5gIafTm0m`12065(Yv00Z9EG`0+wVVwK9!JodgMIE!^zzFBC^o(|i1siduR4== zX|6}z12oHzKyLXbl4k-?`DKdnk`+Pbg$QcHr%qUs4YA(K5zOt3AkRurab656F}Dzu z{~kd(+JnkN5i3v$!GtwPK3|RC{4x-@_Y+!rC=`GV1rdvGiHbfuh6Zh9tMmaNI*c>y z)lLWswSe$EKL=noS>hUvyq1lCGWsV3OU{76y?FpMVsb});O(cWTFCx(VZAxpBRQYy zz5F4{zL*Q-8B>vTu8Cv=w&m*r2#Tx&a%3wI*hc8Zb4YHv1;8+81g**<$VuB-qA&t` zPIrYLBUX=&L&9h1Ol1Z1Rv$*}Y)2q}ItzeniHJ@76;)OuptH^b@6-YW8>lL+s{+uGQ~nStT*4%K9EE6AsIUb z$Uk2OUQ{K-mghszh?CqaD)pl}K#3#Kl7Aq`HxtS6-YDCgF3IHTsCRS>DvJIEdG4`* zezFy1J2ybmnd9GCy7bZvza-R%L`ORpfv56NBBh!-X#e`OFD2~zDi zOHSr=x1kSE{D&afm`ps@1(c^wLO-%zL9%x(B)ijW-aUn2*vAM;)kd+J2T)?i9N_gU z4FXmbL|d};i>@OUR2Z?t&Csg0?SX8Wfjp0;D0}W6itVH!o2m!2(|EKw%QyrZR|DmG z8w4(8K(9_H@bVT%i8+n znhE4RI8S$V2VmMM;I*J)7QY9S@Bc*b35jmtc=KSDjX6FRxPsK(mB_ovnK(2a4a&>8 z`#>X<2&Vx(cLspir=WbFdSCfGDw@|FC>v?6uXjOg$pX-GAnT6(z&3L#pZ+7rTUmJ_ zx^Ek@An8wEC9y7&ZK)t6{%X=4Sx%CI>*fGuejz!3o;pQdyB#rYV9AY~T95 zh)uZ$3$g2o z2yXTV;L>dnt$r7H!QBAWu?0V}EnANw*iEZf+={$ekAc#}7eSF0DCWmW>6f2D<-t0{ z?z3r8V*zz1(NE~3+f7I8<0>F<$qfx!wGSxm*~p&sa#vSJUeUsch0Q=-KxPEJmjF3) zH3Un!I@wQqU)BqF`TMYrSxDZYahr7m!OTCAw`B{0x)ucUUIK6KHK5pWe7MB}rNJ?f zDvu>>!ol6B$eEteQ?|4VhvaTf%$3&yp?DInTpEbzX32Fm*vAo&xmz%njnjxGR7 zd{+dw+XJQhHIN!j^KfS(f>~_=DA^Twndn{jivfWtCy~s&6oEG#v`MoO45kS>wI0FP z6(|u!YgTJFS}=~?Ur7(DI2rqJAnJIq3RLn<1R!t{0Ka5LP?DXgM%|6t1-#EVOi@Z+#L4IO9lCfVRdHp_$eazjITssi!#i_S8 zUF;*rfb#Syg8Cl;uLWl{m*Plf=OVZR)yIw^yT)Of$T_sj4*<-ljyxAy%z^EY9M=ud zBJ8<;F_f*k8_9KCM@^+(ITr)ort%1?(_I){1b9vt0q9EQ|9vw6C0NlTdby3iMl6=yeg$y+#lSXGIPlp~M~vWo&z()LjOYING7SWa63ZX!Cx$?8U|-xI%eM? z66!~L5Li_RfZ_2#_M^i$@G6qaDgc_$0(o^?B51c6bu=0VKUp$QwC6fM^N5X z55?9^2jI*kBqx1^VBUBj?_|@?d<*DidSqgaeXBHz&7q-q$<3+ebSrMq+J2h}F_nt> zBlFsl5%;JfH|-d#T>rLlAt&y^)LOfLt*Vct#qx zOPs-$4F&Q_Ga7VcD3aUQ(%5j&JCg$_qh5lF1D7(HeUX=M3P^sRkRA zm3t4x1^}-+#aJUVicJbfat!xr@^jLh(Fx?8w;=gT9h6yT0O<7) zfHSj@=Q0D(U;aRHC+Dq*>Bv(#&01OSGB3nFCc*H)Zs)Tn3<&K1&9g0?c8H~Wh^+E&A zR$KKbTY{5_QWnUew}JfIPXGjS?^@WB9?y~dZ3LiG>4*7ooOk4qoJ(hRP9$RXKclv% z^FgKhE9C8FBUg~IL+NE?T0&}BW5x8WX=H)D{zYL8fT^7KM&^lcJlxtf+R|6maC zE(B!18X(_*Gfv*(i0M}Yu%aE3*;#BRP5qW&Bs~rxHl{0rLH3}$h)Q#lojy)`nwR{` zaSF+XoHcq}M>3Xko@GChr|Sdo-3r8RT}I41KVs*J5=YOY%md{8YzO4c3W8i^ke7`f z{M|-qLF>i{8gl~wy*^4zy@q7&GYGmqM$ncf=*zZ1p3UKR?g@ep+?nYA5~Q-S;fbSx zQl8xCTmiv$?gpGY2~j*@-@KY4FF=nH?bxc=f{2ylFwO0OvN4?QMwAAMo-Orjj$jr| zeU(1Ivus5PT@xg~nTDYI1O&S|J*{BRt@OE?Wd_QH4gh@2ZI;zs8P;!!vR;&jx)~J> z=AKL$`aTD_8=x~F*_ZQC-c=}@gUV$p0D4#F0A(Ys<131+IK^|16aA?#L3xoYpqps~ zw{dw`pR-H8oPZ|%j#$in&15 zR!^5lAogkI?nkW8&j>09A!zUof=b+>w$%EvJ$H2=$@q}}kw(AsvJ=`gO{0HzHpCM*mguL#|JNYL{jN*XU)(<6K zP?fK94`p^X;?Z$^LD3fRM^JYsg2dHm%d*M{I^RK3H;#3j2Hs)|2=u2FWp8WIo{1V=cEe&#Oqr zP|;Vl1}D#OgJca`)x0JE_j(kcN#2W}dFNuRJGt$ZkL&Z!vy9QYk& zThpQciC)VKp=(?f&F8wO4)Zb}McL9c(mkmMw+Sso^0m3Se4b15hcs1lYarHsBJtXw zgYMi2_>(5GL>3?$SzB{TYt;b+J4oOe1-grP`DY{6Ud-Lx?M_^Y2K~-Os~7hfTzIl_ zbvcsd*Q3f`*8;`BbFhg&06LdS_&J;QLrnxjIVlb5i@b6i0fuZq{)MEznv7&Q))rj= zu{b-_@ku4bKDvft+bP-@ZY7@0kDx#IzLJ^&u<08BN;)E_#^KUwID+FPk?cSN^_;Wc zqqQJk)ef<*j-c!-j@9kAkSx^{u~poa4D$kVJcnNo+TF#R(E2|@BOlQz$`XQNO}OHl z(-uk7FMzt|K`iec#EQ_1Y<&^P-yKJ+<{%*Na6&Mh4*fi??nFoI(~VHyk;-Z`d@E>R6M9Q-$sM5H z#{l?xB$6BI02;jxK`C0UCri<)(Q5%6PcOsuApoa1pXca?pfYF9F|UvpTNGtqk)7K& zp{3t*&m$*&i|3p$j(mpL!v4Uk!WQgh!#8t8m7?+8ikln>wdpbLZ;ZTLxqxzNCt^OQ z04+Ec$c4Fg*ujLn8C0ZUNuW29p2ysiD7KWHUY`%pKRyEV7Ox6?N`t2)B6*vw%1?hI zg52#ymuX}_)RDOaO0=JgAezi6MXrsj3_!WuC=tbzkeD8*qt`6*-U$G44))D7K<9F= z)T=%6!uun*lmkK0Z;^L_$3HhoU>@%uG@+M~Z#t5WJgw?G5Y1RekK%q^1b$NixK{;v z_2}IM)3QFJN);_X@$;$pCy#JU4FSxzjuRGaPt&dH^^3AXaBM z@>bDV^yV1sMAeInM{)sgpNyt>)(-{IdjpW{!YRv=6R~T15OZCFpb+hS#orKklm=kn zImEV-Ic;J@~T5uO-gR21QOZoQh zh7!lP>9m%eo=x37$F6o*gII|l0nHtZWPy`N4!DD$^GBf4@CW3Toq%Majwm+g3$$;4 z0P5(N2YI)C2TCSNFlZhKl;tt+0yaGCE|P8sQFaV9F>_0l=raY$Xf89{FM~??{s3&) zj991V2&{Ddb`C`_oUQt}31WTO`X^TbEkPZ>EcPR=fV(vhA$fqq#rOs2wTnYgpKLn7 zwiKKQz-Khqlh>f$$MHzI@mOLL+xI6mEE6{>F4ORQmkqHeLl6sNr?)Rdkc<9Ccg{k4 zISIF>#@5-3SQl=n{rUo}I-MQCIr@{o#UMzq0I;GV0(V-5*u04Kp%2%OTl_z+14^^= zXhxr>Xn}7KQ09?9(G@`Xl#3dF&e#<=rB?C=z{0JFByPuyyoqG_&rxC#ciNoDoU2ro zLyH0Zc_)&WIluMoj@UXX>st15R1PHPaWiurZYL(ZItK#ttsp<^36M{5@)}MO+m=(?=X4iF(IsBk7${wcvg1?IW9wawNFF1vRxUy1kGPLH<~NjG_6uSsxz)4i++?aVrU7Pq3lJ#jP%k@U` z#1@n&K$pE9m${F*+Y?Ans{zO0DLW*uTR`eWMZ_9B2A~PI@1{OLTTHu=_pl!D7H>fE z@k#)O4Fk$yZgn=JM=`Yr1b|SEo-*8eX~7Y7nw{>=Iv!B3 zMn6Jq{xnd2NVeag+SZ5ym1rt!9MAm6^+b?^qoNa6EUQ-_C`5*}r++_*OO#o!Q1;X= zB=ga+cA1K@%{ivKa}GVz6VN+Z5xdRP(%4^-Y|ptOoIDuAMfC(yX~8@vuA{yu<@!{R zifqP9ZZ12}#V*7BoP$FVTM`JsQ`(%bh_ZVc%Gy(#o~}S=_Hi*)q7s5py?{LCA!0+W z0Wh5QJ@?HGkP991|c}~2T-oNqpS-T7YBJl zIqd}U90&>nU$=NJpo{VY`pgAXKHCVusxT1P(F1_Z+ykAWM;)iU5nQJtIb{Lh zDRsBmEkG}9MV@H~@*2}X*awOt;GVl@u}aDXS(cT_+N)IxA<8>;L-A3+ia z(?YI#Yt8_2?K23RmjKzF%_u|HxkLm|3OWFAk1l)tqX<4-g%U?D0x*Sws`&tT`N*qb z{ZXtcZ+5L(3@Ww#fb7gpf7TPR>Lm4Q3xa12fP9$#?vqjo&TzoyrmmUEy2bQQ`_w>{ zANwL%wg*sdwMT3YHx<?!jb$_9s{!vDuCjhpffqIwfFqd@{80jUUvQco zy9p?l*CV!iCFr%)0lI-+>6-0`jbUNpuo>iqH8-q zFE&Qr!JmQRu?>K4Xub|{Sl=D`vAu=1Uq<`oiqTk zp~VnPpl(##3M$(tBH5Hq!ta%lx0c1S-au?&K>(@@MzNE3k>^CCTA?#yy-opn(Pf|* zh_{U!lI8Csh=>C;fcGf+a##0keUR_Q4UJ)(qrTyMxqvOuw?*v429(&;8nJA&Yx;^n z)^Url*w+X;aPe6C1OS0taP++cp-iI$gQ;c>IkU%cz}~t6K%W4Vc!|sV3CGFARou@1 zmIF4DBdRb5&J${EpDKv8<_Tp}s!HApK(1C8^{SZwjhg`~ZF%ak;XH!MT|r2F5z8=8lboEMIcMGzT^;CLSZ%5y_J6FY6lg6kKyG);Gb3+A1cHc}s8@Fx^a^wD^*1u7|2@<@ogQ*i?xBpMG3wI+#X?x`J?d!( zuFGcJM9f6S&Z8gJVK1N+$=F96e!D2&Pl#O3A9YOP$zHqtsB&i(1Vy;rmYa5?FSmg< z@@#B4yZ_Ri{qP2~-Xa7M^vs9#MQnK-P^v#ca%>=yYuX@KT>;1whJgIinE>>oL$GT! z@}`L~%{ebCH>U~@K}DH2uzkNFd4y{wcaD#?nE?o+Z9h*oJtglio&a9(pMZAa@ps%n zAjeKao}LCJoQtXNzC%zx3-VUBLY3#|BKb{61S75k`7zh*^Ctm1aT5p}8i$x2Yn#tS z!)luA>fBGXd<}pL*DmheKsi6#;!O*jl^0aL`4#k@FgC-Ayyy;yjrjv*_i&YJ;jC7i zGt>9HUi}5vs~5OV(X9cg!L@`#TB5;0*yn&Sv8%It?u!APru&SdG zD^IQanfrw6r=#96JQMEK1%T^25i1@FyfNI0ZNg)n8uLNwG+jw6JJVzsDxX0ycH-o} z?RSuB!t;vuO@UmQqP@zl?xCsQuo5Lg&Vcf5&Z`4{Lu_Ryl!%N5-a?wMX#;_07mK_g z`d77REsBzpJ6ZthM3$W6a;_IG+*EhaJHHmtbH4-mcW%iCbG9;28MaZh%Lb#^2Hpor zNy%c-e-i~ID%qhe*j>12%1rBHuAc>KycC# zfJyW=@AU$`UiJu1mPPP!X#oDnjMypO>YQ;JqynZQwyiYsF0%W(gF){RR|$1^ZeKl+ zb#OQNGWXZ2(i~2s5=Qhx5Xo61hW^zPj?n&GjoH({x2k|4Ien@5~pgy_Lf+wv}_W=El{g_LaL~g#Joj7{+$kU3+lo6Y)CdI{}$%~%Gf-JZEufYHTCMx$%uVUU5lOq=x4W) zSBR3S#<4JpU1%=G^c(?43yboReau@OlZ>CxcHC{LlZq%|^8AuNk88BlM0hm~n24#*Bu}M#X$lF+W! z>^_VUF>_5poHA4WO*Iw}qg5EoK6nHxGQiutfr zzhQ_F{RonFQIKs=A{vqnt(|?-blrnm_;+2ersmmYwK_O9barvbmtC-6lCx+QxR80Z zR3E&hOZ8#Lco$*({UMH03-gi=o{MFSE!arA%zbRpC)i%{=*}5s2dm(I= zd9(8gJblb3z0J`|gcu4J$u98axsMqNa6+)`t6;&hu4JN%V5j>j0?tBrFp6B6&vB)m z-lC~O$}oDd5?R{t>C!Pq4wk7LTNeG3#j@jW>c&_xdIVqG)Ikz_E*bm{!SC~DYz12( z`)ap+qt^R|&VfE=1xDsVL-w%+VmYk(>p`NEPU|yKlLM*A^<>*w9xXQ)VB-zyY3jE{ zUt4RPL4ADSom;2LL+Y+wd0UIdJ4c}o#ryzmQp~lf!Y)+kiZCNWpgl>ijruJk;qY8T^q%aXR<06NoN#0OvF!%>C}4L(X%+vMMB4j(E*WI z2wi6~A2*p}6>}>vE0wYQ!D{oUcV_E5s|E+XJx2sSw*-FMEm^PW#CT^nk#j)_9qy+K z&V`A}>T5{AYsNquZm(EcD1i7o4$2CJQ8bg{=_drxb&wPQUgOn?(IdtKhX|z81VBs+ z6c9~;7(&z|qqjDEjoj>KGOC!C&w@UAO6j4LATCKet2HMT8X0Pkz zFh>YxsEMDy!$qvRVVbMYPFsD^eLa$v@A{5MR`(0wxBj2KpYM;%2 z*-~SxcAjlP6jSM!jtXW2@i#^>L;0V3yT&SY_Bo7mBJ(2pQOJFql!zc_#T0?*$;VQ+ zkT?8^&_fPNou7t&qL`1e+{pw^uXWU+6%|X?ik!#moKPI4WFjtY3!!Ly2Qff~=pIBE~rS zSQ^18>*}PKk13(A90#ExrC`|A=9sq?OPfr#IS>do`J z!Zw^!omecQmY5FFRmF^so6P7hSZeU>(zRoZ8a$tD%@3dChB6tv@8a3Tvoq|zI%6&+TYUq==OFan;`_%1Y2U>V6N`i-a@K73r(UZ*Ykz6d@d;f}XlGA@S)2Z|n__mb>VNJh!P5n}HF5zj zVzM-~Z)h=MO2iDgN<+cde?S35=~Wo4`i&w#7)h82X(Q=s{DjHQWSQ^GCVQJZ!f782 z58xLVTZ_JVMc8gjo&Y@5KupnCX27kNlSpGRNcC&x$hp&~2J9A7YvE*TTux$qEig0- z-2g~OK>2`+pj^)tlnasahyJ5H9BKQU+R;jKa(SUdfI}CsssX^$NeLa{iWO{z-JeEo z+SeR9!mu|=Gt1lXZ<=|k96E+3w7!P5>XuaUT z@0{S4>HKGB z5HUBmx9Uft3dZQaEN3;A#t<9F0SqIiQoHt($Tj%?CQF`Ph||G=(LZa|8@^!cg3*+! z+S*8T1j>F3(<+snU4^ncd7JyDQg{wGcn>-N)qq8yZqXl|DcuW^H({sHaBU6MNMfuO z7+h5Kmf(}5K~Ge5mKYHl4UtzLNFPLiZy}<|H;6`wMiTO~mkxus`M$UL8K!p=Bl*V-j-&8wCHEe$o95Ojuaw3r^ae&u`6LNq%Hv~BfaUF3q_?4z#79> zO6bwYHO0D`J zkssUxjH+0MirxUaVpmT@;YiyBl@*yTuaoav&GNRNM?*2+*}!o( zc0aiQFQp3&?^#l_>6Fudp`z4v2qUxDI2-DY_2Z4+wQ&N12Yu9hf{0!6dD z2Z2S)+fUhYr4%}J(+FJS;*Gz|X| z!ltbzo6iAE<886aBN*=K0yH<^xZ!D3;yeY5edvASySrEld4mS_2#$Nf!?fyWe=gKw zd?;XwWx8_+pIjnkmw+%iRW^|8TdstN!LoF7go%Ojp-$Lk1|AHI!k@-c)i*Pcnd4{G zmlOnpJKJbrVs_H#SoQfN(8*-!L?H=JjA+ zqL$Z7<~3*DIp+QAf2r*WOoX-443V&7BUC^ncZc7F&7WyAa^%*d39P)^PV6NDj& zm@pgMLMn<6%jETZm64xJgMdCVSwa_Qn2SYFk_%YKtMd ze6r0J_mEpFDNe9KVuT3{%@o%Y7TuzcE+Ht_hG5lvr2H@bY5E3#Shxb3{e|WeF?>c{qNPu0`ZW$rwdt2wjoTLD@8BN1!3i{H zcu~#*VnS#pqA<^UZJq|;*NYI2Oq}n?lM5RV)UY3mWdOF&Ff(AQ4O^6zvH8kfO55_( zWcC!B4BoEs@aN?wLuu}XE`sI2bnb|5aawm0(|H!`lq#Z_#TiR~u1O=7*}`V*QOo!nH#+(2l9;(8wVi2hM( zXj#R4o8-`QN$8X*$OC%UKmVN|z{$lfBLz3mmazg`1ie z>VjpFsWX;E5hGD$D}Nz-s8LhpZNl$NCSSlxA4ReHY9Ll$#_*9CmaRPK1Q#@Vj5G%4 z1TDDHft^Gh(9~AKv=ZndfKFC@D+$C<>cj=JSeurNcvmr{>2vCYraui;?+A`Q^$oyA;~{PZ8LgoC<&pCZ^HTD_#qDi zQ;~K`hxE{@Bs+s-&4)oQghcR%DCx*C87Qqnf+I$(Y9Ia|aK$#Bu=}ssE7}XUw>8p- zjZC8ZZ(Dy@><$(LN8=i#EJL{Q0LuZfJB5ri=!9gkIvU;qVuyVby^_Yw3*K95DgAX^ z>~GsnwAz6Z7T|VJ4;LVgrN4w+>6?}FZI@*lgGl2Q$$$n*D+)@`g& z-$7d4F`m^9@SoCY*I#9&w3mJR&-Jw~oBHAP^;c|ozXJ#SVH#Awuz$pXw46!SS9>x8 zs#Q2-xT7vO2c`q7zLcNPEc+DAN?RDIWPTpjr{ZTkN+gf}^-R2N{PQSGjDIe!<3gj6 zB}Qo|332?d;Dh5I*2PR!dnrzYX2)xz0Y{d9h zSHatQgNq+7Bh7do+BWTYu2n#cXJ0&2zx21+|5hIyKo6G2UT{iSnl~DrtPg!zmu-Ae zhBk>s{3Ct1Oh5cz(}%Al^(b}-e;-O8Dv<2kXPdLLJuvu zozGsEyuJTEUc+LvfmUNHmc$TV6q5Y=0CH?fvRz5`@8qan#le;FNgVlcf)&HdtRxD> zr1rD6j`?6RPT`-F$Fe}1JbXp{$JJFc-&-C}9c^P4QqgAd4nZXM4`*?~z0#r~e`6KZ zMHnX<_k@K2_wHcvDfU}aywqV|{RiAj;TQBR&fx>;TO+pe!|U6<>FoU9acm$4+iUu^ zQxr<0Z;eL(2OLW^SP@ObzuS4z@b8~nbsooXU}a;QKe$!5S%Ved{43IFL9%}g1EH9ES`f( zI*rg@!G^0%gr8mtH)RyFk1wxxJi?@h!$oq_vn!98I(FuYd`os{i6zfjJk*)6Heyp7 z-1J$m4j6|L7X42{xu=bEBs{f9alhP0r?!y5trDnH2Lp(*;y$In>Mo(P1(ZkPttA*o z;!G8k;Ni*O8WPM~hyvjud{|WNmyA%52>&DhjDMl8M<%?BzE<&mCw;xAyr;e{KtU?o z>-u_D))y_`nYk54>TbK${>FXXi#Za2E z!J58alLvHAN$Be$3Ct#eIyDBs6nzbqP&J4}si8|GSku>@5_~Wj945iZ`r1GutVl-a zNreBAf83Mj-Qt}v1lZ>=q&gZA?d5#$$o=y`7~SmSH6?Dy1ECAthQ=ju2EM$U?Z=G{ zV>q)cQzJ<)bZ;Onol)IA&}t2RmdPOuzfTFCl2f=p?kDe$3kn93aTAxlZDb5@ye~s( z7}Pn##5okUw?W&0Yo|fQNzx$SBoXge;QA{}uR2g*!U%eZ-GRE?$bpSCq`JSH?mHy? z)&1DIPRt$pEVILm=y0(!L|f`7$k<**F}{tAK^+Y;tkIt~Hv|(sFLs0r*6a_&?X8zz zqAThXhW{P)NF&c$kFaB%BF`0+!28H^EyyIxbN$da z>cvH@*IeJy&r6RKF5+C=fv+YK938`_mQVFw&hdgx&D3S`7`#m zljV6W_zih>8bEorW%z$Vp0mDsM|qkoV+9LRn_akq>PhrSi1qvTFuM+=8e%n_{H~(3 zy(I>}t85<*BIf(ZRvDjKwkO_KwwXXCS+-fBX|LJd5ZJItbp*rzj%-;=8vDC#)PE@7 zo3MvMzUw}ed_Uz>^iE^9fWSMn5t|`*C4TKbrFltgu2PA0Q@+$n9sybMUccY53AGJKp+W6LWP3_ z*5Mpq75T#3H@vwzRpjavcU!|n1;X3M4LypGc%?;qp$qG3 zQB{Af35P{_zT7KUr&vbI)hT-FDVtM5u1>`pyKOOn!rLdeQr4zLo@Yll@_d4a`U3N? z@b$qipD6VdtP*_vT7AG)rXS(*4K$3tev-OH0*gvul6nq6o3HPy&XUlV0W69|x4K<| zg|F|c4wK-YlfiQ&m}`B3-cBO?kc=>l2>)aLcpoLRc(pyEzT=y(x2Ls76^13-qX2QX zMprp>xKZa2CN2kt?!^V1+B%2vhagUq#je&qhr%V zz0axDG7?$5j9=$jkT-N1m%`;GC5Kc8tWJEPi}x&2-?tjYP2FnPvY^r_c(>WX(S+qj zzUGdJctxJ8krT*+m8YjJ7 zuYXUX*k2oaCq#@6yA?x{*&hf|DG~YbmM2(x!DPX!Ddu>qzFuvP=wMuA!VaSLPH-hQ zc%xA)nW|2M+msZd>&uJR~N5f?3zlWAxCV!oVFP z3{-Cov=E@guN1Qv2CV+Khfu1pXl?DMIC!0a57Nk^Zsy>pCW{Z=>W5|fN~?V_3YvWq zLlZIwIfo`>3Mv(vkR_;S=<`fLdXw2J4)|lVw_aPLL}G#0G8=1T2C@^pJY})#`5-$k zZI5(n7(Nm!QgNC8OJwm1n#FE8n-T(|mMQtA2|{<$$2l1{`SW)KI(uhB{XWV6cI&*+&b67!#sm zr9O5)W$oFutK0|tls&cN$%cnI8IvwAoL3|tEO{Q>N8Si6?*J0WyTZI)THbY;cZhi{ zwY(a#>{jO0)ABrJ-eTre((*>jyvcZ|g|xh>GH(R)GBfXg(;wc)O&&*faf7r0E?Q7`AhUhp0J56@u^8!i-BxT@r1w3LYJJ4Or`+%ktG3zdrpERYBj2^V9QkhQ z?SFEA2j4sKF~^I~5a1gO2NkQoV;XiV=FISO6n>x~9zgpvKqQ1clgedx{>$XS>4D+6vAgS)Fz*U3FefKU)Ti*Ua?_h6>hl!*I%96SMbW}FL~v!?!ubk z^)CIRH2r(LTA2Lu(&@lt9$Z7^eA^J0R&ZsLGbCmn@p5Mc*^@y`VkSDSo`-L3;+Iy; z->}KJhO`|IoHt0sFSx975vpO;Kd3I)P@3JnMr2H4g?h95^PPp~Cto2FFK*7fCx+|y zc&OWW>`g*w1=os`;WcBFKkO=bVN}1zO`=G&fK@9N?T&hY#5yXlw7dx)@XFEa{F^@T z9r$;JDVu@cMlKs z>4>!aI|eTmoN@1D-zDzEYH zJmxTsf1>qf^9jMfW)d+C{~mlK3a8;;q3-GPZ{}~({^6l+(;jep<6 zK$3r~I+=d~66>hIve`dc(hu~9{e%FVw0!%8#x|bzikX6+e{n){cn%E<|8Y08HgtbL zy5}`~zd=kw!t|K!n%k(^KI_Ae%6MQM$9t2jE$w?eDuljKp!7HAR<3Oo8+3I0?%OmAWKk1&eR8sx8R>ABQ#nzy2 ze*TcYWxjY>TE2}v*dRVVpdR%T)yV1FSG~kxV$mDhOOg4iFKJUg=pXeN=U>U+=gG=l z1b6X$H#e>t@J7jNlX(YMGRYy#EO^`1p8Ruj*g8wf0^j>uR4D~P98)RgSq6Y>!H-KL#q zYum+;6A+LThh2}}nt;5ZwD)boF;Z1=A!K(&$@}S8GAZURaIg-0$agx&CkS!QoXzgJ z&Wz+^?~80g`>py{F0$N6l=E`G>1BSTnD-Dzerlx79u{*LA1-Kc+bKj{Ya&xE?F?c^ zYN1RC_ZB*^RHL_)?SP88aTh~)y&hN*hA5$kXvJD+#r#+d z27)^vmNro+wp|p9VlnK-d94@4nrp>gv3aNs7Dn636UVcDPzI?l@SoKtEjaob0?DFZ zCbWpTA2S!m$HU7UD{jA_HAanW1ju??vFF%kyV%jGCboioqEhX`r2mbtCMc+OpskPi ze7zFqwVfxwv0hOSO`F-NNrk+Xlocga2ar-i_l5*Eww28a;1TtE*<_-eP=Ayt&bIQ`aaf7rD}jq8FuM)7KQ%B+ z0)J~I8g@cmo*Eb+fk$n?uK`52WV4z|;CcxRQTwyx|6hN}^98S>Vj@4yWw@L#lAxlg z<_m~fn50VOqy}CU;O1gsC}v}WRX@O4!uZuUG3k0tr2Yi8P%N`(eZ;qF_??>kikUMF zmXs#*#3({&F4}3uPctK}m2q&vtb~uUiHV%X;I%pEvQ|`%pOjHBUgXO;NOTAzVFhMo z&Ozd{Vq^ES=VG<#a$TsuCmyOd=6Ep&q1$q%S4(sf8a}QC^-RmFgMDHcOZlL^wv31U`1#7!s zI8v)3@*TqXWfR&Bc=d7_Xj@3V(h#N!nWngyOC>=ZFicARB1P7rOcA&R{GMEn>21pkF;HQPCHlR@%71nt1aooDE?TtPK#P9^#b&RO*VrGymP zV@#V+s2oCdptoH3tpr`~NBCv0@1G8`xvx*~^GDpTS11FeCyVoi6-s<;55i<<)e{ zpAfmM|Js}I)aPU29W{C26QW`h8skCxR_;e7g$N4KR}){#Ey&s9jZ?8zZ3Oomno8~& z)WbA8fA=TqPhz{wcJ{XV$IFdYv61VTdLy?>3DJz+O6W)@T~I0N2PA!1wdYi4#wNG9 zDPE}dmss7oO2)*CN!zNgEc3*`6KsH9_`>H#A6UE4i}M$RUfjn+eU9C-6umI2Cpbtg z`Wj7S&y4DQ91FrR!^ajdw?=}5x>lm(7bsfZVPO4T_umTRe1=bl^m8_7AMIK%d3Bj< zayfRQM9xL7#<0C_biWI1I5^r>cY~MvL0rdAmSjvZvQS>cS0Y@+_wTfiYZ${_am$pZ z5YoU$!}002Oy;9F`gI6$8B$CTIYDlJ>J47tyLo^SEfM!yiG`I>{i8~q=R~L)bXT@#aVIgL5kpxs-@j_6fWqB9>)Vy#v^TZ~Qq@ z4}|sLKp_m5SLPLw`ayRYSBTy0co=&PiJ)M77t_&XX^gWVtW(1w6ZIB%J7r;vGLq!3 zqE+7uMDVp?gD%LJx{#u7NnHT5rmeuIC}3+*7%Jle8gFXkO3ba8`Tapyb>T$Irig=M z`8iF|X^iFZK5WT+XJGEo10$ICwhiD5HbXw0r#pZPH_V$TNfL0t*?*6GlBeJA%X?;LwjepPzya z?S#!MTfXfn{B!YrP}no=yD@!W50XscflPVB1ST!O|R z;U2Z)N2~lBqttooF!2Gi%*W){;X)5OD0PnWyIy$_yL=VhEFkbx<}-Gp!C7{xbt zg(>TV-I7pz=&>t4SExod1$))q@ltwjBrF#M{nE$@wPNQ?`^>|qLmZUj5Gflo=mIi z-A`HLekHk{zIO8LHZP50N|xBi3+6Y)_Us0*0e^^H1` zi6Nqx4~bX%60%6G_lCXGzIvsk_X8$k{%)haVmJ1VHhY(3lT**$c*E}g4o4`Nw^_v* zwt4`~E;oWSvcz7oa-(&sO1HXQP8!((C#5I_u zU<$3g{4yu}0$OF z%7neHF=Zn^k_=Cc+>>w9b&e5Ipf@sts~7nuoUd9DV*-YJvQZj(TvWhGX=?fX+wru& zzfsdSSz=?y zV8-je#E~5a2^{M8ndFe0>ViWas5N#NAqG{YZ-@0yGB^jp@Bf#2ec{6G0cw59?{SD_ zhPKA=l$}ofdmQV$L=VV2UMndeXP$<#jVtTPE*R9$)0t@gqRC?Z;dxVt+yj`-{RlY{ z14RyhdI!!^CdKT*N!KkK zl%(5&Y(y8wAz^V*A+$!85pDb^r-CIIU%#QCphW3uv7%%1RT!3`>EelD_b8%{MuLZ_0p zy{7i|raGR6!C2dRx)9&3i8*()m>#%x_DFP<>ts18U|TXUkFYMVv^2cvfq{6Ur~%T4 z6%oH~q{$xAtw61V8K&eRT{eXq(DVXB>JoH9us~hS;cC%4){z6#s2;(A#eXIu_6O@< ztR>ngmNm}M1emltQB*Vh{uP(nWJXvrFR*37&rqUITr6_`h-UJdxIP`P)`Ia1eU{Z> zyn`SBsvMCXp4*+-GmF005!g{qd82d7LGxo4`h8%I*yYpa%|HM#<8WU6fpD=j0g}IZ z0J~FgZJHmYITnY8%n=>toOCwF4s0^ZXlfYuEU}*n&&)M8YrT87jiIY&iC+l+}MFkwjl_0y` z{JAxUiTt)g0*_x)7!J#GT+Ph`mp5MtXtSPta#62hEJp4SmUmc1V1ie;I}#mKl)Q%8 zt=C(!G`AjuCbiC*VL`ae5YS)D4D_?T5JVzk39O~I;w7g=Zyu%Bb_Hjm_Q zXmpNIvtm(pME$b{Lg5?w7}dOLe#yYFqx&! zt3?h$`GFiKkt^Gf6Tl&8o_rN%l>|E2fJeAU5Vb{0$m1GX?L09#qIOQHqgJXqdPwAW ziJYW{31l}SXZ(Fw4y2i1`Z-5pa*=+Z-H3+T?dTt3P7_E@l=- zj$^*{l6GdvO?%BV!Lr$;m52sj+L;BwLIA=uq!rmsxNTEKr+T{H^+fc4_Ti zMWoqce%eKwS{$^grMZ0q-<;H@7MQKWY8!0crf0UIq}g)8D2?0^k3#BRXJFdQRv~&? z25|`oCM!<`5;+fV>k?^>rS~Z(qQk1mRWn&w4rv!=G#e9@%4DT`Rj#7?5sjZ2t0*6T z-a)BSTN)UuL|Oy$T{VtuaWBJB-9#tIqIaq;2DhVnri~o-(drxt`LmjUM60_9QG1EP z!n7E%(3hqqTJ0y1Puh?t6ZwDH-(QcXN}lgBo@(+Cg_9CY;NOj>ANFbE>8H$pGoE4r zOn*ET!+3?VFO9J&yBJSDaMFCw@$>*Al;bHUT9$e|?fb!2#b1o4;cR3oSM5Tke=?rz zc(|F48=#G+^OzzvH{i?Cz)XKU32vl}r)pxV6u$Febssn-T!8l(Pd{@-kTRaGU<%`e z{pNUTRVCGU>VaX0@f2T08&6@_<=`|Lt$ItyIthtZ`x2rS5{1QhN~+2VIaNoi#U=7s z8*)7&|1bMXGoIGGzW(`C8&Ypw|L_0rj>bzzBgN_Im7u8yn{`v>NzgYj&6D+<%GO5--oHqYC zi{<(U;t}hg-Dz2zW4o=2^jW<3RazF8M*6?G{=t$jJsGW+GP;Vb@W>rWbR>oq2d2&N zy}ACm&*f37^^cf^we`YlR}>aTbzUXbOrwhRk3_C)Lr#zvaPOgW#5!g#^P+E=w8 zrj%Vq@ePdxoJZkwsPA(s3pNgUs)J3ogIFA?jf?W!sUEBeymPK>FR&4Hnz`xRkvgn&6gR>F*KlD%dM?BAwJHU4PKTg)%5QxCGa?e3u z0NbFWpHL}+@gv4qqT;1*u?LEcI$ZCBghUA}`)XkcnQFhAq&*x;zW$!yg>m90*>eK(WFGUfIizFq?*F{rMx zMUiD?iwvsitt}G#!}#asI@E%j>nFrI-fo1u#>uc~^xyVkwcK2HOIgt$S3|iq0q62! zbA&-z zi%$slKOT|2Jlf*Tqlu2=85fqgP`vPA|$)Kotw)0$Zu?!Qd#+R(5f}OJ7U1$&>!RbXUwfYD2NzN@q%FHwJxuv8OcO zS;y`BvHLj+x_0Rtlj7$4Q+zYIZ;-OwP8MIZ6ki{VK!^_{L=S|-dx#?O>Q2~IA->V6 z$483zyulqD&1->U_2J|%n?c;VwIx>X_IV5=^8@WS8^=cJI zV1l=$`S$EC=OJ7AS*AZ0Y);6;a#pdcq>dX<1;hI)GK0AZSCyO#09JolUEf^ zsX3!d>BwK4s_-i}>I9C|h|!MVi<3N2;mFXKtnGG2ry`Z^Zf9%tGf5_yy|G@=B%`tS z=a;DDP4@0(_M7Y-nlE8FAnMoXc%(WW;Su#KhI0K8s7~hi!ufx34sM@7bv>3dTpJkF zAPKo3AqI6OA*!b+Oa`mPN}{M(e;Cxp5_ydcxet(`U|fF~)JhUK#RfEKbp)!85)y2y zy}GF5=VGD_tYce=lsbMXFPf^@$k?T>BUS=kZ9o-!9_&Y;x<*3s+3Gk(h&mi~M5=>D z*q`-f{QW=70pZVSzNkkfsJdK5g>XU;_ec06UBOxLeSCOxImDrcRbSx_C%E7eu;m8D zoZ^RmZ-5>qzqlf=Ke?%1JQuO(R~6wvqU!d-uHL({6!$N2$r6_<;ql@sue@~GK*a@2 z{EJJMNopQWB%%8~(z%|3`;`5haUWZJ{{R<@y?F~%_=dQ_7(XbBj~R|Mek#hfCB97u>zG}!6t_2-58xaJUw2d+)!{u~S1=3ciG}EA z%A5VXT&N~sm58kxUWio)$%fAyqBV`292~RbQ;80a&GBWlX2@ym7>?~~yfPgGuPd&x zFp}t!+uvXAdV)@> z6Q29jdFC+wnwa#x9lfn_3V!Jno$^)oKF`KCA#h8bKVyx%%3Myn?lVR7#5_?aen=iA zE;br;@T1NZ603oEIlawKz3ar`&GjVjI!O)_!$@@Rt!&EJKXr~e9e!ICm`a^v4ioxv zni!JW{ZDL*jk`u5)zHEO>t`te7oETXDn$z6p?J*8~4dGD9YiFoP0|OLf%nGZtG@ zqm>xc8JLkbFwvl*xTgjYe{Kw^IEdSJ)Wntk_Zl(N>A5U_>&!PJBbXx}8nw&4x1KFHB4`;&9XCuot|l4g z%TW>alVZ6}I?2gu|na7TkiH(PK?K+(6HxTe~SLb>O zaoWqd{>=e4cCHoTn3@H4Zr;Sy-QF`)ge&b_|CHphb+gIqd}pRcoh(DqBq3OnmzF~l zBH~wHXPAeh4^k=kE2tYWUy6V%b9sv3ZIA!`@rd-6uNB{nN5ENrj4@&(?c{d*5i|K7 z$FVi)t1SF`4n+Z_#`G%bB%Z8N#6NjulqNLD-X}l=z^oV*i4~O+ncz}T;HvjtyVqOa z(3d1-+tbGJspC#FYCo896S_BJP^a;97UgR@XB=xRJx1W*a5RgUeu>M*!FxzCQj@^J zx52?N+k0x34U;68O>H|ky~9YI#kP$dn#{6?BM6yopYh*4Pe?qTfvQZ(!GH=wd(B85 zuF>;4_JO=)B|W369xdBd{x0IRy^T;9^B7-iq2|f_3Qr!d zd2)sm3vXuWji;)$;X+MhUA1q0u>I@r*JI;;#h;b1MCM`}5%6cXVBmQ1*)^WXjr?+N z%QX%y_!kA!lMgudW-GPS1bcJAXbo@E>X`cAUBhHA&o^8dK0S$x>A| zsUHrNhOQH4KcPf!^BSBvZ6m+I{jL{}RbCn^>rbXdPMtlF7G#`)A$~}sr&1!F(p z4eKAd|3CW^{Pv4|<6K*8BT)E8l$@J%FWh$@ZX;0mpoqC4YQD>cEQnbKZz3bw;15pk zt(Rz3OaHjzZvIh`LlCD@yuvN)nRq)Z!X>H%*+AbMA{u28@d*}t6vF#N`9v5FoI*pi zy9J*2XaQmfYvyyr5x&DPPwX2;+1RE78fCXXdk}E(Jga8c(@7egRtfodW$_xcP(`DlNw+H1r`&5Y|l?9cM1QUl>NMv zZSR+|PF*N;#J5^5TuanXbvbCG4FRu&sL+3vc7vne`l+X?%CUSy9U zgT#IA0}a&sDn^19kcdr!KN7y_5&}4(T2+^VuZz?qe%Gqypz&H2mHYoM{{<$V2Xzwc z#|*nomiVGT2;t(wQZh@I#5xpVryyHfHF_?x}a&SG&X_gnWtYGfx9d2BKT zR_H*$@V7~t)2T+`X!59QbXVfnqobxI^1$Aj8#b131U8(q#0-yZ`sun zvE}u4L{crUdvAY|Dpd0kS$1UYEtJn^3F6J5MIfAj5j+DS>3@^VApzwi-BG!lD%J$U zFnu9&v>%;CrTPI2IAQdYgjN1mug0-1+@*14{WNaoL29$sS7Q50m%X<{CPepzkUw>O zk)ZfS+O}3T%Kd-9U*7o{t3bT_1xDEa56ZB`W7wE#i&f!Q`;)3(6_URjscItIpnC~b zB&6z!)Zc-!B~nd9{ZqGD{Sat~K=tv_az&t;ctk!ALtMnf4RY(D_|pvcZ}5m}`Zy*fjUZ)8wa1M&l5_$h!$ zlV-tavQ4rHc|PF!WdOreEzN;mzri^nztgCCg`nyR)-$+21C_OEslI<)e*g3SdYuQU zz~FKrg{J$-p&1NjjR*!KEPu4Sg~7vnK;hji4C*$iDzE`0UTN8GITYnJAS6iqRq?ac zNDQ&c31XY}io{p8TPVux!&fdcCZx71<$1psGzJnli_>KF+Rv3#Mchga;S*QvpU1g zh`SExJRG4uUFQEyW|}y_xB0KfW9hPoC2buo*`!8$q`!Jv{4FhwvJ6O>ojv*e?iUBY ztd`(QlbI4QytQhvXe8&Ykg>E}V>mT|g~cXy97w)aeMd_Se!2g@{u9L-@h*OMH}Nj6 zfgkm4Pv9J_EY6-mQgJ|*rB9U&{-{U;qF1YueV73j;4)~Hay|e9<3}Zn#OxR%MCp*n zk(kkc1nTB*jUNM{D%bWsf{YqZ$>$cz@;IFBoG!D>~{~>Qi{4E}bHDyHRzZts&NDHIfHS#^{+Y zyOaVc?J%KBYoYDCwzkKRul0}K!`vWJiKe+QN%A>V_G7 zWt~uC9ZyrJ6$`)w>B#P+XoiGQ2hwF9K1#1d&tRWC^9^A#meY(N)kXWGmg+mKU-(%j z7`l*aWK(NQBKaiVW7OTHzARdd6fKOX&rw5UbrsI)Hh^oXCydT#tTB8xyPDeihz#Hs zw5H=M--B&`VaGT&l`b_-Q>E>qz_4a{)GVZCioy#oWai3voH7_QM4IPSIRIxhu|{p# zwlmGd!%b?9dWU=M%a2xHCg~78Di@2aq}8D@2@#)q-!I!3J%PGit$*5CB*{Tb39dAQ=>`4AYJz8 zuQO{=O03nvtFjTXYP)|zOIV3!rjgnqd{$}*na}B>sYy?!yeXj4WfxJXH3gnkt7Hsz zDY+*spBwU%n*v69Wnko}uL}OdSv3B?tUOxUcvj7$oPO{>gZlJVYew^t{u-&;M*2%J zSA1c_-Nz66jNeJ6`#F9C_G$dI5)(j}y;}c1`wPkQwElfe|NdD2KE*FSOn+Eg z?C6$=8tLJ`;a13@N0t)kOF|Xcp|CL0(5Y;*g5&TDwd5CBjo*vK&ko6?bi(Rlhw>m! z;liY|U9YoUud`jRvuQQ$xiW1m4Q$k0Xlrs;Ozm-`H_?MJ4cu8R+D0wQZl;M&R)+vWrDThi*wNCL_DMKU$S&^>>SSdx4!t#)m&(`R=KIhW? zIW9}-;U8HkA4^J)PEl4$x1?;;DgSGwydf!_I^`uRy#ENWxk{g z*C{tyDK|^XfjXthO1VK&oH}KSm2#z|e1NhkJ^W%T&O!~ggN_jz2 z-qa~8t&~nld0wYHX{F3wMaok;Wg55C{!7X8OPz8*w>mx?LL27K<;9LftT9#5>aA>e^*{&B)&oPkd(V#=Od6#%Ka66ibD-JmTLO#k^a64*syS{q+kJ1MWzrDbu&zOe7(l!RH+!a z)3!a0Pk;S6H&b9g{rSt^b+J2iyRmHc-!nVLU=D|znIe0&@w--GYx4{12Z#D=B8uOxwGG*fF!#;OtQc=Kpb{^%n3S6oSEFvzgwn-<)a>YMwx1j)a`LcZD z;2H_8nQ{-#w3_Mrp-f+MH9`D-A&R{eA!+rx7-8P835ojVN5ESA+xT*nuA6N_E48CQ zjP<}?-PHQfggfW=hbPBMB`NoPy6^Vn-N!KqWD4vDPu72^iw)-&+wT~_=UObVC)z#T zzE5^qsu7y>W?uSsv{-s&LHeq^^i6r`kL9Iz<)wc&Fa6QH^m%#d_vWQvm6zU}mp&mc zeQI8MOBe(W} zXFE*0H#}qeTjoW5%e;1%GX48oW>McV58kEBwOSn`o-g~@_utIx)Awg!_PzT)Yk$kU ztZ$h&WXts1_*t>PWe)0F=9jW%W^jI;R%7hB?};5nb0^0x#Hs2`IdC{AKPSr1G4gYW z{FKV#v=M@FKNAtR9QR23x(?Kn=c)E}6T_jO?dukrD9>GzKhf=pohQXbXa*}O0H^7-ji?vQlY`OKlGBYM0&auY?t*VshZX&_(hO@$Umaq1(IdqMxW8IBL^+35lULEi{E$oU`Q`M@Ax^Dn6vhC@6W0<%VOhPolNk7?yGJ2L@dkOm^<^?qN zBWueyO-6+uF?U2$V_YgoPK})Zkx^Uv=5~)G?laokeN(ozr_*s~hta;u*M0XN z`*xQhp3gjl4O{iui7u~%RJh#V`O`$c3 zcb&0H`5Bh@gkmfUmW-=ffPt#Vt*-xcXWF|M7c$Z!=%l!I9}R)6!(Mkct3Vzl5>DT- zk>{L@Df(f1Y#5iQ`61EY55PXwg3Ygs!c-3pU$CJS!%tv|GjZyNSeS6ac!pPY{N6PHBUO6Nf1~Al`F%n8__6A8aG&gcX4IFj((ene z)jPM;X*K#s-su%KI)QjRYB3Hboa zxnbgYS^CP#VnWTnkapiNsMw+5W(Abhydfs|l0y|X*wcPLwJhonP+uS|D_2zo7VI$H z?++9m@7z-HTN0sM%irm)r28das1y}z==u|*R=K-rD=aXmAzV*bKqqv?0%9Hg>Q^TXr0KsB} zM+T>wn;&8X@z#_bM?2>h;brnyAe9=;CR69kFh-?&g(Wkb12f(~JwvfeJR`*cfCc*kB6Fj_r;wvLLA zuquuX&g4m#y|V%!r(^C!x-cHd7W+7Qs7#G9HW0Y~+-xb$ChalN*(0SBDkzByAK6ieHxL`q5W+pfUuNBSv^sfKUu1%?~-L# zUES9-k9Yreu6)1ybzi2Q`lSC{5G2Cwl^pr& zog>NCTSk3}Nnm$>_v@Xk?DLweI#OlFyp!Sl2@-IWm!qS^j|XhF3Qi>{e2h~ zUuEG|y((RH=(kaWN+8C8+@#Bf>c_4pid_z&)BcMXVh?HA%Iq7<1i_BEW#W;8U)Q&U zXvB(^30-^kSP1CZMNo^oahwpRGWLbLYdoTGmHR{+=;2;P22koKNlv=IJwToy+T7p6 zn@;z&q)0P5-B)raRJ+rCgMDX(1HZaWDD_qHWv9z2HRsaJ(p4V(APha{bY2%Vune5JF#@dnVOu+8U71XEvc4uU;qtf`i!Tuu| z=*&ryoOJ)pC7oHwuhp5`xRcIsz>eXV;WN0_JK`Sbv_Yy)9z0_pa5CUS{OY^5qoD1S2uI zVkGax)smjovxmuchS2UH4f25bUKfjBye>`-+})ewf!;TweJyCkwr@%+ej}}@#@VV( zn$iG$PM7^z-q4PkTsv?Qv(+kJs$Vokv@I1_%;1YmHu1^N_zO^ zw8+Xt+TEme--7yA!yx7UKF=CZaI+s}@1bXE%d;{aJQeEF=k-kiZOJov3q4eK{u$}0 zOI~zOM7+y1CE6Gq74$9%d4|@dN<2`xa#m+LVF3F~o9j}pRduypvBQIAq{OIwVcMXe z8T1skvx#!rfJmafvggeRytulpzY*-dk>*g5Y(G0@Y2AhF(Wr68zhqFQQP@6jWPO-T zK!cYJf=NuNG0NkGk2*U}=u^@ahUpq!#U!8t-H$W>q*uI0W?x8Dj2<^zkz+%v+qM|q z$4c*mpvC`sg7C`9jz^t6+cKTCuezK8Ryjp#0^)Jc!RiKN5|#rsEI623t`pjNiqx{_ zcBUV7_6BBN87y+%eOXoy-n*^3^4_UeUXnL)Dd+%I`lfy;Qgi>8%HHdzOx>m$#ggY@ zvh>cN<(S-lL#@GOy(a`bsrOTq!`v9Z5-r)x|5oKzFDh{it)M3hq@o8|`O*RD*|+5R9{n8q zDkD}c5oN-0B*sKn`eW~0_XT8No?p&I9_7m8)m&D(PvY09M-1D=GB=%3!}g@s$bdm# zffGy5c6)ZXgG+a&GONa!2mMd~-NfC#9-2;o!uB+2Sy=C9Nbfo2)Q zo|9dz|CI2Ml;CYSmpP`jh^6@rpL0j(no&;SZv`K*ai}q8*MRj%I#XrbeU_OJ$9M+EUP~v-ZBP6sthh&$3{r? z2N7p@OqV&yY?$9yWHVBCZ{Q{C04;rda2sy`@2CvdPi@j~b*3EWN3oky@p;F zPf#W+c@ZipPZkQP@D}e~1g%4;lS(H@rPPM2>uKCF-AX_YPs%7%uZZZ&ew=jx3%@ae z*rOUebT88D6Wfp()#H)-(1OC=!&)Fk$b9Pu_Sqr5Oo>7`uCUTu4=3>@a zGcJ!^_v)SyD`o|5O9W&lW%LijtBZwk$F|$Zh;>AzmZTg?y<(&j@JW`MtMcm)y4#>#16(tk}kp5cDml>y(a@4R0ao20jaW6JD{W*a(CM=Gjqcyx~_6T zRv)L4uJS$*GTXz|uZPSv!FgM*i(PR|aNdVwuedHAGS{11s#gVx1`;0B<$WMH@1v`( zyCRZwRfGqvW{$bc9S~3tEAEnby^$zA;!WB=e9P%+@2PG00mmv&Z5UACh#h%qlUxpQ zKf2>Hben$83|{7B`7EN1;r(&@^r0csJ@qq>BbexNhLY|}xa}z-?Obk%Va>Lfl<{fp zmRtTy+Dh#qQ?!S!Ox@lm-Y%X#Fg&Q8Z;#}YPPe(qqe~AZOIx}1KCyYIHz7y4lQ5lx z--~N%@=MoP?+%@QBRLM6KAqy7>x}ld{KlYl)&@&ibsyDnN=N*B(|sDb6J4H8_gA

;QPSSk<+uJ9Qy+zylwBP;h zgC$nym$nx8VgRhzz{E>+hB>LqFavPO2FjJCzF+JArp@IEUh0=%Lf)-~p17O(eGzRH@LeWcKm-7T zhik-_h2NguY5LxK&4NXMO>RnqVu$)0dQYr-w22LXlSZm{k)tZ{i>%OUN2gQR9hi^=4q|#P2j2@UbdSn8ie(S{LJTFVB4)kEyLe#YP477G zA6kYy^rXizdcndWZCs5J>&(%gy{IC|dQT9e*j}=c7u1kWj&^PB@WciN&4Nf`xhpx^v$eyQ z_gE5XET{u^>{ASlWOqfperrcTY&>18+)dGpVaPoDv*3&GhB^B=488W71?D)HkviK` zyON^Q?cv(h(|US}gS_u4Opf-6A!#^G^;kG@SD&UX51RF#z4&f0c@9|0=DO&JPN7!B z9|WTC2(cv-nJY_K_b`b2_=@NY9u8an@IgUXLIq`zwb+JX@t%=&PuULJOKISAA7m9w z-N(M!Yke7i+&b2%P8Mo-C2-e_stx96>DqcJ2o@AnXzz(W_^qQt=v~#HsIANSm;kKi z8uoswY1u+YScS$11QV;$J+6>x;MM|hA?I^yu2_#4t|}R$Jt4e3CbA~PF$TUa0tD6 z3EFrk@9=pC(l0qDbLop4zKjbN*a=wP)_82yx`0w)I+#@X!p| zgf_;|y+qBz8;U@4=9Vzd04);kFKUkUpyZ1- zUPOeAu8^sM<}0ZSH6@IsT&<&PW96o@!7KznJ)o<`tYRb2U{cuei!mPr!svDW6A#)Iz3PyTc{vhL%Dm(7SG7ra;vmu-n z(wB^O<>zMZ(D|!^=Jueu#T(ioW!mMP;{ljC64ftvHj?LflI%*)lEppb$|HCE=1Pvy z)J}>t2O30sPmZq$*S34-N7x6IUPxLh%IoIP-{*z|}6c@cv( z-7jZ@GIDW3EX6A7Wguk?;Sz8EQ+Y$*@ixpMOf`5X0+P%#o?#t}f3$C`Bex!qa~s)fKVjyfx^V+oH&z({pXkB6XIjy5!(`cB`_nw_eA1igHnW}y^Sh% zCveDfAi%S{uID+xa|6%yUSDf7C6m-ZQj=jeOH@4`o4iAk^2SKclN2f%{elP+gQ%KV zVBxd4{?KR)U&i%8p3mpH#Je~=muqLl937AqQzbWq1FO3SX(5^nKO(_|s*L2srz0kZ zYRf{5AYHPGOPBrS23b|rd1agVFFL_cD|pmDL5H~u48OguFAR5F{BMHc!)xhT9{_5= znBnUMkU0Pv<#lGjA1NH?sVn3Jj>hnnyx-g(V2xxQk--=j4OU8f)dq7f_}a5#bThvT}&s!V_t&MxEwoW$6ArGCFUNa=tn55<*aiF zyu-?1!k(8C5uCNGmhF-LWwY&>0A{lxBMS|oZ55KX$FgO8G(oztHxg`T+jA3iXKayk zf?gj9h$0n{gmQZ4qb5k_OAndR|JPnKax4zKLzL%5(6@Hdr0Ijy=NK@tSWjXxg@XwD zyWW$8CevO)1*0J^cJJi#Xxpvm1_(|%wx}f?=B4`|Am=~gP|0G6K!52kUG_2=+ z_3doIBEcrK&j062cE|rkc2y0!OqPE+y|qp^tn{gQ>Dm6N5mr6&QJz$udq2o}FCXW< z@2+`NH>LY)*42_BkbbA4HEXiGad7hno5jwJ+JcGMt)7OW11xyvB_q}2*27fwbGb3k zABl6fcw!FJ(ymcxG@u|rgCumjN@%-C;eG?h?*xvQNUna-u_muW2>R%F}M$~1+)OnlC<=E7SY zzCn(`_{>xZ>#$YcTZ33@7bQ;pQ5WiX@2zj+DHEBu z-QjmQW(<=XN4aBW=~nk(d{7I#^Cv^;p4oYQ!HOTvx&E4hO_Bk~dv9BTI3!xD#G6O3 zk;oqzu_`j+g}TD_Y=$3`!7k2w`)T%Q<;IIL2l9WmpPvf@{9NAf%;$59`JdqD=Yjw~ z-)JCxK{Ew${nq`~^?PmB^?^-t{d}&L&$!-szxDjxHtYJMOK9#AJW{-U5J@q-;w6errCF- z1+r=O9cc~OH2d!Q=)h(vELtoVp6<7vrN@J&$B1B!#$Ct_{`vlrl3!F(x@`EpIc7BV!0 zG2Yw0$*+akUNGC2kJ*x8#tq&hLJk(g%rx)yXZ!fM(9h515{adl{|P>RE|BOf-(cN* z{kVW+W8roEg$~{(qUm>mqcr8sEf$Wt1V>x5 zFqh^7Bbn;J$a-32J;_Bd%zBawPmfwpa^b1XdXfuI>#Qfa@U+Q#(wA$TLQotXS$fM# zD{8JcM!XOy>|)(HWD8a&AHtDuYr8jg5Y*bB!CoKlTtmD=kZs%RMsV;#SERkWD0aQ~ zSZB}BUgP6EHt6H{R9zG*hasDcdEEj8(wn@;Mp&1HhOkbH4hclkt4ORTk@Z_>2#dMs z5I-qZr1&Mp=k=8giT_$kj3hSA^;Wi9^}1q*N0vG5zo_?-)$mZC_qLC~ zx+xLwb?sBU4Q)16nCa`jT9R|+Z*{-_N61M09#AEU?`opmCm0_cVIx~n?9^y&>6z_V z(Qj|ic9-&$qApgPDppi^WTyaKEo?(!Zu0Z`f+l?r*f<5 zBhMctCwxNwoxJnO{}iOv)_O!Np`Z4%q>B{$Z=Y)HOYNTVsI_vjY#~>MZcUl(xKbVJ!`GpyX;y;$|~JWS(Z&0+nMZjEVuTdHs6RHN<#g8 z7>h~;sD(pD;(5HaI-5t0bi|3SewI_+^Mr`^8|3X_Q4=@K^HFtosUQ7Hk~@Mc&+wq* zX1AEA2Jd(Tw?mGzNrGOK1lfz}KxyR|5_>Ji zn6-P>sdv}u`N^&^jvr9-(9+hKS8|}#$r1Cik#!^fwl(aU5;SKT-uZuI{)h>qO29O- zw%VImfHY_BGz!yZ=u=me6QOSX1$lVz$V1}$JS1-U)aUTFe9O8mamEhfb&1vvMhaI% z%$L*a=C{q7JtsDAwnMwQRpQEd?ReZ~Vu#}(H<>$iFp4T5JlOJzFrQ7A)sbvQKlKH* z4@jhNEd{BM(7i^?u>nrtG0*)J_3E=Bv(6DI52tGB0tl zZ`vOVVR{JD$P&>CNy{V^|=a90AKOD_-O zZND~Xt_s(_5I;@wPzK)k+v62stP#icd?|H?^D$>IIo1ftcl5Kaa78eU6%%*;RjeD$ zb{c!@d2~a=BF~y27J})4URHwrpyB_ztli(RR2AK`AJ!9JXuve<7X9?3dZArOB?{CwY)!pA)Y||~; z{P-_3_kCzlA9|EucCU8bKmmJedtLu|>6Rtz~tHI7$({`C2O7opm`nlk{Wm-n&nIjgto zGf+NUB-Y^ht0;b{qY|oH5DJ{I-gqmTPZ@5@*vw?NWO)F!eK~4wQY)y7-6(b5$4-m6<&4z>^m$+G%J|=O*>5i>hK_6#djCWG z9VD3TJ^H%x-!n0_PHzPRncbgqEY0PiNZp9irf0YNQ%(}x%9!AD)@vz`y&1Q%SE1L& z6-fuX2C9XWst)I;*K6%Vt(tl#YhP2W(O0&z$B_bzc{Q5ipTo%!t~gOD{9h6C3x3Tr z1BMx_l5soPAOHnw&>=?Q1PpAEN_8fF%su{|!?!woV7(cvG&u8-QgP3P_lj%Nc5zHk ztT1*#zC2ts(r;OOF{6KNSr5N454L@+57fTarRJDylQ;}f_%&`auvc-h7CV1(l3)8+ z7g`UM>WX_UGLTnO?w0AP4QknWuhyWbL`Bdv7Ns%K__&ToE4 z_s<$T^b)k)+meDn8Rh}{ejfMpPSFT`W8x+ddOC-CWD$CbbTew6J<@12O2lP}#mZ=N z=#csA=ZuP^F7QPf9d)S-ed8LVJ{L4NTDUPf;&qHmXLuKvlm|zwihCeu7|!E8p!xx6 z)<|tki@Dl`S`bC^{+^H3kAJwwVaR|cdli1W^(WRhyU5?^vhcaZj$L-~XYp4g&t-hv z58pz=ogTh~uLWoGqyKXA>VCm2{pN2x4&`st(qVDum|0+}MThdN5mNtq zl|mtgz&74{4oqS{p<6k01=&HSo!PR@(vv7Su_GO;7G^kDr6H(hsh>nRMD=?0D|{`) z7Q+@T_xE&(8$=FYqkbvw41MMA46rpGJ^NGnv<=Q72&O*%er~*MIX&aUmpJv;kK>RY zm&h7o^-h;9Ih#$brQaph+^((`Zk<@2uHMQM2sc z`_|61y~}i${z$oI=>bv}C{m&}!5kB%PU%5!CdikPx31ARtWF%=oI%s&Ol;p7AB2q| zVy;#jWu2HKG~~DG3(gY=?id&-RQ@ zxegRW42I0$P~0qJK~#n3)S7XPLx)5P*BiC3O=Ho6i)Gg|C5~wa22&BvNOi3lZH6Fx zdgdUy_55AE_PyN1kP7?!W&M(xShUX~BzKcPaib5>YXj;~Z_C5re6%rwS^uQfbEMxl zc@QlNpJ%=xG-8Y|wjF%?ICFM|%?of2?P2W|yBhxn>~owmyxZJtn8qKtaErMzQiwl6 zr%}6M+6c*yo6>G72$~b{7EP}X*LF<%sldl&F7GK6aTQ#KhKLpdbpYVRgKAF_Odo*s zc|hVtESI_t zYK2o=QO^L}C_|=r!g*U}vI+>}s5nHO#cLK4V5AA2&%QggE>?y0Hu zrpC%c?JWbz<}nH>Y0K8a=GY0rtpj|q;|$Y%fMKEj)!BN5;%zyeZzRS~%YVrY z=Wd%_J(sa(B6euRtP|qyZ5fiu;?Y?K_nc0N&e%B4z9R$e{5v?I%MjPVy2dkbLVQl0 z2bBya<_z_C=l@dP*PP~Uc|dN=!4X2Is-Z&rk^{QM8WF6SQy%k18ZRwZn`K_6N($MW z&Jkp9(17@fk($|+-j=)MV`-_$4S9!3G15r23Q7aT)jp`tsXtM0Ppy0tyNdj=$za?N zb%&nsUATO*^Vfo)Ot7)R1p_Kv1aw-pZ6gshWZRP8?94cA*9+E660B)p231);fgS2z zBr^4F`T3^&B;}`tpG9hp{PsbZ|AWVU$3Kt8Kact=L}3^FyNU6(@b7tETlfcJ<>Q|m z&sB4CNxZn`W|ub=(NC^hip?=4HUf@ul;i94xE>=n76vwK9pn1P zQSe1X=sls}og$I$ih`4+v-^pHXGl?56ugj%cSXSx3yA*|6fC}KTduY zsZa0vk3hkUZZt~+<)m^y4j&Td?)6|z`D`ZmM?FQ6#wJke1hwjubQ-k*@jACV<5!~Y zWon;Uss6f5{3*B8Tvm=au!c3D(RdjXctenlf^taoO7Y!++Wg`UAWpz$`?DqapWT)F zEcd~>6kxLWv-VTZQxvPE-~Iw1>^tZB^mmfW?r_j-Vs4zECJ`a6pALVH$dm2xYmk%O zba>e}dv$na{%1eVeU|I+8w+>e;Z9_-FG99#SwZ61<)6fh6LXYfo7(gUG2m}SQwF>j zeK=0L1f*N5?xR9El4BiN=&fP?wxUaNLy;x4oE-CkM~)orAe*~3@Ct_@vqp_&t!Ol! zSyE>{CntM6$_se#f`t{bGaM~aD_is_U!OoFTl)eq;*sdoId1hDab*gz#(iJ(G3I?0 z_sb`V6%AQWZw{3Fg0%Vz!{Ii}QG18Ok9L8>=}dLt;QL45(88kQp9}}<%)Yz>nK$6l zTq$JTbh~~E>DMmJpu$tK>=MKWC|#kQxt3(s~r9JOPG<8WhXmMo>FXqUY6pQg+_4U_lwU+b~Hxr*?a;7?OLPn}l+<^M5^^8QrNQXM;c!vYkVVN9+TwNvi-j<8_y88rvrTAI6i(>fi(1<+Z?j`<*0&tKSdRTwmh7?RP-joPWRcIW=)9fR&gQ zi0{woh@)Y1r8;woIMatWh_`z}v6o+;irZMB4oVVVL958MUE=n*ia| z$LBSvw#*9>%@T?0HhKQ4Iiu7=I-QNMQF9D2CGZ9$^gtae+I0Z4RUN`OvK4qZyD}#m z2@Xhf=`d`Qi4uzGhfO3O#4hKU!$sZKpzl~P|6W=K*d(4B1Hw{yVl%#xlNNv+T!u zX3=o!J>t|OQPz5I{e&_ZP=9Q&I_plE?`QexPW(u7Y(={&c*yB(5yEJ1yDEmCfkiqx zY&OIEQoyc@7@|s~2*A)dmQwW2o0moPkUCCd-+WQHaf)iIoX%&yA~bqC3}Zpc0zsDz zf)|Cr%8o2(t06Qs0OUvVU&R;FLFUUf^fLJ~xYMbLxh0MnCpSMOWia!^XlX%8U`jrY za_bZjq2&)zV5NXq14&_|R35QBBxYd|zLFgSgg{%XW(i}Pw?ZgNj%ss) z|NhVV(EW!i#PJZ)->S)gyZDD0($BQ~-4?+#33B^WkA4lw=b$d)%|h%s75#o_y{7qf zrcwrySYnQWRxWms+J;^+F>BUN@BDdCea@&)d{EGHgxX{$$A+qxxix3aQqOYj49pUp z6Dlq5!U^POA%NdO%02YDo$1)Ikw#AMfDq*z?w$4?PiOufPgw}oZuh33b6GaCg7#Zf z_z6MioFT(|`_DH3I=Ngr{iyhG|Xs1_j){V|oRGcRB&A#)TP zJkxVdQ4>iOZi0nUf^{?*jh<-Xn?MfNp_kM^{6pX!SwTdG)i3A{z1OxJ|BXqJM@d$>zB zJK`<^Ux`9G{p!ZQ3k#XuT!$w-wC}4|Q?0dy#>nipw>R6{TWwxcb;+^p_!yhnYO}X| znVmMf%_qc^@`yw#C0koxxu zfnh%^qxB))!u8Y@x5*9hLp952Rqu&rR&BXie&`=l}oQ;veU2 z*4il>XCr?dnVQPs@b9&O0`qF1TF9Mj<=&10A$Fa5_Xn~XxZ--loP8xj?sLTA5<2Z? zHDW>8pw{r(sF~!8T^5{onl{9q$BkHKL*}(JV|9pUbM@q#coss4%uZZ-kdMKv5R!>4 ztbNLWqc1%|mPzG8kBGQNYjTKmNrx0?%j%CHt3N0*kN38(li4aKHSs~IN5q=2NY8a| zs242C_=Zr%C3%!_+w^-7yx$0!v!7-&|^c`hkZ|p?PgY?!Vio|J6PAF!zk-^=`8HR8L=1_6Xx8`^qX5pM+ZD`Bf-;nZ&!Nf`M*Rkuh@MxKCeE)pbd&O_3NyopBu z0HePMm!Zzd!hl=#;+-xwz{UevHr^Z*KE7Exs5hU($Y0Yi87qvu*>2RM!pMIzlkS?V zc2jkavQS&9PGU)vNiZ+5(vBo8(c_E}n4#`bb)e+nG5%p<_Buj}sSzzCG)`Q{8ZmYV z{ttuI!8)amlpG$PwKcpp5RdeQqDEn$*b9rB1v)ks!*Vm2oaMRhzY5PqdI1toHH!R| zACqQJ(LnNcaPBEv-VV-wv-J)dA^}6-!42tliFE_RZK$n#$b0KlW)Hd+i?z0<@kI-n0cZG-&=B25 zdlwINj95)r*mN7NOYfr_6)S$tqXjKtN6fvo$U~eTF~o7}j2+CaOKx4n0cjaPh}fc- zTL%f|gcA2s1{|WL-3qdyj8QWgVi?{x-{}1rm3Firm>Z^HtJ}{TPf>t-%;T zYdo=I^k~SvGj^yR4!Os|E92pA8O!keUkwO@x4SVxi-ju#G3L6gX`(i;=2oUCn2~y# z0qruDkIhf~7e9$v0Y`kK?a@|MOPKCnsj)GO~FC@N4yJ9k$kn|`9j+m&9f?d(B*a5 z2U!)uK)Sc-)|5Enqcg1*-P^RGiJScnILNEB0Yl?>t#|Wha!9|tw?4&}=9r8oPEgQ- zOZ+-uQaEkuyt#hKIO8%lBUdG6c^t8cY9LfLDz=TW=q3%8kuSso-o*P$z?bI$bp+RC1O%+pjlbE`7tV3vmdJF~1{>=J+eO}wfmWyE|(VphL z*Q`6cF=7(B2rOoW@R2%zb)R}hYlEMxXd^@Q*5Fb>wZoR>c(Re;u@KaY@1d0?+%+n;* z*qWr8d`*(*C4MfSTb3^G{QIm@{oaslaPIPJ=LH(T@L zQi2p!)iimS9z8eN(?eAEdDCNqF8o<*dQh!pHx%_jZhCZ)$C@6N4mn*m{=&@kSZ952 zPmfNfhvepaYkI6B}Gco zv7rk2^{Jb%MD!FSQOWlko1jb6t<+Vdt};TU@{{V4`k1gfvMQPKVGccDC5z zHzm9b8-x36NY;l}_MoIn|30w4Gs;r3j!U`yWksy`k%f1I0hu$(d^#V|L{skfhsr0t zMjx3)?@8KyEYiOHrkqP?my{!Cn#GXtG~{p*_XvXN;CMp_qvah^AQ7}QLXFGC;v$>G zGrddP`}6O$ziVQ-M@m)Wne|ZfyV{VQGmh-kV&~V9lJoBk(&v}E z#`(}lkIp$FS~k^Yvdh^lcx}$}jm8{0kBxGMa1sBgEKy?LSyh_|L-IVP#hBbAOrEC^ieC=?hzg^CjX4PQxW=lpK-TEmd)1cX}4$G zbq{)7pJdnlv3=e4vh{rZ27Q%ts)8BU2pvawN4PpI+8cl9$S1WcOY}%FpzNqML= zYEIP_)qwg0D6)6MZzNl^IAfSI>y6}ZD@5OfJZT7Xt76McKns^V7*TVkwhh!no>gHh z;?QC#1AkuiD}BS>lAq{O>;3GHK?{V&K(#USV(FlSk?J zT&NovT&m-Zh$25)VW{;?4RL|z<4VJ{s_X&r!<;6lgBg4>I5V9p6Rx|kIJpp#LljDn8z+p168 zd+VdvUr^|-RmagHEHd#E=AEWDkbF5YhYchZtS+(}NDeYg9LHJA+_A>XV429p4*^Fo+cuAZ zWqG!}JXZd7!Q;gOJv$ zM;#|B5>rWeMzrS2NwI^$N$H8ks!gJ;HU%ef#?K%mt~Lmw>Kl6TZzCkz-)6HT^Wqgv z>@cxHzX>5gs3Z3p_41Wc4$4&Vzp3iEC5yImsX)+H&EN*%Q#zA0W(gJx5Wr$-3%jZ< z+&K}?Ji(N}o>BNEzo77B8-;Tf3o;w*uvRx9vxn!uvv<_J05xY0b$^HWrPc!7sGx2K zH{fukdV(9;zKMp?cJ)ghZ40?z@Vpg*D8vw% zrjcUxA*n&)1GK~4wID0p0pB4ar8+~c9P%Uq^W-S#V{%g7!S?d(;QZxTCZsr-3u1$< zpnP^TazAOVeJOwlegqmXh^EF7&o59JT(G>Ns*bQ*eD8_Xj`GFXi&h*-1qnz_DDtFH z)iH|IUN;bVeiBE}Vo82qXs{_#yT?9@vtj!OF%cVXk zf}-OW>-`dDJz+a^$n{;nlRXylg#^x`J$tO9ciu00%IN;#hb0qeX=g();dkhR8iGqj z)f6EY23N@W=*mb_&t-E zyjDtAO zOR*=uBT+}hKek1CMeBjzV2Gd84nYjf-Ws&4lwgdZMqQOfhN;>IaE&^I4&op?*Kpu1 zwTi`$Nc>g2r5?AF@s@g!TeE4F`XN`F7pQM@FIaRl`pSUOcnwER)}V;6$qE9g}NYhbc|ujePby;MPk%aF!kT7k%WlRI%JCMZHm^igU5SY1-BCU zk+m14s_Q^6F?aH)mp0Q`FIgz&t)y+lBxtF)U;1KwvPPZC2j&@ z>4ansnlEYfmzskP!W5^d5Vr3Cez~hS8F6LSh|10XqD`Fh;rvy^A@7pm49J$fIjJ)W zh(?kM$~o^d4vI9cG78V~WT%IUF=u*C7SW=?Fnv(4cqv_9NX=2xW&TV>NDk@Qq&2=GhZx;heADV%EPm{%bUU|tkGiFA6Z_#drl+^^ zx0Vz)Z-t<5zT~UsT>fvFNB^?g%+3_Vh5_<vAbz5G8CG+l1P|FsP=fDsYfhS_?&fM! zf=n}X3)IgV_NeJJN4q*C%yR5_(KkUT9tjDL$d6~-uQsf|BXD&;^mz_42LAjtGh^{C z8z=Ri!zV$#@CoeEt~tT`%{zEdznV;)=DLU(u8KA`ltdCM2nFz#`c5vHr5k>ICl2Ho zgE{9Kjhy%FYL-RCBy|IsBIYG5ptnaFT@^;*cJ)UL`uY@Du^2VhxyZao=xkw^dI>Cm zw+{}cpOacBZthb(g~27x^vYVo&@a3}uM0UwDYyWv$P1S1&rX&ObHPgK(Dme@S&BlaTm zN0LJ*_^|z0uXn%3vWfn554EoL7-ZrK80IMu35mloxJk1M3uq&@8%fM`!fpDQ&%2ay zu#vjKW0-saeOaSAAQf<)eJN^f_jkxl`_L9fFf*n%aZju#iDPN5BjQ$s*evqLCi3!V zD&jXMxO6xPm>A_><$Wg)WKTIBp_L1*2>uts)&@t2b_Q+0Q&?X z0oQP6{39bZrrd&CKXBK8;0JwcYG||WmCW!&+j|y5m`-iQ)(=a?lFJ<-r+}@~43u<$ z(|?R4FDkD~j`t(C`11W0MXSm>G;qTE;S;tJMaff5vgwK+F3vcerJ1oP#UR6>h&qJqhPcch=UEh7aV9O2Sy0Iv&85NZ+z>G zyHz4fG_YKe)ynyvx>~%UZrA%tYTyL7CumT_ltZ|Psye|F8L^zBE@z+Q^*M?2SmC$C zBk=%_)~=hu!SyVQr1zDo{Te|QREh*)tQqT>`A*NtUSCm=_?ErDi_`=>GlN80nq4uDEBsc_rIW|obI_REZy_; zr>*NzEDojo^ziwEb5os^T)a=c`V=eld_@?q=t>XMm^rB!yxRg^qxc$Jqage4>}DzVe6QHICLpDXtqjvx#(MPy>iXJ+d#cNlg|oaZj2Yj;|aUTCEszCi!3)Qn_IzoPBVm-&ClHBKB9gP9 zLxnwq?MSDEJuX^-{ZN{ zy1IAW7yX;+9wT)xxwKcm-x&1I?YAt=z?f`IUt-zF8GAw%1otk7oXxoeJX?~G!<)A| zWB%0nra#(W=VM+kOOVJ)PQ zNW2z)7FhUc5t99i^J~p68+UbIbg)7pZrMIemOflYOFzEV?!!?}luH{gX00wLRV`;@ z+ROefRf+Ye=P0Wer`S1$=uZ5&SSYr1LaR)Za_D<}V86ZC%T&uWTVM6O+gsaD?$h@B zFYd4HA3?n{ZJ%T3u-d*^Y~%lew&P*4)D1A9b4!EP6@mj(uslz8cP|0%GI{#+-+J{) z;u{Rsf-Mp{(A>D7prtK#Jz=Sc#TPhbW$ZX&tKzC(z<`Wy9_4YwOSZXpG<&F@Gs#bq z(*)sBN$&zD8z-L^X8g+=0GC;`z|*n{X2$zuQQ(y4V*V_d9L6vf^!S=lm+B#PYQhO; z-cRP%Yh<%>gYNA{>5?2#CHRPlaDXb)t?G}hSv-Wi$dnm4*?cosma1iuxT}cK2c8mH z`=jIq6thES^ckshFshYqo(pZc2(ck*w#gj$5*{~47Zo`oNymaSJ{S{d=y;i{E8ggb`pD?!z0=S#~!Y?MuTO`NKvugB@S$f6@lKX z;XVk`=P}!#AJW5If7VNXPK+jp(2S7CjONBr>$w#t?r-a*#V6)k{K;9pTl^NDW&7S@ z#_Ss|p(-N3+JlrR1|fM!yKkMHp#tc^Ck2Tr7fSj0nUXV^_;3KTCG z?K!Sslye4n%^9P)8DHJ2*Qw0mkw;j24y6_ z2JR$LO96*dQ|AdO_#-q=)zeI&1FY0b4=t2Y^(;6mM+bHySZdZ?Y9y<(91pp2Kgpvt z7T*K3;tR-BXSA5s`bSjI4jXJ z`%x=k`(qQa)@C77bIut>B^tIMp&N=K)laoOPumRqVly~lFXc%KHC|Lf5*Zy4Mpg@H z^p0Hxgix_UUS5Q-;n?NAOvXk?qcmKoonNh&C7WJo_8;lj#yKFzvCuD1R zJx{dQ$axU}N!DF+FBB^Xwguwy#)k>l$uMu3te4QTo{?IJWV+nPmJsDThl-g$I4yWF zn>>^r;6QW6326i+@g(a}0j(1r@q4Yv0@L;z6!p3**JN%M}vnK)UA(&jaXl<*cMywFpGH2;Y_)0=}Zw)b!*9WfqN zd`~KfOjr87_J)68frh^UpABi~do$2i(J54Syq3&q)bN>r{ksz^u(QS}b?qGB2(${B zf=p;=zi@_y4f_V|KJ+pV8Ll9JF!b_LqvmS_iNF1HnsK)G52HP>kYbRobvy~dOuJGu zXqVG&7h+ZE+Rq2{OHO+rpSXVLmVSgie!q#S4NYqfS?Bd+#j;~|Lmb%rS)>l83X++Zu`@&K(gnd}dafYSKE${gf8)Ps$KsLlgF~*ZF zYd=PKJ5QXRO&8+-D>{|_&vu8)v$(ptQmC{~z|=20p6dYW&|MToPWwjlcq;U{DYg&`6{tyvQzQ zVWWwnh~f)^B1)^aRCX0bBykgEb6v5mT3cos?U5tU9{Tc0*mnhA>X@V8G~jnEXN$`as|yn7iakg4dmvY^k|PB90!W; zm+T>fE)uT~;~9EQCJi%j#*I&bAZN~3BBm(It7-+2-C z%_}mCb`>4-aZ&i{I|GBP&E-2?M-bb)+|?Y9KO84gW3YR9tE(3`p=)KX#HM&!`wOtrpF>aO zotk{1%wswZ%b6h<@Wf2Di_EfxS!p-ne={RXuq|PqKQt@K!K}2Lo|%;ad8l5bf$3;+ zFt2>3ERB%52E%0Rd!jj`LxuCz>zd=Dxy9>5bstT|QdYf!9{g#+Oyz)GKV~<3WuooI zU;f$IrCYDts>jFsYzBiXF&<{D93dVva?>BbstHw}U0q~)wJxuIAiG625Oj4qq|3?u z`?d7ow4mx_X@PMzmEdqY1LA?}>C#+#uR-gUYWR8TT2UqH_C8qx;bl*xsaD+<)zZjp zxXh}nQ=N43{K}2N>4_e+VPARL+LuKBdc0%2)wwiJw|J^*#(6EV*NHV&Z$ue9oiunM{+ zxH?14V{sU!GgH+~#m@NaM?YczR;ED?Gs3cnyFrO}VuT(jIWqG-u8=B4m_A*lfvc z;JvzsO`o@Vggod*=c(0RU8LHcFgVI5N=#=3Y*6>xub11eo78!-Yvk+MWJEl3uN0HwP&<>CvNmD(aDn8s*ue-Z>ExI3Wf63m+c@XOwinzXJ%NyV>eR*}uV; zr|Rdaq-MBQ4ilb#A$7MWocGR=5j!r~J(Zo>w@j)_FsLJwgd&Up`IvYr8Ub&g01q@a zU+Gj|r+VpF1}%*hYjGgEdTa`=o}_4Oh&rDF``C5SG39ybl zt!;je1WN46{Ph|{eH#e5$>vfA#EF22Jx$kwIaa;*n7RqBg|xZiRAe8vN8d-re2u<3 zJsS77B#>Y)4c9yFwPaRc+yPTHSN#QcZp#_MR%I$oRpVs`2!XML3cb;hnDznk*fXVA zR)F>^9dYhxqW9TuwAS=(56_(Ei!9zJ2b{JE-#3n&CnViP#3DQP4ULQVc3V4Gw2(x~ zKNo?Wh6;`P>R`HO3;K8?WAXFYLB}G&ME^P|(SyX=aHG~{r?y{KKVS#4sEGyzjzD`IEje}MTYM8N>arhO2f=n9)Yv@^itqff) zsnA{z`vBed2809|{XcZuoOF!VpX~r2h0vamkEr{(Mx4Q_LOz$c-i;1qX@xh%Ns}34v~3gNP{Zt z0~fX!CtU7`H%UAWqsBv2wwqO;P0*Ffo;~AWl`&#D3jk^_XYWK03G{&jfX+K8P|Z-; z&IvaSPllP^N5pN24&_Gq^RoH;&)w5H>~#P8_+JeC7X#ll1}x(djF6h$hMF8lCd;^6 z=dn3Y$-7zSWwgutq0Teg`pqGaBU6+jNq)UOBNpQIu2{je|$R(#4Oe{{1%PG5TyA()CTzs6G#= zske+?^T*qT0aZ*WJG88O`l;bXia-};}VucW~XFM5v$-wb3Mk5^(Oe@r9i-}=A z!#4FBxJrK`c4OMFC+O!#qNtfgAWFV1}nTnCTULU&_UC2l6%HTk!rx=n;)i_^neg8kC7pfbsB7 zBtf5IE9Am85;@O)7D?M5<~t&vo5SR9X(Kx^Uz2)4%y||#>?TICQ?sJwb}iIU32Ziu zXoWJcmBg+TZz9n)gpDh8-N6oZ|LQGWx9C}8s9KC{yKYf##E#@+r(JwMTp(-3h4C&Q zNz0^Fc8hxHt+g|ZjNmuE;^r&IG09)KSI)$_wpuA7pu( zz5Gt*o~>`mRSO1E1P?+Ok@^gom?1qCxGAjWWL?d-#%gSPj)!{QxFFg7UJifEwc8)P zONLYP!cTmnQPFDmTv2g716LSTi@RBOIE-%f1ZlM{`y#r|WXFCvKzHU^Dv{2N)m~-B z74~DG6DO)_G-=TBm5UkOQr@Ufw7TZo>uc&@Iy^Sv&uL#($jnQG)iXApFREaAfNAcN zqJjdmqKGM|E=3Q=bv!7hmM-VntoS9rV*g{_;R%!i3#8~x;rp;8yQejw#gK}>*R5QI<=A;^m0!Aagbh$eENKrViNW1ChC500MmpTm%aI-swtt3YD5*%M9S1JT`qIqw}O|;X+^Di07O|> z3J7m()ZLf}cidmh@PKv|?16 zq>HE=s-$lEuG>_rCbLv~bp!*aWvVB=mWITRZ;w4S23X0W(xYni-Vt_>1cOlYuHiQF zP)#jAPAak^;jurngW)Y0R%|Uw1jGC8*h(s?eywzeHDtS{q-OQ3bW3x~(nbP-NjR$} z^&y&cR@j~AX1T=qGcZp(f@W{wd3;_VZ~Ul$d;I9&>{LM}TA_IX3hAxdEWjv0anBqM zDHkMobHtdo-Db#AWBaAzF&Id!M-6iZj>4BW&@R4nCd;zdzwEmJ-$6>Uj#$2JtTB$& zd$z34|LHI|K1y;N0N-q^-3xO$h?Q7{*Gw12_&R<|MdlNE98WVVCSZl~hvqiAN+O=L z(A;fuBo~LfdnoC(Uh;NzB-teBxatt1t4(C150K@W6R^JLh!C`HTmzb|t3FNs_Zu=Qv;Wm7LAwSX)B7 zN(0{y?UHKvIZ}R1`ROV@1}+T200&N^Ll}W1z`-(nGCIEj>-D}p7*BXM{$Yn6rirhSGme~4>#V?NuF2pOhH?2hvWP=XYoQ>~@X4VJ zY>3n48ep^1O>sPv!{=p16-l4@L;)Y-VqlEqLoaIOP`uQ<6%#p(crCx7)+y$#zakMB z;H!uS7KWmO1;4qe_|+=wRko(jJyP2FknX(QOSdUGKO=`8KTSH(|FBOwEaWT}B44vA zAEKueY!t^hkafS7kQ<`;(&&is&YPXZ3A17vJ;W|p?-RYGD>@0tp{W1hL;os8ysKDA z0N`G;jfQm9O>-K%Typm4GEUA-lJg!pq1I{Utv8V{E50v}(KF17vveXYFhyu9Pks*9 z1U8@iq6jV^5%&+}``_{GO(5hd$&t{jNfNwUa&9K)DdcHvFOa>EJSS@K^58bJ=CE&1 zsC9pE*3)_ojQE9q;3W!?zR)U$(REl^mehl5VKBnbNTi+ZxBl9QI+n$@jvc#1RM zn{Yi3pP3ciMfKu%b-A@Y^iDeN27yUMkx2$U@X$Jq{@qAaTzOjrHxU&k6`UlmY=N}{ z7dn;-V*M%ICyDLLUUlI75jgfWn=CTYIJQ5V)#tfT_+_bR*}(^~A11#qg1lq1LeX;q zrGn|gP&7R-L{h!w1h<*QZ$Qe8fiSK-3x8J^R~#l^4U$(!CLyNFW43n{J|jX7NARdS znk@}1+ka}{1aD;W(<@r(MA`mX!OOj6AN#yz@vQ4E^6sur3!V!GuK1g#U#-#=Nj?)8 z41gvcP0z`R>|p*4*s)$)wF^MAdQc0epg}C#zC9SM{h@I#;%kQHiVJ6Hb7<}!+&k0` z_9C`O(j>X+D*4V?Zq%=PC3ttH@a`#Dv4Qd#?Rk#*1!$RA9HT*8$Ny8;sG~CzM1UIs zC9oaAZ=3+l|0%2gT5IY5-wP+#Mf+|6@%qfue!Fv+o1dy2#FTdHv7kIyr!$%XMLo9+>6(ojB6S?CXejX{jxuw%KFbyWvIhoXuFhfq6x!uwZ9I&(p}oD$TetGUGJ5hT`oV;l6<*vVHnHFHGW7QT(BAIX zO%6=JvNtNUH$8A{Xm6)L|IpsffgYi~++ki$smOUo?5rAAHCODk8j&z!r`8A$kB!%I zTx@iWFqGH{p}jo9l*)>rjdC|*+5Q}#mX|!LgANEN_1JAZEzyQ2?iOG z^E9~y{mhDcz*$)VVY>dX9GnD4`K%YkCY9@t+;s;TvW1?Zo^(s+Wu`#KxPOWbel`p= z8s%%M7)li-);mHY^Y}ks5;M%zS*!X00&hjwDD_R{|5=f#!^dtw^JSK<;dJu4km_Vs zoIyjmi`lGrgyK4JyPXJJi}uZ|?87Kq#>=PK^dm&`AYaso`%G!&y8+x7N>`{kN3k4f zKeAQQ=y~?;0#ly4A7uuM02@V~WN-B=mfaF7myM!a<2Db2-u!5(Ad72SqjFWMb{u;E zO5;A7v(ln+os`bH-Oiet7CnY6%b1wbB>ApJPST6FlQc=GMk= z=yUp7X5&%b7xW8oO^dOdWN80U=B*-$`sY;I1e{%0%j%v{tF^VbQdJn zlNbmX@IvsiR2AsmXqGjDsZ2r8?H8nt(j%!0k*iK)YcC@>PgWFgrP2=kjL5Ggg_jMU z(f->Rs)zHf5TpL~g*ygrUWfj4A{`ORtL#al2v`N??W@3r_y{=S>#X%6y9nMy z8=dq|S;*!IQ3EHEgg51C`d&mbTQRB4osP?VI zT*3LjMzOuqE}NR|c1&L?5c1SVcs3zCFSXz}QdjImYWaM!UCTLkEvsoCi?=@`&__G; z5f8q-Lm!_s@QFSI%Kd4zEG(;dE^GA!2Is#Ko|Uz3itym0qBEJC&W2tFXa)KdmS{fz z1;wqGwy4m~?pn8ea;UX?@WT8zKy2_iyA}IrY07-ON9F6LCy5|7OuiXv7jER;A)CzD zrQ3cS&JJM7hC`0ghY0m;waXYiuJ>?^5k1iU3YrXon`XmxcEVFO9TM(c2f)4Ppm2){ zE*m^GFe!zoc5ie5OS2M0m7slxvd$ZS0MQDdvur>N2K?0c^S=S8$AN%Wi5?Tx_>TLCWaRZZe!D)V; zTGr3;H=TZutOkBtO&Pnuta+!~f=ruIFFX)*NQ17A4V0?K9r%9E0absbm6T3PJZfO3 zO_AN+5+xiSoyRWa^Wo9yan{#;`J4w6T8qY&Q0>pv9w2i$f z6&OH`?Vy(5N&yZchtos{Y0DJc4}T%L#|6arUWBi&zK}y=7k>wG&bK7q{uj*uA`B3_ zYnqrA^J_~Zr*9)d*S6xwG{s+q&pVV{z>b1HLXx@a+%CdqWHU0geRxmNJ2>YejUPY0D;T3@_b&(h_(HpZE()8-v5x zqSzWtUE3lMXBPF z_a?*&_>s13G_#yVCu(PZbyb#TsG@k(HjHi2GeyzGeI6|Fe5%{Q=eA;Gt6IiB(b;8) zd3g4>Hv2SQb!-b^uk0%%T5gI>YJ1!`pEe`^@@v*KWiL3=aqlS56$e!K@r9S$b*zJGlip!83W{&oPW>wK}V- z9?>=v%70niHCPn=q~$yYhN#9I zm~e1Ki4|O4%5J`gS@T|(1zFx_SZ_EkC9(Rg{ocBdO>gM^G;OfzRuaw+FUX2ML}|0&zTkP=z*tsUmQ;JLW`?WdCFo{Hem!sT!F>wjAJChXjL=VwYv5<*;$uZ-1ie) zZq3gM2Uh@b*97T{$E?t&L&aqEh(HuOc4@UHgjLYM!sj%B)jEbMXslM$zhXfLv|}ZE zUZ3Wf-V|f)GbSJUizbcRpW0t=+mLU$EQaG~AT6VfG)|g{BW0kwU@FtB`KSw-Pr1ru zX(qmNw@-NFm07W!eL{`)g#6U3+$5U@%jl)M9zBhF zKfi&&5@!FX%1`iO3C*o_6%CpzQn4VcN!^ShFnWXDhG5TQ-u{>jEbxF4kQ{yOEMTFF zh|&6jpeQ4r{R~i<7zvwM!eCZv&G}z!F#8((x&7WBJJI}vooKd?L$8Dkv9j+Rhl5Pj zr{1c!$_mfo;9k7$FW4)x7n9AQ;lnCk4&p#%tb=V8g|CCuGNYoUiA-u7-{m^Sr;f5` zQMTfZz?jISE&e%;3`e8-j7>H=;P^m6@HRa{d3}VWMblm@1hki312+)YBH4s?ok)ph zwOT%MyrxZYLV(26JIQ%~U_)R6w4lZcxaqZ?irstLmtfs)9F#JT;Pe#noC$|(D{-NM97L9Wh%C9K zmY7f9`PLX_%GlAO!)Z}j!K~oPWed}01y8U~h8h{YE||Z`)EHkBJ=thoUx+4B3?39i*ofC zS=rkPSZp|4NENsS{o1VA+5MV(sE3ABdo3b(%LzdDZzzS`!>srdgp9?*tdQI5b)wQv z1V)M>#5O)HCkx{fq~?yU#;|lN&qJ`Ed8C58Xdw5=Z&s=E{p+@9)E<*=ztfPQ0SJ`)l{+fYjxKC|LO zx~s`QFL1t?e9w^|kNk|2p9|&ZX!+@lEf`m^(;Zi_ZqZsBQGK5VQA3i}K$kpXq;jmK zQB=AbjoU~h49L*iJgq4=Zuy>O5^-ZOiHLXeiq@b});h-inT#0cY}8ltH5hM#L=&bu zZDnmz#fQlrozc|FkS5hrGc_>`ibYC^MJm-TK-yx=V}j8U)+9$v`&PUJ+7G)UtKFE? z%cF3{GAh!rmA!0q7KggGX)~#2={J#qx8z|yYmGOgyk^BUNHwIGEMs*Fb!){iQe}mR zGrdTdtG&2nm=&3%iIUF&Y!XDtt$Vvud3_^iNC*^^?#&=ZjWGz|p?KQ0`Qn2G?$1W_ z(x(QS)YC{b60<7dzVnK9!?KTzVrKVk^H!gdeEG302a65fGB%wIE!n1ck@8r`YN_f8 za$|$N)fXo}s!9Fm=cyl|nXU^s-`ynN<&`bombT>hQgqn_dv>pRmNA$1?#BpVVez+E zS-Lx#r0fTIYu4=QApu0EIUa?P?Azs=aJSfx>(hld#EzB=1hkNo@U)Fxu<{h|I--{d zWWOwmmf@0S#cN}ElnxFpveLZ~kA%~@wg;Z8X+d{=y0&U`wt+H!oAdb~;w5^(F;r*N z@~E9)#2)$GkyLvE`!}E3_6%)T!V-_LHR0bog0`#W*@6drD!A#(AIf!wW-}b=`NTTg zD#q=Xy73yv=RAaF6cMBf=)N4#Bk3W@5iL@F5$*Y#>r#cE?@K5;X6x5#WoMx@tpH*r zX;4343)UtGF6gJ_YR5k`xzfDz^*w8)zd5o;;+lf;545J)GVXUXUiKv-Wx}=Kfrw+- zS)*9L_Ie6V3YzRB@NGU5<`w-bC92X!bMTZ!8E-yB3+D>4bwSVdC zvi0$TSM_uDKt)xKl8kE325xLbDDDk*`%HglUhqb2Z56be{SXYXqLzpvFYV^2ph#5W zYtc;;-))0+C-XO{Sqz*YSU^z8IZ9Z{N&%P&5 z%u#!b3XTgNQxX}y^C=N>ul|_r%==8o_eJrA7Hld!Df$F6jzRd|_>612loif0D}PCb zx%wn;s39Ku=zBJ5{lE+DKQ1@~h=D)y)*m@5E%ea@gpQHCBD`T_@)w~!8D4WrbF4QT zqNV2mg(y6s{Tb#mKWXo{W|a9PP-PZb?}-w#Bz*O2v}y+nNPT!F9z^e^n-!v7D=YNS z=n*v9tdNu9EF_EmEMmyV?2;K`ADx(KijMjS71~rR4MJB{=VG=+BdXC%ao{b zeXm(QGwj>pT`dQm(Vb&ylxr(2V<|A{%uw4fW_zity|np2eB91Lm5PreDCOXzMdPEZ z?rIVr7t*Lq8U^;Ix6mk4WAUfE_u>8eahiGik7x=Z7e0>8AtCPt7E8e$lgrM%x1}X*)Lem`>3{d+7`%vBMlC%z$B-p%<=BcMpbURKDT}r~k zio)|a!clDfOUIQd?W-1m4!{gmOIa7&S1mNyUuxGoO1tvkV|}(Ow^6>?CE!IEuU8vB z-iHUplOtq<0GSXRqn~Ij*xOE*cm?(9VO`*E3e-h=Ie{!nhX#7-r6U2QfZTSK^Xvu?7vN9fD0yi{NtV}UKN>J;aJ*q@A2kMwVA;BiuhZ_%Kj z)&!;D&f`TFWz&r$4pVkfJGe4%T8Mc4dNYR$2=Md2Tbm5T#TPAa`5e4_B%<&d+z zh$Xb~p8sm&zkCh(Pv4~a$eflTW87iyZFRx;AIun4iz5&_bPv8TLr(pBmdmM_U{z_H zBHQ0EI9H!_)A0>M9}M$b#aTEMAws(424Mc8GS%P5-JSRx9Cf%v@k-7^J%kXzWzYg2$`>rr7Ktci_Ma^8dia{AxrH5^akQDMR5tvc&LL+8pj@1 zjIG0HdHZv6{Z@+9ofeyGi$niJ)LY4xT12BWOm6E0hf*V2-(6Z#VwTFg-^HYM<7NQL znGffz+yV_>#HVlbtXwi)zjc1DKXMJ>Mc>+ybko_ANSdH=M+Ue zt!zO|+7dZEOAVH0BOH$x;n;7T*-vP}kS=%fho>NJPU+_#{+2&HE7xz44ApW!9HiDh zkZ*o%?1O)g(uGPQr_sip5(4#?uO|pqj{yT`oH^7PgIU4xD6@RQ?};*tb$FQGFNcj2 zqyXbiUyYuR$>@Mk@j=MdM&ex66RJs7YRQB-c)&}i$%t>;j}=WBD$2lYTOZj2F-(+@ z;q2ACTFW?l|Llnkp}@q*r02$)*X4PMl;{oBK4-38Q_|WFqb_>D&Ujtb;T_@Gn!{sJPdR9 zYW3CqPAYJ;JO_@{zkT#?j{fZm82qGuBvPlj`dsGeu2KFBCa&SThe5%JQe+i1!WDWq zs&lozc6xOwkrFCCK%T1iDccXuxM#VH;K8&Xr?ccDWY9a2FPl{F9x~;pHx*ekRrFDS z(Dm9<>z{PJp#r!^kVUo4>TcNN%JICF6|<4oY_GSe0u+n(3g0Bz>IK;s+HShFs^$HC zybRX*BctDcw6jacxe)_IDc3$1Tlh|Ta^mg}U*l}ZDZ#>mnGNQ$a_|$GhNzXjZZP7< zSc28bEb8J9=W&8GS7eXp?KQhrE%>Jmoe!6k05<4ed5ScicA(Up+o0|f8`230c_t_T zqx;(dJf$7LqaA>RstIIxmmcM}M)%{RqJm?CJxao3Y{h0&9NPRDpFs$pAEPB(!48bd zizrlL-js?!wHLLo9*l%z^DW)mMk4`5 zFy;oQ(y?mw+xMgz;9E0Sm4y2i;cXy#@%gs!z+TNhPK1R7lfE|R&xD^(mZK4;(-sKn zK0UjM{C!DQ?0JZ;5POw4jfbLH0mzS=MK1S7&L{e~kYB`j@h(Uyw5w2RhZ5V!?={d{ zNpzI!`B++{$#AX+!!*r{M?{zCg*-vf)0TJx)j&Qi@QA<OjS2+vHWrX^Fw$<)MTYIHI+T&G$Mvr-)V%+9z6E0*kvYQ~qTyktor50;JpeO{nM8m-SfOp??D`6-Z}eEB&+&)8@AjF_bH zkm{kg{F`-@&xmpRouDtHQEf#-9z9#kU*_twWm@-$4i=qTc=Y3g^spGrkfQJv+JJLB z<@CVZCXI=9mKLO=?xwch^3zX#y2_710R$RtR+JY0=qg&f4 z`XG382B22%>k~_!al%jA2H;0pRx;*L3;k&>E0`EOPW^qC$V|etYt`j%OWK%30g;~u z*eck39%F~8+y2p3Z~_HcO<2K%V;uVcb+lhiv|Xu5oyh6|b=5*$(KiY16^a%gIJ$vT z=#N<;Gf^i-B*rnEN{oNN5?R(d%B);KuILbFvRRDgexB@eW3ta;{rgc{n#hz^BJVY^DwxbV!^Hyqd=jyeu`m7&XGh1NO&@5db*>P z_-!Sqtl^F?p|Y1X0*vMXpd1ka_3)aE*50S|+G%CNo0|P{AThp%2)5#USfh|Z+^Z=h?2iMjsu`I+HnM6` z+W5hNLQJ%ka^E^D!l&%wXy+dNJ*1$ox!$TS(OT0342S;E8ocM-a{)}pLak?;%fyS# ztcdW7wDU(1H@+{T#i{bsBh=c%toRM@9J~CaH1N_aJr5hX073uVtZRofinIggU9e^- zF}f3>L`29okCL$QQ6E9=M&VS^*+Tm+ZFu-^@gI;Y)4S(!xv`_vjRRDtwOi zqrLl%IOjSAucM%>`8kvocdfqKUF)#2h3OXryP@aGfC|o_VsSf|%)7zCi+Fbq2b%47 zqf#0rzH~3!mC0B}FW2;H{NBzIQiv`htE}MspxioYlh`M{AhA6{`S(aiL=o~=q-lwb z;z7{&0`poZ0*N{$NpE4c&9q(?AD%HI@CzB$ns`|1rj3O4cL6YS4I$sleiKcYksaU9k`c|Be*+X zN1Vi$MK6igON7`hvev2#wlP-2HEB6=Wd4Wy;>Cpn1O5GlM+LeFzIhw$UMv?Vur!YN z8zjaX_R<2nNgW{>T6}#;-M}Ig{X0!5vKH@Q2*%p$Zc})s!oBvU35lC(K0ORFxg0Ji zI<0C8UtJRc&Ol%tsytir5ZB190c#Rc7FT4e=A z=CU71X4vRYIZi5uK5`sAyYeiK0Jo0kJ?9|>OlWR3!7EldM>EX|Io`)u$lmJ6_`Z0J zy&xdQMcxIULNL5a#>@E_eWbWuhZ!hqf6I(GgL@;cghk7 zkF167)y6o?Zd|AHw>kOZ@yRGow-+1TfS&-p<+Wp40wXDXmM(2?>FvF|KHeY&#q*$9 z&7pMkI^k`LSEVf})sFCT_YxhHLej~V$EhilisdCJE7ydw?nFuw%0i)*9cL2@WpS?o z6fHzmtv0@;38`Akk8*B+i^FjEPP$hm9c3LoCRZJ{`S)tS(XY*7{^Ji4bY=AI;gE_4 zbDVZqGsscTV>Rc}rS}osI*O;sx;xk#rhBnA_#-P;hyYOjfd}~z7w?kD$a%{otjkH> zs@+9$F`W2(8_Tnuvk5OSx@mnDT`0*kQqFV}um^}ZEa;Ea^! zK?lpV&BmiHR-!DfhbpRNn>|dd_4)({>W)>|tHn)wj0Cijum@P!rWTQ!q2{ny*q_zv zT=lWug7|7_qgIuOhcB(%+g;YwiDu;o)a^%Ei1_&)c_MyB2ct?QTPr3`(uw|NMUdHn z%w|>`rE?Gz21-tAmT0(3J?hg>X<_89JTjvXQ>55>OPYkFAPP(2?8LvJ2EBhFct0ma z)d$WBg+Az zPDY<&Ll7Ofz-;+U2&S!lbh>k*(}SdGabtH^gjk78<&Q*a1+rQX_|hsj|a8{0zIGc zzeCkBJ7Q;m9N8UfZ1>l7M??}(m&)Eaa+iphF}e1QHswNnr|azLIZ_$*tP}c8L0D12 zb7AaF zJQ|)Socj(TH~ZA5iimYjPk13~HKs#z#M49=PX}X>7>X|T&ipP8Q6#zH|Gk8kFNAd_ z;;78FZ^za54BHga2!$Mn0E!pj&0%(rLK)(*I^M-H2t_=VNtoI5kv#(E2u+;BtP#Q@ zuu6ll9Ozo>*=yCM?+6g|w$A3@Ay#2~IyK8UpQ$&Y4saXv#ef#&kmD|WCXcZNQd4{1 z=Gjo5CCY8QUAhm_uKEyOMhq?*tfj_8Q$(W9zA@9<5rF{1I&cAq&&;YxY&Mk3-MYM^r^>e;dS zLs#7WBR)fHn_=L#f_KB5SJgV*HSO7*FE<227zQngaa|z#oUJ8u))mJaO2k>k(=YBm zk?+^R67_|)8SBzr-}Dy6O`F80DmeZrQ3VtYUsE)$ZgCbzf>0s^a=B}KLxio8wWVY@ zah=wjTGc7dyVO-2uPqMkN((mo=hXQ#1RDq5JiBRA@wmnXSvY7dO&23vTM;N`nD}c6 zQu;aGS~(6vd{)9FB{CIPk)FxAK&x=% znuI6ymblxcp&l}%`KA)d{wD8Xqiz{Od5$a*!kgkz5?9e6rSZ-YbKtl0yJ4=6v=D9?H1Iqf$22 zRgRxcUoywf3KE~!n`Zluv4k3F4@<6gghwxj+yyK9PokbDI7Iuu!?zTT+fZblxj{~P zFz{P^LRNJkHb;|)CaF(~g`^VKYHI+AJ%Jp@anVo?*1%%s=zjPuyB}kdr% zi%;0Nh$8rVr%>Q`G6T;)sZIbhFnj_g`EGai{IzWH}R8Ejg-kEaz43gU<^ zsQ8x)iVp|tiE(H~y?8s6T~CTc4y989p};1A2LM{760Tzyu0XxHEXLv&K$B&I%5 z5&0oRSVrJPiUubGo4><#sI^qZK@DC?S$Kuy?Jo(8u3B}@>uFxr6 z0%QGh$JMK}IiQ)Y1*Z!WKfXpTWP)Ed*ukVURI#w?)x`H0n*A|lP zs=;?K7v>9{SjO&s+@)UiHbkm-!gHkCPIoOMf^b_C5mq zg4sVwCQ&5viXzvf>&`l)c$kH!=Xk4LWuh-2lgf*h zJ}djS;8E~{l1Qbbd3i1`)dh%;MOFHBEX!B5PTeU~VNbToxNLXLCkziIy=D=#edFNV zrN&7-67klol+AcaWWo>_n%?^^nGCg}{N{qiT)mo*7`Ae}8i`^vc6@^LJ4?Mcyk?U= z=O_x$3XRu9DeKRZGTB*)3e?0mq$SR>wC*{15V*MDo#E#)TnjEEUV`<1(q4jNbqj1i z!9-2>eL+n*?Q6!S}$uTQ^O-4lsDm1SOqSDwK&Jd zWdhlhMRf25OrS*xH@^Q*MdcA033}yBou;M^ezud|qUUnBPRxzQ<9h{P9QfMZ=HRlN zJnNHC>tu7;4v#%%gd>b7PC_501;)zHu+T^8fj*)A zs8Dmnkrsjd8nmy``Od=_Xd*htdDtyhxpR3a8|w*<5#0#8FCJy`94<|Z7#H6ttGo7^ zsn(kyYqPM(YPBC7d9*);S02j}*u;FrQW{k1Xwis@?sN7F!b5B2g=`>xk6TrA7c5tr z)Dw$C^zZUuJLo*tsw>-fvs9KTT7c+tPSN|sT(OdeP;`tP=Nos(F7_e#VPXjF6KYL2 zE01xC?|Po%A?Kk59cA=d9uGg7Ug5lZoXuMF0_UNVbVdSfhxX&T_nAif7MNHl zIwdewDmh(#Cd&`CXAt>YeDVGyY%XH_9w8IF$x-;|7H#4b=OU0U%4Bm{STn=TsvFZZ z8s%Xns>>9FeS(l;5fOF5b4&0O&XK_+qIH{x3ecJJam{L+0Y{K_< zL_2`XMe5-y@vW?iiwIAwK7QGr&KzSBRy0C9fA#I}V$2!Vu#Yo>lkot6diwHXR=n&G z)RmfywhKMTfX;+bB%09g&`lVS(u6%NG~ud4HQ}Lphh#oa`s+2RCu$Da$)_3GL?`c- z8oC~;hEo$Y{34}>bEv^vy;uk|D*msyJlc+k6J?xx$WIqN&h-flT&TZhVM2PAZ6r#9 zj}acAZ@vF{1RdAXycl8c$7mAfR!lPNp;lAbCbSrvcS9x~2y&bExi}Wpz=?2ybz};= zJ;vJTJ!W&<{p!OoMV@=HTnWM<-Koz&JaXNG_m~|Vg>76YJ3=nzEN#+DfvUnJC#7v8 zORe&;nuI<&J1|<<0ahFdORzr;HF}$ZH8vaC-3TDA*XR%ASYMv+xEblpfK%mwl+hTMh${!M9`9U-2K10 zw{KPUbJm|533=6K_S^UxB$ixuCj65pYkO5zS?df=!-xx2g6$tIukYY-$+tGrD37UPr8Z0Zio;by949z>QQ=vHa1%$Pw3%$N^< zr!^=PUQ6Lvr**z20oSCC*$z)^fPUic^^}pxfG(g`Plk=^)TfyH7eltaboIt5($Iqv z>G`OVQi=3vCSj6Dx2n@&3o*B2=9{j~e6m43d5h34$_txzr@SaYY}!SY;RJN~R>v$A zSevdaaa34h%Q-RTl*E_=6UeOv{P#18YA<~3OY~&|7vHbaPcvOr>4~5`<1ygW;RdYT zvPbbMd1P*r=!HrwV*r_4I_!bnX#e8;m%SK_gW07SoHyD+xcx6ap+J>ugm?Vm<}EL> zrtu!RzX>jiVu}K9NC9M;Q0r)O*?xw}m;bV)D^8|}IG%~ifEdau|4c%zp(rbuT4EN} z+MnN-{JeC@$iR^h4^eJv9>$|LF3wx01tx}COU%mK=a(_Z_l(NYcFkmvOMNW~zQWxsNsGQcu{miV;hMnOX z%?jD<@`+g?M;zqaCGvAks5LwIoYVhi-LUa_HZ^8@%cceH*%U$w-e1^UAGP8 z>s`1PSzCzek?lQtty#3i8`{}9(2t`d>4EP2cH$%z=!$tLkr^8s+Te+e-n~tC;fUId zHPK%(5akP(AjT=PiD z!dc^*P3lvf$|a>pL3~;>lK*m4q!JyhExK8!vMBNbsj}9>U~ihtoRD3)aW*Z}3ujsD zIQxa`D*d8RUi^$Nc5l~1bwq8;wv0x7*_z-QteJ>z0N*QZ>zP|{&n@mpOFFCVP^z0^J}%GRi4rVN3|HY ze8^IRu#Az%GOp%9l&tKT+3h08Snf;7(x70L>I>MusIn^G2u_qua3@Zenu#qomVmj- zZ4-cHoGzcuc?qSMK2REWpT;ZfA*?`7XhRl67PT`4)^RByj+Szf>~4JT7!$4+nUh6~ zwF^C7--Pi1Pp(O#c}1#=yFa+!HX&rJ%WzfM@kq9ED(N`ypL4Y)13%NT>w{*|(ysVM z#cPWSvI2Wz=}Ws-WffbE9JqLWX;-~aT{PGu#s@$8dhT!dZV1HDt6N4q29DZ0a~B0= z1x|}T$b1s4=P5V4oz%PSnzVYuSj)F!?wcs9xfDc8o3UCD<)}fP`y(dwv3lgxL=ovV zw9Q(Ybc)<3MG)IXnR28Qv5c#1u!&RAGj$8azu`O5rE6T|QSoQHG%h4YYoNHSz#Hfu zPR9I-`9!ip!K9;mg^hYC>l`z_^~a8EMI%#B8n0l}tfOvyx*#>`)>j-i)&p+q$638+ zQI9w{oTEd~#!e8M#Ds`fju;K6Z6SvK{a=B-0=U0%Kp4VCgE&rfQ=)y8y;HHHRl+%@d3gyVTL`1*k>P@!d zW!$l6E)(9r66*_@quD;7F|6c!eLTDPfP7x9 zmIBk>xh_{1KV}mcU+>WRVWijjA_o$~v5sYbkhD>}ShLyU#)jFM-R;aKCF+w{FFUhE z>5|RrPugqAhS9xI+?|o@8mwl>}TySm#djt7wKEB{liuq z)a1jJ=CaOmpLrR7zN5WT!nU$qMfFTe^(9QuI@j(JkuuGil%KkV3P{1%OEwHr(O#zRbXLSNi#1N6{bQ&tPJqEhlgb6ZgHmbQfE#u;}^GoiV9 zSo>wD59c&1?v}43 zrDIev77g8eo^c7ol^#0VV4 zBdwtNCDV0{3xssJgY7EadSu%~>xU*r|>_Tu<0wV7BF!8O^BeJ24>zk;`Q zd~Mqf(fZCu>C1hG9qfkS_%!r`_6B@RiIx4#yBHX%8VPM%VtsOmV zAbTlgO2XMc;g6bJ&8~YYnCA{vZ&~5Q;B>J*m%gTQ*b4ite%e%LTu#xdEE};GkcRP_ z6|V^C#T)#Q0rx|FOfZiwRaHkQw0O&oc)gA`yCeFTO`@;Q74P%)-c>yrW^ZU?yh=h? zm}7G|O+d@ywZ4qC!I=3(7xM|%xQ1YFnfrWF@7vLv4~j!|y;%0pDKQ3Xi*QMaWcJaQk%{~y^ zk5TmmdouXN)((1l@7rtut$6Hk+Y|6M9;q}_eYh?$-r~PH77Oepyb=rS3E}{HT*5FE zB3HGrd6j@-4YVVZeotrQ|UV__F3t;=*zDW9E^&Pw?<(4)nh|XVk;OG! z`yCdO_U|-oGXbMaqAUGc8eqHS1T*rTI84mqA~ypND$TmGpKz zde|D_n#2C4lFvH2@@&#;r}&QLT3$9Jt(CRc55*@aC-Ko#`N%pmi_MP%<`i-=)=Kyu z+=KG~n0v6jhULv!%dxcUdWvUKB>V91!*vL3BOWEp^07QRNCC&mHcW*@{%Hqt>l^+s z-d3%0SBGr5US!5;&10v;<-2sbR%{uKejz6(x0fsp)KtTD0bL> z96%`lK%}W+Yr9r2>}BaK#l!E&d|U?Z8*IO7clyG6@!I_LY7E=cJN)4Rd4Fe2t%||o z63q}FCy${ah5T`u=hbo(mobnu*p~M2f1y7-;mtRN945RdfAF^_%lNaC&L#aT(m)i) z>aej&UhtG%L0Q zQ3C$^mBOVxFb8p^~FY*pIHL zVAjPmJKoun=remGo2Z14L`NlB$^?->6%a_jHyAViHodM#a;N?0E%^flyu;sAl5vRS zHnN3aAQJaIk`BAW@&~~%Y+RvV(l>`#!p3595E^dhkI>=W{9R{U$*)WOM$6DbAq#mH z3h|*G3rITb4$2>E175LWhwMqth2+HD(<4G8?lbICXSS8Xk=DrL5f?Ia1Le=lr1>)3 zByjZa{FU`fYlO190=;HAmQi)_uf>5d&^2xhB(FLxmZ_$bH43D*cS@xKz0`CsV@cSs zoi0VXH?UZ~KQp;l+WT8;z$?6s$w|@Ql89qJ?S8Kmj=MKfHlF=ga?$JUsK#CHfM|nl zbzI(7ht*bx|5kimaYjAhua$O(a3xkz`>!x$o^k9QJ*P9*`(V!Da8cVaZ(P!gUzhrw#yBaa*+<@21z+Q9i&{gU9OLmo7 z;ZjbPQ_2~3xgJt(LTb5=b6oFxkSP4tF4=&O+mMKHJK^mr#OpD|)_pBYOS`)65Mi~u zKlC|1Rx79@Hn-Gzyrt|_@!BLhns=28rFz^Qyh!L!l&`_7;_mY<y z)FSRz5CBw9RErQw9|%Z)9d}P?`|e~v=q|psLRae#)pzob+h2{Fdg?(*AQ z?=0`daslqf;#+UCKS7>?>Nm#S+o&F@kF8G(&Nuvf0L~JArXq>8;s^3%nB%yim$(6L zXR)P9tX;)cMSQtnt$5rzvmyq*L^i5?mqh8fI&4dN`)zvWrsM?99|Fq`Jr~gL88*&O7kZZalq2p=v%vWzHe#UTWKGZH$K6*azY7es zX;arMvc8SZ@w&j;SPy9iIMlCg%podWC5qsHkUCdXYV=(!4CovFI~Z=xNlbhQmM91% z91a-Qn3(%R-n+$_`~U1X_eHALbN`C=Zj)SXf;_eI2Ye%1gt8FvERUdS5Df9`h zylvl&b>_aV_ABN-sF{(Ztc&0PYawa-L*Uz3ew9WPa|T|B_GQwsns120cAwd66DD@e z^iZ+KN9M!jIM=uP5N2L8b1D_N&q zAN8ia*h$B(%1Kv&IV8#ehkyS>LxI zUn7vyfGqa2TH*aRuw4~xfPZ*Uz$tKj0@qpNPO{;S6}S%*W2^(*pQga=d{DTW59|Fe zG9iu50upOh#GNU%I4flALcpH}c--mm$ED?2argIt9qSx-KQUcM^blKNjU0#HCt~Wd z_n@+;fh)BdkC2e1GUBc#r59ZFIw8OGT@q4XH{|`edu_zCUk)y@!w#9mtSrk zRl!UXIrM{J+T~hXhl-GrVG5k~tyAZ$!VcZ23h$Eb0BSI8JnHFPCD>MDcu8G}@Xh}Y zyiPW}=$-ApY+rweTDCmduB>^Kr$c*1s`nHj)%$%GO42%YzkI|SwSWOvY@%^@W3YrwbuP5%lA2?-8a$HbvUXTmrIGLIM^13NG5)a!t59^uO z%d41pP%^9aHq0GycYlqFHwY{tCjsPYTRqp+CHL+-#6DdJBDHtYGC`8lCaX2>K8)7n zzbtJjI4_6c51+@0`}S?w&s0in%k6>)@rO$`qpip7Q*HDm*Wt7loSzfqVBoLM6dV%p zTh|nKp8`DTJ32la>X+&gWdh0nls>fKbqZj=60f5=^koen$>yUYUc3DAka!gwYM*{* z!8j=&X0x695Q5|4?$u{7)j+7HV3Ee?BBF8G7+pjUv0}&oKm4-v7h)HH{Bx5HaRHDY!t7_a95!kM|kWCr!ElTJQ9h)Cid$a{1D9 zoW%L`^CWu6V}o-Y{ zSBBOy5O;6k!~FHup16C7fM7uVaradukq>k5W$Ml*I*@5?R4zL0w<3ZJG3Wf`H?}!P zu+?VHA=tsJ@5qNhI6=$HgMK1wi7b0)AYZ`fsaL?zgaI$2jpEt}dqHIQ3Li!H$zp0O zr%>vGDl&q)mDUTU;eBPR0LbJ>NFSQ^lCI5i*J^0ObDMy^&ezC)#s6mh@3Gg*u76;? z^eI^{eOLfE$ifg0^IN_=TW@^Pb3#4FL5l^a#2T>jVG(Qa zDP3EVzdh76v8thX>&8+Tq}f(cF}&iZqH&)Me5nW&=1RrZi)seWSTgco{~zPbqITKf zT#VZ5^)?1|^aDb~q2~)y<)(v`yIz;;@bRWUbZm>z(o=mIpSb({Vwp05%%_+St{0E9 z<2Tmy?c^fVw?9q&3Ob0p2U7?kQfCXvAetPa~l(*9R8(4@$C;Pci_3}y!~h@8wcVh zB?QHs(1gFPXC?%*krZ-%w5uubGlAcZ6L zS(5JJaE}u9MjTEzpGYr`uko5s^x}@e=R$i9_eK1MmiE2hyi6eJ> ziRLXsJN`Q`?C2-%xjZ;{9t}^Zs zoWq(*tTM3&nNMW;^#izXal5zevj@^R<^Ex*g0pGxBn zEdsZ-)k-&?SP#)jbp(}2AP(OAtA`wVCH)i9U$*ZF>UUqU@2M&poFlL?O!+7u{X0FC zM#z}^$2DBXvGl|2_sFi{><893b+^rr+rghK1_NP9xm%CiVSb4D0YP z(4Ys#rB;rV#S)Pr*vJ7J{@2gF`;<>A$j!B6$Fd5$irQyQ zj(=QZ@H3?Plz1eo<}A3nXeIzO?f=(dWT4#`YkQmJhVpIWWza^!U#2U#@O zfumT$kQqxN%wHD$75iQda9ptyYbxc>uo`i3iVdo%kU#xv%H>b5np@;g_nMIW zF=}q+Pk5TpNdDHmGmpB@dJ2mQf*`x>TYt=UWl>J7zjT!X3tpRAd`sOr%il@Ap2ur{ z_{yxP+zpYK0N>$Xc+AKL68r|4A8f+Y^uEG27h7FbGbRS6?q((T_TFK2Q&-<7GwDlJ z5u&3Ov7z3huxrP|{(fP9Zb`)7j{rIZ>&qqVOO{&3n>%0`slo>R6#lpT%Xwb8e)knT z54qvb_yO7brt~mtrmd)f)d`v6lM2abuE^f%fcIJE8Gj6oyU{v_A5Ow86mtr2_Ni!x}WHg zvjc9_rqh1U7)9I-{dLx#4=2kbS=OmpQoP4H_9ec63uBpTow}H z&!+n8eN94X!mwsr+r`J_G}-nY!{@?fCOlPo0TKENvx52lIsWnfjE3^UsXnBS!K=EV zV!gc3+b?){=qZ`eJ+93OJte9!m)_Q055=$Z4FjvbetrVC^Ea2jcr*Bh@pq5zZrJw< z*H7cd{0gTXDZ>5F;==w1g74iCTAYhoPbSN3`Y?6oTK0-31O1yI*lmjGZND#JPr*AA1{0fR(6cZGUO`<5TJ&Fdkp{P#+ zMcD}yb;2TK3i*m>ZHxqhqrklE70pFG2F-L9B)(-tO0oKXp^G#0nN+H zCm7Kua4zw%naq5Mcx5oJ?Wc~vjT>-8W)JsMW0#;{TN^!=_o}n(W+DR?ufmIVRVQ-L zg&}`k{X1blqgOvi7s3OslRsQAW_Sut38D-8j49^-D~ZOM;3Jt7sO6JBhqP)R=@#LqB}Sc)h2@ zMqA-njy6lk(@qZ;e+~6T z>Tv(tX)Vir`M6F>9oMtjCMCx8Qpk*PJz7RFGGNz}?S?e&{{C2*PNVnAN){gQ7x^P& zdU@f$Gp4sC$5bXzVoZa2FYJtIJ)*}~jOk>cv>($Fni0+(#jjA^^>m=anBMaX^4iAq zG>Ux1nEr#cGC8In@SxlRH#w%6^7KDFralX#b&0xhL)3I&KO_BYEpTi==x1jjI;Z$i zBz*-+u({9HPA=OBa?i%9I5gB%T%X23Glnmt`wRCk4z0`bjQX%_;?Y6VQ}LnaiK9K{ zoiDI6j*TgfXNn>}vnq3`?2paWW5{NnPGRezxo-RSycC!DBY_gE_LS|<4Rq$WOYlJf z(q-MLaaRm5n?0j;S7mY!NrhZfHa<7dX?z!smB#C|D40JAD#9KQK?z)9bGM#VE3H~v`?AF< zinS6R6_Nmf@CF|ht%~^Qo+pa7@|OF5e>1!H$|ZM~T!7fi=aaqJ+1c5d-~8tHo*4wt zQ{&8@|{_tDOse0#yQ!-Rb$ek%3M$>{8ts zSeJpXr#2)_Ko8I%hz(!S=j9o?XC;K!>IAeX4}PBo1P5wWuTcbC<-FtxgD#5-q@1qQ26E`f^&M7 zIL<(osh$?d^**HXKpupx*Sg#0&5MFJV_$M5v9SMN=31fSExxZFD=?GAHa2o^;!{_ z0@U=#-Oz)%iB?w3-5EJ1Vd3?VAtKC_uMko58efKkvNr(>5wOoJ*L7}Z%5S`BCFS>i=@-0dzkUV4>WLZQ;dyTaWz3<= zkZdZfX;f!EOvElw3&Z*3x;{t7TKYR5XQ05OIP*G4Y_Qvy4;`@J?nlfFV^-5*y!=Kq=>6$f&2|qU)|{AHf*P4f(?=;af=k)Yy&Fxkr`(Qfexv(tfBE!L z0FKErSZDzG^kLMk3z{>KR!+EYXi-}2!s^td)kNH=MSfLW$uikE=qGYf^%L(H`-`fZnX870s+sCJ zXozo&58j6{CQ9Gj82`M<7%xT~lRae~uEArhJ{B;>&!TR9j2}Zf>=<9d>eR;g3f!pU z{Hhqv(x+sMyFKulP6zGXtll(q)8+Sap_XV6EM`4kq2a2v79#y2MwZeSONA+WkY*c- z^i>C7+`*vJRS`Qr5Nk%!zfnEHO? z_l>bs6mye)!hYidzk1I_T0UES5M+V1+Ya9-+Kp(}l%t5Q&`6=r>=oSJ4=DsggF_?I zsB4X0*BIVDs%v@6b&kLYc~%215=^@>h{& zd^b%rd_Tpu!-Lpod&)FwkUix({GjZAr!p*6zrrv1E1NYJd;3KRM&EtyIf6I^)}CSN zR?IKIrYuIa-lhz|tPE(%F1&}PtilhPa<|r$JECgJ*8JV>3&o1V*U{FT2rY*nVka>+ zND>t|hsk<~RQ{w*CWoOEd;Y_@8@v}fJS5mN$$fD-)|Q8;1hQsV(RvU|U__D&A(R@* z$#l81X-y=nG}YxOCLSi|ZxKVRG&uUWFRD0-&xq94Iv54Dwu%+Suyh`zt*w%9j!s79 zZtFkM@>S%KP~U-+q5-uF0A;)f{J7RV!=n7hkqSlVcFDF4{oPPedpJM z1xx{iIg{D0Uc;(j5WbkAn<#`}lX?SeG7Q2)%=R11wvB0OHR>*N4xHtFfk6B(CTOTL zk?DQ}Aif6)4a6e@R&sEDzK%S3@bYCb+o75at6r-?+T=wtvj+H3;cCP4e9*8hX@TBH^&*Ev5#om0Zr>3Ra>1+9181p^;`HQdn83S{d~fS=b* z`3odR8a3>=UPZxeA~*X0usFbql(mWA0!9sO3ld5dw!$$F>TxZs*Exv(+Y!gOmX??t}hfq2A;kM-`TpgjBIY~*&c|S9BjV47hneDd8B&kydn{_ zQ`b6u`Q^6a!M=srM&fySlJ4suFdND1F0tjhdnD&vL>KIk&xbeTlaJ2&?)tPp0|Gb` z5$hpFL$1|=4?fW#-|}W;QGBc4TO-H*avHcd|JG&%mq+(4E?cEbMcqaqS_9FcZVDsy z$w|KF=ke#~(~(tv&o%o(fZqGeBpT}`c7y=^-%n=_%>Sx@VIujWk;uY?q_yzsRIonj zX?!`*A&vG)SfY-?a5@%HNlIYjG+ec5C{<~1O8OvcvkC9w+yx6PH+YSfPh_DUU~EE& zPjR2QB-th&0E8#1IE+o&%ilA?KufRfC0UGG*yKCS*d>_F!I`r354w!)OnK2Sz1T1P zgkSmvzqH+#4vH5Fjvs0k-aea*YyTWJJ;+WHFrJNfgdR__mC!%e0X|2Z0&xkF$v;6_ zlgS5t?;%rcx@yKkAv`9ze-#z=A(0<-)9U)YUtLaLT@UMZ^#+z|b~$frIaH+}uDn=dl~5+fV7{TWEX;!@7poSKzuD3yu6*rqK;&$`6QfV3-6u(GhQ& z!yuhrM#D%)d52;lG@!jn0pd5eTI(tpzR3-;b5G*zOD79-(py)EJA>``dZc=X?>n)GEW% zD2j)Ukj?+DEFX)nwwv?cM<_BP94)l#E=6rfxgV{d4T_|?V@XmGaQv7g3_VOiB}qt` z4ogMHW}IhomO^~PO4seG3Speoy94SA6CmPa#Y>LloR=)FAni>nv))@~Aul6TZpKrz zZZuj~=Ir{B*?G^*6zs4?%18We8u|Zk&TuD@90i3yBHcxkvu%78 z`pNW&Kn_fI&9s7~;P=Bj`R_a0?|8~*w4td!nFZW|md-K9nugxE*r^Um5hl&Dxr9LD z)6DsY&H3*EV1z>e5n$jP3IcHW2jOQFNroq7$^ksIC;*0Avf<#nqK{|Xj?hu;OCW!P z)s8p?i3gB*<5JH?^gO;{Vc$sADpznc9D=|Hry)QdZ!rYjR0cO#id3{g{&N`}EeAAL zp@q01ZD7xDsA@aZi*BJ63n>Y_E{u+a0_##)0-}MQ%HYACMn6?P=3_4zet;2iF~}%Y5ygVJ&%)5KhPjkC37&wx2sX>Im*&_@_o_Y75HJm6 z=x7qo-@7^g2w`OGO#qeB?Fpo@JPRUJ1Vf`ZFCD&K*CCCe;@8Rc_^0=Z>Y$Zc)p)XG8rj$(y(rW@+{Kdn0+v^BY}v zlK7z4+3nS5*~V9R9=%TZp&ldKZLs$dZKP*UgZld60p(%;Zk!x{-P4dlN!uI_ z*QHhhk%77VE7|x8iB_&3fXF(cYQL=BPrye5>czqtAn_z1gd~(=H#c6Gl}*15na*xQ z>6vW~$_b@XCiyx8WndkT_NecX@BvG*Gvy5S&V%e7>`HFGB@-_Np(6Xn3+xpmBo7|X z=q2!juurr*LEVft_=W8%DfKgPHk?u~9@^P&v#DRLsSAz|Oj(Lded=-e-2)Q_)!BI^ zTY2+19Hj?Ss!%LZzD!%V^}92)gG z(TzeJDBj`%2hV8U{jGSi4vE zP+z4tFGQ2v>tU~MVN)RfZ7h++*SoT?5c>Mr)qT}zejlIT^2a~(eS8nz9N_!7-o+-r zu6c+XL~fbVqfAMoP)4XXuq*>LOxZc$od`q6QAHx6Y!;48hO}m1coTkzC7A4DmZ@6I z#?u_6^U8679YK_kX<_>qESyM1DU=MN{h2x88mcw^^nzWR#}UI6ytYx6j^Feh}v7CFt0&(qk_ypZ-c5=5WBQ8U2(_B;a& za3uYHRMxUJui3gr>vhezK(Fh`*4EWYuj>oM(DQZ;X>DDrM{9lDewJR>QA;cPc)woP zQ7^n+X>DEo^t%3hw%)Eg!_~!YpOR+$#BYH0lQzT+lAuX`!_H!VA=y(7Yi~xQ9@4 zvA<<0S?G%zF*~jd}JyzP`*IAlJ`+ng5uzDE>OB5S^w6X0q z_s6X57joz3$!q&DXk{^i`*zxgFRG1J+6ea>V%PQtZWlXwaJStXGq^u;vf;jQTFl!1 z1-U$($=K%V*?gozrL$%3;JJZ&Bf+w{oNO7?-0qOPhd-J_*y0-!hpq9 zfe79QQx+zp7NaqZ92zn?H2CJH6zWFOV%z?j@j>L#SLSHon~rmA{2-__f#7^V@Hq{F zAo2SFM(lQ8K{-u;n8Sehxdy~M0P!v;Lf1EeV!m33GI%uqz7zEDT?WRtO$7_`a99|D z@iGR+>=0mNyaj{CB8GAhJ)uDnu=CrOSc_(B8~o^P0l{_c%N#tY%gvjZj6 zNr-wxCtPfGEKW2`A!OZLrW`Wiu^CXBoLy$Bo}B#?@c7* zrs}(%!zn*izr!0Ad}}0e@`)z<3$zuIdM!niO+rZ8L3x;XaHB!)M`2#+VB{${p~!s= z%`T%D({O}3)8&M2!42tSFGDaLH zfqpFej?s^i-HBYJtR1i8h>=-JtCr!Xlr}Wy^y8DT^aGK)YCl9Z5{_gA;mC0lLKldB zOe6X+Es%apBl_`gMn8!8c3ZJ}{j= z0BVABJxum{iJIICYH}~A$-REmWU`l&VG>m#Kto&ef% zMIdeI@1-pd6ls{lKn>b*bR@$Z8Vb-B+QPnh+A{5=(-s}|TEw3PH^%~hK85Fu@Q3zm zpjoK%pHqlGKpUbs_k!X?hePlB_!H<)6C7%e{&?g7`g27P{ps(eKe>fLSoHT1&0$dp z`ZMk1)1P2G8q4WWpd54UI317LBFFq1`<-+YImScLAzoS&YdI$6+8{3V7%X6+xzuSd z$DBPT7PzqhUg?e`$2hT7kA@%ZBFB6>FbG4Y4QmcVLeP;@AjdFWlCMip-iKHsi{wBr zCKKMZBxp_H%UvK3aGhFR2T2Fw9G$05D&7r#S~Sy$-M#6xi6lYfkcOlwMY@*k-G{am z@fW}xt|;3gK2)8>Zy}VwwulPgO5v!OU}$ z%I*2o>gywHHB;{pBC2cmkB|3jG!%Qp@<-fqvdykcgT|9!O=a<+2p3zJKw8@_)n^p& zF9W{qEmNl^dJEw_ss~XW5>^57?2vi1?$a+;5r*|FX$6!j`dfhAkg+k{tR5nb(tuhK z14XOX-4n3!x^rMpsgO0+nl3FoL9LvH^&PKKVm58%1>D%K{v{8%&DSxV3qhXRr0%;4 zdG_B>+KBx>>~GL3u#0R)zR{tDT|=V>$CjZ{A{Hi8G?C8Tn*IjcJ_7o5Lvwwa$ojMx z-9uDU*naJ}vT46MH`A~00E3wIi_JsZN*N%dC3IFqIfPFDC2sNPAg?%y;Y%3{B1HOc0qxAvBJWz60 z&^DVU$M8bQ*=t?Cr*M$9_r^rvA5QWemTVuEfw4p{-D6-g$kMmx+M=dFYQnPEeYD}A z-h}+dfJT%60llsjBI0BoVU2Vcw8P%nOEffU z8QW(qkDWGF+%bot)==tgekPyI&@X9LHaEQgx|F@WQL zN5veDUB&3&_yC&Vn*pa3jyqb7k1xZ127Dxez#ku@q{~4VnbbczNM3?Qv@;~b(q%7B zwjP!fp>D<;mKT&n2g?s&%4&aD>U3FH9zd48G`X$$Ez@C(u(qx8@!t`#g|UjIeEj+4 z(T&tqXo7E~Bw=mr32|6iq|I=g2Af!n;aCY9e>75^Yxrpc$JWbq+2{n|7+d*x-o?>D z@_CrA+8HCm(qZr1ZapmDGq(dQpMlRZ8mt_RMzlXHbvg{{5kQEcM|){;ET4s<%e}pJ z3zI`UY^qLlZE3YQaxSzGOoK;*#F41X7C#LXk4NN0H*n7m^&dEgq55RlEMf`6J+Lpt z7>3_o9UTnEq6t3aZwDCac<&&rul6d1UYrlk4~4frdmA=tYpY&2xs(AtmU`Xdi=qSi zCnkTOWAC|Bpx3n-j_05gK;BrwabT4C@iUOPeaL%C;n;dzj|XKDuW`hxE6g3BG}nCba_@4sBnHB^(!DA9FY^jZ!`Ci6)#TaBMy4D1+7zbJFpr z%;+$3Q*nDkGNhfMDL%Fyjw$Fu%;DGo&u=s;T?Gsi?Te9KIx9^IO@G^(-!lC*DV+Xp zZMFV(>mW8x&bH`pqXYG~$Igmwl-`G%+BZtrSSZ#`XVR_P8;-rv3E+Dy;dptJdhnA4 zrwtri9|o}vF?@jI&x7zWO7}((MrNN89Y#uMMEhc7g!tHcI96TL4saZTg`d&T-vl(G zo#Cj?a5#|I{ry zNNz%yQ2RnMLVRpJ98=H*;A3pz*pM9^94iq0*v@d&>8}(>Xnk^VJLR`GT`q;H5o3BX zONegt>aS?;(ew8?wQ-!o4I>Dxt!7>YT4o8KwA z5&2zidyh!W=vZX)qxIvl7@~R1$75`i?t=_8qJ3vb)Z-Bu+*>cdpL=P{>C%Yw=w`vQ zuoJW|)Wh0O+AhDpb4kqMxW7+yaQrEnaGJoe^>o0A2%?zNfzJ%lK{5@EXkSRSyZl}X zUw+KtnA$fwIMzbmZ)Z5RxBMQ8{+^*xadYN(LWX#_4bex>_X{~nEkqw-VN;OxWGuH{ z(*v@e>`aPojLtz5d}D+T8I~Eo6M7`Za@ABb^fz{J90yZJ2yAZ)9PjTD9UR}j;Ix5b z>!kq!od6u41TIAyoKJWcWIYMO$nxXIqq4d>;QwxKj0{PCgYmKTaNKx)JHW9zN-w}* zG@{+%sMB8%4kIGth;rx)ro6IlET4s<$9{g_HruniL1n-Uh{B$YEy;o?vSvM`2Skyt zKM^JVpX)zv9n_w^0mg|K!|}r|(NW~VXo3&_PbnN*FAqO-HiKg{c38r@Ac`D>k#8T2 z4kHi4Bi_D{3`vih&g<60@oID-goMzNUp71(4@T)1SO)pIo#Cj{SNDBGf3x zbYsoo=&-#rn$W(Z)Qmjb6yIAffs~#Zb2#3b8Xf(uhyCI-fn)3G#t(2t$DD55_-%9; zIR}ksUr4q){e7cXJHT;PT67qhheotB98U%PJ=1HCV6o@m{fVyDQ;sfBGoquwO*eAU zVSGu)Gr8h?1Lyhvk99=&$Hu%MESbwaakydf!GC65L?KA{y_%Wmm^EV9v?&>qeL4<@oRcMv(GH`=F@l3cIsxH*i{dK7UhF;9=f6Ad*_gmi zaa{KKagTcdHtioGI*r(B|H4_<@$*?4z2~vuq?TzosYN@UAb+>|c4ykv4oBb8i3*iK zIUFd818QA!krW-*mN|zSL}7VdY5qZlcAB&8NHkWQxLhbbET3?yKLw==z+trL zNHaS}A{6utpx}~^<;$z~TkJ{f%xj@^gQDV)&myrPO}<9`3xsj4-zz>ljsuF5+!q)f z11!$L2KJ6gDBUJ1E_c_e{VO`7E$sFD-Pm06(Dx=~lXJw*iX*&j+ii6_-Ti!R!~Kiy zGkDvm?YM8mQPho|qHQzt&|Oh!5MJHj?1hc=igpT5*5%ih7JX|{z7u{`+htSTCyBPk zv@S;&Op@GBn?0M*0b}Jsxwlx5CugYN9PqX~0qr&(+?a+P{jgP@#a=`wawb{q1vrG^ zXK1px0+)(Xr$nWat(mwQy8mKdz5 zqHVj!eU+q)PQxzG8MF^3cE|35ow0C?w>vlBzRrC%t2IeH^bs|M+QAFs6z~ReDfyqb zfb%4#(7t?ZkN(i-4g1ga(O|+3Zo=>=i|4!V=e<#1sf2U*#?D@3I z`0sQhhy%*Y!}#x-u%JXrL~i}nbM>Ohmq zZN~=91T5C&*12A$`=a*++f$Sfi{29!{T8W}_n=33VP+Q;6LV`_MAq>5ePPi8dVDnC zalPv<{`do7(L{PY9T4!nz0Ng+KgRb(dVC<@ah>ZDdQ6}0#}d!6p_$nYpT3;N#?=Yg zIJhQ{^#I*M;R)FTg++zv8}bWS{=c>SVqwt*Jm1LjNo1t*CSg%J&zD$!jh1f_7JZBJ zFi_7(mjAq#f1|Ky56{1e{!%ckMv16FT4?6F=b z)NFBzYi)=7I>qN_rQ=ul8687|#Ox$n-Cn0id|Jtj8e91NN5?%J@i~%nG#qE~6q2_=DRTg2RLu4gDi zEc#fm5w3BhbRe~YBjtNq!A-8|{4tPnDm~^%sXyNA8pR(2DJ}GvBc=X$i)#R7e!)-? zsCOyuoKj~D3qg8I?j~1HdQSMqP%|BOG!{fPW_*Nwkb#YO?K|AkC=Q&l8F|1&>I}OfPL@HxRdgLeb?|jVBdQ)Mo=EG??Rpj?0av+}WA}tVVEG(>!1#enU5>c+;-ETRK~kQ}-bc;;7KdTo zR{DqiX&wD5NYg(&veALg1NeTFZGTc~EmCefC_nuWN6c)N z;dt&^SkO7oorEbIp6BlSCrUA%yOp?aOnI&Y%rpX?J04sXJa@=D_(@Tp`M5oKuI1lB z7#hTLU;j`;&^xw9iJ)Wc~-Um?( z`1Nb9N3=oD-3jlhKYkg4_1w>PX!tc`y&rz{BRzKo+3&fsTV8081!&sF6Qu2y+YP6s zw##FSPJzDrI#^j)-s>Q(mFc^qK1C|5zPkuQ5a+#56W5L@@9hp@0r>S<7=5=#Es&$D z`r0S>Nl}M3tM5J=1AX`6Abr;m#CwnYOGDI^{)8}cL_N(puof2=*GnR{*$jiQ784rz zGA3q=H1dwOHPlP-*GnQtz0-*k$MGy$oAW+U-ro4C&LZl+##fOOhbyY`fz)y<$ zO?`8Ea4dN7vj9o}MGWG_rZ+W2Jq~AOD-bo#i+^N(xiv7$#Dqp>f!GFMUa-Eh4KtC^ z$h+~$R-j&-7X!Q<*Z&Ix9Plg#{@=F(@vMpe_p5apo=pa;@ZwqA{~MYA7sC{m2QPsG zQ}h4AgBhL&Pv3)5-2Y3OaZGve30T>HS7H6Xz#8)Zg6on0w^<$>6aVkdAPf!S!N+u^ zBm+`oR0w*SbKkiCH%k96urVeyaRjEJKkscq6H|2e$Me9=s8H^7;<|DCiVnZ_fxg59 zzrNlQ2ET56SL3-y{Ov4po*NO*{S+?AusnBd0}3%4^dzX0;d$=9l__nErp^xjzTTuWmRh6eH6CpT&cx))k_R0J^2bAMd^UogO!(8TvK zAzS3R-TtbfT<)qUQ7+DNJFcF4A4D(?O1UXm8KIY$+H z^*Ue|miIbHYvul5aF6i3chRdT#dz=2#I<9}d%Hte0Dgt_|Na5U0sk-ALg4>xR^N?< z&H3UWeK*+ud*K=lQSbaqs}S`x=fH8lT(o||NAmZasTgckcufUUId4A1ibhV@jv)~!Trep3$ZQq+M`(T;%5Pr0E!r-2Ypgn#lZjj zMj(Z2;_I0Gnucc;Z~Ea`+!h^?E&6K=Q&=9n1iVA@|1Lu+EDxSekyqUROPX;^dGLvU zFuV%u{{_~N{}-k>^8Yr=gJWTfu7wQf&w~?!cyQG(H3WScLE2tI7zu)&=G-^#pNq~v zHyGF$6Ph>z(=Y(zf@7~Tbd-Ddk5QuB>7<#&@hdv~+6T{DOz`XLrD5=E;By*D8~juU z$FEZn_xuW&VmQ5b?GhB?{$Hq*;d$=9U!xTF|HeG-*#Tw>yb8y2$CHBs{@-U9&wU1z zC$!!h3!ZCvDF{P@c&iSJ`Vw#ajze^x`e z3o#X=Lb*84?ZEzDh+@F682Eqx9*AE}>?zxHnQqwAe)!dqeH*8M_r4BR7MAxqNNeT( zU)XTN^WH^I=)Cu7;@UCQce_Ja0Dgt_|5h^I``QbP_YQ4V-;IUM`QjjbH`xFC6nHb^ zy|(9Dg{Y^w)*JW#M(zIvLd1kdzKn_K&x4!L$ZH?bP;bqntwO!ii4({1ELuF<2kILW zJTnF9zfJHgQ_=9OCs5lf>&1C-RIyl}R)blF(}S;qu%r2Z5nmae7pFdkQr!Q$0I8Vr z;ze*+N5G2@{SL?h|F0cC@c)7&h1P>(!Hb^-Py#4okRH7Fw;H1M^*01Yj;L{7{A2U~ z0uN$BBeR0^;U+Zlg2y$~yX;3nBb9|WCDTzVb&{=aq)FL~eeA8BR?wc&?rxH@$*fe2 z#B&MzMmtA(q@-PD`$$L=^`au>RW&Y1DXnUhvz?+xbTo=~V_wB4oy>~SSW%ZJ*13|Z z)65>pNEz-OVlLkE)Qa|zlG$!F`fWiSa&uuR-mW;j{s-|3N2ky%#I)mExUAS9WBaklX7!jsZv*3^#PxixuUbgL$lB>=9P=Ky`3aQ zG$K)(hZ7sIX}L&Ssfk95veUg@%H3&p4o;MI9kq{=B)b@Pda^kiZ)+T`aU5tL9Psi# z9Q;=|vefaON!i_mHFIjPOSOO)Sd!|>FmcUFt*Dqa*1TIDL97`BV8u4fSn<%lx-XL) z^|gBwon12$8%>w(5-aL)KwiD**o^v%3m@(-I<{1NYpDGsrJ}A=BDlY3BqnY~y`s_m zLTRo@OuW=Cf{8~+B{+MJ_a{C+aeRxzsXnU%4 zzr<`$IMX*e+mntl&EZSDKk@O28sQp=G&H1y;vGixf+ZCPv zFAlGc3NP{xVDwt)&nnaWSu`t|KZ|A|moVDNpA~Ow`}hgtaQ)wgtCuh9{w#Q`qx5H$ z!PI-B=FgItLyN>3^PzoG^Ik1{C9GHL`PN(IL)duZ{nGu9@$vF`SL1ltDzEYX?MMd~MD{9|PJHX#WZl z-opFKXqx)`W#*IZFN?Rgef^Pf_{QPu@1OSJLv;QnA`^lB7$Oy?-d`5)5BF!r$LHku zXXE&Gy5U=CRju&YBiKhrQr1iMo3It=6l`BHJyWvJ$r8s(wy(0x${v%j<~vbQCFR?E z?39_RNWJP@T@Th7BUc1Eev!{|6FDSJxuKai9&BxP`# zR5&=p+N^q$ElNmO6B__3yQ|j@Gu*|9j1)+p})}Z$|MQJ_Kb| zwQ`c#4kRR?<4+r!Ci(fb2pWVM)$R1W#^>|z0;1*=7iWan{-cD5YV zTP>@bE-lwnEf%1vL6KF(ailbVw}tvLDg*zS7W)$v7KtBP4U5*Lne3yoOx2^Z@iYf% zS~NGR0RIv)EezupPNbq5dIC=oN@)m2O>g@t!Em#qd>7p;pgs?3Tc2Cq?^FH#$j94c ze_{$Sp?NCXF5_<7@lfDMoT@%J6 zWwW}`a@*6lJf9qHIbOW%mq>yuC}K zD7!F`$80D=SESsEQ+!hL{awp0g=O@F^aOkiK6TSQIsu> zqHNzN%I?1^ayZmQQFd_@W$%un>~&F;?GZ)U&+{UO!^$YiI-4(RQHa9!aF{b(uU&K8 z!=!S5dPr1RE#vPq3LQi{E9Pb-kU0*V0TpQk8MQF8&N$8&j!4S;l9H~bvT7~?y-$+t z2us{3+4|vzY;qvTw+HYDYKU#$0?C;?N~7_HbyO#Gc{w|C%sBBzajZB_a=x5B@wmq$ zE&S?tXsD#5RE|hZkn&+tta?0&GGLzBV^JPRvnT~-Wrvyv3!$V8&n(UV%%XG=#??y7 z=q#h-fJNzBrld>CAUw>lP;Z8#Hx`(JoR;h?lYMfw(NsM-+hjpXqT7*ldlQtk$=SEi zWeVL-D;E}2O~-dFc4r0qxiLG-f>y(jG(Q_!{0r5{RjaO~MmXmnt-PlmxZ=2{Olh## zU!V-L@=v2AKHs9$DNIVIss7Ez`YzqI{@6@ z4-No#4#1sfR^|ch4CJwecbYcw2=*g@8#HXqz<$$r4B4}~Gi3kOa2@s;Ocf_&ml(36 zvD?*>5)S*)e2+yb0h%9%sTVp18;c%g3MPI}j_-Ie5Z~t$zRxFohl$*T3-EnD!}s}w z@AC=Y=lk$ovM=WNZX$fYF+0zKaRR=-N%(HDze!kZu`hlaKlZ8wG9FYVQ zxd1xNgg5z2c-QFIp`Hys!iI)*5i{Wykq-^Q05hTehQ>R4ni-40dC+B;J{BPfPYqgq zYUjZNtOYvNdGNAO^WYUw=zw{!|Avz|4-zm7Iqs*shV=KP2l=J{1$2mbe$1BiF$p<8 z`Wa(5KfnqwL1H&G{z?PnWfEI*LQIVW(29Vmal`c|b!rg3`YoENkC_poj-GzRFQ0Ht z&p$^m1Fjg3m#-M24`0YBH5t97DRoMDx&5d9!<2nV2wr|OSWdvCdb&7ZQnec|=UXN? zlY1n0V)8*pyZ0<4OR}WwQdq)vI7u$F9Zs~S+g8eWV32c5^J|wGO!kFzYisn_9n3K8 z;D%`j8K5QmFgRKU_g^=lHl&Oc{|1vBB7_zB8*D4-nkX#x0@SlGHu(c;3&dnOwXlaZ zahcEF12Yet(@MQ$@7yrh&kmF*DUTm!)}us|Bh6vJrqI0{JF%zSpj~no$y4VrICfUn zTE9jTj|$xB{Y#g8ET^+4$p4nMp7k_348?i!A#qThTi|X7`kYHT9BB&9d!XAUZ6f!JU}jC@ilN zh2@)^y=s$oLA$|+xOT(qqbslDni$maxBbnx1C6K^mNzr zcr?eFY;s^zHDw_q8qQIPG}{r$;xJSvVzxUHMaL!+OPUZukEo4>aanOADktb+^mAqT1tPP zepjG(L};4*1wCfZv3YjDZ@BmL=coDmRiknkw`s3mUkH+8ShA=b7MD#gb?g!cZ4xSv z14N~iIEaM!+Q&|DsaRQu;G?C&Q|pj&if@WMg*-~uA`{or{Km=;gsNfmIwh8|M6FPD z9TJuJeICC~afx|_A!AV%(h0>`vpa)j)S87q*3L+)IC2?wHn%3eWQMoZYN3hO+LBs3%ok!)jZBYoh!&_n)xF-u=o-R_^ST1Oaz1 z+n1@bK=pODeVHhyxc_8UHd~4ap00%`AP)M#dXH&Pt@SS6xt&z%d@A1u9g`7v1wk&aTIU?P6ePHwQk)pG zyf-m-kszvExm&0jf_F-ZXih_-vQelSM8CM7fL{<>A4!Ikm^C|HsNpoZbGhy4WpeU> zMmMOkbLf&LPd)Us*3HRs2G!V^K2_M)wH?HZ=<-qgmMUUKK9S{-pg*9-b@{bEs=NmU zbgF#RlytV%&yn6Ykx+WhijDiM!6i6`F5g*gXvO0mytx7N8~rUhY`Jf zkEruo8dctcI#T6&R?|O9bL-_A_lr=d-LHe{x|@<@F?Tme@=GA{oFuzN5J&4}gEm<& zrannZch!8>aSsvOkwVQsaqoCfy%srx-t*B@8osA$Y3vqj^fZq`u?s>wfKCqS4ETyh zN8>oiB!do!gB#8a#=+N-)3I=n=?Zmf*KBSDS>f?`7Lfc8>QI4S$(eHN-ei*WS$dRT zy3{XS=$F3SFMWYuy0>3C-7o#a$G-Z%^-F*5m)@hNo#M{o^x2(+HFY*MZ=F+ozPPV; zHx74ey?58HgY${C+BfA^<)KsMMVp01KLfGE1_6VFMKh6FmBCg-Y!+26}GR_YGi zIR|$xhYY)DI6XO_KN;%xw4T z{wL0nL+JS^?f!;U#ti<(4O-6StM;DBb1v6%&UTKxSg5Hh&#edhN}t`w-Fd}X4A7fq zc1C_~J(kZ{`w2C>oP*aohdpmQ+;>*G?MUBQ$ux3Ez&s@kt+%Py1`VTcK-(#0QT}DN zkIyjMr)HY%GqXrQ0OzwNn)a--{)3eEJAAZ2>9IZ;qt^G-wU(p#bHQP&2 zavOeBH3L3Jd#C(HNg0w>Amz!awmJPTl;QC=WgDfUAsI7LCHs(!*WePBvu|=>?Z>VC zN$!_u-Oxzzsl29v3L*L&yY@~j=veJthUkHg1mA=X*4~kb7U)Ru{T)JCPMh}HYEOhE z5T=VyMuR~!BBT+KwE6LiI$oRqmEG~$oYMi@EcfepaIU@ZB(+(KDV&y_Id&XdcMPe5 zA|eq-WuHji&h4K3{Zdt%dnmb zm2QB5C7$L9`BpNjj-<#<}UX z;W^2N_TUEAa5VBkeAP9Oy_F>wR~+ppUr}*1SI(+9db!-Q;%J^wMH&EJN^^DRiDXv_ zPZ(UssXxPWvRwb+iA2|zNJ#dnIRJ5ieP*70>OiC{%+M|=^RNnfs>N7ve~uOB&FoMg z&N}XKj4lM&Ey9}3rlRfhr%B3CthPuSEYu{MFG{FLNRV%q6dNHHBJ$Fdk-h4^?0T@? zAmhkWmMaxbNt3Z0`xjIM=6kiQ({WExgPh_i$#N$_@TDO)ITEzNHdU7tk}a!}6bHQu zWptWvrF=leXNov=$O2b7uU|co+O%>nBB2``m#S)h@OT_0+3=z#7k9D_4aCQ)*?5ZR zLRTVwBgO4%M08QvAnbSHFkKcY6hff>k!1zY9UjZfG@6jK=Q@8lg`zzLh@9lKXA04t z>5TU9&|uJ?M+8QHK8lY1e1@nkqCYQMoEQChdvb!uM$tG5yCM`vs2q!EP725AW?Rj| zafC_}a)5;tcVltR>u+(+%oFWbiuNmrFxg+CQufzbh|cR2qN9;6*Y7}L7@>NJ2$iT4 zDl7`pqbE$w5h_Qr1!M%IO1(dmIw@3s4+2mzFB_EWx2R26K0F%~rII{ijAW6ojU`Bd zCt~#=UGAkz4qf^%+Op z=V#$f+iHT8!3UVCRrsn{c*R2_MEf;vGXUaRf*ie`6htArm#fDTcoq2}tC&qyD4nWm zHInz9Xz#>HUJ}Z?Zo*?nNnvr8Tu|Ik&MnTB&nv!M?okYaM=nQ3@Q5rTk?hLl34`lG zp2%|b<%vWW^Q7CaWb|%o4w|czyhG@?KKKS}cRuEc);_L}2#`R7u7zxXg-SAq1Q17% z_8saSXCvrMSW{A1rff15HOvR1dP$?mN#mI4NaKLSrqrtmX_W7eo-FP$G_BYH+XCmW z!wbo2U}4m5i~1HKW(n;c2IX??p~(0M*?Sd21w)a*b5IA7Q*i(P5mFctWe=d2v_DL% z<+QF)??TIIw{@nml%tf>{sGl1l$_=O`GK64yD30UYl5Ic

lkb!=i3a4^!M)5u7m z8PNbf66lrHO0p5TC265s5Y)zMf*MuB1+|_unMqLlj;1Chp5+PoHX?DO=;9}+eWMY( zySjmrl@p~~4MD~|L996JC#ih}E4mxI<%E#bAQo{+jlID|wXOaoLyKy&iEibit#~a< zHsab(z6#e|`9fSTm(RczfcLong(RT&Q@Own$ncbjtkQOu2*MnN&u#>HBs8f#NNQa>uEogc7;_X%ukBNAZNXGAv9MgzLQbtqa@hy>-7Kq1mP6c#5 zF9PDB;tf|Jf2{@L(Jsm!BOXum^b!vu)R1T(Y3$U58mN03^|(b+6hakdRVWlQtQp3F zyEC~y*AM!f`#flNl7~DPTme+lOx5r`@EZ@_BYiK3d6@-paz zPv098L{0AI)FgzVBT~`Fab8H;64I)28_FsT?k6G=5;}OH0Gbn^6Shcqo{fs`bUT;R zol3j~&2DRL2+i&;JPXw9M$cHfhKO@mv&2A_p4-&DrpboCtEk>%9n%yIK zmFShLi=SpU=J>G?n%(51AZc^dlD_=&7QES1vwMR`P=IFlN8|))cK4<5D$+w%F@vfI zsoCwp6W3^5n$heE@Q7)4SMo%%>tdcTxX$H?ELSg{NOY0;4%&EA&5oqRkeVGuBL!%7 zn;6ycGkY=3?q?wGOtT}k?(U{)-PqO;swN~*CsdlCBSU{|Ghy}8RY+x|)Qw^S(iU|z zhz=BiTV4C2Q0V>+JP9E&g`{fLC=05V1VxYNDEbm?wCUiaEGEqlpod@n$s#dB?7OWJxM zX1Y$w-N4thag)*Z7TtTVqAE^z3`j9!5!p~!;yIo`NHGjXKMk@P{Q<>^?tFOylm!e7 zRwK9>+_zzK`6GU2qw!zivDx1kL=L_kL(ntPhfKmuR=7Ft4ZwonkRfA#o z@~Kx>1x@r5KK05-Vu3_)Xd`Jq<(s%i8N0$XahwGR89+DYknYz5lX#>1jhOJ_Q&CB% zxf!SyVSess^D~4w<`|owk(y%;0(nUk_#AJEYqNk|P>x=GJ%n;pixPp#(JS;NT{)WB zUt(^rD+0V;tC`npwZGTve7wbUqbrc0IV|RGWRn={QtQmQ8~GfL!1J{Mwn5U5`k@}K zAMM8s(e)!qpVpV@30jRnlX(tZrqRXE^Ysx*(PZ8U*RbnXC`mV$eGmP}ftzyMyg}Uc zCBgNz863quOI`X6|2`=`O%)_^Izc}wvtREv!|!zwZoRd@@%65Ih5EMUJG(Pv1>}nt zl~jMnS1NaW4M2HDK!lo-LFHo6M%f4e!ibD3jL5jch>R9LkJ(iFmjXS?&MnHs`;e)~u5qSCg z=wA57W5=2yApZ1&h(AbYRimb(yv%e;`6}0VmeDdv&|_3GpsIl+=z0gp$~1~rkrAx| z0yD+uHa^+my(gW#grY4z6{97-&n%u1^Znn#&Omg97Lo?>{V$NE^Zk@pk`wHl=ewRm zKI86xLxLE3d2Wl`y*ZWQPk6mmto>Jbk*57$FfTc4KXwpYJealr74EVavv#stoJOqu z%EQgg%w|}7DOh_DKff4RnwoEH8$TZng{MRE^VZL`3gWC0&$R(*e6F2?w}R$cDzfys zw&$e)8C$5y@QT>>(IB#jo?8z*G-1@}#E=Ic8J8LuvwBi0BQWyC25Orm8)Yup!sxxpv`O?2U*Wv;FX0 z7qzUs=pFe=yxULC#x+;Y#PxEyE3SFghlriJXXBdeet;OMdn(D+<-|eV6GO<>7S0j_ zRpwsCf(J6?bQnzxc0{=4*ym-r`)PN9UXgOze3<(#aKHzN*C7V3YG{kHb!yD!;zn@a z4mlTfMjL8QMlM?)W%Dvp+4@=V5#oWL;VrLhJ$gw9*?KKX1j^P+=}S?|*5~0ZCR<;Q zL|bI*Z$IR+?S-g^%hq2JHPE8UqLi)4WJdG(7hgb})@AFLz+*zl*1!22vwD{LswP{L zw%t^=rr-%b**Y7y!Ls!~zU3XDb#qNCAk%+n*_u|+u`t*0vh`9TW+Yqxi6@d>w7iW- zg6l~nm~3t5If!i;JW)Q6>L?K$gfuOOtXwAq=DB2R4Y(0f$d&K;HFf1=bSCa8o5WoK#=&SSl z7ysastw|;}DZ|0o8-?oSxPg3Kt8;d;p4B$Bo;4?5`}lg4rZb(d_dsknm#=??Y0l(p z|A?#EkoQ`WuiwK|f}IPmL~J^{fM)gY=si=>24*^gx=f}s=*wg}gThRvv%`7ThiOK; z=ir*`obj;f_IWYm>)*hZ(joae_Lsu`*ge?3dEQ^j!+(RAY*6a?)>P@Ea@Ixj z&o=NWWcx2#I~THz7Ue|0y%gK~Id#bYU*8JSpzi{i=b%+$Ro`ab6^ANM%3o+}Ri}S4K*vz0l zeQ-^7XW(jZcg8i#os6q*Z%AF1jn|<=g8#+>9zu;cXjK+*ilTbb0l_Dr1AG;P;~xoPmZG>DdjiUm0dR^04R zZLVY9)g6!@Ji?=!fjdoNfrLuh5ku4C16ROd1)Zkd)3L7J;Abp>8@BTpJJpr>){a!6~p1vi@yDFSOE+!iFVL2RZ} zm^tWy$v|IW73(?Jur;{nZ62^n*fJxUgX2-Kl>;U;Y4*vQgDud?aWF5iaT2j*c`3HH ze6%q%t^6Cy4zzXjsF+I!G}Ch6Yy^Zv7(X5qJQ)qC{O~}8!}NC)#4rsGj>~MJ#ah>T z(6+l;G^fYV{v#BgMwT?8kz@~RN+TcL*O7*@C#(z+%{bTBu^h^iLLI}<#!vTlq=CA7 ze}n^NM8S?R=lH(Y{IoHW9SuT_8Ha5#kHr8l!pF!{xvR>1^DHS-{B7|OfK zwm9)FO*(_|mQ>MWgeOk4Nm(BE1$0A>II~hsA&}VW9F{sPeCKyILsM;B@11UUq1{O# zf%-vyLIC7PuqK_1_UJ7;nK1D28sZ*J^rqqe3YOV^7g`n|2TGKBQ_ppg$!wAANW;~p zU23Z(v8wvu#AL@d;7+OY-9Nu?81#6|`+q+3)P6@oHf=aa) zya&|A8s6VRgK8zbUsxO5m{S7pWB&}6bDj@PPpVmVd*~LCqxT{xLa~!xVlQTfp(Q_m zw*$et&!-(4*8Se;K(PMnC#N^8+a!0M4YOw8a)&5n@z%=!Fc+TeZ|1k|n3V`=4LF&zP9{lQzUKil}~}$tqpDe z`gOE@$L`p)ee8-z+EQ+ti&dQr@Grj-$qT@64txG)An^YVcBVc97Ksq*RstXO`?YEC z+Yz?O@10v3BYda%ew+=-N4*j@rdajkFOUbrBL@18-7O0!hHHqm&p|_)P<1zaj}2mW zC*W#<>uE?e#UrdDd-4|WAr;ko>qL1JfV1+Jg``nvx{dVIPXEBidHUd6bItaodmYB2x%O4 zli=FG^E**`B`)}MMn%CiY>Z9YrivLW;5wyKED0c$uEqGpyD9i_aoaYPpW-Wz zo+Y^7;pa$hN6Btv^dU2j8yB#`4Z?z z@p0}5S9;(`cM&T>{oL=py%{{vvm$zaR79nJ#qGX2lT4BNw`#-N*);&Kb5bp&OM! z>|PIP6DbJZukjQ_@89y&6nPGw+#{FcI!&gA$#M>^v*kXxLJa>3UNArB@Fu#SYxos0rrar_26y@o#>XdR$E^-AOyl-tysP~xSfNmM(1@owyBgTydQEapA-- z{?Im@7=~E0I8OYya3Tfr03@JR%b3@I_r!6cgW&|$)MiL_IXhFb&(F>pBi<;E5yy(- zB;_lJpV*u+W%+9<2~z%g$zFN@4go}ui*J%JZmgLjF26~v5sN1;xK*fJg)DKdk3HOdI^I!#{xVY5;{SViTJhcT_~QHIk;V7R{fno|nZ+~ZZpBu4xN*=%>rMH) z-EXUNoeLjma)aDSSmo+uAD)9laIgW=2H3*febux- z;-@Fpjc1?@5B&o-De6B#+bV0Voq)?h|x3OfdyPHzCOJyI&lPt6HJe%2;DjiTu zk2Ws(Sa_-yCu&-g;q^JY!F2WBJaN#wa*8B9wvM4(w z=a{`FrNOLhS4&>QwkE^ba3m2#Zmx4BqGi@m7G+Xe{y}Q?5LDu;5-U7-m2z*h(x*&W zzcP=Sy7o!l)IN$pE$u`N?ItFDFBTn|zt){(6L9pR1uKf_ltkM+DM5H_AyW8=k@nHX z8f@p7&q{@wuGx~aY_ILEy$NN`$=QkG3escAO_ik%1aGXWwMr(XbT77hk#C@ecvoE$ zGzGnB))bSWle?E+cR!=Pj)UJ9O)8oxSs!(aXp*~Fs{=dwNfu?a(bvtOy3Ww+GAp~O zs;;QYc00&>w_@m_;94=My0z_Muqxu?8{Gu|ZPG4oLZ1)dhb- z)P-|G_DHibzQC-^G@6xpl3Dpwq@z4<6(`(!QruGQq#AhTMKs^&>Fowoz3B`Whpux*Rj3ja2p8M?*p^G*!Ly z`8ZXLn)-&Pt!Mq^q|nyCzNpjILw^B3>Q#-Co`9RP--U24X=)`)N&WKPvk4ui8pQSHBQ5DmooiwULT``$!a2^iv2H zaoIFtIvSpSzW@8?=%*37{qg|azM*B^-q?a}e+H%n*X?hxgNiZw+3*{rB9u*)N|cR4 zw>OXlp|85M3O~AR`a%V6Qq*O?_R6LUyi({4qRJ-3s+I=IQ zF&UMq_l>%G-+OPK39w5k9n@e=GBWkPH`M$3L}h0G-0yN{N~GK0j$Oj44nBMn)N>2p zu)?eu)69j&3@eVPo`dapl09`$ej7csA5S({;mZs-P)gg;Oi61nWa*3d4LPU>3zy`y z(xh#sqV4lv;)?OSER#~tbYP2fHL3Z~;LTi#SC2d%NFv8->iY;BEsT~8RiMY7DJg@o zQe!Z!)OgUpO@jL@rmI^F_h1)?P7<{y4+#reB4`cSKu0&OCfywe!a#3-xSVwM(nyu| z1uzRhyzH+l?frCJpR5q1)}tfpKy;!s>3b6?=1bfckYaugl|va)%&D)?&AAmIjXI38 zPUejBY2Fsz+0rPxif@PLs-M!`d2yVuH6?4|>DO7mIVtq(Nf-$^{VIac&*|5PL|h`I zUvDo#*(m7O^&nE9Un3vFk50d=l$WC3?W13G0&P>>dVZX$MM2g2VLbf>ztfGXy$H2D zELFQriJYnpK-rT;)ri{0#kHn%jdH@%w(FlhDYWey@J&wJzIhlFhRJ5zeu-3sv~4o^ zQKF!2bGdAmPCq(rd)tPa6jcRoYJQivY!;1dcI(ehZz}dF}hC%k;-P%Q1)a| zvHO6PaVi!}#Weagjr_(q>~oygZ_J&>3xA;zFH^RWLKxS~A@7>9$9dmgle658D1*tf zXYezqkQRl?y?BmPiCl=QNqFR6{C=qLNCQuemaXMDFCq_*Z;`Wbg$wy5{s>NFI{yU@ z+`ofevQwkfew2C~xuWB3bvB03W#fhaZx)5M-YwsS>wPjseBLh)z;(KO4z4q00arMd z%ZnPUSyrBcnREvFqDA6T>?3>G=INF<0fDo znyFxFfl&1mq?rB*J!PO-`Jo)Y1tQz}Tyrw7m-96z^Ln|9=p5XQiVSq0Emm%oJFUn? z*WCNLt9iYgj@|KYq>~>`W@tl{x7+AmxlI3&-D7C z@eTM{EvO%E=E6ESkd5Z>LwCHOC+q5RHho0Bk(!TGb^Q;lJbs48J<>dw`Au@PFyULjA`mq zV4appd#Nr8-=@Yvg%xV>+_zh#&w1VxjaFUY5Z=c6HZeCReI@>bqB+E*<03xbDVir) ztAL`W!YhPFSKxuJ`>q!%U&O7X%)|J82p9>EJ;OiV9GtT7*rIGy@ALokU4C$yASV5b zT+plCKc(mb-Vpa9^oN}7!H)8+au017tZ61gs_PbE!~c={$8U~v1{fbj&Ka%%|2;XJ z;Y@JuSa62O?<pw z86qO}ttu3TKivAWQ^FqT`S@mj=Vy}*{$I%A1t*vRIlwD+w~-V43Bp9goM1XID_TylVV+-O zPcA1I=Ktw-_q<;ft~0B5OP>- zg6u>M&Dn`wMse7QX8xbf1G>XU;pG8KAfiXDBW$$Z!t6w2CPl{s-hh+{9CUNey!4m~3?6MdwIDUj_4wgGM?Vn@t|HWQVGGZRfCGtt}F!?k3PxQgsV z{3zN6*n{f1p=hgaC^9*=;Y{?k;#vyAr{{iA4CljAH2=ndIMB60?nGy|GF#D!a%93* z6d1`c(WGocyui&NA{ly$1yeEu0vRsW0~sdz1v21cm+D~+IHuJX%CMC}8UETdl!2{S zV4)1$5Trhf;rA!+H)$rIktSsW+GeI$1|0mM$1)fT?(u7u;66u-Ww;Zu46s$Cp+SX| zqQ>aa4C^VHVI{^5#-H~9G0ph14M{Tohz0lNSi6wvXB*f)9$J)nh;?X$~Gl!llUhYftcy%8M2Y*H(DmuR@FX?c6JwPZiHz_(e}seX(}*h%Bd#9B%H~_HptAR zw8e0T-cmamQK+G1Nr%OxuZpHh*2nYriyVh2*x@0s!AG9Kp)u7T7FRP^`LX zcJ+&%*zSv-xV9Xayp-ZmLc;6PknmdUZ?!o%Gft6PB(2Rp3`282pLa@VZgml?_q};EP~Si-sP*1s)H2JQfVWOONj(8l9rfhbSDEff3BxPBQQ>C!9W% zxAFccDDPs}3OWYm%^wd;ZWHDG4tB-3RU!fs+oTBXg>7+){pB>XveWe`Lfd@X9*;aM z+B2$l&rPR8;}5-$8}F9s-g=tu>)oI4>zxWYQGI(9MXJf!P4@N9P=@!fYDCS$QS%=A z@czy3?!9&E|Ficc@KF@m|1&ut9HGMz2qGFFNF<<#G~j+k!2Rff{`^A%?h^y< zyZP@$6BRBgp|8#pv1`t;k1O42Pj|YF_HOub3{=FZs!bF|Q{{Abu@9yfNltf^y)WIx zIZq&8Mnx6de!NQW7*E*%DE${u*ywsOBoJMnS-`K^ zpcQ%^pymGv3O_w>g*`)85u+>ibJtEXu*s&zJh+)A=gCrB9{O>GJaw$|NR&OKV(zJ zQRpo@R47?P`ysf35j9xUD3yBcqa=BGoK)IiA7+-tvBJiwIP1EbdSM~Ho(a>F{bb{1kMeEhuIGH!!adohRR7Yc8Z#bmK7$=zy?xi*t`TVcs~61ht$l) z4DUa0!QXk3yo&fcxY0Ri^fWZOhibQlX>@FTVo2=jjW$KpXpNmu8>RS+@; z+MNvSBa7*!6)XDFuq>v0*ib*H!g=_Fvm)LlrhCqHoC9m%CVN~)1+J4FJ+ToQDI`oQ zVJBWHEAnG!BT2#<*ZFnohd__G$pDWwqR~?%=hm5svoJVfMY+P$9kXlsc$D_5O4+lg zyjWA5?unLjAqMV@qx8}WNif$)7*-``4jqt`lVp?crxI-PEIej>EhLy4h1Y+P^|jF3 zoH8%3^njzMO}U4vgE{6&vB~!sklQLZAqt$T!lGunSogd0qIXIAk68DsHc-7(gY^T{ z50Z45dKmOPfG3s3{z~$@Y9j^{Hfa_6g3-Q;&Q)?OqcG*-HK_&%8naKmWiC)A=bCKt z)k$XI6{A(YHvxr;#p4qeQdF@~@>Wv%#D*ACjN@xjc%=fbiX1WKaxuy(uWh6TC{v>( z!LlFIedWfoD9O9MJW4FDHM3iDc}2-i#}`=sJ!&#GcDqn-j^q5`hWu*|Z-}JKNK!|T zAV#aojpIi<;$bkF&Deih~iyKC+T4WMmx#?>@52qhChBKq)NO}4B~))LQQ^MV*m_O8Uw`0)q(UM z%g8^+NBPiH=MnkKyBP;SeVqr|%rU7`;K`)+uLfb^*h0<=G&S1SEYC_OR**_}`j|kH z-|;blB%jcjK$8EaF@Y_5CzwFm|Ah@x{St-#&(k>pySmx1sv*-1_DBz6gf9U?o$^96 z!q3V4?hK4j56>7igfYT-B=Ap<5o*B*;8i0S!IdMq51#a515(Zd#21V!Ix9B>vt28^ z(V=qxGq~D+8gkzN`Pn+TFM;QyQ;@rRW&pWgJo&WA{ii4QJCwG2K&t#SXgdWWv31&h z=-N&~+wodMm?)oS{vU1o^mTO&9CtsgPSXv7rsH&)5txGgk#(9u5SFbof-FhY#h z5XJ~o#M5Sk|LHXCwPpLlZT!=a`=cN~TPOD?^E(N-Cu$90fODZ&+*x+&0*2J#_>8Qolg7_s8N5bLX)6&0q_$b3FO&)Mj+A4$a`&!t`(+ zoGZ8oCy+ZB>|1aLyg7_JR_ffbl5s~H{+xKYKTb#YDGc`K6moygL(srU_qj8iKWE&T z`Ev@}_UD`rq1rl=+^cy`ItPok^J`eXIg8`P zcbNY9X^a>BAaYx0g*!B_O6OpO#z~y|87o|I>6x)YfQIxF8ZXWw-A7}J?x#Wb=R%6M zPWN|f9+%ER_Xe#sjP56m`5)b59=Exkbl#7wC;i*fk$Tb}pvnKpdeZT+Z86Esnm49% zFvq!|0 z+)s={oGz}edVkmJ)MAVibPD8{3eP2a-QBdh9fN&9qfg8DcRK;HS_&Z|Fd}-2 zAlCtbKtCw$Y)tPIwDW`Zxe7|aPlsQ6T;B2g@(g&eO@2A||3`kgb9CpS9d-^T3;U+k zArQL0)d&F*=)%UrM)leA7_M?nWp;`#Um90tPPrs=QYr;(?o~H4kIAGY3fYt7dzf&8 zNKS{#)h6$yolqd?_Ng+|dd#v6VnQ@AFmowM!hHptYkHNl=oQj4ZG{ z*qz6oc&t03br)fy;lgCr@r=(|*Oh$i+PesyIiz-nKqCw3B^q|N7GkV0BHVMUoor)hz$M*Owm9VyQ|7H2bRL7fBgt(-=a(2h0G(t8opXeZ zC@2(&fF?bt*AE*O+sg+LEX-L<04qCVd_s5Rbrf_YWi#Qy(5&+q)av1dSgc;nV{+T@Kj(5oV#h^eqU z{_A;T?!eaQ!~wAr0VF1m|8ePrpSIK2Yje-0iCd|o~x`1v2r-X8$z1?JzWmq+p}j@UZA`4TMk77#a1y}%fh6Ne28 zaCBJ4fsCEirgUSCX;gn^Iv^??0p6*!3^LiEHo&lhvVRq=Y{W9tWc%eXGD2Ua#>doRz7xt^@i61Erje&cZ0Fm)N!{oKPOpobtTEqg*daJ=2po$ z$@pAl9cjmprVFEy5{$HKFc4r^+dqU+U)M1eZaRjc<;ZqFQq_X~3)O!A? zL13g^1O%p2$7m_71KYkK9A4O%3oyia09ZVg=O&lMd4`9B#T_h@G(Q&riPHcAt7sNB zF2l#zI}Qc48z2F&YYqR2?Ztmq=fr<2eY~SzJNwwDllCzrjsF9l6Ya2$R%m=(-*(b? zFU;!vL}>gD$l-R$xIQorJEM$ig~or=yPbW!=(5h)$B;C>4vJ#iH2!2lJ866*Ot_y2 zjsHeyFaDvt{Fl-A>%H39$0;zqI%6M0(s(0g7TTuqE%EK7ahl-%iO~4#J==?a7+ReX z|MJvSc{}zj##-R6!j>alT~kvrB~lMJ0$18Xzn>D<`uicnTYtYEUYpj+|79EBFVM}8 zJ)zq-Xjtpz?}w_{TKzZb=24jPFHCLy`*Gm**2?dZqQC#E5i8FVp!(N{V|(D@-c7Sl z{IA8kzxcX^eQKJ0H;!ht!hBZ_+augN3nW>%ci*;B-!vZzTejtp4}C4)J>vsi%Xc$j zp@(bBV0g5{y}QRp4!(VI*zP@Sdk=UE)3L=ijC-kZ6ArstBTpM^rb#upGie{6@wAW6 zK-$NL&+Lr~n%g>$!d81oO8h+sq7mtuYqHL-qfK$tw;>~OV4C)Jt^cjM3(SGlwXh_y z0Z611aXx(t(}LH*eTX&AZ>jH$BsnaUl#;=?jk`j-Ikz!asN*(yMmq1$)nlDaUcp>P zR_zsJ{Au%)Yp}h~MdgzN<|&gUxd%15J393Ge(F#UY5sxg$>>iE_2-;`_b>Y1tBqaJ zqsi1GwogbT`2DdMrxM`W zPfwTl->SdravJRpNl%BF2kb1-)2;i0=;>w1qab>k<9n~Z5Zig_>34gB>FFrsl^-vU z_}{7@#hfl)LhnN)-v zuzg4M@)r8${(bZB3$Rv$Nh_MXah~*QI~56LRg$kzcSN&}B~!a0nK1Y!yyEBZ6d69mXf`MNmy zYp6xVEBP)(yVV_Vl_M$-vh4uQAh|>=&NA53uoqEpioe3PLkJ;?nQB$6Mse+7LoxPB z63jbA?{*tf%-Qd(+Q)PmQQl61BC;v%=5nEBo6jpG}uJ<>9)o~pJBB$$B7_{l?(Bdg~66@l5Ru7(Dt36kr z;^}W_`P}diQ@)P@aJm-LTp_NXz&B3UziHnsCnFutZn98ub!zRItK}c5)e}t?Gv2$% zdc@3Pszf`KA+FDeeOLQsCfF0ynNa;}3^a$R-rUrL9e8)71_Vgz-#9By;iCfVnwnUU zMV}4ve>SG&XM2tx7&4X0Ia^nfH*C8~lXEk(`JiMu`fE1S)FiV!vC-@jN4YO$Yc9nE znrmd|Ugy&+X}W|U(@gO%FxqnC#7*7Nc}mV#t1#EAO+V6+&-qHe7rXZwu`O4EPMb~pPHxigq~Wmy9}X3ava}m94gjKkb|iM!ajZaOQ@T(gv;aTU1!4O zUhrglaG3!|W8}DuMehG1TxPb9FN@(%Z;8t&&X;s18t2O=aaZ6Z#(V&Gj4@^0_!tw@ z{o~r=%z>OUabQ~OtZ9PCZx1>bKr}~=&dZRy6QFZXq`cWqd~N_QbTWLthiQxU;PZi` z_TaMsxjO|u^}XBW{KgGN*VIwkSnrFjJ;U_k6{!ZH#N7QmFE6--U2sCZ8XhiM)G5ie zl6(xSIo5+kZLTQXm9e|Y$u@a%ocaK0gl>=*zS+I%+ut{NZaI-NViJCW|tZd`6f z?>ZAM?_*BD$o0VEuuCGxQepl@j?N|+k(~gY z5$X=o1K3Vr#`^?DQ8nixsGK zB2$B*URpcK>Dxi&?1pXS18Vd3@E9oPI0O7Eh;p9i=wo(8F|Wl$oOA|&Ap9AglVr6U z7ipddd=ETA{Tg2Ft9s8{UL&sC4$Tm%d*pT3L)S-_+f#R6^qbp+%{rc`wzKkCZB^c) z-(l;%fK7I^qvIb!r*5_5q#Gwqm*k@$L{ssK6k2&Fl&*tbj#-QZoG&okUL@a79ycsd zUO6g#e7EIuBv;-sNwHwoGcUocOvI57Sm3QpKSusFm!(m?6&=PIIMxq1B8f zb9q?cHysnfaOeHSsC)EK_t$}jW?mBfd9M3EA&;Eq)pPuz^gz*I`0^Y{a2KrZ%UuQJ zBiQe{pImnySHu*(4ptAAFw8(8O-o`v!<4gumv_+K$neq)LvF|7<$BcZ8^q5tUXCE> z=!eA%xrK>egpEcVeLGwzS&IanZG_TdJYl2AbiC`fd~RFpQv&xo&~!PmPl2;l{`ooP zaXS`IT~T=$JTVQL@y~hWa|_ErWf3!wh&cry>e{oxKpOvr=A#b9*V~N|Wp$SEMQ8s7{*!)GE~X&T=hE?A?O3)Y`qsk*t%eihpw9)Yhx-&GOIRfb zv~jxS-hGzJz3eQN`vD~R*?_|xyxe7cHZIEX3+HAYlX;^we=UupHf1dh^){MkQpBVw zN=&VkU2D&getOYQH)j);wHHAgaQ7rHg1(^7tx&ps{(tG~c4*W8ZG8=tjdV}r8(%}LaU#>-w?g62 z7*Z&G5f5NW(t3|9cq66}6N)7do79WbSxSQ7;X51!KYOycv| z^n&KIKmL#zOCLp`60jOCMvb10T=A!f#WUK1=&Zt~6f^Z_2AdZ@Zy#*>qQQ(6FlSEoO1Tpw+}ks!Y9yS(1CsslCL@lK3239v~x!A z8FZ|D@HzNhhr*|Y973#-EcUBZd%l1noXj6}Hii=0{92omIHM^BiooEyq*z0qTq)wn zYiFZz*&wT2X_fa&l}%lohp$9HN`+O9c?{pgwwDU9fA6@B^}K!$lfKayBqF@0_TZwOS=dg zE7P`DZArkP4D`lXfHzy_;pk_UkDlNFDafu}^3IlHdTPEuwPH&F{2VOrIDhINl>B8Z z?E-(=LwZ^tf7&`d?Gzfu>k-!70`*8w|1==|XGq^t&{L~zPr#eZfG=JSNKXz(e>@;P zj!Me!rIkd!AieG{aG)ozd&#YO+IuW*68f{`dOfWgX&?^S2*DN&rd}A&WV2};QqmY zdso2y>VW&(0`39B}Z=7R4FteI>b%DA$6?)VKG;Fl_YNW4zIxXlDH0J*#8 z2BW#8mSEmna{dZ1$04wQ`EGT79RoNfGyv+Lxe97EY!8aXq_&1DXaI@?aCfOipZI|r zrZ_&==G!w3TYkk(If^5MGjM`7j=e2jVT1a0NGN#-%Ue9iS4xg`o+-}UWUt2zs}6nqHfjMYApO}@?)woo{nuSrQpp;oL1Oh=KVC(_oK8GFg6)WNhrqCLy0j{s16(!9pDbq?Y`CL zL*~pCHtu-Am{wXL-2E&YeOJVpGuNbIxhf8p@BJ@CH-e<)UzkMsIP#QiXL%-LViOAy zY&54TAB2js3J=(|R6PWlZkvA$GegrP*-3n010T`e(D_gXp$n2K7_Yy|DvGoB$Ntik zPaOd|@M&wY-kfAl3^A8A`U`J$_EO2=@>m(Ok#n}qLAe)={V1Lf^g&~CA54uCd}k8O z7vr>ZjKy@Ke7ZPSoYV2E3N#))eH+<_COPSI$b0q&LzcfA-p+Vii_a#i7{q-dP>>H?Xhr6d7_LN zBr4NMVL*f?ZB!wz;`@b*?KsMm^@Wyc5)-2*zD+qa#SC3JVV!@Bbp`tgHSfwLo++#= zX6lMfhV(>Ns%_{>u5#{WHn~duEBt9zxvOMM!mo{Wr>oYT%RTY7>;`m4@Oq-nMg;EM zK)qN@o83ZglIN}63Q)LiP>J)b)ECu;O#q^gpkGopHvX71%Dw_E6NT6N`yD9Vsm07Q zm@DrBQmpa-b?a-)PvyuezCGPwpXj`O)JVs8w-p=((hfng}59&3qUTHum!C#C{-5vqKMm^jRTkUP{gO`8jY_v zp=j>(W_3}zA|75AC0AUR)p&V62w4JQQI-^3^Qe!3Us z2{t7UE6*(3@Z1&818j;#!1GPGKOfC36a(Ha%1u8&!Wgs z%iHFBhL)h6EMEPk!7j+NJ;=OGUAY%~2hB__UVWS;e!~(ASYnD?Bdy&*@R&Pmc1XXn zpUT^J*M4|+Yt-SrpuWT4EyHT+KzLvOiwNM|ksxXM*>I-|Fx#IoM(F{v&Ln4up60q6pxfwkrg@`?JK(1n0A z2zXz{63-sI`58+v1`1);6eZbQ^OC1CbAYXODTLM`Su#GcxfWLB$zPev7S>tiW4Nf2 z{2nfJ+X&~aJyu9CcoNK6!(TlX!w_PsY1<$(G31WVk0S4|6z$2u*4KPsJu|FvC6YB z*Sj>;Dz8k>ljmnz<&VjV>R6R3Vg;li6VN4mX6`dXo-S6 ziONd;N;eVEQi?`PQ#dX0If)?ZaNmQX)bF7I!$-GZ>8WPKRMec9ZUQl7AZz5*bQOZL zBB!QgzSxpkdjY9KxGSPa^-8f7QqIFq$nR}}&3;*Ol^%nMCCsQmSBt2} zF3SrL%bSq90<|ox#XmZ|@E--jn$p9_YICh#Z*%26ZFc>(5szvd%mWFID&mF`kg(WL zW3*pPayStJ9J?SYDrK|$p~>q`gN059_?V>ZD#x{@-lA)z?C+LM^}Gjuv!74hgfD4D zthww0&v;+Hi_n=2uP2RO|HYS@q!r9ws-OM7$-51qYF-Q$W#rJ}mDVA-cvVVKl%pqo znD3W|#rEFt6s=i3It`cE6Xe+?Jhd-Nr6E#Q7%d>wW#Be+cI^(L6%vTz4Rhyo zu%Q{TRBSt==Eqr;lAtXzMQqN(3edDAz1mVoqbUB5;lB|SrjNDG3Hb>2;A8C{cLvBu ze3ltJQmRW~KGI+#H!^d*!e_1@W0pA|ZuY#csUM9jkq^IfQND=yn7$FcZkvY zh&^T{%+~6wX-U6G$2^S70kVG2ROYC|zl#53`1dOoLe`}VRBbHSRvXY)a-3umy=9PJ zq$;d=W-I;ZohB0g7mte-U~1T zpbOM=8WrZ8@{FboFZq%YJIbUXf2+RwoGvPRBPC^$E-RlydIYlaGM^;|gRbLcrBybVg;#cJQv%k4VcWUu88Zb) z_e~WPI1k78e9{e-F^+*0ygRI+GRodZ+60L}f5lRE-7*0yA|%?Sp8nQ&j*bbMUO@bD zZ<|YuqoFC<>PnFGNrLd{&8Fq95xFgnXa$=*RFqYV@QND)CDhrx(oY^El zh0!pk^mF?pQ8B?N8M#CGgeTD$rxcr-i2_T4yO!L2yaF(Mb zm(l$KZm~1=*c2<&PZWUxItn2RsgAzt?ORa|l(cB!m2}AqOFTMHnVhsG4j{pHba!Fe z2l3E{Mfs#M>7a98l&SdCXi>17eBmT%cG0GC?IZE;1CPJ)C7>phl4-6?s>7xk-Auyk z)y|4KPqH%UDRJBzdcyBLf--3vCCubGcA}0v96eIr+lKibn=4wG_`(Yx+Al2qTypi; zL~Ri)Z^$aP^UcWYZNFG`z2pPaqrXA>2aDzDR>cIxK6+CEa(iOgcDJRUv(GXPU?Iiv zZ_RS8a#daN3Er-~&dNH^@PKw9;rE_?TDz#_NZ5%vznySZL}$Ob^b*t|%GJV4Zz%n+ z?mD|pxUVv!!jk=!S^iphxS~fbHK6ieQO=!kzC`yp;kge9n30J#l{DBBO_}M~Pk8@} zzIK1~Oq18tP!k8w2_o8Tu3@AJM%!G;85Qn3(FKtRv)H0Ylq<%OgkPimTKq=YyIQi3 zL3fWu-OKXi8nJqEy3zSrlvp!)6uB>6FgmbeXs?&f`a{0eTFKspPIhs17v&04 z=mVZBJ%d=O(c0`O1QQ8(q((kjfy*O`Jay{_I2Gkf(`1EwG;~I)jd< zGHJ?=Girs#sHAw>Fgc&BT3Fb`)to ztfnM|HjypFM$nrI@KXaz^iy0nry~^)V~^p1E&9SkW&sYP!iF_y7@o!#;>oN?#ke=o zax0N7{KAvDke;^Ef-gKtpW+Eu+cAF4FTna+JYQ4DuQO?Z6`pUno?qwH@#}*3_;pdT zz}_z&$*+a9oC^8vQ~0%r7E+SA^{Pp|7x_R`vkS%%Bzpipm;;&J^NUx6ty{>eRpx0FOFn04eL(S57R6Uw-7VO=+#F0u5DTDnbG_Z4h* zl#|cWpVHE=5!M~z=`&e6$swxu1^|(#&qMl>rIfZnSode1wusW^Qrco+-6K4$kkWD~ z%`U7fDX?LX*qXzW3Agz)uf*a_*4(SEikEakiIl{JML6>7F$eqvL zWA1)gH_XxtchaWExLF?UtURoUG=!{@WI^2gA;2YUq>&`b=IV-(q(CgKv`gSr$tAGC z1Or&LSw2P^ySXs1NDoS~{q24o?U5)i1#!Qbv7Kcp9j$e#woL z2I{+vr-AzFms~|@puV9z4b)e^WE`b|`g&2?11ZI*fl(h{f_W|hVV5VtM}HhU`3rWt|~-9Rp9i) z6o#%nzH%Qv>4mQGYDyiN1qwT5leN*u)wKYICC(&Bf)1fP?<3VGA0Zv0n&}Xep+k%a z&>@I{0(FRLrbAR4?bGoEbOw zLR_e+5d68)GmsS;b^M={Kj5AGh9p0pau{ua^KLygiJW(&Jp5R58l6-n`AIfQ^AY;P z5}VsU$6DAwFnTmOT=@{`SD?N2*gr64u+=r((IqV;ub31cy9k>z^aHck$Tlv zT?36=Gk-Fhn?L(hrHY$B7WrFc@aQkPn z&;CII**}wg_74)m+CLbwbo-}TKIXT7VDxBUdh|hb0QOHNnIEt=0!Jgv3|R1)ZT{Yj z0}^Z?>+!E_a-DLu&j{MbjUa#HkU&NdZyXsxNbnm$dzW5D70HzntRQ(m4A1B~n9a-( zvSuHV{L;;D2$_3)Oh~aBm_J$%>L0*>OHvFAxtm!+o|RY*B*G582IDif z!2Hl^5c?)tBEc18`bZ?X zeuAbCTSFa*?bF!8_UQ+MM?=~0`-wL#uq`9EeXMW^NwQ}9OoKA5**+3(gKQtG&-VEU zQ&-_^pBvyQ`5|qe{9@Q0-1gZ@n_l3F+di8+lkHQ(Z68Mm**?%CL)bo5y6pqwCWP%% zsoOqKQbX82+y7_#oVo484g?OeeU`Oi`%DC<2G~9|X1S4UpJ8PCoTrY5!K3kY-aS6s zhY@+iR*x4}4;7m?e;*%exY>gNM|_CV%FOr8cJx=2l)z3no2_AM2eQLO6)FnPFQz|Edu%^-x`^AWRqUT(wg zc@V~qMyAi-rP)2u7@FBVo?k&@fWj~g`UO`QCZ!w2nn}zv3L_;zVYoVu87;cPK#sT& z3Ik6DKii__n6^36^%gh6>xAwij2XZ;&W{@R}zvQQTJ4$2*YbEoL$+Sz_>X+-c2ZYJ0>{$VYH& zORIfdUaj}_!1EFIb-{fR^!3PNA^LidCH`oAl@X%B@%rg+BkXHDtU1D~)M_}-$wxzU zR%MC2vl0s*J>7U7qVdzAO?mk8PSn(X6!avb6hkwdgn}4RcJNhfu=c6&L%$I03=NspQ>oKQ~ zP_W>zFt%Lmx6cLw)VXjILYp88AR(Ak$gAK-0H|+16$w0F`*jHVd4VN%1U$p^uX)Ev zt|7KOiWbJr+pd$&*55?d(~mU?*gB`Y^>B!uzRnUmqNfq_Nnl^?m3m+IJrh}93xJw7 zrM(I#Sqo|Z7E9z^JtLWL8aTbHLht8iPe<0z+ku!i`)LT(PY+yQx-j^m`}y29y`SEv zBJ1Y}jKOV7`2nm?SYsI&h!hpj(KD5L8cuyaS;)3zY5s|f_vItXaw9@p;1reCGD8E`EE5RAbj0lEC0vp9-!{I z9d(~%bz>jWbBl(3AXj-tpk6Hz%TqCD6H_#-+S410yp6Ya!@fcvL0j-dWmITw@hz%v zt3lz%Jm-Y%uK~l&#TS#y@lQsE@uyu8Q1%6IrM2MT-YoHqIXDdeIwySkYPh~#@wjk?)NBP_T6AtKOY8_q9HxKGkrpV2k8aiZcJkwq^>ox7k@R%#y&-x!g(Y@GPfu&i zG5GpA>#@lC`i0ilRuxhE`Vd{6%M#C+V#D^+IbqC}a5TI6(a3t25J~SIf(xt#$*yII zXWYBfpx5!6b$WgHk;r;EvNQszvjHl2i(Wp)63@7ot>Ez1P2q63`PY&4?#XqLaN~X@ zME720i5r-4WNMjem)9*(T1FRzWHr=P(U)&h|SSYk)?v=vBMrhH*tH?|>u%ms(z28A37wpVcJ?jEj&k%u+1N~adlbqy zI{uAU!p81t`YtrQ1WDfIUbckqXT@mOMhB137MxgubjT_<%H7p-f7Rq&PgAQhw$fZn z!K=r-2DyiN9|)4G$Dx(taOLe;!O9abts{3+Uqo!;dX#2vwX|?$74x!i+PRG2c>(*j zQ<>LmWgY|Jx7I>U7KP|@DleD!*~J2O;c7h(5f8_NN+XV4aP-0U_IKQe#Zx$qsf#-1 zHuMR-xV_C9b-3>!7m!OzvMExMOTxZd+a)C*`}az5>P?szfaMdo`8lnd4x2v*6EW?{ zKfj&%*R;$pM`3D1TdaV!3hXv8E!@4HH~30RAh=&E+;`#9^>XyR_p!ZNH}$vw2ednf z8OVB^NZW_z!2xLQ4KzQso})Qd&1EGAVTR)q<$b#h z<>9&#HX2=*(p4{8XB)jWXeJ|n_e+o`C_uJC zc`ZHDcJ5d*NwMeJ0i;_n?}(E^@={$>Q?Xf-iZx6Lk`h1S(rBy+#-{c0Z{C9*AbNaDvx0G%-sxD^*&f3 zJpfjyd3vfJUiG-u;Du$)C_{sn3O}P4jjIDF(1_`%H7`jWPVjQ>$Um+A6Vp))(mB&e zTw|kBm1eBzxTxnA69WVie;|3lwSpO-#DUby?Co|ex~Wx{&=+zZsLxucF7!XlRA>4h z=Bc^4lv05_ z0u&IaP6Ysi@)13S$X9xT!8HA}U>Zn(I(?Z?s|p&!KcO!1@FmfPV9KI5Iz@pMK4GJ~ z2H7O)o{WzPvOW9{Gu2bK_}VQc| zLB(+r9jlUv)0^V2#!Jb$%d1X@9|wv|Oh$!g_Lf=@$7T{_>MZ!KHb2d5Xte&C^vO%74%#5`EWp|?m+A0 z_-j~szD`|(d}!q-i_odRQKxd)hYoaVB=6K1B=|bj1eQSdzazVJa}5DZimr06fcg-k z8?7d>KGK@@1lCb+;{79H4RZY7?*t?pR`v7rwrz;b~4P%K)oPHkC=_RLg^7S@5aC+(Y~4Q zL35xubP~m*)LPc&dssqt{K4PF7!W_I#NKrW`VLL8hjT@O!4azpn0=63Px0^G2Qz>~ zUxkmnb#0Y*fOHl){v4D@Xz8vFBb^gqCvSD2)=1-n&VNTsdG3+wx8+m|QJj6S9RD`b z0qK7bQ=$poXgtDoegU4t@kk3=xoJ4jii?W!(aPPdnwGROAGsK<+>9zi(aNoGjLGri zDVv{G#v?OmWzRyLR?_&_pp`zn2j{RJXteUtamE)I87jH$LU&`@?c+a}L4DteCpC7;(#b~x1e--8Mi?*wf z554_h0eX8GNr4IMLy`h1$O(LnVv zz7Xha17#s!H|x6`zil0=htT<&_-l|_g^3BR+Z?Ma2&<1G6YKQTU_W4WK>$|&fQHNQ zMU=ze-y-Bgf8(gX*xUGB^(OWqVf8Ai@PK+PF|sc2&ij^O_0Ww-yZHky+dt%zPM;w= zO^L^B9wojK6{ty25nQo**MfpEe#PK4#YFYxB2)=9c0+5U@ZRIbITV3{MS~)jL-*0Q zfKyNP0?e~HpqEY>RNJ9!2I^EBnT3dhk*^lbzpfXun!b`9GSd41niRqh8e;8m}rJE`4HBT z;)IZ7MDs(T?~x}Pn2o0X=3LUXb72G-0W7SIry+plqqQRT(KaPE7ihJmRl@Ot{e}A( z)3!T6Kb29~k@qMFrU%<7_|DirWA*-8a6L)TXFn)|4`?9>^wrJK5hNmJIkhIKDs zoR4zMZiqcl9%C>%aDV`BtP)>t#Xx8(`WhEJHF=go%Eh^C2T0+i?REFJjPLFDZi`#bm#vTsmzH zE+7J!0kQW`Qg*$4pp=zi$1d*g&`|Z=Jnx{{-@|i5%{CFQNT7o@&%SLz z6Nk9pD}}X0^LvSL-0Ag%R(u!=W4&Sa7;~T1s{4Q}5Nb4l&$m?il1MYaD?zq@E54n# zTKZmE&A*#l)DioRyzMN1Ys>O&v?qEcojjF9yKN=8kE2XoM(`LVU9Xgs72vQ#QuaRk zFd%o?Y9KTKm-V;#a4BVf=ztxi1p>6H-39uFbbnA_THrnHq?0PSM6fcVv2l|OEeRiy z2g>HMCItE+0>2BqZ>x?_dD~O3UVif{(>K5+71Un&05umKh|5#f&cxyjfVEmoGT>N0 zar1O0i|W)@X0h=Y4kfa9(r4j!K}s^Vz}tzPKG^0}6N|&E2|>E>)Ej`BmOizhJfkDX z(=Bu!j3t?L9s&r-0hCx1woo7PAgCY^se6#S>Sxz$>VG3OAX!Nv0bU_f=ufK|B)dUV-x|U5ueVe+%nUbrsEKB3uLB2wN0l~X6z4=lxvMPxdx*(IeZ_( z8|e7Z|ElybH&cMd)B;@tp$)cN# zM4MH~jZ?pbCDKBI;GB-B+t@i7$=W#?TK@y%3^5wk!yPBdU#Zh!sbqYPE-jQ4XE8co zkdsC*#;xqI6a%Vi9n}iET)WHn+!OI z1}Y_;qCp$*=mY5q7)=qtN6*r{FZ#KMa3_hIcA;4`JLFbtF~5VO5DUy%*^aK*#_1&W z%b9(V;}V;a6IEcz%CwKzl0eN>6zYswnc`I|rV(m|Qa5EbyIwmFFFe~t+3S85DK=$n z4%Sv(R_b*?hix}=zt5OTzVp@)Hfnj%X%1k2Gc_dqC{|AN-8X;Z!vV<8YxDESjm08t>6 z5PqfXT|&vDxM5@reF~c_-Hz~hQRrx@pHhBJ_SD*=iy%YL%#;78HM5kr z`?Wfh35K@Gf3L?K)8(Pl<;iZE#4W-|OY5L$__e_ozX(Wm45v8-g?)~uE#OU~;{E%c zVB6vXXI7456y(H;D93QP9%d#J|J0GJ8xJoi_8%iAdInT#abXYKYR@0lmDiz{vA-rD zL6AwB)qv{3U+)soW?IURo6A;#%M=NUD7J{QDaFjxP^1)kHrbS?X%VayG9&kDE_AX{ zg@mo*Z1SlL9BoxoFfnWVN=Jirt(VZT)CK`ym3QQ&?GQH7sZ0F~X}icPQo+3e_iuplu8tSH4Cmj$V-phmOT@7lYnk6;Y* z#Hv>4tssHxDaRISl~vxODl~p7%F}oRz`fN4SuwXcj!QDA#HN%|viLf>N_|D3&SmPX zt9($Mho)GSHAeRb$iS-vVLgbEgMr;X%cA6g!533W(C@dzBp8xOw$(tkp&fB#iK5N1 zn@GG18!OOp?8wF%hEmZu8>T-zc^tmqpbm`U=&ySotL`o8pL(>n!B7G()Dvi;)(y2U zT0ovD7t(}{rNy`)Hb^M>3vO(3DNXmwwa$ud*mOvlia~b2v&rGWF_aIk!y9EHOP_-D zUCtAB$0(#zC{%EIfumo6^R+vWp6Tdbzz&Zq#)FnN+R?i}bT-l}bJm|}^CkPjJo(?2 zk_JaAoj5;}sV+9!G)&VjZGeTOdTqR~v@H~f#r-{e4&r7&+0Yz{9AWBea7DzBd`2t% z_b5-|s3m-xvqlv<8bqeRNXmmx!di1fm0Zp;@r4 z{dCRZDWGvr^TcvW{NG=z5MVFd`7xUOga?GV;Iu-sd;+7r zaOZbuJy?r0pkuf-D+`UHyhoXyppINhEjR{nI1<#CFi6xGuzRGzO)*W(VM7u>mSrN_ z2${2y3m)&10y4G(;^@l__SkYDi0f;k!i78g`=Hq!JjVY z_M};!dB6^;7y^ixv7MR=8wp{Z69o84$u$Xxz<#LTO0w#Ka{(W->UJZG`Z*L>n)j}k z=(=02W7oZEExW!EV6Ws1meS617-t#xr3hub;?XAMD7lo@nLL)P=U0Vo$1W&PAj*w>nxeE@WbNRpe>d-DN83L$zNC|B2$3ME?* z7{`LK>cJApM9I!FQsNUp@o*4Z>Ts>a6|dRzVO%Tltl|nk9dQy1ZEIA!5u3<(>D)1| zT`@;3Y`}oM%)m+8FuWT!KM(hoT52I(0`71|(u2tenip;dU7J!EOWt5Rz(8|7Z~UUZy0g_hBfKl+iWF2p#hKM0#})Z&feT znuSs_CG+GN$tcz;ACS`Ope{hS=$T+ntJKuEoemF(#0GU1HSFN^;fN&^1c#FIjU?3h zJ67;stFs1bC6sd<{bW%4v$|vdh`Ob0Rk&*<3_jSX(;$>Hv1K^P*S>NMMc+o(IN$@! z%~W3lSm1$5C$+z?ybtfXNAF|r($#11&gPmA2SGJ1sAnn8R9Twpt|0v!JzC4Y4O{e$ z{56VhUTwNMiM`8NM8#9t_($3EQ{4;L0FKdnf!_}O*P_-5`t(^bqA!WYl7qJ-PJn2W z{CQr$m80_}qbbN5^1 z6H3P80cu{RO(^9X*gA`%a)i?Bcydw9T%j}%_Yj!R_9dfaxB3lyPc}x&Ldiw+N>-&b zkF@`!P;x$f<;=_$N)mA=zKS1^;)F~45Ge{a+CuFubr)0j9Q~0(d(dH%J<{GpM*|4Q z-dFVQ0FBM3FPt?=w(Q2+->~9TS=66~`iYvqB>x)oiaC0q0Y1y73dKW)nLRAAO*mHSfxCh#xJ zE3j}(f|ynd#(^0I-gO)S(GO%@li#8SdZ-$t$6^m@4?5v#hREMA55(_7j#`P0)huxHkx3@9Vm>6on7T1f{1JKB8(c2JQtDkO|WdCJdav4h$Lw_3A6BHHTRRhlwm@ z8wzC~U<8%OA3R0A%bQBCkdQB5-4hoxto<0ZD_At6fqVv+p_T$CyZ|}0(|-)eEjtx# zlVwl2(GdejLN|<^h3ZfYu~S?ntS}LtK%w*mnm{&?S*~_Xh9>lm6-Sq#EKx2wSc_}c zHj=w)qx~E>*7S^4S1En0XNGkdE0nIIswVfu z&i20o>8GPVG<;d(qYcCxqB3=zq?9HjIRidh@P_(3E8=tZqUdqji!ENf^;Q-P!SHX2 za-LYT1SVVJwmCqvqR^M(rc(sc6U@sY?-d@X6kW<5v;_5vyiKB9N(rvX=X%Zs2#k(y z)P2|Fex7(d#yYz4$D~{(W(|bV^=O`TOJUKw%Qjs$_!&u#LAUoI?s9aj0S%i=7Nf*~ zt>Z}Ddj-h_>~RdmREM>?8Hq?U1IElzLNgJM9PR_*X|&~4HP1n!~64G^ezj8 zV84>cEffARjG%GO6Gj{u4N}QeXR``z+3D&u-1*uuiIQFR?9?f)mpQ^~Vp0g`oN8SQ zvNPRFAO@I=-0mL=-=WFApXi^kaliA(XnTL>5hG$en=Y~UWR8R?=7fdF4phd;Z;N^O zOg4ICa>oX93aNi*lQPUBlu7cId4!->2G6Y$2uVgI1&-@DKl~5`6ptN>EuEzaC>+); zf9;=9IHWF{!`xCfW#KlQz#%FQqXm|T(;Fi=?L_C`T^#hLB=+dZ$I2>DJiHm&Fl)&g zHObMC2j66)6n!dB89T}9ib=tALN6L(EpQ%UG24zLr+c*hg|xl)Tbw5@u|FlHof1lD z=WljH8`l@vNC-msRjSRJ^8TSp&ZI|%qk)#7IaH#+j-h&lvV^1r?eM& zn%DgZZp3X!HMnU%JH5Q;wDQP3rI)vul?M$+na;`@#maKrtUo8QZyeX@`FpbW_DS^K z1J^QdDXp`>iobL{7j$SmI}p;sTm23%1vBORc{^Hw_t9ecx2E!H4}=UaCkpvIQDZ7# zKMx?Ly@L#uPP@A`8G6oNC19s-v=|m#l}(;P;TeQOn;gYl5^7EsGk0S)7!kJJJlf># z*`Xu=vxC^QGfIaLK|u8h2dvqj!7nlK6lRo+%O_%nSzW+!ahVOin=K}Q6sM?=dQz9k zs!XGFNx6r_HQp%s)74k_o8D*)gL3%U=y4%i)>2rpw$j935{~(}77$7Iwb?C{K95Fi zK`S9wr^Pui==D%(Uw)weGRe6zE?Ouh7phIp$iVKF8^_+RUNWx9yBV8VVmrvMmj437 zd?5}Nvfn6S4$SF|UV>A6s7p#Q`zo4sTK(7Mth+x`il)o&VsgibvF^G!Xx4nBQio$A z6vAVS_N@jEcp`f87X$s!0FW1x`hZEaIdkW<45>-MJGysM(=CXpTU`hE-?%PuY`C0mc?!2O#~R8iD;b2TCU;Pj&L@b zQDkUNrg-2coBS2onrVc*IjSAhg*lc@9Dm1_!$sb6$=ZKK1LF`d-YO~k!zBk12@7jI zog6eKa?nsjVzM}=3X!&-w$hw7+mOoJa16u{*oF(K4bFeX_!>}udJTY*J8(J15MO}G zG*WpH{^E+i4SE9$P$`_DP4a8~pm9wd4yBXLt>IHP7(t~(?`zc+CTc0vGgujz@M$)t zNs2g@#>i?h#wc%h^`?6qqO8QjJ8vb)>UpeIJxIU7eW`C1V_cQ*E3-eprf zsHbXer5Tcc6CKv*Jkd)OCRJ34vboZKNLK)?eRH?F$q@_cfeIV@$7>M{8-uo`$h%!h z>I`V|a=rR{%Av%U<0UfMvD8sYb`2yHhL{-Sg`Wf1w_pwI*HU+Z} z(NGtgHA;g~v$AAgS&s#jwOlVNIfAkU=Z*XY0rR}NbVDe^cNwG4{d_e$(rOWF5RS>f_eEE{&#J88XFm?pW|CFMsIKINC(0es+`~T zTJjbK7+O1U=+Y)H(-eXz-_MBBd;|^mEC%zvz62dqde&lf!24gt(0XY4({Mhx4k+*p zMz)8M%?s}gYe20xaU1e_M zA=UbO6Zd`zQC+K+!(ji@jkvD3%Q-S5N7G{dEi$`mXfos zi(A#5JQSH~5|li+1Tu}n164|{@y_^X@R^d+LdyADuHiCvRYc`qKDSx)Ke+I*eJ(e{iT+?;fyo%T(2%KwJe_IsnC$)6-#?g$_(g^{B{iL>) z)L&1}tr&H1t|YG$U|WE4!_}?hhpxOGEFzYMdwVbNzB2K!bo?7@cEyq$tMF1i7e=M; zOI#j(00{$OlS=aF3Iwj;{#=NQ8Bf%qg5CDq{MO8G)qBq?j|8q}p-p;FJXQ%`}8zlr2rgL{0+! zF$K9a+1(4&Y0kXFG2NE6B*|e3$o{03okfnQ;z$}Pa}umrHgvpxP{r{&=i#2h1KZ)_ ze4w%{7ju5olE~j#0bn4MI{{w(bk7qMHD-pp1J2kQ3du^A--JcdU0pN=rOiLa#q3Q- zn3#PBoS=%?K)J!Q8uL;~Quf!&M04g+*8bcCHC}5FMzG7&zg!riJ;2vH!3}a`P-CbW zG^2)A$Zx_c2&;rz@zEtH ztEn}-ehW~vz$@9U@MvG+xTXbS-_Y{&WfzN5LjW=aV)tu^HJ1Uegv(5VD&64Z+!}`D zj05tU49n_Mq;fO-4)iA8sWSXFK%Y^6j-gLBxXF&!QEUo8@kp&{G{v}YM2Lokz;L#X zVb&;((9-2M3E^OE=CKy2Jsi`En`4?;@iTcmEHJ$YBfRPCW13Tl1#=Xb7D#r>nBqs0 z@3{-&)$q*h*g!uei($!UA&@xT3G(ZJV}RNdmb9qM?hnIjFnC0+a=#1g3o|f{JPwig z-w10ghi$IaH2bZGxJ{P|YAn*oD`8ri%T`ZO9{_UTOF$0Cc+9^XX37Ix8*!KHBY z%c~Dd@`qCPYE>xtC&OM3broR<3kRj_*{b6UcQuj`;evd1>RZ@CioS$#NEzg4&$^%@ zD8iO}7g@nYI9c-Q!&c`WG{>P@<#%l|j@+7_Z%acoVU4x&RJ7Gw4d17Is7;1tixshz zmdx>Sh&9B-2bspv`=#t^$4B%Hk4B>@OPN{EELdd>RO_k>sJH0NDL8A&OR= zFGcx3zq&L5rp+J&)Ps41~kB0ODz0ZU$!03G_r+4y`z-5Gp zDkzH-P+(%T-;K&w9^8OZYf9;Nq~S_bSc}2xw=d&S+G?c1JQ_VZ~YIj4GY0emgXyCEo55}vJE0$y-O zS+n;#{)Jh|0%y}WM>nf7DGI@Ij;jltN07T|^l}_=xt(%vFfM_^dxte`uNm!6mG+rpnlM} zAD~CD7Wm30e~P6N&eeBa_R1|I|C zh&_lyl#JWL;!VJ*Fqedq9jx&^)aYS4zuu6N>G<5uBKYa+1^AjFhH*FhhEM7AQ1=ZD z`o^;of(6haxdQ5vNV1TC;lgFO4Zb=IZ;&onC6ZzVV+V-i28B-xi6Hqh zpXv&bFVlQ=L%z^#Gr0Lmq(Qzsi7xr%i$XN1iI{6`vd5P8r6yrADkvB{Co86iWDKr#-K_&AkTfs%*~X@X@qR5X%531BzOiW0j9iXb*)iLf?4cw7Lp`K$?%|AK-w zAGB}1l^7VGh9eTOUO%HD4~Id@M+oKKH%yshFLWGdyRRYaN{T*$?JNfhZRHv^W?pGGPo6Sm9=WlSQ>Jm&jndyZ+09f z6no#$P&|~mb=yQTn;g?HT{<}orVWFeV|u9{(;uJ9Uq*!Kp{Rmm`aYBi?42g26)3Yh zrX^O=ZqTF$Y zNrzy}L+B7R7N15TW$(8SEsq*?@%YipyGz3BTqQ^#IXjxHVXQXFu5o-|E{_t68^<}$ zla$HW57EJ0xL>KTS=9AS>TEQI! zXjrmUu%dUGb)kL}c`6!qviOc|uZ3awDb;;d<7Q%JL+ z{$b=(^48vO*rFMM6*Cx-P@FS?R~${avvX$2GqNwDlH&br8Pez|DGG`EmBz1}{K6pA6}iYI;i zMUL3asZn+n9fv5Vc=+eBeSuk4X^79X)Z3vX?N$FXkO~C`5f}lYgC4Z_J<_6B02=L3 zVwGc3tk4?bpeB$O2G0t%RZD{!2g62*f9P{W8!40G)IT#T5Z|AR?}I>lFRDP~WLoj+ zdIPU?4N_QL#}369ieWb!bTll)8yqwUy@B|E^oGwbLf*AIh)?vx#>zd->&>TqsE?W`g0Eb(3yqVCgjp2G|QxLH2@Gc(#JlvI4-r`$8q*Ytn%$(qbsCJZ!|?Q-f)p4N!VyknM20G2xc6_!OOHD zWgb&ENW|QLu^sxp`fu!s$>=mso6iPW9ekHr27kB0Y?iO}Q)80@9!k9bE#8C5E+At; z>DdU<{20q)#7$(BsR&^l$ow zF6VuJI_)mpx`Dlau9KPJ#LOXbVR!Q;mK+3aI(xKO|HbnbuSf-4Szc>``T@FFor9ESGj^f!{xwWq zrrS|$Rk9>w3i5=MeO;VAkz7W__<|ctbK@LeNb>n0OdhI&>gKwC?uW02Uhc~aS=QLr z%SsGUmJ+-3Gq0CX6lQi0`tA{9hOv5{ybEqmIQn6Xk(ZWvyZ?hB1+d7}>66-J&92ku z9dPTPcL(!|=EID^bzTz23>06q*K_AtZ$RU6aQ@1e9CBG*Qv_Ch8jn=VP{EgLK2QWls z8c3Bve!i91Ni1$}Q7Xq)C>puDPvrD;W0<^tdg8Q-uy>tYFV;VSn)h}Bx`W9UQkr{7 zLvoVJa#DHV2exfVH4?|HO!8A(FkE;KG~Y3!w-$9(_13zg^t@8NsUs>wr5eA|9z(m- zKCDoj%BxQmHRnRDeH04_p@LvBjWh5y7Qk8IGG3X0ea`sO66TrS=}1$i#wk<2SIgm0 zCA%bAZK7((ZSAu_b0Ma359=Pibf^WE4fe&GemRA5Vf;!spd;0XHHxkhOkN<3+=x)wjhs&>7Nqg1xxV9HAH?VIz3@-Y|V7xEy5O8H~MQ6AgBPQSXJ=*0#?7W4G~$a@#~D2uCsJDX%7K;i}^ z5EL{@P}*pX25QoX?m`03$_9g1tW~kpyk6Q$WfxFUgPTZ}$5pGXwXc_IwXMFk-irip zNf45N+^c|ifoj`lT`%zliB|UepP6Sbxq*W3`@P@$@%xdTXXebznVBp+6aO;Z$zrHfdXY z{W)GKC|G|yY7vRK<+ep`{gtrFv%_PqcTD!xJl2GM`B2 z>gJKYQDzlO8Gdo}o++oFGO*PUvwN?PJ@y!B!)(E18Jhz&mk9UMwlh%~skL?AZF_{% z`vYy;B8K&V+ZK7fK+jz);H7-Tej<4slF`Ez0&X+$0y~IV;YklRv{u|^sLNf|f zKgWOJB}S3MXzt9AXyIkuz9X6W3jfGJI-m5&r#qET(8x>gs^325pu6M)51Yw^<;P*} z(#yyBGu;iBk26A-v&LSI;C^{QWQFV#%f1sBZ2O$088a@`H%qAv=&Q|JB?kaK^2IAlkWL7>2TSTrfKH$Vbd&)wFhj{RfoWUR|6 z8nX@`_l_~^*f=lSU3$ehe^@GsE{>nytHLQ$m0hw4;dPu8%q*}@mxAT|-v6g=RvOj9 z&1T91J?op2zZ%#6{v^)f|INNq#wU0&l#y_C%5Y*qsh?ZF`p0o&HoM)^JE9Fx4xW_h3=(G{0iM;<^Zb0Td2NB$eCJ!$bE$c+wsmR|;s}Y`vv_@8 z#+rJYEUG4gvwAEEX@dEV7b*rkcDPY8HGx<-SKsflzs$b20P~=Lu0HQ2wW%_`@S6{ z@x8V*I$97+69oT+NrknR{k4tYTLXoVkj11Qhq5?wr8AuyQ~`Vy>DaJy!&q=DbI79; zgRHAFB?JA=8f<5~QM-lV;!4VJi1%xk^*eQ9wI6GBe|&0x;>E@cmeBXxX?M$sMygZ{ z|KK`_{O|3Txu18(21TAl9Mbv@;pO^G6vK3=JBA`2n>o)-p%cyA@Rd-3?l7TO$nz&M z*k_nq_IJ3~3QZarD-~ICoz$jDHROsWpDAR>UuUyz4|&vSk09fzXO5XOR zf87!Ks5|`~Bgj-Gk-1PIqX-G&g9Q7azv?k5^w;J1+Vqzq{j0s~{?N|;e zDDn{cfB$!bkxa4X&GF|3v8m=B4Ld96)32we$?t>q?;ZAUP=34D8sCqpHPMaBBwGjc zC`ygs*sHM}N(+9uCvb49^K!z>a*T8R&D?>=3x4@kU|6g3%tZ9rM4MZqBZ6Q4J8-aK z_^r+fcB(luJ0XatsEiPqUv}?Pv&?BYR&j0f*@vmSSc-4QH5?!uY|gh?G=u-O!nt7#16$I|^7!!lwghCAy*}4oO|yaa`ib_cT;w6&s6U zLfH!~V0=fBy=W^CgE{_NvPhU}L*0-QWi?*(h4jY4clMfYVzOYl!w<7>r-_M-P| zF%M+S&OMwu)fzuX*+q4k-poZ^${SzZRBDt}vpSa7`I6do*NrC%4HnD#oaY3g21g8! zfz9PBuKIjQMd3LDeU2>a1<`^E*V0K2*V4A=kn%NivsYDQ&nbvCd&=A9;YG70eMve; zW^b5NGi7TuM`;f$xP8V7qHHMeO)!UM%cfIA$WK^%fN^7@NX_J`poh)hNDr5^1Hs{0 ztkxg`1y&ZvR^76&YDhOm&av?I7NGdXZ z|6P(wA4Ig5sD$0~9OPGkUApXZ#o{%(>Mw)fZIQ(bqVFP$~E3Z=Z5Z5 zGLi0TQ#lH&&p8V@iq}_gAu0XO48*^uudtAahwTWw?-8rs3KXs|PU-pqEad+pma&M#=oDj{;A9EcoIeC{~Jac*jVs}lKMh@ke!(7G^U< zm>te=4L*$F;w%IR8M7z5WQGhdLW^})`W=x~trWWCci|aQ4pao&#OyLfD{eiLLABqs zxoRCp5UriK?qt?%@pYYZmMkTqoIel&jx~qMPfkoIE9AUOB11Wg__6*A%`%H+Jz<~O z^pv9!u{CBbg&VAL))MJZw;7YV-JZCqJ#nMRPT@Salq)WCULF^zh1~ zgA(DCbElIKY}CdxxF9Rd?=;<+;#jZ`xuN$KKYnL$n{@(s(3oYI578L3DQkc(I6v|) zEL`Hq@GEq|mJU5j!o)!7A)Q->(*Rk2Wf3z!vEGrVzP6j4^;r9#1@-&FV^5}EE6h(Z z8Vz6JD8rI=I#aA7<8yY2#h&0E=T*@~F$6s)hnB1Si#YyKPo)he{AV_4*xN(r5*%KPw7biDWyMj z_{)%V(nZ**C~ulySjmy4XVDiT)Xg2?Su(I9W2Gmn;>7%lj8|=#c{@ZnC_Oa5zPmXK zi$Gt|=YhxQL@-?Rk&?5&6Z|OCe^~IN9Dh#vR{`2N`touf~Y0PP%ooCIj+=urfG zMQ_w*nQ=Zwo>*%VCQ_>OA1o$5%<|oE zTmD~xiSj#fTZ|qedO|{)4qMego^=Pi|L4SM0@lB&C^`;2rp%~c zrCQ`vcOLuVTrm4;VfHh@XWO`~| zkscyPB-6U(l|;!amTh*~!LC7p%&_OA71|w?xsfND!k$wiZzMr*1HP#j7|%T^xMxz} z1P?Z(O(p7z85vgNUrmqJw4sIK=l zddYSR?!Tu<-MJ}kwsF5HktTWIjr5h|`FSE<<&gw)qn+oBM4IFgR;cs*AQ7+fNJ1jd z;fb^)Zk}c5%9vy%lGxZlSMf2CMCsml@Of_2MmLf;DAFEJNx_jEkikKbzr@p|zN`d} zcgCZ2U6PQ%@tS0sI$J*UNhPdI9xtv0^7O|PK6(ozSj^xX!TEVfT*e4HKS&9GoDxoj zc_bx175;%lJa`Cu8ex4FLl93B{$x2n?b7aDqKM1ROMn%EdeaDrF$t1S4+bsrkuKwj zWEst$q?U2QzRJ*N7Rp5M3Y_BNK>|B{=gLUvo~_aS!b6fwzA&9{Auum6s!EWCRx5HuSH!GkbCAI5nl8+xLvSw(EM!AGI@W& zBQ~DSVApp8-$MzusOzrRkmw5*bv?ozt$Bwn>Uvs!|FNh`1T+7eTB8!k2>v~bgWGO3 zBtPuB3R3G@Zr9bK>pH$;=Y&&{WK}AZT2Hb~-=$6dv34D! z!;8*2Qnh>D!Qn;uT<2g5GH;-3`6mNuM|anLiPF`&cCH4mu1T~dHGn!$wmqq~QiFsp2gmZd=;S_LtwQck zc}GjrvQnYP^ELOMPi$R&PjYwO!}#aL9TJue^Kf%Eob3?-x~6Ps;GbwN)05PN(q0Ww zDh>%<&828C=CC7KpnZI~V|m9>Sqb;kl%_@OUsk|-3^Q6&R_q_0sMB957iGggt)#sx zsWp%mct>QdQUfo>{NmzjWjgMR>F)}zar^Z(ZmtEeuNUJHpSoB+goQ7bw}SqU-YG`# z_eW$0+sS~bmv?u(*ATu4oZSX3W? zfsnKzpR1I)srS|K@W-R(IO5~(ZaWVJT#TMUFG-P4VS&phLLgosKgS6wR! z-ttyg-HQZ#=7e*= zMOksSQ8wX7Qv5#a4`OY_SRZb^)fq>@P`B{bThGu<_+GBj)mh_Ib%V$kSSYpJny6(h zNzqH)bsxCu@)0zY=MTAd*~QU=(3JDf09cn$9BAK9SnlEd79{Q=95_A!-yVmr6Zi=- zN@Wuk5O&pFiqK2u**deUZYJND%k%C_Rnfn^=37Dv|6I6yzJ_lzs!gZwgbj)7Q*cd&h?gk-+zYJ%zn#S`me4SP2!?a=;XH| zcdG%Zcq&9Qo_cGcd|Bm1WgDZGFQMz0y^fFZ_gJ~U2p)!bd7XTnQc|-oU zvV5Tlr&EJr?!k5P0$1Ig!dVzUpZPg=b|;sPKPi57GCV!qx>Q+YDmEmpv^M{fxqT)V z6TIPb(nVli{F!u{t6p3uq6YAWs~p~R=D$yHp+2 z@2`0-P!|^Tt9URvWM=ie>^pL9_J8$XPo9^0KNgUYHILEm0UBxjj*Ok3UJ}PVFM{^9`Wwz^ikhtijJni(ZcFr#aelJ|jS@Rle z1#6k&8uI|Mj;Bbtz~zMfcfkQJBLH%N@rr8*{2g)l=>i{nM{$`+8q8I9F%wHon>fcP z`pCPHJHd)${6O6vQyk+*nx2QlF&c&Y^1@j5rT$!g#$TG`8>{=_8#9G(oT>Q6^&lV( zvl+)dl;t(|$~fx9wns6JN#qsA@iQ1lE$7+MpGZlHbKKj5bA)?HJiFiUhASOLICC;-@Qs?#oIS>v4Y9nE2Swuv*OpiuE!S-{ir&_8ogENiOJ7!D@RSrUH^9H1 z7MVUkpzQf(nD`wl0MQ+zQxN4+v5o75B(8(>Hj1q+mqbsVGm+J#qHO$}B(}IG`8wD# zSFxB?{+++(kVe)C5nvyE8*G_h`&Q*Cak)u1KOCC(=cGSh-PPc=5T@qEbK^G+P{ zJ4-WPuh|ZvoYCG>p+o)v`E_5*Tu#{E(gpI)JNCDwEYY_yG4M&o!zWV!H(P=`PHl7} zB^0%JH@EppxNhy7K;8E8k#h+wEtYr1-Pm+t6rFQ0c{trZ1PE@I&O_pa|EgAhojEM? z7dFyC~Ul&+d=bs4l1fja5j-sN(HgJYksRR9HTKT+zW=nIHZFx4Y&?p zsg3y}qlTS7BaGF;<@`kcfd{SxQo#LH;11Prf6#Eh7q}OCz+E74BQ;!=hC5B*e%%A^ z*8+E#hO5_bHwxU(dcajZo6d0#$hirC+(dpNMhXzPd5KeJgMdxYV5bP!kttx(Rt2Zz z@$PV4?5R@Qs^H|1k`+_5`C)^`_!GTLpxJ5nSW=K24+JSndoiulfwBx+K;LsfP zggc=xI5|@4QQn}w;09?pkFHns-%k14INlUvNWu!~L=c+{IF! zFmlS1ai+cJNO_m_fV)iKax~o88ty`Y^YnoGg}@!8;V#f{_uUQL$R2R29r#G^*^ZB) zjnwvDE#>iiv%p=V%lkP$5zz>w!kr*+xf*V?hC5o|9_Rt5#`j>-D2t|pJcq_$w!fIFDQ>uuG%bQu@ zPV$=f?7r>n!5l_z_q&YXmoZoUD$*mh{HZdZ**zR=XS06x-Ytooil-6ogqv%;i*L4@(T>n72M2ekLRUoF6GL)9 zfnNQZ^d(ood%nK#gv*=IeV98D%J3&Q&AfR}@i~K8+nmcgSPHTDWF7V5Vya{#V#$&= zSwhRVxa!`c3)PV*hvAX8`S6y%@2YDgUBbrQG z{3}&$G;}~?zdxD#-OnjnIpsy!f!FPk!9^iJQ*xEF%kpN!Rk1R1FJtF5pV^}a7%@FQ z`PSVUAK(D?{7>AX2X{7u3y>bkqF*z(a-dJ4r|GEt$6+cA?wLAvyqbAL#PY6Bl;_7c zpv)qLlIT!$uU9F66;U2gYiH1PvL3}^d$-%;U7-Extdu-`^;_cYYzT&382 zZ0sk`+kEV^_*Aj^*efzuYE@VM`LlReu8ntPkj{(qu@FGqe+;MaG10$-^WM6H&K$*N zlFn3oOh>o=g=nXa)>DP}SYC0W$iNS5KBjSkk9p;>xW4%qn{Kh}Qq0WrBbfxuF1s;t z>R$3fNCJZ5;plh^80hptZGGN>TMu`lLJVw|pTtkjpAQs4H!74JFb$tAt(dlVD0uhE~fDQ4*Y@?ZA;Z$foDI7< ze!%zy1Mi!)`)@vq2{({V5Dlh&*uZP9VBN)bJ9;828FQ_5@pc$g8wFFC08_49pODjx zcMb~*_MA~|D@{~CJ%ZVB*g2gaWk$%* zoI%*i!Gc_d<_LOd^V_AyF}2T%nei+hmj-?FwOHPxSd>SL_4Brm63p^TW<#zJh!Fs<2j#)EXMSKnMW>C^lcyDhhz0f&)+5^O&?*+B)Q_l%;h+_8^9Q^Y|vv|-Ax4Amr-vY18&c&JZXl#XLjh8 z4d%zH!ZJKQwZ@%YUHj}$*VBC8XTX@{jfp?&HMJZ}!yq-#qC^(GTtL-Pjvf*m)v>W zMzL(-qRFqG25)?iWP=gsMF^ni_VAi|?HW-diw>Ffe;;F;!~^vJX3W5_WM*kl_~@S=l2sB z_?LizC{L{S?1$+OrRvu=omhR!{WtPdxZMq5YK#uCKXwH5=oAZae~pU;sWkn!KTw~o zglQtoXteWV{nV~qXu9qEA9fyoK}!k|A4K&s+tyg`{!M5{tGq?>5e}D_P<$RfE1_^+6F*AvWPKkTQ`Y{!pIiOoBOZ9?TVDHr`2-EM z*Zxa3+stksYyZj{HHplU-q^1NGET@TzsY%|hOP^@)nd3B&f86>(blkSCu|-5QF1_t1Kxa3-D`;Dz5FN%aV&r$WHfp#Z=j@7z)Z!@_+8kU11j(b7Jt*{W` z@Ou&p=ba?Th=$P0vynLgWWJa&r}56v>v|#M9+Be9&pf6Fsu$T>C+q_&JurRHuD!-; z++O~DoOqv-P&n^7ei}t9XtlI_F0bd+h~zz;0<}D}OF3$tYL(J$4e6s&>=e6L*%>yTb;^dt zb=!Kc4m+`#w&u3=-$SYV_*kjJR@UZA#o@dorKUHcx?_YNd(X)azIe9SFRR{wY_F$^ z{(8oySGDYvY`6XdUkqRC;C8sdIQ;s4C7<8K4>jG&Pk7oe>q@(_qk*_XL)2-Au!6|5 zsx*Xa>2_D;+e=`@ZXsdzX)Ru`V2p}(G98*RGQ`@9!^M_yYe z{|I67KE;pq!q>75p!PXly#~ESKp#+`ox;BPj3c?ASP}MShiBmH3Nah)JZ=MGc`mY% zYv3-n-Ht#ePqn9W1BIQ2TdoQ3L=YB+FbgvICR_0Cox+!@kV&`m;a_;v?E}2 z*UyRTJ?sy%(_o6nJ#0~j+NOK*tf zwaiy9IbcxbFZ{8qPQRO1fsh6(th-sjX6GB>Ihik|6%fvNi_87KQfx^dd$uc9KJkfk z?i8Fp@ezLNWByql^Ft$89>XbKkVou1y9PM?C+`}NCEoXk#PW78P~-Mp!(0hDJtEzO zQmMIX07pjHHnthzVNIBLp-b2}Zpna#ijAf6fDI33N&g1%Z1te{+Yr>b0iMeZa9rTc zEx-+)_Pf!Ou6qsWULyMLCk_@%c8NvWY)<_qb}ABR78{P{&H+YvRJ&oG%si`jdmL^K z(s>unF>i3K@9omsh?xDas(8C}k+}}bq~S73gK_#qFgh9`=jd&0FUD-#j8x6yxLXI&@96u}j^ z3x6xHoj?9^4lDg964hx0ukB3Z%9PG|FgeT5J0j0gyJbX?+-fiK8ch~j;e}<{>${MU~}oZ#P?o-jCrs+Cw}nARN&M< z_@zS~9n9TQ?Y*gamFRp}G7ovcK01hQ-s>bxN#spP|MB9PEI{c5mLCdvr+g?6LLV}^hU+E>v-0xWIXdpyVE&a-66o8U}eb%6-WNGaDiv3 zLmtPPBVBl8uq)H=3w90gj|g^U`6mUthWIB2yIlUPuqVp8GXFXT(N*`jkWeJkRVV8U zgQ;(uFrcow8zqK8^_RpVw-UB)SrxzV7|2(5JMK}ZGvLPK!}>lL9nK8Pxof@*%1#EQ zjX{~2$-`9AxbkKh6vTkQ!PXFrKkO@Jqn_rz%3}r(_*I^`OEmx=H{ppZzQ_0w61Jrd7TS-IP0*QC}d3 z6IK!5t?pbAX$0UzYJ72?CP!}uSB1@-m(-`~2szIfM;FMg;#pas-;^7TlH--NLLdX9 z12igv`e5CfLUa&k9q?ymCWjTF^nNB|&sUsc*GNeS5pMl!Pk}i70HtQ?6 zqHIpcXFA)7ugbuO=ddQG^Mb^5Zn3AcpHt21ET4I>YQf>t!`aPV2tBXtntulv1;iRS za`?1PZ+Uwl>NQ)UhX-RxCfo@V{t9^@g$W~Xxn*l<_|z>Qb>%e9FaHNfs9P0G(eJEg ziuPr9PT%CHw0+18J=Zu{SD2L>+hI?ujgq{M&uy7uHI{8`*y3$v;dqrK^$Gj~!28T* zmF0!hECF#z%dG#!Su_7Ruwg6SCRzBBINxVY47u0-8 zy+0uSyA5QxX|QdW?U@i)hL9Kn^bbw%FtfSY$|-dCr<=`%87HR)oV%KFSKwN{bI4Vh zvGnLkh?lvwTw;@JLS!>N!!}xgAEBsikoALSaCF%j6Ia!fvtr8C*W~6-`UP<`0<6u3oYZQ?vh0tw2OB&Hv>EdX;$n@U*M!1|+)(EdYKNc-<8tQE9^FVDi1^TIf(q_p_!1(W@v z6sh{?U&eK=?iI#okoD)MSQIz}7-BvCUxe72_S^e=mB+>3REi8E7~1fLEx_|z;Dczx z)dlQZv#bkxOYr;5GovplOfF!A(Bn4D)>mw;Hc^Z+$GR zs0(U+MM6+(be@_>BaBcbuIF*O5hu`x9sYAu2{bte-S`bI2A-3qs#3WE6t3LL=MLUC z*kG7b(L7a+J_&B?=>ts&rqAJR3}B6YrL-NtYu2a99A43VY#N2dWJ zq_Z^vxPzDQHek4NT=0?tI91gS86*Y|O;4pBsPNhE5{9Q#b~1?h%S6x0z=kT{wLU`z zsl6^Y&8#eNRaT;3dfDCYkO?n8x&qdWWis3x-17-3c0Rzfs|lrx$F+RNkgJ?AoHnnB zYZ4RPMjtsCx-qLUp8r*RF>8+G)b4aFk!kpfO_o_K4gS<;_)^IgPe(h4^mwGtXF5Et z90Ro6!_2lJt2;cdCyil&&+1!J7EQ_ruEJdH*}X9Z+B2rz2LH4tc%OF#6)C=_7BtoH z>4L1+EHAn?D=4q;m~+`Dl+?$rpCH5fU)Trv%ysIJNS4f~?d%!1nMP-GGLnTotoMWS7T zV@NM8EL;E$&gz#2lho9A=t)Opr#P~MF~XR9tgFnwf!12$qCRuRFtf!LKU$Rd@pr@z zCfkW(f5#HcDy+) z%x+Vj0z%Gv0J1XJlgP=4^G^A?Qfew2y@ass=_fQXz=t??*v95lLH<-AD>dXSfpiKv z2XK*PgeM%|CL+^>TzBSf@FTbCoJF5*&X_(Gp;L*zu{il@qD$h6%@P)=B^{qrb z&xP406v`|(zBaf~GjdZ``uqW{0}vHrXz9@}&s6J-`bAZLU+*dNEvuQ;$g;ABb53mq z<13nG8X1aTNrE0DYXsY1s|D7M_Snoh{XJ<}_7Lk)VrcNG`a6U6aH=%)B2k&jNyC@< zfsKF{kZg6`C*wQz5W*tG^?CTOFoB-X4GCF~u-<^5*y@rGpeN;e6)g#_0nvxZJGbdo zto<3@5S{|tRa~yOA4iFlE$Fd5xcEYQdtiT`m-trvdv|ja>hCyb)jYj^b?Ud9m2FUA zk9ANTD_dL8!Ea7sR{0;<2Xl<{ z0JN@4{<&Q;PYh1nV4)xyt`RuLj=zTZHsWK>$M_3ldqi3lnBB2x+OQir0oT3(0%eV9 z94cEm_h_;oXq|DdjHvQ}G1>@E8`U~FSI)}~c}Fueq;+zEd_CcajxyvSL;yn>fJh;v z$xrm}CpPUxUbcsLuRnF|{*%sx2nx(e!_d&v*{mN0aw&=>=i$4%VjYWS54!;_9-LhO zEzK6S(wKgT%5+}!oNOOgvx5wFI$bx5PEQ=~?rL)QU05D+UN_i3SDZ9QKMU?WVp)Nt z7d0EZw^bds$v0+$cjJ3i<*Tb)lkkt)J}sPC?JIBcyHqaDGI;j^o$JTmq7BBzFTCZO z0>^v9!>U(CKH9YMgTUaGUu|iIH4Ol+Ao}6T&iN{vd{UXtBdS_a&M3T6ks9QmC+tCx zaxJ4@ZKPzAD_*at?>%4nYOlu2n}XLMIb(sZl(z|9ZN^49-w?dA4cEEtpSrGe)VKo8 zHLfj98nx!!=zHKb$PZpppPh%DgV$`*9h4<$O)9O)*x0$>o3Fi&I`WZo6>1-@|Eqxt z(`E)u4TvYW;|On2lXv%4dr(YNEt`CJr58V? zEZIn@VNzPpZX?nYqiMY8vNx2TNub1VfK`W$)kr-w{`k-cO1Xm4zZ6Q@pyaCig<2&P zS|3GzA|Dy6y=bd?b%D1i!NT{^>)$NdbRNZ-03Mp-^Jz81r0Di&Bb+&d{&Lm*g{YEE zIH`2i{ay&yrp6B=;?k-69D|&z4%_YvXT2;Q8Y4&=_CT7`8nPmr2M3R_4(S+$O zUlTaH3Svg1<}KoMXU7hfE2!HooiJL4_T}b4Aa!i0CgNkdkq(_F=P+}WIh-V5U}o4bE>)0fl0bdjtt`O+vfS0|@Q(mqH(ztE z&+WE%r@pGg+I?f%=q~TZh_`$r{A9IIU$!CL2le&tJQTcv6NK0_3kf)2A#pxxvv`P0 zb5iP5+!xl-f8V60>=XCYh2Q{iht_IbSHfokECmVlWf?di+!LJIXTDB%!^e~S+Gf__ z%)vc)tBh+A!`~99@D}mh*58@U8^w-b)XJ`pnpS@0w|h9jq-8OCmpL%9M?p4|PVLYB z!kT*tnT$=DE(gcgy2ONG`BW1og=j{P1l6m#!nb6R2D$EQ``4zf?!5u6DXD^$)wO@)?#rk0Nr;r&j2C2^^3VcG3PxVM;J8uo3z+%KJ>2Ly;m_ zyZR6qyU)09=gV~d{xKP&X7(^jOumt>Q1aJM_A+IIU3Fd3W3t2eIE8O1rqzz;AC|j~ z5oRPyoD#4G3rEqr7~})Ji`nR^Urr%=-^oZ-w*ODr9eJr{1k=#^$JKe2HF`eK0OE;PKm3W_jN6EY<3l?JU z101j0V{j+Ic(;BSX^?aG9v##)A%B(EeUf)#FaHz-pvdY}(@^UzftNM?_Q-}Cww^fxl&o7bd_H96V!sj0) zit%v>WhiESVmDT@X_cqg5jyW!wEthp+3t$SXi-C&gO=;DXx3xVVwAVI>gy;)427h$ zDy$CF>9x6;m?mQIenW(tFKI48&N1o=? z8mtd-M52tsaj%oM#ydPOa6bW`*-LkLmK6i(G2gEUJ*0Z8`5(^YU<6kV^d?EGzAcbn(U5_odWO{y zeaZ)(MgI`X_-Mwe47N7&9rdw*)3aoS*eu+mI-#QU{BePig8I$qdl`ykd6nVG#h5JQ z8)ieNYMx_Bnx|o4RsBJ(n|>omxt`tNmBoaAE}pAf&B@WRs&YuKSxC;4(FEC*&C96C zSlKWjwjMKeZ}WSZHNlpDU%fs$y@FwFA~U|ho9TM5xyky)5Je9d6JsneJ+@?Mc+&ER z-wtH0a-iL9kA8%$kN=R`FUkS~+_fuz5X}f*&PxQ}iDvBa#41ePL0~aj9a^n3-+oCt z&%I=eRl!-mk?|?*i#kUoNN$dmP5@ z2&V%BH7_{T$k-6h9N}qj7?-u=bDo14A(SoJ!>*q!EHRc1+4A6=iG#O1D7n}pajeiI zW11KJ*A*@Iq+}etu*g{UA2s@)t`5hH!g>y=I5` zXKfW~egRkUDDLSEP2Nxyn%0K-tQ9`nVO@ZIgU@_M&Cm**k;9X<1 z!bz&f^{Zw$%Q)`EV=z;IH}u~%8$}zvMH?}U#3gIRYdlzMWUQC7JhwG$sXoG7H83qY zp#p|-8z{+vpIeGAtuR;eNOLi)2frj@jA^c?rn`XQtH3&6fH|FDn~E+i*R&l0|Sz97)Bc|<(#QlJ#2WvirVK3YblGS@+gJ>yCs`~ryS?{Rg00a zh5D~Q)XV7}vuBcW{<}-&QTQ~6bs4shz!~P-fq|@YIkG%~gsMPI^Jy+O2i z;bEtGT@_obJAWyo>8e+*)YvH#o(b4sR%hl;Nr=-It>)nvzU zEXzMxc-XQd>Z3C}yRGIgoMub2bwtL7v@_FT1{E1i01O5|*nk2+Sg-*yu4vf>KtSur+hTom&t({HN=!!(`;x=&d${iLv)2lNj)l{!%RIFS53XiHAZQl@05 zJw)n`#~}8%G9MuwnUdyfGAUg{nIqOJ$ftty@CwK)Wh$ykBvzq+R&zzBq|86OgBMq1 ztWpz+VN>%HEx|}8k%+m_noZ!(a{2raU0VVpASsK0tk>Y*H}Ktq35(akZX3m zWGFqw3V3F478Pyt&h}~5g$BO|F^cTqF@DKABRjz+9i!c|s<~pKB$Y1=E=t;zRxtc_B ziF%!N6g{#k13BTXXoiuo6?S&ZVrhQ=IXV=pWCnX`Z_ra~y_L%urPrL=V`_Pr4fRb| z|6uo4g;5~0eC2iNTmp-=)}DL{ZvYsx*ZRU!nQk})MEq*oc+VdQ}j=U(!5quXoqt3q=N6hBNMUW-)(M;iDS5-!u7c$1_%1k;oX7#*bB zWRq@NVikEczScmxP3()+S|fDpiLI|dKrS$XU%_@pu|Q~lQ;_hhid2O@UwT|oaTbe8 zBnS#JL1Jye&VMgFrCftwH=&}u^SbOMBAeDV1$H+~-V-lLl_K@A*u2VmBZTj;&f~;3 z`h#u@R6GM{SY8B}UR>OH=Ln?-ECp?L)C^X-gGa-(XW_ zg&efC&2@QJrKc^+77}88IiDk__E_B}{~<&l=Z&>UDhD-KCB)iYOV28tg-^{`@Dm4* z38!b^dwuj}KgP>Ni#LNMD{}>^q}r3SAXFr-@^)T1<(f}LI1?#zV^zkA=|EU@rW%Ud zd%ZyMbKCxAFQnEjN$e`*Oczs$Ba#aqRsp-bv)g6O%V@(TrZpF%3tHCQoq}QZw!=yI zTQtm(-sj_+N@L9Hm9CdMykod7*X1$Sak0SI95u}Ms5g*Z!?g?79Ziu3=|1bX*GbC) zSMjz4fS_iKS?L|~vb__XH&ERp}vq^*_0Nsdua03zZ@vxO>DI%wYu#| zSNcfaY<1t0HnAsd@*K5cNlSFx#56WoV1qZ?2YqFyF1#;#$HX+WD>~{nqOLQewc3)w zox&QJY?$XHd@y$F-u?cFh?xtyZ60p>7OJkoCyI%49$o?26j1xyhv~HN4~MJmt-Yh| zMHHjiqOrfdlJ-?$@OGHUsFF{;;i=};DmQ!Kna4(77MqzJKGJJR7ekuOw!{_e^7wPY zp69qLJJ0DpaaT0My%ZzWd(=v}Yekl;{-5M9OitO97DMfYjES-%a@DVqq~wN^H(&K! zL8Fmb(jGl7MU{bOW3cEmoE!s3G4*H>b;$0ma@9V#^WPjGWTE1~WNK2TuYBv=0W!0q z{~?syW4cvgal>?5<9025jR}@@QF=h9A`PRf7+w9}K z)m*Kn+2{r#My+InpJMqL`7RWJo2c4%3cw>%D_VAKKWzJ$d(?(M81cC3*3sOQt7H!U z*>XwwkYMCc?Rix03(l1bWfS8g0h5z)kWUdZP*Av$^4Vi;a&wJMeBg}}v-yH5bA`1L zzNh9&JTp*|8Kr|r@pk_1dH%t5=;&4P4Bw=-LvTM9rD#nt-y~<5?XwU5>{oI(4g-3T z=8LT0`#nki7i6r(!+<}7hc<0xTSDf_=cQW~RQsld8wH7Jara8UxDm*csg;W&$5mGd zL4`&}MhjhWpFJZuh*eGROpHY=kFgu(4SrGF=|sK*Na;o60tYb)R^A<~^R8#PriN{L zzG-CJuf9$|y|PivI4|`HP2n<8_8_0#D*B~eyoNd;*qQ0NMJ_v*UQ`U`7ahyH=O-Cu zca>6l;QVDVQfey7+va_r_sF<9$dhWkg}zex@wO)X7K6L*3V}{NcGXnY2*o9vWW_JA4yPLW zXJ{F~fm?07FCkq z9Cl>ps>mr6@jppIQaKiLNqc2_?UJUn6Pv_N+4bz}4RX(*tD&-^p|VrxW0=R4nQ5yw@V#>Vv&Ww~afkf!S`VYh7UAKu8i-B{vssJ+K^5YiYY#z-D zS2jua7g*~T(+AfTAg93KD!cY!$GjeSqn91?aur!9S|RM1wcChmaU1c@ep@o@(deh2 zQeUFW~W$eS2YD6c$getb+_35 z$C5r;x_~0|3!sz#GplVO_S1Ik0VYZer`+c*~NK_TbklG`xNA~mj zZ!)rRYSBU8LW{UF zg=(Es)~rc9aqekMtA$mLNm}ysB@fFrJB-11sY_){Zx#TN-CT8JV2Vs~SKXlmDoRfb zz-n0y4&jTH3Ye!M^l>W3&*|7-&%9FePB6{YhW zoUEb!H{Ds$X{#m|I}puUCm$<|Mzov~HMiI0QXZvBk)AMDom8|gBr0D0Cc*C*}+y!i`ApDP&|CifD9-FB;7Irv#v(NVD7VU*?Uz^XWTBa3~O znO9|}uO>aONvH4LCL5129QfrtMof~_5_4VNP_I^wUpW=&M6u|4R^C(#oaB)`m8aEx zta61Ia(5U^keubzL#n zvy{EYDw!j})_uQB5}cH~=jtriv+a?K*-*iRs4*~!26c^FCea)S=_10@7 z1v~fn$H_-KAI9vh1bM@8fVEuG5|?=1#?Mw;l(W>=mP{(!({?g07Vd`iNxomILSlZl z?dz>NyTqgAV}AD%FYR6;7qQz)wtGr1EWPeb7W#FfKgM<2WT)KI(mv8H2a^D;$+1Yx z#n=0MVSnLxkL$&Q)T*$>%Ko{aAM@v+z>Tdc2WH{U=+TP&qDKX%LMhn$v3}rd*E;c9 zT#)2&i=!q)_Y6#TJ&V^2+xy!)wL(e>UngkUMC3m}Y47WCZGGp+_3So%)g{Qb5xtZM zwrF0?k9^6hktir~JH5eIzx4h6NBg7iMbJ+QvxdG8;nY<`j=j_O!n!32Is0JC3D?bT&zfw7*jI~~iSdBc^KsB-|mKgh@%QJLI#&u-i0 zndtDlWvkXYRq;)=f9s_*sQM+NAI?+iR%o->GGP3--3IHAjA2g~ydu|e^-#?}q3A)^ zAP;v6O=q|pFbBv$CA3Ex{LjltXpMAmj+LODZ#&R04L&7%k3QGiuNqQlFnBp_$>C;m zljXTuwS%oox@&1y12B;V}plbQCT~#`f~4=PEwE zV617@*1ObHHSL*t9TGrFCr7-$-uql#@~8g#>D9$4{iJ$myFFL;x;@BbJ?zyfA1#!~ z1L%~;s-z$mLP@h{4UW#jw zt+9;ZC6e&zTnKNr3`UN<^FY_LU=iJ*BHPt`I#KK}lDaq#x z0uR=)`p#}=k;*hG#ReZ*|K4`Dpl^tx7X5(6A1G`(U zMh2*4s-tAPu7+7$xq%%RRa_mt!7$I>V74}QW_i>>fNN=+tm|c?jO%h6s+uY}uXi_G z*W7SHOLQ=Srb=^l!v)Q>0NrY_b{No96RMP}+8fMC*&cI~+TMs80i`2Z$hyg@I;`}9 z9r*1sE8FZl-l(F6yPmDI#;meas@iN_0&0a0@srxfTor$s(m1Uc!A8Wqw&1{(BlM&E z>xg-B4Rg^B$`>6-Mn?=8V^K%?!pu8z2DTyx+;Vl~s30BT-6jlH$08 zyueDshn!iB55#y>6Rw#oM_`R%h6*SxaH7~8EQTMW0^yylwciJ*gkR8|eQhc3|Gp>0UN*HuoLjos_xlf)Hsx5>#e(HQ)(-g%-a!Ae zy*{1($0MgeIIUGGWfd2xTRE)#z!7+ol}uK1SV=ek36Xn%+}ns8c$%O!iq>SGfc*;G zC|B*-J6z3+enfj?7>tVcI>`bAzF1x2CDWE-GU4Ndd?QSifti+Lja7QfHP&0Rqz8Im z370YsCHq~HoxBIJ=qGAy>sh1b!{l+*-O0dt(2I0bIJ~JdCzA+NEQzTT|Bla{_;;K_ z^mpp)xpPh|SQuJrV=B+)wSKa_)~Joo(|%a-HvxnwlA>co|BD`5So zf|Sh^g1@W-)_-0`roAJR#D$HP@QEohLLN?kjq=yU5qE3!`$nits@yhT*Af-k>t5z# z@Y>w8z?%%_71ztO-|ELPz#8jgR9(?ly&&0$>;(n!Iq}qmn$jiw$9P!zFG5dX|7w{; z2o66Kiva55dU!XO3;Kph^;MA??w0q+zVmj2`Ral`aZqx@n>D2MB{!TP!!2@y>CWy= zHY)D}{pI}}3b6AI>nHCe{pD?p=QW(d%6ezl^3K@)@?Ra#k5;gEW;H+mi3FyUJ6Vch zXnPoJEAc~(EzG$I`|m~X-w!<_Y}|J(L?c^$ZMf(&7m1dWbGFd5hf%U(o%uwC8Lcos zl|Sz&RqGO`*xOy5EkrvLOCwL&5rMP*s5VtqM5BP0-Treq_%a| zX5>~mKf*tX<@r%p?1frtTh57knz`0msuF#sWgSftidf=)Z^w052Pfig(S-oF=X?d% z=%5s9z74v=`joII)!`sXUyTJuJo{frh0 zy4s)UTt}138?F~YpeB^>X}Iu)h6`@+G~8E9M8m!ES7_o=9K2V%Zu&1i!k)?(b}r;uLa5FlEL#_8b9G1<^0iu&*#n)Yg|*;)ObRJtHNibPi`27d3bKdYrc$C zi@uQK*z5lmJxj(jweKhELP~$=@Rz!l4t6b_tC6Qfg@BEN}3GS_+he4k=Y4(|}N!Db8CgF$Kh^%oOLXmKZlNvm}@L znuRmgIi_cUCset>^{i(heN(y6W8SoYW}#ufNt(y+Eh3VUNwn@a73lDEs?5EmSbt0@ zkQBF_Le;sqRNEx3pgHpdGX|ELiB))(Z~A(%!IOpj%uo^-G&SAzErDde$dI%u(&G zS2fe}CG}EoL*?~`d21RWSz=Gqf{&woRp3;jQ{~m)pDVoOR>6t+S8Ls_zw_hYH|lRG z$(pCaFg3J&p~b3j)|XjEh#LryHE~k1H++-O24AYsaJ~H{MFLhGnwk}5^X!8+j-@~@ zK3JpG?>Z|_Rj}5|;n#c%W@TkaXhpONp-VSLZC^N=cFvxNP#5~GiVZnlq;Pg8&Y!te ztZHFskw(BdZjwYU5(G+`Lcc)T(GPFR=Ii92>dn{vGSd7`>wL*&PAed0 zxsLJb7<^afJfUMw(lN!v{87h@)iI^S+@oU-(J^jfZr3pm9b*vFpkqEdQ`L1TF?Z^i zH+9S$Vs6$kYjn&4Vs6wijVi`eld(J}pd%mBkqt6=%5yH&k+4$Cn2vXf1PeI_zYEb_>R1eW2}#TWsPpSJ&;epkN{4X-sR|}WFgnw<{+7P zULZDYxm-x`z)Q|WHsoTA*=?GI9@)&+(s0zSi7qonS-lupUrQ?*;~o z>C>>ZY@vbFL;VD$UN&Y0Xg?Vq($0&YH~!d@9O;h|1#)PstZ$vPdN! z^_&{|q7IMwsx=X{GtSybWWtMwIXz#(Fy(?K0b zBkFOpcukc5Cg~paYIRlk=cN?wlcOJjAF`Db^N97l0;rbCRU{ykJ`o?P)x>dva51@;RQyGrA`~keYn1r}510$v2Xm9LynD z)k@E?-pL?`XMA8?tN_%wrgZI`IKYRNTLH-7Zff6S(xyvz-#S78$e5-8*z2fUlF>mBhfmA~%zIa(MvT z#TL&J1IaY23dx*@n?BZ%(Jd^|*DT1;qAjLaB9FOp4aBga(-DH)h+spfAn+N8Uqh!O z0J#yphE74?GpZ$~nwVJB6lQj5UF1K@;ZA$F4u2@7&cs-#bjIw*BC9b*?`74UTJM26=tgV1m)xWFr ztdTsgfUhSss!%-BqVj%0a(dLG%4*%gdf3CAu7^-uat}Pqqh3!;F1+L+nUy&RfG_;> zT#tS~(Oy|eQ{}QW{}=#Wt{tPe?Ub2u_WqgWRuH&&g}qa*T0)HQlv#0zPp!j&fGM*v zT4ya~F_7N@G(t8(d%Tn%Tt|3)%nkL`M&`Fh{@rBW|AmjJ? zAY+79=a*NZ3JY=d+u5Z;Q{Z6ET{;LCbe7DObdbjntq#KdPV$-WKmc()H%C6?3h$8i zFc*68Jr!?xK^hpv11A#ph5jJfh3~zfGKT)zgYW&Hx+Z?WJcfPE07LI0T>h!97zkf#)gC)SDr z4&$A(V6Bzm>q;xbSN_c#e!g&n0EegEPezJC0gn8r(GUy*WTsMuuGCDNN*vN*{V-m2 zwh>n9q35LDIC|XWmHZPFP~RVnT2V1ie_{{-7Z@8|oST`no?a>OQ3UhtX!tHtiD+R2=TvHLga+`v)k(51HBXDGsJb+)jO~7vhM{`RYN$XBklt4)0T{4{J zns}U2*{#b!vL^c4e z`xStENi|P&Z?yp20DuxvhpdVVsd6j$|Gu1>$_Klh$z3+7Z@wvdA~^uC83{%VV%A^q zg79S6rBI&OtQ&Rl zLO0et9TxJiF4tkeZ>wi0T_DNo>77Nrum@Ss66+>2w(M`Fm7Bf;-i}Np+ ze&L~pCNY-ahC`cmENx+l;B$@jxst2!n6ch^)NSu?qepjJFYX|o-CBY4W;RE094&|L zlP}wB0)HqXm-k%NdMzV~2u(AU92}bMA}evtZIgcxCyas7T-_LI{h+!lrmoh8@~zV* zi?UnG{oJw`>c=o$9Q?n>ex)Vwfr#S+II$TTZTA)7coCDs1~K9#D&7hE`J3!J=utU9+a{fNtaKiKHu;BHk5(mn=sD&> z1*^6g40*T;t>|8Q6%(xO{=Z3Uhe+2B5JHZ=%==(_A=*Qt5BA%E_u3tJV!s`@Al`v4 z_53s)7z<=dwWnR(WA=b^37c2S`px)Qz+P#x-^aWoLJGPBg zID5bWi;&1jne~U%gwhQTe`VIMS0;9mXo*TN%r8^Yo|ZK6B@M~#V4#rc#P?IHOi!qf z-fjxqs)}{hObYpD?7`r=`u}0?UErgtuKw>yW4K#6isoGjc{I ziWijD8-38!K5EM&Gk{ezI7!WL9HkXnd$oOfZ*8@$a`TppCIJK@sDP*huV*}7P%8;o znfJT)nVDP&i1zaSpXVtbCUfRo_St*wwbx#2?cZK2K11jhJ;nMNCb&bkv;JPP^`jTe zM=m@DuQd7;AsByz`A(8oCJA=-*?pO>FVSGWZJ`bFyu*AdH;;3;(nu1GfOor9>qhpY z+3yw2-nPr+ykU0rBH7{;$w-{CLy_!UAsJiSNIC_-AymM6d=-Ku>2_}Pk}vJ`$EHn- zUnF!BiGCecyF<9s{$9etZEEIdmVrg2>(KGlW_yjFxZ)$|?|ca`ewYN~GAFY*x}gzb_tTsl!?T~<9# z2lH`pk0UHtq4wvP^YglXyqFV8Wq-=taKy&QHO1rx<8P5G@@h_^*;>Is4bIvL4YEn# z`yw|7OhVi3!dpX~cd8v;#A^LD7YNGdVnt~liJ){1B{gOG>%-0fTl>Cv4tS z#ugfkM&Uj-RhTUVAPbESnz34`levjSutec8yGh!@@>z>Lm@Q-yE|RW^89UQm^Sd)- zE7nMt!YaFxSY;LoOg0IZt+S3{9xzO3Z9;1kTF0(UMnd}+x}yc7wl7od6x#J+Dv>YX z-50*IQ&Ax6q3OaE3hmX&nT3ITkJ8|_D(BlOSzWR&z%hWI{|hxEPP5TaCJ*EmOzn; zB>+5V(3d|Sy0&MYCfaL&MFs2zYG<|+?5Cz;(s|)7Ix4c;jRh8+%tFKD9O9Em%`2&S zq}y$_sVk%9o^ZCx>tmlTb}u5rV{WidP^UoNXA%bzq5mWSG)K+NBR;G36$#QhYF?I} zXtH0?O*SB|j!rG0ApowgrHw2gxvk}s7+F*EcQs{eOPk3zH(2{laiEZQSJDo!B)w-}6Nq!vJP> zk_5BRS!sd;655k!wqNNVdsp$Z?A#kkM3Cw5b)#^bnYHDjG+#fY&U|2Prz>=o`&com z5xeg`u9#Ctvl-P~f5gUxuVx{V7B*+*!}GVJkd(a(3lAj{5E-Js6gihPNA8q&N28i}$wsP9qdx~@S{WOLIxhq|~Zd{YMNvr#^Ix|vLx@(I=q9jFnRsKeXuPEs6 z;8jmIVENTfp_1sFLbX-a;OON1it9&)rgIFblwjagO~vtA{RdQ(XmK?aC*BtBic5Q7 z8@y^aG7X3m|0Aj-ueg%mG>8~?y&4ohfwK@Ibh}}qiV(b(0e&I_+&i@(e7!vWuzEZ^ zIcN?c5NE(#jnWeuClkI*(XlFL?B>=)-u_BWWY4I1Y<3y0CmQV?ps7h`M4Fcq_3$nq zp{%EBtFF&a)t;({&rDa_9=%V)!lTnygKPs5dgDa6yHrRME`u!iFS|M-otUOh1Y(hf z?;})YCrcw#z)eK3u^cnI0vwkGUD5=tA;t?ke1N4jw z(gW1-8SJ*sMg`JW&W9j<2k1x{peP^?XV&VmT<|(tynWgNL)QuD2HBY~8Qgx!648PM&Qfs=2%|>&I=%(bv#j;qckE#Lv z{2krWn?|_6@R&=GR;)){WIur-H5I35bxS#5Takx-A=XZx8hLdKopYU~;Pz011SgG% zxq#c=O`bZ`IW>t>ZzoUvMLirodlliGLD?YKQY61eCUR>b>l2i6vdM(b)UhCIg#egk zo+|H^NmSmqWCAFlH&=o2F0z+lk!|||G*G^jN_b*ib&@B*F6%1?Cu>y%9hhgPSvEt4 zS{oa*2} z^+(20w+~swvMxYJ1fM3N+?k4538|$EebHI@!Puk1h(;7}{G1$o6UVU*iw#y3It=lu zGkK0c%PJ{iAgp)hBQBzCt_=Zyb#BbIIzJ}FT9)-PG1`0;v+~1wkaop}W*w2~T2;x5 ztb2JB(v9H}9#zF>TfdX1@~mG=WVbBqnZG&@Yjqck+=?ljFn1n@3yL>}bFd%YVM{h^ zyql~u*e7dlks0h*Za&Lm%xHB-aL9i8MB&GzDwS&zfkq;1x%KE#YPZ3M)WwKBA|gjb z7MAg`BDSVf6gy(8Iw`MYjw?Sw`qBvs=!+SZ#1~j4x`kX@3%kn;L=`b&kJs{*)ORRA zv>LhTSIL{|xVq|Uxf26vzJQ5g5kS-@$?xl&-=R_I=XsPd*k*lIJst`e4g!DSCu(QI z7=0ysI*=h*Gfosa)Xu#_thu5w$ui<)tXwp~6WEf;K zep=AJj=9yB-~M0v)uWHfhTI~V@YGa7z8@n!;pNlQ2sNwvRI!LG%dfuKZn%P7WG-t7 z>mO$9VMS11aZ%S+XHqoV&7FO<)I{O&qKI!r zh66jI9pyrdU@@^ABeM!4vuYnBQ$2WsJc01zh>n@Qe^+V*suL3JM9me9nwdt{r&Ar zrA4UTx#J<)8XAukeNc9@9$oYR52%LG$nzKiiNfpN`dnSxry;0h`_=ie)=~KT?x61( zvnr}&dc-dA?K5J3h{kBd9+LjI?vZ0NJ!)T}-sbtEMRn~xWViGmvUA^by9it+g8Iiw z4uG#zqxE|5(MDvQ67MT`0io^vvGeCU)?|^nwyy%5D4ak+Qp#njlwnRG$5M!?ArOW* z24(bWkNq{VA-`re`6}iXguKC7=PDDjNH#=Yix#bJ9~)Vn8NE6usu?Eu>|vt95W5T& z#(Qo-c!HEN-fa3!MtH2ka%KJLSP>^9Lx(0<>p-0B5pl9QLzQ4=_p&Yj=rqKk3by5Z z`Mpn5{^Jd&DR*&I-md6zxue&eW@an1GMnm;4CRRR70tG%sm7p3P}QfUs$Zk3UoQxE zDmJpm$j#x2>LzBiWQl{F5|5M>#x|7KAJS#a|3kG^C+GMo=7|I2>R!Uo&hbUhNNR3( z6{p1F=~yYf#A4cTlOUaa*zo^}A4%R$+Fr@2=uv$i#%?YVX5MM7Qr~H&9t>}pcguJl zkgt2}u|(ldUXwly4?a4nh~o>rTgge)nRl~r=@caQ;O;q{ya)C;IjFc>hJT1|>UIBB z+|Qk(QeCx^iqKVqWzM>q|2YHCS>MN1+pBYW%(Z_+XCPF9F+CIWfPfeF8L_JSaRz41 z%U-dS-Gufq$H9;_FK5MWe%H7=^rjtTk7y#A(i&NU@VQB;!I}e}#i#U?-@bpndiPgf zJ1}%HHel#{vH!-2{fBE8f}G9o0)C4vCZ2L=cC>jxjxTn8rZS?Hg_kJIcvU(lG(ikH zyFzZ>HU`7(WNuZrIX0j&;}V6>?NB}G!JHc=4^ZYH_PcVnzXjO8_6Pp0T%(0^$7bR- ztjwtK=7xrm5JPrNO4f{<-s``9(vKGAhiD6jqf?q|Rh<{^kfcmb&9znWTp9TYweCdW zp;T2FaiQrFlq)2WZhb-X9$`mjQ}GA|fCB965z2EsLTW{4hs2r}CljVzK-@x2q24BD zUsL$N4exhV+La?dOQ6UyFw>?T`UN&9KxAw>3?=NjF-d!FXVBaw_FTX$ILQ*6G@W@o zCfrqG!rhkP{p7ZeeFLbY)2K*d7(IUMzSclAn}iZu`_*ROpOw=uW+HSfPG_4Dw)vfB zC1r*mAYV5rWJn2S-F2Lj8iM@rcM|x;xf$%Lp| zmRW#xh(%`>jxB(LV?!@LB-523dwh$v6@||iy|$AL1nPcnzFFNohiFr3g+~3tjauDl zO%qd1!t-`o{w^`suI<$7ALrd>;qKui2#BdN5^H$F;GqniTPa*NXe^fM?OR-i6gN*5 zw@VIhNZxaydgWB>d&f$nI~04Q)YT@g6{82rGJ?*Y=h)DXi0>`>-W{T#Fi~+js_wxwshUdc}xM?{pT^td~DYS(q!hMVXa9 zdD)peWtq*aem(iBk(4OP!M8c9c4Ght=c*C=?oKpOY$`qWU(?BxV$B^#YuK)Fjk@|h znIX6;SFYd+C!eUK2p@Z{MFGc%OcXw>-WaMdtF2(tWH;9<12a*0pL6XX1N2VxUj zrW?{>TI>^ts)_ustu+#gO3IR;Z-v$s%)D(bS<<&|JW2(Vvvcko`cv*A0qH(v$fz~E z&uZUlmRHF3wX_%!@lsjM`YytSy}6cH&(m-xo*yg5H~m3PjW$M%e^^WQ4gWRheQVx{ z+87_dSIv&Ta@Er1;d^mrVDJabwnX7&gC)#?pAk&iJ- zwo@d}Ys+%9Wd-hrJa+@T-YYW%AP|1rDETzt-8=6)K~q(Ohh!G16n|6NxAevANx@!` zjI*d3>2O4_WR13rMfqiU!}SKwa5k#ME^=yM?N2RpR?M-`r+GvWWc{MNM=jz^wYj6( zMDT(WTMZ}<*hQhWoaraoN$sQAHt}0ToA`3xWH&{K8DmeTcE?iA8POjV8&YcYf#OQ_ z{cv%)`hKjql<#2lvEuRa9s6dYT6=JB(7n5iAQ*TwNgS2xAHjaK1xlU{bg`s9gM~5D zdEEI!ID=(t*u;|p=F5h;H{k7>cY-#ifB$U=m`^1Nzn7itzwH4xcP8d;1JG8-bXfNu$U0t%5_sv@(UezKX3nYx;Kx_CGawKTp@JwmYeC!z< zajtk!mT{i71KNYHoEMu|(wm)LU|*=JPL8V1Z6`|*2eUQkeJ@m;ZZDk&Pj(n3n~1#7 zkja)fY|H>}48PG+mQ+1i)?DbLjL9 zr?9dVb-D!hv7W;E&}TsYq89>YqGqw-{b+7U!2OEhePzzLo|h!~;H}%URO7Z8=KFz?y@q%1-2V4D{kvSGY@$d_a`Jo(EcC#r*u;VA?^X{39uy0pN*kXYZ=pC3U}6e7z#q~z*gKBdRZ`f z0QJD=`5FM!*xMCG&(|=@Zr%r@SEw&S*krP&kmP2Y)O_)-eUh96o|iiRsGLt?^Ik{R z_r~UBHe_-pe4m1t4Li5NH$0(`c>+6Y&2U-SQr)r00wtWjU_U1H^<=J~A}ou6F?l~g zVM@{FcOwoClb7Xd7;XzlG^~yu-3O6Z(2GKUQWSd6K1mU%D@C9mqzD8O?+rzu9weUI z*Wdv0Zh|5yDqS*)O)TK>uHqc;w|0z8QK^bEUyw@9W9Tz8m`cBNN^&aoNxrwBxyFce z7m-PQ&b(Hirw9-LW?y&FtveTG+GDh39i;qmYs(rVo!Q#5U_p`g`zBng4IJrz?kHYwGXgVm88*<@99Z+f-v5>HWh46}rPQI4Oz(_5Xzze*Y5cZ(?!d1?mO#zs4C z{R|)b=WJQ8ewXA>vD1!l$>zdW@saHbl(0Mtq`FDFY+E2!l^}JxMw5okn`72}>!r+W zm*H+rbk=Bdwr1Ef~U<6v&+$7$xRi-x}$by01^{pyb^dQhY{SOc?n|a(EgN z|7G&0TYkFZ-%bAX$WKrF&g4&3wJiGB`zrZzt7h);*wf@!mK~6}dMSQ-*XC|Mo^7%TS zFrUvk?EhEXj;}5L$MKHHOV8<*DnILPna&HWcd%cQrp%|B+A2Cz5VdciNY43CMF~dD zx2``@tXbI;&IZEB%{eaYH#{lcJ@bf-mbuH9Gs*)3npF@ain%GWBZJ(@+(3fRauwv3 zGSVS@n}x-uA(JZ)-rno8r)(dL^E5Edm0+9+ys`ijH|y0CWZDsobB-}9JQE9!ji(h%pf6#AL0#s=u;_IYkXF_Cs} zC-7}+9;F#2JB-+^&<01$*tTqid?rRmyVW^Z$WNf!#!wpk+=jT?&YfD_8brL0Ad4)u zNp00WQ)iN7q5p8ol`8&{n*_C8DNt@XC`Ta%6MGGLs@XOfG_Q537P5QZ0e4$JVyZL* z*UfGm9$qDN_tn20y2$j;mXjxN(z{c;XX=4VW-ly@BSc>CJKn-hdK4H$nQM`)&YwxwwXU>x4Q z=>T*P+_=;h=Sh+E1Kd)O{1k^=;8Tyr(F2ho0NzQs0-f_j&W)D~MOG`ugfuLC9D5Uc zaN{@8c>?6xZkGrx(uAw7ztJCiW`MbI57k2R$}sUO1z>z zvyBtw5-pVdxt!ovX*$uO^aSUB>YOjKevL;JX?0yvT1`tzE0uf=z#p@qL>ND4#Dnq; z*3(aAt8pi6x+*(cW4j=;ihIWcdG zoQmIw-&v5Ma{LN|d%$@rNxSsg0`Hur^5?Kr8W&S3n~CAiG#=Mo_;Bkj%#`H&yJ0o; z{`kG>@~+U1M^$yapUgePdZOpX4Z^RpNt!FPFSPF9wr=GjbsB12oi3jBj2V0B5JPncJ(t>Vp_G!D;x@ca)RNiI zfy9>s65$|EM$W1~m%h;IvI-StTbh2eS>&2uG+nK6#jg7q-d3R$aqFCEa{jaV#v*tY-^^@BAAc6$DzvjJ)s&U-^RVYL8A^vT=kX zuur#+pQxxYYM;wa$~3!Rp9@TskZZxlh@TGDKVhyi+%~Q(g7i*z~s~&RFa;Y2bn`dXf!o)yLu4OBC*G zVLf1r%_7rwiq<3?`37sS8)rlLf^#H8T=j9*o=j&ETnMeYHVNChr5r&f^Toe#ktP1< zp=wNt>=Vf_$_gR6k|U!&ixvuC7LnG1Ee&zap{EN@juS@Wn0sk#KMqUlvPC_*Y%bcA zwG7+b9>WY8&bD@Ea17}Glg_ylERT9$p7dR#D4?Yj&ZczhDC8D%{B~IkzYWg~$1Hjb zT|Pzf>a1nlm2FHEj-m#ld_8MF)vqG`e)`O*Lct5m?y(;Zu&l}fWLKTx*S9< zK8{yCzLJ96&{6*SjWHvkYk}1`F6uY>Ofq`}8d+ez?P-WHut@7K*Hdf8Ea;F_Ya{;m zvcwbeaxlR93fZ>xeRwDd1~w!!{L6+Lzg59z>zE?d*h5)94$JcKf(-B8+uC_EAXfJ_ z-SlmTsgf%+2qY(iT5=`1U#s{1*}tCjdud=+H>pvOo?T4|Rz<@(YzCx1!sm;q^wcMA z_tz)p>oT>)Cd|(S9k41%#avdub+bbN&FuzYijsokL!~L=tw}Tr?Vg2p?LP17+cr4e zTd9D|scMt>t-f*o8^(PK@Gok*dBf8*Z=Lm+TDsm+pSW#=cl!b+m(4OYG3>s=&}PVG z37qnejz&z?=-jf6>`$wKQ}%83!Jp|*pI-gQ@CcnpM1j~@e|fh%@ubt4V+QWbk5y+b z**xu(!Q>!7-GE0051=63S7vy(-}cl%zcvCQ0IlSUWZ-gY=AntS=ZKh z=wR1paeLqPN?h4*?d?`{N$qoWu$Guzk{94>T>Lz7lO*m@ub4`G$~tmCW%a{Uz;{Kf z3>gpSbz9${uSF48Ho@ga>^HbGurQtu1&!EzEZYk@=-yR7CFYp*Ut;e@E}*`#3x?Hx zb!a!*cl3<5DLF1zZf@(8Jo4R~g7Y%b1oG#mkH{8c;EwK~tndoM{0IhF@F~wKF(Z0= z$XV!2?qTmswgdiB%#dW3l;hcm{Yh0^h`QVGt|yDMxgk+F^l=fGRK&Yinc~)-zon~? z-abFj%X*3z%WAd!x|6~N66gyp8 z$`Y{)vaRzxlICo?nROu&REjS0?!5JMxH(+qb_FUXZ4YJIW39#c68y=7{VGFjex6-m zW)<;3q_HxZb(lPvXtA4Cf`E2e-$K12&&8sF>b}2o#w?O_XJztA;($mNG!m&LGofLk zlR_WiWwZyv;v@oysO&$R9x zraGTrco9}|HIg;X?{-x-y*7wR`0PEf?W`6j^_}Ob*2;1+YJC(J1WPdXgv0rJ#dsLc zGInV0t|{diu+&I326mG~RGq-Z!;tuppK3^m)nT)uyw_M!arbNG{2yj?y>B$_$yAB* ztaA)^2XA+8BEhtrDzXQ9RDK~= z6@4+XdvCbVn&gygO-jGYKA+Z}>K$q^%IBOwVl+m4KCQ)@CJ7UpEQV!)Bu#AGEEqOg{v^Z5DRM}tp} zbR}PvXuY~6(w!O3s$E-Y=dcSe?5_bQ*akmD+pAs6)>G`r%`pBTi1peehc#k(!V?`0SF~dpcsgMB3hCgE+H2a++AC#b zP{3SfM6x-41+M=L`W(z=`%#n%0iI0eFWDQ|dGGpZpN_BE%Ef{y}kNCU$tX3aP zbyeJ0STSm_J=z!_j#578Re0v|KbeRm=c7+$7 z?cH7)DvgxJI-Glqbx5kA_roYCc>>C%sey-8Q;V=|XzJ0}QO+oIIJxKm8y=~uIXM2a zBT!@cUh`MfHhP2XLGP3^H$?XA#T)Z1Q@K-~eFH;nhPQCRISe&q+#0I=%QNW`#u)B6t#04$68mj`FzQ36nR zf!fjP_k*!XBsi;UUVK@u>paufJ)V*_`$4I>JA=_{?@1Jza7EOAe_28=UqFI;a8lN} zGUb}pB)He}d{O_;X?N7ko~K~Nwac~0f4gP*BK5lM=H^Ai8c1y!T@cY96F)^TcI0uq zUticQP8O~Ho17FwsViXCwMaG2kL7)Ow%q7$5137r<>jGaiDq&kv%nvS?9ICMU6ohq zdAY-!{_Ck`-6naeidFvZv(MF@_{FH7dUIWRf`yi+N}8ko?~!=&9;4(1^5O=)&DuTx zl?f5e4WIxTd_x6{4J;twU4QF)crtGzU0rp8?X1W->mh`oynzbO?G){I^HlRL^)AD` zrmErA-DiU_33y+))ncXSN$}A0iNDQk(<6WLfYMDg`pixu#Hc&~*Opc1`@9{b|!ScEvF)p3gW%Ig#`(wZPChYNGT(*8o120H6 zYx1Jt?z46^c|u1|UgX<-c7s2A(Vzx@PVJ6QCO2@!*>6U%*>->#X;8rQqbTJ_;1hkp zDZ$v>jG#Asj~0g}{`HIJ9QBw%4smA%uXK-mn$~KzS_gnWPt$b<$sP1@08GMxx`%a-oY`Vru6wtnB z5`~Zb$-yrFjgrh4N~SM&Uz`)Y*yF1R->Kd4J|}SxSLTK*R}AI220tiEfT^Nlm46k1 zQ>hA?lPu^j+!tAJXNGpipEycP&Ph!6m=}8tMFQDfPiNqL^Zz{lH-VGYZ@dj;(%xC1Uz=~;o^i3qo+X@Ero0Du?U-IEih-KfnBw*GFgg}_P6e67 z!!RKa!yC7D`Z6Ya>|+)Unk>bpZmy~gcAw>mRb{Xx(MA&e2MObW%8Tr(K1@I@D-oCy zLq}lRz}GsddujpbUz9LBE%p9q9_-iN!+FOtvHNW!ni18J)++jf_xU+~Uu^bJZTT4_ zh_@!b)19axG1T#q$)3!b$lly=0c(NQk#bt+{BZaR?!xlOG`yeA$+f{x-~WKqh01!P zAC)Qh#jLor{)tN+e%F(_|86{?=xM(~PeVbNg{Fs@>MCb;?rE?4| zI@L|uQS>FZ#ax=2+Jk0DP3>w*4|<=T^9@-et`vA{@uES9s!6%w!HFq3t?r@t85-RD zF=BPa=kN~lWZtydarY@5ri36qEN}T3dyYIoZ6EgsMT0|FsVU8v;_H~mnC z>hj+?N&{;4U8>SDTyt?m%XTzr9!o4mEU}b|5B?vsS8yO29{*vAhA#~MEE>L4dN4H9 zB6o;{OwsWaZ8>2QTVen1+;DzmN>1iVM+^@kEE|zL-SQCD&f|LzG^$virF;EdU|Jy#y91p zX*`oFicirxoBageb@+7t$qtRH-8H*2Mh(<^}CE}kksrpJ< z6NN{>>)blhjU0pj*P%z1v@vB-@%Tja-9+JUf1RGV?kX12$Y}T*u2JbSAtIxJks$fw zoYXDs{W+kH{rAo`z(=tS_6&Es7I~aZs7~(p91*4YDrLH?@J6m}bVbhk`gru>R(}T{ zi_cCz-L7!HmY=nf4(DXXN80Uv1VnYC^<4&B?E)*)><$lMmTpYq2Wl7WbcHnYO38uV zXj!y8I-{s|LAN@Iio(fF>Lgh#t|*=@*7>c)^RYE%9{l2*GndKw>d0VpW>M70(H#qf zoF*V9{AOp+e4CW-k;LBcXuVZ0&(I@ZndsuEG(&IGPZT#}{7L>0WT-)sV0zD53T}4} z=@8q3W+Kq^K66LmvJ=zJ0%4uf^Gwg4UE&xEUCOKzeG~Hl2OuFPV%*5ZZYGT4QguhT zuyt~2M%!fdrq;>j8If5N3F*l4n%^V_?(;nV5C$OoW0g# zet>T_cF5 z1)Ww@yhi49%E)>XjGR+w1f(! zC4{xqLls)xCK`gG(1H5C^E@*cM^Dgx+f%RCl2q>|I}3yEj9-)5}{fh!vkr zr8=rjHWvL=iyX;0GyEL8ae&xzm9Ey?D#9WPGKJRwWGe8Gk0dKwWrolQugBiW~?)z>9UqZA60g2I4w>__Ac zJ?ENsbM9w-&kbg8svT2gLUMq(^)u?l2@$~VqM}j%mPBFWFNAz3DTOr{=bSYcY@wF^ z4$_zUQH@j=j-!s)8J)N~i@5np4iU#EvLqEgtlx->PM#S5InEZdnuj-8uVN?1@8!4Z z#9cnCyfQRMuRZ(l&=?t;$%jYNMj5X0ugR1C*Gt+|SgpuY*Yy}1|08y4e)gbNsj&;1 ztf9pjYW@)}AwDYZU8S|GWZlnYeIt%@l2s#C!mcPT_8$2cBwgr6mNrmTALN)(2}E;s zIMcqw)SbdYqrei}>s;H-e1Q|EI}!3El+P*ao2iE)O{Iy#;LoIpq1UGFJ`% zk>YL_D`Iy#6$#<3M)@p~IYX50&u~l)(EL<;2PNC<_#>$`ekiDbBsoqsVGu`0lD9L* zdH{dQ&V{oIp2U+S-XrWA@gSj#^b47z-Uj8A-+rid7g|!%iCBdb@g(oiazxskWAWD` z-ew*vZSL{c=i%A%G;7P4SR$R3_90ev`f=;3*Sh7+eI2d++9tak9%9)z(X=RIQfa6Q zO#9B1LLq%hrF&!IiXtpu0)PELFokN%eK@D~%+s_VH`@PceVrCFtV(OWr^Sqn+jDQ7 zZU6=li14B&d#d4XT9jYAr!=&yPNGPAUk;tVXmVm~lYPorE~Iz3u$C}Od6C3~P`1j; zW3M@Nwe4gO59i6Xom>ms_N!?tD!s4=MGx$0?AK_14rI@!V#SqK0}f%O7|uLR?MuRW zSX>JitGNfwkh#g3PzBl$opEAoWod?GAR^3`_#mXRfDl{D8rew2#HMQ(;3qTgGssAu zt@c#e56afpUk1#t5y9q5xVt}X%_y}C7iF^vA&ZchcIHE+%Er4|ea_E7;QUUorDuDvxo!xjFR!$9n^3^p)Y&!b#GA_g0-Z`rPl!8=p5jO%3V zDOvc>SmW#8%fi1S`*@hy-^c`mm$^}NdNb?oPcj|Pa{WVM5}5TxoPPpt#QmsHh4tg* zMviCt_~XMlU&(}`K%18cjIddjWM%}Ktcm){1h)pv_P{uXWRuag#Sl;}|MFeN5!;M$ z{1z3TtuQWQT!-O)(dgQGM5BLPQ*6>8-Q8{7ZgnTD$t=EnsGZnO%|pIeO(M1scB+kZ z?(N#*KjK}Z$u9DZi*s?l+2WJU>s^FNA}CVVi@N(cDmQy!Vj`e(?T&M4Ls?^6{YVkM z)F4`4z)|#(eEtgXdo0EJWg2cbeRqW_>SA(Ps~;k#-B0=O$-M51-M=1;uL=wvFkfP? zmfu{fuPCBCJ@VQZy(ylB5YS6LVFKUunqKmf_PDPuWeK16h0uAVfzV5u0D5_w=Vbd# z%Cy~7)w^cSAoG&D_(3EkecW^AhD~q##o9+*_3Fa8FeAuyE^=#0RLy(IaEWMHrsL7x7GV-I;3M?z%MH~jDw~l%hvtt{-Gqe zXMZHP`Cm^0#peC#5Pd}GkfMPPE{Y^h*Xm@)!hzVSgzE#aQ-PdLvXk~W918{^%^Jc7 ziksjO7>-SKtSYQcz!$<4b8}N2WM8C{R6_T*gnT};!xyVmjB&0RT%s6by-)b0$_xsh z(Bn<HkupGhv9AJ9d@9hy(slHgGM18*susgw1g(Aa8U9ePP%-Fj z(eCV|KqIzPp0*~x*PV#RInlLEk%B!hkxmc8#uFNlDt_-%`=`qJDXQROI2fvo0bMzG zAc{0P6gllPD6(evKop6`(QY6Z{*d2tgSFu;QC`N_$bdPBh#3TP#G}0HIbL%k$nf>=B*PT(*%brHOVVjkfHr`mr+x zyEu5bejEpMnCj=4XBbsTc4xF+`o%he+F%*gJzk`4R6T7py-75BAgb6h1@)EHgIOqg z-ueSxXrH-Mp3)|fiOCc6mw3MQP$CmEpy z)HyUiRbLV~9Bh42KtdIf$E8wp<{WL-%YiRir{ra_ds&A}jstsyzNj@xGKgmnPTuhl zDu-6Tg-1~Wih7atMW$W9_cGU90~XvioCS$?!!Vu790(QDb>!{AD?B z5-hR_NU>J8N_xlK+O>_)T602IGQ%+n!-q)VEuMT_o{ZMZgL=#}l9-5Q!5uohr#<)r zh$yp8-N2DtCHqWti8=ulz8^ThUhk;uLltg^4q%T)hXr^n2H7^%8%+M|d5O$)s>=DaKoh z$<}=glYN9akz_K@<}{NrlqWSal!L{^YTTCK#G;RiwfZw9s;>-gx;*BobvKfplC&mo zQFu(JwRQDd7@IQaZOmmgxYlw_4X$Q6P=gEU_W79glq9oiktJen5a&Ds?3_aekTzmS>>isaygR1V5v zZy|MgT1X8|&69C)Oerc3ld&QD9JACQ*+)b%A@-6_@=FP)4dIvKKUTsifpC&}3I#rt z7EOCZ`<*R*)fTTK|`Nsih0oHPKB0bJ4DGKR68hRqd{`bkw4Eu4lzZ<5-Bpw zSCsx2e-0(b@7#m|P6__?{4_<8(b#ZTMc zFMia!`iP(MKH}%il=$g+*TIM%RqQ_E=leFvL8lLqUUftuqj5m z=mQvO{`NE@MK>lHiDBCEID+Sr;$k%xOD-v%2!|qgYDDnJ$i-Awf~TZCG`pY3`Ku#x zLNkN~FCIYD9GC^?Di+ite-IHfAR9V7rV!t+$UERh8HkQ7Gkr@!psH(87=kg60TcHO z!k2}`s~i>|kuDnt*lhbm#mx3E@I%0^qOl|=M#agi9Cd+FX}vH}X`LeEWpQh^^%??P ze}tR_xmvx1?@P3`4kD-2RT)a!Dzl___3G68+NXxjDMwN~6W%P9yga2AjOZ(66H4aV zlLn}!Ql^p>RZ6l|LRIbIXj`7d279oc`Lxuk0XT@Scm|zV87*g%%kYJm?QG~A?5hYB z`@)%Sf+S&+8;D#0{cVO;)or-<>Wg*}T}`XoEkf)`S*7t&!fb3nt?q4psUCPiH#h2u zX4L~^rftOB5s%mLb_-uHqG|=nxg4VYejv1g`NSj{dzpShu`L99H6SEqP%~!HX zS3XIl6YE`_L~vQOrg2AR%riW*(RV`Q1Mz8*?GD8nd?GBDwk#0gHUD~@6ZijULZ!>i+bt|IMv<0$cR1zt(SzUh1jTmOdRlDbCsp z$^;WDCiSOe2f|bcm4Pnk75}r!^nKSuaJ!~Ai~R1*fg#|+-zqY?K0vu6@_`!Ab`qk0%bL8y_dH=ccelXp4dO08ncVN~=Ur8f@ z)Y%{3&;^i~3uhO_p!SmefUmY&Mv4mimGwn(;2J;crL-{IX7;1bNGNG2mh+9wo~( zm9idF>i51q50~&IfArXy=JU}d#SPq|1726HjrsTbq($ON8V@U;NTop{qid?o4j2uA zO_nTbbOwhsQd2$hsr#nGcw8!&uAiM1L@gXIF%267T_2#b1zG#?w#^-7sA$c?F#&f| zH3ex8;=&BN8>_u-^Cp^06bTiemEP1IY+4*JWtVnQV8~iPX>*4K=&zFIpu2_p=e~vw zPM}^i*cYH_(0tx!zKq-G8$t6I#q(*Ej~Jao_(0?-Pf9-Mrl+_%c1^KIN@pnJ`7MKU zs9w|CMbdzPxiOF+dR=2so4gTL&=W0D-`yUcciT-k>74={`ucc{6wd;v&@h0nz1n9! zPYuWx_#;(=ASnYQEuLQEf%ly%DmL7MsQQ*}x~pTCdmup24GUEv_pKtIchgOqX{kRp z9sltaVkfQ(G`&_N!bfbkpqniy?_~s$0OeY=1d}pIbW-VRo%qD&8t;fX1*!JR`cCwQ zZ+X1KZu)C<1Z%Iu5^E}M_^u~BNPdMs43MH$^xuU~iJWnkA3=Q|c(acqivRr=3dol7 zCA}uAvc~9z2&=b?kdqhYXiHh%?%A}({Yl(Fdhe^kTa$%ALf<#Nmn8yA!hwu_1ddj# zEnmkRiM%yNjhjks8O9wO6*hHNMSW!+QWUDOqCnGnlpPtZq9z<@53jWqe>Ml<{hc!m`~O=2#1n(!4^gv$-!9rsqS)m+wJ~nWO$b~S5Ia`mk)YU} zRLWYzosIl5RWT*Cx?YUZj|h{k2Dq!hw^fMQ?+sA_1kg{rl3H*E#QDs9c@ zRpP1Z-Bzcay~exKUfnFH3&is3oCa^|-{2Re!GGAN!4E>r(R<5_)Jc;=I??V7}Imz9D` zeC8JPy5Rs{&W+ynV__fX!B}24^Q!5Kd319PAZHH)Quoy|Ty<@c&smAORylC=SroSvJG6GlFH?_VJ*FOEJNyc2K;c)o=vh?i zg-^+VQ#lDl+nMN-DLFNWq}XzbMPdK-|5f2CB1zcZY@%OE2#YLa0$eg&1PQ`X9PLGl zVAjy1r3ZwhJkTQ1@dYboFyJMz56hM0pBRMN#Wm(O|7dPe>J*?bWO4ba{2E zO8#iRk|U}CscN(J(7L!tb#mK3pp)62iXzivLkx)P0jD9jo-EMEye^k&Dfu z<~gg-Wv_R=$~+`nUJE0??k2&rtU%*(>*fnos8)9*kF1c@os@ooP(79<0iQO-63|Vt zXp%;3QoUMQcJC?Ms4csI3;;x@?7txWI^Dr?A%Cq!EQf>C1x!Dbw;Hi;%lflgk&eaW zHd&Q+uSH+F!#ZL;maTe9mUHfWT4YVV+#^#|fcc5F%Y6C(!uzAgGIV9R)8Utwk5XcL zJOfZI1&!grZ;lY#ha5I>aT!;usp=_q7!uee$sbK>@wy;_{7z0-{p9zWu#(@u&>aD; z`JEX{XUckvicu3;PnBlGR86UuBT1OG0@NwKgloEadUfnJPecICFVQI79Fx2q)mf(Y zls`Z)WQXz;v($tG6urTE??~z0TZ@Zm+eF?VQ`P%UdqZ!r*eTm6O+qsz+jl4JV*oUw z7Z2RNza-mNpbG8P$juJ9_t(e`)-|b`FhBo}o4sHRmP(&#-)XwZP4WdXdQ0n8lN!`~ zrrLZf8j~LM$p#Xw?kEoJ0-26~DUbNf_ngb-&a!R95H=_MfM9t?%G@NYa?DN9$9^n* z?%WlBj+2akvjy|0?s0zjXmi&#k@Yj!u)?%a$h1_|2Fi5(dQ;Uq{BxO_rYG}7@FJ})O0muym3*1v%AS|WJSDI1Jx|GR zr@)?h>d#W`b7bkLRHmqxwfav{{+%gG?$`UwQ5!7#2zjq!0UubyVlpV%C-O&Rs!uV` zHN};R7vV`^tW~K8)a|D>N=Bm?_4Jo~ib$CKb3FC3OVE)3^)6=-dpwt>%Oz~S6V;j$ zMtEofumA#T-r=lchi`DkChtp)Ose3FOFu6aAsQ2TBztz zFX@xRm0W#TG|)dJS^bxN#`NMezkk+v*6OZf`cLxwP{r;tqA%uTigFGadyVE>)cfP7 zaL+$LwEw$^gP?%2r^*`9%-7|yseQD+NOOx@57QQ2MJBo?^L-_|1X@X| zvQ2L!)&UIlnV;ew5>=sVGf1{30pdLa3hxlc^4wB?v?vfWl#31}=NhGrJEP)cqOXAF zUig%})v?Qou_#(jk%&P8#CrjnzodPy#SOsq#mFaf<{q>E(smpsrKz|_q9Bz@5wXk3 zYw=BhrQ1Unrs+i!L?tR|PJ&GFbJcnTWcmys(`?}q)q+X+P5SA3BOW% zuf)%aMNCi|QIk3a)ofr-k{2Vy8_K2phf75rOP&p(u<HX(1WbJ?1@-#T(NVzNQ7-tb(has`@g)s&J$kjdBuLp7sG1qIZj zo?>TlIu9ry{(60tAgE#4iGh_!7yfCkz_{k{*g*Z((6BBRz{cku=F@bSSVUWpf_6fZ2<`Kq9PV+BEc6^fT9{DR(WqF{4|_2~KKXOH{28x%+rmU*$-0d<80J!gy5Xm_e(;#!?X~)K_`l=#@`qb4mP!!G zE2~Nl7^UiNexJZ^dFa~YL-)x;m-8ou1t)6pxGfS10#dPE2|uBNmn-PRG;tUZ91EAh zL4@AE0^?wlONG2X!3DQ z(JSwxW6RAJfszZ3d~rT%TXL19Qj0!qK}mFSB&U9xPaco175$R zs-mu5u4?tWxYzG)6Bzj$YFn*8_M>6}ljC4TTsZJ?D@($mY}ZRZGS@2r`F4=7^-FpI z$nn{gbR$MGMZvgpp%hw1KFRIC$6I~w5B=_)dSvgMdDrW)`M}37Wt49Y8RCp6X-vb% zgY`=o*=4I8_;_pyj=+tA9#_M9twN8>xCTAGbcsTbZw_Ud(-+$-(5-P;91^)Ew#22o zH|Q+7e0C9zarq`izNw=460^e!X6(sya>1gd+cRDPf(A&}tdI>v%W5RRh z-m;DTAl#$YB>~HADG0aR*cZYrY>ZAX9jPGPS8(uX5_K#6svz9Qa)2@~Pg}K(K)6rl zgw8%vFzH&|H;_|(5!g!|j!WUvVZh9?)dRrNmo5R8uGO7H0m5;sy0!@*{2F$lJE-ui zC4K0jd%+6!A;?_x+g(oxaQicfk@w6%#E8EqxG$$Ap=Afvias#%WD9Oiw%`c|2>#Qx z2%XlIX~fp%2SjgHM8>mUuFP=RIsGOT@7kdZ@jc&58R8^wKpa(yRfK?d=}HY}@S);p zQyRJC6PP7X@H+$w4ifwhL4qrHvMBL{@l9gErMsf_(!rKSg|NGq@)9w)L4~h$P~naZ z?r=~q`}>DaNQIZmvn<`s18XUTVSMMH^TbC=?|a)wRl$LRPbC=~7&w9k-(E~u$1yXL zAn>ZFb5ePK-5Uf5zB&F|;b!k!+MUz6-TbjUlm=T04m`<~JveZOBOSn{;>Hibzol?; zCty%m(^jOZ{*~XSsV;(A5>)AELAMAFd@jQ=Xm0vEwH0Al9#JAs!N8?*0t1&iB|F#e zMkuOowhJNDsg0>$xyc*!MQs8DKOV`!_2gCY>(2*_DQkOmXEDiAH&roTY)LNw+PP7F z``sHH|M~jxb}FRR4dwpGg2i*RNGA%6>0gYJ!W5FRU~&9IPJk?D;5xnWQc_YR;p9R; zU8{Og76GS$D`x_pl)SeGQ(metjGb zFFzpf$_uR1AMN4YueZUwOCCw{?k|6n=3QBq#rEEMZ+D_3SnPA;0ex0Uf-0t1R8fU= zS0=fj%LR}L)H7|AlgXDeYP^1j12tZwav=89=Nhjv0!~Pd04?IB46}aVQ4l|xi%Fi3 zkLI{*E4ttanxGKnxFa2>W2r)vPZCDH7k1nSQ7-UCwe6)gwe6*Lz-=$RL|w6{(y^hx z`_4g%x`z?aXVOA$efZ`0_v8U@ zmv-k?4$Lc;q$M2t@TM;o5b&8vGZ zXB7lTm~xObL>T){+5=4Hxt{4v*~e&Y_2Ra#*Xe9sRcNpVDp z6DS3SAu7o}A%gzGCa8acN9x~2{+j~-rog``@Wm+5gDp$OK__hBPNI%V;%tfWeW^rk zDYT~iwmY3t`m!G}54PBo$fZE$57NC4#ZMu@kN@&V^aLkkk!9m4l^aO9{>hv?D_fo) z%j{u4u|lGb^+3=Be0C7QW&~$$En*rVNc~(YfUbF*imwtHr6R9{hD>lViQ{x_v=3c@ z3hA=*R>Hu;1@$ zu4S&^c)0y$SF;OcBAlzD?C5`Lw9nuSIH2%hu{&Jj6N$6L4L>)qQYxkYsnZ@Qmpc>T zGZyYiB=TMJP9{l&T-g~kw=QaKdV5guIeE2{8$5>wB6ddjT|M_%z2OjvIc;{tuVZU4 ziQn*C$H%ZPkgDlte<%BS-x!0rKsyK}I6#cS>5#E+jKRAfbYcvG$vZ%h!N?y52r~F} zbbYTX6G9c$i3|yJtmC?K!BFU2U^j zy)ERfi5?0kR1Sb<6&e!dkXW&o zvA&lIaad}YXO=ax$`dfHpu%LrGHlDHdc0Y=K_B8+;I_4VmuH7_bkz`hborDF`5`T_ zwMA2CO7#(dpSOU$11a!~iUKa#5@g-T`XNS|!Ipyv@w;vTeai~j4JdarWh)>2nbF@wf zSw!o|Rn+)P)hCJ2NP}^Gw{%Zf#l&@Y6B!pN^c#6$@_i~x2Hq3a!){R77o7k|SL#!if}>muHwbqS`Av9 zuzjqF-G~sAyuF#x?D8v1LvHiR6Y04dDKx&I3yu4Py5*eh3pu(o9{+vTDMu#xBe@19{fz zKTr}mM~{w)|3S)$juGKcbB~fLxg%OadT@pCOVod2Tr%?T{$Ymcs;L-lXb4K0;(ce% zVS0n6QVL6`^tNoFXk6AIRb_Cos>+b`e6qaT)q4%);9Z7Km%P>@AL3WEbwg3{-eptr8ZvTW=^CAc%b5sV8q~USpDU*9RdT|J z4szn#RfDK#H9z?ns5+Y&K}3<7higrq2lDukL*TMLu9bxDwy*~bvYUN zDo)GVkm+iuMqq?1YocLPh46~XhHyKdPCgc&oht6K{-EeYoht4!(PsTCoZPLVT8t;b z1h6)LB_2sf*TAJwZf##t4$%H-&*T3#*Y%K zXl~A9WsCefcWpT$F>b*-cCnJG+d{()Z|mGalv!rW-_T^_D$<*rQo6ZUdZG`5`Fcqf z;=kXox`C73B5r_y5ET9ib<*jE)X0+r^tTjMn{&qheS9{6Na}Mc$%m(I? z7p)00H%%`1&7g2$+Y~39`;^j*osp>p`REXBg zA~GxAMO;|G`YM3%&d98Sz4Cmf9CgW69{6n|cZP{Yyw-Ynad(0szNq7CtsocxrDtpc z0%M61O-XmK!%n4M#1ND`BnRiu=+j_+9H7k=EWbEyKCFM6)vRLA+qcy(_iA+^CSS7E z(D2||{RHbcsa9Y5yHu+s_ss21t82C8e}AK;-Abpys=f}XIJ>C9$WeYMGQ0&upLx;p zvW#s`EeOu)*ww_su4Lgfy^=)t;+&FOi1%B?h;y5hixTa`f+madQRJfcVVR(;N50LY z*k4m~yj_dX265bcT_++vQ17{814!mr;a3p$lCF&;87h^Whixo`fQ}WkqteF;o00gt zst9Ml3Y436dGEr)D1(S7N5 zyb_)JrQ0H=1x2?NJ#;%vY+0e(F9x6+^NX_1I^a8!P5!g!mSGwN!bVHg?%QNsiVF*f z8MLc8L**2@im2niX_N%^Bwwn?2nEf+NUIQXO4ep-AM!dHpWyh*B~N^NqVQpI$0Es( zRy=^5NEH6SIRh*f`WY46N{dv!BD#M7&r+Z6J&-Jzzy#vRf-fZhuwXv7{4;wbK@b;I zFZqXY^e>TrtTz8$@(-i-bIZR)J*~bJ@08POCI6gO|HI^8;+P2}%f&|N!6CZH*f#ew?BcaYAgrw?Z+C_W;~=-q_43P<7iq~i%unP_HuDnH zwZ*BI^?>rBgwFAq^|fl)uLJXf{}w$Nhe0_HUIS(`Fpemum=n7AdT{2@Xo-sZ8j7#E z(;i$ViPTYXhLazC=fVnkVK~cbs1*nGNLNUVD_7FcpuuK!kx{nJa(`DU2~|y~YC_f6 zwQ1+!7qTe&j@!@rRoN#-ONY?h%v%1FH54DVT6p!{Uw#fzRIt1WDOjSjNrNw-v-t?=S*B@M?~FjNA*7l2GzWBeToO%#SDVRQF4ofpDU;$v}MC7X>e=54`Q-2$?b*sd_z zDjs%O_kuAK8A&ycVf&%l^VRdzkvzo}x`maZ?bOV6M>cT(TI>1S=+HJh^r%b$-c4bz z!^7tDg7aSp#8ka3bRjRI!V`Ml@+4VJ2mt5YID;GQpWvrDUR(91RJ&iK>AJbyS5D4zwpz!gOz7HL6U~gxcrF;bC=-C3wEm_{Y5ki1t*=QozsB8M zqen9x0=yt?U!w?6)z?T_N5MUfe*4c!b#f!asFi&O#BJoVVb6C0|`%lwN zukGv4V(J&p`r@k;2jGFe450O90Ma7B0T9b!0=B!r1xDA$s4n~C1MwiH7-4k}BUGUZ zs6|{D;UXEf|4K$+R3&Ysfp{U^{xl;D7e=7%DNgt@oRFqM=KiSAmml1{3DKHjh%>DU zw1X5O0t^0sV+f_cBH>uK+!!8Z{X9yo#JNlN{N+}um3U7tZxK-Ft7JMZp2=u72wo|; z&^#+7w~ys^djk?L2Fdt!rD~mCXmGz2nWVvkw|piIW*?viVjv3r;`L~JpGkvs4UX(pg9!uH zpbrh+yL10ENY}v4?780>q-Y=l=SA?Ix#E{veRJkRq*iEeKvf7Z(^-v>Q6^u-5&gDof6OR~RXyp~rnJY-BTf);D#*XFri9J3f-PO$ z(r*y*lLYA`2hF;jT@Y2fJe3(C>?dZb28nDzs(MdG3pez7ZiQ?ksA1*%nB8Nb9IJGTRy~~C&-1pe$L_Aveo)7 z-vyZ&AtIXIA+%hSmjNMVfAuBB^)75QRVh)?BqSS14N02pLad@mH&l{qDzDaRTi+{fU#qsSPx?>(Xk|A65&}vB zRf4n{pw+vqR=_p{tnBx5X71hHY!U)$-}n1_zYXlYcmAE3IdkUB%$YN1upDLJg{@=h zLSbR6EPZxqN$(FP#mQP{4E9(XaVLC^#*sjhAA`C8g}T!U+C8nHEmQ2D0&m7IHWeI% za88RD>YdtbcN=IiE|ex)Ohl6A7Auh??C$J^3se~($#}A=I?C#jqnx`!2rMKQPA7l< zbqJkgHw2o`>=>F(7D1LsODLk5(O80o08~DQn$xQH#u>3W!!!`s)p1wLtyp|0gn6h| z$cRb7&)2#MVG*V!I_1vQLxbBoG4~=mSH|QPIR@Rr;vZlI0QIOLWX1V$Wzbu z;DH0<;Z&6E#znnjAy$HD)$gvKuhTfssBwm(0kUzJZ!IBhROuw_OMyTi15-O>h5ly~ z6XW!VB`~6iwj;9<^>}Y^KL+_i7a7Z1g&2@K%|=NxNt|SatYjaTF44JECSZagQ;3%! z9N;(Kj@bYS!c`ePOtndB^Yl-}EpgDp!4KP@_cBi+v~1JupTnmt9jc1|DR9rmCwZXdQv zd*#Y#?lOmgI2fYuCR_0m_MnIwp0 z1QPdei&~g3T>^o0wVzTrms^)(^@jxK{DyquY+{BOgf(=&5wo3q%+Ei zu9!$NR3?pR%R>rB6m4KKOyEzh06=h!G_Z(tv;@1+-hfu#6)64^#ITk0Vx-LyTb2f8 z&k0{+x5G+#StM$Hjs&kQc9F>vN%ikR90@{ui(2e1no!jaanfEfrNi;6*lWHgiN#xzsKAOqh$IDArQw4G5Z-~&nU5_|IV=+1#Gz)aLmUXAdNDx}$ zO;$<9?Wm^T1la7osK%6?Bt19Hz168BQK^}*hKkLd>%A60q-8L8_XcSt7$JeDcMd(W zAXC>fz?^+{qQ0*a9GtM7dozc0o{C41W;2OgwG0u$Z);I$bz!j3jPfOO1z8<~zU z(=);MCWIo$AkPDT1y3wslTSbl;fdA66YIbei!O;LlF@q_OW3&tdDJs(E89VL%8YR> z==@Ez23w`DHwp;@jT-|;BCM+#KFlXRAjSS^Lttye$b61$|2rtkpOgZ7ia7Etw&Y_q zb^fz;1vC>kVnNZ2d3$3j@s*8GT5rV_zm5c9tClp=G3#(*?+F_h=8cW1*@%+SMH@s} zq;zJWeUU84ORz%^k^?Y*(uEmxv-6XwENck(M?oM30Y8;(#2wfm5e_4BL`xju=%IZB z+UaMvkdKLcNe*ZXK2)9VwUe<8MHeh+@w0mC8Lzx;|UAiW_!{tdqS(u-(V zxx9b~WlcA|_*+s*IBeP$116lk*PoPltrjK>9{T{GCnELxNKM1b0ePX4elyZ5D$!-8 zxpVGx_K}PYyVdj8LLt$#+r&yLW`NT2Ze-^P5=;Q}768fBrBnuI5!~HyEBdw{u4BGS z(Bl=KceqcEX`9}F(zhgSRVwjwust8sj)@`>4j+Ll)H{kHZsH3awvhrgQFSBb=U71o zvHazJNwL>%iPp63Z%Vv|z4`nS`zCeJ11mB>T_SLJ0~44d7OB@PofJ#Xx%?NLlTCX} zInaGCo}V#tM)PIB-$ju)${QvAmqwlM8nX`Lg8&~HcyJrF$c5njs zh1sN1#uE6-;Y;2992wuX%f zw>T>bbm9FzD32RXPR9bu+_EIfpY*5cG?jE-;ZIs=&}wk00ybc0ehc0GO*-ZPu1mau zxUU%#1e$yPk|l89Tsb_&1z`1$KQ@IejyWZ=NZ&#vWKQxWUjvHbsK=-V_Vf17(VoW_ z;wX#gIfo840XIP;bkvu2=X^$7#Yo~4kp{B-FHbXku$&6x9?*7<(00H?YEUQTt2R+n z0%zkwdMUN7@2jNOK!^}Ahb2v*UrbXmmIdo&9Ajr2fw3-*5~}WQa9~vTgP$qYJuqT* z!9*`<+*Y}07(I|~80vHqbs}x7Q??c(>UEB{aX(rXZJgv!dh8mt#1@p8s&}W-%v3wx z%x|(5+{MyBg|Y#f0j!ayg*Wn#5ks^#o}Y;2Hb zdm;1W$00w*X~_Niy)%$EDl=?7ZXC8A>mLiR$E!4Tgp%+@>+xR@xecnvv&{30)MFv? zzF0lJ_V2^B$M4sN*8_(;ECfi!X?s}#j>^K zZUdNFzO`kk9`6DW{EV|B)t)3orAk7D(UML4j61qn`^ z)A^#X3UN^Ty>$hwgw$`7`ITMEIDhuy0@i~+!iq`Sod?y7-i5fF$m%&iipkghVQYzT zFO|%1Y3`6#xYKd?#F1D(FV3l3RBvH8n4@~rg6kk0^2gHHI5Y+#a-_&q>;_ml7QnD<~OjV zg~_n!n9__S_2=W9v3s;}zPrpDQ+VjcdphR%7GnWhgdnI|IC_;VT%CTbl|~mrvyTED z(~-n?^-{_9mS$12*^~34(K#j|deKIF`bO>1UJYfYjQ1d^04>r+OO}aAU%u1{uF{sF zFIBe>@sMh9oL=tYytD#iLm3mYL^H zcaC19L-VSwyQF2p5}F>7hSnLuC1Q$d+79#KFp^jP2?X@mbntK!vS?-6zSzy1Ifa_} zrZUUiX-wWC3T88={@M=MStd{DyjXVQXg7z&PJyGvU-rt3T%Js=$D2!ycyhFPHEZ)- z$<*dTBW<9}f9V3lGH-Psb;2O@BT2yUg0QjHSsa?){? z6yGCwW|W~H)=|tQSVJ|N=htmC&z%SHujukeKl%X$+_tgQJ>Pc+a8sIEO=R+}!!5SA zV&MrI!P;Ldzqg{_&x0Kq1k*PSC3ytAcd3+cXb`>V5G9_~IOAO$b#IB8#3<%Lg=Pj% z8$z4>U-oS)@!&Aoo*$AN0BRXnQ{s5SQs4wA@K8Sqnazk4H|Yn63th-E=*jA>h@5?p z2o5QhN-?d#W=FGmf_|fU9I%PQ)8~Or3Rtwq+%Z2c1ej8zP~N2I+hy5G&H<4>Sxjpo z9K`#WmFlxmObz)=o^%%Xcc6HUzD>*HP?CH4!J^!b1Y%L6>uvquP_gx;{W+iB(UO3D zX(;5rYhu>Vt+}TKR~!hrSzmu1Eb1818ZK9;KcDCr4Mx9lyl;v%cW-SPIFvIE9D{Ao zP(M$!V$q@XptoD0Zs+#yrj%^eOZ=(MLS2s$YNtPG(v^%kJp$%br*SwqdA_{})5HLI zHXfpqhmfeD8CM(zylsD;o+NPm7ZjHYBrxE?xjnJ-iR;8ysX+kXS~a{F>eG?)QI(uo|~(2 zj>d8R$?z3RaM=dzO;9iM=nZb zMiJ+Ma%#pk$HS>M^+sENuIs$kImmZDAY}CT^k?58+>~J5aX?;-!CB%G%Zzu?*CCUJ zwHWLUl+pp@?R5BC{*dBy@m1%C<7i4R-w)RBeE?lNqYd12s)-h{PkO1j>Pycp`0Q-Y z)$Y`2o%!4X7|5q9AnH*I){UWT`9H(_|3#dD&F$}KnXt%Ka)e!A+KOukthonkSG~%{ zXkn|q%ys^1$1Qj!I+Lv}Vzd>UUMQP8(HSRfJ;a63O5#mW<-e`582=X$X80IQTPvDP8w**6q z)Ps+|LrDcXuao52N(Qro$rjxmkgq{Vft?zXuhBLn)A==hY10qouGdi8BSp57V^D#% zNHVNsTyQ4K->Kk;{SG>gg4lmT22F_l6W-?Bw3~lGm^}c874!0z1@}F}P|9aq%<>HE zz~U;aQM3Xu+FIrS(-RJ0_&k$iqWfK*K}u5tv=V{uWO=%h-*lEA;oJKJB3Q`2$trxj z7%gll#5)h0w+C+%USDx$ZuZe7lKD(J*~kSW$T4qxK6NwFnOh#gwE-QDY%&jjtx4K_ zwhQ?=C(An@>i17emfa5qwzIpx0`Yyc#}**w#{R>wLhchs6T(y77^ zpJwFOnWydd znOXj%Lu1)^d0+i&tW~0&I694eKU>R_skG_MD~M#vJ)eR{Ym8vq|itXvC&1v{`HID?!FO+ToP-3t=7 zcFP#cMU7)ECN5YIg2zhd?`%m}l$YCGyUfIRE!LK0u5(vAa`8-bPJ#%HwESzY!2CJc znE=(Feb}!->0oJ+O_HrzOvVIT%k9xvHq!*wWnUQ`s=jgDN_I>hi57`ym++AOy6X1a>k?^y(^H;b6iT5QTc zB~BA%b#q1j5kxM8UksLXyce=soFT<2^wcQFX!&XE(fN+aV=z2GY;u^i7BkU+kiz53 z!a9d<_Yh?X^$N&ytMy!#E1g$#DATAgw6(^{;|?h$j>?VZa2YY+8SUoJi!sHtd$0E9KJPuB$LyO1}C(pJbqN^kwJ#C-tc^I+T z*>59Bx`~ot|Vaxye z#^K68W>EQ`!st0-`E!OUf65mvKa-;yOu~*+<8ir5iW?V*gPvaM{pYEFI?|}cSP08l&dbYR$20&zW8_aUQ2@6c zDG%&*v)hNTM7syKHEk!(j=#q-ix*Qo>P1S%#ZYrFk%=`76IZFer(n{|vlctdo!&FI zquR=?OQ#mXyEcO~epb>7`zn!!RQju@aZShWJkt4Y!#j4(w{dyWd}Ovg8{u>h)O8(9 z^#(Vw!{oDgwo6QD4M|1H!-=G!2`B}zHz4(3(Lg8)hy8{Cte{MI9J~Fl1(Tjbm%u%X zc$Nw2xMMB7w@j!#G^b1y9&?uopH7*IeBdjW3HM~4Xrb>LGLPadG(vlXLb^T?-v6Xb zSpE@0b_?ISf%zUy8jW;kgcWH|vGh0Gbk$RorU&y3KuRlz3#U-Ul-Q2}%a)SZkC(Ok z7;cb9&Xpa2l@?1WzWE-<&8#xPmvlFSF{)`lQ#Mq>>i=6~#vZ^*22aH(;Uhk51v~SF|C#7k+K{?N{KVV)wp@-@6E-N_p@@ zc(77vp&v8QE0Vs?-ujaOne>?i@E|ADsrIcoWy1N)NvI^K<{#eEV6tVKoY$ZfiE9zf zEXBTzFxiN4&L^t(%TZ_@4}FG0r&H*4Wr6$c#9Tf7WiVFUd*qPx}(r;0+@F-ex#IS<$)6Qw!>b$4#jF?oaOZ z?EX|gWjn?FRG-;^_paloUz+lq@{xH1K7g=Z=3B#}-3v$e_Ksc0k8R%%0Ey326_NOl zc<(yC_m@E$KK@;WhIji4-a^p!*v%|%LF?{wfp*@6v`H^A{}r)Y=<>nhT!vk@*7(_1)XO`{=#L@jl4D58Zom_tApC?moKW zeV}p5_ZWl~ZSdvq; zXnJ?o9-On=do<~5l;&J|>+bIJnct>>^B_jL=Y`RS^Lo@I@%@dA9;c!h@)igUL*Vl6 z8=yam-NR%51Hj~O4vf7CWcd<;9W(H;i9U!vx8j4bI?#L@rLrNF4;NS)QL+H8hvngs zfG-~dxN}SDNNGLPi*YsdyKF-zt}VfKjB>au)VZOvjD-nXd0=Q5gKT&hzaULTY+Xp(S+Z^w99mffH&v7l>%s(E}zP;VD>sU;Dx5;%ZN_)`c!FQ`EUMa=E z`U_jTx09MOu2zs*(@01{P|PVFfR0en#M{r`$KAeh}~N8nmZZ5fTWL?Z%iqtJ{n@EqUWEu$ULnrKJQ zvDhKnGNqGKnffkE=>)3U_N(rAC0u=%#q;nneA|7$`YuyGRJY_ot7CGDeIYatn!ESP z0779|%X2K5=S%VY{)KLkNt#CE7Kkv^m>zF3qVjmce?#<)DY$OC8+++xDJoG0{E-o5 zz}(w-oDPbgwh+YtwZ^y7d|3Ez%)A2yQR7oQH)Z5#9am=(wVkvAU5<(EOYf^69+DI3ST@nHEBU*7R=BeYh^TOdX-2AlsJ=9 z;?klHsYgG zmjVfyLc&|+9;D;3))A2@i z9arRbI7Z<#a$-$E4>Zd7A#l%03WU^wGs2*u4p^}# z%(g+OXrymo6r5xSQ5ndnLogF(ANa=-1e#%z(hP}c1}#|FHfn;lZAKIbPx=l`&Dclp zLR0`9m3nC_dT9u|M@7(5y#G-j(DNqDKFB(m8PZxE?*WV}r?i?{mMA@el`7B^SVdS* zXayakC%_t?2jo$Nre$5hl+sGKHyA)bxV^!MS0b)`GwCLlz@I@J$rhpze}RVG#XoGOT}=@4e|ky3O`!#+(1j!`nfHSO>Rc!8>` zq}YAONu3+-!Y)cStcydEM)uh^BRbSdmVPT5X9$jBgYX$IZQt#MFbO-ju;NYzUra3z zMTvstJZ`IpPd~2U$eYw>OF5l~gNq4byBo_Lzc&wrgiVtBMmbkQ`#^v;kEL;M-BomA zTWe_=3kO7BIAqf1O(BwN_N4aCcjLbCEz!Pf$aQLdFS)cnJ-PblpAt5FjKZ0=#E?yc z?YLP*lhGl)b?CUMxhLZ-Q%bjQrlolijE-MnYQAq2`0R!G(ZUn2A)0aCpM`JIxkA&t z9>Mhsd+F0@ZRG-l^0n@lMBJqRG9d zF}a3rhHz+2O;?_M$0{9U#{=Jx*J1OSwvKRCv{Rl1Z4Gv6gbbG5OkzPCb7gxvIA8dG zZ%b#8JY2OK{oh{)1KBgw-7@FCGC-cM+Kt`{Jg^l8I@G@NVH}rF*N7^{1>)1vES0PSSL@)q6T%FQw>We&;TyB zES|g*)racbVqMcC2C_g2Au{o=VN_%XupU+Cw1DZ7Vy+-G(v6>7@cp2X_M;)628*U% zqu!j5Eo>#@O)ZP+$tuWX7`cF0=X&T2!2pH{77Sux3&VH4@JhGu8&+v!4wCwyi3fd5 z%r*|z&JbQ{Mf?ks0`c|2D=@>WoXMV`^PvYH^g)-8C8dpmY&wuvO;ik6P)4LD+g~LG z*&@tfEDH#$W9g%s@3q1}21NME8AVL6nb>jw1}@)`ebBpi8R-H;Rd>VQI)m$6 z^ka#xb6V$>QtXor(Hh@0DYg;sro_j{HD3PutpRm{Z_ZXXNy82_q8JK&2kedkzJbnd z;t-Q`#Gmy0kD{RlX%wE>gF52AlcNp@{P)SPW7k6d#~gs|$AHLphZoCEsQ<#it@B2C z&P`-u)G<^3D|)eQiW<> z58Eb}aXMs#x_CbfsSECK!3GcN;!pDa4Tb>I!z=S5ipDFm3PG$g$-`9UcZiD0SibsY zRt9Zjk;ddn81zUnUwypozCmhSVj5Cf)+A z$P>aV^Ih~nUYWZQ#3~arOl3ABDk?MkORbFBUumb@2p1{3AVC;b5th-<(`1&;h+rdc^N=RNRUT)oQ+Tk6IRg(rv6b2 zs6aD=w@VC6A(h^w*q+1C7rP2kFjaK*U%)*x7(}zoEsM2y;{k^pFlYM)&G9IE9XN3pAZ^z7pzReNf29bqR7lRFkD1-&keAK4>z7d_`=1GRIS0~>atAavg6Kd!|a=Y2%!E3p5c z_#YL}eJ|1F(G5tfmXL=o6j3!)(XCWZ2W4@mdpfb>#4(Iy+ib+T`6dx{eO33>G%}<$dM!C)e)MIz!-kwEe!_Bo@ZW}Py zhVIOPxqO;^(er+<8=J4aVtM&KZhoxMWi5WBu-Pulo{zO zi=7ByXSQf^%CtJF<=0_T&^L?nhJ=%{#|>DZ4oaV{&<74gqr3+B575)%8gvCikc`?L zhkYyKD`Zt+ZT9Wb;o9toIlRrbV6Hl%zL0L-5N-AeTDz&>3$&S1e)T>UC~)Hl6KMLv zUA%ih;pV81y2$wQOXwmUNEPTJuM!A!k=Ft4W%{Nr^5kDw7x{%h>EtnDm!&Moz$U&C z!sIK;036U&!UR!{MMTk+f)OKBooRnC4g@pXvGmu-Kb}c!nrSj|#azhs#*?kAD_twG zR&=d|z8y()Tq|`N*OFvEPjwDGkejF+Mzd-EewQ_w6tS9UmY}1FLX&ASe(6t`CIrYA z)1hql6N{LK2wsX(u`s2ramOjUg^zJUQCjd7Fh5Z`EtX_1q%T){GOpA6Ol+C;v6%ZA zKLI96Y;L%KT}A^{Lzt69OX#n|;GVd20(_+oVTU*Il<@1N6P%ww8?mn|HOg5)krt#7 z&f0ap-|Q#=W?GiKB%7gWM(ga+^6v~(VHl=$JF;A2GP64=2|G3mSZcaFS@P{z3?py0 z?l!;=@O}u)icQzhRejgOgI3%$0+X^L#$My+CIp2fXiboVEXWybSG4^YD(c|22d;(0 zB@?7YK@=pi6~NuT?Ok_^!?v?9Y*-o8u%JTNP}hp%sQ@ zabZLh?9324`dXtMvCwn$jz?94cn9r+P9|;K9{Hq&nZfI8Tj*E{HQ6@l5JdDO zpy%kXKL%O0ihOKQ!q%p_gP}ZCFSW5Eb@C!0T4!HdND0DNLU=Kl+q(}fh%aHsnepD8 z{Cj)-RH%F}xq&E-?ayIDgi!=Y13UUCm?gdyMNz2&6^-sexUK7Uf}^XG@`^A^}EI@@K& z-eAg~%<*mJ+*YA+GpLw&)iFKxzJM*Fx3{r1Pepc1ot#=(VOdajYP1@J{i4(;CFDr_ zyNpH!^ARLVBN}z2BY0rSb;>JC(F7n2(VsxF@3GXfN zW@uKLjiJ{U#{-{6ptKK7i~56^P>Y&aL%@NC;`|$R;h2*do=E`K_?~LojROwuwN9UMeZ0vhjV3S{YZW^YjC(inovs0SJ z#&fW#E9`iGOl_Qe4Ga3zH{aOT9_6@_yyI#GKK+YkVHbP`ghe~9rm*jx35Q3Ov)Ty0CW8vU)E} z{`DdQVP-XO8~fLrFhiuxM9ary>EJX&I~&7H5=kiJF_5)Od4;qV6A52N1-H-vho!R7wf^yF=Qzo-)75(d;m(&`9oi<#PP1ewWCj5V5X4MK4GX1JWV90v zm`}b2`3{o8?_10yk#k@?6Ei{N3Y(-nPw4>O4^&CZR#EgUmU}v$P^6ZB4dr1Ut=$*0 z8Kx~&WHphOVBbeAao)$Y757W@aUuP8sa-$ewu%(ozj=K>6_k3S#BqNEEinGI zxM%cElO6o&G-5o&dXQo;5>TX5G+*;xNxrOb0bkzyY<{W7+=E1*v7=UDQynG_Xjbu) zrWl-N)N7I{X-WqgCkEn&1k9dhW$zWDxXSun_*dr{*QG;>$U6|sePH)i!>sCjj-I!=qks=WOn$* zw2?L{r&DZTG6wIEfdKYVX-BnAeg#rOA$^aK&PT%4m)M0BTzvG6OR8gCXdSyk>R5$3 zb_mP&qTh*b)DiFeZSBS_ypAspsw3;aN*(cy)4PM}2tj{7tLbLc7;#W9s%gI5GbvEh zBD6!@CDwGvy)SO6y`L_3@RF%^T%F5IwZEIw@6T;(DTsPB8iH>W#fW8Wz!E!lK}xZ; z0+Ees$^8w+%Hga>VL91-40w%1Web~|7drGEZ6jq|Jxr@iS|m33)L40e1(*kkU1J?5YxYS*z-kfqB@ zuR@tJj?vwVyl>)8M2swlBCi&ibuiiUy6a(`3zM6df|DEU+{EfK z)xmZuZjgMOCOGY2F3VoPq0}GY1S}dF$JO^%w1+r!>j^9kGt$2U%>3-M?}+@ ztK_{5#|xOMn6b42FN1s#a|i};pL_=5Fiew@AnC&}ng+4vGz>PD9|_BklH@;KNPk;; zn{hV-CZ|8Y1&fl2_;?N7bg1@qx75o+8BY;0UHkk;2>wv$}gunJ_9Dh`|0RDi)M|!^;Bm(8wo;!`5Qry!g zdFJXINq(r~#J;>1=9XPxSMi%<17rPUh*QuYG8{Zcie@`euj5w}V*K)^b`F=!%(FG=3#93EIk;tWs z3-LB$Nqr5Du{!Gr!8jRsL+nXZ5{}sW)sEeNP(zqz^HxbZc%^fU?2Vy{xpf)2X?)z@}1eRe$LroVWsO)afkXW14;$X@&YcGj=begLsX?ciWlbM1H`G#TVyYm&fV8{MdBP zmH01aDvFK)%|bbE!&fzDZojA5gDX`3LgBgUU9cjInk$=&nCHA>l1^tI+=&UcyXh-2 zqGZuG!PMv0I}*vU^C^V8#F!{}MJrxUbFXN4MJZkot5U2Oc*Q7QFv&z-I(X?6 zFEl=R>A^1X(}K1~dwOHec4eEO$gH1DiYaQq7@XKr0(1ic;&3KG35XdG5U+JB{?YIU zbb;E0m6 z0iJcM!n3YbcouFi^5D)70-@9TX0Q*#1@4aaUB%t7RZZbhJ`8pEF#MBV4e$H0TjhB_ zw!tt}a{x~*HQ^J1-PDlBt!7i#~$&z@Ri9je7y9gQ&7X7sR zB6>+B;){B3S>vu#3%J^-wB$k+3D~$R17KghqUip>M)3zT@aSnt#XBH&ji@KS7Fe z^=h$ghc(<(dW@xYT)Nm0uPMSrY%0Y`#3N%Ytc~D%EPW>ebqy*0AK@$+VFh{SUO zxw_6pIg)UFD-gRbS>8OJ6k4Yvxi4ORnmMKsEZ3l25hkYu*T>yAc-{kBw4wwK^kF_G zAr%+~$=)wCG~9Fbjs+&zg>6Z^wvtao&7jHg|)7?g=tUQUyxSF)rwS^gqf(wi)@WSP}u`4Gh4WH}{S z<}_LU-t<71e0VY{-;&oQ--0?}T1`UPm!J}W0mgF5_ivYvZe`zAPK7K_>T#V|D1U+t zT}&*o?g$7_2uB09!QX+|bon$%(@tTK&B0~b-3@ymulM^?I#NE3KY$@NtA4>6tPnJg zv_6l~VUV9ed41FN#1@bzhVU%cv7K@~JV^%Y!y&|-at*n#I}O1c(KRFKkr%gteP_8C z!xKoTF(?Z1ly7xZrR$qte&O${QP{_87CGnyP1E-+crNUV_ zEO|TGD+cU2V(#v>*NHIhS?zaBENi;vb?N|3>t^k_oz!`-VDdf)1_@)lrq}WjQr5KM zwhQd6g|%rEY~T{=^O;f};h)Gh3x*?CjNAqRBwxY@8?W>AOkz$#iFRWTosYp98x*$M z!0c-S>8CB(eJ1GwNhb7UkA*HY`~}zn?9|StmdFfTO2Qie`js{u1_RpJO&@#ZE3j)p z=YG6cNN6lMUr&cg7j%|($R)@M&1xJ{NS4HehI3?X)0s+%i&(>vj#Lpe&uNB>SZ~VT zM+Pt3w%{-YhQ)7~#gpSkp(xKmokQ6024eY>VqYh{%WpW;>lNs%66$-i?-d-) zA(L#Yafdr{yw2p`YstxSOvgzYJ=Ft498CSr`O12_e4avHr}u`vzCT(ru%ER!IZy(N z)BzamI0q^(KM|`G!TA+mGnG!Q*;v#A6`JQf>%AGRV@ByYetGfP9bmFGkXo-?aX=;Z z#!_>_tPZFN)Lnr|oC}9@unq7f)z#9t9g3bV_Fx^Tg_tA*r2l0pO|Vvc~X1^?^Xp?#6Ir z$qBC$X${2+dJR>{5UA24Q$nf)S%O=cZ(FkXbo)K5>PFPHd;W?c>h}cm5^*DI3V5Q zhJ!-m_u!3zVLJ&Bu(XFd(6b&a+4Rm-fJxB0F^5UmaPZ;Lw7*9l2mO2d%&BAbj=x~P zNhiQW``8^HW6PY%j|gL#z<{0drxW+&!>Xd&@$pW!nQq2p0+4BGMs?=s+R?iZ5C+7@ zIWnA618gJ%`Vh~Ss)xw|;FW!Yu>(O0l+g57Hh3>+nfL;^n3{$#U4C&!I6^2dFvBrr z?vZ2Cs7#rZr`lXR&UV(c)EE?z`6a_f1q>CSl^JS=YUQEQA{9@*opLGDc8>sqs=(p! za$?fw@ft`0>(t}89Tlguw}DPHZOq5dd`4|UkJGf7w)Hnk`-k+zgQ^VsuF_WTNa-p!uN*mF61 z-pii%v*!csS;(Hn>{-H|cJ^Gwp5^TM5PPm+&nou(I(yc#r;|O`vFF3=`3QTiXV1sk zvw=Nb?74wGpJ2}>_LSJOg*~5Q&wpdjr`huv_I#E-zt5gOWY2$R&mXbpkJgL4zRI3|V9%ZG>0!?{_T0^$?d-XiJ@>Ka z8|-<2J-gZS5PQDGo`>1<2zwr7&p)&0d+d3PJx{RbU)l2m_Vlu+k3BzP&yVp08Q{o8 zOQLk*tRJ@csgE%CBVq1`!rb?VxtE5ybHm&jK{xie=SE?^*<#gU_V0pO{J*PRQ(4oU zjTKj-3qa-wlWCxBxd*~Cx>r|&%>b~L*k^8sU<2ny@bV{}I*vma6F=Dme;Dh_w@oL(uG-rBaN*mZd4wmHYa5??hwnQUCXCIRXWb$}1hR|CW%gaGtndeK@8 z#|58424Z{cEO^l$^A40atRD^GWaFr!g&lk7HXKBznuxjWj#?^fIdWT86orZ`{4Mgq z9xFU?@6~%g?93p{DeZKxL9jHE-YLaC&1``GVJdZj6&fo(mgjOSg>7qjbutN=XTY^;e?d7 zmAXJ`t}sW?~{^ zq$TUESZ2{Tqyg;w98MuixOo3H0`r-j>>JtrXx73QAf0r1I{W!VV6V^SJ*OIo1;w|WAyC)7;lvGba-#% zv|JMV+MkJnr#y@o#L3c;x!+CxJBs7D!z?u>6ZP7(Z6?V`lZ#xaJ=?TU6X|S@68)Y= zxAUwuqcaccA^yFl<|r%k>dVX6XZ7#J9Wc&06trQl^J**RFknL<;MO)1%9Ru4Oh9Za z-ED)ieF*u$82qAP6zPvvm)qd`_D~od+D|Mo%~yu9{g7n0kq}0}wrg`V<$_`Y16Jzx ze-mDb5?+bR2+IPqXl#tX?$KrhpAb!cw-Ej z#4Wl`MmbN3(i{GyykFrOgQm$h%d4?-&jwhg#G#%QMbAV(z8qbS&=v{uMmG4p`WWyc zKMTQwQo)5%K>|dMEwKV>hr4R%NYvc;F!F7gv(JYUVTVW|;-|!pTx~kK9OpwER3^ru z7WEQ_Gb#@kl@hNuEDP+hGpRXl(>)I1ogAG6o^@LcM%lV|&H~MAbt3q$bVq_sdq%oL zZ_{>~rOFASwiAo_UUY?%c*~@#=CYsCNMFS%ElYmYDEcqW0h_mgQtnJG+YutRt#`a4Zy}hwu09NVNJn5f#8Rx7Xzt$q5{bSBy zsj|>@3aXr4jtPs%-IDmnBW&UZkUc)#B4KOHITF!Ju|H|S^%qBpkfuTxV+-9v-F^h@ zh0QO74J2DctVa=xE}P%*V=5{UKShQXfj{Z{EH;s%vjW=$WJE6epg$?@7X*ZPFY_lQ zzy&csAe~u`IY|(J)}K@m1dtJ^wI3R5O06FY)cUIorbYH9vQo8MpBRM+ixYM$a3k$Y zEHL)qlZ4Cly_CllR7j@(<4-!%qg3jsu;GWO#M}obIA+a#aI#~DSaSRPhWR=97K}_+ zOLX7R328pDx-~r@`;!cSE+1w? zZyS?$Kn9g#m1>QULy3?>saxllD~}58oBy}JZQ#+E1mQ{}NJ!W$h|hpr?quA%!6!iZ z3AWsWm;i}7ZKo}_yJjq#0J+r(PzX03TpPxFlsWei7{B_jx6w<$LdM20Wr*ow#(N4= zIRy0xY7Id$rh4S5XS-kwEO_X2IJUAa?>?-x=SDdV%4pNT>1^Egcy!&exneSwHzN78haCeMj9Hv;%(8keO@OAkwA5d+XKI7+8$x{$IKwnXBYnp(~1`OJH*+*@d zDJ9!7y7GiYhwL_KavIiZn!MaYwO5wmw2|giUdsE0pm!>}^$mWMN{R3Nk@ zppR58;;mTd9&|2*DGkh@x<%LVQ#iqA0?JT%6VN6&qJb7SR7srUMOUkyaH9Buf<6*n z!=`_0n`?m_6|IRDT1Wv6Es-Zd*S%M;0-V(0Ii`a^T&ToBOo-3X0wLgmS%QyX-WV|C z%6(t}7ymn)nZh5?4nRp&t5w^%;h;^h?6smC6faJVjNrpvSiT&RJZF1SJpPW9E+h-a z2SQB3>zdqFLXW9FN8|VqGh9f>1?LASEwu_j%`4FuYZGlHd-Jp%iqo-+Xu)^<66o(z zqmUXo=9jdqfR!Fv05c}qum#_O)_^~0^G`8T87Kwur`5vKpXOxGb?o`lX7VBbOU*bE zFM@#x1|k@UU?75l2nHe;h+rUsfd~d77>HmXf`JGIA{dBZAcBDi1|k@UU?75l2nHe; zh+rUsfd~d77>HmXf`JGIA{dBZAcBDi1|k@UU?75l2nHe;h+rUsfd~d77>HmXf`JGI zA{dBZAcBDi1|k@UU?75l2nHe;xMU0j&oBFXhe{L@o_5`{kpquI;V9x4!9WB95e!5y z5WzqM0}%{FFc85&1OpKaL@*G+!2ezhh%Ls726qm*+k@_Oa&HZ~jpTm) zStUN%Vxqf)4Y(x})+@7Q@wK!5O`>uII4pC)vfo7vD60A2^#=u>)SM6aFm0CXZT{6@ z>uq8nJj)xu=VIZaSF4mcwDpiai^~6sJCGl_kzcj<(0>dGkA*jQHc_%I;Zab2hM(`C z)|8J5|Eoj5uMJNej4vwiAN@gC5mb1ihJcqcGCWOq6cyepI|r1P*Z<$cG9O&NE#XlV zcqsoC!q28b;R=3gUJc}Dq=+{M^CvgU|L*X_JbxCh;3q3Q3i4ONS^oM#;VmrO>;0XQ zzv4a;=05y{ zMT3!Ti&1%tFwlp~c(OFscDi&Mx2#Mx!}zY>y{LXZ49E7-Z5u7%AHElee@J--(1Zwc zwpqAW+%W~_TVYCny{H$Sb~n03!LlsNCRvQ~A9(C#qUbu$!yGr0;cajtvEe-3Y)}J0 ztut(rso$E>A-0(MMOXjSb+J~d!#7I)uOFit@@Q1<(peU$^3wlQ{&4%#1M$CdTfj{S z^4=A6*ONQ`4}oyzzC~dSfM=xe>B0ESeMQi1pz!E0_nEB$cr5(5;%4{06Ys_~f-uMm zgM^7Ldlqi$%rnYu--iv)F!rs|(?c%?;4ymm%?`z_(nA&-4_Y>(F!D{WgyT1BxFLbr z_6r$L408YP!xN7%o)jTVZ~K-&`MSt`_PKzYg})FC-$LPsmGA&Qc2F{)Azk*O^xP^Bfu-7@@#!MP=8A3{XiYRTbfz; zv%&B!6yC0c2k~(V-V7f{&>$DXM>VCtJqWLt-0On*vG5tea5sf74+|e145up(ytfQ0 zkBnp}PmXN8l=7VYUZDQ@l-~zI_ZD&=4!T+Sq#(az?yX_rF9hAal>S-Ot;{c;;O+qW zn)8edXWo|;M!tW4NSHx>4&Iv-tOf#jivLzfL8Uns%)3{V#Oz?Eqth918EN+Kaqqfh zsg{xbDossC`)t_El9*9GspUC*+oTPf z$V+-=BYTaJr@eO8FOMTAuA*uU1`IOi%*-yM=;8x`D@N7&5B(mZ(0};Nu!a5!1)2lwbAeeTG0qD@+;#uH7{ZjECBxe+|z}AA)(ldltIrI8+LDFWV#p*|0w-I=A ztv6_#^F-<2DY9bQIm7h`DwQTJHe^zbT>a7Ol0|80x?BpjfH5lmH@M$vHM ze}FdKNKUnq_b@m5Ta%c6Sv3ghl4291b=(YSFiRUat9hoMYBPGc+KBQin6m|HLyV-QnTF+=csGp>X#;q zfp>wh=|-TSp>UrX3T{ZgRYQj7iJ~-y7pzPgqF~^tfe4n7BBYKKK|4}}#H@6cos>vBV1)YN?U}WA_!-}5O8RG4s?h)8wXbd z^Nr_F5*1PBLIgkoObr0?@e>1q@M#rtp-Gdsd+5*tc^d)-POJjp*=2Ve72gPE9}Es6 z`u>Xt&mSVVp2o`QVhN$aBYOHr;r5))&M1xR*g~--VXr8~wAPn)JU36uz|xP%MLA~`Bj1A)P+=mL$tDJW(doYeaZ74G1$HwK1b&VXrYkYVJ6!KHAl zOgVc0ZD3lZ=_n9QcjdR#OoP-F3i+Nu;$ZmpV1;&KViJlAUa%-WTXrNgHmXf`JGIA{dBZAcBDi1|k@UU?75l2nHe; zh+rUsfiH*w$bBMz|2r|T>Cc*a+JBAwMKBP-z{nVgi5oqjzkKz^f&Hgw!a(=P5F;@n z82JA$2JB(|=k}CH{|Tjr4>BY82*pR_JA#1-1}+~1b`$3#Gj8DT?MVaqinH>e%Bpph z276tJz1mS;RjFk0^!S14-cKEvZpXxnhp#LyH5Av>6hCaJw68N%*eh2#R)?0p)=^Vl zxyscSJ^A=HRUA%_sPXP-_g_gJG?&Mx|RETCi8dl9RA)ipTB>t z)a$2LarfE`{!W|C-+_#jkILfe^1@YiM`1;At)tLhQ&Uw_SYBCHrN*<6&%Ake*w=9% z7Qei|%)qbx@a)`W($QY#^IR+bjewcldToHKWJcIKSYl_i;TZz{EC=FFX4 zva;;vn{S$%W6xv>zFJ%nfTkG$uWIGj>?IB!sMMdm$cN=yYA-9Vv=>&_R8`w+9Od@f zAfV84)!57IHTKF9doWnD#$H=nyejC!<5yJG+6z|$WfiDx37`g2h|KeD@|!pBu@ILM zBP6}OwxqbacqKp#0m-5UhJXOTp}Yfm)5lkpaXOsdjw}6RnnGudGcJwZMo;1K!r@(U zE%#rkz)Mo{9f^MXlzCM+Jgb?*n>>%dpHJol?rj9eX5IVYu8oPl&Xz(mr8T<@40o}ynss$9`vTe zOrd}I#Wlri><)X4VMeXJW^H+ieTHF;v({l)X*U!bcuyQAz7q*5k@%tsLg1@Kzi520 zru@(<)`q!D?G-5PfGDhZ=%A&czT{q9V=uK=I?9VHf*sa8Z$+2L`F$Q8_+#U=MBLjGwQW!&7c?A%zL{wgD z!GWr329F=TsZj&g=~VRV?R7zhp`;J@H*6fk(rsPH=`1B|oLn}{IQgQI?z_r35}uBY zgB2B3C8$+ka77t%ns|O&l<_%v9M4y+C8aBKR+dmI#{89l4kg_~xkHz;pqayM945S9 z3BOJ0PvPZ#PU7izE8}Z;c+QhNe8n)~9ZLA!3SS9Nzq*B|pEPUe@~ic)v9Ge%@$ojD z4M&9~RTUK&?Pkt1+_Tz_`AT&Sh6;wAs!9il(2fa5B}UA(#TDhH1|FLT2_0Y!s2T(5 z8vFGs_(AU>@^d^~eaX4423sg0u26z`LhT57QRaj5W5d&>X2>I>nrg9vBQZ z&~Ag_R~KV0af$HL8T^@-1)s`)(dG#$|04|k`pbh~TsmSFAp~AiT)E0l6U1V}BcZ)v zm`n%bivhS8zCtn!kePv{nq{bUmaH}u*Bb6$nOXb*m10d5#z4&Fs%WlTdy$GOEjYM5 zwbcRq*4Pc}0KB}i)>&3oUQ$loca42bRn5a-_~_b|YcZ`fI0mwT@=AmiW3Z?!ci1r! zgI5^V6ql?9XBfFSL-a>*;2L{1CfLByot1V&Rhi+sg&B{ql2ukY4B$T{7@|rID<4L- zoa>-g&WhrikoFiZ>%sLesajKAVXrH9JghWI(1Y?uYZN;i_BGWGWXbx8p?DS89?)Kl zju@UVThOuM6;nwwF)zR>Y^}XwxB>-w7XKJrK44VszZY+xQkovE0oo1gR@>1?7^Trt zLlhA+wFUQ%9Gj`{`Zt=9f^CoK_1D)!*=f*;h{XR6g29A5h{hK)KkLP$7E zqWiWoP9+Z4hc zKk!lAl1 zkFH4wbL+$6PY4T74s%Zqa~l-5+8(pQ!k_!?!182;h0h6d=O}Kq{PV-y#xS>8ach}q&t}D~ z;;%z-rz!FK6?dxQPT$YVr-m0O?hGY-lj2t4Z&BO^CA>#*PgmT!H#od>#cfpFs(hnP zaZgghH!E(HA8%3Isc+=@Fz~$~6 z1MX@^&CPQZmj>m8xCeVi>b^r^p|cW#o>dV0usCX{S~1#oq5uOIfU-CX@Vxa_jb{FQ zjb<9Y7rpbA9{{e!_oMhdh#&nGtu1rV z9>omqgnMO}n~%W$MI>shV9Vd~62mHIaZPC;jKSw3>VO~MgC2k-_&Z6Y zs)Q6N0#=4T5-1Id!3$V~y`Excg@ab*DhLR{s%o7zfjaPfQ7o*CM}(*38ww8VdDb?8 zLIYs1e1TktiWZ2+t2q)>f?HnWZ~}v+<+arnkVr7u;hN%V6)*PHhD#}8Q7~Q*bB4i1 z42gG1MJ&Qj*TWYL+J+aBgbm&SeFjLmID0OFnziK$%5{Zs>0%R#pUXb zp30}^FCfkf`nw1G&tQf;yr#T5$i6g&Ma0$?GiiJ<6e2W(Izq7I1LB!TUqQjYl2j}Q z>!~SO{qPW3@cb7uu^nWMcd}h^gAM#Qq#Q-Xl~t7wuc>nKO#vq4RI<=4{^~pf0hu>X zqan#2ZEs{kY{fSiY2*R^h6`Y!8jYeKkx9bybfZq&cScGEmNP__?pfqU}WtxQx z3m237`s=UP+_B7Nqwh2fvB7e%oWe>Ok}ul;39m&+I5tmLSCtNmQ0c6wz=%)TY1USi z^FbZo!F&T*vN-E!7&PmtUTcAD;??%LM<^iRW-hpkOTUKg*{T}VJ%AoVxWQ_B1*QOM z(**NXhtkqwM==SZSJEa=$XFMajuno|p`v-H^uuSXCfAVs8r&h^R);0kqq?SiEy#rv z5Imu4;lP%ty;Sk3cCM@_F9`%|?su$)YRvyCTr-OZ5`VM80t}T^T%3lml4_@>culotmVwuW;UUkY8Cv zRWb3C(kdXyuF7OWSx3oI(cHgNq>cf>u#Q7V4s?0 zcPzc*&gFM-2cE&!LY_pnN{B&iFvVS@l-FP{sdXy7z*$M#t2_dqWpM}JThet_8`Mh~dL5yb72q$-Sd1WD(0QtKd8us?^n|E(m<}M##i)tzOKCU75$k9(*~Aj<99gx z_mutgZz%dfZF(NBPI;^FFXtVoH$I{QfB43~5RX8J@HKG zldTEzy@ButCR1@izPDA>nn>*>G)7qXZ8df<-;lqs@Z0SU=pZ_Sal*py4h^Sv2@SUf zrqzpUFu}&+^KJ}};AfV)kQ{@bv0yE#tc`r9z)kI}{{0{J-UA@2qw61@T^3jnWd&5g zwstHib}ZZr*s!384NDXh6dSI9ibf+E6H%k0vBiqUf}I#m&=`XqjRj3iFdBm;mc*C^ z8}|P>ch2lyR(O*4`=0lEpYQ!=@b0<4IcLtCIaBWJ%-nUE4W18JFPK0V*x-dW7=8=2 zi2NcOyx0bRY=ie|i>BXagH@*d%Uc&4Zk7$UZNE-7e67;@85?xj+I|OtjE*@dl8Hs) zakYd8k#32Kk6iq@QXwNK)@6FO6Eji-)Qu&eJo4`XUj)Qvz@in~$_qI`QQrSl@%pj< ziC!1O8nS3;|H|Zm61N){-vPdlg~g8>2FH(tMqUoon|#`8m*5)d2KgeCRPI7ZZzQ3= zQx2bROP0s{bZ4ygAT|IN-+=y(J;@+noINY{Yl}QL*@2?iMCYt;d-La1A<4fa+NK_l z52AB+t>`@19=D>;ziy=W62&*9bG5(IbGS!&F8>8R7vCfPVw>kKxs)xjvD;{adsBXS z6n~3o2GOfF@BCI z(!W*fHn21!2L=VVYu}+`r;yHFx^@fg-XpAMc(2}l`u2wn@(OWnIz{~pFb#-yxU$Gk5VaqZxeprM#N{> z#7__8<3_ekd_$V&-?fP!Y~=F#>pWkfe-oWwFWFMg>BiczAuNb>gFg%$w_`n&m>|}h zb>M>ZDfqove-@_V@%T_k*BxSegT`=>um;ZW&ib%W;D@u$kgqy$es73JJ`Vw`jdFvZ z0dV0uk}p`ReBp+B)PSe~Pz*!h52#|(Yr(o ziRymk`VB-Y5j7I6Nz{jE1EPLJn-TRV+LmY_(e^|`h=vi3Bszv@B2l4#D&bi~KO(w< zXgbkMqS-{hCz?w%kEofb{x&bK@*DvFdJ^^_>Q6L;Xavz%qDe$kh^`=-PBe>XE>Sa4 zc8BNdNz{j^KhY4P5kzB&CJ{{`x`Jpr(M+P*M01IniR$lCzCvE`(JZ3bMDvIm?(zJ5h>CXnpFn#}h-0DfvOsV6?$ZzUH+#oUU>)N}vR<%i1-$5} z$qe}l1(^iph71S!ICTu9jTZu-!y*d0Cd3o!5*5cf#tdblQSmIu6c2PV>jE}(nJ|V0 zO&Gy?#h6$R*m&(eZX#{MxqAG`&&p0b$n5UYJ`CD*MC}Ux8VF(Rv6dm1Yvc;fi2n~#(5R7;;8G<4g z64H9?*w)sWdoOtU#VH*A5enb9)wnnC72`>!AE0QJd~f(BJwb&#!Z-AhD%^`jF|p=` z(LBFsh~@V1{H&PgmjHPP39gLii{HnK@_7EZDo`{9x5FC8?U(@8S>sT17sy9l-j0yN zP@bjo847$+Hy9BF>lA8?e2de8-^IqCh}GYpf&h%L%>+74chc*w0NhnEM}KX~Bf8ELVR+i$ILZogGCw|@fon_J24 zPXw#R()tY7%gZsYNE~u_d2FRcx!#Tsg6A}bFruMA8$lgL!{=mGi7^KM8ZaYB@IRv^ z1|`+f@FVW<*BWdd3!e$_CqfLg249#x^b!$7@i|l;E?i^5%Z@0nk$A#o4_9fp@Cyun zcX{_@Oq$V$40m?pDl2q+?Q~nUFYCJ{*Q1Wzdtw-&xm<~Q_w&EuHgAQJ>Q7> z6Ad9M@)-sF!xwrj`VGSrWo57(v{N2NL;v$-T@`;?`Mni?l88c#_j!IMqFF?ZfAIKJ zqGqCE9n}8;=cf?OA!_`S$0rjt6Ad%-_za?A9W|S99#Q{%E~mEfU)>j7*L-{Z6-Q0% z<%ux5j|D1LPm5cF#eDusAFk()QR%@|*e3tNz`xQr2I^@Tpj^>_L=Nctl6>}8`cWr7spH^j zq}FF^@n7qi3>KlD;b5=ORI<1KN*`}|@nD_Mg{8E$>aW{ZlHxVqW>FKjs5ni$ii)=j z?GUS>zEH+Qc%CLeJ;Z}e+|p<$^`yVB6>}(FKk6C=Il56yC%)$i`zfK^d=au#z7j~$?*kGqfd()#ftAqqP~RyS7*+EPn;JZUj#fZ121a!QhxqJwHJfWM73N8*f;JqIRU;K;DMSk zF$pA#&tx~D3@B_81;M_~#F&2Y0{gg0Do#;-AlDwwOLQC;5AV*Y^2KMmI$x0M5Qhga zqa%9ZD}){41wc5;Xqh14GukHqZg2pW+YmO+G{MA8uq_YhsKOUmWALj-(`e<)~ z7YL1jT`NT?&YM6FcT4Y)V`IYL6~vJVF+mCFdW_(Ci%*+!p}n>&2R+3RLgesyW{}AgHV#ezO@;J!LMlx z6%TJ$KjHI1LDL8ex{4XK%u;FLf@N;bVc{Y3-bBe&u-8;hhq~WZ4Pcfsx<2dwT&foezwF3XZAo=l8FljzzNnzXBNHTVByWAJ_-we?{Yq zMitX#Ev&DwQo>o07sL-?4Mo?u^g& ze7<+z7hh)XKk(JTuMd5bb@<59W5-XN%szGc+cRg+ozJ;&@w@LY{qSS%<)5xx{rTE2 zdDm~;y!GqtJ9qE>_WS)m9{g#}FL?Oq@sp>8&z`?{`RetX|JNISC2#2ctqs5b@$&zh z8_)lEdH%aMa7*6cRW@+{$IJh3u1{w3^uVWtcz*a4!$W@2zkkCML^H$k_jiv`iYEZl znHuY#R`d7%M0#~u{$6?2Dezuj%=6PtgZlj}91rFJ_dM1B_u>wv{%(o6oUQ!dE3H+^ zz^wQDPNVs^H>rQ2(B#O^{dRzr*ghbaVuLemaIOjmfqWt1?r^>!7_dQa)rV{4K73K`IK_sasp4b$yDENfz@AP#e_>A`VNt$V6-N70RJa@9 z3>8NEb5t11$DFO@!~BgZ+y!um3J(ArtHM~mG!;gB^HjJKU{=biAM3+tg98b7gq3o% zCsu{g-c%LF@?@zn=ATEnJ)FwG^6OoAeuy!>zY1geSQWIFGMdsAU7PlO8N zm+BQN+!1h=3U>f(R$;6UqpMXvw#N_^4h3vdVJy!I6-NJLt1$Z8tisqnJPlU;=r4a2 z#`=#{Vcb(nRpGvXvk3QMeHoVLE@7-s^k1PxzB^OeS6PuC@9%mW3`zc11@yT(cv5+B z=Mi~+ggZg&L;r^m#_ucs0Z=+@56OhPQh!Xd;b+)Lg zgFClRV1L5GpNz_5!Jy;c87kN)i&A#Ua9tmFrTCf#irB^*VO<*cU~u0m!Llp=ww!N? za(pj79yFs4bzYbszB4ff^xJZ{Rk)v2l!GS&Vlg2F#3Ka&$}vBOVO@=~jrWCAxMMK_ z-lO1Ds3@8q_d9Su(WKapdxAwzm%Oc)?=_8pa+*Lh?uiu*w)%0Gif) zJVS&2iiZ*w4MpV>l-)=5xs?%+I$o(UJiihJI>Zid(Y8=j4o3_u5$-qQ{vuM`%e4ku z`MFUDq!dpjQc_c&-3*s84~ zKyh+$(AIc-f=w&Jb26A8?gNj23wP&n$A2iqML|!%GYv(@Q{l-3NQpHe%8tDieZ}`8 z$HzZBi%>MYEr2y7NIyfzIST`i)}{(cqi4ST(}=T z7UZy`y!B%`JmWS2yu{m^$P1}$dcGfyJs$mR4R6bhf$;$Q=on?6_^;%#w)klPUjNn- z^E_2!|eZp^;E4NuK{kFe&tKws|TGCc8 z%2{<<&-1-4hvUcui>kNz*y^zdj06Ak7NH)CZROE_yss2JCuu7;5wzm0VhTv(jOFe6 z!9I?&6`UpU_d(+nxj2Zm2HSB$JO{*6*mhhm`W(0F!5+=WprYd;?_bvbI!t+TV=NC? z3Y^VhUsu~T0`%eeokZ|jNxD%3wmW>|&NjW6Px;!+sL*G4{siX_*ca64)X!!-Ph?ca zdMuCCyBLq}+2Sm(XuP$a@zezN=A!kCqX(YQ;Lq8=dd{o)I49)ZAg2Mb^6}|~PrIUH zjhbIv`nTr`wV}Kv&lm6%2-YvQDfB6pegxd(=%o%t<-{o#9QTU`oZ}2Z#nHO zX9`i0^L;H6J#6?cF5WJVh88*(y|2zr=VCDEE9=!cXb4=b$-n1l3Ev`YNBBNr9pOU4 z_JsAdczQf%fWbi6kwfN5SY&P_>_mJY!gvk^gCF5i95R2xE`$RKj~E-Y#@whaxr)kuFoMe5^g})hp;bUKf;X&`x6%D5dsOfBz_2C(R0EG zw<3N7Veva6k%VR9#}W=CY$6;)IEgT>xnW2q+@3?0LKxR1Fr*U3H4zLe2;-UthBU&s zrivk*a90jl2I206GYR(~oJBZ{a5iCFGsBQWSezfqC5&rw8151l^SeUA(>a^z>hSu7 z_dS)MC#)sxN!X6C4`Cf)aX#9fus`t~1fQ@Y;RwQd!m)&%2#fcNN)b*Xz6;?L!lenX zAY6uUI$>ABnS>35vk8|aEY5wq5fFOCgEJdwFuuO zT$^wq;W~u%b$R*g680oqkFXEn`h@)nHy|8B*q3lD;YNg$2sa^|Lbw^>6@;4;PAA-g za3>`7QA>_a$^us`7-!Xbp)5so0-o^TT3 z4un$(cO<-ma3{j)ggXa|w4Ne3x){!i9u;5Z2e{i;RwPpgkuShCY(fg4B-^QGYGFBOfRvsbiz8CkoeI18~o*Tc-|7b|HM1uz_$PVRyp%2HYPWggptDC+tJmo3KA&FB+?U35$S94^eaSq!s#MC;Y^X9aJESA z!_()A^n~w<^n?qAd;>18_v7VtBJ4@nnXnIGjUSiy7xIKdggoI0A>WM4#|nAENkX1* zijeo`@+$s=UdeH8=llVQO9L<|X*@^HIwl^nwu%6B-~iTeo{Vqwn%1MXsA zhyl$Q#?ty8uE}8-P3iD$KMZ1b7=Jem!)THpP5N*>7Q+P6n@IWNdNc-HKx+yR9l@VCr5DQ7kiWBc)i6Axnj0NWAbaAZQj z_T&rPZX5!h060WB^M+B_zL4LG_}I=6_a=<(%NI_Bi1cw#BE&t2kL}GDRw4x-+Z~oy z_5JcT9gmveIa!a zB}h{IW5u}tq2^=1Q)BFZzR+4l`S@G69WC{T{SnI}>>sO?H`G#IzF%o=AJ}ivKH*R7 zzxckpXz$pM5sUtT{TZ>yANw`dPf7m3{;qCMLzVJd?Za_EZ7+@oYK-GTQOx^`C?Ad! zYW`TIJy`YQ_@UM@HZcyIW7aP z*7SV5u=3*+eb)BC#|J$1$U}nSzh2Noi*N6|zgx#Qb^mCmjKyO}lhB9tXB{7S`wO=C zU)`RHOE3J%PlaNC#QN=EX`lRgkEhyr;Qqtk7vq8ZFUT^!asTl%i73JS*Ur*E)#WeF z9^Rj<t3k8qx!0Y2*=Z8I9v}m4RZ%g~)`C0oP&#%43A8P%@*EgOYuq{sy z=z%u=%n^zCf=H~vnZC_f*uil!H%4?cge{(>#_E&M6Q zYo1>hi#{%orz(a0XdV8l9uHiepP|PXErLgj&DeufrfIOb=@tr$E+;Vi-n3Fi<# zPdJb8CBkOH7YVa=+`g@Z4TSd-HWEHY*pKj4!hwWEzYHUMhWL?$zaeZQoK4t={8g85 zGVxatP9r>;u-NCUMmUT3!w8Fga1G%c;){7?9^q-kHxvGnu-G@(5;nBw{t^8~Py47k z;v0!C=0$#lXN&YCZ%;Uo_+s4lB)-^(4m>K211> z@IJzMgbx!o6aJns>&WxpNZ3GlCt)MuUkLjV{+Mte;XJ}&gufyjN%$OL6XENGlL=oT zoJ#l_;WWaR31<*KLAbCMx4#DAEaJxy_N&eL;v7K^@y8I~K>XT-^N1fy*q`(}6E+jS z8{sfY-;glt#Pdra97yR)5jGHi31K7QO@#dj?-J<=i|2Y6;V+0EN%$aPv2QQVDVT_# zLi`nEZ%e|-#25SaA!M%$@l%N}zL!K$`bNZ0BYq;`bV~0@ID`1R31<-&-!sBUzBKW3 zh~I;-k@E8)oJago0#o{`gw4c{A{;^dGK5(OuOC{rW|72qCBA|9O9>kZ_aq!k@&>|w z#23%$5VF^o_<_XdPit6bA%0`xhY>%Ca0c;P6OJVQOu{D0zbxTgl9vUa&)wO7U4+Z`w=z}e+^+HVZIs&=f((6Abud>K7^CV-)@A%h`)?* zB;nqKO@x;dPNwwk0uz5e;Z(A>g}}srk8ld5_aK}`{Juh-_~i&^5WgScEW#@Y=Mesg za30}xgw2H039lgi#*@dpw%6TdoP6Y--7ClfwIIF;~G!fAvv2xkz^B%DR~Tf#YnPZG|g{Jjb1 z5q}V2u@82Wu$lNr2phU`|9(x_kML%~VT3;+oJILnBy1x7O2Wy6-yxht_0g1YD)FZf zzDxW-!fC{xD=_i>31<*LnQ%JsTM^D8{tUv|WN#(HIm91KIFE3g;FEl1!e-(RA)G?_ zH7CrvasN#vEY2w!2^)w%lyENTuR_>J{7Aydq`w(qKjNtGBMB!H z9!EHpupQwv!Z!$K5KbkWMR+~o9Kw4D=MmmU*i5)1VHV2$V-olu`i}?x7khy3Ti`FT z^1#<|qF}v6jfcYShZ;xIE}>XQ!neBA{E@U9D)^&l7gFHSwA(1~7}zgTrym0=(rS!r zd1`Du{m<!)w)<$Tx z>-eZwjjiv&@O5SURP*uuucBDY|HQt@SlX@S`>6QV3=e$W5#MW6N*58Wf`C03m;}Mqn<2V*tkvjcYc(+ZB@tqkp7Q6Uj9o3}r zCzi+hTlrkS$ez6mybd@D@waUU^8g>jz{weZ0Aaq;a^fpK3=oZi5F9o**@ zrxwIMk2ozMu(kd0eFtlM<`_SPe%yD$_jc8IESwkMf$tky?c@8J*8a)&{jI;d&-ZQB zeAJKqmj}MjBTk3lxdAM{IE8{3`zyZ9#sl9+7pFqRIRbH7g`Zd9?|lh*^shL@!q2hz z!p@DDukd|md}EadzE3>b(*O8Atkr(8Pby*%<9k-Ze|%qgv}Jtf`|{#+3Z7HJeS2|g z1Q;?7Qv?4deI3D6B4}2e3&FB5i%11ob(*F3qIezlM&sE@C!2)A` z*7n2qRmEu^Jokh7tL0I@bv)qv-d20~ISp|-h@TJQ?-ld>_`a+-HN@aK$ahM`h#|1( z@dAq;$zG&W3oKodF$ez#g$*pFRuLj9L+?qiU)qq#cChl zSHtm@kKk6!dz`=`J;$*Y`#8q8s(Iiz!7`q3oM?I8@^dxT{7d@(C$sg=OsqNBlWv9F zD%D%7+!%)W4n8@Wc!9tDk=QY3b%S-vx^2|s{oB9UIOu48-C_KDbM(Gf&Fqg|oIQN; zvvO_5wCDN^ms4YwGzcF0qozakl@)5&>49rNf!d{xhv)RIS!v7j<0HmqCtMx7^Y?fS zCOCX9y3U4Sr#(0RS?k>kXH9?pGPN!3;j?X(>R)GE9< zzHgT!M}KmJcRLq0OxL&Dvu&z(wFQCa<~}TS?%1q4rGB4!bV;q9o!u}~@1K9_z3$96 zQT?xO-#+N1OMCmrBg!AV5Wf4%7j@?^j9gL=^Jmpu=6+RSsXQdlqy86w2ZuFo|*sxE=pW0mhUY7+v4fPeq#dY?M z^FnV2HmM!BQx_Ir<=LeROX_}gcHr=34clzEGVOWHj$YR$t=eGB==JQI6WePo=^A=d z$7c8*eeo!#dU%+R>z5A;-21tE1Ye!@POBe2@#rb;aqXwjbGwjW4d+qnN&XS$=D-{+VwntYH6K5 z+i(0(=XUz)&7TE8Iu_U^=l&yeN{#8q$2v!h(|yzK=sUiJA^NfpD)mo$?qhy*R^HUm zD{cG_2WPh*IZYGy%&?}f_v8s17czEz&;GU(Qf7W!UOqdz_1-zxX0O$E><}93viZuZ zMIYDv#r=M)U!C@QKY0)|XMZdWH{(u74o&A=S-IvUU z@2hJ(fARQ_)5gl1DusS|_L^zUPXR&YzwCZGXZ#BHTR*0@4(xG5-u`Udq|n;8cROP% zGc@kA-RWY4%jR!uNA;ckex*@|AI+XH@oxJD=R2hZt+m&mk{k}C-OWCKr%%@N>wDU3 z{>*sKSTmtk{Dm3MGH>m&FXtFIw9S+r?`%BRH0VZ;v147U6*TSpYhU-nwU+<*yU(oO zmwh*>P3J1Re5-ac`tMwJ;oS4NSI%DR{$W;ZpY`vI+%u=GTg~wurWxQDv@6x=QX#J2 zuA%q0&8hz9&o4H7aqG|P6$-u{-ZVL7Z%e5`<~NJ3?eNk^Kl;A=s5i~ajOshWWB--F z({1V{#ja{H`ttGJj}MNFt_|h6^=L@)i`^Ic{E=?#vZ}D(^6k#AcWK_;+@QXU9doo+@VsZI z)+{QOuzTto`wx8EWsICq-?zc6ewz({R?T67Q%?RmH1qDLlw8BFE6!#g?=#2H=ZpS1 z-yeDr(RgO2omYo$cCAi@dhKAxtKP`!HhF#WsWumUKf700eeB?sbNt`U^_qMxe&UIw zb^Cvv+}&=;EoJCnZ2i6O2aOpw?bfP0m)ksBKW^xxp3UZ+xZA(}wTNqN&quuJSiRiT ze(C)u+^OAb#H0$tzP$bW5a(AnN4C1#w0W9+`t1FUpR{wWTJ1`^0lCW_SKPkAOODln z1EXJ0JJd*bs%yp{kFWpKef`3OD^9moKj<-{^ty6ef7rM0NttE-35$+&{{77I`a_n= z{;p3xUu5)XnRMZo;0uSZRhP>3`(^jsA-_JJH1G7CPX~rKvJ2>OC)gSEGQ-c0!ks$2 zb3J(Pu7=G%|8(4^XXUslK6{@|I@~oU`{Iba!t`Au+ML??dEe|YrPi!j$_|GN448YU z%cB;T!$a?08GpQ5rDskvI&>M8yY0uR-LC6bZ(22hrL?`p*T@4Ge{aaw9g2_kbUEB& z_KWRF9(8y3eA#OG@3qSL)$dlSjNSS+ZD0Ewc$qROqTSlejkf|4judp9x?*VJLf2|u zS9X2zX~R7pVcX_!Z}nSnvt`S-{_>0F^>+_1CTl0BwFJ{Ot5%2Q@4R}l!Oj5xmZ2vS zaz>2(%^`hN&%y$`V;ioAr?swO_;G8(2kj4Bb~|t9Ioq_V_0{mZ;d_4V{-T0oqs^g* zuK&2*xyK(vKYI86{&Up=hkwuBFSq{ogqvpy>Nc7+1ATL=!ldXIkG~rqFfr|3Badmr zyFF^!FhBF*g3_+;BbRhbNO!Fr8R)KQ>zp$FOf}z4E&n|A)7-s{zX}fO_Uwl-_Vcnc zHTE~A{;@p#Sk%#>+j4)JeeJiVnNhLkC10;R<38%r;rYHwgE6?@Z87D<+PdW*Im?|N zp5MG_(x){JZJar9!Y44)f zrWTh6ef7a|kKk9{XF3-C?0@^>Y{!umE@-`9=kJqtZQp-%+yi~3L;N8cxa~;bjLVY> z8wC7#ef)|>cP=>%>ly#ESNiUb1M2;7?y9!l>z_NGn_ttt&d!T9zV!M^cdY&yhc8e6 z{#mE1U7gmP)?Pinpy%zz$$gJ5NRMdLEVznpp2x4>ymo*2#@==Euo16XTpB(x?E3zp z4&b+_j1k_>nu}T2?Q_~BxLuJOuKV=HnmtiBt`4hrP*;1&s!OJ*WwmY|**~F_N3{l( zt45A;&)m@F;+%wO`H{c;c=|;BUq(8#oSj+o4~LJ3{~p)bYuuIjA5WN>IJm{ixZ{n# zOl@&I*e83z|ezVPRr+?*%XWok%?M{n5Ap4H^Vf&nd3JUD^kI(m*EPDfraI=w40FC7+_rDaNjLpJ{WhS-+KV$9 ztbMvM@#M3k%kNYg<$r6)j@9!XIzGRja%som0n)iMyFW0=Ro8qs*7vT9=d=prmW&*H zy}^R$kXGxLmd$f*7SXoC-X%{$>U`a=_SA+y&6|*xn%u_yiz~jVA?L@wr@K}2lQ1RE ze?IK&$Y8OiKjCNTTbGnsvvRA%qGjybsQVh)Bw%%SXg=2$k5Il2`vM|XRT-rZB9FXyY# zmv5(WD&Jq@RKcWi@=VbeTY#@QvI0{|_1A++#fa;qT#8ga2>O8BR(f!gWtv%W2Jw zV3RtuRo2w35=PL*f5XVAXvTFI{2!^}n50ey|6eiw@qqc*hEVvXK1|6Qe`#kpd|Nca znMqtP!taRqTU+f|efTrN$;hH5=mt{!_s@#{50vU0%;K1YIuh>9Z;D2krx(SAHhjH> z{f2-4v0#nmj^Dgdf@{%OvkkVYV`YA=UGCj)uN1K}Nrjs)9q-d}Yr5L0Veaj}v&h$y zhF+8Zv{Umj??4*^Eb=@)&x&mepa?`-`3knm_ff(n8-9)julxkVDGTQE$1PYp&GjTY>)$bWz00N6Ljg4gxTcdXHQs0Ewf zyp!E5xvd4G9@HuHp}TM@Vbcr*`~NeFC$sUac^^1IU9Y-1S#v~ zxD08|(VfeYnm2}jg4Foz@k*qoqsvz#O>^*Hi!|f-59<`HIgp0bczyPIq*>ZN8x%UC z+NVfU%l@IzWKHHq#CiTRHz76b@46Xj;QJn1kY=s8s?eP0pQbB#+o-KbbGG_zLke~% zl&w6l9dYXX_jVvPTngHWG;O?Y7gAI73590tn!OuwmQPKk{h4deQfTVMn+o-7(C#zj z2R7TF(8%A}9>j+5Aqvfl{aT@6eic8*_`LKah5CJWNug=Go9xB-9BH9KjWd2%sNbYc zO8bng_NhVxlV5YXr2iKvZ+>U5LNk6Y^Ce>DF;bzCnxhK!+gvGAiMN}mP(RP}3Jttn zXFtZLj!jl*+OAxMf`1NReA45LRiVjo8x@*iJfqOmFCHos>hUP1GcE|`G-sqjlb@t2G*XkP z&^+@sh58-0KcUq*!3s@{ zn5EFbQri@2+IXJhnvWHlGuQhB<`TO?Mxn_*b2+WQTcLU7zUTZqg$gyTuY6MR zM{ux01J4XsXj;HLh59Yutx&_|?-UwlSEx{9`AXTCF12i+LbDzZQ)u3i*$QQow<{Fd zpF-2p3KVK`E3Z5cGRC%2X!4#x3T4-)D>Urc28Ehl99L+@ox2J(e_iS{=9m0lLxo1x z?WxeTLkS8sNy`*!PR~@R@%2v%^^;z4Io}y6G;FStZy|7=Q<|daFnl`ggp<#KYa+Lfh zR#d2;uD(JIb6P7j(7ua8^OE{2)O<5mp{9;W3QbO%tx!Y3GKKoJ*{o3WyZaOxw)dDq zBX51j`7SpVnpM9*p@w#v3z&akxPjCDRTb(N(NLkRM}R_e0=g+Qt>!?5n(Rg?H0-A& zg$8b&tDH#p6Umk_XK=j zx?$6iuAc?;yZGMS(o4?;j2t_(P5X!61@x0zZ2E1$qkvN1TyGoO?pQ$CO(!DH&UqHF zu3=T*yY;`9Ce3{sEZ9J*w8b(eM?T)+0GcIBmdzdhZ% zWq4)j&zDdA^Y%OmNHLpE^uG5n;Pcb1ot)xz(w2AX+*xR%2tpH^^My$bZR8EzFz<4agPep${q=?wtQ7v zdVf~lzJ-ro1uQKUdU92x8j`!qRat z`$yNBcfO*O{Kve?=|ieYw=UOx7TTqzw8W))u5pE%CT*W2g06nis(R<0-ZMxWoPQ3rUgvi|Y9Lka zzr39Jx4Ke`cN@oT-sUCsafo;78{bgsy<^JDrj=?-;TxjP*B@S2@~d;KY<4?Osl~Sg zN_`b=ls0PW%yMbwEd4Nf;l4f#yrq?E2CuH>doN(rtLde050fR2VLdOGS=CT-X+G2| zwMJcO#^5CXlyOa@-J7>}8#S39%)`g06kYkpkD6ylQsR;is%KAZE#3U^ zTKI`F0n+Y>5A)7!Y$UC9&bqi^RvYQUz#|12n~c&YPX<t}lD`nRe3 zYNSZglVw#NmUV9-t#sWmXm-_x(x&~bI>#?l36~=y#g*7uQ!+a7R-s79^P7VUH$!=mwo-EpMLb2+0eyL z%KN4Lk{tK^fX)4XD>KYcODg+g6W64MwWafg2Jg$#9|0en?fPDqm>N>Goynb(2HH!} zai4wf+o+o4^0?LIoyS^AFO$a)omIg{it2p*ie>^`=H~o<=%w> z+rIp^(ik5}`q;U8=TgIbq(Kcf94=StO+ZJdN_RT+ZZ3T=)}hevb{nbHn9Js0KB*kD&Nb-n_$^HjgOPiRAlWV zi|R|i)c>OPFH`DCr{ZR2_n7D@nPXjl4d_u-y18`ngwv5v13L9g{_efuF9XK?GRo^o z)0Wcc_oau1FB?hjhUf!vDXk>$k9Oz8_IeR8zV7^rBR^^mc8skav*dNaawa>x7tvJm zT<4~}?-x$`uvyh2a@!4%q`|Lx&w_5 zp;F|HmLG123z5tlT=I9vbd(bBhwOe;wvlx5!p09P9_l8=OiX`0Fr$`Kxr?{+k#j-P zx>bSBL(T?Crm))CeOq*pBCGo}&wa0@ba8*6-@ytsrGh^vzx(HcKh{@%!D$CsMvS#M;w z=bCMm*1wUBg)^!a&Uhp5yOOrUFzk&yKDf);nD&63YqWn->y50hI@NsG@r|rq(4p|; zz1MQqea+{NXI{&{YYt3F-t}4@@uhit<3+FKTVcyLc_+S>6Mxm5YTfU(oZx+R@}kzS zCr&T&WyIzCmvbO7#XWx~F_%sdtdoEvYYFN79{xjJ( zc65bxKR%PS>u+_xaO9c%lcCRVHFrIe`Fi#<`Ayb>(v3cNCdX&G6y7pDlXp$JS?a4n z&*Z#&KfKHcc_!a(uxk2=X3ylhH*z|^Fg}wnrE1)Ilzt{Z_gua3@Uuc$ZkazN{C1)I zou}V?&3A=z>o@Sl?9gLM)MWzP?z z;9sHa;gEEM^(d5oKD1}b^0tL?+QylhF7<$~ghJWDGcsA@P$&mZ*SxZS^i;0gV?fVZ zH=fFm?570{$$2VI)ihlE`Jt!s(ffJ&>N}sx^ICl|dfTd}a`wig8QtbSl}n#kSyn&! zsr=d2X1A`6cq)&bpgD57?^C&Bg?AD!ba*Pye;st(-0Z1*@LI>|J~f}pPE%KpO>%!K zn`V?6l&5_vSBNYqA6f83KH0L}=%?48$WhrdYHz;qM6NLAaQQKZpU45;pE`H`?1`Kj z-|Ir#^-tuioRrp`76CtYM)}woPh{^AnilKEKarnR?>Xvz)D!vBE^R*O5&lGuu2!ml zcJLGVTGrgmzD=LVfkQQup4WIHFWJ>N_H&OXvP1cZ$Qkxe6#KCYi~>ao1&d8ZQx4?LE$253gx?|3Y4J5wV+YRzN$kBAw57Z*I1 zBkdzJeUl%{tw)Eo{bT%N`9}EE1Ivd!mihk0WBK*WuWr}s^jQAg^-+jZtH*Lz`}DqV z>OGdr72f#GvGQa2__4CrtGfaY)4;#S@~Un>4_)~1k=)9@(U!blAIaSsTs_n-_mLd8 zyVmT?(~soq3pf8Pef>xt_)U1)54#`9T{IJSPT%lI9+9)>W~-%-jDAdp(k0Tpk)z*zu7Z`e3_Xoz{=!*;Oyq z8t(f@?%98E?R~~avWF5NeN34PGaW(RJww*KcqlvW-W0s>!9!WQ_13`#Hy+9-CTv@D z`O-uA&h~dVE7?o+qM<;bre${uY#b8qw6L%DkP6#tr=9?HX}dp4-_$wPU8e)xCQ z=L6q=hP(fahw_6Cr!EYf@K6qMy!LSZ$cJ)ay>&y*z4K5$oK*isrSOMxNB6uPlRG|? z_Z;ju@K)=G^7G20{utEgq5O@ZewUjy9?D<*elKE@=R-O5f}h5#^g}sPd#qlz=Aj(h zX#Ll-o)pMkFT7sg{r3WSd2-jRT6qO>T9~iK`4Z3uGeTdSDv-;z9I)Wop#nLuzGkOx zZ-H!o_~GJ8TMOj1Znx?Ntu2r@=`sh#e_SBDXQa4gq!h@Z=hpi_pH?6@uQMYvETKTI zqxoU#=dlHH{^Dd)^}z-5o=J<|ThpsRUR<*?{40=F6)$e3aa4Nxpoge(L)fbMs|4&lzPsXXMMXeyHd*cT&DQIU#tC zLtMVBY4S2`essQEy3T|lRR-qEr!Kwvbbrr$xy@PUGDAZ0<(i$E%`YS8%Vo2h!@qoa zN7f&6<~7KdoBF+TC!$8aTsvfom!CKAm5?td8#ISrI081mHke0poXr_A#Bpm`r|$ui5?YiixU z{iRvncfVnLqupkCiy_u|#%8k|`Tp+BSJs&2-cFiU@=~*WBWA+q+dnePvkbxdYO?_U zmRWb*yJq>s(@xH{6U_1px5=ybjWWwGx8`3A9cq?8oDiS(pubtxHT&`D@}6e-cy#$Q zojaRlgDwdEfn2AVU!L$c%ie>l?px$%mhaV_^fKDVEbDdJ8G%N#+;U3K7BxLVUI}J7 z8UAB-o!*S=eh>uZ=%3I3Ob?71H)1$i2DGss+yUkHDs%b%u-uO5Q58$M^`MBWQ~7(d z;vh&KVLXY8Vd@ml7w=&w6RyhH>=wzp6TVNl8sSHTmE&6w_mXgF;_Iey{o>?+3t_R- z?Lk`?H@F8qe5MvDpE9b`{&W|vhPF8|H;c|on35)l*LkN2jKa8;W zor(y;p2UwNEPhuYmazC80TW?32LaSQJf8TI{n(Jnjp2%8L!cuJMJ9wH zaWP4WQNt5sP z9y-7;xHV->;7n0_xa%g^ENIyH2_xfUdWHAvHg4GH4oSntOh_0xF~-6Vj~Npal~6L@ zB4~5tU+no98=?OPFxJmGxp>v3lz1cK^exrJCwfclzdOP}_W2PFBwE#{>U(;2#hCfJ^0#Zo)ar9K~|j}?F$515n|!~@7RZV6lWjiTU=1v z=MQPKL2g9}vg-6`U!F=%|Iy#G5A!I_KFqhcptjEhzK?}`{NehmfO#aVx6p)7?UmtBIaIz9T!FyE@vAMQ)CNu3V!D9&G)Z*f6wUoNCw0r|wL z@+~e6#-V)~D!JUhX&>fMoPC&YaY1cgGQ4%`zrcy<;rgq9>B3ZUk*a%4i@HQm*CXmL zE~xF$2RXAWkV`E=R-GRGl&h9o2=>F+R9xFqr^7so^AqMAY_qO2x;|;oLFuNvg-6`j}c@=@Q3^2 z>_MF(54Am*PjNxWBG1?k`aj6UmLRK6kM?A!^2f}-`?=`y9yg7^hc+z7>wO)sBmRX#OesAA;P}HEfanUipqhlr~M#UGo zA39;=nCL;Y1U!ffG&DsICA09ieeuF@l9PWv|M9>-9{9%t|9IfvuTzl)8 zYcogY+N2b2jaqfO>6u$^XXe(-iMcf?V|Fo>ibQ@jdo8oSrDuUx7+VF`RLlqC;d(m` zW&p*=dR5XfXN^0vGim)&YQXmpQ~<%NjuR`_yD}@+tP(4yDbLE}@mwQ)8LP0$iEZFw zK1R5&4VShIo33ZtQ2Y@L@^n2!m#w1&vejx zgYrp%`-PZ~^R*UGI^A_GTMJn+uWF9WT~m)a=GmKck#>ICFrM}+kPYS&8J}Zt|E-et zk{@t&mvrnSC2a}$J_T8kFI(-z9O2^mhUp$tzM{UpYUsf~zRbyNwE%5z18Kr3|Mqa- zRndX@C+ps^XQ@j5C8V9CN}CM#vx`Y9^4GXIfY02SgIQOTq zZP~9FTLC&SRAV}52XLCASRQ!xzaVdEzZLYXLT@)#p;=j0VUK%WS(70W^YW_h$PCSD zG6U49Q=X&A0bW7ydS@lQZi99Zv?lVSo5hbUKx(Fvua6A39pMt)_B|~eb?~a|#41ELhBo5|ZKe^c zplQGiP&%xG1P~VeW-8pzhs&W%>SR4@n1LTT@WJ$#?ATNXiFI*cUP>SKhOxs7`ayZi z*zpyl+o0IMe2&5Ww{U5lKZj#IVfv}eq+Q7pwY>h}7kd1P*5g|~r@HW}Y|lz*+!*w< zNRcL)=fS*`c2NP^g`1^a6y?JAACc$xaa?O?dLACh%v?bwE5 z{V)@R$Pe@2cCjT*;D6l@ry();;X5F|!sVc}2k^rb^aFe_@_^By5T;QEWQ+tfcK5cLnY zgW>w?`UfFV|8Tq5lICC4e=%i00STe(=Yd>@OO!nl%bsj0d-oE{?!3uTc6Yd~23N^t zZ%~R=iEhZMH1lOuG_{$V*^pNz3+9hue2kBP#MSxSi1|bTNP^2jnb`5sM57(Gr46(} z=tmx#wAxC#ty+gfZKxef(*`q1+tJ}Ja6}&~I&SO%RphU);Pwby)V^%nilgP3s?4Kd z{%u&wSS`5DKq3s);IfUg9dj&gMR_)qw>%qgjF&cxXOK@Pxa|&?Rv9zH90sw;c3S+g ztK#Ov8kht*HL=gbIk{qoy90B7x^RsFg$kcRhXp40F~T{w!1Uc%>+q$*t@UT47Qz*y5f9qPir z9ej3#YY-xus&jOdGDXJj?&(9K**Ep7DV&UuwQ7rh;}PDU zd@|tvI$UL(KZUlF*BT$rGwfO`U=#vP5ulSYWr|0GAf}dvs9{fBwghv#i#D|qhuGjB~ZCi;52 ztuSbjZQbC099+(dZCQ$KLEM}y#kRv*$;i#|oU2&VfvoAQ(^qj0*0+F}538%itp6(C zuT=RSgZn#wk*^_Hal_xww-(ezVpFJ(CQu&@E#+;x4aP|-Z(FzzgUdlFZyK))t(1XT zm3dDoU}rmB6^GWk7Datog6@SX-7DaJ$J@Fi|5~>bb8l7=zB79;7qfGoXh+x&EN#0M z%2WZF@^8tcDV7%B{xyyo<_P1A##O^yhl)Pf6#Af_Weya+-H9bA{_&55+mUe1fD7ln zuUo<6L7DfChZyQ2GqhpQM{3zK{WF;K>f*E~KtIlV!yUpjRa{sV7=x-rJF_aio#1(+ zXH}Ybn?3W&XQ7#I^=IY#c8#~btKY%wsLsrAUx-*4sAt$Y6tL=ABa}s1XYgRwZ~6RL zR$~XWZ_ErHt_|S6DO@~lp2J<9l<_|8QRLY$z>>~q7~GChCA-0DV~&s~&cQWh8H~_j zSU*V^2|@XunP^~<1D;sdetk% zDmAOaDrqV)gBezca-6e7d&2QOa3_4*RxAVObOsOu7ys^N(^Yb)q(7jGfm|7`uXse4W*)s=U@ljRdBhu(^?+5N3ck%?@Yx9W+u_o>-~bn? z%hT?K?;twnQox^~=(|`h%c@n=v1*UXF#Bj%7FkWhcEFVZX)!2%g~1!+p23wZ;(=FO zoNf9N^Q@_3H7QSH4GkLuSIu2T^TfD=aJ3cjkY{mmw&`*Gu5HcL56LwsTx zrib$QRnf3LaIFx!aorHgk8#i8$`J98XK``1={2sfRtbI175bcOIA5z&=1|c87>og} z;BwhbNc?!cH<-xfQ$cVYl+cJ#V##zeesbQW+ z=vk#+Gqzc?5pzh}@k-G%6Vl_n;_uLZwPu9rk^fhA{3r8;AC&e7Z4cU;Xn$|{t|TAB zK##L(OC5PRGcQ;(@PhA(UcDWe7p%2;H7S<|tw;&@SP=D7wj8YWf^4~HM_3nkVC9;W z&8zLkaCBs8@PdtND-9bm6WR=fc(|XY!b&83kgl+@ihX)~j+syg&S_qNymxC2dzW;W z0XG4>gm4?U@2KJ#C)-Q>p{otHX8OhTuDS@a3LB=3Z{I%A@IpLf!*fDm~8LHUp>IN96rqrH)z{7TvA+m$Qd9bpZAfG8r$W@Q-Tk*Vf;**wzN6 zpFq7evuCbuw5Oz$9&`h>lwFZ?1-UZJbur16gLa+>Hbv`TAIJ`D(=yR3lyq2sO1cu- zMsd9I&a6B<$Nvv|?*rH8y#N0{-~ZpWw!PQdR@SUdvyh!k$T>rsHX%FNGC5++ibl4y z_Xr&_nGiA|giHvrObFTHgg7CSqcb6dkR#4a2*3O5dS6$2@4c%w=NzBU`F%gz?e^IH z(d+%XUf1*W=Xza#-q-uO#QBGM+KIF3+#qW0HqDv^Jd$PkIl@2_jD9!T(D>V6 zU|VbBVaMYVEnY2s4CBPZI2kQr8+>sF@x530=CC+pOx~4dkxl63%iS8aWnDIopKYnW zvwo4lWey|%$ta9v6wQ{gXzOSHnZ~hFe6V)Bv^}n!)2*CM*~W|0nrX@Nm8ccV@vu!e z9due4|=xvRc2^6zdwBYz-`KHFXH?(!<1+8+k=eb7jY@UZ^D z`Q`fp=D7eIyzlU3gv97?l1OATK zoAbW~+WDWcK5cumu}_<`W8n?!m>MimNe_OBg?XS1t2mJn4ajJiV`%qsDslM&Y zWIv$C7~ye?XR~%@-R5la?aS0QZ>6k59=6Dz&~aC|HLAZiqZRz^|8H=eYCiBALlFmz zkcga7>?8IT?gHovZgV#|^BkG>IFUKLL`SXTss@XEh7P7)iVr+#5$97DIaaUdn|>?O z*0X^9sES=Nuszjyu#8jJ00!5j>Y|QSUR=*Uz0M+|Xir7;_qFf{{#O4+K5CJ%$oSm& z+xT3|r2jWmef9L6w!gt`XQ*+Z%_k$-XRz;J4vd@`u+JE3%xcGi>>sk&KctOhKM^7k zYxVua#9*12HC`sBjgyJ-VKVWXu)fePeIGQ;F{EXf&w{kiSO@1a5yTm>U|b*H-nALy z<*n5g2`;v1^KTN|A1SJ>QqlOgt8x}yLErFR54FTg@L{BA{5@EX$^35YuP(XLB3qGK zCb-16?x11vuOQFINag%d&mS?JI$Ea5$i5L>L2a%kGjt!H&HjM8J>k4i2G>ys|nHl1nTc(YWY4Q8WG`^qTVJ6T%WqTfGSzmn9P1hY` zteg5MtN*#vH6}}tx~E_-?Hq$_zGE!*6=TA=-`2agglA2XaPFxIC(oF!?fa0wudvGc zJgZ!#Z>QR_JIp!k%Q@c;i)ZdxppUyyhlHNttNRG%0BxDwnMaN7#w@Q%TEsZ!hkW1l zg#_Pf#4K&t<3VGcLos0P37m`mrLs-x;w#s8-lery2-k^d(~t%3Jne54pW5e-vdbur z^GD4L_N52JH%9H>n#XhPaUA=(FxlHTA87ZQ9NeT``-qtZk4Dzu%r=X3+1FUV)IKog zwTJ^p$YgJXOy*vk$y~Ra%y$*qtio7T+eDGx)|Sa3GP!vidBey%mb{@dd9yaBk&`ht zb%ady&X=iKC&<+J6uw(a7HzxGKIL=38N&iy{2;`v5DPgCn)+zhVE|8FDR zpW1m|u#C*tm!GWK=Md@~Put9pv3g|3 z>mIQm_3<)iXEA5TkClm=eJ!lw&Qz7+Uj$!xhk8S)*BA-iJVLwHnyG!lIwI9I&RFIo z?qdqL#;LLl?u)e8LuBMyzq-$)?t$s5FSuqM%6uQ1AJ7+C-cd4ggI03^k#cbLv7tg{S6x9Kai^J*v3K` z$D!Zo=fZ(`jK3$S?|{a!-Y~ucVtX*QH{)}~1^W0msK$F>YFh zUxylJ#^0)}Iez2P_&Z?!8q6P@de}mhfQq<%oT9IQx(AnSRHElR{(?+xR3tpTy^r_lvfd zIObh@waGD=@A|E8>>K&NByS{l7H=}iZyC*bwf{9#EiS)pN88R#&MS?21TbQ> zZ*KXJhXz&ref#<2)N-r#yY9g;V6>sJy#9B@-gb^#LS)R^;8ayci(ZEM%~vGnc-O79 zsv#ypDnE0VQO7&Db9o#3fjZ8``??s1s=R)^yxQx1@r?1Szfsm{e0C<< zV%A>j+>`jmF7W@Bnz21p`VjRTY=@zi8!CNQ+pw`dgX(%|H`hzOTrbViub1{|O}Kq~ zH1ZmKF$BkqWDeKcF>{NrZ;gJ@zx&?)y8~6mYQH&v@7}cU-~-23;NSYXBO>^|gZqZm zc?JEPr~0l;U#E(GYpp(>hRNULmp}7iJ-=Unt8#W4|3lP$@OVm_dpR#=4vkH-c07ZP^)%aHirAC zN9cXf7tjZ4`GN+kg823WtT&DI#!R-=6b+uf{R1N+`sc7jzqF1PF^eRaIev_G2E#Yg__ zPM)34^*!9<$z11QF7Ye~$y4R{uFnlI&kQrK_}2f5g)!rICCfKv67`3n?oOV;@olu# zaL1LZ515k%w^3smgWB)JI9H74{BnWui!JhN{o;4cL;IWi@c8aoYlFbQwYib+kC@ZK zn9~NYH|gt-IFRcRUamuAaUFtl=E-ZfpT((T%0yKt|FpUp=RN8iMJt!@#L_sQi|2gK zIF}2EFJf+e-=5agMJZ|Hf$E{rRDBt1QNtr%Qw0qLjoNKg^ z!GEWnf6cyWS8aKK`hIgP=K`Ue3yhJ-?QOYZy|wKv;CR|>8{FMAZLDyf&v%reYqh(x zGqpYo=nLQeZ6y0Q_OFbq9rmqyTSm+rAycv{WlH?*GKGE^{AO1_$JnVajB#xA#h!87 zrLJ12alXs8+B5cibJo8*_Ox+6V*7PZ)4%=ZOyfG9acxrN_i`Vd@g1p($A7NV?sXW& zy$&N~{DQ$P!fzWJX8zS;@%wzJImFn04F1~rIdDBjIa+$)xv9y#t=D(re?ij znHvAHWvZpwVq8g7Y(CWE9^5Br=XxW#M#6O)&LJjoo-k>F z-}M@!T@3!({@C3)UMrXVZ5r1B^xrLMbFy~a!Z8ci4?HvV;}$Ki$@K!W`VKYM8||R& z3wJTcYx~=Oq5q}^v!CYoKHNJsm3ybAQirKC_wLf_WwfWk|3mu$?HEoS%S{Pp--$TK zof7YsDKjVaP3(%;VU8Odr^C(t+ISe|m~D5*pf-N~7mhQA>U(``?9TE2?&KM4cVo=` zr{)UxJ;?$^ffztunge_8LZ zZO>ns-|QOrB`;Z}1WmYV_pX`W_9EW{qI#2S=4R#3r0iK}+ivFngtGh4Tf3QmK6%s8 zjk}rOO5PBZZ<60K)c(P=o&C;Bwa@+j*2dc~$DscO*A0ig-n*;#cXvPkUwRBZc->g- z-_r6Q$Lu@2J!$%Vh5_Ggnzf5De;72&^Y5f-_fzrPFzykIz-jVmI?&M%mY+bd&t1_g@VouJ#>g&ciQ97wLa%W5>4+-|ui{(idZ_GG;??s%01VAVnOg zek*Z;>F*U%wUsj_Cpcun8DsN8GsmQQ;?&wm8)`lt?)&aI?!}HjkNdFC-041ORsSfP zUiL1wwTS&j$b|S4xLoLLZZu-grrhNy!KCcLHX3Ry43%z-fq#{OiSofjw?P@O5?iT{`yM~em=A|4 z`#%*!G|z;#EbzZqO8fn|HZK_a0HaTJ`kvL5&Tr^W=DxQy?RN_*KezSnJddbj0i&(8 zy6pTLa?@iOV>}u(V$jQqn5LcuFoy5PJu*Ij`}gB24&ygw+A&Bz>knwF2yGv*{W~h- z{=qvYIHebDGTZKXrq#5ph5R;f0ly8LFWiftH~4!QRUY3>?r?v$KG*x&YAbE^Pui+) zu&wf3zP9qsRXhtPf5hP2dD94|#Pe*MyUgMU+^)2`j9}fqGE}KM%~64EXtbr%CeC<{ z*R-QtV|)3P+rm&~t78HBM!(;u&3A`TaH(}Bl`E8N5PYk$6ZK$!oLs=%*=8bg@wS2(X z4jk*I+tvpDfyg=&Z_?`*r z`+b+1GZNLnz`kyZ3Jw$K1Z>kqrIYox!nh#I4UGrpGjgIps9;p4mL1FCX}u zl-Evm%E#zuvtbfYk2oWqov3dIW^pb$i+v!fHi>hL zicj5(zQK2Yu+cB!IZkOpFPJUk_gfAl|BPi$`2+gQB>&(xFx)mc)O_IAU#d?Bw`c8{ zPY(UM3HJqaooDb_MaKA3WvcU@U0tWv;u_*P54*MfbFVJPE|IjO|NXjJyu-~c+Bh(o zuT?z!K0Cs@!*eJ4wDSI)>tbfhs%QLi|8+R+7oN|r#Ca;q_VomeTeGpOwcQZ+%NzY* zww%%5CZ9!2R`<4z5zpG~zxDE;(|zZt?33czhWyS^@4Lq-Pom(`fVpG=*HBE>GdPw^ zKJ%@EV_S~H)H5cHc_*^QDQ}|~eH~qR`vcqmR&A&LX=SVR8f~DBeKjs^1uF%gH&3LGn#dblF9jl*JXXjk@~f= z!G1By(T*>NdFGdK?rgS?3U@NTU5sxyGb~f9Gfo+7R65?sB%-n~dk9X$`2xozWLV&v{K+8|-Rc3y9hG{-3?sfAbC? zo~1IX&G-HvH7@E@f&2>`TfXN*?9cvXKh8<_9eh4Slzwg0_dM+>JP+9So(EM{msS#G zY3;H7oK7X1K4T;>&M4lEl)vLIw^X@tM!Cby$AM){=XfP;f9kv+b&mG^PCC=KEf~+I zF|TtBb)HV0qX+9eWd8lsyHEC$328C(?R2h#@?43$fOQz-&ZJGu+G%hM7~^L$@2Ig{ zEzT}`o3%+VTmL=Glo;M&x%CQ(@~+|c>sN{=twh}MS4rJ>%pv_wskQswLpz1`3rw?c zZasl(EWBexJ&A*;d1mf7u75W3%nr`e9L&#o+njPGvOBhy6PRXtP7}}<+A~}E9qkCt zZ+%Z;U_7XI+pP1|CsD1Of4=_kyS}Bh*%*!wJTiK-Z^?)QN1n99_Ox*4?J3V+`=}_CC8z&%;GY(DT8jF*{6=zjlYLEPn$i_ zCAXt(X62e3OIX6Vp8kB`Q?7giY)mBI*);PkOOEv-`E7{tJWHc(2ljW#A9$Aj_-jp$ zX$HSv*#7)kRjT?e+%(>^6~Xf}cX%#bD(A&V^V^COcma@a_44Lqm+$!i!}LeQfk84c zt;{+x{yOVK%hgunmxO9wP2~6C>fdhVIf(C!(r&g+jxV=Pwp?f3ewEL+4QJ|Q`L^Nh z_lfw9aeVg`8SV1k?_81*=aQL$?V^rxj6O8BtzGR4hZ=9%wzA`OK;J#(1OC@nwci)3 zwrJC@0S>O;h(qfqljmgK5+t|8CyB>$r0*H@O}0$6KUe>J&vc(BMT=dsAk!sD!Q1E0 zz%+}xp2fYo7MFU4>`^ks!*iFsM>3BmO5Y-v?02$D%8ljK^KP{kQG;gl zhZ;xfy0`i+g>$tD%o7t93_krz+wWRJ91`-O(HnZ*w6e_Z$1r)OQ#a4T@`iGZ$+N!L zSMppeZ6x~6n|3TCB05B(vpf>TzD_-Z*OR~f`IhQ=5izIup7pMx`1a4f`6Xg|px=R%D=der8?WA{uwuXfyK z?1R*G3pFPGoBmeqsp1-DU!iRWyPIdY;}v6F!{sry87&XjFu31GzmBo}S)4{5Z67e2 z-}H^*H+}rJkLw+i^8J3(r`2hQYd}UB+BgdMZbnPfpOw8qKfatk;-rX$VLZ)y=Y77~ zPZSybt;IdWb4v7e`tB<^Zu@;DR^P&=*E7uKj@?bu_JJnHlzKlz3~`)dTtlsV*d_0v z69f0hTm#wFvLWkTay&ZMWZ7ZA^BpSY5Z*VTwj1?a`8jZyW4R?yxMT&oDsbH#NBEA- z)HQRC(c*)|cy6q546^rgE;$K3V6v=sPt69u@4WTB%HX~_OkKa?d|`oKo=p8&RqC0+ zYF=I7{{|K6F(n&0~m0>^{#x85&7 z#x~2C^(ks&#J7B^MIDQ&=T(}tL&U!9n{#-62>RzQ@zSJ~!uiQ=kNGN;rh_G@Zf&f=tJ#uhq#^};&ZKzJ73r5y-$az z@AXF<%*fH>8@#tcm2IUjhuOEPYj6?Nb6orsu17^ma9&WRJFuQS6MRwu-}$TOg7e&C z^=xpne1qG`)KN0Ez$O!OIA-U0s62yZr>B}~c~|RWS&{cp`JROx%G&vRqMKt!&Jo$J zCUSfpDv+vk-F8AQ6XRP_2ce2Aix@+)V6T|eC**M*4J2mQPP_+}! z+7ISg`-9Js(4I39s^008r?rnZhpYE!`~CJmU>h6U$7t8Nd5$pO_fF;+z4|kP)w?pZ zehc!OH;lReg#Fx7gv#g>#U1)&xcaI(@ZIci<2SJWTG{+(8O3wq=V+_i^WUBp*wX@g zT3}BL>}i4jXItP0kFRR!QNC-U{uNbU%N3DcgW6EPNggAA;*q}P)p3eSQ#xiB6<(cGrdFIaf=I!T8Yv5Trf&VzfmMGGbO+MRrurGI?$!F@)wufg~Bp|b8)sj^v z@wM_2+rWPvCi!Bb19OR-sTz!bMXWRMpNgky7xB0gcW(dF4hSqsqp z-U%k_`F#JK*Rxzd#!IEVz<;Vfd8FqJ(Kjl8j>&pf9U54Y$iDmf(i%+GqxyfSb-czq zlhnVyA(nGToA-T{Nn95tYDMkv-*kQKr&3PfKdt_x4;7or-x08$DAF!CT79zPKQHgv zRsR}>SWgG(Lu~_UIrr?H$IZ7U<8yy~d`5Bae&9dV&IzQOZ7Yc; zo;~O2q`C8sNj~3I89b_f|j}Z!qrpsad6-JK6CfIK3;ZL*MM?~mlSENA^&stY`G`O_wi2u zU-q*vDN*O+yP1Esp8pB*zrL<}-CpwXx}J5X4qg5wcWX%+AkVzBD^v3Ez@t%N-THeVIkRLiA;KF2Zd2?1H7) zdER9!mM5mn3cb5`T0w7ml0F`S*y;?UhXvs%QUXs6=yA5YPuHldgNv=Kg*kAzJOU=D^__I zuQ+pY{*vWqWe3J&n*aRl{4;Y`TwuP2q5EI;$C;~^FI8Q*cqu&-xUwPog^P9B1w*XN zEIzH@^YfQnxOjQ?1&e*H5xAlogWn1W7;$5{eaP{WvU$ShcIQNW_JuUEC zwm{y69BXm~C#ot)ir{`1ixl1;B$+UcpC%>Zt6(laQL>Y#3I<=oZ(Z&Sk~p~JQkKQn z!P%FI%py-6{2X~%R#sCc$|aBDA(vA=UU4?6#48?y8u3-|HPnVz9CrmjkHRZXL2k-a zoQ`7gWw33HNXG3!5_P4>0Lr*6ND@m#p1n#Wi#4Fy3w&L61+M9Vk!JT+ma|_?$5_1ksDx#!;Oodko-R24PRdbz z2fI-(G0R;dKcFhgOst}Qs6fR46Yi!jsAC>HdmZgS40X_5jVIAOc*RE4jn|0p$Co`z>>K%Ro4ORiq)m(y+OP;-*u;1KDo*&+bF>M4EzgU5 zkFuys;$K7#Z^l!{B6#5ojA8211iwZ#w7I+}Vta|$C^Hq7v=B38cEPo+YzvfG^eW${ zyv{QMD6Ho-49lZP@B-xS$~A}Ob>oig4MNv7_pF#d1EthNO>p@TM5b%Ea? zH!&z)^>>kIykak!g;yN0h5L5!dGJ~k&a!pzGvvmrAL@pqID8a52&Lf@;q9mpujuWh zeejB9s1~nSiJI{8F6E#c*2Q;KQiP%(VqLIXi8&$eJ(0)XC%y++R~Pj~IW?qzAaWb> zkiQ9D^bvK&_rd+TDTh3H@ZgUbOO%rbi$15#AE2$i5IOH3%wwv|uec`mHRa&*z9G+d zjBS;tpFaJ8aYB08kIYvC%psJM3Lirr%5Q^5bB}Q`KFVp4TTv@{n&6ixmU#H_s~nC( z)(2@^fseu~K8F(U!fz&yL1}o!F~Jte!7ENeC3wYsPz}BgzK0s|iqZVGs12_ehqmGs z4@Kd1Y`?s#`%>;_E+?Kgcq;Eeug4d`!^T)-RxM@1tZ^0zdzk#=EwT=INmty4O7V&@ z6D(4VSFA^kc*WV_#DG^k2KC?-Pe23sHu&>i76t+BIng3zlPuCq44%C$G6kimnBfLg z@ko%yAMkZ}#akxRws^&A)QwkcMg921DB59)MG92>uol(f6~9LgP_ zJ_A;uSn|}suTV5z4rDzj7oP%eL|OQ1_!X+c+h;HaQ7OI{HlY-J8=UYvV#bHZS>#VB zi*@C~M^G)k30e;#KRygDLR;}U@Ie&DvW@U()K0o*rbQN@c+#`reaMS%fIpx*e8|BT znUB)&nf$K22zgny1lFKNd>wof72-SLFQ^#rKExsipi+E1JQGwE^g1k{F4gX>WXz6Bn0m_<79Met74k8gyZq5-@;fp}5l2I>wkIh_8&H^b!L z)0g;Mc*h^;FMQZ6i=2r1@rAGfg*-<5M_A-I6o$`$g(w}oVFilASHaIv z59JTQE03YA@U<{0nX!k@g=MGkJEK&5 z7JLGw)^BAv>^h=q)|Cz!`zH>$yV(k!wBdGQ7CWt4~yUu2PUP}t+NC%h4b;49$MCsSX_ zY)rSvCn$#Wewc9zZHO;`526Zu1H9}{v>m<+PR^j+@pL5J@o{oC(S+Edwsbyg$>ciK=-)A%TvTO#NcqTF9 zGhrU;z!$-9b7>cR-E!Iq_2JuKW**xbz8n66qMu|upT``CV)1G417yeB^BLPH5+4tb z^0F=9J*$`>P@zhPe?+DDR`@9@#`nPy=hN5tB)A-<;hSK`1+*_ds(|ePRpQfN4ywoJ z!PTe{Ujpw&)%Y6NfNJqg@W2b{#|GLBR-;6GGyErNCr`pf%rj^J-vGy6%)E+^g-4=J zd=gxQy73usIqJoG;U%aUUj(NWvcJG*!Anpj>netKp;~+={0`OQ<?Bcfp_{>Vl7ki%~1S z1pWgx;@y|ApF-XEl+|pr#q>oZ>w>SYp)UB;D;ZNIdd&Gy`#=iIt%EULppYCKVQGUu@Z2MKrY4|QU z;U4ll!~6gf?qj=9>F`hYvn@ZxIC+5ag1qF3e2{gaQhc}a4>3=YCj~A;h4>|C~jBL@D^<=PmLqD#puSs5f$Nq3;v;*eE2k2j>?*e8OjUH zOLz}ljS601e*wEt1?he8j2CHV(i`F4FR|_86X0zq4POt(x6qFGIJg!i;cMZjmzi7e zG4N&7Lz!FQRj;UZ(>`$SU)gUe4;Qzx%@SuRd=j+XTo);178n+LOpoTo1BB71bh-a z7bW5g;N2)0Ukl$tsrW7!)XuhvkAsh(JbW9x{4K^3z79tIjWK{vfPY0r_&#{*+w={- z0Jb4%qMQzkC#VRia@eV$G?+B~x%d>Es@bPf&NULPwOJSbJDjw<>%R5od=Uq2F z_?WR)nT-aBAsJ2|XO(X9SHUMy9KI3uj<-qzK4F4Yj*75KExrjB?L|2(TL=F(k!KfB zuc%0?oHWHMNu*a#waT+7M71HDvX52j@Ud_SYQvYpuT(nu-O*OL9i>oC6P!QIDmC;) zDf|a2BTvP?R=GOPDuu-FKG-Thp)B&x;@JqNpf>Vk!i!J`z6j1d%qm`D?t-<4TP2M2 zsNY-V+do*PpY+^WR=FH?kzN899BGvbd^7Av8RT&vWtC@+wn`=I?Mb38^Q_W{&x6}g z2R{55mPJi!y>LvjRiYUuHSjIeKz+O50mqUbUktO4qpk2AF!6Zabx2(@U=2#4%tkn4 zzE#ReZ-u9wNL}#u1y(uiWXi-Br(5NVQ>@a7Px_NpR-+bTXoB-kw@Nti$1k?ZnoQb? zb#=l=mryVA_rTN6V7;Ul!Y@%9>kV0Im8Dt4Po4(&I*KJvJ50^CN<2OfUT_xeiSLK+ zo^6#hmMzG&N)@Uhy%v6hn(%SwT4m01>V?l(L7Srl)xU6K9`(nEoM)Bgs1RQQx1e%- zAKaF2l^A@&N~@fWs+h+r;OnRc-{-Z;$Ez6UFS1`gpLaA~z`F1)@WBGBY$Z=O?7NV< zkRE@LRjxz5q*uewP#t~%&bgSj#izmBP!qlu{)AfaVTD#%g*xz6unXl;W*^+^&sHhG zN5Ofh2%idXK_&R2ODGfdcjnFSW`Qs0`l-`;ZqeMOHZrCE?3q56V*Mms#aV zmTxXR`eB$-AH%fe&F$14O(fH&tt1Lrx zHR0RfQRVa(z8-#q z3h+rcF`jQG4>3gEVwJTOj1#=)R>taW^eaB`cB_0?Nq@aUnRi%aJ*p$U0ltYmq<6ya z&@6oSo%9Q8AdmYltL%fqNsoocpd@@MJQLNBCl9`gs_@dE#oUa{L2~4SYF# z3&p8&;C>I%NB9)D|3lOTp9S}>rOok;aO}gh6=lZ2OOc!Oa`*^pBfTEJhJ^G^_#G<6 zM?b>;5S5W94X#EN_%iqys=_zI&ruD&c0Kz|RL-&;aBLm(A?eX@G0MW{!N*W8z7y{M zDDw$E5nhMV@b&OxRDuuRV3mcaq?LNXyHEqZ4*m@#;k)4I$7pAKWIb~@ipM9xt&h{E z_@XC>_es`;-wH=JFb436@N(2g%*`<5Ddqxv6ucOvyvn-Zo5+pthFg&bFHc+L2o#P_ zgXJg+-vMVn!#s>nhHFp^z72Mxe%9Ly2au31jaE4X^^l$f(@-Bi53WT;l%O1$LoXc=xMpA1Ddm44;3E z_2KQW^K7Ix`V5~8zk7rBe21~LnSDw-@!?D0!oSg{ZL|Ztt%LD{_xzpte+y%kWnP;z!k=G9KXjAJB$9)b~S<2|vPtF)5d05|sFNte%P^UrA?(oJ@X1^0i*M-*@|VGzx8cd(0lU7V z9Y~MvXFvZv>n6PozV!p+nDp=;tukonF-2y#}uTnf@X@^%s^Cn}mGEScR1q zJbAj{Csv!3;$v(!nPInySCtRna@ZvDL(1oULX%uJ$?Bqfc$V8HB_B{eTpwhUHrhOg z=Y5^a^N?c6-w%HZp&as;jI_!1qij+^{_xQ@ne4Gi7x~NJO=E0QLwW~%H`FG5YD|u` z$@DOrgpr;DSB$es66v1tHW@d8m?=LUo)&JCG|I1n_ea>Ifc!o1tG#T}MEzm7lfx!ce|!PFG|DE$)HiC1O{PsHe)8wQbN9iMrw%?DZIfDjKm28y zP0Gn%wJ+x{y4i55P}PA`j(cEutRjHpx?MehSaII+gNOf5CH4vq`;* z2ZmMIIGTHu0QglLQq{4)H9r$$*OIY~snKO;kM4y@Ga7@xV*Z zBaey)e!7x8DjuG9RDM3~rsBDPcrK)T6%Rc3V){tM14A#dNrQ?9URK07QSrbJR+C4? zb2;%`VPg&;o;AdCrA=B@JSD_)wM}NJc%b`Qn?$R4;HB4-N5um_y@5O`p0&hNPFtyX zZX%vrC|||%s!hUQvq=o;v*2bFg71gtzHXDP%%!E!%0qBF@oDccHc|g;#1BVw+9aL% zEesxpnwY~A;Zl^w{G1D~M{UfF74R8U#C+ZiKSk;9a!d}#zDsq}gJ3eGC zBL3Kqs8cs}q3$*CqmLOglo|htO;SJQGuo;J{@g>m5l_iyHmUxc?T$JYeZ#zk+>{x% zmAu<*;-M}bFywoiL{XPYc*l>7RhEq!u*sC4S%$haSnM*_YL{xt$${UZLY57;+2vl; zOC4L_Np`zL(-#HM;jl|7WyZkAQ7v(Hz%!k8sVB}-xR=W=A@oHed<`YgCR^cZw_Um^ zrv@GxMES&!0Y67ow3UZvf34%$Vj09!GRiIwhuS5Mcp7*4F*a?2{8CU8Wc~X9M;teYfh)FSXUQ(W--s-V_jR}>zUMrb-9<=}do zWqcN%WlP{@R7;-ZY`ffuVp*@}OuL+lLfG!AVN4F~#(GPk=WN=9WxcTf9O7jBXXM(Y z>s-6cV!cVr>7NyhE6R+`vrFB1c4=n4Vfl91xRN%Zjxk==yUH%{tZUZ!cKPH2yQEUb z)B?Nwa3SqXIawFkWmF+`A%+4t^%BMq{aXq*t)@)kX}#Po<4TC1cw(+1=4*+Wcyg|z z?6r(P%89v=XNBHE{KR9guuI$R#6UdFm3CQsH*HNkE$b-be&Q#do*KJ6@vvReiKq7w z+W#@?$Xt|JPs|N=i6oxBrx;Tk?b1X%)teYcs9d#Ylb!2cv=8gbeaE>}{jZES z$}EOIp#kEFY-PKC4Nv>@L+=}S))lsy{Oz;}?b8Q;|2E~*KCLi$3+={s)B|U}OPrL` z45PcKC-F4G`5)1S#IqHqeL_2`_JJv%Q4aBR!}EI?SHu(fC23zVhcH)r`|NVa*UTHl zlLJ?LLz@#%9X#)!^b_$^!|bh$XX2@VcYRCy&?a5*?rpRW{nZX{{*Jn+{(>9(nKy`M z0B-!AZG(9F;D#R!KXu$$&?= z9a2v`1u!ckphj@u69)64lXrC~T zL+(QZYP*J6V~CS@N?~HCL&}IJ54y)Xq(+S&*n-lCrw>+#IV6vG+F|ZEhj@r*D_l07 zcN|kr3H%AwP);Q8`@R7+QcfM57VeN7%1MGxp%TjJfG0!{gR0kF#E%BZlL@ayt@wU; zW~4*fD8Cub+}j~txL9MK}9UeA=_F=uL@Rr{>M9AL*e|He^lfMXd%%nZZ zA9pbE#`Au8^7p~R4sl2dV;~t`k6Nf#75o$xFjo8FQHK(bDj$wGj6Af%EchMjAb(5( z@3=>Klpl7uLtaOjW`r^2h#xu{4X=h$k7w9zhJ`&w(jN5)=6=;LM}QLz{1% z&3flh4sDeN*P#~LD)(rIJb+3`Z-D)1E9vee%ACs>Am##CIgjmy@_S%NGUJRq>F}Uq z8GnrD960+pmSMdG@WkWsw0Q|^OkvCubI1vd=lKrlWE_^k=0CDN#$i~hLnfX`IrM1; zT)Kc|7>CvHp@qauo1~;U-u+Pt4|>)@Ho9MX+1hxeZCkXn2%oO>?yrJPQ+6_w!aw=hp4555;xRxrl!EpYX%v=6=xo^cy>#Fr`F zPJH-67+c9Q_;l#LgFeQ`!%t8%KJHFpLs7kqtGgVs5Ji8loXp3Ev8DxQDjJH^UpMi4)%f zdr%R+4}N^FLmKeW_c504r!Vk1&{0D^d@SrjLTsJ~_#Aog;SW0GVAM~ZS@0fIf^USK zs0-f%_j`zaiOK^<*E%E~p9DWa$#~Dhl!;RDA&)rZ6_kq~fQPK7-Bf;fCW^(^z)w)f z*UV#Z=A-1t7r}p^jy}rSK-p*(>FMw?REaNz8 z_*(dK1LGF&d5UsSBgU4Z3RDhmOS{xjm*8MpZv{m^(Mx!$`AK%qOZx53}0yG*aP4Ff!^cjhB}4*U+K;3Ky<F|8y#uvdV)I**c*n-;dZE(c9v=u%Qo{YNiIdC27!`H#jQ3pQiJ?3iU zq0CHp6N=H7dEh%J0q^c|$UZ0$p9t?n$@pd{AF%DF1&sc9M zd;~S)8(=G{BEQ|{l)s`*@(;kj*qxF|o_=_n!zq2_X@}=KdFM2~4t{{b$=?U3xSY~O zdJ(+U%{vRfr9Fe3vJeeWP9Cg6Tk*Bc9`c;OV@V z8lMV#Q4>BahIJl5yWx{!dC&LnoD%XK{SxPt?1P+=hp&Ry&vZ%&z7>9rV(|lT%E3-a z!Nu9G?b1LQ#14@w`_aCE&eq zdJ5}OdEh3Lj_-tro#2!ld@5{01u7jLHJ`r5r^79%7C!)c{zzZrqf?!78EVE?K+B25 ziI0T0pdNe!Ja_?dQm-_4Ckn^c!7ou1egK}dkaouB!UmL%Z-s}au`T1%;A)hIFM}IV zk;()2T|~_ILg+r3v4M|;r=dpLDiXa;e4}310F^^9;i|rIu3^1NyM-Foe-m{Exga+`L za1AQLm%#>9f^UYsr~qGowo}eH$0-^3N*I<)o8Z&oJ*W)d0LPunc7%^y?v(q`EPM;R zbp?Hg?|?_<(Wm%acqK~xi8A4nC>`Gf-#?FS6Q7vxl-p4zz8?OFV)248VwK%Dq;_{m!8 zi=TBP`vO!={*ZF&gevjL@bsJLJA5s?p@Me9XWYu1bUW?LvITHyCEEzT3Z8HW<42{# zBkm-Ad>$Nq7yA!Q{`w-(0p9OD3F%r!0 z*671p=0JP_EP9yo@!m&>Z9RRV((Bk4Bc9{LZ>Wg>QTh?z1ZQlZt?()EQPhCn3P(Ri zy)3~J4i83Q_%yfz#o`O#jVKad3IB@h_zvi*r`_>ka2^_<%rtm8YQa}S$1}7qzP`~Z zucHj|cf(&$7T*1=Q$jZ~hVf}|&0iRYs>~Ot2P(x^!b@7%58>NicFI?%7w>t+DRa;O zJ`KKsI`MsQ#%s(o_>k9`W6@T89873q{>K->@Hc29d?I`qg;{AgxO_A9!k58o-=rPz zt+1_~cEE?dMcx0#c7#uYiElGT@zEW$1FFCm!f{)OS$TLn%EDK}W8Y!?+vq!ZbSLA1 z^aAL4ml#w!JiUwUiuCXgoMQcuJ|cY)%&Uc@Ezsz zj%vkOC;{*PzH9X^?5ZCbV=Sw<5%uAl2b^;EPqYvDJK#${bL@e)|H5{Pit%l*!se1Z ze1+X5u@0A1;4|T+ZkIITlY?CH9;(6HgL#J%>cL0B6{rti480><(vNS2ts%Sz$jNvc z>5_*=@!nK?6a`BE``VMxYj3C~R09Q{XCO6}JAD0{+ zO&)wEv`lkJF+LW~*q3VH|!NmP|KP|ovChyO?Jyjlf6YpG3#&^NK8T1*x z`FAc^#XE;{$zKn*qDs8|AeSsf)%XfHZzgSu_rh%lyEs>%J>y++!(5j{g;3_Pyi@o% z-h0cF?_%L;$U}NAEJESREYO~cd-Avfz>;L*P;g2rPzqt@QUxEZhTxi zpP%NED$0rC9mdO0De3<2E>`a~ZbO-*EB=TI@EJ>J*OkOUyTul`O? z<%~g8MxLl*mwb$>@!?nSPFmD}PgvuUzoQm7X7ruou@qKX0 zZER!YkAo+oc6F;j^e1-vawlE#7`RV-{88V_}98J_nYdG<+FsLXG%V*o*4% zTVZr1eTR>OsVEDd4lhQ%_+oeq>c&^XO{fyz0^dR9_%3L>gMPt>z{#i?9}SN|h4@ss z6nXKnce*4W6;tws8;puLoQ*=|Pvc@kww6%ETAKeIBBZ@G0?2f^UP~7Gl6x!GxC?-}p?}k4o`TuduzKetactL^787 z8G8OoJL99F7kThStu8rWGvgee__j-eJ7{No(iUQPhwTgB3CF$5oPdvd&n4f#Paom) zx?D2m1DB-WXTkeX5xyBd^SUOu9(r~;n~|B2f0k==}Q)Pv9Z*d?w{s0%(0wxb5T zeCm=1Q3CIS?Sm6~hyfo3PeoDqT(}Vlz8&_V7<@l`;xp=t?}3Xyr(f`ea2=||&-#LX zM5Xvn=}iJ0+a zP=02;_(YhA!p1Y7z!J1o<$-l5g!BeD{}<*)(!H=8_2MgG0#7~f#Am`!Q6%}@7PqWJ z@%S#-hf?uLR=2!@((#Elw;aTyfW7!Uc)r6e75IMmrQ0nn`1&BXyo0vlyW!U%ZVBOi z?e!zw@*e6Xy$6mT<(4LVH2fM3D9^huXQOEHC&OkGi|>Xu-UXb44}p_VCO#S_k8w*6 zz8sc~rA)ks_l`b}YVlq0=5fS{Z-%FjcS|w87{>CR^E`ZiBz2$UmQvnB-3rg*oxAb) zGWa%1!uP-;-j$hyuYt3p+>(aRf!k04K5~j%)}wNKI}D!cmK3}fhVJ8*N_;20Iod6D zd^0?Bnp>jqX>i{dw^ZX3dEex3`-Ork5}d?&Nyf zrNo9}Z|9mAycm@}#Pt){fHG^i#!}>#1Cjed&Z*&_Q4_unzKXK&QJ1;p2vqg}>F`w) zj$gc*v4oO01j)s)9M$3#YfwG@G58tk!*7G5E+_uSxYh*kMHNp3$;&XOn04W=htsZb z^Q@*IIS#Hsxli*99QY~n;zz9^9+dG+kj5r_7QPo+uXIcQQ$ZT1;f4GM!(&l9UNIMS z;;({tA@4@6!@#GJyCq0A!M9KXehb`+a$e@yGH`kc+Z}!;OhI+6L9zhmqAq+sycV@{ zkKc{(5mb$@hp(eB{9CXOdGXuen5!78_z7?(>gL|y1h@dD@LgLv%txL00=O0x;w#_= zREuwbn^8R9C3V1WP&vLIhF;CM#fQV0C<~tePeD!iCGaAY!S`;8H=->3UGOQC$aU;Z zumd%4?fpI2k8*wplAqy(YuHBcli*<}oa<&sz(uHw>w6jS&!`4}1-uhw;H%*#)I|Ol z;D=}{{xfJVWj^6LRWO{2YPhx&1LvS9u8kzaC8!R67A!&yoLjAdccCc!z3>y%%{kgO z=;58w9?pZt!vj$vekME~m2-Tq-u<3~qS?Qzcexj%OuTxx`aP%Z(tM`k) zi~8{DebhgpR`xIIebbSsAFtj8Js;&TZ>#qNUxCt@yVUz>>rgNA!=8V8T3}BL>}i2L zEwHBr_O!sB7TD7Qds^VPZh@A+`;I%G(D|UwN}Yex`CG@4rLSkc&RII+bROB|i}ND= z?x|Qxt}{z#zRn_@SL>|M`Jm25ov-NZ(z#7%@VmbCjn_F<=M0^5 zbS}`DrE|H?i*&BhS)ubmoy|Jm)7h`n{+@5Wp*o{`_@t#hr;8l4+; zw(0EB`464W_x1MG8Le}s&N(_4={!ScfzGRS-lp>rolon0MQ4}Jf9M?08KRHdNS!lu zrt18yx2ylQ@)O?j^@obffIE%GWk~<||)2?3u58?XYLQ z8fwP)_tMX?9+T}&S+dfrz0^uQDj;PAuN<0}pPem_TIQ|DKX-}ugzS|omzWEy!Myb+X*5`MJw^{ZsxD?bDmJl%(w3Z1rcQ z_Lml<%uZS~JM~zj%=hgJytzj&$@8wt&pvv^axbsHl227y%8C`|tje3GzgB7Pa&P{H z{76H6vS?Ypch!>Ila^nwY3#^UqzjoLU%3a+B@YmHHnm^5RTh!v+ZQZZwlaIL_4uKb%H?a|xdn0wF;F93ICf5UR_dyiIa+UM z(MX~HXY+FT(3gIKYI(nLdWdE2@};~QDRsp%t#uCPZ^}HH!L*F=yD(dOdlrw7vZZ7% zIX`=+^e~HWECqhx^=qGi&t@;rT9~(Nxz-=D(UF$Ba<+PDnn;uKG|i$VxvR3}IrSI8 z`u^Ia{?Z2O;}(UKWoP6sVdyogwp4>)c2*W$zf$B)w!9@-`sZ^CXxkji+=69;Bk8ih z*4Oe}vOQJxfO=yTOHNa%`bhMR3f>6v|Fw6uA&y;T_|$GSZE+1nG-|ci+BOll-E1p1 z*4b{lv%93QZNu)i8$_LCXEK}EOmdr#X;#z*iV{H~f=H~j+?(Wnf91z2`5_W5NI;QT zD&(ILqy$k3Vr_&9KIh&unaQ+uTSaVb2Htsc-gEDJ?s?ApzUQ8N+;cUChxab|3+`(# zexA7M6#RZQS16^)*WA~qve^2VT60_YuB&?xfkaj3$@k$a=v#JUmC}#AfbUYGwfk1% zgtTe951o8~zWxQ(uEweB;1gT=y08U@Mi28y1;5*;IZuw$b5G{Cv&BN5?)rANT+HS# zme8BaE_1I|6{cRXr{a-RF`K$Tud;L1srmTG^fiooBcjmKe0(HYa)~%Z+dqLg^^zXi zz3FObXw=L#&k%HiPZiVN#o?HrUVVD?ffPS47pN6Cg{HlrAwSsR%hQq|wfb-=T|ANA zOd*?|UcLVWA)kl;R<^v5^$w&xf0kNfse+Cke%eGeXUiL2O2yaVX_*epIczG1Cy}6I zNPDG1F1=bV=Deedc!HFB7A2G(2g~cO2b@I~!2Un(>oaN3H!{@5o)$DPgfOIS9ItF* zFGKk1UGH?WHr0{qsBPBfLzOaL!JuPLo;_Nm47757=Spd#$O6Y`JJbRTVW`NH2Wb9x z&61k?ni<9w2M>7G-8?nt`&V=(po0cO=gBvS>&J|oJH4x%oA`^%f}0gxul&7-e{lVV+@~ z;nNI%#PF94f6wq`hJn9%_U~kPnjz2dI}CM(J%-OSoH0De`h6S2dl{Z#m}B^LhEFrR z%y7VP#&AEsZjg44-HC0>c@@>sY^UWOxU|D8n-h zHyCa+tTTLy;ZGR8S;lq$b=;lIr}*sJ#dLWshgGk)TdunqDniz;^d@dpv6lMG zt~Ou6vi0z8`9cBrS*bj}VCm`B-CL2hg1hfC_On~irre!&AJ1aPVQ;Hl@_~i=l6$|4 zt14&nN63d>t*%nujF5v1HSV6uz${K6bHB8QV zwV70DjV~7Xbg_Jitn8jK*Ht`S30Cr0Z*1%y9oap4UrlNE9IWB#{XHQ!dpeKl9V6K^ z?k``0VT=;p`*^++GWNyuj%O?vclOmLx9!-WZw{>O>W_JP+S|F(>o*}6y*l(Vzviv> z*GlUs5%Le#HeC=cR&DM%CtX@k@pP%NcnEoU@7b?$P{_06*6y5-ohLnQIa4e=j`e_7 z%9hsVJ1wu_S~qY9PY!u?v|m_Ht*yfci_DvM-moC=^NwL$Vd%E7A}5b|S}ZsVx$X2C zn1`Fd$#Xk;x?%aQnta^TZ>GwroEIvDT(e*~Rl1a4Uwgbze3X!nc{LmEn>1^CYi?XP zr*vuSLILmp+_0eC+3^~CCwh9?zx4|&Hs7;wEEc2bVm<{MDNn!UzR!eVzKFLp=sPtT zPybjY4KLq&Df<(`vb_qo7i{h zBKAiD-UNIK@&ts3OriT0@L|X)$PndqU>M?qbWz^UV$UT=3UU^55^@CcVaTmAPI`gza;~2O9l`d=r^Rc*nPw&6yaCVUwZ)i zhog@F==F5V$K~G@7+5)0-O6#>_>>@9$R79jX-JjnsJen>Bxk~oF zb^4+3(coq(S4s!D!*e?;hhMvumBS0yv~qafIh?+7c!xI>t}r&s>LmkjI|c;&t`D8| zi_uQJlk7AULFuY9lUP10Y(=c76}J*r(i&JpYh+EVsWr2R?X&%Mz~*e6*u`)A00|)} zWCUKQ3N@iFGz3-X3O%7O41}RD62`(zAfiw7ivf`nLt-Z$U6p%tvSc*t7 zDJ~_XjKoV-sV+67rW7_KX2MLG8MA8E%!Hk>dAn*0cGvFPLwjsbZQ}SH&IvnFC+;L2 z-l;haM{v4M-x)e%XX>D1eINNTfCzqp6T(7Nh@+=Gdf5;J^s$frjfE+C=SR=NVif&K zqE9ukfgW|yo1r)sry^bCl=VQbu)wn*FG=Gx(Qv>k6J z+dO*TXbbIbyWbwR$L(pGbo?C-OhnyL;yX34A#}Q(KG+z83j!uM@DK$HNpMgD19*T8 z`3^3902?D%nY3rHpry;N!0k1JIn*g^Nuv-Pcbuion z$EwTn06dSt^aNbbz_t&32f%m;oJYWV47?}6d5i ziQxkunO88LVfAciAWV<$%n|Avr8Zz;Fy4C%|$>=H;qP2!6+l!@B=-?-Hc0 z)R%_RSei-%*UaI1J%8Zg5e-?8yK-M1%42yd69o?=A`RRF4&ZIn*L<#@MO+`txc=4b zP~RH3@k^tZ#x9Lq8n-lRo02N^q=7V&Celpufuj)kiGiC8c&W=xS(SV8Kpx2xc_#am zfD%$7N=!*88KtV!m8PO9J!PPbl!-D^d}=@qsS!1%Ce(~tRqJX~Rn?w4P)F)SovA)8 zpoO%E7Sj^&>nc3Esi|5|8)zeKqRlj)9?(O2M33nSJ)>9ky57`Py{8ZKkv_r5`;34Q zG9pIINMQV{h=!&c2?IpI#F()dh`|37ZVsxOO;a^{=D-}86LV(ztbi3lj*TJ1W~{1J zx0;q}^^j{v$h0%dha4NSBX-PAAa_;my4|!@yJrvVkv*|zw$BMTAt&O*oP?8cs!rW$ zI;zui2F?i4hFIh9+&}n{4{;VkjKvUN8D!|X&_sUjAvceN2{N+}Sve#|kdqULzN%P9 z+^NXK1960CL#&1I>_?1i{7sYD-k4wd6;25&Q6;V<6<(<+4LZjuePyVOm8pV9$*7zf zR-FHljw{&6_pkOu^_PUk;Hgrv@?oCWlNJHRG78 zc+6A{Q!u+`-yE7_bBdYRZ*iE5qnL@47H`$8h9y{CtB)CZjQN;gF6Qj89kt_j5;I)Q zZd_rG!vlZ`zJf%0|F$OwFlR>KWnNY%VLV5}^)s5$yYMLjU&_FbRQS+L^zyWuiCtDk z;AH}4yxi$`qbQ6xiXxKYh@~VVDGHAlFh~0_H}ja2M|3WZ;+Y|CI}!M?0Ppo-zO5m{ z50TS3, Brendan Forster , Hari Juturu -// Adapted from DefinitelyTyped: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/keytar/index.d.ts - -/** - * Get the stored password for the service and account. - * - * @param service The string service name. - * @param account The string account name. - * - * @returns A promise for the password string. - */ -export declare function getPassword(service: string, account: string): Promise; - -/** - * Add the password for the service and account to the keychain. - * - * @param service The string service name. - * @param account The string account name. - * @param password The string password. - * - * @returns A promise for the set password completion. - */ -export declare function setPassword(service: string, account: string, password: string): Promise; - -/** - * Delete the stored password for the service and account. - * - * @param service The string service name. - * @param account The string account name. - * - * @returns A promise for the deletion status. True on success. - */ -export declare function deletePassword(service: string, account: string): Promise; - -/** - * Find a password for the service in the keychain. - * - * @param service The string service name. - * - * @returns A promise for the password string. - */ -export declare function findPassword(service: string): Promise; - -/** - * Find all accounts and passwords for `service` in the keychain. - * - * @param service The string service name. - * - * @returns A promise for the array of found credentials. - */ -export declare function findCredentials(service: string): Promise>; diff --git a/lib/authentication/SecureStorage/keytar/lib/keytar.js b/lib/authentication/SecureStorage/keytar/lib/keytar.js deleted file mode 100644 index 027456c56..000000000 --- a/lib/authentication/SecureStorage/keytar/lib/keytar.js +++ /dev/null @@ -1,43 +0,0 @@ -var keytar = require('../build/Release/keytar.node') - -function checkRequired(val, name) { - if (!val || val.length <= 0) { - throw new Error(name + ' is required.'); - } -} - -module.exports = { - getPassword: function (service, account) { - checkRequired(service, 'Service') - checkRequired(account, 'Account') - - return keytar.getPassword(service, account) - }, - - setPassword: function (service, account, password) { - checkRequired(service, 'Service') - checkRequired(account, 'Account') - checkRequired(password, 'Password') - - return keytar.setPassword(service, account, password) - }, - - deletePassword: function (service, account) { - checkRequired(service, 'Service') - checkRequired(account, 'Account') - - return keytar.deletePassword(service, account) - }, - - findPassword: function (service) { - checkRequired(service, 'Service') - - return keytar.findPassword(service) - }, - - findCredentials: function (service) { - checkRequired(service, 'Service') - - return keytar.findCredentials(service) - } -} diff --git a/lib/authentication/SecureStorage/keytar/package.json b/lib/authentication/SecureStorage/keytar/package.json deleted file mode 100644 index 6254f49db..000000000 --- a/lib/authentication/SecureStorage/keytar/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "main": "./lib/keytar.js", - "typings": "keytar.d.ts", - "name": "keytar", - "description": "Bindings to native Mac/Linux/Windows password APIs", - "version": "7.9.0", - "gypfile": true, - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/atom/node-keytar.git" - }, - "bugs": { - "url": "https://github.com/atom/node-keytar/issues" - }, - "homepage": "http://atom.github.io/node-keytar", - "keywords": [ - "keychain", - "password", - "passwords", - "credential", - "credentials", - "vault", - "credential vault" - ], - "files": [ - "lib", - "src", - "binding.gyp", - "keytar.d.ts" - ], - "types": "./keytar.d.ts", - "scripts": { - "install": "prebuild-install || npm run build", - "build": "node-gyp rebuild", - "lint": "npm run cpplint", - "cpplint": "node-cpplint --filters legal-copyright,build-include,build-namespaces src/*.cc", - "test": "npm run lint && npm rebuild && mocha --require babel-core/register spec/", - "prebuild-napi-x64": "prebuild -t 3 -r napi -a x64 --strip", - "prebuild-napi-ia32": "prebuild -t 3 -r napi -a ia32 --strip", - "prebuild-napi-arm64": "prebuild -t 3 -r napi -a arm64 --strip", - "prebuild-napi-armv7l": "prebuild -t 3 -r napi -a armv7l --strip", - "upload": "node ./script/upload.js" - }, - "devDependencies": { - "babel-core": "^6.26.3", - "babel-plugin-transform-async-to-generator": "^6.24.1", - "chai": "^4.2.0", - "mocha": "^9.2.0", - "node-cpplint": "~0.4.0", - "node-gyp": "^8.4.1", - "prebuild": "^11.0.2" - }, - "dependencies": { - "node-addon-api": "^4.3.0", - "prebuild-install": "^7.0.1" - }, - "binary": { - "napi_versions": [ - 3 - ] - }, - "config": { - "runtime": "napi", - "target": 3 - } -} \ No newline at end of file diff --git a/lib/authentication/SecureStorage/keytar/src/async.cc b/lib/authentication/SecureStorage/keytar/src/async.cc deleted file mode 100644 index aef449add..000000000 --- a/lib/authentication/SecureStorage/keytar/src/async.cc +++ /dev/null @@ -1,242 +0,0 @@ -#include -#include - -#include "napi.h" -#include "keytar.h" -#include "async.h" - -using keytar::KEYTAR_OP_RESULT; - -SetPasswordWorker::SetPasswordWorker( - const std::string& service, - const std::string& account, - const std::string& password, - const Napi::Env &env -) : AsyncWorker(env), - service(service), - account(account), - password(password), - deferred(Napi::Promise::Deferred::New(env)) {} - -SetPasswordWorker::~SetPasswordWorker() {} - -Napi::Promise SetPasswordWorker::Promise() { - return deferred.Promise(); -} - -void SetPasswordWorker::Execute() { - std::string error; - KEYTAR_OP_RESULT result = keytar::SetPassword(service, - account, - password, - &error); - if (result == keytar::FAIL_ERROR) { - SetError(error.c_str()); - } -} - -void SetPasswordWorker::OnOK() { - Napi::HandleScope scope(Env()); - deferred.Resolve(Env().Undefined()); -} - -void SetPasswordWorker::OnError(Napi::Error const &error) { - Napi::HandleScope scope(Env()); - deferred.Reject(error.Value()); -} - - -GetPasswordWorker::GetPasswordWorker( - const std::string& service, - const std::string& account, - const Napi::Env &env -) : AsyncWorker(env), - service(service), - account(account), - deferred(Napi::Promise::Deferred::New(env)) {} - -GetPasswordWorker::~GetPasswordWorker() {} - -Napi::Promise GetPasswordWorker::Promise() { - return deferred.Promise(); -} - -void GetPasswordWorker::Execute() { - std::string error; - KEYTAR_OP_RESULT result = keytar::GetPassword(service, - account, - &password, - &error); - if (result == keytar::FAIL_ERROR) { - SetError(error.c_str()); - } else if (result == keytar::FAIL_NONFATAL) { - success = false; - } else { - success = true; - } -} - -void GetPasswordWorker::OnOK() { - Napi::HandleScope scope(Env()); - Napi::Value val = Env().Null(); - if (success) { - val = Napi::String::New(Env(), password.data(), - password.length()); - } - deferred.Resolve(val); -} - -void GetPasswordWorker::OnError(Napi::Error const &error) { - Napi::HandleScope scope(Env()); - deferred.Reject(error.Value()); -} - -DeletePasswordWorker::DeletePasswordWorker( - const std::string& service, - const std::string& account, - const Napi::Env &env -) : AsyncWorker(env), - service(service), - account(account), - deferred(Napi::Promise::Deferred::New(env)) {} - -DeletePasswordWorker::~DeletePasswordWorker() {} - -Napi::Promise DeletePasswordWorker::Promise() { - return deferred.Promise(); -} - -void DeletePasswordWorker::Execute() { - std::string error; - KEYTAR_OP_RESULT result = keytar::DeletePassword(service, account, &error); - if (result == keytar::FAIL_ERROR) { - SetError(error.c_str()); - } else if (result == keytar::FAIL_NONFATAL) { - success = false; - } else { - success = true; - } -} - -void DeletePasswordWorker::OnOK() { - Napi::HandleScope scope(Env()); - deferred.Resolve(Napi::Boolean::New(Env(), success)); -} - -void DeletePasswordWorker::OnError(Napi::Error const &error) { - Napi::HandleScope scope(Env()); - deferred.Reject(error.Value()); -} - -FindPasswordWorker::FindPasswordWorker( - const std::string& service, - const Napi::Env &env -) : AsyncWorker(env), - service(service), - deferred(Napi::Promise::Deferred::New(env)) {} - -FindPasswordWorker::~FindPasswordWorker() {} - -Napi::Promise FindPasswordWorker::Promise() { - return deferred.Promise(); -} - -void FindPasswordWorker::Execute() { - std::string error; - KEYTAR_OP_RESULT result = keytar::FindPassword(service, - &password, - &error); - if (result == keytar::FAIL_ERROR) { - SetError(error.c_str()); - } else if (result == keytar::FAIL_NONFATAL) { - success = false; - } else { - success = true; - } -} - -void FindPasswordWorker::OnOK() { - Napi::HandleScope scope(Env()); - Napi::Value val = Env().Null(); - if (success) { - val = Napi::String::New(Env(), password.data(), - password.length()); - } - deferred.Resolve(val); -} - -void FindPasswordWorker::OnError(Napi::Error const &error) { - Napi::HandleScope scope(Env()); - deferred.Reject(error.Value()); -} - -FindCredentialsWorker::FindCredentialsWorker( - const std::string& service, - const Napi::Env &env -) : AsyncWorker(env), - service(service), - deferred(Napi::Promise::Deferred::New(env)) {} - -FindCredentialsWorker::~FindCredentialsWorker() {} - -Napi::Promise FindCredentialsWorker::Promise() { - return deferred.Promise(); -} - -void FindCredentialsWorker::Execute() { - std::string error; - KEYTAR_OP_RESULT result = keytar::FindCredentials(service, - &credentials, - &error); - if (result == keytar::FAIL_ERROR) { - SetError(error.c_str()); - } else if (result == keytar::FAIL_NONFATAL) { - success = false; - } else { - success = true; - } -} - -void FindCredentialsWorker::OnOK() { - Napi::HandleScope scope(Env()); - Napi::Env env = Env(); - - if (success) { - Napi::Array val = Napi::Array::New(env, credentials.size()); - unsigned int idx = 0; - std::vector::iterator it; - for (it = credentials.begin(); it != credentials.end(); it++) { - keytar::Credentials cred = *it; - Napi::Object obj = Napi::Object::New(env); - - Napi::String account = Napi::String::New(env, - cred.first.data(), - cred.first.length()); - - Napi::String password = Napi::String::New(env, - cred.second.data(), - cred.second.length()); - -#ifndef _WIN32 -#pragma GCC diagnostic ignored "-Wunused-result" -#endif - obj.Set("account", account); -#ifndef _WIN32 -#pragma GCC diagnostic ignored "-Wunused-result" -#endif - obj.Set("password", password); - - (val).Set(idx, obj); - ++idx; - } - - deferred.Resolve(val); - } else { - deferred.Resolve(Napi::Array::New(env, 0)); - } -} - -void FindCredentialsWorker::OnError(Napi::Error const &error) { - Napi::HandleScope scope(Env()); - deferred.Reject(error.Value()); -} diff --git a/lib/authentication/SecureStorage/keytar/src/async.h b/lib/authentication/SecureStorage/keytar/src/async.h deleted file mode 100644 index e29928cec..000000000 --- a/lib/authentication/SecureStorage/keytar/src/async.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef SRC_ASYNC_H_ -#define SRC_ASYNC_H_ - -#include -#include "napi.h" - -#include "credentials.h" - -class SetPasswordWorker : public Napi::AsyncWorker { - public: - SetPasswordWorker(const std::string& service, const std::string& account, const std::string& password, - const Napi::Env &env); - - ~SetPasswordWorker(); - - void Execute(); - void OnOK(); - void OnError(Napi::Error const &error); - Napi::Promise Promise(); - - private: - const std::string service; - const std::string account; - const std::string password; - Napi::Promise::Deferred deferred; -}; - -class GetPasswordWorker : public Napi::AsyncWorker { - public: - GetPasswordWorker(const std::string& service, const std::string& account, - const Napi::Env &env); - - ~GetPasswordWorker(); - - void Execute(); - void OnOK(); - void OnError(Napi::Error const &error); - Napi::Promise Promise(); - - private: - const std::string service; - const std::string account; - std::string password; - bool success; - const Napi::Promise::Deferred deferred; -}; - -class DeletePasswordWorker : public Napi::AsyncWorker { - public: - DeletePasswordWorker(const std::string& service, const std::string& account, - const Napi::Env &env); - - ~DeletePasswordWorker(); - - void Execute(); - void OnOK(); - void OnError(Napi::Error const &error); - Napi::Promise Promise(); - - private: - const std::string service; - const std::string account; - bool success; - Napi::Promise::Deferred deferred; -}; - -class FindPasswordWorker : public Napi::AsyncWorker { - public: - FindPasswordWorker(const std::string& service, const Napi::Env &env); - - ~FindPasswordWorker(); - - void Execute(); - void OnOK(); - void OnError(Napi::Error const &error); - Napi::Promise Promise(); - - private: - const std::string service; - std::string password; - bool success; - const Napi::Promise::Deferred deferred; -}; - -class FindCredentialsWorker : public Napi::AsyncWorker { - public: - FindCredentialsWorker(const std::string& service, const Napi::Env &env); - - ~FindCredentialsWorker(); - - void Execute(); - void OnOK(); - void OnError(Napi::Error const &error); - Napi::Promise Promise(); - - private: - const std::string service; - std::vector credentials; - bool success; - const Napi::Promise::Deferred deferred; -}; - -#endif // SRC_ASYNC_H_ diff --git a/lib/authentication/SecureStorage/keytar/src/credentials.h b/lib/authentication/SecureStorage/keytar/src/credentials.h deleted file mode 100644 index 99e071b16..000000000 --- a/lib/authentication/SecureStorage/keytar/src/credentials.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef SRC_CREDENTIALS_H_ -#define SRC_CREDENTIALS_H_ - -#include -#include - -namespace keytar { - -typedef std::pair Credentials; - -} - -#endif // SRC_CREDENTIALS_H_ diff --git a/lib/authentication/SecureStorage/keytar/src/keytar.h b/lib/authentication/SecureStorage/keytar/src/keytar.h deleted file mode 100644 index 1a6d3ada0..000000000 --- a/lib/authentication/SecureStorage/keytar/src/keytar.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef SRC_KEYTAR_H_ -#define SRC_KEYTAR_H_ - -#include -#include - -#include "credentials.h" - -namespace keytar { - -enum KEYTAR_OP_RESULT { - SUCCESS, - FAIL_ERROR, - FAIL_NONFATAL -}; - -KEYTAR_OP_RESULT SetPassword(const std::string& service, - const std::string& account, - const std::string& password, - std::string* error); - -KEYTAR_OP_RESULT GetPassword(const std::string& service, - const std::string& account, - std::string* password, - std::string* error); - -KEYTAR_OP_RESULT DeletePassword(const std::string& service, - const std::string& account, - std::string* error); - -KEYTAR_OP_RESULT FindPassword(const std::string& service, - std::string* password, - std::string* error); - -KEYTAR_OP_RESULT FindCredentials(const std::string& service, - std::vector*, - std::string* error); - -} // namespace keytar - -#endif // SRC_KEYTAR_H_ diff --git a/lib/authentication/SecureStorage/keytar/src/keytar_mac.cc b/lib/authentication/SecureStorage/keytar/src/keytar_mac.cc deleted file mode 100644 index 93741bd62..000000000 --- a/lib/authentication/SecureStorage/keytar/src/keytar_mac.cc +++ /dev/null @@ -1,296 +0,0 @@ -#include -#include "keytar.h" -#include "credentials.h" - - -namespace keytar { - -/** - * Converts a CFString to a std::string - * - * This either uses CFStringGetCStringPtr or (if that fails) - * CFStringGetCString, trying to be as efficient as possible. - */ -const std::string CFStringToStdString(CFStringRef cfstring) { - const char* cstr = CFStringGetCStringPtr(cfstring, kCFStringEncodingUTF8); - - if (cstr != NULL) { - return std::string(cstr); - } - - CFIndex length = CFStringGetLength(cfstring); - // Worst case: 2 bytes per character + NUL - CFIndex cstrPtrLen = length * 2 + 1; - char* cstrPtr = static_cast(malloc(cstrPtrLen)); - - Boolean result = CFStringGetCString(cfstring, - cstrPtr, - cstrPtrLen, - kCFStringEncodingUTF8); - - std::string stdstring; - if (result) { - stdstring = std::string(cstrPtr); - } - - free(cstrPtr); - - return stdstring; -} - -const std::string errorStatusToString(OSStatus status) { - std::string errorStr; - CFStringRef errorMessageString = SecCopyErrorMessageString(status, NULL); - - const char* errorCStringPtr = CFStringGetCStringPtr(errorMessageString, - kCFStringEncodingUTF8); - if (errorCStringPtr) { - errorStr = std::string(errorCStringPtr); - } else { - errorStr = std::string("An unknown error occurred."); - } - - CFRelease(errorMessageString); - return errorStr; -} - -KEYTAR_OP_RESULT AddPassword(const std::string& service, - const std::string& account, - const std::string& password, - std::string* error) { - OSStatus status = SecKeychainAddGenericPassword(NULL, - service.length(), - service.data(), - account.length(), - account.data(), - password.length(), - password.data(), - NULL); - - if (status != errSecSuccess) { - *error = errorStatusToString(status); - return FAIL_ERROR; - } - - return SUCCESS; -} - -KEYTAR_OP_RESULT SetPassword(const std::string& service, - const std::string& account, - const std::string& password, - std::string* error) { - SecKeychainItemRef item; - OSStatus result = SecKeychainFindGenericPassword(NULL, - service.length(), - service.data(), - account.length(), - account.data(), - NULL, - NULL, - &item); - - if (result == errSecItemNotFound) { - return AddPassword(service, account, password, error); - } else if (result != errSecSuccess) { - *error = errorStatusToString(result); - return FAIL_ERROR; - } - - result = SecKeychainItemModifyAttributesAndData(item, - NULL, - password.length(), - password.data()); - CFRelease(item); - if (result != errSecSuccess) { - *error = errorStatusToString(result); - return FAIL_ERROR; - } - - return SUCCESS; -} - -KEYTAR_OP_RESULT GetPassword(const std::string& service, - const std::string& account, - std::string* password, - std::string* error) { - void *data; - UInt32 length; - OSStatus status = SecKeychainFindGenericPassword(NULL, - service.length(), - service.data(), - account.length(), - account.data(), - &length, - &data, - NULL); - - if (status == errSecItemNotFound) { - return FAIL_NONFATAL; - } else if (status != errSecSuccess) { - *error = errorStatusToString(status); - return FAIL_ERROR; - } - - *password = std::string(reinterpret_cast(data), length); - SecKeychainItemFreeContent(NULL, data); - return SUCCESS; -} - -KEYTAR_OP_RESULT DeletePassword(const std::string& service, - const std::string& account, - std::string* error) { - SecKeychainItemRef item; - OSStatus status = SecKeychainFindGenericPassword(NULL, - service.length(), - service.data(), - account.length(), - account.data(), - NULL, - NULL, - &item); - if (status == errSecItemNotFound) { - // Item could not be found, so already deleted. - return FAIL_NONFATAL; - } else if (status != errSecSuccess) { - *error = errorStatusToString(status); - return FAIL_ERROR; - } - - status = SecKeychainItemDelete(item); - CFRelease(item); - if (status != errSecSuccess) { - *error = errorStatusToString(status); - return FAIL_ERROR; - } - - return SUCCESS; -} - -KEYTAR_OP_RESULT FindPassword(const std::string& service, - std::string* password, - std::string* error) { - SecKeychainItemRef item; - void *data; - UInt32 length; - - OSStatus status = SecKeychainFindGenericPassword(NULL, - service.length(), - service.data(), - 0, - NULL, - &length, - &data, - &item); - if (status == errSecItemNotFound) { - return FAIL_NONFATAL; - } else if (status != errSecSuccess) { - *error = errorStatusToString(status); - return FAIL_ERROR; - } - - *password = std::string(reinterpret_cast(data), length); - SecKeychainItemFreeContent(NULL, data); - CFRelease(item); - return SUCCESS; -} - -Credentials getCredentialsForItem(CFDictionaryRef item) { - CFStringRef service = (CFStringRef) CFDictionaryGetValue(item, - kSecAttrService); - CFStringRef account = (CFStringRef) CFDictionaryGetValue(item, - kSecAttrAccount); - - CFMutableDictionaryRef query = CFDictionaryCreateMutable( - NULL, - 0, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - - CFDictionaryAddValue(query, kSecAttrService, service); - CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword); - CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne); - CFDictionaryAddValue(query, kSecReturnAttributes, kCFBooleanTrue); - CFDictionaryAddValue(query, kSecReturnData, kCFBooleanTrue); - CFDictionaryAddValue(query, kSecAttrAccount, account); - - Credentials cred; - CFTypeRef result = NULL; - OSStatus status = SecItemCopyMatching((CFDictionaryRef) query, &result); - - CFRelease(query); - - if (status == errSecSuccess) { - CFDataRef passwordData = (CFDataRef) CFDictionaryGetValue( - (CFDictionaryRef) result, - CFSTR("v_Data")); - CFStringRef password = CFStringCreateFromExternalRepresentation( - NULL, - passwordData, - kCFStringEncodingUTF8); - - cred = Credentials( - CFStringToStdString(account), - CFStringToStdString(password)); - - CFRelease(password); - } - - if (result != NULL) { - CFRelease(result); - } - - return cred; -} - -KEYTAR_OP_RESULT FindCredentials(const std::string& service, - std::vector* credentials, - std::string* error) { - CFStringRef serviceStr = CFStringCreateWithCString( - NULL, - service.c_str(), - kCFStringEncodingUTF8); - - CFMutableDictionaryRef query = CFDictionaryCreateMutable( - NULL, - 0, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword); - CFDictionaryAddValue(query, kSecAttrService, serviceStr); - CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitAll); - CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue); - CFDictionaryAddValue(query, kSecReturnAttributes, kCFBooleanTrue); - - CFTypeRef result = NULL; - OSStatus status = SecItemCopyMatching((CFDictionaryRef) query, &result); - - CFRelease(serviceStr); - CFRelease(query); - - if (status == errSecSuccess) { - CFArrayRef resultArray = (CFArrayRef) result; - int resultCount = CFArrayGetCount(resultArray); - - for (int idx = 0; idx < resultCount; idx++) { - CFDictionaryRef item = (CFDictionaryRef) CFArrayGetValueAtIndex( - resultArray, - idx); - - Credentials cred = getCredentialsForItem(item); - credentials->push_back(cred); - } - } else if (status == errSecItemNotFound) { - return FAIL_NONFATAL; - } else { - *error = errorStatusToString(status); - return FAIL_ERROR; - } - - if (result != NULL) { - CFRelease(result); - } - - return SUCCESS; -} - -} // namespace keytar diff --git a/lib/authentication/SecureStorage/keytar/src/keytar_posix.cc b/lib/authentication/SecureStorage/keytar/src/keytar_posix.cc deleted file mode 100644 index 3a5ba7ca0..000000000 --- a/lib/authentication/SecureStorage/keytar/src/keytar_posix.cc +++ /dev/null @@ -1,184 +0,0 @@ -#include "keytar.h" - -// This is needed to make the builds on Ubuntu 14.04 / libsecret v0.16 work. -// The API we use has already stabilized. -#define SECRET_API_SUBJECT_TO_CHANGE -#include -#include -#include - -namespace keytar { - -namespace { - -static const SecretSchema schema = { - "org.freedesktop.Secret.Generic", SECRET_SCHEMA_NONE, { - { "service", SECRET_SCHEMA_ATTRIBUTE_STRING }, - { "account", SECRET_SCHEMA_ATTRIBUTE_STRING } - } -}; - -} // namespace - -KEYTAR_OP_RESULT SetPassword(const std::string& service, - const std::string& account, - const std::string& password, - std::string* errStr) { - GError* error = NULL; - - secret_password_store_sync( - &schema, // The schema. - SECRET_COLLECTION_DEFAULT, // Default collection. - (service + "/" + account).c_str(), // The label. - password.c_str(), // The password. - NULL, // Cancellable. (unneeded) - &error, // Reference to the error. - "service", service.c_str(), - "account", account.c_str(), - NULL); // End of arguments. - - if (error != NULL) { - *errStr = std::string(error->message); - g_error_free(error); - return FAIL_ERROR; - } - - return SUCCESS; -} - -KEYTAR_OP_RESULT GetPassword(const std::string& service, - const std::string& account, - std::string* password, - std::string* errStr) { - GError* error = NULL; - - gchar* raw_password = secret_password_lookup_sync( - &schema, // The schema. - NULL, // Cancellable. (unneeded) - &error, // Reference to the error. - "service", service.c_str(), - "account", account.c_str(), - NULL); // End of arguments. - - if (error != NULL) { - *errStr = std::string(error->message); - g_error_free(error); - return FAIL_ERROR; - } - - if (raw_password == NULL) - return FAIL_NONFATAL; - - *password = raw_password; - secret_password_free(raw_password); - return SUCCESS; -} - -KEYTAR_OP_RESULT DeletePassword(const std::string& service, - const std::string& account, - std::string* errStr) { - GError* error = NULL; - - gboolean result = secret_password_clear_sync( - &schema, // The schema. - NULL, // Cancellable. (unneeded) - &error, // Reference to the error. - "service", service.c_str(), - "account", account.c_str(), - NULL); // End of arguments. - - if (error != NULL) { - *errStr = std::string(error->message); - g_error_free(error); - return FAIL_ERROR; - } - - if (!result) - return FAIL_NONFATAL; - - return SUCCESS; -} - -KEYTAR_OP_RESULT FindPassword(const std::string& service, - std::string* password, - std::string* errStr) { - GError* error = NULL; - - gchar* raw_password = secret_password_lookup_sync( - &schema, // The schema. - NULL, // Cancellable. (unneeded) - &error, // Reference to the error. - "service", service.c_str(), - NULL); // End of arguments. - - if (error != NULL) { - *errStr = std::string(error->message); - g_error_free(error); - return FAIL_ERROR; - } - - if (raw_password == NULL) - return FAIL_NONFATAL; - - *password = raw_password; - secret_password_free(raw_password); - return SUCCESS; -} - -KEYTAR_OP_RESULT FindCredentials(const std::string& service, - std::vector* credentials, - std::string* errStr) { - GError* error = NULL; - - GHashTable* attributes = g_hash_table_new(NULL, NULL); - g_hash_table_replace(attributes, - (gpointer) "service", - (gpointer) service.c_str()); - - GList* items = secret_service_search_sync( - NULL, - &schema, // The schema. - attributes, - static_cast(SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | - SECRET_SEARCH_LOAD_SECRETS), - NULL, // Cancellable. (unneeded) - &error); // Reference to the error. - - g_hash_table_destroy(attributes); - - if (error != NULL) { - *errStr = std::string(error->message); - g_error_free(error); - return FAIL_ERROR; - } - - GList* current = items; - for (current = items; current != NULL; current = current->next) { - SecretItem* item = reinterpret_cast(current->data); - - GHashTable* itemAttrs = secret_item_get_attributes(item); - char* account = strdup( - reinterpret_cast(g_hash_table_lookup(itemAttrs, "account"))); - - SecretValue* secret = secret_item_get_secret(item); - char* password = strdup(secret_value_get_text(secret)); - - if (account == NULL || password == NULL) { - if (account) - free(account); - - if (password) - free(password); - - continue; - } - - credentials->push_back(Credentials(account, password)); - free(account); - free(password); - } - - return SUCCESS; -} - -} // namespace keytar diff --git a/lib/authentication/SecureStorage/keytar/src/keytar_win.cc b/lib/authentication/SecureStorage/keytar/src/keytar_win.cc deleted file mode 100644 index 60a56dab1..000000000 --- a/lib/authentication/SecureStorage/keytar/src/keytar_win.cc +++ /dev/null @@ -1,272 +0,0 @@ -#include "keytar.h" - -#define UNICODE - -#include -#include - -#include "credentials.h" - -namespace keytar { - -LPWSTR utf8ToWideChar(std::string utf8) { - int wide_char_length = MultiByteToWideChar(CP_UTF8, - 0, - utf8.c_str(), - -1, - NULL, - 0); - if (wide_char_length == 0) { - return NULL; - } - - LPWSTR result = new WCHAR[wide_char_length]; - if (MultiByteToWideChar(CP_UTF8, - 0, - utf8.c_str(), - -1, - result, - wide_char_length) == 0) { - delete[] result; - return NULL; - } - - return result; -} - -std::string wideCharToAnsi(LPWSTR wide_char) { - if (wide_char == NULL) { - return std::string(); - } - - int ansi_length = WideCharToMultiByte(CP_ACP, - 0, - wide_char, - -1, - NULL, - 0, - NULL, - NULL); - if (ansi_length == 0) { - return std::string(); - } - - char* buffer = new char[ansi_length]; - if (WideCharToMultiByte(CP_ACP, - 0, - wide_char, - -1, - buffer, - ansi_length, - NULL, - NULL) == 0) { - delete[] buffer; - return std::string(); - } - - std::string result = std::string(buffer); - delete[] buffer; - return result; -} - -std::string wideCharToUtf8(LPWSTR wide_char) { - if (wide_char == NULL) { - return std::string(); - } - - int utf8_length = WideCharToMultiByte(CP_UTF8, - 0, - wide_char, - -1, - NULL, - 0, - NULL, - NULL); - if (utf8_length == 0) { - return std::string(); - } - - char* buffer = new char[utf8_length]; - if (WideCharToMultiByte(CP_UTF8, - 0, - wide_char, - -1, - buffer, - utf8_length, - NULL, - NULL) == 0) { - delete[] buffer; - return std::string(); - } - - std::string result = std::string(buffer); - delete[] buffer; - return result; -} - -std::string getErrorMessage(DWORD errorCode) { - LPWSTR errBuffer; - ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, errorCode, 0, (LPWSTR) &errBuffer, 0, NULL); - std::string errMsg = wideCharToAnsi(errBuffer); - LocalFree(errBuffer); - return errMsg; -} - -KEYTAR_OP_RESULT SetPassword(const std::string& service, - const std::string& account, - const std::string& password, - std::string* errStr) { - LPWSTR target_name = utf8ToWideChar(service + '/' + account); - if (target_name == NULL) { - return FAIL_ERROR; - } - - LPWSTR user_name = utf8ToWideChar(account); - if (user_name == NULL) { - return FAIL_ERROR; - } - - CREDENTIAL cred = { 0 }; - cred.Type = CRED_TYPE_GENERIC; - cred.TargetName = target_name; - cred.UserName = user_name; - cred.CredentialBlobSize = password.size(); - cred.CredentialBlob = (LPBYTE)(password.data()); - cred.Persist = CRED_PERSIST_ENTERPRISE; - - bool result = ::CredWrite(&cred, 0); - delete[] target_name; - if (!result) { - *errStr = getErrorMessage(::GetLastError()); - return FAIL_ERROR; - } else { - return SUCCESS; - } -} - -KEYTAR_OP_RESULT GetPassword(const std::string& service, - const std::string& account, - std::string* password, - std::string* errStr) { - LPWSTR target_name = utf8ToWideChar(service + '/' + account); - if (target_name == NULL) { - return FAIL_ERROR; - } - - CREDENTIAL* cred; - bool result = ::CredRead(target_name, CRED_TYPE_GENERIC, 0, &cred); - delete[] target_name; - if (!result) { - DWORD code = ::GetLastError(); - if (code == ERROR_NOT_FOUND) { - return FAIL_NONFATAL; - } else { - *errStr = getErrorMessage(code); - return FAIL_ERROR; - } - } - - *password = std::string(reinterpret_cast(cred->CredentialBlob), - cred->CredentialBlobSize); - ::CredFree(cred); - return SUCCESS; -} - -KEYTAR_OP_RESULT DeletePassword(const std::string& service, - const std::string& account, - std::string* errStr) { - LPWSTR target_name = utf8ToWideChar(service + '/' + account); - if (target_name == NULL) { - return FAIL_ERROR; - } - - bool result = ::CredDelete(target_name, CRED_TYPE_GENERIC, 0); - delete[] target_name; - if (!result) { - DWORD code = ::GetLastError(); - if (code == ERROR_NOT_FOUND) { - return FAIL_NONFATAL; - } else { - *errStr = getErrorMessage(code); - return FAIL_ERROR; - } - } - - return SUCCESS; -} - -KEYTAR_OP_RESULT FindPassword(const std::string& service, - std::string* password, - std::string* errStr) { - LPWSTR filter = utf8ToWideChar(service + "*"); - if (filter == NULL) { - return FAIL_ERROR; - } - - DWORD count; - CREDENTIAL** creds; - bool result = ::CredEnumerate(filter, 0, &count, &creds); - delete[] filter; - if (!result) { - DWORD code = ::GetLastError(); - if (code == ERROR_NOT_FOUND) { - return FAIL_NONFATAL; - } else { - *errStr = getErrorMessage(code); - return FAIL_ERROR; - } - } - - *password = std::string(reinterpret_cast(creds[0]->CredentialBlob), - creds[0]->CredentialBlobSize); - ::CredFree(creds); - return SUCCESS; -} - -KEYTAR_OP_RESULT FindCredentials(const std::string& service, - std::vector* credentials, - std::string* errStr) { - LPWSTR filter = utf8ToWideChar(service + "*"); - if (filter == NULL) { - *errStr = "Error generating credential filter"; - return FAIL_ERROR; - } - - DWORD count; - CREDENTIAL **creds; - - bool result = ::CredEnumerate(filter, 0, &count, &creds); - if (!result) { - DWORD code = ::GetLastError(); - if (code == ERROR_NOT_FOUND) { - return FAIL_NONFATAL; - } else { - *errStr = getErrorMessage(code); - return FAIL_ERROR; - } - } - - for (unsigned int i = 0; i < count; ++i) { - CREDENTIAL* cred = creds[i]; - - if (cred->UserName == NULL || cred->CredentialBlobSize == NULL) { - continue; - } - - std::string login = wideCharToUtf8(cred->UserName); - std::string password( - reinterpret_cast( - cred->CredentialBlob), - cred->CredentialBlobSize); - - credentials->push_back(Credentials(login, password)); - } - - CredFree(creds); - - return SUCCESS; -} - - -} // namespace keytar diff --git a/lib/authentication/SecureStorage/keytar/src/main.cc b/lib/authentication/SecureStorage/keytar/src/main.cc deleted file mode 100644 index 7c7dc7456..000000000 --- a/lib/authentication/SecureStorage/keytar/src/main.cc +++ /dev/null @@ -1,139 +0,0 @@ -#include "napi.h" -#include "async.h" - -namespace { - -Napi::Value SetPassword(const Napi::CallbackInfo& info) { - Napi::Env env = info.Env(); - - if (!info[0].IsString()) { - Napi::TypeError::New(env, "Parameter 'service' must be a string"). - ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string service = info[0].As(); - - if (!info[1].IsString()) { - Napi::TypeError::New(env, "Parameter 'username' must be a string"). - ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string username = info[1].As(); - - if (!info[2].IsString()) { - Napi::TypeError::New(env, "Parameter 'password' must be a string"). - ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string password = info[2].As(); - - SetPasswordWorker* worker = new SetPasswordWorker( - service, - username, - password, - env); - worker->Queue(); - return worker->Promise(); -} - -Napi::Value GetPassword(const Napi::CallbackInfo& info) { - Napi::Env env = info.Env(); - if (!info[0].IsString()) { - Napi::TypeError::New(env, "Parameter 'service' must be a string"). - ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string service = info[0].As(); - - if (!info[1].IsString()) { - Napi::TypeError::New(env, "Parameter 'username' must be a string"). - ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string username = info[1].As(); - - GetPasswordWorker* worker = new GetPasswordWorker( - service, - username, - env); - worker->Queue(); - return worker->Promise(); -} - -Napi::Value DeletePassword(const Napi::CallbackInfo& info) { - Napi::Env env = info.Env(); - if (!info[0].IsString()) { - Napi::TypeError::New(env, "Parameter 'service' must be a string"). - ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string service = info[0].As(); - - if (!info[1].IsString()) { - Napi::TypeError::New(env, "Parameter 'username' must be a string"). - ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string username = info[1].As(); - - DeletePasswordWorker *worker = new DeletePasswordWorker( - service, - username, - env); - worker->Queue(); - return worker->Promise(); -} - -Napi::Value FindPassword(const Napi::CallbackInfo& info) { - Napi::Env env = info.Env(); - if (!info[0].IsString()) { - Napi::TypeError::New(env, "Parameter 'service' must be a string"). - ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string service = info[0].As(); - - FindPasswordWorker* worker = new FindPasswordWorker( - service, - env); - worker->Queue(); - return worker->Promise(); -} - -Napi::Value FindCredentials(const Napi::CallbackInfo& info) { - Napi::Env env = info.Env(); - if (!info[0].IsString()) { - Napi::TypeError::New(env, "Parameter 'service' must be a string"). - ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string service = info[0].As(); - - FindCredentialsWorker* worker = new FindCredentialsWorker( - service, - env); - worker->Queue(); - return worker->Promise(); -} - -Napi::Object Init(Napi::Env env, Napi::Object exports) { - exports.Set("getPassword", Napi::Function::New(env, GetPassword)); - exports.Set("setPassword", Napi::Function::New(env, SetPassword)); - exports.Set("deletePassword", Napi::Function::New(env, DeletePassword)); - exports.Set("findPassword", Napi::Function::New(env, FindPassword)); - exports.Set("findCredentials", Napi::Function::New(env, FindCredentials)); - return exports; -} - -} // namespace - -NODE_API_MODULE(keytar, Init) diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index 30915d798..5818a7018 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -5,10 +5,11 @@ const path = require('path'); const GlobalConfig = require('../global_config'); const Logger = require('../logger'); -const keytar = require('./SecureStorage/keytar/lib/keytar.js'); const os = require('os'); const fs = require('fs/promises'); + + function createCredentialCacheDir() { const cacheDirectory = GlobalConfig.mkdirCacheDir(process.env.SF_TEMPORARY_CREDENTIAL_CACHE_DIR); const credCache = path.join(cacheDirectory, 'temporary_credential.json'); @@ -24,6 +25,11 @@ function createCredentialCacheDir() { * @returns */ +function isLinuxMachine() { + const osList = ['win32','darwin']; + return !osList.some((element)=> element === os.platform()); +} + function buildTemporaryCredentialName(host, user, credType) { return `{${host.toUpperCase()}}:{${user.toUpperCase()}}:{SF_NODE_JS_DRIVER}:{${credType}}}`; } @@ -32,40 +38,58 @@ async function writeCredential(host, user, credType, token){ Logger.getInstance().trace('The os is ', os.platform()); if (!token || token === '') { Logger.getInstance().debug('Token is not provided'); + return; } else { - try { - if (os.platform() === 'linux') { - const dir = createCredentialCacheDir(); - await fs.writeFile(dir, token, 'utf8'); - } else { - await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); - } - } catch (err){ + // try { + // try { + // const keytar = require('keytar'); + // await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); + // } catch(err) { + // const dir = createCredentialCacheDir(); + // await fs.writeFile(dir, token, 'utf8'); + // } + try{ + const dir = createCredentialCacheDir(); + await fs.writeFile(dir, token, 'utf8'); + } + catch (err){ Logger.getInstance().error('Failed to save Credential: ', err.message); } } } async function readCredential(host, user, credType) { - Logger.getInstance().trace('The os is ', os.platform()); + try{ + // try{ + // const keytar = require('keytar'); + // return await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType)); + // }catch(err) { + // const dir = createCredentialCacheDir(); + // return await fs.readFile(dir, 'utf8'); + // } - if (os.platform() === 'linux') { - const dir = createCredentialCacheDir(); - return await fs.readFile(dir, 'utf8'); - } else { - return await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType)); - } + const dir = createCredentialCacheDir(); + return await fs.readFile(dir, 'utf8'); + }catch (err){ + Logger.getInstance().error('Failed to save Credential: ', err.message); + } } async function deleteCredential(host, user, credType) { - Logger.getInstance().trace('The os is ', os.platform()); + try{ + // try{ + // const keytar = require('keytar'); + // return await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType)); + // }catch(err) { + // const dir = createCredentialCacheDir(); + // return await fs.unlink(dir); + // } - if (os.platform() === 'linux') { const dir = createCredentialCacheDir(); return await fs.unlink(dir); - } else { - await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType)); - } + }catch (err){ + Logger.getInstance().error('Failed to save Credential: ', err.message); + } } module.exports = { diff --git a/package.json b/package.json index 14ecf45d4..58c8e1183 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,9 @@ "nyc": "^15.1.0", "test-console": "^2.0.0" }, + "optionalDependencies": { + "keytar": "^7.9.0" + }, "peerDependencies": { "asn1.js": "^5.4.1" }, diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index 2f82a0f60..e2bb6da2b 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -1,5 +1,5 @@ const assert = require('assert'); -const keytar = require('../../../lib/authentication/SecureStorage/keytar/lib/keytar.js'); +// const keytar = require('../../../lib/authentication/SecureStorage/keytar/lib/keytar.js'); const SecureStorage = require('../../../lib/authentication/secureStorage'); const { randomUUID } = require('crypto'); @@ -9,15 +9,15 @@ describe('Secure Storage Test', function () { const user = 'mock_user'; const credType = 'MOCK_CREDTYPE'; const randomPassword = randomUUID(); - const userNameForStorage = SecureStorage.buildTemporaryCredentialName(host, user, credType, 0); + const userNameForStorage = SecureStorage.buildTemporaryCredentialName(host, user, credType); - async function findCredentialFromStorage(userName, password){ - const credentialList = await keytar.findCredentials(host); - const result = credentialList.some((element) => { - return element.account === userName && element.password === password; - }); - return result; - } + // async function findCredentialFromStorage(userName, password){ + // const credentialList = await keytar.findCredentials(host); + // const result = credentialList.some((element) => { + // return element.account === userName && element.password === password; + // }); + // return result; + // } it('test build user name', function (done){ assert.strictEqual(userNameForStorage, @@ -37,9 +37,9 @@ describe('Secure Storage Test', function () { assert.strictEqual(savedPassword, randomPassword); }); - it('test - delete the mock credential in Local Storage', async function () { - await SecureStorage.deleteCredential(host, user, credType); - const result = await findCredentialFromStorage(userNameForStorage, randomPassword); - assert.strictEqual(result, false); - }); +// it('test - delete the mock credential in Local Storage', async function () { +// await SecureStorage.deleteCredential(host, user, credType); +// const result = await findCredentialFromStorage(userNameForStorage, randomPassword); +// assert.strictEqual(result, false); +// }); }); From eebbbecd6d7b7b0ff58d847c113c167afa85a7ac Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 23 Nov 2023 14:37:31 -0800 Subject: [PATCH 36/38] dependency testing --- lib/authentication/secureStorage.js | 56 +++++++++---------- .../unit/authentication/secureStorage_test.js | 1 - 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index 5818a7018..b8380b778 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -40,17 +40,17 @@ async function writeCredential(host, user, credType, token){ Logger.getInstance().debug('Token is not provided'); return; } else { - // try { - // try { - // const keytar = require('keytar'); - // await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); - // } catch(err) { - // const dir = createCredentialCacheDir(); - // await fs.writeFile(dir, token, 'utf8'); - // } - try{ - const dir = createCredentialCacheDir(); - await fs.writeFile(dir, token, 'utf8'); + try { + try { + const keytar = require('keytar'); + await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); + } catch(err) { + const dir = createCredentialCacheDir(); + await fs.writeFile(dir, token, 'utf8'); + } + // try{ + // const dir = createCredentialCacheDir(); + // await fs.writeFile(dir, token, 'utf8'); } catch (err){ Logger.getInstance().error('Failed to save Credential: ', err.message); @@ -60,16 +60,16 @@ async function writeCredential(host, user, credType, token){ async function readCredential(host, user, credType) { try{ - // try{ - // const keytar = require('keytar'); - // return await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType)); - // }catch(err) { - // const dir = createCredentialCacheDir(); - // return await fs.readFile(dir, 'utf8'); - // } - + try{ + const keytar = require('keytar'); + return await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType)); + }catch(err) { const dir = createCredentialCacheDir(); return await fs.readFile(dir, 'utf8'); + } + + // const dir = createCredentialCacheDir(); + // return await fs.readFile(dir, 'utf8'); }catch (err){ Logger.getInstance().error('Failed to save Credential: ', err.message); } @@ -77,16 +77,16 @@ async function readCredential(host, user, credType) { async function deleteCredential(host, user, credType) { try{ - // try{ - // const keytar = require('keytar'); - // return await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType)); - // }catch(err) { - // const dir = createCredentialCacheDir(); - // return await fs.unlink(dir); - // } + try{ + const keytar = require('keytar'); + return await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType)); + }catch(err) { + const dir = createCredentialCacheDir(); + return await fs.unlink(dir); + } - const dir = createCredentialCacheDir(); - return await fs.unlink(dir); + // const dir = createCredentialCacheDir(); + // return await fs.unlink(dir); }catch (err){ Logger.getInstance().error('Failed to save Credential: ', err.message); } diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index e2bb6da2b..1f85f7236 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -1,5 +1,4 @@ const assert = require('assert'); -// const keytar = require('../../../lib/authentication/SecureStorage/keytar/lib/keytar.js'); const SecureStorage = require('../../../lib/authentication/secureStorage'); const { randomUUID } = require('crypto'); From b8c9c603e5ad12606c3cf50308997825ec2c9af6 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 23 Nov 2023 15:10:09 -0800 Subject: [PATCH 37/38] fixed Secure storage code --- lib/authentication/secureStorage.js | 41 ++++++------------- .../unit/authentication/secureStorage_test.js | 18 +++----- 2 files changed, 17 insertions(+), 42 deletions(-) diff --git a/lib/authentication/secureStorage.js b/lib/authentication/secureStorage.js index b8380b778..22b2a8ecd 100644 --- a/lib/authentication/secureStorage.js +++ b/lib/authentication/secureStorage.js @@ -5,11 +5,8 @@ const path = require('path'); const GlobalConfig = require('../global_config'); const Logger = require('../logger'); -const os = require('os'); const fs = require('fs/promises'); - - function createCredentialCacheDir() { const cacheDirectory = GlobalConfig.mkdirCacheDir(process.env.SF_TEMPORARY_CREDENTIAL_CACHE_DIR); const credCache = path.join(cacheDirectory, 'temporary_credential.json'); @@ -25,17 +22,11 @@ function createCredentialCacheDir() { * @returns */ -function isLinuxMachine() { - const osList = ['win32','darwin']; - return !osList.some((element)=> element === os.platform()); -} - function buildTemporaryCredentialName(host, user, credType) { return `{${host.toUpperCase()}}:{${user.toUpperCase()}}:{SF_NODE_JS_DRIVER}:{${credType}}}`; } async function writeCredential(host, user, credType, token){ - Logger.getInstance().trace('The os is ', os.platform()); if (!token || token === '') { Logger.getInstance().debug('Token is not provided'); return; @@ -44,50 +35,42 @@ async function writeCredential(host, user, credType, token){ try { const keytar = require('keytar'); await keytar.setPassword(host, buildTemporaryCredentialName(host, user, credType), token); - } catch(err) { + } catch (err) { const dir = createCredentialCacheDir(); + Logger.getInstance().trace('Failed to save the token in the credential manager. The token will be saved on the the local machine at', dir); await fs.writeFile(dir, token, 'utf8'); } - // try{ - // const dir = createCredentialCacheDir(); - // await fs.writeFile(dir, token, 'utf8'); - } - catch (err){ + } catch (err){ Logger.getInstance().error('Failed to save Credential: ', err.message); } } } async function readCredential(host, user, credType) { - try{ - try{ + try { + try { const keytar = require('keytar'); return await keytar.getPassword(host, buildTemporaryCredentialName(host, user, credType)); - }catch(err) { + } catch (err) { const dir = createCredentialCacheDir(); + Logger.getInstance().trace('Failed to read the token from the credential manager. Searching the token at ', dir); return await fs.readFile(dir, 'utf8'); } - - // const dir = createCredentialCacheDir(); - // return await fs.readFile(dir, 'utf8'); - }catch (err){ + } catch (err){ Logger.getInstance().error('Failed to save Credential: ', err.message); } } async function deleteCredential(host, user, credType) { - try{ - try{ + try { + try { const keytar = require('keytar'); return await keytar.deletePassword(host, buildTemporaryCredentialName(host, user, credType)); - }catch(err) { + } catch (err) { const dir = createCredentialCacheDir(); return await fs.unlink(dir); } - - // const dir = createCredentialCacheDir(); - // return await fs.unlink(dir); - }catch (err){ + } catch (err){ Logger.getInstance().error('Failed to save Credential: ', err.message); } } diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index 1f85f7236..828fc91e2 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -10,14 +10,6 @@ describe('Secure Storage Test', function () { const randomPassword = randomUUID(); const userNameForStorage = SecureStorage.buildTemporaryCredentialName(host, user, credType); - // async function findCredentialFromStorage(userName, password){ - // const credentialList = await keytar.findCredentials(host); - // const result = credentialList.some((element) => { - // return element.account === userName && element.password === password; - // }); - // return result; - // } - it('test build user name', function (done){ assert.strictEqual(userNameForStorage, '{MOCK_TEST}:{MOCK_USER}:{SF_NODE_JS_DRIVER}:{MOCK_CREDTYPE}}' @@ -36,9 +28,9 @@ describe('Secure Storage Test', function () { assert.strictEqual(savedPassword, randomPassword); }); -// it('test - delete the mock credential in Local Storage', async function () { -// await SecureStorage.deleteCredential(host, user, credType); -// const result = await findCredentialFromStorage(userNameForStorage, randomPassword); -// assert.strictEqual(result, false); -// }); + it('test - delete the mock credential in Local Storage', async function () { + await SecureStorage.deleteCredential(host, user, credType); + const result = await SecureStorage.readCredential(host, user, credType); + assert.strictEqual(result, null); + }); }); From 3eb3c49a2824c1652cc562cd9aeb2d61b1699a26 Mon Sep 17 00:00:00 2001 From: sfc-gh-ext-simba-jy Date: Thu, 23 Nov 2023 15:56:03 -0800 Subject: [PATCH 38/38] fixed error --- test/unit/authentication/secureStorage_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/authentication/secureStorage_test.js b/test/unit/authentication/secureStorage_test.js index 828fc91e2..58f1197ee 100644 --- a/test/unit/authentication/secureStorage_test.js +++ b/test/unit/authentication/secureStorage_test.js @@ -31,6 +31,6 @@ describe('Secure Storage Test', function () { it('test - delete the mock credential in Local Storage', async function () { await SecureStorage.deleteCredential(host, user, credType); const result = await SecureStorage.readCredential(host, user, credType); - assert.strictEqual(result, null); + assert.ok(result === null || result === undefined); }); });